{-# LANGUAGE GADTs #-}

-- | Defines functions to render 'CodeExpr's as printable 'P.Expr's.
module Language.Drasil.Printing.Import.ModelExpr where -- TODO: tighten exports

-- TODO: tighten exports
import Language.Drasil (UID, DomainDesc(..), RealInterval(..), Inclusive(..),
  RTopology(..), LiteralC(int))
import qualified Language.Drasil.Display as S (Symbol(..))
import Language.Drasil.Literal.Development (Literal(..))
import Language.Drasil.ModelExpr.Development

import qualified Language.Drasil.Printing.AST as P
import Language.Drasil.Printing.PrintingInformation (PrintingInformation, ckdb, stg)

import Control.Lens ((^.))
import Data.List (intersperse)

import Language.Drasil.Printing.Import.Literal (literal)
import Language.Drasil.Printing.Import.Space (space)
import Language.Drasil.Printing.Import.Symbol (symbol)
import Language.Drasil.Printing.Import.Helpers (lookupC, parens)

-- | Helper that adds parenthesis to a display expression where appropriate.
modelExpr' :: PrintingInformation -> Int -> ModelExpr -> P.Expr
modelExpr' :: PrintingInformation -> Int -> ModelExpr -> Expr
modelExpr' PrintingInformation
s Int
p ModelExpr
e = Expr -> Expr
fence (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
e PrintingInformation
s
  where fence :: Expr -> Expr
fence = if ModelExpr -> Int
mePrec ModelExpr
e Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
p then Expr -> Expr
parens else Expr -> Expr
forall a. a -> a
id

-- | Helper that creates an expression row given printing information, an operator, and an expression.
mkCall :: PrintingInformation -> P.Ops -> ModelExpr -> P.Expr
mkCall :: PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
s Ops
o ModelExpr
e = [Expr] -> Expr
P.Row [Ops -> Expr
P.MO Ops
o, Expr -> Expr
parens (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
e PrintingInformation
s]

-- | Helper that creates a binary expression row given printing information, an operator, and two expressions.
mkBOp :: PrintingInformation -> P.Ops -> ModelExpr -> ModelExpr -> P.Expr
mkBOp :: PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
o ModelExpr
a ModelExpr
b = [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
sm, Ops -> Expr
P.MO Ops
o, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
b PrintingInformation
sm]

-- | Helper for properly rendering negation of expressions.
neg' :: ModelExpr -> Bool
neg' :: ModelExpr -> Bool
neg' (Lit (Dbl Double
_))          = Bool
True
neg' (Lit (Int Integer
_))          = Bool
True
neg' (Lit (ExactDbl Integer
_))     = Bool
True
neg' Operator{}             = Bool
True
neg' (AssocA AssocArithOper
Mul [ModelExpr]
_)       = Bool
True
neg' (LABinaryOp LABinOp
Index ModelExpr
_ ModelExpr
_) = Bool
True
neg' (UnaryOp UFunc
_ ModelExpr
_)          = Bool
True
neg' (UnaryOpB UFuncB
_ ModelExpr
_)         = Bool
True
neg' (UnaryOpVV UFuncVV
_ ModelExpr
_)        = Bool
True
neg' (C UID
_)                  = Bool
True
neg' ModelExpr
_                      = Bool
False

