命题逻辑
自然语言的例子
| 命题 (proposition) | 真假值 (bool) |
| 人是生物 | 真, true, 1 |
| 铁是生物 | 假, false, 0 |
数字电路表示 bool
| 电路值 | bool |
| 高电平 | 1 |
| 低电平 | 0 |
这里不处理数字电路的硬件实现. 我也不知道细节
[logic-operator] logical and, or, not
- 且, ,
and, 逻辑合取 (conjunction) - 或, ,
or, 逻辑析取 (disjunction) - 非, ,
not, 逻辑反取 (negation)
自然语言的例子
| 命题 | 真假值 |
| 人是生物且 1 是自然数 | 1 |
| 人是生物且 1 = 2 | 0 |
形式语言
| 1 | 1 | 1 |
| 1 | 0 | 0 |
| 0 | 1 | 0 |
| 0 | 0 | 0 |
| 1 | 1 | 1 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 0 | 0 | 0 |
| 1 | 0 |
| 0 | 1 |
的数字电路和逻辑门 (gate) 的表示
gate 设计为不允许反向电流?
not gate 将低电平转到高电平, 说明 gate 的硬件实现需要外部能量, 需要通电
是 “冗余” 的, e.g. 逻辑等价地, 我们可以用 表示
电路 gate 实现是用 not,nand, 也即 作为开始. 但我觉得保持 的对称性是有用的, 无论是认知上, 还是 对于 的对偶上
[computability] 电路的可计算性
可用逻辑门制造任何 函数
(image from p.85 of ref-1)


分别考虑 函数的输入 和输出
- 输入的构造
根据上图, 使用 条电路 + 个 not gate + 个 and gate , 共 种输入可能性
有些函数只需要 个输入的一部分, 不需要全部. 此时可以不接一些线
代表了 值并行电路的 “乘法” 性质
对于输出, 我们先讨论 输出
- 输出的构造
在 输入中, 将想要输出到 的电线接到 or gate
Example not xor 函数. 将输入 接入输出的 or gate
xor 叫做互斥或, . 这个函数的真值表
| 1 | 1 | 0 |
| 1 | 0 | 1 |
| 0 | 1 | 1 |
| 0 | 0 | 0 |
- 输出的构造. 可以认为是 个 作为其分量
如果不需要完整的 函数, 电路计算元件不一定要按这种固定方式来构建. 可以根据情况, 进一步简化, 减少 gate 数量的使用. 但这里不进入细节
计算单元中多条输入线或输出线的一种符号表示 (p. 54 of ref-1) (3 输入 2 输出)
[control-circuit] 控制电路, 选择器 or 复用器 (multiplexer)
是控制电路. 其功能是
- 时, 输出到 , 不输出到
- 时 输出到 , 不输出到
(p. 81–82 of ref-1)


个输入 需要 条控制电路
[De-Morgan-law] negative dual 律 or De Morgan 律
用穷举证明, 就像人类数数其实也是穷举. 下同
[boolean-algebra]
bool 代数记为 或者
[bool-distributive-law] 分配律
其 negative dual
归纳地 ( 和 指取所有 函数)
类似地
[bool-commutative-law] 交换律 . same for
[bool-associative-law] 结合律 . same for
[periodic-circuit] 周期电路
由晶体振荡器实现
[memory-circuit] 电路记忆
黑箱模型
可能的实现
- 图中间使用环电路重用上一个周期的 Bool 值. 如果关闭 write control, 则 的值不变
- 反相器 (
notgate) 确保电流方向并防止衰减 (通过外部能量) - 假设环电路中黄色部分的值是 , 蓝色部分的值是 . 为了将 写入已有的 , 需要比环电路里的电压更高的写入电压来覆盖循环电路, i.e. 用更高电压 从而 来覆盖已有的
[finite-machine] 有限状态机
[i/o] 电路的输入可能来自外界 (e.g. 传感器, 键盘), 电路的输出也可能到达外界 (e.g. 信号灯, 屏幕)
外界输入的节奏通常不一致于计算机内部周期电路的节奏, 因此需要让外界输入先经过同步元件
[memory-array] 内存阵列
Example 就是从 000, 001, 010 数到 111 时经过的步数, 虽然这假设了我们能识别三位 bit. ,
用多位 bit 包含的自然数范围, 例如 3 bit 的 作为参数, 去对应到真实世界的内容. Example 计算机的字符的表示方式 e.g. ASCII, Unicode, 屏幕的发光点位置和颜色
(image modified from wiki media about ASCII. Hex 是指十六进制)
在实际应用中, 每个地址多个 bit 好于每个地址 1 bit, 或者说, 二维内存阵列比一维高效
(p. 265 of ref-1)
[instruction] 指令
通过指令来控制计算机完成一些电路任务. 指令也由二进制 (多位 bit 的数据) 表示. 指令流由编译器根据源代码生成并存放在内存中, 被读取然后被 CPU 执行
一些常用电路任务
- 自然数的加法
- 判断 bit 数据是否满足所需条件, 例如判断
- 跳转到其它指令的执行
假设一个指令在一个电路周期内完成 (单周期计算机)
Example add 指令. add x_1 x_2. 指令的 bit 数据位分为三个区域, 表示不同类型的信息

-
读取
add指令add指令在adress_0(add x_1 x_2以及adress_1, adress 2来自源代码和编译器的生成)- 固定的内存地址
adress_of_instruction存储的值adress_0被读出,add指令的 index 区的数据被送到控制信号元件 (control unit), 然后计算出控制信号并输出 (细节太多, 见 ref-1)
-
执行
add指令- 输出的控制信号输入到内存的控制电路元件, 读出内存的
x_1inadress_1和x_2inadress_2, 将它们输入到算术元件 (ALU) - 根据输出控制信号, 算术元件的输出
x_1 + x_2被写到adress_1(覆盖了x_1的值)
- 输出的控制信号输入到内存的控制电路元件, 读出内存的
-
进入和读取下一个周期的指令
adress_of_instruction存储的值adress_0被已经设计好的电路送到算术元件, 计算出adress_0 + 1i.e. 下一个指令地址, 被写到adress_of_instruction里面的数据.adress_0 + 1将在下一个电路周期被执行
其它指令可能有多于两个的数据区 (非指令 index 区)
指令流
Example [loop] 循环
周期电路的速度远远高过人类速度 (1 GHz = 每秒 10^9 次周期)
高级编程语言的循环
let i : int = 0;
while (i < 10) {
i = i + 1;
} // result = 10
let i : int = 0;
while (i < 10) {
i = i + 1;
} // result = 10
-
读取指令
bgt(branch_grater_than) 指令存储在adress_0. (指令从源代码和编译器生成.)10在bgt的一个数据区, while loop 需要的指令数量3在bgt的另一个数据区 -
执行指令
执行条件判断
读出
i和10, 在算术元件中比较大小, 根据结果给出控制信号, 结合指令bgtindex 区给出的控制信号根据条件判断的结果, 执行不同的任务
- 时
算术元件根据此判断输出控制信号, 将
adress_of_instruction存储的值改变为下一条指令的地址adress_0 + 1-
adress_0 + 1的指令要执行任务用
add指令计算i + 1, 写回adress_1 -
执行完
add后, 要回到下一次循环的判断add指令的下一条指令是jump指令, 在adress_0 + 2, 执行结果是, 修改adress_of_instruction的值为adress_of_instruction - 2 = (adress_0 + 2) - 2 = adress_0, 实现指令的跳转, 进行下一次循环的判断
- 时
算术元件根据此bgt判断, 输出控制信号, 将adress_of_instruction存储的值改变为adress_0 + 3而不是adress_0 + 1, 跳出 while 循环, 执行后面的指令
[compile] [parse]
用 parser or compiler (编译器) 验证 token 流语言正确性, 本质上是遍历所有语言规则, 然后在内存中存储为带结构的数据 (一些形象的描述: 表格, 结点, 树)
一种实现方法是递归下降, enum + match (或 if else) + 递归
如果想要让软件在计算机上运行, 就要将源代码的 token 流转为带结构的数据, 再转为指令流
如果语言规则很复杂, 可以对语言规则进行 (多次) 分类和分解, 先遍历分类, 再遍历分类里面的规则. Example 分开为 “syntax 检查” 和 “semantics 检查”
抽象和 API (application programming interface) 的概念的启发性例子: 你周围的物品, 不知道制作原理也能方便地使用, 因为它们是被这样设计的
计算机, 除了周期电路高速的优势, 其它优势有, 内存记忆的容量 (1 GB = 2^(30+3) bit = 8589934592 bit) 和记忆持续性 (通电时间)
内存里可以构造复杂的数据结构和计算函数. 对很多其它领域也可能有用
变量 or 变量名的动机是人类无法记忆和处理那么多地址, 变量名是为了用语义协助人类的记忆和使用, 并让计算机自动处理地址
变量 or 变量名使得可以通过地址对内存里面所存储的值进行复用, 可以尽量减少新的地址的记忆和使用