CSCI 341 Theory of Computation

Fall 2025, with Schmid
← 3.7 Reductions Of Halting4.0 Timing Turing Machines →

Recognizability and Enumerability

Recall that a language \(L\) is recognizable if there is a Turing machine \(\mathcal T\) with a state \(x\) such that \(L = \{w \in A^* \mid \text{\(x\) halts on input \(w\)}\}\). While it is true that \(L_{Halt}\) is not decidable, there is a recognition procedure for \(L_{Halt}\). Indeed, a universal Turing machine \(\mathcal U\) can be used for this purpose.

(Universally Recognized) Let \(\mathcal U\) at state \(c\) be a universal Turing program. Typically, \(\mathcal U\) at \(c\) typically just halts on input \(u \in A_{\mathcal U}^*\) (the universal Turing machine alphabet) if \(u\) is not of the form \(\lfloor \mathcal T\rfloor \mathtt{*} x \mathtt{*} w\) with \(\mathcal T\) a Turing machine, \(x\) a state of \(\mathcal T\), and a word \(w \in \{0,1\}^*\) (this amounts to a syntax error). We can change this behaviour rather easily: instead of halting, let \(\mathcal U\) at state \(c\) enter a forever-loop if it encounters a syntax error.
  1. Consider the string \(\lfloor \mathcal T\rfloor \mathtt{*} x \mathtt{*} w\) with \(\mathcal T\) a Turing machine, \(x\) a state of \(\mathcal T\), and a word \(w \in \{0,1\}^*\). If \(\mathcal U_c(\lfloor \mathcal T\rfloor \mathtt{*} x \mathtt{*} w)\) is well-defined, i.e., \(c\) halts on input \(\lfloor \mathcal T\rfloor \mathtt{*} x \mathtt{*} w\), does \(x\) halt on input \(w\)? Or does it run forever? If it halts, write down its value.
  2. Given any string \(u \in A_{\mathcal U}^*\), if \(c\) halts on input \(u\), what can you tell me about the string \(u\)?
  3. Calculate the language recognized by \(\mathcal U_c\), i.e., \(\mathcal R(\mathcal U, c)\).

The issue here is that while \(L_{Halt}\) is recognizable, it is not additionally co-recognizable. The terminology "co-recognizable" just means that the complement is also recognizable. Write \(\mathsf{coRec}\) for the family of co-recognizable languages.

(Switching Sides) Check that if \(L \in \mathsf{Rec}\), then \(A^* \setminus L \in \mathsf{coRec}\).
(Recognizable + Corecognizable = Decidable) Let \(L \subseteq A^*\) be a language. If \(L\) is both recognizable and co-recognizable (meaning that \(A^*\setminus L\) is recognizable), then \(L\) is decidable. Formally, \(\mathsf{Dec} = \mathsf{Rec} \cap \mathsf{coRec}\).
(C + R = D) Prove that if \(L \subseteq A^*\) is both recognizable and co-recognizable, then \(L\) is decidable. Explain why this implies that \(A^*\setminus L_{Halt}\) is not recognizable.
For the first part, you are essentially given two Turing machines here: one that recognizes \(L\) and one that recognizes \(A^*\setminus L\). Run them "in parallel". For the second, argue by contradition using the first part.

An immediate consequence of this fact is that we have also encountered our first unrecognizable language.

(co-Halting Problem is Unecognizable) The language \(A^* \setminus L_{Halt}\) is unrecognizable, i.e., \(A^* \setminus L_{Halt} \notin \mathsf{Rec}\).

And as an immediate consequence of the co-halting problem being unrecognizable, we also have found our first un-co-recognizable language as well.

(Not Not Not Not Halting Problem) Is \(L_{Halt} \in \mathsf{coRec}\)?

You might be wondering at this point if there are languages that are neither recognizable nor co-recognizable. These languages are a bit exotic, but they do exist. If you're just looking for an example, there is a nice little lemma we can use to produce them.

