(** * Properties of string comparison *)

(* Specifications: *)
Lemma char63_compare_refl (c1 c2 : char63) :
char63_compare c1 c2 = Eq <-> c1 = c2.
Lemma char63_compare_antisym (c1 c2 : char63) :
char63_compare c2 c1 = CompOpp (char63_compare c1 c2).
Lemma char63_compare_trans (c1 c2 c3 : char63) (c : comparison) :
char63_compare c1 c2 = c -> char63_compare c2 c3 = c -> char63_compare c1 c3 = c.
Lemma compare_refl (s : string) : compare s s = Eq.
Lemma compare_antisym (s1 s2 : string) :
compare s2 s1 = CompOpp (compare s1 s2).
Lemma compare_trans (c : comparison) (s1 s2 s3 : string) :
compare s1 s2 = c -> compare s2 s3 = c -> compare s1 s3 = c.
Lemma compare_eq_correct (s1 s2 : string) :
compare s1 s2 = Eq -> s1 = s2.
Lemma string_eq_ext (s1 s2 : string) :
(length s1 = length s2 /\
forall i, to_Z i < to_Z (length s1) -> get s1 i = get s2 i) ->
s1 = s2.
Lemma to_list_firstn_skipn_middle (s : string) (i : int) :
to_Z i < to_Z (length s) ->
to_list s = List.firstn (to_nat i) (to_list s) ++
get s i :: List.skipn (to_nat (i + 1)) (to_list s).
Lemma compare_spec (s1 s2 : string) (c : comparison) :
compare s1 s2 = c <->
exists i,
to_Z i <= to_Z (length s1) /\
to_Z i <= to_Z (length s2) /\
(forall j, to_Z j < to_Z i -> get s1 j = get s2 j) /\
match (i =? length s1, i =? length s2)%uint63 with
| (true , true ) => c = Eq
| (true , false) => c = Lt
| (false, true ) => c = Gt
| (false, false) =>
match Uint63.compare (get s1 i) (get s2 i) with
| Eq => False
| ci => c = ci
end
end.
Lemma compare_eq (s1 s2 : string) : compare s1 s2 = Eq <-> s1 = s2.
(** * Properties of make *)
Lemma make_0 (c : char63) : make 0 c = ""%pstring.
(** * Properties of cat *)
Lemma length_0_empty (s : string) : length s = 0%uint63 -> s = ""%pstring.
Lemma cat_empty_l (s : string) : cat ""%pstring s = s.
Lemma cat_empty_r (s : string) : cat s ""%pstring = s.
Lemma cat_assoc (s1 s2 s3 : string) :
cat (cat s1 s2) s3 = cat s1 (cat s2 s3).