grisette-0.9.0.0: Symbolic evaluation as a library
Copyright(c) Sirui Lu 2021-2023
LicenseBSD-3-Clause (see the LICENSE file)
Maintainersiruilu@cs.washington.edu
StabilityExperimental
PortabilityGHC only
Safe HaskellTrustworthy
LanguageHaskell2010

Grisette.Internal.Core.Data.Class.Solver

Description

 
Synopsis

Note for the examples

The examples assumes that the z3 solver is available in PATH.

Solver interfaces

data SolvingFailure Source #

The current failures that can be returned by the solver.

Constructors

Unsat

Unsatisfiable: No model is available.

Unk

Unknown: The solver cannot determine whether the formula is satisfiable.

ResultNumLimitReached

The solver has reached the maximum number of models to return.

SolvingError Text

The solver has encountered an error.

Terminated

The solver has been terminated.

Instances

Instances details
Generic SolvingFailure Source # 
Instance details

Defined in Grisette.Internal.Core.Data.Class.Solver

Associated Types

type Rep SolvingFailure :: Type -> Type #

Show SolvingFailure Source # 
Instance details

Defined in Grisette.Internal.Core.Data.Class.Solver

Binary SolvingFailure Source # 
Instance details

Defined in Grisette.Internal.Core.Data.Class.Solver

Serial SolvingFailure Source # 
Instance details

Defined in Grisette.Internal.Core.Data.Class.Solver

Serialize SolvingFailure Source # 
Instance details

Defined in Grisette.Internal.Core.Data.Class.Solver

NFData SolvingFailure Source # 
Instance details

Defined in Grisette.Internal.Core.Data.Class.Solver

Methods

rnf :: SolvingFailure -> () #

Eq SolvingFailure Source # 
Instance details

Defined in Grisette.Internal.Core.Data.Class.Solver

PPrint SolvingFailure Source # 
Instance details

Defined in Grisette.Internal.Core.Data.Class.Solver

Hashable SolvingFailure Source # 
Instance details

Defined in Grisette.Internal.Core.Data.Class.Solver

Lift SolvingFailure Source # 
Instance details

Defined in Grisette.Internal.Core.Data.Class.Solver

Methods

lift :: Quote m => SolvingFailure -> m Exp #

liftTyped :: forall (m :: Type -> Type). Quote m => SolvingFailure -> Code m SolvingFailure #

type Rep SolvingFailure Source # 
Instance details

Defined in Grisette.Internal.Core.Data.Class.Solver

type Rep SolvingFailure = D1 ('MetaData "SolvingFailure" "Grisette.Internal.Core.Data.Class.Solver" "grisette-0.9.0.0-8b30m8DmEAJELhVBobm0Vc" 'False) ((C1 ('MetaCons "Unsat" 'PrefixI 'False) (U1 :: Type -> Type) :+: C1 ('MetaCons "Unk" 'PrefixI 'False) (U1 :: Type -> Type)) :+: (C1 ('MetaCons "ResultNumLimitReached" 'PrefixI 'False) (U1 :: Type -> Type) :+: (C1 ('MetaCons "SolvingError" 'PrefixI 'False) (S1 ('MetaSel ('Nothing :: Maybe Symbol) 'NoSourceUnpackedness 'NoSourceStrictness 'DecidedLazy) (Rec0 Text)) :+: C1 ('MetaCons "Terminated" 'PrefixI 'False) (U1 :: Type -> Type))))

class Monad m => MonadicSolver m where Source #

A monadic solver interface.

This interface abstract the monadic interface of a solver. All the operations performed in the monad are using a single solver instance. The solver instance is management by the monad's run function.

monadicSolverSolve :: MonadicSolver m => SymBool -> m (Either SolvingFailure Model) Source #

Solve a single formula with a monadic solver. Find an assignment to it to make it true.

data SolverCommand Source #

The commands that can be sent to a solver.

class Solver handle => ConfigurableSolver config handle | config -> handle where Source #

A class that abstracts the creation of a solver instance based on a configuration.

The solver instance will need to be terminated by the user, with the solver interface.

Methods

newSolver :: config -> IO handle Source #

class Solver handle where Source #

A class that abstracts the solver interface.

Methods

solverRunCommand :: (handle -> IO (Either SolvingFailure a)) -> handle -> SolverCommand -> IO (Either SolvingFailure a) Source #

Run a solver command.

solverAssert :: handle -> SymBool -> IO (Either SolvingFailure ()) Source #

Assert a formula.

solverCheckSat :: handle -> IO (Either SolvingFailure Model) Source #

Solve a formula.

solverPush :: handle -> Int -> IO (Either SolvingFailure ()) Source #

Push n levels.

solverPop :: handle -> Int -> IO (Either SolvingFailure ()) Source #

Pop n levels.

solverResetAssertions :: handle -> IO (Either SolvingFailure ()) Source #

Reset all assertions in the solver.

The solver keeps all the assertions used in the previous commands:

>>> solver <- newSolver z3
>>> solverSolve solver "a"
Right (Model {a -> true :: Bool})
>>> solverSolve solver $ symNot "a"
Left Unsat

You can clear the assertions using solverResetAssertions:

>>> solverResetAssertions solver
Right ()
>>> solverSolve solver $ symNot "a"
Right (Model {a -> false :: Bool})

solverTerminate :: handle -> IO () Source #

Terminate the solver, wait until the last command is finished.

solverForceTerminate :: handle -> IO () Source #

Force terminate the solver, do not wait for the last command to finish.

