4 (define (adder a1 a2 sum)
5 (define (process-new-value)
6 (cond ((and (has-value? a1) (has-value? a2))
8 (+ (get-value a1) (get-value a2))
10 ((and (has-value? a1) (has-value? sum))
12 (- (get-value sum) (get-value a1))
14 ((and (has-value? a2) (has-value? sum))
16 (- (get-value sum) (get-value a2))
18 (define (process-forget-value)
19 (forget-value! sum me)
24 (cond ((eq? request 'I-have-a-value)
26 ((eq? request 'I-lost-my-value)
27 (process-forget-value))
29 (error "Unknown request -- ADDER" request))))
35 (define (multiplier m1 m2 product)
36 (define (process-new-value)
37 (cond ((or (and (has-value? m1) (= (get-value m1) 0))
38 (and (has-value? m2) (= (get-value m2) 0)))
39 (set-value! product 0 me))
40 ((and (has-value? m1) (has-value? m2))
42 (* (get-value m1) (get-value m2))
44 ((and (has-value? product) (has-value? m1))
46 (/ (get-value product) (get-value m1))
48 ((and (has-value? product) (has-value? m2))
50 (/ (get-value product) (get-value m2))
52 (define (process-forget-value)
53 (forget-value! product me)
58 (cond ((eq? request 'I-have-a-value)
60 ((eq? request 'I-lost-my-value)
61 (process-forget-value))
63 (error "Unknown request -- MULTIPLIER" request))))
69 (define (constant value connector)
71 (error "Unknown request -- CONSTANT" request))
72 (connect connector me)
73 (set-value! connector value me)
76 (define (probe name connector)
77 (define (print-probe value)
83 (define (process-new-value)
84 (print-probe (get-value connector)))
85 (define (process-forget-value)
88 (cond ((eq? request 'I-have-a-value)
90 ((eq? request 'I-lost-my-value)
91 (process-forget-value))
93 (error "Unknown request -- PROBE" request))))
94 (connect connector me)
97 (define (inform-about-value constraint)
98 (constraint 'I-have-a-value))
99 (define (inform-about-no-value constraint)
100 (constraint 'I-lost-my-value))
102 (define (make-connector)
103 (let ((value false) (informant #f) (constraints '()))
104 (define (set-my-value newval setter)
105 (cond ((not (has-value? me))
107 (set! informant setter)
108 (for-each-except setter
111 ((not (= value newval))
112 (error "Contradiction" (list value newval)))
114 (define (forget-my-value retractor)
115 (if (eq? retractor informant)
116 (begin (set! informant false)
117 (for-each-except retractor
118 inform-about-no-value
121 (define (connect new-constraint)
122 (when (not (memq new-constraint constraints))
124 (cons new-constraint constraints)))
125 (when (has-value? me)
126 (inform-about-value new-constraint))
129 (cond ((eq? request 'has-value?)
130 (if informant #t #f))
131 ((eq? request 'value) value)
132 ((eq? request 'set-value!) set-my-value)
133 ((eq? request 'forget) forget-my-value)
134 ((eq? request 'connect) connect)
135 (else (error "Unknown operation -- CONNECTOR"
139 (define (for-each-except exception procedure list)
141 (cond ((null? items) 'done)
142 ((eq? (car items) exception) (loop (cdr items)))
143 (else (procedure (car items))
144 (loop (cdr items)))))
147 (define (has-value? connector)
148 (connector 'has-value?))
149 (define (get-value connector)
151 (define (set-value! connector new-value informant)
152 ((connector 'set-value!) new-value informant))
153 (define (forget-value! connector retractor)
154 ((connector 'forget) retractor))
155 (define (connect connector new-constraint)
156 ((connector 'connect) new-constraint))
158 (define (squarer a b)
159 (define (process-new-value)
161 (if (< (get-value b) 0)
162 (error "square less than 0 -- SQUARER" (get-value b))
168 (* (get-value a) (get-value a))
170 (define (process-forget-value)
175 (cond ((eq? request 'I-have-a-value)
177 ((eq? request 'I-lost-my-value)
178 (process-forget-value))
180 (error "Unknown request -- SQUARER" request))))
185 (define d (make-connector))
186 (define e (make-connector))
190 (probe "input to the squarer" d)
191 (probe "squarer output" e)