Sicp
Sicp
Sicp
worked examples
Mac Radigan
Abstract
A collection of worked examples from Gerald Sussmans book Structure and Interpretation of Computer Programs (SICP) [1].
Contents
1 Building Abstractions with Procedures
1.1
1.2
1.3
1.1.1
Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.2
1.1.3
Evaluating Combinations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.4
Compound Procedures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1.1.5
10
1.1.6
17
1.1.7
17
1.1.8
19
19
1.2.1
19
1.2.2
Tree Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
1.2.3
Orders of Growth . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
1.2.4
Exponentiation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
27
1.2.5
32
1.2.6
32
32
1.3.1
Procedures as Arguments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
32
1.3.2
32
1.3.3
32
1.3.4
32
2.2
2.3
2.4
2.5
34
34
2.1.1
34
2.1.2
Abstraction Barriers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
36
2.1.3
39
2.1.4
39
39
2.2.1
Representing Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
2.2.2
Hierarchical Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
41
2.2.3
41
2.2.4
41
Symbolic Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
47
2.3.1
Quotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
47
2.3.2
52
2.3.3
55
2.3.4
55
55
2.4.1
55
2.4.2
Tagged data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
55
2.4.3
55
55
2.5.1
55
2.5.2
55
2.5.3
55
56
56
3.1.1
56
3.1.2
56
3.1.3
3.2
3.3
3.4
3.5
56
56
3.2.1
56
3.2.2
56
3.2.3
56
3.2.4
Internal Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
56
3.3.1
56
3.3.2
Representing Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
3.3.3
Representing Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
3.3.4
56
3.3.5
Propagation of Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
56
3.4.1
56
3.4.2
56
Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
56
3.5.1
56
3.5.2
Infinite Streams . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
58
3.5.3
58
3.5.4
58
3.5.5
58
4 Metalinguistic Abstraction
4.1
4.2
59
60
4.1.1
60
4.1.2
Representing Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
4.1.3
60
4.1.4
60
4.1.5
Data as Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
4.1.6
Internal Definitions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
4.1.7
60
60
4.2.1
60
4.3
4.4
4.2.2
60
4.2.3
60
60
4.3.1
60
4.3.2
60
4.3.3
60
Logic Programming
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
60
4.4.1
60
4.4.2
67
4.4.3
67
4.4.4
67
5.2
5.3
5.4
5.5
69
69
5.1.1
69
5.1.2
69
5.1.3
Subroutines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
5.1.4
69
5.1.5
Instruction Summary
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
A Register-Machine Simulator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
5.2.1
69
5.2.2
The Assembler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
5.2.3
. . . . . . . . . . . . . . . . . . . .
69
5.2.4
69
69
5.3.1
Memory as Vectors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
5.3.2
69
69
5.4.1
69
5.4.2
69
5.4.3
69
5.4.4
69
Compilation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
5.5.1
69
5.5.2
Compiling Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
5.5.3
Compiling Combinations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
5.5.4
69
5.5.5
69
5.5.6
Lexical Addressing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
69
5.5.7
69
6 Appendix A: Modules
6.1
70
util.scm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
70
78
Chicken Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
8 Appendix C: Notation
78
79
8.1
Membership . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
8.2
Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
8.3
Access . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
79
8.4
Equality . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
80
8.5
Logic . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
80
9 Appendix D: Y-Combinator
81
9.1
Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
81
9.2
Cannonical Expression . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
81
9.3
81
9.3.1
81
9.3.2
82
83
9.4.1
83
9.4.2
84
9.4.3
84
85
9.5.1
85
9.5.2
87
9.5.3
88
9.4
9.5
1.1
1.1.1
Expressions
Exercise 1.1. Below is a sequence of expressions. What is the result printed by the interpreter in response
to each expression? Assume that the sequence is to be evaluated in the order in which it is presented.
#!/usr/bin/csi -s
;; sicp_ch1_e1-1.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; Exercise 1.1. Below is a sequence of expressions. What is the result printed by the interpreter in
;;; response to each expression? Assume that the sequence is to be evaluated in the order in which it is
10
;;; presented.
11
12
(prn 10 )
13
(prn (+ 5 3 4) )
14
(prn (- 9 1) )
15
(prn (/ 6 2) )
16
(prn (+ (* 2 4) (- 4 6)) )
17
18
(define a 3)
19
(define b (+ a 1))
20
21
(prn (+ a b (* a b)) )
22
(prn (= a b) )
23
24
25
26
a) )
27
28
29
((= b 4) (+ 6 7 a))
30
(else 25)) )
31
32
33
34
35
((< a b) b)
36
(else -1))
37
(+ a 1)) )
38
39
;; *EOF*
## ./sicp_ch1_e1-1.scm
10
12
8
3
6
19
#f
4
16
6
16
1.1.2
#!/usr/bin/csi -s
;; sicp_ch1_e1-2.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; Exercise 1.2. Translate the following expression into prefix form
;;;
10
;;;
5 + 1/2 + (2 - (3 - (6 + 1/5) ) )
11
;;;
---------------------------------
(1)
12
;;;
3 * ( 6 - 2 ) * ( 2 - 7 )
13
14
15
(prn
16
(/
17
(+ 5 1/2 (- 2 (- 3 (+ 6 1/5) ) ) )
18
(* 3 (- 6 2) (- 2 7) )
)
19
20
21
22
;; *EOF*
## ./sicp_ch1_e1-2.scm
-0.178333333333333
1.1.3
Evaluating Combinations
Exercise 1.3. Define a procedure that takes three numbers as arguments and returns the sum of the squares
of the two larger numbers.
#!/usr/bin/csi -s
;; sicp_ch1_e1-3.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; Exercise 1.3. Define a procedure that takes three numbers as arguments and returns the sum of the
10
11
12
13
14
15
16
17
18
19
(define (take x N)
20
(if (> N 1)
21
22
23
24
25
26
27
28
29
30
31
(define (topss-1 x) ((compose ss-2 (lambda (x) (top x > 2)) ) x))
32
33
34
;; test solution
35
(define x (3 5 2 9 1) )
36
37
(prn (topss-1 x) )
38
(prn (topss-2 x) )
39
40
41
42
43
44
45
;; *EOF*
## ./sicp_ch1_e1-3.scm
106
106
1.1.4
Compound Procedures
Exercise 1.4. Observe that our model of evaluation allows for combinations whose operators are compound
expressions. Use this observation to describe the behavior of the following procedure:
(define (a-plus-abs-b a b)
((if (< b 0) + -) a b))
#!/usr/bin/csi -s
;; sicp_ch1_e1-4.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; Exercise 1.4. Observe that our model of evaluation allows for combinations whose operators are
;;; compound expressions. Use this observation to describe the behavior of the following procedure:
10
11
12
(define (a-plus-abs-b a b)
13
14
15
16
17
18
;; *EOF*
19
## ./sicp_ch1_e1-4.scm
7
7
1.1.5
Exercise 1.5. Ben Bitdiddle has invented a test to determine whether the interpreter he is faced with is using
applicative-order evaluation or normal-order evaluation. He defines the following two procedures:
(define (p) (p))
(define (test x y)
(if (= x 0)
0
y))
Then he evaluates the expression
(test 0 (p))
What behavior will Ben observe with an interpreter that uses applicative-order evaluation? What behavior
will he observe with an interpreter that uses normal-order evaluation? Explain your answer. (Assume that
the evaluation rule for the special form if is the same whether the interpreter is using normal or applicative
10
order: The predicate expression is evaluated first, and the result determines whether to evaluate the consequent or the alternative expression.)
#!/usr/bin/csi -s
;; sicp_ch1_e1-5.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; Exercise 1.5. Ben Bitdiddle has invented a test to determine whether the interpreter he is faced with
,
is
;;; using applicative-order evaluation or normal-order evaluation. He defines the following two
10
;;; procedures:
11
;;;
12
;;;
(define (test x y)
13
;;;
14
;;;
15
;;;
y))
16
17
;;;
18
;;; What behavior will Ben observe with an interpreter that uses applicative-order evaluation? What
19
;;; behavior will he observe with an interpreter that uses normal-order evaluation? Explain your answer.
20
;;; (Assume that the evaluation rule for the special form if is the same whether the interpreter is using
21
;;; normal or applicative order: The predicate expression is evaluated first, and the result determines
22
(if (= x 0)
(test 0 (p))
23
24
; infinite recursion
25
26
27
(define (test x y)
(if (= x 0)
28
29
y))
30
31
32
33
(prn (p) )
; infinite loop
34
35
;; *EOF*
11
Exercise 1.6. Alyssa P. Hacker doesnt see why if needs to be provided as a special form. Why cant I
just define it as an ordinary procedure in terms of cond? she asks. Alyssas friend Eva Lu Ator claims this
can indeed be done, and she defines a new version of if:
(new-if (= 2 3) 0 5)
5
(new-if (= 1 1) 0 5)
0
Delighted, Alyssa uses new-if to rewrite the square-root program:
(new-if (= 1 1) 0 5)
(define (sqrt-iter guess x)
(new-if (good-enough? guess x)
guess
(sqrt-iter (improve guess x) x)))
What happens when Alyssa attempts to use this to compute square roots? Explain.
Calls to the compound procedure new-if are applicatively evaluated, that is evaluated first and then
passed as arguments to the procedure. The predicates and clauses to cond, and thus results in infinite
recursion of unintended clause.
This is not the case with the intrinsic if procedure, which performs normal evaluation of the expression.
12
if-clause
if predicate
then-clause
otherwise
(2)
One possible correction for new-if, here, new-if-im, is to accept quasi-quoted arguments, and then eval
them.
new-ifim predicate, if-clause, else-clause =
eval (if-clause)
if eval (predicate)
eval (then-clause)
otherwise
#!/usr/bin/csi -s
;; sicp_ch1_e1-6.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
10
11
;;; Eva Lu Ator claims this can indeed be done, and she defines a new
12
13
14
;;;
15
;;;
16
;;;
17
18
19
20
;;;
21
;;;
(new-if (= 2 3) 0 5)
5
22
23
;;;
24
;;;
(new-if (= 1 1) 0 5)
0
25
26
27
28
;;;
29
;;;
13
(3)
30
;;;
guess
31
;;;
32
;;;
x)))
33
34
;;;
35
;;;
36
37
;; =======================================================
38
;; EXPERIMENT
39
;; =======================================================
40
41
42
43
guess
44
45
46
47
48
49
50
51
52
(define (average x y)
(/ (+ x y) 2))
53
54
55
56
57
((p1) (c1))
58
((p2) (c2))
59
(else (ow))
60
))
61
62
;; =======================================================
63
;; NEW IF
64
;; =======================================================
65
66
67
;;
68
;;
69
;;
14
70
;;
unintended clause.
71
;;
72
73
;;
74
75
76
(else else-clause)))
77
78
79
80
81
guess
82
83
84
;; =======================================================
85
;; IMPROVED NEW IF
86
;; =======================================================
87
88
89
;;
90
91
92
93
94
95
96
97
,guess
98
99
100
;; =======================================================
101
;; TESTS
102
;; =======================================================
103
104
(bar)
105
(prn "example:")
106
(prn (new-if (= 2 3) 0 5) ) ; 5
107
(prn (new-if (= 1 1) 0 5) ) ; 0
108
(hr)
109
15
110
111
(sqrt-iter-if 9 9))
112
(hr)
113
114
(define (p1) (let ((val #t)) (begin (prnvar "predicate-1" val) val)))
115
116
(define (p2) (let ((val #t)) (begin (prnvar "predicate-2" val) val)))
117
118
119
(cond-trace p1 c1
120
(hr)
121
122
(define (p1) (let ((val #f)) (begin (prnvar "predicate-1" val) val)))
123
124
(define (p2) (let ((val #t)) (begin (prnvar "predicate-2" val) val)))
125
126
127
(cond-trace p1 c1
128
(hr)
129
130
(define (p1) (let ((val #f)) (begin (prnvar "predicate-1" val) val)))
131
132
(define (p2) (let ((val #f)) (begin (prnvar "predicate-2" val) val)))
133
134
135
(cond-trace p1 c1
136
(hr)
137
138
139
(bar)
p2 c2 ow)
p2 c2 ow)
p2 c2 ow)
140
141
;; *EOF*
16
## ./sicp_ch1_e1-6.scm
================================================================================
example:
5
0
-------------------------------------------------------------------------------example 1.6: applied
sqrt-iter-if 9 := 3.00009155413138
-------------------------------------------------------------------------------example 1.6: cond-trace 1
predicate-1 := #t
clause-1
-------------------------------------------------------------------------------example 1.6: cond-trace 2
predicate-1 := #f
predicate-2 := #t
clause-2
-------------------------------------------------------------------------------example 1.6: cond-trace otherwise
predicate-1 := #f
predicate-2 := #f
otherwise
-------------------------------------------------------------------------------example 1.6: improved, using quasi-quote and eval
sqrt-iter-new-if-im 9 := 3.00009155413138
================================================================================
1.1.6
1.1.7
Exercise 1.7. The good-enough? test used in computing square roots will not be very effective for finding
the square roots of very small numbers. Also, in real computers, arithmetic operations are almost always
performed with limited precision. This makes our test inadequate for very large numbers. Explain these
statements, with examples showing how the test fails for small and large numbers. An alternative strategy
for implementing good-enough? is to watch how guess changes from one iteration to the next and to stop
when the change is a very small fraction of the guess. Design a square-root procedure that uses this kind of
end test. Does this work better for small and large numbers?
Newtons method:
f (xn )
f 0 (xn )
(4)
x2n guess
2xn
(5)
xn+1 = xn
Applied to square root:
xn+1 = xn
17
#!/usr/bin/csi -s
;; sicp_ch1_e1-5.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; Exercise 1.5. Ben Bitdiddle has invented a test to determine whether the interpreter he is faced with
,
is
;;; using applicative-order evaluation or normal-order evaluation. He defines the following two
10
;;; procedures:
11
;;;
12
;;;
(define (test x y)
13
;;;
14
;;;
15
;;;
y))
16
17
;;;
18
;;; What behavior will Ben observe with an interpreter that uses applicative-order evaluation? What
19
;;; behavior will he observe with an interpreter that uses normal-order evaluation? Explain your answer.
20
;;; (Assume that the evaluation rule for the special form if is the same whether the interpreter is using
21
;;; normal or applicative order: The predicate expression is evaluated first, and the result determines
22
(if (= x 0)
(test 0 (p))
23
24
; infinite recursion
25
26
27
(define (test x y)
(if (= x 0)
28
29
y))
30
31
32
33
; (prn (p) )
; infinite loop
34
35
;; *EOF*
## ./sicp_ch1_e1-7.scm
18
1.1.8
1.2
1.2.1
Exercise 1.9: Each of the following two procedures defines a method for adding two positive integers in terms
of the procedures inc, which increments its argument by 1, and dec, which decrements its argument by 1.
#!/usr/bin/csi -s
;; sicp_ch1_e1-9.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; Exercise 1.9: Each of the following two procedures defines a method for adding two positive integers
,
in terms of the procedures inc, which increments its argument by 1, and dec, which decrements its
argument by 1.
9
10
11
12
13
(define (recursive-+ a b)
(if (= a 0) b (my-inc (recursive-+ (my-dec a) b))))
14
15
16
(define (iterative-+ a b)
(if (= a 0) b (iterative-+ (my-dec a) (my-inc b)))) ; proper tail recursion
17
18
19
;;; Using the substitution model, illustrate the process gener- ated by each procedure in evaluating (+ 4
,
20
5).
21
22
(define a 4)
23
(define b 5)
24
25
(prnvar "a" a )
26
(prnvar "b" b )
27
28
19
29
30
;; *EOF*
## ./sicp_ch1_e1-9.scm
a := 4
b := 5
dec
dec
dec
dec
inc
inc
inc
inc
recursive := 9
dec
inc
dec
inc
dec
inc
dec
inc
iterative := 9
f (n) =
n<3
(6)
1f (n 1) + 2f (n 2) + 3f (n 3)
otherwise
Write a procedure that computes f by means of a recursive process. Write a procedure that computes f
by means of an iterative process.
f (n) := s0
20
(7)
s0 s0 + 2s1 + 3s2
s1 s0
s2 s1
(8)
s0 := 2
s := 1
1
s2 := 0
(9)
f (n, s)
nth s
n=0
(10)
f n 1, nth
1 1 (s), [1, 2, 3]
x, y ,
xk yk = xk y k
otherwise
(11)
nth
k , xk
(12)
k (x) , x(n+k)mod|x| n x
(13)
21
Xk = FXk1
F
Xk
Xk1
0
x0 1 2 3 x0
0
x = 1 0 0 x
1
1
0
x2
0 1 0
x2
22
(14)
(15)
where
X0
2
X0 =
1
(16)
so
#!/usr/bin/csi -s
;; sicp_ch1_e1-1.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;;
10
;;;
11
12
;;;
13
;;; Write a procedure that computes f by means of a recursive process. Write a procedure that computes f
,
14
{ n
if n<3,
;;;
15
16
;; =======================================================
17
;; RECURSIVE
18
;; =======================================================
19
20
;;
{ n
21
;; f(n)={
22
;;
if n<3
otherwise
23
24
25
(define (f-recursive n)
26
(if (< n 3)
27
28
23
(17)
29
30
31
32
;; =======================================================
33
;; DIRECT ITERATIVE
34
;; =======================================================
35
36
37
;;
38
;;
39
;;
40
;;
41
;;
s1 <- s0
42
;;
s2 <- s1
f(n) = s0
state transition
43
44
45
46
(define (f-direct n)
(f-direct-iter 2 1 0 n) ; initial state vector [ 0 1 2 ]
47
48
49
50
51
(define (f-direct-iter s0 s1 s2 n)
52
(if (< n 3)
53
s0
54
(f-direct-iter
55
56
s0
57
s1
58
(- n 1)
59
60
61
) ; next
) ; iteration test
) ; direct form
62
63
64
65
;; =======================================================
66
67
;; =======================================================
68
24
69
70
;;
71
;;
72
;;
73
;;
74
;;
75
;;
76
;;
77
;;
78
;;
79
;;
80
;;
81
;;
82
;;
83
;;
84
;;
85
;;
x[k] = LFSR(x[k-1], a)
= program { circshift(x), x_0 = <x,a> }
where
x[0] := [ 0 1 2 ]
a := [ 1 2 3 ]
86
87
88
89
(define (f-lfsr n)
90
(let (
91
(a
92
93
(k
(1 2 3)) ; coefficients
(- n 2))
; k transitions
94
) ; bindings
95
(f-lfsr-iter x0 a k)
x0 := [ 0 1 2 ]
k := n - 2
) ; let
96
97
a := [ 1 2 3 ]
98
99
100
101
(if (= k 0)
102
(car x)
103
104
105
106
107
;; =======================================================
108
25
109
;; =======================================================
110
111
112
;;
113
;;
114
;;
representation F := [ 0 1 0 ; 0 0 1 ; 1
115
;;
initial conditions x0 := [ 0 1 2 ]
116
;;
117
;;
118
;;
= F * ( F * x[k-2] )
119
;;
= F * ( F * ( F * x[k-3] ) )
120
;;
= ...
121
;;
= F^n * x0
122
;;
123
;;
124
;;
125
;;
126
;;
127
;;
128
;;
129
;;
[ 1 2 3 ]
130
;;
F := [ 1 0 0 ]
131
;;
[ 0 1 0 ]
132
;;
x[k] = F * x[k-1]
f(n) = x[n]
where
x[0] := [ 2 1 0 ]
133
134
135
136
137
(define (f-ss n)
(let (
138
(t_ref 2)
139
140
(F
(1 2 3
141
1 0 0
142
0 1 0 )
143
144
145
146
) ; bindings
147
148
) ; let
26
149
150
151
152
153
154
;; x[k] = F * x[k-1]
155
156
157
) ; ff-ss-iter
158
159
(define n 12)
160
161
; recursive
162
(prnvar "
; direct
163
(prnvar "
164
(prnvar "
SS f(n)" (f-ss n) )
; LFSR
; state space
165
166
;; *EOF*
## ./sicp_ch1_e1-11.scm
recursive
direct
LFSR
SS
f(n)
f(n)
f(n)
f(n)
:=
:=
:=
:=
10661
10661
10661
10661
1.2.2
Tree Recursion
1.2.3
Orders of Growth
1.2.4
Exponentiation
Exercise 1.16: Design a procedure that evolves an iterative exponentiation process that uses successive
squaring and uses a logarithmic number of steps, as does fast-expt. (Hint: Using the observation that
n
n 2
b 2 = b2 2 , keep, along with the exponent n and the base b, an additional state variable a, and define
the state transformation in such a way that the product a bn is unchanged from state to state. At the
beginning of the process a is taken to be 1, and the answer is given by the value of a at the end of the
process. In general, the technique of defining an invariant quantity that remains unchanged from state to
27
fbenchmark (x, n) =
if n is zero
2
fbenchmark x, n2
if n is even, nonzero
(18)
if n is odd
may be restructured as
f (x, n) = fk (x, n, p)
(19)
where
fk (x, n, p) =
#!/usr/bin/csi -s
;; sicp_ch1_e1-16.scm
;; Mac Radigan
if n is zero
n
f
x,
,
p
k
2
fk (x, n 1, p x)
(20)
if n is even, nonzero
if n is odd
4
5
(load "../library/util.scm")
(import util)
7
8
9
observation that (bn/2)2 = (b2)n/2, keep, along with the exponent n and the base b, an additional
state variable a, and define the state transformation in such a way that the product a bn is
unchanged from state to state. At the beginning of the process a is taken to be 1, and the answer is
given by the value of a at the end of the process. In general, the technique of defining an invariant
quantity that remains unchanged from state to state is a powerful way to think about the design of
iterative algorithms.)
10
11
;; ==============================================================================
12
13
;;
14
;;
if n is zero
28
15
;;
f(x,n) = {
16
;;
17
;;
f(x,n/2)^2
if n is even, nonzero
f(x,n-1)
if n is odd
18
(define (even? n)
19
(= (remainder n 2) 0))
20
21
(define (ref-fast-expt b n)
22
(cond ((= n 0) 1)
23
24
25
26
27
28
;; ==============================================================================
29
30
;;
31
;;
32
;;
f(x,n,p) = {
33
;;
34
;;
if n is zero
f(x,n/2,p)
if n is even, nonzero
f(x,n-1,x*p)
if n is odd
35
36
37
(define (fast-expt-iter b n p)
(cond ((= n 0) p)
((even? n) (fast-expt-iter (* b b) (/ n 2) p) )
38
39
40
41
(define (sep-fast-expt b n)
42
(fast-expt-iter b n 1))
43
44
45
;; ==============================================================================
46
47
48
(define (fast-expt b n)
49
;;
50
;;
f(x,n,p) = {
51
;;
52
(define (f b n p)
53
54
if n is zero
f(x,n/2,p)
if n is even, nonzero
f(x,n-1,x*p)
if n is odd
(cond ((= n 0) p)
((even? n) (f (* b b) (/ n 2) p) )
29
55
(f b n 1) ; call
56
57
58
59
60
;; ==============================================================================
61
62
63
(define (sr-fast-expt b n)
64
65
(cond ((= n 0) p )
66
((even? n) ((f f) (* b b) (/ n 2) p) )
67
68
) ; f(x,n)
69
70
)) ; self
71
((f f) b n 1)
72
73
74
75
;; ==============================================================================
76
77
78
79
80
81
(define-syntax call
(syntax-rules ()
((_ f)
(f f))))
82
83
84
85
86
(define-syntax fn
(syntax-rules ()
((_ signature self fn-base fn-iter)
(define signature
87
88
fn-base
89
) )))
90
91
(fn (mac-fast-expt b n) f
92
;; f(b,n,1)
93
((call f) b n 1)
94
;; f(b,n,p)
30
(lambda (b n p)
95
(cond ((= n 0) p )
96
97
((even? n) ((call f) (* b b) (/ n 2) p) )
98
99
100
101
102
103
;; ==============================================================================
104
;; test:
105
(define b 2)
106
(define n 8)
107
108
(bar)
109
(prn "intrinsic:")
110
111
(hr)
112
(prn "reference:")
113
114
(hr)
115
116
117
(hr)
118
119
120
(hr)
121
122
123
(hr)
124
125
(prn (mac-fast-expt b n) )
126
(bar)
127
128
;; *EOF*
31
## ./sicp_ch1_e1-16.scm
================================================================================
intrinsic:
256
-------------------------------------------------------------------------------reference:
256
-------------------------------------------------------------------------------example 1-16: (separate functions)
256
-------------------------------------------------------------------------------example 1-16: (nested functions)
256
-------------------------------------------------------------------------------example 1-16 (self-referencing lambdas):
256
-------------------------------------------------------------------------------example 1-16 (using macros):
256
================================================================================
1.2.5
1.2.6
1.3
1.3.1
Procedures as Arguments
1.3.2
1.3.3
1.3.4
Exercise 1.42. Let f and g be two one-argument functions. The composition f after g is defined to be the
function x 7 f (g (x)). Define a procedure compose that implements composition. For example, if inc is a
procedure that adds 1 to its argument, ((compose square inc) 6)
1
#!/usr/bin/csi -s
;; sicp_ch1_e1-42.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
32
;;; Exercise 1.42. Let f and g be two one-argument functions. The composition f after g is defined to be
;;; the function x f(g(x)). Define a procedure compose that implements composition. For example, if
10
11
12
13
14
15
16
17
18
19
20
;; *EOF*
## ./sicp_ch1_e1-42.scm
49
33
2.1
2.1.1
Exercise 2.1. Define a better version of make-rat that handles both positive and negative arguments. Makerat should normalize the sign so that if the rational number is positive, both the numerator and denominator
are positive, and if the rational number is negative, only the numerator is negative.
1
#!/usr/bin/csi -s
;; sicp_ch2_e2-1.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; Exercise 2.1. Define a better version of make-rat that handles both positive and negative
;;; arguments. Make-rat should normalize the sign so that if the rational number is positive, both the
10
;;; numerator and denominator are positive, and if the rational number is negative, only the numerator is
11
;;; negative.
12
13
14
15
16
(define (add-rat x y)
(make-rat (+ (* (numer x) (denom y))
(* (numer y) (denom x)))
(* (denom x) (denom y))))
17
18
19
20
21
(define (sub-rat x y)
(make-rat (- (* (numer x) (denom y))
(* (numer y) (denom x)))
(* (denom x) (denom y))))
22
23
24
25
(define (mul-rat x y)
(make-rat (* (numer x) (numer y))
(* (denom x) (denom y))))
26
27
28
29
(define (div-rat x y)
(make-rat (* (numer x) (denom y))
(* (denom x) (numer y))))
30
31
(define (equal-rat? x y)
34
32
33
34
35
36
(define (signum x)
(if (> x 0) +1 -1) )
37
38
39
40
41
42
(define (numer x)
(car x))
43
44
45
(define (denom x)
(cdr x))
46
47
(define x1 (make-rat
2))
; x1 =
1/2
48
(define x2 (make-rat
4))
; x2 =
1/4
49
(define x3 (make-rat
4))
; x3 =
2/4
50
(define x4 (make-rat -1
2))
; x4 = -1/2
51
(define x5 (make-rat
1 -4))
; x5 = -1/4
52
; x6 =
2/4
53
54
1/2
55
1/4
56
2/4
57
58
59
2/4
60
61
62
63
64
65
66
;; *EOF*
## ./sicp_ch2_e2-1.scm
35
1/2 *
1/4 = 1/8
2.1.2
Abstraction Barriers
Exercise 2.2. Consider the problem of representing line segments in a plane. Each segment is represented
as a pair of points: a starting point and an ending point. Define a constructor make-segment and selectors
start-segment and end-segment that define the representation of segments in terms of points. Furthermore,
a point can be represented as a pair of numbers: the x coordinate and the y coordinate. Accordingly, specify
a constructor make-point and selectors x-point and y-point that define this representation. Finally, using
your selectors and constructors, define a procedure midpoint-segment that takes a line segment as argument
and returns its midpoint (the point whose coordinates are the average of the coordinates of the endpoints).
To try your procedures, youll need a way to print points:
1
#!/usr/bin/csi -s
;; sicp_ch2_e2-2.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; Exercise 2.2. Consider the problem of representing line segments in a plane. Each segment is
;;; represented as a pair of points: a starting point and an ending point. Define a constructor
10
;;; make-segment and selectors start-segment and end-segment that define the representation
11
;;; of segments in terms of points. Furthermore, a point can be represented as a pair of numbers: the x
12
;;; coordinate and the y coordinate. Accordingly, specify a constructor make-point and selectors
13
;;; x-point and y-point that define this representation. Finally, using your selectors and
14
;;; constructors, define a procedure midpoint-segment that takes a line segment as argument and
15
;;; returns its midpoint (the point whose coordinates are the average of the coordinates of the
,
16
endpoints).
17
18
(define (print-point p)
19
(newline)
20
(display "(")
21
22
(display ",")
23
24
(display ")")
25
(newline)
26
27
36
28
;; point construct
29
(define (make-point x y)
(cons x y))
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
;; segment construct
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
;; test constructs
63
64
65
66
67
(define s-x
37
68
(define s-y
69
70
71
72
73
(print-point pt-mid)
74
75
2/4 = -1/8
76
77
;; *EOF*
## ./sicp_ch2_e2-2.scm
(0.5,0.5)
midpoint = (0.5 . 0.5)
Exercise 2.3. Implement a representation for rectangles in a plane. (Hint: You may want to make use
of exercise 2.2.) In terms of your constructors and selectors, create procedures that compute the perimeter
and the area of a given rectangle. Now implement a different representation for rectangles. Can you design
your system with suitable abstraction barriers, so that the same perimeter and area procedures will work
using either representation?
1
#!/usr/bin/csi -s
;; sicp_ch2_e1-1.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; Exercise 2.3. Implement a representation for rectangles in a plane. (Hint: You may want to make use
;;; of exercise 2.2.) In terms of your constructors and selectors, create procedures that compute the
10
;;; perimeter and the area of a given rectangle. Now implement a different representation for rectangles.
11
;;; Can you design your system with suitable abstraction barriers, so that the same perimeter and area
12
13
14
;; *EOF*
## ./sicp_ch2_e2-3.scm
38
2.1.3
2.1.4
2.2
Exercise 2.17. Define a procedure last-pair that returns the list that contains only the last element of a given
(nonempty) list:
1
#!/usr/bin/csi -s
;; sicp_ch2_e2-17.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; that contains only the last element of a given (nonempty) list:
10
11
(define (last-pair x)
(if (null? x)
12
13
14
15
(car x)
16
17
18
19
20
21
;; =======================================================
22
;; TESTS
23
;; =======================================================
24
25
(bar)
26
27
(prnvar "(
28
(bar)
; #f
29
30
;; *EOF*
39
## ./sicp_ch2_e2-17.scm
================================================================================
(23 72 149 34) := 34
(
) := #f
================================================================================
Exercise 2.18. Define a procedure reverse that takes a list as argument and returns a list of the same elements
in reverse order:
1
#!/usr/bin/csi -s
;; sicp_ch2_e2-17.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; argument and returns a list of the same elements in reverse order:
10
11
; ;; my-reverse
12
; (define (my-reverse x)
13
14
(list)
15
16
17
; )
(if (null? x)
18
19
;; =======================================================
20
;; TESTS
21
;; =======================================================
22
23
(bar)
24
25
(prnvar "(
26
(bar)
; #f
27
28
;; *EOF*
## ./sicp_ch2_e2-18.scm
================================================================================
(1 4 9 16 25) := (25 16 9 4 1)
(
) := ()
================================================================================
40
2.2.1
Representing Sequences
2.2.2
Hierarchical Structures
2.2.3
2.2.4
Exercise 2.44. Define the procedure up-split used by corner-split. It is similar to right-split, except that it
switches the roles of below and beside.
1
#!/usr/bin/csi -s
;; sicp_ch2_e2-44.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
(use sicp)
9
10
11
;;; It is similar to right-split, except that it switches the roles of below ;;; and beside.
12
13
14
(if (= n 0)
15
painter
16
(let
17
18
19
20
21
22
23
;; =======================================================
24
;; TEST
25
;; =======================================================
26
27
(bar)
28
29
30
31
(write-painter-to-png (up-split
(image->painter "../figures/lena.jpg") 2)
"../figures/sicp_ch2_e2-44.png")
41
32
(bar)
33
34
;; *EOF*
## ./sicp_ch2_e2-44.scm
================================================================================
up-split lena.jpg := ../figures/sicp_ch2_e2-44.png
Background RRGGBBAA: ffffff00
Area 0:0:256:256 exported to 256 x 256 pixels (90 dpi)
Bitmap saved as: ../figures/sicp_ch2_e2-44.png
================================================================================
Figure 2: Up Split 2
Exercise 2.45. Right-split and up-split can be expressed as instances of a general splitting operation.
Define a procedure split with the property that evaluating
(define right-split (split beside below))
(define up-split (split below beside))
produces procedures right-split and up-split with the same behaviors as the ones already defined.
1
#!/usr/bin/csi -s
;; sicp_ch2_e2-45.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
42
7
8
(use sicp)
9
10
11
12
13
;;;
14
;;;
15
;;;
16
;;;
17
18
19
20
21
22
(if (= n 0)
23
painter
24
(let
25
26
27
28
) ; if
29
) ; lambda
30
) ; split
31
32
33
34
35
36
;; =======================================================
37
;; TEST
38
;; =======================================================
39
40
(bar)
41
42
43
(write-painter-to-png (right-split
(image->painter "../figures/lena.jpg") 2)
"../figures/sicp_ch2_e2-45_right.png")
44
45
(hr)
46
43
47
48
49
50
(write-painter-to-png (up-split
(image->painter "../figures/lena.jpg") 2)
"../figures/sicp_ch2_e2-45_up.png")
(bar)
51
52
;; *EOF*
## ./sicp_ch2_e2-45.scm
================================================================================
right-split lena.jpg := ../figures/sicp_ch2_e2-45_right.png
Background RRGGBBAA: ffffff00
Area 0:0:256:256 exported to 256 x 256 pixels (90 dpi)
Bitmap saved as: ../figures/sicp_ch2_e2-45_right.png
-------------------------------------------------------------------------------up-split lena.jpg := ../figures/sicp_ch2_e2-45_up.png
Background RRGGBBAA: ffffff00
Area 0:0:256:256 exported to 256 x 256 pixels (90 dpi)
Bitmap saved as: ../figures/sicp_ch2_e2-45_up.png
================================================================================
44
Figure 4: Up Split 2
Exercise 2.46. A two-dimensional vector v running from the origin to a point can be represented as a
pair consisting of an x-coordinate and a y-coordinate. Implement a data abstraction for vectors by giving a
constructor make-vect and corresponding selectors xcor-vect and ycor-vect. In terms of your selectors and
constructor, implement procedures add-vect, sub-vect, and scale-vect that perform the operations vector
addition, vector subtraction, and multiplying a vector by a scalar:
1
#!/usr/bin/csi -s
;; sicp_ch2_e2-46.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
10
11
12
13
14
15
16
;;; by a scalar:
17
45
18
19
(define (make-vect x y)
(cons x y))
20
21
22
(define (xcor-vect v)
(car v))
23
24
25
(define (ycor-vect v)
(cdr v))
26
27
28
(define (scale-vect v s)
(make-vect (* s (xcor-vect v)) (* s (ycor-vect v)) ) )
29
30
31
32
33
34
35
36
37
38
39
40
;; =======================================================
41
;; TESTS
42
;; =======================================================
43
44
(define v1 (make-vect
2))
45
(define v2 (make-vect
-4))
46
47
(prnvar "v1
" v1)
48
(prnvar "v2
" v2)
49
50
51
(prnvar "v1
52
53
54
55
;; *EOF*
46
## ./sicp_ch2_e2-46.scm
v1
v2
v1.x
v1.y
v1
v1+v2
v1-v2
2.3
2.3.1
:=
:=
:=
:=
:=
:=
:=
(1
(1
1
2
(2
(2
(0
. 2)
. -4)
. 4)
. -2)
. 6)
Symbolic Data
Quotation
Exercise 2.54. Two lists are said to be equal? if they contain equal elements arranged in the same order.
For example,
is true, but
the basic eq? equality of symbols by saying that a and b are equal? if they are both symbols and the
symbols are eq?, or if they are both lists such that (car a) is equal? to (car b) and (cdr a) is equal? to (cdr
b). Using this idea, implement equal? as a procedure.
(equals? a b) = f (a, b) =
if S (a) S (b)
?
a=b
if S (a) S (b)
47
(21)
where
(23)
At this point, the recursive form is functional, but it is not expressed in tail-recursive form, and as such
is not subject to tail-call optimization. The following is a conversion to tail-recursive form:
if S (a) S (b)
?
fk (a, b, p) = p a =
b
if S (a) S (b)
#!/usr/bin/csi -s
;; sicp_ch2_e2-54.scm
48
(24)
(24)
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; Exercise 2.54. Two lists are said to be equal? if they contain equal
10
;;;
11
12
;;;
13
14
;;;
15
16
;;;
17
18
;;; the basic eq? equality of symbols by saying that a and b are equal? if
19
;;; they are both symbols and the symbols are eq?, or if they are both lists
20
;;; such that (car a) is equal? to (car b) and (cdr a) is equal? to (cdr b).
21
22
23
;; =======================================================
24
;; NOT TAIL-RECURSIVE
25
;; =======================================================
26
27
;;
28
;;
29
{ #f
if
;; f(a,b) = { a =?= b
if
30
;;
31
;;
32
(define (my-equal-subopt? a b)
{ f(car(a),car(b)) ^ f(cdr(a),cdr(b))
33
34
(cond
35
;;
36
37
;;
38
#t
(null check)
#t )
39
40
;;
41
42
;;
->
a =?= b
49
( (and (notlist?
43
a) (notlist?
(eq? a b) )
44
45
;;
46
47
;;
48
->
#f
49
50
;;
51
;; case: !( s(a)^s(b) )
52
;;
53
;;
54
;;
55
( else
->
f( cdr(a), cdr(b) )
56
57
58
b))
59
60
;; =======================================================
61
;; TAIL-RECURSIVE
62
;; =======================================================
63
64
;;
65
;;
66
{ #f
if
;; f(a,b,p=#t) = { p ^ a =?= b
if
67
;;
68
;;
69
(define (my-equal? a b)
70
71
(define (f a b p)
72
(cond
73
;;
74
75
;;
76
(null check)
77
78
;;
79
80
;;
81
82
#t
->
a =?= b
50
83
;;
84
85
;;
86
#f
87
88
;;
89
;; case: !( s(a)^s(b) )
90
;;
91
( else
->
f( cdr(a), cdr(b) )
92
) ;; cond
93
94
95
96
->
;; <= recur
97
98
(bar)
99
(prn "intrinsic:")
100
101
102
(hr)
103
104
105
106
; (hr)
107
108
109
110
(bar)
111
112
;; *EOF*
## ./sicp_ch2_e2-54.scm
================================================================================
intrinsic:
#t
#f
-------------------------------------------------------------------------------example 2-54: (not tail-recursive)
#t
#f
================================================================================
Exercise 2.55. Eva Lu Ator types to the interpreter the expression (car abracadabra)
To her surprise, the interpreter prints back quote. Explain.
51
#!/usr/bin/csi -s
;; sicp_ch2_e2-55.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
;;; Exercise 2.55. Eva Lu Ator types to the interpreter the expression (car abracadabra)
10
11
(bar)
12
13
(hr)
14
(prn "Quote constructs a non-modifiable list, whose contents are the literal arguments to quote.")
15
16
(prn "Car returns the first element of the list, which itself is quote.")
17
(bar)
18
19
;; *EOF*
## ./sicp_ch2_e2-55.scm
================================================================================
quote
-------------------------------------------------------------------------------Quote constructs a non-modifiable list, whose contents are the literal arguments to quote.
The second quote is part of the literal quoted list.
Car returns the first element of the list, which itself is quote.
================================================================================
2.3.2
Exercise 2.56. Show how to extend the basic differentiator to handle more kinds of expressions. For instance,
implement the differentiation rule
d (un )
u
= nu1
u
x
#!/usr/bin/csi -s
;; sicp_ch2_e2-56.scm
;; Mac Radigan
52
(24)
4
5
(load "../library/util.scm")
(import util)
7
8
10
;;;
11
;;;
d(u^n)
12
;;;
------
13
;;;
dx
14
;;;
du
=
nu^-1 -dx
15
16
17
18
19
20
((sum? exp)
(make-sum (deriv (addend exp) var)
21
22
23
((product? exp)
(make-sum
24
25
26
27
(multiplicand exp))))
28
29
30
d(u^n)
31
------
32
dx
33
34
((exponent? exp)
35
36
39
40
nu^-1 -dx
(make-product
(make-product (power exp)
(make-exponent (base exp) (- (power exp) 1)))
37
38
du
41
42
43
53
44
45
46
47
48
49
50
51
52
53
(define (make-exponent b p)
54
(cond ((=number? p 0) 1)
55
((=number? p 1) b)
56
(else (^ b p))))
57
58
59
60
61
62
63
64
65
66
67
68
69
70
(define (product? x)
(and (pair? x) (eq? (car x) *)))
71
72
73
74
75
76
(bar)
77
78
(bar)
79
80
;; *EOF*
54
## ./sicp_ch2_e2-56.scm
================================================================================
d/dx (2x)^4 := (* (* 4 ((quote ^) b p)) (+ (* 2 1) (* 0 x)))
================================================================================
2.3.3
2.3.4
2.4
2.4.1
2.4.2
Tagged data
2.4.3
2.5
2.5.1
2.5.2
2.5.3
55
3.1
3.1.1
3.1.2
3.1.3
3.2
3.2.1
3.2.2
3.2.3
3.2.4
Internal Definitions
3.3
3.3.1
3.3.2
Representing Queues
3.3.3
Representing Tables
3.3.4
3.3.5
Propagation of Constraints
3.4
3.4.1
3.4.2
3.5
3.5.1
Streams
Streams Are Delayed Lists
Exercise 3.50. Complete the following definition, which generalizes stream-map to allow procedures that
take multiple arguments, analogous to map in section 2.2.3, footnote 12.
(define (stream-map proc . argstreams)
56
#!/usr/bin/csi -s
;; sicp_ch3_e3-50.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
(load "./ch3support.scm")
10
(load "./ch3.scm")
11
12
13
14
15
16
;;;
17
;;;
18
;;;
the-empty-stream
19
;;;
(<??>
20
;;;
21
;;;
(apply stream-map
22
;;;
23
24
25
26
the-empty-stream
27
(cons-stream
28
29
(apply stream-map
30
31
32
57
33
34
35
;; *EOF*
3.5.2
Infinite Streams
3.5.3
3.5.4
3.5.5
58
Metalinguistic Abstraction
#!/usr/bin/csi -s
;; run-query.scm
;; Mac Radigan
4
5
(load "./ch4-query.scm")
(initialize-data-base microshaft-data-base)
10
(query-driver-loop)
11
12
;; *EOF*
59
4.1
4.1.1
4.1.2
Representing Expressions
4.1.3
4.1.4
4.1.5
Data as Programs
4.1.6
Internal Definitions
4.1.7
4.2
4.2.1
4.2.2
4.2.3
4.3
4.3.1
4.3.2
4.3.3
4.4
Logic Programming
An excellent discussion of logic programming can be found in chapter 19 of Paul Grahams On Lisp [2].
4.4.1
Exercise 4.55. Give simple queries that retrieve the following information from the data base:
(a) all people supervised by Ben Bitdiddle;
(b) the names and jobs of all people in the accounting division;
(c) the names and addresses of all people who live in Slumerville.
60
#!/usr/bin/csi -s
;; sicp_ch4_e4-55.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
(load "./ch4-query.scm")
10
11
12
13
(initialize-data-base microshaft-data-base)
14
15
Give simple queries that retrieve the following information from the data base:
16
;;;
17
;;;
18
;;;
19
20
;; =======================================================
21
;; QUERY PROCESSOR
22
;; =======================================================
23
24
25
26
27
28
(newline)
29
30
31
(else
32
(newline)
33
(display output-prompt)
34
35
(display-stream
36
37
38
(stream-map
(lambda (frame)
(instantiate q
39
frame
40
(lambda (v f)
61
(contract-question-mark v))))
41
42
))))
43
44
45
;; =======================================================
46
47
;; =======================================================
48
49
(define query-a
(supervisor ?person (Bitdiddle Ben)) )
50
51
;; =======================================================
52
53
;; =======================================================
54
55
(define query-b
(job ?person (accounting . ?title)) )
56
57
;; =======================================================
58
59
;; =======================================================
60
61
62
;; =======================================================
63
;; TESTS
64
;; =======================================================
65
66
(bar)
67
68
69
(prn "Query B. the names and jobs of all people in the accounting division:")
70
71
(prn "Query C. the names and addresses of all people who live in Slumerville:")
72
73
(bar)
74
75
;; *EOF*
62
## ./sicp_ch4_e4-55.scm
================================================================================
Query A. all people supervised by Ben Bitdiddle:
;;; Query results:
(supervisor (Tweakit Lem E) (Bitdiddle Ben))
(supervisor (Fect Cy D) (Bitdiddle Ben))
(supervisor (Hacker Alyssa P) (Bitdiddle Ben))
-------------------------------------------------------------------------------Query B. the names and jobs of all people in the accounting division:
;;; Query results:
(job (Cratchet Robert) (accounting scrivener))
(job (Scrooge Eben) (accounting chief accountant))
-------------------------------------------------------------------------------Query C. the names and addresses of all people who live in Slumerville:
;;; Query results:
(address (Aull DeWitt) (Slumerville (Onion Square) 5))
(address (Reasoner Louis) (Slumerville (Pine Tree Road) 80))
(address (Bitdiddle Ben) (Slumerville (Ridge Road) 10))
================================================================================
Exercise 4.56. Formulate compound queries that retrieve the following information:
(a) the names of all people who are supervised by Ben Bitdiddle, together with their addresses;
(b) all people whose salary is less than Ben Bitdiddles, together with their salary and Ben Bitdiddles salary;
(c) all people who are supervised by someone who is not in the computer division, together with the supervisors name and job.
#!/usr/bin/csi -s
;; sicp_ch4_e4-56.scm
;; Mac Radigan
4
5
(load "../library/util.scm")
(import util)
7
8
(load "./ch4-query.scm")
10
11
12
13
(initialize-data-base microshaft-data-base)
14
15
63
16
;;;
a. the names of all people who are supervised by Ben Bitdiddle, together with their addresses;
17
;;;
b. all people whose salary is less than Ben Bitdiddles, together with their salary and Ben
,
18
;;;
,
Bitdiddles salary;
c. all people who are supervised by someone who is not in the computer division, together with
the supervisors name and job.
19
20
;; =======================================================
21
;; QUERY PROCESSOR
22
;; =======================================================
23
24
25
(cond ((assertion-to-be-added? q)
26
27
28
(newline)
29
30
)
(else
31
32
(newline)
33
(display output-prompt)
34
35
(display-stream
(stream-map
36
(lambda (frame)
37
(instantiate q
38
39
frame
40
(lambda (v f)
(contract-question-mark v))))
41
42
))))
43
44
45
;; =======================================================
46
47
;;
48
;; =======================================================
49
50
51
52
53
(define query-a
(and (supervisor (Bitdiddle Ben) ?person)
(address ?person ?address)
) ; conjunction
) ; query A
64
54
55
;; =======================================================
56
57
;;
58
;; =======================================================
59
60
;;; TODO
61
(define query-b
62
63
64
) ; conjunction
65
) ; query B
66
67
68
; (define query-b
69
70
71
72
73
; ) ; query B
74
75
;; =======================================================
76
77
;;
78
;;
79
;; =======================================================
80
) ; conjunction
(define query-c
(and (supervisor ?supervisor ?person)
81
82
83
84
85
) ; query C
86
87
;; =======================================================
88
;; TESTS
89
;; =======================================================
90
91
(bar)
92
(prn "Query A. the names of all people who are supervised by Ben Bitdiddle, together with their
,
addresses")
65
93
94
(prn "[TODO] Query B. all people whose salary is less than Ben Bitdiddles, together with their salary
,
95
96
(prn "Query C. all people who are supervised by someone who is not in the computer division, together
,
97
98
(bar)
99
100
;; *EOF*
## ./sicp_ch4_e4-56.scm
================================================================================
Query A. the names of all people who are supervised by Ben Bitdiddle, together with their addresses
;;; Query results:
(and (supervisor (Bitdiddle Ben) (Warbucks Oliver)) (address (Warbucks Oliver) (Swellesley (Top Heap
,
Road))))
-------------------------------------------------------------------------------[TODO] Query B. all people whose salary is less than Ben Bitdiddles, together with their salary and Ben
,
Bitdiddles salary
;;; Query results:
(and (salary (Bitdiddle Ben) 60000) (salary (Aull DeWitt) 25000))
(and (salary (Bitdiddle Ben) 60000) (salary (Cratchet Robert) 18000))
(and (salary (Bitdiddle Ben) 60000) (salary (Scrooge Eben) 75000))
(and (salary (Bitdiddle Ben) 60000) (salary (Warbucks Oliver) 150000))
(and (salary (Bitdiddle Ben) 60000) (salary (Reasoner Louis) 30000))
(and (salary (Bitdiddle Ben) 60000) (salary (Tweakit Lem E) 25000))
(and (salary (Bitdiddle Ben) 60000) (salary (Fect Cy D) 35000))
(and (salary (Bitdiddle Ben) 60000) (salary (Hacker Alyssa P) 40000))
(and (salary (Bitdiddle Ben) 60000) (salary (Bitdiddle Ben) 60000))
-------------------------------------------------------------------------------Query C. all people who are supervised by someone who is not in the computer division, together with the
,
supervisors name and job.
;;; Query results:
(and (supervisor (Aull DeWitt) (Warbucks Oliver)) (not (job (Aull DeWitt) (computer . ?supervisor-title)))
,
(job (Aull DeWitt) (administration secretary)))
(and (supervisor (Cratchet Robert) (Scrooge Eben)) (not (job (Cratchet Robert) (computer .
,
?supervisor-title))) (job (Cratchet Robert) (accounting scrivener)))
(and (supervisor (Scrooge Eben) (Warbucks Oliver)) (not (job (Scrooge Eben) (computer .
,
?supervisor-title))) (job (Scrooge Eben) (accounting chief accountant)))
================================================================================
66
4.4.2
4.4.3
4.4.4
67
68
5
5.1
5.1.1
5.1.2
5.1.3
Subroutines
5.1.4
5.1.5
Instruction Summary
5.2
A Register-Machine Simulator
5.2.1
5.2.2
The Assembler
5.2.3
5.2.4
5.3
5.3.1
Memory as Vectors
5.3.2
5.4
5.4.1
5.4.2
5.4.3
5.4.4
5.5
Compilation
5.5.1
5.5.2
Compiling Expressions
5.5.3
Compiling Combinations
5.5.4
5.5.5
5.5.6
Lexical Addressing
69
Appendix A: Modules
6.1
util.scm
#!/usr/bin/csi -s
;; util.scm
;; Mac Radigan
4
5
(module util (
bind
bar
bin
br
10
but-last
11
ck
12
compose
13
dec
14
dotprod
15
flatmap
16
fmt
17
hr
18
hex
19
inc
20
my-iota
21
join
22
kron-comb
23
lfsr
24
mat-*
25
mat-col
26
mat-row
27
mod
28
my-last
29
nth
30
oct
31
permute
32
pr
33
prn
34
prnvar
35
my-reverse
36
range
70
37
rotate-right
38
rotate-left
39
rotate
40
square
41
sum
42
xor
43
44
Y-normal
45
Y2
46
yeild
47
48
49
(use extras)
50
(use srfi-1)
51
52
53
(define (br)
54
(format #t "~%"))
55
56
57
(define (pr x)
(format #t "~a" x))
58
59
60
(define (fmt s x)
(format #t s x))
61
62
63
(define (prn x)
(format #t "~a~%" x))
64
65
66
67
68
69
70
71
72
73
(format #t "~a = ~a
74
) ; ck
75
76
71
77
(define (hex x)
78
(define (bin x)
79
(define (oct x)
80
81
;;; delimiters
82
(define (bar)
83
(define (hr)
84
85
86
(define (nth x n)
87
(if (= n 1)
88
(car x)
89
90
91
) ; nth
92
93
94
(define (dotprod u v)
(apply + (map * u v))
95
96
97
98
99
(define (mod x n)
(- x (* n (floor (/ x n))))
100
101
102
103
104
(define (permute x p)
(map (lambda (pk) (nth x pk)) p)
105
106
107
108
109
(define (rotate-left x n)
110
(if (< n 1)
111
112
113
114
) ; if last iter
) ; rotate-left
115
116
72
117
(define (rotate-right x n)
(if (< n 1)
118
119
120
(rotate-right
121
122
(- n 1)
) ; call
123
) ; if last iter
124
125
) ; rotate-right
126
127
128
(define (rotate x n)
(cond
129
130
((= n 0) x)
131
132
133
134
135
136
137
(define (but-last x)
(if (null? x)
138
139
(list)
140
141
(list)
142
143
144
145
146
147
148
(define (my-last x)
(if (null? x)
149
150
#f
151
152
(car x)
153
154
155
156
73
157
158
;; composition
159
160
161
;; my-reverse
162
(define (my-reverse x)
(if (null? x)
163
164
(list)
165
166
167
168
169
170
;;
171
;;
172
(define (lfsr x a)
(append (list (dotprod x a)) (cdr (rotate x +1)) ) ; next state x[k]
173
174
) ; lfsr
175
176
177
178
179
180
181
182
) ; local bindings
183
184
185
186
187
188
) ; let
189
) ; mat-*
190
191
192
;;
193
194
NB:
(let (
195
(start
) ; start
:= kth column
196
74
197
) ; M_rows
198
199
) ; local bindings
200
201
) ; let
202
) ; mat-col
203
204
205
;;
206
NB:
(let (
207
208
(start
(* k (cadr dim))
) ; start
209
(stride 1
) ; stride := 1
210
) ; M_rows
211
) ; N_cols
212
) ; local bindings
213
214
) ; let
215
) ; mat-col
216
217
218
(define (flatmap f x)
(apply append (map f x))
219
220
) ; flatmap
221
222
223
(define (kron-comb a b)
(flatmap (lambda (ak) (map (lambda (bk) (list ak bk)) a)) b)
224
225
) ; kron-comb
226
227
228
229
230
231
232
233
234
235
236
75
237
238
(define (my-iota n)
(range 0 1 n)
239
240
241
242
243
244
245
246
(range-iter (append x (list val)) (+ val step) step (- n 1) ) ; x << val + step
)
247
248
249
250
;; exclusive or
251
(define (xor a b)
(or (and (not a) b) (and a (not b)))
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
;; Y combiner
267
;;
268
(define Y
strict-order
(lambda (f)
269
270
271
272
;;
273
(define (Y-normal f)
274
275
276
normal-order
76
277
(lambda (h)
(lambda args (apply (h (Y h)) args))))
278
279
280
281
) ; module util
282
283
;; hello.scm
284
285
;; *EOF*
77
7.1
Chicken Scheme
#!/bin/bash
## apt-install.sh
## Mac Radigan
## *EOF*
#!/bin/bash
## yum-install.sh
## Mac Radigan
## *EOF*
#!/bin/bash
## brew-install.sh
## Mac Radigan
## *EOF*
#!/bin/bash
## chicken-install.sh
## Mac Radigan
chicken-install sicp
# *EOF*
78
8
8.1
Appendix C: Notation
Membership
S (x) , x SYMBOL
(24)
L (x) , x LIST
(25)
8.2
Symbols
> , #t
(26)
, #f
(27)
8.3
Access
xA , (car x)
(28)
xD , (cdr x)
(29)
79
8.4
Equality
?
x = y , (eq? x y)
(30)
8.5
Logic
x , (not x)
(31)
x y , (and x y)
(32)
x y , (or x y)
(33)
80
Appendix D: Y-Combinator
9.1
Introduction
Description of the Y Combinator based on Mike Mvaniers blog post [?]. see http://mvanier.livejournal.com/2897.html
9.2
Cannonical Expression
(35)
9.3
Direct implementation of the above expression for the Y Combinator will not terminate during applicative
order [?].
9.3.1
#!/usr/bin/csi -s
;; y-combinator.scm
;; Mac Radigan
;;
6
7
(load "../library/util.scm")
(import util)
9
10
11
81
12
(define Y
13
(lambda (f)
14
(f (Y f))))
15
16
(define almost-factorial
17
(lambda (f)
18
(lambda (n)
19
(if (= n 0)
20
21
22
(* n (f (- n 1)))))))
23
24
25
26
27
28
;; *EOF*
9.3.2
This will work in a lazy language, as shown using the lazy extension in Racket.
1
#!/usr/bin/racket
;; y-combinator.scm
;; Mac Radigan
;;
6
7
#lang lazy
8
9
10
11
12
13
(define Y
(lambda (f)
(f (Y f))))
14
15
16
17
18
19
(define almost-factorial
(lambda (f)
(lambda (n)
(if (= n 0)
1
82
(* n (f (- n 1)))))))
20
21
22
23
24
25
26
;; *EOF*
## ./y-combinator.rkt-lazy
720
9.4
The Normal Order Y Combinator will not terminate during applicative order [?].
9.4.1
#!/usr/bin/csi -s
;; y-combinator-normal.scm
;; Mac Radigan
;;
6
7
(load "../library/util.scm")
(import util)
9
10
11
12
13
14
15
16
(define Y
(lambda (f)
((lambda (x) (f (x x)))
(lambda (x) (f (x x))))))
17
18
19
20
21
(define almost-factorial
(lambda (f)
(lambda (n)
(if (= n 0)
22
23
(* n (f (- n 1)))))))
83
24
25
26
27
28
29
;; *EOF*
9.4.2
#!/usr/bin/racket
;; y-combinator-normal.scm
;; Mac Radigan
;;
6
7
#lang lazy
8
9
10
11
(define Y
(lambda (f)
12
13
14
15
16
(define almost-factorial
(lambda (f)
17
(lambda (n)
18
(if (= n 0)
19
20
21
(* n (f (- n 1)))))))
22
23
24
25
26
27
;; *EOF*
9.4.3
84
#!/usr/bin/racket
;; y-combinator-normal.scm
;; Mac Radigan
;;
#lang lazy
7
8
9
10
(define Y
11
(lambda (f)
12
13
14
15
(define almost-factorial
16
(lambda (f)
17
(lambda (n)
18
(if (= n 0)
19
20
21
(* n (f (- n 1)))))))
22
23
24
25
26
27
;; *EOF*
## ./y-combinator-normal.rkt-lazy
720
9.5
The Strict (Applicative-Order) Y Combinator can be used with both applicative order and lazy evaluation
[?].
9.5.1
85
#!/usr/bin/csi -s
;; y-combinator-struct.scm
;; Mac Radigan
;;
6
7
(load "../library/util.scm")
(import util)
9
10
11
12
13
14
15
16
(define Y
(lambda (f)
((lambda (x) (x x))
(lambda (x) (f (lambda (y) ((x x) y)))))))
17
18
19
20
(define almost-factorial
(lambda (f)
(lambda (n)
(if (= n 0)
21
22
23
(* n (f (- n 1)))))))
24
25
26
27
28
29
30
(* n (f (- n 1)))))))
31
32
33
34
35
36
;; *EOF*
## ./y-combinator-strict.scm
86
9.5.2
#!/usr/bin/racket
;; y-combinator-struct.scm
;; Mac Radigan
;;
#lang racket
7
8
9
10
(define Y
11
(lambda (f)
12
13
14
15
(define almost-factorial
16
(lambda (f)
17
(lambda (n)
18
(if (= n 0)
19
20
21
(* n (f (- n 1)))))))
22
23
24
(lambda (n)
25
(if (= n 0)
26
27
28
(* n (f (- n 1)))))))
29
30
31
32
33
34
;; *EOF*
## ./y-combinator-strict.rkt
720
87
9.5.3
#!/usr/bin/racket
;; y-combinator-struct.scm
;; Mac Radigan
;;
#lang lazy
7
8
9
10
(define Y
11
(lambda (f)
12
13
14
15
(define almost-factorial
16
(lambda (f)
17
(lambda (n)
18
(if (= n 0)
19
20
21
(* n (f (- n 1)))))))
22
23
24
(lambda (n)
25
(if (= n 0)
26
27
28
(* n (f (- n 1)))))))
29
30
31
32
33
34
;; *EOF*
## ./y-combinator-strict.rkt-lazy
720
88
References
[1] H. Abelson and G. J. Sussman, Structure and Interpretation of Computer Programs, 2nd Edition.
Cambridge, MA, USA: MIT Press, 1996.
[2] P. Graham, On LISP: Advanced Techniques for Common LISP. Upper Saddle River, NJ, USA: PrenticeHall, Inc., 1993.
[3] M. Mvanier, The y combinator (slight return) or how to succeed at recursion without really recursing,
http://mvanier.livejournal.com/2897.html, 2010.
[4] Wikipedia, Fixed-point combinator Wikipedia, the free encyclopedia, 2011, [Online; accessed
11-July-2016]. [Online]. Available: http://en.wikipedia.org/Fixed-point combinator
[5] J. Bender, Read scheme, 2009, [Online; accessed 11-July-2016]. [Online]. Available:
http:
//readscheme.org
[6] ,
Read scheme,
2009,
[Online;
http:
//repository.readscheme.org/ftp
[7] K. E. Iverson, Notation as a tool of thought, 2006, [Online; accessed 11-July-2016]. [Online].
Available: http://www.eecg.toronto.edu/jzhu/csc326/readings/iverson.pdf
[8] P. Michaux,
peter.michaux.ca,
2006,
[Online;
http://peter.michaux.ca
[9] , bootstrap-scheme, 2010, [Online;
https:
//github.com/petermichaux/bootstrap-scheme
[10] H. G. Baker, Cons should not cons its arguments, part ii: Cheney on the m.t.a. SIGPLAN Not.,
vol. 30, no. 9, pp. 1720, Sep. 1995. [Online]. Available: http://doi.acm.org/10.1145/214448.214454
[11] J. A. Brzozowski, Derivatives of regular expressions, J. ACM, vol. 11, no. 4, pp. 481494, Oct. 1964.
[Online]. Available: http://doi.acm.org/10.1145/321239.321249
[12] B. Ford and M. F. Kaashoek, Packrat parsing: a practical linear-time algorithm with backtracking,
2002.
[13] G. L. Steele, Jr., Common LISP: The Language, (2nd Ed.).
[14] J. A. Brzozowski, Derivatives of regular expressions, J. ACM, vol. 11, no. 4, pp. 481494, Oct. 1964.
[Online]. Available: http://doi.acm.org/10.1145/321239.321249
89
[15] P. Norvig, Paradigms of Artificial Intelligence Programming: Case Studies in Common Lisp, 1st ed.
San Francisco, CA, USA: Morgan Kaufmann Publishers Inc., 1992.
90