(****************)
(* main methods *)
(****************)

Definition def h := if h is Def _ _ then true else false.Definition empty := @Def (finmap.nil _ _) is_true_true.Definition dom h : pred ptr := nosimpl
  (if h is Def f _ then mem (supp f) else pred0).Definition free x h : heap :=
  (if h is Def hs ns then Def (free_nullP x ns) else Undef).Definition look (x : ptr) h :=
  (if h is Def hs _ then
    if fnd x hs is Some d then d else dyn tt
  else dyn tt).Definition union2 h1 h2 := nosimpl
  (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 subheap h1 h2 p :=  *)
(*   if (h1, h2) is (Def hs1 _, Def hs2 _) then  *)
(*     all (fun x => p (look x h1) (look x h2)) (supp hs1) *)
(*   else false. *)

Definition subtract h1 h2 :=
  if h1 is (Def hs1 _) then
    foldl (fun h x => free x h) h2 (supp hs1)
  else Undef.Definition pick h :=
  if h is Def hs _ then head null (supp hs) else null.Definition pts A (x : ptr) (v : A) := upd empty x (dyn v).Notation "h1 :+ h2" := (union2 h1 h2) (at level 43, left associativity).Notation "h2 :- h1" := (subtract h1 h2) (at level 43, left associativity).Notation "x :-> v" := (pts x v) (at level 30).

(* Specifications: *)
Lemma dom0 : dom empty = pred0.
Lemma def0 : def empty.
Lemma defF h x : def (free x h) = def h.
Lemma undefE x : ~~ def x <-> x = Undef.
Lemma free0 x : free x empty = empty.
Lemma empP h : reflect (h = empty) (empb h).
Lemma empU h x d : empb (upd h x d) = false.
Lemma empbE h : h = empty <-> empb h.
Lemma path_filter (A : ordType) (s : seq A) (p : pred A) x : path ord x s -> path ord x (filter p s).
Lemma subdom_def h1 h2 : subdom h1 h2 -> def h1 && def h2.
Lemma subdom_refl h : def h -> subdom h h.
Lemma subdom_emp h : def h -> subdom empty h.
Lemma subdom_emp_inv h : subdom h empty -> h = empty.
Lemma subdom_trans h2 h1 h3 : subdom h1 h2 -> subdom h2 h3 -> subdom h1 h3.
Lemma subheap_refl h : def h -> subheap h h.
Lemma subheapE h : def h -> subheap empty h.
Lemma subheap_def h1 h2 : subheap h1 h2 -> def h1 /\ def h2.
Lemma subheap_trans h2 h1 h3 : subheap h1 h2 -> subheap h2 h3 -> subheap h1 h3.
Lemma subheap_id hp1 hp2: subheap hp1 hp2 -> subheap hp2 hp1 -> hp1 = hp2.
Lemma updi_inv x xs1 xs2 : def (updi x xs1) -> updi x xs1 = updi x xs2 -> xs1 = xs2.
Lemma last_inv A B (f : A -> B) (x1 x2 : A) (h : seq A) : f x1 = f x2 -> f (last x1 h) = f (last x2 h).
Lemma hlE x : high x = ~~ low x.
Lemma lhE x : low x = ~~ high x.