solverSolve :: Solver handle => handle -> SymBool -> IO (Either SolvingFailure Model) Source #

Solve a single formula. Find an assignment to it to make it true.

withSolver :: ConfigurableSolver config handle => config -> (handle -> IO a) -> IO a Source #

Start a solver, run a computation with the solver, and terminate the solver after the computation finishes.

When an exception happens, this will forcibly terminate the solver.

Note: if Grisette is compiled with sbv < 10.10, the solver likely won't be really terminated until it has finished the last action, and this will result in long-running or zombie solver instances.

This was due to a bug in sbv, which is fixed in https://github.com/LeventErkok/sbv/pull/695.

solve Source #

Arguments

:: ConfigurableSolver config handle 
=> config

solver configuration

-> SymBool

formula to solve, the solver will try to make it true

-> IO (Either SolvingFailure Model) 

Solve a single formula. Find an assignment to it to make it true.

>>> solve z3 ("a" .&& ("b" :: SymInteger) .== 1)
Right (Model {a -> true :: Bool, b -> 1 :: Integer})
>>> solve z3 ("a" .&& symNot "a")
Left Unsat

solverSolveMulti Source #

Arguments

:: Solver handle 
=> handle

solver handle

-> Int

maximum number of models to return

-> SymBool

formula to solve, the solver will try to make it true

-> IO ([Model], SolvingFailure) 

Solve a single formula while returning multiple models to make it true. The maximum number of desired models are given.

solveMulti Source #

Arguments

:: ConfigurableSolver config handle 
=> config

solver configuration

-> Int

maximum number of models to return

-> SymBool

formula to solve, the solver will try to make it true

-> IO ([Model], SolvingFailure) 

Solve a single formula while returning multiple models to make it true. The maximum number of desired models are given.

>>> solveMulti z3 4 ("a" .|| "b")
[Model {a -> True :: Bool, b -> False :: Bool},Model {a -> False :: Bool, b -> True :: Bool},Model {a -> True :: Bool, b -> True :: Bool}]

Union with exceptions

class UnionWithExcept t u e v | t -> u e v where Source #

A class that abstracts the union-like structures that contains exceptions.

Methods

extractUnionExcept :: t -> u (Either e v) Source #

Extract a union of exceptions and values from the structure.

Instances

Instances details
UnionWithExcept (Union (Either e v)) Union e v Source # 
Instance details

Defined in Grisette.Internal.Core.Control.Monad.Union

UnionWithExcept (Union (CBMCEither e v)) Union e v Source # 
Instance details

Defined in Grisette.Internal.Core.Control.Monad.CBMCExcept

(Monad u, TryMerge u, Mergeable e, Mergeable v) => UnionWithExcept (CBMCExceptT e u v) u e v Source # 
Instance details

Defined in Grisette.Internal.Core.Control.Monad.CBMCExcept

Methods

extractUnionExcept :: CBMCExceptT e u v -> u (Either e v) Source #

UnionWithExcept (ExceptT e u v) u e v Source # 
Instance details

Defined in Grisette.Internal.Core.Data.Class.Solver

Methods

extractUnionExcept :: ExceptT e u v -> u (Either e v) Source #

solverSolveExcept Source #

Arguments

:: (UnionWithExcept t u e v, PlainUnion u, Functor u, Solver handle) 
=> handle

solver handle

-> (Either e v -> SymBool)

mapping the results to symbolic boolean formulas, the solver would try to find a model to make the formula true

-> t

the program to be solved, should be a union of exception and values

-> IO (Either SolvingFailure Model) 

Solver procedure for programs with error handling.

solveExcept Source #

Arguments

:: (UnionWithExcept t u e v, PlainUnion u, Functor u, ConfigurableSolver config handle) 
=> config

solver configuration

-> (Either e v -> SymBool)

mapping the results to symbolic boolean formulas, the solver would try to find a model to make the formula true

-> t

the program to be solved, should be a union of exception and values

-> IO (Either SolvingFailure Model) 

Solver procedure for programs with error handling.

>>> import Control.Monad.Except
>>> let x = "x" :: SymInteger
>>> :{
  res :: ExceptT AssertionError Union ()
  res = do
    symAssert $ x .> 0       -- constrain that x is positive
    symAssert $ x .< 2       -- constrain that x is less than 2
:}
>>> :{
  translate (Left _) = con False -- errors are not desirable
  translate _ = con True         -- non-errors are desirable
:}
>>> solveExcept z3 translate res
Right (Model {x -> 1 :: Integer})

solverSolveMultiExcept Source #

Arguments

:: (UnionWithExcept t u e v, PlainUnion u, Functor u, Solver handle) 
=> handle

solver configuration

-> Int

maximum number of models to return

-> (Either e v -> SymBool)

mapping the results to symbolic boolean formulas, the solver would try to find a model to make the formula true

-> t

the program to be solved, should be a union of exception and values

-> IO ([Model], SolvingFailure) 

Solver procedure for programs with error handling. Would return multiple models if possible.

solveMultiExcept Source #

Arguments

:: (UnionWithExcept t u e v, PlainUnion u, Functor u, ConfigurableSolver config handle) 
=> config

solver configuration

-> Int

maximum number of models to return

-> (Either e v -> SymBool)

mapping the results to symbolic boolean formulas, the solver would try to find a model to make the formula true

-> t

the program to be solved, should be a union of exception and values

-> IO ([Model], SolvingFailure) 

Solver procedure for programs with error handling. Would return multiple models if possible.