Module ext_red_one (invert : ext_invert_sig).
Set Implicit Arguments.
Set Bullet Behavior "Strict Subproofs".
(* ------------------------------------------------------------ *)
(* tactics for substitution proofs. *)
Ltac subst_helper x x0 b0 :=
replace (a_Var_f x) with (tm_subst_tm_tm b0 x0 (a_Var_f x));
[idtac| rewrite tm_subst_tm_tm_var_neq; auto];
replace (g_Var_f x) with (tm_subst_tm_co b0 x0 (g_Var_f x));
[idtac| simpl; auto];
try (rewrite <- tm_subst_tm_tm_open_tm_wrt_co; eauto);
try (rewrite <- tm_subst_tm_tm_open_tm_wrt_co; eauto);
try (rewrite <- tm_subst_tm_tm_open_tm_wrt_tm; eauto);
try (rewrite <- tm_subst_tm_tm_open_tm_wrt_tm; eauto);
eauto using tm_subst_tm_tm_lc_tm.
(* Most of the substitution cases below are about showing that the term is locally closed after the substiution. This tactic takes care of that argument. *)
Ltac lc_subst_case x0 b0  :=
let x:= fresh in
lc_inversion x; subst;
try (rewrite tm_subst_tm_tm_open_tm_wrt_tm; eauto);
try (rewrite tm_subst_tm_tm_open_tm_wrt_co; eauto);
econstructor; eauto using Value_lc,
tm_subst_tm_tm_lc_tm, tm_subst_tm_co_lc_co,
tm_subst_tm_constraint_lc_constraint;
apply_lc_exists x;
eauto using tm_subst_tm_tm_lc_tm, tm_subst_tm_co_lc_co,
Value_lc, tm_subst_tm_constraint_lc_constraint;
subst_helper x x0 b0.
(* ------------------------------------------------- *)

Lemma subst_reduction_in_one : forall a a',
reduction_in_one a a' -> forall b x, lc_tm b ->
reduction_in_one (tm_subst_tm_tm b x a)
(tm_subst_tm_tm b x a').