(** * Tarski Semantics *)
Require Export Undecidability.FOL.FOL.
(** ** Variables and Substitutions *)
Fixpoint vars_t (t : term) : list var :=
match t with
| V v => [v]
| P p => []
| t_f b t => vars_t t
| t_e => []
end.
Fixpoint consts_t (t : term) : list var :=
match t with
| V v => []
| P p => [p]
| t_f b t => consts_t t
| t_e => []
end.
Fixpoint subst_t x y (t : term) : term :=
match t with
| V v => if Dec (v = x) then y else V v
| P p => P p
| t_e => t_e
| t_f b t => t_f b (subst_t x y t)
end.
Fixpoint consts {b} (phi : form b) : list var :=
match phi with
| Pr t1 t2  => consts_t t1 ++ consts_t t2
| Fal
| Q => []
| Impl phi psi => consts phi ++ consts psi
| All v phi => v :: consts phi
end.
Fixpoint subst {b} x t phi :=
match phi with
| Pr t1 t2 => Pr (subst_t x t t1) (subst_t x t t2)
| Q => Q
| Fal => Fal
| Impl phi1 phi2 => Impl (subst x t phi1) (subst x t phi2)
| All v phi => All v (if Dec (x = v) then phi else subst x t phi)
end.
Definition consts_l {b} A := flat_map (@consts b) A.
Definition fresh (y : var) A := ~ y el A.
Fixpoint mkfresh (l : list nat) :=
match l with
| [] => 0
| x :: l => S x + mkfresh l
end.

(* Specifications: *)
Lemma mkfresh_spec l a : a el l -> a < mkfresh l.
Lemma make_fresh A : {z | fresh z A}.
Class interp (domain : Type) (rho : nat -> domain) :=
{
i_f : bool -> domain -> domain ;
i_e : domain ;
i_P : domain -> domain -> Prop ;
i_Q : Prop
}.