DecSyn.Autosubst2.syntax

Require Import core unscoped.

Require Import Setoid Morphisms Relation_Definitions.

Module Core.

Inductive BTag : Type :=
  | PPi : BTag
  | PSig : BTag.

Lemma congr_PPi : PPi = PPi.
Proof.
exact (eq_refl).
Qed.


Lemma congr_PSig : PSig = PSig.
Proof.
exact (eq_refl).
Qed.


Inductive PTag : Type :=
  | PL : PTag
  | PR : PTag.

Lemma congr_PL : PL = PL.
Proof.
exact (eq_refl).
Qed.


Lemma congr_PR : PR = PR.
Proof.
exact (eq_refl).
Qed.


Inductive PTm : Type :=
  | VarPTm : PTm
  | PAbs : PTm PTm
  | PApp : PTm PTm PTm
  | PPair : PTm PTm PTm
  | PProj : PTag PTm PTm
  | PBind : BTag PTm PTm PTm
  | PUniv : PTm
  | PNat : PTm
  | PZero : PTm
  | PSuc : PTm PTm
  | PInd : PTm PTm PTm PTm PTm.

Lemma congr_PAbs {s0 : PTm} {t0 : PTm} (H0 : = ) : PAbs = PAbs .
Proof.
exact (eq_trans eq_refl (ap (fun x PAbs x) )).
Qed.


Lemma congr_PApp {s0 : PTm} {s1 : PTm} {t0 : PTm} {t1 : PTm} (H0 : = )
  (H1 : = ) : PApp = PApp .
Proof.
exact (eq_trans (eq_trans eq_refl (ap (fun x PApp x ) ))
         (ap (fun x PApp x) )).
Qed.


Lemma congr_PPair {s0 : PTm} {s1 : PTm} {t0 : PTm} {t1 : PTm} (H0 : = )
  (H1 : = ) : PPair = PPair .
Proof.
exact (eq_trans (eq_trans eq_refl (ap (fun x PPair x ) ))
         (ap (fun x PPair x) )).
Qed.


Lemma congr_PProj {s0 : PTag} {s1 : PTm} {t0 : PTag} {t1 : PTm}
  (H0 : = ) (H1 : = ) : PProj = PProj .
Proof.
exact (eq_trans (eq_trans eq_refl (ap (fun x PProj x ) ))
         (ap (fun x PProj x) )).
Qed.


Lemma congr_PBind {s0 : BTag} {s1 : PTm} {s2 : PTm} {t0 : BTag} {t1 : PTm}
  {t2 : PTm} (H0 : = ) (H1 : = ) (H2 : = ) :
  PBind = PBind .
Proof.
exact (eq_trans
         (eq_trans (eq_trans eq_refl (ap (fun x PBind x ) ))
            (ap (fun x PBind x ) ))
         (ap (fun x PBind x) )).
Qed.


Lemma congr_PUniv {s0 : } {t0 : } (H0 : = ) : PUniv = PUniv .
Proof.
exact (eq_trans eq_refl (ap (fun x PUniv x) )).
Qed.


Lemma congr_PNat : PNat = PNat.
Proof.
exact (eq_refl).
Qed.


Lemma congr_PZero : PZero = PZero.
Proof.
exact (eq_refl).
Qed.


Lemma congr_PSuc {s0 : PTm} {t0 : PTm} (H0 : = ) : PSuc = PSuc .
Proof.
exact (eq_trans eq_refl (ap (fun x PSuc x) )).
Qed.


Lemma congr_PInd {s0 : PTm} {s1 : PTm} {s2 : PTm} {s3 : PTm} {t0 : PTm}
  {t1 : PTm} {t2 : PTm} {t3 : PTm} (H0 : = ) (H1 : = )
  (H2 : = ) (H3 : = ) : PInd = PInd .
Proof.
exact (eq_trans
         (eq_trans
            (eq_trans (eq_trans eq_refl (ap (fun x PInd x ) ))
               (ap (fun x PInd x ) ))
            (ap (fun x PInd x ) ))
         (ap (fun x PInd x) )).
Qed.


Lemma upRen_PTm_PTm (xi : ) : .
Proof.
exact (up_ren ).
Defined.


Fixpoint ren_PTm (xi_PTm : ) (s : PTm) {struct s} : PTm :=
  match s with
  | VarPTm VarPTm (xi_PTm )
  | PAbs PAbs (ren_PTm (upRen_PTm_PTm xi_PTm) )
  | PApp PApp (ren_PTm xi_PTm ) (ren_PTm xi_PTm )
  | PPair PPair (ren_PTm xi_PTm ) (ren_PTm xi_PTm )
  | PProj PProj (ren_PTm xi_PTm )
  | PBind
      PBind (ren_PTm xi_PTm ) (ren_PTm (upRen_PTm_PTm xi_PTm) )
  | PUniv PUniv
  | PNat PNat
  | PZero PZero
  | PSuc PSuc (ren_PTm xi_PTm )
  | PInd
      PInd (ren_PTm (upRen_PTm_PTm xi_PTm) ) (ren_PTm xi_PTm )
        (ren_PTm xi_PTm )
        (ren_PTm (upRen_PTm_PTm (upRen_PTm_PTm xi_PTm)) )
  end.

