Module LO := FMapList.Make_ord(X)(D).
Definition t := MapS.t D.t.
Definition cmp e e' :=
match D.compare e e' with EQ _ => true | _ => false end.
Definition elements (m:t) :=
LO.MapS.Build_slist (Raw.Proofs.elements_sort (is_bst m)).
(** * As comparison function, we propose here a non-structural version faithful to the code of Ocaml's Map library, instead of the structural version of FMapAVL *)
Fixpoint cardinal_e (e:Raw.enumeration D.t) :=
match e with
| Raw.End _ => 0%nat
| Raw.More _ _ r e => S (Raw.cardinal r + cardinal_e e)
end.
Definition cardinal_e_2 ee :=
(cardinal_e (fst ee) + cardinal_e (snd ee))%nat.
Local Unset Keyed Unification.
Function compare_aux (ee:Raw.enumeration D.t * Raw.enumeration D.t)
{ measure cardinal_e_2 ee } : comparison :=
match ee with
| (Raw.End _, Raw.End _) => Eq
| (Raw.End _, Raw.More _ _ _ _) => Lt
| (Raw.More _ _ _ _, Raw.End _) => Gt
| (Raw.More x1 d1 r1 e1, Raw.More x2 d2 r2 e2) =>
match X.compare x1 x2 with
| EQ _ => match D.compare d1 d2 with
| EQ _ => compare_aux (Raw.cons r1 e1, Raw.cons r2 e2)
| LT _ => Lt
| GT _ => Gt
end
| LT _ => Lt
| GT _ => Gt
end
end.
Hint Resolve cons_Cmp : core.
Definition eq (m1 m2 : t) := LO.eq_list (Raw.elements m1) (Raw.elements m2).
Definition lt (m1 m2 : t) := LO.lt_list (Raw.elements m1) (Raw.elements m2).
Definition compare (s s':t) : Compare lt eq s s'.

Lemma eq_sym : forall m1 m2 : t, eq m1 m2 -> eq m2 m1.