{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}
module Language.Drasil.ModelExpr.Class where
import Prelude hiding (sqrt, log, sin, cos, tan, exp)
import Control.Lens ((^.))
import Language.Drasil.UID (HasUID(..))
import Language.Drasil.ModelExpr.Lang (ModelExpr(..), DerivType(..),
SpaceBinOp(..), StatBinOp(..), AssocBoolOper(..), AssocArithOper(..))
import Language.Drasil.Space (DomainDesc(..), RTopology(..), Space)
import Language.Drasil.Symbol (Symbol, HasSymbol)
assocCreate :: AssocBoolOper -> [ModelExpr] -> ModelExpr
assocCreate :: AssocBoolOper -> [ModelExpr] -> ModelExpr
assocCreate AssocBoolOper
abo [] = [Char] -> ModelExpr
forall a. HasCallStack => [Char] -> a
error ([Char] -> ModelExpr) -> [Char] -> ModelExpr
forall a b. (a -> b) -> a -> b
$ [Char]
"Need at least 1 expression to create " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ AssocBoolOper -> [Char]
forall a. Show a => a -> [Char]
show AssocBoolOper
abo
assocCreate AssocBoolOper
_ [ModelExpr
x] = ModelExpr
x
assocCreate AssocBoolOper
b [ModelExpr]
des = AssocBoolOper -> [ModelExpr] -> ModelExpr
AssocB AssocBoolOper
b ([ModelExpr] -> ModelExpr) -> [ModelExpr] -> ModelExpr
forall a b. (a -> b) -> a -> b
$ AssocBoolOper -> [ModelExpr] -> [ModelExpr]
assocSanitize AssocBoolOper
b [ModelExpr]
des
assocSanitize :: AssocBoolOper -> [ModelExpr] -> [ModelExpr]
assocSanitize :: AssocBoolOper -> [ModelExpr] -> [ModelExpr]
assocSanitize AssocBoolOper
_ [] = []
assocSanitize AssocBoolOper
b (it :: ModelExpr
it@(AssocB AssocBoolOper
c [ModelExpr]
des):[ModelExpr]
r)
| AssocBoolOper
b AssocBoolOper -> AssocBoolOper -> Bool
forall a. Eq a => a -> a -> Bool
== AssocBoolOper
c = AssocBoolOper -> [ModelExpr] -> [ModelExpr]
assocSanitize AssocBoolOper
b [ModelExpr]
des [ModelExpr] -> [ModelExpr] -> [ModelExpr]
forall a. [a] -> [a] -> [a]
++ AssocBoolOper -> [ModelExpr] -> [ModelExpr]
assocSanitize AssocBoolOper
b [ModelExpr]
r
| Bool
otherwise = ModelExpr
it ModelExpr -> [ModelExpr] -> [ModelExpr]
forall a. a -> [a] -> [a]
: AssocBoolOper -> [ModelExpr] -> [ModelExpr]
assocSanitize AssocBoolOper
b [ModelExpr]
r
assocSanitize AssocBoolOper
b (ModelExpr
de:[ModelExpr]
des) = ModelExpr
de ModelExpr -> [ModelExpr] -> [ModelExpr]
forall a. a -> [a] -> [a]
: AssocBoolOper -> [ModelExpr] -> [ModelExpr]
assocSanitize AssocBoolOper
b [ModelExpr]
des
class ModelExprC r where
deriv, pderiv :: (HasUID c, HasSymbol c) => r -> c -> r
nthderiv, nthpderiv :: (HasUID c, HasSymbol c) => Integer -> r -> c -> r
defines :: r -> r -> r
space :: Space -> r
isIn :: r -> Space -> r
equiv :: [r] -> r
intAll, sumAll, prodAll :: Symbol -> r -> r
instance ModelExprC ModelExpr where
deriv :: forall c. (HasUID c, HasSymbol c) => ModelExpr -> c -> ModelExpr
deriv ModelExpr
e c
c = Integer -> DerivType -> ModelExpr -> UID -> ModelExpr
Deriv Integer
1 DerivType
Total ModelExpr
e (c
c c -> Getting UID c UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID c UID
forall c. HasUID c => Getter c UID
Getter c UID
uid)
pderiv :: forall c. (HasUID c, HasSymbol c) => ModelExpr -> c -> ModelExpr
pderiv ModelExpr
e c
c = Integer -> DerivType -> ModelExpr -> UID -> ModelExpr
Deriv Integer
1 DerivType
Part ModelExpr
e (c
c c -> Getting UID c UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID c UID
forall c. HasUID c => Getter c UID
Getter c UID
uid)
nthderiv :: forall c.
(HasUID c, HasSymbol c) =>
Integer -> ModelExpr -> c -> ModelExpr
nthderiv Integer
n ModelExpr
e c
c
| Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 = Integer -> DerivType -> ModelExpr -> UID -> ModelExpr
Deriv Integer
n DerivType
Total ModelExpr
e (c
c c -> Getting UID c UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID c UID
forall c. HasUID c => Getter c UID
Getter c UID
uid)
| Integer
n Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = Integer -> DerivType -> ModelExpr -> UID -> ModelExpr
Deriv Integer
0 DerivType
Total ModelExpr
e (c
c c -> Getting UID c UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID c UID
forall c. HasUID c => Getter c UID
Getter c UID
uid)
| Bool
otherwise = [Char] -> ModelExpr
forall a. HasCallStack => [Char] -> a
error [Char]
"non-positive argument to derivative"
nthpderiv :: forall c.
(HasUID c, HasSymbol c) =>
Integer -> ModelExpr -> c -> ModelExpr
nthpderiv Integer
n ModelExpr
e c
c
| Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
0 = Integer -> DerivType -> ModelExpr -> UID -> ModelExpr
Deriv Integer
n DerivType
Part ModelExpr
e (c
c c -> Getting UID c UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID c UID
forall c. HasUID c => Getter c UID
Getter c UID
uid)
| Integer
n Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
0 = Integer -> DerivType -> ModelExpr -> UID -> ModelExpr
Deriv Integer
0 DerivType
Total ModelExpr
e (c
c c -> Getting UID c UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID c UID
forall c. HasUID c => Getter c UID
Getter c UID
uid)
| Bool
otherwise = [Char] -> ModelExpr
forall a. HasCallStack => [Char] -> a
error [Char]
"non-positive argument to derivative"
defines :: ModelExpr -> ModelExpr -> ModelExpr
defines = StatBinOp -> ModelExpr -> ModelExpr -> ModelExpr
StatBinaryOp StatBinOp
Defines
space :: Space -> ModelExpr
space = Space -> ModelExpr
Spc
isIn :: ModelExpr -> Space -> ModelExpr
isIn ModelExpr
a Space
s = SpaceBinOp -> ModelExpr -> ModelExpr -> ModelExpr
SpaceBinaryOp SpaceBinOp
IsIn ModelExpr
a (Space -> ModelExpr
Spc Space
s)
equiv :: [ModelExpr] -> ModelExpr
equiv [ModelExpr]
des
| [ModelExpr] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [ModelExpr]
des Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
2 = AssocBoolOper -> [ModelExpr] -> ModelExpr
assocCreate AssocBoolOper
Equivalence [ModelExpr]
des
| Bool
otherwise = [Char] -> ModelExpr
forall a. HasCallStack => [Char] -> a
error ([Char] -> ModelExpr) -> [Char] -> ModelExpr
forall a b. (a -> b) -> a -> b
$ [Char]
"Need at least 2 expressions to create " [Char] -> [Char] -> [Char]
forall a. [a] -> [a] -> [a]
++ AssocBoolOper -> [Char]
forall a. Show a => a -> [Char]
show AssocBoolOper
Equivalence
intAll :: Symbol -> ModelExpr -> ModelExpr
intAll Symbol
v = AssocArithOper
-> DomainDesc 'Continuous ModelExpr ModelExpr
-> ModelExpr
-> ModelExpr
forall (t :: RTopology).
AssocArithOper
-> DomainDesc t ModelExpr ModelExpr -> ModelExpr -> ModelExpr
Operator AssocArithOper
Add (Symbol -> RTopology -> DomainDesc 'Continuous ModelExpr ModelExpr
forall a b. Symbol -> RTopology -> DomainDesc 'Continuous a b
AllDD Symbol
v RTopology
Continuous)
sumAll :: Symbol -> ModelExpr -> ModelExpr
sumAll Symbol
v = AssocArithOper
-> DomainDesc 'Continuous ModelExpr ModelExpr
-> ModelExpr
-> ModelExpr
forall (t :: RTopology).
AssocArithOper
-> DomainDesc t ModelExpr ModelExpr -> ModelExpr -> ModelExpr
Operator AssocArithOper
Add (Symbol -> RTopology -> DomainDesc 'Continuous ModelExpr ModelExpr
forall a b. Symbol -> RTopology -> DomainDesc 'Continuous a b
AllDD Symbol
v RTopology
Discrete)
prodAll :: Symbol -> ModelExpr -> ModelExpr
prodAll Symbol
v = AssocArithOper
-> DomainDesc 'Continuous ModelExpr ModelExpr
-> ModelExpr
-> ModelExpr
forall (t :: RTopology).
AssocArithOper
-> DomainDesc t ModelExpr ModelExpr -> ModelExpr -> ModelExpr
Operator AssocArithOper
Mul (Symbol -> RTopology -> DomainDesc 'Continuous ModelExpr ModelExpr
forall a b. Symbol -> RTopology -> DomainDesc 'Continuous a b
AllDD Symbol
v RTopology
Discrete)