Theory Classical_Connectives

chapter ‹ Classical Logic Connectives \label{sec:logical-connectives}›

theory Classical_Connectives
  imports
    Classical_Logic_Completeness
    List_Utilities
begin

text ‹ Here we define the usual connectives for classical logic. ›

no_notation FuncSet.funcset (infixr "" 60)

section ‹ Verum ›

definition (in classical_logic) verum :: "'a" ("")
  where
    " =   "

lemma (in classical_logic) verum_tautology [simp]: " "
  by (metis list_implication.simps(1) list_implication_axiom_k verum_def)

lemma verum_semantics [simp]:
  "𝔐 prop "
  unfolding verum_def by simp

lemma (in classical_logic) verum_embedding [simp]:
  "   = "
  by (simp add: classical_logic_class.verum_def verum_def)

section ‹ Conjunction ›

definition (in classical_logic)
  conjunction :: "'a  'a  'a" (infixr "" 67)
  where
    "φ  ψ = (φ  ψ  )  "

primrec (in classical_logic)
  arbitrary_conjunction :: "'a list  'a" ("")
  where
     " [] = "
  |  " (φ # Φ) = φ   Φ"

lemma (in classical_logic) conjunction_introduction:
  " φ  ψ  (φ  ψ)"
  by (metis
        modus_ponens
        conjunction_def
        list_flip_implication1
        list_implication.simps(1)
        list_implication.simps(2))

lemma (in classical_logic) conjunction_left_elimination:
  " (φ  ψ)  φ"
  by (metis (full_types)
        Peirces_law
        pseudo_scotus
        conjunction_def
        list_deduction_base_theory
        list_deduction_modus_ponens
        list_deduction_theorem
        list_deduction_weaken)

lemma (in classical_logic) conjunction_right_elimination:
  " (φ  ψ)  ψ"
  by (metis (full_types)
        axiom_k
        Contraposition
        modus_ponens
        conjunction_def
        flip_hypothetical_syllogism
        flip_implication)

lemma (in classical_logic) conjunction_embedding [simp]:
  " φ  ψ  =  φ    ψ "
  unfolding conjunction_def classical_logic_class.conjunction_def
  by simp

lemma conjunction_semantics [simp]:
  "𝔐 prop φ  ψ = (𝔐 prop φ  𝔐 prop ψ)"
  unfolding conjunction_def by simp

section ‹ Biconditional ›

definition (in classical_logic) biconditional :: "'a  'a  'a"   (infixr "" 75)
  where
    "φ  ψ = (φ  ψ)  (ψ  φ)"

lemma (in classical_logic) biconditional_introduction:
  " (φ  ψ)  (ψ  φ)  (φ  ψ)"
  by (simp add: biconditional_def conjunction_introduction)

lemma (in classical_logic) biconditional_left_elimination:
  " (φ  ψ)  φ  ψ"
  by (simp add: biconditional_def conjunction_left_elimination)

lemma (in classical_logic) biconditional_right_elimination:
  " (φ  ψ)  ψ  φ"
  by (simp add: biconditional_def conjunction_right_elimination)

lemma (in classical_logic) biconditional_embedding [simp]:
  " φ  ψ  =  φ    ψ "
  unfolding biconditional_def classical_logic_class.biconditional_def
  by simp

lemma biconditional_semantics [simp]:
  "𝔐 prop φ  ψ = (𝔐 prop φ  𝔐 prop ψ)"
  unfolding biconditional_def
  by (simp, blast)

section ‹ Negation ›

definition (in classical_logic) negation :: "'a  'a"  ("")
  where
    " φ = φ  "

lemma (in classical_logic) negation_introduction:
  " (φ  )   φ"
  unfolding negation_def
  by (metis axiom_k modus_ponens implication_absorption)

lemma (in classical_logic) negation_elimination:
  "  φ  (φ  )"
  unfolding negation_def
  by (metis axiom_k modus_ponens implication_absorption)

lemma (in classical_logic) negation_embedding [simp]:
  "  φ  =   φ "
  by (simp add:
        classical_logic_class.negation_def
        negation_def)

lemma negation_semantics [simp]:
  "𝔐 prop  φ = (¬ 𝔐 prop φ)"
  unfolding negation_def
  by simp

section ‹ Disjunction ›

definition (in classical_logic) disjunction :: "'a  'a  'a"   (infixr "" 67)
  where
    "φ  ψ = (φ  )  ψ"

primrec (in classical_logic) arbitrary_disjunction :: "'a list  'a" ("")
  where
     " [] = "
  |  " (φ # Φ) = φ   Φ"

lemma (in classical_logic) disjunction_elimination:
  " (φ  χ)  (ψ  χ)  (φ  ψ)  χ"
proof -
  let  = "[φ  χ, ψ  χ, φ  ψ]"
  have " :⊢ (φ  )  χ"
    unfolding disjunction_def
    by (metis hypothetical_syllogism
              list_deduction_def
              list_implication.simps(1)
              list_implication.simps(2)
              set_deduction_base_theory
              set_deduction_theorem
              set_deduction_weaken)
  hence " :⊢ χ"
    using excluded_middle_elimination
          list_deduction_modus_ponens
          list_deduction_theorem
          list_deduction_weaken
    by blast
  thus ?thesis
    unfolding list_deduction_def
    by simp
qed

lemma (in classical_logic) disjunction_left_introduction:
  " φ  (φ  ψ)"
  unfolding disjunction_def
  by (metis modus_ponens
            pseudo_scotus
            flip_implication)

lemma (in classical_logic) disjunction_right_introduction:
  " ψ  (φ  ψ)"
  unfolding disjunction_def
  using axiom_k
  by simp

lemma (in classical_logic) disjunction_embedding [simp]:
  " φ  ψ  =  φ    ψ "
  unfolding disjunction_def classical_logic_class.disjunction_def
  by simp

