=========================================================================== CSC 363 Lecture Summary for Week 2 Fall 2009 =========================================================================== -------- Variants -------- How do we know TMs are the "right" model? Consider different decisions we made when defining TMs and how they affect the outcome. How to compare different models? By their power to recognize languages: models that can recognize the same class of languages are equivalent. Example: Finite-State Automata (FSA) are NOT equivalent to TMs: they are strictly weaker, because every language recognized by a FSA can be recognized by a TM (following the same transition function, moving right at each step, and accepting/rejecting when it reads a blank symbol, depending on what state it's in), but TMs can recognize non-regular languages, such as { w#w : w (- {0,1}* } or { 0^n 1^n : n (- N }. Turing machines with "stay put" head movement: - Allow head to stay on same square during a transition. Formally, \delta : Q-{q_A,q_R} x \Gamma -> Q x \Gamma x {L,R,S}. - Equivalent to TM: simulate stay put move by moving right to "extra" state then left to correct state (need more than one extra state). - Details: Let M = (Q,\Sigma,\Gamma,q_1,q_A,q_R,\delta) be a regular TM. Then M' = M = (Q,\Sigma,\Gamma,q_1,q_A,q_R,\delta) is also a stay-put TM (one that just happens to never use a stay-put transition) whose behaviour is identical to that of M on every input string. In other words, regular TMs are just special cases of stay-put TMs, so stay-put TMs are at least as powerful as regular TMs. Now, let M = (Q,\Sigma,\Gamma,q_1,q_A,q_R,\delta) be a stay-put TM, where Q = {q_1,...,q_n,q_A,q_R}. Let M' by the regular TM defined as follows. \Sigma' = \Sigma, \Gamma' = \Gamma Q' = Q U {q'_1,...,q'_n,q'_A,q'_R} (i.e., copy each state of M) initial state = q_1 (same as for M) accepting state = q_A (same as for M) rejecting state = q_R (same as for M) \delta' is defined as follows: - for all q_i,q_j (- Q, a,b (- \Gamma such that \delta(q_i,a) = (q_j,b,L) or \delta(q_i,a) = (q_j,b,R), set \delta'(q,a) = \delta(q,a) (i.e., all transitions that move left or right stay the same); - for all q_i,q_j (- Q, a,b (- \Gamma such that \delta(q_i,a) = (q_j,b,S), set \delta'(q_i,a) = (q'_j,b,R) (i.e., all transitions that stay put become transitions that move right to one of the new states); - for all q'_j (- Q', a (- \Gamma, set \delta'(q'_j,a) = (q_j,a,L) (i.e., each new state simply moves one square left without changing the tape, and back to the corresponding original state). On every input string w (- \Sigma*, the behaviour of M' is the same as that of M: - the initial configuration of M (q_1 w) remains the same in M' - each of the following transitions of M remains the same in M': u q_i av -> ub q_j v uc q_i av -> u q_j cbv q_i av -> q_j bv when \delta(q_i,a) = (q_j,b,L) - each transition of M where the head stays put u q_i av -> u q_j bv becomes the following transitions in M' u q_i av -> ub q'_j v -> u q_j bv Hence, M' accepts/rejects/loops exactly when M accepts/rejects/loops. Turing machines with doubly infinite tape: - Similar to regular TMs except no leftmost square. Tape initially all blank except for input, and head starts on first symbol of input. - Equivalent to regular TM: (main idea only) . Doubly-infinite tape TMs can simulate regular TMs: use a few extra states at start of computation to write a special symbol to the left of input; then, during computation, remain in same state and move right whenever special symbol is read. . Regular TMs can simulate doubly-infinite tape TMs: start by placing special symbol on leftmost square (shift input one square right) and on first blank to the right of input; during computation, whenever "left edge" symbol is read, shift entire tape content one square right (insert blank), using "right edge" symbol to know when to stop, then return to leftmost blank square to continue computation; when "right edge" symbol is read, simply move it one square to the right (insert blank) then go back to newly inserted blank square and continue. . Formal details: see separate notes on website, as an extended example. Multi-tape Turing machines: - Allow more than 1 tape, each with independent head. Initially, all tapes blank except tape 1 that contains input. In one step, current state and symbols read on all tapes determine next state, symbols written and head movements for all tapes. Formally, \delta : Q-{q_A,q_R} x \Gamma^k -> Q x \Gamma^k x {L,R}^k. Note: Different from k independent machines running concurrently! In other words, this does *not* work by having tape 1 read/write/move, then tape 2 read/write/move, then... What happens on tape 1 (or tape 2, or...) is determined by the characters read from every other tape, all at once. - Equivalent to TM: keep track of contents of k tapes separated by special symbol, as well as head positions by using additional symbols (duplicates of tape alphabet), and use additional states to remember k symbols to read/write (since k is fixed). Simulating one step of multi-tape machine requires single-tape machine to scan over its entire tape twice: once to read k tapes, once to update k tapes. Other direction is trivial since 1 tape is just a special case of k tapes. - Details: see Theorem 3.13 on p.149. Non-deterministic Turing machines: - Allow transition function to specify more than one possible outcome for any state and symbol. Formally, \delta : Q-{q_A,q_R} x \Gamma -> P(Q x \Gamma x {L,R}), where P(A) is the "power set" of A, the set of all subsets of A, i.e., given non-halting state q and tape symbol a, d(q,a) gives a *set* of next states, symbols, and head movements (possibly empty). - For deterministic TMs, computation is "straight-line": initial config -> next config -> next config -> ... For non-deterministic TMs, think of initial config as root, and each config has finite number of next configs (possibly none), which yields a computation "tree". Convention: non-deterministic TM (NTM) "accepts" if there is at least one path in computation tree that leads to q_A (irrespective of what other paths do) -- intuitively, non-deterministic TMs carry out all computation paths "in parallel" and stop as soon as one path accepts. NTM "rejects" if *every* path leads to q_R. NTM "loops" if no path accepts and at least one path never halts -- treat "dead-ends" like rejections. - Note: NTMs cannot be implemented, unlike regular TMs! They are a purely theoretical model -- although recent work on quantum computing may yield physical implementations of something similar (but not identical). - Equivalent to TM! Idea: go through all paths in computation tree in breadth-first fashion (depth-first doesn't work because we could get stuck in an infinite loop even though another path accepts). - Details: One way to do this is in Theorem 3.16 on pp.150-151. - Alternative: Keep track of all possible current configurations on tape, separated by special symbol (initially, this is just the initial configuration). At each stage, replace each configuration with all possible next configurations -- possibly removing configurations that have rejected or stopped at a dead-end. Accept if any accepting configuration is encountered; reject if all configurations have rejected. Computing functions: - More "natural" notion of computing: TM works on input w and "produces" output f(w) (string left on tape when machine halts). Many possible formal definitions, depending on specific details (e.g., meaning of input rejected, or of machine looping). - See Exercise 2 for one possible formalization. Enumerators: - Similar to regular TM except: no input, two tapes, no accept/reject states (q_A/q_R), special "print" state (q_P) and "halt" state (q_H). Machine starts with both tapes blank and whenever it enters state q_P, string written on second tape is "printed" (technically, only the part of the string over \Sigma). Language is set of strings printed during computation (could be infinite if computation never halts). - Example: Enumerator with states {q_P,q_H}, tape alphabet {_,0,1}, initial state q_P, transition function \delta(q_P,a,a) = (q_P,a,L,0,R) for all a (- {_,0,1}. Language = {\epsilon, 0, 00, 000, ...} = L(0*). - Equivalent to TM: (Theorem 3.21 on p.135) . Given enumerator E for language A, construct TM M that recognizes A as follows: M = "On input w: 1. Run E; every time a string is "printed", compare it with w. 2. Accept if w is ever printed. Reject if E stops without printing w." If w (- A, then E eventually prints w so M accepts w. If w !(- A, then E never prints w so M rejects or loops on w. Hence, M recognizes A. . Given TM M that recognizes A, construct enumerator E for A as follows, where s_0,s_1,s_2,... is a complete list of all strings in \Sigma* (e.g., in lexicographic order): E = "Repeat for i = 0, 1, 2, 3, ... 1. Run M for i steps on each input string s_0,s_1,...,s_i. 2. Print every string that is accepted." If w (- A, then M accepts w so E will eventually print w (infinitely many times). If w !(- A, then M rejects or loops on w so E never prints w. Hence, E generates language A. Note: Why "for i steps"? Suppose M loops on s_k but accepts s_{k+1}; then E would enter infinite loop running M on s_k and never get to print s_{k+1}. Solution is the technique above, called "dovetailing": run multiple partial computations, stopping early to avoid infinite loops, but make sure to eventually continue all unfinished computations. There are other ways to achieve the same result, e.g., keep track of all ongoing computations on tape, separated by special symbol '#', and at each stage perform one more step of each computation as well as starting one more computation for the next string, removing any computation that has halted -- this avoids repeating computations and printing strings multiple times, but is slightly harder to describe precisely. Other models: - Register machines, Post correspondence systems, recursive functions, Conway's "Game of Life", etc. Given formal definitions of the different models, all have been shown equivalent to each other!