Enumerators and Dovetailing
Context: FIT2014_MOC · the generative characterisation of r.e. — a machine that prints a language instead of testing it — and the reason the class is called “recursively enumerable” at all
Quick Revision
- 🎯 Objective: is r.e. is enumerated by some enumerator ➔ recogniser enumerator by dovetailing, enumerator recogniser by scan-and-compare.
- ⚠️ Key Constraint: naive “simulate all inputs in parallel” is not a machine — infinitely many simulations, finite time. The -then- nested schedule is the whole content of the direction.
📝 Core
An enumerator is a Turing machine that outputs a sequence of strings. is enumerated by iff .
- It never accepts or rejects ➔ an enumerator has no verdict states in play; it just keeps emitting. If the sequence is infinite it never halts, and that is not a defect.
- Finite languages ➔ the enumerator may stop once it has finished printing; the state it stops in is irrelevant — nothing is being decided.
- Order and repetition are free ➔ members may appear in any order, and repeats are allowed. Only the set of emitted strings is specified, so “enumerable” carries no sorting or de-duplication obligation.
- Contrast with a recogniser ➔ a recogniser is asked “is this in ?”; an enumerator is asked “name the members”. The theorem below says these are the same power.
🧮 Proof Blueprint — enumerable r.e.
Theorem. A language is recursively enumerable if and only if it is enumerated by some enumerator.
Strategy ➔ turn printing into testing by comparing against each printed string; turn testing into printing by dovetailing all inputs so no computation starves.
Derivation — ( ) enumerator r.e.
Let enumerate . Build :
accepts iff appears in ‘s output iff , so and is r.e.
- Note what happens for ➔ loops forever, which the r.e. definition permits. This direction cannot give a decider, and that is exactly the gap between r.e. and decidable.
Derivation — ( ) r.e. enumerator
Let and list in shortlex order . The hazard: simulating on all “in parallel” is infinitely many computations in finite time — not implementable. The fix is the schedule:
- Each round is finite ➔ round performs exactly (or fewer) simulation steps, so a TM implements it.
- Nothing starves ➔ if accepts after steps, that acceptance occurs by round , so is eventually printed.
- Nothing spurious ➔ only accepted strings are printed, so the emitted set is exactly .
- Key move: bound the work per round, then let the bound grow. A looping run on some consumes one step per round and can never block the others.
⚠️ Common Mistakes
- 💡 Running on to completion first ➔ if and loops on it, the enumerator prints nothing ever. Depth-first is fatal; dovetailing is the point.
- 💡 Demanding sorted or duplicate-free output ➔ neither is required, and imposing sorted order would be strictly stronger (that stronger version characterises decidable infinite languages, not r.e.).
- 💡 “It never halts, so it’s broken” ➔ non-termination is the normal behaviour for an infinite language. An enumerator is judged by its output stream, not its final state.
- 💡 Treating the enumerator as a decider ➔ seeing printed proves ; not seeing it printed yet proves nothing, because you cannot know whether it is still coming.
🧠 Active Recall
Why must the construction dovetail, rather than simply "simulate all inputs in parallel"?
Answer
- Short answer: a Turing machine performs one step at a time, so “in parallel” over an infinite input list is not a computation. The -then- schedule keeps every round finite ( steps) while giving each unboundedly many steps as grows.
- Why: Finite work per round, unbounded work in the limit ➔ acceptance of after steps surfaces by round , so every member is printed in finite time; meanwhile a non-halting run on some costs only one step per round and cannot block the rest. This is the same anti-starvation trick as the interleaved decider in Recursively Enumerable Languages.
Enumerators explain why r.e. languages are sometimes called "computable". Why is that name dangerous?
Answer
- Short answer: it is defensible — a machine computes (generates) every member — but “computable” is also used for decidable, and the two classes are provably different ( is r.e., not decidable).
- Why: Generating all members answering all membership questions ➔ the enumerator confirms by eventually printing , but supplies no finite signal for . Write r.e./Turing recognisable for this class and decidable/recursive for the other; the ambiguity is a mark-loss vector, not a stylistic choice.