数理逻辑03 形式化证明

\(\newcommand{\I}{\mathfrak{I}}\newcommand{\A}{\mathfrak{A}}\)通过一阶逻辑,我们能够形式化许多“数学命题”。接下来我们要讨论如何形式化“数学证明”。“数学证明”是从一些“前提”出发,根据“推导规则”得出“结论”的过程。其中,“前提”有两种,一种是公认的数学事实(公理),一种是在当前证明中假设已经成立的数学命题。事实上,我们可以不用考虑后一种“前提”,例如当我们要基于公理和前提\(A\)证明结论\(B\)时,我们可以等价地认为我是在基于公理证明结论\(A\to B\),只要我们能给出一套恰当的“推导规则”使得这二者是等价的。“推导规则”是一套由已知成立命题给出一个新的成立的命题的演算法则。即便我们都采用一阶逻辑作为描述数学命题的语言,基于此也可以提出多种“推导规则集合”。每一套“推导规则集合”就构成了一套“一阶逻辑证明系统”。最常用的一阶逻辑证明系统有:希尔伯特系统(Hilbert system),自然演绎法(Natural Deduction),相继式演算(Sequent Calculus)。其中,希尔伯特系统是最简单的证明系统,它只引入了极少量的推导规则,这虽然降低了分析的难度,但使得证明的形式化非常冗长;自然演绎法是更接近数学实践的证明系统,但是却增加了分析的难度;相继式演算在自然演绎法的基础上发展而来,重构了部分规则,从而降低了分析的难度。本文把相继式演算作为证明系统,研究一阶逻辑作为命题语言下的形式化证明。

相继式演算

相继式演算基于以下对于“数学证明”的观察:一个数学证明可以看作有限个步骤。每个步骤是由一个“已知的命题集合”根据“证明规则”导出一个“新的已知命题”的过程。在通过一个证明步骤得到了一个新命题以后,这个新命题可以作为新的已知的命题,在下一个步骤中当作已知命题使用。如果需要,我们也可以剔除一些不需要的已知命题。有时,我们会用到反证法:把一个命题\(A\)的否定\(\neg A\)暂时加入已知命题集合\(\Phi\),然后同时推出某个命题\(B\)以及它的否定\(\neg B\),那么可以认为\(\Phi\)能推出\(A\)

我们总结发现,每个证明步骤都是由若干个称为前件(antecedent)的命题得到一个后件(succedent),这个过程可以写作一个formula的序列(sequent) \(\varphi_1\varphi_2\cdots \varphi_n \ \varphi\),其中\(\varphi_i\)都是前件,\(\varphi\)是后件。假如\(\varphi_1\cdots \varphi_n\)恰好就是公理集合\(\Phi\)中的所有公理,\(\varphi\)是要证的命题,那么序列\(\varphi_1\varphi_2\cdots \varphi_n \ \varphi\)就是证明的目标:一个证明就是从某个已知成立的序列(例如\(\varphi_1\cdots \varphi_n \ \varphi_1\))出发做“序列的变换”得到\(\varphi_1\varphi_2\cdots \varphi_n \ \varphi\)。这个序列的变换过程就是一个用相继式演算的方式表示的形式化证明。

我们像算数中的“列竖式”一样用横线来表示一条演算规则。用\(\Gamma\)表示有限的一列formula \(\psi_1\psi_2\cdots \psi_k\)\(\begin{array}{aligned} & \Gamma & \varphi\\ \hline & \Gamma' & \psi &\\ \end{array}\)表示序列\(\Gamma \ \varphi\)可以变换为\(\Gamma' \ \psi\)。对于每一条演算规则,我们都可以用语义后承关系验证其正确性(soundness):如果\(\Gamma \models \varphi\)成立总是意味着\(\Gamma'\models \psi\)成立,就说明这条演算规则是正确、可靠的(“总是意味着”的意思是,如果\(\Gamma \models \varphi\)在数学事实上成立,也即对于任何解释\(\I\)都有“\(\I(\Gamma)\)在数学事实上成立意味着\(\I(\varphi)\)在数学事实上成立,那么\(\Gamma'\models \psi\)一定也在数学事实上成立”。再次强调,数学事实是不依赖于任何文字描述的客观实体)。

