4.6.19 · D3Theory of Computation

Worked examples — Reducibility — many-one reductions

4,458 words20 min readBack to topic

The scenario matrix

Every many-one reduction problem is really one of these cells. Below, each worked example is tagged with the cell it covers, so by the end every row is filled.

# Cell (the case class) What makes it tricky Covered by
C1 Both directions checked (YES→YES and NO→NO) forgetting the NO direction Ex 1
C2 Decidability transfer ( decidable ⇒ decidable) using + a decider correctly Ex 2
C3 Undecidability transfer ( undecidable ⇒ undecidable) picking the right known-hard Ex 3
C4 Degenerate targets: (everything) or (nothing) when does a reduction even exist? Ex 4
C5 Complement flip () same , sets swapped Ex 5
C6 Wrong-direction trap reducing new→known proves nothing Ex 6
C7 Recognizability (not decidability) transfer where target-decider may loop Ex 7
C8 Real-world word problem translating an informal task into Ex 8
C9 Exam twist: build that is total even when it looks like it must simulate avoid running inside Ex 9

Example 1 — both directions, a concrete finite reduction (C1)

Step 1. Define Why this step? We do not need to preserve at all — a many-one reduction only needs the YES/NO bit to survive. So we throw the input away and output a hand-picked string whose membership in matches membership in . The string has odd length (in ); the string has even length (not in ).

Step 2. Check the YES direction. If starts with then , and is odd, so . ✓ Why this step? This is — the "useful" half.

Step 3. Check the NO direction. If does not start with (starts with , or is empty) then , and is even, so . ✓ Why this step? This is the half everyone forgets. Without it a NO instance could sneak in as a YES image and the translator would lie — the reduction would wrongly accept a string not in .

Step 4. Conclude is total and computable: read the first symbol, output or . Always halts. Hence . Why this step? is only earned once we confirm is a computable total function — the definition demands halting on every input, so we must explicitly certify termination before claiming the reduction exists.

Verify (explicit case table):

starts with 1? () odd? () agree?
yes yes
no no
no no
yes yes
no no

All rows: column matches column. ✓


Example 2 — decidability transfer, used as a sanity check (C2)

Forecast: is trivially decidable ("does the string contain a 1?"). Will correctly turn "more 0s than 1s" into "contains a 1"?

Step 1. Compute by one scan. Why this step? Counting is a guaranteed-terminating mechanical operation, so stays total — a looping would destroy decidability transfer, so we must keep every step of terminating.

Step 2. If output ; else output . Why this step? We want the presence of a 1 in the output to track " says YES". When we append a ; when we output the single symbol (no anywhere).

Step 3. Both directions:

  • () contains a . ✓
  • () contains no . ✓

Step 4. Apply Theorem 1 (decidability transfer): decidable, , so decide by "compute , then check if it contains a ." Since is obviously decidable directly, this is a sanity check that the machinery is sound. Why this step? This is the payoff of the whole reduction: Theorem 1 lets us reuse 's decider through , so establishing was the point — the conclusion is not automatic until we invoke the transfer theorem by name. See also Turing-recognizable vs Decidable languages.

Verify (explicit case table):

more 0s? () has a 1? () agree?
yes yes
no no
no no
yes yes
no no

All rows agree. ✓


Example 3 — undecidability transfer (C3): the direction that does real work

Figure — Reducibility — many-one reductions

Figure — what you are looking at. The board shows the machine that the reduction writes down, split into its only two possible fates. Top box (chalk-blue): the case accepts . Because erases its own input and just runs on , once accepts the machine accepts no matter what was — so it "leaks" acceptance to every input and , which is non-empty. The blue arrow (labelled ) carries this to the right column: . Bottom box (chalk-pink): the case does not accept . Then the inner simulation never accepts, so accepts nothing, , and the pink arrow carries it to . The single design — "ignore , run on " — is exactly what makes 's language all-or-nothing: it is either every string or no string, and which of the two it is exactly mirrors whether accepts . That all-or-nothing property is the whole trick.

Step 1. Given , build the description of a new machine : "On any input : erase , run on ; if accepts , accept." Why this step? 's behaviour no longer depends on (top vs bottom box in the figure). So its language is either all strings (if accepts ) or empty (if does not) — never anything in between.

