(* Rewrite the context in to the appropriate form for the induction hypothesis (in the cases with binding). This rewriting is specific for substitution lemmas. *)
Ltac rewrite_subst_context :=
match goal with
| [ |- context [([(?y, ?C (_ _ _ ?T))] ++ map ?sub ?F ++ ?G0)] ] =>
rewrite_env (map sub ((y ~ (C T)) ++ F) ++ G0)
end.
(* These are constructors for the E judgements that - do not bind variables - are syntax directed - are not variables Therefore, they are safe to just use in the substitution lemmas below. *)
Ltac eapply_E_subst :=
first [ eapply E_Star     |
eapply E_App      |
eapply E_IApp     |
eapply E_CApp     |
eapply E_Const    |
eapply E_IsoConv  |
eapply E_AppCong  |
eapply E_IAppCong |
eapply E_CAppCong |
eapply E_PiSnd    |
eapply E_CPiSnd].

Lemma tm_substitution_mutual :
(forall G0 b B (H : Typing G0 b B),
forall G a A, Typing G a A ->
forall F x, G0 = (F ++ (x ~ Tm A) ++ G) ->
Typing (map (tm_subst_tm_sort a x) F ++ G)
(tm_subst_tm_tm a x b)
(tm_subst_tm_tm a x B)) /\
(forall G0 phi (H : PropWff G0 phi),
forall G a A, Typing G a A ->
forall F x, G0 = (F ++ (x ~ Tm A) ++ G) ->
PropWff (map (tm_subst_tm_sort a x) F ++ G)
(tm_subst_tm_constraint a x phi)) /\
(forall G0 D p1 p2 (H : Iso G0 D p1 p2),
forall G a A, Typing G a A ->
forall F x, G0 = (F ++ (x ~ Tm A) ++ G) ->
Iso (map (tm_subst_tm_sort a x) F ++ G) D
(tm_subst_tm_constraint a x p1)
(tm_subst_tm_constraint a x p2)) /\
(forall G0 D A B T (H : DefEq G0 D A B T),
forall G a A0, Typing G a A0 ->
forall F x, G0 = (F ++ (x ~ Tm A0) ++ G) ->
DefEq (map (tm_subst_tm_sort a x) F ++ G) D
(tm_subst_tm_tm a x A)
(tm_subst_tm_tm a x B) (tm_subst_tm_tm a x T)) /\
(forall G0 (H : Ctx G0),
forall G a A, Typing G a A ->
forall F x, G0 = (F ++ (x ~ Tm A) ++ G) ->
Ctx (map (tm_subst_tm_sort a x) F ++ G)).