数学 / 集合论 · 从 ∈ 到映射与量词 / 集合推导与量词 ∀ ∃ 待审核 9 / 11
逻辑运算 · {x∣P(x)}\{x \mid P(x)\} · ∀\forall ∃\exists

集合推导与量词 ∀ ∃

集合与逻辑是一体两面。谓词(predicate)PP 是对每个对象或真或假的条件,本身不是命题(见命题的判定);把它交给不同的机制,就得到不同的东西。交给集合推导 {x∈U∣P(x)}\{x \in U \mid P(x)\},得到一个子集;交给量词,得到一个命题。

1 · 谓词的三种用法

logic · P(a)P(a) · {x∣P(x)}\{x \mid P(x)\} · ∀\forall ∃\exists

同一个谓词有三种用法,产出物的类型各不相同。代入一个具体对象 aa,P(a)P(a) 是一个命题,有真假。用它作筛选条件,{x∈U∣P(x)}\{x \in U \mid P(x)\} 是 UU 的一个子集,没有真假。用量词约束它,∃x∈U, P(x)\exists x \in U,\ P(x) 与 ∀x∈U, P(x)\forall x \in U,\ P(x) 又是命题,各有真假。

三者由同一个真值集合 S={x∈U∣P(x)}S = \{x \in U \mid P(x)\} 串起来:P(a)P(a) 为真即 a∈Sa \in S;∃x P(x)\exists x\, P(x) 为真即 S≠∅S \ne \emptyset;∀x P(x)\forall x\, P(x) 为真即 S=US = U。存在命题的证明只需给出一个见证(SS 的任一元素),全称命题的否证只需给出一个反例(ScS^c 的任一元素)——两者的不对称,源头就是「非空」与「等于全集」这两个条件的不对称。

图 1-1 · 同一个谓词的三种用法:判定单个对象、筛出子集、给出全称或存在命题,以及对应的见证与反例。可切换谓词对照三者。

2 · 量词与否定的对偶

duality · ¬∃  ⟺  ∀¬\neg \exists \iff \forall \neg

定理 2.1(量词否定) ¬∃x P(x)\neg \exists x\, P(x) 与 ∀x ¬P(x)\forall x\, \neg P(x) 等价;¬∀x P(x)\neg \forall x\, P(x) 与 ∃x ¬P(x)\exists x\, \neg P(x) 等价。

用真值集合读一遍即是显然的:¬∃x P(x)\neg \exists x\, P(x) 说 S=∅S = \emptyset,∀x ¬P(x)\forall x\, \neg P(x) 说 Sc=US^c = U,二者是同一句话。这与De Morgan 律是同一条对偶——量词是遍历全集的合取与析取,否定进去时把 ∀\forall 与 ∃\exists 对调,正如它把 ∩\cap 与 ∪\cup 对调。

实用价值在于「否定一个命题」有了机械做法:把否定符号逐层推进去,每穿过一个量词就对调一次,最后只否定最内层的谓词。「所有连续函数都可导」的否定不是「所有连续函数都不可导」,而是「存在一个连续函数不可导」。

3 · 空集与量词次序

pitfalls · vacuous truth · ∀∃≠∃∀\forall \exists \ne \exists \forall

警示 · 全集为空时两个量词都退化,且退化方向相反:∀x∈∅, P(x)\forall x \in \emptyset,\ P(x) 恒真(S=U=∅S = U = \emptyset 自动成立),∃x∈∅, P(x)\exists x \in \emptyset,\ P(x) 恒假(S⊆∅S \subseteq \emptyset 不可能非空)。前者叫 vacuous truth,「所有」没有对象可反驳。∅⊆A\emptyset \subseteq A 恒成立正是它的一个实例(见包含的边界)。

另一处是次序。∀\forall 与 ∃\exists 相邻时不可交换:∀x∃y R(x,y)\forall x \exists y\, R(x, y) 允许 yy 随 xx 而变,∃y∀x R(x,y)\exists y \forall x\, R(x, y) 要求一个 yy 对所有 xx 通用,后者严格更强。取 U={1,…,12}U = \{1, \dots, 12\}、R(x,y)R(x, y) 为「yy 是 xx 的倍数」:前者为真,取 y=xy = x 即可;后者为假,因为通用的 yy 必须是 11 到 1212 的公倍数,而最小的那个是 2772027720,早已跑出 UU。

集合推导落到代码里就是 filter,两个量词就是 some 与 every,它们对空数组的取值恰好复刻上面那条警示:[].every(() => false) 为 true,[].some(() => true) 为 false。不过这个类比只在数组稠密时成立。every 与 some 会跳过 hole:长度为 33 的稀疏数组 [ , , , ] 上 every(() => false) 仍返回 true,some(() => true) 返回 false——谓词一次也没被调用。[1, , 3].every 实测只访问到 1 与 3 两个元素,而 length 是 3(node v26.6.0)。也就是说这两个方法量词化的全集是「有值的下标」,不是 0 到 length - 1;把稀疏数组当作一个 1212 元素的全集来推理会得到假结论。

4 · 参考文献

  1. Quantifier (logic). Wikipedia. 全称与存在量词的语义,以及量词次序不可交换。https://en.wikipedia.org/wiki/Quantifier_(logic)
  2. Set-builder notation. Wikipedia. 集合推导的记法与分离公理。https://en.wikipedia.org/wiki/Set-builder_notation
  3. Vacuous truth. Wikipedia. 空全集上全称命题为真的约定及其理由。https://en.wikipedia.org/wiki/Vacuous_truth
  4. Array.prototype.every. ECMA-262. 遍历时跳过缺失下标的规定。https://tc39.es/ecma262/#sec-array.prototype.every