Section permMapDefs.
Definition empty_map : access_map :=
(fun z => None, Maps.PTree.empty (Z -> option permission)).
intros. unfold empty_map, Maps.PMap.get.
rewrite Maps.PTree.gempty; reflexivity.
Qed.
Definition permission_at (m : mem) (b : block) (ofs : Z) (k : perm_kind) :=
Maps.PMap.get b (Mem.mem_access m) ofs k.
(** Coherence between permissions. This is used for the relation between data and lock permissions*)
(** Note: p1 should be data permission and p2 lock permission*)
Definition perm_coh (p1 p2 : option permission) :=
match p1 with
| Some Freeable | Some Writable | Some Readable =>
match p2 with
| None => True
| _ => False
end
| Some Nonempty | None =>
match p2 with
| Some Freeable => False
| _ => True
end
end.
destruct res; simpl; auto.
- apply perm_coh_empty_1.
- destruct k; try apply perm_coh_empty_1; simpl.
destruct (perm_of_sh (Share.glb Share.Rsh sh)) eqn: ?; auto.
destruct p0; auto.
eapply perm_of_glb_not_Freeable; eauto.
Qed.
Definition permMapCoherence (pmap1 pmap2 : access_map) :=
forall b ofs, perm_coh (pmap1 !! b ofs) (pmap2 !! b ofs).
intros r H b ofs.
rewrite empty_map_spec.
specialize (H b ofs).
apply perm_coh_empty_2; assumption.
Qed.
(* Some None represents the empty permission. None is used for permissions that conflict/race. *)
Definition perm_union (p1 p2 : option permission) : option (option permission) :=
match p1,p2 with
| None, _ => Some p2
| _, None => Some p1
| Some p1', Some p2' =>
match p1', p2' with
| Freeable, _ => None
| _, Freeable => None
| Nonempty, _ => Some p2
| _, Nonempty => Some p1
| Writable, _ => None
| _, Writable => None
| Readable, Readable => Some (Some Readable)
end
end.

Lemma perm_union_lower_2:
forall p1 p2 p3 p4
(Hpu: exists pu, perm_union p1 p2 = Some pu)
(Hperm: Mem.perm_order'' p1 p3)
(Hperm': Mem.perm_order'' p2 p4),
exists pu, perm_union p3 p4 = Some pu.