Section ENUMERATION.
Context {L : language}.
Let rank : Set := nat.
Fixpoint trm_depth (t : trm L) : rank :=
match t with
| Var_trm x => 0
| Fun_trm f ts => 1 + trms_depth ts
| Con_trm c => 1
end
with trms_depth {n : nat} (ts : trms L n) : rank :=
match ts with
| O_trms => 0
| S_trms n t ts => 1 + max (trm_depth t) (trms_depth ts)
end.
Definition enum_trm (x : nat) : trm L :=
let rk := fst (cp x) in
let seed := snd (cp x) in
gen_trm seed rk.
Definition enum_trms {n : nat} (x : nat) : trms L n :=
let rk := fst (cp x) in
let seed := snd (cp x) in
gen_trms seed rk.
#[local]
Instance trm_isEnumerable : isEnumerable (trm L) :=
{ enum := enum_trm
; enum_spec := trm_is_enumerable
}.
#[local]
Instance trms_isRecursivelyEnumerable (n : nat) : isEnumerable (trms L n) :=
{ enum := enum_trms
; enum_spec := trms_is_enumerable n
}.
Hypothesis enum_relation_symbols : isEnumerable L.(relation_symbols).
Fixpoint gen_frm (seed : nat) (rk : nat) {struct rk} : frm L :=
match rk with
| O =>
let '(seed1, seed') := cp seed in
let '(seed2, seed3) := cp seed' in
match seed1 with
| 0 => Eqn_frm (enum seed2) (enum seed3)
| _ => Rel_frm (enum seed2) (enum seed3)
end
| S rk' =>
let '(seed1, seed') := cp seed in
let '(seed2, seed3) := cp seed' in
match seed1 with
| 0 => Neg_frm (gen_frm seed' rk')
| 1 => Imp_frm (gen_frm seed2 rk') (gen_frm seed3 rk')
| 2 => All_frm seed2 (gen_frm seed3 rk')
| S (S (S i)) =>
match i with
| 0 => Eqn_frm (enum seed2) (enum seed3)
| _ => Rel_frm (enum seed2) (enum seed3)
end
end
end.
Definition enum_frm (x : nat) : frm L :=
let rk := fst (cp x) in
let seed := snd (cp x) in
gen_frm seed rk.

Theorem frm_is_enumerable (p : frm L)
: { x : nat | enum_frm x = p }.