maths.free › Set Theory & Logic › Logic › Halting problem
Halting problem
In computability theory, the halting problem is the decision problem of, given an arbitrary computer program and an input, determining whether said program will eventually finish running and halt, or will continue to…
Halting problem
In computability theory, the halting problem is the decision problem of, given an arbitrary computer program and an input, determining whether said program will eventually finish running and halt, or will continue to run forever. Alan Turing proved in 1937 that the halting problem is undecidable, meaning that no general algorithm exists that can correctly solve the problem for all possible program, input pairs. The problem comes up often in discussions of computability since it demonstrates that some functions are mathematically definable but not computable.
A key part of the formal statement of the problem is a mathematical definition of a computer and program, usually via a Turing machine. The proof then shows, for any program f that might determine whether programs halt, that a "pathological" program g exists for which f makes an incorrect determination. Specifically, g is the program that, when called with some input, passes its own source and its input to f and does the opposite of what f predicts g will do. The behavior of f on g shows undecidability as it means no program f will solve the halting problem in every possible case.
Background
The halting problem is a decision problem about properties of computer programs on a fixed Turing-complete model of computation. This model of computation includes all programs in Turing-equivalent programming languages. Given a program and an input, the question is whether the program will eventually halt when run with that particular input. In this abstract framework, there are no limitations on the memory or time required for the program's execution; the program may run arbitrarily long and consume arbitrarily large amounts of storage before halting.
For example, in pseudocode, the program
while (true) continue
never halts; rather, it goes on forever in an infinite loop. By contrast,
print "Hello, world!"
halts immediately after printing.
Simple cases like these are easy to decide, but more complex programs are not. Turing proved no algorithm exists that always correctly decides whether, for a given arbitrary program and input, the program halts when run with that input. The essence of Turing's proof is that any such algorithm can be made to produce contradictory output and therefore cannot be correct.
Programming consequences
Most subroutines are intended to finish. The fact that the halting problem is undecidable is often naively taken to mean that establishing whether a program halts is impossible. However, programs such as the T2 Temporal Prover could automatically establish that certain Windows device-driver dispatch routines will always eventually return. It appears feasible that "future program-termination proof tools [may] work 99.9% of the time on programs written by humans."
Some infinite loops can be quite useful. For instance, event loops are typically coded as infinite loops. In total functional programming languages these are often encoded using corecursion, as functions that process and produce infinite coinductive data types such as streams. This formalism allows proving a dual termination property known as productivity.
In hard real-time computing, subroutines must not only finish, but finish before a given deadline. In order to meet these requirements, programmers apply the rule of least power and use restricted styles, not quite fully Turing-complete, that make it easy to prove that the resulting subroutines finish before the given deadline. These include languages such as MISRA C, SPARK, and Rocq.
Common pitfalls
The halting problem requires a decision procedure that works for all programs and inputs. But for any specific program and input, the answer is simply "halts" or "does not halt". Consider two simple decision procedures, one that always answers "halts" and another that always answers "does not halt". For any given case, one of these two algorithms answers correctly, yet neither algorithm solves the halting problem.
Interpreters are programs that simulate the execution of programs whatever source code they are given. Such programs can demonstrate that a program does halt, by running the program for some number of steps. However, an interpreter will not halt if its input program does not halt, so this approach cannot solve the halting problem as stated; it does not successfully answer "does not halt" for programs that do not halt, or determine whether a program will eventually halt or run forever.
The halting problem is decidable for linear bounded automata (LBAs) or deterministic machines with finite memory. Such a machine has finitely many possible configurations, so any deterministic program on it must eventually either halt or repeat a previous configuration:
However, Minsky notes:
For example, a computer with a million two-state components would have at least 2 possible states:
For nondeterministic finite automata (restricted to finite memory), it is also decidable whether the machine halts on none, some, or all of the possible sequences of nondeterministic decisions, by enumerating states after each possible decision.
History
In April 1936, Alonzo Church published his proof of the undecidability of a problem in the lambda calculus. Turing's proof was published later, in January 1937. Since then, many other undecidable problems have been described, including the halting problem which emerged in the 1950s.
Timeline
- 1900 (1900): David Hilbert poses his "23 questions" (now known as Hilbert's problems) at the Second International Congress of Mathematicians in Paris. "Of these, the second was that of proving the consistency of the 'Peano axioms' on which, as he had shown, the rigour of mathematics depended".
- 1920 (1920)–1921 (1921): Emil Post explores the halting problem for tag systems, regarding it as a candidate for unsolvability. Its unsolvability was not established until much later, by Marvin Minsky.
- 1928 (1928): Hilbert recasts his 'Second Problem' at the Bologna International Congress. He posed three questions: i.e. #1: Was mathematics complete? #2: Was mathematics consistent? #3: Was mathematics decidable? The third question is known as the Entscheidungsproblem (Decision Problem).
- 1930 (1930): Kurt Gödel announces a proof as an answer to the first two of Hilbert's 1928 questions. "At first he [Hilbert] was only angry and frustrated, but then he began to try to deal constructively with the problem... Gödel himself felt, and expressed the thought in his paper, that his work did not contradict Hilbert's formalistic point of view".
- 1931 (1931): Gödel publishes "On Formally Undecidable Propositions of Principia Mathematica and Related Systems I".
- 19 April 1935 (1935-04-19): Alonzo Church publishes "An Unsolvable Problem of Elementary Number Theory", which proposes that the intuitive notion of an effectively calculable function can be formalized by the general recursive functions or equivalently by the lambda-definable functions. He proves that the halting problem for lambda calculus (i.e., whether a given lambda-expression has a normal form) is not effectively calculable.
- 1936 (1936): Church publishes the first proof that the Entscheidungsproblem is unsolvable, using a notion of calculation by recursive functions.
- 7 October 1936 (1936-10-07): Emil Post's paper "Finite Combinatory Processes. Formulation I" is received. Post adds to his "process" an instruction "(C) Stop". He called such a process "type 1 ... if the process it determines terminates for each specific problem."
- May 1936 (1936-05) – January 1937 (1937-01): Alan Turing's paper On Computable Numbers With an Application to the Entscheidungsproblem goes to press in May 1936 and reaches print in January 1937. Turing proves three problems undecidable: the "satisfaction" problem, the "printing" problem, and the Entscheidungsproblem. Turing's proof differs from Church's by introducing the notion of computation by machine. This is one of the "first examples of decision problems proved unsolvable".
- 1939 (1939): J. Barkley Rosser observes the essential equivalence of "effective method" defined by Gödel, Church, and Turing.
- 1943 (1943): In a paper, Stephen Kleene states that "In setting up a complete algorithmic theory, what we do is describe a procedure ... which procedure necessarily terminates and in such manner that from the outcome we can read a definite answer, 'Yes' or 'No,' to the question, 'Is the predicate value true?'."
- 1952 (1952): Kleene includes a discussion of the unsolvability of the halting problem for Turing machines and reformulates it in terms of machines that "eventually stop", i.e. halt: "...there is no algorithm for deciding whether any given machine, when started from any given situation, eventually stops."
- 1952 (1952): Martin Davis uses the term 'halting problem' in a series of lectures at the Control Systems Laboratory at the University of Illinois in 1952. It is likely that this is the first such use of the term.
Origin of the halting problem
Many papers and textbooks refer the definition and proof of undecidability of the halting problem to Turing's 1936 paper. However, this is not correct. Turing did not use the terms "halt" or "halting" in any of his published works, including his 1936 paper. A search of the academic literature from 1936 to 1958 showed that the first published material using the term "halting problem" was Rogers (1957). However, Rogers says he had a draft of Davis (1958) available to him, and Martin Davis states in the introduction that "the expert will perhaps find some novelty in the arrangement and treatment of topics", so the terminology must be attributed to Davis. Davis stated in a letter that he had been referring to the halting problem since 1952. The usage in Davis's book is as follows:
A possible precursor to Davis's formulation is Kleene's 1952 statement, which differs only in wording:
The halting problem is Turing equivalent to both Davis's printing problem ("does a Turing machine starting from a given state ever print a given symbol?") and to the printing problem considered in Turing's 1936 paper ("does a Turing machine starting from a blank tape ever print a given symbol?"). However, Turing equivalence is rather loose and does not mean that the two problems are the same. There are machines which print but do not halt, and halt but not print. The printing and halting problems address different issues and exhibit important conceptual and technical differences. Thus, Davis was simply being modest when he said:
Formalization
In theoretical computer science, a decision problem is any problem that can be phrased as a yes, no question about a mathematical object. Formally, the halting problem is the decision problem:
Given the description of a program (P) and an input (x), does (P(x)) eventually halt?
The conventional representation of decision problems is the set of objects possessing the property in question. The halting set
K = {(i, x) | program i halts when run on input x}
represents the halting problem.
This set is recursively enumerable, which means there is a computable function that lists all of the pairs (i, x) it contains. However, the complement of this set is not recursively enumerable.
Undecidability
A decision problem is said to be decidable if there exists an algorithm that always halts with the correct answer, and an undecidable problem if no such algorithm exists. In his original proof Turing formalized the concept of algorithm by introducing Turing machines. However, the result is in no way specific to them; it applies equally to any other model of computation that is equivalent in its computational power to Turing machines, such as Markov algorithms, Lambda calculus, Post systems, register machines, or tag systems.
What is important is that the formalization allows a straightforward mapping of algorithms to some data type that the algorithm can operate upon. For example, if the formalism lets algorithms define functions over strings (such as Turing machines) then there should be a mapping of these algorithms to strings, and if the formalism lets algorithms define functions over natural numbers (such as computable functions) then there should be a mapping of algorithms to natural numbers. The mapping to strings is usually the most straightforward, but strings over an alphabet with n characters can also be mapped to numbers by interpreting them as numbers in an n-ary numeral system.
There are many undecidable problems; any set whose Turing degree equals that of the halting problem is such a formulation. Examples of such sets include, besides the halting problem:
- {i | program i eventually halts when run with input 0}
- {i | there is an input x such that program i eventually halts when run with input x}.
Proof concept
Christopher Strachey outlined a proof by contradiction that the halting problem is not solvable. The proof proceeds as follows: Suppose that there exists a total computable function halts(f) that returns true if the subroutine f halts (when run with no inputs) and returns false otherwise. Now consider the following subroutine:
def g() -> None: if halts(g): loop_forever()halts(g) must either return true or false, because halts was assumed to be total. If halts(g) returns true, then g will call loop_forever and never halt, which is a contradiction. If halts(g) returns false, then g will halt, because it will not call loop_forever; this is also a contradiction. Overall, g does the opposite of what halts says g should do, so halts(g) can not return a truth value that is consistent with whether g halts. Therefore, the initial assumption that halts is a total computable function must be false.
Sketch of rigorous proof
The concept above shows the general method of the proof, but the computable function halts does not directly take a subroutine as an argument; instead it takes the source code of a program. Moreover, the definition of g is self-referential. A rigorous proof addresses these issues. The overall goal is to show that there is no total computable function that decides whether an arbitrary program i halts on arbitrary input x; that is, the following function h (for "halts") is not computable:
\(h(i,x) = \begin{cases} 1 & \text{if } \text{ program }i\text{ halts on input }x, \\ 0 & \text{otherwise.} \end{cases}\)
Here program i refers to the i th program in an enumeration of all the programs of a fixed Turing-complete model of computation.
Possible values for a total computable function f arranged in a 2D array. The orange cells are the diagonal. The values of f(i,i) and g(i) are shown at the bottom; U indicates that the function g is undefined for a particular input value.
The proof proceeds by directly establishing that no total computable function with two arguments can be the required function h. As in the sketch of the concept, given any total computable binary function f, the following partial function g is also computable by some program e:
\(g(i) = \begin{cases} 0 & \text{if } f(i,i) = 0,\\ \text{undefined} & \text{otherwise.} \end{cases}\)
The verification that g is computable relies on the following constructs (or their equivalents):
- computable subprograms (the program that computes f is a subprogram in program e),
- duplication of values (program e computes the inputs i,i for f from the input i for g),
- conditional branching (program e selects between two results depending on the value it computes for f(i,i)),
- not producing a defined result (for example, by looping forever),
- returning a value of 0.
The following pseudocode for e illustrates a straightforward way to compute g:
procedure e(i): if f(i, i) == 0 then return 0 else loop foreverBecause g is partial computable, there must be a program e that computes g, by the assumption that the model of computation is Turing-complete. This program is one of all the programs on which the halting function h is defined. The next step of the proof shows that h(e,e) will not have the same value as f(e,e).
It follows from the definition of g that exactly one of the following two cases must hold:
- f(e,e) = 0 and so g(e) = 0. In this case program e halts on input e, so h(e,e) = 1.
- f(e,e) ≠ 0 and so g(e) is undefined. In this case program e does not halt on input e, so h(e,e) = 0.
Condensed: the full section is in Wikipedia.
Computability theory
A typical method of proving a problem \(P\) to be undecidable is to reduce the halting problem to \(P\). For example, there cannot be a general algorithm that decides whether a given statement about natural numbers is true or false. The reason for this is that the proposition stating that a certain program will halt given a certain input can be converted into an equivalent statement about natural numbers. If an algorithm could find the truth value of every statement about natural numbers, it could certainly find the truth value of this one; but that would determine whether the original program halts.
Rice's theorem generalizes the theorem that the halting problem is unsolvable. It states that for any non-trivial property, there is no general decision procedure that, for all programs, decides whether the partial function implemented by the input program has that property. (A partial function is a function which may not always produce a result, and so is used to model programs, which can either produce results or fail to halt.) For example, the property "halt for the input 0" is undecidable. Here, "non-trivial" means that the set of partial functions that satisfy the property is neither the empty set nor the set of all partial functions. For example, "halts or fails to halt on input 0" is clearly true of all partial functions, so it is a trivial property, and can be decided by an algorithm that simply reports "true." Also, this theorem holds only for properties of the partial function implemented by the program; Rice's Theorem does not apply to properties of the program itself. For example, "halt on input 0 within 100 steps" is not a property of the partial function that is implemented by the program, it is a property of the program implementing the partial function and is very much decidable.
Gregory Chaitin has defined a halting probability, represented by the symbol Ω, a type of real number that informally is said to represent the probability that a randomly produced program halts. These numbers have the same Turing degree as the halting problem. It is a normal and transcendental number which can be defined but cannot be completely computed. This means one can prove that there is no algorithm which produces the digits of Ω, although its first few digits can be calculated in simple cases.
Condensed: the full section is in Wikipedia.
Approximations
Turing's proof shows that there can be no mechanical, general method (i.e., a Turing machine or a program in some equivalent model of computation) to determine whether algorithms halt. However, each individual instance of the halting problem has a definitive answer, which may or may not be practically computable. Given a specific algorithm and input, one can often show that it halts or does not halt, and in fact computer scientists often do just that as part of a correctness proof. There are some heuristics that can be used in an automated fashion to attempt to construct a proof, which frequently succeed on typical programs. This field of research is known as automated termination analysis.
Some results have been established on the theoretical performance of halting problem heuristics, in particular the fraction of programs of a given size that may be correctly classified by a recursive algorithm. These results do not give precise numbers because the fractions are uncomputable and also highly dependent on the choice of program encoding used to determine "size". For example, consider classifying programs by their number of states and using a specific "Turing semi-infinite tape" model of computation that errors (without halting) if the program runs off the left side of the tape. Then \(\lim_{n\to\infty} P(x\,\text{halts is decidable} \mid x\,\text{has}\,n\,\text{states}) = 1\), over programs \(x\) chosen uniformly by number of states. But this result is in some sense "trivial" because these decidable programs are simply the ones that fall off the tape, and the heuristic is simply to predict not halting due to error. Thus a seemingly irrelevant detail, namely the treatment of programs with errors, can turn out to be the deciding factor in determining the fraction of programs.
To avoid these issues, several restricted notions of the "size" of a program have been developed. A dense Gödel numbering assigns numbers to programs such that each computable function occurs a positive fraction in each sequence of indices from 1 to n, i.e. a Gödelization φ is dense iff for all \(i\), there exists a \(c > 0\) such that \(\liminf_{n\to\infty} \#\{j \in \N : 0 \leq j < n, \phi_i = \phi_j\}/n\geq c\). For example, a numbering that assigns indices \(2^n\) to nontrivial programs and all other indices the error state is not dense, but there exists a dense Gödel numbering of syntactically correct Brainfuck programs. A dense Gödel numbering is called optimal if, for any other Gödel numbering \(\alpha\), there is a 1-1 total recursive function \(f\) and a constant \(c\) such that for all \(i\), \(\alpha_i=\phi_{f(i)}\) and \(f(i) \leq c i\). This condition ensures that all programs have indices not much larger than their indices in any other Gödel numbering. Optimal Gödel numberings are constructed by numbering the inputs of a universal Turing machine. A third notion of size uses universal machines operating on binary strings and measures the length of the string needed to describe the input program. A universal machine U is a machine for which every other machine V there exists a total computable function h such that \(V (x) = U (h(x))\). An optimal machine is a universal machine that achieves the Kolmogorov complexity invariance bound, i.e. for every machine V, there exists c such that for all outputs x, if a V-program of length n outputs x, then there exists a U-program of at most length \(n+c\) outputting x.
We consider partial computable functions (algorithms) \(A\). For each \(n\) we consider the fraction \(\epsilon_n(A)\) of errors among all programs of size metric at most \(n\), counting each program \(x\) for which \(A\) fails to terminate, produces a "don't know" answer, or produces a wrong answer, i.e. \(x\) halts and \(A(x)\) outputs DOES_NOT_HALT, or \(x\) does not halt and \(A(x)\) outputs HALTS. The behavior may be described as follows, for dense Gödelizations and optimal machines:
Condensed: the full section is in Wikipedia.
Gödel's incompleteness theorems
The concepts raised by Gödel's incompleteness theorems are very similar to those raised by the halting problem, and the proofs are quite similar. In fact, a weaker form of the First Incompleteness Theorem is an easy consequence of the undecidability of the halting problem. This weaker form differs from the standard statement of the incompleteness theorem by asserting that an effective axiomatization of the natural numbers that is both complete and sound is impossible. The "sound" part is the weakening: it means that we require the axiomatic system in question to prove only true statements about natural numbers. Since soundness implies consistency, this weaker form can be seen as a corollary of the strong form. It is important to observe that the statement of the standard form of Gödel's First Incompleteness Theorem is completely unconcerned with the truth value of a statement, but only concerns the issue of whether it is possible to find it through a mathematical proof.
The weaker form of the theorem can be proved from the undecidability of the halting problem as follows. Assume that we have a sound (and hence consistent) and complete effective axiomatization of all true first-order logic statements about natural numbers. Then we can build an algorithm that enumerates all these statements. This means that there is an algorithm N(n) that, given a natural number n, computes a true first-order logic statement about natural numbers, and that for all true statements, there is at least one n such that N(n) yields that statement. Now suppose we want to decide if the algorithm with representation a halts on input i. We know that this statement can be expressed with a first-order logic statement, say H(a, i). Since the axiomatization is complete it follows that either there is an n such that N(n) = H(a, i) or there is an n′ such that N(n′) = ¬ H(a, i). So if we iterate over all n until we either find H(a, i) or its negation, we will always halt, and furthermore, the answer it gives us will be true (by soundness). This means that this gives us an algorithm to decide the halting problem. Since we know that there cannot be such an algorithm, it follows that the assumption that there is a sound and complete effective axiomatization of all true first-order logic statements about natural numbers must be false.
አሁን ምንም ዓይነት መሳሪያ ይህን አይቆጣጠርም፤ ነገር ግን ክፍሎቹ ሊቆጠሩ ይችላሉ። በታች ያለውን ይሞክሩ ወይም የራሳችሁን ይጻፉ።
ፊደላት
ለሙሉ መግለጫ፣ ምስል፣ እና በውስጡ ያለውን ፊደል ትርጓሜ ለማየት ማንኛውንም ምልክት ይጫኑ።
ጥያቄዎች
Are some infinities bigger than others?
Yes. The integers and the rationals can be listed; the real numbers cannot (Cantor's diagonal argument), so there are strictly more reals than integers.
What is the difference between a relation and a function?
A relation pairs inputs with outputs freely; a function is a relation in which every input gets exactly one output.
የዚህ ገጽ ክፍሎች ከ Wikipedia (CC BY-SA 4.0). እዚህ የተቀረጸና የተተረጎመ፤ ስህተቶች የእኛ ናቸው፡፡
በ Set Theory & Logic
Sets and operationsRelations, functions and equivalenceCardinality and infinityLogic and methods of proof