ChatGPT解决这个技术问题 Extra ChatGPT

像 Coq 这样的非图灵完备语言的实际限制是什么?

由于那里有非图灵完整的语言,并且鉴于我没有在大学学习 Comp Sci,有人可以解释一些图灵不完整的语言(如 Coq)不能做的事情吗?

还是没有真正的实际兴趣的完整性/不完整性(即在实践中没有太大区别)?

编辑 - 我正在寻找一个答案,由于 X 或类似的原因,您无法用非图灵完备的语言构建哈希表!

顺便说一句,较早的一个类似问题有几个有趣的答案与这里的答案互补:stackoverflow.com/questions/315340/…
@ulidtko“能够解释图灵完备的语言需要解释器宿主语言的图灵完备”......这是真的。那里引用的 Agda 代码避免模拟 BF 代码。它确实为任何 BF 程序“分配语义”,原则上可以在框架中使用,以允许在 Agda 中证明特定 BF 程序的终止。

G
Gilles 'SO- stop being evil'

首先,我假设您已经听说过 Church-Turing thesis,它指出我们称之为“计算”的任何事情都可以用图灵机(或许多其他等效模型中的任何一个)来完成。因此,图灵完备的语言是可以表达任何计算的语言。相反,图灵不完全语言是一种无法表达的计算。

好的,这不是很丰富。让我举个例子。在任何图灵不完备的语言中,有一件事是你不能做的:你不能编写图灵机模拟器(否则你可以在模拟的图灵机上编码任何计算)。

好的,这仍然不是很丰富。真正的问题是,什么有用的程序不能用图灵不完备的语言编写?好吧,没有人提出“有用程序”的定义,其中包括某人为有用目的而编写的所有程序,并且不包括所有图灵机计算。所以设计一种图灵不完备的语言,让你可以编写所有有用的程序,仍然是一个非常长期的研究目标。

现在有几种非常不同类型的图灵不完全语言,它们在不能做的事情上有所不同。然而,有一个共同的主题。如果您正在设计一种语言,有两种主要方法可以确保该语言是图灵完备的:

要求语言具有任意循环(while)和动态内存分配(malloc)

要求语言支持任意递归函数

让我们看一些非图灵完备语言的例子,有些人可能仍然称之为编程语言。

FORTRAN 的早期版本没有动态内存分配。您必须提前弄清楚您的计算需要多少内存并分配它。尽管如此,FORTRAN 曾经是使用最广泛的编程语言。明显的实际限制是您必须在运行程序之前预测程序的内存需求。这可能很难,如果输入数据的大小事先没有限制,那也是不可能的。当时,提供输入数据的人通常是编写程序的人,所以这没什么大不了的。但对于今天编写的大多数程序来说,情况并非如此。

Coq 是一种为证明定理而设计的语言。现在证明定理和运行程序密切相关,所以你可以像证明一个定理一样在 Coq 中编写程序。直观地说,定理“A 蕴含 B”的证明是将定理 A 的证明作为参数并返回定理 B 的证明的函数。由于系统的目标是证明定理,所以不能让程序员编写任意函数。想象一下,这种语言允许你编写一个愚蠢的递归函数,它只是调用自己(选择使用你最喜欢的语言的那一行): theorem_B boom (theorem_A a) { return boom(a); } let rec boom (a : theorem_A) : theorem_B = boom (a) def boom(a): boom(a) (define (boom a) (boom a)) 你不能让这样一个函数的存在说服你A 蕴含 B,否则你将能够证明任何事情,而不仅仅是真定理!所以 Coq(和类似的定理证明者)禁止任意递归。当你写一个递归函数时,你必须证明它总是终止,这样每当你在定理 A 的证明上运行它时,你就知道它将构造一个定理 B 的证明。 Coq 直接的实际限制是你不能写任意递归函数。由于系统必须能够拒绝所有非终止函数,因此停止问题(或更一般地说,赖斯定理)的不可判定性确保了也有终止函数被拒绝。另一个实际困难是您必须帮助系统证明您的函数确实终止了。有很多正在进行的研究使证明系统更像编程语言而不损害他们的保证,即如果你有一个从 A 到 B 的函数,它与 A 隐含 B 的数学证明一样好。扩展系统以接受更多终止函数是研究课题之一。其他扩展方向包括处理输入/输出和并发等“现实世界”问题。另一个挑战是让普通人可以访问这些系统(或者让普通人相信它们实际上是可以访问的)。

同步编程语言是为实时系统编程而设计的语言,即程序必须在少于 n 个时钟周期内响应的系统。它们主要用于关键任务系统,例如车辆控制或信号。这些语言为程序运行需要多长时间以及它可以分配多少内存提供了强有力的保证。当然,与这种强有力的保证相对应的是,您不能编写无法提前预测内存消耗和运行时间的程序。特别是,您不能编写内存消耗或运行时间取决于输入数据的程序。

有许多专门的语言甚至不尝试成为编程语言,因此与图灵完备性相去甚远:正则表达式、数据语言、大多数标记语言……

