Decidable and Turing-Recognizable Languages

Imagine handing a computer a description of another program and a claimed property. You ask it to answer yes or no. It must always answer, correctly, and in finite time. This is the question that separates the languages a machine can decide from the languages it can merely recognize. Some problems admit an algorithm that always halts with the right verdict. Others admit only a procedure that confirms "yes" when the answer is yes. Such a procedure may loop forever on "no" instances. It never tells you to give up. This distinction is not a technicality. It is the central fault line of computability theory. It explains why some real problems are fully automatable. For example, testing whether a regular expression matches a string is fully automatable. Other problems can only be approximated, never fully solved by a general algorithm. Examples include testing whether an arbitrary program halts. Another example is testing whether a compiler optimization preserves behavior. Understanding deciders versus recognizers is the prerequisite for everything that follows in the theory of unsolvability. The Halting Problem, reductions, and the arithmetic hierarchy all rest on this vocabulary. The big picture is a hierarchy of language classes. These classes are built directly from the notion of a Turing Machine computing on a configuration sequence. A Turing machine can accept, reject, or run forever on a given input. Depending on which of these behaviors we permit and which we forbid, we get different classes. These are the decidable languages (also called recursive), the Turing-recognizable languages (also called recursively enumerable, r.e., or semidecidable). As a preview, there are also the co-Turing-recognizable languages. Their relationship to decidability will be developed once closure properties are in hand. This article delivers precise definitions of deciders and recognizers. It offers a careful proof that decidable languages form a strict subset of recognizable languages. It presents worked machine constructions. These show how to convert between semi-decision procedures and search-based enumeration. Finally, it gives an honest discussion of why the gap between the two classes is unavoidable. This gap is not a defect of imagination.

Key takeaways
  • A decider is a Turing machine that halts on every input, always outputting accept or reject.
  • A recognizer only guarantees halting and accepting on "yes" inputs; on "no" inputs it may reject or loop forever.
  • Decidable (recursive) languages are exactly those recognized by some decider.
  • Turing-recognizable (recursively enumerable) languages are exactly those recognized by some Turing machine, decider or not.
  • Every decidable language is Turing-recognizable, but not conversely — the containment is strict.
  • The strictness is witnessed concretely by the Halting Problem language, which is recognizable but not decidable.
The core insight

A language is decidable if some machine always halts and answers correctly, but merely Turing-recognizable if some machine halts and answers correctly only on the "yes" instances.

The idea

A Turing machine MM processes an input string ww by running through a sequence of configurations, as established when configurations and single-step computation were defined. On any fixed input, exactly one of three things happens: MM enters its accept state and halts, MM enters its reject state and halts, or MM runs forever without halting. This trichotomy is the raw material from which the entire vocabulary of computability is built. Call MM a decider if, for every input string ww, MM halts — either accepting or rejecting — and never loops forever. A decider gives you a complete, guaranteed verdict on every input; this is the strongest and most desirable behavior an algorithm can exhibit. A language LL is decidable (equivalently, recursive) if there exists some decider MM with L(M)=LL(M) = L, meaning w∈L  ⟺  Mw \in L \iff M accepts ww, and additionally MM halts on every ww (accepting members of LL and rejecting everything else). Call MM a recognizer for language LL if L(M)=LL(M) = L, with no further requirement: MM must accept every w∈Lw \in L, but on strings w∉Lw \notin L, MM is permitted either to reject or to run forever. A language LL is Turing-recognizable (equivalently, recursively enumerable, or r.e., or semidecidable) if some Turing machine recognizes it. The word "semidecidable" captures the asymmetry precisely: only the "yes" side of the decision is guaranteed to terminate. The crucial structural fact is that every decider is automatically a recognizer — a machine that always halts correctly is in particular a machine that accepts exactly the members of LL (it just happens to also reject everything else with a guarantee). This immediately gives

Decidable⊆Turing-recognizable.\text{Decidable} \subseteq \text{Turing-recognizable}.

The heart of computability theory is the discovery that this containment is strict: there exist languages that are Turing-recognizable but not decidable. The canonical witness is

