Computer Science / Software Engineering Notes Network

Theory of Computing

Matthew Barnes, Mathias Ritter

Books        4

Automata theory: Regular languages        5

Deterministic Finite Automata        5

Alphabets and strings        5

Languages        6

Deterministic finite automata (DFAs)        6

Product construction        9

Regular languages        10

Nondeterminism, subset construction and ϵ-moves        15

Nondeterminism        15

Subset construction        18

ϵ-moves        21

Regular expressions and Kleene’s theorem        23

Defining regular expressions        23

Atomic patterns        23

Compound patterns        24

Examples        24

Kleene’s theorem        24

Reg exp to εNFA        25

εNFA to reg exp        26

Limitations of regular languages        29

Pumping (🎃) Lemma for regular languages - contrapositive form        30

Automata theory: Context free languages        34

Pushdown Automata (PDA)        34

Transition relation        34

Configuration        35

Acceptance        35

By final state        36

By empty stack        36

Example PDA accepting palindromes        36

Context free grammars        38

Chomsky Normal Form        41

Greibach Normal Form        42

Removing epsilon and unit productions        42

Removing left-recursive productions        42

Converting between CFG, CNF and GNF        44

Converting a CFG to GNF        44

Converting a CFG to GNF        46

PDA and CFG conversions        49

CFG to PDA        49

PDA to CFG        51

Proving closure        58

Union        58

Concatenation        58

Kleene star        59

Intersection with regular languages        59

Limits of context-free languages        60

Pumping (🎃) Lemma for context-free languages - contrapositive form        63

Computability theory        67

Turing machines        67

Decidability        68

Recursive and R.E languages        68

Proof: Recursive Sets Closed under Complement        68

(Semi) Decidable properties        70

Universal Turing machines        71

Multiple tapes        71

Simulating Turing machines        71

Encoding Turing machines        71

Constructing a UTM        72

Halting problem        72

Proof by contradiction        72

Proof by diagonalisation        73

Decidable / Undecidable problems        74

Reductions        77

Properties of reductions        82

Rice’s theorem        83

Complexity theory        85

Big-O and Big-ϴ        86

Big-ϴ        86

Big-O        86

The class P        87

Feasible and infeasible problems        87

Decision problems        87

Definition        88

The PATH problem        89

The HAMPATH problem        90

Regular and context-free languages        90

The class NP        91

Non-deterministic Turing machine        91

Time complexity of Turing machines        92

Definition        95

The SAT problem        95

The HAMPATH problem        96

The TSP(D) problem        97

The 3COL problem        97

NP = P?        97

Presburger arithmetic        98

NP-Completeness        99

Polynomial time reduction        99

3COL to SAT        100

NP-hard        101

The Cook-Levin theorem        101

What is NP-completeness        101

Space complexity        101

Space complexity        101

PSPACE        103

NPSPACE        103

Savitch’s Theorem        104

EXPTIME        104

Relationships between complexity classes        104

PSPACE-hard        104

PSPACE-completeness        105

TL;DR        105

Automata theory: Regular languages        105

Automata theory: Context free languages        106

Computability theory        107

Complexity theory        108


Books


Automata theory: Regular languages

Deterministic Finite Automata

Alphabets and strings

Languages

Deterministic finite automata (DFAs)

Property

Symbol

Description

States

Q

Possible states that the automata can be in.

Alphabet

Σ

The alphabet that the transition names depend on.

Transitions

δ

A function that allows the automata to go from one state to the other by consuming a symbol.

This takes an element of Σ and a state from Q, and outputs the next state from Q to transition to.

Start state

s

The state that the automata starts at.

Final states (accept states)

F

Set of states at which, if the automata ends at them, it accepts the string that was entered into it.

Product construction

L1’s DFA state

L2’s DFA state

Product state

Transition

Step

0

0

(0,0)

None (yet)

0

1

1

(1,1)

a

1

2

1

(2,1)

b

2

3

2

(3,2)

a

3

Regular languages

The proper one

The illustrative one

Nondeterminism, subset construction and ϵ-moves

Nondeterminism

Step

Description

String so far

Illustration

1

So far, we haven’t gone anywhere.

The arrow that seems to come from nowhere indicates where we are initially, so we start at state ‘0’.

The smiley faces indicate different “paths” that the NFA is going through. A different coloured face is a different path, and their journey is displayed on the right, for example the green path has just started on 0, so a green ‘0’ is shown on the right.

2

Let’s try inputting ‘a’ and see where that leads us.

There’s only one transition we can go down if we input ‘a’, so no new simultaneous paths are created; we just stick with our original one.

The ‘a’ path just goes from 0 to 0, so our green path goes from ‘0’ to ‘0’.

3

Let’s try inputting a ‘b’ and see where that leads us.

There are two paths that ‘b’ can take us, from 0 to 0 or from 0 to 1. Here, our green path splits into two, one red and one blue.

