Advertisement
IzhanVarsky

Untitled

Apr 29th, 2019
136
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.81 KB | None | 0 0
  1. (defn proto-get [obj key]
  2. (cond
  3. (contains? obj key) (obj key)
  4. :else (proto-get (:prototype obj) key)))
  5.  
  6. (defn field [key] (fn [name] (proto-get name key)))
  7. (defn method [key] (fn [this & args] (apply (proto-get this key) (cons this args))))
  8.  
  9. (def evaluate (method :evaluate))
  10. (def toString (method :toString))
  11. (def diff (method :diff))
  12. (def operands (field :operands))
  13.  
  14. (defn Constant [value]
  15. {
  16. :evaluate (fn [_ _] value)
  17. :toString (fn [_] (format "%.1f" value))
  18. :diff (fn [_ _] (Constant 0))
  19. })
  20.  
  21. (defn Variable [name]
  22. {
  23. :evaluate (fn [_ map] (get map name))
  24. :toString (fn [_] (str name))
  25. :diff (fn [_ v] (if (= v name) (Constant 1) (Constant 0)))
  26. })
  27.  
  28. (defn OperationFactory [action symbol howToDiff]
  29. (fn [& args]
  30. {:prototype {:evaluate (fn [this vars]
  31. (apply ((field :action) this) (mapv #(evaluate % vars) (operands this))))
  32. :toString (fn [this]
  33. (str "("
  34. ((field :symbol) this)
  35. (apply str (mapv #(str " " (toString %)) (operands this)))
  36. ")"))}
  37. :action action
  38. :symbol symbol
  39. :diff howToDiff
  40. :operands args}
  41. ))
  42.  
  43. (defn nth-among-operands [this x] (nth (operands this) x))
  44. (def Add
  45. (OperationFactory
  46. +
  47. "+"
  48. (fn [this v]
  49. (Add (diff (nth-among-operands this 0) v)
  50. (diff (nth-among-operands this 1) v)))))
  51. (def Subtract
  52. (OperationFactory
  53. -
  54. "-"
  55. (fn [this v]
  56. (Subtract (diff (nth-among-operands this 0) v)
  57. (diff (nth-among-operands this 1) v)))))
  58. (def Negate
  59. (OperationFactory
  60. -
  61. "negate"
  62. (fn [this v]
  63. (Negate (diff (nth-among-operands this 0) v)))))
  64. (def Multiply
  65. (OperationFactory
  66. *
  67. "*"
  68. (fn [this v]
  69. (Add
  70. (Multiply (diff (nth-among-operands this 0) v) (nth-among-operands this 1))
  71. (Multiply (diff (nth-among-operands this 1) v) (nth-among-operands this 0)))
  72. )))
  73.  
  74. (def Divide
  75. (OperationFactory
  76. (fn rec
  77. ([a b] (/ (double a) b))
  78. ([a b & more] (apply rec (rec a b) more)))
  79. "/"
  80. (fn [this v]
  81. (Divide
  82. (Subtract
  83. (Multiply (diff (nth-among-operands this 0) v) (nth-among-operands this 1))
  84. (Multiply (diff (nth-among-operands this 1) v) (nth-among-operands this 0)))
  85. (Multiply (nth-among-operands this 1) (nth-among-operands this 1))))))
  86.  
  87. (def SqrtWithNegationIfNan
  88. (OperationFactory
  89. #(if (> % 0)
  90. (Math/sqrt (double %))
  91. (* (Math/sqrt (Math/abs (double %))) -1)
  92. )
  93. "sqrt"
  94. (fn [this v]
  95. (Divide (diff (nth-among-operands this 0) v)
  96. (Multiply (Constant 2) (SqrtWithNegationIfNan (nth-among-operands this 0))))
  97. )))
  98.  
  99. (def Sqrt
  100. (OperationFactory
  101. #(Math/sqrt (Math/abs (double %)))
  102. "sqrt"
  103. (fn [this v]
  104. (diff (SqrtWithNegationIfNan (nth-among-operands this 0)) v)
  105. )))
  106.  
  107. (def Square
  108. (OperationFactory
  109. #(* % %)
  110. "square"
  111. (fn [this v]
  112. (diff (Multiply (nth-among-operands this 0) (nth-among-operands this 0)) v)
  113. )))
  114.  
  115. (def obj-operations {'+ Add
  116. '- Subtract
  117. '* Multiply
  118. '/ Divide
  119. 'negate Negate
  120. 'sqrt Sqrt
  121. 'square Square
  122. })
  123.  
  124. (defn parseList [s]
  125. (if (list? s)
  126. (apply (get obj-operations (first s)) (map parseList (rest s)))
  127. (if (number? s)
  128. (Constant s)
  129. (Variable (str s)))
  130. )
  131. )
  132. (def parseObject #(parseList (read-string %)))
  133.  
  134. ;(pr (evaluate (diff (Square (Subtract (Variable "x") (Variable "y"))) "x") {"z" 1.0, "x" 1.0, "y" 1.0}))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement