Section ListEnumerability.
Variable (X: Const).
Hypothesis (enumX: enumT X).
Fixpoint L_exp (n: nat) : list (exp X) :=
match n with
| 0 => nil
| S n => L_exp n
++ [var x | x ∈ L_T nat n]
++ [const c | c ∈ L_T X n]
++ [lambda s | s ∈ L_exp n]
++ [app s t | (s, t) ∈ (L_exp n × L_exp n)]
end.
Global Instance enumT_exp: enumT (exp X).
Fixpoint L_type (n: nat) : list (type) :=
match n with
| 0 => nil
| S n => L_type n
++ [typevar x | x ∈ L_T nat n]
++ [A → B | (A, B) ∈ (L_type n × L_type n)]
end.
Global Instance enumT_type: enumT type.
(* ** Typing Proofs *)
Fixpoint L_typingT Gamma s A n : list (Gamma ⊢ (s: exp X) : A) :=
match n with
| 0 => nil
| S n => L_typingT Gamma s A n ++
match s as s return list (Gamma ⊢ s : A) with
| var i => [typingVar Gamma i H where H: nth Gamma i = Some A]
| const c => [cast (typingConst Gamma c) H where H : ctype X c = A]
| lambda s => match A with
| typevar beta => nil
| A → B => [ typingLam H | H ∈ L_typingT (A :: Gamma) s B n]
end
| app s t =>
[typingApp H1 H2 | (H1, H2) ∈ (L_typingT Gamma s (A1 → A) n × L_typingT Gamma t A1 n) & A1 ∈ L_T n]
end
end.
Scheme typing_strong_ind := Induction for typing Sort Prop.
Global Instance enumT_typing Gamma (s: exp X) A: enumT (Gamma ⊢ s: A).
Fixpoint L_typing n : list (ctx * exp X * type) :=
match n with
| 0 => nil
| S n =>
L_typing n ++ [(Gamma, s, A) | (Gamma, s, A) ∈ (L_T n × L_T n × L_T n), |@L_T (Gamma ⊢ s : A) _ n| <> 0]
end.

Lemma enum_typing:
enum (fun '(Gamma, s, A) => Gamma ⊢ (s: exp X) : A) L_typing.