-
Notifications
You must be signed in to change notification settings - Fork 1
/
040-triples-sum-to-zero.dfy
46 lines (46 loc) · 2.97 KB
/
040-triples-sum-to-zero.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
method triples_sum_to_zero(l : seq<int>) returns (result : bool)
// post-conditions-start
ensures result ==> exists i : int, j : int, k : int :: 0 <= i < |l| && 0 <= j < |l| && 0 <= k < |l| && i != j && j != k && i != k && l[i] + l[j] + l[k] == 0
ensures !result ==> forall i : int, j : int, k : int :: 0 <= i < |l| && 0 <= j < |l| && 0 <= k < |l| && i != j && j != k && i != k ==> l[i] + l[j] + l[k] != 0
// post-conditions-end
{
// impl-start
result := false;
var i : int := 0;
while i < |l|
// invariants-start
invariant i >= 0 && i <= |l|
invariant !result ==> forall i1 : int, j : int, k : int :: 0 <= i1 < i && 0 <= j < |l| && 0 <= k < |l| && i1 != j && j != k && i1 != k ==> l[i1] + l[j] + l[k] != 0
invariant result ==> exists i1 : int, j : int, k : int :: 0 <= i1 < i && 0 <= j < |l| && 0 <= k < |l| && i1 != j && j != k && i1 != k && l[i1] + l[j] + l[k] == 0
// invariants-end
{
var j : int := 0;
while j < |l|
// invariants-start
invariant j >= 0 && j <= |l|
invariant !result ==> forall i1 : int, j : int, k : int :: 0 <= i1 < i && 0 <= j < |l| && 0 <= k < |l| && i1 != j && j != k && i1 != k ==> l[i1] + l[j] + l[k] != 0
invariant !result ==> forall j1 : int, k : int :: 0 <= j1 < j && 0 <= k < |l| && i != j1 && j1 != k && i != k ==> l[i] + l[j1] + l[k] != 0
invariant result ==> (exists i1 : int, j : int, k : int :: 0 <= i1 < i && 0 <= j < |l| && 0 <= k < |l| && i1 != j && j != k && i1 != k && l[i1] + l[j] + l[k] == 0) || (exists j1 : int, k : int :: 0 <= j1 < j && 0 <= k < |l| && i != j1 && j1 != k && i != k && l[i] + l[j1] + l[k] == 0)
// invariants-end
{
var k : int := 0;
while k < |l|
// invariants-start
invariant k >= 0 && k <= |l|
invariant !result ==> forall i1 : int, j : int, k : int :: 0 <= i1 < i && 0 <= j < |l| && 0 <= k < |l| && i1 != j && j != k && i1 != k ==> l[i1] + l[j] + l[k] != 0
invariant !result ==> forall j1 : int, k : int :: 0 <= j1 < j && 0 <= k < |l| && i != j1 && j1 != k && i != k ==> l[i] + l[j1] + l[k] != 0
invariant !result ==> forall k1 : int :: 0 <= k1 < k && i != j && j != k1 && i != k1 ==> l[i] + l[j] + l[k1] != 0
invariant result ==> (exists i1 : int, j : int, k : int :: 0 <= i1 < i && 0 <= j < |l| && 0 <= k < |l| && i1 != j && j != k && i1 != k && l[i1] + l[j] + l[k] == 0) || (exists j1 : int, k : int :: 0 <= j1 < j && 0 <= k < |l| && i != j1 && j1 != k && i != k && l[i] + l[j1] + l[k] == 0) || (exists k1 : int :: 0 <= k1 < k && i != j && j != k1 && i != k1 && l[i] + l[j] + l[k1] == 0)
// invariants-end
{
if i != j && j != k && i != k && l[i] + l[j] + l[k] == 0 {
result := true;
}
k := k + 1;
}
j := j + 1;
}
i := i + 1;
}
// impl-end
}