Notation natmap := NMDef.tp.Definition natmapMixin A := 
  UMCMixin (@NMDef.ftE A) (@NMDef.tfE A) (@NMDef.defE A) 
           (@NMDef.undefE A) (@NMDef.emptyE A) (@NMDef.updE A) 
           (@NMDef.domE A) (@NMDef.dom_eqE A) (@NMDef.freeE A)
           (@NMDef.findE A) (@NMDef.unionE A) (@NMDef.nmfiltE A)
           (@NMDef.empbE A) (@NMDef.undefbE A) (@NMDef.ptsE A).Canonical nat_mapUMC A := 
  Eval hnf in UMC (natmap A) (@natmapMixin A).(* we add the canonical projections matching against naked type *)
(* thus, there are two ways to get a PCM for a union map: *)
(* generic one going through union_map_classPCM, and another by going *)
(* through union_mapPCM. Luckily, they produce equal results *)
(* and this is just a matter of convenience *)
(* Ditto for the equality type *)

Definition nat_mapPCMMix A := union_map_classPCMMix (nat_mapUMC A).Canonical nat_mapPCM A := Eval hnf in PCM (natmap A) (@nat_mapPCMMix A).Definition nat_mapCPCMMix A := union_map_classCPCMMix (nat_mapUMC A).Canonical nat_mapCPCM A := Eval hnf in CPCM (natmap A) (@nat_mapCPCMMix A).Definition nat_mapTPCMMix A := union_map_classTPCMMix (nat_mapUMC A).Canonical nat_mapTPCM A := Eval hnf in TPCM (natmap A) (@nat_mapTPCMMix A).Definition nat_map_eqMix (A : eqType) := 
  @union_map_class_eqMix nat_ordType A _ _ (@natmapMixin A).Canonical nat_map_eqType (A : eqType) := 
  Eval hnf in EqType (natmap A) (@nat_map_eqMix A).Definition nm_pts A (k : nat) (v : A) := 
  @UMC.pts nat_ordType A (@nat_mapUMC A) k v.Notation "x \-> v" := (@nm_pts _ x v) (at level 30).Implicit Type h : natmap (A * A).Definition last_key h := last 0 (dom h).

(* Specifications: *)
Lemma lastkey_undef : last_key um_undef = 0.
Lemma lastkey0 : last_key Unit = 0.
Lemma lastkey_dom h : valid h -> last_key h \notin dom h -> h = Unit.
Lemma dom_lastkey h : valid h -> ~~ empb h -> last_key h \in dom h.
Lemma lastkeyxx h : valid h -> last_key h = 0 -> h = Unit.
Lemma dom_lastkeyE h a : a < last_key h -> last_key h \in dom h.
Lemma lastkey_max h x : x \in dom h -> x <= last_key h.
Lemma max_lastkey h x : x \in dom h -> {in dom h, forall y, y <= x} -> last_key h = x.
Lemma hist_path h : path oleq 0 (dom h).
Lemma lastkey_mono h1 h2 : {subset dom h1 <= dom h2} -> last_key h1 <= last_key h2.
Lemma dom_ordfresh h x : x \in dom h -> x < fresh h.
Lemma dom_freshn h n : fresh h + n \notin dom h.
Lemma dom_fresh h : fresh h \notin dom h.