Section Semantics.
Variable domain : Type.
Class interp := B_I
{
i_f : forall f : Funcs, Vector.t domain (fun_ar f) -> domain ;
i_P : forall P : Preds, Vector.t domain (pred_ar P) -> Prop ;
}.
Definition env := nat -> domain.
Context {I : interp }.
Fixpoint eval (rho : env) (t : term) : domain :=
match t with
| var_term s => rho s
| Func f v => i_f (Vector.map (eval rho) v)
end.
Fixpoint sat (rho : env) (phi : form) : Prop :=
match phi with
| Pred P v => i_P (Vector.map (eval rho) v)
| Fal => False
| Impl phi psi => sat rho phi -> sat rho psi
| Conj phi psi => sat rho phi /\ sat rho psi
| Disj phi psi => sat rho phi \/ sat rho psi
| Ex phi => exists d : domain, sat (d .: rho) phi
| All phi => forall d : domain, sat (d .: rho) phi
end.
End Semantics.
Arguments sat  {_ _} _ _, _ _ _ _.
Notation "rho ⊨ phi" := (sat rho phi) (at level 20).
Fixpoint list_or (A : list form) : form :=
match A with
| nil => ⊥
| phi::A => phi ∨ list_or A
end.

Lemma list_or_spec A D (I : interp D) rho :
rho ⊨ list_or A <-> exists phi, phi el A /\ rho ⊨ phi.