Step 2. Set . Why this step? only writes down the code of ; it never runs . Pure text editing ⇒ is total and computable (running inside could loop and would make partial — see Ex 9).

Step 3. Check the biconditional against (the " does not accept " language; recall means exactly ):

  • ( does not accept ) . ✓ (pink path)
  • ( accepts ) . ✓ (blue path)

Step 4. Apply Theorem 2 (undecidability transfer): so , and since is undecidable (complement of an undecidable language is undecidable), is undecidable. Hardness flowed along the arrow into . Why this step? Theorem 2 (contrapositive of decidability transfer) is what actually concludes the proof: a valid from a known-hard language forces the target hard. Without naming this theorem, Steps 1–3 are just a function — the undecidability result is only earned here.

Recall Why reduce

and not ? Because our maps "accepts" to "non-empty" — the YES side of lands on the NO side of . Flipping to realigns YES with YES. (You could equally state it as .) Compare Rice's Theorem, which gives this for free.

Verify (explicit two-world table):

world ? ? agree?
accepts no no
does not accept yes yes

Both worlds: source membership matches target membership. ✓


Example 4 — degenerate targets and (C4)

Step 1. Take . We need with . But is always true. So the biconditional forces to always be true, i.e. . Why this step? The right side of the biconditional is a constant; a biconditional with a constant right side forces the left side constant too.

Step 2. So holds iff . Symmetrically holds iff (since is always false, forcing ). Why this step? We must cover the nothing language too — the same constant-side argument runs with "false" instead of "true", so both degenerate targets are pinned down.

Step 3. The other direction: what reduces from a trivial ? If , pick any fixed and set (constant). Then (always) (true) — valid provided . If there's no such , so , matching Step 2. Why this step? Constant functions are the simplest totals; checking when they work isolates the only obstruction (an empty target has no image to hit).

Step 4. The four trivial-target cases, spelled out:

does exist? reason
yes any fixed member of
no has a YES string but has no member to send it to
yes any fixed non-member... none exist, but every so map anywhere; biconditional is "false true"? no — see note
yes any fixed non-member of (every string)

Careful reading of row 3: means every is a NO instance, so we need for all — impossible, since everything is in . So . Corrected: reduces only to targets that miss at least... in fact iff (we need a non-member to hit). The clean rule is below.

Verify (explicit truth check): treat each language as a pair (has-a-member?, has-a-nonmember?). , . Then needs to have a member; needs to have a non-member. Checked below.


Example 5 — the complement flip (C5)

Step 1. Recall . Negate both sides: , i.e. (using the complement definition ) . Why this step? A biconditional is logically identical to . No new function needed — the same translator works on the complemented sets.

