開発環境
- OS X Lion - Apple(OS)
- Emacs、BBEdit - Bare Bones Software, Inc. (Text Editor)
- プログラミング言語: MIT/GNU Scheme
計算機プログラムの構造と解釈(Gerald Jay Sussman(原著)、Julie Sussman(原著)、Harold Abelson(原著)、和田 英一(翻訳)、ピアソンエデュケーション、原書: Structure and Interpretation of Computer Programs (MIT Electrical Engineering and Computer Science)(SICP))の2(データによる抽象の構築)、2.4(抽象データの多重表現)、2.4.3(データ主導プログラミングと加法性)の問題 2.73を解いてみる。
その他参考書籍
問題 2.73
a.
やったことは、演算(derive)対型(+, *)というテーブルを使用したデータ主導プログラミングにしていて、テーブルから対応する手続きを取得し実行している。
+ | * | |
---|---|---|
deriv | deriv-sum | deriv-product |
述語number?やvariable?がデータ主導の振り分けに吸収できないのは、数値や変数がリストではないので、手続きoperatorやoperandsを適用できないから。
b, c.
コード
sample.scm
;; 和の微分 (define (install-sum-package) ;; 内部手続き (define (inner-deriv exp var) (make-sum (deriv (addend exp) var) (deriv (augend exp) var))) (define (addend exp) (cadr exp)) (define (augend exp) (caddr exp)) (define (make-sum a1 a2) (cond ((=number? a1 0) a2) ((=number? a2 0) a1) ((and (number? a1) (number? a2)) (+ a1 a2)) (else (list '+ a1 a2)))) (define (=number? exp num) (and (number? exp) (= exp num))) ;; システムの他の部分とのインターフェース (put 'deriv '+ inner-deriv) 'done) ;; 積の微分 (define (install-product-package) ;; 内部手続き (define (inner-deriv exp var) (make-sum (make-product (multiplier exp) (deriv (multiplicand exp) var)) (make-product (deriv (multiplier exp) var) (multiplicand exp)))) (define (multiplier exp) (car (operands exp))) (define (multiplicand exp) (cadr (operands exp))) (define (make-product m1 m2) (cond ((or (=number? m1 0) (=number? v2 0)) 0) ((=number? m1 1) m2) ((=number? m2 1) m1) ((and (number? m1) (number? m2)) (* m1 m2)) (else (list '* m1 m2)))) (define (=number? exp num) (and (number? exp) (= exp num))) ;; システムの他の部分とのインターフェース (put 'deriv '* inner-deriv) 'done) ;; べき乗の微分 (define (install-expt-pakcage) ;; 内部手続き (define (inner-deriv exp var) (let ((n (exponent exp)) (u (base exp))) (* n (make-exponentitation u (- n 1)) (deriv u var)))) (define (base x) (cadr x)) (define (exponent x) (caddr x)) (define (make-exponentiaton a b) (cond ((=number? b 0) 1) ((=number? b 1) a) ((and (number? a) (number? b)) (expt a b)) (else (list '** a b)))) (define (=number? exp num) (and (number? exp) (= exp num))) ;; システムの他の部分とのインターフェース (put 'deriv '** inner-deriv) 'done)
d.
各微分のパッケージの表を操作する手続きputの第1引数、第2引数の順序を入れ替える、つまり、次のように変更すればいい。
コード
sample.scm
;; 式の型を、結合している代数演算ではなく、derivにした場合の微分システム ;; 和の微分 (define (install-sum-package) ;; 内部手続きは同じなので省略 ;; システムの他の部分とのインターフェース (put '+ 'deriv inner-deriv) 'done) ;; 積の微分 (define (install-product-package) ;; 内部手続きは同じなので省略 ;; システムの他の部分とのインターフェース (put '* 'deriv inner-deriv) 'done) ;; べき乗の微分 (define (install-expt-pakcage) ;; 内部手続きは同じなので省略 ;; システムの他の部分とのインターフェース (put '** 'deriv inner-deriv) 'done)
パッケージを呼び出して出来上がるテーブル。
deriv | |
---|---|
+ | deriv-sum |
* | deriv-product |
** | deriv-expt |
0 コメント:
コメントを投稿