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).

Lemma lastkey_undef : last_key um_undef = 0.