CS 学生通常手头有图灵机到整数的编码,他们在编写软件图灵机模拟器时需要它,该模拟器将图灵机作为输入,并将指定机器的输出作为输出写入。可以安排这种编码具有每个整数都是不同的有效程序的属性。
所以列出和执行所有程序的天真的两行代码是:
for (int i = 0; ; ++i)
printf("%d: %d\n", i, universal_turing_machine(i));
这忽略了在 C 中,int 是一个固定宽度的类型。
现在,显然该程序并没有走多远,因为很快它就会遇到i,相应的图灵机不会停止。所以“燕尾”技巧是从第一台机器运行一条指令,然后从第二台机器运行一条指令,从第一台机器运行一条指令,然后从第三台机器运行一条指令,第二台机器,第一台机器,依此类推。当每台机器停止时(如果它停止了),您当然可以停止处理它,或者在它的“时间片”中什么也不做。
考虑到每一步图灵机之间必要的上下文切换,我不太清楚这是一个“双线”。但是dovetail程序有理论上的用途(在实践中可能没有用处)。关于它的一件有趣的事情是它具有以下属性:
如果存在解决方案P
多项式时间内的问题 X(并提供证明解决方案所需的信息),然后
燕尾程序解决 X 在
多项式时间。
证明相当简单(相当于执行P*(P-1)/2图灵指令到达正确程序的开头P[*],然后执行它的多项式时间比执行它所花费的时间更短。自行执行该程序)。我觉得最有趣的属性的重新陈述是:
如果 P=NP,那么我们已经知道
所有的多项式解
NP完全问题。
我们只是还没有证明它们是多项式的。 P=NP 的证明将完成该证明,而无需实际展示哪个子程序解决了问题。燕尾程序本身可以在运行过程中计算出来——当每台机器停止时,使用多项式时间“这是原始输入的 X 的解决方案吗?” X 是 NP 所暗示的算法。如果是解决方案,则输出并停止。如果不是,请继续。
[*] 好吧,也许是线性时间,因为当你创建每个新的虚拟图灵机时,你需要给它一个输入的副本来处理。同样在实践中,上下文切换可能不是恒定时间,所以称之为二次。 Hand-wave-hand-wave 多项式可以吗?