Lemma up_PTm_PTm (sigma : PTm) : PTm.
Proof.
exact (scons (VarPTm var_zero) (funcomp (ren_PTm shift) )).
Defined.


Fixpoint subst_PTm (sigma_PTm : PTm) (s : PTm) {struct s} : PTm :=
  match s with
  | VarPTm sigma_PTm
  | PAbs PAbs (subst_PTm (up_PTm_PTm sigma_PTm) )
  | PApp PApp (subst_PTm sigma_PTm ) (subst_PTm sigma_PTm )
  | PPair PPair (subst_PTm sigma_PTm ) (subst_PTm sigma_PTm )
  | PProj PProj (subst_PTm sigma_PTm )
  | PBind
      PBind (subst_PTm sigma_PTm ) (subst_PTm (up_PTm_PTm sigma_PTm) )
  | PUniv PUniv
  | PNat PNat
  | PZero PZero
  | PSuc PSuc (subst_PTm sigma_PTm )
  | PInd
      PInd (subst_PTm (up_PTm_PTm sigma_PTm) ) (subst_PTm sigma_PTm )
        (subst_PTm sigma_PTm )
        (subst_PTm (up_PTm_PTm (up_PTm_PTm sigma_PTm)) )
  end.

Lemma upId_PTm_PTm (sigma : PTm) (Eq : x, x = VarPTm x) :
   x, up_PTm_PTm x = VarPTm x.
Proof.
exact (fun n
       match n with
       | S n' ap (ren_PTm shift) (Eq n')
       | O eq_refl
       end).
Qed.


Fixpoint idSubst_PTm (sigma_PTm : PTm)
(Eq_PTm : x, sigma_PTm x = VarPTm x) (s : PTm) {struct s} :
subst_PTm sigma_PTm s = s :=
  match s with
  | VarPTm Eq_PTm
  | PAbs
      congr_PAbs
        (idSubst_PTm (up_PTm_PTm sigma_PTm) (upId_PTm_PTm _ Eq_PTm) )
  | PApp
      congr_PApp (idSubst_PTm sigma_PTm Eq_PTm )
        (idSubst_PTm sigma_PTm Eq_PTm )
  | PPair
      congr_PPair (idSubst_PTm sigma_PTm Eq_PTm )
        (idSubst_PTm sigma_PTm Eq_PTm )
  | PProj congr_PProj (eq_refl ) (idSubst_PTm sigma_PTm Eq_PTm )
  | PBind
      congr_PBind (eq_refl ) (idSubst_PTm sigma_PTm Eq_PTm )
        (idSubst_PTm (up_PTm_PTm sigma_PTm) (upId_PTm_PTm _ Eq_PTm) )
  | PUniv congr_PUniv (eq_refl )
  | PNat congr_PNat
  | PZero congr_PZero
  | PSuc congr_PSuc (idSubst_PTm sigma_PTm Eq_PTm )
  | PInd
      congr_PInd
        (idSubst_PTm (up_PTm_PTm sigma_PTm) (upId_PTm_PTm _ Eq_PTm) )
        (idSubst_PTm sigma_PTm Eq_PTm ) (idSubst_PTm sigma_PTm Eq_PTm )
        (idSubst_PTm (up_PTm_PTm (up_PTm_PTm sigma_PTm))
           (upId_PTm_PTm _ (upId_PTm_PTm _ Eq_PTm)) )
  end.

Lemma upExtRen_PTm_PTm (xi : ) (zeta : )
  (Eq : x, x = x) :
   x, upRen_PTm_PTm x = upRen_PTm_PTm x.
Proof.
exact (fun n match n with
                | S n' ap shift (Eq n')
                | O eq_refl
                end).
Qed.


Fixpoint extRen_PTm (xi_PTm : ) (zeta_PTm : )
(Eq_PTm : x, xi_PTm x = zeta_PTm x) (s : PTm) {struct s} :
ren_PTm xi_PTm s = ren_PTm zeta_PTm s :=
  match s with
  | VarPTm ap (VarPTm) (Eq_PTm )
  | PAbs
      congr_PAbs
        (extRen_PTm (upRen_PTm_PTm xi_PTm) (upRen_PTm_PTm zeta_PTm)
           (upExtRen_PTm_PTm _ _ Eq_PTm) )
  | PApp
      congr_PApp (extRen_PTm xi_PTm zeta_PTm Eq_PTm )
        (extRen_PTm xi_PTm zeta_PTm Eq_PTm )
  | PPair
      congr_PPair (extRen_PTm xi_PTm zeta_PTm Eq_PTm )
        (extRen_PTm xi_PTm zeta_PTm Eq_PTm )
  | PProj
      congr_PProj (eq_refl ) (extRen_PTm xi_PTm zeta_PTm Eq_PTm )
  | PBind
      congr_PBind (eq_refl ) (extRen_PTm xi_PTm zeta_PTm Eq_PTm )
        (extRen_PTm (upRen_PTm_PTm xi_PTm) (upRen_PTm_PTm zeta_PTm)
           (upExtRen_PTm_PTm _ _ Eq_PTm) )
  | PUniv congr_PUniv (eq_refl )
  | PNat congr_PNat
  | PZero congr_PZero
  | PSuc congr_PSuc (extRen_PTm xi_PTm zeta_PTm Eq_PTm )
  | PInd
      congr_PInd
        (extRen_PTm (upRen_PTm_PTm xi_PTm) (upRen_PTm_PTm zeta_PTm)
           (upExtRen_PTm_PTm _ _ Eq_PTm) )
        (extRen_PTm xi_PTm zeta_PTm Eq_PTm )
        (extRen_PTm xi_PTm zeta_PTm Eq_PTm )
        (extRen_PTm (upRen_PTm_PTm (upRen_PTm_PTm xi_PTm))
           (upRen_PTm_PTm (upRen_PTm_PTm zeta_PTm))
           (upExtRen_PTm_PTm _ _ (upExtRen_PTm_PTm _ _ Eq_PTm)) )
  end.

