-
Notifications
You must be signed in to change notification settings - Fork 1
/
085-add.dfy
53 lines (50 loc) · 1.67 KB
/
085-add.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
function sumc(s: seq<int>, p: seq<bool>) : int
requires |s| == |p|
{
if |s| == 0 then 0 else (if p[0] then s[0] else 0) + sumc(s[1..], p[1..])
}
lemma sum_prop(s: seq<int>, p: seq<bool>)
requires |s| > 0
requires |s| == |p|
ensures sumc(s, p) == sumc(s[..|s| - 1], p[..|s| - 1]) + (if p[ |s| - 1 ] then s[ |s| - 1 ] else 0)
{
if (|s| > 1) {
assert (s[1..][..|s[1..]| - 1]) == s[1..|s| - 1];
assert (p[1..][..|s[1..]| - 1]) == p[1..|s| - 1];
}
}
function add_conditon(lst: seq<int>) : (p : seq<bool>)
ensures |lst| == |p|
{
seq(|lst|, i requires 0 <= i < |lst| => i % 2 == 1 && lst[i] % 2 == 0)
}
method add(v: seq<int>) returns (r : int)
// post-conditions-start
ensures r == sumc(v, add_conditon(v))
// post-conditions-end
{
// impl-start
r := 0;
var k := 0;
var p := add_conditon(v);
while(k < |v|)
// invariants-start
invariant 0 <= k <= |v|
invariant r == sumc(v[..k], p[..k])
// invariants-end
{
assert v[..k + 1][..k] == v[..k]; // assert-line
assert p[..k + 1][..k] == p[..k]; // assert-line
r := r + if p[k] then v[k] else 0;
k := k + 1;
// assert-start
assert sumc(v[..k], p[..k]) == r by {
sum_prop(v[..k], p[..k]);
}
// assert-end
}
assert v[..k] == v; // assert-line
assert p[..k] == p; // assert-line
return r;
// impl-end
}