Commit 58ae6f4f authored by MARCHE Claude's avatar MARCHE Claude

LCP: proof of LRS function in progress

parent 65086408
......@@ -89,7 +89,7 @@ predicate permutation (a:array int) =
use import array.ArrayPermut
lemma permut_permutation :
forall a1 a2:array int, n:int.
forall a1 a2:array int.
permut a1 a2 /\ permutation a1 -> permutation a2
......@@ -136,6 +136,11 @@ lemma lcp_refl :
forall a:array int, x:int.
0 <= x <= a.length -> longest_common_prefix a x x = a.length - x
lemma lcp_sym :
forall a:array int, x y:int.
0 <= x <= a.length /\ 0 <= y <= a.length ->
longest_common_prefix a x y = longest_common_prefix a y x
use import ref.Refint
......@@ -303,6 +308,16 @@ let compare (a:array int) (x y:int) : int
done
(* additional properties relating le and longest_common_prefix, needed
for LRS
*)
lemma lcp_le_le:
forall a:array int, x y z:int.
le a x y /\ le a y z ->
longest_common_prefix a x z <= longest_common_prefix a y z
end
......@@ -392,6 +407,7 @@ module LRS "longest repeated substring"
use import int.Int
use import ref.Ref
use import array.Array
use map.MapInjection
use LCP
use SuffixArray
......@@ -402,14 +418,15 @@ module LRS "longest repeated substring"
requires { a.length > 0 }
ensures { 0 <= !solLength <= a.length }
ensures { 0 <= !solStart <= a.length }
ensures { forall x y:int.
0 <= x < a.length /\ 0 <= y <= a.length /\ x <> y ->
!solLength >= LCP.longest_common_prefix a x y }
ensures { exists y:int.
0 <= y <= a.length /\ !solStart <> y /\
!solLength = LCP.longest_common_prefix a !solStart y }
ensures { forall x y:int.
0 <= x < y < a.length ->
!solLength >= LCP.longest_common_prefix a x y }
=
let sa = SuffixArray.create a in
assert { LCP.permutation sa.SuffixArray.suffixes };
solStart := 0;
solLength := 0;
for i=1 to a.length - 1 do
......@@ -418,12 +435,40 @@ module LRS "longest repeated substring"
invariant { exists y:int.
0 <= y <= a.length /\ !solStart <> y /\
!solLength = LCP.longest_common_prefix a !solStart y }
invariant { forall j k:int.
0 <= j < k < i ->
!solLength >= LCP.longest_common_prefix a
sa.SuffixArray.suffixes[j] sa.SuffixArray.suffixes[k] }
let l = SuffixArray.lcp sa i in
assert { forall j:int. 0 <= j < i ->
LCP.le a sa.SuffixArray.suffixes[j]
sa.SuffixArray.suffixes[i] };
assert { forall j:int. 0 <= j < i ->
LCP.longest_common_prefix a
sa.SuffixArray.suffixes[j]
sa.SuffixArray.suffixes[i]
<= l };
assert { forall j k:int. 0 <= j < k < i-1 ->
!solLength >= LCP.longest_common_prefix a
sa.SuffixArray.suffixes[j]
sa.SuffixArray.suffixes[k] };
if l > !solLength then begin
solStart := SuffixArray.select sa i;
solLength := l
end
done
done;
assert { let s = sa.SuffixArray.suffixes in
MapInjection.surjective s.elts s.length };
assert { forall j k:int.
0 <= j < a.length /\ 0 <= k < a.length /\ j <> k ->
!solLength >= LCP.longest_common_prefix a
sa.SuffixArray.suffixes[j] sa.SuffixArray.suffixes[k] };
assert { forall x y:int.
0 <= x < y < a.length ->
exists j k : int.
0 <= j < a.length /\ 0 <= k < a.length /\ j <> k /\
x = sa.SuffixArray.suffixes[j] /\
y = sa.SuffixArray.suffixes[k] }
let test () =
let arr = Array.make 4 0 in
......
......@@ -77,9 +77,25 @@ Definition make {a:Type} {a_WT:WhyType a}(n:Z) (v:a): (array a) :=
(mk_array n (const v:(map Z a))).
(* Why3 assumption *)
Definition array_bounded(a:(array Z)) (b:Z): Prop := forall (i:Z),
((0%Z <= i)%Z /\ (i < (length a))%Z) -> ((0%Z <= (get1 a i))%Z /\ ((get1 a
i) < b)%Z).
Definition injective(a:(map Z Z)) (n:Z): Prop := forall (i:Z) (j:Z),
((0%Z <= i)%Z /\ (i < n)%Z) -> (((0%Z <= j)%Z /\ (j < n)%Z) ->
((~ (i = j)) -> ~ ((get a i) = (get a j)))).
(* Why3 assumption *)
Definition surjective(a:(map Z Z)) (n:Z): Prop := forall (i:Z),
((0%Z <= i)%Z /\ (i < n)%Z) -> exists j:Z, ((0%Z <= j)%Z /\ (j < n)%Z) /\
((get a j) = i).
(* Why3 assumption *)
Definition range(a:(map Z Z)) (n:Z): Prop := forall (i:Z), ((0%Z <= i)%Z /\
(i < n)%Z) -> ((0%Z <= (get a i))%Z /\ ((get a i) < n)%Z).
Axiom injective_surjective : forall (a:(map Z Z)) (n:Z), (injective a n) ->
((range a n) -> (surjective a n)).
(* Why3 assumption *)
Definition permutation(a:(array Z)): Prop := (range (elts a) (length a)) /\
(injective (elts a) (length a)).
(* Why3 assumption *)
Definition map_eq_sub {a:Type} {a_WT:WhyType a}(a1:(map Z a)) (a2:(map Z a))
......@@ -165,8 +181,8 @@ Axiom array_eq_sub_permut : forall {a:Type} {a_WT:WhyType a},
Axiom array_eq_permut : forall {a:Type} {a_WT:WhyType a}, forall (a1:(array
a)) (a2:(array a)), (array_eq a1 a2) -> (permut a1 a2).
Axiom permut_bounded : forall (a1:(array Z)) (a2:(array Z)) (n:Z),
((permut a1 a2) /\ (array_bounded a1 n)) -> (array_bounded a2 n).
Axiom permut_permutation : forall (a1:(array Z)) (a2:(array Z)), ((permut a1
a2) /\ (permutation a1)) -> (permutation a2).
(* Why3 assumption *)
Definition is_common_prefix(a:(array Z)) (x:Z) (y:Z) (l:Z): Prop :=
......@@ -206,6 +222,10 @@ Axiom lcp_refl : forall (a:(array Z)) (x:Z), ((0%Z <= x)%Z /\
(x <= (length a))%Z) -> ((longest_common_prefix a x
x) = ((length a) - x)%Z).
Axiom lcp_sym : forall (a:(array Z)) (x:Z) (y:Z), (((0%Z <= x)%Z /\
(x <= (length a))%Z) /\ ((0%Z <= y)%Z /\ (y <= (length a))%Z)) ->
((longest_common_prefix a x y) = (longest_common_prefix a y x)).
(* Why3 assumption *)
Definition le(a:(array Z)) (x:Z) (y:Z): Prop := let n := (length a) in
(((0%Z <= x)%Z /\ (x <= n)%Z) /\ (((0%Z <= y)%Z /\ (y <= n)%Z) /\ let l :=
......@@ -262,6 +282,10 @@ Axiom sorted_sub_set2 : forall (a:(array Z)) (data:(array Z)) (l:Z) (u:Z)
Definition sorted(a:(array Z)) (data:(array Z)): Prop := (sorted_sub a data
0%Z (length data)).
Axiom lcp_le_le : forall (a:(array Z)) (x:Z) (y:Z) (z:Z), ((le a x y) /\
(le a y z)) -> ((longest_common_prefix a x z) <= (longest_common_prefix a y
z))%Z.
(* Why3 assumption *)
Inductive suffixArray :=
| mk_suffixArray : (array Z) -> (array Z) -> suffixArray .
......@@ -283,19 +307,27 @@ Definition values(v:suffixArray): (array Z) :=
(* Why3 assumption *)
Definition inv(s:suffixArray): Prop :=
((length (values s)) = (length (suffixes s))) /\
(array_bounded (suffixes s) (length (values s))).
(permutation (suffixes s)).
Require Import Why3.
(* Why3 goal *)
Theorem WP_parameter_lrs : forall (a:Z), forall (a1:(map Z Z)),
(0%Z < a)%Z -> ((0%Z <= a)%Z -> forall (sa:Z) (sa1:(map Z Z)) (sa2:Z)
(sa3:(map Z Z)), ((sa = a) /\ (inv (mk_suffixArray (mk_array sa sa1)
(mk_array sa2 sa3)))) -> forall (solStart:Z), (solStart = 0%Z) ->
forall (solLength:Z), (solLength = 0%Z) -> (((a - 1%Z)%Z < 1%Z)%Z ->
exists y:Z, ((0%Z <= y)%Z /\ (y <= a)%Z) /\ ((~ (solStart = y)) /\
(solLength = (longest_common_prefix (mk_array a a1) solStart y))))).
intros a a1 h1 h2 sa sa1 sa2 sa3 (h3,h4) solStart h5 solLength h6 h7.
Theorem WP_parameter_lrs : forall (a:Z), forall (a1:(map Z Z)), let a2 :=
(mk_array a a1) in ((0%Z < a)%Z -> ((0%Z <= a)%Z -> forall (sa:Z) (sa1:(map
Z Z)) (sa2:Z) (sa3:(map Z Z)), (((sa = a) /\ (sa1 = a1)) /\
(inv (mk_suffixArray (mk_array sa sa1) (mk_array sa2 sa3)))) ->
((permutation (mk_array sa2 sa3)) -> forall (solStart:Z),
(solStart = 0%Z) -> forall (solLength:Z), (solLength = 0%Z) ->
(((a - 1%Z)%Z < 1%Z)%Z -> ((surjective sa3 sa2) -> ((forall (j:Z) (k:Z),
(((0%Z <= j)%Z /\ (j < a)%Z) /\ (((0%Z <= k)%Z /\ (k < a)%Z) /\
~ (j = k))) -> ((longest_common_prefix a2 (get sa3 j) (get sa3
k)) <= solLength)%Z) -> ((forall (x:Z) (y:Z), (((0%Z <= x)%Z /\
(x < y)%Z) /\ (y < a)%Z) -> exists j:Z, exists k:Z, ((0%Z <= j)%Z /\
(j < a)%Z) /\ (((0%Z <= k)%Z /\ (k < a)%Z) /\ ((~ (j = k)) /\
((x = (get sa3 j)) /\ (y = (get sa3 k)))))) -> exists y:Z, ((0%Z <= y)%Z /\
(y <= a)%Z) /\ ((~ (solStart = y)) /\
(solLength = (longest_common_prefix a2 solStart y)))))))))).
intro a; intros.
exists a.
why3 "alt-ergo".
Qed.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment