【问题标题】:Could a program determine if another program plays chess?一个程序能否确定另一个程序是否下棋?
【发布时间】:2011-11-29 22:30:13
【问题描述】:

我想知道以下问题。我显然不希望有任何实际的解决方案,但我会感谢任何开发人员对此的想法:

理论上是否有可能让一个程序打开其他程序(为了论证,假设它打开 .exe 文件),并确定执行时是否特定可执行文件(具有固定输入和机器状态) ,下国际象棋(在它可能执行的任何其他任务中)。

对于“下棋”,我的意思是对棋盘和棋子进行一些表示,然后应用源自内置国际象棋 AI 引擎的黑白棋步。

这种理论上的“国际象棋检测程序”可能包含虚拟机或 PC 模拟器或其他任何东西,以便在必要时实际模拟扫描的可执行文件。我们可以假设它在具有同上 ram 的任意速度的计算机上运行。


(编辑)关于停机问题,我可以这样解决:

将程序加载到具有 N 位(硬盘和内存空间以及 CPU 寄存器)的虚拟机中。这个虚拟机最多可以假设 2^N 种不同的状态。

逐步执行VM中的程序。在每一步之后,检​​查它是否停止。 如果是:问题已解决(结果:是,它停止了)。 如果否:获取虚拟机的当前状态,并查看该状态是否存在于我们之前已经遇到的状态列表中。如果是:问题已解决(结果:否,它将永远运行)。如果否:将此状态添加到列表中并继续。

由于最多可以出现 2^N 种不同的状态,因此该算法将在有限时间内确定程序是否停止。


(Edit2) 扫描的可执行文件或运行它的(虚拟)机器的(无限)有限性似乎有些模棱两可。假设要扫描的可执行文件最多为 1 GB(这应该足够了,因为大多数国际象棋程序要小得多),并且它们应该在具有 10 GB 内存的 PC(或 VM)上运行。

我们理论上的国际象棋检测程序可以使用任意数量的 ram。

【问题讨论】:

  • 编写一个程序,检测可以检测象棋程序的程序。然后在您的任意速度的计算机上创建随机 .exe 文件,并等待它检测到您正在寻找的 exe。 (不,这是不可能的)
  • 为什么不呢? (尽管国际象棋检测器检测器很可能比国际象棋检测器更难)
  • IF 你想要做的是抓住作弊者,那么你为什么要关心弄清楚“exe”可执行文件是否可以下棋。相反,扫描内存中的当前运行程序,它可以为您提供每个程序的快照,并且更容易处理并且不会减少到停止问题。
  • 这不是我的想法,但听起来很有趣。您将如何确定当前正在运行的程序是否正在下棋? (确实不管它是否会停止)
  • 你可以做一些事情,比如在内存中寻找一个位板表示。 en.wikipedia.org/wiki/Bitboard 这样做的好处是,位板通常占用相当大的连续内存块,每块 64 位(板上每方格 1 位),其中一些移动编码在 64 位字中。

标签: algorithm executable theory detect chess


【解决方案1】:

不,没有这样的算法可以检测可执行文件是否下棋。

这方面的证据在于以下问题(称为停机问题)无法通过任何算法解决:

给定一个计算机程序,该程序最终会终止吗?

我们可以证明,如果有一个计算机程序可以确定另一个程序是否下棋,我们就可以解决停机问题。为此,我们将编写一个执行以下操作的计算机程序:

  1. 将其他一些计算机程序 P 作为输入。
  2. 运行程序 P.
  3. 如果程序 P 终止,下棋。

这个程序有以下有趣的行为:当且仅当程序 P 终止时,它才下棋。换句话说,如果我们可以检测到这个程序是否可以下棋,我们将检测程​​序 P 是否终止。但是,我们知道这可证明是不可能的,所以一定没有程序可以检测某些计算机程序是否下棋。

这种通用方法称为停止问题的简化,可用于表明大量不同的问题可能无法解决。

希望这会有所帮助,对于“否”的回答,我们深表歉意!

