2016/01/21
SICP 問題 4.77
簡略化して.
(and (not A) B C)を(and B C (not A))に並び替えてからqevalしていく.
入れ子になっていた場合もqevalでまたcojoinに送られるので対処出来る.
ただ問題文通りだと,必要な変数を満たす表明が現れたらすぐにnotを実行しなければいけないが,それは難しかったので妥協.
(define (conjoin conjuncts frame-stream)
(let ((new (bring-filter-behind conjuncts)))
(if (empty-conjunction? new)
frame-stream
(conjoin (rest-conjuncts new)
(qeval (first-conjunct new)
frame-stream)))))
(put 'and 'qeval conjoin)
(define (filter? exp) (or (eq? exp 'not) (eq? exp 'lisp-value)))
(define (bring-filter-behind conjuncts)
(let iter ((conjuncts conjuncts) (infront '()) (behind '()))
(cond ((null? conjuncts) (append infront behind))
(let ((first (first-conjunct conjuncts))
(rest (rest-conjuncts conjuncts)))
(cond ((filter? (type first))
(iter rest infront (append behind first)))
(else
(iter rest (append infront first) behind)))))))
4.78と4.79はパス.