我对计算机程序结构和解释的第4.3.3节中的练习4.54有疑问(http://mitpress.mit.edu/sicp/full-text/book/book-ZH-28.html#% _sec_4.3.3)。本练习涉及Amb评估员。
练习如下:
如果我们没有意识到
require
可以作为使用amb
的普通过程实现,由用户定义为非确定性程序的一部分,我们将不得不将其实现为一种特殊的形式。这需要语法程序
(define (require? exp) (tagged-list? exp 'require))
(define (require-predicate exp) (cadr exp))
以及
中发送的新条款analyze
((require? exp) (analyze-require exp))
以及处理
analyze-require
表达式的过程require
。完成analyze-require
的以下定义。(define (analyze-require exp) (let ((pproc (analyze (require-predicate exp)))) (lambda (env succeed fail) (pproc env (lambda (pred-value fail2) (if <??> <??> (succeed 'ok fail2))) fail))))
我完成了如下:
(define (analyze-require exp)
(let ((pproc (analyze (require-predicate exp))))
(lambda (env succeed fail)
(pproc env
(lambda (pred-value fail2)
(if (false? pred-value)
(fail2) ;; or (fail)
(succeed 'ok fail2)))
fail))))
我怀疑如下:
我知道,在执行期间,当谓词值pred-value
为false时,require
应该失败;也就是说,它应该调用失败继续程序。但我对是否应该拨打(fail)
或(fail2)
感到困惑。哪一个是正确的?
答案 0 :(得分:1)
(fail2)
是正确的。该过程符合continuation-passing style,在这种情况下正确的延续过程为fail2
。
答案 1 :(得分:0)
我认为(fail)
是正确的。
这里我们得到pred-value
,这意味着pproc
现在评估得很好。但如果它是false
值,我们会将其视为错误,因为pproc
评估错误。所以此处的延续时间为fail
而不是fail2
。
可在此处找到测试:
答案 2 :(得分:0)
(fail2)
是正确的,好吧,大部分时间无论您选择哪个都无关紧要,但对于以下条件:
1.谓词部分包含(amb),例如
(require (amb false true false true true))
2.谓词部分包含(设置!&lt; ...&gt;&lt; ...&gt;)
你可以检查出来,这是因为除了上述两种过程外,大多数进程的失败继续与其调用者相同。虽然听起来有些荒谬。