跳到主要内容

数理逻辑

数理逻辑是用数学方法研究推理规律的学科。它为数学证明提供了精确的语言和规则,也为计算机科学中的程序验证、人工智能推理、数据库查询等领域奠定了理论基础。本章将从最基础的命题逻辑开始,逐步深入到谓词逻辑和证明方法。

命题逻辑

命题逻辑(Propositional Logic)研究的是命题之间的逻辑关系。它是逻辑学中最简单也最基础的部分。

什么是命题?

命题(Proposition)是一个能够判断真假的陈述句。命题的关键特征是它必须有确定的真值——要么为真(True,记作 T 或 1),要么为假(False,记作 F 或 0)。

命题的例子:

  • "2 + 2 = 4" —— 这是一个命题,真值为真
  • "北京是中国的首都" —— 这是一个命题,真值为真
  • "1 + 1 = 3" —— 这是一个命题,真值为假

不是命题的例子:

  • "x + 1 = 2" —— 不是命题,因为 x 的值不确定,无法判断真假
  • "今天天气真好啊!" —— 不是命题,这是感叹句,不是陈述句
  • "你在说什么?" —— 不是命题,这是疑问句

命题通常用小写字母 pp, qq, rr 等表示。例如,设 pp 表示命题"今天下雨",那么我们可以讨论 pp 的真值。

命题联结词

单个命题的作用有限。通过联结词,我们可以将简单命题组合成复合命题,表达更复杂的逻辑关系。

否定(Negation)

否定是一元运算,将命题的真值取反。命题 pp 的否定记作 ¬p\neg p(读作"非 p")。

pp¬p\neg p
TF
FT

例如,设 pp 表示"今天是周末",则 ¬p\neg p 表示"今天不是周末"。

合取(Conjunction)

合取就是逻辑"与",当且仅当两个命题都为真时,合取结果为真。ppqq 的合取记作 pqp \land q(读作"p 且 q")。

ppqqpqp \land q
TTT
TFF
FTF
FFF

生活中的例子:"我有电脑 并且 我会编程"——只有两个条件同时满足,整个命题才为真。

析取(Disjunction)

析取是逻辑"或",只要有一个命题为真,析取结果就为真。ppqq 的析取记作 pqp \lor q(读作"p 或 q")。

ppqqpqp \lor q
TTT
TFT
FTT
FFF

注意区分"或"的两种含义:这里的"或"是可兼的(inclusive or),即两者都可以为真。日常生活中也有"要么...要么..."的表达,那是异或(exclusive or),表示两者恰有一个为真。

异或(Exclusive OR)

异或表示两个命题恰好有一个为真。记作 pqp \oplus qpqp \veebar q

ppqqpqp \oplus q
TTF
TFT
FTT
FFF

异或在计算机中应用广泛,例如校验位的计算。在编程中,异或运算符通常写作 ^

# 异或运算
print(True ^ True) # False
print(True ^ False) # True

蕴含(Implication)

蕴含表示"如果...那么..."的关系。pqp \to q 读作"如果 p,则 q"或"p 蕴含 q"。其中 pp 称为前件(antecedent),qq 称为后件(consequent)。

ppqqpqp \to q
TTT
TFF
FTT
FFT

蕴含的真值表可能令人困惑:为什么前件为假时,整个蕴含式为真?这称为"空真"(vacuously true)。可以这样理解:

"如果我今天中奖,我就请你吃饭。"

  • 如果我今天中奖了(pp 为真)并且我请你吃饭了(qq 为真),我没有违背承诺,命题为真。
  • 如果我今天中奖了(pp 为真)但我没有请你吃饭(qq 为假),我违背了承诺,命题为假。
  • 如果我今天没中奖(pp 为假),无论我是否请你吃饭,我都算不上违背承诺。因为没有触发条件,承诺自然成立。

等价(Biconditional)

等价表示"当且仅当"的关系,记作 pqp \leftrightarrow q。当 ppqq 真值相同时,等价式为真。

ppqqpqp \leftrightarrow q
TTT
TFF
FTF
FFT

例如:"一个三角形是等边三角形,当且仅当它的三个角相等。"

运算优先级

当表达式中有多个运算符时,需要遵循优先级规则:

  1. ¬\neg(否定)—— 最高优先级
  2. \land(合取)
  3. \lor(析取)
  4. \to(蕴含)
  5. \leftrightarrow(等价)—— 最低优先级

例如,¬pqr\neg p \land q \to r 应理解为 ((¬p)q)r((\neg p) \land q) \to r。为了清晰起见,建议在复杂表达式中使用括号。

真值表

真值表是分析复合命题的工具。通过列出所有可能的真值组合,我们可以判断一个命题是永真式、矛盾式还是可满足式。

永真式(Tautology):无论命题变量的真值如何,整个命题恒为真。例如 p¬pp \lor \neg p(排中律)。

矛盾式(Contradiction):无论命题变量的真值如何,整个命题恒为假。例如 p¬pp \land \neg p(矛盾律)。

可满足式(Contingency):至少有一种真值组合使命题为真。

让我们构造 pqp \to q¬pq\neg p \lor q 的真值表,看看它们是否等价:

ppqqpqp \to q¬p\neg p¬pq\neg p \lor q
TTTFT
TFFFF
FTTTT
FFTTT

可以看到 pqp \to q¬pq\neg p \lor q 的真值完全相同,因此它们是逻辑等价的。这是一个重要的等价关系,常用于证明中。

逻辑等价

两个命题 ppqq 逻辑等价,记作 pqp \equiv q,当且仅当它们的真值表完全相同。以下是常用的逻辑等价式:

