Skip to content
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

Chore: Fine-tuning verification and compilation performance #5028

Merged
merged 4 commits into from
Jan 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docs/DafnyRef/integration-java/IntegrationJava.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,6 @@ Often this requires defining a Dafny class that corresponds to the Java class.
the Dafny-generated (Java) types and the types used in the desired method.
The wrapper will do appropriate conversions and call the desired method.

## Performance notes

If you have the choice, given a `m: map<K, V>`, prefer iterating over the map itself like `forall k <- m` rather than over the keys `forall k <- m.Keys`. The latter currently results in `O(N²)` steps, whereas the first one remains linear.
21 changes: 21 additions & 0 deletions docs/VerificationOptimization/VerificationOptimization.md
Original file line number Diff line number Diff line change
Expand Up @@ -608,6 +608,27 @@ As a general rule, designing a program from the start so that it can be broken i

* Break methods up into smaller pieces, as well. Because methods are always opaque, this will, in many cases, require adding a contract to each broken-out method. To make this more tractable, consider abstracting the concepts used in those contracts into separate functions, some of which may be opaque.

# Verification fine-tuning

## Conjunction vs. Nested ifs

We have witnessed cases where the following code:
```dafny
if (a && b) {
assert true;
}
```
verifies slower than
```dafny
if (a) {
if (b) {
assert true;
}
}
```
This is because the well-formedness of `&& b` adds an extra proof obligation, which is empty in this case but not trimmed, so there is an extra `if (a) {}` in the encoding.
Therefore, for verification performance, the nested ifs _could_ verify faster, and we have witnessed one case where it does. In other cases, this difference in translation might trigger butterfly effects and uncover brittleness.

# Summary

When you're dealing with a program that exhibits high verification variability, or simply slow or unsuccessful verification, careful encapsulation and information hiding combined with hints to add information in the context of difficult constructs is frequently the best solution. Breaking one large definition with extensive contracts down into several, smaller definitions, each with simpler contracts, can be very valuable. Within each smaller definition, a few internal, locally-encapsulated hints can help the prover make effective progress on goals it might be unable to prove in conjunction with other code.
Expand Down
Loading