From Require Import core unscoped core_axioms unscoped_axioms.

Require Import Setoid Morphisms Relation_Definitions.

Module Core.

Inductive tm : Type :=
  | var_tm : tm
  | tt : tm
  | ff : tm
  | bot : tm
  | trny : tm tm tm tm
  | app : tm tm tm
  | lam : tm tm.

Lemma congr_tt : tt = tt.
Proof.
exact (eq_refl).
Qed.


Lemma congr_ff : ff = ff.
Proof.
exact (eq_refl).
Qed.


Lemma congr_bot : bot = bot.
Proof.
exact (eq_refl).
Qed.


Lemma congr_trny {s0 : tm} {s1 : tm} {s2 : tm} {t0 : tm} {t1 : tm} {t2 : tm}
  (H0 : = ) (H1 : = ) (H2 : = ) :
  trny = trny .
Proof.
exact (eq_trans
         (eq_trans (eq_trans eq_refl (ap ( x trny x ) ))
            (ap ( x trny x ) )) (ap ( x trny x) )).
Qed.


Lemma congr_app {s0 : tm} {s1 : tm} {t0 : tm} {t1 : tm} (H0 : = )
  (H1 : = ) : app = app .
Proof.
exact (eq_trans (eq_trans eq_refl (ap ( x app x ) ))
         (ap ( x app x) )).
Qed.


Lemma congr_lam {s0 : tm} {t0 : tm} (H0 : = ) : lam = lam .
Proof.
exact (eq_trans eq_refl (ap ( x lam x) )).
Qed.


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


Fixpoint ren_tm (xi_tm : ) (s : tm) {struct s} : tm :=
  match s with
  | var_tm var_tm (xi_tm )
  | tt tt
  | ff ff
  | bot bot
  | trny
      trny (ren_tm xi_tm ) (ren_tm xi_tm ) (ren_tm xi_tm )
  | app app (ren_tm xi_tm ) (ren_tm xi_tm )
  | lam lam (ren_tm (upRen_tm_tm xi_tm) )
  end.

Lemma up_tm_tm (sigma : tm) : tm.
Proof.
exact (scons (var_tm var_zero) (funcomp (ren_tm shift) )).
Defined.


Fixpoint subst_tm (sigma_tm : tm) (s : tm) {struct s} : tm :=
  match s with
  | var_tm sigma_tm
  | tt tt
  | ff ff
  | bot bot
  | trny
      trny (subst_tm sigma_tm ) (subst_tm sigma_tm )
        (subst_tm sigma_tm )
  | app app (subst_tm sigma_tm ) (subst_tm sigma_tm )
  | lam lam (subst_tm (up_tm_tm sigma_tm) )
  end.

Lemma upId_tm_tm (sigma : tm) (Eq : x, x = var_tm x) :
   x, up_tm_tm x = var_tm x.
Proof.
exact ( n
       match n with
       | S n' ap (ren_tm shift) (Eq n')
       | O eq_refl
       end).
Qed.


Fixpoint idSubst_tm (sigma_tm : tm)
(Eq_tm : x, sigma_tm x = var_tm x) (s : tm) {struct s} :
subst_tm sigma_tm s = s :=
  match s with
  | var_tm Eq_tm
  | tt congr_tt
  | ff congr_ff
  | bot congr_bot
  | trny
      congr_trny (idSubst_tm sigma_tm Eq_tm )
        (idSubst_tm sigma_tm Eq_tm ) (idSubst_tm sigma_tm Eq_tm )
  | app
      congr_app (idSubst_tm sigma_tm Eq_tm ) (idSubst_tm sigma_tm Eq_tm )
  | lam
      congr_lam (idSubst_tm (up_tm_tm sigma_tm) (upId_tm_tm _ Eq_tm) )
  end.

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


Fixpoint extRen_tm (xi_tm : ) (zeta_tm : )
(Eq_tm : x, xi_tm x = zeta_tm x) (s : tm) {struct s} :
ren_tm xi_tm s = ren_tm zeta_tm s :=
  match s with
  | var_tm ap (var_tm) (Eq_tm )
  | tt congr_tt
  | ff congr_ff
  | bot congr_bot
  | trny
      congr_trny (extRen_tm xi_tm zeta_tm Eq_tm )
        (extRen_tm xi_tm zeta_tm Eq_tm ) (extRen_tm xi_tm zeta_tm Eq_tm )
  | app
      congr_app (extRen_tm xi_tm zeta_tm Eq_tm )
        (extRen_tm xi_tm zeta_tm Eq_tm )
  | lam
      congr_lam
        (extRen_tm (upRen_tm_tm xi_tm) (upRen_tm_tm zeta_tm)
           (upExtRen_tm_tm _ _ Eq_tm) )
  end.

