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).
Hint Resolve Exp_under Exp_exp_type Exp_topsort Exp_db Exp_lam_topsort
Exp_type Exp_fun Exp_appl_err: pts.

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