diff --git a/whyml/linear_search.why b/whyml/linear_search.why new file mode 100644 index 0000000..b16cf1a --- /dev/null +++ b/whyml/linear_search.why @@ -0,0 +1,70 @@ +(* + * 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