(*Realizer [e:env][u,v:term] Cases (fix_inference u e) of (inl y)  => Cases (pa_least_prod the_algos e y) of (inleft (dom,rng)) => Cases (fix_chk_wk e v dom) of Chk_ok => (inl ? type_error (pa_subst the_algos v rng)) | (Chk_fail err) => (inr term ? (app_chk_err u (Prod dom rng) err)) end | _  => (inr term ? (Not_a_fun u y)) end | (inr err) => (inr term ? err) end.*)
intros.
case (fix_inference u e); trivial;
[ intros (y, ppty_u) | intros (err, expl, is_err) ].
case (pa_least_prod the_algos e y).
apply type_correctness with (1 := pp_ok ppty_u).
intros ((dom, rng), (wfprd, (leprd, lstprd))).
case (fix_chk_wk e v dom); intros; trivial.
apply wf_type_prod_l with (1 := wfprd).
left.
case (pa_subst the_algos v rng); intros x eqx.
exists x; subst x.
split; intros.
apply type_app with dom; auto with pts.
apply typ_conv_wf with y; auto with pts.
apply (pp_ok ppty_u).
Inversion_typ H0.
apply le_type_trans with (subst v Ur); auto with pts.
apply le_type_subst0 with V.
apply le_type_prod_r with dom; auto with pts.
apply lstprd.
apply (pp_least ppty_u) with (1 := H2).
right.
exists (app_chk_err u (Prod dom rng) err).
generalize e0.
inversion_clear c; simpl in |- *; trivial.
elim H0; simpl in |- *; intros; auto.
pattern dom at 0, err in |- *.
elim H0; simpl in |- *; intros; auto.
intros.
inversion_clear e1.
constructor; intros; auto.
apply typ_conv_wf with y; trivial.
apply (pp_ok ppty_u).
apply lstprd.
apply (pp_least ppty_u) with (1 := H3); trivial.
generalize e0.
inversion_clear c; simpl in |- *; intros.
generalize H0.
case err; simpl in |- *; intros;
try (apply Infe_subt with v; auto with pts; fail).
elim inf_no_exp with (1 := H1).
inversion_clear wfprd.
Inversion_typ H2.
elim inf_error_no_type with (1 := H0) (2 := e0) (3 := H4).
apply False_ind.
inversion_clear wfprd.
Inversion_typ H1.
inversion_clear e1.
elim H7 with s1; trivial.
constructor.
right.
exists (Not_a_fun u y); auto with pts.
constructor.
apply (pp_ok ppty_u).
red in |- *; intros.
elim n with (1 := pp_least ppty_u H0).
right.
exists err; auto with pts.
apply Infe_subt with u; trivial with pts.
Defined.
End Infer_Application.

(* Specifications: *)
Theorem infer_sort :
forall (e : env) (s : sort), wf e -> infer_ppal_type e (Srt s).