Blob


1 (define (memo-proc proc)
2 (let ((already-run? false) (result false))
3 (lambda ()
4 (if already-run?
5 result
6 (begin (set! already-run? true)
7 (set! result (proc))
8 result)))))
10 (define-syntax mydelay
11 (rsc-macro-transformer
12 (let ((xfmr
13 (lambda (exp)
14 `(memo-proc (lambda () ,exp)))))
15 (lambda (e r)
16 (apply xfmr (cdr e))))))
18 (define (myforce delayed-object)
19 (delayed-object))
21 (define-syntax cons-stream
22 (rsc-macro-transformer
23 (let ((xfmr (lambda (x y) `(cons ,x (mydelay ,y)))))
24 (lambda (e r)
25 (apply xfmr (cdr e))))))
27 (define (stream-car s)
28 (car s))
29 (define (stream-cdr s)
30 (myforce (cdr s)))
31 (define stream-null? null?)
32 (define the-empty-stream '())
34 (define (integers-starting-from n)
35 (cons-stream n (integers-starting-from (+ n 1))))
37 (define (stream-ref s n)
38 (if (= n 0)
39 (stream-car s)
40 (stream-ref (stream-cdr s) (- n 1))))
41 (define (stream-map proc . argstreams)
42 (if (stream-null? (car argstreams))
43 the-empty-stream
44 (cons-stream
45 (apply proc (map stream-car argstreams))
46 (apply stream-map (cons proc (map stream-cdr argstreams))))))
47 (define (stream-for-each proc s)
48 (if (stream-null? s)
49 'done
50 (begin (proc (stream-car s))
51 (stream-for-each proc (stream-cdr s)))))
53 (define (stream-enumerate-interval low high)
54 (if (> low high)
55 the-empty-stream
56 (cons-stream
57 low
58 (stream-enumerate-interval (+ low 1) high))))
59 (define (stream-filter pred s)
60 (if (stream-null? s)
61 the-empty-stream
62 (let ((scar (stream-car s)))
63 (if (pred scar)
64 (cons-stream scar (stream-filter pred (stream-cdr s)))
65 (stream-filter pred (stream-cdr s))))))
67 (define (display-stream s)
68 (stream-for-each display-line s))
69 (define (display-line x)
70 (newline)
71 (display x))
73 (define (test-case actual expected)
74 (newline)
75 (display "Actual: ")
76 (display actual)
77 (newline)
78 (display "Expected: ")
79 (display expected)
80 (newline))
82 (define (integers-starting-from n)
83 (cons-stream n (integers-starting-from (+ n 1))))
84 (define integers (integers-starting-from 1))
86 (define (divisible? x y) (= (remainder x y) 0))
87 (define no-sevens
88 (stream-filter (lambda (x) (not (divisible? x 7)))
89 integers))
91 (define (fibgen a b)
92 (cons-stream a (fibgen b (+ a b))))
93 (define fibs (fibgen 0 1))
95 (define (sieve s)
96 (cons-stream
97 (stream-car s)
98 (sieve (stream-filter
99 (lambda (x)
100 (not (divisible? x (stream-car s))))
101 (stream-cdr s)))))
103 ;; (define primes (sieve (integers-starting-from 2)))
104 ;; (test-case (stream-ref primes 25) 101)
106 (define ones (cons-stream 1 ones))
107 (define (add-streams s1 s2)
108 (stream-map + s1 s2))
109 (define integers (cons-stream 1 (add-streams ones integers)))
110 ;; (test-case (stream-ref integers 15) 16)
112 (define fibs
113 (cons-stream 0
114 (cons-stream 1
115 (add-streams (stream-cdr fibs)
116 fibs))))
118 (define (scale-stream stream factor)
119 (stream-map (lambda (x)
120 (* x factor))
121 stream))
122 (define double (cons-stream 1 (scale-stream double 2)))
124 (define primes
125 (cons-stream
127 (stream-filter prime? (integers-starting-from 3))))
128 (define (prime? n)
129 (define (iter ps)
130 (cond ((> (square (stream-car ps)) n) true)
131 ((divisible? n (stream-car ps)) false)
132 (else (iter (stream-cdr ps)))))
133 (iter primes))
135 (define (mul-streams s1 s2)
136 (stream-map * s1 s2))
138 (define (partial-sums s)
139 (define sums
140 (cons-stream (stream-car s)
141 (add-streams sums
142 (stream-cdr s))))
143 sums)
145 (define (merge s1 s2)
146 (cond ((stream-null? s1) s2)
147 ((stream-null? s2) s1)
148 (else
149 (let ((s1car (stream-car s1))
150 (s2car (stream-car s2)))
151 (cond ((< s1car s2car)
152 (cons-stream
153 s1car
154 (merge (stream-cdr s1) s2)))
155 ((> s1car s2car)
156 (cons-stream
157 s2car
158 (merge s1 (stream-cdr s2))))
159 (else
160 (cons-stream
161 s1car
162 (merge (stream-cdr s1) (stream-cdr s2)))))))))
164 (define (test-stream-list stream list)
165 (if (null? list)
166 'done
167 (begin (display "A: ")
168 (display (stream-car stream))
169 (display " -- ")
170 (display "E: ")
171 (display (car list))
172 (newline)
173 (test-stream-list (stream-cdr stream) (cdr list)))))
175 (define (integrate-series a)
176 (stream-map / a integers))
178 (define exp-series
179 (cons-stream 1 (integrate-series exp-series)))
181 (define cosine-series
182 (cons-stream
184 (integrate-series (stream-map - sine-series))))
185 (define sine-series
186 (cons-stream
188 (integrate-series cosine-series)))
190 (define (mul-series s1 s2)
191 (cons-stream
192 (* (stream-car s1) (stream-car s2))
193 (add-streams
194 (scale-stream (stream-cdr s2) (stream-car s1))
195 (mul-series (stream-cdr s1) s2))))
197 (define (invert-unit-series s)
198 (define x
199 (cons-stream
201 (mul-series (stream-map - (stream-cdr s))
202 x)))
203 x)
205 (define (div-series num den)
206 (let ((den-car (stream-car den)))
207 (if (zero? den-car)
208 (error "Denominator has zero constant term -- DIV-SERIES")
209 (scale-stream
210 (mul-series
211 num
212 (invert-unit-series (scale-stream den (/ 1 den-car))))
213 (/ 1 den-car)))))
216 (define (sqrt-improve guess x)
217 (define (average x y)
218 (/ (+ x y) 2))
219 (average guess (/ x guess)))
221 (define (sqrt-stream x)
222 (define guesses
223 (cons-stream
225 (stream-map (lambda (guess)
226 (sqrt-improve guess x))
227 guesses)))
228 guesses)
230 (define (pi-summands n)
231 (cons-stream (/ 1 n)
232 (stream-map - (pi-summands (+ n 2)))))
233 (define pi-stream
234 (scale-stream (partial-sums (pi-summands 1)) 4))
236 (define (euler-transform s)
237 (let ((s0 (stream-ref s 0))
238 (s1 (stream-ref s 1))
239 (s2 (stream-ref s 2)))
240 (cons-stream
241 (- s2 (/ (square (- s2 s1))
242 (+ s0 (* -2 s1) s2)))
243 (euler-transform (stream-cdr s)))))
245 (define (make-tableau transform s)
246 (cons-stream s
247 (make-tableau transform
248 (transform s))))
250 (define (stream-limit s tol)
251 (let* ((scar (stream-car s))
252 (scdr (stream-cdr s))
253 (scadr (stream-car scdr)))
254 (if (< (abs (- scar scadr)) tol)
255 scadr
256 (stream-limit scdr tol))))
258 (define (sqrt x tolerance)
259 (stream-limit (sqrt-stream x) tolerance))
261 (define (pairs s t)
262 (cons-stream
263 (list (stream-car s) (stream-car t))
264 (interleave
265 (stream-map
266 (lambda (x)
267 (list (stream-car s) x))
268 (stream-cdr t))
269 (pairs (stream-cdr s) (stream-cdr t)))))
270 (define (interleave s1 s2)
271 (if (stream-null? s1)
272 s2
273 (cons-stream (stream-car s1)
274 (interleave s2 (stream-cdr s1)))))
276 (define (display-streams n . streams)
277 (if (> n 0)
278 (begin (newline)
279 (for-each
280 (lambda (s)
281 (display (stream-car s))
282 (display " -- "))
283 streams)
284 (apply display-streams
285 (cons (- n 1) (map stream-cdr streams))))))
287 (define (all-pairs s t)
288 (cons-stream
289 (list (stream-car s) (stream-car t))
290 (interleave
291 (stream-map
292 (lambda (x)
293 (list x (stream-car t)))
294 (stream-cdr s))
295 (interleave
296 (stream-map
297 (lambda (x)
298 (list (stream-car s) x))
299 (stream-cdr t))
300 (all-pairs (stream-cdr s) (stream-cdr t))))))
302 ;; Exercise 3.68. Louis Reasoner thinks that building a stream of pairs from three parts is unnecessarily complicated. Instead of separating the pair (S0,T0) from the rest of the pairs in the first row, he proposes to work with the whole first row, as follows:
304 (define (pairs s t)
305 (interleave
306 (stream-map (lambda (x) (list (stream-car s) x))
307 t)
308 (pairs (stream-cdr s) (stream-cdr t))))
310 ;; Does this work? Consider what happens if we evaluate (pairs integers integers) using Louis's definition of pairs.
312 ;; This fails because interleave is a regular procedure, so the argument (pairs (stream-cdr s) (stream-cdr t)) will be evaluated. This will result in an infinite loop. We need to delay the expression, but the delay is missing without cons-stream.
314 Exercise 3.69. Write a procedure triples that takes three infinite streams, S, T, and U, and produces the stream of triples (Si,Tj,Uk) such that i < j < k. Use triples to generate the stream of all Pythagorean triples of positive integers, i.e., the triples (i,j,k) such that i < j and i2 + j2 = k2.