Inductive wf : env -> Prop :=
| wf_nil : wf nil
| wf_var :
forall (e : env) (T : term) (s : sort),
typ e T (Srt s) -> wf (Ax T :: e)
| wf_cst :
forall (e : env) (t T : term) (s : sort),
typ e t T -> typ e T (Srt s) -> wf (Def t T :: e)
with typ : env -> term -> term -> Prop :=
| type_ax :
forall (e : env) (s1 s2 : sort),
wf e -> axiom s1 s2 -> typ e (Srt s1) (Srt s2)
| type_var :
forall (e : env) (v : nat) (t : term),
wf e -> item_lift t e v -> typ e (Ref v) t
| type_abs :
forall (e : env) (T U M : term) (s : sort),
typ e (Prod T U) (Srt s) ->
typ (Ax T :: e) M U -> typ e (Abs T M) (Prod T U)
| type_app :
forall (e : env) (u v V Ur : term),
typ e v V -> typ e u (Prod V Ur) -> typ e (App u v) (subst v Ur)
| type_prod :
forall (e : env) (T U : term) (s1 s2 s3 : sort),
typ e T (Srt s1) ->
typ (Ax T :: e) U (Srt s2) ->
rule s1 s2 s3 -> typ e (Prod T U) (Srt s3)
| type_conv :
forall (e : env) (t U V : term) (s : sort),
typ e t U ->
le_type e U V ->
typ e V (Srt s) ->
typ e t V
(* sert uniquement quand il y a des sortes non typees: *)
| type_conv_srt :
forall (e : env) (t U : term) (s : sort),
typ e t U -> le_type e U (Srt s) -> typ e t (Srt s).
Hint Resolve wf_nil type_ax type_var: pts.
Definition rule_sat (s1 s2 s3 : sort) : Prop :=
exists2 x1 : _,
le_sort s1 x1 & (exists2 x2 : _, le_sort s2 x2 & rule x1 x2 s3).

Lemma type_prod_sat :
forall (e : env) (T U : term) (s1 s2 s3 : sort),
typ e T (Srt s1) ->
typ (Ax T :: e) U (Srt s2) ->
rule_sat s1 s2 s3 -> typ e (Prod T U) (Srt s3).