The red one picks the path that stays on 0, and the blue path picks the one that goes to 1.

Right now, there exists a path that is on a final state: the blue one. Therefore, if we left the string as just , this NFA will accept that string.

4

Let’s try inputting another ‘b’ and see where that leads us.

The red and blue paths will both need to go through a ‘b’ transition. Since the blue path doesn’t have a blue transition where it is, it’ll ‘die’.

The red path needs to go down a ‘b’ transition, too. There are two transitions that the red path can go down, the one that goes from 0 to 0 and the one that goes from 0 to 1. Like last time, the red path splits into two different paths: a yellow path and purple path.

The yellow path takes the transition from 0 to 0, therefore the yellow path is still on 0.

The purple path takes the transition from 0 to 1, therefore the purple path is now on 1.

The NFA should accept this string too, since the purple path is on a final state.

Subset construction

Line in weird maths language

Line in plain English

Here, we create an NFA with the parameters , , ,  and .

Here, we create a DFA with the parameters , , ,  and . The parameters ,  and  are all dependent on the parameters for the NFA .

 is the set of all states, like . However,  is the powerset of , so it’s the set of all subsets of , so for example,

Because of this, the states in the DFA is all the subsets of , so you could have a state , a state  or even a state .

From before, we know that  is a transition function that defines how we go from one state to the other. Therefore, the inputs must be a state and a letter.

 is our state input. It’s actually a set, which makes sense, because the states in our DFA are all subsets of .

 is our letter input. Nothing strange here; it’s just a letter within the alphabet .

Don’t be too confused with the  that comes after. This simply means that, for each NFA state in our input , we’re going to apply the NFA transition function on that state with our input letter  and put the result in our state output.

More formally, is a bit like the sum in maths, except instead of adding all the terms, it unions all the terms.

Remember that the transition function also outputs a state. Since the states of our DFA are subsets of , the DFA transition function  also outputs a subset of .

For example, let’s say we input . The output will be . I’ll go over this in more detail in our example below, but the point is that this transition function just transitions all the states in  and unions them all together into one big output.

The set of final states  is a subset of .

For a DFA state to be a final state, it needs to contain an NFA state that is in .

For example, if 0 is a non-final state and if 1 is a final state in the NFA, then in the DFA, {0} would not be a final state, but {0,1} and {1} would be final states.

That’s basically what the left expression gets; a subset of  where all elements contain at least one final state from .

What we’re defining

How we did it

The value of  is , so we just need to  get the powerset of , or the ‘set of subsets’. This is:

This is just the same as before, nothing new here:

First of all, let’s create a transition table. This is a table where the input letters go on the top, the states go on the left, and you can look up transition results by looking up a state and a letter:

Now we work through this table from top to bottom. First of all, there’s the empty set state. You can’t go from any state from the empty set state; it’s practically a death state. So just input all empty set states here.

Now we’re moving onto the singleton states. For  and , just have a look at the NFA and see what states you’d end up at if you were at 0 and you took the paths labelled ‘a’. As you can see, you’d just end up back at 0, so we just input  there. As for  and , you can see that you can go to 0 or 1 using a ‘b’ path on 0, so we can input there. Continue this until we’re done with all the singleton states.

Now we’re faced with a state with more than one element! Remember the definition from before: we need to perform the transition function on all the elements, then union the results together. For example, on  and , we need to union the results of doing  and , and  and . Just above the  and  cell, we can see the results of those. We just need to union those together, by which I mean, union  and  together. When we do that, we get , so in this transition table, when you input  on the state , you get . Repeat this for all the states and inputs until you finish the table.

Once you’re done, that’s pretty much it! This transition table is your new transition function for your DFA.

This video goes into more detail and I strongly suggest it if you still struggle with this.

It’s pretty much the same as the original, but you encapsulate it in a set:

Get all the elements of :

{, , , }

Now get rid of the ones that do not have final states in them:

{, , , }

So therefore, your new  is:

{, }

ϵ-moves

Line in weird maths language

Line in plain English

We’re just defining an ϵNFA with these parameters.

We’re just defining an NFA with these parameters. These parameters will be based off of the parameters for .

When you input a state and a symbol, the output will be all the possible states it can reach to using epsilon-moves and that symbol.

The new set of final states is a superset of the old set of final states, meaning we still keep the final states the same, but we add more. We add the states that can epsilon-move towards a final state.

What we’re defining

How we did it

First, let’s create that transition table again. Just for example’s sake, I’m calling the initial state 0, the left-most state 1 and the final state 2:

0

1

2

If you were at state 0 and had an input ‘a’, what states could you get to? Well, you could go down the left epsilon-move to get to state 1 and spend the ‘a’ on going back to state 1. That’s pretty much it, so here, we’d input just state 1.

