WEBVTT

00:00:00.000 --> 00:00:04.910
[SQUEAKING]
[RUSTLING] [CLICKING]

00:00:25.270 --> 00:00:29.350
MICHAEL SIPSER: OK,
why don't we begin.

00:00:29.350 --> 00:00:30.250
Hi, everybody.

00:00:30.250 --> 00:00:36.040
Let's see how many we
got here, most of you.

00:00:36.040 --> 00:00:39.490
I'm sure the others will show
up, hopefully, soon enough.

00:00:39.490 --> 00:00:43.540
So welcome back.

00:00:43.540 --> 00:00:45.760
We have today's lecture 4.

00:00:45.760 --> 00:00:51.400
And let's just remember
what we've been doing.

00:00:51.400 --> 00:00:54.640
In the last few
lectures, we were

00:00:54.640 --> 00:01:01.180
exploring the regular languages,
as described by finite automata

00:01:01.180 --> 00:01:03.190
and regular expressions.

00:01:03.190 --> 00:01:06.310
We showed how to convert them
back and forth, those two

00:01:06.310 --> 00:01:08.780
models, to one another.

00:01:08.780 --> 00:01:12.100
And we also showed how to
prove certain languages

00:01:12.100 --> 00:01:13.090
are not regular.

00:01:13.090 --> 00:01:18.520
Now remember, finite automata
are a very weak model

00:01:18.520 --> 00:01:19.330
of computation.

00:01:19.330 --> 00:01:22.600
They only have a limited
memory, finite memory.

00:01:22.600 --> 00:01:26.290
And they still aren't
able to do certain things

00:01:26.290 --> 00:01:30.805
with their finite
memory, but they are--

00:01:33.670 --> 00:01:37.120
if you can pair them
with a general purpose

00:01:37.120 --> 00:01:39.790
computer, at least the
way we think about it,

00:01:39.790 --> 00:01:45.580
is their capabilities are
just extremely limited.

00:01:45.580 --> 00:01:49.960
And so we're going, to
over the next few lectures,

00:01:49.960 --> 00:01:52.390
explore some more
powerful models.

00:01:52.390 --> 00:01:55.932
We started doing that last
time, the context-free grammars.

00:01:55.932 --> 00:01:58.390
And as we'll see, there are
certain things that you can do.

00:01:58.390 --> 00:01:59.800
Well, I think we saw
that last time as well.

00:01:59.800 --> 00:02:02.620
There are some things you can do
with context-free grammars that

00:02:02.620 --> 00:02:05.800
you cannot do with
finite automata.

00:02:05.800 --> 00:02:09.169
But they still have their
limitations, as we'll see.

00:02:09.169 --> 00:02:13.720
So today what we're
going to do, we're

00:02:13.720 --> 00:02:15.820
going to continue
that discussion

00:02:15.820 --> 00:02:19.480
by looking at the definition of
context-free grammars in a more

00:02:19.480 --> 00:02:20.830
formal way.

00:02:20.830 --> 00:02:23.560
One of the things that
we do in this course

00:02:23.560 --> 00:02:27.520
is develop a practice
with formalism,

00:02:27.520 --> 00:02:30.460
so that's going to be
in the spirit of that.

00:02:30.460 --> 00:02:33.700
We also are going to look at
their associated languages,

00:02:33.700 --> 00:02:35.410
called the
context-free languages.

00:02:35.410 --> 00:02:37.210
So they are going to
be the counterpart

00:02:37.210 --> 00:02:40.270
for context-free grammars of
what the regular languages are

00:02:40.270 --> 00:02:43.780
for the finite automata
regular expressions.

00:02:43.780 --> 00:02:48.700
And then we're going to look at
an automaton-based model, which

00:02:48.700 --> 00:02:53.620
is the counterpart to the
grammars called the pushdown

00:02:53.620 --> 00:02:54.340
automata.

00:02:54.340 --> 00:02:57.830
And we'll see that those
are equivalent in power.

00:02:57.830 --> 00:03:01.030
And finally-- well,
and as part of that,

00:03:01.030 --> 00:03:03.700
we will show how to convert
the context-free grammars

00:03:03.700 --> 00:03:05.500
to the pushdown automata.

00:03:05.500 --> 00:03:07.880
And that's what we're
going to do today.

00:03:07.880 --> 00:03:10.990
So we're going to move
on then and return

00:03:10.990 --> 00:03:14.290
to our topic of
context-free grammars

00:03:14.290 --> 00:03:15.760
that we began last time.

00:03:15.760 --> 00:03:18.520
And just to refresh
your memory, so here

00:03:18.520 --> 00:03:20.650
was that example of a
context-free grammar

00:03:20.650 --> 00:03:22.810
that we gave last time.

00:03:22.810 --> 00:03:27.790
And it has-- the way
we're going to be writing

00:03:27.790 --> 00:03:31.570
context-free grammars is using
a bit of a shorthand, which

00:03:31.570 --> 00:03:32.620
looks like this.

00:03:32.620 --> 00:03:35.800
When you have
multiple rules that

00:03:35.800 --> 00:03:39.710
have the same variable
on the left-hand side,

00:03:39.710 --> 00:03:42.760
you can combine
them into one line.

00:03:42.760 --> 00:03:47.410
So these two rules over here,
S goes to 0S1 and S goes to R,

00:03:47.410 --> 00:03:51.370
can be written in one line as
a little bit more compact way,

00:03:51.370 --> 00:03:55.990
this is standard, as
S goes to 0S1 or R.

00:03:55.990 --> 00:03:57.500
That's the way you
would read this.

00:03:57.500 --> 00:04:02.600
This is really two rules
but written on one line.

00:04:02.600 --> 00:04:07.400
So as you recall from last
time, a context-free grammar

00:04:07.400 --> 00:04:10.160
has terminals,
variables, and rules.

00:04:10.160 --> 00:04:13.100
Those are the parts
that we speak of,

00:04:13.100 --> 00:04:15.270
as well as one of
the variables being

00:04:15.270 --> 00:04:17.954
designated as a
starting variable, which

00:04:17.954 --> 00:04:19.079
gets the whole thing going.

00:04:19.079 --> 00:04:23.420
So I'll remind you about
how the computation goes.

00:04:23.420 --> 00:04:25.970
So the variables
are the symbols that

00:04:25.970 --> 00:04:28.960
appear in the left-hand
side of the rules.

00:04:28.960 --> 00:04:31.480
The terminals are
the other symbols

00:04:31.480 --> 00:04:33.910
that appear in the grammar.

00:04:33.910 --> 00:04:43.090
And the-- we take
the grammar, and we

00:04:43.090 --> 00:04:47.410
use it to generate strings,
according to a certain system.

00:04:47.410 --> 00:04:52.300
And the system is that you start
up by writing down the starting

00:04:52.300 --> 00:04:53.020
variable.

00:04:53.020 --> 00:04:57.007
And then once you've
written down that variable,

00:04:57.007 --> 00:04:58.840
or whatever variables
you have written down,

00:04:58.840 --> 00:05:00.640
you're allowed to
substitute them

00:05:00.640 --> 00:05:03.700
according to the
rules, the substitution

00:05:03.700 --> 00:05:05.710
rules, that are in the grammar.

00:05:05.710 --> 00:05:08.170
So you can keep on
replacing the variables

00:05:08.170 --> 00:05:11.120
that you have with the
corresponding right-hand sides.

00:05:11.120 --> 00:05:14.470
And then you do that
over and over again

00:05:14.470 --> 00:05:16.420
until you don't have
any variables left,

00:05:16.420 --> 00:05:18.340
only terminal symbols remain.

00:05:18.340 --> 00:05:22.778
And at that point, you have
generated a string that's

00:05:22.778 --> 00:05:24.070
in the language of the grammar.

00:05:26.610 --> 00:05:31.410
So the grammar's
language is going

00:05:31.410 --> 00:05:37.320
to be a language over strings
whose alphabet are the terminal

00:05:37.320 --> 00:05:38.380
symbols.

00:05:38.380 --> 00:05:40.620
So the terminal symbols
in a certain sense

00:05:40.620 --> 00:05:44.490
play the same role as
the input alphabet,

00:05:44.490 --> 00:05:47.700
say, for the finite automata.

00:05:47.700 --> 00:05:52.410
The variables are
internal-working symbols

00:05:52.410 --> 00:05:53.190
for the grammar.

00:05:53.190 --> 00:05:59.940
The terminals are the symbols of
which the language is written.

00:05:59.940 --> 00:06:01.610
We'll make that more
precise in a minute

00:06:01.610 --> 00:06:03.780
when I give the
formal definition.

00:06:03.780 --> 00:06:05.660
So the result is the
generated string.

00:06:05.660 --> 00:06:07.820
And the language of the
grammar is the language

00:06:07.820 --> 00:06:12.470
of all generated strings that
you can get using that grammar.

00:06:12.470 --> 00:06:15.740
And the important thing is
that we call that language

00:06:15.740 --> 00:06:19.620
a context-free language.

00:06:19.620 --> 00:06:22.470
So that's like
what we get from--

00:06:22.470 --> 00:06:25.440
that's the analogous thing
to the regular languages,

00:06:25.440 --> 00:06:27.930
but here we call them
context-free languages,

00:06:27.930 --> 00:06:30.270
the things that you can get
from a context-free grammar.

00:06:30.270 --> 00:06:35.020
Again, just a quick recap of
that example we did last time.

00:06:35.020 --> 00:06:39.580
So you start out by
writing the start variable.

00:06:39.580 --> 00:06:43.110
And then I'm going to give
you two views of that,

00:06:43.110 --> 00:06:45.630
either in terms of the tree of
substitutions, which we call

00:06:45.630 --> 00:06:48.510
the parse tree, or in terms
of the resulting string

00:06:48.510 --> 00:06:50.190
as you do the substitutions.

00:06:50.190 --> 00:06:54.420
So here is the parse tree,
here is the resulting strings,

00:06:54.420 --> 00:06:57.610
here are the substitutions
that you make.

00:06:57.610 --> 00:07:03.220
And now we have R coming
from S, and we have 00R11.

00:07:03.220 --> 00:07:08.920
And now we have R in turn
becomes an empty string.

00:07:08.920 --> 00:07:13.020
And then the string that
we generated is 0011.

00:07:13.020 --> 00:07:16.490
That's in the language
of the grammar.

00:07:16.490 --> 00:07:19.980
And now if you play
with this a little bit,

00:07:19.980 --> 00:07:21.800
you'll see that the
language of the grammar

00:07:21.800 --> 00:07:26.090
is all strings that look
like runs of zeros followed

00:07:26.090 --> 00:07:26.885
by runs of ones.

00:07:29.410 --> 00:07:32.660
So is that clear?

00:07:32.660 --> 00:07:34.610
I think we're going to have a--

00:07:34.610 --> 00:07:39.310
I think the next slide is
going to have a check-in,

00:07:39.310 --> 00:07:43.360
and so hopefully that'll
get us all together

00:07:43.360 --> 00:07:44.830
on the same page with this.

00:07:44.830 --> 00:07:46.300
Anyway.

00:07:46.300 --> 00:07:48.910
So here's our formal
definition anyway.

00:07:48.910 --> 00:07:53.050
We have a context-free
grammar is a 4-tuple.

00:07:53.050 --> 00:07:55.480
There are four parts to
a context-free grammar.

00:07:55.480 --> 00:07:58.900
These are the parts we've
already been discussing,

00:07:58.900 --> 00:08:03.070
the variables, the terminal
symbols, the rules.

00:08:03.070 --> 00:08:04.570
The rules are always
that they form

00:08:04.570 --> 00:08:09.040
a variable followed
with an arrow

00:08:09.040 --> 00:08:12.070
to a string of
variables and terminals.

00:08:12.070 --> 00:08:13.710
That's the way we
just write that down.

00:08:13.710 --> 00:08:16.180
So this is the form of
the rule, and then we

00:08:16.180 --> 00:08:17.620
have the special start variable.

00:08:17.620 --> 00:08:21.190
And we all wrap that up into
a package, this 4-tuple.

00:08:21.190 --> 00:08:23.260
That's what the
context-free grammar is.

00:08:26.430 --> 00:08:29.625
Now we have here--

00:08:29.625 --> 00:08:32.470
and now, maybe a
little bit overkill,

00:08:32.470 --> 00:08:37.620
but let's talk about, formally
speaking, the way the grammar

00:08:37.620 --> 00:08:42.840
actually processes
and produces strings.

00:08:42.840 --> 00:08:45.480
So we're going to write--

00:08:45.480 --> 00:08:47.700
the standard
notation for this is

00:08:47.700 --> 00:08:52.910
that if you have two strings
of variables and terminals--

00:08:52.910 --> 00:08:55.490
so imagine you have an
intermediate string that

00:08:55.490 --> 00:09:00.350
you've generated in
the grammar so far,

00:09:00.350 --> 00:09:04.230
which might be like 00S11
from the previous line,

00:09:04.230 --> 00:09:07.100
so that's an intermediate
string that is so far what

00:09:07.100 --> 00:09:11.330
you've generated, you're
going to say maybe that's u,

00:09:11.330 --> 00:09:15.270
and v might be the
next line down.

00:09:15.270 --> 00:09:18.770
So that means we're going
to write u arrow v--

00:09:18.770 --> 00:09:21.650
and that arrow is--

