; Symbolic derivation (define (diff e) (define (sum e1 e2) (cond ((and (number? e1) (number? e2)) (+ e1 e2)) ((eq? e1 0) e2) ((eq? e2 0) e1) (else `(+ ,e1 ,e2)))) (define (sub e1 e2) (cond ((and (number? e1) (number? e2)) (- e1 e2)) ((eq? e1 0) `(* -1 ,e2)) ((eq? e2 0) e1) ((eq? e1 e2) 0) (else `(-,e1 ,e2)))) (define (prod e1 e2) (cond ((and (number? e1) (number? e2)) (* e1 e2)) ((eq? e1 0) 0) ((eq? e2 0) 0) ((eq? e1 1) e2) ((eq? e2 1) e1) (else `(* ,e1 ,e2)))) (define (div e1 e2) (cond ((and (number? e1) (number? e2)) (/ e1 e2)) ((eq? e1 0) 0) ((eq? e2 1) e1) ((eq? e1 e2) 1) (else `(/ ,e1 ,e2)))) (define (expt* e1 e2) (cond ((eq? e2 0) 1) ((eq? e2 1) e1) (else `(expt ,e1 ,e2)))) (if (not (pair? e)) (if (eq? e 'x) 1 0) (case (car e) ((+) (let ((e1 (cadr e)) (e2 (caddr e))) (sum (diff e1) (diff e2)))) ((-) (let ((e1 (cadr e)) (e2 (caddr e))) (sub (diff e1) (diff e2)))) ((*) (let ((e1 (cadr e)) (e2 (caddr e))) (sum (prod e1 (diff e2)) (prod (diff e1) e2)))) ((/) (let ((z (cadr e)) (n (caddr e))) (div (sub (prod n (diff z)) (prod z (diff n))) (prod n n)))) ((expt) (let ((e1 (cadr e)) (e2 (caddr e))) (if (number? e2) (prod e2 (prod (expt* e1 (- e2 1)) (diff e1))) (error "Not implemented")))) (else (error "Invalid expression")))))