If you were at state 0 and had an input ‘b’, what states could you get to? You could go down the left epsilon-move and use ‘b’ to go to state 1 or use your ‘b’ to get to state 2. If you went down the right epsilon-move, you wouldn’t be able to use ‘b’, so you can ignore it. Seems like you can get to states 1 and 2, so we put that in the transition table.

We keep going like this until we fill out the transition table:

0

1

2

This transition table is our new transition function!

For this one, you could look at the final states in the graph, and work your way back up the epsilon-moves, looking for non-final states that can epsilon-move to the final state.

As you can see in the graph above, if you start at state 2 (the final state) and work your way up the epsilon-move, you’ll find yourself at state 0. Therefore, we can make state 0 a final state. However, you cannot go up to state 1 from state 2, so state 1 cannot be a new final state.

Obviously, we keep the old final states from the ϵNFA:

Regular expressions and Kleene’s theorem

Defining regular expressions

Atomic patterns

Pattern

Matched by …

… the single symbol from the alphabet:

… the empty string

… nothing

… any single symbol from the alphabet

… any string formed by the symbols in  (including the empty string), i.e. any string in

Compound patterns

Pattern

A String will match if ...

… it matches  or  

… it matches both  and  

… it can be broken down into two parts such that the first part matches  and the second part matches  

… it does not match

… it matches 0 or more repetitions of .

… it matches 1 or more repetitions of .

Examples

Kleene’s theorem

Reg exp to εNFA

εNFA to reg exp

  1. Base case
  2. Inductive step

Step

Weird maths language

Normal English + pretty pictures

Base case

Let

be all symbols such that

for

Firstly, our base case. The simplest case is going from the initial state to the final state without going through any intermediate states.

This is what we’re defining on the left here; from top to bottom, we’re defining

  1. If the initial state isn’t the same as the final state and there are transitions from initial state to final state
  2. If the initial state isn’t the same as the final state and there are no transitions from initial state to final state
  3. If the initial state is the final state and there are transitions from the initial state to the final state
  4. If the initial state is the final state and there are no transitions from the initial state to the final state

All those symbols are all transitions that go straight from the initial state to the final state.

Inductive step

First, we have a proposition (assumption). We propose that exists and works.

Then, we define a out of . Once we do that, we’ve defined our inductive step.

By doing this, we show that if there exists a regex from u to v through intermediate states X, there also exists a regex from u to v with intermediate states X + {q}, where ‘q’ is any other state in the automata.

This means we can keep adding on states from our base case until we’ve filled in all the states in our automata.

b + b(a+b)*(a+b) = b(a+b)*

Limitations of regular languages

Pumping (🎃) Lemma for regular languages - contrapositive form

  1. The demon chooses a number  such that .
  1. We choose a string  such that .
  1. The demon splits the  part of the string into  such that , i.e.  The whole string would be .
  1. We pick an  such that the string If this is the case we have proven that the language is not regular!

  1. You MUST say “Therefore L is not regular”, if you don’t, you will lose marks.

Example

Description

  1. The demon chooses  such that
  2. Now choose a string  and .
  • I’ll do it like , so and .
  • For every value of  I will get a specific string which is in the language of .
  • It is ok that I cannot get the empty string ( which is in the language) because I do not need to cover the whole language.
  1. The demon splits your  into a  such that
  • Now, we have to do the splitting in a general case.
  • Since  cannot be empty, then  and .
  • Since , then .
  1. We pick an  such that the string
  • Now for this example, choose
  • Then as the number of b’s will be bigger than the number of a’s, no matter what value k is.
  1. Therefore L is not regular

  1. The demon chooses  such that
  2. Now choose a string  and .
  • I’m going to choose , so
  1. The demon splits your  into a  such that
  • , as it cannot be empty we have .
  • The remaining part  because
  1. We pick an  such that the string
  • We pick
  • Then because the power we have got here is not going to be a factorial!
  • Let me prove why this is not going to be a factorial:
  •  is going to be some factorial .
  • The next higher factorial is going to be .
  • However, our power  is going to be in the middle of these two factorials: Therefore, it cannot be a factorial!
  • If you still have some doubts, try it out with the smallest k we could have, . Then choose the largest l we can choose, . So we have  which holds. For any choice of  the next higher factorial is going to grow even faster, therefore this will always hold.
  1. Therefore L is not regular

  1. The demon chooses  such that
  2. Now choose a string  and .
  • I’m going to choose  where  is going to be the next prime number . Since the number of primes is infinite this will always work, no matter how large  is.
  • Therefore,
  1. The demon splits your  into a  such that
  • The length of is going to be , so
  • Since  we have
  • That’s all info we need to continue our proof, you will see why in the next step.
  1. We pick an  such that the string
  • We will pick
  • I’m going to show that the length of  is not going to be equal to a prime number, therefore it is outside of the language.

  • , which is not going to be a prime number since we also have a factor  here but prime numbers should only be divisible by 1 or itself (p).
  • Therefore,
  1. Therefore L is not regular