-- | Render negated expressions.
neg :: PrintingInformation -> ModelExpr -> P.Expr
neg :: PrintingInformation -> ModelExpr -> Expr
neg PrintingInformation
sm ModelExpr
a = [Expr] -> Expr
P.Row [Ops -> Expr
P.MO Ops
P.Neg, (if ModelExpr -> Bool
neg' ModelExpr
a then Expr -> Expr
forall a. a -> a
id else Expr -> Expr
parens) (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
sm]

-- | For printing indexes.
indx :: PrintingInformation -> ModelExpr -> ModelExpr -> P.Expr
indx :: PrintingInformation -> ModelExpr -> ModelExpr -> Expr
indx PrintingInformation
sm (C UID
c) ModelExpr
i = Symbol -> Expr
f Symbol
s
  where
    i' :: Expr
i' = ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
i PrintingInformation
sm
    s :: Symbol
s = Stage -> ChunkDB -> UID -> Symbol
lookupC (PrintingInformation
sm PrintingInformation
-> Getting Stage PrintingInformation Stage -> Stage
forall s a. s -> Getting a s a -> a
^. Getting Stage PrintingInformation Stage
Lens' PrintingInformation Stage
stg) (PrintingInformation
sm PrintingInformation
-> Getting ChunkDB PrintingInformation ChunkDB -> ChunkDB
forall s a. s -> Getting a s a -> a
^. Getting ChunkDB PrintingInformation ChunkDB
Lens' PrintingInformation ChunkDB
ckdb) UID
c
    f :: Symbol -> Expr
f (S.Corners [] [] [] [Symbol
b] Symbol
e) =
      let e' :: Expr
e' = Symbol -> Expr
symbol Symbol
e
          b' :: Expr
b' = Symbol -> Expr
symbol Symbol
b in
      [Expr] -> Expr
P.Row [[Expr] -> Expr
P.Row [Expr
e', Expr -> Expr
P.Sub ([Expr] -> Expr
P.Row [Expr
b', Ops -> Expr
P.MO Ops
P.Comma, Expr
i'])]] -- FIXME, extra Row
    f a :: Symbol
a@(S.Variable String
_) = [Expr] -> Expr
P.Row [Symbol -> Expr
symbol Symbol
a, Expr -> Expr
P.Sub Expr
i']
    f a :: Symbol
a@(S.Label String
_)    = [Expr] -> Expr
P.Row [Symbol -> Expr
symbol Symbol
a, Expr -> Expr
P.Sub Expr
i']
--    f a@(Greek _)  = P.Row [symbol a, P.Sub i']
    f   Symbol
e          = let e' :: Expr
e' = Symbol -> Expr
symbol Symbol
e in [Expr] -> Expr
P.Row [[Expr] -> Expr
P.Row [Expr
e'], Expr -> Expr
P.Sub Expr
i']
indx PrintingInformation
sm ModelExpr
a ModelExpr
i = [Expr] -> Expr
P.Row [[Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
sm], Expr -> Expr
P.Sub (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
i PrintingInformation
sm]

-- | For printing expressions that call something.
call :: PrintingInformation -> UID -> [ModelExpr] -> P.Expr
call :: PrintingInformation -> UID -> [ModelExpr] -> Expr
call PrintingInformation
sm UID
f [ModelExpr]
ps = [Expr] -> Expr
P.Row [
    Symbol -> Expr
symbol (Symbol -> Expr) -> Symbol -> Expr
forall a b. (a -> b) -> a -> b
$ Stage -> ChunkDB -> UID -> Symbol
lookupC (PrintingInformation
sm PrintingInformation
-> Getting Stage PrintingInformation Stage -> Stage
forall s a. s -> Getting a s a -> a
^. Getting Stage PrintingInformation Stage
Lens' PrintingInformation Stage
stg) (PrintingInformation
sm PrintingInformation
-> Getting ChunkDB PrintingInformation ChunkDB -> ChunkDB
forall s a. s -> Getting a s a -> a
^. Getting ChunkDB PrintingInformation ChunkDB
Lens' PrintingInformation ChunkDB
ckdb) UID
f,
    Expr -> Expr
parens (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ [Expr] -> Expr
P.Row ([Expr] -> Expr) -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ Expr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
intersperse (Ops -> Expr
P.MO Ops
P.Comma) ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ (ModelExpr -> Expr) -> [ModelExpr] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (ModelExpr -> PrintingInformation -> Expr
`modelExpr` PrintingInformation
sm) [ModelExpr]
ps
  ]

-- | Helper function for addition 'EOperator's.
eopAdds :: PrintingInformation -> DomainDesc t ModelExpr ModelExpr -> ModelExpr -> P.Expr
eopAdds :: forall (t :: RTopology).
PrintingInformation
-> DomainDesc t ModelExpr ModelExpr -> ModelExpr -> Expr
eopAdds PrintingInformation
sm (BoundedDD Symbol
v RTopology
Continuous ModelExpr
l ModelExpr
h) ModelExpr
e =
  [Expr] -> Expr
P.Row [Ops -> Expr
P.MO Ops
P.Inte, Expr -> Expr
P.Sub (ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
l PrintingInformation
sm), Expr -> Expr
P.Sup (ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
h PrintingInformation
sm),
         [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
e PrintingInformation
sm], Spacing -> Expr
P.Spc Spacing
P.Thin, String -> Expr
P.Ident String
"d", Symbol -> Expr
symbol Symbol
v]
eopAdds PrintingInformation
sm (AllDD Symbol
v RTopology
Continuous) ModelExpr
e =
  [Expr] -> Expr
P.Row [Ops -> Expr
P.MO Ops
P.Inte, Expr -> Expr
P.Sub (Symbol -> Expr
symbol Symbol
v), [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
e PrintingInformation
sm], Spacing -> Expr
P.Spc Spacing
P.Thin,
         String -> Expr
P.Ident String
"d", Symbol -> Expr
symbol Symbol
v]
eopAdds PrintingInformation
sm (BoundedDD Symbol
v RTopology
Discrete ModelExpr
l ModelExpr
h) ModelExpr
e =
  [Expr] -> Expr
P.Row [Ops -> Expr
P.MO Ops
P.Summ, Expr -> Expr
P.Sub ([Expr] -> Expr
P.Row [Symbol -> Expr
symbol Symbol
v, Ops -> Expr
P.MO Ops
P.Eq, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
l PrintingInformation
sm]), Expr -> Expr
P.Sup (ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
h PrintingInformation
sm),
         [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
e PrintingInformation
sm]]
eopAdds PrintingInformation
sm (AllDD Symbol
_ RTopology
Discrete) ModelExpr
e = [Expr] -> Expr
P.Row [Ops -> Expr
P.MO Ops
P.Summ, [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
e PrintingInformation
sm]]

-- | Helper function for multiplicative 'EOperator's.
eopMuls :: PrintingInformation -> DomainDesc t ModelExpr ModelExpr -> ModelExpr -> P.Expr
eopMuls :: forall (t :: RTopology).
PrintingInformation
-> DomainDesc t ModelExpr ModelExpr -> ModelExpr -> Expr
eopMuls PrintingInformation
sm (BoundedDD Symbol
v RTopology
Discrete ModelExpr
l ModelExpr
h) ModelExpr
e =
  [Expr] -> Expr
P.Row [Ops -> Expr
P.MO Ops
P.Prod, Expr -> Expr
P.Sub ([Expr] -> Expr
P.Row [Symbol -> Expr
symbol Symbol
v, Ops -> Expr
P.MO Ops
P.Eq, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
l PrintingInformation
sm]), Expr -> Expr
P.Sup (ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
h PrintingInformation
sm),
         [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
e PrintingInformation
sm]]
eopMuls PrintingInformation
sm (AllDD Symbol
_ RTopology
Discrete) ModelExpr
e = [Expr] -> Expr
P.Row [Ops -> Expr
P.MO Ops
P.Prod, [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
e PrintingInformation
sm]]
eopMuls PrintingInformation
_ (AllDD Symbol
_ RTopology
Continuous) ModelExpr
_ = String -> Expr
forall a. HasCallStack => String -> a
error String
"Printing/Import.hs Product-Integral not implemented."
eopMuls PrintingInformation
_ (BoundedDD Symbol
_ RTopology
Continuous ModelExpr
_ ModelExpr
_) ModelExpr
_ = String -> Expr
forall a. HasCallStack => String -> a
error String
"Printing/Import.hs Product-Integral not implemented."


-- | Helper function for translating 'EOperator's.
eop :: PrintingInformation -> AssocArithOper -> DomainDesc t ModelExpr ModelExpr -> ModelExpr -> P.Expr
eop :: forall (t :: RTopology).
PrintingInformation
-> AssocArithOper
-> DomainDesc t ModelExpr ModelExpr
-> ModelExpr
-> Expr
eop PrintingInformation
sm AssocArithOper
Add = PrintingInformation
-> DomainDesc t ModelExpr ModelExpr -> ModelExpr -> Expr
forall (t :: RTopology).
PrintingInformation
-> DomainDesc t ModelExpr ModelExpr -> ModelExpr -> Expr
eopAdds PrintingInformation
sm
eop PrintingInformation
sm AssocArithOper
Mul = PrintingInformation
-> DomainDesc t ModelExpr ModelExpr -> ModelExpr -> Expr
forall (t :: RTopology).
PrintingInformation
-> DomainDesc t ModelExpr ModelExpr -> ModelExpr -> Expr
eopMuls PrintingInformation
sm

-- | Helper function for display nth derivative
sup :: Integer -> [P.Expr]
sup :: Integer -> [Expr]
sup Integer
n | Integer
n Integer -> Integer -> Bool
forall a. Eq a => a -> a -> Bool
== Integer
1 = []
      | Integer
n Integer -> Integer -> Bool
forall a. Ord a => a -> a -> Bool
> Integer
1 = [Expr -> Expr
P.Sup (Integer -> Expr
P.Int Integer
n)]
      | Bool
otherwise = String -> [Expr]
forall a. HasCallStack => String -> a
error String
"non-positive argument to derivative"

-- | Translate Exprs to printable layout AST.
modelExpr :: ModelExpr -> PrintingInformation -> P.Expr
modelExpr :: ModelExpr -> PrintingInformation -> Expr
modelExpr (Lit Literal
l)                    PrintingInformation
sm = Literal -> PrintingInformation -> Expr
literal Literal
l PrintingInformation
sm
modelExpr (AssocB AssocBoolOper
And [ModelExpr]
l)             PrintingInformation
sm = Ops -> Int -> [ModelExpr] -> PrintingInformation -> Expr
assocExpr Ops
P.And (AssocBoolOper -> Int
precB AssocBoolOper
And) [ModelExpr]
l PrintingInformation
sm
modelExpr (AssocB AssocBoolOper
Or [ModelExpr]
l)              PrintingInformation
sm = Ops -> Int -> [ModelExpr] -> PrintingInformation -> Expr
assocExpr Ops
P.Or (AssocBoolOper -> Int
precB AssocBoolOper
Or) [ModelExpr]
l PrintingInformation
sm
modelExpr (AssocB AssocBoolOper
Equivalence [ModelExpr]
l)     PrintingInformation
sm = Ops -> Int -> [ModelExpr] -> PrintingInformation -> Expr
assocExpr Ops
P.Eq (AssocBoolOper -> Int
precB AssocBoolOper
Equivalence) [ModelExpr]
l PrintingInformation
sm
modelExpr (AssocA AssocArithOper
Add [ModelExpr]
l)             PrintingInformation
sm = [Expr] -> Expr
P.Row ([Expr] -> Expr) -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ [ModelExpr] -> AssocArithOper -> PrintingInformation -> [Expr]
addExpr [ModelExpr]
l AssocArithOper
Add PrintingInformation
sm
modelExpr (AssocA AssocArithOper
Mul [ModelExpr]
l)             PrintingInformation
sm = [Expr] -> Expr
P.Row ([Expr] -> Expr) -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ [ModelExpr] -> AssocArithOper -> PrintingInformation -> [Expr]
mulExpr [ModelExpr]
l AssocArithOper
Mul PrintingInformation
sm
modelExpr (AssocC AssocConcatOper
SUnion [ModelExpr]
l)          PrintingInformation
sm = Ops -> Int -> [ModelExpr] -> PrintingInformation -> Expr
assocExpr Ops
P.SUnion (AssocConcatOper -> Int
precC AssocConcatOper
SUnion) [ModelExpr]
l PrintingInformation
sm
modelExpr (Deriv Integer
0 DerivType
Part ModelExpr
a UID
_)         PrintingInformation
sm = [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
sm]
modelExpr (Deriv Integer
0 DerivType
Total ModelExpr
a UID
_)        PrintingInformation
sm = [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
sm]
modelExpr (Deriv Integer
n DerivType
Part ModelExpr
a UID
b)         PrintingInformation
sm =
  let st :: [Expr]
st = [Spacing -> Expr
P.Spc Spacing
P.Thin, Ops -> Expr
P.MO Ops
P.Partial] in 
    Expr -> Expr -> Expr
P.Div ([Expr] -> Expr
P.Row ([Expr]
st [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ Integer -> [Expr]
sup Integer
n [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
sm]))
    ([Expr] -> Expr
P.Row ([Expr]
st [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [Symbol -> Expr
symbol (Symbol -> Expr) -> Symbol -> Expr
forall a b. (a -> b) -> a -> b
$ Stage -> ChunkDB -> UID -> Symbol
lookupC (PrintingInformation
sm PrintingInformation
-> Getting Stage PrintingInformation Stage -> Stage
forall s a. s -> Getting a s a -> a
^. Getting Stage PrintingInformation Stage
Lens' PrintingInformation Stage
stg) (PrintingInformation
sm PrintingInformation
-> Getting ChunkDB PrintingInformation ChunkDB -> ChunkDB
forall s a. s -> Getting a s a -> a
^. Getting ChunkDB PrintingInformation ChunkDB
Lens' PrintingInformation ChunkDB
ckdb) UID
b] [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ Integer -> [Expr]
sup Integer
n))
modelExpr (Deriv Integer
n DerivType
Total ModelExpr
a UID
b)        PrintingInformation
sm =
  let st :: [Expr]
st = [Spacing -> Expr
P.Spc Spacing
P.Thin, String -> Expr
P.Ident String
"d"] in
    Expr -> Expr -> Expr
P.Div ([Expr] -> Expr
P.Row ([Expr]
st [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ Integer -> [Expr]
sup Integer
n [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
sm]))
        ([Expr] -> Expr
P.Row ([Expr]
st [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [Symbol -> Expr
symbol (Symbol -> Expr) -> Symbol -> Expr
forall a b. (a -> b) -> a -> b
$ Stage -> ChunkDB -> UID -> Symbol
lookupC (PrintingInformation
sm PrintingInformation
-> Getting Stage PrintingInformation Stage -> Stage
forall s a. s -> Getting a s a -> a
^. Getting Stage PrintingInformation Stage
Lens' PrintingInformation Stage
stg) (PrintingInformation
sm PrintingInformation
-> Getting ChunkDB PrintingInformation ChunkDB -> ChunkDB
forall s a. s -> Getting a s a -> a
^. Getting ChunkDB PrintingInformation ChunkDB
Lens' PrintingInformation ChunkDB
ckdb) UID
b] [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ Integer -> [Expr]
sup Integer
n))
modelExpr (C UID
c)                      PrintingInformation
sm = Symbol -> Expr
symbol (Symbol -> Expr) -> Symbol -> Expr
forall a b. (a -> b) -> a -> b
$ Stage -> ChunkDB -> UID -> Symbol
lookupC (PrintingInformation
sm PrintingInformation
-> Getting Stage PrintingInformation Stage -> Stage
forall s a. s -> Getting a s a -> a
^. Getting Stage PrintingInformation Stage
Lens' PrintingInformation Stage
stg) (PrintingInformation
sm PrintingInformation
-> Getting ChunkDB PrintingInformation ChunkDB -> ChunkDB
forall s a. s -> Getting a s a -> a
^. Getting ChunkDB PrintingInformation ChunkDB
Lens' PrintingInformation ChunkDB
ckdb) UID
c
modelExpr (FCall UID
f [ModelExpr
x])              PrintingInformation
sm =
  [Expr] -> Expr
P.Row [Symbol -> Expr
symbol (Symbol -> Expr) -> Symbol -> Expr
forall a b. (a -> b) -> a -> b
$ Stage -> ChunkDB -> UID -> Symbol
lookupC (PrintingInformation
sm PrintingInformation
-> Getting Stage PrintingInformation Stage -> Stage
forall s a. s -> Getting a s a -> a
^. Getting Stage PrintingInformation Stage
Lens' PrintingInformation Stage
stg) (PrintingInformation
sm PrintingInformation
-> Getting ChunkDB PrintingInformation ChunkDB -> ChunkDB
forall s a. s -> Getting a s a -> a
^. Getting ChunkDB PrintingInformation ChunkDB
Lens' PrintingInformation ChunkDB
ckdb) UID
f, Expr -> Expr
parens (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
x PrintingInformation
sm]
modelExpr (FCall UID
f [ModelExpr]
l)                PrintingInformation
sm = PrintingInformation -> UID -> [ModelExpr] -> Expr
call PrintingInformation
sm UID
f [ModelExpr]
l
modelExpr (Case Completeness
_ [(ModelExpr, ModelExpr)]
ps)                PrintingInformation
sm =
  if [(ModelExpr, ModelExpr)] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [(ModelExpr, ModelExpr)]
ps Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
2
    then String -> Expr
forall a. HasCallStack => String -> a
error String
"Attempting to use multi-case modelExpr incorrectly"
    else [(Expr, Expr)] -> Expr
P.Case ([Expr] -> [Expr] -> [(Expr, Expr)]
forall a b. [a] -> [b] -> [(a, b)]
zip (((ModelExpr, ModelExpr) -> Expr)
-> [(ModelExpr, ModelExpr)] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map ((ModelExpr -> PrintingInformation -> Expr)
-> PrintingInformation -> ModelExpr -> Expr
forall a b c. (a -> b -> c) -> b -> a -> c
flip ModelExpr -> PrintingInformation -> Expr
modelExpr PrintingInformation
sm (ModelExpr -> Expr)
-> ((ModelExpr, ModelExpr) -> ModelExpr)
-> (ModelExpr, ModelExpr)
-> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModelExpr, ModelExpr) -> ModelExpr
forall a b. (a, b) -> a
fst) [(ModelExpr, ModelExpr)]
ps) (((ModelExpr, ModelExpr) -> Expr)
-> [(ModelExpr, ModelExpr)] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map ((ModelExpr -> PrintingInformation -> Expr)
-> PrintingInformation -> ModelExpr -> Expr
forall a b c. (a -> b -> c) -> b -> a -> c
flip ModelExpr -> PrintingInformation -> Expr
modelExpr PrintingInformation
sm (ModelExpr -> Expr)
-> ((ModelExpr, ModelExpr) -> ModelExpr)
-> (ModelExpr, ModelExpr)
-> Expr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (ModelExpr, ModelExpr) -> ModelExpr
forall a b. (a, b) -> b
snd) [(ModelExpr, ModelExpr)]
ps))
modelExpr (Matrix [[ModelExpr]]
a)                 PrintingInformation
sm = [[Expr]] -> Expr
P.Mtx ([[Expr]] -> Expr) -> [[Expr]] -> Expr
forall a b. (a -> b) -> a -> b
$ ([ModelExpr] -> [Expr]) -> [[ModelExpr]] -> [[Expr]]
forall a b. (a -> b) -> [a] -> [b]
map ((ModelExpr -> Expr) -> [ModelExpr] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (ModelExpr -> PrintingInformation -> Expr
`modelExpr` PrintingInformation
sm)) [[ModelExpr]]
a
modelExpr (Set Space
_ [ModelExpr]
l)                  PrintingInformation
sm = Ops -> Int -> [ModelExpr] -> PrintingInformation -> Expr
setExpr Ops
P.And (AssocBoolOper -> Int
precB AssocBoolOper
And) [ModelExpr]
l PrintingInformation
sm
modelExpr (Variable String
_ ModelExpr
l)             PrintingInformation
sm = ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
l PrintingInformation
sm
modelExpr (UnaryOp UFunc
Log ModelExpr
u)            PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
sm Ops
P.Log ModelExpr
u
modelExpr (UnaryOp UFunc
Ln ModelExpr
u)             PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
sm Ops
P.Ln ModelExpr
u
modelExpr (UnaryOp UFunc
Sin ModelExpr
u)            PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
sm Ops
P.Sin ModelExpr
u
modelExpr (UnaryOp UFunc
Cos ModelExpr
u)            PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
sm Ops
P.Cos ModelExpr
u
modelExpr (UnaryOp UFunc
Tan ModelExpr
u)            PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
sm Ops
P.Tan ModelExpr
u
modelExpr (UnaryOp UFunc
Sec ModelExpr
u)            PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
sm Ops
P.Sec ModelExpr
u
modelExpr (UnaryOp UFunc
Csc ModelExpr
u)            PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
sm Ops
P.Csc ModelExpr
u
modelExpr (UnaryOp UFunc
Cot ModelExpr
u)            PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
sm Ops
P.Cot ModelExpr
u
modelExpr (UnaryOp UFunc
Arcsin ModelExpr
u)         PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
sm Ops
P.Arcsin ModelExpr
u
modelExpr (UnaryOp UFunc
Arccos ModelExpr
u)         PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
sm Ops
P.Arccos ModelExpr
u
modelExpr (UnaryOp UFunc
Arctan ModelExpr
u)         PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
sm Ops
P.Arctan ModelExpr
u
modelExpr (UnaryOp UFunc
Exp ModelExpr
u)            PrintingInformation
sm = [Expr] -> Expr
P.Row [Ops -> Expr
P.MO Ops
P.Exp, Expr -> Expr
P.Sup (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
u PrintingInformation
sm]
modelExpr (UnaryOp UFunc
Abs ModelExpr
u)            PrintingInformation
sm = Fence -> Fence -> Expr -> Expr
P.Fenced Fence
P.Abs Fence
P.Abs (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
u PrintingInformation
sm
modelExpr (UnaryOpB UFuncB
Not ModelExpr
u)           PrintingInformation
sm = [Expr] -> Expr
P.Row [Ops -> Expr
P.MO Ops
P.Not, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
u PrintingInformation
sm]
modelExpr (UnaryOpVN UFuncVN
Norm ModelExpr
u)         PrintingInformation
sm = Fence -> Fence -> Expr -> Expr
P.Fenced Fence
P.Norm Fence
P.Norm (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
u PrintingInformation
sm
modelExpr (UnaryOpVN UFuncVN
Dim ModelExpr
u)          PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> Expr
mkCall PrintingInformation
sm Ops
P.Dim ModelExpr
u
modelExpr (UnaryOp UFunc
Sqrt ModelExpr
u)           PrintingInformation
sm = Expr -> Expr
P.Sqrt (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
u PrintingInformation
sm
modelExpr (UnaryOp UFunc
Neg ModelExpr
u)            PrintingInformation
sm = PrintingInformation -> ModelExpr -> Expr
neg PrintingInformation
sm ModelExpr
u
modelExpr (UnaryOpVV UFuncVV
NegV ModelExpr
u)         PrintingInformation
sm = PrintingInformation -> ModelExpr -> Expr
neg PrintingInformation
sm ModelExpr
u
modelExpr (ArithBinaryOp ArithBinOp
Frac ModelExpr
a ModelExpr
b)   PrintingInformation
sm = Expr -> Expr -> Expr
P.Div (ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
sm) (ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
b PrintingInformation
sm)
modelExpr (ArithBinaryOp ArithBinOp
Pow ModelExpr
a ModelExpr
b)    PrintingInformation
sm = PrintingInformation -> ModelExpr -> ModelExpr -> Expr
pow PrintingInformation
sm ModelExpr
a ModelExpr
b
modelExpr (ArithBinaryOp ArithBinOp
Subt ModelExpr
a ModelExpr
b)   PrintingInformation
sm = [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
sm, Ops -> Expr
P.MO Ops
P.Subt, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
b PrintingInformation
sm]
modelExpr (BoolBinaryOp BoolBinOp
Impl ModelExpr
a ModelExpr
b)    PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.Impl ModelExpr
a ModelExpr
b
modelExpr (BoolBinaryOp BoolBinOp
Iff ModelExpr
a ModelExpr
b)     PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.Iff ModelExpr
a ModelExpr
b
modelExpr (EqBinaryOp EqBinOp
Eq ModelExpr
a ModelExpr
b)        PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.Eq ModelExpr
a ModelExpr
b
modelExpr (EqBinaryOp EqBinOp
NEq ModelExpr
a ModelExpr
b)       PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.NEq ModelExpr
a ModelExpr
b
modelExpr (LABinaryOp LABinOp
Index ModelExpr
a ModelExpr
b)     PrintingInformation
sm = PrintingInformation -> ModelExpr -> ModelExpr -> Expr
indx PrintingInformation
sm ModelExpr
a ModelExpr
b
modelExpr (LABinaryOp LABinOp
IndexOf ModelExpr
a ModelExpr
b)   PrintingInformation
sm = PrintingInformation -> ModelExpr -> ModelExpr -> Expr
indx PrintingInformation
sm ModelExpr
a ModelExpr
b
modelExpr (OrdBinaryOp OrdBinOp
Lt ModelExpr
a ModelExpr
b)       PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.Lt ModelExpr
a ModelExpr
b
modelExpr (OrdBinaryOp OrdBinOp
Gt ModelExpr
a ModelExpr
b)       PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.Gt ModelExpr
a ModelExpr
b
modelExpr (OrdBinaryOp OrdBinOp
LEq ModelExpr
a ModelExpr
b)      PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.LEq ModelExpr
a ModelExpr
b
modelExpr (OrdBinaryOp OrdBinOp
GEq ModelExpr
a ModelExpr
b)      PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.GEq ModelExpr
a ModelExpr
b
modelExpr (VVNBinaryOp VVNBinOp
Dot ModelExpr
a ModelExpr
b)      PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.Dot ModelExpr
a ModelExpr
b
modelExpr (VVVBinaryOp VVVBinOp
Cross ModelExpr
a ModelExpr
b)    PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.Cross ModelExpr
a ModelExpr
b
modelExpr (VVVBinaryOp VVVBinOp
VAdd ModelExpr
a ModelExpr
b)     PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.VAdd ModelExpr
a ModelExpr
b
modelExpr (VVVBinaryOp VVVBinOp
VSub ModelExpr
a ModelExpr
b)     PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.VSub ModelExpr
a ModelExpr
b
modelExpr (NVVBinaryOp NVVBinOp
Scale ModelExpr
a ModelExpr
b)    PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.Scale ModelExpr
a ModelExpr
b
modelExpr (ESSBinaryOp ESSBinOp
SAdd ModelExpr
a ModelExpr
b)     PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.SAdd ModelExpr
a ModelExpr
b
modelExpr (ESSBinaryOp ESSBinOp
SRemove ModelExpr
a ModelExpr
b)    PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.SRemove ModelExpr
a ModelExpr
b
modelExpr (ESBBinaryOp ESBBinOp
SContains ModelExpr
a ModelExpr
b)  PrintingInformation
sm = PrintingInformation -> Ops -> ModelExpr -> ModelExpr -> Expr
mkBOp PrintingInformation
sm Ops
P.SContains ModelExpr
a ModelExpr
b
modelExpr (Operator AssocArithOper
o DomainDesc t ModelExpr ModelExpr
d ModelExpr
e)           PrintingInformation
sm = PrintingInformation
-> AssocArithOper
-> DomainDesc t ModelExpr ModelExpr
-> ModelExpr
-> Expr
forall (t :: RTopology).
PrintingInformation
-> AssocArithOper
-> DomainDesc t ModelExpr ModelExpr
-> ModelExpr
-> Expr
eop PrintingInformation
sm AssocArithOper
o DomainDesc t ModelExpr ModelExpr
d ModelExpr
e
modelExpr (RealI UID
c RealInterval ModelExpr ModelExpr
ri)               PrintingInformation
sm = PrintingInformation
-> Symbol -> RealInterval ModelExpr ModelExpr -> Expr
renderRealInt PrintingInformation
sm (Stage -> ChunkDB -> UID -> Symbol
lookupC (PrintingInformation
sm PrintingInformation
-> Getting Stage PrintingInformation Stage -> Stage
forall s a. s -> Getting a s a -> a
^. Getting Stage PrintingInformation Stage
Lens' PrintingInformation Stage
stg)
  (PrintingInformation
sm PrintingInformation
-> Getting ChunkDB PrintingInformation ChunkDB -> ChunkDB
forall s a. s -> Getting a s a -> a
^. Getting ChunkDB PrintingInformation ChunkDB
Lens' PrintingInformation ChunkDB
ckdb) UID
c) RealInterval ModelExpr ModelExpr
ri
modelExpr (Spc Space
s)                    PrintingInformation
sm = PrintingInformation -> Space -> Expr
space PrintingInformation
sm Space
s
modelExpr (SpaceBinaryOp SpaceBinOp
IsIn ModelExpr
l ModelExpr
r)   PrintingInformation
sm = [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
l PrintingInformation
sm, Ops -> Expr
P.MO Ops
P.IsIn, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
r PrintingInformation
sm]
modelExpr (StatBinaryOp StatBinOp
Defines ModelExpr
l ModelExpr
r) PrintingInformation
sm = [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
l PrintingInformation
sm, Ops -> Expr
P.MO Ops
P.Eq, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
r PrintingInformation
sm]
modelExpr (ForAll UID
c Space
s ModelExpr
de)            PrintingInformation
sm = [Expr] -> Expr
P.Row [
    Ops -> Expr
P.MO Ops
P.ForAll, Symbol -> Expr
symbol (Symbol -> Expr) -> Symbol -> Expr
forall a b. (a -> b) -> a -> b
$ Stage -> ChunkDB -> UID -> Symbol
lookupC (PrintingInformation
sm PrintingInformation
-> Getting Stage PrintingInformation Stage -> Stage
forall s a. s -> Getting a s a -> a
^. Getting Stage PrintingInformation Stage
Lens' PrintingInformation Stage
stg) (PrintingInformation
sm PrintingInformation
-> Getting ChunkDB PrintingInformation ChunkDB -> ChunkDB
forall s a. s -> Getting a s a -> a
^. Getting ChunkDB PrintingInformation ChunkDB
Lens' PrintingInformation ChunkDB
ckdb) UID
c, Ops -> Expr
P.MO Ops
P.IsIn, PrintingInformation -> Space -> Expr
space PrintingInformation
sm Space
s,
    Ops -> Expr
P.MO Ops
P.Dot, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
de PrintingInformation
sm
  ]

-- | Common method of converting associative operations into printable layout AST.
assocExpr :: P.Ops -> Int -> [ModelExpr] -> PrintingInformation -> P.Expr
assocExpr :: Ops -> Int -> [ModelExpr] -> PrintingInformation -> Expr
assocExpr Ops
op Int
prec [ModelExpr]
exprs PrintingInformation
sm = [Expr] -> Expr
P.Row ([Expr] -> Expr) -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ Expr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
intersperse (Ops -> Expr
P.MO Ops
op) ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ (ModelExpr -> Expr) -> [ModelExpr] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (PrintingInformation -> Int -> ModelExpr -> Expr
modelExpr' PrintingInformation
sm Int
prec) [ModelExpr]
exprs

setExpr :: P.Ops -> Int -> [ModelExpr] -> PrintingInformation -> P.Expr
setExpr :: Ops -> Int -> [ModelExpr] -> PrintingInformation -> Expr
setExpr Ops
_ Int
prec [ModelExpr]
exprs PrintingInformation
sm = Fence -> Fence -> Expr -> Expr
P.Fenced Fence
P.Curly Fence
P.Curly (Expr -> Expr) -> Expr -> Expr
forall a b. (a -> b) -> a -> b
$ [Expr] -> Expr
P.Row ([Expr] -> Expr) -> [Expr] -> Expr
forall a b. (a -> b) -> a -> b
$ Expr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
intersperse (Ops -> Expr
P.MO Ops
P.Comma) ([Expr] -> [Expr]) -> [Expr] -> [Expr]
forall a b. (a -> b) -> a -> b
$ (ModelExpr -> Expr) -> [ModelExpr] -> [Expr]
forall a b. (a -> b) -> [a] -> [b]
map (PrintingInformation -> Int -> ModelExpr -> Expr
modelExpr' PrintingInformation
sm Int
prec) [ModelExpr]
exprs

-- | Add add symbol only when the second Expr is not negation 
addExpr :: [ModelExpr] -> AssocArithOper -> PrintingInformation -> [P.Expr]
addExpr :: [ModelExpr] -> AssocArithOper -> PrintingInformation -> [Expr]
addExpr [] AssocArithOper
_ PrintingInformation
_ = []
addExpr [ModelExpr
x] AssocArithOper
o PrintingInformation
sm = [PrintingInformation -> Int -> ModelExpr -> Expr
modelExpr' PrintingInformation
sm (AssocArithOper -> Int
precA AssocArithOper
o) ModelExpr
x]
addExpr (ModelExpr
x1:(UnaryOp UFunc
Neg ModelExpr
x2):[ModelExpr]
xs) AssocArithOper
o PrintingInformation
sm = PrintingInformation -> Int -> ModelExpr -> Expr
modelExpr' PrintingInformation
sm (AssocArithOper -> Int
precA AssocArithOper
o) ModelExpr
x1 Expr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
: [ModelExpr] -> AssocArithOper -> PrintingInformation -> [Expr]
addExpr (UFunc -> ModelExpr -> ModelExpr
UnaryOp UFunc
Neg ModelExpr
x2ModelExpr -> [ModelExpr] -> [ModelExpr]
forall a. a -> [a] -> [a]
:[ModelExpr]
xs) AssocArithOper
o PrintingInformation
sm
addExpr (ModelExpr
x:[ModelExpr]
xs) AssocArithOper
o PrintingInformation
sm = PrintingInformation -> Int -> ModelExpr -> Expr
modelExpr' PrintingInformation
sm (AssocArithOper -> Int
precA AssocArithOper
o) ModelExpr
x Expr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
: Ops -> Expr
P.MO Ops
P.AddExpr -> [Expr] -> [Expr]
forall a. a -> [a] -> [a]
: [ModelExpr] -> AssocArithOper -> PrintingInformation -> [Expr]
addExpr [ModelExpr]
xs AssocArithOper
o PrintingInformation
sm

-- | Helper for rendering printable expressions.
mulExpr ::  [ModelExpr] -> AssocArithOper -> PrintingInformation -> [P.Expr]
mulExpr :: [ModelExpr] -> AssocArithOper -> PrintingInformation -> [Expr]
mulExpr (ModelExpr
hd1:ModelExpr
hd2:[ModelExpr]
tl) AssocArithOper
o PrintingInformation
sm = case (ModelExpr
hd1, ModelExpr
hd2) of
  (ModelExpr
a, Lit (Int Integer
_))      ->  [PrintingInformation -> Int -> ModelExpr -> Expr
modelExpr' PrintingInformation
sm (AssocArithOper -> Int
precA AssocArithOper
o) ModelExpr
a, Ops -> Expr
P.MO Ops
P.Dot] [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [ModelExpr] -> AssocArithOper -> PrintingInformation -> [Expr]
mulExpr (ModelExpr
hd2 ModelExpr -> [ModelExpr] -> [ModelExpr]
forall a. a -> [a] -> [a]
: [ModelExpr]
tl) AssocArithOper
o PrintingInformation
sm
  (ModelExpr
a, Lit (ExactDbl Integer
_)) ->  [PrintingInformation -> Int -> ModelExpr -> Expr
modelExpr' PrintingInformation
sm (AssocArithOper -> Int
precA AssocArithOper
o) ModelExpr
a, Ops -> Expr
P.MO Ops
P.Dot] [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [ModelExpr] -> AssocArithOper -> PrintingInformation -> [Expr]
mulExpr (ModelExpr
hd2 ModelExpr -> [ModelExpr] -> [ModelExpr]
forall a. a -> [a] -> [a]
: [ModelExpr]
tl) AssocArithOper
o PrintingInformation
sm
  (ModelExpr
a, Lit (Dbl Double
_))      ->  [PrintingInformation -> Int -> ModelExpr -> Expr
modelExpr' PrintingInformation
sm (AssocArithOper -> Int
precA AssocArithOper
o) ModelExpr
a, Ops -> Expr
P.MO Ops
P.Dot] [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [ModelExpr] -> AssocArithOper -> PrintingInformation -> [Expr]
mulExpr (ModelExpr
hd2 ModelExpr -> [ModelExpr] -> [ModelExpr]
forall a. a -> [a] -> [a]
: [ModelExpr]
tl) AssocArithOper
o PrintingInformation
sm
  (ModelExpr
a, ModelExpr
_)                ->  [PrintingInformation -> Int -> ModelExpr -> Expr
modelExpr' PrintingInformation
sm (AssocArithOper -> Int
precA AssocArithOper
o) ModelExpr
a, Ops -> Expr
P.MO Ops
P.Mul] [Expr] -> [Expr] -> [Expr]
forall a. [a] -> [a] -> [a]
++ [ModelExpr] -> AssocArithOper -> PrintingInformation -> [Expr]
mulExpr (ModelExpr
hd2 ModelExpr -> [ModelExpr] -> [ModelExpr]
forall a. a -> [a] -> [a]
: [ModelExpr]
tl) AssocArithOper
o PrintingInformation
sm
mulExpr [ModelExpr
hd]         AssocArithOper
o PrintingInformation
sm = [PrintingInformation -> Int -> ModelExpr -> Expr
modelExpr' PrintingInformation
sm (AssocArithOper -> Int
precA AssocArithOper
o) ModelExpr
hd]
mulExpr []           AssocArithOper
o PrintingInformation
sm = [PrintingInformation -> Int -> ModelExpr -> Expr
modelExpr' PrintingInformation
sm (AssocArithOper -> Int
precA AssocArithOper
o) (Integer -> ModelExpr
forall r. LiteralC r => Integer -> r
int Integer
1)]


-- | Helper that adds parenthesis to the first expression. The second expression
-- is written as a superscript attached to the first.
withParens :: PrintingInformation -> ModelExpr -> ModelExpr -> P.Expr
withParens :: PrintingInformation -> ModelExpr -> ModelExpr -> Expr
withParens PrintingInformation
prI ModelExpr
a ModelExpr
b = [Expr] -> Expr
P.Row [Expr -> Expr
parens (ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
prI), Expr -> Expr
P.Sup (ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
b PrintingInformation
prI)]

-- | Helper for properly rendering exponents.
pow :: PrintingInformation -> ModelExpr -> ModelExpr -> P.Expr
pow :: PrintingInformation -> ModelExpr -> ModelExpr -> Expr
pow PrintingInformation
prI a :: ModelExpr
a@(AssocA AssocArithOper
Add [ModelExpr]
_)           ModelExpr
b = PrintingInformation -> ModelExpr -> ModelExpr -> Expr
withParens PrintingInformation
prI ModelExpr
a ModelExpr
b
pow PrintingInformation
prI a :: ModelExpr
a@(AssocA AssocArithOper
Mul [ModelExpr]
_)           ModelExpr
b = PrintingInformation -> ModelExpr -> ModelExpr -> Expr
withParens PrintingInformation
prI ModelExpr
a ModelExpr
b
pow PrintingInformation
prI a :: ModelExpr
a@(ArithBinaryOp ArithBinOp
Subt ModelExpr
_ ModelExpr
_) ModelExpr
b = PrintingInformation -> ModelExpr -> ModelExpr -> Expr
withParens PrintingInformation
prI ModelExpr
a ModelExpr
b
pow PrintingInformation
prI a :: ModelExpr
a@(ArithBinaryOp ArithBinOp
Frac ModelExpr
_ ModelExpr
_) ModelExpr
b = PrintingInformation -> ModelExpr -> ModelExpr -> Expr
withParens PrintingInformation
prI ModelExpr
a ModelExpr
b
pow PrintingInformation
prI a :: ModelExpr
a@(ArithBinaryOp ArithBinOp
Pow ModelExpr
_ ModelExpr
_)  ModelExpr
b = PrintingInformation -> ModelExpr -> ModelExpr -> Expr
withParens PrintingInformation
prI ModelExpr
a ModelExpr
b
pow PrintingInformation
prI ModelExpr
a                          ModelExpr
b = [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
prI, Expr -> Expr
P.Sup (ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
b PrintingInformation
prI)]

-- | Print a 'RealInterval'.
renderRealInt :: PrintingInformation -> S.Symbol -> RealInterval ModelExpr ModelExpr -> P.Expr
renderRealInt :: PrintingInformation
-> Symbol -> RealInterval ModelExpr ModelExpr -> Expr
renderRealInt PrintingInformation
st Symbol
s (Bounded (Inclusive
Inc,ModelExpr
a) (Inclusive
Inc,ModelExpr
b)) =
  [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
st, Ops -> Expr
P.MO Ops
P.LEq, Symbol -> Expr
symbol Symbol
s, Ops -> Expr
P.MO Ops
P.LEq, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
b PrintingInformation
st]
renderRealInt PrintingInformation
st Symbol
s (Bounded (Inclusive
Inc,ModelExpr
a) (Inclusive
Exc,ModelExpr
b)) =
  [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
st, Ops -> Expr
P.MO Ops
P.LEq, Symbol -> Expr
symbol Symbol
s, Ops -> Expr
P.MO Ops
P.Lt, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
b PrintingInformation
st]
renderRealInt PrintingInformation
st Symbol
s (Bounded (Inclusive
Exc,ModelExpr
a) (Inclusive
Inc,ModelExpr
b)) =
  [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
st, Ops -> Expr
P.MO Ops
P.Lt, Symbol -> Expr
symbol Symbol
s, Ops -> Expr
P.MO Ops
P.LEq, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
b PrintingInformation
st]
renderRealInt PrintingInformation
st Symbol
s (Bounded (Inclusive
Exc,ModelExpr
a) (Inclusive
Exc,ModelExpr
b)) =
  [Expr] -> Expr
P.Row [ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
st, Ops -> Expr
P.MO Ops
P.Lt, Symbol -> Expr
symbol Symbol
s, Ops -> Expr
P.MO Ops
P.Lt, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
b PrintingInformation
st]
renderRealInt PrintingInformation
st Symbol
s (UpTo (Inclusive
Inc,ModelExpr
a))   = [Expr] -> Expr
P.Row [Symbol -> Expr
symbol Symbol
s, Ops -> Expr
P.MO Ops
P.LEq, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
st]
renderRealInt PrintingInformation
st Symbol
s (UpTo (Inclusive
Exc,ModelExpr
a))   = [Expr] -> Expr
P.Row [Symbol -> Expr
symbol Symbol
s, Ops -> Expr
P.MO Ops
P.Lt,  ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
st]
renderRealInt PrintingInformation
st Symbol
s (UpFrom (Inclusive
Inc,ModelExpr
a)) = [Expr] -> Expr
P.Row [Symbol -> Expr
symbol Symbol
s, Ops -> Expr
P.MO Ops
P.GEq, ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
st]
renderRealInt PrintingInformation
st Symbol
s (UpFrom (Inclusive
Exc,ModelExpr
a)) = [Expr] -> Expr
P.Row [Symbol -> Expr
symbol Symbol
s, Ops -> Expr
P.MO Ops
P.Gt,  ModelExpr -> PrintingInformation -> Expr
modelExpr ModelExpr
a PrintingInformation
st]