Sophie

Sophie

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

why-2.23-2.fc13.i686.rpm

(** Fully axiomatic version of Dijkstra's "Dutch national flag" 
    See also flag.mlw in the same directory *)

type color

logic blue : color
logic white : color
logic red : color

predicate is_color(c:color) = c=blue or c=white or c=red

parameter eq_color  : 
  c1:color -> c2:color -> {} bool { if result then c1=c2 else c1<>c2 }

type color_array

logic acc : color_array, int -> color
logic upd : color_array, int, color -> color_array
logic length : color_array -> int

axiom acc_upd_eq :
  forall a:color_array. forall i:int. forall c:color.
    acc(upd(a,i,c),i) = c

axiom acc_upd_neq :
  forall a:color_array. forall i,j:int. forall c:color.
    i <> j -> acc(upd(a,j,c),i) = acc(a,i)

axiom length_update : 
  forall a:color_array. forall i:int. forall c:color.
    length(upd(a,i,c)) = length(a)

parameter get : 
  t:color_array ref -> i:int -> 
    { 0<=i<length(t) } color reads t { result=acc(t,i) }

parameter set : 
  t:color_array ref -> i:int -> c:color -> 
    { 0<=i<length(t) } unit writes t { t=upd(t@,i,c) }

predicate monochrome(t:color_array, i:int, j:int, c:color) =
  forall k:int. i<=k<j -> acc(t,k)=c

logic Permutation : color_array, color_array, int, int -> prop

axiom permut_refl : forall t: color_array. forall l,r:int.
  Permutation(t,t,l,r)

axiom permut_swap : forall t:color_array. forall l,r,i,j:int.
  l <= i <= r -> l <= j <= r ->
  Permutation(t, upd(upd(t,i,acc(t,j)), j, acc(t,i)), l, r)

axiom permut_sym : forall t1,t2:color_array. forall l,r:int.
  Permutation(t1,t2,l,r) -> Permutation(t2,t1,l,r)

axiom permut_trans : forall t1,t2,t3: color_array. forall l,r:int.
  Permutation(t1,t2,l,r) -> Permutation(t2,t3,l,r) -> Permutation(t1,t3,l,r)

let swap (t:color_array ref) (i:int) (j:int) =
  { 0 <= i < length(t) and 0 <= j < length(t) }
  let u = get t i in
  set t i (get t j);
  set t j u
  { t = upd(upd(t@,i,acc(t@,j)), j, acc(t@,i)) }

let dutch_flag (t:color_array ref) (n:int) = 
  { 0 <= n and length(t) = n and 
    forall k:int. 0 <= k < n -> is_color(acc(t,k)) }
  let b = ref 0 in
  let i = ref 0 in
  let r = ref n in
  init:
  while !i < !r do
     { invariant 0 <= b <= i and i <= r <= n and
	         monochrome(t,0,b,blue) and 
	         monochrome(t,b,i,white) and 
	         monochrome(t,r,n,red) and
		 length(t) = n and
                 (forall k:int. 0 <= k < n -> is_color(acc(t,k))) and
	         Permutation(t,t@init,0,n-1)
       variant r - i }
     if eq_color (get t !i) blue then begin
       swap t !b !i;
       b := !b + 1;
       i := !i + 1
     end else if eq_color (get t !i) white then
       i := !i + 1
     else begin
       r := !r - 1;
       swap t !r !i
     end
  done
  { (exists b:int. exists r:int.	
      monochrome(t,0,b,blue) and 
      monochrome(t,b,r,white) and 
      monochrome(t,r,n,red))
    and Permutation(t,t@,0,n-1) }

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