=========================================================================== CSC 363 Lecture Summary for Week 3 Winter 2008 =========================================================================== ANNOUNCEMENTS: - Next week's office hours changed to T10-12, W2-4, because of Undergraduate Project Showcase on Wed 2-4, BA1230 -- come and find out about undergraduate research projects from last year. - You can submit homework electronically through CDF's 'submit' command -- check the Homework page for details. - Faculty rule: 1-month deadline for remarking requests (after work returned). 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). - Equivalent to TMs as per Exercise 2. Enumerators: - No input but two tapes and a special state q_print (q_P for short). Machine starts with both tapes blank and whenever it enters state q_P, string written on second tape is "printed". Language is set of strings printed during computation (could be infinite if computation never halts). - Example: Enumerator with states {q_P,q_A,q_R}, tape alphabet {_,0,1}, initial state q_P, transition function \delta(q_P,a,a) = (q_P,a,L,0,R) for all a in tape alphabet. Language = { \E, 0, 00, 000, ... } = L(0*) ('\E' is empty string). - 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) -- such is list can easily be generated by a TM: E = "Repeat for i = 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 such 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. 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 T -> P(Q x T 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_accept (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_reject. NTM "loops" if no path accepts and at least one path never halts. - 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. - 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: 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. Accept if any accepting configuration is encountered; reject if all configurations are rejecting. Other models: - Register machines, Post correspondence systems, recursive functions, Conway's "Game of Life", etc.: all have unrestricted access to unlimited memory, and each step carries out only finite amount of work. - Given formal definitions of the different models, all have been shown equivalent to each other! ------------------------ The Church-Turing thesis ------------------------ "All reasonable models of computation are equivalent". Reasonable means has access to unlimited resources, can only carry out finite amount of work in one step. A "thesis" rather than a "theorem" because states something about informal notion of "reasonable model of computation". Any formal model chosen can be *proven* equivalent to others. In other words, any reasonable model of computation captures informal notion of "computation" precisely, i.e., there is a single, well-defined notion of "algorithm" independent of model used to define it. In particular, Turing machines are as powerful as any other model, and every pseudo-code algorithm you've ever seen has a TM implementation! Question: Is there some language that cannot be recognized by a TM? (We'll get back to this question a little later.) -------------------------- Turing machine conventions -------------------------- Turing machine algorithms described in high-level stages (i.e., without specifying details of head movement, states, or tape symbols), with indentation for blocks that represent loops. Each stage simple (and clear) enough that it is obvious it can be implemented on Turing machine -- if not, break it up into simpler stages. Description always starts with input, always a string. Use notation to represent string encoding of object O (e.g., represents string encoding of graph G). TM can easily decode such strings and reject automatically if input does not follow proper encoding, i.e., "On input , ..." really means "On input w, reject if w not in form ; otherwise, ...". Description must always include clear, explicit conditions for accepting and rejecting -- no condition for looping, because that's not an action explicitly taken by TM. ------------------------------------ Decidable and recognizable languages ------------------------------------ Example: A_DFA = { | B is a DFA that accepts input w } is decidable (A_DFA is "acceptance language for DFAs"). Main idea: A TM can check is valid encoding of DFA (using any reasonable convention), then use tape to keep track of current state of B and position on string w while simulating B's transitions one by one (going back and forth to check description of B). At the end, easy to check if last state is accepting or rejecting. Using conventions above: "On input : 1. Simulate B on w (use appropriate tape alphabet symbols to keep track of position of B on input w; use separate portion of tape to keep track of B's current state). 2. Accept if B accepts; reject if B rejects." Since a DFA always halts, TM above is a decider for A_DFA.