(wat-aro)

生きてます

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