{-# LANGUAGE TemplateHaskell #-}
module Language.Drasil.Chunk.CodeDefinition (
CodeDefinition, DefinitionType(..), qtoc, qtov, odeDef, auxExprs, defType,
) where
import Language.Drasil
import Language.Drasil.Chunk.Code (quantvar, quantfunc)
import Language.Drasil.CodeExpr.Development (expr, CanGenCode(..))
import Language.Drasil.Data.ODEInfo (ODEInfo(..), ODEOptions(..))
import Control.Lens ((^.), makeLenses, view)
data DefinitionType = Definition | ODE
data CodeDefinition = CD { CodeDefinition -> CodeChunk
_cchunk :: CodeChunk
, CodeDefinition -> CodeExpr
_def :: CodeExpr
, CodeDefinition -> [CodeExpr]
_auxExprs :: [CodeExpr]
, CodeDefinition -> DefinitionType
_defType :: DefinitionType
}
makeLenses ''CodeDefinition
instance HasUID CodeDefinition where uid :: Getter CodeDefinition UID
uid = (CodeChunk -> f CodeChunk) -> CodeDefinition -> f CodeDefinition
Lens' CodeDefinition CodeChunk
cchunk ((CodeChunk -> f CodeChunk) -> CodeDefinition -> f CodeDefinition)
-> ((UID -> f UID) -> CodeChunk -> f CodeChunk)
-> (UID -> f UID)
-> CodeDefinition
-> f CodeDefinition
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (UID -> f UID) -> CodeChunk -> f CodeChunk
forall c. HasUID c => Getter c UID
Getter CodeChunk UID
uid
instance NamedIdea CodeDefinition where term :: Lens' CodeDefinition NP
term = (CodeChunk -> f CodeChunk) -> CodeDefinition -> f CodeDefinition
Lens' CodeDefinition CodeChunk
cchunk ((CodeChunk -> f CodeChunk) -> CodeDefinition -> f CodeDefinition)
-> ((NP -> f NP) -> CodeChunk -> f CodeChunk)
-> (NP -> f NP)
-> CodeDefinition
-> f CodeDefinition
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (NP -> f NP) -> CodeChunk -> f CodeChunk
forall c. NamedIdea c => Lens' c NP
Lens' CodeChunk NP
term
instance Idea CodeDefinition where getA :: CodeDefinition -> Maybe String
getA = CodeChunk -> Maybe String
forall c. Idea c => c -> Maybe String
getA (CodeChunk -> Maybe String)
-> (CodeDefinition -> CodeChunk) -> CodeDefinition -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting CodeChunk CodeDefinition CodeChunk
-> CodeDefinition -> CodeChunk
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting CodeChunk CodeDefinition CodeChunk
Lens' CodeDefinition CodeChunk
cchunk
instance HasSpace CodeDefinition where typ :: Getter CodeDefinition Space
typ = (CodeChunk -> f CodeChunk) -> CodeDefinition -> f CodeDefinition
Lens' CodeDefinition CodeChunk
cchunk ((CodeChunk -> f CodeChunk) -> CodeDefinition -> f CodeDefinition)
-> ((Space -> f Space) -> CodeChunk -> f CodeChunk)
-> (Space -> f Space)
-> CodeDefinition
-> f CodeDefinition
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Space -> f Space) -> CodeChunk -> f CodeChunk
forall c. HasSpace c => Getter c Space
Getter CodeChunk Space
typ
instance HasSymbol CodeDefinition where symbol :: CodeDefinition -> Stage -> Symbol
symbol CodeDefinition
c = CodeChunk -> Stage -> Symbol
forall c. HasSymbol c => c -> Stage -> Symbol
symbol (CodeDefinition
c CodeDefinition
-> Getting CodeChunk CodeDefinition CodeChunk -> CodeChunk
forall s a. s -> Getting a s a -> a
^. Getting CodeChunk CodeDefinition CodeChunk
Lens' CodeDefinition CodeChunk
cchunk)
instance Quantity CodeDefinition
instance CodeIdea CodeDefinition where
codeName :: CodeDefinition -> String
codeName (CD c :: CodeChunk
c@(CodeC QuantityDict
_ VarOrFunc
Var) CodeExpr
_ [CodeExpr]
_ DefinitionType
_) = CodeChunk -> String
forall c. CodeIdea c => c -> String
codeName CodeChunk
c
codeName (CD c :: CodeChunk
c@(CodeC QuantityDict
_ VarOrFunc
Func) CodeExpr
_ [CodeExpr]
_ DefinitionType
_) = String
funcPrefix String -> String -> String
forall a. [a] -> [a] -> [a]
++ CodeChunk -> String
forall c. CodeIdea c => c -> String
codeName CodeChunk
c
codeChunk :: CodeDefinition -> CodeChunk
codeChunk = Getting CodeChunk CodeDefinition CodeChunk
-> CodeDefinition -> CodeChunk
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting CodeChunk CodeDefinition CodeChunk
Lens' CodeDefinition CodeChunk
cchunk
instance Eq CodeDefinition where CodeDefinition
c1 == :: CodeDefinition -> CodeDefinition -> Bool
== CodeDefinition
c2 = (CodeDefinition
c1 CodeDefinition -> Getting UID CodeDefinition UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID CodeDefinition UID
forall c. HasUID c => Getter c UID
Getter CodeDefinition UID
uid) UID -> UID -> Bool
forall a. Eq a => a -> a -> Bool
== (CodeDefinition
c2 CodeDefinition -> Getting UID CodeDefinition UID -> UID
forall s a. s -> Getting a s a -> a
^. Getting UID CodeDefinition UID
forall c. HasUID c => Getter c UID
Getter CodeDefinition UID
uid)
instance MayHaveUnit CodeDefinition where getUnit :: CodeDefinition -> Maybe UnitDefn
getUnit = CodeChunk -> Maybe UnitDefn
forall u. MayHaveUnit u => u -> Maybe UnitDefn
getUnit (CodeChunk -> Maybe UnitDefn)
-> (CodeDefinition -> CodeChunk)
-> CodeDefinition
-> Maybe UnitDefn
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Getting CodeChunk CodeDefinition CodeChunk
-> CodeDefinition -> CodeChunk
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view Getting CodeChunk CodeDefinition CodeChunk
Lens' CodeDefinition CodeChunk
cchunk
instance DefiningCodeExpr CodeDefinition where codeExpr :: Lens' CodeDefinition CodeExpr
codeExpr = (CodeExpr -> f CodeExpr) -> CodeDefinition -> f CodeDefinition
Lens' CodeDefinition CodeExpr
def
qtoc :: (Quantity (q Expr), MayHaveUnit (q Expr), DefiningExpr q) => q Expr -> CodeDefinition
qtoc :: forall (q :: * -> *).
(Quantity (q Expr), MayHaveUnit (q Expr), DefiningExpr q) =>
q Expr -> CodeDefinition
qtoc q Expr
q = CodeChunk
-> CodeExpr -> [CodeExpr] -> DefinitionType -> CodeDefinition
CD (CodeFuncChunk -> CodeChunk
forall c. CodeIdea c => c -> CodeChunk
codeChunk (CodeFuncChunk -> CodeChunk) -> CodeFuncChunk -> CodeChunk
forall a b. (a -> b) -> a -> b
$ q Expr -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc q Expr
q) (Expr -> CodeExpr
expr (Expr -> CodeExpr) -> Expr -> CodeExpr
forall a b. (a -> b) -> a -> b
$ q Expr
q q Expr -> Getting Expr (q Expr) Expr -> Expr
forall s a. s -> Getting a s a -> a
^. Getting Expr (q Expr) Expr
forall e. Lens' (q e) e
forall (c :: * -> *) e. DefiningExpr c => Lens' (c e) e
defnExpr) [] DefinitionType
Definition
qtov :: CanGenCode e => QDefinition e -> CodeDefinition
qtov :: forall e. CanGenCode e => QDefinition e -> CodeDefinition
qtov QDefinition e
q = CodeChunk
-> CodeExpr -> [CodeExpr] -> DefinitionType -> CodeDefinition
CD (CodeVarChunk -> CodeChunk
forall c. CodeIdea c => c -> CodeChunk
codeChunk (CodeVarChunk -> CodeChunk) -> CodeVarChunk -> CodeChunk
forall a b. (a -> b) -> a -> b
$ QDefinition e -> CodeVarChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeVarChunk
quantvar QDefinition e
q) (e -> CodeExpr
forall e. CanGenCode e => e -> CodeExpr
toCodeExpr (e -> CodeExpr) -> e -> CodeExpr
forall a b. (a -> b) -> a -> b
$ QDefinition e
q QDefinition e -> Getting e (QDefinition e) e -> e
forall s a. s -> Getting a s a -> a
^. Getting e (QDefinition e) e
forall e. Lens' (QDefinition e) e
forall (c :: * -> *) e. DefiningExpr c => Lens' (c e) e
defnExpr) [] DefinitionType
Definition
odeDef :: ODEInfo -> CodeDefinition
odeDef :: ODEInfo -> CodeDefinition
odeDef ODEInfo
info = CodeChunk
-> CodeExpr -> [CodeExpr] -> DefinitionType -> CodeDefinition
CD
(CodeFuncChunk -> CodeChunk
forall c. CodeIdea c => c -> CodeChunk
codeChunk (CodeFuncChunk -> CodeChunk) -> CodeFuncChunk -> CodeChunk
forall a b. (a -> b) -> a -> b
$ CodeVarChunk -> CodeFuncChunk
forall c. (Quantity c, MayHaveUnit c) => c -> CodeFuncChunk
quantfunc (CodeVarChunk -> CodeFuncChunk) -> CodeVarChunk -> CodeFuncChunk
forall a b. (a -> b) -> a -> b
$ ODEInfo -> CodeVarChunk
depVar ODEInfo
info)
([[CodeExpr]] -> CodeExpr
forall r. ExprC r => [[r]] -> r
matrix [ODEInfo -> [CodeExpr]
odeSyst ODEInfo
info])
([[CodeExpr]] -> CodeExpr
forall r. ExprC r => [[r]] -> r
matrix [ODEInfo -> [CodeExpr]
initVal ODEInfo
info]CodeExpr -> [CodeExpr] -> [CodeExpr]
forall a. a -> [a] -> [a]
:
((ODEInfo -> CodeExpr) -> CodeExpr)
-> [ODEInfo -> CodeExpr] -> [CodeExpr]
forall a b. (a -> b) -> [a] -> [b]
map ((ODEInfo -> CodeExpr) -> ODEInfo -> CodeExpr
forall a b. (a -> b) -> a -> b
$ ODEInfo
info) [ODEInfo -> CodeExpr
tInit, ODEInfo -> CodeExpr
tFinal, ODEOptions -> CodeExpr
absTol (ODEOptions -> CodeExpr)
-> (ODEInfo -> ODEOptions) -> ODEInfo -> CodeExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ODEInfo -> ODEOptions
odeOpts, ODEOptions -> CodeExpr
relTol (ODEOptions -> CodeExpr)
-> (ODEInfo -> ODEOptions) -> ODEInfo -> CodeExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ODEInfo -> ODEOptions
odeOpts, ODEOptions -> CodeExpr
stepSize (ODEOptions -> CodeExpr)
-> (ODEInfo -> ODEOptions) -> ODEInfo -> CodeExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ODEInfo -> ODEOptions
odeOpts])
DefinitionType
ODE