מבוא מורחב למדעי המחשב בשפת scheme תרגול 12. outline streams infinite...
TRANSCRIPT
מבוא מורחב למדעי המחשב Scheme בשפת
12תרגול
Outline
• Streams
• Infinite streams
• Stream implementation
• Questions from exams
2
Streams
3.5, pages 316-352
Definitions file on web
3
cons, car, cdr
(define s (cons 9 (begin (display 7) 5)))-> prints 7
The display command is evaluated whileevaluating the cons.
(car s) -> 9(cdr s) -> 5
4
cons-stream, stream-car, stream-cdr
(define s (cons-stream 9 (begin (display 7) 5)))
Due to the delay of the second argument, cons-stream does not activate the display command
(stream-car s) -> 9(stream-cdr s) -> prints 7 and returns 5 stream-cdr activates the display whichprints 7, and then returns 5.
5
List enumerate(define (enumerate-interval low high)
(if (> low high) nil
(cons low
(enumerate-interval
(+ low 1) high))))
(enumerate-interval 2 8)
-> (2 3 4 5 6 7 8)
(car (enumerate-interval 2 8))
-> 2
(cdr (enumerate-interval 2 8))
-> (3 4 5 6 7 8)6
Stream enumerate(define (stream-enumerate-interval low high)
(if (> low high) the-empty-stream
(cons-stream low
(stream-enumerate-interval
(+ low 1) high))))
(stream-enumerate-interval 2 8)
-> (2 . #<promise>)
(stream-car (stream-enumerate-interval 2 8))
-> 2
(stream-cdr (stream-enumerate-interval 2 8))
-> (3 . #<promise>)7
List map
(map <proc> <list>)
(define (map proc s) (if (null? s) nil (cons (proc (car s)) (map proc (cdr s)))))
(map square (enumerate-interval 2 8))
-> (4 9 16 25 36 49 64)
8
Stream map
(map <proc> <stream>)
(define (stream-map proc s) (if (stream-null? s) the-empty-stream (cons-stream (proc (stream-car s)) (stream-map proc (stream-cdr s)) )))
(stream-map square (stream-enumerate-interval 2 8))-> (4 . #<promise>)
9
List of squares
(define squares
(map square
(enumerate-interval 2 8)))
squares
-> (4 9 16 25 36 49 64)
(car squares)
-> 4
(cdr squares)
-> (9 16 25 36 49 64)10
Stream of squares
(define stream-squares
(stream-map square
(stream-enumerate-interval 2 8)))
stream-squares
-> (4 . #<promise>)
(stream-car stream-squares)
-> 4
(stream-cdr stream-squares)
-> (9 . #<promise>)11
List reference
(define (list-ref s n)
(if (= n 0) (car s)
(list-ref (cdr s) (- n 1))))
(define squares
(map square
(enumerate-interval 2 8)))
(list-ref squares 3)
-> 25
12
Stream reference
(define (stream-ref s n)
(if (= n 0) (stream-car s)
(stream-ref (stream-cdr s) (- n 1))))
(define stream-squares
(stream-map square
(stream-enumerate-interval 2 8)))
(stream-ref stream-squares 3)
-> 25
13
List filter
(filter <predicate> <list>)
(define (filter pred s) (cond ((null? s) nil) ((pred (car s)) (cons (car s) (filter pred (cdr s)))) (else (filter pred (cdr s)))))
(filter even? (enumerate-interval 1 20))-> (2 4 6 8 10 12 14 16 18 20)
14
Stream filter(stream-filter <predicate> <stream>)
(define (stream-filter pred s) (cond ((stream-null? s) the-empty-stream) ((pred (stream-car s)) (cons-stream (stream-car s) (stream-filter pred (stream-cdr s)))) (else (stream-filter pred (stream-cdr s))))))(stream-filter even?
(stream-enumerate-interval 1 20)) -> (2 . #<promise>)
15
Generalized list map
(generalized-map <proc> <list1> … <listn>)
(define (generalized-map proc . arglists) (if (null? (car arglists)) nil (cons (apply proc (map car arglists)) (apply generalized-map (cons proc (map cdr arglists))))))
(generalized-map + squares squares squares)
-> (12 27 48 75 108 147 192)
16
Generalized stream map
(generalized-stream-map <proc> <stream1> … <streamn>)
(define (generalized-stream-map proc . argstreams) (if (stream-null? (car argstreams)) the-empty-stream (cons-stream (apply proc (map stream-car argstreams)) (apply generalized-stream-map (cons proc (map stream-cdr argstreams))))))
(generalized-stream-map + stream-squares stream-squares stream-squares)-> (12 . #<promise>)
17
List for each
(define (for-each proc s)
(if (null? s) 'done
(begin
(proc (car s))
(for-each proc (cdr s)))))
18
Stream for each
(define (stream-for-each proc s) (if (stream-null? s) 'done (begin (proc (stream-car s)) (stream-for-each proc (stream-cdr s)))))
useful for viewing (finite!) streams(define (display-stream s) (stream-for-each display s))
(display-stream (stream-enumerate-interval 1 20)) -> prints 1 … 20 done
19
Lists(define sum 0)(define (acc x) (set! sum (+ x sum)) sum)
(define s (map acc (enumerate-interval 1 20)))s -> (1 3 6 10 15 21 28 36 45 55 66 78 91 105 120 136 153 171 190 210) sum -> 210(define y (filter even? s))y -> (6 10 28 36 66 78 120 136 190 210)
sum -> 210
(define z (filter (lambda (x) (= (remainder x 5) 0)) s))z -> (10 15 45 55 105 120 190 210) sum -> 210
20
(list-ref y 7)
-> 136 sum -> 210
(display z)
-> prints (10 15 45 55 105 120 190 210)
sum -> 210
21
Streams
(define sum 0)(define (acc x) (set! sum (+ x sum)) sum)
(define s (stream-map acc (stream-enumerate-interval 1 20)))s -> (1 . #<promise>) sum -> 1
(define y (stream-filter even? s))y -> (6 . #<promise>) sum -> 6
(define z (stream-filter (lambda (x) (= (remainder x 5) 0)) s))z -> (10 . #<promise>) sum -> 10
22
(stream-ref y 7)
-> 136 sum -> 136
(display-stream z)
-> prints 10 15 45 55 105 120 190 210 done
sum -> 210
23
Defining streams implicitlyby delayed evaluation
Suppose we needed an infinite list of Dollars.We can(define bill-gates (cons-stream ‘dollar bill-gates))
If we need a Dollar we can take the car
(stream-car bill-gates) -> dollar
The cdr would still be an infinite list of
Dollars.
(stream-cdr bill-gates)->(dollar . #<promise>)24
25
Infinite Streams
Formulate rules defining
infinite series
wishful thinking is key
25
1,ones
(define ones
(cons-stream 1 ones))
1,1,1,… = ones =
26
2,twos(define twos (cons-stream 2 twos))
ones + onesadding two infinite series of ones(define twos (stream-map + ones ones))
2 * oneselement-wise operations on an infinite series of ones(define twos (stream-map (lambda (x) (* 2 x)) ones)) or (+ x x)
2,2,2,… = twos =
27
1,2,3,… = integers =
1,ones + integers
1,1,1…
1,2,3,…
2,3,4,…
(define integers
(cons-stream 1
(stream-map + ones integers)))
+
28
0,1,1,2,3,… = fibs =
0,1,fibs + (fibs from 2nd position) 0,1,1,2,… 1,1,2,3,… 1,2,3,5,…
(define fibs (cons-stream 0 (cons-stream 1 (stream-map + fibs (stream-cdr fibs)))))
+
29
1,doubles + doubles
1,2,4,8,…
1,2,4,8,…
2,4,8,16,…
(define doubles (cons-stream 1
(stream-map + doubles doubles)))
1,2,4,8,… = doubles =
+
30
1,2 * doubles
(define doubles (cons-stream 1
(stream-map (lambda (x) (* 2 x)) doubles)))
or (+ x x)
1,2,4,8,… = doubles =
31
1,factorials * integers from 2nd
position 1, 1*2, 1*2*3,… 2, 3, 4,… 1*2,1*2*3,1*2*3*4,…
(define factorials (cons-stream 1 (stream-map * factorials (stream-cdr integers))))
1,1x2,1x2x3,... = factorials =
x
32
(1),(1 2),(1 2 3),… = runs =
(1), append runs with a list of integers from 2nd position
(1), (1 2), (1 2 3),… (2), (3), (4),… (1 2),(1 2 3),(1 2 3 4),…
(define runs (cons-stream (list 1) (stream-map append runs (stream-map list (stream-cdr integers)))))
append
33
a0,a0+a1,a0+a1+a2,… = partial sums =
a0,partial sums + (stream from 2nd pos) a0, a0+a1, a0+a1+a2,… a1, a2, a3,… a0+a1,a0+a1+a2,a0+a1+a2+a3,…
(define (partial-sums a) (cons-stream
(stream-car a) (stream-map + (partial-sums a) (stream-cdr a))))
+
34
35
Partial Sums (cont.)
(define (partial-sums a)(define sums
(cons-stream (stream-car a) (stream-map + sums (stream-cdr a)))) sums)
This implementation is more efficient since it uses the stream itself rather than recreating it recursively
35
RepeatInput: procedure f of one argument, number of repetitionsOutput: f*…*f, n times
(define (repeated f n) (if (= n 1) f (compose f (repeated f (- n 1)))))
(define (compose f g) (lambda (x) (f (g x))))
36
Repeat streamf,f*f,f*f*f,… = repeat =f,compose f,f,f,… with repeat
(define f-series (cons-stream f f-series))
(define stream-repeat (cons-stream f (stream-map compose f-series stream-repeat)))
We would like f to be a parameter37
Repeat streamf,f*f,f*f*f,… = repeat =f,compose f,f,f,… with repeat
(define (make-repeated f) (define f-series (cons-stream f f-series)) (define stream-repeat (cons-stream f (stream-map compose f-series stream-repeat))) stream-repeat)
38
Interleave
1,1,1,2,1,3,1,4,1,5,1,6,…(interleave ones integers)
s0,t0,s1,t1,s2,t2,… interleave =s0,interleave (t, s from 2nd position)(define (interleave s t) (if (stream-null? s) t (cons-stream (stream-car s) (interleave t (stream-cdr s)))))
39
streamsמימוש
streamמימוש
force/delayמנגנוני ••delay הוא special form
41
(delay <exp>) => (lambda () <exp>)
(force <delayed-exp>) => ((<delayed-exp>)) => ((lambda () <exp>)) => <exp>
streamמימוש
•memoization
42
(define (memo-proc proc) (let ((already-run? #f) (result #f)) (lambda () (if (not already-run?) (begin (set! result (proc)) (set! already-run? #t) result) result))))
streamמימוש
:delayהגדרה מתוקנת עבור •
ולכן:•
43
(delay <exp>) => (memo-proc (lambda () <exp>))
(cons-stream a b) => (cons a (delay b))
streams
44
(define ones (cons-stream 1 (begin (set! x (+ x 1)) ones))
GE x:0
streams
45
(define ones (cons 1 (delay (begin (set! x (+ x 1)) ones)))
GE x:0
streams
46
GE x:0
(define ones (cons 1 (memo-proc(lambda () ...)))
streams
47
GE x:0 ones:
(define ones (cons 1 (memo-proc(lambda () ...)))
1
proc:
p:-b:…
already-run:#fresult: #f
p:-b:(begin…)
streams
48
GE x:0 ones:
(stream-cdr ones)
1
proc:
p:-b:…
already-run:#fresult: #f
p:-b:(begin…)
streams
49
GE x:0 ones:
(force (cdr ones))
1
proc:
p:-b:…
already-run:#fresult: #f
p:-b:(begin…)
streams
50
GE x:0 ones:
((cdr ones))
1
proc:
p:-b:…
already-run:#fresult: #f
p:-b:(begin…)
streams
51
GE x:0 ones:
(not already-run) is #t => (set! result (proc))
1
proc:
p:-b:…
already-run:#fresult: #f
p:-b:(begin…)
streams
52
GE x:0 ones:
(begin (set! x (+ x 1)) ones)
1
proc:
p:-b:…
already-run:#fresult: #f
p:-b:(begin…)
streams
53
GE x:01 ones:
(begin (set! x (+ x 1)) ones)
1
proc:
p:-b:…
already-run:#fresult: #f
p:-b:(begin…)
/
streams
54
GE x:01 ones:
(set! already-run #t)
1
proc:
p:-b:…
already-run:#f #tresult: #f
p:-b:(begin…)
/
streams
55
GE x:01 ones:
(stream-cdr ones)
1
proc:
p:-b:…
already-run:#f #tresult: #f
p:-b:(begin…)
/
streams
56
GE x:01 ones:
((cdr ones))
1
proc:
p:-b:…
already-run:#f #tresult: #f
p:-b:(begin…)
/
streams
57
GE x:01 ones:
(not already-run) is #f=> result
1
proc:
p:-b:…
already-run:#f #tresult: #f
p:-b:(begin…)
/
streams
58
GE x:01 ones:
1
proc:
p:-b:…
already-run:#f #tresult: #f
p:-b:(begin…)
/
Questions from Exams
59
Extra
convert
.)convert num base(יש לממש את הפונקציה numהפונקציה מחזירה רשימה המייצגת את ספרותיו של
בסדר הפוך (ספרת האחדות ראשונה)baseבבסיס
60
)define (convert num base) (if (= num 0) '() ______________________________
______________________________
______________________________
______________________________ ))
(cons (remainder num base)
(convert (quotient num base) base))
convert-all
• -numbers (אולי אינסופי) של מספריםזרם.•bases - של מספרים.רשימה )convert-all numbers bases(ממשו את הפונקציה •
ברשימה i כך שהזרם ה-רשימה של זרמיםשמחזירה לפי numbersמכיל את הייצוג של כל המספרים ב-
iהמספר ה- (כל ייצוג כזה הוא רשימה בעצמו).basesב-
61
> (define N (cons-stream 5 (cons-stream 11 (cons-stream 35 …))))> (define B (list 2 3 4))> (convert-all N B) ([(1 0 1)(1 1 0 1)(1 1 0 0 0 1)…] [(2 1)(2 0 1)(2 2 0 1)…] [(1 1)(3 2)(3 0 2)…])
convert-all
62
(define (convert-all numbers bases) __________________________________
__________________________________
__________________________________
__________________________________
__________________________________
__________________________________ )
(map (lambda (base) (stream-map (lambda (x) (convert x base))
numbers)) bases))
common-digits-all
. )common-digits-all numbers bases(ממשו את הפונקציה • לפי f# ו-t#הפונקציה מחזירה רשימה של זרמים המכילים •
הכלל הבא:
basei אם בייצוג לפי בסיס t# יופיע i בזרם ה-kבמקום ה-•יש סיפרה משותפת. אחרת יופיע numbersk+1 ו- numberskשל
#f.) common-digit? L1 L2(ניתן להשתמש בפונקצית העזר •
אחרת. f# ,ו-L2 ו- L1 אם יש ספרה משותפת ל-t#המחזירה
63
common-digit-all
64
(define (common-digit-all nums bases) __________________________________
__________________________________
__________________________________
__________________________________ __________________________________
__________________________________
__________________________________ )
(map (lambda (base)
(stream-map (lambda (n1 n2) (common-digit? (convert n1 base) (convert n2 base))) (stream-cdr numbers) numbers)) bases))
in-sorted?
המקבלת מספר ?in-sortedממשו את הפונקצייה • אינסופי של מספרים ממוינים בסדר עולה. streamו-
אם המספר שהיא מקבלת נמצא t#הפונקציה מחזירה אחרת. f# ו- streamבתוך ה-
הינו 13 כי t# צריך להחזיר (in-sorted? 13 fibs): לדוגמא• צריך (in-sorted? 14 stream-of-fibs) -מספר פיבונצ'י ו
. איננו מספר פיבונצ'י14 כי f#להחזיר
65
in-sorted?
66
(define in-sorted? (lambda (x stream) (let ((e (__________ stream))) (or (= x e) (______ (____ x e) (__________ x (__________ stream)) )))))
stream-car
and > in-sorted? stream-cdr
merge-inc
אינסופיים של streams המקבלת שני merge-incממשו את הפונקצייה • אינסופי ממוין streamמספרים ממוינים בסדר עולה. הפונקציה מחזירה
הנתונים. אם ישנו מספר streamsבסדר עולה המתקבל ממיזוגם של ה- התוצאה.stream אזי הוא יופיע פעמיים ב-streamsהמשותף לשני ה-
לדוגמא:•
)merge-inc fibs
) stream-map
) lambda (x) (* x 10) (fibs(((
[ 10 10 8 5 3 2 1 1 0 0 ]צריך להחזיר
67
merge-inc
68
(define (merge-inc s1 s2) (let ((e1 (__________ s1)) (e2 (__________ s2))) (if (___ e1 e2) (___________ e1 (merge-inc (__________ s1) s2)) (___________ e2 (merge-inc s1 (__________ s2)) )))))
stream-car stream-car < cons-stream stream-cdr cons-stream stream-cdr
stream-conv
אינסופי של streamו- ) a1 a2 .. an(נגדיר קונבולוציה בין רשימת מספרים• כך … [ c1 c2 c3] אינסופי של מספריםstreamלהיות …[b1 b2 b3]מספרים
ci= a1*bi+a2*bi+1 ... an*bi+nש-
המחשבת את זרם הקונבולוציה עפ"י stream-convממשו את הפונקצייה•ההגדרה הנ"ל.
לדוגמא:•
)stream-conv ‘(1 2) fibs(
……[89 55 34 21 13 8 5 3 2]צריך להחזיר
69
stream-conv
70
(define (stream-conv lst str) (define (first-term lst str) (if (null? lst) ___ (___ (* (car lst) (__________ str)) (first-term (__________ lst) (__________ str) )))) (___________ (first-term lst str) (stream-conv lst (__________ str))))
0 + stream-car cdr stream-cdr cons-stream
stream-cdr
stream-conv
בסוף השערוך?x2 ו-x1 מהם ערכי •
71
(define x1 0)(define x2 0)(define str1 (cons-stream 1 (begin (set! x1 (+ x1 1)) str1)))(define (integers n) (cons-stream n (begin (set! x2 (+ x2 1)) (integers (+ n 1)))))
(define str2 (integers 1))(define c1 (stream-conv '(1 1) str1))(define c2 (stream-conv '(1 1) str2))
/ 1 / 2
מודל הסביבות
ציירו את מהלך השערוך של הביטוי הבא במודל הסביבות. •מהי תוצאת השערוך?
72
(let ((f (lambda (x) (+ x 3)))) (define y (lambda (g)
(lambda (y) (f (g y))))) ((y f) 3))
מודל הסביבות
73
(let ((f (lambda (x) (+ x 3)))) ...) => ((lambda (f) ...) (lambda (x) (+ x 3)
GE
מודל הסביבות
74
((lambda (f) ...) (lambda (x) (+ x 3)
GE
p: fb: (define y …
L1
מודל הסביבות
75
(L1 (lambda (x) (+ x 3)
GE
p: fb: (define y …
L1
p: xb:(+ x 3)
L2
מודל הסביבות
76
(L1 L2)
GE
p: xb:(+ x 3)
p: fb: (define y …
L2 L1
מודל הסביבות
77
(L1 L2)
GE
p: xb:(+ x 3)
p: fb: (define y …
f:L2 L1E1
מודל הסביבות
78
(define y (lambda (g) (lambda (y) (f (g y))))) | E1
GE
p: xb:(+ x 3)
p: fb: (define y …
f:y:
p: gb:(lambda…)
L2 L1
L3
E1
מודל הסביבות
79
((y f) 3) | E1
GE
p: xb:(+ x 3)
p: fb: (define y …
f:y:
p: gb:(lambda…)
L2 L1
L3
E1
מודל הסביבות
80
GE
p: xb:(+ x 3)
p: fb: (define y …
f:y:
p: gb:(lambda…)
L2 L1
L3
E1
((L3 f) 3) | E1
מודל הסביבות
81
GE
p: xb:(+ x 3)
p: fb: (define y …
f:y:
p: gb:(lambda (y) (f (g y)))
g:L2 L1
L3
E1 E2
((L3 f) 3) | E1
מודל הסביבות
82
GE
p: xb:(+ x 3)
p: fb: (define y …
f:y:
p: gb:(lambda (y) (f (g y)))
g:L2 L1
L3
E1 E2
(lambda (y) (f (g y)) | E2
מודל הסביבות
83
(L4 3) | E1
GE
p: xb:(+ x 3)
p: fb: (define y …
f:y:
p: gb:(…)
g:
p: yb:(f (g y))
L2 L1
L3L4
E1 E2
מודל הסביבות
84
(L4 3) | E1
GE
p: xb:(+ x 3)
p: fb: …
f:y:
p: gb:(…)
g:
p: yb:(f (g y))
L1 L2
L3L4
y:3
E1 E2 E3
מודל הסביבות
85
(f (g y)) | E3 => (f 6) | E3 => 9
GE
p: xb:(+ x 3)
p: fb: …
f:y:
p: gb:(…)
g:
p: yb:(f (g y))
L1 L2
L3L4
y:3
E1 E2 E3