Section InternalSteps.
Context {Sem : Semantics}
{SemAx : SemAxioms}
{SemD : SemDet}.
Notation schedule := (seq nat).
Existing Instance OrdinalPool.OrdinalThreadPool.
Existing Instance dryResources.
Existing Instance DryHybridMachineSig.
(** Internal steps are just thread coresteps or resume steps or start steps, they mimic fine-grained internal steps *)
Definition internal_step {tid} {tp} m (cnt: containsThread tp tid)
(Hcomp: mem_compatible tp m) tp' m' :=
(exists ev, threadStep cnt Hcomp tp' m' ev) \/
(resume_thread m cnt tp' /\ m = m') \/
(start_thread m cnt tp' m').
(* For now we don't emit events from internal_execution*)
(*NOTE: we will probably never need to do so*)
Inductive internal_execution : schedule -> t -> mem ->
t -> mem -> Prop :=
| refl_exec : forall tp m,
internal_execution [::] tp m tp m
| step_trans : forall tid U U' tp m tp' m' tp'' m''
(cnt: containsThread tp tid)
(HschedN: schedPeek U = Some tid)
(HschedS: schedSkip U = U')
(Hcomp: mem_compatible tp m)
(Hstep: internal_step cnt Hcomp tp' m')
(Htrans: internal_execution U' tp' m' tp'' m''),
internal_execution U tp m tp'' m''.
(** ** Lemmas about internal steps and internal executions *)
Ltac exec_induction base_case :=
intros;
match goal with
| [xs : list _, i : nat, Hexec: internal_execution _ ?Tp ?M _ _ |- _] =>
generalize dependent Tp; generalize dependent M;
induction xs as [| x xs' IHxs]; intros;
[ match goal with
| [Hexec: internal_execution _ _ _ _ _ |- _] =>
try (inversion Hexec; subst;
by Tactics.pf_cleanup)
end
| match goal with
| [Hexec: internal_execution _ _ _ _ _ |- _] =>
simpl in Hexec;
destruct (x == i) eqn:Heq;
move/eqP:Heq=>Heq;
try eauto;
subst;
try (inversion Hexec as [|? ? ? ? ? ? ? ? ? ?
HschedN HschedS Hcomp ? Htrans]; subst;
simpl in Htrans;
simpl in HschedN; inversion HschedN; subst;
Tactics.pf_cleanup;
specialize (IHxs _ _  Htrans);
rewrite <- IHxs;
erewrite base_case; eauto)
end
]
end.
Opaque OrdinalPool.getThreadR.

Lemma addThread_internal_execution:
forall tp tp' m m' i j xs vf arg pmap
(Hneq: i <> j)
(Hinv': invariant (addThread tp vf arg pmap))
(Hcomp': mem_compatible (addThread tp vf arg pmap) m)
(Hexec: internal_execution [seq x <- xs | x == j] tp m tp' m'),
internal_execution [seq x <- xs | x == j]
(addThread tp vf arg pmap) m
(addThread tp' vf arg pmap) m'.