数式微分

何度見ても美しいと思うSchemeの課題をClojureで。

(defn third [x]
  (first (next (next x))))

(defn constant? [exp]
      (cond (contains? #{'+ '- '* '/ '**} exp) false
        (coll? exp) false
        :else true))

(defn diff [e x]
  (cond
    (constant? e) (if (= e x) 1 0)
    (= (first e) '+) (list '+ (diff (second e) x)
                              (diff (third e) x))
    (= (first e) '-) (list '- (diff (second e) x)
                              (diff (third e) x))
    (= (first e) '*) (list '+ (list '* (second e)
                                       (diff (third e) x))
                              (list '* (third e)
                                       (diff (second e) x)))
    (= (first e) '**) (list '* (third e)
                               (list '* (list '** (second e)
                                              (- (third e) 1))
                                      (diff (second e) x)))))

(defn simple-plus [p q]
  (cond (= p 0) q
        (= q 0) p
        :else (list '+ p q)))

(defn simple-multi [p q]
  (cond (= p 0) 0
        (= q 0) 0
        (= p 1) q
        (= q 1) p
        :else (list '* p q)))

(defn simple [e]
  (cond (constant? e) e
        (= '+ (first e)) (simple-plus (simple (second e))
                                      (simple (third e)))
        (= '* (first e)) (simple-multi (simple (second e))
                                       (simple (third e)))
        :else e))

;
; (simple (diff '(+ (* 2 x) a) 'x))
; 2
; (simple (diff '(* a (** x 2)) 'x))
; (* a (* 2 (** x 1)))