Record PTS_sub_spec : Type :=
{pts_axiom : relation sort;
pts_rules : sort -> sort -> sort -> Prop;
pts_le_type : Subtyping_rule}.
Load "PTS_spec".
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.

(* Specifications: *)
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).