实现 or-odd,一个 or 忽略偶数索引参数

Implementing or-odd, an or which ignores even-indexed arguments

我是新来的,我有一个问题我一直试图解决整整两天(真的)。

过几天准备考试,不知道要做什么。

如果你能帮助我,我会很高兴,因为我也没有找到太多material关于这个语言,互联网没有太多支持。

这个问题是讲师给我的,我认为不是从任何教科书上摘下来的,而是我用SICP这本书学习的,问题是这样的:

本题涉及奇或表达式和替代模型的值。 在解决问题时,除了最后一节外,假设 Scheme 中没有“或”的实现(即不依赖于“或”表达式的现有实现。)

奇或表达式定义为:

(or-odd exp1 exp2 ... expn)

当至少得到一个表达式作为参数时(1> = n, (且参数个数为奇数。

奇或表达式的取值如下:

首先,计算表达式 exp1。如果该值不为 false,则 Return 它。否则,计算表达式 exp2 但不引用它的值(例如,它可能是一个表达式打印操作)。 然后检查表达式 exp3 的值——如果它不为 false return 就可以了。如果是这样,重写 exp4 并移动到 exp5 等等,直到最后一个表达式。

当你到达最后一个表达式(其索引为奇数)时,你 return 它的值。

例如 Revaluation (or 1 2 3) will return 1, revaluation (or-odd false (display 2) 3) will print 2 and return 3.

 1) Implement the following procedures (must use the tag package):
 • The odd-or-make constructor, which receives a list of expressions as an 
   argument
 • Selectors :
     - expression-get that works on a whole odd-or expression.
     - first-exp , second-exp and rest-exps that works on exps
     - and the predicates Odd-or and Exp-last? Note that the predicate should 
       also check that number of arguments is odd
    Also write down the type of each of them on the actual side.




2) Implement odd-or-eval. It is recommended to use begin.

3) Now, assume that or expressions exist in a language, and write a procedure for performing a syntactic derivation of expressions or-even for or expressions. 

程序的签名应该是

我想运行赏金,但要等两天,如果有选项可以给任何帮助我的人我会这样做。

这道题对我来说很难。很难。如果有人可以帮助我,我会很高兴,第一部分我认为我能够做到,第二部分和第三部分 - 我什至不知道如何开始,太难了。

第一部分我做的代码:

#lang racket

;Signature: attach-tag(x,tag)
;Type: [Symbol*T -> Pair(Symbol, T)]
(define attach-tag (lambda (x tag) (cons tag x)))
;Signature: get-tag(tagged)
;Type: Pair(Symbol,T) -> Symbol
(define get-tag (lambda (tagged) (car tagged)))
;Signature: get-content(tagged)
;Type: [Pair(Symbol,T) -> T]
(define get-content (lambda (tagged) (cdr tagged)))
;Signature: tagged-data?(datum)
;Type: [T -> Boolean]
(define tagged-data?
(lambda (datum)
  (and (pair? datum) (symbol? (car datum))) ))
;Signature: tagged-by?(tagged,tag)
;Type: [T*Symbol -> Boolean]
(define tagged-by?
  (lambda (tagged tag)
    (and (tagged-data? tagged)
         (eq? (get-tag tagged) tag))))



