You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/src/reference/experimental/autoharness.md
+42-7Lines changed: 42 additions & 7 deletions
Original file line number
Diff line number
Diff line change
@@ -8,18 +8,18 @@ Recall the harness for `estimate_size` that we wrote in [First Steps](../../tuto
8
8
This harness first declares a local variable `x` using `kani::any()`, then calls `estimate_size` with argument `x`.
9
9
Many proof harnesses follow this predictable format—to verify a function `foo`, we create arbitrary values for each of `foo`'s arguments, then call `foo` on those arguments.
10
10
11
-
The `autoharness` subcommand leverages this observation to automatically generate and run harnesses.
11
+
The `autoharness` subcommand leverages this observation to automatically generate harnesses and run Kani against them.
12
12
Kani scans the crate for functions whose arguments all implement the `kani::Arbitrary` trait, generates harnesses for them, then runs them.
13
-
These harnesses are internal to Kani--i.e., Kani does not make any changes to your source code.
13
+
These harnesses are internal to Kani—i.e., Kani does not make any changes to your source code.
14
14
15
15
## Usage
16
16
Run either:
17
17
```
18
-
# cargo kani autoharness -Z unstable-options
18
+
# cargo kani autoharness -Z autoharness
19
19
```
20
20
or
21
21
```
22
-
# kani autoharness -Z unstable-options <FILE>
22
+
# kani autoharness -Z autoharness <FILE>
23
23
```
24
24
25
25
If Kani detects that all of a function `foo`'s arguments implement `kani::Arbitrary`, it will generate and run a `#[kani::proof]` harness, which prints:
@@ -42,11 +42,11 @@ These flags look for partial matches against the fully qualified name of a funct
42
42
43
43
For example, if a module `my_module` has many functions, but we are only interested in `my_module::foo` and `my_module::bar`, we can run:
44
44
```
45
-
cargo run autoharness -Z unstable-options --include-function foo include-function bar
45
+
cargo run autoharness -Z autoharness --include-function foo --include-function bar
46
46
```
47
47
To exclude `my_module` entirely, run:
48
48
```
49
-
cargo run autoharness -Z unstable-options --exclude-function my_module
49
+
cargo run autoharness -Z autoharness --exclude-function my_module
50
50
```
51
51
52
52
## Example
@@ -58,7 +58,7 @@ Using the `estimate_size` example from [First Steps](../../tutorial-first-steps.
58
58
We get:
59
59
60
60
```
61
-
# cargo kani autoharness -Z unstable-options
61
+
# cargo kani autoharness -Z autoharness
62
62
Autoharness: Checking function estimate_size against all possible inputs...
63
63
RESULTS:
64
64
Check 3: estimate_size.assertion.1
@@ -76,9 +76,44 @@ If you have ideas for improving the user experience of this feature,
76
76
please add them to [this GitHub issue](https://github.com/model-checking/kani/issues/3832).
77
77
78
78
## Limitations
79
+
### Arguments Implementing Arbitrary
79
80
Kani will only generate an automatic harness for a function if it can determine that all of the function's arguments implement Arbitrary.
80
81
It does not attempt to derive/implement Arbitrary for any types, even if those types could implement Arbitrary.
82
+
For example, imagine a user defines `struct MyStruct { x: u8, y: u8}`, but does not derive or implement Arbitrary for `MyStruct`.
83
+
Kani does not attempt to add such derivations itself, so it will not generate a harness for a function that takes `MyStruct` as input.
81
84
85
+
### Generic Functions
86
+
The current implementation does not generate harnesses for generic functions.
87
+
For example, given:
88
+
```rust
89
+
fnfoo<T:Eq>(x:T, y:T) {
90
+
ifx==y {
91
+
panic!("x and y are equal");
92
+
}
93
+
}
94
+
```
95
+
Kani would report that no functions were eligible for automatic harness generation.
96
+
97
+
If, however, some caller of `foo` is eligible for an automatic harness, then a monomorphized version of `foo` may still be reachable during verification.
98
+
For instance, if we add `main`:
99
+
```rust
100
+
fnmain() {
101
+
letx:u8=2;
102
+
lety:u8=2;
103
+
foo(x, y);
104
+
}
105
+
```
106
+
and run the autoharness subcommand, we get:
107
+
```
108
+
Autoharness: Checking function main against all possible inputs...
109
+
110
+
Failed Checks: x and y are equal
111
+
File: "src/lib.rs", line 3, in foo::<u8>
112
+
113
+
VERIFICATION:- FAILED
114
+
```
115
+
116
+
### Loop Contracts
82
117
If a function contains a loop with a loop contract, Kani will detect the presence of a loop contract and verify that contract.
83
118
If, however, the loop does not have a contract, then there is currently no way to specify an unwinding bound for the function, meaning that Kani may hang as it tries to unwind the loop.
84
119
We recommend using the `--exclude-function` option to exclude any functions that have this issue (or `--harness-timeout` to bail after attempting verification for some amount of time).
0 commit comments