要点
mindmap
Root(布尔函数)
A(总可以写成析取范式(DNF)的形式)
B(DNF中只用到了 And/Or/Not 三种运算)
C(Or 可以用 And/Not 来表示)
D(Not 可以用 Nand 来表示)
E(And 可以用 Nand 来表示)
正文
在 The Elements of Computing Systems 一书的附录 A 中提到
任何布尔函数都可以用只包含 Nand 运算符的表达式表示
我们可以通过以下几步来证明它。
第一步:任何布尔函数都可以写成析取范式(DNF, Disjunctive Normal Form)的形式
我们通过具体的例子来进行说明。假设一个布尔函数 f(a,b,c) 的真值表如下
| a | b | c | f(a,b,c) |
|---|
| 0 | 0 | 0 | 1 |
| 0 | 0 | 1 | 1 |
| 0 | 1 | 0 | 0 |
| 0 | 1 | 1 | 1 |
| 1 | 0 | 0 | 1 |
| 1 | 0 | 1 | 0 |
| 1 | 1 | 0 | 1 |
| 1 | 1 | 1 | 0 |
在真值表的某些行中,f(a,b,c) 值为 1,我们可以为所有这样的行找到对应的最小项(minterm)。例如
- 对 a=0,b=0,c=0 那一行,对应的最小项是 f0(a,b,c)=¬a∧¬b∧¬c
- 对 a=1,b=1,c=0 那一行,对应的最小项是 f6(a,b,c)=a∧b∧¬c
于是,我们可以将 f(a,b,c) 写成一些最小项(minterm)的 或(∨),具体如下
f(a,b,c)=f0(a,b,c)∨f1(a,b,c)∨f3(a,b,c)∨f4(a,b,c)∨f6(a,b,c)
其中
- f0(a,b,c)=¬a∧¬b∧¬c
- f1(a,b,c)=¬a∧¬b∧c
- f3(a,b,c)=¬a∧b∧c
- f4(a,b,c)=a∧¬b∧¬c
- f6(a,b,c)=a∧b∧¬c
基于以上结果,我们可以画一个详细的真值表 ⬇️ (a,b,c 三列是输入,其他列是计算结果)
| a | b | c | f(a,b,c) | f0(a,b,c) | f1(a,b,c) | f3(a,b,c) | f4(a,b,c) | f6(a,b,c) |
|---|
| 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 |
| 0 | 0 | 1 | 1 | 0 | 1 | 0 | 0 | 0 |
| 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 0 | 1 | 1 | 1 | 0 | 0 | 1 | 0 | 0 |
| 1 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 0 |
| 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
| 1 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 1 |
| 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
第二步:任何布尔函数都可以用只包含与(And)/或(Or)/非(Not)运算的布尔表达式表示
在第一步中,我们通过一个例子说明了任何布尔函数都可以写成 析取范式(即 最小项 的 或)的形式,而 最小项 中只用到了 非(Not) 运算和 与(And) 运算。在析取范式中,我们是用 或(Or) 运算将 最小项 连接起来的,所以 析取范式 中只用到了 与(And)/或(Or)/非(Not) 三种运算。所以任何布尔函数都可以用只包含 与(And)/或(Or)/非(Not)运算 的布尔表达式表示。
第三步:任何布尔函数都可以用只包含非(Not)和与(And)运算符的布尔表达式表示
或(Or)运算的真值表如下
| a | b | a∨b |
|---|
| 0 | 0 | 0 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 1 |
不难验证,a∨b 的真值表和 ¬(¬a∧¬b) 的真值表相同 ⬇️ (a,b 两列是输入,其他列是计算结果)
| a | b | ¬a | ¬b | ¬a∧¬b | ¬(¬a∧¬b) |
|---|
| 0 | 0 | 1 | 1 | 1 | 0 |
| 0 | 1 | 1 | 0 | 0 | 1 |
| 1 | 0 | 0 | 1 | 0 | 1 |
| 1 | 1 | 0 | 0 | 0 | 1 |
所以在析取范式的基础上,我们可以用 非(Not)/与(And) 运算来替代所有的 或(Or) 运算,这样我们就可以只用 非(Not) 和 与(And) 运算符来表达任意的布尔函数。
第四步:任何布尔函数都可以用只包含 Nand 运算符的表达式表示
在第三步中,我们已经证明了任何布尔函数都可以用只包含 非(Not) 和 与(And) 运算符的布尔表达式表示。所以如果我们能用 Nand 运算符来替代 非(Not) 以及 与(And) 运算符,那么就可以证明任何布尔函数都可以用只包含 Nand 运算符的表达式表示。
非(Not) 运算符的真值表如下
| a | ¬a |
|---|
| 0 | 1 |
| 1 | 0 |
因为 Nand(a,b)=¬(a∧b),可以得出 Nand 运算符的真值表如下 ⬇️
| a | b | Nand(a,b) |
|---|
| 0 | 0 | 1 |
| 0 | 1 | 1 |
| 1 | 0 | 1 |
| 1 | 1 | 0 |
所以 ¬a=Nand(a,a),可见 Nand 运算符可以替代 非(Not) 运算符。
因为
a∧b=¬(¬(a∧b))=¬Nand(a,b)
而 非(Not) 运算符可以用 Nand 运算符来表示,所以 Nand 运算符可以替代 与(And) 运算符。
至此,我们证明了
任何布尔函数都可以用只包含 Nand 运算符的表达式表示
总结
我们通过如下的方式证明了,任何布尔函数都可以用只包含 Nand 运算符的表达式表示 ⬇️
- 任何布尔函数可以写成对应的
DNF
DNF 中只包含 And/Or/Not 运算符(用 And/Or/Not 运算符可以表示任意的布尔函数)
Or 运算符可以用 And 和 Not 运算符来替代 (用 And/Not 运算符可以表示任意的布尔函数)
Not 运算符和 And 运算符都可以用 Nand 运算符来替代 (用 Nand 运算符可以表示任意的布尔函数)
可以把证明中关于 And/Or/Not 的部分写成 ⬇️
Not: ¬a=Nand(a,a)
And: a∧b=¬Nand(a,b)=Nand(Nand(a,b),Nand(a,b))
Or: a∨b=¬(¬a∧¬b)=Nand(Nand(a,a),Nand(b,b))
参考资料