sicp-3-3-4

Posted on 2015-02-28 07:36:07 +0900 in SICP Lisp

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!

----------------------------------- 本文内容遵从CC版权协议转载请注明出自kamelzcs -----------------------------------
«  | sicp-3-3-3 »

Hide Comments

comments powered by Disqus