Blame


1 665c255d 2023-08-04 jrmu (define (test-case actual expected)
2 665c255d 2023-08-04 jrmu (newline)
3 665c255d 2023-08-04 jrmu (display "Actual: ")
4 665c255d 2023-08-04 jrmu (display actual)
5 665c255d 2023-08-04 jrmu (newline)
6 665c255d 2023-08-04 jrmu (display "Expected: ")
7 665c255d 2023-08-04 jrmu (display expected)
8 665c255d 2023-08-04 jrmu (newline))
9 665c255d 2023-08-04 jrmu
10 665c255d 2023-08-04 jrmu (define (variable? x) (symbol? x))
11 665c255d 2023-08-04 jrmu (define (same-variable? v1 v2)
12 665c255d 2023-08-04 jrmu (and (variable? v1) (variable? v2) (eq? v1 v2)))
13 665c255d 2023-08-04 jrmu (define (make-sum a1 a2) (list '+ a1 a2))
14 665c255d 2023-08-04 jrmu (define (make-product m1 m2) (list '* m1 m2))
15 665c255d 2023-08-04 jrmu (define (sum? x)
16 665c255d 2023-08-04 jrmu (and (pair? x) (eq? (car x) '+)))
17 665c255d 2023-08-04 jrmu (define (addend s) (cadr s))
18 665c255d 2023-08-04 jrmu (define (augend s) (caddr s))
19 665c255d 2023-08-04 jrmu (define (product? x)
20 665c255d 2023-08-04 jrmu (and (pair? x) (eq? (car x) '*)))
21 665c255d 2023-08-04 jrmu (define (multiplier p) (cadr p))
22 665c255d 2023-08-04 jrmu (define (multiplicand p) (caddr p))
23 665c255d 2023-08-04 jrmu
24 665c255d 2023-08-04 jrmu (define (make-sum a1 a2)
25 665c255d 2023-08-04 jrmu (cond ((=number? a1 0) a2)
26 665c255d 2023-08-04 jrmu ((=number? a2 0) a1)
27 665c255d 2023-08-04 jrmu ((and (number? a1) (number? a2)) (+ a1 a2))
28 665c255d 2023-08-04 jrmu (else (list '+ a1 a2))))
29 665c255d 2023-08-04 jrmu (define (=number? exp num)
30 665c255d 2023-08-04 jrmu (and (number? exp) (= exp num)))
31 665c255d 2023-08-04 jrmu
32 665c255d 2023-08-04 jrmu (define (make-product m1 m2)
33 665c255d 2023-08-04 jrmu (cond ((or (=number? m1 0) (=number? m2 0)) 0)
34 665c255d 2023-08-04 jrmu ((=number? m1 1) m2)
35 665c255d 2023-08-04 jrmu ((=number? m2 1) m1)
36 665c255d 2023-08-04 jrmu ((and (number? m1) (number? m2)) (* m1 m2))
37 665c255d 2023-08-04 jrmu (else (list '* m1 m2))))
38 665c255d 2023-08-04 jrmu
39 665c255d 2023-08-04 jrmu ;; Exercise 2.56. Show how to extend the basic differentiator to handle more kinds of expressions. For instance, implement the differentiation rule
40 665c255d 2023-08-04 jrmu
41 665c255d 2023-08-04 jrmu ;; d(u^n)/dx = n*u^(n-1) * (du/dx)
42 665c255d 2023-08-04 jrmu
43 665c255d 2023-08-04 jrmu ;; by adding a new clause to the deriv program and defining appropriate procedures exponentiation?, base, exponent, and make-exponentiation. (You may use the symbol ** to denote exponentiation.) Build in the rules that anything raised to the power 0 is 1 and anything raised to the power 1 is the thing itself.
44 665c255d 2023-08-04 jrmu
45 665c255d 2023-08-04 jrmu (define (deriv exp var)
46 665c255d 2023-08-04 jrmu (cond ((number? exp) 0)
47 665c255d 2023-08-04 jrmu ((variable? exp) (if (same-variable? exp var) 1 0))
48 665c255d 2023-08-04 jrmu ((sum? exp) (make-sum (deriv (addend exp) var)
49 665c255d 2023-08-04 jrmu (deriv (augend exp) var)))
50 665c255d 2023-08-04 jrmu ((product? exp) (make-sum
51 665c255d 2023-08-04 jrmu (make-product (multiplier exp)
52 665c255d 2023-08-04 jrmu (deriv (multiplicand exp) var))
53 665c255d 2023-08-04 jrmu (make-product (deriv (multiplier exp) var)
54 665c255d 2023-08-04 jrmu (multiplicand exp))))
55 665c255d 2023-08-04 jrmu ((and (exponentiation? exp)
56 665c255d 2023-08-04 jrmu (number? (exponent exp)))
57 665c255d 2023-08-04 jrmu (make-product
58 665c255d 2023-08-04 jrmu (make-product (exponent exp)
59 665c255d 2023-08-04 jrmu (make-exponentiation (base exp)
60 665c255d 2023-08-04 jrmu (make-sum (exponent exp) -1)))
61 665c255d 2023-08-04 jrmu ;; or (- (exponent exp) 1)
62 665c255d 2023-08-04 jrmu (deriv (base exp) var)))
63 665c255d 2023-08-04 jrmu (error "unknown expression type -- DERIV" exp)))
64 665c255d 2023-08-04 jrmu
65 665c255d 2023-08-04 jrmu ;; by adding a new clause to the deriv program and defining appropriate procedures exponentiation?, base, exponent, and make-exponentiation. (You may use the symbol ** to denote exponentiation.) Build in the rules that anything raised to the power 0 is 1 and anything raised to the power 1 is the thing itself.
66 665c255d 2023-08-04 jrmu
67 665c255d 2023-08-04 jrmu (define (exponentiation? exp)
68 665c255d 2023-08-04 jrmu (and (pair? exp) (eq? (car exp) '**)))
69 665c255d 2023-08-04 jrmu (define (base exp)
70 665c255d 2023-08-04 jrmu (cadr exp))
71 665c255d 2023-08-04 jrmu (define (exponent exp)
72 665c255d 2023-08-04 jrmu (caddr exp))
73 665c255d 2023-08-04 jrmu
74 665c255d 2023-08-04 jrmu (define (make-exponentiation base exponent)
75 665c255d 2023-08-04 jrmu (cond ((and (=number? base 0) (=number? exponent 0)) (error "0^0 undefined"))
76 665c255d 2023-08-04 jrmu ((=number? exponent 0) 1)
77 665c255d 2023-08-04 jrmu ((=number? base 0) 0)
78 665c255d 2023-08-04 jrmu ((=number? base 1) 1)
79 665c255d 2023-08-04 jrmu ((and (number? base) (number? exponent)) (expt base exponent))
80 665c255d 2023-08-04 jrmu ((=number? exponent 1) base)
81 665c255d 2023-08-04 jrmu (else (list '** base exponent))))
82 665c255d 2023-08-04 jrmu ;; warning, does not warn if x = 0 for 0^x
83 665c255d 2023-08-04 jrmu
84 665c255d 2023-08-04 jrmu ;;(test-case (make-exponentiation 0 0) "0^0 undefined")
85 665c255d 2023-08-04 jrmu (test-case (make-exponentiation 0 1) 0)
86 665c255d 2023-08-04 jrmu (test-case (make-exponentiation 1 0) 1)
87 665c255d 2023-08-04 jrmu (test-case (make-exponentiation 5 5) 3125)
88 665c255d 2023-08-04 jrmu (test-case (make-exponentiation 'x 0) 1) ;; bug -- what if x = 0?
89 665c255d 2023-08-04 jrmu (test-case (make-exponentiation 'x 1) 'x)
90 665c255d 2023-08-04 jrmu (test-case (make-exponentiation 1 'x) 1)
91 665c255d 2023-08-04 jrmu (test-case (make-exponentiation 'x 5) '(** x 5))
92 665c255d 2023-08-04 jrmu (test-case (make-exponentiation 0 'x) 0) ;; bug -- what if x = 0?
93 665c255d 2023-08-04 jrmu (test-case (make-exponentiation 5 'x) '(** 5 x))
94 665c255d 2023-08-04 jrmu (test-case (make-exponentiation 'x 'x) '(** x x))
95 665c255d 2023-08-04 jrmu
96 665c255d 2023-08-04 jrmu (test-case (deriv (make-sum (make-sum (make-exponentiation 'x 3)
97 665c255d 2023-08-04 jrmu (make-product 3 (make-exponentiation 'x 2)))
98 665c255d 2023-08-04 jrmu (make-product 2 'x))
99 665c255d 2023-08-04 jrmu 'x)
100 665c255d 2023-08-04 jrmu '(+ (+ (* 3 (** x 2))
101 665c255d 2023-08-04 jrmu (* 6 x))
102 665c255d 2023-08-04 jrmu 2))
103 665c255d 2023-08-04 jrmu
104 665c255d 2023-08-04 jrmu ;; Exercise 2.57. Extend the differentiation program to handle sums and products of arbitrary numbers of (two or more) terms. Then the last example above could be expressed as
105 665c255d 2023-08-04 jrmu
106 665c255d 2023-08-04 jrmu ;; (deriv '(* x y (+ x 3)) 'x)
107 665c255d 2023-08-04 jrmu
108 665c255d 2023-08-04 jrmu ;; Try to do this by changing only the representation for sums and products, without changing the deriv procedure at all. For example, the addend of a sum would be the first term, and the augend would be the sum of the rest of the terms.
109 665c255d 2023-08-04 jrmu
110 665c255d 2023-08-04 jrmu ;; (define (collect-terms term structure)
111 665c255d 2023-08-04 jrmu ;; ...)
112 665c255d 2023-08-04 jrmu ;; (make-sum 1 2 3 4 5)
113 665c255d 2023-08-04 jrmu ;; (+ 1 (+ 2 (+ 3 (+ 4 5))))
114 665c255d 2023-08-04 jrmu
115 665c255d 2023-08-04 jrmu ;; (+ (+ (+ (+ 4 5)
116 665c255d 2023-08-04 jrmu ;; 3)
117 665c255d 2023-08-04 jrmu ;; 2)
118 665c255d 2023-08-04 jrmu ;; 1)
119 665c255d 2023-08-04 jrmu
120 665c255d 2023-08-04 jrmu ;; (+ 1 x 4 y -2)
121 665c255d 2023-08-04 jrmu ;; (+ 3 x y)
122 665c255d 2023-08-04 jrmu ;; (+
123 665c255d 2023-08-04 jrmu
124 665c255d 2023-08-04 jrmu ;; (test-case (combine-terms 1 '()) 0)
125 665c255d 2023-08-04 jrmu ;; (test-case (combine-terms '(+ 1 2 3)
126 665c255d 2023-08-04 jrmu ;; (test-case (+ 1 x 4 y -2) '(+ 3 x y))
127 665c255d 2023-08-04 jrmu ;; (test-case (+ 1 (* x y) (* 2 x y) -3) '(+ -2 (* 3 x y)))
128 665c255d 2023-08-04 jrmu
129 665c255d 2023-08-04 jrmu ;; (test-case (combine-constants '(+ 1 2 3)) 6)
130 665c255d 2023-08-04 jrmu ;; (define (combine-constants exp)
131 665c255d 2023-08-04 jrmu ;; (define (combine accum terms)
132 665c255d 2023-08-04 jrmu ;; (cond ((null? terms) accum)
133 665c255d 2023-08-04 jrmu ;; ((number? terms) (+ accum terms))
134 665c255d 2023-08-04 jrmu ;; ((product? terms) terms)
135 665c255d 2023-08-04 jrmu ;; ((exponentiation? terms) terms)
136 665c255d 2023-08-04 jrmu ;; ((sum? terms)
137 665c255d 2023-08-04 jrmu ;; (if (number? (addend terms))
138 665c255d 2023-08-04 jrmu ;; (combine (+ accum (addend terms)) (augend terms))
139 665c255d 2023-08-04 jrmu ;; (make-sum ()
140 665c255d 2023-08-04 jrmu
141 665c255d 2023-08-04 jrmu ;; (augend terms)
142 665c255d 2023-08-04 jrmu ;; (combine (+ accum (addend terms)) (augend terms)))))
143 665c255d 2023-08-04 jrmu ;; (combine 0 exp))
144 665c255d 2023-08-04 jrmu
145 665c255d 2023-08-04 jrmu ;; combines terms within items that share term in common
146 665c255d 2023-08-04 jrmu (define (combine-terms term items)
147 665c255d 2023-08-04 jrmu (cond ((null? items) 0)
148 665c255d 2023-08-04 jrmu ((
149 665c255d 2023-08-04 jrmu ((number? term)
150 665c255d 2023-08-04 jrmu ...)
151 665c255d 2023-08-04 jrmu (else ...)))
152 665c255d 2023-08-04 jrmu
153 665c255d 2023-08-04 jrmu ;; we no longer combine constants, nor do we combine like terms
154 665c255d 2023-08-04 jrmu ;; all sums must have at least 2 terms
155 665c255d 2023-08-04 jrmu (define (make-sum . items)
156 665c255d 2023-08-04 jrmu (cond ((null? items) 0)
157 665c255d 2023-08-04 jrmu ((null? (cdr items)) (car items))
158 665c255d 2023-08-04 jrmu (else (append (list '+) items))))
159 665c255d 2023-08-04 jrmu
160 665c255d 2023-08-04 jrmu ;; (define (make-sum . exps)
161 665c255d 2023-08-04 jrmu ;; (define (make-sum-recur items)
162 665c255d 2023-08-04 jrmu ;; (cond ((null? items) 0)
163 665c255d 2023-08-04 jrmu ;; (else (list '+ (car items) (make-sum (cdr items))))))
164 665c255d 2023-08-04 jrmu ;; (make-sum-recur items))
165 665c255d 2023-08-04 jrmu
166 665c255d 2023-08-04 jrmu ;; (if (null? augends)
167 665c255d 2023-08-04 jrmu ;; addend
168 665c255d 2023-08-04 jrmu ;; (cons addend (make-sum (car augends) (cdr augends)))))
169 665c255d 2023-08-04 jrmu ;; (list '+ addend augends))
170 665c255d 2023-08-04 jrmu (define (make-product . items)
171 665c255d 2023-08-04 jrmu (append (list '*) items))
172 665c255d 2023-08-04 jrmu
173 665c255d 2023-08-04 jrmu (define (make-sum a1 a2)
174 665c255d 2023-08-04 jrmu (cond ((=number? a1 0) a2)
175 665c255d 2023-08-04 jrmu ((=number? a2 0) a1)
176 665c255d 2023-08-04 jrmu ((and (number? a1) (number? a2)) (+ a1 a2))
177 665c255d 2023-08-04 jrmu (else (list '+ a1 a2))))
178 665c255d 2023-08-04 jrmu (define (=number? exp num)
179 665c255d 2023-08-04 jrmu (and (number? exp) (= exp num)))
180 665c255d 2023-08-04 jrmu
181 665c255d 2023-08-04 jrmu (define (make-product m1 m2)
182 665c255d 2023-08-04 jrmu (cond ((or (=number? m1 0) (=number? m2 0)) 0)
183 665c255d 2023-08-04 jrmu ((=number? m1 1) m2)
184 665c255d 2023-08-04 jrmu ((=number? m2 1) m1)
185 665c255d 2023-08-04 jrmu ((and (number? m1) (number? m2)) (* m1 m2))
186 665c255d 2023-08-04 jrmu (else (list '* m1 m2))))
187 665c255d 2023-08-04 jrmu
188 665c255d 2023-08-04 jrmu ;; assuming that all sums must contain at least 1 term
189 665c255d 2023-08-04 jrmu '(+ 1 2)
190 665c255d 2023-08-04 jrmu '(1 2)
191 665c255d 2023-08-04 jrmu '(2)
192 665c255d 2023-08-04 jrmu (define (augend s)
193 665c255d 2023-08-04 jrmu (cond ((null? (cddr s)) 0)
194 665c255d 2023-08-04 jrmu ((null? (cdddr s))
195 665c255d 2023-08-04 jrmu (caddr s))
196 665c255d 2023-08-04 jrmu (define (multiplicand p) ...)