;Type: [LIST(T)->or-odd]
(define make-or-odd
  (lambda (expressions)
    (attach-tag expressions 'or-odd)))

;Type: [T -> Boolean]
(define or-odd?
  (lambda (exp) (and (tagged-by? exp 'or-odd)
                     (list? (car get-content exp))
                     (eq? (remainder (length (get-content exp)) 2) 1))))

;Type: [T -> Boolean]
(define last-exps?
  (lambda (exp) (null? (cdr exp))))

;Type: [or-odd -> LIST(T)]
(define get-expressions
  (lambda (or-odd)  (car (get-content or-odd))))

;Type: [LIST(T)->T]
(define first-exp 
  (lambda (exps)  (car (exps))))

;Type: [LIST(T)->T]
(define second-exp 
  (lambda (exps) (cadr (exps))))

;Type: [LIST(T)->T]
(define rest-exp 
  (lambda (exps) (cddr (exps))))

如果有什么不明白的地方,我会再解释一遍,告诉我,这个问题对我很重要,如果你能帮助我,我会很高兴。

因此您必须编写操作表达式的代码,并且需要为新的 or-odd 种表达式编写求值器。

您需要实现的一些抽象模型

让我们将 E 命名为您的语言中所有表达式的集合。 在 E 中的表达式 e 要么是字面值(我们现在不需要变量),要么是复合形式 (f e1 .. en) 其中 e1en 是来自 E 的表达式, 和 f 指定一些函数或原语。这里我们对 for-odd.

的情况感兴趣

让我们写[e] E 中任意表达式e 的求值函数。

对于 E 中的任何表达式 v 是文字值,[v]被定义为 v 本身。 我们想为 v 的所有合适值给出 [(or-odd e1 .. en)] 的定义e1en 表达式来自 E.

When at least one expression is obtained as an argument (1> = n, (and the number of arguments is odd.

我们必须给出 n 为奇数且至少为 1 的定义,如果我理解正确的话。

First, evaluate the expression exp1. If the value is not false, Return it. Otherwise, evaluate the expression exp2 but do not refer to its value (for example, it could be an expression print operation). Then check the value of the expression exp3 - if it is not false return it. If so, rewrite The exp4 and move to exp5 and so on until the last expression. When you get to the last expression (whose index is odd) you return its value.

n为大于零的奇数,e1en表达式来自 E.

   [(or-odd e1 e2 e3 ... en)] is:

   Let v1 = [e1]  (it exists because n => 1)
   if v1 is false or if there is no e2, return v1.

   otherwise, there is an expression e2, as well as, at least, an expression e3 (because n is odd)
   let v2 = [e2]
   recursively compute [(or-odd e3 ... en)] as the value of [(or-odd e1 e2 e3 ... en)]

以更常见的 Lispy 方式,我们可以编写如下所示的函数,其中 evaluate 是通用评估函数,evaluate-or-odd 评估 or-odd 项的特定函数:

  (defun evaluate-or-odd (e)
    (let ((v1 (evaluate (first e))))
      (cond
        ((not v1) v1)
        ((not (rest e)) v1)
        (t (let ((e2/en (rest e)))
             ;; evaluate and discard
             (evaluate e2/en)
             ;;
             (evaluate-or-odd (rest e2/en)))))))

但是上面不是你必须写的,这更像是你需要使用给你的 API 来实现的规范。

使用给定的代码操作函数

在你的问题中,你定义了很多辅助函数和它们的签名,要求你使用它们来编写一个像上面那样的求值器,而不使用现有的 or(但我我猜你可以使用 ifcond)。 所以你必须像这样定义一个函数:

(define odd-or-eval
  (lambda (odd-or-exp)
    ...))

odd-or-expr 将通过这样的调用创建:

(odd-or-make (list e1 e2 e3))

对于某些值 e1e2e3

因此,首先,您需要访问数据所包含的表达式,然后调用:

(get-expressions odd-or-exp)

这将是 return 一个表达式列表。

然后您就可以进入递归过程来评估您的特殊术语,用于此表达式列表。 您需要调用 first-exprest-exp 来解构不同的子表达式。

请注意,您需要评估子元素,但没有通用的 evaluate 函数可用。我希望这是您的问题中缺少的部分,让我们称该函数为 evaluate.

您需要 evaluate 第一个表达式,将其与 false 进行比较,等等,如上所述。最终您将 return 一个结果或递归地调用其余表达式的计算器。我不会添加更多详细信息,因为我认为这可能足以让您入门,但如果有什么需要澄清的地方,请随时提问。

如果您没有 evaluate 函数,也许您应该编写转换代码的代码,即。您需要在原始表达式的基础上构建一个新表达式。