-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathsection-4.3.3.rkt
82 lines (65 loc) · 2.36 KB
/
section-4.3.3.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
#lang sicp
; ex 4.50
(define (ramb? exp) (tagged-list? exp 'ramb))
(define (pop xs)
(define n (random (length xs)))
(let loop ([i 0]
[accu '()]
[tail xs])
(cond
[(= i n)
(cons (car tail) (append accu (cdr tail)))]
[else (loop (+ i 1) (append accu (list (car tail))) (cdr tail))])))
(define (analyze-ramb exp)
(let ([cprocs (map analyze (amb-choices exp))])
(lambda (env succeed fail)
(define (try-next choices)
(if (null? choices)
(fail)
(let* ([p (pop choices)]
[choice (car p)]
[rest (cdr p)])
(choice env succeed (lambda () (try-next rest))))))
(try-next cprocs))))
; ex 4.51
; The count would have been 1 if set! had been used.
(define (permanent-assignment? exp) (tagged-list? exp 'permanent-set!))
(define (analyze-permanent-assignment exp)
(let ([var (assignment-variable exp)]
[vproc (analyze (assignment-value exp))])
(lambda (env succeed fail)
(vproc env
(lambda (val fail2)
(set-variable-value! var val env)
; I was wondering why the following line is needed. In case of
; this ex, succeed is a procedure in which the interpreter calls
; the analyzed lambda of next line. fail2 is a procedure in
; which the interpreter chooses another value for y. If omitted,
; the program just stops.
(succeed 'ok fail2))
fail))))
; ex 4.52
(define (if-fail? exp) (tagged-list? exp 'if-fail))
(define (analyze-if-fail exp)
(let ((pproc (analyze (if-predicate exp)))
(cproc (analyze (if-consequent exp))))
(lambda (env succeed fail)
(pproc env
(lambda (val fail2) (succeed val fail2))
(lambda () (cproc env
(lambda (val fail3) (succeed val fail3))
fail))))))
; ex 4.53
; All pairs of prime sum.
; ex 4.54
(define (require? exp) (tagged-list? exp 'require))
(define (require-predicate exp) (cadr exp))
(define (analyze-require exp)
(let ([pproc (analyze (require-predicate exp))])
(lambda (env succeed fail)
(pproc env
(lambda (pred-value fail2)
(if (not pred-value)
(fail2)
(succeed 'ok fail2)))
fail))))