Lemma upExt_PTm_PTm (sigma : PTm) (tau : PTm)
  (Eq : x, x = x) :
   x, up_PTm_PTm x = up_PTm_PTm x.
Proof.
exact (fun n
       match n with
       | S n' ap (ren_PTm shift) (Eq n')
       | O eq_refl
       end).
Qed.


Fixpoint ext_PTm (sigma_PTm : PTm) (tau_PTm : PTm)
(Eq_PTm : x, sigma_PTm x = tau_PTm x) (s : PTm) {struct s} :
subst_PTm sigma_PTm s = subst_PTm tau_PTm s :=
  match s with
  | VarPTm Eq_PTm
  | PAbs
      congr_PAbs
        (ext_PTm (up_PTm_PTm sigma_PTm) (up_PTm_PTm tau_PTm)
           (upExt_PTm_PTm _ _ Eq_PTm) )
  | PApp
      congr_PApp (ext_PTm sigma_PTm tau_PTm Eq_PTm )
        (ext_PTm sigma_PTm tau_PTm Eq_PTm )
  | PPair
      congr_PPair (ext_PTm sigma_PTm tau_PTm Eq_PTm )
        (ext_PTm sigma_PTm tau_PTm Eq_PTm )
  | PProj
      congr_PProj (eq_refl ) (ext_PTm sigma_PTm tau_PTm Eq_PTm )
  | PBind
      congr_PBind (eq_refl ) (ext_PTm sigma_PTm tau_PTm Eq_PTm )
        (ext_PTm (up_PTm_PTm sigma_PTm) (up_PTm_PTm tau_PTm)
           (upExt_PTm_PTm _ _ Eq_PTm) )
  | PUniv congr_PUniv (eq_refl )
  | PNat congr_PNat
  | PZero congr_PZero
  | PSuc congr_PSuc (ext_PTm sigma_PTm tau_PTm Eq_PTm )
  | PInd
      congr_PInd
        (ext_PTm (up_PTm_PTm sigma_PTm) (up_PTm_PTm tau_PTm)
           (upExt_PTm_PTm _ _ Eq_PTm) )
        (ext_PTm sigma_PTm tau_PTm Eq_PTm )
        (ext_PTm sigma_PTm tau_PTm Eq_PTm )
        (ext_PTm (up_PTm_PTm (up_PTm_PTm sigma_PTm))
           (up_PTm_PTm (up_PTm_PTm tau_PTm))
           (upExt_PTm_PTm _ _ (upExt_PTm_PTm _ _ Eq_PTm)) )
  end.

Lemma up_ren_ren_PTm_PTm (xi : ) (zeta : )
  (rho : ) (Eq : x, funcomp x = x) :
   x,
  funcomp (upRen_PTm_PTm ) (upRen_PTm_PTm ) x = upRen_PTm_PTm x.
Proof.
exact (up_ren_ren Eq).
Qed.


Fixpoint compRenRen_PTm (xi_PTm : ) (zeta_PTm : )
(rho_PTm : )
(Eq_PTm : x, funcomp zeta_PTm xi_PTm x = rho_PTm x) (s : PTm) {struct
 s} : ren_PTm zeta_PTm (ren_PTm xi_PTm s) = ren_PTm rho_PTm s :=
  match s with
  | VarPTm ap (VarPTm) (Eq_PTm )
  | PAbs
      congr_PAbs
        (compRenRen_PTm (upRen_PTm_PTm xi_PTm) (upRen_PTm_PTm zeta_PTm)
           (upRen_PTm_PTm rho_PTm) (up_ren_ren _ _ _ Eq_PTm) )
  | PApp
      congr_PApp (compRenRen_PTm xi_PTm zeta_PTm rho_PTm Eq_PTm )
        (compRenRen_PTm xi_PTm zeta_PTm rho_PTm Eq_PTm )
  | PPair
      congr_PPair (compRenRen_PTm xi_PTm zeta_PTm rho_PTm Eq_PTm )
        (compRenRen_PTm xi_PTm zeta_PTm rho_PTm Eq_PTm )
  | PProj
      congr_PProj (eq_refl )
        (compRenRen_PTm xi_PTm zeta_PTm rho_PTm Eq_PTm )
  | PBind
      congr_PBind (eq_refl )
        (compRenRen_PTm xi_PTm zeta_PTm rho_PTm Eq_PTm )
        (compRenRen_PTm (upRen_PTm_PTm xi_PTm) (upRen_PTm_PTm zeta_PTm)
           (upRen_PTm_PTm rho_PTm) (up_ren_ren _ _ _ Eq_PTm) )
  | PUniv congr_PUniv (eq_refl )
  | PNat congr_PNat
  | PZero congr_PZero
  | PSuc congr_PSuc (compRenRen_PTm xi_PTm zeta_PTm rho_PTm Eq_PTm )
  | PInd
      congr_PInd
        (compRenRen_PTm (upRen_PTm_PTm xi_PTm) (upRen_PTm_PTm zeta_PTm)
           (upRen_PTm_PTm rho_PTm) (up_ren_ren _ _ _ Eq_PTm) )
        (compRenRen_PTm xi_PTm zeta_PTm rho_PTm Eq_PTm )
        (compRenRen_PTm xi_PTm zeta_PTm rho_PTm Eq_PTm )
        (compRenRen_PTm (upRen_PTm_PTm (upRen_PTm_PTm xi_PTm))
           (upRen_PTm_PTm (upRen_PTm_PTm zeta_PTm))
           (upRen_PTm_PTm (upRen_PTm_PTm rho_PTm))
           (up_ren_ren _ _ _ (up_ren_ren _ _ _ Eq_PTm)) )
  end.

