Skip to content

Commit 67c6303

Browse files
authored
Add a kani::any_value_where function to enable easy generation of constrained symbolic values (rust-lang#2103)
1 parent d1fb824 commit 67c6303

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

library/kani/src/lib.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,31 @@ pub fn any<T: Arbitrary>() -> T {
109109
T::any()
110110
}
111111

112+
/// This creates a symbolic *valid* value of type `T`.
113+
/// The value is constrained to be a value accepted by the predicate passed to the filter.
114+
/// You can assign the return value of this function to a variable that you want to make symbolic.
115+
/// The explanation field gives a mechanism to explain why the assumption is required for the proof.
116+
///
117+
/// # Example:
118+
///
119+
/// In the snippet below, we are verifying the behavior of the function `fn_under_verification`
120+
/// under all possible `NonZeroU8` input values between 0 and 12.
121+
///
122+
/// ```rust
123+
/// let inputA = kani::any_value_where::<std::num::NonZeroU8>(|x| *x < 12, "explanation");
124+
/// fn_under_verification(inputA);
125+
/// ```
126+
///
127+
/// Note: This is a safe construct and can only be used with types that implement the `Arbitrary`
128+
/// trait. The Arbitrary trait is used to build a symbolic value that represents all possible
129+
/// valid values for type `T`.
130+
#[inline(always)]
131+
pub fn any_value_where<T: Arbitrary, F: FnOnce(&T) -> bool>(f: F, _msg: &'static str) -> T {
132+
let result = T::any();
133+
assume(f(&result));
134+
result
135+
}
136+
112137
/// This function creates a symbolic value of type `T`. This may result in an invalid value.
113138
///
114139
/// # Safety

tests/kani/Assume/main.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,9 @@ fn main() {
77
kani::assume(i < 10);
88
assert!(i < 20);
99
}
10+
11+
#[kani::proof]
12+
fn verify_any_value_where() {
13+
let i: i32 = kani::any_value_where(|x| *x < 10, "Only single digit values are legal");
14+
assert!(i < 20);
15+
}

0 commit comments

Comments
 (0)