example decrease1: Coq proof and recursive version

This commit is contained in:
Jean-Christophe Filliatre
2011-05-16 14:28:44 +02:00
parent b7c7d6f937
commit c232ed5bac
3 changed files with 292 additions and 11 deletions

View File

@@ -18,21 +18,38 @@ module Decrease1
forall a: array int. decrease1 a ->
forall i j: int. 0 <= i <= j < length a -> a[j] >= a[i] + i - j
exception Found int
exception Found
let search (a: array int) =
{ decrease1 a }
let i = ref 0 in
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 get a !i = 0 then raise (Found !i);
if get a !i > 0 then i := !i + get a !i else i := !i + 1
done
{ forall j: int. 0 <= j < length a -> a[j] <> 0 }
| Found -> { 0 <= result < length a and a[result] = 0 and
forall j: int. 0 <= j < result -> a[j] <> 0 }
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 get a !i = 0 then raise Found;
if get a !i > 0 then i := !i + get 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 get a i = 0 then i
else if get a i > 0 then search_rec a (i + get 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