Skip to content

Commit 686a082

Browse files
authored
Merge pull request #2777 from martin-cs/documentation/solvers
Revise, expand and update the documentation on solvers/
2 parents 600a2af + 0773e23 commit 686a082

File tree

1 file changed

+142
-33
lines changed

1 file changed

+142
-33
lines changed

src/solvers/README.md

Lines changed: 142 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,156 @@
66

77
\section solvers-overview Overview
88

9-
The basic role of solvers is to answer whether the set of equations given
10-
is satisfiable.
11-
One example usage, is to determine whether an assertion in a
12-
program can be violated.
13-
We refer to \ref goto-symex for how CBMC and JBMC convert a input program
14-
and property to a set of equations.
15-
16-
The secondary role of solvers is to provide a satisfying assignment of
17-
the variables of the equations, this can for instance be used to construct
18-
a trace.
19-
20-
The `solvers/` directory contains interfaces to a number of
21-
different decision procedures, roughly one per directory.
22-
23-
* prop/: The basic and common functionality. The key file is
24-
`prop_conv.h` which defines `prop_convt`. This is the base class that
25-
is used to interface to the decision procedures. The key functions are
26-
`convert` which takes an `exprt` and converts it to the appropriate,
27-
solver specific, data structures and `dec_solve` (inherited from
28-
`decision_proceduret`) which invokes the actual decision procedures.
29-
Individual decision procedures (named `*_dect`) objects can be created
30-
but `prop_convt` is the preferred interface for code that uses them.
31-
32-
* flattening/: A library that converts operations to bit-vectors,
9+
This directory contains most of the decision procedure code in CPROVER.
10+
A decision procedure is an algorithm which can check if a set of logical
11+
statements is satisfiable, i.e. if there is a value for each variable which
12+
makes all of them true at the same time. Formally all
13+
that is needed is determining if they are satisfiable, in practice it
14+
is often very valuable to know the assignments of the variables.
15+
Tools (and components) that implement decision procedures are often
16+
called solvers. For example a SAT solver is a tool that implements a
17+
decision procedure for checking the satisfiability of formulae (often
18+
in CNF) over Boolean variables. An SMT solver is a tool that
19+
implements decision procedures for the Satisfiability Modulo Theories
20+
class of problems. CPROVER includes its own SMT solver, built on top
21+
of a SAT solver but can also interface to external solvers.
22+
23+
CBMC and JBMC create formulae which describe some of the execution of parts of a
24+
program (see \ref goto-symex for how this is done) and then use a solver to see
25+
if there are any executions which break an assertion. If the formula describing
26+
the execution and the formula describing the assertion are satisfiable
27+
then it is possible for the assertion to fail and the assignment of the
28+
variables can be used to build an error trace (see \ref goto_tracet). Thus
29+
the performance and capability of the solver used is crucial to the utility of
30+
CBMC and JBMC. Other tools make use of solvers in other ways to handle other
31+
problems. It is important to distinguish between goto-models,
32+
goto-programs, etc. which describe programs and have a semantics in
33+
terms of execution and formula that have a semantics in terms of
34+
logic. Solvers work with formulae and so have no notion of execution
35+
order, assignment, "before", branching, loops, exceptions,
36+
side-effects, function calls, etc. All of these have to be described
37+
in the formula presented to the decision procedure if you want to reason about them.
38+
39+
Other tools use solvers in different ways but the basic interface and
40+
ideas remain the same.
41+
42+
43+
\section solvers-interfaces Key Interfaces
44+
45+
The most basic interface is `decision_proceduret`. It gives the
46+
interface of all decision procedures. You call `set_to_true` and
47+
`set_to_false` to give the formulae and then `dec_solve` to check if
48+
they are satisfiable. If they are, it returns `D_SATISFIABLE` and you
49+
can use `get` to find the values in the satisfying assignment (if the
50+
underlying decision procedure supports this). If you are implementing
51+
a solver, then this is the most basic interface you have to support,
52+
if you are using the solver, this is the best interface to use as it
53+
does not commit you to any particular kind of solver. Looking at the
54+
inheritance diagram from `decision_proceduret` is a good way of
55+
getting an over-view of the solvers currently supported.
56+
57+
Many (but not all) decision procedures have a notion of logical
58+
expression and can provide information about logical expressions
59+
within the solver. `prop_convt` expands on the interface of
60+
`decision_proceduret` to add a data-type (`literalt`) and interfaces
61+
for manipulating logical expressions within the solver.
62+
63+
Within decision procedures it is common to reduce the logical
64+
expressions to equivalent expressions in a simpler language. This is
65+
similar to what a compiler will do in reducing higher-level language
66+
constructs to simple, assembler like instructions. This, of course,
67+
relies on having a decision procedure for the simpler language, just
68+
as a compiler relies on you having a processor that can handle the
69+
assembler. One of the popular choices of "processor" for decision
70+
procedures are SAT solvers. These handle a very restricted language
71+
in which all variables are simple Booleans and all formulae are just
72+
made of logical gates. By keeping their input simple, they can be
73+
made very fast and efficient; kind of like RISC processors. Like
74+
processors, creating a good SAT solver is a very specialised skill, so
75+
CPROVER uses third-party SAT solvers. By default this is MiniSAT, but
76+
others are supported (see the `sat/` directory). To do this it needs a
77+
software interface to a SAT solver : this is `propt`. It uses the
78+
same `literalt` to refer to Boolean variables, just as `prop_convt`
79+
uses them to refer to logical expressions. `land`, `lor`, `lxor` and
80+
so on allow gates to be constructed to express the formulae to be
81+
solved. If `cnf_handled_well` is true then you may also use `lcnf` to
82+
build formulae. Finally, `prop_solve` will run the decision procedure.
83+
84+
As previously mentioned, many decision procedures reduce formulae to
85+
CNF and solve with a SAT solver. `prop_conv_solvert` contains the
86+
foundations of this conversion. It implements the `prop_convt` by
87+
having an instance of `propt` (a SAT solver) and reducing the
88+
expressions that are input into CNF. The key entry point to this
89+
procedure is `prop_conv_solvert::convert` which then splits into
90+
`prop_conv_solvert::convert_boolean` (which
91+
uses `propt::land` and so on to convert Boolean expressions) and
92+
`prop_conv_solvert::convert_rest` which gives an error to start with.
93+
Various solvers inherit from `prop_conv_solvert` adding to `convert` and
94+
`convert_rest` to increase the language of expressions that can be
95+
converted. `equalityt` adds handling of equality between variables,
96+
`arrayst` then builds on that to add support for arrays, `boolbvt`
97+
adds bit-vector operations (plus, negate, multiply, shift, etc.) and
98+
finally `bv_pointers` adds pointers. This layering simplifies the
99+
conversion to CNF and allows parts of it to be over-ridden and
100+
modified (as `bv_refinementt` and `string_refinementt` do).
101+
102+
103+
\section solvers-directories Directories
104+
105+
* `prop/`: The interfaces above mostly live in `prop/`, which also
106+
contains a number of other supporting classes, like `literal.h`.
107+
108+
* `sat/`: All of the code for interacting and interfacing with SAT
109+
solvers. This is largely a 'leaf' directory and makes little use of
110+
external interfaces beyond things in `prop`. `cnf.h` contains
111+
`cnft` and `cnf_solvert` which give default implements `propt`s gate
112+
functions (`land`, `lxor`, etc.) in terms of `lcnf` as most modern
113+
SAT solvers only have interfaces for handling CNF, not logical
114+
gates. The various satcheck_* files implement the `propt`
115+
interfaces (generally with the `cnf_solvert` additions /
116+
simplifications) by connecting to various third-party SAT solvers.
117+
Finally `satcheck.h` use the build time flags to pick which SAT
118+
solvers are available and which should be used as default.
119+
120+
* `qbf/`: An equivalent of `sat/` for QBF solvers. These extend
121+
the basic language of SAT solvers with universal and existential
122+
quantification over Boolean variables. This makes the solvers more
123+
expressive but also slower. `qbf/` is not used by the main CPROVER
124+
tools and the solvers it integrates are somewhat dated.
125+
126+
* `flattening/`: A library that converts operations to bit-vectors,
33127
including calling the conversions in `floatbv` as necessary. Is
34128
implemented as a simple conversion (with caching) and then a
35-
post-processing function that adds extra constraints. This is not used
36-
by the SMT2 back-ends.
129+
post-processing function that adds extra constraints. The `boolbvt`
130+
solver uses these to express bit-vector operations via the `propt`
131+
interfaces. This is not used by the SMT2 back-ends.
37132

