{-# LANGUAGE CPP #-}
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE StandaloneDeriving #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE UndecidableInstances #-}
module Grisette.Internal.Internal.Impl.Core.Data.Class.SymOrd () where
import Control.Monad.Except (ExceptT)
import Control.Monad.Identity
( Identity,
IdentityT (IdentityT),
)
import Control.Monad.Trans.Maybe (MaybeT)
import qualified Control.Monad.Writer.Lazy as WriterLazy
import qualified Control.Monad.Writer.Strict as WriterStrict
import qualified Data.ByteString as B
import Data.Functor.Compose (Compose (Compose))
import Data.Functor.Const (Const)
import Data.Functor.Product (Product)
import Data.Functor.Sum (Sum)
import Data.Int (Int16, Int32, Int64, Int8)
import Data.Monoid (Alt, Ap)
import qualified Data.Monoid as Monoid
import Data.Ord (Down (Down))
import Data.Proxy (Proxy)
import Data.Ratio (Ratio, denominator, numerator)
import qualified Data.Text as T
import Data.Word (Word16, Word32, Word64, Word8)
import GHC.TypeLits (KnownNat, type (<=))
import Generics.Deriving
( Default (Default),
Default1 (Default1),
K1 (K1),
M1 (M1),
Par1 (Par1),
Rec1 (Rec1),
U1,
V1,
(:.:) (Comp1),
type (:*:),
type (:+:),
)
import Grisette.Internal.Core.Control.Exception
( AssertionError,
VerificationConditions,
)
import Grisette.Internal.Core.Control.Monad.Union (Union)
import Grisette.Internal.Core.Data.Class.LogicalOp
( LogicalOp (symNot, (.&&), (.||)),
)
import Grisette.Internal.Core.Data.Class.PlainUnion
( simpleMerge,
)
import Grisette.Internal.Core.Data.Class.SimpleMergeable
( mrgIf,
)
import Grisette.Internal.Core.Data.Class.Solvable (Solvable (con))
import Grisette.Internal.Core.Data.Class.SymEq
( SymEq ((.==)),
)
import Grisette.Internal.Core.Data.Class.TryMerge
( mrgSingle,
tryMerge,
)
import Grisette.Internal.Internal.Decl.Core.Data.Class.SymOrd
( SymOrd (symCompare, (.<), (.<=), (.>), (.>=)),
SymOrd1 (liftSymCompare),
SymOrd2,
symCompare1,
)
import Grisette.Internal.SymPrim.AlgReal (AlgReal)
import Grisette.Internal.SymPrim.BV (IntN, WordN)
import Grisette.Internal.SymPrim.FP (FP, FPRoundingMode, NotRepresentableFPError, ValidFP)
import Grisette.Internal.SymPrim.Prim.Term
( PEvalOrdTerm
( pevalLeOrdTerm,
pevalLtOrdTerm
),
pevalGeOrdTerm,
pevalGtOrdTerm,
)
import Grisette.Internal.SymPrim.SymAlgReal (SymAlgReal (SymAlgReal))
import Grisette.Internal.SymPrim.SymBV
( SymIntN (SymIntN),
SymWordN (SymWordN),
)
import Grisette.Internal.SymPrim.SymBool (SymBool (SymBool))
import Grisette.Internal.SymPrim.SymFP
( SymFP (SymFP),
SymFPRoundingMode (SymFPRoundingMode),
)
import Grisette.Internal.SymPrim.SymInteger (SymInteger (SymInteger))
import Grisette.Internal.TH.Derivation.Derive (derive)
#define CONCRETE_SORD(type) \
instance SymOrd type where \
l .<= r = con $ l <= r; \
l .< r = con $ l < r; \
l .>= r = con $ l >= r; \
l .> r = con $ l > r; \
symCompare l r = mrgSingle $ compare l r; \
{-# INLINE (.<=) #-}; \
{-# INLINE (.<) #-}; \
{-# INLINE (.>=) #-}; \
{-# INLINE (.>) #-}; \
{-# INLINE symCompare #-}
#define CONCRETE_SORD_BV(type) \
instance (KnownNat n, 1 <= n) => SymOrd (type n) where \
l .<= r = con $ l <= r; \
l .< r = con $ l < r; \
l .>= r = con $ l >= r; \
l .> r = con $ l > r; \
symCompare l r = mrgSingle $ compare l r; \
{-# INLINE (.<=) #-}; \
{-# INLINE (.<) #-}; \
{-# INLINE (.>=) #-}; \
{-# INLINE (.>) #-}; \
{-# INLINE symCompare #-}
#if 1
CONCRETE_SORD(Bool)
CONCRETE_SORD(Integer)
CONCRETE_SORD(Char)
CONCRETE_SORD(Int)
CONCRETE_SORD(Int8)
CONCRETE_SORD(Int16)
CONCRETE_SORD(Int32)
CONCRETE_SORD(Int64)
CONCRETE_SORD(Word)
CONCRETE_SORD(Word8)
CONCRETE_SORD(Word16)
CONCRETE_SORD(Word32)
CONCRETE_SORD(Word64)
CONCRETE_SORD(Float)
CONCRETE_SORD(Double)
CONCRETE_SORD(B.ByteString)
CONCRETE_SORD(T.Text)
CONCRETE_SORD(FPRoundingMode)
CONCRETE_SORD(Monoid.All)
CONCRETE_SORD(Monoid.Any)
CONCRETE_SORD(Ordering)
CONCRETE_SORD_BV(WordN)
CONCRETE_SORD_BV(IntN)
CONCRETE_SORD(AlgReal)
#endif
instance SymOrd (Proxy a) where
Proxy a
_ .<= :: Proxy a -> Proxy a -> SymBool
.<= Proxy a
_ = Bool -> SymBool
forall c t. Solvable c t => c -> t
con Bool
True
{-# INLINE (.<=) #-}
Proxy a
_ .< :: Proxy a -> Proxy a -> SymBool
.< Proxy a
_ = Bool -> SymBool
forall c t. Solvable c t => c -> t
con Bool
False
{-# INLINE (.<) #-}
Proxy a
_ .>= :: Proxy a -> Proxy a -> SymBool
.>= Proxy a
_ = Bool -> SymBool
forall c t. Solvable c t => c -> t
con Bool
True
{-# INLINE (.>=) #-}
Proxy a
_ .> :: Proxy a -> Proxy a -> SymBool
.> Proxy a
_ = Bool -> SymBool
forall c t. Solvable c t => c -> t
con Bool
False
{-# INLINE (.>) #-}
symCompare :: Proxy a -> Proxy a -> Union Ordering
symCompare Proxy a
_ Proxy a
_ = Ordering -> Union Ordering
forall (m :: * -> *) a.
(TryMerge m, Applicative m, Mergeable a) =>
a -> m a
mrgSingle Ordering
EQ
{-# INLINE symCompare #-}
instance SymOrd1 Proxy where
liftSymCompare :: forall a b.
(a -> b -> Union Ordering) -> Proxy a -> Proxy b -> Union Ordering
liftSymCompare a -> b -> Union Ordering
_ Proxy a
_ Proxy b
_ = Ordering -> Union Ordering
forall (m :: * -> *) a.
(TryMerge m, Applicative m, Mergeable a) =>
a -> m a
mrgSingle Ordering
EQ
{-# INLINE liftSymCompare #-}
instance (SymOrd a, Integral a) => SymOrd (Ratio a) where
Ratio a
a .<= :: Ratio a -> Ratio a -> SymBool
.<= Ratio a
b = Ratio a -> a
forall a. Ratio a -> a
numerator Ratio a
a a -> a -> a
forall a. Num a => a -> a -> a
* Ratio a -> a
forall a. Ratio a -> a
denominator Ratio a
b a -> a -> SymBool
forall a. SymOrd a => a -> a -> SymBool
.<= Ratio a -> a
forall a. Ratio a -> a
numerator Ratio a
b a -> a -> a
forall a. Num a => a -> a -> a
* Ratio a -> a
forall a. Ratio a -> a
denominator Ratio a
a
{-# INLINE (.<=) #-}
Ratio a
a .< :: Ratio a -> Ratio a -> SymBool
.< Ratio a
b = Ratio a -> a
forall a. Ratio a -> a
numerator Ratio a
a a -> a -> a
forall a. Num a => a -> a -> a
* Ratio a -> a
forall a. Ratio a -> a
denominator Ratio a
b a -> a -> SymBool
forall a. SymOrd a => a -> a -> SymBool
.< Ratio a -> a
forall a. Ratio a -> a
numerator Ratio a
b a -> a -> a
forall a. Num a => a -> a -> a
* Ratio a -> a
forall a. Ratio a -> a
denominator Ratio a
a
{-# INLINE (.<) #-}
instance (ValidFP eb sb) => SymOrd (FP eb sb) where
FP eb sb
l .<= :: FP eb sb -> FP eb sb -> SymBool
.<= FP eb sb
r = Bool -> SymBool
forall c t. Solvable c t => c -> t
con (Bool -> SymBool) -> Bool -> SymBool
forall a b. (a -> b) -> a -> b
$ FP eb sb
l FP eb sb -> FP eb sb -> Bool
forall a. Ord a => a -> a -> Bool
<= FP eb sb
r
{-# INLINE (.<=) #-}
FP eb sb
l .< :: FP eb sb -> FP eb sb -> SymBool
.< FP eb sb
r = Bool -> SymBool
forall c t. Solvable c t => c -> t
con (Bool -> SymBool) -> Bool -> SymBool
forall a b. (a -> b) -> a -> b
$ FP eb sb
l FP eb sb -> FP eb sb -> Bool
forall a. Ord a => a -> a -> Bool
< FP eb sb
r
{-# INLINE (.<) #-}
FP eb sb
l .>= :: FP eb sb -> FP eb sb -> SymBool
.>= FP eb sb
r = Bool -> SymBool
forall c t. Solvable c t => c -> t
con (Bool -> SymBool) -> Bool -> SymBool
forall a b. (a -> b) -> a -> b
$ FP eb sb
l FP eb sb -> FP eb sb -> Bool
forall a. Ord a => a -> a -> Bool
>= FP eb sb
r
{-# INLINE (.>=) #-}
FP eb sb
l .> :: FP eb sb -> FP eb sb -> SymBool
.> FP eb sb
r = Bool -> SymBool
forall c t. Solvable c t => c -> t
con (Bool -> SymBool) -> Bool -> SymBool
forall a b. (a -> b) -> a -> b
$ FP eb sb
l FP eb sb -> FP eb sb -> Bool
forall a. Ord a => a -> a -> Bool
> FP eb sb
r
{-# INLINE (.>) #-}
#define SORD_SIMPLE(symtype) \
instance SymOrd symtype where \
(symtype a) .<= (symtype b) = SymBool $ pevalLeOrdTerm a b; \
(symtype a) .< (symtype b) = SymBool $ pevalLtOrdTerm a b; \
(symtype a) .>= (symtype b) = SymBool $ pevalGeOrdTerm a b; \
(symtype a) .> (symtype b) = SymBool $ pevalGtOrdTerm a b; \
a `symCompare` b = mrgIf \
(a .< b) \
(mrgSingle LT) \
(mrgIf (a .== b) (mrgSingle EQ) (mrgSingle GT)); \
{-# INLINE (.<=) #-}; \
{-# INLINE (.<) #-}; \
{-# INLINE (.>=) #-}; \
{-# INLINE (.>) #-}; \
{-# INLINE symCompare #-}
#define SORD_BV(symtype) \
instance (KnownNat n, 1 <= n) => SymOrd (symtype n) where \
(symtype a) .<= (symtype b) = SymBool $ pevalLeOrdTerm a b; \
(symtype a) .< (symtype b) = SymBool $ pevalLtOrdTerm a b; \
(symtype a) .>= (symtype b) = SymBool $ pevalGeOrdTerm a b; \
(symtype a) .> (symtype b) = SymBool $ pevalGtOrdTerm a b; \
a `symCompare` b = mrgIf \
(a .< b) \
(mrgSingle LT) \
(mrgIf (a .== b) (mrgSingle EQ) (mrgSingle GT)); \
{-# INLINE (.<=) #-}; \
{-# INLINE (.<) #-}; \
{-# INLINE (.>=) #-}; \
{-# INLINE (.>) #-}; \
{-# INLINE symCompare #-}
instance (ValidFP eb sb) => SymOrd (SymFP eb sb) where
(SymFP Term (FP eb sb)
a) .<= :: SymFP eb sb -> SymFP eb sb -> SymBool
.<= (SymFP Term (FP eb sb)
b) = Term Bool -> SymBool
SymBool (Term Bool -> SymBool) -> Term Bool -> SymBool
forall a b. (a -> b) -> a -> b
$ Term (FP eb sb) -> Term (FP eb sb) -> Term Bool
forall t. PEvalOrdTerm t => Term t -> Term t -> Term Bool
pevalLeOrdTerm Term (FP eb sb)
a Term (FP eb sb)
b
{-# INLINE (.<=) #-}
(SymFP Term (FP eb sb)
a) .< :: SymFP eb sb -> SymFP eb sb -> SymBool
.< (SymFP Term (FP eb sb)
b) = Term Bool -> SymBool
SymBool (Term Bool -> SymBool) -> Term Bool -> SymBool
forall a b. (a -> b) -> a -> b
$ Term (FP eb sb) -> Term (FP eb sb) -> Term Bool
forall t. PEvalOrdTerm t => Term t -> Term t -> Term Bool
pevalLtOrdTerm Term (FP eb sb)
a Term (FP eb sb)
b
{-# INLINE (.<) #-}
(SymFP Term (FP eb sb)
a) .>= :: SymFP eb sb -> SymFP eb sb -> SymBool
.>= (SymFP Term (FP eb sb)
b) = Term Bool -> SymBool
SymBool (Term Bool -> SymBool) -> Term Bool -> SymBool
forall a b. (a -> b) -> a -> b
$ Term (FP eb sb) -> Term (FP eb sb) -> Term Bool
forall t. PEvalOrdTerm t => Term t -> Term t -> Term Bool
pevalGeOrdTerm Term (FP eb sb)
a Term (FP eb sb)
b
{-# INLINE (.>=) #-}
(SymFP Term (FP eb sb)
a) .> :: SymFP eb sb -> SymFP eb sb -> SymBool
.> (SymFP Term (FP eb sb)
b) = Term Bool -> SymBool
SymBool (Term Bool -> SymBool) -> Term Bool -> SymBool
forall a b. (a -> b) -> a -> b
$ Term (FP eb sb) -> Term (FP eb sb) -> Term Bool
forall t. PEvalOrdTerm t => Term t -> Term t -> Term Bool
pevalGtOrdTerm Term (FP eb sb)
a Term (FP eb sb)
b
{-# INLINE (.>) #-}
instance SymOrd SymBool where
SymBool
l .<= :: SymBool -> SymBool -> SymBool
.<= SymBool
r = SymBool -> SymBool
forall b. LogicalOp b => b -> b
symNot SymBool
l SymBool -> SymBool -> SymBool
forall b. LogicalOp b => b -> b -> b
.|| SymBool
r
{-# INLINE (.<=) #-}
SymBool
l .< :: SymBool -> SymBool -> SymBool
.< SymBool
r = SymBool -> SymBool
forall b. LogicalOp b => b -> b
symNot SymBool
l SymBool -> SymBool -> SymBool
forall b. LogicalOp b => b -> b -> b
.&& SymBool
r
{-# INLINE (.<) #-}
SymBool
l .>= :: SymBool -> SymBool -> SymBool
.>= SymBool
r = SymBool
l SymBool -> SymBool -> SymBool
forall b. LogicalOp b => b -> b -> b
.|| SymBool -> SymBool
forall b. LogicalOp b => b -> b
symNot SymBool
r
{-# INLINE (.>=) #-}
SymBool
l .> :: SymBool -> SymBool -> SymBool
.> SymBool
r = SymBool
l SymBool -> SymBool -> SymBool
forall b. LogicalOp b => b -> b -> b
.&& SymBool -> SymBool
forall b. LogicalOp b => b -> b
symNot SymBool
r
{-# INLINE (.>) #-}
symCompare :: SymBool -> SymBool -> Union Ordering
symCompare SymBool
l SymBool
r =
SymBool -> Union Ordering -> Union Ordering -> Union Ordering
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf
(SymBool -> SymBool
forall b. LogicalOp b => b -> b
symNot SymBool
l SymBool -> SymBool -> SymBool
forall b. LogicalOp b => b -> b -> b
.&& SymBool
r)
(Ordering -> Union Ordering
forall (m :: * -> *) a.
(TryMerge m, Applicative m, Mergeable a) =>
a -> m a
mrgSingle Ordering
LT)
(SymBool -> Union Ordering -> Union Ordering -> Union Ordering
forall (u :: * -> *) a.
(SymBranching u, Mergeable a) =>
SymBool -> u a -> u a -> u a
mrgIf (SymBool
l SymBool -> SymBool -> SymBool
forall a. SymEq a => a -> a -> SymBool
.== SymBool
r) (Ordering -> Union Ordering
forall (m :: * -> *) a.
(TryMerge m, Applicative m, Mergeable a) =>
a -> m a
mrgSingle Ordering
EQ) (Ordering -> Union Ordering
forall (m :: * -> *) a.
(TryMerge m, Applicative m, Mergeable a) =>
a -> m a
mrgSingle Ordering
GT))
{-# INLINE symCompare #-}
#if 1
SORD_SIMPLE(SymInteger)
SORD_SIMPLE(SymAlgReal)
SORD_SIMPLE(SymFPRoundingMode)
SORD_BV(SymIntN)
SORD_BV(SymWordN)
#endif
instance (SymOrd a) => SymOrd (Union a) where
Union a
x .<= :: Union a -> Union a -> SymBool
.<= Union a
y = Union SymBool -> SymBool
forall (u :: * -> *) a.
(SimpleMergeable a, PlainUnion u) =>
u a -> a
simpleMerge (Union SymBool -> SymBool) -> Union SymBool -> SymBool
forall a b. (a -> b) -> a -> b
$ do
x1 <- Union a
x
y1 <- y
mrgSingle $ x1 .<= y1
Union a
x .< :: Union a -> Union a -> SymBool
.< Union a
y = Union SymBool -> SymBool
forall (u :: * -> *) a.
(SimpleMergeable a, PlainUnion u) =>
u a -> a
simpleMerge (Union SymBool -> SymBool) -> Union SymBool -> SymBool
forall a b. (a -> b) -> a -> b
$ do
x1 <- Union a
x
y1 <- y
mrgSingle $ x1 .< y1
Union a
x .>= :: Union a -> Union a -> SymBool
.>= Union a
y = Union SymBool -> SymBool
forall (u :: * -> *) a.
(SimpleMergeable a, PlainUnion u) =>
u a -> a
simpleMerge (Union SymBool -> SymBool) -> Union SymBool -> SymBool
forall a b. (a -> b) -> a -> b
$ do
x1 <- Union a
x
y1 <- y
mrgSingle $ x1 .>= y1
Union a
x .> :: Union a -> Union a -> SymBool
.> Union a
y = Union SymBool -> SymBool
forall (u :: * -> *) a.
(SimpleMergeable a, PlainUnion u) =>
u a -> a
simpleMerge (Union SymBool -> SymBool) -> Union SymBool -> SymBool
forall a b. (a -> b) -> a -> b
$ do
x1 <- Union a
x
y1 <- y
mrgSingle $ x1 .> y1
Union a
x symCompare :: Union a -> Union a -> Union Ordering
`symCompare` Union a
y = Union Ordering -> Union Ordering
forall (m :: * -> *) a. (TryMerge m, Mergeable a) => m a -> m a
tryMerge (Union Ordering -> Union Ordering)
-> Union Ordering -> Union Ordering
forall a b. (a -> b) -> a -> b
$ do
x1 <- Union a
x
y1 <- y
x1 `symCompare` y1
instance SymOrd1 Union where
liftSymCompare :: forall a b.
(a -> b -> Union Ordering) -> Union a -> Union b -> Union Ordering
liftSymCompare a -> b -> Union Ordering
f Union a
x Union b
y = Union Ordering -> Union Ordering
forall (m :: * -> *) a. (TryMerge m, Mergeable a) => m a -> m a
tryMerge (Union Ordering -> Union Ordering)
-> Union Ordering -> Union Ordering
forall a b. (a -> b) -> a -> b
$ do
x1 <- Union a
x
y1 <- y
f x1 y1
derive
[ ''(),
''AssertionError,
''VerificationConditions,
''NotRepresentableFPError
]
[''SymOrd]