Files
why3/examples/programs/decrease1.mlw
2011-05-20 18:03:51 +02:00

61 lines
1.6 KiB
Plaintext

(*
We look for the first occurrence of zero in an array of integers.
The values have the following property: they never decrease by more than one.
The code makes use of that property to speed up the search.
*)
module Decrease1
use import int.Int
use import module ref.Ref
use import module array.Array
logic decrease1 (a: array int) =
forall i: int. 0 <= i < length a - 1 -> a[i+1] >= a[i] - 1
lemma decrease1_induction:
forall a: array int. decrease1 a ->
forall i j: int. 0 <= i <= j < length a -> a[j] >= a[i] + i - j
exception Found
let search (a: array int) =
{ decrease1 a }
let i = ref 0 in
try
while !i < length a do
invariant { 0 <= !i and
forall j: int. 0 <= j < !i -> j < length a -> a[j] <> 0 }
variant { length a - !i }
if a[!i] = 0 then raise Found;
if a[!i] > 0 then i := !i + a[!i] else i := !i + 1
done;
-1
with Found ->
!i
end
{ (result = -1 and forall j: int. 0 <= j < length a -> a[j] <> 0)
or (0 <= result < length a and a[result] = 0 and
forall j: int. 0 <= j < result -> a[j] <> 0) }
let rec search_rec (a: array int) (i : int) =
{ decrease1 a and 0 <= i }
if i < length a then
if a[i] = 0 then i
else if a[i] > 0 then search_rec a (i + a[i])
else search_rec a (i + 1)
else
-1
{ (result = -1 and forall j: int. i <= j < length a -> a[j] <> 0)
or (i <= result < length a and a[result] = 0 and
forall j: int. i <= j < result -> a[j] <> 0) }
end
(*
Local Variables:
compile-command: "unset LANG; make -C ../.. examples/programs/decrease1.gui"
End:
*)