微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

实现 or-odd, an or 忽略偶数索引参数 你需要实现的一些抽象模型使用给定的代码操作函数

如何解决实现 or-odd, an or 忽略偶数索引参数 你需要实现的一些抽象模型使用给定的代码操作函数

我是新来的,我在计划中有一个问题,我已经尝试解决了整整两天(真的)。

我准备过几天参加考试,但我不知道该怎么办。

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

问题是讲师给我的,我认为不是从任何教科书中摘录的,但我是用SICP这本书学习的,问题是这样的:

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

奇数或表达式定义为:

(或奇数 exp1 exp2… expn)

当获得至少一个表达式作为参数时 (1> = n,(并且参数的数量是奇数。

奇数或表达式的值如下获得:

首先,计算表达式 exp1。如果该值不为假,则返回它。否则,计算表达式 exp2 但不引用其值(例如,它可能是表达式打印操作)。 然后检查表达式 exp3 的值 - 如果它不是 false 则返回它。如果是,则重写 exp4 并移至 exp5,依此类推,直到最后一个表达式。

当您到达最后一个表达式(其索引为奇数)时,您将返回其值。

例如 重估(或 1 2 3)将返回 1,重估(或奇数 false(显示 2)3)将打印 2 并返回 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本身。 我们想为 ve1 的所有合适的值给出一个 [(or-odd e1 .. en)] 的定义>en 来自 E 的表达式。

当获得至少一个表达式作为参数时 (1> = n,(并且参数的数量是奇数。

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

首先,计算表达式 exp1。如果该值不为假,则返回它。否则,计算表达式 exp2 但不引用其值(例如,它可能是表达式打印操作)。然后检查表达式 exp3 的值 - 如果它不是 false 则返回它。如果是,则重写 exp4 并移至 exp5,依此类推,直到最后一个表达式。 当您到达最后一个表达式(其索引为奇数)时,您将返回其值。

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)

这将返回一个表达式列表。

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

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

您需要 evaluate 第一个表达式,将其与 false 进行比较,等等,如上所述。最终,您将返回结果或递归调用其余表达式的求值器。我不会添加更多细节,因为我认为这可能足以让您开始使用,但如果有什么需要澄清的地方,请随时提出问题。

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。