-- 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, 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.3 -- | 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 = 'BaseBoolType " @:: 'BaseType'@." type BaseIntegerType = 'BaseIntegerType " @:: 'BaseType'@." type BaseRealType = 'BaseRealType " @:: 'BaseType'@." type BaseStringType = 'BaseStringType " @:: 'BaseType'@." type BaseBVType = 'BaseBVType " @:: 'TypeNats.Nat' -> 'BaseType'@." type BaseFloatType = 'BaseFloatType " @:: 'FloatPrecision' -> 'BaseType'@." type BaseComplexType = 'BaseComplexType " @:: 'BaseType'@." type BaseStructType = 'BaseStructType " @:: 'Ctx.Ctx' 'BaseType' -> 'BaseType'@." type BaseArrayType = 'BaseArrayType " @:: 'Ctx.Ctx' 'BaseType' -> 'BaseType' -> 'BaseType'@." data StringInfo type Char8 = 'Char8 " @:: 'StringInfo'@." type Char16 = 'Char16 " @:: 'StringInfo'@." type Unicode = 'Unicode " @:: 'StringInfo'@." -- | 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 = 'FloatingPointPrecision " @:: 'GHC.TypeNats.Nat' -> 'GHC.TypeNats.Nat' -> 'FloatPrecision'@." -- | 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 GHC.TypeNats.<= 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 GHC.TypeNats.<= eb, 2 GHC.TypeNats.<= 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 CVC4/Z3, and tuples in -- Yices. useStructs :: ProblemFeatures -- | Indicates whether the problem uses strings -- -- Strings have some symbolic support in CVC4 and Z3. useStrings :: ProblemFeatures -- | Indicates whether the problem uses floating-point -- -- Floating-point has some symbolic support in CVC4 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 -- | 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 Data.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 () 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.Integer.Type.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 -- | 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. allSupported :: 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 givne 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 -- | Disjunction 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 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: -- -- -- -- 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 = 'SemiRingInteger " @:: 'SemiRing'@" type SemiRingReal = 'SemiRingReal " @:: 'SemiRing'@" type SemiRingBV = 'SemiRingBV " @:: 'BVFlavor' -> 'Nat' -> '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 type BVBits = 'BVBits " @:: 'BVFlavor'@" type BVArith = 'BVArith " @:: 'BVFlavor'@" 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) -- | 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 -> Type) (tp :: k). Data.Parameterized.Classes.OrdF e => Data.Type.Equality.TestEquality (What4.SpecialFunctions.SpecialFnArg e tp) instance forall k (e :: k -> Type) (tp :: k). Data.Parameterized.Classes.OrdF e => Data.Parameterized.Classes.OrdF (What4.SpecialFunctions.SpecialFnArg e tp) instance forall k (e :: k -> Type) (tp :: k). Data.Parameterized.Classes.HashableF e => Data.Parameterized.Classes.HashableF (What4.SpecialFunctions.SpecialFnArg e tp) instance forall k (e :: k -> Type) (tp :: k) (r :: Data.Parameterized.Ctx.Ctx Type). Data.Parameterized.Classes.OrdF e => GHC.Classes.Eq (What4.SpecialFunctions.SpecialFnArgs e tp r) instance forall k (e :: k -> Type) (tp :: k) (r :: Data.Parameterized.Ctx.Ctx Type). Data.Parameterized.Classes.OrdF e => GHC.Classes.Ord (What4.SpecialFunctions.SpecialFnArgs e tp r) instance forall k (e :: k -> Type) (tp :: k) (args :: Data.Parameterized.Ctx.Ctx 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: -- -- -- -- 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 -- | 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_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) -- | 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 -> Type) (x :: k). Data.Type.Equality.TestEquality f => GHC.Classes.Eq (What4.Expr.BoolMap.Wrap f x) instance forall k (f :: k -> Type) (x :: k). Data.Parameterized.Classes.OrdF f => GHC.Classes.Ord (What4.Expr.BoolMap.Wrap f x) instance forall k (f :: k -> 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 -- -- -- -- 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 Data.Versions.VUnit instance Language.Haskell.TH.Syntax.Lift Data.Versions.Version 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 GHC.TypeNats.<= 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: -- -- -- -- 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: -- -- -- -- 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 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 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.Integer.Type.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: -- -- -- -- 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 -- | 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 -- | 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), 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: -- -- -- -- 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: -- -- 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: -- -- 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)) => 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) -- | 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: -- -- -- -- 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 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) -- | 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_a33YK v_a33YL p_a34nN. Lens (Partial p_a33YK v_a33YL) (Partial p_a34nN v_a33YL) p_a33YK p_a34nN partialValue :: forall p_a33YK v_a33YL v_a34nO. Lens (Partial p_a33YK v_a33YL) (Partial p_a33YK v_a34nO) v_a33YL v_a34nO -- | 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 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 e, Data.Data.Data p, Data.Data.Data v) => 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 = 'HalfFloat " 16 bit binary IEEE754." type SingleFloat = 'SingleFloat " 32 bit binary IEEE754." type DoubleFloat = 'DoubleFloat " 64 bit binary IEEE754." type QuadFloat = 'QuadFloat " 128 bit binary IEEE754." type X86_80Float = 'X86_80Float " X86 80-bit extended floats." type DoubleDoubleFloat = 'DoubleDoubleFloat " Two 64-bit floats fused in the "double-double" style." -- | 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 CVC4/Z3, 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 Control.Monad.Fail.MonadFail (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 -- | 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.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.Interface.IsSymExprBuilder (What4.Expr.Builder.ExprBuilder t st fs) 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 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 2 .|| infixr 3 .&& infix 4 .== infix 4 ./= infix 4 .<= infix 4 .< infix 4 .>= type ArrayConstantFn v = [Some TypeMap] " Type for indices" -> Some TypeMap " Type for value." -> v " Constant to assign all values." -> 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 -- | Push 1 new scope pushCommand :: SMTWriter h => f h -> Command h -- | Pop 1 existing scope popCommand :: 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 -- | 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 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 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 () 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 -- | 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 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 CVC4/Z3, 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) -- | 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 -- | 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] -- | 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 () -- | 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 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] -- | 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. allSupported :: Logic -- | Set the logic to all supported logics. -- | Deprecated: Use allSupported 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 () 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 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 () 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 -- | 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 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))