(** or it wasn't and the operation denoted by the event implies the permission*)
(** *** Properties about permission decay and events *)

(* Specifications: *)
(** Permission decrease: A thread can decrease its data permissions by: - Freeing memory. - Spawning a thread - A makelock operation, turning data into lock - Releasing a lock *)
Lemma data_permission_decrease_step:
forall U tr tp m U' tp' m' tr' tidn b ofs
(cnt: containsThread tp tidn)
(cnt': containsThread tp' tidn)
(Hstep: MachStep (U, tr, tp) m (U', tr ++ tr', tp') m')
(Hperm: Mem.perm_order'' ((getThreadR cnt).1 !! b ofs) (Some Readable))
(Hperm': ~ Mem.perm_order'' ((getThreadR cnt').1 !! b ofs) (Some Readable)),
exists ev,
(List.In ev tr' /\ action ev = Free /\ deadLocation tp' m' b ofs) \/
(tr' = [:: ev] /\ action ev = Spawn) \/
(tr' = [:: ev] /\ action ev = Mklock /\
thread_id ev = tidn /\
match location ev with
| Some (addr, sz) =>
b = addr.1 /\
Intv.In ofs (addr.2, addr.2 + (Z.of_nat sz))%Z
| None =>
False
end) \/
(tr' = [:: ev] /\ action ev = Release /\ thread_id ev = tidn /\
exists rmap, match location ev with
| Some (laddr, sz) =>
sz = lksize.LKSIZE_nat /\
lockRes tp' laddr = Some rmap /\
Mem.perm_order'' (rmap.1 !! b ofs) (Some Readable)
| None => False
end).
(** Lifting [data_permission_decrease_step] to multiple steps using [multi_step] *)
Lemma data_permission_decrease_execution:
forall U tr tpi mi U' tr' tpj mj
b ofs tidn
(cnti: containsThread tpi tidn)
(cntj: containsThread tpj tidn)
(Hexec: multi_step (U, tr, tpi) mi (U', tr ++ tr', tpj) mj)
(Hperm: Mem.perm_order'' ((getThreadR cnti).1 !! b ofs) (Some Readable))
(Hperm: ~ Mem.perm_order'' ((getThreadR cntj).1 !! b ofs) (Some Readable)),
exists tr_pre tru U'' U''' tp_pre m_pre tp_dec m_dec,
multi_step (U, tr, tpi) mi (U'', tr ++ tr_pre, tp_pre) m_pre /\
MachStep (U'', tr ++ tr_pre, tp_pre) m_pre
(U''', tr ++ tr_pre ++ tru, tp_dec) m_dec /\
multi_step (U''', tr ++ tr_pre ++ tru, tp_dec) m_dec
(U', tr ++ tr',tpj) mj /\
(exists evu,
(List.In evu tru /\ action evu = Free /\ deadLocation tpj mj b ofs) \/
(tru = [:: evu] /\ action evu = Spawn) \/
(tru = [:: evu] /\ action evu = Mklock /\ thread_id evu = tidn /\
match location evu with
| Some (addr, sz) =>
b = addr.1 /\
Intv.In ofs (addr.2, addr.2 + (Z.of_nat sz))%Z
| None => False
end) \/
(tru = [:: evu] /\ action evu = Release /\ thread_id evu = tidn /\
(exists rmap, match location evu with
| Some (laddr, sz) =>
sz = lksize.LKSIZE_nat /\
lockRes tp_dec laddr = Some rmap /\
Mem.perm_order'' (rmap.1 !! b ofs) (Some Readable)
| None => False
end))).
(** Permission decrease: A thread can decrease its lock permissions by: - Spawning a thread - A freelock operation, turning a lock into data - Releasing a lock *)
Lemma lock_permission_decrease_step:
forall U tr tp m U' tp' m' tr' tidn b ofs
(cnt: containsThread tp tidn)
(cnt': containsThread tp' tidn)
(Hstep: MachStep (U, tr, tp) m (U', tr ++ tr', tp') m')
(Hperm: Mem.perm_order'' ((getThreadR cnt).2 !! b ofs) (Some Readable))
(Hperm': ~ Mem.perm_order'' ((getThreadR cnt').2 !! b ofs) (Some Readable)),
exists ev,
(List.In ev tr' /\ action ev = Free /\ deadLocation tp' m' b ofs) \/
(tr' = [:: ev] /\ action ev = Spawn) \/
(tr' = [:: ev] /\ action ev = Freelock /\
thread_id ev = tidn /\
match location ev with
| Some (addr, sz) =>
b = addr.1 /\
Intv.In ofs (addr.2, addr.2 + (Z.of_nat sz))%Z
| None =>
False
end) \/
(tr' = [:: ev] /\ action ev = Release /\ thread_id ev = tidn /\
exists rmap, match location ev with
| Some (laddr, sz) =>
sz = lksize.LKSIZE_nat /\
lockRes tp' laddr = Some rmap /\
Mem.perm_order'' (rmap.2 !! b ofs) (Some Readable)
| None => False
end).
(** Lifting [lock_permission_decrease_step] to multiple steps using [multi_step] *)
Lemma lock_permission_decrease_execution:
forall U tr tpi mi U' tr' tpj mj
b ofs tidn
(cnti: containsThread tpi tidn)
(cntj: containsThread tpj tidn)
(Hexec: multi_step (U, tr, tpi) mi (U', tr ++ tr', tpj) mj)
(Hperm: Mem.perm_order'' ((getThreadR cnti).2 !! b ofs) (Some Readable))
(Hperm: ~ Mem.perm_order'' ((getThreadR cntj).2 !! b ofs) (Some Readable)),
exists tr_pre tru U'' U''' tp_pre m_pre tp_dec m_dec,
multi_step (U, tr, tpi) mi (U'', tr ++ tr_pre, tp_pre) m_pre /\
MachStep (U'', tr ++ tr_pre, tp_pre) m_pre
(U''', tr ++ tr_pre ++ tru, tp_dec) m_dec /\
multi_step (U''', tr ++ tr_pre ++ tru, tp_dec) m_dec
(U', tr ++ tr',tpj) mj /\
(exists evu,
(List.In evu tru /\ action evu = Free /\ deadLocation tpj mj b ofs) \/
(tru = [:: evu] /\ action evu = Spawn) \/
(tru = [:: evu] /\ action evu = Freelock /\ thread_id evu = tidn /\
match location evu with
| Some (addr, sz) =>
b = addr.1 /\
Intv.In ofs (addr.2, addr.2 + (Z.of_nat sz))%Z
| None => False
end) \/
(tru = [:: evu] /\ action evu = Release /\ thread_id evu = tidn /\
(exists rmap, match location evu with
| Some (laddr, sz) =>
sz = lksize.LKSIZE_nat /\
lockRes tp_dec laddr = Some rmap /\
Mem.perm_order'' (rmap.2 !! b ofs) (Some Readable)
| None => False
end))).
Lemma permission_decrease_execution:
forall U tr tpi mi U' tr' tpj mj
b ofs tidn
(cnti: containsThread tpi tidn)
(cntj: containsThread tpj tidn)
(Hexec: multi_step (U, tr, tpi) mi (U', tr ++ tr', tpj) mj)
(Hperm: (Mem.perm_order'' ((getThreadR cnti).1 !! b ofs) (Some Readable) /\
~ Mem.perm_order'' ((getThreadR cntj).1 !! b ofs) (Some Readable)) \/
(Mem.perm_order'' ((getThreadR cnti).2 !! b ofs) (Some Readable) /\
~ Mem.perm_order'' ((getThreadR cntj).2 !! b ofs) (Some Readable))),
exists tr_pre tru U'' U''' tp_pre m_pre tp_dec m_dec,
multi_step (U, tr, tpi) mi (U'', tr ++ tr_pre, tp_pre) m_pre /\
MachStep (U'', tr ++ tr_pre, tp_pre) m_pre
(U''', tr ++ tr_pre ++ tru, tp_dec) m_dec /\
multi_step (U''', tr ++ tr_pre ++ tru, tp_dec) m_dec
(U', tr ++ tr',tpj) mj /\
(exists evu,
(List.In evu tru /\ action evu = Free /\ deadLocation tpj mj b ofs) \/
(tru = [:: evu] /\ action evu = Spawn) \/
(tru = [:: evu] /\ action evu = Freelock /\ thread_id evu = tidn /\
match location evu with
| Some (addr, sz) =>
b = addr.1 /\
Intv.In ofs (addr.2, addr.2 + (Z.of_nat sz))%Z
| None => False
end) \/
(tru = [:: evu] /\ action evu = Mklock /\ thread_id evu = tidn /\
match location evu with
| Some (addr, sz) =>
b = addr.1 /\
Intv.In ofs (addr.2, addr.2 + (Z.of_nat sz))%Z
| None => False
end) \/
(tru = [:: evu] /\ action evu = Release /\ thread_id evu = tidn /\
(exists rmap, match location evu with
| Some (laddr, sz) =>
sz = lksize.LKSIZE_nat /\
lockRes tp_dec laddr = Some rmap /\
(Mem.perm_order'' (rmap.1 !! b ofs) (Some Readable) \/
Mem.perm_order'' (rmap.2 !! b ofs) (Some Readable))
| None => False
end))).
(** Permission increase: A thread can increase its data permissions on a valid block by: - If it is spawned - A freelock operation, turning a lock into data. - Acquiring a lock *)
Lemma data_permission_increase_step:
forall U tr tp m U' tp' m' tr' tidn b ofs
(cnt: containsThread tp tidn)
(cnt': containsThread tp' tidn)
(Hstep: MachStep (U, tr, tp) m (U', tr ++ tr', tp') m')
(Hperm': Mem.perm_order'' ((getThreadR cnt').1 !! b ofs) (Some Readable))
(Hperm: ~ Mem.perm_order'' ((getThreadR cnt).1 !! b ofs) (Some Readable))
(Hvalid: Mem.valid_block m b),
exists ev,
(tr' = [:: ev] /\ action ev = Spawn) \/
(tr' = [:: ev] /\ action ev = Freelock /\ thread_id ev = tidn /\
match location ev with
| Some (addr, sz) =>
b = addr.1 /\
Intv.In ofs (addr.2, addr.2 + (Z.of_nat sz))%Z
| None =>
False
end) \/
(tr' = [:: ev] /\ action ev = Acquire /\ thread_id ev = tidn /\
exists rmap, match location ev with
| Some (laddr, sz) =>
sz = lksize.LKSIZE_nat /\
lockRes tp laddr = Some rmap /\
Mem.perm_order'' (rmap.1 !! b ofs) (Some Readable)
| None => False
end).
Lemma data_permission_increase_execution:
forall U tr tpi mi U' tr' tpj mj
b ofs tidn
(cnti: containsThread tpi tidn)
(cntj: containsThread tpj tidn)
(Hexec: multi_step (U, tr, tpi) mi (U', tr ++ tr', tpj) mj)
(Hperm': Mem.perm_order'' ((getThreadR cntj).1 !! b ofs) (Some Readable))
(Hperm: ~ Mem.perm_order'' ((getThreadR cnti).1 !! b ofs) (Some Readable))
(Hvalid: Mem.valid_block mi b),
exists tr_pre evu U'' U''' tp_pre m_pre tp_inc m_inc,
multi_step (U, tr, tpi) mi (U'', tr ++ tr_pre, tp_pre) m_pre /\
MachStep (U'', tr ++ tr_pre, tp_pre) m_pre
(U''', tr ++ tr_pre ++ [:: evu], tp_inc) m_inc /\
multi_step (U''', tr ++ tr_pre ++ [:: evu], tp_inc) m_inc
(U', tr ++ tr',tpj) mj /\
((action evu = Spawn) \/
(action evu = Freelock /\ thread_id evu = tidn /\
match location evu with
| Some (addr, sz) =>
b = addr.1 /\
Intv.In ofs (addr.2, addr.2 + (Z.of_nat sz))%Z
| None =>
False
end) \/
(action evu = Acquire /\ thread_id evu = tidn /\
exists rmap, match location evu with
| Some (laddr, sz) =>
sz = lksize.LKSIZE_nat /\
lockRes tp_pre laddr = Some rmap /\
Mem.perm_order'' (rmap.1 !! b ofs) (Some Readable)
| None => False
end)).
(** Permission increase: A thread can increase its lock permissions on a valid block by: - If it is spawned - A freelock operation, turning a lock into data. - Acquiring a lock *)
Lemma lock_permission_increase_step:
forall U tr tp m U' tp' m' tr' tidn b ofs
(cnt: containsThread tp tidn)
(cnt': containsThread tp' tidn)
(Hstep: MachStep (U, tr, tp) m (U', tr ++ tr', tp') m')
(Hperm': Mem.perm_order'' ((getThreadR cnt').2 !! b ofs) (Some Readable))
(Hperm: ~ Mem.perm_order'' ((getThreadR cnt).2 !! b ofs) (Some Readable))
(Hvalid: Mem.valid_block m b),
exists ev,
(tr' = [:: ev] /\ action ev = Spawn) \/
(tr' = [:: ev] /\ action ev = Mklock /\ thread_id ev = tidn /\
match location ev with
| Some (addr, sz) =>
b = addr.1 /\
Intv.In ofs (addr.2, addr.2 + (Z.of_nat sz))%Z
| None =>
False
end) \/
(tr' = [:: ev] /\ action ev = Acquire /\ thread_id ev = tidn /\
exists rmap, match location ev with
| Some (laddr, sz) =>
sz = lksize.LKSIZE_nat /\
lockRes tp laddr = Some rmap /\
Mem.perm_order'' (rmap.2 !! b ofs) (Some Readable)
| None => False
end).
Lemma lock_permission_increase_execution:
forall U tr tpi mi U' tr' tpj mj
b ofs tidn
(cnti: containsThread tpi tidn)
(cntj: containsThread tpj tidn)
(Hexec: multi_step (U, tr, tpi) mi (U', tr ++ tr', tpj) mj)
(Hperm': Mem.perm_order'' ((getThreadR cntj).2 !! b ofs) (Some Readable))
(Hperm: ~ Mem.perm_order'' ((getThreadR cnti).2 !! b ofs) (Some Readable))
(Hvalid: Mem.valid_block mi b),
exists tr_pre evu U'' U''' tp_pre m_pre tp_inc m_inc,
multi_step (U, tr, tpi) mi (U'', tr ++ tr_pre, tp_pre) m_pre /\
MachStep (U'', tr ++ tr_pre, tp_pre) m_pre
(U''', tr ++ tr_pre ++ [:: evu], tp_inc) m_inc /\
multi_step (U''', tr ++ tr_pre ++ [:: evu], tp_inc) m_inc
(U', tr ++ tr',tpj) mj /\
((action evu = Spawn) \/
(action evu = Mklock /\ thread_id evu = tidn /\
match location evu with
| Some (addr, sz) =>
b = addr.1 /\
Intv.In ofs (addr.2, addr.2 + (Z.of_nat sz))%Z
| None =>
False
end) \/
(action evu = Acquire /\ thread_id evu = tidn /\
exists rmap, match location evu with
| Some (laddr, sz) =>
sz = lksize.LKSIZE_nat /\
lockRes tp_pre laddr = Some rmap /\
Mem.perm_order'' (rmap.2 !! b ofs) (Some Readable)
| None => False
end)).
Lemma permission_increase_execution:
forall U tr tpi mi U' tr' tpj mj
b ofs tidn
(cnti: containsThread tpi tidn)
(cntj: containsThread tpj tidn)
(Hexec: multi_step (U, tr, tpi) mi (U', tr ++ tr', tpj) mj)
(Hperm: (Mem.perm_order'' ((getThreadR cntj).1 !! b ofs) (Some Readable) /\
~ Mem.perm_order'' ((getThreadR cnti).1 !! b ofs) (Some Readable)) \/
(Mem.perm_order'' ((getThreadR cntj).2 !! b ofs) (Some Readable) /\
~ Mem.perm_order'' ((getThreadR cnti).2 !! b ofs) (Some Readable)))
(Hvalid: Mem.valid_block mi b),
exists tr_pre evu U'' U''' tp_pre m_pre tp_inc m_inc,
multi_step (U, tr, tpi) mi (U'', tr ++ tr_pre, tp_pre) m_pre /\
MachStep (U'', tr ++ tr_pre, tp_pre) m_pre
(U''', tr ++ tr_pre ++ [:: evu], tp_inc) m_inc /\
multi_step (U''', tr ++ tr_pre ++ [:: evu], tp_inc) m_inc
(U', tr ++ tr',tpj) mj /\
((action evu = Spawn) \/
(action evu = Freelock /\ thread_id evu = tidn /\
match location evu with
| Some (addr, sz) =>
b = addr.1 /\
Intv.In ofs (addr.2, addr.2 + (Z.of_nat sz))%Z
| None =>
False
end) \/
(action evu = Mklock /\ thread_id evu = tidn /\
match location evu with
| Some (addr, sz) =>
b = addr.1 /\
Intv.In ofs (addr.2, addr.2 + (Z.of_nat sz))%Z
| None =>
False
end) \/
(action evu = Acquire /\ thread_id evu = tidn /\
exists rmap, match location evu with
| Some (laddr, sz) =>
sz = lksize.LKSIZE_nat /\
lockRes tp_pre laddr = Some rmap /\
(Mem.perm_order'' (rmap.1 !! b ofs) (Some Readable) \/
Mem.perm_order'' (rmap.2 !! b ofs) (Some Readable))
| None => False
end)).
Lemma lockRes_mklock_step:
forall U tr tp m U' tp' m' tr' laddr rmap
(Hres: lockRes tp laddr = None)
(Hres': lockRes tp' laddr = Some rmap)
(Hstep: MachStep (U, tr, tp) m (U', tr ++ tr', tp') m'),
exists ev,
tr' = [:: ev] /\ action ev = Mklock /\
location ev = Some (laddr, lksize.LKSIZE_nat) /\
lockRes tp' laddr = Some (empty_map, empty_map).
Lemma lockRes_mklock_execution:
forall U tr tpi mi U' tpj mj tr' laddr rmapj
(Hres: lockRes tpi laddr = None)
(Hres': lockRes tpj laddr = Some rmapj)
(Hexec: multi_step (U, tr, tpi) mi (U', tr ++ tr', tpj) mj),
exists tr_pre evu U'' U''' tp_pre m_pre tp_mk m_mk,
multi_step (U, tr, tpi) mi (U'', tr ++ tr_pre, tp_pre) m_pre /\
MachStep (U'', tr ++ tr_pre, tp_pre) m_pre
(U''', tr ++ tr_pre ++ [:: evu], tp_mk) m_mk /\
multi_step (U''', tr ++ tr_pre ++ [:: evu], tp_mk) m_mk
(U', tr ++ tr',tpj) mj /\
action evu = Mklock /\
location evu = Some (laddr, lksize.LKSIZE_nat) /\
lockRes tp_mk laddr = Some (empty_map, empty_map).
Lemma lockRes_freelock_step:
forall U tr tp m U' tp' m' tr' laddr rmap
(Hres: lockRes tp laddr = Some rmap)
(Hres': lockRes tp' laddr = None)
(Hstep: MachStep (U, tr, tp) m (U', tr ++ tr', tp') m'),
exists ev,
tr' = [:: ev] /\ action ev = Freelock /\
location ev = Some (laddr, lksize.LKSIZE_nat) /\
forall b ofs, rmap.1 !! b ofs = None /\ rmap.2 !! b ofs = None.
Lemma lockRes_freelock_execution:
forall U tr tpi mi U' tpj mj tr' laddr rmapi
(Hres: lockRes tpi laddr = Some rmapi)
(Hres': lockRes tpj laddr = None)
(Hexec: multi_step (U, tr, tpi) mi (U', tr ++ tr', tpj) mj),
exists tr_pre evu U'' U''' tp_pre m_pre tp_mk m_mk,
multi_step (U, tr, tpi) mi (U'', tr ++ tr_pre, tp_pre) m_pre /\
MachStep (U'', tr ++ tr_pre, tp_pre) m_pre
(U''', tr ++ tr_pre ++ [:: evu], tp_mk) m_mk /\
multi_step (U''', tr ++ tr_pre ++ [:: evu], tp_mk) m_mk
(U', tr ++ tr',tpj) mj /\
action evu = Freelock /\
location evu = Some (laddr, lksize.LKSIZE_nat) /\
exists rmap,
lockRes tp_pre laddr = Some rmap /\
forall b ofs, rmap.1 !! b ofs = None /\
rmap.2 !! b ofs = None.
Lemma lockRes_data_permission_decrease_step:
forall U tr tp m U' tp' m' tr' laddr rmap rmap' b ofs
(Hres: lockRes tp laddr = Some rmap)
(Hres': lockRes tp' laddr = Some rmap')
(Hstep: MachStep (U, tr, tp) m (U', tr ++ tr', tp') m')
(Hperm: Mem.perm_order'' (rmap.1 !! b ofs) (Some Readable))
(Hperm': ~ Mem.perm_order'' (rmap'.1 !! b ofs) (Some Readable)),
exists ev,
tr' = [:: ev] /\ action ev = Acquire /\
location ev = Some (laddr, lksize.LKSIZE_nat).
Lemma lockRes_data_permission_decrease_execution:
forall U tr tpi mi U' tpj mj tr' laddr rmapi rmapj b ofs
(Hres: lockRes tpi laddr = Some rmapi)
(Hres': lockRes tpj laddr = Some rmapj)
(Hexec: multi_step (U, tr, tpi) mi (U', tr ++ tr', tpj) mj)
(Hperm: Mem.perm_order'' (rmapi.1 !! b ofs) (Some Readable))
(Hperm': ~ Mem.perm_order'' (rmapj.1 !! b ofs) (Some Readable)),
exists v ev,
nth_error tr' v = Some ev /\ action ev = Acquire /\
location ev = Some (laddr, lksize.LKSIZE_nat).
Lemma lockRes_lock_permission_decrease_step:
forall U tr tp m U' tp' m' tr' laddr rmap rmap' b ofs
(Hres: lockRes tp laddr = Some rmap)
(Hres': lockRes tp' laddr = Some rmap')
(Hstep: MachStep (U, tr, tp) m (U', tr ++ tr', tp') m')
(Hperm: Mem.perm_order'' (rmap.2 !! b ofs) (Some Readable))
(Hperm': ~ Mem.perm_order'' (rmap'.2 !! b ofs) (Some Readable)),
exists ev,
tr' = [:: ev] /\ action ev = Acquire /\
location ev = Some (laddr, lksize.LKSIZE_nat).
Lemma lockRes_lock_permission_decrease_execution:
forall U tr tpi mi U' tpj mj tr' laddr rmapi rmapj b ofs
(Hres: lockRes tpi laddr = Some rmapi)
(Hres': lockRes tpj laddr = Some rmapj)
(Hexec: multi_step (U, tr, tpi) mi (U', tr ++ tr', tpj) mj)
(Hperm: Mem.perm_order'' (rmapi.2 !! b ofs) (Some Readable))
(Hperm': ~ Mem.perm_order'' (rmapj.2 !! b ofs) (Some Readable)),
exists v ev,
nth_error tr' v = Some ev /\ action ev = Acquire /\
location ev = Some (laddr, lksize.LKSIZE_nat).
Lemma lockRes_permission_decrease_execution:
forall U tr tpi mi U' tpj mj tr' laddr rmapi rmapj b ofs
(Hres: lockRes tpi laddr = Some rmapi)
(Hres': lockRes tpj laddr = Some rmapj)
(Hexec: multi_step (U, tr, tpi) mi (U', tr ++ tr', tpj) mj)
(Hperm: (Mem.perm_order'' (rmapi.1 !! b ofs) (Some Readable) /\
~ Mem.perm_order'' (rmapj.1 !! b ofs) (Some Readable)) \/
(Mem.perm_order'' (rmapi.2 !! b ofs) (Some Readable) /\
~ Mem.perm_order'' (rmapj.2 !! b ofs) (Some Readable))),
exists v ev,
nth_error tr' v = Some ev /\ action ev = Acquire /\
location ev = Some (laddr, lksize.LKSIZE_nat).
Lemma lockRes_data_permission_increase_step:
forall U tr tp m U' tp' m' tr' laddr rmap rmap' b ofs
(Hres: lockRes tp laddr = Some rmap)
(Hres': lockRes tp' laddr = Some rmap')
(Hstep: MachStep (U, tr, tp) m (U', tr ++ tr', tp') m')
(Hperm: ~ Mem.perm_order'' (rmap.1 !! b ofs) (Some Readable))
(Hperm': Mem.perm_order'' (rmap'.1 !! b ofs) (Some Readable)),
exists ev,
tr' = [:: ev] /\ action ev = Release /\
location ev = Some (laddr, lksize.LKSIZE_nat).
Lemma lockRes_lock_permission_increase_step:
forall U tr tp m U' tp' m' tr' laddr rmap rmap' b ofs
(Hres: lockRes tp laddr = Some rmap)
(Hres': lockRes tp' laddr = Some rmap')
(Hstep: MachStep (U, tr, tp) m (U', tr ++ tr', tp') m')
(Hperm: ~ Mem.perm_order'' (rmap.2 !! b ofs) (Some Readable))
(Hperm': Mem.perm_order'' (rmap'.2 !! b ofs) (Some Readable)),
exists ev,
tr' = [:: ev] /\ action ev = Release /\
location ev = Some (laddr, lksize.LKSIZE_nat).