Lemma upExt_tm_tm (sigma : tm) (tau : tm)
  (Eq : x, x = x) :
   x, up_tm_tm x = up_tm_tm x.
Proof.
exact ( n
       match n with
       | S n' ap (ren_tm shift) (Eq n')
       | O eq_refl
       end).
Qed.


Fixpoint ext_tm (sigma_tm : tm) (tau_tm : tm)
(Eq_tm : x, sigma_tm x = tau_tm x) (s : tm) {struct s} :
subst_tm sigma_tm s = subst_tm tau_tm s :=
  match s with
  | var_tm Eq_tm
  | tt congr_tt
  | ff congr_ff
  | bot congr_bot
  | trny
      congr_trny (ext_tm sigma_tm tau_tm Eq_tm )
        (ext_tm sigma_tm tau_tm Eq_tm ) (ext_tm sigma_tm tau_tm Eq_tm )
  | app
      congr_app (ext_tm sigma_tm tau_tm Eq_tm )
        (ext_tm sigma_tm tau_tm Eq_tm )
  | lam
      congr_lam
        (ext_tm (up_tm_tm sigma_tm) (up_tm_tm tau_tm) (upExt_tm_tm _ _ Eq_tm)
           )
  end.

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


Fixpoint compRenRen_tm (xi_tm : ) (zeta_tm : )
(rho_tm : ) (Eq_tm : x, funcomp zeta_tm xi_tm x = rho_tm x)
(s : tm) {struct s} : ren_tm zeta_tm (ren_tm xi_tm s) = ren_tm rho_tm s :=
  match s with
  | var_tm ap (var_tm) (Eq_tm )
  | tt congr_tt
  | ff congr_ff
  | bot congr_bot
  | trny
      congr_trny (compRenRen_tm xi_tm zeta_tm rho_tm Eq_tm )
        (compRenRen_tm xi_tm zeta_tm rho_tm Eq_tm )
        (compRenRen_tm xi_tm zeta_tm rho_tm Eq_tm )
  | app
      congr_app (compRenRen_tm xi_tm zeta_tm rho_tm Eq_tm )
        (compRenRen_tm xi_tm zeta_tm rho_tm Eq_tm )
  | lam
      congr_lam
        (compRenRen_tm (upRen_tm_tm xi_tm) (upRen_tm_tm zeta_tm)
           (upRen_tm_tm rho_tm) (up_ren_ren _ _ _ Eq_tm) )
  end.

Lemma up_ren_subst_tm_tm (xi : ) (tau : tm)
  (theta : tm) (Eq : x, funcomp x = x) :
   x, funcomp (up_tm_tm ) (upRen_tm_tm ) x = up_tm_tm x.
Proof.
exact ( n
       match n with
       | S n' ap (ren_tm shift) (Eq n')
       | O eq_refl
       end).
Qed.


Fixpoint compRenSubst_tm (xi_tm : ) (tau_tm : tm)
(theta_tm : tm)
(Eq_tm : x, funcomp tau_tm xi_tm x = theta_tm x) (s : tm) {struct s} :
subst_tm tau_tm (ren_tm xi_tm s) = subst_tm theta_tm s :=
  match s with
  | var_tm Eq_tm
  | tt congr_tt
  | ff congr_ff
  | bot congr_bot
  | trny
      congr_trny (compRenSubst_tm xi_tm tau_tm theta_tm Eq_tm )
        (compRenSubst_tm xi_tm tau_tm theta_tm Eq_tm )
        (compRenSubst_tm xi_tm tau_tm theta_tm Eq_tm )
  | app
      congr_app (compRenSubst_tm xi_tm tau_tm theta_tm Eq_tm )
        (compRenSubst_tm xi_tm tau_tm theta_tm Eq_tm )
  | lam
      congr_lam
        (compRenSubst_tm (upRen_tm_tm xi_tm) (up_tm_tm tau_tm)
           (up_tm_tm theta_tm) (up_ren_subst_tm_tm _ _ _ Eq_tm) )
  end.

Lemma up_subst_ren_tm_tm (sigma : tm) (zeta_tm : )
  (theta : tm)
  (Eq : x, funcomp (ren_tm zeta_tm) x = x) :
   x,
  funcomp (ren_tm (upRen_tm_tm zeta_tm)) (up_tm_tm ) x =
  up_tm_tm x.
