(** Reflexive-transitive closure of machine step relation*)
    Inductive multi_step :
      MachState -> mem -> MachState -> mem -> Prop :=
    | Step_refl : forall ms (m : mem),
        multi_step ms m ms m
    | Step_trans : forall i U U'
                     (tp tp' tp'' : t)
                     tr tr' tr''
                     (m m' m'' : mem),
        MachStep (i :: U, tr, tp) m (U, tr ++ tr', tp') m' ->
        multi_step (U, tr ++ tr', tp') m' (U', tr ++ tr' ++ tr'', tp'') m'' ->
        multi_step (i :: U,tr,tp) m (U',tr ++ tr' ++ tr'',tp'') m''.(** Reflexive-transitive closure of machine step relation*)
    Inductive multi_step :
      MachState -> mem -> MachState -> mem -> Prop :=
    | Step_refl : forall ms (m : mem),
        multi_step ms m ms m
    | Step_trans : forall i U U'
                     (tp tp' tp'' : t)
                     tr tr' tr''
                     (m m' m'' : mem),
        MachStep (i :: U, tr, tp) m (U, tr ++ tr', tp') m' ->
        multi_step (U, tr ++ tr', tp') m' (U', tr ++ tr' ++ tr'', tp'') m'' ->
        multi_step (i :: U,tr,tp) m (U',tr ++ tr' ++ tr'',tp'') m''.(** Reflexive-transitive closure of machine step relation*)
    Inductive multi_step :
      MachState -> mem -> MachState -> mem -> Prop :=
    | Step_refl : forall ms (m : mem),
        multi_step ms m ms m
    | Step_trans : forall i U U'
                     (tp tp' tp'' : t)
                     tr tr' tr''
                     (m m' m'' : mem),
        MachStep (i :: U, tr, tp) m (U, tr ++ tr', tp') m' ->
        multi_step (U, tr ++ tr', tp') m' (U', tr ++ tr' ++ tr'', tp'') m'' ->
        multi_step (i :: U,tr,tp) m (U',tr ++ tr' ++ tr'',tp'') m''.(** Complete executions (until the schedule is empty) of the FineConc machine*)
    Inductive fine_execution :
      MachState -> mem -> MachState -> mem -> Prop :=
    | fine_completed : forall ms (m : mem),
        halted_machine ms ->
        fine_execution ms m ms m
    | fine_exec : forall i U U'
                    tp tp' tp''
                    tr tr' tr''
                    (m m' m'' : mem),
        MachStep (i :: U, tr, tp) m (U, tr ++ tr', tp') m' ->
        fine_execution (U, tr ++ tr', tp') m' (U', tr ++ tr' ++ tr'', tp'') m'' ->
        fine_execution (i :: U,tr,tp) m (U',tr ++ tr' ++ tr'',tp'') m''.(** Complete executions (until the schedule is empty) of the FineConc machine*)
    Inductive fine_execution :
      MachState -> mem -> MachState -> mem -> Prop :=
    | fine_completed : forall ms (m : mem),
        halted_machine ms ->
        fine_execution ms m ms m
    | fine_exec : forall i U U'
                    tp tp' tp''
                    tr tr' tr''
                    (m m' m'' : mem),
        MachStep (i :: U, tr, tp) m (U, tr ++ tr', tp') m' ->
        fine_execution (U, tr ++ tr', tp') m' (U', tr ++ tr' ++ tr'', tp'') m'' ->
        fine_execution (i :: U,tr,tp) m (U',tr ++ tr' ++ tr'',tp'') m''.(** Complete executions (until the schedule is empty) of the FineConc machine*)
    Inductive fine_execution :
      MachState -> mem -> MachState -> mem -> Prop :=
    | fine_completed : forall ms (m : mem),
        halted_machine ms ->
        fine_execution ms m ms m
    | fine_exec : forall i U U'
                    tp tp' tp''
                    tr tr' tr''
                    (m m' m'' : mem),
        MachStep (i :: U, tr, tp) m (U, tr ++ tr', tp') m' ->
        fine_execution (U, tr ++ tr', tp') m' (U', tr ++ tr' ++ tr'', tp'') m'' ->
        fine_execution (i :: U,tr,tp) m (U',tr ++ tr' ++ tr'',tp'') m''.

(* Specifications: *)
Lemma step_event_tid: forall U tr tp m U' tr' tp' m' (Hstep: MachStep (U, tr, tp) m (U', tr ++ tr', tp') m'), forall ev ev', List.In ev tr' -> List.In ev' tr' -> thread_id ev = thread_id ev'.
Lemma step_trace_monotone: forall U tp m tr U' tp' m' tr' (Hstep: MachStep (U, tr, tp) m (U', tr', tp') m'), exists tr'', tr' = tr ++ tr''.
Lemma multi_step_trace_monotone: forall U tr tp m U' tr' tp' m' (Hexec: multi_step (U, tr, tp) m (U', tr', tp') m'), exists tr'', tr' = tr ++ tr''.
Lemma step_sched_inv: forall i U tp m tr U' tp' m' tr' (Hstep: MachStep (i :: U, tr, tp) m (U', tr', tp') m'), U' = U.
Lemma multi_step_snoc: forall U U' U'' tr tr' tr'' tp m tp' m' tp'' m'' (Hexec: multi_step (U, tr, tp) m (U', tr ++ tr', tp') m') (Hstep: MachStep (U', tr ++ tr', tp') m' (U'', tr ++ tr' ++ tr'', tp'') m''), multi_step (U, tr, tp) m (U'', tr ++ tr' ++ tr'', tp'') m''.
Lemma step_trace_irr: forall U i tp m tp' m' tr tr' (Hstep: MachStep (i :: U, tr, tp) m (U, tr', tp') m'), forall tr'', exists ev, MachStep (i :: U, tr'', tp) m (U, tr'' ++ ev, tp') m'.
Lemma multi_step_refl: forall U tr tp m tr' tp' m' (Hexec: multi_step (U, tr, tp) m (U, tr', tp') m'), tp = tp' /\ m = m' /\ tr = tr'.
Lemma multi_step_mem_compatible : forall U tr tp m U' tr' tp' m' (Hexec: multi_step (U, tr, tp) m (U', tr', tp') m'), mem_compatible tp m \/ tp = tp' /\ m = m' /\ U = U' /\ tr = tr'.
Lemma multi_step_invariant : forall U tr tp m U' tr' tp' m' (Hexec: multi_step (U, tr, tp) m (U', tr', tp') m'), invariant tp \/ tp = tp' /\ m = m' /\ U = U' /\ tr = tr'.
Lemma multi_step_containsThread : forall U tp tr m U' tp' tr' m' i (Hexec: multi_step (U, tr, tp) m (U', tr', tp') m'), containsThread tp i -> containsThread tp' i.
Lemma multi_step_valid_block: forall U tr tp m U' tr' tp' m' b (Hexec: multi_step (U, tr, tp) m (U', tr', tp') m') (Hvalid: Mem.valid_block m b), Mem.valid_block m' b.
Lemma updThreadC_deadLocation: forall tp m b ofs i (cnti: containsThread tp i) c, deadLocation tp m b ofs -> deadLocation (updThreadC cnti c) m b ofs.
Lemma step_deadLocation: forall U U' tr tp m tr' tp' m' b ofs (Hdead: deadLocation tp m b ofs) (Hstep: MachStep (U, tr, tp) m (U',tr ++ tr', tp') m'), deadLocation tp' m' b ofs.
Lemma multi_step_deadLocation: forall U U' tr tp m tr' tp' m' b ofs (Hdead: deadLocation tp m b ofs) (Hexec: multi_step (U, tr, tp) m (U',tr ++ tr', tp') m'), deadLocation tp' m' b ofs.
Lemma remLockRes_Freelock: forall i U tr tr' tp m tp' m' addr (Hlock: lockRes tp addr) (HisLock: isLock tp addr) (Hstep: MachStep (i :: U, tr, tp) m (U, tr ++ tr', tp') m') (Hev: forall u ev, nth_error tr' u = Some ev -> action ev <> Freelock \/ location ev <> Some (addr, lksize.LKSIZE_nat)), lockRes tp' addr /\ isLock tp' addr.
Lemma remLockRes_Freelock_execution: forall U U' tr tr' tp m tp' m' addr (Hlock: lockRes tp addr) (HisLock: isLock tp addr) (Hstep: multi_step (U, tr, tp) m (U', tr ++ tr', tp') m') (Hfreelock: forall (u : nat) (evu : machine_event), nth_error tr' u = Some evu -> action evu <> Freelock \/ location evu <> Some (addr, lksize.LKSIZE_nat)), lockRes tp' addr /\ isLock tp' addr.
Lemma ev_elim_stable: forall m m' b ofs es (Hvalid: Mem.valid_block m b) (Hperm: Mem.perm_order'' (Some Writable) (permission_at m b ofs Cur)) (Helim: ev_elim m es m'), permission_at m b ofs Cur = permission_at m' b ofs Cur.