module Feldspar.Core.Constructs.Condition
( module Language.Syntactic.Constructs.Condition
) where
import Language.Syntactic
import Language.Syntactic.Constructs.Binding hiding (subst)
import Language.Syntactic.Constructs.Binding.HigherOrder (CLambda(..))
import Language.Syntactic.Constructs.Literal
import Language.Syntactic.Constructs.Condition
import Feldspar.Lattice
import Feldspar.Core.Types
import Feldspar.Core.Interpretation
import Feldspar.Core.Constructs.Eq
import Feldspar.Core.Constructs.Ord
import Feldspar.Core.Constructs.Logic
import Feldspar.Core.Constructs.Binding (subst)
import Data.Typeable (Typeable)
instance Sharable Condition
instance Monotonic Condition
instance SizeProp (Condition :|| Type)
where
sizeProp (C' Condition) (_ :* WrapFull t :* WrapFull f :* Nil)
= infoSize t \/ infoSize f
instance ( (Condition :|| Type) :<: dom
, (Logic :|| Type) :<: dom
, (EQ :|| Type) :<: dom
, (ORD :|| Type) :<: dom
, (Variable :|| Type) :<: dom
, CLambda Type :<: dom
, Monotonic dom
, OptimizeSuper dom
)
=> Optimize (Condition :|| Type) dom
where
optimizeFeat opts s@(C' Condition) (c :* t :* f :* Nil)
| Just (C' (Variable v)) <- prjF c
= optimizeFeatDefault opts s $ c :* subst v (literal True) t
:* subst v (literal False) f
:* Nil
optimizeFeat opts s@(C' Condition) (c@(op :$ a :$ b) :* t :* f :* Nil)
| Just (C' Equal) <- prjF op
, Just (C' (Variable v)) <- prjF b
= optimizeFeatDefault opts s $ c :* subst v a t :* f :* Nil
| Just (C' Equal) <- prjF op
, Just (C' (Variable v)) <- prjF a
= optimizeFeatDefault opts s $ c :* subst v b t :* f :* Nil
optimizeFeat opts s@(C' Condition) (c@(op :$ a :$ b) :* t :* f :* Nil)
| Just (C' NotEqual) <- prjF op
, Just (C' (Variable v)) <- prjF b
= optimizeFeatDefault opts s $ c :* t :* subst v a f :* Nil
| Just (C' NotEqual) <- prjF op
, Just (C' (Variable v)) <- prjF a
= optimizeFeatDefault opts s $ c :* t :* subst v b f :* Nil
optimizeFeat opts sym args = optimizeFeatDefault opts sym args
constructFeatOpt opts (C' Condition) (c :* t :* f :* Nil)
| Just cl <- viewLiteral c = return $ if cl then t else f
constructFeatOpt opts (C' Condition) (c :* t :* f :* Nil)
| BoolType <- infoType (getInfo t)
, Just tl <- viewLiteral t
, Just fl <- viewLiteral f
= case (tl,fl) of
(True,False) -> return c
(False,True) -> constructFeat opts (c' Not) (c :* Nil)
constructFeatOpt _ (C' Condition) (_ :* t :* f :* Nil)
| alphaEq t f = return t
constructFeatOpt opts cond@(C' Condition) ((op :$ c) :* t :* f :* Nil)
| Just (C' Not) <- prjF op
= constructFeat opts cond (c :* f :* t :* Nil)
constructFeatOpt opts a args = constructFeatUnOpt opts a args
constructFeatUnOpt opts x@(C' _) = constructFeatUnOptDefault opts x