00:09:21.650 --> 00:09:23.810
the word we're going
to use is "yields."

00:09:23.810 --> 00:09:28.910
We'll say u yields v if
it can go from u to v just

00:09:28.910 --> 00:09:30.320
with one substitution step.

00:09:33.260 --> 00:09:37.310
And then we'll write u yields
v in some number of steps--

00:09:37.310 --> 00:09:40.910
or actually, we say
u derives v if it

00:09:40.910 --> 00:09:43.610
can go to u to v with some
number of substitutions instead

00:09:43.610 --> 00:09:44.470
of just one.

00:09:44.470 --> 00:09:49.010
And that's used with the yields
arrow with the star above it.

00:09:49.010 --> 00:09:52.130
It means "some number of."

00:09:52.130 --> 00:09:54.590
Another way of writing
that is you can say,

00:09:54.590 --> 00:09:58.760
u goes to v if there are
a bunch of one-step moves

00:09:58.760 --> 00:10:01.460
that you can make which
take you from u to v.

00:10:01.460 --> 00:10:05.830
And that whole sequence is
called a derivation of v

00:10:05.830 --> 00:10:08.590
from u.

00:10:08.590 --> 00:10:10.090
That's a sequence
of steps that you

00:10:10.090 --> 00:10:14.090
go through doing these
substitutions one by one

00:10:14.090 --> 00:10:16.190
to take you from
u to v, according

00:10:16.190 --> 00:10:18.080
to the rules of the grammar.

00:10:18.080 --> 00:10:22.100
And lastly, if u is
a starting variable,

00:10:22.100 --> 00:10:26.450
then we call that sequence
just the derivation of v. It

00:10:26.450 --> 00:10:28.610
could be the derivation
from the start variable,

00:10:28.610 --> 00:10:31.640
but that's the assumed
if you don't say it's

00:10:31.640 --> 00:10:33.020
a derivation from anything.

00:10:33.020 --> 00:10:35.180
The derivation of
v in the grammar

00:10:35.180 --> 00:10:37.440
is the derivation of v
from the start variable.

00:10:37.440 --> 00:10:39.290
It's just the sequence
of substitutions

00:10:39.290 --> 00:10:45.590
that you make, kind of what
I think you would expect.

00:10:45.590 --> 00:10:47.900
Now, the language of
the grammar is the set

00:10:47.900 --> 00:10:53.930
of all strings of
terminal symbols

00:10:53.930 --> 00:10:58.015
that you can get from starting
at the starting variable

00:10:58.015 --> 00:10:58.640
of the grammar.

00:11:01.410 --> 00:11:03.160
And that's called a
context-free language,

00:11:03.160 --> 00:11:04.320
as I mentioned before.

00:11:04.320 --> 00:11:06.090
So it's a context-free language.

00:11:06.090 --> 00:11:10.740
It's the language of the
grammar for some grammar.

00:11:10.740 --> 00:11:13.560
So let's have a little check in
here, again, nothing too hard,

00:11:13.560 --> 00:11:15.060
nothing to get
worried about anyway.

00:11:15.060 --> 00:11:17.230
We're not counting correct here.

00:11:17.230 --> 00:11:23.910
So let's just see, I'm going
to give you two things that

00:11:23.910 --> 00:11:26.060
look like grammars.

00:11:26.060 --> 00:11:28.550
Which of them are
actually grammars?

00:11:28.550 --> 00:11:32.820
And let me just pull
that poll up here.

00:11:32.820 --> 00:11:36.720
So which of these are
valid grammars here?

00:11:36.720 --> 00:11:37.540
Are they both?

00:11:37.540 --> 00:11:38.040
Neither?

00:11:40.910 --> 00:11:43.712
I mean, you could kind of
make an argument either way

00:11:43.712 --> 00:11:44.420
for both of them.

00:11:44.420 --> 00:11:47.160
But both of them are a
little-- have their own--

00:11:47.160 --> 00:11:49.280
a bit of weirdness
to them in a way

00:11:49.280 --> 00:11:52.010
if you study them for a second.

00:11:56.400 --> 00:12:00.020
That's pretty much converged.

00:12:00.020 --> 00:12:00.830
Share the results.

00:12:07.800 --> 00:12:11.550
So, in fact, the
correct answer is b.

00:12:14.060 --> 00:12:18.920
And why is only C2--

00:12:18.920 --> 00:12:20.255
well, first of all--

00:12:20.255 --> 00:12:23.390
well, what's wrong with C1?

00:12:23.390 --> 00:12:25.760
The problem with C1
is that the rules

00:12:25.760 --> 00:12:31.470
have things besides a single
variable on the left-hand side.

00:12:31.470 --> 00:12:33.650
So having a B1 on
the left-hand side

00:12:33.650 --> 00:12:37.160
is not legal in a
context-free grammar.

00:12:37.160 --> 00:12:40.400
In fact, there are
other kinds of grammars.

00:12:40.400 --> 00:12:43.040
There's a kind of grammar called
the context-sensitive grammar.

00:12:43.040 --> 00:12:46.970
The term "context-free" means
you can replace the variable

00:12:46.970 --> 00:12:50.720
independent of its context
in the intermediate string,

00:12:50.720 --> 00:12:52.550
so independent of
what's around it.

00:12:52.550 --> 00:12:56.150
But here, this substitution is
going to-- you can replace B,

00:12:56.150 --> 00:13:01.078
but it depends on there
being a 1 next to it.

00:13:01.078 --> 00:13:02.870
This is called a
context-sensitive grammar,

00:13:02.870 --> 00:13:05.328
but it's not the kind of
grammar we're going to be using,

00:13:05.328 --> 00:13:06.870
which are only
context-free grammars.

00:13:06.870 --> 00:13:08.570
So C1 is out.

00:13:08.570 --> 00:13:12.800
That's not a legit
context-free grammar.

00:13:12.800 --> 00:13:17.090
C2, the thing that's a
little weird about C2

00:13:17.090 --> 00:13:19.520
is if you try to
generate a string in C2,

00:13:19.520 --> 00:13:24.800
you'll see that there's no way
to get rid of the variables,

00:13:24.800 --> 00:13:27.600
that you're always going to
be stuck with a variable.

00:13:27.600 --> 00:13:30.350
Now, that doesn't
violate the definition

00:13:30.350 --> 00:13:31.880
of a context-free grammar.

00:13:31.880 --> 00:13:34.552
So this is a
context-free grammar,

00:13:34.552 --> 00:13:36.260
but it's not going to
be able to generate

00:13:36.260 --> 00:13:39.260
any strings of only terminals.

00:13:39.260 --> 00:13:41.710
So this is a
context-free grammar

00:13:41.710 --> 00:13:44.320
whose language happens
to be the empty language,

00:13:44.320 --> 00:13:47.200
but that's totally OK.

00:13:47.200 --> 00:13:51.820
So the correct answer here
is B, that only C2 here is

00:13:51.820 --> 00:13:53.860
a valid context-free grammar.

00:13:58.290 --> 00:13:59.310
Common-- let's just see.

00:13:59.310 --> 00:14:03.525
Common question, does a
string u derive itself?

00:14:03.525 --> 00:14:06.660
Yes, a string u derives itself.

00:14:06.660 --> 00:14:07.942
That's a little bit of a--

00:14:07.942 --> 00:14:09.900
little bit of an esoteric
question there for us

00:14:09.900 --> 00:14:12.270
right now, but yes.

00:14:12.270 --> 00:14:14.580
A string u-- in this
definition here,

00:14:14.580 --> 00:14:18.420
u arrow star u is
legit-- is legal.

00:14:18.420 --> 00:14:22.820
Maybe it isn't according to the
way I've written it down here,

00:14:22.820 --> 00:14:24.982
but it is a legal thing.

00:14:24.982 --> 00:14:26.940
It's not going to really
matter for you anyway,

00:14:26.940 --> 00:14:28.250
but it is legal.

00:14:28.250 --> 00:14:31.190
OK, let's continue.

00:14:31.190 --> 00:14:34.040
Let's do another somewhat
interesting example

00:14:34.040 --> 00:14:36.110
of a context-free grammar.

00:14:36.110 --> 00:14:41.180
This is a grammar
that can generate

00:14:41.180 --> 00:14:46.360
arithmetical expressions
involving pluses and times.

00:14:46.360 --> 00:14:47.460
So here it is.

00:14:47.460 --> 00:14:49.740
It has how many rules?

00:14:49.740 --> 00:14:51.120
Well, there are six rules here.

00:14:51.120 --> 00:14:52.890
Each line represents two rules.

00:14:52.890 --> 00:14:57.090
So E goes to E plus T or T;
T goes to T times F or F;

00:14:57.090 --> 00:15:02.990
and F goes to parentheses
E parentheses or a.

00:15:02.990 --> 00:15:06.210
And so the variables are
going to be the symbols that

00:15:06.210 --> 00:15:08.400
appear on the left-hand
side, E, T, and F.

00:15:08.400 --> 00:15:10.110
The terminal symbols,
which are going

00:15:10.110 --> 00:15:12.360
to be the symbols
of the language

00:15:12.360 --> 00:15:15.060
that you're going to be
generating, is going to be

00:15:15.060 --> 00:15:16.830
the plus, the time symbols.

00:15:16.830 --> 00:15:20.200
The parentheses are just
terminal symbols here.

00:15:20.200 --> 00:15:23.010
So they're not playing any
special role besides that.

00:15:23.010 --> 00:15:25.650
And then you have the
a, which is representing

00:15:25.650 --> 00:15:30.840
the upper end on which
those operators would

00:15:30.840 --> 00:15:33.700
be working if there was actually
an expression you would use.

00:15:33.700 --> 00:15:37.890
But they're just symbols from
the perspective of the grammar.

00:15:37.890 --> 00:15:39.840
And lastly, the
start variable is

00:15:39.840 --> 00:15:42.540
going to be, as
normally appears,

00:15:42.540 --> 00:15:46.950
on the upper left-hand
side of the grammar,

00:15:46.950 --> 00:15:49.990
in terms of the way
you write it down.

00:15:49.990 --> 00:15:52.830
So sometimes, you might specify
a different start variable,

00:15:52.830 --> 00:15:55.620
but otherwise-- if
it's not specified,

00:15:55.620 --> 00:15:58.170
it's the one in
this corner here.

00:15:58.170 --> 00:16:02.400
So let's just see some
examples of using the grammar

00:16:02.400 --> 00:16:06.440
to generate a string.

00:16:06.440 --> 00:16:09.590
So here is a string in the
language, a plus a times a.

00:16:09.590 --> 00:16:13.780
And this example will reveal
some other interesting features

00:16:13.780 --> 00:16:17.270
of the grammar, but let's just
see it in operation first.

00:16:17.270 --> 00:16:19.330
So, again, I'll try
to write it to you

00:16:19.330 --> 00:16:21.760
in both ways in terms of the
parse tree and the resulting

00:16:21.760 --> 00:16:24.670
string as you're doing
the substitutions.

00:16:24.670 --> 00:16:30.010
So the-- so first
we start with the E,

00:16:30.010 --> 00:16:33.340
then we substitute E plus T. And
we see the resulting string's E

00:16:33.340 --> 00:16:37.330
plus T. But now as we're doing
additional substitutions,

00:16:37.330 --> 00:16:38.800
the resulting
string that you get

00:16:38.800 --> 00:16:41.960
is going to evolve accordingly.

00:16:41.960 --> 00:16:48.040
And so I hope it comes
across that this tree here

00:16:48.040 --> 00:16:51.220
picture on the left
shows you the structure

00:16:51.220 --> 00:16:53.687
of the various substitutions,
whereas on the right,

00:16:53.687 --> 00:16:55.270
it just shows you
the strings that you

00:16:55.270 --> 00:16:57.400
get as a result of
those substitutions.

00:17:00.410 --> 00:17:04.609
So now you can generate
this particular string,

00:17:04.609 --> 00:17:06.500
which is now in the
language of this grammar.

00:17:06.500 --> 00:17:08.510
You can generate all
sorts of other strings

00:17:08.510 --> 00:17:13.670
as well, such as parentheses
a plus a parentheses times a

00:17:13.670 --> 00:17:14.880
and so on.

00:17:14.880 --> 00:17:21.290
And in fact, this might be a
piece of a programming language

00:17:21.290 --> 00:17:24.230
that you're trying to describe.

00:17:24.230 --> 00:17:28.700
And one application of
context-free grammars

00:17:28.700 --> 00:17:32.660
is to describe the syntax
of programming languages.

00:17:32.660 --> 00:17:37.370
What are the legal
programs that you can write

00:17:37.370 --> 00:17:39.020
in that programming language?

00:17:39.020 --> 00:17:43.250
And not only that,
the grammar can

00:17:43.250 --> 00:17:46.040
be used to
automatically generate

00:17:46.040 --> 00:17:50.450
the part of the compiler for
that programming language,

00:17:50.450 --> 00:17:53.315
which will interpret the--

00:17:53.315 --> 00:17:57.080
which will interpret
the structure

00:17:57.080 --> 00:18:01.310
of the input, the so-called
parser, which will figure out

00:18:01.310 --> 00:18:05.240
the meaning of the
input to the compiler

00:18:05.240 --> 00:18:07.820
so that the compiler then
can generate the code,

00:18:07.820 --> 00:18:12.530
or if it's an interpreter, it
can interpret the resulting

00:18:12.530 --> 00:18:14.360
code that you've given it.

