sicp-3-3-4
Posted on 2015-02-28 07:36:07 +0900 in SICP
3.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)
3.29
(define (or-gate a1 a2 output)
(define (or-action-procedure)
(let ((not-a1 (make-wire))
(not-a2 (make-wire))
(b (make-wire))
)
(inverter a1 not-a1)
(inverter a2 not-a2)
(and-gate not-a1 not-a2 b)
(inverter b result)))
(add-action! a1 or-action-procedure)
(add-action! a2 or-action-procedure)
'ok)
2 * inverter + and-gate
3.30
(define (ripple-carry-adder A B S C)
(let ((c-middle (make-wire)))
(if (null? (cdr A))
(set-signal! c-middle 0)
(ripple-carry-adder (cdr A) (cdr B) (cdr S) c-middle))
(full-adder (car A) (car B) c-middle (car S) C)))
3.31
After calling it immediatly, the initial value of the circuit is propagated.
But there is somoe overhead here, in the and-date
function, both a1
and a2
will call the and-function-procedure
, there would be two function calls and yield
two same results, one of which will be looked over by the set-my-signal
function.
3.32
(define (make-wire)
(let ((signal-value 0) (action-procedures '()))
(define (set-my-signal! new-value)
(if (not (= signal-value new-value))
(begin (set! signal-value new-value)
(call-each action-procedures))
'done))
(define (accept-action-procedure! proc)
(set! action-procedures (cons proc action-procedures))
(proc))
(define (dispatch m)
(cond ((eq? m 'get-signal) signal-value)
((eq? m 'set-signal!) set-my-signal!)
((eq? m 'add-action!) accept-action-procedure!)
(else (error "Unknown operation -- WIRE" m))))
dispatch))
(define (and-gate a1 a2 output)
(define (and-action-procedure)
(let ((new-value
(logical-and (get-signal a1) (get-signal a2))))
(after-delay and-gate-delay
(lambda ()
(set-signal! output new-value)))))
(add-action! a1 and-action-procedure)
(add-action! a2 and-action-procedure)
'ok)
It is important to note that set-my-value
will set the state and
push the procedure into the queue of the agenda.
(define a (make-wire))
(define b (make-wire))
(define o (make-wire))
(and-gate a b o)
(propagate)
(set-signal! a 0)
(set-signal! b 1)
(propagate)
(set-signal! a 1)
(set-signal! b 0)
(propagate)
When a
changed from 0
to 1
, output=1
is pushed to the agenda queue,
in the following, when b
changed from 1
to 0
, output=0
is pushed to the agenda queue.
If FIFO
is used in the agenda, the final result would be output=0
, otherwise,
FILO
is used, the final result would be output=1
, which is not the correct answer at all!