Skip to content

Commit 4d47855

Browse files
committed
add support for z3 probes
1 parent b8ea0c1 commit 4d47855

File tree

16 files changed

+391
-37
lines changed

16 files changed

+391
-37
lines changed

Cargo.lock

Lines changed: 31 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,6 @@ libtest-mimic = "0.8.1"
7676
name = "integration"
7777
path = "tests/integration.rs"
7878
harness = false
79-
80-
[profile.release]
8179
# Unfortunately, adding debug information to release binaries incurs
8280
# an unacceptable overhead of about 450 megabytes. So we disable it.
8381
# debug = "line-tables-only"

src/driver.rs

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,10 @@ use ariadne::ReportKind;
6060
use itertools::Itertools;
6161
use z3::{
6262
ast::{Ast, Bool},
63-
Config, Context,
63+
Config, Context, Goal,
6464
};
6565
use z3rro::{
66+
probes::ProbeSummary,
6667
prover::{ProveResult, Prover},
6768
smtlib::Smtlib,
6869
util::{PrefixWriter, ReasonUnknown},
@@ -696,6 +697,18 @@ impl<'ctx> SmtVcUnit<'ctx> {
696697

697698
let prover = mk_valid_query_prover(limits_ref, ctx, translate, &self.vc);
698699

700+
if options.debug_options.probe {
701+
let goal = Goal::new(ctx, false, false, false);
702+
for assertion in prover.solver().get_assertions() {
703+
goal.assert(&assertion);
704+
}
705+
eprintln!(
706+
"Probe results for {}:\n{}",
707+
name,
708+
ProbeSummary::probe(ctx, &goal)
709+
);
710+
}
711+
699712
let smtlib = get_smtlib(options, &prover);
700713
if let Some(smtlib) = &smtlib {
701714
write_smtlib(&options.debug_options, name, smtlib, None)?;

src/main.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,10 @@ pub struct DebugOptions {
370370
/// Enable Z3 tracing for the final SAT check.
371371
#[arg(long)]
372372
pub z3_trace: bool,
373+
374+
/// Run a bunch of probes on the SMT solver.
375+
#[arg(long)]
376+
pub probe: bool,
373377
}
374378

375379
#[derive(Debug, Default, Args)]
@@ -815,9 +819,10 @@ fn verify_files_main(
815819
// If `--no-verify` is set and we don't need to print SMT-LIB or explain the
816820
// core VC, we can return early.
817821
if options.debug_options.no_verify
822+
&& !options.lsp_options.explain_core_vc
823+
&& !options.debug_options.probe
818824
&& !options.debug_options.print_smt
819825
&& options.debug_options.smt_dir.is_none()
820-
&& !options.lsp_options.explain_core_vc
821826
{
822827
return Ok(true);
823828
}

src/vc/subst.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ impl<'a> VisitorMut for Subst<'a> {
120120
///
121121
/// As said in the module description [`crate::vc::subst`], this is the "strict"
122122
/// and simpler version of the [`crate::opt::unfolder`].
123-
#[instrument(skip(tcx, e))]
123+
#[instrument(skip_all)]
124124
pub fn apply_subst(tcx: &TyCtx, e: &mut Expr, limits_ref: &LimitsRef) -> Result<(), LimitError> {
125125
let mut subst = Subst::new(tcx, limits_ref);
126126
subst.visit_expr(e)

website/docs/caesar/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Set a memory limit of 16000 megabytes with `--mem 16000`.
4444
* With the `--print-theorem` flag, Caesar prints the theorem that is encoded into SMT.
4545
* With the `--print-smt` flag, Caesar prints the SMT-LIB query for each verification task. You can also use `--smt-dir DIR` with a directory `DIR` to have Caesar write the SMT-LIB queries to files in `DIR`.
4646
* If [`raco read`](https://docs.racket-lang.org/raco/read.html) is installed, Caesar will auto-format the SMT-LIB code with it. This is very useful as Z3's default formatting is really confusing sometimes.
47+
* With the `--probe` flag, [Caesar will print information from Z3 probes](./debugging.md#z3-probes) to standard error.
4748

4849
## More Topics
4950

website/docs/caesar/benchmarks.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
sidebar_position: 4
2+
sidebar_position: 5
33
---
44

55
# Benchmarks

website/docs/caesar/debugging.md

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,60 @@
11
---
2-
sidebar_position: 5
2+
sidebar_position: 1
33
---
44

55
# Debugging
66

7-
TODO.
7+
Follow this guide if you are debugging verification with Caesar.
8+
9+
10+
## SMT Theories and Incompleteness {#incompleteness}
11+
12+
[Expressions](../heyvl/expressions.md) are the main reason for *incompleteness* of Caesar, i.e. instances Caesar is unable to decide whether a given HeyVL program verifies or not.
13+
Caesar's incompleteness comes from incompleteness of the underlying SMT solver which is used to prove or disprove verification.
14+
15+
At the moment, Caesar's translation of HeyVL verification problems is rather direct: most expressions are translated as one would intuitively expect.
16+
If operators have a direct correspondence in [SMT-LIB](https://smt-lib.org/), then we translate directly to those.
17+
Otherwise, usually only additional simple case distinctions are introduced.
18+
We have some more explanations in [Section 5 of our paper on HeyVL](https://arxiv.org/pdf/2309.07781#page=23).
19+
20+
As a consequence, it is usually pretty simple to predict which [SMT-LIB theories](https://smt-lib.org/theories.shtml) will be used for the SMT query done by Caesar.
21+
[Caesar supports Z3 probes](#z3-probes) to help you check in which theory your problem falls.
22+
Also refer to the [Z3 documentation on arithmetic theories](https://microsoft.github.io/z3guide/docs/theories/Arithmetic/), since a lot of Caesar's reasoning will need arithmetic.
23+
24+
Here are some rules of thumb for (in-)completeness:
25+
* Linear integer and real arithmetic (QF_LRA, QF_LIRA) is decidable.
26+
* Nonlinear integer arithmetic (QF_NIA) is undecidable.
27+
* Nonlinear real arithmetic (QF_NRA) is decidable for algebraic reals.
28+
* Quantifiers usually introduce undecidability, although there are [a bunch of strategies and fragments in Z3 that allow decidability](https://microsoft.github.io/z3guide/docs/logic/Quantifiers#model-based-quantifier-instantiation).
29+
* In particular, restrictive [quantifier triggers](../heyvl/expressions.md#triggers) can help e-matching prove many instances.
30+
* HeyVL's [quantitative quantifiers](../heyvl/expressions.md#quantifiers) (`inf` and `sup`) currently have a very naive default encoding that is problematic for Z3. If the quantitative quantifiers cannot be eliminated by Caesar's quantifier elimination (QE) procedure, then they are often a cause of nontermination of Caesar.
31+
* Quantitative quantifiers also come from the semantics of [`havoc` and `cohavoc`](../heyvl/statements.md#havoc). However, for e.g. the [induction-based proof rules](../proof-rules/induction.md), the HeyVL encodings fall into a fragment where Caesar's QE applies and the generated quantifiers are eliminated.
32+
* In practice, the SMT solver can often *prove* correctness, but it often has problems with *refutations* (i.e. providing counter-examples).
33+
34+
35+
### Z3 Probes
36+
37+
Caesar supports the use of [Z3's *probes*](https://microsoft.github.io/z3guide/docs/strategies/probes/) to quickly help you determine performance-relevant properties about the SMT query, such as the presence of quantifiers or the theoretical complexity of the problem.
38+
39+
Run Caesar with the `--probe` flag to enable probes.
40+
Caesar will print an output of the following form to standard error:
41+
42+
```
43+
Probe results for test.heyvl::test:
44+
Has quantifiers: false
45+
Detected theories: NIRA
46+
- complexity: Undecidable
47+
- rejected theories: LRA, LIA, LIRA, NRA, NIA
48+
Number of arithmetic constants: 1
49+
Number of Boolean constants: 4
50+
Number of bit-vector constants: 0
51+
Number of constants: 1
52+
Number of expressions: 71
53+
```
54+
55+
The tool also tries to compute the complexity class of the problem to help you determine whether a problem is "easy".
56+
57+
## Further Reading
58+
59+
* [Dafny's guidelines for verification](https://dafny.org/dafny/DafnyRef/DafnyRef.html#sec-verification) can be helpful.
60+
Many of the ideas translate pretty much directly to Caesar.

website/docs/caesar/optimizations.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
sidebar_position: 3
2+
sidebar_position: 4
33
---
44

55
# Optimizations & Alternative Implementations

website/docs/caesar/slicing.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
sidebar_position: 2
2+
sidebar_position: 3
33
description: Caesar supports program slicing on the HeyVL intermediate verification language.
44
---
55

0 commit comments

Comments
 (0)