SICP §2.3.2(記号微分 その1 [抽象データによる微分プログラム])

数式を受け取り、その微分形式を求めるというお題を使っているセクション。
改めて、和や積を使って表現される数式に対する微分規則はこんな感じ。


dc
─ = 0 (cは定数か、xと異なる変数)
dx

dx
─ = 1
dx

d(u + v) du dv
──── = ─ + ─
dx dx dx

d(uv) dv du
─── = u(──) + (──)v
dx dx dx

後ろ2つの微分形式は、再帰的に適用される。
つまり、例として4番目の式を適用する数式を考えると、


3 * x * (x + 1) * (x + y)
微分する場合、次のような解釈を行うことになる。

u = 3
v = x * (x + 1) * (x + y)
→ u' = x
v' = (x + 1) * (x + y)
→ u'' = (x + 1)
v'' = (x + y)
このセクションでは、数式をおそらくリストの形式で表現することになると思うが、その際、u に相当する式を car 的な方法で、v に相当する式を cdr 的な方法で抽出することになると思う。(選択子のことなんだが。)

次に、この手の式をどう表現(構成子)し、どう解釈(選択子、述語)すればいいかが記述されている。

(variable? e)e は変数か?
(same-variable? v1 v2)v1 と v2 は同じ変数か?
(sum? e) e は和か?
(addend e) e の加数
(augend e) e の被加数
(make-sum a1 a2) a1 と a2 の和を構成
(product? e) e は積か?
(multiplier e) e の乗数
(multiplicand e) e の被乗数
(make-product m1 m2) m1 と m2 の積を構成

こいつらに、「数値かどうか」を判別する number? を加えると、上述した4種の微分規則は次のように表現できる。

(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))))
	(else
	 (error "unknown expression type -- DERIV" exp))))

3番目と4番目の微分規則を表現するのに、再帰を使用しているのがミソ。