関数型言語の勉強にSICPを読もう - (40) 3章 - 標準部品化力、オブジェクトおよび状態 (156-163ページ)

待ちに待っていたデジタル回路のシミュレーション。
オラ、何だかワクワクしてきたぞ!

問題3.24-27

略。

問題3.28

and とほぼ同じ。
今の段階では add-action の実装が見えないので or-action-procedure が2回呼ばれておかしくなるんじゃないかと心配。
と思ったけどよく考えれば入力は同時に届くことはありえないのでこれで正しい。

(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)

問題3.29

inverter と and-gate を利用して or-gate 。


図の通り、遅延は and-gate-delay + inverter-delay * 2である。

(define (or-gate a1 a2 output)
  (let ((b (make-wire)) (c (make-wire)) (d (make-wire)))
    (inverter a1 b)
    (inverter a2 c)
    (and-gate b c d)
    (inverter d output)
    'ok))


間違っていたので修正しました。 tarosukeさんに感謝。

問題3.30

半加算器とか全加算器とか理解が怪しく、SICPだけだといまいち分からなかったので調べた。

半加算器(half adder)は、2進数の1つの桁を演算し、桁上がりは桁上げ出力(Carry out)によって出力する。AND、OR、NOTの3種類の論理回路のみで構成できる。 入力A、入力B、出力(S)、桁上げ出力(C)の関係を示す真理値表は次の通り。


分かった!
Monaの開発のときにインテルのマニュアルを読んでいると、「キャリーフラグが・・・」とかそういう記述を見かけたのはこのことだったのか。
SICP万歳!ありがとうありがとう!


2桁の場合どうなるか?を頭の中で考えたら分かったのでいざ n桁へ。

(define (ripple-carry-adder a-list b-list s-list cout)
  (define (ripple-carry-adder-iter as bs ss cn-1)
    (if (pair? as)
        (let ((an (car as))
              (bn (car bs))
              (sn (car ss))
              (cn (make-wire)))
          (full-adder an bn cn-1 sn cn)
          (ripple-carry-adder-iter (cdr as) (cdr bs) (cdr ss) cn)))
    'ok)
  (ripple-carry-adder-iter a-list b-list s-list (make-wire)))


まだ未実装の手続きがあるのでテストできないのが玉に瑕。
あとでまとめてテストします。


※「SICPを読もう」の目次はこちら


計算機プログラムの構造と解釈
Gerald Jay Sussman Julie Sussman Harold Abelson 和田 英一
ピアソンエデュケーション (2000/02)
売り上げランキング: 56,404