Title

ECS 120 Theory of Computation
Undecidability: More Undecidable Problems
Julian Panetta
University of California, Davis

Recall: The Halting Problem and Turing Reducibility

The following problem is Turing recognizable but not decidable: \[ \probHALT = \setbuild{\encoding{M, w}}{M \text{ is a Turing machine that halts on } w} \]

  • We can use this to show that other problems are also undecidable via Turing reductions.
  • Informally: \(A\) is Turing reducible to \(B\) if
    “an algorithm \(M_B\) for \(B\) can be used as a subroutine to create an algorithm \(M_A\) for \(A\).”
  • These Turing reductions are more flexible than the polynomial-time reductions we used to prove \(\NP\)-hardness.
    • The input conversion doesn’t have to run in polynomial time or keep lengths small.
    • The “subroutine” \(M_B\) can be called multiple times.
    • Arbitrary (but finite) computation can be done on \(M_B\)’s “return values”

More Undecidable Problems: No-Input Halting

Simple example of a Turing reduction:
showing that the no-input Halting problem is undecidable

\[ \probHALT_\emptystring = \setbuild{\encoding{M}}{M \text{ is a Turing machine and } M(\emptystring)} \]

\(\probHALT_\emptystring\) is obviously reducible to \(\probHALT\) since it is just a special case!
We could decide if \(\encoding{M} \in \probHALT_\emptystring\) by checking if \(\encoding{M, \emptystring} \in \probHALT\).

But \(\probHALT_\emptystring\) could easier…

  • We’ll show \(\probHALT\) is reducible to \(\probHALT_\emptystring\).
    • If we had an algorithm to decide \(\probHALT_\emptystring\),
      we could use it to decide \(\probHALT\).
    • Since \(\probHALT\) is undecidable, this algorithm cannot exist!

More Undecidable Problems: No-Input Halting

Simple example of a Turing reduction:
showing that the no-input Halting problem is undecidable

\[ \probHALT_\emptystring = \setbuild{\encoding{M}}{M \text{ is a Turing machine and } M(\emptystring)} \]

Theorem: \(\probHALT_\emptystring\) is undecidable.

Proof:

  • Suppose that \(\probHALT_\emptystring\) is decidable by an algorithm:

    def H_𝜀(M): raise NotImplementedError()
  • We can use this to decide \(\probHALT\) as follows:

    def H(M, w):
        # Create a new algorithm T_Mw that ignores its input
        # and has the original input w "hardcoded".
        def T_Mw(_):     # This is algorithm is never actually run!!!
            return M(w)
        return H_𝜀(T_Mw) # ... but instead is analyzed by H_𝜀.
  • If M(w) halts, then:
    • T_Mw halts on all inputs (including \(\emptystring\)).
    • So H_𝜀(T_Mw)returns True.
  • If M(w) loops (doesn’t halt), then:
    • T_Mw loops on any input.
    • So H_𝜀(T_Mw) returns False.
  • Therefore H decides \(\probHALT\), which is a contradiction.

More Undecidable Problems: a General Recipe

  • The previous argument follows a pattern we will use to show that many other questions we might ask about an algorithm’s eventual behavior are undecidable.

  • We prove that an algorithm \(A\) deciding that other question cannot exist by showing it can be used to solve the Halting problem.

  • Specifically, we will use it to solve \(\probHALTe\), which is slightly more convenient.

  • The steps are:

    1. Receive an arbitrary Turing machine \(M\) (or a Python function)
    2. Construct a new Turing machine \(T_M\) that:
      1. Runs \(M(\emptystring)\).
      2. Does the behavior that \(A\) is looking for if and only if \(M(\emptystring)\) ever halts.
    3. Pass \(T_M\) to algorithm \(A\) and return the result.
  • The resulting \(A\) will return true if and only if \(M(\emptystring)\) halts, thus deciding \(\probHALTe\).

More Undecidable Problems: Acceptance Problem

Let’s apply this recipe to the following problem:

\[ \probAccepts = \setbuild{\encoding{M, w}}{M \text{ is a Turing machine that accepts } w} \]

Theorem: \(\probAccepts\) is undecidable.

Proof:

  • Suppose that \(\probAccepts\) is decidable by alg. A:

    def A(M, w): raise NotImplementedError()
  • We can use A to decide \(\probHALTe\) as follows:

    def H_𝜀(M):
        # Create a new algorithm T_M that accepts any input
        # if and only if M halts on the empty string.
        def T_M(w):          # Input is ignored!
            M('')
            return True
        return A(T_M, '011') # Analyze T_M using hypothetical decider A
  • If M('') halts, then:
    • T_M returns True on all inputs.
    • So A(T_M, w) and H_𝜀 return True.
  • If M('') loops (does not halt), then:
    • T_M never reaches the return.
    • So A(T_M, w) and H_𝜀 return False.
  • Formally: \[ \begin{aligned} M(\emptystring) \text{ halts } &\iff T_M \text{ accepts } \string{011} \\ &\iff A \text{ accepts } \encoding{T_M, 011} \\ &\iff H_𝜀 \text{ accepts } \encoding{M} \end{aligned} \]
  • Therefore H_𝜀 decides \(\probHALTe\),
    which is a contradiction.

