本节实现了amb求值器,题目都是扩展这个求值器,引入一些特殊的过程。我的尝试解答从4.51开始
习题4.51,要求实现permanent-set!,这个过程的副作用在遇到失败时不撤销,实现如下:
;扩充analyze
((permanent-assignment? exp)
(analyze-permanent-assignment exp))
;实现
(define (permanent-assignment? exp)
(tagged-list? exp 'permanent-set!))
(define (analyze-permanent-assignment exp)
(let ((var (assignment-variable exp))
(vproc (analyze (assignment-value exp))))
(lambda(env succeed fail)
(vproc env
(lambda(val fail2)
(set-variable-value! var val env)
(succeed 'ok fail2))
fail))))
习题4.52,实现if-fail的特殊形式,在第一个表达式如果求值成功,就返回该表达式的值,否则返回第二个表达式的值,实现如下:
;扩充analyze
((if-fail? exp)
(analyze-if-fail exp))
;实现
(define (if-fail? exp)
(tagged-list? exp 'if-fail))
(define (analyze-if-fail exp)
(let ((pproc (analyze (if-predicate exp)))
(cproc (analyze (if-consequent exp))))
(lambda(env succeed fail)
(pproc env (lambda(pred-value fail2)
(succeed pred-value fail2))
(lambda() (cproc env succeed fail))))))
pproc如果执行成功,就返回结果pred-value,否则就执行fail过程(lambda() (cproc env succeed fail)),测试略。
习题4.53,根据题意可知这个过程返回结果应该是(prime-sum-pair '(1 3 5 8) '(20 35 110))的所有结果,执行也是如此:
;;; AMB-Eval value:
((8 35) (3 110) (3 20))
习题4.54,将require实现为特殊形式:
;扩充analyze
((require? exp)
(analyze-require exp))
;实现
(define (require? exp)
(tagged-list? exp 'require))
(define (require-predicate exp)
(cadr exp))
(define (analyze-require exp)
(let ((pproc (analyze (require-predicate exp))))
(lambda (env succeed fail)
(pproc env (lambda(pred-value fail2)
(if (not pred-value)
(fail2)
(succeed 'ok fail2)))
fail))))
文章转自庄周梦蝶 ,原文发布时间2008-11-21