今年最後

今年分は今日で最後。年明け以降はいつまでできるのだろうか。
進められる分は先に進めておきたいのですが、おっさんへろへろなのと今日は諸々の用件が入っていたのとで微妙に無理矢理終わった感がありました。申し訳ない。

今日は

3.3.4 のデジタル回路のシミュレータ、な節。色々喧喧諤諤しつつ問題 3.31 に到達。整理という所で_シミュレーションの例_にて例示されているソレを辿りつつ諸々確認してみる事に。
順に。

(define input-1 (make-wire))
(define input-2 (make-wire))
(define sum (make-wire))
(define carry (make-wire))

これで二つの内部手続きと signal-value と action-procedures という private な属性を持ったオブジェクトが四つでき上がる。次に probe な手続きをまず sum という wire について適用。

(probe 'sum sum)
sum 0 New-value = 0

probe は add-action! の wrapper です。直下な出力を sum が持つ action-procedures に追加しつつ一回呼び出します。carry についても同様に以下。

(probe 'carry carry)
carry 0 New-value = 0

で回線を半加算器に接続との事。

(half-adder input-1 input-2 sum carry)

ええと、これでどうなるか、というと

  • input-1
    • or-gate-procedure と and-gate-procedure が action-procedures に格納される
  • input-2
    • or-gate-procedure と and-gate-procedure が action-procedures に格納される
  • sum
    • probe が action-procedures に格納されている
  • carry
    • probe が action-procedures に格納されている

ええとここが核心のはずなのでもう少し精緻に確認が必要かな。ええと、half-adder の定義が以下。

(define (half-adder a b s c)
  (let ((d (make-wire)) (e (make-wire)))
    (or-gate a b d)
    (and-gate a b c)
    (inverter c e)
    (and-gate d e s)
    'ok))

まず最初の or-gate 手続きが呼び出されるはず。内部手続き or-action-procedure が定義されてて a と b に対して add-action! してるはず。

(add-action! input-1 or-action-procedure)
(add-action! input-2 or-action-procedure)

これで何が起きるかというと input-1 の action-procefures に or-action-procedure が追加されて、一回呼び出されます。input-2 についても同様。or-action-procedure は以下なカンジになりますでしょうか。

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

ここで after-delay が呼び出されるのがポイント高い、というのが相方の主張。after-delay の定義が以下との事。

(define (after-delay delay action)
  (add-to-agenda! (+ delay (current-time the-agenda))
                  action
                  the-agenda))

set-signal! な thunk が the-agenda に登録されている。165p で出てくる propagate 手続きは the-agenda な次第書きに登録されている手続きを実行するものになってます。
ここも微妙にこんがらがる所かも。

ええと

  • 半加算器作った時点で
    • input-1 に or と and な action-procedure が action-procedures 属性に登録されて一回実行
    • input-2 に or と and な action-procedure が action-procedures 属性に登録されて一回実行
    • carry に inverter な action-procedure が action-procedures 属性に登録されて一回実行

ちなみに carry と sum には probe なソレも設定済み。というか実行されても次第書きに登録された thunk は実行されていないので set-signal! はまだ実行されてない。
という事は half-adder 手続きを実行した時点では、次第書きな the-agenda に上記の action-procedure 達が登録されました、という事でしかないのか。
で、結局の所、(propagate) しないと何も始まらないし、その時点で the-agenda に諸々の手続きが登録されていないと何も起きないのか。

うーん

なんか思考がループを始めたので止めます。