【讨论】:

  • 我认为这种推理方式行不通。假设我们的问题是“我们能否确定 9 的平方根是否为 3”。现在用上面的步骤 1 和 2 编写一个计算机程序,将步骤 3 替换为“如果程序 P 终止,将 9 除以 3 并测试结果是否等于 3”。事实上,您的国际象棋能力三步测试甚至没有将程序 PC 作为输入,该程序是要测试国际象棋能力的程序。
  • @phoog:“您的国际象棋能力三步测试甚至没有将要测试国际象棋能力的程序[..]作为输入。” - 我想你看错了。他正在描述程序以输入到我们的 chess-detection-oracle。如果存在这样的 chess-detection-oracle,则必须解决停止问题以确定上述程序是否曾经下过棋。
  • @BlueRaja-DannyPflughoeft 啊哈,当然,感谢您直言不讳。
【解决方案2】:

关于您编辑的问题:是的,如果我们限制内存的大小,所以我们只有有限多个可能的程序,我们理论上可以枚举每个可能的程序并手动将它们分为“下棋”和“非下棋” - 国际象棋“根据您想要的任何标准。

在这种情况下,我们将不再有图灵机,因此停止问题不适用。相反,我们会有一个finite state machine(是的,这意味着在现实世界中,所有计算机实际上都是图灵机的有限状态近似)。

但是,您添加此限制是因为您想要“实用,而不是理论”,所以这里还有一点实用性:枚举所有 256 位程序 (有 10 亿台 PC,每个每秒枚举十亿个程序)将花费比宇宙年龄更长的时间来完成。那么,您很难想象枚举所有小于 1 GB(约 1,000,000,000 位)的程序需要多长时间。

因此,将真实计算机建模为图灵机实际上比有限状态机更实用;而在这种模式下,正如@templatetypedef 所证明的那样,这是不可能的。

【讨论】:

  • 同意我们正在处理的荒谬数字的不切实际方面。这只是理论上的,我只是添加了限制以确保我们正在处理有限状态机(感谢澄清该术语)。但现在我想知道:我们真的可以客观地确定给定程序是否下棋吗?我的意思是,它可以隐藏在如此多的抽象层中,以至于我们根本不会认出它是国际象棋。
【解决方案3】:

没有。这相当于停机问题。

【讨论】:

  • 请注意我上面关于停止问题的编辑。我认为最初的停止问题是关于检测可以在 infinite 计算机上运行的程序。这不适用于这里。
  • 但是使用比特序列来表示国际象棋游戏的方法有无数种。
  • 如果我们限制要检查的可执行文件有帮助吗? (见上面的edit2)
  • 即使你只考虑有限长度的位序列,你仍然有无数种方法来解释每个序列。例如,您如何知道 1000001 是表示整数 65 还是 ASCII 字符“A”,或者可能是有符号的 7 位整数 -63,或者可能是某些未知编码方案中的字符“k”,或者可能是两个 6 位索引一个 64 元素的数组,代表一个棋盘,或者可能是位图图像的一部分,或者......
【解决方案4】:

程序下棋是什么意思?我不相信这个问题存在一个精确的数学定义,它不能被玩弄,也不会等同于无法处理的问题。

例如,如果您问“这个程序下棋时是否存在移动编码?”然后一个裸 Python 解释器下棋 - 在规定您需要输入的编码下:

  • 一个下棋的 Python 程序加上对手的第一步,如果你想让它下黑的话
  • 一个下棋的 Python 程序,如果你想让它下白棋

如果你修复了编码,那么问题就会变得无聊。国际象棋游戏是有限的(根据 50 步规则),所以唯一的难题是“这个程序是否在任何有限的国际象棋游戏的移动之间挂起”。如果它不并且总是尊重编码(并且做出有效的移动,所有这些都是微不足道的),那么它就会下棋。当然,检查它是否挂起是无法治疗的。枚举所有国际象棋游戏是可以处理的,但考虑到实际考虑,当然也完全不可能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多