Hilbert's Tenth Problem, Part V: The MRDP Theorem
Author: silverxz
Proofreader: Acidmoon
In this article, we will prove that the Diophantine sets are exactly the recursively enumerable sets.
We have already noted that the direction from Diophantine sets to recursively enumerable sets is fairly straightforward. Let be a Diophantine set with corresponding Diophantine equation . For , we need only have a Turing machine systematically try every possible to see whether holds. If , the machine will eventually halt. The candidates must, of course, be enumerated in a way that guarantees every possible solution will be reached in finite time.
There is a subtle point here: given , we do not know what is. Yet some such must exist, so the corresponding Turing machine must exist as well.
That completes this direction of the proof. What really concerns us is how to prove that every recursively enumerable set is Diophantine. Our method is to construct Diophantine functions and relations that simulate each computational step of a Turing machine. This approach is not unusual. Readers familiar with basic computability theory may know the computation history method, a general technique used in undecidability proofs; the idea used here is much the same.
Diophantine Relations
We have already mentioned that a Diophantine relation is essentially the same thing as a Diophantine set, and that a Diophantine function can be viewed as a special Diophantine set or relation. Readers may not yet have an intuitive sense of the constructions this makes possible, however, so I will begin with a few simple examples before turning to the proof.
Perhaps the simplest example is the unary relation (predicate) “is even,” characterized as follows:
Why is this a Diophantine relation? Let . The equation , with as its parameter and as its unknown, defines the Diophantine set as follows:
This shows that is a Diophantine relation. Note that because we have restricted the solutions of Diophantine equations to natural numbers, all existential quantifiers are understood to range over the natural numbers.
Similarly, (divisibility) are also Diophantine binary relations. Taking as an example, we may write
Of course, is rather awkward notation. From here on, we will write such binary relations in the customary form instead.
Next come Diophantine functions. Recall that a multivariable function on the natural numbers is itself, in essence, a subset of the relevant Cartesian product , so when we say that is a Diophantine function, what we really mean is that is a Diophantine set or relation. Addition, subtraction, and multiplication are naturally Diophantine functions. Another example is the remainder function , defined as the remainder when is divided by . Since
In other words, is the remainder when is divided by if and only if and divides . The remainder function is therefore Diophantine. Wait, did you say “”? That is logical conjunction. Recall that we proved Diophantine sets are closed under intersection and union. In the language of Diophantine relations, this means that Diophantine relations are closed under logical AND and OR. We may therefore join simple Diophantine relations and functions with logical connectives to construct highly complex relations. Consequently, , which was not listed above, is also Diophantine, because it is or . Likewise, integer division is a Diophantine function. Since all our arithmetic takes place in the natural numbers, all division below means integer division by default.
Two further elementary facts are useful. First, nesting Diophantine relations or placing additional existential quantifiers outside them still yields a Diophantine relation, because we can always expand the definitions and move every existential quantifier to the outermost level. We should make full use of this freedom; many later constructions rely on it: rather than constructing the desired object directly, we describe its properties and use existential quantifiers to “select” it. Second, for a Diophantine set , is also Diophantine; this merely adds a few irrelevant variables to the corresponding equation. We therefore need not worry about matching the number of variables when applying logical connectives—we can simply “pad” the sets as needed.
Combining these facts with Bézout’s identity from number theory, readers can verify that the greatest-common-divisor function is also Diophantine.
By now, readers should have more confidence in our proof: Diophantine relations are indeed quite expressive. Our goal is to express the following statement with such relations. Given a recursively enumerable set , there are a Turing machine , an input , and a number of steps such that if and only if halts after steps (that is, reaches the final state ). We therefore need a Diophantine function capable of simulating steps of a Turing machine’s execution.
To simulate steps of execution, we must of course first simulate a single step. To do that, we must at least determine how to encode the Turing machine’s various states and its operation. Crucially, this encoding must itself be “Diophantine.”
Encoding a Turing Machine
Let us review the “information” contained in a Turing machine: a finite set of states , where is the initial state and is the final state (also denoted ); a finite alphabet , where is the blank symbol; and, finally, a transition function. We will use and for the sizes of the state set and the alphabet, saving ourselves a few letters.
A Turing machine’s transition function is usually defined as a single whole. For convenience, we divide it into three parts here. Suppose the machine is in state , and the symbol at the current position is . Let the index of the state reached by the transition be , the index of the symbol written by the machine be , and the direction in which the tape head moves be (stay, move left, or move right, which we may represent as ). We thus obtain three functions , where and are once again “overloaded” to save letters. Their meanings should be clear from context.
For the Turing machine, these functions are meaningful only when holds. But to make them Diophantine functions, we must extend their domains to . The values assigned on the extended portion depend on what we will need later; here we simply specify them. In these otherwise meaningless cases, let equal , equal , and equal . In other words, invalid arguments leave the state and symbol unchanged, and the head stays put. We now claim that the functions are all Diophantine.
This is because each amounts to modifying a Diophantine function ( and so on) at finitely many points (), so we can simply use a logical expression to enumerate the cases. For the simplest example, suppose I want to describe a function whose value at is , and which equals everywhere else. Call it : I need only write
Provided that is a Diophantine function, is one as well. The same applies to : we need only enumerate the finitely many valid cases, then assign the “remaining cases” another Diophantine function of our choosing. This characterizes the Turing machine itself; will also be the notation used below.
We must also describe the Turing machine at each point in its execution: the string on the tape , the current state , and the tape head’s position. Together, these three quantities form the machine’s configuration—its instantaneous state during execution. We need a suitable way to record them. Using directly will not work, because may grow linearly as the machine runs, whereas a Diophantine equation always has only finitely many unknowns. We therefore need the technique of tuple encoding.
Encoding Tuples: Cantor Encoding and Positional Encoding
(We actually use only positional encoding. Cantor encoding is also simple and elegant, however, so I will present it as well. Comparing the two should make it clearer why we choose positional encoding.)
We begin with a relatively “classical” method: Cantor encoding. First, how can we encode as a single natural number? Cantor supplied a beautiful method. Readers can verify that the following function gives a bijection .
Readers who are not interested may simply accept this result. If you have trouble verifying it, try drawing a two-dimensional table and substituting ; you may notice something interesting.
This is a useful encoding: it is a Diophantine function, and given a Cantor code , the functions that recover —namely —are Diophantine as well. For , for example, we have
Furthermore, a triple may be represented by ; the coordinate functions are similar. Continuing inductively, we obtain Cantor encodings for tuples of any fixed length . Note, however, that here must be a fixed constant; it cannot be supplied as a variable input.
This encoding makes it easy both to encode a fixed-length tuple as a natural number and to recover it. Should we therefore use it for our tuples? No. Useful though it is, it is not quite enough: variable-length tuples are difficult to handle, and more complex operations such as concatenation are harder still.
We therefore introduce another encoding, called positional encoding; it applies when the tuple’s entries have an upper bound.
Let there be a tuple , whose entries have an upper bound ; we may then use base . Define
Then is called a positional encoding of ; is called the encoding’s base or radix. It records the tuple length , the radix , and its value in base , namely . Readers need not understand the principle behind Cantor encoding, but they do need to understand positional encoding—which is simply place-value notation—because we will make concrete use of many properties of this expression, really just properties of numeral systems. They reveal what an elegant choice this is.
Sometimes we can use Cantor encoding to encode this triple still further. At other times, all we actually need is , because will be known and need not be included in the code, while may not matter. In that case, we also call itself a positional code whenever the context makes its meaning clear. One further advantage of positional encoding is that if is larger than the original code’s length, decoding merely produces additional trailing s, and in many situations those extra s do not matter.
Its coordinate function is likewise Diophantine, but using radix notation has a drawback: we must introduce something more powerful. Let denote the value at position , so
Did you notice the “more powerful” ingredient we introduced? We used an exponential function such as , which we have not yet proved to be Diophantine. As the historical account showed, this is in fact a very difficult part of the proof. For now, we assume that exponentiation is a Diophantine function; a proof may be supplied in the next article.
It follows that is also a Diophantine function. But recall that we introduced this encoding to perform more complex operations. Consider componentwise addition, for example: we need only add the positional codes directly, provided the result in every position does not exceed . With positional encoding, this is nearly trivial.
Now consider another operation: concatenation . Let there be another tuple , which we want to append to to form . If also has an upper bound , it too may be represented positionally by . The positional code of the concatenated tuple is easy to calculate. Readers can verify that the following relation holds exactly when the values form the positional code of the concatenation:
Strictly speaking, we must also use to conjoin two further conditions: and must indeed be valid positional codes. Unlike Cantor encoding, positional encoding need not be a bijection, so invalid cases may occur. The validity relation is also Diophantine, because
Again, this requires assuming that exponentiation is a Diophantine function.
Encoding Turing-Machine Configurations
With positional encoding in hand, we can return to the unfinished task of encoding Turing-machine configurations. As noted above, a configuration contains three pieces of information: the string on the tape, the head position, and the current state. We can capture all three with two tuples. The first tuple simultaneously records the tape head’s position and the machine’s current state , while the second tuple records the string currently on the tape. Both tuples have length .
More importantly, the entries of both tuples are bounded. An entry of the first tuple cannot exceed the number of states , while an entry of the second cannot exceed the size of the alphabet . We therefore choose a fixed base , use positional encoding to encode the first tuple as , and encode the second as .
Since is constant and is their common length—and, as we will see, we scarcely need it—we directly regard as the encoding of the Turing-machine configuration. For convenience, we also use to refer to the two tuples themselves.
Diophantine Functions for One Step of a Turing Machine
The preliminaries are complete: we have nearly all the parts, and it is time to assemble them. Our first goal in this section is to construct the Diophantine functions and . They give the two components of the code for the configuration obtained from after one step. We will later use them to construct and , the Diophantine functions that represent the configuration codes obtained from after steps of execution.
We begin with ; the idea is relatively simple. Consider what must be done: from the tuple we must produce a new tuple , in which, at every position where takes in the original tuple, we simply copy the value of into ; at the position where it takes —the position of the tape head—the corresponding symbol must be changed. This is exactly what our existing Turing-machine function does, because leaves the symbol unchanged when , returning ; otherwise it returns the modified symbol. In fact, this requirement is precisely why we designed .
But handles only a single position, whereas we want to process an entire tuple. We therefore need some syntactic sugar that extends a function from one entry to a variable-length tuple, applying the function to every entry. This should be easy to understand, since such syntactic sugar is common in modern programming languages.
In general, consider a Diophantine function , and assume that every entry of the tuples below is less than . We wish to construct a Diophantine function , which maps the positional code of the tuple to the tuple ; its positional code is . When is not a valid code, may be assigned arbitrarily.
This construction requires some care and is slightly laborious. I will give its outline and leave the proof to you. The key idea is this: because is a fixed finite bound, we enumerate the possible values and decompose the tuple into a collection of 0–1 indicator vectors.
Specifically, let be the positional code of the vector , where indicates whether : it takes the value when the equality holds and otherwise. In other words, records the positions at which takes the value .
Recall that positional codes can be added directly. Thus, observe that
Also observe that
It therefore suffices to show that are vectors determined by Diophantine functions and relations; this will establish that is a Diophantine function.
Define the function as the positional code for the tuple (), a -entry tuple written in base . Define the relation to mean that the tuples encoded by and are mutually disjoint -indicator vectors: entries equal to never occur at the same position. You can verify that both are Diophantine. These two Diophantine relations, together with the preceding equation—which is itself essentially a Diophantine relation because is constant—uniquely determine all the . This shows that is a Diophantine function. Notice that this uses the earlier idea: we do not write down directly, but instead use relations such as to constrain , ensuring that a qualifying exists and is unique; we then use the existential quantifier to select it.
More generally, this construction extends to multivariable functions , yielding , because we still need only a finite enumeration. This is precisely what we wanted.
Returning to our construction of , this syntactic sugar gives us everything we need:
Here serves as the tuple length. Readers may notice that when , can still be decoded. Could this produce an incorrect ? No, because it merely produces extra s; after the mapping, they remain s, so they do not affect the value of . We proceed this way because changes as the Turing machine runs, making it both difficult and unnecessary to keep track of a changing . Instead, we rely only on the existence of and the useful property that “redundant entries do not change a positional code.”
We have thus obtained . Although the construction is lengthy, its idea is not complicated. Next comes , whose construction is less direct. changes componentwise, so our syntactic sugar handles it neatly. The Turing machine’s tape head moves left or right, however, which means that the change in depends on neighboring values.
This obstacle can nevertheless be overcome. A positional code can easily be shifted by multiplying by or dividing by ! For a base- positional code , we use (integer division) to represent a left shift—removing the first entry and appending —and use to represent a right shift—making the first entry and shifting every other entry one place to the right.
We can now apply our syntactic sugar to the tuples after shifting them left and right. At the level of a single entry, this amounts to “taking neighboring entries into account.” Specifically, we want to define a function (because it combines the Turing-machine functions and ) such that its lifted, componentwise form gives as follows:
If you already see what we are doing, excellent: spelling out the definition of is genuinely cumbersome. If not, compare the idea with the explicit definition of and work through it again. We define as follows. Notice that left and right are reversed here: shifting left moves the entry on the right into place, so the variable corresponding to is denoted ; the other cases are analogous:
Thus, has been constructed as well.
Diophantine Functions for Multiple Steps of a Turing Machine
The end is in sight. We now prove that and are also Diophantine functions. They encode the configurations obtained from after steps of execution.
The obvious difficulty is . We know that iterating and exactly times yields the two desired functions, but is a variable rather than a constant, so this iteration does not establish that the functions are Diophantine.
The solution follows the computation-history method: consider the entire computation over these steps—that is, all configurations—find enough conditions to constrain them, and then select them with existential quantifiers.
Continue to use the aforementioned as the radix for positional encoding. Let , and let be the encoded result after iterations.
Recall that positional encoding lets us concatenate tuples. To handle these configurations, we concatenate them. Concatenation requires a specified tuple length, however, while the configuration tuples vary in length. This is not a problem: we can assign a length greater than every tuple involved. This merely introduces a few trailing upon decoding, and we already know that extra entries cause no error.
Specifically, let be the result of concatenating the positional codes ; let be the result of concatenating in the same way. We do likewise for .
Why define them this way instead of concatenating all configurations? Because of the following observation: . This holds because acts componentwise, so it can operate on several concatenated configurations at once, while is almost componentwise, except that it also examines adjacent entries. We need only insert s between configurations to prevent interference, which merely requires taking sufficiently large.
This observation supplies an important constraint. We can also see that if denotes the “middle portion,” namely the concatenation of , and we define analogously, then: is the concatenation of and ; while is the concatenation of and . are analogous.
This transformation may look almost trivial, but it makes an essential difference. Now is no longer a concatenation of tuples; it has become a concatenation of just and —two tuples—so the operation is now Diophantine. The same is true of . Yet remains a concatenation of tuples. It may seem that we have not really solved the problem, but we have. We can now assert that the relations above uniquely determine .
To see this, let us collect the constraints obtained so far (we write for tuple concatenation):
Existence is immediate, because we can in fact run the machine for steps; only uniqueness remains to be proved. To establish it, consider one by one the entries represented by and the other encoded tuples.
has its first entries equal to itself, so they are uniquely determined. From and the decomposition of , it follows that is determined through its first entries (because 's first output entries depend only on the first input entries). Once has been determined through its first entries, the decomposition of determines entries, and so on. Repeating this argument determines in full.
A careful reader may spot a remaining issue: the last entry of has not yet been determined. This is because determines an output one entry shorter than its input. Recall, however, that we made slightly larger, so the last entry of is actually . This determines as well. The argument for is exactly analogous—and even simpler.
This is equivalent to saying that and are Diophantine functions. If you insist on writing the definition explicitly, it requires only a large collection of existential quantifiers: there is a sufficiently large ; there are and all the other variables above; and the listed conditions are joined by logical conjunction. This completes the final part.
Hilbert’s Tenth Problem Is Unsolvable
Everything now falls into place. Given a Turing machine and its corresponding recursively enumerable set , define the Diophantine functions as above. Then holds if and only if:
Let us unpack these three conditions. says that after steps, the Turing-machine head is at position , and the current state is (the final state). selects the initial state , so is the tuple code representing the machine’s initial head position and state. encodes the machine’s initial input. Notice that is a fixed constant, so this sum is a valid operation. Together, the conditions say that the Turing machine, on input , halts after steps.
All three conditions are Diophantine, establishing that is a Diophantine set. We have therefore proved the MRDP theorem:
Diophantine sets are precisely the recursively enumerable sets.
We already know that some recursively enumerable sets are not recursive—for example, the recursively enumerable set associated with the halting problem. The process above is entirely constructive. Thus, in principle, given a Turing machine corresponding to such a recursively enumerable set, we can explicitly write down the variables and coefficients of a family of Diophantine equations corresponding to that set. The existence of integer solutions for this family must be undecidable; otherwise, the set itself would be decidable.
If solvability is undecidable even for a subclass of Diophantine equations—and we can explicitly provide their variables and coefficients, so encoding conversion poses no obstacle—then solvability for all Diophantine equations is certainly undecidable. We may therefore conclude: Hilbert’s Tenth Problem is unsolvable.
(\Done—cue the confetti!/)

