33 lines
927 B
Janet
33 lines
927 B
Janet
(defn diff [expr var]
|
|
(cond
|
|
(symbol? expr) (if (= expr var) 1 0)
|
|
(number? expr) 0
|
|
(match expr
|
|
[op & args] (case op
|
|
'+ ['+ ;(map |(diff $ var) args)]
|
|
'* (let [[a b] args]
|
|
['+ ['* (diff a var) b]
|
|
['* a (diff b var)]])
|
|
(errorf "unknown op: %v" op)))))
|
|
|
|
(defn simplify [expr]
|
|
(cond
|
|
(symbol? expr) expr
|
|
(number? expr) expr
|
|
(match expr [op & args]
|
|
(do
|
|
(def args (map simplify args))
|
|
(case op
|
|
'+ (do
|
|
(def terms (filter |(not= $ 0) args))
|
|
(if (= (length terms) 1) (first terms) ['+ ;terms]))
|
|
'* (cond
|
|
(find |(= $ 0) args) 0
|
|
(find |(= $ 1) args) (first (filter |(not= $ 1) args))
|
|
['* ;args]) # otherwise leave unchanged
|
|
[op ;args])))))
|
|
|
|
|
|
(pp (simplify (diff '(+ (* x x) 3) 'x)))
|
|
(pp (simplify (diff '(+ x 3) 'x)))
|