数学不仅仅是数字。 当你超越算术【arithmetic】并接触到抽象【abstract】的东西,数学的乐趣才真正开始变得清晰起来。 所有的抽象【abstract】都可以用两个基本的东西来构建:
- 逻辑【Logic】
- 集合论【Set theory】
Mr. Spock Is Not Logical
我是科幻小说的忠实粉丝。事实上,我全家几乎都是科幻极客。我小时候,每周六下午6点是《星际迷航【Star Trek】》时间,当地的一个频道会重播原著。到了周六,我们总是确保 6 点前到家,然后聚在电视机前看节目。这真是一段美好的回忆。但关于《星际迷航》,有一件事我永远不会原谅吉恩·罗登贝里【Gene Roddenberry】或这部剧:他们滥用"逻辑【logic】"这个词的方式,每次 Mr. Spock 说,“但那是不合逻辑的【But that would not be logical】。”
Mr. Spock 的声明告诉了很多人,“合乎逻辑【logical】”与“合理【reasonable】”或“正确【correct】”的含义相同。当你听到人们说某事合乎逻辑时,他们的意思通常不是说"合乎逻辑【logical】":他们的意思几乎完全相反——常识告诉他们这是正确的。
如果你正确地使用了“合乎逻辑【logical】”这个词,那么仅仅说某事是合乎逻辑【logical】的并不意味着它是否正确。任何事,任何事都是合乎逻辑的。对于合乎逻辑【logical】的事物,它必须是一个从某些前提进行推理的有效示例。
例如,如果我告诉你这是合乎逻辑【logical】的:“如果我的车是用铀做的,那么月亮是用奶酪做的。”你可能会认为我疯了。这是一个愚蠢、荒谬的陈述,而且根据直觉,这不是真的。Mr. Spock 肯定会说这不合乎逻辑【logical】。但事实上,这是合乎逻辑【logical】的。在谓词逻辑【predicate logic】的标准规则下,它是一个真命题【true statement】。事实上,这是一个愚蠢的命题【statement】,并不意味着任何事情都是无关紧要的。这是合乎逻辑【logical】的,因为逻辑上说这是真的。
它是怎么合乎逻辑【logical】的呢?要说某事是合乎逻辑【logical】的,您的意思是可以使用正式的推理系统推断【inferred】或证明【proven】它。在一阶谓词逻辑 【first-order predicate logic】(FOPL)(数学家最常用的逻辑)中,如果“if”部分为假或“then”部分为真,则 if/then 命题/陈述(正式称为蕴涵)为真。如果你在“if”部分放了假【false 】的东西,那么你可以在“then”命题/陈述中放任何东西【anything at all 】,即 if/then 命题/陈述是逻辑正确的【logically true】。
但远不止这些。 逻辑,在我们通常谈论的意义上讲,其实并不是一回事。 逻辑是一系列具有推理规则的形式证明系统的名称。 有许多种逻辑,在一个系统中是有效推理(即逻辑)的陈述在另一个系统中可能无效。 举一个非常简单的例子,大多数人都知道,在逻辑中,有一条叫做排中律的规则,它表示对于给定的陈述 A,A 或非 A 为真。 在 FOPL 中,这是一种称为重言式【tautology 】的陈述,它必须始终为真。 但是我们还可以使用更多种类的逻辑。 还有另一种非常有用的逻辑,称为直觉逻辑【intuitionistic logic】,在这种逻辑中, A 或非 A 不一定为真。 在不证明 A 是真还是假的情况下,你无法推断出它是真还是假。
逻辑的种类比你想象的要多得多。 FOPL 和直觉逻辑非常相似,但还有许多其他类型的逻辑可用于不同的事情。 FOPL 非常适合代数和几何的证明,但在谈论时间时却很糟糕。“直到今晚6点前,我都不会饿”,该表述真正抓住了这句话的时间意义,但是 FOPL 没有好的办法来表述。 但是有一些逻辑,比如 CTL(我们将在第 15 节中详细讨论, 时间推理 )专门设计用于擅长这种陈述。 但它们对 FOPL 擅长的那些事情却不怎么擅长。 每种逻辑都是为一个目的而设计的,以进行特定类型的推理。 每种逻辑都可以用不同的方式来证明不同的事情。
《星际迷航》和 Mr. Spock 说得对的是,逻辑的基本要点之一是公正/无偏见。 至少在理论上, Mr. Spock 确实试图将事物简化为一种无需情感就能理解的形式。 但说是合乎逻辑的话,还不够有意义。 您需要说明您使用的是哪种逻辑。 你需要说明你用什么公理(基本事实)进行推理,以及你的逻辑是如何让你进行推理的。
相同的论点,在一个逻辑中可能在逻辑上是有效和正确,在另一个逻辑中在逻辑上是无效和不正确,甚至在同一逻辑中使用不同的一组基本事实。 在不指定逻辑和公理的情况下,说某一个结论是合乎逻辑的并不能告诉你什么。
What Is Logic, Really?
逻辑【Logic】是一种机械推理系统。它是一个系统,允许你用中立的符号形式【neutral symbolic form 】来表达一个论点【argument】,然后用这个符号形式【symbolic form】来确定论点【argument 】是否有效。在逻辑上重要的不是意义【meaning】;而是构成论点的推理步骤是否前后相顾。这是一个非常强大的工具,特别是因为它在推理时忽略了意义【meaning】。逻辑不能偏向论点的某一方,因为逻辑既不知道也不关心论点的意义【mean】!
为了使这种公正/无偏见【unbiased 】的推理发挥作用,逻辑需要以一种严格、正式的方式构建。这种形式向我们表明,逻辑中的推理【reasoning】(正式称为推理【inference】)在应用于实际参数时会产生正确的结果。
我们关心这一点,是因为逻辑【Logic】是我们推理【Reason】的核心,而推理【Reasoning 】是我们沟通的核心! 每一次政治辩论、每一次哲学争论、每一篇技术论文、每一个数学证明,每一个论点【argument】的核心都有一个逻辑结构【logical structure】。 我我们使用逻辑【Logic】以一种让我们看到结构的方式来捕捉核心,而不仅仅是看到它——理解它并测试它,最终看看它是否正确。
我们把这一切都形式化【formal】,因为我们想要确保在分析一个论点【argument】时,我们是公正/无偏见的。 形式【formality 】确保我们的逻辑系统是真正可靠的、系统的和客观的。 逻辑所做的是将一个论点【argument】简化为一种符号形式【symbolic form】,可以在不知道其含义的情况下评估其正确性。 如果你考虑意义【meaning】,很容易让你的直觉理解影响到你的判断。 如果你知道论点【argument】是关于什么的,很容易让你自己的偏见蔓延。但逻辑将其简化为理论上可以由机器评估的符号。
形式上,逻辑由三部分组成:语法【syntax】、语义【semantics】和一组推理规则【a set of inference rules】:
- 语法准确地告诉您逻辑中的命题/陈述【statement】是什么样的以及您应该如何阅读【read】和编写【write】它们。
- 语义通过告诉你如何在逻辑的抽象符号命题/陈述【abstract symbolic statements】与你正在推理的思想和对象之间进行转换,从而告诉你逻辑中的命题/陈述意味着什么。
- 最后,推理规则描述了在给定一组在该逻辑下编写的命题/陈述的情况下,您如何在逻辑中执行推理。
FOPL, Logically
关于逻辑,您需要了解的第一件事就是它的语法【syntax】。 逻辑的语法正式地告诉您如何在该逻辑中阅读和编写句子。 语法不会告诉你如何理解命题/陈述或它们的含义。 它只是告诉你它们的样子以及如何正确地将它们组合在一起。
逻辑【Logic】将命题/陈述的意义【meaning】与语法分离开来。 意义【meaning】被称为逻辑的语义【semantics 】。 对于 FOPL,语义【semantics 】很容易理解——不是因为它们真的那么简单,而是因为你每天都在使用它们。 你每天听到的大多数论点【arguments】,大多数推理都是 FOPL ,所以你已经习惯了,即使你没有意识到。
我们将一起学习 FOPL 的基本语法和语义,因为这样更容易理解。我们将从我们要推理的对象开始。
逻辑的重点是让你对事物进行推理。 这些事物可以是具体的东西,比如汽车或人,也可以是抽象的实体,比如三角形或集合。 但是要在逻辑【Logic】中进行推理,我们需要使用符号【symbols】来表示这些对象。 对于我们想要推理的每个对象,我们引入一个称为常量【constant】或原子【atom】的符号【symbol 】。 每个原子【atom 】代表一个特定的对象、数字或值,可以使用逻辑【Logic】对其进行推理。 如果我想对我的家庭【family】进行推理,常量将是我家庭成员的姓名、住址等等。 我会将常量写为数字或引用单词。
当您不想引用特定对象时,可以使用变量【variable】。 例如,如果你想说每个对象都有一个属性,就像每个人都有一个父亲,你不想写“Mark has a father”、“Jennifer has a father”、“Rebecca has a father” ,等等。 您希望能够写出这样一个命题/陈述,说明这对每个人都是正确的。 变量可以让你做到这一点。 变量本身没有任何意义; 它的意义来源于上下文。 等一下我们讲到量词【quantifiers】的时候,就会知道这是什么意思了。
FOPL 需要的最后一种类型是谓词【predicate】。 谓词类似于描述对象属性或对象之间关系的函数。 例如,当我说“Mark has a father”时,短语“has a father”就是谓词【predicate】。 在我们的示例中,我们将使用大写标识符编写谓词,它所讨论的对象在括号内。 如果我想在 FOPL 中写下“Mark’s father is Irving”命题/陈述,我会写作 Father("Irving", "Mark")。
每个谓词【predicate】在定义时,都会解释它何时为真,何时为假。 如果我想使用前面的示例谓词,Father,我对它的定义需要解释它何时为真。 在这种情况下,您可能认为这个名字就足够了:当我们说“Joe is Jane’s father”时,我们知道这是什么意思。但逻辑需要精确。 如果 Joe 是 Jane 的养父,Father("Joe", "Jane") 应该是真的吗? 如果我们关心的是家庭关系【family relationships】,那么答案应该是肯定的; 如果我们关心的是生物关系【biological relationships】,那么答案应该是否定的。 在我们的例子中,我们会说我们在讨论生物关系。
填充了参数的谓词称为简单事实【simple fact】或简单命题/陈述【simple statement】。
我们可以通过获取我们拥有的命题/陈述【statements 】,修改它们或组合它们,来形成更有趣的命题/陈述【statement】。 最简单的组合和修饰是“and”(称为合取【conjunction】)、“or”(称为析取【disjunction】)和“not”(称为否定【negation】)。 在形式化语法中,我们使用 ∧ 符号表示“and”,使用 ∨ 符号表示“or”,以及 ¬ 符号表示“not”。 使用这些,我们可以写出诸如:
- Father("Mark", "Rebecca") ∧ Mother("Jennifer", "Rebecca")(Mark 是 Rebecca 的父亲,Jennifer 是 Rebecca 的母亲)
- YoungestChild("Aaron", "Mark" ) ∨ YoungestChild("Rebecca", "Mark")(Aaron 是 Mark 最小的孩子,或 Rebecca 是 Mark 最小的孩子
- ¬Mother("Mark", "Rebecca")(Mark 不是 Rebecca 的母亲)
and,or,not,按照你所期望的方式工作。如果 A 和 B 都为真,A∧B为真。如果 A 为真,或者 B 为真,则 A ∨ B 为真。如果 A 为假,则 ¬ A 为真。
关于逻辑或【or】有一件棘手的事情。 在非正式谈话中,如果你说“我想要汉堡包或鸡肉三明治”,你的意思是你想要汉堡包或鸡肉三明治,但不是两者都想要。 对于逻辑或【or】,若要 A ∨ B 为真,则只要 A 和 B 中至少有一个为真,两者都是真也可以。 非正式的逻辑或【or】在 FOPL 中也被称为排他性或【exclusive or】。 当我们定义逻辑时,我们不定义排他性或【exclusive or】,因为它可以用其他命题/陈述【statement】来表示。
使用 ∧、∨ 和 ¬,我们可以组成我们想要的所有句子【sentences】。 但是我们错过了我们真正想要的一件事:if-then,也称为蕴涵【implication】。 在所有类型的参数中,蕴涵是一种常见且有用的工具,因此我们非常希望能够直接编写它。 严格来说,我们不需要它,因为我们可以使用 and、or 和 not 来编写它。 但是因为它非常有用,我们无论如何都会添加它。 蕴含【implication】有两种含义:simple if 和 if-and-only-if。
一个 simple if 命题/陈述可以写成 A ⇒ B,可以读作“A 蕴含 B”或“if A then B”。 这意味着如果 A 部分为真,那么 B 部分也一定为真——反之亦然:如果 B 部分为假,那么 A 部分也一定为假。
if-and-only-if 写作 A ⇔ B,可以读作“A if-and-only-if B”,或者简称为“A if/f B”。if/f 是相等的逻辑版本:当 A 和 B 都为真或当 A 和 B 都为假时,A ⇔ B为真。正如双头箭头标记所表明的,A ⇔ B 与 A ⇒ B ∧ B ⇒ A 是完全相同的。
连接词【connectives 】使我们能够形成所有基本的逻辑命题/陈述【logical statements】。 但是我们仍然无法写出有趣的论点。 像这样的简单命题/陈述【statements 】是不够的。 为了了解原因,我们来看看古希腊哲学家亚里士多德提出的一个最简单、最著名的逻辑论点:
-
All men are mortal【人终有一死】
-
Socrates is a man【苏格拉底是人】
-
Therefore, Socrates is mortal.【因此,苏格拉底终有一死】
就我们目前对 FOPL 的了解,我们无法写出这个论点。 我们知道如何编写关于特定原子【atom】的特定命题/陈述【statement】,这意味着我们可以将第 2 步和第 3 步写为 Is_A_Man("Socrates") 和 Is_Mortal("Socrates")。 但是我们无法写出第一个命题/陈述。 我们无法说“All men are mortal【人终有一死】”,因为我们无法说“all men”。 这是关于所有原子【atom】的命题/陈述,我们还没有办法对所有原子【atom】作出一般性陈述【general statement】。
要对所有可能的值进行一般性陈述【general statement】,请使用全称陈述【universal statement】。 它写作 ∀ a: P(a)(读作“对于所有 a,P(a)”),这意味着 P(a) 对于 a 的所有可能值都为真。
大多数情况下,全称陈述【universal statement】出现在蕴含【implications】中,这让您可以将陈述【statement 】限制为一组特定的值,而不是所有可能的值。 在苏格拉底的例子中,全称陈述【universal statement】“All men are mortal【人终有一死】”将写成 ∀ x: Is_A_Man(x) ⇒ Is_Mortal(x)(“对于所有 x,如果 x 是一个人,那么 x 是凡人”)。 由于使用如此频繁,因此有一个简写:我们通常将其写为 ∀ x ∈ Is_A_Man: Is_Mortal(x)。
我们想要做的最后一件事情称为存在命题命题/陈述【existential statement】。 存在主义让我们说,一定存在一个值,使得陈述/命题为真,即使我们不知道这个陈述/命题到底是什么。 使用我们的家庭陈述,我们可以说我必须有一个父亲:∃ x:Father(x, "Mark"),我们读作“存在一个 x,使得 x 是 Mark 的父亲。”
存在性【Existentials 】与全称性【universals】相结合时最有用。 说我必须有一个父亲并不是一个特别有用的陈述:我们知道我父亲是谁。 但是通过将普遍性与存在性结合起来,我可以说每个人都有一个父亲:∀ x:∃ y:父亲(y,x)。 这总是正确的——这是人类生物学的一个基本事实。 如果我们看到一个人,我们就知道那个人一定有一个父亲。 我们可能不知道他是谁。 事实上,这个人可能不知道他或她的父亲是谁。 但我们知道,毫无疑问,这个人有一个父亲。 量词的组合让我们可以这么说。
说我必须有一个父亲,这并不是一个特别有用的陈述:我们知道我父亲是谁。 但是通过将存在性【Existentials 】与全称性【universals】结合起来,我可以说每个人都有一个父亲:∀ x: ∃ y: Father(y, x)。 这总是正确的——这是人类生物学的一个基本事实。 如果我们看到一个人,我们就知道那个人一定有一个父亲,即使我们可能不知道他是谁。 事实上,这个人也有可能不知道他或她的父亲是谁。 但我们知道,毫无疑问,这个人有一个父亲。 量词【quantifiers 】的组合让我们可以这么说。
Show Me Something New!
现在我们已经看到了逻辑的语言:如何读写命题/陈述【statements 】以及如何理解它们的意思。但到目前为止,我们只有写命题/陈述【statements 】的语言。使它成为逻辑的是证明【proof】的能力。逻辑上的证明【proof】是通过推理【inference】来完成的:推理为您提供了一种方法,通过利用你所知道的,来证明信的事实,并补充到你所知道的信息中。
在本节中,我不会详细介绍 FOPL 中所允许的整个推理规则集。 我将给你们举几个例子,足以证明一些推论。在下一章中,我将以更详细的形式向你展示所有的规则,这对检查证明很有用。但现在,让我们来看看它是如何工作的:
- Modus Ponens:这是谓词逻辑最基本的规则。如果我知道P(x) ⇒ Q(x),并且我知道 P(x),那么我可以推断Q(x)一定是真的。同样,我们也可以反过来做。如果我知道 P(x) ⇒ Q(x),并且知道¬ Q(x),即 Q(x) 是假,那么我就可以得出结论:¬ P(x),也就是说,P(x) 一定也是假的。
- Weakening:如果我知道 P(x) ∧ Q(x) 为真,那么我可以推断 P(x) 一定是真的。类似地,如果我知道 P(x) ∨ Q(x) 为真,且 Q(x) 为假,那么 P(x) 一定是真的。
- Universal Elimination:如果我们知道 ∀ x: P(x) 为真,且“a”是一个特定的原子【atom】,那么我们可以推断 P(“a”) 为真。
- Existential Introduction:如果 x 是一个未使用的变量,并且我们知道 P(“a”) 为真,那么我们可以推断 ∃x: P(x) 为真。
- Universal Introduction:如果我们在不需要知道 x 的情况下,可以证明 P(x) 为真,那么我们可以从中归纳出 ∀ x: P(x) 。
要用逻辑推理,你要从一组公理开始,这些公理是你知道为真的基本事实,即使你没有证据。如果一个命题/陈述【statement】可以通过公理和逻辑推理规则证明,那么该命题/陈述【statement】在逻辑上为真。
所以再一次,下面是一组关于我的家庭的公理。
-
Axiom 1. Father("Mark", "Rebecca") Mark is Rebecca’s father.
-
Axiom 2. Mother("Jennifer", "Rebecca")
-
Axiom 3. Father("Irving", "Mark")
-
Axiom 4. Mother("Gail", "Mark")
-
Axiom 5. Father("Robert", "Irving")
-
Axiom 6. Mother("Anna", "Irving")
-
Axiom 7. ∀ a, ∀ b:(Father(a, b) ∨ Mother(a, b)) ⇒ Parent(a, b)
-
Axiom 8. ∀ g, ∀ c : (∃ p : Parent(g, p) ∧ Parent(p, c)) ⇒ Grandparent(g, c)
现在让我们使用这些公理和我们的推理规则来证明 Irving 是 Rebecca 的祖父母。
例子:证明 Irving 是 Rebecca 的祖父母。
-
通过公理 1 Father("Mark", "Rebecca"),我们可以推理出 Parent("Mark", "Rebecca"),我们称其推理 I1.
-
通过公理 3 Father("Irving","Mark"),我们可以推理出 Parent("Irving","Mark"),我们称其推理I2.
-
根据推理I1 Parent(Irving, Mark) 和推理 I2 Parent("Mark", "Rebecca"),我们可以推理出 Parent("Irving", "Mark") ∧ Parent(Mark,Rebecca),我们称其推理 I3.
-
根据推理 I3 Parent("Irving", "Mark") ∧ Parent("Mark", "Rebecca"),通过公理 8, 我们可以推断出 Grandparent("Irving", "Rebecca").
-
QED.
在一给定的逻辑中,由其规则形成的一连串的推理【inferences 】被称为证明【proof】。 我们示例中的一连串的推理,是在一阶谓词逻辑【FOPL】中的证明。 需要注意的一件非常重要的事情是,证明完全是符号化的:我们不需要知道原子【atom】代表什么或谓词【predicates 】意味着什么! 逻辑中的推理过程纯粹是符号化的,可以在完全不知道您要证明的命题/陈述【statement】的含义的情况下完成。 推理是一个简单的过程,它使用推理规则从给定的一组前提得到结论。 只要有适当的前提,你几乎可以证明任何命题/陈述【statement】;给定前提和逻辑的选择,您绝对可以证明任何命题/陈述【statement】。
例子:证明对于所有 n,从 0 到 n 的自然数之和为 n(n+1)/2。
-
归纳规则,从逻辑上将,是这样的一个蕴含:如果该命题/陈述【statement】对 0 为真,并且如果我们可以证明对于所有大于或等于 1 的值 n,该命题/陈述【statement】依然为真,如果对 n 为真,则对 n - 1 也为真 ,那么它对所有 n 都成立——我们已经证明了这一点。
-
我们需要证明这两种情况,才能使用该蕴涵。 我们从最基本的情况开始。 我们需要证明,当 n = 0 时,,n(n+1)/2 = 从 0 到 n 的自然数之和。如果我们想要完整,我们实际上需要通过基于 Peano 的加法和乘法的正式定义进行推理。在乘法的定义中,0 乘以任何数都是 0;所以我们可以把它作为一个逻辑等价【logical equivalence】,将 n(n+1) 替换为 0 —— 因此从 0 到 0 的总和是 0,这就证明了基本情况。我们现在有一个推理,它对 0 为真。
-
现在是归纳部分,归纳部分本身就是一个蕴含。 如果我们将试图证明的事实【fact】视为谓词 P,那么我们想要做的是证明对于所有 n,P(n) 蕴含 P(n+1)。 我们通过使用全称引入推理规则【universal introduction inference rule】来做到这一点。 我们通过使用未绑定的 n 【unbound n】来证明 n/n+1 推理是正确的:
假设,对于一个数字 n,它为真。 现在我们要证明 n + 1 。所以我们要证明的是:
-
然后我们就像第一次一样进行代数运算部分。 最后,我们得到一个命题/陈述【statement】,如果 P 对 n 成立,那么它对 n + 1 也成立。我们可以用推理规则把它推广成一个全称的/普遍的【universal】。
-
现在我们有了蕴涵所要求的两个命题/陈述【statement】,因此,我们可以使用蕴涵推理(如果 A 蕴涵 B ,且 A 为真,那么 B 必须为真的规则)。 我们知道 P 对 0 为真。我们知道对于所有 n > 0,如果 P 对 n - 1 为真,那么 P 对 n 也为真。所以根据归纳规则,我们现在可以推断出结论:对于所有自然数 n , 0 到 n 的数字之和为 n(n+1)/2。
-
QED
在这里回顾所有的推理规则可能看起来有点过头了,但这是有意义的。
逻辑的美妙之处在于,它是一种使推理清晰而机械的简单方法。 规则列表可能看起来很复杂,但当仔细想想,实际上你在日常生活中,在政治、商业、学校或餐桌旁听到的每一个论点【argument】,当你总结它时,都可以用一阶谓词逻辑【FOFL】来表达。 所有这些论点【arguments】,在每种情况下,都是可以通过将它们转换成 FOPL 形式,然后使用那套推理规则来进行测试验证【check】。 这就是你需要检查验证【check】任何论点或证明的全部。 当你这样想的时候,你应该能够开始看到为什么它真的是如此的简单 。
Proofs, Truth, and Trees: Oh My!
逻辑的意义在于使证明事物成为可能。 什么是证明?在数学中,它是一系列逻辑推理,表明一个新的事实(称为结论)是如何从一组已知的事实(称为前提)中推导出来的。
证明【proof】往往会吓到人。 我还记得在高中二年级的时候,在几何课上学习了证明。这是迄今为止我上过的最糟糕的数学课!我试着在作业中做一个证明;当老师把它交回来时,上面全是红墨水,每隔一行都标有“无法推断出”或“缺失案例”等字眼。我只是想不通我应该做什么。
很多人都有过类似的经历。我们被教导,一个有效的证明必须由之前的每一步推断而来,并且必须涵盖所有可能的情况。遗憾的是,我们几乎没有被教导,应该如何准确地判断步骤何时可以推断,或者如何确保我们已经涵盖了所有情况。只有真正理解证明中用到的逻辑和逻辑推理机制,才能理解如何做到这一点。
这就是证明对我们很多人来说如此困难的原因。并不是说证明真的有那么难。相反,掌握证明需要掌握在证明中使用的逻辑。在大多数数学课上,我们并没有真正学到证明的逻辑【logic 】部分。它被视为我们应该理解的东西。对于某些人来说,这很容易; 对我们中的许多人来说,事实并非如此。
因此,在本章中,我们将研究 FOPL 中的证明机制。 我将使用一种称为真值树【truth trees】或语义表【semantic tableaus】的技术来处理它。 您将看到的内容与真实树的典型呈现方式略有不同。 当我在大学时,我有幸从一位名叫 Ernest Lepore 的伟大教授那里上了一门逻辑学课程。 Lepore 教授用他自己的方法来教学生真理树,直到今天我还在用他的方法。因为它们是我用的,所以我要展示给你们看。( Lepore 教授的书,Meaning and Argument: An Introduction to Logic Through Language [Lep00].)。
Building a Simple Proof with a Tree
真值树【Truth trees】的工作原理是制造矛盾。我们想要证明一个命题是正确的,通过否定它来扭转它,然后证明这个否定会导致矛盾。
例如,我可以用这个基本方法来证明不存在最大的偶数 N:
例子:证明不存在最大偶数 N 之类的东西。
-
我们将首先反转事实来证明,然后我们将证明它会导致矛盾。 假设有一个最大的偶数 N。
-
由于 N 是最大的偶数,那么对于其他偶数 n,需满足 n < N。
-
N 是自然数; 因此,它可以与其他自然数相加。
-
如果我们将 N 加 2,结果将是偶数,并且会大于 N。
-
我们创造了一个比 N 大的偶数,这与步骤 2 相矛盾。因为我们有这样一个矛盾,这意味着 N 是最大的偶数的说法是错误的。
这就是真值树【truth tree】的工作原理:从否定你想证明【proof】的东西开始,通过展示每一个可能的推理链都会导致矛盾。 树机制为您提供了一种简单、直观的方式,以确保您涵盖了所有案例:每次执行任何引入另一个案例的操作时,您就创建了树的一个分支。
在实践中,我实际上并没有使用真值树【truth tree】来编写证明; 我用它来检查【checking】证明。 当我认为我已经在 FOPL 中得到了一个很好的证明时,我通过建立一个真理树来检查我是否做对了。 该树可以轻松地查看证明并验证一切都遵循正确的推理并且涵盖所有情况,从而确保证明有效。
在真值树中这样做的方法是首先写下您在列中给出的前提; 然后你把你想证明的陈述写在页面的顶部。 然后你否定那个陈述。 在真值树中,我们将证明,在否定陈述的情况下,每条可能的推理路径都会导致矛盾。 如果发生这种情况,那么我们就知道否定陈述是假的,而我们想要证明的陈述是真的。
在真值树【truth tree】中这样做的方法是首先在一列中写下已知的前提【premises 】;然后把你想证明的命题/陈述【statement 】写在顶部。再然后你否定了这个命题/陈述【statement】。在真理树中,我们将证明,当命题被否定时,每一条可能的推理路径都会导致一个矛盾。如果是这样,我们就知道否定命题为假,而我们要证明的命题为真。
Table 1. Logical equivalence rules
Implication Equivalence | A ⇒ B is equivalent to ¬ A ∨ B |
Universal Negation | ¬ ∀ x: P(x) is equivalent to ∃ x: ¬ P(x) |
Existential Negation | ¬ ∃ x: P(x) is equivalent to ∀ x: ¬ P(x) |
And Negation | ¬(A ∧ B) is equivalent to ¬ A ∨ ¬ B |
Or Negation | ¬ (A ∨ B) is equivalent to ¬ A ∧ ¬ B |
Double Negation | ¬ ¬ A is equivalent to A |
Universal Reordering | ∀ a: (∀ b: P(a, b)) is equivalent to ∀ b: (∀ a: P(a, b)) |
Existential Reordering | ∃ a: (∃ b: P(a, b)) is equivalent to ∃ b: (∃ a: P(a, b)) |
Table 2. The inference rules for truth trees in FOPL
Given | Rule | Infer |
---|---|---|
And Weakening (left) | A ∧ B | A |
And Introduction | A and B | A ∧ B |
Or Branching | A ∨ B | Two branches: one with A, one with B |
Or Negation | A ∨ B and ¬ A | B |
Or Introduction | A | A ∨ B |
Modus Ponens | A ⇒ B and A | B |
Universal Elimination | ∀ x: P(x) | P(a) for any specific atom a |
Existential Elimination | ∃ x: P(x) | P(a) for any unused atom a |
我没有在推理规则列表中进行冗长的讨论,而是将它们列在表格中。在大多数情况下,如果你仔细查看并思考它们,你就能明白它们的含义。但是逻辑作为一种推理系统的意义在于你不需要知道它们的意思。逻辑定义了这些推理规则;只要你遵循它们,你就可以创建有效的证明。
A Proof from Nothing
既然我们已经看到了所有这些论点的形式化表述,那么我们如何使用它们呢?
让我们从一个简单但基本的逻辑规则——排中律——的证明开始。 它说任何命题/陈述【statement】都必须是真或假。 当你把它写成逻辑时,这意味着如果你有一个命题/陈述【statement】 A,那么不管 A 是什么,A ∨ ¬A 一定是真的。
排中律是一个重言式【tautology】,这意味着无论我们选择什么公理,它都是一个必须始终为真的基本真理。 为了证明重言式【tautology 】是正确的,我们需要建立一个证明【proof】,只使用命题/陈述【statement】和逻辑推理规则。 如果我们可以在没有前提【premises】的情况下推导出 A ∨ ¬ A 的证明,我们就可以证明它是普遍真理【universal truth】。
由于我们要证明 A ∨ ¬ A,我们从它的否定的真理树【truth tree】开始,然后我们将证明通过树的每条路径都会以矛盾结束。 证明如下图所示。
Figure 10. A proof tree for the law of the excluded middle
Prove that A ∨ ¬ A.
-
We want to prove A ∨ ¬ A, so we start with its negation: ¬ (A ∨ ¬ A).
-
By using the and negation equivalence rule, we can write down ¬ A ∧ ¬ ¬ A.
-
By using and weakening on (2), we can add ¬ A.
-
By using and weakening on (2) again, we can add ¬ ¬ A.
-
By using double negation on (4), we can add A to the tree.
-
Our only branch of the tree now contains both A and ¬ A, which is a contradiction.
这是我们重言式【tautology】的完整证明。 没那么难,是吗? 证明的重点是我们知道我们已经涵盖了我们所有的基础,一切都是由前面推论而来,并且肯定涵盖了所有情况。
请注意,在每一步中,我们都不需要考虑任何事情的意义【mean】。 我们可以观察到,在步骤的开始,我们有一些符合规则中的一个模式的东西,然后我们使用这个规则派生出新的东西:一个新的推断,并将其添加到树中。
这是一个简单的例子,但即使在这样的情况下,证明的困难部分也不是应用规则。 应用推理规则很容易。 但是你如何决定应用哪个推理规则呢? 这是最困难的部分。 我怎么知道在第 3 步中应该使用和弱化【and weakening】? 基本上,我做了一个有根据的猜测。 我知道我想要得到一个简单的矛盾,为此,我需要将可能变成矛盾的部分分开。
如果您是一名程序员,那么构建证明很像遍历搜索树【search tree】。从理论上讲,在证明的每一步,您都可以找到所有适用的推理规则,并尝试使用它们。 如果你一直这样做,并且这个命题/陈述【statement】是可证明的,那么最终你会找到证明。 这可能需要很长时间,但如果这个命题是可证明的,你终归会得到它, 但如果这个命题不能被证明,你可能会一直找下去,这就是著名的停止问题。在实践中,建立真实的证明是一个搜索过程和大量的直接试验和错误的结合。 你看看你想证明什么,以及你有什么可用的事实,然后你找出你可以采取的推理步骤。了解您所有选项【options】后,您会根据对所证明内容的理解,选择最有可能得出结论的选项【option】。 如果您尝试这样做但它不起作用,那么您选择不同的选项【option】并重试。
All in the Family
现在让我们继续尝试一些更有趣的事情。 我们将回到上一章中的家庭关系示例,并证明如果两个人是堂兄弟,那么他们有一个共同的祖父母。
在我们的家庭关系中,我们需要用逻辑项【logical term】来定义什么是表亲:如果两个人的父母都是对方父母之一的兄弟姐妹,我们就会说他们是表亲。 在 FOPL 中,就是这样:∀ a: ∀ b: Cousin(a, b) ⇔ ∃ m: ∃ n: Sibling(m, n) ∧ Parent(m, a) ∧ Parent(n, b)。
我们要证明 ∀ d: ∀ e: Cousin(d, e) ⇔ ∃ g: Grandparent(g, d) ∧ Grandparent(g, e)。 就像排中律的证明一样,我们不需要对树进行分支。 这个证明确实有一些跳跃。理解它的关键是要记住,树中的任何命题/陈述【statement 】上面的内容都可以在它下面使用。
在整个证明过程中,我们的目标是采用 Cousin 和 Grandparent 的定义,将它们分解为简单项【simple terms】,然后推动这些项【terms】形成一个矛盾。
-
As always, we start by taking the statement we want to prove and negating it; that’s the root of the tree:
¬ (∀ d: ∀ e: Cousin(d, e) ⇔ ∃ g: Grandparent(g, d) ∧ Grandparent(g, e).
-
Use universal negation equivalence to push the ¬ inside the first ∀:
(∃ d: ¬ ∀ e: Cousin(d, e) ⇔ ∃ g: Grandparent(g, d) ∧ Grandparent(g, e)).
-
Use universal negation equivalence again to push inside the second ∀:
∃ d: ∃ e: ¬ (Cousin (d, e) ⇔ ∃ g(Grandparent(g, d) ∧ Grandparent(g, e)).
-
Use implication equivalence to convert ⇒ to an ∨:
∃ d: ∃ e: ¬ ( ¬ Cousin(d, e) ∨ ∃ g: Grandparent(g, d) ∧ Grandparent(g, e)).
-
Use or negation to push the ¬ into the or:
∃ d, ∃ e: Cousin(d, e) ∧ ¬ ∃ g: Grandparent(g, d) ∧ Grandparent(g, e)).
-
Use existential elimination to get rid of the ∃ by substituting a new variable:
Cousin(d’, e’) ∧ ¬ ∃ g: Grandparent(g, d’) ∧ Grandparent(g, e’)).
-
Use and weakening to separate the left clause of the ∧:
Cousin(d’, e’).
-
Use universal elimination to specialize the definition of cousin with d’ and e’:
Cousin(d’, e’) ⇔ ∃ p, ∃ q: Sibling(p, q) ∧ Parent(p, d’) ∧ Parent(q, e’).
-
Modus ponens:
∃ p, ∃ q: Sibling(p, q) ∧ Parent(p, d’) ∧ Parent(q, e’).
-
Existential elimination:
Sibling(p’, q’) ∧ Parent(p’, d’) ∧ Parent(q’, e’).
-
And weakening:
Sibling(p’, q’).
-
Universal elimination to specialize the definition of sibling for p’, q’:
Sibling(p’, q’) ⇒ ∃ g: Parent(g, p’) ∧ Parent(g, q’).
-
Modus ponens:
∃ g: Parent(g, p’) ∧ Parent(g, q’).
-
Universal elimination to specialize the definition of Grandparent for d’:
∀ g: Grandparent(g, d’) ⇔ ∃ e, Parent(g, e) ∧ Parent(e, d’).
-
And introduction:
Parent(p’, d’) ∧ Parent(g, p’).
-
Modus ponens:
Grandparent(g, d’).
-
Now repeat the specialization of Grandparent using e’, and you’ll get
Grandparent(g, e’).
-
Go back to where we did and weakening to separate the left-hand clause and do a separate right to separate the right, and you’ll get
¬ ∃ g: Grandparent(g, d’) ∧ Grandparent(g, e’)).
-
And that is a contradiction. Since we never branched, we’ve got a contradiction on the only branch that our tree has, and that means we’re done.
Branching Proofs
到目前为止,我们看到的两个真值树证明【truth-tree proofs】都是单分支证明【single-branch proofs】。 在实践中,很多有趣的证明,特别是在数论和几何中,都是单分支的。 不过,有些证明确实需要多分支。为了了解它是如何运作的,我们来看看另一个重言式【tautology】:蕴涵的传递性。如果我们知道命题/陈述 A 蕴含了命题/陈述 B,而且我们还知道命题/陈述 B 蕴含了命题/陈述 C,那么 A 蕴含 C 一定为真。在逻辑形式中, (A ⇒ B ∧ B ⇒ C) ⇒ (A ⇒ C)。
下图显示了这个的真值树证明。我们将一起完成这些步骤。这个证明的方法和我们证明排中律的方法很相似。我们只是想把证明的最上面的命题/陈述【statement】,分解成简单的命题/陈述【statement】,然后试着找出矛盾之处。
Figure 11. Truth tree example
例子:证明 (A ⇒ B ∧ B ⇒ C) ⇒ (A ⇒ C)
-
As always, start by negating the statement we want to prove.
-
Use implication equivalence to get rid of the outermost implication.
-
Use and negation and double negation to push the outer negation through the statement.
-
Implication equivalence twice to eliminate the first two implications.
-
And weakening to separate out the first term.
-
And weakening to separate out the second term.
-
And weakening to separate out the third term.
-
Implication equivalence and or negation to simplify the statement from step 7.
-
Or branching on the statement from step 5.
-
Left branch of the or branching from step 9.
-
And weakening of the statement in step 8. This gives us both A and ¬A in this branch, which is a contradiction. That means we’re done on this branch.
-
Right branch of the or branching from step 9.
-
Or branching of the statement in step 6.
-
Left branch of the or branching in step 13. That gives us ¬ B here and B in step 12, which is a contradiction, so we’re done on this branch.
-
Right branch of the or branching in step 13.
-
And weakening of step 8. This gives us ¬ C. We’ve got C in step 16, which means that we’ve got a contradiction on our final branch. All of the branches end in contradiction! That means we’re done.
对真值树进行推理的深入研究已经非常详细,但我们之所以要这样做,有两个重要原因。
首先,逻辑推理可能看起来非常神奇。我们将在下一章中看到,你可以让逻辑推理做一些非常困难的事情。 这使得推断似乎必须做一些复杂的事情。但事实并非如此。推理是很容易的。你可以看到有一些规则,你可以不费多大力气就理解它们。但是这个简单的框架却变得非常强大。
其次,详细查看规则有助于使逻辑的基本点之一真正清晰。 这些规则完全是语法上的,所以你可以根据符号进行推理,而不是根据其意义【mean】。
Programming with Logic
在了解了一阶谓词逻辑的推理如何使用真理树【truth tree】之后,您可能想知道您可以用推理做多少事情。答案是,非常多!事实上,计算机可以做的任何事情——任何可以写成程序的计算——都可以通过一阶谓词逻辑【(FOPL】推理来完成!
这不是空洞的夸口,也不是理论上的对等,而是实实在在的事实。有一种非常强大、非常有用的编程语言 Prolog,在这种语言中,程序只由事实和谓词的集合组成——您所能做的就是为它提供事实和谓词的集合。Prolog 程序的执行是由 Prolog 解释器使用程序的事实和谓词执行的一系列推断。
即使您是一名专业的工程师,也可能永远不需要编写 Prolog。但我是一个编程语言迷,相信我:这是值得学习的。我知道相当多的编程语言,当有人问我他们应该学习哪一种语言时,我通常会告诉他们 Prolog。这也不是因为我希望他们使用它,而是 Prolog 为您打开了一种完全不同的编程方式,为此付出努力是值得的。
我不会教你所有你想知道的关于 Prolog 的东西——这里介绍的太多了。 为此,您需要阅读一本关于 Prolog 的书。但我绝对可以让您体验一下它是什么样的。
Computing Family Relationships
我将使用与上一章相同的示例向您介绍 Prolog:家庭关系。 但是我们不会用形式逻辑语法写出它们,而是用 Prolog 来做,我们将看到您如何与 Prolog 系统交互。 我正在使用一个免费的、开源的 Prolog 解释器,称为 SWI-Prolog,但你可以使用它或在你的计算机上运行的任何其他 Prolog 系统。
在逻辑中,您对称为原子【atom】的对象进行推理。 在 Prolog 中,原子【atom】是任何小写的标识符、数字或带引号的字符串。 例如,mark、23 和“q”都是原子。 例如,我们研究的是家庭关系的推理,因此原子【atom】就都是名字。
Prolog 中的变量代表的是一个原子【atom】的符号。 这些变量可以在逻辑中用于推理全称性质【universal properties】——如果每个对象都有一个性质(例如,每个人都有一个父亲),那么在逻辑中可以使用变量来说明这一点。 Prolog 中的变量是大写字母:比如 X、Y。
谓词在 Prolog 中是一个语句,它允许你定义或描述对象和变量的性质【properties】。谓词被写成一个标识符,它所讨论的对象紧跟在括号内。例如,假设我们想表达 Mak 的父亲是 Irving ,那么我们可以使用一个名为 father 的谓词:father(Irving, Mark) 。在我们的例子中,我们用谓词人称陈述一系列事实,表示一堆原子是人。我们在这里所做的是向Prolog解释器提供一组基本的、已知的事实,这些事实被称为我们的逻辑公理。
在我们的例子中,我们用谓词 person 陈述了一系列事实,表示一堆原子【atom】是人。我们在这里所做的是向 Prolog 解释器提供一组基本的、已知的事实,这些事实在逻辑中也被称为公理。
logic/family.pl
person(aaron).
person(rebecca).
person(mark).
person(jennifer).
person(irving).
person(gail).
person(yin).
person(paul).
person(deb).
person(jocelyn).
我们可以用逗号连接一系列事实:A, B 表示 A 和 B 都是真的。
现在我们可以看看某些原子【atom】是不是人。如果我们将事实集加载到 Prolog 中,我们可以向它提问:
=>
person(mark).
<=
true.
=>
person(piratethedog).
<=
false.
=>
person(jennifer).
<=
true.