Require Import Tarski.
Require Import List.
Notation "x 'el' A" := (In x A) (at level 70).
Notation "A '<<=' B" := (incl A B) (at level 70).
Local Set Implicit Arguments.
Inductive peirce := class | intu.
Existing Class peirce.
Section ND_def.
Context {Σ_funcs : funcs_signature}.
Context {Σ_preds : preds_signature}.
Reserved Notation "A ⊢ phi" (at level 61).
Implicit Type p : peirce.
Implicit Type ff : falsity_flag.
Inductive prv : forall (ff : falsity_flag) (p : peirce), list form -> form -> Prop :=
| II {ff} {p} A phi psi : phi::A ⊢ psi -> A ⊢ phi --> psi
| IE {ff} {p} A phi psi : A ⊢ phi --> psi -> A ⊢ phi -> A ⊢ psi
| AllI {ff} {p} A phi : map (subst_form ↑) A ⊢ phi -> A ⊢ ∀ phi
| AllE {ff} {p} A t phi : A ⊢ ∀ phi -> A ⊢ phi[t..]
| ExI {ff} {p} A t phi : A ⊢ phi[t..] -> A ⊢ ∃ phi
| ExE {ff} {p} A phi psi : A ⊢ ∃ phi -> phi::(map (subst_form ↑) A) ⊢ psi[↑] -> A ⊢ psi
| Exp {p} A phi : prv p A falsity -> prv p A phi
| Ctx {ff} {p} A phi : phi el A -> A ⊢ phi
| CI {ff} {p} A phi psi : A ⊢ phi -> A ⊢ psi -> A ⊢ phi ∧ psi
| CE1 {ff} {p} A phi psi : A ⊢ phi ∧ psi -> A ⊢ phi
| CE2 {ff} {p} A phi psi : A ⊢ phi ∧ psi -> A ⊢ psi
| DI1 {ff} {p} A phi psi : A ⊢ phi -> A ⊢ phi ∨ psi
| DI2 {ff} {p} A phi psi : A ⊢ psi -> A ⊢ phi ∨ psi
| DE {ff} {p} A phi psi theta : A ⊢ phi ∨ psi -> phi::A ⊢ theta -> psi::A ⊢ theta -> A ⊢ theta
| Pc {ff} A phi psi : prv class A (((phi --> psi) --> phi) --> phi)
where "A ⊢ phi" := (prv _ A phi).
Definition tprv `{falsity_flag} `{peirce} (T : form -> Prop) phi :=
exists A, (forall psi, psi el A -> T psi) /\ A ⊢ phi.
End ND_def.
Arguments prv {_ _ _ _} _ _.
Notation "A ⊢ phi" := (prv A phi) (at level 55).
Notation "A ⊢C phi" := (@prv _ _ _ class A phi) (at level 55).
Notation "A ⊢I phi" := (@prv _ _ _ intu A phi) (at level 55).
Notation "A ⊢M phi" := (@prv _ _ falsity_off intu A phi) (at level 55).
Notation "T ⊢T phi" := (tprv T phi) (at level 55).
Notation "T ⊢TI phi" := (@tprv _ _ _ intu T phi) (at level 55).
Notation "T ⊢TC phi" := (@tprv _ _ _ class T phi) (at level 55).
Ltac comp := repeat (progress (cbn in *; autounfold in *)).
Section ND_def.
Context {Σ_funcs : funcs_signature}.
Context {Σ_preds : preds_signature}.
Context {ff : falsity_flag}.
Context {p : peirce}.
Theorem Weak A B phi :
A ⊢ phi -> A <<= B -> B ⊢ phi.
Proof.
intros H. revert B.
induction H; intros B HB; try unshelve (solve [econstructor; intuition]); try now econstructor.
Qed.
Lemma combine_context {Γ1 Γ2} alpha beta : Γ1 ⊢ alpha -> Γ2 ⊢ (alpha --> beta) -> (Γ1 ++ Γ2) ⊢ beta.
Proof.
intros H1 H2.
apply (@Weak _ (Γ1 ++ Γ2)) in H1.
apply (@Weak _ (Γ1 ++ Γ2)) in H2.
eapply IE; eassumption.
now apply incl_appr. now apply incl_appl.
Qed.
Hint Constructors prv : core.
Lemma imps T phi psi :
T ⊢ phi --> psi <-> (phi :: T) ⊢ psi.
Proof.
split; try apply II.
intros H. apply IE with phi; auto. apply (Weak H). firstorder.
Qed.
Lemma CE T phi psi :
T ⊢ phi ∧ psi -> T ⊢ phi /\ T ⊢ psi.
Proof.
intros H. split.
- apply (CE1 H).
- apply (CE2 H).
Qed.
Lemma DE' A phi :
A ⊢ phi ∨ phi -> A ⊢ phi.
Proof.
intros H. apply (DE H); apply Ctx; firstorder.
Qed.
Lemma switch_conj_imp alpha beta phi A :
A ⊢ alpha ∧ beta --> phi <-> A ⊢ alpha --> beta --> phi.
Proof.
split; intros H.
- apply II, II. eapply IE.
apply (@Weak A). apply H. firstorder.
apply CI; apply Ctx; firstorder.
- apply II. eapply IE. eapply IE.
eapply Weak. apply H.
firstorder.
eapply CE1, Ctx; firstorder.
eapply CE2, Ctx; firstorder.
Qed.
End ND_def.
Hint Constructors prv : core.
Section Soundness.
Context {Σ_funcs : funcs_signature}.
Context {Σ_preds : preds_signature}.
Lemma soundness {ff : falsity_flag} A phi :
A ⊢I phi -> valid_ctx A phi.
Proof.
remember intu as p.
induction 1; intros D I rho HA; comp.
- intros Hphi. apply IHprv; trivial. intros ? []; subst. assumption. now apply HA.
- now apply IHprv1, IHprv2.
- intros d. apply IHprv; trivial. intros psi [psi'[<- H' % HA]] % in_map_iff.
eapply sat_comp. now comp.
- eapply sat_comp, sat_ext. 2: apply (IHprv Heqp D I rho HA (eval rho t)). now intros [].
- exists (eval rho t). cbn. specialize (IHprv Heqp D I rho HA).
apply sat_comp in IHprv. eapply sat_ext; try apply IHprv. now intros [].
- edestruct IHprv1 as [d HD]; eauto.
assert (H' : forall psi, phi = psi \/ psi el map (subst_form ↑) A -> (d.:rho) ⊨ psi).
+ intros P [<-|[psi'[<- H' % HA]] % in_map_iff]; trivial. apply sat_comp. apply H'.
+ specialize (IHprv2 Heqp D I (d.:rho) H'). apply sat_comp in IHprv2. apply IHprv2.
- apply (IHprv Heqp) in HA. firstorder.
- firstorder.
- firstorder.
- firstorder. now apply H0.
- firstorder. now apply H0.
- firstorder.
- firstorder.
- edestruct IHprv1; eauto.
+ apply IHprv2; trivial. intros xi [<-|HX]; auto.
+ apply IHprv3; trivial. intros xi [<-|HX]; auto.
- discriminate.
Qed.
Lemma soundness' {ff : falsity_flag} phi :
List.nil ⊢I phi -> valid phi.
Proof.
intros H % soundness.
intros D I rho. apply H. cbn. firstorder.
Qed.
Corollary tsoundness {ff : falsity_flag} T phi :
T ⊢TI phi -> forall D (I : interp D) rho, (forall psi, T psi -> rho ⊨ psi) -> rho ⊨ phi.
Proof.
intros (A & H1 & H2) D I rho HI. apply (soundness H2).
intros psi HP. apply HI, H1, HP.
Qed.
Hypothesis LEM : forall P, P \/ ~ P.
Lemma Peirce (P Q : Prop) :
((P -> Q) -> P) -> P.
Proof.
destruct (LEM (((P -> Q) -> P) -> P)); tauto.
Qed.
Lemma soundness_class {ff : falsity_flag} A phi :
A ⊢C phi -> valid_ctx A phi.
Proof.
remember class as p.
induction 1; intros D I rho HA; comp.
- intros Hphi. apply IHprv; trivial. intros ? []; subst. assumption. now apply HA.
- now apply IHprv1, IHprv2.
- intros d. apply IHprv; trivial. intros psi [psi'[<- H' % HA]] % in_map_iff.
eapply sat_comp. now comp.
- eapply sat_comp, sat_ext. 2: apply (IHprv Heqp D I rho HA (eval rho t)). now intros [].
- exists (eval rho t). cbn. specialize (IHprv Heqp D I rho HA).
apply sat_comp in IHprv. eapply sat_ext; try apply IHprv. now intros [].
- edestruct IHprv1 as [d HD]; eauto.
assert (H' : forall psi, phi = psi \/ psi el map (subst_form ↑) A -> (d.:rho) ⊨ psi).
+ intros P [<-|[psi'[<- H' % HA]] % in_map_iff]; trivial. apply sat_comp. apply H'.
+ specialize (IHprv2 Heqp D I (d.:rho) H'). apply sat_comp in IHprv2. apply IHprv2.
- apply (IHprv Heqp) in HA. firstorder.
- firstorder.
- clear LEM. firstorder.
- firstorder. now apply H0.
- firstorder. now apply H0.
- clear LEM. firstorder.
- clear LEM. firstorder.
- edestruct IHprv1; eauto.
+ apply IHprv2; trivial. intros xi [<-|HX]; auto.
+ apply IHprv3; trivial. intros xi [<-|HX]; auto.
- apply Peirce.
Qed.
Lemma soundness_class' {ff : falsity_flag} phi :
List.nil ⊢C phi -> valid phi.
Proof.
intros H % soundness_class. clear LEM.
intros D I rho. apply H. cbn. firstorder.
Qed.
Corollary tsoundness_class {ff : falsity_flag} T phi :
T ⊢TC phi -> forall D (I : interp D) rho, (forall psi, T psi -> rho ⊨ psi) -> rho ⊨ phi.
Proof.
intros (A & H1 & H2) D I rho HI. apply (soundness_class H2).
intros psi HP. apply HI, H1, HP.
Qed.
End Soundness.
Section Incl.
Context {Σ_funcs : funcs_signature}.
Context {Σ_preds : preds_signature}.
Notation "A ⊏ B" := (forall psi, psi el A -> B psi) (at level 70).
Lemma incl_app {ff : falsity_flag} (A B : list form) (T : form -> Prop) : A ⊏ T -> B ⊏ T -> A ++ B ⊏ T.
Proof.
intros H1 H2 psi []%List.in_app_or.
now apply H1. now apply H2.
Qed.
End Incl.
From Undecidability.Synthetic Require Import Definitions DecidabilityFacts EnumerabilityFacts ListEnumerabilityFacts ReducibilityFacts.
From Undecidability Require Import Shared.ListAutomation.
Import ListAutomationNotations.
(* ** Enumerability of proofs *)
Section Enumerability.
Context {Σ_funcs : funcs_signature}.
Context {Σ_preds : preds_signature}.
Variable list_Funcs : nat -> list syms.
Hypothesis enum_Funcs' : list_enumerator__T list_Funcs syms.
Variable list_Preds : nat -> list preds.
Hypothesis enum_Preds' : list_enumerator__T list_Preds preds.
Hypothesis eq_dec_Funcs : eq_dec syms.
Hypothesis eq_dec_Preds : eq_dec preds.
Instance eqdec_binop : eq_dec binop.
Proof.
intros x y. unfold dec. decide equality.
Qed.
Instance eqdec_quantop : eq_dec quantop.
Proof.
intros x y. unfold dec. decide equality.
Qed.
Definition list_binop (n : nat) := [Conj; Impl; Disj].
Instance enum_binop :
list_enumerator__T list_binop binop.
Proof.
intros []; exists 0; cbn; tauto.
Qed.
Definition list_quantop (n : nat) := [All; Ex].
Instance enum_quantop :
list_enumerator__T list_quantop quantop.
Proof.
intros []; exists 0; cbn; tauto.
Qed.
Lemma enumT_binop :
enumerable__T binop.
Proof.
apply enum_enumT. exists list_binop. apply enum_binop.
Qed.
Lemma enumT_quantop :
enumerable__T quantop.
Proof.
apply enum_enumT. exists list_quantop. apply enum_quantop.
Qed.
Instance enum_term' :
list_enumerator__T (L_term _ _) term :=
enum_term _ _.
Instance enum_form' {ff : falsity_flag} :
list_enumerator__T (L_form _ _ _ _ _ _ _ _) form :=
enum_form _ _ _ _ _ _ _ _.
Instance dec_list {ff : falsity_flag} A (phi : form ff) :
dec (phi el A).
Proof.
apply list_in_dec.
Admitted.
Fixpoint L_ded {p : peirce} {b : falsity_flag} (A : list form) (n : nat) : list form :=
match n with
| 0 => A
| S n => L_ded A n ++
(* II *) concat ([ [ phi --> psi | psi ∈ L_ded (phi :: A) n ] | phi ∈ L_T form n ]) ++
(* IE *) [ psi | (phi, psi) ∈ (L_ded A n × L_T form n) , (phi --> psi el L_ded A n) ] ++
(* AllI *) [ ∀ phi | phi ∈ L_ded (map (subst_form ↑) A) n ] ++
(* AllE *) [ phi[t..] | (phi, t) ∈ (L_T form n × L_T term n), (∀ phi) el L_ded A n ] ++
(* ExI *) [ ∃ phi | (phi, t) ∈ (L_T form n × L_T term n), (phi[t..]) el L_ded A n ] ++
(* ExE *) [ psi | (phi, psi) ∈ (L_T form n × L_T form n),
(∃ phi) el L_ded A n /\ psi[↑] el L_ded (phi::(map (subst_form ↑) A)) n ] ++
(* Exp *) (match b with falsity_on => fun A =>
[ phi | phi ∈ L_T form n, ⊥ el @L_ded _ falsity_on A n ]
| _ => fun _ => nil end A) ++
(* Pc *) (if p then
[ (((phi --> psi) --> phi) --> phi) | (pair phi psi) ∈ (L_T form n × L_T form n)]
else nil) ++
(* CI *) [ phi ∧ psi | (phi, psi) ∈ (L_ded A n × L_ded A n) ] ++
(* CE1 *) [ phi | (phi, psi) ∈ (L_T form n × L_T form n), phi ∧ psi el L_ded A n] ++
(* CE2 *) [ psi | (phi, psi) ∈ (L_T form n × L_T form n), phi ∧ psi el L_ded A n] ++
(* DI1 *) [ phi ∨ psi | (phi, psi) ∈ (L_T form n × L_T form n), phi el L_ded A n] ++
(* DI2 *) [ phi ∨ psi | (phi, psi) ∈ (L_T form n × L_T form n), psi el L_ded A n] ++
(* DE *) [ theta | (phi, (psi, theta)) ∈ (L_T form n × (L_T form n × L_T form n)),
theta el L_ded (phi::A) n /\ theta el L_ded (psi::A) n /\ phi ∨ psi el L_ded A n]
end.
Opaque in_dec.
Ltac inv_collect' :=
repeat
(match goal with
| [ H : ?x el concat _ |- _ ] => eapply in_concat_iff in H as (? & ? & ?)
| [ H : ?x el map _ _ |- _ ] => let x := fresh "x" in eapply in_map_iff in H as (x & ? & ?)
| [ x : ?A * ?B |- _ ] => destruct x; subst
| [ H : ?x el filter _ _ |- _ ] => let H' := fresh "H" in eapply in_filter_iff in H as (? & H' % to_dec)
| [ H : ?x el list_prod _ _ |- _ ] => eapply in_prod_iff in H
| [ H : _ el _ ++ _ |- _ ] => try eapply in_app_iff in H as []
| [H : _ el _ :: _ |- _ ] => destruct H
end; intuition; subst).
Lemma enum_prv {p : peirce} {b : falsity_flag} A :
list_enumerator (L_ded A) (prv A).
Proof with try (eapply cum_ge'; eauto; lia).
split.
- rename x into phi. induction 1; try congruence; subst.
+ destruct IHprv as [m1], (el_T phi) as [m2]. exists (1 + m1 + m2). cbn. in_app 2.
eapply in_concat_iff. eexists. split. 2:in_collect phi... in_collect psi...
+ destruct IHprv1 as [m1], IHprv2 as [m2], (el_T psi) as [m3]; eauto.
exists (1 + m1 + m2 + m3).
cbn. in_app 3. in_collect (phi, psi)...
+ destruct IHprv as [m]. exists (1 + m). cbn. in_app 4. in_collect phi...
+ destruct IHprv as [m1], (el_T t) as [m2], (el_T phi) as [m3]. exists (1 + m1 + m2 + m3).
cbn. in_app 5. in_collect (phi, t)...
+ destruct IHprv as [m1], (el_T t) as [m2], (el_T phi) as [m3]. exists (1 + m1 + m2 + m3).
cbn. in_app 6. in_collect (phi, t)...
+ destruct IHprv1 as [m1], IHprv2 as [m2], (el_T phi) as [m4], (el_T psi) as [m5].
exists (1 + m1 + m2 + m4 + m5). cbn. in_app 7. cbn. in_collect (phi, psi)...
+ destruct IHprv as [m1], (el_T phi) as [m2]. exists (1 + m1 + m2). cbn. in_app 8. in_collect phi...
+ now exists 0.
+ destruct IHprv1 as [m1], IHprv2 as [m2]. exists (1 + m1 + m2). cbn. in_app 10. in_collect (phi, psi)...
+ destruct IHprv as [m1], (el_T phi) as [m2], (el_T psi) as [m3].
exists (1 + m1 + m2 + m3). cbn. in_app 11. in_collect (phi, psi)...
+ destruct IHprv as [m1], (el_T phi) as [m2], (el_T psi) as [m3].
exists (1 + m1 + m2 + m3). cbn. in_app 12. in_collect (phi, psi)...
+ destruct IHprv as [m1], (el_T phi) as [m2], (el_T psi) as [m3].
exists (1 + m1 + m2 + m3). cbn. in_app 13. in_collect (phi, psi)...
+ destruct IHprv as [m1], (el_T phi) as [m2], (el_T psi) as [m3].
exists (1 + m1 + m2 + m3). cbn. in_app 14. in_collect (phi, psi)...
+ destruct IHprv1 as [m1], IHprv2 as [m2], IHprv3 as [m3], (el_T phi) as [m4], (el_T psi) as [m5], (el_T theta) as [m6].
exists (1 + m1 + m2 + m3 + m4 + m5 + m6). cbn. in_app 15. cbn. in_collect (phi, (psi, theta))...
+ destruct (el_T phi) as [m1], (el_T psi) as [m2]. exists (1 + m1 + m2). cbn. in_app 9. in_collect (phi, psi)...
- intros [m]; induction m in A, x, H |-*; cbn in *.
+ now apply Ctx.
+ destruct p, b; inv_collect. all: eauto 3.
* eapply IE; apply IHm; eauto.
* eapply ExE; apply IHm; eauto.
* eapply DE; apply IHm; eauto.
* eapply IE; apply IHm; eauto.
* eapply ExE; apply IHm; eauto.
* eapply DE; apply IHm; eauto.
* eapply IE; apply IHm; eauto.
* eapply ExE; apply IHm; eauto.
* eapply DE; apply IHm; eauto.
* eapply IE; apply IHm; eauto.
* eapply ExE; apply IHm; eauto.
* eapply DE; apply IHm; eauto.
Qed.
Fixpoint L_con `{falsity_flag} (L : nat -> list form) (n : nat) : list (list form) :=
match n with
| 0 => [ nil ]
| S n => L_con L n ++ [ phi :: A | (pair phi A) ∈ (L n × L_con L n) ]
end.
Lemma enum_el X (p : X -> Prop) L x :
list_enumerator L p -> p x -> exists m, x el L m.
Proof.
firstorder.
Qed.
Arguments enum_el {X p L} x _ _.
Lemma enum_p X (p : X -> Prop) L x m :
list_enumerator L p -> x el L m -> p x.
Proof.
firstorder.
Qed.
Definition containsL `{falsity_flag} A (T : form -> Prop) :=
forall psi, psi el A -> T psi.
Lemma enum_containsL `{falsity_flag} T L :
cumulative L -> list_enumerator L T -> list_enumerator (L_con L) (fun A => containsL A T).
Proof with try (eapply cum_ge'; eauto; lia).
intros HL He. split.
- induction x as [| phi A]; intros HT.
+ exists 0. firstorder.
+ destruct IHA as [m1], (enum_el phi He) as [m2]. 1,2,3: firstorder.
exists (1 + m1 + m2). cbn. in_app 2. in_collect (phi, A)...
- intros [m]. induction m in x, H0 |-*; cbn in *.
+ destruct H0 as [<- | []]. firstorder.
+ inv_collect. apply IHm in H2. apply (enum_p _ _ He) in H0. unfold containsL in *. firstorder congruence.
Qed.
Fixpoint L_tded {p : peirce} {b : falsity_flag} (L : nat -> list form) (n : nat) : list form :=
match n with
| 0 => nil
| S n => L_tded L n ++ concat ([ L_ded A n | A ∈ L_con L n ])
end.
Lemma enum_tprv {p : peirce} {b : falsity_flag} T L :
list_enumerator L T -> list_enumerator (L_tded (cumul L)) (tprv T).
Proof with try (eapply cum_ge'; eauto; lia).
intros He.
assert (HL : list_enumerator (cumul L) T) by now apply list_enumerator_to_cumul.
split.
- intros (A & [m1] % (enum_el A (@enum_containsL _ _ (cumul L) (to_cumul_cumulative L) HL)) & [m2] % (enum_el x (enum_prv A))).
exists (1 + m1 + m2). cbn. in_app 2. eapply in_concat_iff. eexists. split. 2: in_collect A... idtac...
- intros [m]. induction m in x, H |-*; cbn in *. 1: contradiction. inv_collect. exists x1. split.
+ eapply (enum_p _ _ (enum_containsL (to_cumul_cumulative L) HL)); eauto.
+ eapply (enum_p _ _ (enum_prv x1)); eassumption.
Qed.
End Enumerability.