(** * Semantics annotated with Owens-style trace*)
Inductive mem_event :=
Write : forall (b : block) (ofs : Z) (bytes : list memval), mem_event
| Read : forall (b:block) (ofs n:Z) (bytes: list memval), mem_event
| Alloc: forall (b:block)(lo hi:Z), mem_event
(*| Lock: drf_event | Unlock: drf_event  -- these events are not generated by core steps*)
| Free: forall (l: list (block * Z * Z)), mem_event.
Fixpoint ev_elim (m:mem) (T: list mem_event) (m':mem):Prop :=
match T with
nil => m'=m
| (Read b ofs n bytes :: R) => Mem.loadbytes m b ofs n = Some bytes /\ ev_elim m R m'
| (Write b ofs bytes :: R) => exists m'', Mem.storebytes m b ofs bytes = Some m'' /\ ev_elim m'' R m'
| (Alloc b lo hi :: R) => exists m'', Mem.alloc m lo hi = (m'',b) /\ ev_elim m'' R m'
| (Free l :: R) => exists m'', Mem.free_list m l = Some m'' /\ ev_elim m'' R m'
end.
Definition pmax (popt qopt: option permission): option permission :=
match popt, qopt with
_, None => popt
| None, _ => qopt
| Some p, Some q => if Mem.perm_order_dec p q then Some p else Some q
end.

(* Specifications: *)
Lemma po_pmax_I p q1 q2:
Mem.perm_order'' p q1 -> Mem.perm_order'' p q2 -> Mem.perm_order'' p (pmax q1 q2).