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
Requested feature: Make proof harnesses optional, when possible
Use case: There are plenty of "boilerplate harnesses" that look something like this:
fnfoo(x:u8,y:u8){ ...}#[kani::proof]fnfoo_proof(){let x = kani::any();let y = kani::any();foo(x, y);}
There's nothing surprising in this harness--the user just creates arbitrary variables for each argument of the function they're verifying, and then calls the function. Ideally, the user shouldn't have to write this harness at all; Kani should detect that each of the arguments implements Arbitrary, then attempt to verify it automatically.
Tasks
(We define "standard harness" as a #[kani::proof] harness and a "contract harness" as a #[kani::proof_for_contract] harness).
I'll break these tasks down into subtasks as I start working, but a road map for now:
Autogenerate standard harnesses for types that already implement Arbitrary (either provided by Kani or implemented by the user)
Detect which functions have contracts and autogenerate contract harnesses for them.
Try to derive/implement Arbitrary for other types in the crate if doing so would allow us to verify more functions
Extend the harness autogeneration to support more complex use cases:
Types with invariants that the harnesses need to respect
Pointers
Loops
Generics
Open Questions
UI: Support error messages where we say which function caused the problem, rather than which harness, with which inputs. Also, print which functions we couldn't automatically verify, and support a --function filter to only autoverify certain functions.
How will this interplay with concrete playback?
Performance: If we try to verify everything that we can verify, it may take quite a long time.
Should we try to be more discerning about what we verify, e.g., introducing some kind of ordering (e.g., look for unsafe functions first, then safe abstractions?)
Should this feature have an automatic harness timeout, or perhaps an attribute you can put on a function to opt out of automatic verification?
Can we detect if a harness we'd autogenerate would duplicate a manually written harness, and if so, skip generating it?
Reasonable defaults: For types that do not trivially implement Arbitrary (e.g., pointers), we need to decide:
Do reasonable default values exist?
If so, what are they, and how do we communicate our default assumptions clearly so that users don't have a false sense of security if their code verifies?
Similarly, for code with loops, we can statically detect the presence of the loop, but most of the time we won't be able to statically determine an unwinding bound. So we need to decide if it's worth it to pick an arbitrary number, or just leave loops out of this for now.
The text was updated successfully, but these errors were encountered:
Note from #3874 -- Should log metadata about which functions were skipped, then print those functions in the driver, ideally with a note about why they were skipped.
This PR introduces an initial implementation for the `autoharness`
subcommand and a book chapter describing the feature. I recommend
reading the book chapter before reviewing the code (or proceeding
further in this PR description).
## Callouts
`--harness` is to manual harnesses what `--include-function` and
`--exclude-function` are to autoharness; both allow the user to filter
which harnesses/functions get verified. Their implementation is
different, however--`--harness` is a driver-only flag, i.e., we still
compile every harness, but then only call CBMC on the ones specified in
`--harness`. `--include-function` and `--exclude-function` get passed to
the compiler. I made this design choice to try to be more aggressive
about improving compiler performance--if a user only asks to verify one
function and we go try to codegen a thousand, the compiler will take
much longer than it needs to. I thought this more aggressive
optimization was warranted given that crates are likely to have far many
more functions eligible for autoverification than manual Kani harnesses.
(See also the limitations in the book chapter).
## Testing
Besides the new tests in this PR, I also ran against
[s2n-quic](https://github.com/aws/s2n-quic) to confirm that the
subcommand works on larger crates.
Towards #3832
By submitting this pull request, I confirm that my contribution is made
under the terms of the Apache 2.0 and MIT licenses.
Requested feature: Make proof harnesses optional, when possible
Use case: There are plenty of "boilerplate harnesses" that look something like this:
There's nothing surprising in this harness--the user just creates arbitrary variables for each argument of the function they're verifying, and then calls the function. Ideally, the user shouldn't have to write this harness at all; Kani should detect that each of the arguments implements
Arbitrary
, then attempt to verify it automatically.Tasks
(We define "standard harness" as a
#[kani::proof]
harness and a "contract harness" as a#[kani::proof_for_contract]
harness).I'll break these tasks down into subtasks as I start working, but a road map for now:
Arbitrary
(either provided by Kani or implemented by the user)Open Questions
UI: Support error messages where we say which function caused the problem, rather than which harness, with which inputs. Also, print which functions we couldn't automatically verify, and support a
--function
filter to only autoverify certain functions.How will this interplay with concrete playback?
Performance: If we try to verify everything that we can verify, it may take quite a long time.
Reasonable defaults: For types that do not trivially implement
Arbitrary
(e.g., pointers), we need to decide:Similarly, for code with loops, we can statically detect the presence of the loop, but most of the time we won't be able to statically determine an unwinding bound. So we need to decide if it's worth it to pick an arbitrary number, or just leave loops out of this for now.
The text was updated successfully, but these errors were encountered: