sbv-13.1: SMT Based Verification: Symbolic Haskell theorem prover using SMT solving.
Copyright(c) Joel Burget
Levent Erkok
LicenseBSD3
Maintainererkokl@gmail.com
Stabilityexperimental
Safe HaskellNone
LanguageHaskell2010

Data.SBV.Either

Description

Symbolic coproduct, symbolic version of Haskell's Either type.

Synopsis

Constructing sums

sLeft :: (SymVal a, SymVal b) => SBV a -> SBV (Either a b) Source #

Symbolic version of the constructor Left.

sRight :: (SymVal a, SymVal b) => SBV b -> SBV (Either a b) Source #

Symbolic version of the constructor Right.

liftEither :: (SymVal a, SymVal b) => Either (SBV a) (SBV b) -> SEither a b Source #

Construct an SEither a b from an Either (SBV a) (SBV b)

>>> liftEither (Left 3 :: Either SInteger SBool)
Left 3 :: Either Integer Bool
>>> liftEither (Right sTrue :: Either SInteger SBool)
Right True :: Either Integer Bool

type SEither a b = SBV (Either a b) Source #

Symbolic version of the type Either.

sEither :: (SymVal a, SymVal b) => String -> Symbolic (SEither a b) Source #

Declare a symbolic maybe.

sEither_ :: (SymVal a, SymVal b) => Symbolic (SEither a b) Source #

Declare a symbolic maybe, unnamed.

sEithers :: (SymVal a, SymVal b) => [String] -> Symbolic [SEither a b] Source #

Declare a list of symbolic maybes.

Destructing sums

either :: (SymVal a, SymVal b, SymVal c) => (SBV a -> SBV c) -> (SBV b -> SBV c) -> SEither a b -> SBV c Source #

Case analysis for symbolic Eithers. If the value isLeft, apply the first function; if it isRight, apply the second function.

>>> either (*2) (*3) (sLeft (3 :: SInteger))
6 :: SInteger
>>> either (*2) (*3) (sRight (3 :: SInteger))
9 :: SInteger
>>> let f = uninterpret "f" :: SInteger -> SInteger
>>> let g = uninterpret "g" :: SInteger -> SInteger
>>> prove $ \x -> either f g (sLeft x) .== f x
Q.E.D.
>>> prove $ \x -> either f g (sRight x) .== g x
Q.E.D.

Mapping functions

bimap :: (SymVal a, SymVal b, SymVal c, SymVal d) => (SBV a -> SBV b) -> (SBV c -> SBV d) -> SEither a c -> SEither b d Source #

Map over both sides of a symbolic Either at the same time

>>> let f = uninterpret "f" :: SInteger -> SInteger
>>> let g = uninterpret "g" :: SInteger -> SInteger
>>> prove $ \x -> fromLeft (bimap f g (sLeft x)) .== f x
Q.E.D.
>>> prove $ \x -> fromRight (bimap f g (sRight x)) .== g x
Q.E.D.

first :: (SymVal a, SymVal b, SymVal c) => (SBV a -> SBV b) -> SEither a c -> SEither b c Source #

Map over the left side of an Either

>>> let f = uninterpret "f" :: SInteger -> SInteger
>>> prove $ \x -> first f (sLeft x :: SEither Integer Integer) .== sLeft (f x)
Q.E.D.
>>> prove $ \x -> first f (sRight x :: SEither Integer Integer) .== sRight x
Q.E.D.

second :: (SymVal a, SymVal b, SymVal c) => (SBV b -> SBV c) -> SEither a b -> SEither a c Source #

Map over the right side of an Either

>>> let f = uninterpret "f" :: SInteger -> SInteger
>>> prove $ \x -> second f (sRight x :: SEither Integer Integer) .== sRight (f x)
Q.E.D.
>>> prove $ \x -> second f (sLeft x :: SEither Integer Integer) .== sLeft x
Q.E.D.

Scrutinizing branches of a sum

isLeft :: (SymVal a, SymVal b) => SBV (Either a b) -> SBool Source #

Field recognizer predicate.

isRight :: (SymVal a, SymVal b) => SBV (Either a b) -> SBool Source #

Field recognizer predicate.

fromLeft :: (SymVal a, SymVal b) => SEither a b -> SBV a Source #

Return the value from the left component. The behavior is undefined if passed a right value, i.e., it can return any value.

