-
Notifications
You must be signed in to change notification settings - Fork 274
Incremental smt2 backend documentation #7363
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
thomasspriggs
merged 1 commit into
diffblue:develop
from
esteffin:esteffin/incr-smt2-backend-documentation
Nov 30, 2022
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
[CPROVER Manual TOC](../) | ||
|
||
## SMT 2 incremental backend | ||
|
||
CBMC supports many different smt solver backends. This document describes how to use the incremental | ||
smt2 solver. For other solver usages use `cbmc --help`. | ||
|
||
The incremental smt2 solver backend of CBMC is a solver-agnostic smt backend that allows the user to | ||
specify which smtlib 2.6 compliant solver CBMC should use. This choice increases the flexibility of | ||
CBMC as the user can easily switch solver at runtime also allowing custom parametrization of the | ||
solver to be used. Further, the backend exploits the incremental mode of the smt solver, so | ||
subsequent incremental SMT solver queries do not require a full re-evaluation of the entire SMT | ||
formula. | ||
|
||
### Supported features | ||
|
||
The incremental smt2 solver supports the following CBMC C features: | ||
|
||
* Integral types (including integers, characters and boolean). These are encoded into smt by using | ||
bit-vectors, | ||
* Pointers. Encoded by using smt bit-vectors. This includes support for pointers to both stack and | ||
heap-allocated memory, | ||
* Arrays. Encoded by using smt array theory. | ||
|
||
Currently, unsupported features include floating-point types, structs and unions. | ||
|
||
For more details on which features are supported see regression | ||
tests in [`regression/cbmc-incr-smt2`](../regression/cbmc-incr-smt2). | ||
|
||
The backend has been tested with these instrumentation passes: | ||
|
||
* `--bounds-check`, | ||
* `--conversion-check`, | ||
* `--div-by-zero-check`, | ||
* `--pointer-check`, | ||
* `--pointer-overflow-check`, | ||
* `--signed-overflow-check`, | ||
* `--unsigned-overflow-check`, | ||
* `--unwinding-assertions`. | ||
|
||
### Requisites | ||
|
||
To run the incremental smt2 backend it is necessary to have an smt solver that: | ||
|
||
* is runnable from the command line, | ||
* supports interactive mode from the command line, | ||
* supports smtlib 2.6 input, | ||
* supports incremental mode. | ||
|
||
Because of the way supported features are encoded the smt solver should be capable to handle arrays, | ||
bit-vectors, uninterpreted functions and quantifiers. Also, the solver should work with the `ALL` | ||
smt theory. | ||
|
||
At the time of writing the smt solvers tested in CI | ||
are [Z3](https://github.com/Z3Prover/z3) | ||
and [CVC5](https://cvc5.github.io/). | ||
|
||
### Usage | ||
|
||
To use the incremental SMT2 backend it is enough to add the `--incremental-smt2-solver` argument to | ||
the CBMC command line followed by the command to invoke the chosen solver using smtlib 2.6 input in | ||
interactive mode. | ||
|
||
Note that the use of the `--slice-formula` option is recommended at this time to slice out | ||
unnecessary code (that may not be supported at the moment) and this can also improve performance. | ||
|
||
Here are two examples to show how to analyse a file `program.c` using Z3 and CVC5 solvers. | ||
|
||
To use the Z3 SMT solver: | ||
|
||
```shell | ||
cbmc --slice-formula --incremental-smt2-solver 'z3 -smt2 -in' program.c | ||
``` | ||
|
||
If `z3` is not on the `PATH`, then it is enough to replace `'z3 -smt2 -in'` | ||
with `'<command-to-execute-z3> -smt2 -in'`, | ||
|
||
Similarly to execute CBMC using the CVC5 solver: | ||
|
||
```shell | ||
cbmc --slice-formula --incremental-smt2-solver 'cvc5 --lang=smtlib2.6 --incremental' program.c | ||
``` | ||
|
||
As the command to execute the solver is left to the user, it is possible to fine-tune it by passing | ||
extra parameters (when the solver allows so). For example Z3 allows to set certain parameters by | ||
adding `param_name=value` to the command line, so to use the Z3 solver with `well_sorted_check` | ||
property set to `false` the following has to be run: | ||
|
||
```shell | ||
cbmc --slice-formula --incremental-smt2-solver 'z3 -smt2 -in well_sorted_check=false' program.c | ||
``` | ||
|
||
### Examples | ||
|
||
Given a C program `program.c` as follows: | ||
|
||
```C | ||
int main() | ||
{ | ||
int x, y; | ||
if(x != 0) | ||
__CPROVER_assert(y != 4, "Assert of inequality to 4."); | ||
else | ||
__CPROVER_assert(y != 2, "Assert of inequality to 2."); | ||
int z = y; | ||
return 0; | ||
} | ||
``` | ||
|
||
To analyze it we should run: | ||
|
||
```shell | ||
cbmc --incremental-smt2-solver 'z3 -smt2 -in' --slice-formula program.c | ||
``` | ||
|
||
We will get the verification results as follows: | ||
|
||
```text | ||
CBMC version 5.70.0 (cbmc-5.70.0-53-g20535ad14d) 64-bit x86_64 macos | ||
Parsing program.c | ||
Converting | ||
Type-checking program | ||
Generating GOTO Program | ||
Adding CPROVER library (x86_64) | ||
Removal of function pointers and virtual functions | ||
Generic Property Instrumentation | ||
Running with 8 object bits, 56 offset bits (default) | ||
Starting Bounded Model Checking | ||
Runtime Symex: 0.00168879s | ||
size of program expression: 45 steps | ||
slicing removed 23 assignments | ||
Generated 2 VCC(s), 2 remaining after simplification | ||
Runtime Postprocess Equation: 2.1865e-05s | ||
Passing problem to incremental SMT2 solving via "z3 -smt2 -in" | ||
``` | ||
|
||
Note here that the solver used by CBMC is `"z3 -smt2 -in"` as specified by the user. | ||
|
||
```text | ||
[continues] | ||
converting SSA | ||
Runtime Convert SSA: 0.00130809s | ||
Running incremental SMT2 solving via "z3 -smt2 -in" | ||
Runtime Solver: 0.0738685s | ||
Runtime decision procedure: 0.0765297s | ||
Running incremental SMT2 solving via "z3 -smt2 -in" | ||
Runtime Solver: 0.00535358s | ||
Runtime decision procedure: 0.00570765s | ||
|
||
** Results: | ||
program.c function main | ||
[main.assertion.1] line 5 Assert of inequality to 4.: FAILURE | ||
[main.assertion.2] line 7 Assert of inequality to 2.: FAILURE | ||
|
||
** 2 of 2 failed (3 iterations) | ||
VERIFICATION FAILED | ||
``` | ||
|
||
As expected CBMC returns `FAILURE` for both assertions at lines `5` and `7`. | ||
|
||
The incremental smt2 backend also supports trace generation, so to get a trace that fails the | ||
assertions the `--trace` argument should be added, so the command to run is: | ||
|
||
```shell | ||
cbmc --incremental-smt2-solver 'z3 -smt2 -in' --slice-formula --trace program.c | ||
``` | ||
|
||
This will append the trace to CBMC's output as follows: | ||
|
||
```text | ||
CBMC version 5.70.0 (cbmc-5.70.0-53-g20535ad14d) 64-bit x86_64 macos | ||
Parsing program.c | ||
[...] | ||
[main.assertion.1] line 5 Assert of inequality to 4.: FAILURE | ||
[main.assertion.2] line 7 Assert of inequality to 2.: FAILURE | ||
|
||
Trace for main.assertion.1: | ||
|
||
State 6 file program.c function main line 3 thread 0 | ||
---------------------------------------------------- | ||
x=-1 (11111111 11111111 11111111 11111111) | ||
|
||
State 7 file program.c function main line 3 thread 0 | ||
---------------------------------------------------- | ||
y=4 (00000000 00000000 00000000 00000100) | ||
|
||
Violated property: | ||
file program.c function main line 5 thread 0 | ||
Assert of inequality to 4. | ||
y != 4 | ||
|
||
|
||
|
||
Trace for main.assertion.2: | ||
|
||
State 6 file program.c function main line 3 thread 0 | ||
---------------------------------------------------- | ||
x=0 (00000000 00000000 00000000 00000000) | ||
|
||
State 7 file program.c function main line 3 thread 0 | ||
---------------------------------------------------- | ||
y=2 (00000000 00000000 00000000 00000010) | ||
|
||
Violated property: | ||
file program.c function main line 7 thread 0 | ||
Assert of inequality to 2. | ||
y != 2 | ||
|
||
|
||
|
||
** 2 of 2 failed (3 iterations) | ||
VERIFICATION FAILED | ||
``` |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leaving it up to @kroening to make a call here, for he maintains the rendered version of this documentation. My own view is that we should not discuss a particular solver as part of this manual.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I consider the "official" documentation now to be automatically rendered here: https://diffblue.github.io/cbmc/ Is that not the case? Will that not be the case for this file?
Where would you propose we discuss things specific to a particular solver?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree that this one (github.io) is the right place; it will also include the CPROVER manual (which is otherwise rendered on cprover.org), but isn't limited to that manual.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can confirm that if I checkout and build the documentation locally as will be done on the documentation publishing job, then this new documentation will be included. Therefore it should be uploaded to the github.io page by github actions after this PR is merged.
The links to follow to find it will be -
I think this is the right place to add this documentation. Most information about the SAT solvers for instance wouldn't belong here, because they are compile/link time swappable not run-time swappable. However I think this list started by Enrico could be the right place to add documentation of the the dimacs file and external sat solver support, when someone takes the time to write it.