-
Notifications
You must be signed in to change notification settings - Fork 98
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
Feature Request: Function Contracts #2652
Comments
Let's keep this open until stabilization. |
Hello, I have a couple of issues with function contracts. This is not about incorrect behavior, but about features that could improve Kani's integration into a codebase. Note: The examples in this post are simple on purpose. In practice, the use-cases are complex functions that need a contract and are used with Multiple contracts for the same functionLet's say I have a safe function fn foo<F: Fn(i32) -> i32>(f: &F) -> i32 {
f(0)
} The function #[requires(true)]
fn foo<F>(f: &F) -> i32
where
F: Fn(i32) -> i32,
{
f(0)
}
fn over_approximation(_:i32) -> i32 {
kani::any()
}
#[proof_for_contract(foo)]
fn check_safety_only() {
foo(&over_approximation);
} However, I also would like to express the correctness in the function contract as follows. #[ensures(|res: &i32| implies!(f(0) == 0 => *res == 0))]
fn foo<F>(f: &F) -> i32
where
F: Fn(i32) -> i32,
{
f(0)
}
#[proof_for_contract(foo)]
fn check_safety_and_correctness() {
foo(&over_approximation);
} But in this case, the harness with #[requires(true)]
fn foo<F>(f: &F) -> i32
where
F: Fn(i32) -> i32,
{
f(0)
}
#[requires(f(0) == 0)]
#[ensures(*res == 0)]
fn wraps_foo<F>(f: &F) -> i32
where
F: Fn(i32) -> i32,
{
f(0)
}
fn over_approximation(_:i32) -> i32 {
kani::any()
}
#[proof_for_contract(foo)]
fn check_safety_only() {
foo(&over_approximation);
}
#[proof_for_contract(wraps_foo)]
fn check_correctness_only() {
foo(&any_valid_f);
} However, this is not ideal, as I would also need to re-export the wrappers if users want to reuse the correctness contracts. A potential solution would be the possibility to have several contracts for the same function and annotate them (for instance using the same syntax as for loop annotations An additional feature would be to say that a contract Pre-conditions on a function with an
|
Hi @BusyBeaver-42. Thanks for the suggested features. For the first question, for the harness that checks safety, you can perhaps use #[kani::stub(f, over_approximation)]
#[kani::proof]
fn check_foo_safety() { ... } The harness that checks the correctness of For the second question:
Can you clarify why? For the third question, you can specify that |
I've updated my previous message, I had written it in a rush and it wasn't really clear. Here's what I modified:
About the first point, I did not think about stubbing the argument itself, that's clever! However, I think this does not really fit my use-case. It does work, but it does not really feel clean because I have several levels of nesting: About the former third point (now fourth), the problem is not about being within the same allocation (I had not included the
|
@BusyBeaver-42 would #3567 address the issue with specifying safety and correctness contracts? |
Thanks, @zhassan-aws , for pointing me to this issue. I actually needed something similar for another function. However, it does not address the issue of specifying safety and correctness contracts. The problem lies in the over-approximation I use to verify safety. While it satisfies the correctness pre-conditions, it does not satisfy the correctness post-conditions. This may seem nonsensical at first glance, but it is related to the point about function determinism in my first comment. One of the arguments of the function #[requires(safety_pre_conditions)]
#[ensures(implies!(correctness_pre_conditions => correctness_post_conditions))] Indeed, the safety check must be done with a non-deterministic |
By adding contracts support (requires/ensures/assigns/frees) to Kani we can unlock modular verification.
The RFC for Function Contracts is now live.
The text was updated successfully, but these errors were encountered: