Live2D

【实时更新中】Note -「Intro. to TOC」“我们盛放直到世界倾圮”

  总之就是群友等着看所以就实时更新了, 快帮我捉虫.

\[\mathscr{Lorain~wy~Lora~blea.} \newcommand{\DS}[0]{\displaystyle} % operators alias \newcommand{\opn}[1]{\operatorname{#1}} \newcommand{\card}[0]{\opn{card}} \newcommand{\lcm}[0]{\opn{lcm}} \newcommand{\char}[0]{\opn{char}} \newcommand{\Char}[0]{\opn{Char}} \newcommand{\Min}[0]{\opn{Min}} \newcommand{\rank}[0]{\opn{rank}} \newcommand{\Hom}[0]{\opn{Hom}} \newcommand{\End}[0]{\opn{End}} \newcommand{\im}[0]{\opn{im}} \newcommand{\tr}[0]{\opn{tr}} \newcommand{\diag}[0]{\opn{diag}} \newcommand{\coker}[0]{\opn{coker}} \newcommand{\id}[0]{\opn{id}} \newcommand{\sgn}[0]{\opn{sgn}} \newcommand{\Res}[0]{\opn{Res}} \newcommand{\Ad}[0]{\opn{Ad}} \newcommand{\ord}[0]{\opn{ord}} \newcommand{\Stab}[0]{\opn{Stab}} \newcommand{\conjeq}[0]{\sim_{\u{conj}}} \newcommand{\cent}[0]{\u{\degree C}} \newcommand{\Sym}[0]{\opn{Sym}} \newcommand{\Var}[0]{\opn{Var}} \newcommand{\wg}[0]{\wedge} \newcommand{\Wg}[0]{\bigwedge} \newcommand{\sq}[0]{\opn{\square}} % symbols alias \newcommand{\E}[0]{\exist} \newcommand{\A}[0]{\forall} \newcommand{\l}[0]{\left} \newcommand{\r}[0]{\right} \newcommand{\ox}[0]{\otimes} \newcommand{\lra}[0]{\leftrightarrow} \newcommand{\llra}[0]{\longleftrightarrow} \newcommand{\iso}[1]{\overset{\sim}{#1}} \newcommand{\eps}[0]{\varepsilon} \newcommand{\Ra}[0]{\Rightarrow} \newcommand{\Eq}[0]{\Leftrightarrow} \newcommand{\d}[0]{\mathrm{d}} \newcommand{\e}[0]{\mathrm{e}} \newcommand{\i}[0]{\mathrm{i}} \newcommand{\j}[0]{\mathrm{j}} \newcommand{\k}[0]{\mathrm{k}} \newcommand{\Ex}[0]{\mathbb{E}} \newcommand{\D}[0]{\mathbb{D}} \newcommand{\oo}[0]{\infty} \newcommand{\tto}[0]{\rightrightarrows} \newcommand{\mmap}[0]{\hookrightarrow} \newcommand{\emap}[0]{\twoheadrightarrow} \newcommand{\actl}[0]{\curvearrowright} \newcommand{\actr}[0]{\curvearrowleft} \newcommand{\nsubg}[0]{\triangleleft} \newcommand{\nsupg}[0]{\triangleright} \newcommand{\lin}[0]{\lim_{n\to\oo}} \newcommand{\linf}[0]{\liminf_{n\to\oo}} \newcommand{\lsup}[0]{\limsup_{n\to\oo}} \newcommand{\ser}[0]{\sum_{n=1}^\oo} \newcommand{\serz}[0]{\sum_{n=0}^\oo} \newcommand{\isoto}[0]{\overset\sim\to} \newcommand{\F}[0]{\mathbb F} \newcommand{\x}[0]{\times} \newcommand{\M}[0]{\mathbf{M}} \newcommand{\T}[0]{\intercal} \newcommand{\Co}[0]{\complement} \newcommand{\alp}[0]{\alpha} \newcommand{\lmd}[0]{\lambda} \newcommand{\mmid}[0]{\parallel} \newcommand{\loop}[0]{{\circlearrowleft}} \newcommand{\go}[0]{\triangleright} % symbols with parameters \newcommand{\der}[1]{\frac{\d}{\d #1}} \newcommand{\ul}[1]{\underline{#1}} \newcommand{\ol}[1]{\overline{#1}} \newcommand{\wt}[1]{\widetilde{#1}} \newcommand{\br}[1]{\l(#1\r)} \newcommand{\bk}[1]{\l[#1\r]} \newcommand{\ev}[1]{\l.#1\r|} \newcommand{\wh}[1]{\widehat{#1}} \newcommand{\eval}[1]{\l[\!\l[#1\r]\!\r]} \newcommand{\abs}[1]{\l|#1\r|} \newcommand{\bs}[1]{\boldsymbol{#1}} \newcommand{\dat}[1]{\bs{\mathrm{#1}}} \newcommand{\env}[2]{\begin{#1}#2\end{#1}} \newcommand{\ALI}[1]{\env{aligned}{#1}} \newcommand{\CAS}[1]{\env{cases}{#1}} \newcommand{\pmat}[1]{\env{pmatrix}{#1}} \newcommand{\algo}[1]{\begin{array}{r|l}#1\end{array}} \newcommand{\dary}[2]{\l|\begin{array}{#1}#2\end{array}\r|} \newcommand{\pary}[2]{\l(\begin{array}{#1}#2\end{array}\r)} \newcommand{\pblk}[4]{\l(\begin{array}{c|c}{#1}&{#2}\\\hline{#3}&{#4}\end{array}\r)} \newcommand{\u}[1]{\mathrm{#1}} \newcommand{\t}[1]{\text{#1}} \newcommand{\ts}[1]{\textsf{#1}} \newcommand{\tb}[1]{\textbf{#1}} \newcommand{\os}[2]{\overset{#1}{#2}} \newcommand{\lix}[1]{\lim_{x\to #1}} \newcommand{\ops}[1]{#1\cdots #1} \newcommand{\seq}[3]{{#1}_{#2}\ops,{#1}_{#3}} \newcommand{\dedu}[2]{\u{(#1)}\Ra\u{(#2)}} \newcommand{\prv}[3]{\DS{{\DS #1} \over {\DS #2}}~(#3)} \]

第一章 自动机与语言

\(\S 1.1\) DFA 与 NFA

定义 1.1.1 (DFA)

  称资料 \(M=(Q,\Sigma,\delta,q_0,F)\) 是确定性有限状态自动机 (DFA), 当

  • \(Q\) 是有限状态集;
  • \(\Sigma\) 是有限字符集;
  • \(\delta:Q\x\Sigma\to Q\) 是转移函数;
  • \(q_0\in Q\) 是起始状态;
  • \(F\sub Q\) 是接收状态集.

  若字符串 \(\seq w1n=w\in\Sigma^*\) 在输入 \(M\) 后到达接受状态 \(q\in F\), 即

\[\E(\seq r0n),~r_0=q_0\land(\A i\in[1:n],~\delta(r_{i-1},w_i)=r_i)\land r_n\in F, \]

则称 \(w\)\(M\) 接受.

定义 1.1.2 (语言/正则语言)

  \(A:=\{w\in\Sigma^*:w\u{~accepted~by~}M\}\) 称为由 \(M\) 定义的语言. 若语言 \(A\sub\Sigma^*\) 能被某种 DFA 识别, 则称它是一个正则语言.

  我们知道 \(|\mathcal P(\Sigma^*)|=\aleph_1\), 也容易说明 \(|\{M:\text{automanta with given }\Sigma\}|=\aleph_0\), 所以一定存在非正则的语言.

  这样的非正则的语言其实也容易举出例子: \(\Sigma=\{0,1\}\), \(A=\{w:\#\{0\in w\}=\#\{1\in w\}\}\). Intuitively, 设 \(n=|Q|\), 当我们的字符串长于 \(n\) 时, 前 \(n+1\) 个字符共有至少 \(n+1\) 种状态需要区分 (即两种字符的数量差值), 这是不可能做到的.

命题 1.1.3

  若 \(A,B\) 是正则语言, 则 \(A\cap B\), \(A\cup B\), \(\Co_{\Sigma^*}A\), \(A\circ B\), \(A^*\) 都是正则语言.

  (其中 \(A\circ B:=\{w=xy:x\in A\land y\in B\}\), \(A^*=\bigcup_{k=0}^\oo A^{\circ k}\).)

  → Proof. 前三者都是明显的. 后两者的速通解释是: 我们可以通过有限状态的 DP (你谁?) 判断给定 \(w\) 是否被接受, 那么添加任意有限记录维度的但具有非确定转移的 DP 也是有限状态的, 把这些记录维度直接展开的确定转移 DP (像是 DP of DP) 的状态数也是有限的, over.

  但我们为什么要展开所谓的非确定性转移呢?

定义 1.1.4 (NFA)

  称资料 \(N=(Q,\Sigma,\delta,q_0,F)\) 是非确定性有限状态自动机 (NFA), 当

  • \(Q\), \(\Sigma\), \(q_0\), \(F\) 意义同上;
  • \(\Sigma_\eps:=\Sigma\sqcup\{\eps\}\), \(\delta:Q\x\Sigma_\eps\to\mathcal P(Q)\).

  若字符串 \(\seq w1n=w\in\Sigma^*\) 在输入 \(M\) 后到达接受状态 \(q\in F\), 即

\[\ALI{ \E w'\in\Sigma_\eps^*,~&(w'~\u{is}~w~\u{but~some}~\eps~\u{inserted})\\ &\land r_0=q_0\\ &\land (\E(\seq r0{|w'|}),~\A i\in[1:|w'|],~r_i\in\delta(r_{i-1},w'_i))\\ &\land r_{|w'|}\in F. } \]

则称 \(w\)\(M\) 接受.

  DFA 自然地能被升级为 NFA.

定理 1.1.5

   NFA 编码的语言都是正则语言 (即存在与之等价的 DFA).

  → Proof. 思路其实和上面的讨论别无二致. 对 NFA \(N\), 容易构造 \(M=(Q',\Sigma',\delta',q_0',F')\), 其中

  • \(Q'=\mathcal P(Q)\);
  • \(\Sigma'=\Sigma\);
  • \(\delta'(S,a)=\bigcup_{p\in S}\bigcup_{k=0}^{\oo}(\delta(\cdot,\eps))^k(\delta(p,a))\);
  • \(q_0'=\bigcup_{k=0}^{\oo}(\delta(\cdot,\eps))^k(q_0)\);
  • \(F'=\{S\in Q':F\cap S\neq\varnothing\}\).

  于是, NFA 变成了一种强大的构建 DFA 的方式. 命题 1.3 的结论都可以用 NFA 轻松编码.

\(\S1.2\) 正则表达式

定义 1.2.1 (正则表达式)

  字符串集合 \(R\) 是正则表达式, 当且仅当它一定满足如下之一:

  • \(R=\{a\}\), 其中 \(a\in\Sigma\);
  • \(R=\{\eps\}\);
  • \(R=\varnothing\);
  • \(R=R_1\cup R_2\), 其中 \(R_1,R_2\) 是正则表达式;
  • \(R=R_1R_2\), 其中 \(R_1,R_2\) 是正则表达式, 我们省略了连接运算 \(\circ\);
  • \(R=R_0^*\), 其中 \(R_0\) 是正则表达式.

  例如 (虽然是一些 corner case), \(\{111\}\circ\varnothing=\varnothing\), \(\varnothing^*=\{\eps\}\).

定理 1.2.2

  一个语言是正则语言, 当且仅当它可以被一个正则表达式描述.

  → Proof. 右推左, 对正则表达式的定义进行结构归纳地构建 NFA 即可.

  左推右, 我们需要将任意一个 DFA 转译为正则表达式, 为此, 我们引入充当媒介的 GNFA:

定义 1.2.3 (GNFA)

  一个广义非确定性有限状态自动机是资料 \(G=(Q,\Sigma,\delta,q_s,q_a)\), 其中:

  • \(Q,\Sigma\) 同 NFA; \(q_s\) 是唯一起始状态, \(q_a\) 是唯一接收状态.
  • \(\delta:(Q\setminus\{q_a\})\x(Q\setminus\{q_s\})\to\mathcal R\), 其中 \(\mathcal R\) 是所有正则表达式构成的集合.

  → Proof @ 1.2.2 Cont. NFA 自然地可以被转译为 GNFA, 我们需要证明 GNFA 总是对应一个正则表达式. 归纳地, 对 \(k:=|Q|=2\)\(G\), 显然成立. 对 \(k>2\), 任选 \(q_r\in Q\setminus\{q_s,q_a\}\), 令 \(G':=(Q':=Q\setminus\{q_r\},\Sigma,\delta',q_s,q_a)\), 我们只需要构造 \(\delta'\) 使得 \(G'\)\(G\) 编码同一个语言.

  对任意 \((q_1,q_2)\in Q'\setminus\{q_a\}\x Q'\setminus\{q_s\}\), 简记 \(R_{ij}=\delta(q_i,q_j)~(i,j\in\{1,2,r\})\), 直接枚举所有可能的路径:

\[\delta'(q_1,q_2):=R_{12}\cup R_{1r}R_{rr}^*R_{r2}. \]

明所欲证 (在 Rocq 中, 这四个字可以写作 auto).

\(\S1.3\) 正则性判定

  我们希望判定任意给定的语言是否是正则语言.

引理 1.3.1 (Pumping)

  若 \(A\) 是正则语言, 则

\[\ALI{ \E p\in\N,~\A s\in A,~|s|\ge p\Ra\E x,y,z\in\Sigma^*,~&s=xyz\\ &\land (\A i\ge 0,~xy^iz\in A)\\ &\land |y|>0\\ &\land |xy|<p. } \]

  → Proof.\(A\) 可由 DFA \(M\) 编码, 令 \(p=|Q|\), 任取 \(s=s_1\cdots s_n\in A\), \(n\ge p\), 它对应 \(M\) 上的游走路径 \(\seq r1{n+1}\in Q\). 由鸽巢原理, 不妨设 \(1\le i<j\le p+1\) 使得 \(r_i=r_j\). 令 \(x=s_1\cdots s_{i-1}\), \(y=s_i\cdots s_{j-1}\), \(z=s_j\cdots s_n\), 明所欲证.

  反之, 不满足 pumping 引理的语言一定不是正则语言. 例如:

  • \(B=\{0^n1^n:n\ge 0\}\), 任意的 \(p\) 都被 \(0^p1^p\in B\) 反驳.

    • 值得注意的是, 它的补集 \(B=\{0^n1^m:n\neq m\}\) 不正则, 但取 \(p=3\) 就满足引理.
  • \(C=\{w:\#\{0\in w\}=\#\{1\in w\}\}\), 上面的反例仍然适用.

  • \(D=\{1^{n^2}:n\ge 0\}\), 任意的 \(p\) 都被 \(1^p\in D\) 反驳.

  • \(E=\{0^i1^j:i>j\ge 0\}\), 任意的 \(p\) 都被 \(0^{p+1}1^p\in E\) 反驳 (循环节 \(y\) 的指数取 \(0\) 时).

  • \(F=\{ww:w\in\{0,1\}^*\}\), 任意的 \(p\) 都被 \(0^p10^p1\in F\) 反驳.

例子 1.3.2

  设 \(N\sub\N\), \(A=\{0^n:n\in N\}\), \(B=\{n_1\cdots n_k:(\ol{n_1\cdots n_k})_2\in N\}\), 证明或推翻:

  • (a) 若 \(A\) 正则, 则 \(B\) 正则.
  • (b) 若 \(B\) 正则, 则 \(A\) 正则.

  → Solution. (a) 正确. \(A\) 满足 pumping 引理, 设 pumping 给出 \(p\). 取 \(d=\lcm\{1,\cdots,p\}\), 对任意 \(s=0^n\), \(n>2(d+p)\) 时, 设 pumping 给出 \(s=xyz\), 总能调整 \(|z|<p\) 得到 \(s=xy^kz\), 其中 \(|x|+|z|<2p\), \(|y|<p\), \(|y^k|\ge 2d\). 那么 \(xy^{k-d/|y|}z\in A\), 也即 \(0^{n-d}\in A\). 总之, 我们得到 \(\E n_0\in\N,~\A k\ge n_0,~0^k\in A\Eq 0^{k-d}\in A\) (存在最终周期性). 所以, 除了有限个短特例以外, \(s\in A\) 可由 \(|s|\bmod d\) 确定. 容易构造对应的特判和维护二进制数模 \(d\) 的 NFA 来识别 \(B\). 所以 \(B\) 正则.

  (b) 错误. \(N=\{n\in\N:2\mid\opn{popcount}(n)\}\), \(A\) 显然不能满足 (a) 中推导出的最终周期性.

\(\S1.4\) CFL 与 PDA

定义 1.4.1 (上下文无关文法)

  称资料 \(G=(V,\Sigma,R,S)\) 是上下文无关文法, 当且仅当

  • \(V\) 是有限的变量集;
  • \(\Sigma\) 是有限的终结字符集, \(\Sigma\cap V=\varnothing\);
  • \(R\sub V\x(V\sqcup\Sigma)^*\) 是有限的文法集.
  • \(S\in V\) 是起始变量.

\(u,v,w\in(V\sqcup \Sigma)^*\). 若 \((A,w)\in R\), 也记作 \(A\to w\), 则对任意 \(u,v\) 可记 \(uAv\Ra uwv\). 若 \(u=w\) 或者存在一列 \(u=\seq u0k=w\) 使得 \(u_i\Ra u_{i+1}\), 则记 \(u\overset*\Ra w\). \(G\) 编码的语言定义为

\[A=\{w:S\overset*\Ra w\}. \]

  例如, \(G=(\{A,B\},\{0,1,\#\},R,A)\), 其中 \(R=\{(A,0A1),(A,B),(B,\#)\}\), 则它的语言是 \(A=\{0^n\#1^n:n\ge 0\}\).

  对语言 \(A=\{0^n1^n:n\ge 0\}\cup\{1^n0^n:n\ge n\}\), 我们也能设计文法 \(G=(\{A,B,C\},\{0,1\},R,A)\), 其中 \(R\) 包含

\[A\to\eps\mid 0B1\mid 1C0,\quad B\to\eps\mid 0B1,\quad C\to\eps\mid 1C0. \]

  为了给这类语言构造自动机, 我们可以为 NFA 配备一个 "存储设备", 例如... 一个 "栈".

定义 1.4.2 (下推自动机)

  称资料 \(P=(Q,\Sigma,\Gamma,\delta,q_0,F)\) 是一个下推自动机 (PDA), 当且仅当

  • \(Q\), \(\Sigma\), \(q_0\), \(F\) 同理 NFA;
  • \(\Gamma\) 是有限集, 描述栈字母表.
  • \(\delta:Q\x\Sigma_\eps\x\Gamma_\eps\to\mathcal P(Q\x\Gamma_\eps)\).

它接受 \(w=w_1\cdots w_m\in\Sigma_\eps^*\), 当且仅当存在一列状态 \(\seq s0m\in Q\) 和一列栈状态 \(\seq t0m\in\Gamma^*\), 满足

  • \(s_0=q_0\), \(t_0=\eps\);
  • \(\A i\in[0:m-1],~\E r\in\Gamma^*,~\E a,b\in\Gamma_\eps,~t_i=ar\land t_{i+1}=br\land (s_{i+1},b)\in\delta (s_i,w_{i+1},a)\).
  • \(s_m\in F\).

  记号上, 我们可以在绘制 NFA 的基础上, 在转移边添加形如 \(a\to b\) 的标记.

  当然, 你一定喜欢 PDA 的省流描述: "只是用一个栈作为内存的 streaming algorithm".

定理 1.4.3

  如果一个语言是上下文无关的, 则它可被 PDA 编码.

  → Proof. 设语言的文法为 \(G=(V,\Sigma,R,S)\), 为方便描述, 我们直接以 streaming algorithm 的视角来构造:

\[\begin{array}{r|l} 1& \textit{stack}\text{.push}(\$)\\ 2& \textit{stack}\text{.push}(S)\\ 3& \textbf{repeat}\\ 4& \qquad c\gets \textit{stack}\text{.pop()}\\ 5& \qquad \textbf{if}~~c\in V~~\textbf{then}\\ 6& \qquad \qquad \textbf{fork}~\A(c,w)\in R\\ 7& \qquad \qquad \textit{stack}\text{.push}(w)\\ 8& \qquad \textbf{elif}~~c\in\Sigma~~\textbf{then}\\ 9& \qquad \qquad s\gets \text{nextchar}()\\ 10& \qquad \qquad \textbf{if}~~c\neq s~~\textbf{then}\\ 11& \qquad \qquad \qquad \textbf{return}~~\text{Reject}\\ 12& \qquad \textbf{else}\qquad \texttt{//}~c=\$\\ 13& \qquad \qquad \textbf{return}~~\text{Accept} \end{array} \]

定理 1.4.4

  如果一个语言由一个 PDA 编码, 则它服从某个上下文无关文法.

  → Proof.\(P=(Q,\Sigma,\Gamma,\delta,q_0,F)\), 我们不妨加强对 \(P\) 的限制:

  • 只有一个接受状态 \(q_1\) (新增一个总接受状态, 由 \(\eps\) 边连接);
  • 被接受时清空了栈 (新增若干状态, 初始时压入特殊字符, 接受时先不断弹栈直到弹出特殊字符);
  • 转移时, 要不只压一次栈, 要不只弹一次栈 (否则可以拆成两步转移).

接下来, 我们构造 \(G=(V,\Sigma,R,S)\), \(V=\{A_{pq}:p,q\in Q\}\), \(S=A_{q_0q_1}\), 有三类规则:

\[\ALI{ R_1&=\{A_{pq}\to aA_{rs}b:p,q,r,s\in Q,~u\in\Gamma,~a,b\in\Sigma_\eps,\\ &\qquad\qquad\qquad \qquad (r,u)\in\delta(p,a,\eps)\land(q,\eps)\in\delta(s,b,u)\},\\ R_2&=\{A_{pq}\to A_{pr}A_{rq}:p,q,r\in Q\},\\ R_3&=\{A_{pp}\to\eps:p\in Q\},\\ R&=R_1\cup R_2\cup R_3. } \]

其组合意义是自然的:

  • 第一类描述一次互相匹配的压栈-弹栈: \(u\)\(p\) 因字符 \(a\) 压入, 在 \(s\) 因字符 \(b\) 弹出;
  • 第二类描述路径的组合: 为了从 \(p\)\(q\), 我们可以添加任意途经点 \(r\);
  • 第三类描述 \(p\) 可以直接到达自己.

  我们来严格证明 \(G\) 编码了与 \(P\) 相同的语言. 结论由下面的 引理 1.4.5引理 1.4.6 给出.

引理 1.4.5

  上述语境下若 \(A_{pq}\overset*\Ra x\in\Sigma^*\), 则在 \(P\) 上有 \((p,[])\overset{x}\Ra(q,[])\). (\([]\) 表示空栈, 注意在 PDA 的定义里栈顶是序列的开头.)

  → Proof.\(A_{pq}\overset*\Ra x\) 的步数 \(k\) 归纳. 当 \(k=1\), 规则必须来自 \(R_3\), 则 \(x=\eps\), \(p=q\), 成立.

  接着考虑从 \(k\)\(k+1\) 的归纳. 考察第一步规则, 它只能来自 \(R_1\) 或者 \(R_2\):

  • 若第一步是 \(A_{pq}\to aA_{rs}b\), 归纳地, \(A_{rs}\overset*\Ra y\) 带来 \(P\) 上的转移 \((r,[])\overset{y}\Ra(s,[])\), 则根据定义, 存在 \(u\in\Gamma\) 使得

    \[(p,[])\overset{a}\to(r,[u])\overset y\Ra (s,[u])\overset{b}\to (q,[]). \]

  • 若第一步是 \(A_{pq}\to A_{pr}A_{rq}\), 归纳地, \(A_{pr}\overset*\Ra y\)\(A_{rq}\overset*\Ra z\) 拼起来就得到

    \[(p,[])\overset y\Ra(r,[])\overset z\Ra (q,[]). \]

明所欲证.

引理 1.4.6

  上述语境下若 \(P\) 上有 \((p,[])\overset x\Ra(q,[])\), 则 \(A_{pq}\overset*\Ra x\).

  → Proof. (和上一个引理如出一辙, 别听雨兔念经了.) 对 \(x\)\(P\) 上的转移次数 \(k\) 归纳. 当 \(k=0\), \(p=q\), \(x=\eps\), 规则由 \(R_3\) 给出.

  同样考虑从 \(k\)\(k+1\) 的归纳. 考察是否存在某个中间状态的栈是空栈:

  • 若存在这样的 \((r,[])\), 设 \((p,[])\overset y\Ra (r,[])\overset z\Ra (q,[])\), 归纳地 \(A_{pr}\overset *\Ra y\)\(A_{rq}\overset *\Ra z\), 那么

    \[A_{pq}\to A_{pr}A_{rq}\overset *\Ra yz=x. \]

  • 否则, 必然有 \((p,[])\overset a\to(r,[u])\overset{x'}\Ra (s,[u])\overset b\to (q,[])\), 归纳地 \(A_{rs}\overset*\Ra x'\), 那么

    \[A_{pq}\to aA_{rs}b\overset*\Ra ax'b=x. \]

明所欲证.

 

  当然, 作为一个 "只用单栈的在线算法", PDA 与 CFL 的表达能力亦有局限.

引理 1.4.7 (Pumping)

  若 \(A\) 是 CFL, 则

\[\ALI{ \E p\in\N,~\A s\in A,~|s|\ge p\Ra\E u,v,x,y,z\in\Sigma^*,~{}&s=uvxyz\\ &\land(\A i\ge 0,~uv^ixy^iz\in A)\\ &\land|vy|>0\\ &\land|vxy|\le p. } \]

  → Proof.\(A\) 可由文法 \(G\) 编码. 设 \(b=\max\{|w|:(A,w)\in R\}\), 设从 \(S\) 出发形成的推导树高为 \(h\), 则最终串长不超过 \(b^h\). 另一方面, 若 \(h\ge|V|+1\), 则至少有一个变量在叶子-根的树链中出现了至少两次. 现在取 \(p=b^{|V|+1}\), 对任意 \(s\in A\), 若 \(|s|\ge p\), 则推导出 \(s\) 的树高至少是 \(|V|+1\), 因此就存在上述重复出现的变量, 取对应子树高最小的 \(A\) 和它子树内和它相同的 \(A'\), 满足 \(S\overset*\Ra uAz\), \(A\overset*\Ra vA'y\), \(A'\overset*\Ra x\). 不妨设 \(|vy|>0\) (否则可以精简推导树结构而不改变已有性质), 由子树高的最小性, \(A\) 子树内不再有任何出现在叶子-根树链的重复变量, 因此 \(A\overset*\Ra vxy\) 满足 \(|vxy|\le p\). 显然 \(s=uvxyz\) 已然满足条件.

  例如, \(L=\{a^nb^nc^n:n\ge 0\}\). 对任意 \(p\), \(a^pb^pc^p\) 都无法拆分.

  注意这个 \(L\) 是非常典型的非 CFL 例子, 它可以用来构造很多反例. 例如:

命题 1.4.8

  (a) 存在 CFL \(A,B\), \(A\cap B\) 不是 CFL.

  (b) 存在 CFL \(A\), \(\ol A\) 不是 CFL.

  → Proof. (a) \(A=\{a^nb^nc^*:n\ge 0\}\), \(B=\{a^*b^nc^n:n\ge 0\}\), \(A\cap B=L\).

  (b) 其实可以作为 (a) 的平凡推论: 若 \(\ol A\)\(\ol B\) 都是 CFL, 而 CFL 显然又对 \(\cup\) 封闭, 所以 \(\ol{\ol A\cup\ol B}=A\cap B\) 是 CFL, 矛盾.

 

  既然 NFA 等价于 DFA, 这个 PDA 是否等价于确定性 PDA (DPDA) 呢?

定理 1.4.9

  存在 CFL \(A\) 不是 DCFL, 即它不能被任何 DPDA 识别.

  → Proof. 一个漂亮的 RAA 风味证明: DCFL 显然对取补集封闭, 则 命题 1.4.8 (a) 的反例 \(A\), \(B\), \(\ol A\), \(\ol B\) 中至少有一个不是 DCFL.

  构造主义者吓哭了, 所以我们给两个例子: \(\{ww^{\t R}:w\in\{0,1\}^*\}\)\(\{0^n1^n:n\ge 0\}\cup\{0^n1^{2n}:n\ge 0\}\) (免责声明: 均来自 LLM). 至于它俩是不是真的反例, 我们应该留给构造主义者自己去证.

第二章 图灵机

  (我习惯不音译人名, 但 Turing 出现得实在太多了, 每次插一个单词反而很奇怪.)

\(\S2.1\) 确定性图灵机

定义 2.1.1 [图灵机 (Turing Machine, TM)]

  (a) 一个 \(k\)-tape TM 是七元组 \((Q,\Sigma,\Gamma,\delta,q_0,q_{\u{accept}},q_{\u{reject}})\), 其中:

  • \(\Gamma\) 是有限集, 是纸带字母表; 这里我们采用一种更方便的变种定义:

    • \(\_\in\Gamma\), 它是唯一可以在纸带上出现无穷次的空白字符;
    • \(\triangleright\in\Gamma\), 标识输入字符串起点.
  • \(\Sigma\sub\Gamma\setminus\{\_\}\) 是输入字母表 (可以出现在初始纸带的字符集).

  • \(Q\) 是有限的状态集 (注意它不保存任何读写头位置信息和纸带信息).

  • \(q_0\in Q\) 是初始状态; \(q_{\t{accept}}\) 是接受状态; \(q_{\t{reject}}\) 是拒绝状态.

  • \(\delta:(Q\setminus F)\x\Gamma^k\to Q\x\Gamma^k\x\{\t L,\t N,\t R\}^k\) 是状态转移函数.


  (b) TM 运行时, 设当前状态 \(q\), 读写头读入纸带符号 \(x=(\seq x1k)\), 则取转移 \(\delta(q,x)=(q',x',z)\), 其中:

  • \(q'\) 描述新状态;
  • \(x'\) 描述当前读写头的写入信息;
  • \(z\) 描述每个读写头的移动方式.

  (c) TM 的格局 (configuration 感觉翻译成构型会更高级) \(C\) 记录了其某一时刻的状态, 纸带完整信息和读写头位置. 称 TM \(M\) 输入 \(w\) 时停机, 若存在一列格局 \(\seq C0t\), 使得

  • \(C_0\) 是起始格局: \(q=q_0\), 所有读写头在各自纸带最左侧;
  • \(C_i\) 可由 \(C_{i-1}\) 一步转移到, 且 \(C_i~(i<t)\) 的状态均不是停机状态;
  • \(C_t\) 的状态为停机状态 \(q_{\t{accept}}\) (被接受) 或 \(q_{\t{reject}}\) (被拒绝).

约定 2.1.2

  此后我们简记 (注意这些记号并不通用于其他资料):

  • \(M\os w\to\t A\), \(M\) 接受 \(w\); \(M\os w\to\t R\), \(M\) 拒绝 \(w\).
  • \(M\os w\to\t H\), \(M\) 输入 \(w\) 会停机; \(M\os w\loop\), \(M\) 输入 \(w\) 不停机.
  • \(M[w]\): 已填充输入为 \(w\) 的 TM (一台新图灵机).
  • \(M(w)=x\): \(M\os w\to\t H\) 且按照特定规则能够在输出纸带读出 \(x\).
    • 特别地若 \(M[w]\loop\)\(M'[w']\loop\), 我们也认为 \(M(w)=M'(w')\).

 

  相比上面的各类自动机, TM 的结构更复杂, 其运行的 "结果" 也更复杂: 有接受, 拒绝和不停机这三种可能. 为此, 我们需要更细致地规定其描述的语言:

定义 2.1.3

  (a) 称语言 \(A\) 是图灵可识别 (Turing-recognizable) / 递归可枚举 (recursively enumerable) 的, 当且仅当存在 TM \(M\) 使得

\[\br{\A w\in A,~M\os w\to\t A}\land \br{\A w\in\ol A,~M\os w\to\t R\lor M\os w\loop}. \]

\(L(M)=A\).

  (b) 称语言 \(A\) 是图灵可判定 (Turing-decidable) 的, 当且仅当存在 TM \(M\) 使得

\[\br{\A w\in A,~M\os w\to\t A}\land \br{\A w\in\ol A,~M\os w\to\t R}. \]

这样永不死循环的 \(M\) 称为判定机 (decider).

  喜闻乐见地, 我们也开始关注这台大机器的计算效率:

定义 2.1.4 (计算, 计算复杂度, 时间可构造函数)

  (a) 对 \(f:\{0,1\}^*\to\{0,1\}^*\), 称 \(M\) 计算 \(f\), 当且仅当 \(\A x\in D_f,~f(x)=M(x)\).

  (b) 称 \(M\)\(T(n)\) 运行, 当且仅当对任意输入 \(x\), \(M[x]\) 在不超过 \(T(|x|)\) 步停机.

  (c) 称 \(T:\N\to\R\) 是时间可构造 (time-constructible) 的, 当且仅当存在 TM 计算 \(x\mapsto\lfloor T(|x|)\rfloor\).

 

  来一点简单的例子吧! 我们先装作不知道 TM 的强大能力, 只在原本定义下构造结果.

  例: \(A=\{w\#w:w\in\{0,1\}^*\}\) 可以被 \(1\)-tape TM \(\mathcal O(n^2)\) 地识别:

  • 每次读入第一个非 \(\go\) 字符 \(x\).

  • 循环右移, 直到经过 \(\#\) 且当前字符 \(y\ne\go\):

    • \(x=\_\), 对比完成, 接受; 若 \(x\neq y\), 拒绝.

    • 否则 \(x=y\), \(y\) 写为 \(\go\).

  • 循环左移, 直到回到 \(x\) 的位置, 将 \(x\) 写为 \(\go\).

  例: \(A=\{ww:w\in\{0,1\}^*\}\) 可以被 \(2\)-tape TM \(\mathcal O(n)\) 地识别:

  • 循环地将整个输入串复制到纸带 \(2\).

  • 两个读写头 \(p_1,p_2\) 移动回各自纸带的字符串开头. 接着循环移动 (Floyd 判环的 trick):

    • \(p_2\) 右移一次.
    • \(p_1\) 右移两次, 若第一次右移后读到 \(\_\), 拒绝; 若第二次右移读到 \(\_\), 跳出循环.
  • \(p_1\) 移动回起点. 接着循环移动:

    • \(p_2\) 读到 \(\_\), 接受; 否则若 \(p_1\)\(p_2\) 读入字符不同, 拒绝.
    • \(p_1\), \(p_2\) 各自右移一次.

 

  没听说过 TM 还能用超大有限字符集? 没听说过 TM 还能用多纸带? 没关系, 它们都不会强于我们印象中的原味 TM.

定理 2.1.5

  对任意 TM \(M\), 若它在 \(\Gamma\) 工作, 于 \(T(n)\) 计算 \(f:\{0,1\}^*\to\{0,1\}\), 则存在 TM \(M'\), 它在 \(\Gamma'=\{0,1,\go,\_\}\) 工作, 于 \(\mathcal O(T(n)\log|\Gamma|)\) 计算 \(f\).

  → Proof. 把每个符号展开成 \(\mathcal O(\log|\Gamma|)\) 个 bit, 用相应的时间模拟原 TM 的单步转移.

定理 2.1.6

  对任意 \(k\)-tape TM \(M\), 若它于 \(T(n)\) 计算 \(f:\{0,1\}^*\to\{0,1\}\), 则存在 \(1\)-tape TM \(M'\)\(\mathcal O(kT(n)^2)\) 计算 \(f\).

  → Proof. 交错编码 \(k\) 条纸带即可.

论点 2.1.7 (Church-Turing)

  所有直观意义下的算法都能编码到图灵机.

  我们做证明的时候都已经相信过这一点啦.

引理 2.1.8

  存在嵌入 \(\mathcal D:\{M:\t{TM}\}\mmap\N\).

  这似乎是一个明显到无人在意但确实很有奠基性的引理. (如果你把 \(\mathcal D\) 当成反汇编器, \(\mathcal D^{-1}:=\mathcal C\) 就是编译器.)

  为了方便后面的证明, 若 \(\mathcal D^{-1}(\alp)=\varnothing\), 约定 \(\mathcal C(\alp)\) 对应一个直接拒绝的 TM.

定理 2.1.9

  存在通用 (universal) 图灵机 (UTM) \(U\), 使得 \(\A x,\alpha\in\{0,1\}^*,~U(x,\alp)=M_\alpha(x)\), 其中 \(M_\alp:=D^{-1}(\alp)\), 且若 \(M_\alp[x]\)\(T\) 步停机, 则 \(U[x,\alp]\)\(CT\log T\) 步停机, 其中 \(C\) 是只与 \(M_\alp\) 有关的参数.

  → Proof. 利用 定理 2.1.6, 将 \(M_\alp\) 转化为 \(1\)-tape TM \(M\), 则 \(M\)\(\mathcal O(T^2)\) 步停机. 我们构造 \(U\) 为一个 \(5\)-tape TM, 其中各个纸带的功能为:

  1. 记录输入;
  2. 记录 \(M\) 的描述;
  3. \(M\) 的模拟;
  4. \(M\) 的状态;
  5. 记录输出.

沿此思路做一些细节构造即可, 在此略过 (因为 ck 也略过了).

Remark.

  我也想到过这个问题, 或许你也发现证明的实例就在身边: 看看你的操作系统呢?

\(\S2.2\) 可计算性

  在 定义 2.1.3 中, 我们知道

\[\{\t{decidable languages}\}\sub\{\t{recognizable languages}\}\sub\{\t{languages}\}. \]

它们是否都是真包含关系? 能否找到各自的例子? 如何理论描述这些问题?

  我已在数分, 高代, 离散和 TOC 四门课听了四次集合论入门.

  以后默认 \(\Sigma=\{0,1\}\).

定理 2.2.1

  存在不可识别的语言 \(A\sub\Sigma^*\).

  → Proof. 引理 2.1.8 给出 \(|\{\t{TMs}\}|=\aleph_0<|\Sigma^*|=\aleph_1\).

  构造主义者就要闹了, 我们不理他就好.

定理 2.2.2

  存在不可判定的语言 \(A\sub\Sigma^*\).

  → Proof. 为了安抚构造主义者, 我们构造函数

\[\opn{UC}:\Sigma^*\to\Sigma,~\alp\mapsto 1-[\mathcal C(\alp)\os\alp\to\t A]. \]

我们断言这个 \(\opn{UC}\) 是不可计算的, 也即 \(f^{-1}(1)\sub\Sigma^*\) 不可判定.

  反证, 若有 TM \(M\) 计算 \(\opn{UC}\), 应当有 \(M(\mathcal D(M))=\opn{UC}(\mathcal D(M))\), 但是根据 \(\opn{UC}\) 的定义, \(\opn{UC}(\mathcal D(M))=1-M(\mathcal D(M))\), 矛盾.

  可以看出, \(\opn{UC}\) 的构造其实来源于经典的 Cantor 对角线法. 而它的一个更著名的推论是停机问题的不可计算性.

推论 2.2.3

  (a) 语言 \(\t{HALT}=\{\alp\#x:\mathcal C(\alp)\os x\to\t H\}\) 不可判定.

  (b) 语言 \(\u{A_{TM}}=\{\alp\# x:\mathcal C(\alp)\os x\to\t A\}\) 不可判定但可识别.

  → Proof. (a) 如果存在 \(M_{\t{HALT}}\) 判定 \(\t{HALT}\), 构造判定机 \(M\):

\[M(\alp)=\CAS{ 1-\mathcal C(\alp)(\alp),& M_{\t{HALT}}(\alp\#\alp)=1;\\ 1,& \t{otherwise}. } \]

它计算了 \(\opn{UC}\), 但这不可能.

  (b) \(\u{A_{TM}}\) 显然可识别: 直接 compile & run 即可. 但如果存在 \(M_A\) 判定 \(\u{A_{TM}}\), 构造判定机 \(M\):

\[M(\alp)=[M_A(\alp\#\alp)=1]. \]

它又计算了 \(\opn{UC}\), 这不可能.

  这个推论的证明思路就是我们常说的归约方法. 我们还能再语言上更严格地描述这种归约关系:

定义 2.2.4 [映射可归约性 (mapping reducibility)]

  称语言 \(A\) 映射可归约到 \(B\), 写作 \(A\le_{\t m}B\), 当且仅当

\[\E(\t{computable}~f:\Sigma^*\to\Sigma^*),~\A w\in\Sigma^*,~(w\in A\Eq f(w)\in B). \]

  显然, 如果 \(A\le_{\t m}B\), 那么:

  • \(B\) 可判定, 那么 \(A\) 可判定 (先计算 \(f\) 再在 \(B\) 上判定);
  • \(A\) 不可判定, 则 \(B\) 不可判定 (否则先计算 \(f\) 再在 \(B\) 上判定就判定了 \(A\)).

  所以, 为了证明某个语言 \(B\) 不可判定, 我们只需要找到一个已知不可判定的 \(A\) 并证明 \(A\le_{\t m}B\). 推论 2.2.3 便是将 \(\opn{UC}\) 作为这样的 \(A\) 的例子.

例子 2.2.5

  (a) 语言 \(\u{E_{TM}}=\{\alp:\nexists w\in\Sigma^*,~\mathcal C(a)\os w\to\t A\}\) 不可判定.

  (b) 语言 \(\u{EQ_{TM}}=\{\alp\#\beta:L(\mathcal C(\alp))=L(\mathcal C(\beta))\}\) 不可判定.

  → Proof. (a) 考虑归约 \(\u{A_{TM}}\le_{\t m}\ol{\u{E_{TM}}}\). 若有 \(M_E\) 判定后者, 则构造 \(M\):

\[M(\alp\# x)=M_E(\beta_{\alp,x}),\\ \mathcal C(\beta_{\alp,x})(y)=\CAS{ 0,&x\neq y;\\ \mathcal C(\alp)(y),&x=y. } \]

它就判定了 \(\u{A_{TM}}\), 矛盾.

  (b) 取 \(\mathcal C(\beta)\to\t R\) 即可, 这样 \(\u{EQ_{TM}}\) 的判定器可以判定 \(\u{E_{TM}}\).

 

  我们再来研究刚刚提到的五个语言 (\(\t{UC},\t{HALT},\u{A_{TM}},\u{E_{TM}},\u{EQ_{TM}}\)) 的可识别性:

  • \(\ol{\u{E_{TM}}}\) 可识别: 设 \(\Sigma^*=\{x_1\prec x_2\prec\cdots\}\), 接着运行 \(\mathcal C(\alp)[x_1]\) 一步, 再运行 \(\mathcal C(\alp)[x_1]\)\(\mathcal C(\alp)[x_2]\) 各一步, ..., 如此可以在有限步内发现接受者.
  • \(\u{A_{TM}}\) 可识别: 直接 compile & run.
  • \(\t{HALT}\) 可识别: 直接 compile & run.
  • \(\ol{\t{UC}}\) 可识别: 直接 compile & run.

  我们不太容易严格论证其他的语言不可识别, 但这些观察也启发我们了如下结论:

定理 2.2.6

  语言 \(A\) 可判定, 当且仅当 \(A\)\(\ol{A}\) 可识别.

  → Proof. 左推右显然. 右推左, 交替运行两个识别器, 总有一个在有限步内返回.

  因此 \(\u{E_{TM}}\), \(\ol{\u{A_{TM}}}\), \(\ol{\t{HALT}}\)\(\t{UC}\) 都不可识别. 还剩下 \(\u{EQ_{TM}}\)\(\ol{\u{EQ_{TM}}}\), 我们尝试证明二者皆不可识别:

命题 2.2.7

   \(\u{EQ_{TM}}\)\(\ol{\u{EQ_{TM}}}\) 不可识别.

  → Proof. 对于 \(\u{EQ_{TM}}\), 若 \(M_Q\) 识别它, 则构造 \(M\) 满足

\[M(\alp\# x)=M_Q(\alp\#\beta_{\alp,x}),\\ \mathcal C(\beta_{\alp,x})(y)=\CAS{ \mathcal C(\alp)(y),&x\neq y;\\ 0,&x=y. } \]

\(M\) 识别了 "\(\mathcal C(\alp)\) 不接受 \(x\)", 即 \(\ol{\u{A_{TM}}}\), 矛盾.

  对于 \(\ol{\u{EQ_{TM}}}\), 若 \(M_Q'\) 识别它, 完全对称地构造 \(M'\) 满足

\[M'(\alp\# x)=M_Q'(\alp\#\beta_{\alp,x}),\\ \mathcal C(\beta_{\alp,x})(y)=\CAS{ \mathcal C(\alp)(y),&x\neq y;\\ 1,&x=y. } \]

\(M'\) 识别了 "\(\mathcal C(\alp)\) 不接受 \(x\)", 也即 \(\ol{\u{A_{TM}}}\), 矛盾.

  下面两个命题来自 第二次作业 7.

引理 2.2.8

  给定 \(1\)-tape TM \(M\) 和输入 \(w\), 存在对 \(M[w]\) 运行历史的编码方式, 设 \(A=\{H:M~\text{correctly accepted}~w~\t{in}~H\}\) 包含所有正确记录 \(M\) 接受 \(w\) 的运行历史的字符串 (至多一个元素), 则 \(\ol A\) 是 CFL.

  → Proof. 对一列格局 \(C_0,\cdots,C_k\), 构造其编码 \(\mathcal H(\seq C0k)=\#q_0@w_0\#q_1@w_1^{\t R}\#\cdots\#\), 其中 \(q_i\)\(C_i\) 的 TM 状态编码, \(w_i\)\(C_i\) 的纸带状态, 并包括了特殊字符 \(\uparrow\) 记录指针位置. 构造 PDA \(P\), 它接受所有 \(\ol A\) 内的字符串. 具体地, \(P\) 非确定性地选择如下错误原因之一:

  分隔符错误: 字符串的开头或结尾不是 \(\#\), 或者两个相邻的 \(\#\) 之间包括零个或多余一个 \(@\), 或者存在相邻 \(\#@\), \(@\#\), \(\#\#\).

  初始格局错误: 读取前两个 \(\#\) 之间的编码 \(q_0@w_0\), 字符串比对它是否和期待的 \(C_0\) 一致.

  接受格局错误: 非确定性地选取一对相邻的 \(\#\) 读取 \(q@w\) (或 \(q@w^{\t R}\), 可以在 PDA 内部维护当前 \(w\) 是否反转), 如果发现这不是最后一个格局, 直接拒绝; 否则检查 \(q\) 是否为 \(q_{\t{accept}}\).

  状态转移错误: 非确定性地读取三个相邻 \(\#\) 之间的 \(q@w^{\t R}\)\((q')@(w')\) (后一项反转时完全同理), 不妨设 \(|w|=|w'|\): 先读取并记录 \(q\), 再读取 \(w^{\t R}\) 并逐字符压栈; 接着读取并记录 \(q'\), 然后读取 \(w'\) 并弹栈, 非确定性地枚举出指针附近 (包括指针下一个字符, 指针移动到的位置) 的字符串, 这个小子段中只有有限种可能, 因此可以在 PDA 中硬编程实现 TM 转移状态 \(q'\), 纸带状态 \(w'\) 和指针移动情况的检查. 其他情况要求来自 \(w^{\t R}\) 的弹出字符与来自 \(w'\) 的输入字符保持一致即可.

  综上, \(P\) 识别了 \(\ol A\), \(\ol A\) 是 CFL.

  这个引理给出如下直接推论:

命题 2.2.9

  \(\u{ALL_{CFG}}=\{\alp:\mathcal C(\alp)~\text{defined a CFG}\land L(\mathcal C(\alp))=\Sigma^*\}\) 不可判定.

  → Proof. 利用 引理 2.2.8 归约到 \(\u{A_{TM}}\).

 

Remark.

  好啦, 我们似乎已经对图灵可识别性做出了有一定见地的刻画, 但也可以隐约察觉图灵可识别语言与所有语言这两个集合之间的巨大空洞... 我们要加强图灵机! 为了方便自然语言叙述, 我们就从程序语言的角度来看这些机器.

  一个自然的想法是, 我们允许代码长度 (可数) 无穷. 但这太过平凡: 叠加可数无穷条 if 语句就能识别所有语言.

  那么... 如果我们允许图灵机完成超任务呢? 具体来说, 我们可以加入一条指令

\[\tb{syscall}^0\quad M\quad x \]

它以参数 \(x\) 调用 TM \(M\) (可以视作编码在程序里的一个函数), 并立即获知 \(M[x]\) 的结果, 包括停机时的输出或者 "\(M[x]\) 不停机" 这个事实. (其实我也想把这个指令叫做 \(\tb{dream}\), 表示托梦.)

  我们称原本的图灵机为 \(0\)-TM, 记为 \(\mathcal M_0\), 允许 syscall \(k\)-TM 的 "TM" 称为 \((k+1)\)-TM, 记为 \(\mathcal M_{k+1}\), 对应的 syscall 指令记为 \(\tb{syscall}^k\). 明显, \(\mathcal M_{k+1}\) 总是严格强于 \(\mathcal M_k\), 但由于 \(|\mathcal M_k|=\aleph_0\), 它们都无法识别所有语言, 但也因此我们可以像研究 TM 一样研究这些 "高阶 TM" 的性质.

  再进一步, 我们或许可以构造 "\(\omega\) 层嵌套 syscall 的 \(\mathcal M_\omega\)", 等等. (之所以需要区分 syscall 阶次, 是因为我觉得需要避免 "\(M\) syscall \(M\)" 这样的自指行为, 这样的行为很可能让系统不一致.)

  我暂时没法给出这些高阶 TM 的有趣性质, 但这个定义本身也很有趣不是吗~

第三章 图灵机时间复杂性

\(\S3.1\) 时间复杂性

定义 3.1.1

  对时间函数 \(T:\N\to\N\), \(\t{DTIME}(T):=\{A\in\Sigma^*:A~\t{decidable in }T(n)\}\).

定理 3.1.2 [时间谱系 (time hierarchy)]

  若 \(g\) 是时间可构造函数, \(f(n)\log f(n)=o(g(n))\), 则 \(\t{DTIME}(f(n))\subsetneq\t{DTIME}(g(n))\).

  → Proof. 只需说明不等号. 构造语言 \(E\) 的判定机 \(M_E\):

  • 输入 \(\alp\), 模拟 \(\mathcal C(\alp)[\alp]\) 运行 \(f'\) 步, 其中 \(f'\log f'=\Theta(g)\).
  • 如果得到了输出 \(b\), 则输出 \(1-b\); 否则输出 \(1\).

计数器和 TM 模拟的每步需要 \(\log f'\), 所以 \(M_E\)\(\mathcal O(f'\log f')\) 的. 如果 \(E\in\t{DTIME}(f)\), 则存在判定机 \(M^*\)\(\mathcal O(f)\) 判定 \(E\).

  作为判定机, \(M^*(\mathcal D(M^*))=[\mathcal D(M^*)\in E]\); 但 \(1-M_E(\mathcal D(M^*))=[\mathcal D(M^*)\in E]\), 不可能超时. 得到矛盾.

定义 3.1.3

  (a) 时间复杂性类 \(\ts{P}:=\bigcup_{c\ge 0}\t{DTIME}(n^c)\).

  (b) 语言 \(L\) 属于时间复杂性类 \(\ts{NP}\), 当且仅当

\[\E~{\t{poly}}~P:\N\to\N,~\E M\in\ts P,~\A x\in\Sigma^*,~\br{x\in L\Eq\E u\in\Sigma^{P(|x|)}, M(x\# u)=1}. \]

即, 存在一个 take 多项式长度 "证书" 的 verifier 在多项式时间验证是否 \(x\in L\).

  (c) 时间复杂性类 \(\ts{EXP}:=\bigcup_{c\ge 0}\t{DTIME}(2^{n^c})\).

  独立集问题 (\(u\) 编码取出的独立集), 旅行商问题 (\(u\) 编码一条具体路径), 子集和问题 (\(u\) 编码取出的元素列表) 都是典型的 \(\ts{NP}\) 问题.

命题 3.1.4

  \(\ts{P}\subseteq\ts{NP}\subseteq\ts{EXP}\).

  → Proof. 前一对显然, 后一对直接枚举证书 \(u\) 即可.

  根据 定理 3.1.2, \(P\subsetneq\ts{EXP}\), 所以 \(P\subseteq\ts{NP}\)\(\ts{NP}\subseteq\ts{EXP}\) 至少一个不取等. 有生之年会知道是哪个吗?

定义 3.1.5 [非确定性图灵机 (Non-deterministic Turing Machine, NDTM)]

  (a) 简略地说, 在 TM 的基础上, NDTM 的 \(\delta\) 可以有多个 (WLOG, 两个) 输出, 分支出多个并行运行的 NDTM. 它接受某个输入, 当且仅当存在任何一个分支接受.

  (b) 称 NDTM \(N\)\(T(n)\) 运行, 当且仅当对所有长为 \(n\) 的输入, \(N\) 的所有分支都在 \(T(n)\) 步内停机.

  (c) 对 \(T:\N\to\N\), \(\t{NTIME}(T)\) 表示所有被某个 NDTM \(\mathcal O(T(n))\) 判定的语言.

定理 3.1.6

  设 \(\ts{NP'}=\bigcup_{n\ge 0}\t{NTIME}(n^c)\), 则 \(\ts{NP'}=\ts{NP}\).

  → Proof. 右含于左, 以 NDTM \(\mathcal O(P)\) 地并行枚举出所有可能的证书, 再在每个分支 \(\mathcal O(P)\) 验证即可.

  左含于右, 把每次非确定性选择的正确路径记录在证书里, 交由 TM 验证.

  为了探索 \(\ts{P}\)\(\ts{NP}\) 之间的关系, 我们可以先尝试找到 \(\ts{NP}\) 中最 "难" 的问题, 也即建立 \(\ts{NP}\) 中的难度关系.

定义 3.1.7 (多项式归约, \(\ts{NP}\)-hard, \(\ts{NP}\)-complete)

  (a) 称 \(A\le_{\u p} B\), 当且仅当存在多项式可计算的 \(f:\Sigma^*\to\Sigma^*\), 使得 \(\A x\in\Sigma^*,~x\in A\Eq f(x)\in B\).

  (b) 若 \(\A A\in\ts{NP},~A\le_{\u p} L\), 则称 \(L\)\(\ts{NP}\)-hard 的.

  (c) 若 \(L\in\ts{NP}\)\(\ts{NP}\)-hard 的, 则称 \(L\)\(\ts{NP}\)-complete 的.

  如果 \(\ts{NP}\)-complete 的 \(L\) 存在, 那么 \(L\in\ts P\Eq\ts P=\ts{NP}\), 找到一个 \(L\) 的例子无疑是重要的.

定理 3.1.8 (Cook-Levin)

  设 \(\varphi\) 为 CNF Boolean 表达式, 即 \(\varphi=\bigwedge_i\bigvee_j v_{ij}\), 其中 \(v_{ij}\in\{x_n\}\cup\{\ol{x_n}\}\). 则

  (a) 设 \(\t{CKT-SAT}=\{\t{all satisfiable CKT formulas}\}\), 它是 \(\ts{NP}\)-complete 的. 其中 \(\t{CKT}\) 是任意多项式层的逻辑函数集.

  (b) 设 \(\t{SAT}=\{\t{all satisfiable CNF formulas}\}\), 它是 \(\ts{NP}\)-complete 的;

  (c) 设 \({}^3\t{SAT}=\{\t{all satisfiable 3-CNF formulas}\}\), 它是 \(\ts{NP}\)-complete 的.

  → Proof. (a) \(\t{CKT-SAT}\)\(\ts{NP}\)-complete 性是容易的: 它显然在 \(\ts{NP}\) 中, 且通过硬编码验证机的格局转移就能构造相应电路. (或者, 把你电脑的时序逻辑展开成多项式层组合逻辑!)

  (b) 从 (a) 出发, 要求证书提供 \(u\) 和所有 (a) 中电路所有结点的输出, 容易用 CNF 判断电路元件合法性.

  (c) 对 (b) 的任意子句 \(C_i=A_i\lor B_i\), 其中 \(B_i\) 有两个字符, 则新建变量 \(u_i\), \(D_i=A_i\lor u\), \(D_i'=B_i\lor\lnot u_i\), 最后将所有 \(D\) 字句合取即可.

Remark.

  关于 (b), 我觉得上面的证法比课上那堆编码 TM 的 dirty work 聪明许多.

\(\S3.2\) 时间完全性问题

  定理 3.1.8 给出了三个 \(\ts{NP}\)-complete 问题, 接下来喜闻乐见的工作便是向它的归约.

  以下问题都是 \(\ts{NP}\)-complete 的:

命题 3.2.1 (最大独立集)

  \(\t{INDSET}\): 给定无向图 \(G\) 和整数 \(k\), 判定 \(G\) 中是否存在大小为 \(k\) 的独立集.

  → Proof. 显然 \(\t{INDSET}\in\ts{NP}\). 接下来尝试证明 \(^3\t{SAT}\le_{\u p}\t{INDSET}\). 构造多项式可算的

\[f:\psi\to(G,k),\quad \psi\in{}^3\ts{SAT}\Eq(G,k)\in\t{INDSET}. \]

\(\psi\) 中每个字句 \(C_i\), 共有 (不超过) \(7\) 种赋值使它 SAT, 为每种赋值创建一个顶点. 则 \(|V|=7m\). 如果不同 \(C_i\) 的两个赋值不相容, 则建一条边. 后续就简单了.

命题 3.2.2 (最小点覆盖)

  \(\t{VTXCOV}\): 给定无向图 \(G\) 和整数 \(k\), 判定 \(G\) 中是否存在 \(k\) 个结点覆盖了所有边.

  → Proof. 显然 \(\t{VTXCOV}\in\ts{NP}\), 而 \(\t{INDSET}\le_{\u p}\t{VTXCOV}\), 因为点覆盖的补是独立集.

命题 3.2.3 (整数规划)

  \(\t{IPROG}\): 给定 \(m\) 个有理系数线性不等式, 判定是否存在对 \(x\in\{0,1\}^n\) 的赋值使所有不等式成立.

  → Proof. 显然 \(\t{IPROG}\in\ts{NP}\). \({}^3\t{SAT}\le_{\u p}\t{IPROG}\) 的方法比较多, 比如暴力把 \(a\lor b\lor c\) 记为 \(a+b+c\ge 1\).

命题 3.2.4 (Hamilton 路)

  \(\t{HPATH}\): 给定有向图 \(G\), 判定 \(G\) 中是否存在 Hamilton 路 (点不交地遍历所有点的路径).

  → Proof. 是一个用 \(\t{SAT}\) 的巧妙归约构造. 对某个变量 \(u_i\) 设它在某个子句 \(C_j\) 中取 \(u_i\), 在另一个 \(C_k\) 中取 \(\lnot u_i\), 构造形如:

\[\begin{array}{ccccc} \vdots&&C_j&&&&&&&&\vdots\\ \downarrow&&\uparrow&~~\searrow&&&&&&&\downarrow\\ v^i_0 & \overset\cdots\longleftrightarrow & v^i_j & \longleftrightarrow & v^i_{j'}&\os\cdots\longleftrightarrow&v_{k'}^i&\longleftrightarrow&v_k^i&\os\cdots\longleftrightarrow&v_{m+1}^i\\ \downarrow&&&&&&&\nwarrow~~&\downarrow&&\downarrow\\ \vdots&&&&&&&&C_k&&\vdots \end{array} \]

(我们就免去唠叨地严谨叙述了.) 可见, 我们通过 \(v^i\) 这条链的遍历方向来规定了 \(u_i\) 的真值, 当 \(u_i\) SAT 了某个合取子式, 它就可以顺向进入子式结点.

命题 3.2.5 (Hamilton 环路)

  \(\t{HCYCLE}\): 给定有向图 \(G\), 判定 \(G\) 中是否存在 Hamilton 环路.

  → Proof. 新增 \(v_s\) 连向所有原图点, 所有原图点连向 \(v_t\), \(v_t\) 连向 \(v_s\).

命题 3.2.5 (无向 Hamilton 路)

  \(\t{uHCYCLE}\): 给定无向图 \(G\), 判定 \(G\) 中是否存在有向 Hamilton 路.

  → Proof. 用有向版本归约. 在有向图中, 把每个结点拆为 \(x,y,z\) 三个点, 连接 \((x,y),(y,z)\), 有向边 \((u,v)\) 构造为 \((u_z,v_x)\) 即可.

命题 3.2.5 (旅行商问题)

  \(\t{TSP}\): 给定带权有向图 \(G\), 判定 \(G\) 存在访问每个结点恰好一次的路径, 使得边权和不超过 \(k\).

  → Proof.\(\t{HPATH}\) 容易归纳. 环路版本也一样.

\(\S3.3\) NP 相关的复杂性类

定义-命题 3.3.1

  (a) \(\ts{coNP}:=\{L:\lnot L\in\ts{NP}\}\).

  (b) \(L\in\ts{coNP'}\) 当且仅当

\[\E~{\t{poly}}~P:\N\to\N,~\E M\in\ts P,~\A x\in\Sigma^*,~\br{x\in L\Eq\E u\in\Sigma^{P(|x|)}, M(x\# u)={\color{red}{0}}}. \]

两个定义等价.

  注意 \(\ts{coNP}\neq\lnot{\ts{NP}}\). 事实上 \(\ts{P}\sub\ts{NP}\cap\ts{coNP}\). 我们也能研究所谓 "\(\ts{coNP}\)-complete" 的问题.

  \(\ts{coNP}\os?=\ts{NP}\) 也是一个 open problem. 例如, \(\lnot\ts{SAT}\)\(\ts{coNP}\)-complete 的, \(\ts{coNP}=\ts{NP}\) 意味着我们能够给出一个多项式长度的 "说明一个 SAT 问题不可满足" 的证书, 人们对此大多不太有信心.

定义 3.3.2

  \(\ts{NEXP}:=\bigcup_{c\ge 0}\opn{NTIME}(2^{n^c})\).

定理 3.3.3

  \(\ts{P}=\ts{NP}\Ra \ts{EXP}=\ts{NEXP}\).

  → Proof. 考虑某个 \(L\in\opn{NTIME}(2^{n^c})\), 它被 NDTM \(N\) 判定, 设 \(L':=\{x\#1^t:t=2^{|x|^c}\}\), 那么 \(x\in L\Eq x\#1^t\in L'\). 根据定义, \(L'\in\ts{NP}\), 如果 \(\ts{P}=\ts{NP}\), 有 \(L'\in\ts{P}\), 反过来就给出 \(L\in\ts{EXP}\).

Remark.

  一个比较令人 (我) 满意的 happy ending 是 \(\ts{P}=\ts{NP}\), 但依赖 RAA. 当然这方面的畅想也会引出很多有意思的脑洞问题.

第四章 图灵机空间复杂性

\(\S4.1\) 空间复杂性

定义 4.1.1

  函数 \(S:\N\to\N\) 描述在输入规模为 \(n\) 时, 某台 TM 最大的 work tape 使用量 (work tape 排除了 input tape, 这时通常认为 input tape 不可写). 一般来说 \(S\) 是空间可构造 (space-constructible) 的, 即 \(S(n)\) 可在 \(\mathcal O(S(n))\) 空间计算.

  称 \(L\in\t{SPACE}(S(n))\), 当且仅当存在 \(\mathcal O(S(n))\) 的 TM \(M\) 判定 \(L\); 称 \(L\in\t{NSPACE}(S(n))\), 当且仅当存在 \(\mathcal O(S(n))\) (指所有分支停机且 work tape 用量不超过这一量级) 的 NDTM \(N\) 判定 \(L\).

  不同于时间复杂性一般考虑的 \(T(n)\ge n\), 由于假定输入纸带不可写, 我们更感兴趣 \(S(n)<n\) 的问题. 而为了 TM 至少能描述输入串的下标, 通常也考虑 \(S(n)\ge \log n\).

  \(\t{DTIME}(S(n))\sub\t{SPACE}(S(n))\sub\t{NSPACE}(S(n))\sub\t{DTIME}(2^{\mathcal O(S(n))})\).

  → Proof. 只说明最后一个包含: \(\t{NSPACE}(S(n))\) 的 NDTM 只产生 \(2^{\mathcal O(S(n))}\) 种格局, 在格局图上搜索是否存在从初始格局到接受格局的路径, 就能模拟一台 NDTM.

定义 4.1.3

  定义空间复杂性类:

  • \(\ts{PSPACE}:=\bigcup_{c\ge 0}\t{SPACE}(n^c)\);
  • \(\ts{NPSPACE}:=\bigcup_{c\ge 0}\t{NSPACE}(n^c)\);
  • \(\ts{L}:=\t{SPACE}(\log n)\);
  • \(\ts{NL}:=\t{NSPACE}(\log n)\).

  例如, \(\t{SAT}\in\ts{PSPACE}\), 同理用证书版本的定义可知 \(\ts{NP}\sub\ts{PSPACE}\).

  一些 tricky 的小例子:

  • \(\t{EVEN}:=\{x:x~\t{has even \# of}~0\}\in \t{SPACE}(1)\), 当然你也可以认为它是不需要任何空间的自动机.
  • \(\t{MULT}:=\{(a,b,ab)\}\in\ts{L}\), 我们可以先枚举位 (\(\log n\) space), 再枚举检查所有贡献到这一位的 \(1\), 检查奇偶性是否与 \(ab\) 中的对应位置相同.
  • \(\t{PATH}:=\{(G,s,t):\E~\t{path}~(s\to t)\in G\}\in\ts{NL}\), 这是平凡的. 事实上它是 \(\ts{NL}\)-complete 的, 而 \(\ts{L}=\ts{NL}\) 是 open 的.

定理 4.1.4 (Space Hierarchy)

  若空间可构造的 \(f,g\) 满足 \(f(n)=o(g(n))\), 则 \(\t{SPACE}(f(n))\subsetneq\t{SPACE}(g(n))\).

  → Proof. 考虑 \(M[\alp]\): 模拟运行以 \(\mathcal O(g(|\alp|))\) 的空间, \(2^{\mathcal O(g(|\alp|))}\) 的时间限制模拟 \(\mathcal C(\alp)[\alp]\), 如果完成运行, 则反转输出; 否则拒绝. 显然 \(M\in\t{SPACE}(g(n))\). 如果 \(M\in\t{SPACE}(f(n))\), 则可以要求 \(M\in\t{DTIME}(2^{\mathcal O(f(n))})\), 那么 \(M[\mathcal D(M)]\) 能够完成对 \(M\) 自己的模拟, 但输出总会导致矛盾.

\(\S4.2\) 空间完全性问题

  我们可以仿照时间完全性来定义空间完全性.

定义-命题 4.2.1

  考虑 Quantified Boolean Formula (QBF) \(\varphi:=Q_1x_1\cdots Q_nx_n~\phi(\seq x1n)\), 其中 \(Q_i\in\{\A,\E\}\), \(\phi\) 是任意 Boolean formula. (可以证明所有量词不在前缀的 QBF 都可以转换成上述形式.)

  设 \(\t{TQBF}:=\{\varphi\in\t{QBF}:\varphi=\t{True}\}\), 则 \(\t{TQBF}\)\(\ts{PSPACE}\)-complete 的.

  → Proof. 显然 \(\t{TQBF}\in\ts{PSPACE}\) (什么叫做课件写了四页来证, 水课时来了), 下证 \(\t{TQBF}\)\(\t{PSPACE}\)-hard 的. \(\A L\in\ts{SPACE},~L\le_{\u p}\t{TQBF}\).

  对给定的 \(L\), 设 \(M\)\(S(n)\) 空间判定 \(L\), 而编码 \(M\) 的格局需要 \(m=\mathcal O(S(n))\) 的空间. 我们需要构造多项式可算的 \(f:\{0,1\}^*\to\t{QBF}\), 使得 \(f(x)\in\t{TQBF}\Eq x\in L\). 固定输入 \(x\), 对 \(M[x]\) 的任意两个格局编码 \(c,c'\), 显然存在 \(\mathcal O(m)\) 的 Boolean formula \(\phi(c,c')\) 判断转移是否合法. 我们希望检查是否能从 \(M[x]\) 的初始状态编码 \(c_0\) 转移到接受状态编码 \(c_1\), 为此, intuitively, 可以倍增地构造

\[\ALI{ \psi_0(c,c')&:=\phi(c,c'),\\ \psi_{k+1}(c,c')&:=\E c''~\psi_k(c,c'')\land\psi_k(c'',c'). } \]

然而这样的递归展开之后并非多项式长度, 但一个 tricky 的修正:

\[\psi_{k+1}(c,c'):=\E c''~\A d~\A d'~((d=c\land d'=c'')\lor(d=c''\land d'=c'))\to\psi_k(d,d'). \]

就能够让 \(\psi_m\) 的长度变为 \(\mathcal O(m^2)=\mathcal O(S(n)^2)\). (其中的 \(=\)\(\to\) 也容易展开为基本逻辑运算.) 事实上这个 \(f\) 可以 \(\mathcal O(\log m)\) 额外空间地完成计算 (不考虑输入和输出纸带).

  直接利用这个归约, 我们知道 \(\t{TQBF}\)\(\t{NPSPACE}\)-hard 的, 所以 \(\t{NPSPACE}=\ts{PSPACE}\).

  由于 \(\t{SAT}\)\(\lnot\t{SAT}\) 都是 \(\t{QBF}\), 我们知道 \(\ts{NP}\)\(\ts{coNP}\) 都是 \(\t{PSPACE}\) 的子集.

推论 4.2.2 (Savitch)

  对任意 \(S=\Omega(\log n)\), \(\t{NSPACE}(S(n))\sub\t{SPACE}(S(n)^2)\).

  → Proof. 和上面的思路相似. 若 \(N\in\t{NSPACE}(S(n))\) 判定 \(L\), 对给定输入 \(|x|=n\), 考虑 \(N[x]\) 的格局图, 它至多存在 \(2^m\) 个结点 (\(m\) 的定义同上), 我们需要判定从初始格局到接受格局的路径的存在性. 同样倍增计算并复用递归的空间即可.

推论 4.2.3

  \(\t{TQBF}\) 无法在 \(\mathcal O(\t{polylog}(n))\) 空间内解决.

  → Proof. 归约算法是 \(\ts{L}\) 的, 进而若 \(\t{TQBF}\)\(\mathcal O(\t{polylog}(n))\) 空间解决, \(\t{PSPACE}\) 就不强于这个空间复杂性类, 违背了分层定理.

posted @ 2026-03-27 19:25  Rainybunny  阅读(133)  评论(1)    收藏  举报