下面我们逐一定义相继式演算中可以使用的演算规则,共十条,并验证每条规则的正确性:(由功能完全性,我们依然只需考虑\(\neg,\lor,\exists\)这三个逻辑符号)

  1. \(\begin{array}{aligned} \\ \hline & \Gamma & \varphi &\\ \end{array} \text{ if } \varphi \in \Gamma \text{ (Assumption Rule)}\),这个规则允许我们把某个前件作为后件。这可以作为的起点。正确性:当\(\varphi\in \Gamma\)时,对任意\(\I\),只要\(\I(\Gamma)=true\),那么\(\I(\varphi)=true\),所以\(\Gamma\models \varphi\)成立;
  2. \(\begin{array}{aligned} \\ \hline & t\equiv t &\\ \end{array}\text{ (Reflexivity)}\),等式的自反性恒成立。这也可以作为形式化证明的起点。正确性:对于任意\(\I\)\(\I(t)=\I(t)\)
  3. \(\begin{array}{aligned} & \Gamma & \varphi\\ \hline & \Gamma' & \varphi &\\ \end{array}\)\(\text{ if }\) \(\Gamma \subseteq \Gamma'\) \(\text{ (Antecedent Rule)}\),这个规则会允许我们可以添加任意多个新的前件或改变已有的各个前件的顺序。正确性:对于任意\(\I\),如果\(\I(\Gamma')=true\),要证\(\I(\varphi)=true\)。因为\(\Gamma \subseteq \Gamma'\),所以\(\I(\Gamma)=true\)。而已知\(\Gamma\models \varphi\),所以\(\I(\Gamma)=true\)意味着\(\I(\varphi)=true\)。综上,对任意\(\I\)只要\(\I(\Gamma')=true\)就有\(\I(\varphi)=true\),所以\(\Gamma'\models \varphi\)
  4. \(\begin{array}{aligned} & \Gamma & \psi&\varphi\\ & \Gamma & \neg\psi&\varphi\\ \hline & \Gamma & &\varphi &\\ \end{array} \text{ (Proof by Case)}\),这个规则允许我们做分类讨论。正确性:对于任意\(\I\),如果\(\I(\Gamma)=true\),此时从数学事实上\(\I(\psi)=true\)\(\I(\neg\psi)=true\)只能恰好有一个成立。假如是前者成立,那么\(\I(\Gamma\cup\{\psi\})=true\),那么由第一行的sequent得到\(\I(\varphi)=true\);如果是后者成立,那么由第二行的sequent得到\(\I(\varphi)=true\)。综上,对于任意\(\I\),只要\(\I(\Gamma)=true\)就有\(\I(\varphi)=true\)。所以\(\Gamma\models \varphi\)
  5. \(\begin{array}{aligned} & \Gamma & \neg\varphi&\psi\\ & \Gamma & \neg\varphi&\neg\psi\\ \hline & \Gamma & &\varphi &\\ \end{array} \text{ (Contradiction Rule)}\),这个规则允许我们做反证法。正确性:对于任意\(\I\),如果\(\I(\Gamma)=true\),假如此时\(\I(\neg\varphi)=true\),那么由第一行的sequent可以得到\(\I(\psi) =true\),由第二行的sequent可以得到\(\I(\neg\psi)=true\)。但这在数学事实上是矛盾的。所以只能是\(\I(\varphi)=true\)。所以\(\Gamma\models \varphi\)
  6. \(\begin{array}{aligned} & \Gamma & \varphi&\chi\\ & \Gamma & \psi&\chi\\ \hline & \Gamma &(\varphi\lor \psi) &\chi &\\ \end{array} \text{ (Or Rule for Antecedent)}\),这个规则允许我们用或连接词合并两个sequent。正确性:对于任意\(\I\),如果\(\I(\Gamma)=true\)\(\I(\varphi\lor \psi)=true\)\(\I(\varphi)=true\)\(\I(\psi)=true\)中至少有一个成立,那么由第一行或第二行的sequent就可以推出\(\I(\chi)=true\)成立;
  7. \(\begin{array}{aligned} & \Gamma & \varphi\\ \hline & \Gamma & (\varphi\lor\psi) &\\ \end{array}, \ \ \begin{array}{aligned} & \Gamma & \varphi\\ \hline & \Gamma & (\psi\lor\varphi) &\\ \end{array} \text{ (Or Rule for Succeedent)}\),这个规则会允许我们在后件中用或并上一个别的命题。正确性:对于任意\(\I\),如果\(\I(\Gamma)=true\),由第一行的sequent得到\(\I(\varphi)=true\),那么“\(\I(\varphi)=true\)\(\I(\psi)=true\)”一定成立,所以\(\I(\varphi\lor\psi)=true\)
  8. \(\begin{array}{aligned} & \Gamma & \varphi\dfrac{t}{x}\\ \hline & \Gamma &\exists x\varphi &\\ \end{array}\) \(\text{ (Rule for }\)\(\exists\)\(\text{ in Succedent)}\),这个规则允许:当我们要证存在\(x\)使得\(\varphi\)成立时,只需举出一个\(x\)的一个实例\(t\)。这里的\(t\)称为\(\varphi\)成立的witness(见证)。这里的\(\varphi\dfrac{t}{x}\)就是我们在上一节中定义的substitution。自然地,对这一规则的正确性验证会用到“语法替换”与“语义替换”的等价性:对于任意\(\I\),如果\(\I(\Gamma)=true\),由\(\Gamma\models \varphi\dfrac{t}{x}\)得到\(\I( \varphi\dfrac{t}{x})=true\),由The Substitution Lemma这等价于\(\I\dfrac{\I(t)}{x}( \varphi)=true\),也即论域中存在一个元素\(a\),使得\(a=\I(t)\)\(\I\dfrac{a}{x}\models \varphi\),这恰好满足语义的定义:\(\I(\exists x\varphi)=true\)
  9. \(\begin{array}{aligned} & \Gamma & \varphi\dfrac{y}{x} & \psi\\ \hline & \Gamma &\exists x\varphi & \psi\\ \end{array}\) \(\text{ if }\) \(y \not\in \text{free}(\Gamma),\text{free}(\exists x\varphi),\text{free}(\psi)\) \(\text{ (Rule for }\)\(\exists\)\(\text{ in Antecedent)}\),这个规则允许我们在前件中做推断“\(\varphi\dfrac{y}{x}\)\(\implies\)\(\exists x\varphi\)”。正确性:对于任意\(\I\),如果\(\I(\Gamma)=true\)\(\I(\exists x\varphi)=true\)\(\mathfrak{I}(\exists x \varphi)=true\)意味着论域中存在元素\(a\)使得\(\mathfrak{I}\dfrac{a}{x}(\varphi)=true\)。由于\(y \notin \text{free}(\exists x \varphi)\),那么\(y \notin \text{free}(\varphi)\),因此\(\left(\mathfrak{I}\dfrac{a}{y}\right)\dfrac{a}{x}\)\(\mathfrak{I}\dfrac{a}{x}\)在所有\(\varphi\)的自由变量上有相同的解释,由The Coincidence Lemma可得\(\mathfrak{I}\dfrac{a}{x}(\varphi)= \left(\mathfrak{I}\dfrac{a}{y}\right)\dfrac{a}{x} (\varphi)\)。而\(\mathfrak{I}\dfrac{a}{y}(y)=a\),于是\(\left(\mathfrak{I}\dfrac{a}{y}\right)\dfrac{a}{x}(\varphi)=\)\(\left(\mathfrak{I}\dfrac{a}{y}\right)\dfrac{\mathfrak{I}\dfrac{a}{y}(y)}{x}(\varphi)\)\(=\mathfrak{I}\dfrac{a}{y}(\varphi \dfrac{y}{x})\)。由于\(y \notin \text{free}(\Gamma)\),由The Coincidence Lemma得\(\mathfrak{I}\dfrac{a}{y}(\Gamma)= \mathfrak{I}(\Gamma)=true\)。所以由第一行的sequent得\(\mathfrak{I}\dfrac{a}{y}(\psi)=true\)。由于\(y \notin \text{free}(\psi)\),再次根据The Coincidence Lemma得\(\mathfrak{I}\dfrac{a}{y}(\psi)= \mathfrak{I}( \psi)=true\)。综上,\(\Gamma \cup \{\exists x \varphi\} \models \psi\);(注意,这条规则中对\(y\)的限制是必要的。不做限制将会导致这条规则出错。考虑以下反例:已知\((x\equiv f y)\dfrac{y}{x}\)推出\(y\equiv fy\),这二者是语义后承关系,所以成立。但此时\(y\)是自由变量,如果应用本条规则会得到\(\exists x \ x\equiv fy\)能推出\(y\equiv fy\),而这不是语义后承关系,因此不正确)
  10. \(\begin{array}{aligned} & \Gamma && \varphi\dfrac{t}{x}\\ \hline & \Gamma &t\equiv t' & \varphi\dfrac{t'}{x}\\ \end{array}\) \(\text{ (Substitution Rule for Equality)}\),这个规则允许我们根据前件中的等式做替换。正确性:对于任意\(\I\),如果\(\I(\Gamma)=true\)\(\I(t)=\I(t')\),由第一行的sequent得\(\I(\varphi\dfrac{t}{x})=true\),根据The Substitution Lemma得到\(\I\dfrac{\I(t)}{x}(\varphi)=true\),而\(\I(t)=\I(t')\),所以\(\I\dfrac{\I(t')}{x}(\varphi)=true\),再次根据The Substitution Lemma有\(\I( \varphi\dfrac{t'}{x})=true\)

接下来,我们可以根据以上十条规则,进一步给出一系列由以上十条规则的组合使用得到的推导规则。我们在此列出一些重要的:

  • \(\text{Tertium non datur: }\begin{array}{aligned} \\ \hline & (\varphi \lor \neg\varphi)\\ \end{array}\),排中律;
  • \(\text{Chain Rule: }\begin{array}{aligned} & \Gamma & &\varphi\\ & \Gamma & \varphi & \psi\\ \hline & \Gamma & &\psi\\ \end{array}\),链式法则;
  • \(\text{Modus ponens: }\begin{array}{aligned} & \Gamma & (\varphi\to\psi)\\ & \Gamma & \varphi\\ \hline & \Gamma &\psi\\ \end{array}\),肯定前件式;
  • \(\text{Moified Or Rule: }\begin{array}{aligned} & \Gamma & (\varphi\lor\psi)\\ & \Gamma & \neg\varphi\\ \hline & \Gamma &\psi\\ \end{array}\),或规则的变形;
  • \(\text{Modified Contradiction Rule: }\begin{array}{aligned} & \Gamma & \psi\\ & \Gamma & \neg\psi\\ \hline & \Gamma &\varphi &\\ \end{array}\),矛盾规则的变形:如果一个前件能推出矛盾的后件,则这个前件可以推出任意命题;

我们以Modified Contradiction Rule为例,展示上述规则是如何导出的(注意,此时我们不再依据数学事实做证明,而是基于已有规则做形式上的推导):对第一行的sequent应用规则三antecedent rule,得到\(\Gamma \ \ \neg \varphi \ \ \psi\);对第二行的sequent应用规则三antecedent rule,得到\(\Gamma \ \ \neg \varphi \ \ \neg\psi\);对这两个sequent应用规则五contradiction rule得到\(\Gamma \ \ \varphi\),证明结束。

形式化证明

当我们从一个永真式出发,依据演算规则不断对算式做变换,直到最后演算出我们想要证明的结论,我们就已经纯粹从形式上给出了一个证明。这就是一个形式化证明(formal proof)。而既然我们已经逐一验证了这十条演算规则的正确性,就说明形式化证明一定是正确的:如果横线以上的每一条sequent \(\Gamma_i \ \varphi_i\)都满足\(\Gamma_i\models \varphi_i\),那么横线下的sequent \(\Gamma \ \varphi\)就一定满足\(\Gamma\models \varphi\)。要确认这一点,只需在数学事实层面做归纳证明:对演算的步骤归纳,初始步骤是符合数学事实的,每一条规则的应用也是符合数学事实的,而步骤是有限的,因此最终得出的结论也是符合数学事实的。这就是基于一阶逻辑语言的相继式演算的可靠性(Soundness)。

我们必须把语义后承和演算推导区分开来。具体而言,对于一个有限的一阶逻辑formula集合\(\Phi\)和一个一阶逻辑formula \(\varphi\),如果\(\varphi\)\(\Phi\)的语义后承,我们就记为\(\Phi \models \varphi\)\(\Phi \models \varphi\)的含义是:在任何解释\(\I\)下,数学事实上\(\Phi\)成立都意味着数学事实上\(\varphi\)成立。但是这没有涉及任何有关形式化证明的事情。所以,为了讨论命题\(\varphi\)能否由集合\(\Phi\)通过形式化证明得到,我们引入新的符号:如果可以由相继式演算得到sequence \(\Phi \ \varphi\),那么记为\(\Phi \vdash \varphi\)

可靠性说的是:任何可以从\(\Phi\)出发由形式化证明得到的命题\(\varphi\),都是数学事实上\(\Phi\)的语义后承。用新定义的符号来表达:选定符号集\(S\),对于任意有限的\(S\)-formula集合\(\Phi\)\(S\)-formula \(\varphi\),如果\(\Phi\vdash \varphi\)成立,那么一定有\(\Phi \models \varphi\)成立。形式化证明永远不会引发错误,不会由正确的前提导出错误的结论。

Remark: 我们通常不必强调\(\Phi\)是一个有限的集合还是一个无限的集合。因为一个证明一定是有限长的,因此即便\(\Phi\)是一个包含无穷多个formula的集合,只要能找到一个形式化证明从\(\Phi\)推出了\(\varphi\),那么我们一定能找到\(\Phi\)的一个有限子集\(\Phi_0\)使得\(\Phi_0\vdash \varphi\)。于是根据可靠性,能满足\(\Phi \models \varphi\)\(\Phi\)也一定有一个有限子集\(\Phi_0'\)使得\(\Phi_0'\models \varphi\)

此时,最自然的一个疑问是:是否对于任何\(\Phi\)\(\varphi\),只要\(\Phi \models \varphi\)成立,就有\(\Phi \vdash \varphi\)成立?也就是说,是不是任何数学事实上成立的语义后承关系都存在一个形式化的证明(可以写出一个有限长的相继式演算的算式)?这一性质就称为基于一阶逻辑语言的相继式演算的完备性(completeness)。我们将在下一节证明基于一阶逻辑语言的相继式演算是具有完备性的,这就是哥德尔完备性定理(Gödel's Completeness Theorem)。


我在Lean里形式化了SequentCalculus以及Soundness的证明

import Mathlib
import MIL.DennyQi_LogicEbbinghaus.FirstOrderLogic
open Classical
open FirstOrderLogic

set_option maxHeartbeats 9999999

structure Sequent (S : SymbolSet) where
  antecedent : List (Formula S)
  succedent : Formula S

inductive Derivable (S : SymbolSet) : ((Sequent S) -> Prop) where
  | ReflexivityRule (t):
      Derivable S { antecedent := [], succedent := (Formula.Eq t t) }
  | AssumptionRule (Γ φ) :
      φ ∈ Γ → Derivable S { antecedent := Γ, succedent := φ }
  | AntecedentRule (Γ φ) :
      ∀ Γ', (Γ' ⊆ Γ) -> (Derivable S { antecedent := Γ', succedent := φ }) → Derivable S { antecedent := Γ, succedent := φ }
  | ProofByCasesRule (Γ φ) :
      ∀ ψ, (Derivable S { antecedent := ψ :: Γ, succedent := φ }) → (Derivable S { antecedent := (Formula.Neg ψ) :: Γ, succedent := φ }) → Derivable S { antecedent := Γ, succedent := φ }
  | ContradictionRule (Γ φ) :
      ∀ ψ, (Derivable S { antecedent := (Formula.Neg φ) :: Γ, succedent := ψ }) → (Derivable S { antecedent := (Formula.Neg φ) :: Γ, succedent := (Formula.Neg ψ) }) → Derivable S { antecedent := Γ, succedent := φ }
  | OrRuleForAntecedent (Γ φ ψ ξ) :
      (Derivable S { antecedent := φ :: Γ, succedent := ξ }) → (Derivable S { antecedent := ψ :: Γ, succedent := ξ }) → Derivable S { antecedent := (Formula.Or φ ψ) :: Γ, succedent := ξ }
  | OrRuleForSuccedent1 (Γ φ ψ) :
      (Derivable S { antecedent := Γ, succedent := φ }) → Derivable S { antecedent := Γ, succedent := (Formula.Or φ ψ) }
  | OrRuleForSuccedent2 (Γ φ ψ) :
      (Derivable S { antecedent := Γ, succedent := φ }) → Derivable S { antecedent := Γ, succedent := (Formula.Or ψ φ) }
  | RuleForExistsInSuccedent (Γ x φ t) :
      (Derivable S { antecedent := Γ, succedent := FormulaSubstitution S φ [(x, t)] }) → Derivable S { antecedent := Γ, succedent := (Formula.Exists x φ) }
  | RuleForExistsInAntecedent (Γ x y φ ψ) :
      (∀ ξ ∈ Γ, y ∉ Freevar S ξ) -> (y ∉ Freevar S (Formula.Exists x φ)) → (y ∉ Freevar S ψ) -> (Derivable S { antecedent := (FormulaSubstitution S φ [(x, Term.Var y)]) :: Γ, succedent := ψ }) → Derivable S { antecedent := (Formula.Exists x φ) :: Γ, succedent := ψ }
  | SubstitutionRuleForEquality (Γ x t t' φ) :
      (Derivable S { antecedent := Γ, succedent := (FormulaSubstitution S φ [(x,t)]) }) → Derivable S { antecedent := (Formula.Eq t t') :: Γ, succedent := (FormulaSubstitution S φ [(x,t')]) }

theorem Derivable.Tertium_non_datur
  (S : SymbolSet)
  (φ : Formula S)
  :
  (Derivable S { antecedent := [], succedent := Formula.Or φ (Formula.Neg φ) })
:= by
  have hseq1 : (Derivable S { antecedent := [φ], succedent := φ }) := by
    apply Derivable.AssumptionRule
    tauto
  have hseq2 : (Derivable S { antecedent := [φ], succedent := Formula.Or φ (Formula.Neg φ) }) := by
    apply Derivable.OrRuleForSuccedent1
    tauto
  have hseq3 : (Derivable S { antecedent := [Formula.Neg φ], succedent := Formula.Neg φ }) := by
    apply Derivable.AssumptionRule
    tauto
  have hseq4 : (Derivable S { antecedent := [Formula.Neg φ], succedent := Formula.Or φ (Formula.Neg φ) }) := by
    apply Derivable.OrRuleForSuccedent2
    tauto
  have hseq5 : (Derivable S { antecedent := [], succedent := Formula.Or φ (Formula.Neg φ) }) := by
    apply Derivable.ProofByCasesRule [] (Formula.Or φ (Formula.Neg φ)) (φ) <;> tauto
  exact hseq5

theorem Derivable.Modified_Contradiction_Rule
  (S : SymbolSet)
  (Γ : List (Formula S))
  (φ ψ: Formula S)
  (hseq1 : Derivable S { antecedent := Γ, succedent := ψ })
  (hseq2 : Derivable S { antecedent := Γ, succedent := Formula.Neg ψ })
  :
  (Derivable S { antecedent := Γ, succedent := φ })
:= by
  have hseq3 : (Derivable S { antecedent := (Formula.Neg φ) :: Γ, succedent := ψ }) := by
    apply Derivable.AntecedentRule ((Formula.Neg φ) :: Γ) ψ Γ
    repeat tauto
  have hseq4 : (Derivable S { antecedent := (Formula.Neg φ) :: Γ, succedent := Formula.Neg ψ }) := by
    apply Derivable.AntecedentRule ((Formula.Neg φ) :: Γ) (Formula.Neg ψ) Γ
    repeat tauto
  have hseq5 : (Derivable S { antecedent := Γ, succedent := φ }) := by
    apply Derivable.ContradictionRule Γ φ ψ
    repeat tauto
  exact hseq5

theorem Derivable.Chain_Rule
  (S : SymbolSet)
  (Γ : List (Formula S))
  (φ ψ : Formula S)
  (hseq1 : Derivable S { antecedent := Γ, succedent := φ })
  (hseq2 : Derivable S { antecedent := φ :: Γ, succedent := ψ })
  :
  (Derivable S { antecedent := Γ, succedent := ψ })
:= by
  have hseq3 : (Derivable S { antecedent := (Formula.Neg φ) :: Γ, succedent := φ }) := by
    apply Derivable.AntecedentRule ((Formula.Neg φ) :: Γ) φ Γ
    repeat tauto
  have hseq4 : (Derivable S { antecedent := (Formula.Neg φ) :: Γ, succedent := Formula.Neg φ }) := by
    apply Derivable.AssumptionRule
    tauto
  have hseq5 : (Derivable S { antecedent := (Formula.Neg φ) :: Γ, succedent := ψ }) := by
    apply Derivable.Modified_Contradiction_Rule S ((Formula.Neg φ) :: Γ) ψ φ <;> tauto
  have hseq6 : (Derivable S { antecedent := Γ, succedent := ψ }) := by
    apply Derivable.ProofByCasesRule Γ ψ φ <;> tauto
  exact hseq6

theorem Derivable.Modus_Ponens
  (S : SymbolSet)
  (Γ : List (Formula S))
  (φ ψ : Formula S)
  (h1 : Derivable S { antecedent := Γ, succedent := Formula.Imply φ ψ })
  (h2 : Derivable S { antecedent := Γ, succedent := φ })
  :
  (Derivable S { antecedent := Γ, succedent := ψ })
:= by
  have hseq1 : (Derivable S { antecedent := (Formula.Neg φ) :: Γ, succedent := φ }) := by
    apply Derivable.AntecedentRule ((Formula.Neg φ) :: Γ) φ Γ
    repeat tauto
  have hseq2 : (Derivable S { antecedent := (Formula.Neg φ) :: Γ, succedent := Formula.Neg φ }) := by
    apply Derivable.AssumptionRule
    tauto
  have hseq3 : (Derivable S { antecedent := (Formula.Neg φ) :: Γ, succedent := ψ }) := by
    apply Derivable.Modified_Contradiction_Rule S ((Formula.Neg φ) :: Γ) ψ φ <;> tauto
  have hseq4 : (Derivable S { antecedent := ψ :: Γ, succedent := ψ }) := by
    apply Derivable.AssumptionRule
    tauto
  have hseq5 : (Derivable S { antecedent := (Formula.Or (Formula.Neg φ) ψ) :: Γ, succedent := ψ }) := by
    apply Derivable.OrRuleForAntecedent <;> tauto
  have hseq6 : (Derivable S { antecedent := Γ, succedent := ψ }) := by
    simp [Formula.Imply] at h1
    apply Derivable.Chain_Rule S Γ (Formula.Or (Formula.Neg φ) ψ) ψ <;> try tauto
  exact hseq6

theorem Derivable.Modified_Or_Rule
  (S : SymbolSet)
  (Γ : List (Formula S))
  (φ ψ : Formula S)
  (hseq1 : Derivable S { antecedent := Γ, succedent := Formula.Or φ ψ })
  (hseq2 : Derivable S { antecedent := Γ, succedent := Formula.Neg φ })
  :
  (Derivable S { antecedent := Γ, succedent := ψ })
:= by
  have hseq3 : (Derivable S { antecedent := φ :: Γ, succedent := Formula.Neg φ }) := by
    apply Derivable.AntecedentRule (φ :: Γ) (Formula.Neg φ) Γ
    repeat tauto
  have hseq4 : (Derivable S { antecedent := φ :: Γ, succedent := φ }) := by
    apply Derivable.AssumptionRule
    tauto
  have hseq5 : (Derivable S { antecedent := φ :: Γ, succedent := ψ }) := by
    apply Derivable.Modified_Contradiction_Rule S (φ :: Γ) ψ φ <;> tauto
  have hseq6 : (Derivable S { antecedent := ψ :: Γ, succedent := ψ }) := by
    apply Derivable.AssumptionRule
    tauto
  have hseq7 : (Derivable S { antecedent := (Formula.Or φ ψ) :: Γ, succedent := ψ }) := by
    apply Derivable.OrRuleForAntecedent <;> tauto
  have hseq8 : (Derivable S { antecedent := Γ, succedent := ψ }) := by
    apply Derivable.Chain_Rule S Γ (Formula.Or φ ψ) ψ <;> tauto
  exact hseq8


theorem Derivable.Double_Negation_Elim_Rule
  (S : SymbolSet)
  (Γ : List (Formula S))
  (φ : Formula S)
  (hseq1 : Derivable S { antecedent := Γ, succedent := Formula.Neg (Formula.Neg φ) })
  :
  (Derivable S { antecedent := Γ, succedent := φ })
:= by
  have hseq2 : (Derivable S { antecedent := (Formula.Neg φ) :: Γ, succedent := Formula.Neg (Formula.Neg φ) }) := by
    apply Derivable.AntecedentRule ((Formula.Neg φ) :: Γ) (Formula.Neg (Formula.Neg φ)) Γ
    repeat tauto
  have hseq3 : (Derivable S { antecedent := (Formula.Neg φ) :: Γ, succedent := Formula.Neg φ }) := by
    apply Derivable.AssumptionRule
    tauto
  have hseq4 : (Derivable S { antecedent := Γ, succedent := φ }) := by
    apply Derivable.ContradictionRule Γ φ (Formula.Neg φ) <;> tauto
  exact hseq4

theorem Derivable.Double_Negation_Intro_Rule
  (S : SymbolSet)
  (Γ : List (Formula S))
  (φ : Formula S)
  (hseq1 : Derivable S { antecedent := Γ, succedent := φ })
  :
  (Derivable S { antecedent := Γ, succedent := Formula.Neg (Formula.Neg φ) })
:= by
  have hseq2 : (Derivable S { antecedent := (Formula.Neg (Formula.Neg (Formula.Neg φ))) :: Γ, succedent := φ }) := by
    apply Derivable.AntecedentRule ((Formula.Neg (Formula.Neg (Formula.Neg φ))) :: Γ) φ Γ
    repeat tauto
  have hseq3 : (Derivable S { antecedent := (Formula.Neg (Formula.Neg (Formula.Neg φ))) :: Γ, succedent := Formula.Neg (Formula.Neg (Formula.Neg φ)) }) := by
    apply Derivable.AssumptionRule
    tauto
  have hseq4 : (Derivable S { antecedent := (Formula.Neg (Formula.Neg (Formula.Neg φ))) :: Γ, succedent := Formula.Neg φ }) := by
    apply Derivable.Double_Negation_Elim_Rule S ((Formula.Neg (Formula.Neg (Formula.Neg φ))) :: Γ) (Formula.Neg φ)
    tauto
  have hseq5 : (Derivable S { antecedent := Γ, succedent := Formula.Neg (Formula.Neg φ) }) := by
    apply Derivable.ContradictionRule Γ (Formula.Neg (Formula.Neg φ)) φ <;> tauto
  exact hseq5
import Mathlib
import MIL.DennyQi_LogicEbbinghaus.FirstOrderLogic
import MIL.DennyQi_LogicEbbinghaus.SequentCalculus
open Classical
open FirstOrderLogic

set_option maxHeartbeats 9999999

def IsValid (S : SymbolSet) (φ : Formula S) : Prop :=
  ∀ (I : Interp S), FormulaEval S I φ

def IsContradiction (S : SymbolSet) (φ : Formula S) : Prop :=
  ∀ (I : Interp S), ¬ FormulaEval S I φ

def IsSatisfiable (S : SymbolSet) (φ : Formula S) : Prop :=
  ∃ (I : Interp S), FormulaEval S I φ

def Consequence (S : SymbolSet) (φ ψ : Formula S) : Prop :=
  ∀ (I : Interp S), FormulaEval S I φ → FormulaEval S I ψ

def FormulaSet (S : SymbolSet) := (Formula S) → Prop

def Consequence_set (S : SymbolSet) (Φ : FormulaSet S) (ψ : Formula S) : Prop :=
  ∀ (I : Interp S), (∀ (φ : Formula S), (Φ φ) → (FormulaEval S I φ)) → FormulaEval S I ψ

def Equivalent (S : SymbolSet) (φ ψ : Formula S) : Prop :=
  ∀ (I : Interp S), FormulaEval S I φ ↔ FormulaEval S I ψ

lemma equiv_iff_mutual_consequence (S : SymbolSet) (φ ψ : Formula S) :
  (Equivalent S φ ψ) ↔ ((Consequence S φ ψ) ∧ (Consequence S ψ φ))
:= by
  constructor
  · intro h1
    dsimp [Equivalent] at h1
    dsimp [Consequence]
    constructor
    · intro I h2
      rw [← h1 I]
      tauto
    · intro I h2
      rw [h1 I]
      tauto
  · dsimp [Equivalent]
    dsimp [Consequence]
    intro h1 I
    rcases h1 with ⟨h2, h3⟩
    specialize h2 I
    specialize h3 I
    tauto

theorem Soundness_of_Sequent_Calculus
  (S : SymbolSet)
  (seq : Sequent S)
  (hder : Derivable S seq)
  :
  (Consequence_set S {φ | φ ∈ seq.antecedent}  (seq.succedent))
:= by
  induction hder with
  | ReflexivityRule t =>
    simp [Consequence_set, FormulaEval]
  | AssumptionRule Γ φ h =>
    simp [Consequence_set]
    intro I h1
    apply h1
    tauto
  | AntecedentRule Γ φ Γ' hsubset h1 h2=>
    simp [Consequence_set]
    intro I h3
    simp [Consequence_set] at h2
    specialize h2 I
    apply h2
    intro φ' h
    apply h3
    tauto
  | ProofByCasesRule Γ φ ψ h1 h2 h3 h4 =>
    simp [Consequence_set]
    intro I h5
    by_cases hcase : FormulaEval S I ψ
    · simp [Consequence_set] at h3
      apply h3
      intro ξ h6
      have h7 : ξ = ψ ∨ ξ ∈ Γ := by tauto
      by_cases heq : ξ = ψ
      · rw [heq]
        tauto
      · have hin : ξ ∈ Γ := by tauto
        apply h5
        tauto
    · simp [Consequence_set] at h4
      apply h4
      intro ξ h6
      have h7 : ξ = ψ.Neg ∨ ξ ∈ Γ := by tauto
      by_cases heq : ξ = ψ.Neg
      · rw [heq]
        tauto
      · have hin : ξ ∈ Γ := by tauto
        apply h5
        tauto
  | ContradictionRule Γ φ ψ h1 h2 h3 h4 =>
    simp [Consequence_set]
    intro I h5
    by_cases hcase : FormulaEval S I φ.Neg
    · have htrue : FormulaEval S I ψ := by
        simp [Consequence_set] at h3
        specialize h3 I
        apply h3
        intro ξ h6
        have h7 : ξ = φ.Neg ∨ ξ ∈ Γ := by tauto
        by_cases hcase' : ξ = φ.Neg
        · rw [hcase']
          tauto
        · have hin : ξ ∈ Γ := by tauto
          apply h5
          tauto
      have hfalse : FormulaEval S I ψ.Neg := by
        simp [Consequence_set] at h4
        specialize h4 I
        apply h4
        intro ξ h6
        have h7 : ξ = φ.Neg ∨ ξ ∈ Γ := by tauto
        by_cases hcase' : ξ = φ.Neg
        · rw [hcase']
          tauto
        · have hin : ξ ∈ Γ := by tauto
          apply h5
          tauto
      simp [FormulaEval] at hcase
      tauto
    · simp [FormulaEval] at hcase
      tauto
  | OrRuleForAntecedent Γ φ ψ ξ h1 h2 h3 h4 =>
    simp [Consequence_set]
    intro I h5
    have hor := h5 (Formula.Or φ ψ)
    have h0 : FormulaEval S I (φ.Or ψ) := by
      apply hor
      tauto
    have hex : (FormulaEval S I φ) ∨ (FormulaEval S I ψ) := by
      exact Decidable.or_iff_not_and_not.mpr h0
    rcases hex with hc1 | hc2
    · simp [Consequence_set] at h3
      specialize h3 I
      apply h3
      intro ζ h6
      have h7 : ζ = φ ∨ ζ ∈ Γ := by tauto
      rcases h6 with h8 | h9
      · rw [h8]
        tauto
      · apply h5
        tauto
    · simp [Consequence_set] at h4
      specialize h4 I
      apply h4
      intro ζ h6
      have h7 : ζ = ψ ∨ ζ ∈ Γ := by tauto
      rcases h6 with h8 | h9
      · rw [h8]
        tauto
      · apply h5
        tauto
  | OrRuleForSuccedent1 Γ φ ψ h1 h2 =>
    simp [Consequence_set]
    intro I h3
    have hconcl : (FormulaEval S I φ) ∨ (FormulaEval S I ψ) := by
      left
      simp [Consequence_set] at h2
      specialize h2 I
      apply h2
      tauto
    simp [Formula.Or, FormulaEval]
    tauto
  | OrRuleForSuccedent2 Γ φ ψ h1 h2 =>
    simp [Consequence_set]
    intro I h3
    have hconcl : (FormulaEval S I φ) ∨ (FormulaEval S I ψ) := by
      left
      simp [Consequence_set] at h2
      specialize h2 I
      apply h2
      tauto
    simp [Formula.Or, FormulaEval]
    tauto
  | RuleForExistsInSuccedent Γ x φ t h1 h2=>
    simp [Consequence_set]
    intro I h3
    simp [Formula.Exists, FormulaEval]
    simp [Consequence_set] at h2
    specialize h2 I h3
    rw [The_Substitution_Lemma_formula] at h2
    simp at h2
    use TermEval S I t
    simp [AssignmentSubstitution] at h2
    simp [eq_comm]
    tauto
  | RuleForExistsInAntecedent Γ x yy φ ψ h1 h2 h3 h4 h5 =>
    simp [Consequence_set]
    intro I h6
    have h7 : FormulaEval S I (Formula.Exists x φ) := by
      apply h6
      tauto
    simp [Formula.Exists, FormulaEval] at h7
    rcases h7 with ⟨d, h7⟩
    have h8 : FormulaEval S { 𝔸 := I.𝔸, β := fun y ↦ if y = x then d else I.β y } φ ↔ FormulaEval S { 𝔸 := I.𝔸, β := fun y ↦ if (y = x || y = yy) then d else I.β y } φ := by
      apply The_Coincidence_Lemma_formula <;> try tauto
      intro x1 hx1
      split_ifs with hif1 hif2 hif3 <;> try rfl
      · simp at hif2
        tauto
      · simp at hif3
        rcases hif3 with hc1 | hc2 <;> try tauto
        rw [hc2] at hx1
        simp [Formula.Exists, Freevar] at h2
        specialize h2 hx1
        rw [← h2] at hif1
        tauto
    have h9 : FormulaEval S { 𝔸 := I.𝔸, β := fun y ↦ if (y = x || y = yy) then d else I.β y } φ := by
      rw [← h8]
      tauto
    have h10 : FormulaEval S { 𝔸 := I.𝔸, β := fun y ↦ if (y = x || y = yy) then d else I.β y } φ ↔ FormulaEval S { 𝔸 := I.𝔸, β := fun y ↦ if (y = yy) then d else I.β y } (FormulaSubstitution S φ [(x,Term.Var yy)]) := by
      rw [The_Substitution_Lemma_formula]
      simp
      apply The_Coincidence_Lemma_formula <;> try tauto
      intro x1 hx1
      split_ifs with hif
      · rcases hif with hif1 | hif2
        · rw [← hif1]
          simp [AssignmentSubstitution, TermEval]
        · rw [← hif2]
          simp [AssignmentSubstitution, TermEval]
      · simp at hif
        rcases hif with ⟨ hif1, hif2 ⟩
        simp [AssignmentSubstitution, TermEval]
        split_ifs with hspl <;> tauto
    have h11 : FormulaEval S { 𝔸 := I.𝔸, β := fun y ↦ if y = yy then d else I.β y } (FormulaSubstitution S φ [(x, Term.Var yy)]) := by
      tauto
    simp [Consequence_set] at h5
    have h12 := h5 { 𝔸 := I.𝔸, β := fun y ↦ if y = yy then d else I.β y }
    have h13 : FormulaEval S { 𝔸 := I.𝔸, β := fun y ↦ if y = yy then d else I.β y } ψ := by
      apply h12
      intro ζ hzeta
      have hin : ζ = FormulaSubstitution S φ [(x, Term.Var yy)] ∨ ζ ∈ Γ := by tauto
      rcases hin with hc1 | hc2
      · rw [hc1]
        tauto
      · have h13 : FormulaEval S I ζ := by
          apply h6
          tauto
        have h14 : (FormulaEval S I ζ) ↔ (FormulaEval S { 𝔸 := I.𝔸, β := fun y ↦ if y = yy then d else I.β y } ζ) := by
          have h14 := The_Coincidence_Lemma_formula S I.𝔸.A I.𝔸.a I.𝔸.a I.β (fun y ↦ if y = yy then d else I.β y) ζ
          apply h14 <;> try tauto
          intro x1 hx1
          split_ifs with hspl <;> try tauto
          rw [hspl] at hx1
          specialize h1 ζ
          tauto
        tauto
    have hconcl : (FormulaEval S I ψ) ↔ (FormulaEval S { 𝔸 := I.𝔸, β := fun y ↦ if y = yy then d else I.β y } ψ) := by
      have h14 := The_Coincidence_Lemma_formula S I.𝔸.A I.𝔸.a I.𝔸.a I.β (fun y ↦ if y = yy then d else I.β y) ψ
      apply h14 <;> try tauto
      intro x1 hx1
      split_ifs with hspl <;> try tauto
      rw [hspl] at hx1
      tauto
    tauto
  | SubstitutionRuleForEquality Γ x t t' φ h1 h2 =>
    simp [Consequence_set]
    intro I h3
    dsimp [Consequence_set] at h2
    specialize h2 I
    have h4 : FormulaEval S I (Formula.Eq t t') := by
      apply h3
      tauto
    simp [FormulaEval] at h4
    rw [The_Substitution_Lemma_formula]
    simp
    rw [← h4]
    have h5 : (∀ (φ : Formula S), {φ | φ ∈ Γ} φ → FormulaEval S I φ) := by
      intro ξ h6
      apply h3
      refine Set.setOf_app_iff.mpr ?_
      right
      tauto
    have h6 := h2 h5
    rw [The_Substitution_Lemma_formula] at h6
    tauto

参考文献

[1] H.-D. Ebbinghaus, J.Flum, W. Thomas: Mathematical Logic

posted @ 2025-07-15 02:47  行而上  阅读(261)  评论(0)    收藏  举报