Section fo_term_rect.
Variable (P   : fo_term -> Type)
(HP0 : forall x, P (in_var x))
(IHP : forall s v, (forall p, P (vec_pos v p)) -> P (@in_fot s v)).
Fixpoint fo_term_rect t : P t :=
match t with
| in_var x => HP0 x
| in_fot v => IHP v (fun p => fo_term_rect (vec_pos v p))
end.
End fo_term_rect.
Definition fo_term_rec (P : _ -> Set) := @fo_term_rect P.
Definition fo_term_ind (P : _ -> Prop) := @fo_term_rect P.
Fixpoint fo_term_size t : nat :=
match t with
| in_var x => 1
| in_fot v => 1 + lsum (vec_list (vec_map fo_term_size v))
end.
Fixpoint fo_term_height t : nat :=
match t with
| in_var x => 0
| in_fot v => 1 + lmax (vec_list (vec_map fo_term_height v))
end.
Fact fo_term_size_lt s v p : fo_term_size (vec_pos v p) < fo_term_size (@in_fot s v).
Fact fo_term_height_lt s v p : fo_term_height (vec_pos v p) < fo_term_height (@in_fot s v).
Fact in_fot_inv_dep s s' v w : @in_fot s v = @in_fot s' w -> exists E : s = s', eq_rect s (fun s => vec _ (ar_syms s)) v _ E = w.

Theorem eq_fo_term_dec : discrete fo_term.