(* 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.(* 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).