方案:评估逻辑表达式列表

时间:2016-02-09 23:33:00

标签: scheme lisp

我正在尝试在Scheme中编写一个程序,该程序接受一个表示逻辑表达式的列表并计算总表达式。我需要返回一个列表,其中包含在达到最终值之前完成的每个中间结果。输入看起来像'(((〜#t)V #t V(#f&(〜#f)))& #t&(〜(#t V #f)))其中& =>并且,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结果,如何构建要返回的结果列表而不是最终结果。我是计划的新手,非常感谢任何方向或帮助。

2 个答案:

答案 0 :(得分:0)

如果我正确地阅读它,这个问题基本上就是"存储传递风格的一个例子。" (哦,那里没有SPS的维基百科条目?)这个想法是每个函数都必须返回一个历史列表,每个调用都必须包含一个。

开发此项目的最佳方法是遵循(如何设计程序)[http://www.htdp.org/]的设计方法。我不能在一个段落中总结它,但除此之外,它还要求你在编写程序之前编写测试。

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

答案 1 :(得分:0)

您可以使用SPS或"州monad"为此,你也可以采取简单的丑陋副作用:

(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)部分定义一个在不同地方重复的宏。