(* Autor(s): Andrej Dudenhefner (1) Yannick Forster (1) Affiliation(s): (1) Saarland University, Saarbrücken, Germany *)
From Undecidability.SystemF.Util Require Import Facts poly_type_facts term_facts.
Arguments funcomp {X Y Z} _ _ / _.
(* Church-style System F Type Assignment Predicate *)
Inductive typing : environment -> term -> poly_type -> Prop :=
| typing_var {Gamma x t} :
nth_error Gamma x = Some t -> typing Gamma (var x) t
| typing_app {Gamma P Q s t} :
typing Gamma P (poly_arr s t) -> typing Gamma Q s -> typing Gamma (app P Q) t
| typing_abs {Gamma P s t} :
typing (s :: Gamma) P t -> typing Gamma (abs s P) (poly_arr s t)
| typing_ty_app {Gamma P s t} :
typing Gamma P (poly_abs s) -> typing Gamma (ty_app P t) (subst_poly_type (scons t poly_var) s)
| typing_ty_abs {Gamma P s} :
typing (map (ren_poly_type S) Gamma) P s -> typing Gamma (ty_abs P) (poly_abs s).

(* assigned types are unique *)
Lemma typing_functional {Gamma P t t'} : typing Gamma P t -> typing Gamma P t' -> t = t'.