(Binary Branching Recognizable) Let \(L \subseteq \{0,1\}^*\) be any language. If \(L \notin \mathsf{Rec}\), then \[ (\{0\} \cdot L) \cup (\{1\}\cdot (A^* \setminus L)) \notin \mathsf{Rec} \qquad \text{and} \qquad (\{0\} \cdot L) \cup (\{1\}\cdot (A^* \setminus L)) \notin \mathsf{coRec} \]
Let \(L \subseteq \{0,1\}^*\) be a language that is not recognizable, and let \[ U = (\{0\} \cdot L) \cup (\{1\}\cdot (A^* \setminus L)) \] Assume for a contradiction that \(U \in \mathsf{Rec}\). Then there is a Turing machine \(\mathcal T\) with a state \(x\) such that \( U = \mathcal R(\mathcal T, x) \). That is, for any \(w \in \{0,1\}^*\), \(w \in U\) if and only if \(x\) halts on input \(w\). We need to produce a Turing program that recognizes \(L\). Exhibit A: let \(\mathcal T'\) at its state \(y\) be the Turing program that writes a \(0\) to the left of the input tape and then proceeds with the Turing program \(\mathcal T\) at \(x\). Then
\(\mathcal T'\) at \(y\) halts on an input word \(w\)
if and only if \(\mathcal T\) at \(x\) halts on input \(0w\)
if and only if \(0w \in U\)
if and only if \(w \in L\)

Hence, \(\mathcal T'\) at \(y\) recognizes \(L\), which contradicts our initial assumption that \(L\) is unrecognizable.

Conversely, suppose that \(U\) is co-recognizable. This is the same thing as saying that \(A^*\setminus U\) is recognizable. Suppose that \(\mathcal T\) at state \(x\) recognizes \(A^*\setminus U\). Since \[\begin{aligned} A^* \setminus U &= A^* \setminus ((\{0\} \cdot L) \cup (\{1\}\cdot (A^* \setminus L))) \\ &= (A^* \setminus (\{0\} \cdot L)) \cap (A^* \setminus (\{1\}\cdot (A^* \setminus L))) \\ &= \{\varepsilon\} \cup (\{1\} \cdot L) \cup (\{0\}\cdot (A^* \setminus L)) \end{aligned}\] we can argue similarly to how we did before that if \(A^* \setminus U \) is recognizable, then \(L\) is recognizable.

Enumerators and Recognizability

Recognizability is closely related to enumerator programs. Roughly, an enumerator program is a program (state in a Turing machine) that computably represents a language as a sequence of words rather than just a set of words. For example, the language \(L_{\mathbb N} = \{1^n \mid n \in \mathbb{N}\}\) can be represented as the sequence \[ \varepsilon,~1,~11,~111,~1111,~\cdots \] This is really the most basic language-as-sequence, and so we're going to build our notion of "enumerability" on top of it.

(Enumerator) Let \(L \subseteq A^*\) be a language and write \(L = \{w_n \mid n \in \mathbb N\}\). An enumerator for \(L\) is a Turing machine \(\mathcal E\) with a state \(x\) such that \[ \mathcal E_x(1^n) = w_n \] for all \(n \in \mathbb N\).

A language \(L\) is called enumerable if there is an enumerator for \(L\). The family of enumerable languages is written \(\mathsf{Enu}\).
If the alphabet is finite or Since \(L\) is countable, \(L\) is going to be countable as well, so we can always write the elements of \(L\) as a list, \(L = \{w_0, w_1, w_2, \dots\}\). This doesn't mean that \(L\) is enumerable!

An easy (direct) consequence of the definition is that the Turing machine that does nothing and immediately halts is an enumerator for the language \(L_{\mathbb N}\) defined above.

(I will Be the 11111) Show that the language \(L_{\mathbb N} = \{1^n \mid n \in \mathbb{N}\}\) is enumerable.

Let's take a look at a slightly more complex enumerable language.

Consider the language of all binary representations of natural numbers, \[ L_{bin} = \{\mathsf{bin}(n) \mid n \in \mathbb{N}\} \] This language can be written as a list, \[ 0,~1,~10,~11,~100,~101,~110,~\dots \] where we simply add \(1\) to the number in binary at each step. In a previous section, you showed how to build a Turing program called \(\mathtt{succ}\), which added one to its input represented as a binary number. For example, \(\mathcal T_{\mathtt{succ}}(1001) = 1010\), because \(9 + 1 = 10\). This is the key helper-subroutine that goes into out enumerator. Define the following Turing machine \(\mathcal E\) at its state \(\mathtt{enum}\) on input \(1^n\). Note that at the start, the tape is a sequence of \(1\)s.
  1. Rewind the tape and write \(0\#\) to the beginning of the tape. \[\begin{array}{l c c c c c c r} & \triangledown & & {\color{grey}(} & {\color{grey} 1^n} & {\color{grey})} & & \\ \hline \cdots & 0 & \# & 1 & \cdots & 1 & & \cdots \\ \hline \end{array}\]
  2. Fast forward to the end of the tape. If the tape head reads \(\#\), erase and halt. Otherwise, if it reads a \(1\), erase the \(1\) and proceed to step 3.
  3. Rewind to the cell immediately to the left of \(\#\). Run \(\mathtt{succ}\) to add one to the number represented in binary before the \(\#\). Go to step 2.
For example, for \(n = 3\), \[\begin{array}{l c c c c c c c c c r} & & & & & & \triangledown & & & & \text{input}\\ \hline \cdots & & & & & & 1 & 1 & 1 & & \cdots \\ \hline %%%%%%%%% & & & & \triangledown & & & & & & \text{step 1}\\ \hline \cdots & & & & 0 & \# & 1 & 1 & 1 & & \cdots \\ \hline %%%%%%%%% & & & & & & & & \triangledown & & \text{step 2} \\ \hline \cdots & & & & 0 & \# & 1 & 1 & & & \cdots \\ \hline %%%%%%%%% & & & & \triangledown & & & & & & \text{step 3} \\ \hline \cdots & & & & 1 & \# & 1 & 1 & & & \cdots \\ \hline %%%%%%%%% & & & & & & & \triangledown & & & \text{step 2} \\ \hline \cdots & & & & 1 & \# & 1 & & & & \cdots \\ \hline %%%%%%%%% & & & \triangledown & & & & & & & \text{step 3} \\ \hline \cdots & & &1 & 0 & \# & 1 & & & & \cdots \\ \hline %%%%%%%%% & & & & & & \triangledown & & & & \text{step 2} \\ \hline \cdots & & & 1 & 0 & \# & & & & & \cdots \\ \hline %%%%%%%%% & & & \triangledown & & & & & & & \text{step 3} \\ \hline \cdots & & & 1 & 1 & \# & & & & & \cdots \\ \hline %%%%%%%%% & & & & & \triangledown & & & & & \text{step 2} \\ \hline \cdots & & & 1 & 1 & & & & & & \cdots \\ \hline \end{array}\] At the end, \(\mathcal E_{\mathtt{enum}}(111) = 11 = \mathsf{bin}(3)\).
(Let's Enumerate Everything!) Show that the complete language of all strings \( \{0,1\}^* \) is enumerable by designing an enumerator for it.
You should make use of the enumerator for \(L_{bin}\) in the example, but with a twist. Every string of \(0\)s and \(1\)s corresponds to a binary representation of a natural number, except those that have leading \(0\)s. So how do you include the strings of \(0\)s and \(1\)s that don't necessarily start with a \(1\)?
(Enumerating Doubles) Show that the language \[ L_{2bin} = \{\mathsf{bin}(2n) \mid n \in \mathbb{N}\} \] is enumerable by designing an enumerator for it.

As it turns out, recognizability and enumerability are equivalent.

(Enumerable = Recognizable) A language is recognizable if and only if it is enumerable. That is, \(\mathsf{Rec} = \mathsf{Enu}\).
Show that if a language is enumerable, then it is recognizable.
Let \(L \subseteq A^*\). Suppose that \(\mathcal E\) at state \(\mathtt{enum}\) is an enumerator for \(L\). Construct a Turing machine \(\mathcal T\) with a state \(x\) that operates as follows: given a word \(w \in A^*\), \(x\) checks whether \(\mathcal E_y(1^n) = w\) for each \(n \in \mathbb N\), and halts when it succeeds.
(Sketch) The problem above shows that \(\mathsf{Enu} \subseteq \mathsf{Rec}\). For the other direction, let \(L \in \mathsf{Rec}\), and let \(\mathcal T\) at state \(x\) be a Turing program that recognizes \(L\). All that is left is to exhibit an enumerator for \(L\). The basic idea behind the construction is to start by enumerating all of the possible sequenece of \(0\)s and \(1\)s, \[ \varepsilon, ~0, ~1, ~00, ~01, ~10, ~11, ~000, ~001, ~010, ~100, ~101, \dots \] For \(k \in \mathbb N\), write \(w_k\) for the \(k\)th string in this sequence. The pseudocode for the enumeration procedure is as follows: starting with an input string \(1^n\), we need to produce the \(n\)th word in the language.
def enum :
  set k = 1
  set m = n
  while m > 0 :
     for i from 1 to k :
       if \(x\) halts in \(\le k - i\) steps on input \(w_i\) :
         set m = m - 1
Intuitively, the \(n\)th time \(\mathtt{enum}\) sees that \(x\) halts, \(\mathtt{enum}\) halts.

Altogether, we have the following picture.

← 3.7 Reductions Of Halting4.0 Timing Turing Machines →
Top