-
Notifications
You must be signed in to change notification settings - Fork 1
/
ex232.lisp
139 lines (105 loc) · 3.05 KB
/
ex232.lisp
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
; Answers for 2-3-2
(defun deriv (exp var)
(cond ((numberp exp) 0)
((variable? exp)
(if (same-variable? exp var) 1 0))
((sum? exp)
(make-sum (deriv (addend exp) var)
(deriv (augend exp) var)))
((product? exp)
(make-sum
(make-product (multiplier exp)
(deriv (multiplicand exp) var))
(make-product (deriv (multiplier exp) var)
(multiplicand exp))))
(t (error "unknown expression type -- DERIV"))))
(defun variable? (x)
(symbolp x))
(defun same-variable? (x y)
(and (variable? x) (variable? y) (eq x y)))
(defun make-sum (a1 a2)
(cond ((=numberp a1 0) a2)
((=numberp a2 0) a1)
((and (numberp a1) (numberp a2)) (+ a1 a2))
(t (list '+ a1 a2))))
(defun =numberp (exp num)
(and (numberp exp) (= exp num)))
(defun make-product (m1 m2)
(cond ((or (=numberp m1 0) (=numberp m2 0)) 0)
((=numberp m1 1) m2)
((=numberp m2 1) m1)
((and (numberp m1) (numberp m2)) (* m1 m2))
(t (list '* m1 m2))))
(defun sum? (exp)
(and (listp exp) (eq (car exp) '+)))
(defun addend (s)
(cadr s))
(defun augend (s)
(caddr s))
(defun product? (exp)
(and (listp exp) (eq (car exp) '*)))
(defun multiplier (p)
(cadr p))
(defun multiplicand (p)
(caddr p))
; Exercise 2.56
(defun exponentiation? (exp)
(and (listp exp) (eq (car exp) '**)))
(defun base (exp)
(cadr exp))
(defun exponent (exp)
(caddr exp))
(defun make-exponentiation (base exponent)
(cond ((= exponent 0) 1)
((= exponent 1) base)
((numberp base) (expt base exponent))
(t (list '** base exponent))))
(defun deriv-2 (exp var)
(cond ((numberp exp) 0)
((variable? exp)
(if (same-variable? exp var) 1 0))
((exponentiation? exp)
(make-product
(make-product
(exponent exp)
(make-exponentiation (base exp) (1- (exponent exp))))
(deriv-2 (base exp) var)))
((sum? exp)
(make-sum (deriv-2 (addend exp) var)
(deriv-2 (augend exp) var)))
((product? exp)
(make-sum
(make-product (multiplier exp)
(deriv-2 (multiplicand exp) var))
(make-product (deriv-2 (multiplier exp) var)
(multiplicand exp))))
(t (error "unknown expression type -- DERIV"))))
; Exercise 2.57
(defun augend (exp)
(let ((rest (cddr exp)))
(if (null (cdr rest))
(car rest)
(list* '+ rest))))
(defun multiplicand (exp)
(let ((rest (cddr exp)))
(if (null (cdr rest))
(car rest)
(list* '* rest))))
;; Could be abstracted into a common pattern?
; Exercise 2.58
; a)
(defun addend (s)
(car s))
(defun augend (s)
(caddr s))
(defun multiplier (p)
(car p))
(defun multiplicand (p)
(caddr p))
(defun sum? (exp)
(and (listp exp) (eq (cadr exp) '+)))
(defun product? (exp)
(and (listp exp) (eq (cadr exp) '*)))
; b)
;; Not given how 'deriv' is defined.
;; i.e.. Is (3 * 4 + 4) a sum or a product?