Require Vector.
Section Model_Theory.
Variable L : Language.
Fixpoint naryFunc (A : Set) (n : nat) {struct n} : Set :=
match n with
| O => A
| S m => A -> naryFunc A m
end.
Fixpoint naryRel (A : Set) (n : nat) {struct n} : Type :=
match n with
| O => Prop
| S m => A -> naryRel A m
end.
Record Model : Type := model
{U : Set;
func : forall f : Functions L, naryFunc U (arity L (inr _ f));
rel : forall r : Relations L, naryRel U (arity L (inl _ r))}.
Variable M : Model.
Fixpoint interpTerm (value : nat -> U M) (t : Term L) {struct t} :
U M :=
match t with
| var v => value v
| apply f ts => interpTerms _ (func M f) value ts
end
with interpTerms (m : nat) (f : naryFunc (U M) m)
(value : nat -> U M) (ts : Terms L m) {struct ts} :
U M :=
match ts in (Terms _ n) return (naryFunc (U M) n -> U M) with
| Tnil => fun f => f
| Tcons m t ts => fun f => interpTerms m (f (interpTerm value t)) value ts
end f.
Fixpoint interpRels (m : nat) (r : naryRel (U M) m)
(value : nat -> U M) (ts : Terms L m) {struct ts} : Prop :=
match ts in (Terms _ n) return (naryRel (U M) n -> Prop) with
| Tnil => fun r => r
| Tcons m t ts => fun r => interpRels m (r (interpTerm value t)) value ts
end r.
Definition updateValue (value : nat -> U M) (n : nat)
(v : U M) (x : nat) : U M :=
match eq_nat_dec n x with
| left _ => v
| right _ => value x
end.
Fixpoint interpFormula (value : nat -> U M) (f : Formula L) {struct f} :
Prop :=
match f with
| equal t s => interpTerm value t = interpTerm value s
| atomic r ts => interpRels _ (rel M r) value ts
| impH A B => interpFormula value A -> interpFormula value B
| notH A => interpFormula value A -> False
| forallH v A => forall x : U M, interpFormula (updateValue value v x) A
end.

(* Specifications: *)
Lemma freeVarInterpTerm :
forall (v1 v2 : nat -> U M) (t : Term L),
(forall x : nat, In x (freeVarTerm L t) -> v1 x = v2 x) ->
interpTerm v1 t = interpTerm v2 t.
Lemma freeVarInterpRel :
forall (v1 v2 : nat -> U M) (n : nat) (ts : Terms L n) (r : naryRel (U M) n),
(forall x : nat, In x (freeVarTerms L n ts) -> v1 x = v2 x) ->
interpRels n r v1 ts -> interpRels n r v2 ts.
Lemma freeVarInterpFormula :
forall (v1 v2 : nat -> U M) (g : Formula L),
(forall x : nat, In x (freeVarFormula L g) -> v1 x = v2 x) ->
interpFormula v1 g -> interpFormula v2 g.
Lemma subInterpTerm :
forall (value : nat -> U M) (t : Term L) (v : nat) (s : Term L),
interpTerm (updateValue value v (interpTerm value s)) t =
interpTerm value (substituteTerm L t v s).
Lemma subInterpRel :
forall (value : nat -> U M) (n : nat) (ts : Terms L n)
(v : nat) (s : Term L) (r : naryRel (U M) n),
interpRels n r (updateValue value v (interpTerm value s)) ts <->
interpRels n r value (substituteTerms L n ts v s).
Lemma subInterpFormula :
forall (value : nat -> U M) (f : Formula L) (v : nat) (s : Term L),
interpFormula (updateValue value v (interpTerm value s)) f <->
interpFormula value (substituteFormula L f v s).
Lemma subInterpFormula1 :
forall (value : nat -> U M) (f : Formula L) (v : nat) (s : Term L),
interpFormula (updateValue value v (interpTerm value s)) f ->
interpFormula value (substituteFormula L f v s).
Lemma subInterpFormula2 :
forall (value : nat -> U M) (f : Formula L) (v : nat) (s : Term L),
interpFormula value (substituteFormula L f v s) ->
interpFormula (updateValue value v (interpTerm value s)) f.