ATM={⟨M,w⟩:M is a Turing machine that accepts input w},A_{TM} = \{\langle M, w\rangle : M \text{ is a Turing machine that accepts input } w\},

the language underlying the Halting Problem's acceptance variant. ATMA_{TM} is Turing-recognizable — simulate MM on ww and accept if the simulation accepts — but no decider for ATMA_{TM} can exist, by a diagonalization argument. This single example is the seed from which nearly all undecidability results grow via reduction.

How it works

The clean way to see the relationship between deciding and recognizing is to build the machines explicitly and to prove the equivalence theorem that connects "recognizable" to "there is an algorithm that enumerates the language."

Building a recognizer from a machine that simulates another machine. Given the encoded pair ⟨M,w⟩\langle M, w \rangle, a universal recognizer UU simulates MM step by step on ww: ``` procedure Recognize-ATM(⟨M, w⟩): // U is a universal Turing machine: it interprets M's transition // table and simulates M running on w, one configuration at a time. initialize configuration C0 := start configuration of M on w C := C0 loop forever: if C is an accepting configuration of M: accept if C is a rejecting configuration of M: reject C := next configuration of M from C // one simulated step // if M loops forever on w, this loop never halts — that is fine // for a recognizer, but would violate the decider requirement ``` This machine is a legitimate recognizer for ATMA_{TM}: whenever MM accepts ww, the simulation eventually reaches an accepting configuration and UU accepts; whenever MM rejects ww, UU rejects; whenever MM loops on ww, UU loops too. UU never gives a wrong answer, but it fails the decider requirement precisely on the looping case — it does not halt there.

Why you cannot simply "wait longer" to fix this. A natural instinct is: run MM for more and more steps, and if it hasn't halted, guess "no." This is unsound, because for any finite bound tt, there exist machine-input pairs that take more than tt steps to accept. Any fixed cutoff misclassifies some accepting instance as rejecting. There is no way to distinguish, by looking only at a finite prefix of the computation, "still working" from "will never finish."

The Enumeration Theorem. A deeper structural fact makes "Turing-recognizable" synonymous with "the language of accepted strings can be listed by an algorithm, possibly with repetition and without a guarantee of ever hitting a given non-member." Formally: LL is Turing-recognizable iff there is a Turing machine EE (an enumerator) that, running with no input, prints out a sequence of strings w1,w2,w3,…w_1, w_2, w_3, \ldots (with possible repeats, in any order, possibly running forever) such that LL is exactly the set of strings that eventually get printed. From enumerator to recognizer: given EE, build MM that on input ww runs EE, and whenever EE prints a string, checks whether it equals ww; if so, MM accepts. If w∈Lw \in L, it will appear in EE's output eventually, so MM accepts; if w∉Lw \notin L, MM simply never accepts (it loops), which is exactly recognizer behavior. From recognizer to enumerator — the dovetailing trick: this direction is the more delicate and instructive one, because a naive attempt fails. Given recognizer MM, you cannot just "run MM on w1w_1, then w2w_2, then …" because MM might loop forever on w1w_1 if w1∉Lw_1 \notin L, and you would never get to try w2w_2. The fix is to dovetail: interleave a growing amount of simulation time across a growing set of candidate strings. ``` procedure Enumerate(M): // M is a recognizer for language L, over some fixed alphabet Σ. // s1, s2, s3, ... is the standard enumeration of all strings in Σ* // in length-then-lexicographic order (so every string appears at // a specific finite index). for i := 1, 2, 3, ...: for j := 1 to i: simulate M on input s_j for exactly i steps if M accepts s_j within those i steps: print s_j // may print duplicates; that is allowed ``` Every pair (i,j)(i, j) with j≤ij \le i is visited exactly once as ii ranges over all positive integers, so for any fixed string sjs_j that MM accepts within kk steps, the pair (i,j)=(max⁡(k,j),j)(i, j) = (\max(k, j), j) (or any i≥max⁡(k,j)i \ge \max(k,j)) is eventually reached, and sjs_j gets printed. Strings not in LL are never printed, because MM never accepts them regardless of how long it runs. This establishes the equivalence in both directions.