and

  1. The demon chooses  such that
  2. Now choose a string  and .
  • I’m going to choose  where  and  
  • The demon splits your  into a  such that
  1. We pick an  such that the string
  • Pick
  • Now  and because we deleted at least one  by letting .  
  • Therefore
  1. Therefore L is not regular

Automata theory: Context free languages

Pushdown Automata (PDA)

Transition relation

Here, we are in the state , we will read the symbol , and we see  on top of the stack. We will then pop (remove)  off the stack, go to the next state  and push (add)  on the stack. We will start pushing with  and end with , such that we now have  on top of the stack.

Configuration

Configurations


when there exists such an element in


when there exists such an element in

Acceptance

By final state

By empty stack

Example PDA accepting palindromes

don’t change the stack contents.

   


The PDA has reached state 2 and will therefore accept.

   

 X at this point our computation dies because there is no transition we could take (d ≠ b). Therefore the PDA will reject.

Context free grammars

Language

Converting it to a grammar

  • Every string with the same number of a’s followed by the same number of b’s will be in the language.
  • We have shown that this language is not regular, however, it is context free as we can come up with a CFG for it.
  • The CFG is
  • We can produce 0 a’s and b’s, i.e. the empty string, by applying only the second production rule:
  • We can produce 1 a and 1 b by applying the first production rule once and the second production rule last:
  • We can produce 2 a’s and 2 b’s by applying the first production rule 2 times and the second production rule last:
  • Therefore, we can produce  a’s and  b’s by applying the first production rule  times and the second production rule last.
  • We achieve this through pumping  in the middle of the string every time we want to add an  and a .

L(G) is the set of all palindromes over the alphabet

L(G) is the set of all balanced parentheses

English, please

So you have a bunch of ‘a’s, then a bunch of ‘b’s, then another bunch of ‘a’s.

There needs to be twice as many ‘b’s as ‘a’s.

Examples:

ε

abb

abbbba

bbbbaa

  • Simplify:  
  • We know that  and  are just going to be repetitions of the letter
  • We let , then we can use those for the number of times we repeat the first  and the last . We put  and  in the corresponding exponents to denote these repetitions.
  • Simplify further:  
  • We use  and  to denote repetitions of the letters, so they can’t be negative. For example, what would mean? It doesn’t make sense, as we can’t repeat the letter  minus one times.
  • We split  into . No magic here, just exponent rules.
  • We can now split this into two grammars which we will then concatenate, because CFL are closed under concatenation.
  • One will be for the first half:
  • One will be for the second half:
  • Now, the final grammar will be the concatenation of the grammar for the left and the right part:

Chomsky Normal Form

Two non-terminals are derivable by one non-terminal

One terminal is derivable by one non-terminal

Language

CFG in Chomsky Normal Form

Greibach Normal Form

One terminal followed by  non-terminals is derivable by one non-terminal

Language

CFG in Greibach Normal Form

Removing epsilon and unit productions

Where  is the grammar  but without any epsilon or unit productions

Removing left-recursive productions

With left-recursion

Without left-recursion

Converting between CFG, CNF and GNF

Converting a CFG to CNF

  1. Remove all epsilon and unit productions like described above
  2. For all  add a new nonterminal  to our set of non-terminals
  1. In all productions, replace any terminal  with the the non-terminal
  1. Add productions  to our set of productions
  1. While there exists a production ... with , i.e. while there exists a production that derives more than 2 non-terminals and therefore cannot be in CNF

Step

Progress

Description

0

We haven’t done anything yet, I just wanted to show you the grammar first before we start converting it. It’s on the left.

1

Remove

Remove

Remove

Remove

In this step, we’re simply removing the -productions and the unit productions, as detailed in the previous section.

First, we remove the -production in A, but then it shifts it to B.

So then, we remove the -production in B. We’ve gotten rid of all the -productions, but now we’ve got to get rid of all the unit productions.

We get rid of the unit productions in B and S. For the one in B, we just replace it with A’s contents, and for the one in S, we just remove it, because is trivial.

2

In this step, we create a non-terminal for every terminal that exists. I call these and .

3

In this step, I convert all terminals into their respective non-terminals that I’ve defined in the last step. At first, this doesn’t make much sense, until the next step...

4

In this step, I set up productions such that the non-terminals can produce their respective terminals. Now the previous step makes sense!

5

In this step, I split up productions that have more than 2 non-terminals. I create non-terminals called so I don’t run out of names and so that I know that any non-terminal called  is just used for shortening.

Every red highlighted production is a production I need to shorten, and the blue highlighted production underneath is the shortened version.

Finish

This isn’t really a step. I’ve just compiled all the productions and put them into one place, so you can see the finished CNF result!

This grammar accepts the same language as the one at the start, except now it’s in a different form: Chomsky Normal Form.

Converting a CFG to GNF

