【问题标题】:Is a language built specifically to not print quines still Turing complete? [closed]专门为不打印 quines 而构建的语言是否仍然是图灵完备的? [关闭]
【发布时间】:2017-08-18 16:16:00
【问题描述】:

Is it possible to create a quine in every turing-complete language?”表示:

任何编程语言 图灵完备,并且能够 输出任何字符串(通过可计算的 字符串作为程序的功能— 这是一个技术条件 对每一次编程都很满意 存在的语言)有一个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 是否仍然是图灵完备的?为什么?

【问题讨论】:

  • 我投票结束这个问题,因为“Software Engineering”是一个更好的网站。
  • @theTinMan 首先,如果您认为这个问题不合适,那么投票关闭是不正确的功能。您将其标记为版主干预,然后将您希望它迁移到的站点放入框中。
  • @theTinMan 其次,以正确的方式进行操作,软件工程可能会拒绝迁移,因为它与编写软件相关的策略无关。
  • 这个问题太老了,无法迁移。
  • 问题在发布后的 60 天内无法迁移。

标签: output semantics turing-complete quine


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    您如何证明您的语言不会被欺骗而输出自己的源代码?为了使它工作,你的语言不能有任何方式来运行外部程序,否则,它可能会意外地将其源代码的适当编码版本发送到命令行工具,如 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 强制语言 X(应该是图灵完备的)输出它自己的源代码——同时保持语言 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 可以模拟这一整类图灵机,那么它可能是图灵完备的。如果它不能,那么它不是。每一台图灵机都可以模拟图灵机整个可能性空间中的每一台图灵机。无数的图灵机。

    【讨论】:

    • 好信息.. 没有回答问题。
    • 我无法让您满意地回答这个问题。我回答了为什么您的语言(如果它满足您的要求 - 即阻止输出 quine)不是图灵完备的。现在,如果您问“鉴于该语言不是图灵完备的,而是空程序上的错误,那么它现在是图灵完备的吗?”,那么额外的语言功能无法以任何方式改变我的答案。
    • 我认为你想多了。这真的很简单:如何使程序无法输出它自己的源代码:1)在执行完成之前不要打印任何东西而不会中断。 2) 如果执行完成,获取打印的 sha-512 散列,并将其与源的 sha-512 散列进行比较。如果哈希值相等,则不打印任何内容。 3)如果要编译一个空程序,抛出一个错误。
    • 在 quine 的情况下,如果程序不使用外部资源来帮助它,它只是一个 quine。在 quine 中使用外部库不是真正的 quine,因此外部库不是问题。
    • 用自己的语言构建编译器是没有问题的,因为任何编译器也必须遵循不能打印 quines 的规则。当然,这个编译器甚至可以自己编译!是编译器!我认为您的意思是,反编译器无法自行反编译。
    猜你喜欢
    • 2011-04-05
    • 1970-01-01
    • 2017-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-18
    • 2020-07-07
    相关资源
    最近更新 更多