Blame


1 665c255d 2023-08-04 jrmu (define (celsius-fahrenheit-converter c f)
2 665c255d 2023-08-04 jrmu (let ((u (make-connector))
3 665c255d 2023-08-04 jrmu (v (make-connector))
4 665c255d 2023-08-04 jrmu (w (make-connector))
5 665c255d 2023-08-04 jrmu (x (make-connector))
6 665c255d 2023-08-04 jrmu (y (make-connector)))
7 665c255d 2023-08-04 jrmu (multiplier c w u)
8 665c255d 2023-08-04 jrmu (multiplier v x u)
9 665c255d 2023-08-04 jrmu (adder v y f)
10 665c255d 2023-08-04 jrmu (constant 9 w)
11 665c255d 2023-08-04 jrmu (constant 5 x)
12 665c255d 2023-08-04 jrmu (constant 32 y)
13 665c255d 2023-08-04 jrmu 'ok))
14 665c255d 2023-08-04 jrmu
15 665c255d 2023-08-04 jrmu (define (adder a1 a2 sum)
16 665c255d 2023-08-04 jrmu (define (process-new-value)
17 665c255d 2023-08-04 jrmu (cond ((and (has-value? a1) (has-value? a2))
18 665c255d 2023-08-04 jrmu (set-value! sum
19 665c255d 2023-08-04 jrmu (+ (get-value a1) (get-value a2))
20 665c255d 2023-08-04 jrmu me))
21 665c255d 2023-08-04 jrmu ((and (has-value? a1) (has-value? sum))
22 665c255d 2023-08-04 jrmu (set-value! a2
23 665c255d 2023-08-04 jrmu (- (get-value sum) (get-value a1))
24 665c255d 2023-08-04 jrmu me))
25 665c255d 2023-08-04 jrmu ((and (has-value? a2) (has-value? sum))
26 665c255d 2023-08-04 jrmu (set-value! a1
27 665c255d 2023-08-04 jrmu (- (get-value sum) (get-value a2))
28 665c255d 2023-08-04 jrmu me))))
29 665c255d 2023-08-04 jrmu (define (process-forget-value)
30 665c255d 2023-08-04 jrmu (forget-value! sum me)
31 665c255d 2023-08-04 jrmu (forget-value! a1 me)
32 665c255d 2023-08-04 jrmu (forget-value! a2 me)
33 665c255d 2023-08-04 jrmu (process-new-value))
34 665c255d 2023-08-04 jrmu (define (me request)
35 665c255d 2023-08-04 jrmu (cond ((eq? request 'I-have-a-value)
36 665c255d 2023-08-04 jrmu (process-new-value))
37 665c255d 2023-08-04 jrmu ((eq? request 'I-lost-my-value)
38 665c255d 2023-08-04 jrmu (process-forget-value))
39 665c255d 2023-08-04 jrmu (else
40 665c255d 2023-08-04 jrmu (error "Unknown request -- ADDER" request))))
41 665c255d 2023-08-04 jrmu (connect a1 me)
42 665c255d 2023-08-04 jrmu (connect a2 me)
43 665c255d 2023-08-04 jrmu (connect sum me)
44 665c255d 2023-08-04 jrmu me)
45 665c255d 2023-08-04 jrmu
46 665c255d 2023-08-04 jrmu (define (inform-about-value constraint)
47 665c255d 2023-08-04 jrmu (constraint 'I-have-a-value))
48 665c255d 2023-08-04 jrmu (define (inform-about-no-value constraint)
49 665c255d 2023-08-04 jrmu (constraint 'I-lost-my-value))
50 665c255d 2023-08-04 jrmu
51 665c255d 2023-08-04 jrmu (define (multiplier m1 m2 product)
52 665c255d 2023-08-04 jrmu (define (process-new-value)
53 665c255d 2023-08-04 jrmu (cond ((or (and (has-value? m1) (= (get-value m1) 0))
54 665c255d 2023-08-04 jrmu (and (has-value? m2) (= (get-value m2) 0)))
55 665c255d 2023-08-04 jrmu (set-value! product 0 me))
56 665c255d 2023-08-04 jrmu ((and (has-value? m1) (has-value? m2))
57 665c255d 2023-08-04 jrmu (set-value! product
58 665c255d 2023-08-04 jrmu (* (get-value m1) (get-value m2))
59 665c255d 2023-08-04 jrmu me))
60 665c255d 2023-08-04 jrmu ((and (has-value? product) (has-value? m1))
61 665c255d 2023-08-04 jrmu (set-value! m2
62 665c255d 2023-08-04 jrmu (/ (get-value product) (get-value m1))
63 665c255d 2023-08-04 jrmu me))
64 665c255d 2023-08-04 jrmu ((and (has-value? product) (has-value? m2))
65 665c255d 2023-08-04 jrmu (set-value! m1
66 665c255d 2023-08-04 jrmu (/ (get-value product) (get-value m2))
67 665c255d 2023-08-04 jrmu me))))
68 665c255d 2023-08-04 jrmu (define (process-forget-value)
69 665c255d 2023-08-04 jrmu (forget-value! product me)
70 665c255d 2023-08-04 jrmu (forget-value! m1 me)
71 665c255d 2023-08-04 jrmu (forget-value! m2 me)
72 665c255d 2023-08-04 jrmu (process-new-value))
73 665c255d 2023-08-04 jrmu (define (me request)
74 665c255d 2023-08-04 jrmu (cond ((eq? request 'I-have-a-value)
75 665c255d 2023-08-04 jrmu (process-new-value))
76 665c255d 2023-08-04 jrmu ((eq? request 'I-lost-my-value)
77 665c255d 2023-08-04 jrmu (process-forget-value))
78 665c255d 2023-08-04 jrmu (else
79 665c255d 2023-08-04 jrmu (error "Unknown request -- MULTIPLIER" request))))
80 665c255d 2023-08-04 jrmu (connect m1 me)
81 665c255d 2023-08-04 jrmu (connect m2 me)
82 665c255d 2023-08-04 jrmu (connect product me)
83 665c255d 2023-08-04 jrmu me)
84 665c255d 2023-08-04 jrmu
85 665c255d 2023-08-04 jrmu (define (constant value connector)
86 665c255d 2023-08-04 jrmu (define (me request)
87 665c255d 2023-08-04 jrmu (error "Unknown request -- CONSTANT" request))
88 665c255d 2023-08-04 jrmu (connect connector me)
89 665c255d 2023-08-04 jrmu (set-value! connector value me)
90 665c255d 2023-08-04 jrmu me)
91 665c255d 2023-08-04 jrmu
92 665c255d 2023-08-04 jrmu (define (probe name connector)
93 665c255d 2023-08-04 jrmu (define (print-probe value)
94 665c255d 2023-08-04 jrmu (newline)
95 665c255d 2023-08-04 jrmu (display "Probe: ")
96 665c255d 2023-08-04 jrmu (display name)
97 665c255d 2023-08-04 jrmu (display " = ")
98 665c255d 2023-08-04 jrmu (display value))
99 665c255d 2023-08-04 jrmu (define (process-new-value)
100 665c255d 2023-08-04 jrmu (print-probe (get-value connector)))
101 665c255d 2023-08-04 jrmu (define (process-forget-value)
102 665c255d 2023-08-04 jrmu (print-probe "?"))
103 665c255d 2023-08-04 jrmu (define (me request)
104 665c255d 2023-08-04 jrmu (cond ((eq? request 'I-have-a-value)
105 665c255d 2023-08-04 jrmu (process-new-value))
106 665c255d 2023-08-04 jrmu ((eq? request 'I-lost-my-value)
107 665c255d 2023-08-04 jrmu (process-forget-value))
108 665c255d 2023-08-04 jrmu (else
109 665c255d 2023-08-04 jrmu (error "Unknown request -- PROBE" request))))
110 665c255d 2023-08-04 jrmu (connect connector me)
111 665c255d 2023-08-04 jrmu me)
112 665c255d 2023-08-04 jrmu
113 665c255d 2023-08-04 jrmu (define (make-connector)
114 665c255d 2023-08-04 jrmu (let ((value false) (informant false) (constraints '()))
115 665c255d 2023-08-04 jrmu (define (set-my-value newval setter)
116 665c255d 2023-08-04 jrmu (cond ((not (has-value? me))
117 665c255d 2023-08-04 jrmu (set! value newval)
118 665c255d 2023-08-04 jrmu (set! informant setter)
119 665c255d 2023-08-04 jrmu (for-each-except setter
120 665c255d 2023-08-04 jrmu inform-about-value
121 665c255d 2023-08-04 jrmu constraints))
122 665c255d 2023-08-04 jrmu ((not (= value newval))
123 665c255d 2023-08-04 jrmu (error "Contradiction" (list value newval)))
124 665c255d 2023-08-04 jrmu (else 'ignored)))
125 665c255d 2023-08-04 jrmu (define (forget-my-value retractor)
126 665c255d 2023-08-04 jrmu (if (eq? retractor informant)
127 665c255d 2023-08-04 jrmu (begin (set! informant false)
128 665c255d 2023-08-04 jrmu (for-each-except retractor
129 665c255d 2023-08-04 jrmu inform-about-no-value
130 665c255d 2023-08-04 jrmu constraints))
131 665c255d 2023-08-04 jrmu 'ignored))
132 665c255d 2023-08-04 jrmu (define (connect new-constraint)
133 665c255d 2023-08-04 jrmu (if (not (memq new-constraint constraints))
134 665c255d 2023-08-04 jrmu (set! constraints
135 665c255d 2023-08-04 jrmu (cons new-constraint constraints)))
136 665c255d 2023-08-04 jrmu (if (has-value? me)
137 665c255d 2023-08-04 jrmu (inform-about-value new-constraint))
138 665c255d 2023-08-04 jrmu 'done)
139 665c255d 2023-08-04 jrmu (define (me request)
140 665c255d 2023-08-04 jrmu (cond ((eq? request 'has-value?)
141 665c255d 2023-08-04 jrmu (if informant true false))
142 665c255d 2023-08-04 jrmu ((eq? request 'value) value)
143 665c255d 2023-08-04 jrmu ((eq? request 'set-value!) set-my-value)
144 665c255d 2023-08-04 jrmu ((eq? request 'forget) forget-my-value)
145 665c255d 2023-08-04 jrmu ((eq? request 'connect) connect)
146 665c255d 2023-08-04 jrmu (else (error "Unknown operation -- CONNECTOR"
147 665c255d 2023-08-04 jrmu request))))
148 665c255d 2023-08-04 jrmu me))
149 665c255d 2023-08-04 jrmu
150 665c255d 2023-08-04 jrmu (define (for-each-except exception procedure list)
151 665c255d 2023-08-04 jrmu (define (loop items)
152 665c255d 2023-08-04 jrmu (cond ((null? items) 'done)
153 665c255d 2023-08-04 jrmu ((eq? (car items) exception) (loop (cdr items)))
154 665c255d 2023-08-04 jrmu (else (procedure (car items))
155 665c255d 2023-08-04 jrmu (loop (cdr items)))))
156 665c255d 2023-08-04 jrmu (loop list))
157 665c255d 2023-08-04 jrmu
158 665c255d 2023-08-04 jrmu (define (has-value? connector)
159 665c255d 2023-08-04 jrmu (connector 'has-value?))
160 665c255d 2023-08-04 jrmu (define (get-value connector)
161 665c255d 2023-08-04 jrmu (connector 'value))
162 665c255d 2023-08-04 jrmu (define (set-value! connector new-value informant)
163 665c255d 2023-08-04 jrmu ((connector 'set-value!) new-value informant))
164 665c255d 2023-08-04 jrmu (define (forget-value! connector retractor)
165 665c255d 2023-08-04 jrmu ((connector 'forget) retractor))
166 665c255d 2023-08-04 jrmu (define (connect connector new-constraint)
167 665c255d 2023-08-04 jrmu ((connector 'connect) new-constraint))
168 665c255d 2023-08-04 jrmu
169 665c255d 2023-08-04 jrmu (define (test-case actual expected)
170 665c255d 2023-08-04 jrmu (newline)
171 665c255d 2023-08-04 jrmu (display "Actual: ")
172 665c255d 2023-08-04 jrmu (display actual)
173 665c255d 2023-08-04 jrmu (newline)
174 665c255d 2023-08-04 jrmu (display "Expected: ")
175 665c255d 2023-08-04 jrmu (display expected)
176 665c255d 2023-08-04 jrmu (newline))
177 665c255d 2023-08-04 jrmu
178 665c255d 2023-08-04 jrmu ;; Exercise 3.33. Using primitive multiplier, adder, and constant constraints, define a procedure averager that takes three connectors a, b, and c as inputs and establishes the constraint that the value of c is the average of the values of a and b.
179 665c255d 2023-08-04 jrmu
180 665c255d 2023-08-04 jrmu (define (averager a b c)
181 665c255d 2023-08-04 jrmu (let ((sum (make-connector))
182 665c255d 2023-08-04 jrmu (two (make-connector)))
183 665c255d 2023-08-04 jrmu (adder a b sum)
184 665c255d 2023-08-04 jrmu (constant 2 two)
185 665c255d 2023-08-04 jrmu (multiplier two c sum)))
186 665c255d 2023-08-04 jrmu
187 665c255d 2023-08-04 jrmu (define five (make-connector))
188 665c255d 2023-08-04 jrmu (define three (make-connector))
189 665c255d 2023-08-04 jrmu (define avg (make-connector))
190 665c255d 2023-08-04 jrmu (constant 5 five)
191 665c255d 2023-08-04 jrmu (constant 3 three)
192 665c255d 2023-08-04 jrmu (averager five three avg)
193 665c255d 2023-08-04 jrmu (test-case (get-value avg) 4)