Resource > SICP Exersise 2_73
Exersise 2.73
a. 上記は何をしているか。
"number?"や"same-variable?"は、なぜデータ手動方式に吸収されないか。
number?やsame-variable?にはTYPEに相当するものが存在しないから。
b,c. 加算や乗算の微分や必要な補助コードをテーブルに導入する手続きを書く。
d. `deriv' 手続きが下記の場合、変更が必要な箇所は?
((get (operator exp) 'deriv) (operands exp) var)
put手続きの引数の順序
(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))))
(define (operator exp) (car exp))
(define (operands exp) (cdr exp))
a. 上記は何をしているか。
"number?"や"same-variable?"は、なぜデータ手動方式に吸収されないか。
number?やsame-variable?にはTYPEに相当するものが存在しないから。
b,c. 加算や乗算の微分や必要な補助コードをテーブルに導入する手続きを書く。
(define (make-table)
(let ((local-table (list '*table*)))
(define (lookup key-1 key-2)
(let ((subtable (assoc key-1 (cdr local-table))))
(if subtable
(let ((record (assoc key-2 (cdr subtable))))
(if record
(cdr record)
#f))
#f)))
(define (insert! key-1 key-2 value)
(let ((subtable (assoc key-1 (cdr local-table))))
(if subtable
(let ((record (assoc key-2 (cdr subtable))))
(if record
(set-cdr! record value)
(set-cdr! subtable
(cons (cons key-2 value)
(cdr subtable)))))
(set-cdr! local-table
(cons (list key-1
(cons key-2 value))
(cdr local-table)))))
'ok)
(define (dispatch m)
(cond ((eq? m 'lookup-proc) lookup)
((eq? m 'insert-proc!) insert!)
(else (error "Unknown operation -- TABLE" m))))
dispatch))
(define operation-table (make-table))
(define get (operation-table 'lookup-proc))
(define put (operation-table 'insert-proc!))
;; 微分の各手続きをテーブルにインストール
(define (install-deriv-package)
(define (addend s) (car s))
(define (augend s)
(if (null? (cddr s))
(cadr s)
(cons '+ (cdr s))))
(define (multiplier p) (car p))
(define (multiplicand p)
(if (null? (cddr p))
(cadr p)
(cons '* (cdr p))))
(define (base exp)
(car exp))
(define (exponent exp)
(cadr exp))
(define (make-sum x y)
(cond [(and (number? x) (number? y)) (+ x y)]
[(eq? x 0) y]
[(eq? y 0) x]
[else (list '+ x y)] ))
(define (make-product x y)
(cond [(and (number? x) (number? y)) (* x y)]
[(eq? x 1) y]
[(eq? y 1) x]
[(or (eq? x 0) (eq? y 0)) 0]
[else (list '* x y)]))
(define (make-exponentation x y)
(cond [(and (number? x) (number? y)) (expt x y)]
[(or (eq? x 0) (eq? x 1)) x]
[(eq? y 1) x]
[(eq? y 0) 1]
[else (list '** x y)]))
(define (sum exp var)
(make-sum
(deriv (addend exp) var)
(deriv (augend exp) var)))
(define (product exp var)
(make-sum
(make-product (multiplier exp)
(deriv (multiplicand exp) var))
(make-product (deriv (multiplier exp) var)
(multiplicand exp))))
(define (exponentation exp var)
(make-product
(make-product (exponent exp)
(make-exponentation (base exp) (- (exponent exp) 1)))
(deriv (base exp) var)))
(put 'deriv '+ sum)
(put 'deriv '* product)
(put 'deriv '** exponentation)
'done)
(install-deriv-package)
;; 微分手続き
(define (deriv exp var)
(cond ((number? exp) 0)
((variable? exp) (if (eq? exp var) 1 0))
(else ((get 'deriv (operator exp) ) (operands exp)
var))))
(define (variable? var)
(not (pair? var)))
(define (operator exp) (car exp))
(define (operands exp) (cdr exp))
d. `deriv' 手続きが下記の場合、変更が必要な箇所は?
((get (operator exp) 'deriv) (operands exp) var)
put手続きの引数の順序
(put '+ 'deriv sum) (put '* 'deriv product) (put '** 'deriv exponentation)