This is not examinable according to Gennaro, but still worth reading to give further insight into context-free grammars.

  1. Convert the CFG into CNF.
  2. Re-order the rules such that the start rule is at the top, the next derivable rules are below and so on. In other words it should be the case that for every possible derivation we are going down in the list of rules we have, but never up.
  1. Replace all non-terminals with non-terminals of the form  where  is equal to the number of all non-terminals. Start with the first rule at the top and work down, otherwise we cannot benefit from the ordering we did in the last step.
  2. Check if for every production , it is true that  Check the rules in ascending order, i.e. start with the rule where . If we find one rule where this does not hold, we must modify this rule immediately before we continue to check other rules. We have to deal with the following two cases:
  1. Now, we are taking a closer look at every production starting with a non-terminal, i.e. every production which is not in GNF yet. For all of those rules it must hold that  where . Starting with the rule where the highest number and working in descending order, derive The result of deriving will be either a terminal symbol or two non-terminal symbols:

  1. Rename all non-terminals back to their old names.

  1. There might exist some rules which are unreachable from the start symbol. Remove those rules.

Step

Progress

Description

0

Here, we haven’t done anything yet!

This is the grammar we want to convert to GNF.

Right now, it’s not in any normal form.

1

In this step, we convert the grammar into CNF using the method described above that you should have read.

2

In this step, we reorder the steps so that, when going through productions, you go from the top and work your way down; you don’t go back up.

Sometimes, this isn’t always completely possible, for example the production uses , which is further up.

3

In this step, we replace all non-terminals with , where  is the position of the non-terminal from the top to the bottom.

4

----------------------------

----------------------------

----------------------------

In this step, we look for any productions  where .

There doesn’t actually exist any productions in the example where this is true, so I’ve created a sub-example to demonstrate this step. This won’t affect the example we’re working on. That’s why the text looks like that.

In the first block, we notice the production  where this condition is true. So we replace  in that production with it’s derivation.

Next, we notice that, in the production , , which means that we have left recursion. Therefore, we introduce another non-terminal to rectify this called .

Finally, on the last block, we notice that  in . Therefore, we convert both non-terminals into their derivations, which happen to be single terminals.

With this, we’ve completed this step.

5

----------------------------

----------------------------

----------------------------

In this step, we look at all the productions that are not in GNF, and we substitute productions until all the productions are in GNF. We start with the highest rule (which is the furthest down in our list) and work in descending order.

For example, in the first block,  is not in GNF. So we substitute ’s production into it, making the first part ‘a’.

Next,  is not in GNF, so we substitute the same thing in that, and we get .

After that, the only production that is not in GNF is . So we substitute  into that one, and we get .

There are no longer any more productions that are not in GNF. We’re now in Greibach normal form! But we’re not done yet; our non-terminal symbols are all . We need to change them back.

6

In this step, we’ve just renamed our non-terminal symbols back to normal.

7

In this step, we’re just getting rid of any productions that are unreachable / unused.

In this example, the productions for  and  are never used, so they are deleted.

PDA and CFG conversions

CFG to PDA

   where

One terminal followed by  non-terminals is derivable by one non-terminal

representing

is defined as

because

set of states

a singleton set containing the state

we will only have a single state in this PDA

input alphabet

terminal symbols of CFG

these are the symbols, produced by the grammar, which our PDA is going to scan

stack alphabet

non-terminal symbols of CFG

this is what we will push on/pop off the stack

transition relation

see below

see below

start state

the state

we only have a single state, so we don’t have much choice where to start.

S

initial stack symbol

the start production of CFG

we won’t have anything on the stack when we start scanning our string

final states

empty set

our PDA will accept by empty stack, therefore we don’t need any final states.

Grammar derivations

PDA transitions

PDA to CFG

  1. Prove that one-state PDAs can be converted to a CFG
  2. Prove that any PDA can be converted to a one-state PDA

  1. First, we will prove that one-state PDAs can be converted to a CFG.

Line in weird maths language

Line in plain English

This one’s nice and simple; I’m just defining a PDA with only one state, .

 is the alphabet that the PDA accepts

 is the set of symbols accepted onto the stack

 is the transition function

 is the initial stack symbol

Where it says  just means that there is no final state; this PDA will accept by empty stack.

Again, I’m just defining a grammar.

 is the set of non-terminal symbols (notice how it’s the same as the set of symbols accepted onto the PDA stack)

 is the set of terminal symbols (notice how it’s the same as the alphabet that the PDA accepts)

 is the set of productions

 is the start non-terminal (notice how it’s the same as the initial stack symbol in the PDA)

For every transition that exists in the PDA, there is also a production in the grammar that takes in the input stack symbol, and outputs the input symbol followed by all the stack symbols put into the stack.

  1. Now, we will prove that any PDA can be converted to a single-state PDA.

Multi-state PDA

Single-state PDA guesses

Description

We haven’t really done anything yet.

