1) For each of the following languages L, state whether it is in D, in SD/D, or not in SD. Prove your answer.
Assume that any input of the form <M> is a description of a Turing machine.
a) {a}.
D. L is finite and thus regular and context-free. By Theorem 20.1, every context-free language is in D.
b) <M> : a L(M)}.
SD/D. Let R be a mapping reduction from H to L defined as follows:
R(< M, w>) =
1. Construct the description <M#> of a new Turing machine M#(x) that, on input x, operates as follows:
1.1. Erase the tape.
1.2. Write w on the tape.
1.3. Run M on w.
1.4. Accept.
2. Return <M#>.
If Oracle exists, then C = Oracle(R(<M, w>)) decides L:
R can be implemented as a Turing machine.
C is correct: M# accepts everything or nothing, depending on whether M halts on w. So:
< M, w> H: M halts on w, so M# accepts all inputs, including a. Oracleaccepts.
< M, w> H: M does not halt on w, so M# accepts nothing. In particular, it does not accept a. Oracle rejects.
But no machine to decide H can exist, so neither does Oracle.
c) {<M> : L(M) = {a}}.
SD: Let R be a reduction from H = {<M, w> : TM M does not halt on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. If x = a, accept.
1.2. Erase the tape.
1.3. Write w.
1.4. Run M on w.
1.5. Accept.
2. Return <M#>.
If Oracle exists and semidecides L, then C = R(<M, w>)) semidecides H:
<M, w> H: M does not halt on w, so M# accepts the string a and nothing else. So L(M#) = {a}.
Oracle accepts.
<M, w> H: M halts on w. M# accepts everything. So L(M#) {a}. Oracle does not accept.
But no machine to semidecide H can exist, so neither does Oracle.
d) {<Ma, Mb> : L(Ma) - L(Mb)}.
SD. Let R be a reduction from H = {<M, w> : TM M does not halt on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that operates as follows:
1.1. Erase the tape.
1.2. Write w.
1.3. Run M on w.
1.4. Accept.
2. Construct the description of M?(x) that, on input x, operates as follows:
2.1. Accept.
3. Return <M?, M#>.
If Oracle exists and semidecides L, then C = Oracle(R(<M, w>)) semidecides H:
R can be implemented as a Turing machine.
C is correct: M? accepts everything, including . M# accepts everything or nothing, depending on whether M halts on w. So:
<M, w> H: M does not halt on w. M# gets stuck in step 1.3. L(M#) = . L(M?) - L(M#)
= L(M?), which contains . So Oracle accepts.
<M, w> H: M halts on w. So L(M#) = *. L(M?) - L(M#) = , which does not contain .
So Oracle does not accept.
But no machine to semidecide H can exist, so neither does Oracle.
e) {<Ma, Mb> : L(Ma) = L(Mb) – {}}.
SD.
f) {<Ma, Mb> : L(Ma) L(Mb)}.
SD. Let R be a reduction from H = {<M, w> : TM M does not halt on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. Erase the tape.
1.2. Write w.
1.3. Run M on w.
1.4. Accept.
2. Construct the description of M?(x) that, on input x, operates as follows:
2.1. Accept.
3. Return <M?, M#>.
If Oracle exists and semidecides L, then C = Oracle(R(<M, w>)) semidecides H:
R can be implemented as a Turing machine.
C is correct: L(M?) = *. M# accepts everything or nothing, depending on whether M halts on w.
So: <M, w> H: M does not halt on w. M# gets stuck in step 1.3. L(M#) = . L(M?) L(M#).
So Oracle accepts.
<M, w> H: M halts on w. So L(M#) = *. L(M?) = L(M#). So Oracle does not accept.
But no machine to semidecide H can exist, so neither does Oracle.
g) {<M, w> : M, when operating on input w, never moves to the right on two consecutive moves}.
D. Notice that M = (K, , , , s, H) must move either to the right or the left on each move. If it cannot move right on two consecutive moves, then every time it moves right, it must next move back left. So it
will never be able to read more than the first square of its input tape. It can, however, move left indefinitely. That part of the tape is already known to contain only blanks. M can write on the tape as it moves left, but it cannot ever come back to read anything that it has written except the character it just wrote and the one immediately to its right. So the rest of the tape is no longer an effective part of M’s configuration. We need only consider the current square and one square on either side of it. Thus the number of effectively distinct configurations of M is max = |K| ||3. Once M has executed max steps, it must either halt or be in a loop. If the latter, it will just keep doing the same thing forever. So the following procedure decides L:
Run M on w for |K| ||3 +1 moves or until M halts or moves right on two consecutive moves:
If M ever moves right on two consecutive moves, halt and reject.
If M halts without doing that or if it has not done that after |K| ||3 +1 moves, halt and accept.
h) {<M> : M is the only Turing machine that accepts L(M)}.
D. L = , since any language that is accepted by some Turing machine is accepted by an infinite number of Turing machines.
i) {<M> : L(M) contains at least two strings}.
SD/D: The following algorithm semidecides L:
Run M on the strings in * in lexicographic order, interleaving the computations. As soon as two such computations have accepted, halt.
Proof not in D: R is a reduction from H = {<M, w> : TM M halts on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. Erase the tape.
1.2. Write w on the tape.
1.3. Run M.
1.4. Accept.
2. Return <M#>.
If Oracle exists and decides L, then C = Oracle(R(<M, w>)) decides H:
<M, w> H: M halts on w so M# accepts everything and thus accepts at least two strings, so Oracle accepts.
<M, w> H: M doesn’t halt on w so M# doesn’t halt and thus accepts nothing and so does not accept at least two strings so Oracle rejects.
But no machine to decide H can exist, so neither does Oracle.
j) {<M> : M rejects at least two even length strings}.
SD/D: The following algorithm semidecides L:
Run M on the even length strings in * in lexicographic order, interleaving the computations. As soon as two such computations have rejected, halt.
Chapter 21 116
Proof not in D: R is a reduction from H = {<M, w> : TM M halts on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. Erase the tape.
1.2. Write w on the tape.
1.3. Run M.
1.4. Reject.
2. Return <M#>.
If Oracle exists and decides L, then C = Oracle(R(<M, w>)) decides H:
<M, w> H: M halts on w so M# rejects everything and thus rejects at least two even length strings, so Oracle accepts.
<M, w> H: M doesn’t halt on w so M# doesn’t halt and thus rejects nothing and so does not reject at least even length two strings. Oracle rejects.
But no machine to decide H can exist, so neither does Oracle.
k) {<M> : M halts on all palindromes}.
SD: Assume that . R is a reduction from H = {<M, w> : TM M does not halt on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. Save its input x on a second tape.
1.2. Erase the tape.
1.3. Write w.
1.4. Run M on w for |x| steps or until it halts.
1.5. If M would have halted, then loop.
1.6. Else halt.
2. Return <M#>.
If Oracle exists and semidecides L, then C = R(<M, w>)) semidecides H:
<M, w> H: M does not halt on w, so M# always gets to step 1.6. So it halts on everything, including all palindromes, so Oracle accepts.
<M, w> H: M halts on w. Suppose it does so in k steps. Then, for all strings of length k or more, M# loops at step 1.5. For any k, there is a palindrome of length greater than k. So M# fails to accept all palindromes. So Oracle does not accept.
But no machine to semidecide H can exist, so neither does Oracle.
l) {<M> : L(M) is context-free}.
SD. R is a reduction from H = {<M, w> : TM M does not halt on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. Save x.
If Oracle exists and semidecides L, then C = Oracle(R(<M, w>)) semidecides H:
<M, w> H: M does not halt on w. M# gets stuck in step 1.4. So L(M#) = , which is context-free.
So Oracle accepts.
<M, w> H: M halts on w. So L(M#) = AnBnCn, which is not context-free. So Oracle does not accept.
But no machine to semidecide H can exist, so neither does Oracle.
m) {<M> : L(M) is not context-free}.
SD. R is a reduction from H = {<M, w> : TM M does not halt on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. If x AnBnCn, accept.
1.2. Erase the tape.
1.3. Write w.
1.4. Run M on w.
1.5. Accept.
2. Return <M#>.
If Oracle exists and semidecides L, then C = Oracle(R(<M, w>)) semidecides H:
<M, w> H: M does not halt on w. M# gets stuck in step 1.4. So L(M*) = AnBnCn, which is not context-free. So Oracle accepts.
<M, w> H: M halts on w. So L(M#) = *, which is context -free. So Oracle does not accept.
But no machine to semidecide H can exist, so neither does Oracle.
n) {<M> : A#(L(M)) > 0}, where A#(L) = |L {a*}|.
SD/D: The following algorithm semidecides L: Lexicographically enumerate the strings in a* and run them through M in dovetailed mode. If M ever accepts a string, accept.
We show not in D by reduction: R is a reduction from H to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1 Erase the tape.
1.2 Write w.
1.3 Run M on w.
1.4 Accept.
2. Return <M#>.
If Oracle exists and decides L, then C = Oracle(R(<M, w>)) decides H:
<M, w> H: M halts on w. M# accepts everything, including strings in a*. So Oracle accepts.
<M, w> H: M does not halt on w. M# accepts nothing. So Oracle rejects.
But no machine to decide H can exist, so neither does Oracle.
Chapter 21 118
o) {<M> : |L(M)| is a prime integer greater than 0}.
SD: Assume that . R is a reduction from H = {<M, w> : TM M does not halt on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. If x is one of the first two strings (lexicographically) in *, accept.
1.2. Erase the tape.
1.3. Write w on the tape.
1.4. Run M on w.
1.5. Accept.
2. Return <M#>.
If Oracle exists and semidecides L, then C = R(<M, w>)) semidecides H:
<M, w> H: M does not halt on w, so the M# accepts only the two strings that it accepts in step 1.1.
So |L(M#)| = 2, which is greater than 0 and prime, so Oracle accepts.
<M, w> H: M halts on w so, M# accepts everything else at step 1.5. There is an infinite number of strings over any nonempty alphabet, so L(M#) is infinite. Its cardinality is not a prime integer. So Oracle does not accept.
But no machine to semidecide H can exist, so neither does Oracle.
p) {<M> : there exists a string w such that |w| < |<M>| and that M accepts w}.
SD/D: The following algorithm semidecides L:
Run M on the strings in * of length less than
|<
M>|
, in lexicographic order, interleaving the computations. If any such computation halts, halt and accept.Proof not in D: R is a reduction from H = {<M, w> : TM M halts on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description <M#> of a new Turing machine M#(x) that, on input x, operates as follows:
1.1. Erase the tape.
1.2. Write w on the tape.
1.3. Run M on w.
1.4. Accept.
2. Return <M#>.
If Oracle exists and decides L, then C = Oracle(R(<M, w>)) decides H:
<M, w> H: M halts on w so M# accepts everything. So, in particular, it accepts , which is a string of length less than |<M>|, so Oracle(<M#>) accepts.
<M, w> H: M doesn’t halt on w so M# doesn’t halt and thus accepts nothing. So, in particular there is no string of length less than |<M>| that M# accepts, so Oracle(<M#>) rejects.
But no machine to decide H can exist, so neither does Oracle.
q) {<M> : M does not accept any string that ends with 0}.
SD: R is a reduction from H = {<M, w> : TM M does not halt on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. Erase the tape.
1.2. Write w on the tape.
1.3. Run M on w.
1.4. Accept.
2. Return <M#>.
If Oracle exists and semidecides L, then C = R(<M, w>)) semidecides H:
<M, w> H: M does not halt on w so M# accepts nothing and so, in particular, accepts no string that ends in 0. So Oracle accepts.
<M, w> H: M halts on w so M# accepts everything, including all strings that end in 0. Since M#
does accept strings that end in 0, M# is not in L and Oracle does not accept.
But no machine to semidecide H can exist, so neither does Oracle.
r) {<M> : there are at least two strings w and x such that M halts on both w and x within some number of steps s, and s < 1000 and s is prime}.
D. Note that in any fixed number s steps, M can examine no more than s squares of its tape. So if it is going to accept any string w that is longer than s, it must also accept a string w that is no longer than s and that is an initial substring of w. So the following algorithm decides L:
Run M on all strings in * of length between 0 and 1000. Try each for 1000 steps or until the computation halts:
If at least two such computations halted in some prime number of steps s, accept.
Else reject.
s) {<M> : there exists an input on which TM M halts in fewer than |<M>| steps}.
D. In |<M>| steps, M can examine no more than |<M>| squares of its tape. So the following algorithm decides L:
Run M on all strings in * of length between 0 and |<M>|. Try each for |<M>| steps or until the computation halts:
If at least one such computation halted, accept.
Else reject.
It isn’t necessary to try any longer strings because, if M accepts some longer string, it does so by looking at no more than |<M>| initial characters. So it would also accept the string that contains just those initial characters. And we’d have discovered that.
Chapter 21 120
t) {<M> : L(M ) is infinite}.
SD. Assume that . R is a reduction from H = {<M, w> : TM M does not halt on w} to L, defined as follows:
R(
<
M,
w>
) =1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. Save its input x on a second tape.
1.2. Erase the tape.
1.3. Write w.
1.4. Run M on w for |x| steps or until it halts.
1.5. If M would have halted, then loop.
1.6. Else accept.
2. Return Oracle(<M#>)
If Oracle exists and semidecides L, then R semidecides H:
<M, w> H: M does not halt on w. So M# always makes it to step 1.6. It accepts everything, which is an infinte set. So Oracle accepts.
<M, w> H: M halts on w. Suppose it does so in k steps. Then M# loops on all strings of length k or greater. It accepts strings of length less than k. But that set is finite. So Oracle does not accept.
But no machine to semidecide H can exist, so neither does Oracle.
u) {<M> : L(M) is uncountably infinite}.
D. L = , since every Turing machine M = (K, , , , s, H) accepts some subset of * and |*| is countably infinite. So L is not only in D, it is regular.
v) {<M> : TM M accepts the string <M, M> and does not accept the string <M>}.
SD. R is a reduction from H = {<M, w> : TM M does not halt on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. If x is of the form yy for some y, accept.
If Oracle exists and semidecides L, then C = R(<M, w>)) semidecides H:
<M, w> H: M does not halt on w. So M# accepts <M, M> and does not accept anything that is not of the form yy, including <M> (which can never be of that form). So Oracle accepts.
<M, w> H: M halts on w. So M# accepts everything. It thus accepts <M>. So Oracle does not accept.
But no machine to semidecide H can exist, so neither does Oracle.
w) {<M> : TM M accepts at least two strings of different lengths}.
SD/D: The following algorithm semidecides L:
Lexicographically enumerate the strings over M* and run M on them in interleaved mode. Each time M accepts a string s, record |s|. If M ever accepts two strings of different lengths, halt and accept.
Proof not in D: R is a reduction from H = {<M, w> : TM M halts on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. Erase the tape.
1.2. Write w on the tape.
1.3. Run M on w.
1.4. Accept.
2. Return <M#>.
If Oracle exists and decides L, then C = Oracle(R(<M, w>)) decides H:
<M, w> H: M halts on w so M# accepts everything. So it accepts at least two strings of different lengths. Oracle accepts.
<M, w> H: M doesn’t halt on w so M# accepts nothing. M# does not accept two strings of any length, so Oracle rejects.
But no machine to decide H can exist, so neither does Oracle.
x) {<M> : TM M accepts exactly two strings and they are of different lengths}.
SD: Assume that . R is a reduction from H = {<M, w> : TM M does not halt on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. If x = a or x = aa accept.
If Oracle exists and semidecides L, then C = Oracle(R(<M, w>)) semidecides H:
<M, w> H: M# accepts at least two strings (a and aa) of different lengths. M does not halt on w, so, on all other inputs, M# gets stuck in step 1.4. So M# accepts exactly two strings and they are of different lengths, so Oracle accepts.
<M, w> H: M# accepts everything. So it accepts more than two strings. So Oracle does not accept.
But no machine to semidecide H can exist, so neither does Oracle.
y) {<M, w> : TM M accepts w and rejects wR}.
SD/D: The following algorithm semidecides L:
Run M on w. If it accepts, run M on wR. If it rejects, accept. In all other cases, loop.
Proof not in D: R is a reduction from H = {<M, w> : TM M halts on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. Save x.
If Oracle exists and decides L, then C = Oracle(R(<M, w>)) decides H:
<M, w> H: M halts on w so M# always makes it to step 1.5. It accepts ab and rejects ba so Oracle accepts.
<M, w> H: M doesn’t halt on w so M# accepts nothing, so Oracle does not accept.
But no machine to decide H can exist, so neither does Oracle.
z) {<M, x, y> : M accepts xy}.
SD/D: The following algorithm semidecides L:
Run M on xy. If it accepts, accept.
Proof not in D: R is a reduction from H = {<M, w> : TM M halts on w} to L, defined as follows:
R(<M, w>) =
1. Construct the description of M#(x) that, on input x, operates as follows:
1.1. Erase the tape.
1.2. Write w on the tape.
1.3. Run M on w.
1.4. Accept.
2. Return <M#, , >.
If Oracle exists and decides L, then C = Oracle(R(<M>)) decides H. R can be implemented as a Turing machine. And C is correct. M# accepts everything or nothing, depending on whether M halts on w. So:
<M, w> H: M halts on w so M# accepts everything, including , so Oracle accepts.
<M, w> H: M doesn’t halt on w so M# accepts nothing, including , so Oracle rejects.
But no machine to decide H can exist, so neither does Oracle.
aa) {<D> : <D> is the string encoding of a deterministic FSM D and L(D) = }.
D. The following algorithm decides L:
1. Check to see that <D> is the string encoding of some deterministic FSM. If it is not, reject.
2. Else use emptyFSM to decide whether L(D) = . If it is, accept. Else reject.
2) In E.3, we describe a straightforward use of reduction that solves a grid coloring problem by reducing it to a graph problem. Given the grid G shown here:
a) Show the graph that corresponds to G.
b) Use the graph algorithm we describe to find a coloring of G.
A, 3, B, 4, A is a cycle. Color A-3 red, 3 blue,
B-4 red, and A-B-4 blue and then remove those edges from the graph.. That leaves the edges B-1, C-4, and D-2. These edges correspond to independent subtrees that can be colored independently. So color them all red.
A B C D
3) In this problem, we consider the relationship between H and a very simple language {a}.
a) Show that {a} is mapping reducible to H.
We must show a computable function R that maps instances of {a} to instances of H. Define R as follows:
R(w) =
1. If w {a}, construct the description of M#(x) that immediately halts on all inputs.
2. If w {a}, construct the description of M#(x) that immediately loops on all inputs.
3. Return <M#, >.
If Oracle exists and decides H, then C = Oracle(R(w)) decides {a}:
s {a}: M# halts on everything, including , so Oracle(<M#, >) accepts.
s {a}: M# halts on nothing, including , so Oracle(<M#, >) rejects.
s {a}: M# halts on nothing, including , so Oracle(<M#, >) rejects.