Section selectors.
Variable (j: juicy_mem).
Definition m_dry := match j with mkJuicyMem m _ _ _ _ _ => m end.
Definition m_phi := match j with mkJuicyMem _ phi _ _ _ _ => phi end.
Program Definition age1_juicy_mem (j: juicy_mem): option juicy_mem :=
match age1 (m_phi j) with
| Some phi' => Some (mkJuicyMem (m_dry j) phi' _ _ _ _)
| None => None
end.
Next Obligation.  (* contents_cohere *)
assert (necR (m_phi j) phi')
by (constructor 1; symmetry in Heq_anonymous; apply Heq_anonymous).
destruct j; hnf; simpl in *; intros.
case_eq (phi @ loc); intros.
apply (necR_NO _ _ _ _ _ H) in H1. congruence.
generalize (necR_YES _ _ _ _ _ _ _ H H1); intros.
rewrite H0 in H2. inv H2.
destruct (JMcontents sh0 r v loc _ H1). subst; split; auto.
rewrite (necR_PURE _ _ _ _ _ H H1) in H0. inv H0.
Qed.
Next Obligation. (* access_cohere *)
assert (necR (m_phi j) phi')
by (constructor 1; symmetry in Heq_anonymous; apply Heq_anonymous).
destruct j; hnf; simpl in *; intros.
generalize (JMaccess loc); case_eq (phi @ loc); intros.
apply (necR_NO _ _ loc _ _ H) in H0. rewrite H0; auto.
rewrite (necR_YES _ _ _ _ _ _ _ H H0); auto.
rewrite (necR_PURE _ _ _ _ _ H H0); auto.
Qed.
Next Obligation. (* max_access_cohere *)
assert (necR (m_phi j) phi')
by (constructor 1; symmetry in Heq_anonymous; apply Heq_anonymous).
destruct j; hnf; simpl in *; intros.
generalize (JMmax_access loc); case_eq (phi @ loc); intros.
apply (necR_NO _ _ loc _ _ H) in H0. rewrite H0; auto.
rewrite (necR_YES _ _ _ _ _ _ _ H H0); auto.
rewrite (necR_PURE _ _ _ _ _ H H0); auto.
Qed.
Next Obligation. (* alloc_cohere *)
assert (necR (m_phi j) phi')
by (constructor 1; symmetry in Heq_anonymous; apply Heq_anonymous).
destruct j; hnf; simpl in *; intros.
specialize (JMalloc loc H0).
apply (necR_NO _ _ loc _ _ H). auto.
Qed.

(* TODO: move into rmaps_lemmas *)
Lemma rmap_join_eq_level: forall phi1 phi2: rmap, joins phi1 phi2 -> level phi1 = level phi2.