End AvlProofs.
(** * Encapsulation  We can implement [S] with balanced binary search trees. When compared to [FMapAVL], we maintain here two invariants (bst and avl) instead of only bst, which is enough for fulfilling the FMap interface. *)
Module IntMake (I:Int)(X: OrderedType) <: S with Module E := X.
Module E := X.
Module Import AvlProofs := AvlProofs I X.
#[universes(template)]
Record bbst (elt:Type) :=
Bbst {this :> tree elt; is_bst : bst this; is_avl: avl this}.
Definition t := bbst.
Definition key := E.t.
Section Elt.
Variable elt elt' elt'': Type.
Implicit Types m : t elt.
Implicit Types x y : key.
Implicit Types e : elt.
Definition empty : t elt := Bbst (empty_bst elt) (empty_avl elt).
Definition is_empty m : bool := is_empty (this m).
Definition add x e m : t elt :=
Bbst (add_bst x e (is_bst m)) (add_avl x e (is_avl m)).
Definition remove x m : t elt :=
Bbst (remove_bst x (is_bst m)) (remove_avl x (is_avl m)).
Definition mem x m : bool := mem x (this m).
Definition find x m : option elt := find x (this m).
Definition map f m : t elt' :=
Bbst (map_bst f (is_bst m)) (map_avl f (is_avl m)).
Definition mapi (f:key->elt->elt') m : t elt' :=
Bbst (mapi_bst f (is_bst m)) (mapi_avl f (is_avl m)).
Definition map2 f m (m':t elt') : t elt'' :=
Bbst (map2_bst f (is_bst m) (is_bst m')) (map2_avl f (is_avl m) (is_avl m')).
Definition elements m : list (key*elt) := elements (this m).
Definition cardinal m := cardinal (this m).
Definition fold (A:Type) (f:key->elt->A->A) m i := fold (A:=A) f (this m) i.
Definition equal cmp m m' : bool := equal cmp (this m) (this m').
Definition MapsTo x e m : Prop := MapsTo x e (this m).
Definition In x m : Prop := In0 x (this m).
Definition Empty m : Prop := Empty (this m).
Definition eq_key : (key*elt) -> (key*elt) -> Prop := @PX.eqk elt.
Definition eq_key_elt : (key*elt) -> (key*elt) -> Prop := @PX.eqke elt.
Definition lt_key : (key*elt) -> (key*elt) -> Prop := @PX.ltk elt.

Lemma elements_3 : forall m, sort lt_key (elements m).