Lemma up_ren_subst_PTm_PTm (xi : ) (tau : PTm)
  (theta : PTm) (Eq : x, funcomp x = x) :
   x,
  funcomp (up_PTm_PTm ) (upRen_PTm_PTm ) x = up_PTm_PTm x.
Proof.
exact (fun n
       match n with
       | S n' ap (ren_PTm shift) (Eq n')
       | O eq_refl
       end).
Qed.


Fixpoint compRenSubst_PTm (xi_PTm : ) (tau_PTm : PTm)
(theta_PTm : PTm)
(Eq_PTm : x, funcomp tau_PTm xi_PTm x = theta_PTm x) (s : PTm) {struct
 s} : subst_PTm tau_PTm (ren_PTm xi_PTm s) = subst_PTm theta_PTm s :=
  match s with
  | VarPTm Eq_PTm
  | PAbs
      congr_PAbs
        (compRenSubst_PTm (upRen_PTm_PTm xi_PTm) (up_PTm_PTm tau_PTm)
           (up_PTm_PTm theta_PTm) (up_ren_subst_PTm_PTm _ _ _ Eq_PTm) )
  | PApp
      congr_PApp (compRenSubst_PTm xi_PTm tau_PTm theta_PTm Eq_PTm )
        (compRenSubst_PTm xi_PTm tau_PTm theta_PTm Eq_PTm )
  | PPair
      congr_PPair (compRenSubst_PTm xi_PTm tau_PTm theta_PTm Eq_PTm )
        (compRenSubst_PTm xi_PTm tau_PTm theta_PTm Eq_PTm )
  | PProj
      congr_PProj (eq_refl )
        (compRenSubst_PTm xi_PTm tau_PTm theta_PTm Eq_PTm )
  | PBind
      congr_PBind (eq_refl )
        (compRenSubst_PTm xi_PTm tau_PTm theta_PTm Eq_PTm )
        (compRenSubst_PTm (upRen_PTm_PTm xi_PTm) (up_PTm_PTm tau_PTm)
           (up_PTm_PTm theta_PTm) (up_ren_subst_PTm_PTm _ _ _ Eq_PTm) )
  | PUniv congr_PUniv (eq_refl )
  | PNat congr_PNat
  | PZero congr_PZero
  | PSuc
      congr_PSuc (compRenSubst_PTm xi_PTm tau_PTm theta_PTm Eq_PTm )
  | PInd
      congr_PInd
        (compRenSubst_PTm (upRen_PTm_PTm xi_PTm) (up_PTm_PTm tau_PTm)
           (up_PTm_PTm theta_PTm) (up_ren_subst_PTm_PTm _ _ _ Eq_PTm) )
        (compRenSubst_PTm xi_PTm tau_PTm theta_PTm Eq_PTm )
        (compRenSubst_PTm xi_PTm tau_PTm theta_PTm Eq_PTm )
        (compRenSubst_PTm (upRen_PTm_PTm (upRen_PTm_PTm xi_PTm))
           (up_PTm_PTm (up_PTm_PTm tau_PTm))
           (up_PTm_PTm (up_PTm_PTm theta_PTm))
           (up_ren_subst_PTm_PTm _ _ _ (up_ren_subst_PTm_PTm _ _ _ Eq_PTm))
           )
  end.

Lemma up_subst_ren_PTm_PTm (sigma : PTm) (zeta_PTm : )
  (theta : PTm)
  (Eq : x, funcomp (ren_PTm zeta_PTm) x = x) :
   x,
  funcomp (ren_PTm (upRen_PTm_PTm zeta_PTm)) (up_PTm_PTm ) x =
  up_PTm_PTm x.
