Blame


1 12687dd9 2023-08-04 jrmu ;; The first three lines of this file were inserted by DrScheme. They record metadata
2 12687dd9 2023-08-04 jrmu ;; about the language level of this file in a form that our tools can easily process.
3 12687dd9 2023-08-04 jrmu #reader(lib "htdp-advanced-reader.ss" "lang")((modname |32.1|) (read-case-sensitive #t) (teachpacks ((lib "draw.ss" "teachpack" "htdp") (lib "arrow.ss" "teachpack" "htdp") (lib "gui.ss" "teachpack" "htdp"))) (htdp-settings #(#t constructor repeating-decimal #t #t none #f ((lib "draw.ss" "teachpack" "htdp") (lib "arrow.ss" "teachpack" "htdp") (lib "gui.ss" "teachpack" "htdp")))))
4 12687dd9 2023-08-04 jrmu ;A SchemeData (a representation of a Scheme expression) is either
5 12687dd9 2023-08-04 jrmu ;1. a number,
6 12687dd9 2023-08-04 jrmu ;2. a symbol,
7 12687dd9 2023-08-04 jrmu ;3. an operator structure, or
8 12687dd9 2023-08-04 jrmu ;4. a function structure.
9 12687dd9 2023-08-04 jrmu ;5. a Lam structure.
10 12687dd9 2023-08-04 jrmu
11 12687dd9 2023-08-04 jrmu (define-struct add (left right))
12 12687dd9 2023-08-04 jrmu (define-struct sub (left right))
13 12687dd9 2023-08-04 jrmu (define-struct mul (left right))
14 12687dd9 2023-08-04 jrmu (define-struct div (left right))
15 12687dd9 2023-08-04 jrmu (define-struct function (name arg))
16 12687dd9 2023-08-04 jrmu (define-struct definition (function parameter body))
17 12687dd9 2023-08-04 jrmu (define-struct Lam (parameter body))
18 12687dd9 2023-08-04 jrmu
19 12687dd9 2023-08-04 jrmu ;An operator is a structure
20 12687dd9 2023-08-04 jrmu ;(make-operator left right)
21 12687dd9 2023-08-04 jrmu ;where operator is replaced by one of the four operators:
22 12687dd9 2023-08-04 jrmu ;1. add (addition)
23 12687dd9 2023-08-04 jrmu ;2. sub (subtraction)
24 12687dd9 2023-08-04 jrmu ;3. mul (multiplication)
25 12687dd9 2023-08-04 jrmu ;4. div (division)
26 12687dd9 2023-08-04 jrmu ;and left and right are SchemeData. It represents the expression
27 12687dd9 2023-08-04 jrmu ;(operator left right)
28 12687dd9 2023-08-04 jrmu ;in Scheme.
29 12687dd9 2023-08-04 jrmu
30 12687dd9 2023-08-04 jrmu ;A function is a structure
31 12687dd9 2023-08-04 jrmu ;(make-function name arg)
32 12687dd9 2023-08-04 jrmu ;where name is a symbol and arg is a SchemeData. It represents the expression
33 12687dd9 2023-08-04 jrmu ;(name arg)
34 12687dd9 2023-08-04 jrmu
35 12687dd9 2023-08-04 jrmu ;A definition is a structure
36 12687dd9 2023-08-04 jrmu ;(make-definition function parameter body)
37 12687dd9 2023-08-04 jrmu ;where function and parameter are symbols and body is a SchemeData.
38 12687dd9 2023-08-04 jrmu
39 12687dd9 2023-08-04 jrmu ;A Lam is a structure
40 12687dd9 2023-08-04 jrmu ;(make-Lam p b)
41 12687dd9 2023-08-04 jrmu ;where p is a symbol (representing a variable) and b is a SchemeData (representing an expression).
42 12687dd9 2023-08-04 jrmu
43 12687dd9 2023-08-04 jrmu ;numeric? : SchemeData -> boolean
44 12687dd9 2023-08-04 jrmu ;Given a-data, determine if the expression it represents is numeric. That is, numeric? evaluates true if the SchemeData lacks symbols, which corresponds to an expression which lacks variables.
45 12687dd9 2023-08-04 jrmu
46 12687dd9 2023-08-04 jrmu (define (numeric? a-data)
47 12687dd9 2023-08-04 jrmu (cond
48 12687dd9 2023-08-04 jrmu [(number? a-data) true]
49 12687dd9 2023-08-04 jrmu [(add? a-data) (and (numeric? (add-left a-data))
50 12687dd9 2023-08-04 jrmu (numeric? (add-right a-data)))]
51 12687dd9 2023-08-04 jrmu [(sub? a-data) (and (numeric? (sub-left a-data))
52 12687dd9 2023-08-04 jrmu (numeric? (sub-right a-data)))]
53 12687dd9 2023-08-04 jrmu [(mul? a-data) (and (numeric? (mul-left a-data))
54 12687dd9 2023-08-04 jrmu (numeric? (mul-right a-data)))]
55 12687dd9 2023-08-04 jrmu [(div? a-data) (and (numeric? (div-left a-data))
56 12687dd9 2023-08-04 jrmu (numeric? (div-right a-data)))]
57 12687dd9 2023-08-04 jrmu [else false]))
58 12687dd9 2023-08-04 jrmu
59 12687dd9 2023-08-04 jrmu ;evaluate-expression : SchemeData -> number
60 12687dd9 2023-08-04 jrmu ;Given a-data, evaluates the numeric expression it represents and returns the value.
61 12687dd9 2023-08-04 jrmu
62 12687dd9 2023-08-04 jrmu (define (evaluate-expression a-data)
63 12687dd9 2023-08-04 jrmu (cond
64 12687dd9 2023-08-04 jrmu [(number? a-data) a-data]
65 12687dd9 2023-08-04 jrmu [(add? a-data) (+ (evaluate-expression (add-left a-data))
66 12687dd9 2023-08-04 jrmu (evaluate-expression (add-right a-data)))]
67 12687dd9 2023-08-04 jrmu [(sub? a-data) (- (evaluate-expression (sub-left a-data))
68 12687dd9 2023-08-04 jrmu (evaluate-expression (sub-right a-data)))]
69 12687dd9 2023-08-04 jrmu [(mul? a-data) (* (evaluate-expression (mul-left a-data))
70 12687dd9 2023-08-04 jrmu (evaluate-expression (mul-right a-data)))]
71 12687dd9 2023-08-04 jrmu [(div? a-data) (/ (evaluate-expression (div-left a-data))
72 12687dd9 2023-08-04 jrmu (evaluate-expression (div-right a-data)))]))
73 12687dd9 2023-08-04 jrmu
74 12687dd9 2023-08-04 jrmu ;subst : symbol SchemeData SchemeData -> SchemeData
75 12687dd9 2023-08-04 jrmu ;Given the representation of a variable V (symbol), the expression E, and a SchemeData which represents an expression, produce a new SchemeData representing an expression where all occurrences of the variable V (symbol) have been replaced with the expression E.
76 12687dd9 2023-08-04 jrmu
77 12687dd9 2023-08-04 jrmu (define (subst V E a-data)
78 12687dd9 2023-08-04 jrmu (cond
79 12687dd9 2023-08-04 jrmu [(number? a-data) a-data]
80 12687dd9 2023-08-04 jrmu [(symbol? a-data) (cond
81 12687dd9 2023-08-04 jrmu [(symbol=? a-data V) E]
82 12687dd9 2023-08-04 jrmu [else 'free])]
83 12687dd9 2023-08-04 jrmu [(add? a-data) (make-add (subst V E (add-left a-data))
84 12687dd9 2023-08-04 jrmu (subst V E (add-right a-data)))]
85 12687dd9 2023-08-04 jrmu [(sub? a-data) (make-sub (subst V E (sub-left a-data))
86 12687dd9 2023-08-04 jrmu (subst V E (sub-right a-data)))]
87 12687dd9 2023-08-04 jrmu [(mul? a-data) (make-mul (subst V E (mul-left a-data))
88 12687dd9 2023-08-04 jrmu (subst V E (mul-right a-data)))]
89 12687dd9 2023-08-04 jrmu [(div? a-data) (make-div (subst V E (div-left a-data))
90 12687dd9 2023-08-04 jrmu (subst V E (div-right a-data)))]
91 12687dd9 2023-08-04 jrmu [(Lam? a-data) (make-Lam (Lam-parameter a-data)
92 12687dd9 2023-08-04 jrmu (subst V E (Lam-body a-data)))]
93 12687dd9 2023-08-04 jrmu [else a-data]))
94 12687dd9 2023-08-04 jrmu
95 12687dd9 2023-08-04 jrmu ;evaluate-with-one-def : SchemeData definition -> number
96 12687dd9 2023-08-04 jrmu ;Given an-exp and P, evaluate the argument an-exp, substitute that for the parameter in P, and then evaluate the body of P.
97 12687dd9 2023-08-04 jrmu
98 12687dd9 2023-08-04 jrmu (define (evaluate-with-one-def an-exp P)
99 12687dd9 2023-08-04 jrmu (cond
100 12687dd9 2023-08-04 jrmu [(and (definition? P)
101 12687dd9 2023-08-04 jrmu (numeric? an-exp)) (evaluate-expression (subst (definition-parameter P)
102 12687dd9 2023-08-04 jrmu (evaluate-expression an-exp)
103 12687dd9 2023-08-04 jrmu (definition-body P)))]
104 12687dd9 2023-08-04 jrmu [else (error 'evaluate-with-one-def "unexpected error")]))
105 12687dd9 2023-08-04 jrmu
106 12687dd9 2023-08-04 jrmu ;evaluate-with-defs : SchemeData list-of-definitions -> list-of-numbers
107 12687dd9 2023-08-04 jrmu ;Given an-exp and defs, evaluate an-exp, substitute this value in the body for each definition in the list-of-definitions in place of each one's parameter and evaluate the resulting body.
108 12687dd9 2023-08-04 jrmu
109 12687dd9 2023-08-04 jrmu (define (evaluate-with-defs an-exp defs)
110 12687dd9 2023-08-04 jrmu (cond
111 12687dd9 2023-08-04 jrmu [(empty? defs) empty]
112 12687dd9 2023-08-04 jrmu [(cons? defs) (cons (evaluate-with-one-def an-exp (first defs))
113 12687dd9 2023-08-04 jrmu (evaluate-with-defs an-exp (rest defs)))]))
114 12687dd9 2023-08-04 jrmu
115 12687dd9 2023-08-04 jrmu ;test-evaluate SchemeData list-of-definitions list-of-numbers -> boolean
116 12687dd9 2023-08-04 jrmu
117 12687dd9 2023-08-04 jrmu ;Given an-exp, defs, and expected-result, evaluate an-exp, substitute it for the parameter for the body of each of the function definitions in defs, evaluate the resulting expressions, and compare that with expected-result. Return true if the two list-of-numbers are identical, false otherwise.
118 12687dd9 2023-08-04 jrmu
119 12687dd9 2023-08-04 jrmu (define (test-evaluate an-exp defs expected-result)
120 12687dd9 2023-08-04 jrmu (equal? (evaluate-with-defs an-exp defs) expected-result))
121 12687dd9 2023-08-04 jrmu
122 12687dd9 2023-08-04 jrmu ;Exercise 32.1.1
123 12687dd9 2023-08-04 jrmu
124 12687dd9 2023-08-04 jrmu ;(make-Lam 'y 'x)
125 12687dd9 2023-08-04 jrmu ;(make-Lam 'x 'x)
126 12687dd9 2023-08-04 jrmu ;
127 12687dd9 2023-08-04 jrmu ;(lambda (y) ((lambda (x) x) x))
128 12687dd9 2023-08-04 jrmu ;
129 12687dd9 2023-08-04 jrmu ;((lambda (y) x)
130 12687dd9 2023-08-04 jrmu ; (lambda (x) x))
131 12687dd9 2023-08-04 jrmu
132 12687dd9 2023-08-04 jrmu ;Exercise 32.1.2. Develop the function
133 12687dd9 2023-08-04 jrmu
134 12687dd9 2023-08-04 jrmu ;; free-or-bound : Lam -> Lam
135 12687dd9 2023-08-04 jrmu ;; to replace each non-binding occurrence of a variable in a-lam
136 12687dd9 2023-08-04 jrmu ;; with 'free or 'bound, depending on whether the
137 12687dd9 2023-08-04 jrmu ;; occurrence is bound or not.
138 12687dd9 2023-08-04 jrmu (define (free-or-bound a-lam)
139 12687dd9 2023-08-04 jrmu (subst (Lam-parameter a-lam) 'bound a-lam))
140 12687dd9 2023-08-04 jrmu
141 12687dd9 2023-08-04 jrmu ;Tests
142 12687dd9 2023-08-04 jrmu ;(equal? (free-or-bound (make-Lam 'x 'x)) (make-Lam 'x 'bound))
143 12687dd9 2023-08-04 jrmu ;(equal? (free-or-bound (make-Lam 'x 'y)) (make-Lam 'x 'free))
144 12687dd9 2023-08-04 jrmu
145 12687dd9 2023-08-04 jrmu ;;Exercise 32.1.3. Develop the function
146 12687dd9 2023-08-04 jrmu
147 12687dd9 2023-08-04 jrmu ;; unique-binding : Lam -> Lam
148 12687dd9 2023-08-04 jrmu ;; to replace variables names of binding occurrences and their bound
149 12687dd9 2023-08-04 jrmu ;; counterparts so that no name is used twice in a binding occurrence
150 12687dd9 2023-08-04 jrmu (define (unique-binding a-lam)
151 12687dd9 2023-08-04 jrmu (local ;; the accumulator contains the name of the parameter whose scope is the current expression
152 12687dd9 2023-08-04 jrmu ((define (unique-binding-accu a-lam accu)
153 12687dd9 2023-08-04 jrmu (cond
154 12687dd9 2023-08-04 jrmu [(not (Lam? a-lam)) ...]
155 12687dd9 2023-08-04 jrmu [else
156 12687dd9 2023-08-04 jrmu (local ((define new-sym (gensym (Lam-parameter a-lam))))
157 12687dd9 2023-08-04 jrmu (make-Lam new-sym
158 12687dd9 2023-08-04 jrmu (unique-binding (Lam-body a-lam))))])))
159 12687dd9 2023-08-04 jrmu (unique-binding-accu a-lam ...)))
160 12687dd9 2023-08-04 jrmu
161 12687dd9 2023-08-04 jrmu gensym