-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | SMT Based Verification: Symbolic Haskell theorem prover using SMT solving.
--   
--   Express properties about Haskell programs and automatically prove them
--   using SMT (Satisfiability Modulo Theories) solvers.
--   
--   For details, please see: <a>http://leventerkok.github.io/sbv/</a>
@package sbv
@version 10.2


-- | A collection of arbitrary float operations.
module Data.SBV.Float

-- | Internal representation of a parameterized float.
--   
--   A note on cardinality: If we have eb exponent bits, and sb significand
--   bits, then the total number of floats is 2^sb*(2^eb-1) + 3: All
--   exponents except 11..11 is allowed. So we get, 2^eb-1, different
--   combinations, each with a sign, giving us 2^sb*(2^eb-1) totals. Then
--   we have two infinities, and one NaN, adding 3 more.
data FP
FP :: Int -> Int -> BigFloat -> FP
[fpExponentSize] :: FP -> Int
[fpSignificandSize] :: FP -> Int
[fpValue] :: FP -> BigFloat

-- | Convert from an sign<i>exponent</i>mantissa representation to a float.
--   The values are the integers representing the bit-patterns of these
--   values, i.e., the raw representation. We assume that these integers
--   fit into the ranges given, i.e., no overflow checking is done here.
fpFromRawRep :: Bool -> (Integer, Int) -> (Integer, Int) -> FP

-- | Construct a float, by appropriately rounding
fpFromBigFloat :: Int -> Int -> BigFloat -> FP

-- | Make NaN. Exponent is all 1s. Significand is non-zero. The sign is
--   irrelevant.
fpNaN :: Int -> Int -> FP

-- | Make Infinity. Exponent is all 1s. Significand is 0.
fpInf :: Bool -> Int -> Int -> FP

-- | Make a signed zero.
fpZero :: Bool -> Int -> Int -> FP

-- | Make from an integer value.
fpFromInteger :: Int -> Int -> Integer -> FP

-- | Make a generalized floating-point value from a <a>Rational</a>.
fpFromRational :: Int -> Int -> Rational -> FP

-- | Convert from a IEEE float.
fpFromFloat :: Int -> Int -> Float -> FP

-- | Convert from a IEEE double.
fpFromDouble :: Int -> Int -> Double -> FP

-- | Encode from exponent/mantissa form to a float representation.
--   Corresponds to <a>encodeFloat</a> in Haskell.
fpEncodeFloat :: Int -> Int -> Integer -> Int -> FP


-- | More generalized alternative to <tt>Data.SBV.Control</tt> for advanced
--   client use
module Data.SBV.Trans.Control

-- | Monads which support <a>IO</a> operations and can extract all
--   <a>IO</a> behavior for interoperation with functions like
--   <a>catches</a>, which takes an <a>IO</a> action in negative position.
--   This function can not be implemented for transformers like <tt>ReaderT
--   r</tt> or <tt>StateT s</tt>, whose resultant <a>IO</a> actions are a
--   function of some environment or state.
class MonadIO m => ExtractIO m

-- | Law: the <tt>m a</tt> yielded by <a>IO</a> is pure with respect to
--   <a>IO</a>.
extractIO :: ExtractIO m => m a -> IO (m a)

-- | Computations which support query operations.
class Monad m => MonadQuery m
queryState :: MonadQuery m => m State
queryState :: (MonadQuery m, MonadTrans t, MonadQuery m', m ~ t m') => m State

-- | A query is a user-guided mechanism to directly communicate and extract
--   results from the solver. A generalization of <a>Query</a>.
data QueryT m a

-- | A query is a user-guided mechanism to directly communicate and extract
--   results from the solver.
type Query = QueryT IO

-- | Run a custom query.
query :: ExtractIO m => QueryT m a -> SymbolicT m a

-- | Generalization of <a>freshVar_</a>
freshVar_ :: forall a m. (MonadIO m, MonadQuery m, SymVal a) => m (SBV a)

-- | Generalization of <a>freshVar</a>
freshVar :: forall a m. (MonadIO m, MonadQuery m, SymVal a) => String -> m (SBV a)

-- | Generalization of <a>freshArray_</a>
freshArray_ :: (MonadIO m, MonadQuery m, SymArray array, HasKind a, HasKind b) => Maybe (SBV b) -> m (array a b)

-- | Generalization of <a>freshArray</a>
freshArray :: (MonadIO m, MonadQuery m, SymArray array, HasKind a, HasKind b) => String -> Maybe (SBV b) -> m (array a b)

-- | Generalization of <a>freshLambdaArray_</a>
freshLambdaArray_ :: (MonadIO m, MonadQuery m, SymArray array, HasKind a, HasKind b, Lambda (SymbolicT IO) (a -> b)) => (a -> b) -> m (array a b)

-- | Generalization of <a>freshLambdaArray</a>
freshLambdaArray :: (MonadIO m, MonadQuery m, SymArray array, HasKind a, HasKind b, Lambda (SymbolicT IO) (a -> b)) => String -> (a -> b) -> m (array a b)

-- | Result of a <a>checkSat</a> or <a>checkSatAssuming</a> call.
data CheckSatResult

-- | Satisfiable: A model is available, which can be queried with
--   <a>getValue</a>.
Sat :: CheckSatResult

-- | Delta-satisfiable: A delta-sat model is available. String is the
--   precision info, if available.
DSat :: Maybe String -> CheckSatResult

-- | Unsatisfiable: No model is available. Unsat cores might be obtained
--   via <a>getUnsatCore</a>.
Unsat :: CheckSatResult

-- | Unknown: Use <a>getUnknownReason</a> to obtain an explanation why this
--   might be the case.
Unk :: CheckSatResult

-- | Generalization of <a>checkSat</a>
checkSat :: (MonadIO m, MonadQuery m) => m CheckSatResult

-- | Generalization of <a>ensureSat</a>
ensureSat :: (MonadIO m, MonadQuery m) => m ()

-- | Generalization of <a>checkSatUsing</a>
checkSatUsing :: (MonadIO m, MonadQuery m) => String -> m CheckSatResult

-- | Generalization of <a>checkSatAssuming</a>
checkSatAssuming :: (MonadIO m, MonadQuery m) => [SBool] -> m CheckSatResult

-- | Generalization of <a>checkSatAssumingWithUnsatisfiableSet</a>
checkSatAssumingWithUnsatisfiableSet :: (MonadIO m, MonadQuery m) => [SBool] -> m (CheckSatResult, Maybe [SBool])

-- | Generalization of <a>getValue</a>
getValue :: (MonadIO m, MonadQuery m, SymVal a) => SBV a -> m a

-- | Generalization of <a>getFunction</a>
getFunction :: (MonadIO m, MonadQuery m, SolverContext m, MonadSymbolic m, SymVal a, SymVal r, SMTFunction fun a r) => fun -> m (Either String ([(a, r)], r))

-- | Generalization of <a>getUninterpretedValue</a>
getUninterpretedValue :: (MonadIO m, MonadQuery m, HasKind a) => SBV a -> m String

-- | Generalization of <a>getModel</a>
getModel :: (MonadIO m, MonadQuery m) => m SMTModel

-- | Generalization of <a>getAssignment</a>
getAssignment :: (MonadIO m, MonadQuery m) => m [(String, Bool)]

-- | Generalization of <a>getSMTResult</a>
getSMTResult :: (MonadIO m, MonadQuery m) => m SMTResult

-- | Generalization of <a>getUnknownReason</a>
getUnknownReason :: (MonadIO m, MonadQuery m) => m SMTReasonUnknown

-- | Get observables, i.e., those explicitly labeled by the user with a
--   call to <a>observe</a>.
getObservables :: (MonadIO m, MonadQuery m) => m [(Name, CV)]

-- | Generalization of <a>getUnsatCore</a>
getUnsatCore :: (MonadIO m, MonadQuery m) => m [String]

-- | Generalization of <a>getProof</a>
getProof :: (MonadIO m, MonadQuery m) => m String

-- | Generalization of <a>getInterpolantMathSAT</a>. Use this version with
--   MathSAT.
getInterpolantMathSAT :: (MonadIO m, MonadQuery m) => [String] -> m String

-- | Generalization of <a>getInterpolantZ3</a>. Use this version with Z3.
getInterpolantZ3 :: (MonadIO m, MonadQuery m) => [SBool] -> m String

-- | Generalization of <a>getAbduct</a>.
getAbduct :: (SolverContext m, MonadIO m, MonadQuery m) => Maybe String -> String -> SBool -> m String

-- | Generalization of <a>getAbductNext</a>.
getAbductNext :: (MonadIO m, MonadQuery m) => m String

-- | Generalization of <a>getAssertions</a>
getAssertions :: (MonadIO m, MonadQuery m) => m [String]

-- | Collectable information from the solver.
data SMTInfoFlag
AllStatistics :: SMTInfoFlag
AssertionStackLevels :: SMTInfoFlag
Authors :: SMTInfoFlag
ErrorBehavior :: SMTInfoFlag
Name :: SMTInfoFlag
ReasonUnknown :: SMTInfoFlag
Version :: SMTInfoFlag
InfoKeyword :: String -> SMTInfoFlag

-- | Behavior of the solver for errors.
data SMTErrorBehavior
ErrorImmediateExit :: SMTErrorBehavior
ErrorContinuedExecution :: SMTErrorBehavior

-- | Collectable information from the solver.
data SMTInfoResponse
Resp_Unsupported :: SMTInfoResponse
Resp_AllStatistics :: [(String, String)] -> SMTInfoResponse
Resp_AssertionStackLevels :: Integer -> SMTInfoResponse
Resp_Authors :: [String] -> SMTInfoResponse
Resp_Error :: SMTErrorBehavior -> SMTInfoResponse
Resp_Name :: String -> SMTInfoResponse
Resp_ReasonUnknown :: SMTReasonUnknown -> SMTInfoResponse
Resp_Version :: String -> SMTInfoResponse
Resp_InfoKeyword :: String -> [String] -> SMTInfoResponse

-- | Generalization of <a>getInfo</a>
getInfo :: (MonadIO m, MonadQuery m) => SMTInfoFlag -> m SMTInfoResponse

-- | Generalization of <a>getInfo</a>
getOption :: (MonadIO m, MonadQuery m) => (a -> SMTOption) -> m (Maybe SMTOption)

-- | Generalization of <a>getAssertionStackDepth</a>
getAssertionStackDepth :: (MonadIO m, MonadQuery m) => m Int

-- | Generalization of <a>push</a>
push :: (MonadIO m, MonadQuery m) => Int -> m ()

-- | Generalization of <a>pop</a>
pop :: (MonadIO m, MonadQuery m) => Int -> m ()

-- | Generalization of <a>inNewAssertionStack</a>
inNewAssertionStack :: (MonadIO m, MonadQuery m) => m a -> m a

-- | Generalization of <a>caseSplit</a>
caseSplit :: (MonadIO m, MonadQuery m) => Bool -> [(String, SBool)] -> m (Maybe (String, SMTResult))

-- | Generalization of <a>resetAssertions</a>
resetAssertions :: (MonadIO m, MonadQuery m) => m ()

-- | Make an assignment. The type <a>Assignment</a> is abstract, the result
--   is typically passed to <a>mkSMTResult</a>:
--   
--   <pre>
--   mkSMTResult [ a |-&gt; 332
--               , b |-&gt; 2.3
--               , c |-&gt; True
--               ]
--   </pre>
--   
--   End users should use <a>getModel</a> for automatically constructing
--   models from the current solver state. However, an explicit
--   <a>Assignment</a> might be handy in complex scenarios where a model
--   needs to be created manually.
(|->) :: SymVal a => SBV a -> a -> Assignment
infix 1 |->

-- | Generalization of <a>mkSMTResult</a> NB. This function does not allow
--   users to create interpretations for UI-Funs. But that's probably not a
--   good idea anyhow. Also, if you use the <a>validateModel</a> or
--   <a>optimizeValidateConstraints</a> features, SBV will fail on models
--   returned via this function.
mkSMTResult :: (MonadIO m, MonadQuery m) => [Assignment] -> m SMTResult

-- | Generalization of <a>exit</a>
exit :: (MonadIO m, MonadQuery m) => m ()

-- | If true, we shall ignore the exit code upon exit. Otherwise we require
--   ExitSuccess.
ignoreExitCode :: SMTConfig -> Bool

-- | Generalization of <a>timeout</a>
timeout :: (MonadIO m, MonadQuery m) => Int -> m a -> m a

-- | Generalization of <a>queryDebug</a>
queryDebug :: (MonadIO m, MonadQuery m) => [String] -> m ()

-- | Generalization of <a>echo</a>
echo :: (MonadIO m, MonadQuery m) => String -> m ()

-- | Generalization of <a>io</a>
io :: MonadIO m => IO a -> m a

-- | Option values that can be set in the solver, following the SMTLib
--   specification <a>http://smtlib.cs.uiowa.edu/language.shtml</a>.
--   
--   Note that not all solvers may support all of these!
--   
--   Furthermore, SBV doesn't support the following options allowed by
--   SMTLib.
--   
--   <ul>
--   <li><tt>:interactive-mode</tt> (Deprecated in SMTLib, use
--   <a>ProduceAssertions</a> instead.)</li>
--   <li><tt>:print-success</tt> (SBV critically needs this to be True in
--   query mode.)</li>
--   <li><tt>:produce-models</tt> (SBV always sets this option so it can
--   extract models.)</li>
--   <li><tt>:regular-output-channel</tt> (SBV always requires regular
--   output to come on stdout for query purposes.)</li>
--   <li><tt>:global-declarations</tt> (SBV always uses global declarations
--   since definitions are accumulative.)</li>
--   </ul>
--   
--   Note that <a>SetLogic</a> and <a>SetInfo</a> are, strictly speaking,
--   not SMTLib options. However, we treat it as such here uniformly, as it
--   fits better with how options work.
data SMTOption
DiagnosticOutputChannel :: FilePath -> SMTOption
ProduceAssertions :: Bool -> SMTOption
ProduceAssignments :: Bool -> SMTOption
ProduceProofs :: Bool -> SMTOption
ProduceInterpolants :: Bool -> SMTOption
ProduceUnsatAssumptions :: Bool -> SMTOption
ProduceUnsatCores :: Bool -> SMTOption
ProduceAbducts :: Bool -> SMTOption
RandomSeed :: Integer -> SMTOption
ReproducibleResourceLimit :: Integer -> SMTOption
SMTVerbosity :: Integer -> SMTOption
OptionKeyword :: String -> [String] -> SMTOption
SetLogic :: Logic -> SMTOption
SetInfo :: String -> [String] -> SMTOption


-- | Test generation from symbolic programs
module Data.SBV.Tools.GenTest

-- | Generate a set of concrete test values from a symbolic program. The
--   output can be rendered as test vectors in different languages as
--   necessary. Use the function <a>output</a> call to indicate what fields
--   should be in the test result. (Also see <a>constrain</a> for filtering
--   acceptable test values.)
genTest :: Outputtable a => Int -> Symbolic a -> IO TestVectors

-- | Type of test vectors (abstract)
data TestVectors

-- | Retrieve the test vectors for further processing. This function is
--   useful in cases where <a>renderTest</a> is not sufficient and custom
--   output (or further preprocessing) is needed.
getTestValues :: TestVectors -> [([CV], [CV])]

-- | Render the test as a Haskell value with the given name <tt>n</tt>.
renderTest :: TestStyle -> TestVectors -> String

-- | Test output style
data TestStyle

-- | As a Haskell value with given name
Haskell :: String -> TestStyle

-- | As a C array of structs with given name
C :: String -> TestStyle

-- | As a Forte/Verilog value with given name. If the boolean is True then
--   vectors are blasted big-endian, otherwise little-endian The indices
--   are the split points on bit-vectors for input and output values
Forte :: String -> Bool -> ([Int], [Int]) -> TestStyle


-- | Accessing symbolic tuple fields and deconstruction.
module Data.SBV.Tuple

-- | Field access, inspired by the lens library. This is merely reverse
--   application, but allows us to write things like <tt>(1, 2)^._1</tt>
--   which is likely to be familiar to most Haskell programmers out there.
--   Note that this is precisely equivalent to <tt>_1 (1, 2)</tt>, but
--   perhaps it reads a little nicer.
(^.) :: a -> (a -> b) -> b
infixl 8 ^.

-- | Access the 1st element of an <tt>STupleN</tt>, <tt>2 &lt;= N &lt;=
--   8</tt>. Also see <a>^.</a>.
_1 :: HasField "_1" b a => SBV a -> SBV b

-- | Access the 2nd element of an <tt>STupleN</tt>, <tt>2 &lt;= N &lt;=
--   8</tt>. Also see <a>^.</a>.
_2 :: HasField "_2" b a => SBV a -> SBV b

-- | Access the 3rd element of an <tt>STupleN</tt>, <tt>3 &lt;= N &lt;=
--   8</tt>. Also see <a>^.</a>.
_3 :: HasField "_3" b a => SBV a -> SBV b

-- | Access the 4th element of an <tt>STupleN</tt>, <tt>4 &lt;= N &lt;=
--   8</tt>. Also see <a>^.</a>.
_4 :: HasField "_4" b a => SBV a -> SBV b

-- | Access the 5th element of an <tt>STupleN</tt>, <tt>5 &lt;= N &lt;=
--   8</tt>. Also see <a>^.</a>.
_5 :: HasField "_5" b a => SBV a -> SBV b

-- | Access the 6th element of an <tt>STupleN</tt>, <tt>6 &lt;= N &lt;=
--   8</tt>. Also see <a>^.</a>.
_6 :: HasField "_6" b a => SBV a -> SBV b

-- | Access the 7th element of an <tt>STupleN</tt>, <tt>7 &lt;= N &lt;=
--   8</tt>. Also see <a>^.</a>.
_7 :: HasField "_7" b a => SBV a -> SBV b

-- | Access the 8th element of an <tt>STupleN</tt>, <tt>8 &lt;= N &lt;=
--   8</tt>. Also see <a>^.</a>.
_8 :: HasField "_8" b a => SBV a -> SBV b

-- | Constructing a tuple from its parts. Forms an isomorphism pair with
--   <a>untuple</a>:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \p -&gt; untuple @(Integer, Bool, (String, Char)) (tuple p) .== p
--   Q.E.D.
--   </pre>
tuple :: Tuple tup a => a -> SBV tup

-- | Deconstruct a tuple, getting its constituent parts apart. Forms an
--   isomorphism pair with <a>tuple</a>:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \p -&gt; tuple @(Integer, Bool, (String, Char)) (untuple p) .== p
--   Q.E.D.
--   </pre>
untuple :: Tuple tup a => SBV tup -> a

-- | Swap the elements of a 2-tuple
swap :: (SymVal a, SymVal b) => STuple a b -> STuple b a
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Data.SymVal b) => Data.SBV.Tuple.Tuple (a, b) (Data.SBV.Core.Data.SBV a, Data.SBV.Core.Data.SBV b)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Data.SymVal c) => Data.SBV.Tuple.Tuple (a, b, c) (Data.SBV.Core.Data.SBV a, Data.SBV.Core.Data.SBV b, Data.SBV.Core.Data.SBV c)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Data.SymVal c, Data.SBV.Core.Data.SymVal d) => Data.SBV.Tuple.Tuple (a, b, c, d) (Data.SBV.Core.Data.SBV a, Data.SBV.Core.Data.SBV b, Data.SBV.Core.Data.SBV c, Data.SBV.Core.Data.SBV d)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Data.SymVal c, Data.SBV.Core.Data.SymVal d, Data.SBV.Core.Data.SymVal e) => Data.SBV.Tuple.Tuple (a, b, c, d, e) (Data.SBV.Core.Data.SBV a, Data.SBV.Core.Data.SBV b, Data.SBV.Core.Data.SBV c, Data.SBV.Core.Data.SBV d, Data.SBV.Core.Data.SBV e)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Data.SymVal c, Data.SBV.Core.Data.SymVal d, Data.SBV.Core.Data.SymVal e, Data.SBV.Core.Data.SymVal f) => Data.SBV.Tuple.Tuple (a, b, c, d, e, f) (Data.SBV.Core.Data.SBV a, Data.SBV.Core.Data.SBV b, Data.SBV.Core.Data.SBV c, Data.SBV.Core.Data.SBV d, Data.SBV.Core.Data.SBV e, Data.SBV.Core.Data.SBV f)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Data.SymVal c, Data.SBV.Core.Data.SymVal d, Data.SBV.Core.Data.SymVal e, Data.SBV.Core.Data.SymVal f, Data.SBV.Core.Data.SymVal g) => Data.SBV.Tuple.Tuple (a, b, c, d, e, f, g) (Data.SBV.Core.Data.SBV a, Data.SBV.Core.Data.SBV b, Data.SBV.Core.Data.SBV c, Data.SBV.Core.Data.SBV d, Data.SBV.Core.Data.SBV e, Data.SBV.Core.Data.SBV f, Data.SBV.Core.Data.SBV g)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Data.SymVal c, Data.SBV.Core.Data.SymVal d, Data.SBV.Core.Data.SymVal e, Data.SBV.Core.Data.SymVal f, Data.SBV.Core.Data.SymVal g, Data.SBV.Core.Data.SymVal h) => Data.SBV.Tuple.Tuple (a, b, c, d, e, f, g, h) (Data.SBV.Core.Data.SBV a, Data.SBV.Core.Data.SBV b, Data.SBV.Core.Data.SBV c, Data.SBV.Core.Data.SBV d, Data.SBV.Core.Data.SBV e, Data.SBV.Core.Data.SBV f, Data.SBV.Core.Data.SBV g, Data.SBV.Core.Data.SBV h)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Data.SymVal a) => Data.SBV.Tuple.HasField "_1" a (a, b)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Data.SymVal a) => Data.SBV.Tuple.HasField "_1" a (a, b, c)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Data.SymVal a) => Data.SBV.Tuple.HasField "_1" a (a, b, c, d)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Data.SymVal a) => Data.SBV.Tuple.HasField "_1" a (a, b, c, d, e)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Data.SymVal a) => Data.SBV.Tuple.HasField "_1" a (a, b, c, d, e, f)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Data.SymVal a) => Data.SBV.Tuple.HasField "_1" a (a, b, c, d, e, f, g)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Kind.HasKind h, Data.SBV.Core.Data.SymVal a) => Data.SBV.Tuple.HasField "_1" a (a, b, c, d, e, f, g, h)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Data.SymVal b) => Data.SBV.Tuple.HasField "_2" b (a, b)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Data.SymVal b) => Data.SBV.Tuple.HasField "_2" b (a, b, c)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Data.SymVal b) => Data.SBV.Tuple.HasField "_2" b (a, b, c, d)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Data.SymVal b) => Data.SBV.Tuple.HasField "_2" b (a, b, c, d, e)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Data.SymVal b) => Data.SBV.Tuple.HasField "_2" b (a, b, c, d, e, f)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Data.SymVal b) => Data.SBV.Tuple.HasField "_2" b (a, b, c, d, e, f, g)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Kind.HasKind h, Data.SBV.Core.Data.SymVal b) => Data.SBV.Tuple.HasField "_2" b (a, b, c, d, e, f, g, h)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Data.SymVal c) => Data.SBV.Tuple.HasField "_3" c (a, b, c)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Data.SymVal c) => Data.SBV.Tuple.HasField "_3" c (a, b, c, d)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Data.SymVal c) => Data.SBV.Tuple.HasField "_3" c (a, b, c, d, e)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Data.SymVal c) => Data.SBV.Tuple.HasField "_3" c (a, b, c, d, e, f)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Data.SymVal c) => Data.SBV.Tuple.HasField "_3" c (a, b, c, d, e, f, g)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Kind.HasKind h, Data.SBV.Core.Data.SymVal c) => Data.SBV.Tuple.HasField "_3" c (a, b, c, d, e, f, g, h)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Data.SymVal d) => Data.SBV.Tuple.HasField "_4" d (a, b, c, d)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Data.SymVal d) => Data.SBV.Tuple.HasField "_4" d (a, b, c, d, e)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Data.SymVal d) => Data.SBV.Tuple.HasField "_4" d (a, b, c, d, e, f)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Data.SymVal d) => Data.SBV.Tuple.HasField "_4" d (a, b, c, d, e, f, g)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Kind.HasKind h, Data.SBV.Core.Data.SymVal d) => Data.SBV.Tuple.HasField "_4" d (a, b, c, d, e, f, g, h)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Data.SymVal e) => Data.SBV.Tuple.HasField "_5" e (a, b, c, d, e)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Data.SymVal e) => Data.SBV.Tuple.HasField "_5" e (a, b, c, d, e, f)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Data.SymVal e) => Data.SBV.Tuple.HasField "_5" e (a, b, c, d, e, f, g)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Kind.HasKind h, Data.SBV.Core.Data.SymVal e) => Data.SBV.Tuple.HasField "_5" e (a, b, c, d, e, f, g, h)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Data.SymVal f) => Data.SBV.Tuple.HasField "_6" f (a, b, c, d, e, f)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Data.SymVal f) => Data.SBV.Tuple.HasField "_6" f (a, b, c, d, e, f, g)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Kind.HasKind h, Data.SBV.Core.Data.SymVal f) => Data.SBV.Tuple.HasField "_6" f (a, b, c, d, e, f, g, h)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Data.SymVal g) => Data.SBV.Tuple.HasField "_7" g (a, b, c, d, e, f, g)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Kind.HasKind h, Data.SBV.Core.Data.SymVal g) => Data.SBV.Tuple.HasField "_7" g (a, b, c, d, e, f, g, h)
instance (Data.SBV.Core.Kind.HasKind a, Data.SBV.Core.Kind.HasKind b, Data.SBV.Core.Kind.HasKind c, Data.SBV.Core.Kind.HasKind d, Data.SBV.Core.Kind.HasKind e, Data.SBV.Core.Kind.HasKind f, Data.SBV.Core.Kind.HasKind g, Data.SBV.Core.Kind.HasKind h, Data.SBV.Core.Data.SymVal h) => Data.SBV.Tuple.HasField "_8" h (a, b, c, d, e, f, g, h)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Model.Metric a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Model.Metric b) => Data.SBV.Core.Model.Metric (a, b)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Model.Metric a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Model.Metric b, Data.SBV.Core.Data.SymVal c, Data.SBV.Core.Model.Metric c) => Data.SBV.Core.Model.Metric (a, b, c)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Model.Metric a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Model.Metric b, Data.SBV.Core.Data.SymVal c, Data.SBV.Core.Model.Metric c, Data.SBV.Core.Data.SymVal d, Data.SBV.Core.Model.Metric d) => Data.SBV.Core.Model.Metric (a, b, c, d)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Model.Metric a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Model.Metric b, Data.SBV.Core.Data.SymVal c, Data.SBV.Core.Model.Metric c, Data.SBV.Core.Data.SymVal d, Data.SBV.Core.Model.Metric d, Data.SBV.Core.Data.SymVal e, Data.SBV.Core.Model.Metric e) => Data.SBV.Core.Model.Metric (a, b, c, d, e)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Model.Metric a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Model.Metric b, Data.SBV.Core.Data.SymVal c, Data.SBV.Core.Model.Metric c, Data.SBV.Core.Data.SymVal d, Data.SBV.Core.Model.Metric d, Data.SBV.Core.Data.SymVal e, Data.SBV.Core.Model.Metric e, Data.SBV.Core.Data.SymVal f, Data.SBV.Core.Model.Metric f) => Data.SBV.Core.Model.Metric (a, b, c, d, e, f)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Model.Metric a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Model.Metric b, Data.SBV.Core.Data.SymVal c, Data.SBV.Core.Model.Metric c, Data.SBV.Core.Data.SymVal d, Data.SBV.Core.Model.Metric d, Data.SBV.Core.Data.SymVal e, Data.SBV.Core.Model.Metric e, Data.SBV.Core.Data.SymVal f, Data.SBV.Core.Model.Metric f, Data.SBV.Core.Data.SymVal g, Data.SBV.Core.Model.Metric g) => Data.SBV.Core.Model.Metric (a, b, c, d, e, f, g)
instance (Data.SBV.Core.Data.SymVal a, Data.SBV.Core.Model.Metric a, Data.SBV.Core.Data.SymVal b, Data.SBV.Core.Model.Metric b, Data.SBV.Core.Data.SymVal c, Data.SBV.Core.Model.Metric c, Data.SBV.Core.Data.SymVal d, Data.SBV.Core.Model.Metric d, Data.SBV.Core.Data.SymVal e, Data.SBV.Core.Model.Metric e, Data.SBV.Core.Data.SymVal f, Data.SBV.Core.Model.Metric f, Data.SBV.Core.Data.SymVal g, Data.SBV.Core.Model.Metric g, Data.SBV.Core.Data.SymVal h, Data.SBV.Core.Model.Metric h) => Data.SBV.Core.Model.Metric (a, b, c, d, e, f, g, h)


-- | Implementation of full-binary symbolic trees, providing logarithmic
--   time access to elements. Both reads and writes are supported.
module Data.SBV.Tools.STree

-- | A symbolic tree containing values of type e, indexed by elements of
--   type i. Note that these are full-trees, and their their shapes remain
--   constant. There is no API provided that can change the shape of the
--   tree. These structures are useful when dealing with data-structures
--   that are indexed with symbolic values where access time is important.
--   <a>STree</a> structures provide logarithmic time reads and writes.
type STree i e = STreeInternal (SBV i) (SBV e)

-- | Reading a value. We bit-blast the index and descend down the full tree
--   according to bit-values.
readSTree :: (SFiniteBits i, SymVal e) => STree i e -> SBV i -> SBV e

-- | Writing a value, similar to how reads are done. The important thing is
--   that the tree representation keeps updates to a minimum.
writeSTree :: (SFiniteBits i, SymVal e) => STree i e -> SBV i -> SBV e -> STree i e

-- | Construct the fully balanced initial tree using the given values.
mkSTree :: forall i e. HasKind i => [SBV e] -> STree i e
instance GHC.Show.Show e => GHC.Show.Show (Data.SBV.Tools.STree.STreeInternal i e)
instance Data.SBV.Core.Data.SymVal e => Data.SBV.Core.Model.Mergeable (Data.SBV.Tools.STree.STree i e)


-- | A collection of string/character utilities, useful when working with
--   symbolic strings. To the extent possible, the functions in this module
--   follow those of <a>Data.List</a> so importing qualified is the
--   recommended workflow. Also, it is recommended you use the
--   <tt>OverloadedStrings</tt> extension to allow literal strings to be
--   used as symbolic-strings.
module Data.SBV.String

-- | Length of a string.
--   
--   <pre>
--   &gt;&gt;&gt; sat $ \s -&gt; length s .== 2
--   Satisfiable. Model:
--     s0 = "BA" :: String
--   
--   &gt;&gt;&gt; sat $ \s -&gt; length s .&lt; 0
--   Unsatisfiable
--   
--   &gt;&gt;&gt; prove $ \s1 s2 -&gt; length s1 + length s2 .== length (s1 ++ s2)
--   Q.E.D.
--   </pre>
length :: SString -> SInteger

-- | <tt><a>null</a> s</tt> is True iff the string is empty
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s -&gt; null s .&lt;=&gt; length s .== 0
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \s -&gt; null s .&lt;=&gt; s .== ""
--   Q.E.D.
--   </pre>
null :: SString -> SBool

-- | <tt><a>head</a></tt> returns the head of a string. Unspecified if the
--   string is empty.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; head (singleton c) .== c
--   Q.E.D.
--   </pre>
head :: SString -> SChar

-- | <tt><a>tail</a></tt> returns the tail of a string. Unspecified if the
--   string is empty.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \h s -&gt; tail (singleton h ++ s) .== s
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \s -&gt; length s .&gt; 0 .=&gt; length (tail s) .== length s - 1
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \s -&gt; sNot (null s) .=&gt; singleton (head s) ++ tail s .== s
--   Q.E.D.
--   </pre>
tail :: SString -> SString

-- | @<a>uncons</a> returns the pair of the first character and tail.
--   Unspecified if the string is empty.
uncons :: SString -> (SChar, SString)

-- | <tt><a>init</a></tt> returns all but the last element of the list.
--   Unspecified if the string is empty.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c t -&gt; init (t ++ singleton c) .== t
--   Q.E.D.
--   </pre>
init :: SString -> SString

-- | <tt><a>singleton</a> c</tt> is the string of length 1 that contains
--   the only character whose value is the 8-bit value <tt>c</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; c .== literal 'A' .=&gt; singleton c .== "A"
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; length (singleton c) .== 1
--   Q.E.D.
--   </pre>
singleton :: SChar -> SString

-- | <tt><a>strToStrAt</a> s offset</tt>. Substring of length 1 at
--   <tt>offset</tt> in <tt>s</tt>. Unspecified if offset is out of bounds.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s1 s2 -&gt; strToStrAt (s1 ++ s2) (length s1) .== strToStrAt s2 0
--   Q.E.D.
--   
--   &gt;&gt;&gt; sat $ \s -&gt; length s .&gt;= 2 .&amp;&amp; strToStrAt s 0 ./= strToStrAt s (length s - 1)
--   Satisfiable. Model:
--     s0 = "AB" :: String
--   </pre>
strToStrAt :: SString -> SInteger -> SString

-- | <tt><a>strToCharAt</a> s i</tt> is the 8-bit value stored at location
--   <tt>i</tt>. Unspecified if index is out of bounds.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \i -&gt; i .&gt;= 0 .&amp;&amp; i .&lt;= 4 .=&gt; "AAAAA" `strToCharAt` i .== literal 'A'
--   Q.E.D.
--   </pre>
--   
--   <ul>
--   <li>&gt;&gt;&gt; prove $ s i c -&gt; i <a>inRange</a> (0, length s -
--   1) .&amp;&amp; s <a>strToCharAt</a> i .== c .=&gt; indexOf s
--   (singleton c) .&lt;= i Q.E.D.</li>
--   </ul>
strToCharAt :: SString -> SInteger -> SChar

-- | Short cut for <a>strToCharAt</a>
(!!) :: SString -> SInteger -> SChar

-- | <tt><a>implode</a> cs</tt> is the string of length <tt>|cs|</tt>
--   containing precisely those characters. Note that there is no
--   corresponding function <tt>explode</tt>, since we wouldn't know the
--   length of a symbolic string.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c1 c2 c3 -&gt; length (implode [c1, c2, c3]) .== 3
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c1 c2 c3 -&gt; map (strToCharAt (implode [c1, c2, c3])) (map literal [0 .. 2]) .== [c1, c2, c3]
--   Q.E.D.
--   </pre>
implode :: [SChar] -> SString

-- | Concatenate two strings. See also <a>++</a>.
concat :: SString -> SString -> SString

-- | Prepend an element, the traditional <tt>cons</tt>.
(.:) :: SChar -> SString -> SString
infixr 5 .:

-- | Append an element
snoc :: SString -> SChar -> SString

-- | Empty string. This value has the property that it's the only string
--   with length 0:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \l -&gt; length l .== 0 .&lt;=&gt; l .== nil
--   Q.E.D.
--   </pre>
nil :: SString

-- | Short cut for <a>concat</a>.
--   
--   <pre>
--   &gt;&gt;&gt; sat $ \x y z -&gt; length x .== 5 .&amp;&amp; length y .== 1 .&amp;&amp; x ++ y ++ z .== "Hello world!"
--   Satisfiable. Model:
--     s0 =  "Hello" :: String
--     s1 =      " " :: String
--     s2 = "world!" :: String
--   </pre>
(++) :: SString -> SString -> SString
infixr 5 ++

-- | <tt><a>isInfixOf</a> sub s</tt>. Does <tt>s</tt> contain the substring
--   <tt>sub</tt>?
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s1 s2 s3 -&gt; s2 `isInfixOf` (s1 ++ s2 ++ s3)
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \s1 s2 -&gt; s1 `isInfixOf` s2 .&amp;&amp; s2 `isInfixOf` s1 .&lt;=&gt; s1 .== s2
--   Q.E.D.
--   </pre>
isInfixOf :: SString -> SString -> SBool

-- | <tt><a>isSuffixOf</a> suf s</tt>. Is <tt>suf</tt> a suffix of
--   <tt>s</tt>?
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s1 s2 -&gt; s2 `isSuffixOf` (s1 ++ s2)
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \s1 s2 -&gt; s1 `isSuffixOf` s2 .=&gt; subStr s2 (length s2 - length s1) (length s1) .== s1
--   Q.E.D.
--   </pre>
isSuffixOf :: SString -> SString -> SBool

-- | <tt><a>isPrefixOf</a> pre s</tt>. Is <tt>pre</tt> a prefix of
--   <tt>s</tt>?
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s1 s2 -&gt; s1 `isPrefixOf` (s1 ++ s2)
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \s1 s2 -&gt; s1 `isPrefixOf` s2 .=&gt; subStr s2 0 (length s1) .== s1
--   Q.E.D.
--   </pre>
isPrefixOf :: SString -> SString -> SBool

-- | <tt><a>take</a> len s</tt>. Corresponds to Haskell's <a>take</a> on
--   symbolic-strings.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s i -&gt; i .&gt;= 0 .=&gt; length (take i s) .&lt;= i
--   Q.E.D.
--   </pre>
take :: SInteger -> SString -> SString

-- | <tt><a>drop</a> len s</tt>. Corresponds to Haskell's <a>drop</a> on
--   symbolic-strings.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s i -&gt; length (drop i s) .&lt;= length s
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \s i -&gt; take i s ++ drop i s .== s
--   Q.E.D.
--   </pre>
drop :: SInteger -> SString -> SString

-- | <tt><a>subStr</a> s offset len</tt> is the substring of <tt>s</tt> at
--   offset <tt>offset</tt> with length <tt>len</tt>. This function is
--   under-specified when the offset is outside the range of positions in
--   <tt>s</tt> or <tt>len</tt> is negative or <tt>offset+len</tt> exceeds
--   the length of <tt>s</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s i -&gt; i .&gt;= 0 .&amp;&amp; i .&lt; length s .=&gt; subStr s 0 i ++ subStr s i (length s - i) .== s
--   Q.E.D.
--   
--   &gt;&gt;&gt; sat  $ \i j -&gt; subStr "hello" i j .== "ell"
--   Satisfiable. Model:
--     s0 = 1 :: Integer
--     s1 = 3 :: Integer
--   
--   &gt;&gt;&gt; sat  $ \i j -&gt; subStr "hell" i j .== "no"
--   Unsatisfiable
--   </pre>
subStr :: SString -> SInteger -> SInteger -> SString

-- | <tt><a>replace</a> s src dst</tt>. Replace the first occurrence of
--   <tt>src</tt> by <tt>dst</tt> in <tt>s</tt>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s -&gt; replace "hello" s "world" .== "world" .=&gt; s .== "hello"
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \s1 s2 s3 -&gt; length s2 .&gt; length s1 .=&gt; replace s1 s2 s3 .== s1
--   Q.E.D.
--   </pre>
replace :: SString -> SString -> SString -> SString

-- | <tt><a>indexOf</a> s sub</tt>. Retrieves first position of
--   <tt>sub</tt> in <tt>s</tt>, <tt>-1</tt> if there are no occurrences.
--   Equivalent to <tt><a>offsetIndexOf</a> s sub 0</tt>.
--   
--   <ul>
--   <li>&gt;&gt;&gt; prove $ s i -&gt; i .&gt; 0 .&amp;&amp; i .<a>s
--   .=</a> indexOf s (subStr s i 1) .&lt;= i Q.E.D.</li>
--   </ul>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s1 s2 -&gt; length s2 .&gt; length s1 .=&gt; indexOf s1 s2 .== -1
--   Q.E.D.
--   </pre>
indexOf :: SString -> SString -> SInteger

-- | <tt><a>offsetIndexOf</a> s sub offset</tt>. Retrieves first position
--   of <tt>sub</tt> at or after <tt>offset</tt> in <tt>s</tt>, <tt>-1</tt>
--   if there are no occurrences.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s sub -&gt; offsetIndexOf s sub 0 .== indexOf s sub
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \s sub i -&gt; i .&gt;= length s .&amp;&amp; length sub .&gt; 0 .=&gt; offsetIndexOf s sub i .== -1
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \s sub i -&gt; i .&gt; length s .=&gt; offsetIndexOf s sub i .== -1
--   Q.E.D.
--   </pre>
offsetIndexOf :: SString -> SString -> SInteger -> SInteger

-- | <tt><a>reverse</a> s</tt> reverses the string. &gt;&gt;&gt; sat $ s
--   -&gt; reverse s .== "abc" Satisfiable. Model: s0 = "cba" :: String
--   &gt;&gt;&gt; prove $ s -&gt; reverse s .== "" .<a>=</a> null s Q.E.D.
reverse :: SString -> SString

-- | <tt><a>strToNat</a> s</tt>. Retrieve integer encoded by string
--   <tt>s</tt> (ground rewriting only). Note that by definition this
--   function only works when <tt>s</tt> only contains digits, that is, if
--   it encodes a natural number. Otherwise, it returns '-1'.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s -&gt; let n = strToNat s in length s .== 1 .=&gt; (-1) .&lt;= n .&amp;&amp; n .&lt;= 9
--   Q.E.D.
--   </pre>
strToNat :: SString -> SInteger

-- | <tt><a>natToStr</a> i</tt>. Retrieve string encoded by integer
--   <tt>i</tt> (ground rewriting only). Again, only naturals are
--   supported, any input that is not a natural number produces empty
--   string, even though we take an integer as an argument.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \i -&gt; length (natToStr i) .== 3 .=&gt; i .&lt;= 999
--   Q.E.D.
--   </pre>
natToStr :: SInteger -> SString


-- | A collection of set utilities, useful when working with symbolic sets.
--   To the extent possible, the functions in this module follow those of
--   <a>Data.Set</a> so importing qualified is the recommended workflow.
--   
--   Note that unlike <a>Data.Set</a>, SBV sets can be infinite,
--   represented as a complement of some finite set. This means that a
--   symbolic set is either finite, or its complement is finite. (If the
--   underlying domain is finite, then obviously both the set itself and
--   its complement will always be finite.) Therefore, there are some
--   differences in the API from Haskell sets. For instance, you can take
--   the complement of any set, which is something you cannot do in
--   Haskell! Conversely, you cannot compute the size of a symbolic set (as
--   it can be infinite!), nor you can turn it into a list or necessarily
--   enumerate its elements.
--   
--   <b>A note on cardinality</b>: You can indirectly talk about
--   cardinality: <a>hasSize</a> can be used to state that the set is
--   finite and has size <tt>k</tt> for a user-specified symbolic integer
--   <tt>k</tt>.
module Data.SBV.Set

-- | Empty set.
--   
--   <pre>
--   &gt;&gt;&gt; empty :: SSet Integer
--   {} :: {SInteger}
--   </pre>
empty :: forall a. HasKind a => SSet a

-- | Full set.
--   
--   <pre>
--   &gt;&gt;&gt; full :: SSet Integer
--   U :: {SInteger}
--   </pre>
--   
--   Note that the universal set over a type is represented by the letter
--   <tt>U</tt>.
full :: forall a. HasKind a => SSet a

-- | Synonym for <a>full</a>.
universal :: forall a. HasKind a => SSet a

-- | Singleton list.
--   
--   <pre>
--   &gt;&gt;&gt; singleton 2 :: SSet Integer
--   {2} :: {SInteger}
--   </pre>
singleton :: forall a. (Ord a, SymVal a) => SBV a -> SSet a

-- | Conversion from a list.
--   
--   <pre>
--   &gt;&gt;&gt; fromList ([] :: [Integer])
--   {} :: {SInteger}
--   
--   &gt;&gt;&gt; fromList [1,2,3]
--   {1,2,3} :: {SInteger}
--   
--   &gt;&gt;&gt; fromList [5,5,5,12,12,3]
--   {3,5,12} :: {SInteger}
--   </pre>
fromList :: forall a. (Ord a, SymVal a) => [a] -> SSet a

-- | Complement.
--   
--   <pre>
--   &gt;&gt;&gt; empty .== complement (full :: SSet Integer)
--   True
--   </pre>
--   
--   Complementing twice gets us back the original set:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(s :: SSet Integer) -&gt; complement (complement s) .== s
--   Q.E.D.
--   </pre>
complement :: forall a. (Ord a, SymVal a) => SSet a -> SSet a

-- | Insert an element into a set.
--   
--   Insertion is order independent:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x y (s :: SSet Integer) -&gt; x `insert` (y `insert` s) .== y `insert` (x `insert` s)
--   Q.E.D.
--   </pre>
--   
--   Deletion after insertion is not necessarily identity:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x (s :: SSet Integer) -&gt; x `delete` (x `insert` s) .== s
--   Falsifiable. Counter-example:
--     s0 = 2 :: Integer
--     s1 = U :: {Integer}
--   </pre>
--   
--   But the above is true if the element isn't in the set to start with:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x (s :: SSet Integer) -&gt; x `notMember` s .=&gt; x `delete` (x `insert` s) .== s
--   Q.E.D.
--   </pre>
--   
--   Insertion into a full set does nothing:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; insert x full .== (full :: SSet Integer)
--   Q.E.D.
--   </pre>
insert :: forall a. (Ord a, SymVal a) => SBV a -> SSet a -> SSet a

-- | Delete an element from a set.
--   
--   Deletion is order independent:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x y (s :: SSet Integer) -&gt; x `delete` (y `delete` s) .== y `delete` (x `delete` s)
--   Q.E.D.
--   </pre>
--   
--   Insertion after deletion is not necessarily identity:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x (s :: SSet Integer) -&gt; x `insert` (x `delete` s) .== s
--   Falsifiable. Counter-example:
--     s0 =       2 :: Integer
--     s1 = U - {2} :: {Integer}
--   </pre>
--   
--   But the above is true if the element is in the set to start with:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x (s :: SSet Integer) -&gt; x `member` s .=&gt; x `insert` (x `delete` s) .== s
--   Q.E.D.
--   </pre>
--   
--   Deletion from an empty set does nothing:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; delete x empty .== (empty :: SSet Integer)
--   Q.E.D.
--   </pre>
delete :: forall a. (Ord a, SymVal a) => SBV a -> SSet a -> SSet a

-- | Test for membership.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; x `member` singleton (x :: SInteger)
--   Q.E.D.
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x (s :: SSet Integer) -&gt; x `member` (x `insert` s)
--   Q.E.D.
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; x `member` (full :: SSet Integer)
--   Q.E.D.
--   </pre>
member :: (Ord a, SymVal a) => SBV a -> SSet a -> SBool

-- | Test for non-membership.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; x `notMember` observe "set" (singleton (x :: SInteger))
--   Falsifiable. Counter-example:
--     set = {0} :: {Integer}
--     s0  =   0 :: Integer
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x (s :: SSet Integer) -&gt; x `notMember` (x `delete` s)
--   Q.E.D.
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; x `notMember` (empty :: SSet Integer)
--   Q.E.D.
--   </pre>
notMember :: (Ord a, SymVal a) => SBV a -> SSet a -> SBool

-- | Is this the empty set?
--   
--   <pre>
--   &gt;&gt;&gt; null (empty :: SSet Integer)
--   True
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; null (x `delete` singleton (x :: SInteger))
--   Q.E.D.
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ null (full :: SSet Integer)
--   Falsifiable
--   </pre>
--   
--   Note how we have to call <a>prove</a> in the last case since dealing
--   with infinite sets requires a call to the solver and cannot be
--   constant folded.
null :: HasKind a => SSet a -> SBool

-- | Synonym for <a>null</a>.
isEmpty :: HasKind a => SSet a -> SBool

-- | Is this the full set?
--   
--   <pre>
--   &gt;&gt;&gt; prove $ isFull (empty :: SSet Integer)
--   Falsifiable
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; isFull (observe "set" (x `delete` (full :: SSet Integer)))
--   Falsifiable. Counter-example:
--     set = U - {2} :: {Integer}
--     s0  =       2 :: Integer
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; isFull (full :: SSet Integer)
--   True
--   </pre>
--   
--   Note how we have to call <a>prove</a> in the first case since dealing
--   with infinite sets requires a call to the solver and cannot be
--   constant folded.
isFull :: HasKind a => SSet a -> SBool

-- | Synonym for <a>isFull</a>.
isUniversal :: HasKind a => SSet a -> SBool

-- | Does the set have the given size? It implicitly asserts that the set
--   it is operating on is finite. NB. Only z3 supported this call, and as
--   discussed in <a>http://github.com/Z3Prover/z3/issues/3854</a>, recent
--   versions of z3 doesn't support size calls either. So, you can only use
--   this if you have a sufficiently old version of z3.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \i -&gt; hasSize (empty :: SSet Integer) i .== (i .== 0)
--   Q.E.D.
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; sat $ \i -&gt; hasSize (full :: SSet Integer) i
--   Unsatisfiable
--   </pre>
--   
--   The following tests are commented out since z3 no longer supports
--   size:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \a b i j k -&gt; hasSize (a :: SSet Integer) i .&amp;&amp; hasSize (b :: SSet Integer) j .&amp;&amp; hasSize (a `union` b) k .=&gt; k .&gt;= i `smax` j
--   Q.E.D.
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \a b i j k -&gt; hasSize (a :: SSet Integer) i .&amp;&amp; hasSize (b :: SSet Integer) j .&amp;&amp; hasSize (a `intersection` b) k .=&gt; k .&lt;= i `smin` j
--   Q.E.D.
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \a k -&gt; hasSize (a :: SSet Integer) k .=&gt; k .&gt;= 0
--   Q.E.D.
--   </pre>
hasSize :: (Ord a, SymVal a) => SSet a -> SInteger -> SBool

-- | Subset test.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ empty `isSubsetOf` (full :: SSet Integer)
--   Q.E.D.
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x (s :: SSet Integer) -&gt; s `isSubsetOf` (x `insert` s)
--   Q.E.D.
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x (s :: SSet Integer) -&gt; (x `delete` s) `isSubsetOf` s
--   Q.E.D.
--   </pre>
isSubsetOf :: (Ord a, SymVal a) => SSet a -> SSet a -> SBool

-- | Proper subset test.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ empty `isProperSubsetOf` (full :: SSet Integer)
--   Q.E.D.
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x (s :: SSet Integer) -&gt; s `isProperSubsetOf` (x `insert` s)
--   Falsifiable. Counter-example:
--     s0 = 2 :: Integer
--     s1 = U :: {Integer}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x (s :: SSet Integer) -&gt; x `notMember` s .=&gt; s `isProperSubsetOf` (x `insert` s)
--   Q.E.D.
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x (s :: SSet Integer) -&gt; (x `delete` s) `isProperSubsetOf` s
--   Falsifiable. Counter-example:
--     s0 =         2 :: Integer
--     s1 = U - {2,3} :: {Integer}
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x (s :: SSet Integer) -&gt; x `member` s .=&gt; (x `delete` s) `isProperSubsetOf` s
--   Q.E.D.
--   </pre>
isProperSubsetOf :: (Ord a, SymVal a) => SSet a -> SSet a -> SBool

-- | Disjoint test.
--   
--   <pre>
--   &gt;&gt;&gt; disjoint (fromList [2,4,6])   (fromList [1,3])
--   True
--   
--   &gt;&gt;&gt; disjoint (fromList [2,4,6,8]) (fromList [2,3,5,7])
--   False
--   
--   &gt;&gt;&gt; disjoint (fromList [1,2])     (fromList [1,2,3,4])
--   False
--   
--   &gt;&gt;&gt; prove $ \(s :: SSet Integer) -&gt; s `disjoint` complement s
--   Q.E.D.
--   
--   &gt;&gt;&gt; allSat $ \(s :: SSet Integer) -&gt; s `disjoint` s
--   Solution #1:
--     s0 = {} :: {Integer}
--   This is the only solution.
--   </pre>
--   
--   The last example is particularly interesting: The empty set is the
--   only set where <a>disjoint</a> is not reflexive!
--   
--   Note that disjointness of a set from its complement is guaranteed by
--   the fact that all types are inhabited; an implicit assumption we have
--   in classic logic which is also enjoyed by Haskell due to the presence
--   of bottom!
disjoint :: (Ord a, SymVal a) => SSet a -> SSet a -> SBool

-- | Union.
--   
--   <pre>
--   &gt;&gt;&gt; union (fromList [1..10]) (fromList [5..15]) .== (fromList [1..15] :: SSet Integer)
--   True
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) b -&gt; a `union` b .== b `union` a
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) b c -&gt; a `union` (b `union` c) .== (a `union` b) `union` c
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) -&gt; a `union` full .== full
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) -&gt; a `union` empty .== a
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) -&gt; a `union` complement a .== full
--   Q.E.D.
--   </pre>
union :: (Ord a, SymVal a) => SSet a -> SSet a -> SSet a

-- | Unions. Equivalent to <tt><a>foldr</a> <a>union</a> <a>empty</a></tt>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ unions [] .== (empty :: SSet Integer)
--   Q.E.D.
--   </pre>
unions :: (Ord a, SymVal a) => [SSet a] -> SSet a

-- | Intersection.
--   
--   <pre>
--   &gt;&gt;&gt; intersection (fromList [1..10]) (fromList [5..15]) .== (fromList [5..10] :: SSet Integer)
--   True
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) b -&gt; a `intersection` b .== b `intersection` a
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) b c -&gt; a `intersection` (b `intersection` c) .== (a `intersection` b) `intersection` c
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) -&gt; a `intersection` full .== a
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) -&gt; a `intersection` empty .== empty
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) -&gt; a `intersection` complement a .== empty
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) b -&gt; a `disjoint` b .=&gt; a `intersection` b .== empty
--   Q.E.D.
--   </pre>
intersection :: (Ord a, SymVal a) => SSet a -> SSet a -> SSet a

-- | Intersections. Equivalent to <tt><a>foldr</a> <a>intersection</a>
--   <a>full</a></tt>. Note that Haskell's <a>Set</a> does not support this
--   operation as it does not have a way of representing universal sets.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ intersections [] .== (full :: SSet Integer)
--   Q.E.D.
--   </pre>
intersections :: (Ord a, SymVal a) => [SSet a] -> SSet a

-- | Difference.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) -&gt; empty `difference` a .== empty
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) -&gt; a `difference` empty .== a
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) -&gt; full `difference` a .== complement a
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(a :: SSet Integer) -&gt; a `difference` a .== empty
--   Q.E.D.
--   </pre>
difference :: (Ord a, SymVal a) => SSet a -> SSet a -> SSet a

-- | Synonym for <a>difference</a>.
(\\) :: (Ord a, SymVal a) => SSet a -> SSet a -> SSet a
infixl 9 \\


-- | Symbolic rationals, corresponds to Haskell's <a>Rational</a> type
module Data.SBV.Rational

-- | Construct a symbolic rational from a given numerator and denominator.
--   Note that it is not possible to deconstruct a rational by taking
--   numerator and denominator fields, since we do not represent them
--   canonically. (This is due to the fact that SMTLib has no functions to
--   compute the GCD. One can use the maximization engine to compute the
--   GCD of numbers, but not as a function.)
(.%) :: SInteger -> SInteger -> SRational
infixl 7 .%


-- | Symbolic option type, symbolic version of Haskell's <a>Maybe</a> type.
module Data.SBV.Maybe

-- | Construct an <tt>SMaybe a</tt> from an <tt>SBV a</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; sJust (3 :: SInteger)
--   Just 3 :: SMaybe Integer
--   </pre>
sJust :: forall a. SymVal a => SBV a -> SMaybe a

-- | The symbolic <a>Nothing</a>.
--   
--   <pre>
--   &gt;&gt;&gt; sNothing :: SMaybe Integer
--   Nothing :: SMaybe Integer
--   </pre>
sNothing :: forall a. SymVal a => SMaybe a

-- | Construct an <tt>SMaybe a</tt> from a <tt>Maybe (SBV a)</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; liftMaybe (Just (3 :: SInteger))
--   Just 3 :: SMaybe Integer
--   
--   &gt;&gt;&gt; liftMaybe (Nothing :: Maybe SInteger)
--   Nothing :: SMaybe Integer
--   </pre>
liftMaybe :: SymVal a => Maybe (SBV a) -> SMaybe a

-- | Case analysis for symbolic <a>Maybe</a>s. If the value
--   <a>isNothing</a>, return the default value; if it <a>isJust</a>, apply
--   the function.
--   
--   <pre>
--   &gt;&gt;&gt; maybe 0 (`sMod` 2) (sJust (3 :: SInteger))
--   1 :: SInteger
--   
--   &gt;&gt;&gt; maybe 0 (`sMod` 2) (sNothing :: SMaybe Integer)
--   0 :: SInteger
--   
--   &gt;&gt;&gt; let f = uninterpret "f" :: SInteger -&gt; SBool
--   
--   &gt;&gt;&gt; prove $ \x d -&gt; maybe d f (sJust x) .== f x
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \d -&gt; maybe d f sNothing .== d
--   Q.E.D.
--   </pre>
maybe :: forall a b. (SymVal a, SymVal b) => SBV b -> (SBV a -> SBV b) -> SMaybe a -> SBV b

-- | Map over the <a>Just</a> side of a <a>Maybe</a>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; fromJust (map (+1) (sJust x)) .== x+(1::SInteger)
--   Q.E.D.
--   
--   &gt;&gt;&gt; let f = uninterpret "f" :: SInteger -&gt; SBool
--   
--   &gt;&gt;&gt; prove $ \x -&gt; map f (sJust x) .== sJust (f x)
--   Q.E.D.
--   
--   &gt;&gt;&gt; map f sNothing .== sNothing
--   True
--   </pre>
map :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b) -> SMaybe a -> SMaybe b

-- | Map over two maybe values.
map2 :: forall a b c. (SymVal a, SymVal b, SymVal c) => (SBV a -> SBV b -> SBV c) -> SMaybe a -> SMaybe b -> SMaybe c

-- | Check if the symbolic value is nothing.
--   
--   <pre>
--   &gt;&gt;&gt; isNothing (sNothing :: SMaybe Integer)
--   True
--   
--   &gt;&gt;&gt; isNothing (sJust (literal "nope"))
--   False
--   </pre>
isNothing :: SymVal a => SMaybe a -> SBool

-- | Check if the symbolic value is not nothing.
--   
--   <pre>
--   &gt;&gt;&gt; isJust (sNothing :: SMaybe Integer)
--   False
--   
--   &gt;&gt;&gt; isJust (sJust (literal "yep"))
--   True
--   
--   &gt;&gt;&gt; prove $ \x -&gt; isJust (sJust (x :: SInteger))
--   Q.E.D.
--   </pre>
isJust :: SymVal a => SMaybe a -> SBool

-- | Return the value of an optional value. The default is returned if
--   Nothing. Compare to <a>fromJust</a>.
--   
--   <pre>
--   &gt;&gt;&gt; fromMaybe 2 (sNothing :: SMaybe Integer)
--   2 :: SInteger
--   
--   &gt;&gt;&gt; fromMaybe 2 (sJust 5 :: SMaybe Integer)
--   5 :: SInteger
--   
--   &gt;&gt;&gt; prove $ \x -&gt; fromMaybe x (sNothing :: SMaybe Integer) .== x
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt; fromMaybe (x+1) (sJust x :: SMaybe Integer) .== x
--   Q.E.D.
--   </pre>
fromMaybe :: SymVal a => SBV a -> SMaybe a -> SBV a

-- | Return the value of an optional value. The behavior is undefined if
--   passed Nothing, i.e., it can return any value. Compare to
--   <a>fromMaybe</a>.
--   
--   <pre>
--   &gt;&gt;&gt; fromJust (sJust (literal 'a'))
--   'a' :: SChar
--   
--   &gt;&gt;&gt; prove $ \x -&gt; fromJust (sJust x) .== (x :: SChar)
--   Q.E.D.
--   
--   &gt;&gt;&gt; sat $ \x -&gt; x .== (fromJust sNothing :: SChar)
--   Satisfiable. Model:
--     s0 = 'A' :: Char
--   </pre>
--   
--   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.
fromJust :: forall a. SymVal a => SMaybe a -> SBV a
instance (GHC.Classes.Ord a, Data.SBV.Core.Data.SymVal a, GHC.Num.Num a) => GHC.Num.Num (Data.SBV.Core.Data.SBV (GHC.Maybe.Maybe a))


-- | A collection of list utilities, useful when working with symbolic
--   lists. To the extent possible, the functions in this module follow
--   those of <a>Data.List</a> so importing qualified is the recommended
--   workflow. Also, it is recommended you use the <tt>OverloadedLists</tt>
--   extension to allow literal lists to be used as symbolic-lists.
module Data.SBV.List

-- | Length of a list.
--   
--   <pre>
--   &gt;&gt;&gt; sat $ \(l :: SList Word16) -&gt; length l .== 2
--   Satisfiable. Model:
--     s0 = [0,0] :: [Word16]
--   
--   &gt;&gt;&gt; sat $ \(l :: SList Word16) -&gt; length l .&lt; 0
--   Unsatisfiable
--   
--   &gt;&gt;&gt; prove $ \(l1 :: SList Word16) (l2 :: SList Word16) -&gt; length l1 + length l2 .== length (l1 ++ l2)
--   Q.E.D.
--   </pre>
length :: SymVal a => SList a -> SInteger

-- | <tt><a>null</a> s</tt> is True iff the list is empty
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(l :: SList Word16) -&gt; null l .&lt;=&gt; length l .== 0
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(l :: SList Word16) -&gt; null l .&lt;=&gt; l .== []
--   Q.E.D.
--   </pre>
null :: SymVal a => SList a -> SBool

-- | <tt><a>head</a></tt> returns the first element of a list. Unspecified
--   if the list is empty.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; head (singleton c) .== (c :: SInteger)
--   Q.E.D.
--   </pre>
head :: SymVal a => SList a -> SBV a

-- | <tt><a>tail</a></tt> returns the tail of a list. Unspecified if the
--   list is empty.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(h :: SInteger) t -&gt; tail (singleton h ++ t) .== t
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(l :: SList Integer) -&gt; length l .&gt; 0 .=&gt; length (tail l) .== length l - 1
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(l :: SList Integer) -&gt; sNot (null l) .=&gt; singleton (head l) ++ tail l .== l
--   Q.E.D.
--   </pre>
tail :: SymVal a => SList a -> SList a

-- | <tt><a>uncons</a></tt> returns the pair of the head and tail.
--   Unspecified if the list is empty.
uncons :: SymVal a => SList a -> (SBV a, SList a)

-- | <tt><a>init</a></tt> returns all but the last element of the list.
--   Unspecified if the list is empty.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(h :: SInteger) t -&gt; init (t ++ singleton h) .== t
--   Q.E.D.
--   </pre>
init :: SymVal a => SList a -> SList a

-- | <tt><a>singleton</a> x</tt> is the list of length 1 that contains the
--   only value <tt>x</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(x :: SInteger) -&gt; head (singleton x) .== x
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(x :: SInteger) -&gt; length (singleton x) .== 1
--   Q.E.D.
--   </pre>
singleton :: SymVal a => SBV a -> SList a

-- | <tt><a>listToListAt</a> l offset</tt>. List of length 1 at
--   <tt>offset</tt> in <tt>l</tt>. Unspecified if index is out of bounds.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(l1 :: SList Integer) l2 -&gt; listToListAt (l1 ++ l2) (length l1) .== listToListAt l2 0
--   Q.E.D.
--   
--   &gt;&gt;&gt; sat $ \(l :: SList Word16) -&gt; length l .&gt;= 2 .&amp;&amp; listToListAt l 0 ./= listToListAt l (length l - 1)
--   Satisfiable. Model:
--     s0 = [0,16] :: [Word16]
--   </pre>
listToListAt :: SymVal a => SList a -> SInteger -> SList a

-- | <tt><a>elemAt</a> l i</tt> is the value stored at location <tt>i</tt>,
--   starting at 0. Unspecified if index is out of bounds.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \i -&gt; i `inRange` (0, 4) .=&gt; [1,1,1,1,1] `elemAt` i .== (1::SInteger)
--   Q.E.D.
--   </pre>
--   
--   <ul>
--   <li>&gt;&gt;&gt; prove $ (l :: SList Integer) i e -&gt; i
--   <a>inRange</a> (0, length l - 1) .&amp;&amp; l <a>elemAt</a> i .== e
--   .=&gt; indexOf l (singleton e) .&lt;= i Q.E.D.</li>
--   </ul>
elemAt :: SymVal a => SList a -> SInteger -> SBV a

-- | Short cut for <a>elemAt</a>
(!!) :: SymVal a => SList a -> SInteger -> SBV a

-- | <tt><a>implode</a> es</tt> is the list of length <tt>|es|</tt>
--   containing precisely those elements. Note that there is no
--   corresponding function <tt>explode</tt>, since we wouldn't know the
--   length of a symbolic list.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(e1 :: SInteger) e2 e3 -&gt; length (implode [e1, e2, e3]) .== 3
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(e1 :: SInteger) e2 e3 -&gt; P.map (elemAt (implode [e1, e2, e3])) (P.map literal [0 .. 2]) .== [e1, e2, e3]
--   Q.E.D.
--   </pre>
implode :: SymVal a => [SBV a] -> SList a

-- | Concatenate list of lists.
--   
--   NB. Concat is typically defined in terms of foldr. Here we prefer
--   foldl, since the underlying solver primitive is foldl: Otherwise, we'd
--   induce an extra call to reverse.
--   
--   <pre>
--   &gt;&gt;&gt; concat [[1..3::Integer], [4..7], [8..10]]
--   [1,2,3,4,5,6,7,8,9,10] :: [SInteger]
--   </pre>
concat :: SymVal a => SList [a] -> SList a

-- | Prepend an element, the traditional <tt>cons</tt>.
(.:) :: SymVal a => SBV a -> SList a -> SList a
infixr 5 .:

-- | Append an element
snoc :: SymVal a => SList a -> SBV a -> SList a

-- | Empty list. This value has the property that it's the only list with
--   length 0:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(l :: SList Integer) -&gt; length l .== 0 .&lt;=&gt; l .== nil
--   Q.E.D.
--   </pre>
nil :: SymVal a => SList a

-- | Append two lists.
--   
--   <pre>
--   &gt;&gt;&gt; sat $ \x y z -&gt; length x .== 5 .&amp;&amp; length y .== 1 .&amp;&amp; x ++ y ++ z .== [1 .. 12]
--   Satisfiable. Model:
--     s0 =      [1,2,3,4,5] :: [Integer]
--     s1 =              [6] :: [Integer]
--     s2 = [7,8,9,10,11,12] :: [Integer]
--   </pre>
(++) :: SymVal a => SList a -> SList a -> SList a
infixr 5 ++

-- | <tt><a>elem</a> e l</tt>. Does <tt>l</tt> contain the element
--   <tt>e</tt>?
elem :: (Eq a, SymVal a) => SBV a -> SList a -> SBool

-- | <tt><a>notElem</a> e l</tt>. Does <tt>l</tt> not contain the element
--   <tt>e</tt>?
notElem :: (Eq a, SymVal a) => SBV a -> SList a -> SBool

-- | <tt><a>isInfixOf</a> sub l</tt>. Does <tt>l</tt> contain the
--   subsequence <tt>sub</tt>?
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(l1 :: SList Integer) l2 l3 -&gt; l2 `isInfixOf` (l1 ++ l2 ++ l3)
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(l1 :: SList Integer) l2 -&gt; l1 `isInfixOf` l2 .&amp;&amp; l2 `isInfixOf` l1 .&lt;=&gt; l1 .== l2
--   Q.E.D.
--   </pre>
isInfixOf :: (Eq a, SymVal a) => SList a -> SList a -> SBool

-- | <tt><a>isSuffixOf</a> suf l</tt>. Is <tt>suf</tt> a suffix of
--   <tt>l</tt>?
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(l1 :: SList Word16) l2 -&gt; l2 `isSuffixOf` (l1 ++ l2)
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(l1 :: SList Word16) l2 -&gt; l1 `isSuffixOf` l2 .=&gt; subList l2 (length l2 - length l1) (length l1) .== l1
--   Q.E.D.
--   </pre>
isSuffixOf :: (Eq a, SymVal a) => SList a -> SList a -> SBool

-- | <tt><a>isPrefixOf</a> pre l</tt>. Is <tt>pre</tt> a prefix of
--   <tt>l</tt>?
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(l1 :: SList Integer) l2 -&gt; l1 `isPrefixOf` (l1 ++ l2)
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(l1 :: SList Integer) l2 -&gt; l1 `isPrefixOf` l2 .=&gt; subList l2 0 (length l1) .== l1
--   Q.E.D.
--   </pre>
isPrefixOf :: (Eq a, SymVal a) => SList a -> SList a -> SBool

-- | <tt><a>take</a> len l</tt>. Corresponds to Haskell's <a>take</a> on
--   symbolic lists.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(l :: SList Integer) i -&gt; i .&gt;= 0 .=&gt; length (take i l) .&lt;= i
--   Q.E.D.
--   </pre>
take :: SymVal a => SInteger -> SList a -> SList a

-- | <tt><a>drop</a> len s</tt>. Corresponds to Haskell's <a>drop</a> on
--   symbolic-lists.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(l :: SList Word16) i -&gt; length (drop i l) .&lt;= length l
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(l :: SList Word16) i -&gt; take i l ++ drop i l .== l
--   Q.E.D.
--   </pre>
drop :: SymVal a => SInteger -> SList a -> SList a

-- | <tt><a>subList</a> s offset len</tt> is the sublist of <tt>s</tt> at
--   offset <tt>offset</tt> with length <tt>len</tt>. This function is
--   under-specified when the offset is outside the range of positions in
--   <tt>s</tt> or <tt>len</tt> is negative or <tt>offset+len</tt> exceeds
--   the length of <tt>s</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(l :: SList Integer) i -&gt; i .&gt;= 0 .&amp;&amp; i .&lt; length l .=&gt; subList l 0 i ++ subList l i (length l - i) .== l
--   Q.E.D.
--   
--   &gt;&gt;&gt; sat  $ \i j -&gt; subList [1..5] i j .== ([2..4] :: SList Integer)
--   Satisfiable. Model:
--     s0 = 1 :: Integer
--     s1 = 3 :: Integer
--   
--   &gt;&gt;&gt; sat  $ \i j -&gt; subList [1..5] i j .== ([6..7] :: SList Integer)
--   Unsatisfiable
--   </pre>
subList :: SymVal a => SList a -> SInteger -> SInteger -> SList a

-- | <tt><a>replace</a> l src dst</tt>. Replace the first occurrence of
--   <tt>src</tt> by <tt>dst</tt> in <tt>s</tt>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \l -&gt; replace [1..5] l [6..10] .== [6..10] .=&gt; l .== ([1..5] :: SList Word8)
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(l1 :: SList Integer) l2 l3 -&gt; length l2 .&gt; length l1 .=&gt; replace l1 l2 l3 .== l1
--   Q.E.D.
--   </pre>
replace :: (Eq a, SymVal a) => SList a -> SList a -> SList a -> SList a

-- | <tt><a>indexOf</a> l sub</tt>. Retrieves first position of
--   <tt>sub</tt> in <tt>l</tt>, <tt>-1</tt> if there are no occurrences.
--   Equivalent to <tt><a>offsetIndexOf</a> l sub 0</tt>.
--   
--   <ul>
--   <li>&gt;&gt;&gt; prove $ (l :: SList Int8) i -&gt; i .&gt; 0
--   .&amp;&amp; i .<a>l .=</a> indexOf l (subList l i 1) .&lt;= i
--   Q.E.D.</li>
--   </ul>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(l1 :: SList Word16) l2 -&gt; length l2 .&gt; length l1 .=&gt; indexOf l1 l2 .== -1
--   Q.E.D.
--   </pre>
indexOf :: (Eq a, SymVal a) => SList a -> SList a -> SInteger

-- | <tt><a>offsetIndexOf</a> l sub offset</tt>. Retrieves first position
--   of <tt>sub</tt> at or after <tt>offset</tt> in <tt>l</tt>, <tt>-1</tt>
--   if there are no occurrences.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(l :: SList Int8) sub -&gt; offsetIndexOf l sub 0 .== indexOf l sub
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(l :: SList Int8) sub i -&gt; i .&gt;= length l .&amp;&amp; length sub .&gt; 0 .=&gt; offsetIndexOf l sub i .== -1
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(l :: SList Int8) sub i -&gt; i .&gt; length l .=&gt; offsetIndexOf l sub i .== -1
--   Q.E.D.
--   </pre>
offsetIndexOf :: (Eq a, SymVal a) => SList a -> SList a -> SInteger -> SInteger

-- | <tt><a>reverse</a> s</tt> reverses the sequence.
--   
--   NB. We can define <tt>reverse</tt> in terms of <tt>foldl</tt> as:
--   <tt>foldl (soFar elt -&gt; singleton elt ++ soFar) []</tt> But in my
--   experiments, I found that this definition performs worse instead of
--   the recursive definition SBV generates for reverse calls. So we're
--   keeping it intact.
--   
--   <pre>
--   &gt;&gt;&gt; sat $ \(l :: SList Integer) -&gt; reverse l .== literal [3, 2, 1]
--   Satisfiable. Model:
--     s0 = [1,2,3] :: [Integer]
--   
--   &gt;&gt;&gt; prove $ \(l :: SList Word32) -&gt; reverse l .== [] .&lt;=&gt; null l
--   Q.E.D.
--   </pre>
reverse :: SymVal a => SList a -> SList a

-- | <tt><a>map</a> op s</tt> maps the operation on to sequence.
--   
--   <pre>
--   &gt;&gt;&gt; map (+1) [1 .. 5 :: Integer]
--   [2,3,4,5,6] :: [SInteger]
--   
--   &gt;&gt;&gt; map (+1) [1 .. 5 :: WordN 8]
--   [2,3,4,5,6] :: [SWord8]
--   
--   &gt;&gt;&gt; map singleton [1 .. 3 :: Integer]
--   [[1],[2],[3]] :: [[SInteger]]
--   
--   &gt;&gt;&gt; import Data.SBV.Tuple
--   
--   &gt;&gt;&gt; import GHC.Exts (fromList)
--   
--   &gt;&gt;&gt; map (\t -&gt; t^._1 + t^._2) (fromList [(x, y) | x &lt;- [1..3], y &lt;- [4..6]] :: SList (Integer, Integer))
--   [5,6,7,6,7,8,7,8,9] :: [SInteger]
--   </pre>
--   
--   Of course, SBV's <a>map</a> can also be reused in reverse:
--   
--   <pre>
--   &gt;&gt;&gt; sat $ \l -&gt; map (+1) l .== [1,2,3 :: Integer]
--   Satisfiable. Model:
--     s0 = [0,1,2] :: [Integer]
--   </pre>
map :: forall a b. (SymVal a, SymVal b) => (SBV a -> SBV b) -> SList a -> SList b

-- | <tt><a>mapi</a> op s</tt> maps the operation on to sequence, with the
--   counter given at each element, starting at the given value. In Haskell
--   terms, it is:
--   
--   <pre>
--   mapi :: (Integer -&gt; a -&gt; b) -&gt; Integer -&gt; [a] -&gt; [b]
--   mapi f i xs = zipWith f [i..] xs
--   </pre>
--   
--   Note that <a>mapi</a> is definable in terms of <a>zipWith</a>, with
--   extra coding. The reason why SBV provides this function natively is
--   because it maps to a native function in the underlying solver. So,
--   hopefully it'll perform better in terms being decidable.
--   
--   <pre>
--   &gt;&gt;&gt; mapi (+) 10 [1 .. 5 :: Integer]
--   [11,13,15,17,19] :: [SInteger]
--   </pre>
mapi :: forall a b. (SymVal a, SymVal b) => (SInteger -> SBV a -> SBV b) -> SInteger -> SList a -> SList b

-- | <tt><a>foldl</a> op base s</tt> folds the from the left.
--   
--   <pre>
--   &gt;&gt;&gt; foldl (+) 0 [1 .. 5 :: Integer]
--   15 :: SInteger
--   
--   &gt;&gt;&gt; foldl (*) 1 [1 .. 5 :: Integer]
--   120 :: SInteger
--   
--   &gt;&gt;&gt; foldl (\soFar elt -&gt; singleton elt ++ soFar) ([] :: SList Integer) [1 .. 5 :: Integer]
--   [5,4,3,2,1] :: [SInteger]
--   </pre>
--   
--   Again, we can use <a>foldl</a> in the reverse too:
--   
--   <pre>
--   &gt;&gt;&gt; sat $ \l -&gt; foldl (\soFar elt -&gt; singleton elt ++ soFar) ([] :: SList Integer) l .== [5, 4, 3, 2, 1 :: Integer]
--   Satisfiable. Model:
--     s0 = [1,2,3,4,5] :: [Integer]
--   </pre>
foldl :: (SymVal a, SymVal b) => (SBV b -> SBV a -> SBV b) -> SBV b -> SList a -> SBV b

-- | <tt><a>foldr</a> op base s</tt> folds the sequence from the right.
--   
--   <pre>
--   &gt;&gt;&gt; foldr (+) 0 [1 .. 5 :: Integer]
--   15 :: SInteger
--   
--   &gt;&gt;&gt; foldr (*) 1 [1 .. 5 :: Integer]
--   120 :: SInteger
--   
--   &gt;&gt;&gt; foldr (\elt soFar -&gt; soFar ++ singleton elt) ([] :: SList Integer) [1 .. 5 :: Integer]
--   [5,4,3,2,1] :: [SInteger]
--   </pre>
foldr :: (SymVal a, SymVal b) => (SBV a -> SBV b -> SBV b) -> SBV b -> SList a -> SBV b

-- | <tt><a>foldli</a> op i base s</tt> folds the sequence, with the
--   counter given at each element, starting at the given value. In Haskell
--   terms, it is:
--   
--   <pre>
--   foldli :: (Integer -&gt; b -&gt; a -&gt; b) -&gt; Integer -&gt; b -&gt; [a] -&gt; b
--   foldli f c e xs = foldl (b (i, a) -&gt; f i b a) e (zip [c..] xs)
--   </pre>
--   
--   While this function is rather odd looking, it maps directly to the
--   implementation in the underlying solver, and proofs involving it might
--   have better decidability.
--   
--   <pre>
--   &gt;&gt;&gt; foldli (\i b a -&gt; i+b+a) 10 0 [1 .. 5 :: Integer]
--   75 :: SInteger
--   </pre>
foldli :: (SymVal a, SymVal b) => (SInteger -> SBV b -> SBV a -> SBV b) -> SInteger -> SBV b -> SList a -> SBV b

-- | <tt><a>foldri</a> op base i s</tt> folds the sequence from the right,
--   with the counter given at each element, starting at the given value.
--   This function is provided as a parallel to <a>foldli</a>.
foldri :: (SymVal a, SymVal b) => (SBV a -> SBV b -> SInteger -> SBV b) -> SBV b -> SInteger -> SList a -> SBV b

-- | <tt><a>zip</a> xs ys</tt> zips the lists to give a list of pairs. The
--   length of the final list is the minumum of the lengths of the given
--   lists.
--   
--   <pre>
--   &gt;&gt;&gt; zip [1..10::Integer] [11..20::Integer]
--   [(1,11),(2,12),(3,13),(4,14),(5,15),(6,16),(7,17),(8,18),(9,19),(10,20)] :: [(SInteger, SInteger)]
--   
--   &gt;&gt;&gt; import Data.SBV.Tuple
--   
--   &gt;&gt;&gt; foldr (+) 0 (map (\t -&gt; t^._1+t^._2::SInteger) (zip [1..10::Integer] [10, 9..1::Integer]))
--   110 :: SInteger
--   </pre>
zip :: (SymVal a, SymVal b) => SList a -> SList b -> SList (a, b)

-- | <tt><a>zipWith</a> f xs ys</tt> zips the lists to give a list of
--   pairs, applying the function to each pair of elements. The length of
--   the final list is the minumum of the lengths of the given lists.
--   
--   <pre>
--   &gt;&gt;&gt; zipWith (+) [1..10::Integer] [11..20::Integer]
--   [12,14,16,18,20,22,24,26,28,30] :: [SInteger]
--   
--   &gt;&gt;&gt; foldr (+) 0 (zipWith (+) [1..10::Integer] [10, 9..1::Integer])
--   110 :: SInteger
--   </pre>
zipWith :: (SymVal a, SymVal b, SymVal c) => (SBV a -> SBV b -> SBV c) -> SList a -> SList b -> SList c

-- | <tt>filter f xs</tt> filters the list with the given predicate.
--   
--   <pre>
--   &gt;&gt;&gt; filter (\x -&gt; x `sMod` 2 .== 0) [1 .. 10 :: Integer]
--   [2,4,6,8,10] :: [SInteger]
--   
--   &gt;&gt;&gt; filter (\x -&gt; x `sMod` 2 ./= 0) [1 .. 10 :: Integer]
--   [1,3,5,7,9] :: [SInteger]
--   </pre>
filter :: SymVal a => (SBV a -> SBool) -> SList a -> SList a

-- | Check all elements satisfy the predicate.
--   
--   <pre>
--   &gt;&gt;&gt; let isEven x = x `sMod` 2 .== 0
--   
--   &gt;&gt;&gt; all isEven [2, 4, 6, 8, 10 :: Integer]
--   True
--   
--   &gt;&gt;&gt; all isEven [2, 4, 6, 1, 8, 10 :: Integer]
--   False
--   </pre>
all :: SymVal a => (SBV a -> SBool) -> SList a -> SBool

-- | Check some element satisfies the predicate. -- &gt;&gt;&gt; let isEven
--   x = x <a>sMod</a> 2 .== 0 &gt;&gt;&gt; any (sNot . isEven) [2, 4, 6,
--   8, 10 :: Integer] False &gt;&gt;&gt; any isEven [2, 4, 6, 1, 8, 10 ::
--   Integer] True
any :: SymVal a => (SBV a -> SBool) -> SList a -> SBool


-- | Symbolic coproduct, symbolic version of Haskell's <a>Either</a> type.
module Data.SBV.Either

-- | Construct an <tt>SEither a b</tt> from an <tt>SBV a</tt>
--   
--   <pre>
--   &gt;&gt;&gt; sLeft 3 :: SEither Integer Bool
--   Left 3 :: SEither Integer Bool
--   </pre>
sLeft :: forall a b. (SymVal a, SymVal b) => SBV a -> SEither a b

-- | Construct an <tt>SEither a b</tt> from an <tt>SBV b</tt>
--   
--   <pre>
--   &gt;&gt;&gt; sRight sFalse :: SEither Integer Bool
--   Right False :: SEither Integer Bool
--   </pre>
sRight :: forall a b. (SymVal a, SymVal b) => SBV b -> SEither a b

-- | Construct an <tt>SEither a b</tt> from an <tt>Either (SBV a) (SBV
--   b)</tt>
--   
--   <pre>
--   &gt;&gt;&gt; liftEither (Left 3 :: Either SInteger SBool)
--   Left 3 :: SEither Integer Bool
--   
--   &gt;&gt;&gt; liftEither (Right sTrue :: Either SInteger SBool)
--   Right True :: SEither Integer Bool
--   </pre>
liftEither :: (SymVal a, SymVal b) => Either (SBV a) (SBV b) -> SEither a b

-- | Case analysis for symbolic <a>Either</a>s. If the value <a>isLeft</a>,
--   apply the first function; if it <a>isRight</a>, apply the second
--   function.
--   
--   <pre>
--   &gt;&gt;&gt; either (*2) (*3) (sLeft 3)
--   6 :: SInteger
--   
--   &gt;&gt;&gt; either (*2) (*3) (sRight 3)
--   9 :: SInteger
--   
--   &gt;&gt;&gt; let f = uninterpret "f" :: SInteger -&gt; SInteger
--   
--   &gt;&gt;&gt; let g = uninterpret "g" :: SInteger -&gt; SInteger
--   
--   &gt;&gt;&gt; prove $ \x -&gt; either f g (sLeft x) .== f x
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt; either f g (sRight x) .== g x
--   Q.E.D.
--   </pre>
either :: forall a b c. (SymVal a, SymVal b, SymVal c) => (SBV a -> SBV c) -> (SBV b -> SBV c) -> SEither a b -> SBV c

-- | Map over both sides of a symbolic <a>Either</a> at the same time
--   
--   <pre>
--   &gt;&gt;&gt; let f = uninterpret "f" :: SInteger -&gt; SInteger
--   
--   &gt;&gt;&gt; let g = uninterpret "g" :: SInteger -&gt; SInteger
--   
--   &gt;&gt;&gt; prove $ \x -&gt; fromLeft (bimap f g (sLeft x)) .== f x
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt; fromRight (bimap f g (sRight x)) .== g x
--   Q.E.D.
--   </pre>
bimap :: forall a b c d. (SymVal a, SymVal b, SymVal c, SymVal d) => (SBV a -> SBV b) -> (SBV c -> SBV d) -> SEither a c -> SEither b d

-- | Map over the left side of an <a>Either</a>
--   
--   <pre>
--   &gt;&gt;&gt; let f = uninterpret "f" :: SInteger -&gt; SInteger
--   
--   &gt;&gt;&gt; prove $ \x -&gt; first f (sLeft x :: SEither Integer Integer) .== sLeft (f x)
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt; first f (sRight x :: SEither Integer Integer) .== sRight x
--   Q.E.D.
--   </pre>
first :: (SymVal a, SymVal b, SymVal c) => (SBV a -> SBV b) -> SEither a c -> SEither b c

-- | Map over the right side of an <a>Either</a>
--   
--   <pre>
--   &gt;&gt;&gt; let f = uninterpret "f" :: SInteger -&gt; SInteger
--   
--   &gt;&gt;&gt; prove $ \x -&gt; second f (sRight x :: SEither Integer Integer) .== sRight (f x)
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt; second f (sLeft x :: SEither Integer Integer) .== sLeft x
--   Q.E.D.
--   </pre>
second :: (SymVal a, SymVal b, SymVal c) => (SBV b -> SBV c) -> SEither a b -> SEither a c

-- | Return <a>sTrue</a> if the given symbolic value is <a>Left</a>,
--   <a>sFalse</a> otherwise
--   
--   <pre>
--   &gt;&gt;&gt; isLeft (sLeft 3 :: SEither Integer Bool)
--   True
--   
--   &gt;&gt;&gt; isLeft (sRight sTrue :: SEither Integer Bool)
--   False
--   </pre>
isLeft :: (SymVal a, SymVal b) => SEither a b -> SBV Bool

-- | Return <a>sTrue</a> if the given symbolic value is <a>Right</a>,
--   <a>sFalse</a> otherwise
--   
--   <pre>
--   &gt;&gt;&gt; isRight (sLeft 3 :: SEither Integer Bool)
--   False
--   
--   &gt;&gt;&gt; isRight (sRight sTrue :: SEither Integer Bool)
--   True
--   </pre>
isRight :: (SymVal a, SymVal b) => SEither a b -> SBV Bool

-- | Return the value from the left component. The behavior is undefined if
--   passed a right value, i.e., it can return any value.
--   
--   <pre>
--   &gt;&gt;&gt; fromLeft (sLeft (literal 'a') :: SEither Char Integer)
--   'a' :: SChar
--   
--   &gt;&gt;&gt; prove $ \x -&gt; fromLeft (sLeft x :: SEither Char Integer) .== (x :: SChar)
--   Q.E.D.
--   
--   &gt;&gt;&gt; sat $ \x -&gt; x .== (fromLeft (sRight 4 :: SEither Char Integer))
--   Satisfiable. Model:
--     s0 = 'A' :: Char
--   </pre>
--   
--   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.
fromLeft :: forall a b. (SymVal a, SymVal b) => SEither a b -> SBV a

-- | Return the value from the right component. The behavior is undefined
--   if passed a left value, i.e., it can return any value.
--   
--   <pre>
--   &gt;&gt;&gt; fromRight (sRight (literal 'a') :: SEither Integer Char)
--   'a' :: SChar
--   
--   &gt;&gt;&gt; prove $ \x -&gt; fromRight (sRight x :: SEither Char Integer) .== (x :: SInteger)
--   Q.E.D.
--   
--   &gt;&gt;&gt; sat $ \x -&gt; x .== (fromRight (sLeft (literal 2) :: SEither Integer Char))
--   Satisfiable. Model:
--     s0 = 'A' :: Char
--   </pre>
--   
--   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 :: forall a b. (SymVal a, SymVal b) => SEither a b -> SBV b


-- | Implementation of polynomial arithmetic
module Data.SBV.Tools.Polynomial

-- | Implements polynomial addition, multiplication, division, and modulus
--   operations over GF(2^n). NB. Similar to <a>sQuotRem</a>, division by
--   <tt>0</tt> is interpreted as follows:
--   
--   <pre>
--   x <a>pDivMod</a> 0 = (0, x)
--   </pre>
--   
--   for all <tt>x</tt> (including <tt>0</tt>)
--   
--   Minimal complete definition: <a>pMult</a>, <a>pDivMod</a>,
--   <a>showPolynomial</a>
class (Num a, Bits a) => Polynomial a

-- | Given bit-positions to be set, create a polynomial For instance
--   
--   <pre>
--   polynomial [0, 1, 3] :: SWord8
--   </pre>
--   
--   will evaluate to <tt>11</tt>, since it sets the bits <tt>0</tt>,
--   <tt>1</tt>, and <tt>3</tt>. Mathematicians would write this polynomial
--   as <tt>x^3 + x + 1</tt>. And in fact, <a>showPoly</a> will show it
--   like that.
polynomial :: Polynomial a => [Int] -> a

-- | Add two polynomials in GF(2^n).
pAdd :: Polynomial a => a -> a -> a

-- | Multiply two polynomials in GF(2^n), and reduce it by the irreducible
--   specified by the polynomial as specified by coefficients of the third
--   argument. Note that the third argument is specifically left in this
--   form as it is usually in GF(2^(n+1)), which is not available in our
--   formalism. (That is, we would need SWord9 for SWord8 multiplication,
--   etc.) Also note that we do not support symbolic irreducibles, which is
--   a minor shortcoming. (Most GF's will come with fixed irreducibles, so
--   this should not be a problem in practice.)
--   
--   Passing [] for the third argument will multiply the polynomials and
--   then ignore the higher bits that won't fit into the resulting size.
pMult :: Polynomial a => (a, a, [Int]) -> a

-- | Divide two polynomials in GF(2^n), see above note for division by 0.
pDiv :: Polynomial a => a -> a -> a

-- | Compute modulus of two polynomials in GF(2^n), see above note for
--   modulus by 0.
pMod :: Polynomial a => a -> a -> a

-- | Division and modulus packed together.
pDivMod :: Polynomial a => a -> a -> (a, a)

-- | Display a polynomial like a mathematician would (over the monomial
--   <tt>x</tt>), with a type.
showPoly :: Polynomial a => a -> String

-- | Display a polynomial like a mathematician would (over the monomial
--   <tt>x</tt>), the first argument controls if the final type is shown as
--   well.
showPolynomial :: Polynomial a => Bool -> a -> String

-- | Compute CRC's over polynomials, i.e., symbolic words. The first
--   <a>Int</a> argument plays the same role as the one in the <a>crcBV</a>
--   function.
crc :: (SFiniteBits a, SFiniteBits b) => Int -> SBV a -> SBV b -> SBV b

-- | Compute CRCs over bit-vectors. The call <tt>crcBV n m p</tt> computes
--   the CRC of the message <tt>m</tt> with respect to polynomial
--   <tt>p</tt>. The inputs are assumed to be blasted big-endian. The
--   number <tt>n</tt> specifies how many bits of CRC is needed. Note that
--   <tt>n</tt> is actually the degree of the polynomial <tt>p</tt>, and
--   thus it seems redundant to pass it in. However, in a typical proof
--   context, the polynomial can be symbolic, so we cannot compute the
--   degree easily. While this can be worked-around by generating code that
--   accounts for all possible degrees, the resulting code would be
--   unnecessarily big and complicated, and much harder to reason with.
--   (Also note that a CRC is just the remainder from the polynomial
--   division, but this routine is much faster in practice.)
--   
--   NB. The <tt>n</tt>th bit of the polynomial <tt>p</tt> <i>must</i> be
--   set for the CRC to be computed correctly. Note that the polynomial
--   argument <tt>p</tt> will not even have this bit present most of the
--   time, as it will typically contain bits <tt>0</tt> through
--   <tt>n-1</tt> as usual in the CRC literature. The higher order
--   <tt>n</tt>th bit is simply assumed to be set, as it does not make
--   sense to use a polynomial of a lesser degree. This is usually not a
--   problem since CRC polynomials are designed and expressed this way.
--   
--   NB. The literature on CRC's has many variants on how CRC's are
--   computed. We follow the following simple procedure:
--   
--   <ul>
--   <li>Extend the message <tt>m</tt> by adding <tt>n</tt> 0 bits on the
--   right</li>
--   <li>Divide the polynomial thus obtained by the <tt>p</tt></li>
--   <li>The remainder is the CRC value.</li>
--   </ul>
--   
--   There are many variants on final XOR's, reversed polynomials etc., so
--   it is essential to double check you use the correct <i>algorithm</i>.
crcBV :: Int -> [SBool] -> [SBool] -> [SBool]

-- | Run down a boolean condition over two lists. Note that this is
--   different than zipWith as shorter list is assumed to be filled with
--   sFalse at the end (i.e., zero-bits); which nicely pads it when
--   considered as an unsigned number in little-endian form.
ites :: SBool -> [SBool] -> [SBool] -> [SBool]

-- | Compute modulus/remainder of polynomials on bit-vectors.
mdp :: [SBool] -> [SBool] -> ([SBool], [SBool])

-- | Add two polynomials
addPoly :: [SBool] -> [SBool] -> [SBool]
instance Data.SBV.Tools.Polynomial.Polynomial GHC.Word.Word8
instance Data.SBV.Tools.Polynomial.Polynomial GHC.Word.Word16
instance Data.SBV.Tools.Polynomial.Polynomial GHC.Word.Word32
instance Data.SBV.Tools.Polynomial.Polynomial GHC.Word.Word64
instance Data.SBV.Tools.Polynomial.Polynomial Data.SBV.Core.Data.SWord8
instance Data.SBV.Tools.Polynomial.Polynomial Data.SBV.Core.Data.SWord16
instance Data.SBV.Tools.Polynomial.Polynomial Data.SBV.Core.Data.SWord32
instance Data.SBV.Tools.Polynomial.Polynomial Data.SBV.Core.Data.SWord64
instance (GHC.TypeNats.KnownNat n, Data.SBV.Core.Kind.BVIsNonZero n) => Data.SBV.Tools.Polynomial.Polynomial (Data.SBV.Core.Sized.SWord n)


-- | Implementation of overflow detection functions. Based on:
--   <a>http://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/z3prefix.pdf</a>
module Data.SBV.Tools.Overflow

-- | Detecting underflow/overflow conditions. For each function, the first
--   result is the condition under which the computation underflows, and
--   the second is the condition under which it overflows.
class ArithOverflow a

-- | Bit-vector addition. Unsigned addition can only overflow. Signed
--   addition can underflow and overflow.
--   
--   A tell tale sign of unsigned addition overflow is when the sum is less
--   than minimum of the arguments.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x y -&gt; snd (bvAddO x (y::SWord16)) .&lt;=&gt; x + y .&lt; x `smin` y
--   Q.E.D.
--   </pre>
bvAddO :: ArithOverflow a => a -> a -> (SBool, SBool)

-- | Bit-vector subtraction. Unsigned subtraction can only underflow.
--   Signed subtraction can underflow and overflow.
bvSubO :: ArithOverflow a => a -> a -> (SBool, SBool)

-- | Bit-vector multiplication. Unsigned multiplication can only overflow.
--   Signed multiplication can underflow and overflow.
bvMulO :: ArithOverflow a => a -> a -> (SBool, SBool)

-- | Same as <a>bvMulO</a>, except instead of doing the computation
--   internally, it simply sends it off to z3 as a primitive. Obviously,
--   only use if you have the z3 backend! Note that z3 provides this
--   operation only when no logic is set, so make sure to call <tt>setLogic
--   Logic_NONE</tt> in your program!
bvMulOFast :: ArithOverflow a => a -> a -> (SBool, SBool)

-- | Bit-vector division. Unsigned division neither underflows nor
--   overflows. Signed division can only overflow. In fact, for each signed
--   bitvector type, there's precisely one pair that overflows, when
--   <tt>x</tt> is <tt>minBound</tt> and <tt>y</tt> is <tt>-1</tt>:
--   
--   <pre>
--   &gt;&gt;&gt; allSat $ \x y -&gt; snd (x `bvDivO` (y::SInt8))
--   Solution #1:
--     s0 = -128 :: Int8
--     s1 =   -1 :: Int8
--   This is the only solution.
--   </pre>
bvDivO :: ArithOverflow a => a -> a -> (SBool, SBool)

-- | Bit-vector negation. Unsigned negation neither underflows nor
--   overflows. Signed negation can only overflow, when the argument is
--   <tt>minBound</tt>:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; x .== minBound .&lt;=&gt; snd (bvNegO (x::SInt16))
--   Q.E.D.
--   </pre>
bvNegO :: ArithOverflow a => a -> (SBool, SBool)

-- | A class of checked-arithmetic operations. These follow the usual
--   arithmetic, except make calls to <a>sAssert</a> to ensure no
--   overflow/underflow can occur. Use them in conjunction with <a>safe</a>
--   to ensure no overflow can happen.
class (ArithOverflow (SBV a), Num a, SymVal a) => CheckedArithmetic a
(+!) :: (CheckedArithmetic a, ?loc :: CallStack) => SBV a -> SBV a -> SBV a
(-!) :: (CheckedArithmetic a, ?loc :: CallStack) => SBV a -> SBV a -> SBV a
(*!) :: (CheckedArithmetic a, ?loc :: CallStack) => SBV a -> SBV a -> SBV a
(/!) :: (CheckedArithmetic a, ?loc :: CallStack) => SBV a -> SBV a -> SBV a
negateChecked :: (CheckedArithmetic a, ?loc :: CallStack) => SBV a -> SBV a
infixl 6 +!
infixl 6 -!
infixl 7 *!
infixl 7 /!

-- | Detecting underflow/overflow conditions for casting between
--   bit-vectors. The first output is the result, the second component
--   itself is a pair with the first boolean indicating underflow and the
--   second indicating overflow.
--   
--   <pre>
--   &gt;&gt;&gt; sFromIntegralO (256 :: SInt16) :: (SWord8, (SBool, SBool))
--   (0 :: SWord8,(False,True))
--   
--   &gt;&gt;&gt; sFromIntegralO (-2 :: SInt16) :: (SWord8, (SBool, SBool))
--   (254 :: SWord8,(True,False))
--   
--   &gt;&gt;&gt; sFromIntegralO (2 :: SInt16) :: (SWord8, (SBool, SBool))
--   (2 :: SWord8,(False,False))
--   
--   &gt;&gt;&gt; prove $ \x -&gt; sFromIntegralO (x::SInt32) .== (sFromIntegral x :: SInteger, (sFalse, sFalse))
--   Q.E.D.
--   </pre>
--   
--   As the last example shows, converting to <a>sInteger</a> never
--   underflows or overflows for any value.
sFromIntegralO :: forall a b. (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b, SymVal b) => SBV a -> (SBV b, (SBool, SBool))

-- | Version of <a>sFromIntegral</a> that has calls to <a>sAssert</a> for
--   checking no overflow/underflow can happen. Use it with a <a>safe</a>
--   call.
sFromIntegralChecked :: forall a b. (?loc :: CallStack, Integral a, HasKind a, HasKind b, Num a, SymVal a, HasKind b, Num b, SymVal b) => SBV a -> SBV b
instance Data.SBV.Tools.Overflow.CheckedArithmetic GHC.Word.Word8
instance Data.SBV.Tools.Overflow.CheckedArithmetic GHC.Word.Word16
instance Data.SBV.Tools.Overflow.CheckedArithmetic GHC.Word.Word32
instance Data.SBV.Tools.Overflow.CheckedArithmetic GHC.Word.Word64
instance Data.SBV.Tools.Overflow.CheckedArithmetic GHC.Int.Int8
instance Data.SBV.Tools.Overflow.CheckedArithmetic GHC.Int.Int16
instance Data.SBV.Tools.Overflow.CheckedArithmetic GHC.Int.Int32
instance Data.SBV.Tools.Overflow.CheckedArithmetic GHC.Int.Int64
instance (GHC.TypeNats.KnownNat n, Data.SBV.Core.Kind.BVIsNonZero n) => Data.SBV.Tools.Overflow.CheckedArithmetic (Data.SBV.Core.Sized.WordN n)
instance (GHC.TypeNats.KnownNat n, Data.SBV.Core.Kind.BVIsNonZero n) => Data.SBV.Tools.Overflow.CheckedArithmetic (Data.SBV.Core.Sized.IntN n)
instance Data.SBV.Tools.Overflow.ArithOverflow Data.SBV.Core.Data.SWord8
instance Data.SBV.Tools.Overflow.ArithOverflow Data.SBV.Core.Data.SWord16
instance Data.SBV.Tools.Overflow.ArithOverflow Data.SBV.Core.Data.SWord32
instance Data.SBV.Tools.Overflow.ArithOverflow Data.SBV.Core.Data.SWord64
instance Data.SBV.Tools.Overflow.ArithOverflow Data.SBV.Core.Data.SInt8
instance Data.SBV.Tools.Overflow.ArithOverflow Data.SBV.Core.Data.SInt16
instance Data.SBV.Tools.Overflow.ArithOverflow Data.SBV.Core.Data.SInt32
instance Data.SBV.Tools.Overflow.ArithOverflow Data.SBV.Core.Data.SInt64
instance (GHC.TypeNats.KnownNat n, Data.SBV.Core.Kind.BVIsNonZero n) => Data.SBV.Tools.Overflow.ArithOverflow (Data.SBV.Core.Sized.SWord n)
instance (GHC.TypeNats.KnownNat n, Data.SBV.Core.Kind.BVIsNonZero n) => Data.SBV.Tools.Overflow.ArithOverflow (Data.SBV.Core.Sized.SInt n)
instance Data.SBV.Tools.Overflow.ArithOverflow Data.SBV.Core.Symbolic.SVal


-- | A collection of character utilities, follows the namings in
--   <a>Data.Char</a> and is intended to be imported qualified. Also, it is
--   recommended you use the <tt>OverloadedStrings</tt> extension to allow
--   literal strings to be used as symbolic-strings when working with
--   symbolic characters and strings.
--   
--   <a>SChar</a> type only covers all unicode characters, following the
--   specification in
--   <a>http://smtlib.cs.uiowa.edu/theories-UnicodeStrings.shtml</a>.
--   However, some of the recognizers only support the Latin1 subset,
--   suffixed by <tt>L1</tt>. The reason for this is that there is no
--   performant way of performing these functions for the entire unicode
--   set. As SMTLib's capabilities increase, we will provide full unicode
--   versions as well.
module Data.SBV.Char

-- | Is the character in the string?
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings
--   
--   &gt;&gt;&gt; prove $ \c -&gt; c `elem` singleton c
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; sNot (c `elem` "")
--   Q.E.D.
--   </pre>
elem :: SChar -> SString -> SBool

-- | Is the character not in the string?
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c s -&gt; c `elem` s .&lt;=&gt; sNot (c `notElem` s)
--   Q.E.D.
--   </pre>
notElem :: SChar -> SString -> SBool

-- | The <a>ord</a> of a character.
ord :: SChar -> SInteger

-- | Conversion from an integer to a character.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; 0 .&lt;= x .&amp;&amp; x .&lt; 256 .=&gt; ord (chr x) .== x
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt; chr (ord x) .== x
--   Q.E.D.
--   </pre>
chr :: SInteger -> SChar

-- | Convert to lower-case. Only works for the Latin1 subset, otherwise
--   returns its argument unchanged.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; toLowerL1 (toLowerL1 c) .== toLowerL1 c
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; isLowerL1 c .&amp;&amp; c `notElem` "\181\255" .=&gt; toLowerL1 (toUpperL1 c) .== c
--   Q.E.D.
--   </pre>
toLowerL1 :: SChar -> SChar

-- | Convert to upper-case. Only works for the Latin1 subset, otherwise
--   returns its argument unchanged.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; toUpperL1 (toUpperL1 c) .== toUpperL1 c
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; isUpperL1 c .=&gt; toUpperL1 (toLowerL1 c) .== c
--   Q.E.D.
--   </pre>
toUpperL1 :: SChar -> SChar

-- | Convert a digit to an integer. Works for hexadecimal digits too. If
--   the input isn't a digit, then return -1.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; isDigit c .|| isHexDigit c .=&gt; digitToInt c .&gt;= 0 .&amp;&amp; digitToInt c .&lt;= 15
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; sNot (isDigit c .|| isHexDigit c) .=&gt; digitToInt c .== -1
--   Q.E.D.
--   </pre>
digitToInt :: SChar -> SInteger

-- | Convert an integer to a digit, inverse of <a>digitToInt</a>. If the
--   integer is out of bounds, we return the arbitrarily chosen space
--   character. Note that for hexadecimal letters, we return the
--   corresponding lowercase letter.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \i -&gt; i .&gt;= 0 .&amp;&amp; i .&lt;= 15 .=&gt; digitToInt (intToDigit i) .== i
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \i -&gt; i .&lt;  0 .|| i .&gt;  15 .=&gt; digitToInt (intToDigit i) .== -1
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; digitToInt c .== -1 .&lt;=&gt; intToDigit (digitToInt c) .== literal ' '
--   Q.E.D.
--   </pre>
intToDigit :: SInteger -> SChar

-- | Is this a control character? Control characters are essentially the
--   non-printing characters. Only works for the Latin1 subset, otherwise
--   returns <a>sFalse</a>.
isControlL1 :: SChar -> SBool

-- | Is this white-space? Only works for the Latin1 subset, otherwise
--   returns <a>sFalse</a>.
isSpaceL1 :: SChar -> SBool

-- | Is this a lower-case character? Only works for the Latin1 subset,
--   otherwise returns <a>sFalse</a>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; isUpperL1 c .=&gt; isLowerL1 (toLowerL1 c)
--   Q.E.D.
--   </pre>
isLowerL1 :: SChar -> SBool

-- | Is this an upper-case character? Only works for the Latin1 subset,
--   otherwise returns <a>sFalse</a>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; sNot (isLowerL1 c .&amp;&amp; isUpperL1 c)
--   Q.E.D.
--   </pre>
isUpperL1 :: SChar -> SBool

-- | Is this an alphabet character? That is lower-case, upper-case and
--   title-case letters, plus letters of caseless scripts and modifiers
--   letters. Only works for the Latin1 subset, otherwise returns
--   <a>sFalse</a>.
isAlphaL1 :: SChar -> SBool

-- | Is this an alphabetical character or a digit? Only works for the
--   Latin1 subset, otherwise returns <a>sFalse</a>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; isAlphaNumL1 c .&lt;=&gt; isAlphaL1 c .|| isNumberL1 c
--   Q.E.D.
--   </pre>
isAlphaNumL1 :: SChar -> SBool

-- | Is this a printable character? Only works for the Latin1 subset,
--   otherwise returns <a>sFalse</a>.
isPrintL1 :: SChar -> SBool

-- | Is this an ASCII digit, i.e., one of <tt>0</tt>..<tt>9</tt>. Note that
--   this is a subset of <a>isNumberL1</a>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; isDigit c .=&gt; isNumberL1 c
--   Q.E.D.
--   </pre>
isDigit :: SChar -> SBool

-- | Is this an Octal digit, i.e., one of <tt>0</tt>..<tt>7</tt>.
isOctDigit :: SChar -> SBool

-- | Is this a Hex digit, i.e, one of <tt>0</tt>..<tt>9</tt>,
--   <tt>a</tt>..<tt>f</tt>, <tt>A</tt>..<tt>F</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; isHexDigit c .=&gt; isAlphaNumL1 c
--   Q.E.D.
--   </pre>
isHexDigit :: SChar -> SBool

-- | Is this an alphabet character. Only works for the Latin1 subset,
--   otherwise returns <a>sFalse</a>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; isLetterL1 c .&lt;=&gt; isAlphaL1 c
--   Q.E.D.
--   </pre>
isLetterL1 :: SChar -> SBool

-- | Is this a mark? Only works for the Latin1 subset, otherwise returns
--   <a>sFalse</a>.
--   
--   Note that there are no marks in the Latin1 set, so this function
--   always returns false!
--   
--   <pre>
--   &gt;&gt;&gt; prove $ sNot . isMarkL1
--   Q.E.D.
--   </pre>
isMarkL1 :: SChar -> SBool

-- | Is this a number character? Only works for the Latin1 subset,
--   otherwise returns <a>sFalse</a>.
isNumberL1 :: SChar -> SBool

-- | Is this a punctuation mark? Only works for the Latin1 subset,
--   otherwise returns <a>sFalse</a>.
isPunctuationL1 :: SChar -> SBool

-- | Is this a symbol? Only works for the Latin1 subset, otherwise returns
--   <a>sFalse</a>.
isSymbolL1 :: SChar -> SBool

-- | Is this a separator? Only works for the Latin1 subset, otherwise
--   returns <a>sFalse</a>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; isSeparatorL1 c .=&gt; isSpaceL1 c
--   Q.E.D.
--   </pre>
isSeparatorL1 :: SChar -> SBool

-- | Is this an ASCII character, i.e., the first 128 characters.
isAscii :: SChar -> SBool

-- | Is this a Latin1 character?
isLatin1 :: SChar -> SBool

-- | Is this an ASCII Upper-case letter? i.e., <tt>A</tt> thru <tt>Z</tt>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; isAsciiUpper c .&lt;=&gt; ord c .&gt;= ord (literal 'A') .&amp;&amp; ord c .&lt;= ord (literal 'Z')
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; isAsciiUpper c .&lt;=&gt; isAscii c .&amp;&amp; isUpperL1 c
--   Q.E.D.
--   </pre>
isAsciiUpper :: SChar -> SBool

-- | Is this an ASCII Lower-case letter? i.e., <tt>a</tt> thru <tt>z</tt>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; isAsciiLower c .&lt;=&gt; ord c .&gt;= ord (literal 'a') .&amp;&amp; ord c .&lt;= ord (literal 'z')
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; isAsciiLower c .&lt;=&gt; isAscii c .&amp;&amp; isLowerL1 c
--   Q.E.D.
--   </pre>
isAsciiLower :: SChar -> SBool


-- | A collection of regular-expression related utilities. The recommended
--   workflow is to import this module qualified as the names of the
--   functions are specifically chosen to be common identifiers. Also, it
--   is recommended you use the <tt>OverloadedStrings</tt> extension to
--   allow literal strings to be used as symbolic-strings and
--   regular-expressions when working with this module.
module Data.SBV.RegExp

-- | Regular expressions. Note that regular expressions themselves are
--   concrete, but the <a>match</a> function from the
--   <a>RegExpMatchable</a> class can check membership against a symbolic
--   string/character. Also, we are preferring a datatype approach here, as
--   opposed to coming up with some string-representation; there are way
--   too many alternatives already so inventing one isn't a priority.
--   Please get in touch if you would like a parser for this type as it
--   might be easier to use.
data RegExp

-- | Precisely match the given string
Literal :: String -> RegExp

-- | Accept every string
All :: RegExp

-- | Accept every single character
AllChar :: RegExp

-- | Accept no strings
None :: RegExp

-- | Accept range of characters
Range :: Char -> Char -> RegExp

-- | Concatenation
Conc :: [RegExp] -> RegExp

-- | Kleene Star: Zero or more
KStar :: RegExp -> RegExp

-- | Kleene Plus: One or more
KPlus :: RegExp -> RegExp

-- | Zero or one
Opt :: RegExp -> RegExp

-- | Complement of regular expression
Comp :: RegExp -> RegExp

-- | Difference of regular expressions
Diff :: RegExp -> RegExp -> RegExp

-- | From <tt>n</tt> repetitions to <tt>m</tt> repetitions
Loop :: Int -> Int -> RegExp -> RegExp

-- | Exactly <tt>n</tt> repetitions, i.e., nth power
Power :: Int -> RegExp -> RegExp

-- | Union of regular expressions
Union :: [RegExp] -> RegExp

-- | Intersection of regular expressions
Inter :: RegExp -> RegExp -> RegExp

-- | Matchable class. Things we can match against a <a>RegExp</a>.
--   
--   For instance, you can generate valid-looking phone numbers like this:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XOverloadedStrings
--   
--   &gt;&gt;&gt; let dig09 = Range '0' '9'
--   
--   &gt;&gt;&gt; let dig19 = Range '1' '9'
--   
--   &gt;&gt;&gt; let pre   = dig19 * Loop 2 2 dig09
--   
--   &gt;&gt;&gt; let post  = dig19 * Loop 3 3 dig09
--   
--   &gt;&gt;&gt; let phone = pre * "-" * post
--   
--   &gt;&gt;&gt; sat $ \s -&gt; (s :: SString) `match` phone
--   Satisfiable. Model:
--     s0 = "200-8000" :: String
--   </pre>
class RegExpMatchable a

-- | <tt><a>match</a> s r</tt> checks whether <tt>s</tt> is in the language
--   generated by <tt>r</tt>.
match :: RegExpMatchable a => a -> RegExp -> SBool

-- | Match everything, universal acceptor.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(s :: SString) -&gt; s `match` everything
--   Q.E.D.
--   </pre>
everything :: RegExp

-- | Match nothing, universal rejector.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(s :: SString) -&gt; sNot (s `match` nothing)
--   Q.E.D.
--   </pre>
nothing :: RegExp

-- | Match any character, i.e., strings of length 1
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(s :: SString) -&gt; s `match` anyChar .&lt;=&gt; length s .== 1
--   Q.E.D.
--   </pre>
anyChar :: RegExp

-- | A literal regular-expression, matching the given string exactly. Note
--   that with <tt>OverloadedStrings</tt> extension, you can simply use a
--   Haskell string to mean the same thing, so this function is rarely
--   needed.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(s :: SString) -&gt; s `match` exactly "LITERAL" .&lt;=&gt; s .== "LITERAL"
--   Q.E.D.
--   </pre>
exactly :: String -> RegExp

-- | Helper to define a character class.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \(c :: SChar) -&gt; c `match` oneOf "ABCD" .&lt;=&gt; sAny (c .==) (map literal "ABCD")
--   Q.E.D.
--   </pre>
oneOf :: String -> RegExp

-- | Recognize a newline. Also includes carriage-return and form-feed.
--   
--   <pre>
--   &gt;&gt;&gt; newline
--   (re.union (str.to.re "\n") (str.to.re "\r") (str.to.re "\f"))
--   
--   &gt;&gt;&gt; prove $ \c -&gt; c `match` newline .=&gt; isSpaceL1 c
--   Q.E.D.
--   </pre>
newline :: RegExp

-- | Recognize white-space, but without a new line.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; c `match` whiteSpaceNoNewLine .=&gt; c `match` whiteSpace .&amp;&amp; c ./= literal '\n'
--   Q.E.D.
--   </pre>
whiteSpaceNoNewLine :: RegExp

-- | Recognize white space.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; c `match` whiteSpace .=&gt; isSpaceL1 c
--   Q.E.D.
--   </pre>
whiteSpace :: RegExp

-- | Recognize a tab.
--   
--   <pre>
--   &gt;&gt;&gt; tab
--   (str.to.re "\t")
--   
--   &gt;&gt;&gt; prove $ \c -&gt; c `match` tab .=&gt; c .== literal '\t'
--   Q.E.D.
--   </pre>
tab :: RegExp

-- | Recognize a punctuation character.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \c -&gt; c `match` punctuation .=&gt; isPunctuationL1 c
--   Q.E.D.
--   </pre>
punctuation :: RegExp

-- | Recognize an alphabet letter, i.e., <tt>A</tt>..<tt>Z</tt>,
--   <tt>a</tt>..<tt>z</tt>.
asciiLetter :: RegExp

-- | Recognize an ASCII lower case letter
--   
--   <pre>
--   &gt;&gt;&gt; asciiLower
--   (re.range "a" "z")
--   
--   &gt;&gt;&gt; prove $ \c -&gt; (c :: SChar) `match` asciiLower  .=&gt; c `match` asciiLetter
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; c `match` asciiLower  .=&gt; toUpperL1 c `match` asciiUpper
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; c `match` asciiLetter .=&gt; toLowerL1 c `match` asciiLower
--   Q.E.D.
--   </pre>
asciiLower :: RegExp

-- | Recognize an upper case letter
--   
--   <pre>
--   &gt;&gt;&gt; asciiUpper
--   (re.range "A" "Z")
--   
--   &gt;&gt;&gt; prove $ \c -&gt; (c :: SChar) `match` asciiUpper  .=&gt; c `match` asciiLetter
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; c `match` asciiUpper  .=&gt; toLowerL1 c `match` asciiLower
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; c `match` asciiLetter .=&gt; toUpperL1 c `match` asciiUpper
--   Q.E.D.
--   </pre>
asciiUpper :: RegExp

-- | Recognize a digit. One of <tt>0</tt>..<tt>9</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; digit
--   (re.range "0" "9")
--   
--   &gt;&gt;&gt; prove $ \c -&gt; c `match` digit .&lt;=&gt; let v = digitToInt c in 0 .&lt;= v .&amp;&amp; v .&lt; 10
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \c -&gt; sNot ((c::SChar) `match` (digit - digit))
--   Q.E.D.
--   </pre>
digit :: RegExp

-- | Recognize an octal digit. One of <tt>0</tt>..<tt>7</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; octDigit
--   (re.range "0" "7")
--   
--   &gt;&gt;&gt; prove $ \c -&gt; c `match` octDigit .&lt;=&gt; let v = digitToInt c in 0 .&lt;= v .&amp;&amp; v .&lt; 8
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(c :: SChar) -&gt; c `match` octDigit .=&gt; c `match` digit
--   Q.E.D.
--   </pre>
octDigit :: RegExp

-- | Recognize a hexadecimal digit. One of <tt>0</tt>..<tt>9</tt>,
--   <tt>a</tt>..<tt>f</tt>, <tt>A</tt>..<tt>F</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; hexDigit
--   (re.union (re.range "0" "9") (re.range "a" "f") (re.range "A" "F"))
--   
--   &gt;&gt;&gt; prove $ \c -&gt; c `match` hexDigit .&lt;=&gt; let v = digitToInt c in 0 .&lt;= v .&amp;&amp; v .&lt; 16
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \(c :: SChar) -&gt; c `match` digit .=&gt; c `match` hexDigit
--   Q.E.D.
--   </pre>
hexDigit :: RegExp

-- | Recognize a decimal number.
--   
--   <pre>
--   &gt;&gt;&gt; decimal
--   (re.+ (re.range "0" "9"))
--   
--   &gt;&gt;&gt; prove $ \s -&gt; (s::SString) `match` decimal .=&gt; sNot (s `match` KStar asciiLetter)
--   Q.E.D.
--   </pre>
decimal :: RegExp

-- | Recognize an octal number. Must have a prefix of the form
--   <tt>0o</tt>/<tt>0O</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; octal
--   (re.++ (re.union (str.to.re "0o") (str.to.re "0O")) (re.+ (re.range "0" "7")))
--   
--   &gt;&gt;&gt; prove $ \s -&gt; s `match` octal .=&gt; sAny (.== take 2 s) ["0o", "0O"]
--   Q.E.D.
--   </pre>
octal :: RegExp

-- | Recognize a hexadecimal number. Must have a prefix of the form
--   <tt>0x</tt>/<tt>0X</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; hexadecimal
--   (re.++ (re.union (str.to.re "0x") (str.to.re "0X")) (re.+ (re.union (re.range "0" "9") (re.range "a" "f") (re.range "A" "F"))))
--   
--   &gt;&gt;&gt; prove $ \s -&gt; s `match` hexadecimal .=&gt; sAny (.== take 2 s) ["0x", "0X"]
--   Q.E.D.
--   </pre>
hexadecimal :: RegExp

-- | Recognize a floating point number. The exponent part is optional if a
--   fraction is present. The exponent may or may not have a sign.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s -&gt; s `match` floating .=&gt; length s .&gt;= 3
--   Q.E.D.
--   </pre>
floating :: RegExp

-- | For the purposes of this regular expression, an identifier consists of
--   a letter followed by zero or more letters, digits, underscores, and
--   single quotes. The first letter must be lowercase.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \s -&gt; s `match` identifier .=&gt; isAsciiLower (head s)
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \s -&gt; s `match` identifier .=&gt; length s .&gt;= 1
--   Q.E.D.
--   </pre>
identifier :: RegExp
instance Data.SBV.RegExp.RegExpMatchable Data.SBV.Core.Data.SChar
instance Data.SBV.RegExp.RegExpMatchable Data.SBV.Core.Data.SString


-- | Control sublanguage for interacting with SMT solvers.
module Data.SBV.Control

-- | Monads which support <a>IO</a> operations and can extract all
--   <a>IO</a> behavior for interoperation with functions like
--   <a>catches</a>, which takes an <a>IO</a> action in negative position.
--   This function can not be implemented for transformers like <tt>ReaderT
--   r</tt> or <tt>StateT s</tt>, whose resultant <a>IO</a> actions are a
--   function of some environment or state.
class MonadIO m => ExtractIO m

-- | Law: the <tt>m a</tt> yielded by <a>IO</a> is pure with respect to
--   <a>IO</a>.
extractIO :: ExtractIO m => m a -> IO (m a)

-- | Computations which support query operations.
class Monad m => MonadQuery m
queryState :: MonadQuery m => m State
queryState :: (MonadQuery m, MonadTrans t, MonadQuery m', m ~ t m') => m State

-- | An queriable value. This is a generalization of the <a>Fresh</a>
--   class, in case one needs to be more specific about how
--   projections/embeddings are done.
class Queriable m a where {
    type QueryResult a :: Type;
}

-- | ^ Create a new symbolic value of type <tt>a</tt>
create :: Queriable m a => QueryT m a

-- | ^ Extract the current value in a SAT context
project :: Queriable m a => a -> QueryT m (QueryResult a)

-- | ^ Create a literal value. Morally, <a>embed</a> and <a>project</a> are
--   inverses of each other via the <a>QueryT</a> monad transformer.
embed :: Queriable m a => QueryResult a -> QueryT m a

-- | Create a fresh variable of some type in the underlying query monad
--   transformer. For further control on how these variables are projected
--   and embedded, see the <a>Queriable</a> class.
class Fresh m a
fresh :: Fresh m a => QueryT m a

-- | A query is a user-guided mechanism to directly communicate and extract
--   results from the solver.
type Query = QueryT IO

-- | Run a custom query
query :: Query a -> Symbolic a

-- | Similar to <a>freshVar</a>, except creates unnamed variable.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>freshVar_</a>
freshVar_ :: SymVal a => Query (SBV a)

-- | Create a fresh variable in query mode. You should prefer creating
--   input variables using <a>sBool</a>, <a>sInt32</a>, etc., which act as
--   primary inputs to the model. Use <a>freshVar</a> only in query mode
--   for anonymous temporary variables. Note that <a>freshVar</a> should
--   hardly be needed: Your input variables and symbolic expressions should
--   suffice for -- most major use cases.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>freshVar</a>
freshVar :: SymVal a => String -> Query (SBV a)

-- | Similar to <a>freshArray</a>, except creates unnamed array.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>freshArray_</a>
freshArray_ :: (SymArray array, HasKind a, HasKind b) => Maybe (SBV b) -> Query (array a b)

-- | Create a fresh array in query mode. Again, you should prefer creating
--   arrays before the queries start using <a>newArray</a>, but this method
--   can come in handy in occasional cases where you need a new array after
--   you start the query based interaction.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>freshArray</a>
freshArray :: (SymArray array, HasKind a, HasKind b) => String -> Maybe (SBV b) -> Query (array a b)

-- | Result of a <a>checkSat</a> or <a>checkSatAssuming</a> call.
data CheckSatResult

-- | Satisfiable: A model is available, which can be queried with
--   <a>getValue</a>.
Sat :: CheckSatResult

-- | Delta-satisfiable: A delta-sat model is available. String is the
--   precision info, if available.
DSat :: Maybe String -> CheckSatResult

-- | Unsatisfiable: No model is available. Unsat cores might be obtained
--   via <a>getUnsatCore</a>.
Unsat :: CheckSatResult

-- | Unknown: Use <a>getUnknownReason</a> to obtain an explanation why this
--   might be the case.
Unk :: CheckSatResult

-- | Check for satisfiability.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>checkSat</a>
checkSat :: Query CheckSatResult

-- | Ensure that the current context is satisfiable. If not, this function
--   will throw an error.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>ensureSat</a>
ensureSat :: Query ()

-- | Check for satisfiability with a custom check-sat-using command.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>checkSatUsing</a>
checkSatUsing :: String -> Query CheckSatResult

-- | Check for satisfiability, under the given conditions. Similar to
--   <a>checkSat</a> except it allows making further assumptions as
--   captured by the first argument of booleans. (Also see
--   <a>checkSatAssumingWithUnsatisfiableSet</a> for a variant that returns
--   the subset of the given assumptions that led to the <a>Unsat</a>
--   conclusion.)
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>checkSatAssuming</a>
checkSatAssuming :: [SBool] -> Query CheckSatResult

-- | Check for satisfiability, under the given conditions. Returns the
--   unsatisfiable set of assumptions. Similar to <a>checkSat</a> except it
--   allows making further assumptions as captured by the first argument of
--   booleans. If the result is <a>Unsat</a>, the user will also receive a
--   subset of the given assumptions that led to the <a>Unsat</a>
--   conclusion. Note that while this set will be a subset of the inputs,
--   it is not necessarily guaranteed to be minimal.
--   
--   You must have arranged for the production of unsat assumptions first
--   via
--   
--   <pre>
--   <a>setOption</a> $ <a>ProduceUnsatAssumptions</a> <a>True</a>
--   </pre>
--   
--   for this call to not error out!
--   
--   Usage note: <a>getUnsatCore</a> is usually easier to use than
--   <a>checkSatAssumingWithUnsatisfiableSet</a>, as it allows the use of
--   named assertions, as obtained by <a>namedConstraint</a>. If
--   <a>getUnsatCore</a> fills your needs, you should definitely prefer it
--   over <a>checkSatAssumingWithUnsatisfiableSet</a>.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>checkSatAssumingWithUnsatisfiableSet</a>
checkSatAssumingWithUnsatisfiableSet :: [SBool] -> Query (CheckSatResult, Maybe [SBool])

-- | Get the value of a term.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getValue</a>
getValue :: SymVal a => SBV a -> Query a

-- | Registering an uninterpreted SMT function. This is typically not
--   necessary as uses of the UI function itself will register it
--   automatically. But there are cases where doing this explicitly can
--   come in handy.
registerUISMTFunction :: (MonadIO m, SolverContext m, MonadSymbolic m) => SMTFunction fun a r => fun -> m ()

-- | Get the value of an uninterpreted function, as a list of domain, value
--   pairs. The final value is the "else" clause, i.e., what the function
--   maps values outside of the domain of the first list.
getFunction :: (SymVal a, SymVal r, SMTFunction fun a r) => fun -> Query (Either String ([(a, r)], r))

-- | Get the value of an uninterpreted sort, as a String
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getUninterpretedValue</a>
getUninterpretedValue :: HasKind a => SBV a -> Query String

-- | Collect model values. It is implicitly assumed that we are in a
--   check-sat context. See <a>getSMTResult</a> for a variant that issues a
--   check-sat first and returns an <a>SMTResult</a>.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getModel</a>
getModel :: Query SMTModel

-- | Retrieve the assignment. This is a lightweight version of
--   <a>getValue</a>, where the solver returns the truth value for all
--   named subterms of type <a>Bool</a>.
--   
--   You must have first arranged for assignments to be produced via
--   
--   <pre>
--   <a>setOption</a> $ <a>ProduceAssignments</a> <a>True</a>
--   </pre>
--   
--   for this call to not error out!
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getAssignment</a>
getAssignment :: Query [(String, Bool)]

-- | Issue check-sat and get an SMT Result out.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getSMTResult</a>
getSMTResult :: Query SMTResult

-- | Get the reason unknown. Only internally used.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getUnknownReason</a>
getUnknownReason :: Query SMTReasonUnknown

-- | Get the observables recorded during a query run.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getObservables</a>
getObservables :: Query [(Name, CV)]

-- | Retrieve the unsat-core. Note you must have arranged for unsat cores
--   to be produced first via
--   
--   <pre>
--   <a>setOption</a> $ <a>ProduceUnsatCores</a> <a>True</a>
--   </pre>
--   
--   for this call to not error out!
--   
--   NB. There is no notion of a minimal unsat-core, in case
--   unsatisfiability can be derived in multiple ways. Furthermore, Z3 does
--   not guarantee that the generated unsat core does not have any
--   redundant assertions either, as doing so can incur a performance
--   penalty. (There might be assertions in the set that is not needed.) To
--   ensure all the assertions in the core are relevant, use:
--   
--   <pre>
--   <a>setOption</a> $ <a>OptionKeyword</a> ":smt.core.minimize" ["true"]
--   </pre>
--   
--   Note that this only works with Z3.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getUnsatCore</a>
getUnsatCore :: Query [String]

-- | Retrieve the proof. Note you must have arranged for proofs to be
--   produced first via
--   
--   <pre>
--   <a>setOption</a> $ <a>ProduceProofs</a> <a>True</a>
--   </pre>
--   
--   for this call to not error out!
--   
--   A proof is simply a <a>String</a>, as returned by the solver. In the
--   future, SBV might provide a better datatype, depending on the use
--   cases. Please get in touch if you use this function and can suggest a
--   better API.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getProof</a>
getProof :: Query String

-- | Interpolant extraction for MathSAT. Compare with
--   <a>getInterpolantZ3</a>, which performs similar function (but with a
--   different use model) in Z3.
--   
--   Retrieve an interpolant after an <a>Unsat</a> result is obtained. Note
--   you must have arranged for interpolants to be produced first via
--   
--   <pre>
--   <a>setOption</a> $ <a>ProduceInterpolants</a> <a>True</a>
--   </pre>
--   
--   for this call to not error out!
--   
--   To get an interpolant for a pair of formulas <tt>A</tt> and
--   <tt>B</tt>, use a <a>constrainWithAttribute</a> call to attach
--   interplation groups to <tt>A</tt> and <tt>B</tt>. Then call
--   <a>getInterpolantMathSAT</a> <tt>["A"]</tt>, assuming those are the
--   names you gave to the formulas in the <tt>A</tt> group.
--   
--   An interpolant for <tt>A</tt> and <tt>B</tt> is a formula <tt>I</tt>
--   such that:
--   
--   <pre>
--       A .=&gt; I
--   and B .=&gt; sNot I
--   </pre>
--   
--   That is, it's evidence that <tt>A</tt> and <tt>B</tt> cannot be true
--   together since <tt>A</tt> implies <tt>I</tt> but <tt>B</tt> implies
--   <tt>not I</tt>; establishing that <tt>A</tt> and <tt>B</tt> cannot be
--   satisfied at the same time. Furthermore, <tt>I</tt> will have only the
--   symbols that are common to <tt>A</tt> and <tt>B</tt>.
--   
--   NB. Interpolant extraction isn't standardized well in SMTLib.
--   Currently both MathSAT and Z3 support them, but with slightly
--   differing APIs. So, we support two APIs with slightly differing types
--   to accommodate both. See
--   <a>Documentation.SBV.Examples.Queries.Interpolants</a> for example
--   usages in these solvers.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getInterpolantMathSAT</a>
getInterpolantMathSAT :: [String] -> Query String

-- | Interpolant extraction for z3. Compare with
--   <a>getInterpolantMathSAT</a>, which performs similar function (but
--   with a different use model) in MathSAT.
--   
--   Unlike the MathSAT variant, you should simply call
--   <a>getInterpolantZ3</a> on symbolic booleans to retrieve the
--   interpolant. Do not call <a>checkSat</a> or create named constraints.
--   This makes it harder to identify formulas, but the current state of
--   affairs in interpolant API requires this kludge.
--   
--   An interpolant for <tt>A</tt> and <tt>B</tt> is a formula <tt>I</tt>
--   such that:
--   
--   <pre>
--       A ==&gt; I
--   and B ==&gt; not I
--   </pre>
--   
--   That is, it's evidence that <tt>A</tt> and <tt>B</tt> cannot be true
--   together since <tt>A</tt> implies <tt>I</tt> but <tt>B</tt> implies
--   <tt>not I</tt>; establishing that <tt>A</tt> and <tt>B</tt> cannot be
--   satisfied at the same time. Furthermore, <tt>I</tt> will have only the
--   symbols that are common to <tt>A</tt> and <tt>B</tt>.
--   
--   In Z3, interpolants generalize to sequences: If you pass more than two
--   formulas, then you will get a sequence of interpolants. In general,
--   for <tt>N</tt> formulas that are not satisfiable together, you will be
--   returned <tt>N-1</tt> interpolants. If formulas are <tt>A1 .. An</tt>,
--   then interpolants will be <tt>I1 .. I(N-1)</tt>, such that <tt>A1
--   ==&gt; I1</tt>, <tt>A2 /\ I1 ==&gt; I2</tt>, <tt>A3 /\ I2 ==&gt;
--   I3</tt>, ..., and finally <tt>AN ===&gt; not I(N-1)</tt>.
--   
--   Currently, SBV only returns simple and sequence interpolants, and does
--   not support tree-interpolants. If you need these, please get in touch.
--   Furthermore, the result will be a list of mere strings representing
--   the interpolating formulas, as opposed to a more structured type.
--   Please get in touch if you use this function and can suggest a better
--   API.
--   
--   NB. Interpolant extraction isn't standardized well in SMTLib.
--   Currently both MathSAT and Z3 support them, but with slightly
--   differing APIs. So, we support two APIs with slightly differing types
--   to accommodate both. See
--   <a>Documentation.SBV.Examples.Queries.Interpolants</a> for example
--   usages in these solvers.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getInterpolantZ3</a>
getInterpolantZ3 :: [SBool] -> Query String

-- | Get an abduct. The first argument is a conjecture. The return value
--   will be an assertion such that in addition with the existing
--   assertions you have, will imply this conjecture. The second argument
--   is the grammar which guides the synthesis of this abduct, if given.
--   Note that SBV doesn't do any checking on the grammar. See the relevant
--   documentation on CVC5 for details.
--   
--   NB. Before you use this function, make sure to call
--   
--   <pre>
--   setOption $ ProduceAbducts True
--   </pre>
--   
--   to enable abduct generation.
getAbduct :: Maybe String -> String -> SBool -> Query String

-- | Get the next abduct. Only call this after the first call to
--   <a>getAbduct</a> goes through. You can call it repeatedly to get a
--   different abduct.
getAbductNext :: Query String

-- | Retrieve assertions. Note you must have arranged for assertions to be
--   available first via
--   
--   <pre>
--   <a>setOption</a> $ <a>ProduceAssertions</a> <a>True</a>
--   </pre>
--   
--   for this call to not error out!
--   
--   Note that the set of assertions returned is merely a list of strings,
--   just like the case for <a>getProof</a>. In the future, SBV might
--   provide a better datatype, depending on the use cases. Please get in
--   touch if you use this function and can suggest a better API.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getAssertions</a>
getAssertions :: Query [String]

-- | Collectable information from the solver.
data SMTInfoFlag
AllStatistics :: SMTInfoFlag
AssertionStackLevels :: SMTInfoFlag
Authors :: SMTInfoFlag
ErrorBehavior :: SMTInfoFlag
Name :: SMTInfoFlag
ReasonUnknown :: SMTInfoFlag
Version :: SMTInfoFlag
InfoKeyword :: String -> SMTInfoFlag

-- | Behavior of the solver for errors.
data SMTErrorBehavior
ErrorImmediateExit :: SMTErrorBehavior
ErrorContinuedExecution :: SMTErrorBehavior

-- | Collectable information from the solver.
data SMTInfoResponse
Resp_Unsupported :: SMTInfoResponse
Resp_AllStatistics :: [(String, String)] -> SMTInfoResponse
Resp_AssertionStackLevels :: Integer -> SMTInfoResponse
Resp_Authors :: [String] -> SMTInfoResponse
Resp_Error :: SMTErrorBehavior -> SMTInfoResponse
Resp_Name :: String -> SMTInfoResponse
Resp_ReasonUnknown :: SMTReasonUnknown -> SMTInfoResponse
Resp_Version :: String -> SMTInfoResponse
Resp_InfoKeyword :: String -> [String] -> SMTInfoResponse

-- | Ask solver for info.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getInfo</a>
getInfo :: SMTInfoFlag -> Query SMTInfoResponse

-- | Retrieve the value of an 'SMTOption.' The curious function argument is
--   on purpose here, simply pass the constructor name. Example: the call
--   <tt><a>getOption</a> <a>ProduceUnsatCores</a></tt> will return either
--   <tt>Nothing</tt> or <tt>Just (ProduceUnsatCores True)</tt> or <tt>Just
--   (ProduceUnsatCores False)</tt>.
--   
--   Result will be <a>Nothing</a> if the solver does not support this
--   option.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getOption</a>
getOption :: (a -> SMTOption) -> Query (Maybe SMTOption)

-- | The current assertion stack depth, i.e., #push - #pops after start.
--   Always non-negative.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>getAssertionStackDepth</a>
getAssertionStackDepth :: Query Int

-- | Push the context, entering a new one. Pushes multiple levels if
--   <i>n</i> &gt; 1.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>push</a>
push :: Int -> Query ()

-- | Pop the context, exiting a new one. Pops multiple levels if <i>n</i>
--   &gt; 1. It's an error to pop levels that don't exist.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>pop</a>
pop :: Int -> Query ()

-- | Run the query in a new assertion stack. That is, we push the context,
--   run the query commands, and pop it back.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>inNewAssertionStack</a>
inNewAssertionStack :: Query a -> Query a

-- | Search for a result via a sequence of case-splits, guided by the user.
--   If one of the conditions lead to a satisfiable result, returns
--   <tt>Just</tt> that result. If none of them do, returns
--   <tt>Nothing</tt>. Note that we automatically generate a coverage case
--   and search for it automatically as well. In that latter case, the
--   string returned will be <a>Coverage</a>. The first argument controls
--   printing progress messages See
--   <a>Documentation.SBV.Examples.Queries.CaseSplit</a> for an example use
--   case.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>caseSplit</a>
caseSplit :: Bool -> [(String, SBool)] -> Query (Maybe (String, SMTResult))

-- | Reset the solver, by forgetting all the assertions. However, bindings
--   are kept as is, as opposed to a full reset of the solver. Use this
--   variant to clean-up the solver state while leaving the bindings
--   intact. Pops all assertion levels. Declarations and definitions
--   resulting from the <a>setLogic</a> command are unaffected. Note that
--   SBV implicitly uses global-declarations, so bindings will remain
--   intact.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>resetAssertions</a>
resetAssertions :: Query ()

-- | Make an assignment. The type <a>Assignment</a> is abstract, the result
--   is typically passed to <a>mkSMTResult</a>:
--   
--   <pre>
--   mkSMTResult [ a |-&gt; 332
--               , b |-&gt; 2.3
--               , c |-&gt; True
--               ]
--   </pre>
--   
--   End users should use <a>getModel</a> for automatically constructing
--   models from the current solver state. However, an explicit
--   <a>Assignment</a> might be handy in complex scenarios where a model
--   needs to be created manually.
(|->) :: SymVal a => SBV a -> a -> Assignment
infix 1 |->

-- | Produce the query result from an assignment.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>mkSMTResult</a>
mkSMTResult :: [Assignment] -> Query SMTResult

-- | Exit the solver. This action will cause the solver to terminate.
--   Needless to say, trying to communicate with the solver after issuing
--   "exit" will simply fail.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>exit</a>
exit :: Query ()

-- | If true, we shall ignore the exit code upon exit. Otherwise we require
--   ExitSuccess.
ignoreExitCode :: SMTConfig -> Bool

-- | Timeout a query action, typically a command call to the underlying SMT
--   solver. The duration is in microseconds (<tt>1/10^6</tt> seconds). If
--   the duration is negative, then no timeout is imposed. When specifying
--   long timeouts, be careful not to exceed <tt>maxBound :: Int</tt>. (On
--   a 64 bit machine, this bound is practically infinite. But on a 32 bit
--   machine, it corresponds to about 36 minutes!)
--   
--   Semantics: The call <tt>timeout n q</tt> causes the timeout value to
--   be applied to all interactive calls that take place as we execute the
--   query <tt>q</tt>. That is, each call that happens during the execution
--   of <tt>q</tt> gets a separate time-out value, as opposed to one
--   timeout value that limits the whole query. This is typically the
--   intended behavior. It is advisable to apply this combinator to calls
--   that involve a single call to the solver for finer control, as opposed
--   to an entire set of interactions. However, different use cases might
--   call for different scenarios.
--   
--   If the solver responds within the time-out specified, then we continue
--   as usual. However, if the backend solver times-out using this
--   mechanism, there is no telling what the state of the solver will be.
--   Thus, we raise an error in this case.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>timeout</a>
timeout :: Int -> Query a -> Query a

-- | If <a>verbose</a> is <a>True</a>, print the message, useful for
--   debugging messages in custom queries. Note that <a>redirectVerbose</a>
--   will be respected: If a file redirection is given, the output will go
--   to the file.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>queryDebug</a>
queryDebug :: [String] -> Query ()

-- | Echo a string. Note that the echoing is done by the solver, not by
--   SBV.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>echo</a>
echo :: String -> Query ()

-- | Perform an arbitrary IO action.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>io</a>
io :: IO a -> Query a

-- | Option values that can be set in the solver, following the SMTLib
--   specification <a>http://smtlib.cs.uiowa.edu/language.shtml</a>.
--   
--   Note that not all solvers may support all of these!
--   
--   Furthermore, SBV doesn't support the following options allowed by
--   SMTLib.
--   
--   <ul>
--   <li><tt>:interactive-mode</tt> (Deprecated in SMTLib, use
--   <a>ProduceAssertions</a> instead.)</li>
--   <li><tt>:print-success</tt> (SBV critically needs this to be True in
--   query mode.)</li>
--   <li><tt>:produce-models</tt> (SBV always sets this option so it can
--   extract models.)</li>
--   <li><tt>:regular-output-channel</tt> (SBV always requires regular
--   output to come on stdout for query purposes.)</li>
--   <li><tt>:global-declarations</tt> (SBV always uses global declarations
--   since definitions are accumulative.)</li>
--   </ul>
--   
--   Note that <a>SetLogic</a> and <a>SetInfo</a> are, strictly speaking,
--   not SMTLib options. However, we treat it as such here uniformly, as it
--   fits better with how options work.
data SMTOption
DiagnosticOutputChannel :: FilePath -> SMTOption
ProduceAssertions :: Bool -> SMTOption
ProduceAssignments :: Bool -> SMTOption
ProduceProofs :: Bool -> SMTOption
ProduceInterpolants :: Bool -> SMTOption
ProduceUnsatAssumptions :: Bool -> SMTOption
ProduceUnsatCores :: Bool -> SMTOption
ProduceAbducts :: Bool -> SMTOption
RandomSeed :: Integer -> SMTOption
ReproducibleResourceLimit :: Integer -> SMTOption
SMTVerbosity :: Integer -> SMTOption
OptionKeyword :: String -> [String] -> SMTOption
SetLogic :: Logic -> SMTOption
SetInfo :: String -> [String] -> SMTOption


-- | Code-generation from SBV programs.
module Data.SBV.Tools.CodeGen

-- | The code-generation monad. Allows for precise layout of input values
--   reference parameters (for returning composite values in languages such
--   as C), and return values.
data SBVCodeGen a

-- | Reach into symbolic monad from code-generation
cgSym :: Symbolic a -> SBVCodeGen a

-- | Sets RTC (run-time-checks) for index-out-of-bounds, shift-with-large
--   value etc. on/off. Default: <a>False</a>.
cgPerformRTCs :: Bool -> SBVCodeGen ()

-- | Sets driver program run time values, useful for generating programs
--   with fixed drivers for testing. Default: None, i.e., use random
--   values.
cgSetDriverValues :: [Integer] -> SBVCodeGen ()

-- | Should we generate a driver program? Default: <a>True</a>. When a
--   library is generated, it will have a driver if any of the constituent
--   functions has a driver. (See <a>compileToCLib</a>.)
cgGenerateDriver :: Bool -> SBVCodeGen ()

-- | Should we generate a Makefile? Default: <a>True</a>.
cgGenerateMakefile :: Bool -> SBVCodeGen ()

-- | If passed <a>True</a>, then we will not ask the user if we're
--   overwriting files as we generate the C code. Otherwise, we'll prompt.
cgOverwriteFiles :: Bool -> SBVCodeGen ()

-- | If passed <a>True</a>, then we will show 'SWord 8' type in hex.
--   Otherwise we'll show it in decimal. All signed types are shown
--   decimal, and all unsigned larger types are shown hexadecimal
--   otherwise.
cgShowU8UsingHex :: Bool -> SBVCodeGen ()

-- | Creates an atomic input in the generated code.
cgInput :: SymVal a => String -> SBVCodeGen (SBV a)

-- | Creates an array input in the generated code.
cgInputArr :: SymVal a => Int -> String -> SBVCodeGen [SBV a]

-- | Creates an atomic output in the generated code.
cgOutput :: String -> SBV a -> SBVCodeGen ()

-- | Creates an array output in the generated code.
cgOutputArr :: SymVal a => String -> [SBV a] -> SBVCodeGen ()

-- | Creates a returned (unnamed) value in the generated code.
cgReturn :: SBV a -> SBVCodeGen ()

-- | Creates a returned (unnamed) array value in the generated code.
cgReturnArr :: SymVal a => [SBV a] -> SBVCodeGen ()

-- | Adds the given lines to the header file generated, useful for
--   generating programs with uninterpreted functions.
cgAddPrototype :: [String] -> SBVCodeGen ()

-- | Adds the given lines to the program file generated, useful for
--   generating programs with uninterpreted functions.
cgAddDecl :: [String] -> SBVCodeGen ()

-- | Adds the given words to the compiler options in the generated
--   Makefile, useful for linking extra stuff in.
cgAddLDFlags :: [String] -> SBVCodeGen ()

-- | Ignore assertions (those generated by <a>sAssert</a> calls) in the
--   generated C code
cgIgnoreSAssert :: Bool -> SBVCodeGen ()

-- | Sets number of bits to be used for representing the <a>SInteger</a>
--   type in the generated C code. The argument must be one of <tt>8</tt>,
--   <tt>16</tt>, <tt>32</tt>, or <tt>64</tt>. Note that this is
--   essentially unsafe as the semantics of unbounded Haskell integers
--   becomes reduced to the corresponding bit size, as typical in most C
--   implementations.
cgIntegerSize :: Int -> SBVCodeGen ()

-- | Sets the C type to be used for representing the <a>SReal</a> type in
--   the generated C code. The setting can be one of C's <tt>"float"</tt>,
--   <tt>"double"</tt>, or <tt>"long double"</tt>, types, depending on the
--   precision needed. Note that this is essentially unsafe as the
--   semantics of infinite precision SReal values becomes reduced to the
--   corresponding floating point type in C, and hence it is subject to
--   rounding errors.
cgSRealType :: CgSRealType -> SBVCodeGen ()

-- | Possible mappings for the <a>SReal</a> type when translated to C. Used
--   in conjunction with the function <a>cgSRealType</a>. Note that the
--   particular characteristics of the mapped types depend on the platform
--   and the compiler used for compiling the generated C program. See
--   <a>http://en.wikipedia.org/wiki/C_data_types</a> for details.
data CgSRealType

-- | <pre>
--   float
--   </pre>
CgFloat :: CgSRealType

-- | <pre>
--   double
--   </pre>
CgDouble :: CgSRealType

-- | <pre>
--   long double
--   </pre>
CgLongDouble :: CgSRealType

-- | Given a symbolic computation, render it as an equivalent collection of
--   files that make up a C program:
--   
--   <ul>
--   <li>The first argument is the directory name under which the files
--   will be saved. To save files in the current directory pass
--   <tt><a>Just</a> "."</tt>. Use <a>Nothing</a> for printing to
--   stdout.</li>
--   <li>The second argument is the name of the C function to
--   generate.</li>
--   <li>The final argument is the function to be compiled.</li>
--   </ul>
--   
--   Compilation will also generate a <tt>Makefile</tt>, a header file, and
--   a driver (test) program, etc. As a result, we return whatever the
--   code-gen function returns. Most uses should simply have <tt>()</tt> as
--   the return type here, but the value can be useful if you want to chain
--   the result of one compilation act to the next.
compileToC :: Maybe FilePath -> String -> SBVCodeGen a -> IO a

-- | Create code to generate a library archive (.a) from given symbolic
--   functions. Useful when generating code from multiple functions that
--   work together as a library.
--   
--   <ul>
--   <li>The first argument is the directory name under which the files
--   will be saved. To save files in the current directory pass
--   <tt><a>Just</a> "."</tt>. Use <a>Nothing</a> for printing to
--   stdout.</li>
--   <li>The second argument is the name of the archive to generate.</li>
--   <li>The third argument is the list of functions to include, in the
--   form of function-name/code pairs, similar to the second and third
--   arguments of <a>compileToC</a>, except in a list.</li>
--   </ul>
compileToCLib :: Maybe FilePath -> String -> [(String, SBVCodeGen a)] -> IO [a]


-- | Low level functions to access the SBV infrastructure, for developers
--   who want to build further tools on top of SBV. End-users of the
--   library should not need to use this module.
--   
--   NB. There are various coding invariants in SBV that are maintained
--   throughout the code. Indiscriminate use of functions in this module
--   can break those invariants. So, you are on your own if you do utilize
--   the functions here. (Unfortunately, what exactly those invariants are
--   is a very good but also a very difficult question to answer!)
module Data.SBV.Internals

-- | Result of running a symbolic computation
data Result
Result :: ProgInfo -> Set Kind -> [(String, CV)] -> [(String, CV -> Bool, SV)] -> [(String, [String])] -> ResultInp -> (CnstMap, [(SV, CV)]) -> [((Int, Kind, Kind), [SV])] -> [(Int, ArrayInfo)] -> [(String, (Maybe [String], SBVType))] -> [SMTDef] -> SBVPgm -> Seq (Bool, [(String, String)], SV) -> [(String, Maybe CallStack, SV)] -> [SV] -> Result

-- | various info we collect about the program
[progInfo] :: Result -> ProgInfo

-- | kinds used in the program
[reskinds] :: Result -> Set Kind

-- | quick-check counter-example information (if any)
[resTraces] :: Result -> [(String, CV)]

-- | observable expressions (part of the model)
[resObservables] :: Result -> [(String, CV -> Bool, SV)]

-- | uninterpeted code segments
[resUISegs] :: Result -> [(String, [String])]

-- | top-inputs or lambda params
[resParams] :: Result -> ResultInp

-- | constants
[resConsts] :: Result -> (CnstMap, [(SV, CV)])

-- | tables (automatically constructed) (tableno, index-type, result-type)
--   elts
[resTables] :: Result -> [((Int, Kind, Kind), [SV])]

-- | arrays (user specified)
[resArrays] :: Result -> [(Int, ArrayInfo)]

-- | uninterpreted constants
[resUIConsts] :: Result -> [(String, (Maybe [String], SBVType))]

-- | definitions created via smtFunction or lambda
[resDefinitions] :: Result -> [SMTDef]

-- | assignments
[resAsgns] :: Result -> SBVPgm

-- | additional constraints (boolean)
[resConstraints] :: Result -> Seq (Bool, [(String, String)], SV)

-- | assertions
[resAssertions] :: Result -> [(String, Maybe CallStack, SV)]

-- | outputs
[resOutputs] :: Result -> [SV]

-- | Different means of running a symbolic piece of code
data SBVRunMode

-- | In regular mode, with a stage. Bool is True if this is SAT.
SMTMode :: QueryContext -> IStage -> Bool -> SMTConfig -> SBVRunMode

-- | Code generation mode.
CodeGen :: SBVRunMode

-- | Inside a lambda-expression at level
LambdaGen :: Int -> SBVRunMode

-- | Concrete simulation mode, with given environment if any. If Nothing:
--   Random.
Concrete :: Maybe (Bool, [(NamedSymVar, CV)]) -> SBVRunMode

-- | Stage of an interactive run
data IStage
ISetup :: IStage
ISafe :: IStage
IRun :: IStage

-- | Query execution context
data QueryContext

-- | Triggered from inside SBV
QueryInternal :: QueryContext

-- | Triggered from user code
QueryExternal :: QueryContext

-- | Which context is this variable being created?
data VarContext
NonQueryVar :: Maybe Quantifier -> VarContext
QueryVar :: VarContext

-- | Create a new state
mkNewState :: MonadIO m => SMTConfig -> SBVRunMode -> m State

-- | Translation tricks needed for specific capabilities afforded by each
--   solver
data SolverCapabilities
SolverCapabilities :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe String -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe [String] -> SolverCapabilities

-- | Supports SMT-Lib2 style quantifiers?
[supportsQuantifiers] :: SolverCapabilities -> Bool

-- | Supports define-fun construct?
[supportsDefineFun] :: SolverCapabilities -> Bool

-- | Supports calls to distinct?
[supportsDistinct] :: SolverCapabilities -> Bool

-- | Supports bit-vectors?
[supportsBitVectors] :: SolverCapabilities -> Bool

-- | Supports SMT-Lib2 style uninterpreted-sorts
[supportsUninterpretedSorts] :: SolverCapabilities -> Bool

-- | Supports unbounded integers?
[supportsUnboundedInts] :: SolverCapabilities -> Bool

-- | Supports int2bv?
[supportsInt2bv] :: SolverCapabilities -> Bool

-- | Supports reals?
[supportsReals] :: SolverCapabilities -> Bool

-- | Supports printing of approximations of reals?
[supportsApproxReals] :: SolverCapabilities -> Bool

-- | Supports delta-satisfiability? (With given precision query)
[supportsDeltaSat] :: SolverCapabilities -> Maybe String

-- | Supports floating point numbers?
[supportsIEEE754] :: SolverCapabilities -> Bool

-- | Supports set operations?
[supportsSets] :: SolverCapabilities -> Bool

-- | Supports optimization routines?
[supportsOptimization] :: SolverCapabilities -> Bool

-- | Supports pseudo-boolean operations?
[supportsPseudoBooleans] :: SolverCapabilities -> Bool

-- | Supports interactive queries per SMT-Lib?
[supportsCustomQueries] :: SolverCapabilities -> Bool

-- | Supports global declarations? (Needed for push-pop.)
[supportsGlobalDecls] :: SolverCapabilities -> Bool

-- | Supports datatypes?
[supportsDataTypes] :: SolverCapabilities -> Bool

-- | Does it support fold and map?
[supportsFoldAndMap] :: SolverCapabilities -> Bool

-- | Does it support special relations (orders, transitive closure etc.)
[supportsSpecialRels] :: SolverCapabilities -> Bool

-- | Supports data-type accessors without full ascription?
[supportsDirectAccessors] :: SolverCapabilities -> Bool

-- | Supports flattened model output? (With given config lines.)
[supportsFlattenedModels] :: SolverCapabilities -> Maybe [String]

-- | Result of running a symbolic computation
data Result
Result :: ProgInfo -> Set Kind -> [(String, CV)] -> [(String, CV -> Bool, SV)] -> [(String, [String])] -> ResultInp -> (CnstMap, [(SV, CV)]) -> [((Int, Kind, Kind), [SV])] -> [(Int, ArrayInfo)] -> [(String, (Maybe [String], SBVType))] -> [SMTDef] -> SBVPgm -> Seq (Bool, [(String, String)], SV) -> [(String, Maybe CallStack, SV)] -> [SV] -> Result

-- | various info we collect about the program
[progInfo] :: Result -> ProgInfo

-- | kinds used in the program
[reskinds] :: Result -> Set Kind

-- | quick-check counter-example information (if any)
[resTraces] :: Result -> [(String, CV)]

-- | observable expressions (part of the model)
[resObservables] :: Result -> [(String, CV -> Bool, SV)]

-- | uninterpeted code segments
[resUISegs] :: Result -> [(String, [String])]

-- | top-inputs or lambda params
[resParams] :: Result -> ResultInp

-- | constants
[resConsts] :: Result -> (CnstMap, [(SV, CV)])

-- | tables (automatically constructed) (tableno, index-type, result-type)
--   elts
[resTables] :: Result -> [((Int, Kind, Kind), [SV])]

-- | arrays (user specified)
[resArrays] :: Result -> [(Int, ArrayInfo)]

-- | uninterpreted constants
[resUIConsts] :: Result -> [(String, (Maybe [String], SBVType))]

-- | definitions created via smtFunction or lambda
[resDefinitions] :: Result -> [SMTDef]

-- | assignments
[resAsgns] :: Result -> SBVPgm

-- | additional constraints (boolean)
[resConstraints] :: Result -> Seq (Bool, [(String, String)], SV)

-- | assertions
[resAssertions] :: Result -> [(String, Maybe CallStack, SV)]

-- | outputs
[resOutputs] :: Result -> [SV]

-- | The state of the symbolic interpreter
data State

-- | Values that we can turn into a constraint
class MonadSymbolic m => Constraint m a
mkConstraint :: Constraint m a => State -> a -> m ()

-- | Symbolic operations
data Op
Plus :: Op
Times :: Op
Minus :: Op
UNeg :: Op
Abs :: Op
Quot :: Op
Rem :: Op
Equal :: Op
Implies :: Op
NotEqual :: Op
LessThan :: Op
GreaterThan :: Op
LessEq :: Op
GreaterEq :: Op
Ite :: Op
And :: Op
Or :: Op
XOr :: Op
Not :: Op
Shl :: Op
Shr :: Op
Rol :: Int -> Op
Ror :: Int -> Op
Extract :: Int -> Int -> Op
Join :: Op
ZeroExtend :: Int -> Op
SignExtend :: Int -> Op
LkUp :: (Int, Kind, Kind, Int) -> !SV -> !SV -> Op
ArrEq :: ArrayIndex -> ArrayIndex -> Op
ArrRead :: ArrayIndex -> Op
KindCast :: Kind -> Kind -> Op
Uninterpreted :: String -> Op
QuantifiedBool :: String -> Op
SpecialRelOp :: Kind -> SpecialRelOp -> Op
Label :: String -> Op
IEEEFP :: FPOp -> Op
NonLinear :: NROp -> Op
OverflowOp :: OvOp -> Op
PseudoBoolean :: PBOp -> Op
RegExOp :: RegExOp -> Op
StrOp :: StrOp -> Op
SeqOp :: SeqOp -> Op
SetOp :: SetOp -> Op
TupleConstructor :: Int -> Op
TupleAccess :: Int -> Int -> Op
EitherConstructor :: Kind -> Kind -> Bool -> Op
EitherIs :: Kind -> Kind -> Bool -> Op
EitherAccess :: Bool -> Op
RationalConstructor :: Op
MaybeConstructor :: Kind -> Bool -> Op
MaybeIs :: Kind -> Bool -> Op
MaybeAccess :: Op

-- | Kind of symbolic value
data Kind
KBool :: Kind
KBounded :: !Bool -> !Int -> Kind
KUnbounded :: Kind
KReal :: Kind
KUserSort :: String -> Maybe [String] -> Kind
KFloat :: Kind
KDouble :: Kind
KFP :: !Int -> !Int -> Kind
KChar :: Kind
KString :: Kind
KList :: Kind -> Kind
KSet :: Kind -> Kind
KTuple :: [Kind] -> Kind
KMaybe :: Kind -> Kind
KRational :: Kind
KEither :: Kind -> Kind -> Kind

-- | A symbolic boolean/bit
type SBool = SBV Bool

-- | The <a>Symbolic</a> value. The parameter <tt>a</tt> is phantom, but is
--   extremely important in keeping the user interface strongly typed.
newtype SBV a
SBV :: SVal -> SBV a
[unSBV] :: SBV a -> SVal

-- | 8-bit unsigned symbolic value
type SWord8 = SBV Word8

-- | 16-bit unsigned symbolic value
type SWord16 = SBV Word16

-- | 32-bit unsigned symbolic value
type SWord32 = SBV Word32

-- | 64-bit unsigned symbolic value
type SWord64 = SBV Word64

-- | 8-bit signed symbolic value, 2's complement representation
type SInt8 = SBV Int8

-- | 16-bit signed symbolic value, 2's complement representation
type SInt16 = SBV Int16

-- | 32-bit signed symbolic value, 2's complement representation
type SInt32 = SBV Int32

-- | 64-bit signed symbolic value, 2's complement representation
type SInt64 = SBV Int64

-- | Infinite precision signed symbolic value
type SInteger = SBV Integer

-- | IEEE-754 single-precision floating point numbers
type SFloat = SBV Float

-- | IEEE-754 double-precision floating point numbers
type SDouble = SBV Double

-- | A symbolic arbitrary precision floating point value
type SFloatingPoint (eb :: Nat) (sb :: Nat) = SBV (FloatingPoint eb sb)

-- | A symbolic half-precision float
type SFPHalf = SBV FPHalf

-- | A symbolic brain-float precision float
type SFPBFloat = SBV FPBFloat

-- | A symbolic single-precision float
type SFPSingle = SBV FPSingle

-- | A symbolic double-precision float
type SFPDouble = SBV FPDouble

-- | A symbolic quad-precision float
type SFPQuad = SBV FPQuad

-- | A symbolic rational value.
type SRational = SBV Rational

-- | Infinite precision symbolic algebraic real value
type SReal = SBV AlgReal

-- | Algebraic reals. Note that the representation is left abstract. We
--   represent rational results explicitly, while the roots-of-polynomials
--   are represented implicitly by their defining equation
data AlgReal

-- | bool says it's exact (i.e., SMT-solver did not return it with ? at the
--   end.)
AlgRational :: Bool -> Rational -> AlgReal

-- | which root of this polynomial and an approximate decimal
--   representation with given precision, if available
AlgPolyRoot :: (Integer, AlgRealPoly) -> Maybe String -> AlgReal

-- | interval, with low and high bounds
AlgInterval :: RealPoint Rational -> RealPoint Rational -> AlgReal

-- | A symbolic character. Note that this is the full unicode character
--   set. see:
--   <a>http://smtlib.cs.uiowa.edu/theories-UnicodeStrings.shtml</a> for
--   details.
type SChar = SBV Char

-- | A symbolic string. Note that a symbolic string is <i>not</i> a list of
--   symbolic characters, that is, it is not the case that <tt>SString =
--   [SChar]</tt>, unlike what one might expect following Haskell strings.
--   An <a>SString</a> is a symbolic value of its own, of possibly
--   arbitrary but finite length, and internally processed as one unit as
--   opposed to a fixed-length list of characters.
type SString = SBV String

-- | A symbolic list of items. Note that a symbolic list is <i>not</i> a
--   list of symbolic items, that is, it is not the case that <tt>SList a =
--   [a]</tt>, unlike what one might expect following haskell
--   lists/sequences. An <a>SList</a> is a symbolic value of its own, of
--   possibly arbitrary but finite length, and internally processed as one
--   unit as opposed to a fixed-length list of items. Note that lists can
--   be nested, i.e., we do allow lists of lists of ... items.
type SList a = SBV [a]

-- | Symbolic 2-tuple. NB. <a>STuple</a> and <a>STuple2</a> are equivalent.
type STuple a b = SBV (a, b)

-- | Symbolic 2-tuple. NB. <a>STuple</a> and <a>STuple2</a> are equivalent.
type STuple2 a b = SBV (a, b)

-- | Symbolic 3-tuple.
type STuple3 a b c = SBV (a, b, c)

-- | Symbolic 4-tuple.
type STuple4 a b c d = SBV (a, b, c, d)

-- | Symbolic 5-tuple.
type STuple5 a b c d e = SBV (a, b, c, d, e)

-- | Symbolic 6-tuple.
type STuple6 a b c d e f = SBV (a, b, c, d, e, f)

-- | Symbolic 7-tuple.
type STuple7 a b c d e f g = SBV (a, b, c, d, e, f, g)

-- | Symbolic 8-tuple.
type STuple8 a b c d e f g h = SBV (a, b, c, d, e, f, g, h)

-- | Symbolic <a>Maybe</a>
type SMaybe a = SBV (Maybe a)

-- | Symbolic <a>Either</a>
type SEither a b = SBV (Either a b)

-- | A <a>RCSet</a> is either a regular set or a set given by its
--   complement from the corresponding universal set.
data RCSet a
RegularSet :: Set a -> RCSet a
ComplementSet :: Set a -> RCSet a

-- | Symbolic <a>Set</a>. Note that we use <a>RCSet</a>, which supports
--   both regular sets and complements, i.e., those obtained from the
--   universal set (of the right type) by removing elements.
type SSet a = SBV (RCSet a)

-- | Arrays of symbolic values An <tt>array a b</tt> is an array indexed by
--   the type <tt><a>SBV</a> a</tt>, with elements of type <tt><a>SBV</a>
--   b</tt>.
--   
--   If a default value is supplied, then all the array elements will be
--   initialized to this value. Otherwise, they will be left unspecified,
--   i.e., a read from an unwritten location will produce an uninterpreted
--   constant.
--   
--   The reason for this class is rather historic. In the past, SBV
--   provided two different kinds of arrays: an <a>SArray</a> abstraction
--   that mapped directly to SMTLib arrays (which is still available
--   today), and a functional notion of arrays that used internal caching,
--   called <tt>SFunArray</tt>. The latter has been removed as the code
--   turned out to be rather tricky and hard to maintain; so we only have
--   one instance of this class. But end users can add their own instances,
--   if needed.
--   
--   NB. <a>sListArray</a> insists on a concrete initializer, because not
--   having one would break referential transparency. See
--   <a>https://github.com/LeventErkok/sbv/issues/553</a> for details.
class SymArray array

-- | Generalization of <a>newArray_</a>
newArray_ :: (SymArray array, MonadSymbolic m, HasKind a, HasKind b) => Maybe (SBV b) -> m (array a b)

-- | Generalization of <a>newArray</a>
newArray :: (SymArray array, MonadSymbolic m, HasKind a, HasKind b) => String -> Maybe (SBV b) -> m (array a b)

-- | Create a literal array
sListArray :: (SymArray array, HasKind a, SymVal b) => b -> [(SBV a, SBV b)] -> array a b

-- | Read the array element at <tt>a</tt>
readArray :: SymArray array => array a b -> SBV a -> SBV b

-- | Update the element at <tt>a</tt> to be <tt>b</tt>
writeArray :: (SymArray array, SymVal b) => array a b -> SBV a -> SBV b -> array a b

-- | Merge two given arrays on the symbolic condition Intuitively:
--   <tt>mergeArrays cond a b = if cond then a else b</tt>. Merging pushes
--   the if-then-else choice down on to elements
mergeArrays :: (SymArray array, SymVal b) => SBV Bool -> array a b -> array a b -> array a b

-- | Internal function, not exported to the user
newArrayInState :: (SymArray array, HasKind a, HasKind b) => Maybe String -> Either (Maybe (SBV b)) String -> State -> IO (array a b)

-- | Arrays implemented in terms of SMT-arrays:
--   <a>http://smtlib.cs.uiowa.edu/theories-ArraysEx.shtml</a>
--   
--   <ul>
--   <li>Maps directly to SMT-lib arrays</li>
--   <li>Reading from an uninitialized value is OK. If the default value is
--   given in <a>newArray</a>, it will be the result. Otherwise, the read
--   yields an uninterpreted constant.</li>
--   <li>Can check for equality of these arrays</li>
--   <li>Cannot be used in code-generation (i.e., compilation to C)</li>
--   <li>Cannot quick-check theorems using <tt>SArray</tt> values</li>
--   </ul>
newtype SArray a b
SArray :: SArr -> SArray a b
[unSArray] :: SArray a b -> SArr

-- | Symbolic Equality. Note that we can't use Haskell's <a>Eq</a> class
--   since Haskell insists on returning Bool Comparing symbolic values will
--   necessarily return a symbolic value.
--   
--   Minimal complete definition: None, if the type is instance of
--   <tt>Generic</tt>. Otherwise <a>(.==)</a>.
class EqSymbolic a

-- | Symbolic equality.
(.==) :: EqSymbolic a => a -> a -> SBool

-- | Symbolic inequality.
(./=) :: EqSymbolic a => a -> a -> SBool

-- | Strong equality. On floats (<a>SFloat</a>/<a>SDouble</a>), strong
--   equality is object equality; that is <tt>NaN == NaN</tt> holds, but
--   <tt>+0 == -0</tt> doesn't. On other types, (.===) is simply (.==).
--   Note that (.==) is the <i>right</i> notion of equality for floats per
--   IEEE754 specs, since by definition <tt>+0 == -0</tt> and <tt>NaN</tt>
--   equals no other value including itself. But occasionally we want to be
--   stronger and state <tt>NaN</tt> equals <tt>NaN</tt> and <tt>+0</tt>
--   and <tt>-0</tt> are different from each other. In a context where your
--   type is concrete, simply use <a>fpIsEqualObject</a>. But in a
--   polymorphic context, use the strong equality instead.
--   
--   NB. If you do not care about or work with floats, simply use (.==) and
--   (./=).
(.===) :: EqSymbolic a => a -> a -> SBool

-- | Negation of strong equality. Equaivalent to negation of (.===) on all
--   types.
(./==) :: EqSymbolic a => a -> a -> SBool

-- | Returns (symbolic) <a>sTrue</a> if all the elements of the given list
--   are different.
distinct :: EqSymbolic a => [a] -> SBool

-- | Returns (symbolic) <a>sTrue</a> if all the elements of the given list
--   are different. The second list contains exceptions, i.e., if an
--   element belongs to that set, it will be considered distinct regardless
--   of repetition.
distinctExcept :: EqSymbolic a => [a] -> [a] -> SBool

-- | Returns (symbolic) <a>sTrue</a> if all the elements of the given list
--   are the same.
allEqual :: EqSymbolic a => [a] -> SBool

-- | Symbolic membership test.
sElem :: EqSymbolic a => a -> [a] -> SBool

-- | Symbolic negated membership test.
sNotElem :: EqSymbolic a => a -> [a] -> SBool

-- | Symbolic equality.
(.==) :: (EqSymbolic a, Generic a, GEqSymbolic (Rep a)) => a -> a -> SBool
infix 4 ./==
infix 4 .===
infix 4 .==
infix 4 ./=

-- | Rounding mode to be used for the IEEE floating-point operations. Note
--   that Haskell's default is <a>RoundNearestTiesToEven</a>. If you use a
--   different rounding mode, then the counter-examples you get may not
--   match what you observe in Haskell.
data RoundingMode

-- | Round to nearest representable floating point value. If precisely at
--   half-way, pick the even number. (In this context, <i>even</i> means
--   the lowest-order bit is zero.)
RoundNearestTiesToEven :: RoundingMode

-- | Round to nearest representable floating point value. If precisely at
--   half-way, pick the number further away from 0. (That is, for positive
--   values, pick the greater; for negative values, pick the smaller.)
RoundNearestTiesToAway :: RoundingMode

-- | Round towards positive infinity. (Also known as rounding-up or
--   ceiling.)
RoundTowardPositive :: RoundingMode

-- | Round towards negative infinity. (Also known as rounding-down or
--   floor.)
RoundTowardNegative :: RoundingMode

-- | Round towards zero. (Also known as truncation.)
RoundTowardZero :: RoundingMode

-- | The symbolic variant of <a>RoundingMode</a>
type SRoundingMode = SBV RoundingMode

-- | A value that can be used as a quantified boolean
class QuantifiedBool a

-- | Turn a quantified boolean into a regular boolean. That is, this
--   function turns an exists/forall quantified formula to a simple boolean
--   that can be used as a regular boolean value. An example is:
--   
--   <pre>
--   quantifiedBool $ \(Forall x) (Exists y) -&gt; y .&gt; (x :: SInteger)
--   </pre>
--   
--   is equivalent to <a>sTrue</a>. You can think of this function as
--   performing quantifier-elimination: It takes a quantified formula, and
--   reduces it to a simple boolean that is equivalent to it, but has no
--   quantifiers.
quantifiedBool :: QuantifiedBool a => a -> SBool

-- | Style of optimization. Note that in the pareto case the user is
--   allowed to specify a max number of fronts to query the solver for,
--   since there might potentially be an infinite number of them and there
--   is no way to know exactly how many ahead of time. If <a>Nothing</a> is
--   given, SBV will possibly loop forever if the number is really
--   infinite.
data OptimizeStyle

-- | Objectives are optimized in the order given, earlier objectives have
--   higher priority.
Lexicographic :: OptimizeStyle

-- | Each objective is optimized independently.
Independent :: OptimizeStyle

-- | Objectives are optimized according to pareto front: That is, no
--   objective can be made better without making some other worse.
Pareto :: Maybe Int -> OptimizeStyle

-- | Objective of optimization. We can minimize, maximize, or give a soft
--   assertion with a penalty for not satisfying it.
data Objective a

-- | Minimize this metric
Minimize :: String -> a -> Objective a

-- | Maximize this metric
Maximize :: String -> a -> Objective a

-- | A soft assertion, with an associated penalty
AssertWithPenalty :: String -> a -> Penalty -> Objective a

-- | Penalty for a soft-assertion. The default penalty is <tt>1</tt>, with
--   all soft-assertions belonging to the same objective goal. A positive
--   weight and an optional group can be provided by using the
--   <a>Penalty</a> constructor.
data Penalty

-- | Default: Penalty of <tt>1</tt> and no group attached
DefaultPenalty :: Penalty

-- | Penalty with a weight and an optional group
Penalty :: Rational -> Maybe String -> Penalty

-- | A simple expression type over extended values, covering infinity,
--   epsilon and intervals.
data ExtCV
Infinite :: Kind -> ExtCV
Epsilon :: Kind -> ExtCV
Interval :: ExtCV -> ExtCV -> ExtCV
BoundedCV :: CV -> ExtCV
AddExtCV :: ExtCV -> ExtCV -> ExtCV
MulExtCV :: ExtCV -> ExtCV -> ExtCV

-- | A generalized CV allows for expressions involving infinite and epsilon
--   values/intervals Used in optimization problems.
data GeneralizedCV
ExtendedCV :: ExtCV -> GeneralizedCV
RegularCV :: CV -> GeneralizedCV

-- | The result of an SMT solver call. Each constructor is tagged with the
--   <a>SMTConfig</a> that created it so that further tools can inspect it
--   and build layers of results, if needed. For ordinary uses of the
--   library, this type should not be needed, instead use the accessor
--   functions on it. (Custom Show instances and model extractors.)
data SMTResult

-- | Unsatisfiable. If unsat-cores are enabled, they will be returned in
--   the second parameter.
Unsatisfiable :: SMTConfig -> Maybe [String] -> SMTResult

-- | Satisfiable with model
Satisfiable :: SMTConfig -> SMTModel -> SMTResult

-- | Delta satisfiable with queried string if available and model
DeltaSat :: SMTConfig -> Maybe String -> SMTModel -> SMTResult

-- | Prover returned a model, but in an extension field containing
--   Infinite/epsilon
SatExtField :: SMTConfig -> SMTModel -> SMTResult

-- | Prover returned unknown, with the given reason
Unknown :: SMTConfig -> SMTReasonUnknown -> SMTResult

-- | Prover errored out, with possibly a bogus result
ProofError :: SMTConfig -> [String] -> Maybe SMTResult -> SMTResult

-- | Solver configuration. See also <a>z3</a>, <a>yices</a>, <a>cvc4</a>,
--   <a>boolector</a>, <a>mathSAT</a>, etc. which are instantiations of
--   this type for those solvers, with reasonable defaults. In particular,
--   custom configuration can be created by varying those values. (Such as
--   <tt>z3{verbose=True}</tt>.)
--   
--   Most fields are self explanatory. The notion of precision for printing
--   algebraic reals stems from the fact that such values does not
--   necessarily have finite decimal representations, and hence we have to
--   stop printing at some depth. It is important to emphasize that such
--   values always have infinite precision internally. The issue is merely
--   with how we print such an infinite precision value on the screen. The
--   field <a>printRealPrec</a> controls the printing precision, by
--   specifying the number of digits after the decimal point. The default
--   value is 16, but it can be set to any positive integer.
--   
--   When printing, SBV will add the suffix <tt>...</tt> at the end of a
--   real-value, if the given bound is not sufficient to represent the
--   real-value exactly. Otherwise, the number will be written out in
--   standard decimal notation. Note that SBV will always print the whole
--   value if it is precise (i.e., if it fits in a finite number of
--   digits), regardless of the precision limit. The limit only applies if
--   the representation of the real value is not finite, i.e., if it is not
--   rational.
--   
--   The <a>printBase</a> field can be used to print numbers in base 2, 10,
--   or 16.
--   
--   The <a>crackNum</a> field can be used to display numbers in detail,
--   all its bits and how they are laid out in memory. Works with all
--   bounded number types (i.e., SWord and SInt), but also with floats. It
--   is particularly useful with floating-point numbers, as it shows you
--   how they are laid out in memory following the IEEE754 rules.
data SMTConfig
SMTConfig :: Bool -> Timing -> Int -> Int -> Bool -> String -> Maybe Int -> Bool -> Bool -> (String -> Bool) -> Bool -> Bool -> Maybe FilePath -> SMTLibVersion -> Maybe Double -> SMTSolver -> [String] -> RoundingMode -> [SMTOption] -> Bool -> Maybe FilePath -> SMTConfig

-- | Debug mode
[verbose] :: SMTConfig -> Bool

-- | Print timing information on how long different phases took
--   (construction, solving, etc.)
[timing] :: SMTConfig -> Timing

-- | Print integral literals in this base (2, 10, and 16 are supported.)
[printBase] :: SMTConfig -> Int

-- | Print algebraic real values with this precision. (SReal, default: 16)
[printRealPrec] :: SMTConfig -> Int

-- | For each numeric value, show it in detail in the model with its bits
--   spliced out. Good for floats.
[crackNum] :: SMTConfig -> Bool

-- | Usually "(check-sat)". However, users might tweak it based on solver
--   characteristics.
[satCmd] :: SMTConfig -> String

-- | In a <a>allSat</a> call, return at most this many models. If nothing,
--   return all.
[allSatMaxModelCount] :: SMTConfig -> Maybe Int

-- | In a <a>allSat</a> call, print models as they are found.
[allSatPrintAlong] :: SMTConfig -> Bool

-- | In a <a>allSat</a> call, should we try to extract values of
--   uninterpreted functions?
[allSatTrackUFs] :: SMTConfig -> Bool

-- | When constructing a model, ignore variables whose name satisfy this
--   predicate. (Default: (const False), i.e., don't ignore anything)
[isNonModelVar] :: SMTConfig -> String -> Bool

-- | If set, SBV will attempt to validate the model it gets back from the
--   solver.
[validateModel] :: SMTConfig -> Bool

-- | Validate optimization results. NB: Does NOT make sure the model is
--   optimal, just checks they satisfy the constraints.
[optimizeValidateConstraints] :: SMTConfig -> Bool

-- | If Just, the entire interaction will be recorded as a playable file
--   (for debugging purposes mostly)
[transcript] :: SMTConfig -> Maybe FilePath

-- | What version of SMT-lib we use for the tool
[smtLibVersion] :: SMTConfig -> SMTLibVersion

-- | Delta-sat precision
[dsatPrecision] :: SMTConfig -> Maybe Double

-- | The actual SMT solver.
[solver] :: SMTConfig -> SMTSolver

-- | Extra command line arguments to pass to the solver.
[extraArgs] :: SMTConfig -> [String]

-- | Rounding mode to use for floating-point conversions
[roundingMode] :: SMTConfig -> RoundingMode

-- | Options to set as we start the solver
[solverSetOptions] :: SMTConfig -> [SMTOption]

-- | If true, we shall ignore the exit code upon exit. Otherwise we require
--   ExitSuccess.
[ignoreExitCode] :: SMTConfig -> Bool

-- | Redirect the verbose output to this file if given. If Nothing, stdout
--   is implied.
[redirectVerbose] :: SMTConfig -> Maybe FilePath

-- | Representation of SMTLib Program versions. As of June 2015, we're
--   dropping support for SMTLib1, and supporting SMTLib2 only. We keep
--   this data-type around in case SMTLib3 comes along and we want to
--   support 2 and 3 simultaneously.
data SMTLibVersion
SMTLib2 :: SMTLibVersion

-- | Solvers that SBV is aware of
data Solver
ABC :: Solver
Boolector :: Solver
Bitwuzla :: Solver
CVC4 :: Solver
CVC5 :: Solver
DReal :: Solver
MathSAT :: Solver
Yices :: Solver
Z3 :: Solver

-- | An SMT solver
data SMTSolver
SMTSolver :: Solver -> String -> (String -> String) -> (SMTConfig -> [String]) -> SMTEngine -> SolverCapabilities -> SMTSolver

-- | The solver in use
[name] :: SMTSolver -> Solver

-- | The path to its executable
[executable] :: SMTSolver -> String

-- | Each line sent to the solver will be passed through this function
--   (typically id)
[preprocess] :: SMTSolver -> String -> String

-- | Options to provide to the solver
[options] :: SMTSolver -> SMTConfig -> [String]

-- | The solver engine, responsible for interpreting solver output
[engine] :: SMTSolver -> SMTEngine

-- | Various capabilities of the solver
[capabilities] :: SMTSolver -> SolverCapabilities

-- | A class for capturing values that have a sign and a size (finite or
--   infinite) minimal complete definition: kindOf, unless you can take
--   advantage of the default signature: This class can be automatically
--   derived for data-types that have a <a>Data</a> instance; this is
--   useful for creating uninterpreted sorts. So, in reality, end users
--   should almost never need to define any methods.
class HasKind a
kindOf :: HasKind a => a -> Kind
hasSign :: HasKind a => a -> Bool
intSizeOf :: HasKind a => a -> Int
isBoolean :: HasKind a => a -> Bool
isBounded :: HasKind a => a -> Bool
isReal :: HasKind a => a -> Bool
isFloat :: HasKind a => a -> Bool
isDouble :: HasKind a => a -> Bool
isRational :: HasKind a => a -> Bool
isFP :: HasKind a => a -> Bool
isUnbounded :: HasKind a => a -> Bool
isUserSort :: HasKind a => a -> Bool
isChar :: HasKind a => a -> Bool
isString :: HasKind a => a -> Bool
isList :: HasKind a => a -> Bool
isSet :: HasKind a => a -> Bool
isTuple :: HasKind a => a -> Bool
isMaybe :: HasKind a => a -> Bool
isEither :: HasKind a => a -> Bool
showType :: HasKind a => a -> String
kindOf :: (HasKind a, Read a, Data a) => a -> Kind

-- | A <a>SymVal</a> is a potential symbolic value that can be created
--   instances of to be fed to a symbolic program.
class (HasKind a, Typeable a) => SymVal a

-- | Generalization of <a>mkSymVal</a>
mkSymVal :: (SymVal a, MonadSymbolic m) => VarContext -> Maybe String -> m (SBV a)

-- | Turn a literal constant to symbolic
literal :: SymVal a => a -> SBV a

-- | Extract a literal, from a CV representation
fromCV :: SymVal a => CV -> a

-- | Does it concretely satisfy the given predicate?
isConcretely :: SymVal a => SBV a -> (a -> Bool) -> Bool

-- | Generalization of <a>mkSymVal</a>
mkSymVal :: (SymVal a, MonadSymbolic m, Read a, Data a) => VarContext -> Maybe String -> m (SBV a)

-- | Turn a literal constant to symbolic
literal :: (SymVal a, Show a) => a -> SBV a

-- | Extract a literal, from a CV representation
fromCV :: (SymVal a, Read a) => CV -> a

-- | Generalization of <a>free</a>
free :: (SymVal a, MonadSymbolic m) => String -> m (SBV a)

-- | Generalization of <a>free_</a>
free_ :: (SymVal a, MonadSymbolic m) => m (SBV a)

-- | Generalization of <a>mkFreeVars</a>
mkFreeVars :: (SymVal a, MonadSymbolic m) => Int -> m [SBV a]

-- | Generalization of <a>symbolic</a>
symbolic :: (SymVal a, MonadSymbolic m) => String -> m (SBV a)

-- | Generalization of <a>symbolics</a>
symbolics :: (SymVal a, MonadSymbolic m) => [String] -> m [SBV a]

-- | Extract a literal, if the value is concrete
unliteral :: SymVal a => SBV a -> Maybe a

-- | Is the symbolic word concrete?
isConcrete :: SymVal a => SBV a -> Bool

-- | Is the symbolic word really symbolic?
isSymbolic :: SymVal a => SBV a -> Bool

-- | <a>Symbolic</a> is specialization of <a>SymbolicT</a> to the <a>IO</a>
--   monad. Unless you are using transformers explicitly, this is the type
--   you should prefer.
type Symbolic = SymbolicT IO

-- | The <a>Symbolic</a> value. Either a constant (<tt>Left</tt>) or a
--   symbolic value (<tt>Right Cached</tt>). Note that caching is essential
--   for making sure sharing is preserved.
data SVal
SVal :: !Kind -> !Either CV (Cached SV) -> SVal

-- | <a>CV</a> represents a concrete word of a fixed size: For signed
--   words, the most significant digit is considered to be the sign.
data CV
CV :: !Kind -> !CVal -> CV
[_cvKind] :: CV -> !Kind
[cvVal] :: CV -> !CVal

-- | A constant value
data CVal

-- | Algebraic real
CAlgReal :: !AlgReal -> CVal

-- | Bit-vector/unbounded integer
CInteger :: !Integer -> CVal

-- | Float
CFloat :: !Float -> CVal

-- | Double
CDouble :: !Double -> CVal

-- | Arbitrary float
CFP :: !FP -> CVal

-- | Rational
CRational :: Rational -> CVal

-- | Character
CChar :: !Char -> CVal

-- | String
CString :: !String -> CVal

-- | List
CList :: ![CVal] -> CVal

-- | Set. Can be regular or complemented.
CSet :: !RCSet CVal -> CVal

-- | Value of an uninterpreted/user kind. The Maybe Int shows index
--   position for enumerations
CUserSort :: !(Maybe Int, String) -> CVal

-- | Tuple
CTuple :: ![CVal] -> CVal

-- | Maybe
CMaybe :: !Maybe CVal -> CVal

-- | Disjoint union
CEither :: !Either CVal CVal -> CVal

-- | Quantifiers: forall or exists. Note that we allow arbitrary nestings.
data Quantifier
ALL :: Quantifier
EX :: Quantifier

-- | Different means of running a symbolic piece of code
data SBVRunMode

-- | In regular mode, with a stage. Bool is True if this is SAT.
SMTMode :: QueryContext -> IStage -> Bool -> SMTConfig -> SBVRunMode

-- | Code generation mode.
CodeGen :: SBVRunMode

-- | Inside a lambda-expression at level
LambdaGen :: Int -> SBVRunMode

-- | Concrete simulation mode, with given environment if any. If Nothing:
--   Random.
Concrete :: Maybe (Bool, [(NamedSymVar, CV)]) -> SBVRunMode

-- | Translation tricks needed for specific capabilities afforded by each
--   solver
data SolverCapabilities
SolverCapabilities :: Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe String -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Bool -> Maybe [String] -> SolverCapabilities

-- | Supports SMT-Lib2 style quantifiers?
[supportsQuantifiers] :: SolverCapabilities -> Bool

-- | Supports define-fun construct?
[supportsDefineFun] :: SolverCapabilities -> Bool

-- | Supports calls to distinct?
[supportsDistinct] :: SolverCapabilities -> Bool

-- | Supports bit-vectors?
[supportsBitVectors] :: SolverCapabilities -> Bool

-- | Supports SMT-Lib2 style uninterpreted-sorts
[supportsUninterpretedSorts] :: SolverCapabilities -> Bool

-- | Supports unbounded integers?
[supportsUnboundedInts] :: SolverCapabilities -> Bool

-- | Supports int2bv?
[supportsInt2bv] :: SolverCapabilities -> Bool

-- | Supports reals?
[supportsReals] :: SolverCapabilities -> Bool

-- | Supports printing of approximations of reals?
[supportsApproxReals] :: SolverCapabilities -> Bool

-- | Supports delta-satisfiability? (With given precision query)
[supportsDeltaSat] :: SolverCapabilities -> Maybe String

-- | Supports floating point numbers?
[supportsIEEE754] :: SolverCapabilities -> Bool

-- | Supports set operations?
[supportsSets] :: SolverCapabilities -> Bool

-- | Supports optimization routines?
[supportsOptimization] :: SolverCapabilities -> Bool

-- | Supports pseudo-boolean operations?
[supportsPseudoBooleans] :: SolverCapabilities -> Bool

-- | Supports interactive queries per SMT-Lib?
[supportsCustomQueries] :: SolverCapabilities -> Bool

-- | Supports global declarations? (Needed for push-pop.)
[supportsGlobalDecls] :: SolverCapabilities -> Bool

-- | Supports datatypes?
[supportsDataTypes] :: SolverCapabilities -> Bool

-- | Does it support fold and map?
[supportsFoldAndMap] :: SolverCapabilities -> Bool

-- | Does it support special relations (orders, transitive closure etc.)
[supportsSpecialRels] :: SolverCapabilities -> Bool

-- | Supports data-type accessors without full ascription?
[supportsDirectAccessors] :: SolverCapabilities -> Bool

-- | Supports flattened model output? (With given config lines.)
[supportsFlattenedModels] :: SolverCapabilities -> Maybe [String]

-- | A model, as returned by a solver
data SMTModel
SMTModel :: [(String, GeneralizedCV)] -> Maybe [(NamedSymVar, CV)] -> [(String, CV)] -> [(String, (SBVType, Either String ([([CV], CV)], CV)))] -> SMTModel

-- | Mapping of symbolic values to objective values.
[modelObjectives] :: SMTModel -> [(String, GeneralizedCV)]

-- | Mapping of input variables as reported by the solver. Only collected
--   if model validation is requested.
[modelBindings] :: SMTModel -> Maybe [(NamedSymVar, CV)]

-- | Mapping of symbolic values to constants.
[modelAssocs] :: SMTModel -> [(String, CV)]

-- | Mapping of uninterpreted functions to association lists in the model.
--   Note that an uninterpreted constant (function of arity 0) will be
--   stored in the <a>modelAssocs</a> field. Left is used when the function
--   returned is too difficult for SBV to figure out what it means
[modelUIFuns] :: SMTModel -> [(String, (SBVType, Either String ([([CV], CV)], CV)))]

-- | Values that we can turn into a lambda abstraction
class MonadSymbolic m => Lambda m a
mkLambda :: Lambda m a => State -> a -> m ()

-- | String operations. Note that we do not define <tt>StrAt</tt> as it
--   translates to <a>StrSubstr</a> trivially.
data StrOp

-- | Concatenation of one or more strings
StrConcat :: StrOp

-- | String length
StrLen :: StrOp

-- | Unit string
StrUnit :: StrOp

-- | Nth element
StrNth :: StrOp

-- | Retrieves substring of <tt>s</tt> at <tt>offset</tt>
StrSubstr :: StrOp

-- | Retrieves first position of <tt>sub</tt> in <tt>s</tt>, <tt>-1</tt> if
--   there are no occurrences
StrIndexOf :: StrOp

-- | Does <tt>s</tt> contain the substring <tt>sub</tt>?
StrContains :: StrOp

-- | Is <tt>pre</tt> a prefix of <tt>s</tt>?
StrPrefixOf :: StrOp

-- | Is <tt>suf</tt> a suffix of <tt>s</tt>?
StrSuffixOf :: StrOp

-- | Replace the first occurrence of <tt>src</tt> by <tt>dst</tt> in
--   <tt>s</tt>
StrReplace :: StrOp

-- | Retrieve integer encoded by string <tt>s</tt> (ground rewriting only)
StrStrToNat :: StrOp

-- | Retrieve string encoded by integer <tt>i</tt> (ground rewriting only)
StrNatToStr :: StrOp

-- | Equivalent to Haskell's ord
StrToCode :: StrOp

-- | Equivalent to Haskell's chr
StrFromCode :: StrOp

-- | Check if string is in the regular expression
StrInRe :: RegExp -> StrOp

-- | Sequence operations.
data SeqOp

-- | See StrConcat
SeqConcat :: SeqOp

-- | See StrLen
SeqLen :: SeqOp

-- | See StrUnit
SeqUnit :: SeqOp

-- | See StrNth
SeqNth :: SeqOp

-- | See StrSubseq
SeqSubseq :: SeqOp

-- | See StrIndexOf
SeqIndexOf :: SeqOp

-- | See StrContains
SeqContains :: SeqOp

-- | See StrPrefixOf
SeqPrefixOf :: SeqOp

-- | See StrSuffixOf
SeqSuffixOf :: SeqOp

-- | See StrReplace
SeqReplace :: SeqOp

-- | Mapping over sequences
SeqMap :: String -> SeqOp

-- | Mapping over sequences with offset
SeqMapI :: String -> SeqOp

-- | Folding of sequences
SeqFoldLeft :: String -> SeqOp

-- | Folding of sequences with offset
SeqFoldLeftI :: String -> SeqOp

-- | Reversal of sequences. NB. Also works for strings; hence the name.
SBVReverse :: Kind -> SeqOp

-- | Regular expressions. Note that regular expressions themselves are
--   concrete, but the <a>match</a> function from the
--   <a>RegExpMatchable</a> class can check membership against a symbolic
--   string/character. Also, we are preferring a datatype approach here, as
--   opposed to coming up with some string-representation; there are way
--   too many alternatives already so inventing one isn't a priority.
--   Please get in touch if you would like a parser for this type as it
--   might be easier to use.
data RegExp

-- | Precisely match the given string
Literal :: String -> RegExp

-- | Accept every string
All :: RegExp

-- | Accept every single character
AllChar :: RegExp

-- | Accept no strings
None :: RegExp

-- | Accept range of characters
Range :: Char -> Char -> RegExp

-- | Concatenation
Conc :: [RegExp] -> RegExp

-- | Kleene Star: Zero or more
KStar :: RegExp -> RegExp

-- | Kleene Plus: One or more
KPlus :: RegExp -> RegExp

-- | Zero or one
Opt :: RegExp -> RegExp

-- | Complement of regular expression
Comp :: RegExp -> RegExp

-- | Difference of regular expressions
Diff :: RegExp -> RegExp -> RegExp

-- | From <tt>n</tt> repetitions to <tt>m</tt> repetitions
Loop :: Int -> Int -> RegExp -> RegExp

-- | Exactly <tt>n</tt> repetitions, i.e., nth power
Power :: Int -> RegExp -> RegExp

-- | Union of regular expressions
Union :: [RegExp] -> RegExp

-- | Intersection of regular expressions
Inter :: RegExp -> RegExp -> RegExp

-- | A query is a user-guided mechanism to directly communicate and extract
--   results from the solver. A generalization of <a>Query</a>.
newtype QueryT m a
QueryT :: ReaderT State m a -> QueryT m a
[runQueryT] :: QueryT m a -> ReaderT State m a

-- | A class representing what can be returned from a symbolic computation.
class Outputtable a

-- | Generalization of <a>output</a>
output :: (Outputtable a, MonadSymbolic m) => a -> m a

-- | A symbolic word, tracking it's signedness and size.
data SV
SV :: !Kind -> !NodeId -> SV

-- | A univariate polynomial, represented simply as a coefficient list. For
--   instance, "5x^3 + 2x - 5" is represented as [(5, 3), (2, 1), (-5, 0)]
newtype AlgRealPoly
AlgRealPoly :: [(Integer, Integer)] -> AlgRealPoly

-- | A symbolic node id
newtype NodeId
NodeId :: (Int, Int) -> NodeId
[getId] :: NodeId -> (Int, Int)

-- | The context of a symbolic array as created
data ArrayContext

-- | A new array, the contents are initialized with the given value, if
--   any, or the custom lambda given
ArrayFree :: Either (Maybe SV) String -> ArrayContext

-- | An array created by mutating another array at a given cell
ArrayMutate :: ArrayIndex -> SV -> SV -> ArrayContext

-- | An array created by symbolically merging two other arrays
ArrayMerge :: SV -> ArrayIndex -> ArrayIndex -> ArrayContext

-- | Representation for symbolic arrays
type ArrayInfo = (String, (Kind, Kind), ArrayContext)

-- | A symbolic expression
data SBVExpr
SBVApp :: !Op -> ![SV] -> SBVExpr

-- | We implement a peculiar caching mechanism, applicable to the use case
--   in implementation of SBV's. Whenever we do a state based computation,
--   we do not want to keep on evaluating it in the then-current state.
--   That will produce essentially a semantically equivalent value. Thus,
--   we want to run it only once, and reuse that result, capturing the
--   sharing at the Haskell level. This is similar to the "type-safe
--   observable sharing" work, but also takes into the account of how
--   symbolic simulation executes.
--   
--   See Andy Gill's type-safe observable sharing trick for the inspiration
--   behind this technique:
--   <a>http://ku-fpg.github.io/files/Gill-09-TypeSafeReification.pdf</a>
--   
--   Note that this is *not* a general memo utility!
data Cached a

-- | Pseudo-boolean operations
data PBOp

-- | At most k
PB_AtMost :: Int -> PBOp

-- | At least k
PB_AtLeast :: Int -> PBOp

-- | Exactly k
PB_Exactly :: Int -> PBOp

-- | At most k, with coefficients given. Generalizes PB_AtMost
PB_Le :: [Int] -> Int -> PBOp

-- | At least k, with coefficients given. Generalizes PB_AtLeast
PB_Ge :: [Int] -> Int -> PBOp

-- | Exactly k, with coefficients given. Generalized PB_Exactly
PB_Eq :: [Int] -> Int -> PBOp

-- | Floating point operations
data FPOp
FP_Cast :: Kind -> Kind -> SV -> FPOp
FP_Reinterpret :: Kind -> Kind -> FPOp
FP_Abs :: FPOp
FP_Neg :: FPOp
FP_Add :: FPOp
FP_Sub :: FPOp
FP_Mul :: FPOp
FP_Div :: FPOp
FP_FMA :: FPOp
FP_Sqrt :: FPOp
FP_Rem :: FPOp
FP_RoundToIntegral :: FPOp
FP_Min :: FPOp
FP_Max :: FPOp
FP_ObjEqual :: FPOp
FP_IsNormal :: FPOp
FP_IsSubnormal :: FPOp
FP_IsZero :: FPOp
FP_IsInfinite :: FPOp
FP_IsNaN :: FPOp
FP_IsNegative :: FPOp
FP_IsPositive :: FPOp

-- | Regular-expression operators. The only thing we can do is to compare
--   for equality/disequality.
data RegExOp
RegExEq :: RegExp -> RegExp -> RegExOp
RegExNEq :: RegExp -> RegExp -> RegExOp

-- | <a>NamedSymVar</a> pairs symbolic values and user given/automatically
--   generated names
data NamedSymVar
NamedSymVar :: !SV -> !Name -> NamedSymVar

-- | Overflow operations
data OvOp

-- | Signed multiplication overflow
Overflow_SMul_OVFL :: OvOp

-- | Signed multiplication underflow
Overflow_SMul_UDFL :: OvOp

-- | Unsigned multiplication overflow
Overflow_UMul_OVFL :: OvOp

-- | A program is a sequence of assignments
newtype SBVPgm
SBVPgm :: Seq (SV, SBVExpr) -> SBVPgm
[pgmAssignments] :: SBVPgm -> Seq (SV, SBVExpr)

-- | Actions we can do in a context: Either at problem description time or
--   while we are dynamically querying. <a>Symbolic</a> and <a>Query</a>
--   are two instances of this class. Note that we use this mechanism
--   internally and do not export it from SBV.
class SolverContext m

-- | Add a constraint, any satisfying instance must satisfy this condition.
constrain :: (SolverContext m, QuantifiedBool a) => a -> m ()

-- | Add a soft constraint. The solver will try to satisfy this condition
--   if possible, but won't if it cannot.
softConstrain :: (SolverContext m, QuantifiedBool a) => a -> m ()

-- | Add a named constraint. The name is used in unsat-core extraction.
namedConstraint :: (SolverContext m, QuantifiedBool a) => String -> a -> m ()

-- | Add a constraint, with arbitrary attributes.
constrainWithAttribute :: (SolverContext m, QuantifiedBool a) => [(String, String)] -> a -> m ()

-- | Set info. Example: <tt>setInfo ":status" ["unsat"]</tt>.
setInfo :: SolverContext m => String -> [String] -> m ()

-- | Set an option.
setOption :: SolverContext m => SMTOption -> m ()

-- | Set the logic.
setLogic :: SolverContext m => Logic -> m ()

-- | Set a solver time-out value, in milli-seconds. This function
--   essentially translates to the SMTLib call <tt>(set-info :timeout
--   val)</tt>, and your backend solver may or may not support it! The
--   amount given is in milliseconds. Also see the function <a>timeOut</a>
--   for finer level control of time-outs, directly from SBV.
setTimeOut :: SolverContext m => Integer -> m ()

-- | Get the state associated with this context
contextState :: SolverContext m => m State

-- | A simple type for SBV computations, used mainly for uninterpreted
--   constants. We keep track of the signedness/size of the arguments. A
--   non-function will have just one entry in the list.
newtype SBVType
SBVType :: [Kind] -> SBVType

-- | Representation of an SMT-Lib program. In between pre and post goes the
--   refuted models
data SMTLibPgm
SMTLibPgm :: SMTLibVersion -> [String] -> SMTLibPgm

-- | A script, to be passed to the solver.
data SMTScript
SMTScript :: String -> [String] -> SMTScript

-- | Initial feed
[scriptBody] :: SMTScript -> String

-- | Continuation script, to extract results
[scriptModel] :: SMTScript -> [String]

-- | The state we keep track of as we interact with the solver
data QueryState
QueryState :: (Maybe Int -> String -> IO String) -> (Maybe Int -> String -> IO ()) -> (Maybe Int -> IO String) -> SMTConfig -> IO () -> Maybe Int -> Int -> QueryState
[queryAsk] :: QueryState -> Maybe Int -> String -> IO String
[querySend] :: QueryState -> Maybe Int -> String -> IO ()
[queryRetrieveResponse] :: QueryState -> Maybe Int -> IO String
[queryConfig] :: QueryState -> SMTConfig
[queryTerminate] :: QueryState -> IO ()
[queryTimeOutValue] :: QueryState -> Maybe Int
[queryAssertionStackDepth] :: QueryState -> Int

-- | Internal representation of a symbolic simulation result
newtype SMTProblem

-- | SMTLib representation, given the config
SMTProblem :: (SMTConfig -> SMTLibPgm) -> SMTProblem
[smtLibPgm] :: SMTProblem -> SMTConfig -> SMTLibPgm

-- | Infinity for <a>Double</a> and <a>Float</a>. Surprisingly, Haskell
--   Prelude doesn't have this value defined, so we provide it here.
infinity :: Floating a => a

-- | Conversion from <a>Bool</a> to <a>SBool</a>
fromBool :: Bool -> SBool

-- | Cache a state-based computation
cache :: (State -> IO a) -> Cached a

-- | Symbolic <a>True</a>
sTrue :: SBool

-- | Symbolic <a>False</a>
sFalse :: SBool

-- | Symbolic boolean negation
sNot :: SBool -> SBool

-- | Symbolic conjunction
(.&&) :: SBool -> SBool -> SBool
infixr 3 .&&

-- | Symbolic disjunction
(.||) :: SBool -> SBool -> SBool
infixr 2 .||

-- | Symbolic logical xor
(.<+>) :: SBool -> SBool -> SBool
infixl 6 .<+>

-- | Symbolic nand
(.~&) :: SBool -> SBool -> SBool
infixr 3 .~&

-- | Symbolic nor
(.~|) :: SBool -> SBool -> SBool
infixr 2 .~|

-- | Symbolic implication
(.=>) :: SBool -> SBool -> SBool
infixr 1 .=>

-- | Symbolic boolean equivalence
(.<=>) :: SBool -> SBool -> SBool
infixr 1 .<=>

-- | Generalization of <a>and</a>
sAnd :: [SBool] -> SBool

-- | Generalization of <a>or</a>
sOr :: [SBool] -> SBool

-- | Generalization of <a>any</a>
sAny :: (a -> SBool) -> [a] -> SBool

-- | Generalization of <a>all</a>
sAll :: (a -> SBool) -> [a] -> SBool

-- | Not-A-Number for <a>Double</a> and <a>Float</a>. Surprisingly, Haskell
--   Prelude doesn't have this value defined, so we provide it here.
nan :: Floating a => a

-- | Symbolic variant of Not-A-Number. This value will inhabit
--   <a>SFloat</a>, <a>SDouble</a> and <a>SFloatingPoint</a>. types.
sNaN :: (Floating a, SymVal a) => SBV a

-- | Symbolic variant of infinity. This value will inhabit both
--   <a>SFloat</a>, <a>SDouble</a> and <a>SFloatingPoint</a>. types.
sInfinity :: (Floating a, SymVal a) => SBV a

-- | Symbolic variant of <a>RoundNearestTiesToEven</a>
sRoundNearestTiesToEven :: SRoundingMode

-- | Symbolic variant of <a>RoundNearestTiesToAway</a>
sRoundNearestTiesToAway :: SRoundingMode

-- | Symbolic variant of <a>RoundTowardPositive</a>
sRoundTowardPositive :: SRoundingMode

-- | Symbolic variant of <a>RoundTowardNegative</a>
sRoundTowardNegative :: SRoundingMode

-- | Symbolic variant of <a>RoundTowardZero</a>
sRoundTowardZero :: SRoundingMode

-- | Alias for <a>sRoundNearestTiesToEven</a>
sRNE :: SRoundingMode

-- | Alias for <a>sRoundNearestTiesToAway</a>
sRNA :: SRoundingMode

-- | Alias for <a>sRoundTowardPositive</a>
sRTP :: SRoundingMode

-- | Alias for <a>sRoundTowardNegative</a>
sRTN :: SRoundingMode

-- | Alias for <a>sRoundTowardZero</a>
sRTZ :: SRoundingMode

-- | Convert a CV to a Haskell boolean (NB. Assumes input is well-kinded)
cvToBool :: CV -> Bool

-- | Is this a regular CV?
isRegularCV :: GeneralizedCV -> Bool

-- | Are two CV's of the same type?
cvSameType :: CV -> CV -> Bool

-- | Create a constant word from an integral.
mkConstCV :: Integral a => Kind -> a -> CV

-- | Lift a binary function through a <a>CV</a>.
liftCV2 :: (AlgReal -> AlgReal -> b) -> (Integer -> Integer -> b) -> (Float -> Float -> b) -> (Double -> Double -> b) -> (FP -> FP -> b) -> (Rational -> Rational -> b) -> (Char -> Char -> b) -> (String -> String -> b) -> ([CVal] -> [CVal] -> b) -> ([CVal] -> [CVal] -> b) -> (Maybe CVal -> Maybe CVal -> b) -> (Either CVal CVal -> Either CVal CVal -> b) -> ((Maybe Int, String) -> (Maybe Int, String) -> b) -> CV -> CV -> b

-- | Map a unary function through a <a>CV</a>.
mapCV :: (AlgReal -> AlgReal) -> (Integer -> Integer) -> (Float -> Float) -> (Double -> Double) -> (FP -> FP) -> (Rational -> Rational) -> (Char -> Char) -> (String -> String) -> ((Maybe Int, String) -> (Maybe Int, String)) -> CV -> CV

-- | Map a binary function through a <a>CV</a>.
mapCV2 :: (AlgReal -> AlgReal -> AlgReal) -> (Integer -> Integer -> Integer) -> (Float -> Float -> Float) -> (Double -> Double -> Double) -> (FP -> FP -> FP) -> (Rational -> Rational -> Rational) -> (Char -> Char -> Char) -> (String -> String -> String) -> ((Maybe Int, String) -> (Maybe Int, String) -> (Maybe Int, String)) -> CV -> CV -> CV

-- | Constant True as an <a>SV</a>. Note that this value always occupies
--   slot -1 and level 0.
trueSV :: SV

-- | Constant False as an <a>SV</a>. Note that this value always occupies
--   slot -2 and level 0.
falseSV :: SV

-- | Constant True as a <a>CV</a>. We represent it using the integer value
--   1.
trueCV :: CV

-- | Constant False as a <a>CV</a>. We represent it using the integer value
--   0.
falseCV :: CV

-- | Normalize a CV. Essentially performs modular arithmetic to make sure
--   the value can fit in the given bit-size. Note that this is rather
--   tricky for negative values, due to asymmetry. (i.e., an 8-bit negative
--   number represents values in the range -128 to 127; thus we have to be
--   careful on the negative side.)
normCV :: CV -> CV

-- | Generalization of <a>mkSymSBV</a>
mkSymSBV :: forall a m. MonadSymbolic m => VarContext -> Kind -> Maybe String -> m (SBV a)

-- | Convert a symbolic value to a symbolic-word
sbvToSV :: State -> SBV a -> IO SV

-- | Generalization of <a>sbvToSymSW</a>
sbvToSymSV :: MonadSymbolic m => SBV a -> m SV

-- | Forcing an argument; this is a necessary evil to make sure all the
--   arguments to an uninterpreted function are evaluated before called;
--   the semantics of uinterpreted functions is necessarily strict;
--   deviating from Haskell's
forceSVArg :: SV -> IO ()

-- | Create a new expression; hash-cons as necessary
newExpr :: State -> Kind -> SBVExpr -> IO SV

-- | Uncache a previously cached computation
uncache :: Cached SV -> State -> IO SV

-- | Uncache, retrieving SMT array indexes
uncacheAI :: Cached ArrayIndex -> State -> IO ArrayIndex

-- | Create a new table; hash-cons as necessary
getTableIndex :: State -> Kind -> Kind -> [SV] -> IO Int

-- | Generalization of <a>runSymbolic</a>
runSymbolic :: MonadIO m => SMTConfig -> SBVRunMode -> SymbolicT m a -> m (a, Result)

-- | Get the current path condition
getPathCondition :: State -> SBool

-- | Extend the path condition with the given test value.
extendPathCondition :: State -> (SBool -> SBool) -> State

-- | Are we running in proof mode?
inSMTMode :: State -> IO Bool

-- | Create an internal variable, which acts as an input but isn't visible
--   to the user. Such variables are existentially quantified in a SAT
--   context, and universally quantified in a proof context.
internalVariable :: State -> Kind -> IO SV

-- | Require a boolean condition to be true in the state. Only used for
--   internal purposes.
internalConstraint :: State -> Bool -> [(String, String)] -> SVal -> IO ()

-- | Is this a CodeGen run? (i.e., generating code)
isCodeGenMode :: State -> IO Bool

-- | Create a new uninterpreted symbol, possibly with user given code
newUninterpreted :: State -> (String, Maybe [String]) -> SBVType -> UICodeKind -> IO ()

-- | Are there any existential quantifiers?
needsExistentials :: [Quantifier] -> Bool

-- | The extension associated with the version
smtLibVersionExtension :: SMTLibVersion -> String

-- | Names reserved by SMTLib. This list is current as of Dec 6 2015; but
--   of course there's no guarantee it'll stay that way.
smtLibReservedNames :: [String]

-- | Grab the program from a running symbolic simulation state.
extractSymbolicSimulationState :: State -> IO Result

-- | Generate a finite constant bitvector
genLiteral :: Integral a => Kind -> a -> SBV b

-- | Convert a constant to an integral value
genFromCV :: Integral a => CV -> a

-- | <a>CV</a> represents a concrete word of a fixed size: For signed
--   words, the most significant digit is considered to be the sign.
data CV
CV :: !Kind -> !CVal -> CV
[_cvKind] :: CV -> !Kind
[cvVal] :: CV -> !CVal

-- | Generalization of <a>genMkSymVar</a>
genMkSymVar :: MonadSymbolic m => Kind -> VarContext -> Maybe String -> m (SBV a)

-- | Parse a signed/sized value from a sequence of CVs
genParse :: Integral a => Kind -> [CV] -> Maybe (a, [CV])

-- | Show a model in human readable form. Ignore bindings to those
--   variables that start with "__internal_sbv_" and also those marked as
--   "nonModelVar" in the config; as these are only for internal purposes
showModel :: SMTConfig -> SMTModel -> String

-- | A model, as returned by a solver
data SMTModel
SMTModel :: [(String, GeneralizedCV)] -> Maybe [(NamedSymVar, CV)] -> [(String, CV)] -> [(String, (SBVType, Either String ([([CV], CV)], CV)))] -> SMTModel

-- | Mapping of symbolic values to objective values.
[modelObjectives] :: SMTModel -> [(String, GeneralizedCV)]

-- | Mapping of input variables as reported by the solver. Only collected
--   if model validation is requested.
[modelBindings] :: SMTModel -> Maybe [(NamedSymVar, CV)]

-- | Mapping of symbolic values to constants.
[modelAssocs] :: SMTModel -> [(String, CV)]

-- | Mapping of uninterpreted functions to association lists in the model.
--   Note that an uninterpreted constant (function of arity 0) will be
--   stored in the <a>modelAssocs</a> field. Left is used when the function
--   returned is too difficult for SBV to figure out what it means
[modelUIFuns] :: SMTModel -> [(String, (SBVType, Either String ([([CV], CV)], CV)))]

-- | Lift <a>quotRem</a> to symbolic words. Division by 0 is defined s.t.
--   <tt>x/0 = 0</tt>; which holds even when <tt>x</tt> is <tt>0</tt>
--   itself.
liftQRem :: (Eq a, SymVal a) => SBV a -> SBV a -> (SBV a, SBV a)

-- | Lift <a>divMod</a> to symbolic words. Division by 0 is defined s.t.
--   <tt>x/0 = 0</tt>; which holds even when <tt>x</tt> is <tt>0</tt>
--   itself. Essentially, this is conversion from quotRem (truncate to 0)
--   to divMod (truncate towards negative infinity)
liftDMod :: (Ord a, SymVal a, Num a, SDivisible (SBV a)) => SBV a -> SBV a -> (SBV a, SBV a)

-- | Register a new kind with the system, used for uninterpreted sorts. NB:
--   Is it safe to have new kinds in query mode? It could be that the new
--   kind might introduce a constraint that effects the logic. For
--   instance, if we're seeing <a>Double</a> for the first time and using a
--   BV logic, then things would fall apart. But this should be rare, and
--   hopefully the success-response checking mechanism will catch the rare
--   cases where this is an issue. In either case, the user can always
--   arrange for the right logic by calling <a>setLogic</a> appropriately,
--   so it seems safe to just allow for this.
registerKind :: State -> Kind -> IO ()

-- | Convert a symbolic value to an internal SV
svToSV :: State -> SVal -> IO SV

-- | A type <tt>a</tt> is provable if we can turn it into a predicate,
--   i.e., it has to return a boolean. This class captures essentially
--   prove calls.
class ExtractIO m => ProvableM m a

-- | A type <tt>a</tt> is satisfiable if it has constraints, potentially
--   returning a boolean. This class captures essentially sat and optimize
--   calls.
class ExtractIO m => SatisfiableM m a

-- | Kind of code we have for uninterpretation
data UICodeKind
UINone :: UICodeKind
UISMT :: SMTDef -> UICodeKind
UICgC :: [String] -> UICodeKind

-- | Lower level version of <a>compileToC</a>, producing a
--   <a>CgPgmBundle</a>
compileToC' :: String -> SBVCodeGen a -> IO (a, CgConfig, CgPgmBundle)

-- | Lower level version of <a>compileToCLib</a>, producing a
--   <a>CgPgmBundle</a>
compileToCLib' :: String -> [(String, SBVCodeGen a)] -> IO ([a], CgConfig, CgPgmBundle)

-- | The code-generation monad. Allows for precise layout of input values
--   reference parameters (for returning composite values in languages such
--   as C), and return values.
newtype SBVCodeGen a
SBVCodeGen :: StateT CgState Symbolic a -> SBVCodeGen a

-- | Reach into symbolic monad from code-generation
cgSym :: Symbolic a -> SBVCodeGen a

-- | Creates an atomic input in the generated code.
cgInput :: SymVal a => String -> SBVCodeGen (SBV a)

-- | Creates an array input in the generated code.
cgInputArr :: SymVal a => Int -> String -> SBVCodeGen [SBV a]

-- | Creates an atomic output in the generated code.
cgOutput :: String -> SBV a -> SBVCodeGen ()

-- | Creates an array output in the generated code.
cgOutputArr :: SymVal a => String -> [SBV a] -> SBVCodeGen ()

-- | Creates a returned (unnamed) value in the generated code.
cgReturn :: SBV a -> SBVCodeGen ()

-- | Creates a returned (unnamed) array value in the generated code.
cgReturnArr :: SymVal a => [SBV a] -> SBVCodeGen ()

-- | Creates an atomic input in the generated code.
svCgInput :: Kind -> String -> SBVCodeGen SVal

-- | Creates an array input in the generated code.
svCgInputArr :: Kind -> Int -> String -> SBVCodeGen [SVal]

-- | Creates an atomic output in the generated code.
svCgOutput :: String -> SVal -> SBVCodeGen ()

-- | Creates an array output in the generated code.
svCgOutputArr :: String -> [SVal] -> SBVCodeGen ()

-- | Creates a returned (unnamed) value in the generated code.
svCgReturn :: SVal -> SBVCodeGen ()

-- | Creates a returned (unnamed) array value in the generated code.
svCgReturnArr :: [SVal] -> SBVCodeGen ()

-- | Sets RTC (run-time-checks) for index-out-of-bounds, shift-with-large
--   value etc. on/off. Default: <a>False</a>.
cgPerformRTCs :: Bool -> SBVCodeGen ()

-- | Sets driver program run time values, useful for generating programs
--   with fixed drivers for testing. Default: None, i.e., use random
--   values.
cgSetDriverValues :: [Integer] -> SBVCodeGen ()

-- | Adds the given lines to the header file generated, useful for
--   generating programs with uninterpreted functions.
cgAddPrototype :: [String] -> SBVCodeGen ()

-- | Adds the given lines to the program file generated, useful for
--   generating programs with uninterpreted functions.
cgAddDecl :: [String] -> SBVCodeGen ()

-- | Adds the given words to the compiler options in the generated
--   Makefile, useful for linking extra stuff in.
cgAddLDFlags :: [String] -> SBVCodeGen ()

-- | Ignore assertions (those generated by <a>sAssert</a> calls) in the
--   generated C code
cgIgnoreSAssert :: Bool -> SBVCodeGen ()

-- | If passed <a>True</a>, then we will not ask the user if we're
--   overwriting files as we generate the C code. Otherwise, we'll prompt.
cgOverwriteFiles :: Bool -> SBVCodeGen ()

-- | If passed <a>True</a>, then we will show 'SWord 8' type in hex.
--   Otherwise we'll show it in decimal. All signed types are shown
--   decimal, and all unsigned larger types are shown hexadecimal
--   otherwise.
cgShowU8UsingHex :: Bool -> SBVCodeGen ()

-- | Sets number of bits to be used for representing the <a>SInteger</a>
--   type in the generated C code. The argument must be one of <tt>8</tt>,
--   <tt>16</tt>, <tt>32</tt>, or <tt>64</tt>. Note that this is
--   essentially unsafe as the semantics of unbounded Haskell integers
--   becomes reduced to the corresponding bit size, as typical in most C
--   implementations.
cgIntegerSize :: Int -> SBVCodeGen ()

-- | Sets the C type to be used for representing the <a>SReal</a> type in
--   the generated C code. The setting can be one of C's <tt>"float"</tt>,
--   <tt>"double"</tt>, or <tt>"long double"</tt>, types, depending on the
--   precision needed. Note that this is essentially unsafe as the
--   semantics of infinite precision SReal values becomes reduced to the
--   corresponding floating point type in C, and hence it is subject to
--   rounding errors.
cgSRealType :: CgSRealType -> SBVCodeGen ()

-- | Possible mappings for the <a>SReal</a> type when translated to C. Used
--   in conjunction with the function <a>cgSRealType</a>. Note that the
--   particular characteristics of the mapped types depend on the platform
--   and the compiler used for compiling the generated C program. See
--   <a>http://en.wikipedia.org/wiki/C_data_types</a> for details.
data CgSRealType

-- | <pre>
--   float
--   </pre>
CgFloat :: CgSRealType

-- | <pre>
--   double
--   </pre>
CgDouble :: CgSRealType

-- | <pre>
--   long double
--   </pre>
CgLongDouble :: CgSRealType

-- | Abstract over code generation for different languages
class CgTarget a
targetName :: CgTarget a => a -> String
translate :: CgTarget a => a -> CgConfig -> String -> CgState -> Result -> CgPgmBundle

-- | Options for code-generation.
data CgConfig
CgConfig :: Bool -> Maybe Int -> Maybe CgSRealType -> [Integer] -> Bool -> Bool -> Bool -> Bool -> Bool -> CgConfig

-- | If <a>True</a>, perform run-time-checks for index-out-of-bounds or
--   shifting-by-large values etc.
[cgRTC] :: CgConfig -> Bool

-- | Bit-size to use for representing SInteger (if any)
[cgInteger] :: CgConfig -> Maybe Int

-- | Type to use for representing SReal (if any)
[cgReal] :: CgConfig -> Maybe CgSRealType

-- | Values to use for the driver program generated, useful for generating
--   non-random drivers.
[cgDriverVals] :: CgConfig -> [Integer]

-- | If <a>True</a>, will generate a driver program
[cgGenDriver] :: CgConfig -> Bool

-- | If <a>True</a>, will generate a makefile
[cgGenMakefile] :: CgConfig -> Bool

-- | If <a>True</a>, will ignore <a>sAssert</a> calls
[cgIgnoreAsserts] :: CgConfig -> Bool

-- | If <a>True</a>, will overwrite the generated files without prompting.
[cgOverwriteGenerated] :: CgConfig -> Bool

-- | If <a>True</a>, then 8-bit unsigned values will be shown in hex as
--   well, otherwise decimal. (Other types always shown in hex.)
[cgShowU8InHex] :: CgConfig -> Bool

-- | Code-generation state
data CgState
CgState :: [(String, CgVal)] -> [(String, CgVal)] -> [CgVal] -> [String] -> [String] -> [String] -> CgConfig -> CgState
[cgInputs] :: CgState -> [(String, CgVal)]
[cgOutputs] :: CgState -> [(String, CgVal)]
[cgReturns] :: CgState -> [CgVal]
[cgPrototypes] :: CgState -> [String]
[cgDecls] :: CgState -> [String]
[cgLDFlags] :: CgState -> [String]
[cgFinalConfig] :: CgState -> CgConfig

-- | Representation of a collection of generated programs.
data CgPgmBundle
CgPgmBundle :: (Maybe Int, Maybe CgSRealType) -> [(FilePath, (CgPgmKind, [Doc]))] -> CgPgmBundle

-- | Different kinds of "files" we can produce. Currently this is quite
--   <a>C</a> specific.
data CgPgmKind
CgMakefile :: [String] -> CgPgmKind
CgHeader :: [Doc] -> CgPgmKind
CgSource :: CgPgmKind
CgDriver :: CgPgmKind

-- | Abstraction of target language values
data CgVal
CgAtomic :: SV -> CgVal
CgArray :: [SV] -> CgVal

-- | Default options for code generation. The run-time checks are
--   turned-off, and the driver values are completely random.
defaultCgConfig :: CgConfig

-- | Initial configuration for code-generation
initCgState :: CgState

-- | Is this a driver program?
isCgDriver :: CgPgmKind -> Bool

-- | Is this a make file?
isCgMakefile :: CgPgmKind -> Bool

-- | Should we generate a driver program? Default: <a>True</a>. When a
--   library is generated, it will have a driver if any of the constituent
--   functions has a driver. (See <a>compileToCLib</a>.)
cgGenerateDriver :: Bool -> SBVCodeGen ()

-- | Should we generate a Makefile? Default: <a>True</a>.
cgGenerateMakefile :: Bool -> SBVCodeGen ()

-- | Generate code for a symbolic program, returning a Code-gen bundle,
--   i.e., collection of makefiles, source code, headers, etc.
codeGen :: CgTarget l => l -> CgConfig -> String -> SBVCodeGen a -> IO (a, CgConfig, CgPgmBundle)

-- | Render a code-gen bundle to a directory or to stdout
renderCgPgmBundle :: Maybe FilePath -> (CgConfig, CgPgmBundle) -> IO ()

-- | The SMT-Lib (in particular Z3) implementation for min/max for floats
--   does not agree with Haskell's; and also it does not agree with what
--   the hardware does. Sigh.. See:
--   <a>http://ghc.haskell.org/trac/ghc/ticket/10378</a>
--   <a>http://github.com/Z3Prover/z3/issues/68</a> So, we codify here what
--   the Z3 (SMTLib) is implementing for fpMax. The discrepancy with
--   Haskell is that the NaN propagation doesn't work in Haskell The
--   discrepancy with x86 is that given +0/-0, x86 returns the second
--   argument; SMTLib is non-deterministic
fpMaxH :: RealFloat a => a -> a -> a

-- | SMTLib compliant definition for <a>fpMin</a>. See the comments for
--   <a>fpMax</a>.
fpMinH :: RealFloat a => a -> a -> a

-- | Convert double to float and back. Essentially <tt>fromRational .
--   toRational</tt> except careful on NaN, Infinities, and -0.
fp2fp :: (RealFloat a, RealFloat b) => a -> b

-- | Compute the "floating-point" remainder function, the float/double
--   value that remains from the division of <tt>x</tt> and <tt>y</tt>.
--   There are strict rules around 0's, Infinities, and NaN's as coded
--   below.
fpRemH :: RealFloat a => a -> a -> a

-- | Convert a float to the nearest integral representable in that type
fpRoundToIntegralH :: RealFloat a => a -> a

-- | Check that two floats are the exact same values, i.e., +0/-0 does not
--   compare equal, and NaN's compare equal to themselves.
fpIsEqualObjectH :: RealFloat a => a -> a -> Bool

-- | Ordering for floats, avoiding the +0<i>-0</i>NaN issues. Note that
--   this is essentially used for indexing into a map, so we need to be
--   total. Thus, the order we pick is: NaN -oo -0 +0 +oo The placement of
--   NaN here is questionable, but immaterial.
fpCompareObjectH :: RealFloat a => a -> a -> Ordering

-- | Check if a number is "normal." Note that +0/-0 is not considered a
--   normal-number and also this is not simply the negation of
--   isDenormalized!
fpIsNormalizedH :: RealFloat a => a -> Bool

-- | Reinterpret-casts a <a>Float</a> to a <a>Word32</a>.
floatToWord :: Float -> Word32

-- | Reinterpret-casts a <a>Word32</a> to a <a>Float</a>.
wordToFloat :: Word32 -> Float

-- | Reinterpret-casts a <a>Double</a> to a <a>Word64</a>.
doubleToWord :: Double -> Word64

-- | Reinterpret-casts a <a>Word64</a> to a <a>Double</a>.
wordToDouble :: Word64 -> Double

-- | PrettyNum class captures printing of numbers in hex and binary
--   formats; also supporting negative numbers.
class PrettyNum a

-- | Show a number in hexadecimal, starting with <tt>0x</tt> and type.
hexS :: PrettyNum a => a -> String

-- | Show a number in binary, starting with <tt>0b</tt> and type.
binS :: PrettyNum a => a -> String

-- | Show a number in hexadecimal, starting with <tt>0x</tt> but no type.
hexP :: PrettyNum a => a -> String

-- | Show a number in binary, starting with <tt>0b</tt> but no type.
binP :: PrettyNum a => a -> String

-- | Show a number in hex, without prefix, or types.
hex :: PrettyNum a => a -> String

-- | Show a number in bin, without prefix, or types.
bin :: PrettyNum a => a -> String

-- | A more convenient interface for reading binary numbers, also supports
--   negative numbers
readBin :: Num a => String -> a

-- | Show as a hexadecimal value. First bool controls whether type info is
--   printed while the second boolean controls whether 0x prefix is
--   printed. The tuple is the signedness and the bit-length of the input.
--   The length of the string will <i>not</i> depend on the value, but
--   rather the bit-length.
shex :: (Show a, Integral a) => Bool -> Bool -> (Bool, Int) -> a -> String

-- | Show as hexadecimal, but for C programs. We have to be careful about
--   printing min-bounds, since C does some funky casting, possibly losing
--   the sign bit. In those cases, we use the defined constants in
--   <a>stdint.h</a>. We also properly append the necessary suffixes as
--   needed.
chex :: (Show a, Integral a) => Bool -> Bool -> (Bool, Int) -> a -> String

-- | Show as a hexadecimal value, integer version. Almost the same as shex
--   above except we don't have a bit-length so the length of the string
--   will depend on the actual value.
shexI :: Bool -> Bool -> Integer -> String

-- | Similar to <a>shex</a>; except in binary.
sbin :: (Show a, Integral a) => Bool -> Bool -> (Bool, Int) -> a -> String

-- | Similar to <a>shexI</a>; except in binary.
sbinI :: Bool -> Bool -> Integer -> String

-- | A version of show for floats that generates correct C literals for
--   nan/infinite. NB. Requires "math.h" to be included.
showCFloat :: Float -> String

-- | A version of show for doubles that generates correct C literals for
--   nan/infinite. NB. Requires "math.h" to be included.
showCDouble :: Double -> String

-- | A version of show for floats that generates correct Haskell literals
--   for nan/infinite
showHFloat :: Float -> String

-- | A version of show for doubles that generates correct Haskell literals
--   for nan/infinite
showHDouble :: Double -> String

-- | Show a float as a binary
showBFloat :: (Show a, RealFloat a) => a -> ShowS

-- | Like Haskell's showHFloat, but uses arbitrary base instead. Note that
--   the exponent is always written in decimal. Let the exponent value be
--   d: If base=10, then we use <tt>e</tt> to denote the exponent; meaning
--   10^d If base is a power of 2, then we use <tt>p</tt> to denote the
--   exponent; meaning 2^d Otherwise, we use @ to denote the exponent, and
--   it means base^d
showFloatAtBase :: (Show a, RealFloat a) => Int -> a -> ShowS

-- | A version of show for floats that generates correct SMTLib literals
--   using the rounding mode
showSMTFloat :: RoundingMode -> Float -> String

-- | A version of show for doubles that generates correct SMTLib literals
--   using the rounding mode
showSMTDouble :: RoundingMode -> Double -> String

-- | Convert a rounding mode to the format SMT-Lib2 understands.
smtRoundingMode :: RoundingMode -> String

-- | Convert a CV to an SMTLib2 compliant value
cvToSMTLib :: RoundingMode -> CV -> String

-- | When we show a negative number in SMTLib, we must properly
--   parenthesize.
showNegativeNumber :: (Show a, Num a, Ord a) => a -> String

-- | Specify how to save timing information, if at all.
data Timing
NoTiming :: Timing
PrintTiming :: Timing
SaveTiming :: IORef NominalDiffTime -> Timing

-- | Show <a>NominalDiffTime</a> in human readable form.
--   <a>NominalDiffTime</a> is essentially picoseconds (10^-12 seconds). We
--   show it so that it's represented at the day:hour:minute:second.XXX
--   granularity.
showTDiff :: NominalDiffTime -> String

-- | Send an arbitrary string to the solver in a query. Note that this is
--   inherently dangerous as it can put the solver in an arbitrary state
--   and confuse SBV. If you use this feature, you are on your own!
sendStringToSolver :: (MonadIO m, MonadQuery m) => String -> m ()

-- | Send an arbitrary string to the solver in a query, and return a
--   response. Note that this is inherently dangerous as it can put the
--   solver in an arbitrary state and confuse SBV.
sendRequestToSolver :: (MonadIO m, MonadQuery m) => String -> m String

-- | Retrieve multiple responses from the solver, until it responds with a
--   user given tag that we shall arrange for internally. The optional
--   timeout is in milliseconds. If the time-out is exceeded, then we will
--   raise an error. Note that this is inherently dangerous as it can put
--   the solver in an arbitrary state and confuse SBV. If you use this
--   feature, you are on your own!
retrieveResponseFromSolver :: (MonadIO m, MonadQuery m) => String -> Maybe Int -> m [String]

-- | Generalization of <a>addSValOptGoal</a>
addSValOptGoal :: MonadSymbolic m => Objective SVal -> m ()

-- | Convert a float to a comparable <a>SWord32</a>. The trick is to ignore
--   the sign of -0, and if it's a negative value flip all the bits, and
--   otherwise only flip the sign bit. This is known as the lexicographic
--   ordering on floats and it works as long as you do not have a
--   <tt>NaN</tt>.
sFloatAsComparableSWord32 :: SFloat -> SWord32

-- | Convert a double to a comparable <a>SWord64</a>. The trick is to
--   ignore the sign of -0, and if it's a negative value flip all the bits,
--   and otherwise only flip the sign bit. This is known as the
--   lexicographic ordering on doubles and it works as long as you do not
--   have a <tt>NaN</tt>.
sDoubleAsComparableSWord64 :: SDouble -> SWord64

-- | Convert a float to the correct size word, that can be used in
--   lexicographic ordering. Used in optimization.
sFloatingPointAsComparableSWord :: forall eb sb. (ValidFloat eb sb, KnownNat (eb + sb), BVIsNonZero (eb + sb)) => SFloatingPoint eb sb -> SWord (eb + sb)

-- | Inverse transformation to <a>sFloatAsComparableSWord32</a>. Note that
--   this isn't a perfect inverse, since <tt>-0</tt> maps to <tt>0</tt> and
--   back to <tt>0</tt>. Otherwise, it's faithful:
--   
--   <pre>
--   &gt;&gt;&gt; prove  $ \x -&gt; let f = sComparableSWord32AsSFloat x in fpIsNaN f .|| fpIsNegativeZero f .|| sFloatAsComparableSWord32 f .== x
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt; fpIsNegativeZero x .|| sComparableSWord32AsSFloat (sFloatAsComparableSWord32 x) `fpIsEqualObject` x
--   Q.E.D.
--   </pre>
sComparableSWord32AsSFloat :: SWord32 -> SFloat

-- | Inverse transformation to <a>sDoubleAsComparableSWord64</a>. Note that
--   this isn't a perfect inverse, since <tt>-0</tt> maps to <tt>0</tt> and
--   back to <tt>0</tt>. Otherwise, it's faithful:
--   
--   <pre>
--   &gt;&gt;&gt; prove  $ \x -&gt; let d = sComparableSWord64AsSDouble x in fpIsNaN d .|| fpIsNegativeZero d .|| sDoubleAsComparableSWord64 d .== x
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt; fpIsNegativeZero x .|| sComparableSWord64AsSDouble (sDoubleAsComparableSWord64 x) `fpIsEqualObject` x
--   Q.E.D.
--   </pre>
sComparableSWord64AsSDouble :: SWord64 -> SDouble

-- | Inverse transformation to <a>sFloatingPointAsComparableSWord</a>. Note
--   that this isn't a perfect inverse, since <tt>-0</tt> maps to
--   <tt>0</tt> and back to <tt>0</tt>. Otherwise, it's faithful:
--   
--   <pre>
--   &gt;&gt;&gt; prove  $ \x -&gt; let d = sComparableSWordAsSFloatingPoint x in fpIsNaN d .|| fpIsNegativeZero d .|| sFloatingPointAsComparableSWord (d :: SFPHalf) .== x
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt; fpIsNegativeZero x .|| sComparableSWordAsSFloatingPoint (sFloatingPointAsComparableSWord x) `fpIsEqualObject` (x :: SFPHalf)
--   Q.E.D.
--   </pre>
sComparableSWordAsSFloatingPoint :: forall eb sb. (KnownNat (eb + sb), BVIsNonZero (eb + sb), ValidFloat eb sb) => SWord (eb + sb) -> SFloatingPoint eb sb

-- | Create an SMTLib lambda, in the given state.
lambda :: (MonadIO m, Lambda (SymbolicT m) a) => State -> Kind -> a -> m SMTDef

-- | Create an anonymous lambda, rendered as n SMTLib string
lambdaStr :: (MonadIO m, Lambda (SymbolicT m) a) => State -> Kind -> a -> m String

-- | Create a named SMTLib function, in the given state.
namedLambda :: (MonadIO m, Lambda (SymbolicT m) a) => State -> String -> Kind -> a -> m SMTDef

-- | Create a named SMTLib function, in the given state, string version
namedLambdaStr :: (MonadIO m, Lambda (SymbolicT m) a) => State -> String -> Kind -> a -> m String

-- | Generate a constraint.
constraint :: (MonadIO m, Constraint (SymbolicT m) a) => State -> a -> m SV

-- | Generate a constraint, string version
constraintStr :: (MonadIO m, Constraint (SymbolicT m) a) => State -> a -> m String

-- | Values that we can turn into a lambda abstraction
class MonadSymbolic m => Lambda m a
mkLambda :: Lambda m a => State -> a -> m ()

-- | Values that we can turn into a constraint
class MonadSymbolic m => Constraint m a
mkConstraint :: Constraint m a => State -> a -> m ()


-- | More generalized alternative to <tt>Data.SBV</tt> for advanced client
--   use
module Data.SBV.Trans

-- | A symbolic boolean/bit
type SBool = SBV Bool

-- | Symbolic <a>True</a>
sTrue :: SBool

-- | Symbolic <a>False</a>
sFalse :: SBool

-- | Symbolic boolean negation
sNot :: SBool -> SBool

-- | Symbolic conjunction
(.&&) :: SBool -> SBool -> SBool
infixr 3 .&&

-- | Symbolic disjunction
(.||) :: SBool -> SBool -> SBool
infixr 2 .||

-- | Symbolic logical xor
(.<+>) :: SBool -> SBool -> SBool
infixl 6 .<+>

-- | Symbolic nand
(.~&) :: SBool -> SBool -> SBool
infixr 3 .~&

-- | Symbolic nor
(.~|) :: SBool -> SBool -> SBool
infixr 2 .~|

-- | Symbolic implication
(.=>) :: SBool -> SBool -> SBool
infixr 1 .=>

-- | Symbolic boolean equivalence
(.<=>) :: SBool -> SBool -> SBool
infixr 1 .<=>

-- | Conversion from <a>Bool</a> to <a>SBool</a>
fromBool :: Bool -> SBool

-- | Returns 1 if the boolean is <a>sTrue</a>, otherwise 0.
oneIf :: (Ord a, Num a, SymVal a) => SBool -> SBV a

-- | Generalization of <a>and</a>
sAnd :: [SBool] -> SBool

-- | Generalization of <a>or</a>
sOr :: [SBool] -> SBool

-- | Generalization of <a>any</a>
sAny :: (a -> SBool) -> [a] -> SBool

-- | Generalization of <a>all</a>
sAll :: (a -> SBool) -> [a] -> SBool

-- | 8-bit unsigned symbolic value
type SWord8 = SBV Word8

-- | 16-bit unsigned symbolic value
type SWord16 = SBV Word16

-- | 32-bit unsigned symbolic value
type SWord32 = SBV Word32

-- | 64-bit unsigned symbolic value
type SWord64 = SBV Word64

-- | A symbolic unsigned bit-vector carrying its size info
type SWord (n :: Nat) = SBV (WordN n)

-- | An unsigned bit-vector carrying its size info
data WordN (n :: Nat)

-- | 8-bit signed symbolic value, 2's complement representation
type SInt8 = SBV Int8

-- | 16-bit signed symbolic value, 2's complement representation
type SInt16 = SBV Int16

-- | 32-bit signed symbolic value, 2's complement representation
type SInt32 = SBV Int32

-- | 64-bit signed symbolic value, 2's complement representation
type SInt64 = SBV Int64

-- | A symbolic signed bit-vector carrying its size info
type SInt (n :: Nat) = SBV (IntN n)

-- | A signed bit-vector carrying its size info
data IntN (n :: Nat)

-- | Type family to create the appropriate non-zero constraint
type family BVIsNonZero (arg :: Nat) :: Constraint

-- | Capture the correspondence between sized and fixed-sized BVs
type family FromSized (t :: Type) :: Type

-- | Capture the correspondence between fixed-sized and sized BVs
type family ToSized (t :: Type) :: Type

-- | Convert a sized bit-vector to the corresponding fixed-sized
--   bit-vector, for instance 'SWord 16' to <a>SWord16</a>. See also
--   <a>toSized</a>.
fromSized :: FromSizedBV a => a -> FromSized a

-- | Convert a fixed-sized bit-vector to the corresponding sized
--   bit-vector, for instance <a>SWord16</a> to 'SWord 16'. See also
--   <a>fromSized</a>.
toSized :: ToSizedBV a => a -> ToSized a

-- | Infinite precision signed symbolic value
type SInteger = SBV Integer

-- | IEEE-754 single-precision floating point numbers
type SFloat = SBV Float

-- | IEEE-754 double-precision floating point numbers
type SDouble = SBV Double

-- | A symbolic arbitrary precision floating point value
type SFloatingPoint (eb :: Nat) (sb :: Nat) = SBV (FloatingPoint eb sb)

-- | Infinite precision symbolic algebraic real value
type SReal = SBV AlgReal

-- | Algebraic reals. Note that the representation is left abstract. We
--   represent rational results explicitly, while the roots-of-polynomials
--   are represented implicitly by their defining equation
data AlgReal

-- | Convert an SReal to an SInteger. That is, it computes the largest
--   integer <tt>n</tt> that satisfies <tt>sIntegerToSReal n &lt;= r</tt>
--   essentially giving us the <tt>floor</tt>.
--   
--   For instance, <tt>1.3</tt> will be <tt>1</tt>, but <tt>-1.3</tt> will
--   be <tt>-2</tt>.
sRealToSInteger :: SReal -> SInteger

-- | A symbolic character. Note that this is the full unicode character
--   set. see:
--   <a>http://smtlib.cs.uiowa.edu/theories-UnicodeStrings.shtml</a> for
--   details.
type SChar = SBV Char

-- | A symbolic string. Note that a symbolic string is <i>not</i> a list of
--   symbolic characters, that is, it is not the case that <tt>SString =
--   [SChar]</tt>, unlike what one might expect following Haskell strings.
--   An <a>SString</a> is a symbolic value of its own, of possibly
--   arbitrary but finite length, and internally processed as one unit as
--   opposed to a fixed-length list of characters.
type SString = SBV String

-- | A symbolic list of items. Note that a symbolic list is <i>not</i> a
--   list of symbolic items, that is, it is not the case that <tt>SList a =
--   [a]</tt>, unlike what one might expect following haskell
--   lists/sequences. An <a>SList</a> is a symbolic value of its own, of
--   possibly arbitrary but finite length, and internally processed as one
--   unit as opposed to a fixed-length list of items. Note that lists can
--   be nested, i.e., we do allow lists of lists of ... items.
type SList a = SBV [a]

-- | Arrays of symbolic values An <tt>array a b</tt> is an array indexed by
--   the type <tt><a>SBV</a> a</tt>, with elements of type <tt><a>SBV</a>
--   b</tt>.
--   
--   If a default value is supplied, then all the array elements will be
--   initialized to this value. Otherwise, they will be left unspecified,
--   i.e., a read from an unwritten location will produce an uninterpreted
--   constant.
--   
--   The reason for this class is rather historic. In the past, SBV
--   provided two different kinds of arrays: an <a>SArray</a> abstraction
--   that mapped directly to SMTLib arrays (which is still available
--   today), and a functional notion of arrays that used internal caching,
--   called <tt>SFunArray</tt>. The latter has been removed as the code
--   turned out to be rather tricky and hard to maintain; so we only have
--   one instance of this class. But end users can add their own instances,
--   if needed.
--   
--   NB. <a>sListArray</a> insists on a concrete initializer, because not
--   having one would break referential transparency. See
--   <a>https://github.com/LeventErkok/sbv/issues/553</a> for details.
class SymArray array

-- | Generalization of <a>newArray_</a>
newArray_ :: (SymArray array, MonadSymbolic m, HasKind a, HasKind b) => Maybe (SBV b) -> m (array a b)

-- | Generalization of <a>newArray</a>
newArray :: (SymArray array, MonadSymbolic m, HasKind a, HasKind b) => String -> Maybe (SBV b) -> m (array a b)

-- | Read the array element at <tt>a</tt>
readArray :: SymArray array => array a b -> SBV a -> SBV b

-- | Update the element at <tt>a</tt> to be <tt>b</tt>
writeArray :: (SymArray array, SymVal b) => array a b -> SBV a -> SBV b -> array a b

-- | Merge two given arrays on the symbolic condition Intuitively:
--   <tt>mergeArrays cond a b = if cond then a else b</tt>. Merging pushes
--   the if-then-else choice down on to elements
mergeArrays :: (SymArray array, SymVal b) => SBV Bool -> array a b -> array a b -> array a b

-- | Arrays implemented in terms of SMT-arrays:
--   <a>http://smtlib.cs.uiowa.edu/theories-ArraysEx.shtml</a>
--   
--   <ul>
--   <li>Maps directly to SMT-lib arrays</li>
--   <li>Reading from an uninitialized value is OK. If the default value is
--   given in <a>newArray</a>, it will be the result. Otherwise, the read
--   yields an uninterpreted constant.</li>
--   <li>Can check for equality of these arrays</li>
--   <li>Cannot be used in code-generation (i.e., compilation to C)</li>
--   <li>Cannot quick-check theorems using <tt>SArray</tt> values</li>
--   </ul>
data SArray a b

-- | Generalization of <a>sBool</a>
sBool :: MonadSymbolic m => String -> m SBool

-- | Generalization of <a>sWord8</a>
sWord8 :: MonadSymbolic m => String -> m SWord8

-- | Generalization of <a>sWord16</a>
sWord16 :: MonadSymbolic m => String -> m SWord16

-- | Generalization of <a>sWord32</a>
sWord32 :: MonadSymbolic m => String -> m SWord32

-- | Generalization of <a>sWord64</a>
sWord64 :: MonadSymbolic m => String -> m SWord64

-- | Generalization of <a>sWord</a>
sWord :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => String -> m (SWord n)

-- | Generalization of <a>sInt8</a>
sInt8 :: MonadSymbolic m => String -> m SInt8

-- | Generalization of <a>sInt16</a>
sInt16 :: MonadSymbolic m => String -> m SInt16

-- | Generalization of <a>sInt32</a>
sInt32 :: MonadSymbolic m => String -> m SInt32

-- | Generalization of <a>sInt64</a>
sInt64 :: MonadSymbolic m => String -> m SInt64

-- | Generalization of <a>sInt</a>
sInt :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => String -> m (SInt n)

-- | Generalization of <a>sInteger</a>
sInteger :: MonadSymbolic m => String -> m SInteger

-- | Generalization of <a>sReal</a>
sReal :: MonadSymbolic m => String -> m SReal

-- | Generalization of <a>sFloat</a>
sFloat :: MonadSymbolic m => String -> m SFloat

-- | Generalization of <a>sDouble</a>
sDouble :: MonadSymbolic m => String -> m SDouble

-- | Generalization of <a>sChar</a>
sChar :: MonadSymbolic m => String -> m SChar

-- | Generalization of <a>sString</a>
sString :: MonadSymbolic m => String -> m SString

-- | Generalization of <a>sList</a>
sList :: (SymVal a, MonadSymbolic m) => String -> m (SList a)

-- | Generalization of <a>sBools</a>
sBools :: MonadSymbolic m => [String] -> m [SBool]

-- | Generalization of <a>sWord8s</a>
sWord8s :: MonadSymbolic m => [String] -> m [SWord8]

-- | Generalization of <a>sWord16s</a>
sWord16s :: MonadSymbolic m => [String] -> m [SWord16]

-- | Generalization of <a>sWord32s</a>
sWord32s :: MonadSymbolic m => [String] -> m [SWord32]

-- | Generalization of <a>sWord64s</a>
sWord64s :: MonadSymbolic m => [String] -> m [SWord64]

-- | Generalization of <a>sWord64s</a>
sWords :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => [String] -> m [SWord n]

-- | Generalization of <a>sInt8s</a>
sInt8s :: MonadSymbolic m => [String] -> m [SInt8]

-- | Generalization of <a>sInt16s</a>
sInt16s :: MonadSymbolic m => [String] -> m [SInt16]

-- | Generalization of <a>sInt32s</a>
sInt32s :: MonadSymbolic m => [String] -> m [SInt32]

-- | Generalization of <a>sInt64s</a>
sInt64s :: MonadSymbolic m => [String] -> m [SInt64]

-- | Generalization of <a>sInts</a>
sInts :: (KnownNat n, BVIsNonZero n) => MonadSymbolic m => [String] -> m [SInt n]

-- | Generalization of <a>sIntegers</a>
sIntegers :: MonadSymbolic m => [String] -> m [SInteger]

-- | Generalization of <a>sReals</a>
sReals :: MonadSymbolic m => [String] -> m [SReal]

-- | Generalization of <a>sFloats</a>
sFloats :: MonadSymbolic m => [String] -> m [SFloat]

-- | Generalization of <a>sDoubles</a>
sDoubles :: MonadSymbolic m => [String] -> m [SDouble]

-- | Generalization of <a>sChars</a>
sChars :: MonadSymbolic m => [String] -> m [SChar]

-- | Generalization of <a>sStrings</a>
sStrings :: MonadSymbolic m => [String] -> m [SString]

-- | Generalization of <a>sLists</a>
sLists :: (SymVal a, MonadSymbolic m) => [String] -> m [SList a]

-- | Symbolic Equality. Note that we can't use Haskell's <a>Eq</a> class
--   since Haskell insists on returning Bool Comparing symbolic values will
--   necessarily return a symbolic value.
--   
--   Minimal complete definition: None, if the type is instance of
--   <tt>Generic</tt>. Otherwise <a>(.==)</a>.
class EqSymbolic a

-- | Symbolic equality.
(.==) :: EqSymbolic a => a -> a -> SBool

-- | Symbolic inequality.
(./=) :: EqSymbolic a => a -> a -> SBool

-- | Strong equality. On floats (<a>SFloat</a>/<a>SDouble</a>), strong
--   equality is object equality; that is <tt>NaN == NaN</tt> holds, but
--   <tt>+0 == -0</tt> doesn't. On other types, (.===) is simply (.==).
--   Note that (.==) is the <i>right</i> notion of equality for floats per
--   IEEE754 specs, since by definition <tt>+0 == -0</tt> and <tt>NaN</tt>
--   equals no other value including itself. But occasionally we want to be
--   stronger and state <tt>NaN</tt> equals <tt>NaN</tt> and <tt>+0</tt>
--   and <tt>-0</tt> are different from each other. In a context where your
--   type is concrete, simply use <a>fpIsEqualObject</a>. But in a
--   polymorphic context, use the strong equality instead.
--   
--   NB. If you do not care about or work with floats, simply use (.==) and
--   (./=).
(.===) :: EqSymbolic a => a -> a -> SBool

-- | Negation of strong equality. Equaivalent to negation of (.===) on all
--   types.
(./==) :: EqSymbolic a => a -> a -> SBool

-- | Returns (symbolic) <a>sTrue</a> if all the elements of the given list
--   are different.
distinct :: EqSymbolic a => [a] -> SBool

-- | Returns (symbolic) <a>sTrue</a> if all the elements of the given list
--   are different. The second list contains exceptions, i.e., if an
--   element belongs to that set, it will be considered distinct regardless
--   of repetition.
distinctExcept :: EqSymbolic a => [a] -> [a] -> SBool

-- | Returns (symbolic) <a>sTrue</a> if all the elements of the given list
--   are the same.
allEqual :: EqSymbolic a => [a] -> SBool

-- | Symbolic membership test.
sElem :: EqSymbolic a => a -> [a] -> SBool

-- | Symbolic negated membership test.
sNotElem :: EqSymbolic a => a -> [a] -> SBool

-- | Symbolic equality.
(.==) :: (EqSymbolic a, Generic a, GEqSymbolic (Rep a)) => a -> a -> SBool
infix 4 .==
infix 4 ./=
infix 4 .===
infix 4 ./==

-- | Symbolic Comparisons. Similar to <a>Eq</a>, we cannot implement
--   Haskell's <a>Ord</a> class since there is no way to return an
--   <a>Ordering</a> value from a symbolic comparison. Furthermore,
--   <a>OrdSymbolic</a> requires <a>Mergeable</a> to implement
--   if-then-else, for the benefit of implementing symbolic versions of
--   <a>max</a> and <a>min</a> functions.
class (Mergeable a, EqSymbolic a) => OrdSymbolic a

-- | Symbolic less than.
(.<) :: OrdSymbolic a => a -> a -> SBool

-- | Symbolic less than or equal to.
(.<=) :: OrdSymbolic a => a -> a -> SBool

-- | Symbolic greater than.
(.>) :: OrdSymbolic a => a -> a -> SBool

-- | Symbolic greater than or equal to.
(.>=) :: OrdSymbolic a => a -> a -> SBool

-- | Symbolic minimum.
smin :: OrdSymbolic a => a -> a -> a

-- | Symbolic maximum.
smax :: OrdSymbolic a => a -> a -> a

-- | Is the value within the allowed <i>inclusive</i> range?
inRange :: OrdSymbolic a => a -> (a, a) -> SBool
infix 4 .<
infix 4 .<=
infix 4 .>
infix 4 .>=

-- | Equality as a proof method. Allows for very concise construction of
--   equivalence proofs, which is very typical in bit-precise proofs.
class Equality a
(===) :: Equality a => a -> a -> IO ThmResult
infix 4 ===

-- | Symbolic conditionals are modeled by the <a>Mergeable</a> class,
--   describing how to merge the results of an if-then-else call with a
--   symbolic test. SBV provides all basic types as instances of this
--   class, so users only need to declare instances for custom data-types
--   of their programs as needed.
--   
--   A <a>Mergeable</a> instance may be automatically derived for a custom
--   data-type with a single constructor where the type of each field is an
--   instance of <a>Mergeable</a>, such as a record of symbolic values.
--   Users only need to add <a>Generic</a> and <a>Mergeable</a> to the
--   <tt>deriving</tt> clause for the data-type. See <a>Status</a> for an
--   example and an illustration of what the instance would look like if
--   written by hand.
--   
--   The function <a>select</a> is a total-indexing function out of a list
--   of choices with a default value, simulating array/list indexing. It's
--   an n-way generalization of the <a>ite</a> function.
--   
--   Minimal complete definition: None, if the type is instance of
--   <tt>Generic</tt>. Otherwise <a>symbolicMerge</a>. Note that most types
--   subject to merging are likely to be trivial instances of
--   <tt>Generic</tt>.
class Mergeable a

-- | Merge two values based on the condition. The first argument states
--   whether we force the then-and-else branches before the merging, at the
--   word level. This is an efficiency concern; one that we'd rather not
--   make but unfortunately necessary for getting symbolic simulation
--   working efficiently.
symbolicMerge :: Mergeable a => Bool -> SBool -> a -> a -> a

-- | Total indexing operation. <tt>select xs default index</tt> is
--   intuitively the same as <tt>xs !! index</tt>, except it evaluates to
--   <tt>default</tt> if <tt>index</tt> underflows/overflows.
select :: (Mergeable a, Ord b, SymVal b, Num b) => [a] -> a -> SBV b -> a

-- | Merge two values based on the condition. The first argument states
--   whether we force the then-and-else branches before the merging, at the
--   word level. This is an efficiency concern; one that we'd rather not
--   make but unfortunately necessary for getting symbolic simulation
--   working efficiently.
symbolicMerge :: (Mergeable a, Generic a, GMergeable (Rep a)) => Bool -> SBool -> a -> a -> a

-- | If-then-else. This is by definition <a>symbolicMerge</a> with both
--   branches forced. This is typically the desired behavior, but also see
--   <a>iteLazy</a> should you need more laziness.
ite :: Mergeable a => SBool -> a -> a -> a

-- | A Lazy version of ite, which does not force its arguments. This might
--   cause issues for symbolic simulation with large thunks around, so use
--   with care.
iteLazy :: Mergeable a => SBool -> a -> a -> a

-- | Symbolic Numbers. This is a simple class that simply incorporates all
--   number like base types together, simplifying writing polymorphic
--   type-signatures that work for all symbolic numbers, such as
--   <a>SWord8</a>, <a>SInt8</a> etc. For instance, we can write a generic
--   list-minimum function as follows:
--   
--   <pre>
--   mm :: SIntegral a =&gt; [SBV a] -&gt; SBV a
--   mm = foldr1 (a b -&gt; ite (a .&lt;= b) a b)
--   </pre>
--   
--   It is similar to the standard <a>Integral</a> class, except ranging
--   over symbolic instances.
class (SymVal a, Num a, Bits a, Integral a) => SIntegral a

-- | The <a>SDivisible</a> class captures the essence of division.
--   Unfortunately we cannot use Haskell's <a>Integral</a> class since the
--   <a>Real</a> and <a>Enum</a> superclasses are not implementable for
--   symbolic bit-vectors. However, <a>quotRem</a> and <a>divMod</a> both
--   make perfect sense, and the <a>SDivisible</a> class captures this
--   operation. One issue is how division by 0 behaves. The verification
--   technology requires total functions, and there are several design
--   choices here. We follow Isabelle/HOL approach of assigning the value 0
--   for division by 0. Therefore, we impose the following pair of laws:
--   
--   <pre>
--   x <a>sQuotRem</a> 0 = (0, x)
--   x <a>sDivMod</a>  0 = (0, x)
--   </pre>
--   
--   Note that our instances implement this law even when <tt>x</tt> is
--   <tt>0</tt> itself.
--   
--   NB. <a>quot</a> truncates toward zero, while <a>div</a> truncates
--   toward negative infinity.
--   
--   <h3>C code generation of division operations</h3>
--   
--   In the case of division or modulo of a minimal signed value (e.g.
--   <tt>-128</tt> for <a>SInt8</a>) by <tt>-1</tt>, SMTLIB and Haskell
--   agree on what the result should be. Unfortunately the result in C code
--   depends on CPU architecture and compiler settings, as this is
--   undefined behaviour in C. **SBV does not guarantee** what will happen
--   in generated C code in this corner case.
class SDivisible a
sQuotRem :: SDivisible a => a -> a -> (a, a)
sDivMod :: SDivisible a => a -> a -> (a, a)
sQuot :: SDivisible a => a -> a -> a
sRem :: SDivisible a => a -> a -> a
sDiv :: SDivisible a => a -> a -> a
sMod :: SDivisible a => a -> a -> a

-- | Conversion between integral-symbolic values, akin to Haskell's
--   <a>fromIntegral</a>
sFromIntegral :: forall a b. (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b, SymVal b) => SBV a -> SBV b

-- | Generalization of <a>shiftL</a>, when the shift-amount is symbolic.
--   Since Haskell's <a>shiftL</a> only takes an <a>Int</a> as the shift
--   amount, it cannot be used when we have a symbolic amount to shift
--   with.
sShiftLeft :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a

-- | Generalization of <a>shiftR</a>, when the shift-amount is symbolic.
--   Since Haskell's <a>shiftR</a> only takes an <a>Int</a> as the shift
--   amount, it cannot be used when we have a symbolic amount to shift
--   with.
--   
--   NB. If the shiftee is signed, then this is an arithmetic shift;
--   otherwise it's logical, following the usual Haskell convention. See
--   <a>sSignedShiftArithRight</a> for a variant that explicitly uses the
--   msb as the sign bit, even for unsigned underlying types.
sShiftRight :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a

-- | Generalization of <a>rotateL</a>, when the shift-amount is symbolic.
--   Since Haskell's <a>rotateL</a> only takes an <a>Int</a> as the shift
--   amount, it cannot be used when we have a symbolic amount to shift
--   with. The first argument should be a bounded quantity.
sRotateLeft :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a

-- | An implementation of rotate-left, using a barrel shifter like design.
--   Only works when both arguments are finite bitvectors, and furthermore
--   when the second argument is unsigned. The first condition is enforced
--   by the type, but the second is dynamically checked. We provide this
--   implementation as an alternative to <a>sRotateLeft</a> since SMTLib
--   logic does not support variable argument rotates (as opposed to
--   shifts), and thus this implementation can produce better code for
--   verification compared to <a>sRotateLeft</a>.
sBarrelRotateLeft :: (SFiniteBits a, SFiniteBits b) => SBV a -> SBV b -> SBV a

-- | Generalization of <a>rotateR</a>, when the shift-amount is symbolic.
--   Since Haskell's <a>rotateR</a> only takes an <a>Int</a> as the shift
--   amount, it cannot be used when we have a symbolic amount to shift
--   with. The first argument should be a bounded quantity.
sRotateRight :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a

-- | An implementation of rotate-right, using a barrel shifter like design.
--   See comments for <a>sBarrelRotateLeft</a> for details.
sBarrelRotateRight :: (SFiniteBits a, SFiniteBits b) => SBV a -> SBV b -> SBV a

-- | Arithmetic shift-right with a symbolic unsigned shift amount. This is
--   equivalent to <a>sShiftRight</a> when the argument is signed. However,
--   if the argument is unsigned, then it explicitly treats its msb as a
--   sign-bit, and uses it as the bit that gets shifted in. Useful when
--   using the underlying unsigned bit representation to implement custom
--   signed operations. Note that there is no direct Haskell analogue of
--   this function.
sSignedShiftArithRight :: (SFiniteBits a, SIntegral b) => SBV a -> SBV b -> SBV a

-- | Finite bit-length symbolic values. Essentially the same as
--   <a>SIntegral</a>, but further leaves out <a>Integer</a>. Loosely based
--   on Haskell's <tt>FiniteBits</tt> class, but with more methods defined
--   and structured differently to fit into the symbolic world view.
--   Minimal complete definition: <a>sFiniteBitSize</a>.
class (Ord a, SymVal a, Num a, Bits a) => SFiniteBits a

-- | Bit size.
sFiniteBitSize :: SFiniteBits a => SBV a -> Int

-- | Least significant bit of a word, always stored at index 0.
lsb :: SFiniteBits a => SBV a -> SBool

-- | Most significant bit of a word, always stored at the last position.
msb :: SFiniteBits a => SBV a -> SBool

-- | Big-endian blasting of a word into its bits.
blastBE :: SFiniteBits a => SBV a -> [SBool]

-- | Little-endian blasting of a word into its bits.
blastLE :: SFiniteBits a => SBV a -> [SBool]

-- | Reconstruct from given bits, given in little-endian.
fromBitsBE :: SFiniteBits a => [SBool] -> SBV a

-- | Reconstruct from given bits, given in little-endian.
fromBitsLE :: SFiniteBits a => [SBool] -> SBV a

-- | Replacement for <a>testBit</a>, returning <a>SBool</a> instead of
--   <a>Bool</a>.
sTestBit :: SFiniteBits a => SBV a -> Int -> SBool

-- | Variant of <a>sTestBit</a>, where we want to extract multiple bit
--   positions.
sExtractBits :: SFiniteBits a => SBV a -> [Int] -> [SBool]

-- | Variant of <a>popCount</a>, returning a symbolic value.
sPopCount :: SFiniteBits a => SBV a -> SWord8

-- | A combo of <a>setBit</a> and <a>clearBit</a>, when the bit to be set
--   is symbolic.
setBitTo :: SFiniteBits a => SBV a -> Int -> SBool -> SBV a

-- | Full adder, returns carry-out from the addition. Only for unsigned
--   quantities.
fullAdder :: SFiniteBits a => SBV a -> SBV a -> (SBool, SBV a)

-- | Full multiplier, returns both high and low-order bits. Only for
--   unsigned quantities.
fullMultiplier :: SFiniteBits a => SBV a -> SBV a -> (SBV a, SBV a)

-- | Count leading zeros in a word, big-endian interpretation.
sCountLeadingZeros :: SFiniteBits a => SBV a -> SWord8

-- | Count trailing zeros in a word, big-endian interpretation.
sCountTrailingZeros :: SFiniteBits a => SBV a -> SWord8

-- | Extract a portion of bits to form a smaller bit-vector.
bvExtract :: forall i j n bv proxy. (KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat i, KnownNat j, (i + 1) <= n, j <= i, BVIsNonZero ((i - j) + 1)) => proxy i -> proxy j -> SBV (bv n) -> SBV (bv ((i - j) + 1))

-- | Join two bitvectors.
(#) :: (KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat m, BVIsNonZero m, SymVal (bv m)) => SBV (bv n) -> SBV (bv m) -> SBV (bv (n + m))
infixr 5 #

-- | Zero extend a bit-vector.
zeroExtend :: forall n m bv. (KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat m, BVIsNonZero m, SymVal (bv m), (n + 1) <= m, SIntegral (bv (m - n)), BVIsNonZero (m - n)) => SBV (bv n) -> SBV (bv m)

-- | Sign extend a bit-vector.
signExtend :: forall n m bv. (KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat m, BVIsNonZero m, SymVal (bv m), (n + 1) <= m, SFiniteBits (bv n), SIntegral (bv (m - n)), BVIsNonZero (m - n)) => SBV (bv n) -> SBV (bv m)

-- | Drop bits from the top of a bit-vector.
bvDrop :: forall i n m bv proxy. (KnownNat n, BVIsNonZero n, KnownNat i, (i + 1) <= n, ((i + m) - n) <= 0, BVIsNonZero (n - i)) => proxy i -> SBV (bv n) -> SBV (bv m)

-- | Take bits from the top of a bit-vector.
bvTake :: forall i n bv proxy. (KnownNat n, BVIsNonZero n, KnownNat i, BVIsNonZero i, i <= n) => proxy i -> SBV (bv n) -> SBV (bv i)

-- | Symbolic exponentiation using bit blasting and repeated squaring.
--   
--   N.B. The exponent must be unsigned/bounded if symbolic. Signed
--   exponents will be rejected.
(.^) :: (Mergeable b, Num b, SIntegral e) => b -> SBV e -> b

-- | A class of floating-point (IEEE754) operations, some of which behave
--   differently based on rounding modes. Note that unless the rounding
--   mode is concretely RoundNearestTiesToEven, we will not concretely
--   evaluate these, but rather pass down to the SMT solver.
class (SymVal a, RealFloat a) => IEEEFloating a

-- | Compute the floating point absolute value.
fpAbs :: IEEEFloating a => SBV a -> SBV a

-- | Compute the unary negation. Note that <tt>0 - x</tt> is not equivalent
--   to <tt>-x</tt> for floating-point, since <tt>-0</tt> and <tt>0</tt>
--   are different.
fpNeg :: IEEEFloating a => SBV a -> SBV a

-- | Add two floating point values, using the given rounding mode
fpAdd :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a -> SBV a

-- | Subtract two floating point values, using the given rounding mode
fpSub :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a -> SBV a

-- | Multiply two floating point values, using the given rounding mode
fpMul :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a -> SBV a

-- | Divide two floating point values, using the given rounding mode
fpDiv :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a -> SBV a

-- | Fused-multiply-add three floating point values, using the given
--   rounding mode. <tt>fpFMA x y z = x*y+z</tt> but with only one rounding
--   done for the whole operation; not two. Note that we will never
--   concretely evaluate this function since Haskell lacks an FMA
--   implementation.
fpFMA :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a -> SBV a -> SBV a

-- | Compute the square-root of a float, using the given rounding mode
fpSqrt :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a

-- | Compute the remainder: <tt>x - y * n</tt>, where <tt>n</tt> is the
--   truncated integer nearest to x/y. The rounding mode is implicitly
--   assumed to be <tt>RoundNearestTiesToEven</tt>.
fpRem :: IEEEFloating a => SBV a -> SBV a -> SBV a

-- | Round to the nearest integral value, using the given rounding mode.
fpRoundToIntegral :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a

-- | Compute the minimum of two floats, respects <tt>infinity</tt> and
--   <tt>NaN</tt> values
fpMin :: IEEEFloating a => SBV a -> SBV a -> SBV a

-- | Compute the maximum of two floats, respects <tt>infinity</tt> and
--   <tt>NaN</tt> values
fpMax :: IEEEFloating a => SBV a -> SBV a -> SBV a

-- | Are the two given floats exactly the same. That is, <tt>NaN</tt> will
--   compare equal to itself, <tt>+0</tt> will <i>not</i> compare equal to
--   <tt>-0</tt> etc. This is the object level equality, as opposed to the
--   semantic equality. (For the latter, just use <a>.==</a>.)
fpIsEqualObject :: IEEEFloating a => SBV a -> SBV a -> SBool

-- | Is the floating-point number a normal value. (i.e., not denormalized.)
fpIsNormal :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number a subnormal value. (Also known as
--   denormal.)
fpIsSubnormal :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number 0? (Note that both +0 and -0 will satisfy
--   this predicate.)
fpIsZero :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number infinity? (Note that both +oo and -oo
--   will satisfy this predicate.)
fpIsInfinite :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number a NaN value?
fpIsNaN :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number negative? Note that -0 satisfies this
--   predicate but +0 does not.
fpIsNegative :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number positive? Note that +0 satisfies this
--   predicate but -0 does not.
fpIsPositive :: IEEEFloating a => SBV a -> SBool

-- | Is the floating point number -0?
fpIsNegativeZero :: IEEEFloating a => SBV a -> SBool

-- | Is the floating point number +0?
fpIsPositiveZero :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number a regular floating point, i.e., not NaN,
--   nor +oo, nor -oo. Normals or denormals are allowed.
fpIsPoint :: IEEEFloating a => SBV a -> SBool

-- | Rounding mode to be used for the IEEE floating-point operations. Note
--   that Haskell's default is <a>RoundNearestTiesToEven</a>. If you use a
--   different rounding mode, then the counter-examples you get may not
--   match what you observe in Haskell.
data RoundingMode

-- | Round to nearest representable floating point value. If precisely at
--   half-way, pick the even number. (In this context, <i>even</i> means
--   the lowest-order bit is zero.)
RoundNearestTiesToEven :: RoundingMode

-- | Round to nearest representable floating point value. If precisely at
--   half-way, pick the number further away from 0. (That is, for positive
--   values, pick the greater; for negative values, pick the smaller.)
RoundNearestTiesToAway :: RoundingMode

-- | Round towards positive infinity. (Also known as rounding-up or
--   ceiling.)
RoundTowardPositive :: RoundingMode

-- | Round towards negative infinity. (Also known as rounding-down or
--   floor.)
RoundTowardNegative :: RoundingMode

-- | Round towards zero. (Also known as truncation.)
RoundTowardZero :: RoundingMode

-- | The symbolic variant of <a>RoundingMode</a>
type SRoundingMode = SBV RoundingMode

-- | Not-A-Number for <a>Double</a> and <a>Float</a>. Surprisingly, Haskell
--   Prelude doesn't have this value defined, so we provide it here.
nan :: Floating a => a

-- | Infinity for <a>Double</a> and <a>Float</a>. Surprisingly, Haskell
--   Prelude doesn't have this value defined, so we provide it here.
infinity :: Floating a => a

-- | Symbolic variant of Not-A-Number. This value will inhabit
--   <a>SFloat</a>, <a>SDouble</a> and <a>SFloatingPoint</a>. types.
sNaN :: (Floating a, SymVal a) => SBV a

-- | Symbolic variant of infinity. This value will inhabit both
--   <a>SFloat</a>, <a>SDouble</a> and <a>SFloatingPoint</a>. types.
sInfinity :: (Floating a, SymVal a) => SBV a

-- | Symbolic variant of <a>RoundNearestTiesToEven</a>
sRoundNearestTiesToEven :: SRoundingMode

-- | Symbolic variant of <a>RoundNearestTiesToAway</a>
sRoundNearestTiesToAway :: SRoundingMode

-- | Symbolic variant of <a>RoundTowardPositive</a>
sRoundTowardPositive :: SRoundingMode

-- | Symbolic variant of <a>RoundTowardNegative</a>
sRoundTowardNegative :: SRoundingMode

-- | Symbolic variant of <a>RoundTowardZero</a>
sRoundTowardZero :: SRoundingMode

-- | Alias for <a>sRoundNearestTiesToEven</a>
sRNE :: SRoundingMode

-- | Alias for <a>sRoundNearestTiesToAway</a>
sRNA :: SRoundingMode

-- | Alias for <a>sRoundTowardPositive</a>
sRTP :: SRoundingMode

-- | Alias for <a>sRoundTowardNegative</a>
sRTN :: SRoundingMode

-- | Alias for <a>sRoundTowardZero</a>
sRTZ :: SRoundingMode

-- | Conversion to and from floats
class SymVal a => IEEEFloatConvertible a

-- | Convert from an IEEE74 single precision float.
fromSFloat :: IEEEFloatConvertible a => SRoundingMode -> SFloat -> SBV a

-- | Convert to an IEEE-754 Single-precision float.
toSFloat :: IEEEFloatConvertible a => SRoundingMode -> SBV a -> SFloat

-- | Convert to an IEEE-754 Single-precision float.
toSFloat :: (IEEEFloatConvertible a, Integral a) => SRoundingMode -> SBV a -> SFloat

-- | Convert from an IEEE74 double precision float.
fromSDouble :: IEEEFloatConvertible a => SRoundingMode -> SDouble -> SBV a

-- | Convert to an IEEE-754 Double-precision float.
toSDouble :: IEEEFloatConvertible a => SRoundingMode -> SBV a -> SDouble

-- | Convert to an IEEE-754 Double-precision float.
toSDouble :: (IEEEFloatConvertible a, Integral a) => SRoundingMode -> SBV a -> SDouble

-- | Convert from an arbitrary floating point.
fromSFloatingPoint :: (IEEEFloatConvertible a, ValidFloat eb sb) => SRoundingMode -> SFloatingPoint eb sb -> SBV a

-- | Convert to an arbitrary floating point.
toSFloatingPoint :: (IEEEFloatConvertible a, ValidFloat eb sb) => SRoundingMode -> SBV a -> SFloatingPoint eb sb

-- | Convert to an arbitrary floating point.
toSFloatingPoint :: (IEEEFloatConvertible a, Integral a, ValidFloat eb sb) => SRoundingMode -> SBV a -> SFloatingPoint eb sb

-- | Convert an <a>SFloat</a> to an <a>SWord32</a>, preserving the
--   bit-correspondence. Note that since the representation for
--   <tt>NaN</tt>s are not unique, this function will return a symbolic
--   value when given a concrete <tt>NaN</tt>.
--   
--   Implementation note: Since there's no corresponding function in SMTLib
--   for conversion to bit-representation due to partiality, we use a
--   translation trick by allocating a new word variable, converting it to
--   float, and requiring it to be equivalent to the input. In
--   code-generation mode, we simply map it to a simple conversion.
sFloatAsSWord32 :: SFloat -> SWord32

-- | Reinterpret the bits in a 32-bit word as a single-precision floating
--   point number
sWord32AsSFloat :: SWord32 -> SFloat

-- | Convert an <a>SDouble</a> to an <a>SWord64</a>, preserving the
--   bit-correspondence. Note that since the representation for
--   <tt>NaN</tt>s are not unique, this function will return a symbolic
--   value when given a concrete <tt>NaN</tt>.
--   
--   See the implementation note for <a>sFloatAsSWord32</a>, as it applies
--   here as well.
sDoubleAsSWord64 :: SDouble -> SWord64

-- | Reinterpret the bits in a 32-bit word as a single-precision floating
--   point number
sWord64AsSDouble :: SWord64 -> SDouble

-- | Convert a float to the word containing the corresponding bit pattern
sFloatingPointAsSWord :: forall eb sb. (ValidFloat eb sb, KnownNat (eb + sb), BVIsNonZero (eb + sb)) => SFloatingPoint eb sb -> SWord (eb + sb)

-- | Convert a word to an arbitrary float, by reinterpreting the bits of
--   the word as the corresponding bits of the float.
sWordAsSFloatingPoint :: forall eb sb. (KnownNat (eb + sb), BVIsNonZero (eb + sb), ValidFloat eb sb) => SWord (eb + sb) -> SFloatingPoint eb sb

-- | Extract the sign/exponent/mantissa of a single-precision float. The
--   output will have 8 bits in the second argument for exponent, and 23 in
--   the third for the mantissa.
blastSFloat :: SFloat -> (SBool, [SBool], [SBool])

-- | Extract the sign/exponent/mantissa of a single-precision float. The
--   output will have 11 bits in the second argument for exponent, and 52
--   in the third for the mantissa.
blastSDouble :: SDouble -> (SBool, [SBool], [SBool])

-- | Extract the sign/exponent/mantissa of an arbitrary precision float.
--   The output will have <tt>eb</tt> bits in the second argument for
--   exponent, and <tt>sb-1</tt> bits in the third for mantissa.
blastSFloatingPoint :: forall eb sb. (ValidFloat eb sb, KnownNat (eb + sb), BVIsNonZero (eb + sb)) => SFloatingPoint eb sb -> (SBool, [SBool], [SBool])

-- | Make an enumeration a symbolic type.
mkSymbolicEnumeration :: Name -> Q [Dec]

-- | Make an uninterpred sort.
mkUninterpretedSort :: Name -> Q [Dec]

-- | SMT definable constants and functions, which can also be uninterpeted.
--   This class captures functions that we can generate standalone-code for
--   in the SMT solver. Note that we also allow uninterpreted constants and
--   functions too. An uninterpreted constant is a value that is indexed by
--   its name. The only property the prover assumes -- about these values
--   are that they are equivalent to themselves; i.e., (for functions) they
--   return the same results when applied to same arguments. We support
--   uninterpreted-functions as a general means of black-box'ing operations
--   that are <i>irrelevant</i> for the purposes of the proof; i.e., when
--   the proofs can be performed without any knowledge about the function
--   itself.
--   
--   Minimal complete definition: <a>sbvDefineValue</a>. However, most
--   instances in practice are already provided by SBV, so end-users should
--   not need to define their own instances.
class SMTDefinable a

-- | Generate the code for this value as an SMTLib function, instead of the
--   usual unrolling semantics. This is useful for generating sub-functions
--   in generated SMTLib problem, or handling recursive (and
--   mutually-recursive) definitions that wouldn't terminate in an
--   unrolling symbolic simulation context.
--   
--   <b>IMPORTANT NOTE</b> The string argument names this function. Note
--   that SBV will identify this function with that name, i.e., if you use
--   this function twice (or use it recursively), it will simply assume
--   this name uniquely identifies the function being defined. Hence, the
--   user has to assure that this string is unique amongst all the
--   functions you use. Furthermore, if the call to <a>smtFunction</a>
--   happens in the scope of a parameter, you must make sure the string is
--   chosen to keep it unique per parameter value. For instance, if you
--   have:
--   
--   <pre>
--   bar :: SInteger -&gt; SInteger -&gt; SInteger
--   bar k = smtFunction "bar" (x -&gt; x+k)   -- Note the capture of k!
--   </pre>
--   
--   and you call <tt>bar 2</tt> and <tt>bar 3</tt>, you *will* get the
--   same SMTLib function. Obviously this is unsound. The reason is that
--   the parameter value isn't captured by the name. In general, you should
--   simply not do this, but if you must, have a concrete argument to make
--   sure you can create a unique name. Something like:
--   
--   <pre>
--   bar :: String -&gt; SInteger -&gt; SInteger -&gt; SInteger
--   bar tag k = smtFunction ("bar_" ++ tag) (x -&gt; x+k)   -- Tag should make the name unique!
--   </pre>
--   
--   Then, make sure you use <tt>bar "two" 2</tt> and <tt>bar "three"
--   3</tt> etc. to preserve the invariant.
--   
--   Note that this is a design choice, to keep function creation as easy
--   to use as possible. SBV could've made <a>smtFunction</a> a monadic
--   call and generated the name itself to avoid all these issues. But the
--   ergonomics of that is worse, and doesn't fit with the general design
--   philosophy. If you can think of a solution (perhaps using some nifty
--   GHC tricks?) to avoid this issue without making <a>smtFunction</a>
--   return a monadic result, please get in touch!
smtFunction :: (SMTDefinable a, Lambda Symbolic a) => String -> a -> a

-- | Uninterpret a value, i.e., add this value as a completely undefined
--   value/function that the solver is free to instantiate to satisfy other
--   constraints.
uninterpret :: SMTDefinable a => String -> a

-- | Uninterpret a value, only for the purposes of code-generation. For
--   execution and verification the value is used as is. For
--   code-generation, the alternate definition is used. This is useful when
--   we want to take advantage of native libraries on the target languages.
cgUninterpret :: SMTDefinable a => String -> [String] -> a -> a

-- | Most generalized form of uninterpretation, this function should not be
--   needed by end-user-code, but is rather useful for the library
--   development.
sbvDefineValue :: SMTDefinable a => String -> UIKind a -> a

-- | A synonym for <a>uninterpret</a>. Allows us to create variables
--   without having to call <a>free</a> explicitly, i.e., without being in
--   the symbolic monad.
sym :: SMTDefinable a => String -> a

-- | A predicate is a symbolic program that returns a (symbolic) boolean
--   value. For all intents and purposes, it can be treated as an n-ary
--   function from symbolic-values to a boolean. The <a>Symbolic</a> monad
--   captures the underlying representation, and can/should be ignored by
--   the users of the library, unless you are building further utilities on
--   top of SBV itself. Instead, simply use the <a>Predicate</a> type when
--   necessary.
type Predicate = Symbolic SBool

-- | A constraint set is a symbolic program that returns no values. The
--   idea is that the constraints/min-max goals will serve as the
--   collection of constraints that will be used for sat/optimize calls.
type ConstraintSet = Symbolic ()

-- | A type <tt>a</tt> is provable if we can turn it into a predicate,
--   i.e., it has to return a boolean. This class captures essentially
--   prove calls.
class ExtractIO m => ProvableM m a

-- | Reduce an arg, for proof purposes.
proofArgReduce :: ProvableM m a => a -> SymbolicT m SBool

-- | Generalization of <a>prove</a>
prove :: ProvableM m a => a -> m ThmResult

-- | Generalization of <a>proveWith</a>
proveWith :: ProvableM m a => SMTConfig -> a -> m ThmResult

-- | Generalization of <a>dprove</a>
dprove :: ProvableM m a => a -> m ThmResult

-- | Generalization of <a>dproveWith</a>
dproveWith :: ProvableM m a => SMTConfig -> a -> m ThmResult

-- | Generalization of <a>isVacuousProof</a>
isVacuousProof :: ProvableM m a => a -> m Bool

-- | Generalization of <a>isVacuousProofWith</a>
isVacuousProofWith :: ProvableM m a => SMTConfig -> a -> m Bool

-- | Generalization of <a>isTheorem</a>
isTheorem :: ProvableM m a => a -> m Bool

-- | Generalization of <a>isTheoremWith</a>
isTheoremWith :: ProvableM m a => SMTConfig -> a -> m Bool

-- | <a>Provable</a> is specialization of <a>ProvableM</a> to the <a>IO</a>
--   monad. Unless you are using transformers explicitly, this is the type
--   you should prefer.
type Provable = ProvableM IO

-- | A type <tt>a</tt> is satisfiable if it has constraints, potentially
--   returning a boolean. This class captures essentially sat and optimize
--   calls.
class ExtractIO m => SatisfiableM m a

-- | Reduce an arg, for sat purposes.
satArgReduce :: SatisfiableM m a => a -> SymbolicT m SBool

-- | Generalization of <a>sat</a>
sat :: SatisfiableM m a => a -> m SatResult

-- | Generalization of <a>satWith</a>
satWith :: SatisfiableM m a => SMTConfig -> a -> m SatResult

-- | Generalization of <a>sat</a>
dsat :: SatisfiableM m a => a -> m SatResult

-- | Generalization of <a>satWith</a>
dsatWith :: SatisfiableM m a => SMTConfig -> a -> m SatResult

-- | Generalization of <a>allSat</a>
allSat :: SatisfiableM m a => a -> m AllSatResult

-- | Generalization of <a>allSatWith</a>
allSatWith :: SatisfiableM m a => SMTConfig -> a -> m AllSatResult

-- | Generalization of <a>isSatisfiable</a>
isSatisfiable :: SatisfiableM m a => a -> m Bool

-- | Generalization of <a>isSatisfiableWith</a>
isSatisfiableWith :: SatisfiableM m a => SMTConfig -> a -> m Bool

-- | Generalization of <a>optimize</a>
optimize :: SatisfiableM m a => OptimizeStyle -> a -> m OptimizeResult

-- | Generalization of <a>optimizeWith</a>
optimizeWith :: SatisfiableM m a => SMTConfig -> OptimizeStyle -> a -> m OptimizeResult

-- | <a>Satisfiable</a> is specialization of <a>SatisfiableM</a> to the
--   <a>IO</a> monad. Unless you are using transformers explicitly, this is
--   the type you should prefer.
type Satisfiable = SatisfiableM IO

-- | Create an SMT-Lib2 benchmark, for a SAT query.
generateSMTBenchmarkSat :: SatisfiableM m a => a -> m String

-- | Create an SMT-Lib2 benchmark, for a Proof query.
generateSMTBenchmarkProof :: ProvableM m a => a -> m String

-- | Generalization of <a>solve</a>
solve :: MonadSymbolic m => [SBool] -> m SBool

-- | Add a constraint, any satisfying instance must satisfy this condition.
constrain :: (SolverContext m, QuantifiedBool a) => a -> m ()

-- | Add a soft constraint. The solver will try to satisfy this condition
--   if possible, but won't if it cannot.
softConstrain :: (SolverContext m, QuantifiedBool a) => a -> m ()

-- | Add a named constraint. The name is used in unsat-core extraction.
namedConstraint :: (SolverContext m, QuantifiedBool a) => String -> a -> m ()

-- | Add a constraint, with arbitrary attributes.
constrainWithAttribute :: (SolverContext m, QuantifiedBool a) => [(String, String)] -> a -> m ()

-- | <a>sTrue</a> if at most <tt>k</tt> of the input arguments are
--   <a>sTrue</a>
pbAtMost :: [SBool] -> Int -> SBool

-- | <a>sTrue</a> if at least <tt>k</tt> of the input arguments are
--   <a>sTrue</a>
pbAtLeast :: [SBool] -> Int -> SBool

-- | <a>sTrue</a> if exactly <tt>k</tt> of the input arguments are
--   <a>sTrue</a>
pbExactly :: [SBool] -> Int -> SBool

-- | <a>sTrue</a> if the sum of coefficients for <a>sTrue</a> elements is
--   at most <tt>k</tt>. Generalizes <a>pbAtMost</a>.
pbLe :: [(Int, SBool)] -> Int -> SBool

-- | <a>sTrue</a> if the sum of coefficients for <a>sTrue</a> elements is
--   at least <tt>k</tt>. Generalizes <a>pbAtLeast</a>.
pbGe :: [(Int, SBool)] -> Int -> SBool

-- | <a>sTrue</a> if the sum of coefficients for <a>sTrue</a> elements is
--   exactly least <tt>k</tt>. Useful for coding <i>exactly K-of-N</i>
--   constraints, and in particular mutex constraints.
pbEq :: [(Int, SBool)] -> Int -> SBool

-- | <a>sTrue</a> if there is at most one set bit
pbMutexed :: [SBool] -> SBool

-- | <a>sTrue</a> if there is exactly one set bit
pbStronglyMutexed :: [SBool] -> SBool

-- | Symbolic assert. Check that the given boolean condition is always
--   <a>sTrue</a> in the given path. The optional first argument can be
--   used to provide call-stack info via GHC's location facilities.
sAssert :: HasKind a => Maybe CallStack -> String -> SBool -> SBV a -> SBV a

-- | Check if a safe-call was safe or not, turning a <a>SafeResult</a> to a
--   Bool.
isSafe :: SafeResult -> Bool

-- | Symbolically executable program fragments. This class is mainly used
--   for <a>safe</a> calls, and is sufficiently populated internally to
--   cover most use cases. Users can extend it as they wish to allow
--   <a>safe</a> checks for SBV programs that return/take types that are
--   user-defined.
class ExtractIO m => SExecutable m a

-- | Generalization of <a>sName</a>
sName :: SExecutable m a => a -> SymbolicT m ()

-- | Generalization of <a>safe</a>
safe :: SExecutable m a => a -> m [SafeResult]

-- | Generalization of <a>safeWith</a>
safeWith :: SExecutable m a => SMTConfig -> a -> m [SafeResult]

-- | Quick check an SBV property. Note that a regular <tt>quickCheck</tt>
--   call will work just as well. Use this variant if you want to receive
--   the boolean result.
sbvQuickCheck :: Symbolic SBool -> IO Bool

-- | Style of optimization. Note that in the pareto case the user is
--   allowed to specify a max number of fronts to query the solver for,
--   since there might potentially be an infinite number of them and there
--   is no way to know exactly how many ahead of time. If <a>Nothing</a> is
--   given, SBV will possibly loop forever if the number is really
--   infinite.
data OptimizeStyle

-- | Objectives are optimized in the order given, earlier objectives have
--   higher priority.
Lexicographic :: OptimizeStyle

-- | Each objective is optimized independently.
Independent :: OptimizeStyle

-- | Objectives are optimized according to pareto front: That is, no
--   objective can be made better without making some other worse.
Pareto :: Maybe Int -> OptimizeStyle

-- | Objective of optimization. We can minimize, maximize, or give a soft
--   assertion with a penalty for not satisfying it.
data Objective a

-- | Minimize this metric
Minimize :: String -> a -> Objective a

-- | Maximize this metric
Maximize :: String -> a -> Objective a

-- | A soft assertion, with an associated penalty
AssertWithPenalty :: String -> a -> Penalty -> Objective a

-- | Generalization of <a>assertWithPenalty</a>
assertWithPenalty :: MonadSymbolic m => String -> SBool -> Penalty -> m ()

-- | Penalty for a soft-assertion. The default penalty is <tt>1</tt>, with
--   all soft-assertions belonging to the same objective goal. A positive
--   weight and an optional group can be provided by using the
--   <a>Penalty</a> constructor.
data Penalty

-- | Default: Penalty of <tt>1</tt> and no group attached
DefaultPenalty :: Penalty

-- | Penalty with a weight and an optional group
Penalty :: Rational -> Maybe String -> Penalty

-- | A simple expression type over extended values, covering infinity,
--   epsilon and intervals.
data ExtCV
Infinite :: Kind -> ExtCV
Epsilon :: Kind -> ExtCV
Interval :: ExtCV -> ExtCV -> ExtCV
BoundedCV :: CV -> ExtCV
AddExtCV :: ExtCV -> ExtCV -> ExtCV
MulExtCV :: ExtCV -> ExtCV -> ExtCV

-- | A generalized CV allows for expressions involving infinite and epsilon
--   values/intervals Used in optimization problems.
data GeneralizedCV
ExtendedCV :: ExtCV -> GeneralizedCV
RegularCV :: CV -> GeneralizedCV

-- | A <a>prove</a> call results in a <a>ThmResult</a>
newtype ThmResult
ThmResult :: SMTResult -> ThmResult

-- | A <a>sat</a> call results in a <a>SatResult</a> The reason for having
--   a separate <a>SatResult</a> is to have a more meaningful <a>Show</a>
--   instance.
newtype SatResult
SatResult :: SMTResult -> SatResult

-- | An <a>allSat</a> call results in a <a>AllSatResult</a>
data AllSatResult
AllSatResult :: Bool -> Bool -> Bool -> [SMTResult] -> AllSatResult

-- | Did we reach the user given model count limit?
[allSatMaxModelCountReached] :: AllSatResult -> Bool

-- | Did the solver report unknown at the end?
[allSatSolverReturnedUnknown] :: AllSatResult -> Bool

-- | Did the solver report delta-satisfiable at the end?
[allSatSolverReturnedDSat] :: AllSatResult -> Bool

-- | All satisfying models
[allSatResults] :: AllSatResult -> [SMTResult]

-- | A <a>safe</a> call results in a <a>SafeResult</a>
newtype SafeResult
SafeResult :: (Maybe String, String, SMTResult) -> SafeResult

-- | An <a>optimize</a> call results in a <a>OptimizeResult</a>. In the
--   <a>ParetoResult</a> case, the boolean is <a>True</a> if we reached
--   pareto-query limit and so there might be more unqueried results
--   remaining. If <a>False</a>, it means that we have all the pareto
--   fronts returned. See the <a>Pareto</a> <a>OptimizeStyle</a> for
--   details.
data OptimizeResult
LexicographicResult :: SMTResult -> OptimizeResult
ParetoResult :: (Bool, [SMTResult]) -> OptimizeResult
IndependentResult :: [(String, SMTResult)] -> OptimizeResult

-- | The result of an SMT solver call. Each constructor is tagged with the
--   <a>SMTConfig</a> that created it so that further tools can inspect it
--   and build layers of results, if needed. For ordinary uses of the
--   library, this type should not be needed, instead use the accessor
--   functions on it. (Custom Show instances and model extractors.)
data SMTResult

-- | Unsatisfiable. If unsat-cores are enabled, they will be returned in
--   the second parameter.
Unsatisfiable :: SMTConfig -> Maybe [String] -> SMTResult

-- | Satisfiable with model
Satisfiable :: SMTConfig -> SMTModel -> SMTResult

-- | Delta satisfiable with queried string if available and model
DeltaSat :: SMTConfig -> Maybe String -> SMTModel -> SMTResult

-- | Prover returned a model, but in an extension field containing
--   Infinite/epsilon
SatExtField :: SMTConfig -> SMTModel -> SMTResult

-- | Prover returned unknown, with the given reason
Unknown :: SMTConfig -> SMTReasonUnknown -> SMTResult

-- | Prover errored out, with possibly a bogus result
ProofError :: SMTConfig -> [String] -> Maybe SMTResult -> SMTResult

-- | Reason for reporting unknown.
data SMTReasonUnknown
UnknownMemOut :: SMTReasonUnknown
UnknownIncomplete :: SMTReasonUnknown
UnknownTimeOut :: SMTReasonUnknown
UnknownOther :: String -> SMTReasonUnknown

-- | Observe the value of an expression, unconditionally. See
--   <a>observeIf</a> for a generalized version.
observe :: SymVal a => String -> SBV a -> SBV a

-- | Instances of <a>SatModel</a> can be automatically extracted from
--   models returned by the solvers. The idea is that the sbv
--   infrastructure provides a stream of CV's (constant values) coming from
--   the solver, and the type <tt>a</tt> is interpreted based on these
--   constants. Many typical instances are already provided, so new
--   instances can be declared with relative ease.
--   
--   Minimum complete definition: <a>parseCVs</a>
class SatModel a

-- | Given a sequence of constant-words, extract one instance of the type
--   <tt>a</tt>, returning the remaining elements untouched. If the next
--   element is not what's expected for this type you should return
--   <a>Nothing</a>
parseCVs :: SatModel a => [CV] -> Maybe (a, [CV])

-- | Given a parsed model instance, transform it using <tt>f</tt>, and
--   return the result. The default definition for this method should be
--   sufficient in most use cases.
cvtModel :: SatModel a => (a -> Maybe b) -> Maybe (a, [CV]) -> Maybe (b, [CV])

-- | Given a sequence of constant-words, extract one instance of the type
--   <tt>a</tt>, returning the remaining elements untouched. If the next
--   element is not what's expected for this type you should return
--   <a>Nothing</a>
parseCVs :: (SatModel a, Read a) => [CV] -> Maybe (a, [CV])

-- | Various SMT results that we can extract models out of.
class Modelable a

-- | Is there a model?
modelExists :: Modelable a => a -> Bool

-- | Extract assignments of a model, the result is a tuple where the first
--   argument (if True) indicates whether the model was "probable". (i.e.,
--   if the solver returned unknown.)
getModelAssignment :: (Modelable a, SatModel b) => a -> Either String (Bool, b)

-- | Extract a model dictionary. Extract a dictionary mapping the variables
--   to their respective values as returned by the SMT solver. Also see
--   <a>getModelDictionaries</a>.
getModelDictionary :: Modelable a => a -> Map String CV

-- | Extract a model value for a given element. Also see
--   <a>getModelValues</a>.
getModelValue :: (Modelable a, SymVal b) => String -> a -> Maybe b

-- | Extract a representative name for the model value of an uninterpreted
--   kind. This is supposed to correspond to the value as computed
--   internally by the SMT solver; and is unportable from solver to solver.
--   Also see <a>getModelUninterpretedValues</a>.
getModelUninterpretedValue :: Modelable a => String -> a -> Maybe String

-- | A simpler variant of <a>getModelAssignment</a> to get a model out
--   without the fuss.
extractModel :: (Modelable a, SatModel b) => a -> Maybe b

-- | Extract model objective values, for all optimization goals.
getModelObjectives :: Modelable a => a -> Map String GeneralizedCV

-- | Extract the value of an objective
getModelObjectiveValue :: Modelable a => String -> a -> Maybe GeneralizedCV

-- | Extract model uninterpreted-functions
getModelUIFuns :: Modelable a => a -> Map String (SBVType, Either String ([([CV], CV)], CV))

-- | Extract the value of an uninterpreted-function as an association list
getModelUIFunValue :: Modelable a => String -> a -> Maybe (SBVType, Either String ([([CV], CV)], CV))

-- | Given an <a>allSat</a> call, we typically want to iterate over it and
--   print the results in sequence. The <a>displayModels</a> function
--   automates this task by calling <tt>disp</tt> on each result,
--   consecutively. The first <a>Int</a> argument to <tt>disp</tt> 'is the
--   current model number. The second argument is a tuple, where the first
--   element indicates whether the model is alleged (i.e., if the solver is
--   not sure, returning Unknown). The arrange argument can sort the
--   results in any way you like, if necessary.
displayModels :: SatModel a => ([(Bool, a)] -> [(Bool, a)]) -> (Int -> (Bool, a) -> IO ()) -> AllSatResult -> IO Int

-- | Return all the models from an <a>allSat</a> call, similar to
--   <a>extractModel</a> but is suitable for the case of multiple results.
extractModels :: SatModel a => AllSatResult -> [a]

-- | Get dictionaries from an all-sat call. Similar to
--   <a>getModelDictionary</a>.
getModelDictionaries :: AllSatResult -> [Map String CV]

-- | Extract value of a variable from an all-sat call. Similar to
--   <a>getModelValue</a>.
getModelValues :: SymVal b => String -> AllSatResult -> [Maybe b]

-- | Extract value of an uninterpreted variable from an all-sat call.
--   Similar to <a>getModelUninterpretedValue</a>.
getModelUninterpretedValues :: String -> AllSatResult -> [Maybe String]

-- | Solver configuration. See also <a>z3</a>, <a>yices</a>, <a>cvc4</a>,
--   <a>boolector</a>, <a>mathSAT</a>, etc. which are instantiations of
--   this type for those solvers, with reasonable defaults. In particular,
--   custom configuration can be created by varying those values. (Such as
--   <tt>z3{verbose=True}</tt>.)
--   
--   Most fields are self explanatory. The notion of precision for printing
--   algebraic reals stems from the fact that such values does not
--   necessarily have finite decimal representations, and hence we have to
--   stop printing at some depth. It is important to emphasize that such
--   values always have infinite precision internally. The issue is merely
--   with how we print such an infinite precision value on the screen. The
--   field <a>printRealPrec</a> controls the printing precision, by
--   specifying the number of digits after the decimal point. The default
--   value is 16, but it can be set to any positive integer.
--   
--   When printing, SBV will add the suffix <tt>...</tt> at the end of a
--   real-value, if the given bound is not sufficient to represent the
--   real-value exactly. Otherwise, the number will be written out in
--   standard decimal notation. Note that SBV will always print the whole
--   value if it is precise (i.e., if it fits in a finite number of
--   digits), regardless of the precision limit. The limit only applies if
--   the representation of the real value is not finite, i.e., if it is not
--   rational.
--   
--   The <a>printBase</a> field can be used to print numbers in base 2, 10,
--   or 16.
--   
--   The <a>crackNum</a> field can be used to display numbers in detail,
--   all its bits and how they are laid out in memory. Works with all
--   bounded number types (i.e., SWord and SInt), but also with floats. It
--   is particularly useful with floating-point numbers, as it shows you
--   how they are laid out in memory following the IEEE754 rules.
data SMTConfig
SMTConfig :: Bool -> Timing -> Int -> Int -> Bool -> String -> Maybe Int -> Bool -> Bool -> (String -> Bool) -> Bool -> Bool -> Maybe FilePath -> SMTLibVersion -> Maybe Double -> SMTSolver -> [String] -> RoundingMode -> [SMTOption] -> Bool -> Maybe FilePath -> SMTConfig

-- | Debug mode
[verbose] :: SMTConfig -> Bool

-- | Print timing information on how long different phases took
--   (construction, solving, etc.)
[timing] :: SMTConfig -> Timing

-- | Print integral literals in this base (2, 10, and 16 are supported.)
[printBase] :: SMTConfig -> Int

-- | Print algebraic real values with this precision. (SReal, default: 16)
[printRealPrec] :: SMTConfig -> Int

-- | For each numeric value, show it in detail in the model with its bits
--   spliced out. Good for floats.
[crackNum] :: SMTConfig -> Bool

-- | Usually "(check-sat)". However, users might tweak it based on solver
--   characteristics.
[satCmd] :: SMTConfig -> String

-- | In a <a>allSat</a> call, return at most this many models. If nothing,
--   return all.
[allSatMaxModelCount] :: SMTConfig -> Maybe Int

-- | In a <a>allSat</a> call, print models as they are found.
[allSatPrintAlong] :: SMTConfig -> Bool

-- | In a <a>allSat</a> call, should we try to extract values of
--   uninterpreted functions?
[allSatTrackUFs] :: SMTConfig -> Bool

-- | When constructing a model, ignore variables whose name satisfy this
--   predicate. (Default: (const False), i.e., don't ignore anything)
[isNonModelVar] :: SMTConfig -> String -> Bool

-- | If set, SBV will attempt to validate the model it gets back from the
--   solver.
[validateModel] :: SMTConfig -> Bool

-- | Validate optimization results. NB: Does NOT make sure the model is
--   optimal, just checks they satisfy the constraints.
[optimizeValidateConstraints] :: SMTConfig -> Bool

-- | If Just, the entire interaction will be recorded as a playable file
--   (for debugging purposes mostly)
[transcript] :: SMTConfig -> Maybe FilePath

-- | What version of SMT-lib we use for the tool
[smtLibVersion] :: SMTConfig -> SMTLibVersion

-- | Delta-sat precision
[dsatPrecision] :: SMTConfig -> Maybe Double

-- | The actual SMT solver.
[solver] :: SMTConfig -> SMTSolver

-- | Extra command line arguments to pass to the solver.
[extraArgs] :: SMTConfig -> [String]

-- | Rounding mode to use for floating-point conversions
[roundingMode] :: SMTConfig -> RoundingMode

-- | Options to set as we start the solver
[solverSetOptions] :: SMTConfig -> [SMTOption]

-- | If true, we shall ignore the exit code upon exit. Otherwise we require
--   ExitSuccess.
[ignoreExitCode] :: SMTConfig -> Bool

-- | Redirect the verbose output to this file if given. If Nothing, stdout
--   is implied.
[redirectVerbose] :: SMTConfig -> Maybe FilePath

-- | Specify how to save timing information, if at all.
data Timing
NoTiming :: Timing
PrintTiming :: Timing
SaveTiming :: IORef NominalDiffTime -> Timing

-- | Representation of SMTLib Program versions. As of June 2015, we're
--   dropping support for SMTLib1, and supporting SMTLib2 only. We keep
--   this data-type around in case SMTLib3 comes along and we want to
--   support 2 and 3 simultaneously.
data SMTLibVersion
SMTLib2 :: SMTLibVersion

-- | Solvers that SBV is aware of
data Solver
ABC :: Solver
Boolector :: Solver
Bitwuzla :: Solver
CVC4 :: Solver
CVC5 :: Solver
DReal :: Solver
MathSAT :: Solver
Yices :: Solver
Z3 :: Solver

-- | An SMT solver
data SMTSolver
SMTSolver :: Solver -> String -> (String -> String) -> (SMTConfig -> [String]) -> SMTEngine -> SolverCapabilities -> SMTSolver

-- | The solver in use
[name] :: SMTSolver -> Solver

-- | The path to its executable
[executable] :: SMTSolver -> String

-- | Each line sent to the solver will be passed through this function
--   (typically id)
[preprocess] :: SMTSolver -> String -> String

-- | Options to provide to the solver
[options] :: SMTSolver -> SMTConfig -> [String]

-- | The solver engine, responsible for interpreting solver output
[engine] :: SMTSolver -> SMTEngine

-- | Various capabilities of the solver
[capabilities] :: SMTSolver -> SolverCapabilities

-- | Default configuration for the Boolector SMT solver
boolector :: SMTConfig

-- | Default configuration for the Bitwuzla SMT solver
bitwuzla :: SMTConfig

-- | Default configuration for the CVC4 SMT Solver.
cvc4 :: SMTConfig

-- | Default configuration for the CVC5 SMT Solver.
cvc5 :: SMTConfig

-- | Default configuration for the Yices SMT Solver.
dReal :: SMTConfig

-- | Default configuration for the Yices SMT Solver.
yices :: SMTConfig

-- | Default configuration for the Z3 SMT solver
z3 :: SMTConfig

-- | Default configuration for the MathSAT SMT solver
mathSAT :: SMTConfig

-- | Default configuration for the ABC synthesis and verification tool.
abc :: SMTConfig

-- | The default configs corresponding to supported SMT solvers
defaultSolverConfig :: Solver -> SMTConfig

-- | The default solver used by SBV. This is currently set to z3.
defaultSMTCfg :: SMTConfig

-- | Check whether the given solver is installed and is ready to go. This
--   call does a simple call to the solver to ensure all is well.
sbvCheckSolverInstallation :: SMTConfig -> IO Bool

-- | Return the known available solver configs, installed on your machine.
getAvailableSolvers :: IO [SMTConfig]

-- | Set the logic.
setLogic :: SolverContext m => Logic -> m ()

-- | SMT-Lib logics. If left unspecified SBV will pick the logic based on
--   what it determines is needed. However, the user can override this
--   choice using a call to <a>setLogic</a> This is especially handy if one
--   is experimenting with custom logics that might be supported on new
--   solvers. See <a>http://smtlib.cs.uiowa.edu/logics.shtml</a> for the
--   official list.
data Logic

-- | Formulas over the theory of linear integer arithmetic and arrays
--   extended with free sort and function symbols but restricted to arrays
--   with integer indices and values.
AUFLIA :: Logic

-- | Linear formulas with free sort and function symbols over one- and
--   two-dimentional arrays of integer index and real value.
AUFLIRA :: Logic

-- | Formulas with free function and predicate symbols over a theory of
--   arrays of arrays of integer index and real value.
AUFNIRA :: Logic

-- | Linear formulas in linear real arithmetic.
LRA :: Logic

-- | Quantifier-free formulas over the theory of bitvectors and bitvector
--   arrays.
QF_ABV :: Logic

-- | Quantifier-free formulas over the theory of bitvectors and bitvector
--   arrays extended with free sort and function symbols.
QF_AUFBV :: Logic

-- | Quantifier-free linear formulas over the theory of integer arrays
--   extended with free sort and function symbols.
QF_AUFLIA :: Logic

-- | Quantifier-free formulas over the theory of arrays with
--   extensionality.
QF_AX :: Logic

-- | Quantifier-free formulas over the theory of fixed-size bitvectors.
QF_BV :: Logic

-- | Difference Logic over the integers. Boolean combinations of
--   inequations of the form x - y &lt; b where x and y are integer
--   variables and b is an integer constant.
QF_IDL :: Logic

-- | Unquantified linear integer arithmetic. In essence, Boolean
--   combinations of inequations between linear polynomials over integer
--   variables.
QF_LIA :: Logic

-- | Unquantified linear real arithmetic. In essence, Boolean combinations
--   of inequations between linear polynomials over real variables.
QF_LRA :: Logic

-- | Quantifier-free integer arithmetic.
QF_NIA :: Logic

-- | Quantifier-free real arithmetic.
QF_NRA :: Logic

-- | Difference Logic over the reals. In essence, Boolean combinations of
--   inequations of the form x - y &lt; b where x and y are real variables
--   and b is a rational constant.
QF_RDL :: Logic

-- | Unquantified formulas built over a signature of uninterpreted (i.e.,
--   free) sort and function symbols.
QF_UF :: Logic

-- | Unquantified formulas over bitvectors with uninterpreted sort function
--   and symbols.
QF_UFBV :: Logic

-- | Difference Logic over the integers (in essence) but with uninterpreted
--   sort and function symbols.
QF_UFIDL :: Logic

-- | Unquantified linear integer arithmetic with uninterpreted sort and
--   function symbols.
QF_UFLIA :: Logic

-- | Unquantified linear real arithmetic with uninterpreted sort and
--   function symbols.
QF_UFLRA :: Logic

-- | Unquantified non-linear real arithmetic with uninterpreted sort and
--   function symbols.
QF_UFNRA :: Logic

-- | Unquantified non-linear real integer arithmetic with uninterpreted
--   sort and function symbols.
QF_UFNIRA :: Logic

-- | Linear real arithmetic with uninterpreted sort and function symbols.
UFLRA :: Logic

-- | Non-linear integer arithmetic with uninterpreted sort and function
--   symbols.
UFNIA :: Logic

-- | Quantifier-free formulas over the theory of floating point numbers,
--   arrays, and bit-vectors.
QF_FPBV :: Logic

-- | Quantifier-free formulas over the theory of floating point numbers.
QF_FP :: Logic

-- | Quantifier-free finite domains.
QF_FD :: Logic

-- | Quantifier-free formulas over the theory of strings.
QF_S :: Logic

-- | The catch-all value.
Logic_ALL :: Logic

-- | Use this value when you want SBV to simply not set the logic.
Logic_NONE :: Logic

-- | In case you need a really custom string!
CustomLogic :: String -> Logic

-- | Set an option.
setOption :: SolverContext m => SMTOption -> m ()

-- | Set info. Example: <tt>setInfo ":status" ["unsat"]</tt>.
setInfo :: SolverContext m => String -> [String] -> m ()

-- | Set a solver time-out value, in milli-seconds. This function
--   essentially translates to the SMTLib call <tt>(set-info :timeout
--   val)</tt>, and your backend solver may or may not support it! The
--   amount given is in milliseconds. Also see the function <a>timeOut</a>
--   for finer level control of time-outs, directly from SBV.
setTimeOut :: SolverContext m => Integer -> m ()

-- | An exception thrown from SBV. If the solver ever responds with a
--   non-success value for a command, SBV will throw an
--   <a>SBVException</a>, it so the user can process it as required. The
--   provided <a>Show</a> instance will render the failure nicely. Note
--   that if you ever catch this exception, the solver is no longer alive:
--   You should either -- throw the exception up, or do other proper
--   clean-up before continuing.
data SBVException
SBVException :: String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe ExitCode -> SMTConfig -> Maybe [String] -> Maybe [String] -> SBVException
[sbvExceptionDescription] :: SBVException -> String
[sbvExceptionSent] :: SBVException -> Maybe String
[sbvExceptionExpected] :: SBVException -> Maybe String
[sbvExceptionReceived] :: SBVException -> Maybe String
[sbvExceptionStdOut] :: SBVException -> Maybe String
[sbvExceptionStdErr] :: SBVException -> Maybe String
[sbvExceptionExitCode] :: SBVException -> Maybe ExitCode
[sbvExceptionConfig] :: SBVException -> SMTConfig
[sbvExceptionReason] :: SBVException -> Maybe [String]
[sbvExceptionHint] :: SBVException -> Maybe [String]

-- | The <a>Symbolic</a> value. The parameter <tt>a</tt> is phantom, but is
--   extremely important in keeping the user interface strongly typed.
data SBV a

-- | A class for capturing values that have a sign and a size (finite or
--   infinite) minimal complete definition: kindOf, unless you can take
--   advantage of the default signature: This class can be automatically
--   derived for data-types that have a <a>Data</a> instance; this is
--   useful for creating uninterpreted sorts. So, in reality, end users
--   should almost never need to define any methods.
class HasKind a
kindOf :: HasKind a => a -> Kind
hasSign :: HasKind a => a -> Bool
intSizeOf :: HasKind a => a -> Int
isBoolean :: HasKind a => a -> Bool
isBounded :: HasKind a => a -> Bool
isReal :: HasKind a => a -> Bool
isFloat :: HasKind a => a -> Bool
isDouble :: HasKind a => a -> Bool
isRational :: HasKind a => a -> Bool
isFP :: HasKind a => a -> Bool
isUnbounded :: HasKind a => a -> Bool
isUserSort :: HasKind a => a -> Bool
isChar :: HasKind a => a -> Bool
isString :: HasKind a => a -> Bool
isList :: HasKind a => a -> Bool
isSet :: HasKind a => a -> Bool
isTuple :: HasKind a => a -> Bool
isMaybe :: HasKind a => a -> Bool
isEither :: HasKind a => a -> Bool
showType :: HasKind a => a -> String
kindOf :: (HasKind a, Read a, Data a) => a -> Kind

-- | Kind of symbolic value
data Kind
KBool :: Kind
KBounded :: !Bool -> !Int -> Kind
KUnbounded :: Kind
KReal :: Kind
KUserSort :: String -> Maybe [String] -> Kind
KFloat :: Kind
KDouble :: Kind
KFP :: !Int -> !Int -> Kind
KChar :: Kind
KString :: Kind
KList :: Kind -> Kind
KSet :: Kind -> Kind
KTuple :: [Kind] -> Kind
KMaybe :: Kind -> Kind
KRational :: Kind
KEither :: Kind -> Kind -> Kind

-- | A <a>SymVal</a> is a potential symbolic value that can be created
--   instances of to be fed to a symbolic program.
class (HasKind a, Typeable a) => SymVal a

-- | Generalization of <a>mkSymVal</a>
mkSymVal :: (SymVal a, MonadSymbolic m) => VarContext -> Maybe String -> m (SBV a)

-- | Turn a literal constant to symbolic
literal :: SymVal a => a -> SBV a

-- | Extract a literal, from a CV representation
fromCV :: SymVal a => CV -> a

-- | Does it concretely satisfy the given predicate?
isConcretely :: SymVal a => SBV a -> (a -> Bool) -> Bool

-- | Generalization of <a>mkSymVal</a>
mkSymVal :: (SymVal a, MonadSymbolic m, Read a, Data a) => VarContext -> Maybe String -> m (SBV a)

-- | Turn a literal constant to symbolic
literal :: (SymVal a, Show a) => a -> SBV a

-- | Extract a literal, from a CV representation
fromCV :: (SymVal a, Read a) => CV -> a

-- | Generalization of <a>free</a>
free :: (SymVal a, MonadSymbolic m) => String -> m (SBV a)

-- | Generalization of <a>free_</a>
free_ :: (SymVal a, MonadSymbolic m) => m (SBV a)

-- | Generalization of <a>mkFreeVars</a>
mkFreeVars :: (SymVal a, MonadSymbolic m) => Int -> m [SBV a]

-- | Generalization of <a>symbolic</a>
symbolic :: (SymVal a, MonadSymbolic m) => String -> m (SBV a)

-- | Generalization of <a>symbolics</a>
symbolics :: (SymVal a, MonadSymbolic m) => [String] -> m [SBV a]

-- | Extract a literal, if the value is concrete
unliteral :: SymVal a => SBV a -> Maybe a

-- | Is the symbolic word concrete?
isConcrete :: SymVal a => SBV a -> Bool

-- | Is the symbolic word really symbolic?
isSymbolic :: SymVal a => SBV a -> Bool

-- | A Symbolic computation. Represented by a reader monad carrying the
--   state of the computation, layered on top of IO for creating unique
--   references to hold onto intermediate results.
--   
--   Computations which support symbolic operations
class MonadIO m => MonadSymbolic m
symbolicEnv :: MonadSymbolic m => m State
symbolicEnv :: (MonadSymbolic m, MonadTrans t, MonadSymbolic m', m ~ t m') => m State

-- | <a>Symbolic</a> is specialization of <a>SymbolicT</a> to the <a>IO</a>
--   monad. Unless you are using transformers explicitly, this is the type
--   you should prefer.
type Symbolic = SymbolicT IO

-- | A generalization of <a>Symbolic</a>.
data SymbolicT m a

-- | label: Label the result of an expression. This is essentially a no-op,
--   but useful as it generates a comment in the generated C/SMT-Lib code.
--   Note that if the argument is a constant, then the label is dropped
--   completely, per the usual constant folding strategy. Compare this to
--   <a>observe</a> which is good for printing counter-examples.
label :: SymVal a => String -> SBV a -> SBV a

-- | Generalization of <a>output</a>
output :: (Outputtable a, MonadSymbolic m) => a -> m a

-- | Generalization of <a>runSMT</a>
runSMT :: MonadIO m => SymbolicT m a -> m a

-- | Generalization of <a>runSMTWith</a>
runSMTWith :: MonadIO m => SMTConfig -> SymbolicT m a -> m a


-- | (The sbv library is hosted at
--   <a>http://github.com/LeventErkok/sbv</a>. Comments, bug reports, and
--   patches are always welcome.)
--   
--   SBV: SMT Based Verification
--   
--   Express properties about Haskell programs and automatically prove them
--   using SMT solvers.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; x `shiftL` 2 .== 4 * (x :: SWord8)
--   Q.E.D.
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; x `shiftL` 2 .== 2 * (x :: SWord8)
--   Falsifiable. Counter-example:
--     s0 = 64 :: Word8
--   </pre>
--   
--   And similarly, <a>sat</a> finds a satisfying instance. The types
--   involved are:
--   
--   <pre>
--   <a>prove</a> :: <a>Provable</a> a =&gt; a -&gt; <a>IO</a> <a>ThmResult</a>
--   <a>sat</a>   :: <a>Satisfiable</a> a =&gt; a -&gt; <a>IO</a> <a>SatResult</a>
--   </pre>
--   
--   The classes <a>Provable</a> and <a>Satisfiable</a> come with instances
--   for n-ary predicates, for arbitrary n. The predicates are just regular
--   Haskell functions over symbolic types listed below. Functions for
--   checking satisfiability (<a>sat</a> and <a>allSat</a>) are also
--   provided.
--   
--   The sbv library introduces the following symbolic types:
--   
--   <ul>
--   <li><a>SBool</a>: Symbolic Booleans (bits).</li>
--   <li><a>SWord8</a>, <a>SWord16</a>, <a>SWord32</a>, <a>SWord64</a>:
--   Symbolic Words (unsigned).</li>
--   <li><a>SInt8</a>, <a>SInt16</a>, <a>SInt32</a>, <a>SInt64</a>:
--   Symbolic Ints (signed).</li>
--   <li><a>SWord</a> <tt>n</tt>: Generalized symbolic words of arbitrary
--   bit-size.</li>
--   <li><a>SInt</a> <tt>n</tt>: Generalized symbolic ints of arbitrary
--   bit-size.</li>
--   <li><a>SInteger</a>: Unbounded signed integers.</li>
--   <li><a>SReal</a>: Algebraic-real numbers.</li>
--   <li><a>SFloat</a>: IEEE-754 single-precision floating point
--   values.</li>
--   <li><a>SDouble</a>: IEEE-754 double-precision floating point
--   values.</li>
--   <li><a>SRational</a>: Rationals. (Ratio of two symbolic
--   integers.)</li>
--   <li><a>SFloatingPoint</a>: Generalized IEEE-754 floating point values,
--   with user specified exponent and mantissa widths.</li>
--   <li><a>SChar</a>, <a>SString</a>, <a>RegExp</a>: Characters, strings
--   and regular expressions.</li>
--   <li><a>SList</a>: Symbolic lists (which can be nested)</li>
--   <li><a>STuple</a>, <a>STuple2</a>, <a>STuple3</a>, .., <a>STuple8</a>
--   : Symbolic tuples (upto 8-tuples, can be nested)</li>
--   <li><a>SEither</a>: Symbolic sums</li>
--   <li><a>SMaybe</a>: Symbolic optional values.</li>
--   <li><a>SSet</a>: Symbolic sets.</li>
--   <li><a>SArray</a>: Arrays of symbolic values.</li>
--   <li>Symbolic polynomials over GF(2^n), polynomial arithmetic, and
--   CRCs.</li>
--   <li>Uninterpreted constants and functions over symbolic values, with
--   user defined SMT-Lib axioms.</li>
--   <li>Uninterpreted sorts, and proofs over such sorts, potentially with
--   axioms.</li>
--   <li>Ability to define SMTLib functions, generated directly from
--   Haskell versions, including support for recursive and mutually
--   recursive functions.</li>
--   <li>Express quantified formulas (both universals and existentials,
--   including alternating quantifiers), covering first-order logic.</li>
--   <li>Model validation: SBV can validate models returned by solvers,
--   which allows for protection against bugs in SMT solvers and SBV
--   itself. (See the <a>validateModel</a> parameter.)</li>
--   </ul>
--   
--   The user can construct ordinary Haskell programs using these types,
--   which behave very similar to their concrete counterparts. In
--   particular these types belong to the standard classes <a>Num</a>,
--   <a>Bits</a>, custom versions of <a>Eq</a> (<a>EqSymbolic</a>) and
--   <a>Ord</a> (<a>OrdSymbolic</a>), along with several other custom
--   classes for simplifying programming with symbolic values. The
--   framework takes full advantage of Haskell's type inference to avoid
--   many common mistakes.
--   
--   Furthermore, predicates (i.e., functions that return <a>SBool</a>)
--   built out of these types can also be:
--   
--   <ul>
--   <li>proven correct via an external SMT solver (the <a>prove</a>
--   function)</li>
--   <li>checked for satisfiability (the <a>sat</a>, <a>allSat</a>
--   functions)</li>
--   <li>used in synthesis (the <a>sat</a> function with existentials)</li>
--   <li>quick-checked</li>
--   </ul>
--   
--   If a predicate is not valid, <a>prove</a> will return a
--   counterexample: An assignment to inputs such that the predicate fails.
--   The <a>sat</a> function will return a satisfying assignment, if there
--   is one. The <a>allSat</a> function returns all satisfying assignments.
--   
--   The sbv library uses third-party SMT solvers via the standard SMT-Lib
--   interface: <a>http://smtlib.cs.uiowa.edu/</a>
--   
--   The SBV library is designed to work with any SMT-Lib compliant
--   SMT-solver. Currently, we support the following SMT-Solvers out-of-the
--   box:
--   
--   <ul>
--   <li>ABC from University of Berkeley:
--   <a>http://www.eecs.berkeley.edu/~alanmi/abc/</a></li>
--   <li>CVC4, and CVC5 from Stanford University and the University of
--   Iowa. <a>https://cvc4.github.io/</a> and
--   <a>https://cvc5.github.io</a></li>
--   <li>Boolector from Johannes Kepler University:
--   <a>https://boolector.github.io</a> and its successor Bitwuzla from
--   Stanford university: <a>https://bitwuzla.github.io</a></li>
--   <li>MathSAT from Fondazione Bruno Kessler and DISI-University of
--   Trento: <a>http://mathsat.fbk.eu/</a></li>
--   <li>Yices from SRI: <a>http://yices.csl.sri.com/</a></li>
--   <li>DReal from CMU: <a>http://dreal.github.io/</a></li>
--   <li>Z3 from Microsoft: <a>http://github.com/Z3Prover/z3/wiki</a></li>
--   </ul>
--   
--   SBV requires recent versions of these solvers; please see the file
--   <tt>SMTSolverVersions.md</tt> in the source distribution for
--   specifics.
--   
--   SBV also allows calling these solvers in parallel, either getting
--   results from multiple solvers or returning the fastest one. (See
--   <a>proveWithAll</a>, <a>proveWithAny</a>, etc.)
--   
--   Support for other compliant solvers can be added relatively easily,
--   please get in touch if there is a solver you'd like to see included.
module Data.SBV

-- | A symbolic boolean/bit
type SBool = SBV Bool

-- | Symbolic <a>True</a>
sTrue :: SBool

-- | Symbolic <a>False</a>
sFalse :: SBool

-- | Symbolic boolean negation
sNot :: SBool -> SBool

-- | Symbolic conjunction
(.&&) :: SBool -> SBool -> SBool
infixr 3 .&&

-- | Symbolic disjunction
(.||) :: SBool -> SBool -> SBool
infixr 2 .||

-- | Symbolic logical xor
(.<+>) :: SBool -> SBool -> SBool
infixl 6 .<+>

-- | Symbolic nand
(.~&) :: SBool -> SBool -> SBool
infixr 3 .~&

-- | Symbolic nor
(.~|) :: SBool -> SBool -> SBool
infixr 2 .~|

-- | Symbolic implication
(.=>) :: SBool -> SBool -> SBool
infixr 1 .=>

-- | Symbolic boolean equivalence
(.<=>) :: SBool -> SBool -> SBool
infixr 1 .<=>

-- | Conversion from <a>Bool</a> to <a>SBool</a>
fromBool :: Bool -> SBool

-- | Returns 1 if the boolean is <a>sTrue</a>, otherwise 0.
oneIf :: (Ord a, Num a, SymVal a) => SBool -> SBV a

-- | Generalization of <a>and</a>
sAnd :: [SBool] -> SBool

-- | Generalization of <a>or</a>
sOr :: [SBool] -> SBool

-- | Generalization of <a>any</a>
sAny :: (a -> SBool) -> [a] -> SBool

-- | Generalization of <a>all</a>
sAll :: (a -> SBool) -> [a] -> SBool

-- | 8-bit unsigned symbolic value
type SWord8 = SBV Word8

-- | 16-bit unsigned symbolic value
type SWord16 = SBV Word16

-- | 32-bit unsigned symbolic value
type SWord32 = SBV Word32

-- | 64-bit unsigned symbolic value
type SWord64 = SBV Word64

-- | A symbolic unsigned bit-vector carrying its size info
type SWord (n :: Nat) = SBV (WordN n)

-- | An unsigned bit-vector carrying its size info
data WordN (n :: Nat)

-- | 8-bit signed symbolic value, 2's complement representation
type SInt8 = SBV Int8

-- | 16-bit signed symbolic value, 2's complement representation
type SInt16 = SBV Int16

-- | 32-bit signed symbolic value, 2's complement representation
type SInt32 = SBV Int32

-- | 64-bit signed symbolic value, 2's complement representation
type SInt64 = SBV Int64

-- | A symbolic signed bit-vector carrying its size info
type SInt (n :: Nat) = SBV (IntN n)

-- | A signed bit-vector carrying its size info
data IntN (n :: Nat)

-- | Type family to create the appropriate non-zero constraint
type family BVIsNonZero (arg :: Nat) :: Constraint

-- | Capture the correspondence between sized and fixed-sized BVs
type family FromSized (t :: Type) :: Type

-- | Capture the correspondence between fixed-sized and sized BVs
type family ToSized (t :: Type) :: Type

-- | Convert a sized bit-vector to the corresponding fixed-sized
--   bit-vector, for instance 'SWord 16' to <a>SWord16</a>. See also
--   <a>toSized</a>.
fromSized :: FromSizedBV a => a -> FromSized a

-- | Convert a fixed-sized bit-vector to the corresponding sized
--   bit-vector, for instance <a>SWord16</a> to 'SWord 16'. See also
--   <a>fromSized</a>.
toSized :: ToSizedBV a => a -> ToSized a

-- | Infinite precision signed symbolic value
type SInteger = SBV Integer

-- | A valid float has restrictions on eb/sb values. NB. In the below
--   encoding, I found that CPP is very finicky about substitution of the
--   machine-dependent macros. If you try to put the conditionals in the
--   same line, it fails to substitute for some reason. Hence the awkward
--   spacing. Filed this as a bug report for CPPHS at
--   <a>https://github.com/malcolmwallace/cpphs/issues/25</a>.
type family ValidFloat (eb :: Nat) (sb :: Nat) :: Constraint

-- | IEEE-754 single-precision floating point numbers
type SFloat = SBV Float

-- | IEEE-754 double-precision floating point numbers
type SDouble = SBV Double

-- | A symbolic arbitrary precision floating point value
type SFloatingPoint (eb :: Nat) (sb :: Nat) = SBV (FloatingPoint eb sb)

-- | A floating point value, indexed by its exponent and significand sizes.
--   
--   An IEEE SP is <tt>FloatingPoint 8 24</tt> DP is <tt>FloatingPoint 11
--   53</tt> etc.
data FloatingPoint (eb :: Nat) (sb :: Nat)

-- | A symbolic half-precision float
type SFPHalf = SBV FPHalf

-- | Abbreviation for IEEE half precision float, bit width 16 = 5 + 11.
type FPHalf = FloatingPoint 5 11

-- | A symbolic brain-float precision float
type SFPBFloat = SBV FPBFloat

-- | Abbreviation for brain-float precision float, bit width 16 = 8 + 8.
type FPBFloat = FloatingPoint 8 8

-- | A symbolic single-precision float
type SFPSingle = SBV FPSingle

-- | Abbreviation for IEEE single precision float, bit width 32 = 8 + 24.
type FPSingle = FloatingPoint 8 24

-- | A symbolic double-precision float
type SFPDouble = SBV FPDouble

-- | Abbreviation for IEEE double precision float, bit width 64 = 11 + 53.
type FPDouble = FloatingPoint 11 53

-- | A symbolic quad-precision float
type SFPQuad = SBV FPQuad

-- | Abbreviation for IEEE quadruble precision float, bit width 128 = 15 +
--   113.
type FPQuad = FloatingPoint 15 113

-- | A symbolic rational value.
type SRational = SBV Rational

-- | Infinite precision symbolic algebraic real value
type SReal = SBV AlgReal

-- | Algebraic reals. Note that the representation is left abstract. We
--   represent rational results explicitly, while the roots-of-polynomials
--   are represented implicitly by their defining equation
data AlgReal

-- | bool says it's exact (i.e., SMT-solver did not return it with ? at the
--   end.)
AlgRational :: Bool -> Rational -> AlgReal

-- | which root of this polynomial and an approximate decimal
--   representation with given precision, if available
AlgPolyRoot :: (Integer, AlgRealPoly) -> Maybe String -> AlgReal

-- | interval, with low and high bounds
AlgInterval :: RealPoint Rational -> RealPoint Rational -> AlgReal

-- | Convert an SReal to an SInteger. That is, it computes the largest
--   integer <tt>n</tt> that satisfies <tt>sIntegerToSReal n &lt;= r</tt>
--   essentially giving us the <tt>floor</tt>.
--   
--   For instance, <tt>1.3</tt> will be <tt>1</tt>, but <tt>-1.3</tt> will
--   be <tt>-2</tt>.
sRealToSInteger :: SReal -> SInteger

-- | Convert an <a>AlgReal</a> to a <a>Rational</a>. If the <a>AlgReal</a>
--   is exact, then you get a <a>Left</a> value. Otherwise, you get a
--   <a>Right</a> value which is simply an approximation.
algRealToRational :: AlgReal -> RationalCV

-- | Is the endpoint included in the interval?
data RealPoint a

-- | open: i.e., doesn't include the point
OpenPoint :: a -> RealPoint a

-- | closed: i.e., includes the point
ClosedPoint :: a -> RealPoint a

-- | Extract the point associated with the open-closed point
realPoint :: RealPoint a -> a

-- | Conversion from internal rationals to Haskell values
data RationalCV

-- | Root of a polynomial, cannot be reduced
RatIrreducible :: AlgReal -> RationalCV

-- | An exact rational
RatExact :: Rational -> RationalCV

-- | An approximated value
RatApprox :: Rational -> RationalCV

-- | Interval. Can be open/closed on both ends.
RatInterval :: RealPoint Rational -> RealPoint Rational -> RationalCV

-- | A symbolic character. Note that this is the full unicode character
--   set. see:
--   <a>http://smtlib.cs.uiowa.edu/theories-UnicodeStrings.shtml</a> for
--   details.
type SChar = SBV Char

-- | A symbolic string. Note that a symbolic string is <i>not</i> a list of
--   symbolic characters, that is, it is not the case that <tt>SString =
--   [SChar]</tt>, unlike what one might expect following Haskell strings.
--   An <a>SString</a> is a symbolic value of its own, of possibly
--   arbitrary but finite length, and internally processed as one unit as
--   opposed to a fixed-length list of characters.
type SString = SBV String

-- | A symbolic list of items. Note that a symbolic list is <i>not</i> a
--   list of symbolic items, that is, it is not the case that <tt>SList a =
--   [a]</tt>, unlike what one might expect following haskell
--   lists/sequences. An <a>SList</a> is a symbolic value of its own, of
--   possibly arbitrary but finite length, and internally processed as one
--   unit as opposed to a fixed-length list of items. Note that lists can
--   be nested, i.e., we do allow lists of lists of ... items.
type SList a = SBV [a]

-- | Identify tuple like things. Note that there are no methods, just
--   instances to control type inference
class SymTuple a

-- | Symbolic 2-tuple. NB. <a>STuple</a> and <a>STuple2</a> are equivalent.
type STuple a b = SBV (a, b)

-- | Symbolic 2-tuple. NB. <a>STuple</a> and <a>STuple2</a> are equivalent.
type STuple2 a b = SBV (a, b)

-- | Symbolic 3-tuple.
type STuple3 a b c = SBV (a, b, c)

-- | Symbolic 4-tuple.
type STuple4 a b c d = SBV (a, b, c, d)

-- | Symbolic 5-tuple.
type STuple5 a b c d e = SBV (a, b, c, d, e)

-- | Symbolic 6-tuple.
type STuple6 a b c d e f = SBV (a, b, c, d, e, f)

-- | Symbolic 7-tuple.
type STuple7 a b c d e f g = SBV (a, b, c, d, e, f, g)

-- | Symbolic 8-tuple.
type STuple8 a b c d e f g h = SBV (a, b, c, d, e, f, g, h)

-- | Symbolic <a>Maybe</a>
type SMaybe a = SBV (Maybe a)

-- | Symbolic <a>Either</a>
type SEither a b = SBV (Either a b)

-- | A <a>RCSet</a> is either a regular set or a set given by its
--   complement from the corresponding universal set.
data RCSet a
RegularSet :: Set a -> RCSet a
ComplementSet :: Set a -> RCSet a

-- | Symbolic <a>Set</a>. Note that we use <a>RCSet</a>, which supports
--   both regular sets and complements, i.e., those obtained from the
--   universal set (of the right type) by removing elements.
type SSet a = SBV (RCSet a)

-- | Arrays of symbolic values An <tt>array a b</tt> is an array indexed by
--   the type <tt><a>SBV</a> a</tt>, with elements of type <tt><a>SBV</a>
--   b</tt>.
--   
--   If a default value is supplied, then all the array elements will be
--   initialized to this value. Otherwise, they will be left unspecified,
--   i.e., a read from an unwritten location will produce an uninterpreted
--   constant.
--   
--   The reason for this class is rather historic. In the past, SBV
--   provided two different kinds of arrays: an <a>SArray</a> abstraction
--   that mapped directly to SMTLib arrays (which is still available
--   today), and a functional notion of arrays that used internal caching,
--   called <tt>SFunArray</tt>. The latter has been removed as the code
--   turned out to be rather tricky and hard to maintain; so we only have
--   one instance of this class. But end users can add their own instances,
--   if needed.
--   
--   NB. <a>sListArray</a> insists on a concrete initializer, because not
--   having one would break referential transparency. See
--   <a>https://github.com/LeventErkok/sbv/issues/553</a> for details.
class SymArray array

-- | Create a literal array
sListArray :: (SymArray array, HasKind a, SymVal b) => b -> [(SBV a, SBV b)] -> array a b

-- | Read the array element at <tt>a</tt>
readArray :: SymArray array => array a b -> SBV a -> SBV b

-- | Update the element at <tt>a</tt> to be <tt>b</tt>
writeArray :: (SymArray array, SymVal b) => array a b -> SBV a -> SBV b -> array a b

-- | Merge two given arrays on the symbolic condition Intuitively:
--   <tt>mergeArrays cond a b = if cond then a else b</tt>. Merging pushes
--   the if-then-else choice down on to elements
mergeArrays :: (SymArray array, SymVal b) => SBV Bool -> array a b -> array a b -> array a b

-- | Create a new anonymous array, possibly with a default initial value.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>newArray_</a>
newArray_ :: (SymArray array, HasKind a, HasKind b) => Maybe (SBV b) -> Symbolic (array a b)

-- | Create a named new array, possibly with a default initial value.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>newArray</a>
newArray :: (SymArray array, HasKind a, HasKind b) => String -> Maybe (SBV b) -> Symbolic (array a b)

-- | Arrays implemented in terms of SMT-arrays:
--   <a>http://smtlib.cs.uiowa.edu/theories-ArraysEx.shtml</a>
--   
--   <ul>
--   <li>Maps directly to SMT-lib arrays</li>
--   <li>Reading from an uninitialized value is OK. If the default value is
--   given in <a>newArray</a>, it will be the result. Otherwise, the read
--   yields an uninterpreted constant.</li>
--   <li>Can check for equality of these arrays</li>
--   <li>Cannot be used in code-generation (i.e., compilation to C)</li>
--   <li>Cannot quick-check theorems using <tt>SArray</tt> values</li>
--   </ul>
data SArray a b

-- | Using a lambda as an array
lambdaAsArray :: forall a b. (SymVal a, HasKind b) => (SBV a -> SBV b) -> SArray a b

-- | Declare a named <a>SBool</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sBool</a>
sBool :: String -> Symbolic SBool

-- | Declare an unnamed <a>SBool</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sBool_</a>
sBool_ :: Symbolic SBool

-- | Declare a named <a>SWord8</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord8</a>
sWord8 :: String -> Symbolic SWord8

-- | Declare an unnamed <a>SWord8</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord8_</a>
sWord8_ :: Symbolic SWord8

-- | Declare a named <a>SWord16</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord16</a>
sWord16 :: String -> Symbolic SWord16

-- | Declare an unnamed <a>SWord16</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord16_</a>
sWord16_ :: Symbolic SWord16

-- | Declare a named <a>SWord32</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord32</a>
sWord32 :: String -> Symbolic SWord32

-- | Declare an unnamed <a>SWord32</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord32_</a>
sWord32_ :: Symbolic SWord32

-- | Declare a named <a>SWord64</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord64</a>
sWord64 :: String -> Symbolic SWord64

-- | Declare an unnamed <a>SWord64</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord64_</a>
sWord64_ :: Symbolic SWord64

-- | Declare a named <a>SWord</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord</a>
sWord :: (KnownNat n, BVIsNonZero n) => String -> Symbolic (SWord n)

-- | Declare an unnamed <a>SWord</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord_</a>
sWord_ :: (KnownNat n, BVIsNonZero n) => Symbolic (SWord n)

-- | Declare a named <a>SInt8</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt8</a>
sInt8 :: String -> Symbolic SInt8

-- | Declare an unnamed <a>SInt8</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt8_</a>
sInt8_ :: Symbolic SInt8

-- | Declare a named <a>SInt16</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt16</a>
sInt16 :: String -> Symbolic SInt16

-- | Declare an unnamed <a>SInt16</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt16_</a>
sInt16_ :: Symbolic SInt16

-- | Declare a named <a>SInt32</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt32</a>
sInt32 :: String -> Symbolic SInt32

-- | Declare an unnamed <a>SInt32</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt32_</a>
sInt32_ :: Symbolic SInt32

-- | Declare a named <a>SInt64</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt64</a>
sInt64 :: String -> Symbolic SInt64

-- | Declare an unnamed <a>SInt64</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt64_</a>
sInt64_ :: Symbolic SInt64

-- | Declare a named <a>SInt</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt</a>
sInt :: (KnownNat n, BVIsNonZero n) => String -> Symbolic (SInt n)

-- | Declare an unnamed <a>SInt</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt_</a>
sInt_ :: (KnownNat n, BVIsNonZero n) => Symbolic (SInt n)

-- | Declare a named <a>SInteger</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInteger</a>
sInteger :: String -> Symbolic SInteger

-- | Declare an unnamed <a>SInteger</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInteger_</a>
sInteger_ :: Symbolic SInteger

-- | Declare a named <a>SReal</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sReal</a>
sReal :: String -> Symbolic SReal

-- | Declare an unnamed <a>SReal</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sReal_</a>
sReal_ :: Symbolic SReal

-- | Declare a named <a>SRational</a>.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sRational</a>
sRational :: String -> Symbolic SRational

-- | Declare an unnamed <a>SRational</a>.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sRational_</a>
sRational_ :: Symbolic SRational

-- | Declare a named <a>SFloat</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFloat</a>
sFloat :: String -> Symbolic SFloat

-- | Declare an unnamed <a>SFloat</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFloat_</a>
sFloat_ :: Symbolic SFloat

-- | Declare a named <a>SDouble</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sDouble</a>
sDouble :: String -> Symbolic SDouble

-- | Declare an unnamed <a>SDouble</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sDouble_</a>
sDouble_ :: Symbolic SDouble

-- | Declare a named 'SFloatingPoint eb sb'
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFloatingPoint</a>
sFloatingPoint :: ValidFloat eb sb => String -> Symbolic (SFloatingPoint eb sb)

-- | Declare an unnamed <a>SFloatingPoint</a> <tt>eb</tt> <tt>sb</tt>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFloatingPoint_</a>
sFloatingPoint_ :: ValidFloat eb sb => Symbolic (SFloatingPoint eb sb)

-- | Declare a named <a>SFPHalf</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPHalf</a>
sFPHalf :: String -> Symbolic SFPHalf

-- | Declare an unnamed <a>SFPHalf</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPHalf_</a>
sFPHalf_ :: Symbolic SFPHalf

-- | Declare a named <a>SFPBFloat</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>SFPBFloat</a>
sFPBFloat :: String -> Symbolic SFPBFloat

-- | Declare an unnamed <a>SFPBFloat</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>SFPBFloat</a>
sFPBFloat_ :: Symbolic SFPBFloat

-- | Declare a named <a>SFPSingle</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPSingle</a>
sFPSingle :: String -> Symbolic SFPSingle

-- | Declare an unnamed <a>SFPSingle</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPSingle_</a>
sFPSingle_ :: Symbolic SFPSingle

-- | Declare a named <a>SFPDouble</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPDouble</a>
sFPDouble :: String -> Symbolic SFPDouble

-- | Declare an unnamed <a>SFPDouble</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPDouble_</a>
sFPDouble_ :: Symbolic SFPDouble

-- | Declare a named <a>SFPQuad</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPQuad</a>
sFPQuad :: String -> Symbolic SFPQuad

-- | Declare an unnamed <a>SFPQuad</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPQuad_</a>
sFPQuad_ :: Symbolic SFPQuad

-- | Declare a named <a>SChar</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sChar</a>
sChar :: String -> Symbolic SChar

-- | Declare an unnamed <a>SChar</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sChar_</a>
sChar_ :: Symbolic SChar

-- | Declare a named <a>SString</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sString</a>
sString :: String -> Symbolic SString

-- | Declare an unnamed <a>SString</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sString_</a>
sString_ :: Symbolic SString

-- | Declare a named <a>SList</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sList</a>
sList :: SymVal a => String -> Symbolic (SList a)

-- | Declare an unnamed <a>SList</a>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sList_</a>
sList_ :: SymVal a => Symbolic (SList a)

-- | Declare a named tuple.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sTuple</a>
sTuple :: (SymTuple tup, SymVal tup) => String -> Symbolic (SBV tup)

-- | Declare an unnamed tuple.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sTuple_</a>
sTuple_ :: (SymTuple tup, SymVal tup) => Symbolic (SBV tup)

-- | Declare a named <a>SEither</a>.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sEither</a>
sEither :: (SymVal a, SymVal b) => String -> Symbolic (SEither a b)

-- | Declare an unnamed <a>SEither</a>.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sEither_</a>
sEither_ :: (SymVal a, SymVal b) => Symbolic (SEither a b)

-- | Declare a named <a>SMaybe</a>.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sMaybe</a>
sMaybe :: SymVal a => String -> Symbolic (SMaybe a)

-- | Declare an unnamed <a>SMaybe</a>.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sMaybe_</a>
sMaybe_ :: SymVal a => Symbolic (SMaybe a)

-- | Declare a named <a>SSet</a>.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sSet</a>
sSet :: (Ord a, SymVal a) => String -> Symbolic (SSet a)

-- | Declare an unnamed <a>SSet</a>.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sSet_</a>
sSet_ :: (Ord a, SymVal a) => Symbolic (SSet a)

-- | Declare a list of <a>SBool</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sBools</a>
sBools :: [String] -> Symbolic [SBool]

-- | Declare a list of <a>SWord8</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord8s</a>
sWord8s :: [String] -> Symbolic [SWord8]

-- | Declare a list of <a>SWord16</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord16s</a>
sWord16s :: [String] -> Symbolic [SWord16]

-- | Declare a list of <a>SWord32</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord32s</a>
sWord32s :: [String] -> Symbolic [SWord32]

-- | Declare a list of <a>SWord64</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWord64s</a>
sWord64s :: [String] -> Symbolic [SWord64]

-- | Declare a list of <a>SWord8</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sWords</a>
sWords :: (KnownNat n, BVIsNonZero n) => [String] -> Symbolic [SWord n]

-- | Declare a list of <a>SInt8</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt8s</a>
sInt8s :: [String] -> Symbolic [SInt8]

-- | Declare a list of <a>SInt16</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt16s</a>
sInt16s :: [String] -> Symbolic [SInt16]

-- | Declare a list of <a>SInt32</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt32s</a>
sInt32s :: [String] -> Symbolic [SInt32]

-- | Declare a list of <a>SInt64</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInt64s</a>
sInt64s :: [String] -> Symbolic [SInt64]

-- | Declare a list of <a>SInt</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sInts</a>
sInts :: (KnownNat n, BVIsNonZero n) => [String] -> Symbolic [SInt n]

-- | Declare a list of <a>SInteger</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sIntegers</a>
sIntegers :: [String] -> Symbolic [SInteger]

-- | Declare a list of <a>SReal</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sReals</a>
sReals :: [String] -> Symbolic [SReal]

-- | Declare a list of <a>SRational</a> values.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sRationals</a>
sRationals :: [String] -> Symbolic [SRational]

-- | Declare a list of <a>SFloat</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFloats</a>
sFloats :: [String] -> Symbolic [SFloat]

-- | Declare a list of <a>SDouble</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sDoubles</a>
sDoubles :: [String] -> Symbolic [SDouble]

-- | Declare a list of <a>SFloatingPoint</a> <tt>eb</tt> <tt>sb</tt>'s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFloatingPoints</a>
sFloatingPoints :: ValidFloat eb sb => [String] -> Symbolic [SFloatingPoint eb sb]

-- | Declare a list of <a>SFPHalf</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPHalfs</a>
sFPHalfs :: [String] -> Symbolic [SFPHalf]

-- | Declare a list of <a>SFPQuad</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPBFloats</a>
sFPBFloats :: [String] -> Symbolic [SFPBFloat]

-- | Declare a list of <a>SFPSingle</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPSingles</a>
sFPSingles :: [String] -> Symbolic [SFPSingle]

-- | Declare a list of <a>SFPDouble</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPDoubles</a>
sFPDoubles :: [String] -> Symbolic [SFPDouble]

-- | Declare a list of <a>SFPQuad</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sFPQuads</a>
sFPQuads :: [String] -> Symbolic [SFPQuad]

-- | Declare a list of <a>SChar</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sChars</a>
sChars :: [String] -> Symbolic [SChar]

-- | Declare a list of <a>SString</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sStrings</a>
sStrings :: [String] -> Symbolic [SString]

-- | Declare a list of <a>SList</a>s
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sLists</a>
sLists :: SymVal a => [String] -> Symbolic [SList a]

-- | Declare a list of tuples.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sTuples</a>
sTuples :: (SymTuple tup, SymVal tup) => [String] -> Symbolic [SBV tup]

-- | Declare a list of <a>SEither</a> values.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sEithers</a>
sEithers :: (SymVal a, SymVal b) => [String] -> Symbolic [SEither a b]

-- | Declare a list of <a>SMaybe</a> values.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sMaybes</a>
sMaybes :: SymVal a => [String] -> Symbolic [SMaybe a]

-- | Declare a list of <a>SSet</a> values.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sSets</a>
sSets :: (Ord a, SymVal a) => [String] -> Symbolic [SSet a]

-- | Symbolic Equality. Note that we can't use Haskell's <a>Eq</a> class
--   since Haskell insists on returning Bool Comparing symbolic values will
--   necessarily return a symbolic value.
--   
--   Minimal complete definition: None, if the type is instance of
--   <tt>Generic</tt>. Otherwise <a>(.==)</a>.
class EqSymbolic a

-- | Symbolic equality.
(.==) :: EqSymbolic a => a -> a -> SBool

-- | Symbolic inequality.
(./=) :: EqSymbolic a => a -> a -> SBool

-- | Strong equality. On floats (<a>SFloat</a>/<a>SDouble</a>), strong
--   equality is object equality; that is <tt>NaN == NaN</tt> holds, but
--   <tt>+0 == -0</tt> doesn't. On other types, (.===) is simply (.==).
--   Note that (.==) is the <i>right</i> notion of equality for floats per
--   IEEE754 specs, since by definition <tt>+0 == -0</tt> and <tt>NaN</tt>
--   equals no other value including itself. But occasionally we want to be
--   stronger and state <tt>NaN</tt> equals <tt>NaN</tt> and <tt>+0</tt>
--   and <tt>-0</tt> are different from each other. In a context where your
--   type is concrete, simply use <a>fpIsEqualObject</a>. But in a
--   polymorphic context, use the strong equality instead.
--   
--   NB. If you do not care about or work with floats, simply use (.==) and
--   (./=).
(.===) :: EqSymbolic a => a -> a -> SBool

-- | Negation of strong equality. Equaivalent to negation of (.===) on all
--   types.
(./==) :: EqSymbolic a => a -> a -> SBool

-- | Returns (symbolic) <a>sTrue</a> if all the elements of the given list
--   are different.
distinct :: EqSymbolic a => [a] -> SBool

-- | Returns (symbolic) <a>sTrue</a> if all the elements of the given list
--   are different. The second list contains exceptions, i.e., if an
--   element belongs to that set, it will be considered distinct regardless
--   of repetition.
distinctExcept :: EqSymbolic a => [a] -> [a] -> SBool

-- | Returns (symbolic) <a>sTrue</a> if all the elements of the given list
--   are the same.
allEqual :: EqSymbolic a => [a] -> SBool

-- | Symbolic membership test.
sElem :: EqSymbolic a => a -> [a] -> SBool

-- | Symbolic negated membership test.
sNotElem :: EqSymbolic a => a -> [a] -> SBool

-- | Symbolic equality.
(.==) :: (EqSymbolic a, Generic a, GEqSymbolic (Rep a)) => a -> a -> SBool
infix 4 .==
infix 4 ./=
infix 4 .===
infix 4 ./==

-- | Symbolic Comparisons. Similar to <a>Eq</a>, we cannot implement
--   Haskell's <a>Ord</a> class since there is no way to return an
--   <a>Ordering</a> value from a symbolic comparison. Furthermore,
--   <a>OrdSymbolic</a> requires <a>Mergeable</a> to implement
--   if-then-else, for the benefit of implementing symbolic versions of
--   <a>max</a> and <a>min</a> functions.
class (Mergeable a, EqSymbolic a) => OrdSymbolic a

-- | Symbolic less than.
(.<) :: OrdSymbolic a => a -> a -> SBool

-- | Symbolic less than or equal to.
(.<=) :: OrdSymbolic a => a -> a -> SBool

-- | Symbolic greater than.
(.>) :: OrdSymbolic a => a -> a -> SBool

-- | Symbolic greater than or equal to.
(.>=) :: OrdSymbolic a => a -> a -> SBool

-- | Symbolic minimum.
smin :: OrdSymbolic a => a -> a -> a

-- | Symbolic maximum.
smax :: OrdSymbolic a => a -> a -> a

-- | Is the value within the allowed <i>inclusive</i> range?
inRange :: OrdSymbolic a => a -> (a, a) -> SBool
infix 4 .<
infix 4 .<=
infix 4 .>
infix 4 .>=

-- | Equality as a proof method. Allows for very concise construction of
--   equivalence proofs, which is very typical in bit-precise proofs.
class Equality a
(===) :: Equality a => a -> a -> IO ThmResult
infix 4 ===

-- | Symbolic conditionals are modeled by the <a>Mergeable</a> class,
--   describing how to merge the results of an if-then-else call with a
--   symbolic test. SBV provides all basic types as instances of this
--   class, so users only need to declare instances for custom data-types
--   of their programs as needed.
--   
--   A <a>Mergeable</a> instance may be automatically derived for a custom
--   data-type with a single constructor where the type of each field is an
--   instance of <a>Mergeable</a>, such as a record of symbolic values.
--   Users only need to add <a>Generic</a> and <a>Mergeable</a> to the
--   <tt>deriving</tt> clause for the data-type. See <a>Status</a> for an
--   example and an illustration of what the instance would look like if
--   written by hand.
--   
--   The function <a>select</a> is a total-indexing function out of a list
--   of choices with a default value, simulating array/list indexing. It's
--   an n-way generalization of the <a>ite</a> function.
--   
--   Minimal complete definition: None, if the type is instance of
--   <tt>Generic</tt>. Otherwise <a>symbolicMerge</a>. Note that most types
--   subject to merging are likely to be trivial instances of
--   <tt>Generic</tt>.
class Mergeable a

-- | Merge two values based on the condition. The first argument states
--   whether we force the then-and-else branches before the merging, at the
--   word level. This is an efficiency concern; one that we'd rather not
--   make but unfortunately necessary for getting symbolic simulation
--   working efficiently.
symbolicMerge :: Mergeable a => Bool -> SBool -> a -> a -> a

-- | Total indexing operation. <tt>select xs default index</tt> is
--   intuitively the same as <tt>xs !! index</tt>, except it evaluates to
--   <tt>default</tt> if <tt>index</tt> underflows/overflows.
select :: (Mergeable a, Ord b, SymVal b, Num b) => [a] -> a -> SBV b -> a

-- | Merge two values based on the condition. The first argument states
--   whether we force the then-and-else branches before the merging, at the
--   word level. This is an efficiency concern; one that we'd rather not
--   make but unfortunately necessary for getting symbolic simulation
--   working efficiently.
symbolicMerge :: (Mergeable a, Generic a, GMergeable (Rep a)) => Bool -> SBool -> a -> a -> a

-- | If-then-else. This is by definition <a>symbolicMerge</a> with both
--   branches forced. This is typically the desired behavior, but also see
--   <a>iteLazy</a> should you need more laziness.
ite :: Mergeable a => SBool -> a -> a -> a

-- | A Lazy version of ite, which does not force its arguments. This might
--   cause issues for symbolic simulation with large thunks around, so use
--   with care.
iteLazy :: Mergeable a => SBool -> a -> a -> a

-- | Symbolic Numbers. This is a simple class that simply incorporates all
--   number like base types together, simplifying writing polymorphic
--   type-signatures that work for all symbolic numbers, such as
--   <a>SWord8</a>, <a>SInt8</a> etc. For instance, we can write a generic
--   list-minimum function as follows:
--   
--   <pre>
--   mm :: SIntegral a =&gt; [SBV a] -&gt; SBV a
--   mm = foldr1 (a b -&gt; ite (a .&lt;= b) a b)
--   </pre>
--   
--   It is similar to the standard <a>Integral</a> class, except ranging
--   over symbolic instances.
class (SymVal a, Num a, Bits a, Integral a) => SIntegral a

-- | The <a>SDivisible</a> class captures the essence of division.
--   Unfortunately we cannot use Haskell's <a>Integral</a> class since the
--   <a>Real</a> and <a>Enum</a> superclasses are not implementable for
--   symbolic bit-vectors. However, <a>quotRem</a> and <a>divMod</a> both
--   make perfect sense, and the <a>SDivisible</a> class captures this
--   operation. One issue is how division by 0 behaves. The verification
--   technology requires total functions, and there are several design
--   choices here. We follow Isabelle/HOL approach of assigning the value 0
--   for division by 0. Therefore, we impose the following pair of laws:
--   
--   <pre>
--   x <a>sQuotRem</a> 0 = (0, x)
--   x <a>sDivMod</a>  0 = (0, x)
--   </pre>
--   
--   Note that our instances implement this law even when <tt>x</tt> is
--   <tt>0</tt> itself.
--   
--   NB. <a>quot</a> truncates toward zero, while <a>div</a> truncates
--   toward negative infinity.
--   
--   <h3>C code generation of division operations</h3>
--   
--   In the case of division or modulo of a minimal signed value (e.g.
--   <tt>-128</tt> for <a>SInt8</a>) by <tt>-1</tt>, SMTLIB and Haskell
--   agree on what the result should be. Unfortunately the result in C code
--   depends on CPU architecture and compiler settings, as this is
--   undefined behaviour in C. **SBV does not guarantee** what will happen
--   in generated C code in this corner case.
class SDivisible a
sQuotRem :: SDivisible a => a -> a -> (a, a)
sDivMod :: SDivisible a => a -> a -> (a, a)
sQuot :: SDivisible a => a -> a -> a
sRem :: SDivisible a => a -> a -> a
sDiv :: SDivisible a => a -> a -> a
sMod :: SDivisible a => a -> a -> a

-- | Euclidian division and modulus.
sEDivMod :: SInteger -> SInteger -> (SInteger, SInteger)

-- | Euclidian division.
sEDiv :: SInteger -> SInteger -> SInteger

-- | Euclidian modulus.
sEMod :: SInteger -> SInteger -> SInteger

-- | Conversion between integral-symbolic values, akin to Haskell's
--   <a>fromIntegral</a>
sFromIntegral :: forall a b. (Integral a, HasKind a, Num a, SymVal a, HasKind b, Num b, SymVal b) => SBV a -> SBV b

-- | Generalization of <a>shiftL</a>, when the shift-amount is symbolic.
--   Since Haskell's <a>shiftL</a> only takes an <a>Int</a> as the shift
--   amount, it cannot be used when we have a symbolic amount to shift
--   with.
sShiftLeft :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a

-- | Generalization of <a>shiftR</a>, when the shift-amount is symbolic.
--   Since Haskell's <a>shiftR</a> only takes an <a>Int</a> as the shift
--   amount, it cannot be used when we have a symbolic amount to shift
--   with.
--   
--   NB. If the shiftee is signed, then this is an arithmetic shift;
--   otherwise it's logical, following the usual Haskell convention. See
--   <a>sSignedShiftArithRight</a> for a variant that explicitly uses the
--   msb as the sign bit, even for unsigned underlying types.
sShiftRight :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a

-- | Generalization of <a>rotateL</a>, when the shift-amount is symbolic.
--   Since Haskell's <a>rotateL</a> only takes an <a>Int</a> as the shift
--   amount, it cannot be used when we have a symbolic amount to shift
--   with. The first argument should be a bounded quantity.
sRotateLeft :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a

-- | An implementation of rotate-left, using a barrel shifter like design.
--   Only works when both arguments are finite bitvectors, and furthermore
--   when the second argument is unsigned. The first condition is enforced
--   by the type, but the second is dynamically checked. We provide this
--   implementation as an alternative to <a>sRotateLeft</a> since SMTLib
--   logic does not support variable argument rotates (as opposed to
--   shifts), and thus this implementation can produce better code for
--   verification compared to <a>sRotateLeft</a>.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x y -&gt; (x `sBarrelRotateLeft`  y) `sBarrelRotateRight` (y :: SWord32) .== (x :: SWord64)
--   Q.E.D.
--   </pre>
sBarrelRotateLeft :: (SFiniteBits a, SFiniteBits b) => SBV a -> SBV b -> SBV a

-- | Generalization of <a>rotateR</a>, when the shift-amount is symbolic.
--   Since Haskell's <a>rotateR</a> only takes an <a>Int</a> as the shift
--   amount, it cannot be used when we have a symbolic amount to shift
--   with. The first argument should be a bounded quantity.
sRotateRight :: (SIntegral a, SIntegral b) => SBV a -> SBV b -> SBV a

-- | An implementation of rotate-right, using a barrel shifter like design.
--   See comments for <a>sBarrelRotateLeft</a> for details.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x y -&gt; (x `sBarrelRotateRight` y) `sBarrelRotateLeft`  (y :: SWord32) .== (x :: SWord64)
--   Q.E.D.
--   </pre>
sBarrelRotateRight :: (SFiniteBits a, SFiniteBits b) => SBV a -> SBV b -> SBV a

-- | Arithmetic shift-right with a symbolic unsigned shift amount. This is
--   equivalent to <a>sShiftRight</a> when the argument is signed. However,
--   if the argument is unsigned, then it explicitly treats its msb as a
--   sign-bit, and uses it as the bit that gets shifted in. Useful when
--   using the underlying unsigned bit representation to implement custom
--   signed operations. Note that there is no direct Haskell analogue of
--   this function.
sSignedShiftArithRight :: (SFiniteBits a, SIntegral b) => SBV a -> SBV b -> SBV a

-- | Finite bit-length symbolic values. Essentially the same as
--   <a>SIntegral</a>, but further leaves out <a>Integer</a>. Loosely based
--   on Haskell's <tt>FiniteBits</tt> class, but with more methods defined
--   and structured differently to fit into the symbolic world view.
--   Minimal complete definition: <a>sFiniteBitSize</a>.
class (Ord a, SymVal a, Num a, Bits a) => SFiniteBits a

-- | Bit size.
sFiniteBitSize :: SFiniteBits a => SBV a -> Int

-- | Least significant bit of a word, always stored at index 0.
lsb :: SFiniteBits a => SBV a -> SBool

-- | Most significant bit of a word, always stored at the last position.
msb :: SFiniteBits a => SBV a -> SBool

-- | Big-endian blasting of a word into its bits.
blastBE :: SFiniteBits a => SBV a -> [SBool]

-- | Little-endian blasting of a word into its bits.
blastLE :: SFiniteBits a => SBV a -> [SBool]

-- | Reconstruct from given bits, given in little-endian.
fromBitsBE :: SFiniteBits a => [SBool] -> SBV a

-- | Reconstruct from given bits, given in little-endian.
fromBitsLE :: SFiniteBits a => [SBool] -> SBV a

-- | Replacement for <a>testBit</a>, returning <a>SBool</a> instead of
--   <a>Bool</a>.
sTestBit :: SFiniteBits a => SBV a -> Int -> SBool

-- | Variant of <a>sTestBit</a>, where we want to extract multiple bit
--   positions.
sExtractBits :: SFiniteBits a => SBV a -> [Int] -> [SBool]

-- | Variant of <a>popCount</a>, returning a symbolic value.
sPopCount :: SFiniteBits a => SBV a -> SWord8

-- | A combo of <a>setBit</a> and <a>clearBit</a>, when the bit to be set
--   is symbolic.
setBitTo :: SFiniteBits a => SBV a -> Int -> SBool -> SBV a

-- | Full adder, returns carry-out from the addition. Only for unsigned
--   quantities.
fullAdder :: SFiniteBits a => SBV a -> SBV a -> (SBool, SBV a)

-- | Full multiplier, returns both high and low-order bits. Only for
--   unsigned quantities.
fullMultiplier :: SFiniteBits a => SBV a -> SBV a -> (SBV a, SBV a)

-- | Count leading zeros in a word, big-endian interpretation.
sCountLeadingZeros :: SFiniteBits a => SBV a -> SWord8

-- | Count trailing zeros in a word, big-endian interpretation.
sCountTrailingZeros :: SFiniteBits a => SBV a -> SWord8

-- | Extract a portion of bits to form a smaller bit-vector.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; bvExtract (Proxy @7) (Proxy @3) (x :: SWord 12) .== bvDrop (Proxy @4) (bvTake (Proxy @9) x)
--   Q.E.D.
--   </pre>
bvExtract :: forall i j n bv proxy. (KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat i, KnownNat j, (i + 1) <= n, j <= i, BVIsNonZero ((i - j) + 1)) => proxy i -> proxy j -> SBV (bv n) -> SBV (bv ((i - j) + 1))

-- | Join two bitvectors.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x y -&gt; x .== bvExtract (Proxy @79) (Proxy @71) ((x :: SWord 9) # (y :: SWord 71))
--   Q.E.D.
--   </pre>
(#) :: (KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat m, BVIsNonZero m, SymVal (bv m)) => SBV (bv n) -> SBV (bv m) -> SBV (bv (n + m))
infixr 5 #

-- | Zero extend a bit-vector.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; bvExtract (Proxy @20) (Proxy @12) (zeroExtend (x :: SInt 12) :: SInt 21) .== 0
--   Q.E.D.
--   </pre>
zeroExtend :: forall n m bv. (KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat m, BVIsNonZero m, SymVal (bv m), (n + 1) <= m, SIntegral (bv (m - n)), BVIsNonZero (m - n)) => SBV (bv n) -> SBV (bv m)

-- | Sign extend a bit-vector.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; sNot (msb x) .=&gt; bvExtract (Proxy @20) (Proxy @12) (signExtend (x :: SInt 12) :: SInt 21) .== 0
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt;       msb x  .=&gt; bvExtract (Proxy @20) (Proxy @12) (signExtend (x :: SInt 12) :: SInt 21) .== complement 0
--   Q.E.D.
--   </pre>
signExtend :: forall n m bv. (KnownNat n, BVIsNonZero n, SymVal (bv n), KnownNat m, BVIsNonZero m, SymVal (bv m), (n + 1) <= m, SFiniteBits (bv n), SIntegral (bv (m - n)), BVIsNonZero (m - n)) => SBV (bv n) -> SBV (bv m)

-- | Drop bits from the top of a bit-vector.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; bvDrop (Proxy @0) (x :: SWord 43) .== x
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt; bvDrop (Proxy @20) (x :: SWord 21) .== ite (lsb x) 1 (0 :: SWord 1)
--   Q.E.D.
--   </pre>
bvDrop :: forall i n m bv proxy. (KnownNat n, BVIsNonZero n, KnownNat i, (i + 1) <= n, ((i + m) - n) <= 0, BVIsNonZero (n - i)) => proxy i -> SBV (bv n) -> SBV (bv m)

-- | Take bits from the top of a bit-vector.
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; bvTake (Proxy @13) (x :: SWord 13) .== x
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt; bvTake (Proxy @1) (x :: SWord 13) .== ite (msb x) 1 0
--   Q.E.D.
--   
--   &gt;&gt;&gt; prove $ \x -&gt; bvTake (Proxy @4) x # bvDrop (Proxy @4) x .== (x :: SWord 23)
--   Q.E.D.
--   </pre>
bvTake :: forall i n bv proxy. (KnownNat n, BVIsNonZero n, KnownNat i, BVIsNonZero i, i <= n) => proxy i -> SBV (bv n) -> SBV (bv i)

-- | A helper class to convert sized bit-vectors to/from bytes.
class ByteConverter a

-- | Convert to a sequence of bytes
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \a b c d -&gt; toBytes ((fromBytes [a, b, c, d]) :: SWord 32) .== [a, b, c, d]
--   Q.E.D.
--   </pre>
toBytes :: ByteConverter a => a -> [SWord 8]

-- | Convert from a sequence of bytes
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \r -&gt; fromBytes (toBytes r) .== (r :: SWord 64)
--   Q.E.D.
--   </pre>
fromBytes :: ByteConverter a => [SWord 8] -> a

-- | Symbolic exponentiation using bit blasting and repeated squaring.
--   
--   N.B. The exponent must be unsigned/bounded if symbolic. Signed
--   exponents will be rejected.
(.^) :: (Mergeable b, Num b, SIntegral e) => b -> SBV e -> b

-- | A class of floating-point (IEEE754) operations, some of which behave
--   differently based on rounding modes. Note that unless the rounding
--   mode is concretely RoundNearestTiesToEven, we will not concretely
--   evaluate these, but rather pass down to the SMT solver.
class (SymVal a, RealFloat a) => IEEEFloating a

-- | Compute the floating point absolute value.
fpAbs :: IEEEFloating a => SBV a -> SBV a

-- | Compute the unary negation. Note that <tt>0 - x</tt> is not equivalent
--   to <tt>-x</tt> for floating-point, since <tt>-0</tt> and <tt>0</tt>
--   are different.
fpNeg :: IEEEFloating a => SBV a -> SBV a

-- | Add two floating point values, using the given rounding mode
fpAdd :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a -> SBV a

-- | Subtract two floating point values, using the given rounding mode
fpSub :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a -> SBV a

-- | Multiply two floating point values, using the given rounding mode
fpMul :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a -> SBV a

-- | Divide two floating point values, using the given rounding mode
fpDiv :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a -> SBV a

-- | Fused-multiply-add three floating point values, using the given
--   rounding mode. <tt>fpFMA x y z = x*y+z</tt> but with only one rounding
--   done for the whole operation; not two. Note that we will never
--   concretely evaluate this function since Haskell lacks an FMA
--   implementation.
fpFMA :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a -> SBV a -> SBV a

-- | Compute the square-root of a float, using the given rounding mode
fpSqrt :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a

-- | Compute the remainder: <tt>x - y * n</tt>, where <tt>n</tt> is the
--   truncated integer nearest to x/y. The rounding mode is implicitly
--   assumed to be <tt>RoundNearestTiesToEven</tt>.
fpRem :: IEEEFloating a => SBV a -> SBV a -> SBV a

-- | Round to the nearest integral value, using the given rounding mode.
fpRoundToIntegral :: IEEEFloating a => SRoundingMode -> SBV a -> SBV a

-- | Compute the minimum of two floats, respects <tt>infinity</tt> and
--   <tt>NaN</tt> values
fpMin :: IEEEFloating a => SBV a -> SBV a -> SBV a

-- | Compute the maximum of two floats, respects <tt>infinity</tt> and
--   <tt>NaN</tt> values
fpMax :: IEEEFloating a => SBV a -> SBV a -> SBV a

-- | Are the two given floats exactly the same. That is, <tt>NaN</tt> will
--   compare equal to itself, <tt>+0</tt> will <i>not</i> compare equal to
--   <tt>-0</tt> etc. This is the object level equality, as opposed to the
--   semantic equality. (For the latter, just use <a>.==</a>.)
fpIsEqualObject :: IEEEFloating a => SBV a -> SBV a -> SBool

-- | Is the floating-point number a normal value. (i.e., not denormalized.)
fpIsNormal :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number a subnormal value. (Also known as
--   denormal.)
fpIsSubnormal :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number 0? (Note that both +0 and -0 will satisfy
--   this predicate.)
fpIsZero :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number infinity? (Note that both +oo and -oo
--   will satisfy this predicate.)
fpIsInfinite :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number a NaN value?
fpIsNaN :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number negative? Note that -0 satisfies this
--   predicate but +0 does not.
fpIsNegative :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number positive? Note that +0 satisfies this
--   predicate but -0 does not.
fpIsPositive :: IEEEFloating a => SBV a -> SBool

-- | Is the floating point number -0?
fpIsNegativeZero :: IEEEFloating a => SBV a -> SBool

-- | Is the floating point number +0?
fpIsPositiveZero :: IEEEFloating a => SBV a -> SBool

-- | Is the floating-point number a regular floating point, i.e., not NaN,
--   nor +oo, nor -oo. Normals or denormals are allowed.
fpIsPoint :: IEEEFloating a => SBV a -> SBool

-- | Rounding mode to be used for the IEEE floating-point operations. Note
--   that Haskell's default is <a>RoundNearestTiesToEven</a>. If you use a
--   different rounding mode, then the counter-examples you get may not
--   match what you observe in Haskell.
data RoundingMode

-- | Round to nearest representable floating point value. If precisely at
--   half-way, pick the even number. (In this context, <i>even</i> means
--   the lowest-order bit is zero.)
RoundNearestTiesToEven :: RoundingMode

-- | Round to nearest representable floating point value. If precisely at
--   half-way, pick the number further away from 0. (That is, for positive
--   values, pick the greater; for negative values, pick the smaller.)
RoundNearestTiesToAway :: RoundingMode

-- | Round towards positive infinity. (Also known as rounding-up or
--   ceiling.)
RoundTowardPositive :: RoundingMode

-- | Round towards negative infinity. (Also known as rounding-down or
--   floor.)
RoundTowardNegative :: RoundingMode

-- | Round towards zero. (Also known as truncation.)
RoundTowardZero :: RoundingMode

-- | The symbolic variant of <a>RoundingMode</a>
type SRoundingMode = SBV RoundingMode

-- | Not-A-Number for <a>Double</a> and <a>Float</a>. Surprisingly, Haskell
--   Prelude doesn't have this value defined, so we provide it here.
nan :: Floating a => a

-- | Infinity for <a>Double</a> and <a>Float</a>. Surprisingly, Haskell
--   Prelude doesn't have this value defined, so we provide it here.
infinity :: Floating a => a

-- | Symbolic variant of Not-A-Number. This value will inhabit
--   <a>SFloat</a>, <a>SDouble</a> and <a>SFloatingPoint</a>. types.
sNaN :: (Floating a, SymVal a) => SBV a

-- | Symbolic variant of infinity. This value will inhabit both
--   <a>SFloat</a>, <a>SDouble</a> and <a>SFloatingPoint</a>. types.
sInfinity :: (Floating a, SymVal a) => SBV a

-- | Symbolic variant of <a>RoundNearestTiesToEven</a>
sRoundNearestTiesToEven :: SRoundingMode

-- | Symbolic variant of <a>RoundNearestTiesToAway</a>
sRoundNearestTiesToAway :: SRoundingMode

-- | Symbolic variant of <a>RoundTowardPositive</a>
sRoundTowardPositive :: SRoundingMode

-- | Symbolic variant of <a>RoundTowardNegative</a>
sRoundTowardNegative :: SRoundingMode

-- | Symbolic variant of <a>RoundTowardZero</a>
sRoundTowardZero :: SRoundingMode

-- | Alias for <a>sRoundNearestTiesToEven</a>
sRNE :: SRoundingMode

-- | Alias for <a>sRoundNearestTiesToAway</a>
sRNA :: SRoundingMode

-- | Alias for <a>sRoundTowardPositive</a>
sRTP :: SRoundingMode

-- | Alias for <a>sRoundTowardNegative</a>
sRTN :: SRoundingMode

-- | Alias for <a>sRoundTowardZero</a>
sRTZ :: SRoundingMode

-- | Conversion to and from floats
class SymVal a => IEEEFloatConvertible a

-- | Convert from an IEEE74 single precision float.
fromSFloat :: IEEEFloatConvertible a => SRoundingMode -> SFloat -> SBV a

-- | Convert to an IEEE-754 Single-precision float.
toSFloat :: IEEEFloatConvertible a => SRoundingMode -> SBV a -> SFloat

-- | Convert to an IEEE-754 Single-precision float.
toSFloat :: (IEEEFloatConvertible a, Integral a) => SRoundingMode -> SBV a -> SFloat

-- | Convert from an IEEE74 double precision float.
fromSDouble :: IEEEFloatConvertible a => SRoundingMode -> SDouble -> SBV a

-- | Convert to an IEEE-754 Double-precision float.
toSDouble :: IEEEFloatConvertible a => SRoundingMode -> SBV a -> SDouble

-- | Convert to an IEEE-754 Double-precision float.
toSDouble :: (IEEEFloatConvertible a, Integral a) => SRoundingMode -> SBV a -> SDouble

-- | Convert from an arbitrary floating point.
fromSFloatingPoint :: (IEEEFloatConvertible a, ValidFloat eb sb) => SRoundingMode -> SFloatingPoint eb sb -> SBV a

-- | Convert to an arbitrary floating point.
toSFloatingPoint :: (IEEEFloatConvertible a, ValidFloat eb sb) => SRoundingMode -> SBV a -> SFloatingPoint eb sb

-- | Convert to an arbitrary floating point.
toSFloatingPoint :: (IEEEFloatConvertible a, Integral a, ValidFloat eb sb) => SRoundingMode -> SBV a -> SFloatingPoint eb sb

-- | Convert an <a>SFloat</a> to an <a>SWord32</a>, preserving the
--   bit-correspondence. Note that since the representation for
--   <tt>NaN</tt>s are not unique, this function will return a symbolic
--   value when given a concrete <tt>NaN</tt>.
--   
--   Implementation note: Since there's no corresponding function in SMTLib
--   for conversion to bit-representation due to partiality, we use a
--   translation trick by allocating a new word variable, converting it to
--   float, and requiring it to be equivalent to the input. In
--   code-generation mode, we simply map it to a simple conversion.
sFloatAsSWord32 :: SFloat -> SWord32

-- | Reinterpret the bits in a 32-bit word as a single-precision floating
--   point number
sWord32AsSFloat :: SWord32 -> SFloat

-- | Convert an <a>SDouble</a> to an <a>SWord64</a>, preserving the
--   bit-correspondence. Note that since the representation for
--   <tt>NaN</tt>s are not unique, this function will return a symbolic
--   value when given a concrete <tt>NaN</tt>.
--   
--   See the implementation note for <a>sFloatAsSWord32</a>, as it applies
--   here as well.
sDoubleAsSWord64 :: SDouble -> SWord64

-- | Reinterpret the bits in a 32-bit word as a single-precision floating
--   point number
sWord64AsSDouble :: SWord64 -> SDouble

-- | Convert a float to the word containing the corresponding bit pattern
sFloatingPointAsSWord :: forall eb sb. (ValidFloat eb sb, KnownNat (eb + sb), BVIsNonZero (eb + sb)) => SFloatingPoint eb sb -> SWord (eb + sb)

-- | Convert a word to an arbitrary float, by reinterpreting the bits of
--   the word as the corresponding bits of the float.
sWordAsSFloatingPoint :: forall eb sb. (KnownNat (eb + sb), BVIsNonZero (eb + sb), ValidFloat eb sb) => SWord (eb + sb) -> SFloatingPoint eb sb

-- | Extract the sign/exponent/mantissa of a single-precision float. The
--   output will have 8 bits in the second argument for exponent, and 23 in
--   the third for the mantissa.
blastSFloat :: SFloat -> (SBool, [SBool], [SBool])

-- | Extract the sign/exponent/mantissa of a single-precision float. The
--   output will have 11 bits in the second argument for exponent, and 52
--   in the third for the mantissa.
blastSDouble :: SDouble -> (SBool, [SBool], [SBool])

-- | Extract the sign/exponent/mantissa of an arbitrary precision float.
--   The output will have <tt>eb</tt> bits in the second argument for
--   exponent, and <tt>sb-1</tt> bits in the third for mantissa.
blastSFloatingPoint :: forall eb sb. (ValidFloat eb sb, KnownNat (eb + sb), BVIsNonZero (eb + sb)) => SFloatingPoint eb sb -> (SBool, [SBool], [SBool])

-- | Show a value in detailed (cracked) form, if possible. This makes most
--   sense with numbers, and especially floating-point types.
crack :: SBV a -> String

-- | Make an enumeration a symbolic type.
mkSymbolicEnumeration :: Name -> Q [Dec]

-- | Make an uninterpred sort.
mkUninterpretedSort :: Name -> Q [Dec]

-- | SMT definable constants and functions, which can also be uninterpeted.
--   This class captures functions that we can generate standalone-code for
--   in the SMT solver. Note that we also allow uninterpreted constants and
--   functions too. An uninterpreted constant is a value that is indexed by
--   its name. The only property the prover assumes -- about these values
--   are that they are equivalent to themselves; i.e., (for functions) they
--   return the same results when applied to same arguments. We support
--   uninterpreted-functions as a general means of black-box'ing operations
--   that are <i>irrelevant</i> for the purposes of the proof; i.e., when
--   the proofs can be performed without any knowledge about the function
--   itself.
--   
--   Minimal complete definition: <a>sbvDefineValue</a>. However, most
--   instances in practice are already provided by SBV, so end-users should
--   not need to define their own instances.
class SMTDefinable a

-- | Generate the code for this value as an SMTLib function, instead of the
--   usual unrolling semantics. This is useful for generating sub-functions
--   in generated SMTLib problem, or handling recursive (and
--   mutually-recursive) definitions that wouldn't terminate in an
--   unrolling symbolic simulation context.
--   
--   <b>IMPORTANT NOTE</b> The string argument names this function. Note
--   that SBV will identify this function with that name, i.e., if you use
--   this function twice (or use it recursively), it will simply assume
--   this name uniquely identifies the function being defined. Hence, the
--   user has to assure that this string is unique amongst all the
--   functions you use. Furthermore, if the call to <a>smtFunction</a>
--   happens in the scope of a parameter, you must make sure the string is
--   chosen to keep it unique per parameter value. For instance, if you
--   have:
--   
--   <pre>
--   bar :: SInteger -&gt; SInteger -&gt; SInteger
--   bar k = smtFunction "bar" (x -&gt; x+k)   -- Note the capture of k!
--   </pre>
--   
--   and you call <tt>bar 2</tt> and <tt>bar 3</tt>, you *will* get the
--   same SMTLib function. Obviously this is unsound. The reason is that
--   the parameter value isn't captured by the name. In general, you should
--   simply not do this, but if you must, have a concrete argument to make
--   sure you can create a unique name. Something like:
--   
--   <pre>
--   bar :: String -&gt; SInteger -&gt; SInteger -&gt; SInteger
--   bar tag k = smtFunction ("bar_" ++ tag) (x -&gt; x+k)   -- Tag should make the name unique!
--   </pre>
--   
--   Then, make sure you use <tt>bar "two" 2</tt> and <tt>bar "three"
--   3</tt> etc. to preserve the invariant.
--   
--   Note that this is a design choice, to keep function creation as easy
--   to use as possible. SBV could've made <a>smtFunction</a> a monadic
--   call and generated the name itself to avoid all these issues. But the
--   ergonomics of that is worse, and doesn't fit with the general design
--   philosophy. If you can think of a solution (perhaps using some nifty
--   GHC tricks?) to avoid this issue without making <a>smtFunction</a>
--   return a monadic result, please get in touch!
smtFunction :: (SMTDefinable a, Lambda Symbolic a) => String -> a -> a

-- | Uninterpret a value, i.e., add this value as a completely undefined
--   value/function that the solver is free to instantiate to satisfy other
--   constraints.
uninterpret :: SMTDefinable a => String -> a

-- | Uninterpret a value, only for the purposes of code-generation. For
--   execution and verification the value is used as is. For
--   code-generation, the alternate definition is used. This is useful when
--   we want to take advantage of native libraries on the target languages.
cgUninterpret :: SMTDefinable a => String -> [String] -> a -> a

-- | Most generalized form of uninterpretation, this function should not be
--   needed by end-user-code, but is rather useful for the library
--   development.
sbvDefineValue :: SMTDefinable a => String -> UIKind a -> a

-- | A synonym for <a>uninterpret</a>. Allows us to create variables
--   without having to call <a>free</a> explicitly, i.e., without being in
--   the symbolic monad.
sym :: SMTDefinable a => String -> a

-- | A type synonym for binary relations.
type Relation a = (SBV a, SBV a) -> SBool

-- | Check if a relation is a partial order. The string argument must
--   uniquely identify this order.
isPartialOrder :: SymVal a => String -> Relation a -> SBool

-- | Check if a relation is a linear order. The string argument must
--   uniquely identify this order.
isLinearOrder :: SymVal a => String -> Relation a -> SBool

-- | Check if a relation is a tree order. The string argument must uniquely
--   identify this order.
isTreeOrder :: SymVal a => String -> Relation a -> SBool

-- | Check if a relation is a piece-wise linear order. The string argument
--   must uniquely identify this order.
isPiecewiseLinearOrder :: SymVal a => String -> Relation a -> SBool

-- | Create the transitive closure of a given relation. The string argument
--   must uniquely identify the newly created relation.
mkTransitiveClosure :: forall a. SymVal a => String -> Relation a -> Relation a

-- | A predicate is a symbolic program that returns a (symbolic) boolean
--   value. For all intents and purposes, it can be treated as an n-ary
--   function from symbolic-values to a boolean. The <a>Symbolic</a> monad
--   captures the underlying representation, and can/should be ignored by
--   the users of the library, unless you are building further utilities on
--   top of SBV itself. Instead, simply use the <a>Predicate</a> type when
--   necessary.
type Predicate = Symbolic SBool

-- | A constraint set is a symbolic program that returns no values. The
--   idea is that the constraints/min-max goals will serve as the
--   collection of constraints that will be used for sat/optimize calls.
type ConstraintSet = Symbolic ()

-- | <a>Provable</a> is specialization of <a>ProvableM</a> to the <a>IO</a>
--   monad. Unless you are using transformers explicitly, this is the type
--   you should prefer.
type Provable = ProvableM IO

-- | <a>Satisfiable</a> is specialization of <a>SatisfiableM</a> to the
--   <a>IO</a> monad. Unless you are using transformers explicitly, this is
--   the type you should prefer.
type Satisfiable = SatisfiableM IO

-- | Prove a predicate, using the default solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>prove</a>
prove :: Provable a => a -> IO ThmResult

-- | Prove the predicate using the given SMT-solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>proveWith</a>
proveWith :: Provable a => SMTConfig -> a -> IO ThmResult

-- | Prove a predicate with delta-satisfiability, using the default solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>prove</a>
dprove :: Provable a => a -> IO ThmResult

-- | Prove the predicate with delta-satisfiability using the given
--   SMT-solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>proveWith</a>
dproveWith :: Provable a => SMTConfig -> a -> IO ThmResult

-- | Find a satisfying assignment for a predicate, using the default
--   solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sat</a>
sat :: Satisfiable a => a -> IO SatResult

-- | Find a satisfying assignment using the given SMT-solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>satWith</a>
satWith :: Satisfiable a => SMTConfig -> a -> IO SatResult

-- | Find a delta-satisfying assignment for a predicate, using the default
--   solver for delta-satisfiability.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>dsat</a>
dsat :: Satisfiable a => a -> IO SatResult

-- | Find a satisfying assignment using the given SMT-solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>satWith</a>
dsatWith :: Satisfiable a => SMTConfig -> a -> IO SatResult

-- | Find all satisfying assignments, using the default solver. Equivalent
--   to <tt><a>allSatWith</a> <a>defaultSMTCfg</a></tt>. See
--   <a>allSatWith</a> for details.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>allSat</a>
allSat :: Satisfiable a => a -> IO AllSatResult

-- | Return all satisfying assignments for a predicate. Note that this call
--   will block until all satisfying assignments are found. If you have a
--   problem with infinitely many satisfying models (consider
--   <a>SInteger</a>) or a very large number of them, you might have to
--   wait for a long time. To avoid such cases, use the
--   <a>allSatMaxModelCount</a> parameter in the configuration.
--   
--   NB. Uninterpreted constant/function values and counter-examples for
--   array values are ignored for the purposes of <a>allSat</a>. That is,
--   only the satisfying assignments modulo uninterpreted functions and
--   array inputs will be returned. This is due to the limitation of not
--   having a robust means of getting a function counter-example back from
--   the SMT solver. Find all satisfying assignments using the given
--   SMT-solver
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>allSatWith</a>
allSatWith :: Satisfiable a => SMTConfig -> a -> IO AllSatResult

-- | Optimize a given collection of <a>Objective</a>s.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>optimize</a>
optimize :: Satisfiable a => OptimizeStyle -> a -> IO OptimizeResult

-- | Optimizes the objectives using the given SMT-solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>optimizeWith</a>
optimizeWith :: Satisfiable a => SMTConfig -> OptimizeStyle -> a -> IO OptimizeResult

-- | Check if the constraints given are consistent in a prove call using
--   the default solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>isVacuousProof</a>
isVacuousProof :: Provable a => a -> IO Bool

-- | Determine if the constraints are vacuous in a SAT call using the given
--   SMT-solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>isVacuousProofWith</a>
isVacuousProofWith :: Provable a => SMTConfig -> a -> IO Bool

-- | Checks theoremhood using the default solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>isTheorem</a>
isTheorem :: Provable a => a -> IO Bool

-- | Check whether a given property is a theorem.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>isTheoremWith</a>
isTheoremWith :: Provable a => SMTConfig -> a -> IO Bool

-- | Checks satisfiability using the default solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>isSatisfiable</a>
isSatisfiable :: Satisfiable a => a -> IO Bool

-- | Check whether a given property is satisfiable.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>isSatisfiableWith</a>
isSatisfiableWith :: Satisfiable a => SMTConfig -> a -> IO Bool

-- | Prove a property with multiple solvers, running them in separate
--   threads. Only the result of the first one to finish will be returned,
--   remaining threads will be killed. Note that we send an exception to
--   the losing processes, but we do *not* actually wait for them to
--   finish. In rare cases this can lead to zombie processes. In previous
--   experiments, we found that some processes take their time to
--   terminate. So, this solution favors quick turnaround.
proveWithAny :: Provable a => [SMTConfig] -> a -> IO (Solver, NominalDiffTime, ThmResult)

-- | Prove a property with multiple solvers, running them in separate
--   threads. The results will be returned in the order produced.
proveWithAll :: Provable a => [SMTConfig] -> a -> IO [(Solver, NominalDiffTime, ThmResult)]

-- | Prove a property by running many queries each isolated to their own
--   thread concurrently and return the first that finishes, killing the
--   others
proveConcurrentWithAny :: Provable a => SMTConfig -> [Query b] -> a -> IO (Solver, NominalDiffTime, ThmResult)

-- | Prove a property by running many queries each isolated to their own
--   thread concurrently and wait for each to finish returning all results
proveConcurrentWithAll :: Provable a => SMTConfig -> [Query b] -> a -> IO [(Solver, NominalDiffTime, ThmResult)]

-- | Find a satisfying assignment to a property with multiple solvers,
--   running them in separate threads. Only the result of the first one to
--   finish will be returned, remaining threads will be killed. Note that
--   we send an exception to the losing processes, but we do *not* actually
--   wait for them to finish. In rare cases this can lead to zombie
--   processes. In previous experiments, we found that some processes take
--   their time to terminate. So, this solution favors quick turnaround.
satWithAny :: Satisfiable a => [SMTConfig] -> a -> IO (Solver, NominalDiffTime, SatResult)

-- | Find a satisfying assignment to a property with multiple solvers,
--   running them in separate threads. The results will be returned in the
--   order produced.
satWithAll :: Satisfiable a => [SMTConfig] -> a -> IO [(Solver, NominalDiffTime, SatResult)]

-- | Find a satisfying assignment to a property using a single solver, but
--   providing several query problems of interest, with each query running
--   in a separate thread and return the first one that returns. This can
--   be useful to use symbolic mode to drive to a location in the search
--   space of the solver and then refine the problem in query mode. If the
--   computation is very hard to solve for the solver than running in
--   concurrent mode may provide a large performance benefit.
satConcurrentWithAny :: Satisfiable a => SMTConfig -> [Query b] -> a -> IO (Solver, NominalDiffTime, SatResult)

-- | Find a satisfying assignment to a property using a single solver, but
--   run each query problem in a separate isolated thread and wait for each
--   thread to finish. See <a>satConcurrentWithAny</a> for more details.
satConcurrentWithAll :: Satisfiable a => SMTConfig -> [Query b] -> a -> IO [(Solver, NominalDiffTime, SatResult)]

-- | Create an SMT-Lib2 benchmark, for a SAT query.
generateSMTBenchmarkSat :: SatisfiableM m a => a -> m String

-- | Create an SMT-Lib2 benchmark, for a Proof query.
generateSMTBenchmarkProof :: ProvableM m a => a -> m String

-- | Form the symbolic conjunction of a given list of boolean conditions.
--   Useful in expressing problems with constraints, like the following:
--   
--   <pre>
--   sat $ do [x, y, z] &lt;- sIntegers ["x", "y", "z"]
--            solve [x .&gt; 5, y + z .&lt; x]
--   </pre>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>solve</a>
solve :: [SBool] -> Symbolic SBool

-- | Add a constraint, any satisfying instance must satisfy this condition.
constrain :: (SolverContext m, QuantifiedBool a) => a -> m ()

-- | Add a soft constraint. The solver will try to satisfy this condition
--   if possible, but won't if it cannot.
softConstrain :: (SolverContext m, QuantifiedBool a) => a -> m ()

-- | A value that can be used as a quantified boolean
class QuantifiedBool a

-- | Turn a quantified boolean into a regular boolean. That is, this
--   function turns an exists/forall quantified formula to a simple boolean
--   that can be used as a regular boolean value. An example is:
--   
--   <pre>
--   quantifiedBool $ \(Forall x) (Exists y) -&gt; y .&gt; (x :: SInteger)
--   </pre>
--   
--   is equivalent to <a>sTrue</a>. You can think of this function as
--   performing quantifier-elimination: It takes a quantified formula, and
--   reduces it to a simple boolean that is equivalent to it, but has no
--   quantifiers.
quantifiedBool :: QuantifiedBool a => a -> SBool

-- | A universal symbolic variable, used in building quantified
--   constraints. The name attached via the symbol is used during
--   skolemization. It names the corresponding argument to the
--   skolem-functions within the scope of this quantifier.
newtype Forall (nm :: Symbol) a
Forall :: SBV a -> Forall (nm :: Symbol) a

-- | An existential symbolic variable, used in building quantified
--   constraints. The name attached via the symbol is used during
--   skolemization to create a skolem-function name when this variable is
--   eliminated.
newtype Exists (nm :: Symbol) a
Exists :: SBV a -> Exists (nm :: Symbol) a

-- | An existential unique symbolic variable, used in building quantified
--   constraints. The name attached via the symbol is used during
--   skolemization. It's split into two extra names, suffixed <tt>_eu1</tt>
--   and <tt>_eu2</tt>, to name the universals in the equivalent formula:
--   &lt;math&gt;
newtype ExistsUnique (nm :: Symbol) a
ExistsUnique :: SBV a -> ExistsUnique (nm :: Symbol) a

-- | Exactly <tt>n</tt> universal symbolic variables, used in in building
--   quantified constraints. The name attached will be prefixed in front of
--   <tt>_1</tt>, <tt>_2</tt>, ..., <tt>_n</tt> to form the names of the
--   variables.
newtype ForallN (n :: Nat) (nm :: Symbol) a
ForallN :: [SBV a] -> ForallN (n :: Nat) (nm :: Symbol) a

-- | Exactly <tt>n</tt> existential symbolic variables, used in building
--   quantified constraints. The name attached will be prefixed in front of
--   <tt>_1</tt>, <tt>_2</tt>, ..., <tt>_n</tt> to form the names of the
--   variables.
newtype ExistsN (n :: Nat) (nm :: Symbol) a
ExistsN :: [SBV a] -> ExistsN (n :: Nat) (nm :: Symbol) a

-- | Class of things that we can logically negate
class QNot a where {
    type NegatesTo a :: Type;
}

-- | Negation of a quantified formula. This operation essentially lifts
--   <a>sNot</a> to quantified formulae. Note that you can achieve the same
--   using <tt><a>sNot</a> . <a>quantifiedBool</a></tt>, but that will hide
--   the quantifiers, so prefer this version if you want to keep them
--   around.
qNot :: QNot a => a -> NegatesTo a

-- | A class of values that can be skolemized. Note that we don't export
--   this class. Use the <a>skolemize</a> function instead.
class Skolemize a

-- | Skolemization. For any formula, skolemization gives back an
--   equisatisfiable formula that has no existential quantifiers in it. You
--   have to provide enough names for all the existentials in the argument.
--   (Extras OK, so you can pass an infinite list if you like.) The names
--   should be distinct, and also different from any other uninterpreted
--   name you might have elsewhere.
skolemize :: (Skolemize a, Constraint Symbolic (SkolemsTo a), Skolemize a) => a -> SkolemsTo a

-- | If you use the same names for skolemized arguments in different
--   functions, they will collide; which is undesirable. Unfortunately
--   there's no easy way for SBV to detect this. In such cases, use
--   <a>taggedSkolemize</a> to add a scope to the skolem-function names
--   generated.
taggedSkolemize :: (Skolemize a, Constraint Symbolic (SkolemsTo a), Skolemize a) => String -> a -> SkolemsTo a

-- | Add a named constraint. The name is used in unsat-core extraction.
namedConstraint :: (SolverContext m, QuantifiedBool a) => String -> a -> m ()

-- | Add a constraint, with arbitrary attributes.
constrainWithAttribute :: (SolverContext m, QuantifiedBool a) => [(String, String)] -> a -> m ()

-- | <a>sTrue</a> if at most <tt>k</tt> of the input arguments are
--   <a>sTrue</a>
pbAtMost :: [SBool] -> Int -> SBool

-- | <a>sTrue</a> if at least <tt>k</tt> of the input arguments are
--   <a>sTrue</a>
pbAtLeast :: [SBool] -> Int -> SBool

-- | <a>sTrue</a> if exactly <tt>k</tt> of the input arguments are
--   <a>sTrue</a>
pbExactly :: [SBool] -> Int -> SBool

-- | <a>sTrue</a> if the sum of coefficients for <a>sTrue</a> elements is
--   at most <tt>k</tt>. Generalizes <a>pbAtMost</a>.
pbLe :: [(Int, SBool)] -> Int -> SBool

-- | <a>sTrue</a> if the sum of coefficients for <a>sTrue</a> elements is
--   at least <tt>k</tt>. Generalizes <a>pbAtLeast</a>.
pbGe :: [(Int, SBool)] -> Int -> SBool

-- | <a>sTrue</a> if the sum of coefficients for <a>sTrue</a> elements is
--   exactly least <tt>k</tt>. Useful for coding <i>exactly K-of-N</i>
--   constraints, and in particular mutex constraints.
pbEq :: [(Int, SBool)] -> Int -> SBool

-- | <a>sTrue</a> if there is at most one set bit
pbMutexed :: [SBool] -> SBool

-- | <a>sTrue</a> if there is exactly one set bit
pbStronglyMutexed :: [SBool] -> SBool

-- | Symbolic assert. Check that the given boolean condition is always
--   <a>sTrue</a> in the given path. The optional first argument can be
--   used to provide call-stack info via GHC's location facilities.
sAssert :: HasKind a => Maybe CallStack -> String -> SBool -> SBV a -> SBV a

-- | Check if a safe-call was safe or not, turning a <a>SafeResult</a> to a
--   Bool.
isSafe :: SafeResult -> Bool

-- | Symbolically executable program fragments. This class is mainly used
--   for <a>safe</a> calls, and is sufficiently populated internally to
--   cover most use cases. Users can extend it as they wish to allow
--   <a>safe</a> checks for SBV programs that return/take types that are
--   user-defined.
class ExtractIO m => SExecutable m a

-- | Create an argument for a name used in a safety-checking call.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>sName_</a>
sName :: SExecutable IO a => a -> Symbolic ()

-- | Check safety using the default solver.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>safe</a>
safe :: SExecutable IO a => a -> IO [SafeResult]

-- | Check if any of the <a>sAssert</a> calls can be violated.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>safeWith</a>
safeWith :: SExecutable IO a => SMTConfig -> a -> IO [SafeResult]

-- | Quick check an SBV property. Note that a regular <tt>quickCheck</tt>
--   call will work just as well. Use this variant if you want to receive
--   the boolean result.
sbvQuickCheck :: Symbolic SBool -> IO Bool

-- | Style of optimization. Note that in the pareto case the user is
--   allowed to specify a max number of fronts to query the solver for,
--   since there might potentially be an infinite number of them and there
--   is no way to know exactly how many ahead of time. If <a>Nothing</a> is
--   given, SBV will possibly loop forever if the number is really
--   infinite.
data OptimizeStyle

-- | Objectives are optimized in the order given, earlier objectives have
--   higher priority.
Lexicographic :: OptimizeStyle

-- | Each objective is optimized independently.
Independent :: OptimizeStyle

-- | Objectives are optimized according to pareto front: That is, no
--   objective can be made better without making some other worse.
Pareto :: Maybe Int -> OptimizeStyle

-- | Objective of optimization. We can minimize, maximize, or give a soft
--   assertion with a penalty for not satisfying it.
data Objective a

-- | Minimize this metric
Minimize :: String -> a -> Objective a

-- | Maximize this metric
Maximize :: String -> a -> Objective a

-- | A soft assertion, with an associated penalty
AssertWithPenalty :: String -> a -> Penalty -> Objective a

-- | Class of metrics we can optimize for. Currently, booleans, bounded
--   signed/unsigned bit-vectors, unbounded integers, algebraic reals and
--   floats can be optimized. You can add your instances, but bewared that
--   the <a>MetricSpace</a> should map your type to something the backend
--   solver understands, which are limited to unsigned bit-vectors, reals,
--   and unbounded integers for z3.
--   
--   A good reference on these features is given in the following paper:
--   <a>http://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/nbjorner-scss2014.pdf</a>.
--   
--   Minimal completion: None. However, if <tt>MetricSpace</tt> is not
--   identical to the type, you want to define <a>toMetricSpace</a> and
--   possibly <a>minimize</a>/<a>maximize</a> to add extra constraints as
--   necessary.
class Metric a where {
    
    -- | The metric space we optimize the goal over. Usually the same as the
    --   type itself, but not always! For instance, signed bit-vectors are
    --   optimized over their unsigned counterparts, floats are optimized over
    --   their <a>Word32</a> comparable counterparts, etc.
    type MetricSpace a :: Type;
    type MetricSpace a = a;
}

-- | Compute the metric value to optimize.
toMetricSpace :: Metric a => SBV a -> SBV (MetricSpace a)

-- | Compute the value itself from the metric corresponding to it.
fromMetricSpace :: Metric a => SBV (MetricSpace a) -> SBV a

-- | Minimizing a metric space
msMinimize :: (Metric a, MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()

-- | Maximizing a metric space
msMaximize :: (Metric a, MonadSymbolic m, SolverContext m) => String -> SBV a -> m ()

-- | Compute the metric value to optimize.
toMetricSpace :: (Metric a, a ~ MetricSpace a) => SBV a -> SBV (MetricSpace a)

-- | Compute the value itself from the metric corresponding to it.
fromMetricSpace :: (Metric a, a ~ MetricSpace a) => SBV (MetricSpace a) -> SBV a

-- | Minimize a named metric
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>minimize</a>
minimize :: Metric a => String -> SBV a -> Symbolic ()

-- | Maximize a named metric
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>maximize</a>
maximize :: Metric a => String -> SBV a -> Symbolic ()

-- | Introduce a soft assertion, with an optional penalty
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>assertWithPenalty</a>
assertWithPenalty :: String -> SBool -> Penalty -> Symbolic ()

-- | Penalty for a soft-assertion. The default penalty is <tt>1</tt>, with
--   all soft-assertions belonging to the same objective goal. A positive
--   weight and an optional group can be provided by using the
--   <a>Penalty</a> constructor.
data Penalty

-- | Default: Penalty of <tt>1</tt> and no group attached
DefaultPenalty :: Penalty

-- | Penalty with a weight and an optional group
Penalty :: Rational -> Maybe String -> Penalty

-- | A simple expression type over extended values, covering infinity,
--   epsilon and intervals.
data ExtCV
Infinite :: Kind -> ExtCV
Epsilon :: Kind -> ExtCV
Interval :: ExtCV -> ExtCV -> ExtCV
BoundedCV :: CV -> ExtCV
AddExtCV :: ExtCV -> ExtCV -> ExtCV
MulExtCV :: ExtCV -> ExtCV -> ExtCV

-- | A generalized CV allows for expressions involving infinite and epsilon
--   values/intervals Used in optimization problems.
data GeneralizedCV
ExtendedCV :: ExtCV -> GeneralizedCV
RegularCV :: CV -> GeneralizedCV

-- | A <a>prove</a> call results in a <a>ThmResult</a>
newtype ThmResult
ThmResult :: SMTResult -> ThmResult

-- | A <a>sat</a> call results in a <a>SatResult</a> The reason for having
--   a separate <a>SatResult</a> is to have a more meaningful <a>Show</a>
--   instance.
newtype SatResult
SatResult :: SMTResult -> SatResult

-- | An <a>allSat</a> call results in a <a>AllSatResult</a>
data AllSatResult
AllSatResult :: Bool -> Bool -> Bool -> [SMTResult] -> AllSatResult

-- | Did we reach the user given model count limit?
[allSatMaxModelCountReached] :: AllSatResult -> Bool

-- | Did the solver report unknown at the end?
[allSatSolverReturnedUnknown] :: AllSatResult -> Bool

-- | Did the solver report delta-satisfiable at the end?
[allSatSolverReturnedDSat] :: AllSatResult -> Bool

-- | All satisfying models
[allSatResults] :: AllSatResult -> [SMTResult]

-- | A <a>safe</a> call results in a <a>SafeResult</a>
newtype SafeResult
SafeResult :: (Maybe String, String, SMTResult) -> SafeResult

-- | An <a>optimize</a> call results in a <a>OptimizeResult</a>. In the
--   <a>ParetoResult</a> case, the boolean is <a>True</a> if we reached
--   pareto-query limit and so there might be more unqueried results
--   remaining. If <a>False</a>, it means that we have all the pareto
--   fronts returned. See the <a>Pareto</a> <a>OptimizeStyle</a> for
--   details.
data OptimizeResult
LexicographicResult :: SMTResult -> OptimizeResult
ParetoResult :: (Bool, [SMTResult]) -> OptimizeResult
IndependentResult :: [(String, SMTResult)] -> OptimizeResult

-- | The result of an SMT solver call. Each constructor is tagged with the
--   <a>SMTConfig</a> that created it so that further tools can inspect it
--   and build layers of results, if needed. For ordinary uses of the
--   library, this type should not be needed, instead use the accessor
--   functions on it. (Custom Show instances and model extractors.)
data SMTResult

-- | Unsatisfiable. If unsat-cores are enabled, they will be returned in
--   the second parameter.
Unsatisfiable :: SMTConfig -> Maybe [String] -> SMTResult

-- | Satisfiable with model
Satisfiable :: SMTConfig -> SMTModel -> SMTResult

-- | Delta satisfiable with queried string if available and model
DeltaSat :: SMTConfig -> Maybe String -> SMTModel -> SMTResult

-- | Prover returned a model, but in an extension field containing
--   Infinite/epsilon
SatExtField :: SMTConfig -> SMTModel -> SMTResult

-- | Prover returned unknown, with the given reason
Unknown :: SMTConfig -> SMTReasonUnknown -> SMTResult

-- | Prover errored out, with possibly a bogus result
ProofError :: SMTConfig -> [String] -> Maybe SMTResult -> SMTResult

-- | Reason for reporting unknown.
data SMTReasonUnknown
UnknownMemOut :: SMTReasonUnknown
UnknownIncomplete :: SMTReasonUnknown
UnknownTimeOut :: SMTReasonUnknown
UnknownOther :: String -> SMTReasonUnknown

-- | Observe the value of an expression, unconditionally. See
--   <a>observeIf</a> for a generalized version.
observe :: SymVal a => String -> SBV a -> SBV a

-- | Observe the value of an expression, if the given condition holds. Such
--   values are useful in model construction, as they are printed part of a
--   satisfying model, or a counter-example. The same works for quick-check
--   as well. Useful when we want to see intermediate values, or
--   expected/obtained pairs in a particular run. Note that an observed
--   expression is always symbolic, i.e., it won't be constant folded.
--   Compare this to <a>label</a> which is used for putting a label in the
--   generated SMTLib-C code.
observeIf :: SymVal a => (a -> Bool) -> String -> SBV a -> SBV a

-- | A variant of observe that you can use at the top-level. This is useful
--   with quick-check, for instance.
sObserve :: SymVal a => String -> SBV a -> Symbolic ()

-- | Instances of <a>SatModel</a> can be automatically extracted from
--   models returned by the solvers. The idea is that the sbv
--   infrastructure provides a stream of CV's (constant values) coming from
--   the solver, and the type <tt>a</tt> is interpreted based on these
--   constants. Many typical instances are already provided, so new
--   instances can be declared with relative ease.
--   
--   Minimum complete definition: <a>parseCVs</a>
class SatModel a

-- | Given a sequence of constant-words, extract one instance of the type
--   <tt>a</tt>, returning the remaining elements untouched. If the next
--   element is not what's expected for this type you should return
--   <a>Nothing</a>
parseCVs :: SatModel a => [CV] -> Maybe (a, [CV])

-- | Given a parsed model instance, transform it using <tt>f</tt>, and
--   return the result. The default definition for this method should be
--   sufficient in most use cases.
cvtModel :: SatModel a => (a -> Maybe b) -> Maybe (a, [CV]) -> Maybe (b, [CV])

-- | Given a sequence of constant-words, extract one instance of the type
--   <tt>a</tt>, returning the remaining elements untouched. If the next
--   element is not what's expected for this type you should return
--   <a>Nothing</a>
parseCVs :: (SatModel a, Read a) => [CV] -> Maybe (a, [CV])

-- | Various SMT results that we can extract models out of.
class Modelable a

-- | Is there a model?
modelExists :: Modelable a => a -> Bool

-- | Extract assignments of a model, the result is a tuple where the first
--   argument (if True) indicates whether the model was "probable". (i.e.,
--   if the solver returned unknown.)
getModelAssignment :: (Modelable a, SatModel b) => a -> Either String (Bool, b)

-- | Extract a model dictionary. Extract a dictionary mapping the variables
--   to their respective values as returned by the SMT solver. Also see
--   <a>getModelDictionaries</a>.
getModelDictionary :: Modelable a => a -> Map String CV

-- | Extract a model value for a given element. Also see
--   <a>getModelValues</a>.
getModelValue :: (Modelable a, SymVal b) => String -> a -> Maybe b

-- | Extract a representative name for the model value of an uninterpreted
--   kind. This is supposed to correspond to the value as computed
--   internally by the SMT solver; and is unportable from solver to solver.
--   Also see <a>getModelUninterpretedValues</a>.
getModelUninterpretedValue :: Modelable a => String -> a -> Maybe String

-- | A simpler variant of <a>getModelAssignment</a> to get a model out
--   without the fuss.
extractModel :: (Modelable a, SatModel b) => a -> Maybe b

-- | Extract model objective values, for all optimization goals.
getModelObjectives :: Modelable a => a -> Map String GeneralizedCV

-- | Extract the value of an objective
getModelObjectiveValue :: Modelable a => String -> a -> Maybe GeneralizedCV

-- | Extract model uninterpreted-functions
getModelUIFuns :: Modelable a => a -> Map String (SBVType, Either String ([([CV], CV)], CV))

-- | Extract the value of an uninterpreted-function as an association list
getModelUIFunValue :: Modelable a => String -> a -> Maybe (SBVType, Either String ([([CV], CV)], CV))

-- | Given an <a>allSat</a> call, we typically want to iterate over it and
--   print the results in sequence. The <a>displayModels</a> function
--   automates this task by calling <tt>disp</tt> on each result,
--   consecutively. The first <a>Int</a> argument to <tt>disp</tt> 'is the
--   current model number. The second argument is a tuple, where the first
--   element indicates whether the model is alleged (i.e., if the solver is
--   not sure, returning Unknown). The arrange argument can sort the
--   results in any way you like, if necessary.
displayModels :: SatModel a => ([(Bool, a)] -> [(Bool, a)]) -> (Int -> (Bool, a) -> IO ()) -> AllSatResult -> IO Int

-- | Return all the models from an <a>allSat</a> call, similar to
--   <a>extractModel</a> but is suitable for the case of multiple results.
extractModels :: SatModel a => AllSatResult -> [a]

-- | Get dictionaries from an all-sat call. Similar to
--   <a>getModelDictionary</a>.
getModelDictionaries :: AllSatResult -> [Map String CV]

-- | Extract value of a variable from an all-sat call. Similar to
--   <a>getModelValue</a>.
getModelValues :: SymVal b => String -> AllSatResult -> [Maybe b]

-- | Extract value of an uninterpreted variable from an all-sat call.
--   Similar to <a>getModelUninterpretedValue</a>.
getModelUninterpretedValues :: String -> AllSatResult -> [Maybe String]

-- | Solver configuration. See also <a>z3</a>, <a>yices</a>, <a>cvc4</a>,
--   <a>boolector</a>, <a>mathSAT</a>, etc. which are instantiations of
--   this type for those solvers, with reasonable defaults. In particular,
--   custom configuration can be created by varying those values. (Such as
--   <tt>z3{verbose=True}</tt>.)
--   
--   Most fields are self explanatory. The notion of precision for printing
--   algebraic reals stems from the fact that such values does not
--   necessarily have finite decimal representations, and hence we have to
--   stop printing at some depth. It is important to emphasize that such
--   values always have infinite precision internally. The issue is merely
--   with how we print such an infinite precision value on the screen. The
--   field <a>printRealPrec</a> controls the printing precision, by
--   specifying the number of digits after the decimal point. The default
--   value is 16, but it can be set to any positive integer.
--   
--   When printing, SBV will add the suffix <tt>...</tt> at the end of a
--   real-value, if the given bound is not sufficient to represent the
--   real-value exactly. Otherwise, the number will be written out in
--   standard decimal notation. Note that SBV will always print the whole
--   value if it is precise (i.e., if it fits in a finite number of
--   digits), regardless of the precision limit. The limit only applies if
--   the representation of the real value is not finite, i.e., if it is not
--   rational.
--   
--   The <a>printBase</a> field can be used to print numbers in base 2, 10,
--   or 16.
--   
--   The <a>crackNum</a> field can be used to display numbers in detail,
--   all its bits and how they are laid out in memory. Works with all
--   bounded number types (i.e., SWord and SInt), but also with floats. It
--   is particularly useful with floating-point numbers, as it shows you
--   how they are laid out in memory following the IEEE754 rules.
data SMTConfig
SMTConfig :: Bool -> Timing -> Int -> Int -> Bool -> String -> Maybe Int -> Bool -> Bool -> (String -> Bool) -> Bool -> Bool -> Maybe FilePath -> SMTLibVersion -> Maybe Double -> SMTSolver -> [String] -> RoundingMode -> [SMTOption] -> Bool -> Maybe FilePath -> SMTConfig

-- | Debug mode
[verbose] :: SMTConfig -> Bool

-- | Print timing information on how long different phases took
--   (construction, solving, etc.)
[timing] :: SMTConfig -> Timing

-- | Print integral literals in this base (2, 10, and 16 are supported.)
[printBase] :: SMTConfig -> Int

-- | Print algebraic real values with this precision. (SReal, default: 16)
[printRealPrec] :: SMTConfig -> Int

-- | For each numeric value, show it in detail in the model with its bits
--   spliced out. Good for floats.
[crackNum] :: SMTConfig -> Bool

-- | Usually "(check-sat)". However, users might tweak it based on solver
--   characteristics.
[satCmd] :: SMTConfig -> String

-- | In a <a>allSat</a> call, return at most this many models. If nothing,
--   return all.
[allSatMaxModelCount] :: SMTConfig -> Maybe Int

-- | In a <a>allSat</a> call, print models as they are found.
[allSatPrintAlong] :: SMTConfig -> Bool

-- | In a <a>allSat</a> call, should we try to extract values of
--   uninterpreted functions?
[allSatTrackUFs] :: SMTConfig -> Bool

-- | When constructing a model, ignore variables whose name satisfy this
--   predicate. (Default: (const False), i.e., don't ignore anything)
[isNonModelVar] :: SMTConfig -> String -> Bool

-- | If set, SBV will attempt to validate the model it gets back from the
--   solver.
[validateModel] :: SMTConfig -> Bool

-- | Validate optimization results. NB: Does NOT make sure the model is
--   optimal, just checks they satisfy the constraints.
[optimizeValidateConstraints] :: SMTConfig -> Bool

-- | If Just, the entire interaction will be recorded as a playable file
--   (for debugging purposes mostly)
[transcript] :: SMTConfig -> Maybe FilePath

-- | What version of SMT-lib we use for the tool
[smtLibVersion] :: SMTConfig -> SMTLibVersion

-- | Delta-sat precision
[dsatPrecision] :: SMTConfig -> Maybe Double

-- | The actual SMT solver.
[solver] :: SMTConfig -> SMTSolver

-- | Extra command line arguments to pass to the solver.
[extraArgs] :: SMTConfig -> [String]

-- | Rounding mode to use for floating-point conversions
[roundingMode] :: SMTConfig -> RoundingMode

-- | Options to set as we start the solver
[solverSetOptions] :: SMTConfig -> [SMTOption]

-- | If true, we shall ignore the exit code upon exit. Otherwise we require
--   ExitSuccess.
[ignoreExitCode] :: SMTConfig -> Bool

-- | Redirect the verbose output to this file if given. If Nothing, stdout
--   is implied.
[redirectVerbose] :: SMTConfig -> Maybe FilePath

-- | Specify how to save timing information, if at all.
data Timing
NoTiming :: Timing
PrintTiming :: Timing
SaveTiming :: IORef NominalDiffTime -> Timing

-- | Representation of SMTLib Program versions. As of June 2015, we're
--   dropping support for SMTLib1, and supporting SMTLib2 only. We keep
--   this data-type around in case SMTLib3 comes along and we want to
--   support 2 and 3 simultaneously.
data SMTLibVersion
SMTLib2 :: SMTLibVersion

-- | Solvers that SBV is aware of
data Solver
ABC :: Solver
Boolector :: Solver
Bitwuzla :: Solver
CVC4 :: Solver
CVC5 :: Solver
DReal :: Solver
MathSAT :: Solver
Yices :: Solver
Z3 :: Solver

-- | An SMT solver
data SMTSolver
SMTSolver :: Solver -> String -> (String -> String) -> (SMTConfig -> [String]) -> SMTEngine -> SolverCapabilities -> SMTSolver

-- | The solver in use
[name] :: SMTSolver -> Solver

-- | The path to its executable
[executable] :: SMTSolver -> String

-- | Each line sent to the solver will be passed through this function
--   (typically id)
[preprocess] :: SMTSolver -> String -> String

-- | Options to provide to the solver
[options] :: SMTSolver -> SMTConfig -> [String]

-- | The solver engine, responsible for interpreting solver output
[engine] :: SMTSolver -> SMTEngine

-- | Various capabilities of the solver
[capabilities] :: SMTSolver -> SolverCapabilities

-- | Default configuration for the Boolector SMT solver
boolector :: SMTConfig

-- | Default configuration for the Bitwuzla SMT solver
bitwuzla :: SMTConfig

-- | Default configuration for the CVC4 SMT Solver.
cvc4 :: SMTConfig

-- | Default configuration for the CVC5 SMT Solver.
cvc5 :: SMTConfig

-- | Default configuration for the Yices SMT Solver.
yices :: SMTConfig

-- | Default configuration for the Yices SMT Solver.
dReal :: SMTConfig

-- | Default configuration for the Z3 SMT solver
z3 :: SMTConfig

-- | Default configuration for the MathSAT SMT solver
mathSAT :: SMTConfig

-- | Default configuration for the ABC synthesis and verification tool.
abc :: SMTConfig

-- | The default configs corresponding to supported SMT solvers
defaultSolverConfig :: Solver -> SMTConfig

-- | The default solver used by SBV. This is currently set to z3.
defaultSMTCfg :: SMTConfig

-- | The default solver used by SBV for delta-satisfiability problems. This
--   is currently set to dReal, which is also the only solver that supports
--   delta-satisfiability.
defaultDeltaSMTCfg :: SMTConfig

-- | Check whether the given solver is installed and is ready to go. This
--   call does a simple call to the solver to ensure all is well.
sbvCheckSolverInstallation :: SMTConfig -> IO Bool

-- | Return the known available solver configs, installed on your machine.
getAvailableSolvers :: IO [SMTConfig]

-- | Set the logic.
setLogic :: SolverContext m => Logic -> m ()

-- | SMT-Lib logics. If left unspecified SBV will pick the logic based on
--   what it determines is needed. However, the user can override this
--   choice using a call to <a>setLogic</a> This is especially handy if one
--   is experimenting with custom logics that might be supported on new
--   solvers. See <a>http://smtlib.cs.uiowa.edu/logics.shtml</a> for the
--   official list.
data Logic

-- | Formulas over the theory of linear integer arithmetic and arrays
--   extended with free sort and function symbols but restricted to arrays
--   with integer indices and values.
AUFLIA :: Logic

-- | Linear formulas with free sort and function symbols over one- and
--   two-dimentional arrays of integer index and real value.
AUFLIRA :: Logic

-- | Formulas with free function and predicate symbols over a theory of
--   arrays of arrays of integer index and real value.
AUFNIRA :: Logic

-- | Linear formulas in linear real arithmetic.
LRA :: Logic

-- | Quantifier-free formulas over the theory of bitvectors and bitvector
--   arrays.
QF_ABV :: Logic

-- | Quantifier-free formulas over the theory of bitvectors and bitvector
--   arrays extended with free sort and function symbols.
QF_AUFBV :: Logic

-- | Quantifier-free linear formulas over the theory of integer arrays
--   extended with free sort and function symbols.
QF_AUFLIA :: Logic

-- | Quantifier-free formulas over the theory of arrays with
--   extensionality.
QF_AX :: Logic

-- | Quantifier-free formulas over the theory of fixed-size bitvectors.
QF_BV :: Logic

-- | Difference Logic over the integers. Boolean combinations of
--   inequations of the form x - y &lt; b where x and y are integer
--   variables and b is an integer constant.
QF_IDL :: Logic

-- | Unquantified linear integer arithmetic. In essence, Boolean
--   combinations of inequations between linear polynomials over integer
--   variables.
QF_LIA :: Logic

-- | Unquantified linear real arithmetic. In essence, Boolean combinations
--   of inequations between linear polynomials over real variables.
QF_LRA :: Logic

-- | Quantifier-free integer arithmetic.
QF_NIA :: Logic

-- | Quantifier-free real arithmetic.
QF_NRA :: Logic

-- | Difference Logic over the reals. In essence, Boolean combinations of
--   inequations of the form x - y &lt; b where x and y are real variables
--   and b is a rational constant.
QF_RDL :: Logic

-- | Unquantified formulas built over a signature of uninterpreted (i.e.,
--   free) sort and function symbols.
QF_UF :: Logic

-- | Unquantified formulas over bitvectors with uninterpreted sort function
--   and symbols.
QF_UFBV :: Logic

-- | Difference Logic over the integers (in essence) but with uninterpreted
--   sort and function symbols.
QF_UFIDL :: Logic

-- | Unquantified linear integer arithmetic with uninterpreted sort and
--   function symbols.
QF_UFLIA :: Logic

-- | Unquantified linear real arithmetic with uninterpreted sort and
--   function symbols.
QF_UFLRA :: Logic

-- | Unquantified non-linear real arithmetic with uninterpreted sort and
--   function symbols.
QF_UFNRA :: Logic

-- | Unquantified non-linear real integer arithmetic with uninterpreted
--   sort and function symbols.
QF_UFNIRA :: Logic

-- | Linear real arithmetic with uninterpreted sort and function symbols.
UFLRA :: Logic

-- | Non-linear integer arithmetic with uninterpreted sort and function
--   symbols.
UFNIA :: Logic

-- | Quantifier-free formulas over the theory of floating point numbers,
--   arrays, and bit-vectors.
QF_FPBV :: Logic

-- | Quantifier-free formulas over the theory of floating point numbers.
QF_FP :: Logic

-- | Quantifier-free finite domains.
QF_FD :: Logic

-- | Quantifier-free formulas over the theory of strings.
QF_S :: Logic

-- | The catch-all value.
Logic_ALL :: Logic

-- | Use this value when you want SBV to simply not set the logic.
Logic_NONE :: Logic

-- | In case you need a really custom string!
CustomLogic :: String -> Logic

-- | Set an option.
setOption :: SolverContext m => SMTOption -> m ()

-- | Set info. Example: <tt>setInfo ":status" ["unsat"]</tt>.
setInfo :: SolverContext m => String -> [String] -> m ()

-- | Set a solver time-out value, in milli-seconds. This function
--   essentially translates to the SMTLib call <tt>(set-info :timeout
--   val)</tt>, and your backend solver may or may not support it! The
--   amount given is in milliseconds. Also see the function <a>timeOut</a>
--   for finer level control of time-outs, directly from SBV.
setTimeOut :: SolverContext m => Integer -> m ()

-- | An exception thrown from SBV. If the solver ever responds with a
--   non-success value for a command, SBV will throw an
--   <a>SBVException</a>, it so the user can process it as required. The
--   provided <a>Show</a> instance will render the failure nicely. Note
--   that if you ever catch this exception, the solver is no longer alive:
--   You should either -- throw the exception up, or do other proper
--   clean-up before continuing.
data SBVException
SBVException :: String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe String -> Maybe ExitCode -> SMTConfig -> Maybe [String] -> Maybe [String] -> SBVException
[sbvExceptionDescription] :: SBVException -> String
[sbvExceptionSent] :: SBVException -> Maybe String
[sbvExceptionExpected] :: SBVException -> Maybe String
[sbvExceptionReceived] :: SBVException -> Maybe String
[sbvExceptionStdOut] :: SBVException -> Maybe String
[sbvExceptionStdErr] :: SBVException -> Maybe String
[sbvExceptionExitCode] :: SBVException -> Maybe ExitCode
[sbvExceptionConfig] :: SBVException -> SMTConfig
[sbvExceptionReason] :: SBVException -> Maybe [String]
[sbvExceptionHint] :: SBVException -> Maybe [String]

-- | The <a>Symbolic</a> value. The parameter <tt>a</tt> is phantom, but is
--   extremely important in keeping the user interface strongly typed.
data SBV a

-- | A class for capturing values that have a sign and a size (finite or
--   infinite) minimal complete definition: kindOf, unless you can take
--   advantage of the default signature: This class can be automatically
--   derived for data-types that have a <a>Data</a> instance; this is
--   useful for creating uninterpreted sorts. So, in reality, end users
--   should almost never need to define any methods.
class HasKind a
kindOf :: HasKind a => a -> Kind
hasSign :: HasKind a => a -> Bool
intSizeOf :: HasKind a => a -> Int
isBoolean :: HasKind a => a -> Bool
isBounded :: HasKind a => a -> Bool
isReal :: HasKind a => a -> Bool
isFloat :: HasKind a => a -> Bool
isDouble :: HasKind a => a -> Bool
isRational :: HasKind a => a -> Bool
isFP :: HasKind a => a -> Bool
isUnbounded :: HasKind a => a -> Bool
isUserSort :: HasKind a => a -> Bool
isChar :: HasKind a => a -> Bool
isString :: HasKind a => a -> Bool
isList :: HasKind a => a -> Bool
isSet :: HasKind a => a -> Bool
isTuple :: HasKind a => a -> Bool
isMaybe :: HasKind a => a -> Bool
isEither :: HasKind a => a -> Bool
showType :: HasKind a => a -> String
kindOf :: (HasKind a, Read a, Data a) => a -> Kind

-- | Kind of symbolic value
data Kind
KBool :: Kind
KBounded :: !Bool -> !Int -> Kind
KUnbounded :: Kind
KReal :: Kind
KUserSort :: String -> Maybe [String] -> Kind
KFloat :: Kind
KDouble :: Kind
KFP :: !Int -> !Int -> Kind
KChar :: Kind
KString :: Kind
KList :: Kind -> Kind
KSet :: Kind -> Kind
KTuple :: [Kind] -> Kind
KMaybe :: Kind -> Kind
KRational :: Kind
KEither :: Kind -> Kind -> Kind

-- | A <a>SymVal</a> is a potential symbolic value that can be created
--   instances of to be fed to a symbolic program.
class (HasKind a, Typeable a) => SymVal a

-- | Create a free variable, universal in a proof, existential in sat
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>free</a>
free :: SymVal a => String -> Symbolic (SBV a)

-- | Create an unnamed free variable, universal in proof, existential in
--   sat
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>free_</a>
free_ :: SymVal a => Symbolic (SBV a)

-- | Create a bunch of free vars
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>mkFreeVars</a>
mkFreeVars :: SymVal a => Int -> Symbolic [SBV a]

-- | Similar to free; Just a more convenient name
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>symbolic</a>
symbolic :: SymVal a => String -> Symbolic (SBV a)

-- | Similar to mkFreeVars; but automatically gives names based on the
--   strings
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>symbolics</a>
symbolics :: SymVal a => [String] -> Symbolic [SBV a]

-- | Turn a literal constant to symbolic
literal :: SymVal a => a -> SBV a

-- | Extract a literal, if the value is concrete
unliteral :: SymVal a => SBV a -> Maybe a

-- | Extract a literal, from a CV representation
fromCV :: SymVal a => CV -> a

-- | Is the symbolic word concrete?
isConcrete :: SymVal a => SBV a -> Bool

-- | Is the symbolic word really symbolic?
isSymbolic :: SymVal a => SBV a -> Bool

-- | Does it concretely satisfy the given predicate?
isConcretely :: SymVal a => SBV a -> (a -> Bool) -> Bool

-- | One stop allocator
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>mkSymVal</a>
mkSymVal :: SymVal a => VarContext -> Maybe String -> Symbolic (SBV a)

-- | A Symbolic computation. Represented by a reader monad carrying the
--   state of the computation, layered on top of IO for creating unique
--   references to hold onto intermediate results.
--   
--   Computations which support symbolic operations
class MonadIO m => MonadSymbolic m
symbolicEnv :: MonadSymbolic m => m State
symbolicEnv :: (MonadSymbolic m, MonadTrans t, MonadSymbolic m', m ~ t m') => m State

-- | <a>Symbolic</a> is specialization of <a>SymbolicT</a> to the <a>IO</a>
--   monad. Unless you are using transformers explicitly, this is the type
--   you should prefer.
type Symbolic = SymbolicT IO

-- | A generalization of <a>Symbolic</a>.
data SymbolicT m a

-- | label: Label the result of an expression. This is essentially a no-op,
--   but useful as it generates a comment in the generated C/SMT-Lib code.
--   Note that if the argument is a constant, then the label is dropped
--   completely, per the usual constant folding strategy. Compare this to
--   <a>observe</a> which is good for printing counter-examples.
label :: SymVal a => String -> SBV a -> SBV a

-- | Mark an interim result as an output. Useful when constructing Symbolic
--   programs that return multiple values, or when the result is
--   programmatically computed.
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>output</a>
output :: Outputtable a => a -> Symbolic a

-- | Run an arbitrary symbolic computation, equivalent to
--   <tt><a>runSMTWith</a> <a>defaultSMTCfg</a></tt>
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>runSMT</a>
runSMT :: Symbolic a -> IO a

-- | Runs an arbitrary symbolic computation, exposed to the user in SAT
--   mode
--   
--   NB. For a version which generalizes over the underlying monad, see
--   <a>runSMTWith</a>
runSMTWith :: SMTConfig -> Symbolic a -> IO a
instance Data.SBV.ByteConverter (Data.SBV.Core.Sized.SWord 8)
instance Data.SBV.ByteConverter (Data.SBV.Core.Sized.SWord 16)
instance Data.SBV.ByteConverter (Data.SBV.Core.Sized.SWord 32)
instance Data.SBV.ByteConverter (Data.SBV.Core.Sized.SWord 64)
instance Data.SBV.ByteConverter (Data.SBV.Core.Sized.SWord 128)
instance Data.SBV.ByteConverter (Data.SBV.Core.Sized.SWord 256)
instance Data.SBV.ByteConverter (Data.SBV.Core.Sized.SWord 512)
instance Data.SBV.ByteConverter (Data.SBV.Core.Sized.SWord 1024)


-- | A toy imperative language with a proof system based on Dijkstra's
--   weakest preconditions methodology to establish partial/total
--   correctness proofs.
--   
--   See <tt>Documentation.SBV.Examples.WeakestPreconditions</tt> directory
--   for several example proofs.
module Data.SBV.Tools.WeakestPreconditions

-- | A program over a state is simply a statement, together with a
--   pre-condition capturing environmental assumptions and a post-condition
--   that states its correctness. In the usual Hoare-triple notation, it
--   captures:
--   
--   <pre>
--   {precondition} program {postcondition}
--   </pre>
--   
--   We also allow for a stability check, which is ensured at every
--   assignment statement to deal with ghost variables. In general, this is
--   useful for making sure what you consider as "primary inputs" remain
--   unaffected. Of course, you can also put any arbitrary condition you
--   want to check that you want performed for each <a>Assign</a>
--   statement.
--   
--   Note that stability is quite a strong condition: It is intended to
--   capture constants that never change during execution. So, if you have
--   a program that changes an input temporarily but always restores it at
--   the end, it would still fail the stability condition.
--   
--   The <a>setup</a> field is reserved for any symbolic code you might
--   want to run before the proof takes place, typically for calls to
--   <a>setOption</a>. If not needed, simply pass <tt>return ()</tt>. For
--   an interesting use case where we use setup to axiomatize the spec, see
--   <a>Documentation.SBV.Examples.WeakestPreconditions.Fib</a> and
--   <a>Documentation.SBV.Examples.WeakestPreconditions.GCD</a>.
data Program st
Program :: Symbolic () -> (st -> SBool) -> Stmt st -> (st -> SBool) -> Stable st -> Program st

-- | Any set-up required
[setup] :: Program st -> Symbolic ()

-- | Environmental assumptions
[precondition] :: Program st -> st -> SBool

-- | Program
[program] :: Program st -> Stmt st

-- | Correctness statement
[postcondition] :: Program st -> st -> SBool

-- | Each assignment must satisfy stability
[stability] :: Program st -> Stable st

-- | A statement in our imperative program, parameterized over the state.
data Stmt st

-- | Skip, do nothing.
Skip :: Stmt st

-- | Abort execution. The name is for diagnostic purposes.
Abort :: String -> Stmt st

-- | Assignment: Transform the state by a function.
Assign :: (st -> st) -> Stmt st

-- | Conditional: <tt>If condition thenBranch elseBranch</tt>.
If :: (st -> SBool) -> Stmt st -> Stmt st -> Stmt st

-- | A while loop: <tt>While name invariant measure condition body</tt>.
--   The string <tt>name</tt> is merely for diagnostic purposes. If the
--   measure is <a>Nothing</a>, then only partial correctness of this loop
--   will be proven.
While :: String -> Invariant st -> Maybe (Measure st) -> (st -> SBool) -> Stmt st -> Stmt st

-- | A sequence of statements.
Seq :: [Stmt st] -> Stmt st

-- | An <a>assert</a> is a quick way of ensuring some condition holds. If
--   it does, then it's equivalent to <a>Skip</a>. Otherwise, it is
--   equivalent to <a>Abort</a>.
assert :: String -> (st -> SBool) -> Stmt st

-- | Stability: A call of the form <tt>stable "f" f</tt> means the value of
--   the field <tt>f</tt> does not change during any assignment. The string
--   argument is for diagnostic purposes only. Note that we use
--   strong-equality here, so if the program is manipulating floats, we
--   don't get a false-positive on <tt>NaN</tt> and also not miss
--   <tt>+0</tt> and <tt>-</tt>@ changes.
stable :: EqSymbolic a => String -> (st -> a) -> st -> st -> (String, SBool)

-- | An invariant takes a state and evaluates to a boolean.
type Invariant st = st -> SBool

-- | A measure takes the state and returns a sequence of integers. The
--   ordering will be done lexicographically over the elements.
type Measure st = st -> [SInteger]

-- | A stability condition captures a primary input that does not change.
--   Use <a>stable</a> to create elements of this type.
type Stable st = [st -> st -> (String, SBool)]

-- | A verification condition. Upon failure, each <a>VC</a> carries enough
--   state and diagnostic information to indicate what particular proof
--   obligation failed for further debugging.
data VC st m

-- | The precondition doesn't hold. This can only happen in
--   <a>traceExecution</a>.
BadPrecondition :: st -> VC st m

-- | The postcondition doesn't hold
BadPostcondition :: st -> st -> VC st m

-- | Stability condition is violated
Unstable :: String -> st -> st -> VC st m

-- | The named abort condition is reachable
AbortReachable :: String -> st -> st -> VC st m

-- | Invariant doesn't hold upon entry to the named loop
InvariantPre :: String -> st -> VC st m

-- | Invariant isn't maintained by the body
InvariantMaintain :: String -> st -> st -> VC st m

-- | Measure cannot be shown to be non-negative
MeasureBound :: String -> (st, [m]) -> VC st m

-- | Measure cannot be shown to decrease through each iteration
MeasureDecrease :: String -> (st, [m]) -> (st, [m]) -> VC st m

-- | The result of a weakest-precondition proof.
data ProofResult res

-- | The property holds. If <a>Bool</a> is <a>True</a>, then total
--   correctness, otherwise partial.
Proven :: Bool -> ProofResult res

-- | Failed to establish correctness. Happens when the proof obligations
--   lead to the SMT solver to return <tt>Unk</tt>. This can happen, for
--   instance, if you have non-linear constraints, causing the solver to
--   give up.
Indeterminate :: String -> ProofResult res

-- | The property fails, failing to establish the conditions listed.
Failed :: [VC res Integer] -> ProofResult res

-- | Configuration for WP proofs.
data WPConfig
WPConfig :: SMTConfig -> Bool -> WPConfig

-- | SMT Solver to use
[wpSolver] :: WPConfig -> SMTConfig

-- | Should we be chatty?
[wpVerbose] :: WPConfig -> Bool

-- | Default WP configuration: Uses the default solver, and is not verbose.
defaultWPCfg :: WPConfig

-- | Check correctness using the default solver. Equivalent to
--   <tt><a>wpProveWith</a> <a>defaultWPCfg</a></tt>.
wpProve :: (Show res, Mergeable st, Queriable IO st, res ~ QueryResult st) => Program st -> IO (ProofResult res)

-- | Checking WP based correctness
wpProveWith :: forall st res. (Show res, Mergeable st, Queriable IO st, res ~ QueryResult st) => WPConfig -> Program st -> IO (ProofResult res)

-- | Trace the execution of a program, starting from a sufficiently
--   concrete state. (Sufficiently here means that all parts of the state
--   that is used uninitialized must have concrete values, i.e.,
--   essentially the inputs. You can leave the "temporary" variables
--   initialized by the program before use undefined or even symbolic.) The
--   return value will have a <a>Good</a> state to indicate the program
--   ended successfully, if that is the case. The result will be
--   <a>Stuck</a> if the program aborts without completing: This can happen
--   either by executing an <a>Abort</a> statement, or some invariant gets
--   violated, or if a metric fails to go down through a loop body.
traceExecution :: forall st. Show st => Program st -> st -> IO (Status st)

-- | Are we in a good state, or in a stuck state?
data Status st

-- | Execution finished in the given state.
Good :: st -> Status st

-- | Execution got stuck, with the failing VC
Stuck :: VC st Integer -> Status st
instance GHC.Show.Show st => GHC.Show.Show (Data.SBV.Tools.WeakestPreconditions.Status st)
instance GHC.Show.Show res => GHC.Show.Show (Data.SBV.Tools.WeakestPreconditions.ProofResult res)
instance (GHC.Show.Show st, GHC.Show.Show m) => GHC.Show.Show (Data.SBV.Tools.WeakestPreconditions.VC st m)


-- | Single variable valid range detection.
module Data.SBV.Tools.Range

-- | A boundary value
data Boundary a

-- | Unbounded
Unbounded :: Boundary a

-- | Exclusive of the point
Open :: a -> Boundary a

-- | Inclusive of the point
Closed :: a -> Boundary a

-- | A range is a pair of boundaries: Lower and upper bounds
data Range a
Range :: Boundary a -> Boundary a -> Range a

-- | Given a single predicate over a single variable, find the contiguous
--   ranges over which the predicate is satisfied. SBV will make one call
--   to the optimizer, and then as many calls to the solver as there are
--   disjoint ranges that the predicate is satisfied over. (Linear in the
--   number of ranges.) Note that the number of ranges is large, this can
--   take a long time!
--   
--   Beware that, as of June 2021, z3 no longer supports optimization with
--   <a>SReal</a> in the presence of strict inequalities. See
--   <a>https://github.com/Z3Prover/z3/issues/5314</a> for details. So, if
--   you have <a>SReal</a> variables, it is important that you do
--   <i>not</i> use a strict inequality, i.e., <a>.&gt;</a>, <a>.&lt;</a>,
--   <a>./=</a> etc. Inequalities of the form <a>.&lt;=</a>, <a>.&gt;=</a>
--   should be OK. Please report if you see any fishy behavior due to this
--   change in z3's behavior.
--   
--   Some examples:
--   
--   <pre>
--   &gt;&gt;&gt; ranges (\(_ :: SInteger) -&gt; sFalse)
--   []
--   
--   &gt;&gt;&gt; ranges (\(_ :: SInteger) -&gt; sTrue)
--   [(-oo,oo)]
--   
--   &gt;&gt;&gt; ranges (\(x :: SInteger) -&gt; sAnd [x .&lt;= 120, x .&gt;= -12, x ./= 3])
--   [[-12,3),(3,120]]
--   
--   &gt;&gt;&gt; ranges (\(x :: SInteger) -&gt; sAnd [x .&lt;= 75, x .&gt;= 5, x ./= 6, x ./= 67])
--   [[5,6),(6,67),(67,75]]
--   
--   &gt;&gt;&gt; ranges (\(x :: SInteger) -&gt; sAnd [x .&lt;= 75, x ./= 3, x ./= 67])
--   [(-oo,3),(3,67),(67,75]]
--   
--   &gt;&gt;&gt; ranges (\(x :: SReal) -&gt; sAnd [x .&gt;= 3.2, x .&lt;= 12.7])
--   [[3.2,12.7]]
--   
--   &gt;&gt;&gt; ranges (\(x :: SReal) -&gt; sAnd [x .&lt;= 12.7, x ./= 8])
--   [(-oo,8.0),(8.0,12.7]]
--   
--   &gt;&gt;&gt; ranges (\(x :: SReal) -&gt; sAnd [x .&gt;= 12.7, x ./= 15])
--   [[12.7,15.0),(15.0,oo)]
--   
--   &gt;&gt;&gt; ranges (\(x :: SInt8) -&gt; sAnd [x .&lt;= 7, x ./= 6])
--   [[-128,6),(6,7]]
--   
--   &gt;&gt;&gt; ranges $ \x -&gt; x .&gt;= (0::SReal)
--   [[0.0,oo)]
--   
--   &gt;&gt;&gt; ranges $ \x -&gt; x .&lt;= (0::SReal)
--   [(-oo,0.0]]
--   
--   &gt;&gt;&gt; ranges $ \(x :: SWord8) -&gt; 2*x .== 4
--   [[2,3),(129,130]]
--   </pre>
ranges :: forall a. (Ord a, Num a, SymVal a, SatModel a, Metric a, SymVal (MetricSpace a), SatModel (MetricSpace a)) => (SBV a -> SBool) -> IO [Range a]

-- | Compute ranges, using the given solver configuration.
rangesWith :: forall a. (Ord a, Num a, SymVal a, SatModel a, Metric a, SymVal (MetricSpace a), SatModel (MetricSpace a)) => SMTConfig -> (SBV a -> SBool) -> IO [Range a]
instance GHC.Show.Show a => GHC.Show.Show (Data.SBV.Tools.Range.Range a)


-- | Proof by induction over naturals.
module Data.SBV.Tools.NaturalInduction

-- | Perform natural induction over the given function, which returns left
--   and right hand-sides to be proven equal. Uses <a>defaultSMTCfg</a>.
--   That is, given <tt>f x = (lhs x, rhs x)</tt>, we inductively establish
--   that <tt>lhs</tt> and <tt>rhs</tt> agree on <tt>0</tt>, <tt>1</tt>,
--   ... <tt>n</tt>, i.e., for all non-negative integers.
--   
--   <pre>
--   &gt;&gt;&gt; import Data.SBV
--   
--   &gt;&gt;&gt; import Data.SBV.Tools.NaturalInduction
--   
--   &gt;&gt;&gt; let sumToN        :: SInteger -&gt; SInteger = smtFunction "sumToN"        $ \x -&gt; ite (x .&lt;= 0) 0 (x   + sumToN        (x-1))
--   
--   &gt;&gt;&gt; let sumSquaresToN :: SInteger -&gt; SInteger = smtFunction "sumSquaresToN" $ \x -&gt; ite (x .&lt;= 0) 0 (x*x + sumSquaresToN (x-1))
--   
--   &gt;&gt;&gt; inductNat $ \n -&gt; (sumToN n, (n*(n+1)) `sEDiv` 2)
--   Q.E.D.
--   
--   &gt;&gt;&gt; inductNat $ \n -&gt; (sumSquaresToN n, (n*(n+1)*(2*n+1)) `sEDiv` 6)
--   Q.E.D.
--   
--   &gt;&gt;&gt; inductNat $ \n -&gt; (sumSquaresToN n, ite (n .== 12) 0 ((n*(n+1)*(2*n+1)) `sEDiv` 6))
--   Falsifiable. Counter-example:
--     P(0)   =     (0,0) :: (Integer, Integer)
--     P(k)   = (506,506) :: (Integer, Integer)
--     P(k+1) =   (650,0) :: (Integer, Integer)
--     k      =        11 :: Integer
--   </pre>
inductNat :: SymVal a => (SInteger -> (SBV a, SBV a)) -> IO ThmResult

-- | Perform natural induction over, using the given solver.
inductNatWith :: SymVal a => SMTConfig -> (SInteger -> (SBV a, SBV a)) -> IO ThmResult


-- | Induction engine for state transition systems. See the following
--   examples for details:
--   
--   <ul>
--   <li><a>Documentation.SBV.Examples.ProofTools.Strengthen</a>: Use of
--   strengthening to establish inductive invariants.</li>
--   <li><a>Documentation.SBV.Examples.ProofTools.Sum</a>: Proof for
--   correctness of an algorithm to sum up numbers,</li>
--   <li><a>Documentation.SBV.Examples.ProofTools.Fibonacci</a>: Proof for
--   correctness of an algorithm to fast-compute fibonacci numbers, using
--   axiomatization.</li>
--   </ul>
module Data.SBV.Tools.Induction

-- | Result of an inductive proof, with a counter-example in case of
--   failure.
--   
--   If a proof is found (indicated by a <a>Proven</a> result), then the
--   invariant holds and the goal is established once the termination
--   condition holds. If it fails, then it can fail either in an initiation
--   step or in a consecution step:
--   
--   <ul>
--   <li>A <a>Failed</a> result in an <a>Initiation</a> step means that the
--   invariant does <i>not</i> hold for the initial state, and thus
--   indicates a true failure.</li>
--   <li>A <a>Failed</a> result in a <a>Consecution</a> step will return a
--   state <i>s</i>. This state is known as a CTI (counterexample to
--   inductiveness): It will lead to a violation of the invariant in one
--   step. However, this does not mean the property is invalid: It could be
--   the case that it is simply not inductive. In this case, human
--   intervention---or a smarter algorithm like IC3 for certain
--   domains---is needed to see if one can strengthen the invariant so an
--   inductive proof can be found. How this strengthening can be done
--   remains an art, but the science is improving with algorithms like
--   IC3.</li>
--   <li>A <a>Failed</a> result in a <a>PartialCorrectness</a> step means
--   that the invariant holds, but assuming the termination condition the
--   goal still does not follow. That is, the partial correctness does not
--   hold.</li>
--   </ul>
data InductionResult a
Failed :: InductionStep -> a -> InductionResult a
Proven :: InductionResult a

-- | A step in an inductive proof. If the tag is present (i.e., <tt>Just
--   nm</tt>), then the step belongs to the subproof that establishes the
--   strengthening named <tt>nm</tt>.
data InductionStep
Initiation :: Maybe String -> InductionStep
Consecution :: Maybe String -> InductionStep
PartialCorrectness :: InductionStep

-- | Induction engine, using the default solver. See
--   <a>Documentation.SBV.Examples.ProofTools.Strengthen</a> and
--   <a>Documentation.SBV.Examples.ProofTools.Sum</a> for examples.
induct :: (Show res, Queriable IO st, res ~ QueryResult st) => Bool -> Symbolic () -> (st -> SBool) -> (st -> [st]) -> [(String, st -> SBool)] -> (st -> SBool) -> (st -> (SBool, SBool)) -> IO (InductionResult res)

-- | Induction engine, configurable with the solver
inductWith :: (Show res, Queriable IO st, res ~ QueryResult st) => SMTConfig -> Bool -> Symbolic () -> (st -> SBool) -> (st -> [st]) -> [(String, st -> SBool)] -> (st -> SBool) -> (st -> (SBool, SBool)) -> IO (InductionResult res)
instance GHC.Show.Show a => GHC.Show.Show (Data.SBV.Tools.Induction.InductionResult a)
instance GHC.Show.Show Data.SBV.Tools.Induction.InductionStep


-- | A collection of bounded list utilities, useful when working with
--   symbolic lists. These functions all take a concrete bound, and operate
--   on the prefix of a symbolic list that is at most that long. Due to
--   limitations on writing recursive functions over lists (the classic
--   symbolic termination problem), we cannot write arbitrary recursive
--   programs on symbolic lists. But most of the time all we need is a
--   bounded prefix of this list, at which point these functions come in
--   handy.
module Data.SBV.Tools.BoundedList

-- | Bounded fold from the right.
bfoldr :: (SymVal a, SymVal b) => Int -> (SBV a -> SBV b -> SBV b) -> SBV b -> SList a -> SBV b

-- | Bounded monadic fold from the right.
bfoldrM :: forall a b m. (SymVal a, SymVal b, Monad m, Mergeable (m (SBV b))) => Int -> (SBV a -> SBV b -> m (SBV b)) -> SBV b -> SList a -> m (SBV b)

-- | Bounded fold from the left.
bfoldl :: (SymVal a, SymVal b) => Int -> (SBV b -> SBV a -> SBV b) -> SBV b -> SList a -> SBV b

-- | Bounded monadic fold from the left.
bfoldlM :: forall a b m. (SymVal a, SymVal b, Monad m, Mergeable (m (SBV b))) => Int -> (SBV b -> SBV a -> m (SBV b)) -> SBV b -> SList a -> m (SBV b)

-- | Bounded map.
bmap :: (SymVal a, SymVal b) => Int -> (SBV a -> SBV b) -> SList a -> SList b

-- | Bounded monadic map.
bmapM :: (SymVal a, SymVal b, Monad m, Mergeable (m (SBV [b]))) => Int -> (SBV a -> m (SBV b)) -> SList a -> m (SList b)

-- | Bounded filter.
bfilter :: SymVal a => Int -> (SBV a -> SBool) -> SList a -> SList a

-- | Bounded zipWith
bzipWith :: (SymVal a, SymVal b, SymVal c) => Int -> (SBV a -> SBV b -> SBV c) -> SList a -> SList b -> SList c

-- | Bounded element check
belem :: (Eq a, SymVal a) => Int -> SBV a -> SList a -> SBool

-- | Bounded sum.
bsum :: (SymVal a, Num a, Ord a) => Int -> SList a -> SBV a

-- | Bounded product.
bprod :: (SymVal a, Num a, Ord a) => Int -> SList a -> SBV a

-- | Bounded logical and
band :: Int -> SList Bool -> SBool

-- | Bounded logical or
bor :: Int -> SList Bool -> SBool

-- | Bounded any
bany :: SymVal a => Int -> (SBV a -> SBool) -> SList a -> SBool

-- | Bounded all
ball :: SymVal a => Int -> (SBV a -> SBool) -> SList a -> SBool

-- | Bounded maximum. Undefined if list is empty.
bmaximum :: (Ord a, SymVal a) => Int -> SList a -> SBV a

-- | Bounded minimum. Undefined if list is empty.
bminimum :: (Ord a, SymVal a) => Int -> SList a -> SBV a

-- | Bounded reverse
breverse :: SymVal a => Int -> SList a -> SList a

-- | Bounded insertion sort
bsort :: (Ord a, SymVal a) => Int -> SList a -> SList a


-- | Bounded fixed-point unrolling.
module Data.SBV.Tools.BoundedFix

-- | Bounded fixed-point operation. The call <tt>bfix bnd nm f</tt> unrolls
--   the recursion in <tt>f</tt> at most <tt>bnd</tt> times, and
--   uninterprets the function (with the name <tt>nm</tt>) after the bound
--   is reached.
--   
--   This combinator is handy for dealing with recursive definitions that
--   are not symbolically terminating and when the property we are
--   interested in does not require an infinite unrolling, or when we are
--   happy with a bounded proof. In particular, this operator can be used
--   as a basis of software-bounded model checking algorithms built on top
--   of SBV. The bound can be successively refined in a CEGAR like loop as
--   necessary, by analyzing the counter-examples and rejecting them if
--   they are false-negatives.
--   
--   For instance, we can define the factorial function using the bounded
--   fixed-point operator like this:
--   
--   <pre>
--   bfac :: SInteger -&gt; SInteger
--   bfac = bfix 10 "fac" fact
--     where fact f n = ite (n .== 0) 1 (n * f (n-1))
--   </pre>
--   
--   This definition unrolls the recursion in factorial at most 10 times
--   before uninterpreting the result. We can now prove:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \n -&gt; n .&gt;= 1 .&amp;&amp; n .&lt;= 9 .=&gt; bfac n .== n * bfac (n-1)
--   Q.E.D.
--   </pre>
--   
--   And we would get a bogus counter-example if the proof of our property
--   needs a larger bound:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \n -&gt; n .== 10 .=&gt; bfac n .== 3628800
--   Falsifiable. Counter-example:
--     s0 = 10 :: Integer
--   
--     fac :: Integer -&gt; Integer
--     fac _ = 2
--   </pre>
--   
--   The counter-example is telling us how it instantiated the function
--   <tt>fac</tt> when the recursion bottomed out: It simply made it return
--   <tt>2</tt> for all arguments at that point, which provides the
--   (unintended) counter-example.
--   
--   By design, if a function defined via <a>bfix</a> is given a concrete
--   argument, it will unroll the recursion as much as necessary to
--   complete the call (which can of course diverge). The bound only
--   applies if the given argument is symbolic. This fact can be used to
--   observe concrete values to see where the bounded-model-checking
--   approach fails:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \n -&gt; n .== 10 .=&gt; observe "bfac_n" (bfac n) .== observe "bfac_10" (bfac 10)
--   Falsifiable. Counter-example:
--     bfac_10 = 3628800 :: Integer
--     bfac_n  = 7257600 :: Integer
--     s0      =      10 :: Integer
--   
--     fac :: Integer -&gt; Integer
--     fac _ = 2
--   </pre>
--   
--   Here, we see further evidence that the SMT solver must have decided to
--   assign the value <tt>2</tt> in the final call just as it was reaching
--   the base case, and thus got the final result incorrect. (Note that
--   <tt>7257600 = 2 * 3628800</tt>.) A wrapper algorithm can then assert
--   the actual value of <tt>bfac 10</tt> here as an extra constraint and
--   can search for "deeper bugs."
bfix :: (SymVal a, SMTDefinable (SBV a -> r)) => Int -> String -> ((SBV a -> r) -> SBV a -> r) -> SBV a -> r


-- | Bounded model checking interface. See
--   <a>Documentation.SBV.Examples.ProofTools.BMC</a> for an example use
--   case.
module Data.SBV.Tools.BMC

-- | Bounded model checking, using the default solver. See
--   <a>Documentation.SBV.Examples.ProofTools.BMC</a> for an example use
--   case.
--   
--   Note that the BMC engine does *not* guarantee that the solution is
--   unique. However, if it does find a solution at depth <tt>i</tt>, it is
--   guaranteed that there are no shorter solutions.
bmc :: (EqSymbolic st, Queriable IO st, res ~ QueryResult st) => Maybe Int -> Bool -> Symbolic () -> (st -> SBool) -> (st -> [st]) -> (st -> SBool) -> IO (Either String (Int, [res]))

-- | Bounded model checking, configurable with the solver
bmcWith :: (EqSymbolic st, Queriable IO st, res ~ QueryResult st) => SMTConfig -> Maybe Int -> Bool -> Symbolic () -> (st -> SBool) -> (st -> [st]) -> (st -> SBool) -> IO (Either String (Int, [res]))


-- | Dynamically typed low-level API to the SBV library, for users who want
--   to generate symbolic values at run-time. Note that with this API it is
--   possible to create terms that are not type correct; use at your own
--   risk!
module Data.SBV.Dynamic

-- | The <a>Symbolic</a> value. Either a constant (<tt>Left</tt>) or a
--   symbolic value (<tt>Right Cached</tt>). Note that caching is essential
--   for making sure sharing is preserved.
data SVal

-- | A class for capturing values that have a sign and a size (finite or
--   infinite) minimal complete definition: kindOf, unless you can take
--   advantage of the default signature: This class can be automatically
--   derived for data-types that have a <a>Data</a> instance; this is
--   useful for creating uninterpreted sorts. So, in reality, end users
--   should almost never need to define any methods.
class HasKind a
kindOf :: HasKind a => a -> Kind
hasSign :: HasKind a => a -> Bool
intSizeOf :: HasKind a => a -> Int
isBoolean :: HasKind a => a -> Bool
isBounded :: HasKind a => a -> Bool
isReal :: HasKind a => a -> Bool
isFloat :: HasKind a => a -> Bool
isDouble :: HasKind a => a -> Bool
isRational :: HasKind a => a -> Bool
isFP :: HasKind a => a -> Bool
isUnbounded :: HasKind a => a -> Bool
isUserSort :: HasKind a => a -> Bool
isChar :: HasKind a => a -> Bool
isString :: HasKind a => a -> Bool
isList :: HasKind a => a -> Bool
isSet :: HasKind a => a -> Bool
isTuple :: HasKind a => a -> Bool
isMaybe :: HasKind a => a -> Bool
isEither :: HasKind a => a -> Bool
showType :: HasKind a => a -> String
kindOf :: (HasKind a, Read a, Data a) => a -> Kind

-- | Kind of symbolic value
data Kind
KBool :: Kind
KBounded :: !Bool -> !Int -> Kind
KUnbounded :: Kind
KReal :: Kind
KUserSort :: String -> Maybe [String] -> Kind
KFloat :: Kind
KDouble :: Kind
KFP :: !Int -> !Int -> Kind
KChar :: Kind
KString :: Kind
KList :: Kind -> Kind
KSet :: Kind -> Kind
KTuple :: [Kind] -> Kind
KMaybe :: Kind -> Kind
KRational :: Kind
KEither :: Kind -> Kind -> Kind

-- | <a>CV</a> represents a concrete word of a fixed size: For signed
--   words, the most significant digit is considered to be the sign.
data CV
CV :: !Kind -> !CVal -> CV
[_cvKind] :: CV -> !Kind
[cvVal] :: CV -> !CVal

-- | A constant value
data CVal

-- | Algebraic real
CAlgReal :: !AlgReal -> CVal

-- | Bit-vector/unbounded integer
CInteger :: !Integer -> CVal

-- | Float
CFloat :: !Float -> CVal

-- | Double
CDouble :: !Double -> CVal

-- | Arbitrary float
CFP :: !FP -> CVal

-- | Rational
CRational :: Rational -> CVal

-- | Character
CChar :: !Char -> CVal

-- | String
CString :: !String -> CVal

-- | List
CList :: ![CVal] -> CVal

-- | Set. Can be regular or complemented.
CSet :: !RCSet CVal -> CVal

-- | Value of an uninterpreted/user kind. The Maybe Int shows index
--   position for enumerations
CUserSort :: !(Maybe Int, String) -> CVal

-- | Tuple
CTuple :: ![CVal] -> CVal

-- | Maybe
CMaybe :: !Maybe CVal -> CVal

-- | Disjoint union
CEither :: !Either CVal CVal -> CVal

-- | Convert a CV to a Haskell boolean (NB. Assumes input is well-kinded)
cvToBool :: CV -> Bool

-- | Arrays in terms of SMT-Lib arrays
data SArr

-- | Read the array element at <tt>a</tt>
readSArr :: SArr -> SVal -> SVal

-- | Update the element at <tt>a</tt> to be <tt>b</tt>
writeSArr :: SArr -> SVal -> SVal -> SArr

-- | Merge two given arrays on the symbolic condition Intuitively:
--   <tt>mergeArrays cond a b = if cond then a else b</tt>. Merging pushes
--   the if-then-else choice down on to elements
mergeSArr :: SVal -> SArr -> SArr -> SArr

-- | Create a named new array
newSArr :: State -> (Kind, Kind) -> (Int -> String) -> Either (Maybe SVal) String -> IO SArr

-- | Compare two arrays for equality
eqSArr :: SArr -> SArr -> SVal

-- | <a>Symbolic</a> is specialization of <a>SymbolicT</a> to the <a>IO</a>
--   monad. Unless you are using transformers explicitly, this is the type
--   you should prefer.
type Symbolic = SymbolicT IO

-- | Quantifiers: forall or exists. Note that we allow arbitrary nestings.
data Quantifier
ALL :: Quantifier
EX :: Quantifier

-- | Create a symbolic value, based on the quantifier we have. If an
--   explicit quantifier is given, we just use that. If not, then we pick
--   the quantifier appropriately based on the run-mode. <tt>randomCV</tt>
--   is used for generating random values for this variable when used for
--   <tt>quickCheck</tt> or <a>genTest</a> purposes.
svMkSymVar :: VarContext -> Kind -> Maybe String -> State -> IO SVal

-- | Create an unnamed fresh existential variable in the current context
svNewVar_ :: MonadSymbolic m => Kind -> m SVal

-- | Create a named fresh existential variable in the current context
svNewVar :: MonadSymbolic m => Kind -> String -> m SVal

-- | Generalization of <a>sWordN</a>
sWordN :: MonadSymbolic m => Int -> String -> m SVal

-- | Generalization of <a>sWordN_</a>
sWordN_ :: MonadSymbolic m => Int -> m SVal

-- | Generalization of <a>sIntN</a>
sIntN :: MonadSymbolic m => Int -> String -> m SVal

-- | Generalization of <a>sIntN_</a>
sIntN_ :: MonadSymbolic m => Int -> m SVal

-- | Boolean True.
svTrue :: SVal

-- | Boolean False.
svFalse :: SVal

-- | Convert from a Boolean.
svBool :: Bool -> SVal

-- | Extract a bool, by properly interpreting the integer stored.
svAsBool :: SVal -> Maybe Bool

-- | Convert from an Integer.
svInteger :: Kind -> Integer -> SVal

-- | Extract an integer from a concrete value.
svAsInteger :: SVal -> Maybe Integer

-- | Convert from a Float
svFloat :: Float -> SVal

-- | Convert from a Double
svDouble :: Double -> SVal

-- | Convert from a generalized floating point
svFloatingPoint :: FP -> SVal

-- | Convert from a Rational
svReal :: Rational -> SVal

-- | Grab the numerator of an SReal, if available
svNumerator :: SVal -> Maybe Integer

-- | Grab the denominator of an SReal, if available
svDenominator :: SVal -> Maybe Integer

-- | Equality.
svEqual :: SVal -> SVal -> SVal

-- | Inequality.
svNotEqual :: SVal -> SVal -> SVal

-- | Strong equality. Only matters on floats, where it says <tt>NaN</tt>
--   equals <tt>NaN</tt> and <tt>+0</tt> and <tt>-0</tt> are different.
--   Otherwise equivalent to <a>svEqual</a>.
svStrongEqual :: SVal -> SVal -> SVal

-- | Constructing [x, y, .. z] and [x .. y]. Only works when all arguments
--   are concrete and integral and the result is guaranteed finite Note
--   that the it isn't "obviously" clear why the following works; after all
--   we're doing the construction over Integer's and mapping it back to
--   other types such as SIntN/SWordN. The reason is that the values we
--   receive are guaranteed to be in their domains; and thus the lifting to
--   Integers preserves the bounds; and then going back is just fine. So,
--   things like <tt>[1, 5 .. 200] :: [SInt8]</tt> work just fine (end
--   evaluate to empty list), since we see <tt>[1, 5 .. -56]</tt> in the
--   <tt>Integer</tt> domain. Also note the explicit check for <tt>s /=
--   f</tt> below to make sure we don't stutter and produce an infinite
--   list.
svEnumFromThenTo :: SVal -> Maybe SVal -> SVal -> Maybe [SVal]

-- | Less than.
svLessThan :: SVal -> SVal -> SVal

-- | Greater than.
svGreaterThan :: SVal -> SVal -> SVal

-- | Less than or equal to.
svLessEq :: SVal -> SVal -> SVal

-- | Greater than or equal to.
svGreaterEq :: SVal -> SVal -> SVal

-- | Given a composite structure, figure out how to compare for less than
svStructuralLessThan :: SVal -> SVal -> SVal

-- | Addition.
svPlus :: SVal -> SVal -> SVal

-- | Multiplication.
svTimes :: SVal -> SVal -> SVal

-- | Subtraction.
svMinus :: SVal -> SVal -> SVal

-- | Unary minus. We handle arbitrary-FP's specially here, just for the
--   negated literals.
svUNeg :: SVal -> SVal

-- | Absolute value.
svAbs :: SVal -> SVal

-- | Division.
svDivide :: SVal -> SVal -> SVal

-- | Quotient: Overloaded operation whose meaning depends on the kind at
--   which it is used: For unbounded integers, it corresponds to the
--   SMT-Lib "div" operator (<a>Euclidean</a> division, which always has a
--   non-negative remainder). For unsigned bitvectors, it is "bvudiv"; and
--   for signed bitvectors it is "bvsdiv", which rounds toward zero.
--   Division by 0 is defined s.t. <tt>x/0 = 0</tt>, which holds even when
--   <tt>x</tt> itself is <tt>0</tt>.
svQuot :: SVal -> SVal -> SVal

-- | Remainder: Overloaded operation whose meaning depends on the kind at
--   which it is used: For unbounded integers, it corresponds to the
--   SMT-Lib "mod" operator (always non-negative). For unsigned bitvectors,
--   it is "bvurem"; and for signed bitvectors it is "bvsrem", which rounds
--   toward zero (sign of remainder matches that of <tt>x</tt>). Division
--   by 0 is defined s.t. <tt>x/0 = 0</tt>, which holds even when
--   <tt>x</tt> itself is <tt>0</tt>.
svRem :: SVal -> SVal -> SVal

-- | Combination of quot and rem
svQuotRem :: SVal -> SVal -> (SVal, SVal)

-- | Exponentiation.
svExp :: SVal -> SVal -> SVal

-- | Add a constant value:
svAddConstant :: Integral a => SVal -> a -> SVal

-- | Increment:
svIncrement :: SVal -> SVal

-- | Decrement:
svDecrement :: SVal -> SVal

-- | Bitwise and.
svAnd :: SVal -> SVal -> SVal

-- | Bitwise or.
svOr :: SVal -> SVal -> SVal

-- | Bitwise xor.
svXOr :: SVal -> SVal -> SVal

-- | Bitwise complement.
svNot :: SVal -> SVal

-- | Shift left by a constant amount. Translates to the "bvshl" operation
--   in SMT-Lib.
--   
--   NB. Haskell spec says the behavior is undefined if the shift amount is
--   negative. We arbitrarily return the value unchanged if this is the
--   case.
svShl :: SVal -> Int -> SVal

-- | Shift right by a constant amount. Translates to either "bvlshr"
--   (logical shift right) or "bvashr" (arithmetic shift right) in SMT-Lib,
--   depending on whether <tt>x</tt> is a signed bitvector.
--   
--   NB. Haskell spec says the behavior is undefined if the shift amount is
--   negative. We arbitrarily return the value unchanged if this is the
--   case.
svShr :: SVal -> Int -> SVal

-- | Rotate-left, by a constant.
--   
--   NB. Haskell spec says the behavior is undefined if the shift amount is
--   negative. We arbitrarily return the value unchanged if this is the
--   case.
svRol :: SVal -> Int -> SVal

-- | Rotate-right, by a constant.
--   
--   NB. Haskell spec says the behavior is undefined if the shift amount is
--   negative. We arbitrarily return the value unchanged if this is the
--   case.
svRor :: SVal -> Int -> SVal

-- | Extract bit-sequences.
svExtract :: Int -> Int -> SVal -> SVal

-- | Join two words, by concatenating
svJoin :: SVal -> SVal -> SVal

-- | Zero-extend by given number of bits.
svZeroExtend :: Int -> SVal -> SVal

-- | Sign-extend by given number of bits.
svSignExtend :: Int -> SVal -> SVal

-- | Convert a symbolic bitvector from unsigned to signed.
svSign :: SVal -> SVal

-- | Convert a symbolic bitvector from signed to unsigned.
svUnsign :: SVal -> SVal

-- | Convert a symbolic bitvector from one integral kind to another.
svFromIntegral :: Kind -> SVal -> SVal

-- | Total indexing operation. <tt>svSelect xs default index</tt> is
--   intuitively the same as <tt>xs !! index</tt>, except it evaluates to
--   <tt>default</tt> if <tt>index</tt> overflows. Translates to SMT-Lib
--   tables.
svSelect :: [SVal] -> SVal -> SVal -> SVal

-- | Convert an SVal from kind Bool to an unsigned bitvector of size 1.
svToWord1 :: SVal -> SVal

-- | Convert an SVal from a bitvector of size 1 (signed or unsigned) to
--   kind Bool.
svFromWord1 :: SVal -> SVal

-- | Test the value of a bit. Note that we do an extract here as opposed to
--   masking and checking against zero, as we found extraction to be much
--   faster with large bit-vectors.
svTestBit :: SVal -> Int -> SVal

-- | Set a given bit at index
svSetBit :: SVal -> Int -> SVal

-- | Generalization of <a>svShl</a>, where the shift-amount is symbolic.
svShiftLeft :: SVal -> SVal -> SVal

-- | Generalization of <a>svShr</a>, where the shift-amount is symbolic.
--   
--   NB. If the shiftee is signed, then this is an arithmetic shift;
--   otherwise it's logical.
svShiftRight :: SVal -> SVal -> SVal

-- | Generalization of <a>svRol</a>, where the rotation amount is symbolic.
--   If the first argument is not bounded, then the this is the same as
--   shift.
svRotateLeft :: SVal -> SVal -> SVal

-- | Generalization of <a>svRor</a>, where the rotation amount is symbolic.
--   If the first argument is not bounded, then the this is the same as
--   shift.
svRotateRight :: SVal -> SVal -> SVal

-- | A variant of <a>svRotateLeft</a> that uses a barrel-rotate design,
--   which can lead to better verification code. Only works when both
--   arguments are finite and the second argument is unsigned.
svBarrelRotateLeft :: SVal -> SVal -> SVal

-- | A variant of <a>svRotateLeft</a> that uses a barrel-rotate design,
--   which can lead to better verification code. Only works when both
--   arguments are finite and the second argument is unsigned.
svBarrelRotateRight :: SVal -> SVal -> SVal

-- | Un-bit-blast from little-endian representation to a word of the right
--   size. The input is assumed to be unsigned.
svWordFromBE :: [SVal] -> SVal

-- | Un-bit-blast from big-endian representation to a word of the right
--   size. The input is assumed to be unsigned.
svWordFromLE :: [SVal] -> SVal

-- | Bit-blast: Little-endian. Assumes the input is a bit-vector or a
--   floating point type.
svBlastLE :: SVal -> [SVal]

-- | Bit-blast: Big-endian. Assumes the input is a bit-vector or a floating
--   point type.
svBlastBE :: SVal -> [SVal]

-- | If-then-else. This one will force branches.
svIte :: SVal -> SVal -> SVal -> SVal

-- | Lazy If-then-else. This one will delay forcing the branches unless
--   it's really necessary.
svLazyIte :: Kind -> SVal -> SVal -> SVal -> SVal

-- | Merge two symbolic values, at kind <tt>k</tt>, possibly
--   <tt>force</tt>'ing the branches to make sure they do not evaluate to
--   the same result.
svSymbolicMerge :: Kind -> Bool -> SVal -> SVal -> SVal -> SVal

-- | Uninterpreted constants and functions. An uninterpreted constant is a
--   value that is indexed by its name. The only property the prover
--   assumes about these values are that they are equivalent to themselves;
--   i.e., (for functions) they return the same results when applied to
--   same arguments. We support uninterpreted-functions as a general means
--   of black-box'ing operations that are <i>irrelevant</i> for the
--   purposes of the proof; i.e., when the proofs can be performed without
--   any knowledge about the function itself.
svUninterpreted :: Kind -> String -> UICodeKind -> [SVal] -> SVal

-- | Proves the predicate using the given SMT-solver
proveWith :: SMTConfig -> Symbolic SVal -> IO ThmResult

-- | Find a satisfying assignment using the given SMT-solver
satWith :: SMTConfig -> Symbolic SVal -> IO SatResult

-- | Find all satisfying assignments using the given SMT-solver
allSatWith :: SMTConfig -> Symbolic SVal -> IO AllSatResult

-- | Check safety using the given SMT-solver
safeWith :: SMTConfig -> Symbolic SVal -> IO [SafeResult]

-- | Prove a property with multiple solvers, running them in separate
--   threads. The results will be returned in the order produced.
proveWithAll :: [SMTConfig] -> Symbolic SVal -> IO [(Solver, NominalDiffTime, ThmResult)]

-- | Prove a property with multiple solvers, running them in separate
--   threads. Only the result of the first one to finish will be returned,
--   remaining threads will be killed.
proveWithAny :: [SMTConfig] -> Symbolic SVal -> IO (Solver, NominalDiffTime, ThmResult)

-- | Find a satisfying assignment to a property with multiple solvers,
--   running them in separate threads. The results will be returned in the
--   order produced.
satWithAll :: [SMTConfig] -> Symbolic SVal -> IO [(Solver, NominalDiffTime, SatResult)]

-- | Find a satisfying assignment to a property with multiple solvers,
--   running them in separate threads. Only the result of the first one to
--   finish will be returned, remaining threads will be killed.
satWithAny :: [SMTConfig] -> Symbolic SVal -> IO (Solver, NominalDiffTime, SatResult)

-- | Prove a property with query mode using multiple threads. Each query
--   computation will spawn a thread and a unique instance of your solver
--   to run asynchronously. The <a>Symbolic</a> <a>SVal</a> is duplicated
--   for each thread. This function will block until all child threads
--   return.
proveConcurrentWithAll :: SMTConfig -> Symbolic SVal -> [Query SVal] -> IO [(Solver, NominalDiffTime, ThmResult)]

-- | Prove a property with query mode using multiple threads. Each query
--   computation will spawn a thread and a unique instance of your solver
--   to run asynchronously. The <a>Symbolic</a> <a>SVal</a> is duplicated
--   for each thread. This function will return the first query computation
--   that completes, killing the others.
proveConcurrentWithAny :: SMTConfig -> Symbolic SVal -> [Query SVal] -> IO (Solver, NominalDiffTime, ThmResult)

-- | Find a satisfying assignment to a property with multiple threads in
--   query mode. The <a>Symbolic</a> <a>SVal</a> represents what is known
--   to all child query threads. Each query thread will spawn a unique
--   instance of the solver. Only the first one to finish will be returned
--   and the other threads will be killed.
satConcurrentWithAny :: SMTConfig -> [Query b] -> Symbolic SVal -> IO (Solver, NominalDiffTime, SatResult)

-- | Find a satisfying assignment to a property with multiple threads in
--   query mode. The <a>Symbolic</a> <a>SVal</a> represents what is known
--   to all child query threads. Each query thread will spawn a unique
--   instance of the solver. This function will block until all child
--   threads have completed.
satConcurrentWithAll :: SMTConfig -> [Query b] -> Symbolic SVal -> IO [(Solver, NominalDiffTime, SatResult)]

-- | Dynamic variant of quick-check
svQuickCheck :: Symbolic SVal -> IO Bool

-- | A <a>prove</a> call results in a <a>ThmResult</a>
newtype ThmResult
ThmResult :: SMTResult -> ThmResult

-- | A <a>sat</a> call results in a <a>SatResult</a> The reason for having
--   a separate <a>SatResult</a> is to have a more meaningful <a>Show</a>
--   instance.
newtype SatResult
SatResult :: SMTResult -> SatResult

-- | An <a>allSat</a> call results in a <a>AllSatResult</a>
data AllSatResult
AllSatResult :: Bool -> Bool -> Bool -> [SMTResult] -> AllSatResult

-- | Did we reach the user given model count limit?
[allSatMaxModelCountReached] :: AllSatResult -> Bool

-- | Did the solver report unknown at the end?
[allSatSolverReturnedUnknown] :: AllSatResult -> Bool

-- | Did the solver report delta-satisfiable at the end?
[allSatSolverReturnedDSat] :: AllSatResult -> Bool

-- | All satisfying models
[allSatResults] :: AllSatResult -> [SMTResult]

-- | A <a>safe</a> call results in a <a>SafeResult</a>
newtype SafeResult
SafeResult :: (Maybe String, String, SMTResult) -> SafeResult

-- | An <a>optimize</a> call results in a <a>OptimizeResult</a>. In the
--   <a>ParetoResult</a> case, the boolean is <a>True</a> if we reached
--   pareto-query limit and so there might be more unqueried results
--   remaining. If <a>False</a>, it means that we have all the pareto
--   fronts returned. See the <a>Pareto</a> <a>OptimizeStyle</a> for
--   details.
data OptimizeResult
LexicographicResult :: SMTResult -> OptimizeResult
ParetoResult :: (Bool, [SMTResult]) -> OptimizeResult
IndependentResult :: [(String, SMTResult)] -> OptimizeResult

-- | The result of an SMT solver call. Each constructor is tagged with the
--   <a>SMTConfig</a> that created it so that further tools can inspect it
--   and build layers of results, if needed. For ordinary uses of the
--   library, this type should not be needed, instead use the accessor
--   functions on it. (Custom Show instances and model extractors.)
data SMTResult

-- | Unsatisfiable. If unsat-cores are enabled, they will be returned in
--   the second parameter.
Unsatisfiable :: SMTConfig -> Maybe [String] -> SMTResult

-- | Satisfiable with model
Satisfiable :: SMTConfig -> SMTModel -> SMTResult

-- | Delta satisfiable with queried string if available and model
DeltaSat :: SMTConfig -> Maybe String -> SMTModel -> SMTResult

-- | Prover returned a model, but in an extension field containing
--   Infinite/epsilon
SatExtField :: SMTConfig -> SMTModel -> SMTResult

-- | Prover returned unknown, with the given reason
Unknown :: SMTConfig -> SMTReasonUnknown -> SMTResult

-- | Prover errored out, with possibly a bogus result
ProofError :: SMTConfig -> [String] -> Maybe SMTResult -> SMTResult

-- | Parse a signed/sized value from a sequence of CVs
genParse :: Integral a => Kind -> [CV] -> Maybe (a, [CV])

-- | Extract a model, the result is a tuple where the first argument (if
--   True) indicates whether the model was "probable". (i.e., if the solver
--   returned unknown.)
getModelAssignment :: SMTResult -> Either String (Bool, [CV])

-- | Extract a model dictionary. Extract a dictionary mapping the variables
--   to their respective values as returned by the SMT solver. Also see
--   <a>getModelDictionaries</a>.
getModelDictionary :: SMTResult -> Map String CV

-- | Solver configuration. See also <a>z3</a>, <a>yices</a>, <a>cvc4</a>,
--   <a>boolector</a>, <a>mathSAT</a>, etc. which are instantiations of
--   this type for those solvers, with reasonable defaults. In particular,
--   custom configuration can be created by varying those values. (Such as
--   <tt>z3{verbose=True}</tt>.)
--   
--   Most fields are self explanatory. The notion of precision for printing
--   algebraic reals stems from the fact that such values does not
--   necessarily have finite decimal representations, and hence we have to
--   stop printing at some depth. It is important to emphasize that such
--   values always have infinite precision internally. The issue is merely
--   with how we print such an infinite precision value on the screen. The
--   field <a>printRealPrec</a> controls the printing precision, by
--   specifying the number of digits after the decimal point. The default
--   value is 16, but it can be set to any positive integer.
--   
--   When printing, SBV will add the suffix <tt>...</tt> at the end of a
--   real-value, if the given bound is not sufficient to represent the
--   real-value exactly. Otherwise, the number will be written out in
--   standard decimal notation. Note that SBV will always print the whole
--   value if it is precise (i.e., if it fits in a finite number of
--   digits), regardless of the precision limit. The limit only applies if
--   the representation of the real value is not finite, i.e., if it is not
--   rational.
--   
--   The <a>printBase</a> field can be used to print numbers in base 2, 10,
--   or 16.
--   
--   The <a>crackNum</a> field can be used to display numbers in detail,
--   all its bits and how they are laid out in memory. Works with all
--   bounded number types (i.e., SWord and SInt), but also with floats. It
--   is particularly useful with floating-point numbers, as it shows you
--   how they are laid out in memory following the IEEE754 rules.
data SMTConfig
SMTConfig :: Bool -> Timing -> Int -> Int -> Bool -> String -> Maybe Int -> Bool -> Bool -> (String -> Bool) -> Bool -> Bool -> Maybe FilePath -> SMTLibVersion -> Maybe Double -> SMTSolver -> [String] -> RoundingMode -> [SMTOption] -> Bool -> Maybe FilePath -> SMTConfig

-- | Debug mode
[verbose] :: SMTConfig -> Bool

-- | Print timing information on how long different phases took
--   (construction, solving, etc.)
[timing] :: SMTConfig -> Timing

-- | Print integral literals in this base (2, 10, and 16 are supported.)
[printBase] :: SMTConfig -> Int

-- | Print algebraic real values with this precision. (SReal, default: 16)
[printRealPrec] :: SMTConfig -> Int

-- | For each numeric value, show it in detail in the model with its bits
--   spliced out. Good for floats.
[crackNum] :: SMTConfig -> Bool

-- | Usually "(check-sat)". However, users might tweak it based on solver
--   characteristics.
[satCmd] :: SMTConfig -> String

-- | In a <a>allSat</a> call, return at most this many models. If nothing,
--   return all.
[allSatMaxModelCount] :: SMTConfig -> Maybe Int

-- | In a <a>allSat</a> call, print models as they are found.
[allSatPrintAlong] :: SMTConfig -> Bool

-- | In a <a>allSat</a> call, should we try to extract values of
--   uninterpreted functions?
[allSatTrackUFs] :: SMTConfig -> Bool

-- | When constructing a model, ignore variables whose name satisfy this
--   predicate. (Default: (const False), i.e., don't ignore anything)
[isNonModelVar] :: SMTConfig -> String -> Bool

-- | If set, SBV will attempt to validate the model it gets back from the
--   solver.
[validateModel] :: SMTConfig -> Bool

-- | Validate optimization results. NB: Does NOT make sure the model is
--   optimal, just checks they satisfy the constraints.
[optimizeValidateConstraints] :: SMTConfig -> Bool

-- | If Just, the entire interaction will be recorded as a playable file
--   (for debugging purposes mostly)
[transcript] :: SMTConfig -> Maybe FilePath

-- | What version of SMT-lib we use for the tool
[smtLibVersion] :: SMTConfig -> SMTLibVersion

-- | Delta-sat precision
[dsatPrecision] :: SMTConfig -> Maybe Double

-- | The actual SMT solver.
[solver] :: SMTConfig -> SMTSolver

-- | Extra command line arguments to pass to the solver.
[extraArgs] :: SMTConfig -> [String]

-- | Rounding mode to use for floating-point conversions
[roundingMode] :: SMTConfig -> RoundingMode

-- | Options to set as we start the solver
[solverSetOptions] :: SMTConfig -> [SMTOption]

-- | If true, we shall ignore the exit code upon exit. Otherwise we require
--   ExitSuccess.
[ignoreExitCode] :: SMTConfig -> Bool

-- | Redirect the verbose output to this file if given. If Nothing, stdout
--   is implied.
[redirectVerbose] :: SMTConfig -> Maybe FilePath

-- | Representation of SMTLib Program versions. As of June 2015, we're
--   dropping support for SMTLib1, and supporting SMTLib2 only. We keep
--   this data-type around in case SMTLib3 comes along and we want to
--   support 2 and 3 simultaneously.
data SMTLibVersion
SMTLib2 :: SMTLibVersion

-- | Solvers that SBV is aware of
data Solver
ABC :: Solver
Boolector :: Solver
Bitwuzla :: Solver
CVC4 :: Solver
CVC5 :: Solver
DReal :: Solver
MathSAT :: Solver
Yices :: Solver
Z3 :: Solver

-- | An SMT solver
data SMTSolver
SMTSolver :: Solver -> String -> (String -> String) -> (SMTConfig -> [String]) -> SMTEngine -> SolverCapabilities -> SMTSolver

-- | The solver in use
[name] :: SMTSolver -> Solver

-- | The path to its executable
[executable] :: SMTSolver -> String

-- | Each line sent to the solver will be passed through this function
--   (typically id)
[preprocess] :: SMTSolver -> String -> String

-- | Options to provide to the solver
[options] :: SMTSolver -> SMTConfig -> [String]

-- | The solver engine, responsible for interpreting solver output
[engine] :: SMTSolver -> SMTEngine

-- | Various capabilities of the solver
[capabilities] :: SMTSolver -> SolverCapabilities

-- | Default configuration for the Boolector SMT solver
boolector :: SMTConfig

-- | Default configuration for the Bitwuzla SMT solver
bitwuzla :: SMTConfig

-- | Default configuration for the CVC4 SMT Solver.
cvc4 :: SMTConfig

-- | Default configuration for the CVC5 SMT Solver.
cvc5 :: SMTConfig

-- | Default configuration for the Yices SMT Solver.
dReal :: SMTConfig

-- | Default configuration for the Yices SMT Solver.
yices :: SMTConfig

-- | Default configuration for the Z3 SMT solver
z3 :: SMTConfig

-- | Default configuration for the MathSAT SMT solver
mathSAT :: SMTConfig

-- | Default configuration for the ABC synthesis and verification tool.
abc :: SMTConfig

-- | The default configs corresponding to supported SMT solvers
defaultSolverConfig :: Solver -> SMTConfig

-- | The default solver used by SBV. This is currently set to z3.
defaultSMTCfg :: SMTConfig

-- | Check whether the given solver is installed and is ready to go. This
--   call does a simple call to the solver to ensure all is well.
sbvCheckSolverInstallation :: SMTConfig -> IO Bool

-- | Return the known available solver configs, installed on your machine.
getAvailableSolvers :: IO [SMTConfig]

-- | Generalization of <a>outputSVal</a>
outputSVal :: MonadSymbolic m => SVal -> m ()

-- | The code-generation monad. Allows for precise layout of input values
--   reference parameters (for returning composite values in languages such
--   as C), and return values.
data SBVCodeGen a

-- | Sets RTC (run-time-checks) for index-out-of-bounds, shift-with-large
--   value etc. on/off. Default: <a>False</a>.
cgPerformRTCs :: Bool -> SBVCodeGen ()

-- | Sets driver program run time values, useful for generating programs
--   with fixed drivers for testing. Default: None, i.e., use random
--   values.
cgSetDriverValues :: [Integer] -> SBVCodeGen ()

-- | Should we generate a driver program? Default: <a>True</a>. When a
--   library is generated, it will have a driver if any of the constituent
--   functions has a driver. (See <a>compileToCLib</a>.)
cgGenerateDriver :: Bool -> SBVCodeGen ()

-- | Should we generate a Makefile? Default: <a>True</a>.
cgGenerateMakefile :: Bool -> SBVCodeGen ()

-- | Creates an atomic input in the generated code.
svCgInput :: Kind -> String -> SBVCodeGen SVal

-- | Creates an array input in the generated code.
svCgInputArr :: Kind -> Int -> String -> SBVCodeGen [SVal]

-- | Creates an atomic output in the generated code.
svCgOutput :: String -> SVal -> SBVCodeGen ()

-- | Creates an array output in the generated code.
svCgOutputArr :: String -> [SVal] -> SBVCodeGen ()

-- | Creates a returned (unnamed) value in the generated code.
svCgReturn :: SVal -> SBVCodeGen ()

-- | Creates a returned (unnamed) array value in the generated code.
svCgReturnArr :: [SVal] -> SBVCodeGen ()

-- | Adds the given lines to the header file generated, useful for
--   generating programs with uninterpreted functions.
cgAddPrototype :: [String] -> SBVCodeGen ()

-- | Adds the given lines to the program file generated, useful for
--   generating programs with uninterpreted functions.
cgAddDecl :: [String] -> SBVCodeGen ()

-- | Adds the given words to the compiler options in the generated
--   Makefile, useful for linking extra stuff in.
cgAddLDFlags :: [String] -> SBVCodeGen ()

-- | Ignore assertions (those generated by <a>sAssert</a> calls) in the
--   generated C code
cgIgnoreSAssert :: Bool -> SBVCodeGen ()

-- | Sets number of bits to be used for representing the <a>SInteger</a>
--   type in the generated C code. The argument must be one of <tt>8</tt>,
--   <tt>16</tt>, <tt>32</tt>, or <tt>64</tt>. Note that this is
--   essentially unsafe as the semantics of unbounded Haskell integers
--   becomes reduced to the corresponding bit size, as typical in most C
--   implementations.
cgIntegerSize :: Int -> SBVCodeGen ()

-- | Sets the C type to be used for representing the <a>SReal</a> type in
--   the generated C code. The setting can be one of C's <tt>"float"</tt>,
--   <tt>"double"</tt>, or <tt>"long double"</tt>, types, depending on the
--   precision needed. Note that this is essentially unsafe as the
--   semantics of infinite precision SReal values becomes reduced to the
--   corresponding floating point type in C, and hence it is subject to
--   rounding errors.
cgSRealType :: CgSRealType -> SBVCodeGen ()

-- | Possible mappings for the <a>SReal</a> type when translated to C. Used
--   in conjunction with the function <a>cgSRealType</a>. Note that the
--   particular characteristics of the mapped types depend on the platform
--   and the compiler used for compiling the generated C program. See
--   <a>http://en.wikipedia.org/wiki/C_data_types</a> for details.
data CgSRealType

-- | <pre>
--   float
--   </pre>
CgFloat :: CgSRealType

-- | <pre>
--   double
--   </pre>
CgDouble :: CgSRealType

-- | <pre>
--   long double
--   </pre>
CgLongDouble :: CgSRealType

-- | Given a symbolic computation, render it as an equivalent collection of
--   files that make up a C program:
--   
--   <ul>
--   <li>The first argument is the directory name under which the files
--   will be saved. To save files in the current directory pass
--   <tt><a>Just</a> "."</tt>. Use <a>Nothing</a> for printing to
--   stdout.</li>
--   <li>The second argument is the name of the C function to
--   generate.</li>
--   <li>The final argument is the function to be compiled.</li>
--   </ul>
--   
--   Compilation will also generate a <tt>Makefile</tt>, a header file, and
--   a driver (test) program, etc. As a result, we return whatever the
--   code-gen function returns. Most uses should simply have <tt>()</tt> as
--   the return type here, but the value can be useful if you want to chain
--   the result of one compilation act to the next.
compileToC :: Maybe FilePath -> String -> SBVCodeGen a -> IO a

-- | Create code to generate a library archive (.a) from given symbolic
--   functions. Useful when generating code from multiple functions that
--   work together as a library.
--   
--   <ul>
--   <li>The first argument is the directory name under which the files
--   will be saved. To save files in the current directory pass
--   <tt><a>Just</a> "."</tt>. Use <a>Nothing</a> for printing to
--   stdout.</li>
--   <li>The second argument is the name of the archive to generate.</li>
--   <li>The third argument is the list of functions to include, in the
--   form of function-name/code pairs, similar to the second and third
--   arguments of <a>compileToC</a>, except in a list.</li>
--   </ul>
compileToCLib :: Maybe FilePath -> String -> [(String, SBVCodeGen a)] -> IO [a]

-- | Create SMT-Lib benchmark for a sat call
generateSMTBenchmarkSat :: Symbolic SVal -> IO String

-- | Create SMT-Lib benchmark for a proof call
generateSMTBenchmarkProof :: Symbolic SVal -> IO String


-- | Checks the correctness of a few tricks from the large collection found
--   in: <a>http://graphics.stanford.edu/~seander/bithacks.html</a>
module Documentation.SBV.Examples.BitPrecise.BitTricks

-- | Formalizes
--   <a>http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax</a>
fastMinCorrect :: SInt32 -> SInt32 -> SBool

-- | Formalizes
--   <a>http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax</a>
fastMaxCorrect :: SInt32 -> SInt32 -> SBool

-- | Formalizes
--   <a>http://graphics.stanford.edu/~seander/bithacks.html#DetectOppositeSigns</a>
oppositeSignsCorrect :: SInt32 -> SInt32 -> SBool

-- | Formalizes
--   <a>http://graphics.stanford.edu/~seander/bithacks.html#ConditionalSetOrClearBitsWithoutBranching</a>
conditionalSetClearCorrect :: SBool -> SWord32 -> SWord32 -> SBool

-- | Formalizes
--   <a>http://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2</a>
powerOfTwoCorrect :: SWord32 -> SBool

-- | Collection of queries
queries :: IO ()


-- | The classic "binary-searches are broken" example:
--   <a>http://ai.googleblog.com/2006/06/extra-extra-read-all-about-it-nearly.html</a>
module Documentation.SBV.Examples.BitPrecise.BrokenSearch

-- | Model the mid-point computation of the binary search, which is broken
--   due to arithmetic overflow. Note how we use the overflow checking
--   variants of the arithmetic operators. We have:
--   
--   <pre>
--   &gt;&gt;&gt; checkArithOverflow midPointBroken
--   ./Documentation/SBV/Examples/BitPrecise/BrokenSearch.hs:39:32:+!: SInt32 addition overflows: Violated. Model:
--     low  = 2147475456 :: Int32
--     high = 2147483646 :: Int32
--   </pre>
--   
--   Indeed:
--   
--   <pre>
--   &gt;&gt;&gt; (2147475456 + 2147483646) `div` (2::Int32)
--   -4097
--   </pre>
--   
--   giving us a negative mid-point value!
midPointBroken :: SInt32 -> SInt32 -> SInt32

-- | The correct version of how to compute the mid-point. As expected, this
--   version doesn't have any underflow or overflow issues:
--   
--   <pre>
--   &gt;&gt;&gt; checkArithOverflow midPointFixed
--   No violations detected.
--   </pre>
--   
--   As expected, the value is computed correctly too:
--   
--   <pre>
--   &gt;&gt;&gt; checkCorrectMidValue midPointFixed
--   Q.E.D.
--   </pre>
midPointFixed :: SInt32 -> SInt32 -> SInt32

-- | Show that the variant suggested by the blog post is good as well:
--   
--   <pre>
--   mid = ((unsigned int)low + (unsigned int)high) &gt;&gt; 1;
--   </pre>
--   
--   In this case the overflow is eliminated by doing the computation at a
--   wider range:
--   
--   <pre>
--   &gt;&gt;&gt; checkArithOverflow midPointAlternative
--   No violations detected.
--   </pre>
--   
--   And the value computed is indeed correct:
--   
--   <pre>
--   &gt;&gt;&gt; checkCorrectMidValue midPointAlternative
--   Q.E.D.
--   </pre>
midPointAlternative :: SInt32 -> SInt32 -> SInt32

-- | A helper predicate to check safety under the conditions that
--   <tt>low</tt> is at least 0 and <tt>high</tt> is at least <tt>low</tt>.
checkArithOverflow :: (SInt32 -> SInt32 -> SInt32) -> IO ()

-- | Another helper to show that the result is actually the correct value,
--   if it was done over 64-bit integers, which is sufficiently large
--   enough.
checkCorrectMidValue :: (SInt32 -> SInt32 -> SInt32) -> IO ThmResult


-- | An encoding and correctness proof of Legato's multiplier in Haskell.
--   Bill Legato came up with an interesting way to multiply two 8-bit
--   numbers on Mostek, as described here:
--   <a>http://www.cs.utexas.edu/~moore/acl2/workshop-2004/contrib/legato/Weakest-Preconditions-Report.pdf</a>
--   
--   Here's Legato's algorithm, as coded in Mostek assembly:
--   
--   <pre>
--   step1 :       LDX #8         ; load X immediate with the integer 8
--   step2 :       LDA #0         ; load A immediate with the integer 0
--   step3 : LOOP  ROR F1         ; rotate F1 right circular through C
--   step4 :       BCC ZCOEF      ; branch to ZCOEF if C = 0
--   step5 :       CLC            ; set C to 0
--   step6 :       ADC F2         ; set A to A+F2+C and C to the carry
--   step7 : ZCOEF ROR A          ; rotate A right circular through C
--   step8 :       ROR LOW        ; rotate LOW right circular through C
--   step9 :       DEX            ; set X to X-1
--   step10:       BNE LOOP       ; branch to LOOP if Z = 0
--   </pre>
--   
--   This program came to be known as the Legato's challenge in the
--   community, where the challenge was to prove that it indeed does
--   perform multiplication. This file formalizes the Mostek architecture
--   in Haskell and proves that Legato's algorithm is indeed correct.
module Documentation.SBV.Examples.BitPrecise.Legato

-- | We model only two registers of Mostek that is used in the above
--   algorithm, can add more.
data Register
RegX :: Register
RegA :: Register

-- | The carry flag (<a>FlagC</a>) and the zero flag (<a>FlagZ</a>)
data Flag
FlagC :: Flag
FlagZ :: Flag

-- | Mostek was an 8-bit machine.
type Value = SWord 8

-- | Convenient synonym for symbolic machine bits.
type Bit = SBool

-- | Register bank
type Registers = Array Register Value

-- | Flag bank
type Flags = Array Flag Bit

-- | We have three memory locations, sufficient to model our problem
data Location

-- | multiplicand
F1 :: Location

-- | multiplier
F2 :: Location

-- | low byte of the result gets stored here
LO :: Location

-- | Memory is simply an array from locations to values
type Memory = Array Location Value

-- | Abstraction of the machine: The CPU consists of memory, registers, and
--   flags. Unlike traditional hardware, we assume the program is stored in
--   some other memory area that we need not model. (No self modifying
--   programs!)
--   
--   <a>Mostek</a> is equipped with an automatically derived
--   <a>Mergeable</a> instance because each field is <a>Mergeable</a>.
data Mostek
Mostek :: Memory -> Registers -> Flags -> Mostek
[memory] :: Mostek -> Memory
[registers] :: Mostek -> Registers
[flags] :: Mostek -> Flags

-- | Given a machine state, compute a value out of it
type Extract a = Mostek -> a

-- | Programs are essentially state transformers (on the machine state)
type Program = Mostek -> Mostek

-- | Get the value of a given register
getReg :: Register -> Extract Value

-- | Set the value of a given register
setReg :: Register -> Value -> Program

-- | Get the value of a flag
getFlag :: Flag -> Extract Bit

-- | Set the value of a flag
setFlag :: Flag -> Bit -> Program

-- | Read memory
peek :: Location -> Extract Value

-- | Write to memory
poke :: Location -> Value -> Program

-- | Checking overflow. In Legato's multiplier the <tt>ADC</tt> instruction
--   needs to see if the expression x + y + c overflowed, as checked by
--   this function. Note that we verify the correctness of this check
--   separately below in <a>checkOverflowCorrect</a>.
checkOverflow :: SWord 8 -> SWord 8 -> SBool -> SBool

-- | Correctness theorem for our <a>checkOverflow</a> implementation.
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; checkOverflowCorrect
--   Q.E.D.
--   </pre>
checkOverflowCorrect :: IO ThmResult

-- | An instruction is modeled as a <a>Program</a> transformer. We model
--   mostek programs in direct continuation passing style.
type Instruction = Program -> Program

-- | LDX: Set register <tt>X</tt> to value <tt>v</tt>
ldx :: Value -> Instruction

-- | LDA: Set register <tt>A</tt> to value <tt>v</tt>
lda :: Value -> Instruction

-- | CLC: Clear the carry flag
clc :: Instruction

-- | ROR, memory version: Rotate the value at memory location <tt>a</tt> to
--   the right by 1 bit, using the carry flag as a transfer position. That
--   is, the final bit of the memory location becomes the new carry and the
--   carry moves over to the first bit. This very instruction is one of the
--   reasons why Legato's multiplier is quite hard to understand and is
--   typically presented as a verification challenge.
rorM :: Location -> Instruction

-- | ROR, register version: Same as <a>rorM</a>, except through register
--   <tt>r</tt>.
rorR :: Register -> Instruction

-- | BCC: branch to label <tt>l</tt> if the carry flag is sFalse
bcc :: Program -> Instruction

-- | ADC: Increment the value of register <tt>A</tt> by the value of memory
--   contents at location <tt>a</tt>, using the carry-bit as the carry-in
--   for the addition.
adc :: Location -> Instruction

-- | DEX: Decrement the value of register <tt>X</tt>
dex :: Instruction

-- | BNE: Branch if the zero-flag is sFalse
bne :: Program -> Instruction

-- | The <a>end</a> combinator "stops" our program, providing the final
--   continuation that does nothing.
end :: Program

-- | Multiplies the contents of <tt>F1</tt> and <tt>F2</tt>, storing the
--   low byte of the result in <tt>LO</tt> and the high byte of it in
--   register <tt>A</tt>. The implementation is a direct transliteration of
--   Legato's algorithm given at the top, using our notation.
legato :: Program

-- | Given values for F1 and F2, <tt>runLegato</tt> takes an arbitrary
--   machine state <tt>m</tt> and returns the high and low bytes of the
--   multiplication.
runLegato :: Mostek -> (Value, Value)

-- | Helper synonym for capturing relevant bits of Mostek
type InitVals = (Value, Value, Value, Value, Value, Bit, Bit)

-- | Create an instance of the Mostek machine, initialized by the memory
--   and the relevant values of the registers and the flags
initMachine :: InitVals -> Mostek

-- | The correctness theorem. For all possible memory configurations, the
--   factors (<tt>x</tt> and <tt>y</tt> below), the location of the
--   low-byte result and the initial-values of registers and the flags,
--   this function will return True only if running Legato's algorithm does
--   indeed compute the product of <tt>x</tt> and <tt>y</tt> correctly.
legatoIsCorrect :: InitVals -> SBool

-- | The correctness theorem.
correctnessTheorem :: IO ThmResult

-- | Generate a C program that implements Legato's algorithm automatically.
legatoInC :: IO ()
instance GHC.Enum.Bounded Documentation.SBV.Examples.BitPrecise.Legato.Register
instance GHC.Ix.Ix Documentation.SBV.Examples.BitPrecise.Legato.Register
instance GHC.Classes.Ord Documentation.SBV.Examples.BitPrecise.Legato.Register
instance GHC.Classes.Eq Documentation.SBV.Examples.BitPrecise.Legato.Register
instance GHC.Enum.Bounded Documentation.SBV.Examples.BitPrecise.Legato.Flag
instance GHC.Ix.Ix Documentation.SBV.Examples.BitPrecise.Legato.Flag
instance GHC.Classes.Ord Documentation.SBV.Examples.BitPrecise.Legato.Flag
instance GHC.Classes.Eq Documentation.SBV.Examples.BitPrecise.Legato.Flag
instance GHC.Enum.Bounded Documentation.SBV.Examples.BitPrecise.Legato.Location
instance GHC.Ix.Ix Documentation.SBV.Examples.BitPrecise.Legato.Location
instance GHC.Classes.Ord Documentation.SBV.Examples.BitPrecise.Legato.Location
instance GHC.Classes.Eq Documentation.SBV.Examples.BitPrecise.Legato.Location
instance Data.SBV.Core.Model.Mergeable Documentation.SBV.Examples.BitPrecise.Legato.Mostek
instance GHC.Generics.Generic Documentation.SBV.Examples.BitPrecise.Legato.Mostek


-- | Symbolic implementation of merge-sort and its correctness.
module Documentation.SBV.Examples.BitPrecise.MergeSort

-- | Element type of lists we'd like to sort. For simplicity, we'll just
--   use <a>SWord8</a> here, but we can pick any symbolic type.
type E = SWord8

-- | Merging two given sorted lists, preserving the order.
merge :: [E] -> [E] -> [E]

-- | Simple merge-sort implementation. We simply divide the input list in
--   two halves so long as it has at least two elements, sort each half on
--   its own, and then merge.
mergeSort :: [E] -> [E]

-- | Check whether a given sequence is non-decreasing.
nonDecreasing :: [E] -> SBool

-- | Check whether two given sequences are permutations. We simply check
--   that each sequence is a subset of the other, when considered as a set.
--   The check is slightly complicated for the need to account for possibly
--   duplicated elements.
isPermutationOf :: [E] -> [E] -> SBool

-- | Asserting correctness of merge-sort for a list of the given size. Note
--   that we can only check correctness for fixed-size lists. Also, the
--   proof will get more and more complicated for the backend SMT solver as
--   the list size increases. A value around 5 or 6 should be fairly easy
--   to prove. For instance, we have:
--   
--   <pre>
--   &gt;&gt;&gt; correctness 5
--   Q.E.D.
--   </pre>
correctness :: Int -> IO ThmResult

-- | Generate C code for merge-sorting an array of size <tt>n</tt>. Again,
--   we're restricted to fixed size inputs. While the output is not how one
--   would code merge sort in C by hand, it's a faithful rendering of all
--   the operations merge-sort would do as described by its Haskell
--   counterpart.
codeGen :: Int -> IO ()


-- | An SBV solution to the bit-precise puzzle of shuffling the bits in a
--   64-bit word in a custom order. The idea is to take a 64-bit value:
--   
--   <pre>
--   1.......2.......3.......4.......5.......6.......7.......8.......
--   </pre>
--   
--   And turn it into another 64-bit value, that looks like this:
--   
--   <pre>
--   12345678........................................................
--   </pre>
--   
--   We do not care what happens to the bits that are represented by dots.
--   The problem is to do this with one mask and one multiplication.
--   
--   Apparently this operation has several applications, including in
--   programs that play chess of all things. We use SBV to find the
--   appropriate mask and the multiplier.
--   
--   Note that this is an instance of the program synthesis problem, where
--   we "fill in the blanks" given a certain skeleton that satisfy a
--   certain property, using quantified formulas.
module Documentation.SBV.Examples.BitPrecise.MultMask

-- | Find the multiplier and the mask as described. We have:
--   
--   <pre>
--   &gt;&gt;&gt; maskAndMult
--   Satisfiable. Model:
--     mask = 0x8080808080808080 :: Word64
--     mult = 0x0002040810204081 :: Word64
--   </pre>
--   
--   That is, any 64 bit value masked by the first and multiplied by the
--   second value above will have its bits at positions
--   <tt>[7,15,23,31,39,47,55,63]</tt> moved to positions
--   <tt>[56,57,58,59,60,61,62,63]</tt> respectively.
--   
--   NB. Depending on your z3 version, you might also get the following
--   multiplier as the result: 0x8202040810204081. That value works just
--   fine as well!
--   
--   NB. Note the custom call to z3 with a specific tactic. A simple call
--   to z3 unfortunately does not terminate quickly.
maskAndMult :: IO ()


-- | The PrefixSum algorithm over power-lists and proof of the
--   Ladner-Fischer implementation. See
--   <a>http://dl.acm.org/citation.cfm?id=197356</a> and
--   <a>http://www.cs.utexas.edu/~plaxton/c/337/05f/slides/ParallelRecursion-4.pdf</a>.
module Documentation.SBV.Examples.BitPrecise.PrefixSum

-- | A poor man's representation of powerlists and basic operations on
--   them: <a>http://dl.acm.org/citation.cfm?id=197356</a> We merely
--   represent power-lists by ordinary lists.
type PowerList a = [a]

-- | The tie operator, concatenation.
tiePL :: PowerList a -> PowerList a -> PowerList a

-- | The zip operator, zips the power-lists of the same size, returns a
--   powerlist of double the size.
zipPL :: PowerList a -> PowerList a -> PowerList a

-- | Inverse of zipping.
unzipPL :: PowerList a -> (PowerList a, PowerList a)

-- | Reference prefix sum (<tt>ps</tt>) is simply Haskell's <tt>scanl1</tt>
--   function.
ps :: (a, a -> a -> a) -> PowerList a -> PowerList a

-- | The Ladner-Fischer (<tt>lf</tt>) implementation of prefix-sum. See
--   <a>http://www.cs.utexas.edu/~plaxton/c/337/05f/slides/ParallelRecursion-4.pdf</a>
--   or pg. 16 of <a>http://dl.acm.org/citation.cfm?id=197356</a>
lf :: (a, a -> a -> a) -> PowerList a -> PowerList a

-- | Correctness theorem, for a powerlist of given size, an associative
--   operator, and its left-unit element.
flIsCorrect :: Int -> (forall a. (OrdSymbolic a, Num a, Bits a) => (a, a -> a -> a)) -> Symbolic SBool

-- | Proves Ladner-Fischer is equivalent to reference specification for
--   addition. <tt>0</tt> is the left-unit element, and we use a power-list
--   of size <tt>8</tt>. We have:
--   
--   <pre>
--   &gt;&gt;&gt; thm1
--   Q.E.D.
--   </pre>
thm1 :: IO ThmResult

-- | Proves Ladner-Fischer is equivalent to reference specification for the
--   function <tt>max</tt>. <tt>0</tt> is the left-unit element, and we use
--   a power-list of size <tt>16</tt>. We have:
--   
--   <pre>
--   &gt;&gt;&gt; thm2
--   Q.E.D.
--   </pre>
thm2 :: IO ThmResult


-- | Simple code generation example.
module Documentation.SBV.Examples.CodeGeneration.AddSub

-- | Simple function that returns add/sum of args
addSub :: SWord8 -> SWord8 -> (SWord8, SWord8)

-- | Generate C code for addSub. Here's the output showing the generated C
--   code:
--   
--   <pre>
--   &gt;&gt;&gt; genAddSub
--   == BEGIN: "Makefile" ================
--   # Makefile for addSub. Automatically generated by SBV. Do not edit!
--   
--   # include any user-defined .mk file in the current directory.
--   -include *.mk
--   
--   CC?=gcc
--   CCFLAGS?=-Wall -O3 -DNDEBUG -fomit-frame-pointer
--   
--   all: addSub_driver
--   
--   addSub.o: addSub.c addSub.h
--   	${CC} ${CCFLAGS} -c $&lt; -o $@
--   
--   addSub_driver.o: addSub_driver.c
--   	${CC} ${CCFLAGS} -c $&lt; -o $@
--   
--   addSub_driver: addSub.o addSub_driver.o
--   	${CC} ${CCFLAGS} $^ -o $@
--   
--   clean:
--   	rm -f *.o
--   
--   veryclean: clean
--   	rm -f addSub_driver
--   == END: "Makefile" ==================
--   == BEGIN: "addSub.h" ================
--   /* Header file for addSub. Automatically generated by SBV. Do not edit! */
--   
--   #ifndef __addSub__HEADER_INCLUDED__
--   #define __addSub__HEADER_INCLUDED__
--   
--   #include &lt;stdio.h&gt;
--   #include &lt;stdlib.h&gt;
--   #include &lt;inttypes.h&gt;
--   #include &lt;stdint.h&gt;
--   #include &lt;stdbool.h&gt;
--   #include &lt;string.h&gt;
--   #include &lt;math.h&gt;
--   
--   /* The boolean type */
--   typedef bool SBool;
--   
--   /* The float type */
--   typedef float SFloat;
--   
--   /* The double type */
--   typedef double SDouble;
--   
--   /* Unsigned bit-vectors */
--   typedef uint8_t  SWord8;
--   typedef uint16_t SWord16;
--   typedef uint32_t SWord32;
--   typedef uint64_t SWord64;
--   
--   /* Signed bit-vectors */
--   typedef int8_t  SInt8;
--   typedef int16_t SInt16;
--   typedef int32_t SInt32;
--   typedef int64_t SInt64;
--   
--   /* Entry point prototype: */
--   void addSub(const SWord8 x, const SWord8 y, SWord8 *sum,
--               SWord8 *dif);
--   
--   #endif /* __addSub__HEADER_INCLUDED__ */
--   == END: "addSub.h" ==================
--   == BEGIN: "addSub_driver.c" ================
--   /* Example driver program for addSub. */
--   /* Automatically generated by SBV. Edit as you see fit! */
--   
--   #include &lt;stdio.h&gt;
--   #include "addSub.h"
--   
--   int main(void)
--   {
--     SWord8 sum;
--     SWord8 dif;
--   
--     addSub(132, 241, &amp;sum, &amp;dif);
--   
--     printf("addSub(132, 241, &amp;sum, &amp;dif) -&gt;\n");
--     printf("  sum = %"PRIu8"\n", sum);
--     printf("  dif = %"PRIu8"\n", dif);
--   
--     return 0;
--   }
--   == END: "addSub_driver.c" ==================
--   == BEGIN: "addSub.c" ================
--   /* File: "addSub.c". Automatically generated by SBV. Do not edit! */
--   
--   #include "addSub.h"
--   
--   void addSub(const SWord8 x, const SWord8 y, SWord8 *sum,
--               SWord8 *dif)
--   {
--     const SWord8 s0 = x;
--     const SWord8 s1 = y;
--     const SWord8 s2 = s0 + s1;
--     const SWord8 s3 = s0 - s1;
--   
--     *sum = s2;
--     *dif = s3;
--   }
--   == END: "addSub.c" ==================
--   </pre>
genAddSub :: IO ()


-- | Computing the CRC symbolically, using the USB polynomial. We also
--   generating C code for it as well. This example demonstrates the use of
--   the <a>crcBV</a> function, along with how CRC's can be computed
--   mathematically using polynomial division. While the results are the
--   same (i.e., proven equivalent, see <a>crcGood</a> below), the internal
--   CRC implementation generates much better code, compare <a>cg1</a> vs
--   <a>cg2</a> below.
module Documentation.SBV.Examples.CodeGeneration.CRC_USB5

-- | The USB CRC polynomial: <tt>x^5 + x^2 + 1</tt>. Although this
--   polynomial needs just 6 bits to represent (5 if higher order bit is
--   implicitly assumed to be set), we'll simply use a 16 bit number for
--   its representation to keep things simple for code generation purposes.
usb5 :: SWord16

-- | Given an 11 bit message, compute the CRC of it using the USB
--   polynomial, which is 5 bits, and then append it to the msg to get a
--   16-bit word. Again, the incoming 11-bits is represented as a 16-bit
--   word, with 5 highest bits essentially ignored for input purposes.
crcUSB :: SWord16 -> SWord16

-- | Alternate method for computing the CRC, <i>mathematically</i>. We
--   shift the number to the left by 5, and then compute the remainder from
--   the polynomial division by the USB polynomial. The result is then
--   appended to the end of the message.
crcUSB' :: SWord16 -> SWord16

-- | Prove that the custom <a>crcBV</a> function is equivalent to the
--   mathematical definition of CRC's for 11 bit messages. We have:
--   
--   <pre>
--   &gt;&gt;&gt; crcGood
--   Q.E.D.
--   </pre>
crcGood :: IO ThmResult

-- | Generate a C function to compute the USB CRC, using the internal CRC
--   function.
cg1 :: IO ()

-- | Generate a C function to compute the USB CRC, using the mathematical
--   definition of the CRCs. While this version generates functionally
--   equivalent C code, it's less efficient; it has about 30% more code.
--   So, the above version is preferable for code generation purposes.
cg2 :: IO ()


-- | Computing Fibonacci numbers and generating C code. Inspired by Lee
--   Pike's original implementation, modified for inclusion in the package.
--   It illustrates symbolic termination issues one can have when working
--   with recursive algorithms and how to deal with such, eventually
--   generating good C code.
module Documentation.SBV.Examples.CodeGeneration.Fibonacci

-- | This is a naive implementation of fibonacci, and will work fine
--   (albeit slow) for concrete inputs:
--   
--   <pre>
--   &gt;&gt;&gt; map fib0 [0..6]
--   [0 :: SWord64,1 :: SWord64,1 :: SWord64,2 :: SWord64,3 :: SWord64,5 :: SWord64,8 :: SWord64]
--   </pre>
--   
--   However, it is not suitable for doing proofs or generating code, as it
--   is not symbolically terminating when it is called with a symbolic
--   value <tt>n</tt>. When we recursively call <tt>fib0</tt> on
--   <tt>n-1</tt> (or <tt>n-2</tt>), the test against <tt>0</tt> will
--   always explore both branches since the result will be symbolic, hence
--   will not terminate. (An integrated theorem prover can establish
--   termination after a certain number of unrollings, but this would be
--   quite expensive to implement, and would be impractical.)
fib0 :: SWord64 -> SWord64

-- | The recursion-depth limited version of fibonacci. Limiting the maximum
--   number to be 20, we can say:
--   
--   <pre>
--   &gt;&gt;&gt; map (fib1 20) [0..6]
--   [0 :: SWord64,1 :: SWord64,1 :: SWord64,2 :: SWord64,3 :: SWord64,5 :: SWord64,8 :: SWord64]
--   </pre>
--   
--   The function will work correctly, so long as the index we query is at
--   most <tt>top</tt>, and otherwise will return the value at
--   <tt>top</tt>. Note that we also use accumulating parameters here for
--   efficiency, although this is orthogonal to the termination concern.
--   
--   A note on modular arithmetic: The 64-bit word we use to represent the
--   values will of course eventually overflow, beware! Fibonacci is a fast
--   growing function..
fib1 :: SWord64 -> SWord64 -> SWord64

-- | We can generate code for <a>fib1</a> using the <a>genFib1</a> action.
--   Note that the generated code will grow larger as we pick larger values
--   of <tt>top</tt>, but only linearly, thanks to the accumulating
--   parameter trick used by <a>fib1</a>. The following is an excerpt from
--   the code generated for the call <tt>genFib1 10</tt>, where the code
--   will work correctly for indexes up to 10:
--   
--   <pre>
--   SWord64 fib1(const SWord64 x)
--   {
--     const SWord64 s0 = x;
--     const SBool   s2 = s0 == 0x0000000000000000ULL;
--     const SBool   s4 = s0 == 0x0000000000000001ULL;
--     const SBool   s6 = s0 == 0x0000000000000002ULL;
--     const SBool   s8 = s0 == 0x0000000000000003ULL;
--     const SBool   s10 = s0 == 0x0000000000000004ULL;
--     const SBool   s12 = s0 == 0x0000000000000005ULL;
--     const SBool   s14 = s0 == 0x0000000000000006ULL;
--     const SBool   s17 = s0 == 0x0000000000000007ULL;
--     const SBool   s19 = s0 == 0x0000000000000008ULL;
--     const SBool   s22 = s0 == 0x0000000000000009ULL;
--     const SWord64 s25 = s22 ? 0x0000000000000022ULL : 0x0000000000000037ULL;
--     const SWord64 s26 = s19 ? 0x0000000000000015ULL : s25;
--     const SWord64 s27 = s17 ? 0x000000000000000dULL : s26;
--     const SWord64 s28 = s14 ? 0x0000000000000008ULL : s27;
--     const SWord64 s29 = s12 ? 0x0000000000000005ULL : s28;
--     const SWord64 s30 = s10 ? 0x0000000000000003ULL : s29;
--     const SWord64 s31 = s8 ? 0x0000000000000002ULL : s30;
--     const SWord64 s32 = s6 ? 0x0000000000000001ULL : s31;
--     const SWord64 s33 = s4 ? 0x0000000000000001ULL : s32;
--     const SWord64 s34 = s2 ? 0x0000000000000000ULL : s33;
--     
--     return s34;
--   }
--   </pre>
genFib1 :: SWord64 -> IO ()

-- | Compute the fibonacci numbers statically at <i>code-generation</i>
--   time and put them in a table, accessed by the <a>select</a> call.
fib2 :: SWord64 -> SWord64 -> SWord64

-- | Once we have <a>fib2</a>, we can generate the C code
--   straightforwardly. Below is an excerpt from the code that SBV
--   generates for the call <tt>genFib2 64</tt>. Note that this code is a
--   constant-time look-up table implementation of fibonacci, with no
--   run-time overhead. The index can be made arbitrarily large, naturally.
--   (Note that this function returns <tt>0</tt> if the index is larger
--   than 64, as specified by the call to <a>select</a> with default
--   <tt>0</tt>.)
--   
--   <pre>
--   SWord64 fibLookup(const SWord64 x)
--   {
--     const SWord64 s0 = x;
--     static const SWord64 table0[] = {
--         0x0000000000000000ULL, 0x0000000000000001ULL,
--         0x0000000000000001ULL, 0x0000000000000002ULL,
--         0x0000000000000003ULL, 0x0000000000000005ULL,
--         0x0000000000000008ULL, 0x000000000000000dULL,
--         0x0000000000000015ULL, 0x0000000000000022ULL,
--         0x0000000000000037ULL, 0x0000000000000059ULL,
--         0x0000000000000090ULL, 0x00000000000000e9ULL,
--         0x0000000000000179ULL, 0x0000000000000262ULL,
--         0x00000000000003dbULL, 0x000000000000063dULL,
--         0x0000000000000a18ULL, 0x0000000000001055ULL,
--         0x0000000000001a6dULL, 0x0000000000002ac2ULL,
--         0x000000000000452fULL, 0x0000000000006ff1ULL,
--         0x000000000000b520ULL, 0x0000000000012511ULL,
--         0x000000000001da31ULL, 0x000000000002ff42ULL,
--         0x000000000004d973ULL, 0x000000000007d8b5ULL,
--         0x00000000000cb228ULL, 0x0000000000148addULL,
--         0x0000000000213d05ULL, 0x000000000035c7e2ULL,
--         0x00000000005704e7ULL, 0x00000000008cccc9ULL,
--         0x0000000000e3d1b0ULL, 0x0000000001709e79ULL,
--         0x0000000002547029ULL, 0x0000000003c50ea2ULL,
--         0x0000000006197ecbULL, 0x0000000009de8d6dULL,
--         0x000000000ff80c38ULL, 0x0000000019d699a5ULL,
--         0x0000000029cea5ddULL, 0x0000000043a53f82ULL,
--         0x000000006d73e55fULL, 0x00000000b11924e1ULL,
--         0x000000011e8d0a40ULL, 0x00000001cfa62f21ULL,
--         0x00000002ee333961ULL, 0x00000004bdd96882ULL,
--         0x00000007ac0ca1e3ULL, 0x0000000c69e60a65ULL,
--         0x0000001415f2ac48ULL, 0x000000207fd8b6adULL,
--         0x0000003495cb62f5ULL, 0x0000005515a419a2ULL,
--         0x00000089ab6f7c97ULL, 0x000000dec1139639ULL,
--         0x000001686c8312d0ULL, 0x000002472d96a909ULL,
--         0x000003af9a19bbd9ULL, 0x000005f6c7b064e2ULL, 0x000009a661ca20bbULL
--     };
--     const SWord64 s65 = s0 &gt;= 65 ? 0x0000000000000000ULL : table0[s0];
--     
--     return s65;
--   }
--   </pre>
genFib2 :: SWord64 -> IO ()


-- | Computing GCD symbolically, and generating C code for it. This example
--   illustrates symbolic termination related issues when programming with
--   SBV, when the termination of a recursive algorithm crucially depends
--   on the value of a symbolic variable. The technique we use is to
--   statically enforce termination by using a recursion depth counter.
module Documentation.SBV.Examples.CodeGeneration.GCD

-- | The symbolic GCD algorithm, over two 8-bit numbers. We define <tt>sgcd
--   a 0</tt> to be <tt>a</tt> for all <tt>a</tt>, which implies <tt>sgcd 0
--   0 = 0</tt>. Note that this is essentially Euclid's algorithm, except
--   with a recursion depth counter. We need the depth counter since the
--   algorithm is not <i>symbolically terminating</i>, as we don't have a
--   means of determining that the second argument (<tt>b</tt>) will
--   eventually reach 0 in a symbolic context. Hence we stop after 12
--   iterations. Why 12? We've empirically determined that this algorithm
--   will recurse at most 12 times for arbitrary 8-bit numbers. Of course,
--   this is a claim that we shall prove below.
sgcd :: SWord8 -> SWord8 -> SWord8

-- | We have:
--   
--   <pre>
--   &gt;&gt;&gt; prove sgcdIsCorrect
--   Q.E.D.
--   </pre>
sgcdIsCorrect :: SWord8 -> SWord8 -> SWord8 -> SBool

-- | This call will generate the required C files. The following is the
--   function body generated for <a>sgcd</a>. (We are not showing the
--   generated header, <tt>Makefile</tt>, and the driver programs for
--   brevity.) Note that the generated function is a constant time
--   algorithm for GCD. It is not necessarily fastest, but it will take
--   precisely the same amount of time for all values of <tt>x</tt> and
--   <tt>y</tt>.
--   
--   <pre>
--   /* File: "sgcd.c". Automatically generated by SBV. Do not edit! */
--   
--   #include &lt;stdio.h&gt;
--   #include &lt;stdlib.h&gt;
--   #include &lt;inttypes.h&gt;
--   #include &lt;stdint.h&gt;
--   #include &lt;stdbool.h&gt;
--   #include "sgcd.h"
--   
--   SWord8 sgcd(const SWord8 x, const SWord8 y)
--   {
--     const SWord8 s0 = x;
--     const SWord8 s1 = y;
--     const SBool  s3 = s1 == 0;
--     const SWord8 s4 = (s1 == 0) ? s0 : (s0 % s1);
--     const SWord8 s5 = s3 ? s0 : s4;
--     const SBool  s6 = 0 == s5;
--     const SWord8 s7 = (s5 == 0) ? s1 : (s1 % s5);
--     const SWord8 s8 = s6 ? s1 : s7;
--     const SBool  s9 = 0 == s8;
--     const SWord8 s10 = (s8 == 0) ? s5 : (s5 % s8);
--     const SWord8 s11 = s9 ? s5 : s10;
--     const SBool  s12 = 0 == s11;
--     const SWord8 s13 = (s11 == 0) ? s8 : (s8 % s11);
--     const SWord8 s14 = s12 ? s8 : s13;
--     const SBool  s15 = 0 == s14;
--     const SWord8 s16 = (s14 == 0) ? s11 : (s11 % s14);
--     const SWord8 s17 = s15 ? s11 : s16;
--     const SBool  s18 = 0 == s17;
--     const SWord8 s19 = (s17 == 0) ? s14 : (s14 % s17);
--     const SWord8 s20 = s18 ? s14 : s19;
--     const SBool  s21 = 0 == s20;
--     const SWord8 s22 = (s20 == 0) ? s17 : (s17 % s20);
--     const SWord8 s23 = s21 ? s17 : s22;
--     const SBool  s24 = 0 == s23;
--     const SWord8 s25 = (s23 == 0) ? s20 : (s20 % s23);
--     const SWord8 s26 = s24 ? s20 : s25;
--     const SBool  s27 = 0 == s26;
--     const SWord8 s28 = (s26 == 0) ? s23 : (s23 % s26);
--     const SWord8 s29 = s27 ? s23 : s28;
--     const SBool  s30 = 0 == s29;
--     const SWord8 s31 = (s29 == 0) ? s26 : (s26 % s29);
--     const SWord8 s32 = s30 ? s26 : s31;
--     const SBool  s33 = 0 == s32;
--     const SWord8 s34 = (s32 == 0) ? s29 : (s29 % s32);
--     const SWord8 s35 = s33 ? s29 : s34;
--     const SBool  s36 = 0 == s35;
--     const SWord8 s37 = s36 ? s32 : s35;
--     const SWord8 s38 = s33 ? s29 : s37;
--     const SWord8 s39 = s30 ? s26 : s38;
--     const SWord8 s40 = s27 ? s23 : s39;
--     const SWord8 s41 = s24 ? s20 : s40;
--     const SWord8 s42 = s21 ? s17 : s41;
--     const SWord8 s43 = s18 ? s14 : s42;
--     const SWord8 s44 = s15 ? s11 : s43;
--     const SWord8 s45 = s12 ? s8 : s44;
--     const SWord8 s46 = s9 ? s5 : s45;
--     const SWord8 s47 = s6 ? s1 : s46;
--     const SWord8 s48 = s3 ? s0 : s47;
--     
--     return s48;
--   }
--   </pre>
genGCDInC :: IO ()


-- | Computing population-counts (number of set bits) and automatically
--   generating C code.
module Documentation.SBV.Examples.CodeGeneration.PopulationCount

-- | Given a 64-bit quantity, the simplest (and obvious) way to count the
--   number of bits that are set in it is to simply walk through all the
--   bits and add 1 to a running count. This is slow, as it requires 64
--   iterations, but is simple and easy to convince yourself that it is
--   correct. For instance:
--   
--   <pre>
--   &gt;&gt;&gt; popCountSlow 0x0123456789ABCDEF
--   32 :: SWord8
--   </pre>
popCountSlow :: SWord64 -> SWord8

-- | Faster version. This is essentially the same algorithm, except we go 8
--   bits at a time instead of one by one, by using a precomputed table of
--   population-count values for each byte. This algorithm <i>loops</i>
--   only 8 times, and hence is at least 8 times more efficient.
popCountFast :: SWord64 -> SWord8

-- | Look-up table, containing population counts for all possible 8-bit
--   value, from 0 to 255. Note that we do not "hard-code" the values, but
--   merely use the slow version to compute them.
pop8 :: [SWord8]

-- | States the correctness of faster population-count algorithm, with
--   respect to the reference slow version. Turns out Z3's default solver
--   is rather slow for this one, but there's a magic incantation to make
--   it go fast. See <a>http://github.com/Z3Prover/z3/issues/1150</a> for
--   details.
--   
--   <pre>
--   &gt;&gt;&gt; let cmd = "(check-sat-using (then (using-params ackermannize_bv :div0_ackermann_limit 1000000) simplify bit-blast sat))"
--   
--   &gt;&gt;&gt; proveWith z3{satCmd = cmd} fastPopCountIsCorrect
--   Q.E.D.
--   </pre>
fastPopCountIsCorrect :: SWord64 -> SBool

-- | Not only we can prove that faster version is correct, but we can also
--   automatically generate C code to compute population-counts for us.
--   This action will generate all the C files that you will need,
--   including a driver program for test purposes.
--   
--   Below is the generated header file for <a>popCountFast</a>:
--   
--   <pre>
--   &gt;&gt;&gt; genPopCountInC
--   == BEGIN: "Makefile" ================
--   # Makefile for popCount. Automatically generated by SBV. Do not edit!
--   
--   # include any user-defined .mk file in the current directory.
--   -include *.mk
--   
--   CC?=gcc
--   CCFLAGS?=-Wall -O3 -DNDEBUG -fomit-frame-pointer
--   
--   all: popCount_driver
--   
--   popCount.o: popCount.c popCount.h
--   	${CC} ${CCFLAGS} -c $&lt; -o $@
--   
--   popCount_driver.o: popCount_driver.c
--   	${CC} ${CCFLAGS} -c $&lt; -o $@
--   
--   popCount_driver: popCount.o popCount_driver.o
--   	${CC} ${CCFLAGS} $^ -o $@
--   
--   clean:
--   	rm -f *.o
--   
--   veryclean: clean
--   	rm -f popCount_driver
--   == END: "Makefile" ==================
--   == BEGIN: "popCount.h" ================
--   /* Header file for popCount. Automatically generated by SBV. Do not edit! */
--   
--   #ifndef __popCount__HEADER_INCLUDED__
--   #define __popCount__HEADER_INCLUDED__
--   
--   #include &lt;stdio.h&gt;
--   #include &lt;stdlib.h&gt;
--   #include &lt;inttypes.h&gt;
--   #include &lt;stdint.h&gt;
--   #include &lt;stdbool.h&gt;
--   #include &lt;string.h&gt;
--   #include &lt;math.h&gt;
--   
--   /* The boolean type */
--   typedef bool SBool;
--   
--   /* The float type */
--   typedef float SFloat;
--   
--   /* The double type */
--   typedef double SDouble;
--   
--   /* Unsigned bit-vectors */
--   typedef uint8_t  SWord8;
--   typedef uint16_t SWord16;
--   typedef uint32_t SWord32;
--   typedef uint64_t SWord64;
--   
--   /* Signed bit-vectors */
--   typedef int8_t  SInt8;
--   typedef int16_t SInt16;
--   typedef int32_t SInt32;
--   typedef int64_t SInt64;
--   
--   /* Entry point prototype: */
--   SWord8 popCount(const SWord64 x);
--   
--   #endif /* __popCount__HEADER_INCLUDED__ */
--   == END: "popCount.h" ==================
--   == BEGIN: "popCount_driver.c" ================
--   /* Example driver program for popCount. */
--   /* Automatically generated by SBV. Edit as you see fit! */
--   
--   #include &lt;stdio.h&gt;
--   #include "popCount.h"
--   
--   int main(void)
--   {
--     const SWord8 __result = popCount(0x1b02e143e4f0e0e5ULL);
--   
--     printf("popCount(0x1b02e143e4f0e0e5ULL) = %"PRIu8"\n", __result);
--   
--     return 0;
--   }
--   == END: "popCount_driver.c" ==================
--   == BEGIN: "popCount.c" ================
--   /* File: "popCount.c". Automatically generated by SBV. Do not edit! */
--   
--   #include "popCount.h"
--   
--   SWord8 popCount(const SWord64 x)
--   {
--     const SWord64 s0 = x;
--     static const SWord8 table0[] = {
--         0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4, 1, 2, 2, 3, 2, 3,
--         3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4,
--         3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 1, 2,
--         2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5,
--         3, 4, 4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5,
--         5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 1, 2, 2, 3,
--         2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4,
--         4, 5, 4, 5, 5, 6, 2, 3, 3, 4, 3, 4, 4, 5, 3, 4, 4, 5, 4, 5, 5, 6,
--         3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 2, 3, 3, 4, 3, 4,
--         4, 5, 3, 4, 4, 5, 4, 5, 5, 6, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6,
--         5, 6, 6, 7, 3, 4, 4, 5, 4, 5, 5, 6, 4, 5, 5, 6, 5, 6, 6, 7, 4, 5,
--         5, 6, 5, 6, 6, 7, 5, 6, 6, 7, 6, 7, 7, 8
--     };
--     const SWord64 s11 = s0 &amp; 0x00000000000000ffULL;
--     const SWord8  s12 = table0[s11];
--     const SWord64 s14 = s0 &gt;&gt; 8;
--     const SWord64 s15 = 0x00000000000000ffULL &amp; s14;
--     const SWord8  s16 = table0[s15];
--     const SWord8  s17 = s12 + s16;
--     const SWord64 s18 = s14 &gt;&gt; 8;
--     const SWord64 s19 = 0x00000000000000ffULL &amp; s18;
--     const SWord8  s20 = table0[s19];
--     const SWord8  s21 = s17 + s20;
--     const SWord64 s22 = s18 &gt;&gt; 8;
--     const SWord64 s23 = 0x00000000000000ffULL &amp; s22;
--     const SWord8  s24 = table0[s23];
--     const SWord8  s25 = s21 + s24;
--     const SWord64 s26 = s22 &gt;&gt; 8;
--     const SWord64 s27 = 0x00000000000000ffULL &amp; s26;
--     const SWord8  s28 = table0[s27];
--     const SWord8  s29 = s25 + s28;
--     const SWord64 s30 = s26 &gt;&gt; 8;
--     const SWord64 s31 = 0x00000000000000ffULL &amp; s30;
--     const SWord8  s32 = table0[s31];
--     const SWord8  s33 = s29 + s32;
--     const SWord64 s34 = s30 &gt;&gt; 8;
--     const SWord64 s35 = 0x00000000000000ffULL &amp; s34;
--     const SWord8  s36 = table0[s35];
--     const SWord8  s37 = s33 + s36;
--     const SWord64 s38 = s34 &gt;&gt; 8;
--     const SWord64 s39 = 0x00000000000000ffULL &amp; s38;
--     const SWord8  s40 = table0[s39];
--     const SWord8  s41 = s37 + s40;
--   
--     return s41;
--   }
--   == END: "popCount.c" ==================
--   </pre>
genPopCountInC :: IO ()


-- | Demonstrates the use of uninterpreted functions for the purposes of
--   code generation. This facility is important when we want to take
--   advantage of native libraries in the target platform, or when we'd
--   like to hand-generate code for certain functions for various purposes,
--   such as efficiency, or reliability.
module Documentation.SBV.Examples.CodeGeneration.Uninterpreted

-- | A definition of shiftLeft that can deal with variable length shifts.
--   (Note that the <a>`shiftL`</a> method from the <a>Bits</a> class
--   requires an <a>Int</a> shift amount.) Unfortunately, this'll generate
--   rather clumsy C code due to the use of tables etc., so we uninterpret
--   it for code generation purposes using the <a>cgUninterpret</a>
--   function.
shiftLeft :: SWord32 -> SWord32 -> SWord32

-- | Test function that uses shiftLeft defined above. When used as a normal
--   Haskell function or in verification the definition is fully used,
--   i.e., no uninterpretation happens. To wit, we have:
--   
--   <pre>
--   &gt;&gt;&gt; tstShiftLeft 3 4 5
--   224 :: SWord32
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x y -&gt; tstShiftLeft x y 0 .== x + y
--   Q.E.D.
--   </pre>
tstShiftLeft :: SWord32 -> SWord32 -> SWord32 -> SWord32

-- | Generate C code for "tstShiftLeft". In this case, SBV will *use* the
--   user given definition verbatim, instead of generating code for it.
--   (Also see the functions <a>cgAddDecl</a>, <a>cgAddLDFlags</a>, and
--   <a>cgAddPrototype</a>.)
genCCode :: IO ()


-- | An implementation of AES (Advanced Encryption Standard), using SBV.
--   For details on AES, see
--   <a>http://en.wikipedia.org/wiki/Advanced_Encryption_Standard</a>.
--   
--   We do a T-box implementation, which leads to good C code as we can
--   take advantage of look-up tables. Note that we make virtually no
--   attempt to optimize our Haskell code. The concern here is not with
--   getting Haskell running fast at all. The idea is to program the T-Box
--   implementation as naturally and clearly as possible in Haskell, and
--   have SBV's code-generator generate fast C code automatically.
--   Therefore, we merely use ordinary Haskell lists as our
--   data-structures, and do not bother with any unboxing or strictness
--   annotations. Thus, we achieve the separation of concerns: Correctness
--   via clarity and simplicity and proofs on the Haskell side, performance
--   by relying on SBV's code generator. If necessary, the generated code
--   can be FFI'd back into Haskell to complete the loop.
--   
--   All 3 valid key sizes (128, 192, and 256) as required by the FIPS-197
--   standard are supported.
module Documentation.SBV.Examples.Crypto.AES

-- | An element of the Galois Field 2^8, which are essentially polynomials
--   with maximum degree 7. They are conveniently represented as values
--   between 0 and 255.
type GF28 = SWord 8

-- | Multiplication in GF(2^8). This is simple polynomial multiplication,
--   followed by the irreducible polynomial <tt>x^8+x^4+x^3+x^1+1</tt>. We
--   simply use the <a>pMult</a> function exported by SBV to do the
--   operation.
gf28Mult :: GF28 -> GF28 -> GF28

-- | Exponentiation by a constant in GF(2^8). The implementation uses the
--   usual square-and-multiply trick to speed up the computation.
gf28Pow :: GF28 -> Int -> GF28

-- | Computing inverses in GF(2^8). By the mathematical properties of
--   GF(2^8) and the particular irreducible polynomial used
--   <tt>x^8+x^5+x^3+x^1+1</tt>, it turns out that raising to the 254 power
--   gives us the multiplicative inverse. Of course, we can prove this
--   using SBV:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x -&gt; x ./= 0 .=&gt; x `gf28Mult` gf28Inverse x .== 1
--   Q.E.D.
--   </pre>
--   
--   Note that we exclude <tt>0</tt> in our theorem, as it does not have a
--   multiplicative inverse.
gf28Inverse :: GF28 -> GF28

-- | AES state. The state consists of four 32-bit words, each of which is
--   in turn treated as four GF28's, i.e., 4 bytes. The T-Box
--   implementation keeps the four-bytes together for efficient
--   representation.
type State = [SWord 32]

-- | The key, which can be 128, 192, or 256 bits. Represented as a sequence
--   of 32-bit words.
type Key = [SWord 32]

-- | The key schedule. AES executes in rounds, and it treats first and last
--   round keys slightly differently than the middle ones. We reflect that
--   choice by being explicit about it in our type. The length of the
--   middle list of keys depends on the key-size, which in turn determines
--   the number of rounds.
type KS = (Key, [Key], Key)

-- | Rotating a state row by a fixed amount to the right.
rotR :: [GF28] -> Int -> [GF28]

-- | Definition of round-constants, as specified in Section 5.2 of the AES
--   standard.
roundConstants :: [GF28]

-- | The <tt>InvMixColumns</tt> transformation, as described in Section
--   5.3.3 of the standard. Note that this transformation is only used
--   explicitly during key-expansion in the T-Box implementation of AES.
invMixColumns :: State -> State

-- | Key expansion. Starting with the given key, returns an infinite
--   sequence of words, as described by the AES standard, Section 5.2,
--   Figure 11.
keyExpansion :: Int -> Key -> [Key]

-- | The values of the AES S-box table. Note that we describe the S-box
--   programmatically using the mathematical construction given in Section
--   5.1.1 of the standard. However, the code-generation will turn this
--   into a mere look-up table, as it is just a constant table, all
--   computation being done at "compile-time".
sboxTable :: [GF28]

-- | The sbox transformation. We simply select from the sbox table. Note
--   that we are obliged to give a default value (here <tt>0</tt>) to be
--   used if the index is out-of-bounds as required by SBV's <a>select</a>
--   function. However, that will never happen since the table has all 256
--   elements in it.
sbox :: GF28 -> GF28

-- | The values of the inverse S-box table. Again, the construction is
--   programmatic.
unSBoxTable :: [GF28]

-- | The inverse s-box transformation.
unSBox :: GF28 -> GF28

-- | Prove that the <a>sbox</a> and <a>unSBox</a> are inverses. We have:
--   
--   <pre>
--   &gt;&gt;&gt; prove sboxInverseCorrect
--   Q.E.D.
--   </pre>
sboxInverseCorrect :: GF28 -> SBool

-- | Adding the round-key to the current state. We simply exploit the fact
--   that addition is just xor in implementing this transformation.
addRoundKey :: Key -> State -> State

-- | T-box table generation function for encryption
t0Func :: GF28 -> [GF28]

-- | First look-up table used in encryption
t0 :: GF28 -> SWord 32

-- | Second look-up table used in encryption
t1 :: GF28 -> SWord 32

-- | Third look-up table used in encryption
t2 :: GF28 -> SWord 32

-- | Fourth look-up table used in encryption
t3 :: GF28 -> SWord 32

-- | T-box table generating function for decryption
u0Func :: GF28 -> [GF28]

-- | First look-up table used in decryption
u0 :: GF28 -> SWord 32

-- | Second look-up table used in decryption
u1 :: GF28 -> SWord 32

-- | Third look-up table used in decryption
u2 :: GF28 -> SWord 32

-- | Fourth look-up table used in decryption
u3 :: GF28 -> SWord 32

-- | Generic round function. Given the function to perform one round, a
--   key-schedule, and a starting state, it performs the AES rounds.
doRounds :: (Bool -> State -> Key -> State) -> KS -> State -> State

-- | One encryption round. The first argument indicates whether this is the
--   final round or not, in which case the construction is slightly
--   different.
aesRound :: Bool -> State -> Key -> State

-- | One decryption round. Similar to the encryption round, the first
--   argument indicates whether this is the final round or not.
aesInvRound :: Bool -> State -> Key -> State

-- | Key schedule. Given a 128, 192, or 256 bit key, expand it to get
--   key-schedules for encryption and decryption. The key is given as a
--   sequence of 32-bit words. (4 elements for 128-bits, 6 for 192, and 8
--   for 256.) Compare this function to <a>aesInvKeySchedule</a> which can
--   calculate the key-expansion for decryption on the fly, as opposed to
--   calculating the forward key-expansion first.
aesKeySchedule :: Key -> (KS, KS)

-- | Block encryption. The first argument is the plain-text, which must
--   have precisely 4 elements, for a total of 128-bits of input. The
--   second argument is the key-schedule to be used, obtained by a call to
--   <a>aesKeySchedule</a>. The output will always have 4 32-bit words,
--   which is the cipher-text.
aesEncrypt :: [SWord 32] -> KS -> [SWord 32]

-- | Block decryption. The arguments are the same as in <a>aesEncrypt</a>,
--   except the first argument is the cipher-text and the output is the
--   corresponding plain-text.
aesDecrypt :: [SWord 32] -> KS -> [SWord 32]

-- | Inverse key expansion. Starting from the final round key, unwinds key
--   generation operation to construct keys for the previous rounds. Used
--   in on-the-fly decryption.
invKeyExpansion :: Int -> Key -> [Key]

-- | AES inverse key schedule. Starting from the last-round key, construct
--   the sequence of keys that can be used for doing on-the-fly decryption.
--   Compare this function to <a>aesKeySchedule</a> which returns both
--   encryption and decryption schedules: In this case, we don't calculate
--   the encryption sequence, hence we can fuse this function with the
--   decryption operation.
aesInvKeySchedule :: Key -> KS

-- | Block decryption, starting from the unwound key. That is, start from
--   the final key. Also; we don't use the T-box implementation. Just pure
--   AES inverse cipher.
aesDecryptUnwoundKey :: [SWord 32] -> KS -> [SWord 32]

-- | Common plain text for test vectors
commonPT :: [SWord 32]

-- | Key for 128-bit encryption test
aes128Key :: Key

-- | Key for 192-bit encryption test
aes192Key :: Key

-- | Key for 256-bit encryption test
aes256Key :: Key

-- | Expected cipher-text for 128-bit encryption
aes128CT :: [SWord 32]

-- | Expected cipher-text for 192-bit encryption
aes192CT :: [SWord 32]

-- | Expected cipher-text for 256-bit encryption
aes256CT :: [SWord 32]

-- | Calculate the 128-bit final-round key from on-the-fly decryption key
--   schedule
aes128InvKey :: Key

-- | Calculate the 192-bit final-round key from on-the-fly decryption key
--   schedule
aes192InvKey :: Key

-- | Calculate the 192-bit final-round key from on-the-fly decryption key
--   schedule. Compare this to <a>aes192InvKey</a>: Typically we just need
--   the final 6-blocks, but it is advantageous to have the entire last
--   8-blocks even for 192-bit keys. That is, e store the final 256-bits of
--   key-expansion for speed purposes for both 192 and 256 bit versions.
--   (But only the final 128 bits for the 128-bit version.)
aes192InvKeyExtended :: Key

-- | Calculate the 256-bit final-round key from on-the-fly decryption key
--   schedule
aes256InvKey :: Key

-- | Extract the final key for on-the-fly decryption. This will extract
--   exactly the number of blocks we need.
extractFinalKey :: [SWord 32] -> [SWord 32]

-- | Extract the extended key for on-the-fly decryption. This will extract
--   4-blocks for 128-bit decryption, but 256 bit for both 192 and 256-bit
--   variants
extractFinalKeyExtended :: [SWord 32] -> [SWord 32]

-- | 128-bit encryption test, from Appendix C.1 of the AES standard:
--   
--   <pre>
--   &gt;&gt;&gt; map hex8 t128Enc
--   ["69c4e0d8","6a7b0430","d8cdb780","70b4c55a"]
--   </pre>
t128Enc :: [SWord 32]

-- | 128-bit decryption test, from Appendix C.1 of the AES standard:
--   
--   <pre>
--   &gt;&gt;&gt; map hex8 t128Dec
--   ["00112233","44556677","8899aabb","ccddeeff"]
--   </pre>
t128Dec :: [SWord 32]

-- | 192-bit encryption test, from Appendix C.2 of the AES standard:
--   
--   <pre>
--   &gt;&gt;&gt; map hex8 t192Enc
--   ["dda97ca4","864cdfe0","6eaf70a0","ec0d7191"]
--   </pre>
t192Enc :: [SWord 32]

-- | 192-bit decryption test, from Appendix C.2 of the AES standard:
--   
--   <pre>
--   &gt;&gt;&gt; map hex8 t192Dec
--   ["00112233","44556677","8899aabb","ccddeeff"]
--   </pre>
t192Dec :: [SWord 32]

-- | 256-bit encryption, from Appendix C.3 of the AES standard:
--   
--   <pre>
--   &gt;&gt;&gt; map hex8 t256Enc
--   ["8ea2b7ca","516745bf","eafc4990","4b496089"]
--   </pre>
t256Enc :: [SWord 32]

-- | 256-bit decryption, from Appendix C.3 of the AES standard:
--   
--   <pre>
--   &gt;&gt;&gt; map hex8 t256Dec
--   ["00112233","44556677","8899aabb","ccddeeff"]
--   </pre>
t256Dec :: [SWord 32]

-- | Various tests for round-trip properties. We have:
--   
--   <pre>
--   &gt;&gt;&gt; runAESTests False
--   GOOD: Key generation AES128
--   GOOD: Key generation AES192
--   GOOD: Key generation AES256
--   GOOD: Encryption     AES128
--   GOOD: Decryption     AES128
--   GOOD: Decryption-OTF AES128
--   GOOD: Encryption     AES192
--   GOOD: Decryption     AES192
--   GOOD: Decryption-OTF AES192
--   GOOD: Encryption     AES256
--   GOOD: Decryption     AES256
--   GOOD: Decryption-OTF AES256
--   </pre>
runAESTests :: Bool -> IO ()

-- | Correctness theorem for 128-bit AES. Ideally, we would run:
--   
--   <pre>
--   prove aes128IsCorrect
--   </pre>
--   
--   to get a proof automatically. Unfortunately, while SBV will
--   successfully generate the proof obligation for this theorem and ship
--   it to the SMT solver, it would be naive to expect the SMT-solver to
--   finish that proof in any reasonable time with the currently available
--   SMT solving technologies. Instead, we can issue:
--   
--   <pre>
--   quickCheck aes128IsCorrect
--   </pre>
--   
--   and get some degree of confidence in our code. Similar predicates can
--   be easily constructed for 192, and 256 bit cases as well.
aes128IsCorrect :: (SWord 32, SWord 32, SWord 32, SWord 32) -> (SWord 32, SWord 32, SWord 32, SWord 32) -> SBool

-- | Code generation for 128-bit AES encryption.
--   
--   The following sample from the generated code-lines show how T-Boxes
--   are rendered as C arrays:
--   
--   <pre>
--   static const SWord32 table1[] = {
--       0xc66363a5UL, 0xf87c7c84UL, 0xee777799UL, 0xf67b7b8dUL,
--       0xfff2f20dUL, 0xd66b6bbdUL, 0xde6f6fb1UL, 0x91c5c554UL,
--       0x60303050UL, 0x02010103UL, 0xce6767a9UL, 0x562b2b7dUL,
--       0xe7fefe19UL, 0xb5d7d762UL, 0x4dababe6UL, 0xec76769aUL,
--       ...
--       }
--   </pre>
--   
--   The generated program has 5 tables (one sbox table, and 4-Tboxes), all
--   converted to fast C arrays. Here is a sample of the generated
--   straightline C-code:
--   
--   <pre>
--   const SWord8  s1915 = (SWord8) s1912;
--   const SWord8  s1916 = table0[s1915];
--   const SWord16 s1917 = (((SWord16) s1914) &lt;&lt; 8) | ((SWord16) s1916);
--   const SWord32 s1918 = (((SWord32) s1911) &lt;&lt; 16) | ((SWord32) s1917);
--   const SWord32 s1919 = s1844 ^ s1918;
--   const SWord32 s1920 = s1903 ^ s1919;
--   </pre>
--   
--   The GNU C-compiler does a fine job of optimizing this straightline
--   code to generate a fairly efficient C implementation.
cgAES128BlockEncrypt :: IO ()

-- | Components of the AES implementation that the library is generated
--   from. For each case, we provide the driver values from the AES
--   test-vectors.
aesLibComponents :: Int -> [(String, [Integer], SBVCodeGen ())]

-- | Generate code for AES functionality; given the key size.
cgAESLibrary :: Int -> Maybe FilePath -> IO ()

-- | Generate a C library, containing functions for performing 128-bit
--   enc<i>dec</i>key-expansion. A note on performance: In a very rough
--   speed test, the generated code was able to do 6.3 million block
--   encryptions per second on a decent MacBook Pro. On the same machine,
--   OpenSSL reports 8.2 million block encryptions per second. So, the
--   generated code is about 25% slower as compared to the highly optimized
--   OpenSSL implementation. (Note that the speed test was done somewhat
--   simplistically, so these numbers should be considered very rough
--   estimates.)
cgAES128Library :: IO ()

-- | For doctest purposes only
hex8 :: (SymVal a, Show a, Integral a) => SBV a -> String

-- | Chunk in groups of 4. (This function must be in some standard library,
--   where?)
chop4 :: [a] -> [[a]]


-- | Implementation of Prince encryption and decrytion, following the spec
--   <a>https://eprint.iacr.org/2012/529.pdf</a>
module Documentation.SBV.Examples.Crypto.Prince

-- | Section 2: Prince is essentially a 64-bit cipher, with 128-bit key,
--   coming in two parts.
type Block = SWord 64

-- | Plantext is simply a block.
type PT = Block

-- | Key is again a 64-bit block.
type Key = Block

-- | Cypher text is another 64-bit block.
type CT = Block

-- | A nibble is 4-bits. Ideally, we would like to represent a nibble by
--   <tt>SWord 4</tt>; and indeed SBV can do that for verification purposes
--   just fine. Unfortunately, the SBV's C compiler doesn't support 4-bit
--   bit-vectors, as there's nothing meaningful in the C-land that we can
--   map it to. Thus, we represent a nibble with 8-bits. The top 4 bits
--   will always be 0.
type Nibble = SWord 8

-- | Expanding a key, from Section 3.4 of the spec.
expandKey :: Key -> Key

-- | expandKey(x) = x has a unique solution. We have:
--   
--   <pre>
--   &gt;&gt;&gt; prop_ExpandKey
--   Q.E.D.
--   </pre>
prop_ExpandKey :: IO ()

-- | Section 2: Encryption
encrypt :: PT -> Key -> Key -> CT

-- | Decryption
decrypt :: CT -> Key -> Key -> PT

-- | Basic prince algorithm
prince :: Block -> Key -> Key -> Key -> Block

-- | Core prince. It's essentially folding of 12 rounds stitched together:
princeCore :: Key -> Block -> Block

-- | Forward round.
round :: Key -> Block -> Int -> Block

-- | Backend round.
invRound :: Key -> Block -> Int -> Block

-- | M transformation.
m :: Block -> Block

-- | Inverse of M.
mInv :: Block -> Block

-- | SR.
sr :: Block -> Block

-- | Inverse of SR:
srInv :: Block -> Block

-- | Prove sr and srInv are inverses: We have:
--   
--   <pre>
--   &gt;&gt;&gt; prove prop_sr
--   Q.E.D.
--   </pre>
prop_sr :: Predicate

-- | M' transformation
m' :: Block -> Block

-- | The matrix as described in Section 3.3
mat :: [[Int]]

-- | Multiplication.
mMult :: Block -> Block

-- | Non-linear transformation of a block
nonLinear :: [Nibble] -> Nibble -> Block -> Block

-- | SBox transformation.
sBox :: Block -> Block

-- | Inverse SBox transformation.
sBoxInv :: Block -> Block

-- | Prove that sbox and sBoxInv are inverses: We have:
--   
--   <pre>
--   &gt;&gt;&gt; prove prop_SBox
--   Q.E.D.
--   </pre>
prop_SBox :: Predicate

-- | Round constants
rConstants :: Int -> SWord 64

-- | Round-constants property: rc_i <a>xor</a> rc_{11-i} is constant. We
--   have:
--   
--   <pre>
--   &gt;&gt;&gt; prop_RoundKeys
--   True
--   </pre>
prop_RoundKeys :: SBool

-- | Convert a 64 bit word to nibbles
toNibbles :: SWord 64 -> [Nibble]

-- | Convert from nibbles to a 64 bit word
fromNibbles :: [Nibble] -> SWord 64

-- | From Appendix A of the spec. We have:
--   
--   <pre>
--   &gt;&gt;&gt; testVectors
--   True
--   </pre>
testVectors :: SBool

-- | Nicely show a concrete block.
showBlock :: Block -> String

-- | Generating C code for the encryption block.
codeGen :: IO ()


-- | An implementation of RC4 (AKA Rivest Cipher 4 or Alleged RC4/ARC4),
--   using SBV. For information on RC4, see:
--   <a>http://en.wikipedia.org/wiki/RC4</a>.
--   
--   We make no effort to optimize the code, and instead focus on a clear
--   implementation. In fact, the RC4 algorithm relies on in-place update
--   of its state heavily for efficiency, and is therefore unsuitable for a
--   purely functional implementation.
module Documentation.SBV.Examples.Crypto.RC4

-- | RC4 State contains 256 8-bit values. We use the symbolically
--   accessible full-binary type <a>STree</a> to represent the state, since
--   RC4 needs access to the array via a symbolic index and it's important
--   to minimize access time.
type S = STree Word8 Word8

-- | Construct the fully balanced initial tree, where the leaves are simply
--   the numbers <tt>0</tt> through <tt>255</tt>.
initS :: S

-- | The key is a stream of <a>Word8</a> values.
type Key = [SWord8]

-- | Represents the current state of the RC4 stream: it is the <tt>S</tt>
--   array along with the <tt>i</tt> and <tt>j</tt> index values used by
--   the PRGA.
type RC4 = (S, SWord8, SWord8)

-- | Swaps two elements in the RC4 array.
swap :: SWord8 -> SWord8 -> S -> S

-- | Implements the PRGA used in RC4. We return the new state and the next
--   key value generated.
prga :: RC4 -> (SWord8, RC4)

-- | Constructs the state to be used by the PRGA using the given key.
initRC4 :: Key -> S

-- | The key-schedule. Note that this function returns an infinite list.
keySchedule :: Key -> [SWord8]

-- | Generate a key-schedule from a given key-string.
keyScheduleString :: String -> [SWord8]

-- | RC4 encryption. We generate key-words and xor it with the input. The
--   following test-vectors are from Wikipedia
--   <a>http://en.wikipedia.org/wiki/RC4</a>:
--   
--   <pre>
--   &gt;&gt;&gt; concatMap hex2 $ encrypt "Key" "Plaintext"
--   "bbf316e8d940af0ad3"
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; concatMap hex2 $ encrypt "Wiki" "pedia"
--   "1021bf0420"
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; concatMap hex2 $ encrypt "Secret" "Attack at dawn"
--   "45a01f645fc35b383552544b9bf5"
--   </pre>
encrypt :: String -> String -> [SWord8]

-- | RC4 decryption. Essentially the same as decryption. For the above test
--   vectors we have:
--   
--   <pre>
--   &gt;&gt;&gt; decrypt "Key" [0xbb, 0xf3, 0x16, 0xe8, 0xd9, 0x40, 0xaf, 0x0a, 0xd3]
--   "Plaintext"
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; decrypt "Wiki" [0x10, 0x21, 0xbf, 0x04, 0x20]
--   "pedia"
--   </pre>
--   
--   <pre>
--   &gt;&gt;&gt; decrypt "Secret" [0x45, 0xa0, 0x1f, 0x64, 0x5f, 0xc3, 0x5b, 0x38, 0x35, 0x52, 0x54, 0x4b, 0x9b, 0xf5]
--   "Attack at dawn"
--   </pre>
decrypt :: String -> [SWord8] -> String

-- | Prove that round-trip encryption/decryption leaves the plain-text
--   unchanged. The theorem is stated parametrically over key and
--   plain-text sizes. The expression performs the proof for a 40-bit key
--   (5 bytes) and 40-bit plaintext (again 5 bytes).
--   
--   Note that this theorem is trivial to prove, since it is essentially
--   establishing xor'in the same value twice leaves a word unchanged
--   (i.e., <tt>x <a>xor</a> y <a>xor</a> y = x</tt>). However, the proof
--   takes quite a while to complete, as it gives rise to a fairly large
--   symbolic trace.
rc4IsCorrect :: IO ThmResult

-- | For doctest purposes only
hex2 :: (SymVal a, Show a, Integral a) => SBV a -> String


-- | Implementation of SHA2 class of algorithms, closely following the spec
--   <a>http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf</a>.
--   
--   We support all variants of SHA in the spec, except for SHA1. Note that
--   this implementation is really useful for code-generation purposes from
--   SBV, as it is hard to state (or prove!) any particular properties of
--   these algorithms that is suitable for SMT solving.
module Documentation.SBV.Examples.Crypto.SHA

-- | Parameterized SHA representation, that captures all the differences
--   between variants of the algorithm. <tt>w</tt> is the word-size type.
data SHA w
SHA :: Int -> Int -> (Int, Int, Int) -> (Int, Int, Int) -> (Int, Int, Int) -> (Int, Int, Int) -> [w] -> [w] -> Int -> SHA w

-- | Section 1 : Word size we operate with
[wordSize] :: SHA w -> Int

-- | Section 1 : Block size for messages
[blockSize] :: SHA w -> Int

-- | Section 4.1.2-3 : Coefficients of the Sum0 function
[sum0Coefficients] :: SHA w -> (Int, Int, Int)

-- | Section 4.1.2-3 : Coefficients of the Sum1 function
[sum1Coefficients] :: SHA w -> (Int, Int, Int)

-- | Section 4.1.2-3 : Coefficients of the sigma0 function
[sigma0Coefficients] :: SHA w -> (Int, Int, Int)

-- | Section 4.1.2-3 : Coefficients of the sigma1 function
[sigma1Coefficients] :: SHA w -> (Int, Int, Int)

-- | Section 4.2.2-3 : Magic SHA constants
[shaConstants] :: SHA w -> [w]

-- | Section 5.3.2-6 : Initial hash value
[h0] :: SHA w -> [w]

-- | Section 6.2.2, 6.4.2: How many iterations are there in the inner loop
[shaLoopCount] :: SHA w -> Int

-- | The choose function.
ch :: Bits a => a -> a -> a -> a

-- | The majority function.
maj :: Bits a => a -> a -> a -> a

-- | The sum-0 function. We parameterize over the rotation amounts as
--   different variants of SHA use different rotation amounts.
sum0 :: Bits a => SHA w -> a -> a

-- | The sum-1 function. Again, parameterized.
sum1 :: Bits a => SHA w -> a -> a

-- | The sigma0 function. Parameterized.
sigma0 :: Bits a => SHA w -> a -> a

-- | The sigma1 function. Parameterized.
sigma1 :: Bits a => SHA w -> a -> a

-- | Parameterization for SHA224.
sha224P :: SHA (SWord 32)

-- | Parameterization for SHA256. Inherits mostly from SHA224.
sha256P :: SHA (SWord 32)

-- | Parameterization for SHA384.
sha384P :: SHA (SWord 64)

-- | Parameterization for SHA512. Inherits mostly from SHA384.
sha512P :: SHA (SWord 64)

-- | Parameterization for SHA512_224. Inherits mostly from SHA512
sha512_224P :: SHA (SWord 64)

-- | Parameterization for SHA512_256. Inherits mostly from SHA512
sha512_256P :: SHA (SWord 64)

-- | <a>Block</a> is a synonym for lists, but makes the intent clear.
newtype Block a
Block :: [a] -> Block a

-- | Prepare the message by turning it into blocks. We also check for the
--   message size requirement here. Note that this won't actually happen in
--   practice as the input length would be &gt; 2^64 (or 2^128), and you'd
--   run out of memory first!
prepareMessage :: forall w. (Num w, ByteConverter w) => SHA w -> String -> [Block w]

-- | Hash one block of message, starting from a previous hash. This
--   function corresponds to body of the for-loop in the spec. This
--   function always produces a list of length 8, corresponding to the
--   final 8 values of the <tt>H</tt>.
hashBlock :: (Num w, Bits w) => SHA w -> [w] -> Block w -> [w]

-- | Compute the hash of a given string using the specified parameterized
--   hash algorithm.
shaP :: (Num w, Bits w, ByteConverter w) => SHA w -> String -> [w]

-- | SHA224 digest.
sha224 :: String -> SWord 224

-- | SHA256 digest.
sha256 :: String -> SWord 256

-- | SHA384 digest.
sha384 :: String -> SWord 384

-- | SHA512 digest.
sha512 :: String -> SWord 512

-- | SHA512_224 digest.
sha512_224 :: String -> SWord 224

-- | SHA512_256 digest.
sha512_256 :: String -> SWord 256

-- | Collection of known answer tests for SHA. Since these tests take too
--   long during regular regression runs, we pass as an argument how many
--   to run. Increase the below number to 24 to run all tests. We have:
--   
--   <pre>
--   &gt;&gt;&gt; knownAnswerTests 1
--   True
--   </pre>
knownAnswerTests :: Int -> Bool

-- | Generate code for one block of SHA256 in action, starting from an
--   arbitrary hash value.
cgSHA256 :: IO ()

-- | Generate code for one block of SHA512 in action, starting from an
--   arbitrary hash value.
cgSHA512 :: IO ()

-- | Helper for chunking a list by given lengths and combining each chunk
--   with a function
chunkBy :: Int -> ([a] -> b) -> [a] -> [b]

-- | Nicely lay out a hash value as a string
showHash :: (Show a, Integral a, SymVal a) => SBV a -> String


-- | The encoding of the Flyspec example from the dReal web page
module Documentation.SBV.Examples.DeltaSat.DeltaSat

-- | Encode the delta-sat problem as given in
--   <a>http://dreal.github.io/</a> We have:
--   
--   <pre>
--   &gt;&gt;&gt; flyspeck
--   Unsatisfiable
--   </pre>
flyspeck :: IO SatResult


-- | This program demonstrates the use of the existentials and the QBVF
--   (quantified bit-vector solver). We generate CRC polynomials of degree
--   16 that can be used for messages of size 48-bits. The query finds all
--   such polynomials that have hamming distance is at least 4. That is, if
--   the CRC can't tell two different 48-bit messages apart, then they must
--   differ in at least 4 bits.
module Documentation.SBV.Examples.Existentials.CRCPolynomial

-- | Compute the 16 bit CRC of a 48 bit message, using the given polynomial
crc_48_16 :: SWord 48 -> SWord16 -> [SBool]

-- | Count the differing bits in the message and the corresponding CRC
diffCount :: (SWord 48, [SBool]) -> (SWord 48, [SBool]) -> SWord8

-- | Given a hamming distance value <tt>hd</tt>, <a>crcGood</a> returns
--   <tt>true</tt> if the 16 bit polynomial can distinguish all messages
--   that has at most <tt>hd</tt> different bits. Note that we express this
--   conversely: If the <tt>sent</tt> and <tt>received</tt> messages are
--   different, then it must be the case that that must differ from each
--   other (including CRCs), in more than <tt>hd</tt> bits.
crcGood :: SWord8 -> SWord16 -> SWord 48 -> SWord 48 -> SBool

-- | Generate good CRC polynomials for 48-bit words, given the hamming
--   distance <tt>hd</tt>.
genPoly :: SWord8 -> Int -> IO ()

-- | Find and display all degree 16 polynomials with hamming distance at
--   least 4, for 48 bit messages.
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; findHD4Polynomials 2
--   Polynomial #1. x^16 + x^3 + x^2 + 1
--   Polynomial #2. x^16 + x^2 + x + 1
--   Found: 2 polynomial(s).
--   </pre>
--   
--   Note that different runs can produce different results, depending on
--   the random numbers used by the solver, solver version, etc. (Also, the
--   solver will take some time to generate these results, as the
--   generation of these polynomials is rather slow.)
findHD4Polynomials :: Int -> IO ()


-- | Finding minimal natural number solutions to linear Diophantine
--   equations, using explicit quantification.
module Documentation.SBV.Examples.Existentials.Diophantine

-- | For a homogeneous problem, the solution is any linear combination of
--   the resulting vectors. For a non-homogeneous problem, the solution is
--   any linear combination of the vectors in the second component plus one
--   of the vectors in the first component.
data Solution
Homogeneous :: [[Integer]] -> Solution
NonHomogeneous :: [[Integer]] -> [[Integer]] -> Solution

-- | ldn: Solve a (L)inear (D)iophantine equation, returning minimal
--   solutions over (N)aturals. The input is given as a rows of equations,
--   with rhs values separated into a tuple. The first argument must be a
--   proxy of a natural, must be total number of columns in the system.
--   (i.e., #of variables + 1). The second parameter limits the search to
--   bound: In case there are too many solutions, you might want to limit
--   your search space.
ldn :: forall proxy n. KnownNat n => proxy n -> Maybe Int -> [([Integer], Integer)] -> IO Solution

-- | Find the basis solution. By definition, the basis has all non-trivial
--   (i.e., non-0) solutions that cannot be written as the sum of two other
--   solutions. We use the mathematically equivalent statement that a
--   solution is in the basis if it's least according to the natural
--   partial order using the ordinary less-than relation.
basis :: forall proxy n. KnownNat n => proxy n -> Maybe Int -> [[SInteger]] -> IO [[Integer]]

-- | Solve the equation:
--   
--   <pre>
--   2x + y - z = 2
--   </pre>
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; test
--   (k', 2+k, k+2k')
--   (1+k', k, k+2k')
--   </pre>
--   
--   That is, for arbitrary <tt>k</tt> and <tt>k'</tt>, we have two
--   different solutions. (An infinite family.) You can verify these
--   solutuions by substituting the values for <tt>x</tt>, <tt>y</tt> and
--   <tt>z</tt> in the above, for each choice. It's harder to see that they
--   cover all possibilities, but a moments thought reveals that is indeed
--   the case.
test :: IO Solution

-- | A puzzle: Five sailors and a monkey escape from a naufrage and reach
--   an island with coconuts. Before dawn, they gather a few of them and
--   decide to sleep first and share the next day. At night, however, one
--   of them awakes, counts the nuts, makes five parts, gives the remaining
--   nut to the monkey, saves his share away, and sleeps. All other sailors
--   do the same, one by one. When they all wake up in the morning, they
--   again make 5 shares, and give the last remaining nut to the monkey.
--   How many nuts were there at the beginning?
--   
--   We can model this as a series of diophantine equations:
--   
--   <pre>
--     x_0 = 5 x_1 + 1
--   4 x_1 = 5 x_2 + 1
--   4 x_2 = 5 x_3 + 1
--   4 x_3 = 5 x_4 + 1
--   4 x_4 = 5 x_5 + 1
--   4 x_5 = 5 x_6 + 1
--   </pre>
--   
--   We need to solve for x_0, over the naturals. If you run this program,
--   z3 takes its time (quite long!) but, it eventually computes:
--   [15621,3124,2499,1999,1599,1279,1023] as the answer.
--   
--   That is:
--   
--   <pre>
--   * There was a total of 15621 coconuts
--   * 1st sailor: 15621 = 3124*5+1, leaving 15621-3124-1 = 12496
--   * 2nd sailor: 12496 = 2499*5+1, leaving 12496-2499-1 =  9996
--   * 3rd sailor:  9996 = 1999*5+1, leaving  9996-1999-1 =  7996
--   * 4th sailor:  7996 = 1599*5+1, leaving  7996-1599-1 =  6396
--   * 5th sailor:  6396 = 1279*5+1, leaving  6396-1279-1 =  5116
--   * In the morning, they had: 5116 = 1023*5+1.
--   </pre>
--   
--   Note that this is the minimum solution, that is, we are guaranteed
--   that there's no solution with less number of coconuts. In fact, any
--   member of <tt>[15625*k-4 | k &lt;- [1..]]</tt> is a solution, i.e., so
--   are <tt>31246</tt>, <tt>46871</tt>, <tt>62496</tt>, <tt>78121</tt>,
--   etc.
--   
--   Note that we iteratively deepen our search by requesting increasing
--   number of solutions to avoid the all-sat pitfall.
sailors :: IO [Integer]
instance GHC.Show.Show Documentation.SBV.Examples.Existentials.Diophantine.Solution


-- | Demonstrates use of bounded list utilities, proving a simple mutex
--   algorithm correct up to given bounds.
module Documentation.SBV.Examples.Lists.BoundedMutex

-- | Each agent can be in one of the three states
data State

-- | Regular work
Idle :: State

-- | Intention to enter critical state
Ready :: State

-- | In the critical state
Critical :: State

-- | Symbolic version of the type <a>State</a>.
type SState = SBV State

-- | Symbolic version of the constructor <a>Critical</a>.
sCritical :: SBV State

-- | Symbolic version of the constructor <a>Ready</a>.
sReady :: SBV State

-- | Symbolic version of the constructor <a>Idle</a>.
sIdle :: SBV State

-- | A bounded mutex property holds for two sequences of state transitions,
--   if they are not in their critical section at the same time up to that
--   given bound.
mutex :: Int -> SList State -> SList State -> SBool

-- | A sequence is valid upto a bound if it starts at <a>Idle</a>, and
--   follows the mutex rules. That is:
--   
--   <ul>
--   <li>From <a>Idle</a> it can switch to <a>Ready</a> or stay
--   <a>Idle</a></li>
--   <li>From <a>Ready</a> it can switch to <a>Critical</a> if it's its
--   turn</li>
--   <li>From <a>Critical</a> it can either stay in <a>Critical</a> or go
--   back to <a>Idle</a></li>
--   </ul>
--   
--   The variable <tt>me</tt> identifies the agent id.
validSequence :: Int -> Integer -> SList Integer -> SList State -> SBool

-- | The mutex algorithm, coded implicitly as an assignment to turns. Turns
--   start at <tt>1</tt>, and at each stage is either <tt>1</tt> or
--   <tt>2</tt>; giving preference to that process. The only condition is
--   that if either process is in its critical section, then the turn value
--   stays the same. Note that this is sufficient to satisfy safety (i.e.,
--   mutual exclusion), though it does not guarantee liveness.
validTurns :: Int -> SList Integer -> SList State -> SList State -> SBool

-- | Check that we have the mutex property so long as <a>validSequence</a>
--   and <a>validTurns</a> holds; i.e., so long as both the agents and the
--   arbiter act according to the rules. The check is bounded up-to-the
--   given concrete bound; so this is an example of a
--   bounded-model-checking style proof. We have:
--   
--   <pre>
--   &gt;&gt;&gt; checkMutex 20
--   All is good!
--   </pre>
checkMutex :: Int -> IO ()

-- | Our algorithm is correct, but it is not fair. It does not guarantee
--   that a process that wants to enter its critical-section will always do
--   so eventually. Demonstrate this by trying to show a bounded trace of
--   length 10, such that the second process is ready but never transitions
--   to critical. We have:
--   
--   <pre>
--   ghci&gt; notFair 10
--   Fairness is violated at bound: 10
--   P1: [Idle,Idle,Ready,Critical,Idle,Idle,Ready,Critical,Idle,Idle]
--   P2: [Idle,Ready,Ready,Ready,Ready,Ready,Ready,Ready,Ready,Ready]
--   Ts: [1,2,1,1,1,1,1,1,1,1]
--   </pre>
--   
--   As expected, P2 gets ready but never goes critical since the arbiter
--   keeps picking P1 unfairly. (You might get a different trace depending
--   on what z3 happens to produce!)
--   
--   Exercise for the reader: Change the <a>validTurns</a> function so that
--   it alternates the turns from the previous value if neither process is
--   in critical. Show that this makes the <a>notFair</a> function below no
--   longer exhibits the issue. Is this sufficient? Concurrent programming
--   is tricky!
notFair :: Int -> IO ()
instance GHC.Classes.Eq Documentation.SBV.Examples.Lists.BoundedMutex.State
instance GHC.Classes.Ord Documentation.SBV.Examples.Lists.BoundedMutex.State
instance GHC.Show.Show Documentation.SBV.Examples.Lists.BoundedMutex.State
instance GHC.Read.Read Documentation.SBV.Examples.Lists.BoundedMutex.State
instance Data.Data.Data Documentation.SBV.Examples.Lists.BoundedMutex.State
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Lists.BoundedMutex.State
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Lists.BoundedMutex.State
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Lists.BoundedMutex.State


-- | Shows that COAT (Count-out-and-transfer) trick preserves order of
--   cards. From pg. 35 of
--   <a>http://graphics8.nytimes.com/packages/pdf/crossword/Mulcahy_Mathematical_Card_Magic-Sample2.pdf</a>:
--   
--   <i>Given a packet of n cards, COATing k cards refers to counting out
--   that many from the top into a pile, thus reversing their order, and
--   transferring those as a unit to the bottom.</i>
--   
--   We show that if you COAT 4 times where <tt>k</tt> is at least
--   <tt>n/2</tt> for a deck of size <tt>n</tt>, then the deck remains in
--   the same order.
module Documentation.SBV.Examples.Lists.CountOutAndTransfer

-- | Count-out-and-transfer (COAT): Take <tt>k</tt> cards from top, reverse
--   it, and put it at the bottom of a deck.
coat :: SymVal a => SInteger -> SList a -> SList a

-- | COAT 4 times.
fourCoat :: SymVal a => SInteger -> SList a -> SList a

-- | A deck is simply a list of integers. Note that a regular deck will
--   have distinct cards, we do not impose this in our proof. That is, the
--   proof works regardless whether we put duplicates into the deck, which
--   generalizes the theorem.
type Deck = SList Integer

-- | Key property of COATing. If you take a deck of size <tt>n</tt>, and
--   COAT it 4 times, then the deck remains in the same order. The COAT
--   factor, <tt>k</tt>, must be greater than half the size of the deck
--   size.
--   
--   Note that the proof time increases significantly with <tt>n</tt>.
--   Here's a proof for deck size of 6, for all <tt>k</tt> &gt;=
--   <tt>3</tt>.
--   
--   <pre>
--   &gt;&gt;&gt; coatCheck 6
--   Q.E.D.
--   </pre>
--   
--   It's interesting to note that one can also express this theorem by
--   making <tt>n</tt> symbolic as well. However, doing so definitely
--   requires an inductive proof, and the SMT-solver doesn't handle this
--   case out-of-the-box, running forever.
coatCheck :: Integer -> IO ThmResult


-- | Define the fibonacci sequence as an SBV symbolic list.
module Documentation.SBV.Examples.Lists.Fibonacci

-- | Compute a prefix of the fibonacci numbers. We have:
--   
--   <pre>
--   &gt;&gt;&gt; mkFibs 10
--   [1,1,2,3,5,8,13,21,34,55]
--   </pre>
mkFibs :: Int -> IO [Integer]

-- | Generate fibonacci numbers as a sequence. Note that we constrain only
--   the first 200 entries.
genFibs :: Symbolic [Integer]


-- | Demonstrates nested lists
module Documentation.SBV.Examples.Lists.Nested

-- | Simple example demonstrating the use of nested lists. We have:
--   
--   Turned off. See: <a>https://github.com/Z3Prover/z3/issues/2820</a>
--   nestedExample [[1,2,3],[4,5,6,7],[8,9,10],[11,12,13]]
nestedExample :: IO ()


-- | Demonstrates model construction with auxiliary variables. Sometimes we
--   need to introduce a variable in our problem as an existential
--   variable, but it's "internal" to the problem and we do not consider it
--   as part of the solution. Also, in an <a>allSat</a> scenario, we may
--   not care for models that only differ in these auxiliaries. SBV allows
--   designating such variables as <a>isNonModelVar</a> so we can still use
--   them like any other variable, but without considering them explicitly
--   in model construction.
module Documentation.SBV.Examples.Misc.Auxiliary

-- | A simple predicate, based on two variables <tt>x</tt> and <tt>y</tt>,
--   true when <tt>0 &lt;= x &lt;= 1</tt> and <tt>x - abs y</tt> is
--   <tt>0</tt>.
problem :: Predicate

-- | Generate all satisfying assignments for our problem. We have:
--   
--   <pre>
--   &gt;&gt;&gt; allModels
--   Solution #1:
--     x =  1 :: Integer
--     y = -1 :: Integer
--   Solution #2:
--     x = 1 :: Integer
--     y = 1 :: Integer
--   Solution #3:
--     x = 0 :: Integer
--     y = 0 :: Integer
--   Found 3 different solutions.
--   </pre>
--   
--   Note that solutions <tt>2</tt> and <tt>3</tt> share the value <tt>x =
--   1</tt>, since there are multiple values of <tt>y</tt> that make this
--   particular choice of <tt>x</tt> satisfy our constraint.
allModels :: IO AllSatResult

-- | Generate all satisfying assignments, but we first tell SBV that
--   <tt>y</tt> should not be considered as a model problem, i.e., it's
--   auxiliary. We have:
--   
--   <pre>
--   &gt;&gt;&gt; modelsWithYAux
--   Solution #1:
--     x = 1 :: Integer
--   Solution #2:
--     x = 0 :: Integer
--   Found 2 different solutions.
--   </pre>
--   
--   Note that we now have only two solutions, one for each unique value of
--   <tt>x</tt> that satisfy our constraint.
modelsWithYAux :: IO AllSatResult


-- | Demonstrates how we can add actual SMT-definitions for functions that
--   cannot otherwise be defined in SBV. Typically, these are used for
--   recursive definitions.
module Documentation.SBV.Examples.Misc.Definitions

-- | Add one to an argument
add1 :: SInteger -> SInteger

-- | Reverse run the add1 function. Note that the generated SMTLib will
--   have the function add1 itself defined. You can verify this by running
--   the below in verbose mode.
--   
--   <pre>
--   &gt;&gt;&gt; add1Example
--   Satisfiable. Model:
--     x = 4 :: Integer
--   </pre>
add1Example :: IO SatResult

-- | Sum of numbers from 0 to the given number. Since this is a recursive
--   definition, we cannot simply symbolically simulate it as it wouldn't
--   terminat. So, we use the function generation facilities to define it
--   directly in SMTLib. Note how the function itself takes a "recursive
--   version" of itself, and all recursive calls are made with this name.
sumToN :: SInteger -> SInteger

-- | Prove that sumToN works as expected.
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; sumToNExample
--   Satisfiable. Model:
--     s0 =  5 :: Integer
--     s1 = 15 :: Integer
--   </pre>
sumToNExample :: IO SatResult

-- | Coding list-length recursively. Again, we map directly to an SMTLib
--   function.
len :: SList Integer -> SInteger

-- | Calculate the length of a list, using recursive functions.
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; lenExample
--   Satisfiable. Model:
--     s0 = [1,2,3] :: [Integer]
--     s1 =       3 :: Integer
--   </pre>
lenExample :: IO SatResult

-- | A simple mutual-recursion example, from the z3 documentation. We have:
--   
--   <pre>
--   &gt;&gt;&gt; pingPong
--   Satisfiable. Model:
--     s0 = 1 :: Integer
--   </pre>
pingPong :: IO SatResult

-- | Usual way to define even-odd mutually recursively. Unfortunately,
--   while this goes through, the backend solver does not terminate on this
--   example. See <a>evenOdd2</a> for an alternative technique to handle
--   such definitions, which seems to be more solver friendly.
evenOdd :: IO SatResult

-- | Another technique to handle mutually definitions is to define the
--   functions together, and pull the results out individually. This
--   usually works better than defining the functions separately, from a
--   solver perspective.
isEvenOdd :: SInteger -> STuple Bool Bool

-- | Extract the isEven function for easier use.
isEven :: SInteger -> SBool

-- | Extract the isOdd function for easier use.
isOdd :: SInteger -> SBool

-- | We can prove 20 is even and definitely not odd, thusly:
--   
--   <pre>
--   &gt;&gt;&gt; evenOdd2
--   Satisfiable. Model:
--     s0 =    20 :: Integer
--     s1 =  True :: Bool
--     s2 = False :: Bool
--   </pre>
evenOdd2 :: IO SatResult

-- | Ackermann function, demonstrating nested recursion.
ack :: SInteger -> SInteger -> SInteger

-- | We can prove constant-folding instances of the equality <tt>ack 1 y ==
--   y + 2</tt>:
--   
--   <pre>
--   &gt;&gt;&gt; ack1y
--   Satisfiable. Model:
--     s0 = 5 :: Integer
--     s1 = 7 :: Integer
--   </pre>
--   
--   Expecting the prover to handle the general case for arbitrary
--   <tt>y</tt> is beyond the current scope of what SMT solvers do
--   out-of-the-box for the time being.
ack1y :: IO SatResult


-- | Demonstrates how enumerations can be translated to their SMT-Lib
--   counterparts, without losing any information content. Also see
--   <a>Documentation.SBV.Examples.Puzzles.U2Bridge</a> for a more detailed
--   example involving enumerations.
module Documentation.SBV.Examples.Misc.Enumerate

-- | A simple enumerated type, that we'd like to translate to SMT-Lib
--   intact; i.e., this type will not be uninterpreted but rather preserved
--   and will be just like any other symbolic type SBV provides.
--   
--   Also note that we need to have the following <tt>LANGUAGE</tt> options
--   defined: <tt>TemplateHaskell</tt>, <tt>StandaloneDeriving</tt>,
--   <tt>DeriveDataTypeable</tt>, <tt>DeriveAnyClass</tt> for this to work.
data E
A :: E
B :: E
C :: E

-- | Symbolic version of the type <a>E</a>.
type SE = SBV E

-- | Symbolic version of the constructor <a>C</a>.
sC :: SBV E

-- | Symbolic version of the constructor <a>B</a>.
sB :: SBV E

-- | Symbolic version of the constructor <a>A</a>.
sA :: SBV E

-- | Have the SMT solver enumerate the elements of the domain. We have:
--   
--   <pre>
--   &gt;&gt;&gt; elts
--   Solution #1:
--     s0 = C :: E
--   Solution #2:
--     s0 = B :: E
--   Solution #3:
--     s0 = A :: E
--   Found 3 different solutions.
--   </pre>
elts :: IO AllSatResult

-- | Shows that if we require 4 distinct elements of the type <a>E</a>, we
--   shall fail; as the domain only has three elements. We have:
--   
--   <pre>
--   &gt;&gt;&gt; four
--   Unsatisfiable
--   </pre>
four :: IO SatResult

-- | Enumerations are automatically ordered, so we can ask for the maximum
--   element. Note the use of quantification. We have:
--   
--   <pre>
--   &gt;&gt;&gt; maxE
--   Satisfiable. Model:
--     maxE = C :: E
--   </pre>
maxE :: IO SatResult

-- | Similarly, we get the minimum element. We have:
--   
--   <pre>
--   &gt;&gt;&gt; minE
--   Satisfiable. Model:
--     minE = A :: E
--   </pre>
minE :: IO SatResult
instance GHC.Classes.Eq Documentation.SBV.Examples.Misc.Enumerate.E
instance GHC.Classes.Ord Documentation.SBV.Examples.Misc.Enumerate.E
instance GHC.Show.Show Documentation.SBV.Examples.Misc.Enumerate.E
instance GHC.Read.Read Documentation.SBV.Examples.Misc.Enumerate.E
instance Data.Data.Data Documentation.SBV.Examples.Misc.Enumerate.E
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Misc.Enumerate.E
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Misc.Enumerate.E
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Misc.Enumerate.E


-- | Proves various first-order logic properties using SBV. The properties
--   we prove all come from
--   <a>https://en.wikipedia.org/wiki/First-order_logic</a>
module Documentation.SBV.Examples.Misc.FirstOrderLogic

-- | An uninterpreted sort for demo purposes, named <a>U</a>
data U

-- | Symbolic version of the type <a>U</a>.
type SU = SBV U

-- | An uninterpreted sort for demo purposes, named <a>V</a>
data V

-- | Symbolic version of the type <a>V</a>.
type SV = SBV V

-- | An enumerated type for demo purposes, named <a>E</a>
data E
A :: E
B :: E
C :: E

-- | Symbolic version of the type <a>E</a>.
type SE = SBV E

-- | Symbolic version of the constructor <a>C</a>.
sC :: SBV E

-- | Symbolic version of the constructor <a>B</a>.
sB :: SBV E

-- | Symbolic version of the constructor <a>A</a>.
sA :: SBV E

-- | Helper to turn quantified formula to a regular boolean. We can think
--   of this as quantifier elimination, hence the name <a>qe</a>.
qe :: QuantifiedBool a => a -> SBool

-- | Consider the formula &lt;math&gt;, over bit-vectors of size 8. We can
--   ask SBV to satisfy it:
--   
--   <pre>
--   &gt;&gt;&gt; sat skolemEx1
--   Satisfiable
--   </pre>
--   
--   But this isn't really illimunating. We can first skolemize, and then
--   ask to satisfy:
--   
--   <pre>
--   &gt;&gt;&gt; sat $ skolemize skolemEx1
--   Satisfiable. Model:
--     y :: Word8 -&gt; Word8
--     y x = x
--   </pre>
--   
--   which is much better We are told that we can have the witness as the
--   value given for each choice of <tt>x</tt>.
skolemEx1 :: Forall "x" Word8 -> Exists "y" Word8 -> SBool

-- | Consider the formula &lt;math&gt;, over bit-vectors of size 8. We can
--   ask SBV to satisfy it:
--   
--   <pre>
--   &gt;&gt;&gt; sat skolemEx2
--   Satisfiable
--   </pre>
--   
--   Again, we're left in the dark as to why this is satisfiable. Let's
--   skolemize first, and then call <a>sat</a> on it:
--   
--   <pre>
--   &gt;&gt;&gt; sat $ skolemize skolemEx2
--   Satisfiable. Model:
--     b :: Word8 -&gt; Word8
--     b _ = 0
--   
--     d :: Word8 -&gt; Word8 -&gt; Word8
--     d a c = a + (255 * c)
--   </pre>
--   
--   Let's see what the solver said. It suggested we should use the value
--   of <tt>0</tt> for <tt>b</tt>, regardless of the choice of <tt>a</tt>.
--   (Note how <tt>b</tt> is a function of one variable, i.e., of
--   <tt>a</tt>) And it suggested using <tt>a + (255 * c)</tt> for
--   <tt>d</tt>, for whatever we choose for <tt>a</tt> and <tt>c</tt>. Why
--   does this work? Well, given arbitrary <tt>a</tt> and <tt>c</tt>, we
--   end up with:
--   
--   <pre>
--   a + b &gt;= c + d
--   --&gt; substitute b = 0 and d = a + 255c as suggested by the solver
--   a + 0 &gt;= c + a + 255c
--   a &gt;= 256c + a
--   a &gt;= a
--   </pre>
--   
--   showing the formula is satisfiable for whatever values you pick for
--   <tt>a</tt> and <tt>c</tt>. Note that <tt>256</tt> is simply <tt>0</tt>
--   when interpreted modulo <tt>2^8</tt>. Clever!
skolemEx2 :: Forall "a" Word8 -> Exists "b" Word8 -> Forall "c" Word8 -> Exists "d" Word8 -> SBool

-- | A common proof technique to show validity is to show that the negation
--   is unsatisfiable. Note that if you want to skolemize during this
--   process, you should first <i>negate</i> and then skolemize!
--   
--   This example demonstrates the possible pitfall. The <a>skolemEx3</a>
--   function encodes &lt;math&gt; for 8-bit bitvectors; which is a valid
--   statement since <tt>x = 0</tt> acts as the witness. We can directly
--   prove this in SBV:
--   
--   <pre>
--   &gt;&gt;&gt; prove skolemEx3
--   Q.E.D.
--   </pre>
--   
--   Or, we can ask if the negation is unsatisfiable:
--   
--   <pre>
--   &gt;&gt;&gt; sat (qNot skolemEx3)
--   Unsatisfiable
--   </pre>
--   
--   If we want, we can skolemize after the negation step:
--   
--   <pre>
--   &gt;&gt;&gt; sat (skolemize (qNot skolemEx3))
--   Unsatisfiable
--   </pre>
--   
--   and get the same result. However, it would be <b>unsound</b> to
--   skolemize first and then negate:
--   
--   <pre>
--   &gt;&gt;&gt; sat (qNot (skolemize skolemEx3))
--   Satisfiable. Model:
--     x = 1 :: Word8
--   </pre>
--   
--   And that would be the incorrect conclusion that our formula is invalid
--   with a counter-example! You can see the same by doing:
--   
--   <pre>
--   &gt;&gt;&gt; prove (skolemize skolemEx3)
--   Falsifiable. Counter-example:
--     x = 1 :: Word8
--   </pre>
--   
--   So, if you want to check validity and want to also perform
--   skolemization; you should negate your formula first and then
--   skolemize, not the other way around!
skolemEx3 :: Exists "x" Word8 -> Forall "y" Word8 -> SBool

-- | If you skolemize different formulas that share the same name for their
--   existentials, then SBV will get confused and will think those
--   represent the same skolem function. This is unfortunate, but it
--   follows the requirement that uninterpreted function names should be
--   unique. In this particular case, however, since SBV creates these
--   functions, it is harder to control the internal names. In such cases,
--   use the function <a>taggedSkolemize</a> to provide a name to prefix
--   the skolem functions. As demonstrated by <a>skolemEx4</a>. We get:
--   
--   <pre>
--   &gt;&gt;&gt; skolemEx4
--   Satisfiable. Model:
--     c1_y :: Integer -&gt; Integer
--     c1_y x = x
--   
--     c2_y :: Integer -&gt; Integer
--     c2_y x = 1 + x
--   </pre>
--   
--   Note how the internal skolem functions are named according to the tag
--   given. If you use regular <a>skolemize</a> this program will
--   essentially do the wrong thing by assuming the skolem functions for
--   both predicates are the same, and will return unsat. Beware! All
--   skolem functions should be named differently in your program for your
--   deductions to be sound.
skolemEx4 :: IO SatResult

-- | Demonstrates creating a partial order. We have:
--   
--   <pre>
--   &gt;&gt;&gt; poExample
--   Q.E.D.
--   </pre>
poExample :: IO ThmResult

-- | Create a transitive relation of a simple relation and show that
--   transitive connections are respected. We have:
--   
--   <pre>
--   &gt;&gt;&gt; tcExample1
--   Q.E.D.
--   </pre>
tcExample1 :: IO ThmResult

-- | Another transitive-closure example, this time we show the transitive
--   closure is the smallest relation, i.e., doesn't have extra
--   connections. We have:
--   
--   <pre>
--   &gt;&gt;&gt; tcExample2
--   Q.E.D.
--   </pre>
tcExample2 :: IO ThmResult

-- | Demonstrates computing the transitive closure of existing relations.
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; tcExample3
--   Q.E.D.
--   </pre>
tcExample3 :: IO ThmResult
instance GHC.Classes.Eq Documentation.SBV.Examples.Misc.FirstOrderLogic.E
instance GHC.Classes.Ord Documentation.SBV.Examples.Misc.FirstOrderLogic.E
instance GHC.Show.Show Documentation.SBV.Examples.Misc.FirstOrderLogic.E
instance GHC.Read.Read Documentation.SBV.Examples.Misc.FirstOrderLogic.E
instance Data.Data.Data Documentation.SBV.Examples.Misc.FirstOrderLogic.E
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Misc.FirstOrderLogic.E
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Misc.FirstOrderLogic.E
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Misc.FirstOrderLogic.E
instance GHC.Show.Show Documentation.SBV.Examples.Misc.FirstOrderLogic.V
instance GHC.Read.Read Documentation.SBV.Examples.Misc.FirstOrderLogic.V
instance Data.Data.Data Documentation.SBV.Examples.Misc.FirstOrderLogic.V
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Misc.FirstOrderLogic.V
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Misc.FirstOrderLogic.V
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Misc.FirstOrderLogic.V
instance GHC.Show.Show Documentation.SBV.Examples.Misc.FirstOrderLogic.U
instance GHC.Read.Read Documentation.SBV.Examples.Misc.FirstOrderLogic.U
instance Data.Data.Data Documentation.SBV.Examples.Misc.FirstOrderLogic.U
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Misc.FirstOrderLogic.U
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Misc.FirstOrderLogic.U
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Misc.FirstOrderLogic.U


-- | Several examples involving IEEE-754 floating point numbers, i.e.,
--   single precision <a>Float</a> (<a>SFloat</a>), double precision
--   <a>Double</a> (<a>SDouble</a>), and the generic <a>SFloatingPoint</a>
--   <tt>eb</tt> <tt>sb</tt> type where the user can specify the exponent
--   and significand bit-widths. (Note that there is always an extra
--   sign-bit, and the value of <tt>sb</tt> includes the hidden bit.)
--   
--   Arithmetic with floating point is full of surprises; due to precision
--   issues associativity of arithmetic operations typically do not hold.
--   Also, the presence of <tt>NaN</tt> is always something to look out
--   for.
module Documentation.SBV.Examples.Misc.Floating

-- | Prove that floating point addition is not associative. For
--   illustration purposes, we will require one of the inputs to be a
--   <tt>NaN</tt>. We have:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ assocPlus (0/0)
--   Falsifiable. Counter-example:
--     s0 = 0.0 :: Float
--     s1 = 0.0 :: Float
--   </pre>
--   
--   Indeed:
--   
--   <pre>
--   &gt;&gt;&gt; let i = 0/0 :: Float
--   
--   &gt;&gt;&gt; i + (0.0 + 0.0)
--   NaN
--   
--   &gt;&gt;&gt; ((i + 0.0) + 0.0)
--   NaN
--   </pre>
--   
--   But keep in mind that <tt>NaN</tt> does not equal itself in the
--   floating point world! We have:
--   
--   <pre>
--   &gt;&gt;&gt; let nan = 0/0 :: Float in nan == nan
--   False
--   </pre>
assocPlus :: SFloat -> SFloat -> SFloat -> SBool

-- | Prove that addition is not associative, even if we ignore
--   <tt>NaN</tt>/<tt>Infinity</tt> values. To do this, we use the
--   predicate <a>fpIsPoint</a>, which is true of a floating point number
--   (<a>SFloat</a> or <a>SDouble</a>) if it is neither <tt>NaN</tt> nor
--   <tt>Infinity</tt>. (That is, it's a representable point in the
--   real-number line.)
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; assocPlusRegular
--   Falsifiable. Counter-example:
--     x =  2097149.9 :: Float
--     y =  13.999817 :: Float
--     z = -1.9998167 :: Float
--   </pre>
--   
--   Indeed, we have:
--   
--   <pre>
--   &gt;&gt;&gt; let x =  2097149.9 :: Float
--   
--   &gt;&gt;&gt; let y =  13.999817 :: Float
--   
--   &gt;&gt;&gt; let z = -1.9998167 :: Float
--   
--   &gt;&gt;&gt; x + (y + z)
--   2097162.0
--   
--   &gt;&gt;&gt; (x + y) + z
--   2097161.8
--   </pre>
--   
--   Note the difference in the results!
assocPlusRegular :: IO ThmResult

-- | Demonstrate that <tt>a+b = a</tt> does not necessarily mean <tt>b</tt>
--   is <tt>0</tt> in the floating point world, even when we disallow the
--   obvious solution when <tt>a</tt> and <tt>b</tt> are <tt>Infinity.</tt>
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; nonZeroAddition
--   Falsifiable. Counter-example:
--     a =   -7.441692e23 :: Float
--     b = -7.5039685e-27 :: Float
--   </pre>
--   
--   Indeed, we have:
--   
--   <pre>
--   &gt;&gt;&gt; let a =   -7.441692e23 :: Float
--   
--   &gt;&gt;&gt; let b = -7.5039685e-27 :: Float
--   
--   &gt;&gt;&gt; a + b == a
--   True
--   
--   &gt;&gt;&gt; b == 0
--   False
--   </pre>
nonZeroAddition :: IO ThmResult

-- | This example illustrates that <tt>a * (1/a)</tt> does not necessarily
--   equal <tt>1</tt>. Again, we protect against division by <tt>0</tt> and
--   <tt>NaN</tt>/<tt>Infinity</tt>.
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; multInverse
--   Falsifiable. Counter-example:
--     a = -5.69379e-39 :: Float
--   </pre>
--   
--   Indeed, we have:
--   
--   <pre>
--   &gt;&gt;&gt; let a = -5.69379e-39 :: Float
--   
--   &gt;&gt;&gt; a * (1/a)
--   0.99999994
--   </pre>
multInverse :: IO ThmResult

-- | One interesting aspect of floating-point is that the chosen
--   rounding-mode can effect the results of a computation if the exact
--   result cannot be precisely represented. SBV exports the functions
--   <a>fpAdd</a>, <a>fpSub</a>, <a>fpMul</a>, <a>fpDiv</a>, <a>fpFMA</a>
--   and <a>fpSqrt</a> which allows users to specify the IEEE supported
--   <a>RoundingMode</a> for the operation. This example illustrates how
--   SBV can be used to find rounding-modes where, for instance, addition
--   can produce different results. We have:
--   
--   <pre>
--   &gt;&gt;&gt; roundingAdd
--   Satisfiable. Model:
--     rm = RoundTowardZero :: RoundingMode
--     x  =  -1.0579198e-37 :: Float
--     y  =   4.7017266e-38 :: Float
--   </pre>
--   
--   (Note that depending on your version of Z3, you might get a different
--   result.) Unfortunately Haskell floats do not allow computation with
--   arbitrary rounding modes, but SBV's <a>SFloatingPoint</a> type does.
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; fpAdd sRoundTowardZero (-1.0579198e-37) (4.7017266e-38) :: SFPSingle
--   -5.87747119e-38 :: SFloatingPoint 8 24
--   
--   &gt;&gt;&gt; fpAdd sRoundNearestTiesToEven (-1.0579198e-37) (4.7017266e-38) :: SFPSingle
--   -5.87747175e-38 :: SFloatingPoint 8 24
--   </pre>
--   
--   We can see why these two results are indeed different: The
--   <a>RoundTowardZero</a> (which rounds towards zero) produces a larger
--   result, closer to 0. Indeed, if we treat these numbers as
--   <a>Double</a> values, we get:
--   
--   <pre>
--   &gt;&gt;&gt; (-1.0579198e-37) + (4.7017266e-38) :: Double
--   -5.8774714e-38
--   </pre>
--   
--   we see that the "more precise" result is larger than what the
--   <a>Float</a> value is, justifying the larger value with
--   <a>RoundTowardZero</a>. A more detailed study is beyond our current
--   scope, so we'll merely note that floating point representation and
--   semantics is indeed a thorny subject, and point to
--   <a>http://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Double/paper.pdf</a>
--   as an excellent guide.
roundingAdd :: IO SatResult

-- | Arbitrary precision floating-point numbers. SBV can talk about
--   floating point numbers with arbitrary exponent and significand sizes
--   as well. Here is a simple example demonstrating the minimum non-zero
--   positive and maximum floating point values with exponent width 5 and
--   significand width 4, which is actually 3 bits for the significand
--   explicitly stored, includes the hidden bit. We have:
--   
--   <pre>
--   &gt;&gt;&gt; fp54Bounds
--   Objective "max": Optimal model:
--     x   = 61400 :: FloatingPoint 5 4
--     max =   503 :: WordN 9
--     min =   503 :: WordN 9
--   Objective "min": Optimal model:
--     x   = 0.00000763 :: FloatingPoint 5 4
--     max =        257 :: WordN 9
--     min =        257 :: WordN 9
--   </pre>
--   
--   The careful reader will notice that the numbers <tt>61400</tt> and
--   <tt>0.00000763</tt> are quite suspicious, but the metric space
--   equivalents are correct. The reason for this is due to the sparcity of
--   floats. The "computed" value of the maximum in this bound is actually
--   <tt>61440</tt>, however in <tt>FloatingPoint 5 4</tt> representation
--   all numbers between <tt>57344</tt> and <tt>61440</tt> collapse to the
--   same bit-pattern, and the pretty-printer picks a string representation
--   in decimal that falls within range that it considers is the
--   "simplest." (Printing floats precisely is a thorny subject!) Likewise,
--   the minimum value we're looking for is actually 2^-17, but any number
--   between 2^-16 and 2^-17 will map to this number. It turns out that
--   0.00000763 in decimal is one such value. Moral of the story is that
--   when reading floating-point numbers in decimal notation one should be
--   very careful about the printed representation and the numeric value;
--   while they will match in vsalue (if there are no bugs!), they can
--   print quite differently! (Also keep in mind the rounding modes that
--   impact how the conversion is done.)
fp54Bounds :: IO OptimizeResult


-- | Demonstrates how lambda-abstractions can be used to model arrays.
module Documentation.SBV.Examples.Misc.LambdaArray

-- | Given an array, and bounds on it, initialize it within the bounds to
--   the element given. Otherwise, leave it untouched.
memset :: SArray Integer Integer -> SInteger -> SInteger -> SInteger -> SArray Integer Integer

-- | Prove a simple property: If we read from the initialized region, we
--   get the initial value. We have:
--   
--   <pre>
--   &gt;&gt;&gt; memsetExample
--   Q.E.D.
--   </pre>
memsetExample :: IO ThmResult

-- | Get an example of reading a value out of range. The value returned
--   should be out-of-range for lo/hi
--   
--   <pre>
--   &gt;&gt;&gt; outOfInit
--   Satisfiable. Model:
--     Read = 1 :: Integer
--     lo   = 0 :: Integer
--     hi   = 0 :: Integer
--     zero = 0 :: Integer
--     idx  = 1 :: Integer
--   </pre>
outOfInit :: IO SatResult


-- | Demonstrates use of programmatic model extraction. When programming
--   with SBV, we typically use <a>sat</a>/<a>allSat</a> calls to compute
--   models automatically. In more advanced uses, however, the user might
--   want to use programmable extraction features to do fancier
--   programming. We demonstrate some of these utilities here.
module Documentation.SBV.Examples.Misc.ModelExtract

-- | A simple function to generate a new integer value, that is not in the
--   given set of values. We also require the value to be non-negative
outside :: [Integer] -> IO SatResult

-- | We now use "outside" repeatedly to generate 10 integers, such that we
--   not only disallow previously generated elements, but also any value
--   that differs from previous solutions by less than 5. Here, we use the
--   <a>getModelValue</a> function. We could have also extracted the
--   dictionary via <a>getModelDictionary</a> and did fancier programming
--   as well, as necessary. We have:
--   
--   <pre>
--   &gt;&gt;&gt; genVals
--   [45,40,35,30,25,20,15,10,5,0]
--   </pre>
genVals :: IO [Integer]


-- | Demonstrates how to model nested-arrays, i.e., arrays of arrays in
--   SBV. Instead of SMTLib's nested model, in SBV we use a tuple as an
--   index, which is isomorphic to nested arrays.
module Documentation.SBV.Examples.Misc.NestedArray

-- | Model a nested array that is indexed by integers, and we store another
--   integer to integer array in each index. We have:
--   
--   <pre>
--   &gt;&gt;&gt; nestedArray
--   (0,10)
--   </pre>
nestedArray :: IO (Integer, Integer)


-- | Demonstrates how to create symbolic newtypes with the same behaviour
--   as their wrapped type.
module Documentation.SBV.Examples.Misc.Newtypes

-- | A <a>Metres</a> is a newtype wrapper around <a>Integer</a>.
newtype Metres
Metres :: Integer -> Metres

-- | Symbolic version of <a>Metres</a>.
type SMetres = SBV Metres

-- | Similarly, we can create another newtype, this time wrapping over
--   <a>Word16</a>. As an example, consider measuring the human height in
--   centimetres? The tallest person in history, Robert Wadlow, was 272 cm.
--   We don't need negative values, so <a>Word16</a> is the smallest type
--   that suits our needs.
newtype HumanHeightInCm
HumanHeightInCm :: Word16 -> HumanHeightInCm

-- | Symbolic version of <a>HumanHeightInCm</a>.
type SHumanHeightInCm = SBV HumanHeightInCm

-- | The tallest human ever was 272 cm. We can simply use <a>literal</a> to
--   lift it to the symbolic space.
tallestHumanEver :: SHumanHeightInCm

-- | Given a distance between a floor and a ceiling, we can see whether the
--   human can stand in that room. Comparison is expressed using
--   <a>sFromIntegral</a>.
ceilingHighEnoughForHuman :: SMetres -> SHumanHeightInCm -> SBool

-- | Now, suppose we want to see whether we could design a room with a
--   ceiling high enough that any human could stand in it. We have:
--   
--   <pre>
--   &gt;&gt;&gt; sat problem
--   Satisfiable. Model:
--     floorToCeiling =   3 :: Integer
--     humanheight    = 255 :: Word16
--   </pre>
problem :: Predicate
instance GHC.Classes.Ord Documentation.SBV.Examples.Misc.Newtypes.Metres
instance GHC.Classes.Eq Documentation.SBV.Examples.Misc.Newtypes.Metres
instance GHC.Enum.Enum Documentation.SBV.Examples.Misc.Newtypes.Metres
instance GHC.Num.Num Documentation.SBV.Examples.Misc.Newtypes.Metres
instance GHC.Real.Integral Documentation.SBV.Examples.Misc.Newtypes.Metres
instance GHC.Real.Real Documentation.SBV.Examples.Misc.Newtypes.Metres
instance GHC.Classes.Ord Documentation.SBV.Examples.Misc.Newtypes.HumanHeightInCm
instance GHC.Classes.Eq Documentation.SBV.Examples.Misc.Newtypes.HumanHeightInCm
instance GHC.Enum.Enum Documentation.SBV.Examples.Misc.Newtypes.HumanHeightInCm
instance GHC.Num.Num Documentation.SBV.Examples.Misc.Newtypes.HumanHeightInCm
instance GHC.Real.Integral Documentation.SBV.Examples.Misc.Newtypes.HumanHeightInCm
instance GHC.Real.Real Documentation.SBV.Examples.Misc.Newtypes.HumanHeightInCm
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Misc.Newtypes.HumanHeightInCm
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Misc.Newtypes.HumanHeightInCm
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Misc.Newtypes.Metres
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Misc.Newtypes.Metres


-- | Demonstrates SBV's assertion checking facilities
module Documentation.SBV.Examples.Misc.NoDiv0

-- | A simple variant of division, where we explicitly require the caller
--   to make sure the divisor is not 0.
checkedDiv :: (?loc :: CallStack) => SInt32 -> SInt32 -> SInt32

-- | Check whether an arbitrary call to <a>checkedDiv</a> is safe. Clearly,
--   we do not expect this to be safe:
--   
--   <pre>
--   &gt;&gt;&gt; test1
--   [./Documentation/SBV/Examples/Misc/NoDiv0.hs:38:14:checkedDiv: Divisor should not be 0: Violated. Model:
--     s0 = 0 :: Int32
--     s1 = 0 :: Int32]
--   </pre>
test1 :: IO [SafeResult]

-- | Repeat the test, except this time we explicitly protect against the
--   bad case. We have:
--   
--   <pre>
--   &gt;&gt;&gt; test2
--   [./Documentation/SBV/Examples/Misc/NoDiv0.hs:46:41:checkedDiv: Divisor should not be 0: No violations detected]
--   </pre>
test2 :: IO [SafeResult]


-- | Simple usage of polynomials over GF(2^n), using Rijndael's finite
--   field:
--   <a>http://en.wikipedia.org/wiki/Finite_field_arithmetic#Rijndael.27s_finite_field</a>
--   
--   The functions available are:
--   
--   <ul>
--   <li><i><i>pMult</i></i> GF(2^n) Multiplication</li>
--   <li><i><i>pDiv</i></i> GF(2^n) Division</li>
--   <li><i><i>pMod</i></i> GF(2^n) Modulus</li>
--   <li><i><i>pDivMod</i></i> GF(2^n) Division/Modulus, packed
--   together</li>
--   </ul>
--   
--   Note that addition in GF(2^n) is simply <a>xor</a>, so no custom
--   function is provided.
module Documentation.SBV.Examples.Misc.Polynomials

-- | Helper synonym for representing GF(2^8); which are merely 8-bit
--   unsigned words. Largest term in such a polynomial has degree 7.
type GF28 = SWord8

-- | Multiplication in Rijndael's field; usual polynomial multiplication
--   followed by reduction by the irreducible polynomial. The irreducible
--   used by Rijndael's field is the polynomial <tt>x^8 + x^4 + x^3 + x +
--   1</tt>, which we write by giving it's <i>exponents</i> in SBV. See:
--   <a>http://en.wikipedia.org/wiki/Finite_field_arithmetic#Rijndael.27s_finite_field</a>.
--   Note that the irreducible itself is not in GF28! It has a degree of 8.
--   
--   NB. You can use the <a>showPoly</a> function to print polynomials
--   nicely, as a mathematician would write.
gfMult :: GF28 -> GF28 -> GF28

-- | States that the unit polynomial <tt>1</tt>, is the unit element
multUnit :: GF28 -> SBool

-- | States that multiplication is commutative
multComm :: GF28 -> GF28 -> SBool

-- | States that multiplication is associative, note that associativity
--   proofs are notoriously hard for SAT/SMT solvers
multAssoc :: GF28 -> GF28 -> GF28 -> SBool

-- | States that the usual multiplication rule holds over GF(2^n)
--   polynomials Checks:
--   
--   <pre>
--   if (a, b) = x <a>pDivMod</a> y then x = y <a>pMult</a> a + b
--   </pre>
--   
--   being careful about <tt>y = 0</tt>. When divisor is 0, then quotient
--   is defined to be 0 and the remainder is the numerator. (Note that
--   addition is simply <a>xor</a> in GF(2^8).)
polyDivMod :: GF28 -> GF28 -> SBool

-- | Queries
testGF28 :: IO ()


-- | Proves various algebraic properties of sets using SBV. The properties
--   we prove all come from
--   <a>http://en.wikipedia.org/wiki/Algebra_of_sets</a>.
module Documentation.SBV.Examples.Misc.SetAlgebra

-- | Abbreviation for set of integers. For convenience only in
--   monomorphising the properties.
type SI = SSet Integer


-- | Demonstrates soft-constraints, i.e., those that the solver is free to
--   leave unsatisfied. Solvers will try to satisfy this constraint, unless
--   it is impossible to do so to get a model. Can be good in modeling
--   default values, for instance.
module Documentation.SBV.Examples.Misc.SoftConstrain

-- | Create two strings, requiring one to be a particular value,
--   constraining the other to be different than another constant string.
--   But also add soft constraints to indicate our preferences for each of
--   these variables. We get:
--   
--   <pre>
--   &gt;&gt;&gt; example
--   Satisfiable. Model:
--     x = "x-must-really-be-hello" :: String
--     y =        "default-y-value" :: String
--   </pre>
--   
--   Note how the value of <tt>x</tt> is constrained properly and thus the
--   default value doesn't kick in, but <tt>y</tt> takes the default value
--   since it is acceptable by all the other hard constraints.
example :: IO SatResult


-- | A basic tuple use case, also demonstrating regular expressions,
--   strings, etc. This is a basic template for getting SBV to produce
--   valid data for applications that require inputs that satisfy arbitrary
--   criteria.
module Documentation.SBV.Examples.Misc.Tuple

-- | A dictionary is a list of lookup values. Note that we store the type
--   <tt>[(a, b)]</tt> as a symbolic value here, mixing sequences and
--   tuples.
type Dict a b = SBV [(a, b)]

-- | Create a dictionary of length 5, such that each element has an string
--   key and each value is the length of the key. We impose a few more
--   constraints to make the output interesting. For instance, you might
--   get:
--   
--   <pre>
--   ghci&gt; example
--   [("nt_",3),("dHAk",4),("kzkk0",5),("mZxs9s",6),("c32'dPM",7)]
--   </pre>
--   
--   Depending on your version of z3, a different answer might be provided.
--   Here, we check that it satisfies our length conditions:
--   
--   <pre>
--   &gt;&gt;&gt; import Data.List (genericLength)
--   
--   &gt;&gt;&gt; example &gt;&gt;= \ex -&gt; return (length ex == 5 &amp;&amp; all (\(l, i) -&gt; genericLength l == i) ex)
--   True
--   </pre>
example :: IO [(String, Integer)]


-- | Demonstrates how enumerations can be used with optimization, by
--   properly defining your metric values.
module Documentation.SBV.Examples.Optimization.Enumerate

-- | A simple enumeration
data Day
Mon :: Day
Tue :: Day
Wed :: Day
Thu :: Day
Fri :: Day
Sat :: Day
Sun :: Day

-- | Symbolic version of the type <a>Day</a>.
type SDay = SBV Day

-- | Symbolic version of the constructor <a>Sun</a>.
sSun :: SBV Day

-- | Symbolic version of the constructor <a>Sat</a>.
sSat :: SBV Day

-- | Symbolic version of the constructor <a>Fri</a>.
sFri :: SBV Day

-- | Symbolic version of the constructor <a>Thu</a>.
sThu :: SBV Day

-- | Symbolic version of the constructor <a>Wed</a>.
sWed :: SBV Day

-- | Symbolic version of the constructor <a>Tue</a>.
sTue :: SBV Day

-- | Symbolic version of the constructor <a>Mon</a>.
sMon :: SBV Day

-- | Identify weekend days
isWeekend :: SDay -> SBool

-- | Using optimization, find the latest day that is not a weekend. We
--   have:
--   
--   <pre>
--   &gt;&gt;&gt; almostWeekend
--   Optimal model:
--     almostWeekend = Fri :: Day
--     last-day      =   4 :: Word8
--   </pre>
almostWeekend :: IO OptimizeResult

-- | Using optimization, find the first day after the weekend. We have:
--   
--   <pre>
--   &gt;&gt;&gt; weekendJustOver
--   Optimal model:
--     weekendJustOver = Mon :: Day
--     first-day       =   0 :: Word8
--   </pre>
weekendJustOver :: IO OptimizeResult

-- | Using optimization, find the first weekend day: We have:
--   
--   <pre>
--   &gt;&gt;&gt; firstWeekend
--   Optimal model:
--     firstWeekend  = Sat :: Day
--     first-weekend =   5 :: Word8
--   </pre>
firstWeekend :: IO OptimizeResult
instance GHC.Classes.Eq Documentation.SBV.Examples.Optimization.Enumerate.Day
instance GHC.Classes.Ord Documentation.SBV.Examples.Optimization.Enumerate.Day
instance GHC.Show.Show Documentation.SBV.Examples.Optimization.Enumerate.Day
instance GHC.Read.Read Documentation.SBV.Examples.Optimization.Enumerate.Day
instance Data.Data.Data Documentation.SBV.Examples.Optimization.Enumerate.Day
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Optimization.Enumerate.Day
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Optimization.Enumerate.Day
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Optimization.Enumerate.Day
instance Data.SBV.Core.Model.Metric Documentation.SBV.Examples.Optimization.Enumerate.Day


-- | Demonstrates the extension field (<tt>oo</tt>/<tt>epsilon</tt>)
--   optimization results.
module Documentation.SBV.Examples.Optimization.ExtField

-- | Optimization goals where min/max values might require assignments to
--   values that are infinite (integer case), or infinite/epsilon (real
--   case). This simple example demonstrates how SBV can be used to extract
--   such values.
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; optimize Independent problem
--   Objective "one-x": Optimal in an extension field:
--     one-x =  oo :: Integer
--     min_y = 7.0 :: Real
--     min_z = 5.0 :: Real
--   Objective "min_y": Optimal in an extension field:
--     one-x =  oo :: Integer
--     min_y = 7.0 :: Real
--     min_z = 5.0 :: Real
--   Objective "min_z": Optimal in an extension field:
--     one-x =  oo :: Integer
--     min_y = 7.0 :: Real
--     min_z = 5.0 :: Real
--   </pre>
problem :: ConstraintSet


-- | Simple linear optimization example, as found in operations research
--   texts.
module Documentation.SBV.Examples.Optimization.LinearOpt

-- | Taken from
--   <a>http://people.brunel.ac.uk/~mastjjb/jeb/or/morelp.html</a>
--   
--   <ul>
--   <li>maximize 5x1 + 6x2</li>
--   <li>subject to<ol><li>x1 + x2 &lt;= 10</li><li>x1 - x2 &gt;=
--   3</li><li>5x1 + 4x2 &lt;= 35</li><li>x1 &gt;= 0</li><li>x2 &gt;=
--   0</li></ol></li>
--   </ul>
--   
--   <pre>
--   &gt;&gt;&gt; optimize Lexicographic problem
--   Optimal model:
--     x1   =  47 % 9 :: Real
--     x2   =  20 % 9 :: Real
--     goal = 355 % 9 :: Real
--   </pre>
problem :: ConstraintSet


-- | Solves a simple linear optimization problem
module Documentation.SBV.Examples.Optimization.Production

-- | Taken from
--   <a>http://people.brunel.ac.uk/~mastjjb/jeb/or/morelp.html</a>
--   
--   A company makes two products (X and Y) using two machines (A and B).
--   
--   <ul>
--   <li>Each unit of X that is produced requires 50 minutes processing
--   time on machine A and 30 minutes processing time on machine B.</li>
--   <li>Each unit of Y that is produced requires 24 minutes processing
--   time on machine A and 33 minutes processing time on machine B.</li>
--   <li>At the start of the current week there are 30 units of X and 90
--   units of Y in stock. Available processing time on machine A is
--   forecast to be 40 hours and on machine B is forecast to be 35
--   hours.</li>
--   <li>The demand for X in the current week is forecast to be 75 units
--   and for Y is forecast to be 95 units.</li>
--   <li>Company policy is to maximise the combined sum of the units of X
--   and the units of Y in stock at the end of the week.</li>
--   </ul>
--   
--   How much of each product should we make in the current week?
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; optimize Lexicographic production
--   Optimal model:
--     X     = 45 :: Integer
--     Y     =  6 :: Integer
--     stock =  1 :: Integer
--   </pre>
--   
--   That is, we should produce 45 X's and 6 Y's, with the final maximum
--   stock of just 1 expected!
production :: ConstraintSet


-- | Solves a VM allocation problem using optimization features
module Documentation.SBV.Examples.Optimization.VM

-- | Computer allocation problem:
--   
--   <ul>
--   <li>We have three virtual machines (VMs) which require 100, 50 and 15
--   GB hard disk respectively.</li>
--   <li>There are three servers with capabilities 100, 75 and 200 GB in
--   that order.</li>
--   <li>Find out a way to place VMs into servers in order
--   to<ul><li>Minimize the number of servers used</li><li>Minimize the
--   operation cost (the servers have fixed daily costs 10, 5 and 20 USD
--   respectively.)</li></ul></li>
--   </ul>
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; optimize Lexicographic allocate
--   Optimal model:
--     x11         = False :: Bool
--     x12         = False :: Bool
--     x13         =  True :: Bool
--     x21         = False :: Bool
--     x22         = False :: Bool
--     x23         =  True :: Bool
--     x31         = False :: Bool
--     x32         = False :: Bool
--     x33         =  True :: Bool
--     noOfServers =     1 :: Integer
--     cost        =    20 :: Integer
--   </pre>
--   
--   That is, we should put all the jobs on the third server, for a total
--   cost of 20.
allocate :: ConstraintSet


-- | A BMC example, showing how traditional state-transition reachability
--   problems can be coded using SBV, using bounded model checking.
--   
--   We imagine a system with two integer variables, <tt>x</tt> and
--   <tt>y</tt>. At each iteration, we can either increment <tt>x</tt> by
--   <tt>2</tt>, or decrement <tt>y</tt> by <tt>4</tt>.
--   
--   Can we reach a state where <tt>x</tt> and <tt>y</tt> are the same
--   starting from <tt>x=0</tt> and <tt>y=10</tt>?
--   
--   What if <tt>y</tt> starts at <tt>11</tt>?
module Documentation.SBV.Examples.ProofTools.BMC

-- | System state, containing the two integers.
data S a
S :: a -> a -> S a
[x] :: S a -> a
[y] :: S a -> a

-- | We parameterize over the initial state for different variations.
problem :: Int -> (S SInteger -> SBool) -> IO (Either String (Int, [S Integer]))

-- | Example 1: We start from <tt>x=0</tt>, <tt>y=10</tt>, and search up to
--   depth <tt>10</tt>. We have:
--   
--   <pre>
--   &gt;&gt;&gt; ex1
--   BMC: Iteration: 0
--   BMC: Iteration: 1
--   BMC: Iteration: 2
--   BMC: Iteration: 3
--   BMC: Solution found at iteration 3
--   Right (3,[(0,10),(0,6),(0,2),(2,2)])
--   </pre>
--   
--   As expected, there's a solution in this case. Furthermore, since the
--   BMC engine found a solution at depth <tt>3</tt>, we also know that
--   there is no solution at depths <tt>0</tt>, <tt>1</tt>, or <tt>2</tt>;
--   i.e., this is "a" shortest solution. (That is, it may not be unique,
--   but there isn't a shorter sequence to get us to our goal.)
ex1 :: IO (Either String (Int, [S Integer]))

-- | Example 2: We start from <tt>x=0</tt>, <tt>y=11</tt>, and search up to
--   depth <tt>10</tt>. We have:
--   
--   <pre>
--   &gt;&gt;&gt; ex2
--   BMC: Iteration: 0
--   BMC: Iteration: 1
--   BMC: Iteration: 2
--   BMC: Iteration: 3
--   BMC: Iteration: 4
--   BMC: Iteration: 5
--   BMC: Iteration: 6
--   BMC: Iteration: 7
--   BMC: Iteration: 8
--   BMC: Iteration: 9
--   Left "BMC limit of 10 reached"
--   </pre>
--   
--   As expected, there's no solution in this case. While SBV (and BMC)
--   cannot establish that there is no solution at a larger depth, you can
--   see that this will never be the case: In each step we do not change
--   the parity of either variable. That is, <tt>x</tt> will remain even,
--   and <tt>y</tt> will remain odd. So, there will never be a solution at
--   any depth. This isn't the only way to see this result of course, but
--   the point remains that BMC is just not capable of establishing
--   inductive facts.
ex2 :: IO (Either String (Int, [S Integer]))
instance Data.Traversable.Traversable Documentation.SBV.Examples.ProofTools.BMC.S
instance Data.Foldable.Foldable Documentation.SBV.Examples.ProofTools.BMC.S
instance GHC.Base.Functor Documentation.SBV.Examples.ProofTools.BMC.S
instance GHC.Show.Show a => GHC.Show.Show (Documentation.SBV.Examples.ProofTools.BMC.S a)
instance Data.SBV.Core.Data.EqSymbolic a => Data.SBV.Core.Data.EqSymbolic (Documentation.SBV.Examples.ProofTools.BMC.S a)
instance Data.SBV.Core.Symbolic.Fresh GHC.Types.IO (Documentation.SBV.Examples.ProofTools.BMC.S Data.SBV.Core.Data.SInteger)


-- | Example inductive proof to show partial correctness of the for-loop
--   based fibonacci algorithm:
--   
--   <pre>
--   i = 0
--   k = 1
--   m = 0
--   while i &lt; n:
--      m, k = k, m + k
--      i++
--   </pre>
--   
--   We do the proof against an axiomatized fibonacci implementation using
--   an uninterpreted function.
module Documentation.SBV.Examples.ProofTools.Fibonacci

-- | System state. We simply have two components, parameterized over the
--   type so we can put in both concrete and symbolic values.
data S a
S :: a -> a -> a -> a -> S a
[i] :: S a -> a
[k] :: S a -> a
[m] :: S a -> a
[n] :: S a -> a

-- | Encoding partial correctness of the sum algorithm. We have:
--   
--   <pre>
--   &gt;&gt;&gt; fibCorrect
--   Q.E.D.
--   </pre>
--   
--   NB. In my experiments, I found that this proof is quite fragile due to
--   the use of quantifiers: If you make a mistake in your algorithm or the
--   coding, z3 pretty much spins forever without finding a
--   counter-example. However, with the correct coding, the proof is almost
--   instantaneous!
fibCorrect :: IO (InductionResult (S Integer))
instance Data.Traversable.Traversable Documentation.SBV.Examples.ProofTools.Fibonacci.S
instance Data.Foldable.Foldable Documentation.SBV.Examples.ProofTools.Fibonacci.S
instance GHC.Base.Functor Documentation.SBV.Examples.ProofTools.Fibonacci.S
instance GHC.Generics.Generic (Documentation.SBV.Examples.ProofTools.Fibonacci.S a)
instance Data.SBV.Core.Model.Mergeable a => Data.SBV.Core.Model.Mergeable (Documentation.SBV.Examples.ProofTools.Fibonacci.S a)
instance GHC.Show.Show a => GHC.Show.Show (Documentation.SBV.Examples.ProofTools.Fibonacci.S a)
instance Data.SBV.Core.Symbolic.Fresh GHC.Types.IO (Documentation.SBV.Examples.ProofTools.Fibonacci.S Data.SBV.Core.Data.SInteger)


-- | An example showing how traditional state-transition invariance
--   problems can be coded using SBV, using induction. We also demonstrate
--   the use of invariant strengthening.
--   
--   This example comes from Bradley's <a>Understanding IC3</a> paper,
--   which considers the following two programs:
--   
--   <pre>
--   x, y := 1, 1                    x, y := 1, 1
--   while *:                        while *:
--     x, y := x+1, y+x                x, y := x+y, y+x
--   </pre>
--   
--   Where <tt>*</tt> stands for non-deterministic choice. For each program
--   we try to prove that <tt>y &gt;= 1</tt> is an invariant.
--   
--   It turns out that the property <tt>y &gt;= 1</tt> is indeed an
--   invariant, but is not inductive for either program. We proceed to
--   strengten the invariant and establish it for the first case. We then
--   note that the same strengthening doesn't work for the second program,
--   and find a further strengthening to establish that case as well. This
--   example follows the introductory example in Bradley's paper quite
--   closely.
module Documentation.SBV.Examples.ProofTools.Strengthen

-- | System state. We simply have two components, parameterized over the
--   type so we can put in both concrete and symbolic values.
data S a
S :: a -> a -> S a
[x] :: S a -> a
[y] :: S a -> a

-- | We parameterize over the transition relation and the strengthenings to
--   investigate various combinations.
problem :: (S SInteger -> [S SInteger]) -> [(String, S SInteger -> SBool)] -> IO (InductionResult (S Integer))

-- | The first program, coded as a transition relation:
pgm1 :: S SInteger -> [S SInteger]

-- | The second program, coded as a transition relation:
pgm2 :: S SInteger -> [S SInteger]

-- | Example 1: First program, with no strengthenings. We have:
--   
--   <pre>
--   &gt;&gt;&gt; ex1
--   Failed while establishing consecution.
--   Counter-example to inductiveness:
--     S {x = -1, y = 1}
--   </pre>
ex1 :: IO (InductionResult (S Integer))

-- | Example 2: First program, strengthened with <tt>x &gt;= 0</tt>. We
--   have:
--   
--   <pre>
--   &gt;&gt;&gt; ex2
--   Q.E.D.
--   </pre>
ex2 :: IO (InductionResult (S Integer))

-- | Example 3: Second program, with no strengthenings. We have:
--   
--   <pre>
--   &gt;&gt;&gt; ex3
--   Failed while establishing consecution.
--   Counter-example to inductiveness:
--     S {x = -1, y = 1}
--   </pre>
ex3 :: IO (InductionResult (S Integer))

-- | Example 4: Second program, strengthened with <tt>x &gt;= 0</tt>. We
--   have:
--   
--   <pre>
--   &gt;&gt;&gt; ex4
--   Failed while establishing consecution for strengthening "x &gt;= 0".
--   Counter-example to inductiveness:
--     S {x = 0, y = -1}
--   </pre>
ex4 :: IO (InductionResult (S Integer))

-- | Example 5: Second program, strengthened with <tt>x &gt;= 0</tt> and
--   <tt>y &gt;= 1</tt> separately. We have:
--   
--   <pre>
--   &gt;&gt;&gt; ex5
--   Failed while establishing consecution for strengthening "x &gt;= 0".
--   Counter-example to inductiveness:
--     S {x = 0, y = -1}
--   </pre>
--   
--   Note how this was sufficient in <a>ex2</a> to establish the invariant
--   for the first program, but fails for the second.
ex5 :: IO (InductionResult (S Integer))

-- | Example 6: Second program, strengthened with <tt>x &gt;= 0 /\ y &gt;=
--   1</tt> simultaneously. We have:
--   
--   <pre>
--   &gt;&gt;&gt; ex6
--   Q.E.D.
--   </pre>
--   
--   Compare this to <a>ex5</a>. As pointed out by Bradley, this shows that
--   <i>a conjunction of assertions can be inductive when none of its
--   components, on its own, is inductive.</i> It remains an art to find
--   proper loop invariants, though the science is improving!
ex6 :: IO (InductionResult (S Integer))
instance Data.Traversable.Traversable Documentation.SBV.Examples.ProofTools.Strengthen.S
instance Data.Foldable.Foldable Documentation.SBV.Examples.ProofTools.Strengthen.S
instance GHC.Base.Functor Documentation.SBV.Examples.ProofTools.Strengthen.S
instance GHC.Show.Show a => GHC.Show.Show (Documentation.SBV.Examples.ProofTools.Strengthen.S a)
instance Data.SBV.Core.Symbolic.Fresh GHC.Types.IO (Documentation.SBV.Examples.ProofTools.Strengthen.S Data.SBV.Core.Data.SInteger)


-- | Example inductive proof to show partial correctness of the traditional
--   for-loop sum algorithm:
--   
--   <pre>
--   s = 0
--   i = 0
--   while i &lt;= n:
--      s += i
--      i++
--   </pre>
--   
--   We prove the loop invariant and establish partial correctness that
--   <tt>s</tt> is the sum of all numbers up to and including <tt>n</tt>
--   upon termination.
module Documentation.SBV.Examples.ProofTools.Sum

-- | System state. We simply have two components, parameterized over the
--   type so we can put in both concrete and symbolic values.
data S a
S :: a -> a -> a -> S a
[s] :: S a -> a
[i] :: S a -> a
[n] :: S a -> a

-- | Encoding partial correctness of the sum algorithm. We have:
--   
--   <pre>
--   &gt;&gt;&gt; sumCorrect
--   Q.E.D.
--   </pre>
sumCorrect :: IO (InductionResult (S Integer))
instance Data.Traversable.Traversable Documentation.SBV.Examples.ProofTools.Sum.S
instance Data.Foldable.Foldable Documentation.SBV.Examples.ProofTools.Sum.S
instance GHC.Base.Functor Documentation.SBV.Examples.ProofTools.Sum.S
instance GHC.Generics.Generic (Documentation.SBV.Examples.ProofTools.Sum.S a)
instance Data.SBV.Core.Model.Mergeable a => Data.SBV.Core.Model.Mergeable (Documentation.SBV.Examples.ProofTools.Sum.S a)
instance GHC.Show.Show a => GHC.Show.Show (Documentation.SBV.Examples.ProofTools.Sum.S a)
instance Data.SBV.Core.Symbolic.Fresh GHC.Types.IO (Documentation.SBV.Examples.ProofTools.Sum.S Data.SBV.Core.Data.SInteger)


-- | A solution to the advent-of-code problem, 2021, day 24:
--   <a>http://adventofcode.com/2021/day/24</a>.
--   
--   Here is a high-level summary: We are essentially modeling the ALU of a
--   fictional computer with 4 integer registers (w, x, y, z), and 6
--   instructions (inp, add, mul, div, mod, eql). You are given a program
--   (hilariously called "monad"), and your goal is to figure out what the
--   maximum and minimum inputs you can provide to this program such that
--   when it runs register z ends up with the value 1. Please refer to the
--   above link for the full description.
--   
--   While there are multiple ways to solve this problem in SBV, the
--   solution here demonstrates how to turn programs in this fictional
--   language into actual Haskell/SBV programs, i.e., developing a little
--   EDSL (embedded domain-specific language) for it. Hopefully this should
--   provide a template for other similar programs.
module Documentation.SBV.Examples.Puzzles.AOC_2021_24

-- | A Register in the machine, identified by its name.
type Register = String

-- | We operate on 64-bit signed integers. It is also possible to use the
--   unbounded integers here as the problem description doesn't mention any
--   size limitations. But performance isn't as good with unbounded
--   integers, and 64-bit signed bit-vectors seem to fit the bill just
--   fine, much like any other modern processor these days.
type Value = SInt64

-- | An item of data to be processed. We can either be referring to a named
--   register, or an immediate value.
data Data
Reg :: Register -> Data
[register] :: Data -> Register
Imm :: Int64 -> Data

-- | Shorthand for the <tt>w</tt> register.
w :: Data

-- | Shorthand for the <tt>x</tt> register.
x :: Data

-- | Shorthand for the <tt>y</tt> register.
y :: Data

-- | Shorthand for the <tt>z</tt> register.
z :: Data

-- | The state of the machine. We keep track of the data values, along with
--   the input parameters.
data State
State :: Map Register Value -> [Value] -> State

-- | Values of registers
[env] :: State -> Map Register Value

-- | Input parameters, stored in reverse.
[inputs] :: State -> [Value]

-- | The ALU is simply a state transformer, manipulating the state, wrapped
--   around SBV's <a>Symbolic</a> monad.
type ALU = StateT State Symbolic

-- | Reading a value. For a register, we simply look it up in the
--   environment. For an immediate, we simply return it.
read :: Data -> ALU Value

-- | Writing a value. We update the registers.
write :: Data -> Value -> ALU ()

-- | Reading an input value. In this version, we simply write a free
--   symbolic value to the specified register, and keep track of the inputs
--   explicitly.
inp :: Data -> ALU ()

-- | Addition.
add :: Data -> Data -> ALU ()

-- | Multiplication.
mul :: Data -> Data -> ALU ()

-- | Division.
div :: Data -> Data -> ALU ()

-- | Modulus.
mod :: Data -> Data -> ALU ()

-- | Equality.
eql :: Data -> Data -> ALU ()

-- | Run a given program, returning the final state. We simply start with
--   the initial environment mapping all registers to zero, as specified in
--   the problem specification.
run :: ALU () -> Symbolic State

-- | We simply run the <a>monad</a> program, and specify the constraints at
--   the end. We take a boolean as a parameter, choosing whether we want to
--   minimize or maximize the model-number. Note that this test takes
--   rather long to run. We get:
--   
--   <pre>
--   ghci&gt; puzzle True
--   Optimal model:
--     Maximum model number = 96918996924991 :: Int64
--   ghci&gt; puzzle False
--   Optimal model:
--     Minimum model number = 91811241911641 :: Int64
--   </pre>
puzzle :: Bool -> IO ()

-- | The program we need to crack. Note that different users get different
--   programs on the Advent-Of-Code site, so this is simply one example.
--   You can simply cut-and-paste your version instead. (Don't forget the
--   pragma <tt>NegativeLiterals</tt> to GHC so <tt>add x -1</tt> parses
--   correctly as <tt>add x (-1)</tt>.)
monad :: ALU ()
instance GHC.Num.Num Documentation.SBV.Examples.Puzzles.AOC_2021_24.Data


-- | This is a formalization of the Cheryl's birthday problem, which went
--   viral in April 2015. (See
--   <a>http://www.nytimes.com/2015/04/15/science/a-math-problem-from-singapore-goes-viral-when-is-cheryls-birthday.html</a>.)
--   
--   Here's the puzzle:
--   
--   <pre>
--   Albert and Bernard just met Cheryl. "When’s your birthday?" Albert asked Cheryl.
--   
--   Cheryl thought a second and said, "I’m not going to tell you, but I’ll give you some clues." She wrote down a list of 10 dates:
--   
--     May 15, May 16, May 19
--     June 17, June 18
--     July 14, July 16
--     August 14, August 15, August 17
--   
--   "My birthday is one of these," she said.
--   
--   Then Cheryl whispered in Albert’s ear the month — and only the month — of her birthday. To Bernard, she whispered the day, and only the day. 
--   “Can you figure it out now?” she asked Albert.
--   
--   Albert: I don’t know when your birthday is, but I know Bernard doesn’t know, either.
--   Bernard: I didn’t know originally, but now I do.
--   Albert: Well, now I know, too!
--   
--   When is Cheryl’s birthday?
--   </pre>
--   
--   NB. Thanks to Amit Goel for suggesting the formalization strategy used
--   in here.
module Documentation.SBV.Examples.Puzzles.Birthday

-- | Months. We only put in the months involved in the puzzle for
--   simplicity
data Month
May :: Month
Jun :: Month
Jul :: Month
Aug :: Month

-- | Days. Again, only the ones mentioned in the puzzle.
data Day
D14 :: Day
D15 :: Day
D16 :: Day
D17 :: Day
D18 :: Day
D19 :: Day

-- | Symbolic version of the type <a>Month</a>.
type SMonth = SBV Month

-- | Symbolic version of the constructor <a>Aug</a>.
sAug :: SBV Month

-- | Symbolic version of the constructor <a>Jul</a>.
sJul :: SBV Month

-- | Symbolic version of the constructor <a>Jun</a>.
sJun :: SBV Month

-- | Symbolic version of the constructor <a>May</a>.
sMay :: SBV Month

-- | Symbolic version of the type <a>Day</a>.
type SDay = SBV Day

-- | Symbolic version of the constructor <a>D19</a>.
sD19 :: SBV Day

-- | Symbolic version of the constructor <a>D18</a>.
sD18 :: SBV Day

-- | Symbolic version of the constructor <a>D17</a>.
sD17 :: SBV Day

-- | Symbolic version of the constructor <a>D16</a>.
sD16 :: SBV Day

-- | Symbolic version of the constructor <a>D15</a>.
sD15 :: SBV Day

-- | Symbolic version of the constructor <a>D14</a>.
sD14 :: SBV Day

-- | Represent the birthday as a record
data Birthday
BD :: SMonth -> SDay -> Birthday

-- | Make a valid symbolic birthday
mkBirthday :: Symbolic Birthday

-- | Is this a valid birthday? i.e., one that was declared by Cheryl to be
--   a possibility.
valid :: Birthday -> SBool

-- | Encode the conversation as given in the puzzle.
--   
--   NB. Lee Pike pointed out that not all the constraints are actually
--   necessary! (Private communication.) The puzzle still has a unique
--   solution if the statements <tt>a1</tt> and <tt>b1</tt> (i.e., Albert
--   and Bernard saying they themselves do not know the answer) are
--   removed. To experiment you can simply comment out those statements and
--   observe that there still is a unique solution. Thanks to Lee for
--   pointing this out! In fact, it is instructive to assert the
--   conversation line-by-line, and see how the search-space gets reduced
--   in each step.
puzzle :: ConstraintSet

-- | Find all solutions to the birthday problem. We have:
--   
--   <pre>
--   &gt;&gt;&gt; cheryl
--   Solution #1:
--     birthMonth = Jul :: Month
--     birthDay   = D16 :: Day
--   This is the only solution.
--   </pre>
cheryl :: IO ()
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Birthday.Day
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Birthday.Day
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Birthday.Day
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Birthday.Day
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Birthday.Day
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Birthday.Day
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Birthday.Day
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Birthday.Day
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Birthday.Month
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Birthday.Month
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Birthday.Month
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Birthday.Month
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Birthday.Month
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Birthday.Month
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Birthday.Month
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Birthday.Month


-- | Solves the following puzzle:
--   
--   <pre>
--   You and a friend pass by a standard coin operated vending machine and you decide to get a candy bar.
--   The price is US $0.95, but after checking your pockets you only have a dollar (US $1) and the machine
--   only takes coins. You turn to your friend and have this conversation:
--     you: Hey, do you have change for a dollar?
--     friend: Let's see. I have 6 US coins but, although they add up to a US $1.15, I can't break a dollar.
--     you: Huh? Can you make change for half a dollar?
--     friend: No.
--     you: How about a quarter?
--     friend: Nope, and before you ask I cant make change for a dime or nickel either.
--     you: Really? and these six coins are all US government coins currently in production? 
--     friend: Yes.
--     you: Well can you just put your coins into the vending machine and buy me a candy bar, and I'll pay you back?
--     friend: Sorry, I would like to but I cant with the coins I have.
--   What coins are your friend holding?
--   </pre>
--   
--   To be fair, the problem has no solution <i>mathematically</i>. But
--   there is a solution when one takes into account that vending machines
--   typically do not take the 50 cent coins!
module Documentation.SBV.Examples.Puzzles.Coins

-- | We will represent coins with 16-bit words (more than enough precision
--   for coins).
type Coin = SWord16

-- | Create a coin. The argument Int argument just used for naming the
--   coin. Note that we constrain the value to be one of the valid U.S.
--   coin values as we create it.
mkCoin :: Int -> Symbolic Coin

-- | Return all combinations of a sequence of values.
combinations :: [a] -> [[a]]

-- | Constraint 1: Cannot make change for a dollar.
c1 :: [Coin] -> SBool

-- | Constraint 2: Cannot make change for half a dollar.
c2 :: [Coin] -> SBool

-- | Constraint 3: Cannot make change for a quarter.
c3 :: [Coin] -> SBool

-- | Constraint 4: Cannot make change for a dime.
c4 :: [Coin] -> SBool

-- | Constraint 5: Cannot make change for a nickel
c5 :: [Coin] -> SBool

-- | Constraint 6: Cannot buy the candy either. Here's where we need to
--   have the extra knowledge that the vending machines do not take 50 cent
--   coins.
c6 :: [Coin] -> SBool

-- | Solve the puzzle. We have:
--   
--   <pre>
--   &gt;&gt;&gt; puzzle
--   Satisfiable. Model:
--     c1 = 50 :: Word16
--     c2 = 25 :: Word16
--     c3 = 10 :: Word16
--     c4 = 10 :: Word16
--     c5 = 10 :: Word16
--     c6 = 10 :: Word16
--   </pre>
--   
--   i.e., your friend has 4 dimes, a quarter, and a half dollar.
puzzle :: IO SatResult


-- | Consider the sentence:
--   
--   <pre>
--   In this sentence, the number of occurrences of 0 is _, of 1 is _, of 2 is _,
--   of 3 is _, of 4 is _, of 5 is _, of 6 is _, of 7 is _, of 8 is _, and of 9 is _.
--   </pre>
--   
--   The puzzle is to fill the blanks with numbers, such that the sentence
--   will be correct. There are precisely two solutions to this puzzle,
--   both of which are found by SBV successfully.
--   
--   References:
--   
--   <ul>
--   <li>Douglas Hofstadter, Metamagical Themes, pg. 27.</li>
--   
--   <li><a>http://mathcentral.uregina.ca/mp/archives/previous2002/dec02sol.html</a></li>
--   </ul>
module Documentation.SBV.Examples.Puzzles.Counts

-- | We will assume each number can be represented by an 8-bit word, i.e.,
--   can be at most 128.
type Count = SWord8

-- | Given a number, increment the count array depending on the digits of
--   the number
count :: Count -> [Count] -> [Count]

-- | Encoding of the puzzle. The solution is a sequence of 10 numbers for
--   the occurrences of the digits such that if we count each digit, we
--   find these numbers.
puzzle :: [Count] -> SBool

-- | Finds all two known solutions to this puzzle. We have:
--   
--   <pre>
--   &gt;&gt;&gt; counts
--   Solution #1
--   In this sentence, the number of occurrences of 0 is 1, of 1 is 11, of 2 is 2, of 3 is 1, of 4 is 1, of 5 is 1, of 6 is 1, of 7 is 1, of 8 is 1, of 9 is 1.
--   Solution #2
--   In this sentence, the number of occurrences of 0 is 1, of 1 is 7, of 2 is 3, of 3 is 2, of 4 is 1, of 5 is 1, of 6 is 1, of 7 is 2, of 8 is 1, of 9 is 1.
--   Found: 2 solution(s).
--   </pre>
counts :: IO ()


module Documentation.SBV.Examples.Puzzles.DogCatMouse

-- | Prints the only solution:
--   
--   <pre>
--   &gt;&gt;&gt; puzzle
--   Solution #1:
--     dog   =  3 :: Integer
--     cat   = 41 :: Integer
--     mouse = 56 :: Integer
--   This is the only solution.
--   </pre>
puzzle :: IO AllSatResult


-- | SBV proof of the drinker paradox:
--   <a>http://en.wikipedia.org/wiki/Drinker_paradox</a>
--   
--   Let P be the non-empty set of people in a bar. The theorem says if
--   there is somebody drinking in the bar, then everybody is drinking in
--   the bar. The general formulation is:
--   
--   <pre>
--   ∃x : P. D(x) -&gt; ∀y : P. D(y)
--   </pre>
module Documentation.SBV.Examples.Puzzles.Drinker

-- | Declare a carrier data-type in Haskell named P, representing all the
--   people in a bar.
data P

-- | Symbolic version of the type <a>P</a>.
type SP = SBV P

-- | Declare the uninterpret function <a>d</a>, standing for drinking. For
--   each person, this function assigns whether they are drinking; but is
--   otherwise completely uninterpreted. (i.e., our theorem will be true
--   for all such functions.)
d :: SP -> SBool

-- | Formulate the drinkers paradox, if some one is drinking, then everyone
--   is!
--   
--   <pre>
--   &gt;&gt;&gt; drinker
--   Q.E.D.
--   </pre>
drinker :: IO ThmResult
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Drinker.P
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Drinker.P
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Drinker.P
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Drinker.P
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Drinker.P
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Drinker.P


-- | A solution to Project Euler problem #185:
--   <a>http://projecteuler.net/index.php?section=problems&amp;id=185</a>
module Documentation.SBV.Examples.Puzzles.Euler185

-- | The given guesses and the correct digit counts, encoded as a simple
--   list.
guesses :: [(String, SWord8)]

-- | Encode the problem, note that we check digits are within 0-9 as we use
--   8-bit words to represent them. Otherwise, the constraints are simply
--   generated by zipping the alleged solution with each guess, and making
--   sure the number of matching digits match what's given in the problem
--   statement.
euler185 :: Symbolic SBool

-- | Print out the solution nicely. We have:
--   
--   <pre>
--   &gt;&gt;&gt; solveEuler185
--   4640261571849533
--   Number of solutions: 1
--   </pre>
solveEuler185 :: IO ()


-- | Solves the following logic puzzle, attributed to Albert Einstein:
--   
--   <ul>
--   <li>The Briton lives in the red house.</li>
--   <li>The Swede keeps dogs as pets.</li>
--   <li>The Dane drinks tea.</li>
--   <li>The green house is left to the white house.</li>
--   <li>The owner of the green house drinks coffee.</li>
--   <li>The person who plays football rears birds.</li>
--   <li>The owner of the yellow house plays baseball.</li>
--   <li>The man living in the center house drinks milk.</li>
--   <li>The Norwegian lives in the first house.</li>
--   <li>The man who plays volleyball lives next to the one who keeps
--   cats.</li>
--   <li>The man who keeps the horse lives next to the one who plays
--   baseball.</li>
--   <li>The owner who plays tennis drinks beer.</li>
--   <li>The German plays hockey.</li>
--   <li>The Norwegian lives next to the blue house.</li>
--   <li>The man who plays volleyball has a neighbor who drinks water.</li>
--   </ul>
--   
--   Who owns the fish?
module Documentation.SBV.Examples.Puzzles.Fish

-- | Colors of houses
data Color
Red :: Color
Green :: Color
White :: Color
Yellow :: Color
Blue :: Color

-- | Symbolic version of the type <a>Color</a>.
type SColor = SBV Color

-- | Symbolic version of the constructor <a>Blue</a>.
sBlue :: SBV Color

-- | Symbolic version of the constructor <a>Yellow</a>.
sYellow :: SBV Color

-- | Symbolic version of the constructor <a>White</a>.
sWhite :: SBV Color

-- | Symbolic version of the constructor <a>Green</a>.
sGreen :: SBV Color

-- | Symbolic version of the constructor <a>Red</a>.
sRed :: SBV Color

-- | Nationalities of the occupants
data Nationality
Briton :: Nationality
Dane :: Nationality
Swede :: Nationality
Norwegian :: Nationality
German :: Nationality

-- | Symbolic version of the type <a>Nationality</a>.
type SNationality = SBV Nationality

-- | Symbolic version of the constructor <a>German</a>.
sGerman :: SBV Nationality

-- | Symbolic version of the constructor <a>Norwegian</a>.
sNorwegian :: SBV Nationality

-- | Symbolic version of the constructor <a>Swede</a>.
sSwede :: SBV Nationality

-- | Symbolic version of the constructor <a>Dane</a>.
sDane :: SBV Nationality

-- | Symbolic version of the constructor <a>Briton</a>.
sBriton :: SBV Nationality

-- | Beverage choices
data Beverage
Tea :: Beverage
Coffee :: Beverage
Milk :: Beverage
Beer :: Beverage
Water :: Beverage

-- | Symbolic version of the type <a>Beverage</a>.
type SBeverage = SBV Beverage

-- | Symbolic version of the constructor <a>Water</a>.
sWater :: SBV Beverage

-- | Symbolic version of the constructor <a>Beer</a>.
sBeer :: SBV Beverage

-- | Symbolic version of the constructor <a>Milk</a>.
sMilk :: SBV Beverage

-- | Symbolic version of the constructor <a>Coffee</a>.
sCoffee :: SBV Beverage

-- | Symbolic version of the constructor <a>Tea</a>.
sTea :: SBV Beverage

-- | Pets they keep
data Pet
Dog :: Pet
Horse :: Pet
Cat :: Pet
Bird :: Pet
Fish :: Pet

-- | Symbolic version of the type <a>Pet</a>.
type SPet = SBV Pet

-- | Symbolic version of the constructor <a>Fish</a>.
sFish :: SBV Pet

-- | Symbolic version of the constructor <a>Bird</a>.
sBird :: SBV Pet

-- | Symbolic version of the constructor <a>Cat</a>.
sCat :: SBV Pet

-- | Symbolic version of the constructor <a>Horse</a>.
sHorse :: SBV Pet

-- | Symbolic version of the constructor <a>Dog</a>.
sDog :: SBV Pet

-- | Sports they engage in
data Sport
Football :: Sport
Baseball :: Sport
Volleyball :: Sport
Hockey :: Sport
Tennis :: Sport

-- | Symbolic version of the type <a>Sport</a>.
type SSport = SBV Sport

-- | Symbolic version of the constructor <a>Tennis</a>.
sTennis :: SBV Sport

-- | Symbolic version of the constructor <a>Hockey</a>.
sHockey :: SBV Sport

-- | Symbolic version of the constructor <a>Volleyball</a>.
sVolleyball :: SBV Sport

-- | Symbolic version of the constructor <a>Baseball</a>.
sBaseball :: SBV Sport

-- | Symbolic version of the constructor <a>Football</a>.
sFootball :: SBV Sport

-- | We have:
--   
--   <pre>
--   &gt;&gt;&gt; fishOwner
--   German
--   </pre>
--   
--   It's not hard to modify this program to grab the values of all the
--   assignments, i.e., the full solution to the puzzle. We leave that as
--   an exercise to the interested reader! NB. We use the
--   <a>allSatTrackUFs</a> configuration to indicate that the uninterpreted
--   function changes do not matter for generating different values. All we
--   care is that the fishOwner changes!
fishOwner :: IO ()
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Fish.Sport
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Fish.Sport
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Fish.Sport
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Fish.Sport
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Fish.Sport
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Fish.Sport
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Fish.Sport
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Fish.Sport
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Fish.Pet
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Fish.Pet
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Fish.Pet
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Fish.Pet
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Fish.Pet
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Fish.Pet
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Fish.Pet
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Fish.Pet
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Fish.Beverage
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Fish.Beverage
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Fish.Beverage
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Fish.Beverage
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Fish.Beverage
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Fish.Beverage
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Fish.Beverage
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Fish.Beverage
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Fish.Nationality
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Fish.Nationality
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Fish.Nationality
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Fish.Nationality
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Fish.Nationality
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Fish.Nationality
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Fish.Nationality
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Fish.Nationality
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Fish.Color
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Fish.Color
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Fish.Color
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Fish.Color
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Fish.Color
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Fish.Color
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Fish.Color
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Fish.Color


-- | The origin of this puzzle is Raymond Smullyan's "The Flower Garden"
--   riddle:
--   
--   In a certain flower garden, each flower was either red, yellow, or
--   blue, and all three colors were represented. A statistician once
--   visited the garden and made the observation that whatever three
--   flowers you picked, at least one of them was bound to be red. A second
--   statistician visited the garden and made the observation that whatever
--   three flowers you picked, at least one was bound to be yellow.
--   
--   Two logic students heard about this and got into an argument. The
--   first student said: “It therefore follows that whatever three flowers
--   you pick, at least one is bound to be blue, doesn’t it?” The second
--   student said: “Of course not!”
--   
--   Which student was right, and why?
--   
--   We slightly modify the puzzle. Assuming the first student is right, we
--   use SBV to show that the garden must contain exactly 3 flowers. In any
--   other case, the second student would be right.
module Documentation.SBV.Examples.Puzzles.Garden

-- | Colors of the flowers
data Color
Red :: Color
Yellow :: Color
Blue :: Color

-- | Symbolic version of the type <a>Color</a>.
type SColor = SBV Color

-- | Symbolic version of the constructor <a>Blue</a>.
sBlue :: SBV Color

-- | Symbolic version of the constructor <a>Yellow</a>.
sYellow :: SBV Color

-- | Symbolic version of the constructor <a>Red</a>.
sRed :: SBV Color

-- | Represent flowers by symbolic integers
type Flower = SInteger

-- | The uninterpreted function <a>col</a> assigns a color to each flower.
col :: Flower -> SBV Color

-- | Describe a valid pick of three flowers <tt>i</tt>, <tt>j</tt>,
--   <tt>k</tt>, assuming we have <tt>n</tt> flowers to start with.
--   Essentially the numbers should be within bounds and distinct.
validPick :: SInteger -> Flower -> Flower -> Flower -> SBool

-- | Count the number of flowers that occur in a given set of flowers.
count :: Color -> [Flower] -> SInteger

-- | Smullyan's puzzle.
puzzle :: ConstraintSet

-- | Solve the puzzle. We have:
--   
--   <pre>
--   &gt;&gt;&gt; flowerCount
--   Solution #1:
--     N = 3 :: Integer
--   This is the only solution.
--   </pre>
--   
--   So, a garden with 3 flowers is the only solution. (Note that we simply
--   skip over the prefix existentials and the assignments to uninterpreted
--   function <a>col</a> for model purposes here, as they don't represent a
--   different solution.)
flowerCount :: IO ()
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Garden.Color
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Garden.Color
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Garden.Color
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Garden.Color
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Garden.Color
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Garden.Color
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Garden.Color
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Garden.Color


-- | We're given a board, with 19 hexagon cells. The cells are arranged as
--   follows:
--   
--   <pre>
--       01  02  03
--     04  05  06  07
--   08  09  10  11  12
--     13  14  15  16
--       17  18  19
--   </pre>
--   
--   <ul>
--   <li>Each cell has a color, one of <tt>BLACK</tt>, <tt>BLUE</tt>,
--   <tt>GREEN</tt>, or <tt>RED</tt>.</li>
--   <li>At each step, you get to press one of the center buttons. That is,
--   one of 5, 6, 9, 10, 11, 14, or 15.</li>
--   <li>Pressing a button that is currently colored <tt>BLACK</tt> has no
--   effect.</li>
--   <li>Otherwise (i.e., if the pressed button is not <tt>BLACK</tt>),
--   then colors rotate clockwise around that button. For instance if you
--   press 15 when it is not colored <tt>BLACK</tt>, then 11 moves to 16,
--   16 moves to 19, 19 moves to 18, 18 moves to 14, 14 moves to 10, and 10
--   moves to 11.</li>
--   <li>Note that by "move," we mean the colors move: We still refer to
--   the buttons with the same number after a move.</li>
--   </ul>
--   
--   You are given an initial board coloring, and a final one. Your goal is
--   to find a minimal sequence of button presses that will turn the
--   original board to the final one.
module Documentation.SBV.Examples.Puzzles.HexPuzzle

-- | Colors we're allowed
data Color
Black :: Color
Blue :: Color
Green :: Color
Red :: Color

-- | Symbolic version of the type <a>Color</a>.
type SColor = SBV Color

-- | Symbolic version of the constructor <a>Red</a>.
sRed :: SBV Color

-- | Symbolic version of the constructor <a>Green</a>.
sGreen :: SBV Color

-- | Symbolic version of the constructor <a>Blue</a>.
sBlue :: SBV Color

-- | Symbolic version of the constructor <a>Black</a>.
sBlack :: SBV Color

-- | Use 8-bit words for button numbers, even though we only have 1 to 19.
type Button = Word8

-- | Symbolic version of button.
type SButton = SBV Button

-- | The grid is an array mapping each button to its color.
type Grid = SArray Button Color

-- | Given a button press, and the current grid, compute the next grid. If
--   the button is "unpressable", i.e., if it is not one of the center
--   buttons or it is currently colored black, we return the grid
--   unchanged.
next :: SButton -> Grid -> Grid

-- | Iteratively search at increasing depths of button-presses to see if we
--   can transform from the initial board position to a final board
--   position.
search :: [Color] -> [Color] -> IO ()

-- | A particular example run. We have:
--   
--   <pre>
--   &gt;&gt;&gt; example
--   Searching at depth: 0
--   Searching at depth: 1
--   Searching at depth: 2
--   Searching at depth: 3
--   Searching at depth: 4
--   Searching at depth: 5
--   Searching at depth: 6
--   Found: [10,10,9,11,14,6]
--   Found: [10,10,11,9,14,6]
--   There are no more solutions.
--   </pre>
example :: IO ()
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.HexPuzzle.Color
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.HexPuzzle.Color
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.HexPuzzle.Color
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.HexPuzzle.Color
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.HexPuzzle.Color
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.HexPuzzle.Color
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.HexPuzzle.Color
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.HexPuzzle.Color


-- | Solves the classic water jug puzzle: We have 3 jugs. The capacity of
--   the jugs are 8, 5, and 3 gallons. We begin with the 8 gallon jug full,
--   the other two empty. We can transfer from any jug to any other,
--   completely topping off the latter. We want to end with 4 gallons of
--   water in the first and second jugs, and with an empty third jug. What
--   moves should we execute in order to do so?
module Documentation.SBV.Examples.Puzzles.Jugs

-- | A Jug has a capacity (i.e., maximum amount of water it can hold), and
--   content, showing how much it currently has. The invariant is that
--   content is always non-negative and is at most the capacity.
data Jug
Jug :: Integer -> SInteger -> Jug
[capacity] :: Jug -> Integer
[content] :: Jug -> SInteger

-- | Transfer from one jug to another. By definition, we transfer to fill
--   the second jug, which may end up filling it fully, or leaving some in
--   the first jug.
transfer :: Jug -> Jug -> (Jug, Jug)

-- | At the beginning, we have an full 8-gallon jug, and two empty jugs, 5
--   and 3 gallons each.
initJugs :: (Jug, Jug, Jug)

-- | We've solved the puzzle if 8 and 5 gallon jugs have 4 gallons each,
--   and the third one is empty.
solved :: (Jug, Jug, Jug) -> SBool

-- | Execute a bunch of moves.
moves :: [(SInteger, SInteger)] -> (Jug, Jug, Jug)

-- | Solve the puzzle. We have:
--   
--   <pre>
--   &gt;&gt;&gt; puzzle
--   # of moves: 0
--   # of moves: 1
--   # of moves: 2
--   # of moves: 3
--   # of moves: 4
--   # of moves: 5
--   # of moves: 6
--   # of moves: 7
--   1 --&gt; 2
--   2 --&gt; 3
--   3 --&gt; 1
--   2 --&gt; 3
--   1 --&gt; 2
--   2 --&gt; 3
--   3 --&gt; 1
--   </pre>
--   
--   Here's the contents in terms of gallons after each move: (8, 0, 0) (3,
--   5, 0) (3, 2, 3) (6, 2, 0) (6, 0, 2) (1, 5, 2) (1, 4, 3) (4, 4, 0)
--   
--   Note that by construction this is the minimum length solution. (Though
--   our construction does not guarantee that it is unique.)
puzzle :: IO ()
instance Data.SBV.Core.Model.Mergeable Documentation.SBV.Examples.Puzzles.Jugs.Jug
instance GHC.Generics.Generic Documentation.SBV.Examples.Puzzles.Jugs.Jug


-- | From Raymond Smullyan: On a fictional island, all inhabitants are
--   either knights, who always tell the truth, or knaves, who always lie.
--   John and Bill are residents of the island of knights and knaves. John
--   and Bill make several utterances. Determine which one is a knave or a
--   knight, depending on their answers.
module Documentation.SBV.Examples.Puzzles.KnightsAndKnaves

-- | Inhabitants of the island, as an uninterpreted sort
data Inhabitant

-- | Symbolic version of the type <a>Inhabitant</a>.
type SInhabitant = SBV Inhabitant

-- | Each inhabitant is either a knave or a knight
data Identity
Knave :: Identity
Knight :: Identity

-- | Symbolic version of the type <a>Identity</a>.
type SIdentity = SBV Identity

-- | Symbolic version of the constructor <a>Knight</a>.
sKnight :: SBV Identity

-- | Symbolic version of the constructor <a>Knave</a>.
sKnave :: SBV Identity

-- | Statements are utterances which are either true or false
data Statement
Truth :: Statement
Falsity :: Statement

-- | Symbolic version of the type <a>Statement</a>.
type SStatement = SBV Statement

-- | Symbolic version of the constructor <a>Falsity</a>.
sFalsity :: SBV Statement

-- | Symbolic version of the constructor <a>Truth</a>.
sTruth :: SBV Statement

-- | John is an inhabitant of the island.
john :: SInhabitant

-- | Bill is an inhabitant of the island.
bill :: SInhabitant

-- | The connective <a>is</a> makes a statement about an inhabitant
--   regarding his/her identity.
is :: SInhabitant -> SIdentity -> SStatement

-- | The connective <a>says</a> makes a predicate from what an inhabitant
--   states
says :: SInhabitant -> SStatement -> SBool

-- | The connective <a>holds</a> is will be true if the statement is true
holds :: SStatement -> SBool

-- | The connective <a>and</a> creates the conjunction of two statements
and :: SStatement -> SStatement -> SStatement

-- | The connective <a>not</a> negates a statement
not :: SStatement -> SStatement

-- | The connective <a>iff</a> creates a statement that equates the truth
--   values of its argument statements
iff :: SStatement -> SStatement -> SStatement

-- | Encode Smullyan's puzzle. We have:
--   
--   <pre>
--   &gt;&gt;&gt; puzzle
--   Question 1.
--     John says, We are both knaves
--       Then, John is: Knave
--       And,  Bill is: Knight
--   Question 2.
--     John says If (and only if) Bill is a knave, then I am a knave.
--     Bill says We are of different kinds.
--       Then, John is: Knave
--       And,  Bill is: Knight
--   </pre>
puzzle :: IO ()
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Statement
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Statement
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Statement
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Statement
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Statement
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Statement
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Statement
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Statement
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Identity
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Identity
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Identity
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Identity
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Identity
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Identity
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Identity
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Identity
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Inhabitant
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Inhabitant
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Inhabitant
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Inhabitant
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Inhabitant
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.KnightsAndKnaves.Inhabitant


module Documentation.SBV.Examples.Puzzles.LadyAndTigers

-- | Prints the only solution:
--   
--   <pre>
--   &gt;&gt;&gt; ladyAndTigers
--   Solution #1:
--     sign1  = False :: Bool
--     sign2  = False :: Bool
--     sign3  =  True :: Bool
--     tiger1 = False :: Bool
--     tiger2 =  True :: Bool
--     tiger3 =  True :: Bool
--   This is the only solution.
--   </pre>
--   
--   That is, the lady is in room 1, and only the third room's sign is
--   true.
ladyAndTigers :: IO AllSatResult


-- | Solves the magic-square puzzle. An NxN magic square is one where all
--   entries are filled with numbers from 1 to NxN such that sums of all
--   rows, columns and diagonals is the same.
module Documentation.SBV.Examples.Puzzles.MagicSquare

-- | Use 32-bit words for elements.
type Elem = SWord32

-- | A row is a list of elements
type Row = [Elem]

-- | The puzzle board is a list of rows
type Board = [Row]

-- | Checks that all elements in a list are within bounds
check :: Elem -> Elem -> [Elem] -> SBool

-- | Get the diagonal of a square matrix
diag :: [[a]] -> [a]

-- | Test if a given board is a magic square
isMagic :: Board -> SBool

-- | Group a list of elements in the sublists of length <tt>i</tt>
chunk :: Int -> [a] -> [[a]]

-- | Given <tt>n</tt>, magic <tt>n</tt> prints all solutions to the
--   <tt>nxn</tt> magic square problem
magic :: Int -> IO ()


-- | Solution to "Malice and Alice," from George J. Summers' Logical
--   Deduction Puzzles:
--   
--   <pre>
--   A man and a woman were together in a bar at the time of the murder.
--   The victim and the killer were together on a beach at the time of the murder.
--   One of Alice’s two children was alone at the time of the murder.
--   Alice and her husband were not together at the time of the murder.
--   The victim's twin was not the killer.
--   The killer was younger than the victim.
--   
--   Who killed who?
--   </pre>
module Documentation.SBV.Examples.Puzzles.Murder

-- | Locations
data Location
Bar :: Location
Beach :: Location
Alone :: Location

-- | Sexes
data Sex
Male :: Sex
Female :: Sex

-- | Roles
data Role
Victim :: Role
Killer :: Role
Bystander :: Role

-- | Symbolic version of the type <a>Location</a>.
type SLocation = SBV Location

-- | Symbolic version of the constructor <a>Alone</a>.
sAlone :: SBV Location

-- | Symbolic version of the constructor <a>Beach</a>.
sBeach :: SBV Location

-- | Symbolic version of the constructor <a>Bar</a>.
sBar :: SBV Location

-- | Symbolic version of the type <a>Sex</a>.
type SSex = SBV Sex

-- | Symbolic version of the constructor <a>Female</a>.
sFemale :: SBV Sex

-- | Symbolic version of the constructor <a>Male</a>.
sMale :: SBV Sex

-- | Symbolic version of the type <a>Role</a>.
type SRole = SBV Role

-- | Symbolic version of the constructor <a>Bystander</a>.
sBystander :: SBV Role

-- | Symbolic version of the constructor <a>Killer</a>.
sKiller :: SBV Role

-- | Symbolic version of the constructor <a>Victim</a>.
sVictim :: SBV Role

-- | A person has a name, age, together with location and sex. We
--   parameterize over a function so we can use this struct both in a
--   concrete context and a symbolic context. Note that the name is always
--   concrete.
data Person f
Person :: String -> f Integer -> f Location -> f Sex -> f Role -> Person f
[nm] :: Person f -> String
[age] :: Person f -> f Integer
[location] :: Person f -> f Location
[sex] :: Person f -> f Sex
[role] :: Person f -> f Role

-- | Helper functor
newtype Const a
Const :: a -> Const a
[getConst] :: Const a -> a

-- | Create a new symbolic person
newPerson :: String -> Symbolic (Person SBV)

-- | Get the concrete value of the person in the model
getPerson :: Person SBV -> Query (Person Const)

-- | Solve the puzzle. We have:
--   
--   <pre>
--   &gt;&gt;&gt; killer
--   Alice     48  Bar    Female  Bystander
--   Husband   47  Beach  Male    Killer
--   Brother   48  Beach  Male    Victim
--   Daughter  21  Alone  Female  Bystander
--   Son       20  Bar    Male    Bystander
--   </pre>
--   
--   That is, Alice's brother was the victim and Alice's husband was the
--   killer.
killer :: IO ()

-- | Constraints of the puzzle, coded following the English description.
puzzle :: IO [Person Const]
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Murder.Role
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Murder.Role
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Murder.Role
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Murder.Role
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Murder.Role
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Murder.Role
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Murder.Role
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Murder.Role
instance GHC.Show.Show (Documentation.SBV.Examples.Puzzles.Murder.Person Documentation.SBV.Examples.Puzzles.Murder.Const)
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Murder.Sex
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Murder.Sex
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Murder.Sex
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Murder.Sex
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Murder.Sex
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Murder.Sex
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Murder.Sex
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Murder.Sex
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Murder.Location
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Murder.Location
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Murder.Location
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Murder.Location
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Murder.Location
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Murder.Location
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Murder.Location
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Murder.Location


-- | Solves the NQueens puzzle:
--   <a>http://en.wikipedia.org/wiki/Eight_queens_puzzle</a>
module Documentation.SBV.Examples.Puzzles.NQueens

-- | A solution is a sequence of row-numbers where queens should be placed
type Solution = [SWord8]

-- | Checks that a given solution of <tt>n</tt>-queens is valid, i.e., no
--   queen captures any other.
isValid :: Int -> Solution -> SBool

-- | Given <tt>n</tt>, it solves the <tt>n-queens</tt> puzzle, printing all
--   possible solutions.
nQueens :: Int -> IO ()


-- | Based on
--   <a>http://github.com/goldfirere/video-resources/blob/main/2022-08-12-java/Haskell.hs</a>
module Documentation.SBV.Examples.Puzzles.Orangutans

-- | Orangutans in the puzzle.
data Orangutan
Merah :: Orangutan
Ofallo :: Orangutan
Quirrel :: Orangutan
Shamir :: Orangutan

-- | Handlers for each orangutan.
data Handler
Dolly :: Handler
Eva :: Handler
Francine :: Handler
Gracie :: Handler

-- | Location for each orangutan.
data Location
Ambalat :: Location
Basahan :: Location
Kendisi :: Location
Tarakan :: Location

-- | Symbolic version of the type <a>Orangutan</a>.
type SOrangutan = SBV Orangutan

-- | Symbolic version of the constructor <a>Shamir</a>.
sShamir :: SBV Orangutan

-- | Symbolic version of the constructor <a>Quirrel</a>.
sQuirrel :: SBV Orangutan

-- | Symbolic version of the constructor <a>Ofallo</a>.
sOfallo :: SBV Orangutan

-- | Symbolic version of the constructor <a>Merah</a>.
sMerah :: SBV Orangutan

-- | Symbolic version of the type <a>Handler</a>.
type SHandler = SBV Handler

-- | Symbolic version of the constructor <a>Gracie</a>.
sGracie :: SBV Handler

-- | Symbolic version of the constructor <a>Francine</a>.
sFrancine :: SBV Handler

-- | Symbolic version of the constructor <a>Eva</a>.
sEva :: SBV Handler

-- | Symbolic version of the constructor <a>Dolly</a>.
sDolly :: SBV Handler

-- | Symbolic version of the type <a>Location</a>.
type SLocation = SBV Location

-- | Symbolic version of the constructor <a>Tarakan</a>.
sTarakan :: SBV Location

-- | Symbolic version of the constructor <a>Kendisi</a>.
sKendisi :: SBV Location

-- | Symbolic version of the constructor <a>Basahan</a>.
sBasahan :: SBV Location

-- | Symbolic version of the constructor <a>Ambalat</a>.
sAmbalat :: SBV Location

-- | An assignment is solution to the puzzle
data Assignment
MkAssignment :: SOrangutan -> SHandler -> SLocation -> SInteger -> Assignment
[orangutan] :: Assignment -> SOrangutan
[handler] :: Assignment -> SHandler
[location] :: Assignment -> SLocation
[age] :: Assignment -> SInteger

-- | Create a symbolic assignment, using symbolic fields.
mkSym :: Orangutan -> Symbolic Assignment

-- | We get:
--   
--   <pre>
--   &gt;&gt;&gt; allSat puzzle
--   Solution #1:
--     Merah.handler    =   Gracie :: Handler
--     Merah.location   =  Tarakan :: Location
--     Merah.age        =       10 :: Integer
--     Ofallo.handler   =      Eva :: Handler
--     Ofallo.location  =  Kendisi :: Location
--     Ofallo.age       =       13 :: Integer
--     Quirrel.handler  =    Dolly :: Handler
--     Quirrel.location =  Basahan :: Location
--     Quirrel.age      =        4 :: Integer
--     Shamir.handler   = Francine :: Handler
--     Shamir.location  =  Ambalat :: Location
--     Shamir.age       =        7 :: Integer
--   This is the only solution.
--   </pre>
puzzle :: ConstraintSet
instance Data.SBV.Core.Model.Mergeable Documentation.SBV.Examples.Puzzles.Orangutans.Assignment
instance GHC.Generics.Generic Documentation.SBV.Examples.Puzzles.Orangutans.Assignment
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Orangutans.Location
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Orangutans.Location
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Orangutans.Location
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Orangutans.Location
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Orangutans.Location
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Orangutans.Location
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Orangutans.Location
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Orangutans.Location
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Orangutans.Handler
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Orangutans.Handler
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Orangutans.Handler
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Orangutans.Handler
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Orangutans.Handler
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Orangutans.Handler
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Orangutans.Handler
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Orangutans.Handler
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.Orangutans.Orangutan
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.Orangutans.Orangutan
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Orangutans.Orangutan
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Orangutans.Orangutan
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Orangutans.Orangutan
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Orangutans.Orangutan
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Orangutans.Orangutan
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Orangutans.Orangutan
instance GHC.Enum.Bounded Documentation.SBV.Examples.Puzzles.Orangutans.Orangutan
instance GHC.Enum.Enum Documentation.SBV.Examples.Puzzles.Orangutans.Orangutan


-- | A puzzle, attributed to Lewis Caroll:
--   
--   <ul>
--   <li>All rabbits, that are not greedy, are black</li>
--   <li>No old rabbits are free from greediness</li>
--   <li>Therefore: Some black rabbits are not old</li>
--   </ul>
--   
--   What's implicit here is that there is a rabbit that must be
--   not-greedy; which we add to our constraints.
module Documentation.SBV.Examples.Puzzles.Rabbits

-- | A universe of rabbits
data Rabbit

-- | Symbolic version of the type <a>Rabbit</a>.
type SRabbit = SBV Rabbit

-- | Identify those rabbits that are greedy. Note that we leave the
--   predicate uninterpreted.
greedy :: SRabbit -> SBool

-- | Identify those rabbits that are black. Note that we leave the
--   predicate uninterpreted.
black :: SRabbit -> SBool

-- | Identify those rabbits that are old. Note that we leave the predicate
--   uninterpreted.
old :: SRabbit -> SBool

-- | Express the puzzle.
rabbits :: Predicate

-- | Prove the claim. We have:
--   
--   <pre>
--   &gt;&gt;&gt; rabbitsAreOK
--   Q.E.D.
--   </pre>
rabbitsAreOK :: IO ThmResult
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.Rabbits.Rabbit
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.Rabbits.Rabbit
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.Rabbits.Rabbit
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.Rabbits.Rabbit
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.Rabbits.Rabbit
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.Rabbits.Rabbit


-- | Solves the classic <tt>send + more = money</tt> puzzle.
module Documentation.SBV.Examples.Puzzles.SendMoreMoney

-- | Solve the puzzle. We have:
--   
--   <pre>
--   &gt;&gt;&gt; sendMoreMoney
--   Solution #1:
--     s = 9 :: Integer
--     e = 5 :: Integer
--     n = 6 :: Integer
--     d = 7 :: Integer
--     m = 1 :: Integer
--     o = 0 :: Integer
--     r = 8 :: Integer
--     y = 2 :: Integer
--   This is the only solution.
--   </pre>
--   
--   That is:
--   
--   <pre>
--   &gt;&gt;&gt; 9567 + 1085 == 10652
--   True
--   </pre>
sendMoreMoney :: IO AllSatResult


-- | The Sudoku solver, quintessential SMT solver example!
module Documentation.SBV.Examples.Puzzles.Sudoku

-- | A row is a sequence of digits that we represent symbolic integers
type Row = [SInteger]

-- | A Sudoku board is a sequence of 9 rows
type Board = [Row]

-- | Given a series of elements, make sure they are all different and they
--   all are numbers between 1 and 9
check :: [SInteger] -> SBool

-- | Given a full Sudoku board, check that it is valid
valid :: Board -> SBool

-- | A puzzle is simply a list of rows. Put 0 to indicate blanks.
type Puzzle = [[Integer]]

-- | Fill a given board, replacing 0's with appropriate elements to solve
--   the puzzle
fillBoard :: Puzzle -> IO Puzzle

-- | Solve a given puzzle and print the results
sudoku :: Puzzle -> IO ()

-- | A random puzzle, found on the internet..
puzzle1 :: Puzzle

-- | Another random puzzle, found on the internet..
puzzle2 :: Puzzle

-- | Another random puzzle, found on the internet..
puzzle3 :: Puzzle

-- | According to the web, this is the toughest sudoku puzzle ever.. It
--   even has a name: Al Escargot:
--   <a>http://zonkedyak.blogspot.com/2006/11/worlds-hardest-sudoku-puzzle-al.html</a>
puzzle4 :: Puzzle

-- | This one has been called diabolical, apparently
puzzle5 :: Puzzle

-- | The following is nefarious according to
--   <a>http://haskell.org/haskellwiki/Sudoku</a>
puzzle6 :: Puzzle

-- | Solve them all, this takes a fraction of a second to run for each case
allPuzzles :: IO ()


-- | The famous U2 bridge crossing puzzle:
--   <a>http://www.braingle.com/brainteasers/515/u2.html</a>
module Documentation.SBV.Examples.Puzzles.U2Bridge

-- | U2 band members. We want to translate this to SMT-Lib as a data-type,
--   and hence the call to mkSymbolicEnumeration.
data U2Member
Bono :: U2Member
Edge :: U2Member
Adam :: U2Member
Larry :: U2Member

-- | Symbolic version of the type <a>U2Member</a>.
type SU2Member = SBV U2Member

-- | Symbolic version of the constructor <a>Larry</a>.
sLarry :: SBV U2Member

-- | Symbolic version of the constructor <a>Adam</a>.
sAdam :: SBV U2Member

-- | Symbolic version of the constructor <a>Edge</a>.
sEdge :: SBV U2Member

-- | Symbolic version of the constructor <a>Bono</a>.
sBono :: SBV U2Member

-- | Model time using 32 bits
type Time = Word32

-- | Symbolic variant for time
type STime = SBV Time

-- | Crossing times for each member of the band
crossTime :: U2Member -> Time

-- | The symbolic variant.. The duplication is unfortunate.
sCrossTime :: SU2Member -> STime

-- | Location of the flash
data Location
Here :: Location
There :: Location

-- | Symbolic version of the type <a>Location</a>.
type SLocation = SBV Location

-- | Symbolic version of the constructor <a>There</a>.
sThere :: SBV Location

-- | Symbolic version of the constructor <a>Here</a>.
sHere :: SBV Location

-- | The status of the puzzle after each move
--   
--   This type is equipped with an automatically derived <a>Mergeable</a>
--   instance because each field is <a>Mergeable</a>. A <a>Generic</a>
--   instance must also be derived for this to work, and the
--   <tt>DeriveAnyClass</tt> language extension must be enabled. The
--   derived <a>Mergeable</a> instance simply walks down the structure
--   field by field and merges each one. An equivalent hand-written
--   <a>Mergeable</a> instance is provided in a comment below.
data Status
Status :: STime -> SLocation -> SLocation -> SLocation -> SLocation -> SLocation -> Status

-- | elapsed time
[time] :: Status -> STime

-- | location of the flash
[flash] :: Status -> SLocation

-- | location of Bono
[lBono] :: Status -> SLocation

-- | location of Edge
[lEdge] :: Status -> SLocation

-- | location of Adam
[lAdam] :: Status -> SLocation

-- | location of Larry
[lLarry] :: Status -> SLocation

-- | Start configuration, time elapsed is 0 and everybody is here
start :: Status

-- | A puzzle move is modeled as a state-transformer
type Move a = State Status a

-- | Read the state via an accessor function
peek :: (Status -> a) -> Move a

-- | Given an arbitrary member, return his location
whereIs :: SU2Member -> Move SLocation

-- | Transferring the flash to the other side
xferFlash :: Move ()

-- | Transferring a person to the other side
xferPerson :: SU2Member -> Move ()

-- | Increment the time, when only one person crosses
bumpTime1 :: SU2Member -> Move ()

-- | Increment the time, when two people cross together
bumpTime2 :: SU2Member -> SU2Member -> Move ()

-- | Symbolic version of <a>when</a>
whenS :: SBool -> Move () -> Move ()

-- | Move one member, remembering to take the flash
move1 :: SU2Member -> Move ()

-- | Move two members, again with the flash
move2 :: SU2Member -> SU2Member -> Move ()

-- | A move action is a sequence of triples. The first component is
--   symbolically True if only one member crosses. (In this case the third
--   element of the triple is irrelevant.) If the first component is
--   (symbolically) False, then both members move together
type Actions = [(SBool, SU2Member, SU2Member)]

-- | Run a sequence of given actions.
run :: Actions -> Move [Status]

-- | Check if a given sequence of actions is valid, i.e., they must all
--   cross the bridge according to the rules and in less than 17 seconds
isValid :: Actions -> SBool

-- | See if there is a solution that has precisely <tt>n</tt> steps
solveN :: Int -> IO Bool

-- | Solve the U2-bridge crossing puzzle, starting by testing solutions
--   with increasing number of steps, until we find one. We have:
--   
--   <pre>
--   &gt;&gt;&gt; solveU2
--   Checking for solutions with 1 move.
--   Checking for solutions with 2 moves.
--   Checking for solutions with 3 moves.
--   Checking for solutions with 4 moves.
--   Checking for solutions with 5 moves.
--   Solution #1:
--    0 --&gt; Edge, Bono
--    2 &lt;-- Bono
--    3 --&gt; Larry, Adam
--   13 &lt;-- Edge
--   15 --&gt; Edge, Bono
--   Total time: 17
--   Solution #2:
--    0 --&gt; Edge, Bono
--    2 &lt;-- Edge
--    4 --&gt; Larry, Adam
--   14 &lt;-- Bono
--   15 --&gt; Edge, Bono
--   Total time: 17
--   Found: 2 solutions with 5 moves.
--   </pre>
--   
--   Finding all possible solutions to the puzzle.
solveU2 :: IO ()
instance Data.SBV.Core.Model.Mergeable Documentation.SBV.Examples.Puzzles.U2Bridge.Status
instance GHC.Generics.Generic Documentation.SBV.Examples.Puzzles.U2Bridge.Status
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.U2Bridge.Location
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.U2Bridge.Location
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.U2Bridge.Location
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.U2Bridge.Location
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.U2Bridge.Location
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.U2Bridge.Location
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.U2Bridge.Location
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.U2Bridge.Location
instance Data.SBV.Core.Model.Mergeable a => Data.SBV.Core.Model.Mergeable (Documentation.SBV.Examples.Puzzles.U2Bridge.Move a)
instance GHC.Classes.Eq Documentation.SBV.Examples.Puzzles.U2Bridge.U2Member
instance GHC.Classes.Ord Documentation.SBV.Examples.Puzzles.U2Bridge.U2Member
instance GHC.Show.Show Documentation.SBV.Examples.Puzzles.U2Bridge.U2Member
instance GHC.Read.Read Documentation.SBV.Examples.Puzzles.U2Bridge.U2Member
instance Data.Data.Data Documentation.SBV.Examples.Puzzles.U2Bridge.U2Member
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Puzzles.U2Bridge.U2Member
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Puzzles.U2Bridge.U2Member
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Puzzles.U2Bridge.U2Member


-- | Demonstrates extraction of abducts via queries.
--   
--   N.B. Interpolants are only supported by CVC5 currently.
module Documentation.SBV.Examples.Queries.Abducts

-- | Abduct extraction example. We have the constraint <tt>x &gt;= 0</tt>
--   and we want to make <tt>x + y &gt;= 2</tt>. We have:
--   
--   <pre>
--   &gt;&gt;&gt; example
--   Got: (define-fun abd () Bool (= s1 2))
--   Got: (define-fun abd () Bool (&lt;= 2 s1))
--   Got: (define-fun abd () Bool (= (+ s1 s0) 2))
--   Got: (define-fun abd () Bool (= (+ s0 2) s1))
--   </pre>
--   
--   Note that <tt>s0</tt> refers to <tt>x</tt> and <tt>s1</tt> refers to
--   <tt>y</tt> above. You can verify that adding any of these will ensure
--   <tt>x + y &gt;= 2</tt>.
example :: IO ()


-- | When we would like to find all solutions to a problem, we can query
--   the solver repeatedly, telling it to give us a new model each time.
--   SBV already provides <a>allSat</a> that precisely does this. However,
--   this example demonstrates how the query mode can be used to achieve
--   the same, and can also incorporate extra conditions with easy as we
--   walk through solutions.
module Documentation.SBV.Examples.Queries.AllSat

-- | Find all solutions to <tt>x + y .== 10</tt> for positive <tt>x</tt>
--   and <tt>y</tt>. This is rather silly to do in the query mode as
--   <a>allSat</a> can do this automatically, but it demonstrates how we
--   can dynamically query the result and put in new constraints based on
--   those.
goodSum :: Symbolic [(Integer, Integer)]

-- | Run the query. We have:
--   
--   <pre>
--   &gt;&gt;&gt; demo
--   Starting the all-sat engine!
--   Iteration: 1
--   Current solution is: (0,10)
--   Iteration: 2
--   Current solution is: (1,9)
--   Iteration: 3
--   Current solution is: (2,8)
--   Iteration: 4
--   Current solution is: (3,7)
--   Iteration: 5
--   Current solution is: (4,6)
--   Iteration: 6
--   Current solution is: (5,5)
--   Iteration: 7
--   Current solution is: (6,4)
--   Iteration: 8
--   Current solution is: (7,3)
--   Iteration: 9
--   Current solution is: (8,2)
--   Iteration: 10
--   Current solution is: (9,1)
--   Iteration: 11
--   Current solution is: (10,0)
--   Iteration: 12
--   No other solution!
--   [(0,10),(1,9),(2,8),(3,7),(4,6),(5,5),(6,4),(7,3),(8,2),(9,1),(10,0)]
--   </pre>
demo :: IO ()


-- | A couple of demonstrations for the <a>caseSplit</a> function.
module Documentation.SBV.Examples.Queries.CaseSplit

-- | A simple floating-point problem, but we do the sat-analysis via a
--   case-split. Due to the nature of floating-point numbers, a case-split
--   on the characteristics of the number (such as NaN, negative-zero, etc.
--   is most suitable.)
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; csDemo1
--   Case fpIsNegativeZero: Starting
--   Case fpIsNegativeZero: Unsatisfiable
--   Case fpIsPositiveZero: Starting
--   Case fpIsPositiveZero: Unsatisfiable
--   Case fpIsNormal: Starting
--   Case fpIsNormal: Unsatisfiable
--   Case fpIsSubnormal: Starting
--   Case fpIsSubnormal: Unsatisfiable
--   Case fpIsPoint: Starting
--   Case fpIsPoint: Unsatisfiable
--   Case fpIsNaN: Starting
--   Case fpIsNaN: Satisfiable
--   ("fpIsNaN",NaN)
--   </pre>
csDemo1 :: IO (String, Float)

-- | Demonstrates the "coverage" case.
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; csDemo2
--   Case negative: Starting
--   Case negative: Unsatisfiable
--   Case less than 8: Starting
--   Case less than 8: Unsatisfiable
--   Case Coverage: Starting
--   Case Coverage: Satisfiable
--   ("Coverage",10)
--   </pre>
csDemo2 :: IO (String, Integer)


-- | When we would like to solve a set of related problems we can use query
--   mode to perform push's and pop's. However performing a push and a pop
--   is still single threaded and so each solution will need to wait for
--   the previous solution to be found. In this example we show a class of
--   functions <a>satConcurrentWithAll</a> and <a>satConcurrentWithAny</a>
--   which spin up independent solver instances and runs query computations
--   concurrently. The children query computations are allowed to
--   communicate with one another as demonstrated in the second demo.
module Documentation.SBV.Examples.Queries.Concurrency

-- | Find all solutions to <tt>x + y .== 10</tt> for positive <tt>x</tt>
--   and <tt>y</tt>, but at each iteration we would like to ensure that the
--   value of <tt>x</tt> we get is at least twice as large as the previous
--   one. This is rather silly, but demonstrates how we can dynamically
--   query the result and put in new constraints based on those.
shared :: MVar (SInteger, SInteger) -> Symbolic ()

-- | In our first query we'll define a constraint that will not be known to
--   the shared or second query and then solve for an answer that will
--   differ from the first query. Note that we need to pass an MVar in so
--   that we can operate on the shared variables. In general, the variables
--   you want to operate on should be defined in the shared part of the
--   query and then passed to the children queries via channels, MVars, or
--   TVars. In this query we constrain x to be less than y and then return
--   the sum of the values. We add a threadDelay just for demonstration
--   purposes
queryOne :: MVar (SInteger, SInteger) -> Query (Maybe Integer)

-- | In the second query we constrain for an answer where y is smaller than
--   x, and then return the product of the found values.
queryTwo :: MVar (SInteger, SInteger) -> Query (Maybe Integer)

-- | Run the demo several times to see that the children threads will
--   change ordering.
demo :: IO ()

-- | Example computation.
sharedDependent :: MVar (SInteger, SInteger) -> Symbolic ()

-- | In our first query we will make a constrain, solve the constraint and
--   return the values for our variables, then we'll mutate the MVar
--   sending information to the second query. Note that you could use
--   channels, or TVars, or TMVars, whatever you need here, we just use
--   MVars for demonstration purposes. Also note that this effectively
--   creates an ordering between the children queries
firstQuery :: MVar (SInteger, SInteger) -> MVar (SInteger, SInteger) -> Query (Maybe Integer)

-- | In the second query we create a new variable z, and then a symbolic
--   query using information from the first query and return a solution
--   that uses the new variable and the old variables. Each child query is
--   run in a separate instance of z3 so you can think of this query as
--   driving to a point in the search space, then waiting for more
--   information, once it gets that information it will run a completely
--   separate computation from the first one and return its results.
secondQuery :: MVar (SInteger, SInteger) -> Query (Maybe Integer)

-- | In our second demonstration we show how through the use of concurrency
--   constructs the user can have children queries communicate with one
--   another. Note that the children queries are independent and so
--   anything side-effectual like a push or a pop will be isolated to that
--   child thread, unless of course it happens in shared.
demoDependent :: IO ()


-- | Demonstrates the use of enumeration values during queries.
module Documentation.SBV.Examples.Queries.Enums

-- | Days of the week. We make it symbolic using the
--   <a>mkSymbolicEnumeration</a> splice.
data Day
Monday :: Day
Tuesday :: Day
Wednesday :: Day
Thursday :: Day
Friday :: Day
Saturday :: Day
Sunday :: Day

-- | Symbolic version of the type <a>Day</a>.
type SDay = SBV Day

-- | Symbolic version of the constructor <a>Sunday</a>.
sSunday :: SBV Day

-- | Symbolic version of the constructor <a>Saturday</a>.
sSaturday :: SBV Day

-- | Symbolic version of the constructor <a>Friday</a>.
sFriday :: SBV Day

-- | Symbolic version of the constructor <a>Thursday</a>.
sThursday :: SBV Day

-- | Symbolic version of the constructor <a>Wednesday</a>.
sWednesday :: SBV Day

-- | Symbolic version of the constructor <a>Tuesday</a>.
sTuesday :: SBV Day

-- | Symbolic version of the constructor <a>Monday</a>.
sMonday :: SBV Day

-- | A trivial query to find three consecutive days that's all before
--   <a>Thursday</a>. The point here is that we can perform queries on such
--   enumerated values and use <a>getValue</a> on them and return their
--   values from queries just like any other value. We have:
--   
--   <pre>
--   &gt;&gt;&gt; findDays
--   [Monday,Tuesday,Wednesday]
--   </pre>
findDays :: IO [Day]
instance GHC.Classes.Eq Documentation.SBV.Examples.Queries.Enums.Day
instance GHC.Classes.Ord Documentation.SBV.Examples.Queries.Enums.Day
instance GHC.Show.Show Documentation.SBV.Examples.Queries.Enums.Day
instance GHC.Read.Read Documentation.SBV.Examples.Queries.Enums.Day
instance Data.Data.Data Documentation.SBV.Examples.Queries.Enums.Day
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Queries.Enums.Day
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Queries.Enums.Day
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Queries.Enums.Day


-- | A query based solution to the four-fours puzzle. Inspired by
--   <a>http://www.gigamonkeys.com/trees/</a>
--   
--   <pre>
--   Try to make every number between 0 and 20 using only four 4s and any
--   mathematical operation, with all four 4s being used each time.
--   </pre>
--   
--   We pretty much follow the structure of
--   <a>http://www.gigamonkeys.com/trees/</a>, with the exception that we
--   generate the trees filled with symbolic operators and ask the SMT
--   solver to find the appropriate fillings.
module Documentation.SBV.Examples.Queries.FourFours

-- | Supported binary operators. To keep the search-space small, we will
--   only allow division by <tt>2</tt> or <tt>4</tt>, and exponentiation
--   will only be to the power <tt>0</tt>. This does restrict the search
--   space, but is sufficient to solve all the instances.
data BinOp
Plus :: BinOp
Minus :: BinOp
Times :: BinOp
Divide :: BinOp
Expt :: BinOp

-- | Symbolic version of the type <a>BinOp</a>.
type SBinOp = SBV BinOp

-- | Symbolic version of the constructor <a>Expt</a>.
sExpt :: SBV BinOp

-- | Symbolic version of the constructor <a>Divide</a>.
sDivide :: SBV BinOp

-- | Symbolic version of the constructor <a>Times</a>.
sTimes :: SBV BinOp

-- | Symbolic version of the constructor <a>Minus</a>.
sMinus :: SBV BinOp

-- | Symbolic version of the constructor <a>Plus</a>.
sPlus :: SBV BinOp

-- | Supported unary operators. Similar to <a>BinOp</a> case, we will
--   restrict square-root and factorial to be only applied to the value @4.
data UnOp
Negate :: UnOp
Sqrt :: UnOp
Factorial :: UnOp

-- | Symbolic version of the type <a>UnOp</a>.
type SUnOp = SBV UnOp

-- | Symbolic version of the constructor <a>Factorial</a>.
sFactorial :: SBV UnOp

-- | Symbolic version of the constructor <a>Sqrt</a>.
sSqrt :: SBV UnOp

-- | Symbolic version of the constructor <a>Negate</a>.
sNegate :: SBV UnOp

-- | The shape of a tree, either a binary node, or a unary node, or the
--   number <tt>4</tt>, represented hear by the constructor <tt>F</tt>. We
--   parameterize by the operator type: When doing symbolic computations,
--   we'll fill those with <a>SBinOp</a> and <a>SUnOp</a>. When finding the
--   shapes, we will simply put unit values, i.e., holes.
data T b u
B :: b -> T b u -> T b u -> T b u
U :: u -> T b u -> T b u
F :: T b u

-- | Construct all possible tree shapes. The argument here follows the
--   logic in <a>http://www.gigamonkeys.com/trees/</a>: We simply construct
--   all possible shapes and extend with the operators. The number of such
--   trees is:
--   
--   <pre>
--   &gt;&gt;&gt; length allPossibleTrees
--   640
--   </pre>
--   
--   Note that this is a <i>lot</i> smaller than what is generated by
--   <a>http://www.gigamonkeys.com/trees/</a>. (There, the number of trees
--   is 10240000: 16000 times more than what we have to consider!)
allPossibleTrees :: [T () ()]

-- | Given a tree with hols, fill it with symbolic operators. This is the
--   <i>trick</i> that allows us to consider only 640 trees as opposed to
--   over 10 million.
fill :: T () () -> Symbolic (T SBinOp SUnOp)

-- | Minor helper for writing "symbolic" case statements. Simply walks down
--   a list of values to match against a symbolic version of the key.
sCase :: (Eq a, SymVal a, Mergeable v) => SBV a -> [(a, v)] -> v

-- | Evaluate a symbolic tree, obtaining a symbolic value. Note how we
--   structure this evaluation so we impose extra constraints on what
--   values square-root, divide etc. can take. This is the power of the
--   symbolic approach: We can put arbitrary symbolic constraints as we
--   evaluate the tree.
eval :: T SBinOp SUnOp -> Symbolic SInteger

-- | In the query mode, find a filling of a given tree shape <i>t</i>, such
--   that it evaluates to the requested number <i>i</i>. Note that we
--   return back a concrete tree.
generate :: Integer -> T () () -> IO (Maybe (T BinOp UnOp))

-- | Given an integer, walk through all possible tree shapes (at most 640
--   of them), and find a filling that solves the puzzle.
find :: Integer -> IO ()

-- | Solution to the puzzle. When you run this puzzle, the solver can
--   produce different results than what's shown here, but the expressions
--   should still be all valid!
--   
--   <pre>
--   ghci&gt; puzzle
--    0 [OK]: (4 - (4 + (4 - 4)))
--    1 [OK]: (4 / (4 + (4 - 4)))
--    2 [OK]: sqrt((4 + (4 * (4 - 4))))
--    3 [OK]: (4 - (4 ^ (4 - 4)))
--    4 [OK]: (4 + (4 * (4 - 4)))
--    5 [OK]: (4 + (4 ^ (4 - 4)))
--    6 [OK]: (4 + sqrt((4 * (4 / 4))))
--    7 [OK]: (4 + (4 - (4 / 4)))
--    8 [OK]: (4 - (4 - (4 + 4)))
--    9 [OK]: (4 + (4 + (4 / 4)))
--   10 [OK]: (4 + (4 + (4 - sqrt(4))))
--   11 [OK]: (4 + ((4 + 4!) / 4))
--   12 [OK]: (4 * (4 - (4 / 4)))
--   13 [OK]: (4! + ((sqrt(4) - 4!) / sqrt(4)))
--   14 [OK]: (4 + (4 + (4 + sqrt(4))))
--   15 [OK]: (4 + ((4! - sqrt(4)) / sqrt(4)))
--   16 [OK]: (4 * (4 * (4 / 4)))
--   17 [OK]: (4 + ((sqrt(4) + 4!) / sqrt(4)))
--   18 [OK]: -(4 + (4 - (sqrt(4) + 4!)))
--   19 [OK]: -(4 - (4! - (4 / 4)))
--   20 [OK]: (4 * (4 + (4 / 4)))
--   </pre>
puzzle :: IO ()
instance GHC.Classes.Eq Documentation.SBV.Examples.Queries.FourFours.UnOp
instance GHC.Classes.Ord Documentation.SBV.Examples.Queries.FourFours.UnOp
instance GHC.Show.Show Documentation.SBV.Examples.Queries.FourFours.UnOp
instance GHC.Read.Read Documentation.SBV.Examples.Queries.FourFours.UnOp
instance Data.Data.Data Documentation.SBV.Examples.Queries.FourFours.UnOp
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Queries.FourFours.UnOp
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Queries.FourFours.UnOp
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Queries.FourFours.UnOp
instance GHC.Show.Show (Documentation.SBV.Examples.Queries.FourFours.T Documentation.SBV.Examples.Queries.FourFours.BinOp Documentation.SBV.Examples.Queries.FourFours.UnOp)
instance GHC.Classes.Eq Documentation.SBV.Examples.Queries.FourFours.BinOp
instance GHC.Classes.Ord Documentation.SBV.Examples.Queries.FourFours.BinOp
instance GHC.Show.Show Documentation.SBV.Examples.Queries.FourFours.BinOp
instance GHC.Read.Read Documentation.SBV.Examples.Queries.FourFours.BinOp
instance Data.Data.Data Documentation.SBV.Examples.Queries.FourFours.BinOp
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Queries.FourFours.BinOp
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Queries.FourFours.BinOp
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Queries.FourFours.BinOp


-- | A simple number-guessing game implementation via queries. Clearly an
--   SMT solver is hardly needed for this problem, but it is a nice demo
--   for the interactive-query programming.
module Documentation.SBV.Examples.Queries.GuessNumber

-- | Use the backend solver to guess the number given as argument. The
--   number is assumed to be between <tt>0</tt> and <tt>1000</tt>, and we
--   use a simple binary search. Returns the sequence of guesses we
--   performed during the search process.
guess :: Integer -> Symbolic [Integer]

-- | Play a round of the game, making the solver guess the secret number
--   42. Note that you can generate a random-number and make the solver
--   guess it too! We have:
--   
--   <pre>
--   &gt;&gt;&gt; play
--   Current bounds: (0,1000)
--   Current bounds: (21,1000)
--   Current bounds: (31,1000)
--   Current bounds: (36,1000)
--   Current bounds: (39,1000)
--   Current bounds: (40,1000)
--   Current bounds: (41,1000)
--   Current bounds: (42,1000)
--   Solved in: 8 guesses:
--     8 21 31 36 39 40 41 42
--   </pre>
play :: IO ()


-- | Demonstrates extraction of interpolants via queries.
--   
--   N.B. Interpolants are supported by MathSAT and Z3. Unfortunately the
--   extraction of interpolants is not standardized, and are slightly
--   different for these two solvers. So, we have two separate examples to
--   demonstrate the usage.
module Documentation.SBV.Examples.Queries.Interpolants

-- | MathSAT example. Compute the interpolant for the following sets of
--   formulas:
--   
--   <pre>
--   {x - 3y &gt;= -1, x + y &gt;= 0}
--   </pre>
--   
--   AND
--   
--   <pre>
--   {z - 2x &gt;= 3, 2z &lt;= 1}
--   </pre>
--   
--   where the variables are integers. Note that these sets of formulas are
--   themselves satisfiable, but not taken all together. The pair <tt>(x,
--   y) = (0, 0)</tt> satisfies the first set. The pair <tt>(x, z) = (-2,
--   0)</tt> satisfies the second. However, there's no triple <tt>(x, y,
--   z)</tt> that satisfies all these four formulas together. We can use
--   SBV to check this fact:
--   
--   <pre>
--   &gt;&gt;&gt; sat $ \x y z -&gt; sAnd [x - 3*y .&gt;= -1, x + y .&gt;= 0, z - 2*x .&gt;= 3, 2 * z .&lt;= (1::SInteger)]
--   Unsatisfiable
--   </pre>
--   
--   An interpolant for these sets would only talk about the variable
--   <tt>x</tt> that is common to both. We have:
--   
--   <pre>
--   &gt;&gt;&gt; runSMTWith mathSAT exampleMathSAT
--   "(&lt;= 0 s0)"
--   </pre>
--   
--   Notice that we get a string back, not a term; so there's some
--   back-translation we need to do. We know that <tt>s0</tt> is <tt>x</tt>
--   through our translation mechanism, so the interpolant is saying that
--   <tt>x &gt;= 0</tt> is entailed by the first set of formulas, and is
--   inconsistent with the second. Let's use SBV to indeed show that this
--   is the case:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x y -&gt; (x - 3*y .&gt;= -1 .&amp;&amp; x + y .&gt;= 0) .=&gt; (x .&gt;= (0::SInteger))
--   Q.E.D.
--   </pre>
--   
--   And:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \x z -&gt; (z - 2*x .&gt;= 3 .&amp;&amp; 2 * z .&lt;= 1) .=&gt; sNot (x .&gt;= (0::SInteger))
--   Q.E.D.
--   </pre>
--   
--   This establishes that we indeed have an interpolant!
exampleMathSAT :: Symbolic String

-- | Z3 example. Compute the interpolant for formulas <tt>y = 2x</tt> and
--   <tt>y = 2z+1</tt>.
--   
--   These formulas are not satisfiable together since it would mean
--   <tt>y</tt> is both even and odd at the same time. An interpolant for
--   this pair of formulas is a formula that's expressed only in terms of
--   <tt>y</tt>, which is the only common symbol among them. We have:
--   
--   <pre>
--   &gt;&gt;&gt; runSMT evenOdd
--   "(or (= s1 0) (= s1 (* 2 (div s1 2))))"
--   </pre>
--   
--   This is a bit hard to read unfortunately, due to translation artifacts
--   and use of strings. To analyze, we need to know that <tt>s1</tt> is
--   <tt>y</tt> through SBV's translation. Let's express it in regular
--   infix notation with <tt>y</tt> for <tt>s1</tt>:
--   
--   <pre>
--   (y == 0) || (y == 2 * (y <a>div</a> 2))
--   </pre>
--   
--   Notice that the only symbol is <tt>y</tt>, as required. To establish
--   that this is indeed an interpolant, we should establish that when
--   <tt>y</tt> is even, this formula is <tt>True</tt>; and if <tt>y</tt>
--   is odd, then it should be <tt>False</tt>. You can argue mathematically
--   that this indeed the case, but let's just use SBV to prove these:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \y -&gt; (y `sMod` 2 .== 0) .=&gt; ((y .== 0) .|| (y .== 2 * (y `sDiv` (2::SInteger))))
--   Q.E.D.
--   </pre>
--   
--   And:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \y -&gt; (y `sMod` 2 .== 1) .=&gt; sNot ((y .== 0) .|| (y .== 2 * (y `sDiv` (2::SInteger))))
--   Q.E.D.
--   </pre>
--   
--   This establishes that we indeed have an interpolant!
evenOdd :: Symbolic String


-- | Demonstrates extraction of unsat-cores via queries.
module Documentation.SBV.Examples.Queries.UnsatCore

-- | A simple goal with three constraints, two of which are conflicting
--   with each other. The third is irrelevant, in the sense that it does
--   not contribute to the fact that the goal is unsatisfiable.
p :: Symbolic (Maybe [String])

-- | Extract the unsat-core of <a>p</a>. We have:
--   
--   <pre>
--   &gt;&gt;&gt; ucCore
--   Unsat core is: ["less than 5","more than 10"]
--   </pre>
--   
--   Demonstrating that the constraint <tt>a .&gt; b</tt> is <i>not</i>
--   needed for unsatisfiablity in this case.
ucCore :: IO ()


-- | This example solves regex crosswords from
--   <a>http://regexcrossword.com</a>
module Documentation.SBV.Examples.Strings.RegexCrossword

-- | Solve a given crossword, returning the corresponding rows
solveCrossword :: [RegExp] -> [RegExp] -> IO [String]

-- | Solve
--   <a>http://regexcrossword.com/challenges/intermediate/puzzles/1</a>
--   
--   <pre>
--   &gt;&gt;&gt; puzzle1
--   ["ATO","WEL"]
--   </pre>
puzzle1 :: IO [String]

-- | Solve
--   <a>http://regexcrossword.com/challenges/intermediate/puzzles/2</a>
--   
--   <pre>
--   &gt;&gt;&gt; puzzle2
--   ["WA","LK","ER"]
--   </pre>
puzzle2 :: IO [String]

-- | Solve
--   <a>http://regexcrossword.com/challenges/palindromeda/puzzles/3</a>
--   
--   <pre>
--   &gt;&gt;&gt; puzzle3
--   ["RATS","ABUT","TUBA","STAR"]
--   </pre>
puzzle3 :: IO [String]


-- | Implement the symbolic evaluation of a language which operates on
--   strings in a way similar to bash. It's possible to do different
--   analyses, but this example finds program inputs which result in a
--   query containing a SQL injection.
module Documentation.SBV.Examples.Strings.SQLInjection

-- | Simple expression language
data SQLExpr
Query :: SQLExpr -> SQLExpr
Const :: String -> SQLExpr
Concat :: SQLExpr -> SQLExpr -> SQLExpr
ReadVar :: SQLExpr -> SQLExpr

-- | Evaluation monad. The state argument is the environment to store
--   variables as we evaluate.
type M = StateT (SArray String String) (WriterT [SString] Symbolic)

-- | Given an expression, symbolically evaluate it
eval :: SQLExpr -> M SString

-- | A simple program to query all messages with a given topic id. In SQL
--   like notation:
--   
--   <pre>
--   query ("SELECT msg FROM msgs where topicid='" ++ my_topicid ++ "'")
--   </pre>
exampleProgram :: SQLExpr

-- | Limit names to be at most 7 chars long, with simple letters.
nameRe :: RegExp

-- | Strings: Again, at most of length 5, surrounded by quotes.
strRe :: RegExp

-- | A "select" command:
selectRe :: RegExp

-- | A "drop" instruction, which can be exploited!
dropRe :: RegExp

-- | We'll greatly simplify here and say a statement is either a select or
--   a drop:
statementRe :: RegExp

-- | The exploit: We're looking for a DROP TABLE after at least one
--   legitimate command.
exploitRe :: RegExp

-- | Analyze the program for inputs which result in a SQL injection. There
--   are other possible injections, but in this example we're only looking
--   for a <tt>DROP TABLE</tt> command.
--   
--   Remember that our example program (in pseudo-code) is:
--   
--   <pre>
--   query ("SELECT msg FROM msgs WHERE topicid='" ++ my_topicid ++ "'")
--   </pre>
--   
--   Depending on your z3 version, you might see an output of the form:
--   
--   <pre>
--   ghci&gt; findInjection exampleProgram
--   "kg'; DROP TABLE 'users"
--   </pre>
--   
--   though the topic might change obviously. Indeed, if we substitute the
--   suggested string, we get the program:
--   
--   <pre>
--   query ("SELECT msg FROM msgs WHERE topicid='kg'; DROP TABLE 'users'")
--   </pre>
--   
--   which would query for topic <tt>kg</tt> and then delete the users
--   table!
--   
--   Here, we make sure that the injection ends with the malicious string:
--   
--   <pre>
--   &gt;&gt;&gt; ("'; DROP TABLE 'users" `Data.List.isSuffixOf`) &lt;$&gt; findInjection exampleProgram
--   True
--   </pre>
findInjection :: SQLExpr -> IO String
instance Data.String.IsString Documentation.SBV.Examples.Strings.SQLInjection.SQLExpr


-- | A demonstration of the use of the <a>SymbolicT</a> and <a>QueryT</a>
--   transformers in the setting of symbolic program evaluation.
--   
--   In this example, we perform symbolic evaluation across three steps:
--   
--   <ol>
--   <li>allocate free variables, so we can extract a model after
--   evaluation</li>
--   <li>perform symbolic evaluation of a program and an associated
--   property</li>
--   <li>querying the solver for whether it's possible to find a set of
--   program inputs that falsify the property. if there is, we extract a
--   model.</li>
--   </ol>
--   
--   To simplify the example, our programs always have exactly two integer
--   inputs named <tt>x</tt> and <tt>y</tt>.
module Documentation.SBV.Examples.Transformers.SymbolicEval

-- | Monad for allocating free variables.
newtype Alloc a
Alloc :: SymbolicT (ExceptT String IO) a -> Alloc a
[runAlloc] :: Alloc a -> SymbolicT (ExceptT String IO) a

-- | Environment holding allocated variables.
data Env
Env :: SBV Integer -> SBV Integer -> Maybe SVal -> Env
[envX] :: Env -> SBV Integer
[envY] :: Env -> SBV Integer
[result] :: Env -> Maybe SVal

-- | Allocate an integer variable with the provided name.
alloc :: String -> Alloc (SBV Integer)

-- | Allocate an <a>Env</a> holding all input variables for the program.
allocEnv :: Alloc Env

-- | The term language we use to express programs and properties.
data Term :: Type -> Type
[Var] :: String -> Term r
[Lit] :: Integer -> Term Integer
[Plus] :: Term Integer -> Term Integer -> Term Integer
[LessThan] :: Term Integer -> Term Integer -> Term Bool
[GreaterThan] :: Term Integer -> Term Integer -> Term Bool
[Equals] :: Term Integer -> Term Integer -> Term Bool
[Not] :: Term Bool -> Term Bool
[Or] :: Term Bool -> Term Bool -> Term Bool
[And] :: Term Bool -> Term Bool -> Term Bool
[Implies] :: Term Bool -> Term Bool -> Term Bool

-- | Monad for performing symbolic evaluation.
newtype Eval a
Eval :: ReaderT Env (Except String) a -> Eval a
[unEval] :: Eval a -> ReaderT Env (Except String) a

-- | Unsafe cast for symbolic values. In production code, we would check
--   types instead.
unsafeCastSBV :: SBV a -> SBV b

-- | Symbolic evaluation function for <a>Term</a>.
eval :: Term r -> Eval (SBV r)

-- | Runs symbolic evaluation, sending a <a>Term</a> to a symbolic value
--   (or failing). Used for symbolic evaluation of programs and properties.
runEval :: Env -> Term a -> Except String (SBV a)

-- | A program that can reference two input variables, <tt>x</tt> and
--   <tt>y</tt>.
newtype Program a
Program :: Term a -> Program a

-- | A symbolic value representing the result of running a program -- its
--   output.
newtype Result
Result :: SVal -> Result

-- | Makes a <a>Result</a> from a symbolic value.
mkResult :: SBV a -> Result

-- | Performs symbolic evaluation of a <a>Program</a>.
runProgramEval :: Env -> Program a -> Except String Result

-- | A property describes a quality of a <a>Program</a>. It is a
--   <a>Term</a> yields a boolean value.
newtype Property
Property :: Term Bool -> Property

-- | Performs symbolic evaluation of a 'Property.
runPropertyEval :: Result -> Env -> Property -> Except String (SBV Bool)

-- | The result of <a>check</a>ing the combination of a <a>Program</a> and
--   a <a>Property</a>.
data CheckResult
Proved :: CheckResult
Counterexample :: Integer -> Integer -> CheckResult

-- | Sends an <a>Identity</a> computation to an arbitrary monadic
--   computation.
generalize :: Monad m => Identity a -> m a

-- | Monad for querying a solver.
newtype Q a
Q :: QueryT (ExceptT String IO) a -> Q a
[runQ] :: Q a -> QueryT (ExceptT String IO) a

-- | Creates a computation that queries a solver and yields a
--   <a>CheckResult</a>.
mkQuery :: Env -> Q CheckResult

-- | Checks a <a>Property</a> of a <a>Program</a> (or fails).
check :: Program a -> Property -> IO (Either String CheckResult)

-- | Check that <tt>x+1+y</tt> generates a counter-example for the property
--   that the result is less than <tt>10</tt> when <tt>x+y</tt> is at least
--   <tt>9</tt>. We have:
--   
--   <pre>
--   &gt;&gt;&gt; ex1
--   Right (Counterexample 0 9)
--   </pre>
ex1 :: IO (Either String CheckResult)

-- | Check that the program <tt>x+y</tt> correctly produces a result
--   greater than <tt>1</tt> when both <tt>x</tt> and <tt>y</tt> are at
--   least <tt>1</tt>. We have:
--   
--   <pre>
--   &gt;&gt;&gt; ex2
--   Right Proved
--   </pre>
ex2 :: IO (Either String CheckResult)

-- | Check that we catch the cases properly through the monad stack when
--   there is a syntax error, like an undefined variable. We have:
--   
--   <pre>
--   &gt;&gt;&gt; ex3
--   Left "unknown variable"
--   </pre>
ex3 :: IO (Either String CheckResult)
instance Data.SBV.Core.Symbolic.MonadSymbolic Documentation.SBV.Examples.Transformers.SymbolicEval.Alloc
instance Control.Monad.Error.Class.MonadError GHC.Base.String Documentation.SBV.Examples.Transformers.SymbolicEval.Alloc
instance Control.Monad.IO.Class.MonadIO Documentation.SBV.Examples.Transformers.SymbolicEval.Alloc
instance GHC.Base.Monad Documentation.SBV.Examples.Transformers.SymbolicEval.Alloc
instance GHC.Base.Applicative Documentation.SBV.Examples.Transformers.SymbolicEval.Alloc
instance GHC.Base.Functor Documentation.SBV.Examples.Transformers.SymbolicEval.Alloc
instance GHC.Show.Show Documentation.SBV.Examples.Transformers.SymbolicEval.Env
instance GHC.Classes.Eq Documentation.SBV.Examples.Transformers.SymbolicEval.Env
instance Control.Monad.Error.Class.MonadError GHC.Base.String Documentation.SBV.Examples.Transformers.SymbolicEval.Eval
instance Control.Monad.Reader.Class.MonadReader Documentation.SBV.Examples.Transformers.SymbolicEval.Env Documentation.SBV.Examples.Transformers.SymbolicEval.Eval
instance GHC.Base.Monad Documentation.SBV.Examples.Transformers.SymbolicEval.Eval
instance GHC.Base.Applicative Documentation.SBV.Examples.Transformers.SymbolicEval.Eval
instance GHC.Base.Functor Documentation.SBV.Examples.Transformers.SymbolicEval.Eval
instance GHC.Show.Show Documentation.SBV.Examples.Transformers.SymbolicEval.CheckResult
instance GHC.Classes.Eq Documentation.SBV.Examples.Transformers.SymbolicEval.CheckResult
instance Data.SBV.Core.Symbolic.MonadQuery Documentation.SBV.Examples.Transformers.SymbolicEval.Q
instance Control.Monad.Error.Class.MonadError GHC.Base.String Documentation.SBV.Examples.Transformers.SymbolicEval.Q
instance Control.Monad.IO.Class.MonadIO Documentation.SBV.Examples.Transformers.SymbolicEval.Q
instance GHC.Base.Monad Documentation.SBV.Examples.Transformers.SymbolicEval.Q
instance GHC.Base.Applicative Documentation.SBV.Examples.Transformers.SymbolicEval.Q
instance GHC.Base.Functor Documentation.SBV.Examples.Transformers.SymbolicEval.Q


-- | Formalizes and proves the following theorem, about arithmetic,
--   uninterpreted functions, and arrays. (For reference, see
--   <a>http://research.microsoft.com/en-us/um/redmond/projects/z3/fmcad06-slides.pdf</a>
--   slide number 24):
--   
--   <pre>
--   x + 2 = y  implies  f (read (write (a, x, 3), y - 2)) = f (y - x + 1)
--   </pre>
--   
--   We interpret the types as follows (other interpretations certainly
--   possible):
--   
--   <ul>
--   <li><i><i>x</i></i> <a>SWord32</a> (32-bit unsigned address)</li>
--   <li><i><i>y</i></i> <a>SWord32</a> (32-bit unsigned address)</li>
--   <li><i><i>a</i></i> An array, indexed by 32-bit addresses, returning
--   32-bit unsigned integers</li>
--   <li><i><i>f</i></i> An uninterpreted function of type
--   <tt><a>SWord32</a> -&gt; <a>SWord64</a></tt></li>
--   </ul>
--   
--   The function <tt>read</tt> and <tt>write</tt> are usual array
--   operations.
module Documentation.SBV.Examples.Uninterpreted.AUF

-- | Uninterpreted function in the theorem
f :: SWord32 -> SWord64

-- | Correctness theorem. We state it for all values of <tt>x</tt>,
--   <tt>y</tt>, and the given array <tt>a</tt>. Note that we're being
--   generic in the type of array we're expecting.
thm :: SymArray a => SWord32 -> SWord32 -> a Word32 Word32 -> SBool

-- | Prove it using SMT-Lib arrays.
--   
--   <pre>
--   &gt;&gt;&gt; proveSArray
--   Q.E.D.
--   </pre>
proveSArray :: IO ThmResult


-- | Demonstrates uninterpreted sorts and how they can be used for
--   deduction. This example is inspired by the discussion at
--   <a>http://stackoverflow.com/questions/10635783/using-axioms-for-deductions-in-z3</a>,
--   essentially showing how to show the required deduction using SBV.
module Documentation.SBV.Examples.Uninterpreted.Deduce

-- | The uninterpreted sort <a>B</a>, corresponding to the carrier.
data B

-- | Symbolic version of the type <a>B</a>.
type SB = SBV B

-- | Uninterpreted logical connective <a>and</a>
and :: SB -> SB -> SB

-- | Uninterpreted logical connective <a>or</a>
or :: SB -> SB -> SB

-- | Uninterpreted logical connective <a>not</a>
not :: SB -> SB

-- | Proves the equivalence <tt>NOT (p OR (q AND r)) == (NOT p AND NOT q)
--   OR (NOT p AND NOT r)</tt>, following from the axioms we have specified
--   above. We have:
--   
--   <pre>
--   &gt;&gt;&gt; test
--   Q.E.D.
--   </pre>
test :: IO ThmResult
instance GHC.Show.Show Documentation.SBV.Examples.Uninterpreted.Deduce.B
instance GHC.Read.Read Documentation.SBV.Examples.Uninterpreted.Deduce.B
instance Data.Data.Data Documentation.SBV.Examples.Uninterpreted.Deduce.B
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Uninterpreted.Deduce.B
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Uninterpreted.Deduce.B
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Uninterpreted.Deduce.B


-- | Demonstrates function counter-examples
module Documentation.SBV.Examples.Uninterpreted.Function

-- | An uninterpreted function
f :: SWord8 -> SWord8 -> SWord16

-- | Asserts that <tt>f x z == f (y+2) z</tt> whenever <tt>x == y+2</tt>.
--   Naturally correct:
--   
--   <pre>
--   &gt;&gt;&gt; prove thmGood
--   Q.E.D.
--   </pre>
thmGood :: SWord8 -> SWord8 -> SWord8 -> SBool


-- | Demonstrates how to use uninterpreted function models to synthesize a
--   simple two-bit multiplier.
module Documentation.SBV.Examples.Uninterpreted.Multiply

-- | The uninterpreted implementation of our 2x2 multiplier. We simply
--   receive two 2-bit values, and return the high and the low bit of the
--   resulting multiplication via two uninterpreted functions that we
--   called <tt>mul22_hi</tt> and <tt>mul22_lo</tt>. Note that there is
--   absolutely no computation going on here, aside from simply passing the
--   arguments to the uninterpreted functions and stitching it back
--   together.
--   
--   NB. While defining <tt>mul22_lo</tt> we used our domain knowledge that
--   the low-bit of the multiplication only depends on the low bits of the
--   inputs. However, this is merely a simplifying assumption; we could
--   have passed all the arguments as well.
mul22 :: (SBool, SBool) -> (SBool, SBool) -> (SBool, SBool)

-- | Synthesize a 2x2 multiplier. We use 8-bit inputs merely because that
--   is the lowest bit-size SBV supports but that is more or less
--   irrelevant. (Larger sizes would work too.) We simply assert this for
--   all input values, extract the bottom two bits, and assert that our
--   "uninterpreted" implementation in <a>mul22</a> is precisely the same.
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; sat synthMul22
--   Satisfiable. Model:
--     mul22_hi :: Bool -&gt; Bool -&gt; Bool -&gt; Bool -&gt; Bool
--     mul22_hi True  False False True  = True
--     mul22_hi True  True  False True  = True
--     mul22_hi False True  True  True  = True
--     mul22_hi True  False True  True  = True
--     mul22_hi False True  True  False = True
--     mul22_hi True  True  True  False = True
--     mul22_hi _     _     _     _     = False
--   
--     mul22_lo :: Bool -&gt; Bool -&gt; Bool
--     mul22_lo True True = True
--     mul22_lo _    _    = False
--   </pre>
--   
--   It is easy to see that the low bit is simply the logical-and of the
--   low bits. It takes a moment of staring, but you can see that the high
--   bit is correct as well: The logical formula is <tt>a1b xor a0b1</tt>,
--   and if you work out the truth-table presented, you'll see that it is
--   exactly that. Of course, you can use SBV to prove this. First, let's
--   define the function we have synthesized into a symbolic function:
--   
--   <pre>
--   &gt;&gt;&gt; :{
--   mul22_hi :: (SBool, SBool, SBool, SBool) -&gt; SBool
--   mul22_hi params = params `sElem` [ (sTrue,  sFalse, sFalse, sTrue)
--                                    , (sTrue,  sTrue,  sFalse, sTrue)
--                                    , (sFalse, sTrue,  sTrue,  sTrue)
--                                    , (sTrue,  sFalse, sTrue,  sTrue)
--                                    , (sFalse, sTrue,  sTrue,  sFalse)
--                                    , (sTrue,  sTrue,  sTrue,  sFalse)
--                                    ]
--   :}
--   </pre>
--   
--   Now we can say:
--   
--   <pre>
--   &gt;&gt;&gt; prove $ \a1 a0 b1 b0 -&gt; mul22_hi (a1, a0, b1, b0) .== (a1 .&amp;&amp; b0) .&lt;+&gt; (a0 .&amp;&amp; b1)
--   Q.E.D.
--   </pre>
--   
--   and rest assured that we have a correctly synthesized circuit!
synthMul22 :: ConstraintSet


-- | Proves (instances of) Shannon's expansion theorem and other relevant
--   facts. See: <a>http://en.wikipedia.org/wiki/Shannon's_expansion</a>
module Documentation.SBV.Examples.Uninterpreted.Shannon

-- | A ternary boolean function
type Ternary = SBool -> SBool -> SBool -> SBool

-- | A binary boolean function
type Binary = SBool -> SBool -> SBool

-- | Positive Shannon cofactor of a boolean function, with respect to its
--   first argument
pos :: (SBool -> a) -> a

-- | Negative Shannon cofactor of a boolean function, with respect to its
--   first argument
neg :: (SBool -> a) -> a

-- | Shannon's expansion over the first argument of a function. We have:
--   
--   <pre>
--   &gt;&gt;&gt; shannon
--   Q.E.D.
--   </pre>
shannon :: IO ThmResult

-- | Alternative form of Shannon's expansion over the first argument of a
--   function. We have:
--   
--   <pre>
--   &gt;&gt;&gt; shannon2
--   Q.E.D.
--   </pre>
shannon2 :: IO ThmResult

-- | Computing the derivative of a boolean function (boolean difference).
--   Defined as exclusive-or of Shannon cofactors with respect to that
--   variable.
derivative :: Ternary -> Binary

-- | The no-wiggle theorem: If the derivative of a function with respect to
--   a variable is constant False, then that variable does not "wiggle" the
--   function; i.e., any changes to it won't affect the result of the
--   function. In fact, we have an equivalence: The variable only changes
--   the result of the function iff the derivative with respect to it is
--   not False:
--   
--   <pre>
--   &gt;&gt;&gt; noWiggle
--   Q.E.D.
--   </pre>
noWiggle :: IO ThmResult

-- | Universal quantification of a boolean function with respect to a
--   variable. Simply defined as the conjunction of the Shannon cofactors.
universal :: Ternary -> Binary

-- | Show that universal quantification is really meaningful: That is, if
--   the universal quantification with respect to a variable is True, then
--   both cofactors are true for those arguments. Of course, this is a
--   trivial theorem if you think about it for a moment, or you can just
--   let SBV prove it for you:
--   
--   <pre>
--   &gt;&gt;&gt; univOK
--   Q.E.D.
--   </pre>
univOK :: IO ThmResult

-- | Existential quantification of a boolean function with respect to a
--   variable. Simply defined as the conjunction of the Shannon cofactors.
existential :: Ternary -> Binary

-- | Show that existential quantification is really meaningful: That is, if
--   the existential quantification with respect to a variable is True,
--   then one of the cofactors must be true for those arguments. Again,
--   this is a trivial theorem if you think about it for a moment, but we
--   will just let SBV prove it:
--   
--   <pre>
--   &gt;&gt;&gt; existsOK
--   Q.E.D.
--   </pre>
existsOK :: IO ThmResult


-- | Demonstrates uninterpreted sorts, together with axioms.
module Documentation.SBV.Examples.Uninterpreted.Sort

-- | A new data-type that we expect to use in an uninterpreted fashion in
--   the backend SMT solver.
data Q

-- | Symbolic version of the type <a>Q</a>.
type SQ = SBV Q

-- | Declare an uninterpreted function that works over Q's
f :: SQ -> SQ

-- | A satisfiable example, stating that there is an element of the domain
--   <a>Q</a> such that <a>f</a> returns a different element. Note that
--   this is valid only when the domain <a>Q</a> has at least two elements.
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; t1
--   Satisfiable. Model:
--     x = Q!val!0 :: Q
--   
--     f :: Q -&gt; Q
--     f _ = Q!val!1
--   </pre>
t1 :: IO SatResult

-- | This is a variant on the first example, except we also add an axiom
--   for the sort, stating that the domain <a>Q</a> has only one element.
--   In this case the problem naturally becomes unsat. We have:
--   
--   <pre>
--   &gt;&gt;&gt; t2
--   Unsatisfiable
--   </pre>
t2 :: IO SatResult
instance GHC.Show.Show Documentation.SBV.Examples.Uninterpreted.Sort.Q
instance GHC.Read.Read Documentation.SBV.Examples.Uninterpreted.Sort.Q
instance Data.Data.Data Documentation.SBV.Examples.Uninterpreted.Sort.Q
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Uninterpreted.Sort.Q
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Uninterpreted.Sort.Q
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Uninterpreted.Sort.Q


-- | Demonstrates uninterpreted sorts and how all-sat behaves for them.
--   Thanks to Eric Seidel for the idea.
module Documentation.SBV.Examples.Uninterpreted.UISortAllSat

-- | A "list-like" data type, but one we plan to uninterpret at the SMT
--   level. The actual shape is really immaterial for us.
data L

-- | Symbolic version of the type <a>L</a>.
type SL = SBV L

-- | An uninterpreted "classify" function. Really, we only care about the
--   fact that such a function exists, not what it does.
classify :: SL -> SInteger

-- | Formulate a query that essentially asserts a cardinality constraint on
--   the uninterpreted sort <a>L</a>. The goal is to say there are
--   precisely 3 such things, as it might be the case. We manage this by
--   declaring four elements, and asserting that for a free variable of
--   this sort, the shape of the data matches one of these three instances.
--   That is, we assert that all the instances of the data <a>L</a> can be
--   classified into 3 equivalence classes. Then, allSat returns all the
--   possible instances, which of course are all uninterpreted.
--   
--   As expected, we have:
--   
--   <pre>
--   &gt;&gt;&gt; allSat genLs
--   Solution #1:
--     l  = L!val!2 :: L
--     l0 = L!val!0 :: L
--     l1 = L!val!1 :: L
--     l2 = L!val!2 :: L
--   
--     classify :: L -&gt; Integer
--     classify L!val!2 = 2
--     classify L!val!1 = 1
--     classify _       = 0
--   Solution #2:
--     l  = L!val!1 :: L
--     l0 = L!val!0 :: L
--     l1 = L!val!1 :: L
--     l2 = L!val!2 :: L
--   
--     classify :: L -&gt; Integer
--     classify L!val!2 = 2
--     classify L!val!1 = 1
--     classify _       = 0
--   Solution #3:
--     l  = L!val!0 :: L
--     l0 = L!val!0 :: L
--     l1 = L!val!1 :: L
--     l2 = L!val!2 :: L
--   
--     classify :: L -&gt; Integer
--     classify L!val!2 = 2
--     classify L!val!1 = 1
--     classify _       = 0
--   Found 3 different solutions.
--   </pre>
genLs :: Predicate
instance GHC.Show.Show Documentation.SBV.Examples.Uninterpreted.UISortAllSat.L
instance GHC.Read.Read Documentation.SBV.Examples.Uninterpreted.UISortAllSat.L
instance Data.Data.Data Documentation.SBV.Examples.Uninterpreted.UISortAllSat.L
instance Data.SBV.Core.Data.SymVal Documentation.SBV.Examples.Uninterpreted.UISortAllSat.L
instance Data.SBV.Core.Kind.HasKind Documentation.SBV.Examples.Uninterpreted.UISortAllSat.L
instance Data.SBV.SMT.SMT.SatModel Documentation.SBV.Examples.Uninterpreted.UISortAllSat.L


-- | Proof of correctness of an imperative list-append algorithm, using
--   weakest preconditions. Illustrates the use of SBV's symbolic lists
--   together with the WP algorithm.
module Documentation.SBV.Examples.WeakestPreconditions.Append

-- | The state of the length program, paramaterized over the element type
--   <tt>a</tt>
data AppS a
AppS :: SList a -> SList a -> SList a -> SList a -> AppS a

-- | The first input list
[xs] :: AppS a -> SList a

-- | The second input list
[ys] :: AppS a -> SList a

-- | Temporary variable
[ts] :: AppS a -> SList a

-- | Output
[zs] :: AppS a -> SList a

-- | The concrete counterpart of <a>AppS</a>. Again, we can't simply use
--   the duality between <tt>SBV a</tt> and <tt>a</tt> due to the
--   difference between <tt>SList a</tt> and <tt>[a]</tt>.
data AppC a
AppC :: [a] -> [a] -> [a] -> [a] -> AppC a

-- | Helper type synonym
type A = AppS Integer

-- | The imperative append algorithm:
--   
--   <pre>
--   zs = []
--   ts = xs
--   while not (null ts)
--     zs = zs ++ [head ts]
--     ts = tail ts
--   ts = ys
--   while not (null ts)
--     zs = zs ++ [head ts]
--     ts = tail ts
--   </pre>
algorithm :: Stmt A

-- | A program is the algorithm, together with its pre- and
--   post-conditions.
imperativeAppend :: Program A

-- | We check that <tt>zs</tt> is <tt>xs ++ ys</tt> upon termination.
--   
--   <pre>
--   &gt;&gt;&gt; correctness
--   Total correctness is established.
--   Q.E.D.
--   </pre>
correctness :: IO (ProofResult (AppC Integer))
instance Data.SBV.Core.Data.SymVal a => Data.SBV.Core.Model.Mergeable (Documentation.SBV.Examples.WeakestPreconditions.Append.AppS a)
instance GHC.Generics.Generic (Documentation.SBV.Examples.WeakestPreconditions.Append.AppS a)
instance GHC.Show.Show a => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.Append.AppC a)
instance Data.SBV.Core.Symbolic.Queriable GHC.Types.IO (Documentation.SBV.Examples.WeakestPreconditions.Append.AppS GHC.Num.Integer.Integer)
instance (Data.SBV.Core.Data.SymVal a, GHC.Show.Show a) => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.Append.AppS a)


-- | Some basic aspects of weakest preconditions, demonstrating programs
--   that do not use while loops. We use a simple increment program as an
--   example.
module Documentation.SBV.Examples.WeakestPreconditions.Basics

-- | The state for the swap program, parameterized over a base type
--   <tt>a</tt>.
data IncS a
IncS :: a -> a -> IncS a

-- | Input value
[x] :: IncS a -> a

-- | Output
[y] :: IncS a -> a

-- | Helper type synonym
type I = IncS SInteger

-- | The increment algorithm:
--   
--   <pre>
--   y = x+1
--   </pre>
--   
--   The point here isn't really that this program is interesting, but we
--   want to demonstrate various aspects of WP proofs. So, we take a before
--   and after program to annotate our algorithm so we can experiment
--   later.
algorithm :: Stmt I -> Stmt I -> Stmt I

-- | Precondition for our program. Strictly speaking, we don't really need
--   any preconditions, but for example purposes, we'll require <tt>x</tt>
--   to be non-negative.
pre :: I -> SBool

-- | Postcondition for our program: <tt>y</tt> must equal <tt>x+1</tt>.
post :: I -> SBool

-- | Stability: <tt>x</tt> must remain unchanged.
noChange :: Stable I

-- | A program is the algorithm, together with its pre- and
--   post-conditions.
imperativeInc :: Stmt I -> Stmt I -> Program I

-- | State the correctness with respect to before/after programs. In the
--   simple case of nothing prior/after, we have the obvious proof:
--   
--   <pre>
--   &gt;&gt;&gt; correctness Skip Skip
--   Total correctness is established.
--   Q.E.D.
--   </pre>
correctness :: Stmt I -> Stmt I -> IO (ProofResult (IncS Integer))
instance Data.Traversable.Traversable Documentation.SBV.Examples.WeakestPreconditions.Basics.IncS
instance Data.Foldable.Foldable Documentation.SBV.Examples.WeakestPreconditions.Basics.IncS
instance GHC.Base.Functor Documentation.SBV.Examples.WeakestPreconditions.Basics.IncS
instance Data.SBV.Core.Model.Mergeable a => Data.SBV.Core.Model.Mergeable (Documentation.SBV.Examples.WeakestPreconditions.Basics.IncS a)
instance GHC.Generics.Generic (Documentation.SBV.Examples.WeakestPreconditions.Basics.IncS a)
instance GHC.Show.Show a => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.Basics.IncS a)
instance (Data.SBV.Core.Data.SymVal a, GHC.Show.Show a) => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.Basics.IncS (Data.SBV.Core.Data.SBV a))
instance Data.SBV.Core.Data.SymVal a => Data.SBV.Core.Symbolic.Fresh GHC.Types.IO (Documentation.SBV.Examples.WeakestPreconditions.Basics.IncS (Data.SBV.Core.Data.SBV a))


-- | Proof of correctness of an imperative fibonacci algorithm, using
--   weakest preconditions. Note that due to the recursive nature of
--   fibonacci, we cannot write the spec directly, so we use an
--   uninterpreted function and proper axioms to complete the proof.
module Documentation.SBV.Examples.WeakestPreconditions.Fib

-- | The state for the sum program, parameterized over a base type
--   <tt>a</tt>.
data FibS a
FibS :: a -> a -> a -> a -> FibS a

-- | The input value
[n] :: FibS a -> a

-- | Loop counter
[i] :: FibS a -> a

-- | tracks <tt>fib (i+1)</tt>
[k] :: FibS a -> a

-- | tracks <tt>fib i</tt>
[m] :: FibS a -> a

-- | Helper type synonym
type F = FibS SInteger

-- | The imperative fibonacci algorithm:
--   
--   <pre>
--   i = 0
--   k = 1
--   m = 0
--   while i &lt; n:
--      m, k = k, m + k
--      i++
--   </pre>
--   
--   When the loop terminates, <tt>m</tt> contains <tt>fib(n)</tt>.
algorithm :: Stmt F

-- | Symbolic fibonacci as our specification. Note that we cannot really
--   implement the fibonacci function since it is not symbolically
--   terminating. So, we instead uninterpret and axiomatize it below.
--   
--   NB. The concrete part of the definition is only used in calls to
--   <a>traceExecution</a> and is not needed for the proof. If you don't
--   need to call <a>traceExecution</a>, you can simply ignore that part
--   and directly uninterpret.
fib :: SInteger -> SInteger

-- | Constraints and axioms we need to state explicitly to tell the SMT
--   solver about our specification for fibonacci.
axiomatizeFib :: Symbolic ()

-- | Precondition for our program: <tt>n</tt> must be non-negative.
pre :: F -> SBool

-- | Postcondition for our program: <tt>m = fib n</tt>
post :: F -> SBool

-- | Stability condition: Program must leave <tt>n</tt> unchanged.
noChange :: Stable F

-- | A program is the algorithm, together with its pre- and
--   post-conditions.
imperativeFib :: Program F

-- | With the axioms in place, it is trivial to establish correctness:
--   
--   <pre>
--   &gt;&gt;&gt; correctness
--   Total correctness is established.
--   Q.E.D.
--   </pre>
--   
--   Note that I found this proof to be quite fragile: If you do not get
--   the algorithm right or the axioms aren't in place, z3 simply goes to
--   an infinite loop, instead of providing counter-examples. Of course,
--   this is to be expected with the quantifiers present.
correctness :: IO (ProofResult (FibS Integer))
instance Data.Traversable.Traversable Documentation.SBV.Examples.WeakestPreconditions.Fib.FibS
instance Data.Foldable.Foldable Documentation.SBV.Examples.WeakestPreconditions.Fib.FibS
instance GHC.Base.Functor Documentation.SBV.Examples.WeakestPreconditions.Fib.FibS
instance Data.SBV.Core.Model.Mergeable a => Data.SBV.Core.Model.Mergeable (Documentation.SBV.Examples.WeakestPreconditions.Fib.FibS a)
instance GHC.Generics.Generic (Documentation.SBV.Examples.WeakestPreconditions.Fib.FibS a)
instance GHC.Show.Show a => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.Fib.FibS a)
instance (Data.SBV.Core.Data.SymVal a, GHC.Show.Show a) => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.Fib.FibS (Data.SBV.Core.Data.SBV a))
instance Data.SBV.Core.Data.SymVal a => Data.SBV.Core.Symbolic.Fresh GHC.Types.IO (Documentation.SBV.Examples.WeakestPreconditions.Fib.FibS (Data.SBV.Core.Data.SBV a))


-- | Proof of correctness of an imperative GCD (greatest-common divisor)
--   algorithm, using weakest preconditions. The termination measure here
--   illustrates the use of lexicographic ordering. Also, since symbolic
--   version of GCD is not symbolically terminating, this is another
--   example of using uninterpreted functions and axioms as one writes
--   specifications for WP proofs.
module Documentation.SBV.Examples.WeakestPreconditions.GCD

-- | The state for the sum program, parameterized over a base type
--   <tt>a</tt>.
data GCDS a
GCDS :: a -> a -> a -> a -> GCDS a

-- | First value
[x] :: GCDS a -> a

-- | Second value
[y] :: GCDS a -> a

-- | Copy of x to be modified
[i] :: GCDS a -> a

-- | Copy of y to be modified
[j] :: GCDS a -> a

-- | Helper type synonym
type G = GCDS SInteger

-- | The imperative GCD algorithm, assuming strictly positive <tt>x</tt>
--   and <tt>y</tt>:
--   
--   <pre>
--   i = x
--   j = y
--   while i != j      -- While not equal
--     if i &gt; j
--        i = i - j    -- i is greater; reduce it by j
--     else
--        j = j - i    -- j is greater; reduce it by i
--   </pre>
--   
--   When the loop terminates, <tt>i</tt> equals <tt>j</tt> and contains
--   <tt>GCD(x, y)</tt>.
algorithm :: Stmt G

-- | Symbolic GCD as our specification. Note that we cannot really
--   implement the GCD function since it is not symbolically terminating.
--   So, we instead uninterpret and axiomatize it below.
--   
--   NB. The concrete part of the definition is only used in calls to
--   <a>traceExecution</a> and is not needed for the proof. If you don't
--   need to call <a>traceExecution</a>, you can simply ignore that part
--   and directly uninterpret. In that case, we simply use Prelude's
--   version.
gcd :: SInteger -> SInteger -> SInteger

-- | Constraints and axioms we need to state explicitly to tell the SMT
--   solver about our specification for GCD.
axiomatizeGCD :: Symbolic ()

-- | Precondition for our program: <tt>x</tt> and <tt>y</tt> must be
--   strictly positive
pre :: G -> SBool

-- | Postcondition for our program: <tt>i == j</tt> and <tt>i = gcd x
--   y</tt>
post :: G -> SBool

-- | Stability condition: Program must leave <tt>x</tt> and <tt>y</tt>
--   unchanged.
noChange :: Stable G

-- | A program is the algorithm, together with its pre- and
--   post-conditions.
imperativeGCD :: Program G

-- | With the axioms in place, it is trivial to establish correctness:
--   
--   <pre>
--   &gt;&gt;&gt; correctness
--   Total correctness is established.
--   Q.E.D.
--   </pre>
--   
--   Note that I found this proof to be quite fragile: If you do not get
--   the algorithm right or the axioms aren't in place, z3 simply goes to
--   an infinite loop, instead of providing counter-examples. Of course,
--   this is to be expected with the quantifiers present.
correctness :: IO (ProofResult (GCDS Integer))
instance Data.Traversable.Traversable Documentation.SBV.Examples.WeakestPreconditions.GCD.GCDS
instance Data.Foldable.Foldable Documentation.SBV.Examples.WeakestPreconditions.GCD.GCDS
instance GHC.Base.Functor Documentation.SBV.Examples.WeakestPreconditions.GCD.GCDS
instance Data.SBV.Core.Model.Mergeable a => Data.SBV.Core.Model.Mergeable (Documentation.SBV.Examples.WeakestPreconditions.GCD.GCDS a)
instance GHC.Generics.Generic (Documentation.SBV.Examples.WeakestPreconditions.GCD.GCDS a)
instance GHC.Show.Show a => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.GCD.GCDS a)
instance (Data.SBV.Core.Data.SymVal a, GHC.Show.Show a) => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.GCD.GCDS (Data.SBV.Core.Data.SBV a))
instance Data.SBV.Core.Data.SymVal a => Data.SBV.Core.Symbolic.Fresh GHC.Types.IO (Documentation.SBV.Examples.WeakestPreconditions.GCD.GCDS (Data.SBV.Core.Data.SBV a))


-- | Proof of correctness of an imperative integer division algorithm,
--   using weakest preconditions. The algorithm simply keeps subtracting
--   the divisor until the desired quotient and the remainder is found.
module Documentation.SBV.Examples.WeakestPreconditions.IntDiv

-- | The state for the division program, parameterized over a base type
--   <tt>a</tt>.
data DivS a
DivS :: a -> a -> a -> a -> DivS a

-- | The dividend
[x] :: DivS a -> a

-- | The divisor
[y] :: DivS a -> a

-- | The quotient
[q] :: DivS a -> a

-- | The remainder
[r] :: DivS a -> a

-- | Helper type synonym
type D = DivS SInteger

-- | The imperative division algorithm, assuming non-negative <tt>x</tt>
--   and strictly positive <tt>y</tt>:
--   
--   <pre>
--   r = x                     -- set remainder to x
--   q = 0                     -- set quotient  to 0
--   while y &lt;= r              -- while we can still subtract
--     r = r - y                    -- reduce the remainder
--     q = q + 1                    -- increase the quotient
--   </pre>
--   
--   Note that we need to explicitly annotate each loop with its invariant
--   and the termination measure. For convenience, we take those two as
--   parameters for simplicity.
algorithm :: Invariant D -> Maybe (Measure D) -> Stmt D

-- | Precondition for our program: <tt>x</tt> must non-negative and
--   <tt>y</tt> must be strictly positive. Note that there is an explicit
--   call to <a>abort</a> in our program to protect against this case, so
--   if we do not have this precondition, all programs will fail.
pre :: D -> SBool

-- | Postcondition for our program: Remainder must be non-negative and less
--   than <tt>y</tt>, and it must hold that <tt>x = q*y + r</tt>:
post :: D -> SBool

-- | Stability: <tt>x</tt> and <tt>y</tt> must remain unchanged.
noChange :: Stable D

-- | A program is the algorithm, together with its pre- and
--   post-conditions.
imperativeDiv :: Invariant D -> Maybe (Measure D) -> Program D

-- | The invariant is simply that <tt>x = q * y + r</tt> holds at all times
--   and <tt>r</tt> is strictly positive. We need the <tt>y &gt; 0</tt>
--   part of the invariant to establish the measure decreases, which is
--   guaranteed by our precondition.
invariant :: Invariant D

-- | The measure. In each iteration <tt>r</tt> decreases, but always
--   remains positive. Since <tt>y</tt> is strictly positive, <tt>r</tt>
--   can serve as a measure for the loop.
measure :: Measure D

-- | Check that the program terminates and the post condition holds. We
--   have:
--   
--   <pre>
--   &gt;&gt;&gt; correctness
--   Total correctness is established.
--   Q.E.D.
--   </pre>
correctness :: IO ()
instance Data.Traversable.Traversable Documentation.SBV.Examples.WeakestPreconditions.IntDiv.DivS
instance Data.Foldable.Foldable Documentation.SBV.Examples.WeakestPreconditions.IntDiv.DivS
instance GHC.Base.Functor Documentation.SBV.Examples.WeakestPreconditions.IntDiv.DivS
instance Data.SBV.Core.Model.Mergeable a => Data.SBV.Core.Model.Mergeable (Documentation.SBV.Examples.WeakestPreconditions.IntDiv.DivS a)
instance GHC.Generics.Generic (Documentation.SBV.Examples.WeakestPreconditions.IntDiv.DivS a)
instance GHC.Show.Show a => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.IntDiv.DivS a)
instance (Data.SBV.Core.Data.SymVal a, GHC.Show.Show a) => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.IntDiv.DivS (Data.SBV.Core.Data.SBV a))
instance Data.SBV.Core.Data.SymVal a => Data.SBV.Core.Symbolic.Fresh GHC.Types.IO (Documentation.SBV.Examples.WeakestPreconditions.IntDiv.DivS (Data.SBV.Core.Data.SBV a))


-- | Proof of correctness of an imperative integer square-root algorithm,
--   using weakest preconditions. The algorithm computes the floor of the
--   square-root of a given non-negative integer by keeping a running some
--   of all odd numbers starting from 1. Recall that <tt>1+3+5+...+(2n+1) =
--   (n+1)^2</tt>, thus we can stop the counting when we exceed the input
--   number.
module Documentation.SBV.Examples.WeakestPreconditions.IntSqrt

-- | The state for the division program, parameterized over a base type
--   <tt>a</tt>.
data SqrtS a
SqrtS :: a -> a -> a -> a -> SqrtS a

-- | The input
[x] :: SqrtS a -> a

-- | The floor of the square root
[sqrt] :: SqrtS a -> a

-- | Successive squares, as the sum of j's
[i] :: SqrtS a -> a

-- | Successive odds
[j] :: SqrtS a -> a

-- | Helper type synonym
type S = SqrtS SInteger

-- | The imperative square-root algorithm, assuming non-negative <tt>x</tt>
--   
--   <pre>
--   sqrt = 0                  -- set sqrt to 0
--   i    = 1                  -- set i to 1, sum of j's so far
--   j    = 1                  -- set j to be the first odd number i
--   while i &lt;= x              -- while the sum hasn't exceeded x yet
--     sqrt = sqrt + 1              -- increase the sqrt
--     j    = j + 2                 -- next odd number
--     i    = i + j                 -- running sum of j's
--   </pre>
--   
--   Note that we need to explicitly annotate each loop with its invariant
--   and the termination measure. For convenience, we take those two as
--   parameters for simplicity.
algorithm :: Invariant S -> Maybe (Measure S) -> Stmt S

-- | Precondition for our program: <tt>x</tt> must be non-negative. Note
--   that there is an explicit call to <a>abort</a> in our program to
--   protect against this case, so if we do not have this precondition, all
--   programs will fail.
pre :: S -> SBool

-- | Postcondition for our program: The <tt>sqrt</tt> squared must be less
--   than or equal to <tt>x</tt>, and <tt>sqrt+1</tt> squared must strictly
--   exceed <tt>x</tt>.
post :: S -> SBool

-- | Stability condition: Program must leave <tt>x</tt> unchanged.
noChange :: Stable S

-- | A program is the algorithm, together with its pre- and
--   post-conditions.
imperativeSqrt :: Invariant S -> Maybe (Measure S) -> Program S

-- | The invariant is that at each iteration of the loop <tt>sqrt</tt>
--   remains below or equal to the actual square-root, and <tt>i</tt>
--   tracks the square of the next value. We also have that <tt>j</tt> is
--   the <tt>sqrt</tt>'th odd value. Coming up with this invariant is not
--   for the faint of heart, for details I would strongly recommend looking
--   at Manna's seminal <i>Mathematical Theory of Computation</i> book
--   (chapter 3). The <tt>j .&gt; 0</tt> part is needed to establish the
--   termination.
invariant :: Invariant S

-- | The measure. In each iteration <tt>i</tt> strictly increases, thus
--   reducing the differential <tt>x - i</tt>
measure :: Measure S

-- | Check that the program terminates and the post condition holds. We
--   have:
--   
--   <pre>
--   &gt;&gt;&gt; correctness
--   Total correctness is established.
--   Q.E.D.
--   </pre>
correctness :: IO ()
instance Data.Traversable.Traversable Documentation.SBV.Examples.WeakestPreconditions.IntSqrt.SqrtS
instance Data.Foldable.Foldable Documentation.SBV.Examples.WeakestPreconditions.IntSqrt.SqrtS
instance GHC.Base.Functor Documentation.SBV.Examples.WeakestPreconditions.IntSqrt.SqrtS
instance Data.SBV.Core.Model.Mergeable a => Data.SBV.Core.Model.Mergeable (Documentation.SBV.Examples.WeakestPreconditions.IntSqrt.SqrtS a)
instance GHC.Generics.Generic (Documentation.SBV.Examples.WeakestPreconditions.IntSqrt.SqrtS a)
instance GHC.Show.Show a => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.IntSqrt.SqrtS a)
instance (Data.SBV.Core.Data.SymVal a, GHC.Show.Show a) => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.IntSqrt.SqrtS (Data.SBV.Core.Data.SBV a))
instance Data.SBV.Core.Data.SymVal a => Data.SBV.Core.Symbolic.Fresh GHC.Types.IO (Documentation.SBV.Examples.WeakestPreconditions.IntSqrt.SqrtS (Data.SBV.Core.Data.SBV a))


-- | Proof of correctness of an imperative list-length algorithm, using
--   weakest preconditions. Illustrates the use of SBV's symbolic lists
--   together with the WP algorithm.
module Documentation.SBV.Examples.WeakestPreconditions.Length

-- | The state of the length program, paramaterized over the element type
--   <tt>a</tt>
data LenS a
LenS :: SList a -> SList a -> SInteger -> LenS a

-- | The input list
[xs] :: LenS a -> SList a

-- | Copy of input
[ys] :: LenS a -> SList a

-- | Running length
[l] :: LenS a -> SInteger

-- | The concrete counterpart to <a>LenS</a>. Note that we can no longer
--   use the duality between <tt>SBV a</tt> and <tt>a</tt> as in other
--   examples and just use one datatype for both. This is because <tt>SList
--   a</tt> and <tt>[a]</tt> are fundamentally different types. This can be
--   a bit confusing at first, but the point is that it is the list that is
--   symbolic in case of an <tt>SList a</tt>, not that we have a concrete
--   list with symbolic elements in it. Subtle difference, but it is
--   important to keep these two separate.
data LenC a
LenC :: [a] -> [a] -> Integer -> LenC a

-- | Helper type synonym
type S = LenS Integer

-- | The imperative length algorithm:
--   
--   <pre>
--   ys = xs
--   l  = 0
--   while not (null ys)
--     l  = l+1
--     ys = tail ys
--   </pre>
--   
--   Note that we need to explicitly annotate each loop with its invariant
--   and the termination measure. For convenience, we take those two as
--   parameters, so we can experiment later.
algorithm :: Invariant S -> Maybe (Measure S) -> Stmt S

-- | Precondition for our program. Nothing! It works for all lists.
pre :: S -> SBool

-- | Postcondition for our program: <tt>l</tt> must be the length of the
--   input list.
post :: S -> SBool

-- | Stability condition: Program must leave <tt>xs</tt> unchanged.
noChange :: Stable S

-- | A program is the algorithm, together with its pre- and
--   post-conditions.
imperativeLength :: Invariant S -> Maybe (Measure S) -> Program S

-- | The invariant simply relates the length of the input to the length of
--   the current suffix and the length of the prefix traversed so far.
invariant :: Invariant S

-- | The measure is obviously the length of <tt>ys</tt>, as we peel
--   elements off of it through the loop.
measure :: Measure S

-- | We check that <tt>l</tt> is the length of the input list <tt>xs</tt>
--   upon termination. Note that even though this is an inductive proof, it
--   is fairly easy to prove with our SMT based technology, which doesn't
--   really handle induction at all! The usual inductive proof steps are
--   baked into the invariant establishment phase of the WP proof. We have:
--   
--   <pre>
--   &gt;&gt;&gt; correctness
--   Total correctness is established.
--   Q.E.D.
--   </pre>
correctness :: IO ()
instance Data.SBV.Core.Data.SymVal a => Data.SBV.Core.Model.Mergeable (Documentation.SBV.Examples.WeakestPreconditions.Length.LenS a)
instance GHC.Generics.Generic (Documentation.SBV.Examples.WeakestPreconditions.Length.LenS a)
instance GHC.Show.Show a => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.Length.LenC a)
instance Data.SBV.Core.Symbolic.Queriable GHC.Types.IO (Documentation.SBV.Examples.WeakestPreconditions.Length.LenS GHC.Num.Integer.Integer)
instance (Data.SBV.Core.Data.SymVal a, GHC.Show.Show a) => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.Length.LenS a)


-- | Proof of correctness of an imperative summation algorithm, using
--   weakest preconditions. We investigate a few different invariants and
--   see how different versions lead to proofs and failures.
module Documentation.SBV.Examples.WeakestPreconditions.Sum

-- | The state for the sum program, parameterized over a base type
--   <tt>a</tt>.
data SumS a
SumS :: a -> a -> a -> SumS a

-- | The input value
[n] :: SumS a -> a

-- | Loop counter
[i] :: SumS a -> a

-- | Running sum
[s] :: SumS a -> a

-- | Helper type synonym
type S = SumS SInteger

-- | The imperative summation algorithm:
--   
--   <pre>
--   i = 0
--   s = 0
--   while i &lt; n
--     i = i+1
--     s = s+i
--   </pre>
--   
--   Note that we need to explicitly annotate each loop with its invariant
--   and the termination measure. For convenience, we take those two as
--   parameters, so we can experiment later.
algorithm :: Invariant S -> Maybe (Measure S) -> Stmt S

-- | Precondition for our program: <tt>n</tt> must be non-negative. Note
--   that there is an explicit call to <a>abort</a> in our program to
--   protect against this case, so if we do not have this precondition, all
--   programs will fail.
pre :: S -> SBool

-- | Postcondition for our program: <tt>s</tt> must be the sum of all
--   numbers up to and including <tt>n</tt>.
post :: S -> SBool

-- | Stability condition: Program must leave <tt>n</tt> unchanged.
noChange :: Stable S

-- | A program is the algorithm, together with its pre- and
--   post-conditions.
imperativeSum :: Invariant S -> Maybe (Measure S) -> Program S

-- | Check that the program terminates and <tt>s</tt> equals
--   <tt>n*(n+1)/2</tt> upon termination, i.e., the sum of all numbers upto
--   <tt>n</tt>. Note that this only holds if <tt>n &gt;= 0</tt> to start
--   with, as guaranteed by the precondition of our program.
--   
--   The correct termination measure is <tt>n-i</tt>: It goes down in each
--   iteration provided we start with <tt>n &gt;= 0</tt> and it always
--   remains non-negative while the loop is executing. Note that we do not
--   need a lexicographic measure in this case, hence we simply return a
--   list of one element.
--   
--   The correct invariant is a conjunction of two facts. First, <tt>s</tt>
--   is equivalent to the sum of numbers <tt>0</tt> upto <tt>i</tt>. This
--   clearly holds at the beginning when <tt>i = s = 0</tt>, and is
--   maintained in each iteration of the body. Second, it always holds that
--   <tt>i &lt;= n</tt> as long as the loop executes, both before and after
--   each execution of the body. When the loop terminates, it holds that
--   <tt>i = n</tt>. Since the invariant says <tt>s</tt> is the sum of all
--   numbers up to but not including <tt>i</tt>, we conclude that
--   <tt>s</tt> is the sum of all numbers up to and including <tt>n</tt>,
--   as requested.
--   
--   Note that coming up with this invariant is neither trivial, nor easy
--   to automate by any means. What SBV provides is a way to check that
--   your invariant and termination measures are correct, not a means of
--   coming up with them in the first place.
--   
--   We have:
--   
--   <pre>
--   &gt;&gt;&gt; :set -XNamedFieldPuns
--   
--   &gt;&gt;&gt; let invariant SumS{n, i, s} = s .== (i*(i+1)) `sDiv` 2 .&amp;&amp; i .&lt;= n
--   
--   &gt;&gt;&gt; let measure   SumS{n, i}    = [n - i]
--   
--   &gt;&gt;&gt; correctness invariant (Just measure)
--   Total correctness is established.
--   Q.E.D.
--   </pre>
correctness :: Invariant S -> Maybe (Measure S) -> IO (ProofResult (SumS Integer))
instance Data.Traversable.Traversable Documentation.SBV.Examples.WeakestPreconditions.Sum.SumS
instance Data.Foldable.Foldable Documentation.SBV.Examples.WeakestPreconditions.Sum.SumS
instance GHC.Base.Functor Documentation.SBV.Examples.WeakestPreconditions.Sum.SumS
instance Data.SBV.Core.Model.Mergeable a => Data.SBV.Core.Model.Mergeable (Documentation.SBV.Examples.WeakestPreconditions.Sum.SumS a)
instance GHC.Generics.Generic (Documentation.SBV.Examples.WeakestPreconditions.Sum.SumS a)
instance GHC.Show.Show a => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.Sum.SumS a)
instance (Data.SBV.Core.Data.SymVal a, GHC.Show.Show a) => GHC.Show.Show (Documentation.SBV.Examples.WeakestPreconditions.Sum.SumS (Data.SBV.Core.Data.SBV a))
instance Data.SBV.Core.Data.SymVal a => Data.SBV.Core.Symbolic.Fresh GHC.Types.IO (Documentation.SBV.Examples.WeakestPreconditions.Sum.SumS (Data.SBV.Core.Data.SBV a))