Proof.
exact ( n
       match n with
       | S n'
           eq_trans
             (compRenRen_tm shift (upRen_tm_tm zeta_tm)
                (funcomp shift zeta_tm) ( x eq_refl) ( n'))
             (eq_trans
                (eq_sym
                   (compRenRen_tm zeta_tm shift (funcomp shift zeta_tm)
                      ( x eq_refl) ( n')))
                (ap (ren_tm shift) (Eq n')))
       | O eq_refl
       end).
Qed.


Fixpoint compSubstRen_tm (sigma_tm : tm) (zeta_tm : )
(theta_tm : tm)
(Eq_tm : x, funcomp (ren_tm zeta_tm) sigma_tm x = theta_tm x)
(s : tm) {struct s} :
ren_tm zeta_tm (subst_tm sigma_tm s) = subst_tm theta_tm s :=
  match s with
  | var_tm Eq_tm
  | tt congr_tt
  | ff congr_ff
  | bot congr_bot
  | trny
      congr_trny (compSubstRen_tm sigma_tm zeta_tm theta_tm Eq_tm )
        (compSubstRen_tm sigma_tm zeta_tm theta_tm Eq_tm )
        (compSubstRen_tm sigma_tm zeta_tm theta_tm Eq_tm )
  | app
      congr_app (compSubstRen_tm sigma_tm zeta_tm theta_tm Eq_tm )
        (compSubstRen_tm sigma_tm zeta_tm theta_tm Eq_tm )
  | lam
      congr_lam
        (compSubstRen_tm (up_tm_tm sigma_tm) (upRen_tm_tm zeta_tm)
           (up_tm_tm theta_tm) (up_subst_ren_tm_tm _ _ _ Eq_tm) )
  end.

Lemma up_subst_subst_tm_tm (sigma : tm) (tau_tm : tm)
  (theta : tm)
  (Eq : x, funcomp (subst_tm tau_tm) x = x) :
   x,
  funcomp (subst_tm (up_tm_tm tau_tm)) (up_tm_tm ) x = up_tm_tm x.
Proof.
exact ( n
       match n with
       | S n'
           eq_trans
             (compRenSubst_tm shift (up_tm_tm tau_tm)
                (funcomp (up_tm_tm tau_tm) shift) ( x eq_refl)
                ( n'))
             (eq_trans
                (eq_sym
                   (compSubstRen_tm tau_tm shift
                      (funcomp (ren_tm shift) tau_tm) ( x eq_refl)
                      ( n'))) (ap (ren_tm shift) (Eq n')))
       | O eq_refl
       end).
Qed.


Fixpoint compSubstSubst_tm (sigma_tm : tm) (tau_tm : tm)
(theta_tm : tm)
(Eq_tm : x, funcomp (subst_tm tau_tm) sigma_tm x = theta_tm x)
(s : tm) {struct s} :
subst_tm tau_tm (subst_tm sigma_tm s) = subst_tm theta_tm s :=
  match s with
  | var_tm Eq_tm
  | tt congr_tt
  | ff congr_ff
  | bot congr_bot
  | trny
      congr_trny (compSubstSubst_tm sigma_tm tau_tm theta_tm Eq_tm )
        (compSubstSubst_tm sigma_tm tau_tm theta_tm Eq_tm )
        (compSubstSubst_tm sigma_tm tau_tm theta_tm Eq_tm )
  | app
      congr_app (compSubstSubst_tm sigma_tm tau_tm theta_tm Eq_tm )
        (compSubstSubst_tm sigma_tm tau_tm theta_tm Eq_tm )
  | lam
      congr_lam
        (compSubstSubst_tm (up_tm_tm sigma_tm) (up_tm_tm tau_tm)
           (up_tm_tm theta_tm) (up_subst_subst_tm_tm _ _ _ Eq_tm) )
  end.

Lemma renRen_tm (xi_tm : ) (zeta_tm : ) (s : tm) :
  ren_tm zeta_tm (ren_tm xi_tm s) = ren_tm (funcomp zeta_tm xi_tm) s.
Proof.
exact (compRenRen_tm xi_tm zeta_tm _ ( n eq_refl) s).
Qed.


Lemma renRen'_tm_pointwise (xi_tm : ) (zeta_tm : ) :
  pointwise_relation _ eq (funcomp (ren_tm zeta_tm) (ren_tm xi_tm))
    (ren_tm (funcomp zeta_tm xi_tm)).
Proof.
exact ( s compRenRen_tm xi_tm zeta_tm _ ( n eq_refl) s).
Qed.


Lemma renSubst_tm (xi_tm : ) (tau_tm : tm) (s : tm) :
  subst_tm tau_tm (ren_tm xi_tm s) = subst_tm (funcomp tau_tm xi_tm) s.
Proof.
exact (compRenSubst_tm xi_tm tau_tm _ ( n eq_refl) s).
Qed.


Lemma renSubst_tm_pointwise (xi_tm : ) (tau_tm : tm) :
  pointwise_relation _ eq (funcomp (subst_tm tau_tm) (ren_tm xi_tm))
    (subst_tm (funcomp tau_tm xi_tm)).
Proof.
exact ( s compRenSubst_tm xi_tm tau_tm _ ( n eq_refl) s).
Qed.


Lemma substRen_tm (sigma_tm : tm) (zeta_tm : ) (s : tm) :
  ren_tm zeta_tm (subst_tm sigma_tm s) =
  subst_tm (funcomp (ren_tm zeta_tm) sigma_tm) s.
Proof.
exact (compSubstRen_tm sigma_tm zeta_tm _ ( n eq_refl) s).
Qed.


Lemma substRen_tm_pointwise (sigma_tm : tm) (zeta_tm : ) :
  pointwise_relation _ eq (funcomp (ren_tm zeta_tm) (subst_tm sigma_tm))
    (subst_tm (funcomp (ren_tm zeta_tm) sigma_tm)).
Proof.
exact ( s compSubstRen_tm sigma_tm zeta_tm _ ( n eq_refl) s).
Qed.


Lemma substSubst_tm (sigma_tm : tm) (tau_tm : tm) (s : tm) :
  subst_tm tau_tm (subst_tm sigma_tm s) =
  subst_tm (funcomp (subst_tm tau_tm) sigma_tm) s.
Proof.
exact (compSubstSubst_tm sigma_tm tau_tm _ ( n eq_refl) s).
Qed.


Lemma substSubst_tm_pointwise (sigma_tm : tm) (tau_tm : tm) :
  pointwise_relation _ eq (funcomp (subst_tm tau_tm) (subst_tm sigma_tm))
    (subst_tm (funcomp (subst_tm tau_tm) sigma_tm)).
Proof.
exact ( s compSubstSubst_tm sigma_tm tau_tm _ ( n eq_refl) s).
Qed.


Lemma rinstInst_up_tm_tm (xi : ) (sigma : tm)
  (Eq : x, funcomp (var_tm) x = x) :
   x, funcomp (var_tm) (upRen_tm_tm ) x = up_tm_tm x.
Proof.
exact ( n
       match n with
       | S n' ap (ren_tm shift) (Eq n')
       | O eq_refl
       end).
Qed.


Fixpoint rinst_inst_tm (xi_tm : ) (sigma_tm : tm)
(Eq_tm : x, funcomp (var_tm) xi_tm x = sigma_tm x) (s : tm) {struct s}
   : ren_tm xi_tm s = subst_tm sigma_tm s :=
  match s with
  | var_tm Eq_tm
  | tt congr_tt
  | ff congr_ff
  | bot congr_bot
  | trny
      congr_trny (rinst_inst_tm xi_tm sigma_tm Eq_tm )
        (rinst_inst_tm xi_tm sigma_tm Eq_tm )
        (rinst_inst_tm xi_tm sigma_tm Eq_tm )
  | app
      congr_app (rinst_inst_tm xi_tm sigma_tm Eq_tm )
        (rinst_inst_tm xi_tm sigma_tm Eq_tm )
  | lam
      congr_lam
        (rinst_inst_tm (upRen_tm_tm xi_tm) (up_tm_tm sigma_tm)
           (rinstInst_up_tm_tm _ _ Eq_tm) )
  end.

Lemma rinstInst'_tm (xi_tm : ) (s : tm) :
  ren_tm xi_tm s = subst_tm (funcomp (var_tm) xi_tm) s.
Proof.
exact (rinst_inst_tm xi_tm _ ( n eq_refl) s).
Qed.


Lemma rinstInst'_tm_pointwise (xi_tm : ) :
  pointwise_relation _ eq (ren_tm xi_tm) (subst_tm (funcomp (var_tm) xi_tm)).
Proof.
exact ( s rinst_inst_tm xi_tm _ ( n eq_refl) s).
Qed.


Lemma instId'_tm (s : tm) : subst_tm (var_tm) s = s.
Proof.
exact (idSubst_tm (var_tm) ( n eq_refl) s).
Qed.


Lemma instId'_tm_pointwise : pointwise_relation _ eq (subst_tm (var_tm)) id.
Proof.
exact ( s idSubst_tm (var_tm) ( n eq_refl) s).
Qed.


Lemma rinstId'_tm (s : tm) : ren_tm id s = s.
Proof.
exact (eq_ind_r ( t t = s) (instId'_tm s) (rinstInst'_tm id s)).
Qed.


Lemma rinstId'_tm_pointwise : pointwise_relation _ eq (@ren_tm id) id.
Proof.
exact ( s eq_ind_r ( t t = s) (instId'_tm s) (rinstInst'_tm id s)).
Qed.


Lemma varL'_tm (sigma_tm : tm) (x : ) :
  subst_tm sigma_tm (var_tm x) = sigma_tm x.
Proof.
exact (eq_refl).
Qed.


Lemma varL'_tm_pointwise (sigma_tm : tm) :
  pointwise_relation _ eq (funcomp (subst_tm sigma_tm) (var_tm)) sigma_tm.
Proof.
exact ( x eq_refl).
Qed.


Lemma varLRen'_tm (xi_tm : ) (x : ) :
  ren_tm xi_tm (var_tm x) = var_tm (xi_tm x).
Proof.
exact (eq_refl).
Qed.


Lemma varLRen'_tm_pointwise (xi_tm : ) :
  pointwise_relation _ eq (funcomp (ren_tm xi_tm) (var_tm))
    (funcomp (var_tm) xi_tm).
Proof.
exact ( x eq_refl).
Qed.


Inductive ty : Type :=
  | Base : ty
  | Fun : ty ty ty.

Lemma congr_Base : Base = Base.
Proof.
exact (eq_refl).
Qed.


Lemma congr_Fun {s0 : ty} {s1 : ty} {t0 : ty} {t1 : ty} (H0 : = )
  (H1 : = ) : Fun = Fun .
Proof.
exact (eq_trans (eq_trans eq_refl (ap ( x Fun x ) ))
         (ap ( x Fun x) )).
Qed.


Class Up_tm X Y :=
    up_tm : X Y.

#[global]Instance Subst_tm : (Subst1 _ _ _) := @subst_tm.

#[global]Instance Up_tm_tm : (Up_tm _ _) := @up_tm_tm.

#[global]Instance Ren_tm : (Ren1 _ _ _) := @ren_tm.

#[global]
Instance VarInstance_tm : (Var _ _) := @var_tm.

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

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

Notation "↑__tm" := up_tm (only printing) : subst_scope.

Notation "↑__tm" := up_tm_tm (only printing) : subst_scope.

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

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

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

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

Notation "x '__tm'" := (var_tm x) ( at level 5, format "x __tm") :
  subst_scope.

#[global]
Instance subst_tm_morphism :
 (Proper (respectful (pointwise_relation _ eq) (respectful eq eq))
    (@subst_tm)).
Proof.
exact ( f_tm g_tm Eq_tm s t Eq_st
       eq_ind s ( t' subst_tm f_tm s = subst_tm g_tm t')
         (ext_tm f_tm g_tm Eq_tm s) t Eq_st).
Qed.


#[global]
Instance subst_tm_morphism2 :
 (Proper (respectful (pointwise_relation _ eq) (pointwise_relation _ eq))
    (@subst_tm)).
Proof.
exact ( f_tm g_tm Eq_tm s ext_tm f_tm g_tm Eq_tm s).
Qed.


#[global]
Instance ren_tm_morphism :
 (Proper (respectful (pointwise_relation _ eq) (respectful eq eq)) (@ren_tm)).
Proof.
exact ( f_tm g_tm Eq_tm s t Eq_st
       eq_ind s ( t' ren_tm f_tm s = ren_tm g_tm t')
         (extRen_tm f_tm g_tm Eq_tm s) t Eq_st).
Qed.


#[global]
Instance ren_tm_morphism2 :
 (Proper (respectful (pointwise_relation _ eq) (pointwise_relation _ eq))
    (@ren_tm)).
Proof.
exact ( f_tm g_tm Eq_tm s extRen_tm f_tm g_tm Eq_tm s).
Qed.


Ltac auto_unfold := repeat
                     unfold VarInstance_tm, Var, ids, Ren_tm, Ren1, ,
                      Up_tm_tm, Up_tm, up_tm, Subst_tm, Subst1, .

Tactic Notation "auto_unfold" "in" "*" := repeat
                                           unfold VarInstance_tm, Var, ids,
                                            Ren_tm, Ren1, , Up_tm_tm,
                                            Up_tm, up_tm, Subst_tm, Subst1,
                                             in *.

Ltac asimpl' := repeat (first
                 [ progress setoid_rewrite substSubst_tm_pointwise
                 | progress setoid_rewrite substSubst_tm
                 | progress setoid_rewrite substRen_tm_pointwise
                 | progress setoid_rewrite substRen_tm
                 | progress setoid_rewrite renSubst_tm_pointwise
                 | progress setoid_rewrite renSubst_tm
                 | progress setoid_rewrite renRen'_tm_pointwise
                 | progress setoid_rewrite renRen_tm
                 | progress setoid_rewrite varLRen'_tm_pointwise
                 | progress setoid_rewrite varLRen'_tm
                 | progress setoid_rewrite varL'_tm_pointwise
                 | progress setoid_rewrite varL'_tm
                 | progress setoid_rewrite rinstId'_tm_pointwise
                 | progress setoid_rewrite rinstId'_tm
                 | progress setoid_rewrite instId'_tm_pointwise
                 | progress setoid_rewrite instId'_tm
                 | progress unfold up_tm_tm, upRen_tm_tm, up_ren
                 | progress cbn[subst_tm ren_tm]
                 | progress fsimpl ]).

Ltac asimpl := check_no_evars;
                repeat
                 unfold VarInstance_tm, Var, ids, Ren_tm, Ren1, ,
                  Up_tm_tm, Up_tm, up_tm, Subst_tm, 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'_tm_pointwise;
                  try setoid_rewrite rinstInst'_tm.

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

End Core.

Module Fext.

Import
Core.

Lemma renRen'_tm (xi_tm : ) (zeta_tm : ) :
  funcomp (ren_tm zeta_tm) (ren_tm xi_tm) = ren_tm (funcomp zeta_tm xi_tm).
Proof.
exact (FunctionalExtensionality.functional_extensionality _ _
         ( n renRen_tm xi_tm zeta_tm n)).
Qed.


Lemma renSubst'_tm (xi_tm : ) (tau_tm : tm) :
  funcomp (subst_tm tau_tm) (ren_tm xi_tm) = subst_tm (funcomp tau_tm xi_tm).
Proof.
exact (FunctionalExtensionality.functional_extensionality _ _
         ( n renSubst_tm xi_tm tau_tm n)).
Qed.


Lemma substRen'_tm (sigma_tm : tm) (zeta_tm : ) :
  funcomp (ren_tm zeta_tm) (subst_tm sigma_tm) =
  subst_tm (funcomp (ren_tm zeta_tm) sigma_tm).
Proof.
exact (FunctionalExtensionality.functional_extensionality _ _
         ( n substRen_tm sigma_tm zeta_tm n)).
Qed.


Lemma substSubst'_tm (sigma_tm : tm) (tau_tm : tm) :
  funcomp (subst_tm tau_tm) (subst_tm sigma_tm) =
  subst_tm (funcomp (subst_tm tau_tm) sigma_tm).
Proof.
exact (FunctionalExtensionality.functional_extensionality _ _
         ( n substSubst_tm sigma_tm tau_tm n)).
Qed.


Lemma rinstInst_tm (xi_tm : ) :
  ren_tm xi_tm = subst_tm (funcomp (var_tm) xi_tm).
Proof.
exact (FunctionalExtensionality.functional_extensionality _ _
         ( x rinst_inst_tm xi_tm _ ( n eq_refl) x)).
Qed.


Lemma instId_tm : subst_tm (var_tm) = id.
Proof.
exact (FunctionalExtensionality.functional_extensionality _ _
         ( x idSubst_tm (var_tm) ( n eq_refl) (id x))).
Qed.


Lemma rinstId_tm : @ren_tm id = id.
Proof.
exact (eq_trans (rinstInst_tm (id _)) instId_tm).
Qed.


Lemma varL_tm (sigma_tm : tm) :
  funcomp (subst_tm sigma_tm) (var_tm) = sigma_tm.
Proof.
exact (FunctionalExtensionality.functional_extensionality _ _
         ( x eq_refl)).
Qed.


Lemma varLRen_tm (xi_tm : ) :
  funcomp (ren_tm xi_tm) (var_tm) = funcomp (var_tm) xi_tm.
Proof.
exact (FunctionalExtensionality.functional_extensionality _ _
         ( x eq_refl)).
Qed.


Ltac asimpl_fext' := repeat (first
                      [ progress rewrite ?substSubst_tm_pointwise
                      | progress rewrite ?substSubst_tm
                      | progress rewrite ?substRen_tm_pointwise
                      | progress rewrite ?substRen_tm
                      | progress rewrite ?renSubst_tm_pointwise
                      | progress rewrite ?renSubst_tm
                      | progress rewrite ?renRen'_tm_pointwise
                      | progress rewrite ?renRen_tm
                      | progress rewrite ?varLRen_tm
                      | progress rewrite ?varL_tm
                      | progress rewrite ?rinstId_tm
                      | progress rewrite ?instId_tm
                      | progress rewrite ?substSubst'_tm
                      | progress rewrite ?substRen'_tm
                      | progress rewrite ?renSubst'_tm
                      | progress rewrite ?renRen'_tm
                      | progress unfold up_tm_tm, upRen_tm_tm, up_ren
                      | progress cbn[subst_tm ren_tm]
                      | fsimpl_fext ]).

Ltac asimpl_fext := check_no_evars; repeat try unfold_funcomp;
                     repeat
                      unfold VarInstance_tm, Var, ids, Ren_tm, Ren1, ,
                       Up_tm_tm, Up_tm, up_tm, Subst_tm, Subst1,
                       in *; asimpl_fext'; repeat try unfold_funcomp.

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

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

Ltac substify_fext := auto_unfold; try repeat erewrite ?rinstInst_tm.

Ltac renamify_fext := auto_unfold; try repeat erewrite ?rinstInst_tm.

End Fext.

Module Allfv.

Import
Core.

Lemma upAllfv_tm_tm (p : Prop) : Prop.
Proof.
exact (up_allfv p).
Defined.


Fixpoint allfv_tm (p_tm : Prop) (s : tm) {struct s} : Prop :=
  match s with
  | var_tm p_tm
  | tt True
  | ff True
  | bot True
  | trny
      and (allfv_tm p_tm )
        (and (allfv_tm p_tm ) (and (allfv_tm p_tm ) True))
  | app and (allfv_tm p_tm ) (and (allfv_tm p_tm ) True)
  | lam and (allfv_tm (upAllfv_tm_tm p_tm) ) True
  end.

Lemma upAllfvTriv_tm_tm {p : Prop} (H : x, p x) :
   x, upAllfv_tm_tm p x.
Proof.
exact ( x match x with
                | S n' H n'
                | O I
                end).
Qed.


Fixpoint allfvTriv_tm (p_tm : Prop) (H_tm : x, p_tm x)
(s : tm) {struct s} : allfv_tm p_tm s :=
  match s with
  | var_tm H_tm
  | tt I
  | ff I
  | bot I
  | trny
      conj (allfvTriv_tm p_tm H_tm )
        (conj (allfvTriv_tm p_tm H_tm )
           (conj (allfvTriv_tm p_tm H_tm ) I))
  | app
      conj (allfvTriv_tm p_tm H_tm ) (conj (allfvTriv_tm p_tm H_tm ) I)
  | lam
      conj (allfvTriv_tm (upAllfv_tm_tm p_tm) (upAllfvTriv_tm_tm H_tm) ) I
  end.

Lemma upAllfvImpl_tm_tm {p : Prop} {q : Prop}
  (H : x, p x q x) :
   x, upAllfv_tm_tm p x upAllfv_tm_tm q x.
Proof.
exact ( x match x with
                | S n' H n'
                | O Hp Hp
                end).
Qed.


Fixpoint allfvImpl_tm (p_tm : Prop) (q_tm : Prop)
(H_tm : x, p_tm x q_tm x) (s : tm) {struct s} :
allfv_tm p_tm s allfv_tm q_tm s :=
  match s with
  | var_tm HP H_tm HP
  | tt HP I
  | ff HP I
  | bot HP I
  | trny
       HP
      conj
        (allfvImpl_tm p_tm q_tm H_tm match HP with
                                        | conj HP _ HP
                                        end)
        (conj
           (allfvImpl_tm p_tm q_tm H_tm
              match HP with
              | conj _ HP match HP with
                             | conj HP _ HP
                             end
              end)
           (conj
              (allfvImpl_tm p_tm q_tm H_tm
                 match HP with
                 | conj _ HP
                     match HP with
                     | conj _ HP match HP with
                                    | conj HP _ HP
                                    end
                     end
                 end) I))
  | app
       HP
      conj
        (allfvImpl_tm p_tm q_tm H_tm match HP with
                                        | conj HP _ HP
                                        end)
        (conj
           (allfvImpl_tm p_tm q_tm H_tm
              match HP with
              | conj _ HP match HP with
                             | conj HP _ HP
                             end
              end) I)
  | lam
       HP
      conj
        (allfvImpl_tm (upAllfv_tm_tm p_tm) (upAllfv_tm_tm q_tm)
           (upAllfvImpl_tm_tm H_tm) match HP with
                                       | conj HP _ HP
                                       end) I
  end.

Lemma upAllfvRenL_tm_tm (p : Prop) (xi : ) :
   x,
  upAllfv_tm_tm p (upRen_tm_tm x) upAllfv_tm_tm (funcomp p ) x.
Proof.
exact ( x match x with
                | S n' i i
                | O H H
                end).
Qed.


Fixpoint allfvRenL_tm (p_tm : Prop) (xi_tm : ) (s : tm)
{struct s} :
allfv_tm p_tm (ren_tm xi_tm s) allfv_tm (funcomp p_tm xi_tm) s :=
  match s with
  | var_tm H H
  | tt H I
  | ff H I
  | bot H I
  | trny
       H
      conj (allfvRenL_tm p_tm xi_tm match H with
                                       | conj H _ H
                                       end)
        (conj
           (allfvRenL_tm p_tm xi_tm
              match H with
              | conj _ H match H with
                            | conj H _ H
                            end
              end)
           (conj
              (allfvRenL_tm p_tm xi_tm
                 match H with
                 | conj _ H
                     match H with
                     | conj _ H match H with
                                   | conj H _ H
                                   end
                     end
                 end) I))
  | app
       H
      conj (allfvRenL_tm p_tm xi_tm match H with
                                       | conj H _ H
                                       end)
        (conj
           (allfvRenL_tm p_tm xi_tm
              match H with
              | conj _ H match H with
                            | conj H _ H
                            end
              end) I)
  | lam
       H
      conj
        (allfvImpl_tm _ _ (upAllfvRenL_tm_tm p_tm xi_tm)
           (allfvRenL_tm (upAllfv_tm_tm p_tm) (upRen_tm_tm xi_tm)
              match H with
              | conj H _ H
              end)) I
  end.

Lemma upAllfvRenR_tm_tm (p : Prop) (xi : ) :
   x,
  upAllfv_tm_tm (funcomp p ) x upAllfv_tm_tm p (upRen_tm_tm x).
Proof.
exact ( x match x with
                | S n' i i
                | O H H
                end).
Qed.


Fixpoint allfvRenR_tm (p_tm : Prop) (xi_tm : ) (s : tm)
{struct s} :
allfv_tm (funcomp p_tm xi_tm) s allfv_tm p_tm (ren_tm xi_tm s) :=
  match s with
  | var_tm H H
  | tt H I
  | ff H I
  | bot H I
  | trny
       H
      conj (allfvRenR_tm p_tm xi_tm match H with
                                       | conj H _ H
                                       end)
        (conj
           (allfvRenR_tm p_tm xi_tm
              match H with
              | conj _ H match H with
                            | conj H _ H
                            end
              end)
           (conj
              (allfvRenR_tm p_tm xi_tm
                 match H with
                 | conj _ H
                     match H with
                     | conj _ H match H with
                                   | conj H _ H
                                   end
                     end
                 end) I))
  | app
       H
      conj (allfvRenR_tm p_tm xi_tm match H with
                                       | conj H _ H
                                       end)
        (conj
           (allfvRenR_tm p_tm xi_tm
              match H with
              | conj _ H match H with
                            | conj H _ H
                            end
              end) I)
  | lam
       H
      conj
        (allfvRenR_tm (upAllfv_tm_tm p_tm) (upRen_tm_tm xi_tm)
           (allfvImpl_tm _ _ (upAllfvRenR_tm_tm p_tm xi_tm)
              match H with
              | conj H _ H
              end)) I
  end.

End Allfv.

Module Extra.

Import Core.

#[global]Hint Opaque subst_tm: rewrite.

#[global]Hint Opaque ren_tm: rewrite.

End Extra.

Module interface.

Export Core.

Export Fext.

Export Allfv.

Export Extra.

End interface.

Export interface.