CS52 - Spring 2017 - Class 23

Lecture notes

  • admin

  • which of these languages are regular?
       - language consisting of repetitions of either 01 or 10
          - Regular: (01|10)*
       - language of strings with an equal number of 0s and 1s
          - Not regular
       - language over a's and b's of alternating a's starting with an a, i.e. every other character in the string is an a
          - Regular: a((a|b)a)*|a((a|b)a)*(a|b)
       - language of all words that are palindromes, i.e. read the same forward and reversed
          - Not regular

  • turing machines
       - similar to DFAs/NFAs
          - they have states with transitions defined over the alphabet
          - they have a starting state and one or more final/accepting states
       - key differences:
          - Can *write* to the input tape as well as read
             - We have two alphabets
                - input alphabet: just like DFAs and NFAs
                - tape alphabet: includes the input alphabet PLUS possibly additional characters
          - Can move right *and* left on the input tape
          - The input tape is infinite!
             - it has "blank" characters everywhere beyond the input (in both directions)
          - Has both accept and reject states
             - if it ever enters either it *immediately* accepts/rejects

  • look at the 0n1n example (found in turing_examples)
       - transitions are labeled with three things:
          1) the input character read
          2) the output character to write
          3) which way to move the head (L, R or S)

       - basic idea of this example:
          - put Xs over the 0s. For each X you put on a 0, go find the next 1 and put a Y over it
          - if you get to the point where everything is X and Y (and no 0s or 1s) you're done!

       - slightly more detailed
          - read a 0: put an X down and move right
          - keep reading 0s and Ys to the right until you find a 1
          - put a Y on that 1 and move left
          - keep reading Ys and 0s until you find an X
          - move right
          - repeat
             - if you get to a point where the first character is a Y
             - read all the Ys and move right
             - make sure that you get a blank (and not a 1 or a 0). If so, we're done!

       - JFLAP doesn't have specific reject states for Turing machines
          - if it ever is in a state and there is no transition to take, it rejects
          - to make it clear (and to be consistent with other formulations) we will make one or more reject states without any outgoing transitions
             - if we want to reject, we will move to one of these states

  • look at 0n1n.v2 example
       - what does it do? how?
       - Instead of using X and Y, we just cover up the end 0's and 1's with blanks
       - Specifically:
          - Cover up the first 0 with a blank
          - Search for the 1s
          - Go to the end of the 1s
          - Cover the last 1 with a blank
          - Repeat

  • look at eq1s0s (found in turing_examples)

  • look at palindrome (found in turing_examples)

  • producing output
       - For this class, we'll just focus on accepting or rejecting strings

       - However, since Turing machines can write, they can also provide output

       - Look at simple_add (in turing_examples)
          - accepts strings of the form: number+number
             - where number is represented in *unary*
             - unary numbers:
                1 = 1
                2 = 11
                3 = 111
                4 = 1111
                5 = 11111
          - in addition to accepting strings of this form, it also calculates the result!
             - e.g. 11+111 should give us 11111
             - it gives the result back by putting it on the tape
                - in JFLAP we can run it in "transducer" mode which will also show the output
                - JFLAP outputs whatever from the current position (when the tape accepts) to the blank on the right

       - Look at fancy_add (in turing_examples)
          - accepts strings of the form number(+number)* where number is represented in unary
          - the output is the correct equation, e.g.
             - e.g., 111+1111 would output 111+1111=1111111

  • Church-Turing thesis
  • halting problem
       - Could we write a Turing machine that simulates the running of another Turing machine?
          - take as input two things:
             1) some representation of the Turing machine
             2) some input to run on the Turing machine input (i.e. the input Turing machine from 1)
          - would then "run" the Turing machine it was simulating on the input
          - this is called a "universal Turing machine"

       - Consider a TM H that does the following:
          H(M,w) =
             - accept if M finishes (accepts or rejects) with input w
             - reject if M never finishes with input w, i.e. runs forever

          - this is called the halting problem
             - this program comes up a lot in CS
                - you run your program
                - it doesn't finish
                - will it or is it stuck in an infinite loop?
                   - for particular types of problems we can definitely answer this problem
                   - can we in general, though?

          - Could we ever write this Turing machine?

  • To prove that we *cannot* we'll do a proof by contradiction
       - We assume that we can, i.e. that we could construct H above
       - And show that this results in a contradiction, meaning it couldn't be the case

       - Let's construct the following Turing machine
          D(M) =
             Run H(M, [M]) where [M] is the string representation of M
             - if it accepts (i.e. M(M) will finish), then loop infinitely
             - if it rejects (i.e. M(M) will loop forever), then stop

       - What happens when we run D(D)?
          - Run H(D, [D])
             - if it accepts, that implies that D(D) finishes
                - however, if H(D, [D]) accepts, then we know by the definition of D that D(D) loops infinitely
             - if it rejects, that implies that D(D) never finishes
                - however, if H(D, [D]) rejects, then we know that D(D) halts

       - We've reached a contradiction!
          - If H says D finishes, then it loops infinitely
          - If H says D loops, then it halts