Figure
Dovetailing: interleaving simulation time across all candidate strings so no single non-halting run blocks progress
Dovetailing grid: outer loop i, inner loop j ≤ i strings → steps ↑ s1 s2 s3 s4 s5 s6 i=1 i=2 i=3 i=4 i=5 i=6 accept! s3 loops forever if simulated alone — but at row i=3 it gets exactly 3 steps, catches its accept, and is printed.

Complexity & correctness

Deciders. If MM is a decider running in T(n)T(n) steps on inputs of length nn, deciding membership costs O(T(n))O(T(n)) time and O(S(n))O(S(n)) space where S(n)S(n) is the space MM uses — these bounds are exactly the resource bounds studied later under Time Complexity and space complexity. The definitional claim here is not about a specific bound but about guaranteed termination: for every ww, the computation of MM on ww is a finite sequence of configurations ending in accept or reject. This is an all-quantified halting guarantee, and it is what makes decidability a robust, checkable-in-principle property from the outside — you can always ask "has it halted yet?" and eventually get a truthful "yes."

Recognizers. A recognizer gives no uniform bound on halting time as a function of nn alone — indeed for a fixed length there can be no computable bound, since if there were, you could decide the language by running for that many steps and rejecting if it never halted, contradicting undecidability of languages like ATMA_{TM}. So the "complexity" of a mere recognizer is unbounded on the reject side; only accepting runs are guaranteed finite, and even then with no known bound in advance.

Correctness of the enumerator/recognizer equivalence. The proof sketch above is a full correctness argument, but it is worth stating the invariant explicitly. In the dovetailing enumerator, the invariant maintained after completing outer iteration ii is: > For every j≤ij \le i and every string sjs_j that MM accepts within ii steps, sjs_j has already been printed. This invariant holds by direct execution of the nested loop (the inner loop at outer index ii explicitly simulates sjs_j for ii steps for every j≤ij \le i). Taking i→∞i \to \infty, every string sj∈Ls_j \in L eventually satisfies "MM accepts sjs_j within ii steps" for ii large enough (namely i≥max⁡(j,acceptance time of sj)i \ge \max(j, \text{acceptance time of } s_j)), so it is printed at that stage or later. Conversely no sj∉Ls_j \notin L is ever printed, since printing only happens upon a genuine accept by MM's simulation. This is exactly the semantics of Turing-recognizability, establishing the equivalence rigorously rather than by analogy.

Why decidable ⊊\subsetneq recognizable, not just ⊆\subseteq. The inclusion direction is immediate (a decider is a recognizer). Strictness needs a genuine diagonalization, sketched here because it is the load-bearing fact of the whole subject. Suppose, for contradiction, that ATMA_{TM} had a decider HH: H(⟨M,w⟩)H(\langle M, w\rangle) always halts, accepting iff MM accepts ww. Construct DD: ``` procedure D(⟨M⟩): if H(⟨M, ⟨M⟩⟩) accepts: // does M accept its own description? reject else: accept ``` DD is well defined and always halts, because HH is assumed to always halt. Now ask what DD does on its own description ⟨D⟩\langle D \rangle:

  • If DD accepts ⟨D⟩\langle D\rangle, then by DD's definition H(⟨D,⟨D⟩⟩)H(\langle D,\langle D\rangle\rangle) rejected, meaning DD does not accept ⟨D⟩\langle D\rangle — contradiction.
  • If DD rejects ⟨D⟩\langle D\rangle, then H(⟨D,⟨D⟩⟩)H(\langle D,\langle D\rangle\rangle) accepted, meaning DD does accept ⟨D⟩\langle D\rangle — contradiction.

Both cases are contradictory, so no such HH can exist. Hence ATMA_{TM} is undecidable. But ATMA_{TM} is Turing-recognizable (the universal simulator above recognizes it), which exhibits a concrete language in Turing-recognizable minus decidable, proving the containment strict. This argument is the direct descendant of Cantor's diagonal argument against a bijection between a set and its power set, transplanted into the world of machine descriptions.

