File: maximumsort.mlw

package info (click to toggle)
why 2.30%2Bdfsg-5
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 26,916 kB
  • sloc: ml: 116,979; java: 9,376; ansic: 5,175; makefile: 1,335; sh: 531; lisp: 127
file content (50 lines) | stat: -rw-r--r-- 1,405 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50

include "arrays.why"

(* maxisort: Maximum sort *)

(* swapping two elements of an array *)
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) }

(* Maximize(t,n,x,k) is
   forall i, k <= i <= n implies t[k]<= x *) 
(*external logic Maximize: int farray, int, int, int -> prop*)
predicate Maximize(t:int array, n:int, x:int, k:int) =
  forall i:int. k <= i <= n -> t[k]<= x

(* returns the index of the maximum element of t[0..n] *)
let rec maximum (t:int array)(n,k,i:int): int { variant k } =
  { 0 <= k <= i and i <= n and n < array_length(t) and 
    Maximize(t,n,t[i],k) }
  (if k=0
   then i
   else
    let nk=k-1
    in if t[nk]>t[i]
   then (maximum t n nk nk)
   else (maximum t n nk i))
  { 0 <= result <= n and Maximize(t,n,t[result],0) }

(* Maximum sort *)
let maxisort (t:int array) =
  { 0 <= array_length(t) }
  init:
  (let i = ref ((array_length_ t)-1) in
   while !i >= 0 do
      { invariant 0 <= i+1 <= array_length(t)
            and sorted_array(t,i+1,array_length(t)-1) 
	    and permutation(t,t@init) 
            and (i+1 < array_length(t) -> Maximize(t,i,t[i+1],0))
        variant i+1 }
      (let r = (maximum t !i !i !i) in 
       (swap t !i r));
      i:=!i-1
    done)
  { sorted_array(t,0,array_length(t)-1) and permutation(t,t@) }