Advertisement
Guest User

Untitled

a guest
Dec 19th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.48 KB | None | 0 0
  1. module Expr where
  2. import Parsing
  3. import Data.Char(isDigit, isSpace)
  4. import Data.Maybe
  5. import Test.QuickCheck
  6. import Control.Monad(forever)
  7.  
  8. --Expressions for testing
  9. ex1 = Num 2 -- 2
  10. ex2 = Add (Num 1) (Num 2) -- 1 + 2
  11. ex3 = Mul (Add (Num 1) (Num 2)) (Num 3) -- (1+2)*3
  12. ex4 = Add (Num 1) (Mul (Num 2) (Num 3)) -- 1+2*3
  13. ex5 = Sin (Add (Num 1) (Num 5)) -- sin (1+5)
  14. ex6 = Sin (Mul (Num 7) (Var))
  15. ex8 = Mul (Mul (Num 6) (Num 1)) (Var)
  16. ex7 = Add (Mul (Num 6) (Num 1)) (Var)
  17. ex9 = Cos (Mul (Num 7) (Var))
  18.  
  19. -- * A
  20. --Representation of mathematic operators and fuctions
  21. data Expr = Num Double
  22. | Var
  23. | Add Expr Expr
  24. | Mul Expr Expr
  25. | Sin Expr
  26. | Cos Expr
  27. deriving Show
  28.  
  29.  
  30. -- * B
  31. -- Converts any expression to string
  32. showExpr :: Expr -> String
  33. showExpr (Num n) = show n
  34. showExpr (Var) = "x"
  35. showExpr (Add a b) = showExpr a ++ "+" ++ showExpr b
  36. showExpr (Mul a b) = showFactor a ++ "*" ++ showFactor b
  37. showExpr (Sin a) = "sin" ++ showTrig a
  38. showExpr (Cos a) = "cos" ++ showTrig a
  39.  
  40. showFactor :: Expr -> String
  41. showFactor e@(Add _ _) = "("++ showExpr e ++")"
  42. showFactor e = showExpr e
  43.  
  44. showTrig :: Expr -> String
  45. showTrig e@(Add a b) = "(" ++ showExpr e ++")"
  46. showTrig e@(Mul a b) = "(" ++ showExpr e ++")"
  47. showTrig e = showExpr e
  48.  
  49.  
  50. -- * C
  51. -- Calculates the value of teh expression given
  52. -- an expression and a value for x
  53. eval :: Expr -> Double -> Double
  54. eval (Num n) x = n
  55. eval Var x = x
  56. eval (Add a b) x = eval a x + eval b x
  57. eval (Mul a b) x = eval a x * eval b x
  58. eval (Sin a) x = sin (eval a x)
  59. eval (Cos a) x = cos (eval a x)
  60.  
  61.  
  62. -- * D
  63. -- top level parser
  64. -- remove spaces and expect no junk!
  65. -- Interpret the string as an expression
  66. readExpr :: String -> Maybe Expr
  67. readExpr s = let s' = filter (not.isSpace) s
  68. in case parse expr s' of
  69. Just (e,"") -> Just e
  70. _ -> Nothing
  71.  
  72. expr, term, factor, sinn, coss :: Parser Expr
  73. expr = leftAssoc Add term (char '+')
  74. term = leftAssoc Mul factor (char '*')
  75. sinn = Sin <$> ((string "sin") *> factor)
  76. coss = Cos <$> ((string "cos") *> factor)
  77. factor = (Num <$> readsP) <|> (char '(' *> expr <* char ')') <|>
  78. sinn <|> coss <|> (char 'x' *> return Var)
  79.  
  80.  
  81. leftAssoc :: (t->t->t) -> Parser t -> Parser sep -> Parser t
  82. leftAssoc op item sep = do is <- chain item sep
  83. return (foldl1 op is)
  84.  
  85. string :: String -> Parser String
  86. string s = sequence $ fmap (char) s
  87.  
  88.  
  89. -- * E
  90. -- Checks if showing and then reading an expression
  91. -- gives the same result as the expression it started with
  92. prop_ShowReadExpr :: Expr -> Bool
  93. prop_ShowReadExpr e = let s = showExpr e
  94. Just e' = readExpr s
  95. in showExpr e' == s
  96.  
  97. -- Generates expressions
  98. arbExpr :: Int -> Gen Expr
  99. arbExpr s = frequency [(1,rNum),(s,rOp),(s,sOp), (1,return Var)]
  100. where
  101. s' = s `div` 2
  102. rNum = do
  103. n <- arbitrary
  104. return $ Num n
  105.  
  106. rOp = do
  107. op <- elements [Add,Mul]
  108. e1 <- arbExpr s'
  109. e2 <- arbExpr s'
  110. return $ op e1 e2
  111.  
  112. sOp = do
  113. op1 <- elements [Sin,Cos]
  114. x1 <- arbExpr s'
  115. return $ op1 x1
  116.  
  117.  
  118. instance Arbitrary Expr where
  119. arbitrary = sized arbExpr
  120.  
  121. -- * F
  122. --
  123. simplify :: Expr -> Expr
  124. simplify e = simpLoop e 100
  125. where simpLoop e 0 = simplify' e
  126. simpLoop e i = simpLoop (simplify' e) (i-1)
  127.  
  128. simplify' :: Expr -> Expr
  129. simplify' (Add (Num a) (Num b)) = (Num (a+b))
  130. simplify' (Mul (Num 0) _) = Num 0
  131. simplify' (Mul _ (Num 0)) = Num 0
  132. simplify' (Mul (Num a) (Num b)) = (Num (a*b))
  133. simplify' (Add ex1 ex2) = (Add (simplify' ex1) (simplify' ex2))
  134. simplify' (Mul ex1 ex2) = (Mul (simplify' ex1) (simplify' ex2))
  135. simplify' (Sin ex) = (Sin (simplify' ex))
  136. simplify' (Cos ex) = (Cos (simplify' ex))
  137. simplify' ex = ex
  138.  
  139.  
  140. prop_simplify :: Expr -> Double -> Bool
  141. prop_simplify e x = (eval e x) == (eval (simplify e) x)
  142.  
  143.  
  144.  
  145. -- * G
  146. --
  147. differentiate :: Expr -> Expr
  148. differentiate e = simplify $ differentiate' $ simplify e
  149.  
  150. differentiate' :: Expr -> Expr
  151. differentiate' (Num _) = Num 0
  152. differentiate' Var = Num 1
  153. differentiate' (Mul ex1 Var) = ex1
  154. differentiate' (Mul Var ex2) = ex2
  155. differentiate' (Mul ex1 ex2) = Add (Mul ex1 (differentiate' ex2)) (Mul (differentiate' ex1) ex2)
  156. differentiate' (Add ex1 ex2) = Add (differentiate' ex1) (differentiate' ex2)
  157. differentiate' (Sin ex) = Mul (Cos ex) (differentiate' ex)
  158. differentiate' (Cos ex) = Mul (Mul (Num (-1)) (Sin ex)) (differentiate' ex)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement