由于存在非图灵完备语言,而且我没有在大学学习计算机科学,能否有人解释一下图灵不完备语言(如Coq)不能做什么?
或者说完备性/不完备性在实际中并不真正重要吗?
编辑 - 我想要一个回答,类似于“由于X的原因,在非图灵完备语言中无法构建哈希表”,或者类似的回答!
由于存在非图灵完备语言,而且我没有在大学学习计算机科学,能否有人解释一下图灵不完备语言(如Coq)不能做什么?
或者说完备性/不完备性在实际中并不真正重要吗?
编辑 - 我想要一个回答,类似于“由于X的原因,在非图灵完备语言中无法构建哈希表”,或者类似的回答!
要求语言具有任意循环(while
)和动态内存分配(malloc
)
要求语言支持任意递归函数
让我们来看一些非图灵完备语言的例子,尽管有些人可能仍然称其为编程语言。
Early versions of FORTRAN did not have dynamic memory allocation. You had to figure out in advance how much memory your computation would need and allocate that. In spite of that, FORTRAN was once the most widely used programming language.
The obvious practical limitation is that you have to predict the memory requirements of your program before running it. That can be hard, and can be impossible if the size of the input data is not bounded in advance. At the time, the person feeding the input data was often the person who had written the program, so it wasn't such a big deal. But that's just not true for most programs written today.
Coq is a language designed for proving theorems. Now proving theorems and running programs are very closely related, so you can write programs in Coq just like you prove a theorem. Intuitively, a proof of the theorem “A implies B” is a function that takes a proof of theorem A as an argument and returns a proof of theorem B.
Since the goal of the system is to prove theorems, you can't let the programmer write arbitrary functions. Imagine the language allowed you to write a silly recursive function that just called itself (pick the line that uses your favorite language):
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))
You can't let the existence of such a function convince you that A implies B, or else you would be able to prove anything and not just true theorems! So Coq (and similar theorem provers) forbid arbitrary recursion. When you write a recursive function, you must prove that it always terminates, so that whenever you run it on a proof of theorem A you know that it will construct a proof of theorem B.
The immediate practical limitation of Coq is that you cannot write arbitrary recursive functions. Since the system must be able to reject all non-terminating functions, the undecidability of the halting problem (or more generally Rice's theorem) ensures that there are terminating functions that are rejected as well. An added practical difficulty is that you have to help the system to prove that your function does terminate.
There is a lot of ongoing research on making proof systems more programming-language-like without compromising their guarantee that if you have a function from A to B, it's as good as a mathematical proof that A implies B. Extending the system to accept more terminating functions is one of the research topics. Other extension directions include coping with such “real-world” concerns as input/output and concurrency. Another challenge is to make these systems accessible to mere mortals (or perhaps convince mere mortals that they are in fact accessible).
Synchronous programming languages are languages designed for programming real-time systems, that is, systems where the program must respond in less than n clock cycles. They are mainly used for mission-critical systems such as vehicle controls or signaling. These languages offer strong guarantees on how long a program will take to run and how much memory it may allocate.
Of course, the counterpart of such strong guarantees is that you can't write programs whose memory consumption and running time you're not able to predict in advance. In particular, you can't write a program whose memory consumption or running time depends on the input data.
There are many specialized languages that don't even try to be programming languages and so can remain comfortably far from Turing completeness: regular expressions, data languages, most markup languages, ...
顺便提一下,Douglas Hofstadter 写了几本非常有趣的关于计算的科普书,特别是 Gödel, Escher, Bach: an Eternal Golden Braid。我不记得他是否明确讨论了图灵不完备性的限制,但阅读他的书肯定会帮助您更好地理解技术材料。
malloc
(或是一种理想化的malloc
,它允许你实现一个图灵完备的语言)。你仍然只能让你的程序访问有限的内存;因此从理论上讲,你只拥有一个有限自动机。 - Gilles 'SO- stop being evil'malloc
用尽内存,则从头开始使用更大的实现限制。该C语言的元实现是一个图灵完备的编程环境。 - Gilles 'SO- stop being evil'function collatz(n)
while n > 1
if n is odd then
set n = 3n + 1
else
set n = n / 2
endif
endwhile
forall n, exists k, (iterate collatz k) n = 1.
(其中iterate f k
将函数f
应用k
次)。 - Olivier Verdier2^128
(或2^2^2^2^128
)个步骤模拟图灵机,并报告图灵机是接受、拒绝还是运行超过允许的步骤数。2^128
步之前,您会远去,因此可以说图灵不完备性在“实践中”并没有太大的影响。