Tradeoffs, honestly stated. Decidability is the gold standard but is a strong requirement that many natural questions fail to meet; recognizability is a weaker, more common guarantee that still has teeth (it supports semi-automated verification: run and wait, and if it says yes, trust it). The class of decidable languages is closed under complement, union, and intersection — because you can build a decider for the complement by simply flipping the accept/reject roles of a decider, which halts on everything by hypothesis. Turing-recognizable languages are closed under union and intersection (dovetail two recognizers) but not guaranteed closed under complement, which is exactly the seed of the co-Turing-recognizable class and its relation to decidability, taken up separately.

Worked example

Consider three concrete languages over machine encodings, tracing what kind of machine each admits.

Language 1: ADFA={⟨B,w⟩:BA_{DFA} = \{\langle B, w \rangle : B is a DFA that accepts string w}w\}.

StepWhat the decider does
1Parse ⟨B,w⟩\langle B, w \rangle into a DFA description and a string.
2Simulate BB on ww: start at BB's start state, read ww symbol by symbol, follow transitions.
3Because ww is finite and each symbol read strictly advances the simulation, this loop terminates after exactly ∣w∣|w| transitions.
4Accept if the final state is accepting; reject otherwise.

This machine always halts — the simulation is bounded by ∣w∣|w| steps with no possibility of looping, since DFA computation is a straight-line walk through states with no branching or backtracking. Hence ADFAA_{DFA} is decidable.

Language 2: ATM={⟨M,w⟩:MA_{TM} = \{\langle M, w\rangle : M accepts w}w\}, as above.

StepWhat the universal recognizer does
1Parse ⟨M,w⟩\langle M, w \rangle.
2Simulate MM step by step on ww, updating the simulated configuration each time.
3If a simulated step reaches accept, halt and accept.
4If a simulated step reaches reject, halt and reject.
5If MM never halts on ww, the simulation runs forever — no fallback exists.

This machine recognizes ATMA_{TM} but is not a decider, precisely because step 5 can occur (e.g. MM is a machine that loops on all inputs, so ⟨M,w⟩∉ATM\langle M, w\rangle \notin A_{TM} and the simulator hangs). By the diagonalization argument above, no decider for ATMA_{TM} exists — this failure is unavoidable, not a limitation of this particular construction.

Language 3: ETM={⟨M⟩:L(M)=∅}E_{TM} = \{\langle M \rangle : L(M) = \emptyset\} ("does MM accept nothing at all?"). Trying the naive approach — dovetail MM over all strings and see if it ever accepts — gives a recognizer for the complement ETM‾\overline{E_{TM}} (accept if you ever witness MM accept something), but gives no recognizer for ETME_{TM} itself in any obvious way, and in fact ETME_{TM} can be shown Turing-recognizable-but-not-decidable by reduction from ATMA_{TM}, foreshadowing the reduction technique used pervasively once decidable problems about automata are studied in depth. The three languages above thus stratify exactly the classes this article defines: fully decidable (ADFAA_{DFA}), recognizable but not decidable (ATMA_{TM}), and a further example (ETME_{TM}) whose non-recognizable complement will matter once closure under complement is examined.

A second trace, showing dovetailing concretely. Suppose alphabet Σ={a}\Sigma = \{a\} and MM is a recognizer such that MM accepts sj=ajs_j = a^j after exactly 2j2j steps of simulation (a toy stand-in for "acceptance time grows with input"). Enumerate s1=a,s2=aa,s3=aaa,…s_1=a, s_2=aa, s_3=aaa,\ldots

Outer iiInner jjSteps given to sjs_jsjs_j accepts within budget?Printed?
111needs 2, nono
212needs 2, yesprint aa
222needs 4, nono
313already printed, printed againprint aa (duplicate, harmless)
323needs 4, nono
333needs 6, nono
424needs 4, yesprint aaaa
434needs 6, nono
444needs 8, nono
⋮\vdotseventually every aja^j printed at i≥2ji \ge 2j

