The goal of a reduction proof is to bootstrap what we already know, arguing that since is not decidable (or not semidecidable), can’t be decidable (or semidecidable) either. One particularly convenient form of reduction is mapping reduction (also known as many-one reduction).
We say that if there is a computable function such that
for all .
The intuition is this: we have a language and a string which may or may not be in .

The trick is that instead of answering “is in ?” directly, we can ask the question “is in ?” for some computable function chosen so that the answers to the two questions are the same.

As soon as we find a computable function with this property, we have a mapping reduction ; any question about membership in can be turned into a question about membership in , and so determining membership in cannot be any harder than determining membership in .
Suppose .
Proof:
Suppose iff . If is a function that a TM can
compute, then given any algorithm decide_Q, we can write a decider
for that uses the following algorithm:
def decide_P(x):
return decide_Q(f(x))
It follows that if is decidable then so is .
By the contrapositive, if is not decidable, then is not
decidable.
Suppose iff . If is a function that a TM can
compute, then given any algorithm semidecide_Q, we can write a
semidecider for that uses the following algorithm:
def semidecide_P(x):
return semidecide_Q(f(x))
It follows that if is semidecidable then so is .
By the contrapositive, if is not semidecidable, then is not
semidecidable.
We have already seen that
is not decidable, and that
is not semidecidable, which gives us:
A typical mapping reduction proof that goes as follows:
[Define a function mapping strings to strings.]
[If nonobvious, explain why is computable.]
[Show that if then .]
[Show that if then .]
Therefore iff , so map-reduces to .
QED.
A successful proof (exhibiting a function that maps strings in to strings in and maps strings not in to strings not in ) guarantees that both in terms of decidability (if is not decidable then is not decidable) and in terms of semidecidability (if is not semidecidable then is not semidecidable).
This means that if we do a mapping-reduction proof where is a language like that we already know is not decidable, then just finding a suitable function guarantees that is not decidable.
And if we do a mapping-reduction proof where is a language like that we already know is not semidecidable, then just finding a suitable function guarantees that is not semidecidable.
We previously showed that the language
of Turing Machines (programs) that accept at least one string is semidecidable.
Let be the function that takes and returns (the code for) a Turing Machine that ignores its input, and instead simulates running on the specific input .
Clearly is computable. (Given the code for and a specific string , we can produce a slightly longer piece of code that ignores its input and runs the code on the specific string .).
Note that does not run on ! The input of is a piece of code and a string; the output is a slightly longer piece of code.
If accepts , a Turing Machine that ignores its input and runs on will accept not matter what input we provide.
If does not accept , a Turing Machine that ignores its input and runs on will not accept any input we provide.
So if and only if .
This proves and so is not decidable.
Intuitively, the above proof shows that is not decidable because it is “harder than” the undecidable language , as shown by the following mapping reduction:

which shows that if we had a decider for (on the right) then we could combine it with this mapping function to build a decider for (on the left).
There is no algorithm that can always tell us whether an arbitrary TM
(code) accepts the string abba and nothing else. That is, the language
is not decidable.
To show:
Let be the function that takes and
returns
(the code for!) a Turing Machine that accepts its input if the
input is abba and accepts .
So if and only if , as required.

There is no algorithm that can always tell us whether an arbitrary TM (code) could be reimplemented as a DFA. That is, the language
is not decidable.
To show:
Let be the function that takes and returns (the code for!) a Turing Machine that accepts its input if the input has the form for some or if accepts .
So if and only if , as required.

In fact, the language
of TMs equivalent to some DFA is not even semidecidable.
To show:
Let be the function that takes and returns (the code for!) a Turing Machine that accepts its input if the input has the form for some and accepts .
So if and only if , as required.
Since is not semidecidable, it is also not decidable. Had we done this reduction first, we could have skipped the previous Example.

The language
is not even semidecidable.
Proof. We will prove that .
Let be the function that turns the code into the
pair where is a Turing Machine that rejects all
strings.
(It’s not difficult to define a TM that rejects all strings; we just pick one and call it , and then define to be the function that returns its input paired with the fixed piece of code .)