理系学生日記

おまえはいつまで学生気分なのか

問題2-58 (2.3.2 Example: Symbolic Differentiation)

記号的微分を中置記法に対して行えるように変更しろって言う課題で、変更点は以下な感じ。

(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 (make-product m1 m2)
  (cond ((or (=number? m1 0) (=number? m2 0)) 0)
	((=number? m1 1) m2)
	((=number? m2 1) m1)
	((and (number? m1) (number? m2)) (* m1 m2))
	(else (list m1 '* m2))))

(define (sum? x)
  (and (pair? x) (eq? (cadr x) '+)))

(define (addend s) (car s))

(define (augend s) (caddr s))

(define (product? x)
  (and (pair? x) (eq? (cadr x) '*)))

(define (multiplier p) (car p))

(define (multiplicand p) (caddr p))

(define (exponentiation? x)
  (and (pair? x) (eq? (cadr x) '**)))

(define (base p) (car p))

(define (exponent p) (caddr p))

(define (make-exponentiation base exponent)
  (cond ((=number? exponent 0) 1)
	((=number? exponent 1) base)
	(else (list base '** exponent))))

そしたら、4\cdot 3x^4+5の微分が中置記法ででてくる!

(deriv '((4 * (3 * (x ** 4))) + 5) 'x) ; (4 * (3 * (4 * (x ** 3))))

b.の問題に関しては

Can you design appropriate predicates, selectors, and constructors for this notation such that our derivative program still works?

ていう書き方がされてるんですけど、こういう聞かれ方をされる場合は大概できませんね!!
演算子の優先順位とかは対応がクソ難しそう、構文解析とかたぶんそういうはめになると思うのでむりぽ。
でも再帰下降型の構文解析とか、関数型言語とかにはかなりハマってくれそうだなー。