(* methods *)
Definition def h := if h is Def _ _ then true else false.
Definition empty := @Def (finmap.nil _ _) is_true_true.
Definition upd k v h :=
if h is Def hs ns then
if decP (@idP (k != null)) is left pf then
Def (@upd_nullP _ _ v pf ns)
else Undef
else Undef.
Definition dom h : seq ptr :=
if h is Def f _ then supp f else [::].
Definition dom_eq h1 h2 :=
match h1, h2 with
Def f1 _, Def f2 _ => supp f1 == supp f2
| Undef, Undef => true
| _, _ => false
end.
Definition free x h :=
if h is Def hs ns then Def (free_nullP x ns) else Undef.
Definition find (x : ptr) h :=
if h is Def hs _ then fnd x hs else None.
Definition union h1 h2 :=
if (h1, h2) is (Def hs1 ns1, Def hs2 ns2) then
if disj hs1 hs2 then
Def (@un_nullP _ _ ns1 ns2)
else Undef
else Undef.
Definition um_filter q f :=
if f is Def fs pf then Def (@filt_nullP fs q pf) else Undef.
Definition pts (x : ptr) v := upd x v empty.
Definition empb h := if h is Def hs _ then supp hs == [::] else false.
Definition undefb h := if h is Undef then true else false.
Definition keys_of h : seq ptr :=
if h is Def f _ then supp f else [::].
Local Notation base :=
(@UM.base ptr_ordType (dynamic id) (fun k => k != null)).
Definition from (f : heap) : base :=
if f is Def hs ns then UM.Def (heap_base ns) else UM.Undef _ _.
Definition to (b : base) : heap :=
if b is UM.Def hs ns then Def (base_heap ns) else Undef.

(* Specifications: *)
Lemma ftE b : from (to b) = b.
Lemma umfiltE q f : um_filter q f = to (UM.um_filter q (from f)).
Module Exports.