德摩根律(De Morgan's Laws)

¬(pq)¬p¬q\neg(p \land q) \equiv \neg p \lor \neg q

¬(pq)¬p¬q\neg(p \lor q) \equiv \neg p \land \neg q

德摩根律描述了否定如何分配到合取和析取中。在编程中,这常用于简化条件表达式:

# 这两个条件是等价的
not (a > 0 and b > 0) # 等价于
a <= 0 or b <= 0

分配律

p(qr)(pq)(pr)p \land (q \lor r) \equiv (p \land q) \lor (p \land r)

p(qr)(pq)(pr)p \lor (q \land r) \equiv (p \lor q) \land (p \lor r)

吸收律

p(pq)pp \lor (p \land q) \equiv p

p(pq)pp \land (p \lor q) \equiv p

蕴含等价式

pq¬pqp \to q \equiv \neg p \lor q

这个等价式非常重要,它将蕴含转化为更容易处理的形式。

逆否命题

pq¬q¬pp \to q \equiv \neg q \to \neg p

逆否命题与原命题等价,这是证明中常用的技巧。要证明"如果 ppqq",可以改为证明"如果非 qq 则非 pp"。

对偶原理

将一个命题中的 \land\lor 互换,T 与 F 互换,得到的新命题称为原命题的对偶。如果原命题是永真式,则其对偶也是永真式。

例如,p¬pTp \lor \neg p \equiv T 的对偶是 p¬pFp \land \neg p \equiv F

谓词逻辑

命题逻辑的表达能力有限。例如,"所有人都会死"这样的陈述,无法用命题逻辑精确表达。谓词逻辑(Predicate Logic,也称一阶逻辑)引入了谓词、量词等概念,大大增强了表达能力。

谓词

谓词是描述对象性质或关系的函数。设 P(x)P(x) 表示"xx 是偶数",则 P(2)P(2) 为真,P(3)P(3) 为假。PP 就是谓词,xx 是变量。

一元谓词描述单个对象的性质,如"xx 是素数"。

多元谓词描述对象之间的关系,如"xx 大于 yy",记作 G(x,y)G(x, y)

谓词可以与命题联结词组合使用。例如,设 P(x)P(x) 表示"xx 是学生",Q(x)Q(x) 表示"xx 喜欢学习",则 P(x)Q(x)P(x) \land Q(x) 表示"xx 是学生且喜欢学习"。

量词

量词用来描述谓词中变量的范围。

全称量词

全称量词 \forall(读作"对于所有")表示某个谓词对所有对象都成立。

xP(x)\forall x P(x) 表示"对于所有 xxP(x)P(x) 都成立"。

例如,设论域为全体实数,x(x20)\forall x (x^2 \geq 0) 表示"所有实数的平方都非负"。

存在量词

存在量词 \exists(读作"存在")表示至少存在一个对象使谓词成立。

xP(x)\exists x P(x) 表示"存在一个 xx,使得 P(x)P(x) 成立"。

例如,x(x2=2)\exists x (x^2 = 2) 表示"存在一个数,其平方等于 2"。

量词的否定

量词的否定遵循以下规则:

¬xP(x)x¬P(x)\neg \forall x P(x) \equiv \exists x \neg P(x)

¬xP(x)x¬P(x)\neg \exists x P(x) \equiv \forall x \neg P(x)

理解这两条规则:否定"所有人都喜欢学习",等于说"存在一个人不喜欢学习";否定"存在一个完美的人",等于说"所有人都不完美"。

嵌套量词

量词可以嵌套使用。嵌套量词的顺序很重要:

  • xyP(x,y)\forall x \exists y P(x, y):对每个 xx,存在一个 yy(可以依赖 xx),使 P(x,y)P(x, y) 成立
  • yxP(x,y)\exists y \forall x P(x, y):存在一个 yy,对所有的 xxP(x,y)P(x, y) 都成立

这两者含义不同。以"每个人都有自己的父亲"为例:

  • xyFather(y,x)\forall x \exists y Father(y, x):对每个人 xx,存在一个 yyxx 的父亲。这是正确的。
  • yxFather(y,x)\exists y \forall x Father(y, x):存在一个人 yy,他是所有人的父亲。这显然是错误的。

论域

量词的作用范围称为论域(Domain of Discourse)。明确论域对理解命题至关重要。

例如,x(x>0)\forall x (x > 0) 的真值取决于论域:

  • 如果论域是正整数集合,则命题为真
  • 如果论域是全体整数,则命题为假

在实际应用中,可以用条件限制来指定论域:

x(x>0P(x))\forall x (x > 0 \to P(x)) 表示"对所有正数 xxP(x)P(x) 成立"

x(x>0P(x))\exists x (x > 0 \land P(x)) 表示"存在一个正数 xx,使 P(x)P(x) 成立"

注意全称量词用蕴含,存在量词用合取——这是书写习惯,也是逻辑需要。

证明方法

证明是建立数学命题真实性的过程。掌握证明方法,是学习离散数学的核心目标之一。不同的命题结构需要不同的证明策略,选择合适的策略往往能大大简化证明过程。

直接证明

直接证明从前提出发,通过逻辑推理直接得出结论。证明 pqp \to q 时,假设 pp 为真,然后推导 qq 为真。

例题:证明"如果 nn 是奇数,则 n2n^2 也是奇数"。

证明

假设 nn 是奇数。根据奇数的定义,存在整数 kk,使得 n=2k+1n = 2k + 1

那么 n2=(2k+1)2=4k2+4k+1=2(2k2+2k)+1n^2 = (2k + 1)^2 = 4k^2 + 4k + 1 = 2(2k^2 + 2k) + 1

m=2k2+2km = 2k^2 + 2k,则 n2=2m+1n^2 = 2m + 1,这正是奇数的形式。

因此,n2n^2 是奇数。证毕。

反证法

反证法(Proof by Contradiction)假设结论为假,然后推导出矛盾,从而证明结论必须为真。

适用场景

  • 直接证明困难或复杂
  • 结论的否定更容易处理
  • 想要证明"不存在"或"不可能"

例题:证明 2\sqrt{2} 是无理数。

证明

假设 2\sqrt{2} 是有理数。那么存在互质的正整数 ppqq,使得 2=p/q\sqrt{2} = p/q

两边平方得 2=p2/q22 = p^2/q^2,即 p2=2q2p^2 = 2q^2

这意味着 p2p^2 是偶数,因此 pp 是偶数(因为奇数的平方是奇数)。

p=2rp = 2r,代入得 (2r)2=2q2(2r)^2 = 2q^2,即 4r2=2q24r^2 = 2q^2,化简得 q2=2r2q^2 = 2r^2

同理,q2q^2 是偶数,因此 qq 是偶数。

现在 ppqq 都是偶数,与它们互质的假设矛盾。

因此,2\sqrt{2} 是无理数。证毕。

逆否证明

逆否证明基于等价关系 pq¬q¬pp \to q \equiv \neg q \to \neg p。当直接证明困难时,证明逆否命题往往更简单。

例题:证明"如果 n2n^2 是偶数,则 nn 是偶数"。

直接证明需要涉及复杂的分解。使用逆否证明:

逆否命题是"如果 nn 是奇数,则 n2n^2 是奇数"——这正是我们前面直接证明过的结论。

因此原命题成立。

何时使用逆否证明:当前提比结论更难直接处理时,逆否命题可能更易证明。

数学归纳法

数学归纳法(Mathematical Induction)是证明与自然数相关命题的重要方法。它包含两个步骤:

  1. 基础步骤(Base Case):证明当 n=n0n = n_0(起始值)时命题成立
  2. 归纳步骤(Inductive Step):假设当 n=kn = k 时命题成立(归纳假设),证明当 n=k+1n = k + 1 时命题也成立

例题:证明对所有正整数 nn,有 1+2+3++n=n(n+1)21 + 2 + 3 + \cdots + n = \frac{n(n+1)}{2}

证明

基础步骤:当 n=1n = 1 时,左边 =1= 1,右边 =1×22=1= \frac{1 \times 2}{2} = 1。命题成立。

归纳步骤:假设当 n=kn = k 时命题成立,即 1+2++k=k(k+1)21 + 2 + \cdots + k = \frac{k(k+1)}{2}

n=k+1n = k + 1 时: 1+2++k+(k+1)=k(k+1)2+(k+1)=k(k+1)+2(k+1)2=(k+1)(k+2)21 + 2 + \cdots + k + (k+1) = \frac{k(k+1)}{2} + (k+1) = \frac{k(k+1) + 2(k+1)}{2} = \frac{(k+1)(k+2)}{2}

这正是 n=k+1n = k + 1 时的公式。因此,由数学归纳法,命题对所有正整数成立。证毕。

强归纳法

强归纳法(Strong Induction)在归纳步骤中,假设对所有小于等于 kk 的值命题都成立,而不仅仅是 kk

适用场景

  • 证明中需要引用多个前面的情况
  • 递归定义的结构

例题:证明每个大于 1 的整数都可以表示为素数的乘积。

证明

基础步骤n=2n = 2 是素数,可以表示为自身的乘积。

归纳步骤:假设对所有 2mk2 \leq m \leq k 的整数,mm 都可以表示为素数的乘积。

考虑 n=k+1n = k + 1

  • 如果 k+1k + 1 是素数,它本身就是素数的乘积
  • 如果 k+1k + 1 是合数,则 k+1=a×bk + 1 = a \times b,其中 2a,bk2 \leq a, b \leq k

由归纳假设,aabb 都可以表示为素数的乘积,因此 k+1k + 1 也可以。证毕。

构造性证明

构造性证明通过具体构造一个对象来证明存在性命题。要证明 xP(x)\exists x \, P(x),我们显式地给出一个满足 PPxx

例题:证明存在两个无理数 aabb,使得 aba^b 是有理数。

证明

考虑 22\sqrt{2}^{\sqrt{2}}

情况 1:如果 22\sqrt{2}^{\sqrt{2}} 是有理数,则 a=2a = \sqrt{2}b=2b = \sqrt{2} 即为所求。

情况 2:如果 22\sqrt{2}^{\sqrt{2}} 是无理数,令 a=22a = \sqrt{2}^{\sqrt{2}}b=2b = \sqrt{2}。则: ab=(22)2=22×2=22=2a^b = (\sqrt{2}^{\sqrt{2}})^{\sqrt{2}} = \sqrt{2}^{\sqrt{2} \times \sqrt{2}} = \sqrt{2}^2 = 2

这是有理数。

无论哪种情况,都存在满足条件的无理数。证毕。

存在性证明

存在性证明有两种主要方法:

构造性证明:直接给出满足条件的对象。

非构造性证明:证明满足条件的对象必须存在,但不具体构造它。常用方法包括:

  • 反证法
  • 鸽巢原理
  • 计数论证

例题:证明存在无理数 aabb 使 aba^b 为有理数(非构造性版本)。

上面给出的证明虽然明确,但实际上没有告诉我们到底是哪种情况(22\sqrt{2}^{\sqrt{2}} 是有理数还是无理数)。这就是非构造性证明的特点:我们确定解存在,但不一定知道具体的解是什么。

唯一性证明

要证明"存在唯一的 xx 使得 P(x)P(x)",需要两步:

  1. 存在性:证明存在 xx 使得 P(x)P(x) 成立
  2. 唯一性:证明如果 P(x)P(x)P(y)P(y),则 x=yx = y

例题:证明每个整数有唯一的加法逆元。

证明

存在性:对于整数 nn,取 n-n。则 n+(n)=0n + (-n) = 0,所以逆元存在。

唯一性:假设 aabb 都是 nn 的加法逆元,即 n+a=0n + a = 0n+b=0n + b = 0

n+a=0n + a = 0a=na = -n。 从 n+b=0n + b = 0b=nb = -n

因此 a=ba = b。证毕。

分情况证明

当命题涉及多种情况时,可以分别证明每种情况,然后综合得出结论。

例题:证明对于任意整数 nnn2+nn^2 + n 是偶数。

证明

情况 1:nn 是偶数。 设 n=2kn = 2k,则 n2+n=4k2+2k=2(2k2+k)n^2 + n = 4k^2 + 2k = 2(2k^2 + k),是偶数。

情况 2:nn 是奇数。 设 n=2k+1n = 2k + 1,则 n2+n=(4k2+4k+1)+(2k+1)=4k2+6k+2=2(2k2+3k+1)n^2 + n = (4k^2 + 4k + 1) + (2k + 1) = 4k^2 + 6k + 2 = 2(2k^2 + 3k + 1),是偶数。

由排中律,nn 要么是偶数要么是奇数,因此 n2+nn^2 + n 总是偶数。证毕。

空真证明

要证明 pqp \to q,如果 pp 为假,则整个蕴含式为真(空真)。这在证明全称命题时特别有用。

例题:证明"所有会飞的猪都是粉红色的"。

证明:论域中不存在会飞的猪,因此对于所有 xx,前提" xx 是会飞的猪"为假。所以蕴含式"如果 xx 是会飞的猪,则 xx 是粉红色的"对任意 xx 都为真。证毕。

证明策略选择指南

命题形式推荐策略
pqp \to q直接证明、逆否证明、反证法
xP(x)\forall x \, P(x)任取 xx,证明 P(x)P(x)
xP(x)\exists x \, P(x)构造性证明或非构造性证明
!xP(x)\exists! x \, P(x)存在性 + 唯一性
¬p\neg p反证法
pqp \leftrightarrow q证明 pqp \to qqpq \to p
与自然数相关数学归纳法

常见证明错误

循环论证:在证明中使用了要证明的结论。这是最常见的逻辑错误。

例子:证明 1=21 = 2。 设 a=ba = b,则 a2=aba^2 = aba2b2=abb2a^2 - b^2 = ab - b^2(a+b)(ab)=b(ab)(a+b)(a-b) = b(a-b)a+b=ba+b = b2a=a2a = a2=12 = 1。 错误:当 a=ba = b 时,(ab)=0(a-b) = 0,除以 aba-b 是除以零,无效。

不当推广:从特殊情况错误地推广到一般情况。

忽略边界:归纳证明中忽略基础步骤,或递归定义中忽略基本情况。

推理规则

推理规则是从已知命题推导新命题的规则。正确的推理保证如果前提为真,则结论必然为真。

命题逻辑推理规则

假言推理(Modus Ponens)

pq,pq\frac{p \to q, \quad p}{\therefore q}

如果"如果下雨则地湿"为真,且"下雨了"为真,则"地湿"为真。

拒取式(Modus Tollens)

pq,¬q¬p\frac{p \to q, \quad \neg q}{\therefore \neg p}

如果"如果下雨则地湿"为真,且"地没湿"为真,则"没下雨"为真。

假言三段论

pq,qrpr\frac{p \to q, \quad q \to r}{\therefore p \to r}

这是蕴含的传递性。

析取三段论

pq,¬pq\frac{p \lor q, \quad \neg p}{\therefore q}

"或者今天是周末,或者是工作日"且"今天不是周末",则"今天是工作日"。

谓词逻辑推理规则

谓词逻辑引入量词后,需要新的推理规则来处理量化的陈述。核心思想是:通过实例化将量化的陈述转化为具体陈述,在布尔逻辑中推理,然后再推广回量化陈述。

全称实例化(Universal Instantiation)

从全称命题推出具体实例:

xP(x)P(c)\frac{\forall x \, P(x)}{\therefore P(c)}

含义:如果 P(x)P(x) 对所有 xx 都成立,那么对任何特定的 ccP(c)P(c) 也成立。

例子

  • 前提:所有人都会死。x(Human(x)Mortal(x))\forall x \, (Human(x) \to Mortal(x))
  • 推论:苏格拉底是人 \to 苏格拉底会死。Human(Socrates)Mortal(Socrates)Human(Socrates) \to Mortal(Socrates)

注意cc 可以是论域中的任意元素,包括具体个体或任意选择的元素。

# 全称实例化的直观理解
def universal_instantiation(all_statement, element):
"""
如果 P(x) 对所有 x 成立,则 P(c) 对特定 c 成立
"""
# all_statement 是一个函数,接受任意元素返回 True
return all_statement(element)

# 例子:所有正整数都有后继
def has_successor(n):
return n + 1 > n # 显然成立

# 实例化:5 有后继
print(has_successor(5)) # True

全称推广(Universal Generalization)

从关于任意元素的陈述推出全称命题:

P(c)xP(x)\frac{P(c)}{\therefore \forall x \, P(x)}

限制条件

  1. cc 必须是任意元素(arbitrary element)
  2. cc 不能在任何前提或未释放的假设中出现

含义:如果我们对任意选择的 cc(没有任何特殊性质)证明了 P(c)P(c),那么 P(x)P(x) 对所有 xx 成立。

例子:证明所有偶数的平方是偶数。

  1. nn 是任意偶数(这里 nn 是任意元素)
  2. n=2kn = 2k 对于某个整数 kk
  3. n2=4k2=2(2k2)n^2 = 4k^2 = 2(2k^2)
  4. 所以 n2n^2 是偶数
  5. 由全称推广:所有偶数的平方都是偶数

关键:在步骤 1 中,nn 是任意选择的,没有特殊性质,因此可以推广。

存在实例化(Existential Instantiation)

从存在命题推出具体实例:

xP(x)P(c)\frac{\exists x \, P(x)}{\therefore P(c^*)}

限制条件

  1. cc^* 必须是新引入的符号,之前未使用过
  2. cc^* 代表"某个满足 PP 的元素",但我们不知道具体是哪个

含义:如果存在某个 xx 使 P(x)P(x) 成立,那么我们可以给这个元素一个名字 cc^*,并断言 P(c)P(c^*)

例子

  • 前提:存在一个最大的素数。x(Prime(x)y(Prime(y)yx))\exists x \, (Prime(x) \land \forall y \, (Prime(y) \to y \leq x))
  • 实例化:设 pp^* 是最大的素数。Prime(p)y(Prime(y)yp)Prime(p^*) \land \forall y \, (Prime(y) \to y \leq p^*)

注意:使用星号标记存在实例化引入的元素,以区别于任意元素。

存在推广(Existential Generalization)

从具体实例推出存在命题:

P(c)xP(x)\frac{P(c)}{\therefore \exists x \, P(x)}

含义:如果 P(c)P(c) 对某个具体元素 cc 成立,那么存在 xx 使 P(x)P(x) 成立。

例子

  • 前提:7 是素数。Prime(7)Prime(7)
  • 推广:存在一个素数。xPrime(x)\exists x \, Prime(x)

实例化与推广的关系

这四条规则形成两对互逆的操作:

关键区别

  • 全称实例化可以实例化为任意元素 cc(包括已知的具体元素或新引入的任意元素)
  • 存在实例化必须使用新的符号 cc^*,因为"那个存在的元素"是未知的

推理规则的正确使用顺序

在证明中,正确的实例化顺序至关重要:

规则:先进行存在实例化,再进行全称实例化。

原因:全称实例化可以选择任意元素,而存在实例化必须选择新元素。如果先做全称实例化,可能已经"占用"了某个符号,导致存在实例化无法使用该符号。

例子:证明"如果存在猫,且所有猫都会爬树,则存在会爬树的动物。"

前提:

  1. xCat(x)\exists x \, Cat(x)
  2. x(Cat(x)ClimbTree(x))\forall x \, (Cat(x) \to ClimbTree(x))

正确证明

[1] ∃x Cat(x)                          前提
[2] ∀x (Cat(x) → ClimbTree(x)) 前提
[3] Cat(c*) 存在实例化 [1]
[4] Cat(c*) → ClimbTree(c*) 全称实例化 [2],使用同一个 c*
[5] ClimbTree(c*) 假言推理 [3], [4]
[6] ∃x ClimbTree(x) 存在推广 [5]

错误示范:如果先做全称实例化 [2],得到 Cat(c)ClimbTree(c)Cat(c) \to ClimbTree(c),再做存在实例化 [1],必须用 dd^*,得到 Cat(d)Cat(d^*)。现在 ccdd^* 无法关联,推理失败。

量词交换规则

除了实例化和推广规则,还有两条重要的等价规则:

量词否定(Quantifier Negation)

¬xP(x)x¬P(x)\neg \forall x \, P(x) \equiv \exists x \, \neg P(x)

¬xP(x)x¬P(x)\neg \exists x \, P(x) \equiv \forall x \, \neg P(x)

直观理解

  • "并非所有人都喜欢学习" = "存在一个人不喜欢学习"
  • "不存在完美的人" = "所有人都不完美"

这些规则是德摩根律在量词上的推广。\forall 类似于无穷大的合取,\exists 类似于无穷大的析取。

推理规则的完备性

命题逻辑:假言推理和假言三段论对于 Horn 子句(最多一个正文字的子句)是完备的。对于一般命题公式,消解法是完备的。

谓词逻辑

  • 对于只含 Horn 子句的谓词逻辑,推广的假言推理是完备的
  • 对于一般谓词逻辑,消解法配合合一算法是完备的

重要定理:谓词逻辑是半可判定的。如果公式是有效的,存在算法能在有限步内证明它;但如果公式不是有效的,可能永远无法确定。

证明的有效性

一个证明是有效的,当且仅当如果所有前提为真,则结论必然为真。检验证明有效性可以使用真值表或推理规则。

谓词逻辑证明实例

理解谓词逻辑推理规则的最好方式是通过具体例子。以下是几个经典的证明实例,展示了如何正确使用量词推理规则。

实例 1:苏格拉底论证

前提

  1. 所有人都会死。x(Human(x)Mortal(x))\forall x \, (Human(x) \to Mortal(x))
  2. 苏格拉底是人。Human(Socrates)Human(Socrates)

结论:苏格拉底会死。Mortal(Socrates)Mortal(Socrates)

证明

[1] ∀x (Human(x) → Mortal(x))     前提
[2] Human(Socrates) 前提
[3] Human(Socrates) → Mortal(Socrates) 全称实例化 [1]
[4] Mortal(Socrates) 假言推理 [2], [3]

分析:这是一个直接的应用。全称实例化允许我们将全称量词具体化为特定的个体苏格拉底。

实例 2:存在性结论

前提

  1. 所有猫都会爬树。x(Cat(x)ClimbTree(x))\forall x \, (Cat(x) \to ClimbTree(x))
  2. 存在猫。xCat(x)\exists x \, Cat(x)

结论:存在会爬树的动物。xClimbTree(x)\exists x \, ClimbTree(x)

证明

[1] ∀x (Cat(x) → ClimbTree(x))    前提
[2] ∃x Cat(x) 前提
[3] Cat(c*) 存在实例化 [2],引入新常量 c*
[4] Cat(c*) → ClimbTree(c*) 全称实例化 [1]
[5] ClimbTree(c*) 假言推理 [3], [4]
[6] ∃x ClimbTree(x) 存在推广 [5]

关键点

  • 必须先进行存在实例化,再进行全称实例化
  • cc^* 是新引入的常量,代表"某个存在的猫"
  • 存在推广从具体实例推出存在性结论

实例 3:涉及多个量词的证明

前提

  1. 每个人都有父亲。xyFather(y,x)\forall x \exists y \, Father(y, x)
  2. 父亲比自己年长。xy(Father(x,y)Older(x,y))\forall x \forall y \, (Father(x, y) \to Older(x, y))

结论:每个人都有比自己年长的人。xyOlder(y,x)\forall x \exists y \, Older(y, x)

证明

[1] ∀x ∃y Father(y, x)            前提
[2] ∀x ∀y (Father(x, y) → Older(x, y)) 前提

[3] 设 a 为任意元素 开始全称推广

[4] ∃y Father(y, a) 全称实例化 [1]
[5] Father(f(a), a) 存在实例化 [4],引入 f(a) 作为 a 的父亲
注意:f(a) 是依赖于 a 的元素

[6] ∀y (Father(y, a) → Older(y, a)) 全称实例化 [2]
[7] Father(f(a), a) → Older(f(a), a) 全称实例化 [6]
[8] Older(f(a), a) 假言推理 [5], [7]

[9] ∃y Older(y, a) 存在推广 [8]

[10] ∀x ∃y Older(y, x) 全称推广 [3]-[9]

注意:这个证明使用了函数符号 f(a)f(a) 表示"a 的父亲"。在标准的一阶逻辑中,存在实例化引入的常量可以依赖于之前选择的元素。

实例 4:矛盾证明

前提

  1. 所有学生都完成了作业。x(Student(x)Finished(x))\forall x \, (Student(x) \to Finished(x))
  2. 有人没完成作业。x¬Finished(x)\exists x \, \neg Finished(x)

结论:存在非学生。x¬Student(x)\exists x \, \neg Student(x)

证明

[1] ∀x (Student(x) → Finished(x)) 前提
[2] ∃x ¬Finished(x) 前提

[3] ¬Finished(c*) 存在实例化 [2]

[4] 假设 Student(c*) 假设(用于反证)

[5] Student(c*) → Finished(c*) 全称实例化 [1]
[6] Finished(c*) 假言推理 [4], [5]

[7] Finished(c*) ∧ ¬Finished(c*) 合取引入 [3], [6],矛盾!

[8] ¬Student(c*) 否定引入 [4]-[7]
[9] ∃x ¬Student(x) 存在推广 [8]

分析:这个证明展示了如何结合存在实例化和矛盾法。我们假设"那个没完成作业的人是学生",然后导出矛盾。

常见错误警示

错误 1:全称推广应用于特定元素

错误示例:
[1] 7 是素数 前提
[2] ∀x Prime(x) 错误的全称推广!

77 是一个特定的元素,不能对其进行全称推广。全称推广只适用于"任意"元素。

错误 2:存在实例化使用已存在的常量

错误示例:
[1] ∀x (P(x) → Q(x)) 前提
[2] ∃x P(x) 前提
[3] P(a) 假设:先做了全称实例化得到 P(a)→Q(a)
[4] P(a) 错误!存在实例化不能用已存在的 a

正确做法是先进行存在实例化,引入新常量,再进行全称实例化。

错误 3:混淆存在实例化和存在推广

错误示例:
[1] ∃x P(x) 前提
[2] P(c) 错误!不能用普通常量 c

存在实例化引入的元素必须是新常量,通常用 cc^* 标记,表示"某个存在的、但不具体知道的元素"。

范式

范式是将复合命题转化为标准形式的方法,便于判断命题的性质和进行自动推理。在计算机科学中,范式在逻辑编程、SAT 求解器、定理证明等领域有广泛应用。

基本概念

文字(Literal):命题变量或其否定。例如,pp¬p\neg p 都是文字。pp 称为正文字,¬p\neg p 称为负文字。

子句(Clause):若干文字的析取。例如,p¬qrp \lor \neg q \lor r 是一个子句。在子句中,文字之间是"或"的关系。

合取范式(Conjunctive Normal Form,CNF):若干子句的合取。整个公式是子句的"与"运算。

F=C1C2CnF = C_1 \land C_2 \land \cdots \land C_n

其中每个 CiC_i 是一个子句(文字的析取)。

例子(p¬q)(¬pr)(qr)(p \lor \neg q) \land (\neg p \lor r) \land (q \lor r) 是 CNF。

析取范式(Disjunctive Normal Form,DNF):若干合取项的析取。整个公式是合取项的"或"运算。

F=D1D2DnF = D_1 \lor D_2 \lor \cdots \lor D_n

其中每个 DiD_i 是若干文字的合取。

例子(p¬q)(¬pr)(qr)(p \land \neg q) \lor (\neg p \land r) \lor (q \land r) 是 DNF。

CNF 与 DNF 的比较

特性CNFDNF
结构子句的合取合取项的析取
子句/项内部文字的析取文字的合取
可满足性检测需要每个子句都为真只需一个合取项为真
应用SAT 求解器、消解法直接判断可满足性

DNF 判断可满足性很容易:只要有一个合取项不包含矛盾(同时包含 pp¬p\neg p),公式就可满足。但将一般公式转换为 DNF 可能导致指数级膨胀。

CNF 虽然判断可满足性较难,但转换过程可以高效进行,并且是消解法推理的基础。

转换为 CNF 的算法

任何命题公式都可以转换为等价的 CNF。以下是标准的六步转换算法:

步骤 1:消除蕴含和等价

使用等价关系:

  • pq¬pqp \to q \equiv \neg p \lor q
  • pq(pq)(qp)(¬pq)(¬qp)p \leftrightarrow q \equiv (p \to q) \land (q \to p) \equiv (\neg p \lor q) \land (\neg q \lor p)

步骤 2:将否定内移

使用德摩根律将否定推到命题变量之前:

  • ¬(pq)¬p¬q\neg(p \land q) \equiv \neg p \lor \neg q
  • ¬(pq)¬p¬q\neg(p \lor q) \equiv \neg p \land \neg q

步骤 3:消除双重否定

  • ¬¬pp\neg \neg p \equiv p

经过这三步,公式变为"否定范式"(Negation Normal Form,NNF),即否定只作用于命题变量。

步骤 4:分配析取到合取

使用分配律将 \lor 分配到 \land 中:

  • p(qr)(pq)(pr)p \lor (q \land r) \equiv (p \lor q) \land (p \lor r)
  • (pq)r(pr)(qr)(p \land q) \lor r \equiv (p \lor r) \land (q \lor r)

重复应用直到无法再分配。

转换示例

问题:将 (pq)r(p \to q) \to r 转换为 CNF。

解答

步骤 1:消除蕴含 pq¬pqp \to q \equiv \neg p \lor q (pq)r¬(¬pq)r(p \to q) \to r \equiv \neg(\neg p \lor q) \lor r

步骤 2:将否定内移(德摩根律) ¬(¬pq)¬¬p¬qp¬q\neg(\neg p \lor q) \equiv \neg \neg p \land \neg q \equiv p \land \neg q 所以: ¬(¬pq)r(p¬q)r\neg(\neg p \lor q) \lor r \equiv (p \land \neg q) \lor r

步骤 3:消除双重否定 已经完成(p¬qp \land \neg q

步骤 4:分配析取到合取 (p¬q)r(pr)(¬qr)(p \land \neg q) \lor r \equiv (p \lor r) \land (\neg q \lor r)

最终 CNF:(pr)(¬qr)(p \lor r) \land (\neg q \lor r)

从真值表构造 DNF

给定真值表,可以直接构造 DNF:

  1. 找出所有使公式为真的行
  2. 对每一行,构造一个合取项:变量为真则用正文字,为假则用负文字
  3. 将所有合取项用析取连接

例子:构造公式 pqp \to q 的 DNF

ppqqpqp \to q
TTT
TFF
FTT
FFT

使公式为真的行是 (T,T)、(F,T)、(F,F):

  • (T,T):pqp \land q
  • (F,T):¬pq\neg p \land q
  • (F,F):¬p¬q\neg p \land \neg q

DNF:(pq)(¬pq)(¬p¬q)(p \land q) \lor (\neg p \land q) \lor (\neg p \land \neg q)

可以化简:(pq)(¬pq)(¬p¬q)=q(¬p¬q)=q¬p=¬pq(p \land q) \lor (\neg p \land q) \lor (\neg p \land \neg q) = q \lor (\neg p \land \neg q) = q \lor \neg p = \neg p \lor q

这正是 pqp \to q 的另一种形式,验证了转换的正确性。

范式的应用

SAT 问题:判断一个命题公式是否可满足。将公式转换为 CNF 后,可以使用高效的 SAT 求解器(如 DPLL 算法、CDCL 算法)来求解。

消解法:一种自动推理方法,只适用于 CNF 形式的公式。基本规则是:

{pA,¬pB}\{p \lor A, \neg p \lor B\} 推出 ABA \lor B

其中 AABB 是子句的剩余部分。如果消解出空子句,则原公式不可满足。

def to_cnf(formula):
"""
将命题公式转换为 CNF(简化版)
实际实现需要处理语法树
"""
# 步骤1: 消除蕴含
# 步骤2: 德摩根律
# 步骤3: 消除双重否定
# 步骤4: 分配律
pass

# 示例:验证 CNF 可满足性(简单情况)
def is_satisfiable_cnf(clauses):
"""
检查 CNF 是否可满足(简化版)
clauses: [[('p', True), ('q', False)], ...]
每个子句是 (变量, 是否为正文字) 的列表
"""
# 使用回溯法或 DPLL 算法
pass

前束范式

前束范式(Prenex Normal Form,PNF)是谓词逻辑中的一种标准形式,它将所有量词移到公式的最前面。这种形式在自动定理证明、逻辑编程和数据库查询优化中有重要应用。

前束范式的定义

一个谓词逻辑公式处于前束范式,当且仅当它具有以下形式:

Q1x1Q2x2QnxnBQ_1 x_1 Q_2 x_2 \cdots Q_n x_n \, B

其中:

  • 每个 QiQ_i 是量词(\forall\exists
  • x1,x2,,xnx_1, x_2, \ldots, x_n 是变量
  • BB 是不含量词的公式,称为母式(Matrix)
  • 量词序列 Q1x1Q2x2QnxnQ_1 x_1 Q_2 x_2 \cdots Q_n x_n 称为前束词(Prefix)

特殊情况:不含任何量词的公式本身就是前束范式(前束词为空)。

例子

公式是否为前束范式
xyP(x,y)\forall x \exists y \, P(x, y)
xP(x)yQ(y)\forall x \, P(x) \land \exists y \, Q(y)否(量词在内部)
xy¬R(x,y)S(x,y)\forall x \forall y \, \neg R(x, y) \lor S(x, y)
¬xP(x)\neg \forall x \, P(x)否(否定在量词前面)

为什么需要前束范式?

前束范式的价值体现在以下几个方面:

统一处理:将量词集中在公式开头,便于分析和处理。许多自动推理算法(如消解法)要求输入公式处于前束范式。

简化推理:前束范式将量词"提纯",使我们可以先处理量词部分,再处理无量词的母式。

Skolem 化的准备:前束范式是 Skolem 化的预备步骤,后者用于消除存在量词,将公式转化为只含全称量词的形式。

转换为前束范式的算法

任何谓词逻辑公式都可以转换为等价的前束范式。转换分为四个步骤:

步骤 1:消除蕴含和等价

使用逻辑等价式:

  • AB¬ABA \to B \equiv \neg A \lor B
  • AB(¬AB)(A¬B)A \leftrightarrow B \equiv (\neg A \lor B) \land (A \lor \neg B)

步骤 2:将否定内移

使用量词否定规则和德摩根律,将否定推到原子公式之前:

  • ¬xA(x)x¬A(x)\neg \forall x \, A(x) \equiv \exists x \, \neg A(x)
  • ¬xA(x)x¬A(x)\neg \exists x \, A(x) \equiv \forall x \, \neg A(x)
  • ¬(AB)¬A¬B\neg(A \land B) \equiv \neg A \lor \neg B
  • ¬(AB)¬A¬B\neg(A \lor B) \equiv \neg A \land \neg B
  • ¬¬AA\neg \neg A \equiv A

经过这一步,公式变为否定范式(NNF),即否定只作用于原子公式。

步骤 3:标准化变量

当公式中同一变量名被多个量词约束时,需要重命名以避免冲突。规则是:将约束变量的出现替换为新的、未被使用的变量名。

例子xP(x)xQ(x)\forall x \, P(x) \land \exists x \, Q(x)

两个量词都使用变量 xx,需要标准化。将第二个 xx 重命名为 yy

xP(x)yQ(y)\forall x \, P(x) \land \exists y \, Q(y)

步骤 4:将量词移到前面

使用量词移动等价式,将量词逐步移到公式最前面。

量词移动规则

以下是移动量词的关键等价式,其中 AA 是不含自由变量 xx 的公式,B(x)B(x) 是可能含自由变量 xx 的公式:

量词与合取

AxB(x)x(AB(x))A \land \exists x \, B(x) \equiv \exists x \, (A \land B(x))

AxB(x)x(AB(x))A \land \forall x \, B(x) \equiv \forall x \, (A \land B(x))

xA(x)yB(y)xy(A(x)B(y))\exists x \, A(x) \land \exists y \, B(y) \equiv \exists x \exists y \, (A(x) \land B(y))

xA(x)yB(y)xy(A(x)B(y))\forall x \, A(x) \land \forall y \, B(y) \equiv \forall x \forall y \, (A(x) \land B(y))

量词与析取

AxB(x)x(AB(x))A \lor \exists x \, B(x) \equiv \exists x \, (A \lor B(x))

AxB(x)x(AB(x))A \lor \forall x \, B(x) \equiv \forall x \, (A \lor B(x))

xA(x)yB(y)xy(A(x)B(y))\exists x \, A(x) \lor \exists y \, B(y) \equiv \exists x \exists y \, (A(x) \lor B(y))

xA(x)yB(y)≢xy(A(x)B(y))\forall x \, A(x) \lor \forall y \, B(y) \not\equiv \forall x \forall y \, (A(x) \lor B(y))

注意最后一条xA(x)xB(x)\forall x \, A(x) \lor \forall x \, B(x)x(A(x)B(x))\forall x \, (A(x) \lor B(x)) 不等价。前者要求"所有 xx 都满足 AA 或所有 xx 都满足 BB",后者只要求"每个 xx 满足 AABB"。前者更强。

量词顺序

同类量词可以交换顺序:

xyA(x,y)yxA(x,y)\forall x \forall y \, A(x, y) \equiv \forall y \forall x \, A(x, y)

xyA(x,y)yxA(x,y)\exists x \exists y \, A(x, y) \equiv \exists y \exists x \, A(x, y)

但不同类量词一般不能交换

xyA(x,y)≢yxA(x,y)\forall x \exists y \, A(x, y) \not\equiv \exists y \forall x \, A(x, y)

转换示例

例 1:将 x(P(x)Q(x))xQ(x)\forall x \, (P(x) \to Q(x)) \land \exists x \, Q(x) 转换为前束范式。

解答

步骤 1:消除蕴含 x(¬P(x)Q(x))xQ(x)\forall x \, (\neg P(x) \lor Q(x)) \land \exists x \, Q(x)

步骤 2:否定已在原子公式前,无需移动。

步骤 3:标准化变量。将第二个 xx 重命名为 yyx(¬P(x)Q(x))yQ(y)\forall x \, (\neg P(x) \lor Q(x)) \land \exists y \, Q(y)

步骤 4:移动量词。先移动 y\exists yy[x(¬P(x)Q(x))Q(y)]\exists y \, [\forall x \, (\neg P(x) \lor Q(x)) \land Q(y)]

再移动 x\forall xyx[(¬P(x)Q(x))Q(y)]\exists y \forall x \, [(\neg P(x) \lor Q(x)) \land Q(y)]

这就是前束范式。

例 2:将 ¬(xP(x)yQ(y))\neg(\forall x \, P(x) \to \exists y \, Q(y)) 转换为前束范式。

解答

步骤 1:消除蕴含 ¬(¬xP(x)yQ(y))\neg(\neg \forall x \, P(x) \lor \exists y \, Q(y))

步骤 2:将否定内移(德摩根律) ¬¬xP(x)¬yQ(y)\neg \neg \forall x \, P(x) \land \neg \exists y \, Q(y) xP(x)y¬Q(y)\forall x \, P(x) \land \forall y \, \neg Q(y)

步骤 3:变量已标准化。

步骤 4:移动量词 xy(P(x)¬Q(y))\forall x \forall y \, (P(x) \land \neg Q(y))

例 3:将 xP(x)yQ(y)\exists x \, P(x) \to \forall y \, Q(y) 转换为前束范式。

解答

步骤 1:消除蕴含 ¬xP(x)yQ(y)\neg \exists x \, P(x) \lor \forall y \, Q(y)

步骤 2:将否定内移 x¬P(x)yQ(y)\forall x \, \neg P(x) \lor \forall y \, Q(y)

步骤 3:变量已标准化。

步骤 4:这里遇到了一个关键问题。x¬P(x)yQ(y)\forall x \, \neg P(x) \lor \forall y \, Q(y) 不能简单地合并为 xy(¬P(x)Q(y))\forall x \forall y \, (\neg P(x) \lor Q(y)),因为这两者不等价。

正确的方法是保持原样,或者使用更复杂的技术(如 Skolem 化)。作为前束范式转换,我们得到:

x¬P(x)yQ(y)\forall x \, \neg P(x) \lor \forall y \, Q(y)

这不是标准的前束范式。要解决这个问题,需要注意到:如果我们将 xA(x)yB(y)\forall x \, A(x) \lor \forall y \, B(y) 看作一个整体,可以写成:

xy(¬P(x)Q(y))\forall x \forall y \, (\neg P(x) \lor Q(y))

虽然这两者不完全等价,但在某些情况下(如检查有效性而非可满足性)这种转换是可接受的。更严格的做法是保持公式原样。

前束范式的局限性

前束范式虽然有用,但也有局限:

  1. 可读性下降:将所有量词移到前面可能使公式的直观含义变得不清晰。

  2. 非唯一性:同一公式可能有多个不同的前束范式表示。

  3. 量词顺序敏感:移动量词可能改变原公式的含义,特别是当混合使用全称和存在量词时。

  4. 非等价转换:某些情况下,前束范式转换不能保持严格等价性。

与 CNF 的关系

将谓词逻辑公式转换为 CNF 通常需要先转换为前束范式:

  1. 转换为前束范式
  2. 进行 Skolem 化(消除存在量词)
  3. 将母式转换为 CNF

这个组合形式(Skolem CNF)是消解法推理的输入格式。

def to_prenex_normal_form(formula):
"""
将谓词逻辑公式转换为前束范式的概念框架
实际实现需要语法树操作
"""
# 步骤1: 消除蕴含和等价
# 步骤2: 将否定内移
# 步骤3: 标准化变量
# 步骤4: 移动量词到前面
pass

# 示例:验证量词移动规则
def demonstrate_quantifier_rules():
"""演示量词移动规则"""

# ∀x A(x) ∧ ∀y B(y) ≡ ∀x∀y (A(x) ∧ B(y))
# 示例:"所有学生都学习" ∧ "所有老师都教书"
# 等价于:"对所有x和y,如果x是学生则学习,如果y是老师则教书"

# ∃x A(x) ∧ ∀y B(y) ≡ ∃x∀y (A(x) ∧ B(y))
# 注意:通常存在量词应放在全称量词前面,以保持语义

pass

谓词逻辑的等价式与蕴含式

谓词逻辑有丰富的等价式和蕴含式,它们是进行逻辑推理和公式化简的重要工具。

量词与否定

这是最基本的一组等价式,已在前面讨论:

¬xP(x)x¬P(x)\neg \forall x \, P(x) \equiv \exists x \, \neg P(x)

¬xP(x)x¬P(x)\neg \exists x \, P(x) \equiv \forall x \, \neg P(x)

量词与合取、析取

分配性规则

全称量词对合取可分配: x(P(x)Q(x))xP(x)xQ(x)\forall x \, (P(x) \land Q(x)) \equiv \forall x \, P(x) \land \forall x \, Q(x)

存在量词对析取可分配: x(P(x)Q(x))xP(x)xQ(x)\exists x \, (P(x) \lor Q(x)) \equiv \exists x \, P(x) \lor \exists x \, Q(x)

不可分配的情况

全称量词对析取不可分配x(P(x)Q(x))≢xP(x)xQ(x)\forall x \, (P(x) \lor Q(x)) \not\equiv \forall x \, P(x) \lor \forall x \, Q(x)

反例:设论域为整数,P(x)P(x) 表示"xx 是偶数",Q(x)Q(x) 表示"xx 是奇数"。左边说"每个整数是偶数或奇数",为真;右边说"所有整数都是偶数,或所有整数都是奇数",为假。

存在量词对合取不可分配x(P(x)Q(x))≢xP(x)xQ(x)\exists x \, (P(x) \land Q(x)) \not\equiv \exists x \, P(x) \land \exists x \, Q(x)

反例:同一论域,P(x)P(x) 表示"xx 是偶数",Q(x)Q(x) 表示"xx 是奇数"。左边说"存在一个既是偶数又是奇数的整数",为假;右边说"存在偶数,且存在奇数",为真。

量词与蕴含

蕴含式涉及量词时的等价关系需要特别小心:

x(P(x)Q(x))≢xP(x)xQ(x)\forall x \, (P(x) \to Q(x)) \not\equiv \forall x \, P(x) \to \forall x \, Q(x)

但以下蕴含成立: x(P(x)Q(x))(xP(x)xQ(x))\forall x \, (P(x) \to Q(x)) \Rightarrow (\forall x \, P(x) \to \forall x \, Q(x))

例子:设 P(x)P(x) 表示"xx 能被 4 整除",Q(x)Q(x) 表示"xx 能被 2 整除"。

  • x(P(x)Q(x))\forall x \, (P(x) \to Q(x)):"能被 4 整除则能被 2 整除",为真。
  • xP(x)xQ(x)\forall x \, P(x) \to \forall x \, Q(x):"如果所有数都能被 4 整除,则所有数都能被 2 整除",也为真(因为前件为假)。

但反向不成立。设论域为 {2,4}\{2, 4\}

  • xP(x)\forall x \, P(x) 为假(2 不能被 4 整除)
  • xQ(x)\forall x \, Q(x) 为真
  • 所以 xP(x)xQ(x)\forall x \, P(x) \to \forall x \, Q(x) 为真
  • x(P(x)Q(x))\forall x \, (P(x) \to Q(x)) 为假(因为 P(2)P(2) 为假而 Q(2)Q(2) 为真,但 P(4)P(4) 为真而... 实际上这个例子中它也为真)

更清晰的例子:设论域为 {1,2}\{1, 2\}P(1)P(1) 为真,P(2)P(2) 为假,Q(1)Q(1) 为假,Q(2)Q(2) 为真。

  • x(P(x)Q(x))\forall x \, (P(x) \to Q(x)):检查 P(1)Q(1)=TF=FP(1) \to Q(1) = T \to F = F,所以整体为假。
  • xP(x)xQ(x)\forall x \, P(x) \to \forall x \, Q(x):前件 P(1)P(2)=TF=FP(1) \land P(2) = T \land F = F,所以蕴含式为真。

双量词等价式

当公式含有两个量词时,有许多有用的等价式:

相同量词可交换

xyP(x,y)yxP(x,y)\forall x \forall y \, P(x, y) \equiv \forall y \forall x \, P(x, y)

xyP(x,y)yxP(x,y)\exists x \exists y \, P(x, y) \equiv \exists y \exists x \, P(x, y)

不同量词不可交换

xyP(x,y)≢yxP(x,y)\forall x \exists y \, P(x, y) \not\equiv \exists y \forall x \, P(x, y)

例子:设 P(x,y)P(x, y) 表示"xxyy"。

  • xyP(x,y)\forall x \exists y \, P(x, y):"每个人都爱某个人",这是可能的。
  • yxP(x,y)\exists y \forall x \, P(x, y):"存在一个人被所有人爱",这更难满足。

前者蕴含后者不成立,但后者蕴含前者成立: yxP(x,y)xyP(x,y)\exists y \forall x \, P(x, y) \Rightarrow \forall x \exists y \, P(x, y)

谓词逻辑蕴含式总结

以下是一些重要的谓词逻辑蕴含式(ABA \Rightarrow B 表示 ABA \models B):

前提结论说明
xP(x)\forall x \, P(x)xP(x)\exists x \, P(x)全称蕴含存在(论域非空时)
xyP(x,y)\forall x \forall y \, P(x, y)yxP(x,y)\forall y \forall x \, P(x, y)全称量词可交换
xyP(x,y)\exists x \exists y \, P(x, y)yxP(x,y)\exists y \exists x \, P(x, y)存在量词可交换
yxP(x,y)\exists y \forall x \, P(x, y)xyP(x,y)\forall x \exists y \, P(x, y)强存在蕴含弱存在
x(P(x)Q(x))\forall x \, (P(x) \land Q(x))xP(x)xQ(x)\forall x \, P(x) \land \forall x \, Q(x)等价关系
xP(x)xQ(x)\exists x \, P(x) \lor \exists x \, Q(x)x(P(x)Q(x))\exists x \, (P(x) \lor Q(x))等价关系
def verify_quantifier_equivalence():
"""
验证量词等价式的示例代码
使用有限论域进行验证
"""
# 定义一个有限论域
domain = [1, 2, 3, 4, 5]

# 定义谓词
def is_even(x):
return x % 2 == 0

def is_positive(x):
return x > 0

# 验证: ∀x(P(x)∧Q(x)) ≡ ∀x P(x) ∧ ∀x Q(x)
left = all(is_even(x) and is_positive(x) for x in domain)
right = all(is_even(x) for x in domain) and all(is_positive(x) for x in domain)
print(f"∀x(P(x)∧Q(x)): {left}")
print(f"∀x P(x) ∧ ∀x Q(x): {right}")
print(f"等价: {left == right}")

# 验证: ∃x(P(x)∧Q(x)) ≢ ∃x P(x) ∧ ∃x Q(x)
left = any(is_even(x) and x > 3 for x in domain) # P: 偶数, Q: > 3
right = any(is_even(x) for x in domain) and any(x > 3 for x in domain)
print(f"\n∃x(P(x)∧Q(x)): {left}") # 4 是偶数且 > 3,为 True
print(f"∃x P(x) ∧ ∃x Q(x): {right}") # 存在偶数且存在 > 3 的数,为 True
# 这个例子中两者相等,需要找一个不等的例子

# 更好的例子
# P(x): x 是偶数, Q(x): x 是奇数
left = any(x % 2 == 0 and x % 2 == 1 for x in domain) # 永远为 False
right = any(x % 2 == 0 for x in domain) and any(x % 2 == 1 for x in domain) # True
print(f"\n存在偶数且奇数的数: {left}") # False
print(f"存在偶数且存在奇数: {right}") # True
print(f"不等价: {left != right}")

Skolem化

Skolem化(Skolemization)是将前束范式中的存在量词消除的过程,得到只含全称量词的公式。这在自动定理证明、逻辑编程和数据库查询优化中有重要应用。理解Skolem化对于掌握现代逻辑系统的实现至关重要。

Skolem化的定义

Skolem化的核心思想是:如果存在某个元素满足条件,我们可以给它一个名字(常量或函数),而不必显式地用量词来声明它的存在。

Skolem常量:当存在量词不在任何全称量词的作用域内时,用一个新的常量符号替换存在量词约束的变量。

Skolem函数:当存在量词在某些全称量词的作用域内时,用一个新的函数符号替换存在量词约束的变量,该函数依赖于这些全称量词约束的变量。

Skolem化算法

步骤 1:将公式转换为前束范式。

步骤 2:从左到右扫描量词序列,对每个存在量词 y\exists y

  • 如果 yy 前面没有全称量词,引入一个新常量 cc(Skolem常量),用 cc 替换公式中所有的 yy,删除 y\exists y
  • 如果 yy 前面有全称量词 x1,x2,,xk\forall x_1, \forall x_2, \ldots, \forall x_k,引入一个新的 kk 元函数符号 ff(Skolem函数),用 f(x1,x2,,xk)f(x_1, x_2, \ldots, x_k) 替换公式中所有的 yy,删除 y\exists y

步骤 3:删除所有剩余的全称量词(因为现在所有变量都由全称量词约束,可以省略)。

Skolem化示例

例 1:Skolem化 xP(x)\exists x \, P(x)

没有前置的全称量词,所以引入Skolem常量 ccP(c)P(c)

这表示"存在某个特定元素 cc 使得 P(c)P(c) 为真"。

例 2:Skolem化 xyP(x,y)\forall x \exists y \, P(x, y)

存在量词 y\exists y 在全称量词 x\forall x 的作用域内,所以 yy 依赖于 xx。引入Skolem函数 f(x)f(x)xP(x,f(x))\forall x \, P(x, f(x))

这可以理解为"对于每个 xx,存在一个依赖于 xx 的元素 f(x)f(x),使得 P(x,f(x))P(x, f(x)) 成立"。

例 3:Skolem化 xyzP(x,y,z)\forall x \forall y \exists z \, P(x, y, z)

存在量词 z\exists zx\forall xy\forall y 的作用域内,所以 zz 依赖于 xxyyxyP(x,y,f(x,y))\forall x \forall y \, P(x, y, f(x, y))

例 4:Skolem化 xyzP(x,y,z)\exists x \forall y \exists z \, P(x, y, z)

  • x\exists x 没有前置的全称量词,用常量 cc 替换:yzP(c,y,z)\forall y \exists z \, P(c, y, z)
  • z\exists zy\forall y 的作用域内,用一元函数 f(y)f(y) 替换:yP(c,y,f(y))\forall y \, P(c, y, f(y))

Skolem化的正确性

重要性质:Skolem化不保持逻辑等价,但保持可满足性。

具体来说:

  • 如果原公式可满足,则Skolem化后的公式也可满足
  • 如果Skolem化后的公式可满足,则原公式也可满足

但原公式与Skolem化后的公式不等价。例如:

xP(x)\exists x \, P(x)P(c)P(c) 不等价。前者说"存在某个元素满足 PP",后者说"特定元素 cc 满足 PP"。后者蕴含前者,但前者不蕴含后者。

Skolem范式

经过Skolem化后得到的只含全称量词的公式,称为Skolem范式(Skolem Normal Form)。在自动定理证明中,通常进一步将母式转换为CNF,得到Skolem CNF

完整转换流程

  1. 消除蕴含和等价
  2. 将否定内移(得到否定范式NNF)
  3. 转换为前束范式
  4. Skolem化消除存在量词
  5. 将母式转换为CNF
  6. 省略全称量词

示例:将 x(P(x)yQ(x,y))\forall x (P(x) \to \exists y Q(x, y)) 转换为Skolem CNF。

步骤 1:消除蕴含 x(¬P(x)yQ(x,y))\forall x (\neg P(x) \lor \exists y Q(x, y))

步骤 2:否定已内移

步骤 3:前束范式 xy(¬P(x)Q(x,y))\forall x \exists y (\neg P(x) \lor Q(x, y))

步骤 4:Skolem化。y\exists yx\forall x 作用域内,用 f(x)f(x) 替换 yyx(¬P(x)Q(x,f(x)))\forall x (\neg P(x) \lor Q(x, f(x)))

步骤 5:母式已是CNF形式(一个子句)

步骤 6:省略全称量词 ¬P(x)Q(x,f(x))\neg P(x) \lor Q(x, f(x))

Skolem化的应用

自动定理证明:Skolem CNF是消解法(Resolution)的输入格式。消解法是一种强有力的自动推理方法,广泛应用于定理证明器中。

逻辑编程:Prolog等逻辑编程语言的基础是Horn子句,而Horn子句可以看作Skolem CNF的特殊形式。

数据库查询:SQL查询优化中,存在量词的处理与Skolem化有密切关系。

def skolemize(formula):
"""
Skolem化的概念框架
实际实现需要语法树操作和符号表管理
"""
# 1. 转换为前束范式
# 2. 扫描量词序列
# 3. 对每个存在量词引入Skolem常量或函数
# 4. 删除存在量词
pass

# 示例理解
def skolem_example():
"""Skolem化示例的直观理解"""

# ∀x∃y Parent(y, x): 每个人都有父母
# Skolem化后: ∀x Parent(f(x), x)
# f(x) 可以理解为 "x的父母函数"

# 这在语义上是合理的:
# 不同的人可能有不同的父母
# f(张三) 返回张三的父母
# f(李四) 返回李四的父母

# ∃x∀y Loves(x, y): 存在一个人爱所有人
# Skolem化后: ∀y Loves(c, y)
# c 是一个常量,代表 "那个爱所有人的人"

pass

Skolem化的注意事项

函数符号必须是新的:Skolem函数不能与公式中已有的函数符号重名,否则会导致语义混淆。

依赖关系的正确处理:存在量词变量依赖于它之前所有全称量词约束的变量。例如:

原公式Skolem化结果说明
xyP(x,y)\exists x \forall y \, P(x, y)yP(c,y)\forall y \, P(c, y)xx 不依赖于任何变量,用常量
yxP(x,y)\forall y \exists x \, P(x, y)yP(f(y),y)\forall y \, P(f(y), y)xx 依赖于 yy,用一元函数
yzxP(x,y,z)\forall y \forall z \exists x \, P(x, y, z)yzP(f(y,z),y,z)\forall y \forall z \, P(f(y, z), y, z)xx 依赖于 yyzz,用二元函数

与Herbrand域的关系:Skolem化后的公式可以在Herbrand域上进行解释,这是自动定理证明的理论基础之一。

消解原理

消解原理(Resolution Principle)是命题逻辑和一阶逻辑中一种强有力的推理规则,由J.A. Robinson于1965年提出。它是现代自动定理证明器的核心算法,也是逻辑编程语言Prolog的理论基础。

消解规则

消解规则的基本形式是:

C1LC2¬LC1C2\frac{C_1 \lor L \quad C_2 \lor \neg L}{C_1 \lor C_2}

其中 LL 是一个文字,C1C_1C2C_2 是子句。这个规则说:如果两个子句包含互补的文字(一个正文字,一个负文字),则可以将它们合并,删除互补的文字对。

示例

  • 子句1:pqrp \lor q \lor r
  • 子句2:¬ps\neg p \lor s
  • 消解结果:qrsq \lor r \lor s(消去 pp¬p\neg p

命题逻辑中的消解

消解反驳:要证明命题公式 FF 是永真式,等价于证明 ¬F\neg F 是不可满足的。将 ¬F\neg F 转换为CNF,然后用消解规则推导。如果能推导出空子句(记作 \square),则 ¬F\neg F 不可满足,从而 FF 是永真式。

示例:证明 (pq)pq(p \to q) \land p \to q 是永真式。

步骤 1:否定结论 ¬((pq)pq)=¬(¬((pq)p)q)=(pq)p¬q\neg((p \to q) \land p \to q) = \neg(\neg((p \to q) \land p) \lor q) = (p \to q) \land p \land \neg q

步骤 2:转换为CNF (pq)p¬q=(¬pq)p¬q(p \to q) \land p \land \neg q = (\neg p \lor q) \land p \land \neg q

得到三个子句:

  • C1:¬pqC_1: \neg p \lor q
  • C2:pC_2: p
  • C3:¬qC_3: \neg q

步骤 3:消解

步骤子句来源
1¬pq\neg p \lor q前提
2pp前提
3¬q\neg q前提
4qq消解1, 2(消去 pp¬p\neg p
5\square消解3, 4(消去 qq¬q\neg q

推导出空子句,证明完成。

一阶逻辑中的消解

一阶逻辑中的消解需要处理变量,因此需要**合一(Unification)**算法。

合一:找到最一般的替换,使两个原子公式相同。

示例:合一 P(x,f(y))P(x, f(y))P(a,f(b))P(a, f(b))

替换 {xa,yb}\{x \mapsto a, y \mapsto b\} 可以使两者合一为 P(a,f(b))P(a, f(b))

消解步骤

  1. 将公式转换为Skolem CNF
  2. 对两个子句中的互补文字进行合一
  3. 应用消解规则

示例:从以下前提证明结论。

前提:

  • x(Cat(x)Animal(x))\forall x (Cat(x) \to Animal(x)):所有猫都是动物
  • Cat(Tom)Cat(Tom):Tom是猫

结论:

  • Animal(Tom)Animal(Tom):Tom是动物

步骤 1:转换为CNF

前提1:¬Cat(x)Animal(x)\neg Cat(x) \lor Animal(x) 前提2:Cat(Tom)Cat(Tom)

否定结论:¬Animal(Tom)\neg Animal(Tom)

步骤 2:消解

步骤子句来源
1¬Cat(x)Animal(x)\neg Cat(x) \lor Animal(x)前提
2Cat(Tom)Cat(Tom)前提
3¬Animal(Tom)\neg Animal(Tom)否定结论
4Animal(Tom)Animal(Tom)消解1, 2,替换 {xTom}\{x \mapsto Tom\}
5\square消解3, 4

消解策略

单元消解:优先使用单元子句(只含一个文字的子句)进行消解,可以快速简化问题。

输入消解:至少有一个子句来自原始子句集。这种策略效率高,但不完备。

线性消解:每次消解至少使用上一步产生的子句。这是Prolog采用的策略。

支持集消解:限制消解必须涉及否定目标或其派生出的子句。

消解的完备性

命题逻辑:消解规则是完备的。如果一个CNF公式是不可满足的,则一定能通过消解推导出空子句。

一阶逻辑:消解规则也是完备的(Gödel完备性定理的构造性证明)。但由于一阶逻辑的半可判定性,如果公式不是永真式,消解过程可能不会终止。

def resolution(clauses):
"""
消解算法的概念框架
clauses: 子句集合,每个子句是文字的集合
"""
while True:
new_clauses = set()

# 对所有子句对尝试消解
for c1 in clauses:
for c2 in clauses:
if c1 != c2:
resolvents = resolve(c1, c2)
if empty_clause in resolvents:
return "UNSATISFIABLE"
new_clauses.update(resolvents)

# 如果没有新子句产生,则可满足
if new_clauses.issubset(clauses):
return "SATISFIABLE"

clauses.update(new_clauses)

def resolve(clause1, clause2):
"""
对两个子句进行消解
返回所有可能的消解结果
"""
resolvents = []
for literal in clause1:
if negate(literal) in clause2:
# 找到互补文字对,进行消解
new_clause = (clause1 - {literal}) | (clause2 - {negate(literal)})
resolvents.append(new_clause)
return resolvents

消解的应用

定理证明:消解是许多自动定理证明器的核心算法。

逻辑编程:Prolog使用消解的变种(SLD消解)来执行查询。

约束求解:SAT求解器使用消解的优化版本(CDCL算法)来处理大规模布尔可满足性问题。

程序验证:模型检验和符号执行中大量使用消解技术。

小结

本章介绍了数理逻辑的基础知识:

  1. 命题逻辑:命题、联结词、真值表、逻辑等价
  2. 谓词逻辑:谓词、量词、嵌套量词
  3. 证明方法:直接证明、反证法、逆否证明、数学归纳法
  4. 推理规则:假言推理、拒取式等常用规则,以及谓词逻辑中的实例化和推广规则
  5. 范式:CNF、DNF、前束范式,以及Skolem化的原理和方法
  6. 消解原理:自动定理证明的核心技术

这些知识是后续学习的基础。集合论中将用到逻辑表达式,证明方法将贯穿整个离散数学的学习,而消解原理和Skolem化则是连接理论与实际应用的重要桥梁。

练习

命题逻辑

  1. 构造 (pq)(qr)(pr)(p \to q) \land (q \to r) \to (p \to r) 的真值表,验证它是永真式。这个永真式有什么实际意义?

  2. 用德摩根律简化 ¬(p¬qr)\neg(p \land \neg q \land r),并解释每一步的逻辑含义。

  3. 将公式 (pq)r(p \to q) \to r 转换为 CNF,详细写出每个转换步骤。

  4. 证明下列等价式:

    • p(qr)(pq)rp \to (q \to r) \equiv (p \land q) \to r
    • pq(pq)(¬p¬q)p \leftrightarrow q \equiv (p \land q) \lor (\neg p \land \neg q)
  5. 判断以下命题是永真式、矛盾式还是可满足式:

    • (pq)(qp)(p \to q) \lor (q \to p)
    • (pq)(p(qp))(p \leftrightarrow q) \leftrightarrow (p \leftrightarrow (q \leftrightarrow p))
    • (pq)(qr)¬(pr)(p \to q) \land (q \to r) \land \neg(p \to r)

谓词逻辑

  1. 将命题"没有最大的素数"用谓词逻辑表示。要求给出两种不同的表示方式,并说明它们的等价性。

  2. 设论域为所有人,将以下句子翻译成谓词逻辑:

    • "所有人都喜欢某些人"
    • "有些人被所有人喜欢"
    • "没有人喜欢所有人"
    • "并不是所有人都喜欢某些人"
  3. 判断以下等价式是否成立,并给出证明或反例:

    • x(P(x)Q(x))xP(x)xQ(x)\forall x \, (P(x) \lor Q(x)) \equiv \forall x \, P(x) \lor \forall x \, Q(x)
    • x(P(x)Q(x))xP(x)xQ(x)\exists x \, (P(x) \land Q(x)) \equiv \exists x \, P(x) \land \exists x \, Q(x)
    • xyP(x,y)yxP(x,y)\forall x \exists y \, P(x, y) \equiv \exists y \forall x \, P(x, y)
  4. 设论域为整数,用谓词逻辑表示以下命题:

    • "每个整数都有唯一的后继"
    • "存在唯一的偶素数"
    • "任意两个不同的整数之间必有另一个整数"

前束范式与Skolem化

  1. 将以下公式转换为前束范式,并写出每一步的转换依据:

    • ¬xP(x)yQ(y)\neg \forall x \, P(x) \lor \exists y \, Q(y)
    • x(P(x)yQ(x,y))\forall x \, (P(x) \to \exists y \, Q(x, y))
    • xyz(P(x,y)Q(y,z))\exists x \forall y \exists z \, (P(x, y) \to Q(y, z))
  2. 对以下前束范式进行Skolem化,并解释Skolem函数的语义:

    • xyP(x,y)\forall x \exists y \, P(x, y)
    • xyzR(x,y,z)\exists x \forall y \exists z \, R(x, y, z)
    • xyzwuS(x,y,z,w,u)\forall x \forall y \exists z \forall w \exists u \, S(x, y, z, w, u)
  3. 证明 xyP(x,y)yxP(x,y)\exists x \forall y \, P(x, y) \Rightarrow \forall y \exists x \, P(x, y),但反向不成立。给出一个具体的谓词例子说明反向不成立。

  4. 将以下公式转换为Skolem CNF:

    • x(P(x)yQ(x,y))\forall x (P(x) \to \exists y Q(x, y))
    • xy(P(x)Q(y))\exists x \forall y (P(x) \to Q(y))

证明方法

  1. 用数学归纳法证明:

    • 12+22++n2=n(n+1)(2n+1)61^2 + 2^2 + \cdots + n^2 = \frac{n(n+1)(2n+1)}{6}
    • 12+23++n(n+1)=n(n+1)(n+2)31 \cdot 2 + 2 \cdot 3 + \cdots + n(n+1) = \frac{n(n+1)(n+2)}{3}
    • n<2nn < 2^n 对所有正整数 nn 成立
  2. 用反证法证明:

    • 存在无穷多个素数
    • 3\sqrt{3} 是无理数
  3. 使用谓词逻辑推理规则完成以下证明:

    (a) 从以下前提证明"存在会爬树的动物":

    • 前提 1:xCat(x)\exists x \, Cat(x)
    • 前提 2:x(Cat(x)ClimbTree(x))\forall x \, (Cat(x) \to ClimbTree(x))

    (b) 从以下前提证明"存在喜欢学习的聪明人":

    • 前提 1:x(Smart(x)y(Likes(x,y)Subject(y)))\forall x \, (Smart(x) \to \exists y \, (Likes(x, y) \land Subject(y)))
    • 前提 2:x(Subject(x)Study(x))\forall x \, (Subject(x) \to Study(x))
    • 前提 3:xSmart(x)\exists x \, Smart(x)

    (c) 从以下前提证明"有些人不快乐":

    • 前提 1:x(Rich(x)Happy(x))\forall x \, (Rich(x) \to Happy(x))
    • 前提 2:x(¬Happy(x)Poor(x))\exists x \, (\neg Happy(x) \land Poor(x))
  4. 使用强归纳法证明:每个大于1的整数都可以唯一地表示为素数的乘积(不计顺序)。

消解原理

  1. 用消解法证明以下命题逻辑公式是永真式:

    • (pq)(qr)(pr)(p \to q) \land (q \to r) \to (p \to r)
    • (pq)¬pq(p \lor q) \land \neg p \to q
  2. 用消解法证明一阶逻辑命题:

    (a) 从以下前提证明 Mortal(Socrates)Mortal(Socrates)

    • x(Human(x)Mortal(x))\forall x \, (Human(x) \to Mortal(x))
    • Human(Socrates)Human(Socrates)

    (b) 从以下前提证明 xGrandparent(x,Tom)\exists x \, Grandparent(x, Tom)

    • xyz(Parent(x,y)Parent(y,z)Grandparent(x,z))\forall x \forall y \forall z \, (Parent(x, y) \land Parent(y, z) \to Grandparent(x, z))
    • Parent(John,Mary)Parent(John, Mary)
    • Parent(Mary,Tom)Parent(Mary, Tom)
  3. 解释为什么消解法在一阶逻辑中可能不终止。给出一个具体的例子说明这种情况。

综合应用

  1. 在程序验证中,我们需要证明程序的某些性质。考虑以下简单的条件语句:

    if (x > 0) {
    y = x + 1;
    } else {
    y = 1;
    }
    // 断言: y >= 1

    用谓词逻辑表示这个程序的正确性,并证明断言成立。

  2. 数据库查询优化中常用到逻辑等价式。证明以下查询重写规则的正确性:

    • σcondition(R×S)σcondition(R)×S\sigma_{condition}(R \times S) \equiv \sigma_{condition}(R) \times S(当条件只涉及R的属性时)
    • πattributes(σcondition(R))σcondition(πattributes(R))\pi_{attributes}(\sigma_{condition}(R)) \equiv \sigma_{condition}(\pi_{attributes}(R))(当条件只涉及投影的属性时)

    提示:将关系代数操作转换为逻辑表达式进行证明。

  3. 在人工智能的知识表示中,框架公理用于描述状态变化。用谓词逻辑表示:

    • "在状态 ss 中,如果物体 xx 在位置 pp,且机器人没有移动 xx,则在下一个状态 ss' 中,xx 仍在位置 pp"
    • "在状态 ss 中,如果机器人把 xxp1p_1 移到 p2p_2,则在下一个状态 ss' 中,xx 在位置 p2p_2"
  4. 逻辑编程语言Prolog使用消解的变种。解释以下Prolog程序的执行过程:

    parent(tom, mary).
    parent(mary, john).
    grandparent(X, Z) :- parent(X, Y), parent(Y, Z).

    ?- grandparent(tom, john).

    用本章学到的消解原理分析查询的执行过程。