天天看點

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實作為特殊形式:

((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