Interactive solving
The simplest way to solve an SMT problem is to call sat!
. Under the hood, sat!
translates your problem to the SMT-LIB format, spawns a solver in a new process, feeds in your problem and, if it's satisfiable, requests the satisfying assignment.
However, many use cases require ongoing interaction with the SMT solver. Satisfiability.jl provides this functionality using the InteractiveSolver
struct, allowing users to interface with a running solver process. A typical interactive workflow looks like this.
Construct some expressions
using Satisfiability
@satvariable(x, Bool)
@satvariable(y, Bool)
@satvariable(z, Bool)
expr1 = or(and(not(x), y), and(not(y), x))
expr2 = not(z)
Spawn a solver process and make some assertions.
interactive_solver = open(Z3())
assert!(interactive_solver, expr1, expr2)
Check satisfiability. In interactive solver mode, you can provide more expressions to sat!
; this would look like sat!(interactive_solver, expr3, expr4...)
. Since sat!
only receives the solver object, it's not able to set the values of expr1
and expr2
. Instead, it will return a dictionary containing the satisfying assignment. You can then set your expressions' values using assign!
.
status, assignment = sat!(interactive_solver)
if status == :SAT
assign!(expr1, assignment)
assign!(expr2, assignment)
println("Values of x, y, z: x=$(value(x)), y=$(value(y)), z=$(value(z)))")
end
Do other stuff, then close your process.
close(interactive_solver)
The Graph Coloring example uses interactivity to find every solution to a problem.
Managing the assertion stack
SMT-LIB implements the concept of an assertion stack. Pushing a level onto the stack allows you to assert statements, then pop that level off, erasing the assertions and declarations you made. This is useful when incrementally adding constraints to a problem. Finding Bad Assertions provides an example of using push
and pop
or sat!(solver, exprs...)
to manage assertions.
How can I get more control over the solver?
If you need more granular control over solver commands and responses, check our guide on advanced usage. For suggestions, feel free to open a GitHub issue! This is a new package and we'd like to hear user feedback.
!!! warning Don't set print-success
If you set the SMT-LIB option (set-option :print-success true)
it will confuse the output parser. Future versions of Satisfiability.jl will address this issue.