The initial stack symbol in a single-state PDA is always:

This is possible because there’s only one initial state and, like what we’ve defined before, only one final state.

We’ve inputted an ‘a’ as input, and now our single-state PDA has started guessing!

As you’ve (hopefully) read above, three guesses will be made in this situation; a was read from the stack and an ‘a’ input was read, and now the following three guesses have been established.

These three guesses go like this:

What if we go from state 0 to state 0 using ‘a’ on the stack, then go from state 0 to state 2 using floor?

What if we go from state 0 to state 1 using ‘a’ on the stack, then go from state 1 to state 2 using floor?

What if we go from state 0 to state 2 using ‘a’ on the stack, then go from state 2 to state 2 using floor?

I admit, some of these guesses are a little (really) dumb, but can you blame them? The stack doesn’t know what transitions exist; it doesn’t know that there isn’t a transition from state 0 to state 2. So what does it do? It guesses. It guesses every single combination so that if it gets something wrong, it can fall back on another guess. If all the guesses are wrong, then there’s no way the PDA can accept the string.

Wow! Look at all those guesses!

We’ve inputted another ‘a’ into our PDAs, and now, we’re exponentially making guesses. None of our guesses have died yet.

Because we’re pushing more than we’re popping, we’re making more guesses about what we want to do next; there are more possibilities now.

The transition here is slightly different, because we’re not using floor ⊥, but the concept is still the same.

What? You want to see how this transition is converted to it’s single-state PDA equivalent? Well, alright, but only because you asked so nicely:

Converts to:

-------------------------------------

Oh no! The guesses! They’re dying!

We’ve taken the transition:

...which converts into:

So, what the single-state PDA is doing is, it’s looking for a  on the stack. If it’s there, the guess is right, it just pops it off and doesn’t push anything else on. If it’s not there, the guess is wrong and the guess dies.

As you can see, 6 guesses died, leaving only 3 guesses from each coloured partition.

The top guesses show which ones survived and which ones died from the previous configuration (the gothy red and black ones are the ones that died).

The bottom 3 guesses shows the top 3 living guesses after their ‘b’s have been inputted and stacks have been popped.

-------------------------------------

We’ve taken the transition:

... which converts to:

So, like before, it looks for a on top of the stack. If it’s there, we live. If it’s not there, we die.

There’s only one guess here with a ! This guess has correctly predicted every move that the PDA has done. Congratulations, guess!

So now, we pop off and continue.

The existence of this guess is enough to accept the inputted string, right?

Almost. There’s one formality we need to take care of first: we need to move to state 2, the final state, to properly conclude this. Will this last-standing guess be able to conquer the final step by predicting the final transition from state 1 to state 2?

Spoilers: it does

It should be needless to say that this final transition looks for a to pop, and finds one within the final guess.

We can now accept by empty stack. This string is within the language of this PDA, and this single-state PDA is equivalent to this multi-state PDA!

Proving closure

Union

Where is the start symbol of the first grammar and  is the start symbol from the second grammar

Concatenation

Where is the start symbol of the first grammar and  is the start symbol from the second grammar

Kleene star

Where is the start symbol of the other grammar.

Intersection with regular languages


Limits of context-free languages

Pumping (🎃) Lemma for context-free languages - contrapositive form

  1. The demon chooses a number  such that .
  1. We choose a string  such that .
  1. The demon splits  into  such that , i.e. , and

  1. Case 1:  contains only one repeated letter: Either only ’s, or only ’s, or only ’s
  1. Case 2: either  or  (but not both) is a word that contains more than one kind of symbol.
  1. Case 3:  and  do not have any symbols in common.
  1. It cannot be the case that  contains all three letters because the length of  is at most .


  1. We pick an  such that the string If this is the case we have proven that the language is not context-free!
  1. Let
  2. Case 1:  contains only one repeated letter: then  is going to have either too many of ,  or
  3. Case 2: either  or  contains two different symbols: then  is going to have too many of two of ,  or .
  4. Case 3:  does not contain the same symbol as . then  is going to have too many of two of ,  or .

  1. You MUST say “Therefore L is not context-free”, if you don’t, you will lose marks.

Example

