Skip to content

Commit

Permalink
progress
Browse files Browse the repository at this point in the history
  • Loading branch information
stefan-aws committed Mar 12, 2024
1 parent d7b0cef commit 732f5fd
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 7 deletions.
10 changes: 10 additions & 0 deletions src/Util/FisherYates/Equivalence.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module FisherYates.Equivalence {
import Model
import Rand
import Monad
import opened Pos

ghost predicate LoopInvariant<T>(prevI: nat, i: nat, a: array<T>, prevASeq: seq<T>, oldASeq: seq<T>, oldS: Rand.Bitstream, prevS: Rand.Bitstream, s: Rand.Bitstream)
reads a
Expand All @@ -17,6 +18,15 @@ module FisherYates.Equivalence {
&& Model.Shuffle(prevASeq, prevI)(prevS) == Model.Shuffle(a[..], i)(s)
}

ghost predicate LoopInvariant32<T>(prevI: nat32, i: nat32, a: array<T>, prevASeq: seq<T>, oldASeq: seq<T>, oldS: Rand.Bitstream, prevS: Rand.Bitstream, s: Rand.Bitstream)
reads a
{
&& prevI as nat <= |prevASeq|
&& i as nat <= a.Length - 1
&& Model.Shuffle(oldASeq)(oldS) == Model.Shuffle(prevASeq, prevI as nat)(prevS)
&& Model.Shuffle(prevASeq, prevI as nat)(prevS) == Model.Shuffle(a[..], i as nat)(s)
}

lemma ShuffleElseClause<T>(a: array<T>, oldASeq: seq<T>, oldS: Rand.Bitstream, s: Rand.Bitstream)
requires aLength: a.Length <= 1
requires aInvariant: oldASeq == a[..]
Expand Down
13 changes: 7 additions & 6 deletions src/Util/FisherYates/Implementation.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -55,15 +55,16 @@ module FisherYates.Implementation {
requires a.Length < 0x8000_0000
ensures Model.Shuffle(old(a[..]))(old(s)) == Monad.Result(a[..], s)
{
ghost var prevI, prevASeq, prevS := 0, a[..], s; // ghost
if a.Length > 1 {
for i := 0 to a.Length - 1
invariant Equivalence.LoopInvariant(prevI, i, a, prevASeq, old(a[..]), old(s), prevS, s) // ghost
ghost var prevI, prevASeq, prevS := 0 as int32, a[..], s; // ghost

if (a.Length as nat32) > (1 as nat32) {
for i: nat32 := (0 as nat32) to (a.Length as nat32) - (1 as nat32)
invariant Equivalence.LoopInvariant32(prevI, i, a, prevASeq, old(a[..]), old(s), prevS, s) // ghost
{
prevI, prevASeq, prevS := i, a[..], s; // ghost
var j := UniformIntervalSample32(i as int32, a.Length as int32);
var j := UniformIntervalSample32(i, a.Length as nat32);
assert prevASeq == a[..]; // ghost
Swap32(a, i as nat32, j as nat32);
Swap32(a, i, j);
}
} else {
Equivalence.ShuffleElseClause(a, old(a[..]), old(s), s); // ghost
Expand Down
2 changes: 1 addition & 1 deletion src/Util/FisherYates/Interface.dfy
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ module FisherYates.Interface {
decreases *
modifies `s, a
requires a.Length < 0x8000_0000
ensures Model.Shuffle(old(a[..]))(old(s)) == Monad.Result(a[..], s)
//ensures Model.Shuffle(old(a[..]))(old(s)) == Monad.Result(a[..], s)

}
}

0 comments on commit 732f5fd

Please sign in to comment.