38133
* smt2/: Provides the `smt2_dect` type which converts the formulae to
39-
SMTLib 2 and then invokes one of Boolector, CVC3, CVC4, MathSAT, Yices or Z3.
134+
SMT-LIB 2 and then invokes one of Boolector, CVC3, CVC4, MathSAT, Yices or Z3.
40135
Note that the interaction with the solver is batched and uses
41136
temporary files rather than using the interactive command supported by
42-
SMTLib 2. With the `–fpa` option, this output mode will not flatten
43-
the floating point arithmetic and instead output the proposed SMTLib
44-
floating point standard.
137+
SMT-LIB 2. With the `–fpa` option, this output mode will not flatten
138+
the floating point arithmetic and instead output SMT-LIB floating point standard.
139+
140+
* `floatbv/`: This library contains the code that is used to
141+
convert floating point variables (`floatbv`) to bit vectors
142+
(`bv`). This is referred to as ‘bit-blasting’ and is called in the
143+
`solver` code during conversion to SAT or SMT. It also contains the
144+
abstraction code described in the FMCAD09 paper.
145+
146+
* `lowering/`: These are `exprt` to `exprt` reductions of operations
147+
rather than the `exprt` to `bvt` reductions in `flattening/`
148+
allowing them to be used in SMT solvers which do not inherit from
149+
`prop_conv_solvert`.
150+
151+
* `refinement/`: Solvers that build on the `bv_pointerst` solver
152+
interface and specialise the handling of certain operations to
153+
improve performance.
154+
155+
* `miniBDD/`: A canonical representation of Boolean formulae.
156+
45157

46-
* qbf/: Back-ends for a variety of QBF solvers. Appears to be no
47-
longer used or maintained.
48158

49-
* sat/: Back-ends for a variety of SAT solvers and DIMACS output.
50159

51160
\section flattening-section Flattening
52161

0 commit comments

Comments
 (0)