Solution

  1. The demon chooses a number  such that .
  2. We choose a string  such that .
  • Let’s choose .
  • We can see that .
  1. The demon splits  into  such that , i.e. , and
  • Let’s consider all the different cases:
  • Case 1:  contains only one repeated letter: Either only ’s, or only ’s, or only ’s
  • Case 2: either  or  (but not both) is a word that contains more than one kind of letter.
  • Case 3:  and  do not have any letters in common.
  1. We pick an  such that the string
  • pick , then
  • Case 1:
  1. Our resulting word will have one letter repeated more often than the other two letters.
  • Case 2
  1. Our resulting word is not going to be of the form a*b*c*.
  • Case 3:
  1. Our resulting word is going to have more of two of the letters but the number of occurrences of the third letter remains unchanged.
  1. Therefore, L is not context-free

  1. The demon chooses a number  such that .
  2. We choose a string  such that .
  • Let’s choose .
  • We can see that .
  1. The demon splits  into  such that , i.e. , and
  • Let’s consider all the different cases:
  • Case 1:  contains only one repeated letter: Either only ’s, or only ’s.
  • Case 2: either  or  (but not both) is a word that contains more than one kind of letter.
  • Case 3:  and  do not have any letters in common.
  1. We pick an  such that the string
  • Pick , then
  • Case 1:
  1. We are changing the number of either the ’s or the ’s. Therefore, the number of ’s won’t be eight times the number of ’s anymore.
  • Case 2
  1. Our resulting word is not going to be of the form a*b*a*.
  • Case 3:
  1. We are changing the number of either the first

’s and the ’s or the ’s and the second ’s. Therefore, the number of the first ’s won’t match with the number of the second ’s anymore.

  1. Therefore, L is not context-free

  1. The demon chooses a number  such that .
  2. We choose a string  such that .
  1. Let’s choose .
  2. We can see that .
  1. The demon splits  into  such that , i.e. , and
  1. This time we only have to consider one case as we only have one letter  in our window
  2. We know that we have at least 1 and at most  ’s in our window, which we are going to pump in the next step.
  1. We pick an  such that the string
  1. pick
  2.  where we define l to be
  3. Define the bounds of  to be
  1. This is because  and  when
  1. I know that because its length, , cannot be expressed as some number .
  2. This is because  is going to be strictly between and :  
  3. If you have doubts, check the bounds of  again and also try to plug in  and  (imagine you are the demon)
  1. Therefore, L is not context-free


Computability theory

Turing machines

  1. Informally

a

c

  1. Formally

Decidability

Recursive and R.E languages

Proof: Recursive Sets Closed under Complement

  1. Scans the tape to find a symbol with a hat in the "upper" section of the tape. Then, according to the transitions of M1, it performs M1’s move.
  2. If M1 accepts then N accepts;
  3. Scans the tape to find a symbol with a hat in the "lower" section of the tape. Then, according to the transitions of M2 , it performs M2’s move.
  4. If M2 accepts then N rejects;
  5. Go back to step 1

(Semi) Decidable properties

Universal Turing machines

Multiple tapes

Simulating Turing machines

Weird maths language

Plain English

There exists a TM  such that

Where  is an encoding of the TM ‘M’, followed by a ‘#’, followed by an encoding of ‘x’ in M’s input alphabet.

Like all Turing machines, they have a string input.

Universal Turing machines only accept strings that fit this pattern:

