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

-- | Solver-agnostic symbolic values support for issuing queries
--   
--   What4 is a generic library for representing values as symbolic
--   formulae which may contain references to symbolic values, representing
--   unknown variables. It provides support for communicating with a
--   variety of SAT and SMT solvers, including Z3, CVC4, CVC5, Yices,
--   Boolector, STP, and dReal. The data representation types make heavy
--   use of GADT-style type indices to ensure type-correct manipulation of
--   symbolic values.
@package what4
@version 1.5.1

-- | This is a testing abstraction layer that allows the integration of
--   test properties and functions into the What4 library without requiring
--   a binding to a specific testing library or version thereof (e.g.
--   QuickCheck, Hedgehog, etc.). All test properties and functions should
--   be specified using the primary set of functions in this module, and
--   then the actual test code will specify a binding of these abstractions
--   to a specific test library.
--   
--   In this way, the What4 can implement not only local tests but the test
--   functionality can be exported to enable downstream modules to perform
--   extended testing.
--   
--   The actual tests should be written using only the functions exported
--   in the testing exports section of this module. Note that only the set
--   of functions needed for What4 is defined by this testing abstraction;
--   if additional testing functions are needed, the GenEnv context should
--   be extended to add an adaptation entry and the function should be
--   defined here for use by the tests.
--   
--   The overlap (common subset) between testing libraries such as
--   QuickCheck and Hedgehog is only of moderate size: both libraries (and
--   especially Hedgehog) provide functionality that is not present in the
--   other library. This module does not attempt to provide full coverage
--   for the functionality in both libraries; the intent is that test
--   functions can be written using the proxy functions defined here and
--   that downstream code using either of QuickCheck or Hedgehog can
--   utilize these support functions in their own tests. As such, it is
--   recommended that the What4 integrated tests are limited in expression
--   to the common subset that can be described here.
--   
--   A specific test configuration will need to use the functions and
--   definitions in the concretization exports to bind these abstracted
--   test functions to the specific library being used by that test suite.
--   
--   For example, to bind to QuickCheck, specify:
--   
--   
--   import QuickCheck
--   import qualified Test.Verification as V
--   
--   quickCheckGenerators = V.GenEnv { V.genChooseBool = elements [ True, False ]
--                                   , V.genChooseInteger = \r -> choose r
--                                   , V.genChooseInt = \r -> choose r
--                                   , V.genGetSize = getSize
--                                   }
--   
--   genTest :: String -> V.Gen V.Property -> TestTree
--   genTest nm p = testProperty nm
--                  (property $ V.toNativeProperty quickCheckGenerators p)
--   
module Test.Verification

-- | The named form of the ==> assumption operator
assuming :: Verifiable t => Bool -> t -> Property

-- | The assumption operator that performs the property test (second
--   element) only when the first argument is true (the assumption guard
--   for the test). This is the analog to the corresponding QuickCheck
--   ==> operator.
(==>) :: Verifiable t => Bool -> t -> Property
infixr 0 ==>

-- | Used by testing code to assert a boolean property.
property :: Bool -> Property

-- | A test generator that returns True or False
chooseBool :: Gen Bool

-- | A test generator that returns an Int value between the
--   specified (inclusive) bounds.
chooseInt :: (Int, Int) -> Gen Int

-- | A test generator that returns an Integer value between the
--   specified (inclusive) bounds.
chooseInteger :: (Integer, Integer) -> Gen Integer

-- | This is the generator monad for the Verification proxy tests. The
--   inner monad will be the actual test implementation's monadic
--   generator, and the a return type is the type returned by
--   running this monad.
--   
--   Tests should only use the 'Gen TYPE' as an output; the constructors
--   and internals should be used only by the test concretization.
data Gen a

-- | A test generator that returns the current shrink size of the generator
--   functionality.
getSize :: Gen Int

-- | A class specifying things that can be verified by constructing a local
--   Property.
class Verifiable prop
verifying :: Verifiable prop => prop -> Property

-- | Local definition of a Property: intended to be a proxy for a
--   QuickCheck Property or a Hedgehog Property. The
--   toNativeProperty implementation function converts from these
--   proxy Properties to the native Property implementation.
--   
--   Tests should only use the Property type as an output; the
--   constructors and internals should be used only by the test
--   concretization.
data Property
BoolProperty :: Bool -> Property
AssumptionProp :: Assumption -> Property

-- | Internal data structure to store the two elements to the ==>
--   assumption operator.
data Assumption
Assuming :: Bool -> Property -> Assumption
[preCondition] :: Assumption -> Bool
[assumedProp] :: Assumption -> Property

-- | This is the reader environment for the surface level proxy testing
--   monad. This environment will be provided by the actual test code to
--   map these proxy operations to the specific testing implementation.
data GenEnv m
GenEnv :: m Bool -> ((Int, Int) -> m Int) -> ((Integer, Integer) -> m Integer) -> m Int -> GenEnv m
[genChooseBool] :: GenEnv m -> m Bool
[genChooseInt] :: GenEnv m -> (Int, Int) -> m Int
[genChooseInteger] :: GenEnv m -> (Integer, Integer) -> m Integer
[genGetSize] :: GenEnv m -> m Int

-- | This function should be called by the testing code to convert the
--   proxy tests in this module into the native tests (e.g. QuickCheck or
--   Hedgehog). This function is provided with the mapping environment
--   between the proxy tests here and the native equivalents, and a local
--   Generator monad expression, returning a native Generator equivalent.
toNativeProperty :: Monad m => GenEnv m -> Gen b -> m b
instance GHC.Show.Show Test.Verification.Property
instance GHC.Show.Show Test.Verification.Assumption
instance GHC.Base.Functor Test.Verification.Gen
instance GHC.Base.Applicative Test.Verification.Gen
instance GHC.Base.Monad Test.Verification.Gen
instance Test.Verification.Verifiable GHC.Types.Bool
instance Test.Verification.Verifiable Test.Verification.Property

-- | This module exports the types used in solver expressions.
--   
--   These types are largely used as indexes to various GADTs and type
--   families as a way to let the GHC typechecker help us keep expressions
--   used by solvers apart.
--   
--   In addition, we provide a value-level reification of the type indices
--   that can be examined by pattern matching, called BaseTypeRepr.
module What4.BaseTypes

-- | This data kind enumerates the Crucible solver interface types, which
--   are types that may be represented symbolically.
data BaseType
type BaseBoolType = -- | @:: 'BaseType'@. 'BaseBoolType
type BaseIntegerType = -- | @:: 'BaseType'@. 'BaseIntegerType
type BaseRealType = -- | @:: 'BaseType'@. 'BaseRealType
type BaseStringType = -- | @:: 'BaseType'@. 'BaseStringType
type BaseBVType = -- | @:: 'TypeNats.Nat' -> 'BaseType'@. 'BaseBVType
type BaseFloatType = -- | @:: 'FloatPrecision' -> 'BaseType'@. 'BaseFloatType
type BaseComplexType = -- | @:: 'BaseType'@. 'BaseComplexType
type BaseStructType = -- | @:: 'Ctx.Ctx' 'BaseType' -> 'BaseType'@. 'BaseStructType
type BaseArrayType = -- | @:: 'Ctx.Ctx' 'BaseType' -> 'BaseType' -> 'BaseType'@. 'BaseArrayType
data StringInfo
type Char8 = -- | @:: 'StringInfo'@. 'Char8
type Char16 = -- | @:: 'StringInfo'@. 'Char16
type Unicode = -- | @:: 'StringInfo'@. 'Unicode

-- | This data kind describes the types of floating-point formats. This
--   consist of the standard IEEE 754-2008 binary floating point formats.
data FloatPrecision

-- | This computes the number of bits occupied by a floating-point format.
type family FloatPrecisionBits (fpp :: FloatPrecision) :: Nat
type FloatingPointPrecision = -- | @:: 'GHC.TypeNats.Nat' -> 'GHC.TypeNats.Nat' -> 'FloatPrecision'@. 'FloatingPointPrecision

-- | Floating-point precision aliases
type Prec16 = FloatingPointPrecision 5 11
type Prec32 = FloatingPointPrecision 8 24
type Prec64 = FloatingPointPrecision 11 53
type Prec80 = FloatingPointPrecision 15 65
type Prec128 = FloatingPointPrecision 15 113

-- | A runtime representation of a solver interface type. Parameter
--   bt has kind BaseType.
data BaseTypeRepr (bt :: BaseType) :: Type
[BaseBoolRepr] :: BaseTypeRepr BaseBoolType
[BaseBVRepr] :: 1 <= w => !NatRepr w -> BaseTypeRepr (BaseBVType w)
[BaseIntegerRepr] :: BaseTypeRepr BaseIntegerType
[BaseRealRepr] :: BaseTypeRepr BaseRealType
[BaseFloatRepr] :: !FloatPrecisionRepr fpp -> BaseTypeRepr (BaseFloatType fpp)
[BaseStringRepr] :: StringInfoRepr si -> BaseTypeRepr (BaseStringType si)
[BaseComplexRepr] :: BaseTypeRepr BaseComplexType
[BaseStructRepr] :: !Assignment BaseTypeRepr ctx -> BaseTypeRepr (BaseStructType ctx)
[BaseArrayRepr] :: !Assignment BaseTypeRepr (idx ::> tp) -> !BaseTypeRepr xs -> BaseTypeRepr (BaseArrayType (idx ::> tp) xs)
data FloatPrecisionRepr (fpp :: FloatPrecision)
[FloatingPointPrecisionRepr] :: (2 <= eb, 2 <= sb) => !NatRepr eb -> !NatRepr sb -> FloatPrecisionRepr (FloatingPointPrecision eb sb)
data StringInfoRepr (si :: StringInfo)
[Char8Repr] :: StringInfoRepr Char8
[Char16Repr] :: StringInfoRepr Char16
[UnicodeRepr] :: StringInfoRepr Unicode

-- | Return the type of the indices for an array type.
arrayTypeIndices :: BaseTypeRepr (BaseArrayType idx tp) -> Assignment BaseTypeRepr idx

-- | Return the result type of an array type.
arrayTypeResult :: BaseTypeRepr (BaseArrayType idx tp) -> BaseTypeRepr tp
floatPrecisionToBVType :: FloatPrecisionRepr (FloatingPointPrecision eb sb) -> BaseTypeRepr (BaseBVType (eb + sb))
lemmaFloatPrecisionIsPos :: forall eb' sb'. FloatPrecisionRepr (FloatingPointPrecision eb' sb') -> LeqProof 1 (eb' + sb')

-- | This class is parameterized by a kind k (typically a data
--   kind), a type constructor f of kind k -> *
--   (typically a GADT of singleton types indexed by k), and an
--   index parameter ctx of kind k.
class () => KnownRepr (f :: k -> Type) (ctx :: k)
knownRepr :: KnownRepr f ctx => f ctx

-- | A Context where all the argument types are KnownRepr instances
type KnownCtx f = KnownRepr (Assignment f)
instance Data.Parameterized.Classes.HashableF What4.BaseTypes.BaseTypeRepr
instance Data.Hashable.Class.Hashable (What4.BaseTypes.BaseTypeRepr bt)
instance Data.Parameterized.Classes.HashableF What4.BaseTypes.FloatPrecisionRepr
instance Data.Hashable.Class.Hashable (What4.BaseTypes.FloatPrecisionRepr fpp)
instance Data.Parameterized.Classes.HashableF What4.BaseTypes.StringInfoRepr
instance Data.Hashable.Class.Hashable (What4.BaseTypes.StringInfoRepr si)
instance Prettyprinter.Internal.Pretty (What4.BaseTypes.BaseTypeRepr bt)
instance GHC.Show.Show (What4.BaseTypes.BaseTypeRepr bt)
instance Data.Parameterized.Classes.ShowF What4.BaseTypes.BaseTypeRepr
instance Prettyprinter.Internal.Pretty (What4.BaseTypes.FloatPrecisionRepr fpp)
instance GHC.Show.Show (What4.BaseTypes.FloatPrecisionRepr fpp)
instance Data.Parameterized.Classes.ShowF What4.BaseTypes.FloatPrecisionRepr
instance Prettyprinter.Internal.Pretty (What4.BaseTypes.StringInfoRepr si)
instance GHC.Show.Show (What4.BaseTypes.StringInfoRepr si)
instance Data.Parameterized.Classes.ShowF What4.BaseTypes.StringInfoRepr
instance Data.Type.Equality.TestEquality What4.BaseTypes.BaseTypeRepr
instance GHC.Classes.Eq (What4.BaseTypes.BaseTypeRepr bt)
instance Data.Parameterized.Classes.OrdF What4.BaseTypes.BaseTypeRepr
instance Data.Type.Equality.TestEquality What4.BaseTypes.FloatPrecisionRepr
instance GHC.Classes.Eq (What4.BaseTypes.FloatPrecisionRepr fpp)
instance Data.Parameterized.Classes.OrdF What4.BaseTypes.FloatPrecisionRepr
instance Data.Type.Equality.TestEquality What4.BaseTypes.StringInfoRepr
instance GHC.Classes.Eq (What4.BaseTypes.StringInfoRepr si)
instance Data.Parameterized.Classes.OrdF What4.BaseTypes.StringInfoRepr
instance Data.Parameterized.Classes.KnownRepr What4.BaseTypes.BaseTypeRepr What4.BaseTypes.BaseBoolType
instance Data.Parameterized.Classes.KnownRepr What4.BaseTypes.BaseTypeRepr What4.BaseTypes.BaseIntegerType
instance Data.Parameterized.Classes.KnownRepr What4.BaseTypes.BaseTypeRepr What4.BaseTypes.BaseRealType
instance Data.Parameterized.Classes.KnownRepr What4.BaseTypes.StringInfoRepr si => Data.Parameterized.Classes.KnownRepr What4.BaseTypes.BaseTypeRepr (What4.BaseTypes.BaseStringType si)
instance (1 Data.Type.Ord.<= w, GHC.TypeNats.KnownNat w) => Data.Parameterized.Classes.KnownRepr What4.BaseTypes.BaseTypeRepr (What4.BaseTypes.BaseBVType w)
instance Data.Parameterized.Classes.KnownRepr What4.BaseTypes.FloatPrecisionRepr fpp => Data.Parameterized.Classes.KnownRepr What4.BaseTypes.BaseTypeRepr (What4.BaseTypes.BaseFloatType fpp)
instance Data.Parameterized.Classes.KnownRepr What4.BaseTypes.BaseTypeRepr What4.BaseTypes.BaseComplexType
instance Data.Parameterized.Classes.KnownRepr (Data.Parameterized.Context.Unsafe.Assignment What4.BaseTypes.BaseTypeRepr) ctx => Data.Parameterized.Classes.KnownRepr What4.BaseTypes.BaseTypeRepr (What4.BaseTypes.BaseStructType ctx)
instance (Data.Parameterized.Classes.KnownRepr (Data.Parameterized.Context.Unsafe.Assignment What4.BaseTypes.BaseTypeRepr) idx, Data.Parameterized.Classes.KnownRepr What4.BaseTypes.BaseTypeRepr tp, Data.Parameterized.Classes.KnownRepr What4.BaseTypes.BaseTypeRepr t) => Data.Parameterized.Classes.KnownRepr What4.BaseTypes.BaseTypeRepr (What4.BaseTypes.BaseArrayType (idx Data.Parameterized.Ctx.::> tp) t)
instance Data.Parameterized.Classes.KnownRepr What4.BaseTypes.StringInfoRepr What4.BaseTypes.Char8
instance Data.Parameterized.Classes.KnownRepr What4.BaseTypes.StringInfoRepr What4.BaseTypes.Char16
instance Data.Parameterized.Classes.KnownRepr What4.BaseTypes.StringInfoRepr What4.BaseTypes.Unicode
instance (2 Data.Type.Ord.<= eb, 2 Data.Type.Ord.<= es, GHC.TypeNats.KnownNat eb, GHC.TypeNats.KnownNat es) => Data.Parameterized.Classes.KnownRepr What4.BaseTypes.FloatPrecisionRepr (What4.BaseTypes.FloatingPointPrecision eb es)

-- | Desired instances for the IsInterpretedFloatExprBuilder class
--   are selected via the different mode values from this module.
module What4.FloatMode

-- | Mode flag for how floating-point values should be interpreted.
data FloatMode
data FloatModeRepr :: FloatMode -> Type
[FloatIEEERepr] :: FloatModeRepr FloatIEEE
[FloatUninterpretedRepr] :: FloatModeRepr FloatUninterpreted
[FloatRealRepr] :: FloatModeRepr FloatReal

-- | In this mode "interpreted" floating-point values are treated as
--   bit-precise IEEE-754 floats.
type FloatIEEE = 'FloatIEEE

-- | In this mode "interpreted" floating-point values are treated as
--   bitvectors of the appropriate width, and all operations on them are
--   translated as uninterpreted functions.
type FloatUninterpreted = 'FloatUninterpreted

-- | In this mode "interpreted" floating-point values are treated as
--   real-number values, to the extent possible. Expressions that would
--   result in infinities or NaN will yield unspecified values in this
--   mode, or directly produce runtime errors.
type FloatReal = 'FloatReal
instance GHC.Show.Show (What4.FloatMode.FloatModeRepr fm)
instance Data.Parameterized.Classes.ShowF What4.FloatMode.FloatModeRepr
instance Data.Parameterized.Classes.KnownRepr What4.FloatMode.FloatModeRepr What4.FloatMode.FloatIEEE
instance Data.Parameterized.Classes.KnownRepr What4.FloatMode.FloatModeRepr What4.FloatMode.FloatUninterpreted
instance Data.Parameterized.Classes.KnownRepr What4.FloatMode.FloatModeRepr What4.FloatMode.FloatReal
instance Data.Type.Equality.TestEquality What4.FloatMode.FloatModeRepr

-- | This provides a basic data type for function names.
module What4.FunctionName

-- | For our purposes, a function name is just unicode text. Individual
--   languages may want to further restrict names.
data FunctionName
functionName :: FunctionName -> Text
functionNameFromText :: Text -> FunctionName

-- | Name of function for starting simulator.
startFunctionName :: FunctionName
instance Data.Hashable.Class.Hashable What4.FunctionName.FunctionName
instance GHC.Classes.Ord What4.FunctionName.FunctionName
instance GHC.Classes.Eq What4.FunctionName.FunctionName
instance Data.String.IsString What4.FunctionName.FunctionName
instance GHC.Show.Show What4.FunctionName.FunctionName
instance Prettyprinter.Internal.Pretty What4.FunctionName.FunctionName

module What4.IndexLit

-- | This represents a concrete index value, and is used for creating
--   arrays.
data IndexLit idx
[IntIndexLit] :: !Integer -> IndexLit BaseIntegerType
[BVIndexLit] :: 1 <= w => !NatRepr w -> !BV w -> IndexLit (BaseBVType w)
hashIndexLit :: Int -> IndexLit idx -> Int
instance GHC.Classes.Eq (What4.IndexLit.IndexLit tp)
instance Data.Type.Equality.TestEquality What4.IndexLit.IndexLit
instance Data.Parameterized.Classes.OrdF What4.IndexLit.IndexLit
instance Data.Hashable.Class.Hashable (What4.IndexLit.IndexLit tp)
instance Data.Parameterized.Classes.HashableF What4.IndexLit.IndexLit
instance GHC.Show.Show (What4.IndexLit.IndexLit tp)
instance Data.Parameterized.Classes.ShowF What4.IndexLit.IndexLit

module What4.Panic

-- | Request a CallStack.
--   
--   NOTE: The implicit parameter ?callStack :: CallStack is an
--   implementation detail and should not be considered part of the
--   CallStack API, we may decide to change the implementation in
--   the future.
type HasCallStack = ?callStack :: CallStack
data What4

-- | The exception thrown when panicing.
data () => Panic a

-- | panic represents an error condition that should only arise due
--   to a programming error. It will exit the program and print a message
--   asking users to open a ticket.
panic :: HasCallStack => String -> [String] -> a
instance Panic.PanicComponent What4.Panic.What4

-- | ProblemFeatures uses bit mask to represent the features. The bits are:
--   
--   0 : Uses linear arithmetic 1 : Uses non-linear arithmetic, i.e.
--   multiplication (should also set bit 0) 2 : Uses computational reals
--   (should also set bits 0 & 1) 3 : Uses integer variables (should
--   also set bit 0) 4 : Uses bitvectors 5 : Uses exists-forall. 6 : Uses
--   quantifiers (should also set bit 5) 7 : Uses symbolic arrays or
--   complex numbers. 8 : Uses structs 9 : Uses strings 10 : Uses
--   floating-point 11 : Computes UNSAT cores 12 : Computes UNSAT
--   assumptions 13 : Uses uninterpreted functions 14 : Uses defined
--   functions
module What4.ProblemFeatures

-- | Allowed features represents features that the constraint solver will
--   need to support to solve the problem.
data ProblemFeatures
noFeatures :: ProblemFeatures

-- | Indicates whether the problem uses linear arithmetic.
useLinearArithmetic :: ProblemFeatures

-- | Indicates whether the problem uses non-linear arithmetic.
useNonlinearArithmetic :: ProblemFeatures

-- | Indicates whether the problem uses computable real functions.
useComputableReals :: ProblemFeatures

-- | Indicates the problem contains integer variables.
useIntegerArithmetic :: ProblemFeatures

-- | Indicates whether the problem uses bitvectors.
useBitvectors :: ProblemFeatures

-- | Indicates whether the problem needs exists-forall support.
useExistForall :: ProblemFeatures

-- | Has general quantifier support.
useQuantifiers :: ProblemFeatures

-- | Indicates whether the problem uses symbolic arrays.
useSymbolicArrays :: ProblemFeatures

-- | Indicates whether the problem uses structs
--   
--   Structs are modeled using constructors in CVC4CVC5Z3, and
--   tuples in Yices.
useStructs :: ProblemFeatures

-- | Indicates whether the problem uses strings
--   
--   Strings have some symbolic support in CVC4, CVC5, and Z3.
useStrings :: ProblemFeatures

-- | Indicates whether the problem uses floating-point
--   
--   Floating-point has some symbolic support in CVC4, CVC5, and Z3.
useFloatingPoint :: ProblemFeatures

-- | Indicates if the solver is able and configured to compute UNSAT cores.
useUnsatCores :: ProblemFeatures

-- | Indicates if the solver is able and configured to compute UNSAT
--   assumptions.
useUnsatAssumptions :: ProblemFeatures

-- | Indicates if the solver is able and configured to use uninterpreted
--   functions.
useUninterpFunctions :: ProblemFeatures

-- | Indicates if the solver is able and configured to use defined
--   functions.
useDefinedFunctions :: ProblemFeatures

-- | Indicates if the solver is able and configured to produce abducts.
useProduceAbducts :: ProblemFeatures

-- | Tests if one set of problem features subsumes another. In particular,
--   hasProblemFeature x y is true iff the set of features in
--   x is a superset of those in y.
hasProblemFeature :: ProblemFeatures -> ProblemFeatures -> Bool
instance GHC.Bits.Bits What4.ProblemFeatures.ProblemFeatures
instance GHC.Classes.Eq What4.ProblemFeatures.ProblemFeatures

-- | This module primarily defines the Position datatype for
--   handling program location data. A program location may refer either to
--   a source file location (file name, line and column number), a binary
--   file location (file name and byte offset) or be a dummy "internal"
--   location assigned to generated program fragments.
module What4.ProgramLoc
data Position

-- | A source position containing filename, line, and column.
SourcePos :: !Text -> !Int -> !Int -> Position

-- | A binary position containing a filename and address in memory.
BinaryPos :: !Text -> !Word64 -> Position

-- | Some unstructured position information that doesn't fit into the other
--   categories.
OtherPos :: !Text -> Position

-- | Generated internally by the simulator, or otherwise unknown.
InternalPos :: Position
sourcePos :: FilePath -> Int -> Int -> Position
startOfFile :: FilePath -> Position
ppNoFileName :: Position -> Doc ann

-- | A value with a source position associated.
data Posd v
Posd :: !Position -> !v -> Posd v
[pos] :: Posd v -> !Position
[pos_val] :: Posd v -> !v

-- | A very small type that contains a function and PC identifier.
data ProgramLoc

-- | Make a program loc
mkProgramLoc :: FunctionName -> Position -> ProgramLoc

-- | Location for initialization code
initializationLoc :: ProgramLoc
plFunction :: ProgramLoc -> FunctionName
plSourceLoc :: ProgramLoc -> Position
class HasProgramLoc v
programLoc :: HasProgramLoc v => Lens' v ProgramLoc
instance GHC.Classes.Ord What4.ProgramLoc.Position
instance GHC.Classes.Eq What4.ProgramLoc.Position
instance GHC.Classes.Eq v => GHC.Classes.Eq (What4.ProgramLoc.Posd v)
instance GHC.Show.Show v => GHC.Show.Show (What4.ProgramLoc.Posd v)
instance Data.Traversable.Traversable What4.ProgramLoc.Posd
instance Data.Foldable.Foldable What4.ProgramLoc.Posd
instance GHC.Base.Functor What4.ProgramLoc.Posd
instance GHC.Classes.Ord What4.ProgramLoc.ProgramLoc
instance GHC.Classes.Eq What4.ProgramLoc.ProgramLoc
instance GHC.Show.Show What4.ProgramLoc.ProgramLoc
instance Control.DeepSeq.NFData v => Control.DeepSeq.NFData (What4.ProgramLoc.Posd v)
instance GHC.Show.Show What4.ProgramLoc.Position
instance Control.DeepSeq.NFData What4.ProgramLoc.Position
instance Prettyprinter.Internal.Pretty What4.ProgramLoc.Position

-- | Defines a numeric data-type where each number is represented as the
--   root of a polynomial over a single variable.
--   
--   This currently only defines operations for parsing the roots from the
--   format generated by Yices, and evaluating a polynomial over rational
--   coefficients to the rational derived from the closest double.
module What4.Protocol.PolyRoot
data Root c

-- | This either returns the root exactly, or it computes the closest
--   double precision approximation of the root.
--   
--   Underneath the hood, this uses rational arithmetic to guarantee
--   precision, so this operation is relatively slow. However, it is
--   guaranteed to provide an exact answer.
--   
--   If performance is a concern, there are faster algorithms for computing
--   this.
approximate :: Root Rational -> Rational

-- | Convert text to a root
fromYicesText :: Text -> Maybe (Root Rational)
parseYicesRoot :: Parser (Root Rational)
instance GHC.Show.Show coef => GHC.Show.Show (What4.Protocol.PolyRoot.SingPoly coef)
instance Data.Traversable.Traversable What4.Protocol.PolyRoot.SingPoly
instance Data.Foldable.Foldable What4.Protocol.PolyRoot.SingPoly
instance GHC.Base.Functor What4.Protocol.PolyRoot.SingPoly
instance GHC.Show.Show c => GHC.Show.Show (What4.Protocol.PolyRoot.Root c)
instance (GHC.Classes.Ord c, GHC.Num.Num c, Prettyprinter.Internal.Pretty c) => Prettyprinter.Internal.Pretty (What4.Protocol.PolyRoot.Root c)
instance (GHC.Classes.Ord coef, GHC.Num.Num coef, Prettyprinter.Internal.Pretty coef) => Prettyprinter.Internal.Pretty (What4.Protocol.PolyRoot.SingPoly coef)

module What4.Protocol.ReadDecimal

-- | Read decimal number, returning rational and rest of string, or a
--   failure message if first character is not a digit.
--   
--   A decimal number has the form
--   (-)([0..9])+([0..9])+.([0.9]'*(?)?
readDecimal :: MonadFail m => String -> m (Rational, String)

module What4.Protocol.SExp
data SExp
SAtom :: Text -> SExp
SString :: Text -> SExp
SApp :: [SExp] -> SExp

-- | Parses an SExp. If the input is a string (recognized by the
--   readString argument), return that as an SString; if
--   the input is a single token, return that as an SAtom.
parseSExp :: Parser Text -> Parser SExp

-- | Parses the body of an SExp after the opening '(' has already been
--   parsed.
parseSExpBody :: Parser Text -> Parser SExp
stringToSExp :: MonadFail m => Parser Text -> String -> m [SExp]

-- | Read next contiguous sequence of numbers or letters.
parseNextWord :: Parser Text
asAtomList :: SExp -> Maybe [Text]
asNegAtomList :: SExp -> Maybe [(Bool, Text)]
skipSpaceOrNewline :: Parser ()
sExpToString :: SExp -> String
instance GHC.Show.Show What4.Protocol.SExp.SExp
instance GHC.Classes.Ord What4.Protocol.SExp.SExp
instance GHC.Classes.Eq What4.Protocol.SExp.SExp
instance Data.String.IsString What4.Protocol.SExp.SExp

-- | This module defines types and operations for parsing results from
--   SMTLIB2.
--   
--   It does not depend on the rest of What4 so that it can be used
--   directly by clients interested in generating SMTLIB without depending
--   on the What4 formula interface. All the type constructors are exposed
--   so that clients can generate new values that are not exposed through
--   this interface.
module What4.Protocol.SMTLib2.Parse

-- | Result of check-sat and check-sat-assuming
data CheckSatResponse
SatResponse :: CheckSatResponse
UnsatResponse :: CheckSatResponse
UnknownResponse :: CheckSatResponse
CheckSatUnsupported :: CheckSatResponse
CheckSatError :: !String -> CheckSatResponse

-- | Read the results of a (check-sat) request.
readCheckSatResponse :: Handle -> IO CheckSatResponse

-- | The parsed declarations and definitions returned by "(get-model)"
type GetModelResponse = [ModelResponse]

-- | This reads the model response from a "(get-model)" request.
readGetModelResponse :: Handle -> IO GetModelResponse

-- | A line in the model response
data ModelResponse
DeclareSortResponse :: !Symbol -> !Integer -> ModelResponse
DefineFunResponse :: !DefineFun -> ModelResponse
data DefineFun
DefineFun :: !Symbol -> ![(Symbol, Sort)] -> !Sort -> !Term -> DefineFun
[funSymbol] :: DefineFun -> !Symbol
[funArgs] :: DefineFun -> ![(Symbol, Sort)]
[funResultSort] :: DefineFun -> !Sort
[funDef] :: DefineFun -> !Term

-- | An SMT symbol
data Symbol

-- | An SMT sort.
data Sort

-- | A named sort with the given arguments.
Sort :: Symbol -> [Sort] -> Sort

-- | A bitvector with the given width.
BitVec :: !Integer -> Sort

-- | floating point with exponent bits followed by significand bit.
FloatingPoint :: !Integer -> !Integer -> Sort
pattern Bool :: Sort
pattern Int :: Sort
pattern Real :: Sort
pattern RoundingMode :: Sort
pattern Array :: Sort -> Sort -> Sort

-- | This denotes an SMTLIB term over a fixed vocabulary.
data Term
SymbolTerm :: !Symbol -> Term
AsConst :: !Sort -> !Term -> Term
BVTerm :: !Integer -> !Integer -> Term

-- | IntTerm v denotes the SMTLIB expression v if v
--   >= 0 and @(- `(negate v)) otherwise.
IntTerm :: !Integer -> Term

-- | RatTerm r denotes the SMTLIB expression (/ `(numerator r)
--   `(denomator r)).
RatTerm :: !Rational -> Term

-- | StoreTerm a i v denotes the SMTLIB expression (store a i
--   v).
StoreTerm :: !Term -> !Term -> !Term -> Term

-- | IfEqTerm v c t f denotes the SMTLIB expression (ite (= v
--   c) t f).
IfEqTerm :: !Symbol -> !Term -> !Term -> !Term -> Term
instance GHC.Base.Applicative What4.Protocol.SMTLib2.Parse.Parser
instance GHC.Base.Functor What4.Protocol.SMTLib2.Parse.Parser
instance GHC.Classes.Eq What4.Protocol.SMTLib2.Parse.Symbol
instance What4.Protocol.SMTLib2.Parse.CanParse What4.Protocol.SMTLib2.Parse.ModelResponse
instance What4.Protocol.SMTLib2.Parse.CanParse What4.Protocol.SMTLib2.Parse.Term
instance What4.Protocol.SMTLib2.Parse.CanParse What4.Protocol.SMTLib2.Parse.Sort
instance GHC.Show.Show What4.Protocol.SMTLib2.Parse.Symbol
instance Data.String.IsString What4.Protocol.SMTLib2.Parse.Symbol
instance What4.Protocol.SMTLib2.Parse.CanParse What4.Protocol.SMTLib2.Parse.Symbol
instance What4.Protocol.SMTLib2.Parse.CanParse What4.Protocol.SMTLib2.Parse.CheckSatResponse
instance What4.Protocol.SMTLib2.Parse.CanParse GHC.Num.Integer.Integer
instance GHC.Base.Monad What4.Protocol.SMTLib2.Parse.Parser
instance Control.Monad.Fail.MonadFail What4.Protocol.SMTLib2.Parse.Parser
instance Data.String.IsString (What4.Protocol.SMTLib2.Parse.Parser ())

-- | This module defines types and operations for generating SMTLIB2 files.
--   
--   It does not depend on the rest of What4 so that it can be used
--   directly by clients interested in generating SMTLIB without depending
--   on the What4 formula interface. All the type constructors are exposed
--   so that clients can generate new values that are not exposed through
--   this interface.
module What4.Protocol.SMTLib2.Syntax

-- | This represents a command to be sent to the SMT solver.
newtype Command
Cmd :: Builder -> Command

-- | Set the logic of the SMT solver
setLogic :: Logic -> Command

-- | Set an option in the SMT solver
--   
--   The name should not need to be prefixed with a colon."
setOption :: Text -> Text -> Command

-- | Set option to produce models
--   
--   This is a widely used option so, we we have a custom command to make
--   it.
setProduceModels :: Bool -> Command

-- | This is a subtype of the type of the same name in Data.SBV.Control.
data SMTInfoFlag
Name :: SMTInfoFlag
Version :: SMTInfoFlag
ErrorBehavior :: SMTInfoFlag
InfoKeyword :: Text -> SMTInfoFlag

-- | A get-info command
getInfo :: SMTInfoFlag -> Command
getVersion :: Command
getName :: Command
getErrorBehavior :: Command

-- | Request the SMT solver to exit
exit :: Command

-- | Declare an uninterpreted sort with the given number of sort
--   parameters.
declareSort :: Symbol -> Integer -> Command

-- | Define a sort in terms of other sorts
defineSort :: Symbol -> [Symbol] -> Sort -> Command

-- | Declare a constant with the given name and return types.
declareConst :: Text -> Sort -> Command

-- | Declare a function with the given name, argument types, and return
--   type.
declareFun :: Text -> [Sort] -> Sort -> Command

-- | Declare a function with the given name, argument types, and return
--   type.
defineFun :: Text -> [(Text, Sort)] -> Sort -> Term -> Command
type Symbol = Text

-- | Check the satisfiability of the current assertions
checkSat :: Command

-- | Check the satisfiability of the current assertions and the additional
--   ones in the list.
checkSatAssuming :: [Term] -> Command

-- | Check satisfiability of the given atomic assumptions in the current
--   context.
--   
--   NOTE! The names of variables passed to this function MUST be generated
--   using a `declare-fun` statement, and NOT a `define-fun` statement.
--   Thus, if you want to bind an arbitrary term, you must declare a new
--   term and assert that it is equal to it's definition. Yes, this is
--   quite irritating.
checkSatWithAssumptions :: [Text] -> Command

-- | Get the model associated with the last call to check-sat.
getModel :: Command

-- | Get the values associated with the terms from the last call to
--   check-sat.
getValue :: [Term] -> Command

-- | Push the given number of scope frames to the SMT solver.
push :: Integer -> Command

-- | Pop the given number of scope frames to the SMT solver.
pop :: Integer -> Command

-- | Empties the assertion stack and remove all global assertions and
--   declarations.
resetAssertions :: Command

-- | Assert the predicate holds in the current context.
assert :: Term -> Command

-- | Assert the predicate holds in the current context, and assign it a
--   name so it can appear in unsatisfiable core results.
assertNamed :: Term -> Text -> Command
getUnsatAssumptions :: Command
getUnsatCore :: Command

-- | Get an abduct that entails the formula, and bind it to the name
getAbduct :: Text -> Term -> Command

-- | Get the next command, called after a get-abduct command
getAbductNext :: Command

-- | Declare a SyGuS function to synthesize with the given name, arguments,
--   and return type.
synthFun :: Text -> [(Text, Sort)] -> Sort -> Command

-- | Declare a SyGuS variable with the given name and type.
declareVar :: Text -> Sort -> Command

-- | Add the SyGuS constraint to the current synthesis problem.
constraint :: Term -> Command

-- | Ask the SyGuS solver to find a solution for the synthesis problem
--   corresponding to the current functions-to-synthesize, variables and
--   constraints.
checkSynth :: Command

-- | Identifies the set of predefined sorts and operators available.
newtype Logic
Logic :: Builder -> Logic

-- | Use the QF_BV logic
qf_bv :: Logic

-- | Set the logic to all supported logics.

-- | Deprecated: Use allLogic instead
allSupported :: Logic

-- | Set the logic to all supported logics.
allLogic :: Logic

-- | Use the Horn logic
hornLogic :: Logic

-- | Sort for SMTLIB expressions
newtype Sort
Sort :: Builder -> Sort
[unSort] :: Sort -> Builder

-- | Booleans
boolSort :: Sort

-- | Bitvectors with the given number of bits.
bvSort :: Natural -> Sort

-- | Integers
intSort :: Sort

-- | Real numbers
realSort :: Sort

-- | Create a sort from a symbol name
varSort :: Symbol -> Sort

-- | Denotes an expression in the SMT solver
newtype Term
T :: Builder -> Term
[renderTerm] :: Term -> Builder

-- | Construct an expression with the given operator and single argument.
un_app :: Builder -> Term -> Term

-- | Construct an expression with the given operator and two arguments.
bin_app :: Builder -> Term -> Term -> Term

-- | Construct an expression with the given operator and list of arguments.
term_app :: Builder -> [Term] -> Term

-- | Construct a chainable term with the given relation
--   
--   pairwise_app p [x1, x2, ..., xn] is equivalent to
--   forall_{i,j} p x_i x_j@.
pairwise_app :: Builder -> [Term] -> Term

-- | Append a "name" to a term so that it will be printed when
--   (get-assignment) is called.
namedTerm :: Term -> Text -> Term
builder_list :: [Builder] -> Builder

-- | true Boolean term
true :: Term

-- | false Boolean term
false :: Term

-- | Complement a Boolean
not :: Term -> Term

-- | implies c r is equivalent to c1 => c2 => .. cn
--   => r.
implies :: [Term] -> Term -> Term

-- | Conjunction of all terms
and :: [Term] -> Term

-- | Disjunction of all terms
or :: [Term] -> Term

-- | Xor of all terms
xor :: [Term] -> Term

-- | Return true if all terms are equal.
eq :: [Term] -> Term

-- | Asserts that each term in the list is unique.
distinct :: [Term] -> Term

-- | Create an if-then-else expression.
ite :: Term -> Term -> Term -> Term

-- | forall_ vars t denotes a predicate that holds if t
--   for every valuation of the variables in vars.
forall_ :: [(Text, Sort)] -> Term -> Term

-- | exists_ vars t denotes a predicate that holds if t
--   for some valuation of the variables in vars.
exists_ :: [(Text, Sort)] -> Term -> Term

-- | Create a let binding. NOTE: SMTLib2 defines this to be a "parallel"
--   let, which means that the bound variables are NOT in scope in the
--   right-hand sides of other bindings, even syntactically-later ones.
letBinder :: [(Text, Term)] -> Term -> Term

-- | Negate an integer or real number.
negate :: Term -> Term

-- | Create a numeral literal from the given integer.
numeral :: Integer -> Term

-- | Create a literal as a real from the given integer.
decimal :: Integer -> Term

-- | sub x1 [x2, ..., xn] with n >= 1 returns x1 minus
--   x2 + ... + xn.
--   
--   The terms are expected to have type Int or Real.
sub :: Term -> [Term] -> Term

-- | add [x1, x2, ..., xn] with n >= 2 returns x1
--   minus x2 + ... + xn.
--   
--   The terms are expected to have type Int or Real.
add :: [Term] -> Term

-- | add [x1, x2, ..., xn] with n >= 2 returns x1
--   minus x2 + ... + xn.
--   
--   The terms are expected to have type Int or Real.
mul :: [Term] -> Term

-- | div x1 [x2, ..., xn] with n >= 1 returns x1 div
--   x2 * ... * xn.
--   
--   The terms are expected to have type Int.
div :: Term -> [Term] -> Term

-- | x1 ./ [x2, ..., xn] with n >= 1 returns x1 /
--   x2 * ... * xn.
(./) :: Term -> [Term] -> Term

-- | mod x1 x2 returns x1 - x2 * (x1 div [x2])@.
--   
--   The terms are expected to have type Int.
mod :: Term -> Term -> Term

-- | abs x1 returns the absolute value of x1.
--   
--   The term is expected to have type Int.
abs :: Term -> Term

-- | Less than or equal over a chained list of terms.
--   
--   le [x1, x2, ..., xn] is equivalent to x1 <= x2  x2
--   <= x3  ... / x(n-1) <= xn.
--   
--   This is defined in the Reals, Ints, and Reals_Ints theories, and the
--   number of elements must be at least 2.
--   
--   With a strict interpretation of the SMTLIB standard, the terms should
--   be all of the same type (i.e. Int or Real"), but existing
--   solvers appear to implicitly all mixed terms.
le :: [Term] -> Term

-- | Less than over a chained list of terms.
--   
--   lt [x1, x2, ..., xn] is equivalent to x1 < x2  x2
--   < x3  ... / x(n-1) < xn.
--   
--   With a strict interpretation of the SMTLIB standard, the terms should
--   be all of the same type (i.e. Int or Real"), but existing
--   solvers appear to implicitly all mixed terms.
lt :: [Term] -> Term

-- | Greater than or equal over a chained list of terms.
--   
--   ge [x1, x2, ..., xn] is equivalent to x1 >= x2  x2
--   >= x3  ... / x(n-1) >= xn.
--   
--   With a strict interpretation of the SMTLIB standard, the terms should
--   be all of the same type (i.e. Int or Real"), but existing
--   solvers appear to implicitly all mixed terms.
ge :: [Term] -> Term

-- | Greater than over a chained list of terms.
--   
--   gt [x1, x2, ..., xn] is equivalent to x1 > x2  x2
--   > x3  ... / x(n-1) > xn.
--   
--   With a strict interpretation of the SMTLIB standard, the terms should
--   be all of the same type (i.e. Int or Real"), but existing
--   solvers appear to implicitly all mixed terms.
gt :: [Term] -> Term

-- | Maps a term with type Int to Real.
toReal :: Term -> Term

-- | Returns the largest integer not larger than the given real term.
toInt :: Term -> Term

-- | Returns true if this is an integer.
isInt :: Term -> Term

-- | concat x y returns the bitvector with the bits of x
--   followed by the bits of y.
concat :: Term -> Term -> Term

-- | extract i j x returns the bitvector containing the bits
--   [j..i].
extract :: Natural -> Natural -> Term -> Term

-- | Bitwise negation of term.
bvnot :: Term -> Term

-- | Bitwise and of all arguments.
bvand :: Term -> [Term] -> Term

-- | Bitwise include or of all arguments.
bvor :: Term -> [Term] -> Term

-- | Bitvector exclusive or of all arguments.
bvxor :: Term -> [Term] -> Term

-- | Negate the bitvector
bvneg :: Term -> Term

-- | Bitvector addition
bvadd :: Term -> [Term] -> Term

-- | Bitvector subtraction
bvsub :: Term -> Term -> Term

-- | Bitvector multiplication
bvmul :: Term -> [Term] -> Term

-- | bvudiv x y returns floor (to_nat x / to_nat y) when
--   y != 0.
--   
--   When y = 0, this returns not (from_nat 0).
bvudiv :: Term -> Term -> Term

-- | bvurem x y returns x - y * bvudiv x y when y !=
--   0.
--   
--   When y = 0, this returns from_nat 0.
bvurem :: Term -> Term -> Term

-- | bvshl x y shifts the bits in x to the left by
--   to_nat u bits.
--   
--   The new bits are zeros (false)
bvshl :: Term -> Term -> Term

-- | bvlshr x y shifts the bits in x to the right by
--   to_nat u bits.
--   
--   The new bits are zeros (false)
bvlshr :: Term -> Term -> Term

-- | bvult x y returns a Boolean term that is true if to_nat x
--   < to_nat y.
bvult :: Term -> Term -> Term

-- | A 1-bit bitvector representing 0.
bit0 :: Term

-- | A 1-bit bitvector representing 1.
bit1 :: Term

-- | bvbinary w x constructs a bitvector term with width
--   w equal to x mod 2^w.
--   
--   The width w must be positive.
--   
--   The literal uses a binary notation.
bvbinary :: 1 <= w => NatRepr w -> BV w -> Term

-- | bvdecimal x w constructs a bitvector term with width
--   w equal to x mod 2^w.
--   
--   The width w must be positive.
--   
--   The literal uses a decimal notation.
bvdecimal :: 1 <= w => NatRepr w -> BV w -> Term

-- | bvhexadecimal x w constructs a bitvector term with width
--   w equal to x mod 2^w.
--   
--   The width w must be a positive multiple of 4.
--   
--   The literal uses hex notation.
bvhexadecimal :: 1 <= w => NatRepr w -> BV w -> Term

-- | bvashr x y shifts the bits in x to the right by
--   to_nat u bits.
--   
--   The new bits are the same as the most-significant bit of x.
--   
--   Note. This is in QF_BV, but not the bitvector theory.
bvashr :: Term -> Term -> Term

-- | bvslt x y returns a Boolean term that is true if to_int x
--   < to_int y.
--   
--   Note. This is in QF_BV, but not the bitvector theory.
bvslt :: Term -> Term -> Term

-- | bvsle x y returns a Boolean term that is true if to_int x
--   <= to_int y.
--   
--   Note. This is in QF_BV, but not the bitvector theory.
bvsle :: Term -> Term -> Term

-- | bvule x y returns a Boolean term that is true if to_nat x
--   <= to_nat y.
--   
--   Note. This is in QF_BV, but not the bitvector theory.
bvule :: Term -> Term -> Term

-- | bvsgt x y returns a Boolean term that is true if to_int x
--   < to_int y.
--   
--   Note. This is in QF_BV, but not the bitvector theory.
bvsgt :: Term -> Term -> Term

-- | bvsge x y returns a Boolean term that is true if to_int x
--   <= to_int y.
--   
--   Note. This is in QF_BV, but not the bitvector theory.
bvsge :: Term -> Term -> Term

-- | bvugt x y returns a Boolean term that is true if to_nat x
--   < to_nat y.
--   
--   Note. This is in QF_BV, but not the bitvector theory.
bvugt :: Term -> Term -> Term

-- | bvuge x y returns a Boolean term that is true if to_nat x
--   <= to_nat y.
--   
--   Note. This is in QF_BV, but not the bitvector theory.
bvuge :: Term -> Term -> Term

-- | bvsdiv x y returns round_to_zero (to_int x / to_int
--   y) when y != 0.
--   
--   When y = 0, this returns not (from_nat 0).
--   
--   Note. This is in QF_BV, but not the bitvector theory.
bvsdiv :: Term -> Term -> Term

-- | bvsrem x y returns x - y * bvsdiv x y when y !=
--   0.
--   
--   When y = 0, this returns from_nat 0.
--   
--   Note. This is in QF_BV, but not the bitvector theory.
bvsrem :: Term -> Term -> Term

-- | bvsignExtend w x adds an additional w bits to the
--   most significant bits of x by sign extending x.
--   
--   Note. This is in QF_BV, but not the bitvector theory.
bvsignExtend :: Integer -> Term -> Term

-- | bvzeroExtend w x adds an additional w zero bits to
--   the most significant bits of x.
--   
--   Note. This is in QF_BV, but not the bitvector theory.
bvzeroExtend :: Integer -> Term -> Term

-- | arraySort a b denotes the set of functions from a to
--   be b.
arraySort :: Sort -> Sort -> Sort

-- | arrayConst t1 t2 c generates an array with index type
--   t1 and value type t2 that always returns c.
--   
--   This uses the non-standard SMTLIB2 syntax ((as const (Array t1
--   t2)) c) which is supported by CVC4, CVC5, and Z3 (and perhaps
--   others).
arrayConst :: Sort -> Sort -> Term -> Term

-- | select a i denotes the value of a at i.
select :: Term -> Term -> Term

-- | store a i v denotes the array whose valuation is v
--   at index i and select a j at every other index
--   j.
store :: Term -> Term -> Term -> Term
instance GHC.Base.Semigroup What4.Protocol.SMTLib2.Syntax.Term
instance GHC.Base.Monoid What4.Protocol.SMTLib2.Syntax.Term
instance Data.String.IsString What4.Protocol.SMTLib2.Syntax.Term
instance GHC.Show.Show What4.Protocol.SMTLib2.Syntax.SMTInfoFlag
instance GHC.Generics.Generic What4.Protocol.SMTLib2.Syntax.SMTInfoFlag
instance GHC.Classes.Ord What4.Protocol.SMTLib2.Syntax.SMTInfoFlag
instance GHC.Classes.Eq What4.Protocol.SMTLib2.Syntax.SMTInfoFlag
instance Data.Data.Data What4.Protocol.SMTLib2.Syntax.SMTInfoFlag

module What4.SatResult
data SatResult mdl core
Sat :: mdl -> SatResult mdl core
Unsat :: core -> SatResult mdl core
Unknown :: SatResult mdl core
isSat :: SatResult mdl core -> Bool
isUnsat :: SatResult mdl core -> Bool
isUnknown :: SatResult mdl core -> Bool
forgetModelAndCore :: SatResult a b -> SatResult () ()
traverseSatResult :: Applicative t => (a -> t q) -> (b -> t r) -> SatResult a b -> t (SatResult q r)
instance GHC.Generics.Generic (What4.SatResult.SatResult mdl core)
instance (GHC.Show.Show mdl, GHC.Show.Show core) => GHC.Show.Show (What4.SatResult.SatResult mdl core)

-- | The algebraic assumptions we make about our semirings are that:
--   
--   
--   
- addition is commutative and associative, with a unit called
--   zero,
--   
- multiplication is commutative and associative, with a unit called
--   one,
--   
- one and zero are distinct values,
--   
- multiplication distributes through addition, and
--   
- multiplication by zero gives zero.
--   
--   
--   Note that we do not assume the existence of additive inverses (hence,
--   semirings), but we do assume commutativity of multiplication.
--   
--   Note, moreover, that bitvectors can be equipped with two different
--   semirings (the usual arithmetic one and the XOR/AND boolean ring
--   imposed by the boolean algebra structure), which occasionally requires
--   some care.
--   
--   In addition, some semirings are "ordered" semirings. These are
--   equipped with a total ordering relation such that addition is both
--   order-preserving and order-reflecting; that is, x <= y iff
--   x + z <= y + z. Moreover ordered semirings satisfy: 0
--   <= x and 0 <= y implies 0 <= x*y.
module What4.SemiRing

-- | Data-kind representing the semirings What4 supports.
data SemiRing
type SemiRingInteger = -- | @:: 'SemiRing'@ 'SemiRingInteger
type SemiRingReal = -- | @:: 'SemiRing'@ 'SemiRingReal
type SemiRingBV = -- | @:: 'BVFlavor' -> 'Nat' -> 'SemiRing'@ 'SemiRingBV

-- | Data-kind indicating the two flavors of bitvector semirings. The
--   ordinary arithmetic semiring consists of addition and multiplication,
--   and the "bits" semiring consists of bitwise xor and bitwise and.
data BVFlavor
type BVBits = -- | @:: 'BVFlavor'@ 'BVBits
type BVArith = -- | @:: 'BVFlavor'@ 'BVArith
data SemiRingRepr (sr :: SemiRing)
[SemiRingIntegerRepr] :: SemiRingRepr SemiRingInteger
[SemiRingRealRepr] :: SemiRingRepr SemiRingReal
[SemiRingBVRepr] :: 1 <= w => !BVFlavorRepr fv -> !NatRepr w -> SemiRingRepr (SemiRingBV fv w)

-- | The subset of semirings that are equipped with an appropriate
--   (order-respecting) total order.
data OrderedSemiRingRepr (sr :: SemiRing)
[OrderedSemiRingIntegerRepr] :: OrderedSemiRingRepr SemiRingInteger
[OrderedSemiRingRealRepr] :: OrderedSemiRingRepr SemiRingReal
data BVFlavorRepr (fv :: BVFlavor)
[BVArithRepr] :: BVFlavorRepr BVArith
[BVBitsRepr] :: BVFlavorRepr BVBits
type family SemiRingBase (sr :: SemiRing) :: BaseType

-- | Compute the base type of the given semiring.
semiRingBase :: SemiRingRepr sr -> BaseTypeRepr (SemiRingBase sr)

-- | Compute the semiring corresponding to the given ordered semiring.
orderedSemiRing :: OrderedSemiRingRepr sr -> SemiRingRepr sr

-- | The constant values in the semiring.
type family Coefficient (sr :: SemiRing) :: Type
zero :: SemiRingRepr sr -> Coefficient sr
one :: SemiRingRepr sr -> Coefficient sr
add :: SemiRingRepr sr -> Coefficient sr -> Coefficient sr -> Coefficient sr
mul :: SemiRingRepr sr -> Coefficient sr -> Coefficient sr -> Coefficient sr
eq :: SemiRingRepr sr -> Coefficient sr -> Coefficient sr -> Bool
le :: OrderedSemiRingRepr sr -> Coefficient sr -> Coefficient sr -> Bool
lt :: OrderedSemiRingRepr sr -> Coefficient sr -> Coefficient sr -> Bool
sr_compare :: SemiRingRepr sr -> Coefficient sr -> Coefficient sr -> Ordering
sr_hashWithSalt :: SemiRingRepr sr -> Int -> Coefficient sr -> Int

-- | The Occurrence family counts how many times a term occurs in a
--   product. For most semirings, this is just a natural number
--   representing the exponent. For the boolean ring of bitvectors,
--   however, it is unit because the lattice operations are idempotent.
type family Occurrence (sr :: SemiRing) :: Type
occ_add :: SemiRingRepr sr -> Occurrence sr -> Occurrence sr -> Occurrence sr
occ_one :: SemiRingRepr sr -> Occurrence sr
occ_eq :: SemiRingRepr sr -> Occurrence sr -> Occurrence sr -> Bool
occ_hashWithSalt :: SemiRingRepr sr -> Int -> Occurrence sr -> Int
occ_compare :: SemiRingRepr sr -> Occurrence sr -> Occurrence sr -> Ordering
occ_count :: SemiRingRepr sr -> Occurrence sr -> Natural
instance Data.Type.Equality.TestEquality What4.SemiRing.BVFlavorRepr
instance GHC.Classes.Eq (What4.SemiRing.BVFlavorRepr fv)
instance Data.Type.Equality.TestEquality What4.SemiRing.OrderedSemiRingRepr
instance GHC.Classes.Eq (What4.SemiRing.OrderedSemiRingRepr sr)
instance Data.Type.Equality.TestEquality What4.SemiRing.SemiRingRepr
instance GHC.Classes.Eq (What4.SemiRing.SemiRingRepr sr)
instance Data.Parameterized.Classes.OrdF What4.SemiRing.BVFlavorRepr
instance Data.Parameterized.Classes.OrdF What4.SemiRing.OrderedSemiRingRepr
instance Data.Parameterized.Classes.OrdF What4.SemiRing.SemiRingRepr
instance Data.Parameterized.Classes.HashableF What4.SemiRing.BVFlavorRepr
instance Data.Hashable.Class.Hashable (What4.SemiRing.BVFlavorRepr fv)
instance Data.Parameterized.Classes.HashableF What4.SemiRing.OrderedSemiRingRepr
instance Data.Hashable.Class.Hashable (What4.SemiRing.OrderedSemiRingRepr sr)
instance Data.Parameterized.Classes.HashableF What4.SemiRing.SemiRingRepr
instance Data.Hashable.Class.Hashable (What4.SemiRing.SemiRingRepr sr)

-- | Log msgs via a synchronized channel.
--   
--   With inspiration from the monad-logger package.
--   
--   See examples in Tests.
--   
--   WARNING: loggers that automatically infer the call stack (via
--   HasCallStack) are not composable, in that they infer a call
--   stack at their call site. So, if you use one to build up another log
--   function, then that derived log function will infer bogus call sites!
--   Of course, it's pretty easy to write
--   
--   writeLogEvent logCfg level msg
--   
--   when defining a new logger, so not a big deal, just something to watch
--   out for.
module What4.Serialize.Log

-- | Log levels, in increasing severity/precedence order.
data LogLevel

-- | Fine details
Debug :: LogLevel

-- | Tracking progress
Info :: LogLevel

-- | Something notable or suspicious
Warn :: LogLevel

-- | Something bad
Error :: LogLevel

-- | A log event.
--   
--   Can be converted to a string later, or thrown away.
data LogEvent
LogEvent :: (Maybe String, SrcLoc) -> LogLevel -> LogMsg -> ThreadId -> UTCTime -> LogEvent

-- | The Maybe String is the name of the enclosing function in
--   which the logging function was called. Not always available, since it
--   depends on the enclosing function having a HasCallStack
--   constraint.
[leCallSite] :: LogEvent -> (Maybe String, SrcLoc)
[leLevel] :: LogEvent -> LogLevel
[leMsg] :: LogEvent -> LogMsg

-- | ID of thread that generated the event.
[leThreadId] :: LogEvent -> ThreadId
[leTime] :: LogEvent -> UTCTime
type LogMsg = String

-- | Request a CallStack.
--   
--   NOTE: The implicit parameter ?callStack :: CallStack is an
--   implementation detail and should not be considered part of the
--   CallStack API, we may decide to change the implementation in
--   the future.
type HasCallStack = ?callStack :: CallStack

-- | Access to the log config.
--   
--   Users should prefer withLogCfg to binding the implicit param.
--   The implicit param is an implementation detail, and we could change
--   the implementation later, e.g. to use the reflection package.
--   
--   We use an implicit param to avoid having to change all code in
--   IO that wants to log to be in MonadHasLogCfg and
--   MonadIO classes.
--   
--   An even more convenient but more "unsafe" implementation would store
--   the LogCfg in a global, unsafePerformIOd
--   IORef (cf. uniqueSource in Unique).
type HasLogCfg = (?logCfg :: LogCfg)

-- | Log in a MonadIO.
--   
--   If you want the name of function that called log to be included
--   in the output, then you need to add a HasCallStack constraint
--   to it as well (see LogC). Otherwise, one of two things will
--   happen:
--   
--   
--   
- if no enclosing function has a HasCallStack constraint,
--   then ??? will be used for the enclosing function name.
--   
- if at least one enclosing function has a HasCallStack
--   constraint, then the name of the *closest* enclosing function with
--   that constraint will be used for the enclosing function name. So, for
--   example, if you define outer by
--   
--   
--   
--   outer :: (MonadHasLogCfg m, Ghc.HasCallStack) => m Int
--   outer = inner
--     where
--       inner = do
--         log Debug "Inside 'inner' ..."
--         return 42
--   
--   
--   then the call to log in inner will have "outer" as the
--   enclosing function name.
logIO :: (HasLogCfg, HasCallStack, MonadIO m) => LogLevel -> LogMsg -> m ()

-- | Log in pure code using unsafePerformIO, like Trace.
--   
--   See logIO.
logTrace :: (HasLogCfg, HasCallStack) => LogLevel -> LogMsg -> a -> a

-- | Satisfy a HasLogCfg constraint.
--   
--   Users can call this function instead of using ImplicitParams
--   themselves.
withLogCfg :: LogCfg -> (HasLogCfg => a) -> a

-- | Recover the log config.
--   
--   Useful for going between implicit and monadic interfaces. E.g.
--   
--   
--   flip runReaderT getLogCfg ...
--   
getLogCfg :: HasLogCfg => LogCfg

-- | logIO with an explicit config
logIOWith :: (HasCallStack, MonadIO m) => LogCfg -> LogLevel -> LogMsg -> m ()

-- | Signal to the log consumer that there are no more log messages and
--   terminate the log consumer. This is useful for cases where the logger
--   is running in a separate thread and the parent thread wants to wait
--   until the logger has finished logging and has successfully flushed all
--   log messages before terminating it.
logEndWith :: LogCfg -> IO ()

-- | Write a LogEvent to the underlying channel.
--   
--   This is a low-level function. See logIO, logM, and
--   logTrace for a high-level interface that supplies the
--   LogCfg and CallStack parameters automatically.
--   
--   However, those functions can't be used to build up custom loggers,
--   since they infer call stack information automatically. If you want to
--   define a custom logger (even something simple like
--   
--   
--   debug msg = logM Debug msg
--   
--   
--   ) then use writeLogEvent.
writeLogEvent :: LogCfg -> CallStack -> LogLevel -> LogMsg -> IO ()

-- | Monads with logger configuration.
class MonadHasLogCfg m
getLogCfgM :: MonadHasLogCfg m => m LogCfg

-- | Log in a MonadHasLogCfg.
--   
--   See logIO.
logM :: (MonadHasLogCfg m, HasCallStack, MonadIO m) => LogLevel -> LogMsg -> m ()

-- | Logging configuration.
data LogCfg

-- | Initialize a LogCfg.
--   
--   The first argument is the human friendly name to assign to the current
--   thread. Since logging should be configured as soon as possible on
--   startup, "main" is probably the right name.
--   
--   See asyncNamed for naming other threads.
--   
--   Need to start a log event consumer in another thread, e.g.
--   stdErrLogEventConsumer, if you want anything to happen with the
--   log events.
mkLogCfg :: String -> IO LogCfg

-- | Initialize a LogCfg that does no logging.
--   
--   This can be used as a LogCfg when no logging is to be performed.
--   Runtime overhead is smaller when this configuration is specified at
--   compile time.
mkNonLogCfg :: IO LogCfg

-- | Run an action with the given log event consumer.
--   
--   In particular this provides an easy way to run one-off computations
--   that assume logging, e.g. in GHCi. Spawns the log even consumer before
--   running the action and cleans up the log event consumer afterwards.
withLogging :: (MonadUnliftIO m, MonadIO m) => String -> (LogCfg -> IO ()) -> (HasLogCfg => m a) -> m a

-- | A log event consumer that prints formatted log events to stderr.
stdErrLogEventConsumer :: (LogEvent -> Bool) -> LogCfg -> IO ()

-- | A logger that writes to a user-specified file
--   
--   Note that logs are opened in the w mode (i.e., overwrite).
--   Callers should preserve old log files if they really want.
fileLogEventConsumer :: FilePath -> (LogEvent -> Bool) -> LogCfg -> IO ()

-- | A log event consumer that writes formatted log events to a tmp file.
tmpFileLogEventConsumer :: (LogEvent -> Bool) -> LogCfg -> IO ()

-- | Format a log event.
prettyLogEvent :: LogEvent -> String

-- | Consume a log channel until it receives a shutdown message (i.e. a
--   Nothing).
--   
--   Only messages that satisfy the predicate will be passed to the
--   continuation. For example, using const True will process all
--   log messages, and using (>= Info) . leLevel will only
--   process messsages with LogLevel equal to Info or higher,
--   ignoring Debug level messages.
consumeUntilEnd :: (LogEvent -> Bool) -> (LogEvent -> IO ()) -> LogCfg -> IO ()

-- | Run an IO action with a human friendly thread name.
--   
--   Any existing thread name will be restored when the action finishes.
named :: (MonadUnliftIO m, MonadIO m) => LogCfg -> String -> m a -> m a

-- | Version of named for implicit log cfg.
namedIO :: (HasLogCfg, MonadUnliftIO m, MonadIO m) => String -> m a -> m a

-- | Version of named for MonadHasLogCfg monads.
namedM :: (MonadHasLogCfg m, MonadUnliftIO m, MonadIO m) => String -> m a -> m a
instance GHC.Read.Read What4.Serialize.Log.LogLevel
instance GHC.Classes.Ord What4.Serialize.Log.LogLevel
instance GHC.Classes.Eq What4.Serialize.Log.LogLevel
instance GHC.Show.Show What4.Serialize.Log.LogLevel

-- | Definition of the S-Expression tokens used to (de)serialize What4
--   expressions.
module What4.Serialize.SETokens
data Atom

-- | An identifier.
AId :: Text -> Atom

-- | A prefix followed by a string literal (.e.g, AStr "u" "Hello World" is
--   serialize as `#u"Hello World"`).
AStr :: Some StringInfoRepr -> Text -> Atom

-- | Integer (i.e., unbounded) literal.
AInt :: Integer -> Atom

-- | Natural (i.e., unbounded) literal
ANat :: Natural -> Atom

-- | Real (i.e., unbounded) literal.
AReal :: Rational -> Atom

-- | A floating point literal (with precision)
AFloat :: Some FloatPrecisionRepr -> BigFloat -> Atom

-- | Bitvector, width and then value.
ABV :: Int -> Integer -> Atom

-- | Boolean literal.
ABool :: Bool -> Atom
string :: Some StringInfoRepr -> Text -> SExpr

-- | Lift an unquoted identifier.
ident :: Text -> SExpr

-- | Lift an integer.
int :: Integer -> SExpr

-- | Lift a natural
nat :: Natural -> SExpr

-- | Lift a bitvector.
bitvec :: Natural -> Integer -> SExpr

-- | Lift a boolean.
bool :: Bool -> SExpr

-- | Lift a real
real :: Rational -> SExpr

-- | Lift a float
float :: FloatPrecisionRepr fpp -> BigFloat -> SExpr
string' :: Some StringInfoRepr -> String -> SExpr
ident' :: String -> SExpr
printAtom :: Atom -> Text

-- | Generates the the S-expression tokens represented by the sexpr
--   argument, preceeded by a list of strings output as comments.
printSExpr :: Seq String -> SExpr -> Text
parseSExpr :: Text -> Either String SExpr
instance GHC.Classes.Ord What4.Serialize.SETokens.Atom
instance GHC.Classes.Eq What4.Serialize.SETokens.Atom
instance GHC.Show.Show What4.Serialize.SETokens.Atom

-- | This module implements a specialized s-expression parser
--   
--   The parser in s-cargot is very general, but that also makes it a bit
--   inefficient. This module implements a drop-in replacement parser for
--   the one in What4.Serialize.Parser using megaparsec. It is completely
--   specialized to the types in this library.
module What4.Serialize.FastSExpr

-- | Parse Text into the well-formed s-expression type from
--   s-cargot.
parseSExpr :: Text -> Either String (WellFormedSExpr Atom)
instance GHC.Classes.Ord What4.Serialize.FastSExpr.What4ParseError
instance GHC.Classes.Eq What4.Serialize.FastSExpr.What4ParseError
instance GHC.Show.Show What4.Serialize.FastSExpr.What4ParseError
instance Text.Megaparsec.Error.ShowErrorComponent What4.Serialize.FastSExpr.What4ParseError

-- | Utilties for representing and handling certain "special" functions
--   arising from analysis. Although many of these functions are most
--   properly understood as complex valued functions on complex arguments,
--   here we are primarily interested in their restriction to real-valued
--   functions or their floating-point approximations.
--   
--   The functions considered here include functions from standard and
--   hyperbolic trigonometry, exponential and logarithmic functions, etc.
--   Some of these functions are defineable in terms of others (e.g.
--   tan(x) = sin(x)/cos(x) or expm1(x) = exp(x) - 1@) but are
--   commonly implemented separately in math libraries for increased
--   precision. Some popular constant values are also included.
module What4.SpecialFunctions

-- | Phantom data index representing the real number line. Used for
--   specifying the arity of special functions.
data R

-- | Data type for representing "special" functions. These include
--   functions from standard and hyperbolic trigonometry, exponential and
--   logarithmic functions, as well as other well-known mathematical
--   functions.
--   
--   Generally, little solver support exists for such functions (although
--   systems like dReal and Metatarski can prove some properties).
--   Nonetheless, we may have some information about specific values these
--   functions take, the domains on which they are defined, or the range of
--   values their outputs may take, or specific relationships that may
--   exists between these functions (e.g., trig identities). This
--   information may, in some circumstances, be sufficent to prove
--   properties of interest, even if the functions cannot be represented in
--   their entirety.
data SpecialFunction (args :: Ctx Type)
[Pi] :: SpecialFunction EmptyCtx
[HalfPi] :: SpecialFunction EmptyCtx
[QuarterPi] :: SpecialFunction EmptyCtx
[OneOverPi] :: SpecialFunction EmptyCtx
[TwoOverPi] :: SpecialFunction EmptyCtx
[TwoOverSqrt_Pi] :: SpecialFunction EmptyCtx
[Sqrt_2] :: SpecialFunction EmptyCtx
[Sqrt_OneHalf] :: SpecialFunction EmptyCtx
[E] :: SpecialFunction EmptyCtx
[Log2_E] :: SpecialFunction EmptyCtx
[Log10_E] :: SpecialFunction EmptyCtx
[Ln_2] :: SpecialFunction EmptyCtx
[Ln_10] :: SpecialFunction EmptyCtx
[Sin] :: SpecialFunction (EmptyCtx ::> R)
[Cos] :: SpecialFunction (EmptyCtx ::> R)
[Tan] :: SpecialFunction (EmptyCtx ::> R)
[Arcsin] :: SpecialFunction (EmptyCtx ::> R)
[Arccos] :: SpecialFunction (EmptyCtx ::> R)
[Arctan] :: SpecialFunction (EmptyCtx ::> R)
[Sinh] :: SpecialFunction (EmptyCtx ::> R)
[Cosh] :: SpecialFunction (EmptyCtx ::> R)
[Tanh] :: SpecialFunction (EmptyCtx ::> R)
[Arcsinh] :: SpecialFunction (EmptyCtx ::> R)
[Arccosh] :: SpecialFunction (EmptyCtx ::> R)
[Arctanh] :: SpecialFunction (EmptyCtx ::> R)
[Hypot] :: SpecialFunction ((EmptyCtx ::> R) ::> R)
[Arctan2] :: SpecialFunction ((EmptyCtx ::> R) ::> R)
[Pow] :: SpecialFunction ((EmptyCtx ::> R) ::> R)
[Exp] :: SpecialFunction (EmptyCtx ::> R)
[Log] :: SpecialFunction (EmptyCtx ::> R)
[Expm1] :: SpecialFunction (EmptyCtx ::> R)
[Log1p] :: SpecialFunction (EmptyCtx ::> R)
[Exp2] :: SpecialFunction (EmptyCtx ::> R)
[Log2] :: SpecialFunction (EmptyCtx ::> R)
[Exp10] :: SpecialFunction (EmptyCtx ::> R)
[Log10] :: SpecialFunction (EmptyCtx ::> R)

-- | Some special functions exhibit useful symmetries in their arguments. A
--   function f is an odd function if f(-x) = -f(x), and
--   is even if f(-x) = f(x). We extend this notion to arguments
--   of more than one function by saying that a function is even/odd in its
--   ith argument if it is even/odd when the other arguments are
--   fixed.
data FunctionSymmetry r
NoSymmetry :: FunctionSymmetry r
EvenFunction :: FunctionSymmetry r
OddFunction :: FunctionSymmetry r

-- | Compute function symmetry information for the given special function.
specialFnSymmetry :: SpecialFunction args -> Assignment FunctionSymmetry args

-- | Data type for wrapping the actual arguments to special functions.
data SpecialFnArg (e :: k -> Type) (tp :: k) (r :: Type)
[SpecialFnArg] :: e tp -> SpecialFnArg e tp R
traverseSpecialFnArg :: Applicative m => (e tp -> m (f tp)) -> SpecialFnArg e tp r -> m (SpecialFnArg f tp r)

-- | Data type for wrapping a collction of actual arguments to special
--   functions.
newtype SpecialFnArgs (e :: k -> Type) (tp :: k) args
SpecialFnArgs :: Assignment (SpecialFnArg e tp) args -> SpecialFnArgs (e :: k -> Type) (tp :: k) args
traverseSpecialFnArgs :: Applicative m => (e tp -> m (f tp)) -> SpecialFnArgs e tp r -> m (SpecialFnArgs f tp r)

-- | Values that can appear in the definition of domain and range intervals
--   for special functions.
data RealPoint
Zero :: RealPoint
NegOne :: RealPoint
PosOne :: RealPoint
NegInf :: RealPoint
PosInf :: RealPoint
NegPi :: RealPoint
PosPi :: RealPoint
NegHalfPi :: RealPoint
PosHalfPi :: RealPoint

-- | The endpoint of an interval, which may be inclusive or exclusive.
data RealBound
Incl :: RealPoint -> RealBound
Excl :: RealPoint -> RealBound

-- | An interval on real values, or a point.
data RealInterval r
[RealPoint] :: SpecialFunction EmptyCtx -> RealInterval R
[RealInterval] :: RealBound -> RealBound -> RealInterval R

-- | Compute the domain of the given special function. As a mathematical
--   entity, the value of the given function is not well-defined outside
--   its domain. In floating-point terms, a special function will return a
--   NaN when evaluated on arguments outside its domain.
specialFnDomain :: SpecialFunction args -> Assignment RealInterval args

-- | Compute the range of values that may be returned by the given special
--   function as its arguments take on the possible values of its domain.
--   This may include limiting values if the function's domain includes
--   infinities; for example exp(-inf) = 0.
specialFnRange :: SpecialFunction args -> RealInterval R
instance Data.Parameterized.Classes.HashableF What4.SpecialFunctions.SpecialFunction
instance Data.Hashable.Class.Hashable (What4.SpecialFunctions.SpecialFunction args)
instance Data.Type.Equality.TestEquality What4.SpecialFunctions.SpecialFunction
instance GHC.Classes.Eq (What4.SpecialFunctions.SpecialFunction args)
instance Data.Parameterized.Classes.OrdF What4.SpecialFunctions.SpecialFunction
instance forall k (e :: k -> GHC.Types.Type) (tp :: k). Data.Parameterized.Classes.OrdF e => Data.Type.Equality.TestEquality (What4.SpecialFunctions.SpecialFnArg e tp)
instance forall k (e :: k -> GHC.Types.Type) (tp :: k). Data.Parameterized.Classes.OrdF e => Data.Parameterized.Classes.OrdF (What4.SpecialFunctions.SpecialFnArg e tp)
instance forall k (e :: k -> GHC.Types.Type) (tp :: k). Data.Parameterized.Classes.HashableF e => Data.Parameterized.Classes.HashableF (What4.SpecialFunctions.SpecialFnArg e tp)
instance forall k (e :: k -> GHC.Types.Type) (tp :: k) (r :: Data.Parameterized.Ctx.Ctx GHC.Types.Type). Data.Parameterized.Classes.OrdF e => GHC.Classes.Eq (What4.SpecialFunctions.SpecialFnArgs e tp r)
instance forall k (e :: k -> GHC.Types.Type) (tp :: k) (r :: Data.Parameterized.Ctx.Ctx GHC.Types.Type). Data.Parameterized.Classes.OrdF e => GHC.Classes.Ord (What4.SpecialFunctions.SpecialFnArgs e tp r)
instance forall k (e :: k -> GHC.Types.Type) (tp :: k) (args :: Data.Parameterized.Ctx.Ctx GHC.Types.Type). (Data.Parameterized.Classes.HashableF e, Data.Parameterized.Classes.OrdF e) => Data.Hashable.Class.Hashable (What4.SpecialFunctions.SpecialFnArgs e tp args)
instance forall k (r :: k). GHC.Show.Show (What4.SpecialFunctions.FunctionSymmetry r)
instance GHC.Show.Show (What4.SpecialFunctions.RealInterval r)
instance GHC.Show.Show What4.SpecialFunctions.RealPoint
instance GHC.Show.Show (What4.SpecialFunctions.SpecialFunction args)

-- | This defines a datatype for representing identifiers that can be used
--   with Crucible. These must start with an ASCII letter and can consist
--   of any characters in the set [a-z
--   A-Z '0-9' '_'] as long as the result is
--   not an SMTLIB or Yices keyword.
module What4.Symbol

-- | This represents a name known to the solver.
--   
--   We have three types of symbols:
--   
--   
--   
- The empty symbol
--   
- A user symbol
--   
- A system symbol
--   
--   
--   A user symbol should consist of a letter followed by any combination
--   of letters, digits, and underscore characters. It also cannot be a
--   reserved word in Yices or SMTLIB.
--   
--   A system symbol should start with a letter followed by any number of
--   letter, digit, underscore or an exclamation mark characters. It must
--   contain at least one exclamation mark to distinguish itself from user
--   symbols.
data SolverSymbol
solverSymbolAsText :: SolverSymbol -> Text

-- | This describes why a given text value was not a valid solver symbol.
data SolverSymbolError

-- | Return the empty symbol.
emptySymbol :: SolverSymbol

-- | This returns either a user symbol or the empty symbol if the string is
--   empty.
userSymbol :: String -> Either SolverSymbolError SolverSymbol
systemSymbol :: String -> SolverSymbol

-- | Attempts to create a user symbol from the given string. If this fails
--   for some reason, the string is Z-encoded into a system symbol instead
--   with the prefix "zenc!".
safeSymbol :: String -> SolverSymbol
ppSolverSymbolError :: SolverSymbolError -> String
instance Data.Hashable.Class.Hashable What4.Symbol.SolverSymbol
instance GHC.Classes.Ord What4.Symbol.SolverSymbol
instance GHC.Classes.Eq What4.Symbol.SolverSymbol
instance GHC.Show.Show What4.Symbol.SolverSymbol
instance GHC.Show.Show What4.Symbol.SolverSymbolError

-- | A finite map data structure with monoidal annotations.
module What4.Utils.AnnotatedMap
data AnnotatedMap k v a
null :: AnnotatedMap k v a -> Bool
empty :: (Ord k, Semigroup v) => AnnotatedMap k v a
singleton :: (Ord k, Semigroup v) => k -> v -> a -> AnnotatedMap k v a
size :: (Ord k, Semigroup v) => AnnotatedMap k v a -> Int
lookup :: (Ord k, Semigroup v) => k -> AnnotatedMap k v a -> Maybe (v, a)
delete :: (Ord k, Semigroup v) => k -> AnnotatedMap k v a -> AnnotatedMap k v a
annotation :: (Ord k, Semigroup v) => AnnotatedMap k v a -> Maybe v
toList :: AnnotatedMap k v a -> [(k, a)]
fromAscList :: (Ord k, Semigroup v) => [(k, v, a)] -> AnnotatedMap k v a
insert :: (Ord k, Semigroup v) => k -> v -> a -> AnnotatedMap k v a -> AnnotatedMap k v a
alter :: (Ord k, Semigroup v) => (Maybe (v, a) -> Maybe (v, a)) -> k -> AnnotatedMap k v a -> AnnotatedMap k v a
alterF :: (Functor f, Ord k, Semigroup v) => (Maybe (v, a) -> f (Maybe (v, a))) -> k -> AnnotatedMap k v a -> f (AnnotatedMap k v a)
union :: (Ord k, Semigroup v) => AnnotatedMap k v a -> AnnotatedMap k v a -> AnnotatedMap k v a
unionWith :: (Ord k, Semigroup v) => ((v, a) -> (v, a) -> (v, a)) -> AnnotatedMap k v a -> AnnotatedMap k v a -> AnnotatedMap k v a
unionWithKeyMaybe :: (Ord k, Semigroup v) => (k -> a -> a -> Maybe (v, a)) -> AnnotatedMap k v a -> AnnotatedMap k v a -> AnnotatedMap k v a
filter :: (Ord k, Semigroup v) => (a -> Bool) -> AnnotatedMap k v a -> AnnotatedMap k v a
mapMaybe :: (Ord k, Semigroup v) => (a -> Maybe b) -> AnnotatedMap k v a -> AnnotatedMap k v b
mapMaybeWithKey :: (Ord k, Semigroup v2) => (k -> v1 -> a1 -> Maybe (v2, a2)) -> AnnotatedMap k v1 a1 -> AnnotatedMap k v2 a2
traverseMaybeWithKey :: (Applicative f, Ord k, Semigroup v2) => (k -> v1 -> a1 -> f (Maybe (v2, a2))) -> AnnotatedMap k v1 a1 -> f (AnnotatedMap k v2 a2)
difference :: (Ord k, Semigroup v, Semigroup w) => AnnotatedMap k v a -> AnnotatedMap k w b -> AnnotatedMap k v a
mergeWithKey :: (Ord k, Semigroup u, Semigroup v, Semigroup w) => (k -> (u, a) -> (v, b) -> Maybe (w, c)) -> (AnnotatedMap k u a -> AnnotatedMap k w c) -> (AnnotatedMap k v b -> AnnotatedMap k w c) -> AnnotatedMap k u a -> AnnotatedMap k v b -> AnnotatedMap k w c
mergeWithKeyM :: (Ord k, Semigroup u, Semigroup v, Semigroup w, Applicative m) => (k -> (u, a) -> (v, b) -> m (w, c)) -> (k -> (u, a) -> m (w, c)) -> (k -> (v, b) -> m (w, c)) -> AnnotatedMap k u a -> AnnotatedMap k v b -> m (AnnotatedMap k w c)
mergeA :: (Ord k, Semigroup v, Applicative f) => (k -> (v, a) -> (v, a) -> f (v, a)) -> AnnotatedMap k v a -> AnnotatedMap k v a -> f (AnnotatedMap k v a)
eqBy :: Eq k => (a -> a -> Bool) -> AnnotatedMap k v a -> AnnotatedMap k v a -> Bool
instance Data.Traversable.Traversable (What4.Utils.AnnotatedMap.Entry k v)
instance Data.Foldable.Foldable (What4.Utils.AnnotatedMap.Entry k v)
instance GHC.Base.Functor (What4.Utils.AnnotatedMap.Entry k v)
instance (GHC.Classes.Ord k, GHC.Base.Semigroup v) => GHC.Base.Functor (What4.Utils.AnnotatedMap.AnnotatedMap k v)
instance (GHC.Classes.Ord k, GHC.Base.Semigroup v) => Data.Foldable.Foldable (What4.Utils.AnnotatedMap.AnnotatedMap k v)
instance (GHC.Classes.Ord k, GHC.Base.Semigroup v) => Data.Traversable.Traversable (What4.Utils.AnnotatedMap.AnnotatedMap k v)
instance (GHC.Classes.Ord k, GHC.Base.Semigroup v) => Data.FingerTree.Measured (What4.Utils.AnnotatedMap.Tag k v) (What4.Utils.AnnotatedMap.Entry k v a)
instance (GHC.Classes.Ord k, GHC.Base.Semigroup v) => GHC.Base.Semigroup (What4.Utils.AnnotatedMap.Tag k v)
instance (GHC.Classes.Ord k, GHC.Base.Semigroup v) => GHC.Base.Monoid (What4.Utils.AnnotatedMap.Tag k v)

module What4.Utils.Arithmetic

-- | Returns true if number is a power of two.
isPow2 :: (Bits a, Num a) => a -> Bool

-- | Returns floor of log base 2.
lg :: (Bits a, Num a, Ord a) => a -> Int

-- | Returns ceil of log base 2. We define lgCeil 0 = 0
lgCeil :: (Bits a, Num a, Ord a) => a -> Int

-- | nextMultiple x y computes the next multiple m of x s.t. m
--   >= y. E.g., nextMultiple 4 8 = 8 since 8 is a multiple of 8;
--   nextMultiple 4 7 = 8; nextMultiple 8 6 = 8.
nextMultiple :: Integral a => a -> a -> a

-- | nextPow2Multiple x n returns the smallest multiple of
--   2^n not less than x.
nextPow2Multiple :: (Bits a, Integral a) => a -> Int -> a

-- | This returns the sqrt of an integer if it is well-defined.
tryIntSqrt :: Integer -> Maybe Integer

-- | Return the rational sqrt of a
tryRationalSqrt :: Rational -> Maybe Rational

-- | Evaluate a real to an integer with rounding away from zero.
roundAway :: RealFrac a => a -> Integer

-- | Count trailing zeros
ctz :: NatRepr w -> Integer -> Integer

-- | Count leading zeros
clz :: NatRepr w -> Integer -> Integer
rotateLeft :: NatRepr w -> Integer -> Integer -> Integer
rotateRight :: NatRepr w -> Integer -> Integer -> Integer

-- | Provides an interval-based implementation of bitvector abstract
--   domains.
module What4.Utils.BVDomain.Arith

-- | A value of type BVDomain w represents a set of
--   bitvectors of width w. Each BVDomain can represent a
--   single contiguous interval of bitvectors that may wrap around from -1
--   to 0.
data Domain (w :: Nat)

-- | The set of all bitvectors of width w. Argument caches
--   2^w-1.
BVDAny :: !Integer -> Domain (w :: Nat)

-- | Intervals are represented by a starting value and a size.
--   BVDInterval mask l d represents the set of values of the form
--   x mod 2^w for x such that l <= x <= l +
--   d. It should satisfy the invariants 0 <= l < 2^w
--   and 0 <= d < 2^w. The first argument caches the value
--   2^w-1.
BVDInterval :: !Integer -> !Integer -> !Integer -> Domain (w :: Nat)

-- | Check if the domain satisfies its invariants
proper :: NatRepr w -> Domain w -> Bool

-- | Return the bitvector mask value from this domain
bvdMask :: Domain w -> Integer

-- | Test if the given integer value is a member of the abstract domain
member :: Domain w -> Integer -> Bool

-- | Check that a domain is proper, and that the given value is a member
pmember :: NatRepr n -> Domain n -> Integer -> Bool

-- | Unsafe constructor for internal use only. Caller must ensure that
--   mask = maxUnsigned w, and that aw is non-negative.
interval :: Integer -> Integer -> Integer -> Domain w

-- | Compute how many concrete elements are in the abstract domain
size :: Domain w -> Integer

-- | Return value if this is a singleton.
asSingleton :: Domain w -> Maybe Integer

-- | Return unsigned bounds for domain.
ubounds :: Domain w -> (Integer, Integer)

-- | Return signed bounds for domain.
sbounds :: 1 <= w => NatRepr w -> Domain w -> (Integer, Integer)
eq :: Domain w -> Domain w -> Maybe Bool

-- | Check if all elements in one domain are less than all elements in
--   other.
slt :: 1 <= w => NatRepr w -> Domain w -> Domain w -> Maybe Bool

-- | Check if all elements in one domain are less than all elements in
--   other.
ult :: 1 <= w => Domain w -> Domain w -> Maybe Bool

-- | Check if (bvult (bvadd a c) (bvadd b c)) is equivalent to
--   (bvult a b).
--   
--   This is true if and only if for all natural values i_a,
--   i_b, i_c in a, b, c,
--   either both i_a + i_c and i_b + i_c are less than
--   2^w, or both are not. We prove this by contradiction. If
--   i_a = i_b, then the property is trivial. Assume that i_a
--   < i_b. Then i_a + i_c < i_b + i_c. If exactly one
--   of the additions is less than 2^w, it must be the case that
--   i_a + i_c < 2^w and 0 <= i_b + i_c - 2^w <
--   2^w. Since i_b < 2^w, it follows that i_b + i_c
--   < 2^w + i_c, that i_b + i_c - 2^w < i_c, and that
--   i_b + i_c - 2^w < i_a + i_c. Thus, for these values of
--   i_a, i_b, i_c, (bvult a b) is
--   true, but (bvult (bvadd a c) (bvadd b c)) is false, which is
--   a contradiction.
--   
--   We check this property by case analysis on whether c is a
--   single non-wrapping interval, or it wraps around and is a union of two
--   non-wrapping intervals. For a non-wrapping (sub)interval c'
--   of c, there are four possible cases: 1. a and
--   b contain a single value. 2. (bvadd a c') and
--   (bvadd b c') do not wrap around for any values in a,
--   b, c'. 3. (bvadd a c') and (bvadd b
--   c') wrap around for all values in a, b,
--   c'.
--   
--   This is used to simplify bvult.
isUltSumCommonEquiv :: Domain w -> Domain w -> Domain w -> Bool

-- | Return true if domains contain a common element.
domainsOverlap :: Domain w -> Domain w -> Bool

-- | Return the (lo,sz), the low bound and size of the given
--   arithmetic interval. A value x is in the set defined by this
--   domain iff (x - lo) mod w <= sz holds. Returns
--   Nothing if the domain contains all values.
arithDomainData :: Domain w -> Maybe (Integer, Integer)

-- | Return bitwise bounds for domain (i.e. logical AND of all possible
--   values, paired with logical OR of all possible values).
bitbounds :: Domain w -> (Integer, Integer)

-- | unknowns lo hi returns a bitmask representing the set of bit
--   positions whose values are not constant throughout the range
--   lo..hi.
unknowns :: Domain w -> Integer

-- | fillright x rounds up x to the nearest 2^n-1.
fillright :: Integer -> Integer

-- | Represents all values
any :: 1 <= w => NatRepr w -> Domain w

-- | Create a bitvector domain representing the integer.
singleton :: (HasCallStack, 1 <= w) => NatRepr w -> Integer -> Domain w

-- | range w l u returns domain containing all bitvectors formed
--   from the w low order bits of some i in
--   [l,u]. Note that per testBit, the least significant
--   bit has index 0.
range :: NatRepr w -> Integer -> Integer -> Domain w

-- | Create an abstract domain from an ascending list of elements. The
--   elements are assumed to be distinct.
fromAscEltList :: 1 <= w => NatRepr w -> [Integer] -> Domain w

-- | Return union of two domains.
union :: 1 <= w => Domain w -> Domain w -> Domain w

-- | concat a y returns domain where each element in a
--   has been concatenated with an element in y. The
--   most-significant bits are a, and the least significant bits
--   are y.
concat :: NatRepr u -> Domain u -> NatRepr v -> Domain v -> Domain (u + v)

-- | select i n a selects n bits starting from index
--   i from a.
select :: (1 <= n, (i + n) <= w) => NatRepr i -> NatRepr n -> Domain w -> Domain n
zext :: (1 <= w, (w + 1) <= u) => Domain w -> NatRepr u -> Domain u
sext :: forall w u. (1 <= w, (w + 1) <= u) => NatRepr w -> Domain w -> NatRepr u -> Domain u
shl :: 1 <= w => NatRepr w -> Domain w -> Domain w -> Domain w
lshr :: 1 <= w => NatRepr w -> Domain w -> Domain w -> Domain w
ashr :: 1 <= w => NatRepr w -> Domain w -> Domain w -> Domain w
add :: 1 <= w => Domain w -> Domain w -> Domain w
negate :: 1 <= w => Domain w -> Domain w
scale :: 1 <= w => Integer -> Domain w -> Domain w
mul :: 1 <= w => Domain w -> Domain w -> Domain w
udiv :: 1 <= w => Domain w -> Domain w -> Domain w
urem :: 1 <= w => Domain w -> Domain w -> Domain w
sdiv :: 1 <= w => NatRepr w -> Domain w -> Domain w -> Domain w
srem :: 1 <= w => NatRepr w -> Domain w -> Domain w -> Domain w

-- | Complement bits in range.
not :: Domain w -> Domain w

-- | Random generator for domain values
genDomain :: NatRepr w -> Gen (Domain w)

-- | Generate a random element from a domain
genElement :: Domain w -> Gen Integer

-- | Generate a random domain and an element contained in that domain.
genPair :: NatRepr w -> Gen (Domain w, Integer)
correct_any :: 1 <= n => NatRepr n -> Integer -> Property
correct_ubounds :: 1 <= n => NatRepr n -> (Domain n, Integer) -> Property
correct_sbounds :: 1 <= n => NatRepr n -> (Domain n, Integer) -> Property
correct_singleton :: 1 <= n => NatRepr n -> Integer -> Integer -> Property
correct_overlap :: Domain n -> Domain n -> Integer -> Property
correct_union :: 1 <= n => NatRepr n -> Domain n -> Domain n -> Integer -> Property
correct_zero_ext :: (1 <= w, (w + 1) <= u) => NatRepr w -> Domain w -> NatRepr u -> Integer -> Property
correct_sign_ext :: (1 <= w, (w + 1) <= u) => NatRepr w -> Domain w -> NatRepr u -> Integer -> Property
correct_concat :: NatRepr m -> (Domain m, Integer) -> NatRepr n -> (Domain n, Integer) -> Property
correct_shrink :: NatRepr i -> NatRepr n -> (Domain (i + n), Integer) -> Property
correct_trunc :: n <= w => NatRepr n -> (Domain w, Integer) -> Property
correct_select :: (1 <= n, (i + n) <= w) => NatRepr i -> NatRepr n -> (Domain w, Integer) -> Property
correct_add :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_neg :: 1 <= n => NatRepr n -> (Domain n, Integer) -> Property
correct_mul :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_scale :: 1 <= n => NatRepr n -> Integer -> (Domain n, Integer) -> Property
correct_scale_eq :: 1 <= n => NatRepr n -> Integer -> Domain n -> Property
correct_udiv :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_urem :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_sdivRange :: (Integer, Integer) -> (Integer, Integer) -> Integer -> Integer -> Property
correct_sdiv :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_srem :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_not :: 1 <= n => NatRepr n -> (Domain n, Integer) -> Property
correct_shl :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_lshr :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_ashr :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_eq :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_ult :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_slt :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_isUltSumCommonEquiv :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_unknowns :: 1 <= n => Domain n -> Integer -> Integer -> Property
correct_bitbounds :: 1 <= n => NatRepr n -> (Domain n, Integer) -> Property
instance GHC.Show.Show (What4.Utils.BVDomain.Arith.Domain w)

-- | Provides a bitwise implementation of bitvector abstract domains.
module What4.Utils.BVDomain.Bitwise

-- | A bitwise interval domain, defined via a bitwise upper and lower
--   bound. The ordering used here to construct the interval is the
--   pointwise ordering on bits. In particular x [= y iff x .|. y ==
--   y, and a value x is in the set defined by the pair
--   (lo,hi) just when lo [= x && x [= hi.
data Domain (w :: Nat)

-- | BVDBitInterval mask lo hi. mask caches the value of
--   2^w - 1
BVBitInterval :: !Integer -> !Integer -> !Integer -> Domain (w :: Nat)
bitle :: Integer -> Integer -> Bool

-- | Test if the domain satisfies its invariants
proper :: NatRepr w -> Domain w -> Bool

-- | Return the bitvector mask value from this domain
bvdMask :: Domain w -> Integer

-- | Test if the given integer value is a member of the abstract domain
member :: Domain w -> Integer -> Bool

-- | Check that a domain is proper, and that the given value is a member
pmember :: NatRepr n -> Domain n -> Integer -> Bool

-- | Compute how many concrete elements are in the abstract domain
size :: Domain w -> Integer

-- | Test if this domain contains a single value, and return it if so
asSingleton :: Domain w -> Maybe Integer

-- | Returns true iff there is at least on element in this bitwise domain.
nonempty :: Domain w -> Bool
eq :: Domain w -> Domain w -> Maybe Bool

-- | Returns true iff the domains have some value in common
domainsOverlap :: Domain w -> Domain w -> Bool

-- | Bitwise lower and upper bounds
bitbounds :: Domain w -> (Integer, Integer)

-- | Bitwise domain containing every bitvector value
any :: NatRepr w -> Domain w

-- | Return a domain containing just the given value
singleton :: NatRepr w -> Integer -> Domain w

-- | Construct a domain from bitwise lower and upper bounds
range :: NatRepr w -> Integer -> Integer -> Domain w

-- | Unsafe constructor for internal use.
interval :: Integer -> Integer -> Integer -> Domain w
union :: Domain w -> Domain w -> Domain w
intersection :: Domain w -> Domain w -> Domain w

-- | concat a y returns domain where each element in a
--   has been concatenated with an element in y. The
--   most-significant bits are a, and the least significant bits
--   are y.
concat :: NatRepr u -> Domain u -> NatRepr v -> Domain v -> Domain (u + v)

-- | select i n a selects n bits starting from index
--   i from a.
select :: (1 <= n, (i + n) <= w) => NatRepr i -> NatRepr n -> Domain w -> Domain n
zext :: (1 <= w, (w + 1) <= u) => Domain w -> NatRepr u -> Domain u
sext :: (1 <= w, (w + 1) <= u) => NatRepr w -> Domain w -> NatRepr u -> Domain u
testBit :: Domain w -> Natural -> Maybe Bool
shl :: NatRepr w -> Domain w -> Integer -> Domain w
lshr :: NatRepr w -> Domain w -> Integer -> Domain w
ashr :: 1 <= w => NatRepr w -> Domain w -> Integer -> Domain w
rol :: NatRepr w -> Domain w -> Integer -> Domain w
ror :: NatRepr w -> Domain w -> Integer -> Domain w
and :: Domain w -> Domain w -> Domain w
or :: Domain w -> Domain w -> Domain w
xor :: Domain w -> Domain w -> Domain w
not :: Domain w -> Domain w

-- | Random generator for domain values. We always generate nonempty domain
--   values.
genDomain :: NatRepr w -> Gen (Domain w)
genElement :: Domain w -> Gen Integer

-- | Generate a random nonempty domain and an element contained in that
--   domain.
genPair :: NatRepr w -> Gen (Domain w, Integer)
correct_any :: 1 <= n => NatRepr n -> Integer -> Property
correct_singleton :: 1 <= n => NatRepr n -> Integer -> Integer -> Property
correct_overlap :: Domain n -> Domain n -> Integer -> Property
correct_union :: 1 <= n => NatRepr n -> Domain n -> Domain n -> Integer -> Property
correct_intersection :: 1 <= n => Domain n -> Domain n -> Integer -> Property
correct_zero_ext :: (1 <= w, (w + 1) <= u) => NatRepr w -> Domain w -> NatRepr u -> Integer -> Property
correct_sign_ext :: (1 <= w, (w + 1) <= u) => NatRepr w -> Domain w -> NatRepr u -> Integer -> Property
correct_concat :: NatRepr m -> (Domain m, Integer) -> NatRepr n -> (Domain n, Integer) -> Property
correct_shrink :: NatRepr i -> NatRepr n -> (Domain (i + n), Integer) -> Property
correct_trunc :: n <= w => NatRepr n -> (Domain w, Integer) -> Property
correct_select :: (1 <= n, (i + n) <= w) => NatRepr i -> NatRepr n -> (Domain w, Integer) -> Property
correct_shl :: 1 <= n => NatRepr n -> (Domain n, Integer) -> Integer -> Property
correct_lshr :: 1 <= n => NatRepr n -> (Domain n, Integer) -> Integer -> Property
correct_ashr :: 1 <= n => NatRepr n -> (Domain n, Integer) -> Integer -> Property
correct_rol :: 1 <= n => NatRepr n -> (Domain n, Integer) -> Integer -> Property
correct_ror :: 1 <= n => NatRepr n -> (Domain n, Integer) -> Integer -> Property
correct_eq :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_and :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_or :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_not :: 1 <= n => NatRepr n -> (Domain n, Integer) -> Property
correct_xor :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_testBit :: 1 <= n => NatRepr n -> (Domain n, Integer) -> Natural -> Property
instance GHC.Show.Show (What4.Utils.BVDomain.Bitwise.Domain w)

-- | Provides an implementation of bitvector abstract domains optimized for
--   performing XOR operations.
module What4.Utils.BVDomain.XOR

-- | A value of type BVDomain w represents a set of
--   bitvectors of width w. This is an alternate representation of
--   the bitwise domain values, optimized to compute XOR operations.
data Domain (w :: Nat)

-- | BVDXor mask hi unknown represents a set of values where
--   hi is a bitwise high bound, and unknown represents
--   the bits whose values are not known. The value mask caches
--   the value 2^w-1.
BVDXor :: !Integer -> !Integer -> !Integer -> Domain (w :: Nat)

-- | Test if the domain satisfies its invariants
proper :: NatRepr w -> Domain w -> Bool

-- | Return the bitvector mask value from this domain
bvdMask :: Domain w -> Integer

-- | Test if the given integer value is a member of the abstract domain
member :: Domain w -> Integer -> Bool

-- | Check that a domain is proper, and that the given value is a member
pmember :: NatRepr n -> Domain n -> Integer -> Bool

-- | Construct a domain from bitwise lower and upper bounds
range :: NatRepr w -> Integer -> Integer -> Domain w

-- | Unsafe constructor for internal use.
interval :: Integer -> Integer -> Integer -> Domain w

-- | Bitwise lower and upper bounds
bitbounds :: Domain w -> (Integer, Integer)

-- | Test if this domain contains a single value, and return it if so
asSingleton :: Domain w -> Maybe Integer

-- | Return a domain containing just the given value
singleton :: NatRepr w -> Integer -> Domain w
xor :: Domain w -> Domain w -> Domain w
and :: Domain w -> Domain w -> Domain w
and_scalar :: Integer -> Domain w -> Domain w

-- | Random generator for domain values. We always generate nonempty domain
--   values.
genDomain :: NatRepr w -> Gen (Domain w)
genElement :: Domain w -> Gen Integer

-- | Generate a random nonempty domain and an element contained in that
--   domain.
genPair :: NatRepr w -> Gen (Domain w, Integer)
correct_singleton :: 1 <= n => NatRepr n -> Integer -> Integer -> Property
correct_xor :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_and :: 1 <= n => NatRepr n -> (Domain n, Integer) -> (Domain n, Integer) -> Property
correct_and_scalar :: 1 <= n => NatRepr n -> Integer -> (Domain n, Integer) -> Property
correct_bitbounds :: Domain n -> Integer -> Property
instance GHC.Show.Show (What4.Utils.BVDomain.XOR.Domain w)

-- | Provides an implementation of abstract domains for bitvectors. This
--   abstract domain has essentially two modes: arithmetic and bitvector
--   modes. The arithmetic mode is a fairly straightforward interval
--   domain, albeit one that is carefully implemented to deal properly with
--   intervals that "cross zero", as is relatively common when using 2's
--   complement signed representations. The bitwise mode tracks the values
--   of individual bits independently in a 3-valued logic (true, false or
--   unknown). The abstract domain transitions between the two modes when
--   necessary, but attempts to retain as much precision as possible.
--   
--   The operations of these domains are formalized in the companion
--   Cryptol files found together in this package under the "doc"
--   directory, and their soundness properties stated and established.
module What4.Utils.BVDomain

-- | A value of type BVDomain w represents a set of
--   bitvectors of width w. A BVDomain represents either an
--   arithmetic interval, or a bitwise interval.
data BVDomain (w :: Nat)
BVDArith :: !Domain w -> BVDomain (w :: Nat)
BVDBitwise :: !Domain w -> BVDomain (w :: Nat)

-- | Test if the domain satisfies its invariants
proper :: NatRepr w -> BVDomain w -> Bool

-- | Test if the given integer value is a member of the abstract domain
member :: BVDomain w -> Integer -> Bool

-- | Compute how many concrete elements are in the abstract domain
size :: BVDomain w -> Integer
asArithDomain :: BVDomain w -> Domain w
asBitwiseDomain :: BVDomain w -> Domain w
asXorDomain :: BVDomain w -> Domain w
fromXorDomain :: Domain w -> BVDomain w
arithToXorDomain :: Domain w -> Domain w
bitwiseToXorDomain :: Domain w -> Domain w
xorToBitwiseDomain :: Domain w -> Domain w

-- | Return value if this is a singleton.
asSingleton :: BVDomain w -> Maybe Integer
eq :: BVDomain w -> BVDomain w -> Maybe Bool

-- | Check if all elements in one domain are less than all elements in
--   other.
slt :: 1 <= w => NatRepr w -> BVDomain w -> BVDomain w -> Maybe Bool

-- | Check if all elements in one domain are less than all elements in
--   other.
ult :: 1 <= w => BVDomain w -> BVDomain w -> Maybe Bool

-- | Return Just if every bitvector in the domain has the same bit
--   at the given index.
testBit :: NatRepr w -> BVDomain w -> Natural -> Maybe Bool

-- | Return true if domains contain a common element.
domainsOverlap :: BVDomain w -> BVDomain w -> Bool
ubounds :: BVDomain w -> (Integer, Integer)
sbounds :: 1 <= w => NatRepr w -> BVDomain w -> (Integer, Integer)

-- | Check if (bvult (bvadd a c) (bvadd b c)) is equivalent to (bvult a b)
isUltSumCommonEquiv :: BVDomain w -> BVDomain w -> BVDomain w -> Bool

-- | Return the (lo,sz), the low bound and size of the given
--   arithmetic interval. A value x is in the set defined by this
--   domain iff (x - lo) mod w <= sz holds. Returns
--   Nothing if the domain contains all values.
arithDomainData :: Domain w -> Maybe (Integer, Integer)

-- | Bitwise lower and upper bounds
bitbounds :: Domain w -> (Integer, Integer)

-- | Represents all values
any :: 1 <= w => NatRepr w -> BVDomain w

-- | Create a bitvector domain representing the integer.
singleton :: (HasCallStack, 1 <= w) => NatRepr w -> Integer -> BVDomain w

-- | range w l u returns domain containing all bitvectors formed
--   from the w low order bits of some i in
--   [l,u]. Note that per testBit, the least significant
--   bit has index 0.
range :: NatRepr w -> Integer -> Integer -> BVDomain w

-- | Create an abstract domain from an ascending list of elements. The
--   elements are assumed to be distinct.
fromAscEltList :: 1 <= w => NatRepr w -> [Integer] -> BVDomain w

-- | Return union of two domains.
union :: 1 <= w => BVDomain w -> BVDomain w -> BVDomain w

-- | concat a y returns domain where each element in a
--   has been concatenated with an element in y. The
--   most-significant bits are a, and the least significant bits
--   are y.
concat :: NatRepr u -> BVDomain u -> NatRepr v -> BVDomain v -> BVDomain (u + v)

-- | select i n a selects n bits starting from index
--   i from a.
select :: (1 <= n, (i + n) <= w) => NatRepr i -> NatRepr n -> BVDomain w -> BVDomain n
zext :: (1 <= w, (w + 1) <= u) => BVDomain w -> NatRepr u -> BVDomain u
sext :: forall w u. (1 <= w, (w + 1) <= u) => NatRepr w -> BVDomain w -> NatRepr u -> BVDomain u
shl :: 1 <= w => NatRepr w -> BVDomain w -> BVDomain w -> BVDomain w
lshr :: 1 <= w => NatRepr w -> BVDomain w -> BVDomain w -> BVDomain w
ashr :: 1 <= w => NatRepr w -> BVDomain w -> BVDomain w -> BVDomain w
rol :: 1 <= w => NatRepr w -> BVDomain w -> BVDomain w -> BVDomain w
ror :: 1 <= w => NatRepr w -> BVDomain w -> BVDomain w -> BVDomain w
add :: 1 <= w => BVDomain w -> BVDomain w -> BVDomain w
negate :: 1 <= w => BVDomain w -> BVDomain w
scale :: 1 <= w => Integer -> BVDomain w -> BVDomain w
mul :: 1 <= w => BVDomain w -> BVDomain w -> BVDomain w
udiv :: 1 <= w => BVDomain w -> BVDomain w -> BVDomain w
urem :: 1 <= w => BVDomain w -> BVDomain w -> BVDomain w
sdiv :: 1 <= w => NatRepr w -> BVDomain w -> BVDomain w -> BVDomain w
srem :: 1 <= w => NatRepr w -> BVDomain w -> BVDomain w -> BVDomain w

-- | Complement bits in range.
not :: BVDomain w -> BVDomain w
and :: BVDomain w -> BVDomain w -> BVDomain w
or :: BVDomain w -> BVDomain w -> BVDomain w
xor :: BVDomain w -> BVDomain w -> BVDomain w
popcnt :: NatRepr w -> BVDomain w -> BVDomain w
clz :: NatRepr w -> BVDomain w -> BVDomain w
ctz :: NatRepr w -> BVDomain w -> BVDomain w

-- | Precondition: x <= lomask. Find the (arithmetically)
--   smallest z above x which is bitwise above
--   lomask. In other words find the smallest z such that
--   x <= z and lomask .|. z == z.
bitwiseRoundAbove :: Integer -> Integer -> Integer -> Integer

-- | Precondition: lomask <= x <= himask and lomask .|.
--   himask == himask. Find the (arithmetically) smallest z
--   above x which is bitwise between lomask and
--   himask. In other words, find the smallest z such
--   that x <= z and lomask .|. z = z and z .|.
--   himask == himask.
bitwiseRoundBetween :: Integer -> Integer -> Integer -> Integer -> Integer

-- | Generate a random nonempty domain
genDomain :: NatRepr w -> Gen (BVDomain w)

-- | Generate a random element from a domain, which is assumed to be
--   nonempty
genElement :: BVDomain w -> Gen Integer

-- | Generate a random nonempty domain and an element contained in that
--   domain.
genPair :: NatRepr w -> Gen (BVDomain w, Integer)
correct_arithToBitwise :: NatRepr n -> (Domain n, Integer) -> Property
correct_bitwiseToArith :: NatRepr n -> (Domain n, Integer) -> Property
correct_bitwiseToXorDomain :: NatRepr n -> (Domain n, Integer) -> Property
correct_arithToXorDomain :: NatRepr n -> (Domain n, Integer) -> Property
correct_xorToBitwiseDomain :: NatRepr n -> (Domain n, Integer) -> Property
correct_asXorDomain :: NatRepr n -> (BVDomain n, Integer) -> Property
correct_fromXorDomain :: NatRepr n -> (Domain n, Integer) -> Property
correct_bra1 :: NatRepr n -> Integer -> Integer -> Property
correct_bra2 :: NatRepr n -> Integer -> Integer -> Integer -> Property
correct_brb1 :: NatRepr n -> Integer -> Integer -> Integer -> Property
correct_brb2 :: NatRepr n -> Integer -> Integer -> Integer -> Integer -> Property
correct_any :: 1 <= n => NatRepr n -> Integer -> Property
correct_ubounds :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> Property
correct_sbounds :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> Property
correct_singleton :: 1 <= n => NatRepr n -> Integer -> Integer -> Property
correct_overlap :: BVDomain n -> BVDomain n -> Integer -> Property
precise_overlap :: BVDomain n -> BVDomain n -> Property
correct_union :: 1 <= n => NatRepr n -> BVDomain n -> BVDomain n -> Integer -> Property
correct_zero_ext :: (1 <= w, (w + 1) <= u) => NatRepr w -> BVDomain w -> NatRepr u -> Integer -> Property
correct_sign_ext :: (1 <= w, (w + 1) <= u) => NatRepr w -> BVDomain w -> NatRepr u -> Integer -> Property
correct_concat :: NatRepr m -> (BVDomain m, Integer) -> NatRepr n -> (BVDomain n, Integer) -> Property
correct_select :: (1 <= n, (i + n) <= w) => NatRepr i -> NatRepr n -> (BVDomain w, Integer) -> Property
correct_add :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_neg :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> Property
correct_mul :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_scale :: 1 <= n => NatRepr n -> Integer -> (BVDomain n, Integer) -> Property
correct_udiv :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_urem :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_sdiv :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_srem :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_shl :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_lshr :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_ashr :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_rol :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_ror :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_eq :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_ult :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_slt :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_and :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_or :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_not :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> Property
correct_xor :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> (BVDomain n, Integer) -> Property
correct_testBit :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> Natural -> Property
correct_popcnt :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> Property
correct_clz :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> Property
correct_ctz :: 1 <= n => NatRepr n -> (BVDomain n, Integer) -> Property
instance GHC.Show.Show (What4.Utils.BVDomain.BVDomain w)

-- | This module provides complex numbers without the RealFloat constraints
--   that Data.Complex has. This is useful for representing various
--   intermediate symbolic representations of complex numbers that are not
--   literally number representations.
module What4.Utils.Complex

-- | A complex pair over an arbitrary type.
data Complex a
(:+) :: !a -> !a -> Complex a
infix 6 :+
realPart :: Complex a -> a
imagPart :: Complex a -> a
magnitude :: Floating a => Complex a -> a

-- | Returns square of magnitude.
magnitudeSq :: Num a => Complex a -> a
complexNegate :: Num a => Complex a -> Complex a
complexAdd :: Num a => Complex a -> Complex a -> Complex a
complexSub :: Num a => Complex a -> Complex a -> Complex a
complexMul :: Num a => Complex a -> Complex a -> Complex a
complexDiv :: Fractional a => Complex a -> Complex a -> Complex a
complexRecip :: Fractional a => Complex a -> Complex a
tryComplexSqrt :: (Ord a, Fractional a, Monad m) => (a -> m a) -> Complex a -> m (Complex a)
tryMagnitude :: Num a => (a -> b) -> Complex a -> b
complexAsRational :: Complex Rational -> Maybe Rational
instance GHC.Generics.Generic (What4.Utils.Complex.Complex a)
instance GHC.Base.Functor What4.Utils.Complex.Complex
instance Data.Foldable.Foldable What4.Utils.Complex.Complex
instance GHC.Classes.Ord a => GHC.Classes.Ord (What4.Utils.Complex.Complex a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (What4.Utils.Complex.Complex a)
instance Data.Traversable.Traversable What4.Utils.Complex.Complex
instance Data.Hashable.Class.Hashable a => Data.Hashable.Class.Hashable (What4.Utils.Complex.Complex a)
instance Data.Parameterized.Classes.PolyEq x y => Data.Parameterized.Classes.PolyEq (What4.Utils.Complex.Complex x) (What4.Utils.Complex.Complex y)
instance (GHC.Classes.Eq a, GHC.Num.Num a, GHC.Show.Show a) => GHC.Show.Show (What4.Utils.Complex.Complex a)
instance GHC.Float.Floating a => GHC.Num.Num (What4.Utils.Complex.Complex a)
instance (GHC.Classes.Ord a, GHC.Float.Floating a) => GHC.Real.Real (What4.Utils.Complex.Complex a)
instance GHC.Float.Floating a => GHC.Real.Fractional (What4.Utils.Complex.Complex a)
instance GHC.Float.RealFloat a => GHC.Float.Floating (What4.Utils.Complex.Complex a)
instance (GHC.Classes.Ord a, GHC.Float.Floating a) => GHC.Real.RealFrac (What4.Utils.Complex.Complex a)

module What4.Utils.Endian
data Endian
LittleEndian :: Endian
BigEndian :: Endian
instance GHC.Classes.Ord What4.Utils.Endian.Endian
instance GHC.Show.Show What4.Utils.Endian.Endian
instance GHC.Classes.Eq What4.Utils.Endian.Endian

-- | Provides functions for finding an executable, and expanding a path
--   with referenced to environment variables.
module What4.Utils.Environment

-- | Find an executable from a string.
findExecutable :: (MonadIO m, MonadFail m) => FilePath -> m FilePath
expandEnvironmentPath :: Map String String -> String -> IO String

module What4.Utils.FloatHelpers

-- | Rounding modes for IEEE-754 floating point operations.
data RoundingMode

-- | Round to nearest even.
RNE :: RoundingMode

-- | Round to nearest away.
RNA :: RoundingMode

-- | Round toward plus Infinity.
RTP :: RoundingMode

-- | Round toward minus Infinity.
RTN :: RoundingMode

-- | Round toward zero.
RTZ :: RoundingMode
bfStatus :: HasCallStack => (a, Status) -> a
fppOpts :: FloatPrecisionRepr fpp -> RoundingMode -> BFOpts
toRoundMode :: RoundingMode -> RoundMode

-- | Make LibBF options for the given precision and rounding mode.
fpOpts :: Integer -> Integer -> RoundMode -> BFOpts

-- | Make a floating point number from an integer, using the given rounding
--   mode
floatFromInteger :: BFOpts -> Integer -> BigFloat

-- | Make a floating point number from a rational, using the given rounding
--   mode
floatFromRational :: BFOpts -> Rational -> BigFloat

-- | Convert a floating point number to a rational, if possible.
floatToRational :: BigFloat -> Maybe Rational

-- | Convert a floating point number to an integer, if possible.
floatToInteger :: RoundingMode -> BigFloat -> Maybe Integer
floatRoundToInt :: HasCallStack => FloatPrecisionRepr fpp -> RoundingMode -> BigFloat -> BigFloat
instance GHC.Enum.Enum What4.Utils.FloatHelpers.RoundingMode
instance GHC.Show.Show What4.Utils.FloatHelpers.RoundingMode
instance GHC.Classes.Ord What4.Utils.FloatHelpers.RoundingMode
instance GHC.Generics.Generic What4.Utils.FloatHelpers.RoundingMode
instance GHC.Classes.Eq What4.Utils.FloatHelpers.RoundingMode
instance Data.Hashable.Class.Hashable What4.Utils.FloatHelpers.RoundingMode

module What4.Utils.HandleReader
teeInputStream :: InputStream a -> OutputStream a -> IO (InputStream a)
teeOutputStream :: OutputStream a -> OutputStream a -> IO (OutputStream a)
lineBufferedOutputStream :: Text -> OutputStream Text -> IO (OutputStream Text)
demuxProcessHandles :: Handle -> Handle -> Handle -> Maybe (Text, Handle) -> IO (OutputStream Text, InputStream Text, HandleReader)

-- | Wrapper to help with reading from another process's standard out and
--   stderr.
--   
--   We want to be able to read from another process's stderr and stdout
--   without causing the process to stall because stdout or
--   stderr becomes full. This data type will read from either of
--   the handles, and buffer as much data as needed in the queue. It then
--   provides a line-based method for reading that data as strict
--   bytestrings.
data HandleReader
HandleReader :: !Chan (Maybe Text) -> !Handle -> !ThreadId -> HandleReader
[hrChan] :: HandleReader -> !Chan (Maybe Text)
[hrHandle] :: HandleReader -> !Handle
[hrThreadId] :: HandleReader -> !ThreadId
streamLines :: Chan (Maybe Text) -> Handle -> Maybe (OutputStream Text) -> IO ()

-- | Create a new handle reader for reading the given handle.
startHandleReader :: Handle -> Maybe (OutputStream Text) -> IO HandleReader

-- | Stop the handle reader; cannot be used afterwards.
stopHandleReader :: HandleReader -> IO ()

-- | Run an execution with a handle reader and stop it wheen down
withHandleReader :: Handle -> Maybe (OutputStream Text) -> (HandleReader -> IO a) -> IO a
readNextLine :: HandleReader -> IO (Maybe Text)
readAllLines :: HandleReader -> IO Text

-- | A basic datatype for incremental hashing which supports a monoid
--   instance. Currently this is simply implemented as bitwise xor for
--   simplicity.
--   
--   If we later wish to experiment with other incremenal hash algorithms,
--   this module abstracts over the implementation details.
module What4.Utils.IncrHash
data IncrHash
mkIncrHash :: Int -> IncrHash
toIncrHash :: Hashable a => a -> IncrHash
toIncrHashWithSalt :: Hashable a => Int -> a -> IncrHash
instance GHC.Classes.Ord What4.Utils.IncrHash.IncrHash
instance GHC.Classes.Eq What4.Utils.IncrHash.IncrHash
instance GHC.Base.Semigroup What4.Utils.IncrHash.IncrHash
instance GHC.Base.Monoid What4.Utils.IncrHash.IncrHash
instance Data.Hashable.Class.Hashable What4.Utils.IncrHash.IncrHash

-- | Declares a datatype for representing n-way conjunctions or
--   disjunctions in a way that efficiently captures important algebraic
--   laws like commutativity, associativity and resolution.
module What4.Expr.BoolMap

-- | This data structure keeps track of a collection of expressions
--   together with their polarities. Such a collection might represent
--   either a conjunction or a disjunction of expressions. The
--   implementation uses a map from expression values to their polarities,
--   and thus automatically implements the associative, commutative and
--   idempotency laws common to both conjunctions and disjunctions.
--   Moreover, if the same expression occurs in the collection with
--   opposite polarities, the entire collection collapses via a resolution
--   step to an "inconsistent" map. For conjunctions this corresponds to a
--   contradiction and represents false; for disjunction, this corresponds
--   to the law of the excluded middle and represents true.
data BoolMap (f :: BaseType -> Type)

-- | Produce a singleton bool map, consisting of just the given term
var :: (HashableF f, OrdF f) => f BaseBoolType -> Polarity -> BoolMap f

-- | Add a variable to a bool map, performing a resolution step if possible
addVar :: (HashableF f, OrdF f) => f BaseBoolType -> Polarity -> BoolMap f -> BoolMap f

-- | Generate a bool map from a list of terms and polarities by repeatedly
--   calling addVar.
fromVars :: (HashableF f, OrdF f) => [(f BaseBoolType, Polarity)] -> BoolMap f

-- | Merge two bool maps, performing resolution as necessary.
combine :: OrdF f => BoolMap f -> BoolMap f -> BoolMap f

-- | Describes the occurrence of a variable or expression, whether it is
--   negated or not.
data Polarity
Positive :: Polarity
Negative :: Polarity

-- | Swap a polarity value
negatePolarity :: Polarity -> Polarity

-- | Test if the bool map contains the given term, and return the polarity
--   of that term if so.
contains :: OrdF f => BoolMap f -> f BaseBoolType -> Maybe Polarity

-- | Returns true for an inconsistent bool map
isInconsistent :: BoolMap f -> Bool

-- | Returns true for a "null" bool map with no terms
isNull :: BoolMap f -> Bool

-- | Represents the state of a bool map
data BoolMapView f

-- | A bool map with no expressions, represents the unit of the
--   corresponding operation
BoolMapUnit :: BoolMapView f

-- | An inconsistent bool map, represents the dual of the operation unit
BoolMapDualUnit :: BoolMapView f

-- | The terms appearing in the bool map, of which there is at least one
BoolMapTerms :: NonEmpty (f BaseBoolType, Polarity) -> BoolMapView f

-- | Deconstruct the given bool map for later processing
viewBoolMap :: BoolMap f -> BoolMapView f

-- | Traverse the expressions in a bool map, and rebuild the map.
traverseVars :: (Applicative m, HashableF g, OrdF g) => (f BaseBoolType -> m (g BaseBoolType)) -> BoolMap f -> m (BoolMap g)

-- | Swap the polarities of the terms in the given bool map.
reversePolarities :: OrdF f => BoolMap f -> BoolMap f

-- | Remove the given term from the bool map. The map is unchanged if
--   inconsistent or if the term does not occur.
removeVar :: OrdF f => BoolMap f -> f BaseBoolType -> BoolMap f
newtype Wrap (f :: k -> Type) (x :: k)
Wrap :: f x -> Wrap (f :: k -> Type) (x :: k)
[unWrap] :: Wrap (f :: k -> Type) (x :: k) -> f x
instance GHC.Show.Show What4.Expr.BoolMap.Polarity
instance GHC.Classes.Ord What4.Expr.BoolMap.Polarity
instance GHC.Classes.Eq What4.Expr.BoolMap.Polarity
instance Data.Parameterized.Classes.OrdF f => GHC.Classes.Eq (What4.Expr.BoolMap.BoolMap f)
instance (Data.Parameterized.Classes.OrdF f, Data.Parameterized.Classes.HashableF f) => Data.Hashable.Class.Hashable (What4.Expr.BoolMap.BoolMap f)
instance forall k (f :: k -> GHC.Types.Type) (x :: k). Data.Type.Equality.TestEquality f => GHC.Classes.Eq (What4.Expr.BoolMap.Wrap f x)
instance forall k (f :: k -> GHC.Types.Type) (x :: k). Data.Parameterized.Classes.OrdF f => GHC.Classes.Ord (What4.Expr.BoolMap.Wrap f x)
instance forall k (f :: k -> GHC.Types.Type) (x :: k). (Data.Parameterized.Classes.HashableF f, Data.Type.Equality.TestEquality f) => Data.Hashable.Class.Hashable (What4.Expr.BoolMap.Wrap f x)
instance Data.Hashable.Class.Hashable What4.Expr.BoolMap.Polarity

-- | This module defines a strict map.
--   
--   It is similiar to Data.Map.Strict, but provides some additional
--   operations including splitEntry, splitLeq, fromDistinctDescList.
module What4.Utils.LeqMap
data LeqMap k p
toList :: LeqMap k p -> [(k, p)]
findMin :: LeqMap k p -> (k, p)
findMax :: LeqMap k p -> (k, p)
null :: LeqMap k p -> Bool

-- | Return the empty map
empty :: LeqMap k p
mapKeysMonotonic :: (k1 -> k2) -> LeqMap k1 p -> LeqMap k2 p
union :: Ord k => LeqMap k p -> LeqMap k p -> LeqMap k p
fromDistinctAscList :: [(k, p)] -> LeqMap k p

-- | Create a map from a list of keys in descending order.
fromDistinctDescList :: [(k, p)] -> LeqMap k p
toDescList :: LeqMap k p -> [(k, p)]
deleteFindMin :: LeqMap k p -> ((k, p), LeqMap k p)
deleteFindMax :: LeqMap k p -> ((k, p), LeqMap k p)
minViewWithKey :: LeqMap k p -> Maybe ((k, p), LeqMap k p)
filterGt :: Ord k => k -> LeqMap k p -> LeqMap k p
filterLt :: Ord k => k -> LeqMap k p -> LeqMap k p
insert :: Ord k => k -> p -> LeqMap k p -> LeqMap k p

-- | Find largest element that is less than or equal to key (if any).
lookupLE :: Ord k => k -> LeqMap k p -> Maybe (k, p)

-- | Find less than element that is less than key (if any).
lookupLT :: Ord k => k -> LeqMap k p -> Maybe (k, p)

-- | Find largest element that is at least key (if any).
lookupGE :: Ord k => k -> LeqMap k p -> Maybe (k, p)

-- | Find less than element that is less than key (if any).
lookupGT :: Ord k => k -> LeqMap k p -> Maybe (k, p)
keys :: LeqMap k p -> [k]
mergeWithKey :: forall a b c. (a -> b -> IO c) -> (a -> IO c) -> (b -> IO c) -> LeqMap Integer a -> LeqMap Integer b -> IO (LeqMap Integer c)
singleton :: k -> p -> LeqMap k p
foldlWithKey' :: (a -> k -> b -> a) -> a -> LeqMap k b -> a
size :: LeqMap k p -> Int
splitEntry :: LeqMap k p -> Maybe (LeqMap k p, (k, p), LeqMap k p)
splitLeq :: Ord k => k -> LeqMap k p -> (LeqMap k p, LeqMap k p)
instance (GHC.Classes.Ord k, GHC.Classes.Eq p) => GHC.Classes.Eq (What4.Utils.LeqMap.LeqMap k p)
instance GHC.Base.Functor (What4.Utils.LeqMap.LeqMap k)
instance Data.Foldable.Foldable (What4.Utils.LeqMap.LeqMap k)
instance Data.Traversable.Traversable (What4.Utils.LeqMap.LeqMap k)

-- | This module defines the MonadST class, which contains the ST and IO
--   monads and a small collection of moand transformers over them.
module What4.Utils.MonadST
class Monad m => MonadST s m | m -> s
liftST :: MonadST s m => ST s a -> m a

-- | The strict ST monad. The ST monad allows for destructive
--   updates, but is escapable (unlike IO). A computation of type
--   ST s a returns a value of type a, and execute
--   in "thread" s. The s parameter is either
--   
--   
--   
- an uninstantiated type variable (inside invocations of
--   runST), or
--   
- RealWorld (inside invocations of stToIO).
--   
--   
--   It serves to keep the internal states of different invocations of
--   runST separate from each other and from invocations of
--   stToIO.
--   
--   The >>= and >> operations are strict in the
--   state (though not in values stored in the state). For example,
--   
--   
--   runST (writeSTRef _|_ v >>= f) = _|_
--   
data () => ST s a

-- | RealWorld is deeply magical. It is primitive, but it
--   is not unlifted (hence ptrArg). We never manipulate
--   values of type RealWorld; it's only used in the type system,
--   to parameterise State#.
data RealWorld
instance What4.Utils.MonadST.MonadST GHC.Prim.RealWorld GHC.Types.IO
instance What4.Utils.MonadST.MonadST s (GHC.ST.ST s)
instance What4.Utils.MonadST.MonadST s m => What4.Utils.MonadST.MonadST s (Control.Monad.Trans.Cont.ContT r m)
instance What4.Utils.MonadST.MonadST s m => What4.Utils.MonadST.MonadST s (Control.Monad.Trans.Reader.ReaderT r m)
instance What4.Utils.MonadST.MonadST s m => What4.Utils.MonadST.MonadST s (Control.Monad.Trans.State.Lazy.StateT u m)
instance What4.Utils.MonadST.MonadST s m => What4.Utils.MonadST.MonadST s (Control.Monad.Trans.State.Strict.StateT u m)
instance (What4.Utils.MonadST.MonadST s m, GHC.Base.Monoid w) => What4.Utils.MonadST.MonadST s (Control.Monad.Trans.Writer.Lazy.WriterT w m)
instance (What4.Utils.MonadST.MonadST s m, GHC.Base.Monoid w) => What4.Utils.MonadST.MonadST s (Control.Monad.Trans.Writer.Strict.WriterT w m)

-- | Defines a GADT for indicating a base type must be an integer. Used for
--   restricting index types in MATLAB arrays.
module What4.Utils.OnlyIntRepr

-- | This provides a GADT instance used to indicate a BaseType must
--   have value BaseIntegerType.
data OnlyIntRepr tp
OnlyIntRepr :: OnlyIntRepr tp
toBaseTypeRepr :: OnlyIntRepr tp -> BaseTypeRepr tp
instance Data.Type.Equality.TestEquality What4.Utils.OnlyIntRepr.OnlyIntRepr
instance GHC.Classes.Eq (What4.Utils.OnlyIntRepr.OnlyIntRepr tp)
instance Data.Hashable.Class.Hashable (What4.Utils.OnlyIntRepr.OnlyIntRepr tp)
instance Data.Parameterized.Classes.HashableF What4.Utils.OnlyIntRepr.OnlyIntRepr

module What4.Utils.Streams

-- | Write from input stream to a logging function.
logErrorStream :: InputStream ByteString -> (String -> IO ()) -> IO ()

module What4.Utils.Versions
ver :: Text -> Q Exp
data SolverBounds
SolverBounds :: Maybe Version -> Maybe Version -> Maybe Version -> SolverBounds
[lower] :: SolverBounds -> Maybe Version
[upper] :: SolverBounds -> Maybe Version
[recommended] :: SolverBounds -> Maybe Version
emptySolverBounds :: SolverBounds

-- | This method parses configuration files describing the upper and lower
--   bounds of solver versions we expect to work correctly with What4. See
--   the file "solverBounds.config" for examples of how such bounds are
--   specified.
parseSolverBounds :: FilePath -> IO [(Text, SolverBounds)]
computeDefaultSolverBounds :: Q Exp
instance Language.Haskell.TH.Syntax.Lift What4.Utils.Versions.SolverBounds

module What4.Utils.Word16String

-- | A string of Word16 values, encoded as a bytestring in little endian
--   (LE) order.
--   
--   We maintain the invariant that Word16Strings are represented by an
--   even number of bytes.
data Word16String

-- | Generate a Word16String from a bytestring where the 16bit
--   words are encoded as two bytes in little-endian order.
--   
--   PRECONDITION: the input bytestring must have a length which is a
--   multiple of 2.
fromLEByteString :: ByteString -> Word16String

-- | Return the underlying little endian bytestring.
toLEByteString :: Word16String -> ByteString

-- | Return the empty string
empty :: Word16String

-- | Compute the string containing just the given character
singleton :: Word16 -> Word16String

-- | Test if the given string is empty
null :: Word16String -> Bool

-- | Retrive the nth character of the string. Out of bounds
--   accesses will cause an error.
index :: Word16String -> Int -> Word16
drop :: Int -> Word16String -> Word16String
take :: Int -> Word16String -> Word16String
append :: Word16String -> Word16String -> Word16String
length :: Word16String -> Int
foldl' :: (a -> Word16 -> a) -> a -> Word16String -> a

-- | Find the first index (if it exists) where the first string appears as
--   a substring in the second
findSubstring :: Word16String -> Word16String -> Maybe Int

-- | Returns true if the first string appears somewhere in the second
--   string.
isInfixOf :: Word16String -> Word16String -> Bool
isPrefixOf :: Word16String -> Word16String -> Bool
isSuffixOf :: Word16String -> Word16String -> Bool
instance GHC.Base.Semigroup What4.Utils.Word16String.Word16String
instance GHC.Base.Monoid What4.Utils.Word16String.Word16String
instance GHC.Classes.Eq What4.Utils.Word16String.Word16String
instance GHC.Classes.Ord What4.Utils.Word16String.Word16String
instance GHC.Show.Show What4.Utils.Word16String.Word16String
instance Data.Hashable.Class.Hashable What4.Utils.Word16String.Word16String

module What4.Utils.StringLiteral
data StringLiteral (si :: StringInfo) :: Type
[UnicodeLiteral] :: !Text -> StringLiteral Unicode
[Char8Literal] :: !ByteString -> StringLiteral Char8
[Char16Literal] :: !Word16String -> StringLiteral Char16
stringLiteralInfo :: StringLiteral si -> StringInfoRepr si
fromUnicodeLit :: StringLiteral Unicode -> Text
fromChar8Lit :: StringLiteral Char8 -> ByteString
fromChar16Lit :: StringLiteral Char16 -> Word16String
stringLitEmpty :: StringInfoRepr si -> StringLiteral si
stringLitLength :: StringLiteral si -> Integer
stringLitNull :: StringLiteral si -> Bool
stringLitBounds :: StringLiteral si -> Maybe (Int, Int)
stringLitContains :: StringLiteral si -> StringLiteral si -> Bool
stringLitIsPrefixOf :: StringLiteral si -> StringLiteral si -> Bool
stringLitIsSuffixOf :: StringLiteral si -> StringLiteral si -> Bool
stringLitSubstring :: StringLiteral si -> Integer -> Integer -> StringLiteral si

-- | Index of first occurrence of second string in first one starting at
--   the position specified by the third argument. stringLitIndexOf s t
--   k, with 0 <= k <= |s| is the position of the first
--   occurrence of t in s at or after position
--   k, if any. Otherwise, it is -1. Note that the result
--   is k whenever k is within the range [0,
--   |s|] and t is empty.
stringLitIndexOf :: StringLiteral si -> StringLiteral si -> Integer -> Integer
instance Data.Type.Equality.TestEquality What4.Utils.StringLiteral.StringLiteral
instance GHC.Classes.Eq (What4.Utils.StringLiteral.StringLiteral si)
instance Data.Parameterized.Classes.OrdF What4.Utils.StringLiteral.StringLiteral
instance GHC.Classes.Ord (What4.Utils.StringLiteral.StringLiteral si)
instance Data.Parameterized.Classes.ShowF What4.Utils.StringLiteral.StringLiteral
instance GHC.Show.Show (What4.Utils.StringLiteral.StringLiteral si)
instance Data.Parameterized.Classes.HashableF What4.Utils.StringLiteral.StringLiteral
instance Data.Hashable.Class.Hashable (What4.Utils.StringLiteral.StringLiteral si)
instance GHC.Base.Semigroup (What4.Utils.StringLiteral.StringLiteral si)
instance Data.String.IsString (What4.Utils.StringLiteral.StringLiteral What4.BaseTypes.Unicode)

-- | This module declares a set of abstract domains used by the solver.
--   These are mostly interval domains on numeric types.
--   
--   Since these abstract domains are baked directly into the term
--   representation, we want to get as much bang-for-buck as possible.
--   Thus, we prioritize compact representations and simple algorithms over
--   precision.
module What4.Utils.AbstractDomains

-- | A lower or upper bound on a value.
data ValueBound tp
Unbounded :: ValueBound tp
Inclusive :: !tp -> ValueBound tp
minValueBound :: Ord tp => ValueBound tp -> ValueBound tp -> ValueBound tp
maxValueBound :: Ord tp => ValueBound tp -> ValueBound tp -> ValueBound tp

-- | Describes a range of values in a totally ordered set.
data ValueRange tp

-- | Indicates that range denotes a single value
SingleRange :: !tp -> ValueRange tp

-- | The number is unconstrained.
UnboundedRange :: ValueRange tp

-- | The number is greater than or equal to the given lower bound.
MinRange :: !tp -> ValueRange tp

-- | The number is less than or equal to the given upper bound.
MaxRange :: !tp -> ValueRange tp

-- | The number is between the given lower and upper bounds.
IntervalRange :: !tp -> !tp -> ValueRange tp

-- | Indicates that the number is somewhere between the given upper and
--   lower bound.
pattern MultiRange :: ValueBound tp -> ValueBound tp -> ValueRange tp

-- | Defines a unbounded value range.
unboundedRange :: ValueRange tp

-- | Map a monotonic function over a range.
mapRange :: (a -> b) -> ValueRange a -> ValueRange b

-- | Return lower bound of range.
rangeLowBound :: ValueRange tp -> ValueBound tp

-- | Return upper bound of range.
rangeHiBound :: ValueRange tp -> ValueBound tp

-- | Defines a value range containing a single element.
singleRange :: tp -> ValueRange tp

-- | Defines a unbounded value range.
concreteRange :: Eq tp => tp -> tp -> ValueRange tp

-- | Define a value range with the given bounds
valueRange :: Eq tp => ValueBound tp -> ValueBound tp -> ValueRange tp
addRange :: Num tp => ValueRange tp -> ValueRange tp -> ValueRange tp
negateRange :: Num tp => ValueRange tp -> ValueRange tp

-- | Multiply a range by a scalar value
rangeScalarMul :: (Ord tp, Num tp) => tp -> ValueRange tp -> ValueRange tp

-- | Multiply two ranges together.
mulRange :: (Ord tp, Num tp) => ValueRange tp -> ValueRange tp -> ValueRange tp

-- | Compute the smallest range containing both ranges.
joinRange :: Ord tp => ValueRange tp -> ValueRange tp -> ValueRange tp

-- | Check if range is just a single element.
asSingleRange :: ValueRange tp -> Maybe tp

-- | Return maybe Boolean if range is equal, is not equal, or
--   indeterminant.
rangeCheckEq :: Ord tp => ValueRange tp -> ValueRange tp -> Maybe Bool
rangeCheckLe :: Ord tp => ValueRange tp -> ValueRange tp -> Maybe Bool
rangeMin :: Ord a => ValueRange a -> ValueRange a -> ValueRange a
rangeMax :: Ord a => ValueRange a -> ValueRange a -> ValueRange a
intAbsRange :: ValueRange Integer -> ValueRange Integer

-- | Compute an abstract range for integer division. We are using the
--   SMTLib division operation, where the division is floor when the
--   divisor is positive and ceiling when the divisor is negative. We
--   compute the ranges assuming that division by 0 doesn't happen, and we
--   are allowed to return nonsense ranges for these cases.
intDivRange :: ValueRange Integer -> ValueRange Integer -> ValueRange Integer
intModRange :: ValueRange Integer -> ValueRange Integer -> ValueRange Integer
absAnd :: Maybe Bool -> Maybe Bool -> Maybe Bool
absOr :: Maybe Bool -> Maybe Bool -> Maybe Bool
data RealAbstractValue
RAV :: !ValueRange Rational -> !Maybe Bool -> RealAbstractValue
[ravRange] :: RealAbstractValue -> !ValueRange Rational
[ravIsInteger] :: RealAbstractValue -> !Maybe Bool
ravUnbounded :: RealAbstractValue
ravSingle :: Rational -> RealAbstractValue

-- | Range accepting everything between lower and upper bound.
ravConcreteRange :: Rational -> Rational -> RealAbstractValue
ravJoin :: RealAbstractValue -> RealAbstractValue -> RealAbstractValue

-- | Add two real abstract values.
ravAdd :: RealAbstractValue -> RealAbstractValue -> RealAbstractValue
ravScalarMul :: Rational -> RealAbstractValue -> RealAbstractValue
ravMul :: RealAbstractValue -> RealAbstractValue -> RealAbstractValue
ravCheckEq :: RealAbstractValue -> RealAbstractValue -> Maybe Bool
ravCheckLe :: RealAbstractValue -> RealAbstractValue -> Maybe Bool

-- | The string abstract domain tracks an interval range for the length of
--   the string.
newtype StringAbstractValue
StringAbs :: ValueRange Integer -> StringAbstractValue

-- | The length of the string falls in this range
[_stringAbsLength] :: StringAbstractValue -> ValueRange Integer
stringAbsJoin :: StringAbstractValue -> StringAbstractValue -> StringAbstractValue
stringAbsTop :: StringAbstractValue
stringAbsSingle :: StringLiteral si -> StringAbstractValue
stringAbsOverlap :: StringAbstractValue -> StringAbstractValue -> Bool
stringAbsLength :: StringAbstractValue -> ValueRange Integer
stringAbsConcat :: StringAbstractValue -> StringAbstractValue -> StringAbstractValue
stringAbsSubstring :: StringAbstractValue -> ValueRange Integer -> ValueRange Integer -> StringAbstractValue
stringAbsContains :: StringAbstractValue -> StringAbstractValue -> Maybe Bool
stringAbsIsPrefixOf :: StringAbstractValue -> StringAbstractValue -> Maybe Bool
stringAbsIsSuffixOf :: StringAbstractValue -> StringAbstractValue -> Maybe Bool
stringAbsIndexOf :: StringAbstractValue -> StringAbstractValue -> ValueRange Integer -> ValueRange Integer
stringAbsEmpty :: StringAbstractValue

-- | Create an abstract value that contains every concrete value.
avTop :: BaseTypeRepr tp -> AbstractValue tp

-- | Create an abstract value that contains the given concrete value.
avSingle :: BaseTypeRepr tp -> ConcreteValue tp -> AbstractValue tp

-- | Returns true if the concrete value is a member of the set represented
--   by the abstract value.
avContains :: BaseTypeRepr tp -> ConcreteValue tp -> AbstractValue tp -> Bool

-- | An abstract value represents a disjoint st of values.
type family AbstractValue (tp :: BaseType) :: Type
type family ConcreteValue (tp :: BaseType) :: Type
class Abstractable (tp :: BaseType)

-- | Take the union of the two abstract values.
avJoin :: Abstractable tp => BaseTypeRepr tp -> AbstractValue tp -> AbstractValue tp -> AbstractValue tp

-- | Returns true if the abstract values could contain a common concrete
--   value.
avOverlap :: Abstractable tp => BaseTypeRepr tp -> AbstractValue tp -> AbstractValue tp -> Bool

-- | Check equality on two abstract values. Return true or false if we can
--   definitively determine the equality of the two elements, and nothing
--   otherwise.
avCheckEq :: Abstractable tp => BaseTypeRepr tp -> AbstractValue tp -> AbstractValue tp -> Maybe Bool
withAbstractable :: BaseTypeRepr bt -> (Abstractable bt => a) -> a
newtype AbstractValueWrapper tp
AbstractValueWrapper :: AbstractValue tp -> AbstractValueWrapper tp
[unwrapAV] :: AbstractValueWrapper tp -> AbstractValue tp
newtype ConcreteValueWrapper tp
ConcreteValueWrapper :: ConcreteValue tp -> ConcreteValueWrapper tp
[unwrapCV] :: ConcreteValueWrapper tp -> ConcreteValue tp

-- | A utility class for values that contain abstract values
class HasAbsValue f
getAbsValue :: HasAbsValue f => f tp -> AbstractValue tp
instance GHC.Classes.Ord tp => GHC.Classes.Ord (What4.Utils.AbstractDomains.ValueBound tp)
instance GHC.Classes.Eq tp => GHC.Classes.Eq (What4.Utils.AbstractDomains.ValueBound tp)
instance GHC.Show.Show tp => GHC.Show.Show (What4.Utils.AbstractDomains.ValueBound tp)
instance GHC.Base.Functor What4.Utils.AbstractDomains.ValueBound
instance What4.Utils.AbstractDomains.Abstractable What4.BaseTypes.BaseBoolType
instance What4.Utils.AbstractDomains.Abstractable (What4.BaseTypes.BaseStringType si)
instance What4.Utils.AbstractDomains.Abstractable What4.BaseTypes.BaseIntegerType
instance What4.Utils.AbstractDomains.Abstractable What4.BaseTypes.BaseRealType
instance (1 Data.Type.Ord.<= w) => What4.Utils.AbstractDomains.Abstractable (What4.BaseTypes.BaseBVType w)
instance What4.Utils.AbstractDomains.Abstractable (What4.BaseTypes.BaseFloatType fpp)
instance What4.Utils.AbstractDomains.Abstractable What4.BaseTypes.BaseComplexType
instance What4.Utils.AbstractDomains.Abstractable (What4.BaseTypes.BaseArrayType idx b)
instance What4.Utils.AbstractDomains.Abstractable (What4.BaseTypes.BaseStructType ctx)
instance GHC.Base.Applicative What4.Utils.AbstractDomains.ValueBound
instance GHC.Base.Monad What4.Utils.AbstractDomains.ValueBound

-- | Declares a weighted sum type used for representing sums over variables
--   and an offset in one of the supported semirings. This module also
--   implements a representation of semiring products.
module What4.Expr.WeightedSum
type Tm f = (HashableF f, OrdF f, HasAbsValue f)

-- | A weighted sum of semiring values. Mathematically, this represents an
--   affine operation on the underlying expressions.
data WeightedSum (f :: BaseType -> Type) (sr :: SemiRing)

-- | Runtime representation of the semiring for this sum.
sumRepr :: WeightedSum f sr -> SemiRingRepr sr

-- | Retrieve the constant addend of the weighted sum.
sumOffset :: Lens' (WeightedSum f sr) (Coefficient sr)
sumAbsValue :: OrdF f => WeightedSum f sr -> AbstractValue (SemiRingBase sr)

-- | Create a sum from a constant coefficient value.
constant :: Tm f => SemiRingRepr sr -> Coefficient sr -> WeightedSum f sr

-- | Create a weighted sum corresponding to the given variable.
var :: Tm f => SemiRingRepr sr -> f (SemiRingBase sr) -> WeightedSum f sr

-- | This returns a variable times a constant.
scaledVar :: Tm f => SemiRingRepr sr -> Coefficient sr -> f (SemiRingBase sr) -> WeightedSum f sr

-- | Attempt to parse a weighted sum as a constant.
asConstant :: WeightedSum f sr -> Maybe (Coefficient sr)

-- | Attempt to parse a weighted sum as a single expression. asVar w =
--   Just r when denotation(w) = r
asVar :: WeightedSum f sr -> Maybe (f (SemiRingBase sr))

-- | Attempt to parse weighted sum as a single expression with a
--   coefficient. asWeightedVar w = Just (c,r) when
--   denotation(w) = c*r.
asWeightedVar :: WeightedSum f sr -> Maybe (Coefficient sr, f (SemiRingBase sr))

-- | Attempt to parse a weighted sum as a single expression with a
--   coefficient and offset. asAffineVar w = Just (c,r,o) when
--   denotation(w) = c*r + o.
asAffineVar :: WeightedSum f sr -> Maybe (Coefficient sr, f (SemiRingBase sr), Coefficient sr)

-- | Return true if a weighted sum is equal to constant 0.
isZero :: SemiRingRepr sr -> WeightedSum f sr -> Bool

-- | Traverse the expressions in a weighted sum.
traverseVars :: forall k j m sr. (Applicative m, Tm k) => (j (SemiRingBase sr) -> m (k (SemiRingBase sr))) -> WeightedSum j sr -> m (WeightedSum k sr)

-- | Traverse the coefficients in a weighted sum.
traverseCoeffs :: forall m f sr. (Applicative m, Tm f) => (Coefficient sr -> m (Coefficient sr)) -> WeightedSum f sr -> m (WeightedSum f sr)

-- | Add two sums, collecting terms as necessary and deleting terms whose
--   coefficients sum to 0.
add :: Tm f => SemiRingRepr sr -> WeightedSum f sr -> WeightedSum f sr -> WeightedSum f sr

-- | Add a variable to the sum.
addVar :: Tm f => SemiRingRepr sr -> WeightedSum f sr -> f (SemiRingBase sr) -> WeightedSum f sr

-- | Create a weighted sum that represents the sum of two terms.
addVars :: Tm f => SemiRingRepr sr -> f (SemiRingBase sr) -> f (SemiRingBase sr) -> WeightedSum f sr

-- | Add a constant to the sum.
addConstant :: SemiRingRepr sr -> WeightedSum f sr -> Coefficient sr -> WeightedSum f sr

-- | Multiply a sum by a constant coefficient.
scale :: Tm f => SemiRingRepr sr -> Coefficient sr -> WeightedSum f sr -> WeightedSum f sr

-- | Evaluate a sum given interpretations of addition, scalar
--   multiplication, and a constant rational.
eval :: (r -> r -> r) -> (Coefficient sr -> f (SemiRingBase sr) -> r) -> (Coefficient sr -> r) -> WeightedSum f sr -> r

-- | Evaluate a sum given interpretations of addition, scalar
--   multiplication, and a constant. This evaluation is threaded through a
--   monad. The addition function is associated to the left, as in
--   foldlM.
evalM :: Monad m => (r -> r -> m r) -> (Coefficient sr -> f (SemiRingBase sr) -> m r) -> (Coefficient sr -> m r) -> WeightedSum f sr -> m r

-- | Given two weighted sums x and y, this returns a
--   triple (z,x',y') where x = z + x' and y = z +
--   y' and z contains the "common" parts of x and
--   y. We only extract common terms when both terms occur with
--   the same coefficient in each sum.
--   
--   This is primarily used to simplify if-then-else expressions to
--   preserve shared subterms.
extractCommon :: Tm f => WeightedSum f sr -> WeightedSum f sr -> (WeightedSum f sr, WeightedSum f sr, WeightedSum f sr)

-- | Produce a weighted sum from a list of terms and an offset.
fromTerms :: Tm f => SemiRingRepr sr -> [(f (SemiRingBase sr), Coefficient sr)] -> Coefficient sr -> WeightedSum f sr

-- | Apply update functions to the terms and coefficients of a weighted
--   sum.
transformSum :: (Applicative m, Tm g) => SemiRingRepr sr' -> (Coefficient sr -> m (Coefficient sr')) -> (f (SemiRingBase sr) -> m (g (SemiRingBase sr'))) -> WeightedSum f sr -> m (WeightedSum g sr')

-- | Reduce a weighted sum of integers modulo a concrete integer. This
--   reduces each of the coefficients modulo the given integer, removing
--   any that are congruent to 0; the offset value is also reduced.
reduceIntSumMod :: Tm f => WeightedSum f SemiRingInteger -> Integer -> WeightedSum f SemiRingInteger

-- | A product of semiring values.
data SemiRingProduct (f :: BaseType -> Type) (sr :: SemiRing)

-- | Traverse the expressions in a product.
traverseProdVars :: forall k j m sr. (Applicative m, Tm k) => (j (SemiRingBase sr) -> m (k (SemiRingBase sr))) -> SemiRingProduct j sr -> m (SemiRingProduct k sr)

-- | Returns true if the product is trivial (contains no terms).
nullProd :: SemiRingProduct f sr -> Bool

-- | If the product consists of exactly on term, return it.
asProdVar :: SemiRingProduct f sr -> Maybe (f (SemiRingBase sr))

-- | Runtime representation of the semiring for this product
prodRepr :: SemiRingProduct f sr -> SemiRingRepr sr

-- | Produce a product representing the single given term.
prodVar :: Tm f => SemiRingRepr sr -> f (SemiRingBase sr) -> SemiRingProduct f sr
prodAbsValue :: OrdF f => SemiRingProduct f sr -> AbstractValue (SemiRingBase sr)

-- | Multiply two products, collecting terms and adding occurrences.
prodMul :: Tm f => SemiRingProduct f sr -> SemiRingProduct f sr -> SemiRingProduct f sr

-- | Evaluate a product, given a function representing multiplication and a
--   function to evaluate terms.
prodEval :: (r -> r -> r) -> (f (SemiRingBase sr) -> r) -> SemiRingProduct f sr -> Maybe r

-- | Evaluate a product, given a function representing multiplication and a
--   function to evaluate terms, where both functions are threaded through
--   a monad.
prodEvalM :: Monad m => (r -> r -> m r) -> (f (SemiRingBase sr) -> m r) -> SemiRingProduct f sr -> m (Maybe r)

-- | Returns true if the product contains at least on occurrence of the
--   given term.
prodContains :: OrdF f => SemiRingProduct f sr -> f (SemiRingBase sr) -> Bool
instance Data.Parameterized.Classes.OrdF f => Data.Type.Equality.TestEquality (What4.Expr.WeightedSum.SemiRingProduct f)
instance Data.Parameterized.Classes.OrdF f => GHC.Classes.Eq (What4.Expr.WeightedSum.SemiRingProduct f sr)
instance Data.Parameterized.Classes.OrdF f => Data.Hashable.Class.Hashable (What4.Expr.WeightedSum.SemiRingProduct f sr)
instance Data.Parameterized.Classes.OrdF f => Data.Type.Equality.TestEquality (What4.Expr.WeightedSum.WeightedSum f)
instance Data.Parameterized.Classes.OrdF f => GHC.Classes.Eq (What4.Expr.WeightedSum.WeightedSum f sr)
instance Data.Parameterized.Classes.OrdF f => Data.Hashable.Class.Hashable (What4.Expr.WeightedSum.WeightedSum f sr)
instance GHC.Base.Semigroup (What4.Expr.WeightedSum.ProdNote sr)
instance GHC.Base.Semigroup (What4.Expr.WeightedSum.Note sr)
instance Data.Parameterized.Classes.OrdF f => GHC.Classes.Ord (What4.Expr.WeightedSum.WrapF f i)
instance Data.Type.Equality.TestEquality f => GHC.Classes.Eq (What4.Expr.WeightedSum.WrapF f i)
instance (Data.Parameterized.Classes.HashableF f, Data.Type.Equality.TestEquality f) => Data.Hashable.Class.Hashable (What4.Expr.WeightedSum.WrapF f i)
instance GHC.Base.Semigroup (What4.Expr.WeightedSum.SRAbsValue sr)

module What4.Expr.ArrayUpdateMap
data ArrayUpdateMap e ctx tp
arrayUpdateAbs :: ArrayUpdateMap e ct tp -> Maybe (AbstractValue tp)
empty :: ArrayUpdateMap e ctx tp
null :: ArrayUpdateMap e ctx tp -> Bool
lookup :: Assignment IndexLit ctx -> ArrayUpdateMap e ctx tp -> Maybe (e tp)
filter :: (e tp -> Bool) -> ArrayUpdateMap e ctx tp -> ArrayUpdateMap e ctx tp
singleton :: (HashableF e, HasAbsValue e) => BaseTypeRepr tp -> Assignment IndexLit ctx -> e tp -> ArrayUpdateMap e ctx tp
insert :: (HashableF e, HasAbsValue e) => BaseTypeRepr tp -> Assignment IndexLit ctx -> e tp -> ArrayUpdateMap e ctx tp -> ArrayUpdateMap e ctx tp
delete :: Assignment IndexLit ctx -> ArrayUpdateMap e ctx tp -> ArrayUpdateMap e ctx tp
fromAscList :: (HasAbsValue e, HashableF e) => BaseTypeRepr tp -> [(Assignment IndexLit ctx, e tp)] -> ArrayUpdateMap e ctx tp
toList :: ArrayUpdateMap e ctx tp -> [(Assignment IndexLit ctx, e tp)]
toMap :: ArrayUpdateMap e ctx tp -> Map (Assignment IndexLit ctx) (e tp)
keysSet :: ArrayUpdateMap e ctx tp -> Set (Assignment IndexLit ctx)
traverseArrayUpdateMap :: Applicative m => (e tp -> m (f tp)) -> ArrayUpdateMap e ctx tp -> m (ArrayUpdateMap f ctx tp)
mergeM :: (Applicative m, HashableF g, HasAbsValue g) => BaseTypeRepr tp -> (Assignment IndexLit ctx -> e tp -> f tp -> m (g tp)) -> (Assignment IndexLit ctx -> e tp -> m (g tp)) -> (Assignment IndexLit ctx -> f tp -> m (g tp)) -> ArrayUpdateMap e ctx tp -> ArrayUpdateMap f ctx tp -> m (ArrayUpdateMap g ctx tp)
instance Data.Type.Equality.TestEquality e => GHC.Classes.Eq (What4.Expr.ArrayUpdateMap.ArrayUpdateMap e ctx tp)
instance Data.Type.Equality.TestEquality e => Data.Hashable.Class.Hashable (What4.Expr.ArrayUpdateMap.ArrayUpdateMap e ctx tp)
instance GHC.Base.Semigroup (What4.Expr.ArrayUpdateMap.ArrayUpdateNote tp)

-- | This module defines a representation of concrete values of base types.
--   These are values in fully-evaluated form that do not depend on any
--   symbolic constants.
module What4.Concrete

-- | A data type for representing the concrete values of base types.
data ConcreteVal tp
[ConcreteBool] :: Bool -> ConcreteVal BaseBoolType
[ConcreteInteger] :: Integer -> ConcreteVal BaseIntegerType
[ConcreteReal] :: Rational -> ConcreteVal BaseRealType
[ConcreteFloat] :: FloatPrecisionRepr fpp -> BigFloat -> ConcreteVal (BaseFloatType fpp)
[ConcreteString] :: StringLiteral si -> ConcreteVal (BaseStringType si)
[ConcreteComplex] :: Complex Rational -> ConcreteVal BaseComplexType
[ConcreteBV] :: 1 <= w => NatRepr w -> BV w -> ConcreteVal (BaseBVType w)
[ConcreteStruct] :: Assignment ConcreteVal ctx -> ConcreteVal (BaseStructType ctx)
[ConcreteArray] :: Assignment BaseTypeRepr (idx ::> i) -> ConcreteVal b -> Map (Assignment ConcreteVal (idx ::> i)) (ConcreteVal b) -> ConcreteVal (BaseArrayType (idx ::> i) b)

-- | Compute the type representative for a concrete value.
concreteType :: ConcreteVal tp -> BaseTypeRepr tp

-- | Pretty-print a concrete value
ppConcrete :: ConcreteVal tp -> Doc ann
fromConcreteBool :: ConcreteVal BaseBoolType -> Bool
fromConcreteInteger :: ConcreteVal BaseIntegerType -> Integer
fromConcreteReal :: ConcreteVal BaseRealType -> Rational
fromConcreteString :: ConcreteVal (BaseStringType si) -> StringLiteral si
fromConcreteBV :: ConcreteVal (BaseBVType w) -> BV w
fromConcreteComplex :: ConcreteVal BaseComplexType -> Complex Rational
instance Data.Type.Equality.TestEquality What4.Concrete.ConcreteVal
instance GHC.Classes.Eq (What4.Concrete.ConcreteVal tp)
instance Data.Parameterized.Classes.OrdF What4.Concrete.ConcreteVal
instance GHC.Classes.Ord (What4.Concrete.ConcreteVal tp)
instance Data.Parameterized.Classes.ShowF What4.Concrete.ConcreteVal
instance GHC.Show.Show (What4.Concrete.ConcreteVal tp)

-- | This module provides access to persistent configuration settings, and
--   is designed for access both by Haskell client code of the What4
--   library, and by users of the systems ultimately built using the
--   library, for example, from within a user-facing REPL.
--   
--   Configurations are defined dynamically by combining a collection of
--   configuration option descriptions. This allows disparate modules to
--   define their own configuration options, rather than having to define
--   the options for all modules in a central place. Every configuration
--   option has a name, which consists of a nonempty sequence of
--   period-separated strings. The intention is that option names should
--   conform to a namespace hierarchy both for organizational purposes and
--   to avoid namespace conflicts. For example, the options for an "asdf"
--   module might be named as:
--   
--   
--   
- asdf.widget
--   
- asdf.frob
--   
- asdf.max_bound
--   
--   
--   At runtime, a configuration consists of a collection of nested finite
--   maps corresponding to the namespace tree of the existing options. A
--   configuration option may be queried or set either by using a raw
--   string representation of the name (see
--   getOptionSettingFromText), or by using a ConfigOption
--   value (using getOptionSetting), which provides a modicum of
--   type-safety over the basic dynamically-typed configuration maps.
--   
--   Each option is associated with an "option style", which describes the
--   underlying type of the option (e.g., integer, boolean, string, etc.)
--   as well as the allowed settings of that value. In addition, options
--   can take arbitrary actions when their values are changed in the
--   opt_onset callback.
--   
--   Every configuration comes with the built-in verbosity
--   configuration option pre-defined. A Config value is constructed
--   using the initialConfig operation, which should be given the
--   initial verbosity value and a collection of configuration options to
--   install. A configuration may be later extended with additional options
--   by using the extendConfig operation.
--   
--   Example use (assuming you wanted to use the z3 solver):
--   
--   
--   import What4.Solver
--   
--   setupSolverConfig :: (IsExprBuilder sym) -> sym -> IO ()
--   setupSolverConfig sym = do
--     let cfg = getConfiguration sym
--     extendConfig (solver_adapter_config_options z3Adapter) cfg
--     z3PathSetter <- getOptionSetting z3Path
--     res <- setOpt z3PathSetter "/usr/bin/z3"
--     assert (null res) (return ())
--   
--   
--   Developer's note: we might want to add the following operations:
--   
--   
--   
- a method for "unsetting" options to restore the default state of
--   an option
--   
- a method for removing options from a configuration altogether
--   (i.e., to undo extendConfig)
--   
--   
--   Note regarding concurrency: the configuration data structures in this
--   module are implemented using MVars, and may safely be used in a
--   multithreaded way; configuration changes made in one thread will be
--   visible to others in a properly synchronized way. Of course, if one
--   desires to isolate configuration changes in different threads from
--   each other, separate configuration objects are required. The
--   splitConfig operation may be useful to partially isolate
--   configuration objects. As noted in the documentation for
--   opt_onset, the validation procedures for options should not
--   look up the value of other options, or deadlock may occur.
module What4.Config

-- | A Haskell-land wrapper around the name of a configuration option.
--   Developers are encouraged to define and use ConfigOption values
--   to avoid two classes of errors: typos in configuration option names;
--   and dynamic type-cast failures. Both classes of errors can be lifted
--   to statically-checkable failures (missing symbols and type-checking,
--   respectively) by consistently using ConfigOption values.
--   
--   The following example indicates the suggested usage
--   
--   
--   asdfFrob :: ConfigOption BaseRealType
--   asdfFrob = configOption BaseRealRepr "asdf.frob"
--   
--   asdfMaxBound :: ConfigOption BaseIntegerType
--   asdfMaxBound = configOption BaseIntegerRepr "asdf.max_bound"
--   
data ConfigOption (tp :: BaseType)

-- | Construct a ConfigOption from a string name. Idiomatic usage is
--   to define a single top-level ConfigOption value in the module
--   where the option is defined to consistently fix its name and type for
--   all subsequent uses.
configOption :: BaseTypeRepr tp -> String -> ConfigOption tp

-- | Retrieve the run-time type representation of tp.
configOptionType :: ConfigOption tp -> BaseTypeRepr tp

-- | Reconstruct the original string name of this option.
configOptionName :: ConfigOption tp -> String

-- | Reconstruct the original string name of this option.
configOptionText :: ConfigOption tp -> Text

-- | Get the individual dot-separated segments of an option's name.
configOptionNameParts :: ConfigOption tp -> [Text]

-- | An OptionSetting gives the direct ability to query or set the
--   current value of an option. The getOption field is an action
--   that, when executed, fetches the current value of the option, if it is
--   set. The setOption method attempts to set the value of the
--   option. If the associated opt_onset validation method rejects
--   the option, it will retain its previous value; otherwise it will be
--   set to the given value. In either case, the generated
--   OptionSetResult will be returned.
data OptionSetting (tp :: BaseType)
OptionSetting :: ConfigOption tp -> IO (Maybe (ConcreteVal tp)) -> (ConcreteVal tp -> IO OptionSetResult) -> OptionSetting (tp :: BaseType)
[optionSettingName] :: OptionSetting (tp :: BaseType) -> ConfigOption tp
[getOption] :: OptionSetting (tp :: BaseType) -> IO (Maybe (ConcreteVal tp))
[setOption] :: OptionSetting (tp :: BaseType) -> ConcreteVal tp -> IO OptionSetResult

-- | A utility class for making working with option settings easier. The
--   tp argument is a BaseType, and the a
--   argument is an associcated Haskell type.
class Opt (tp :: BaseType) (a :: Type) | tp -> a

-- | Return the current value of the option, as a Maybe value.
getMaybeOpt :: Opt tp a => OptionSetting tp -> IO (Maybe a)

-- | Attempt to set the value of an option. Return any errors or warnings.
trySetOpt :: Opt tp a => OptionSetting tp -> a -> IO OptionSetResult

-- | Set the value of an option. Return any generated warnings. Throws an
--   OptSetFailure exception if a validation error occurs.
setOpt :: Opt tp a => OptionSetting tp -> a -> IO [Doc Void]

-- | Get the current value of an option. Throw an exception if the option
--   is not currently set.
getOpt :: Opt tp a => OptionSetting tp -> IO a

-- | Given a unicode text value, set the named option to that value or
--   generate an OptSetFailure exception if the option is not a unicode
--   text valued option.
setUnicodeOpt :: Some OptionSetting -> Text -> IO [Doc Void]

-- | Given an integer value, set the named option to that value or generate
--   an OptSetFailure exception if the option is not an integer valued
--   option.
setIntegerOpt :: Some OptionSetting -> Integer -> IO [Doc Void]

-- | Given a boolean value, set the named option to that value or generate
--   an OptSetFailure exception if the option is not a boolean valued
--   option.
setBoolOpt :: Some OptionSetting -> Bool -> IO [Doc Void]

-- | An option defines some metadata about how a configuration option
--   behaves. It contains a base type representation, which defines the
--   runtime type that is expected for setting and querying this option at
--   runtime.
data OptionStyle (tp :: BaseType)
OptionStyle :: BaseTypeRepr tp -> (Maybe (ConcreteVal tp) -> ConcreteVal tp -> IO OptionSetResult) -> Doc Void -> Maybe (ConcreteVal tp) -> OptionStyle (tp :: BaseType)

-- | base type representation of this option
[opt_type] :: OptionStyle (tp :: BaseType) -> BaseTypeRepr tp

-- | An operation for validating new option values. This action may also be
--   used to take actions whenever an option setting is changed. NOTE! the
--   onset action should not attempt to look up the values of other
--   configuration settings, or deadlock may occur.
--   
--   The first argument is the current value of the option (if any). The
--   second argument is the new value that is being set. If the validation
--   fails, the operation should return a result describing why validation
--   failed. Optionally, warnings may also be returned.
[opt_onset] :: OptionStyle (tp :: BaseType) -> Maybe (ConcreteVal tp) -> ConcreteVal tp -> IO OptionSetResult

-- | Documentation for the option to be displayed in the event a user asks
--   for information about this option. This message should contain
--   information relevant to all options in this style (e.g., its type and
--   range of expected values), not necessarily information about a
--   specific option.
[opt_help] :: OptionStyle (tp :: BaseType) -> Doc Void

-- | This gives a default value for the option, if set.
[opt_default_value] :: OptionStyle (tp :: BaseType) -> Maybe (ConcreteVal tp)

-- | Update the opt_default_value field.
set_opt_default :: ConcreteVal tp -> OptionStyle tp -> OptionStyle tp

-- | Update the opt_onset field.
set_opt_onset :: (Maybe (ConcreteVal tp) -> ConcreteVal tp -> IO OptionSetResult) -> OptionStyle tp -> OptionStyle tp

-- | When setting the value of an option, a validation function is called
--   (as defined by the associated OptionStyle). The result of the
--   validation function is an OptionSetResult. If the option
--   value given is invalid for some reason, an error should be returned.
--   Additionally, warning messages may be returned, which will be passed
--   through to the eventual call site attempting to alter the option
--   setting.
data OptionSetResult
OptionSetResult :: !Maybe (Doc Void) -> !Seq (Doc Void) -> OptionSetResult
[optionSetError] :: OptionSetResult -> !Maybe (Doc Void)
[optionSetWarnings] :: OptionSetResult -> !Seq (Doc Void)

-- | Accept the new option value with no errors or warnings.
optOK :: OptionSetResult

-- | Accept the given option value, but report a warning message.
optWarn :: Doc Void -> OptionSetResult

-- | Reject the new option value with an error message.
optErr :: Doc Void -> OptionSetResult

-- | Throw an exception if the given OptionSetResult indicates an
--   error. Otherwise, return any generated warnings.
checkOptSetResult :: OptionSetting tp -> OptionSetResult -> IO [Doc Void]
data OptSetFailure
OptSetFailure :: Some OptionSetting -> Doc Void -> OptSetFailure
data OptGetFailure
OptGetFailure :: OptRef -> Doc Void -> OptGetFailure
data OptCreateFailure
OptCreateFailure :: ConfigDesc -> Doc Void -> OptCreateFailure

-- | An inclusive or exclusive bound.
data Bound r
Exclusive :: r -> Bound r
Inclusive :: r -> Bound r
Unbounded :: Bound r

-- | Standard option style for boolean-valued configuration options
boolOptSty :: OptionStyle BaseBoolType

-- | Standard option style for integral-valued configuration options
integerOptSty :: OptionStyle BaseIntegerType

-- | Standard option style for real-valued configuration options
realOptSty :: OptionStyle BaseRealType
stringOptSty :: OptionStyle (BaseStringType Unicode)

-- | Option style for real-valued options with upper and lower bounds
realWithRangeOptSty :: Bound Rational -> Bound Rational -> OptionStyle BaseRealType

-- | Option style for real-valued options with a lower bound
realWithMinOptSty :: Bound Rational -> OptionStyle BaseRealType

-- | Option style for real-valued options with an upper bound
realWithMaxOptSty :: Bound Rational -> OptionStyle BaseRealType

-- | Option style for integer-valued options with upper and lower bounds
integerWithRangeOptSty :: Bound Integer -> Bound Integer -> OptionStyle BaseIntegerType

-- | Option style for integer-valued options with a lower bound
integerWithMinOptSty :: Bound Integer -> OptionStyle BaseIntegerType

-- | Option style for integer-valued options with an upper bound
integerWithMaxOptSty :: Bound Integer -> OptionStyle BaseIntegerType

-- | A configuration style for options that must be one of a fixed set of
--   text values
enumOptSty :: Set Text -> OptionStyle (BaseStringType Unicode)

-- | A configuration syle for options that must be one of a fixed set of
--   text values. Associated with each string is a validation/callback
--   action that will be run whenever the named string option is selected.
listOptSty :: Map Text (IO OptionSetResult) -> OptionStyle (BaseStringType Unicode)

-- | A configuration style for options that are expected to be paths to an
--   executable image. Configuration options with this style generate a
--   warning message if set to a value that cannot be resolved to an
--   absolute path to an executable file in the current OS environment.
executablePathOptSty :: OptionStyle (BaseStringType Unicode)

-- | A ConfigDesc describes a configuration option before it is
--   installed into a Config object. It consists of a
--   ConfigOption name for the option, an OptionStyle
--   describing the sort of option it is, and an optional help message
--   describing the semantics of this option.
data ConfigDesc

-- | The most general method for constructing a normal ConfigDesc.
mkOpt :: ConfigOption tp -> OptionStyle tp -> Maybe (Doc Void) -> Maybe (ConcreteVal tp) -> ConfigDesc

-- | Construct an option using a default style with a given initial value
opt :: Pretty help => ConfigOption tp -> ConcreteVal tp -> help -> ConfigDesc

-- | Construct an option using a default style with a given initial value.
--   Also provide a validation function to check new values as they are
--   set.
optV :: forall tp help. Pretty help => ConfigOption tp -> ConcreteVal tp -> (ConcreteVal tp -> Maybe help) -> help -> ConfigDesc

-- | Construct an option using a default style with no initial value.
optU :: Pretty help => ConfigOption tp -> help -> ConfigDesc

-- | Construct an option using a default style with no initial value. Also
--   provide a validation function to check new values as they are set.
optUV :: forall help tp. Pretty help => ConfigOption tp -> (ConcreteVal tp -> Maybe help) -> help -> ConfigDesc

-- | The copyOpt creates a duplicate ConfigDesc under a different name.
--   This is typically used to taking a common operation and modify the
--   prefix to apply it to a more specialized role (e.g.
--   solver.strict_parsing --> solver.z3.strict_parsing). The style and
--   help text of the input ConfigDesc are preserved, but any deprecation
--   is discarded.
copyOpt :: (Text -> Text) -> ConfigDesc -> ConfigDesc

-- | Used as a wrapper for an option that has been deprecated. If the
--   option is actually set (as opposed to just using the default value)
--   then this will emit an OptionSetResult warning that time, optionally
--   mentioning the replacement option (if specified).
--   
--   There are three cases of deprecation: 1. Removing an option that no
--   longer applies 2. Changing the name or heirarchical position of an
--   option. 3. #2 and also changing the type. 4. Replacing an option by
--   multiple new options (e.g. split url option into hostname and port
--   options)
--   
--   In the case of #1, the option will presumably be ignored by the code
--   and the warnings are provided to allow the user to clean the option
--   from their configurations.
--   
--   In the case of #2, the old option and the new option will share the
--   same value storage: changes to one can be seen via the other and vice
--   versa. The code can be switched over to reference the new option
--   entirely, and user configurations setting the old option will still
--   work until they have been updated and the definition of the old option
--   is removed entirely.
--   
--   NOTE: in order to support #2, the newer option should be declared (via
--   insertOption) *before* the option it deprecates.
--   
--   In the case of #3, it is not possible to share storage space, so
--   during the deprecation period, the code using the option config value
--   must check both locations and decide which value to utilize.
--   
--   Case #4 is an enhanced form of #3 and #2, and is generally treated as
--   #3, but adds the consideration that deprecation warnings will need to
--   advise about multiple new options. The inverse of #4 (multiple options
--   being combined to a single newer option) is just treated as separate
--   deprecations.
--   
--   NOTE: in order to support #4, the newer options should all be declared
--   (via insertOption) *before* the options they deprecate.
--   
--   Nested deprecations are valid, and replacement warnings are
--   automatically transitive to the newest options.
--   
--   Any user-supplied value for the old option will result in warnings
--   emitted to the OptionSetResult for all four cases. Code should ensure
--   that these warnings are appropriately communicated to the user to
--   allow configuration updates to occur.
--   
--   Note that for #1 and #2, the overhead burden of continuing to define
--   the deprecated option is very small, so actual removal of the older
--   config can be delayed indefinitely.
deprecatedOpt :: [ConfigDesc] -> ConfigDesc -> ConfigDesc

-- | The main configuration datatype. It consists of a Read/Write var
--   containing the actual configuration data.
data Config

-- | Construct a new configuration from the given configuration
--   descriptions.
initialConfig :: Integer -> [ConfigDesc] -> IO Config

-- | Extend an existing configuration with new options. An
--   OptCreateFailure exception will be raised if any of the given
--   options clash with options that already exists.
extendConfig :: [ConfigDesc] -> Config -> IO ()

-- | Extend an existing configuration with new options. If any of the given
--   options are already present in the configuration, nothing is done for
--   that option and it is silently skipped.
tryExtendConfig :: [ConfigDesc] -> Config -> IO ()

-- | Create a new configuration object that shares the option settings
--   currently in the given input config. However, any options added to
--   either configuration using extendConfig will not be
--   propagated to the other.
--   
--   Option settings that already exist in the input configuration will be
--   shared between both; changes to those options will be visible in both
--   configurations.
splitConfig :: Config -> IO Config

-- | Given a ConfigOption name, produce an OptionSetting
--   object for accessing and setting the value of that option.
--   
--   An exception is thrown if the named option cannot be found the
--   Config object, or if a type mismatch occurs.
getOptionSetting :: ConfigOption tp -> Config -> IO (OptionSetting tp)

-- | Given a text name, produce an OptionSetting object for
--   accessing and setting the value of that option.
--   
--   An exception is thrown if the named option cannot be found.
getOptionSettingFromText :: Text -> Config -> IO (Some OptionSetting)

-- | A ConfigValue bundles together the name of an option with its
--   current value.
data ConfigValue
[ConfigValue] :: ConfigOption tp -> ConcreteVal tp -> ConfigValue

-- | Given the name of a subtree, return all the currently-set
--   configuration values in that subtree.
--   
--   If the subtree name is empty, the entire tree will be traversed.
getConfigValues :: Text -> Config -> IO [ConfigValue]

-- | Given the name of a subtree, compute help text for all the options
--   available in that subtree.
--   
--   If the subtree name is empty, the entire tree will be traversed.
configHelp :: Text -> Config -> IO [Doc Void]

-- | Verbosity of the simulator. This option controls how much
--   informational and debugging output is generated. 0 yields low
--   information output; 5 is extremely chatty.
verbosity :: ConfigOption BaseIntegerType

-- | Return an operation that will consult the current value of the
--   verbosity option, and will print a string to the given Handle
--   if the provided int is smaller than the current verbosity setting.
verbosityLogger :: Config -> Handle -> IO (Int -> String -> IO ())
instance Prettyprinter.Internal.Pretty What4.Config.ConfigValue
instance What4.Config.Opt (What4.BaseTypes.BaseStringType What4.BaseTypes.Unicode) Data.Text.Internal.Text
instance What4.Config.Opt What4.BaseTypes.BaseIntegerType GHC.Num.Integer.Integer
instance What4.Config.Opt What4.BaseTypes.BaseBoolType GHC.Types.Bool
instance What4.Config.Opt What4.BaseTypes.BaseRealType GHC.Real.Rational
instance GHC.Exception.Type.Exception What4.Config.OptGetFailure
instance GHC.Show.Show What4.Config.OptGetFailure
instance GHC.Show.Show What4.Config.OptRef
instance GHC.Exception.Type.Exception What4.Config.OptSetFailure
instance GHC.Show.Show What4.Config.OptSetFailure
instance GHC.Exception.Type.Exception What4.Config.OptCreateFailure
instance GHC.Show.Show What4.Config.OptCreateFailure
instance GHC.Show.Show What4.Config.ConfigDesc
instance GHC.Show.Show (What4.Config.OptionSetting tp)
instance Data.Parameterized.Classes.ShowF What4.Config.OptionSetting
instance GHC.Base.Semigroup What4.Config.OptionSetResult
instance GHC.Base.Monoid What4.Config.OptionSetResult
instance GHC.Show.Show (What4.Config.ConfigOption tp)

module What4.Utils.Process

-- | This runs a given external binary, providing the process handle and
--   handles to input and output to the action. It takes care to terminate
--   the process if any exception is thrown by the action.
withProcessHandles :: FilePath -> [String] -> Maybe FilePath -> ((Handle, Handle, Handle, ProcessHandle) -> IO a) -> IO a

-- | Utility function that runs a solver specified by the given config
--   setting within a context. Errors can then be attributed to the solver.
resolveSolverPath :: FilePath -> IO FilePath
findSolverPath :: ConfigOption (BaseStringType Unicode) -> Config -> IO FilePath

-- | Filtering function for use with catchJust or tryJust
--   that filters out async exceptions so they are rethrown instead of
--   captured
filterAsync :: SomeException -> Maybe SomeException

-- | Start a process connected to this one via pipes.
startProcess :: FilePath -> [String] -> Maybe FilePath -> IO (Handle, Handle, Handle, ProcessHandle)

-- | Close the connected process pipes and wait for the process to exit
cleanupProcess :: (Handle, Handle, Handle, ProcessHandle) -> IO ExitCode

-- | Defines interface between the simulator and terms that are sent to the
--   SAT or SMT solver. The simulator can use a richer set of types, but
--   the symbolic values must be representable by types supported by this
--   interface.
--   
--   A solver backend is defined in terms of a type parameter sym,
--   which is the type that tracks whatever state or context is needed by
--   that particular backend. To instantiate the solver interface, one must
--   provide several type family definitions and class instances for
--   sym:
--   
--   
--   
- type SymExpr sym :: BaseType -> *
--   Type of symbolic expressions.
--   
- type BoundVar sym :: BaseType ->
--   * Representation of bound variables in symbolic
--   expressions.
--   
- type SymFn sym :: Ctx BaseType -> BaseType ->
--   * Representation of symbolic functions.
--   
- instance IsExprBuilder sym Functions for
--   building expressions of various types.
--   
- instance IsSymExprBuilder sym Functions for
--   building expressions with bound variables and quantifiers.
--   
- instance IsExpr (SymExpr sym)
--   Recognizers for various kinds of literal expressions.
--   
- instance OrdF (SymExpr sym)
--   
- instance TestEquality (SymExpr
--   sym)
--   
- instance HashableF (SymExpr
--   sym)
--   
- instance OrdF (BoundVar sym)
--   
- instance TestEquality (BoundVar
--   sym)
--   
- instance HashableF (BoundVar
--   sym)
--   
--   
--   The canonical implementation of these interface classes is found in
--   What4.Expr.Builder.
module What4.Interface

-- | The class for expressions.
type family SymExpr (sym :: Type) :: BaseType -> Type

-- | Type of bound variable associated with symbolic state.
--   
--   This type is used by some methods in class IsSymExprBuilder.
type family BoundVar (sym :: Type) :: BaseType -> Type

-- | A function that can be applied to symbolic arguments.
--   
--   This type is used by some methods in classes IsExprBuilder and
--   IsSymExprBuilder.
type family SymFn sym :: Ctx BaseType -> BaseType -> Type

-- | Type used to uniquely identify expressions that have been annotated.
type family SymAnnotation (sym :: Type) :: BaseType -> Type

-- | This class provides operations for recognizing when symbolic
--   expressions represent concrete values, extracting the type from an
--   expression, and for providing pretty-printed representations of an
--   expression.
class HasAbsValue e => IsExpr e

-- | Evaluate if predicate is constant.
asConstantPred :: IsExpr e => e BaseBoolType -> Maybe Bool

-- | Return integer if this is a constant integer.
asInteger :: IsExpr e => e BaseIntegerType -> Maybe Integer

-- | Return any bounding information we have about the term
integerBounds :: IsExpr e => e BaseIntegerType -> ValueRange Integer

-- | Return rational if this is a constant value.
asRational :: IsExpr e => e BaseRealType -> Maybe Rational

-- | Return floating-point value if this is a constant
asFloat :: IsExpr e => e (BaseFloatType fpp) -> Maybe BigFloat

-- | Return any bounding information we have about the term
rationalBounds :: IsExpr e => e BaseRealType -> ValueRange Rational

-- | Return complex if this is a constant value.
asComplex :: IsExpr e => e BaseComplexType -> Maybe (Complex Rational)

-- | Return a bitvector if this is a constant bitvector.
asBV :: IsExpr e => e (BaseBVType w) -> Maybe (BV w)

-- | If we have bounds information about the term, return unsigned upper
--   and lower bounds as integers
unsignedBVBounds :: (IsExpr e, 1 <= w) => e (BaseBVType w) -> Maybe (Integer, Integer)

-- | If we have bounds information about the term, return signed upper and
--   lower bounds as integers
signedBVBounds :: (IsExpr e, 1 <= w) => e (BaseBVType w) -> Maybe (Integer, Integer)

-- | If this expression syntactically represents an "affine" form, return
--   its components. When asAffineVar x = Just (c,r,o), then we
--   have x == c*r + o.
asAffineVar :: IsExpr e => e tp -> Maybe (ConcreteVal tp, e tp, ConcreteVal tp)

-- | Return the string value if this is a constant string
asString :: IsExpr e => e (BaseStringType si) -> Maybe (StringLiteral si)

-- | Return the representation of the string info for a string-typed term.
stringInfo :: IsExpr e => e (BaseStringType si) -> StringInfoRepr si

-- | Return the unique element value if this is a constant array, such as
--   one made with constantArray.
asConstantArray :: IsExpr e => e (BaseArrayType idx bt) -> Maybe (e bt)

-- | Return the struct fields if this is a concrete struct.
asStruct :: IsExpr e => e (BaseStructType flds) -> Maybe (Assignment e flds)

-- | Get type of expression.
exprType :: IsExpr e => e tp -> BaseTypeRepr tp

-- | Get the width of a bitvector
bvWidth :: IsExpr e => e (BaseBVType w) -> NatRepr w

-- | Get the precision of a floating-point expression
floatPrecision :: IsExpr e => e (BaseFloatType fpp) -> FloatPrecisionRepr fpp

-- | Print a sym expression for debugging or display purposes.
printSymExpr :: IsExpr e => e tp -> Doc ann

-- | Set the abstract value of an expression. This is primarily useful for
--   symbolic expressions where the domain is known to be narrower than
--   what is contained in the expression. Setting the abstract value to use
--   the narrower domain can, in some cases, allow the expression to be
--   further simplified.
--   
--   This is prefixed with unsafe- because it has the potential to
--   introduce unsoundness if the new abstract value does not accurately
--   represent the domain of the expression. As such, the burden is on
--   users of this function to ensure that the new abstract value is used
--   soundly.
--   
--   Note that composing expressions together can sometimes widen the
--   abstract domains involved, so if you use this function to change an
--   abstract value, be careful than subsequent operations do not widen
--   away the value. As a potential safeguard, one can use
--   annotateTerm on the new expression to inhibit transformations
--   that could change the abstract value.
unsafeSetAbstractValue :: IsExpr e => AbstractValue tp -> e tp -> e tp

-- | A class for extracting type representatives from symbolic functions
class IsSymFn (fn :: Ctx BaseType -> BaseType -> Type)

-- | Get the argument types of a function.
fnArgTypes :: IsSymFn fn => fn args ret -> Assignment BaseTypeRepr args

-- | Get the return type of a function.
fnReturnType :: IsSymFn fn => fn args ret -> BaseTypeRepr ret

-- | Test whether two functions are equal.
--   
--   The implementation may be incomplete, that is, if it returns
--   Just then the functions are equal, while if it returns
--   Nothing then the functions may or may not be equal. The result
--   of freshTotalUninterpFn or definedFn tests equal with
--   itself.
fnTestEquality :: IsSymFn fn => fn args1 ret1 -> fn args2 ret2 -> Maybe ((args1 ::> ret1) :~: (args2 ::> ret2))

-- | Compare two functions for ordering.
--   
--   The underlying equality test is provided by fnTestEquality.
fnCompare :: IsSymFn fn => fn args1 ret1 -> fn args2 ret2 -> OrderingF (args1 ::> ret1) (args2 ::> ret2)
data SomeSymFn sym
SomeSymFn :: SymFn sym args ret -> SomeSymFn sym

-- | Wrapper for SymFn that concatenates the arguments and the
--   return types.
--   
--   This is useful for implementing TestEquality and OrdF
--   instances for SymFn, and for using SymFn as a key or a
--   value in a MapF.
data SymFnWrapper sym ctx
[SymFnWrapper] :: forall sym args ret. SymFn sym args ret -> SymFnWrapper sym (args ::> ret)

-- | Describes when we unfold the body of defined functions.
data UnfoldPolicy

-- | What4 will not unfold the body of functions when applied to arguments
NeverUnfold :: UnfoldPolicy

-- | The function will be unfolded into its definition whenever it is
--   applied to arguments
AlwaysUnfold :: UnfoldPolicy

-- | The function will be unfolded into its definition only if all the
--   provided arguments are concrete.
UnfoldConcrete :: UnfoldPolicy

-- | Evaluates an UnfoldPolicy on a collection of arguments.
shouldUnfold :: IsExpr e => UnfoldPolicy -> Assignment e args -> Bool

-- | This class allows the simulator to build symbolic expressions.
--   
--   Methods of this class refer to type families SymExpr
--   sym and SymFn sym.
--   
--   Note: Some methods in this class represent operations that are partial
--   functions on their domain (e.g., division by 0). Such functions will
--   have documentation strings indicating that they are undefined under
--   some conditions. When partial functions are applied outside their
--   defined domains, they will silently produce an unspecified value of
--   the expected type. The unspecified value returned as the result of an
--   undefined function is _not_ guaranteed to be equivalant to a free
--   constant, and no guarantees are made about what properties such values
--   will satisfy.
class (IsExpr (SymExpr sym), HashableF (SymExpr sym), HashableF (BoundVar sym), TestEquality (SymAnnotation sym), OrdF (SymAnnotation sym), HashableF (SymAnnotation sym)) => IsExprBuilder sym

-- | Retrieve the configuration object corresponding to this solver
--   interface.
getConfiguration :: IsExprBuilder sym => sym -> Config

-- | Install an action that will be invoked before and after calls to
--   backend solvers. This action is primarily intended to be used for
--   logging/profiling/debugging purposes. Passing Nothing to this
--   function disables logging.
setSolverLogListener :: IsExprBuilder sym => sym -> Maybe (SolverEvent -> IO ()) -> IO ()

-- | Get the currently-installed solver log listener, if one has been
--   installed.
getSolverLogListener :: IsExprBuilder sym => sym -> IO (Maybe (SolverEvent -> IO ()))

-- | Provide the given event to the currently installed solver log
--   listener, if any.
logSolverEvent :: IsExprBuilder sym => sym -> SolverEvent -> IO ()

-- | Get statistics on execution from the initialization of the symbolic
--   interface to this point. May return zeros if gathering statistics
--   isn't supported.
getStatistics :: IsExprBuilder sym => sym -> IO Statistics

-- | Get current location of program for term creation purposes.
getCurrentProgramLoc :: IsExprBuilder sym => sym -> IO ProgramLoc

-- | Set current location of program for term creation purposes.
setCurrentProgramLoc :: IsExprBuilder sym => sym -> ProgramLoc -> IO ()

-- | Return true if two expressions are equal. The default implementation
--   dispatches eqPred, bvEq, natEq, intEq,
--   realEq, cplxEq, structEq, or arrayEq,
--   depending on the type.
isEq :: IsExprBuilder sym => sym -> SymExpr sym tp -> SymExpr sym tp -> IO (Pred sym)

-- | Take the if-then-else of two expressions. The default implementation
--   dispatches itePred, bvIte, natIte, intIte,
--   realIte, cplxIte, structIte, or arrayIte,
--   depending on the type.
baseTypeIte :: IsExprBuilder sym => sym -> Pred sym -> SymExpr sym tp -> SymExpr sym tp -> IO (SymExpr sym tp)

-- | Given a symbolic expression, annotate it with a unique identifier that
--   can be used to maintain a connection with the given term. The
--   SymAnnotation is intended to be used as the key in a hash table
--   or map to additional data can be maintained alongside the terms. The
--   returned SymExpr has the same semantics as the argument, but
--   has embedded in it the SymAnnotation value so that it can be
--   used later during term traversals.
--   
--   Note, the returned annotation is not necessarily fresh; if an
--   already-annotated term is passed in, the same annotation value will be
--   returned.
annotateTerm :: IsExprBuilder sym => sym -> SymExpr sym tp -> IO (SymAnnotation sym tp, SymExpr sym tp)

-- | Project an annotation from an expression
--   
--   It should be the case that using getAnnotation on a term
--   returned by annotateTerm returns the same annotation that
--   annotateTerm did.
getAnnotation :: IsExprBuilder sym => sym -> SymExpr sym tp -> Maybe (SymAnnotation sym tp)

-- | Project the original, unannotated term from an annotated term. This
--   returns Nothing for terms that do not have annotations.
getUnannotatedTerm :: IsExprBuilder sym => sym -> SymExpr sym tp -> Maybe (SymExpr sym tp)

-- | Constant true predicate
truePred :: IsExprBuilder sym => sym -> Pred sym

-- | Constant false predicate
falsePred :: IsExprBuilder sym => sym -> Pred sym

-- | Boolean negation
notPred :: IsExprBuilder sym => sym -> Pred sym -> IO (Pred sym)

-- | Boolean conjunction
andPred :: IsExprBuilder sym => sym -> Pred sym -> Pred sym -> IO (Pred sym)

-- | Boolean disjunction
orPred :: IsExprBuilder sym => sym -> Pred sym -> Pred sym -> IO (Pred sym)

-- | Boolean implication
impliesPred :: IsExprBuilder sym => sym -> Pred sym -> Pred sym -> IO (Pred sym)

-- | Exclusive-or operation
xorPred :: IsExprBuilder sym => sym -> Pred sym -> Pred sym -> IO (Pred sym)

-- | Equality of boolean values
eqPred :: IsExprBuilder sym => sym -> Pred sym -> Pred sym -> IO (Pred sym)

-- | If-then-else on a predicate.
itePred :: IsExprBuilder sym => sym -> Pred sym -> Pred sym -> Pred sym -> IO (Pred sym)

-- | Create an integer literal.
intLit :: IsExprBuilder sym => sym -> Integer -> IO (SymInteger sym)

-- | Negate an integer.
intNeg :: IsExprBuilder sym => sym -> SymInteger sym -> IO (SymInteger sym)

-- | Add two integers.
intAdd :: IsExprBuilder sym => sym -> SymInteger sym -> SymInteger sym -> IO (SymInteger sym)

-- | Subtract one integer from another.
intSub :: IsExprBuilder sym => sym -> SymInteger sym -> SymInteger sym -> IO (SymInteger sym)

-- | Multiply one integer by another.
intMul :: IsExprBuilder sym => sym -> SymInteger sym -> SymInteger sym -> IO (SymInteger sym)

-- | Return the minimum value of two integers.
intMin :: IsExprBuilder sym => sym -> SymInteger sym -> SymInteger sym -> IO (SymInteger sym)

-- | Return the maximum value of two integers.
intMax :: IsExprBuilder sym => sym -> SymInteger sym -> SymInteger sym -> IO (SymInteger sym)

-- | If-then-else applied to integers.
intIte :: IsExprBuilder sym => sym -> Pred sym -> SymInteger sym -> SymInteger sym -> IO (SymInteger sym)

-- | Integer equality.
intEq :: IsExprBuilder sym => sym -> SymInteger sym -> SymInteger sym -> IO (Pred sym)

-- | Integer less-than-or-equal.
intLe :: IsExprBuilder sym => sym -> SymInteger sym -> SymInteger sym -> IO (Pred sym)

-- | Integer less-than.
intLt :: IsExprBuilder sym => sym -> SymInteger sym -> SymInteger sym -> IO (Pred sym)

-- | Compute the absolute value of an integer.
intAbs :: IsExprBuilder sym => sym -> SymInteger sym -> IO (SymInteger sym)

-- | intDiv x y computes the integer division of x by
--   y. This division is interpreted the same way as the SMT-Lib
--   integer theory, which states that div and mod are
--   the unique Euclidean division operations satisfying the following for
--   all y /= 0:
--   
--   
--   
- 
y * (div x y) + (mod x y) == x

--   
- 
 0 <= mod x y < abs y

--   
--   
--   The value of intDiv x y is undefined when y = 0.
--   
--   Integer division requires nonlinear support whenever the divisor is
--   not a constant.
--   
--   Note: div x y is floor (x/y) when y is
--   positive (regardless of sign of x) and ceiling (x/y)
--   when y is negative. This is neither of the more common "round
--   toward zero" nor "round toward -inf" definitions.
--   
--   Some useful theorems that are true of this division/modulus pair:
--   
--   
--   
- 
mod x y == mod x (- y) == mod x (abs y)

--   
- 
div x (-y) == -(div x y)

--   
intDiv :: IsExprBuilder sym => sym -> SymInteger sym -> SymInteger sym -> IO (SymInteger sym)

-- | intMod x y computes the integer modulus of x by
--   y. See intDiv for more details.
--   
--   The value of intMod x y is undefined when y = 0.
--   
--   Integer modulus requires nonlinear support whenever the divisor is not
--   a constant.
intMod :: IsExprBuilder sym => sym -> SymInteger sym -> SymInteger sym -> IO (SymInteger sym)

-- | intDivisible x k is true whenever x is an integer
--   divisible by the known natural number k. In other words
--   `divisible x k` holds if there exists an integer z such that
--   `x = k*z`.
intDivisible :: IsExprBuilder sym => sym -> SymInteger sym -> Natural -> IO (Pred sym)

-- | Create a bitvector with the given width and value.
bvLit :: (IsExprBuilder sym, 1 <= w) => sym -> NatRepr w -> BV w -> IO (SymBV sym w)

-- | Concatenate two bitvectors.
bvConcat :: (IsExprBuilder sym, 1 <= u, 1 <= v) => sym -> SymBV sym u -> SymBV sym v -> IO (SymBV sym (u + v))

-- | Select a subsequence from a bitvector.
bvSelect :: forall idx n w. (IsExprBuilder sym, 1 <= n, (idx + n) <= w) => sym -> NatRepr idx -> NatRepr n -> SymBV sym w -> IO (SymBV sym n)

-- | 2's complement negation.
bvNeg :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (SymBV sym w)

-- | Add two bitvectors.
bvAdd :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Subtract one bitvector from another.
bvSub :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Multiply one bitvector by another.
bvMul :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Unsigned bitvector division.
--   
--   The result of bvUdiv x y is undefined when y is
--   zero, but is otherwise equal to floor( x / y ).
bvUdiv :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Unsigned bitvector remainder.
--   
--   The result of bvUrem x y is undefined when y is
--   zero, but is otherwise equal to x - (bvUdiv x y) * y.
bvUrem :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Signed bitvector division. The result is truncated to zero.
--   
--   The result of bvSdiv x y is undefined when y is
--   zero, but is equal to floor(x/y) when x and
--   y have the same sign, and equal to ceiling(x/y) when
--   x and y have opposite signs.
--   
--   NOTE! However, that there is a corner case when dividing
--   MIN_INT by -1, in which case an overflow condition
--   occurs, and the result is instead MIN_INT.
bvSdiv :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Signed bitvector remainder.
--   
--   The result of bvSrem x y is undefined when y is
--   zero, but is otherwise equal to x - (bvSdiv x y) * y.
bvSrem :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Returns true if the corresponding bit in the bitvector is set.
testBitBV :: (IsExprBuilder sym, 1 <= w) => sym -> Natural -> SymBV sym w -> IO (Pred sym)

-- | Return true if bitvector is negative.
bvIsNeg :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (Pred sym)

-- | If-then-else applied to bitvectors.
bvIte :: (IsExprBuilder sym, 1 <= w) => sym -> Pred sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Return true if bitvectors are equal.
bvEq :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym)

-- | Return true if bitvectors are distinct.
bvNe :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym)

-- | Unsigned less-than.
bvUlt :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym)

-- | Unsigned less-than-or-equal.
bvUle :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym)

-- | Unsigned greater-than-or-equal.
bvUge :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym)

-- | Unsigned greater-than.
bvUgt :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym)

-- | Signed less-than.
bvSlt :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym)

-- | Signed greater-than.
bvSgt :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym)

-- | Signed less-than-or-equal.
bvSle :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym)

-- | Signed greater-than-or-equal.
bvSge :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym)

-- | returns true if the given bitvector is non-zero.
bvIsNonzero :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (Pred sym)

-- | Left shift. The shift amount is treated as an unsigned value.
bvShl :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Logical right shift. The shift amount is treated as an unsigned value.
bvLshr :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Arithmetic right shift. The shift amount is treated as an unsigned
--   value.
bvAshr :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Rotate left. The rotate amount is treated as an unsigned value.
bvRol :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Rotate right. The rotate amount is treated as an unsigned value.
bvRor :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Zero-extend a bitvector.
bvZext :: (IsExprBuilder sym, 1 <= u, (u + 1) <= r) => sym -> NatRepr r -> SymBV sym u -> IO (SymBV sym r)

-- | Sign-extend a bitvector.
bvSext :: (IsExprBuilder sym, 1 <= u, (u + 1) <= r) => sym -> NatRepr r -> SymBV sym u -> IO (SymBV sym r)

-- | Truncate a bitvector.
bvTrunc :: (IsExprBuilder sym, 1 <= r, (r + 1) <= w) => sym -> NatRepr r -> SymBV sym w -> IO (SymBV sym r)

-- | Bitwise logical and.
bvAndBits :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Bitwise logical or.
bvOrBits :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Bitwise logical exclusive or.
bvXorBits :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Bitwise complement.
bvNotBits :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (SymBV sym w)

-- | bvSet sym v i p returns a bitvector v' where bit
--   i of v' is set to p, and the bits at the
--   other indices are the same as in v.
bvSet :: forall w. (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> Natural -> Pred sym -> IO (SymBV sym w)

-- | bvFill sym w p returns a bitvector w-bits long where
--   every bit is given by the boolean value of p.
bvFill :: forall w. (IsExprBuilder sym, 1 <= w) => sym -> NatRepr w -> Pred sym -> IO (SymBV sym w)

-- | Return the bitvector of the desired width with all 0 bits; this is the
--   minimum unsigned integer.
minUnsignedBV :: (IsExprBuilder sym, 1 <= w) => sym -> NatRepr w -> IO (SymBV sym w)

-- | Return the bitvector of the desired width with all bits set; this is
--   the maximum unsigned integer.
maxUnsignedBV :: (IsExprBuilder sym, 1 <= w) => sym -> NatRepr w -> IO (SymBV sym w)

-- | Return the bitvector representing the largest 2's complement signed
--   integer of the given width. This consists of all bits set except the
--   MSB.
maxSignedBV :: (IsExprBuilder sym, 1 <= w) => sym -> NatRepr w -> IO (SymBV sym w)

-- | Return the bitvector representing the smallest 2's complement signed
--   integer of the given width. This consists of all 0 bits except the
--   MSB, which is set.
minSignedBV :: (IsExprBuilder sym, 1 <= w) => sym -> NatRepr w -> IO (SymBV sym w)

-- | Return the number of 1 bits in the input.
bvPopcount :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (SymBV sym w)

-- | Return the number of consecutive 0 bits in the input, starting from
--   the most significant bit position. If the input is zero, all bits are
--   counted as leading.
bvCountLeadingZeros :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (SymBV sym w)

-- | Return the number of consecutive 0 bits in the input, starting from
--   the least significant bit position. If the input is zero, all bits are
--   counted as leading.
bvCountTrailingZeros :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (SymBV sym w)

-- | Unsigned add with overflow bit.
addUnsignedOF :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym, SymBV sym w)

-- | Signed add with overflow bit. Overflow is true if positive + positive
--   = negative, or if negative + negative = positive.
addSignedOF :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym, SymBV sym w)

-- | Unsigned subtract with overflow bit. Overflow is true if x < y.
subUnsignedOF :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym, SymBV sym w)

-- | Signed subtract with overflow bit. Overflow is true if positive -
--   negative = negative, or if negative - positive = positive.
subSignedOF :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym, SymBV sym w)

-- | Compute the carry-less multiply of the two input bitvectors. This
--   operation is essentially the same as a standard multiply, except that
--   the partial addends are simply XOR'd together instead of using a
--   standard adder. This operation is useful for computing on GF(2^n)
--   polynomials.
carrylessMultiply :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym (w + w))

-- | unsignedWideMultiplyBV sym x y multiplies two unsigned
--   w bit numbers x and y.
--   
--   It returns a pair containing the top w bits as the first
--   element, and the lower w bits as the second element.
unsignedWideMultiplyBV :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w, SymBV sym w)

-- | Compute the unsigned multiply of two values with overflow bit.
mulUnsignedOF :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym, SymBV sym w)

-- | signedWideMultiplyBV sym x y multiplies two signed w
--   bit numbers x and y.
--   
--   It returns a pair containing the top w bits as the first
--   element, and the lower w bits as the second element.
signedWideMultiplyBV :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w, SymBV sym w)

-- | Compute the signed multiply of two values with overflow bit.
mulSignedOF :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (Pred sym, SymBV sym w)

-- | Create a struct from an assignment of expressions.
mkStruct :: IsExprBuilder sym => sym -> Assignment (SymExpr sym) flds -> IO (SymStruct sym flds)

-- | Get the value of a specific field in a struct.
structField :: IsExprBuilder sym => sym -> SymStruct sym flds -> Index flds tp -> IO (SymExpr sym tp)

-- | Check if two structs are equal.
structEq :: forall flds. IsExprBuilder sym => sym -> SymStruct sym flds -> SymStruct sym flds -> IO (Pred sym)

-- | Take the if-then-else of two structures.
structIte :: IsExprBuilder sym => sym -> Pred sym -> SymStruct sym flds -> SymStruct sym flds -> IO (SymStruct sym flds)

-- | Create an array where each element has the same value.
constantArray :: IsExprBuilder sym => sym -> Assignment BaseTypeRepr (idx ::> tp) -> SymExpr sym b -> IO (SymArray sym (idx ::> tp) b)

-- | Create an array from an arbitrary symbolic function.
--   
--   Arrays created this way can typically not be compared for equality
--   when provided to backend solvers.
arrayFromFn :: IsExprBuilder sym => sym -> SymFn sym (idx ::> itp) ret -> IO (SymArray sym (idx ::> itp) ret)

-- | Create an array by mapping a function over one or more existing
--   arrays.
arrayMap :: IsExprBuilder sym => sym -> SymFn sym (ctx ::> d) r -> Assignment (ArrayResultWrapper (SymExpr sym) (idx ::> itp)) (ctx ::> d) -> IO (SymArray sym (idx ::> itp) r)

-- | Update an array at a specific location.
arrayUpdate :: IsExprBuilder sym => sym -> SymArray sym (idx ::> tp) b -> Assignment (SymExpr sym) (idx ::> tp) -> SymExpr sym b -> IO (SymArray sym (idx ::> tp) b)

-- | Return element in array.
arrayLookup :: IsExprBuilder sym => sym -> SymArray sym (idx ::> tp) b -> Assignment (SymExpr sym) (idx ::> tp) -> IO (SymExpr sym b)

-- | Copy elements from the source array to the destination array.
--   
--   arrayCopy sym dest_arr dest_idx src_arr src_idx len
--   copies the elements from src_arr at indices [src_idx ..
--   (src_idx + len - 1)] into dest_arr at indices
--   [dest_idx .. (dest_idx + len - 1)].
--   
--   The result is undefined if either dest_idx + len or
--   src_idx + len wraps around.
arrayCopy :: (IsExprBuilder sym, 1 <= w) => sym -> SymArray sym (SingleCtx (BaseBVType w)) a -> SymBV sym w -> SymArray sym (SingleCtx (BaseBVType w)) a -> SymBV sym w -> SymBV sym w -> IO (SymArray sym (SingleCtx (BaseBVType w)) a)

-- | Set elements of the given array.
--   
--   arraySet sym arr idx val len sets the elements of
--   arr at indices [idx .. (idx + len - 1)] to
--   val.
--   
--   The result is undefined if idx + len wraps around.
arraySet :: (IsExprBuilder sym, 1 <= w) => sym -> SymArray sym (SingleCtx (BaseBVType w)) a -> SymBV sym w -> SymExpr sym a -> SymBV sym w -> IO (SymArray sym (SingleCtx (BaseBVType w)) a)

-- | Check whether the lhs array and rhs array are equal at a range of
--   indices.
--   
--   arrayRangeEq sym lhs_arr lhs_idx rhs_arr rhs_idx len
--   checks whether the elements of lhs_arr at indices
--   [lhs_idx .. (lhs_idx + len - 1)] and the elements of
--   rhs_arr at indices [rhs_idx .. (rhs_idx + len - 1)]
--   are equal.
--   
--   The result is undefined if either lhs_idx + len or
--   rhs_idx + len wraps around.
arrayRangeEq :: (IsExprBuilder sym, 1 <= w) => sym -> SymArray sym (SingleCtx (BaseBVType w)) a -> SymBV sym w -> SymArray sym (SingleCtx (BaseBVType w)) a -> SymBV sym w -> SymBV sym w -> IO (Pred sym)

-- | Create an array from a map of concrete indices to values.
--   
--   This is implemented, but designed to be overridden for efficiency.
arrayFromMap :: IsExprBuilder sym => sym -> Assignment BaseTypeRepr (idx ::> itp) -> ArrayUpdateMap (SymExpr sym) (idx ::> itp) tp -> SymExpr sym tp -> IO (SymArray sym (idx ::> itp) tp)

-- | Update an array at specific concrete indices.
--   
--   This is implemented, but designed to be overriden for efficiency.
arrayUpdateAtIdxLits :: IsExprBuilder sym => sym -> ArrayUpdateMap (SymExpr sym) (idx ::> itp) tp -> SymArray sym (idx ::> itp) tp -> IO (SymArray sym (idx ::> itp) tp)

-- | If-then-else applied to arrays.
arrayIte :: IsExprBuilder sym => sym -> Pred sym -> SymArray sym idx b -> SymArray sym idx b -> IO (SymArray sym idx b)

-- | Return true if two arrays are equal.
--   
--   Note that in the backend, arrays do not have a fixed number of
--   elements, so this equality requires that arrays are equal on all
--   elements.
arrayEq :: IsExprBuilder sym => sym -> SymArray sym idx b -> SymArray sym idx b -> IO (Pred sym)

-- | Return true if all entries in the array are true.
allTrueEntries :: IsExprBuilder sym => sym -> SymArray sym idx BaseBoolType -> IO (Pred sym)

-- | Return true if the array has the value true at every index satisfying
--   the given predicate.
arrayTrueOnEntries :: IsExprBuilder sym => sym -> SymFn sym (idx ::> itp) BaseBoolType -> SymArray sym (idx ::> itp) BaseBoolType -> IO (Pred sym)

-- | Convert an integer to a real number.
integerToReal :: IsExprBuilder sym => sym -> SymInteger sym -> IO (SymReal sym)

-- | Return the unsigned value of the given bitvector as an integer.
bvToInteger :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (SymInteger sym)

-- | Return the signed value of the given bitvector as an integer.
sbvToInteger :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (SymInteger sym)

-- | Return 1 if the predicate is true; 0 otherwise.
predToBV :: (IsExprBuilder sym, 1 <= w) => sym -> Pred sym -> NatRepr w -> IO (SymBV sym w)

-- | Convert an unsigned bitvector to a real number.
uintToReal :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (SymReal sym)

-- | Convert an signed bitvector to a real number.
sbvToReal :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (SymReal sym)

-- | Round a real number to an integer.
--   
--   Numbers are rounded to the nearest integer, with rounding away from
--   zero when two integers are equidistant (e.g., 1.5 rounds to 2).
realRound :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymInteger sym)

-- | Round a real number to an integer.
--   
--   Numbers are rounded to the nearest integer, with rounding toward even
--   values when two integers are equidistant (e.g., 2.5 rounds to 2).
realRoundEven :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymInteger sym)

-- | Round down to the nearest integer that is at most this value.
realFloor :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymInteger sym)

-- | Round up to the nearest integer that is at least this value.
realCeil :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymInteger sym)

-- | Round toward zero. This is floor(x) when x is positive and
--   celing(x) when x is negative.
realTrunc :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymInteger sym)

-- | Convert an integer to a bitvector. The result is the unique bitvector
--   whose value (signed or unsigned) is congruent to the input integer,
--   modulo 2^w.
--   
--   This operation has the following properties:
--   
--   
--   
- 
bvToInteger (integerToBv x w) == mod x (2^w)

--   
- bvToInteger (integerToBV x w) == x when 0 <= x
--   < 2^w.
--   
- 
sbvToInteger (integerToBV x w) == mod (x + 2^(w-1)) (2^w) -
--   2^(w-1)

--   
- sbvToInteger (integerToBV x w) == x when -2^(w-1)
--   <= x < 2^(w-1)
--   
- integerToBV (bvToInteger y) w == y when y is a
--   SymBV sym w
--   
- integerToBV (sbvToInteger y) w == y when y is a
--   SymBV sym w
--   
integerToBV :: (IsExprBuilder sym, 1 <= w) => sym -> SymInteger sym -> NatRepr w -> IO (SymBV sym w)

-- | Convert a real number to an integer.
--   
--   The result is undefined if the given real number does not represent an
--   integer.
realToInteger :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymInteger sym)

-- | Convert a real number to an unsigned bitvector.
--   
--   Numbers are rounded to the nearest representable number, with rounding
--   away from zero when two integers are equidistant (e.g., 1.5 rounds to
--   2). When the real is negative the result is zero.
realToBV :: (IsExprBuilder sym, 1 <= w) => sym -> SymReal sym -> NatRepr w -> IO (SymBV sym w)

-- | Convert a real number to a signed bitvector.
--   
--   Numbers are rounded to the nearest representable number, with rounding
--   away from zero when two integers are equidistant (e.g., 1.5 rounds to
--   2).
realToSBV :: (IsExprBuilder sym, 1 <= w) => sym -> SymReal sym -> NatRepr w -> IO (SymBV sym w)

-- | Convert an integer to the nearest signed bitvector.
--   
--   Numbers are rounded to the nearest representable number.
clampedIntToSBV :: (IsExprBuilder sym, 1 <= w) => sym -> SymInteger sym -> NatRepr w -> IO (SymBV sym w)

-- | Convert an integer to the nearest unsigned bitvector.
--   
--   Numbers are rounded to the nearest representable number.
clampedIntToBV :: (IsExprBuilder sym, 1 <= w) => sym -> SymInteger sym -> NatRepr w -> IO (SymBV sym w)

-- | Convert a signed bitvector to the nearest signed bitvector with the
--   given width. If the resulting width is smaller, this clamps the value
--   to min-int or max-int when necessary.
intSetWidth :: (IsExprBuilder sym, 1 <= m, 1 <= n) => sym -> SymBV sym m -> NatRepr n -> IO (SymBV sym n)

-- | Convert an unsigned bitvector to the nearest unsigned bitvector with
--   the given width (clamp on overflow).
uintSetWidth :: (IsExprBuilder sym, 1 <= m, 1 <= n) => sym -> SymBV sym m -> NatRepr n -> IO (SymBV sym n)

-- | Convert an signed bitvector to the nearest unsigned bitvector with the
--   given width (clamp on overflow).
intToUInt :: (IsExprBuilder sym, 1 <= m, 1 <= n) => sym -> SymBV sym m -> NatRepr n -> IO (SymBV sym n)

-- | Convert an unsigned bitvector to the nearest signed bitvector with the
--   given width (clamp on overflow).
uintToInt :: (IsExprBuilder sym, 1 <= m, 1 <= n) => sym -> SymBV sym m -> NatRepr n -> IO (SymBV sym n)

-- | Create an empty string literal
stringEmpty :: IsExprBuilder sym => sym -> StringInfoRepr si -> IO (SymString sym si)

-- | Create a concrete string literal
stringLit :: IsExprBuilder sym => sym -> StringLiteral si -> IO (SymString sym si)

-- | Check the equality of two strings
stringEq :: IsExprBuilder sym => sym -> SymString sym si -> SymString sym si -> IO (Pred sym)

-- | If-then-else on strings
stringIte :: IsExprBuilder sym => sym -> Pred sym -> SymString sym si -> SymString sym si -> IO (SymString sym si)

-- | Concatenate two strings
stringConcat :: IsExprBuilder sym => sym -> SymString sym si -> SymString sym si -> IO (SymString sym si)

-- | Test if the first string contains the second string as a substring
stringContains :: IsExprBuilder sym => sym -> SymString sym si -> SymString sym si -> IO (Pred sym)

-- | Test if the first string is a prefix of the second string
stringIsPrefixOf :: IsExprBuilder sym => sym -> SymString sym si -> SymString sym si -> IO (Pred sym)

-- | Test if the first string is a suffix of the second string
stringIsSuffixOf :: IsExprBuilder sym => sym -> SymString sym si -> SymString sym si -> IO (Pred sym)

-- | Return the first position at which the second string can be found as a
--   substring in the first string, starting from the given index. If no
--   such position exists, return a negative value. If the given index is
--   out of bounds for the string, return a negative value.
stringIndexOf :: IsExprBuilder sym => sym -> SymString sym si -> SymString sym si -> SymInteger sym -> IO (SymInteger sym)

-- | Compute the length of a string
stringLength :: IsExprBuilder sym => sym -> SymString sym si -> IO (SymInteger sym)

-- | stringSubstring s off len evaluates to the longest substring
--   of s of length at most len starting at position
--   off. It evaluates to the empty string if len is
--   negative or off is not in the interval [0,l-1] where
--   l is the length of s.
stringSubstring :: IsExprBuilder sym => sym -> SymString sym si -> SymInteger sym -> SymInteger sym -> IO (SymString sym si)

-- | Return real number 0.
realZero :: IsExprBuilder sym => sym -> SymReal sym

-- | Create a constant real literal.
realLit :: IsExprBuilder sym => sym -> Rational -> IO (SymReal sym)

-- | Make a real literal from a scientific value. May be overridden if we
--   want to avoid the overhead of converting scientific value to rational.
sciLit :: IsExprBuilder sym => sym -> Scientific -> IO (SymReal sym)

-- | Check equality of two real numbers.
realEq :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (Pred sym)

-- | Check non-equality of two real numbers.
realNe :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (Pred sym)

-- | Check <= on two real numbers.
realLe :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (Pred sym)

-- | Check < on two real numbers.
realLt :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (Pred sym)

-- | Check >= on two real numbers.
realGe :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (Pred sym)

-- | Check > on two real numbers.
realGt :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (Pred sym)

-- | If-then-else on real numbers.
realIte :: IsExprBuilder sym => sym -> Pred sym -> SymReal sym -> SymReal sym -> IO (SymReal sym)

-- | Return the minimum of two real numbers.
realMin :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (SymReal sym)

-- | Return the maxmimum of two real numbers.
realMax :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (SymReal sym)

-- | Negate a real number.
realNeg :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymReal sym)

-- | Add two real numbers.
realAdd :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (SymReal sym)

-- | Multiply two real numbers.
realMul :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (SymReal sym)

-- | Subtract one real from another.
realSub :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (SymReal sym)

-- | realSq sym x returns x * x.
realSq :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymReal sym)

-- | realDiv sym x y returns term equivalent to x/y.
--   
--   The result is undefined when y is zero.
realDiv :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (SymReal sym)

-- | realMod x y returns the value of x - y * floor(x /
--   y) when y is not zero and x when y is
--   zero.
realMod :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (SymReal sym)

-- | Predicate that holds if the real number is an exact integer.
isInteger :: IsExprBuilder sym => sym -> SymReal sym -> IO (Pred sym)

-- | Return true if the real is non-negative.
realIsNonNeg :: IsExprBuilder sym => sym -> SymReal sym -> IO (Pred sym)

-- | realSqrt sym x returns sqrt(x). Result is undefined if
--   x is negative.
realSqrt :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymReal sym)

-- | Return value denoting pi.
realPi :: IsExprBuilder sym => sym -> IO (SymReal sym)

-- | Natural logarithm. realLog x is undefined for x <=
--   0.
realLog :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymReal sym)

-- | Natural exponentiation
realExp :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymReal sym)

-- | Sine trig function
realSin :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymReal sym)

-- | Cosine trig function
realCos :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymReal sym)

-- | Tangent trig function. realTan x is undefined when cos x
--   = 0, i.e., when x = pi/2 + k*pi for some integer
--   k.
realTan :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymReal sym)

-- | Hyperbolic sine
realSinh :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymReal sym)

-- | Hyperbolic cosine
realCosh :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymReal sym)

-- | Hyperbolic tangent
realTanh :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymReal sym)

-- | Return absolute value of the real number.
realAbs :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymReal sym)

-- | realHypot x y returns sqrt(x^2 + y^2).
realHypot :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (SymReal sym)

-- | realAtan2 sym y x returns the arctangent of y/x with
--   a range of -pi to pi; this corresponds to the angle
--   between the positive x-axis and the line from the origin
--   (x,y).
--   
--   When x is 0 this returns pi/2 * sgn y.
--   
--   When x and y are both zero, this function is
--   undefined.
realAtan2 :: IsExprBuilder sym => sym -> SymReal sym -> SymReal sym -> IO (SymReal sym)

-- | Apply a special function to real arguments
realSpecialFunction :: IsExprBuilder sym => sym -> SpecialFunction args -> Assignment (SpecialFnArg (SymExpr sym) BaseRealType) args -> IO (SymReal sym)

-- | Access a 0-arity special function constant
realSpecialFunction0 :: IsExprBuilder sym => sym -> SpecialFunction EmptyCtx -> IO (SymReal sym)

-- | Apply a 1-argument special function
realSpecialFunction1 :: IsExprBuilder sym => sym -> SpecialFunction (EmptyCtx ::> R) -> SymReal sym -> IO (SymReal sym)

-- | Apply a 2-argument special function
realSpecialFunction2 :: IsExprBuilder sym => sym -> SpecialFunction ((EmptyCtx ::> R) ::> R) -> SymReal sym -> SymReal sym -> IO (SymReal sym)

-- | Return floating point number +0.
floatPZero :: IsExprBuilder sym => sym -> FloatPrecisionRepr fpp -> IO (SymFloat sym fpp)

-- | Return floating point number -0.
floatNZero :: IsExprBuilder sym => sym -> FloatPrecisionRepr fpp -> IO (SymFloat sym fpp)

-- | Return floating point NaN.
floatNaN :: IsExprBuilder sym => sym -> FloatPrecisionRepr fpp -> IO (SymFloat sym fpp)

-- | Return floating point +infinity.
floatPInf :: IsExprBuilder sym => sym -> FloatPrecisionRepr fpp -> IO (SymFloat sym fpp)

-- | Return floating point -infinity.
floatNInf :: IsExprBuilder sym => sym -> FloatPrecisionRepr fpp -> IO (SymFloat sym fpp)

-- | Create a floating point literal from a rational literal. The rational
--   value will be rounded if necessary using the "round to nearest even"
--   rounding mode.
floatLitRational :: IsExprBuilder sym => sym -> FloatPrecisionRepr fpp -> Rational -> IO (SymFloat sym fpp)

-- | Create a floating point literal from a BigFloat value.
floatLit :: IsExprBuilder sym => sym -> FloatPrecisionRepr fpp -> BigFloat -> IO (SymFloat sym fpp)

-- | Negate a floating point number.
floatNeg :: IsExprBuilder sym => sym -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Return the absolute value of a floating point number.
floatAbs :: IsExprBuilder sym => sym -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Compute the square root of a floating point number.
floatSqrt :: IsExprBuilder sym => sym -> RoundingMode -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Add two floating point numbers.
floatAdd :: IsExprBuilder sym => sym -> RoundingMode -> SymFloat sym fpp -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Subtract two floating point numbers.
floatSub :: IsExprBuilder sym => sym -> RoundingMode -> SymFloat sym fpp -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Multiply two floating point numbers.
floatMul :: IsExprBuilder sym => sym -> RoundingMode -> SymFloat sym fpp -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Divide two floating point numbers.
floatDiv :: IsExprBuilder sym => sym -> RoundingMode -> SymFloat sym fpp -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Compute the reminder: x - y * n, where n in Z is
--   nearest to x / y (breaking ties to even values of
--   n).
floatRem :: IsExprBuilder sym => sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Return the minimum of two floating point numbers. If one argument is
--   NaN, return the other argument. If the arguments are equal when
--   compared as floating-point values, one of the two will be returned,
--   but it is unspecified which; this underspecification can (only) be
--   observed with zeros of different signs.
floatMin :: IsExprBuilder sym => sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Return the maximum of two floating point numbers. If one argument is
--   NaN, return the other argument. If the arguments are equal when
--   compared as floating-point values, one of the two will be returned,
--   but it is unspecified which; this underspecification can (only) be
--   observed with zeros of different signs.
floatMax :: IsExprBuilder sym => sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Compute the fused multiplication and addition: (x * y) + z.
floatFMA :: IsExprBuilder sym => sym -> RoundingMode -> SymFloat sym fpp -> SymFloat sym fpp -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Check logical equality of two floating point numbers.
--   
--   NOTE! This does NOT accurately represent the equality test on floating
--   point values typically found in programming languages. See
--   floatFpEq instead.
floatEq :: IsExprBuilder sym => sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (Pred sym)

-- | Check logical non-equality of two floating point numbers.
--   
--   NOTE! This does NOT accurately represent the non-equality test on
--   floating point values typically found in programming languages. See
--   floatFpEq instead.
floatNe :: IsExprBuilder sym => sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (Pred sym)

-- | Check IEEE-754 equality of two floating point numbers.
--   
--   NOTE! This test returns false if either value is NaN; in
--   particular NaN is not equal to itself! Moreover, positive and
--   negative 0 will compare equal, despite having different bit patterns.
--   
--   This test is most appropriate for interpreting the equality tests of
--   typical languages using floating point. Moreover, not-equal tests are
--   usually the negation of this test, rather than the floatFpNe
--   test below.
floatFpEq :: IsExprBuilder sym => sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (Pred sym)

-- | Check IEEE-754 apartness of two floating point numbers.
--   
--   NOTE! This test returns false if either value is NaN; in
--   particular NaN is not apart from any other value! Moreover,
--   positive and negative 0 will not compare apart, despite having
--   different bit patterns. Note that x is apart from y
--   iff x < y or x > y.
--   
--   This test usually does NOT correspond to the not-equal tests found in
--   programming languages. Instead, one generally takes the logical
--   negation of the floatFpEq test.
floatFpApart :: IsExprBuilder sym => sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (Pred sym)

-- | Check if two floating point numbers are "unordered". This happens
--   precicely when one or both of the inputs is NaN.
floatFpUnordered :: IsExprBuilder sym => sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (Pred sym)

-- | Check IEEE-754 <= on two floating point numbers.
--   
--   NOTE! This test returns false if either value is NaN; in
--   particular NaN is not less-than-or-equal-to any other value!
--   Moreover, positive and negative 0 are considered equal, despite having
--   different bit patterns.
floatLe :: IsExprBuilder sym => sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (Pred sym)

-- | Check IEEE-754 < on two floating point numbers.
--   
--   NOTE! This test returns false if either value is NaN; in
--   particular NaN is not less-than any other value! Moreover,
--   positive and negative 0 are considered equal, despite having different
--   bit patterns.
floatLt :: IsExprBuilder sym => sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (Pred sym)

-- | Check IEEE-754 >= on two floating point numbers.
--   
--   NOTE! This test returns false if either value is NaN; in
--   particular NaN is not greater-than-or-equal-to any other
--   value! Moreover, positive and negative 0 are considered equal, despite
--   having different bit patterns.
floatGe :: IsExprBuilder sym => sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (Pred sym)

-- | Check IEEE-754 > on two floating point numbers.
--   
--   NOTE! This test returns false if either value is NaN; in
--   particular NaN is not greater-than any other value! Moreover,
--   positive and negative 0 are considered equal, despite having different
--   bit patterns.
floatGt :: IsExprBuilder sym => sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (Pred sym)

-- | Test if a floating-point value is NaN.
floatIsNaN :: IsExprBuilder sym => sym -> SymFloat sym fpp -> IO (Pred sym)

-- | Test if a floating-point value is (positive or negative) infinity.
floatIsInf :: IsExprBuilder sym => sym -> SymFloat sym fpp -> IO (Pred sym)

-- | Test if a floating-point value is (positive or negative) zero.
floatIsZero :: IsExprBuilder sym => sym -> SymFloat sym fpp -> IO (Pred sym)

-- | Test if a floating-point value is positive. NOTE! NaN is considered
--   neither positive nor negative.
floatIsPos :: IsExprBuilder sym => sym -> SymFloat sym fpp -> IO (Pred sym)

-- | Test if a floating-point value is negative. NOTE! NaN is considered
--   neither positive nor negative.
floatIsNeg :: IsExprBuilder sym => sym -> SymFloat sym fpp -> IO (Pred sym)

-- | Test if a floating-point value is subnormal.
floatIsSubnorm :: IsExprBuilder sym => sym -> SymFloat sym fpp -> IO (Pred sym)

-- | Test if a floating-point value is normal.
floatIsNorm :: IsExprBuilder sym => sym -> SymFloat sym fpp -> IO (Pred sym)

-- | If-then-else on floating point numbers.
floatIte :: IsExprBuilder sym => sym -> Pred sym -> SymFloat sym fpp -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Change the precision of a floating point number.
floatCast :: IsExprBuilder sym => sym -> FloatPrecisionRepr fpp -> RoundingMode -> SymFloat sym fpp' -> IO (SymFloat sym fpp)

-- | Round a floating point number to an integral value.
floatRound :: IsExprBuilder sym => sym -> RoundingMode -> SymFloat sym fpp -> IO (SymFloat sym fpp)

-- | Convert from binary representation in IEEE 754-2008 format to floating
--   point.
floatFromBinary :: (IsExprBuilder sym, 2 <= eb, 2 <= sb) => sym -> FloatPrecisionRepr (FloatingPointPrecision eb sb) -> SymBV sym (eb + sb) -> IO (SymFloat sym (FloatingPointPrecision eb sb))

-- | Convert from floating point from to the binary representation in IEEE
--   754-2008 format.
--   
--   NOTE! NaN has multiple representations, i.e. all bit patterns
--   where the exponent is 0b1..1 and the significant is not
--   0b0..0. This functions returns the representation of positive
--   "quiet" NaN, i.e. the bit pattern where the sign is
--   0b0, the exponent is 0b1..1, and the significant is
--   0b10..0.
floatToBinary :: (IsExprBuilder sym, 2 <= eb, 2 <= sb) => sym -> SymFloat sym (FloatingPointPrecision eb sb) -> IO (SymBV sym (eb + sb))

-- | Convert a unsigned bitvector to a floating point number.
bvToFloat :: (IsExprBuilder sym, 1 <= w) => sym -> FloatPrecisionRepr fpp -> RoundingMode -> SymBV sym w -> IO (SymFloat sym fpp)

-- | Convert a signed bitvector to a floating point number.
sbvToFloat :: (IsExprBuilder sym, 1 <= w) => sym -> FloatPrecisionRepr fpp -> RoundingMode -> SymBV sym w -> IO (SymFloat sym fpp)

-- | Convert a real number to a floating point number.
realToFloat :: IsExprBuilder sym => sym -> FloatPrecisionRepr fpp -> RoundingMode -> SymReal sym -> IO (SymFloat sym fpp)

-- | Convert a floating point number to a unsigned bitvector.
floatToBV :: (IsExprBuilder sym, 1 <= w) => sym -> NatRepr w -> RoundingMode -> SymFloat sym fpp -> IO (SymBV sym w)

-- | Convert a floating point number to a signed bitvector.
floatToSBV :: (IsExprBuilder sym, 1 <= w) => sym -> NatRepr w -> RoundingMode -> SymFloat sym fpp -> IO (SymBV sym w)

-- | Convert a floating point number to a real number.
floatToReal :: IsExprBuilder sym => sym -> SymFloat sym fpp -> IO (SymReal sym)

-- | Apply a special function to floating-point arguments
floatSpecialFunction :: IsExprBuilder sym => sym -> FloatPrecisionRepr fpp -> SpecialFunction args -> Assignment (SpecialFnArg (SymExpr sym) (BaseFloatType fpp)) args -> IO (SymFloat sym fpp)

-- | Create a complex from cartesian coordinates.
mkComplex :: IsExprBuilder sym => sym -> Complex (SymReal sym) -> IO (SymCplx sym)

-- | getRealPart x returns the real part of x.
getRealPart :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymReal sym)

-- | getImagPart x returns the imaginary part of x.
getImagPart :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymReal sym)

-- | Convert a complex number into the real and imaginary part.
cplxGetParts :: IsExprBuilder sym => sym -> SymCplx sym -> IO (Complex (SymReal sym))

-- | Create a constant complex literal.
mkComplexLit :: IsExprBuilder sym => sym -> Complex Rational -> IO (SymCplx sym)

-- | Create a complex from a real value.
cplxFromReal :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymCplx sym)

-- | If-then-else on complex values.
cplxIte :: IsExprBuilder sym => sym -> Pred sym -> SymCplx sym -> SymCplx sym -> IO (SymCplx sym)

-- | Negate a complex number.
cplxNeg :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymCplx sym)

-- | Add two complex numbers together.
cplxAdd :: IsExprBuilder sym => sym -> SymCplx sym -> SymCplx sym -> IO (SymCplx sym)

-- | Subtract one complex number from another.
cplxSub :: IsExprBuilder sym => sym -> SymCplx sym -> SymCplx sym -> IO (SymCplx sym)

-- | Multiply two complex numbers together.
cplxMul :: IsExprBuilder sym => sym -> SymCplx sym -> SymCplx sym -> IO (SymCplx sym)

-- | Compute the magnitude of a complex number.
cplxMag :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymReal sym)

-- | Return the principal square root of a complex number.
cplxSqrt :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymCplx sym)

-- | Compute sine of a complex number.
cplxSin :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymCplx sym)

-- | Compute cosine of a complex number.
cplxCos :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymCplx sym)

-- | Compute tangent of a complex number. cplxTan x is undefined
--   when cplxCos x is 0, which occurs only along the
--   real line in the same conditions where realCos x is
--   0.
cplxTan :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymCplx sym)

-- | hypotCplx x y returns sqrt(abs(x)^2 + abs(y)^2).
cplxHypot :: IsExprBuilder sym => sym -> SymCplx sym -> SymCplx sym -> IO (SymCplx sym)

-- | roundCplx x rounds complex number to nearest integer. Numbers
--   with a fractional part of 0.5 are rounded away from 0. Imaginary and
--   real parts are rounded independently.
cplxRound :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymCplx sym)

-- | cplxFloor x rounds to nearest integer less than or equal to
--   x. Imaginary and real parts are rounded independently.
cplxFloor :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymCplx sym)

-- | cplxCeil x rounds to nearest integer greater than or equal to
--   x. Imaginary and real parts are rounded independently.
cplxCeil :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymCplx sym)

-- | conjReal x returns the complex conjugate of the input.
cplxConj :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymCplx sym)

-- | Returns exponential of a complex number.
cplxExp :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymCplx sym)

-- | Check equality of two complex numbers.
cplxEq :: IsExprBuilder sym => sym -> SymCplx sym -> SymCplx sym -> IO (Pred sym)

-- | Check non-equality of two complex numbers.
cplxNe :: IsExprBuilder sym => sym -> SymCplx sym -> SymCplx sym -> IO (Pred sym)

-- | This extends the interface for building expressions with operations
--   for creating new symbolic constants and functions.
class (IsExprBuilder sym, IsSymFn (SymFn sym), OrdF (SymExpr sym), OrdF (BoundVar sym)) => IsSymExprBuilder sym

-- | Create a fresh top-level uninterpreted constant.
freshConstant :: IsSymExprBuilder sym => sym -> SolverSymbol -> BaseTypeRepr tp -> IO (SymExpr sym tp)

-- | Create a fresh latch variable.
freshLatch :: IsSymExprBuilder sym => sym -> SolverSymbol -> BaseTypeRepr tp -> IO (SymExpr sym tp)

-- | Create a fresh bitvector value with optional lower and upper bounds
--   (which bound the unsigned value of the bitvector). If provided, the
--   bounds are inclusive. If inconsistent or out-of-range bounds are
--   given, an InvalidRange exception will be thrown.
freshBoundedBV :: (IsSymExprBuilder sym, 1 <= w) => sym -> SolverSymbol -> NatRepr w -> Maybe Natural -> Maybe Natural -> IO (SymBV sym w)

-- | Create a fresh bitvector value with optional lower and upper bounds
--   (which bound the signed value of the bitvector). If provided, the
--   bounds are inclusive. If inconsistent or out-of-range bounds are
--   given, an InvalidRange exception will be thrown.
freshBoundedSBV :: (IsSymExprBuilder sym, 1 <= w) => sym -> SolverSymbol -> NatRepr w -> Maybe Integer -> Maybe Integer -> IO (SymBV sym w)

-- | Create a fresh integer constant with optional lower and upper bounds.
--   If provided, the bounds are inclusive. If inconsistent bounds are
--   given, an InvalidRange exception will be thrown.
freshBoundedInt :: IsSymExprBuilder sym => sym -> SolverSymbol -> Maybe Integer -> Maybe Integer -> IO (SymInteger sym)

-- | Create a fresh real constant with optional lower and upper bounds. If
--   provided, the bounds are inclusive. If inconsistent bounds are given,
--   an InvalidRange exception will be thrown.
freshBoundedReal :: IsSymExprBuilder sym => sym -> SolverSymbol -> Maybe Rational -> Maybe Rational -> IO (SymReal sym)

-- | Return the set of uninterpreted constants in the given expression.
exprUninterpConstants :: IsSymExprBuilder sym => sym -> SymExpr sym tp -> Set (Some (BoundVar sym))

-- | Creates a bound variable.
--   
--   This will be treated as a free constant when appearing inside asserted
--   expressions. These are intended to be bound using quantifiers or
--   symbolic functions.
freshBoundVar :: IsSymExprBuilder sym => sym -> SolverSymbol -> BaseTypeRepr tp -> IO (BoundVar sym tp)

-- | Return an expression that references the bound variable.
varExpr :: IsSymExprBuilder sym => sym -> BoundVar sym tp -> SymExpr sym tp

-- | forallPred sym v e returns an expression that represents
--   forall v . e. Throws a user error if bound var has already
--   been used in a quantifier.
forallPred :: IsSymExprBuilder sym => sym -> BoundVar sym tp -> Pred sym -> IO (Pred sym)

-- | existsPred sym v e returns an expression that represents
--   exists v . e. Throws a user error if bound var has already
--   been used in a quantifier.
existsPred :: IsSymExprBuilder sym => sym -> BoundVar sym tp -> Pred sym -> IO (Pred sym)

-- | Return a function defined by an expression over bound variables. The
--   predicate argument allows the user to specify when an application of
--   the function should be unfolded and evaluated, e.g. to perform
--   constant folding.
definedFn :: IsSymExprBuilder sym => sym -> SolverSymbol -> Assignment (BoundVar sym) args -> SymExpr sym ret -> UnfoldPolicy -> IO (SymFn sym args ret)

-- | Return a function defined by Haskell computation over symbolic
--   expressions.
inlineDefineFun :: (IsSymExprBuilder sym, CurryAssignmentClass args) => sym -> SolverSymbol -> Assignment BaseTypeRepr args -> UnfoldPolicy -> CurryAssignment args (SymExpr sym) (IO (SymExpr sym ret)) -> IO (SymFn sym args ret)

-- | Create a new uninterpreted function.
freshTotalUninterpFn :: forall args ret. IsSymExprBuilder sym => sym -> SolverSymbol -> Assignment BaseTypeRepr args -> BaseTypeRepr ret -> IO (SymFn sym args ret)

-- | Apply a set of arguments to a symbolic function.
applySymFn :: IsSymExprBuilder sym => sym -> SymFn sym args ret -> Assignment (SymExpr sym) args -> IO (SymExpr sym ret)

-- | Apply a variable substitution (variable to symbolic expression
--   mapping) to a symbolic expression.
substituteBoundVars :: IsSymExprBuilder sym => sym -> MapF (BoundVar sym) (SymExpr sym) -> SymExpr sym tp -> IO (SymExpr sym tp)

-- | Apply a function substitution (function to function mapping) to a
--   symbolic expression.
substituteSymFns :: IsSymExprBuilder sym => sym -> MapF (SymFnWrapper sym) (SymFnWrapper sym) -> SymExpr sym tp -> IO (SymExpr sym tp)

-- | This datatype describes events that involve interacting with solvers.
--   A SolverEvent will be provided to the action installed via
--   setSolverLogListener whenever an interesting event occurs.
data SolverEvent
SolverStartSATQuery :: SolverStartSATQuery -> SolverEvent
SolverEndSATQuery :: SolverEndSATQuery -> SolverEvent
data SolverStartSATQuery
SolverStartSATQueryRec :: !String -> !String -> SolverStartSATQuery
[satQuerySolverName] :: SolverStartSATQuery -> !String
[satQueryReason] :: SolverStartSATQuery -> !String
data SolverEndSATQuery
SolverEndSATQueryRec :: !SatResult () () -> !Maybe String -> SolverEndSATQuery
[satQueryResult] :: SolverEndSATQuery -> !SatResult () ()
[satQueryError] :: SolverEndSATQuery -> !Maybe String

-- | Join a Vector of smaller bitvectors. The vector is
--   interpreted in big endian order; that is, with most significant
--   bitvector first.
bvJoinVector :: forall sym n w. (1 <= w, IsExprBuilder sym) => sym -> NatRepr w -> Vector n (SymBV sym w) -> IO (SymBV sym (n * w))

-- | Split a bitvector to a Vector of smaller bitvectors. The
--   returned vector is in big endian order; that is, with most significant
--   bitvector first.
bvSplitVector :: forall sym n w. (IsExprBuilder sym, 1 <= w, 1 <= n) => sym -> NatRepr n -> NatRepr w -> SymBV sym (n * w) -> IO (Vector n (SymBV sym w))

-- | Implement LLVM's "bswap" intrinsic
--   
--   See
--   <https://llvm.org/docs/LangRef.html#llvm-bswap-intrinsics
--   the LLVM bswap documentation.>
--   
--   This is the implementation in SawCore:
--   
--   
--   llvmBSwap :: (n :: Nat) -> bitvector (mulNat n 8) -> bitvector (mulNat n 8);
--   llvmBSwap n x = join n 8 Bool (reverse n (bitvector 8) (split n 8 Bool x));
--   
bvSwap :: forall sym n. (1 <= n, IsExprBuilder sym) => sym -> NatRepr n -> SymBV sym (n * 8) -> IO (SymBV sym (n * 8))

-- | Swap the order of the bits in a bitvector.
bvBitreverse :: forall sym w. (1 <= w, IsExprBuilder sym) => sym -> SymBV sym w -> IO (SymBV sym w)

-- | Rounding modes for IEEE-754 floating point operations.
data RoundingMode

-- | Round to nearest even.
RNE :: RoundingMode

-- | Round to nearest away.
RNA :: RoundingMode

-- | Round toward plus Infinity.
RTP :: RoundingMode

-- | Round toward minus Infinity.
RTN :: RoundingMode

-- | Round toward zero.
RTZ :: RoundingMode

-- | Statistics gathered on a running expression builder. See
--   getStatistics.
data Statistics
Statistics :: !Integer -> !Integer -> Statistics

-- | The number of times an expression node has been allocated.
[statAllocs] :: Statistics -> !Integer

-- | The number of non-linear operations, such as multiplications, that
--   have occurred.
[statNonLinearOps] :: Statistics -> !Integer
zeroStatistics :: Statistics

-- | Symbolic boolean values, AKA predicates.
type Pred sym = SymExpr sym BaseBoolType

-- | Symbolic integers.
type SymInteger sym = SymExpr sym BaseIntegerType

-- | Symbolic real numbers.
type SymReal sym = SymExpr sym BaseRealType

-- | Symbolic floating point numbers.
type SymFloat sym fpp = SymExpr sym (BaseFloatType fpp)

-- | Symbolic strings.
type SymString sym si = SymExpr sym (BaseStringType si)

-- | Symbolic complex numbers.
type SymCplx sym = SymExpr sym BaseComplexType

-- | Symbolic structures.
type SymStruct sym flds = SymExpr sym (BaseStructType flds)

-- | Symbolic bitvectors.
type SymBV sym n = SymExpr sym (BaseBVType n)

-- | Symbolic arrays.
type SymArray sym idx b = SymExpr sym (BaseArrayType idx b)

-- | Symbolic natural numbers.
data SymNat sym

-- | Return nat if this is a constant natural number.
asNat :: IsExpr (SymExpr sym) => SymNat sym -> Maybe Natural

-- | A natural number literal.
natLit :: IsExprBuilder sym => sym -> Natural -> IO (SymNat sym)

-- | Add two natural numbers.
natAdd :: IsExprBuilder sym => sym -> SymNat sym -> SymNat sym -> IO (SymNat sym)

-- | Subtract one number from another.
--   
--   The result is 0 if the subtraction would otherwise be negative.
natSub :: IsExprBuilder sym => sym -> SymNat sym -> SymNat sym -> IO (SymNat sym)

-- | Multiply one number by another.
natMul :: IsExprBuilder sym => sym -> SymNat sym -> SymNat sym -> IO (SymNat sym)

-- | natDiv sym x y performs division on naturals.
--   
--   The result is undefined if y equals 0.
--   
--   natDiv and natMod satisfy the property that given
--   
--   
--   d <- natDiv sym x y
--   m <- natMod sym x y
--   
--   
--   and y > 0, we have that y * d + m = x and m
--   < y.
natDiv :: IsExprBuilder sym => sym -> SymNat sym -> SymNat sym -> IO (SymNat sym)

-- | natMod sym x y returns x mod y.
--   
--   See natDiv for a description of the properties the return value
--   is expected to satisfy.
natMod :: IsExprBuilder sym => sym -> SymNat sym -> SymNat sym -> IO (SymNat sym)

-- | If-then-else applied to natural numbers.
natIte :: IsExprBuilder sym => sym -> Pred sym -> SymNat sym -> SymNat sym -> IO (SymNat sym)

-- | Equality predicate for natural numbers.
natEq :: IsExprBuilder sym => sym -> SymNat sym -> SymNat sym -> IO (Pred sym)

-- | natLe sym x y returns true if x <=
--   y.
natLe :: IsExprBuilder sym => sym -> SymNat sym -> SymNat sym -> IO (Pred sym)

-- | natLt sym x y returns true if x <
--   y.
natLt :: IsExprBuilder sym => sym -> SymNat sym -> SymNat sym -> IO (Pred sym)

-- | Convert a natural number to an integer.
natToInteger :: IsExprBuilder sym => sym -> SymNat sym -> IO (SymInteger sym)

-- | Convert a natural number to an integer. natToInteger is just
--   this operation lifted into IO.
natToIntegerPure :: SymNat sym -> SymInteger sym

-- | Convert the unsigned value of a bitvector to a natural.
bvToNat :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (SymNat sym)

-- | Convert a natural number to a real number.
natToReal :: IsExprBuilder sym => sym -> SymNat sym -> IO (SymReal sym)

-- | Convert an integer to a natural number.
--   
--   For negative integers, the result is clamped to 0.
integerToNat :: IsExprBuilder sym => sym -> SymInteger sym -> IO (SymNat sym)

-- | Convert a real number to a natural number.
--   
--   The result is undefined if the given real number does not represent a
--   natural number.
realToNat :: IsExprBuilder sym => sym -> SymReal sym -> IO (SymNat sym)

-- | Create a fresh natural number constant with optional lower and upper
--   bounds. If provided, the bounds are inclusive. If inconsistent bounds
--   are given, an InvalidRange exception will be thrown.
freshBoundedNat :: IsSymExprBuilder sym => sym -> SolverSymbol -> Maybe Natural -> Maybe Natural -> IO (SymNat sym)

-- | Create a fresh natural number constant.
freshNat :: IsSymExprBuilder sym => sym -> SolverSymbol -> IO (SymNat sym)
printSymNat :: IsExpr (SymExpr sym) => SymNat sym -> Doc ann

-- | This represents a concrete index value, and is used for creating
--   arrays.
data IndexLit idx
[IntIndexLit] :: !Integer -> IndexLit BaseIntegerType
[BVIndexLit] :: 1 <= w => !NatRepr w -> !BV w -> IndexLit (BaseBVType w)

-- | Create a literal from an IndexLit.
indexLit :: IsExprBuilder sym => sym -> IndexLit idx -> IO (SymExpr sym idx)
newtype ArrayResultWrapper f idx tp
ArrayResultWrapper :: f (BaseArrayType idx tp) -> ArrayResultWrapper f idx tp
[unwrapArrayResult] :: ArrayResultWrapper f idx tp -> f (BaseArrayType idx tp)

-- | Return a concrete representation of a value, if it is concrete.
asConcrete :: IsExpr e => e tp -> Maybe (ConcreteVal tp)

-- | Create a literal symbolic value from a concrete value.
concreteToSym :: IsExprBuilder sym => sym -> ConcreteVal tp -> IO (SymExpr sym tp)

-- | This returns true if the value corresponds to a concrete value.
baseIsConcrete :: forall e bt. IsExpr e => e bt -> Bool

-- | Return some default value for each base type. For numeric types, this
--   is 0; for booleans, false; for strings, the empty string. Structs are
--   filled with default values for every field, default arrays are
--   constant arrays of default values.
baseDefaultValue :: forall sym bt. IsExprBuilder sym => sym -> BaseTypeRepr bt -> IO (SymExpr sym bt)

-- | Return value as a constant integer if it exists.
realExprAsInteger :: (IsExpr e, MonadFail m) => e BaseRealType -> m Integer

-- | Return value as a constant integer if it exists.
rationalAsInteger :: MonadFail m => Rational -> m Integer

-- | Extract the value of a complex expression, which is assumed to be a
--   constant real number. Fail if the number has nonzero imaginary
--   component, or if it is not a constant.
cplxExprAsRational :: (MonadFail m, IsExpr e) => e BaseComplexType -> m Rational

-- | Return a complex value as a constant integer if it exists.
cplxExprAsInteger :: (MonadFail m, IsExpr e) => e BaseComplexType -> m Integer

-- | This provides an interface for converting between Haskell values and a
--   solver representation.
data SymEncoder sym v tp
SymEncoder :: !BaseTypeRepr tp -> !sym -> SymExpr sym tp -> IO v -> !sym -> v -> IO (SymExpr sym tp) -> SymEncoder sym v tp
[symEncoderType] :: SymEncoder sym v tp -> !BaseTypeRepr tp
[symFromExpr] :: SymEncoder sym v tp -> !sym -> SymExpr sym tp -> IO v
[symToExpr] :: SymEncoder sym v tp -> !sym -> v -> IO (SymExpr sym tp)

-- | Return predicate equivalent to a Boolean.
backendPred :: IsExprBuilder sym => sym -> Bool -> Pred sym

-- | Compute the conjunction of a sequence of predicates.
andAllOf :: IsExprBuilder sym => sym -> Fold s (Pred sym) -> s -> IO (Pred sym)

-- | Compute the disjunction of a sequence of predicates.
orOneOf :: IsExprBuilder sym => sym -> Fold s (Pred sym) -> s -> IO (Pred sym)

-- | Perform an ite on a predicate lazily.
itePredM :: (IsExpr (SymExpr sym), IsExprBuilder sym, MonadIO m) => sym -> Pred sym -> m (Pred sym) -> m (Pred sym) -> m (Pred sym)

-- | A utility combinator for combining actions that build terms with
--   ifthenelse. If the given predicate is concretely true or false
--   only the corresponding "then" or "else" action is run; otherwise both
--   actions are run and combined with the given "ite" action.
iteM :: IsExprBuilder sym => (sym -> Pred sym -> v -> v -> IO v) -> sym -> Pred sym -> IO v -> IO v -> IO v

-- | An iterated sequence of ifthenelse operations. The list of
--   predicates and "then" results is constructed as-needed. The "default"
--   value represents the result of the expression if none of the
--   predicates in the given list is true.
iteList :: IsExprBuilder sym => (sym -> Pred sym -> v -> v -> IO v) -> sym -> [(IO (Pred sym), IO v)] -> IO v -> IO v

-- | Return 1 if the predicate is true; 0 otherwise.
predToReal :: IsExprBuilder sym => sym -> Pred sym -> IO (SymReal sym)

-- | Divide one number by another.
--   
--   cplxDiv x y is undefined when y is 0.
cplxDiv :: IsExprBuilder sym => sym -> SymCplx sym -> SymCplx sym -> IO (SymCplx sym)

-- | Returns the principal logarithm of the input value.
--   
--   cplxLog x is undefined when x is 0, and has
--   a cut discontinuity along the negative real line.
cplxLog :: IsExprBuilder sym => sym -> SymCplx sym -> IO (SymCplx sym)

-- | Returns logarithm of input at a given base.
--   
--   cplxLogBase b x is undefined when x is 0.
cplxLogBase :: IsExprBuilder sym => Rational -> sym -> SymCplx sym -> IO (SymCplx sym)

-- | Create a value from a rational.
mkRational :: IsExprBuilder sym => sym -> Rational -> IO (SymCplx sym)

-- | Create a value from an integer.
mkReal :: (IsExprBuilder sym, Real a) => sym -> a -> IO (SymCplx sym)

-- | Return predicate that holds if value is non-zero.
isNonZero :: IsExprBuilder sym => sym -> SymCplx sym -> IO (Pred sym)

-- | Return predicate that holds if imaginary part of number is zero.
isReal :: IsExprBuilder sym => sym -> SymCplx sym -> IO (Pred sym)

-- | This function is used for selecting a value from among potential
--   values in a range.
--   
--   muxRange p ite f l h returns an expression denoting the value
--   obtained from the value f i where i is the smallest
--   value in the range [l..h] such that p i is true. If
--   p i is true for no such value, then this returns the value
--   f h.
muxRange :: (IsExpr e, Monad m) => (Natural -> m (e BaseBoolType)) -> (e BaseBoolType -> a -> a -> m a) -> (Natural -> m a) -> Natural -> Natural -> m a

-- | This exception is thrown if the user requests to make a bounded
--   variable, but gives incoherent or out-of-range bounds.
data InvalidRange
[InvalidRange] :: BaseTypeRepr bt -> Maybe (ConcreteValue bt) -> Maybe (ConcreteValue bt) -> InvalidRange

-- | A utility class for values that contain abstract values
class HasAbsValue f

-- | This represents a name known to the solver.
--   
--   We have three types of symbols:
--   
--   
--   
- The empty symbol
--   
- A user symbol
--   
- A system symbol
--   
--   
--   A user symbol should consist of a letter followed by any combination
--   of letters, digits, and underscore characters. It also cannot be a
--   reserved word in Yices or SMTLIB.
--   
--   A system symbol should start with a letter followed by any number of
--   letter, digit, underscore or an exclamation mark characters. It must
--   contain at least one exclamation mark to distinguish itself from user
--   symbols.
data SolverSymbol

-- | Return the empty symbol.
emptySymbol :: SolverSymbol

-- | This returns either a user symbol or the empty symbol if the string is
--   empty.
userSymbol :: String -> Either SolverSymbolError SolverSymbol

-- | Attempts to create a user symbol from the given string. If this fails
--   for some reason, the string is Z-encoded into a system symbol instead
--   with the prefix "zenc!".
safeSymbol :: String -> SolverSymbol

-- | Describes a range of values in a totally ordered set.
data ValueRange tp

-- | Indicates that range denotes a single value
SingleRange :: !tp -> ValueRange tp

-- | The number is unconstrained.
UnboundedRange :: ValueRange tp

-- | The number is greater than or equal to the given lower bound.
MinRange :: !tp -> ValueRange tp

-- | The number is less than or equal to the given upper bound.
MaxRange :: !tp -> ValueRange tp

-- | The number is between the given lower and upper bounds.
IntervalRange :: !tp -> !tp -> ValueRange tp
data StringLiteral (si :: StringInfo) :: Type
[UnicodeLiteral] :: !Text -> StringLiteral Unicode
[Char8Literal] :: !ByteString -> StringLiteral Char8
[Char16Literal] :: !Word16String -> StringLiteral Char16
stringLiteralInfo :: StringLiteral si -> StringInfoRepr si
instance GHC.Generics.Generic What4.Interface.SolverStartSATQuery
instance GHC.Show.Show What4.Interface.SolverStartSATQuery
instance GHC.Generics.Generic What4.Interface.SolverEndSATQuery
instance GHC.Show.Show What4.Interface.SolverEndSATQuery
instance GHC.Generics.Generic What4.Interface.SolverEvent
instance GHC.Show.Show What4.Interface.SolverEvent
instance GHC.Show.Show What4.Interface.UnfoldPolicy
instance GHC.Classes.Ord What4.Interface.UnfoldPolicy
instance GHC.Classes.Eq What4.Interface.UnfoldPolicy
instance GHC.Show.Show What4.Interface.Statistics
instance GHC.Exception.Type.Exception What4.Interface.InvalidRange
instance GHC.Show.Show What4.Interface.InvalidRange
instance What4.Interface.IsSymFn (What4.Interface.SymFn sym) => Data.Type.Equality.TestEquality (What4.Interface.SymFnWrapper sym)
instance What4.Interface.IsSymFn (What4.Interface.SymFn sym) => Data.Parameterized.Classes.OrdF (What4.Interface.SymFnWrapper sym)
instance Data.Type.Equality.TestEquality (What4.Interface.SymExpr sym) => GHC.Classes.Eq (What4.Interface.SymNat sym)
instance Data.Parameterized.Classes.OrdF (What4.Interface.SymExpr sym) => GHC.Classes.Ord (What4.Interface.SymNat sym)
instance (Data.Parameterized.Classes.HashableF (What4.Interface.SymExpr sym), Data.Type.Equality.TestEquality (What4.Interface.SymExpr sym)) => Data.Hashable.Class.Hashable (What4.Interface.SymNat sym)
instance Data.Type.Equality.TestEquality f => Data.Type.Equality.TestEquality (What4.Interface.ArrayResultWrapper f idx)
instance Data.Parameterized.Classes.HashableF e => Data.Parameterized.Classes.HashableF (What4.Interface.ArrayResultWrapper e idx)

module What4.Utils.Serialize
withRounding :: forall sym tp. IsExprBuilder sym => sym -> SymBV sym 2 -> (RoundingMode -> IO (SymExpr sym tp)) -> IO (SymExpr sym tp)

-- | Try converting any String into a SolverSymbol. If it is
--   an invalid symbol, then error.
makeSymbol :: String -> SolverSymbol

-- | Fork an async action that is linked to the parent thread, but can be
--   safely canceld without also killing the parent thread.
--   
--   Note that if your async doesn't return unit, then you probably want to
--   wait for it instead, which eliminates the need for linking it.
--   Also, if you plan to cancel the async near where you fork it, then
--   withAsyncLinked is a better choice than using this function and
--   subsequently canceling, since it ensures cancellation.
--   
--   See https://github.com/simonmar/async/issues/25 for a perhaps
--   more robust, but also harder to use version of this. The linked
--   version is harder to use because it requires a special version of
--   cancel.
asyncLinked :: MonadUnliftIO m => m () -> m (Async ())

-- | A version of withAsync that safely links the child. See
--   asyncLinked.
withAsyncLinked :: MonadUnliftIO m => m () -> (Async () -> m a) -> m a

-- | A wrapper for What4 bitvectors so that the width is not tracked
--   statically.
module What4.SWord

-- | A What4 symbolic bitvector where the size does not appear in the type
data SWord sym
[DBV] :: (IsExpr (SymExpr sym), 1 <= w) => SymBV sym w -> SWord sym
[ZBV] :: SWord sym

-- | Return the signed value if this is a constant bitvector
bvAsSignedInteger :: forall sym. IsExprBuilder sym => SWord sym -> Maybe Integer

-- | Return the unsigned value if this is a constant bitvector
bvAsUnsignedInteger :: forall sym. IsExprBuilder sym => SWord sym -> Maybe Integer

-- | Convert an integer to an unsigned bitvector. The input value is
--   reduced modulo 2^w.
integerToBV :: forall sym width. (Show width, Integral width, IsExprBuilder sym) => sym -> SymInteger sym -> width -> IO (SWord sym)

-- | Interpret the bit-vector as an unsigned integer
bvToInteger :: forall sym. IsExprBuilder sym => sym -> SWord sym -> IO (SymInteger sym)

-- | Interpret the bit-vector as a signed integer
sbvToInteger :: forall sym. IsExprBuilder sym => sym -> SWord sym -> IO (SymInteger sym)
freshBV :: forall sym. IsSymExprBuilder sym => sym -> SolverSymbol -> Integer -> IO (SWord sym)

-- | Get the width of a bitvector
bvWidth :: forall sym. SWord sym -> Integer

-- | Create a bitvector with the given width and value
bvLit :: forall sym. IsExprBuilder sym => sym -> Integer -> Integer -> IO (SWord sym)
bvFill :: forall sym. IsExprBuilder sym => sym -> Integer -> Pred sym -> IO (SWord sym)

-- | Returns true if the corresponding bit in the bitvector is set. NOTE
--   bits are numbered in big-endian ordering, meaning the most-significant
--   bit is bit 0
bvAtBE :: forall sym. IsExprBuilder sym => sym -> SWord sym -> Integer -> IO (Pred sym)

-- | Returns true if the corresponding bit in the bitvector is set. NOTE
--   bits are numbered in little-endian ordering, meaning the
--   least-significant bit is bit 0
bvAtLE :: forall sym. IsExprBuilder sym => sym -> SWord sym -> Integer -> IO (Pred sym)

-- | Set the numbered bit in the given bitvector to the given bit value.
--   NOTE bits are numbered in big-endian ordering, meaning the
--   most-significant bit is bit 0
bvSetBE :: forall sym. IsExprBuilder sym => sym -> SWord sym -> Integer -> Pred sym -> IO (SWord sym)

-- | Set the numbered bit in the given bitvector to the given bit value.
--   NOTE bits are numbered in big-endian ordering, meaning the
--   most-significant bit is bit 0
bvSetLE :: forall sym. IsExprBuilder sym => sym -> SWord sym -> Integer -> Pred sym -> IO (SWord sym)

-- | Select a subsequence from a bitvector, with bits numbered in Big
--   Endian order (most significant bit is 0). This fails if idx + n is
--   >= w
bvSliceBE :: forall sym. IsExprBuilder sym => sym -> Integer -> Integer -> SWord sym -> IO (SWord sym)

-- | Select a subsequence from a bitvector, with bits numbered in Little
--   Endian order (least significant bit is 0). This fails if idx + n is
--   >= w
bvSliceLE :: forall sym. IsExprBuilder sym => sym -> Integer -> Integer -> SWord sym -> IO (SWord sym)

-- | Concatenate two bitvectors.
bvJoin :: forall sym. IsExprBuilder sym => sym -> SWord sym -> SWord sym -> IO (SWord sym)

-- | If-then-else applied to bitvectors.
bvIte :: forall sym. IsExprBuilder sym => sym -> Pred sym -> SWord sym -> SWord sym -> IO (SWord sym)

-- | convert a vector of booleans to a bitvector. The input are used in Big
--   Endian order (most significant bit first)
bvPackBE :: forall sym. (IsExpr (SymExpr sym), IsExprBuilder sym) => sym -> Vector (Pred sym) -> IO (SWord sym)

-- | convert a vector of booleans to a bitvector. The inputs are used in
--   Little Endian order (least significant bit first)
bvPackLE :: forall sym. (IsExpr (SymExpr sym), IsExprBuilder sym) => sym -> Vector (Pred sym) -> IO (SWord sym)

-- | Explode a bitvector into a vector of booleans in Big Endian order
--   (most significant bit first)
bvUnpackBE :: forall sym. IsExprBuilder sym => sym -> SWord sym -> IO (Vector (Pred sym))

-- | Explode a bitvector into a vector of booleans in Little Endian order
--   (least significant bit first)
bvUnpackLE :: forall sym. IsExprBuilder sym => sym -> SWord sym -> IO (Vector (Pred sym))
bvForall :: IsSymExprBuilder sym => sym -> Natural -> (SWord sym -> IO (Pred sym)) -> IO (Pred sym)
unsignedBVBounds :: forall sym. IsExprBuilder sym => SWord sym -> Maybe (Integer, Integer)
signedBVBounds :: forall sym. IsExprBuilder sym => SWord sym -> Maybe (Integer, Integer)

-- | Bitwise complement
bvNot :: SWordUn

-- | Bitwise logical and.
bvAnd :: SWordBin

-- | Bitwise logical or.
bvOr :: SWordBin

-- | Bitwise logical exclusive or.
bvXor :: SWordBin

-- | 2's complement negation.
bvNeg :: SWordUn

-- | Add two bitvectors.
bvAdd :: SWordBin

-- | Subtract one bitvector from another.
bvSub :: SWordBin

-- | Multiply one bitvector by another.
bvMul :: SWordBin

-- | Unsigned bitvector division.
--   
--   The result is undefined when y is zero, but is otherwise
--   equal to floor( x / y ).
bvUDiv :: SWordBin

-- | Unsigned bitvector remainder.
--   
--   The result is undefined when y is zero, but is otherwise
--   equal to x - (bvUdiv x y) * y.
bvURem :: SWordBin

-- | Signed bitvector division. The result is truncated to zero.
--   
--   The result of bvSdiv x y is undefined when y is
--   zero, but is equal to floor(x/y) when x and
--   y have the same sign, and equal to ceiling(x/y) when
--   x and y have opposite signs.
--   
--   NOTE! However, that there is a corner case when dividing
--   MIN_INT by -1, in which case an overflow condition
--   occurs, and the result is instead MIN_INT.
bvSDiv :: SWordBin

-- | Signed bitvector remainder.
--   
--   The result of bvSrem x y is undefined when y is
--   zero, but is otherwise equal to x - (bvSdiv x y) * y.
bvSRem :: SWordBin

-- | Return true if bitvectors are equal.
bvEq :: PredBin

-- | Signed less-than-or-equal.
bvsle :: PredBin

-- | Signed less-than.
bvslt :: PredBin

-- | Unsigned less-than-or-equal.
bvule :: PredBin

-- | Unsigned less-than.
bvult :: PredBin

-- | Signed greater-than-or-equal.
bvsge :: PredBin

-- | Signed greater-than.
bvsgt :: PredBin

-- | Unsigned greater-than-or-equal.
bvuge :: PredBin

-- | Unsigned greater-than.
bvugt :: PredBin
bvIsNonzero :: IsExprBuilder sym => sym -> SWord sym -> IO (Pred sym)
bvPopcount :: SWordUn
bvCountLeadingZeros :: SWordUn
bvCountTrailingZeros :: SWordUn
bvLg2 :: SWordUn
bvShl :: IsExprBuilder sym => sym -> SWord sym -> SWord sym -> IO (SWord sym)
bvLshr :: IsExprBuilder sym => sym -> SWord sym -> SWord sym -> IO (SWord sym)
bvAshr :: IsExprBuilder sym => sym -> SWord sym -> SWord sym -> IO (SWord sym)
bvRol :: IsExprBuilder sym => sym -> SWord sym -> SWord sym -> IO (SWord sym)
bvRor :: IsExprBuilder sym => sym -> SWord sym -> SWord sym -> IO (SWord sym)

-- | Zero-extend a value, adding the specified number of bits.
bvZext :: forall sym. IsExprBuilder sym => sym -> Natural -> SWord sym -> IO (SWord sym)

-- | Sign-extend a value, adding the specified number of bits.
bvSext :: forall sym. IsExprBuilder sym => sym -> Natural -> SWord sym -> IO (SWord sym)
instance GHC.Show.Show (What4.SWord.SWord sym)

-- | Working with floats of dynamic sizes.
module What4.SFloat

-- | Symbolic floating point numbers.
data SFloat sym
[SFloat] :: IsExpr (SymExpr sym) => SymFloat sym fpp -> SFloat sym
fpReprOf :: IsExpr (SymExpr sym) => sym -> SymFloat sym fpp -> FloatPrecisionRepr fpp
fpSize :: SFloat sym -> (Integer, Integer)

-- | Construct the FloatPrecisionRepr with the given parameters.
fpRepr :: Integer -> Integer -> Maybe (Some FloatPrecisionRepr)
fpAsLit :: SFloat sym -> Maybe BigFloat
fpIte :: IsExprBuilder sym => sym -> Pred sym -> SFloat sym -> SFloat sym -> IO (SFloat sym)

-- | A fresh variable of the given type.
fpFresh :: IsSymExprBuilder sym => sym -> Integer -> Integer -> IO (SFloat sym)

-- | Not a number
fpNaN :: IsExprBuilder sym => sym -> Integer -> Integer -> IO (SFloat sym)

-- | Positive infinity
fpPosInf :: IsExprBuilder sym => sym -> Integer -> Integer -> IO (SFloat sym)

-- | Negative infinity
fpNegInf :: IsExprBuilder sym => sym -> Integer -> Integer -> IO (SFloat sym)

-- | A floating point number corresponding to the given BigFloat.
fpFromLit :: IsExprBuilder sym => sym -> Integer -> Integer -> BigFloat -> IO (SFloat sym)

-- | A floating point number corresponding to the given rational.
fpFromRationalLit :: IsExprBuilder sym => sym -> Integer -> Integer -> Rational -> IO (SFloat sym)

-- | Make a floating point number with the given bit representation.
fpFromBinary :: IsExprBuilder sym => sym -> Integer -> Integer -> SWord sym -> IO (SFloat sym)
fpToBinary :: IsExprBuilder sym => sym -> SFloat sym -> IO (SWord sym)
type SFloatRel sym = sym -> SFloat sym -> SFloat sym -> IO (Pred sym)
fpEq :: IsExprBuilder sym => SFloatRel sym
fpEqIEEE :: IsExprBuilder sym => SFloatRel sym
fpLtIEEE :: IsExprBuilder sym => SFloatRel sym
fpGtIEEE :: IsExprBuilder sym => SFloatRel sym
type SFloatBinArith sym = sym -> RoundingMode -> SFloat sym -> SFloat sym -> IO (SFloat sym)
fpNeg :: IsExprBuilder sym => sym -> SFloat sym -> IO (SFloat sym)
fpAbs :: IsExprBuilder sym => sym -> SFloat sym -> IO (SFloat sym)
fpSqrt :: IsExprBuilder sym => sym -> RoundingMode -> SFloat sym -> IO (SFloat sym)
fpAdd :: IsExprBuilder sym => SFloatBinArith sym
fpSub :: IsExprBuilder sym => SFloatBinArith sym
fpMul :: IsExprBuilder sym => SFloatBinArith sym
fpDiv :: IsExprBuilder sym => SFloatBinArith sym
fpMin :: IsExprBuilder sym => sym -> SFloat sym -> SFloat sym -> IO (SFloat sym)
fpMax :: IsExprBuilder sym => sym -> SFloat sym -> SFloat sym -> IO (SFloat sym)
fpFMA :: IsExprBuilder sym => sym -> RoundingMode -> SFloat sym -> SFloat sym -> SFloat sym -> IO (SFloat sym)
fpRound :: IsExprBuilder sym => sym -> RoundingMode -> SFloat sym -> IO (SFloat sym)

-- | This is undefined on "special" values (NaN,infinity)
fpToReal :: IsExprBuilder sym => sym -> SFloat sym -> IO (SymReal sym)
fpFromReal :: IsExprBuilder sym => sym -> Integer -> Integer -> RoundingMode -> SymReal sym -> IO (SFloat sym)
fpFromRational :: IsExprBuilder sym => sym -> Integer -> Integer -> RoundingMode -> SymInteger sym -> SymInteger sym -> IO (SFloat sym)

-- | Returns a predicate and two integers, x and y. If
--   the the predicate holds, then x / y is a rational
--   representing the floating point number. Assumes the FP number is not
--   one of the special ones that has no real representation.
fpToRational :: IsSymExprBuilder sym => sym -> SFloat sym -> IO (Pred sym, SymInteger sym, SymInteger sym)
fpFromInteger :: IsExprBuilder sym => sym -> Integer -> Integer -> RoundingMode -> SymInteger sym -> IO (SFloat sym)
fpIsInf :: IsExprBuilder sym => sym -> SFloat sym -> IO (Pred sym)
fpIsNaN :: IsExprBuilder sym => sym -> SFloat sym -> IO (Pred sym)
fpIsZero :: IsExprBuilder sym => sym -> SFloat sym -> IO (Pred sym)
fpIsNeg :: IsExprBuilder sym => sym -> SFloat sym -> IO (Pred sym)
fpIsSubnorm :: IsExprBuilder sym => sym -> SFloat sym -> IO (Pred sym)
fpIsNorm :: IsExprBuilder sym => sym -> SFloat sym -> IO (Pred sym)

-- | This exception is thrown if the operations try to create a floating
--   point value we do not support
data UnsupportedFloat
UnsupportedFloat :: String -> Integer -> UnsupportedFloat
[fpWho] :: UnsupportedFloat -> String
[exponentBits, precisionBits] :: UnsupportedFloat -> Integer

-- | This exceptoin is throws if the types don't match.
data FPTypeError
FPTypeError :: Some BaseTypeRepr -> Some BaseTypeRepr -> FPTypeError
[fpExpected] :: FPTypeError -> Some BaseTypeRepr
[fpActual] :: FPTypeError -> Some BaseTypeRepr
instance GHC.Show.Show What4.SFloat.UnsupportedFloat
instance GHC.Show.Show What4.SFloat.FPTypeError
instance GHC.Exception.Type.Exception What4.SFloat.FPTypeError
instance GHC.Exception.Type.Exception What4.SFloat.UnsupportedFloat

-- | Often, various operations on values are only partially defined (in the
--   case of Crucible expressions, consider loading a value from a pointer
--   - this is only defined in the case that the pointer is valid and
--   non-null). The PartExpr type allows for packaging values
--   together with predicates that express their partiality: the value is
--   only valid if the predicate is true.
module What4.Partial

-- | A partial value represents a value that may or may not be valid.
--   
--   The _partialPred field represents a predicate (optionally with
--   additional provenance information) embodying the value's partiality.
data Partial p v
Partial :: !p -> !v -> Partial p v
[_partialPred] :: Partial p v -> !p
[_partialValue] :: Partial p v -> !v
partialPred :: forall p_a3jW6 v_a3jW7 p_a3kkt. Lens (Partial p_a3jW6 v_a3jW7) (Partial p_a3kkt v_a3jW7) p_a3jW6 p_a3kkt
partialValue :: forall p_a3jW6 v_a3jW7 v_a3kku. Lens (Partial p_a3jW6 v_a3jW7) (Partial p_a3jW6 v_a3kku) v_a3jW7 v_a3kku

-- | Either a partial value, or a straight-up error.
data PartialWithErr e p v
NoErr :: Partial p v -> PartialWithErr e p v
Err :: e -> PartialWithErr e p v

-- | A PartExpr is a PartialWithErr that provides no
--   information about what went wrong. Its name is historic.
type PartExpr p v = PartialWithErr () p v
pattern PE :: p -> v -> PartExpr p v
pattern Unassigned :: PartExpr p v
mkPE :: IsExpr p => p BaseBoolType -> a -> PartExpr (p BaseBoolType) a

-- | Create a part expression from a value that is always defined.
justPartExpr :: IsExprBuilder sym => sym -> v -> PartExpr (Pred sym) v

-- | Create a part expression from a maybe value.
maybePartExpr :: IsExprBuilder sym => sym -> Maybe a -> PartExpr (Pred sym) a

-- | joinMaybePE = fromMaybe Unassigned.
joinMaybePE :: Maybe (PartExpr p v) -> PartExpr p v

-- | A monad transformer which enables symbolic partial computations to run
--   by maintaining a predicate on the value.
newtype PartialT sym m a
PartialT :: (sym -> Pred sym -> m (PartExpr (Pred sym) a)) -> PartialT sym m a
[unPartial] :: PartialT sym m a -> sym -> Pred sym -> m (PartExpr (Pred sym) a)

-- | Run a partial computation.
runPartialT :: sym -> Pred sym -> PartialT sym m a -> m (PartExpr (Pred sym) a)

-- | End the partial computation and just return the unassigned value.
returnUnassigned :: Applicative m => PartialT sym m a

-- | Lift a Maybe value to a partial expression.
returnMaybe :: (IsExpr (SymExpr sym), Applicative m) => Maybe a -> PartialT sym m a

-- | Return a partial expression.
--   
--   This joins the partial expression with the current constraints on the
--   current computation.
returnPartial :: (IsExprBuilder sym, MonadIO m) => PartExpr (Pred sym) a -> PartialT sym m a

-- | Add an extra condition to the current partial computation.
addCondition :: (IsExprBuilder sym, MonadIO m) => Pred sym -> PartialT sym m ()

-- | If-then-else on partial expressions.
mergePartial :: (IsExprBuilder sym, MonadIO m) => sym -> (Pred sym -> a -> a -> PartialT sym m a) -> Pred sym -> PartExpr (Pred sym) a -> PartExpr (Pred sym) a -> m (PartExpr (Pred sym) a)

-- | Merge a collection of partial values in an if-then-else tree. For
--   example, if we merge a list like [(xp,x),(yp,y),(zp,z)], we
--   get a value that is morally equivalent to: if xp then x else (if
--   yp then y else (if zp then z else undefined)).
mergePartials :: (IsExprBuilder sym, MonadIO m) => sym -> (Pred sym -> a -> a -> PartialT sym m a) -> [(Pred sym, PartExpr (Pred sym) a)] -> m (PartExpr (Pred sym) a)
instance GHC.Base.Functor m => GHC.Base.Functor (What4.Partial.PartialT sym m)
instance (What4.Interface.IsExpr (What4.Interface.SymExpr sym), GHC.Base.Monad m) => GHC.Base.Applicative (What4.Partial.PartialT sym m)
instance (What4.Interface.IsExpr (What4.Interface.SymExpr sym), GHC.Base.Monad m) => GHC.Base.Monad (What4.Partial.PartialT sym m)
instance (What4.Interface.IsExpr (What4.Interface.SymExpr sym), Control.Monad.Fail.MonadFail m) => Control.Monad.Fail.MonadFail (What4.Partial.PartialT sym m)
instance What4.Interface.IsExpr (What4.Interface.SymExpr sym) => Control.Monad.Trans.Class.MonadTrans (What4.Partial.PartialT sym)
instance (What4.Interface.IsExpr (What4.Interface.SymExpr sym), Control.Monad.IO.Class.MonadIO m) => Control.Monad.IO.Class.MonadIO (What4.Partial.PartialT sym m)
instance GHC.Show.Show e => Data.Functor.Classes.Show2 (What4.Partial.PartialWithErr e)
instance (GHC.Show.Show e, GHC.Show.Show p) => Data.Functor.Classes.Show1 (What4.Partial.PartialWithErr e p)
instance GHC.Classes.Ord e => Data.Functor.Classes.Ord2 (What4.Partial.PartialWithErr e)
instance (GHC.Classes.Ord e, GHC.Classes.Ord p) => Data.Functor.Classes.Ord1 (What4.Partial.PartialWithErr e p)
instance GHC.Classes.Eq e => Data.Functor.Classes.Eq2 (What4.Partial.PartialWithErr e)
instance (GHC.Classes.Eq e, GHC.Classes.Eq p) => Data.Functor.Classes.Eq1 (What4.Partial.PartialWithErr e p)
instance Data.Bitraversable.Bitraversable (What4.Partial.PartialWithErr e)
instance Data.Bifoldable.Bifoldable (What4.Partial.PartialWithErr e)
instance Data.Bifunctor.Bifunctor (What4.Partial.PartialWithErr e)
instance (GHC.Show.Show p, GHC.Show.Show v, GHC.Show.Show e) => GHC.Show.Show (What4.Partial.PartialWithErr e p v)
instance (GHC.Classes.Ord p, GHC.Classes.Ord v, GHC.Classes.Ord e) => GHC.Classes.Ord (What4.Partial.PartialWithErr e p v)
instance Data.Traversable.Traversable (What4.Partial.PartialWithErr e p)
instance Data.Foldable.Foldable (What4.Partial.PartialWithErr e p)
instance GHC.Generics.Generic1 (What4.Partial.PartialWithErr e p)
instance GHC.Generics.Generic (What4.Partial.PartialWithErr e p v)
instance GHC.Base.Functor (What4.Partial.PartialWithErr e p)
instance (GHC.Classes.Eq p, GHC.Classes.Eq v, GHC.Classes.Eq e) => GHC.Classes.Eq (What4.Partial.PartialWithErr e p v)
instance (Data.Data.Data p, Data.Data.Data v, Data.Data.Data e) => Data.Data.Data (What4.Partial.PartialWithErr e p v)
instance Data.Functor.Classes.Show2 What4.Partial.Partial
instance GHC.Show.Show p => Data.Functor.Classes.Show1 (What4.Partial.Partial p)
instance Data.Functor.Classes.Ord2 What4.Partial.Partial
instance GHC.Classes.Ord p => Data.Functor.Classes.Ord1 (What4.Partial.Partial p)
instance Data.Functor.Classes.Eq2 What4.Partial.Partial
instance GHC.Classes.Eq p => Data.Functor.Classes.Eq1 (What4.Partial.Partial p)
instance Data.Bitraversable.Bitraversable What4.Partial.Partial
instance Data.Bifoldable.Bifoldable What4.Partial.Partial
instance Data.Bifunctor.Bifunctor What4.Partial.Partial
instance (GHC.Show.Show p, GHC.Show.Show v) => GHC.Show.Show (What4.Partial.Partial p v)
instance (GHC.Classes.Ord p, GHC.Classes.Ord v) => GHC.Classes.Ord (What4.Partial.Partial p v)
instance Data.Traversable.Traversable (What4.Partial.Partial p)
instance Data.Foldable.Foldable (What4.Partial.Partial p)
instance GHC.Generics.Generic1 (What4.Partial.Partial p)
instance GHC.Generics.Generic (What4.Partial.Partial p v)
instance GHC.Base.Functor (What4.Partial.Partial p)
instance (GHC.Classes.Eq p, GHC.Classes.Eq v) => GHC.Classes.Eq (What4.Partial.Partial p v)
instance (Data.Data.Data p, Data.Data.Data v) => Data.Data.Data (What4.Partial.Partial p v)

-- | Predicates alone do not record their semantic content, thus it is
--   often useful to attach some sort of descriptor to them.
module What4.LabeledPred

-- | Information about an assertion that was previously made.
data LabeledPred pred msg
LabeledPred :: !pred -> !msg -> LabeledPred pred msg

-- | Predicate that was asserted.
[_labeledPred] :: LabeledPred pred msg -> !pred

-- | Message added when assumption/assertion was made.
[_labeledPredMsg] :: LabeledPred pred msg -> !msg

-- | Predicate that was asserted.
labeledPred :: Lens (LabeledPred pred msg) (LabeledPred pred' msg) pred pred'

-- | Message added when assumption/assertion was made.
labeledPredMsg :: Lens (LabeledPred pred msg) (LabeledPred pred msg') msg msg'

-- | Partition datastructures containing predicates by their possibly
--   concrete values.
--   
--   The output format is (constantly true, constantly false,
--   unknown/symbolic).
partitionByPreds :: (Foldable t, IsExprBuilder sym) => proxy sym -> (a -> Pred sym) -> t a -> ([a], [a], [a])

-- | Partition datastructures containing predicates by their possibly
--   concrete values.
--   
--   The output format is (constantly true, constantly false,
--   unknown/symbolic).
partitionByPredsM :: (Monad m, Foldable t, IsExprBuilder sym) => proxy sym -> (a -> m (Pred sym)) -> t a -> m ([a], [a], [a])

-- | Partition labeled predicates by their possibly concrete values.
--   
--   The output format is (constantly true, constantly false,
--   unknown/symbolic).
partitionLabeledPreds :: (Foldable t, IsExprBuilder sym) => proxy sym -> t (LabeledPred (Pred sym) msg) -> ([LabeledPred (Pred sym) msg], [LabeledPred (Pred sym) msg], [LabeledPred (Pred sym) msg])
instance Data.Functor.Classes.Show2 What4.LabeledPred.LabeledPred
instance GHC.Show.Show pred => Data.Functor.Classes.Show1 (What4.LabeledPred.LabeledPred pred)
instance Data.Functor.Classes.Ord2 What4.LabeledPred.LabeledPred
instance GHC.Classes.Ord pred => Data.Functor.Classes.Ord1 (What4.LabeledPred.LabeledPred pred)
instance Data.Functor.Classes.Eq2 What4.LabeledPred.LabeledPred
instance GHC.Classes.Eq pred => Data.Functor.Classes.Eq1 (What4.LabeledPred.LabeledPred pred)
instance Data.Bitraversable.Bitraversable What4.LabeledPred.LabeledPred
instance Data.Bifoldable.Bifoldable What4.LabeledPred.LabeledPred
instance Data.Bifunctor.Bifunctor What4.LabeledPred.LabeledPred
instance Data.Traversable.Traversable (What4.LabeledPred.LabeledPred pred)
instance (GHC.Show.Show pred, GHC.Show.Show msg) => GHC.Show.Show (What4.LabeledPred.LabeledPred pred msg)
instance (GHC.Classes.Ord pred, GHC.Classes.Ord msg) => GHC.Classes.Ord (What4.LabeledPred.LabeledPred pred msg)
instance GHC.Generics.Generic1 (What4.LabeledPred.LabeledPred pred)
instance GHC.Generics.Generic (What4.LabeledPred.LabeledPred pred msg)
instance Data.Foldable.Foldable (What4.LabeledPred.LabeledPred pred)
instance GHC.Base.Functor (What4.LabeledPred.LabeledPred pred)
instance (Data.Data.Data pred, Data.Data.Data msg) => Data.Data.Data (What4.LabeledPred.LabeledPred pred msg)
instance (GHC.Classes.Eq pred, GHC.Classes.Eq msg) => GHC.Classes.Eq (What4.LabeledPred.LabeledPred pred msg)

module What4.InterpretedFloatingPoint

-- | This data kind describes the types of floating-point formats. This
--   consist of the standard IEEE 754-2008 binary floating point formats,
--   as well as the X86 extended 80-bit format and the double-double
--   format.
data FloatInfo
type HalfFloat = -- |  16 bit binary IEEE754. 'HalfFloat
type SingleFloat = -- |  32 bit binary IEEE754. 'SingleFloat
type DoubleFloat = -- |  64 bit binary IEEE754. 'DoubleFloat
type QuadFloat = -- | 128 bit binary IEEE754. 'QuadFloat
type X86_80Float = -- | X86 80-bit extended floats. 'X86_80Float
type DoubleDoubleFloat = -- | Two 64-bit floats fused in the "double-double" style. 'DoubleDoubleFloat

-- | A family of value-level representatives for floating-point types.
data FloatInfoRepr (fi :: FloatInfo)
[HalfFloatRepr] :: FloatInfoRepr HalfFloat
[SingleFloatRepr] :: FloatInfoRepr SingleFloat
[DoubleFloatRepr] :: FloatInfoRepr DoubleFloat
[QuadFloatRepr] :: FloatInfoRepr QuadFloat
[X86_80FloatRepr] :: FloatInfoRepr X86_80Float
[DoubleDoubleFloatRepr] :: FloatInfoRepr DoubleDoubleFloat

-- | Representation of 80-bit floating values, since there's no native
--   Haskell type for these.
data X86_80Val
X86_80Val :: Word16 -> Word64 -> X86_80Val
fp80ToBits :: X86_80Val -> Integer
fp80ToRational :: X86_80Val -> Maybe Rational
type family FloatInfoToPrecision (fi :: FloatInfo) :: FloatPrecision
type family FloatPrecisionToInfo (fpp :: FloatPrecision) :: FloatInfo
floatInfoToPrecisionRepr :: FloatInfoRepr fi -> FloatPrecisionRepr (FloatInfoToPrecision fi)
floatPrecisionToInfoRepr :: FloatPrecisionRepr fpp -> FloatInfoRepr (FloatPrecisionToInfo fpp)
type family FloatInfoToBitWidth (fi :: FloatInfo) :: Nat
floatInfoToBVTypeRepr :: FloatInfoRepr fi -> BaseTypeRepr (BaseBVType (FloatInfoToBitWidth fi))

-- | Interpretation of the floating point type.
type family SymInterpretedFloatType (sym :: Type) (fi :: FloatInfo) :: BaseType

-- | Symbolic floating point numbers.
type SymInterpretedFloat sym fi = SymExpr sym (SymInterpretedFloatType sym fi)

-- | Abstact floating point operations.
class IsExprBuilder sym => IsInterpretedFloatExprBuilder sym

-- | Return floating point number +0.
iFloatPZero :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> IO (SymInterpretedFloat sym fi)

-- | Return floating point number -0.
iFloatNZero :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> IO (SymInterpretedFloat sym fi)

-- | Return floating point NaN.
iFloatNaN :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> IO (SymInterpretedFloat sym fi)

-- | Return floating point +infinity.
iFloatPInf :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> IO (SymInterpretedFloat sym fi)

-- | Return floating point -infinity.
iFloatNInf :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> IO (SymInterpretedFloat sym fi)

-- | Create a floating point literal from a rational literal.
iFloatLitRational :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> Rational -> IO (SymInterpretedFloat sym fi)

-- | Create a (single precision) floating point literal.
iFloatLitSingle :: IsInterpretedFloatExprBuilder sym => sym -> Float -> IO (SymInterpretedFloat sym SingleFloat)

-- | Create a (double precision) floating point literal.
iFloatLitDouble :: IsInterpretedFloatExprBuilder sym => sym -> Double -> IO (SymInterpretedFloat sym DoubleFloat)

-- | Create an (extended double precision) floating point literal.
iFloatLitLongDouble :: IsInterpretedFloatExprBuilder sym => sym -> X86_80Val -> IO (SymInterpretedFloat sym X86_80Float)

-- | Negate a floating point number.
iFloatNeg :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Return the absolute value of a floating point number.
iFloatAbs :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Compute the square root of a floating point number.
iFloatSqrt :: IsInterpretedFloatExprBuilder sym => sym -> RoundingMode -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Add two floating point numbers.
iFloatAdd :: IsInterpretedFloatExprBuilder sym => sym -> RoundingMode -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Subtract two floating point numbers.
iFloatSub :: IsInterpretedFloatExprBuilder sym => sym -> RoundingMode -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Multiply two floating point numbers.
iFloatMul :: IsInterpretedFloatExprBuilder sym => sym -> RoundingMode -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Divide two floating point numbers.
iFloatDiv :: IsInterpretedFloatExprBuilder sym => sym -> RoundingMode -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Compute the reminder: x - y * n, where n in Z is
--   nearest to x / y.
iFloatRem :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Return the min of two floating point numbers.
iFloatMin :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Return the max of two floating point numbers.
iFloatMax :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Compute the fused multiplication and addition: (x * y) + z.
iFloatFMA :: IsInterpretedFloatExprBuilder sym => sym -> RoundingMode -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Check logical equality of two floating point numbers.
iFloatEq :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (Pred sym)

-- | Check logical non-equality of two floating point numbers.
iFloatNe :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (Pred sym)

-- | Check IEEE equality of two floating point numbers.
iFloatFpEq :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (Pred sym)

-- | Check IEEE apartness of two floating point numbers.
iFloatFpApart :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (Pred sym)

-- | Check <= on two floating point numbers.
iFloatLe :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (Pred sym)

-- | Check < on two floating point numbers.
iFloatLt :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (Pred sym)

-- | Check >= on two floating point numbers.
iFloatGe :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (Pred sym)

-- | Check > on two floating point numbers.
iFloatGt :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (Pred sym)
iFloatIsNaN :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> IO (Pred sym)
iFloatIsInf :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> IO (Pred sym)
iFloatIsZero :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> IO (Pred sym)
iFloatIsPos :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> IO (Pred sym)
iFloatIsNeg :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> IO (Pred sym)
iFloatIsSubnorm :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> IO (Pred sym)
iFloatIsNorm :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> IO (Pred sym)

-- | If-then-else on floating point numbers.
iFloatIte :: IsInterpretedFloatExprBuilder sym => sym -> Pred sym -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Change the precision of a floating point number.
iFloatCast :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> RoundingMode -> SymInterpretedFloat sym fi' -> IO (SymInterpretedFloat sym fi)

-- | Round a floating point number to an integral value.
iFloatRound :: IsInterpretedFloatExprBuilder sym => sym -> RoundingMode -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Convert from binary representation in IEEE 754-2008 format to floating
--   point.
iFloatFromBinary :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> SymBV sym (FloatInfoToBitWidth fi) -> IO (SymInterpretedFloat sym fi)

-- | Convert from floating point from to the binary representation in IEEE
--   754-2008 format.
iFloatToBinary :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> SymInterpretedFloat sym fi -> IO (SymBV sym (FloatInfoToBitWidth fi))

-- | Convert a unsigned bitvector to a floating point number.
iBVToFloat :: (IsInterpretedFloatExprBuilder sym, 1 <= w) => sym -> FloatInfoRepr fi -> RoundingMode -> SymBV sym w -> IO (SymInterpretedFloat sym fi)

-- | Convert a signed bitvector to a floating point number.
iSBVToFloat :: (IsInterpretedFloatExprBuilder sym, 1 <= w) => sym -> FloatInfoRepr fi -> RoundingMode -> SymBV sym w -> IO (SymInterpretedFloat sym fi)

-- | Convert a real number to a floating point number.
iRealToFloat :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> RoundingMode -> SymReal sym -> IO (SymInterpretedFloat sym fi)

-- | Convert a floating point number to a unsigned bitvector.
iFloatToBV :: (IsInterpretedFloatExprBuilder sym, 1 <= w) => sym -> NatRepr w -> RoundingMode -> SymInterpretedFloat sym fi -> IO (SymBV sym w)

-- | Convert a floating point number to a signed bitvector.
iFloatToSBV :: (IsInterpretedFloatExprBuilder sym, 1 <= w) => sym -> NatRepr w -> RoundingMode -> SymInterpretedFloat sym fi -> IO (SymBV sym w)

-- | Convert a floating point number to a real number.
iFloatToReal :: IsInterpretedFloatExprBuilder sym => sym -> SymInterpretedFloat sym fi -> IO (SymReal sym)

-- | Apply a special function to floating-point arguments
iFloatSpecialFunction :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> SpecialFunction args -> Assignment (SpecialFnArg (SymExpr sym) (SymInterpretedFloatType sym fi)) args -> IO (SymInterpretedFloat sym fi)

-- | Access a 0-arity special function constant
iFloatSpecialFunction0 :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> SpecialFunction EmptyCtx -> IO (SymInterpretedFloat sym fi)

-- | Apply a 1-argument special function
iFloatSpecialFunction1 :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> SpecialFunction (EmptyCtx ::> R) -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | Apply a 2-argument special function
iFloatSpecialFunction2 :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> SpecialFunction ((EmptyCtx ::> R) ::> R) -> SymInterpretedFloat sym fi -> SymInterpretedFloat sym fi -> IO (SymInterpretedFloat sym fi)

-- | The associated BaseType representative of the floating point
--   interpretation for each format.
iFloatBaseTypeRepr :: IsInterpretedFloatExprBuilder sym => sym -> FloatInfoRepr fi -> BaseTypeRepr (SymInterpretedFloatType sym fi)

-- | Helper interface for creating new symbolic floating-point constants
--   and variables.
class (IsSymExprBuilder sym, IsInterpretedFloatExprBuilder sym) => IsInterpretedFloatSymExprBuilder sym

-- | Create a fresh top-level floating-point uninterpreted constant.
freshFloatConstant :: IsInterpretedFloatSymExprBuilder sym => sym -> SolverSymbol -> FloatInfoRepr fi -> IO (SymExpr sym (SymInterpretedFloatType sym fi))

-- | Create a fresh floating-point latch variable.
freshFloatLatch :: IsInterpretedFloatSymExprBuilder sym => sym -> SolverSymbol -> FloatInfoRepr fi -> IO (SymExpr sym (SymInterpretedFloatType sym fi))

-- | Creates a floating-point bound variable.
freshFloatBoundVar :: IsInterpretedFloatSymExprBuilder sym => sym -> SolverSymbol -> FloatInfoRepr fi -> IO (BoundVar sym (SymInterpretedFloatType sym fi))
instance GHC.Classes.Ord What4.InterpretedFloatingPoint.X86_80Val
instance GHC.Classes.Eq What4.InterpretedFloatingPoint.X86_80Val
instance GHC.Show.Show What4.InterpretedFloatingPoint.X86_80Val
instance Data.Parameterized.Classes.HashableF What4.InterpretedFloatingPoint.FloatInfoRepr
instance Data.Hashable.Class.Hashable (What4.InterpretedFloatingPoint.FloatInfoRepr fi)
instance Prettyprinter.Internal.Pretty (What4.InterpretedFloatingPoint.FloatInfoRepr fi)
instance GHC.Show.Show (What4.InterpretedFloatingPoint.FloatInfoRepr fi)
instance Data.Parameterized.Classes.ShowF What4.InterpretedFloatingPoint.FloatInfoRepr
instance Data.Type.Equality.TestEquality What4.InterpretedFloatingPoint.FloatInfoRepr
instance GHC.Classes.Eq (What4.InterpretedFloatingPoint.FloatInfoRepr fi)
instance Data.Parameterized.Classes.OrdF What4.InterpretedFloatingPoint.FloatInfoRepr
instance Data.Parameterized.Classes.KnownRepr What4.InterpretedFloatingPoint.FloatInfoRepr What4.InterpretedFloatingPoint.HalfFloat
instance Data.Parameterized.Classes.KnownRepr What4.InterpretedFloatingPoint.FloatInfoRepr What4.InterpretedFloatingPoint.SingleFloat
instance Data.Parameterized.Classes.KnownRepr What4.InterpretedFloatingPoint.FloatInfoRepr What4.InterpretedFloatingPoint.DoubleFloat
instance Data.Parameterized.Classes.KnownRepr What4.InterpretedFloatingPoint.FloatInfoRepr What4.InterpretedFloatingPoint.QuadFloat
instance Data.Parameterized.Classes.KnownRepr What4.InterpretedFloatingPoint.FloatInfoRepr What4.InterpretedFloatingPoint.X86_80Float
instance Data.Parameterized.Classes.KnownRepr What4.InterpretedFloatingPoint.FloatInfoRepr What4.InterpretedFloatingPoint.DoubleDoubleFloat

-- | This module defines a data structure for representing a symbolic
--   bitvector using a form of "unary" representation.
--   
--   The idea behind this representation is that we associate a predicate
--   to each possible value of the bitvector that is true if the symbolic
--   value is less than or equal to the possible value.
--   
--   As an example, if we had the unary term x equal to "{ 0 ->
--   false, 1 -> p, 2 -> q, 3 -> t }", then x cannot be
--   '0', has the value '1' if p is true, the value '2' if 'q
--   & not p' is true, and '3' if 'not q' is true. By construction, we
--   should have that 'p => q'.
module What4.Expr.UnaryBV

-- | A unary bitvector encoding where the map contains predicates such as
--   u^.unaryBVMap^.at i holds iff the value represented by
--   u is less than or equal to i.
--   
--   The map stored in the representation should always have a single
--   element, and the largest integer stored in the map should be
--   associated with a predicate representing "true". This means that if
--   the map contains only a single binding, then it represents a constant.
data UnaryBV p (n :: Nat)
width :: UnaryBV p n -> NatRepr n

-- | Returns the number of distinct values that this could be.
size :: UnaryBV p n -> Int
traversePreds :: Traversal (UnaryBV p n) (UnaryBV q n) p q

-- | Create a unary bitvector term from a constant.
constant :: IsExprBuilder sym => sym -> NatRepr n -> Integer -> UnaryBV (Pred sym) n

-- | Create a unary bitvector term from a constant.
asConstant :: IsExpr p => UnaryBV (p BaseBoolType) w -> Maybe Integer
unsignedEntries :: 1 <= n => UnaryBV p n -> [(Integer, p)]

-- | unsignedRanges v returns a set of predicates and ranges where
--   we know that for each entry (p,l,h) and each value i : l
--   <= i & i <= h: p iff. v <= i
unsignedRanges :: UnaryBV p n -> [(p, Integer, Integer)]

-- | Evaluate a unary bitvector as an integer given an evaluation function.
evaluate :: Monad m => (p -> m Bool) -> UnaryBV p n -> m Integer

-- | Evaluate a unary bitvector given an evaluation function.
--   
--   This function is used to convert a unary bitvector into some other
--   representation such as a binary bitvector or vector of bits.
--   
--   It is polymorphic over the result type r, and requires
--   functions for manipulating values of type r to construct it.
sym_evaluate :: (Applicative m, Monad m) => (Integer -> m r) -> (p -> r -> r -> m r) -> UnaryBV p n -> m r

-- | This function instantiates the predicates in a unary predicate with
--   new predicates.
--   
--   The mapping f should be monotonic, that is for all predicates
--   p and 'q, such that 'p |- q', f should satisfy the
--   constraint that 'f p |- f q'.
instantiate :: (Applicative m, Eq q) => (p -> m q) -> UnaryBV p w -> m (UnaryBV q w)

-- | Return potential values for abstract domain.
domain :: forall p n. 1 <= n => (p -> Maybe Bool) -> UnaryBV p n -> BVDomain n

-- | Add two bitvectors.
--   
--   The number of integers in the result will be at most the product of
--   the sizes of the individual bitvectors.
add :: forall sym n. (1 <= n, IsExprBuilder sym) => sym -> UnaryBV (Pred sym) n -> UnaryBV (Pred sym) n -> IO (UnaryBV (Pred sym) n)

-- | Negate a bitvector. The size of the result will be equal to the size
--   of the input.
neg :: forall sym n. (1 <= n, IsExprBuilder sym) => sym -> UnaryBV (Pred sym) n -> IO (UnaryBV (Pred sym) n)

-- | mux sym c x y returns value equal to if c then
--   x else y. The number of entries in the return value
--   is at most size x + size y.
mux :: forall sym n. (1 <= n, IsExprBuilder sym) => sym -> Pred sym -> UnaryBV (Pred sym) n -> UnaryBV (Pred sym) n -> IO (UnaryBV (Pred sym) n)

-- | Return predicate that holds if bitvectors are equal.
eq :: (1 <= n, IsExprBuilder sym) => sym -> UnaryBV (Pred sym) n -> UnaryBV (Pred sym) n -> IO (Pred sym)

-- | Return predicate that holds if first value is less than other.
slt :: (1 <= n, IsExprBuilder sym) => sym -> UnaryBV (Pred sym) n -> UnaryBV (Pred sym) n -> IO (Pred sym)

-- | Return predicate that holds if first value is less than other.
ult :: (1 <= n, IsExprBuilder sym) => sym -> UnaryBV (Pred sym) n -> UnaryBV (Pred sym) n -> IO (Pred sym)

-- | Perform a unsigned extension
uext :: (1 <= u, (u + 1) <= r) => UnaryBV p u -> NatRepr r -> UnaryBV p r

-- | Perform a signed extension
sext :: (1 <= u, (u + 1) <= r) => UnaryBV p u -> NatRepr r -> UnaryBV p r

-- | Perform a struncation.
trunc :: forall sym u r. (IsExprBuilder sym, 1 <= u, u <= r) => sym -> UnaryBV (Pred sym) r -> NatRepr u -> IO (UnaryBV (Pred sym) u)
instance GHC.Classes.Eq p => Data.Type.Equality.TestEquality (What4.Expr.UnaryBV.UnaryBV p)
instance GHC.Classes.Eq p => GHC.Classes.Eq (What4.Expr.UnaryBV.UnaryBV p n)
instance Data.Hashable.Class.Hashable p => Data.Hashable.Class.Hashable (What4.Expr.UnaryBV.UnaryBV p n)

-- | A simple datatype for collecting sequences of strings that are to be
--   concatenated together.
--   
--   We intend to maintain several invariants. First, that no sequence is
--   empty; the empty string literal should instead be the unique
--   representative of empty strings. Second, that string sequences do not
--   contain adjacent literals. In other words, adjacent string literals
--   are coalesced.
module What4.Expr.StringSeq
data StringSeq (e :: BaseType -> Type) (si :: StringInfo)
data StringSeqEntry e si
StringSeqLiteral :: !StringLiteral si -> StringSeqEntry e si
StringSeqTerm :: !e (BaseStringType si) -> StringSeqEntry e si
singleton :: (HasAbsValue e, HashableF e, IsExpr e) => StringInfoRepr si -> e (BaseStringType si) -> StringSeq e si
append :: (HasAbsValue e, HashableF e) => StringSeq e si -> StringSeq e si -> StringSeq e si
stringSeqAbs :: (HasAbsValue e, HashableF e) => StringSeq e si -> StringAbstractValue
toList :: StringSeq e si -> [StringSeqEntry e si]
traverseStringSeq :: (HasAbsValue f, HashableF f, Applicative m) => (forall x. e x -> m (f x)) -> StringSeq e si -> m (StringSeq f si)
instance (Data.Type.Equality.TestEquality e, What4.Utils.AbstractDomains.HasAbsValue e, Data.Parameterized.Classes.HashableF e) => Data.Type.Equality.TestEquality (What4.Expr.StringSeq.StringSeq e)
instance (Data.Type.Equality.TestEquality e, What4.Utils.AbstractDomains.HasAbsValue e, Data.Parameterized.Classes.HashableF e) => GHC.Classes.Eq (What4.Expr.StringSeq.StringSeq e si)
instance (What4.Utils.AbstractDomains.HasAbsValue e, Data.Parameterized.Classes.HashableF e) => Data.Parameterized.Classes.HashableF (What4.Expr.StringSeq.StringSeq e)
instance (What4.Utils.AbstractDomains.HasAbsValue e, Data.Parameterized.Classes.HashableF e, Data.Type.Equality.TestEquality e) => Data.Hashable.Class.Hashable (What4.Expr.StringSeq.StringSeq e si)
instance (What4.Utils.AbstractDomains.HasAbsValue e, Data.Parameterized.Classes.HashableF e) => Data.FingerTree.Measured What4.Expr.StringSeq.StringSeqNote (What4.Expr.StringSeq.StringSeqEntry e si)
instance GHC.Base.Semigroup What4.Expr.StringSeq.StringSeqNote
instance GHC.Base.Monoid What4.Expr.StringSeq.StringSeqNote

-- | This module provides an interface that a symbolic backend should
--   implement to support MATLAB intrinsics.
module What4.Expr.MATLAB

-- | Builtin functions that can be used to generate symbolic functions.
--   
--   These functions are expected to be total, but the value returned may
--   not be specified. e.g. IntegerToNatFn must return some
--   natural number for every integer, but for negative integers, the
--   particular number is unspecified.
data MatlabSolverFn (f :: BaseType -> Type) args ret
[BoolOrFn] :: MatlabSolverFn f ((EmptyCtx ::> BaseBoolType) ::> BaseBoolType) BaseBoolType
[IsIntegerFn] :: MatlabSolverFn f (EmptyCtx ::> BaseRealType) BaseBoolType
[IntLeFn] :: MatlabSolverFn f ((EmptyCtx ::> BaseIntegerType) ::> BaseIntegerType) BaseBoolType
[BVToIntegerFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f (EmptyCtx ::> BaseBVType w) BaseIntegerType
[SBVToIntegerFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f (EmptyCtx ::> BaseBVType w) BaseIntegerType
[IntegerToRealFn] :: MatlabSolverFn f (EmptyCtx ::> BaseIntegerType) BaseRealType
[RealToIntegerFn] :: MatlabSolverFn f (EmptyCtx ::> BaseRealType) BaseIntegerType
[PredToIntegerFn] :: MatlabSolverFn f (EmptyCtx ::> BaseBoolType) BaseIntegerType
[IntSeqFn] :: !f BaseIntegerType -> !f BaseIntegerType -> MatlabSolverFn f ((EmptyCtx ::> BaseIntegerType) ::> BaseIntegerType) BaseIntegerType
[RealSeqFn] :: !f BaseRealType -> !f BaseRealType -> MatlabSolverFn f ((EmptyCtx ::> BaseIntegerType) ::> BaseIntegerType) BaseRealType
[IndicesInRange] :: !Assignment OnlyIntRepr (idx ::> itp) -> !Assignment f (idx ::> itp) -> MatlabSolverFn f (idx ::> itp) BaseBoolType
[IsEqFn] :: !BaseTypeRepr tp -> MatlabSolverFn f ((EmptyCtx ::> tp) ::> tp) BaseBoolType
[BVIsNonZeroFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f (EmptyCtx ::> BaseBVType w) BaseBoolType
[ClampedIntNegFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f (EmptyCtx ::> BaseBVType w) (BaseBVType w)
[ClampedIntAbsFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f (EmptyCtx ::> BaseBVType w) (BaseBVType w)
[ClampedIntAddFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f ((EmptyCtx ::> BaseBVType w) ::> BaseBVType w) (BaseBVType w)
[ClampedIntSubFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f ((EmptyCtx ::> BaseBVType w) ::> BaseBVType w) (BaseBVType w)
[ClampedIntMulFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f ((EmptyCtx ::> BaseBVType w) ::> BaseBVType w) (BaseBVType w)
[ClampedUIntAddFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f ((EmptyCtx ::> BaseBVType w) ::> BaseBVType w) (BaseBVType w)
[ClampedUIntSubFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f ((EmptyCtx ::> BaseBVType w) ::> BaseBVType w) (BaseBVType w)
[ClampedUIntMulFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f ((EmptyCtx ::> BaseBVType w) ::> BaseBVType w) (BaseBVType w)
[IntSetWidthFn] :: (1 <= m, 1 <= n) => !NatRepr m -> !NatRepr n -> MatlabSolverFn f (EmptyCtx ::> BaseBVType m) (BaseBVType n)
[UIntSetWidthFn] :: (1 <= m, 1 <= n) => !NatRepr m -> !NatRepr n -> MatlabSolverFn f (EmptyCtx ::> BaseBVType m) (BaseBVType n)
[UIntToIntFn] :: (1 <= m, 1 <= n) => !NatRepr m -> !NatRepr n -> MatlabSolverFn f (EmptyCtx ::> BaseBVType m) (BaseBVType n)
[IntToUIntFn] :: (1 <= m, 1 <= n) => !NatRepr m -> !NatRepr n -> MatlabSolverFn f (EmptyCtx ::> BaseBVType m) (BaseBVType n)
[RealIsNonZeroFn] :: MatlabSolverFn f (EmptyCtx ::> BaseRealType) BaseBoolType
[RealCosFn] :: MatlabSolverFn f (EmptyCtx ::> BaseRealType) BaseRealType
[RealSinFn] :: MatlabSolverFn f (EmptyCtx ::> BaseRealType) BaseRealType
[RealToSBVFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f (EmptyCtx ::> BaseRealType) (BaseBVType w)
[RealToUBVFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f (EmptyCtx ::> BaseRealType) (BaseBVType w)
[PredToBVFn] :: 1 <= w => !NatRepr w -> MatlabSolverFn f (EmptyCtx ::> BaseBoolType) (BaseBVType w)
[CplxIsNonZeroFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseBoolType
[CplxIsRealFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseBoolType
[RealToComplexFn] :: MatlabSolverFn f (EmptyCtx ::> BaseRealType) BaseComplexType
[RealPartOfCplxFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseRealType
[ImagPartOfCplxFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseRealType
[CplxNegFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
[CplxAddFn] :: MatlabSolverFn f ((EmptyCtx ::> BaseComplexType) ::> BaseComplexType) BaseComplexType
[CplxSubFn] :: MatlabSolverFn f ((EmptyCtx ::> BaseComplexType) ::> BaseComplexType) BaseComplexType
[CplxMulFn] :: MatlabSolverFn f ((EmptyCtx ::> BaseComplexType) ::> BaseComplexType) BaseComplexType
[CplxRoundFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
[CplxFloorFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
[CplxCeilFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
[CplxMagFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseRealType
[CplxSqrtFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
[CplxExpFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
[CplxLogFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
[CplxLogBaseFn] :: !Integer -> MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
[CplxSinFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
[CplxCosFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType
[CplxTanFn] :: MatlabSolverFn f (EmptyCtx ::> BaseComplexType) BaseComplexType

-- | Get arg tpyes of solver fn.
matlabSolverArgTypes :: MatlabSolverFn f args ret -> Assignment BaseTypeRepr args

-- | Get return type of solver fn.
matlabSolverReturnType :: MatlabSolverFn f args ret -> BaseTypeRepr ret
ppMatlabSolverFn :: IsExpr f => MatlabSolverFn f a r -> Doc ann
evalMatlabSolverFn :: forall sym args ret. IsExprBuilder sym => MatlabSolverFn (SymExpr sym) args ret -> sym -> Assignment (SymExpr sym) args -> IO (SymExpr sym ret)

-- | Test MatlabSolverFn values for equality.
testSolverFnEq :: TestEquality f => MatlabSolverFn f ax rx -> MatlabSolverFn f ay ry -> Maybe ((ax ::> rx) :~: (ay ::> ry))
traverseMatlabSolverFn :: Applicative m => (forall tp. e tp -> m (f tp)) -> MatlabSolverFn e a r -> m (MatlabSolverFn f a r)

-- | This class is provides functions needed to implement the symbolic
--   array intrinsic functions
class IsSymExprBuilder sym => MatlabSymbolicArrayBuilder sym

-- | Create a Matlab solver function from its prototype.
mkMatlabSolverFn :: MatlabSymbolicArrayBuilder sym => sym -> MatlabSolverFn (SymExpr sym) args ret -> IO (SymFn sym args ret)
clampedIntAdd :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)
clampedIntSub :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)
clampedIntMul :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)

-- | Compute the clamped negation of a signed bitvector.
--   
--   The only difference between this operation and the usual 2's
--   complement negation function is the handling of MIN_INT. The usual 2's
--   complement negation sends MIN_INT to MIN_INT; however, the clamped
--   version instead sends MIN_INT to MAX_INT.
clampedIntNeg :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (SymBV sym w)

-- | Compute the clamped absolute value of a signed bitvector.
--   
--   The only difference between this operation and the usual 2's
--   complement operation is the handling of MIN_INT. The usual 2's
--   complement absolute value function sends MIN_INT to MIN_INT; however,
--   the clamped version instead sends MIN_INT to MAX_INT.
clampedIntAbs :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> IO (SymBV sym w)
clampedUIntAdd :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)
clampedUIntSub :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)
clampedUIntMul :: (IsExprBuilder sym, 1 <= w) => sym -> SymBV sym w -> SymBV sym w -> IO (SymBV sym w)
instance Data.Type.Equality.TestEquality f => GHC.Classes.Eq (What4.Expr.MATLAB.MatlabSolverFn f args tp)
instance (Data.Hashable.Class.Hashable (f What4.BaseTypes.BaseRealType), Data.Hashable.Class.Hashable (f What4.BaseTypes.BaseIntegerType), Data.Parameterized.Classes.HashableF f, Data.Type.Equality.TestEquality f) => Data.Hashable.Class.Hashable (What4.Expr.MATLAB.MatlabSolverFn f args tp)

-- | This module defines datastructures that encode the basic syntax
--   formers used in What4.ExprBuilder.
module What4.Expr.App

-- | This type represents Expr values that were built from a
--   NonceApp.
--   
--   Parameter t is a phantom type brand used to track nonces.
--   
--   Selector functions are provided to destruct NonceAppExpr
--   values, but the constructor is kept hidden. The preferred way to
--   construct an Expr from a NonceApp is to use
--   sbNonceExpr.
data NonceAppExpr t (tp :: BaseType)
NonceAppExprCtor :: {-# UNPACK #-} !Nonce t tp -> !ProgramLoc -> !NonceApp t (Expr t) tp -> !AbstractValue tp -> NonceAppExpr t (tp :: BaseType)
[nonceExprId] :: NonceAppExpr t (tp :: BaseType) -> {-# UNPACK #-} !Nonce t tp
[nonceExprLoc] :: NonceAppExpr t (tp :: BaseType) -> !ProgramLoc
[nonceExprApp] :: NonceAppExpr t (tp :: BaseType) -> !NonceApp t (Expr t) tp
[nonceExprAbsValue] :: NonceAppExpr t (tp :: BaseType) -> !AbstractValue tp

-- | This type represents Expr values that were built from an
--   App.
--   
--   Parameter t is a phantom type brand used to track nonces.
--   
--   Selector functions are provided to destruct AppExpr values, but
--   the constructor is kept hidden. The preferred way to construct an
--   Expr from an App is to use sbMakeExpr.
data AppExpr t (tp :: BaseType)
AppExprCtor :: {-# UNPACK #-} !Nonce t tp -> !ProgramLoc -> !App (Expr t) tp -> !AbstractValue tp -> AppExpr t (tp :: BaseType)
[appExprId] :: AppExpr t (tp :: BaseType) -> {-# UNPACK #-} !Nonce t tp
[appExprLoc] :: AppExpr t (tp :: BaseType) -> !ProgramLoc
[appExprApp] :: AppExpr t (tp :: BaseType) -> !App (Expr t) tp
[appExprAbsValue] :: AppExpr t (tp :: BaseType) -> !AbstractValue tp

-- | The main ExprBuilder expression datastructure. The non-trivial
--   Expr values constructed by this module are uniquely
--   identified by a nonce value that is used to explicitly represent
--   sub-term sharing. When traversing the structure of an Expr it
--   is usually very important to memoize computations based on the values
--   of these identifiers to avoid exponential blowups due to shared term
--   structure.
--   
--   Type parameter t is a phantom type brand used to relate
--   nonces to a specific nonce generator (similar to the s
--   parameter of the ST monad). The type index tp of
--   kind BaseType indicates the type of the values denoted by the
--   given expression.
--   
--   Type Expr t instantiates the type family
--   SymExpr (ExprBuilder t st).
data Expr t (tp :: BaseType)
[SemiRingLiteral] :: !SemiRingRepr sr -> !Coefficient sr -> !ProgramLoc -> Expr t (SemiRingBase sr)
[BoolExpr] :: !Bool -> !ProgramLoc -> Expr t BaseBoolType
[FloatExpr] :: !FloatPrecisionRepr fpp -> !BigFloat -> !ProgramLoc -> Expr t (BaseFloatType fpp)
[StringExpr] :: !StringLiteral si -> !ProgramLoc -> Expr t (BaseStringType si)
[AppExpr] :: {-# UNPACK #-} !AppExpr t tp -> Expr t tp
[NonceAppExpr] :: {-# UNPACK #-} !NonceAppExpr t tp -> Expr t tp
[BoundVarExpr] :: !ExprBoundVar t tp -> Expr t tp
data BVOrNote w
BVOrNote :: !IncrHash -> !BVDomain w -> BVOrNote w
newtype BVOrSet e w
BVOrSet :: AnnotatedMap (Wrap e (BaseBVType w)) (BVOrNote w) () -> BVOrSet e w

-- | Type App e tp encodes the top-level application of an
--   Expr expression. It includes first-order expression forms that
--   do not bind variables (contrast with NonceApp).
--   
--   Parameter e is used everywhere a recursive sub-expression
--   would go. Uses of the App type will tie the knot through this
--   parameter. Parameter tp indicates the type of the expression.
data App (e :: BaseType -> Type) (tp :: BaseType)
[BaseIte] :: !BaseTypeRepr tp -> !Integer -> !e BaseBoolType -> !e tp -> !e tp -> App e tp
[BaseEq] :: !BaseTypeRepr tp -> !e tp -> !e tp -> App e BaseBoolType
[NotPred] :: !e BaseBoolType -> App e BaseBoolType
[ConjPred] :: !BoolMap e -> App e BaseBoolType
[SemiRingSum] :: {-# UNPACK #-} !WeightedSum e sr -> App e (SemiRingBase sr)
[SemiRingProd] :: {-# UNPACK #-} !SemiRingProduct e sr -> App e (SemiRingBase sr)
[SemiRingLe] :: !OrderedSemiRingRepr sr -> !e (SemiRingBase sr) -> !e (SemiRingBase sr) -> App e BaseBoolType
[RealIsInteger] :: !e BaseRealType -> App e BaseBoolType
[IntDiv] :: !e BaseIntegerType -> !e BaseIntegerType -> App e BaseIntegerType
[IntMod] :: !e BaseIntegerType -> !e BaseIntegerType -> App e BaseIntegerType
[IntAbs] :: !e BaseIntegerType -> App e BaseIntegerType
[IntDivisible] :: !e BaseIntegerType -> Natural -> App e BaseBoolType
[RealDiv] :: !e BaseRealType -> !e BaseRealType -> App e BaseRealType
[RealSqrt] :: !e BaseRealType -> App e BaseRealType
[RealSpecialFunction] :: !SpecialFunction args -> !SpecialFnArgs e BaseRealType args -> App e BaseRealType
[BVTestBit] :: 1 <= w => !Natural -> !e (BaseBVType w) -> App e BaseBoolType
[BVSlt] :: 1 <= w => !e (BaseBVType w) -> !e (BaseBVType w) -> App e BaseBoolType
[BVUlt] :: 1 <= w => !e (BaseBVType w) -> !e (BaseBVType w) -> App e BaseBoolType
[BVOrBits] :: 1 <= w => !NatRepr w -> !BVOrSet e w -> App e (BaseBVType w)
[BVUnaryTerm] :: 1 <= n => !UnaryBV (e BaseBoolType) n -> App e (BaseBVType n)
[BVConcat] :: (1 <= u, 1 <= v, 1 <= (u + v)) => !NatRepr (u + v) -> !e (BaseBVType u) -> !e (BaseBVType v) -> App e (BaseBVType (u + v))
[BVSelect] :: (1 <= n, (idx + n) <= w) => !NatRepr idx -> !NatRepr n -> !e (BaseBVType w) -> App e (BaseBVType n)
[BVFill] :: 1 <= w => !NatRepr w -> !e BaseBoolType -> App e (BaseBVType w)
[BVUdiv] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVUrem] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVSdiv] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVSrem] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVShl] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVLshr] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVAshr] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVRol] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVRor] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVZext] :: (1 <= w, (w + 1) <= r, 1 <= r) => !NatRepr r -> !e (BaseBVType w) -> App e (BaseBVType r)
[BVSext] :: (1 <= w, (w + 1) <= r, 1 <= r) => !NatRepr r -> !e (BaseBVType w) -> App e (BaseBVType r)
[BVPopcount] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVCountTrailingZeros] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVCountLeadingZeros] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> App e (BaseBVType w)
[FloatNeg] :: !FloatPrecisionRepr fpp -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatAbs] :: !FloatPrecisionRepr fpp -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatSqrt] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatAdd] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatSub] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatMul] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatDiv] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatRem] :: !FloatPrecisionRepr fpp -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatFMA] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatFpEq] :: !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatLe] :: !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatLt] :: !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsNaN] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsInf] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsZero] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsPos] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsNeg] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsSubnorm] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsNorm] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatCast] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp') -> App e (BaseFloatType fpp)
[FloatRound] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatFromBinary] :: (2 <= eb, 2 <= sb) => !FloatPrecisionRepr (FloatingPointPrecision eb sb) -> !e (BaseBVType (eb + sb)) -> App e (BaseFloatType (FloatingPointPrecision eb sb))
[FloatToBinary] :: (2 <= eb, 2 <= sb, 1 <= (eb + sb)) => !FloatPrecisionRepr (FloatingPointPrecision eb sb) -> !e (BaseFloatType (FloatingPointPrecision eb sb)) -> App e (BaseBVType (eb + sb))
[BVToFloat] :: 1 <= w => !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseBVType w) -> App e (BaseFloatType fpp)
[SBVToFloat] :: 1 <= w => !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseBVType w) -> App e (BaseFloatType fpp)
[RealToFloat] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e BaseRealType -> App e (BaseFloatType fpp)
[FloatToBV] :: 1 <= w => !NatRepr w -> !RoundingMode -> !e (BaseFloatType fpp) -> App e (BaseBVType w)
[FloatToSBV] :: 1 <= w => !NatRepr w -> !RoundingMode -> !e (BaseFloatType fpp) -> App e (BaseBVType w)
[FloatToReal] :: !e (BaseFloatType fpp) -> App e BaseRealType
[FloatSpecialFunction] :: !FloatPrecisionRepr fpp -> !SpecialFunction args -> !SpecialFnArgs e (BaseFloatType fpp) args -> App e (BaseFloatType fpp)
[ArrayMap] :: !Assignment BaseTypeRepr (i ::> itp) -> !BaseTypeRepr tp -> !ArrayUpdateMap e (i ::> itp) tp -> !e (BaseArrayType (i ::> itp) tp) -> App e (BaseArrayType (i ::> itp) tp)
[ConstantArray] :: !Assignment BaseTypeRepr (i ::> tp) -> !BaseTypeRepr b -> !e b -> App e (BaseArrayType (i ::> tp) b)
[UpdateArray] :: !BaseTypeRepr b -> !Assignment BaseTypeRepr (i ::> tp) -> !e (BaseArrayType (i ::> tp) b) -> !Assignment e (i ::> tp) -> !e b -> App e (BaseArrayType (i ::> tp) b)
[SelectArray] :: !BaseTypeRepr b -> !e (BaseArrayType (i ::> tp) b) -> !Assignment e (i ::> tp) -> App e b
[CopyArray] :: 1 <= w => !NatRepr w -> !BaseTypeRepr a -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e (BaseBVType w) -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseArrayType (SingleCtx (BaseBVType w)) a)
[SetArray] :: 1 <= w => !NatRepr w -> !BaseTypeRepr a -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e a -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseArrayType (SingleCtx (BaseBVType w)) a)
[EqualArrayRange] :: 1 <= w => !NatRepr w -> !BaseTypeRepr a -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e (BaseBVType w) -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e BaseBoolType
[IntegerToReal] :: !e BaseIntegerType -> App e BaseRealType
[RealToInteger] :: !e BaseRealType -> App e BaseIntegerType
[BVToInteger] :: 1 <= w => !e (BaseBVType w) -> App e BaseIntegerType
[SBVToInteger] :: 1 <= w => !e (BaseBVType w) -> App e BaseIntegerType
[IntegerToBV] :: 1 <= w => !e BaseIntegerType -> NatRepr w -> App e (BaseBVType w)
[RoundReal] :: !e BaseRealType -> App e BaseIntegerType
[RoundEvenReal] :: !e BaseRealType -> App e BaseIntegerType
[FloorReal] :: !e BaseRealType -> App e BaseIntegerType
[CeilReal] :: !e BaseRealType -> App e BaseIntegerType
[Cplx] :: {-# UNPACK #-} !Complex (e BaseRealType) -> App e BaseComplexType
[RealPart] :: !e BaseComplexType -> App e BaseRealType
[ImagPart] :: !e BaseComplexType -> App e BaseRealType
[StringContains] :: !e (BaseStringType si) -> !e (BaseStringType si) -> App e BaseBoolType
[StringIsPrefixOf] :: !e (BaseStringType si) -> !e (BaseStringType si) -> App e BaseBoolType
[StringIsSuffixOf] :: !e (BaseStringType si) -> !e (BaseStringType si) -> App e BaseBoolType
[StringIndexOf] :: !e (BaseStringType si) -> !e (BaseStringType si) -> !e BaseIntegerType -> App e BaseIntegerType
[StringSubstring] :: !StringInfoRepr si -> !e (BaseStringType si) -> !e BaseIntegerType -> !e BaseIntegerType -> App e (BaseStringType si)
[StringAppend] :: !StringInfoRepr si -> !StringSeq e si -> App e (BaseStringType si)
[StringLength] :: !e (BaseStringType si) -> App e BaseIntegerType
[StructCtor] :: !Assignment BaseTypeRepr flds -> !Assignment e flds -> App e (BaseStructType flds)
[StructField] :: !e (BaseStructType flds) -> !Index flds tp -> !BaseTypeRepr tp -> App e tp

-- | The Kind of a bound variable.
data VarKind

-- | A variable appearing in a quantifier.
QuantifierVarKind :: VarKind

-- | A variable appearing as a latch input.
LatchVarKind :: VarKind

-- | A variable appearing in a uninterpreted constant
UninterpVarKind :: VarKind

-- | Information about bound variables. Parameter t is a phantom
--   type brand used to track nonces.
--   
--   Type ExprBoundVar t instantiates the type family
--   BoundVar (ExprBuilder t st).
--   
--   Selector functions are provided to destruct ExprBoundVar
--   values, but the constructor is kept hidden. The preferred way to
--   construct a ExprBoundVar is to use freshBoundVar.
data ExprBoundVar t (tp :: BaseType)
BVar :: {-# UNPACK #-} !Nonce t tp -> !ProgramLoc -> !SolverSymbol -> !BaseTypeRepr tp -> !VarKind -> !Maybe (AbstractValue tp) -> ExprBoundVar t (tp :: BaseType)
[bvarId] :: ExprBoundVar t (tp :: BaseType) -> {-# UNPACK #-} !Nonce t tp
[bvarLoc] :: ExprBoundVar t (tp :: BaseType) -> !ProgramLoc
[bvarName] :: ExprBoundVar t (tp :: BaseType) -> !SolverSymbol
[bvarType] :: ExprBoundVar t (tp :: BaseType) -> !BaseTypeRepr tp
[bvarKind] :: ExprBoundVar t (tp :: BaseType) -> !VarKind
[bvarAbstractValue] :: ExprBoundVar t (tp :: BaseType) -> !Maybe (AbstractValue tp)

-- | Type NonceApp t e tp encodes the top-level application of an
--   Expr. It includes expression forms that bind variables
--   (contrast with App).
--   
--   Parameter t is a phantom type brand used to track nonces.
--   Parameter e is used everywhere a recursive sub-expression
--   would go. Uses of the NonceApp type will tie the knot through
--   this parameter. Parameter tp indicates the type of the
--   expression.
data NonceApp t (e :: BaseType -> Type) (tp :: BaseType)
[Annotation] :: !BaseTypeRepr tp -> !Nonce t tp -> !e tp -> NonceApp t e tp
[Forall] :: !ExprBoundVar t tp -> !e BaseBoolType -> NonceApp t e BaseBoolType
[Exists] :: !ExprBoundVar t tp -> !e BaseBoolType -> NonceApp t e BaseBoolType
[ArrayFromFn] :: !ExprSymFn t (idx ::> itp) ret -> NonceApp t e (BaseArrayType (idx ::> itp) ret)
[MapOverArrays] :: !ExprSymFn t (ctx ::> d) r -> !Assignment BaseTypeRepr (idx ::> itp) -> !Assignment (ArrayResultWrapper e (idx ::> itp)) (ctx ::> d) -> NonceApp t e (BaseArrayType (idx ::> itp) r)
[ArrayTrueOnEntries] :: !ExprSymFn t (idx ::> itp) BaseBoolType -> !e (BaseArrayType (idx ::> itp) BaseBoolType) -> NonceApp t e BaseBoolType
[FnApp] :: !ExprSymFn t args ret -> !Assignment e args -> NonceApp t e ret

-- | This describes information about an undefined or defined function.
--   Parameter t is a phantom type brand used to track nonces. The
--   args and ret parameters define the types of
--   arguments and the return type of the function.
data SymFnInfo t (args :: Ctx BaseType) (ret :: BaseType)

-- | Information about the argument type and return type of an
--   uninterpreted function.
UninterpFnInfo :: !Assignment BaseTypeRepr args -> !BaseTypeRepr ret -> SymFnInfo t (args :: Ctx BaseType) (ret :: BaseType)

-- | Information about a defined function. Includes bound variables and an
--   expression associated to a defined function, as well as a policy for
--   when to unfold the body.
DefinedFnInfo :: !Assignment (ExprBoundVar t) args -> !Expr t ret -> !UnfoldPolicy -> SymFnInfo t (args :: Ctx BaseType) (ret :: BaseType)

-- | This is a function that corresponds to a matlab solver function. It
--   includes the definition as a ExprBuilder expr to enable export to
--   other solvers.
MatlabSolverFnInfo :: !MatlabSolverFn (Expr t) args ret -> !Assignment (ExprBoundVar t) args -> !Expr t ret -> SymFnInfo t (args :: Ctx BaseType) (ret :: BaseType)

-- | This represents a symbolic function in the simulator. Parameter
--   t is a phantom type brand used to track nonces. The
--   args and ret parameters define the types of
--   arguments and the return type of the function.
--   
--   Type ExprSymFn t (Expr t) instantiates the type family
--   SymFn (ExprBuilder t st).
data ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType)
ExprSymFn :: !Nonce t (args ::> ret) -> !SolverSymbol -> !SymFnInfo t args ret -> !ProgramLoc -> ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType)
[symFnId] :: ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType) -> !Nonce t (args ::> ret)
[symFnName] :: ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType) -> !SolverSymbol
[symFnInfo] :: ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType) -> !SymFnInfo t args ret
[symFnLoc] :: ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType) -> !ProgramLoc

-- | Used to implement foldMapFc from traversal.
data Dummy (tp :: k)
traverseApp :: (Applicative m, OrdF f, Eq (f BaseBoolType), HashableF f, HasAbsValue f) => (forall tp. e tp -> m (f tp)) -> App e utp -> m (App f utp)

-- | Check if two applications are equal.
appEqF :: (Eq (e BaseBoolType), Eq (e BaseRealType), HashableF e, HasAbsValue e, OrdF e) => App e x -> App e y -> Maybe (x :~: y)

-- | Hash an an application.
hashApp :: (OrdF e, HashableF e, HasAbsValue e, Hashable (e BaseBoolType), Hashable (e BaseRealType)) => Int -> App e s -> Int

-- | Return true if an app represents a non-linear operation.
--   Controls whether the non-linear counter ticks upward in the
--   Statistics.
isNonLinearApp :: App e tp -> Bool
traverseArrayResultWrapper :: Functor m => (forall tp. e tp -> m (f tp)) -> ArrayResultWrapper e (idx ::> itp) c -> m (ArrayResultWrapper f (idx ::> itp) c)
traverseArrayResultWrapperAssignment :: Applicative m => (forall tp. e tp -> m (f tp)) -> Assignment (ArrayResultWrapper e (idx ::> itp)) c -> m (Assignment (ArrayResultWrapper f (idx ::> itp)) c)

-- | Destructor for the AppExpr constructor.
asApp :: Expr t tp -> Maybe (App (Expr t) tp)

-- | Destructor for the NonceAppExpr constructor.
asNonceApp :: Expr t tp -> Maybe (NonceApp t (Expr t) tp)
exprLoc :: Expr t tp -> ProgramLoc
mkExpr :: Nonce t tp -> ProgramLoc -> App (Expr t) tp -> AbstractValue tp -> Expr t tp
type BoolExpr t = Expr t BaseBoolType
type FloatExpr t fpp = Expr t (BaseFloatType fpp)
type BVExpr t n = Expr t (BaseBVType n)
type IntegerExpr t = Expr t BaseIntegerType
type RealExpr t = Expr t BaseRealType
type CplxExpr t = Expr t BaseComplexType
type StringExpr t si = Expr t (BaseStringType si)
iteSize :: Expr t tp -> Integer
asSemiRingLit :: SemiRingRepr sr -> Expr t (SemiRingBase sr) -> Maybe (Coefficient sr)
asSemiRingSum :: SemiRingRepr sr -> Expr t (SemiRingBase sr) -> Maybe (WeightedSum (Expr t) sr)
asSemiRingProd :: SemiRingRepr sr -> Expr t (SemiRingBase sr) -> Maybe (SemiRingProduct (Expr t) sr)

-- | This privides a view of a semiring expr as a weighted sum of values.
data SemiRingView t sr
SR_Constant :: !Coefficient sr -> SemiRingView t sr
SR_Sum :: !WeightedSum (Expr t) sr -> SemiRingView t sr
SR_Prod :: !SemiRingProduct (Expr t) sr -> SemiRingView t sr
SR_General :: SemiRingView t sr
viewSemiRing :: SemiRingRepr sr -> Expr t (SemiRingBase sr) -> SemiRingView t sr
asWeightedSum :: HashableF (Expr t) => SemiRingRepr sr -> Expr t (SemiRingBase sr) -> WeightedSum (Expr t) sr
asConjunction :: Expr t BaseBoolType -> [(Expr t BaseBoolType, Polarity)]
asDisjunction :: Expr t BaseBoolType -> [(Expr t BaseBoolType, Polarity)]
asPosAtom :: Expr t BaseBoolType -> (Expr t BaseBoolType, Polarity)
asNegAtom :: Expr t BaseBoolType -> (Expr t BaseBoolType, Polarity)

-- | Get abstract value associated with element.
exprAbsValue :: Expr t tp -> AbstractValue tp
compareExpr :: Expr t x -> Expr t y -> OrderingF x y

-- | A slightly more aggressive syntactic equality check than testEquality,
--   sameTerm will recurse through a small collection of known
--   syntax formers.
sameTerm :: Expr t a -> Expr t b -> Maybe (a :~: b)
data PPIndex
ExprPPIndex :: {-# UNPACK #-} !Word64 -> PPIndex
RatPPIndex :: !Rational -> PPIndex
countOccurrences :: Expr t tp -> Map PPIndex Int
type OccurrenceTable s = HashTable s PPIndex Int
incOccurrence :: OccurrenceTable s -> PPIndex -> ST s () -> ST s ()
countOccurrences' :: forall t tp s. OccurrenceTable s -> Expr t tp -> ST s ()
type BoundVarMap s t = HashTable s PPIndex (Set (Some (ExprBoundVar t)))
cache :: (Eq k, Hashable k) => HashTable s k r -> k -> ST s r -> ST s r
boundVars :: Expr t tp -> ST s (BoundVarMap s t)
boundVars' :: BoundVarMap s t -> Expr t tp -> ST s (Set (Some (ExprBoundVar t)))

-- | AppPPExpr represents a an application, and it may be let
--   bound.
data AppPPExpr ann
APE :: !PPIndex -> !ProgramLoc -> !Text -> ![PPExpr ann] -> !Int -> AppPPExpr ann
[apeIndex] :: AppPPExpr ann -> !PPIndex
[apeLoc] :: AppPPExpr ann -> !ProgramLoc
[apeName] :: AppPPExpr ann -> !Text
[apeExprs] :: AppPPExpr ann -> ![PPExpr ann]

-- | Length of AppPPExpr not including parenthesis.
[apeLength] :: AppPPExpr ann -> !Int
data PPExpr ann

-- | A fixed doc with length.
FixedPPExpr :: !Doc ann -> ![Doc ann] -> !Int -> PPExpr ann

-- | A doc that can be let bound.
AppPPExpr :: !AppPPExpr ann -> PPExpr ann

-- | Pretty print a AppPPExpr
apeDoc :: AppPPExpr ann -> (Doc ann, [Doc ann])
textPPExpr :: Text -> PPExpr ann
stringPPExpr :: String -> PPExpr ann

-- | Get length of Expr including parens.
ppExprLength :: PPExpr ann -> Int
parenIf :: Bool -> Doc ann -> [Doc ann] -> Doc ann

-- | Pretty print PPExpr
ppExprDoc :: Bool -> PPExpr ann -> Doc ann
data PPExprOpts
PPExprOpts :: Int -> Bool -> PPExprOpts
[ppExpr_maxWidth] :: PPExprOpts -> Int
[ppExpr_useDecimal] :: PPExprOpts -> Bool
defaultPPExprOpts :: PPExprOpts

-- | Pretty print an Expr using let bindings to create the term.
ppExpr :: Expr t tp -> Doc ann

-- | Pretty print the top part of an element.
ppExprTop :: Expr t tp -> Doc ann

-- | Contains the elements before, the index, doc, and width and the
--   elements after.
type SplitPPExprList ann = Maybe ([PPExpr ann], AppPPExpr ann, [PPExpr ann])
findExprToRemove :: [PPExpr ann] -> SplitPPExprList ann
ppExpr' :: forall t tp s ann. Expr t tp -> PPExprOpts -> ST s ([Doc ann], PPExpr ann)
symFnArgTypes :: ExprSymFn t args ret -> Assignment BaseTypeRepr args
symFnReturnType :: ExprSymFn t args ret -> BaseTypeRepr ret

-- | Return solver function associated with ExprSymFn if any.
asMatlabSolverFn :: ExprSymFn t args ret -> Maybe (MatlabSolverFn (Expr t) args ret)
testExprSymFnEq :: ExprSymFn t a1 r1 -> ExprSymFn t a2 r2 -> Maybe ((a1 ::> r1) :~: (a2 ::> r2))
traverseBVOrSet :: (HashableF f, HasAbsValue f, OrdF f, Applicative m) => (forall tp. e tp -> m (f tp)) -> BVOrSet e w -> m (BVOrSet f w)
bvOrInsert :: (OrdF e, HashableF e, HasAbsValue e) => e (BaseBVType w) -> BVOrSet e w -> BVOrSet e w
bvOrSingleton :: (OrdF e, HashableF e, HasAbsValue e) => e (BaseBVType w) -> BVOrSet e w
bvOrContains :: OrdF e => e (BaseBVType w) -> BVOrSet e w -> Bool
bvOrUnion :: OrdF e => BVOrSet e w -> BVOrSet e w -> BVOrSet e w
bvOrToList :: BVOrSet e w -> [e (BaseBVType w)]
bvOrAbs :: (OrdF e, 1 <= w) => NatRepr w -> BVOrSet e w -> BVDomain w
nonceAppType :: IsExpr e => NonceApp t e tp -> BaseTypeRepr tp
appType :: App e tp -> BaseTypeRepr tp

-- | Return an unconstrained abstract value.
unconstrainedAbsValue :: BaseTypeRepr tp -> AbstractValue tp

-- | Return abstract domain associated with a nonce app
quantAbsEval :: IsExpr e => (forall u. e u -> AbstractValue u) -> NonceApp t e tp -> AbstractValue tp
abstractEval :: (IsExpr e, HashableF e, OrdF e) => (forall u. e u -> AbstractValue u) -> App e tp -> AbstractValue tp
reduceApp :: IsExprBuilder sym => sym -> (forall w. 1 <= w => sym -> UnaryBV (Pred sym) w -> IO (SymExpr sym (BaseBVType w))) -> App (SymExpr sym) tp -> IO (SymExpr sym tp)
ppVar :: String -> SolverSymbol -> Nonce t tp -> BaseTypeRepr tp -> String
ppBoundVar :: ExprBoundVar t tp -> String

-- | Pretty print a code to identify the type of constant.
ppVarTypeCode :: BaseTypeRepr tp -> String

-- | Either a argument or text or text
data PrettyArg (e :: BaseType -> Type)
[PrettyArg] :: e tp -> PrettyArg e
[PrettyText] :: Text -> PrettyArg e
[PrettyFunc] :: Text -> [PrettyArg e] -> PrettyArg e
exprPrettyArg :: e tp -> PrettyArg e
exprPrettyIndices :: Assignment e ctx -> [PrettyArg e]
stringPrettyArg :: String -> PrettyArg e
showPrettyArg :: Show a => a -> PrettyArg e
type PrettyApp e = (Text, [PrettyArg e])
prettyApp :: Text -> [PrettyArg e] -> PrettyApp e
ppNonceApp :: forall m t e tp. Applicative m => (forall ctx r. ExprSymFn t ctx r -> m (PrettyArg e)) -> NonceApp t e tp -> m (PrettyApp e)
ppApp' :: forall e u. App e u -> PrettyApp e
instance GHC.Generics.Generic What4.Expr.App.PPIndex
instance GHC.Classes.Ord What4.Expr.App.PPIndex
instance GHC.Classes.Eq What4.Expr.App.PPIndex
instance Data.Parameterized.Classes.ShowF e => Prettyprinter.Internal.Pretty (What4.Expr.App.App e u)
instance Data.Hashable.Class.Hashable What4.Expr.App.PPIndex
instance forall k (tp :: k). GHC.Classes.Eq (What4.Expr.App.Dummy tp)
instance Data.Parameterized.Classes.EqF What4.Expr.App.Dummy
instance Data.Type.Equality.TestEquality What4.Expr.App.Dummy
instance forall k (tp :: k). GHC.Classes.Ord (What4.Expr.App.Dummy tp)
instance Data.Parameterized.Classes.OrdF What4.Expr.App.Dummy
instance Data.Parameterized.Classes.HashableF What4.Expr.App.Dummy
instance What4.Utils.AbstractDomains.HasAbsValue What4.Expr.App.Dummy
instance Data.Parameterized.TraversableFC.FoldableFC What4.Expr.App.App
instance (GHC.Classes.Eq (e What4.BaseTypes.BaseBoolType), GHC.Classes.Eq (e What4.BaseTypes.BaseRealType), Data.Parameterized.Classes.HashableF e, What4.Utils.AbstractDomains.HasAbsValue e, Data.Parameterized.Classes.OrdF e) => GHC.Classes.Eq (What4.Expr.App.App e tp)
instance (GHC.Classes.Eq (e What4.BaseTypes.BaseBoolType), GHC.Classes.Eq (e What4.BaseTypes.BaseRealType), Data.Parameterized.Classes.HashableF e, What4.Utils.AbstractDomains.HasAbsValue e, Data.Parameterized.Classes.OrdF e) => Data.Type.Equality.TestEquality (What4.Expr.App.App e)
instance (Data.Parameterized.Classes.OrdF e, Data.Parameterized.Classes.HashableF e, What4.Utils.AbstractDomains.HasAbsValue e, Data.Hashable.Class.Hashable (e What4.BaseTypes.BaseBoolType), Data.Hashable.Class.Hashable (e What4.BaseTypes.BaseRealType)) => Data.Parameterized.Classes.HashableF (What4.Expr.App.App e)
instance Data.Type.Equality.TestEquality e => GHC.Classes.Eq (What4.Expr.App.NonceApp t e tp)
instance Data.Type.Equality.TestEquality e => Data.Type.Equality.TestEquality (What4.Expr.App.NonceApp t e)
instance (Data.Parameterized.Classes.HashableF e, Data.Type.Equality.TestEquality e) => Data.Parameterized.Classes.HashableF (What4.Expr.App.NonceApp t e)
instance Data.Parameterized.TraversableFC.FunctorFC (What4.Expr.App.NonceApp t)
instance Data.Parameterized.TraversableFC.FoldableFC (What4.Expr.App.NonceApp t)
instance Data.Parameterized.TraversableFC.TraversableFC (What4.Expr.App.NonceApp t)
instance Data.Parameterized.Classes.PolyEq (What4.Expr.App.Expr t x) (What4.Expr.App.Expr t y)
instance What4.Interface.IsExpr (What4.Expr.App.Expr t)
instance What4.Utils.AbstractDomains.HasAbsValue (What4.Expr.App.Expr t)
instance Data.Type.Equality.TestEquality (What4.Expr.App.NonceAppExpr t)
instance Data.Parameterized.Classes.OrdF (What4.Expr.App.NonceAppExpr t)
instance GHC.Classes.Eq (What4.Expr.App.NonceAppExpr t tp)
instance GHC.Classes.Ord (What4.Expr.App.NonceAppExpr t tp)
instance Data.Type.Equality.TestEquality (What4.Expr.App.Expr t)
instance Data.Parameterized.Classes.OrdF (What4.Expr.App.Expr t)
instance GHC.Classes.Eq (What4.Expr.App.Expr t tp)
instance GHC.Classes.Ord (What4.Expr.App.Expr t tp)
instance Data.Hashable.Class.Hashable (What4.Expr.App.Expr t tp)
instance Data.Parameterized.Classes.HashableF (What4.Expr.App.Expr t)
instance GHC.Show.Show (What4.Expr.App.Expr t tp)
instance Prettyprinter.Internal.Pretty (What4.Expr.App.Expr t tp)
instance Data.Parameterized.Classes.ShowF (What4.Expr.App.Expr t)
instance GHC.Classes.Eq (What4.Expr.App.ExprBoundVar t tp)
instance Data.Type.Equality.TestEquality (What4.Expr.App.ExprBoundVar t)
instance GHC.Classes.Ord (What4.Expr.App.ExprBoundVar t tp)
instance Data.Parameterized.Classes.OrdF (What4.Expr.App.ExprBoundVar t)
instance Data.Hashable.Class.Hashable (What4.Expr.App.ExprBoundVar t tp)
instance Data.Parameterized.Classes.HashableF (What4.Expr.App.ExprBoundVar t)
instance GHC.Show.Show (What4.Expr.App.ExprSymFn t args ret)
instance GHC.Classes.Eq (What4.Expr.App.ExprSymFn t args tp)
instance Data.Hashable.Class.Hashable (What4.Expr.App.ExprSymFn t args tp)
instance What4.Interface.IsSymFn (What4.Expr.App.ExprSymFn t)
instance GHC.Base.Semigroup (What4.Expr.App.BVOrNote w)
instance (Data.Parameterized.Classes.OrdF e, Data.Type.Equality.TestEquality e) => GHC.Classes.Eq (What4.Expr.App.BVOrSet e w)
instance Data.Parameterized.Classes.OrdF e => Data.Hashable.Class.Hashable (What4.Expr.App.BVOrSet e w)
instance GHC.Show.Show (What4.Expr.App.ExprBoundVar t tp)
instance Data.Parameterized.Classes.ShowF (What4.Expr.App.ExprBoundVar t)
instance Data.Parameterized.Classes.ShowF e => GHC.Show.Show (What4.Expr.App.App e u)

module What4.Expr.AppTheory

-- | The theory that a symbol belongs to.
data AppTheory
BoolTheory :: AppTheory
LinearArithTheory :: AppTheory
NonlinearArithTheory :: AppTheory
ComputableArithTheory :: AppTheory
BitvectorTheory :: AppTheory
QuantifierTheory :: AppTheory
StringTheory :: AppTheory
FloatingPointTheory :: AppTheory
ArrayTheory :: AppTheory

-- | Theory attributed to structs (equivalent to records in
--   CVC4CVC5Z3, tuples in Yices)
StructTheory :: AppTheory

-- | Theory attributed application functions.
FnTheory :: AppTheory
quantTheory :: NonceApp t (Expr t) tp -> AppTheory
appTheory :: App (Expr t) tp -> AppTheory
typeTheory :: BaseTypeRepr tp -> AppTheory
instance GHC.Classes.Ord What4.Expr.AppTheory.AppTheory
instance GHC.Classes.Eq What4.Expr.AppTheory.AppTheory

module What4.Expr.VarIdentification
data CollectedVarInfo t
uninterpConstants :: Simple Lens (CollectedVarInfo t) (Set (Some (ExprBoundVar t)))
latches :: Simple Lens (CollectedVarInfo t) (Set (Some (ExprBoundVar t)))

-- | Contains all information about a bound variable appearing in the
--   expression.
data QuantifierInfo t tp
BVI :: !NonceAppExpr t BaseBoolType -> !BoundQuant -> !ExprBoundVar t tp -> !Expr t BaseBoolType -> QuantifierInfo t tp

-- | The outer term containing the binding (e.g., Ax.f(x))
[boundTopTerm] :: QuantifierInfo t tp -> !NonceAppExpr t BaseBoolType

-- | The type of quantifier that appears
[boundQuant] :: QuantifierInfo t tp -> !BoundQuant

-- | The variable that is bound Variables may be bound multiple times.
[boundVar] :: QuantifierInfo t tp -> !ExprBoundVar t tp

-- | The term that appears inside the binding.
[boundInnerTerm] :: QuantifierInfo t tp -> !Expr t BaseBoolType
data BoundQuant
ForallBound :: BoundQuant
ExistBound :: BoundQuant
type QuantifierInfoMap t = Map (NonceAppExpr t BaseBoolType) (Some (QuantifierInfo t))

-- | Describes types of functionality required by solver based on the
--   problem.
problemFeatures :: Simple Lens (CollectedVarInfo t) ProblemFeatures

-- | Expressions appearing in the problem as existentially quantified when
--   the problem is expressed in negation normal form. This is a map from
--   the existential quantifier element to the info.
existQuantifiers :: Simple Lens (CollectedVarInfo t) (QuantifierInfoMap t)

-- | Expressions appearing in the problem as existentially quantified when
--   the problem is expressed in negation normal form. This is a map from
--   the existential quantifier element to the info.
forallQuantifiers :: Simple Lens (CollectedVarInfo t) (QuantifierInfoMap t)
varErrors :: Simple Lens (CollectedVarInfo t) (Seq (Doc Void))

-- | Information about bound variables outside this context.
data Scope
ExistsOnly :: Scope
ExistsForall :: Scope

-- | Describes the occurrence of a variable or expression, whether it is
--   negated or not.
data Polarity
Positive :: Polarity
Negative :: Polarity
data VarRecorder s t a
collectVarInfo :: VarRecorder s t () -> ST s (CollectedVarInfo t)

-- | Record the variables in an element.
recordExprVars :: Scope -> Expr t tp -> VarRecorder s t ()

-- | Return variables needed to define element as a predicate
predicateVarInfo :: Expr t BaseBoolType -> CollectedVarInfo t
instance What4.Utils.MonadST.MonadST s (What4.Expr.VarIdentification.VarRecorder s t)
instance GHC.Base.Monad (What4.Expr.VarIdentification.VarRecorder s t)
instance GHC.Base.Applicative (What4.Expr.VarIdentification.VarRecorder s t)
instance GHC.Base.Functor (What4.Expr.VarIdentification.VarRecorder s t)

module What4.Expr.Allocator

-- | ExprAllocator provides an interface for creating expressions from an
--   applications. Parameter t is a phantom type brand used to
--   track nonces.
data ExprAllocator t
ExprAllocator :: (forall tp. ProgramLoc -> App (Expr t) tp -> AbstractValue tp -> IO (Expr t tp)) -> (forall tp. ProgramLoc -> NonceApp t (Expr t) tp -> AbstractValue tp -> IO (Expr t tp)) -> ExprAllocator t
[appExpr] :: ExprAllocator t -> forall tp. ProgramLoc -> App (Expr t) tp -> AbstractValue tp -> IO (Expr t tp)
[nonceExpr] :: ExprAllocator t -> forall tp. ProgramLoc -> NonceApp t (Expr t) tp -> AbstractValue tp -> IO (Expr t tp)

-- | Create a new storage that does not do hash consing.
newStorage :: NonceGenerator IO t -> IO (ExprAllocator t)

-- | Create a storage that does hash consing.
newCachedStorage :: forall t. NonceGenerator IO t -> Int -> IO (ExprAllocator t)

-- | Starting size for element cache when caching is enabled. The default
--   value is 100000 elements.
--   
--   This option is named "backend.cache_start_size"
cacheStartSizeOption :: ConfigOption BaseIntegerType

-- | The configuration option for setting the size of the initial hash set
--   used by simple builder (measured in number of elements).
cacheStartSizeDesc :: ConfigDesc

-- | Indicates if we should cache terms. When enabled, hash-consing is used
--   to find and deduplicate common subexpressions. Toggling this option
--   from disabled to enabled will allocate a new hash table; toggling it
--   from enabled to disabled will discard the current hash table. The
--   default value for this option is False.
--   
--   This option is named "use_cache"
cacheTerms :: ConfigOption BaseBoolType
cacheOptDesc :: NonceGenerator IO t -> IORef (ExprAllocator t) -> OptionSetting BaseIntegerType -> ConfigDesc

-- | This module defines the canonical implementation of the solver
--   interface from What4.Interface. Type ExprBuilder t
--   st is an instance of the classes IsExprBuilder and
--   IsSymExprBuilder.
--   
--   Notes regarding concurrency: The expression builder datatype contains
--   a number of mutable storage locations. These are designed so they may
--   reasonably be used in a multithreaded context. In particular, nonce
--   values are generated atomically, and other IORefs used in this module
--   are modified or written atomically, so modifications should propagate
--   in the expected sequentially-consistent ways. Of course, threads may
--   still clobber state others have set (e.g., the current program
--   location) so the potential for truly multithreaded use is somewhat
--   limited. Consider the exprBuilderFreshConfig or
--   exprBuilderSplitConfig operations if this is a concern.
module What4.Expr.Builder

-- | Cache for storing dag terms. Parameter t is a phantom type
--   brand used to track nonces.
data ExprBuilder t (st :: Type -> Type) (fs :: Type)
newExprBuilder :: FloatModeRepr fm -> st t -> NonceGenerator IO t -> IO (ExprBuilder t st (Flags fm))

-- | Get current variable bindings.
getSymbolVarBimap :: ExprBuilder t st fs -> IO (SymbolVarBimap t)
sbMakeExpr :: ExprBuilder t st fs -> App (Expr t) tp -> IO (Expr t tp)

-- | Create an element from a nonce app.
sbNonceExpr :: ExprBuilder t st fs -> NonceApp t (Expr t) tp -> IO (Expr t tp)
curProgramLoc :: ExprBuilder t st fs -> IO ProgramLoc
unaryThreshold :: Getter (ExprBuilder t st fs) (OptionSetting BaseIntegerType)
cacheStartSize :: Getter (ExprBuilder t st fs) (OptionSetting BaseIntegerType)
userState :: Lens' (ExprBuilder t st fs) (st t)
exprCounter :: Getter (ExprBuilder t st fs) (NonceGenerator IO t)

-- | Restart caching applications in backend (clears cache if it is
--   currently caching).
startCaching :: ExprBuilder t st fs -> IO ()

-- | Stop caching applications in backend.
stopCaching :: ExprBuilder t st fs -> IO ()

-- | Return a new expr builder where the configuration object has been
--   "split" using the splitConfig operation. The returned sym
--   will share any preexisting options with the input sym, but any new
--   options added with extendConfig will not be shared. This may
--   be useful if the expression builder needs to be shared across threads,
--   or sequentially for separate use cases. Note, however, that hash
--   consing settings, solver loggers and the current program location will
--   be shared.
exprBuilderSplitConfig :: ExprBuilder t st fs -> IO (ExprBuilder t st fs)

-- | Return a new expr builder where all configuration settings have been
--   isolated from the original. The Config object of the output
--   expr builder will have only the default options that are installed via
--   newExprBuilder, and configuration changes to either expr
--   builder will not be visible to the other. This includes caching
--   settings, the current program location, and installed solver loggers.
exprBuilderFreshConfig :: ExprBuilder t st fs -> IO (ExprBuilder t st fs)
bvUnary :: 1 <= w => ExprBuilder t st fs -> UnaryBV (BoolExpr t) w -> IO (BVExpr t w)

-- | Evaluate a weighted sum of integer values.
intSum :: ExprBuilder t st fs -> WeightedSum (Expr t) SemiRingInteger -> IO (IntegerExpr t)

-- | Evaluate a weighted sum of real values.
realSum :: ExprBuilder t st fs -> WeightedSum (Expr t) SemiRingReal -> IO (RealExpr t)
bvSum :: ExprBuilder t st fs -> WeightedSum (Expr t) (SemiRingBV flv w) -> IO (BVExpr t w)
scalarMul :: ExprBuilder t st fs -> SemiRingRepr sr -> Coefficient sr -> Expr t (SemiRingBase sr) -> IO (Expr t (SemiRingBase sr))

-- | Maximum number of values in unary bitvector encoding.
--   
--   This option is named "backend.unary_threshold"
unaryThresholdOption :: ConfigOption BaseIntegerType

-- | Starting size for element cache when caching is enabled. The default
--   value is 100000 elements.
--   
--   This option is named "backend.cache_start_size"
cacheStartSizeOption :: ConfigOption BaseIntegerType

-- | Indicates if we should cache terms. When enabled, hash-consing is used
--   to find and deduplicate common subexpressions. Toggling this option
--   from disabled to enabled will allocate a new hash table; toggling it
--   from enabled to disabled will discard the current hash table. The
--   default value for this option is False.
--   
--   This option is named "use_cache"
cacheTerms :: ConfigOption BaseBoolType

-- | The main ExprBuilder expression datastructure. The non-trivial
--   Expr values constructed by this module are uniquely
--   identified by a nonce value that is used to explicitly represent
--   sub-term sharing. When traversing the structure of an Expr it
--   is usually very important to memoize computations based on the values
--   of these identifiers to avoid exponential blowups due to shared term
--   structure.
--   
--   Type parameter t is a phantom type brand used to relate
--   nonces to a specific nonce generator (similar to the s
--   parameter of the ST monad). The type index tp of
--   kind BaseType indicates the type of the values denoted by the
--   given expression.
--   
--   Type Expr t instantiates the type family
--   SymExpr (ExprBuilder t st).
data Expr t (tp :: BaseType)
[SemiRingLiteral] :: !SemiRingRepr sr -> !Coefficient sr -> !ProgramLoc -> Expr t (SemiRingBase sr)
[BoolExpr] :: !Bool -> !ProgramLoc -> Expr t BaseBoolType
[FloatExpr] :: !FloatPrecisionRepr fpp -> !BigFloat -> !ProgramLoc -> Expr t (BaseFloatType fpp)
[StringExpr] :: !StringLiteral si -> !ProgramLoc -> Expr t (BaseStringType si)
[AppExpr] :: {-# UNPACK #-} !AppExpr t tp -> Expr t tp
[NonceAppExpr] :: {-# UNPACK #-} !NonceAppExpr t tp -> Expr t tp
[BoundVarExpr] :: !ExprBoundVar t tp -> Expr t tp

-- | Destructor for the AppExpr constructor.
asApp :: Expr t tp -> Maybe (App (Expr t) tp)

-- | Destructor for the NonceAppExpr constructor.
asNonceApp :: Expr t tp -> Maybe (NonceApp t (Expr t) tp)
iteSize :: Expr t tp -> Integer
exprLoc :: Expr t tp -> ProgramLoc

-- | Pretty print an Expr using let bindings to create the term.
ppExpr :: Expr t tp -> Doc ann

-- | Pretty print the top part of an element.
ppExprTop :: Expr t tp -> Doc ann
exprMaybeId :: Expr t tp -> Maybe (Nonce t tp)
asConjunction :: Expr t BaseBoolType -> [(Expr t BaseBoolType, Polarity)]
asDisjunction :: Expr t BaseBoolType -> [(Expr t BaseBoolType, Polarity)]

-- | Describes the occurrence of a variable or expression, whether it is
--   negated or not.
data Polarity
Positive :: Polarity
Negative :: Polarity

-- | Swap a polarity value
negatePolarity :: Polarity -> Polarity

-- | This type represents Expr values that were built from an
--   App.
--   
--   Parameter t is a phantom type brand used to track nonces.
--   
--   Selector functions are provided to destruct AppExpr values, but
--   the constructor is kept hidden. The preferred way to construct an
--   Expr from an App is to use sbMakeExpr.
data AppExpr t (tp :: BaseType)
appExprId :: AppExpr t tp -> Nonce t tp
appExprLoc :: AppExpr t tp -> ProgramLoc
appExprApp :: AppExpr t tp -> App (Expr t) tp

-- | This type represents Expr values that were built from a
--   NonceApp.
--   
--   Parameter t is a phantom type brand used to track nonces.
--   
--   Selector functions are provided to destruct NonceAppExpr
--   values, but the constructor is kept hidden. The preferred way to
--   construct an Expr from a NonceApp is to use
--   sbNonceExpr.
data NonceAppExpr t (tp :: BaseType)
nonceExprId :: NonceAppExpr t tp -> Nonce t tp
nonceExprLoc :: NonceAppExpr t tp -> ProgramLoc
nonceExprApp :: NonceAppExpr t tp -> NonceApp t (Expr t) tp
type BoolExpr t = Expr t BaseBoolType
type IntegerExpr t = Expr t BaseIntegerType
type RealExpr t = Expr t BaseRealType
type FloatExpr t fpp = Expr t (BaseFloatType fpp)
type BVExpr t n = Expr t (BaseBVType n)
type CplxExpr t = Expr t BaseComplexType
type StringExpr t si = Expr t (BaseStringType si)

-- | Type App e tp encodes the top-level application of an
--   Expr expression. It includes first-order expression forms that
--   do not bind variables (contrast with NonceApp).
--   
--   Parameter e is used everywhere a recursive sub-expression
--   would go. Uses of the App type will tie the knot through this
--   parameter. Parameter tp indicates the type of the expression.
data App (e :: BaseType -> Type) (tp :: BaseType)
[BaseIte] :: !BaseTypeRepr tp -> !Integer -> !e BaseBoolType -> !e tp -> !e tp -> App e tp
[BaseEq] :: !BaseTypeRepr tp -> !e tp -> !e tp -> App e BaseBoolType
[NotPred] :: !e BaseBoolType -> App e BaseBoolType
[ConjPred] :: !BoolMap e -> App e BaseBoolType
[SemiRingSum] :: {-# UNPACK #-} !WeightedSum e sr -> App e (SemiRingBase sr)
[SemiRingProd] :: {-# UNPACK #-} !SemiRingProduct e sr -> App e (SemiRingBase sr)
[SemiRingLe] :: !OrderedSemiRingRepr sr -> !e (SemiRingBase sr) -> !e (SemiRingBase sr) -> App e BaseBoolType
[RealIsInteger] :: !e BaseRealType -> App e BaseBoolType
[IntDiv] :: !e BaseIntegerType -> !e BaseIntegerType -> App e BaseIntegerType
[IntMod] :: !e BaseIntegerType -> !e BaseIntegerType -> App e BaseIntegerType
[IntAbs] :: !e BaseIntegerType -> App e BaseIntegerType
[IntDivisible] :: !e BaseIntegerType -> Natural -> App e BaseBoolType
[RealDiv] :: !e BaseRealType -> !e BaseRealType -> App e BaseRealType
[RealSqrt] :: !e BaseRealType -> App e BaseRealType
[RealSpecialFunction] :: !SpecialFunction args -> !SpecialFnArgs e BaseRealType args -> App e BaseRealType
[BVTestBit] :: 1 <= w => !Natural -> !e (BaseBVType w) -> App e BaseBoolType
[BVSlt] :: 1 <= w => !e (BaseBVType w) -> !e (BaseBVType w) -> App e BaseBoolType
[BVUlt] :: 1 <= w => !e (BaseBVType w) -> !e (BaseBVType w) -> App e BaseBoolType
[BVOrBits] :: 1 <= w => !NatRepr w -> !BVOrSet e w -> App e (BaseBVType w)
[BVUnaryTerm] :: 1 <= n => !UnaryBV (e BaseBoolType) n -> App e (BaseBVType n)
[BVConcat] :: (1 <= u, 1 <= v, 1 <= (u + v)) => !NatRepr (u + v) -> !e (BaseBVType u) -> !e (BaseBVType v) -> App e (BaseBVType (u + v))
[BVSelect] :: (1 <= n, (idx + n) <= w) => !NatRepr idx -> !NatRepr n -> !e (BaseBVType w) -> App e (BaseBVType n)
[BVFill] :: 1 <= w => !NatRepr w -> !e BaseBoolType -> App e (BaseBVType w)
[BVUdiv] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVUrem] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVSdiv] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVSrem] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVShl] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVLshr] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVAshr] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVRol] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVRor] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVZext] :: (1 <= w, (w + 1) <= r, 1 <= r) => !NatRepr r -> !e (BaseBVType w) -> App e (BaseBVType r)
[BVSext] :: (1 <= w, (w + 1) <= r, 1 <= r) => !NatRepr r -> !e (BaseBVType w) -> App e (BaseBVType r)
[BVPopcount] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVCountTrailingZeros] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVCountLeadingZeros] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> App e (BaseBVType w)
[FloatNeg] :: !FloatPrecisionRepr fpp -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatAbs] :: !FloatPrecisionRepr fpp -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatSqrt] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatAdd] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatSub] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatMul] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatDiv] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatRem] :: !FloatPrecisionRepr fpp -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatFMA] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatFpEq] :: !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatLe] :: !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatLt] :: !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsNaN] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsInf] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsZero] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsPos] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsNeg] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsSubnorm] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsNorm] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatCast] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp') -> App e (BaseFloatType fpp)
[FloatRound] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatFromBinary] :: (2 <= eb, 2 <= sb) => !FloatPrecisionRepr (FloatingPointPrecision eb sb) -> !e (BaseBVType (eb + sb)) -> App e (BaseFloatType (FloatingPointPrecision eb sb))
[FloatToBinary] :: (2 <= eb, 2 <= sb, 1 <= (eb + sb)) => !FloatPrecisionRepr (FloatingPointPrecision eb sb) -> !e (BaseFloatType (FloatingPointPrecision eb sb)) -> App e (BaseBVType (eb + sb))
[BVToFloat] :: 1 <= w => !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseBVType w) -> App e (BaseFloatType fpp)
[SBVToFloat] :: 1 <= w => !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseBVType w) -> App e (BaseFloatType fpp)
[RealToFloat] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e BaseRealType -> App e (BaseFloatType fpp)
[FloatToBV] :: 1 <= w => !NatRepr w -> !RoundingMode -> !e (BaseFloatType fpp) -> App e (BaseBVType w)
[FloatToSBV] :: 1 <= w => !NatRepr w -> !RoundingMode -> !e (BaseFloatType fpp) -> App e (BaseBVType w)
[FloatToReal] :: !e (BaseFloatType fpp) -> App e BaseRealType
[FloatSpecialFunction] :: !FloatPrecisionRepr fpp -> !SpecialFunction args -> !SpecialFnArgs e (BaseFloatType fpp) args -> App e (BaseFloatType fpp)
[ArrayMap] :: !Assignment BaseTypeRepr (i ::> itp) -> !BaseTypeRepr tp -> !ArrayUpdateMap e (i ::> itp) tp -> !e (BaseArrayType (i ::> itp) tp) -> App e (BaseArrayType (i ::> itp) tp)
[ConstantArray] :: !Assignment BaseTypeRepr (i ::> tp) -> !BaseTypeRepr b -> !e b -> App e (BaseArrayType (i ::> tp) b)
[UpdateArray] :: !BaseTypeRepr b -> !Assignment BaseTypeRepr (i ::> tp) -> !e (BaseArrayType (i ::> tp) b) -> !Assignment e (i ::> tp) -> !e b -> App e (BaseArrayType (i ::> tp) b)
[SelectArray] :: !BaseTypeRepr b -> !e (BaseArrayType (i ::> tp) b) -> !Assignment e (i ::> tp) -> App e b
[CopyArray] :: 1 <= w => !NatRepr w -> !BaseTypeRepr a -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e (BaseBVType w) -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseArrayType (SingleCtx (BaseBVType w)) a)
[SetArray] :: 1 <= w => !NatRepr w -> !BaseTypeRepr a -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e a -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseArrayType (SingleCtx (BaseBVType w)) a)
[EqualArrayRange] :: 1 <= w => !NatRepr w -> !BaseTypeRepr a -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e (BaseBVType w) -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e BaseBoolType
[IntegerToReal] :: !e BaseIntegerType -> App e BaseRealType
[RealToInteger] :: !e BaseRealType -> App e BaseIntegerType
[BVToInteger] :: 1 <= w => !e (BaseBVType w) -> App e BaseIntegerType
[SBVToInteger] :: 1 <= w => !e (BaseBVType w) -> App e BaseIntegerType
[IntegerToBV] :: 1 <= w => !e BaseIntegerType -> NatRepr w -> App e (BaseBVType w)
[RoundReal] :: !e BaseRealType -> App e BaseIntegerType
[RoundEvenReal] :: !e BaseRealType -> App e BaseIntegerType
[FloorReal] :: !e BaseRealType -> App e BaseIntegerType
[CeilReal] :: !e BaseRealType -> App e BaseIntegerType
[Cplx] :: {-# UNPACK #-} !Complex (e BaseRealType) -> App e BaseComplexType
[RealPart] :: !e BaseComplexType -> App e BaseRealType
[ImagPart] :: !e BaseComplexType -> App e BaseRealType
[StringContains] :: !e (BaseStringType si) -> !e (BaseStringType si) -> App e BaseBoolType
[StringIsPrefixOf] :: !e (BaseStringType si) -> !e (BaseStringType si) -> App e BaseBoolType
[StringIsSuffixOf] :: !e (BaseStringType si) -> !e (BaseStringType si) -> App e BaseBoolType
[StringIndexOf] :: !e (BaseStringType si) -> !e (BaseStringType si) -> !e BaseIntegerType -> App e BaseIntegerType
[StringSubstring] :: !StringInfoRepr si -> !e (BaseStringType si) -> !e BaseIntegerType -> !e BaseIntegerType -> App e (BaseStringType si)
[StringAppend] :: !StringInfoRepr si -> !StringSeq e si -> App e (BaseStringType si)
[StringLength] :: !e (BaseStringType si) -> App e BaseIntegerType
[StructCtor] :: !Assignment BaseTypeRepr flds -> !Assignment e flds -> App e (BaseStructType flds)
[StructField] :: !e (BaseStructType flds) -> !Index flds tp -> !BaseTypeRepr tp -> App e tp
traverseApp :: (Applicative m, OrdF f, Eq (f BaseBoolType), HashableF f, HasAbsValue f) => (forall tp. e tp -> m (f tp)) -> App e utp -> m (App f utp)
appType :: App e tp -> BaseTypeRepr tp

-- | Type NonceApp t e tp encodes the top-level application of an
--   Expr. It includes expression forms that bind variables
--   (contrast with App).
--   
--   Parameter t is a phantom type brand used to track nonces.
--   Parameter e is used everywhere a recursive sub-expression
--   would go. Uses of the NonceApp type will tie the knot through
--   this parameter. Parameter tp indicates the type of the
--   expression.
data NonceApp t (e :: BaseType -> Type) (tp :: BaseType)
[Annotation] :: !BaseTypeRepr tp -> !Nonce t tp -> !e tp -> NonceApp t e tp
[Forall] :: !ExprBoundVar t tp -> !e BaseBoolType -> NonceApp t e BaseBoolType
[Exists] :: !ExprBoundVar t tp -> !e BaseBoolType -> NonceApp t e BaseBoolType
[ArrayFromFn] :: !ExprSymFn t (idx ::> itp) ret -> NonceApp t e (BaseArrayType (idx ::> itp) ret)
[MapOverArrays] :: !ExprSymFn t (ctx ::> d) r -> !Assignment BaseTypeRepr (idx ::> itp) -> !Assignment (ArrayResultWrapper e (idx ::> itp)) (ctx ::> d) -> NonceApp t e (BaseArrayType (idx ::> itp) r)
[ArrayTrueOnEntries] :: !ExprSymFn t (idx ::> itp) BaseBoolType -> !e (BaseArrayType (idx ::> itp) BaseBoolType) -> NonceApp t e BaseBoolType
[FnApp] :: !ExprSymFn t args ret -> !Assignment e args -> NonceApp t e ret
nonceAppType :: IsExpr e => NonceApp t e tp -> BaseTypeRepr tp

-- | Information about bound variables. Parameter t is a phantom
--   type brand used to track nonces.
--   
--   Type ExprBoundVar t instantiates the type family
--   BoundVar (ExprBuilder t st).
--   
--   Selector functions are provided to destruct ExprBoundVar
--   values, but the constructor is kept hidden. The preferred way to
--   construct a ExprBoundVar is to use freshBoundVar.
data ExprBoundVar t (tp :: BaseType)
bvarId :: ExprBoundVar t tp -> Nonce t tp
bvarLoc :: ExprBoundVar t tp -> ProgramLoc
bvarName :: ExprBoundVar t tp -> SolverSymbol
bvarType :: ExprBoundVar t tp -> BaseTypeRepr tp
bvarKind :: ExprBoundVar t tp -> VarKind
bvarAbstractValue :: ExprBoundVar t tp -> Maybe (AbstractValue tp)

-- | The Kind of a bound variable.
data VarKind

-- | A variable appearing in a quantifier.
QuantifierVarKind :: VarKind

-- | A variable appearing as a latch input.
LatchVarKind :: VarKind

-- | A variable appearing in a uninterpreted constant
UninterpVarKind :: VarKind
boundVars :: Expr t tp -> ST s (BoundVarMap s t)
ppBoundVar :: ExprBoundVar t tp -> String

-- | This evaluates the term with the given bound variables rebound to the
--   given arguments.
--   
--   The algorithm works by traversing the subterms in the term in a
--   bottom-up fashion while using a hash-table to memoize results for
--   shared subterms. The hash-table is pre-populated so that the bound
--   variables map to the element, so we do not need any extra map lookup
--   when checking to see if a variable is bound.
--   
--   NOTE: This function assumes that variables in the substitution are not
--   themselves bound in the term (e.g. in a function definition or
--   quantifier). If this is not respected, then evalBoundVars will
--   call fail with an error message.
evalBoundVars :: ExprBuilder t st fs -> Expr t ret -> Assignment (ExprBoundVar t) args -> Assignment (Expr t) args -> IO (Expr t ret)

-- | This represents a symbolic function in the simulator. Parameter
--   t is a phantom type brand used to track nonces. The
--   args and ret parameters define the types of
--   arguments and the return type of the function.
--   
--   Type ExprSymFn t (Expr t) instantiates the type family
--   SymFn (ExprBuilder t st).
data ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType)
ExprSymFn :: !Nonce t (args ::> ret) -> !SolverSymbol -> !SymFnInfo t args ret -> !ProgramLoc -> ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType)
[symFnId] :: ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType) -> !Nonce t (args ::> ret)
[symFnName] :: ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType) -> !SolverSymbol
[symFnInfo] :: ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType) -> !SymFnInfo t args ret
[symFnLoc] :: ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType) -> !ProgramLoc

-- | This describes information about an undefined or defined function.
--   Parameter t is a phantom type brand used to track nonces. The
--   args and ret parameters define the types of
--   arguments and the return type of the function.
data SymFnInfo t (args :: Ctx BaseType) (ret :: BaseType)

-- | Information about the argument type and return type of an
--   uninterpreted function.
UninterpFnInfo :: !Assignment BaseTypeRepr args -> !BaseTypeRepr ret -> SymFnInfo t (args :: Ctx BaseType) (ret :: BaseType)

-- | Information about a defined function. Includes bound variables and an
--   expression associated to a defined function, as well as a policy for
--   when to unfold the body.
DefinedFnInfo :: !Assignment (ExprBoundVar t) args -> !Expr t ret -> !UnfoldPolicy -> SymFnInfo t (args :: Ctx BaseType) (ret :: BaseType)

-- | This is a function that corresponds to a matlab solver function. It
--   includes the definition as a ExprBuilder expr to enable export to
--   other solvers.
MatlabSolverFnInfo :: !MatlabSolverFn (Expr t) args ret -> !Assignment (ExprBoundVar t) args -> !Expr t ret -> SymFnInfo t (args :: Ctx BaseType) (ret :: BaseType)
symFnArgTypes :: ExprSymFn t args ret -> Assignment BaseTypeRepr args
symFnReturnType :: ExprSymFn t args ret -> BaseTypeRepr ret
data SomeExprSymFn t
SomeExprSymFn :: ExprSymFn t args ret -> SomeExprSymFn t
data ExprSymFnWrapper t c
ExprSymFnWrapper :: ExprSymFn t a r -> ExprSymFnWrapper t c

-- | A bijective map between vars and their canonical name for printing
--   purposes. Parameter t is a phantom type brand used to track
--   nonces.
data SymbolVarBimap t

-- | This describes what a given SolverSymbol is associated with. Parameter
--   t is a phantom type brand used to track nonces.
data SymbolBinding t

-- | Solver
VarSymbolBinding :: !ExprBoundVar t tp -> SymbolBinding t
FnSymbolBinding :: !ExprSymFn t args ret -> SymbolBinding t

-- | Empty symbol var bimap
emptySymbolVarBimap :: SymbolVarBimap t
lookupBindingOfSymbol :: SolverSymbol -> SymbolVarBimap t -> Maybe (SymbolBinding t)
lookupSymbolOfBinding :: SymbolBinding t -> SymbolVarBimap t -> Maybe SolverSymbol

-- | An IdxCache is used to map expressions with type Expr t tp to
--   values with a corresponding type f tp. It is a mutable map
--   using an IO hash table. Parameter t is a phantom type
--   brand used to track nonces.
data IdxCache t (f :: BaseType -> Type)

-- | Create a new IdxCache
newIdxCache :: MonadIO m => m (IdxCache t f)
lookupIdx :: MonadIO m => IdxCache t f -> Nonce t tp -> m (Maybe (f tp))

-- | Return the value associated to the expr in the index.
lookupIdxValue :: MonadIO m => IdxCache t f -> Expr t tp -> m (Maybe (f tp))

-- | Bind the value to the given expr in the index.
insertIdxValue :: MonadIO m => IdxCache t f -> Nonce t tp -> f tp -> m ()

-- | Remove a value from the IdxCache
deleteIdxValue :: MonadIO m => IdxCache t f -> Nonce t (tp :: BaseType) -> m ()

-- | Remove all values from the IdxCache
clearIdxCache :: MonadIO m => IdxCache t f -> m ()

-- | Implements a cached evaluated using the given element. Given an
--   element this function returns the value of the element if bound, and
--   otherwise calls the evaluation function, stores the result in the
--   cache, and returns the value.
idxCacheEval :: MonadIO m => IdxCache t f -> Expr t tp -> m (f tp) -> m (f tp)

-- | Implements a cached evaluated using the given element. Given an
--   element this function returns the value of the element if bound, and
--   otherwise calls the evaluation function, stores the result in the
--   cache, and returns the value.
idxCacheEval' :: MonadIO m => IdxCache t f -> Nonce t tp -> m (f tp) -> m (f tp)

-- | Mode flag for how floating-point values should be interpreted.
data FloatMode
data FloatModeRepr :: FloatMode -> Type
[FloatIEEERepr] :: FloatModeRepr FloatIEEE
[FloatUninterpretedRepr] :: FloatModeRepr FloatUninterpreted
[FloatRealRepr] :: FloatModeRepr FloatReal

-- | In this mode "interpreted" floating-point values are treated as
--   bit-precise IEEE-754 floats.
type FloatIEEE = 'FloatIEEE

-- | In this mode "interpreted" floating-point values are treated as
--   bitvectors of the appropriate width, and all operations on them are
--   translated as uninterpreted functions.
type FloatUninterpreted = 'FloatUninterpreted

-- | In this mode "interpreted" floating-point values are treated as
--   real-number values, to the extent possible. Expressions that would
--   result in infinities or NaN will yield unspecified values in this
--   mode, or directly produce runtime errors.
type FloatReal = 'FloatReal
data Flags (fi :: FloatMode)
data BVOrSet e w
bvOrToList :: BVOrSet e w -> [e (BaseBVType w)]
bvOrSingleton :: (OrdF e, HashableF e, HasAbsValue e) => e (BaseBVType w) -> BVOrSet e w
bvOrInsert :: (OrdF e, HashableF e, HasAbsValue e) => e (BaseBVType w) -> BVOrSet e w -> BVOrSet e w
bvOrUnion :: OrdF e => BVOrSet e w -> BVOrSet e w -> BVOrSet e w
bvOrAbs :: (OrdF e, 1 <= w) => NatRepr w -> BVOrSet e w -> BVDomain w
traverseBVOrSet :: (HashableF f, HasAbsValue f, OrdF f, Applicative m) => (forall tp. e tp -> m (f tp)) -> BVOrSet e w -> m (BVOrSet f w)

-- | The class for expressions.
type family SymExpr (sym :: Type) :: BaseType -> Type

-- | Get the width of a bitvector
bvWidth :: IsExpr e => e (BaseBVType w) -> NatRepr w

-- | Get type of expression.
exprType :: IsExpr e => e tp -> BaseTypeRepr tp

-- | This represents a concrete index value, and is used for creating
--   arrays.
data IndexLit idx
[IntIndexLit] :: !Integer -> IndexLit BaseIntegerType
[BVIndexLit] :: 1 <= w => !NatRepr w -> !BV w -> IndexLit (BaseBVType w)
newtype ArrayResultWrapper f idx tp
ArrayResultWrapper :: f (BaseArrayType idx tp) -> ArrayResultWrapper f idx tp
[unwrapArrayResult] :: ArrayResultWrapper f idx tp -> f (BaseArrayType idx tp)
instance What4.Interface.IsExprBuilder (What4.Expr.Builder.ExprBuilder t st fs)
instance What4.Interface.IsSymExprBuilder (What4.Expr.Builder.ExprBuilder t st fs)
instance What4.InterpretedFloatingPoint.IsInterpretedFloatExprBuilder (What4.Expr.Builder.ExprBuilder t st (What4.Expr.Builder.Flags What4.FloatMode.FloatReal))
instance What4.InterpretedFloatingPoint.IsInterpretedFloatExprBuilder (What4.Expr.Builder.ExprBuilder t st (What4.Expr.Builder.Flags What4.FloatMode.FloatUninterpreted))
instance What4.InterpretedFloatingPoint.IsInterpretedFloatExprBuilder (What4.Expr.Builder.ExprBuilder t st (What4.Expr.Builder.Flags What4.FloatMode.FloatIEEE))
instance What4.InterpretedFloatingPoint.IsInterpretedFloatExprBuilder (What4.Expr.Builder.ExprBuilder t st fs) => What4.InterpretedFloatingPoint.IsInterpretedFloatSymExprBuilder (What4.Expr.Builder.ExprBuilder t st fs)
instance What4.Expr.MATLAB.MatlabSymbolicArrayBuilder (What4.Expr.Builder.ExprBuilder t st fs)
instance GHC.Classes.Eq (What4.Expr.Builder.SomeExprSymFn t)
instance GHC.Classes.Ord (What4.Expr.Builder.SomeExprSymFn t)
instance GHC.Show.Show (What4.Expr.Builder.SomeExprSymFn t)
instance Data.Type.Equality.TestEquality (What4.Expr.Builder.MatlabFnWrapper t)
instance Data.Parameterized.Classes.HashableF (What4.Expr.Builder.MatlabFnWrapper t)
instance GHC.Classes.Eq (What4.Expr.Builder.SymbolBinding t)
instance GHC.Classes.Ord (What4.Expr.Builder.SymbolBinding t)

module What4.Protocol.VerilogWriter.AST
type Identifier = Text

-- | A type for Verilog binary operators that enforces well-typedness,
--   including bitvector size constraints.
data Binop (inTp :: BaseType) (outTp :: BaseType)
[And] :: Binop BaseBoolType BaseBoolType
[Or] :: Binop BaseBoolType BaseBoolType
[Xor] :: Binop BaseBoolType BaseBoolType
[Eq] :: Binop tp BaseBoolType
[Ne] :: Binop tp BaseBoolType
[Lt] :: Binop (BaseBVType w) BaseBoolType
[Le] :: Binop (BaseBVType w) BaseBoolType
[BVAnd] :: Binop (BaseBVType w) (BaseBVType w)
[BVOr] :: Binop (BaseBVType w) (BaseBVType w)
[BVXor] :: Binop (BaseBVType w) (BaseBVType w)
[BVAdd] :: Binop (BaseBVType w) (BaseBVType w)
[BVSub] :: Binop (BaseBVType w) (BaseBVType w)
[BVMul] :: Binop (BaseBVType w) (BaseBVType w)
[BVDiv] :: Binop (BaseBVType w) (BaseBVType w)
[BVRem] :: Binop (BaseBVType w) (BaseBVType w)
[BVPow] :: Binop (BaseBVType w) (BaseBVType w)
[BVShiftL] :: Binop (BaseBVType w) (BaseBVType w)
[BVShiftR] :: Binop (BaseBVType w) (BaseBVType w)
[BVShiftRA] :: Binop (BaseBVType w) (BaseBVType w)
binopType :: Binop inTp outTp -> BaseTypeRepr inTp -> BaseTypeRepr outTp

-- | A type for Verilog unary operators that enforces well-typedness.
data Unop (tp :: BaseType)
[Not] :: Unop BaseBoolType
[BVNot] :: Unop (BaseBVType w)

-- | A type for Verilog expression names that enforces well-typedness. This
--   type exists essentially to pair a name and type to avoid needing to
--   repeat them and ensure that all uses of the name are well-typed.
data IExp (tp :: BaseType)
[Ident] :: BaseTypeRepr tp -> Identifier -> IExp tp
iexpType :: IExp tp -> BaseTypeRepr tp
data LHS
LHS :: Identifier -> LHS
LHSBit :: Identifier -> Integer -> LHS

-- | A type for Verilog expressions that enforces well-typedness, including
--   bitvector size constraints.
data Exp (tp :: BaseType)
[IExp] :: IExp tp -> Exp tp
[Binop] :: Binop inTp outTp -> IExp inTp -> IExp inTp -> Exp outTp
[Unop] :: Unop tp -> IExp tp -> Exp tp
[BVRotateL] :: NatRepr w -> IExp tp -> BV w -> Exp tp
[BVRotateR] :: NatRepr w -> IExp tp -> BV w -> Exp tp
[Mux] :: IExp BaseBoolType -> IExp tp -> IExp tp -> Exp tp
[Bit] :: IExp (BaseBVType w) -> Integer -> Exp BaseBoolType
[BitSelect] :: (1 <= len, (start + len) <= w) => IExp (BaseBVType w) -> NatRepr start -> NatRepr len -> Exp (BaseBVType len)
[Concat] :: 1 <= w => NatRepr w -> [Some IExp] -> Exp (BaseBVType w)
[BVLit] :: 1 <= w => NatRepr w -> BV w -> Exp (BaseBVType w)
[BoolLit] :: Bool -> Exp BaseBoolType
expType :: Exp tp -> BaseTypeRepr tp

-- | Create a let binding, associating a name with an expression. In
--   Verilog, this is a new "wire".
mkLet :: Exp tp -> VerilogM sym n (IExp tp)

-- | Indicate than an expression name is signed. This causes arithmetic
--   operations involving this name to be interpreted as signed operations.
signed :: IExp tp -> VerilogM sym n (IExp tp)

-- | Apply a binary operation to two expressions and bind the result to a
--   new, returned name.
binop :: Binop inTp outTp -> IExp inTp -> IExp inTp -> VerilogM sym n (IExp outTp)

-- | A special binary operation for scalar multiplication. This avoids the
--   need to call litBV at every call site.
scalMult :: 1 <= w => NatRepr w -> Binop (BaseBVType w) (BaseBVType w) -> BV w -> IExp (BaseBVType w) -> VerilogM sym n (IExp (BaseBVType w))

-- | A wrapper around the BV type allowing it to be put into a map or set.
--   We use this to make sure we generate only one instance of each
--   distinct constant.
data BVConst
BVConst :: Pair NatRepr BV -> BVConst

-- | Return the (possibly-cached) name for a literal bitvector value.
litBV :: 1 <= w => NatRepr w -> BV w -> VerilogM sym n (IExp (BaseBVType w))

-- | Return the (possibly-cached) name for a literal Boolean value.
litBool :: Bool -> VerilogM sym n (IExp BaseBoolType)

-- | Apply a unary operation to an expression and bind the result to a new,
--   returned name.
unop :: Unop tp -> IExp tp -> VerilogM sym n (IExp tp)

-- | Create a conditional, with the given condition, true, and false
--   branches, and bind the result to a new, returned name.
mux :: IExp BaseBoolType -> IExp tp -> IExp tp -> VerilogM sym n (IExp tp)

-- | Extract a single bit from a bit vector and bind the result to a new,
--   returned name.
bit :: IExp (BaseBVType w) -> Integer -> VerilogM sym n (IExp BaseBoolType)

-- | Extract a range of bits from a bit vector and bind the result to a
--   new, returned name. The two NatRepr values are the starting
--   index and the number of bits to extract, respectively.
bitSelect :: (1 <= len, (idx + len) <= w) => IExp (BaseBVType w) -> NatRepr idx -> NatRepr len -> VerilogM sym n (IExp (BaseBVType len))

-- | Concatenate two bit vectors and bind the result to a new, returned
--   name.
concat2 :: (w ~ (w1 + w2), 1 <= w) => NatRepr w -> IExp (BaseBVType w1) -> IExp (BaseBVType w2) -> VerilogM sym n (IExp (BaseBVType w))

-- | A data type for items that may show up in a Verilog module.
data Item
[Input] :: BaseTypeRepr tp -> Identifier -> Item
[Output] :: BaseTypeRepr tp -> Identifier -> Item
[Wire] :: BaseTypeRepr tp -> Identifier -> Item
[Assign] :: LHS -> Exp tp -> Item

-- | Necessary monadic operations
data ModuleState sym n
ModuleState :: [(Word64, Some BaseTypeRepr, Identifier)] -> [(Some BaseTypeRepr, Bool, Identifier, Some Exp)] -> [(Some BaseTypeRepr, Bool, Identifier, Some Exp)] -> Map Word64 Identifier -> Set Identifier -> IdxCache n IExp -> Map BVConst Identifier -> Map Bool Identifier -> sym -> ModuleState sym n

-- | All module inputs, in reverse order. We use Word64 for Nonces to avoid
--   GHC bugs. For more detail:
--   https://gitlab.haskell.org/ghc/ghc/-/issues/2595
--   https://gitlab.haskell.org/ghc/ghc/-/issues/10856
--   https://gitlab.haskell.org/ghc/ghc/-/issues/16501
[vsInputs] :: ModuleState sym n -> [(Word64, Some BaseTypeRepr, Identifier)]

-- | All module outputs, in reverse order. Includes the type, signedness,
--   name, and initializer of each.
[vsOutputs] :: ModuleState sym n -> [(Some BaseTypeRepr, Bool, Identifier, Some Exp)]

-- | All internal wires, in reverse order. Includes the type, signedness,
--   name, and initializer of each.
[vsWires] :: ModuleState sym n -> [(Some BaseTypeRepr, Bool, Identifier, Some Exp)]

-- | A map from the identifier nonces seen so far to their identifier
--   names. These nonces exist for identifiers from the original term, but
--   not intermediate Verilog variables.
[vsSeenNonces] :: ModuleState sym n -> Map Word64 Identifier

-- | A set of all the identifiers used so far, including intermediate
--   Verilog variables.
[vsUsedIdentifiers] :: ModuleState sym n -> Set Identifier

-- | An expression cache to preserve sharing present in the What4
--   representation.
[vsExpCache] :: ModuleState sym n -> IdxCache n IExp

-- | A cache of bit vector constants, to avoid duplicating constant
--   declarations.
[vsBVCache] :: ModuleState sym n -> Map BVConst Identifier

-- | A cache of Boolean constants, to avoid duplicating constant
--   declarations.
[vsBoolCache] :: ModuleState sym n -> Map Bool Identifier

-- | The What4 symbolic backend to use with vsBVCache.
[vsSym] :: ModuleState sym n -> sym
newtype VerilogM sym n a
VerilogM :: StateT (ModuleState sym n) (ExceptT String IO) a -> VerilogM sym n a
newtype Module sym n
Module :: ModuleState sym n -> Module sym n

-- | Create a Verilog module in the context of a given What4 symbolic
--   backend and a monadic computation that returns an expression name that
--   corresponds to the module's output.
mkModule :: sym -> [(Some (Expr n), Text)] -> [VerilogM sym n (Some IExp)] -> ExceptT String IO (Module sym n)
initModuleState :: sym -> IO (ModuleState sym n)
runVerilogM :: VerilogM sym n a -> ModuleState sym n -> ExceptT String IO (a, ModuleState sym n)
execVerilogM :: sym -> VerilogM sym n a -> ExceptT String IO (ModuleState sym n)
addBoundInput :: ExprBoundVar n tp -> Identifier -> VerilogM sym n Identifier

-- | Returns and records a fresh input with the given type and with a name
--   constructed from the given base.
addFreshInput :: Some (Nonce n) -> Some BaseTypeRepr -> Identifier -> VerilogM sym n Identifier

-- | Add an output to the current Verilog module state, given a type, a
--   name, and an initializer expression.
addOutput :: BaseTypeRepr tp -> Identifier -> Exp tp -> VerilogM sym n ()

-- | Add a new wire to the current Verilog module state, given a type, a
--   signedness flag, a name, and an initializer expression.
addWire :: BaseTypeRepr tp -> Bool -> Identifier -> Exp tp -> VerilogM sym n ()

-- | Create a fresh identifier by concatenating the given base with the
--   current fresh identifier counter.
freshIdentifier :: Text -> VerilogM sym n Identifier

-- | Add a new wire to the current Verilog module state, given a type, a
--   signedness flag, the prefix of a name, and an initializer expression.
--   The name prefix will be freshened by appending current value of the
--   fresh variable counter.
addFreshWire :: BaseTypeRepr tp -> Bool -> Text -> Exp tp -> VerilogM sym n Identifier
instance GHC.Classes.Eq What4.Protocol.VerilogWriter.AST.BVConst
instance Control.Monad.IO.Class.MonadIO (What4.Protocol.VerilogWriter.AST.VerilogM sym n)
instance Control.Monad.Error.Class.MonadError GHC.Base.String (What4.Protocol.VerilogWriter.AST.VerilogM sym n)
instance Control.Monad.State.Class.MonadState (What4.Protocol.VerilogWriter.AST.ModuleState sym n) (What4.Protocol.VerilogWriter.AST.VerilogM sym n)
instance GHC.Base.Monad (What4.Protocol.VerilogWriter.AST.VerilogM sym n)
instance GHC.Base.Applicative (What4.Protocol.VerilogWriter.AST.VerilogM sym n)
instance GHC.Base.Functor (What4.Protocol.VerilogWriter.AST.VerilogM sym n)
instance GHC.Classes.Ord What4.Protocol.VerilogWriter.AST.BVConst

module What4.Protocol.VerilogWriter.Backend

-- | Convert a What4 expresssion into a Verilog expression and return a
--   name for that expression's result.
exprToVerilogExpr :: (IsExprBuilder sym, SymExpr sym ~ Expr n) => Expr n tp -> VerilogM sym n (IExp tp)

module What4.Protocol.VerilogWriter.ABCVerilog
moduleDoc :: Module sym n -> Doc () -> Doc ()
typeDoc :: Doc () -> Bool -> BaseTypeRepr tp -> Doc ()
identDoc :: Identifier -> Doc ()
lhsDoc :: LHS -> Doc ()
inputDoc :: (Word64, Some BaseTypeRepr, Identifier) -> Doc ()
wireDoc :: Doc () -> (Some BaseTypeRepr, Bool, Identifier, Some Exp) -> Doc ()
unopDoc :: Unop tp -> Doc ()
binopDoc :: Binop inTp outTp -> Doc ()

-- | Show non-negative Integral numbers in base 16.
hexDoc :: BV w -> Doc ()
decDoc :: NatRepr w -> BV w -> Doc ()
iexpDoc :: IExp tp -> Doc ()
rotateDoc :: String -> String -> NatRepr w -> IExp tp -> BV w -> Doc ()
expDoc :: Exp tp -> Doc ()

module What4.Protocol.VerilogWriter
data Module sym n

-- | Convert the given What4 expressions, representing the outputs of a
--   circuit, into a textual representation of a Verilog module of the
--   given name.
exprsVerilog :: (IsExprBuilder sym, SymExpr sym ~ Expr n) => sym -> [(Some (Expr n), Text)] -> [Some (Expr n)] -> Doc () -> ExceptT String IO (Doc ())

-- | Convert the given What4 expressions, representing the outputs of a
--   circuit, into a Verilog module of the given name.
exprsToModule :: (IsExprBuilder sym, SymExpr sym ~ Expr n) => sym -> [(Some (Expr n), Text)] -> [Some (Expr n)] -> ExceptT String IO (Module sym n)

-- | This module provides a minimalistic interface for manipulating Boolean
--   formulas and execution contexts in the symbolic simulator.
module What4.Expr.Simplify

-- | Simplify a Boolean expression by distributing over ite.
simplify :: ExprBuilder t st fs -> BoolExpr t -> IO (BoolExpr t)

-- | Return a map from nonce indices to the number of times an elt with
--   that nonce appears in the subterm.
count_subterms :: Expr t tp -> Map Word64 Int
instance GHC.Base.Functor What4.Expr.Simplify.Or
instance GHC.Base.Applicative What4.Expr.Simplify.Or

-- | Given a collection of assignments to the symbolic values appearing in
--   an expression, this module computes the ground value.
module What4.Expr.GroundEval
type family GroundValue (tp :: BaseType)

-- | A newtype wrapper around ground value for use in a cache.
newtype GroundValueWrapper tp
GVW :: GroundValue tp -> GroundValueWrapper tp
[unGVW] :: GroundValueWrapper tp -> GroundValue tp

-- | A representation of a ground-value array.
data GroundArray idx b

-- | Lookup function for querying by index
ArrayMapping :: (Assignment GroundValueWrapper idx -> IO (GroundValue b)) -> GroundArray idx b

-- | Default value and finite map of particular indices
ArrayConcrete :: GroundValue b -> Map (Assignment IndexLit idx) (GroundValue b) -> GroundArray idx b

-- | Look up an index in an ground array.
lookupArray :: Assignment BaseTypeRepr idx -> GroundArray idx b -> Assignment GroundValueWrapper idx -> IO (GroundValue b)

-- | A function that calculates ground values for elements. Clients of
--   solvers should use the groundEval function for computing
--   values in models.
newtype GroundEvalFn t
GroundEvalFn :: (forall tp. Expr t tp -> IO (GroundValue tp)) -> GroundEvalFn t
[groundEval] :: GroundEvalFn t -> forall tp. Expr t tp -> IO (GroundValue tp)

-- | Function that calculates upper and lower bounds for real-valued
--   elements. This type is used for solvers (e.g., dReal) that give only
--   approximate solutions.
type ExprRangeBindings t = RealExpr t -> IO (Maybe Rational, Maybe Rational)

-- | Evaluate an element, when given an evaluation function for
--   subelements. Instead of recursing directly, tryEvalGroundExpr
--   calls into the given function on sub-elements to allow the caller to
--   cache results if desired.
--   
--   However, sometimes we are unable to compute expressions outside the
--   solver. In these cases, this function will return Nothing in
--   the `MaybeT IO` monad. In these cases, the caller should instead query
--   the solver directly to evaluate the expression, if possible.
tryEvalGroundExpr :: (forall u. Expr t u -> MaybeT IO (GroundValue u)) -> Expr t tp -> MaybeT IO (GroundValue tp)

-- | Helper function for evaluating Expr expressions in a model.
--   
--   This function is intended for implementers of symbolic backends.
evalGroundExpr :: (forall u. Expr t u -> IO (GroundValue u)) -> Expr t tp -> IO (GroundValue tp)

-- | Helper function for evaluating App expressions.
--   
--   This function is intended for implementers of symbolic backends.
evalGroundApp :: forall t tp. (forall u. Expr t u -> MaybeT IO (GroundValue u)) -> App (Expr t) tp -> MaybeT IO (GroundValue tp)

-- | Helper function for evaluating NonceApp expressions.
--   
--   This function is intended for implementers of symbolic backends.
evalGroundNonceApp :: Monad m => (forall u. Expr t u -> MaybeT m (GroundValue u)) -> NonceApp t (Expr t) tp -> MaybeT m (GroundValue tp)

-- | Construct a default value for a given base type.
defaultValueForType :: BaseTypeRepr tp -> GroundValue tp
groundEq :: BaseTypeRepr tp -> GroundValue tp -> GroundValue tp -> Maybe Bool
instance GHC.Base.Functor What4.Expr.GroundEval.MAnd
instance GHC.Base.Applicative What4.Expr.GroundEval.MAnd

module What4.Solver.Adapter

-- | The main interface for interacting with a solver in an "offline"
--   fashion, which means that a new solver process is started for each
--   query.
data SolverAdapter st
SolverAdapter :: !String -> ![ConfigDesc] -> !forall t fs a. ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a -> !forall t fs. ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO () -> SolverAdapter st
[solver_adapter_name] :: SolverAdapter st -> !String

-- | Configuration options relevant to this solver adapter
[solver_adapter_config_options] :: SolverAdapter st -> ![ConfigDesc]

-- | Operation to check the satisfiability of a formula. The final argument
--   is a callback that calculates the ultimate result from a SatResult and
--   operations for finding model values in the event of a SAT result.
--   Note: the evaluation functions may cease to be avaliable after the
--   callback completes, so any necessary information should be extracted
--   from them before returning.
[solver_adapter_check_sat] :: SolverAdapter st -> !forall t fs a. ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a

-- | Write an SMTLib2 problem instance onto the given handle, incorporating
--   any solver-specific tweaks appropriate to this solver
[solver_adapter_write_smt2] :: SolverAdapter st -> !forall t fs. ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()

-- | Default featues to use for writing SMTLIB2 files.
defaultWriteSMTLIB2Features :: ProblemFeatures
defaultSolverAdapter :: ConfigOption (BaseStringType Unicode)
solverAdapterOptions :: [SolverAdapter st] -> IO ([ConfigDesc], IO (SolverAdapter st))

-- | A collection of operations for producing output from solvers. Solvers
--   can produce messages at varying verbosity levels that might be
--   appropriate for user output by using the logCallbackVerbose
--   operation. If a logHandle is provided, the entire interaction
--   sequence with the solver will be mirrored into that handle.
data LogData
LogData :: (Int -> String -> IO ()) -> Int -> String -> Maybe Handle -> LogData

-- | takes a verbosity and a message to log
[logCallbackVerbose] :: LogData -> Int -> String -> IO ()

-- | the default verbosity; typical default is 2
[logVerbosity] :: LogData -> Int

-- | the reason for performing the operation
[logReason] :: LogData -> String

-- | handle on which to mirror solver input/responses
[logHandle] :: LogData -> Maybe Handle
logCallback :: LogData -> String -> IO ()
defaultLogData :: LogData

-- | Test the ability to interact with a solver by peforming a check-sat
--   query on a trivially unsatisfiable problem.
smokeTest :: ExprBuilder t st fs -> SolverAdapter st -> IO (Maybe SomeException)
instance GHC.Show.Show (What4.Solver.Adapter.SolverAdapter st)
instance GHC.Classes.Eq (What4.Solver.Adapter.SolverAdapter st)
instance GHC.Classes.Ord (What4.Solver.Adapter.SolverAdapter st)

-- | This defines common definitions used in writing SMTLIB (2.0 and
--   later), and yices outputs from Expr values.
--   
--   The writer is designed to support solvers with arithmetic,
--   propositional logic, bitvector, tuples (aka. structs), and arrays.
--   
--   It maps complex Expr values to either structs or arrays depending on
--   what the solver supports (structs are preferred if both are
--   supported).
--   
--   It maps multi-dimensional arrays to either arrays with structs as
--   indices if structs are supported or nested arrays if they are not.
--   
--   The solver should detect when something is not supported and give an
--   error rather than sending invalid output to a file.
module What4.Protocol.SMTWriter

-- | A class of values containing rational and operations.
class Num v => SupportTermOps v
boolExpr :: SupportTermOps v => Bool -> v
notExpr :: SupportTermOps v => v -> v
andAll :: SupportTermOps v => [v] -> v
orAll :: SupportTermOps v => [v] -> v
(.&&) :: SupportTermOps v => v -> v -> v
(.||) :: SupportTermOps v => v -> v -> v

-- | Compare two elements for equality.
(.==) :: SupportTermOps v => v -> v -> v

-- | Compare two elements for in-equality.
(./=) :: SupportTermOps v => v -> v -> v
impliesExpr :: SupportTermOps v => v -> v -> v

-- | Create a let expression. This is a "sequential" let, which is
--   syntactic sugar for a nested series of single let bindings. As a
--   consequence, bound variables are in scope for the right-hand-sides of
--   subsequent bindings.
letExpr :: SupportTermOps v => [(Text, v)] -> v -> v

-- | Create an if-then-else expression.
ite :: SupportTermOps v => v -> v -> v -> v

-- | Add a list of values together.
sumExpr :: SupportTermOps v => [v] -> v

-- | Convert an integer expression to a real.
termIntegerToReal :: SupportTermOps v => v -> v

-- | Convert a real expression to an integer.
termRealToInteger :: SupportTermOps v => v -> v

-- | Convert an integer to a term.
integerTerm :: SupportTermOps v => Integer -> v

-- | Convert a rational to a term.
rationalTerm :: SupportTermOps v => Rational -> v

-- | Less-then-or-equal
(.<=) :: SupportTermOps v => v -> v -> v

-- | Less-then
(.<) :: SupportTermOps v => v -> v -> v

-- | Greater then
(.>) :: SupportTermOps v => v -> v -> v

-- | Greater then or equal
(.>=) :: SupportTermOps v => v -> v -> v

-- | Integer theory terms
intAbs :: SupportTermOps v => v -> v
intDiv :: SupportTermOps v => v -> v -> v
intMod :: SupportTermOps v => v -> v -> v
intDivisible :: SupportTermOps v => v -> Natural -> v

-- | Create expression from bitvector.
bvTerm :: SupportTermOps v => NatRepr w -> BV w -> v
bvNeg :: SupportTermOps v => v -> v
bvAdd :: SupportTermOps v => v -> v -> v
bvSub :: SupportTermOps v => v -> v -> v
bvMul :: SupportTermOps v => v -> v -> v
bvSLe :: SupportTermOps v => v -> v -> v
bvULe :: SupportTermOps v => v -> v -> v
bvSLt :: SupportTermOps v => v -> v -> v
bvULt :: SupportTermOps v => v -> v -> v
bvUDiv :: SupportTermOps v => v -> v -> v
bvURem :: SupportTermOps v => v -> v -> v
bvSDiv :: SupportTermOps v => v -> v -> v
bvSRem :: SupportTermOps v => v -> v -> v
bvAnd :: SupportTermOps v => v -> v -> v
bvOr :: SupportTermOps v => v -> v -> v
bvXor :: SupportTermOps v => v -> v -> v
bvNot :: SupportTermOps v => v -> v
bvShl :: SupportTermOps v => v -> v -> v
bvLshr :: SupportTermOps v => v -> v -> v
bvAshr :: SupportTermOps v => v -> v -> v

-- | Concatenate two bitvectors together.
bvConcat :: SupportTermOps v => v -> v -> v

-- | bvExtract w i n v extracts bits [i..i+n) from v as a
--   new bitvector. v must contain at least w elements,
--   and i+n must be less than or equal to w. The result
--   has n elements. The least significant bit of v
--   should have index 0.
bvExtract :: SupportTermOps v => NatRepr w -> Natural -> Natural -> v -> v

-- | bvTestBit w i x returns predicate that holds if bit
--   i in x is set to true. w should be the
--   number of bits in x.
bvTestBit :: SupportTermOps v => NatRepr w -> Natural -> v -> v
bvSumExpr :: SupportTermOps v => NatRepr w -> [v] -> v
floatTerm :: SupportTermOps v => FloatPrecisionRepr fpp -> BigFloat -> v
floatNeg :: SupportTermOps v => v -> v
floatAbs :: SupportTermOps v => v -> v
floatSqrt :: SupportTermOps v => RoundingMode -> v -> v
floatAdd :: SupportTermOps v => RoundingMode -> v -> v -> v
floatSub :: SupportTermOps v => RoundingMode -> v -> v -> v
floatMul :: SupportTermOps v => RoundingMode -> v -> v -> v
floatDiv :: SupportTermOps v => RoundingMode -> v -> v -> v
floatRem :: SupportTermOps v => v -> v -> v
floatFMA :: SupportTermOps v => RoundingMode -> v -> v -> v -> v
floatEq :: SupportTermOps v => v -> v -> v
floatFpEq :: SupportTermOps v => v -> v -> v
floatLe :: SupportTermOps v => v -> v -> v
floatLt :: SupportTermOps v => v -> v -> v
floatIsNaN :: SupportTermOps v => v -> v
floatIsInf :: SupportTermOps v => v -> v
floatIsZero :: SupportTermOps v => v -> v
floatIsPos :: SupportTermOps v => v -> v
floatIsNeg :: SupportTermOps v => v -> v
floatIsSubnorm :: SupportTermOps v => v -> v
floatIsNorm :: SupportTermOps v => v -> v
floatCast :: SupportTermOps v => FloatPrecisionRepr fpp -> RoundingMode -> v -> v
floatRound :: SupportTermOps v => RoundingMode -> v -> v
floatFromBinary :: SupportTermOps v => FloatPrecisionRepr fpp -> v -> v
bvToFloat :: SupportTermOps v => FloatPrecisionRepr fpp -> RoundingMode -> v -> v
sbvToFloat :: SupportTermOps v => FloatPrecisionRepr fpp -> RoundingMode -> v -> v
realToFloat :: SupportTermOps v => FloatPrecisionRepr fpp -> RoundingMode -> v -> v
floatToBV :: SupportTermOps v => Natural -> RoundingMode -> v -> v
floatToSBV :: SupportTermOps v => Natural -> RoundingMode -> v -> v
floatToReal :: SupportTermOps v => v -> v

-- | Predicate that holds if a real number is an integer.
realIsInteger :: SupportTermOps v => v -> v
realDiv :: SupportTermOps v => v -> v -> v
realSin :: SupportTermOps v => v -> v
realCos :: SupportTermOps v => v -> v
realTan :: SupportTermOps v => v -> v
realATan2 :: SupportTermOps v => v -> v -> v
realSinh :: SupportTermOps v => v -> v
realCosh :: SupportTermOps v => v -> v
realTanh :: SupportTermOps v => v -> v
realExp :: SupportTermOps v => v -> v
realLog :: SupportTermOps v => v -> v

-- | Apply the arguments to the given function.
smtFnApp :: SupportTermOps v => v -> [v] -> v

-- | Update a function value to return a new value at the given point.
--   
--   This may be Nothing if solver has no builtin function for update.
smtFnUpdate :: SupportTermOps v => Maybe (v -> [v] -> v -> v)

-- | Function for creating a lambda term if output supports it.
--   
--   Yices support lambda expressions, but SMTLIB2 does not. The function
--   takes arguments and the expression.
lambdaTerm :: SupportTermOps v => Maybe ([(Text, Some TypeMap)] -> v -> v)
fromText :: SupportTermOps v => Text -> v
infix 4 .>
infixr 3 .&&
infixr 2 .||
infix 4 .==
infix 4 ./=
infix 4 .<=
infix 4 .<
infix 4 .>=
type ArrayConstantFn v = -- | Type for indices [Some TypeMap] -> -- | Type for value. Some TypeMap -> -- | Constant to assign all values. v -> v

-- | Typeclass need to generate SMTLIB commands.
class (SupportTermOps (Term h)) => SMTWriter h

-- | Create a forall expression
forallExpr :: SMTWriter h => [(Text, Some TypeMap)] -> Term h -> Term h

-- | Create an exists expression
existsExpr :: SMTWriter h => [(Text, Some TypeMap)] -> Term h -> Term h

-- | Create a constant array
--   
--   This may return Nothing if the solver does not support constant
--   arrays.
arrayConstant :: SMTWriter h => Maybe (ArrayConstantFn (Term h))

-- | Select an element from an array
arraySelect :: SMTWriter h => Term h -> [Term h] -> Term h

-- | 'arrayUpdate a i v' returns an array that contains value v at
--   index i, and the same value as in a at every other
--   index.
arrayUpdate :: SMTWriter h => Term h -> [Term h] -> Term h -> Term h

-- | Create a command that just defines a comment.
commentCommand :: SMTWriter h => f h -> Builder -> Command h

-- | Create a command that asserts a formula.
assertCommand :: SMTWriter h => f h -> Term h -> Command h

-- | Create a command that asserts a formula and attaches the given name to
--   it (primarily for the purposes of later reporting unsatisfiable
--   cores).
assertNamedCommand :: SMTWriter h => f h -> Term h -> Text -> Command h

-- | Generates command (push 1) that opens the corresponding
--   assertion frame
pushCommand :: SMTWriter h => f h -> Command h

-- | Generates command (pop 1) that closes the corresponding
--   assertion frame
popCommand :: SMTWriter h => f h -> Command h

-- | Generates command (push 2) that opens the corresponding
--   assertion frame
push2Command :: SMTWriter h => f h -> Command h

-- | Generates command (pop 2) that closes the corresponding
--   assertion frame, used for abduction
pop2Command :: SMTWriter h => f h -> Command h

-- | Pop several scopes.
popManyCommands :: SMTWriter h => f h -> Int -> [Command h]

-- | Reset the solver state, forgetting all pushed frames and assertions
resetCommand :: SMTWriter h => f h -> Command h

-- | Check if the current set of assumption is satisfiable. May require
--   multiple commands. The intial commands require an ack. The last one
--   does not.
checkCommands :: SMTWriter h => f h -> [Command h]

-- | Check if a collection of assumptions is satisfiable in the current
--   context. The assumptions must be given as the names of literals
--   already in scope.
checkWithAssumptionsCommands :: SMTWriter h => f h -> [Text] -> [Command h]

-- | Ask the solver to return an unsatisfiable core from among the
--   assumptions passed into the previous "check with assumptions" command.
getUnsatAssumptionsCommand :: SMTWriter h => f h -> Command h

-- | Ask the solver to return an unsatisfiable core from among the named
--   assumptions previously asserted using the assertNamedCommand
--   after an unsatisfiable checkCommand.
getUnsatCoreCommand :: SMTWriter h => f h -> Command h

-- | Ask the solver to return an abduct
getAbductCommand :: SMTWriter h => f h -> Text -> Term h -> Command h

-- | Ask the solver for the next abduct, used after a get-abduct command
getAbductNextCommand :: SMTWriter h => f h -> Command h

-- | Set an option/parameter.
setOptCommand :: SMTWriter h => f h -> Text -> Text -> Command h

-- | Declare a new symbol with the given name, arguments types, and result
--   type.
declareCommand :: SMTWriter h => f h -> Text -> Assignment TypeMap args -> TypeMap rtp -> Command h

-- | Define a new symbol with the given name, arguments, result type, and
--   associated expression.
--   
--   The argument contains the variable name and the type of the variable.
defineCommand :: SMTWriter h => f h -> Text -> [(Text, Some TypeMap)] -> TypeMap rtp -> Term h -> Command h

-- | Declare a new SyGuS function to synthesize with the given name,
--   arguments, and result type.
synthFunCommand :: SMTWriter h => f h -> Text -> [(Text, Some TypeMap)] -> TypeMap tp -> Command h

-- | Declare a new SyGuS universal variables with the given name and type.
declareVarCommand :: SMTWriter h => f h -> Text -> TypeMap tp -> Command h

-- | Add a SyGuS formula to the set of synthesis constraints.
constraintCommand :: SMTWriter h => f h -> Term h -> Command h

-- | Declare a struct datatype if is has not been already given the number
--   of arguments in the struct.
declareStructDatatype :: SMTWriter h => WriterConn t h -> Assignment TypeMap args -> IO ()

-- | Build a struct term with the given types and fields
structCtor :: SMTWriter h => Assignment TypeMap args -> [Term h] -> Term h

-- | Project a field from a struct with the given types
structProj :: SMTWriter h => Assignment TypeMap args -> Index args tp -> Term h -> Term h

-- | Produce a term representing a string literal
stringTerm :: SMTWriter h => Text -> Term h

-- | Compute the length of a term
stringLength :: SMTWriter h => Term h -> Term h

-- | stringIndexOf s t i computes the first index following or at
--   i where t appears within s as a substring, or -1 if
--   no such index exists
stringIndexOf :: SMTWriter h => Term h -> Term h -> Term h -> Term h

-- | Test if the first string contains the second string
stringContains :: SMTWriter h => Term h -> Term h -> Term h

-- | Test if the first string is a prefix of the second string
stringIsPrefixOf :: SMTWriter h => Term h -> Term h -> Term h

-- | Test if the first string is a suffix of the second string
stringIsSuffixOf :: SMTWriter h => Term h -> Term h -> Term h

-- | stringSubstring s off len extracts the substring of
--   s starting at index off and having length
--   len. The result of this operation is undefined if
--   off and len to not specify a valid substring of
--   s; in particular, we must have off+len <=
--   length(s).
stringSubstring :: SMTWriter h => Term h -> Term h -> Term h -> Term h

-- | Append the given strings
stringAppend :: SMTWriter h => [Term h] -> Term h

-- | Forget all previously-declared struct types.
resetDeclaredStructs :: SMTWriter h => WriterConn t h -> IO ()

-- | Write a command to the connection.
writeCommand :: SMTWriter h => WriterConn t h -> Command h -> IO ()

-- | Used when we need two way communication with the solver.
class SMTWriter h => SMTReadWriter h

-- | Get functions for parsing values out of the solver.
smtEvalFuns :: SMTReadWriter h => WriterConn t h -> InputStream Text -> SMTEvalFunctions h

-- | Parse a set result from the solver's response.
smtSatResult :: SMTReadWriter h => f h -> WriterConn t h -> IO (SatResult () ())

-- | Parse a list of names of assumptions that form an unsatisfiable core.
--   These correspond to previously-named assertions.
smtUnsatCoreResult :: SMTReadWriter h => f h -> WriterConn t h -> IO [Text]

-- | Parse an abduct returned by the get-abduct command
smtAbductResult :: SMTReadWriter h => f h -> WriterConn t h -> Text -> Term h -> IO String

-- | Parse an abduct returned by the get-abduct-next command
smtAbductNextResult :: SMTReadWriter h => f h -> WriterConn t h -> IO String

-- | Parse a list of names of assumptions that form an unsatisfiable core.
--   The boolean indicates the polarity of the atom: true for an ordinary
--   atom, false for a negated atom.
smtUnsatAssumptionsResult :: SMTReadWriter h => f h -> WriterConn t h -> IO [(Bool, Text)]
type SMTEvalBVArrayFn h w v = (1 <= w, 1 <= v) => NatRepr w -> NatRepr v -> Term h -> IO (Maybe (GroundArray (SingleCtx (BaseBVType w)) (BaseBVType v)))
newtype SMTEvalBVArrayWrapper h
SMTEvalBVArrayWrapper :: (forall w v. SMTEvalBVArrayFn h w v) -> SMTEvalBVArrayWrapper h
[unEvalBVArrayWrapper] :: SMTEvalBVArrayWrapper h -> forall w v. SMTEvalBVArrayFn h w v

-- | A term in the output language.
type family Term (h :: Type) :: Type
app :: Builder -> [Builder] -> Builder
app_list :: Builder -> [Builder] -> Builder
builder_list :: [Builder] -> Builder
data WriterConn t (h :: Type)

-- | The specific connection information.
connState :: WriterConn t h -> h
newWriterConn :: OutputStream Text -> InputStream Text -> AcknowledgementAction t cs -> String -> ResponseStrictness -> ProblemFeatures -> SymbolVarBimap t -> cs -> IO (WriterConn t cs)

-- | Clear the entry stack, and start with a fresh one.
resetEntryStack :: WriterConn t h -> IO ()

-- | Pop all but the topmost stack entry. Return the number of entries on
--   the stack prior to popping.
popEntryStackToTop :: WriterConn t h -> IO Int

-- | Return the number of pushed stack frames. Note, this is one fewer than
--   the number of entries in the stack beacuse the base entry is the
--   top-level context that is not in the scope of any push.
entryStackHeight :: WriterConn t h -> IO Int

-- | Push a new frame to the stack for maintaining the writer cache.
pushEntryStack :: WriterConn t h -> IO ()
popEntryStack :: WriterConn t h -> IO ()
cacheLookupFnNameBimap :: WriterConn t h -> [SomeExprSymFn t] -> IO (Bimap (SomeExprSymFn t) Text)
type family Command (h :: Type) :: Type

-- | Write a command to the connection along with position information if
--   it differs from the last position.
addCommand :: SMTWriter h => WriterConn t h -> Command h -> IO ()
addCommandNoAck :: SMTWriter h => WriterConn t h -> Command h -> IO ()

-- | Write a sequence of commands. All but the last should have
--   acknowledgement.
addCommands :: SMTWriter h => WriterConn t h -> [Command h] -> IO ()

-- | Create a new variable with the given name.
mkFreeVar :: SMTWriter h => WriterConn t h -> Assignment TypeMap args -> TypeMap rtp -> IO Text

-- | Consider the bound variable as free within the current assumption
--   frame.
bindVarAsFree :: SMTWriter h => WriterConn t h -> ExprBoundVar t tp -> IO ()

-- | TypeMap defines how a given BaseType maps to an SMTLIB
--   type.
--   
--   It is necessary as there may be several ways in which a base type can
--   be encoded.
data TypeMap (tp :: BaseType)
[BoolTypeMap] :: TypeMap BaseBoolType
[IntegerTypeMap] :: TypeMap BaseIntegerType
[RealTypeMap] :: TypeMap BaseRealType
[BVTypeMap] :: 1 <= w => !NatRepr w -> TypeMap (BaseBVType w)
[FloatTypeMap] :: !FloatPrecisionRepr fpp -> TypeMap (BaseFloatType fpp)
[UnicodeTypeMap] :: TypeMap (BaseStringType Unicode)
[ComplexToStructTypeMap] :: TypeMap BaseComplexType
[ComplexToArrayTypeMap] :: TypeMap BaseComplexType
[PrimArrayTypeMap] :: !Assignment TypeMap (idxl ::> idx) -> !TypeMap tp -> TypeMap (BaseArrayType (idxl ::> idx) tp)
[FnArrayTypeMap] :: !Assignment TypeMap (idxl ::> idx) -> TypeMap tp -> TypeMap (BaseArrayType (idxl ::> idx) tp)
[StructTypeMap] :: !Assignment TypeMap idx -> TypeMap (BaseStructType idx)

-- | Given a solver connection and a base type repr, typeMap
--   attempts to find the best encoding for a variable of that type
--   supported by teh solver.
typeMap :: WriterConn t h -> BaseTypeRepr tp -> Either BaseTypeError (TypeMap tp)

-- | Create a variable name eqivalent to the given expression.
freshBoundVarName :: SMTWriter h => WriterConn t h -> DefineStyle -> [(Text, Some TypeMap)] -> TypeMap rtp -> Term h -> IO Text

-- | Assume that the given formula holds.
assumeFormula :: SMTWriter h => WriterConn t h -> Term h -> IO ()
assumeFormulaWithName :: SMTWriter h => WriterConn t h -> Term h -> Text -> IO ()
assumeFormulaWithFreshName :: SMTWriter h => WriterConn t h -> Term h -> IO Text
data DefineStyle
FunctionDefinition :: DefineStyle
EqualityDefinition :: DefineStyle

-- | An action for consuming an acknowledgement message from the solver, if
--   it is configured to produce ack messages.
newtype AcknowledgementAction t h
AckAction :: (WriterConn t h -> Command h -> IO ()) -> AcknowledgementAction t h
[runAckAction] :: AcknowledgementAction t h -> WriterConn t h -> Command h -> IO ()

-- | Strictness level for parsing solver responses.
data ResponseStrictness

-- | allows other output preceeding recognized solver responses
Lenient :: ResponseStrictness

-- | parse _only_ recognized solver responses; fail on anything else
Strict :: ResponseStrictness

-- | Given an optional override configuration option, return the SMT
--   response parsing strictness that should be applied based on the
--   override or thedefault strictSMTParsing configuration.
parserStrictness :: Maybe (ConfigOption BaseBoolType) -> ConfigOption BaseBoolType -> Config -> IO ResponseStrictness

-- | An acknowledgement action that does nothing
nullAcknowledgementAction :: AcknowledgementAction t h
addSynthFun :: SMTWriter h => WriterConn t h -> ExprSymFn t args ret -> IO ()
addDeclareVar :: SMTWriter h => WriterConn t h -> ExprBoundVar t tp -> IO ()
addConstraint :: SMTWriter h => WriterConn t h -> BoolExpr t -> IO ()

-- | Write assume formula predicates for asserting predicate holds.
assume :: SMTWriter h => WriterConn t h -> BoolExpr t -> IO ()

-- | Write a expression to SMT
mkSMTTerm :: SMTWriter h => WriterConn t h -> Expr t tp -> IO (Term h)

-- | Write a logical expression.
mkFormula :: SMTWriter h => WriterConn t h -> BoolExpr t -> IO (Term h)
mkAtomicFormula :: SMTWriter h => WriterConn t h -> BoolExpr t -> IO Text
data SMTEvalFunctions h
SMTEvalFunctions :: (Term h -> IO Bool) -> (forall w. NatRepr w -> Term h -> IO (BV w)) -> (Term h -> IO Rational) -> (forall fpp. FloatPrecisionRepr fpp -> Term h -> IO (BV (FloatPrecisionBits fpp))) -> Maybe (SMTEvalBVArrayWrapper h) -> (Term h -> IO Text) -> SMTEvalFunctions h

-- | Given a SMT term for a Boolean value, this should return an indication
--   of whether the term is assigned true or false.
[smtEvalBool] :: SMTEvalFunctions h -> Term h -> IO Bool

-- | Given a bitwidth, and a SMT term for a bitvector with that bitwidth,
--   this should return an unsigned integer with the value of that
--   bitvector.
[smtEvalBV] :: SMTEvalFunctions h -> forall w. NatRepr w -> Term h -> IO (BV w)

-- | Given a SMT term for real value, this should return a rational value
--   for that term.
[smtEvalReal] :: SMTEvalFunctions h -> Term h -> IO Rational

-- | Given floating point format, and an SMT term for a floating-point
--   value in that format, this returns an unsigned integer with the bits
--   of the IEEE-754 representation.
[smtEvalFloat] :: SMTEvalFunctions h -> forall fpp. FloatPrecisionRepr fpp -> Term h -> IO (BV (FloatPrecisionBits fpp))

-- | If Just, a function to read arrays whose domain and codomain
--   are both bitvectors. If Nothing, signifies that we should fall
--   back to index-selection representation of arrays.
[smtEvalBvArray] :: SMTEvalFunctions h -> Maybe (SMTEvalBVArrayWrapper h)

-- | Given a SMT term representing as sequence of bytes, return the value
--   as a bytestring.
[smtEvalString] :: SMTEvalFunctions h -> Term h -> IO Text

-- | The function creates a function for evaluating elts to concrete values
--   given a connection to an SMT solver along with some functions for
--   evaluating different types of terms to concrete values.
smtExprGroundEvalFn :: forall t h. SMTWriter h => WriterConn t h -> SMTEvalFunctions h -> IO (GroundEvalFn t)

-- | This describes the result that was collected from the solver.
data CollectorResults h a
CollectorResults :: !a -> ![(Text, Term h)] -> ![(Text, Some TypeMap)] -> ![Term h] -> CollectorResults h a

-- | Result from sandboxed computation.
[crResult] :: CollectorResults h a -> !a

-- | List of bound variables.
[crBindings] :: CollectorResults h a -> ![(Text, Term h)]

-- | Constants added during generation.
[crFreeConstants] :: CollectorResults h a -> ![(Text, Some TypeMap)]

-- | List of Boolean predicates asserted by collector.
[crSideConds] :: CollectorResults h a -> ![Term h]

-- | Convert an element to a base expression.
mkBaseExpr :: SMTWriter h => Expr t tp -> SMTCollector t h (Term h)

-- | This runs the side collector and collects the results.
runInSandbox :: SupportTermOps (Term h) => WriterConn t h -> SMTCollector t h a -> IO (CollectorResults h a)

-- | Rounding modes for IEEE-754 floating point operations.
data RoundingMode

-- | Round to nearest even.
RNE :: RoundingMode

-- | Round to nearest away.
RNA :: RoundingMode

-- | Round toward plus Infinity.
RTP :: RoundingMode

-- | Round toward minus Infinity.
RTN :: RoundingMode

-- | Round toward zero.
RTZ :: RoundingMode
instance GHC.Show.Show What4.Protocol.SMTWriter.ResponseStrictness
instance GHC.Classes.Eq What4.Protocol.SMTWriter.ResponseStrictness
instance GHC.Classes.Eq What4.Protocol.SMTWriter.TermLifetime
instance GHC.Show.Show What4.Protocol.SMTWriter.DefineStyle
instance GHC.Classes.Eq What4.Protocol.SMTWriter.DefineStyle
instance Data.Parameterized.Classes.ShowF What4.Protocol.SMTWriter.TypeMap
instance GHC.Show.Show (What4.Protocol.SMTWriter.TypeMap a)
instance GHC.Classes.Eq (What4.Protocol.SMTWriter.TypeMap tp)
instance Data.Type.Equality.TestEquality What4.Protocol.SMTWriter.TypeMap

-- | This module defines types and operations for parsing SMTLib2 solver
--   responses.
--   
--   These are high-level responses, as describe in
--   https://smtlib.cs.uiowa.edu/papers/smt-lib-reference-v2.6-r2017-07-18.pdf,
--   page 47, Figure 3.9.
--   
--   This parser is designed to be the top level handling for solver
--   responses, and to be used in conjuction with
--   What4.Protocol.SMTLib2.Parse and What4.Protocol.SExp with the latter
--   handling detailed parsing of specific constructs returned in the body
--   of the general response.
module What4.Protocol.SMTLib2.Response
data SMTResponse
AckSuccess :: SMTResponse
AckUnsupported :: SMTResponse
AckError :: Text -> SMTResponse
AckSat :: SMTResponse
AckUnsat :: SMTResponse
AckUnknown :: SMTResponse
AckInfeasible :: SMTResponse
AckFail :: SMTResponse
RspName :: Text -> SMTResponse
RspVersion :: Text -> SMTResponse
RspErrBehavior :: Text -> SMTResponse
RspOutOfMemory :: SMTResponse
RspRsnIncomplete :: SMTResponse
RspUnkReason :: SExp -> SMTResponse
AckSuccessSExp :: SExp -> SMTResponse
AckSkipped :: Text -> SMTResponse -> SMTResponse
data SMTLib2Exception
SMTLib2Unsupported :: Command -> SMTLib2Exception
SMTLib2Error :: Command -> Text -> SMTLib2Exception
SMTLib2ParseError :: SMTLib2Intent -> [Command] -> Text -> SMTLib2Exception
SMTLib2ResponseUnrecognized :: Command -> Text -> SMTLib2Exception
SMTLib2InvalidResponse :: Command -> SMTLib2Intent -> SMTResponse -> SMTLib2Exception

-- | Called to get a response from the SMT connection.
getSolverResponse :: WriterConn t h -> IO (Either SomeException SMTResponse)

-- | Gets a limited set of responses, throwing an exception when a response
--   is not matched by the filter. Also throws exceptions for standard
--   error results. The passed command and intent arguments are only used
--   for marking error messages.
--   
--   Callers which do not want exceptions thrown for standard error
--   conditions should feel free to use getSolverResponse and handle
--   all response cases themselves.
getLimitedSolverResponse :: String -> (SMTResponse -> Maybe a) -> WriterConn t h -> Command -> IO a
smtParseOptions :: [ConfigDesc]
strictSMTParsing :: ConfigOption BaseBoolType
strictSMTParseOpt :: ConfigDesc
instance GHC.Show.Show What4.Protocol.SMTLib2.Response.SMTResponse
instance GHC.Classes.Eq What4.Protocol.SMTLib2.Response.SMTResponse
instance GHC.Show.Show What4.Protocol.SMTLib2.Response.SMTLib2Exception
instance GHC.Exception.Type.Exception What4.Protocol.SMTLib2.Response.SMTLib2Exception

-- | The module reexports the most commonly used types and operations of
--   the What4 expression representation.
module What4.Expr

-- | Cache for storing dag terms. Parameter t is a phantom type
--   brand used to track nonces.
data ExprBuilder t (st :: Type -> Type) (fs :: Type)
newExprBuilder :: FloatModeRepr fm -> st t -> NonceGenerator IO t -> IO (ExprBuilder t st (Flags fm))

-- | Restart caching applications in backend (clears cache if it is
--   currently caching).
startCaching :: ExprBuilder t st fs -> IO ()

-- | Stop caching applications in backend.
stopCaching :: ExprBuilder t st fs -> IO ()
userState :: Lens' (ExprBuilder t st fs) (st t)
exprCounter :: Getter (ExprBuilder t st fs) (NonceGenerator IO t)
curProgramLoc :: ExprBuilder t st fs -> IO ProgramLoc
unaryThreshold :: Getter (ExprBuilder t st fs) (OptionSetting BaseIntegerType)
cacheStartSize :: Getter (ExprBuilder t st fs) (OptionSetting BaseIntegerType)

-- | Return a new expr builder where the configuration object has been
--   "split" using the splitConfig operation. The returned sym
--   will share any preexisting options with the input sym, but any new
--   options added with extendConfig will not be shared. This may
--   be useful if the expression builder needs to be shared across threads,
--   or sequentially for separate use cases. Note, however, that hash
--   consing settings, solver loggers and the current program location will
--   be shared.
exprBuilderSplitConfig :: ExprBuilder t st fs -> IO (ExprBuilder t st fs)

-- | Return a new expr builder where all configuration settings have been
--   isolated from the original. The Config object of the output
--   expr builder will have only the default options that are installed via
--   newExprBuilder, and configuration changes to either expr
--   builder will not be visible to the other. This includes caching
--   settings, the current program location, and installed solver loggers.
exprBuilderFreshConfig :: ExprBuilder t st fs -> IO (ExprBuilder t st fs)

-- | A "dummy" data type that can be used for the user state field of an
--   ExprBuilder when there is no other interesting state to track.
data EmptyExprBuilderState t
EmptyExprBuilderState :: EmptyExprBuilderState t

-- | Mode flag for how floating-point values should be interpreted.
data FloatMode
data FloatModeRepr :: FloatMode -> Type
[FloatIEEERepr] :: FloatModeRepr FloatIEEE
[FloatUninterpretedRepr] :: FloatModeRepr FloatUninterpreted
[FloatRealRepr] :: FloatModeRepr FloatReal

-- | In this mode "interpreted" floating-point values are treated as
--   bit-precise IEEE-754 floats.
type FloatIEEE = 'FloatIEEE

-- | In this mode "interpreted" floating-point values are treated as
--   bitvectors of the appropriate width, and all operations on them are
--   translated as uninterpreted functions.
type FloatUninterpreted = 'FloatUninterpreted

-- | In this mode "interpreted" floating-point values are treated as
--   real-number values, to the extent possible. Expressions that would
--   result in infinities or NaN will yield unspecified values in this
--   mode, or directly produce runtime errors.
type FloatReal = 'FloatReal
data Flags (fi :: FloatMode)
type BoolExpr t = Expr t BaseBoolType
type IntegerExpr t = Expr t BaseIntegerType
type RealExpr t = Expr t BaseRealType
type BVExpr t n = Expr t (BaseBVType n)
type CplxExpr t = Expr t BaseComplexType
type StringExpr t si = Expr t (BaseStringType si)

-- | The main ExprBuilder expression datastructure. The non-trivial
--   Expr values constructed by this module are uniquely
--   identified by a nonce value that is used to explicitly represent
--   sub-term sharing. When traversing the structure of an Expr it
--   is usually very important to memoize computations based on the values
--   of these identifiers to avoid exponential blowups due to shared term
--   structure.
--   
--   Type parameter t is a phantom type brand used to relate
--   nonces to a specific nonce generator (similar to the s
--   parameter of the ST monad). The type index tp of
--   kind BaseType indicates the type of the values denoted by the
--   given expression.
--   
--   Type Expr t instantiates the type family
--   SymExpr (ExprBuilder t st).
data Expr t (tp :: BaseType)
[SemiRingLiteral] :: !SemiRingRepr sr -> !Coefficient sr -> !ProgramLoc -> Expr t (SemiRingBase sr)
[BoolExpr] :: !Bool -> !ProgramLoc -> Expr t BaseBoolType
[FloatExpr] :: !FloatPrecisionRepr fpp -> !BigFloat -> !ProgramLoc -> Expr t (BaseFloatType fpp)
[StringExpr] :: !StringLiteral si -> !ProgramLoc -> Expr t (BaseStringType si)
[AppExpr] :: {-# UNPACK #-} !AppExpr t tp -> Expr t tp
[NonceAppExpr] :: {-# UNPACK #-} !NonceAppExpr t tp -> Expr t tp
[BoundVarExpr] :: !ExprBoundVar t tp -> Expr t tp
exprLoc :: Expr t tp -> ProgramLoc

-- | Pretty print an Expr using let bindings to create the term.
ppExpr :: Expr t tp -> Doc ann

-- | This type represents Expr values that were built from an
--   App.
--   
--   Parameter t is a phantom type brand used to track nonces.
--   
--   Selector functions are provided to destruct AppExpr values, but
--   the constructor is kept hidden. The preferred way to construct an
--   Expr from an App is to use sbMakeExpr.
data AppExpr t (tp :: BaseType)
appExprId :: AppExpr t tp -> Nonce t tp
appExprLoc :: AppExpr t tp -> ProgramLoc
appExprApp :: AppExpr t tp -> App (Expr t) tp

-- | Type App e tp encodes the top-level application of an
--   Expr expression. It includes first-order expression forms that
--   do not bind variables (contrast with NonceApp).
--   
--   Parameter e is used everywhere a recursive sub-expression
--   would go. Uses of the App type will tie the knot through this
--   parameter. Parameter tp indicates the type of the expression.
data App (e :: BaseType -> Type) (tp :: BaseType)
[BaseIte] :: !BaseTypeRepr tp -> !Integer -> !e BaseBoolType -> !e tp -> !e tp -> App e tp
[BaseEq] :: !BaseTypeRepr tp -> !e tp -> !e tp -> App e BaseBoolType
[NotPred] :: !e BaseBoolType -> App e BaseBoolType
[ConjPred] :: !BoolMap e -> App e BaseBoolType
[SemiRingSum] :: {-# UNPACK #-} !WeightedSum e sr -> App e (SemiRingBase sr)
[SemiRingProd] :: {-# UNPACK #-} !SemiRingProduct e sr -> App e (SemiRingBase sr)
[SemiRingLe] :: !OrderedSemiRingRepr sr -> !e (SemiRingBase sr) -> !e (SemiRingBase sr) -> App e BaseBoolType
[RealIsInteger] :: !e BaseRealType -> App e BaseBoolType
[IntDiv] :: !e BaseIntegerType -> !e BaseIntegerType -> App e BaseIntegerType
[IntMod] :: !e BaseIntegerType -> !e BaseIntegerType -> App e BaseIntegerType
[IntAbs] :: !e BaseIntegerType -> App e BaseIntegerType
[IntDivisible] :: !e BaseIntegerType -> Natural -> App e BaseBoolType
[RealDiv] :: !e BaseRealType -> !e BaseRealType -> App e BaseRealType
[RealSqrt] :: !e BaseRealType -> App e BaseRealType
[RealSpecialFunction] :: !SpecialFunction args -> !SpecialFnArgs e BaseRealType args -> App e BaseRealType
[BVTestBit] :: 1 <= w => !Natural -> !e (BaseBVType w) -> App e BaseBoolType
[BVSlt] :: 1 <= w => !e (BaseBVType w) -> !e (BaseBVType w) -> App e BaseBoolType
[BVUlt] :: 1 <= w => !e (BaseBVType w) -> !e (BaseBVType w) -> App e BaseBoolType
[BVOrBits] :: 1 <= w => !NatRepr w -> !BVOrSet e w -> App e (BaseBVType w)
[BVUnaryTerm] :: 1 <= n => !UnaryBV (e BaseBoolType) n -> App e (BaseBVType n)
[BVConcat] :: (1 <= u, 1 <= v, 1 <= (u + v)) => !NatRepr (u + v) -> !e (BaseBVType u) -> !e (BaseBVType v) -> App e (BaseBVType (u + v))
[BVSelect] :: (1 <= n, (idx + n) <= w) => !NatRepr idx -> !NatRepr n -> !e (BaseBVType w) -> App e (BaseBVType n)
[BVFill] :: 1 <= w => !NatRepr w -> !e BaseBoolType -> App e (BaseBVType w)
[BVUdiv] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVUrem] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVSdiv] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVSrem] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVShl] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVLshr] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVAshr] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVRol] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVRor] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVZext] :: (1 <= w, (w + 1) <= r, 1 <= r) => !NatRepr r -> !e (BaseBVType w) -> App e (BaseBVType r)
[BVSext] :: (1 <= w, (w + 1) <= r, 1 <= r) => !NatRepr r -> !e (BaseBVType w) -> App e (BaseBVType r)
[BVPopcount] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVCountTrailingZeros] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> App e (BaseBVType w)
[BVCountLeadingZeros] :: 1 <= w => !NatRepr w -> !e (BaseBVType w) -> App e (BaseBVType w)
[FloatNeg] :: !FloatPrecisionRepr fpp -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatAbs] :: !FloatPrecisionRepr fpp -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatSqrt] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatAdd] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatSub] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatMul] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatDiv] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatRem] :: !FloatPrecisionRepr fpp -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatFMA] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatFpEq] :: !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatLe] :: !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatLt] :: !e (BaseFloatType fpp) -> !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsNaN] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsInf] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsZero] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsPos] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsNeg] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsSubnorm] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatIsNorm] :: !e (BaseFloatType fpp) -> App e BaseBoolType
[FloatCast] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp') -> App e (BaseFloatType fpp)
[FloatRound] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseFloatType fpp) -> App e (BaseFloatType fpp)
[FloatFromBinary] :: (2 <= eb, 2 <= sb) => !FloatPrecisionRepr (FloatingPointPrecision eb sb) -> !e (BaseBVType (eb + sb)) -> App e (BaseFloatType (FloatingPointPrecision eb sb))
[FloatToBinary] :: (2 <= eb, 2 <= sb, 1 <= (eb + sb)) => !FloatPrecisionRepr (FloatingPointPrecision eb sb) -> !e (BaseFloatType (FloatingPointPrecision eb sb)) -> App e (BaseBVType (eb + sb))
[BVToFloat] :: 1 <= w => !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseBVType w) -> App e (BaseFloatType fpp)
[SBVToFloat] :: 1 <= w => !FloatPrecisionRepr fpp -> !RoundingMode -> !e (BaseBVType w) -> App e (BaseFloatType fpp)
[RealToFloat] :: !FloatPrecisionRepr fpp -> !RoundingMode -> !e BaseRealType -> App e (BaseFloatType fpp)
[FloatToBV] :: 1 <= w => !NatRepr w -> !RoundingMode -> !e (BaseFloatType fpp) -> App e (BaseBVType w)
[FloatToSBV] :: 1 <= w => !NatRepr w -> !RoundingMode -> !e (BaseFloatType fpp) -> App e (BaseBVType w)
[FloatToReal] :: !e (BaseFloatType fpp) -> App e BaseRealType
[FloatSpecialFunction] :: !FloatPrecisionRepr fpp -> !SpecialFunction args -> !SpecialFnArgs e (BaseFloatType fpp) args -> App e (BaseFloatType fpp)
[ArrayMap] :: !Assignment BaseTypeRepr (i ::> itp) -> !BaseTypeRepr tp -> !ArrayUpdateMap e (i ::> itp) tp -> !e (BaseArrayType (i ::> itp) tp) -> App e (BaseArrayType (i ::> itp) tp)
[ConstantArray] :: !Assignment BaseTypeRepr (i ::> tp) -> !BaseTypeRepr b -> !e b -> App e (BaseArrayType (i ::> tp) b)
[UpdateArray] :: !BaseTypeRepr b -> !Assignment BaseTypeRepr (i ::> tp) -> !e (BaseArrayType (i ::> tp) b) -> !Assignment e (i ::> tp) -> !e b -> App e (BaseArrayType (i ::> tp) b)
[SelectArray] :: !BaseTypeRepr b -> !e (BaseArrayType (i ::> tp) b) -> !Assignment e (i ::> tp) -> App e b
[CopyArray] :: 1 <= w => !NatRepr w -> !BaseTypeRepr a -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e (BaseBVType w) -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseArrayType (SingleCtx (BaseBVType w)) a)
[SetArray] :: 1 <= w => !NatRepr w -> !BaseTypeRepr a -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e a -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e (BaseArrayType (SingleCtx (BaseBVType w)) a)
[EqualArrayRange] :: 1 <= w => !NatRepr w -> !BaseTypeRepr a -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e (BaseArrayType (SingleCtx (BaseBVType w)) a) -> !e (BaseBVType w) -> !e (BaseBVType w) -> !e (BaseBVType w) -> !e (BaseBVType w) -> App e BaseBoolType
[IntegerToReal] :: !e BaseIntegerType -> App e BaseRealType
[RealToInteger] :: !e BaseRealType -> App e BaseIntegerType
[BVToInteger] :: 1 <= w => !e (BaseBVType w) -> App e BaseIntegerType
[SBVToInteger] :: 1 <= w => !e (BaseBVType w) -> App e BaseIntegerType
[IntegerToBV] :: 1 <= w => !e BaseIntegerType -> NatRepr w -> App e (BaseBVType w)
[RoundReal] :: !e BaseRealType -> App e BaseIntegerType
[RoundEvenReal] :: !e BaseRealType -> App e BaseIntegerType
[FloorReal] :: !e BaseRealType -> App e BaseIntegerType
[CeilReal] :: !e BaseRealType -> App e BaseIntegerType
[Cplx] :: {-# UNPACK #-} !Complex (e BaseRealType) -> App e BaseComplexType
[RealPart] :: !e BaseComplexType -> App e BaseRealType
[ImagPart] :: !e BaseComplexType -> App e BaseRealType
[StringContains] :: !e (BaseStringType si) -> !e (BaseStringType si) -> App e BaseBoolType
[StringIsPrefixOf] :: !e (BaseStringType si) -> !e (BaseStringType si) -> App e BaseBoolType
[StringIsSuffixOf] :: !e (BaseStringType si) -> !e (BaseStringType si) -> App e BaseBoolType
[StringIndexOf] :: !e (BaseStringType si) -> !e (BaseStringType si) -> !e BaseIntegerType -> App e BaseIntegerType
[StringSubstring] :: !StringInfoRepr si -> !e (BaseStringType si) -> !e BaseIntegerType -> !e BaseIntegerType -> App e (BaseStringType si)
[StringAppend] :: !StringInfoRepr si -> !StringSeq e si -> App e (BaseStringType si)
[StringLength] :: !e (BaseStringType si) -> App e BaseIntegerType
[StructCtor] :: !Assignment BaseTypeRepr flds -> !Assignment e flds -> App e (BaseStructType flds)
[StructField] :: !e (BaseStructType flds) -> !Index flds tp -> !BaseTypeRepr tp -> App e tp

-- | This type represents Expr values that were built from a
--   NonceApp.
--   
--   Parameter t is a phantom type brand used to track nonces.
--   
--   Selector functions are provided to destruct NonceAppExpr
--   values, but the constructor is kept hidden. The preferred way to
--   construct an Expr from a NonceApp is to use
--   sbNonceExpr.
data NonceAppExpr t (tp :: BaseType)
nonceExprId :: NonceAppExpr t tp -> Nonce t tp
nonceExprLoc :: NonceAppExpr t tp -> ProgramLoc
nonceExprApp :: NonceAppExpr t tp -> NonceApp t (Expr t) tp

-- | Type NonceApp t e tp encodes the top-level application of an
--   Expr. It includes expression forms that bind variables
--   (contrast with App).
--   
--   Parameter t is a phantom type brand used to track nonces.
--   Parameter e is used everywhere a recursive sub-expression
--   would go. Uses of the NonceApp type will tie the knot through
--   this parameter. Parameter tp indicates the type of the
--   expression.
data NonceApp t (e :: BaseType -> Type) (tp :: BaseType)
[Annotation] :: !BaseTypeRepr tp -> !Nonce t tp -> !e tp -> NonceApp t e tp
[Forall] :: !ExprBoundVar t tp -> !e BaseBoolType -> NonceApp t e BaseBoolType
[Exists] :: !ExprBoundVar t tp -> !e BaseBoolType -> NonceApp t e BaseBoolType
[ArrayFromFn] :: !ExprSymFn t (idx ::> itp) ret -> NonceApp t e (BaseArrayType (idx ::> itp) ret)
[MapOverArrays] :: !ExprSymFn t (ctx ::> d) r -> !Assignment BaseTypeRepr (idx ::> itp) -> !Assignment (ArrayResultWrapper e (idx ::> itp)) (ctx ::> d) -> NonceApp t e (BaseArrayType (idx ::> itp) r)
[ArrayTrueOnEntries] :: !ExprSymFn t (idx ::> itp) BaseBoolType -> !e (BaseArrayType (idx ::> itp) BaseBoolType) -> NonceApp t e BaseBoolType
[FnApp] :: !ExprSymFn t args ret -> !Assignment e args -> NonceApp t e ret

-- | Information about bound variables. Parameter t is a phantom
--   type brand used to track nonces.
--   
--   Type ExprBoundVar t instantiates the type family
--   BoundVar (ExprBuilder t st).
--   
--   Selector functions are provided to destruct ExprBoundVar
--   values, but the constructor is kept hidden. The preferred way to
--   construct a ExprBoundVar is to use freshBoundVar.
data ExprBoundVar t (tp :: BaseType)
bvarId :: ExprBoundVar t tp -> Nonce t tp
bvarLoc :: ExprBoundVar t tp -> ProgramLoc
bvarName :: ExprBoundVar t tp -> SolverSymbol
bvarKind :: ExprBoundVar t tp -> VarKind

-- | The Kind of a bound variable.
data VarKind

-- | A variable appearing in a quantifier.
QuantifierVarKind :: VarKind

-- | A variable appearing as a latch input.
LatchVarKind :: VarKind

-- | A variable appearing in a uninterpreted constant
UninterpVarKind :: VarKind
boundVars :: Expr t tp -> ST s (BoundVarMap s t)

-- | This represents a symbolic function in the simulator. Parameter
--   t is a phantom type brand used to track nonces. The
--   args and ret parameters define the types of
--   arguments and the return type of the function.
--   
--   Type ExprSymFn t (Expr t) instantiates the type family
--   SymFn (ExprBuilder t st).
data ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType)
ExprSymFn :: !Nonce t (args ::> ret) -> !SolverSymbol -> !SymFnInfo t args ret -> !ProgramLoc -> ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType)
[symFnId] :: ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType) -> !Nonce t (args ::> ret)
[symFnName] :: ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType) -> !SolverSymbol
[symFnInfo] :: ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType) -> !SymFnInfo t args ret
[symFnLoc] :: ExprSymFn t (args :: Ctx BaseType) (ret :: BaseType) -> !ProgramLoc

-- | This describes information about an undefined or defined function.
--   Parameter t is a phantom type brand used to track nonces. The
--   args and ret parameters define the types of
--   arguments and the return type of the function.
data SymFnInfo t (args :: Ctx BaseType) (ret :: BaseType)

-- | Information about the argument type and return type of an
--   uninterpreted function.
UninterpFnInfo :: !Assignment BaseTypeRepr args -> !BaseTypeRepr ret -> SymFnInfo t (args :: Ctx BaseType) (ret :: BaseType)

-- | Information about a defined function. Includes bound variables and an
--   expression associated to a defined function, as well as a policy for
--   when to unfold the body.
DefinedFnInfo :: !Assignment (ExprBoundVar t) args -> !Expr t ret -> !UnfoldPolicy -> SymFnInfo t (args :: Ctx BaseType) (ret :: BaseType)

-- | This is a function that corresponds to a matlab solver function. It
--   includes the definition as a ExprBuilder expr to enable export to
--   other solvers.
MatlabSolverFnInfo :: !MatlabSolverFn (Expr t) args ret -> !Assignment (ExprBoundVar t) args -> !Expr t ret -> SymFnInfo t (args :: Ctx BaseType) (ret :: BaseType)
symFnArgTypes :: ExprSymFn t args ret -> Assignment BaseTypeRepr args
symFnReturnType :: ExprSymFn t args ret -> BaseTypeRepr ret

-- | The constant values in the semiring.
type family Coefficient (sr :: SemiRing) :: Type

-- | Data-kind representing the semirings What4 supports.
data SemiRing

-- | Data-kind indicating the two flavors of bitvector semirings. The
--   ordinary arithmetic semiring consists of addition and multiplication,
--   and the "bits" semiring consists of bitwise xor and bitwise and.
data BVFlavor
data SemiRingRepr (sr :: SemiRing)
[SemiRingIntegerRepr] :: SemiRingRepr SemiRingInteger
[SemiRingRealRepr] :: SemiRingRepr SemiRingReal
[SemiRingBVRepr] :: 1 <= w => !BVFlavorRepr fv -> !NatRepr w -> SemiRingRepr (SemiRingBV fv w)
data BVFlavorRepr (fv :: BVFlavor)
[BVArithRepr] :: BVFlavorRepr BVArith
[BVBitsRepr] :: BVFlavorRepr BVBits

-- | The subset of semirings that are equipped with an appropriate
--   (order-respecting) total order.
data OrderedSemiRingRepr (sr :: SemiRing)
[OrderedSemiRingIntegerRepr] :: OrderedSemiRingRepr SemiRingInteger
[OrderedSemiRingRealRepr] :: OrderedSemiRingRepr SemiRingReal

-- | A weighted sum of semiring values. Mathematically, this represents an
--   affine operation on the underlying expressions.
data WeightedSum (f :: BaseType -> Type) (sr :: SemiRing)

-- | A unary bitvector encoding where the map contains predicates such as
--   u^.unaryBVMap^.at i holds iff the value represented by
--   u is less than or equal to i.
--   
--   The map stored in the representation should always have a single
--   element, and the largest integer stored in the map should be
--   associated with a predicate representing "true". This means that if
--   the map contains only a single binding, then it represents a constant.
data UnaryBV p (n :: Nat)

-- | The theory that a symbol belongs to.
data AppTheory
BoolTheory :: AppTheory
LinearArithTheory :: AppTheory
NonlinearArithTheory :: AppTheory
ComputableArithTheory :: AppTheory
BitvectorTheory :: AppTheory
QuantifierTheory :: AppTheory
StringTheory :: AppTheory
FloatingPointTheory :: AppTheory
ArrayTheory :: AppTheory

-- | Theory attributed to structs (equivalent to records in
--   CVC4CVC5Z3, tuples in Yices)
StructTheory :: AppTheory

-- | Theory attributed application functions.
FnTheory :: AppTheory
quantTheory :: NonceApp t (Expr t) tp -> AppTheory
appTheory :: App (Expr t) tp -> AppTheory
type family GroundValue (tp :: BaseType)

-- | A newtype wrapper around ground value for use in a cache.
newtype GroundValueWrapper tp
GVW :: GroundValue tp -> GroundValueWrapper tp
[unGVW] :: GroundValueWrapper tp -> GroundValue tp

-- | A representation of a ground-value array.
data GroundArray idx b

-- | Lookup function for querying by index
ArrayMapping :: (Assignment GroundValueWrapper idx -> IO (GroundValue b)) -> GroundArray idx b

-- | Default value and finite map of particular indices
ArrayConcrete :: GroundValue b -> Map (Assignment IndexLit idx) (GroundValue b) -> GroundArray idx b

-- | Look up an index in an ground array.
lookupArray :: Assignment BaseTypeRepr idx -> GroundArray idx b -> Assignment GroundValueWrapper idx -> IO (GroundValue b)

-- | A function that calculates ground values for elements. Clients of
--   solvers should use the groundEval function for computing
--   values in models.
newtype GroundEvalFn t
GroundEvalFn :: (forall tp. Expr t tp -> IO (GroundValue tp)) -> GroundEvalFn t
[groundEval] :: GroundEvalFn t -> forall tp. Expr t tp -> IO (GroundValue tp)

-- | Function that calculates upper and lower bounds for real-valued
--   elements. This type is used for solvers (e.g., dReal) that give only
--   approximate solutions.
type ExprRangeBindings t = RealExpr t -> IO (Maybe Rational, Maybe Rational)

module What4.Serialize.Printer

-- | Serialize a What4 Expr as a well-formed s-expression (i.e., one which
--   contains no improper lists). Equivalent to (resSExpr
--   (serializeExpr' defaultConfig)). Sharing in the AST is achieved
--   via a top-level let-binding around the emitted expression (unless
--   there are no terms with non-atomic terms which can be shared).
serializeExpr :: Expr t tp -> SExpr

-- | Serialize a What4 Expr as a well-formed s-expression (i.e., one which
--   contains no improper lists) according to the configuration. Sharing in
--   the AST is achieved via a top-level let-binding around the emitted
--   expression (unless there are no terms with non-atomic terms which can
--   be shared).
serializeExprWithConfig :: Config -> Expr t tp -> Result t

-- | Serialize a What4 ExprSymFn as a well-formed s-expression (i.e., one
--   which contains no improper lists). Equivalent to (resSExpr
--   (serializeSymFn' defaultConfig)). Sharing in the AST is achieved
--   via a top-level let-binding around the emitted expression (unless
--   there are no terms with non-atomic terms which can be shared).
serializeSymFn :: ExprSymFn t dom ret -> SExpr

-- | Serialize a What4 ExprSymFn as a well-formed s-expression (i.e., one
--   which contains no improper lists) according to the configuration.
--   Sharing in the AST is achieved via a top-level let-binding around the
--   emitted expression (unless there are no terms with non-atomic terms
--   which can be shared).
serializeSymFnWithConfig :: Config -> ExprSymFn t dom ret -> Result t
serializeBaseType :: BaseTypeRepr tp -> SExpr

-- | Convert an Assignment of base types into a list of base types SExpr,
--   where the left-to-right syntactic ordering of the types is maintained.
convertBaseTypes :: Assignment BaseTypeRepr tps -> [SExpr]

-- | Controls how expressions and functions are serialized.
data Config
Config :: Bool -> Bool -> Config

-- | When True, any free What4 ExprBoundVar encountered
--   is simply serialized with a unique name, and the mapping from What4
--   ExprBoundVar to unique names is returned after serialization. When
--   False, an error is raised when a "free" ExprBoundVar is
--   encountered.
[cfgAllowFreeVars] :: Config -> Bool

-- | When True, any encountered What4 ExprSymFn during
--   serialization is simply assigned a unique name and the mapping from
--   What4 ExprSymFn to unique name is returned after serialization. When
--   @False, encountered ExprSymFns are serialized at the top level of the
--   expression in a `(letfn ([f ...]) ...)`.
[cfgAllowFreeSymFns] :: Config -> Bool
data Result t
Result :: WellFormedSExpr Atom -> VarNameEnv t -> FnNameEnv t -> Result t

-- | The serialized term.
[resSExpr] :: Result t -> WellFormedSExpr Atom

-- | The free BoundVars that were encountered during serialization and
--   their associated fresh name that was used to generate the
--   s-expression.
[resFreeVarEnv] :: Result t -> VarNameEnv t

-- | The SymFns that were encountered during serialization and their
--   associated fresh name that was used to generate the s-expression.
[resSymFnEnv] :: Result t -> FnNameEnv t

-- | Generates the the S-expression tokens represented by the sexpr
--   argument, preceeded by a list of strings output as comments.
printSExpr :: Seq String -> SExpr -> Text
defaultConfig :: Config
type SExpr = WellFormedSExpr Atom
data Atom

-- | An identifier.
AId :: Text -> Atom

-- | A prefix followed by a string literal (.e.g, AStr "u" "Hello World" is
--   serialize as `#u"Hello World"`).
AStr :: Some StringInfoRepr -> Text -> Atom

-- | Integer (i.e., unbounded) literal.
AInt :: Integer -> Atom

-- | Natural (i.e., unbounded) literal
ANat :: Natural -> Atom

-- | Real (i.e., unbounded) literal.
AReal :: Rational -> Atom

-- | A floating point literal (with precision)
AFloat :: Some FloatPrecisionRepr -> BigFloat -> Atom

-- | Bitvector, width and then value.
ABV :: Int -> Integer -> Atom

-- | Boolean literal.
ABool :: Bool -> Atom
data SomeExprSymFn t
SomeExprSymFn :: ExprSymFn t dom ret -> SomeExprSymFn t

-- | A well-formed s-expression is one which does not contain any dotted
--   lists. This means that not every value of SExpr a can be
--   converted to a WellFormedSExpr a, although the opposite is
--   fine.
data () => WellFormedSExpr atom
WFSList :: [WellFormedSExpr atom] -> WellFormedSExpr atom
WFSAtom :: atom -> WellFormedSExpr atom

-- | Lift an unquoted identifier.
ident :: Text -> SExpr

-- | Lift an integer.
int :: Integer -> SExpr
string :: Some StringInfoRepr -> Text -> SExpr

-- | Lift a bitvector.
bitvec :: Natural -> Integer -> SExpr

-- | Lift a boolean.
bool :: Bool -> SExpr

-- | Lift a natural
nat :: Natural -> SExpr

-- | Lift a real
real :: Rational -> SExpr
ppFreeVarEnv :: VarNameEnv t -> String
ppFreeSymFnEnv :: FnNameEnv t -> String

-- | A shorter alias for WFSList
--   
--   
--   >>> L [A "pachy", A "derm"]
--   WFSList [WFSAtom "pachy",WFSAtom "derm"]
--   
pattern L :: [WellFormedSExpr t] -> WellFormedSExpr t

-- | A shorter alias for WFSAtom
--   
--   
--   >>> A "elephant"
--   WFSAtom "elephant"
--   
pattern A :: t -> WellFormedSExpr t
instance GHC.Show.Show What4.Serialize.Printer.SKey
instance GHC.Classes.Ord What4.Serialize.Printer.SKey
instance GHC.Classes.Eq What4.Serialize.Printer.SKey
instance GHC.Classes.Eq (What4.Serialize.Printer.SomeExprSymFn t)
instance GHC.Classes.Ord (What4.Serialize.Printer.SomeExprSymFn t)
instance GHC.Show.Show (What4.Serialize.Printer.SomeExprSymFn t)

-- | A parser for an s-expression representation of what4 expressions
module What4.Serialize.Parser

-- | (deserializeExpr sym) is equivalent to (deserializeExpr'
--   (defaultConfig sym)).
deserializeExpr :: forall sym t st fs. sym ~ ExprBuilder t st fs => sym -> SExpr -> IO (Either String (Some (SymExpr sym)))
deserializeExprWithConfig :: forall sym t st fs. sym ~ ExprBuilder t st fs => sym -> Config sym -> SExpr -> IO (Either String (Some (SymExpr sym)))

-- | (deserializeSymFn sym) is equivalent to
--   (deserializeSymFn' (defaultConfig sym)).
deserializeSymFn :: forall sym t st fs. sym ~ ExprBuilder t st fs => sym -> SExpr -> IO (Either String (SomeSymFn sym))
deserializeSymFnWithConfig :: forall sym t st fs. sym ~ ExprBuilder t st fs => sym -> Config sym -> SExpr -> IO (Either String (SomeSymFn sym))
deserializeBaseType :: SExpr -> Either String (Some BaseTypeRepr)
readBaseTypes :: forall m. MonadError String m => SExpr -> m (Some (Assignment BaseTypeRepr))
data Atom

-- | An identifier.
AId :: Text -> Atom

-- | A prefix followed by a string literal (.e.g, AStr "u" "Hello World" is
--   serialize as `#u"Hello World"`).
AStr :: Some StringInfoRepr -> Text -> Atom

-- | Integer (i.e., unbounded) literal.
AInt :: Integer -> Atom

-- | Natural (i.e., unbounded) literal
ANat :: Natural -> Atom

-- | Real (i.e., unbounded) literal.
AReal :: Rational -> Atom

-- | A floating point literal (with precision)
AFloat :: Some FloatPrecisionRepr -> BigFloat -> Atom

-- | Bitvector, width and then value.
ABV :: Int -> Integer -> Atom

-- | Boolean literal.
ABool :: Bool -> Atom

-- | A well-formed s-expression is one which does not contain any dotted
--   lists. This means that not every value of SExpr a can be
--   converted to a WellFormedSExpr a, although the opposite is
--   fine.
data () => WellFormedSExpr atom
WFSList :: [WellFormedSExpr atom] -> WellFormedSExpr atom
WFSAtom :: atom -> WellFormedSExpr atom
data Config sym
Config :: (Text -> IO (Maybe (SomeSymFn sym))) -> (Text -> IO (Maybe (Some (SymExpr sym)))) -> Config sym

-- | The mapping of names to defined What4 SymFns.
[cSymFnLookup] :: Config sym -> Text -> IO (Maybe (SomeSymFn sym))

-- | The mapping of names to defined What4 expressions.
[cExprLookup] :: Config sym -> Text -> IO (Maybe (Some (SymExpr sym)))
defaultConfig :: (IsSymExprBuilder sym, ShowF (SymExpr sym)) => sym -> Config sym
data SomeSymFn t
SomeSymFn :: SymFn t dom ret -> SomeSymFn t
type SExpr = WellFormedSExpr Atom
parseSExpr :: Text -> Either String SExpr

-- | Generates the the S-expression tokens represented by the sexpr
--   argument, preceeded by a list of strings output as comments.
printSExpr :: Seq String -> SExpr -> Text

-- | Normalization and equivalence checking for expressions
module What4.Serialize.Normalize

-- | Apply some normalizations to make function call arguments more
--   readable. Examples include:
--   
--   
--   
- Avoid wrapping single literals in a SemiRingLiteral and
--   just represent them as a bare integer literals
--   
- Attempt to reduce function calls with constant arguments where
--   possible
--   
normSymFn :: forall sym st fs t args ret. sym ~ ExprBuilder t st fs => sym -> ExprSymFn t args ret -> Assignment (Expr t) args -> IO (Expr t ret)
normExpr :: forall sym st fs t tp. sym ~ ExprBuilder t st fs => sym -> Expr t tp -> IO (Expr t tp)
testEquivSymFn :: forall sym st fs t args ret args' ret'. sym ~ ExprBuilder t st fs => sym -> SymFn sym args ret -> SymFn sym args' ret' -> IO ExprEquivResult
testEquivExpr :: forall sym st fs t tp tp'. sym ~ ExprBuilder t st fs => sym -> Expr t tp -> Expr t tp' -> IO ExprEquivResult
data ExprEquivResult
ExprEquivalent :: ExprEquivResult
ExprNormEquivalent :: ExprEquivResult
ExprUnequal :: ExprEquivResult

-- | This module defines an API for interacting with solvers that support
--   online interaction modes.
module What4.Protocol.Online

-- | This class provides an API for starting and shutting down connections
--   to various different solvers that support online interaction modes.
class SMTReadWriter solver => OnlineSolver solver

-- | Start a new solver process attached to the given ExprBuilder.
startSolverProcess :: forall scope st fs. OnlineSolver solver => ProblemFeatures -> Maybe Handle -> ExprBuilder scope st fs -> IO (SolverProcess scope solver)

-- | Shut down a solver process. The process will be asked to shut down in
--   a "polite" way, e.g., by sending an (exit) message, or by
--   closing the process's stdin. Use killProcess instead
--   to shutdown a process via a signal.
shutdownSolverProcess :: forall scope. OnlineSolver solver => SolverProcess scope solver -> IO (ExitCode, Text)

-- | Simple data-type encapsulating some implementation of an online
--   solver.
data AnOnlineSolver
AnOnlineSolver :: Proxy s -> AnOnlineSolver

-- | A live connection to a running solver process.
--   
--   This data structure should be used in a single-threaded manner or with
--   external synchronization to ensure that only a single thread has
--   access at a time. Unsynchronized multithreaded use will lead to race
--   conditions and very strange results.
data SolverProcess scope solver
SolverProcess :: !WriterConn scope solver -> IO ExitCode -> !ProcessHandle -> !ErrorBehavior -> !HandleReader -> !SMTEvalFunctions solver -> (SolverEvent -> IO ()) -> String -> IORef (Maybe Int) -> Bool -> SolverGoalTimeout -> SolverProcess scope solver

-- | Writer for sending commands to the solver
[solverConn] :: SolverProcess scope solver -> !WriterConn scope solver

-- | Callback for regular code paths to gracefully close associated pipes
--   and wait for the process to shutdown
[solverCleanupCallback] :: SolverProcess scope solver -> IO ExitCode

-- | Handle to the solver process
[solverHandle] :: SolverProcess scope solver -> !ProcessHandle

-- | Indicate this solver's behavior following an error response
[solverErrorBehavior] :: SolverProcess scope solver -> !ErrorBehavior

-- | Standard error for the solver process
[solverStderr] :: SolverProcess scope solver -> !HandleReader

-- | The functions used to parse values out of models.
[solverEvalFuns] :: SolverProcess scope solver -> !SMTEvalFunctions solver
[solverLogFn] :: SolverProcess scope solver -> SolverEvent -> IO ()
[solverName] :: SolverProcess scope solver -> String

-- | Some solvers will enter an UNSAT state early, if they can
--   easily determine that context is unsatisfiable. If this IORef contains
--   an integer value, it indicates how many "pop" operations need to be
--   performed to return to a potentially satisfiable state. A Just
--   0 state indicates the special case that the top-level context is
--   unsatisfiable, and must be "reset".
[solverEarlyUnsat] :: SolverProcess scope solver -> IORef (Maybe Int)

-- | Some solvers do not have support for the SMTLib2.6 operation
--   (reset-assertions), or an equivalent. For these solvers, we instead
--   make sure to always have at least one assertion frame pushed, and pop
--   all outstanding frames (and push a new top-level one) as a way to
--   mimic the reset behavior.
[solverSupportsResetAssertions] :: SolverProcess scope solver -> Bool

-- | The amount of time (in seconds) that a solver should spend trying to
--   satisfy any particular goal before giving up. A value of zero
--   indicates no time limit.
--   
--   Note that it is not sufficient to set just this value to control
--   timeouts; this value is used as a reference for common code (e.g.
--   SMTLIB2) to determine the timeout for the associated timer. When
--   initialized, this field of the SolverProcess is initialized from a
--   solver-specific timeout configuration (e.g. z3Timeout); the latter is
--   the definitive reference for the timeout, and solver-specific code
--   will likely use the the latter rather than this common field.
[solverGoalTimeout] :: SolverProcess scope solver -> SolverGoalTimeout

-- | Standard input stream for the solver process.
solverStdin :: SolverProcess t solver -> OutputStream Text

-- | The solver's stdout, for easier parsing of responses.
solverResponse :: SolverProcess t solver -> InputStream Text

-- | The amount of time that a solver is allowed to attempt to satisfy any
--   particular goal.
--   
--   The timeout value may be retrieved with
--   getGoalTimeoutInMilliSeconds or getGoalTimeoutInSeconds.
newtype SolverGoalTimeout
SolverGoalTimeout :: Integer -> SolverGoalTimeout
[getGoalTimeoutInMilliSeconds] :: SolverGoalTimeout -> Integer

-- | Get the SolverGoalTimeout raw numeric value in units of seconds.
getGoalTimeoutInSeconds :: SolverGoalTimeout -> Integer

-- | If the solver cannot voluntarily limit itself to the requested timeout
--   period, this runs a local async process with a slightly longer time
--   period that will forcibly terminate the solver process if it expires
--   while the solver process is still running.
--   
--   Note that this will require re-establishment of the solver process and
--   any associated context for any subsequent solver goal evaluation.
withLocalGoalTimeout :: SolverProcess t s -> (WriterConn t s -> IO (SatResult () ())) -> IO (Either SomeException (SatResult () ()))

-- | This datatype describes how a solver will behave following an error.
data ErrorBehavior

-- | This indicates the solver will immediately exit following an error
ImmediateExit :: ErrorBehavior

-- | This indicates the solver will remain live and respond to further
--   commmands following an error
ContinueOnError :: ErrorBehavior

-- | An impolite way to shut down a solver. Prefer to use
--   shutdownSolverProcess, unless the solver is unresponsive or in
--   some unrecoverable error state.
killSolver :: SolverProcess t solver -> IO ()

-- | Push a new solver assumption frame.
push :: SMTReadWriter solver => SolverProcess scope solver -> IO ()

-- | Pop a previous solver assumption frame.
pop :: SMTReadWriter solver => SolverProcess scope solver -> IO ()

-- | Pop a previous solver assumption frame, but allow this to fail if the
--   solver has exited.
tryPop :: SMTReadWriter solver => SolverProcess scope solver -> IO ()

-- | Pop all assumption frames and remove all top-level asserts from the
--   global scope. Forget all declarations except those in scope at the top
--   level.
reset :: SMTReadWriter solver => SolverProcess scope solver -> IO ()

-- | Perform an action in the scope of a solver assumption frame.
inNewFrame :: (MonadIO m, MonadMask m, SMTReadWriter solver) => SolverProcess scope solver -> m a -> m a

-- | Perform an action in the scope of a solver assumption frame, where the
--   given bound variables are considered free within that frame.
inNewFrameWithVars :: (MonadIO m, MonadMask m, SMTReadWriter solver) => SolverProcess scope solver -> [Some (ExprBoundVar scope)] -> m a -> m a

-- | Open a second solver assumption frame. For abduction, we want the
--   final assertion to be a in a new frame, so that it can be closed
--   before asking for abducts. The following two commands allow frame 2 to
--   be pushed and popped independently of other commands
inNewFrame2Open :: SMTReadWriter solver => SolverProcess scope solver -> IO ()

-- | Close a second solver assumption frame.
inNewFrame2Close :: SMTReadWriter solver => SolverProcess scope solver -> IO ()

-- | Send a check command to the solver, and get the SatResult without
--   asking a model.
check :: SMTReadWriter solver => SolverProcess scope solver -> String -> IO (SatResult () ())

-- | Send a check command to the solver and get the model in the case of a
--   SAT result.
checkAndGetModel :: SMTReadWriter solver => SolverProcess scope solver -> String -> IO (SatResult (GroundEvalFn scope) ())
checkWithAssumptions :: SMTReadWriter solver => SolverProcess scope solver -> String -> [BoolExpr scope] -> IO ([Text], SatResult () ())
checkWithAssumptionsAndModel :: SMTReadWriter solver => SolverProcess scope solver -> String -> [BoolExpr scope] -> IO (SatResult (GroundEvalFn scope) ())

-- | Following a successful check-sat command, build a ground evaluation
--   function that will evaluate terms in the context of the current model.
getModel :: SMTReadWriter solver => SolverProcess scope solver -> IO (GroundEvalFn scope)

-- | After an unsatisfiable check-sat command, compute a set of the named
--   assertions that (together with all the unnamed assertions) form an
--   unsatisfiable core. Note: the returned unsatisfiable core might not be
--   minimal.
getUnsatCore :: SMTReadWriter solver => SolverProcess scope solver -> IO [Text]

-- | get-abuct nm t queries the solver for the first abduct, which
--   is returned as an SMT function definition named nm. The
--   remaining abducts are obtained from the solver by successive
--   invocations of the get-abduct-next command, which return SMT
--   functions bound to the same nm as the first. The name
--   nm is bound within the current assertion frame. Note that
--   this is an unstable API; we expect that the return type will change to
--   a parsed expression in the future
getAbducts :: SMTReadWriter solver => SolverProcess scope solver -> Int -> Text -> BoolExpr scope -> IO [String]

-- | After an unsatisfiable check-with-assumptions command, compute a set
--   of the supplied assumptions that (together with previous assertions)
--   form an unsatisfiable core. Note: the returned unsatisfiable set might
--   not be minimal. The boolean value returned along with the name
--   indicates if the assumption was negated or not: True
--   indidcates a positive atom, and False represents a negated
--   atom.
getUnsatAssumptions :: SMTReadWriter solver => SolverProcess scope solver -> IO [(Bool, Text)]

-- | Get the sat result from a previous SAT command.
getSatResult :: SMTReadWriter s => SolverProcess t s -> IO (SatResult () ())

-- | Check if the given formula is satisfiable in the current solver state,
--   without requesting a model. This is done in a fresh frame, which is
--   exited after the check call.
checkSatisfiable :: SMTReadWriter solver => SolverProcess scope solver -> String -> BoolExpr scope -> IO (SatResult () ())

-- | Check if the formula is satisifiable in the current solver state. This
--   is done in a fresh frame, which is exited after the continuation
--   complets. The evaluation function can be used to query the model. The
--   model is valid only in the given continuation.
checkSatisfiableWithModel :: SMTReadWriter solver => SolverProcess scope solver -> String -> BoolExpr scope -> (SatResult (GroundEvalFn scope) () -> IO a) -> IO a
instance GHC.Show.Show What4.Protocol.Online.RunawaySolverTimeout
instance GHC.Exception.Type.Exception What4.Protocol.Online.RunawaySolverTimeout
instance Prettyprinter.Internal.Pretty What4.Protocol.Online.SolverGoalTimeout
instance GHC.Show.Show What4.Protocol.Online.SolverGoalTimeout

-- | A utility for using an OnlineSolver to query if a SymBV
--   is concrete or symbolic, and if it is symbolic, what the lower and
--   upper bounds are.
module What4.Utils.ResolveBounds.BV

-- | Use an OnlineSolver to attempt to resolve a SymBV as
--   concrete. If it cannot, return the lower and upper bounds. This is
--   primarly intended for compound expressions whose bounds cannot
--   trivially be determined by using signedBVBounds or
--   unsignedBVBounds.
resolveSymBV :: forall w sym solver scope st fs. (1 <= w, sym ~ ExprBuilder scope st fs, OnlineSolver solver) => sym -> SearchStrategy -> NatRepr w -> SolverProcess scope solver -> SymBV sym w -> IO (ResolvedSymBV w)

-- | The strategy to use to search for lower and upper bounds in
--   resolveSymBV.
data SearchStrategy

-- | After making an initial guess for a bound, increase (for upper bounds)
--   or decrease (for lower bounds) the initial guess by an exponentially
--   increasing amount (1, 2, 4, 8, ...) until the bound has been exceeded.
--   At that point, back off from exponential search and use binary search
--   until the bound has been determined.
--   
--   For many use cases, this is a reasonable default.
ExponentialSearch :: SearchStrategy

-- | Use binary search to found each bound, using 0 as the
--   leftmost bounds of the search and maxUnsigned as the rightmost
--   bounds of the search.
BinarySearch :: SearchStrategy

-- | The results of an OnlineSolver trying to resolve a SymBV
--   as concrete.
data ResolvedSymBV w

-- | A concrete bitvector, including its value as a BV.
BVConcrete :: BV w -> ResolvedSymBV w

-- | A symbolic SymBV, including its lower and upper bounds as a
--   Domain.
BVSymbolic :: Domain w -> ResolvedSymBV w
instance Prettyprinter.Internal.Pretty What4.Utils.ResolveBounds.BV.SearchStrategy
instance GHC.Show.Show (What4.Utils.ResolveBounds.BV.ResolvedSymBV w)

-- | This module defines operations for producing SMTLib2-compatible
--   queries useful for interfacing with solvers that accecpt SMTLib2 as an
--   input language.
module What4.Protocol.SMTLib2
data Writer a

-- | This class exists so that solvers supporting the SMTLib2 format can
--   support features that go slightly beyond the standard.
--   
--   In particular, there is no standardized syntax for constant arrays
--   (arrays which map every index to the same value). Solvers that support
--   the theory of arrays and have custom syntax for constant arrays should
--   implement smtlib2arrayConstant. In addition, solvers may
--   override the default representation of complex numbers if necessary.
--   The default is to represent complex numbers as "(Array Bool Real)" and
--   to build instances by updating a constant array.
class Show a => SMTLib2Tweaks a
smtlib2tweaks :: SMTLib2Tweaks a => a
smtlib2exitCommand :: SMTLib2Tweaks a => Maybe Command

-- | Return a representation of the type associated with a
--   (multi-dimensional) symbolic array.
--   
--   By default, we encode symbolic arrays using a nested representation.
--   If the solver, supports tuples/structs it may wish to change this.
smtlib2arrayType :: SMTLib2Tweaks a => [Sort] -> Sort -> Sort
smtlib2arrayConstant :: SMTLib2Tweaks a => Maybe ([Sort] -> Sort -> Term -> Term)
smtlib2arraySelect :: SMTLib2Tweaks a => Term -> [Term] -> Term
smtlib2arrayUpdate :: SMTLib2Tweaks a => Term -> [Term] -> Term -> Term
smtlib2StringSort :: SMTLib2Tweaks a => Sort
smtlib2StringTerm :: SMTLib2Tweaks a => Text -> Term
smtlib2StringLength :: SMTLib2Tweaks a => Term -> Term
smtlib2StringAppend :: SMTLib2Tweaks a => [Term] -> Term
smtlib2StringContains :: SMTLib2Tweaks a => Term -> Term -> Term
smtlib2StringIndexOf :: SMTLib2Tweaks a => Term -> Term -> Term -> Term
smtlib2StringIsPrefixOf :: SMTLib2Tweaks a => Term -> Term -> Term
smtlib2StringIsSuffixOf :: SMTLib2Tweaks a => Term -> Term -> Term
smtlib2StringSubstring :: SMTLib2Tweaks a => Term -> Term -> Term -> Term

-- | The sort of structs with the given field types.
--   
--   By default, this uses SMTLIB2 datatypes and are not primitive to the
--   language.
smtlib2StructSort :: SMTLib2Tweaks a => [Sort] -> Sort

-- | Construct a struct value from the given field values
smtlib2StructCtor :: SMTLib2Tweaks a => [Term] -> Term

-- | Construct a struct field projection term
smtlib2StructProj :: SMTLib2Tweaks a => Int -> Int -> Term -> Term
smtlib2declareStructCmd :: SMTLib2Tweaks a => Int -> Maybe Command
newWriter :: a -> OutputStream Text -> InputStream Text -> AcknowledgementAction t (Writer a) -> ResponseStrictness -> String -> Bool -> ProblemFeatures -> Bool -> SymbolVarBimap t -> IO (WriterConn t (Writer a))

-- | Write check sat command
writeCheckSat :: SMTLib2Tweaks a => WriterConn t (Writer a) -> IO ()
writeExit :: forall a t. SMTLib2Tweaks a => WriterConn t (Writer a) -> IO ()
writeGetValue :: SMTLib2Tweaks a => WriterConn t (Writer a) -> [Term] -> IO ()
writeGetAbduct :: SMTLib2Tweaks a => WriterConn t (Writer a) -> Text -> Term -> IO ()
writeGetAbductNext :: SMTLib2Tweaks a => WriterConn t (Writer a) -> IO ()

-- | Write check-synth command
writeCheckSynth :: SMTLib2Tweaks a => WriterConn t (Writer a) -> IO ()

-- | This function runs a check sat command
runCheckSat :: forall b t a. SMTLib2Tweaks b => Session t b -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a

-- | runGetAbducts s nm p n, returns n formulas (as strings) the
--   disjunction of which entails p (along with all the assertions in the
--   context)
runGetAbducts :: SMTLib2Tweaks a => Session t a -> Int -> Text -> Term -> IO [String]
asSMT2Type :: forall a tp. SMTLib2Tweaks a => TypeMap tp -> Sort
setOption :: SMTLib2Tweaks a => WriterConn t (Writer a) -> Text -> Text -> IO ()
getVersion :: SMTLib2Tweaks a => WriterConn t (Writer a) -> IO ()

-- | Get the result of a version query
versionResult :: WriterConn t a -> IO Text
getName :: SMTLib2Tweaks a => WriterConn t (Writer a) -> IO ()

-- | Get the result of a version query
nameResult :: WriterConn t a -> IO Text

-- | Set the produce models option (We typically want this)
setProduceModels :: SMTLib2Tweaks a => WriterConn t (Writer a) -> Bool -> IO ()
smtLibEvalFuns :: forall t a. SMTLib2Tweaks a => Session t a -> SMTEvalFunctions (Writer a)
smtlib2Options :: [ConfigDesc]
parseFnModel :: sym ~ ExprBuilder t st fs => sym -> WriterConn t h -> [SomeSymFn sym] -> SExp -> IO (MapF (SymFnWrapper sym) (SymFnWrapper sym))
parseFnValues :: sym ~ ExprBuilder t st fs => sym -> WriterConn t h -> [SomeSymFn sym] -> SExp -> IO (MapF (SymFnWrapper sym) (SymFnWrapper sym))

-- | Identifies the set of predefined sorts and operators available.
newtype Logic
Logic :: Builder -> Logic

-- | Use the QF_BV logic
qf_bv :: Logic

-- | Set the logic to all supported logics.

-- | Deprecated: Use allLogic instead
allSupported :: Logic

-- | Use the Horn logic
hornLogic :: Logic

-- | Set the logic to all supported logics.

-- | Deprecated: Use allLogic instead
all_supported :: Logic
setLogic :: SMTLib2Tweaks a => WriterConn t (Writer a) -> Logic -> IO ()

-- | Sort for SMTLIB expressions
newtype Sort
Sort :: Builder -> Sort
[unSort] :: Sort -> Builder

-- | arraySort a b denotes the set of functions from a to
--   be b.
arraySort :: Sort -> Sort -> Sort

-- | Denotes an expression in the SMT solver
newtype Term
T :: Builder -> Term
[renderTerm] :: Term -> Builder
arrayConst :: Sort -> Sort -> Term -> Term
arraySelect :: Term -> Term -> Term
arrayStore :: Term -> Term -> Term -> Term

-- | This is an interactive session with an SMT solver
data Session t a
Session :: !WriterConn t (Writer a) -> !InputStream Text -> Session t a
[sessionWriter] :: Session t a -> !WriterConn t (Writer a)
[sessionResponse] :: Session t a -> !InputStream Text
class (SMTLib2Tweaks a, Show a) => SMTLib2GenericSolver a
defaultSolverPath :: SMTLib2GenericSolver a => a -> ExprBuilder t st fs -> IO FilePath
defaultSolverArgs :: SMTLib2GenericSolver a => a -> ExprBuilder t st fs -> IO [String]
defaultFeatures :: SMTLib2GenericSolver a => a -> ProblemFeatures
getErrorBehavior :: SMTLib2GenericSolver a => a -> WriterConn t (Writer a) -> IO ErrorBehavior
supportsResetAssertions :: SMTLib2GenericSolver a => a -> Bool
setDefaultLogicAndOptions :: SMTLib2GenericSolver a => WriterConn t (Writer a) -> IO ()
newDefaultWriter :: SMTLib2GenericSolver a => a -> AcknowledgementAction t (Writer a) -> ProblemFeatures -> Maybe (ConfigOption BaseBoolType) -> ExprBuilder t st fs -> OutputStream Text -> InputStream Text -> IO (WriterConn t (Writer a))

-- | Run the solver in a session.
withSolver :: SMTLib2GenericSolver a => a -> AcknowledgementAction t (Writer a) -> ProblemFeatures -> Maybe (ConfigOption BaseBoolType) -> ExprBuilder t st fs -> FilePath -> LogData -> (Session t a -> IO b) -> IO b
runSolverInOverride :: SMTLib2GenericSolver a => a -> AcknowledgementAction t (Writer a) -> ProblemFeatures -> Maybe (ConfigOption BaseBoolType) -> ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO b) -> IO b

-- | A default method for writing SMTLib2 problems without any
--   solver-specific tweaks.
writeDefaultSMT2 :: SMTLib2Tweaks a => a -> String -> ProblemFeatures -> Maybe (ConfigOption BaseBoolType) -> ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()
defaultFileWriter :: SMTLib2Tweaks a => a -> String -> ProblemFeatures -> Maybe (ConfigOption BaseBoolType) -> ExprBuilder t st fs -> Handle -> IO (WriterConn t (Writer a))
startSolver :: SMTLib2GenericSolver a => a -> AcknowledgementAction t (Writer a) -> (WriterConn t (Writer a) -> IO ()) -> SolverGoalTimeout -> ProblemFeatures -> Maybe (ConfigOption BaseBoolType) -> Maybe Handle -> ExprBuilder t st fs -> IO (SolverProcess t (Writer a))
shutdownSolver :: SMTLib2GenericSolver a => a -> SolverProcess t (Writer a) -> IO (ExitCode, Text)
smtAckResult :: AcknowledgementAction t (Writer a)
data SMTLib2Exception
SMTLib2Unsupported :: Command -> SMTLib2Exception
SMTLib2Error :: Command -> Text -> SMTLib2Exception
SMTLib2ParseError :: SMTLib2Intent -> [Command] -> Text -> SMTLib2Exception
SMTLib2ResponseUnrecognized :: Command -> Text -> SMTLib2Exception
SMTLib2InvalidResponse :: Command -> SMTLib2Intent -> SMTResponse -> SMTLib2Exception
ppSolverVersionCheckError :: SolverVersionCheckError -> Doc ann
ppSolverVersionError :: SolverVersionError -> Doc ann

-- | Ensure the solver's version falls within a known-good range.
checkSolverVersion :: SMTLib2Tweaks solver => SolverProcess scope (Writer solver) -> IO (Either SolverVersionCheckError (Maybe SolverVersionError))

-- | Ensure the solver's version falls within a known-good range.
checkSolverVersion' :: SMTLib2Tweaks solver => Map Text SolverBounds -> SolverProcess scope (Writer solver) -> IO (Either SolverVersionCheckError (Maybe SolverVersionError))

-- | Query the solver's error behavior setting
queryErrorBehavior :: SMTLib2Tweaks a => WriterConn t (Writer a) -> IO ErrorBehavior

-- | Solver version bounds computed from "solverBounds.config"
defaultSolverBounds :: Map Text SolverBounds
data WriterConn t (h :: Type)

-- | Write assume formula predicates for asserting predicate holds.
assume :: SMTWriter h => WriterConn t h -> BoolExpr t -> IO ()

-- | Indicates features supported by the solver.
supportedFeatures :: WriterConn t h -> ProblemFeatures

-- | An acknowledgement action that does nothing
nullAcknowledgementAction :: AcknowledgementAction t h
instance GHC.Classes.Ord What4.Protocol.SMTLib2.SMTFloatPrecision
instance GHC.Classes.Eq What4.Protocol.SMTLib2.SMTFloatPrecision
instance Control.Monad.Reader.Class.MonadReader (What4.Protocol.SMTLib2.ProcessorEnv sym) (What4.Protocol.SMTLib2.Processor sym)
instance Control.Monad.Error.Class.MonadError GHC.Base.String (What4.Protocol.SMTLib2.Processor sym)
instance Control.Monad.IO.Class.MonadIO (What4.Protocol.SMTLib2.Processor sym)
instance GHC.Base.Monad (What4.Protocol.SMTLib2.Processor sym)
instance GHC.Base.Applicative (What4.Protocol.SMTLib2.Processor sym)
instance GHC.Base.Functor (What4.Protocol.SMTLib2.Processor sym)
instance What4.Protocol.SMTLib2.SMTLib2Tweaks a => What4.Protocol.SMTWriter.SMTReadWriter (What4.Protocol.SMTLib2.Writer a)
instance What4.Protocol.SMTLib2.SMTLib2Tweaks a => What4.Protocol.SMTWriter.SMTWriter (What4.Protocol.SMTLib2.Writer a)
instance What4.Protocol.SMTLib2.SMTLib2Tweaks ()
instance GHC.Num.Num What4.Protocol.SMTLib2.Syntax.Term
instance What4.Protocol.SMTWriter.SupportTermOps What4.Protocol.SMTLib2.Syntax.Term

-- | Z3-specific tweaks to the basic SMTLib2 solver interface.
module What4.Solver.Z3
data Z3
Z3 :: Z3
z3Adapter :: SolverAdapter st

-- | Path to Z3
z3Path :: ConfigOption (BaseStringType Unicode)

-- | Per-check timeout, in milliseconds (zero is none)
z3Timeout :: ConfigOption BaseIntegerType
z3Options :: [ConfigDesc]

-- | Z3 tactic
z3Tactic :: ConfigOption (BaseStringType Unicode)
z3TacticDefault :: Text
z3Features :: ProblemFeatures
runZ3InOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a

-- | Run Z3 in a session. Z3 will be configured to produce models, but
--   otherwise left with the default configuration.
withZ3 :: ExprBuilder t st fs -> FilePath -> LogData -> (Session t Z3 -> IO a) -> IO a
writeZ3SMT2File :: ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()

-- | Check the satisfiability of a set of constrained Horn clauses (CHCs).
--   
--   CHCs are represented as pure SMT-LIB2 implications. For more
--   information, see the Z3 guide.
runZ3Horn :: sym ~ ExprBuilder t st fs => sym -> LogData -> [SomeSymFn sym] -> [BoolExpr t] -> IO (SatResult (MapF (SymFnWrapper sym) (SymFnWrapper sym)) ())
writeZ3HornSMT2File :: sym ~ ExprBuilder t st fs => sym -> Handle -> [SomeSymFn sym] -> [BoolExpr t] -> IO ()
instance GHC.Show.Show What4.Solver.Z3.Z3
instance What4.Protocol.SMTLib2.SMTLib2Tweaks What4.Solver.Z3.Z3
instance What4.Protocol.SMTLib2.SMTLib2GenericSolver What4.Solver.Z3.Z3
instance What4.Protocol.Online.OnlineSolver (What4.Protocol.SMTLib2.Writer What4.Solver.Z3.Z3)

-- | SMTWriter interface for Yices, using the Yices-specific input
--   language. This language shares many features with SMTLib2, but is not
--   quite compatible.
module What4.Solver.Yices

-- | This is a tag used to indicate that a WriterConn is a
--   connection to a specific Yices process.
data Connection
newConnection :: OutputStream Text -> InputStream Text -> (IORef (Maybe Int) -> AcknowledgementAction t Connection) -> ProblemFeatures -> SolverGoalTimeout -> SymbolVarBimap t -> IO (WriterConn t Connection)

-- | Write assume formula predicates for asserting predicate holds.
assume :: SMTWriter h => WriterConn t h -> BoolExpr t -> IO ()

-- | Send a check command to Yices.
sendCheck :: WriterConn t Connection -> IO ()
sendCheckExistsForall :: WriterConn t Connection -> IO ()
eval :: WriterConn t Connection -> Term Connection -> IO ()

-- | Push a new solver assumption frame.
push :: SMTReadWriter solver => SolverProcess scope solver -> IO ()

-- | Pop a previous solver assumption frame.
pop :: SMTReadWriter solver => SolverProcess scope solver -> IO ()

-- | Perform an action in the scope of a solver assumption frame.
inNewFrame :: (MonadIO m, MonadMask m, SMTReadWriter solver) => SolverProcess scope solver -> m a -> m a
setParam :: WriterConn t Connection -> ConfigValue -> IO ()
setYicesParams :: WriterConn t Connection -> Config -> IO ()

-- | Wrapper to help with reading from another process's standard out and
--   stderr.
--   
--   We want to be able to read from another process's stderr and stdout
--   without causing the process to stall because stdout or
--   stderr becomes full. This data type will read from either of
--   the handles, and buffer as much data as needed in the queue. It then
--   provides a line-based method for reading that data as strict
--   bytestrings.
data HandleReader

-- | Create a new handle reader for reading the given handle.
startHandleReader :: Handle -> Maybe (OutputStream Text) -> IO HandleReader
yicesType :: TypeMap tp -> YicesType
assertForall :: WriterConn t Connection -> [(Text, YicesType)] -> Expr -> IO ()
efSolveCommand :: Command Connection

-- | Exceptions that can occur when reading responses from Yices
data YicesException
YicesUnsupported :: YicesCommand -> YicesException
YicesError :: YicesCommand -> Text -> YicesException
YicesParseError :: YicesCommand -> Text -> YicesException

-- | Call eval to get a Boolean term.
yicesEvalBool :: Eval s Bool

-- | Write a command to the connection along with position information if
--   it differs from the last position.
addCommand :: SMTWriter h => WriterConn t h -> Command h -> IO ()
yicesAdapter :: SolverAdapter t

-- | Run writer and get a yices result.
runYicesInOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t) () -> IO a) -> IO a

-- | Write a yices file that checks the satisfiability of the given
--   predicate.
writeYicesFile :: ExprBuilder t st fs -> FilePath -> BoolExpr t -> IO ()

-- | Path to yices
yicesPath :: ConfigOption (BaseStringType Unicode)
yicesOptions :: [ConfigDesc]
yicesDefaultFeatures :: ProblemFeatures

-- | Enable the MC-SAT solver
yicesEnableMCSat :: ConfigOption BaseBoolType

-- | Enable interactive mode (necessary for per-goal timeouts)
yicesEnableInteractive :: ConfigOption BaseBoolType

-- | Set a per-goal timeout in seconds.
yicesGoalTimeout :: ConfigOption BaseIntegerType
instance GHC.Show.Show What4.Solver.Yices.UnparseableYicesResponse
instance GHC.Exception.Type.Exception What4.Solver.Yices.UnparseableYicesResponse
instance What4.Protocol.SMTWriter.SMTReadWriter What4.Solver.Yices.Connection
instance GHC.Show.Show What4.Solver.Yices.YicesException
instance GHC.Exception.Type.Exception What4.Solver.Yices.YicesException
instance What4.Protocol.SMTWriter.SMTWriter What4.Solver.Yices.Connection
instance GHC.Num.Num What4.Solver.Yices.YicesTerm
instance What4.Protocol.SMTWriter.SupportTermOps What4.Solver.Yices.YicesTerm
instance What4.Protocol.Online.OnlineSolver What4.Solver.Yices.Connection

-- | STP-specific tweaks to the basic SMTLib2 solver interface.
module What4.Solver.STP
data STP
STP :: STP
stpAdapter :: SolverAdapter st

-- | Path to stp
stpPath :: ConfigOption (BaseStringType Unicode)

-- | Per-check timeout, in milliseconds (zero is none)
stpTimeout :: ConfigOption BaseIntegerType
stpOptions :: [ConfigDesc]
stpFeatures :: ProblemFeatures
runSTPInOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a

-- | Run STP in a session. STP will be configured to produce models, buth
--   otherwise left with the default configuration.
withSTP :: ExprBuilder t st fs -> FilePath -> LogData -> (Session t STP -> IO a) -> IO a
instance GHC.Show.Show What4.Solver.STP.STP
instance What4.Protocol.SMTLib2.SMTLib2Tweaks What4.Solver.STP.STP
instance What4.Protocol.SMTLib2.SMTLib2GenericSolver What4.Solver.STP.STP
instance What4.Protocol.Online.OnlineSolver (What4.Protocol.SMTLib2.Writer What4.Solver.STP.STP)

-- | ABC-specific tweaks to the basic SMT-LIB2 solver interface.
module What4.Solver.ExternalABC
data ExternalABC
ExternalABC :: ExternalABC
externalABCAdapter :: SolverAdapter st

-- | Path to ABC
abcPath :: ConfigOption (BaseStringType Unicode)
abcOptions :: [ConfigDesc]
runExternalABCInOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a
writeABCSMT2File :: ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()
instance GHC.Show.Show What4.Solver.ExternalABC.ExternalABC
instance What4.Protocol.SMTLib2.SMTLib2Tweaks What4.Solver.ExternalABC.ExternalABC
instance What4.Protocol.SMTLib2.SMTLib2GenericSolver What4.Solver.ExternalABC.ExternalABC

-- | This module provides an interface for running dReal and parsing the
--   results back.
module What4.Solver.DReal
data DReal
DReal :: DReal
type DRealBindings = Map Text (Either Bool (Maybe Rational, Maybe Rational))

-- | Function that calculates upper and lower bounds for real-valued
--   elements. This type is used for solvers (e.g., dReal) that give only
--   approximate solutions.
type ExprRangeBindings t = RealExpr t -> IO (Maybe Rational, Maybe Rational)
getAvgBindings :: WriterConn t (Writer DReal) -> DRealBindings -> IO (GroundEvalFn t)
getBoundBindings :: WriterConn t (Writer DReal) -> DRealBindings -> IO (ExprRangeBindings t)

-- | Path to dReal
drealPath :: ConfigOption (BaseStringType Unicode)
drealOptions :: [ConfigDesc]
drealAdapter :: SolverAdapter st
writeDRealSMT2File :: ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()
runDRealInOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (WriterConn t (Writer DReal), DRealBindings) () -> IO a) -> IO a
instance GHC.Show.Show What4.Solver.DReal.DReal
instance What4.Protocol.SMTLib2.SMTLib2Tweaks What4.Solver.DReal.DReal

-- | CVC5-specific tweaks to the basic SMTLib2 solver interface.
module What4.Solver.CVC5
data CVC5
CVC5 :: CVC5
cvc5Features :: ProblemFeatures
cvc5Adapter :: SolverAdapter st

-- | Path to cvc5
cvc5Path :: ConfigOption (BaseStringType Unicode)

-- | Per-check timeout, in milliseconds (zero is none)
cvc5Timeout :: ConfigOption BaseIntegerType
cvc5Options :: [ConfigDesc]
runCVC5InOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a

-- | Run cvc5 in a session. cvc5 will be configured to produce models, but
--   otherwise left with the default configuration.
withCVC5 :: ExprBuilder t st fs -> FilePath -> LogData -> (Session t CVC5 -> IO a) -> IO a
writeCVC5SMT2File :: ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()
writeMultiAsmpCVC5SMT2File :: ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()

-- | Find a solution to a Syntax-Guided Synthesis (SyGuS) problem.
--   
--   For more information, see the SyGuS standard.
runCVC5SyGuS :: sym ~ ExprBuilder t st fs => sym -> LogData -> [SomeSymFn sym] -> [BoolExpr t] -> IO (SatResult (MapF (SymFnWrapper sym) (SymFnWrapper sym)) ())

-- | Run CVC5 SyGuS in a session, with the default configuration.
withCVC5_SyGuS :: ExprBuilder t st fs -> FilePath -> LogData -> (Session t CVC5_SyGuS -> IO a) -> IO a
writeCVC5SyFile :: sym ~ ExprBuilder t st fs => sym -> Handle -> [SomeSymFn sym] -> [BoolExpr t] -> IO ()
instance GHC.Show.Show What4.Solver.CVC5.CVC5
instance GHC.Show.Show What4.Solver.CVC5.CVC5_SyGuS
instance What4.Protocol.SMTLib2.SMTLib2Tweaks What4.Solver.CVC5.CVC5_SyGuS
instance What4.Protocol.SMTLib2.SMTLib2GenericSolver What4.Solver.CVC5.CVC5_SyGuS
instance What4.Protocol.SMTLib2.SMTLib2Tweaks What4.Solver.CVC5.CVC5
instance What4.Protocol.SMTLib2.SMTLib2GenericSolver What4.Solver.CVC5.CVC5
instance What4.Protocol.Online.OnlineSolver (What4.Protocol.SMTLib2.Writer What4.Solver.CVC5.CVC5)

-- | CVC4-specific tweaks to the basic SMTLib2 solver interface.
module What4.Solver.CVC4
data CVC4
CVC4 :: CVC4
cvc4Features :: ProblemFeatures
cvc4Adapter :: SolverAdapter st

-- | Path to cvc4
cvc4Path :: ConfigOption (BaseStringType Unicode)

-- | Per-check timeout, in milliseconds (zero is none)
cvc4Timeout :: ConfigOption BaseIntegerType
cvc4Options :: [ConfigDesc]
runCVC4InOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a

-- | Run CVC4 in a session. CVC4 will be configured to produce models, but
--   otherwise left with the default configuration.
withCVC4 :: ExprBuilder t st fs -> FilePath -> LogData -> (Session t CVC4 -> IO a) -> IO a
writeCVC4SMT2File :: ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()
writeMultiAsmpCVC4SMT2File :: ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()
instance GHC.Show.Show What4.Solver.CVC4.CVC4
instance What4.Protocol.SMTLib2.SMTLib2Tweaks What4.Solver.CVC4.CVC4
instance What4.Protocol.SMTLib2.SMTLib2GenericSolver What4.Solver.CVC4.CVC4
instance What4.Protocol.Online.OnlineSolver (What4.Protocol.SMTLib2.Writer What4.Solver.CVC4.CVC4)

-- | This module provides an interface for running Boolector and parsing
--   the results back.
module What4.Solver.Boolector
data Boolector
Boolector :: Boolector

-- | Path to boolector
boolectorPath :: ConfigOption (BaseStringType Unicode)

-- | Per-check timeout, in milliseconds (zero is none)
boolectorTimeout :: ConfigOption BaseIntegerType
boolectorOptions :: [ConfigDesc]
boolectorAdapter :: SolverAdapter st
runBoolectorInOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a

-- | Run Boolector in a session. Boolector will be configured to produce
--   models, but otherwise left with the default configuration.
withBoolector :: ExprBuilder t st fs -> FilePath -> LogData -> (Session t Boolector -> IO a) -> IO a
boolectorFeatures :: ProblemFeatures
instance GHC.Show.Show What4.Solver.Boolector.Boolector
instance What4.Protocol.SMTLib2.SMTLib2Tweaks What4.Solver.Boolector.Boolector
instance What4.Protocol.SMTLib2.SMTLib2GenericSolver What4.Solver.Boolector.Boolector
instance What4.Protocol.Online.OnlineSolver (What4.Protocol.SMTLib2.Writer What4.Solver.Boolector.Boolector)

-- | The module reexports the most commonly used types and operations for
--   interacting with solvers.
module What4.Solver

-- | The main interface for interacting with a solver in an "offline"
--   fashion, which means that a new solver process is started for each
--   query.
data SolverAdapter st
SolverAdapter :: !String -> ![ConfigDesc] -> !forall t fs a. ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a -> !forall t fs. ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO () -> SolverAdapter st
[solver_adapter_name] :: SolverAdapter st -> !String

-- | Configuration options relevant to this solver adapter
[solver_adapter_config_options] :: SolverAdapter st -> ![ConfigDesc]

-- | Operation to check the satisfiability of a formula. The final argument
--   is a callback that calculates the ultimate result from a SatResult and
--   operations for finding model values in the event of a SAT result.
--   Note: the evaluation functions may cease to be avaliable after the
--   callback completes, so any necessary information should be extracted
--   from them before returning.
[solver_adapter_check_sat] :: SolverAdapter st -> !forall t fs a. ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a

-- | Write an SMTLib2 problem instance onto the given handle, incorporating
--   any solver-specific tweaks appropriate to this solver
[solver_adapter_write_smt2] :: SolverAdapter st -> !forall t fs. ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()

-- | Function that calculates upper and lower bounds for real-valued
--   elements. This type is used for solvers (e.g., dReal) that give only
--   approximate solutions.
type ExprRangeBindings t = RealExpr t -> IO (Maybe Rational, Maybe Rational)
defaultSolverAdapter :: ConfigOption (BaseStringType Unicode)
solverAdapterOptions :: [SolverAdapter st] -> IO ([ConfigDesc], IO (SolverAdapter st))

-- | A collection of operations for producing output from solvers. Solvers
--   can produce messages at varying verbosity levels that might be
--   appropriate for user output by using the logCallbackVerbose
--   operation. If a logHandle is provided, the entire interaction
--   sequence with the solver will be mirrored into that handle.
data LogData
LogData :: (Int -> String -> IO ()) -> Int -> String -> Maybe Handle -> LogData

-- | takes a verbosity and a message to log
[logCallbackVerbose] :: LogData -> Int -> String -> IO ()

-- | the default verbosity; typical default is 2
[logVerbosity] :: LogData -> Int

-- | the reason for performing the operation
[logReason] :: LogData -> String

-- | handle on which to mirror solver input/responses
[logHandle] :: LogData -> Maybe Handle
logCallback :: LogData -> String -> IO ()
defaultLogData :: LogData

-- | Test the ability to interact with a solver by peforming a check-sat
--   query on a trivially unsatisfiable problem.
smokeTest :: ExprBuilder t st fs -> SolverAdapter st -> IO (Maybe SomeException)
data ExternalABC
ExternalABC :: ExternalABC
externalABCAdapter :: SolverAdapter st

-- | Path to ABC
abcPath :: ConfigOption (BaseStringType Unicode)
abcOptions :: [ConfigDesc]
runExternalABCInOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a
writeABCSMT2File :: ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()
data Boolector
Boolector :: Boolector
boolectorAdapter :: SolverAdapter st

-- | Path to boolector
boolectorPath :: ConfigOption (BaseStringType Unicode)

-- | Per-check timeout, in milliseconds (zero is none)
boolectorTimeout :: ConfigOption BaseIntegerType
runBoolectorInOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a

-- | Run Boolector in a session. Boolector will be configured to produce
--   models, but otherwise left with the default configuration.
withBoolector :: ExprBuilder t st fs -> FilePath -> LogData -> (Session t Boolector -> IO a) -> IO a
boolectorOptions :: [ConfigDesc]
boolectorFeatures :: ProblemFeatures
data CVC4
CVC4 :: CVC4
cvc4Adapter :: SolverAdapter st

-- | Path to cvc4
cvc4Path :: ConfigOption (BaseStringType Unicode)

-- | Per-check timeout, in milliseconds (zero is none)
cvc4Timeout :: ConfigOption BaseIntegerType
runCVC4InOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a
writeCVC4SMT2File :: ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()

-- | Run CVC4 in a session. CVC4 will be configured to produce models, but
--   otherwise left with the default configuration.
withCVC4 :: ExprBuilder t st fs -> FilePath -> LogData -> (Session t CVC4 -> IO a) -> IO a
cvc4Options :: [ConfigDesc]
cvc4Features :: ProblemFeatures
data CVC5
CVC5 :: CVC5
cvc5Adapter :: SolverAdapter st

-- | Path to cvc5
cvc5Path :: ConfigOption (BaseStringType Unicode)

-- | Per-check timeout, in milliseconds (zero is none)
cvc5Timeout :: ConfigOption BaseIntegerType
runCVC5InOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a
writeCVC5SMT2File :: ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()

-- | Run cvc5 in a session. cvc5 will be configured to produce models, but
--   otherwise left with the default configuration.
withCVC5 :: ExprBuilder t st fs -> FilePath -> LogData -> (Session t CVC5 -> IO a) -> IO a
cvc5Options :: [ConfigDesc]
cvc5Features :: ProblemFeatures
data DReal
DReal :: DReal
type DRealBindings = Map Text (Either Bool (Maybe Rational, Maybe Rational))
drealAdapter :: SolverAdapter st

-- | Path to dReal
drealPath :: ConfigOption (BaseStringType Unicode)
runDRealInOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (WriterConn t (Writer DReal), DRealBindings) () -> IO a) -> IO a
writeDRealSMT2File :: ExprBuilder t st fs -> Handle -> [BoolExpr t] -> IO ()
data STP
STP :: STP
stpAdapter :: SolverAdapter st

-- | Path to stp
stpPath :: ConfigOption (BaseStringType Unicode)

-- | Per-check timeout, in milliseconds (zero is none)
stpTimeout :: ConfigOption BaseIntegerType
runSTPInOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a

-- | Run STP in a session. STP will be configured to produce models, buth
--   otherwise left with the default configuration.
withSTP :: ExprBuilder t st fs -> FilePath -> LogData -> (Session t STP -> IO a) -> IO a
stpOptions :: [ConfigDesc]
stpFeatures :: ProblemFeatures
yicesAdapter :: SolverAdapter t

-- | Path to yices
yicesPath :: ConfigOption (BaseStringType Unicode)

-- | Enable the MC-SAT solver
yicesEnableMCSat :: ConfigOption BaseBoolType

-- | Enable interactive mode (necessary for per-goal timeouts)
yicesEnableInteractive :: ConfigOption BaseBoolType

-- | Set a per-goal timeout in seconds.
yicesGoalTimeout :: ConfigOption BaseIntegerType

-- | Run writer and get a yices result.
runYicesInOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t) () -> IO a) -> IO a

-- | Write a yices file that checks the satisfiability of the given
--   predicate.
writeYicesFile :: ExprBuilder t st fs -> FilePath -> BoolExpr t -> IO ()
yicesOptions :: [ConfigDesc]
yicesDefaultFeatures :: ProblemFeatures
data Z3
Z3 :: Z3

-- | Path to Z3
z3Path :: ConfigOption (BaseStringType Unicode)

-- | Per-check timeout, in milliseconds (zero is none)
z3Timeout :: ConfigOption BaseIntegerType

-- | Z3 tactic
z3Tactic :: ConfigOption (BaseStringType Unicode)
z3TacticDefault :: Text
z3Adapter :: SolverAdapter st
runZ3InOverride :: ExprBuilder t st fs -> LogData -> [BoolExpr t] -> (SatResult (GroundEvalFn t, Maybe (ExprRangeBindings t)) () -> IO a) -> IO a

-- | Run Z3 in a session. Z3 will be configured to produce models, but
--   otherwise left with the default configuration.
withZ3 :: ExprBuilder t st fs -> FilePath -> LogData -> (Session t Z3 -> IO a) -> IO a
z3Options :: [ConfigDesc]
z3Features :: ProblemFeatures

module What4.WordMap

-- | A WordMap represents a finite partial map from bitvectors of
--   width w to elements of type tp.
data WordMap sym w tp
SimpleWordMap :: !SymExpr sym (BaseArrayType (EmptyCtx ::> BaseBVType w) BaseBoolType) -> !SymExpr sym (BaseArrayType (EmptyCtx ::> BaseBVType w) tp) -> WordMap sym w tp

-- | Create a word map where every element is undefined.
emptyWordMap :: (IsExprBuilder sym, 1 <= w) => sym -> NatRepr w -> BaseTypeRepr a -> IO (WordMap sym w a)

-- | Compute a pointwise if-then-else operation on the elements of two word
--   maps.
muxWordMap :: IsExprBuilder sym => sym -> NatRepr w -> BaseTypeRepr a -> Pred sym -> WordMap sym w a -> WordMap sym w a -> IO (WordMap sym w a)

-- | Update a word map at the given index.
insertWordMap :: IsExprBuilder sym => sym -> NatRepr w -> BaseTypeRepr a -> SymBV sym w -> SymExpr sym a -> WordMap sym w a -> IO (WordMap sym w a)

-- | Lookup the value of an index in a word map.
lookupWordMap :: IsExprBuilder sym => sym -> NatRepr w -> BaseTypeRepr a -> SymBV sym w -> WordMap sym w a -> IO (PartExpr (Pred sym) (SymExpr sym a))