lemma disjunction_semantics [simp]:
  "𝔐 prop φ  ψ = (𝔐 prop φ  𝔐 prop ψ)"
  unfolding disjunction_def
  by (simp, blast)

section ‹ Mutual Exclusion ›

primrec (in classical_logic) exclusive :: "'a list  'a" ("")
  where
      " [] = "
    | " (φ # Φ) =  (φ   Φ)   Φ"

section ‹ Subtraction ›

definition (in classical_logic) subtraction :: "'a  'a  'a" (infixl "" 69)
  where "φ  ψ = φ   ψ"

lemma (in classical_logic) subtraction_embedding [simp]:
  " φ  ψ  =  φ    ψ "
  unfolding subtraction_def classical_logic_class.subtraction_def
  by simp

section ‹ Negated Lists ›

definition (in classical_logic) map_negation :: "'a list  'a list" ("")
  where [simp]: " Φ  map  Φ"

section ‹ Common (\& Uncommon) Identities ›

subsection ‹ Biconditional Equivalence Relation ›

lemma (in classical_logic) biconditional_reflection:
  " φ  φ"
  by (meson
        axiom_k
        modus_ponens
        biconditional_introduction
        implication_absorption)

lemma (in classical_logic) biconditional_symmetry:
  " (φ  ψ)  (ψ  φ)"
  by (metis (full_types) modus_ponens
                         biconditional_def
                         conjunction_def
                         flip_hypothetical_syllogism
                         flip_implication)

lemma (in classical_logic) biconditional_symmetry_rule:
  " φ  ψ   ψ  φ"
  by (meson modus_ponens
            biconditional_introduction
            biconditional_left_elimination
            biconditional_right_elimination)

lemma (in classical_logic) biconditional_transitivity:
    " (φ  ψ)  (ψ  χ)  (φ  χ)"
proof -
  have " 𝔐. 𝔐 prop (φ  ψ)  (ψ  χ)  (φ  χ)"
    by simp
  hence "  (φ  ψ)  (ψ  χ)  (φ  χ) "
    using propositional_semantics by blast
 thus ?thesis by simp
qed

lemma (in classical_logic) biconditional_transitivity_rule:
  " φ  ψ   ψ  χ   φ  χ"
  using modus_ponens biconditional_transitivity by blast

subsection ‹ Biconditional Weakening ›

lemma (in classical_logic) biconditional_weaken:
  assumes "Γ  φ  ψ"
  shows "Γ  φ = Γ  ψ"
  by (metis assms
            biconditional_left_elimination
            biconditional_right_elimination
            set_deduction_modus_ponens
            set_deduction_weaken)

lemma (in classical_logic) list_biconditional_weaken:
  assumes "Γ :⊢ φ  ψ"
  shows "Γ :⊢ φ = Γ :⊢ ψ"
  by (metis assms
            biconditional_left_elimination
            biconditional_right_elimination
            list_deduction_modus_ponens
            list_deduction_weaken)

lemma (in classical_logic) weak_biconditional_weaken:
  assumes " φ  ψ"
  shows " φ =  ψ"
  by (metis assms
            biconditional_left_elimination
            biconditional_right_elimination
            modus_ponens)

subsection ‹ Conjunction Identities ›

lemma (in classical_logic) conjunction_negation_identity:
  "  (φ  ψ)  (φ  ψ  )"
  by (metis Contraposition
            double_negation_converse
            modus_ponens
            biconditional_introduction
            conjunction_def
            negation_def)

lemma (in classical_logic) conjunction_set_deduction_equivalence [simp]:
  "Γ  φ  ψ = (Γ  φ  Γ  ψ)"
  by (metis set_deduction_weaken [where Γ="Γ"]
            set_deduction_modus_ponens [where Γ="Γ"]
            conjunction_introduction
            conjunction_left_elimination
            conjunction_right_elimination)

lemma (in classical_logic) conjunction_list_deduction_equivalence [simp]:
  "Γ :⊢ φ  ψ = (Γ :⊢ φ  Γ :⊢ ψ)"
  by (metis list_deduction_weaken [where Γ="Γ"]
            list_deduction_modus_ponens [where Γ="Γ"]
            conjunction_introduction
            conjunction_left_elimination
            conjunction_right_elimination)

lemma (in classical_logic) weak_conjunction_deduction_equivalence [simp]:
  " φ  ψ = ( φ   ψ)"
  by (metis conjunction_set_deduction_equivalence set_deduction_base_theory)

lemma (in classical_logic) conjunction_set_deduction_arbitrary_equivalence [simp]:
  "Γ   Φ = ( φ  set Φ. Γ  φ)"
  by (induct Φ, simp add: set_deduction_weaken, simp)

lemma (in classical_logic) conjunction_list_deduction_arbitrary_equivalence [simp]:
  "Γ :⊢  Φ = ( φ  set Φ. Γ :⊢ φ)"
  by (induct Φ, simp add: list_deduction_weaken, simp)

lemma (in classical_logic) weak_conjunction_deduction_arbitrary_equivalence [simp]:
  "  Φ = ( φ  set Φ.  φ)"
  by (induct Φ, simp+)

lemma (in classical_logic) conjunction_commutativity:
  " (ψ  φ)  (φ  ψ)"
  by (metis
        (full_types)
        modus_ponens
        biconditional_introduction
        conjunction_def
        flip_hypothetical_syllogism
        flip_implication)

lemma (in classical_logic) conjunction_associativity:
  " ((φ  ψ)  χ)  (φ  (ψ  χ))"
proof -
  have " 𝔐. 𝔐 prop ((φ  ψ)  χ)  (φ  (ψ  χ))"
    by simp
  hence "  ((φ  ψ)  χ)  (φ  (ψ  χ)) "
    using propositional_semantics by blast
  thus ?thesis by simp