>>> fromLeft (sLeft (literal 'a') :: SEither Char Integer)
'a' :: SChar
>>> prove $ \x -> fromLeft (sLeft x :: SEither Char Integer) .== (x :: SChar)
Q.E.D.
>>> sat $ \x -> x .== (fromLeft (sRight 4 :: SEither Char Integer))
Satisfiable. Model:
  s0 = 'A' :: Char

Note how we get a satisfying assignment in the last case: The behavior is unspecified, thus the SMT solver picks whatever satisfies the constraints, if there is one.

fromRight :: (SymVal a, SymVal b) => SEither a b -> SBV b Source #

Return the value from the right component. The behavior is undefined if passed a left value, i.e., it can return any value.

>>> fromRight (sRight (literal 'a') :: SEither Integer Char)
'a' :: SChar
>>> prove $ \x -> fromRight (sRight x :: SEither Char Integer) .== (x :: SInteger)
Q.E.D.
>>> sat $ \x -> x .== (fromRight (sLeft (literal 2) :: SEither Integer Char))
Satisfiable. Model:
  s0 = 'A' :: Char

Note how we get a satisfying assignment in the last case: The behavior is unspecified, thus the SMT solver picks whatever satisfies the constraints, if there is one.

Orphan instances

(OrdSymbolic (SBV a), OrdSymbolic (SBV b), SymVal a, SymVal b) => OrdSymbolic (SBV (Either a b)) Source #

Custom OrdSymbolic instance over SEither.

Instance details

Methods

(.<) :: SBV (Either a b) -> SBV (Either a b) -> SBool Source #

(.<=) :: SBV (Either a b) -> SBV (Either a b) -> SBool Source #

(.>) :: SBV (Either a b) -> SBV (Either a b) -> SBool Source #

(.>=) :: SBV (Either a b) -> SBV (Either a b) -> SBool Source #

smin :: SBV (Either a b) -> SBV (Either a b) -> SBV (Either a b) Source #

smax :: SBV (Either a b) -> SBV (Either a b) -> SBV (Either a b) Source #

inRange :: SBV (Either a b) -> (SBV (Either a b), SBV (Either a b)) -> SBool Source #

(SymVal a, SymVal b) => SymVal (Either a b) Source # 
Instance details

(HasKind a, HasKind b) => HasKind (Either a b) Source # 
Instance details

(SymVal a, SymVal b) => HasInductionSchema (Forall ta (Either a b) -> SBool) Source # 
Instance details

Methods

inductionSchema :: (Forall ta (Either a b) -> SBool) -> ProofObj Source #

(SymVal a, SymVal b, SymVal extraT) => HasInductionSchema (Forall ta (Either a b) -> Forall extraS extraT -> SBool) Source # 
Instance details

Methods

inductionSchema :: (Forall ta (Either a b) -> Forall extraS extraT -> SBool) -> ProofObj Source #

(SymVal a, SymVal b, SymVal extraT1, SymVal extraT2) => HasInductionSchema (Forall ta (Either a b) -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> SBool) Source # 
Instance details

Methods

inductionSchema :: (Forall ta (Either a b) -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> SBool) -> ProofObj Source #

(SymVal a, SymVal b, SymVal extraT1, SymVal extraT2, SymVal extraT3) => HasInductionSchema (Forall ta (Either a b) -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> Forall extraS3 extraT3 -> SBool) Source # 
Instance details

Methods

inductionSchema :: (Forall ta (Either a b) -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> Forall extraS3 extraT3 -> SBool) -> ProofObj Source #

(SymVal a, SymVal b, SymVal extraT1, SymVal extraT2, SymVal extraT3, SymVal extraT4) => HasInductionSchema (Forall ta (Either a b) -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> Forall extraS3 extraT3 -> Forall extraS4 extraT4 -> SBool) Source # 
Instance details

Methods

inductionSchema :: (Forall ta (Either a b) -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> Forall extraS3 extraT3 -> Forall extraS4 extraT4 -> SBool) -> ProofObj Source #

(SymVal a, SymVal b, SymVal extraT1, SymVal extraT2, SymVal extraT3, SymVal extraT4, SymVal extraT5) => HasInductionSchema (Forall ta (Either a b) -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> Forall extraS3 extraT3 -> Forall extraS4 extraT4 -> Forall extraS5 extraT5 -> SBool) Source # 
Instance details

Methods

inductionSchema :: (Forall ta (Either a b) -> Forall extraS1 extraT1 -> Forall extraS2 extraT2 -> Forall extraS3 extraT3 -> Forall extraS4 extraT4 -> Forall extraS5 extraT5 -> SBool) -> ProofObj Source #