module ToySolver.Data.ArithRel
(
RelOp (..)
, flipOp
, negOp
, showOp
, evalOp
, Rel (..)
, IsRel (..)
, (.<.), (.<=.), (.>=.), (.>.), (.==.), (./=.)
) where
import qualified Data.IntSet as IS
import ToySolver.Data.Boolean
import ToySolver.Data.Var
infix 4 .<., .<=., .>=., .>., .==., ./=.
data RelOp = Lt | Le | Ge | Gt | Eql | NEq
deriving (Show, Eq, Ord)
flipOp :: RelOp -> RelOp
flipOp Le = Ge
flipOp Ge = Le
flipOp Lt = Gt
flipOp Gt = Lt
flipOp Eql = Eql
flipOp NEq = NEq
negOp :: RelOp -> RelOp
negOp Lt = Ge
negOp Le = Gt
negOp Ge = Lt
negOp Gt = Le
negOp Eql = NEq
negOp NEq = Eql
showOp :: RelOp -> String
showOp Lt = "<"
showOp Le = "<="
showOp Ge = ">="
showOp Gt = ">"
showOp Eql = "="
showOp NEq = "/="
evalOp :: Ord a => RelOp -> a -> a -> Bool
evalOp Lt = (<)
evalOp Le = (<=)
evalOp Ge = (>=)
evalOp Gt = (>)
evalOp Eql = (==)
evalOp NEq = (/=)
class IsRel e r | r -> e where
rel :: RelOp -> e -> e -> r
(.<.) :: IsRel e r => e -> e -> r
a .<. b = rel Lt a b
(.<=.) :: IsRel e r => e -> e -> r
a .<=. b = rel Le a b
(.>.) :: IsRel e r => e -> e -> r
a .>. b = rel Gt a b
(.>=.) :: IsRel e r => e -> e -> r
a .>=. b = rel Ge a b
(.==.) :: IsRel e r => e -> e -> r
a .==. b = rel Eql a b
(./=.) :: IsRel e r => e -> e -> r
a ./=. b = rel NEq a b
data Rel e = Rel e RelOp e
deriving (Show, Eq, Ord)
instance Complement (Rel c) where
notB (Rel lhs op rhs) = Rel lhs (negOp op) rhs
instance IsRel e (Rel e) where
rel op a b = Rel a op b
instance Variables e => Variables (Rel e) where
vars (Rel a _ b) = vars a `IS.union` vars b
instance Functor Rel where
fmap f (Rel a op b) = Rel (f a) op (f b)