Advertisement
Guest User

Untitled

a guest
May 14th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (defn evaluate [expression, applyMap] ((.evaluate expression) applyMap))
  2. (defn toString [expression] (.toStr expression))
  3. (defn toStringSuffix [expression] (.toStrSuff expression))
  4. (defn diff [expression, diffVarName] ((.diff expression) diffVarName))
  5.  
  6. (definterface Any
  7.   (evaluate [])
  8.   (toStr [])
  9.   (toStrSuff [])
  10.   (diff []))
  11.  
  12. (declare ZERO)
  13. (declare ONE)
  14. (declare TWO)
  15.  
  16. (deftype Const [value]
  17.   Any
  18.   (evaluate [this] (fn [applyMap] value))
  19.   (toStr [this] (format "%.1f" (double value)))
  20.   (toStrSuff [this] (format "%.1f" (double value)))
  21.   (diff [this] (fn [diffVarName] ZERO)))
  22.  
  23. (defn Constant [value] (Const. value))
  24.  
  25. (def ZERO (Constant 0))
  26. (def ONE (Constant 1))
  27. (def TWO (Constant 2))
  28.  
  29. (deftype Var [varName]
  30.   Any
  31.   (evaluate [this] (fn [applyMap] (applyMap varName)))
  32.   (toStr [this] (str varName))
  33.   (toStrSuff [this] (str varName))
  34.   (diff [this] #(if (= % varName) ONE ZERO)))
  35.  
  36. (defn Variable [varName] (Var. varName))
  37.  
  38. (deftype newOp [evalFun, opName, args, diffFun]
  39.   Any
  40.   (evaluate [this] #(apply evalFun (map (fn [x] (evaluate x %)) args)))
  41.   (toStr [this] (str "(" opName " " (clojure.string/join " " (map toString args)) ")"))
  42.   (toStrSuff [this] (str "(" (clojure.string/join " " (map toStringSuffix args)) " " opName ")"))
  43.   (diff [this] #(apply diffFun (concat args (map (fn [x] (diff x %)) args)))))
  44.  
  45. (defn Add [& args] (newOp. +, "+", args,
  46.                            (fn [a b da db] (Add da db))))
  47.  
  48. (defn Subtract [& args] (newOp. -, "-", args,
  49.                                 (fn [a b da db] (Subtract da db))))
  50.  
  51. (defn Multiply [& args] (newOp. *, "*", args,
  52.                                 (fn [a b da db] (Add
  53.                                                   (Multiply da b)
  54.                                                   (Multiply a db)))))
  55.  
  56. (defn Divide [& args] (newOp. #(/ %1 (double %2)), "/", args,
  57.                               (fn [a b da db] (Divide
  58.                                                 (Subtract
  59.                                                   (Multiply da b)
  60.                                                   (Multiply a db))
  61.                                                 (Multiply b b)))))
  62.  
  63.  
  64. (defn Negate [& arg] (newOp. -, "negate", arg,
  65.                              (fn [a da] (Negate da))))
  66.  
  67. (defn Square [& arg] (newOp. #(* % %), "square", arg,
  68.                              (fn [a da] (Multiply TWO a da))))
  69.  
  70. (defn Sqrt [& arg] (newOp. #(Math/sqrt (Math/abs ^double %)), "sqrt", arg,
  71.                            (fn [a da] (Divide (Multiply a da)
  72.                                               (Multiply TWO
  73.                                                         (Sqrt (Multiply (Square a) a)))))))
  74.  
  75.  
  76. (declare Sinh)
  77. (declare Cosh)
  78.  
  79. (defn Sinh [& arg] (newOp. #(Math/sinh %), "sinh", arg,
  80.                            (fn [a da] (Multiply da (Cosh a)))))
  81.  
  82. (defn Cosh [& arg] (newOp. #(Math/cosh %), "cosh", arg,
  83.                            (fn [a da] (Multiply da (Sinh a)))))
  84.  
  85. (defn Pow [& args] (newOp. #(Math/pow %1 %2), "**", args, ()))
  86.  
  87. (defn Log [& args] (newOp. #(/ (Math/log (Math/abs ^double %2)) (Math/log (Math/abs ^double %1))), "//", args, ()))
  88.  
  89. (def OPERATIONS {"+"      Add,
  90.                  "-"      Subtract,
  91.                  "*"      Multiply,
  92.                  "/"      Divide,
  93.                  "negate" Negate,
  94.                  "square" Square,
  95.                  "sqrt"   Sqrt,
  96.                  "sinh"   Sinh,
  97.                  "cosh"   Cosh,
  98.                  "**"     Pow,
  99.                  "//"     Log
  100.                  })
  101.  
  102. (defn parse [expression]
  103.   (cond
  104.     (number? expression) (Constant expression)
  105.     (symbol? expression) (Variable (str expression))
  106.     (list? expression) (apply (OPERATIONS (str first expression)) (map parse (rest expression)))
  107.     ))
  108.  
  109. (defn parseObject [s] (parse (read-string s)))
  110.  
  111. ;------------------------------------------------------------------------------------------
  112. (defn -return [value tail] {:value value :tail tail})
  113. (def -valid? boolean)
  114. (def -value :value)
  115. (def -tail :tail)
  116.  
  117. (defn _empty [value] (partial -return value))
  118. (defn _char [p] (fn [[c & cs]] (if (and c (p c)) (-return c cs))))
  119. (defn _map [f] (fn [result] (if (-valid? result) (-return (f (-value result)) (-tail result)))))
  120. (defn _combine [f a b] (fn [str] (let [ar ((force a) str)]
  121.                                    (if (-valid? ar) ((_map (partial f (-value ar))) ((force b) (-tail ar)))))))
  122. (defn _either [a b] (fn [str] (let [ar ((force a) str)] (if (-valid? ar) ar ((force b) str)))))
  123. (defn _parser [p] (fn [input] (-value ((_combine (fn [v _] v) p (_char #{\u0000})) (str input \u0000)))))
  124.  
  125. (defn +char [chars] (_char (set chars)))
  126. (defn +char-not [chars] (_char (comp not (set chars))))
  127. (defn +map [f parser] (comp (_map f) parser))
  128. (defn iconj [coll value] (if (= value 'ignore) coll (conj coll value)))
  129. (defn +seq [& ps] (reduce (partial _combine iconj) (_empty []) ps))
  130. (defn +seqf [f & ps] (+map (partial apply f) (apply +seq ps)))
  131. (defn +seqn [n & ps] (apply +seqf (fn [& vs] (nth vs n)) ps))
  132. (defn +or [p & ps] (reduce (partial _either) p ps))
  133. (defn +opt [p] (+or p (_empty nil)))
  134. (defn +star [p] (letfn [(rec [] (+or (+seqf cons p (delay (rec))) (_empty ())))] (rec)))
  135. (defn +plus [p] (+seqf cons p (+star p)))
  136. (defn +str [p] (+map (partial apply str) p))
  137.  
  138. (def +parser _parser)
  139. (def +ignore (partial +map (constantly 'ignore)))
  140.  
  141.  
  142. (def *possible-chars (mapv char (range 32 128)))
  143. (def *whitespace (+char (apply str (filter #(Character/isWhitespace ^char %) *possible-chars))))
  144. (def *letter (+char (apply str (filter #(Character/isLetter ^char %) *possible-chars))))
  145. (def *digit (+char (apply str (filter #(Character/isDigit ^char %) *possible-chars))))
  146.  
  147. (def *ws (+ignore (+star *whitespace)))
  148.  
  149. (def *const (+map (comp Constant read-string) (+str (+seq (+opt (+char "-")) (+str (+plus *digit)) (+char ".") *digit))))
  150.  
  151. (def operation (+or *letter (+char "+-*/")))
  152. (def *identifier (+str (+seqf cons *ws operation (+star (+or operation *digit)))))
  153.  
  154. (def *variable (+map (comp #(get OPERATIONS (str %) (Variable (str %))) symbol) *identifier))
  155.  
  156. ;
  157. ;TODO make better previous raw
  158. ;
  159.  
  160. (declare *expression)
  161. (defn *seq [p] (+seqn 1 *ws (+char "(") (+opt (+seqf cons *ws p (+star (+seqn 0 *ws p)))) *ws (+char ")")))
  162. (def *list (+map (fn [list] (apply (last list) (butlast list))) (*seq (delay *expression))))
  163. (def *expression (+or *const *variable *list))
  164.  
  165. (def parseObjectSuffix (+parser (+seqn 0 *ws *expression *ws)))
  166. ;(def expr (Log (Add (Constant 2.0) (Multiply (Constant 4.0) (Subtract (Variable "x") (Variable "z")))) (Add (Constant 1.0) (Multiply (Constant 2.0) (Subtract (Variable "y") (Variable "z"))))))
  167. ;(println (evaluate expr {"z" 1.0, "x" 0.0, "y" 0.0}))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement