3

是否有可能在每一种图灵完备语言中创建一个 quine? ” 说:

任何图灵完备的编程语言,并且能够输出任何字符串(通过作为程序的字符串的可计算函数——这是存在的每种编程语言都满足的技术条件)都有一个 quine 程序(并且,在事实上,无限多的 quine 程序,以及许多类似的好奇心)如下定点定理。

如果我创建了具有以下输出处理程序的语言 X:

public void outputHander( OutputEvent e ){
  String msg = e.getMessage();
  String src = Runtime.getSource();
  if( msg.equals(src) ){
    e.setMessage("");
  }
}

这可以防止以任何方式输出源。

如果语言 X 的解释器一直在屏幕上检查它的源并且找到了源,它会在它到达屏幕之前被删除。

鉴于空程序会抛出非空白错误,Language X 是否仍然是图灵完备的?为什么?

4

2 回答 2

1

尽管可以防止 quine,但它仍然可以模拟不需要 I/O 的图灵完备算法。语言 X 的图灵完备性是未知的。

于 2019-06-09T12:39:54.600 回答
0

你如何证明你的语言不会被欺骗输出它自己的源代码?为了使它工作,你的语言不能有任何方式来运行外部程序,否则,它可能会意外地将其源代码的适当编码版本发送到命令行工具,如 uuencode 或 rot-13 或其他东西. 几乎任何 UNIX 工具都可以充当解码器。

你的语言也不能自己运行,它不能是解释器,它必须是编译器。否则,它可以修改自己以输出自己的源代码。最重要的是,您的编译器不能用于以任意语言创建解释器,否则,您将手上有一个 quine。

而且,一旦您削弱了该语言以使其无法用于创建任意语言的解释器,就很难看出在什么意义上您会称其为图灵完备。为了被证明不会输出 quine,您的语言必须按照图灵标准非常弱,而且肯定不是图灵完整的。

编辑 - 对话已经开始类似于关于可以在别针头上放置多少个天使的古老争论。因此,我将尝试以严格的方式解决这个问题。虚拟化无关紧要,因为图灵机是计算设备的抽象模型,在原始图灵机模型上实现的唯一 I/O 是打印符号的可移动磁带。相同的磁带用作内存——既用于数据存储也用于程序存储。整个对话似乎取决于图灵机是否必须能够输出任意字符串才能获得图灵完备的资格。我将通过定义一个输出语言 X 源代码的图灵机(图灵机 L)来证明这一点。仅编译代码的机器可能不符合图灵完备的条件,因为该代码可能永远不会运行。因此,我们将语言 X 的实现定义为解释器而不是编译器。

如果将语言 X 的源代码与程序代码/其他数据/其他输出混合,那么输出语言 X 的源代码是否算数,这是一个自然的问题。所以我们将定义这个图灵机在它的磁带上有一个零点。零点左侧的任何内容都是代码或数据。零点右侧的所有内容都用于输出。图灵机 L 有许多(无限)不同的实现。但是它们都有一个预定义的代码部分,可以包含零个或多个字节的程序代码和/或数据。

它在所有方面都是具有正常指令集的普通图灵机,只是将两个数字相加的指令以特殊方式实现。该指令的代码实际上包含语言 X 源代码的适当编码版本。在正常情况下,添加功能的行为与典型的图灵机一样。但是,每当磁带头在数据部分遇到字符串“祝你生日快乐...”时,加法指令的行为就会有所不同。在这种情况下,它会在磁带的输出部分将解码后的源代码打印为语言 X。“祝你生日快乐......”可以很好地存在于磁带的代码/数据部分,而不会触发加法指令的替代行为。它'“祝你生日快乐......”触发了替代行为。这意味着语言 X 必须解决停机问题,以防止图灵机 L 在不改变其行为的情况下将源代码输出到语言 X——这是它永远做不到的。语言 X 必须能够运行(模拟)图灵机 L 才能获得图灵完备的资格。这意味着如果语言 X 是图灵完备的,那么它必须能够运行无限数量的图灵机 L 实现,将源代码输出到语言 X,并且不能干扰,否则它将无法正确模拟语言 X。

现在,询问仅从内存中擦除输出的字符串是否有资格阻止图灵机 L 强制 Language X (应该是图灵完备的)输出它自己的源代码 - 同时保持 Language X 的图灵完备性仍然是有效的。我坚持认为事实并非如此——我也会证明这一点。我们将简单地定义图灵机 L 的导数:图灵机 L'。这与图灵机 L 几乎相同,并且与图灵机 L 一样,它有许多不同的实现。唯一的区别是图灵机 L' 带有用于验证其输出部分完整性的机制。如果磁带头遇到“祝你生日快乐……”,那么除了触发交替的加法行为外,还有一个叫做“生日快乐寄存器”的特殊寄存器。将其位从 0 翻转到 1(它也可以翻转回来)。翻转该位后,图灵机 L' 将读取磁带的输出部分,寻找语言 X 的解码源代码。如果找到,一切正常。但如果没有,那么机器的 JZ(如果为零则跳转)指令的行为会有所不同(它会以一种更不可预测的方式移动磁带磁头,就像它发生故障一样)——但只有一次“生日快乐寄存器”已经翻了回来。此外,每当此验证未能找到所需的源代码时,加法指令也会表现异常,有时会进行加法,有时会使用将源代码输出到语言 X 的替代行为。现在,因为通过擦除图灵的输出机器 L' (语言 X 的源代码)您已经改变了它的行为,现在您必须解决停止问题以便正确模拟它,同时每次出现时仍将源代码擦除为语言 X。这是不可能的。更糟糕的是,语言 X无法提前知道图灵机 L' 是如何实现的,因为图灵机 L 和图灵机 L' 的有效实现有无数种。所以语言 X 必须在图灵完备和拒绝输出自己的源代码之间做出选择。它不能两者兼得。

EDIT2 - 另一个证明。图灵机被定义为具有符号带、非空符号集和定义在这些符号子集上的非空转换函数(指令)的机器(移动带、加法、乘法等) . 如果一台图灵机可以模拟任何其他图灵机,那么它就是图灵完备的。图灵机可以定义为只有两个符号,并且仍然可以是图灵完备的。例如,这些符号可能是<blank>1。现在假设我们采用任何功能齐全的图灵机(无限数量的图灵机,一些图灵完整,一些不完整)用符号<blank>和定义1,但不是1,我们使用X语言的源代码。所以这个图灵机原则上可以做任何任务。它可以计算斐波那契数、打印“hello world”、下国际象棋、计算在轨卫星的轨道参数等。每当它进行任何这些计算时,它都会输出(到其内部数据存储)一些副本源代码转换为语言 X,以空格分隔。语言 X 要么能够模拟整个类的图灵机,要么不能。如果 X 语言可以模拟整个图灵机类,那么它可能是图灵完备的。如果它不能,那么它不是。每一台图灵机都可以模拟图灵机整个可能性空间中的每一台图灵机。无数的图灵机。

于 2020-06-14T20:12:41.197 回答