6 Elliott Brothers Ltd., Hertfordshire, England, U.K.
8 Communications of the ACM archive
9 Volume 4 , Issue 7 (July 1961) table of contents
21 (* we pass m and n (as ghost arguments) to ensure [permut_sub];
22 this will help solvers in the proof of partition *)
23 let exchange (a: array int) (ghost m n: int) (i j: int) =
24 requires { 0 <= m <= i <= n < length a /\ m <= j <= n }
25 ensures { exchange (old a) a i j }
26 ensures { permut_sub (old a) a m (n+1) }
30 assert { exchange (old a) a i j }
32 val random (m n: int) : int ensures { m <= result <= n }
34 let partition_ (a: array int) (m n: int) (i j: ref int) (ghost ghx: ref int)
35 requires { 0 <= m < n < length a }
36 ensures { m <= !j < !i <= n }
37 ensures { permut_sub (old a) a m (n+1) }
38 ensures { forall r:int. m <= r <= !j -> a[r] <= !ghx }
39 ensures { forall r:int. !j < r < !i -> a[r] = !ghx }
40 ensures { forall r:int. !i <= r <= n -> a[r] >= !ghx }
47 let rec up_down () variant { 1 + !j - !i } =
48 requires { m <= !j <= n /\ m <= !i <= n }
49 requires { permut_sub (old a) a m (n+1) }
50 requires { forall r:int. m <= r < !i -> a[r] <= x }
51 requires { forall r:int. !j < r <= n -> a[r] >= x }
53 ensures { m <= !j <= !i <= n }
54 ensures { permut_sub (old a) a m (n+1) }
55 ensures { !i = n \/ a[!i] > x }
56 ensures { !j = m \/ a[!j] < x }
58 ensures { forall r:int. m <= r < !i -> a[r] <= x }
59 ensures { forall r:int. !j < r <= n -> a[r] >= x }
60 while !i < n && a[!i] <= x do
61 invariant { m <= !i <= n }
62 invariant {forall r: int. m <= r < !i -> a[r] <= x }
66 while m < !j && a[!j] >= x do
67 invariant { m <= !j <= n }
68 invariant { forall r: int. !j < r <= n -> a[r] >= x }
80 assert { !j < !i \/ !j = !i = m \/ !j = !i = n };
81 if !i < f then begin exchange a m n !i f; incr i end
82 else if f < !j then begin exchange a m n f !j; decr j end
84 let partition (a: array int) (m n: int) (i j: ref int) =
85 requires { 0 <= m < n < length a }
86 ensures { m <= !j < !i <= n }
87 ensures { permut_sub (old a) a m (n+1) }
88 ensures { exists x: int.
89 (forall r:int. m <= r <= !j -> a[r] <= x) /\
90 (forall r:int. !j < r < !i -> a[r] = x) /\
91 (forall r:int. !i <= r <= n -> a[r] >= x) }
92 partition_ a m n i j (ref 0)