Definition R_rst : red_rule :=
    fun e : env => clos_refl_sym_trans term (R e).Definition reunion : red_rule := fun e => union _ (R e) (R' e).(* passage au contexte *)

  Inductive ctxt : env -> term -> term -> Prop :=
    | ctx_rule : forall (e : env) (x y : term), R e x y -> ctxt e x y
    | ctx_abs_l :
        forall (e : env) (M M' : term),
        ctxt e M M' -> forall N : term, ctxt e (Abs M N) (Abs M' N)
    | ctx_abs_r :
        forall (e : env) (M M' N : term),
        ctxt (Ax N :: e) M M' -> ctxt e (Abs N M) (Abs N M')
    | ctx_app_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (App M1 M2) (App N1 M2)
    | ctx_app_r :
        forall (e : env) (M2 N2 : term),
        ctxt e M2 N2 -> forall M1 : term, ctxt e (App M1 M2) (App M1 N2)
    | ctx_prod_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (Prod M1 M2) (Prod N1 M2)
    | ctx_prod_r :
        forall (e : env) (M2 N2 M1 : term),
        ctxt (Ax M1 :: e) M2 N2 -> ctxt e (Prod M1 M2) (Prod M1 N2).(* passage au contexte *)

  Inductive ctxt : env -> term -> term -> Prop :=
    | ctx_rule : forall (e : env) (x y : term), R e x y -> ctxt e x y
    | ctx_abs_l :
        forall (e : env) (M M' : term),
        ctxt e M M' -> forall N : term, ctxt e (Abs M N) (Abs M' N)
    | ctx_abs_r :
        forall (e : env) (M M' N : term),
        ctxt (Ax N :: e) M M' -> ctxt e (Abs N M) (Abs N M')
    | ctx_app_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (App M1 M2) (App N1 M2)
    | ctx_app_r :
        forall (e : env) (M2 N2 : term),
        ctxt e M2 N2 -> forall M1 : term, ctxt e (App M1 M2) (App M1 N2)
    | ctx_prod_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (Prod M1 M2) (Prod N1 M2)
    | ctx_prod_r :
        forall (e : env) (M2 N2 M1 : term),
        ctxt (Ax M1 :: e) M2 N2 -> ctxt e (Prod M1 M2) (Prod M1 N2).(* passage au contexte *)

  Inductive ctxt : env -> term -> term -> Prop :=
    | ctx_rule : forall (e : env) (x y : term), R e x y -> ctxt e x y
    | ctx_abs_l :
        forall (e : env) (M M' : term),
        ctxt e M M' -> forall N : term, ctxt e (Abs M N) (Abs M' N)
    | ctx_abs_r :
        forall (e : env) (M M' N : term),
        ctxt (Ax N :: e) M M' -> ctxt e (Abs N M) (Abs N M')
    | ctx_app_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (App M1 M2) (App N1 M2)
    | ctx_app_r :
        forall (e : env) (M2 N2 : term),
        ctxt e M2 N2 -> forall M1 : term, ctxt e (App M1 M2) (App M1 N2)
    | ctx_prod_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (Prod M1 M2) (Prod N1 M2)
    | ctx_prod_r :
        forall (e : env) (M2 N2 M1 : term),
        ctxt (Ax M1 :: e) M2 N2 -> ctxt e (Prod M1 M2) (Prod M1 N2).(* passage au contexte *)

  Inductive ctxt : env -> term -> term -> Prop :=
    | ctx_rule : forall (e : env) (x y : term), R e x y -> ctxt e x y
    | ctx_abs_l :
        forall (e : env) (M M' : term),
        ctxt e M M' -> forall N : term, ctxt e (Abs M N) (Abs M' N)
    | ctx_abs_r :
        forall (e : env) (M M' N : term),
        ctxt (Ax N :: e) M M' -> ctxt e (Abs N M) (Abs N M')
    | ctx_app_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (App M1 M2) (App N1 M2)
    | ctx_app_r :
        forall (e : env) (M2 N2 : term),
        ctxt e M2 N2 -> forall M1 : term, ctxt e (App M1 M2) (App M1 N2)
    | ctx_prod_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (Prod M1 M2) (Prod N1 M2)
    | ctx_prod_r :
        forall (e : env) (M2 N2 M1 : term),
        ctxt (Ax M1 :: e) M2 N2 -> ctxt e (Prod M1 M2) (Prod M1 N2).(* passage au contexte *)

  Inductive ctxt : env -> term -> term -> Prop :=
    | ctx_rule : forall (e : env) (x y : term), R e x y -> ctxt e x y
    | ctx_abs_l :
        forall (e : env) (M M' : term),
        ctxt e M M' -> forall N : term, ctxt e (Abs M N) (Abs M' N)
    | ctx_abs_r :
        forall (e : env) (M M' N : term),
        ctxt (Ax N :: e) M M' -> ctxt e (Abs N M) (Abs N M')
    | ctx_app_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (App M1 M2) (App N1 M2)
    | ctx_app_r :
        forall (e : env) (M2 N2 : term),
        ctxt e M2 N2 -> forall M1 : term, ctxt e (App M1 M2) (App M1 N2)
    | ctx_prod_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (Prod M1 M2) (Prod N1 M2)
    | ctx_prod_r :
        forall (e : env) (M2 N2 M1 : term),
        ctxt (Ax M1 :: e) M2 N2 -> ctxt e (Prod M1 M2) (Prod M1 N2).(* passage au contexte *)

  Inductive ctxt : env -> term -> term -> Prop :=
    | ctx_rule : forall (e : env) (x y : term), R e x y -> ctxt e x y
    | ctx_abs_l :
        forall (e : env) (M M' : term),
        ctxt e M M' -> forall N : term, ctxt e (Abs M N) (Abs M' N)
    | ctx_abs_r :
        forall (e : env) (M M' N : term),
        ctxt (Ax N :: e) M M' -> ctxt e (Abs N M) (Abs N M')
    | ctx_app_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (App M1 M2) (App N1 M2)
    | ctx_app_r :
        forall (e : env) (M2 N2 : term),
        ctxt e M2 N2 -> forall M1 : term, ctxt e (App M1 M2) (App M1 N2)
    | ctx_prod_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (Prod M1 M2) (Prod N1 M2)
    | ctx_prod_r :
        forall (e : env) (M2 N2 M1 : term),
        ctxt (Ax M1 :: e) M2 N2 -> ctxt e (Prod M1 M2) (Prod M1 N2).(* passage au contexte *)

  Inductive ctxt : env -> term -> term -> Prop :=
    | ctx_rule : forall (e : env) (x y : term), R e x y -> ctxt e x y
    | ctx_abs_l :
        forall (e : env) (M M' : term),
        ctxt e M M' -> forall N : term, ctxt e (Abs M N) (Abs M' N)
    | ctx_abs_r :
        forall (e : env) (M M' N : term),
        ctxt (Ax N :: e) M M' -> ctxt e (Abs N M) (Abs N M')
    | ctx_app_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (App M1 M2) (App N1 M2)
    | ctx_app_r :
        forall (e : env) (M2 N2 : term),
        ctxt e M2 N2 -> forall M1 : term, ctxt e (App M1 M2) (App M1 N2)
    | ctx_prod_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (Prod M1 M2) (Prod N1 M2)
    | ctx_prod_r :
        forall (e : env) (M2 N2 M1 : term),
        ctxt (Ax M1 :: e) M2 N2 -> ctxt e (Prod M1 M2) (Prod M1 N2).(* passage au contexte *)

  Inductive ctxt : env -> term -> term -> Prop :=
    | ctx_rule : forall (e : env) (x y : term), R e x y -> ctxt e x y
    | ctx_abs_l :
        forall (e : env) (M M' : term),
        ctxt e M M' -> forall N : term, ctxt e (Abs M N) (Abs M' N)
    | ctx_abs_r :
        forall (e : env) (M M' N : term),
        ctxt (Ax N :: e) M M' -> ctxt e (Abs N M) (Abs N M')
    | ctx_app_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (App M1 M2) (App N1 M2)
    | ctx_app_r :
        forall (e : env) (M2 N2 : term),
        ctxt e M2 N2 -> forall M1 : term, ctxt e (App M1 M2) (App M1 N2)
    | ctx_prod_l :
        forall (e : env) (M1 N1 : term),
        ctxt e M1 N1 -> forall M2 : term, ctxt e (Prod M1 M2) (Prod N1 M2)
    | ctx_prod_r :
        forall (e : env) (M2 N2 M1 : term),
        ctxt (Ax M1 :: e) M2 N2 -> ctxt e (Prod M1 M2) (Prod M1 N2).Definition red := R_rt (ctxt R).Definition conv := R_rst (ctxt R).

(* Specifications: *)
Lemma red_trans : forall (e : env) (x y z : term), red e x y -> red e y z -> red e x z.
Lemma conv_trans : forall (e : env) (x y z : term), conv e x y -> conv e y z -> conv e x z.
Lemma conv_sym : forall (e : env) (x y : term), conv e x y -> conv e y x.
Lemma red_conv : forall (e : env) (x y : term), red e x y -> conv e x y.
Lemma red_sym_conv : forall (e : env) (x y : term), red e x y -> conv e y x.
Lemma red_red_abs : forall (e : env) (A A' M M' : term), red e A A' -> red (Ax A' :: e) M M' -> red e (Abs A M) (Abs A' M').
Lemma red_red_app : forall (e : env) (u u' v v' : term), red e u u' -> red e v v' -> red e (App u v) (App u' v').
Lemma red_red_prod : forall (e : env) (A A' B B' : term), red e A A' -> red (Ax A' :: e) B B' -> red e (Prod A B) (Prod A' B').
Lemma conv_conv_abs : forall (e : env) (A A' M M' : term), conv e A A' -> conv (Ax A' :: e) M M' -> conv e (Abs A M) (Abs A' M').
Lemma conv_conv_app : forall (e : env) (u u' v v' : term), conv e u u' -> conv e v v' -> conv e (App u v) (App u' v').
Lemma conv_conv_prod : forall (e : env) (A A' B B' : term), conv e A A' -> conv (Ax A' :: e) B B' -> conv e (Prod A B) (Prod A' B').
Lemma reunion_lift : R_lift (reunion R R').
Lemma ctxt_lift : R_lift (ctxt R).
Lemma R_rt_lift : R_lift (R_rt R).
Lemma R_rst_lift : R_lift (R_rst R).
Lemma reunion_subst : R_subst (reunion R R').
Lemma ctxt_subst : R_subst (ctxt R).
Lemma R_rt_subst : R_subst (R_rt R).
Lemma R_rst_subst : R_subst (R_rst R).
Lemma reunion_stable : R_stable_env (reunion R R').
Lemma ctxt_stable : R_stable_env (ctxt R).
Lemma R_rt_stable : R_stable_env (R_rt R).
Lemma R_rst_stable : R_stable_env (R_rst R).
Lemma red_lift : R_lift (red R).
Lemma conv_lift : R_lift (conv R).
Lemma red_subst : R_subst (red R).
Lemma conv_subst : R_subst (conv R).
Lemma red_subst_l : forall (g : env) (u v : term), ctxt R g u v -> forall (t : term) (n : nat) (e : env), trunc n e g -> red R e (subst_rec u t n) (subst_rec v t n).
Lemma red_red_subst : forall (e : env) (x y t u T : term), red R (Ax T :: e) t u -> red R e x y -> red R e (subst x t) (subst y u).