(** ** Elements *)

(* Specifications: *)
Lemma elements_spec1' : forall s acc x,
InA X.eq x (elements_aux acc s) <-> InT x s \/ InA X.eq x acc.
Lemma elements_spec1 : forall s x, InA X.eq x (elements s) <-> InT x s.
Lemma elements_spec2' : forall s acc `{Ok s}, sort X.lt acc ->
(forall x y : elt, InA X.eq x acc -> InT y s -> X.lt y x) ->
sort X.lt (elements_aux acc s).
Lemma elements_spec2 : forall s `(Ok s), sort X.lt (elements s).
Local Hint Resolve elements_spec2 : core.
Lemma elements_spec2w : forall s `(Ok s), NoDupA X.eq (elements s).
Lemma elements_aux_cardinal :
forall s acc, (length acc + cardinal s)%nat = length (elements_aux acc s).
Lemma elements_cardinal : forall s : tree, cardinal s = length (elements s).
Definition cardinal_spec (s:tree)(Hs:Ok s) := elements_cardinal s.
Lemma elements_app :
forall s acc, elements_aux acc s = elements s ++ acc.
Lemma elements_node c l x r :
elements (Node c l x r) = elements l ++ x :: elements r.
Lemma rev_elements_app :
forall s acc, rev_elements_aux acc s = rev_elements s ++ acc.
Lemma rev_elements_node c l x r :
rev_elements (Node c l x r) = rev_elements r ++ x :: rev_elements l.
Lemma rev_elements_rev s : rev_elements s = rev (elements s).
(** The converse of [elements_spec2], used in MSetRBT *)
(* TODO: TO MIGRATE ELSEWHERE... *)
Lemma sorted_app_inv l1 l2 :
sort X.lt (l1++l2) ->
sort X.lt l1 /\ sort X.lt l2 /\
forall x1 x2, InA X.eq x1 l1 -> InA X.eq x2 l2 -> X.lt x1 x2.
Lemma elements_sort_ok s : sort X.lt (elements s) -> Ok s.
(** ** [for_all] and [exists] *)
Lemma for_all_spec s f : Proper (X.eq==>eq) f ->
(for_all f s = true <-> For_all (fun x => f x = true) s).
Lemma exists_spec s f : Proper (X.eq==>eq) f ->
(exists_ f s = true <-> Exists (fun x => f x = true) s).