Section ListEnumerabilityOrdered.
Variable (X: Const).
Hypothesis (enumX: enumT X).
Fixpoint L_le n: list ({ '(p, q) | p <= q}) :=
match n with
| 0 => nil
| S n => L_le n
++ [exist _ (p, p) (le_n p) | p ∈ L_T n]
++ [exist _ (p, S q) (le_S p q H) | (exist _ (p, q) H) ∈ L_le n ]
end.
Scheme le_strong_ind := Induction for le Sort Prop.
Global Instance enumT_sig_le: enumT ({ '(p, q) | p <= q}).
Global Instance enumT_le a b: enumT (a <= b).
Fixpoint L_ordertypingT Gamma n s A m : list (Gamma ⊢(n) (s: exp X) : A) :=
match m with
| 0 => nil
| S m => L_ordertypingT Gamma n s A m ++
match s as s return list (Gamma ⊢(n) s : A) with
| var i => [@ordertypingVar X n Gamma i A H1 H2 | H1 ∈ L_T m where H2: nth Gamma i = Some A]
| const c => [cast (@ordertypingConst X n Gamma c H1) H2 | H1 ∈ L_T m where H2: ctype X c = A]
| lambda s => match A with
| typevar beta => nil
| A → B => [ ordertypingLam H | H ∈ L_ordertypingT (A :: Gamma) n s B m]
end
| app s t => [ordertypingApp H1 H2 | (H1, H2) ∈ (L_ordertypingT Gamma n s (A1 → A) m × L_ordertypingT Gamma n t A1 m) & A1 ∈ L_T m]
end
end.
Scheme ordertyping_strong_ind := Induction for ordertyping Sort Prop.
Global Instance enumT_ordertyping Gamma n s A: enumT (Gamma ⊢(n) (s: exp X) : A).
Fixpoint L_orduni k (n: nat) : list (orduni k X) :=
match n with
| 0 => nil
| S n => L_orduni k n ++ flat_map (fun '(Gamma, s, t, A) => [@Build_orduni k _ Gamma s t A H1 H2 | (H1, H2) ∈ (L_T n × L_T n)])
[(Gamma, s, t, A) | (Gamma, s, t, A) ∈ (L_T n × L_T n × L_T n × L_T n)]
end.
Global Instance enumT_orduni n:
enumT (orduni n X).
Proof with eauto using cum_ge'.
exists (L_orduni n).
- eauto.
- intros [Gamma s t A H1 H2].
destruct (el_T Gamma) as [x1], (el_T s) as [x2], (el_T t) as [x3], (el_T A) as [x4], (el_T H1) as [x5], (el_T H2) as [x6].
exists (S (x1 + x2 + x3 + x4 + x5 + x6)); cbn. in_app 2.
eapply in_flat_map. exists (Gamma, s, t, A). intuition.
+ in_collect (Gamma, s, t, A); eapply cum_ge'; eauto;lia.
+ in_collect (H1, H2)...
Qed.
End ListEnumerabilityOrdered.

Theorem enumerable_orderdunification n (X: Const): 1 <= n -> enumerable__T X -> enumerable (OU n X).