Commit b7c77790 authored by MARCHE Claude's avatar MARCHE Claude

LCP: simplified [le_trans], and cosmetic changes

parent e7949e64
......@@ -213,6 +213,12 @@ let compare (a:array int) (x y:int) : int
absurd
(** for the [range] predicate used below *)
use map.MapInjection
(** for the [permut] predicate (permutation of elements) *)
use array.ArrayPermut
predicate le (a : array int) (x y:int) = x = y \/ lt a x y
(* needed for le_trans (for cases x = y /\ le y z and le x y /\ y = z) *)
......@@ -220,11 +226,8 @@ let compare (a:array int) (x y:int) : int
forall a:array int, x:int.
0 <= x <= a.length -> LCP.is_longest_common_prefix a x x (a.length - x)
lemma le_trans :
forall a:array int, x y z:int.
0 <= x <= a.length /\ 0 <= y <= a.length /\
0 <= z <= a.length /\ le a x y /\ le a y z -> le a x z
lemma le_trans : forall a:array int, x y z:int.
le a x y /\ le a y z -> le a x z
(** spec of sorted in increasing prefix order *)
use map.Map
......@@ -236,26 +239,22 @@ let compare (a:array int) (x y:int) : int
predicate sorted (a : array int) (data:array int) =
sorted_sub a data.elts 0 data.length
(** spec of permutation of elements *)
use import array.ArrayPermut
use map.MapInjection (* for the range function used below *)
let sort (a:array int) (data : array int)
let sort (a:array int) (data : array int)
requires { data.length = a.length }
requires { MapInjection.range data.elts data.length }
ensures { sorted a data }
ensures { permut (old data) data }
ensures { ArrayPermut.permut (old data) data }
=
'Init:
for i = 0 to data.length - 1 do
invariant { permut (at data 'Init) data }
invariant { ArrayPermut.permut (at data 'Init) data }
invariant { sorted_sub a data.elts 0 i }
invariant { MapInjection.range data.elts data.length }
let j = ref i in
while !j > 0 && compare a data[!j-1] data[!j] > 0 do
invariant { 0 <= !j <= i }
invariant { MapInjection.range data.elts data.length }
invariant { permut (at data 'Init) data }
invariant { ArrayPermut.permut (at data 'Init) data }
invariant { sorted_sub a data.elts 0 !j }
invariant { sorted_sub a data.elts !j (i+1) }
invariant { forall k1 k2:int. 0 <= k1 < !j /\ !j+1 <= k2 <= i ->
......@@ -265,9 +264,11 @@ let compare (a:array int) (x y:int) : int
let t = data[!j] in
data[!j] <- data[b];
data[b] <- t;
assert { exchange (at data 'L) data (!j-1) !j };
assert { ArrayPermut.exchange (at data 'L) data (!j-1) !j };
decr j
done
done;
(* needed to prove the invariant [sorted_sub a data.elts 0 i] *)
assert { !j > 0 -> le a data[!j-1] data[!j] }
done
end
......@@ -309,15 +310,14 @@ let select (s:suffixArray) (i:int) : int
use import array.ArrayPermut
(** needed to establish invariant in function [create] *)
lemma permut_permutation :
forall a1 a2:array int.
permut a1 a2 -> permutation a1.elts a1.length -> permutation a2.elts a2.length
lemma permut_permutation : forall a1 a2:array int.
permut a1 a2 /\ permutation a1.elts a1.length ->
permutation a2.elts a2.length
(** constructor of suffixArray structure *)
let create (a:array int) : suffixArray
ensures { result.values = a }
=
let n = a.length in
= let n = a.length in
let suf = Array.make n 0 in
for i = 0 to n-1 do
invariant { forall j:int. 0 <= j < i -> suf[j] = j }
......@@ -329,11 +329,14 @@ let lcp (s:suffixArray) (i:int) : int
requires { 0 < i < s.values.length }
ensures { LCP.is_longest_common_prefix s.values
s.suffixes[i-1] s.suffixes[i] result }
=
LCP.lcp s.values s.suffixes[i] s.suffixes[i-1]
= LCP.lcp s.values s.suffixes[i] s.suffixes[i-1]
end
module SuffixArray_test
use import array.Array
......
This source diff could not be displayed because it is too large. You can view the blob instead.
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