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.
Instance juicy_mem_ageable: ageable juicy_mem :=
mkAgeable _ (fun j => level (m_phi j)) age1_juicy_mem juicy_mem_ageable_facts.
(* resource coherence *)
(* FIXME: put somewhere else. *)
Definition fmap_option {A B} (v: option A) (m: B) (f: A -> B): B :=
match v with
| None => m
| Some v' => f v'
end.
refine (fun f g lev H Hg => match proj2_sig (make_rmap f g lev H Hg) with
| conj _ (conj RESOURCE_AT _) => RESOURCE_AT
end).
Qed.
refine (fun f g lev H Hg => match proj2_sig (remake_rmap f g lev H Hg) with
| conj _ (conj RESOURCE_AT _) => RESOURCE_AT
end).
Qed.
refine (fun f g lev H Hg => match proj2_sig (make_rmap f g lev H Hg) with
| conj _ (conj _ RESOURCE_AT) => RESOURCE_AT
end).
Qed.
refine (fun f g lev H Hg => match proj2_sig (remake_rmap f g lev H Hg) with
| conj _ (conj _ RESOURCE_AT) => RESOURCE_AT
end).
Qed.
refine (fun f g lev H Hg => match proj2_sig (make_rmap f g lev H Hg) with
| conj LEVEL _ => LEVEL
end).
Qed.

Lemma level_remake_rmap: forall f g lev H Hg, @level rmap _ (proj1_sig (remake_rmap f g lev H Hg)) = lev.