;; Proves that a function is differentiable
(defstep diff? ()
 (then 
   (auto-rewrite "diff_id" "diff_const" "diff_plus" "diff_times_const" "diff_times" 
                 "diff_minus" "diff_neg" "diff_div_const" "diff_div" "diff_sqrt_pos" 
                 "diff_comp" "diff_sq" "diff_sin" "diff_cos"
		 "diff_exp" "diff_log")
   (do-rewrite))
 "Tries to prove a goal having the form derivable(f)."
 "(diff?)"
)

;; Rewrites with all the names 
(defstep rewrites (names)
  (let ((step   (when names (list 'rewrite (car names))))
        (rnames (when names (cdr names))))
       (if names (else step (rewrites rnames))
                 (skip)))
  "Tries to rewrite with all the names"
  "(rewrites (names))"
)

;; Finds the derivative of a function
(defstep deriv ()
  (branch
    (repeat 
      (rewrites ("deriv_id" "deriv_const" "deriv_plus" "deriv_times_const" 
                 "deriv_times" "deriv_minus" "deriv_neg" "deriv_div_const" 
                 "deriv_div" "deriv_sqrt_pos" "deriv_comp" 
                 "deriv_sq" "deriv_sin" "deriv_cos" "deriv_exp" "deriv_log"
                 "sq_0" "sqrt_0" "sq_1" "sqrt_1"
                 "sin_0" "sin_PI2" "sin_PI" "sin_3PI2" "sin_2PI"
                 "cos_0" "cos_PI2" "cos_PI" "cos_3PI2" "cos_2PI")))
    ((ground)(diff?)))
  "Finds deriv(f)"
  "(deriv)"
)


;; Cancellation laws for "lt" (<), "le" (<=), "gt" (>), "ge" (>=)
(defstep cancellation (ord step)
 (let ((plus1   (concatenate 'string "both_sides_plus_" ord "1"))
       (plus2   (concatenate 'string "both_sides_plus_" ord "2"))
       (minus1  (concatenate 'string "both_sides_minus_" ord "1"))
       (minus2  (concatenate 'string "both_sides_minus_" ord "2")) 
       (timesp1 (concatenate 'string "both_sides_times_pos_" ord "1"))
       (timesp2 (concatenate 'string "both_sides_times_pos_" ord "2"))
       (timesn1 (concatenate 'string "both_sides_times_neg_" ord "1"))
       (timesn2 (concatenate 'string "both_sides_times_neg_" ord "2"))
       (divp1   (concatenate 'string "both_sides_div_pos_" ord "1"))
       (divp2   (concatenate 'string "both_sides_div_pos_" ord "2"))
       (divn1   (concatenate 'string "both_sides_div_neg_" ord "1"))
       (divn2   (concatenate 'string "both_sides_div_neg_" ord "2")))
      (branch
        (repeat 
          (rewrites (plus1 plus2 minus1 minus2 timesp1 timesp2 timesn1 timesn2
                     divp1 divp2 divn1 divn2)))
        ((ground) step )))
 "Applies cancellation laws for ord = lt (<), le (<=), gt (>), ge (>=). Uses step to solve subgoals"
 "(cancellation ord step)")
