Extra: Semantic Reduction With Function Quantifiers
Require Import FOL SOL FullSyntax Tarski Henkin.
Require Import Vector VectorLib Util.
Require Import Equations.Equations Equations.Prop.DepElim.
Require Import Lia.
Import VectorNotations.
Definition toFOLBinop b := match b with
| FullSyntax.Conj => FOL.Conj
| FullSyntax.Disj => FOL.Disj
| FullSyntax.Impl => FOL.Impl
end.
Definition toSOLBinop b := match b with
| FOL.Conj => FullSyntax.Conj
| FOL.Disj => FullSyntax.Disj
| FOL.Impl => FullSyntax.Impl
end.
Definition toSOLQuantop b := match b with
| FOL.All => FullSyntax.All
| FOL.Ex => FullSyntax.Ex
end.
Section Signature.
Context {Σf2 : SOL.funcs_signature}.
Context {Σp2 : SOL.preds_signature}.
(* Add symbols for function and predicate application to the
SOL signature. Also add predicates to check if something
is an individual, a function or a predicate. *)
Inductive FOLSyms :=
| NormalSym : syms -> FOLSyms
| FuncApp : nat -> FOLSyms.
Inductive FOLPreds :=
| NormalPred : preds -> FOLPreds
| PredApp : nat -> FOLPreds.
Instance Σf1 : FOL.funcs_signature := {|
FOL.syms := FOLSyms ;
FOL.ar_syms f := match f with NormalSym f => SOL.ar_syms f | FuncApp ar => S ar end
|}.
Instance Σp1 : FOL.preds_signature := {|
FOL.preds := FOLPreds ;
FOL.ar_preds P := match P with NormalPred P => SOL.ar_preds P | PredApp ar => S ar end
|}.
Notation "⊥'" := FOL.falsity.
Notation "A ∧' B" := (@FOL.bin Σf1 Σp1 FOL.full_operators _ FOL.Conj A B) (at level 41).
Notation "A ∨' B" := (@FOL.bin Σf1 Σp1 FOL.full_operators _ FOL.Disj A B) (at level 42).
Notation "A '-->'' B" := (@FOL.bin Σf1 Σp1 FOL.full_operators _ FOL.Impl A B) (at level 43, right associativity).
Notation "A '<-->'' B" := ((A -->' B) ∧' (B -->' A)) (at level 44, right associativity).
Notation "∀' Phi" := (@FOL.quant Σf1 Σp1 FOL.full_operators _ FOL.All Phi) (at level 50).
Notation "∃' Phi" := (@FOL.quant Σf1 Σp1 FOL.full_operators _ FOL.Ex Phi) (at level 50).
Translation from SOL to FOL
(* The idea is to use functions pos_i, pos_f and pos_p that given a
position in the SOL environment tell us the positition of the same
object in the FOL environment.
Quantifiers update those mappings by adding 0 the the matching
kind and shiftig the other two. *)
Definition pcons (pos : nat -> nat) : nat -> nat :=
fun n => match n with 0 => 0 | S n => S (pos n) end.
Definition pcons' (ar : nat) (pos : nat -> nat -> nat) : nat -> nat -> nat :=
fun n ar' => match n with
| 0 => if PeanoNat.Nat.eq_dec ar ar' then 0 else S (pos 0 ar')
| S n => if PeanoNat.Nat.eq_dec ar ar' then S (pos n ar') else S (pos (S n) ar') end.
Definition pshift (pos : nat -> nat) : nat -> nat := fun n => S (pos n).
Definition pshift' (pos : nat -> nat -> nat) : nat -> nat -> nat := fun n ar => S (pos n ar).
Fixpoint toFOLTerm (pos_i : nat -> nat) (pos_f : nat -> nat -> nat) (t : SOL.term) : FOL.term := match t with
| SOL.var_indi x => FOL.var (pos_i x)
| SOL.func (@var_func _ x ar) v => FOL.func (FuncApp ar) (FOL.var (pos_f x ar) :: Vector.map (toFOLTerm pos_i pos_f) v)
| SOL.func (sym f) v => FOL.func (NormalSym f) (Vector.map (toFOLTerm pos_i pos_f) v)
end.
Fixpoint toFOLForm (pos_i : nat -> nat) (pos_f : nat -> nat -> nat) (pos_p : nat -> nat -> nat) (phi : SOL.form) : FOL.form := match phi with
| SOL.fal => FOL.falsity
| SOL.atom (pred P) v => FOL.atom (NormalPred P) (Vector.map (toFOLTerm pos_i pos_f) v)
| SOL.atom (@var_pred _ x ar) v => FOL.atom (PredApp ar) (FOL.var (pos_p x ar) :: Vector.map (toFOLTerm pos_i pos_f) v)
| SOL.bin op phi psi => FOL.bin (toFOLBinop op) (toFOLForm pos_i pos_f pos_p phi) (toFOLForm pos_i pos_f pos_p psi)
| SOL.quant_indi FullSyntax.All phi => ∀' toFOLForm (pcons pos_i) (pshift' pos_f) (pshift' pos_p) phi
| SOL.quant_indi FullSyntax.Ex phi => ∃' toFOLForm (pcons pos_i) (pshift' pos_f) (pshift' pos_p) phi
| SOL.quant_func FullSyntax.All ar phi => ∀' toFOLForm (pshift pos_i) (pcons' ar pos_f) (pshift' pos_p) phi
| SOL.quant_func FullSyntax.Ex ar phi => ∃' toFOLForm (pshift pos_i) (pcons' ar pos_f) (pshift' pos_p) phi
| SOL.quant_pred FullSyntax.All ar phi => ∀' toFOLForm (pshift pos_i) (pshift' pos_f) (pcons' ar pos_p) phi
| SOL.quant_pred FullSyntax.Ex ar phi => ∃' toFOLForm (pshift pos_i) (pshift' pos_f) (pcons' ar pos_p) phi
end.
Translate Henkin model to first-order model.
Section HenkinModel_To_FOModel.
Variable D2 : Type.
Context {I2 : Tarski.interp D2}.
Variable funcs : forall ar, (vec D2 ar -> D2) -> Prop.
Variable preds : forall ar, (vec D2 ar -> Prop) -> Prop.
Inductive D1 :=
| D_indi : D2 -> D1
| D_func : forall ar (f : vec D2 ar -> D2), funcs ar f -> D1
| D_pred : forall ar (P : vec D2 ar -> Prop), preds ar P -> D1.
Hypothesis D2_inhabited : D2.
Hypothesis funcs_inhabited : forall ar, { f | funcs ar f }.
Hypothesis preds_inhabited : forall ar, { P | preds ar P }.
Definition error_i := D2_inhabited.
Definition error_f ar := proj1_sig (funcs_inhabited ar).
Definition error_p ar := proj1_sig (preds_inhabited ar).
Lemma error_f_included ar :
funcs ar (error_f ar).
Proof.
unfold error_f. now destruct funcs_inhabited.
Qed.
Lemma error_p_included ar :
preds ar (error_p ar).
Proof.
unfold error_p. now destruct preds_inhabited.
Qed.
Definition toIndi (d1 : D1) := match d1 with D_indi d2 => d2 | _ => error_i end.
Definition toFunc ar (d1 : D1) := match d1 with
| D_func ar' f2 _ => match PeanoNat.Nat.eq_dec ar ar' with
| left e => match eq_sym e in _ = ar return vec D2 ar -> D2 with eq_refl => f2 end
| right _ => error_f ar
end
| _ => error_f ar
end.
Definition toPred ar (d1 : D1) := match d1 with
| D_pred ar' P2 _ => match PeanoNat.Nat.eq_dec ar ar' with
| left e => match eq_sym e in _ = ar return vec D2 ar -> Prop with eq_refl => P2 end
| right _ => error_p ar
end
| _ => error_p ar
end.
Instance I1 : FOL.interp D1 := {|
FOL.i_func f := match f with
| NormalSym f => fun v => D_indi (Tarski.i_f _ f (Vector.map toIndi v))
| FuncApp ar => fun v => match Vector.hd v with
| D_func ar' f _ => match PeanoNat.Nat.eq_dec ar ar' with
| left e => D_indi (f match e in _ = ar' return vec _ ar' with eq_refl => Vector.map toIndi (Vector.tl v) end)
| right _ => D_indi (error_f ar (Vector.map toIndi (Vector.tl v)))
end
| _ => D_indi (error_f ar (Vector.map toIndi (Vector.tl v)))
end
end ;
FOL.i_atom P := match P with
| NormalPred P => fun v => Tarski.i_P _ P (Vector.map (fun d => match d with D_indi d => d | _ => error_i end) v)
| PredApp ar => fun v => match Vector.hd v with
| D_pred ar' P _ => match PeanoNat.Nat.eq_dec ar ar' with
| left e => P match e in _ = ar' return vec _ ar' with eq_refl => Vector.map toIndi (Vector.tl v) end
| right _ => error_p ar (Vector.map toIndi (Vector.tl v))
end
| _ => error_p ar (Vector.map toIndi (Vector.tl v))
end
end
|}.
Lemma toFOLTerm_correct_2To1 rho1 rho2 pos_i pos_f t :
(forall n, ~bounded_indi_term n t -> toIndi (rho1 (pos_i n)) = get_indi rho2 n)
-> (forall n ar, ~bounded_func_term ar n t -> toFunc ar (rho1 (pos_f n ar)) = get_func rho2 n ar)
-> toIndi (FOL.eval rho1 (toFOLTerm pos_i pos_f t)) = Tarski.eval D2 rho2 t.
Proof.
intros Hi Hf. induction t; cbn.
- apply Hi. cbn; lia.
- rewrite <- Hf. 2: cbn; lia.
assert (map toIndi (map (FOL.eval rho1) (map (toFOLTerm pos_i pos_f) v)) = map (eval D2 rho2) v) as ->. {
rewrite !map_map. eapply map_ext, Forall2_identical, Forall_ext_in.
2: apply IH. intros t H1 H2. rewrite H2. reflexivity.
+ intros n' H3. apply Hi. intros H4. apply H3. eapply Forall_in in H4. apply H4. easy.
+ intros n' ar' H3. apply Hf. intros [_ H4]. apply H3. eapply Forall_in in H4. apply H4. easy. }
destruct (rho1 (pos_f n ar)); try easy. cbn. now destruct PeanoNat.Nat.eq_dec as [<-|].
- f_equal. f_equal. rewrite map_map, map_map. eapply map_ext, Forall2_identical, Forall_ext_in.
2: apply IH. intros t H1 H2. rewrite H2. reflexivity.
+ intros n' H3. apply Hi. intros H4. apply H3. eapply Forall_in in H4. apply H4. easy.
+ intros n' ar' H3. apply Hf. intros H4. apply H3. eapply Forall_in in H4. apply H4. easy.
Qed.
Ltac destruct_eq_dec :=
repeat (cbn; try rewrite nat_eq_dec_same; cbn; try destruct PeanoNat.Nat.eq_dec as [->|]; try destruct PeanoNat.Nat.eq_dec as [<-|]).
Lemma toFOLForm_correct_2To1 rho1 rho2 pos_i pos_f pos_p phi :
(forall n, ~bounded_indi n phi -> toIndi (rho1 (pos_i n)) = get_indi rho2 n)
-> (forall n ar, ~bounded_func ar n phi -> toFunc ar (rho1 (pos_f n ar)) = get_func rho2 n ar)
-> (forall n ar, ~bounded_pred ar n phi -> toPred ar (rho1 (pos_p n ar)) = get_pred rho2 n ar)
-> FOL.sat rho1 (toFOLForm pos_i pos_f pos_p phi) <-> Henkin.sat funcs preds rho2 phi.
Proof.
revert rho1 rho2 pos_i pos_f pos_p. induction phi; intros rho1 rho2 pos_i pos_f pos_p Hi Hf Hp; cbn.
- reflexivity.
- destruct p; cbn.
+ rewrite <- Hp. 2: cbn; lia.
assert (map toIndi (map (FOL.eval rho1) (map (toFOLTerm pos_i pos_f) v)) = map (eval D2 rho2) v) as ->. {
rewrite !map_map. eapply map_ext, Forall2_identical, Forall_in.
intros t H. erewrite toFOLTerm_correct_2To1. reflexivity.
* intros n' H1. apply Hi. intros H2. apply H1. eapply Forall_in in H2. apply H2. easy.
* intros n' ar' H1. apply Hf. intros H2. apply H1. eapply Forall_in in H2. apply H2. easy. }
destruct (rho1 (pos_p n ar)); try easy. cbn. now destruct PeanoNat.Nat.eq_dec as [<-|].
+ assert (forall x y, x = y -> x <-> y) as X by now intros x y ->. apply X; clear X.
f_equal. rewrite !map_map. eapply map_ext, Forall2_identical, Forall_in.
intros t H. rewrite <- (toFOLTerm_correct_2To1 rho1 _ pos_i pos_f). now destruct FOL.eval.
* intros n' H1. apply Hi. intros H2. apply H1. eapply Forall_in in H2. apply H2. easy.
* intros n' ar' H1. apply Hf. intros H2. apply H1. eapply Forall_in in H2. apply H2. easy.
- specialize (IHphi1 rho1 rho2 pos_i pos_f pos_p ltac:(firstorder) ltac:(firstorder) ltac:(firstorder));
specialize (IHphi2 rho1 rho2 pos_i pos_f pos_p ltac:(firstorder) ltac:(firstorder) ltac:(firstorder)).
destruct b; cbn; tauto.
- destruct q; cbn; split.
+ intros H d. eapply IHphi. 4: apply (H (D_indi d)). intros []. all: firstorder.
+ intros H [d|ar f ?|ar P ?].
* eapply IHphi. 4: apply (H d). intros []. all: firstorder.
* eapply IHphi. 4: apply (H error_i). intros []. all: firstorder.
* eapply IHphi. 4: apply (H error_i). intros []. all: firstorder.
+ intros [[d|ar f ?|ar P ?] H].
* exists d. eapply IHphi. 4: apply H. intros []. all: firstorder.
* exists error_i. eapply IHphi. 4: apply H. intros []. all: firstorder.
* exists error_i. eapply IHphi. 4: apply H. intros []. all: firstorder.
+ intros [d H]. exists (D_indi d). eapply IHphi. 4: apply H. intros []. all: firstorder.
- destruct q; cbn; split.
+ intros H f Hf'. eapply IHphi. 4: apply (H (D_func _ f Hf')).
2: intros [] ar'; cbn; destruct PeanoNat.Nat.eq_dec as [->|]; cbn; try rewrite nat_eq_dec_same. all: firstorder.
+ intros H [d|ar f ?|ar P ?].
* eapply IHphi. 4: apply (H (error_f _)), error_f_included. 2: intros [] ar'; destruct_eq_dec. all: firstorder.
* destruct (PeanoNat.Nat.eq_dec n ar) as [->|].
-- eapply IHphi. 4: apply (H f). 2: intros [] ar'; destruct_eq_dec. all: firstorder.
-- eapply IHphi. 4: apply (H (error_f _)). 4: apply error_f_included. 2: intros [] ar'; destruct_eq_dec. all: firstorder.
* eapply IHphi. 4: apply (H (error_f _)), error_f_included. 2: intros [] ar'; destruct_eq_dec. all: firstorder.
+ intros [[d|ar f Hf'|ar P ?] H].
* exists (error_f _), (error_f_included _). eapply IHphi. 4: apply H. 2: intros [] ar'; destruct_eq_dec. all: firstorder.
* destruct (PeanoNat.Nat.eq_dec n ar) as [->|].
-- exists f, Hf'. eapply IHphi. 4: apply H. 2: intros [] ar'; destruct_eq_dec. all: firstorder.
-- exists (error_f _), (error_f_included _). eapply IHphi. 4: apply H. 2: intros [] ar'; destruct_eq_dec. all: firstorder.
* exists (error_f _), (error_f_included _). eapply IHphi. 4: apply H. 2: intros [] ar'; destruct_eq_dec. all: firstorder.
+ intros [f [Hf' H]]. exists (D_func _ f Hf'). eapply IHphi. 4: apply H. 2: intros [] ar'; destruct_eq_dec. all: firstorder.
- destruct q; cbn; split.
+ intros H P HP'. eapply IHphi. 4: apply (H (D_pred _ P HP')). 3: intros [] ar'; destruct_eq_dec. all: firstorder.
+ intros H [d|ar f ?|ar P ?].
* eapply IHphi. 4: apply (H (error_p _)), error_p_included. 3: intros [] ar'; destruct_eq_dec. all: firstorder.
* eapply IHphi. 4: apply (H (error_p _)), error_p_included. 3: intros [] ar'; destruct_eq_dec. all: firstorder.
* destruct (PeanoNat.Nat.eq_dec n ar) as [->|].
-- eapply IHphi. 4: apply (H P). 3: intros [] ar'; destruct_eq_dec. all: firstorder.
-- eapply IHphi. 4: apply (H (error_p _)), error_p_included. 3: intros [] ar'; destruct_eq_dec. all: firstorder.
+ intros [[d|ar f ?|ar P HP'] H].
* exists (error_p _), (error_p_included _). eapply IHphi. 4: apply H. 3: intros [] ar'; destruct_eq_dec. all: firstorder.
* exists (error_p _), (error_p_included _). eapply IHphi. 4: apply H. 3: intros [] ar'; destruct_eq_dec. all: firstorder.
* destruct (PeanoNat.Nat.eq_dec n ar) as [->|].
-- exists P, HP'. eapply IHphi. 4: apply H. 3: intros [] ar'; destruct_eq_dec. all: firstorder.
-- exists (error_p _), (error_p_included _). eapply IHphi. 4: apply H. 3: intros [] ar'; destruct_eq_dec. all: firstorder.
+ intros [P [HP' H]]. exists (D_pred _ P HP'). eapply IHphi. 4: apply H. 3: intros [] ar'; destruct_eq_dec. all: firstorder.
Qed.
End HenkinModel_To_FOModel.
Translate first-order model to Henkin model.
Section FOModel_To_HenkinModel.
Variable D1 : Type.
Context {I1 : FOL.interp D1}.
Definition D2 := D1.
Definition funcs ar (f : vec D2 ar -> D2) :=
exists d : D1, forall v, f v = i_func (f:=FuncApp ar) (d::v).
Definition preds ar (P : vec D2 ar -> Prop) :=
exists d : D1, forall v, P v <-> i_atom (P:=PredApp ar) (d::v).
Instance I2 : Tarski.interp D2 := {|
Tarski.i_f f v := i_func (f:=NormalSym f) v ;
Tarski.i_P P v := i_atom (P:=NormalPred P) v
|}.
Lemma toFOLTerm_correct_1To2 rho1 rho2 pos_i pos_f t :
(forall n, ~bounded_indi_term n t -> get_indi rho2 n = rho1 (pos_i n))
-> (forall n ar, ~bounded_func_term ar n t -> forall v, get_func rho2 n ar v = i_func (f:=FuncApp ar) (rho1 (pos_f n ar) :: v))
-> Tarski.eval D2 rho2 t = FOL.eval rho1 (toFOLTerm pos_i pos_f t).
Proof.
intros Hi Hf. induction t; cbn.
- apply Hi. cbn; lia.
- rewrite Hf. 2: cbn; lia. f_equal. f_equal. rewrite !map_map.
eapply map_ext_forall, Forall_ext_in. 2: apply IH. intros t H1 H2. apply H2.
+ intros n' H3. apply Hi. intros H4. apply H3. eapply Forall_in in H4. apply H4. easy.
+ intros n' ar' H3. apply Hf. intros [_ H4]. apply H3. eapply Forall_in in H4. apply H4. easy.
- f_equal. rewrite map_map. eapply map_ext_forall, Forall_ext_in.
2: apply IH. intros t H1 H2. apply H2.
+ intros n' H3. apply Hi. intros H4. apply H3. eapply Forall_in in H4. apply H4. easy.
+ intros n' ar' H3. apply Hf. intros H4. apply H3. eapply Forall_in in H4. apply H4. easy.
Qed.
Ltac destruct_eq_dec :=
repeat (cbn; try rewrite nat_eq_dec_same; cbn; try destruct PeanoNat.Nat.eq_dec as [->|]; try destruct PeanoNat.Nat.eq_dec as [<-|]).
Lemma toFOLForm_correct_1To2 rho1 rho2 pos_i pos_f pos_p phi :
(forall n, ~bounded_indi n phi -> get_indi rho2 n = rho1 (pos_i n))
-> (forall n ar, ~bounded_func ar n phi -> forall v, get_func rho2 n ar v = i_func (f:=FuncApp ar) (rho1 (pos_f n ar) :: v))
-> (forall n ar, ~bounded_pred ar n phi -> forall v, get_pred rho2 n ar v <-> i_atom (P:=PredApp ar) (rho1 (pos_p n ar) :: v))
-> FOL.sat rho1 (toFOLForm pos_i pos_f pos_p phi) <-> Henkin.sat funcs preds rho2 phi.
Proof.
revert rho1 rho2 pos_i pos_f pos_p. induction phi; intros rho1 rho2 pos_i pos_f pos_p Hi Hf Hp; cbn.
- reflexivity.
- destruct p; cbn.
+ rewrite <- Hp. 2: cbn; lia. assert (forall x y, x = y -> x <-> y) as X by now intros x y ->. apply X; clear X.
f_equal. rewrite !map_map. eapply map_ext_forall, Forall_in. intros t H.
erewrite <- toFOLTerm_correct_1To2. reflexivity.
* intros n' H1. apply Hi. intros H2. apply H1. eapply Forall_in in H2. apply H2. easy.
* intros n' ar' H1. apply Hf. intros H2. apply H1. eapply Forall_in in H2. apply H2. easy.
+ assert (forall x y, x = y -> x <-> y) as X by now intros x y ->. apply X; clear X.
f_equal. rewrite !map_map. eapply map_ext_forall, Forall_in. intros t H.
erewrite <- toFOLTerm_correct_1To2. reflexivity.
* intros n' H1. apply Hi. intros H2. apply H1. eapply Forall_in in H2. apply H2. easy.
* intros n' ar' H1. apply Hf. intros H2. apply H1. eapply Forall_in in H2. apply H2. easy.
- specialize (IHphi1 rho1 rho2 pos_i pos_f pos_p ltac:(clear IHphi1 IHphi2; firstorder) ltac:(clear IHphi1 IHphi2; firstorder) ltac:(clear IHphi1 IHphi2; firstorder));
specialize (IHphi2 rho1 rho2 pos_i pos_f pos_p ltac:(clear IHphi1 IHphi2; firstorder) ltac:(clear IHphi1 IHphi2; firstorder) ltac:(clear IHphi1 IHphi2; firstorder)).
destruct b; cbn; tauto.
- destruct q; cbn; split.
+ intros H d. eapply IHphi. 4: apply (H d). intros []. all: try easy; apply Hi.
+ intros H d. eapply IHphi. 4: apply (H d). intros []. all: try easy; apply Hi.
+ intros [d H]. exists d. eapply IHphi. 4: apply H. intros []. all: try easy; apply Hi.
+ intros [d H]. exists d. eapply IHphi. 4: apply H. intros []. all: try easy; apply Hi.
- destruct q; cbn; split.
+ intros H f [d Hd]. eapply IHphi. 4: apply (H d). 2: intros [] ar'; destruct_eq_dec. all: firstorder.
+ intros H d. eapply IHphi. 4: apply (H (fun v => @i_func Σf1 Σp1 _ _ (FuncApp n) (d::v))).
4: now exists d. 2: intros [] ar'; cbn; destruct_eq_dec. all: firstorder.
+ intros [d H]. exists (fun v => @i_func Σf1 Σp1 _ _ (FuncApp n) (d::v)).
eexists. now exists d. eapply IHphi. 4: apply H. 2: intros [] ar'; cbn; destruct_eq_dec. all: firstorder.
+ intros [f [[d Hd] H]]. exists d. eapply IHphi. 4: apply H. 2: intros [] ar'; cbn; destruct_eq_dec. all: firstorder.
- destruct q; cbn; split.
+ intros H P [d Hd]. eapply IHphi. 4: apply (H d). 3: intros [] ar'; destruct_eq_dec. all: try easy. firstorder. all: clear IHphi; firstorder.
+ intros H d. eapply IHphi. 4: apply (H (fun v => @i_atom Σf1 Σp1 _ _ (PredApp n) (d::v))).
4: now exists d. 3: intros [] ar'; cbn; destruct_eq_dec. all: clear IHphi H; firstorder.
+ intros [d H]. exists (fun v => @i_atom Σf1 Σp1 _ _ (PredApp n) (d::v)).
eexists. now exists d. eapply IHphi. 4: apply H. 3: intros [] ar'; cbn; destruct_eq_dec. all: clear IHphi H; firstorder.
+ intros [f [[d Hd] H]]. exists d. eapply IHphi. 4: apply H. 3: intros [] ar'; cbn; destruct_eq_dec. all: try easy. firstorder. all: clear IHphi; firstorder.
Qed.
End FOModel_To_HenkinModel.
Full translation of validity
Definition toFOLForm' (phi : SOL.form) := toFOLForm (fun _ => 0) (fun _ _ => 0) (fun _ _ => 0) phi.
Definition toFOLTheory (T : SOL.form -> Prop) := fun phi => (exists phi', phi = toFOLForm' phi' /\ T phi').
Definition validH (T : SOL.form -> Prop) phi :=
forall D (I : Tarski.interp D) funcs preds rho, henkin_env funcs preds rho -> (forall psi, T psi -> Henkin.sat funcs preds rho psi) -> Henkin.sat funcs preds rho phi.
Definition validFO `{falsity_flag} (T : FOL.form -> Prop) phi :=
forall D (I : FOL.interp D) rho, (forall psi, T psi -> FOL.sat rho psi) -> FOL.sat rho phi.
Definition closed phi := bounded_indi 0 phi /\ (forall ar, bounded_func ar 0 phi) /\ (forall ar, bounded_pred ar 0 phi).
Lemma henkin_valid_iff_firstorder_valid (T : SOL.form -> Prop) phi :
closed phi -> (forall psi, T psi -> closed psi) -> validH T phi <-> validFO (toFOLTheory T) (toFOLForm' phi).
Proof.
intros C TC. split.
- intros H D1 I1 rho1 HT.
pose (rho2 := ⟨ fun _ => rho1 0,
fun _ ar v => i_func (f:=FuncApp ar) (rho1 0 :: v),
fun _ ar v => i_atom (P:=PredApp ar) (rho1 0 :: v) ⟩).
unshelve eapply toFOLForm_correct_1To2 with (rho2 := rho2).
+ intros n H4. exfalso. eapply H4, bounded_indi_up. 2: apply C. lia.
+ intros n ar H4. exfalso. eapply H4, bounded_func_up. 2: apply C. lia.
+ intros n ar H4. exfalso. eapply H4, bounded_pred_up. 2: apply C. lia.
+ apply H.
* intros n ar. split; now exists (rho1 0).
* intros psi H1. apply toFOLForm_correct_1To2 with (rho1 := rho1) (pos_i := fun _ => 0) (pos_f := fun _ _ => 0) (pos_p := fun _ _ => 0).
-- intros n H2. exfalso. eapply H2, bounded_indi_up. 2: now apply TC. lia.
-- intros n ar H2. exfalso. eapply H2, bounded_func_up. 2: now apply TC. lia.
-- intros n ar H2. exfalso. eapply H2, bounded_pred_up. 2: now apply TC. lia.
-- apply HT. now exists psi.
- intros H D2 I2 funcs preds rho2 H_rho2 HT.
pose (rho1 := fun n : nat => D_indi _ funcs preds (get_indi rho2 0)).
unshelve eapply toFOLForm_correct_2To1 with (rho1 := rho1) (pos_i := fun _ => 0) (pos_f := fun _ _ => 0) (pos_p := fun _ _ => 0).
+ exact (get_indi rho2 0).
+ intros ar. exists (get_func rho2 0 ar). apply H_rho2.
+ intros ar. exists (get_pred rho2 0 ar). apply H_rho2.
+ intros n H1. exfalso. eapply H1, bounded_indi_up. 2: apply C. lia.
+ intros n ar H1. exfalso. eapply H1, bounded_func_up. 2: apply C. lia.
+ intros n ar H1. exfalso. eapply H1, bounded_pred_up. 2: apply C. lia.
+ apply H. intros psi [phi' [-> H1]]. eapply toFOLForm_correct_2To1 with (rho2 := rho2).
-- intros n H2. exfalso. eapply H2, bounded_indi_up. 2: now apply TC. lia.
-- intros n ar H2. exfalso. eapply H2, bounded_func_up. 2: now apply TC. lia.
-- intros n ar H2. exfalso. eapply H2, bounded_pred_up. 2: now apply TC. lia.
-- now apply HT.
Qed.
End Signature.