Every string eventually gets enough simulated steps to reveal its true accept time, so the enumerator prints exactly {aj:j≥1}\{a^j : j \ge 1\} (with repeats), matching L(M)L(M) exactly, as the general argument guarantees.

Common pitfalls & traps

PitfallWhy it's wrongFix
Treating "recognizer rejects" and "recognizer loops" as the same outcomeA recognizer is allowed to loop on non-members; conflating loop with reject silently upgrades it to a decider it may not beAlways state separately: accept guarantee, reject-or-loop on non-members
Believing you can "wait long enough and then reject"No computable bound on halting time exists uniformly for an arbitrary recognizer; assuming one exists effectively assumes decidability, begging the questionOnly convert to a decider if you have an independent proof of a halting bound
Assuming Turing-recognizable is closed under complementIt is not, in general — ATMA_{TM} is recognizable but ATM‾\overline{A_{TM}} is not, a fact that becomes central once co-recognizable classes are studiedDon't reuse decidable-class closure arguments for the recognizable class without separate proof
Confusing "MM halts on this particular ww" with "MM is a decider"Decider-ness is a property of the whole machine over all inputs, not a single runCheck the universally quantified halting condition, not one instance
Building an enumerator by running MM on s1,s2,…s_1, s_2, \ldots sequentially without interleavingIf MM loops on some early sj∉Ls_j \notin L, the whole enumeration stalls forever and later members of LL are never listedUse dovetailing: bound simulation steps per candidate and grow both the candidate pool and the step budget together

Pioneers & history

The vocabulary of deciders, recognizers, and the boundary between them emerged directly from foundational work on the limits of mechanical computation in the 1930s, tightened and formalized over the following decades into the standard hierarchy taught today.

Origins · 1 minAlan Mathison Turing and how this was discovered
AM
Alan Mathison Turing
1912–1954 · Formalized the Turing machine and proved the Halting Problem undecidable, giving the first rigorous separation between recognizable and decidable behavior

History
1936
— Turing introduces the a-machine and proves the Entscheidungsproblem unsolvable via a diagonal argument.
1936
— Alonzo Church independently proves an equivalent unsolvability result using the lambda calculus, establishing the Church–Turing framework.
1943–1944
— Emil Post develops the notion of recursively enumerable sets and the Post correspondence framework, sharpening the recognizer concept.
1953–1958
— Kleene and Post formalize the arithmetic and recursion-theoretic hierarchy, cementing "recursive" versus "recursively enumerable" as standard terms.
1965
onward — Complexity theory (Hartmanis, Stearns, and successors) refines "decidable" by adding resource bounds, giving rise to the time and space complexity classes built atop this foundation.

Where this matters

Every practical verification and analysis tool lives on one side of this line or straddles it deliberately. Type checkers for languages with decidable type systems (Hindley–Milner inference in ML-family languages) are deciders — they always terminate with a definite yes/no on whether a program type-checks. Model checkers for finite-state hardware and protocols exploit decidability of automaton-based questions (emptiness, equivalence) to give guaranteed answers about bounded systems. Static analyzers and linters for general-purpose languages, by contrast, typically implement recognizer-style or approximate procedures for properties like "does this code path ever execute," because the exact question is undecidable by reduction from the halting problem; industrial tools accept this and report either a sound over-approximation or "unknown" rather than looping forever. SAT and SMT solvers are deciders for their respective decidable theories, underlying modern compiler optimizations, program synthesis, and hardware verification pipelines. Theorem provers like Coq, Lean, and Isabelle formalize proofs whose checking is decidable (a fixed, finite proof object is verified in bounded time) even though finding the proof is not guaranteed to terminate — exactly the decider/recognizer split relocated to proof search versus proof checking. Understanding this boundary is also what lets engineers recognize, before writing code, that a proposed feature ("detect all infinite loops in user-submitted code and reject them") is asking for something no algorithm can deliver in full generality, redirecting effort toward sound approximations instead.

Ask the tutor: If a language and its complement are both Turing-recognizable, what can you conclude about the language itself, and why?

