exercise 3.30

やることがあるのに気づいたら飲み会行って、その後寝てしまった・・・。

とりあえず朝に書いたコードでも張っとくか。

(define (make-wire-list n)                                                      
  (if (= 0 n)                                                                   
      '()                                                                       
      (cons (make-wire) (make-wire-list (- n 1)))))                             
                                                                                
(define (set-nbit-signal! wires signals)                                         
  (define (iter wires signals)                                                  
    (cond ((null? wires) 'ok)                                                   
          (else (set-signal! (car wires) (car signals))                         
                (set-nbit-signal! (cdr wires) (cdr signals)))))                  
  (if (not (= (length wires) (length signals)))                                 
      (error "Length of signals is wrong!!" (list wires signals))               
      (iter wires signals)))                                                    
                                                                                
(define (get-nbit-signal wires)                                                 
  (if (null? wires)                                                             
      '()                                                                       
      (cons (get-signal (car wires))                                            
            (get-nbit-signal (cdr wires)))))                                    
                                                                                
(define (ripple-carry-adder A B S c)                                            
  (define (iter A B S c)                                                        
    (cond ((null? S)                                                            
           (set-signal! c 0))                                                   
          (else                                                                 
           (let ((c-next (make-wire)))                                          
             (full-adder (car A) (car B) c-next (car S) c)                      
             (iter (cdr A) (cdr B) (cdr S) c-next)))))                          
  (iter A B S c))   

ripple-carry adderの中で再帰をしていくとc-nextが繰り返し作られるので、名前被ってまずいかなと悩んだが、よくよく考えてみれば再帰で呼び出すごとに新しい環境を作っていくので大丈夫だろう、たぶん。
ちなみに実行結果は以下の通り。

gosh> (define a (make-wire-list 6))                                             
a                                                                               
gosh> (define b (make-wire-list 6))                                             
b                                                                               
gosh> (define s (make-wire-list 6))                                             
s                                                                               
gosh> (define c (make-wire))                                                    
c                                                                               
gosh> (ripple-carry-adder a b s c)                                              
done                                                                            
gosh> (set-nbit-signal! a '(1 1 0 1 0 1))                                       
ok                                                                              
gosh> (set-nbit-signal! b '(1 0 1 1 1 1))                                       
ok                                                                              
gosh> (propagate)                                                               
done                                                                            
gosh> (get-nbit-signal s)                                                       
(1 0 0 1 0 0)                                                                   
gosh> (get-signal c)                                                            
1              

まぁ多分うまく行ってるでしょう。
しかし、ここのセクションは後半の奴まで書いとかないと実行できないのが面倒。
あと、最初はfull-adderとかが何やってるか分からんかった。こういうときは素直に翻訳版が欲しくなったりもする。まぁでも結果的に何とか理解できて満足。

問題には実行時間も考えろとあるが、今日は他にもやることがあるのでそっちが済んでからかなぁ。