1 (define (celsius-fahrenheit-converter c f)
2 (let ((five (make-connector))
3 (nine (make-connector))
4 (three-two (make-connector))
5 (product (make-connector))
6 (difference (make-connector)))
9 (constant 32 three-two)
10 (multiplier nine c product)
11 (adder difference three-two f)
12 (multiplier difference five product)
14 (define (inform-about-value constraint)
15 (constraint 'I-have-a-value))
16 (define (inform-about-no-value constraint)
17 (constraint 'I-lost-my-value))
19 (define (adder a1 a2 sum)
20 (define (process-new-value)
21 (cond ((and (has-value? a1) (has-value? a2))
26 ((and (has-value? a1) (has-value? sum))
31 ((and (has-value? a2) (has-value? sum))
35 (define (process-forget-value)
41 (cond ((eq? request 'I-have-a-value) (process-new-value))
42 ((eq? request 'I-lost-my-value) (process-forget-value))
43 (else (error "Unknown request -- ADDER" request))))
49 (define (multiplier m1 m2 product)
50 (define (process-new-value)
51 (cond ((or (and (has-value? m1) (= (get-value m1) 0))
52 (and (has-value? m2) (= (get-value m2) 0)))
53 (set-value! product 0 me))
54 ((and (has-value? m1) (has-value? m2))
59 ((and (has-value? m1) (has-value? product))
61 (/ (get-value product)
64 ((and (has-value? m2) (has-value? product))
66 (/ (get-value product)
69 (define (process-forget-value)
72 (forget-value! product me)
75 (cond ((eq? request 'I-have-a-value) (process-new-value))
76 ((eq? request 'I-lost-my-value) (process-forget-value))
77 (else (error "Unknown request -- MULTIPLIER" request))))
83 (define (constant value connector)
85 (error "Unknown request -- CONSTANT" request))
86 (set-value! connector value me)
88 (define (probe name connector)
89 (define (print-probe value)
95 (define (process-new-value)
96 (print-probe (get-value connector)))
97 (define (process-forget-value)
100 (cond ((eq? request 'I-have-a-value) (process-new-value))
101 ((eq? request 'I-lost-my-value) (process-forget-value))
102 (else (error "Unknown request -- PROBE" request))))
103 (connect connector me)
106 (define (has-value? connector)
107 (connector 'has-value?))
108 (define (get-value connector)
110 (define (set-value! connector value informant)
111 ((connector 'set-value!) value informant))
112 (define (forget-value! connector retractor)
113 ((connector 'forget-value!) retractor))
114 (define (connect connector constraint)
115 ((connector 'connect) constraint))
117 (define (for-each-except exception proc items)
118 (cond ((null? items) 'done)
119 ((eq? (car items) exception)
120 (for-each-except exception proc (cdr items)))
123 (for-each-except exception proc (cdr items)))))
125 (define (make-connector)
126 (let ((value false) (informant false) (constraints '()))
127 (define (set-value! newval setter)
131 (error "Contradiction: " (list value newval)))
132 (begin (set! informant setter)
134 (for-each-except setter
137 (define (forget-value! retractor)
138 (if (eq? informant retractor)
139 (begin (set! informant false)
140 (for-each-except retractor
141 inform-about-no-value
144 (define (connect constraint)
145 (if (memq constraint constraints)
147 (begin (set! constraints (cons constraint constraints))
149 (inform-about-value constraint)))))
151 (cond ((eq? request 'has-value?) (if informant true false))
152 ((eq? request 'value) value)
153 ((eq? request 'set-value!) set-value!)
154 ((eq? request 'forget-value!) forget-value!)
155 ((eq? request 'connect) connect)
156 (else (error "Unknown operation -- CONNECTOR" request))))