Section Elt.
Variable elt : Type.
Notation eqk := (eqk (elt:=elt)).
Notation eqke := (eqke (elt:=elt)).
Notation ltk := (ltk (elt:=elt)).
Notation MapsTo := (MapsTo (elt:=elt)).
Notation In := (In (elt:=elt)).
Notation Sort := (sort ltk).
Notation Inf := (lelistA (ltk)).
(** * [empty] *)
Definition empty : t elt := nil.
Definition Empty m := forall (a : key)(e:elt) , ~ MapsTo a e m.
Hint Resolve empty_1 : core.
(** * [is_empty] *)
Definition is_empty (l : t elt) : bool := if l then true else false.
(** * [mem] *)
Function mem (k : key) (s : t elt) {struct s} : bool :=
match s with
| nil => false
| (k',_) :: l =>
match X.compare k k' with
| LT _ => false
| EQ _ => true
| GT _ => mem k l
end
end.
(** * [find] *)
Function find (k:key) (s: t elt) {struct s} : option elt :=
match s with
| nil => None
| (k',x)::s' =>
match X.compare k k' with
| LT _ => None
| EQ _ => Some x
| GT _ => find k s'
end
end.
(** * [add] *)
Function add (k : key) (x : elt) (s : t elt) {struct s} : t elt :=
match s with
| nil => (k,x) :: nil
| (k',y) :: l =>
match X.compare k k' with
| LT _ => (k,x)::s
| EQ _ => (k,x)::l
| GT _ => (k',y) :: add k x l
end
end.
Hint Resolve add_Inf : core.
(** * [remove] *)
Function remove (k : key) (s : t elt) {struct s} : t elt :=
match s with
| nil => nil
| (k',x) :: l =>
match X.compare k k' with
| LT _ => s
| EQ _ => l
| GT _ => (k',x) :: remove k l
end
end.
Hint Resolve remove_Inf : core.
(** * [elements] *)
Definition elements (m: t elt) := m.
(** * [fold] *)
Function fold (A:Type)(f:key->elt->A->A)(m:t elt) (acc:A) {struct m} :  A :=
match m with
| nil => acc
| (k,e)::m' => fold f m' (f k e acc)
end.
(** * [equal] *)
Function equal (cmp:elt->elt->bool)(m m' : t elt) {struct m} : bool :=
match m, m' with
| nil, nil => true
| (x,e)::l, (x',e')::l' =>
match X.compare x x' with
| EQ _ => cmp e e' && equal cmp l l'
| _    => false
end
| _, _ => false
end.
Definition Equivb cmp m m' :=
(forall k, In k m <-> In k m') /\
(forall k e e', MapsTo k e m -> MapsTo k e' m' -> cmp e e' = true).

Lemma equal_1 : forall m (Hm:Sort m) m' (Hm': Sort m') cmp,
Equivb cmp m m' -> equal cmp m m' = true.