(*NOTE: how can we have tactics inside sections? *)
(** Solves absurd cases from fine-grained internal steps *)
Ltac absurd_internal Hstep :=
inversion Hstep; try inversion Htstep; subst; simpl in *; Tactics.pf_cleanup;
try match goal with
| [H: Some _ = Some _ |- _] => inversion H; subst
end; Tactics.pf_cleanup;
repeat match goal with
| [H: OrdinalPool.getThreadC ?Pf = _, Hint: ?Pf$_ @ I |- _] =>
unfold getStepType, ctlType in Hint; simpl in *;
rewrite H in Hint; simpl in Hint
| [H: getThreadC ?Pf = _, Hint: ?Pf$_ @ I |- _] =>
unfold getStepType, ctlType in Hint; simpl in *;
rewrite H in Hint; simpl in Hint
| [H1: match ?Expr with _ => _ end = _,
H2: ?Expr = _ |- _] => rewrite H2 in H1
(*     | [H1: is_true (isSome (halted ?Sem ?C)), H2: match at_external _ _ _ with _ => _ end = _ |- _] => destruct (at_external_halted_excl Sem C) as [Hext | Hcontra]; [rewrite Hext in H2; destruct (halted Sem C) eqn:Hh; [discriminate | by exfalso] | rewrite Hcontra in H1; by exfalso]*)
end; try discriminate; try (exfalso; by auto).

Lemma at_internal_cmachine_step :
forall i U U' tp tr tr' tp' m m'
(cnt: containsThread tp i)
(Hcomp: mem_compatible tp m),
let mrestr := restrPermMap (((compat_th _ _ Hcomp) cnt).1) in
forall (Hinternal: cnt$mrestr @ I)
(Hstep: cmachine_step ((i :: U), tr,tp) m (U', tr ++ tr', tp') m'),
internal_step cnt Hcomp tp' m' /\ U' = (i :: U).