71 lines
1.9 KiB
Text
71 lines
1.9 KiB
Text
|
(*
|
||
|
* linear_search.whyml
|
||
|
* WhyML implementation of byteback test `algorithm/LinearSearch`
|
||
|
*)
|
||
|
|
||
|
module LinearSearch
|
||
|
use int.Int
|
||
|
use ref.Ref
|
||
|
use array.Array
|
||
|
|
||
|
type t
|
||
|
|
||
|
val predicate eq (a b : t)
|
||
|
|
||
|
(* nullability preamble *)
|
||
|
exception NullPointerException
|
||
|
|
||
|
type nullable 't = Null | Some 't
|
||
|
|
||
|
let predicate is_null (obj: nullable 't) =
|
||
|
match obj with
|
||
|
| Null -> true
|
||
|
| Some _ -> false
|
||
|
end
|
||
|
|
||
|
let dereference (obj: nullable 't) : 't
|
||
|
raises { NullPointerException -> is_null obj } =
|
||
|
match obj with
|
||
|
| Null -> raise NullPointerException
|
||
|
| Some obj_val -> obj_val
|
||
|
end
|
||
|
(* end nullability preamble *)
|
||
|
|
||
|
type narrt = nullable (array t)
|
||
|
|
||
|
let predicate array_is_not_null (a: narrt) (n: t) (left right: int) = is_null a
|
||
|
|
||
|
let predicate array_is_null (a: narrt) (n: t) (left right: int) = not (is_null a)
|
||
|
|
||
|
let predicate bounded_indices (a: narrt) (n: t) (left right: int) =
|
||
|
match a with
|
||
|
| Null -> false
|
||
|
| Some aa -> 0 <= left && left <= right && right <= length aa
|
||
|
end
|
||
|
|
||
|
let predicate result_is_index (a: narrt) (n: t) (left right return_val: int) =
|
||
|
match a with
|
||
|
| Null -> false
|
||
|
| Some aa -> ((not (0 <= return_val)) || (eq aa[return_val] n))
|
||
|
end
|
||
|
|
||
|
let search (a: narrt) (n: t) (left right: int) : int
|
||
|
requires { array_is_not_null a n left right }
|
||
|
requires { bounded_indices a n left right }
|
||
|
ensures { result_is_index a n left right result }
|
||
|
raises { NullPointerException -> false }
|
||
|
=
|
||
|
let ref i = left in
|
||
|
while i < right do
|
||
|
invariant { left <= i && i <= right }
|
||
|
|
||
|
let a_val = dereference a in
|
||
|
if eq a_val[i] n then
|
||
|
return i;
|
||
|
|
||
|
i <- i + 1;
|
||
|
done;
|
||
|
|
||
|
-1
|
||
|
end
|