function sorted(s : seq<int>) : bool {
forall k1, k2 :: 0 <= k1 <= k2 < |s| ==> s[k1] <= s[k2]
method copyArr(a : array<int>, l : int, r : int) returns (ret : array<int>)
requires 0 <= l < r <= a.Length
ensures ret[..] == a[l..r]
invariant a[..] == old(a[..])
invariant ret[..i] == a[l..(l + i)]
method mergeArr(a : array<int>, l : int, m : int, r : int)
requires 0 <= l < m < r <= a.Length
requires sorted(a[l..m]) && sorted(a[m..r])
ensures a[..l] == old(a[..l])
ensures a[r..] == old(a[r..])
var left := copyArr(a, l, m);
var right := copyArr(a, m, r);
ghost var old_arr := a[..];
invariant 0 <= i <= left.Length
invariant 0 <= j <= right.Length
invariant cur == i + j + l
invariant a[..l] == old_arr[..l]
invariant a[r..] == old_arr[r..]
invariant sorted(a[l..cur])
invariant sorted(left[..])
invariant sorted(right[..])
invariant i < left.Length && cur > l ==> a[cur - 1] <= left[i]
invariant j < right.Length && cur > l ==> a[cur - 1] <= right[j]
if((i == left.Length && j < right.Length) || (j != right.Length && left[i] > right[j])) {
else if((j == right.Length && i < left.Length) || (i != left.Length && left[i] <= right[j])) {
method sort(a : array<int>)
if(a.Length == 0) { return; }
else { sortAux(a, 0, a.Length); }
method sortAux(a : array<int>, l : int, r : int)
ensures a[..l] == old(a[..l])
ensures a[r..] == old(a[r..])
requires 0 <= l < r <= a.Length
if(l >= (r - 1)) {return;}
var m := l + (r - l) / 2;