Section initial_mem.
Variables (m: mem) (w: rmap).
Definition initial_rmap_ok :=
forall loc, ((fst loc >= nextblock m)%positive -> core w @ loc = NO Share.bot bot_unreadable) /\
(match w @ loc with
| PURE _ _ => (fst loc < nextblock m)%positive /\
access_at m loc Cur = Some Nonempty /\
max_access_at m loc = Some Nonempty
| _ => True end).
Hypothesis IOK: initial_rmap_ok.
End initial_mem.
Definition empty_retainer (loc: address) := Share.bot.
Definition initial_mem (m: mem) lev (IOK: initial_rmap_ok m lev) : juicy_mem.
refine (mkJuicyMem m  (inflate_initial_mem m lev) _ _ _ _);
unfold inflate_initial_mem, inflate_initial_mem';
hnf; intros;  try rewrite resource_at_make_rmap in *.
* (* contents_cohere *)
revert H; case_eq (access_at m loc Cur); intros.
destruct p; inv H0; auto.
revert H2; case_eq (lev @ loc); intros; congruence.
destruct (max_access_at m loc); try destruct p; try congruence.
* (* access_cohere *)
symmetry.
destruct (access_at m loc) eqn:?; try destruct p; auto; simpl.
apply perm_of_freeable.
apply perm_of_Ews.
apply perm_of_Ers.
destruct (IOK loc).
destruct (lev @ loc).
simpl; rewrite if_false by apply extern_retainer_neq_bot; auto.
simpl; rewrite if_false by apply extern_retainer_neq_bot; auto.
reflexivity.
rewrite if_true; auto.
* (* max_access_cohere *)
{ generalize (perm_cur_max m (fst loc) (snd loc)); unfold perm; intros.
case_eq (access_at m loc Cur); try destruct p; intros.
- unfold perm_order'', perm_order', max_access_at in *.
simpl; rewrite perm_of_freeable.
apply H.
unfold access_at in H0. rewrite H0. constructor.
- simpl. rewrite perm_of_Ews.
unfold perm_order'', perm_order', max_access_at, access_at in *.
rewrite H0 in *.
specialize (H Writable). spec H. constructor.
apply H.
- simpl. rewrite perm_of_Ers.
unfold perm_order'', perm_order', max_access_at, access_at in *.
rewrite H0 in *.
apply H. constructor.
- destruct (IOK loc).
eapply perm_order''_trans; [apply (access_max m (fst loc) (snd loc))|].
unfold access_at in H0; rewrite H0.
destruct (lev @ loc) ; simpl;
try destruct (@eq_dec Share.t Share.EqDec_share extern_retainer Share.bot); try constructor.
- simpl. destruct (eq_dec Share.bot Share.bot) as [e|n]; [| exfalso; apply n; reflexivity].
rewrite <- H0.
apply (access_max m).
}
* (* alloc_cohere *)
unfold access_at.
unfold block; rewrite (nextblock_noaccess m (fst loc) (snd loc) Cur); auto.
Defined.
Definition juicy_mem_level (j: juicy_mem) (lev: nat) :=
level (m_phi j) = lev.

Lemma perm_mem_access: forall m b ofs p,
perm m b ofs Cur p ->
exists p', (perm_order p' p /\ access_at m (b, ofs) Cur = Some p').