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のままになっていて、おかしなことになっている。