-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path2.73.rkt
122 lines (102 loc) · 3.4 KB
/
2.73.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
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
#lang sicp
(define (contents datum)
(if (pair? datum)
(cdr datum)
(error "Bad tagged datum -- CONTENTS" datum)))
(define (=number? exp num)
(and (number? exp) (= exp num)))
(define (variable? x) (symbol? x))
(define (same-variable? x y) (and (variable? x) (variable? y) (eq? x y)))
(define (apply-generic op . args)
(let ((type-tags (map type-tag args)))
(let ((proc (get op type-tags)))
(if proc
(apply proc (map contents args))
(error "No method for these types -- APPLY-GENERIC"
(list op type-tags))))))
(define (operator exp) (car exp))
(define (operands exp) (cdr exp))
(define table (list))
(define (put op type proc)
(set! table (append table (list (list op type proc)))))
(define (get op type)
(define (search op type t)
(cond ((null? t) #f)
((and (eqv? (caar t) op) (eqv? (cadar t) type))
(caddar t))
(else (search op type (cdr t)))))
(search op type table))
(define (attach-tag type-tag contents)
(cons type-tag contents))
(define (type-tag datum)
(if (pair? datum)
(car datum)
(error "Bad tagged datum -- TYPE-TAG" datum)))
(define (content datum)
(if (pair? datum)
(cdr datum)
(error "Bad tagged datum -- CONTENTS" datum)))
(define (install-sum-package)
(define (make-sum a b)
(cond ((eq? a 0) b)
((eq? b 0) a)
((and (number? a) (number? b)) (+ a b))
(else (list '+ a b))))
(define (addend s) (car s))
(define (augend s) (cadr s))
(define (deriv-sum s var)
(make-sum (deriv (addend s) var)
(deriv (augend s) var)))
(put 'deriv '+ deriv-sum))
(define (install-product-package)
(define (multiplier s) (car s))
(define (multiplicand s) (cadr s))
(define (make-product a b)
(cond ((or (eq? a 0) (eq? b 0)) 0)
((eq? a 1) b)
((eq? b 1) a)
((and (number? a) (number? b)) (* a b))
(else (list '* a b))))
(define (make-sum a b)
(cond ((eq? a 0) b)
((eq? b 0) a)
((and (number? a) (number? b)) (+ a b))
(else (list '+ a b))))
(define (deriv-product p var)
(make-sum
(make-product (multiplier p)
(deriv (multiplicand p) var))
(make-product (deriv (multiplier p) var)
(multiplicand p))))
(put 'deriv '* deriv-product))
(define (install-exponent-package)
(define (make-product a b)
(cond ((or (eq? a 0) (eq? b 0)) 0)
((eq? a 1) b)
((eq? b 1) a)
((and (number? a) (number? b)) (* a b))
(else (list '* a b))))
(define (exponent expr)
(cadr expr))
(define (base expr)
(car expr))
(define (make-exponentiation base exponent)
(cond ((=number? exponent 0) 1)
((=number? exponent 1) base)
((=number? base 1) 1)
(else (list '** base exponent))))
(define (deriv-exponent exp var)
(make-product (make-product (exponent exp) (make-exponentiation (base exp) (- (exponent exp) 1))) (deriv (base exp) var)))
(put 'deriv '** deriv-exponent))
(define (deriv exp var)
(cond ((number? exp) 0)
((variable? exp) (if (same-variable? exp var) 1 0))
(else ((get 'deriv (operator exp)) (operands exp) var))))
(install-sum-package)
(install-product-package)
(install-exponent-package)
(get 'deriv '+)
(deriv '(+ x x) 'x)
(deriv '(* x y) 'x)
(display (deriv '(+ (* x 2) (* x y)) 'x))
(display (deriv '(+ (** x 3) (* x y)) 'x))