(** Similar to effect semantics, event semantics augment memory semantics with suitable effects, in the form of a set of memory access traces associated with each internal step of the semantics. *)
Record EvSem {C} :=
{ (** [sem] is a memory semantics. *)
msem :> @MemSem C
(** The step relation of the new semantics. *)
; ev_step: C -> mem -> list mem_event -> C -> mem -> Prop
(** The next four fields axiomatize [drfstep] and its relation to the underlying step relation of [msem]. *)
; ev_step_ax1: forall c m T c' m',
ev_step c m T c' m' ->
corestep msem c m c' m'
; ev_step_ax2: forall c m c' m',
corestep msem c m c' m' ->
exists T, ev_step c m T c' m'
; ev_step_fun: forall c m T' c' m' T'' c'' m'',
ev_step c m T' c' m' -> ev_step c m T'' c'' m'' -> T'=T''
(*  ; ev_step_elim: forall g c m T c' m', ev_step g c m T c' m' -> ev_elim m T m'*)
; ev_step_elim: forall c m T c' m' (STEP: ev_step c m T c' m'),
ev_elim m T m' (*/\
(forall mm mm', ev_elim mm T mm' -> exists cc', ev_step c mm T cc' mm')*)
}.

(* Specifications: *)
Lemma Ev_sem_cur_perm {C} (R: @EvSem C) c m T c' m' b ofs (D: ev_step R c m T c' m'):
Mem.perm_order'' ((Mem.mem_access m) !! b ofs Cur) (cur_perm (b,ofs) T).
Lemma freelist_mem_access_1 b ofs p: forall l m (ACC:(Mem.mem_access m) !! b ofs Cur = Some p)
m1 (FL: Mem.free_list m1 l = Some m), (Mem.mem_access m1) !! b ofs Cur = Some p.
Lemma freelist_access_2 b ofs: forall l  (FL: in_free_list b ofs l)
m m' (FR : Mem.free_list m l = Some m'),
(Mem.mem_access m') !! b ofs Cur = None /\ Mem.valid_block m' b.
Lemma freelist_access_3 b ofs: forall l m (ACC: (Mem.mem_access m) !! b ofs Cur = None)
(VB: Mem.valid_block m b) m' (FL: Mem.free_list m l = Some m'),
(Mem.mem_access m') !! b ofs Cur = None.
Lemma ev_elim_accessNone b ofs: forall ev m' m'' (EV:ev_elim m'' ev m')
(ACC: (Mem.mem_access m'') !! b ofs Cur = None)
(VB: Mem.valid_block m'' b), (Mem.mem_access m') !! b ofs Cur = None.
Lemma ev_elim_valid_block: forall ev m m' (EV: ev_elim m ev m') b
(VB : Mem.valid_block m b), Mem.valid_block m' b.
(** If (b, ofs) is in the list of freed addresses then the permission was Freeable and became None or it was not allocated*)
Lemma ev_elim_free_1 b ofs:
forall ev m m',
ev_elim m ev m' ->
in_free_list_trace b ofs ev ->
(Mem.perm m b ofs Cur Freeable \/
~ Mem.valid_block m b) /\
(Mem.mem_access m') !! b ofs Cur = None /\
Mem.valid_block m' b /\
exists e, List.In e ev /\
match e with
| Free _ => True
| _ => False
end.
Lemma perm_order_pp_refl p: Mem.perm_order'' p p.
Lemma in_free_list_trace_dec b ofs: forall es, {in_free_list_trace b ofs es} + {~in_free_list_trace b ofs es}.
Lemma freelist_access_1 b ofs: forall l,
~ in_free_list b ofs l ->
forall m m' : mem, Mem.free_list m l = Some m' -> (Mem.mem_access m') !! b ofs Cur = (Mem.mem_access m) !! b ofs Cur.
(** If (b, ofs) is not in the list of freed locations then its permissions cannot decrease*)
Lemma ev_elim_free_2 b ofs:
forall ev m m' (EV: ev_elim m ev m')
(T: ~ in_free_list_trace b ofs ev),
Mem.perm_order'' ((Mem.mem_access m') !! b ofs Cur)
((Mem.mem_access m) !! b ofs Cur).
Lemma free_list_cases:
forall l m m' b ofs
(Hfree: Mem.free_list m l = Some m'),
((Mem.mem_access m) !! b ofs Cur = Some Freeable /\
(Mem.mem_access m') !! b ofs Cur = None) \/
((Mem.mem_access m) !! b ofs Cur =
(Mem.mem_access m') !! b ofs Cur).