00:18:14.360 --> 00:18:16.700
But the very first
step in both of those

00:18:16.700 --> 00:18:18.290
is to figure out the meaning.

00:18:18.290 --> 00:18:22.550
And the meaning is embedded
within the structure

00:18:22.550 --> 00:18:24.690
of the parse tree.

00:18:24.690 --> 00:18:27.450
Now in the case of this
particular tree, just

00:18:27.450 --> 00:18:31.080
to give you some sense of
what meaning I have in mind,

00:18:31.080 --> 00:18:34.650
this parse tree, due to the
structure of this grammar,

00:18:34.650 --> 00:18:38.670
has the precedents
for times over plus.

00:18:38.670 --> 00:18:41.930
So normally when we write
down a plus a times a,

00:18:41.930 --> 00:18:44.782
you assume you're going to do
the multiplication before you

00:18:44.782 --> 00:18:46.740
do the addition, even
though it appears second.

00:18:46.740 --> 00:18:49.050
That's just the way we
tend to write things.

00:18:49.050 --> 00:18:52.770
And this grammar has
grouped it that way for you.

00:18:52.770 --> 00:18:56.880
It groups the times lower down
in the tree than the plus.

00:18:56.880 --> 00:19:01.050
So the times is going to
be done before the plus,

00:19:01.050 --> 00:19:03.510
if you imagine doing this in
terms of the way the tree is

00:19:03.510 --> 00:19:04.380
guiding you.

00:19:04.380 --> 00:19:06.810
So the tree, as you can
see, has a certain amount

00:19:06.810 --> 00:19:08.277
of meaning built into it.

00:19:08.277 --> 00:19:10.860
Now, we're not actually going
to be using that in this course,

00:19:10.860 --> 00:19:16.620
but I just want to describe
that as an illustration of how

00:19:16.620 --> 00:19:18.120
this material can get applied.

00:19:20.710 --> 00:19:23.320
So here is what I'm saying,
that the tree contains

00:19:23.320 --> 00:19:25.430
additional information.

00:19:25.430 --> 00:19:30.910
Now, that's also
relevant if you happen

00:19:30.910 --> 00:19:34.420
to have a grammar which
might allow multiple parse

00:19:34.420 --> 00:19:35.890
trees for the same string.

00:19:38.600 --> 00:19:41.210
That can happen.

00:19:41.210 --> 00:19:44.990
And this particular grammar
does not allow that,

00:19:44.990 --> 00:19:46.800
but you might write
other grammars,

00:19:46.800 --> 00:19:49.220
as we'll see in a minute,
that could generate

00:19:49.220 --> 00:19:52.010
the same string in multiple ways
with multiple different parse

00:19:52.010 --> 00:19:53.180
trees.

00:19:53.180 --> 00:19:57.110
Now that might be undesirable
when you have a programming

00:19:57.110 --> 00:19:59.390
language because
typically you want

00:19:59.390 --> 00:20:03.110
it to be only a single
meaning for your code.

00:20:03.110 --> 00:20:05.210
You don't want it to
be ambiguous and have

00:20:05.210 --> 00:20:06.500
multiple meanings.

00:20:06.500 --> 00:20:14.150
But ambiguity does
occur, and it's not

00:20:14.150 --> 00:20:16.130
necessarily something
we're always

00:20:16.130 --> 00:20:18.880
going to see as a bad thing.

00:20:18.880 --> 00:20:21.560
So I think as I
mentioned last time,

00:20:21.560 --> 00:20:26.090
a lot of this subject
originated with linguistics,

00:20:26.090 --> 00:20:28.700
and that's where the
terminology comes from, grammar,

00:20:28.700 --> 00:20:34.170
and languages, and so on.

00:20:34.170 --> 00:20:35.850
The terminology for
the subject really

00:20:35.850 --> 00:20:37.440
comes out of linguistics.

00:20:37.440 --> 00:20:39.270
In fact, one of the
key players for that

00:20:39.270 --> 00:20:42.090
is an emeritus faculty
member at MIT, Noam Chomsky.

00:20:42.090 --> 00:20:45.480
He was instrumental in setting
a lot of this stuff up.

00:20:45.480 --> 00:20:52.970
But the-- you can
think of grammars

00:20:52.970 --> 00:20:55.710
as applying to natural
human languages as well.

00:20:55.710 --> 00:20:58.670
So let me give you a
little example as a pop-up.

00:20:58.670 --> 00:21:00.790
It's not directly a pop-up--

00:21:00.790 --> 00:21:03.710
a check-in, not directly
relevant to the material

00:21:03.710 --> 00:21:07.820
I just presented,
but just a curiosity.

00:21:07.820 --> 00:21:11.240
If you take the English
sentence "The boy saw the girl

00:21:11.240 --> 00:21:16.310
with the mirror," does that--

00:21:16.310 --> 00:21:20.450
is there only one
natural interpretation

00:21:20.450 --> 00:21:22.130
for that sentence,
or are there perhaps

00:21:22.130 --> 00:21:24.680
other natural interpretations
for that sentence?

00:21:24.680 --> 00:21:30.270
So let me pose that to
you as another poll here.

00:21:30.270 --> 00:21:36.450
And so I ask you to think about
how many different meanings you

00:21:36.450 --> 00:21:41.210
might find for a-- reasonable
different meanings--

00:21:41.210 --> 00:21:42.725
I mean, you can--

00:21:42.725 --> 00:21:45.350
you're going to go wild, you can
think of zillions of meanings.

00:21:45.350 --> 00:21:47.183
But I think in terms
of reasonable meanings,

00:21:47.183 --> 00:21:50.030
how many meanings might
you get for the sentence?

00:21:50.030 --> 00:21:55.310
People are seeing more meanings
than I'm seeing, but that's OK.

00:21:55.310 --> 00:22:02.440
So this is a quick-- why don't
we just give this another 10

00:22:02.440 --> 00:22:03.400
seconds here.

00:22:05.950 --> 00:22:12.460
And then most of you are
in agreement with me.

00:22:12.460 --> 00:22:19.830
I can see here
that you are seeing

00:22:19.830 --> 00:22:21.310
that there were two meanings.

00:22:21.310 --> 00:22:24.898
The two meanings that I see
here for this sentence are,

00:22:24.898 --> 00:22:26.940
when you say the boy saw
the girl with the mirror

00:22:26.940 --> 00:22:28.890
is, who has the mirror?

00:22:28.890 --> 00:22:32.040
Is it the boy seeing the
girl through the mirror,

00:22:32.040 --> 00:22:34.080
or is it the girl
that has the mirror

00:22:34.080 --> 00:22:35.730
and the boy just
happens to see her?

00:22:35.730 --> 00:22:39.090
So two very different meanings
for the same sentence.

00:22:39.090 --> 00:22:44.440
And that's in the nature of
English is just the way--

00:22:44.440 --> 00:22:46.980
it's an ambiguous
structure there.

00:22:46.980 --> 00:22:49.440
And often we resolve
that ambiguity in English

00:22:49.440 --> 00:22:52.570
with other information
that we might have.

00:22:52.570 --> 00:22:55.380
But typically you don't
want there to be ambiguity

00:22:55.380 --> 00:22:59.020
when you have a grammar,
say, describing a programming

00:22:59.020 --> 00:22:59.520
language.

00:23:02.610 --> 00:23:06.300
So let's continue on that.

00:23:06.300 --> 00:23:08.370
So talking a little bit
more about ambiguity,

00:23:08.370 --> 00:23:10.530
I promised you an
example where you might

00:23:10.530 --> 00:23:12.840
have an ambiguous grammar.

00:23:12.840 --> 00:23:17.280
So if you take these two
grammars, G2 and G3, and G2

00:23:17.280 --> 00:23:21.730
from the last slide and G3 is
a similar grammar, in fact,

00:23:21.730 --> 00:23:24.000
it's the grammar that has
the very same language--

00:23:26.407 --> 00:23:27.990
that gives you the
very same language.

00:23:27.990 --> 00:23:30.260
So L of G2 equals L of G3.

00:23:30.260 --> 00:23:34.550
Both of them are describing
these arithmetical expressions.

00:23:34.550 --> 00:23:38.150
But whereas G2 has
a unique parse tree

00:23:38.150 --> 00:23:40.070
for every string
that you generate,

00:23:40.070 --> 00:23:44.180
G3 can have multiple parse
trees for the same string.

00:23:44.180 --> 00:23:46.187
So I'm just going to
illustrate that here.

00:23:46.187 --> 00:23:48.020
So here is the same
string that we generated

00:23:48.020 --> 00:23:50.750
last time, a plus a times a.

00:23:50.750 --> 00:23:56.340
In G3, the parse tree is
actually even simpler here.

00:23:56.340 --> 00:23:58.220
So here I'm showing you the--

00:23:58.220 --> 00:23:59.810
there's just the
two substituents

00:23:59.810 --> 00:24:03.500
that you need to
make starting from E.

00:24:03.500 --> 00:24:07.610
And then to get the
string a plus a times a,

00:24:07.610 --> 00:24:10.130
it's a simpler
grammar in a sense.

00:24:10.130 --> 00:24:11.930
But there's another
parse tree that'll

00:24:11.930 --> 00:24:14.870
give you the same
result. And I've

00:24:14.870 --> 00:24:19.270
written that down
below here upside down.

00:24:19.270 --> 00:24:24.970
So the upper parse tree groups
the times before the plus,

00:24:24.970 --> 00:24:28.510
more inside than the plus.

00:24:28.510 --> 00:24:31.780
But the lower parse tree doesn't
have that precedence built

00:24:31.780 --> 00:24:34.765
into it and can alternatively
interpret the plus

00:24:34.765 --> 00:24:37.510
as being of higher
precedence than the times.

00:24:37.510 --> 00:24:41.260
And so in that sense,
we have here a grammar

00:24:41.260 --> 00:24:47.710
which has two interpretations
for this same string.

00:24:47.710 --> 00:24:49.300
And we call that--
whoops, we call

00:24:49.300 --> 00:24:56.650
that an ambiguous derivation,
an ambiguously-derived string.

00:24:56.650 --> 00:24:59.140
And the grammar itself is
called an ambiguous grammar.

00:25:05.210 --> 00:25:08.835
So let us continue on from that.

00:25:08.835 --> 00:25:11.210
By the way, I think there's
a question here that came in.

00:25:13.910 --> 00:25:17.030
Like, for example, a plus
a, is that ambiguous in G2?

00:25:17.030 --> 00:25:18.740
No.

00:25:18.740 --> 00:25:24.020
If you try to apply it, you'll
see the way that G2 can produce

00:25:24.020 --> 00:25:29.420
a plus a-- a plus a plus a is
going to group the first two

00:25:29.420 --> 00:25:31.200
and then the second one--

00:25:31.200 --> 00:25:32.750
then the last one.

00:25:32.750 --> 00:25:36.620
You can't derive things
in multiple ways.

00:25:36.620 --> 00:25:40.030
Addition is associative,
but the grammar doesn't--

00:25:40.030 --> 00:25:41.270
it doesn't-- the grammar--

00:25:41.270 --> 00:25:44.450
for the grammar,
it's going to have

00:25:44.450 --> 00:25:49.970
a prescribed order for the way
things get interpreted there.

00:25:49.970 --> 00:25:51.890
So that's ambiguity.

00:25:51.890 --> 00:25:56.210
So let's introduce
pushdown automata, which

00:25:56.210 --> 00:25:58.850
is going to be our
automata counterpart

00:25:58.850 --> 00:26:01.880
for context-free languages.

00:26:05.120 --> 00:26:08.210
So the way I'm going to
introduce pushdown automata,

00:26:08.210 --> 00:26:13.550
sort of shifting
gears here now, is

00:26:13.550 --> 00:26:19.040
by first giving a new
view of finite automata.

00:26:19.040 --> 00:26:22.190
Remember before when we
presented a finite automaton,

00:26:22.190 --> 00:26:24.560
we gave it in terms of
a state diagram, which

00:26:24.560 --> 00:26:27.380
I've shown here in miniature
form on the picture.

00:26:31.100 --> 00:26:33.350
We could do that for
pushdown automata,

00:26:33.350 --> 00:26:36.180
but the picture tends
to be very complicated.

00:26:36.180 --> 00:26:40.790
So I'm going to take a
bit of a higher level

00:26:40.790 --> 00:26:43.070
description for
pushdown automata, which

00:26:43.070 --> 00:26:46.700
is I'm calling a schematic
view or a schematic diagram.

00:26:46.700 --> 00:26:48.800
And there I'm really not
going to be showing you

00:26:48.800 --> 00:26:51.050
the individual states, but
I'm going to be showing you

00:26:51.050 --> 00:26:54.800
the individual components
of the machine, more

00:26:54.800 --> 00:26:56.270
of an abstraction--

00:26:56.270 --> 00:26:58.590
from a more abstract
perspective.

00:26:58.590 --> 00:27:03.950
And so from that perspective,
a finite automaton

00:27:03.950 --> 00:27:07.790
has here what I'm going to
call the "finite control."

00:27:07.790 --> 00:27:09.560
So I'm going to be
suppressing the details

00:27:09.560 --> 00:27:12.590
of the states in this picture.

00:27:12.590 --> 00:27:16.430
I'm going to represent
those states as the control

00:27:16.430 --> 00:27:19.520
of the DFA or the NFA.

