Building Turing Machines

Context: FIT2014_MOC · the exam hand skill of Turing Machines“design a TM accepting · the tape-level answer to the languages the pumping lemmas ruled out Problem it solves: turn a counting/matching language into a finite state diagram, using the tape itself as the counter.

Quick Revision

  • 🎯 Trigger: the language couples two or more unbounded counts ➔ mark one symbol of each group per pass, sweep back, repeat until one group runs out, then verify the others are exhausted too.
  • ⚠️ Key Constraint: marking must be reversible information, not destruction — write a distinct symbol ( for a consumed , for a consumed , for a pass boundary) so the sweep-left phase can still tell “already matched” from “not yet reached”.

📐 The marking recipe

  1. Handle first ➔ if the very first cell is , the input is empty; accept or reject immediately from State .
  2. Mark one symbol from the leftmost group and move right.
  3. Sweep right over already-marked symbols and unprocessed ones until the next group’s first unmarked symbol appears; mark it.
  4. Sweep left back to the boundary marker, land on the first unmarked symbol of group 1, and loop.
  5. Detect exhaustion ➔ when group 1 has no unmarked symbol left, leave the loop and verify the tail: sweep right over the remaining marks and require . Anything else ⟹ crash ⟹ reject.
  • ⚡ Why this works and a PDA’s stack wouldn’t for groups ➔ the head can revisit any cell, so the marks act as an arbitrary number of independent counters. This is exactly the capability needed and could not get from a stack.

🔧 Worked machine 1 —

stateDiagram-v2
    direction LR
    [*] --> s1
    s1: 1 Start
    s2: 2 Accept
    s1 --> s2: ∆→R
    s1 --> s3: a→A,R
    s3 --> s3: a→R
    s3 --> s3: B→R
    s3 --> s4: b→B,L
    s4 --> s4: B→L
    s4 --> s5: a→L
    s4 --> s6: A→R
    s5 --> s5: a→L
    s5 --> s1: A→R
    s6 --> s6: B→R
    s6 --> s2: ∆→R
StateJob
1on the leftmost unmarked — mark it , or accept on
3sweep right over s and s to the first unmarked ; mark it and turn left
4sweep left over s; an means more to match (), an means the s are exhausted ()
5sweep left over s to the marked block, then step right into State
6verification tail — sweep right over s; only accepts

Manual Execution Trace —

StepStatePosTapeReadWriteMoveNext
010aabb3
131Aabb3
232Aabb4
341AaBb5
450AaBb1
511AaBb3
632AABb3
733AABb4
842AABB4
941AABB6
1062AABB6
1163AABB6
1264AABB2 — Accept
  • Failure check ➔ after both s are marked the machine sits in State reading ; State has no rule ⟹ crash ⟹ reject.
  • Failure check ➔ State reaches the surplus unmarked ; State has no rule ⟹ crash ⟹ reject.

🔧 Worked machine 2 —

Not context-free (see Proving a Language Non-Context-Free) — yet a TM handles it, because a third counter costs nothing on a tape.

Strategy ➔ per pass, consume one from the front (mark it ), one from the middle (rewrite it as so it joins the right block), then delete two s from the right end — one for the rewritten and one for the trailing block. Every group shrinks in lockstep; the input is in iff they empty together.

FromToReadWriteMovePurpose
13mark the front as the pass boundary
33sweep right over remaining front s
34enter the block
44sweep right over the s
45hit the rear block — step back onto the last
56rewrite that as an
66run to the right end
67found the end — turn around
78delete the last
89delete the second-last
99sweep left home
99sweep left home
91back at the boundary — next pass
12nothing left ⟹ Accept

(Lecture 18 draws this same machine with where Lecture 19’s table writes — same machine, and is the symbol assumed by the tape alphabet in Encoding Turing Machines (Code Words).)

Manual Execution Trace —

StepStatePosTape beforeReadWriteMoveNext
010aba3
131#ba4
242#ba5
351#ba6
462#aa6
563#aa7
672#aa8
781#a9
890#1
911#2 — Accept

✍️ Practice

⚠️ Common Mistakes

  • 💡 Don’t erase what you consume ➔ overwrite rather than inside the matching loop; blanking a cell mid-tape destroys the left/right sweep landmarks. (Machine 2 only deletes at the right end, where nothing lies beyond.)
  • 💡 Verify the tail, don’t just exit the loop ➔ leaving the loop means “group 1 exhausted”; you still must sweep right and require , or slips through.
  • 💡 Handle explicitly is in both languages here; if State has no edge to State the empty string crashes and you lose the base case.
  • 💡 Every state needs every rule you rely on ➔ omitted (state, symbol) pairs are rejections by design in these machines; state which omissions are intentional, or a marker reads them as gaps.

🧠 Active Recall