2015/12/25

SICP4章 真理値のせいではまった.

(define (append x y)
  (if (null? x)
      y
      (cons (car x)
            (append (cdr x) y))))

これが動かなかったんですよ.
はじめはeval-sequenceで(first-exp exp)をevalしていなかったとかそういうのだったんですけど,
どうしても動かなくて.
debug printでも(null? x)が#fになってるのになぜかyが返ってくるんです.

eval-ifはtrue?で真偽が決まります.

(define (eval-if exp env)
  (if (true? (eval (if-predicate exp) env))
      (eval (if-consequent exp) env)
      (eval (if-alternative exp) env)))

(define (true? x)
  (not (eq? x 'false)))
(define (false? x)
  (eq? x 'false))

(define (setup-environment)
  (let ((initial-env
         (extend-environment (primitive-procedure-names)
                             (primitive-procedure-objects)
                             the-empty-environment)))
    (define-variable! 'true true initial-env)
    (define-variable! 'false false initial-env)
    initial-env))

散々迷ってここが原因だとわかりました.
SICPでは#tや#fじゃなくてtrue,falseになっています.
他のコードも統一するために

(define true #t)
(define false #f)

としていたのが裏目にでました.
ここで作ったdebug printで#fとなっていてもこの評価器はtrueを返しているというややこしいことになっていました.
eval-ifも間違っていない.選択子も正しくできている.
null?も問題ない.(null? x)のxはきちんと'(a b c)に束縛されている.
可能性を全部潰してやっとここに行き着きました.
全部を#tと#fに統一してやっと解決しました.
これは辛かった.

(define (true? x)
  (not (eq? x '#f)))
(define (false? x)
  (eq? x '#f))

(define (setup-environment)
  (let ((initial-env
         (extend-environment (primitive-procedure-names)
                             (primitive-procedure-objects)
                             the-empty-environment)))
    (define-variable! '#t #t initial-env)
    (define-variable! '#f #f initial-env)
    initial-env))

超循環評価器はこういう時厳しいですね.


© 2022 wat-aro