-
Notifications
You must be signed in to change notification settings - Fork 4
/
streams.rkt
153 lines (112 loc) · 3.61 KB
/
streams.rkt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;
;;; CS1101S - PS07 support code
;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; some basic stream operations
(require (lib "defmacro.ss"))
(require (lib "trace.ss"))
; Stream implementation for Dr.Scheme
(define-macro cons-stream
(lambda (x y)
`(cons ,x (delay ,y))))
(define the-empty-stream '())
(define (stream-car stream) (car stream))
(define (stream-cdr stream) (force (cdr stream)))
(define (stream-null? stream) (null? stream))
; stream usage tools
(define (eval-stream s n)
(if (or (= n 0) (stream-null? s))
()
(cons (stream-car s)
(eval-stream (stream-cdr s) (- n 1)))))
(define (stream-take s n)
(if (= n 0)
the-empty-stream
(cons-stream
(stream-car s)
(stream-take
(stream-cdr s) (- n 1)))))
(define (stream-tail s n)
(if (= n 0)
s
(stream-tail (stream-cdr s) (- n 1))))
(define (show-stream s nterms)
(if (= nterms 0)
'done
(begin (write-line (stream-car s))
(show-stream (stream-cdr s) (- nterms 1)))))
(define (write-line x) (display x) (newline))
(define (stream-ref s n) (stream-car (stream-tail s n)))
; stream building tools
(define (stream-constant k)
(cons-stream k (stream-constant k)))
(define integers
(cons-stream 1 (add-streams (stream-constant 1) integers)))
(define (stream-map proc . argstreams) ; variable # of args
(if (null? (car argstreams))
the-empty-stream
(cons-stream
(apply proc (map stream-car argstreams))
(apply stream-map
(cons proc (map stream-cdr argstreams))))))
(define (scale-stream k s)
(stream-map * (stream-constant k) s))
(define (add-streams . args)
(apply stream-map (cons + args)))
(define (mul-streams . args)
(apply stream-map (cons * args)))
(define (stream-pairs s)
(if (stream-null? s)
the-empty-stream
(stream-append
(stream-map
(lambda (sn)
(list (stream-car s) sn))
(stream-cdr s))
(delay (stream-pairs (stream-cdr s))))))
(define (stream-append s1 s2)
(if (stream-null? s1)
s2
(cons-stream (stream-car s1)
(stream-append (stream-cdr s1) s2))))
(define (stream-filter pred stream)
(cond ((stream-null? stream)
the-empty-stream)
((pred (stream-car stream))
(cons-stream
(stream-car stream)
(stream-filter pred
(stream-cdr stream))))
(else
(stream-filter pred
(stream-cdr stream)))))
(define (replace str a b)
(cons-stream
(if (equal? (stream-car str) a)
b
(stream-car str))
(replace (stream-cdr str) a b)))
;;; power series operations
(define add-series add-streams)
(define scale-series scale-stream)
(define (negate-series s)
(scale-series -1 s))
(define (subtract-series s1 s2)
(add-series s1 (negate-series s2)))
;;; create a (finite) series from a list of coefficients
(define (coeffs->series list-of-coeffs)
(define zeros (cons-stream 0 zeros))
(define (iter list)
(if (null? list)
zeros
(cons-stream (car list)
(iter (cdr list)))))
(iter list-of-coeffs))
;;; convert a list to a finite stream
(define (list->stream l)
(foldr (lambda (x y) (cons-stream x y)) '() l))
;;; create a series from a procedure: nth term is P(n)
;;; requires non-neg-integers to be 0,1,2,3....
(define (proc->series proc)
(stream-map proc non-neg-integers))