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.

(* Specifications: *)
Lemma perm_coh_lower: forall p1 p2 p3 p4 (Hpu: perm_coh p1 p2) (Hperm2: Mem.perm_order'' p2 p4) (Hperm1: Mem.perm_order'' p1 p3), perm_coh p3 p4.
Lemma perm_coh_not_freeable: forall p p', perm_coh p p' -> p' <> Some Freeable.
Lemma perm_coh_empty_1: forall p, perm_coh p None.
Lemma perm_coh_empty_2: forall p : option permission, Mem.perm_order'' (Some Writable) p -> perm_coh None p.
Lemma perm_of_glb_not_Freeable: forall sh, ~ perm_of_sh (Share.glb Share.Rsh sh) = Some Freeable.
Lemma perm_coh_self: forall res, perm_coh (perm_of_res res) (perm_of_res_lock res).
Lemma perm_coh_joins: forall a b, joins a b -> perm_coh (perm_of_res a) (perm_of_res_lock b).
Lemma po_join_sub_lock: forall r1 r2 , join_sub r2 r1 -> Mem.perm_order'' (perm_of_res_lock r1) (perm_of_res_lock r2).
Lemma permCoh_empty': forall x, permMapCoherence x empty_map.
Lemma perm_of_res_lock_not_Freeable: forall r, Mem.perm_order'' (Some Writable) (perm_of_res_lock r).