More Undecidable Problems: Empty Language Problem

\[ \probEmpty = \setbuild{\encoding{M}}{M \text{ is a Turing machine and } L(M) = \emptyset} \]

In other words: \(M\) accepts no inputs.

Theorem: \(\probEmpty\) is undecidable.

Proof:

  • Suppose that \(\probEmpty\) is decidable by algorithm E:

    def E(M): raise NotImplementedError()
  • We can use E to decide \(\probHALTe\) as follows:

    def H_𝜀(M):
        # Create a new algorithm that accepts a string
        # if and only if M halts on the empty string.
        def T_M(w):
            M('')
            return True
        return not E(T_M) # Analyze T_M using hypothetical decider E
  • If M('') halts, then:
    • T_M returns True on all inputs.
    • So E(T_M, w) returns False and
      H_𝜀 returns True.
  • If M('') loops (does not halt), then:
    • T_M never reaches the return.
    • So E(T_M, w) returns True and
      H_𝜀 returns False.
  • Formally: \[ \begin{aligned} M(\emptystring) \text{ halts } &\iff T_M \text{ accepts all strings } \\ &\iff E \text{ rejects } \encoding{T_M} \\ &\iff H_𝜀 \text{ accepts } \encoding{M} \end{aligned} \]
  • Therefore H_𝜀 decides \(\probHALTe\),
    which is a contradiction.

Could we instead make T_M return False and H_𝜀 return E(T_M)?

  • Yes
  • No

More Undecidable Problems: Rejecting Problem

\[ \probRejects = \setbuild{\encoding{M}}{M \text{ is a Turing machine that rejects at least one input}} \]

Theorem: \(\probRejects\) is undecidable.

Proof:

  • Suppose that \(\probRejects\) is decidable by algorithm R:

    def R(M): raise NotImplementedError()
  • We can use R to decide \(\probHALTe\) as follows:

    def H_𝜀(M):
        # Create a new algorithm that rejects a string
        # if and only if M halts on the empty string.
        def T_M(w):
            M('')
            return False
        return R(T_M) # Analyze T_M using hypothetical decider R
  • If M('') halts, then:
    • T_M returns False on all inputs.
    • So R(T_M, w) returns True and
      H_𝜀 returns True.
  • If M('') does not halt, then:
    • T_M never reaches the return.
    • So R(T_M, w) returns False and
      H_𝜀 returns False.
  • Formally: \[ \begin{aligned} M(\emptystring) \text{ halts } &\iff T_M \text{ rejects all strings } \\ &\iff R \text{ accepts } \encoding{T_M} \\ &\iff H_𝜀 \text{ accepts } \encoding{M} \end{aligned} \]
  • Therefore H_𝜀 decides \(\probHALTe\),
    which is a contradiction.

More Undecidable Problems: How to Spot

  • When faced with a new problem, we can always follow the recipe to show it’s undecidable.
  • But often we can spot at a glance that the problem must be undecidable.
  • Questions about “eventual” algorithm “behavior” are undecidable.
  • Example: given program \(P\) and input \(x\):
    • Does \(P\) accept x?
    • Does \(P\) reject x?
    • Does \(P\) loop on x?
    • Does \(P(x)\) ever call subroutine \(f\)?
  • Example questions about general program behavior:
    • Does \(P\) accept at least one input?
    • Does \(P\) accept all inputs?
    • Is \(P\) total?
    • Is there an input \(x\) such that \(P(x)\) returns 42?
    • Does some input cause \(P\) to call subroutine \(f\)?
    • Do \(P\) and \(Q\) decide the same language?
    • Is \(P\) a polynomial-time machine?

Decidable Problems about Programs

  • Not all questions we can ask about a program are undecidable though!
  • Questions about syntax are decidable:
    • Does \(P\) have 100 lines of code?
    • Does \(P\) have 2 and 3 in its input alphabet?
    • Does \(P\) halt immediately because its first line is an immediate return without a subroutine call?
    • Does \(P\) have a subroutine f?
  • Some questions about behavior are decidable:
    • Does \(P(x)\) halt within 10 steps?
    • Does \(P(x)\) halt within \(n^3\) steps, where \(n = |x|\)?
    • Does \(P(x)\) call subroutine \(f\) in the fifth step?

Some Examples

Which of the following problems is decidable about a problem \(P\) and input \(x\)?

  • Does \(P(x)\) run in \(n \log n\) steps?
  • Does \(P(x)\) run in time \(O(n \log n)\)?
  • Does \(P\) decide the language \(\setbuild{\encoding{n}}{n \text{ is prime}}\)?
  • Does \(P\), as a Turing machine, have transitions only moving the tape head to the right?