Encoding Turing Machines (Code Words)
Context: FIT2014_MOC · turns a Turing machine into a string over — the step that makes a machine into data and so makes the Universal Turing Machine possible Problem it solves: “a program is just another input” — encode any TM as a word, decode any word back into a table.
Quick Revision
- 🎯 Trigger: asked to encode/decode a TM, or to reason about the set of all TMs as a language ➔ go via the transition table, one row per instruction, each row fields.
- ⚠️ Key Constraint: is the set of well-shaped code words, not the set of TM codes — encoding no machine. Well-formed meaningful.
🧩 Fixed assumptions
- Input alphabet · tape alphabet (plus the blank ) · Start State · Accept State .
- Why fixed ➔ the encoding has no field for “which state is the start” or “how big is the alphabet”; those are conventions, so only the transitions need coding.
📝 Step 1 — the machine as a table
One row per transition, columns From · To · Read · Write · Move.
stateDiagram-v2 direction LR [*] --> s1 s1: 1 Start s2: 2 Accept s1 --> s3: a→R s1 --> s3: b→R s3 --> s4: b→R s4 --> s2: ∆→R
| From | To | Read | Write | Move |
|---|---|---|---|---|
| 1 | 3 | |||
| 1 | 3 | |||
| 3 | 4 | |||
| 4 | 2 |
Validity conditions to check
- A row with in the From column ➔ otherwise the machine can never leave the Start State.
- No row with in the From column ➔ the Accept State is a halting state; nothing leaves it.
- No two rows sharing the same From number and the same Read letter ➔ this is exactly determinism; a duplicate pair makes the “machine” ill-defined.
📝 Step 2 — the code
| Field | Item | Code |
|---|---|---|
| State number | (unary, -terminated) | |
| Letter | / / / | / / / |
| Direction | / | / |
- One instruction ➔ — two variable-length unary fields, then exactly 5 fixed letters.
- Whole machine ➔ concatenate the instruction codes with no separators and no spaces. The terminators alone make it parseable.
Worked encoding — the machine
| From | To | Read | Write | Move | Code |
|---|---|---|---|---|---|
| 1 | 3 | abaaabaabbb | |||
| 3 | 3 | aaabaaabaaaab | |||
| 3 | 4 | aaabaaaabababb | |||
| 4 | 4 | aaaabaaaabababb | |||
| 4 | 5 | aaaabaaaaabaaaaa | |||
| 5 | 6 | aaaaabaaaaaababaab | |||
| 6 | 6 | aaaaaabaaaaaabaaaab | |||
| 6 | 7 | aaaaaabaaaaaaabbabaa | |||
| 7 | 8 | aaaaaaabaaaaaaaabaabaa | |||
| 8 | 9 | aaaaaaaabaaaaaaaaabaabaa | |||
| 9 | 9 | aaaaaaaaabaaaaaaaaabaaaaa | |||
| 9 | 9 | aaaaaaaaabaaaaaaaaabababa | |||
| 9 | 1 | aaaaaaaaababbbbbb | |||
| 1 | 2 | abaabbabab |
- Row 1 dissected ➔ , , read , write , ⟹
ab|aaab|aa|bb|b. - The machine’s code word ➔ all fourteen rows run together as one long string with no breaks.
📝 Step 3 — the Code-Word Language
- CWL is regular ➔ it is defined by a regular expression: forces a state number , each terminates a unary field, is read/write/move.
- Every TM code lies in CWL — but not every word of CWL encodes a TM: the shape is right while the content may violate the validity conditions (no From- row, a From- row, two rows with the same From and Read).
Quantifier practice (the negation chain, cf. Quantifiers (Existential and Universal))
📝 Step 4 — decoding
While there are unread letters:
- Read and count the next clump of s, then the ➔ the unary From state number.
- Read and count the next clump of s, then the ➔ the unary To state number.
- Read the next two letters ➔ the letter to be Read.
- Read the next two letters ➔ the letter to be Written.
- Read the next letter ➔ the direction.
Worked decode — abaaabaaaababaaabababbaaabaaaabababbaaaabaabbabab
| Chunk | From | To | Read | Write | Move |
|---|---|---|---|---|---|
ab aaab aa aa b | 1 | 3 | |||
ab aaab ab ab b | 1 | 3 | |||
aaab aaaab ab ab b | 3 | 4 | |||
aaaab aab ba ba b | 4 | 2 |
Result: exactly the machine of Step 1 — it accepts , i.e. any first letter, then , then end of input.
✍️ Practice
Practice 1: encode the successor machine — and .
Reference solution
From To Read Write Move Fields Code 1 1 ab · ab · aa · aa · b ababaaaab1 2 ab · aab · ba · aa · b abaabbaaabConcatenated with no separator ⟹
ababaaaababaabbaaab.
- Key move: the To field is a full unary block with its own even when it repeats the From state —
abab…, notab….
Practice 2: is
aabaaabaaaabin CWL? Doesabaabaaaabencode a Turing machine?Reference solution
aabaaabaaaab➔ parse (From ), (To ), then 5 lettersaaaab. Shape matches ⟹ yes, in CWL. But From is the Accept State, violating a validity condition ⟹ it encodes no TM. This is the witness in the quantifier chain above.abaabaaaab➔ (From ), (To ), thenaaread ,aawrite ,bmove — one valid instruction , a From- row exists, no From- row, no duplicate pair ⟹ yes, it encodes the TM accepting every string beginning with .- Key move: membership in CWL is a regular-language question (shape only); “encodes a TM” additionally demands the three validity conditions.
⚠️ Common Mistakes
- 💡 CWL {codes of TMs} ➔ the containment is proper; saying “CWL is the set of Turing machine encodings” throws away the whole point of the quantifier slide.
- 💡 The state code is , the letter code is 2 letters ➔ mixing the unary state alphabet with the fixed-width letter alphabet is the standard decoding derailment. Count s only until the next .
- 💡 State is impossible ➔ requires at least one , so state numbers start at ; a bare never opens a field.
- 💡 No separators between instructions ➔ the concatenated code word has no delimiter; only the field lengths make it unambiguous — which is why the -letter tail is fixed-width.
- 💡 Duplicate (From, Read) breaks determinism ➔ a table can be well-shaped and still fail; check that condition explicitly before claiming a word encodes a machine.
🧠 Active Recall
CWL is regular. Why doesn't that make "does encode a Turing machine?" a regular-language question too?
Answer
- Short answer: CWL only checks syntax — a repeated pattern of two unary fields plus five letters, which a finite automaton can verify. Encoding a TM additionally requires global, cross-row conditions: some row has From , no row has From , and no two rows share a (From, Read) pair.
- Why: Cross-row comparison is unbounded matching ➔ the duplicate check compares state numbers that can be arbitrarily far apart and arbitrarily large, the same unbounded-counting obstruction that made non-regular in Proving a Language Non-Regular. Syntax is regular; consistency is not.
Why must the read/write/move fields be fixed-width when the state fields are not?
Answer
- Short answer: because the code word is concatenated without separators, every field must be self-delimiting. The state fields are self-delimiting by their terminator (unary s can’t contain one); the letter and direction fields can’t use that trick — their alphabet is — so they are delimited by fixed length instead ().
- Why: Two ways to be prefix-free ➔ terminator or fixed width. The scheme uses each where it fits, which is exactly what lets the decoding algorithm run as a single left-to-right pass with no backtracking — and therefore be implementable as a Turing machine, which is the UTM’s inner loop.