Module NMap := IMap(NIndexed).
(** * An implementation of maps over any type with decidable equality *)
Module Type EQUALITY_TYPE.
Parameter t: Type.
Parameter eq: forall (x y: t), {x = y} + {x <> y}.
End EQUALITY_TYPE.
Module EMap(X: EQUALITY_TYPE) <: MAP.
Definition elt := X.t.
Definition elt_eq := X.eq.
Definition t (A: Type) := X.t -> A.
Definition init (A: Type) (v: A) := fun (_: X.t) => v.
Definition get (A: Type) (x: X.t) (m: t A) := m x.
Definition set (A: Type) (x: X.t) (v: A) (m: t A) :=
fun (y: X.t) => if X.eq y x then v else m y.

(* Specifications: *)
Lemma gi:
forall (A: Type) (i: elt) (x: A), init x i = x.
Lemma gss:
forall (A: Type) (i: elt) (x: A) (m: t A), (set i x m) i = x.
Lemma gso:
forall (A: Type) (i j: elt) (x: A) (m: t A),
i <> j -> (set j x m) i = m i.
Lemma gsspec:
forall (A: Type) (i j: elt) (x: A) (m: t A),
get i (set j x m) = if elt_eq i j then x else get i m.
Lemma gsident:
forall (A: Type) (i j: elt) (m: t A), get j (set i (get i m) m) = get j m.
Lemma gi:
forall (A: Type) (i: elt) (x: A), init x i = x.
Lemma gss:
forall (A: Type) (i: elt) (x: A) (m: t A), (set i x m) i = x.
Lemma gso:
forall (A: Type) (i j: elt) (x: A) (m: t A),
i <> j -> (set j x m) i = m i.
Lemma gsspec:
forall (A: Type) (i j: elt) (x: A) (m: t A),
get i (set j x m) = if elt_eq i j then x else get i m.
Lemma gsident:
forall (A: Type) (i j: elt) (m: t A), get j (set i (get i m) m) = get j m.