Commit b7c77790 by 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!