00:27:19.520 --> 00:27:23.150
They're really going to be the
same from this pictorial point

00:27:23.150 --> 00:27:24.320
of view.

00:27:24.320 --> 00:27:29.180
The input is going to appear
as a string that's written down

00:27:29.180 --> 00:27:30.965
on what we're calling a "tape."

00:27:30.965 --> 00:27:35.090
Again, this is somewhat of
an anachronistic terminology.

00:27:35.090 --> 00:27:39.050
Back in my days, people
actually did feed their inputs

00:27:39.050 --> 00:27:42.620
into computers on
a tape sometimes.

00:27:42.620 --> 00:27:44.120
We don't do that
so much anymore,

00:27:44.120 --> 00:27:46.490
but that terminology
has stuck, and it's

00:27:46.490 --> 00:27:50.480
going to be a persisting
later on in the course,

00:27:50.480 --> 00:27:52.850
too, so you might as
well get used to it.

00:27:52.850 --> 00:27:54.920
So the input is going
to appear on a tape,

00:27:54.920 --> 00:27:57.290
or sometimes called
an input tape.

00:27:57.290 --> 00:28:01.820
And the way the machine
actually will read that input--

00:28:01.820 --> 00:28:05.240
whoops-- it's going
to have a head, which

00:28:05.240 --> 00:28:08.600
is going to be starting
at the left side

00:28:08.600 --> 00:28:12.020
and moving from left to right,
reading the symbols that appear

00:28:12.020 --> 00:28:14.330
on the input tape one by one.

00:28:14.330 --> 00:28:19.700
So this is our picture
of a finite automaton,

00:28:19.700 --> 00:28:23.570
just redone from last
time, just a different way

00:28:23.570 --> 00:28:25.100
of picturing it.

00:28:25.100 --> 00:28:28.220
Now, that's going to be setting
the stage for the picture

00:28:28.220 --> 00:28:31.610
of a pushdown automaton,
because a pushdown automaton is

00:28:31.610 --> 00:28:35.360
like a finite automaton,
but it has an extra feature,

00:28:35.360 --> 00:28:38.010
it has an extra
device attached to it.

00:28:38.010 --> 00:28:41.590
And that's called a "stack."

00:28:41.590 --> 00:28:44.680
So here's the schematic diagram
for a pushdown automaton,

00:28:44.680 --> 00:28:48.310
and that's going to
be a stack, which

00:28:48.310 --> 00:28:55.750
is going to be basically a
form of auxiliary storage.

00:28:55.750 --> 00:28:57.640
Now remember, part
of the limitation

00:28:57.640 --> 00:29:00.070
for a finite
automaton was that we

00:29:00.070 --> 00:29:05.910
had a limited amount of memory.

00:29:05.910 --> 00:29:09.560
So we were not able to do
some very simple things,

00:29:09.560 --> 00:29:12.530
like counting, because
we had a limited memory.

00:29:12.530 --> 00:29:14.450
So the pushdown
automaton is going

00:29:14.450 --> 00:29:18.860
to be able to use its stack
as a kind of unbounded memory,

00:29:18.860 --> 00:29:23.130
but a memory that's restricted
in the way it can be used.

00:29:23.130 --> 00:29:28.600
So it's unlimited but still
restricted, as we'll see.

00:29:28.600 --> 00:29:35.480
So the way the pushdown
automaton uses its extra memory

00:29:35.480 --> 00:29:38.820
on what we're calling the
stack or a pushdown stack

00:29:38.820 --> 00:29:44.070
is that you can write symbols
instead of only reading

00:29:44.070 --> 00:29:44.790
symbols.

00:29:44.790 --> 00:29:49.200
But those symbols can
only be read at the very--

00:29:49.200 --> 00:29:53.610
written or read at the very
top of this list of symbols.

00:29:53.610 --> 00:29:57.060
And every time you add a new
symbol, the other symbols that

00:29:57.060 --> 00:30:00.570
are already there get pushed
down, so hence the name.

00:30:00.570 --> 00:30:03.240
People also often
refer to it as a stack

00:30:03.240 --> 00:30:07.560
of plates in a cafeteria, if
you've ever seen those things,

00:30:07.560 --> 00:30:09.060
or you can remember
back to the days

00:30:09.060 --> 00:30:12.300
when we went to cafeteria, which
are getting further and further

00:30:12.300 --> 00:30:12.850
away.

00:30:12.850 --> 00:30:18.120
But even at the cafeteria,
you had a stack of plates.

00:30:18.120 --> 00:30:21.450
And as you remove plates from
them, they were on a spring,

00:30:21.450 --> 00:30:22.590
and they kept coming up.

00:30:22.590 --> 00:30:24.480
Or if you add more,
they would go down.

00:30:24.480 --> 00:30:25.570
And it's the same idea.

00:30:25.570 --> 00:30:29.580
Imagine these symbols
here are on a spring,

00:30:29.580 --> 00:30:32.400
and the more symbols you
add, the more they go down.

00:30:32.400 --> 00:30:36.030
Or if you move them, and
read them, and remove them,

00:30:36.030 --> 00:30:39.400
then they move back up.

00:30:39.400 --> 00:30:43.570
So a pushdown automaton
operates like a finite--

00:30:43.570 --> 00:30:46.600
like a non-deterministic
finite automaton, as we'll see.

00:30:46.600 --> 00:30:49.810
Pushdown automata
for us are always

00:30:49.810 --> 00:30:51.850
going to be allowed to
be non-deterministic.

00:30:51.850 --> 00:30:54.970
So we're not going to
be studying the pushdown

00:30:54.970 --> 00:30:59.168
automata that are restricted
to be only deterministic.

00:30:59.168 --> 00:31:00.710
I'll say more about
that in a second.

00:31:00.710 --> 00:31:07.390
But they operate like an NFA,
except they can write or read

00:31:07.390 --> 00:31:10.040
symbols from the
top of the stack.

00:31:10.040 --> 00:31:12.350
And when they write, they're
adding the symbol on,

00:31:12.350 --> 00:31:14.185
pushing down that stack.

00:31:14.185 --> 00:31:15.560
And when they're
reading, they're

00:31:15.560 --> 00:31:19.280
removing symbols from the
stack, and thereby lifting

00:31:19.280 --> 00:31:21.830
up the stack.

00:31:21.830 --> 00:31:22.985
We give them special names.

00:31:22.985 --> 00:31:24.860
So those of you who have
seen stacks already,

00:31:24.860 --> 00:31:28.160
this is, I'm sure,
old hat for you.

00:31:28.160 --> 00:31:32.750
But I'm sure not everyone
have seen stacks before.

00:31:32.750 --> 00:31:36.290
So the special name for
writing onto a stack

00:31:36.290 --> 00:31:38.990
is called a "push
operation," so that you're

00:31:38.990 --> 00:31:41.450
pushing a new symbol down
on the top of the stack,

00:31:41.450 --> 00:31:43.250
and it pushes everything down.

00:31:43.250 --> 00:31:45.140
Whereas when you're
reading a symbol

00:31:45.140 --> 00:31:46.940
and removing it from
the top of the stack,

00:31:46.940 --> 00:31:48.600
that's called a "pop."

00:31:48.600 --> 00:31:50.720
So that's reading and removing.

00:31:50.720 --> 00:31:52.880
And we always think of
those as going together.

00:31:52.880 --> 00:31:56.390
Writing and adding and reading
and removing are combined.

00:31:56.390 --> 00:31:58.610
I mean, you might
wonder, well, can't I

00:31:58.610 --> 00:32:03.390
just read it and leave it
alone and not just remove it?

00:32:03.390 --> 00:32:03.890
No.

00:32:03.890 --> 00:32:07.820
You can get that effect by
reading it, which removes it,

00:32:07.820 --> 00:32:10.790
and then putting it back if you
really want it to stay there.

00:32:10.790 --> 00:32:13.130
But the way we're
setting it up is

00:32:13.130 --> 00:32:15.500
that reading comes
with removing,

00:32:15.500 --> 00:32:18.750
writing comes with adding.

00:32:18.750 --> 00:32:21.497
Again, they're called
pushing and popping.

00:32:21.497 --> 00:32:22.455
So let's do an example.

00:32:25.590 --> 00:32:27.650
So we have here a
pushdown automaton

00:32:27.650 --> 00:32:30.800
for a language
we'll call D. We've

00:32:30.800 --> 00:32:33.350
seen that language before.

00:32:33.350 --> 00:32:37.050
It was-- actually, we used
the same letter for it,

00:32:37.050 --> 00:32:39.830
strings of zeros
followed by ones,

00:32:39.830 --> 00:32:43.010
where the numbers were the
same of the two, 0 to the k 1

00:32:43.010 --> 00:32:44.210
to the k.

00:32:44.210 --> 00:32:46.310
We couldn't do that
with a finite automaton.

00:32:46.310 --> 00:32:49.100
We will be able to do that
with a pushdown automaton.

00:32:51.800 --> 00:32:52.912
And here I--

00:32:55.804 --> 00:32:59.110
I thought I wrote down
the input here, but OK.

00:32:59.110 --> 00:33:06.040
So the basic idea is I'm going
to give you an input now,

00:33:06.040 --> 00:33:07.750
and the pushdown
automaton is supposed

00:33:07.750 --> 00:33:11.050
to test whether that
input is in the language,

00:33:11.050 --> 00:33:12.235
whether it's of this form.

00:33:14.740 --> 00:33:18.850
Now it has the ability
to use the stack

00:33:18.850 --> 00:33:21.430
because it's going to have to
count how many zeros it has.

00:33:21.430 --> 00:33:23.050
And so the way
it's going to do it

00:33:23.050 --> 00:33:25.690
is it'll have a bunch of
zeros, hopefully, and then

00:33:25.690 --> 00:33:27.430
a bunch of ones,
and you want to see

00:33:27.430 --> 00:33:29.770
they are of the same number.

00:33:29.770 --> 00:33:32.950
It's going to take the zeros
and store them on the stack

00:33:32.950 --> 00:33:34.690
until it sees a one.

00:33:34.690 --> 00:33:36.892
And then it's going to
start to read the ones,

00:33:36.892 --> 00:33:38.350
and it's going to
remove the zeros,

00:33:38.350 --> 00:33:43.620
matching them off one to one
with the ones that it's seeing.

00:33:43.620 --> 00:33:48.720
So you initially first read
the zeros and push them

00:33:48.720 --> 00:33:50.490
onto the stack until
you read a one,

00:33:50.490 --> 00:33:54.870
and then you read the ones while
popping zeros from the stack.

00:33:54.870 --> 00:33:59.310
And you enter the accept
state if the stack is empty.

00:33:59.310 --> 00:34:02.340
Just like with a
finite automaton,

00:34:02.340 --> 00:34:04.978
entering the accept
state only counts when

00:34:04.978 --> 00:34:06.270
you're at the end of the input.

00:34:09.830 --> 00:34:13.370
So without even me
needing to say anything,

00:34:13.370 --> 00:34:15.650
it's really saying you
would enter the accept state

00:34:15.650 --> 00:34:18.409
if the stack is empty at
the end of the input string.

00:34:18.409 --> 00:34:21.828
But that's implicit because
it only takes effect

00:34:21.828 --> 00:34:23.120
at the end of the input string.

00:34:23.120 --> 00:34:25.429
If you enter an accept state
alone in the middle somewhere,

00:34:25.429 --> 00:34:26.159
it doesn't matter.

00:34:26.159 --> 00:34:27.284
It doesn't affect anything.

00:34:32.139 --> 00:34:34.389
And with that we're going
to take a little break.

00:34:34.389 --> 00:34:38.480
And then we will be back shortly
to look at pushdown automata

00:34:38.480 --> 00:34:40.060
again in a more--

00:34:40.060 --> 00:34:42.973
with a more formal definition.

00:34:42.973 --> 00:34:44.890
Let me put that it's
going to be five minutes.

00:34:44.890 --> 00:34:47.989
Let me see if I can figure out
how to get my timer screen up

00:34:47.989 --> 00:34:48.489
here.

00:34:48.489 --> 00:34:49.690
Yes.

00:34:49.690 --> 00:34:57.270
And we will-- when the
candle burns down to nothing,

00:34:57.270 --> 00:34:59.595
we will return and continue.

00:35:07.600 --> 00:35:13.130
OK, our candle has burned
down and has gone out.

00:35:13.130 --> 00:35:17.150
I never actually watched and see
what would happened at the end.

00:35:17.150 --> 00:35:19.185
So we're good to go.

00:35:19.185 --> 00:35:19.810
Let's continue.

00:35:24.480 --> 00:35:25.320
Good.

00:35:25.320 --> 00:35:29.145
And let me put
myself back in there.

00:35:29.145 --> 00:35:29.645
All righty.

00:35:32.390 --> 00:35:34.370
So we were doing
pushdown automata.

00:35:34.370 --> 00:35:38.660
And we just did that example
of 0 to the k, 1 to the k.

00:35:38.660 --> 00:35:40.850
Now that you have
a stack, we can

00:35:40.850 --> 00:35:45.110
do all sorts of fancy things
that finite automata could not

00:35:45.110 --> 00:35:49.580
do just with their
limited memory.

00:35:49.580 --> 00:35:54.086
So let's take a look at how
we define pushdown automata.

00:35:57.740 --> 00:36:02.420
So now pushdown automata is
actually going to be a 6-tuple.

