-
Notifications
You must be signed in to change notification settings - Fork 81
/
Copy pathtrigger_loops.rs
113 lines (98 loc) · 2.44 KB
/
trigger_loops.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
// rust_verify/tests/example.rs ignore --- these examples are expected to timeout to test the quantifier profiler (i.e., exceed their rlimit)
#[allow(unused_imports)]
use builtin::*;
use builtin_macros::*;
use vstd::{pervasive::*, *};
verus! {
// ANCHOR: def_f_g
spec fn f(x: nat, y: nat) -> bool;
spec fn g(x: nat) -> bool;
spec fn h(x: nat, y: nat) -> bool;
// ANCHOR_END: def_f_g
spec fn j(x: nat) -> bool;
proof fn quantifier_example()
requires
forall|x| g(x),
ensures
exists|y| g(y),
{
let w = choose|z| g(z);
assert(g(w));
}
proof fn choose_example()
requires
exists|x| g(x),
{
let z = choose|y| g(y);
assert(g(z));
}
proof fn cost_example()
requires
f(1, 2),
forall|x, y| #[trigger] f(x, y) <==> g(x) && g(y),
forall|z| #[trigger] g(z) == j(z + 2),
{
assert(j(3) && j(4));
}
proof fn cost_example2()
requires
g(1),
g(2),
forall|x, y| f(x, y) <==> #[trigger] g(x) && #[trigger] g(y),
forall|z| #[trigger] g(z) == j(z + 2),
{
assert(j(3) && j(4));
}
proof fn trigger_forever()
requires
forall|x: nat, y: nat| f(x + 1, 2 * y) && f(2 * x, y + x) || f(y, x) ==> #[trigger] f(x, y),
ensures
forall|x: nat, y: nat| x > 2318 && y < 100 ==> f(x, y),
{
}
// Split the triggering over two different quantifiers
// ANCHOR: trigger_forever2
proof fn trigger_forever2()
requires
forall|x: nat| g(x),
forall|x: nat, y: nat| h(x, y) == f(x, y),
forall|x: nat, y: nat| f(x + 1, 2 * y) && f(2 * x, y + x) || f(y, x) ==> #[trigger] f(x, y),
ensures
forall|x: nat, y: nat| x > 2318 && y < 100 ==> h(x, y),
{
assert(g(4));
}
// ANCHOR_END: trigger_forever2
fn simple_loop()
ensures
forall|x| 0 <= x < 10 ==> g(x),
{
let mut x: u32 = 0;
while x < 10
invariant
0 <= x <= 10,
forall|i: u32| 0 <= i < x ==> g(i as nat),
//decreases x;
{
assume(g(x as nat));
x = x + 1;
}
}
fn bad_loop()
requires
forall|x: nat, y: nat| f(x + 1, 2 * y) && f(2 * x, y + x) || f(y, x) ==> #[trigger] f(x, y),
{
let mut x = 10;
while x > 10
invariant
forall|x: nat, y: nat|
f(x + 1, 2 * y) && f(2 * x, y + x) || f(y, x) ==> #[trigger] f(x, y),
//decreases x;
{
x = x - 1;
assert(forall|x: nat, y: nat| x > 2318 && y < 100 ==> f(x, y));
}
}
fn main() {
}
} // verus!