@@ -8,62 +8,25 @@ module FisherYates.Implementation {
8
8
import Monad
9
9
import Model
10
10
import Uniform
11
+ import Equivalence
11
12
12
13
trait {:termination false } Trait extends Interface. Trait {
13
14
14
- method {:vcs_split_on_every_assert} Shuffle< T> (a: array < T> )
15
+ method Shuffle< T> (a: array < T> )
15
16
decreases *
16
17
modifies `s, a
17
18
ensures Model. Shuffle (old(a[..]))(old (s)) == Monad. Result (a[..], s)
18
19
{
19
- ghost var prevASeq := a[.. ];
20
- ghost var prevI := 0;
21
- ghost var prevS := s;
20
+ ghost var prevI, prevASeq, prevS := 0, a[.. ], s; // ghost
22
21
if a. Length > 1 {
23
- var i := 0;
24
- while i < a. Length - 1
25
- decreases a. Length - 1 - i
26
- invariant prevI == if i == 0 then i else i - 1
27
- invariant prevI <= |prevASeq|
28
- invariant i <= |a[.. ]|
29
- invariant i <= a. Length - 1
30
- invariant |prevASeq| == |a[.. ]| == a. Length
31
- invariant Model. Shuffle (old(a[..]))(old (s)) == Model. Shuffle (prevASeq, prevI)(prevS)
32
- invariant Model. Shuffle (prevASeq, prevI)(prevS) == Model. Shuffle (a[..], i)(s)
22
+ for i := 0 to a. Length - 1
23
+ invariant Equivalence. LoopInvariant (prevI, i, a, prevASeq, old(a[..]), old (s), prevS, s)
33
24
{
34
- prevI := i;
35
- prevASeq := a[.. ];
36
- prevS := s;
25
+ prevI, prevASeq, prevS := i, a[.. ], s; // ghost
37
26
var j := UniformIntervalSample (i, a.Length);
38
- assert prevASeq == a[.. ];
27
+ assert prevASeq == a[.. ]; // ghost
39
28
Swap (a, i, j);
40
- i := i + 1;
41
- assert Model. Shuffle (prevASeq, prevI)(prevS) == Model. Shuffle (a[..], i)(s) by {
42
- calc {
43
- Model. Shuffle (prevASeq, prevI)(prevS);
44
- Model. Shuffle (Model.Swap(prevASeq, prevI, Uniform.Model.IntervalSample(prevI, |prevASeq|)(prevS). value), prevI + 1)(Uniform. Model. IntervalSample (prevI, |prevASeq|)(prevS). rest);
45
- { assert Uniform. Model. IntervalSample (prevI, |prevASeq|)(prevS). value == j;
46
- assert Uniform. Model. IntervalSample (prevI, |prevASeq|)(prevS). rest == s; }
47
- Model. Shuffle (Model.Swap(prevASeq, prevI, j), prevI + 1)(s);
48
- { assert i == prevI + 1;
49
- assert Model. Swap (prevASeq, prevI, j) == a[.. ];
50
- }
51
- Model. Shuffle (a[..], i)(s);
52
- }
53
- }
54
29
}
55
-
56
- assert Model. Shuffle (old(a[..]))(old (s)) == Monad. Result (a[..], s) by {
57
- assert i == a. Length - 1;
58
- calc {
59
- Model. Shuffle (old(a[..]))(old (s));
60
- Model. Shuffle (prevASeq, prevI)(prevS);
61
- Model. Shuffle (a[..], i)(s);
62
- Monad. Return (a[..])(s);
63
- Monad. Result (a[..], s);
64
- }
65
- }
66
-
67
30
}
68
31
}
69
32
0 commit comments