(* MachStep that doesn't change the schedule, Reduces the set of valid schedules... *)
Inductive has_unique_running tp:Prop :=
| HasUniqueRun i (cnti : ThreadPool.containsThread tp i) q:
ThreadPool.getThreadC cnti = Krun q ->
has_unique_running tp.

(* Specifications: *)
Lemma schedPeek_Skip:
forall U tid
( HschedN : schedPeek U = Some tid)
( HschedS : schedSkip U = U),
False.
Lemma unique_Krun_update:
forall st tid,
unique_Krun st tid ->
forall (cnt: ThreadPool.containsThread st tid) c_new m_new cnt,
unique_Krun (ThreadPool.updThread(tid:=tid)(tp:=st) cnt (Krun c_new) m_new) tid.
Lemma unique_Krun_updateC:
forall st tid,
unique_Krun st tid ->
forall (cnt: ThreadPool.containsThread st tid) c_new  cnt,
unique_Krun (ThreadPool.updThreadC(tp:=st)(tid:=tid) cnt (Krun c_new)) tid.
Lemma MachStep_preserve_unique:
forall U tr st tr' st' m m',
valid (tr, st, m) U ->
MachStep (U,tr,st) m (U,tr',st') m' ->
has_unique_running st'.
Lemma CoreStep_preserve_valid:
forall U tr st tr' st' m m',
valid (tr, st, m) U ->
MachStep (U,tr,st) m (U,tr',st') m' ->
valid (tr', st', m') U.
Lemma AngelStep_preserve_valid:
forall U U' tr st tr' st' m m',
valid (tr, st, m) U ->
MachStep (U,tr,st) m (schedSkip U,tr',st') m' ->
valid (tr', st', m') U'.
(* *)
Lemma ksafe_csafe_equiv':
forall st_ m tr,
(forall n U, valid (tr, st_, m) U -> ksafe_kstep (U, tr, st_) m n) ->
(forall n U, valid (tr, st_, m) U -> csafe (U, tr, st_) m n).
Lemma ksafe_csafe_equiv:
forall tp m tr,
(forall U, valid (tr, tp, m) U) ->
(forall n U, ksafe_kstep (U, tr, tp) m n) ->
(forall n U, csafe (U, tr, tp) m n).
Lemma valid_unique_running:
forall tp tr m U U' tid tid',
schedPeek U = Some tid ->
schedPeek U' = Some tid' ->
valid (tr, tp, m) U ->
valid (tr, tp, m) U' ->
has_unique_running tp ->
tid = tid'.
Lemma csafe_first_tid:
forall n U U' tr tp m,
csafe (U, tr, tp) m n ->
schedPeek U = schedPeek U' ->
csafe (U', tr, tp) m n.
Lemma csafe_unique_running:
forall U tr tp m n tid,
schedPeek U = Some tid ->
has_unique_running tp ->
valid (tr, tp, m) U ->
csafe (U, tr, tp) m n ->
forall U', valid (tr, tp, m) U' ->
csafe (U', tr, tp) m n.
Lemma csafe_ksafe_equiv:
forall st_ m tr,
(forall n U, valid (tr, st_, m) U -> csafe (U, tr, st_) m n) ->
(forall n U, valid (tr, st_, m) U -> ksafe_kstep (U, tr, st_) m n).
Lemma csafe_ksafe_equiv_trick:
forall st_ m tr,
(forall U, valid (tr, st_, m) U) ->
(forall n U, csafe (U, tr, st_) m n) ->
(forall n U, ksafe_kstep (U, tr, st_) m n).