{-# LANGUAGE CPP #-}
{-# OPTIONS_GHC -Wcpp-undef #-}
{-# OPTIONS_GHC -fno-warn-orphans #-}
{-# OPTIONS_HADDOCK show-extensions #-}
module Debug.SimpleExpr.Expr
(
number,
variable,
unaryFunc,
binaryFunc,
simplify,
simplifyStep,
SimpleExprF (NumberF, VariableF, BinaryFuncF, SymbolicFuncF),
SimpleExpr,
Expr,
ListOf,
content,
dependencies,
showWithBrackets,
)
where
import Control.Monad.Fix (fix)
import Data.Fix (Fix (Fix, unFix))
import Data.Functor.Classes (Eq1, liftEq)
import Data.List (intercalate, (++))
import NumHask (Additive, Divisive, ExpField, Multiplicative, Subtractive, TrigField, one, zero)
import qualified NumHask as NH
import Prelude
( Bool (False),
Eq,
Functor,
Integer,
Num,
Show,
String,
fmap,
seq,
show,
($),
(&&),
(.),
(<>),
(==),
)
import qualified Prelude as P
data SimpleExprF a
= NumberF Integer
| VariableF String
| BinaryFuncF String a a
| SymbolicFuncF String [a]
deriving (forall a b. a -> SimpleExprF b -> SimpleExprF a
forall a b. (a -> b) -> SimpleExprF a -> SimpleExprF b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> SimpleExprF b -> SimpleExprF a
$c<$ :: forall a b. a -> SimpleExprF b -> SimpleExprF a
fmap :: forall a b. (a -> b) -> SimpleExprF a -> SimpleExprF b
$cfmap :: forall a b. (a -> b) -> SimpleExprF a -> SimpleExprF b
Functor, SimpleExprF a -> SimpleExprF a -> Bool
forall a. Eq a => SimpleExprF a -> SimpleExprF a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SimpleExprF a -> SimpleExprF a -> Bool
$c/= :: forall a. Eq a => SimpleExprF a -> SimpleExprF a -> Bool
== :: SimpleExprF a -> SimpleExprF a -> Bool
$c== :: forall a. Eq a => SimpleExprF a -> SimpleExprF a -> Bool
Eq)
instance Eq1 SimpleExprF where
liftEq :: (a -> b -> Bool) -> SimpleExprF a -> SimpleExprF b -> Bool
liftEq :: forall a b.
(a -> b -> Bool) -> SimpleExprF a -> SimpleExprF b -> Bool
liftEq a -> b -> Bool
eq SimpleExprF a
e1 SimpleExprF b
e2 = case (SimpleExprF a
e1, SimpleExprF b
e2) of
(NumberF Integer
n1, NumberF Integer
n2) -> Integer
n1 forall a. Eq a => a -> a -> Bool
== Integer
n2
(VariableF String
v1, VariableF String
v2) -> String
v1 forall a. Eq a => a -> a -> Bool
== String
v2
(BinaryFuncF String
name1 a
x1 a
y1, BinaryFuncF String
name2 b
x2 b
y2) -> (String
name1 forall a. Eq a => a -> a -> Bool
== String
name2) Bool -> Bool -> Bool
&& a -> b -> Bool
eq a
x1 b
x2 Bool -> Bool -> Bool
&& a -> b -> Bool
eq a
y1 b
y2
(SymbolicFuncF String
name1 [a]
args1, SymbolicFuncF String
name2 [b]
args2) -> (String
name1 forall a. Eq a => a -> a -> Bool
== String
name2) Bool -> Bool -> Bool
&& forall (f :: * -> *) a b.
Eq1 f =>
(a -> b -> Bool) -> f a -> f b -> Bool
liftEq a -> b -> Bool
eq [a]
args1 [b]
args2
(SimpleExprF a, SimpleExprF b)
_ -> Bool
False
instance NH.FromIntegral (SimpleExprF a) Integer where
fromIntegral :: Integer -> SimpleExprF a
fromIntegral = forall a. Integer -> SimpleExprF a
NumberF
type SimpleExpr = Fix SimpleExprF
number :: Integer -> SimpleExpr
number :: Integer -> SimpleExpr
number Integer
n = forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. Integer -> SimpleExprF a
NumberF Integer
n)
variable :: String -> SimpleExpr
variable :: String -> SimpleExpr
variable String
name = forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. String -> SimpleExprF a
VariableF String
name)
dependencies :: SimpleExpr -> [SimpleExpr]
dependencies :: SimpleExpr -> [SimpleExpr]
dependencies (Fix SimpleExprF SimpleExpr
e) = case SimpleExprF SimpleExpr
e of
NumberF Integer
_ -> []
VariableF String
_ -> []
BinaryFuncF String
_ SimpleExpr
leftArg SimpleExpr
rightArg -> [SimpleExpr
leftArg, SimpleExpr
rightArg]
SymbolicFuncF String
_ [SimpleExpr]
args -> [SimpleExpr]
args
instance NH.FromIntegral (Fix SimpleExprF) Integer where
fromIntegral :: Integer -> SimpleExpr
fromIntegral = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. Integer -> SimpleExprF a
NumberF
class ListOf inner outer where
content :: outer -> [inner]
instance ListOf inner () where
content :: () -> [inner]
content = forall a b. a -> b -> a
P.const []
instance ListOf inner inner where
content :: inner -> [inner]
content inner
e = [inner
e]
instance (ListOf inner outer1, ListOf inner outer2) => ListOf inner (outer1, outer2) where
content :: (outer1, outer2) -> [inner]
content (outer1
x1, outer2
x2) = forall inner outer. ListOf inner outer => outer -> [inner]
content outer1
x1 forall a. [a] -> [a] -> [a]
++ forall inner outer. ListOf inner outer => outer -> [inner]
content outer2
x2
instance (ListOf inner outer1, ListOf inner outer2, ListOf inner outer3) => ListOf inner (outer1, outer2, outer3) where
content :: (outer1, outer2, outer3) -> [inner]
content (outer1
x1, outer2
x2, outer3
x3) = forall inner outer. ListOf inner outer => outer -> [inner]
content outer1
x1 forall a. [a] -> [a] -> [a]
++ forall inner outer. ListOf inner outer => outer -> [inner]
content outer2
x2 forall a. [a] -> [a] -> [a]
++ forall inner outer. ListOf inner outer => outer -> [inner]
content outer3
x3
instance
(ListOf inner outer1, ListOf inner outer2, ListOf inner outer3, ListOf inner outer4) =>
ListOf inner (outer1, outer2, outer3, outer4)
where
content :: (outer1, outer2, outer3, outer4) -> [inner]
content (outer1
x1, outer2
x2, outer3
x3, outer4
x4) = forall inner outer. ListOf inner outer => outer -> [inner]
content outer1
x1 forall a. [a] -> [a] -> [a]
++ forall inner outer. ListOf inner outer => outer -> [inner]
content outer2
x2 forall a. [a] -> [a] -> [a]
++ forall inner outer. ListOf inner outer => outer -> [inner]
content outer3
x3 forall a. [a] -> [a] -> [a]
++ forall inner outer. ListOf inner outer => outer -> [inner]
content outer4
x4
instance
(ListOf inner outer1, ListOf inner outer2, ListOf inner outer3, ListOf inner outer4, ListOf inner outer5) =>
ListOf inner (outer1, outer2, outer3, outer4, outer5)
where
content :: (outer1, outer2, outer3, outer4, outer5) -> [inner]
content (outer1
x1, outer2
x2, outer3
x3, outer4
x4, outer5
x5) = forall inner outer. ListOf inner outer => outer -> [inner]
content outer1
x1 forall a. [a] -> [a] -> [a]
++ forall inner outer. ListOf inner outer => outer -> [inner]
content outer2
x2 forall a. [a] -> [a] -> [a]
++ forall inner outer. ListOf inner outer => outer -> [inner]
content outer3
x3 forall a. [a] -> [a] -> [a]
++ forall inner outer. ListOf inner outer => outer -> [inner]
content outer4
x4 forall a. [a] -> [a] -> [a]
++ forall inner outer. ListOf inner outer => outer -> [inner]
content outer5
x5
instance (ListOf inner outer) => ListOf inner [outer] where
content :: [outer] -> [inner]
content = (forall inner outer. ListOf inner outer => outer -> [inner]
content forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
P.=<<)
type Expr = ListOf SimpleExpr
instance {-# OVERLAPPING #-} Show SimpleExpr where
show :: SimpleExpr -> String
show (Fix SimpleExprF SimpleExpr
e) = case SimpleExprF SimpleExpr
e of
NumberF Integer
n -> forall a. Show a => a -> String
show Integer
n
VariableF String
name -> String
name
BinaryFuncF String
name SimpleExpr
leftArg SimpleExpr
rightArg -> SimpleExpr -> String
showWithBrackets SimpleExpr
leftArg forall a. Semigroup a => a -> a -> a
<> String
name forall a. Semigroup a => a -> a -> a
<> SimpleExpr -> String
showWithBrackets SimpleExpr
rightArg
SymbolicFuncF String
name [SimpleExpr]
args -> String
name forall a. Semigroup a => a -> a -> a
<> String
"(" forall a. Semigroup a => a -> a -> a
<> forall a. [a] -> [[a]] -> [a]
intercalate String
"," (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap forall a. Show a => a -> String
show [SimpleExpr]
args) forall a. Semigroup a => a -> a -> a
<> String
")"
showWithBrackets :: SimpleExpr -> String
showWithBrackets :: SimpleExpr -> String
showWithBrackets SimpleExpr
e = case SimpleExpr
e of
n :: SimpleExpr
n@(Fix NumberF {}) -> forall a. Show a => a -> String
show SimpleExpr
n
c :: SimpleExpr
c@(Fix VariableF {}) -> forall a. Show a => a -> String
show SimpleExpr
c
bf :: SimpleExpr
bf@(Fix BinaryFuncF {}) -> String
"(" forall a. Semigroup a => a -> a -> a
<> forall a. Show a => a -> String
show SimpleExpr
bf forall a. Semigroup a => a -> a -> a
<> String
")"
sf :: SimpleExpr
sf@(Fix SymbolicFuncF {}) -> forall a. Show a => a -> String
show SimpleExpr
sf
unaryFunc :: String -> SimpleExpr -> SimpleExpr
unaryFunc :: String -> SimpleExpr -> SimpleExpr
unaryFunc String
name SimpleExpr
x = forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. String -> [a] -> SimpleExprF a
SymbolicFuncF String
name [SimpleExpr
x])
binaryFunc :: String -> SimpleExpr -> SimpleExpr -> SimpleExpr
binaryFunc :: String -> SimpleExpr -> SimpleExpr -> SimpleExpr
binaryFunc String
name SimpleExpr
x SimpleExpr
y = forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. String -> a -> a -> SimpleExprF a
BinaryFuncF String
name SimpleExpr
x SimpleExpr
y)
instance Additive SimpleExpr where
zero :: SimpleExpr
zero = Integer -> SimpleExpr
number Integer
0
+ :: SimpleExpr -> SimpleExpr -> SimpleExpr
(+) = String -> SimpleExpr -> SimpleExpr -> SimpleExpr
binaryFunc String
"+"
instance Subtractive SimpleExpr where
negate :: SimpleExpr -> SimpleExpr
negate = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"-"
(-) = String -> SimpleExpr -> SimpleExpr -> SimpleExpr
binaryFunc String
"-"
instance Multiplicative SimpleExpr where
one :: SimpleExpr
one = Integer -> SimpleExpr
number Integer
1
* :: SimpleExpr -> SimpleExpr -> SimpleExpr
(*) = String -> SimpleExpr -> SimpleExpr -> SimpleExpr
binaryFunc String
"·"
#if MIN_VERSION_numhask(0,11,0)
#else
instance NH.Distributive SimpleExpr
#endif
instance Divisive SimpleExpr where
/ :: SimpleExpr -> SimpleExpr -> SimpleExpr
(/) = String -> SimpleExpr -> SimpleExpr -> SimpleExpr
binaryFunc String
"/"
#if MIN_VERSION_numhask(0,11,0)
#else
instance NH.Field SimpleExpr
#endif
instance ExpField SimpleExpr where
exp :: SimpleExpr -> SimpleExpr
exp = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"exp"
log :: SimpleExpr -> SimpleExpr
log = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"log"
** :: SimpleExpr -> SimpleExpr -> SimpleExpr
(**) = String -> SimpleExpr -> SimpleExpr -> SimpleExpr
binaryFunc String
"^"
sqrt :: SimpleExpr -> SimpleExpr
sqrt = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"sqrt"
instance TrigField SimpleExpr where
pi :: SimpleExpr
pi = String -> SimpleExpr
variable String
"π"
sin :: SimpleExpr -> SimpleExpr
sin = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"sin"
cos :: SimpleExpr -> SimpleExpr
cos = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"cos"
tan :: SimpleExpr -> SimpleExpr
tan = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"tg"
asin :: SimpleExpr -> SimpleExpr
asin = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"arcsin"
acos :: SimpleExpr -> SimpleExpr
acos = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"arccos"
atan :: SimpleExpr -> SimpleExpr
atan = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"arctan"
sinh :: SimpleExpr -> SimpleExpr
sinh = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"sh"
cosh :: SimpleExpr -> SimpleExpr
cosh = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"ch"
tanh :: SimpleExpr -> SimpleExpr
tanh = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"th"
atan2 :: SimpleExpr -> SimpleExpr -> SimpleExpr
atan2 SimpleExpr
a SimpleExpr
b = forall (f :: * -> *). f (Fix f) -> Fix f
Fix forall a b. (a -> b) -> a -> b
$ forall a. String -> [a] -> SimpleExprF a
SymbolicFuncF String
"atan2" [SimpleExpr
a, SimpleExpr
b]
asinh :: SimpleExpr -> SimpleExpr
asinh = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"arcsh"
acosh :: SimpleExpr -> SimpleExpr
acosh = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"arcch"
atanh :: SimpleExpr -> SimpleExpr
atanh = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"arcth"
instance Num SimpleExpr where
+ :: SimpleExpr -> SimpleExpr -> SimpleExpr
(+) = forall a. Additive a => a -> a -> a
(NH.+)
(-) = forall a. Subtractive a => a -> a -> a
(NH.-)
* :: SimpleExpr -> SimpleExpr -> SimpleExpr
(*) = forall a. Multiplicative a => a -> a -> a
(NH.*)
negate :: SimpleExpr -> SimpleExpr
negate = forall a. Subtractive a => a -> a
NH.negate
abs :: SimpleExpr -> SimpleExpr
abs = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"abs"
signum :: SimpleExpr -> SimpleExpr
signum = String -> SimpleExpr -> SimpleExpr
unaryFunc String
"sign"
fromInteger :: Integer -> SimpleExpr
fromInteger = Integer -> SimpleExpr
number
iterateUntilEqual :: Eq x => (x -> x) -> x -> x
iterateUntilEqual :: forall x. Eq x => (x -> x) -> x -> x
iterateUntilEqual x -> x
f x
x =
let fx :: x
fx = x -> x
f x
x
in if x
fx forall a. Eq a => a -> a -> Bool
== x
x
then x
x
else seq :: forall a b. a -> b -> b
seq x
fx (forall x. Eq x => (x -> x) -> x -> x
iterateUntilEqual x -> x
f x
fx)
simplifyStep :: (SimpleExpr -> SimpleExpr) -> SimpleExpr -> SimpleExpr
simplifyStep :: (SimpleExpr -> SimpleExpr) -> SimpleExpr -> SimpleExpr
simplifyStep SimpleExpr -> SimpleExpr
f SimpleExpr
e = case SimpleExpr
e of
n :: SimpleExpr
n@(Fix (NumberF Integer
_)) -> SimpleExpr
n
c :: SimpleExpr
c@(Fix (VariableF String
_)) -> SimpleExpr
c
Fix (BinaryFuncF String
name SimpleExpr
leftArg SimpleExpr
rightArg) -> case String
name of
String
"+" -> case (forall (f :: * -> *). Fix f -> f (Fix f)
unFix SimpleExpr
leftArg, forall (f :: * -> *). Fix f -> f (Fix f)
unFix SimpleExpr
rightArg) of
(NumberF Integer
0, SimpleExprF SimpleExpr
_) -> SimpleExpr -> SimpleExpr
f SimpleExpr
rightArg
(SimpleExprF SimpleExpr
_, NumberF Integer
0) -> SimpleExpr -> SimpleExpr
f SimpleExpr
leftArg
(NumberF Integer
n, NumberF Integer
m) -> forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. Integer -> SimpleExprF a
NumberF (Integer
n forall a. Num a => a -> a -> a
P.+ Integer
m))
(SimpleExprF SimpleExpr, SimpleExprF SimpleExpr)
_ -> forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. String -> a -> a -> SimpleExprF a
BinaryFuncF String
"+" (SimpleExpr -> SimpleExpr
f SimpleExpr
leftArg) (SimpleExpr -> SimpleExpr
f SimpleExpr
rightArg))
String
"-" -> case (forall (f :: * -> *). Fix f -> f (Fix f)
unFix SimpleExpr
leftArg, forall (f :: * -> *). Fix f -> f (Fix f)
unFix SimpleExpr
rightArg) of
(NumberF Integer
0, SimpleExprF SimpleExpr
_) -> forall a. Subtractive a => a -> a
NH.negate SimpleExpr -> SimpleExpr
f SimpleExpr
rightArg
(SimpleExprF SimpleExpr
_, NumberF Integer
0) -> SimpleExpr -> SimpleExpr
f SimpleExpr
leftArg
(NumberF Integer
n, NumberF Integer
m) -> forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. Integer -> SimpleExprF a
NumberF (Integer
n forall a. Num a => a -> a -> a
P.- Integer
m))
(SimpleExprF SimpleExpr, SimpleExprF SimpleExpr)
_ ->
if SimpleExpr
fX forall a. Eq a => a -> a -> Bool
== SimpleExpr
fY
then forall a. Additive a => a
zero
else forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. String -> a -> a -> SimpleExprF a
BinaryFuncF String
"-" SimpleExpr
fX SimpleExpr
fY)
where
fX :: SimpleExpr
fX = SimpleExpr -> SimpleExpr
f SimpleExpr
leftArg
fY :: SimpleExpr
fY = SimpleExpr -> SimpleExpr
f SimpleExpr
rightArg
String
"·" -> case (forall (f :: * -> *). Fix f -> f (Fix f)
unFix SimpleExpr
leftArg, forall (f :: * -> *). Fix f -> f (Fix f)
unFix SimpleExpr
rightArg) of
(NumberF Integer
0, SimpleExprF SimpleExpr
_) -> forall a. Additive a => a
zero
(SimpleExprF SimpleExpr
_, NumberF Integer
0) -> forall a. Additive a => a
zero
(NumberF Integer
1, SimpleExprF SimpleExpr
_) -> SimpleExpr -> SimpleExpr
f SimpleExpr
rightArg
(SimpleExprF SimpleExpr
_, NumberF Integer
1) -> SimpleExpr -> SimpleExpr
f SimpleExpr
leftArg
(NumberF Integer
n, NumberF Integer
m) -> forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. Integer -> SimpleExprF a
NumberF (Integer
n forall a. Num a => a -> a -> a
P.* Integer
m))
(SimpleExprF SimpleExpr, SimpleExprF SimpleExpr)
_ -> forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. String -> a -> a -> SimpleExprF a
BinaryFuncF String
"·" (SimpleExpr -> SimpleExpr
f SimpleExpr
leftArg) (SimpleExpr -> SimpleExpr
f SimpleExpr
rightArg))
String
"^" -> case (forall (f :: * -> *). Fix f -> f (Fix f)
unFix SimpleExpr
leftArg, forall (f :: * -> *). Fix f -> f (Fix f)
unFix SimpleExpr
rightArg) of
(NumberF Integer
n, NumberF Integer
m) -> forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. Integer -> SimpleExprF a
NumberF (Integer
n forall a b. (Num a, Integral b) => a -> b -> a
P.^ Integer
m))
(NumberF Integer
0, SimpleExprF SimpleExpr
_) -> forall a. Additive a => a
zero
(SimpleExprF SimpleExpr
_, NumberF Integer
0) -> forall a. Multiplicative a => a
one
(NumberF Integer
1, SimpleExprF SimpleExpr
_) -> forall a. Multiplicative a => a
one
(SimpleExprF SimpleExpr
_, NumberF Integer
1) -> SimpleExpr -> SimpleExpr
f SimpleExpr
leftArg
(SimpleExprF SimpleExpr, SimpleExprF SimpleExpr)
_ -> forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. String -> a -> a -> SimpleExprF a
BinaryFuncF String
"^" (SimpleExpr -> SimpleExpr
f SimpleExpr
leftArg) (SimpleExpr -> SimpleExpr
f SimpleExpr
rightArg))
String
_ -> forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. String -> a -> a -> SimpleExprF a
BinaryFuncF String
name (SimpleExpr -> SimpleExpr
f SimpleExpr
leftArg) (SimpleExpr -> SimpleExpr
f SimpleExpr
rightArg))
Fix (SymbolicFuncF String
name [SimpleExpr]
args) -> forall (f :: * -> *). f (Fix f) -> Fix f
Fix (forall a. String -> [a] -> SimpleExprF a
SymbolicFuncF String
name (forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SimpleExpr -> SimpleExpr
f [SimpleExpr]
args))
simplify :: SimpleExpr -> SimpleExpr
simplify :: SimpleExpr -> SimpleExpr
simplify = forall a. (a -> a) -> a
fix forall a b. (a -> b) -> a -> b
$ forall x. Eq x => (x -> x) -> x -> x
iterateUntilEqual forall b c a. (b -> c) -> (a -> b) -> a -> c
. (SimpleExpr -> SimpleExpr) -> SimpleExpr -> SimpleExpr
simplifyStep