sicp 4.3.3小节习题

  本节实现了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

时间: 2024-09-12 21:24:30

sicp 4.3.3小节习题的相关文章

sicp 4.4.1小节习题

本节开始进入第4章最后一部分--逻辑程序设计.scheme将实现一种查询语言,非常类似prolog.由于解释器的实现在后面,还未读到,前面的习题我都将用prolog做测试,当然也给出scheme版本的解答,待以后测试.     首先给出依照书中所述写出的prolog事实库: address('BitDiddle Ben','Slumerville','Ridge Road',10). address('Hacker Alyssa P','Cambridge','Mass Ave',78). ad

sicp 3.1.1小节习题尝试解答

这一节主要是介绍局部状态变量,介绍了set!和begin的语法,看来ruby使用!号来表示改变变量值不是什么新鲜主意.    习题3.1,不解释了 ;习题3.1 (define (make-accumulator init)   (define (accumulator num)     (set! init (+ init num))     init)   accumulator) 习题3.2,非常有趣的例子,在内部维持一个计数的变量即可,如果传入的参数是特定的符号就返回计数或者清0,如果不

sicp 4.2.2小节部分习题

4.27, ;;; L-Eval input: (define count 0) ;;; L-Eval value: ok ;;; L-Eval input: (define (id x)   (set! count (+ 1 count))   x) ;;; L-Eval value: ok ;;; L-Eval input: (define w (id (id 10))) ;;; L-Eval value: ok ;;; L-Eval input: count ;;; L-Eval valu

sicp 4.3.1小节两题

本节开始介绍神奇的amb函数,为引入逻辑程序设计做铺垫.关于amb,有清华王垠的一个文档: http://cs2.swfc.edu.cn/~wanghuan/wangyin1/amb/amb.html 4.35,与an-element-of类似: (define (an-integer-between low high)   (require (not (> low high)))   (amb low (an-integer-between (+ low 1) high))) 4.36,与练习

sicp 4.3.2部分习题

4.38,谜题就有翻译错误,问题更是错的离谱.原题是这样的: Baker, Cooper, Fletcher, Miller, and Smith live on different floors of an apartment house that contains only five floors. Baker does not live on the top floor. Cooper does not live on the bottom floor. Fletcher does not

sicp 习题3.6-3.8试解

习题3.6,我的实现如下: (define rand   (let ((x 3))      (lambda(arg)       (cond((eq? arg 'generate)             ((lambda()(set! x (rand-update x)) x)))            ((eq? arg 'reset)             (lambda(init) (set! x init) (set! x (rand-update x)) x))         

sicp 2.3小结习题尝试解答

 习题2.2没有全部做,我读书的速度远远超过做习题的进度,没办法,时间有限,晚上的时间基本用来看书了,习题也都是在工作间隙做的,慢慢来了,前两章读完再总结下.回到2.3节,这一节在前几节介绍数值型符号数据的基础上引入了符号数据,将任意符号作为数据的能力非常有趣,并给出了一个符号求导的例子,实在是太漂亮了. 习题2.53,直接看结果: > (list 'a 'b 'c)(a b c)> (list (list 'george))((george))> (cdr '((x1 x2) (y1 

sicp习题2.33-2.39尝试解答

这一节的内容非常有趣,通过将序列作为interface,在此基础上进而提取出各种高阶操作(map,filter,accumulate,enumerate等),由此引出模块化设计的讨论.模块化设计带来复杂性的降低,同时可能引入性能上的损失,比如书中对sum-odd-squares过程的两种写法,原来的写法枚举列表元素的过程散落在累积.过滤.映射的过程中,主要一次循环就够了,而通过三个高阶过程来操作反而需要3次的遍历. 习题2.33,将map,append,length基本过程用累积操作重新定义,联

sicp 5.1节习题尝试解答

5.1 图就不画在机器上了,麻烦 5.2 用寄存器语言描述5.1题中的阶乘机器,加上了读取和打印,这里的解答全部在实际的寄存机器中验证过,但是仍然按照该节的表示法表示. (controller   fac-loop    (assign n (op read))    (assign product (const 1))    (assign counter (const 1))   iter-loop    (test (op >) (reg counter) (reg n))    (bra