... which is an encoding of the TM ‘M’, a separating character (in this case #), and the encoding of the input string ‘x’.

First of all, the UTM checks if M#x is a valid encoding. If it isn’t, it’ll reject it straight away.

If the TM ‘M’ accepts ‘x’, then the UTM will accept M#x

If the TM ‘M’ rejects ‘x’, then the UTM will reject M#x

The UTM does this by simulating M on ‘x’. If it finds that M accepts, then the UTM will accept. If it finds that M rejects, then the UTM will reject.

Encoding Turing machines

Constructing a UTM

  1. looks at M’s current state and head position (tape 3);
  2. reads the tape contents at the correct position (tape 2);
  3. reads the relevant transition (tape 1);
  4. simulates transition, updating tape, state and head position;
  5. accepts if M accepts, rejects if M rejects.

Halting problem

Proof by contradiction

P on M:
   
call K on M#M
     if K says halt --> go into infinite loop
   
if K says doesn't halt --> halt

P(P) = ?

Proof by diagonalisation

0

1

00

01

10

11 ...

H

L

L

H

L

H

L

L

L

H

H

L

H

L

H

L

L

L

L

L

L

...

L

H

H

L

H

L

H

0

1

00

01

10

11 ...

H

L

L

H

L

H

L

L

L

H

H

L

H

L

H

L

L

L

L

L

L

...

L

H

H

L

H

L

H

0

1

00

01

10

11 ...

L

H

H

H

H

L

H

P on ():

        Call K on #

        According to the table K returns H

        Therefore we will go into an infinite loop

P on ():

        Call K on #

        According to the table K returns L

        Therefore we will halt

Decidable / Undecidable problems

If we had a TM K that solved the membership problem, we could create a TM N that would solve the Halting problem.

Reductions

State Entry Problem

(SEP)

Decide whether a TM M’ enters a given state q on input x

Assume that we already have a TM K that decides the SEP. Create a TM N which decides the HP using a reduction from the HP to the SEP.

N on inputs M and x (e.g. as an encoding M#x):

  1. Construct a new TM M’ from M
  1. Add a new state q which is not in M
  2. From all halting states add a new transition to q
  3. Make all halting states non-halting states
  1. Simulate K on inputs M', q, x (e.g. as an encoding M’#q#x)
  2. Accept if K accepts, reject if K rejects

Since we know that the HP is undecidable, the SEP must also be undecidable

Blank Tape Halting Problem (BTHP)

Decide whether a TM M’ halts on the blank tape (no input).

Decide whether a TM M’ halts on input epsilon.

Assume that we already have a TM K that decides the BTHP. Create a TM N which decides the HP using a reduction from the HP to the BTHP.

N on inputs M and x (e.g. as an encoding M#x):

  1. Construct a new TM M’ from M
  1. Ignore any input
  2. Write x on the blank tape and reset the tape head
  3. Execute M with x on the tape and return the result
  1. Simulate K on input M’
  2. Accept if K accepts, reject if K rejects

If you are confused about M’:

  • M’ is a special version of M
  • M’ has the same instructions as M, however, it has some instructions prepended to the other instructions
  • We will ignore any input given to M’
  • We need to write x on the tape and reset the tape head to the start
  • So all in all we have a TM M’ which has x hard coded in its instructions

Since we know that the HP is undecidable, the BTHP must also be undecidable

Emptiness Problem

(EP)

Semi-decide whether the language of a TM M’ is the empty set

Assume that we already have a TM K that semi-decides the EP. Create a TM N which semi-decides the LP (complement of HP) using a reduction from the LP to the EP.

N on inputs M and x (e.g. as an encoding M#x):

  1. Construct a new TM M’ from M
  1. Ignore any input
  2. Write x on the blank tape and reset the tape head
  3. Execute M with x on the tape
  4. Accept if the execution ends
  1. Simulate K on input M’
  2. Accept if K accepts

If you are confused about M’:

  • Similarly to the last example M’ will ignore any input and write x to the tape, so again our TM M’ comes with the x hard-coded
  • Now, if M loops on x, then M’ will also loop and never accept. Therefore, L(M’) is the empty set.
  • If M doesn’t loop on x, then M’ will accept and its language is clearly not equal to the empty set

Since we know that the LP is not semi-decidable, the EP cannot be semi-decidable as well.

Same

Language

Problem

(SLP)

Decide whether TMs M1 and M2 accept the same language.

Assume that we already have a TM K that decides the SLP. Create a TM N which decides the HP using a reduction from HP to SLP.

N on inputs M and x (e.g. as an encoding M#x):

  1. Construct a new TM M1:
  1. Simulate M on x
  2. If simulation halts accept (no matter what the input is)
  1. Construct a new TM M2:
  1. Accept (no matter what the input is)
  1. Simulate K on inputs M1 and M2
  2. Accept if K accepts, reject if K rejects

This works because

  • M2 always accepts everything, so its language is
  • M1 either accepts nothing or everything
  • If the simulation halts, i.e. if M halts on x, it will accept everything, so its language is
  • If the simulation doesn’t halt, then it will loop and run forever. Therefore its language is the empty set.
  • We can see that the language of M1 and M2 is the same if and only if M halts on x
  • So when we ask K if M1 and M2 have the same language it will accept if and only if M halts on x and reject otherwise
  • We can use this answer to solve the HP, which is a contradiction because we know that the HP is undecidable

Since we know that the HP is not decidable, the SLP must be undecidable as well.

Properties of reductions

Rice’s theorem


Complexity theory

Big-O and Big-ϴ

Big-ϴ

Big-O

The class P

Feasible and infeasible problems

Decision problems

The PATH problem

The HAMPATH problem

Regular and context-free languages

The class NP

Non-deterministic Turing machine

Time complexity of Turing machines

a

c

d

e

h

i

j

l

w

x

y

z

Proof from the tutorial that I don’t understand

My proof that I fully understand

   
 


For all , therefore  and

For all , therefore  and

The SAT problem

The HAMPATH problem

The TSP(D) problem

The 3COL problem

NP = P?

Presburger arithmetic

NP-Completeness

Polynomial time reduction

3COL to SAT

  1. For each vertex ‘x’, the expression:

(rx OR gx OR bx)

must be true (each vertex must be assigned a colour)

  1. For each vertex ‘x’, the expression:

( !(rx AND gx) AND !(rx AND bx) AND !(bx AND gx) )

must be true (each vertex may only have ONE colour)

  1. For each edge ‘x  y’, the expression:

!(rx AND ry) AND !(gx AND gy) AND !(bx AND by)

must be true (no two adjacent vertices should have the same colour)

NP-hard

The Cook-Levin theorem

What is NP-completeness

Space complexity

Space complexity

1

5

8

3

6

...

8

3

2

9

5

...

2

7

3

8

0

...

PSPACE

NPSPACE

Savitch’s Theorem

EXPTIME

Relationships between complexity classes

PSPACE-hard

PSPACE-completeness

TL;DR

Automata theory: Regular languages

Automata theory: Context free languages

Computability theory

Complexity theory