selection sort works

This commit is contained in:
Claudio Maggioni 2023-03-26 22:38:58 +02:00
parent ba9800bcec
commit 05490f52d3
3 changed files with 125 additions and 0 deletions

42
selectionsort.dfy Normal file
View File

@ -0,0 +1,42 @@
predicate sorted(s: seq<int>) {
forall i,j: int :: 0 <= i < j < |s| ==> s[i] <= s[j]
}
method SelectionSort(a: array<int>)
modifies a
ensures sorted(a[..]);
ensures multiset(a[..]) == multiset(old(a[..]));
{
if (a.Length == 0) {
return;
}
var s := 0;
while (s < a.Length - 1)
invariant multiset(a[..]) == multiset(old(a[..]));
invariant forall i,j: int :: 0 <= i < s <= j < a.Length ==> a[i] <= a[j]
invariant s <= a.Length - 1
invariant s >= 1 ==> sorted(a[0..s])
decreases a.Length - s
{
var min: int := s;
var i: int := s + 1;
while i < a.Length
invariant multiset(a[..]) == multiset(old(a[..]));
invariant s <= min < a.Length
invariant s + 1 <= i <= a.Length
invariant forall j: int :: s <= j < i ==> a[min] <= a[j]
decreases a.Length - i
{
if (a[i] < a[min]) {
min := i;
}
i := i + 1;
}
a[s], a[min] := a[min], a[s];
s := s + 1;
}
}

78
slowsort.dfy Normal file
View File

@ -0,0 +1,78 @@
predicate sorted(s: seq<int>) {
forall i,j: int :: 0 <= i < j < |s| ==> s[i] <= s[j]
}
predicate sameElements(sa: seq<int>, sb: seq<int>) {
multiset(sa) == multiset(sb)
}
lemma SubSort(s: seq<int>, i: int, j: int)
requires sorted(s)
requires 0 <= i < j <= |s|
ensures sorted(s[i..j])
{
}
method SlowSortHelper(a: array<int>, startIdx: int, endIdx: int)
requires 0 <= startIdx <= endIdx < a.Length
modifies a
ensures a[..startIdx] == old(a[..startIdx])
ensures endIdx < a.Length ==> a[endIdx + 1..] == old(a[endIdx + 1..])
ensures sorted(a[startIdx..endIdx + 1])
ensures multiset(a[startIdx..endIdx + 1]) == multiset(old(a[startIdx..endIdx + 1]))
decreases endIdx - startIdx
{
if (endIdx == startIdx) {
return;
}
var middleIdx: int := (startIdx + endIdx) / 2;
assert sameElements(a[startIdx..endIdx + 1], old(a[startIdx..endIdx + 1]));
SlowSortHelper(a, startIdx, middleIdx);
SlowSortHelper(a, middleIdx + 1, endIdx);
assert 0 <= startIdx <= middleIdx < endIdx;
assert a[..startIdx] == old(a[..startIdx]);
assert endIdx < a.Length ==> a[endIdx + 1..] == old(a[endIdx + 1..]);
assert sorted(a[startIdx..middleIdx + 1]);
assert sorted(a[middleIdx + 1..endIdx + 1]);
if (a[endIdx] < a[middleIdx]) {
a[endIdx], a[middleIdx] := a[middleIdx], a[endIdx];
}
assert a[middleIdx] <= a[endIdx];
assert forall j: int :: startIdx <= j <= endIdx ==> a[j] <= a[endIdx];
SlowSortHelper(a, startIdx, endIdx - 1);
assert 0 <= startIdx <= middleIdx < endIdx;
assert sorted(a[startIdx..endIdx]);
assert multiset(a[startIdx..endIdx]) == multiset(old(a[startIdx..endIdx]));
assert forall j: int :: startIdx <= j <= endIdx ==> old(a[j]) <= a[endIdx];
// assert 0 <= startIdx < middleIdx + 1 <= endIdx;
// assert sorted(a[startIdx..endIdx]);
// assert a[..startIdx] == old(a[..startIdx]);
// assert endIdx < a.Length ==> a[endIdx + 1..] == old(a[endIdx + 1..]);
// assert sorted(a[startIdx..endIdx]);
// assert middleIdx <= endIdx ==> a[middleIdx] < a[endIdx];
// assert forall j: int :: startIdx <= j < endIdx ==> a[j] <= a[endIdx];
}
method SlowSort(a: array<int>)
modifies a
ensures sorted(a[..])
ensures sameElements(a[..], old(a[..]))
{
if (a.Length > 1) {
SlowSortHelper(a, 0, a.Length - 1);
}
}

5
start-docker.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/sh
SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
docker run --rm -it -v "${SCRIPT_DIR}:/tools/home" bugcounting/satools:y23