【问题标题】:Scheme: Evaluating a Logical expression List方案:评估逻辑表达式列表
【发布时间】:2016-02-09 23:32:59
【问题描述】:

我正在尝试在 Scheme 中编写一个程序,该程序接受一个表示逻辑表达式的列表并评估整个表达式。我需要返回一个列表,其中包含在达到最终值之前完成的每个中间结果。输入看起来像 '(((~ #t) V #t V (#f & (~ #f))) & #t & (~ (#t V #f))) 其中 & => and, V => 或,而 ~ => 不是。该输入的输出应类似于 '(#f #t #f #f #f #f #t #f #f) ,最右边是最终结果,最左边是第一个完成的评估。

我有一个可以评估列表的函数,但是我无法弄清楚如何构建历史列表。这是我目前得到的代码。

(define atom?
  (lambda (x)
    (and (not (pair? x)) (not (null? x)))))

(define evaluate1
  (lambda (lst rst)
   (cond
    ((null? lst) 'ErrEmptyList)
    ((equal? (cadr lst) 'V) (cons rst (or (car lst) (caddr lst))))
    ((equal? (cadr lst) '&) (cons rst (and (car lst) (caddr lst)))))))

(define evaluate
  (lambda (lst)
    (cond
      ((null? lst) 'ErrEmptyList)
      ((null? (cdr lst))
       (cond
         ((atom? (car lst)) (car lst))
         (else
          (evaluate (car lst)))))
      ((equal? (car lst) '~) (not (cadr lst)))
      ((and (and (atom? (car lst)) (atom? (caddr lst))) (null? (cdddr lst))) (evaluate1 lst))
      (else
       (cond
         ((atom? (car lst)) (evaluate (flatten (cons (cons (car lst) (cadr lst)) (evaluate (cddr lst))))))
         (else
          (evaluate (flatten (cons (cons (evaluate (car lst)) (cadr lst)) (list (evaluate (cddr lst))))))))))))

我的代码只是返回给定示例的#f 的结果,如何构建要返回的结果列表而不仅仅是最终结果。我是计划的新手,非常感谢任何方向或帮助。

【问题讨论】:

  • 看起来很有趣的问题。不幸的是,我没有时间详细了解它。但看起来这是“减少”过程的情况:它与reduce(或foldlfold-left)的工作方式相同,但不是只保留最后一个结果,而是将所有结果累积到列表中.

标签: scheme lisp


【解决方案1】:

如果我没看错的话,这个问题本质上是“传店风格”的一个例子。 (哦,没有 SPS 的维基百科条目?)这个想法是每个函数都必须返回一个历史列表,每个调用都必须包含一个。

开发此功能的最佳方法是遵循(如何设计程序)[http://www.htdp.org/].我无法用一段话来总结它,但除此之外,它要求您在编写程序之前编写测试。

最后,如果您使用 Racket,match 表单将使您的代码更具可读性。

【讨论】:

  • 是否有任何索引或方法可以搜索该书以在 htdp 中找到包含 store-passing 样式的页面?谷歌搜索似乎没有返回任何内容。
  • 试过谷歌搜索:“site:htdp.org store passing style”
【解决方案2】:

您可以为此使用 SPS 或“状态单子”,但您也可以诉诸普通的旧丑陋副作用:

(define (evaluate lst)
  (let ((vals '()))
    (define (eval lst)
      (cond
       [...]
       ((equal? (car lst) '~)
        (let ((result (not ...)))
          (setq vals (cons result vals))
          result))
       [...]))
    (let ((val (eval lst)))
      (reverse (cons val vals)))))

您可以为(let ((result ...)) (setq ...) result) 部分定义一个在不同位置重复的宏。

【讨论】:

    猜你喜欢
    • 2012-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多