Module SafePolyType.
(* s1 -> .. sn -> x where n <= x *)
Fixpoint is_safe_poly_arr (n: nat) (t: poly_type) :=
match t with
| poly_var x => n <= x
| poly_arr _ t => is_safe_poly_arr n t
| poly_abs _ => False
end.
(* ∀ .. ∀ s1 -> .. sn -> x where x is free *)
Fixpoint is_safe_poly_type (n: nat) (t: poly_type) :=
if t is poly_abs t then is_safe_poly_type (1+n) t else is_safe_poly_arr n t.
(* ∀ .. ∀ s1 -> .. sn -> x where x is free *)
Definition safe_poly_type (n: nat) (ts: list poly_type) (x: nat) :=
many_poly_abs n (many_poly_arr ts (poly_var (n + x))).

Lemma last_poly_var_safe_poly_type {t n ss x} : t = safe_poly_type n ss x -> last_poly_var t = Some x.