(* the three projections from defPtUn are often useful *)

(* Specifications: *)
Lemma defPt_null A h x (v : A) : def (x :-> v :+ h) -> x != null.
(* look and free *)
Lemma lookPtUn A h x (v : A) :
def (x :-> v :+ h) -> look x (x :-> v :+ h) = dyn v.
Lemma freePtUn A h x (v : A) :
def (x :-> v :+ h) -> free x (x :-> v :+ h) = h.
Lemma updPtUn A1 A2 x i (v1 : A1) (v2 : A2) :
upd (x :-> v1 :+ i) x (dyn v2) = x :-> v2 :+ i.
Lemma heap_etaP h x : x \in dom h -> h = x :-> Dyn.val (look x h) :+ free x h.
Lemma cancelT A1 A2 h1 h2 x (v1 : A1) (v2 : A2) :
def (x :-> v1 :+ h1) ->
x :-> v1 :+ h1 = x :-> v2 :+ h2 -> A1 = A2.
Lemma cancel A h1 h2 x (v1 v2 : A) :
def (x :-> v1 :+ h1) ->
x :-> v1 :+ h1 = x :-> v2 :+ h2 -> [/\ v1 = v2, def h1 & h1 = h2].
Lemma domPtUnX A (v : A) x i : def (x :-> v :+ i) -> x \in dom (x :-> v :+ i).
Lemma updi_cat x vs1 vs2 :
updi x (vs1 ++ vs2) = updi x vs1 :+ updi x.+(size vs1) vs2.
Lemma updi_catI x y vs1 vs2 :
y = x.+(size vs1) -> updi x vs1 :+ updi y vs2 = updi x (vs1 ++ vs2).
Lemma updiD x xs : def (updi x xs) = (x != null) || (size xs == 0).
Lemma updiVm x m xs :
x \in dom (updi x.+m xs) = [&& x != null, m == 0 & size xs > 0].
Lemma updimV x m xs :
x.+m \in dom (updi x xs) = (x != null) && (m < size xs).
Lemma updiP x y xs :
reflect (y != null /\ exists m, x = y.+m /\ m < size xs)
(x \in dom (updi y xs)).
(* Invertibility *)
Lemma updi_inv x xs1 xs2 :
def (updi x xs1) -> updi x xs1 = updi x xs2 -> xs1 = xs2.
Lemma updi_iinv x xs1 xs2 h1 h2 :
size xs1 = size xs2 -> def (updi x xs1 :+ h1) ->
updi x xs1 :+ h1 = updi x xs2 :+ h2 -> xs1 = xs2 /\ h1 = h2.