SICP 読み (234) 4.3.3 amb 評価器の実装

昨晩入れた直前エントリのテンパリようは凄い。後から自分で見ても意味不明。基本的に自分勝手にころんで大騒ぎ、とゆーのが微妙スギ。とりあえず自分で見て後で分かるように要点だけまとめておきたい、と。

  • 問題 4.52 で盛り込んだ if-fail 関連の手続きと cond->if な変換で使う手続きの名前がバッティングしていた。
  • prime-sum-pair が微妙との記述があるが、おそらくテンパッて括弧をミスタイプしたものと思われる
  • ramb な問題で仕込んだ一連の手続きにプリミティブな手続き名とバッティングするものがあった。remainder ってアナタ ...

問題切り分けなソレからログってるんですが微妙スギ。

問題 4.54

朝からバタバタでしたが気をとりなおしてナニを再開。ってーか解はバスの中で検討済みだったりして analyze-require は以下。

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

だよなー、と言いつつ評価器に盛り込んで動作確認。

;;; Amb-Eval input:
(define (distinct? items)
  (cond ((null? items) true)
        ((null? (cdr items)) true)
        ((member (car items) (cdr items)) false)
        (else (distinct? (cdr items)))))
(define (multiple-dwelling)
  (let ((baker (amb 1 2 3 4 5))
        (cooper (amb 1 2 3 4 5))
        (fletcher (amb 1 2 3 4 5))
        (miller (amb 1 2 3 4 5))
        (smith (amb 1 2 3 4 5)))
    (require
     (distinct? (list baker cooper fletcher miller smith)))
    (require (not (= baker 5)))
    (require (not (= cooper 1)))
    (require (not (= fletcher 5)))
    (require (not (= fletcher 1)))
    (require (> miller cooper))
    (require (not (= (abs (- smith fletcher)) 1)))
    (require (not (= (abs (- fletcher cooper)) 1)))
    (list (list 'baker baker)
          (list 'cooper cooper)
          (list 'fletcher fletcher)
          (list 'miller miller)
          (list 'smith smith))))

;;; Starting a new problem 
;;; Amb-Eval value:
ok

;;; Amb-Eval input:

;;; Starting a new problem 
;;; Amb-Eval value:
ok

;;; Amb-Eval input:
(multiple-dwelling)

;;; Starting a new problem 
;;; Amb-Eval value:
((baker 3) (cooper 2) (fletcher 4) (miller 5) (smith 1))

;;; Amb-Eval input:

ボーナスステージまであと約 30 頁。