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/tutorial-nondeterministic-variables.md
+8-5Lines changed: 8 additions & 5 deletions
Original file line number
Diff line number
Diff line change
@@ -6,7 +6,10 @@ Since Kani is a bit-level model checker, this means that Kani considers that an
6
6
As a Rust developer, this sounds a lot like the `mem::transmute` operation, which is highly `unsafe`.
7
7
And that's correct.
8
8
9
-
In this tutorial, we will show how to safely use nondeterministic assignments to generate valid symbolic variables that respect Rust's type invariants, as well as show how you can specify invariants for types that you define enabling creation of safe nondeterministic variables for those types.
9
+
In this tutorial, we will show how to:
10
+
1. Safely use nondeterministic assignments to generate valid symbolic variables that respect Rust's type invariants.
11
+
2. Unsafely use nondeterministic assignments to generate unconstrained symbolic variables that do not respect Rust's type invariants.
12
+
2. Specify invariants for types that you define, enabling the creation of safe nondeterministic variables for those types.
10
13
11
14
## Safe nondeterministic variables
12
15
@@ -17,13 +20,13 @@ Here is a simple implementation of this API:
Now we would like to verify that no matter which combination of `id` and `quantity`, that a call to `Inventory::update()` followed by a call to `Inventory::get()` using the same id returns some value that is equal to the one we inserted:
23
+
Now we would like to verify that, no matter which combination of `id` and `quantity`, a call to `Inventory::update()` followed by a call to `Inventory::get()` using the same `id` returns some value that is equal to the one we inserted:
In this harness, we use`kani::any()` to generate `ProductId` and the new quantity.
29
+
In this harness, we use`kani::any()` to generate the new `id` and `quantity`.
27
30
`kani::any()` is a **safe** API function, and it represents only valid values.
28
31
29
32
If we run this example, Kani verification will succeed, including the assertion that shows that the underlying `u32` variable used to represent `NonZeroU32` cannot be zero, per its type invariant:
Kani also includes an **unsafe** method to generate unconstrained nondeterministic variables which do not take type invariants into consideration.
41
-
As any unsafe method in rust, users must be careful when using unsafe methods and ensure the right guardrails are put in place to avoid undesirable behavior.
44
+
As with any unsafe method in Rust, users have to make sure the right guardrails are put in place to avoid undesirable behavior.
42
45
43
46
That said, there may be cases where you want to verify your code taking into consideration that some inputs may contain invalid data.
44
47
@@ -49,7 +52,7 @@ Let's see what happens if we modify our verification harness to use the unsafe m
49
52
```
50
53
51
54
We commented out the assertion that the underlying `u32` variable cannot be `0`, since this no longer holds.
52
-
The Kani verification will now fail showing that `inventory.get(&id).unwrap()` method call can panic.
55
+
The verification will now fail showing that the`inventory.get(&id).unwrap()` method call can panic.
53
56
54
57
This is an interesting issue that emerges from how `rustc` optimizes the memory layout of `Option<NonZeroU32>`.
55
58
The compiler is able to represent `Option<NonZeroU32>` using `32` bits by using the value `0` to represent `None`.
0 commit comments