3 通用程序
3.1 程序的代码
- Q: 为了确定指令的代码,直观的想法是用3个自然数分别表示标号(label)、涉及的变量以及()
A: 对变量执行的操作(空、增、减,或者若不为零跳转至哪个标号) - Q: 从编码的角度,考察为什么规定\(\mathscr S\)程序中可能出现多个相同标号。
A: 为了一一对应,避免出现过多不合法的程序(当然实际执行时,规定只跳转到第一个标号,写通用程序时也按照此约定。使用有界极小化) - Q: 从编码的角度,考察为什么需要空指令。
A: 哥德尔编码末尾任意增加0相当于增加多条\(Y\to Y\). 不产生效果。借此可以良定义一个自然数集与程序子集的一一映射(子集:考察的程序末尾不能是0对应的指令\(Y\to Y\)) - Q: 为了一一对应,空数列的哥德尔数是()故空程序的哥德尔数是()
A: 1, 0
3.2 停机问题
- Q: ()的势大于()所以存在()的部分函数。
A: 自然数集上全体函数,自然数集的势,不是部分可计算。 - Q: 解说“对角线方法”,“不在表中,矛盾”(分别对实数集不可数和停机问题说明)
A: 这两个问题的证明都是“不在表中,矛盾”。对于实数集,列好可数行可数列的表,构造新的实数第\(i\)位与第\(i\)个数不同,则该实数不在表中,矛盾。
对于停机问题,列好可数行可数列的表,构造新的程序(IF HALT(x,x) THEN 死循环
),对\(x\)的是否停机和第\(x\)个程序不同,则该程序不在表中,和(如果停机问题可计算则)该程序在表中矛盾。
本质上就是第\(x\)位和第\(x\)个对象不同,从而保证了和可数个对象都不同。
更本质地,反映了\(2^X\)的势大于\(X\)的基本原理。
3.3 通用程序
- Q: 解说记号\(\Phi_y(x),\Phi(x,y)\),并区别于\(HALT\).
A: \(\Phi_y(x)\)省略上标1,表示用编号为\(y\)的程序诱导出一元函数,并把\(x\)作为输入。\(y\)是指定常数。(之前是程序诱导一元函数,现在是程序的编码诱导一元函数)
如果\(x,y\)同时作为变量,则用\(\Phi(x,y)\)表示。
\(\Phi(x,y)\)部分可计算,\(HALT\)不可计算,当\(\Phi(x,y)\uparrow\)时\(HALT(x,y)=0\) - Q: 通用程序中哪些部分对应了状态、快相、增、减、转移至不存在的标号?
A: 状态:\(S\),用哥德尔编码。
快相:除了\(S\)还有\(K\),\(K\)表示指令从上到下的序号(不一定等于标号)。初始为1
转移至不存在的标号:有界极小化得到结果0,则\(K\)变为0,随即程序终止运行。(回忆GOTO E
的语义)
增减:乘或整数除法(\(\lfloor a/b\rfloor\))(注意当\(P|S\)时说明某变量本就为0,则无需运算) - Q: 计步(\(STP^{(n)}(x_1,\cdots,x_n,y,t)\))的计算程序相比通用程序需要改哪些地方?
A: 多维护一个变量表示步数(不等于指令从上到下的序号!)(思考:你弄清楚程序的编码、指令的标号、指令从上到下的序号、步数的区别和联系了吗?)
步数超出一定值强行终止。
终止时不输出计算结果,而是如果非强行终止就令\(Y\leftarrow 1\).
3.4 递归可枚举集
- Q: 递归,递归可枚举,通用程序,停机问题有何联系?
A: 提示:确保有输出结果,用输出是1还是0区分,就是递归、停机问题。
不确保有输出结果,有可能停机或不停机。停机则一定停机,不停机时不知道是尚未运行到还是真的不停机(回忆“极小化”运算),则是递归可枚举、通用程序。
这几者之间的联系可以由上看出。具体地可以由此构造出非递归集和非递归可枚举集,更具体的略。 - Q: 计步、“并行”、并集有何联系?
A: 用计步函数(每个循环中分别对两个程序做判断)可以“模拟”“并行”的两个程序,从而可以证明递归可枚举集并集仍递归可枚举。
注:以及\(B,\bar B\)递归可枚举等价于\(B\)递归。 - Q: 递归函数,原始递归函数,部分递归函数,递归语言,递归集,递归可枚举集有何联系?“枚举”一词具体来源为何?
A: 原始递归函数是递归函数的真子集,递归函数等价于可计算函数,是全函数。部分递归函数等价于部分可计算函数,不一定是全函数。递归语言特征函数递归,递归集特征函数递归。递归可枚举集是递归集的真超集,其特征函数不一定递归,但任一个递归可枚举集存在至少一个对应的自然数(表示程序编码),故称“可枚举”(枚举定理) - Q: \(\neg HALT(n,n)\)的自然数\(n\)构成集合为(),因为如果不然,则根据定义存在编号为\(n_0\)的程序满足()。
A: 非递归可枚举集,\(HALT(n,n_0)\Leftrightarrow n在待考察集合中\Leftrightarrow \neg HALT(n,n)\)矛盾(取\(n=n_0\))
3 通用程序 习题
- Q: 证明莱斯定理。\(HALT(0,x)\)不可计算为什么是莱斯定理特例?
A: 莱斯定理:不可能计算:某个编码诱导的函数是否属于部分可计算函数类的指定非空真子集(非平凡子集)。
其证明:如果可以计算某上面所述非空真子集\(A\)的特征函数,则不妨设\(A\)不包含空函数,则其中有一函数\(f\),一个数\(a\)满足\(f(a)\downarrow\),则:对于任意\(s,t\)(不要写成\(x,y\)否则混淆)可以(可计算地)构造程序
Z <- \Phi(s, t) #注意\Phi部分可计算,所以此宏指令合法。区分\Phi和HALT
Y <- f(x)
该程序在\(\Phi(s,t)\downarrow\)时计算的部分可计算函数就是\(f\),属于\(A\);否则计算的是空函数,一定不属于\(A\).
该程序的编码为\(s,t\)的可计算函数\(encode(s,t)\),则谓词:\(encode(s,t)\in A\)就是\(HALT(s,t)\).
停机问题不可计算,\(encode\)可计算则谓词\(n\in A\)不可计算
显然满足\(HALT(0,x)\)的\(x\)是部分可计算函数类的非空真子集。
- Q: 已知程序编号和快相求快相后继只是简单的分类讨论,因此是()的。所以计步函数()。“简单的分类讨论”思想还能得出没有“循环”,即条件转移不会往()转移的\(\mathscr S\)程序计算的函数也是()。
A: 原始递归,原始递归,前或自身(指令所在行数小于等于自身),原始递归函数 - Q: 证明不存在可计算函数\(f(x)\)使得\(\Phi(x,x)\downarrow\)时\(f(x)=\Phi(x,x)\)
A: 否则存在可计算函数\(g(x)\)使得\(\Phi(x,x)\downarrow\)时\(g(x)=\Phi(x,x)+1\),设计算\(g\)的程序编号\(n\),则\(g(n)=\Phi(n,n)+1=g(n)+1\).
注:这其实也是对角线方法,因为对于任意编号为\(x\)的程序,\(g\)可计算但是\(\exists x_0=x,s.t.g(x_0)\ne \Phi(x_0,x)\),则\(g\)编号不为\(x\),\(g\)不在表中,矛盾! - Q: 上一节题1.说“并行”判断\(f_1(x)\)或\(f_2(x)\)停机。是否能做到当其中一个部分\(f_1\)能停机时就一定输出和\(f_1\)相同的结果?
A: 不能。否则考察\(f_1(x)=\Phi(x,x)\)和(存在)一个可计算函数\(f_2\),则“并行判断”总是能停机(\(f_1\)或\(f_2\)至少一个可计算),这个“判断”是可计算函数,则根据2.即得结论。 - Q: \(W_n=\{m|HALT(m,n)\}\),\(A\)为r.e.,则\(\cup_{n\in A}W_n\)和Cantor编码有何联系?
A: 对于任何此集合中的元素\(t\),存在\(a\)使得\(t\in W_a\),其中判断\(a\in A\)需要运行\(\Phi(a, x_A)\)共\(b\)步,判断\(t\in W_a\)需要运行\(\Phi(t,a)\)共\(c\)步。则用三元Cantor编码枚举\((a,b,c)\)即可。
注:也可以令\(d=max\{b,c\}\),则只需要二元Cantor编码。