-
Notifications
You must be signed in to change notification settings - Fork 1
/
106-f.dfy
66 lines (64 loc) · 1.57 KB
/
106-f.dfy
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
function factorial_spec(n : int) : int
requires n >= 0
decreases n
{
if n == 0 then 1 else n * factorial_spec(n - 1)
}
function sum_spec(n : int) : int
requires n >= 0
decreases n
{
if n == 0 then 1 else n + sum_spec(n - 1)
}
method f(n : int) returns (result : seq<int>)
// pre-conditions-start
requires n >= 1
// pre-conditions-end
// post-conditions-start
ensures |result| == n
ensures forall i : int :: i >= 0 && i < |result| && i % 2 == 0 ==> result[i] == factorial_spec(i)
ensures forall i : int :: i >= 0 && i < |result| && i % 2 != 0 ==> result[i] == sum_spec(i)
// post-conditions-end
{
// impl-start
result := [];
var i := 0;
while i < n
// invariants-start
invariant i >= 0 && i <= n
invariant |result| == i
invariant forall i : int :: i >= 0 && i < |result| && i % 2 == 0 ==> result[i] == factorial_spec(i)
invariant forall i : int :: i >= 0 && i < |result| && i % 2 != 0 ==> result[i] == sum_spec(i)
// invariants-end
{
if i % 2 == 0 {
var x := 1;
var j := 0;
while j < i
// invariants-start
invariant j >= 0 && j <= i
invariant x == factorial_spec(j)
// invariants-end
{
j := j + 1;
x := x * j;
}
result := result + [x];
} else {
var x := 1;
var j := 0;
while j < i
// invariants-start
invariant j >= 0 && j <= i
invariant x == sum_spec(j)
// invariants-end
{
j := j + 1;
x := x + j;
}
result := result + [x];
}
i := i + 1;
}
// impl-end
}