00:36:02.420 --> 00:36:05.330
So it's a little bit-- got
some fancier stuff here

00:36:05.330 --> 00:36:09.380
to deal with, not too
much, but a little bit.

00:36:09.380 --> 00:36:12.402
And so it has--

00:36:12.402 --> 00:36:14.360
let's look at these a
little bit more carefully

00:36:14.360 --> 00:36:16.530
since there's some novelty here.

00:36:16.530 --> 00:36:22.190
We have the input alphabet,
just as we had before, sigma,

00:36:22.190 --> 00:36:25.580
but we also have gamma,
which is the alphabet

00:36:25.580 --> 00:36:28.580
for using the stack.

00:36:28.580 --> 00:36:32.510
Now, you might ask, why don't
we just use the same alphabet?

00:36:32.510 --> 00:36:35.180
Well, it's really a
matter of convenience

00:36:35.180 --> 00:36:41.210
that we would like to be able
to have other symbols that

00:36:41.210 --> 00:36:43.010
could include the
input alphabet,

00:36:43.010 --> 00:36:44.910
but could include
other things as well.

00:36:44.910 --> 00:36:46.490
So it just gives
you more flexibility

00:36:46.490 --> 00:36:49.010
in terms of what you're going
to be writing on the stack.

00:36:52.440 --> 00:36:55.157
The transition function,
more complicated.

00:36:55.157 --> 00:36:57.240
So I think-- I don't know
if I'm going to even say

00:36:57.240 --> 00:36:59.823
what the other things are, but
these are the accepting states,

00:36:59.823 --> 00:37:01.030
this is the starting state.

00:37:01.030 --> 00:37:04.060
So that's the same as before.

00:37:04.060 --> 00:37:08.340
But the transition function
is a much different animal

00:37:08.340 --> 00:37:10.530
here in a pushdown automaton.

00:37:10.530 --> 00:37:13.260
So let's just try to
unpack that and understand

00:37:13.260 --> 00:37:15.130
what it's saying.

00:37:15.130 --> 00:37:17.670
So the transition
function tells us

00:37:17.670 --> 00:37:21.840
how the machine operates, how
it goes from state to state,

00:37:21.840 --> 00:37:24.000
how it's going to read
the input, how it reads it

00:37:24.000 --> 00:37:26.610
from the stack, and what
am I to write on the stack,

00:37:26.610 --> 00:37:29.280
too, because that's going to all
happen under program control.

00:37:31.800 --> 00:37:37.410
So what this means
here is that when

00:37:37.410 --> 00:37:42.630
the machine is in
a particular state,

00:37:42.630 --> 00:37:44.760
reading a particular
input symbol--

00:37:44.760 --> 00:37:48.330
let's ignore the empty string
subscript for the moment.

00:37:48.330 --> 00:37:52.500
So it's in a particular state
reading a particular input

00:37:52.500 --> 00:37:56.550
symbol and with a certain
stack symbol appearing

00:37:56.550 --> 00:37:59.230
at the top of the stack.

00:37:59.230 --> 00:38:03.120
So that's all information that's
available to the controller

00:38:03.120 --> 00:38:07.620
of this pushdown
automaton, the transition

00:38:07.620 --> 00:38:12.210
function, the current
state, the next input

00:38:12.210 --> 00:38:14.910
symbol, and the symbol
at the top of the stack.

00:38:14.910 --> 00:38:20.430
And once we have that, we know
what new state we can go into

00:38:20.430 --> 00:38:27.300
and what new symbol we can
write on the top of the stack.

00:38:27.300 --> 00:38:32.430
So that's what the right-hand
side of this function

00:38:32.430 --> 00:38:33.930
specification means.

00:38:33.930 --> 00:38:37.140
So this is where the input
to the function, this

00:38:37.140 --> 00:38:41.310
is going to be the output of the
function, state and new symbol

00:38:41.310 --> 00:38:42.910
to appear on the stack.

00:38:42.910 --> 00:38:46.988
So this is the popping symbol,
this is the pushing symbol.

00:38:46.988 --> 00:38:48.530
So now there are
two things that bear

00:38:48.530 --> 00:38:50.180
explanation here first of all.

00:38:50.180 --> 00:38:53.860
Now this is a power set.

00:38:53.860 --> 00:38:57.480
So this is going to be
representing, as we did before,

00:38:57.480 --> 00:39:00.510
a non-deterministic machine.

00:39:00.510 --> 00:39:02.915
We may have several
possibilities,

00:39:02.915 --> 00:39:04.290
and we're going
to represent that

00:39:04.290 --> 00:39:07.800
as a set of possibilities
for the machine

00:39:07.800 --> 00:39:12.260
that it could go
to at any point.

00:39:12.260 --> 00:39:15.590
I will give an example of
how a pushdown automaton uses

00:39:15.590 --> 00:39:18.840
its non-determinism in a minute.

00:39:18.840 --> 00:39:20.760
The other thing
is these epsilons.

00:39:20.760 --> 00:39:23.390
So we have to understand
why they are there.

00:39:23.390 --> 00:39:26.300
And we remember we
had them for the NFAs,

00:39:26.300 --> 00:39:31.670
corresponding to when the NFA
had an epsilon transition,

00:39:31.670 --> 00:39:32.790
the empty transition.

00:39:32.790 --> 00:39:34.770
So it could go along
in that transition

00:39:34.770 --> 00:39:37.650
without reading any input.

00:39:37.650 --> 00:39:40.470
So this is going to
play the same role here.

00:39:40.470 --> 00:39:42.470
So if you have--

00:39:42.470 --> 00:39:46.010
instead of an input
symbol from sigma

00:39:46.010 --> 00:39:52.232
appearing in this part of the--

00:39:52.232 --> 00:39:55.190
for the transition
function, instead you

00:39:55.190 --> 00:39:57.260
have an epsilon appearing.

00:39:57.260 --> 00:40:01.430
That means that the transition--
that move of the machine

00:40:01.430 --> 00:40:06.332
can happen without
reading any input symbol,

00:40:06.332 --> 00:40:07.290
just like for the NFAs.

00:40:10.230 --> 00:40:13.110
Or if you have an epsilon
appearing for the stack symbol,

00:40:13.110 --> 00:40:15.690
that means you can make that
transition without reading

00:40:15.690 --> 00:40:17.040
any stack symbol.

00:40:17.040 --> 00:40:19.410
So whatever is sitting
on the top of the stack,

00:40:19.410 --> 00:40:23.760
it doesn't matter, the
machine can make that move.

00:40:23.760 --> 00:40:25.262
And it won't read
anything either,

00:40:25.262 --> 00:40:26.470
or not going to pop anything.

00:40:26.470 --> 00:40:29.580
It's just going to be
proceeding without looking

00:40:29.580 --> 00:40:31.200
at the stack at all.

00:40:31.200 --> 00:40:33.660
Or it might have both of
them, in which case, it's

00:40:33.660 --> 00:40:35.580
going to go from one
state to another state

00:40:35.580 --> 00:40:39.250
without looking at the input
or at the top of the stack.

00:40:39.250 --> 00:40:43.560
So that's what the
possibility of epsilon

00:40:43.560 --> 00:40:50.340
means for the transition
function in those places.

00:40:50.340 --> 00:40:52.620
The epsilon appearing
over here means

00:40:52.620 --> 00:40:54.930
something a little
different, but very similar.

00:40:54.930 --> 00:41:01.060
What that means is that
we won't write anything

00:41:01.060 --> 00:41:02.530
on the top of the stack.

00:41:02.530 --> 00:41:03.790
That's going to be--

00:41:03.790 --> 00:41:07.210
we will go to a new state,
but without doing any writing.

00:41:07.210 --> 00:41:10.380
So we'll leave the stack alone.

00:41:10.380 --> 00:41:13.020
So here it means we're
not going to read anything

00:41:13.020 --> 00:41:15.600
if it's in this position,
and this position

00:41:15.600 --> 00:41:19.230
means we're not going
to write anything.

00:41:19.230 --> 00:41:22.410
So all of those things
are valid and legal

00:41:22.410 --> 00:41:25.600
from the perspective of
constructing a pushdown

00:41:25.600 --> 00:41:27.310
automaton.

00:41:27.310 --> 00:41:29.890
And I've illustrated here,
just with a little bit

00:41:29.890 --> 00:41:35.890
of an example, if you have delta
that applies to some state q,

00:41:35.890 --> 00:41:38.800
reading an input
symbol a and popping

00:41:38.800 --> 00:41:42.540
a c from the top of the
stack, then you might have,

00:41:42.540 --> 00:41:44.473
let's say, in this
case, two possibilities

00:41:44.473 --> 00:41:45.765
that you might end up going to.

00:41:45.765 --> 00:41:50.460
You might end up going to
states r1 or to state r2.

00:41:50.460 --> 00:41:53.430
And in the former case,
you'll end up writing a d,

00:41:53.430 --> 00:41:55.590
pushing a d onto the
top of the stack.

00:41:55.590 --> 00:41:58.080
And in the latter case,
you would be pushing an e

00:41:58.080 --> 00:42:01.220
onto the top of the stack.

00:42:01.220 --> 00:42:04.625
So this is I'm trying to help
you look at this notation.

00:42:07.370 --> 00:42:10.070
I hope that this
is clear to you.

00:42:10.070 --> 00:42:14.360
I'm sure for some of you it's
too slow, but others of you

00:42:14.360 --> 00:42:15.590
I'm trying to help along.

00:42:15.590 --> 00:42:17.690
But if you're really
struggling with this notation

00:42:17.690 --> 00:42:20.750
at this point, you're going
to have to dig in and make

00:42:20.750 --> 00:42:21.645
sure you follow it.

00:42:21.645 --> 00:42:23.270
It's only going to
get harder from now.

00:42:23.270 --> 00:42:28.020
I'm going to stop going
over these kinds of points.

00:42:28.020 --> 00:42:30.330
And if you're still
struggling, you can't get it,

00:42:30.330 --> 00:42:32.630
this is not the right class
for you, I'll be honest.

00:42:35.456 --> 00:42:39.040
So we're just going to
be taking off like--

00:42:39.040 --> 00:42:43.640
we're going to start to
accelerate fairly quickly.

00:42:43.640 --> 00:42:46.490
So it's a
non-deterministic machine.

00:42:46.490 --> 00:42:49.490
We accept, like we did before.

00:42:49.490 --> 00:42:52.430
There might be several different
threads of the computation.

00:42:52.430 --> 00:42:55.670
You're going to end
up accepting if some

00:42:55.670 --> 00:42:58.833
of the threads, at
least one of the threads

00:42:58.833 --> 00:43:01.250
ends up in an accept state at
the end of the input string.

00:43:04.290 --> 00:43:06.840
That's when the machine
overall accepts.

00:43:06.840 --> 00:43:10.140
It's just the way we normally
think of non-determinism.

00:43:10.140 --> 00:43:11.880
Again, you can use
the models that we

00:43:11.880 --> 00:43:14.700
had before in terms of
guessing or parallelism,

00:43:14.700 --> 00:43:16.060
whatever works for you.

00:43:16.060 --> 00:43:18.240
And sometimes different
things work in different--

00:43:18.240 --> 00:43:19.740
at different occasions.

00:43:19.740 --> 00:43:21.540
But that's how
non-determinism works.

00:43:21.540 --> 00:43:23.340
We'll do an example of it now.

00:43:23.340 --> 00:43:27.540
Here is a pushdown automaton
for a different language

00:43:27.540 --> 00:43:31.700
we haven't seen before, I don't
think, well, maybe we have,

00:43:31.700 --> 00:43:36.790
which is going to be
using it's non-determinism

00:43:36.790 --> 00:43:38.170
in an essential way.

00:43:38.170 --> 00:43:42.550
This is a language
where non-determinism

00:43:42.550 --> 00:43:44.830
is going to be critical.

00:43:44.830 --> 00:43:47.260
Without it, you can't--
a deterministic pushdown

00:43:47.260 --> 00:43:50.590
automaton, which is something,
by the way, that people study.

00:43:50.590 --> 00:43:52.750
And there's a section
of my book about that,

00:43:52.750 --> 00:43:56.322
it's section 2.4, because it
has relevance to applications.

00:43:56.322 --> 00:43:58.280
We're not going to address
that in this course.

00:43:58.280 --> 00:44:00.190
So you can just
skip section 2.4.

00:44:00.190 --> 00:44:04.120
It's pretty technical,
I'll have to say, but still

00:44:04.120 --> 00:44:06.550
quite interesting and beautiful
if you like that stuff.

00:44:06.550 --> 00:44:08.200
But it's technical.

00:44:08.200 --> 00:44:10.430
We won't do it.

00:44:10.430 --> 00:44:19.240
So here is this input string
ww reverse for all possible w's

00:44:19.240 --> 00:44:21.040
over our alphabet 0, 1.

00:44:21.040 --> 00:44:25.040
And what w reversed, by the way,
means is writing w backwards.

00:44:25.040 --> 00:44:28.660
So this is all strings
followed by a reversal

00:44:28.660 --> 00:44:34.070
of the same string, the
string written backwards.

00:44:34.070 --> 00:44:37.230
Really you can
think of these as--

00:44:37.230 --> 00:44:40.190
well, so these
are strings that--

00:44:40.190 --> 00:44:45.090
well, here's an example, 0,
1, 1, 1, 1, 0, the string

