(** DepMap: Maps with explicit domain contained in their type *)
Set Implicit Arguments.
(******************************************************************************)
(** **  Implementation of maps with explicit domain contained in their type  **)
(******************************************************************************)
Module DepMapImpl (X : OrderedType) : (DepMap X) with Definition key := X.t.
(** The type of domains **)
Module Dom := MSetAVL.Make(X).
Module Ddec := Decide(Dom).
Module DProp := EqProperties(Dom).
Ltac fsetdec := Ddec.fsetdec.
(** The type of maps over this domain **)
Module XOT := OTconvert X.
Module S := FMapList.Make(XOT).
(** The type of dependent maps **)
Definition key := X.t.
Definition OK {A} dom (map : S.t A) := ∀ x, S.In x map <-> Dom.In x dom.
Definition t := fun A dom => { map : S.t A | OK dom map}.
Instance OK_compat A : Proper (Dom.eq ==> @S.Equal A ==> iff) OK.
(** ***  Operations on maps **)

(** The empty map. **)
Lemma empty_OK : forall A, OK Dom.empty (S.empty A).
Definition empty : forall A, t A Dom.empty := fun A => exist (OK Dom.empty) (@S.empty A) (empty_OK A).