从关系到布尔代数:浅谈集合论与计算机科学的联系和启发
从关系到布尔代数:浅谈集合论与计算机科学的联系和启发
引言
在“集合论”课程中,当我们学到“对称差”运算时,其符号(\(\oplus\))和性质(如\(A\oplus B\oplus A=B\))使我联想到位运算中的“异或”运算(exclusive or, xor)。异或常用的符号也是\(\oplus\),其性质也与对称差一模一样(\(a\oplus b\oplus a=b\))。这两种运算的相似性促使我更进一步探究集合论与布尔代数间的关系。
记号约定
对部分符号作出如下约定:
含义 符号 定义 逻辑否 \(\mathtt!\) 对于命题\(p\),命题\(\mathtt!p\)为真当且仅当\(p\)为假 逻辑与 \(\mathtt{\&\&}\) 对于命题\(p,q\),命题\(p\ \mathtt{\&\&}\ q\)为真当且仅当\(p,q\)都为真 逻辑或 $\mathtt{ 包含于 \(\subseteq\) 对于集合\(S,T\),称\(S\subseteq T\)当且仅当\(\forall x\in S\ (x\in T)\) 真包含于 \(\subsetneq\) 对于集合\(S,T\),称\(S\subsetneq T\)当且仅当\(S\subseteq T\ \mathtt{\&\&}\ S\neq T\) \(I(\cdot)\) 对于集合\(S\),$I(S)\triangleq{(x,x) \(\mathrm I(\cdot)\) 对于命题\(p\),\(\operatorname I(p)\triangleq1\text{ if }p\text{ is true else }0\)。 为了避免与直觉的冲突,约定:对于\(S\)上的偏序关系\(\leq\),\(<\triangleq\leq\backslash I(S)\),\(\geq\triangleq\leq^{-1}\),\(>\triangleq\geq\backslash I(S)\)。
关系
等价关系和等价类
对于集合\(S\)上的关系\(\sim\),若\(\sim\)具有自反性(\(\forall x\in S\ ((x,x)\in\sim)\))、对称性(\(\forall(x,y)\in \sim\ ((y,x)\in\sim\))和传递性(\(\forall(x,y),(y,z)\in\sim\ ((x,z)\in\sim)\)),则称\(\sim\)为\(S\)上的一个等价关系,并将\((x,y)\in\sim\)记作\(x\sim y\)。
对于\(S\)上的等价关系\(\sim\),设\(x\in S\),称\([x]\triangleq\{s\in S:\ s\sim x\}\)为以\(x\)为代表元的等价类。
偏序关系
对于集合\(S\)上的关系\(\leq\),若\(\leq\)具有自反性(\(\forall x\in S\ ((x,x)\in\leq)\))、反对称性(\(\forall x,y\in S\ (((x,y)\in\leq\ \mathtt{\&\&}\ (y,x)\in\leq)\iff x=y)\))和传递性(\(\forall x,y,z\in S\ (((x,y)\in\leq\ \mathtt{\&\&}\ (y,z)\in\leq)\implies(x,z)\in\leq)\)),则称\(\leq\)为\(S\)上的一个偏序关系,并将\((x,y)\in\leq\)记作\(x\leq y\)。
对于集合\(S\)上的关系\(<\),若\(<\)具有反自反性(\(\forall x\in S\ ((x,x)\notin<)\))和传递性(\(\forall x,y,z\in S\ (((x,y)\in<\ \mathtt{\&\&}\ (y,z)\in<)\implies(x,z)\in<)\)),则称\(<\)为\(S\)上的一个严格偏序关系,并将\((x,y)\in<\)记作\(x<y\)。
对于集合\(S\)及其上的偏序关系\(\leq\),称\((A,\leq)\)为一个偏序集。
与计算机科学的联系
运算符重载和谓词
等价关系和偏序关系分别从一般的“相等”和“小于等于”关系抽象出来。
C++等高级编程语言也提供了重载运算符的功能,这样可以更加方便地进行对象间的比较,提高编码速度和代码可读性。
C++中“谓词”(predicate)的概念允许接口的使用者在排序时自定义“顺序”,例如,我们可以观察一下<algorithm>库中的std::sort函数原型:
template <class RandIter, class Pred>
inline void sort(RandIter begin, RandIter end, Pred pred) {...}
其中的Pred stands for "predicate"。该函数的第三个参数被要求为一个比较函数指针或仿函数,用于描述严格偏序关系\(<\)。
并查集
并查集(disjoint set union或union find)是一个常用的进阶数据结构。其支持在线性的空间开销下,在\(\log\)级的时间内快速查询元素所在的集合和合并两个集合。其基本思想是,对于每个集合,选取其中一个元素作为代表元。记录每个元素的前驱(初始时均为自身),查询时沿着前驱链查找直至尽头获得该集合的代表元,合并两个集合时,只需将其中一个集合的代表元的前驱从其自身改为另一个集合的代表元即可。
格(Lattice)
一般的格
集合论:设\((L,\leq)\)是一个偏序集,对任意\(x,y\in L\)定义运算\(x\wedge y\triangleq\inf\{x,y\}\)和\(x\vee y\triangleq\sup\{x,y\}\)。若\(\forall x,y\in L\ (x\wedge y\in L\ \mathtt{\&\&}\ x\vee y\in L)\),则称\((L,\leq)\)为一个格。
代数:若集合\(L\)上的二元运算\(\vee\)和\(\wedge\)满足对任意\(x,y,z\in L\)有
则称\((L,\wedge,\vee)\)为一个格。
两种定义是等价的,证明如下:
由集合论定义推出代数定义
设\((L,\leq)\)是一个偏序集,对任意\(x,y\in L\)定义运算\(x\wedge y\triangleq\inf\{x,y\}\)和\(x\vee y\triangleq\sup\{x,y\}\)。设\(L\)满足\(\forall x,y\in L\ (x\wedge y\in L\ \mathtt{\&\&}\ x\vee y\in L)\)。
任取\(x,y,z\in L\)。
交换律是显然的。
设\(r_1=(x\wedge y)\wedge z,\ r_2=x\wedge(y\wedge z)\),即\(r_1=\inf\{\inf\{x,y\},z\},\ r_2=\inf\{x,\inf\{y,z\}\}\),则\(r_1,r_2\leq x,y,z\)。
因\(r_2\leq x,y\),故\(r_2\leq\inf\{x,y\}\)。又\(r_2\leq z\),故\(r_2\)是\(\{\inf\{x,y\},z\}\)的一个下界。由于\(r_1=\inf\{\inf\{x,y\},z\}\),故\(r_2\leq r_1\)。同理可得\(r_1\leq r_2\),因此有\(r_1=r_2\)。
同理可证\(\vee\)运算满足结合律。
由于\(x\leq x\)且\(x\leq\sup\{x,y\}\),故\(x\)是\(\{x,\sup\{x,y\}\}\)的一个下界。任取\(\{x,\sup\{x,y\}\}\)的下界\(\lambda\),若\(x\leq\lambda\),则\(x\leq\lambda\leq x\),故\(\lambda=x\)。因此\(x=\inf\{x,\sup\{x,y\}\}=x\wedge(x\vee y)\)。
同理可证\(x=x\vee(x\wedge y)\)。
由代数定义推出集合论定义
设集合\(L\)上的二元运算\(\vee\)和\(\wedge\)满足对任意\(x,y,z\in L\)有
\[\begin{align} &x\wedge y=y\wedge x,\ x\vee y=y\vee x&&\text{交换律}\\ &(x\wedge y)\wedge z=x\wedge(y\wedge z),\ (x\vee y)\vee z=x\vee(y\vee z)&&\text{结合律}\\ &x\wedge(x\vee y)=x,\ x\vee(x\wedge y)=x&&\text{吸收律} \end{align} \]现在让我们构造一个\(L\)上的关系\(\leq=\{(x,y)\in L^2:\ x\wedge y=x\}\)。这等价于构造\(\leq=\{(x,y)\in L^2:\ x\vee y=y\}\),因为\(x\wedge y=x\implies x\vee y=(x\wedge y)\vee y=y\)且\(x\vee y=y\implies x\wedge y=x\wedge(x\vee y)=x\)(运用吸收律)。
自反性和反对称性是显然的。
任取\(x,y,z\in L\)满足\(x\leq y,\ y\leq z\),即\(x\wedge y=x,\ y\wedge z=y\)。利用结合律可知,\(x\wedge z=(x\wedge y)\wedge z=x\wedge(y\wedge z)=x\wedge y=x\),故\(x\leq z\),因此\(\leq\)具有传递性。
因此\(\leq\)是\(L\)上的一个偏序关系。
由于\((x\wedge y)\wedge x=(x\wedge x)\wedge y=x\wedge y\)即\(x\wedge y\leq x\),且\((x\wedge y)\wedge y=x\wedge(y\wedge y)=x\wedge y\)即\(x\wedge y\leq y\),故\(x\wedge y\)是\(\{x,y\}\)的一个下界。任取\(\{x,y\}\)的一个下界\(\lambda\),则\(\lambda\wedge(x\wedge y)=(\lambda\wedge x)\wedge y=\lambda\wedge y=\lambda\)即\(\lambda\leq x\wedge y\),若\((x\wedge y)\leq\lambda\),则\(x\wedge y=\lambda\)。故\(x\wedge y=\inf\{x,y\}\)。
同理可得\(x\vee y=\sup\{x,y\}\)。
除了上述定义中展现的自反性、反对称性、传递性、交换律、结合律和吸收律以外,我们还可以推导出格具有如下的性质。
格的笛卡尔积也是格:设\((L_1,\leq_1),(L_2,\leq_2)\)都是格,构造\(L=L_1\times L_2,\ \leq=\{((x_1,y_1),(x_2,y_2))\in L^2:\ x_1\leq_1x_2\ \mathtt{\&\&}\ y_1\leq_2y_2\}\),则\((L,\leq)\)也是格。
双重对偶律:设\((L,\leq)\)是格并如上所述定义\(\wedge\)和\(\vee\),则\(\forall x,y\in L\ (x\wedge y=x\iff x\leq y\iff x\vee y=y)\)。上文已经用吸收律证明过。
分配格
若格\((L,\wedge,\vee)\)满足分配律,即对任意\(x,y,z\in L\)有\(x\wedge(y\vee z)=(x\wedge y)\vee(x\wedge z)\),则称\((L,\wedge,\vee)\)为分配格(distributive lattice)。
分配律的另一种形式是对任意\(x,y,z\in L\)有\(x\vee(y\wedge z)=(x\vee y)\wedge(x\vee z)\)。这两种形式是等价的,证明如下:
设\(x\wedge(y\vee z)=(x\wedge y)\vee(x\wedge z)\)。
设\(s=x\vee(y\wedge z),\ t=(x\vee y)\wedge(x\vee z)\)(\(\wedge\)对\(\vee\)的分配律)。
\[\begin{align} &s\wedge t\\ =&(s\vee(y\wedge z))\wedge((x\vee y)\wedge(x\vee z))\\ =&((x\vee y)\wedge(x\vee(y\wedge z)))\wedge(x\vee z)&&\text{结合律和交换律}\\ =&(((x\vee y)\wedge x)\vee((x\vee y)\wedge(y\wedge z)))\wedge(x\vee z)&&\text{$\wedge$对$\vee$的分配律}\\ =&(x\vee(y\wedge z))\wedge(x\vee z)&&\text{结合律和吸收律;结果是$s$“吸收”了$(x\vee y)$}\\ =&x\vee(y\wedge z)&&\text{$y$与$z$等价,$s$可以同样的方式“吸收”掉$(x\vee z)$}\\ =&s \end{align} \]因此\(s\leq t\)。同理可以证明\(t\leq s\)。故\(s=t\)。
设\(x\vee(y\wedge z)=(x\vee y)\wedge(x\vee z)\)(\(\vee\)对\(\wedge\)的分配律)。
由于\(\wedge\)和\(\vee\)是等价的,可以用同样的方式证明\(\vee\)对\(\wedge\)的分配律。
有界格
若格\((L,\wedge,\vee)\)中对于上述定义的偏序关系\(\leq\)存在最小元(记作\(0\))和最大元(记作\(1\)),即\(\forall x\in L\ (0\leq x\leq 1)\),则称\((L,\wedge,\vee,0,1)\)是一个有界格(bounded lattice)。
有补格
若有界格\((L,\wedge,\vee,0,1)\)满足\(\forall x\in L\ \exist x^\mathrm c\in L\ (x\wedge x^\mathrm c=0\ \mathtt{\&\&}\ x\vee x^\mathrm c=1)\),则称这个有界格为有补格(complemented lattice),同时称\(x^\mathrm c\)为\(x\)的补(complement)。
由于预先学过“逆元的逆元等于自身”(例如\(\forall z\in\C\ (-(-z)=z)\),也就是我们常说的“负负得正”)或者“补集的补集等于自身”(即对于全集\(U\),\(\forall S\subseteq U\ (U\backslash(U\backslash S)=S)\),我们在直觉上可能倾向于认为这对有补格也成立,也就是认为\(x^\mathrm c\)的补一定是\(x\),但这实际上是不一定成立的,因为有界格中,一个元素可以有多个补。
例如,考虑如下Hasse图所示的有补格:
1 /|\ a b c ← 彼此为补 \|/ 0更严谨地说,取\(L=\{0,a,b,c,1\}\),定义\(\leq=\{(0,a),(0,b),(0,c),(a,1),(b,1),(c,1)\}\),容易知道\((L,\leq)\)是有补格,且
\[a\wedge b=0,\ a\vee b=1\\ a\wedge c=0,\ a\vee c=1\\ b\wedge c=0,\ b\vee c=1\\ \]这样,每个元素都有两个补,一个元素补的补也不一定是自身。
那末,满足怎样的条件可以“弥补”这个缺憾,使每个元素都有唯一的补呢?
布尔格
若有补格\((L,\wedge,\vee,0,1)\)满足分配律,则称其为布尔格(Boolean lattice)。
布尔格也称为布尔代数,但既然上面都叫做“某某格”,这里也叫布尔格好了。
布尔格各元素的补唯一。
对于布尔格\((L,\wedge,\vee,0,1)\),任取\(x\in L\),设\(c_1,c_2\)都是\(x\)的补,则根据定义有
\[x\wedge c_1=0,\ x\vee c_1=1\\ x\wedge c_2=0,\ x\vee c_2=1 \]下证\(c_1=c_2\)。
\[\begin{align} c_1&=c_1\wedge1\\ &=c_1\wedge(x\vee c_2)&&\text{代入$x\vee c_2=1$}\\ &=(c_1\wedge x)\vee(c_1\wedge c_2)&&\text{$\wedge$对$\vee$的分配律}\\ &=0\vee(c_1\wedge c_2)&&\text{代入$x\wedge c_1=0$}\\ &=c_1\wedge c_2&&\text{$0$是最小元} \end{align} \]同理也有
\[c_2=c_1\wedge c_2 \]故\(c_1=c_2\),即\(x\)的补唯一。将\(x\)的补记为\(\neg x\)。
通常将布尔格记为\((L,\wedge,\vee,\neg,0,1)\)。
一元布尔格
一元布尔格中,由于只有一个元素,所以最小元等于最大元。但因为只有一个元素,所有的运算都失去了意义,研究一元布尔格意义不大。
二元布尔格
称\((\{0,1\},\wedge,\vee,\neg,0,1)\)为二元布尔格。
可以认为二元布尔格是最简单的布尔格(如果不管一元布尔格的话)。
特别地,在二元布尔格中,我们可以将\(\wedge\)称为“与”运算(and),将\(\vee\)称为“或”运算(or),将\(\neg\)称为“非”运算,将\(0\)称为“假”(false),将\(1\)称为真(true)。这样,我们就可以用二元布尔格来描述命题的真假关系。这也就是在某些\(\LaTeX\)渲染器中\(\mathtt{\backslash wedge}(\wedge)\)也可以用\(\mathtt{\backslash and}(\and)\)表示,\(\mathtt{\backslash vee}(\vee)\)也可以用\(\mathtt{\backslash or}(\or)\)表示的原因。
我们还可以定义“异或”运算(exclusive or, xor)。正如其名字所示,异或就是“异”和“或”:对于\(a,b\in\{0,1\}\),\(a\oplus b\triangleq((a\vee b)\wedge(a\neq b))\)。如果不希望将命题代入计算式的话,也可以这样定义:\(a\oplus b\triangleq(a\vee b)\wedge\neg(a\wedge b)\)。这二者是完全等价的,因为当\(a\vee b=1\)时,\(a\neq b\)蕴含着\(a,b\)中至少有一个为\(0\),也就是\(a\wedge b=0\)。
异或运算满足以下性质。任取\(a,b,c\in\{0,1\}\),则
同时可以注意到:恒等律说明,\(0\)是异或运算的单位元;归零律说明,一个元素对于异或运算的逆元就是其自身。这样,异或运算在\(\{0,1\}\)上构成阿贝尔群(Abelian group),又叫交换群(communicative group)。
由这几条运算律还可以推导出如下的神奇而重要的性质:
这与集合的对称差的运算性质相同。
与计算机科学的联系
与、或、非和交、并、补
这只是我个人一个初步的不太严谨的想法,但的确可以在可列的尺度上联系布尔运算与集合运算。
对于命题\(p\),\(\operatorname I(p)\triangleq1\text{ if }p\text{ is true else }0\)。
考虑集合\(S_i\ (i\in\mathbb{N}^*,i\leq m,\ m\in\N^*\cup\{\alef_0\})\)。
设\(\mathcal F=\{F:\ F\left((S_i)_{i=1}^m\right)是对集合S_i\ (i\in\N^*,\ i\leq m)\}进行有限次交、并、补及其复合的结果\}\)。
设全集\(U=\bigcup_{i=1}^{m}S_i\),\(R=\{S\subseteq U:\ \exists F\in\mathcal F\ \left(S=F\left((S_i)_{i=1}^m\right)\right)\}\)是可列集,\(n=\mathrm{Card}(U)\),则存在双射\(\varphi:U\to\N\)。
设矩阵\(M=\left[(\mathrm I(\varphi^{-1}(i)\in S_j)))_{i=1}^n\right]_{j=1}^m\in\{0,1\}^{n\times m}\),即\(M_{i,j}\)标示集合\(U\)中第\(i\)个元素是否在集合\(S_j\)中。
对于任何\(F\in\mathcal F\),将其交、并、补分别替换为与、或、非,可得对应布尔运算\(f:\{0,1\}^{n\times m}\to\{0,1\}^n\),则\(F\left((S_i)_{i=1}^m\right)=\{x\in U:\ f(M)\}\)。这样,任何\(F\in\mathcal F\)都可以用相应的\(f\)来计算了。也就是说,交、并、补和与、或、非之间具有对偶性。这就揭示了这几个运算,以及异或和对称差这两种运算,他们在形式上具有相同性质的原因。
布尔代数与位运算
位运算是对比特位(binary digit, bit)进行的二元操作。目前绝大多数电子计算机中,由于每个bit的状态只有低电位和高电位两种,我们完全可以将二元布尔格的运算全部搬过来。这样,就有了编程中常见的各种按位运算。
计算机领域中,常将“异或”运算描述为“不进位加法”。这就是说,对于两个比特位,其异或运算的结果等于将这两个比特位视为二进制数相加后,舍弃进位(如果没进位就不管)的结果。
这样,利用与门和异或门,就可以制作加法器。
对两个字节(byte)的异或运算被定义为依次将相应比特位进行异或运算。抽象地说,将两个字节视作两个布尔值向量\(\vec u,\vec v\in\{0,1\}^8\),\(\vec u\oplus\vec v\triangleq(u_i\oplus v_i)_{i=0}^7\)。
前文所述\(\forall a,b\in\{0,1\}\ (a\oplus(a\oplus b)=b)\)性质在计算机领域非常重要,下面枚举几种常见用途:
-
快速交换两数
template <std::integral Int> inline void swap(Int &a, Int &b) { if (&a != &b) { // 防止传入同一个地址的数 a ^= (b ^= (a ^= b)); // 等价于:a ^= b; b ^= a; a ^= b; } } -
加密算法
直接利用位运算即可实现一个简易的加密算法。只需指定一定长度的0-1串作为密钥(音“月”),将输入序列分割为若干个与密钥等长的连续子串,每一串都与密钥进行异或操作。
using ByteSeq = std::vector<uint8_t>; inline ByteSeq encode(ByteSeq seq, const ByteSeq &key) { for (size_t i = 0; i < seq.size(); ++i) { seq[i] ^= key[i % key.size()]; } return seq; }在常见的现代加密算法(如AES、DES)中都能看到异或运算的大量使用。
位运算可以用于对整数进行与2有关的快速操作,因为按位运算比乘法或除法快得多。例如:
- 乘2的整数次幂可以描述为按位左移(\(n\times2^m\ (n,m\in\N)\)常用
n << m来计算),向下取整的除以2的整数次幂则可以描述为按位右移。 - 判断奇偶性也可以用按位与运算实现(对于\(n\in\Z\),命题\(n为奇数\)可以由
n & 1 != 0判断),且此方法对于补码表示的负数也成立。更进一步地,同理可以知道\(n\in\Z的因数中没有2^m\ (m\in\N)\)当且仅当n & (1 << m) != 0。
在部分动态规划(dynamic programming, DP)算法中,可以利用\(\neg\neg x=x\)的性质重复利用空间,减少空间开销。
利用前文所述,用0-1向量表示集合的方法,也被广泛用于子集枚举、状态压缩DP等。
总结
集合论将语言学、逻辑学、哲学与数学联系在一起,同时启发着计算机科学。在今天,凡是数学(包括其中更加贴近计算机领域的图论和算法等领域)的内容,没有不使用集合论的语言的。我仍记得中学时第一次看到图的定义(\(G=(V,E)\))、一大坨括号和\(\in\subseteq\)等其他各种符号时的茫然和陌生,而现在的我已经对这种语言很熟悉了。
数学家喜欢抽象,寻找事物间的共性,从一切事物中抽象出本质特征。程序员也一样,于是有了面向对象编程(object-oriented programming, OOP)中的接口和继承,有了空指针和泛型。数学对计算机领域有很多启发,甚至可以说计算机科学完全是以数学为核心的。学好集合论、学好数学,也有利于计算机方面的学习。
近些年,形式化语言(如Lean和Coq等)越来越完善,其可以保证证明的严谨性。我个人觉得,未来或许可以搭建一个国际的数学网络平台,猜想和定理都可以通过形式化语言上传,以方便全世界的数学家打破语言、时空隔阂进行交流,杜绝伪证,减少弱智民科的同时鼓励大众参与,减少像Jumping那样的“造神”现象,也减少数学成就因为提出者没有名气而被埋没的现象。

浙公网安备 33010602011771号