00:44:45.090 --> 00:44:45.840
written backwards.

00:44:45.840 --> 00:44:49.055
So this is a string in the
language appearing on a tape

00:44:49.055 --> 00:44:51.680
as I described.

00:44:51.680 --> 00:44:55.640
So how is the machine going
to recognize this line, which

00:44:55.640 --> 00:44:58.550
is going to be somewhat
similar to before, but with one

00:44:58.550 --> 00:45:01.990
important difference.

00:45:01.990 --> 00:45:03.360
And if you imagine--

00:45:03.360 --> 00:45:07.500
and I like to use this
kind of anthropomorphizing

00:45:07.500 --> 00:45:10.500
these things, putting yourself
in the place of the machine,

00:45:10.500 --> 00:45:13.900
and thinking how
you would do it.

00:45:13.900 --> 00:45:17.555
So if you imagine getting these
symbols one by one, 0, 1, 1,

00:45:17.555 --> 00:45:18.930
you don't know
what's coming next

00:45:18.930 --> 00:45:21.030
as you're getting the symbols.

00:45:21.030 --> 00:45:23.340
You have to figure
out how to match off

00:45:23.340 --> 00:45:24.960
the second half
with the first half.

00:45:24.960 --> 00:45:28.110
So you're going to put the
first half on the stack,

00:45:28.110 --> 00:45:31.890
and then you're going
to remove the first half

00:45:31.890 --> 00:45:36.360
and match it off
with the second half.

00:45:36.360 --> 00:45:39.540
Conveniently, the first
half comes out backwards.

00:45:39.540 --> 00:45:42.670
The stack is a first in
last out kind of thing.

00:45:42.670 --> 00:45:46.390
So it comes out
in reverse order.

00:45:46.390 --> 00:45:48.735
So that's perfect for matching
off with the second half.

00:45:51.320 --> 00:45:54.650
But the tricky part
with this language

00:45:54.650 --> 00:45:58.250
is, how do you know when
you're at the middle

00:45:58.250 --> 00:46:02.510
because you don't
get to see the rest.

00:46:02.510 --> 00:46:04.760
You only get to see
what you've seen so far.

00:46:04.760 --> 00:46:06.140
You don't know what's coming.

00:46:06.140 --> 00:46:13.000
So when you read that second
one-- well, at this point,

00:46:13.000 --> 00:46:16.540
you're reading 0, 1, 1, now
you're reading that second one,

00:46:16.540 --> 00:46:18.430
you don't know that
perhaps it's just

00:46:18.430 --> 00:46:21.770
going to be a 0 following
that and it's going to be all.

00:46:21.770 --> 00:46:25.610
So maybe you should be deciding
so that this point here

00:46:25.610 --> 00:46:31.680
that I've marked
is the midpoint.

00:46:31.680 --> 00:46:35.450
And you put 0, 1 on
the tape and then

00:46:35.450 --> 00:46:39.400
start popping the second
one and matching it off

00:46:39.400 --> 00:46:41.270
with the first one.

00:46:41.270 --> 00:46:45.960
That would be a tempting thing
to do, but you just don't know.

00:46:45.960 --> 00:46:47.750
And that's where
the non-determinism

00:46:47.750 --> 00:46:48.950
is going to be essential.

00:46:48.950 --> 00:46:50.370
So let me write
down more of this.

00:46:50.370 --> 00:46:51.870
So what you're going
to do is you're

00:46:51.870 --> 00:46:53.660
going to read and
push input symbols,

00:46:53.660 --> 00:46:55.490
but non-deterministically
guessing

00:46:55.490 --> 00:46:56.820
that you're at the middle.

00:46:56.820 --> 00:46:58.487
So you're going to
non-deterministically

00:46:58.487 --> 00:47:01.490
either repeat that and continue
to read and push symbols

00:47:01.490 --> 00:47:03.290
onto the stack, or
you're going to go

00:47:03.290 --> 00:47:08.960
to 2 deciding that, or guessing
that you're at the midpoint,

00:47:08.960 --> 00:47:12.320
and now it's time to start
reading and popping instead

00:47:12.320 --> 00:47:13.718
of reading and pushing.

00:47:13.718 --> 00:47:15.260
So you're going to
read input symbols

00:47:15.260 --> 00:47:18.740
and popping the stack
symbols, comparing

00:47:18.740 --> 00:47:22.405
the two, the symbols that
you're reading at the top,

00:47:22.405 --> 00:47:24.620
the symbols you're
removing from the stack.

00:47:24.620 --> 00:47:28.370
If they ever disagree, then this
thread of the non-determinism

00:47:28.370 --> 00:47:32.900
rejects because either the
input is not in the language

00:47:32.900 --> 00:47:35.360
or at least you have
made a wrong choice

00:47:35.360 --> 00:47:36.740
as to where the midpoint is.

00:47:40.192 --> 00:47:42.150
And then you're going to
enter the accept state

00:47:42.150 --> 00:47:44.910
if the stack is empty.

00:47:44.910 --> 00:47:47.670
And ignore this part for
the moment, this software

00:47:47.670 --> 00:47:48.930
reference.

00:47:48.930 --> 00:47:52.120
Let's just-- I'll speak
to that in a second.

00:47:52.120 --> 00:47:54.750
But I just want to
make sure we understand

00:47:54.750 --> 00:47:57.780
that at an intuitive level
how this machine is using

00:47:57.780 --> 00:48:03.130
it's non-determinism
to recognize

00:48:03.130 --> 00:48:05.470
this language because the
non-determinism is critical.

00:48:05.470 --> 00:48:08.450
And it's important
that you understand it.

00:48:08.450 --> 00:48:10.148
So let me just make
some side comments,

00:48:10.148 --> 00:48:12.190
and then we'll come back
to this software remark.

00:48:12.190 --> 00:48:16.705
So first of all, one question
that comes up a lot--

00:48:19.445 --> 00:48:22.168
well, I'm not paying attention
to the chat here, sorry.

00:48:22.168 --> 00:48:23.960
So if you're not getting
an answer from me,

00:48:23.960 --> 00:48:25.010
you try the TAs.

00:48:25.010 --> 00:48:26.750
But one of the--

00:48:29.720 --> 00:48:31.758
one of the questions
that comes up

00:48:31.758 --> 00:48:33.800
a lot when they're thinking
about non-determinism

00:48:33.800 --> 00:48:38.530
for pushdown automata is,
what happens to the stack?

00:48:38.530 --> 00:48:43.620
The stack gets replicated in
the non-determinism every time

00:48:43.620 --> 00:48:46.230
the machine forks, just
like everything else

00:48:46.230 --> 00:48:47.010
gets replicated.

00:48:47.010 --> 00:48:48.810
So an entire--
every time there's

00:48:48.810 --> 00:48:52.050
a fork in the non-determinism
and the machine branches

00:48:52.050 --> 00:48:55.980
into multiple possibilities,
the entire machine

00:48:55.980 --> 00:48:58.650
replicates the current
state, the current position

00:48:58.650 --> 00:49:02.520
of the head, the stack
and its contents.

00:49:02.520 --> 00:49:04.920
All of that gets replicated.

00:49:04.920 --> 00:49:10.230
And the two sides of the-- the
two branches or the two sides

00:49:10.230 --> 00:49:13.170
of the fork each
go on independently

00:49:13.170 --> 00:49:17.150
in their merry way, doing
their own thing independently.

00:49:17.150 --> 00:49:18.770
And then if any one
of them accepts,

00:49:18.770 --> 00:49:21.410
that's the only way they sort
of-- a kind of a communication

00:49:21.410 --> 00:49:23.780
because the one that
accepts raises the flag,

00:49:23.780 --> 00:49:28.250
and then the overall
machine is set to accept.

00:49:28.250 --> 00:49:30.783
So the non-determinism
forks replicate the stack.

00:49:30.783 --> 00:49:31.700
[INAUDIBLE] saying it.

00:49:31.700 --> 00:49:34.220
I just want to make
sure you got that.

00:49:34.220 --> 00:49:36.680
And then this language
requires non-determinism,

00:49:36.680 --> 00:49:41.180
that I said earlier, so our
PDA, pushdown automaton model is

00:49:41.180 --> 00:49:42.470
going to be non-deterministic.

00:49:42.470 --> 00:49:44.803
I mean, you might have examples
which are deterministic,

00:49:44.803 --> 00:49:48.020
but the model is going to
always allow non-determinism.

00:49:48.020 --> 00:49:50.600
What's this bit
about the software?

00:49:50.600 --> 00:49:53.230
So if you look at this
formal definition here,

00:49:53.230 --> 00:49:56.260
it doesn't have anywhere
in it the ability

00:49:56.260 --> 00:49:58.930
to test if the stack is empty.

00:49:58.930 --> 00:50:01.720
That's not part of the
hardware specification,

00:50:01.720 --> 00:50:04.570
at least as we are describing
it for a pushdown automaton.

00:50:04.570 --> 00:50:07.690
You can might imagine somebody
else describes pushdown

00:50:07.690 --> 00:50:10.218
automata in some other way
which gives that as a primitive,

00:50:10.218 --> 00:50:11.510
but we're not going to do that.

00:50:11.510 --> 00:50:12.160
Why?

00:50:12.160 --> 00:50:13.990
Because we don't need
a primitive for that.

00:50:13.990 --> 00:50:17.410
You can get the
effect of testing

00:50:17.410 --> 00:50:21.070
if there's an empty stack,
even if you don't have that

00:50:21.070 --> 00:50:26.590
as a primitive for the machine
because what you can do

00:50:26.590 --> 00:50:28.750
is you can start the
machine off when it--

00:50:28.750 --> 00:50:32.020
and the very first thing it does
is it writes a special symbol

00:50:32.020 --> 00:50:34.420
to mark the bottom--

00:50:34.420 --> 00:50:36.670
what's going to eventually
be the bottom of the stack.

00:50:36.670 --> 00:50:39.170
There's going to be some special
symbol, maybe a dollar sign

00:50:39.170 --> 00:50:39.955
symbol.

00:50:39.955 --> 00:50:41.830
That's the very first
thing the machine does.

00:50:41.830 --> 00:50:43.122
And then it proceeds as before.

00:50:43.122 --> 00:50:45.970
And if it ever sees that
dollar sign symbol again,

00:50:45.970 --> 00:50:50.720
it knows the stack
is effectively empty.

00:50:50.720 --> 00:50:53.180
So you can get the
effect of testing

00:50:53.180 --> 00:50:55.217
for the static being
empty, even if you don't

00:50:55.217 --> 00:50:56.300
have a primitive for that.

00:50:56.300 --> 00:51:00.960
And we're not going to actually
fuss about details like that.

00:51:00.960 --> 00:51:03.950
So you can use-- when you're
writing your homework sets,

00:51:03.950 --> 00:51:06.020
you can just use the
assumption that you

00:51:06.020 --> 00:51:07.458
can test for an
empty stack, which

00:51:07.458 --> 00:51:08.750
is what I'm going to do myself.

00:51:13.380 --> 00:51:15.540
So let's continue on.

00:51:19.150 --> 00:51:19.720
Yeah.

00:51:19.720 --> 00:51:22.842
So now what we're going to do,
we're going to prove our one--

00:51:22.842 --> 00:51:24.550
so far we really
haven't proved anything,

00:51:24.550 --> 00:51:27.580
we've just given some
definitions and some examples.

00:51:27.580 --> 00:51:30.160
Today was going to-- now
we're going to come to our big

00:51:30.160 --> 00:51:34.510
theorem, which actually is
important and has some meat

00:51:34.510 --> 00:51:38.110
to it, and that is,
how do we convert--

00:51:38.110 --> 00:51:41.080
I claim that context-free
grammars and pushdown

00:51:41.080 --> 00:51:42.920
automata are equivalent.

00:51:42.920 --> 00:51:45.940
Well, we're going to prove that
equivalence in one direction,

00:51:45.940 --> 00:51:49.750
converting the grammars
to pushdown automata.

00:51:49.750 --> 00:51:53.860
So let me show
you how that goes.

00:51:53.860 --> 00:51:57.460
In some ways-- and
it's a nice proof,

00:51:57.460 --> 00:52:02.270
not super complicated, but
it has some meat to it.

00:52:02.270 --> 00:52:04.810
So if I give you a
grammar here, what

00:52:04.810 --> 00:52:07.630
I'm going to tell you how to
do is convert that grammar

00:52:07.630 --> 00:52:10.195
into pushdown automaton,
which does the same language.

00:52:12.750 --> 00:52:15.850
So if you were checked
out for a minute,

00:52:15.850 --> 00:52:18.810
please come back because
we're starting this topic now,

00:52:18.810 --> 00:52:22.770
that you can think about
this as a good re-entry

00:52:22.770 --> 00:52:26.280
point if you've been doing
something else, which

00:52:26.280 --> 00:52:30.270
I can't tell, a good thing.

00:52:30.270 --> 00:52:34.440
So converting a given grammar
to a pushdown automaton,

00:52:34.440 --> 00:52:36.070
how is that going to work?

00:52:36.070 --> 00:52:38.130
So the idea is--

00:52:38.130 --> 00:52:41.720
OK-- actually, before
I tell you the idea,

00:52:41.720 --> 00:52:45.100
let's just think
about it together.

00:52:45.100 --> 00:52:47.710
Again, I like to think about
the pushdown automaton,

