sorted : Array of T -> Bool
sorted s ==
(!i,j | i<j /\ j<#s . s[i] <= s[j] )
sorted : Array of T -> (Nat->Bool) -> Bool
sorted s r ==
(!i | r i . i<#s) /\
(!i,j | r i /\ r j /\ i<j /\ j<#s . s[i] <= s[j] )
PROCEDURE Sort(s:Array of T)
s:=s' | sorted s' /\ perm S s' <--
CON S | S=s .
{ s=S } s:=s' | sorted s' /\ perm S s' <--
VAR k . k:=0 ;
{ k=0 /\ s=S } s,k:=s',k' | sorted s' /\ perm S s' <--
DO G ->
{ INV /\ G }
s,k:=s',k' | INV' /\ V'<V
OD
|- k=0 /\ s=S ==> INV
|- INV /\ ~G ==> sorted s /\ perm S s
INV == k <= #s /\ sorted s {i|i<k} /\ perm S s
G == k < #s
V = #s - k
DO k < #s ->
{ k < #s /\ sorted s {i|i<k} /\ perm S s } <--
s,k:=s',k' | k' <= #s' /\ sorted s' {i|i<k'} <--
/\ perm S s' /\ #s'-k' < #s-k <--
OD
{ k < #s /\ sorted s {i|i<k} /\ perm S s }
s:=s' | (k+1) <= #s' /\ sorted s' {i|i<(k+1)}
/\ perm S s' /\ ;
k:=k+1
|- perm S s /\ perm S s' ==> #s = #s'
#s'-(k+1) < #s-k
== #s-(k+1) < #s-k since #s = #s'
== #s-k-1 < #s-k
== true
{ k < #s /\ sorted s {i|i<k} /\ perm S s }
s:=s' | (k+1) <= #s' /\ sorted s' {i|i<(k+1)} /\ perm S s'
VAR m:Nat . m:=k;
{ k < #s /\ sorted s {i|i<k} /\ perm S s /\ m=k }
s,m:=s',m' | (k+1) <= #s' /\ sorted s' {i|i<(k+1)} /\ perm S s'
INV == m<=k /\ sorted s {i| i<m \/ m<i<=k } /\
( m<k ==> s[m] < s[m+1] ) /\ perm S s
G == m > 0 /\ s[m-1] > s[m]
V = m
DO m > 0 /\ s[m] < s[m-1] ->
{ INV /\ m > 0 /\ s[m] < s[m-1] }
s,m:=s',m' | INV' /\ m'<m
OD
{ INV /\ m > 0 /\ s[m] < s[m-1] }
s:=s' | m-1<=k /\ sorted s' {i| i<m-1 \/ m-1<i<=k } /\
( m-1<k ==> s'[m-1] < s'[m] ) /\ perm S s' ;
m:=m-1
{ INV /\ m > 0 /\ s[m] < s[m-1] }
s:=s' | sorted s' {i| i<m-1 \/ m-1<i<=k } /\
s'[m-1] < s'[m] /\ perm S s'
|- INV /\ m > 0 /\ s[m] < s[m-1] /\ s' = swap s m-1 m
==> sorted s' {i| i<m-1 \/ m-1<i<=k } /\
s'[m-1] < s'[m] /\
perm S s'
s:=s' | s' = swap s m-1 m
s[m-1], s[m] := s[m], s[m-1]
PROCEDURE Sort(s:Array of T)
CON S:Array of T | S=s .
VAR k:Nat . k:=0 ;
DO k < #s ->
VAR m:Nat . m:=k;
DO m > 0 /\ s[m] < s[m-1] ->
s[m-1], s[m] := s[m], s[m-1];
m := m-1
OD;
k:=k+1
OD
PROCEDURE Sort(s:Array of T)
VAR k,m:Nat . k:=0 ;
DO k < #s ->
m:=k;
DO m > 0 /\ s[m] < s[m-1] ->
s[m-1], s[m] := s[m], s[m-1];
m := m-1
OD;
k:=k+1
OD