exercise 3.31
コミケで買った同人も消費したのでやることが済んだのでSICP再開。というかそろそろICPCの練習とかも再開したいが、それは別の話か。
問題はmake-wireの中のaccept-action-procedure!がprocedureの登録時に一度そのprocを読んでるのは何故か?って話。
(英単語ばっかだと変な文章に見えるな。詳しくは本文で…)
これをやってる理由は、inverterの初期化のため(・・・と思う)
とりあえず以下に実験したサンプルでも載せてみる。
inverterのテスト。
(define a (make-wire)) (define b (make-wire)) (probe 'a a) (probe 'b b) (inverter a b) (propagate)
accept-action-procedure!に変更を加えないと
gosh> a 0 New-value = 0 b 0 New-value = 0 b 2 New-value = 1 #t
変更あり
(define (accept-action-procedure! proc)
(set! action-procedures (cons proc action-procedures)))
と言う風に(proc)の部分を削除すると
…何も出てこない。まぁprobeも呼ばれないので当然か。
一応値を確認して置くと
gosh> (get-signal b) 0
みたくbの値が初期値のままで、inverterの影響がなくなってる。
もちろん一度aの値を変更して元に戻せば正しい結果になるけど。
では実際にhalf-adderでもトレースしてみる
試してみたのは
(define a (make-wire)) (define b (make-wire)) (define c (make-wire)) (define d (make-wire)) (define e (make-wire)) (define s (make-wire)) (probe 'a a) (probe 'b b) (probe 's s) (probe 'c c) (probe 'd d) (probe 'e e) (or-gate a b d) (and-gate a b c) (inverter c e) (and-gate d e s) (propagate) (set-signal! a 1) (propagate) (set-signal! b 1) (propagate)
まずはaccept-action-procedure!に変更を加えない場合
gosh> a 0 New-value = 0 b 0 New-value = 0 s 0 New-value = 0 c 0 New-value = 0 d 0 New-value = 0 e 0 New-value = 0 e 2 New-value = 1 a 5 New-value = 1 d 10 New-value = 1 s 13 New-value = 1 b 13 New-value = 1 c 16 New-value = 1 e 18 New-value = 0 s 21 New-value = 0 #t
変更あり
a 0 New-value = 1 d 5 New-value = 1 b 8 New-value = 1 c 11 New-value = 1
と言う感じ。ちょっと分かりにくいが(実際初期化が行われないのでかかる時間も違ってて比べにくい)ゆっくり見ていけばinverterの初期化が行われていないので、回路をつないだときのeの値が0のままになっていて、おかしなことになっている。