Sophie

Sophie

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

why-2.23-2.fc13.i686.rpm


include "arrays.why"

(* Search in an array for a null value *)

exception Not_found

parameter t : int array

(* 1. With a loop. As soon as we find it, we raise (Found i) *)

exception Found of int

let search1 () = 
  {} 
  try
    let i = ref 0 in begin
    while !i < (array_length_ t) do
      { invariant 0 <= i and forall k:int. 0 <= k < i -> t[k] <> 0
        variant array_length(t) - i } 
      if t[!i] = 0 then raise (Found !i);
      i := !i + 1
    done;
    raise Not_found : int
    end 
  with Found x ->
    x
  end
  { t[result] = 0 
  | Not_found => forall k:int. 0 <= k < array_length(t) -> t[k] <> 0 }


(* 1. With a loop. As soon as we find it, we raise Break *)

exception Break

let search2 () = 
  {} 
  let i = ref 0 in 
  try
    begin
    while !i < (array_length_ t) do
      { invariant 0 <= i and forall k:int. 0 <= k < i -> t[k] <> 0
        variant array_length(t) - i }
      if t[!i] = 0 then raise Break;
      i := !i + 1
    done;
    raise Not_found : int
    end 
  with Break ->
    !i
  end
  { t[result] = 0 
  | Not_found => forall k:int. 0 <= k < array_length(t) -> t[k] <> 0 }


(* 3. With a recursive function *)

let search3 () =
  { 0 <= array_length(t) }
  (let rec search_rec (i:int) : int { variant array_length(t) - i } =
     { 0 <= i <= array_length(t) }
     (if i = (array_length_ t) then raise Not_found : int
      else if t[i] = 0 then i
      else (search_rec (i + 1)))
     { t[result] = 0 
     | Not_found => forall k:int. i <= k < array_length(t) -> t[k] <> 0 }
   in
  (search_rec 0))
  { t[result] = 0 
  | Not_found => forall k:int. 0 <= k < array_length(t) -> t[k] <> 0 }