Advertisement
Guest User

Untitled

a guest
Apr 29th, 2019
124
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (defn evaluate [expr vars] ((.evaluate expr) vars))
  2. (defn toString [expr] (.toStr expr))
  3. (defn diff [expr var] ((.diff expr) var))
  4.  
  5. ;Interface
  6. (definterface Operation
  7.   (evaluate [])
  8.   (toStr [])
  9.   (diff []))
  10.  
  11. ;Const
  12. (declare Constant)
  13.  
  14. (deftype Const [value]
  15.   Operation
  16.   (evaluate [this] (fn [vars] value))
  17.   (toStr [this] (format "%.1f" (double value)))
  18.   (diff [this] (fn [var] (Constant 0))))
  19.  
  20. (defn Constant [val] (Const. val))
  21.  
  22. (deftype Var [name]
  23.   Operation
  24.   (evaluate [this] (fn [args] (get args name)))
  25.   (toStr [this] name)
  26.   (diff [this] (fn [args] (if (= args name) (Constant 1) (Constant 0)))))
  27.  
  28. (defn Variable [name] (Var. name))
  29.  
  30. (deftype OperationPrototype [op symbol howToDiff])
  31.  
  32. (deftype MakeOperation [prot args]
  33.   Operation
  34.   (evaluate [this] (fn [args] (apply (.op prot) (map (fn [x] (evaluate x args)) args))))
  35.   (toStr [this] (str "(" (.symbol prot) " " (clojure.string/join " " (map toString args)) ")"))
  36.   (diff [this] (fn [args] (apply (.howToDiff prot) (concat args (map (fn [x] (diff x args)) args))))))
  37.  
  38. (declare Add)
  39. (def AddProt (OperationPrototype.
  40.                +
  41.                "+"
  42.                (fn [a b da db] (Add da db))))
  43.  
  44. (defn Add [& ar]
  45.   (MakeOperation. AddProt ar))
  46.  
  47. (declare Subtract)
  48. (def SubProt (OperationPrototype.
  49.                -
  50.                "-"
  51.                (fn [a b da db] (Subtract da db))))
  52.  
  53. (defn Subtract [& ar]
  54.   (MakeOperation. SubProt ar))
  55.  
  56. (declare Multiply)
  57. (def MultiplyProt (OperationPrototype.
  58.                     *
  59.                     "*"
  60.                     (fn [a b da db] (Add (Multiply da b) (Multiply a db)))))
  61.  
  62. (defn Multiply [& ar]
  63.   (MakeOperation. MultiplyProt ar))
  64.  
  65. (declare Divide)
  66. (def DivideProt (OperationPrototype.
  67.                   (fn [x y] (/ (double x) (double y)))
  68.                   "/"
  69.                   (fn [a b da db] (Divide (Subtract (Multiply da b) (Multiply a db)) (Multiply b b)))))
  70.  
  71. (defn Divide [& ar]
  72.   (MakeOperation. DivideProt ar))
  73.  
  74. (declare Negate)
  75. (def NegateProt (OperationPrototype.
  76.                   -
  77.                   "negate"
  78.                   (fn [a da] (Negate da))))
  79.  
  80. (defn Negate [& ar]
  81.   (MakeOperation. NegateProt ar))
  82.  
  83. (def operationsMap {"+" Add,
  84.           "-"           Subtract,
  85.           "*"           Multiply,
  86.           "/"           Divide,
  87.           "negate"      Negate})
  88.  
  89. (def vars {'x (Variable "x"),
  90.            'y (Variable "y"),
  91.            'z (Variable "z")})
  92.  
  93. (defn parse [expression]
  94.   (cond
  95.     (symbol? expression) (get vars expression)
  96.     (number? expression) (Constant expression)
  97.     :else (let [op (first expression) args (rest expression)] (apply (get operationsMap (str op)) (map parse args)))))
  98.  
  99. (defn parseObject [expression] (parse (read-string expression)))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement