||
写过程序的人都熟悉这样的语句:
if x == 0:y = 1else:y = 2
我们自然觉得,计算机理解 if 是天经地义的,这是最基本的条件逻辑。但问题来了:一台图灵机,它只有三件法宝——读、写、左右移动,外加有限状态。它怎么“知道”什么是 if?
这里要讲的,就是如何把高级语言里的逻辑分叉,一层层剥皮,编译回图灵机最底层的“格子动作”。
图灵机的底层世界图灵机的规则永远是:
在状态 q,读到符号 s → 把它改成 s′,移动一格(L/R),进入新状态 q′。
它并不会说:“判断条件是否成立”,它只会说:“读到 1 的时候去状态 q1;读到 0 的时候去状态 q0”。所以 “条件分支”就是不同符号对应不同状态转移。换句话说,if 并不需要额外发明,而是状态表的天然功能。
示例:二进制 +1 的分叉还记得我们在课堂上手算二进制加法的进位逻辑吗?
如果末位是 0 → 改成 1 → 停机。
如果末位是 1 → 改成 0 → 继续向左传递进位。
如果一路全是 1,直到最左边 → 在最左边补 1。
这就是一个标准的“if-else if-else”结构。
翻译到图灵机语言:
(q_carry, 1) → (q_carry, 0, L) ; 读到1,写0,继续左移(传递进位) (q_carry, 0) → (q_done, 1, R) ; 读到0,写1,结束(停止进位) (q_carry, □) → (q_done, 1, R) ; 一路全是1,遇到空格,在最左补1没有任何魔法,这三条转移就完成了 if … elif … else …。逻辑分支就是纸带上的“读符号分路”。
逻辑算子的编译套路(状态 × 符号 → 转移)先记一个万能小模板(两行就够):
结果格 res:res 是 1 → 走路线 Ares 是 0 → 走路线 B
所谓“编译逻辑”,就是先把条件算成一格上的 1/0,然后按这两行跳转。下面全用这套。
NOT(取反)目标:if not P: A else: B
先把 P 算出来,写到 res(1 表示“按 A 路走”,0 表示“按 B 路走”)。
对调去向:
res 是 1 → 去 B
res 是 0 → 去 A
记忆:NOT = 把 A/B 的门对调一下。AND(与)
目标:if P and Q: A else: B(带“短路”)
先算 P,写到 res。
在 res 处看一眼:
是 0 → 直接去 B(P 都没过,没必要看 Q)。
是 1 → 再去算 Q,把结果写回 res。
再按万能模板跳:
res 是 1 → A
res 是 0 → B
记忆:AND = 先看 P;P 过了才看 Q。OR(或)
目标:if P or Q: A else: B(带“短路”)
先算 P,写到 res。
在 res 处看一眼:
是 1 → 直接去 A(已经满足,无需看 Q)。
是 0 → 再去算 Q,写回 res。
再按万能模板跳:
res 是 1 → A
res 是 0 → B
记忆:OR = 先看 P;P 不行才看 Q。复杂条件(一句话心法)
遇到“这一段有没有 0 且右边有没有 #”这类条件,做法只有一条:边走边做记号(在几格上写下“看到 0”/“看到 #”的痕迹),走回“结果格”把答案写成 1/0,然后仍然用那两行万能模板跳转。
为什么这很重要?从 if 到图灵机的转译,揭示了一个核心事实:
逻辑分支不是天上掉下来的,而是有限状态机+符号匹配的自然结果。
高级语言里的条件判断、布尔逻辑,本质上都是“在状态 q 读到符号 s 时,走哪条边”的不同画法。
看似聪明的“if”,其实就是纸带与状态的组合——图灵机的基本循环。
这也解释了为什么一台看似简陋的图灵小机(只会 0/1、左/右)竟能归约任何高级程序。因为所有 if / else / and / or 都能在状态表里逐条落地。
小结:从哲学到工程的桥哲学上:if 是“分叉思维”的最小单元。
工程上:if 在图灵机里就是“符号 + 状态 → 转移”的一条规则。
历史上:图灵 1936 年用这张表,告诉世界计算的本质就是这种有限规则的无限展开。
所以,当你在 Python 里写下一行 if,不妨想象:在底层,正有一只“图灵小蚂蚁”,在纸带上一格一格爬行,根据读到的是 0 还是 1,决定是左转、右转,还是停下来宣布:“我算完啦!”
Archiver|手机版|科学网 ( 京ICP备07017567号-12 )
GMT+8, 2025-9-21 06:28
Powered by ScienceNet.cn
Copyright © 2007- 中国科学报社