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))).

Corollary iipc2_is_safe_environment {Gamma x} : iipc2 Gamma (poly_var x) -> Forall (is_safe_poly_type 0) Gamma ->
exists ss ts,
In (safe_poly_type (length ts) ss x) Gamma /\
Forall (iipc2 Gamma) (map (subst_poly_type (fold_right scons poly_var (rev ts))) ss).