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; } }