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