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.

Corollary permission_at_step:
forall tp tp' m m' i j
(Hneq: i <> j)
(pfi: containsThread tp i)
(pfj: containsThread tp j)
(pfj': containsThread tp' j)
(Hcomp: mem_compatible tp m)
(Hcomp': mem_compatible tp' m')
(Hstep: internal_step pfi Hcomp tp' m') b ofs,
permission_at (restrPermMap ((compat_th _ _ Hcomp) pfj).1) b ofs Cur =
permission_at (restrPermMap ((compat_th _ _ Hcomp') pfj').1) b ofs Cur /\
permission_at (restrPermMap ((compat_th _ _ Hcomp) pfj).2) b ofs Cur =
permission_at (restrPermMap ((compat_th _ _ Hcomp') pfj').2) b ofs Cur.