diff --git a/selectionsort.dfy b/selectionsort.dfy new file mode 100644 index 0000000..27ac285 --- /dev/null +++ b/selectionsort.dfy @@ -0,0 +1,42 @@ +predicate sorted(s: seq) { + forall i,j: int :: 0 <= i < j < |s| ==> s[i] <= s[j] +} + +method SelectionSort(a: array) + 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; + } +} \ No newline at end of file diff --git a/slowsort.dfy b/slowsort.dfy new file mode 100644 index 0000000..86a07f9 --- /dev/null +++ b/slowsort.dfy @@ -0,0 +1,78 @@ +predicate sorted(s: seq) { + forall i,j: int :: 0 <= i < j < |s| ==> s[i] <= s[j] +} + +predicate sameElements(sa: seq, sb: seq) { + multiset(sa) == multiset(sb) +} + +lemma SubSort(s: seq, i: int, j: int) + requires sorted(s) + requires 0 <= i < j <= |s| + ensures sorted(s[i..j]) +{ +} + +method SlowSortHelper(a: array, 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) +modifies a +ensures sorted(a[..]) +ensures sameElements(a[..], old(a[..])) +{ + if (a.Length > 1) { + SlowSortHelper(a, 0, a.Length - 1); + } +} \ No newline at end of file diff --git a/start-docker.sh b/start-docker.sh new file mode 100755 index 0000000..cff3ab2 --- /dev/null +++ b/start-docker.sh @@ -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 +