00:52:47.710 --> 00:52:51.210
building a pushdown automaton
the way you would do it.

00:52:51.210 --> 00:52:54.860
So a grammar is a
generation device.

00:52:54.860 --> 00:52:56.420
It generates strings.

00:52:56.420 --> 00:52:59.480
A pushdown automaton-- or
thinking about it as you,

00:52:59.480 --> 00:53:00.755
you are recognizing it.

00:53:00.755 --> 00:53:02.630
You are given an input,
and you want to know,

00:53:02.630 --> 00:53:03.770
is it in the language?

00:53:03.770 --> 00:53:07.850
So you want to know, is it
possible for that grammar

00:53:07.850 --> 00:53:10.290
to generate that
input you're given?

00:53:10.290 --> 00:53:11.750
So how are you going--

00:53:11.750 --> 00:53:14.270
how are you going to do that?

00:53:14.270 --> 00:53:22.480
And how are you going
to test if the input is

00:53:22.480 --> 00:53:25.408
in the language of the grammar?

00:53:25.408 --> 00:53:27.200
Well, the thing that
you would naturally do

00:53:27.200 --> 00:53:30.178
is you'd say, well, can I
derive that string using

00:53:30.178 --> 00:53:31.220
the rules of the grammar?

00:53:31.220 --> 00:53:33.320
Let me start with
the start string

00:53:33.320 --> 00:53:36.650
and try to do
substitutions and see

00:53:36.650 --> 00:53:39.620
if I get the string I'm given.

00:53:39.620 --> 00:53:43.540
And if I can get it, then I
know it's in the language.

00:53:43.540 --> 00:53:44.990
That's a natural thing to do.

00:53:44.990 --> 00:53:48.430
You're just going to try
to do the substitution see

00:53:48.430 --> 00:53:49.670
if you can get to the string.

00:53:49.670 --> 00:53:52.930
Now the thing is, there might
be many different substitutions

00:53:52.930 --> 00:53:54.170
that you could make.

00:53:54.170 --> 00:53:57.413
And that seems like a really
challenging, hard thing

00:53:57.413 --> 00:53:59.080
to figure out which
substitutions to use

00:53:59.080 --> 00:54:00.640
among the many possibilities.

00:54:00.640 --> 00:54:02.260
That's where
non-determinism is going

00:54:02.260 --> 00:54:05.720
to come in because you can
think of yourself as guessing

00:54:05.720 --> 00:54:06.930
which substitutions to make.

00:54:06.930 --> 00:54:09.090
And you're always going
to make the right guess.

00:54:09.090 --> 00:54:12.030
So the choices of which
substitutions to make,

00:54:12.030 --> 00:54:14.220
that's not going to
be a problem for you.

00:54:14.220 --> 00:54:16.360
That's going to be managed
by the non-determinism.

00:54:16.360 --> 00:54:19.260
So imagine you're always going
to make the right substitution,

00:54:19.260 --> 00:54:21.390
but now the challenge
is, how do you

00:54:21.390 --> 00:54:24.660
keep track of the
intermediate results

00:54:24.660 --> 00:54:26.490
as you're doing
those substitutions?

00:54:30.310 --> 00:54:33.910
And that's where the
stack is going to come in.

00:54:33.910 --> 00:54:37.360
The machine is going to write
down those intermediate results

00:54:37.360 --> 00:54:39.480
on the stack.

00:54:39.480 --> 00:54:42.210
But even there,
there's a subtlety.

00:54:42.210 --> 00:54:45.160
That's an important subtlety
that you have to look at.

00:54:45.160 --> 00:54:47.710
So let's try pulling
that together

00:54:47.710 --> 00:54:51.090
so far before I get
to that subtlety.

00:54:51.090 --> 00:54:57.280
So as I mentioned,
the pushdown automaton

00:54:57.280 --> 00:54:59.500
is going to start out
with a starting variable

00:54:59.500 --> 00:55:02.110
and is going to be guessing
the substitutions to make.

00:55:02.110 --> 00:55:04.390
It's going to keep the
intermediate results

00:55:04.390 --> 00:55:05.650
on the stack.

00:55:05.650 --> 00:55:07.790
When it's done doing
all the substitutions

00:55:07.790 --> 00:55:10.180
and it has only terminal
strings on the stack,

00:55:10.180 --> 00:55:11.770
it can compare with
the input and see

00:55:11.770 --> 00:55:15.100
if it got the right thing, so if
it made all the right guesses.

00:55:15.100 --> 00:55:17.590
So you think of it
as guessing, doing

00:55:17.590 --> 00:55:19.060
the right guesses,
but in the end

00:55:19.060 --> 00:55:21.730
you have to check to make
sure that you got the right--

00:55:21.730 --> 00:55:23.147
that you did all
the right things,

00:55:23.147 --> 00:55:26.950
and you will accept when
things have matched up,

00:55:26.950 --> 00:55:28.497
and you made all
the right guesses.

00:55:28.497 --> 00:55:30.580
So in the end, you have
to check that you actually

00:55:30.580 --> 00:55:37.230
got that input from doing
those substitutions.

00:55:37.230 --> 00:55:41.940
So let's try to see this
operating in action.

00:55:41.940 --> 00:55:47.835
And then you'll see the
subtlety, the delicacy,

00:55:47.835 --> 00:55:50.010
a problem that's going to arise.

00:55:50.010 --> 00:55:52.140
Hopefully you're following,
at least in part,

00:55:52.140 --> 00:55:54.270
what I'm saying so far.

00:55:54.270 --> 00:55:56.520
So here is the input.

00:55:56.520 --> 00:55:59.040
We do know that that's
an input in the language

00:55:59.040 --> 00:56:01.538
that-- we've been seeing
this example multiple times.

00:56:01.538 --> 00:56:03.330
So here is the input
appearing on the input

00:56:03.330 --> 00:56:06.480
tape, a plus a times a.

00:56:06.480 --> 00:56:08.510
And now the pushdown
automaton is

00:56:08.510 --> 00:56:11.088
supposed to be accepting
that input because it's

00:56:11.088 --> 00:56:12.380
in the language of the grammar.

00:56:14.920 --> 00:56:18.160
So it's going to operate
by first writing,

00:56:18.160 --> 00:56:22.690
to start off, the starting
variable on the stack,

00:56:22.690 --> 00:56:25.960
and then doing the substitutions
as we're going along.

00:56:25.960 --> 00:56:33.020
So we're going to substitute
E goes to E plus T.

00:56:33.020 --> 00:56:35.990
So we do that
first substitution.

00:56:35.990 --> 00:56:40.740
And then we do the next
substitution here, the E--

00:56:40.740 --> 00:56:43.640
so if you're looking
at this tree here,

00:56:43.640 --> 00:56:48.450
this is the right
tree for that input.

00:56:48.450 --> 00:56:52.790
So we substitute E
by T. So far so good.

00:56:52.790 --> 00:56:55.760
The automaton can make
that substitution.

00:56:55.760 --> 00:56:59.330
Then the next substitution
is going to be a little--

00:56:59.330 --> 00:57:02.630
so where E plus T,
we substitute here.

00:57:02.630 --> 00:57:06.410
We got T plus T. And now we're
going to substitute the T times

00:57:06.410 --> 00:57:08.630
F, which is this T over here.

00:57:08.630 --> 00:57:10.340
We want to substitute that.

00:57:10.340 --> 00:57:15.410
And that appears as T times
as F now on the stack.

00:57:15.410 --> 00:57:17.680
Now, if you're
following me, you should

00:57:17.680 --> 00:57:25.260
be suddenly getting nervous
because we just cheated.

00:57:25.260 --> 00:57:30.150
It's OK doing substitution--
doing these replacements

00:57:30.150 --> 00:57:33.570
at the very top of the stack
because the pushdown automaton

00:57:33.570 --> 00:57:35.190
has access to the top.

00:57:35.190 --> 00:57:37.570
That's how stacks work.

00:57:37.570 --> 00:57:41.140
But it does not have access
deep down within this deck.

00:57:41.140 --> 00:57:44.540
That is not how--

00:57:44.540 --> 00:57:45.830
that is not how stacks work.

00:57:45.830 --> 00:57:47.640
So that's cheating.

00:57:47.640 --> 00:57:50.460
But ignoring the
cheating for the minute,

00:57:50.460 --> 00:57:54.300
if you could replace those--

00:57:54.300 --> 00:57:57.180
do those substitutions
deep down within the stack,

00:57:57.180 --> 00:57:58.110
this would all work.

00:57:58.110 --> 00:57:58.920
We would be good.

00:57:58.920 --> 00:58:01.980
You would do the substitutions
one after another

00:58:01.980 --> 00:58:05.790
until you ended up
with no variables,

00:58:05.790 --> 00:58:07.350
and then you have
the string here,

00:58:07.350 --> 00:58:09.720
and you're going to match it off
and compare it with the input.

00:58:09.720 --> 00:58:11.970
It's all done in the right
way so that the things are

00:58:11.970 --> 00:58:16.800
in the right order so after
all the substitutions,

00:58:16.800 --> 00:58:19.567
you'd have a plus a times a
sitting here in the stack,

00:58:19.567 --> 00:58:21.900
you compare that with the
input, it's going to match up,

00:58:21.900 --> 00:58:24.120
and you'll end up
accepting, all good.

00:58:24.120 --> 00:58:26.235
So how do we deal with
that problem here?

00:58:26.235 --> 00:58:30.870
The problem, access below
the top of stack is cheating.

00:58:30.870 --> 00:58:33.580
What are we going to do instead?

00:58:33.580 --> 00:58:35.520
So the idea is
actually pretty simple.

00:58:35.520 --> 00:58:39.180
Well, if you understood what
I've said so far, fixing

00:58:39.180 --> 00:58:40.890
that is actually not too bad.

00:58:45.060 --> 00:58:47.715
Sort of fading out here.

00:58:47.715 --> 00:58:52.150
I'll put some more
light on my image.

00:58:52.150 --> 00:58:55.480
So how do we do that?

00:58:55.480 --> 00:58:57.720
How do we get the
effect of the access

00:58:57.720 --> 00:58:59.980
below the top of the stack?

00:58:59.980 --> 00:59:03.250
And the way we're
going to do that is

00:59:03.250 --> 00:59:06.820
by making the-- what we're going
to do, we're only going to do

00:59:06.820 --> 00:59:09.208
substitutions that we can
make at the top of the stack.

00:59:09.208 --> 00:59:11.500
So whenever there's a variable
at the top of the stack,

00:59:11.500 --> 00:59:12.917
we're going to do
the substitution

00:59:12.917 --> 00:59:16.000
because the top we can access.

00:59:16.000 --> 00:59:18.430
Now what happens if we have
a terminal symbol sitting

00:59:18.430 --> 00:59:23.590
at the top blocking our way
from accessing variables below?

00:59:23.590 --> 00:59:25.810
Well, actually,
that's an easy case

00:59:25.810 --> 00:59:28.270
to handle because we have
a terminal symbol sitting

00:59:28.270 --> 00:59:30.680
at the top, they're never
going to change anyway,

00:59:30.680 --> 00:59:34.120
so you might as well match them
with the input at that time.

00:59:37.340 --> 00:59:40.330
So when you have a terminal
sitting at the top,

00:59:40.330 --> 00:59:45.130
we'll just read another input
symbol and match it off there.

00:59:45.130 --> 00:59:47.470
And we just keep reading
the terminal symbols off

00:59:47.470 --> 00:59:49.690
until we have a variable
sitting on the top,

00:59:49.690 --> 00:59:53.593
then we do a substitution.

00:59:53.593 --> 00:59:55.010
And we keep
substituting variables

00:59:55.010 --> 00:59:56.760
until we have a terminal,
then we read it,

00:59:56.760 --> 00:59:58.260
then we compare
it with the input.

00:59:58.260 --> 01:00:02.120
And in so doing, we will end
up getting the same effect

01:00:02.120 --> 01:00:04.130
that I described
before without ever

01:00:04.130 --> 01:00:08.400
needing to dig down into
the interior of the stack

01:00:08.400 --> 01:00:09.650
and doing substitutions there.

01:00:09.650 --> 01:00:11.960
They're all going to
rise up to the top.

01:00:11.960 --> 01:00:16.590
And we can always
do them at the top.

01:00:16.590 --> 01:00:19.780
So anyway, I forgot
to do that here.

01:00:19.780 --> 01:00:21.930
So instead, only
substitute variables

01:00:21.930 --> 01:00:24.090
when they're at the
top of the stack.

01:00:24.090 --> 01:00:27.090
If a terminal's on the top, pop
it and compare with the input,

01:00:27.090 --> 01:00:28.510
reject it if they're not equal.

01:00:28.510 --> 01:00:30.450
So if you ever have
something which is not

01:00:30.450 --> 01:00:31.867
matching the way
it's supposed to,

01:00:31.867 --> 01:00:35.070
I mean, that thread's
just going to fail.

01:00:35.070 --> 01:00:39.437
Then there was not a-- a bad
non-deterministic choice was

01:00:39.437 --> 01:00:41.770
made, or maybe the input was
not in the language anyway,

01:00:41.770 --> 01:00:44.980
and there were no good choices.

01:00:44.980 --> 01:00:48.900
So my animation broke here, so
let me just put the whole thing

01:00:48.900 --> 01:00:50.260
up in front of you.

01:00:50.260 --> 01:00:54.790
So here is the
actual construction.