Step 2. Verify concretely. (doesn't start with 1); , even, so . ✓ And ; , odd, . ✓ Why this step? A single algebraic negation can hide a slip; plugging in a YES and a NO instance confirms the complemented reduction really holds.

Step 3. Why we care: this is the engine for non-recognizability proofs. If and is not Turing-recognizable, then neither is (Theorem 4); complementing lets you carry results about around (see Turing-recognizable vs Decidable languages and Closure properties of language classes).

Verify (explicit case table, same , complemented sets):

? (not start 1) ? ( even) agree?
yes yes
no no
yes yes
no no

All rows agree. ✓


Example 6 — the wrong-direction trap (C6)

Step 1. State the transfer theorem precisely: Theorem 2 says and undecidable undecidable. The hardness lands on the right end of . Why this step? We must pin down which side inherits hardness before judging the argument.

Step 2. The student's reduction is . Matching this to Theorem 2, the "" is and the "" is . Theorem 2 would let us conclude something about the right side () — which we already knew is undecidable. It says nothing about the left side . Why this step? "Hardness flows along the arrow" — into the head, not the tail; matching the roles to the theorem exposes that the wanted conclusion is about the tail, which the theorem never constrains.

Step 3. The correct argument reverses the arrow: (the parent's Example 1: build that runs on , accepts if accepts and loops if rejects). Now, matching Theorem 2, "" = the known-hard and "" = the target , so undecidability flows into . Conclusion earned. ✓ Why this step? Fixing the direction re-aligns the known-hard language with the tail and the target with the head, which is the only configuration Theorem 2 lets us conclude from.

Verify (logic check): the inference " and undecidable undecidable" is valid; the inference " and undecidable undecidable" is not valid (a decidable can reduce to an undecidable ). Checked below.


Example 7 — recognizability, not decidability, transfer (C7)

Step 1. Let recognize : it accepts every , but on it may reject or loop forever (this is the definition of recognizer given at the top). Why this step? "Recognizable" is the weaker guarantee — halting only promised on YES instances, so we must track where looping can occur.

Step 2. Build : on input , compute (halts, total), then run on ; accept if accepts. Why this step? total ⇒ the first stage always finishes; the loop risk lives only inside , so we have located the single source of non-halting.

Step 3. Correctness: accepts accepts . So accepts exactly the strings of . Why this step? This chain is the reduction property threaded through the recognizer; it certifies that the set accepts is precisely , which is what "recognizes " means.

Step 4. But when , we have , and may loop — so may loop on those inputs. It never wrongly accepts, but it need not halt-and-reject. That is exactly a recognizer, not a decider. This is Theorem 3. Why this step? It explains the gap: the halting guarantee we lost in we cannot recover in , so decidability transfer downgrades to recognizability transfer.

Step 5. Contrapositive (Theorem 4): if is not recognizable, then is not recognizable — the standard tool for the " is not recognizable" family. Why this step? Flipping Theorem 3 gives the workhorse used to prove languages outside the recognizable class; it is the recognizability twin of Example 3's undecidability transfer. Connects to Decidability and the Halting Problem.

Verify (acceptance identity): on YES instances the accept-condition chain is a logical identity; it never accepts a NO instance. Checked below.


Example 8 — a real-world word problem (C8)

Step 1. Represent each config as a Turing machine that, on any input, simulates the config's rule engine and emits the name of a triggered step whenever the config would fire one. Why this step? We translate the informal predicate "triggers a step" into the formal "produces output," aligning with so a can even be stated.

Step 2. Set . This is text editing over the config, so is total and computable. Why this step? We never run the config inside (that could loop); we only compile it — same discipline as Example 3 and 9, which keeps total as demands.

Step 3. Both directions:

  • (no step ever triggers) never outputs . ✓
  • (some step can trigger) can output . ✓ Why this step? Both directions confirm the YES/NO bit survives, so the translation is a genuine reduction and not a one-sided illusion.

Step 4. Apply Theorem 2 (undecidability transfer): and symmetrically, so the two are equivalent; since the underlying emptiness question is undecidable (Example 3's ), no perfect linter exists. Why this step? The practical verdict ("no decider possible") is only licensed by Theorem 2 applied to the equivalence with — the reduction is the bridge, the transfer theorem is the conclusion. The engineering takeaway: ship a sound over-approximation (a recognizer), never claim a decider.

Verify (explicit two-world table):

world triggers a step? ? outputs? ? agree?
never triggers no yes no yes
can trigger yes no yes no

Both worlds: matches . ✓


Example 9 — the exam twist: keep total (C9)

Step 1. Consider the case loops on (neither accepts nor rejects). Then 's "run on " step never halts, so is undefined. Why this step? with looping is a genuine NO instance of we are obligated to map somewhere. If diverges there, is partial, not total — illegal.

Step 2. So the proposed is not a valid reduction. The fix is to build by editing 's description (as in Ex 3 and Ex 8): output the code of a machine that will do the simulation later, so itself always halts. Why this step? Delaying the simulation to run-time of the output machine keeps total while preserving the YES/NO correspondence — the definition of is only met by a total .

Step 3. General rule of thumb for exams: may compile but must not execute the machine it is reasoning about. Compilation halts; execution may not.

Recall One-line diagnosis test

Ask: "On the hardest NO instance — a looping — does my still halt?" If not, is partial and the reduction is invalid.

Verify (logic check): "run then branch" is total halts on all inputs, which is not guaranteed for ; the code-editing version is unconditionally total. Checked below.


Scenario matrix — filled

Recall Did we cover every cell?

Which example handles the " / " degenerate case? ::: Example 4. Which example is the one where hardness must flow into the target? ::: Examples 3 and 6. Which example shows a recognizer arises when the target-decider may loop? ::: Example 7. Which example fails only because becomes partial on a looping machine? ::: Example 9. Which example uses the same on complemented sets? ::: Example 5. Which example translates an informal engineering task into a reduction? ::: Example 8.

Related: Polynomial-time reductions and NP-completeness adds a time bound to the exact same -discipline you drilled here.