Section Enumerability.
Context {Sigma : Signature}.
Variable e_F : nat -> list Funcs.
Variable e_P : nat -> list Preds.
Hypothesis enum_Funcs : list_enumerator__T e_F Funcs.
Hypothesis enum_Preds : list_enumerator__T e_P Preds.
Fixpoint L_term n : list term :=
match n with
| 0 => []
| S n => L_term n ++ var_term n :: concat ([ [ Func F v | v ∈ vecs_from (L_term n) (fun_ar F) ] | F ∈ L_T n])
end.
Global Instance enumT_term : list_enumerator__T L_term term.
Proof with try (eapply cum_ge'; eauto; lia).
intros t. induction t using strong_term_ind.
+ exists (S x); cbn. now in_app 2.
+ apply vec_forall_cml in H as [m H]. 2: exact L_term_cml. destruct (cumul_spec__T enum_Funcs F) as [m' H'].
exists (S (m + m')); cbn. in_app 3. eapply in_concat_iff. eexists. split. 2: in_collect F...
apply in_map. rewrite <- vecs_from_correct in H |-*. intros x H''. specialize (H x H'')...
Defined.
Fixpoint L_form n : list form :=
match n with
| 0 => [Fal]
| S n => L_form n
++ [Fal]
++ concat ([ [ Pred P v | v ∈ L_T (H := @enumT_vec _ _ _  _) n ] | P ∈ L_T n])
++ [ phi1 --> phi2 | (phi1, phi2) ∈ (L_form n × L_form n) ]
++ [ ∀ phi | phi ∈ L_form n ]
end.
Global Instance enumT_form : list_enumerator__T L_form form.
Proof with (try eapply cum_ge'; eauto; lia).
intros phi. induction phi.
+ exists 1. cbn; eauto.
+ destruct (el_T P) as [m Hm], (el_T t) as [m' Hm']. exists (S (m + m')); cbn.
in_app 3. eapply in_concat_iff. eexists. split. 2: in_collect P... apply in_map...
+ destruct IHphi1 as [m1], IHphi2 as [m2]. exists (1 + m1 + m2). cbn.
in_app 4. in_collect (pair phi1 phi2)...
+ destruct IHphi as [m]. exists (S m). cbn -[L_T].
in_app 5. in_collect phi...
Defined.
End Enumerability.
(* **** Equality deciders *)

Lemma dec_vec_in X n (v : vector X n) :
(forall x, vec_in x v -> forall y, dec (x = y)) -> forall v', dec (v = v').