さかもとのブログ

つらつらと

SICP演習問題3.28~3.30

;;excercise3.28
(define (or-gate a1 a2 output)
  (define (or-action-procedure)
    (let ((new-value
           (logical-or (get-signal a1)
                       (get-signal a2))))
      (after-delay or-gate-delay
                   (lambda ()
                     (set-signal! output new-value)))))
  (add-action! a1 or-action-procedure)
  (add-action! a2 or-action-procedure)
  'ok)

(define (logical-or x y)
  (if (one-or-zero? x y)
      (if (and (= x 0) (= y 0)) 0 1)
      (error "Invalid signals" (list x y))))

;;excercise3.29
(define (or-gate a1 a2 output)
  (let ((output1 (make-wire))
        (output2 (make-wire))
        (output3 (make-wire)))
    (inverter a1 output1)
    (inverter a2 output2)
    (and-gate output1 output2 output3)
    (inverter output3 output))
  'ok)

;;excercise3.30
(define (ripple-carry-adder a-list b-list s-list c)
  (define (ripple-carry-adder-iter a-list b-list s-list c-in)
    (cond [(not (null? (cdr a)))
           (let ((c-out (make-wire)))
             (full-adder (car a-list)
                         (car b-list)
                         c-in
                         (car s-list)
                         c-out)
             (ripple-carry-adder-iter (cdr a-list) (cdr b-list) (cdr s-list) c-out))]
          [else
           (full-adder (car a-list)
                       (car b-list)
                       c-int
                       (car s-list)
                       c)])
    'ok)
  (ripple-carry-adder-iter a-list b-list s-list (make-wire)))

3.30は問題の意味が少しわかりくいが,図を見る限りでは,番号の小さい方が,桁が大きい.
また,初期値のcに最後の繰り上げの結果が格納されるので,aのcdrがnullならば,cに繰り上げ演算の結果を出力する.