module Numeric.Limp.Program.Constraint where
import Numeric.Limp.Rep
import Numeric.Limp.Program.Linear
import Data.Monoid
data Constraint z r c where
(:==) :: Linear z r c k1 -> Linear z r c k2 -> Constraint z r c
(:<=) :: Linear z r c k1 -> Linear z r c k2 -> Constraint z r c
(:<) :: Linear z r c KZ -> Linear z r c KZ -> Constraint z r c
(:>=) :: Linear z r c k1 -> Linear z r c k2 -> Constraint z r c
(:>) :: Linear z r c KZ -> Linear z r c KZ -> Constraint z r c
Between :: Linear z r c k1 -> Linear z r c k2 -> Linear z r c k3 -> Constraint z r c
(:&&) :: Constraint z r c -> Constraint z r c -> Constraint z r c
(:!) :: String -> Constraint z r c -> Constraint z r c
CTrue :: Constraint z r c
infix 5 :==
infix 5 :<=
infix 5 :<
infix 5 :>=
infix 5 :>
infix 4 :!
infixr 3 :&&
check :: (Rep c, Ord z, Ord r) => Assignment z r c -> Constraint z r c -> Bool
check ass = go
where
go (a :== b)
= evalR ass a == evalR ass b
go (a :<= b)
= evalR ass a <= evalR ass b
go (a :>= b)
= evalR ass a >= evalR ass b
go (a :< b)
= eval ass a < eval ass b
go (a :> b)
= eval ass a > eval ass b
go (Between a b c)
= evalR ass a <= evalR ass b && evalR ass b <= evalR ass c
go (a :&& b)
= go a && go b
go (_ :! a)
= go a
go CTrue
= True
instance Monoid (Constraint z r c) where
mempty = CTrue
mappend = (:&&)