Program Definition approx (n:nat) (p: (pred rmap)) : (pred rmap) :=
fun w => level w < n /\ p w.
Next Obligation.
destruct H0.
split.
apply age_level in H.
simpl in *. omega.
apply pred_hereditary with a; auto.
Qed.

(* Specifications: *)
Lemma unsquash_squash : forall n rm, (unsquash (squash (n,rm))) = (n,rmap_fmap (approx n) rm).
Instance Join_nat_rmap': Join (nat * rmap') := Join_prod _ (Join_equiv nat) _ _.
Lemma fmap_p2p'_inj:
forall p q,
@fmap SM.preds f_preds K.predicate (@pred rmap ag_rmap) p2p' p =
@fmap SM.preds f_preds K.predicate (@pred rmap ag_rmap) p2p' q ->
p=q.
Lemma join_unsquash : forall phi1 phi2 phi3,
join phi1 phi2 phi3 <->
join (unsquash phi1) (unsquash phi2) (unsquash phi3).
Lemma approx_K_approx: approx = K.approx.
Lemma unsquash_squash : forall n rm, (unsquash (squash (n,rm))) = (n,rmap_fmap (approx n) (approx n) rm).
Instance Join_nat_rmap': Join (nat * rmap') := Join_prod _ (Join_equiv nat) _ _.
(* Lemma fmap_p2p'_inj: forall p q, fmap SM.preds K.predicate K.predicate (@pred rmap ag_rmap) p = fmap SM.preds K.predicate K.predicate (@pred rmap ag_rmap) q -> p=q. *)
Lemma g2ghost_inv: forall g1 g2, g2ghost g1 = g2ghost g2 -> g1 = g2.
Lemma join_unsquash : forall phi1 phi2 phi3,
join phi1 phi2 phi3 <->
join (unsquash phi1) (unsquash phi2) (unsquash phi3).
Lemma ghost_of_core : forall phi, ghost_of (core phi) = core (ghost_of phi).
Definition rmap_age1 (k:rmap) : option rmap :=
match unsquash k with
| (O,_) => None
| (S n,x) => Some (squash (n,x))
end.