2026-08-28·作者 Sijie Wang#idea#math

binary-successor

二进制加一:n ↦ n+1

父节点:examples

思路:从最右边的比特开始,把末尾连续的 1 翻转成 0(进位),再把遇到的第一个 0(或空白)翻转成 1。

七元组 (Q, Γ, b, Σ, δ, q₀, F)。

  • Q = {carry, done};q₀ = carry;F = {done}。
  • Γ = {0, 1, b}(b = 空白);Σ = {0, 1}。
  • δ ——「操作手册」:
δ(carry, 1) = (carry, 0, L)     a trailing 1 becomes 0, keep carrying left
δ(carry, 0) = (done,  1, R)     first 0 absorbs the carry -> 1, stop
δ(carry, b) = (done,  1, R)     ran off the left (e.g. 11 -> 100): blank -> 1

在输入 1011(= 11)上的执行轨迹,读写头位于最右边的比特(^ = 读写头;左侧为状态):

carry:  1 0 1 1        scanned Γ-symbol = 1
              ^        look up δ(carry,1)=(carry,0,L)   [uses δ + Q]
carry:  1 0 1 0        wrote 0 (Γ); moved L; stayed carry (Q)
            ^
carry:  1 0 1 0        scanned 1  ->  δ(carry,1)=(carry,0,L)
            ^
carry:  1 0 0 0        wrote 0; moved L
          ^
carry:  1 0 0 0        scanned 0  ->  δ(carry,0)=(done,1,R)
          ^
done:   1 1 0 0        wrote 1; moved R; entered done
            ^

done ∈ F → 停机。输出 1100 = 12。✓

每一步是哪个部件在起作用: 读写头 + Γ 给出被扫描到的符号 → δ + Q 选定动作 → 写入的是 Γ,{L,R} 方向移动读写头,Q 随之更新 → 是否停机则由 F 检验。

用代码表达——地道的 Haskell

图灵机的 δ 字面上就是一个模式匹配函数,Q/Γ/{L,R} 是代数数据类型,纸带则是一个列表 zipper (left-reversed, current, right)。转移表一一对应地映射到各条匹配分支上:

data St = Carry | Done deriving Eq
data Mv = L | R

-- delta: each rule of the table is one pattern-match clause
delta :: St -> Char -> (St, Char, Mv)
delta Carry '1' = (Carry, '0', L)   -- trailing 1 -> 0, carry left
delta Carry '0' = (Done,  '1', R)   -- first 0 -> 1, stop
delta Carry _   = (Done,  '1', R)   -- blank -> 1 (ran off the left)

-- tape zipper: ls is the left half reversed, c the scanned cell, rs the right
run :: St -> [Char] -> Char -> [Char] -> [Char]
run Done ls c rs = reverse ls ++ c : rs                 -- F-test: halt
run q    ls c rs =
  let (q', w, m) = delta q c                            -- look up delta
  in case m of                                          -- write w, then move
       L -> case ls of (l:ls') -> run q' ls'      l   (w:rs)
                       []      -> run q' []        'b' (w:rs)
       R -> case rs of (r:rs') -> run q' (w:ls)    r   rs'
                       []      -> run q' (w:ls)    'b' []

-- run Carry (reverse "101") '1' ""  ==>  "1100"   (11 + 1 = 12)

这份严丝合缝的对应正是要点所在:δ = 模式匹配,状态 = 一个 ADT,纸带 = 一个 zipper——图灵机就是一个微型的函数式程序。把 delta 换成另一张表,同一个 run 就会执行出一台不同的机器——这正是把 δ 当作数据来使用的通用机。

关于这一条

sijie 的一条 wiki 条目。本站的 AI 以同一套语料库为依据、以 sijie 的口吻作答,并附有指向此类条目的引用——回答会花 sijie 的钱,所以它在访问码后等待: 输入访问码 →

binary-successor — Sijie Wang