Proof.
exact (fun n
       match n with
       | S n'
           eq_trans
             (compRenRen_PTm shift (upRen_PTm_PTm zeta_PTm)
                (funcomp shift zeta_PTm) (fun x eq_refl) ( n'))
             (eq_trans
                (eq_sym
                   (compRenRen_PTm zeta_PTm shift (funcomp shift zeta_PTm)
                      (fun x eq_refl) ( n')))
                (ap (ren_PTm shift) (Eq n')))
       | O eq_refl
       end).
Qed.


Fixpoint compSubstRen_PTm (sigma_PTm : PTm) (zeta_PTm : )
(theta_PTm : PTm)
(Eq_PTm : x, funcomp (ren_PTm zeta_PTm) sigma_PTm x = theta_PTm x)
(s : PTm) {struct s} :
ren_PTm zeta_PTm (subst_PTm sigma_PTm s) = subst_PTm theta_PTm s :=
  match s with
  | VarPTm Eq_PTm
  | PAbs
      congr_PAbs
        (compSubstRen_PTm (up_PTm_PTm sigma_PTm) (upRen_PTm_PTm zeta_PTm)
           (up_PTm_PTm theta_PTm) (up_subst_ren_PTm_PTm _ _ _ Eq_PTm) )
  | PApp
      congr_PApp (compSubstRen_PTm sigma_PTm zeta_PTm theta_PTm Eq_PTm )
        (compSubstRen_PTm sigma_PTm zeta_PTm theta_PTm Eq_PTm )
  | PPair
      congr_PPair (compSubstRen_PTm sigma_PTm zeta_PTm theta_PTm Eq_PTm )
        (compSubstRen_PTm sigma_PTm zeta_PTm theta_PTm Eq_PTm )
  | PProj
      congr_PProj (eq_refl )
        (compSubstRen_PTm sigma_PTm zeta_PTm theta_PTm Eq_PTm )
  | PBind
      congr_PBind (eq_refl )
        (compSubstRen_PTm sigma_PTm zeta_PTm theta_PTm Eq_PTm )
        (compSubstRen_PTm (up_PTm_PTm sigma_PTm) (upRen_PTm_PTm zeta_PTm)
           (up_PTm_PTm theta_PTm) (up_subst_ren_PTm_PTm _ _ _ Eq_PTm) )
  | PUniv congr_PUniv (eq_refl )
  | PNat congr_PNat
  | PZero congr_PZero
  | PSuc
      congr_PSuc (compSubstRen_PTm sigma_PTm zeta_PTm theta_PTm Eq_PTm )
  | PInd
      congr_PInd
        (compSubstRen_PTm (up_PTm_PTm sigma_PTm) (upRen_PTm_PTm zeta_PTm)
           (up_PTm_PTm theta_PTm) (up_subst_ren_PTm_PTm _ _ _ Eq_PTm) )
        (compSubstRen_PTm sigma_PTm zeta_PTm theta_PTm Eq_PTm )
        (compSubstRen_PTm sigma_PTm zeta_PTm theta_PTm Eq_PTm )
        (compSubstRen_PTm (up_PTm_PTm (up_PTm_PTm sigma_PTm))
           (upRen_PTm_PTm (upRen_PTm_PTm zeta_PTm))
           (up_PTm_PTm (up_PTm_PTm theta_PTm))
           (up_subst_ren_PTm_PTm _ _ _ (up_subst_ren_PTm_PTm _ _ _ Eq_PTm))
           )
  end.

Lemma up_subst_subst_PTm_PTm (sigma : PTm) (tau_PTm : PTm)
  (theta : PTm)
  (Eq : x, funcomp (subst_PTm tau_PTm) x = x) :
   x,
  funcomp (subst_PTm (up_PTm_PTm tau_PTm)) (up_PTm_PTm ) x =
  up_PTm_PTm x.
Proof.
exact (fun n
       match n with
       | S n'
           eq_trans
             (compRenSubst_PTm shift (up_PTm_PTm tau_PTm)
                (funcomp (up_PTm_PTm tau_PTm) shift) (fun x eq_refl)
                ( n'))
             (eq_trans
                (eq_sym
                   (compSubstRen_PTm tau_PTm shift
                      (funcomp (ren_PTm shift) tau_PTm) (fun x eq_refl)
                      ( n'))) (ap (ren_PTm shift) (Eq n')))
       | O eq_refl
       end).
Qed.


Fixpoint compSubstSubst_PTm (sigma_PTm : PTm) (tau_PTm : PTm)
(theta_PTm : PTm)
(Eq_PTm : x, funcomp (subst_PTm tau_PTm) sigma_PTm x = theta_PTm x)
(s : PTm) {struct s} :
subst_PTm tau_PTm (subst_PTm sigma_PTm s) = subst_PTm theta_PTm s :=
  match s with
  | VarPTm Eq_PTm
  | PAbs
      congr_PAbs
        (compSubstSubst_PTm (up_PTm_PTm sigma_PTm) (up_PTm_PTm tau_PTm)
           (up_PTm_PTm theta_PTm) (up_subst_subst_PTm_PTm _ _ _ Eq_PTm) )
  | PApp
      congr_PApp (compSubstSubst_PTm sigma_PTm tau_PTm theta_PTm Eq_PTm )
        (compSubstSubst_PTm sigma_PTm tau_PTm theta_PTm Eq_PTm )
  | PPair
      congr_PPair (compSubstSubst_PTm sigma_PTm tau_PTm theta_PTm Eq_PTm )
        (compSubstSubst_PTm sigma_PTm tau_PTm theta_PTm Eq_PTm )
  | PProj
      congr_PProj (eq_refl )
        (compSubstSubst_PTm sigma_PTm tau_PTm theta_PTm Eq_PTm )
  | PBind
      congr_PBind (eq_refl )
        (compSubstSubst_PTm sigma_PTm tau_PTm theta_PTm Eq_PTm )
        (compSubstSubst_PTm (up_PTm_PTm sigma_PTm) (up_PTm_PTm tau_PTm)
           (up_PTm_PTm theta_PTm) (up_subst_subst_PTm_PTm _ _ _ Eq_PTm) )
  | PUniv congr_PUniv (eq_refl )
  | PNat congr_PNat
  | PZero congr_PZero
  | PSuc
      congr_PSuc (compSubstSubst_PTm sigma_PTm tau_PTm theta_PTm Eq_PTm )
  | PInd
      congr_PInd
        (compSubstSubst_PTm (up_PTm_PTm sigma_PTm) (up_PTm_PTm tau_PTm)
           (up_PTm_PTm theta_PTm) (up_subst_subst_PTm_PTm _ _ _ Eq_PTm) )
        (compSubstSubst_PTm sigma_PTm tau_PTm theta_PTm Eq_PTm )
        (compSubstSubst_PTm sigma_PTm tau_PTm theta_PTm Eq_PTm )
        (compSubstSubst_PTm (up_PTm_PTm (up_PTm_PTm sigma_PTm))
           (up_PTm_PTm (up_PTm_PTm tau_PTm))
           (up_PTm_PTm (up_PTm_PTm theta_PTm))
           (up_subst_subst_PTm_PTm _ _ _
              (up_subst_subst_PTm_PTm _ _ _ Eq_PTm)) )
  end.

Lemma renRen_PTm (xi_PTm : ) (zeta_PTm : ) (s : PTm) :
  ren_PTm zeta_PTm (ren_PTm xi_PTm s) = ren_PTm (funcomp zeta_PTm xi_PTm) s.
Proof.
exact (compRenRen_PTm xi_PTm zeta_PTm _ (fun n eq_refl) s).
Qed.


Lemma renRen'_PTm_pointwise (xi_PTm : ) (zeta_PTm : ) :
  pointwise_relation _ eq (funcomp (ren_PTm zeta_PTm) (ren_PTm xi_PTm))
    (ren_PTm (funcomp zeta_PTm xi_PTm)).
Proof.
exact (fun s compRenRen_PTm xi_PTm zeta_PTm _ (fun n eq_refl) s).
Qed.


Lemma renSubst_PTm (xi_PTm : ) (tau_PTm : PTm) (s : PTm) :
  subst_PTm tau_PTm (ren_PTm xi_PTm s) = subst_PTm (funcomp tau_PTm xi_PTm) s.
Proof.
exact (compRenSubst_PTm xi_PTm tau_PTm _ (fun n eq_refl) s).
Qed.


Lemma renSubst_PTm_pointwise (xi_PTm : ) (tau_PTm : PTm) :
  pointwise_relation _ eq (funcomp (subst_PTm tau_PTm) (ren_PTm xi_PTm))
    (subst_PTm (funcomp tau_PTm xi_PTm)).
Proof.
exact (fun s compRenSubst_PTm xi_PTm tau_PTm _ (fun n eq_refl) s).
Qed.


Lemma substRen_PTm (sigma_PTm : PTm) (zeta_PTm : ) (s : PTm)
  :
  ren_PTm zeta_PTm (subst_PTm sigma_PTm s) =
  subst_PTm (funcomp (ren_PTm zeta_PTm) sigma_PTm) s.
Proof.
exact (compSubstRen_PTm sigma_PTm zeta_PTm _ (fun n eq_refl) s).
Qed.


Lemma substRen_PTm_pointwise (sigma_PTm : PTm) (zeta_PTm : )
  :
  pointwise_relation _ eq (funcomp (ren_PTm zeta_PTm) (subst_PTm sigma_PTm))
    (subst_PTm (funcomp (ren_PTm zeta_PTm) sigma_PTm)).
Proof.
exact (fun s compSubstRen_PTm sigma_PTm zeta_PTm _ (fun n eq_refl) s).
Qed.


Lemma substSubst_PTm (sigma_PTm : PTm) (tau_PTm : PTm)
  (s : PTm) :
  subst_PTm tau_PTm (subst_PTm sigma_PTm s) =
  subst_PTm (funcomp (subst_PTm tau_PTm) sigma_PTm) s.
Proof.
exact (compSubstSubst_PTm sigma_PTm tau_PTm _ (fun n eq_refl) s).
Qed.


Lemma substSubst_PTm_pointwise (sigma_PTm : PTm)
  (tau_PTm : PTm) :
  pointwise_relation _ eq (funcomp (subst_PTm tau_PTm) (subst_PTm sigma_PTm))
    (subst_PTm (funcomp (subst_PTm tau_PTm) sigma_PTm)).
Proof.
exact (fun s compSubstSubst_PTm sigma_PTm tau_PTm _ (fun n eq_refl) s).
Qed.


Lemma rinstInst_up_PTm_PTm (xi : ) (sigma : PTm)
  (Eq : x, funcomp (VarPTm) x = x) :
   x, funcomp (VarPTm) (upRen_PTm_PTm ) x = up_PTm_PTm x.
Proof.
exact (fun n
       match n with
       | S n' ap (ren_PTm shift) (Eq n')
       | O eq_refl
       end).
Qed.


Fixpoint rinst_inst_PTm (xi_PTm : ) (sigma_PTm : PTm)
(Eq_PTm : x, funcomp (VarPTm) xi_PTm x = sigma_PTm x) (s : PTm)
{struct s} : ren_PTm xi_PTm s = subst_PTm sigma_PTm s :=
  match s with
  | VarPTm Eq_PTm
  | PAbs
      congr_PAbs
        (rinst_inst_PTm (upRen_PTm_PTm xi_PTm) (up_PTm_PTm sigma_PTm)
           (rinstInst_up_PTm_PTm _ _ Eq_PTm) )
  | PApp
      congr_PApp (rinst_inst_PTm xi_PTm sigma_PTm Eq_PTm )
        (rinst_inst_PTm xi_PTm sigma_PTm Eq_PTm )
  | PPair
      congr_PPair (rinst_inst_PTm xi_PTm sigma_PTm Eq_PTm )
        (rinst_inst_PTm xi_PTm sigma_PTm Eq_PTm )
  | PProj
      congr_PProj (eq_refl ) (rinst_inst_PTm xi_PTm sigma_PTm Eq_PTm )
  | PBind
      congr_PBind (eq_refl ) (rinst_inst_PTm xi_PTm sigma_PTm Eq_PTm )
        (rinst_inst_PTm (upRen_PTm_PTm xi_PTm) (up_PTm_PTm sigma_PTm)
           (rinstInst_up_PTm_PTm _ _ Eq_PTm) )
  | PUniv congr_PUniv (eq_refl )
  | PNat congr_PNat
  | PZero congr_PZero
  | PSuc congr_PSuc (rinst_inst_PTm xi_PTm sigma_PTm Eq_PTm )
  | PInd
      congr_PInd
        (rinst_inst_PTm (upRen_PTm_PTm xi_PTm) (up_PTm_PTm sigma_PTm)
           (rinstInst_up_PTm_PTm _ _ Eq_PTm) )
        (rinst_inst_PTm xi_PTm sigma_PTm Eq_PTm )
        (rinst_inst_PTm xi_PTm sigma_PTm Eq_PTm )
        (rinst_inst_PTm (upRen_PTm_PTm (upRen_PTm_PTm xi_PTm))
           (up_PTm_PTm (up_PTm_PTm sigma_PTm))
           (rinstInst_up_PTm_PTm _ _ (rinstInst_up_PTm_PTm _ _ Eq_PTm)) )
  end.

Lemma rinstInst'_PTm (xi_PTm : ) (s : PTm) :
  ren_PTm xi_PTm s = subst_PTm (funcomp (VarPTm) xi_PTm) s.
Proof.
exact (rinst_inst_PTm xi_PTm _ (fun n eq_refl) s).
Qed.


Lemma rinstInst'_PTm_pointwise (xi_PTm : ) :
  pointwise_relation _ eq (ren_PTm xi_PTm)
    (subst_PTm (funcomp (VarPTm) xi_PTm)).
Proof.
exact (fun s rinst_inst_PTm xi_PTm _ (fun n eq_refl) s).
Qed.


Lemma instId'_PTm (s : PTm) : subst_PTm (VarPTm) s = s.
Proof.
exact (idSubst_PTm (VarPTm) (fun n eq_refl) s).
Qed.


Lemma instId'_PTm_pointwise : pointwise_relation _ eq (subst_PTm (VarPTm)) id.
Proof.
exact (fun s idSubst_PTm (VarPTm) (fun n eq_refl) s).
Qed.


Lemma rinstId'_PTm (s : PTm) : ren_PTm id s = s.
Proof.
exact (eq_ind_r (fun t t = s) (instId'_PTm s) (rinstInst'_PTm id s)).
Qed.


Lemma rinstId'_PTm_pointwise : pointwise_relation _ eq (@ren_PTm id) id.
Proof.
exact (fun s
       eq_ind_r (fun t t = s) (instId'_PTm s) (rinstInst'_PTm id s)).
Qed.


Lemma varL'_PTm (sigma_PTm : PTm) (x : ) :
  subst_PTm sigma_PTm (VarPTm x) = sigma_PTm x.
Proof.
exact (eq_refl).
Qed.


Lemma varL'_PTm_pointwise (sigma_PTm : PTm) :
  pointwise_relation _ eq (funcomp (subst_PTm sigma_PTm) (VarPTm)) sigma_PTm.
Proof.
exact (fun x eq_refl).
Qed.


Lemma varLRen'_PTm (xi_PTm : ) (x : ) :
  ren_PTm xi_PTm (VarPTm x) = VarPTm (xi_PTm x).
Proof.
exact (eq_refl).
Qed.


Lemma varLRen'_PTm_pointwise (xi_PTm : ) :
  pointwise_relation _ eq (funcomp (ren_PTm xi_PTm) (VarPTm))
    (funcomp (VarPTm) xi_PTm).
Proof.
exact (fun x eq_refl).
Qed.


Class Up_PTm X Y :=
    up_PTm : X Y.

#[global] Instance Subst_PTm : (Subst1 _ _ _) := @subst_PTm.

#[global] Instance Up_PTm_PTm : (Up_PTm _ _) := @up_PTm_PTm.

#[global] Instance Ren_PTm : (Ren1 _ _ _) := @ren_PTm.

#[global]
Instance VarInstance_PTm : (Var _ _) := @VarPTm.

Notation "[ sigma_PTm ]" := (subst_PTm sigma_PTm)
( at level 1, left associativity, only printing) : fscope.

Notation "s [ sigma_PTm ]" := (subst_PTm sigma_PTm s)
( at level 7, left associativity, only printing) : subst_scope.

Notation "↑__PTm" := up_PTm (only printing) : subst_scope.

Notation "↑__PTm" := up_PTm_PTm (only printing) : subst_scope.

Notation "⟨ xi_PTm ⟩" := (ren_PTm xi_PTm)
( at level 1, left associativity, only printing) : fscope.

Notation "s ⟨ xi_PTm ⟩" := (ren_PTm xi_PTm s)
( at level 7, left associativity, only printing) : subst_scope.

Notation "'var'" := VarPTm ( at level 1, only printing) : subst_scope.

Notation "x '__PTm'" := (@ids _ _ VarInstance_PTm x)
( at level 5, format "x __PTm", only printing) : subst_scope.

Notation "x '__PTm'" := (VarPTm x) ( at level 5, format "x __PTm") :
subst_scope.

#[global]
Instance subst_PTm_morphism :
 (Proper (respectful (pointwise_relation _ eq) (respectful eq eq))
    (@subst_PTm)).
Proof.
exact (fun f_PTm g_PTm Eq_PTm s t Eq_st
       eq_ind s (fun t' subst_PTm f_PTm s = subst_PTm g_PTm t')
         (ext_PTm f_PTm g_PTm Eq_PTm s) t Eq_st).
Qed.


#[global]
Instance subst_PTm_morphism2 :
 (Proper (respectful (pointwise_relation _ eq) (pointwise_relation _ eq))
    (@subst_PTm)).
Proof.
exact (fun f_PTm g_PTm Eq_PTm s ext_PTm f_PTm g_PTm Eq_PTm s).
Qed.


#[global]
Instance ren_PTm_morphism :
 (Proper (respectful (pointwise_relation _ eq) (respectful eq eq)) (@ren_PTm)).
Proof.
exact (fun f_PTm g_PTm Eq_PTm s t Eq_st
       eq_ind s (fun t' ren_PTm f_PTm s = ren_PTm g_PTm t')
         (extRen_PTm f_PTm g_PTm Eq_PTm s) t Eq_st).
Qed.


#[global]
Instance ren_PTm_morphism2 :
 (Proper (respectful (pointwise_relation _ eq) (pointwise_relation _ eq))
    (@ren_PTm)).
Proof.
exact (fun f_PTm g_PTm Eq_PTm s extRen_PTm f_PTm g_PTm Eq_PTm s).
Qed.


Ltac auto_unfold := repeat
                     unfold VarInstance_PTm, Var, ids, Ren_PTm, Ren1, ,
                      Up_PTm_PTm, Up_PTm, up_PTm, Subst_PTm, Subst1, .

Tactic Notation "auto_unfold" "in" "*" := repeat
                                           unfold VarInstance_PTm, Var, ids,
                                            Ren_PTm, Ren1, , Up_PTm_PTm,
                                            Up_PTm, up_PTm, Subst_PTm,
                                            Subst1, in *.

Ltac asimpl' := repeat (first
                 [ progress setoid_rewrite substSubst_PTm_pointwise
                 | progress setoid_rewrite substSubst_PTm
                 | progress setoid_rewrite substRen_PTm_pointwise
                 | progress setoid_rewrite substRen_PTm
                 | progress setoid_rewrite renSubst_PTm_pointwise
                 | progress setoid_rewrite renSubst_PTm
                 | progress setoid_rewrite renRen'_PTm_pointwise
                 | progress setoid_rewrite renRen_PTm
                 | progress setoid_rewrite varLRen'_PTm_pointwise
                 | progress setoid_rewrite varLRen'_PTm
                 | progress setoid_rewrite varL'_PTm_pointwise
                 | progress setoid_rewrite varL'_PTm
                 | progress setoid_rewrite rinstId'_PTm_pointwise
                 | progress setoid_rewrite rinstId'_PTm
                 | progress setoid_rewrite instId'_PTm_pointwise
                 | progress setoid_rewrite instId'_PTm
                 | progress unfold up_PTm_PTm, upRen_PTm_PTm, up_ren
                 | progress cbn[subst_PTm ren_PTm]
                 | progress fsimpl ]).

Ltac asimpl := check_no_evars;
                repeat
                 unfold VarInstance_PTm, Var, ids, Ren_PTm, Ren1, ,
                  Up_PTm_PTm, Up_PTm, up_PTm, Subst_PTm, Subst1,
                  in *; asimpl'; minimize.

Tactic Notation "asimpl" "in" hyp(J) := revert J; asimpl; intros J.

Tactic Notation "auto_case" := auto_case ltac:(asimpl; cbn; eauto).

Ltac substify := auto_unfold; try setoid_rewrite rinstInst'_PTm_pointwise;
                  try setoid_rewrite rinstInst'_PTm.

Ltac renamify := auto_unfold;
                  try setoid_rewrite_left ;
                  try setoid_rewrite_left .

End Core.

Module Extra.

Import Core.

#[global] Hint Opaque subst_PTm: rewrite.

#[global] Hint Opaque ren_PTm: rewrite.

End Extra.

Module interface.

Export Core.

Export Extra.

End interface.

Export interface.