The PDA and the deterministic PDA are not equivalent in power
The NTM and TM are equivalent in power.
Theorem
\(A\) is \(T-recognizable\) iff some NTM recognizes \(A\)
It is trivial for an NTM to emulate a TM
Impose the restriction that sets mapped in \(\delta\) have cardinality =1
Theorem
\(A\) is \(T-recognizable\) iff some NTM recognizes \(A\)
We will show we can convert an NTM to a TM.
Insight
For any computation, we can view the set of possible computations as a tree.
Consider fast exponentiation by squares:
def exp_by_squaring(a, n):if n ==0:return1elif n ==1:return aelif n %2==0:return exp_by_squaring(a * a, n /2)else:return a * exp_by_squaring(a * a, (n -1) /2)
Insight
It would be much faster to ignore checks.
def exp(a, n, magic):return [1,a,exp(a * a, n /2),a * exp(a * a, (n -1) /2)][magic]
Insight
Imagine a growing tree
def exp(a, n, magic):return [1,a,[1,a,exp(a **4, n /4),a * exp(a **4, (n -1) /4)],a * exp(a * a, (n -1) /2)][magic]
Nondeterministic
Recurse
Recurse everywhere
Recurse recursively
It’s tree
Take one path
Multi-tape
Store state as separator
Create new tape on branch
Theorem 9
\(A\) is \(T-recognizable\) iff some NTM recognizes \(A\)
Proof.
Aside
There exists a formulation called a “Turing Enumerator”
---title: "Variants"---## Sketch::: {.nonincremental}- Turing Machines - Rehash - Multi-tape - Non-deterministic:::## Questions- Why use this model? - All models equivalent in power - Herding toward TM by people writing proofs - Seem to be easiest for most people# Multi-tape## Motivation- PDA had a stack, why can't TMs write two places!- We already have a place TMs can write!- I want my TM to have multiple tapes!- My device has multiple SSD/HDDs.## Minimal model- Take a TM- Add any number $n$ of "work tapes"- "work tapes" are intially blank.- TM can read write to any tape, - TM maintains its head position on all tapes.## Theorem- $A$ is $T-recognizable$ iff some multi-tape TM recognizes $A$- It is trivial for a multi-tape machine to emulate a single tape machine. - Leave all work tapes blank with no head movement.## Theorem- $A$ is $T-recognizable$ iff some multi-tape TM recognizes $A$- We will show we can convert multi-tape to single tape.## Statement- $S$ single tape, $M$ multi-tape- $S$ simulates $M$ by storing contents of multiple tapes in blocks.- $S$ introduces novel "tape break" symbol. - Like `EOF`- $S$ introduces a novel "head here" symbol## Statement- $S$ single tape, $M$ multi-tape- $S$ simulates $M$ by storing contents of multiple tapes in blocks.- $S$ introduces novel "tape break" symbol. - Like `EOF`- $S$ introduces a novel "head here" symbol## Graphically```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] t1 [label="a | a | b | b | _ | _ | _ "] t2 [label="1 | 0 | 1 | _ | _ | _ | _ "] t3 [label="c | c | c | a | _ | _ | _ "]}```## Single Tape```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] t1 [label="a | a | b | b | _ | _ | _ "] t2 [label="1 | 0 | 1 | _ | _ | _ | _ "] t3 [label="c | c | c | a | _ | _ | _ "] t [label="a | a | b | b | # | 1 | 0 | 1 | # | c | c | c | a | _"] t1-> t t2-> t t3-> t}```## Show heads```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] h1 h2 h3 t1 [label="a | a | <here> b | b | _ | _ | _ "] t2 [label="1 | <here> 0 | 1 | 1 | _ | _ | _ "] t3 [label="<here> c | c | c | a | _ | _ | _ "] t [label="a | a | <one> b | b | # | 1 | <two> 0 | 1 | 1 | # | <thr> c | c | c | a | _ "] h h1->t1:here; h2->t2:here; h3->t3:here; t1-> t:one t2-> t:two t3-> t:thr t:thr ->h [dir=back];}```## Extend Alphabet```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] h1 h2 h3 t1 [label="a | a | <here> b | b | _ | _ | _ "] t2 [label="1 | <here> 0 | 1 | 1 | _ | _ | _ "] t3 [label="<here> c | c | c | a | _ | _ | _ "] t [label="a | a | b̀ | b | # | 1 | 0̀ | 1 | 1 | # | c̀ | c | c | a | _ "] h h1->t1:here; h2->t2:here; h3->t3:here; t1-> t:one t2-> t:two t3-> t:thr t:thr ->h [dir=back];}```## In Practice- $S$ reads the whole tape before making any read/write.- $S$ maintains head location in every case- $S$ has to extend tape space by copying or correctly guessing work space needed. - This is *curiously similar* to how e.g. a Python dictionary is implemented.## Theorem 8::: {.nonincremental}- $A$ is $T-recognizable$ iff some multi-tape TM recognizes $A$:::*Proof.*```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] t [label="a | a | b̀ | b | # | 1 | 0̀ | 1 | 1 | # | c̀ | c | c | a | _ "] h t:thr ->h [dir=back];}```# Nondetermistic## Definition- A *Nondeterministic TM* (TM) is the same 7-tuple, just- No longer this transition relation: - $\delta: Q \times \Gamma \rightarrow Q \times \Gamma \times \{L, R\} \quad (L = \text{Left}, R = \text{Right})$- Utilize power set: - $\delta: Q \times \Gamma \rightarrow \mathcal{P} (Q \times \Gamma \times \{L, R\})$## Recall- The NFA and the DFA are equivalent in power- The PDA and the deterministic PDA are not equivalent in power- The NTM and TM **are** equivalent in power.## Theorem- $A$ is $T-recognizable$ iff some NTM recognizes $A$- It is trivial for an NTM to emulate a TM - Impose the restriction that sets mapped in $\delta$ have cardinality `=1`## Theorem- $A$ is $T-recognizable$ iff some NTM recognizes $A$- We will show we can convert an NTM to a TM.## Insight- For any computation, we can view the set of possible computations as a tree.- Consider fast exponentiation by squares::::{.fragment}```pydef exp_by_squaring(a, n):if n ==0:return1elif n ==1:return aelif n %2==0:return exp_by_squaring(a * a, n /2)else:return a * exp_by_squaring(a * a, (n -1) /2)```:::## Insight- It would be much faster to ignore checks.:::{.fragment}```pydef exp(a, n, magic):return [1,a,exp(a * a, n /2),a * exp(a * a, (n -1) /2)][magic]```:::## Insight- Imagine a growing tree:::{.fragment}```pydef exp(a, n, magic):return [1,a,[1,a,exp(a **4, n /4),a * exp(a **4, (n -1) /4)],a * exp(a * a, (n -1) /2)][magic]```:::## Nondeterministic```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] s [label="",shape=point] o [label="one"] oa [label="'a'"] oo [label="odd"] oe [label="even"] s -> o s -> oa s -> oo s -> oe}```## Recurse```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] s [label="",shape=point] o [label="one"] oa [label="'a'"] oo [label="odd"] oe [label="even"] t [label="one"] ta [label="'a'"] to [label="odd"] te [label="even"] s -> o s -> oa s -> oo s -> oe oo -> t oo -> ta oo -> to oo -> te}```## Recurse *everywhere*```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] s [label="",shape=point] o [label="one"] oa [label="'a'"] oo [label="odd"] oe [label="even"] t [label="one"] ta [label="'a'"] to [label="odd"] te [label="even"] ss [label="one"] sa [label="'a'"] so [label="odd"] se [label="even"] s -> o s -> oa s -> oo s -> oe oo -> t oo -> ta oo -> to oo -> te oe -> ss oe -> sa oe -> so oe -> se}```## Recurse *recursively*```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] s [label="",shape=point] o [label="one"] oa [label="'a'"] oo [label="odd"] oe [label="even"] t [label="one"] ta [label="'a'"] to [label="odd"] te [label="even"] ss [label="one"] sa [label="'a'"] so [label="odd"] se [label="even"] u [label="one"] ua [label="'a'"] uo [label="odd"] ue [label="even"] s -> o s -> oa s -> oo s -> oe oo -> t oo -> ta oo -> to oo -> te oe -> ss oe -> sa oe -> so oe -> se to -> u to -> ua to -> uo to -> ue}```## It's tree```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=point, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] s [label="",shape=point] o [label=""] oa [label=""] oo [label=""] oe [label=""] t [label=""] ta [label=""] to [label=""] te [label=""] ss [label=""] sa [label=""] so [label=""] se [label=""] u [label=""] ua [label=""] uo [label=""] ue [label=""] s -> o s -> oa s -> oo s -> oe oo -> t oo -> ta oo -> to oo -> te oe -> ss oe -> sa oe -> so oe -> se to -> u to -> ua to -> uo to -> ue}```## Take one path```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=point, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] s [label="",color="orange"] o [label=""] oa [label=""] oo [label="",color="orange"] oe [label=""] t [label=""] ta [label=""] to [label="",color="orange"] te [label=""] ss [label=""] sa [label=""] so [label=""] se [label=""] u [label=""] ua [label="",color="orange"] uo [label=""] ue [label=""] s -> o s -> oa s -> oo [color="orange"] s -> oe oo -> t oo -> ta oo -> to [color="orange"] oo -> te oe -> ss oe -> sa oe -> so oe -> se to -> u to -> ua [color="orange"] to -> uo to -> ue}```## Multi-tape```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] t1 [label="one "] t2 [label="'a' "] t3 [label="odd | # | one | `a` | odd | even | # "]}```## Store state as separator```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] t1 [label="one "] t2 [label="'a' "] t3 [label="odd | q_i | one | `a` | odd | even | q_j "]}```## Create new tape on branch```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] t1 [label="one "] t2 [label="'a' "] t3 [label="odd | q_i | one | `a` | <odd> odd | even | q_j "] t4 [label="<q_j> q_j | one | `a` | odd | even | q_k "] t3:odd -> t4:q_j}```## Theorem 9:::{.nonincremental}- $A$ is $T-recognizable$ iff some NTM recognizes $A$:::*Proof.*```{dot}// | echo: false// | height: 100pxdigraph g { rankdir=TD; bgcolor="#191919"; node [ fontcolor = "#ffffff", color = "#ffffff", shape=record, ] edge [ color = "#ffffff", fontcolor = "#ffffff" ] t1 [label="one "] t2 [label="'a' "] t3 [label="odd | q_i | one | `a` | <odd> odd | even | q_j "] t4 [label="<q_j> q_j | one | `a` | odd | even | q_k "] t3:odd -> t4:q_j}```## Aside- There exists a formulation called a "Turing Enumerator"- It is a generator rather than a recognizer.- Left as an exercise.<!-- https://youtu.be/TTArY7ojshU?si=Dd7Gcscog84Lsgg5 --># Stretch Break- [Home](https://cd-public.github.io/compute/)