Copyright | (c) Levent Erkok |
---|---|
License | BSD3 |
Maintainer | erkokl@gmail.com |
Stability | experimental |
Safe Haskell | None |
Language | Haskell2010 |
Data.SBV.Control
Description
Control sublanguage for interacting with SMT solvers.
Synopsis
- class MonadIO m => ExtractIO (m :: Type -> Type) where
- class Monad m => MonadQuery (m :: Type -> Type) where
- queryState :: m State
- type Query = QueryT IO
- query :: Query a -> Symbolic a
- data CheckSatResult
- checkSat :: (MonadIO m, MonadQuery m) => m CheckSatResult
- ensureSat :: (MonadIO m, MonadQuery m) => m ()
- checkSatUsing :: (MonadIO m, MonadQuery m) => String -> m CheckSatResult
- checkSatAssuming :: (MonadIO m, MonadQuery m) => [SBool] -> m CheckSatResult
- checkSatAssumingWithUnsatisfiableSet :: (MonadIO m, MonadQuery m) => [SBool] -> m (CheckSatResult, Maybe [SBool])
- registerUISMTFunction :: (MonadIO m, SolverContext m, SMTFunction fun a r) => fun -> m ()
- registerSMTType :: forall a m. (MonadIO m, SolverContext m, HasKind a) => Proxy a -> m ()
- getFunction :: (MonadIO m, MonadQuery m, SolverContext m, MonadSymbolic m, SymVal a, SymVal r, SMTFunction fun a r) => fun -> m (Either (String, (Bool, Maybe [String], SExpr)) ([(a, r)], r))
- getUninterpretedValue :: (MonadIO m, MonadQuery m, HasKind a) => SBV a -> m String
- getModel :: (MonadIO m, MonadQuery m) => m SMTModel
- getAssignment :: (MonadIO m, MonadQuery m) => m [(String, Bool)]
- getSMTResult :: (MonadIO m, MonadQuery m) => m SMTResult
- getUnknownReason :: (MonadIO m, MonadQuery m) => m SMTReasonUnknown
- getObservables :: (MonadIO m, MonadQuery m) => m [(Name, CV)]
- getUnsatCore :: (MonadIO m, MonadQuery m) => m [String]
- getProof :: (MonadIO m, MonadQuery m) => m String
- getInterpolantMathSAT :: (MonadIO m, MonadQuery m) => [String] -> m String
- getInterpolantZ3 :: (MonadIO m, MonadQuery m) => [SBool] -> m String
- getAbduct :: (SolverContext m, MonadIO m, MonadQuery m) => Maybe String -> String -> SBool -> m String
- getAbductNext :: (MonadIO m, MonadQuery m) => m String
- getAssertions :: (MonadIO m, MonadQuery m) => m [String]
- data SMTInfoFlag
- data SMTErrorBehavior
- data SMTInfoResponse
- getInfo :: (MonadIO m, MonadQuery m) => SMTInfoFlag -> m SMTInfoResponse
- getOption :: (MonadIO m, MonadQuery m) => (a -> SMTOption) -> m (Maybe SMTOption)
- getAssertionStackDepth :: (MonadIO m, MonadQuery m) => m Int
- push :: (MonadIO m, MonadQuery m) => Int -> m ()
- pop :: (MonadIO m, MonadQuery m) => Int -> m ()
- inNewAssertionStack :: (MonadIO m, MonadQuery m) => m a -> m a
- caseSplit :: (MonadIO m, MonadQuery m) => Bool -> [(String, SBool)] -> m (Maybe (String, SMTResult))
- resetAssertions :: (MonadIO m, MonadQuery m) => m ()
- (|->) :: SymVal a => SBV a -> a -> Assignment
- mkSMTResult :: (MonadIO m, MonadQuery m) => [Assignment] -> m SMTResult
- exit :: (MonadIO m, MonadQuery m) => m ()
- ignoreExitCode :: SMTConfig -> Bool
- timeout :: (MonadIO m, MonadQuery m) => Int -> m a -> m a
- queryDebug :: (MonadIO m, MonadQuery m) => [String] -> m ()
- echo :: (MonadIO m, MonadQuery m) => String -> m ()
- io :: MonadIO m => IO a -> m a
- data SMTOption
- = DiagnosticOutputChannel FilePath
- | ProduceAssertions Bool
- | ProduceAssignments Bool
- | ProduceProofs Bool
- | ProduceInterpolants Bool
- | ProduceUnsatAssumptions Bool
- | ProduceUnsatCores Bool
- | ProduceAbducts Bool
- | RandomSeed Integer
- | ReproducibleResourceLimit Integer
- | SMTVerbosity Integer
- | OptionKeyword String [String]
- | SetLogic Logic
- | SetInfo String [String]
Documentation
In certain cases, the user might want to take over the communication with the solver, programmatically querying the engine and issuing commands accordingly. Queries can be extremely powerful as they allow direct control of the solver. Here's a simple example:
module Test where import Data.SBV import Data.SBV.Control -- queries require this module to be imported! test :: Symbolic (Maybe (Integer, Integer)) test = do x <- sInteger "x" -- a free variable named "x" y <- sInteger "y" -- a free variable named "y" -- require the sum to be 10 constrain $ x + y .== 10 -- Go into the Query mode query $ do -- Query the solver: Are the constraints satisfiable? cs <- checkSat case cs of Unk -> error "Solver said unknown!" DSat{} -> error "Solver said DSat!" Unsat -> return Nothing -- no solution! Sat -> -- Query the values: do xv <- getValue x yv <- getValue y io $ putStrLn $ "Solver returned: " ++ show (xv, yv) -- We can now add new constraints, -- Or perform arbitrary computations and tell -- the solver anything we want! constrain $ x .> literal xv + literal yv -- call checkSat again csNew <- checkSat case csNew of Unk -> error "Solver said unknown!" DSat{} -> error "Solver said DSat!" Unsat -> return Nothing Sat -> do xv2 <- getValue x yv2 <- getValue y return $ Just (xv2, yv2)
Note the type of test
: it returns an optional pair of integers in the Symbolic
monad. We turn
it into an IO value with the runSMT
function: (There's also runSMTWith
that uses a user specified
solver instead of the default. Note that z3
is best supported (and tested), if you use another solver your results may vary!)
pair :: IO (Maybe (Integer, Integer)) pair = runSMT test
When run, this can return:
*Test> pair Solver returned: (10,0) Just (11,-1)
demonstrating that the user has full contact with the solver and can guide it as the program executes. SBV provides access to many SMTLib features in the query mode, as exported from this very module.
For other examples see:
- Documentation.SBV.Examples.Queries.AllSat: Simulating SBV's
allSat
using queries. - Documentation.SBV.Examples.Queries.CaseSplit: Performing a case-split during a query.
- Documentation.SBV.Examples.Queries.Enums: Using enumerations in queries.
- Documentation.SBV.Examples.Queries.FourFours: Solution to a fun arithmetic puzzle, coded using queries.
- Documentation.SBV.Examples.Queries.GuessNumber: The famous number guessing game.
- Documentation.SBV.Examples.Queries.UnsatCore: Extracting unsat-cores using queries.
- Documentation.SBV.Examples.Queries.Interpolants: Extracting interpolants using queries.
User queries
class MonadIO m => ExtractIO (m :: Type -> Type) where Source #
Monads which support IO
operations and can extract all IO
behavior for
interoperation with functions like catches
, which takes
an IO
action in negative position. This function can not be implemented
for transformers like ReaderT r
or StateT s
, whose resultant IO
actions are a function of some environment or state.
Instances
ExtractIO IO Source # | Trivial IO extraction for |
ExtractIO m => ExtractIO (MaybeT m) Source # | IO extraction for |
ExtractIO m => ExtractIO (ExceptT e m) Source # | IO extraction for |
(Monoid w, ExtractIO m) => ExtractIO (WriterT w m) Source # | IO extraction for lazy |
(Monoid w, ExtractIO m) => ExtractIO (WriterT w m) Source # | IO extraction for strict |
class Monad m => MonadQuery (m :: Type -> Type) where Source #
Computations which support query operations.
Minimal complete definition
Nothing
Methods
queryState :: m State Source #
default queryState :: forall (t :: (Type -> Type) -> Type -> Type) (m' :: Type -> Type). (MonadTrans t, MonadQuery m', m ~ t m') => m State Source #
Instances
type Query = QueryT IO Source #
A query is a user-guided mechanism to directly communicate and extract results from the solver.
Checking satisfiability
data CheckSatResult Source #
Result of a checkSat
or checkSatAssuming
call.
Constructors
Sat | Satisfiable: A model is available, which can be queried with |
DSat (Maybe String) | Delta-satisfiable: A delta-sat model is available. String is the precision info, if available. |
Unsat | Unsatisfiable: No model is available. Unsat cores might be obtained via |
Unk | Unknown: Use |
Instances
Show CheckSatResult Source # | |
Defined in Data.SBV.Control.Types Methods showsPrec :: Int -> CheckSatResult -> ShowS # show :: CheckSatResult -> String # showList :: [CheckSatResult] -> ShowS # | |
Eq CheckSatResult Source # | |
Defined in Data.SBV.Control.Types Methods (==) :: CheckSatResult -> CheckSatResult -> Bool # (/=) :: CheckSatResult -> CheckSatResult -> Bool # |
checkSat :: (MonadIO m, MonadQuery m) => m CheckSatResult Source #
Generalization of checkSat
checkSatUsing :: (MonadIO m, MonadQuery m) => String -> m CheckSatResult Source #
Generalization of checkSatUsing
checkSatAssuming :: (MonadIO m, MonadQuery m) => [SBool] -> m CheckSatResult Source #
Generalization of checkSatAssuming
checkSatAssumingWithUnsatisfiableSet :: (MonadIO m, MonadQuery m) => [SBool] -> m (CheckSatResult, Maybe [SBool]) Source #
Generalization of checkSatAssumingWithUnsatisfiableSet
Querying the solver
Extracting values
registerUISMTFunction :: (MonadIO m, SolverContext m, SMTFunction fun a r) => fun -> m () Source #
Registering an uninterpreted SMT function. This is typically not necessary as uses of the UI function itself will register it automatically. But there are cases where doing this explicitly can come in handy, typically in query contexts.
registerSMTType :: forall a m. (MonadIO m, SolverContext m, HasKind a) => Proxy a -> m () Source #
Register a kind with the solver. Like registerUISMTFunction
, this is typically not necessary
since SBV will register kinds as it encounters them automatically. But there are cases
where doing this can explicitly can come handy, typically in query contexts.
getFunction :: (MonadIO m, MonadQuery m, SolverContext m, MonadSymbolic m, SymVal a, SymVal r, SMTFunction fun a r) => fun -> m (Either (String, (Bool, Maybe [String], SExpr)) ([(a, r)], r)) Source #
Generalization of getFunction
getUninterpretedValue :: (MonadIO m, MonadQuery m, HasKind a) => SBV a -> m String Source #
Generalization of getUninterpretedValue
getAssignment :: (MonadIO m, MonadQuery m) => m [(String, Bool)] Source #
Generalization of getAssignment
getSMTResult :: (MonadIO m, MonadQuery m) => m SMTResult Source #
Generalization of getSMTResult
getUnknownReason :: (MonadIO m, MonadQuery m) => m SMTReasonUnknown Source #
Generalization of getUnknownReason
getObservables :: (MonadIO m, MonadQuery m) => m [(Name, CV)] Source #
Get observables, i.e., those explicitly labeled by the user with a call to observe
.
Extracting the unsat core
getUnsatCore :: (MonadIO m, MonadQuery m) => m [String] Source #
Generalization of getUnsatCore
Extracting a proof
Extracting interpolants
getInterpolantMathSAT :: (MonadIO m, MonadQuery m) => [String] -> m String Source #
Generalization of getInterpolantMathSAT
. Use this version with MathSAT.
getInterpolantZ3 :: (MonadIO m, MonadQuery m) => [SBool] -> m String Source #
Generalization of getInterpolantZ3
. Use this version with Z3.
Getting abducts
getAbduct :: (SolverContext m, MonadIO m, MonadQuery m) => Maybe String -> String -> SBool -> m String Source #
Generalization of getAbduct
.
getAbductNext :: (MonadIO m, MonadQuery m) => m String Source #
Generalization of getAbductNext
.
Extracting assertions
getAssertions :: (MonadIO m, MonadQuery m) => m [String] Source #
Generalization of getAssertions
Getting solver information
data SMTInfoFlag Source #
Collectable information from the solver.
Constructors
AllStatistics | |
AssertionStackLevels | |
Authors | |
ErrorBehavior | |
Name | |
ReasonUnknown | |
Version | |
InfoKeyword String |
Instances
Show SMTInfoFlag Source # | |
Defined in Data.SBV.Control.Types Methods showsPrec :: Int -> SMTInfoFlag -> ShowS # show :: SMTInfoFlag -> String # showList :: [SMTInfoFlag] -> ShowS # |
data SMTErrorBehavior Source #
Behavior of the solver for errors.
Constructors
ErrorImmediateExit | |
ErrorContinuedExecution |
Instances
Show SMTErrorBehavior Source # | |
Defined in Data.SBV.Control.Types Methods showsPrec :: Int -> SMTErrorBehavior -> ShowS # show :: SMTErrorBehavior -> String # showList :: [SMTErrorBehavior] -> ShowS # |
data SMTInfoResponse Source #
Collectable information from the solver.
Constructors
Instances
Show SMTInfoResponse Source # | |
Defined in Data.SBV.Control.Types Methods showsPrec :: Int -> SMTInfoResponse -> ShowS # show :: SMTInfoResponse -> String # showList :: [SMTInfoResponse] -> ShowS # |
getInfo :: (MonadIO m, MonadQuery m) => SMTInfoFlag -> m SMTInfoResponse Source #
Generalization of getInfo
getOption :: (MonadIO m, MonadQuery m) => (a -> SMTOption) -> m (Maybe SMTOption) Source #
Generalization of getInfo
Entering and exiting assertion stack
getAssertionStackDepth :: (MonadIO m, MonadQuery m) => m Int Source #
Generalization of getAssertionStackDepth
inNewAssertionStack :: (MonadIO m, MonadQuery m) => m a -> m a Source #
Generalization of inNewAssertionStack
Higher level tactics
caseSplit :: (MonadIO m, MonadQuery m) => Bool -> [(String, SBool)] -> m (Maybe (String, SMTResult)) Source #
Generalization of caseSplit
Resetting the solver state
resetAssertions :: (MonadIO m, MonadQuery m) => m () Source #
Generalization of resetAssertions
Constructing assignments
(|->) :: SymVal a => SBV a -> a -> Assignment infix 1 Source #
Make an assignment. The type Assignment
is abstract, the result is typically passed
to mkSMTResult
:
mkSMTResult [ a |-> 332 , b |-> 2.3 , c |-> True ]
End users should use getModel
for automatically constructing models from the current solver state.
However, an explicit Assignment
might be handy in complex scenarios where a model needs to be
created manually.
Terminating the query
mkSMTResult :: (MonadIO m, MonadQuery m) => [Assignment] -> m SMTResult Source #
Generalization of mkSMTResult
NB. This function does not allow users to create interpretations for UI-Funs. But that's
probably not a good idea anyhow. Also, if you use the validateModel
or optimizeValidateConstraints
features, SBV will
fail on models returned via this function.
Controlling the solver behavior
ignoreExitCode :: SMTConfig -> Bool Source #
If true, we shall ignore the exit code upon exit. Otherwise we require ExitSuccess.
Miscellaneous
queryDebug :: (MonadIO m, MonadQuery m) => [String] -> m () Source #
Generalization of queryDebug
Solver options
Option values that can be set in the solver, following the SMTLib specification https://smt-lib.org/language.shtml.
Note that not all solvers may support all of these!
Furthermore, SBV doesn't support the following options allowed by SMTLib.
:interactive-mode
(Deprecated in SMTLib, useProduceAssertions
instead.):print-success
(SBV critically needs this to be True in query mode.):produce-models
(SBV always sets this option so it can extract models.):regular-output-channel
(SBV always requires regular output to come on stdout for query purposes.):global-declarations
(SBV always uses global declarations since definitions are accumulative.)
Note that SetLogic
and SetInfo
are, strictly speaking, not SMTLib options. However, we treat it as such here
uniformly, as it fits better with how options work.
Constructors