Blame


1 665c255d 2023-08-04 jrmu ;; Exercise 3.28. Define an or-gate as a primitive function box. Your or-gate constructor should be similar to and-gate.
2 665c255d 2023-08-04 jrmu
3 665c255d 2023-08-04 jrmu (define (half-adder a b s c)
4 665c255d 2023-08-04 jrmu (let ((d (make-wire)) (e (make-wire)))
5 665c255d 2023-08-04 jrmu (or-gate a b d)
6 665c255d 2023-08-04 jrmu (and-gate a b c)
7 665c255d 2023-08-04 jrmu (inverter c e)
8 665c255d 2023-08-04 jrmu (and-gate d e s)
9 665c255d 2023-08-04 jrmu 'ok))
10 665c255d 2023-08-04 jrmu (define (full-adder a b c-in sum c-out)
11 665c255d 2023-08-04 jrmu (let ((s (make-wire))
12 665c255d 2023-08-04 jrmu (c1 (make-wire))
13 665c255d 2023-08-04 jrmu (c2 (make-wire)))
14 665c255d 2023-08-04 jrmu (half-adder b c-in s c1)
15 665c255d 2023-08-04 jrmu (half-adder a s sum c2)
16 665c255d 2023-08-04 jrmu (or-gate c1 c2 c-out)
17 665c255d 2023-08-04 jrmu 'ok))
18 665c255d 2023-08-04 jrmu (define (inverter input output)
19 665c255d 2023-08-04 jrmu (define (invert-input)
20 665c255d 2023-08-04 jrmu (let ((new-value (logical-not (get-signal input))))
21 665c255d 2023-08-04 jrmu (after-delay inverter-delay
22 665c255d 2023-08-04 jrmu (lambda ()
23 665c255d 2023-08-04 jrmu (set-signal! output new-value)))))
24 665c255d 2023-08-04 jrmu (add-action! input invert-input)
25 665c255d 2023-08-04 jrmu 'ok)
26 665c255d 2023-08-04 jrmu (define (logical-not s)
27 665c255d 2023-08-04 jrmu (cond ((= s 0) 1)
28 665c255d 2023-08-04 jrmu ((= s 1) 0)
29 665c255d 2023-08-04 jrmu (else (error "Invalid signal" s))))
30 665c255d 2023-08-04 jrmu
31 665c255d 2023-08-04 jrmu (define (and-gate a1 a2 output)
32 665c255d 2023-08-04 jrmu (define (logical-and x y)
33 665c255d 2023-08-04 jrmu (* x y))
34 665c255d 2023-08-04 jrmu (define (and-action-procedure)
35 665c255d 2023-08-04 jrmu (let ((new-value
36 665c255d 2023-08-04 jrmu (logical-and (get-signal a1) (get-signal a2))))
37 665c255d 2023-08-04 jrmu (after-delay and-gate-delay
38 665c255d 2023-08-04 jrmu (lambda ()
39 665c255d 2023-08-04 jrmu (set-signal! output new-value)))))
40 665c255d 2023-08-04 jrmu (add-action! a1 and-action-procedure)
41 665c255d 2023-08-04 jrmu (add-action! a2 and-action-procedure)
42 665c255d 2023-08-04 jrmu 'ok)
43 665c255d 2023-08-04 jrmu (define (make-wire)
44 665c255d 2023-08-04 jrmu (let ((signal-value 0) (action-procedures '()))
45 665c255d 2023-08-04 jrmu (define (set-my-signal! new-value)
46 665c255d 2023-08-04 jrmu (if (not (= signal-value new-value))
47 665c255d 2023-08-04 jrmu (begin (set! signal-value new-value)
48 665c255d 2023-08-04 jrmu (call-each action-procedures))
49 665c255d 2023-08-04 jrmu 'done))
50 665c255d 2023-08-04 jrmu (define (accept-action-procedure! proc)
51 665c255d 2023-08-04 jrmu (set! action-procedures (cons proc action-procedures))
52 665c255d 2023-08-04 jrmu (proc))
53 665c255d 2023-08-04 jrmu (define (dispatch m)
54 665c255d 2023-08-04 jrmu (cond ((eq? m 'get-signal) signal-value)
55 665c255d 2023-08-04 jrmu ((eq? m 'set-signal!) set-my-signal!)
56 665c255d 2023-08-04 jrmu ((eq? m 'add-action!) accept-action-procedure!)
57 665c255d 2023-08-04 jrmu (else (error "Unknown operation -- WIRE" m))))
58 665c255d 2023-08-04 jrmu dispatch))
59 665c255d 2023-08-04 jrmu (define (call-each procedures)
60 665c255d 2023-08-04 jrmu (if (null? procedures)
61 665c255d 2023-08-04 jrmu 'done
62 665c255d 2023-08-04 jrmu (begin
63 665c255d 2023-08-04 jrmu ((car procedures))
64 665c255d 2023-08-04 jrmu (call-each (cdr procedures)))))
65 665c255d 2023-08-04 jrmu (define (get-signal wire)
66 665c255d 2023-08-04 jrmu (wire 'get-signal))
67 665c255d 2023-08-04 jrmu (define (set-signal! wire new-value)
68 665c255d 2023-08-04 jrmu ((wire 'set-signal!) new-value))
69 665c255d 2023-08-04 jrmu (define (add-action! wire action-procedure)
70 665c255d 2023-08-04 jrmu ((wire 'add-action!) action-procedure))
71 665c255d 2023-08-04 jrmu (define (after-delay delay action)
72 665c255d 2023-08-04 jrmu (add-to-agenda! (+ delay (current-time the-agenda))
73 665c255d 2023-08-04 jrmu action
74 665c255d 2023-08-04 jrmu the-agenda))
75 665c255d 2023-08-04 jrmu (define (propagate)
76 665c255d 2023-08-04 jrmu (if (empty-agenda? the-agenda)
77 665c255d 2023-08-04 jrmu 'done
78 665c255d 2023-08-04 jrmu (let ((first-item (first-agenda-item the-agenda)))
79 665c255d 2023-08-04 jrmu (first-item)
80 665c255d 2023-08-04 jrmu (remove-first-agenda-item! the-agenda)
81 665c255d 2023-08-04 jrmu (propagate))))
82 665c255d 2023-08-04 jrmu (define (probe name wire)
83 665c255d 2023-08-04 jrmu (add-action! wire
84 665c255d 2023-08-04 jrmu (lambda ()
85 665c255d 2023-08-04 jrmu (newline)
86 665c255d 2023-08-04 jrmu (display name)
87 665c255d 2023-08-04 jrmu (display " ")
88 665c255d 2023-08-04 jrmu (display (current-time the-agenda))
89 665c255d 2023-08-04 jrmu (display " New-value = ")
90 665c255d 2023-08-04 jrmu (display (get-signal wire)))))
91 665c255d 2023-08-04 jrmu (define inverter-delay 2)
92 665c255d 2023-08-04 jrmu (define and-gate-delay 3)
93 665c255d 2023-08-04 jrmu (define or-gate-delay 5)
94 665c255d 2023-08-04 jrmu (define input-1 (make-wire))
95 665c255d 2023-08-04 jrmu (define input-2 (make-wire))
96 665c255d 2023-08-04 jrmu (define sum (make-wire))
97 665c255d 2023-08-04 jrmu (define carry (make-wire))
98 665c255d 2023-08-04 jrmu (define (make-time-segment time queue)
99 665c255d 2023-08-04 jrmu (cons time queue))
100 665c255d 2023-08-04 jrmu (define (segment-time s) (car s))
101 665c255d 2023-08-04 jrmu (define (segment-queue s) (cdr s))
102 665c255d 2023-08-04 jrmu (define (make-agenda) (list 0))
103 665c255d 2023-08-04 jrmu (define the-agenda (make-agenda))
104 665c255d 2023-08-04 jrmu (define (current-time agenda) (car agenda))
105 665c255d 2023-08-04 jrmu (define (set-current-time! agenda time)
106 665c255d 2023-08-04 jrmu (set-car! agenda time))
107 665c255d 2023-08-04 jrmu (define (segments agenda) (cdr agenda))
108 665c255d 2023-08-04 jrmu (define (set-segments! agenda segments)
109 665c255d 2023-08-04 jrmu (set-cdr! agenda segments))
110 665c255d 2023-08-04 jrmu (define (first-segment agenda) (car (segments agenda)))
111 665c255d 2023-08-04 jrmu (define (rest-segments agenda) (cdr (segments agenda)))
112 665c255d 2023-08-04 jrmu (define (empty-agenda? agenda)
113 665c255d 2023-08-04 jrmu (null? (segments agenda)))
114 665c255d 2023-08-04 jrmu (define (add-to-agenda! time action agenda)
115 665c255d 2023-08-04 jrmu (define (belongs-before? segments)
116 665c255d 2023-08-04 jrmu (or (null? segments)
117 665c255d 2023-08-04 jrmu (< time (segment-time (car segments)))))
118 665c255d 2023-08-04 jrmu (define (make-new-time-segment time action)
119 665c255d 2023-08-04 jrmu (let ((q (make-queue)))
120 665c255d 2023-08-04 jrmu (insert-queue! q action)
121 665c255d 2023-08-04 jrmu (make-time-segment time q)))
122 665c255d 2023-08-04 jrmu (define (add-to-segments! segments)
123 665c255d 2023-08-04 jrmu (if (= (segment-time (car segments)) time)
124 665c255d 2023-08-04 jrmu (insert-queue! (segment-queue (car segments))
125 665c255d 2023-08-04 jrmu action)
126 665c255d 2023-08-04 jrmu (let ((rest (cdr segments)))
127 665c255d 2023-08-04 jrmu (if (belongs-before? rest)
128 665c255d 2023-08-04 jrmu (set-cdr!
129 665c255d 2023-08-04 jrmu segments
130 665c255d 2023-08-04 jrmu (cons (make-new-time-segment time action)
131 665c255d 2023-08-04 jrmu (cdr segments)))
132 665c255d 2023-08-04 jrmu (add-to-segments! rest)))))
133 665c255d 2023-08-04 jrmu (let ((segments (segments agenda)))
134 665c255d 2023-08-04 jrmu (if (belongs-before? segments)
135 665c255d 2023-08-04 jrmu (set-segments!
136 665c255d 2023-08-04 jrmu agenda
137 665c255d 2023-08-04 jrmu (cons (make-new-time-segment time action)
138 665c255d 2023-08-04 jrmu segments))
139 665c255d 2023-08-04 jrmu (add-to-segments! segments))))
140 665c255d 2023-08-04 jrmu (define (remove-first-agenda-item! agenda)
141 665c255d 2023-08-04 jrmu (let ((q (segment-queue (first-segment agenda))))
142 665c255d 2023-08-04 jrmu (delete-queue! q)
143 665c255d 2023-08-04 jrmu (if (empty-queue? q)
144 665c255d 2023-08-04 jrmu (set-segments! agenda (rest-segments agenda)))))
145 665c255d 2023-08-04 jrmu (define (first-agenda-item agenda)
146 665c255d 2023-08-04 jrmu (if (empty-agenda? agenda)
147 665c255d 2023-08-04 jrmu (error "Agenda is empty -- FIRST-AGENDA-ITEM")
148 665c255d 2023-08-04 jrmu (let ((first-seg (first-segment agenda)))
149 665c255d 2023-08-04 jrmu (set-current-time! agenda (segment-time first-seg))
150 665c255d 2023-08-04 jrmu (front-queue (segment-queue first-seg)))))
151 665c255d 2023-08-04 jrmu (define (front-ptr queue) (car queue))
152 665c255d 2023-08-04 jrmu (define (rear-ptr queue) (cdr queue))
153 665c255d 2023-08-04 jrmu (define (set-front-ptr! queue item) (set-car! queue item))
154 665c255d 2023-08-04 jrmu (define (set-rear-ptr! queue item) (set-cdr! queue item))
155 665c255d 2023-08-04 jrmu (define (empty-queue? queue) (null? (front-ptr queue)))
156 665c255d 2023-08-04 jrmu (define (make-queue) (cons '() '()))(define (front-queue queue)
157 665c255d 2023-08-04 jrmu (if (empty-queue? queue)
158 665c255d 2023-08-04 jrmu (error "FRONT called with an empty queue" queue)
159 665c255d 2023-08-04 jrmu (car (front-ptr queue))))
160 665c255d 2023-08-04 jrmu (define (insert-queue! queue item)
161 665c255d 2023-08-04 jrmu (let ((new-pair (cons item '())))
162 665c255d 2023-08-04 jrmu (cond ((empty-queue? queue)
163 665c255d 2023-08-04 jrmu (set-front-ptr! queue new-pair)
164 665c255d 2023-08-04 jrmu (set-rear-ptr! queue new-pair)
165 665c255d 2023-08-04 jrmu queue)
166 665c255d 2023-08-04 jrmu (else
167 665c255d 2023-08-04 jrmu (set-cdr! (rear-ptr queue) new-pair)
168 665c255d 2023-08-04 jrmu (set-rear-ptr! queue new-pair)
169 665c255d 2023-08-04 jrmu queue))))
170 665c255d 2023-08-04 jrmu (define (delete-queue! queue)
171 665c255d 2023-08-04 jrmu (cond ((empty-queue? queue)
172 665c255d 2023-08-04 jrmu (error "DELETE! called with an empty queue" queue))
173 665c255d 2023-08-04 jrmu (else
174 665c255d 2023-08-04 jrmu (set-front-ptr! queue (cdr (front-ptr queue)))
175 665c255d 2023-08-04 jrmu queue)))
176 665c255d 2023-08-04 jrmu
177 665c255d 2023-08-04 jrmu ;; solution
178 665c255d 2023-08-04 jrmu
179 665c255d 2023-08-04 jrmu (define (or-gate a1 a2 output)
180 665c255d 2023-08-04 jrmu (define (logical-or x y)
181 665c255d 2023-08-04 jrmu (if (or (= x 1) (= y 1))
182 665c255d 2023-08-04 jrmu 1
183 665c255d 2023-08-04 jrmu 0))
184 665c255d 2023-08-04 jrmu (define (or-action-procedure)
185 665c255d 2023-08-04 jrmu (let ((new-value (logical-or (get-signal a1) (get-signal a2))))
186 665c255d 2023-08-04 jrmu (after-delay or-gate-delay
187 665c255d 2023-08-04 jrmu (lambda ()
188 665c255d 2023-08-04 jrmu (set-signal! output new-value)))))
189 665c255d 2023-08-04 jrmu (add-action! a1 or-action-procedure)
190 665c255d 2023-08-04 jrmu (add-action! a2 or-action-procedure)
191 665c255d 2023-08-04 jrmu 'ok)
192 665c255d 2023-08-04 jrmu
193 665c255d 2023-08-04 jrmu (define in-wire1 (make-wire))
194 665c255d 2023-08-04 jrmu (define in-wire2 (make-wire))
195 665c255d 2023-08-04 jrmu (define out-wire (make-wire))
196 665c255d 2023-08-04 jrmu (probe 'in-wire1 in-wire1)
197 665c255d 2023-08-04 jrmu (probe 'in-wire2 in-wire2)
198 665c255d 2023-08-04 jrmu (probe 'out-wire out-wire)
199 665c255d 2023-08-04 jrmu (or-gate in-wire1 in-wire2 out-wire)
200 665c255d 2023-08-04 jrmu (propagate)
201 665c255d 2023-08-04 jrmu (set-signal! in-wire1 1)
202 665c255d 2023-08-04 jrmu (propagate)
203 665c255d 2023-08-04 jrmu (set-signal! in-wire2 1)
204 665c255d 2023-08-04 jrmu (propagate)
205 665c255d 2023-08-04 jrmu (set-signal! in-wire1 0)
206 665c255d 2023-08-04 jrmu (propagate)
207 665c255d 2023-08-04 jrmu (set-signal! in-wire2 0)
208 665c255d 2023-08-04 jrmu (propagate)