Section fix_signature.
Context {Σ_funcs : funcs_signature}.
(* We use the stdlib definition of vectors to be maximally compatible  *)
Unset Elimination Schemes.
Inductive term  : Type :=
| var : nat -> term
| func : forall (f : syms), vec term (ar_syms f) -> term.
Set Elimination Schemes.
Fixpoint subst_term (σ : nat -> term) (t : term) : term :=
match t with
| var t => σ t
| func f v => func f (map (subst_term σ) v)
end.
Context {Σ_preds : preds_signature}.
(* We use a flag to switch on and off a constant for falisity *)
Inductive falsity_flag := falsity_off | falsity_on.
Existing Class falsity_flag.
Existing Instance falsity_on | 1.
Existing Instance falsity_off | 0.
(* Syntax is parametrised in binary operators and quantifiers. Most developments will fix these types in the beginning and never change them. *)
Class operators := {binop : Type ; quantop : Type}.
Context {ops : operators}.
(* Formulas have falsity as fixed constant -- we could parametrise against this in principle *)
Inductive form : falsity_flag -> Type :=
| falsity : form falsity_on
| atom {b} : forall (P : preds), vec term (ar_preds P) -> form b
| bin {b} : binop -> form b -> form b -> form b
| quant {b} : quantop -> form b -> form b.
Arguments form {_}.
Definition up (σ : nat -> term) := scons (var 0) (funcomp (subst_term (funcomp var S)) σ).
Fixpoint subst_form `{falsity_flag} (σ : nat -> term) (phi : form) : form :=
match phi with
| falsity => falsity
| atom P v => atom P (map (subst_term σ) v)
| bin op phi1 phi2 => bin op (subst_form σ phi1) (subst_form σ phi2)
| quant op phi => quant op (subst_form (up σ) phi)
end.
(* Induction principle for terms *)
Inductive Forall {A : Type} (P : A -> Type) : forall {n}, t A n -> Type :=
| Forall_nil : Forall P (@Vector.nil A)
| Forall_cons : forall n (x : A) (l : t A n), P x -> Forall P l -> Forall P (@Vector.cons A x n l).
Inductive vec_in {A : Type} (a : A) : forall {n}, t A n -> Type :=
| vec_inB {n} (v : t A n) : vec_in a (cons A a n v)
| vec_inS a' {n} (v : t A n) : vec_in a v -> vec_in a (cons A a' n v).
Hint Constructors vec_in : core.

Lemma term_rect' (p : term -> Type) :
(forall x, p (var x)) -> (forall F v, (Forall p v) -> p (func F v)) -> forall (t : term), p t.