Inductive type_error : Set :=
    | Under : term -> type_error -> type_error
    | Expected_type : term -> term -> term -> type_error
    | Topsort : sort -> type_error
    | Db_error : nat -> type_error
    | Lambda_topsort : term -> sort -> type_error
    | Not_a_type : term -> term -> type_error
    | Not_a_fun : term -> term -> type_error
    | Apply_err : term -> term -> term -> term -> type_error.Inductive type_error : Set :=
    | Under : term -> type_error -> type_error
    | Expected_type : term -> term -> term -> type_error
    | Topsort : sort -> type_error
    | Db_error : nat -> type_error
    | Lambda_topsort : term -> sort -> type_error
    | Not_a_type : term -> term -> type_error
    | Not_a_fun : term -> term -> type_error
    | Apply_err : term -> term -> term -> term -> type_error.Inductive type_error : Set :=
    | Under : term -> type_error -> type_error
    | Expected_type : term -> term -> term -> type_error
    | Topsort : sort -> type_error
    | Db_error : nat -> type_error
    | Lambda_topsort : term -> sort -> type_error
    | Not_a_type : term -> term -> type_error
    | Not_a_fun : term -> term -> type_error
    | Apply_err : term -> term -> term -> term -> type_error.Inductive type_error : Set :=
    | Under : term -> type_error -> type_error
    | Expected_type : term -> term -> term -> type_error
    | Topsort : sort -> type_error
    | Db_error : nat -> type_error
    | Lambda_topsort : term -> sort -> type_error
    | Not_a_type : term -> term -> type_error
    | Not_a_fun : term -> term -> type_error
    | Apply_err : term -> term -> term -> term -> type_error.Inductive type_error : Set :=
    | Under : term -> type_error -> type_error
    | Expected_type : term -> term -> term -> type_error
    | Topsort : sort -> type_error
    | Db_error : nat -> type_error
    | Lambda_topsort : term -> sort -> type_error
    | Not_a_type : term -> term -> type_error
    | Not_a_fun : term -> term -> type_error
    | Apply_err : term -> term -> term -> term -> type_error.Inductive type_error : Set :=
    | Under : term -> type_error -> type_error
    | Expected_type : term -> term -> term -> type_error
    | Topsort : sort -> type_error
    | Db_error : nat -> type_error
    | Lambda_topsort : term -> sort -> type_error
    | Not_a_type : term -> term -> type_error
    | Not_a_fun : term -> term -> type_error
    | Apply_err : term -> term -> term -> term -> type_error.Inductive type_error : Set :=
    | Under : term -> type_error -> type_error
    | Expected_type : term -> term -> term -> type_error
    | Topsort : sort -> type_error
    | Db_error : nat -> type_error
    | Lambda_topsort : term -> sort -> type_error
    | Not_a_type : term -> term -> type_error
    | Not_a_fun : term -> term -> type_error
    | Apply_err : term -> term -> term -> term -> type_error.Inductive type_error : Set :=
    | Under : term -> type_error -> type_error
    | Expected_type : term -> term -> term -> type_error
    | Topsort : sort -> type_error
    | Db_error : nat -> type_error
    | Lambda_topsort : term -> sort -> type_error
    | Not_a_type : term -> term -> type_error
    | Not_a_fun : term -> term -> type_error
    | Apply_err : term -> term -> term -> term -> type_error.Inductive type_error : Set :=
    | Under : term -> type_error -> type_error
    | Expected_type : term -> term -> term -> type_error
    | Topsort : sort -> type_error
    | Db_error : nat -> type_error
    | Lambda_topsort : term -> sort -> type_error
    | Not_a_type : term -> term -> type_error
    | Not_a_fun : term -> term -> type_error
    | Apply_err : term -> term -> term -> term -> type_error.(* Meaning of errors *)
  Inductive expln : env -> type_error -> Prop :=
    | Exp_under :
        forall (e : env) (t : term) (err : type_error),
        expln (Ax t :: e) err -> expln e (Under t err)
    | Exp_exp_type :
        forall (e : env) (m at_ et : term),
        typ_ppal e m at_ ->
        ~ typ e m et ->
        free_db (length e) et -> expln e (Expected_type m at_ et)
    | Exp_topsort :
        forall (e : env) (s : sort),
        wf e -> (forall t : term, ~ typ e (Srt s) t) -> expln e (Topsort s)
    | Exp_db :
        forall (e : env) (n : nat),
        wf e -> length e <= n -> expln e (Db_error n)
    | Exp_lam_topsort :
        forall (e : env) (m t : term) (s : sort),
        typ_ppal (Ax t :: e) m (Srt s) ->
        (forall u : term, ~ typ e (Srt s) u) ->
        expln e (Lambda_topsort (Abs t m) s)
    | Exp_type :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall s : sort, ~ typ e m (Srt s)) -> expln e (Not_a_type m t)
    | Exp_fun :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall a b : term, ~ typ e m (Prod a b)) -> expln e (Not_a_fun m t)
    | Exp_appl_err :
        forall (e : env) (u v a b tv : term),
        typ e u (Prod a b) ->
        (forall c d : term,
         typ e u (Prod c d) -> le_type e (Prod a b) (Prod c d)) ->
        typ_ppal e v tv ->
        ~ typ e v a -> expln e (Apply_err u (Prod a b) v tv).(* Meaning of errors *)
  Inductive expln : env -> type_error -> Prop :=
    | Exp_under :
        forall (e : env) (t : term) (err : type_error),
        expln (Ax t :: e) err -> expln e (Under t err)
    | Exp_exp_type :
        forall (e : env) (m at_ et : term),
        typ_ppal e m at_ ->
        ~ typ e m et ->
        free_db (length e) et -> expln e (Expected_type m at_ et)
    | Exp_topsort :
        forall (e : env) (s : sort),
        wf e -> (forall t : term, ~ typ e (Srt s) t) -> expln e (Topsort s)
    | Exp_db :
        forall (e : env) (n : nat),
        wf e -> length e <= n -> expln e (Db_error n)
    | Exp_lam_topsort :
        forall (e : env) (m t : term) (s : sort),
        typ_ppal (Ax t :: e) m (Srt s) ->
        (forall u : term, ~ typ e (Srt s) u) ->
        expln e (Lambda_topsort (Abs t m) s)
    | Exp_type :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall s : sort, ~ typ e m (Srt s)) -> expln e (Not_a_type m t)
    | Exp_fun :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall a b : term, ~ typ e m (Prod a b)) -> expln e (Not_a_fun m t)
    | Exp_appl_err :
        forall (e : env) (u v a b tv : term),
        typ e u (Prod a b) ->
        (forall c d : term,
         typ e u (Prod c d) -> le_type e (Prod a b) (Prod c d)) ->
        typ_ppal e v tv ->
        ~ typ e v a -> expln e (Apply_err u (Prod a b) v tv).(* Meaning of errors *)
  Inductive expln : env -> type_error -> Prop :=
    | Exp_under :
        forall (e : env) (t : term) (err : type_error),
        expln (Ax t :: e) err -> expln e (Under t err)
    | Exp_exp_type :
        forall (e : env) (m at_ et : term),
        typ_ppal e m at_ ->
        ~ typ e m et ->
        free_db (length e) et -> expln e (Expected_type m at_ et)
    | Exp_topsort :
        forall (e : env) (s : sort),
        wf e -> (forall t : term, ~ typ e (Srt s) t) -> expln e (Topsort s)
    | Exp_db :
        forall (e : env) (n : nat),
        wf e -> length e <= n -> expln e (Db_error n)
    | Exp_lam_topsort :
        forall (e : env) (m t : term) (s : sort),
        typ_ppal (Ax t :: e) m (Srt s) ->
        (forall u : term, ~ typ e (Srt s) u) ->
        expln e (Lambda_topsort (Abs t m) s)
    | Exp_type :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall s : sort, ~ typ e m (Srt s)) -> expln e (Not_a_type m t)
    | Exp_fun :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall a b : term, ~ typ e m (Prod a b)) -> expln e (Not_a_fun m t)
    | Exp_appl_err :
        forall (e : env) (u v a b tv : term),
        typ e u (Prod a b) ->
        (forall c d : term,
         typ e u (Prod c d) -> le_type e (Prod a b) (Prod c d)) ->
        typ_ppal e v tv ->
        ~ typ e v a -> expln e (Apply_err u (Prod a b) v tv).(* Meaning of errors *)
  Inductive expln : env -> type_error -> Prop :=
    | Exp_under :
        forall (e : env) (t : term) (err : type_error),
        expln (Ax t :: e) err -> expln e (Under t err)
    | Exp_exp_type :
        forall (e : env) (m at_ et : term),
        typ_ppal e m at_ ->
        ~ typ e m et ->
        free_db (length e) et -> expln e (Expected_type m at_ et)
    | Exp_topsort :
        forall (e : env) (s : sort),
        wf e -> (forall t : term, ~ typ e (Srt s) t) -> expln e (Topsort s)
    | Exp_db :
        forall (e : env) (n : nat),
        wf e -> length e <= n -> expln e (Db_error n)
    | Exp_lam_topsort :
        forall (e : env) (m t : term) (s : sort),
        typ_ppal (Ax t :: e) m (Srt s) ->
        (forall u : term, ~ typ e (Srt s) u) ->
        expln e (Lambda_topsort (Abs t m) s)
    | Exp_type :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall s : sort, ~ typ e m (Srt s)) -> expln e (Not_a_type m t)
    | Exp_fun :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall a b : term, ~ typ e m (Prod a b)) -> expln e (Not_a_fun m t)
    | Exp_appl_err :
        forall (e : env) (u v a b tv : term),
        typ e u (Prod a b) ->
        (forall c d : term,
         typ e u (Prod c d) -> le_type e (Prod a b) (Prod c d)) ->
        typ_ppal e v tv ->
        ~ typ e v a -> expln e (Apply_err u (Prod a b) v tv).(* Meaning of errors *)
  Inductive expln : env -> type_error -> Prop :=
    | Exp_under :
        forall (e : env) (t : term) (err : type_error),
        expln (Ax t :: e) err -> expln e (Under t err)
    | Exp_exp_type :
        forall (e : env) (m at_ et : term),
        typ_ppal e m at_ ->
        ~ typ e m et ->
        free_db (length e) et -> expln e (Expected_type m at_ et)
    | Exp_topsort :
        forall (e : env) (s : sort),
        wf e -> (forall t : term, ~ typ e (Srt s) t) -> expln e (Topsort s)
    | Exp_db :
        forall (e : env) (n : nat),
        wf e -> length e <= n -> expln e (Db_error n)
    | Exp_lam_topsort :
        forall (e : env) (m t : term) (s : sort),
        typ_ppal (Ax t :: e) m (Srt s) ->
        (forall u : term, ~ typ e (Srt s) u) ->
        expln e (Lambda_topsort (Abs t m) s)
    | Exp_type :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall s : sort, ~ typ e m (Srt s)) -> expln e (Not_a_type m t)
    | Exp_fun :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall a b : term, ~ typ e m (Prod a b)) -> expln e (Not_a_fun m t)
    | Exp_appl_err :
        forall (e : env) (u v a b tv : term),
        typ e u (Prod a b) ->
        (forall c d : term,
         typ e u (Prod c d) -> le_type e (Prod a b) (Prod c d)) ->
        typ_ppal e v tv ->
        ~ typ e v a -> expln e (Apply_err u (Prod a b) v tv).(* Meaning of errors *)
  Inductive expln : env -> type_error -> Prop :=
    | Exp_under :
        forall (e : env) (t : term) (err : type_error),
        expln (Ax t :: e) err -> expln e (Under t err)
    | Exp_exp_type :
        forall (e : env) (m at_ et : term),
        typ_ppal e m at_ ->
        ~ typ e m et ->
        free_db (length e) et -> expln e (Expected_type m at_ et)
    | Exp_topsort :
        forall (e : env) (s : sort),
        wf e -> (forall t : term, ~ typ e (Srt s) t) -> expln e (Topsort s)
    | Exp_db :
        forall (e : env) (n : nat),
        wf e -> length e <= n -> expln e (Db_error n)
    | Exp_lam_topsort :
        forall (e : env) (m t : term) (s : sort),
        typ_ppal (Ax t :: e) m (Srt s) ->
        (forall u : term, ~ typ e (Srt s) u) ->
        expln e (Lambda_topsort (Abs t m) s)
    | Exp_type :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall s : sort, ~ typ e m (Srt s)) -> expln e (Not_a_type m t)
    | Exp_fun :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall a b : term, ~ typ e m (Prod a b)) -> expln e (Not_a_fun m t)
    | Exp_appl_err :
        forall (e : env) (u v a b tv : term),
        typ e u (Prod a b) ->
        (forall c d : term,
         typ e u (Prod c d) -> le_type e (Prod a b) (Prod c d)) ->
        typ_ppal e v tv ->
        ~ typ e v a -> expln e (Apply_err u (Prod a b) v tv).(* Meaning of errors *)
  Inductive expln : env -> type_error -> Prop :=
    | Exp_under :
        forall (e : env) (t : term) (err : type_error),
        expln (Ax t :: e) err -> expln e (Under t err)
    | Exp_exp_type :
        forall (e : env) (m at_ et : term),
        typ_ppal e m at_ ->
        ~ typ e m et ->
        free_db (length e) et -> expln e (Expected_type m at_ et)
    | Exp_topsort :
        forall (e : env) (s : sort),
        wf e -> (forall t : term, ~ typ e (Srt s) t) -> expln e (Topsort s)
    | Exp_db :
        forall (e : env) (n : nat),
        wf e -> length e <= n -> expln e (Db_error n)
    | Exp_lam_topsort :
        forall (e : env) (m t : term) (s : sort),
        typ_ppal (Ax t :: e) m (Srt s) ->
        (forall u : term, ~ typ e (Srt s) u) ->
        expln e (Lambda_topsort (Abs t m) s)
    | Exp_type :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall s : sort, ~ typ e m (Srt s)) -> expln e (Not_a_type m t)
    | Exp_fun :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall a b : term, ~ typ e m (Prod a b)) -> expln e (Not_a_fun m t)
    | Exp_appl_err :
        forall (e : env) (u v a b tv : term),
        typ e u (Prod a b) ->
        (forall c d : term,
         typ e u (Prod c d) -> le_type e (Prod a b) (Prod c d)) ->
        typ_ppal e v tv ->
        ~ typ e v a -> expln e (Apply_err u (Prod a b) v tv).(* Meaning of errors *)
  Inductive expln : env -> type_error -> Prop :=
    | Exp_under :
        forall (e : env) (t : term) (err : type_error),
        expln (Ax t :: e) err -> expln e (Under t err)
    | Exp_exp_type :
        forall (e : env) (m at_ et : term),
        typ_ppal e m at_ ->
        ~ typ e m et ->
        free_db (length e) et -> expln e (Expected_type m at_ et)
    | Exp_topsort :
        forall (e : env) (s : sort),
        wf e -> (forall t : term, ~ typ e (Srt s) t) -> expln e (Topsort s)
    | Exp_db :
        forall (e : env) (n : nat),
        wf e -> length e <= n -> expln e (Db_error n)
    | Exp_lam_topsort :
        forall (e : env) (m t : term) (s : sort),
        typ_ppal (Ax t :: e) m (Srt s) ->
        (forall u : term, ~ typ e (Srt s) u) ->
        expln e (Lambda_topsort (Abs t m) s)
    | Exp_type :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall s : sort, ~ typ e m (Srt s)) -> expln e (Not_a_type m t)
    | Exp_fun :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall a b : term, ~ typ e m (Prod a b)) -> expln e (Not_a_fun m t)
    | Exp_appl_err :
        forall (e : env) (u v a b tv : term),
        typ e u (Prod a b) ->
        (forall c d : term,
         typ e u (Prod c d) -> le_type e (Prod a b) (Prod c d)) ->
        typ_ppal e v tv ->
        ~ typ e v a -> expln e (Apply_err u (Prod a b) v tv).(* Meaning of errors *)
  Inductive expln : env -> type_error -> Prop :=
    | Exp_under :
        forall (e : env) (t : term) (err : type_error),
        expln (Ax t :: e) err -> expln e (Under t err)
    | Exp_exp_type :
        forall (e : env) (m at_ et : term),
        typ_ppal e m at_ ->
        ~ typ e m et ->
        free_db (length e) et -> expln e (Expected_type m at_ et)
    | Exp_topsort :
        forall (e : env) (s : sort),
        wf e -> (forall t : term, ~ typ e (Srt s) t) -> expln e (Topsort s)
    | Exp_db :
        forall (e : env) (n : nat),
        wf e -> length e <= n -> expln e (Db_error n)
    | Exp_lam_topsort :
        forall (e : env) (m t : term) (s : sort),
        typ_ppal (Ax t :: e) m (Srt s) ->
        (forall u : term, ~ typ e (Srt s) u) ->
        expln e (Lambda_topsort (Abs t m) s)
    | Exp_type :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall s : sort, ~ typ e m (Srt s)) -> expln e (Not_a_type m t)
    | Exp_fun :
        forall (e : env) (m t : term),
        typ e m t ->
        (forall a b : term, ~ typ e m (Prod a b)) -> expln e (Not_a_fun m t)
    | Exp_appl_err :
        forall (e : env) (u v a b tv : term),
        typ e u (Prod a b) ->
        (forall c d : term,
         typ e u (Prod c d) -> le_type e (Prod a b) (Prod c d)) ->
        typ_ppal e v tv ->
        ~ typ e v a -> expln e (Apply_err u (Prod a b) v tv).

(* Specifications: *)
Lemma expln_wf : forall (e : env) (err : type_error), expln e err -> wf e.