Sophie

Sophie

distrib > Fedora > 13 > i386 > by-pkgid > 4a989cf09a4b4c5f3273c280e92c6313 > files > 120

why-2.23-2.fc13.i686.rpm


include "arrays.why"

(* A variant of quicksort, with partitioning a la Bentley *)

(* exchange of two elements *)

let swap (t:int array)(i,j:int) =
  { 0 <= i < array_length(t) and 0 <= j < array_length(t) }
  let v = t[i] in
  begin
    t[i] := t[j];
    t[j] := v
  end
  { exchange(t, t@, i, j) }

(* The recursive part of the quicksort algorithm:
   a recursive function to sort between [l] and [r] *)

let rec quick_rec (t:int array) (l,r:int) : unit { variant 1+r-l } =
  { 0 <= l and r < array_length(t) }
  if l < r then 
    let v = t[l] in
    let m = ref l in
    let i = ref (l + 1) in
    begin
      L:
      while !i <= r do
	{ invariant (forall j:int. l < j <= m -> t[j] < v)
                and (forall j:int. m < j <  i -> t[j] >= v)
                and permut(t, t@L, l, r)
                and t[l] = v and l <= m < i and i <= r + 1
          variant 1 + r - i }
        if t[!i] < v then begin m := !m + 1; (swap t !i !m) end;
        i := !i + 1
      done;
      (swap t l !m);
      (quick_rec t l (!m - 1));
      (quick_rec t (!m + 1) r)
    end
  { sorted_array(t, l, r) and permut(t, t@, l, r) }

(* At last, the main program, which is just a call to [quick_rec] *)

let quicksort (t:int array) =
  {} 
  (quick_rec t 0 ((array_length_ t)-1))
  { sorted_array(t, 0, array_length(t)-1) and permutation(t, t@) }

(*
Local Variables: 
compile-command: "gwhy quicksort2.mlw"
End: 
*)