File tree 2 files changed +31
-0
lines changed 2 files changed +31
-0
lines changed Original file line number Diff line number Diff line change @@ -109,6 +109,31 @@ pub fn any<T: Arbitrary>() -> T {
109
109
T :: any ( )
110
110
}
111
111
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
+
112
137
/// This function creates a symbolic value of type `T`. This may result in an invalid value.
113
138
///
114
139
/// # Safety
Original file line number Diff line number Diff line change @@ -7,3 +7,9 @@ fn main() {
7
7
kani:: assume ( i < 10 ) ;
8
8
assert ! ( i < 20 ) ;
9
9
}
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
+ }
You can’t perform that action at this time.
0 commit comments