Section pure_term.
(* (* pure lambda-terms M, N, .. *)
Inductive pure_term : Type :=
| pure_var : nat -> pure_term
| pure_app : pure_term -> pure_term -> pure_term
| pure_abs : pure_term -> pure_term.
*)
Definition up_ren_ren_term_poly_type    (xi : ( nat  ) -> nat ) (tau : ( nat  ) -> nat ) (theta : ( nat  ) -> nat ) (Eq : forall x, (funcomp tau xi) x = theta x) : forall x, (funcomp (upRen_term_poly_type tau) (upRen_term_poly_type xi)) x = (upRen_term_poly_type theta) x.
Definition up_ren_ren_term_term    (xi : ( nat  ) -> nat ) (tau : ( nat  ) -> nat ) (theta : ( nat  ) -> nat ) (Eq : forall x, (funcomp tau xi) x = theta x) : forall x, (funcomp (upRen_term_term tau) (upRen_term_term xi)) x = (upRen_term_term theta) x :=
up_ren_ren xi tau theta Eq.
Fixpoint compRenRen_term    (xipoly_type : ( nat  ) -> nat ) (xiterm : ( nat  ) -> nat ) (zetapoly_type : ( nat  ) -> nat ) (zetaterm : ( nat  ) -> nat ) (rhopoly_type : ( nat  ) -> nat ) (rhoterm : ( nat  ) -> nat ) (Eqpoly_type : forall x, (funcomp zetapoly_type xipoly_type) x = rhopoly_type x) (Eqterm : forall x, (funcomp zetaterm xiterm) x = rhoterm x) (s : term  ) : ren_term zetapoly_type zetaterm (ren_term xipoly_type xiterm s) = ren_term rhopoly_type rhoterm s :=
match s return ren_term zetapoly_type zetaterm (ren_term xipoly_type xiterm s) = ren_term rhopoly_type rhoterm s with
| var   s => ap (var  ) (Eqterm s)
| app   s0 s1 => congr_app (compRenRen_term xipoly_type xiterm zetapoly_type zetaterm rhopoly_type rhoterm Eqpoly_type Eqterm s0) (compRenRen_term xipoly_type xiterm zetapoly_type zetaterm rhopoly_type rhoterm Eqpoly_type Eqterm s1)
| abs   s0 s1 => congr_abs (compRenRen_poly_type xipoly_type zetapoly_type rhopoly_type Eqpoly_type s0) (compRenRen_term (upRen_term_poly_type xipoly_type) (upRen_term_term xiterm) (upRen_term_poly_type zetapoly_type) (upRen_term_term zetaterm) (upRen_term_poly_type rhopoly_type) (upRen_term_term rhoterm) Eqpoly_type (up_ren_ren_term_term (_) (_) (_) Eqterm) s1)
| ty_app   s0 s1 => congr_ty_app (compRenRen_term xipoly_type xiterm zetapoly_type zetaterm rhopoly_type rhoterm Eqpoly_type Eqterm s0) (compRenRen_poly_type xipoly_type zetapoly_type rhopoly_type Eqpoly_type s1)
| ty_abs   s0 => congr_ty_abs (compRenRen_term (upRen_poly_type_poly_type xipoly_type) (upRen_poly_type_term xiterm) (upRen_poly_type_poly_type zetapoly_type) (upRen_poly_type_term zetaterm) (upRen_poly_type_poly_type rhopoly_type) (upRen_poly_type_term rhoterm) (up_ren_ren_poly_type_poly_type (_) (_) (_) Eqpoly_type) Eqterm s0)
end.
Definition up_ren_subst_poly_type_term    (xi : ( nat  ) -> nat ) (tau : ( nat  ) -> term  ) (theta : ( nat  ) -> term  ) (Eq : forall x, (funcomp tau xi) x = theta x) : forall x, (funcomp (up_poly_type_term tau) (upRen_poly_type_term xi)) x = (up_poly_type_term theta) x :=
fun n => ap (ren_term shift id) (Eq n).
Definition up_ren_subst_term_poly_type    (xi : ( nat  ) -> nat ) (tau : ( nat  ) -> poly_type ) (theta : ( nat  ) -> poly_type ) (Eq : forall x, (funcomp tau xi) x = theta x) : forall x, (funcomp (up_term_poly_type tau) (upRen_term_poly_type xi)) x = (up_term_poly_type theta) x :=
fun n => ap (ren_poly_type id) (Eq n).
Definition up_ren_subst_term_term    (xi : ( nat  ) -> nat ) (tau : ( nat  ) -> term  ) (theta : ( nat  ) -> term  ) (Eq : forall x, (funcomp tau xi) x = theta x) : forall x, (funcomp (up_term_term tau) (upRen_term_term xi)) x = (up_term_term theta) x :=
fun n => match n with
| S n => ap (ren_term id shift) (Eq n)
| 0 => eq_refl
end.
Fixpoint compRenSubst_term    (xipoly_type : ( nat  ) -> nat ) (xiterm : ( nat  ) -> nat ) (taupoly_type : ( nat  ) -> poly_type ) (tauterm : ( nat  ) -> term  ) (thetapoly_type : ( nat  ) -> poly_type ) (thetaterm : ( nat  ) -> term  ) (Eqpoly_type : forall x, (funcomp taupoly_type xipoly_type) x = thetapoly_type x) (Eqterm : forall x, (funcomp tauterm xiterm) x = thetaterm x) (s : term  ) : subst_term taupoly_type tauterm (ren_term xipoly_type xiterm s) = subst_term thetapoly_type thetaterm s :=
match s return subst_term taupoly_type tauterm (ren_term xipoly_type xiterm s) = subst_term thetapoly_type thetaterm s with
| var   s => Eqterm s
| app   s0 s1 => congr_app (compRenSubst_term xipoly_type xiterm taupoly_type tauterm thetapoly_type thetaterm Eqpoly_type Eqterm s0) (compRenSubst_term xipoly_type xiterm taupoly_type tauterm thetapoly_type thetaterm Eqpoly_type Eqterm s1)
| abs   s0 s1 => congr_abs (compRenSubst_poly_type xipoly_type taupoly_type thetapoly_type Eqpoly_type s0) (compRenSubst_term (upRen_term_poly_type xipoly_type) (upRen_term_term xiterm) (up_term_poly_type taupoly_type) (up_term_term tauterm) (up_term_poly_type thetapoly_type) (up_term_term thetaterm) (up_ren_subst_term_poly_type (_) (_) (_) Eqpoly_type) (up_ren_subst_term_term (_) (_) (_) Eqterm) s1)
| ty_app   s0 s1 => congr_ty_app (compRenSubst_term xipoly_type xiterm taupoly_type tauterm thetapoly_type thetaterm Eqpoly_type Eqterm s0) (compRenSubst_poly_type xipoly_type taupoly_type thetapoly_type Eqpoly_type s1)
| ty_abs   s0 => congr_ty_abs (compRenSubst_term (upRen_poly_type_poly_type xipoly_type) (upRen_poly_type_term xiterm) (up_poly_type_poly_type taupoly_type) (up_poly_type_term tauterm) (up_poly_type_poly_type thetapoly_type) (up_poly_type_term thetaterm) (up_ren_subst_poly_type_poly_type (_) (_) (_) Eqpoly_type) (up_ren_subst_poly_type_term (_) (_) (_) Eqterm) s0)
end.
Definition up_subst_ren_poly_type_term    (sigma : ( nat  ) -> term  ) (zetapoly_type : ( nat  ) -> nat ) (zetaterm : ( nat  ) -> nat ) (theta : ( nat  ) -> term  ) (Eq : forall x, (funcomp (ren_term zetapoly_type zetaterm) sigma) x = theta x) : forall x, (funcomp (ren_term (upRen_poly_type_poly_type zetapoly_type) (upRen_poly_type_term zetaterm)) (up_poly_type_term sigma)) x = (up_poly_type_term theta) x :=
fun n => eq_trans (compRenRen_term shift id (upRen_poly_type_poly_type zetapoly_type) (upRen_poly_type_term zetaterm) (funcomp shift zetapoly_type) (funcomp id zetaterm) (fun x => eq_refl) (fun x => eq_refl) (sigma n)) (eq_trans (eq_sym (compRenRen_term zetapoly_type zetaterm shift id (funcomp shift zetapoly_type) (funcomp id zetaterm) (fun x => eq_refl) (fun x => eq_refl) (sigma n))) (ap (ren_term shift id) (Eq n))).
Definition up_subst_ren_term_poly_type    (sigma : ( nat  ) -> poly_type ) (zetapoly_type : ( nat  ) -> nat ) (theta : ( nat  ) -> poly_type ) (Eq : forall x, (funcomp (ren_poly_type zetapoly_type) sigma) x = theta x) : forall x, (funcomp (ren_poly_type (upRen_term_poly_type zetapoly_type)) (up_term_poly_type sigma)) x = (up_term_poly_type theta) x :=
fun n => eq_trans (compRenRen_poly_type id (upRen_term_poly_type zetapoly_type) (funcomp id zetapoly_type) (fun x => eq_refl) (sigma n)) (eq_trans (eq_sym (compRenRen_poly_type zetapoly_type id (funcomp id zetapoly_type) (fun x => eq_refl) (sigma n))) (ap (ren_poly_type id) (Eq n))).
Definition up_subst_ren_term_term    (sigma : ( nat  ) -> term  ) (zetapoly_type : ( nat  ) -> nat ) (zetaterm : ( nat  ) -> nat ) (theta : ( nat  ) -> term  ) (Eq : forall x, (funcomp (ren_term zetapoly_type zetaterm) sigma) x = theta x) : forall x, (funcomp (ren_term (upRen_term_poly_type zetapoly_type) (upRen_term_term zetaterm)) (up_term_term sigma)) x = (up_term_term theta) x :=
fun n => match n with
| S n => eq_trans (compRenRen_term id shift (upRen_term_poly_type zetapoly_type) (upRen_term_term zetaterm) (funcomp id zetapoly_type) (funcomp shift zetaterm) (fun x => eq_refl) (fun x => eq_refl) (sigma n)) (eq_trans (eq_sym (compRenRen_term zetapoly_type zetaterm id shift (funcomp id zetapoly_type) (funcomp shift zetaterm) (fun x => eq_refl) (fun x => eq_refl) (sigma n))) (ap (ren_term id shift) (Eq n)))
| 0 => eq_refl
end.
Fixpoint compSubstRen_term    (sigmapoly_type : ( nat  ) -> poly_type ) (sigmaterm : ( nat  ) -> term  ) (zetapoly_type : ( nat  ) -> nat ) (zetaterm : ( nat  ) -> nat ) (thetapoly_type : ( nat  ) -> poly_type ) (thetaterm : ( nat  ) -> term  ) (Eqpoly_type : forall x, (funcomp (ren_poly_type zetapoly_type) sigmapoly_type) x = thetapoly_type x) (Eqterm : forall x, (funcomp (ren_term zetapoly_type zetaterm) sigmaterm) x = thetaterm x) (s : term  ) : ren_term zetapoly_type zetaterm (subst_term sigmapoly_type sigmaterm s) = subst_term thetapoly_type thetaterm s :=
match s return ren_term zetapoly_type zetaterm (subst_term sigmapoly_type sigmaterm s) = subst_term thetapoly_type thetaterm s with
| var   s => Eqterm s
| app   s0 s1 => congr_app (compSubstRen_term sigmapoly_type sigmaterm zetapoly_type zetaterm thetapoly_type thetaterm Eqpoly_type Eqterm s0) (compSubstRen_term sigmapoly_type sigmaterm zetapoly_type zetaterm thetapoly_type thetaterm Eqpoly_type Eqterm s1)
| abs   s0 s1 => congr_abs (compSubstRen_poly_type sigmapoly_type zetapoly_type thetapoly_type Eqpoly_type s0) (compSubstRen_term (up_term_poly_type sigmapoly_type) (up_term_term sigmaterm) (upRen_term_poly_type zetapoly_type) (upRen_term_term zetaterm) (up_term_poly_type thetapoly_type) (up_term_term thetaterm) (up_subst_ren_term_poly_type (_) (_) (_) Eqpoly_type) (up_subst_ren_term_term (_) (_) (_) (_) Eqterm) s1)
| ty_app   s0 s1 => congr_ty_app (compSubstRen_term sigmapoly_type sigmaterm zetapoly_type zetaterm thetapoly_type thetaterm Eqpoly_type Eqterm s0) (compSubstRen_poly_type sigmapoly_type zetapoly_type thetapoly_type Eqpoly_type s1)
| ty_abs   s0 => congr_ty_abs (compSubstRen_term (up_poly_type_poly_type sigmapoly_type) (up_poly_type_term sigmaterm) (upRen_poly_type_poly_type zetapoly_type) (upRen_poly_type_term zetaterm) (up_poly_type_poly_type thetapoly_type) (up_poly_type_term thetaterm) (up_subst_ren_poly_type_poly_type (_) (_) (_) Eqpoly_type) (up_subst_ren_poly_type_term (_) (_) (_) (_) Eqterm) s0)
end.
Definition up_subst_subst_poly_type_term    (sigma : ( nat  ) -> term  ) (taupoly_type : ( nat  ) -> poly_type ) (tauterm : ( nat  ) -> term  ) (theta : ( nat  ) -> term  ) (Eq : forall x, (funcomp (subst_term taupoly_type tauterm) sigma) x = theta x) : forall x, (funcomp (subst_term (up_poly_type_poly_type taupoly_type) (up_poly_type_term tauterm)) (up_poly_type_term sigma)) x = (up_poly_type_term theta) x :=
fun n => eq_trans (compRenSubst_term shift id (up_poly_type_poly_type taupoly_type) (up_poly_type_term tauterm) (funcomp (up_poly_type_poly_type taupoly_type) shift) (funcomp (up_poly_type_term tauterm) id) (fun x => eq_refl) (fun x => eq_refl) (sigma n)) (eq_trans (eq_sym (compSubstRen_term taupoly_type tauterm shift id (funcomp (ren_poly_type shift) taupoly_type) (funcomp (ren_term shift id) tauterm) (fun x => eq_refl) (fun x => eq_refl) (sigma n))) (ap (ren_term shift id) (Eq n))).
Definition up_subst_subst_term_poly_type    (sigma : ( nat  ) -> poly_type ) (taupoly_type : ( nat  ) -> poly_type ) (theta : ( nat  ) -> poly_type ) (Eq : forall x, (funcomp (subst_poly_type taupoly_type) sigma) x = theta x) : forall x, (funcomp (subst_poly_type (up_term_poly_type taupoly_type)) (up_term_poly_type sigma)) x = (up_term_poly_type theta) x :=
fun n => eq_trans (compRenSubst_poly_type id (up_term_poly_type taupoly_type) (funcomp (up_term_poly_type taupoly_type) id) (fun x => eq_refl) (sigma n)) (eq_trans (eq_sym (compSubstRen_poly_type taupoly_type id (funcomp (ren_poly_type id) taupoly_type) (fun x => eq_refl) (sigma n))) (ap (ren_poly_type id) (Eq n))).
Definition up_subst_subst_term_term    (sigma : ( nat  ) -> term  ) (taupoly_type : ( nat  ) -> poly_type ) (tauterm : ( nat  ) -> term  ) (theta : ( nat  ) -> term  ) (Eq : forall x, (funcomp (subst_term taupoly_type tauterm) sigma) x = theta x) : forall x, (funcomp (subst_term (up_term_poly_type taupoly_type) (up_term_term tauterm)) (up_term_term sigma)) x = (up_term_term theta) x :=
fun n => match n with
| S n => eq_trans (compRenSubst_term id shift (up_term_poly_type taupoly_type) (up_term_term tauterm) (funcomp (up_term_poly_type taupoly_type) id) (funcomp (up_term_term tauterm) shift) (fun x => eq_refl) (fun x => eq_refl) (sigma n)) (eq_trans (eq_sym (compSubstRen_term taupoly_type tauterm id shift (funcomp (ren_poly_type id) taupoly_type) (funcomp (ren_term id shift) tauterm) (fun x => eq_refl) (fun x => eq_refl) (sigma n))) (ap (ren_term id shift) (Eq n)))
| 0 => eq_refl
end.
Fixpoint compSubstSubst_term    (sigmapoly_type : ( nat  ) -> poly_type ) (sigmaterm : ( nat  ) -> term  ) (taupoly_type : ( nat  ) -> poly_type ) (tauterm : ( nat  ) -> term  ) (thetapoly_type : ( nat  ) -> poly_type ) (thetaterm : ( nat  ) -> term  ) (Eqpoly_type : forall x, (funcomp (subst_poly_type taupoly_type) sigmapoly_type) x = thetapoly_type x) (Eqterm : forall x, (funcomp (subst_term taupoly_type tauterm) sigmaterm) x = thetaterm x) (s : term  ) : subst_term taupoly_type tauterm (subst_term sigmapoly_type sigmaterm s) = subst_term thetapoly_type thetaterm s :=
match s return subst_term taupoly_type tauterm (subst_term sigmapoly_type sigmaterm s) = subst_term thetapoly_type thetaterm s with
| var   s => Eqterm s
| app   s0 s1 => congr_app (compSubstSubst_term sigmapoly_type sigmaterm taupoly_type tauterm thetapoly_type thetaterm Eqpoly_type Eqterm s0) (compSubstSubst_term sigmapoly_type sigmaterm taupoly_type tauterm thetapoly_type thetaterm Eqpoly_type Eqterm s1)
| abs   s0 s1 => congr_abs (compSubstSubst_poly_type sigmapoly_type taupoly_type thetapoly_type Eqpoly_type s0) (compSubstSubst_term (up_term_poly_type sigmapoly_type) (up_term_term sigmaterm) (up_term_poly_type taupoly_type) (up_term_term tauterm) (up_term_poly_type thetapoly_type) (up_term_term thetaterm) (up_subst_subst_term_poly_type (_) (_) (_) Eqpoly_type) (up_subst_subst_term_term (_) (_) (_) (_) Eqterm) s1)
| ty_app   s0 s1 => congr_ty_app (compSubstSubst_term sigmapoly_type sigmaterm taupoly_type tauterm thetapoly_type thetaterm Eqpoly_type Eqterm s0) (compSubstSubst_poly_type sigmapoly_type taupoly_type thetapoly_type Eqpoly_type s1)
| ty_abs   s0 => congr_ty_abs (compSubstSubst_term (up_poly_type_poly_type sigmapoly_type) (up_poly_type_term sigmaterm) (up_poly_type_poly_type taupoly_type) (up_poly_type_term tauterm) (up_poly_type_poly_type thetapoly_type) (up_poly_type_term thetaterm) (up_subst_subst_poly_type_poly_type (_) (_) (_) Eqpoly_type) (up_subst_subst_poly_type_term (_) (_) (_) (_) Eqterm) s0)
end.
Definition rinstInst_up_poly_type_term   (xi : ( nat  ) -> nat ) (sigma : ( nat  ) -> term  ) (Eq : forall x, (funcomp (var  ) xi) x = sigma x) : forall x, (funcomp (var  ) (upRen_poly_type_term xi)) x = (up_poly_type_term sigma) x :=
fun n => ap (ren_term shift id) (Eq n).
Definition rinstInst_up_term_poly_type   (xi : ( nat  ) -> nat ) (sigma : ( nat  ) -> poly_type ) (Eq : forall x, (funcomp (poly_var ) xi) x = sigma x) : forall x, (funcomp (poly_var ) (upRen_term_poly_type xi)) x = (up_term_poly_type sigma) x :=
fun n => ap (ren_poly_type id) (Eq n).
Definition rinstInst_up_term_term   (xi : ( nat  ) -> nat ) (sigma : ( nat  ) -> term  ) (Eq : forall x, (funcomp (var  ) xi) x = sigma x) : forall x, (funcomp (var  ) (upRen_term_term xi)) x = (up_term_term sigma) x :=
fun n => match n with
| S n => ap (ren_term id shift) (Eq n)
| 0 => eq_refl
end.
Fixpoint rinst_inst_term   (xipoly_type : ( nat  ) -> nat ) (xiterm : ( nat  ) -> nat ) (sigmapoly_type : ( nat  ) -> poly_type ) (sigmaterm : ( nat  ) -> term  ) (Eqpoly_type : forall x, (funcomp (poly_var ) xipoly_type) x = sigmapoly_type x) (Eqterm : forall x, (funcomp (var  ) xiterm) x = sigmaterm x) (s : term  ) : ren_term xipoly_type xiterm s = subst_term sigmapoly_type sigmaterm s :=
match s return ren_term xipoly_type xiterm s = subst_term sigmapoly_type sigmaterm s with
| var   s => Eqterm s
| app   s0 s1 => congr_app (rinst_inst_term xipoly_type xiterm sigmapoly_type sigmaterm Eqpoly_type Eqterm s0) (rinst_inst_term xipoly_type xiterm sigmapoly_type sigmaterm Eqpoly_type Eqterm s1)
| abs   s0 s1 => congr_abs (rinst_inst_poly_type xipoly_type sigmapoly_type Eqpoly_type s0) (rinst_inst_term (upRen_term_poly_type xipoly_type) (upRen_term_term xiterm) (up_term_poly_type sigmapoly_type) (up_term_term sigmaterm) (rinstInst_up_term_poly_type (_) (_) Eqpoly_type) (rinstInst_up_term_term (_) (_) Eqterm) s1)
| ty_app   s0 s1 => congr_ty_app (rinst_inst_term xipoly_type xiterm sigmapoly_type sigmaterm Eqpoly_type Eqterm s0) (rinst_inst_poly_type xipoly_type sigmapoly_type Eqpoly_type s1)
| ty_abs   s0 => congr_ty_abs (rinst_inst_term (upRen_poly_type_poly_type xipoly_type) (upRen_poly_type_term xiterm) (up_poly_type_poly_type sigmapoly_type) (up_poly_type_term sigmaterm) (rinstInst_up_poly_type_poly_type (_) (_) Eqpoly_type) (rinstInst_up_poly_type_term (_) (_) Eqterm) s0)
end.

Lemma rinstInst_term   (xipoly_type : ( nat  ) -> nat ) (xiterm : ( nat  ) -> nat ) : ren_term xipoly_type xiterm === subst_term (funcomp (poly_var ) xipoly_type) (funcomp (var  ) xiterm) .