(*TODO: Move to ev_semantics*)
    Definition in_free_list (b : block) ofs xs :=
      exists x, List.In x xs /\
           let '(b', lo, hi) := x in
           b = b' /\
           (lo <= ofs < hi)%Z.

(* Specifications: *)
Lemma ev_elim_free_1: forall m ev m' b ofs, ev_elim m ev m' -> in_free_list_trace b ofs ev -> (permission_at m b ofs Cur = Some Freeable \/ ~ Mem.valid_block m b) /\ permission_at m' b ofs Cur = None /\ Mem.valid_block m' b /\ exists e, List.In e ev /\ match e with | event_semantics.Free _ => True | _ => False end.
Lemma ev_elim_free_2: forall m ev m' b ofs, ev_elim m ev m' -> ~ in_free_list_trace b ofs ev -> Mem.perm_order'' (permission_at m' b ofs Cur) (permission_at m b ofs Cur).
Lemma free_list_cases: forall l m m' b ofs (Hfree: Mem.free_list m l = Some m'), (permission_at m b ofs Cur = Some Freeable /\ permission_at m' b ofs Cur = None) \/ (permission_at m b ofs Cur = permission_at m' b ofs Cur).
Lemma elim_perm_valid_block: forall m T m' b ofs ofs' bytes (Hintv: Intv.In ofs' (ofs, (ofs + Z.of_nat (length bytes))%Z)) (Helim: ev_elim m T m') (Hvalid: Mem.valid_block m b), (** Either the location was freed*) (permission_at m b ofs' Cur = Some Freeable /\ permission_at m' b ofs' Cur = None) \/ (** or it wasn't and the operation denoted by the event implies the permission*) ((List.In (event_semantics.Write b ofs bytes) T -> Mem.perm_order'' (permission_at m b ofs' Cur) (Some Writable) /\ Mem.perm_order'' (permission_at m' b ofs' Cur) (Some Writable)) /\ (forall n, List.In (event_semantics.Read b ofs n bytes) T -> Mem.perm_order'' (permission_at m b ofs' Cur) (Some Readable) /\ Mem.perm_order'' (permission_at m' b ofs' Cur) (Some Readable))).
Lemma free_list_valid_block: forall m m' l b, Mem.free_list m l = Some m' -> Mem.valid_block m b <-> Mem.valid_block m' b.
Lemma elim_perm_invalid_block: forall m T m' b ofs ofs' bytes (Hintv: Intv.In ofs' (ofs, (ofs + Z.of_nat (length bytes))%Z)) (Helim: ev_elim m T m') (Hinvalid: ~ Mem.valid_block m b), (** or it wasn't and the operation denoted by the event implies the permission*) (List.In (event_semantics.Write b ofs bytes) T -> (permission_at m' b ofs' Cur = Some Freeable \/ permission_at m' b ofs' Cur = None) /\ Mem.valid_block m' b) /\ (forall n, List.In (event_semantics.Read b ofs n bytes) T -> (permission_at m' b ofs' Cur = Some Freeable \/ permission_at m' b ofs' Cur = None) /\ Mem.valid_block m' b).
Lemma start_thread_det: forall tp m tid (cnt: containsThread tp tid) tp' m' tp'' m'' (Hstart: start_thread m cnt tp' m') (Hstart': start_thread m cnt tp'' m''), tp' = tp'' /\ m' = m''.
Lemma sync_step_det: forall tp m tid (cnt: containsThread tp tid) tp' m' tp'' m'' ev ev' (Hcmpt: mem_compatible tp m) (Hstep: @BareMachine.syncStep _ false _ tp m cnt Hcmpt tp' m' ev) (Hstep': @BareMachine.syncStep _ false _ tp m cnt Hcmpt tp'' m'' ev'), tp' = tp'' /\ m' = m'' /\ ev = ev'.
Lemma suspend_thread_det: forall tp m tid (cnt: containsThread tp tid) tp' tp'' (Hsuspend: suspend_thread m cnt tp') (Hsuspend': suspend_thread m cnt tp''), tp' = tp''.
Lemma step_thread_det: forall tp m tid (cnt: containsThread tp tid) tp' m' tp'' m'' ev ev' (Hcmpt: mem_compatible tp m) (Hstep: threadStep cnt Hcmpt tp' m' ev) (Hstep': threadStep cnt Hcmpt tp'' m'' ev'), tp' = tp'' /\ m' = m'' /\ ev = ev'.
Lemma resume_thread_det: forall tp m tid (cnt: containsThread tp tid) tp' tp'' (Hresume: resume_thread m cnt tp') (Hresume': resume_thread m cnt tp''), tp' = tp''.
Lemma bareStep_det: forall U tr tp m U' tr' tp' m' U'' tr'' tp'' m'' (Hstep: MachStep (U, tr, tp) m (U', tr', tp') m') (Hstep': MachStep (U, tr, tp) m (U'', tr'', tp'') m''), U' = U'' /\ tr' = tr'' /\ tp' = tp'' /\ m' = m''.
Lemma bare_execution_det: forall st m st' m' st'' m'' (Hstep: fine_execution st m st' m') (Hstep': fine_execution st m st'' m''), st' = st'' /\ m' = m''.