What exactly is the difference between "Turing-recognizable" and "recursively enumerable"?

Nothing mathematically — they are two names for the same class of languages, arising from two different historical traditions. "Turing-recognizable" (or "semidecidable") comes from automata-theoretic phrasing centered on machine behavior: accept, reject, or loop. "Recursively enumerable" comes from recursion theory, emphasizing that the language can be enumerated (listed) by an algorithm, possibly without ever halting overall. The Enumeration Theorem in this article proves these two descriptions coincide exactly, which is why textbooks use the terms interchangeably once the equivalence is established.

If a language is decidable, does that mean we know a fast algorithm for it?

No — decidability only guarantees the algorithm halts on every input, with absolutely no bound on how long that might take. A language can be decidable yet require exponential, or even non-elementary, time in the worst case; deciding is purely a qualitative, unbounded-resource guarantee. Questions of how fast a decidable language can be decided belong to time and space complexity theory, layered on top of decidability, not a substitute for it. A language being "decidable in principle" and "decidable efficiently in practice" are entirely separate claims, and conflating them is a common beginner mistake.

Can a language be neither decidable nor Turing-recognizable?

Yes, and in fact almost every language is like this. There are only countably many Turing machines (each has a finite string description), so there are only countably many recognizable languages, but there are uncountably many languages over any nonempty alphabet, by a diagonal cardinality argument on infinite binary strings representing membership. The complement of ATMA_{TM}, written ATM‾\overline{A_{TM}}, is a concrete example that is not Turing-recognizable at all, which becomes the entry point for the co-Turing-recognizable class studied alongside closure properties.

Is checking whether a given proof is correct the same kind of problem as finding a proof?

No, and this is exactly the decider/recognizer split in disguise. Checking a fixed, finite candidate proof against inference rules is decidable — you can always finish and report valid or invalid in bounded time relative to the proof's size. Searching for some proof of a given statement, however, is only semidecidable in general: if a proof exists you will eventually find it by systematic search, but if no proof exists, the search may never terminate and tell you so. This asymmetry is why automated theorem provers can confirm true statements but cannot, in general, certify unprovability.

Does every Turing-recognizable language have a "nice" enumerator that lists strings in sorted order?

Not necessarily in increasing length or lexicographic order without extra structure — the dovetailing enumerator described here may print strings out of natural order and with repeats, because it is driven by simulated acceptance times rather than string order. If you additionally require the enumerator to output strings in strictly increasing order without repetition, the resulting notion is sometimes called an enumerator in canonical order, and it turns out a language admits such an enumerator if and only if it is decidable — printing in guaranteed sorted order effectively forces you to know when you've seen everything up to a point, which is a decidability-strength guarantee.

How does this relate to the Halting Problem specifically?

The Halting Problem, usually phrased as HALTTM={⟨M,w⟩:M halts on w}HALT_{TM} = \{\langle M, w\rangle : M \text{ halts on } w\}, is Turing-recognizable by the same universal-simulation idea (run MM on ww, accept once it halts, loop if it never halts) but is provably undecidable by essentially the same diagonalization used for ATMA_{TM} in this article. In fact HALTTMHALT_{TM} and ATMA_{TM} are computably equivalent — a decider for one yields a decider for the other via straightforward reduction — so they serve as interchangeable canonical examples of the recognizable-but-undecidable class, and both anchor the broader theory of reductions used to prove other languages undecidable.

Why does this matter if I'm never going to write a Turing machine by hand?

Because the theorems here transfer, via the Church–Turing thesis, to any real programming language or computational model you will ever use. Whenever a static analysis tool, a build system, or a compiler claims to "detect" some general behavioral property of arbitrary code — infinite loops, unreachable code in full generality, exact resource usage — this theory tells you in advance whether a complete, always-terminating solution can exist at all. Recognizing the decidable/recognizable boundary lets engineers ask for the right kind of guarantee (a sound approximation, a bounded-input decision procedure) instead of chasing an algorithm that provably cannot exist.

Before this

Where this leads