   (is (exists-tree? '((2 3) (4 (5) 3) 2 1) 1)))
 (defn diff-const-e2-rule [d x] (and (not (exists-tree? (d 'e1) x)) d))
 (def diff-const-rule
-  ['(d (? e1) (diff-const-e2-rule e2))
+  (->rule '(d (? e1) (diff-const-e2-rule e2))
    (fn [d] 0)
-   "diff-const-rule"])
+   "diff-const-rule"))
 (defn diff-product-e3-rule [d x]
   (and (not (atom? x))
        (when-let [d2 (match-state '(* (? e1) (? e2)) x)]
          (merge d d2))))
 (def diff-product-rule
-  ['(d (diff-product-e3-rule e3) (? v1))
+  (->rule '(d (diff-product-e3-rule e3) (? v1))
    (fn [d] (list '+
                  (list '* (d 'e2) (list 'd (d 'e1) (d 'v1)))
                  (list '* (d 'e1) (list 'd (d 'e2) (d 'v1)))))
-   "diff-product-rule"])
+   "diff-product-rule"))
 (defn number-state? [d x]
   (when (number? x) d))
 (defn diff-power-e3-rule [d x]

       (when-let [d2 (match-state '(exp (? e1) (number-state? e2)) x)]
         (merge d d2))))
(def diff-power-rule
  ['(d (diff-power-e3-rule e3) (? v1))
   (fn [d] (list '* (d 'e2)
                 (list '* (list 'exp (d 'e1) (list 'dec (d 'e2)))
                       (list 'd (d 'e1) (d 'v1)))))
   "diff-power-rule"])
(def ladd-zero-rule ['(+ (? x) 0) #(% 'x) "ladd-zero-rule"])
(def radd-zero-rule ['(+ 0 (? x)) #(% 'x) "radd-zero-rule"])
(def add-const-rule ['(+ (number-state? x) (number-state? y)) #(+ (% 'x) (% 'y)) "add-const-rule"])
(def lprod-zero-rule ['(* (? x) 0) (fn [d] 0) "lprod-zero-rule"])
(def rprod-zero-rule ['(* 0 (? x)) (fn [d] 0) "rprod-zero-rule"])
(def lprod-id-rule ['(* (? x) 1) #(% 'x) "lprod-id-rule"])
(def rprod-id-rule ['(* 1 (? x)) #(% 'x) "rprod-id-rule"])
(def prod-const-rule ['(* (number-state? x) (number-state? y)) #(* (% 'x) (% 'y)) "prod-const-rule"])
(def exp-zero-rule ['(exp (? x) 0) (fn [d] 1) "exp-zero-rule"])
(def exp-id-rule ['(exp (? x) 1) #(% 'x) "exp-id-rule"])
(def dec-rule ['(dec (number-state? x)) #(dec (% 'x)) "dec-rule"])
; other rules go here ...

; TODO: Clojure HAS to have a class/record facility to do this...
(def rule-pattern first)
(def rule-action second)
(defn rule-name [rule] (nth rule 2))

(def rules
  [[diff-sum-rule diff-x-rule diff-const-rule diff-product-rule diff-power-rule]

      (when-let [temp (try-rule-on-list rule (rest expressions))]
        (cons (first expressions) temp)))))
(defn fire [rule d]
  ;(println (:name rule) "fires.")
  ((:action rule) d))
(defn try-rule [rule expression]
  (if (atom? expression)
    nil
    (if-let [d (match-state (:pattern rule) expression)]
      (fire rule d)
      (try-rule-on-list rule expression))))
(with-test
