-
Notifications
You must be signed in to change notification settings - Fork 1
/
033-sort_third.dfy
71 lines (69 loc) · 2.13 KB
/
033-sort_third.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
67
68
69
70
71
method sort_third(a: seq<int>) returns (sorted_even: seq<int>)
// pre-conditions-start
requires |a| > 0
// pre-conditions-end
// post-conditions-start
ensures |sorted_even| == |a|
ensures forall i, j :: 0 <= i < j < |sorted_even| && i % 3 == 0 && j % 3 == 0 ==>
sorted_even[i] <= sorted_even[j]
ensures forall i :: 0 <= i < |a| && i % 3 != 0 ==> sorted_even[i] == a[i]
ensures multiset(a) == multiset(sorted_even)
// post-conditions-end
{
// impl-start
var p := [];
for i := 0 to |a|
// invariants-start
invariant |p| == i
invariant forall j :: 0 <= j < i ==> p[j] == (j % 3 == 0)
// invariants-end
{
p := p + [i % 3 == 0];
}
sorted_even := SortSeqPred(a, p);
// impl-end
}
method SortSeqPred(s: seq<int>, p: seq<bool>) returns (sorted: seq<int>)
// pre-conditions-start
requires |s| == |p|
// pre-conditions-end
// post-conditions-start
ensures |sorted| == |s|
ensures forall i, j :: 0 <= i < j < |sorted| && p[i] && p[j] ==> sorted[i] <= sorted[j]
ensures multiset(s) == multiset(sorted)
ensures forall i :: 0 <= i < |s| && !p[i] ==> sorted[i] == s[i]
// post-conditions-end
{
// impl-start
sorted := s;
for i := 0 to |sorted|
// invariants-start
invariant |sorted| == |s|
invariant forall j, k :: 0 <= j < k < i && p[j] && p[k] ==> sorted[j] <= sorted[k]
invariant multiset(s) == multiset(sorted)
invariant forall j :: 0 <= j < i && p[j] ==> forall k :: i <= k < |sorted| && p[k] ==> sorted[j] <= sorted[k]
invariant |sorted| == |s|
invariant forall j :: 0 <= j < |s| && !p[j] ==> sorted[j] == s[j]
// invariants-end
{
if p[i] {
var minIndex := i;
for j := i + 1 to |sorted|
// invariants-start
invariant i <= minIndex < j <= |sorted|
invariant p[minIndex]
invariant forall k :: i <= k < j && p[k] ==> sorted[minIndex] <= sorted[k]
// invariants-end
{
if p[j] && sorted[j] < sorted[minIndex] {
minIndex := j;
}
}
if minIndex != i {
var temp := sorted[i];
sorted := sorted[i := sorted[minIndex]][minIndex := temp];
}
}
}
// impl-end
}