Require Import nd models.
Require Import List.
Require Import Coq.Classes.RelationClasses.
Require Import Coq.Program.Equality.
Require Import Coq.Logic.Classical.

Classical Strong Completeness


Definition LEM := p, p p.
Definition DN := p, ~~ p p.
We can derive double-negation elimination from LEM
Lemma LEM2DN: LEM DN.
Proof.
  intros LEM p H.
  destruct (LEM p); firstorder.
Qed.


Section Models.
  Context {d : DerivationType}.

  Definition evalK' {M: KripkeModel} (Γ: theory) :=
     w s, (Γ s) @evalK M s w.

Being an IEL or IEL^- model is a property of a given model.
  Definition isIEL (M: KripkeModel) := w, w', verif w w'.


  Definition model_constraint (d : DerivationType) m :=
      if d then True else isIEL m.


  Definition entails {d: DerivationType} (Γ: theory) (φ: form) :=
     (M : KripkeModel), model_constraint d M
      (( w,evalK' Γ w @evalK M φ w)).

  Notation "Γ ⊨ φ" := (entails Γ φ) (at level 30).

Evaluation is monotone, that is if φ is true at world w and we can reach world v from w, φ true at v.
  Variable M : KripkeModel.

  Lemma monotone_ctx (A:theory) :
     w w', cogn w w' evalK' A w evalK' A w'.
  Proof.
    intros. intros t .
    apply eval_monotone with ( := w); auto.
  Qed.

End Models.

Canonical models

Section Canonical.
We define the *canonical models*, whose worlds are the maximally consistent theories. We first define the relations.
  Context {d : DerivationType}.

  Record mcTheory := mkmcTheory {
                         T: theory;
                         Ttheory: φ, (@ndT d T φ) T φ;
                         consistentT: ~(T );
                         prime: is_prime T;
                       }.

  Definition lindenBaumTheory (DN: DN) (Γ: theory) (φ: form) (H: ~(ndT Γ φ)) :mcTheory.
    destruct (Lindenbaum H). destruct . destruct .

    apply mkmcTheory with (T := (max Γ φ)).
    + tauto.
    + intro. apply . apply ndtE. apply ndtA. assumption.
    + intros a b Ha.
       unfold is_primeDN in . specialize ( a b).
       apply DN in . eauto.
  Defined.

  Lemma lindenBaumTheorySubset (DN: DN) Γ (φ: form) (H: ~(ndT Γ φ)) : Δ: mcTheory ,Γ (T Δ).
  Proof.
    exists (lindenBaumTheory DN H).
    simpl T. assert ( (T (lindenBaumTheory DN H)) = (max Γ φ)). cbv. firstorder. unfold lindenBaumTheory. apply max_subset.
  Qed.


  Definition subsetMKT (A B: mcTheory) := subset (T A) (T B).
  Definition valuationMKT (A: mcTheory) (a: ) := (T A) (Var a).

  Definition subsetVerif (A B:mcTheory) :=
     a, ((T A) (K a)) (T B) a.
  Instance canonical: (KripkeModel).
  Proof.
    apply mkKripkeModel with (world := mcTheory) (cogn := subsetMKT) (val := valuationMKT) (verif := subsetVerif).
    all: try firstorder.
    intros A B c d' E. apply Ttheory with:= d'). destruct B. simpl. apply ndtA. apply c. apply ndtA in E. apply ndtKpos in E.
      apply Ttheory in E. exact E.
  Defined.


  Lemma deductionGamma (Gamma: mcTheory) (phi: form): ndT (T ) (T ) .
  Proof.
    split.
    - intro. apply Ttheory in H. exact H.
    - apply ndtA.
  Qed.

  Hint Resolve deductionGamma : core.

  Lemma world_canonical_disjunction (t: mcTheory) ψ φ :
    ((T t) (φ ψ)) (ndT (T t) φ) ndT (T t) ψ.
  Proof.
    intros. split.
    - intro.
      apply prime.
      apply deductionGamma.
      exact H.
    - intro. destruct H; eauto.
      + apply deductionGamma. apply ndtDIL. eauto.
      + apply deductionGamma. apply ndtDIR. eauto.
  Qed.


End Canonical.

Lemma canonicalIEL (DN: DN): isIEL (@canonical normal).
Proof.
  intros w.
  assert (~(@ndT normal (unbox (T w)) )).
  {
    intros H % modalShiftingLemma.
    destruct w. apply .
    apply @.
    apply @ndtIE with (s := (K )).
    - apply @ndtW with (T := empty).
      + apply IELKBot.
      + firstorder.
    - simpl T in H. exact H.
  }
  exists (lindenBaumTheory DN H).
  intros x . simpl lindenBaumTheory.
  simpl T.
  apply max_subset.
  apply unbox_rewrite.
  exact .
Qed.


Strong Completeness

Section Completeness.

Truth-Lemma

  Lemma truth_lemma {d: DerivationType} (DN: DN): (X: form) (t: (@world canonical)),
    (evalK X t) ((T t) X).
  Proof.
    intro x.
    induction x.
    - split.
      + intro . apply DN. intro H'.
        assert (H: unbox (T t) T x).
        * intros H. now apply H', deductionGamma, modalShiftingLemma.
        * assert ( Δ: mcTheory , (unbox (T t)) (T Δ)
                                   ~((T Δ) x)).
          {
            exists (lindenBaumTheory DN H).
            split.
            - apply max_subset.
            - intro. apply ndtA in .
              apply does_not_derive in ; auto.
          }
          destruct . destruct . apply . apply IHx. auto.


      + intros A. simpl evalK. intros r V. apply IHx. auto.
    - split.
      +
        intro.
        apply deductionGamma. apply DN. rewrite deductionGamma.
        intro.
        enough ( Δ: mcTheory, (T t) (T Δ) ((T Δ) ) ~((T Δ) )). destruct as [Δ ].
        specialize (H Δ). destruct . destruct . apply . apply . (*apply H0.*) firstorder eauto.
        (*    apply IHx1. exact H2.  *)
        rewrite deductionGamma in . rewrite ImpAgree in .
        destruct (Lindenbaum ).
        exists (lindenBaumTheory DN ).
        split. intros x . firstorder eauto.

        split.
        * apply deductionGamma. apply ndtW with (#(T t)). apply ndtA. left. reflexivity. unfold lindenBaumTheory. cbn. apply max_subset.
        * rewrite deductionGamma. destruct . auto.
      + intros. intros w . apply . apply deductionGamma. apply ndtIE with (s := ). apply deductionGamma. apply . exact H. apply deductionGamma. apply . exact .
    - split.
      + intro H.
        destruct H.
        apply deductionGamma.
        apply ndtCI; apply ndtA.
        * apply . exact H.
        * apply . exact .
      + intros . split.
        * apply deductionGamma in . apply ndtCEL in . apply .
          apply deductionGamma. auto.
        * apply deductionGamma in . apply ndtCER in . apply .
          apply deductionGamma. auto.
    - intro. simpl evalK. rewrite world_canonical_disjunction. rewrite . rewrite .
      repeat rewrite deductionGamma. tauto.

    - split.
      +
        intro. exfalso. apply H.
      + intro. exfalso. apply (consistentT H).
    - split; firstorder.
  Qed.


  Lemma StrongCompleteness {d: DerivationType} (Γ: theory) (φ: form):
   LEM (entails Γ φ) Γ T φ.
  Proof.

    intros DN % LEM2DN .
    apply DN.
    intro H.
    unfold entails in .
    specialize ( canonical).
    enough ( Δ: mcTheory, ~((T Δ) T φ) (Γ (T Δ))).
    destruct as [Δ ].
    assert (model_constraint d canonical). {
      destruct d eqn:deq.
      - simpl. auto.
      - apply canonicalIEL. auto.
    }
    specialize ( Δ).
    apply .
    apply deductionGamma.
    apply truth_lemma. auto.
    apply . intros ψ P. apply truth_lemma. auto. apply deductionGamma. destruct . apply ndtA.
    apply . exact P.
    (* Show that such a theory exists *)
    exists (lindenBaumTheory DN H).
    split.
    apply does_not_derive. exact H.
    apply max_subset.
  Qed.



  Lemma evalKimp {M: KripkeModel} s t w: evalK s w evalK (Imp s t) w evalK t w.
  Proof.
    intros .
    apply . apply preorderCogn. auto.
  Qed.


  Lemma evalKdistr {M: KripkeModel} s w w': evalK (K s) w verif w w' evalK s w'.
  Proof.
    intros.
    apply H.
    exact .
  Qed.


  Definition ctx2thy (Γ: context) := x In x Γ.

  Lemma ndSoundIELCtx (A: context) (s: form) {p: DerivationType} (D:@nd p A s):entails (ctx2thy A) s.
  Proof.
    intros M Mc. induction D.
    + eauto.
    + intros. exfalso. apply (IHD) with w; auto.
    + intros . apply IHD; auto. intro s'. intro . destruct . subst s'. assumption. apply eval_monotone with (w := ); auto.
    + intros w H. apply evalKimp with ( := s). apply ; auto. apply ; auto.
    + intros w H w' c w'' v. specialize IHD with w. apply evalKimp with ( := s). apply . exact v.
      apply evalKdistr with ( := w); auto. apply transvalid with (y := w'); auto.
    + intros w H w' v. apply IHD; auto. apply monotone_ctx with (w := w); try tauto; auto. apply vericont; auto.
    + intros w . apply IHD in ; auto. destruct . auto.
    + intros w . apply IHD in ; auto. destruct . auto.
    + intros w . split; auto.
    + intros w . left. auto.
    + intros w . right. auto.
    + intros w . destruct ( Mc w ).
    - apply ( Mc w); auto. apply preorderCogn.
    - apply ( Mc w); auto. apply preorderCogn.
      + intros w u c.
        apply monotone_ctx with (w' := u) in . 2: auto.
        unfold isIEL in Mc. destruct (Mc u).
        specialize (IHD Mc u).
        assert (evalK s x).
        {
          apply IHD; auto.
        }
        intro.
        apply ( x). apply vericont. auto.
        apply .
  Qed.


  Lemma ndSoundIEL (A: theory) (s: form) {p: DerivationType} (D:@ndT p A s):entails A s.
  Proof.
    intros. destruct D. intros M c w . destruct H.
    specialize (ndSoundIELCtx ) . intro . apply . auto. intros a Ha.
    apply . apply H. apply Ha.
  Qed.


  Lemma ndSound (Γ: theory) A {p: DerivationType}: Γ T A entails Γ A.
  Proof.
    intros. apply ndSoundIEL. auto.
  Qed.


  Inductive uno := Uno.
  Definition cogUno := (x: uno) (y: uno) True.
  Definition unoModel: KripkeModel.
    apply mkKripkeModel with (world := uno) (cogn := cogUno) (verif := cogUno) (val := x y True).
    firstorder eauto.
    firstorder eauto.
    firstorder eauto.
    firstorder eauto.
  Defined.

  Lemma hasConstraint (D: DerivationType): model_constraint D unoModel.
  Proof.
    destruct D; firstorder eauto.
  Qed.


  Lemma ndConsistent (D: DerivationType): ~(nil ).
  Proof.
    intro.
    specialize (ndSoundIELCtx H). intro.

    enough ( M, ( w, ~(@evalK M w) model_constraint D M)).
    destruct as (M & w & ( & )). specialize ( M w).
    apply . apply . intros a Ha. destruct Ha.


    exists unoModel. exists Uno. split; try apply hasConstraint.
    intro. simpl evalK in . auto.
  Qed.

End Completeness.

Equivalence between completeness and LEM
Notation "Γ ⊨ A" := (entails Γ A) (at level 100).
Section CompletenessLEM.
  Variable (D: DerivationType).
  Definition strongCompleteness := Γ φ, (entails Γ φ) Γ T φ.

  Definition falsityStable := Γ, ~~(ndT Γ ) (ndT Γ ).

  Lemma entailmentBotDN Γ: ~~(entails Γ ) entails Γ .
  Proof.
    intro.
    intros M mc w . simpl evalK.
     apply wm with (Γ ). intro. destruct ; try tauto.
    specialize ( M mc w ). apply .
  Qed.


  Lemma st2fs: strongCompleteness falsityStable.
  Proof.
    intros H T .
    assert (~~(entails T )). {
     firstorder eauto using ndSoundIEL.
    }
    firstorder eauto using entailmentBotDN.
  Qed.


  Lemma fstab2LEM: falsityStable LEM.
  Proof.
    intros fstab P.
    pose (T := (x: form) P P).
    enough (T T ).
    destruct H as (Γ & & ).
    destruct Γ.
    - exfalso. apply (@ndConsistent D). apply .
    - unfold T in . apply with f. eauto.
    - apply fstab. intro. apply wm with P. intro.
      apply H. apply ndtA. unfold T. apply .
  Qed.


  Theorem st2lem: strongCompleteness LEM.
  Proof.
     intros H % st2fs. apply fstab2LEM; auto.
  Qed.

End CompletenessLEM.

Completeness for enumerable theories and MP
Section CompletenessEnumerableMP.
  Definition MP := (f: bool), ~~( n, f n = true) n, f n = true.
  Context {d: DerivationType}.

  Definition enumerable (T: theory) := (f: option form), x, T x n, f n = (Some x).
  Definition falsityEnumStable := Γ, enumerable Γ ~~(ndT Γ ) (ndT Γ ).

  Definition strongEnumerableCompleteness :=
     Γ φ, enumerable Γ (entails Γ φ) Γ T φ.

  Lemma ste2fs: strongEnumerableCompleteness falsityEnumStable.
  Proof.
    intros H T .
    assert (~~(entails T )). {
      intro. apply . intro. apply ndSoundIEL in . congruence.
    }
    apply H. auto. apply entailmentBotDN. auto.
  Qed.


  Definition ftheroy (f: bool) : option form.
    intro x.
    destruct (f x) eqn:fx.
    + apply (Some (decode x)).
    + apply None.
  Defined.
  Definition ftheroy' (f: bool) : option form :=
     n
         Some ((decode (n)) (¬ (decode (n)))).

  Lemma fenum2MP: strongEnumerableCompleteness MP.
  Proof.
    intros f .
    pose (T := (x: form) n, f n = true ( m, x = (m ¬ m) (decode n = m) )).
    enough (T T ).
    destruct H as (Γ & & ).
    destruct Γ.
    - exfalso. apply (@ndConsistent d). apply .
    - unfold T in . specialize ( ). destruct . eauto. exists x. tauto.
    - apply ste2fs. auto.
      + exists (ftheroy' f).
        intros . unfold T in . destruct as ( & ).
        destruct . destruct (decode_surj ). destruct as ( & & ).
        exists (). unfold ftheroy'. rewrite , . reflexivity.
      + intro. apply wm with ( n, f n = true). intro. destruct ; try tauto. clear .
        apply H. destruct as ( & ). apply ndtIE with ((decode )).
        apply ndtCER with (decode ). apply ndtA. exists . split; eauto.
         apply ndtCEL with (¬(decode )). apply ndtA. exists . split; eauto.
  Qed.

End CompletenessEnumerableMP.