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はパス.