forked from l0stman/sicp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
2.57.tex
108 lines (93 loc) · 2.89 KB
/
2.57.tex
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
\documentclass[a4paper,12pt]{article}
\usepackage{listings}
\lstset{language=Lisp}
\begin{document}
\begin{lstlisting}
(define (deriv exp var)
(cond ((number? 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))))
((exponentiation? exp)
(make-product
(exponent exp)
(make-product (make-exponentiation
(base exp)
(make-sub (exponent exp) 1))
(deriv (base exp) var))))
(else
(error "unknown expression type -- DERIV"
exp))))
(define (variable? x) (symbol? x))
(define (same-variable? v1 v2)
(and (variable? v1) (variable? v2) (eq? v1 v2)))
(define (simplify proc acc vars args)
(cond ((null? args)
(cons acc vars))
((number? (car args))
(simplify proc
(proc (car args) acc)
vars
(cdr args)))
(else
(simplify proc
acc
(cons (car args) vars)
(cdr args)))))
(define (make-sum a1 a2 . rest)
(let ((lst (simplify + 0 '()
(cons a1 (cons a2 rest)))))
(cond ((null? (cdr lst)) (car lst))
((zero? (car lst))
(if (null? (cddr lst))
(cadr lst)
(cons '+ (cdr lst))))
(else (cons '+ lst)))))
(define (=number? exp num)
(and (number? exp) (= exp num)))
(define (sum? x)
(and (pair? x) (eq? (car x) '+)))
(define (addend s) (cadr s))
(define (augend s)
(let ((lst (cddr s)))
(if (null? (cdr lst))
(car lst)
(cons '+ lst))))
(define (make-product m1 m2 . rest)
(let ((lst (simplify * 1 '()
(cons m1 (cons m2 rest)))))
(cond ((null? (cdr lst)) (car lst))
((= (car lst) 0) 0)
((= (car lst) 1)
(if (null? (cddr lst))
(cadr lst)
(cons '* (cdr lst))))
(else (cons '* lst)))))
(define (product? x)
(and (pair? x) (eq? (car x) '*)))
(define (multiplier p) (cadr p))
(define (multiplicand p)
(let ((lst (cddr p)))
(if (null? (cdr lst))
(car lst)
(cons '* lst))))
(define (make-sub a1 a2)
(make-sum a1 (make-product -1 a2)))
(define (make-exponentiation base exponent)
(cond ((=number? exponent 0) 1)
((=number? exponent 1) base)
(else (list '** base exponent))))
(define (exponentiation? x)
(and (pair? x) (eq? (car x) '**)))
(define (base e) (car (cdr e)))
(define (exponent e) (car (cdr (cdr e))))
\end{lstlisting}
\end{document}