顺便说一句,Douglas Hofstadter 写了几本非常有趣的关于计算的科普书籍,尤其是 Gödel, Escher, Bach: an Eternal Golden Braid。我不记得他是否明确讨论过图灵不完备的局限性,但是阅读他的书肯定会帮助您了解更多的技术资料。


@Gabe:您混淆了语言及其实现。计算机上的任何实际实现都将受到有限内存的限制。但这仅意味着实现仅处理语言的有限(但有用)子集。请注意,语言是值得研究的,即使它们在技术上无法实现,因为推理无限系统比推理非常大的有限系统要容易得多。
@Gabe:不,您不能使用预分配的数组编写 malloc(好吧,一个理想化的 malloc,它允许您实现图灵完备的语言)。您仍然会允许您的程序仅访问有限的内存量;因此,从理论的角度来看,您所拥有的只是一个有限自动机。
@Gabe:顺便说一下,C 的图灵完备性有点微妙。由于指针必须完全由它们的位模式决定,因此任何给定的 C 实现(甚至是概念实现)只能为程序提供有限数量的内存(假设您不使用 I/O 来提供额外的存储空间)。但是,您可以创建一个“元实现”,在实现中运行 C 程序,但如果 malloc 内存不足,则从头开始,实现限制更大。 C 的元实现是一个图灵完备的编程环境。
Gilles:是什么让 C 能够实现这种元实现,但不能实现 FORTRAN?
@Gabe:没有具体的实现是图灵完备的,因为不存在无限的存储设备。 (如果你只有 10 亿 TB,它不是无限的。)但是一些编程语言是无限的。例如,基本整数类型为 bignum 的语言(如 Lisp、Haskell、Python)直接是图灵完备的。没有内置限制的语言(例如 C 中由于指针具有给定位数而强加的语言)也很容易实现图灵完备(例如,我认为 Java、C# 属于这一类)。
s
slebetman

最直接的答案是:不能使用图灵完备的机器/语言来实现/模拟图灵机。这来自图灵完备性的基本定义:如果机器/语言能够实现/模拟图灵机,那么它就是图灵完备的。

那么,有哪些实际意义呢?好吧,有证据表明任何可以证明是图灵完备的东西都可以解决所有可计算的问题。从定义上讲,这意味着任何不完整的事物都会存在一些无法解决的可计算问题。这些问题是什么取决于缺少哪些使系统非图灵完备的功能。

例如,如果一种语言不支持循环或递归,或者隐式循环不能是图灵完备的,因为图灵机可以被编程为永远运行。因此,该语言无法解决需要循环的问题。

另一个例子是,如果一种语言不支持列表或数组(或允许您模拟它们,例如使用文件系统),那么它就无法实现图灵机,因为图灵机需要对内存的任意随机访问。因此,该语言无法解决需要任意随机访问内存的问题。

因此,将语言分类为非图灵完备的缺失特征实际上限制了语言的实用性。所以答案是,这取决于:是什么让语言非图灵完备?


+1您不能用非图灵完整语言编写图灵完整语言的解释器。您也不能做任何等效的事情(等效意味着为图灵完备的语言编写解释器可以简化为该问题)。对于其他所有事物(即可计算的),都存在一种非图灵完备的语言,您可以在其中做到这一点。
我将如何“证明”某些给定的问题需要解决循环。例如,可能使用循环可解决的任何事情也可以使用递归解决?
@oxbow_lakes:可以证明递归和循环是可以互换的。因此,循环我们也指递归。没有循环意味着无法进行递归。
@oxbow_lakes:方法 1:为了证明问题 P 需要用语言 L 解决循环,您定义了一种语言 K,它是没有循环的 L,并表明问题 P 不能用语言 K 解决。通常,最后一部分是通过证明来完成的语言 K 中的每个程序都有特定的属性(例如,运行时间的限制),而问题 P 不具有该属性。
@oxbow_lakes:方法 2:为了证明问题 P 需要循环或一些等效的特性来解决,您尝试将循环编码到问题 P 中。例如,为了证明有循环需要递归(即循环与递归一样强大) ),你证明了任何递归程序都可以使用循环来编写。
e
ejgallego

不适合 Coq 等语言的一类重要问题是那些终止是推测或难以证明的问题。您可以在数论中找到大量示例,其中最著名的可能是 Collatz conjecture

function collatz(n)
  while n > 1
    if n is odd then
      set n = 3n + 1
    else
      set n = n / 2
    endif
 endwhile

这种限制导致不得不在 Coq 中以不太自然的方式表达这些问题。


我不同意:你可以在 Coq 中很好地表达 Collatz 猜想:forall n, exists k, (iterate collatz k) n = 1.(其中 iterate f k 应用函数 k 次)。
A
Atsby

您不能编写模拟图灵机的函数。您可以编写一个函数来模拟图灵机的 2^128 步(或 2^2^2^2^128 步),并报告图灵机是否接受、拒绝或运行时间超过了允许的步数。

由于“在实践中”,在您的计算机可以模拟图灵机进行 2^128 步之前,您将早已不复存在,因此可以公平地说,图灵不完备性在“实践”中并没有太大的影响。