|
1 | 1 | # Incremental SMT backend
|
2 | 2 |
|
| 3 | +## General usage |
| 4 | + |
3 | 5 | CBMC comes with a solver-agnostic incremental SMT backend.
|
4 | 6 |
|
5 | 7 | The SMT incremental backend supports the following `C` features:
|
@@ -40,3 +42,60 @@ removed from the formula to be converted.
|
40 | 42 |
|
41 | 43 | As we move forward with our array-support implementation, we anticipate that the
|
42 | 44 | 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. |
0 commit comments