Skip to content

Commit 97a7dcd

Browse files
Merge pull request #7132 from thomasspriggs/tas/more_smt_docs
Add documentation of the structure of the SMT incremental decision procedure
2 parents 8a09391 + 9a14d1a commit 97a7dcd

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

src/solvers/smt2_incremental/README.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# Incremental SMT backend
22

3+
## General usage
4+
35
CBMC comes with a solver-agnostic incremental SMT backend.
46

57
The SMT incremental backend supports the following `C` features:
@@ -40,3 +42,60 @@ removed from the formula to be converted.
4042

4143
As we move forward with our array-support implementation, we anticipate that the
4244
need for this extra flag will be diminished.
45+
46+
## Internal code architecture
47+
48+
### Overview of the sequence of data processing and data flow -
49+
50+
1. Other parts of the cbmc code base send `exprt` based expressions to the
51+
decision procedure through the `handle`, `set_to` and `get` member functions.
52+
See the base class `decision_proceduret` for doxygen of these functions.
53+
54+
2. The `smt2_incremental_decision_proceduret` is responsible for holding state
55+
and building commands to send to the solver. It uses `convert_expr_to_smt` for
56+
the state free (pure) portion of the `exprt` to `termt` conversions.
57+
58+
3. `smt2_incremental_decision_proceduret` sends `smt_commandt` to
59+
`smt_piped_solver_processt`. Although `exprt` is broadly equivalent to `termt`,
60+
the terms must be part of a command giving them a broader meaning before they
61+
are sent to the solver.
62+
63+
4. `smt_piped_solver_processt` uses the `smt_to_smt2_string` function to perform
64+
the conversion from the tree structure of the `smt_commandt` into the linear
65+
structure of the string for sending to the solver.
66+
67+
5. `smt_piped_solver_processt` sends `std::string` to `piped_processt`.
68+
69+
6. `piped_processt` has operating system specific implementations which use
70+
POSIX / Windows API calls to send the strings to the solver process via a pipe.
71+
Note that the solver is kept in a operating system separated process, not a
72+
thread. This supports multiprocessing with the solver ingesting commands whilst
73+
the cbmc process continues symex to generate the following commands.
74+
75+
7. `piped_processt` receives output strings from the solver process using OS API
76+
calls and a buffer, when the `smt_piped_solver_processt` requests them.
77+
78+
8. The response strings returned to `smt_solve_processt` are converted into type
79+
less parse trees in the form of raw `irept`s using `smt2irep`. `smt2irep` is
80+
essentially just an S-expression parser.
81+
82+
9. `smt_piped_solver_processt` uses `validate_smt_response` to convert the
83+
`irept` parse tree into either a set of validation errors or a `smt_responset`.
84+
The case of validation errors is considered to be an error with the solver.
85+
Therefore an exception may be thrown for use as user feedback rather than
86+
violating an `INVARIANT` as would be the case for an internal cbmc error.
87+
88+
10. The well sorted `smt_reponset` is then returned to the
89+
`smt2_incremental_decision_proceduret`.
90+
91+
11. In the case of `smt2_incremental_decision_proceduret::get` the response is
92+
expected to be an `smt_get_value_responset`. The decision procedure uses
93+
`construct_value_expr_from_smt` to convert the value term in the response from
94+
the solver into an expression value. This requires information from the decision
95+
procedure about the kind of type the constructed expression should have. The
96+
reason for this is that the smt formula (although well sorted) does not encode
97+
cbmc's notion of types and a given value in SMT terms could correspond to
98+
multiple different types of cbmc expression.
99+
100+
12. The constructed expression can then be returned to the rest of the cbmc code
101+
base outside the decision procedure.

src/solvers/smt2_incremental/smt2_incremental_decision_procedure.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,13 @@ class smt2_incremental_decision_proceduret final
138138
/// array expressions when support for them is implemented.
139139
std::unordered_map<exprt, smt_identifier_termt, irep_hash>
140140
expression_identifiers;
141+
/// This maps from the unsorted/untyped string/symbol for the identifiers
142+
/// which we have declared in SMT solver to the corresponding sorted/typed
143+
/// `smt_identifier_termt`. This enables type checking the parse trees of
144+
/// responses received back from the solver. It is required because without
145+
/// the definitive sorts we would need to attempt to infer the sorts of
146+
/// identifiers from the surrounding terms which would be a looser check with
147+
/// a more complex implementation.
141148
std::unordered_map<irep_idt, smt_identifier_termt> identifier_table;
142149
/// This map is used to track object related state. See documentation in
143150
/// object_tracking.h for details.

0 commit comments

Comments
 (0)