From: Ramakrishnan Muthukrishnan Date: Sat, 4 Sep 2010 03:38:49 +0000 (+0530) Subject: symbolic differentiation section X-Git-Url: https://git.rkrishnan.org/?a=commitdiff_plain;h=a756568ee7ee1998fbf4277a65fd358b3335374f;p=sicp.git symbolic differentiation section --- diff --git a/src/sicp/ch2_3.clj b/src/sicp/ch2_3.clj index 28df094..b1eea97 100644 --- a/src/sicp/ch2_3.clj +++ b/src/sicp/ch2_3.clj @@ -1,7 +1,67 @@ -(ns sicp.ch2_3) +(ns sicp.ch2_3 + (:use [sicp.utils :only (error)])) (defn memq [item x] (cond (empty? x) false (= (first x) item) x - :else (memq item (rest x)))) \ No newline at end of file + :else (memq item (rest x)))) + +;; differentiation + +;; take it for granted the following primitives. +(declare variable? same-variable? sum? addend augend make-sum product? make-product multiplier multiplicand) + +(defn 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 -- derive"))) + +(defn variable? [x] + (symbol? x)) + +(defn same-variable? [v1 v2] + (and (variable? v1) + (variable? v2) + (= v1 v2))) + +(defn =number? [exp num] + (and (number? exp) (= exp num))) + +(defn make-sum [a1 a2] + (cond (=number? a1 0) a2 + (=number? a2 0) a1 + (and (number? a1) (number? a2)) (+ a1 a2) + :else (list '+ a1 a2))) + +(defn 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))) + +(defn sum? [x] + (and (list? x) (= (first x) '+))) + +(defn addend [s] + (second s)) + +(defn augend [s] + (second (rest s))) + +(defn product? [x] + (and (list? x) (= (first x) '*))) + +(defn multiplier [p] + (second p)) + +(defn multiplicand [p] + (second (rest p))) +