module Feldspar.Core.Constructs.Ord
( ORD (..)
) where
import Language.Syntactic
import Language.Syntactic.Constructs.Binding
import Feldspar.Range
import Feldspar.Core.Types
import Feldspar.Core.Interpretation
data ORD a
where
LTH :: (Type a, Ord a, Ord (Size a)) => ORD (a :-> a :-> Full Bool)
GTH :: (Type a, Ord a, Ord (Size a)) => ORD (a :-> a :-> Full Bool)
LTE :: (Type a, Ord a, Ord (Size a)) => ORD (a :-> a :-> Full Bool)
GTE :: (Type a, Ord a, Ord (Size a)) => ORD (a :-> a :-> Full Bool)
Min :: (Type a, Ord a, Ord (Size a)) => ORD (a :-> a :-> Full a)
Max :: (Type a, Ord a, Ord (Size a)) => ORD (a :-> a :-> Full a)
instance Semantic ORD
where
semantics LTH = Sem "(<)" (<)
semantics GTH = Sem "(>)" (>)
semantics LTE = Sem "(<=)" (<=)
semantics GTE = Sem "(>=)" (>=)
semantics Min = Sem "min" min
semantics Max = Sem "max" max
semanticInstances ''ORD
instance EvalBind ORD where evalBindSym = evalBindSymDefault
instance AlphaEq dom dom dom env => AlphaEq ORD ORD dom env
where
alphaEqSym = alphaEqSymDefault
instance Sharable ORD
instance Monotonic ORD
instance SizeProp (ORD :|| Type)
where
sizeProp (C' Min) (WrapFull a :* WrapFull b :* Nil) = min (infoSize a) (infoSize b)
sizeProp (C' Max) (WrapFull a :* WrapFull b :* Nil) = max (infoSize a) (infoSize b)
sizeProp a@(C' _) args = sizePropDefault a args
instance ( (ORD :|| Type) :<: dom
, Monotonic dom
, OptimizeSuper dom
)
=> Optimize (ORD :|| Type) dom
where
constructFeatOpt _ (C' LTH) (a :* b :* Nil)
| RangeSet ra <- infoRange (getInfo a)
, RangeSet rb <- infoRange (getInfo b)
, ra `rangeLess` rb
= return (literalDecor True)
constructFeatOpt _ (C' LTH) (a :* b :* Nil)
| RangeSet ra <- infoRange (getInfo a)
, RangeSet rb <- infoRange (getInfo b)
, rb `rangeLessEq` ra
= return (literalDecor False)
constructFeatOpt _ (C' GTH) (a :* b :* Nil)
| RangeSet ra <- infoRange (getInfo a)
, RangeSet rb <- infoRange (getInfo b)
, rb `rangeLess` ra
= return (literalDecor True)
constructFeatOpt _ (C' GTH) (a :* b :* Nil)
| RangeSet ra <- infoRange (getInfo a)
, RangeSet rb <- infoRange (getInfo b)
, ra `rangeLessEq` rb
= return (literalDecor False)
constructFeatOpt _ (C' LTE) (a :* b :* Nil)
| RangeSet ra <- infoRange (getInfo a)
, RangeSet rb <- infoRange (getInfo b)
, ra `rangeLessEq` rb
= return (literalDecor True)
constructFeatOpt _ (C' LTE) (a :* b :* Nil)
| RangeSet ra <- infoRange (getInfo a)
, RangeSet rb <- infoRange (getInfo b)
, rb `rangeLess` ra
= return (literalDecor False)
constructFeatOpt _ (C' LTE) (a :* b :* Nil)
| alphaEq a b
= return $ literalDecor True
constructFeatOpt _ (C' GTE) (a :* b :* Nil)
| RangeSet ra <- infoRange (getInfo a)
, RangeSet rb <- infoRange (getInfo b)
, rb `rangeLessEq` ra
= return (literalDecor True)
constructFeatOpt _ (C' GTE) (a :* b :* Nil)
| RangeSet ra <- infoRange (getInfo a)
, RangeSet rb <- infoRange (getInfo b)
, ra `rangeLess` rb
= return (literalDecor False)
constructFeatOpt _ (C' GTE) (a :* b :* Nil)
| alphaEq a b
= return $ literalDecor True
constructFeatOpt _ (C' Min) (a :* b :* Nil)
| RangeSet ra <- infoRange (getInfo a)
, RangeSet rb <- infoRange (getInfo b)
, ra `rangeLessEq` rb
= return a
constructFeatOpt _ (C' Min) (a :* b :* Nil)
| RangeSet ra <- infoRange (getInfo a)
, RangeSet rb <- infoRange (getInfo b)
, rb `rangeLessEq` ra
= return b
constructFeatOpt _ (C' Min) (a :* b :* Nil)
| alphaEq a b
= return a
constructFeatOpt _ (C' Min) (a :* b :* Nil)
| as <- viewMonotonicDec a
, any (alphaEq b) as = return a
| bs <- viewMonotonicDec b
, any (alphaEq a) bs = return b
constructFeatOpt opts s@(C' Min) (a :* (op :$ b :$ c) :* Nil)
| Just (C' Min) <- prjF op
, alphaEq a b = constructFeat opts s (a :* c :* Nil)
| Just (C' Min) <- prjF op
, alphaEq a c = constructFeat opts s (a :* b :* Nil)
constructFeatOpt opts s@(C' Min) ((op :$ b :$ c) :* a :* Nil)
| Just (C' Min) <- prjF op
, alphaEq a b = constructFeat opts s (c :* a :* Nil)
| Just (C' Min) <- prjF op
, alphaEq a c = constructFeat opts s (b :* a :* Nil)
constructFeatOpt _ (C' Max) (a :* b :* Nil)
| RangeSet ra <- infoRange (getInfo a)
, RangeSet rb <- infoRange (getInfo b)
, ra `rangeLessEq` rb
= return b
constructFeatOpt _ (C' Max) (a :* b :* Nil)
| RangeSet ra <- infoRange (getInfo a)
, RangeSet rb <- infoRange (getInfo b)
, rb `rangeLessEq` ra
= return a
constructFeatOpt _ (C' Max) (a :* b :* Nil)
| alphaEq a b
= return a
constructFeatOpt opts s@(C' Max) (a :* (op :$ b :$ c) :* Nil)
| Just (C' Max) <- prjF op
, alphaEq a b = constructFeat opts s (a :* c :* Nil)
| Just (C' Max) <- prjF op
, alphaEq a c = constructFeat opts s (a :* b :* Nil)
constructFeatOpt opts s@(C' Max) ((op :$ b :$ c) :* a :* Nil)
| Just (C' Max) <- prjF op
, alphaEq a b = constructFeat opts s (c :* a :* Nil)
| Just (C' Max) <- prjF op
, alphaEq a c = constructFeat opts s (b :* a :* Nil)
constructFeatOpt opts a args = constructFeatUnOpt opts a args
constructFeatUnOpt opts x@(C' _) = constructFeatUnOptDefault opts x