qed

lemma (in classical_logic) arbitrary_conjunction_antitone:
  "set Φ  set Ψ    Ψ   Φ"
proof -
  have " Φ. set Φ  set Ψ    Ψ   Φ"
  proof (induct Ψ)
    case Nil
    then show ?case
      by (simp add: pseudo_scotus verum_def)
  next
    case (Cons ψ Ψ)
    {
      fix Φ
      assume "set Φ  set (ψ # Ψ)"
      have "  (ψ # Ψ)   Φ"
      proof (cases "ψ  set Φ")
        assume "ψ  set Φ"
                have " φ  set Φ.   Φ  (φ   (removeAll φ Φ))"
        proof (induct Φ)
          case Nil
          then show ?case by simp
        next
          case (Cons χ Φ)
          {
            fix φ
            assume "φ  set (χ # Φ)"
            have "  (χ # Φ)  (φ   (removeAll φ (χ # Φ)))"
            proof cases
              assume "φ  set Φ"
              hence "  Φ  (φ   (removeAll φ Φ))"
                using Cons.hyps φ  set Φ
                by auto
              moreover
              have " ( Φ  (φ   (removeAll φ Φ))) 
                      (χ   Φ)  (φ  χ   (removeAll φ Φ))"
              proof -
                have " 𝔐. 𝔐 prop
                        ( Φ  (φ   (removeAll φ Φ)))
                             (χ   Φ)
                                    (φ  χ   (removeAll φ Φ))"
                    by auto
                hence "  ( Φ  (φ   (removeAll φ Φ)))
                                (χ   Φ)
                                       (φ  χ   (removeAll φ Φ)) "
                  using propositional_semantics by blast
                thus ?thesis by simp
              qed
              ultimately have "  (χ # Φ)  (φ  χ   (removeAll φ Φ))"
                using modus_ponens by auto
              show ?thesis
              proof cases
                assume "φ = χ"
                moreover
                {
                  fix φ
                  have " (χ  φ)  (χ  χ  φ)"
                    unfolding conjunction_def
                    by (meson
                          axiom_s
                          double_negation
                          modus_ponens
                          flip_hypothetical_syllogism
                          flip_implication)
                } note tautology = this
                from   (χ # Φ)  (φ  χ   (removeAll φ Φ))
                     φ = χ
                have " (χ   (removeAll χ Φ))  (χ   Φ)"
                  unfolding biconditional_def
                  by (simp, metis tautology hypothetical_syllogism modus_ponens)
                moreover
                from   (χ # Φ)  (φ  χ   (removeAll φ Φ))
                     φ = χ
                have " (χ   Φ)  (χ   (removeAll χ Φ))"
                  unfolding biconditional_def
                  by (simp,
                      metis conjunction_right_elimination
                            hypothetical_syllogism
                            modus_ponens)
                ultimately show ?thesis
                  unfolding biconditional_def
                  by simp
              next
                assume "φ  χ"
                then show ?thesis
                  using   (χ # Φ)  (φ  χ   (removeAll φ Φ))
                  by simp
              qed
            next
              assume "φ  set Φ"
              hence "φ = χ" "χ  set Φ"
                using φ  set (χ # Φ) by auto
              then show ?thesis
                using biconditional_reflection
                by simp
            qed
          }
          thus ?case by blast
        qed
        hence " (ψ   (removeAll ψ Φ))   Φ"
          using modus_ponens biconditional_right_elimination ψ  set Φ
          by blast
        moreover
        from ψ  set Φ set Φ  set (ψ # Ψ) Cons.hyps
        have "  Ψ   (removeAll ψ Φ)"
          by (simp add: subset_insert_iff insert_absorb)
        hence " (ψ   Ψ)  (ψ   (removeAll ψ Φ))"
          unfolding conjunction_def
          using
            modus_ponens
            hypothetical_syllogism
            flip_hypothetical_syllogism
          by meson
        ultimately have " (ψ   Ψ)   Φ"
          using modus_ponens hypothetical_syllogism
          by blast
        thus ?thesis
          by simp
      next
        assume "ψ  set Φ"
        hence "  Ψ   Φ"
          using Cons.hyps set Φ  set (ψ # Ψ)
          by auto
        hence " (ψ   Ψ)   Φ"
          unfolding conjunction_def
          by (metis
                modus_ponens
                conjunction_def
                conjunction_right_elimination
                hypothetical_syllogism)
        thus ?thesis
          by simp
      qed
    }
    thus ?case by blast
  qed
  thus "set Φ  set Ψ    Ψ   Φ" by blast
qed

lemma (in classical_logic) arbitrary_conjunction_remdups:
  " ( Φ)   (remdups Φ)"
  by (simp add: arbitrary_conjunction_antitone biconditional_def)

lemma (in classical_logic) curry_uncurry:
  " (φ  ψ  χ)  ((φ  ψ)  χ)"
proof -
  have " 𝔐. 𝔐 prop (φ  ψ  χ)  ((φ  ψ)  χ)"
      by auto
  hence "  (φ  ψ  χ)  ((φ  ψ)  χ) "
    using propositional_semantics by blast
  thus ?thesis by simp
qed

lemma (in classical_logic) list_curry_uncurry:
  " (Φ :→ χ)  ( Φ  χ)"
proof (induct Φ)
  case Nil
  have " χ  (  χ)"
    unfolding biconditional_def
              conjunction_def
              verum_def
    using
      axiom_k
      ex_falso_quodlibet
      modus_ponens
      conjunction_def
      excluded_middle_elimination
      set_deduction_base_theory
      conjunction_set_deduction_equivalence
    by metis
  with Nil show ?case
    by simp
next
  case (Cons φ Φ)
  have " ((φ # Φ) :→ χ)  (φ  (Φ :→ χ))"
    by (simp add: biconditional_reflection)
  with Cons have " ((φ # Φ) :→ χ)  (φ   Φ  χ)"
    by (metis modus_ponens
              biconditional_def
              hypothetical_syllogism
              list_implication.simps(2)
              weak_conjunction_deduction_equivalence)
  with curry_uncurry [where ="φ"  and =" Φ" and ="χ"]
  show ?case
    unfolding biconditional_def
    by (simp, metis modus_ponens hypothetical_syllogism)
qed

subsection ‹ Disjunction Identities ›

lemma (in classical_logic) bivalence:
  "  φ  φ"
  by (simp add: double_negation disjunction_def negation_def)

lemma (in classical_logic) implication_equivalence:
  " ( φ  ψ)  (φ  ψ)"
  by (metis double_negation_converse
            modus_ponens
            biconditional_introduction
            bivalence
            disjunction_def
            flip_hypothetical_syllogism
            negation_def)

lemma (in classical_logic) disjunction_commutativity:
  " (ψ  φ)  (φ  ψ)"
  by (meson modus_ponens
            biconditional_introduction
            disjunction_elimination
            disjunction_left_introduction
            disjunction_right_introduction)

lemma (in classical_logic) disjunction_associativity:
  " ((φ  ψ)  χ)  (φ  (ψ  χ))"
proof -
  have " 𝔐. 𝔐 prop ((φ  ψ)  χ)  (φ  (ψ  χ))"
    by simp
  hence "  ((φ  ψ)  χ)  (φ  (ψ  χ)) "
    using propositional_semantics by blast
  thus ?thesis by simp
qed

lemma (in classical_logic) arbitrary_disjunction_monotone:
  "set Φ  set Ψ    Φ   Ψ"
proof -
  have " Φ. set Φ  set Ψ    Φ   Ψ"
  proof (induct Ψ)
    case Nil
    then show ?case using verum_def verum_tautology by auto
  next
    case (Cons ψ Ψ)
    {
      fix Φ
      assume "set Φ  set (ψ # Ψ)"
      have "  Φ   (ψ # Ψ)"
      proof cases
        assume "ψ  set Φ"
        have " φ  set Φ.   Φ  (φ   (removeAll φ Φ))"
        proof (induct Φ)
          case Nil
          then show ?case by simp
        next
          case (Cons χ Φ)
          {
            fix φ
            assume "φ  set (χ # Φ)"
            have "  (χ # Φ)  (φ   (removeAll φ (χ # Φ)))"
            proof cases
              assume "φ  set Φ"
              hence "  Φ  (φ   (removeAll φ Φ))"
                using Cons.hyps φ  set Φ
                by auto
              moreover
              have " ( Φ  (φ   (removeAll φ Φ))) 
                      (χ   Φ)  (φ  χ   (removeAll φ Φ))"
              proof -
                have " 𝔐. 𝔐 prop
                        ( Φ  (φ   (removeAll φ Φ)))
                          (χ   Φ)
                               (φ  χ   (removeAll φ Φ))"
                    by auto
                  hence "  ( Φ  (φ   (removeAll φ Φ)))
                              (χ   Φ)
                                  (φ  χ   (removeAll φ Φ)) "
                    using propositional_semantics by blast
                  thus ?thesis by simp
              qed
              ultimately have "  (χ # Φ)  (φ  χ   (removeAll φ Φ))"
                using modus_ponens by auto
              show ?thesis
              proof cases
                assume "φ = χ"
                then show ?thesis
                  using   (χ # Φ)  (φ  χ   (removeAll φ Φ))
                  unfolding biconditional_def
                  by (simp add: disjunction_def,
                      meson
                        axiom_k
                        modus_ponens
                        flip_hypothetical_syllogism
                        implication_absorption)
              next
                assume "φ  χ"
                then show ?thesis
                  using   (χ # Φ)  (φ  χ   (removeAll φ Φ))
                  by simp
              qed
            next
              assume "φ  set Φ"
              hence "φ = χ" "χ  set Φ"
                using φ  set (χ # Φ) by auto
              then show ?thesis
                using biconditional_reflection
                by simp
            qed
          }
          thus ?case by blast
        qed
        hence "  Φ  (ψ   (removeAll ψ Φ))"
          using modus_ponens biconditional_left_elimination ψ  set Φ
          by blast
        moreover
        from ψ  set Φ set Φ  set (ψ # Ψ) Cons.hyps
        have "  (removeAll ψ Φ)   Ψ"
          by (simp add: subset_insert_iff insert_absorb)
        hence " (ψ   (removeAll ψ Φ))   (ψ # Ψ)"
          using
            modus_ponens
            disjunction_def
            hypothetical_syllogism
          by fastforce
        ultimately show ?thesis
          by (simp, metis modus_ponens hypothetical_syllogism)
      next
        assume "ψ  set Φ"
        hence "  Φ   Ψ"
          using Cons.hyps set Φ  set (ψ # Ψ)
          by auto
        then show ?thesis
          by (metis
                arbitrary_disjunction.simps(2)
                disjunction_def
                list_deduction_def
                list_deduction_theorem
                list_deduction_weaken
                list_implication.simps(1)
                list_implication.simps(2))
      qed
    }
    then show ?case by blast
  qed
  thus "set Φ  set Ψ    Φ   Ψ" by blast
qed

lemma (in classical_logic) arbitrary_disjunction_remdups:
  " ( Φ)   (remdups Φ)"
  by (simp add: arbitrary_disjunction_monotone biconditional_def)

lemma (in classical_logic) arbitrary_disjunction_exclusion_MCS:
  assumes "MCS Ω"
  shows " Ψ  Ω   ψ  set Ψ. ψ  Ω"
proof (induct Ψ)
  case Nil
  then show ?case
    using
      assms
      formula_consistent_def
      formula_maximally_consistent_set_def_def
      maximally_consistent_set_def
      set_deduction_reflection
    by (simp, blast)
next
  case (Cons ψ Ψ)
  have " (ψ # Ψ)  Ω = (ψ  Ω   Ψ  Ω)"
    by (simp add: disjunction_def,
        meson
          assms
          formula_consistent_def
          formula_maximally_consistent_set_def_def
          formula_maximally_consistent_set_def_implication
          maximally_consistent_set_def
          set_deduction_reflection)
  thus ?case using Cons.hyps by simp
qed

lemma (in classical_logic) contra_list_curry_uncurry:
  " (Φ :→ χ)  ( χ   ( Φ))"
proof (induct Φ)
  case Nil
  then show ?case
    by (simp,
          metis
            biconditional_introduction
            bivalence
            disjunction_def
            double_negation_converse
            modus_ponens
            negation_def)
next
  case (Cons φ Φ)
  hence " ( Φ  χ)  ( χ   ( Φ))"
    by (metis
          biconditional_symmetry_rule
          biconditional_transitivity_rule
          list_curry_uncurry)
  have " ( (φ # Φ)  χ)  ( χ   ( (φ # Φ)))"
  proof -
    have " ( Φ  χ)  ( χ   ( Φ))
              ((φ   Φ)  χ)  ( χ  ( φ   ( Φ)))"
    proof -
      have
       " 𝔐. 𝔐 prop
         ( Φ  χ)  ( χ   ( Φ))
              ((φ   Φ)  χ)  ( χ  ( φ   ( Φ)))"
        by auto
      hence
        "  ( Φ  χ)  ( χ   ( Φ))
              ((φ   Φ)  χ)  ( χ  ( φ   ( Φ))) "
        using propositional_semantics by blast
      thus ?thesis by simp
    qed
    thus ?thesis
      using  ( Φ  χ)  ( χ   ( Φ)) modus_ponens by auto
  qed
  then show ?case
    using biconditional_transitivity_rule list_curry_uncurry by blast
qed

subsection ‹ Monotony of Conjunction and Disjunction ›

lemma (in classical_logic) conjunction_monotonic_identity:
  " (φ  ψ)  (φ  χ)  (ψ  χ)"
  unfolding conjunction_def
  using modus_ponens
        flip_hypothetical_syllogism
  by blast

lemma (in classical_logic) conjunction_monotonic:
  assumes " φ  ψ"
  shows " (φ  χ)  (ψ  χ)"
  using assms
        modus_ponens
        conjunction_monotonic_identity
  by blast

lemma (in classical_logic) disjunction_monotonic_identity:
  " (φ  ψ)  (φ  χ)  (ψ  χ)"
  unfolding disjunction_def
  using modus_ponens
        flip_hypothetical_syllogism
  by blast

lemma (in classical_logic) disjunction_monotonic:
  assumes " φ  ψ"
  shows " (φ  χ)  (ψ  χ)"
  using assms
        modus_ponens
        disjunction_monotonic_identity
  by blast

subsection ‹ Distribution Identities ›

lemma (in classical_logic) conjunction_distribution:
  " ((ψ  χ)  φ)  ((ψ  φ)  (χ  φ))"
proof -
  have " 𝔐. 𝔐 prop ((ψ  χ)  φ)  ((ψ  φ)  (χ  φ))"
      by auto
  hence "  ((ψ  χ)  φ)  ((ψ  φ)  (χ  φ)) "
    using propositional_semantics by blast
  thus ?thesis by simp
qed

lemma (in classical_logic) subtraction_distribution:
  " ((ψ  χ)  φ)  ((ψ  φ)  (χ  φ))"
  by (simp add: conjunction_distribution subtraction_def)

lemma (in classical_logic) conjunction_arbitrary_distribution:
  " ( Ψ  φ)   [ψ  φ. ψ  Ψ]"
proof (induct Ψ)
  case Nil
  then show ?case
    by (simp add: ex_falso_quodlibet
                  biconditional_def
                  conjunction_left_elimination)
next
  case (Cons ψ Ψ)
  have " ( (ψ # Ψ)  φ)  ((ψ  φ)  (( Ψ)  φ))"
    using conjunction_distribution by auto
  moreover
  from Cons have
    " ((ψ  φ)  (( Ψ)  φ))  ((ψ  φ)  ( [ψ  φ. ψ  Ψ]))"
    unfolding disjunction_def biconditional_def
    by (simp, meson modus_ponens hypothetical_syllogism)
  ultimately show ?case
    by (simp, metis biconditional_transitivity_rule)
qed

lemma (in classical_logic) subtraction_arbitrary_distribution:
  " ( Ψ  φ)   [ψ  φ. ψ  Ψ]"
  by (simp add: conjunction_arbitrary_distribution subtraction_def)

lemma (in classical_logic) disjunction_distribution:
  " (φ  (ψ  χ))  ((φ  ψ)  (φ  χ))"
proof -
  have " 𝔐. 𝔐 prop (φ  (ψ  χ))  ((φ  ψ)  (φ  χ))"
      by auto
  hence "  (φ  (ψ  χ))  ((φ  ψ)  (φ  χ)) "
    using propositional_semantics by blast
  thus ?thesis by simp
qed

lemma (in classical_logic) implication_distribution:
  " (φ  (ψ  χ))  ((φ  ψ)  (φ  χ))"
proof -
  have " 𝔐. 𝔐 prop (φ  (ψ  χ))  ((φ  ψ)  (φ  χ))"
      by auto
  hence "  (φ  (ψ  χ))  ((φ  ψ)  (φ  χ)) "
    using propositional_semantics by blast
  thus ?thesis by simp
qed

lemma (in classical_logic) list_implication_distribution:
  " (Φ :→ (ψ  χ))  ((Φ :→ ψ)  (Φ :→ χ))"
proof (induct Φ)
  case Nil
  then show ?case
    by (simp add: biconditional_reflection)
next
  case (Cons φ Φ)
  hence "  (φ # Φ) :→ (ψ  χ)  (φ  (Φ :→ ψ  Φ :→ χ))"
    by (metis
          modus_ponens
          biconditional_def
          hypothetical_syllogism
          list_implication.simps(2)
          weak_conjunction_deduction_equivalence)
  moreover
  have " (φ  (Φ :→ ψ  Φ :→ χ))  (((φ # Φ) :→ ψ)  ((φ # Φ) :→ χ))"
    using implication_distribution by auto
  ultimately show ?case
    by (simp, metis biconditional_transitivity_rule)
qed

lemma (in classical_logic) biconditional_conjunction_weaken:
  " (α  β)  ((γ  α)  (γ  β))"
proof -
  have " 𝔐. 𝔐 prop (α  β)  ((γ  α)  (γ  β))"
      by auto
  hence "  (α  β)  ((γ  α)  (γ  β)) "
    using propositional_semantics by blast
  thus ?thesis by simp
qed

lemma (in classical_logic) biconditional_conjunction_weaken_rule:
  " (α  β)   (γ  α)  (γ  β)"
  using modus_ponens biconditional_conjunction_weaken by blast

lemma (in classical_logic) disjunction_arbitrary_distribution:
  " (φ   Ψ)   [φ  ψ. ψ  Ψ]"
proof (induct Ψ)
  case Nil
  then show ?case
    unfolding disjunction_def biconditional_def
    using axiom_k modus_ponens verum_tautology
    by (simp, blast)
next
  case (Cons ψ Ψ)
  have " (φ   (ψ # Ψ))  ((φ  ψ)  (φ   Ψ))"
    by (simp add: disjunction_distribution)
  moreover
  from biconditional_conjunction_weaken_rule
       Cons
  have "  ((φ  ψ)  φ   Ψ)   (map (λ χ . φ  χ) (ψ # Ψ))"
    by simp
  ultimately show ?case
    by (metis biconditional_transitivity_rule)
qed

lemma (in classical_logic) list_implication_arbitrary_distribution:
  " (Φ :→  Ψ)   [Φ :→ ψ. ψ  Ψ]"
proof (induct Ψ)
  case Nil
  then show ?case
    by (simp add: biconditional_def,
        meson
          axiom_k
          modus_ponens
          list_implication_axiom_k
          verum_tautology)
next
  case (Cons ψ Ψ)
  have " Φ :→  (ψ # Ψ)  (Φ :→ ψ  Φ :→  Ψ)"
    using list_implication_distribution
    by fastforce
  moreover
  from biconditional_conjunction_weaken_rule
       Cons
  have " (Φ :→ ψ  Φ :→  Ψ)   [Φ :→ ψ. ψ  (ψ # Ψ)]"
    by simp
  ultimately show ?case
    by (metis biconditional_transitivity_rule)
qed

lemma (in classical_logic) implication_arbitrary_distribution:
  " (φ   Ψ)   [φ  ψ. ψ  Ψ]"
  using list_implication_arbitrary_distribution [where ="[φ]"]
  by simp

subsection ‹ Negation ›

lemma (in classical_logic) double_negation_biconditional:
  "  ( φ)  φ"
  unfolding biconditional_def negation_def
  by (simp add: double_negation double_negation_converse)

lemma (in classical_logic) double_negation_elimination [simp]:
  "Γ   ( φ) = Γ  φ"
  using
    set_deduction_weaken
    biconditional_weaken
    double_negation_biconditional
  by metis

lemma (in classical_logic) alt_double_negation_elimination [simp]:
  "Γ  (φ  )    Γ  φ"
  using double_negation_elimination
  unfolding negation_def
  by auto

lemma (in classical_logic) base_double_negation_elimination [simp]:
  "  ( φ) =  φ"
  by (metis double_negation_elimination set_deduction_base_theory)

lemma (in classical_logic) alt_base_double_negation_elimination [simp]:
  " (φ  )     φ"
  using base_double_negation_elimination
  unfolding negation_def
  by auto

subsection ‹ Mutual Exclusion Identities ›

lemma (in classical_logic) exclusion_contrapositive_equivalence:
  " (φ  γ)   (φ   γ)"
proof -
  have " 𝔐. 𝔐 prop (φ  γ)   (φ   γ)"
    by auto
  hence "  (φ  γ)   (φ   γ) "
    using propositional_semantics by blast
  thus ?thesis by simp
qed

lemma (in classical_logic) disjuction_exclusion_equivalence:
  "Γ   (ψ   Φ)   φ  set Φ. Γ   (ψ  φ)"
proof (induct Φ)
  case Nil
  then show ?case
    by (simp add:
          conjunction_right_elimination
          negation_def
          set_deduction_weaken)
next
  case (Cons φ Φ)
  have "  (ψ   (φ # Φ))   (ψ  (φ   Φ))"
    by (simp add: biconditional_reflection)
  moreover have "  (ψ  (φ   Φ))  ( (ψ  φ)   (ψ   Φ))"
  proof -
    have " 𝔐. 𝔐 prop  (ψ  (φ   Φ))
                          ( (ψ  φ)   (ψ   Φ))"
      by auto
    hence "   (ψ  (φ   Φ))
                ( (ψ  φ)   (ψ   Φ)) "
      using propositional_semantics by blast
    thus ?thesis by simp
  qed
  ultimately
  have "  (ψ   (φ # Φ))  ( (ψ  φ)   (ψ   Φ))"
    by simp
  hence "Γ   (ψ   (φ # Φ)) = (Γ   (ψ  φ)
            (φset Φ. Γ   (ψ  φ)))"
    using set_deduction_weaken [where Γ="Γ"]
          conjunction_set_deduction_equivalence [where Γ="Γ"]
          Cons.hyps
          biconditional_def
          set_deduction_modus_ponens
    by metis
  thus "Γ   (ψ   (φ # Φ)) = (φset (φ # Φ). Γ   (ψ  φ))"
    by simp
qed

lemma (in classical_logic) exclusive_elimination1:
  assumes "Γ   Φ"
  shows " φ  set Φ.  ψ  set Φ. (φ  ψ)  Γ   (φ  ψ)"
  using assms
proof (induct Φ)
  case Nil
  thus ?case by auto
next
  case (Cons χ Φ)
  assume "Γ   (χ # Φ)"
  hence "Γ   Φ" by simp
  hence "φset Φ. ψset Φ. φ  ψ  Γ   (φ  ψ)"
    using Cons.hyps by blast
  moreover have "Γ   (χ   Φ)"
    using Γ   (χ # Φ) conjunction_set_deduction_equivalence by auto
  hence " φ  set Φ. Γ   (χ  φ)"
    using disjuction_exclusion_equivalence by auto
  moreover {
    fix φ
    have "  (χ  φ)   (φ  χ)"
      unfolding negation_def
                conjunction_def
      using modus_ponens flip_hypothetical_syllogism flip_implication by blast
  }
  with  φ  set Φ. Γ   (χ  φ) have " φ  set Φ. Γ   (φ  χ)"
    using set_deduction_weaken [where Γ="Γ"]
          set_deduction_modus_ponens [where Γ="Γ"]
    by blast
  ultimately
  show "φ  set (χ # Φ). ψ  set (χ # Φ). φ  ψ  Γ   (φ  ψ)"
    by simp
qed

lemma (in classical_logic) exclusive_elimination2:
  assumes "Γ   Φ"
  shows " φ  duplicates Φ. Γ   φ"
  using assms
proof (induct Φ)
  case Nil
  then show ?case by simp
next
  case (Cons φ Φ)
  assume "Γ   (φ # Φ)"
  hence "Γ   Φ" by simp
  hence "φduplicates Φ. Γ   φ" using Cons.hyps by auto
  show ?case
  proof cases
    assume "φ  set Φ"
    moreover {
      fix φ ψ χ
      have "  (φ  (ψ  χ))  ( (φ  ψ)   (φ  χ))"
      proof -
        have " 𝔐. 𝔐 prop  (φ  (ψ  χ))
                        ( (φ  ψ)   (φ  χ))"
          by auto
        hence "   (φ  (ψ  χ))  ( (φ  ψ)   (φ  χ)) "
          using propositional_semantics by blast
        thus ?thesis by simp
      qed
      hence "Γ   (φ  (ψ  χ))  Γ   (φ  ψ)   (φ  χ)"
        using set_deduction_weaken
              biconditional_weaken by presburger
    }
    moreover
    have "  (φ  φ)   φ"
    proof -
      have " 𝔐. 𝔐 prop  (φ  φ)   φ"
        by auto
      hence "   (φ  φ)   φ "
        using propositional_semantics by blast
      thus ?thesis by simp
    qed
    hence "Γ   (φ  φ)  Γ   φ"
      using set_deduction_weaken
            biconditional_weaken by presburger
    moreover have "Γ   (φ   Φ)" using Γ   (φ # Φ) by simp
    ultimately have "Γ   φ" by (induct Φ, simp, simp, blast)
    thus ?thesis using φ  set Φ φduplicates Φ. Γ   φ by simp
  next
    assume "φ  set Φ"
    hence "duplicates (φ # Φ) = duplicates Φ" by simp
    then show ?thesis using φduplicates Φ. Γ   φ
      by auto
  qed
qed

lemma (in classical_logic) exclusive_equivalence:
   "Γ   Φ =
      ((φduplicates Φ. Γ   φ) 
         ( φ  set Φ.  ψ  set Φ. (φ  ψ)  Γ   (φ  ψ)))"
proof -
  {
    assume "φduplicates Φ. Γ   φ"
           " φ  set Φ.  ψ  set Φ. (φ  ψ)  Γ   (φ  ψ)"
    hence "Γ   Φ"
    proof (induct Φ)
      case Nil
      then show ?case
        by (simp add: set_deduction_weaken)
    next
      case (Cons φ Φ)
      assume A: "φduplicates (φ # Φ). Γ   φ"
         and B: "χset (φ # Φ). ψset (φ # Φ). χ  ψ  Γ   (χ  ψ)"
      hence C: "Γ   Φ" using Cons.hyps by simp
      then show ?case
      proof cases
        assume "φ  duplicates (φ # Φ)"
        moreover from this have "Γ   φ" using A by auto
        moreover have "duplicates Φ  set Φ" by (induct Φ, simp, auto)
        ultimately have "φ  set Φ" by (metis duplicates.simps(2) subsetCE)
        hence "  φ  (φ   Φ)"
        proof (induct Φ)
          case Nil
          then show ?case by simp
        next
          case (Cons ψ Φ)
          assume "φ  set (ψ # Φ)"
          then show "  φ   (φ   (ψ # Φ))"
          proof -
            {
              assume "φ = ψ"
              hence ?thesis
              proof -
                have " 𝔐. 𝔐 prop  φ   (φ  (ψ   Φ))"
                  using φ = ψ by auto
                hence "   φ   (φ  (ψ   Φ)) "
                  using propositional_semantics by blast
                thus ?thesis by simp
              qed
            }
            moreover
            {
              assume "φ  ψ"
              hence "φ  set Φ" using φ  set (ψ # Φ) by auto
              hence "  φ   (φ   Φ)" using Cons.hyps by auto
              moreover have " ( φ   (φ   Φ))
                                    ( φ   (φ  (ψ   Φ)))"
              proof -
                have " 𝔐. 𝔐 prop ( φ   (φ   Φ)) 
                                     ( φ   (φ  (ψ   Φ)))"
                  by auto
                hence "  ( φ   (φ   Φ))
                            ( φ   (φ  (ψ   Φ))) "
                  using propositional_semantics by blast
                thus ?thesis by simp
              qed
              ultimately have ?thesis using modus_ponens by simp
            }
            ultimately show ?thesis by auto
          qed
        qed
        with Γ   φ have "Γ  (φ   Φ)"
          using biconditional_weaken set_deduction_weaken by blast
        with Γ   Φ show ?thesis by simp
      next
        assume "φ  duplicates (φ # Φ)"
        hence "φ  set Φ" by auto
        with B have "ψset Φ. Γ   (φ  ψ)" by (simp, metis)
        hence "Γ   (φ   Φ)"
          by (simp add: disjuction_exclusion_equivalence)
        with Γ   Φ show ?thesis by simp
      qed
    qed
  }
  thus ?thesis
    by (metis exclusive_elimination1 exclusive_elimination2)
qed

subsection ‹ Miscellaneous Disjunctive Normal Form Identities ›

lemma (in classical_logic) map_negation_list_implication:
  " (( Φ) :→ ( φ))  (φ   Φ)"
proof (induct Φ)
  case Nil
  then show ?case
    unfolding
      biconditional_def
      map_negation_def
      negation_def
    using
      conjunction_introduction
      modus_ponens
      trivial_implication
    by simp
next
  case (Cons ψ Φ)
  have " ( Φ :→  φ  (φ   Φ))
           ( ψ   Φ :→  φ)  (φ  (ψ   Φ))"
  proof -
    have "𝔐. 𝔐 prop ( Φ :→  φ  (φ   Φ)) 
                        ( ψ   Φ :→  φ)  (φ  (ψ   Φ))"
      by fastforce
    hence "  ( Φ :→  φ  (φ   Φ)) 
               ( ψ   Φ :→  φ)  (φ  (ψ   Φ)) "
      using propositional_semantics by blast
    thus ?thesis
      by simp
  qed
  with Cons show ?case
    by (metis
          map_negation_def
          list.simps(9)
          arbitrary_disjunction.simps(2)
          modus_ponens
          list_implication.simps(2))
qed


lemma (in classical_logic) conj_dnf_distribute:
  "  (map (  (λ φs. φ # φs)) Λ)  (φ   (map  Λ))"
proof(induct Λ)
  case Nil
  have "   (φ  )"
  proof -
    let  = "  (φ  )"
    have "𝔐. 𝔐 prop " by fastforce
    hence "   " using propositional_semantics by blast
    thus ?thesis by simp
  qed
  then show ?case by simp
next
  case (Cons Ψ Λ)
  assume "  (map (  (λ φs. φ # φs)) Λ)  (φ   (map  Λ))"
    (is " ?A  (φ  ?B)")
  moreover
  have " (?A  (φ  ?B))  (((φ   Ψ)  ?A)  (φ   Ψ  ?B))"
  proof -
    let  = "(?A  (φ  ?B)) 
               (((φ   Ψ)  ?A)  (φ   Ψ  ?B))"
    have "𝔐. 𝔐 prop " by fastforce
    hence "   " using propositional_semantics by blast
    thus ?thesis
      by simp
  qed
  ultimately have " ((φ   Ψ)  ?A)  (φ   Ψ  ?B)"
    using modus_ponens
    by blast
  moreover
  have "map (  (λ φs. φ # φs)) Λ = map (λΨ. φ   Ψ) Λ" by simp
  ultimately show ?case by simp
qed

lemma (in classical_logic) append_dnf_distribute:
  "  (map (  (λ Ψ. Φ @ Ψ)) Λ)  ( Φ   (map  Λ))"
proof(induct Φ)
  case Nil
  have "  (map  Λ)  (   (map  Λ))"
    (is " ?A  (  ?A)")
  proof -
    let  = "?A  ((  )  ?A)"
    have "𝔐. 𝔐 prop " by simp
    hence "   " using propositional_semantics by blast
    thus ?thesis
      unfolding verum_def
      by simp
  qed
  then show ?case by simp
next
  case (Cons φ Φ)
  have "  (map (  (@) Φ) Λ)  ( Φ   (map  Λ))
       =   (map  (map ((@) Φ) Λ))  ( Φ   (map  Λ))"
    by simp
  with Cons have
    "  (map  (map (λ Ψ. Φ @ Ψ) Λ))  ( Φ   (map  Λ))"
    (is "  (map  ?A)  (?B  ?C)")
    by meson
  moreover have "  (map  ?A)  (?B  ?C)
                 ( (map (  (λ φs. φ # φs)) ?A)  (φ   (map  ?A)))
                  (map (  (λ φs. φ # φs)) ?A)  ((φ  ?B)  ?C)"
  proof -
    let  = " (map  ?A)  (?B  ?C)
            ( (map (  (λ φs. φ # φs)) ?A)  (φ   (map  ?A)))
             (map (  (λ φs. φ # φs)) ?A)  ((φ  ?B)  ?C)"
    have "𝔐. 𝔐 prop " by simp
    hence "   " using propositional_semantics by blast
    thus ?thesis
      by simp
  qed
  ultimately have "  (map (  (λ φs. φ # φs)) ?A)  ((φ  ?B)  ?C)"
    using modus_ponens conj_dnf_distribute
    by blast
  moreover
  have "  (@) (φ # Φ) =   (#) φ  (@) Φ" by auto
  hence
    "  (map (  (@) (φ # Φ)) Λ)  ( (φ # Φ)  ?C)
   =   (map (  (#) φ) ?A)  ((φ  ?B)  ?C)"
    by simp
  ultimately show ?case by meson
qed

notation FuncSet.funcset (infixr "" 60)

end