(* returns the proposition generated by a fact *)
Definition eval_fact i f :=
  match f with
  | eqH h1 h2 => interp i h1 = interp i h2
  | eqD d1 d2 => d1 = d2
  | eqX x1 x2 => plook i x1 = plook i x2
  end.Notation pread' x t := (odflt (dyn tt) (pread x t)).Definition pfree x t := filter (predC (ptreq x)) t.Definition hfree h t := filter (predC (vareq h)) t.

(* Specifications: *)
Lemma eval_cons i f s : eval i (f :: s) <-> eval_fact i f /\ eval i s.
Lemma eval_cat i s1 s2 : eval i (s1 ++ s2) <-> eval i s1 /\ eval i s2.
Lemma eval_rcons i f s : eval i (rcons s f) <-> eval i s /\ eval_fact i f.
Lemma pfree_subdom i x t : def (interp i t) -> subdom (interp i (pfree x t)) (interp i t).
Lemma pfree_def i x t: def (interp i t) -> def (interp i (pfree x t)).
Lemma hfree_subdom i h t : def (interp i t) -> {subset dom (interp i (hfree h t)) <= dom (interp i t)}.
Lemma hfree_subdom' i h t : def (interp i t) -> subdom (interp i (hfree h t)) (interp i t).
Lemma hfree_def i h t : def (interp i t) -> def (interp i (hfree h t)).
Lemma count0_hfree v t: count (pred1 v) (vars t) = 0 -> hfree v t = t.
Lemma count1_hfree v t : count (pred1 v) (vars t) = 1 -> perm (Var v :: hfree v t) t.
Lemma countN_varfree i v t : count (pred1 v) (vars t) > 1 -> def (interp i t) -> hlook i v = Some empty.
Lemma empty_hfree i v t : hlook i v = Some empty -> interp i (hfree v t) = interp i t.
Lemma lookR i t x : def (interp i t) -> has (ptreq x) t -> look (plook' i x) (interp i t) = pread' x t.
Lemma defR i t : def (interp i t) -> uniq (ptrs t).
Lemma freeR i t x : def (interp i t) -> has (ptreq x) t -> free (plook' i x) (interp i t) = interp i (pfree x t).
Lemma cancel_sound' i sh1 sh2 unm fs : interp i sh2 = interp i (sh1 ++ unm) -> def (interp i sh2) -> eval i fs -> eval i (cancel' i sh1 sh2 unm fs).
Lemma cancel_sound i t1 t2 : def (interp i t1) -> interp i t1 = interp i t2 -> eval i (cancel i t1 t2).