01:00:54.790 --> 01:00:57.070
Push the start
symbol on the stack.

01:00:57.070 --> 01:00:59.650
If the top of the
stack is a variable,

01:00:59.650 --> 01:01:02.320
replace it with a
corresponding right-hand side,

01:01:02.320 --> 01:01:04.090
doing a non-deterministic
choice among

01:01:04.090 --> 01:01:05.980
the various possibilities.

01:01:05.980 --> 01:01:07.780
If it's a terminal,
you pop it and match it

01:01:07.780 --> 01:01:08.905
with the next input symbol.

01:01:08.905 --> 01:01:11.450
And if the stack is
empty, you accept.

01:01:11.450 --> 01:01:13.640
So here is how the
stack would actually

01:01:13.640 --> 01:01:16.613
look for this particular input.

01:01:16.613 --> 01:01:17.780
It would start off the same.

01:01:17.780 --> 01:01:20.330
You'd have E, and then
substitute with E plus T.

01:01:20.330 --> 01:01:23.750
And then we're
going to always do

01:01:23.750 --> 01:01:25.670
the substitutions at the top.

01:01:25.670 --> 01:01:28.670
So E gets substituted by F

01:01:28.670 --> 01:01:29.870
Is that right?

01:01:29.870 --> 01:01:30.920
No.

01:01:30.920 --> 01:01:32.630
This slide I messed up.

01:01:32.630 --> 01:01:33.360
I apologize.

01:01:33.360 --> 01:01:38.210
So E gets substituted by T,
which gets substituted by F.

01:01:38.210 --> 01:01:40.070
And the point is
that when you get

01:01:40.070 --> 01:01:42.170
to an A sitting at the top--

01:01:42.170 --> 01:01:46.070
forgive the typos here, now
we have a terminal symbol,

01:01:46.070 --> 01:01:50.760
and that's going to get matched
off with the next input symbol

01:01:50.760 --> 01:01:51.780
and get removed.

01:01:51.780 --> 01:01:54.450
And now we have just
the plus and the T left.

01:01:54.450 --> 01:01:56.393
And then the plus is
also a terminal symbol.

01:01:56.393 --> 01:01:58.560
That's going to get matched
off with the next thing.

01:01:58.560 --> 01:02:00.130
We just have a T
sitting on the top,

01:02:00.130 --> 01:02:02.800
and now we can do
a substitution.

01:02:02.800 --> 01:02:06.250
So that's how it works.

01:02:06.250 --> 01:02:08.445
That's all I wanted
to say, I think.

01:02:08.445 --> 01:02:10.870
Oh, yeah, there's
one just remark.

01:02:10.870 --> 01:02:12.380
So we're not going
to prove this,

01:02:12.380 --> 01:02:16.300
but I do need to say
this, that actually you

01:02:16.300 --> 01:02:20.290
can do the conversion in
the other direction, too.

01:02:20.290 --> 01:02:22.030
You can convert a--

01:02:25.010 --> 01:02:28.640
so a is a context-free
language if and only

01:02:28.640 --> 01:02:32.360
if some pushdown
automaton recognizes a.

01:02:32.360 --> 01:02:37.850
And if you haven't seen if and
only if, it's an expression

01:02:37.850 --> 01:02:41.930
I'm going to use,
again, over and over.

01:02:41.930 --> 01:02:43.310
So you should get used to it.

01:02:43.310 --> 01:02:45.500
It stands for "if and
only if," and which just

01:02:45.500 --> 01:02:47.700
means the implication
goes both ways.

01:02:47.700 --> 01:02:51.260
So "a is a
context-free language"

01:02:51.260 --> 01:02:53.900
implies that some pushdown
automaton recognizes

01:02:53.900 --> 01:02:56.910
a and vice versa.

01:02:56.910 --> 01:02:59.315
So there's really two things
you need to prove whenever

01:02:59.315 --> 01:03:00.440
you have an if and only if.

01:03:00.440 --> 01:03:03.360
You have to prove
both directions.

01:03:03.360 --> 01:03:07.610
So thinking about it that
way, splitting them in half,

01:03:07.610 --> 01:03:10.490
the forward direction
we've already proved,

01:03:10.490 --> 01:03:12.110
converting a pushdown--

01:03:12.110 --> 01:03:16.280
a context-free grammar
to a pushdown automaton.

01:03:16.280 --> 01:03:18.320
The reverse direction
we're not going to prove.

01:03:18.320 --> 01:03:20.480
It's in the book
if you're curious,

01:03:20.480 --> 01:03:23.390
and you are responsible
knowing that the fact is true,

01:03:23.390 --> 01:03:26.668
but you don't have to know the
proof, which is a somewhat--

01:03:26.668 --> 01:03:27.710
a little bit complicated.

01:03:27.710 --> 01:03:30.740
And I think it would take us
too long to go through it,

01:03:30.740 --> 01:03:34.830
so you're not
responsible for it.

01:03:34.830 --> 01:03:36.620
So there's a last
check in here that I

01:03:36.620 --> 01:03:40.670
have for you, which is
just a question, which

01:03:40.670 --> 01:03:42.350
you can answer based
on the material

01:03:42.350 --> 01:03:44.000
that we presented so far.

01:03:44.000 --> 01:03:49.150
Is every regular language
also a context-free language?

01:03:49.150 --> 01:03:52.300
Just "yes," "no,"
or you're not sure.

01:03:52.300 --> 01:03:56.040
So let me launch
that as a poll here.

01:03:56.040 --> 01:03:57.075
OK, about to close.

01:03:59.900 --> 01:04:04.010
A new polling, and
sharing results.

01:04:06.600 --> 01:04:08.970
This one, I think,
you pretty much--

01:04:08.970 --> 01:04:10.170
most of you got.

01:04:10.170 --> 01:04:14.550
Some of you are not sure.

01:04:14.550 --> 01:04:19.560
Every language is in fact
a context-free language.

01:04:19.560 --> 01:04:22.800
And the way to see that is
that every regular language

01:04:22.800 --> 01:04:27.600
can be done by a DFA or an
NFA, as we already showed.

01:04:27.600 --> 01:04:32.400
And a DFA or an NFA is really
just a pushdown automaton

01:04:32.400 --> 01:04:35.430
that never uses its stack.

01:04:35.430 --> 01:04:40.080
So you can always think of a
DFA as a pushdown automaton.

01:04:40.080 --> 01:04:43.050
And we already argue that
pushdown automata are

01:04:43.050 --> 01:04:45.120
equivalent to
context-free grammars,

01:04:45.120 --> 01:04:48.170
and so they do the
context-free languages.

01:04:48.170 --> 01:04:50.360
So anything that you
can do with a DFA

01:04:50.360 --> 01:04:52.490
you can also do with
a pushdown automaton,

01:04:52.490 --> 01:04:57.380
and so therefore all the
regular languages are also

01:04:57.380 --> 01:04:59.540
context-free languages.

01:04:59.540 --> 01:05:04.220
So with that, let's just
pull things together,

01:05:04.220 --> 01:05:06.050
a little quick recap
as to what we've

01:05:06.050 --> 01:05:07.640
been doing so far in the class.

01:05:07.640 --> 01:05:10.970
We have the regular languages
and the context-free languages.

01:05:10.970 --> 01:05:13.550
We had the two forms
of getting at them,

01:05:13.550 --> 01:05:16.340
the recognizer form, which
is like the automata-based

01:05:16.340 --> 01:05:19.250
perspective, like
either a DFA or an NFA

01:05:19.250 --> 01:05:21.620
in the case of the regular
languages, the pushdown

01:05:21.620 --> 01:05:24.410
automaton for the
context-free languages.

01:05:24.410 --> 01:05:28.400
And for the generators, we
had the regular expression

01:05:28.400 --> 01:05:31.220
for the regular languages and
the context-free grammars--

01:05:31.220 --> 01:05:35.390
for the context-free languages.

01:05:35.390 --> 01:05:39.440
And as we just pointed
out in our last check-in,

01:05:39.440 --> 01:05:42.560
the regular languages form
a subset and, in fact,

01:05:42.560 --> 01:05:46.130
a proper subset of the
context-free languages,

01:05:46.130 --> 01:05:48.650
as shown in this Venn diagram
because we have already

01:05:48.650 --> 01:05:51.860
exhibited languages that are
context-free but not regular.

01:05:55.330 --> 01:05:56.650
So a quick review.

01:05:56.650 --> 01:05:58.750
We've defined the
context-free grammars

01:05:58.750 --> 01:06:01.690
and their associated languages,
the context-free languages;

01:06:01.690 --> 01:06:04.180
we defined pushdown
automata; and we

01:06:04.180 --> 01:06:06.430
showed how to convert
context-free grammars

01:06:06.430 --> 01:06:09.290
to pushdown automata.

01:06:09.290 --> 01:06:11.842
And that's all I
have for you today.

01:06:11.842 --> 01:06:13.800
But here's a question
I'll answer to everybody.

01:06:13.800 --> 01:06:15.467
Why do we restrict
ourselves to a stack?

01:06:15.467 --> 01:06:17.170
Why don't we use
random access memory?

01:06:17.170 --> 01:06:21.570
We will use random access
memory for the next model,

01:06:21.570 --> 01:06:22.650
called a Turing machine.

01:06:22.650 --> 01:06:26.380
And we're going to introduce
that I think the next lecture.

01:06:26.380 --> 01:06:29.160
So that's going to be
the model that we're

01:06:29.160 --> 01:06:30.930
going to stick with
throughout the term.

01:06:30.930 --> 01:06:33.480
But we have not--

01:06:33.480 --> 01:06:38.790
we were introducing weaker
models as a kind of prelude

01:06:38.790 --> 01:06:44.940
to the more general-purpose
computational model really

01:06:44.940 --> 01:06:52.110
to get ourselves warmed up and
also because, for the weaker

01:06:52.110 --> 01:06:57.775
models, you can fully analyze
them in a way that you cannot

01:06:57.775 --> 01:07:00.520
for Turing machines.

01:07:00.520 --> 01:07:06.940
As you will see, you
can determine properties

01:07:06.940 --> 01:07:09.760
of languages for the weaker
models that you cannot

01:07:09.760 --> 01:07:11.680
for the more general models.

01:07:11.680 --> 01:07:15.940
And so I think that's helpful
to have that perspective,

01:07:15.940 --> 01:07:20.590
that for some cases, you
can get a full analysis,

01:07:20.590 --> 01:07:23.110
in some other cases you cannot.

01:07:23.110 --> 01:07:27.100
But anyway, that's the
reason why we restrict it

01:07:27.100 --> 01:07:29.410
to the stack, besides the
fact that these models have

01:07:29.410 --> 01:07:36.160
applications that I think
are worth people seeing.

01:07:36.160 --> 01:07:39.610
Why-- yeah, for some
reason we chose a stack?

01:07:39.610 --> 01:07:41.680
Well, why did we
choose a stack and not

01:07:41.680 --> 01:07:45.070
some other data structure
for our temporary--

01:07:45.070 --> 01:07:47.590
for our extra storage?

01:07:47.590 --> 01:07:51.460
And the reason for a stack,
for one thing, the stack

01:07:51.460 --> 01:07:53.720
is exactly what you need to
get you the correspondence

01:07:53.720 --> 01:07:54.845
with context-free grammars.

01:07:57.750 --> 01:08:03.280
If we used some other
storage, like a queue,

01:08:03.280 --> 01:08:05.740
for example, instead
of a stack, in fact,

01:08:05.740 --> 01:08:07.540
you get a very
different outcome.

01:08:07.540 --> 01:08:11.545
And it's an actually interesting
exercise to see what happens.

01:08:11.545 --> 01:08:15.010
What do you get if you use a
queue as an external storage

01:08:15.010 --> 01:08:17.042
instead of as a stack?

01:08:17.042 --> 01:08:18.250
It's a good homework problem.

01:08:18.250 --> 01:08:21.189
Maybe I'll assign it.

01:08:21.189 --> 01:08:21.984
Let's see.

01:08:24.660 --> 01:08:26.859
And if a--

01:08:26.859 --> 01:08:28.840
OK.

01:08:28.840 --> 01:08:35.109
We showed-- so we showed
that non-determinism can be

01:08:35.109 --> 01:08:36.800
eliminated for finite automata.

01:08:36.800 --> 01:08:39.729
So NFAs and DFAs are equivalent.

01:08:39.729 --> 01:08:42.432
What about for
pushdown automata?

01:08:42.432 --> 01:08:44.140
The answer is no,
they're not equivalent.

01:08:44.140 --> 01:08:45.515
I think I mentioned
that earlier,

01:08:45.515 --> 01:08:47.529
but I don't mind repeating it.

01:08:47.529 --> 01:08:50.710
There are certain languages
that can be done only with

01:08:50.710 --> 01:08:53.680
non-deterministic pushdown
automata and cannot be done

01:08:53.680 --> 01:08:55.750
with deterministic
pushdown automata,

01:08:55.750 --> 01:08:59.800
for example that language
ww reverse that requires

01:08:59.800 --> 01:09:02.620
the non-determinism in order for
the machine to be able to guess

01:09:02.620 --> 01:09:04.060
where the middle is.

01:09:04.060 --> 01:09:07.149
So, OK, I'm going to head off.

01:09:07.149 --> 01:09:10.529
Thank you, guys, and
see you on Tuesday.