Skip to content

Commit 4e757bc

Browse files
authored
Add documentation for cover properties (rust-lang#2057)
1 parent 21a68d2 commit 4e757bc

File tree

2 files changed

+110
-0
lines changed

2 files changed

+110
-0
lines changed

docs/src/getting-started/verification-results/src/main.rs

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,4 +48,49 @@ fn unsupp(x: &mut u8) {
4848

4949
// ANCHOR_END: undetermined_example
5050

51+
#[kani::proof]
52+
// ANCHOR: cover_satisfied_example
53+
#[kani::unwind(256)]
54+
fn cover_satisfied_example() {
55+
let mut x: u8 = kani::any();
56+
let mut y: u8 = kani::any();
57+
y /= 2;
58+
let mut i = 0;
59+
while x != 0 && y != 0 {
60+
kani::cover!(i > 2 && x == 24 && y == 72);
61+
if x >= y { x -= y; }
62+
else { y -= x; }
63+
i += 1;
64+
}
65+
}
66+
// ANCHOR_END: cover_satisfied_example
67+
68+
#[kani::proof]
69+
// ANCHOR: cover_unsatisfiable_example
70+
#[kani::unwind(6)]
71+
fn cover_unsatisfiable_example() {
72+
let bytes: [u8; 5] = kani::any();
73+
let s = std::str::from_utf8(&bytes);
74+
if let Ok(s) = s {
75+
kani::cover!(s.chars().count() <= 1);
76+
}
77+
}
78+
// ANCHOR_END: cover_unsatisfiable_example
79+
80+
#[kani::proof]
81+
// ANCHOR: cover_unreachable_example
82+
#[kani::unwind(6)]
83+
fn cover_unreachable_example() {
84+
let r1: std::ops::Range<i32> = kani::any()..kani::any();
85+
let r2: std::ops::Range<i32> = kani::any()..kani::any();
86+
kani::assume(!r1.is_empty());
87+
kani::assume(!r2.is_empty());
88+
if r2.start > r1.end {
89+
if r2.end < r1.end {
90+
kani::cover!(r2.contains(&0));
91+
}
92+
}
93+
}
94+
// ANCHOR_END: cover_unreachable_example
95+
5196
fn main() {}

docs/src/verification-results.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,3 +94,68 @@ Check 2: undetermined_example.assertion.2
9494
- Status: UNDETERMINED
9595
- Description: "assertion failed: x == 0"
9696
```
97+
98+
## Cover property results
99+
100+
Kani provides a [`kani::cover`](https://model-checking.github.io/kani/crates/doc/kani/macro.cover.html) macro that can be used for checking whether a condition may occur at a certain point in the code.
101+
102+
The result of a cover property can be one of the following:
103+
104+
1. `SATISFIED`: This indicates that Kani found an execution that triggers the specified condition.
105+
106+
The following example uses `kani::cover` to check if it's possible for `x` and `y` to hold the values 24 and 72, respectively, after 3 iterations of the `while` loop, which turns out to be the case.
107+
```rust
108+
{{#include getting-started/verification-results/src/main.rs:cover_satisfied_example}}
109+
```
110+
Results:
111+
```
112+
Check 1: cover_satisfied_example.cover.1
113+
- Status: SATISFIED
114+
- Description: "cover condition: i > 2 && x == 24 && y == 72"
115+
- Location: src/main.rs:60:9 in function cover_satisfied_example
116+
```
117+
118+
2. `UNSATISFIABLE`: This indicates that Kani _proved_ that the specified condition is impossible.
119+
120+
The following example uses `kani::cover` to check if it's possible to have a UTF-8 encoded string consisting of 5 bytes that correspond to a string with a single character.
121+
```rust
122+
{{#include getting-started/verification-results/src/main.rs:cover_unsatisfiable_example}}
123+
```
124+
which is not possible as such string will contain at least two characters.
125+
```
126+
Check 46: cover_unsatisfiable_example.cover.1
127+
- Status: UNSATISFIABLE
128+
- Description: "cover condition: s.chars().count() <= 1"
129+
- Location: src/main.rs:75:9 in function cover_unsatisfiable_example
130+
```
131+
132+
3. `UNREACHABLE`: This indicates that the `cover` property itself is unreachable (i.e. it is _vacuously_ unsatisfiable).
133+
134+
In contrast to an `UNREACHABLE` result for assertions, an unreachable (or an unsatisfiable) cover property may indicate an incomplete proof.
135+
136+
Example:
137+
In this example, a `kani::cover` call is unreachable because if the outer `if` condition holds, then the non-empty range `r2` is strictly larger than the non-empty range `r1`, in which case, the condition in the inner `if` condition is impossible.
138+
```rust
139+
{{#include getting-started/verification-results/src/main.rs:cover_unreachable_example}}
140+
```
141+
```
142+
Check 3: cover_unreachable_example.cover.1
143+
- Status: UNREACHABLE
144+
- Description: "cover condition: r2.contains(&0)"
145+
- Location: src/main.rs:90:13 in function cover_unreachable_example
146+
```
147+
148+
4. `UNDETERMINED`: This is the same as the `UNDETERMINED` result for normal checks (see [check_results]).
149+
150+
## Verification summary
151+
152+
Kani reports a summary at the end of the verification report, which includes the overall results of all checks, the overall results of cover properties (if the package includes cover properties), and the overall verification result, e.g.:
153+
```
154+
SUMMARY:
155+
** 0 of 786 failed (41 unreachable)
156+
157+
** 0 of 1 cover properties satisfied
158+
159+
160+
VERIFICATION:- SUCCESSFUL
161+
```

0 commit comments

Comments
 (0)