WEBVTT

00:00:02.190 --> 00:00:02.550
[MUSIC PLAYING - "JESU, JOY OF
MAN'S DESIRING" BY JOHANN

00:00:02.550 --> 00:00:03.800
SEBASTIAN BACH]

00:00:17.260 --> 00:00:20.520
PROFESSOR: Well, up 'til now, I
suppose, we've been learning

00:00:20.520 --> 00:00:26.690
about a lot of techniques for
organizing big programs,

00:00:26.690 --> 00:00:33.180
symbolic manipulation a bit,
some of the technology that

00:00:33.180 --> 00:00:36.250
you use for establishing
languages, one in terms of

00:00:36.250 --> 00:00:39.340
another, which is used for
organizing very large

00:00:39.340 --> 00:00:43.160
programs. In fact, the nicest
programs I know look more like

00:00:43.160 --> 00:00:47.310
a pile of languages than like
a decomposition of a problem

00:00:47.310 --> 00:00:49.900
into parts.

00:00:49.900 --> 00:00:52.880
Well, I suppose at this point,
there are still, however, a

00:00:52.880 --> 00:00:56.260
few mysteries about how this
sort of stuff works.

00:00:56.260 --> 00:01:02.410
And so what we'd like to do now
is diverge from the plan

00:01:02.410 --> 00:01:06.060
of telling you how to organize
big programs, and rather tell

00:01:06.060 --> 00:01:09.870
you something about the
mechanisms by which these

00:01:09.870 --> 00:01:12.196
things can be made to work.

00:01:12.196 --> 00:01:18.652
The main reason for this is
demystification, if you will,

00:01:18.652 --> 00:01:21.930
that we have a lot of mysteries
left, like exactly

00:01:21.930 --> 00:01:27.260
how it is the case that a
program is controlled, how a

00:01:27.260 --> 00:01:30.760
computer knows what the next
thing to do is, or

00:01:30.760 --> 00:01:32.430
something like that.

00:01:32.430 --> 00:01:36.410
And what I'd like to do now is
make that clear to you, that

00:01:36.410 --> 00:01:38.580
even if you've never played
with a physical computer

00:01:38.580 --> 00:01:44.660
before, the mechanism is really
very simple, and that

00:01:44.660 --> 00:01:47.650
you can understand it completely
with no trouble.

00:01:47.650 --> 00:01:51.390
So I'd like to start by
imagining that we--

00:01:51.390 --> 00:01:53.190
well, the way we're going to do
this, by the way, is we're

00:01:53.190 --> 00:01:57.320
going to take some very simple
Lisp programs, very simple

00:01:57.320 --> 00:02:02.160
Lisp programs, and transform
them into hardware.

00:02:02.160 --> 00:02:05.260
I'm not going to worry about
some intermediate step of

00:02:05.260 --> 00:02:07.560
going through some existing
computer machine language and

00:02:07.560 --> 00:02:10.960
then showing you how that
computer works, because that's

00:02:10.960 --> 00:02:12.750
not as illuminating.

00:02:12.750 --> 00:02:16.310
So what I'm really going to
show you is how a piece of

00:02:16.310 --> 00:02:21.130
machinery can be built to do a
job that you have written down

00:02:21.130 --> 00:02:22.040
as a program.

00:02:22.040 --> 00:02:25.760
That program is, in fact, a
description of a machine.

00:02:25.760 --> 00:02:28.600
We're going to start with a very
simple program, proceed

00:02:28.600 --> 00:02:32.250
to show you some simple
mechanisms, proceed to a few

00:02:32.250 --> 00:02:36.660
more complicated programs, and
then later show you a not very

00:02:36.660 --> 00:02:40.360
complicated program, how the
evaluator transforms into a

00:02:40.360 --> 00:02:41.230
piece of hardware.

00:02:41.230 --> 00:02:43.390
And of course at that point,
you have made the universal

00:02:43.390 --> 00:02:47.510
transition and can execute any
program imaginable with a

00:02:47.510 --> 00:02:48.800
piece of well-defined
hardware.

00:02:51.392 --> 00:02:54.320
Well, let's start up now, give
you a real concrete feeling

00:02:54.320 --> 00:02:55.440
for this sort of thing.

00:02:55.440 --> 00:02:59.600
Let's start with a very
simple program.

00:02:59.600 --> 00:03:00.850
Here's Euclid's algorithm.

00:03:03.880 --> 00:03:06.140
It's actually a little
bit more modern

00:03:06.140 --> 00:03:06.770
than Euclid's algorithm.

00:03:06.770 --> 00:03:09.010
Euclid's algorithm for computing
the greatest common

00:03:09.010 --> 00:03:14.300
divisor of two numbers was
invented 350 BC, I think.

00:03:14.300 --> 00:03:15.550
It's the oldest known
algorithm.

00:03:19.320 --> 00:03:23.440
But here we're going to talk
about GCD of A and B, the

00:03:23.440 --> 00:03:27.380
Greatest Common Divisor or two
numbers, A and B. And the

00:03:27.380 --> 00:03:29.500
algorithm is extremely simple.

00:03:29.500 --> 00:03:38.170
If B is 0, then the result is
going to be A. Otherwise, the

00:03:38.170 --> 00:03:52.990
result is the GCD of B and the
remainder when A is divided by

00:03:52.990 --> 00:03:58.530
B.

00:03:58.530 --> 00:04:02.030
So this we have here is a very
simple iterative process.

00:04:02.030 --> 00:04:05.550
This a simple recursive
procedure, recursively defined

00:04:05.550 --> 00:04:08.340
procedure, recursive definition,
which yields an

00:04:08.340 --> 00:04:09.990
iterative process.

00:04:09.990 --> 00:04:13.840
And the way it works is that
every step, it determines

00:04:13.840 --> 00:04:15.996
whether B was zero.

00:04:15.996 --> 00:04:21.660
And if B is 0, we got the answer
in A. Otherwise, we

00:04:21.660 --> 00:04:25.060
make another step where A is
the old B, and B is the

00:04:25.060 --> 00:04:31.110
remainder of the old A divided
by the old B. Very simple.

00:04:31.110 --> 00:04:33.900
Now this, I've already told you
some of the mechanism by

00:04:33.900 --> 00:04:34.860
just saying it that way.

00:04:34.860 --> 00:04:36.360
I set it in time.

00:04:36.360 --> 00:04:39.710
I said there are certain steps,
and that, in fact, one

00:04:39.710 --> 00:04:42.510
of the things you can see here
is that one of the reasons why

00:04:42.510 --> 00:04:46.960
this is iterative is nothing is
needed of the last step to

00:04:46.960 --> 00:04:49.490
get the answer.

00:04:49.490 --> 00:04:54.230
All of the information that's
needed to run this algorithm

00:04:54.230 --> 00:04:57.540
is in A and B. It has two
well-defined state variables.

00:05:00.470 --> 00:05:04.370
So I'm going to define a machine
for you that can

00:05:04.370 --> 00:05:06.560
compute you GCDs.

00:05:06.560 --> 00:05:07.120
Now let's see.

00:05:07.120 --> 00:05:10.010
Every computer that's ever
been made that's a

00:05:10.010 --> 00:05:13.490
single-process computer, as
opposed to a multiprocessor of

00:05:13.490 --> 00:05:17.840
some sort, is made according
to the same plan.

00:05:17.840 --> 00:05:21.630
The plan is the computer has two
parts, a part called the

00:05:21.630 --> 00:05:25.910
datapaths, and a part called
the controller.

00:05:25.910 --> 00:05:28.960
The datapaths correspond to a
calculator that you might

00:05:28.960 --> 00:05:31.580
have. It contains certain
registers that remember

00:05:31.580 --> 00:05:33.560
things, and you've all
used calculators.

00:05:33.560 --> 00:05:37.030
It has some buttons on
it and some lights.

00:05:37.030 --> 00:05:39.010
And so by pushing the various
buttons, you can cause

00:05:39.010 --> 00:05:42.080
operations to happen inside
there among the registers, and

00:05:42.080 --> 00:05:45.160
some of the results
to be displayed.

00:05:45.160 --> 00:05:46.250
That's completely mechanical.

00:05:46.250 --> 00:05:50.900
You could imagine that box has
no intelligence in it.

00:05:50.900 --> 00:05:52.400
Now it might be very impressive
that it can produce

00:05:52.400 --> 00:05:57.670
the sine of a number, but that
at least is apparently

00:05:57.670 --> 00:05:58.970
possibly mechanical.

00:05:58.970 --> 00:06:00.685
At least, I could open that
up in the same way I'm

00:06:00.685 --> 00:06:02.690
about to open GCD.

00:06:02.690 --> 00:06:04.830
So this may have a whole
computer inside of it, but

00:06:04.830 --> 00:06:05.940
that's not interesting.

00:06:05.940 --> 00:06:08.200
Addition is certainly simple.

00:06:08.200 --> 00:06:10.890
That can be done without
any further mechanism.

00:06:10.890 --> 00:06:15.080
Now also, if we were to look
at the other half, the

00:06:15.080 --> 00:06:18.190
controller, that's a part
that's dumb, too.

00:06:18.190 --> 00:06:20.350
It pushes the buttons.

00:06:20.350 --> 00:06:21.920
It pushes them according to the
sequence, which is written

00:06:21.920 --> 00:06:26.290
down on a piece of paper,
and observes the lights.

00:06:26.290 --> 00:06:29.210
And every so often, it comes to
a place in a sequence that

00:06:29.210 --> 00:06:32.370
says, if light A is on,
do this sequence.

00:06:32.370 --> 00:06:34.620
Otherwise, do that sequence.

00:06:34.620 --> 00:06:37.950
And thereby, there's no
complexity there either.

00:06:37.950 --> 00:06:42.510
Well, let's just draw that and
see what we feel about that.

00:06:42.510 --> 00:06:48.270
So for computing GCDs, what I
want you to think about is

00:06:48.270 --> 00:06:50.310
that there are these
registers.

00:06:50.310 --> 00:06:53.240
A register is a place where I
store a number, in this case.

00:06:53.240 --> 00:06:56.810
And this one's called a.

00:06:56.810 --> 00:06:58.700
And then there's another
one for storing b.

00:07:03.170 --> 00:07:04.820
Now we have to see what things
we can do with these

00:07:04.820 --> 00:07:08.150
registers, and they're not
entirely obvious what you can

00:07:08.150 --> 00:07:09.840
do with them.

00:07:09.840 --> 00:07:10.940
Well, we have to see
what things we

00:07:10.940 --> 00:07:11.890
need to do with them.

00:07:11.890 --> 00:07:14.030
We're looking at the problem
we're trying to solve.

00:07:14.030 --> 00:07:17.100
One of the important things
for designing a computer,

00:07:17.100 --> 00:07:20.810
which I think most designers
don't do, is you study the

00:07:20.810 --> 00:07:23.910
problem you want to solve and
then use what you learn from

00:07:23.910 --> 00:07:25.970
studying the problem you want
to solve to put in the

00:07:25.970 --> 00:07:28.260
mechanisms needed to solve
it in the computer you're

00:07:28.260 --> 00:07:32.140
building, no more no less.

00:07:32.140 --> 00:07:34.440
Now it may be that the problem
you're trying to solve is

00:07:34.440 --> 00:07:37.200
everybody's problem, in which
case you have to build in a

00:07:37.200 --> 00:07:40.190
universal interpreter
of some language.

00:07:40.190 --> 00:07:42.580
But you shouldn't put any more
in than required to build the

00:07:42.580 --> 00:07:44.540
universal interpreter
of some language.

00:07:44.540 --> 00:07:47.025
We'll worry about that
in a second.

00:07:47.025 --> 00:07:49.930
OK, going back to
here, let's see.

00:07:49.930 --> 00:07:51.640
What do we have to
be able to do?

00:07:51.640 --> 00:07:56.580
Well, somehow, we have to be
able to get B into A. We have

00:07:56.580 --> 00:07:59.260
to be able to get the old value
of B into the value of

00:07:59.260 --> 00:08:03.340
A. So we have to have some path
by which stuff can flow,

00:08:03.340 --> 00:08:07.390
whatever this information
is, from b to a.

00:08:07.390 --> 00:08:10.520
I'm going to draw that with by
an arrow saying that it is

00:08:10.520 --> 00:08:13.640
possible to move the contents
of b into a, replacing the

00:08:13.640 --> 00:08:15.120
value of a.

00:08:15.120 --> 00:08:17.660
And there's a little button
here which you push which

00:08:17.660 --> 00:08:19.710
allows that to happen.

00:08:19.710 --> 00:08:23.070
That's what the little
x is here.

00:08:23.070 --> 00:08:25.110
Now it's also the case that I
have to be able to compute the

00:08:25.110 --> 00:08:27.000
remainder of a and b.

00:08:27.000 --> 00:08:28.860
Now that may be a complicated
mess.

00:08:28.860 --> 00:08:31.960
On the other hand, I'm going
to make it a small box.

00:08:31.960 --> 00:08:34.890
If we have to, we may open up
that box and look inside and

00:08:34.890 --> 00:08:37.740
see what it is.

00:08:37.740 --> 00:08:39.580
So here, I'm going to have a
little box, which I'm going to

00:08:39.580 --> 00:08:46.440
draw this way, which we'll
call the remainder.

00:08:46.440 --> 00:08:48.265
And it's going to take in a.

00:08:50.910 --> 00:08:54.370
That's going to take in b.

00:08:54.370 --> 00:08:59.660
And it's going to put out
something, the remainder of a

00:08:59.660 --> 00:09:02.290
divided by b.

00:09:02.290 --> 00:09:04.050
Another thing we have to see
here is that we have to be

00:09:04.050 --> 00:09:08.000
able to test whether
b is equal to 0.

00:09:08.000 --> 00:09:10.020
Well, that means somebody's
got to be looking at--

00:09:10.020 --> 00:09:13.390
a thing that's looking
at the value of b.

00:09:13.390 --> 00:09:17.390
I have a light bulb here which
lights up if b equals 0.

00:09:21.110 --> 00:09:24.030
That's its job.

00:09:24.030 --> 00:09:27.250
And finally, I suppose, because
of the fact that we

00:09:27.250 --> 00:09:30.640
want the new value of a to be
the old value of b, and

00:09:30.640 --> 00:09:33.820
simultaneously the new value of
b to be something I've done

00:09:33.820 --> 00:09:38.160
with a, and if I plan to make
my machine such that

00:09:38.160 --> 00:09:41.620
everything happens one at a
time, one motion at a time,

00:09:41.620 --> 00:09:44.526
and I can't put two numbers in
a register, then I have to

00:09:44.526 --> 00:09:46.300
have another place to put one
while I'm interchanging.

00:09:49.534 --> 00:09:50.000
OK?

00:09:50.000 --> 00:09:52.490
I can't interchange the two
things in my hands, unless I

00:09:52.490 --> 00:09:54.730
either put two in one hand and
then pull it back the other

00:09:54.730 --> 00:09:57.960
way, or unless I put one down,
pick it up, and put the other

00:09:57.960 --> 00:10:02.930
one, like that, unless I'm a
juggler, which I'm not, as you

00:10:02.930 --> 00:10:06.200
can see, in which case I have a

00:10:06.200 --> 00:10:08.850
possibility of timing errors.

00:10:08.850 --> 00:10:11.500
In fact, much of the type of
computer design people do

00:10:11.500 --> 00:10:15.260
involves timing errors, of some
potential timing errors,

00:10:15.260 --> 00:10:17.840
which I don't much like.

00:10:17.840 --> 00:10:22.500
So for that reason, I have to
have a place to put the second

00:10:22.500 --> 00:10:23.410
one of them down.

00:10:23.410 --> 00:10:25.820
So I have a place called t,
which is a register just for

00:10:25.820 --> 00:10:30.470
temporary, t, with
a button on it.

00:10:30.470 --> 00:10:32.450
And then I'll take the result of
that, since I have to take

00:10:32.450 --> 00:10:35.640
that and put into b, over here,
we'll take the result of

00:10:35.640 --> 00:10:39.300
that and go like this,
and a button here.

00:10:42.430 --> 00:10:47.600
So that's the datapaths
of a GCD machine.

00:10:47.600 --> 00:10:49.740
Now what's the controller?

00:10:49.740 --> 00:10:52.280
Controller's a very
simple thing, too.

00:10:52.280 --> 00:10:53.710
The machine has a state.

00:10:53.710 --> 00:10:59.010
The way I like to visualize that
is that I've got a maze.

00:10:59.010 --> 00:11:01.680
And the maze has a
bunch of places

00:11:01.680 --> 00:11:04.430
connected by directed arrows.

00:11:04.430 --> 00:11:08.430
And what I have is a marble,
which represents the state of

00:11:08.430 --> 00:11:10.740
the controller.

00:11:10.740 --> 00:11:13.256
The marble rolls around
in the maze.

00:11:13.256 --> 00:11:17.150
Of course, this analogy breaks
down for energy reasons.

00:11:17.150 --> 00:11:19.310
I sometimes have to pump the
marble up to the top, because

00:11:19.310 --> 00:11:22.000
it's going to otherwise be a
perpetual motion machine.

00:11:22.000 --> 00:11:24.270
But not worrying about
that, this is

00:11:24.270 --> 00:11:26.080
not a physical analogy.

00:11:26.080 --> 00:11:27.680
This marble rolls around.

00:11:27.680 --> 00:11:30.180
And every time it rolls around
certain bumpers, like in a

00:11:30.180 --> 00:11:34.830
pinball machine, it pushes
one of these buttons.

00:11:34.830 --> 00:11:36.810
And every so often, it comes
to a place, which is a

00:11:36.810 --> 00:11:40.250
division, where it has
to make a choice.

00:11:40.250 --> 00:11:42.360
And there's a flap, which
is controlled by this.

00:11:46.000 --> 00:11:48.820
So that's a really mechanical
way of thinking about it.

00:11:48.820 --> 00:11:50.980
Of course, controllers these
days, are not built that way

00:11:50.980 --> 00:11:51.840
in real computers.

00:11:51.840 --> 00:11:54.090
They're built with
a little bit of

00:11:54.090 --> 00:11:56.610
ROM and a state register.

00:11:56.610 --> 00:11:59.726
But there was a time, like the
DEC PDP-6, where that's how

00:11:59.726 --> 00:12:01.400
you built the controller
of a machine.

00:12:01.400 --> 00:12:06.800
There was a bit that ran around
the delay line, and it

00:12:06.800 --> 00:12:08.580
triggered things
as it went by.

00:12:08.580 --> 00:12:09.860
And it would come back
to the beginning and

00:12:09.860 --> 00:12:11.990
get fed round again.

00:12:11.990 --> 00:12:13.630
And of course, there were all
sorts of great bugs you could

00:12:13.630 --> 00:12:17.670
have like two bits going
around, two marbles.

00:12:17.670 --> 00:12:19.260
And then the machine has
lost its marbles.

00:12:19.260 --> 00:12:20.980
That happens, too.

00:12:20.980 --> 00:12:21.935
Oh, well.

00:12:21.935 --> 00:12:24.570
So anyway, for this machine,
what I have

00:12:24.570 --> 00:12:25.940
to do is the following.

00:12:25.940 --> 00:12:27.690
I'm going to start
my maze here.

00:12:30.520 --> 00:12:35.460
And the first thing I've got
to do, in a notation which

00:12:35.460 --> 00:12:41.540
many of you are familiar with,
is b equal to zero, a test.

00:12:41.540 --> 00:12:44.540
And there's a possibility,
either yes, in

00:12:44.540 --> 00:12:45.790
which case I'm done.

00:12:49.790 --> 00:12:53.220
Otherwise, if no, then
I'm going have to

00:12:53.220 --> 00:12:54.725
roll over some bumpers.

00:12:54.725 --> 00:12:57.420
I'm going to do it in
the following order.

00:12:57.420 --> 00:13:04.050
I want to do this interchange
game.

00:13:04.050 --> 00:13:07.360
Now first, since I need both a
and b, but then the first--

00:13:07.360 --> 00:13:08.670
and this is not necessary--

00:13:08.670 --> 00:13:11.070
I want to collect this.

00:13:11.070 --> 00:13:13.240
This is the thing that's
going to go into b.

00:13:13.240 --> 00:13:15.680
So I'm going to say, take this,
which depends upon both

00:13:15.680 --> 00:13:19.150
a and b, and put the remainder
into here.

00:13:19.150 --> 00:13:22.940
So I'm going to push this button
first. Then, I'm going

00:13:22.940 --> 00:13:26.460
to transfer b to a, push that
button, and then I transfer

00:13:26.460 --> 00:13:32.030
the temporary into b,
push that button.

00:13:32.030 --> 00:13:37.750
So a very sequential machine,
it's very inefficient.

00:13:37.750 --> 00:13:39.810
But that's fine right now.

00:13:39.810 --> 00:13:42.305
We're going to name the buttons,
t gets remainder.

00:13:46.750 --> 00:13:50.036
a gets b.

00:13:50.036 --> 00:13:55.470
And b gets t.

00:13:55.470 --> 00:13:59.150
And then I'm going to go around
here and it's to go

00:13:59.150 --> 00:14:01.620
back to start.

00:14:01.620 --> 00:14:03.870
And if you look, what
are we seeing here?

00:14:03.870 --> 00:14:05.080
We're seeing the various--

00:14:05.080 --> 00:14:07.400
what I really have is some sort
of mechanical connection,

00:14:07.400 --> 00:14:13.620
where t gets r controls
this thing.

00:14:16.830 --> 00:14:20.910
And I have here that a gets b
controls this fellow over

00:14:20.910 --> 00:14:28.120
here, and this fellow
over here.

00:14:28.120 --> 00:14:31.090
Boy, that's absolutely
pessimal,

00:14:31.090 --> 00:14:32.630
the inverse of optimal.

00:14:32.630 --> 00:14:34.590
Every line heads across every
other line the way I drew it.

00:14:38.540 --> 00:14:41.150
I suppose this goes
here, b gets t.

00:14:45.690 --> 00:14:48.040
Now I'd like to run
this machine.

00:14:48.040 --> 00:14:50.260
But before I run the machine,
I want to write down a

00:14:50.260 --> 00:14:52.243
description of this controller,
just so you can

00:14:52.243 --> 00:14:54.160
see that these things, of
course, as usual, can be

00:14:54.160 --> 00:14:56.560
written down in some nice
language, so that we don't

00:14:56.560 --> 00:14:59.010
have to always draw these
diagrams. One of the problems

00:14:59.010 --> 00:15:00.710
with diagrams is that they
take up a lot of space.

00:15:00.710 --> 00:15:03.220
And for a machine this small,
it takes two blackboards.

00:15:03.220 --> 00:15:05.690
For a machine that's the
evaluator machine, I have

00:15:05.690 --> 00:15:08.320
trouble putting it into
this room, even though

00:15:08.320 --> 00:15:09.900
it isn't very big.

00:15:09.900 --> 00:15:11.550
So I'm going to make a little
language for this that's just

00:15:11.550 --> 00:15:17.530
a description of that,
saying define a

00:15:17.530 --> 00:15:24.420
machine we'll call GCD.

00:15:24.420 --> 00:15:25.970
Of course, once we have
something like this, we have a

00:15:25.970 --> 00:15:27.220
simulator for it.

00:15:27.220 --> 00:15:29.630
And the reason why we want to
build a language in this form,

00:15:29.630 --> 00:15:31.500
is because all of a sudden
we can manipulate these

00:15:31.500 --> 00:15:33.210
expressions that I'm
writing down.

00:15:33.210 --> 00:15:35.970
And then of course I can write
things that can algebraically

00:15:35.970 --> 00:15:38.730
manipulate these things,
simulate them, all that sort

00:15:38.730 --> 00:15:41.255
of things that I might want to
do, perhaps transform them as

00:15:41.255 --> 00:15:43.630
a layout, who knows.

00:15:43.630 --> 00:15:48.185
Once I have a nice
representation of registers,

00:15:48.185 --> 00:15:56.326
it has certain registers, which
we can call A, B, and T.

00:15:56.326 --> 00:15:57.576
And there's a controller.

00:16:02.190 --> 00:16:04.910
Actually, a better language,
which would be more explicit,

00:16:04.910 --> 00:16:09.440
would be one which named
every button also and

00:16:09.440 --> 00:16:10.420
said what it did.

00:16:10.420 --> 00:16:13.390
Like, this button causes the
contents of T to go to the

00:16:13.390 --> 00:16:16.310
contents of B. Well I don't want
to do that, because it's

00:16:16.310 --> 00:16:18.410
actually harder to read
to do that, and it

00:16:18.410 --> 00:16:19.510
takes up more space.

00:16:19.510 --> 00:16:21.710
So I'm going to have that in
the instructions written in

00:16:21.710 --> 00:16:23.290
the controller.

00:16:23.290 --> 00:16:26.460
It's going to be implicit
what the operations are.

00:16:26.460 --> 00:16:29.990
They can be deduced by reading
these and collecting together

00:16:29.990 --> 00:16:33.500
all the different things
that can be done.

00:16:33.500 --> 00:16:35.482
Well, let's just look at
what these things are.

00:16:35.482 --> 00:16:42.550
There's a little loop that we
go around which says branch,

00:16:42.550 --> 00:16:47.430
this is the representation of
the little flap that decides

00:16:47.430 --> 00:16:58.010
which way you go here, if 0
fetch of B, the contents of B,

00:16:58.010 --> 00:17:00.790
and if the contents of
B is 0, then go to a

00:17:00.790 --> 00:17:03.640
place called done.

00:17:03.640 --> 00:17:06.030
Now, one thing you're seeing
here, this looks very much

00:17:06.030 --> 00:17:08.170
like a traditional computer
language.

00:17:08.170 --> 00:17:13.099
And what you're seeing here
is things like labels that

00:17:13.099 --> 00:17:17.609
represent places in a sequence
written down as a sequence.

00:17:17.609 --> 00:17:21.700
The reason why they're needed
is because over here, I've

00:17:21.700 --> 00:17:23.329
written something with loops.

00:17:23.329 --> 00:17:26.569
But if I'm writing English text,
or something like that,

00:17:26.569 --> 00:17:28.580
it's hard to refer to a place.

00:17:28.580 --> 00:17:31.440
I don't have arrows.

00:17:31.440 --> 00:17:33.450
Arrows are represented by giving
names to the places

00:17:33.450 --> 00:17:35.680
where the arrows terminate, and
then referring to them by

00:17:35.680 --> 00:17:37.620
those names.

00:17:37.620 --> 00:17:39.860
Now this is just an encoding.

00:17:39.860 --> 00:17:43.150
There's nothing magical about
things like that.

00:17:43.150 --> 00:17:45.310
Next thing we're going to do is
we're going to say, how do

00:17:45.310 --> 00:17:46.840
we do T gets R?

00:17:46.840 --> 00:17:49.030
Oh, that's easy enough,
assign.

00:17:51.930 --> 00:17:56.400
We assign to T the remainder.

00:17:56.400 --> 00:18:01.470
Assign is the name
of the button.

00:18:01.470 --> 00:18:03.140
That's the button-pusher.

00:18:03.140 --> 00:18:05.910
Assign to T the remainder, and
here's the representation of

00:18:05.910 --> 00:18:17.550
the operation, when we divide
the fetch of A by the fetch of

00:18:17.550 --> 00:18:23.478
B.

00:18:23.478 --> 00:18:35.560
And we're also going to assign
to A the fetch of B, assign to

00:18:35.560 --> 00:18:50.140
B the result of getting the
contents of T. And now I have

00:18:50.140 --> 00:18:53.280
to refer to the beginning
here.

00:18:53.280 --> 00:18:55.760
I see, why don't I call that
loop like I have here?

00:19:05.390 --> 00:19:07.610
So that's that reference
to that arrow.

00:19:07.610 --> 00:19:08.950
And when we're done,
we're done.

00:19:08.950 --> 00:19:14.340
We go to here, which is
the end of the thing.

00:19:14.340 --> 00:19:18.090
So here's just a written
representation of this

00:19:18.090 --> 00:19:21.660
fragment of machinery that
we've drawn here.

00:19:21.660 --> 00:19:25.490
Now the next thing I'd like
to do is run this.

00:19:25.490 --> 00:19:27.620
I want us to feel it running.

00:19:27.620 --> 00:19:31.010
Never done this before,
you got to do it once.

00:19:31.010 --> 00:19:33.100
So let's take a particular
problem.

00:19:33.100 --> 00:19:38.580
Suppose we want to compute
the GCD of a equals 30

00:19:38.580 --> 00:19:42.210
and b equals 42.

00:19:42.210 --> 00:19:45.860
I have no idea what
that is right now.

00:19:45.860 --> 00:19:50.530
But a 30 and b is 42.

00:19:50.530 --> 00:19:52.410
So that's how I start
this thing up.

00:19:52.410 --> 00:19:54.240
Well, what's the first
thing I do?

00:19:54.240 --> 00:19:57.590
I say is B equal to 0, no.

00:19:57.590 --> 00:20:01.500
Then assign to T the remainder
of the fetch of A and the

00:20:01.500 --> 00:20:05.640
fetch of B. Well the remainder
of 30 when divided by

00:20:05.640 --> 00:20:11.130
42 is itself 30.

00:20:11.130 --> 00:20:12.920
Push that button.

00:20:12.920 --> 00:20:17.100
Now the marble has
rolled to here.

00:20:17.100 --> 00:20:21.220
A gets B. That pushes
this button.

00:20:21.220 --> 00:20:26.360
So 42 moves into here.

00:20:26.360 --> 00:20:29.870
B gets C. Push that button.

00:20:29.870 --> 00:20:32.225
The 30 goes here.

00:20:32.225 --> 00:20:34.660
Let met just interchange them.

00:20:34.660 --> 00:20:38.280
Now let's see, go back
to the beginning.

00:20:38.280 --> 00:20:40.200
B 0, no.

00:20:40.200 --> 00:20:43.230
T gets the remainder.

00:20:43.230 --> 00:20:47.240
I suppose the remainder when
dividing 42 by 30 is 12.

00:20:47.240 --> 00:20:48.530
I push that one.

00:20:48.530 --> 00:20:54.360
Next thing I do is allow the
30 to go to here, push this

00:20:54.360 --> 00:20:55.950
one, allow the 12
to go to here.

00:20:59.550 --> 00:21:00.380
Go around this thing.

00:21:00.380 --> 00:21:01.530
Is that done?

00:21:01.530 --> 00:21:02.360
No.

00:21:02.360 --> 00:21:05.080
How about--

00:21:05.080 --> 00:21:08.850
so now I have to find out the
remainder of 30 divided by 12.

00:21:08.850 --> 00:21:12.420
And I believe that's 6.

00:21:12.420 --> 00:21:15.916
So 6 goes here on this
button push.

00:21:15.916 --> 00:21:18.550
Then the next thing I push
is this one, which the

00:21:18.550 --> 00:21:23.730
12 goes into here.

00:21:23.730 --> 00:21:25.090
Then I push this button.

00:21:25.090 --> 00:21:26.340
The 6 gets into here.

00:21:29.850 --> 00:21:32.100
Is 6 equal to 0?

00:21:32.100 --> 00:21:33.420
No.

00:21:33.420 --> 00:21:34.380
OK.

00:21:34.380 --> 00:21:38.380
So then at that point, the next
thing to do is divide it.

00:21:38.380 --> 00:21:40.660
Ooh, this has got a
remainder of 0.

00:21:40.660 --> 00:21:42.360
Looks like we're almost done.

00:21:42.360 --> 00:21:44.360
Move the 6 over here next.

00:21:47.230 --> 00:21:49.090
0 over here.

00:21:49.090 --> 00:21:50.200
Is the answer 0?

00:21:50.200 --> 00:21:51.340
Yes.

00:21:51.340 --> 00:21:54.470
B is 0, therefore the
answer is in A.

00:21:54.470 --> 00:21:56.610
The answer is 6.

00:21:56.610 --> 00:21:58.400
And indeed that's right, because
if we look at the

00:21:58.400 --> 00:22:07.060
original problem, what we have
is 30 is 2 times 3 times 5,

00:22:07.060 --> 00:22:11.670
and 42 is 2 times 3 times 7.

00:22:11.670 --> 00:22:15.090
So the greatest common divisor
is 2 times 3, which is 6.

00:22:18.380 --> 00:22:20.780
Now normally, we write one other
little line here, just

00:22:20.780 --> 00:22:23.770
to make it a little bit clearer,
which is that we

00:22:23.770 --> 00:22:29.760
leave in a connection saying
that this light is the guy

00:22:29.760 --> 00:22:31.010
that that flap looks at.

00:22:34.050 --> 00:22:38.440
Of course, any real machine
has a lot more complicated

00:22:38.440 --> 00:22:41.350
things in it than what
I've just shown you.

00:22:41.350 --> 00:22:47.980
Let's look for a second at
the first still store.

00:22:47.980 --> 00:22:50.190
Wow.

00:22:50.190 --> 00:22:52.850
Well you see, for example, one
thing we might want to do is

00:22:52.850 --> 00:22:56.840
worry about the operations
that are of IO form.

00:22:56.840 --> 00:23:01.980
And we may have to collect
something from the outside.

00:23:01.980 --> 00:23:06.310
So a state machine that we might
have, the controller may

00:23:06.310 --> 00:23:11.190
have to, for example, get a
value from something and put

00:23:11.190 --> 00:23:13.490
register a to load it up.

00:23:13.490 --> 00:23:17.070
I have to master load up
register b with another value.

00:23:17.070 --> 00:23:19.900
And then later, when I'm done,
I might want to print the

00:23:19.900 --> 00:23:20.970
answer out.

00:23:20.970 --> 00:23:26.250
And of course, that might be
either simple or complicated.

00:23:26.250 --> 00:23:28.320
I'm writing, assuming print
is very simple, and

00:23:28.320 --> 00:23:29.880
read is very simple.

00:23:29.880 --> 00:23:31.700
But in fact, in the real
world, those are very

00:23:31.700 --> 00:23:34.930
complicated operations, usually
much, much larger and

00:23:34.930 --> 00:23:37.080
more complicated than the thing
you're doing as your

00:23:37.080 --> 00:23:38.330
problem you're trying
to solve.

00:23:41.670 --> 00:23:45.060
On the other hand, I can
remember a time when, I

00:23:45.060 --> 00:23:49.320
remember using IBM 7090 computer
of sorts, where

00:23:49.320 --> 00:23:53.600
things like read and write of
a single object, a single

00:23:53.600 --> 00:23:58.040
number, a number, is a primitive
operation of the IO

00:23:58.040 --> 00:23:59.065
controller.

00:23:59.065 --> 00:24:00.400
OK?

00:24:00.400 --> 00:24:02.330
And so we have that kind
of thing in there.

00:24:02.330 --> 00:24:08.360
And in such a machine, well,
what are we really doing?

00:24:08.360 --> 00:24:11.110
We're just saying that there's
a source over here called

00:24:11.110 --> 00:24:14.660
"read," which is an operation
which always has a value.

00:24:14.660 --> 00:24:17.480
We have to think about this as
always having a value which

00:24:17.480 --> 00:24:21.660
can be gated into either
register a or b.

00:24:21.660 --> 00:24:24.290
And print is some sort of thing
which when you gate it

00:24:24.290 --> 00:24:27.410
appropriately, when you push the
button on it, will cause a

00:24:27.410 --> 00:24:31.660
print of the value that's
currently in register a.

00:24:31.660 --> 00:24:33.050
Nothing very exciting.

00:24:33.050 --> 00:24:36.110
So that's one sort of thing you
might want to have. But

00:24:36.110 --> 00:24:37.260
these are also other
things that are

00:24:37.260 --> 00:24:38.320
a little bit worrisome.

00:24:38.320 --> 00:24:41.050
Like I've used here some
complicated mechanisms.

00:24:41.050 --> 00:24:43.850
What you see here
is remainder.

00:24:43.850 --> 00:24:44.690
What is that?

00:24:44.690 --> 00:24:46.920
That may not be so obvious
how to compute.

00:24:46.920 --> 00:24:49.860
It may be something which when
you open it up, you get a

00:24:49.860 --> 00:24:51.880
whole machine.

00:24:51.880 --> 00:24:52.720
OK?

00:24:52.720 --> 00:24:54.540
In fact, that's true.

00:24:54.540 --> 00:24:59.570
For example, if I write down the
program for remainder, the

00:24:59.570 --> 00:25:04.480
simplest program for it is
by repeated subtraction.

00:25:04.480 --> 00:25:06.380
Because of course, division
can be done by repeated

00:25:06.380 --> 00:25:09.800
subtraction of numbers,
of integers.

00:25:09.800 --> 00:25:30.270
So the remainder of N divided by
D is nothing more than if N

00:25:30.270 --> 00:25:34.920
is less than D, then the result
is N. Otherwise, it's

00:25:34.920 --> 00:25:48.350
the remainder when we subtract
D from N with respect to D,

00:25:48.350 --> 00:25:52.160
when divided by D. Gee,
this looks just

00:25:52.160 --> 00:25:56.890
like the GCD program.

00:25:56.890 --> 00:25:59.750
Of course, it's not a very nice
way to do remainders.

00:25:59.750 --> 00:26:01.525
You'd really want to use
something like binary notation

00:26:01.525 --> 00:26:05.550
and shift and things like that
in a practical computer.

00:26:05.550 --> 00:26:09.060
But the point of that is that
if I open this thing up, I

00:26:09.060 --> 00:26:11.880
might find inside of
it a computer.

00:26:11.880 --> 00:26:13.510
Oh, we know how to do that.

00:26:13.510 --> 00:26:15.640
We just made one.

00:26:15.640 --> 00:26:17.400
And it could be another
thing just like this.

00:26:17.400 --> 00:26:20.030
On the other hand, we might want
to make a more efficient

00:26:20.030 --> 00:26:22.810
or better-structured machine,
or maybe make use of some of

00:26:22.810 --> 00:26:25.340
the registers more than once,
or some horrible mess like

00:26:25.340 --> 00:26:27.550
that that hardware designers
like to do, and

00:26:27.550 --> 00:26:29.250
for very good reasons.

00:26:29.250 --> 00:26:32.990
So for example, here's a machine
that you see, which

00:26:32.990 --> 00:26:35.050
you're not supposed to
be able to read.

00:26:35.050 --> 00:26:37.520
It's a little bit complicated.

00:26:37.520 --> 00:26:41.830
But what it is is the
integration of the remainder

00:26:41.830 --> 00:26:44.210
into the GCD machine.

00:26:44.210 --> 00:26:46.020
And it takes, in fact,
no more registers.

00:26:46.020 --> 00:26:48.360
There are three registers
in the datapaths.

00:26:48.360 --> 00:26:49.050
OK?

00:26:49.050 --> 00:26:51.550
But now there's a subtractor.

00:26:51.550 --> 00:26:53.020
There are two things
that are tested.

00:26:53.020 --> 00:26:57.250
Is b equal to 0, or
is t less than b?

00:26:57.250 --> 00:27:00.800
And then the controller, which
you see over here, is not much

00:27:00.800 --> 00:27:01.850
more complicated.

00:27:01.850 --> 00:27:07.040
But it has two loops in it, one
of which is the main one

00:27:07.040 --> 00:27:10.370
for doing the GCD, and one of
which is the subtraction loop

00:27:10.370 --> 00:27:14.030
for doing the remainder
sub-operation.

00:27:14.030 --> 00:27:17.190
And there are ways, of course,
of, if you think about it,

00:27:17.190 --> 00:27:19.920
taking the remainder program.

00:27:19.920 --> 00:27:22.270
If I take remainder, as you see
over there, as a lambda

00:27:22.270 --> 00:27:25.920
expression, substitute it in for
remainder over here in the

00:27:25.920 --> 00:27:30.910
GCD program, then do some
simplification by substituting

00:27:30.910 --> 00:27:34.670
a and b for remainder
in there, then I

00:27:34.670 --> 00:27:36.630
can unwind this loop.

00:27:36.630 --> 00:27:41.660
And I can get this piece of
machinery by basically, a

00:27:41.660 --> 00:27:44.700
little bit of algebraic
simplification on the lambda

00:27:44.700 --> 00:27:45.950
expressions.

00:27:48.550 --> 00:27:50.140
So I suppose you've seen
your first very

00:27:50.140 --> 00:27:52.280
simple machines now.

00:27:52.280 --> 00:27:53.530
Are there any questions?

00:28:02.700 --> 00:28:05.360
Good.

00:28:05.360 --> 00:28:06.610
This looks easy, doesn't it?

00:28:10.200 --> 00:28:10.550
Thank you.

00:28:10.550 --> 00:28:11.350
I suppose, take a break.

00:28:11.350 --> 00:28:11.760
[MUSIC PLAYING - "JESU, JOY OF
MAN'S DESIRING" BY JOHANN

00:28:11.760 --> 00:28:13.010
SEBASTIAN BACH]

00:28:47.310 --> 00:28:49.480
PROFESSOR: Well, let's see.

00:28:49.480 --> 00:28:52.750
Now you know how to make an
iterative procedure, or a

00:28:52.750 --> 00:28:53.930
procedure that yields
an iterative

00:28:53.930 --> 00:28:57.770
process, turn into a machine.

00:28:57.770 --> 00:28:59.750
I suppose the next thing we
want to do is worry about

00:28:59.750 --> 00:29:02.690
things that reveal recursive
processes.

00:29:02.690 --> 00:29:04.695
So let's play with a simple
factorial procedure.

00:29:10.894 --> 00:29:24.690
We define factorial of N to be
if n is 1, the result is 1,

00:29:24.690 --> 00:29:26.830
using 1 right now to decrease
the amount of work I have to

00:29:26.830 --> 00:29:33.940
do to simulate it, else it's
times N factorial N minus 1.

00:29:42.520 --> 00:29:47.440
And what's different with this
program, as you know, is that

00:29:47.440 --> 00:29:51.050
after I've computed factorial
of N minus 1 here, I have to

00:29:51.050 --> 00:29:52.260
do something to the result.

00:29:52.260 --> 00:29:56.000
I have to multiply it by N.

00:29:56.000 --> 00:30:00.160
So the only way I can visualize
what this machine is

00:30:00.160 --> 00:30:02.360
doing, because of the fact--

00:30:02.360 --> 00:30:05.320
think of it this way, that I
have a machine out here which

00:30:05.320 --> 00:30:07.530
somehow needs a factorial
machine in order to compute

00:30:07.530 --> 00:30:09.320
its answer.

00:30:09.320 --> 00:30:12.550
But this machine, the outer
machine, has to exist before

00:30:12.550 --> 00:30:16.800
and after the factorial machine,
which is inside.

00:30:16.800 --> 00:30:20.080
Whereas in the iterative case,
the outer machine doesn't need

00:30:20.080 --> 00:30:25.170
to exist after the inner machine
is running, because

00:30:25.170 --> 00:30:26.580
you never need to go
back to the outer

00:30:26.580 --> 00:30:28.640
machine to do anything.

00:30:28.640 --> 00:30:31.200
So here we have a problem where
we have a machine which

00:30:31.200 --> 00:30:34.090
has the same machine
inside of it, an

00:30:34.090 --> 00:30:35.340
infinitely large machine.

00:30:40.390 --> 00:30:42.310
And it's got other things
inside of it, like a

00:30:42.310 --> 00:30:47.240
multiplier, which takes some
inputs, and there's a minus 1

00:30:47.240 --> 00:30:50.690
box, and things like that.

00:30:50.690 --> 00:30:54.370
You can imagine that's
what it looks like.

00:30:54.370 --> 00:30:57.340
But the important thing is that
here I have something

00:30:57.340 --> 00:31:00.360
that happens before and after,
in the outer machine, the

00:31:00.360 --> 00:31:02.540
execution of the
inner machine.

00:31:02.540 --> 00:31:05.570
So this machine has
to have a life.

00:31:05.570 --> 00:31:13.490
It has to exist on both times
sides of this machine.

00:31:13.490 --> 00:31:16.770
So somehow, I have to have a
place to store the things that

00:31:16.770 --> 00:31:20.030
this thing needs to run.

00:31:20.030 --> 00:31:24.140
Infinite objects don't exist
in the real world.

00:31:24.140 --> 00:31:27.020
What we have to do is arrange
an illusion that we have an

00:31:27.020 --> 00:31:28.540
infinite object, we
have an infinite

00:31:28.540 --> 00:31:31.830
amount of hardware somewhere.

00:31:31.830 --> 00:31:36.280
Now of course, illusion's
all that really matters.

00:31:36.280 --> 00:31:39.370
If we can arrange that every
time you look at some infinite

00:31:39.370 --> 00:31:44.800
object, the part of it that
you look at is there, then

00:31:44.800 --> 00:31:47.390
it's as infinite as
you need it to be.

00:31:47.390 --> 00:31:49.830
And of course, one of the things
we might want to do,

00:31:49.830 --> 00:31:53.890
just look at this thing over
here, is the organization that

00:31:53.890 --> 00:32:01.390
we've had so far involves having
a part of the machine,

00:32:01.390 --> 00:32:05.140
which is the controller, which
sits right over here, which is

00:32:05.140 --> 00:32:09.170
perfectly finite and
very simple.

00:32:09.170 --> 00:32:11.070
We have some datapaths,
which consist of

00:32:11.070 --> 00:32:13.080
registers and operators.

00:32:13.080 --> 00:32:16.190
And what I propose to do here is
decompose the machine into

00:32:16.190 --> 00:32:19.260
two parts, such that there is a
part which is fundamentally

00:32:19.260 --> 00:32:22.770
finite, and some part where a
certain amount of infinite

00:32:22.770 --> 00:32:24.230
stuff can be kept.

00:32:24.230 --> 00:32:27.050
On the other hand this is very
simple and really isn't

00:32:27.050 --> 00:32:29.430
infinite, but it's
just very large.

00:32:29.430 --> 00:32:31.840
But it's so simple that it could
be cheaply reproduced in

00:32:31.840 --> 00:32:37.550
such large amounts, we call it
memory, that we can make a

00:32:37.550 --> 00:32:40.710
structure called a stack out of
it which will allow us to,

00:32:40.710 --> 00:32:43.280
in fact, simulate the existence
of an infinite

00:32:43.280 --> 00:32:44.650
machine which is made
out of a recursive

00:32:44.650 --> 00:32:48.340
nest of many machines.

00:32:48.340 --> 00:32:51.760
And the way it's going to work
is that we're going to store

00:32:51.760 --> 00:32:56.290
in this place called the stack
the information required after

00:32:56.290 --> 00:33:00.400
the inner machine runs to resume
the operation of the

00:33:00.400 --> 00:33:01.650
outer machine.

00:33:03.840 --> 00:33:06.760
So it will remember the
important things about the

00:33:06.760 --> 00:33:09.510
life of the outer machine that
will be needed for this

00:33:09.510 --> 00:33:11.390
computation.

00:33:11.390 --> 00:33:15.380
Since, of course, these machines
are nested in a

00:33:15.380 --> 00:33:20.320
recursive manner, then in fact
the stack will only be

00:33:20.320 --> 00:33:25.330
accessed in a manner which is
the last thing that goes in is

00:33:25.330 --> 00:33:26.580
the first thing that
comes out.

00:33:29.330 --> 00:33:31.510
So we'll only need to access
some little part

00:33:31.510 --> 00:33:34.930
of this stack memory.

00:33:34.930 --> 00:33:36.810
OK, well, let's do it.

00:33:36.810 --> 00:33:38.750
I'm going to build you a
datapath now, and I'm going to

00:33:38.750 --> 00:33:40.370
write the controller.

00:33:40.370 --> 00:33:42.090
And then we're going
to execute this to

00:33:42.090 --> 00:33:43.510
see how you do it.

00:33:43.510 --> 00:33:47.900
So the factorial machine
isn't so bad.

00:33:47.900 --> 00:33:52.660
It's going to have a register
called the value, where the

00:33:52.660 --> 00:33:59.890
answer is going to be stored,
and a registered called N,

00:33:59.890 --> 00:34:02.330
which is where the number I'm
taking factorial will be

00:34:02.330 --> 00:34:04.165
stored, factorial of.

00:34:04.165 --> 00:34:09.780
And it will be necessary in some
instances to connect VAL

00:34:09.780 --> 00:34:11.760
to N.

00:34:11.760 --> 00:34:16.389
In fact, one nice case of this
is if I just said over here,

00:34:16.389 --> 00:34:19.139
N, because that would be
right for N equal 1N.

00:34:19.139 --> 00:34:21.389
And I could just move
the answer over

00:34:21.389 --> 00:34:23.909
there if that's important.

00:34:23.909 --> 00:34:26.980
I'm not worried about
that right now.

00:34:26.980 --> 00:34:29.060
And there are things I have
to be able to do.

00:34:29.060 --> 00:34:32.650
Like I have to be able to, as
we see here, multiply N by

00:34:32.650 --> 00:34:36.350
something in VAL, because
VAL is the result

00:34:36.350 --> 00:34:38.290
of computing factorial.

00:34:38.290 --> 00:34:41.429
And I have to put the result
back into VAL.

00:34:41.429 --> 00:34:45.639
So here we can see that the
result of computing a

00:34:45.639 --> 00:34:48.070
factorial is N times the result

00:34:48.070 --> 00:34:50.690
of computing a factorial.

00:34:50.690 --> 00:34:52.770
VAL will be the representation
of the answer

00:34:52.770 --> 00:34:55.199
of the inner factorial.

00:34:55.199 --> 00:35:02.525
And so I'm going to have to have
a multiplier here, which

00:35:02.525 --> 00:35:09.350
is going to sample the value of
N and the value of VAL and

00:35:09.350 --> 00:35:17.170
put the result back into
VAL like that.

00:35:17.170 --> 00:35:20.618
I'm also going to have to be
able to see if N is 1.

00:35:20.618 --> 00:35:22.230
So I need a light bulb.

00:35:28.200 --> 00:35:31.270
And I suppose the other thing
I'm going to need to have is a

00:35:31.270 --> 00:35:38.260
way of decrementing N. So I'm
going to have a decrementer,

00:35:38.260 --> 00:35:46.620
which takes N and is going to
put back the result into N.

00:35:46.620 --> 00:35:49.550
That's pretty much what
I need in my machine.

00:35:49.550 --> 00:35:51.985
Now, there's a little
bit else I need.

00:35:51.985 --> 00:35:55.620
It's a little bit more
complicated, because I'm also

00:35:55.620 --> 00:35:58.925
going to need a way to store, to
save away, the things that

00:35:58.925 --> 00:36:02.600
are going to be needed for
resuming the computation of a

00:36:02.600 --> 00:36:06.250
factorial after I've done
a sub-factorial.

00:36:06.250 --> 00:36:07.230
What's that?

00:36:07.230 --> 00:36:09.850
One thing I need is N.

00:36:09.850 --> 00:36:11.870
So I'm going to build here
a thing called a stack.

00:36:14.700 --> 00:36:24.130
The stack is a bunch of stuff
that I'm going to write in

00:36:24.130 --> 00:36:25.380
sequentially.

00:36:27.410 --> 00:36:28.916
I don't how long it is.

00:36:28.916 --> 00:36:32.890
The longer it is, the better
my illusion of infinity.

00:36:32.890 --> 00:36:36.036
And I'm going to have to have a
way of getting stuff out of

00:36:36.036 --> 00:36:39.515
N and into the stack
and vice versa.

00:36:39.515 --> 00:36:44.740
So I'm going to need a
connection like this, which is

00:36:44.740 --> 00:36:52.500
two-way, whereby I can save
the value of N and then

00:36:52.500 --> 00:36:55.820
restore it some other time
through that connection.

00:36:55.820 --> 00:36:58.100
This is the stack.

00:36:58.100 --> 00:37:02.790
I also need a way of remembering
where I was in the

00:37:02.790 --> 00:37:08.530
computation of factorial
in the outer program.

00:37:08.530 --> 00:37:11.090
Now in the case of
this machine, it

00:37:11.090 --> 00:37:14.090
isn't very much a problem.

00:37:14.090 --> 00:37:18.020
Factorial always returns, has to
go back to the place where

00:37:18.020 --> 00:37:21.650
we multiply by N, except for the
last time, when it has to

00:37:21.650 --> 00:37:23.110
return to whatever needs
the factorial or

00:37:23.110 --> 00:37:25.660
go to done or stop.

00:37:25.660 --> 00:37:28.245
However, in general, I'm going
to have to remember where I

00:37:28.245 --> 00:37:30.570
have been, because I might have
computed factorial from

00:37:30.570 --> 00:37:31.770
somewhere else.

00:37:31.770 --> 00:37:36.070
I have to go back to that place
and continue there.

00:37:36.070 --> 00:37:37.990
So I'm going to have to have
some way of taking the place

00:37:37.990 --> 00:37:41.500
where the marble is in the
finite state controller, the

00:37:41.500 --> 00:37:45.390
state of the controller,
and storing that in

00:37:45.390 --> 00:37:47.400
the stack as well.

00:37:47.400 --> 00:37:49.840
And I'm going to have to have
ways of restoring that back to

00:37:49.840 --> 00:37:51.870
the state of the-- the marble.

00:37:51.870 --> 00:37:53.570
So I have to have something that
moves the marble to the

00:37:53.570 --> 00:37:54.310
right place.

00:37:54.310 --> 00:37:57.462
Well, we're going to have a
place which is the marble now.

00:37:57.462 --> 00:38:09.220
And it's called the continue
register, called continue,

00:38:09.220 --> 00:38:11.480
which is the place to
put the marble next

00:38:11.480 --> 00:38:14.260
time I go to continue.

00:38:14.260 --> 00:38:16.140
That's what that's for.

00:38:16.140 --> 00:38:17.990
And so there's got to be some
path from that into the

00:38:17.990 --> 00:38:19.240
controller.

00:38:22.910 --> 00:38:29.074
I also have to have some way of
saving that on the stack.

00:38:29.074 --> 00:38:32.120
And I have to have some way
of setting that up to have

00:38:32.120 --> 00:38:36.860
various constants, a certain
fixed number of constants.

00:38:36.860 --> 00:38:38.840
And that's very easy
to arrange.

00:38:38.840 --> 00:38:40.180
So let's have some
constants here.

00:38:40.180 --> 00:38:41.430
We'll call this one
after-fact.

00:38:47.430 --> 00:38:50.890
And that's a constant which
we'll get into the continue

00:38:50.890 --> 00:38:54.010
register, and also another
one called fact-done.

00:39:05.210 --> 00:39:08.130
So this is the machine
I want to build.

00:39:08.130 --> 00:39:10.810
That's its datapaths, at least.
And it mixes a little

00:39:10.810 --> 00:39:12.790
with the controller here,
because of the fact that I

00:39:12.790 --> 00:39:15.220
have to remember where
I was and restore

00:39:15.220 --> 00:39:17.300
myself to that place.

00:39:17.300 --> 00:39:19.310
But let's write the program
now which represents the

00:39:19.310 --> 00:39:20.390
controller.

00:39:20.390 --> 00:39:22.760
I'm not going to write the
define machine thing and the

00:39:22.760 --> 00:39:24.890
register list, because that's
not very interesting.

00:39:24.890 --> 00:39:28.020
I'm just going to write down the
sequence of instructions

00:39:28.020 --> 00:39:30.920
that constitute the
controller.

00:39:30.920 --> 00:39:41.510
So we have assign, to set
up, continue to done.

00:39:44.476 --> 00:40:01.150
We have a loop which says branch
if equal 1 fetch N, if

00:40:01.150 --> 00:40:06.300
N is 1, then go to the base
step of the induction, the

00:40:06.300 --> 00:40:08.050
simple case.

00:40:08.050 --> 00:40:10.740
Otherwise, I have to remember
the things that are necessary

00:40:10.740 --> 00:40:14.265
to perform a sub-factorial.

00:40:14.265 --> 00:40:16.280
I'm going to go over here,
and I have to perform a

00:40:16.280 --> 00:40:17.570
sub-factorial.

00:40:17.570 --> 00:40:21.750
So I have to remember what's
needed after I will

00:40:21.750 --> 00:40:24.000
be done with that.

00:40:24.000 --> 00:40:25.510
See, I'm about to do
something terrible.

00:40:25.510 --> 00:40:29.430
I'm about to change the value of
N. But this guy has to know

00:40:29.430 --> 00:40:32.780
the old value of N. But
in order to make the

00:40:32.780 --> 00:40:35.790
sub-factorial work, I have to
change the value of N. So I

00:40:35.790 --> 00:40:38.000
have to remember
the old value.

00:40:38.000 --> 00:40:40.850
And I also have to remember
where I've been.

00:40:40.850 --> 00:40:42.100
So I save up continue.

00:40:47.705 --> 00:40:50.260
And this is an instruction
that says, put

00:40:50.260 --> 00:40:53.580
something in the stack.

00:40:53.580 --> 00:40:56.760
Save the contents of the
continuation register, which

00:40:56.760 --> 00:40:59.830
in this case is done, because
later I'm going to change

00:40:59.830 --> 00:41:00.970
that, too, because I
need to go back to

00:41:00.970 --> 00:41:03.550
after-fact, as well.

00:41:03.550 --> 00:41:05.040
We'll see that.

00:41:05.040 --> 00:41:10.380
We save N, because I'm going
to need that for later.

00:41:10.380 --> 00:41:31.422
Assign to N the decrement of
fetch N. Assign continue,

00:41:31.422 --> 00:41:37.690
we're going to look at this now,
to after, we'll call it.

00:41:37.690 --> 00:41:39.890
That's a good name for this, a
little bit easier and shorter,

00:41:39.890 --> 00:41:41.140
and fits in here.

00:41:52.772 --> 00:41:55.330
Now look what I'm doing here.

00:41:55.330 --> 00:42:00.065
I'm saying, if the answer
is 1, I'm done.

00:42:00.065 --> 00:42:02.150
I'm going to have to just
get the answer.

00:42:02.150 --> 00:42:06.160
Otherwise, I'm going to save the
continuation, save N, make

00:42:06.160 --> 00:42:08.940
N one less than N, remember
I'm going to come back to

00:42:08.940 --> 00:42:10.530
someplace else, and
go back and start

00:42:10.530 --> 00:42:11.780
doing another factorial.

00:42:13.980 --> 00:42:16.050
However, I've got a different
machine [? in me ?] now.

00:42:16.050 --> 00:42:18.380
N is 1, and continue
is something else.

00:42:22.160 --> 00:42:23.590
N is N minus 1.

00:42:23.590 --> 00:42:28.660
Now after I'm done with
that, I can go there.

00:42:28.660 --> 00:42:34.130
I will restore the old value of
N, which is the opposite of

00:42:34.130 --> 00:42:38.360
this save over here.

00:42:38.360 --> 00:42:39.610
I will restore the
continuation.

00:42:49.660 --> 00:42:54.320
I will then go to here.

00:42:54.320 --> 00:43:03.310
I will assign to the VAL
register the product

00:43:03.310 --> 00:43:08.130
of N and fetch VAL.

00:43:13.520 --> 00:43:19.790
VAL fetch product assign.

00:43:19.790 --> 00:43:21.440
And then I will be done.

00:43:21.440 --> 00:43:26.570
I will have my answer to the
sub-factorial in VAL.

00:43:26.570 --> 00:43:30.140
At that point, I'm going to
return by going to the place

00:43:30.140 --> 00:43:33.640
where the continuation
is pointing.

00:43:33.640 --> 00:43:35.300
That says, go to
fetch continue.

00:43:45.870 --> 00:43:49.470
And then I have finally
a base step, which is

00:43:49.470 --> 00:43:50.730
the immediate answer.

00:43:50.730 --> 00:44:02.570
Assign to VAL fetch N, and
go to fetch continue.

00:44:12.670 --> 00:44:13.920
And then I'm done.

00:44:18.640 --> 00:44:20.820
Now let's see how this executes
on a very simple

00:44:20.820 --> 00:44:25.570
case, because then we'll see
the use of this stack to do

00:44:25.570 --> 00:44:26.890
the job we need.

00:44:26.890 --> 00:44:28.820
This is statically what it's
doing, but we have look

00:44:28.820 --> 00:44:31.340
dynamically at this.

00:44:31.340 --> 00:44:32.300
So let's see.

00:44:32.300 --> 00:44:36.730
First thing we do is
continue gets done.

00:44:36.730 --> 00:44:38.300
The way that happened
is I pushed this.

00:44:38.300 --> 00:44:40.122
Let's call that done
the way I have it.

00:44:46.390 --> 00:44:47.030
I push that button.

00:44:47.030 --> 00:44:48.950
Done goes into there.

00:44:48.950 --> 00:44:52.550
Now I also have to set
this thing up to

00:44:52.550 --> 00:44:53.850
have an initial value.

00:44:53.850 --> 00:45:00.192
Let's consider a factorial
of three, a simple case.

00:45:00.192 --> 00:45:03.010
And we're going to start
out with our stack

00:45:03.010 --> 00:45:05.900
growing over here.

00:45:05.900 --> 00:45:08.520
Stacks have their own little
internal state saying where

00:45:08.520 --> 00:45:12.770
they are, where the next place
I'm going to write is.

00:45:12.770 --> 00:45:14.590
So now we say, is N 1?

00:45:14.590 --> 00:45:16.110
The answer is no.

00:45:16.110 --> 00:45:19.066
So now I'm going to save
continue, bang.

00:45:19.066 --> 00:45:22.080
Now that done goes in here.

00:45:22.080 --> 00:45:26.660
And this moves to here, the next
place I'm going to write.

00:45:26.660 --> 00:45:29.950
Save N 3.

00:45:29.950 --> 00:45:30.750
OK?

00:45:30.750 --> 00:45:34.240
Assign to N the decrement
of N. That means

00:45:34.240 --> 00:45:35.940
I've pushed this button.

00:45:35.940 --> 00:45:37.320
This becomes 2.

00:45:40.400 --> 00:45:42.580
Assign to continue aft.

00:45:42.580 --> 00:45:43.610
So I've pushed that button.

00:45:43.610 --> 00:45:44.860
Aft goes in here.

00:45:49.140 --> 00:45:54.830
OK, now go to loop, bang,
so up to here.

00:45:54.830 --> 00:45:56.570
Is N 1?

00:45:56.570 --> 00:45:57.780
No.

00:45:57.780 --> 00:45:59.490
So I have to save continue.

00:45:59.490 --> 00:46:00.600
What's continue?

00:46:00.600 --> 00:46:01.530
Continue is aft.

00:46:01.530 --> 00:46:02.780
Push this button.

00:46:02.780 --> 00:46:04.030
So this moves to here.

00:46:08.490 --> 00:46:11.460
I have to save N.
N is over here.

00:46:11.460 --> 00:46:12.280
I got to 2.

00:46:12.280 --> 00:46:13.655
Push that button.

00:46:13.655 --> 00:46:16.050
So a 2 gets written there.

00:46:16.050 --> 00:46:20.060
And then this thing
moves down here.

00:46:20.060 --> 00:46:24.214
OK, save N. Assign N to
the decrement of N.

00:46:24.214 --> 00:46:25.464
This becomes a 1.

00:46:29.240 --> 00:46:31.370
Assign continue to aft.

00:46:31.370 --> 00:46:34.960
A-F-T gets written
there again.

00:46:34.960 --> 00:46:36.520
Go to loop.

00:46:36.520 --> 00:46:37.930
Is N equal to 1?

00:46:37.930 --> 00:46:41.160
Oh, yes, the answer is 1.

00:46:41.160 --> 00:46:44.160
OK, go to base step.

00:46:44.160 --> 00:46:51.100
Assign to VAL fetch of N. Bang,
1 gets put in there.

00:46:51.100 --> 00:46:52.200
Go to fetch continue.

00:46:52.200 --> 00:46:53.680
So we look in continue.

00:46:53.680 --> 00:46:55.350
Basically, I'm pushing a button
over here that goes to

00:46:55.350 --> 00:46:57.130
the controller.

00:46:57.130 --> 00:46:59.580
The continue becomes aft, and
all of a sudden, the program's

00:46:59.580 --> 00:47:02.640
running here.

00:47:02.640 --> 00:47:06.650
I now have to restore the outer
version of factorial.

00:47:06.650 --> 00:47:07.550
So we go here.

00:47:07.550 --> 00:47:12.410
We say, restore N. So restore
N means take the contents

00:47:12.410 --> 00:47:13.940
that's here.

00:47:13.940 --> 00:47:19.190
Push this button, and it goes
into here, 2, and the

00:47:19.190 --> 00:47:22.230
pointer moves up.

00:47:22.230 --> 00:47:24.810
Restore continue, pretty easy.

00:47:24.810 --> 00:47:27.020
Go push this button.

00:47:27.020 --> 00:47:31.280
And then aft gets written
in here again.

00:47:31.280 --> 00:47:32.640
That means this thing
moves up.

00:47:32.640 --> 00:47:35.190
I've gotten rid of something
else on my stack.

00:47:42.240 --> 00:47:45.930
Right, then I go to here, which
says, assign to VAL the

00:47:45.930 --> 00:47:47.850
product of N an VAL.

00:47:47.850 --> 00:47:50.970
So I push this button
over here, bang.

00:47:50.970 --> 00:47:55.920
2 times 1 gives me a 2,
get written there.

00:47:55.920 --> 00:47:57.540
Go to fetch continue.

00:47:57.540 --> 00:47:59.190
Continue is aft.

00:47:59.190 --> 00:48:01.290
I go to aft.

00:48:01.290 --> 00:48:06.640
Aft says restore N. Do your
restore N, means I take the

00:48:06.640 --> 00:48:11.030
value over here, which is 3,
push this up to here, and move

00:48:11.030 --> 00:48:17.715
it into here, N. Now it's
pushing that button.

00:48:17.715 --> 00:48:20.200
The next thing I do is
restore continue.

00:48:20.200 --> 00:48:22.830
Continue is now going
to become done.

00:48:22.830 --> 00:48:27.260
So this moves up here when
I push this button.

00:48:27.260 --> 00:48:30.470
Done may or may be there
anymore, I'm not interested,

00:48:30.470 --> 00:48:31.720
but it certainly is here.

00:48:35.800 --> 00:48:39.590
Next thing I do is assign to VAL
the product of the fetch

00:48:39.590 --> 00:48:41.440
of N and the fetch of VAL.

00:48:41.440 --> 00:48:44.300
That's pushing this button
over here, bang.

00:48:44.300 --> 00:48:46.520
2 times 3 is 6.

00:48:46.520 --> 00:48:47.870
So I get a 6 over here.

00:48:52.020 --> 00:48:54.140
And go to fetch continue,
whoops, I go to

00:48:54.140 --> 00:48:55.020
done, and I'm done.

00:48:55.020 --> 00:48:58.950
And my answer is 6, as you can
see in the VAL register.

00:48:58.950 --> 00:49:02.380
And in fact, the stack
is in the state it

00:49:02.380 --> 00:49:03.630
originally was in.

00:49:07.735 --> 00:49:09.850
Now there's a bit of discipline
in using these

00:49:09.850 --> 00:49:13.620
things like stacks that we
have to be careful of.

00:49:13.620 --> 00:49:16.260
And we'll see that in
the next segment.

00:49:16.260 --> 00:49:17.340
But first I want to ask
if there are any

00:49:17.340 --> 00:49:18.590
questions for this.

00:49:28.560 --> 00:49:30.170
Are there any questions?

00:49:30.170 --> 00:49:30.630
Yes, Ron.

00:49:30.630 --> 00:49:32.780
AUDIENCE: What happens when you
roll off the end of the

00:49:32.780 --> 00:49:33.640
stack with--

00:49:33.640 --> 00:49:35.030
PROFESSOR: What do you
mean, roll off of?

00:49:35.030 --> 00:49:36.090
AUDIENCE: Well, the
largest number--

00:49:36.090 --> 00:49:38.860
a larger starting point of N
requires more memory, correct?

00:49:38.860 --> 00:49:39.440
PROFESSOR: Oh, yes.

00:49:39.440 --> 00:49:41.530
Well, I need to have a
long enough stack.

00:49:41.530 --> 00:49:43.843
You say, what if I violate
my illusion?

00:49:43.843 --> 00:49:44.550
AUDIENCE: Yes.

00:49:44.550 --> 00:49:48.210
PROFESSOR: Well, then the
magic doesn't work.

00:49:48.210 --> 00:49:51.640
The truth of the matter is that
every machine is finite.

00:49:51.640 --> 00:49:56.480
And for a procedure like this,
there's a limit to the number

00:49:56.480 --> 00:49:59.950
of sub-factorials
I could have.

00:49:59.950 --> 00:50:02.970
Remember when we were doing the
y-operator a while ago, we

00:50:02.970 --> 00:50:05.750
pointed out that there was a
sequence of exponentiation

00:50:05.750 --> 00:50:07.390
procedures, each of which was
a little better than the

00:50:07.390 --> 00:50:08.350
previous one.

00:50:08.350 --> 00:50:10.530
Well, we're now seeing
how we implement that

00:50:10.530 --> 00:50:13.090
mathematical idea.

00:50:13.090 --> 00:50:15.620
The limiting process is only
so good as as far as

00:50:15.620 --> 00:50:17.990
you take the limit.

00:50:17.990 --> 00:50:19.420
If you think about it,
what am I using here?

00:50:19.420 --> 00:50:26.340
I'm using about two pieces of
memory for every recursion of

00:50:26.340 --> 00:50:29.100
this process.

00:50:29.100 --> 00:50:31.920
If we try to compute factorial
of 10,000, that's

00:50:31.920 --> 00:50:33.180
not a lot of memory.

00:50:33.180 --> 00:50:36.080
On the other hand, it's
an awful big number.

00:50:36.080 --> 00:50:39.180
So the question is, is that a
valuable thing in this case.

00:50:39.180 --> 00:50:42.480
But it really turns out not to
be a terrible limit, because

00:50:42.480 --> 00:50:45.085
memory is el cheapo, and people
are pretty expensive.

00:50:48.130 --> 00:50:51.050
OK, thank you, let's
take a break.

00:50:51.050 --> 00:50:51.410
[MUSIC PLAYING - "JESU, JOY OF
MAN'S DESIRING" BY JOHANN

00:50:51.410 --> 00:50:52.660
SEBASTIAN BACH]

00:51:55.176 --> 00:51:58.351
PROFESSOR: Well, let's see.

00:51:58.351 --> 00:52:02.770
What I've shown you now is how
to do a simple iterative

00:52:02.770 --> 00:52:05.640
process and a simple
recursive process.

00:52:05.640 --> 00:52:09.760
I just want to summarize the
design of simple machines for

00:52:09.760 --> 00:52:12.470
specific applications by showing
you a little bit more

00:52:12.470 --> 00:52:15.870
complicated design, that of
a thing that does doubly

00:52:15.870 --> 00:52:19.015
recursive Fibonacci, because
it will indicate to us, and

00:52:19.015 --> 00:52:22.870
we'll understand, a bit about
the conventions required for

00:52:22.870 --> 00:52:26.400
making stacks operate
correctly.

00:52:26.400 --> 00:52:27.110
So let's see.

00:52:27.110 --> 00:52:28.830
I'm just going to write down,
first of all, the program I'm

00:52:28.830 --> 00:52:30.080
going to translate.

00:52:34.150 --> 00:52:41.190
I need a Fibonacci procedure,
it's very simple, which says,

00:52:41.190 --> 00:52:50.390
if N is less than 2, the result
is N, otherwise it's

00:52:50.390 --> 00:52:59.965
the sum of Fib of N minus
1 and Fib of N minus 2.

00:53:07.240 --> 00:53:09.290
That's the plan I have here.

00:53:09.290 --> 00:53:11.180
And we're just going
to write down the

00:53:11.180 --> 00:53:13.070
controller for such a machine.

00:53:13.070 --> 00:53:16.240
We're going to assume that there
are registers, N, which

00:53:16.240 --> 00:53:20.510
holds the number we're taking
Fibonacci of, VAL, which is

00:53:20.510 --> 00:53:23.630
where the answer is going to get
put, and continue, which

00:53:23.630 --> 00:53:26.810
is the thing that's linked to
the controller, like before.

00:53:26.810 --> 00:53:31.740
But I'm not going to draw
another physical datapath,

00:53:31.740 --> 00:53:32.995
because it's pretty much
the same as the

00:53:32.995 --> 00:53:34.360
last one you've seen.

00:53:34.360 --> 00:53:37.070
And of course, one of the most
amazing things about

00:53:37.070 --> 00:53:40.700
computation is that after a
while, you build up a little

00:53:40.700 --> 00:53:42.126
more features and a few more
features, and all of the

00:53:42.126 --> 00:53:44.860
sudden, you've got everything
you need.

00:53:44.860 --> 00:53:48.290
So it's remarkable that it just
gets there so fast. I

00:53:48.290 --> 00:53:51.810
don't need much more to make
a universal computer.

00:53:51.810 --> 00:53:53.630
But in any case, let's look
at the controller for the

00:53:53.630 --> 00:53:55.060
Fibonacci thing.

00:53:55.060 --> 00:54:01.680
First thing I want to do is
start the thing up by assign

00:54:01.680 --> 00:54:10.230
to continue a place called done,
called Fib-done here.

00:54:13.709 --> 00:54:16.630
So that means that somewhere
over here, I'm going to have a

00:54:16.630 --> 00:54:21.610
label, Fib-done, which is the
place where I go when I want

00:54:21.610 --> 00:54:24.120
the machine to stop.

00:54:24.120 --> 00:54:25.395
That's what that is.

00:54:25.395 --> 00:54:26.795
And I'm going to
make up a loop.

00:54:31.110 --> 00:54:33.490
It's a place I'm going to go
to in order to start up

00:54:33.490 --> 00:54:35.470
computing a Fib.

00:54:35.470 --> 00:54:38.210
Whatever is in N at this point,
Fibonacci will be

00:54:38.210 --> 00:54:41.320
computed of, and we will return
to the place specified

00:54:41.320 --> 00:54:42.570
by continue.

00:54:46.070 --> 00:54:48.640
So what you're going to see
here at this place, what I

00:54:48.640 --> 00:54:52.650
want here is the contract that
says, I'm going to write this

00:54:52.650 --> 00:55:00.230
with a comment syntax, the
contract is N contains arg,

00:55:00.230 --> 00:55:02.100
the argument.

00:55:02.100 --> 00:55:09.325
Continue is the recipient.

00:55:12.812 --> 00:55:14.290
And that's where it is.

00:55:17.370 --> 00:55:20.430
At this point, if I ever go to
this place, I'm expecting this

00:55:20.430 --> 00:55:24.820
to be true, the argument for
computing the Fibonacci.

00:55:24.820 --> 00:55:26.450
Now the next thing I want
to do is to branch.

00:55:30.220 --> 00:55:32.070
And if N is less than 2--

00:55:34.930 --> 00:55:38.730
by the way, I'm using what
looks like Lisp syntax.

00:55:38.730 --> 00:55:41.310
This is not Lisp.

00:55:41.310 --> 00:55:42.750
This does not run.

00:55:42.750 --> 00:55:46.120
What I'm writing here does not
run as a simple Lisp program.

00:55:46.120 --> 00:55:49.710
This is a representation
of another language.

00:55:49.710 --> 00:55:52.030
The reason I'm using the syntax
of parentheses and so

00:55:52.030 --> 00:55:56.100
on is because I tend to use
a Lisp system to write an

00:55:56.100 --> 00:55:59.380
interpreter for this which
allows me to simulate the

00:55:59.380 --> 00:56:03.380
machine I'm trying to build.

00:56:03.380 --> 00:56:05.170
I don't want to confuse
this to think that

00:56:05.170 --> 00:56:06.940
this is Lisp code.

00:56:06.940 --> 00:56:09.510
It's just I'm using a lot
of the pieces of Lisp.

00:56:09.510 --> 00:56:12.880
I'm embedding a language in
Lisp, using Lisp as pieces to

00:56:12.880 --> 00:56:16.620
make my process of making
my simulator easy.

00:56:16.620 --> 00:56:18.900
So I'm inheriting from Lisp
all of its properties.

00:56:18.900 --> 00:56:22.700
Fetch of N 2, I want
to go to a place

00:56:22.700 --> 00:56:25.985
called immediate answer.

00:56:25.985 --> 00:56:27.235
It's the base step.

00:56:33.150 --> 00:56:37.750
Now, that's somewhere over
here, just above done.

00:56:37.750 --> 00:56:39.330
And we'll see it later.

00:56:39.330 --> 00:56:41.480
Now, in the general case, which
is the part I'm going to

00:56:41.480 --> 00:56:44.860
write down now, let's
just do it.

00:56:44.860 --> 00:56:46.370
Well, first of all, I'm
going to have to

00:56:46.370 --> 00:56:49.420
call Fibonacci twice.

00:56:49.420 --> 00:56:51.300
In each case--

00:56:51.300 --> 00:56:53.640
well, in one case at least, I'm
going to have to know what

00:56:53.640 --> 00:56:56.310
to do to come back and
do the next one.

00:56:56.310 --> 00:57:01.600
I have to remember, have I done
the first Fib, or have I

00:57:01.600 --> 00:57:04.500
done the second one?

00:57:04.500 --> 00:57:06.630
Do I have to come back to the
place where I do the second

00:57:06.630 --> 00:57:08.240
Fib, or do I have to come
back to the place

00:57:08.240 --> 00:57:09.490
where I do the add?

00:57:12.140 --> 00:57:14.810
In the first case, over the
first Fibonacci, I'm going to

00:57:14.810 --> 00:57:16.980
need the value of N for
computing for the second one.

00:57:20.010 --> 00:57:22.996
So I have to store some
of these things up.

00:57:22.996 --> 00:57:25.820
So first I'm going
to save continue.

00:57:25.820 --> 00:57:27.265
That's who needs the answer.

00:57:31.320 --> 00:57:33.560
And the reason I'm doing that is
because I'm about to assign

00:57:33.560 --> 00:57:42.870
continue to the place
which is the place I

00:57:42.870 --> 00:57:44.130
want to go to after.

00:57:46.870 --> 00:57:52.510
Let's call it Fib-N-minus-1,
big long name,

00:57:52.510 --> 00:57:53.760
classic Lisp name.

00:57:57.700 --> 00:58:00.900
Because I'm going to compute
the first Fib of N minus 1,

00:58:00.900 --> 00:58:02.440
and then after that, I
want to come back and

00:58:02.440 --> 00:58:03.960
do something else.

00:58:03.960 --> 00:58:08.050
That's the place I want to go
to after I've done the first

00:58:08.050 --> 00:58:11.106
Fibonacci calculation.

00:58:11.106 --> 00:58:15.030
And I want to do a save of N,
because I'm going to need it

00:58:15.030 --> 00:58:19.130
later, after that.

00:58:19.130 --> 00:58:21.480
Now I'm going to, at this point,
get ready to do the

00:58:21.480 --> 00:58:23.230
Fibonacci of N minus 1.

00:58:23.230 --> 00:58:33.950
So assign to N the difference
of the fetch of N and 1.

00:58:38.110 --> 00:58:40.270
Now I'm ready to go back
to doing the Fib loop.

00:58:47.630 --> 00:58:50.195
Have I satisfied my contract?

00:58:50.195 --> 00:58:51.770
And the answer is yes.

00:58:51.770 --> 00:58:57.210
N contains N minus 1, which
is what I need.

00:58:57.210 --> 00:59:01.370
Continue contains a place I want
to go to when I'm done

00:59:01.370 --> 00:59:04.100
with calculating N minus 1.

00:59:04.100 --> 00:59:05.440
So I've satisfied
the contract.

00:59:05.440 --> 00:59:11.580
And therefore, I can write
down here a label,

00:59:11.580 --> 00:59:12.830
after-Fib-N-minus-1.

00:59:20.490 --> 00:59:22.690
Now what am I going
to do here?

00:59:22.690 --> 00:59:25.660
Here's a place where I now
have to get ready to do

00:59:25.660 --> 00:59:26.910
Fib of N minus 2.

00:59:29.270 --> 00:59:31.780
But in order to do a Fib of N
minus 2, look, I don't know.

00:59:31.780 --> 00:59:33.810
I've clobbered my N over here.

00:59:33.810 --> 00:59:36.610
And presumably my N is counted
down all the way to 1 or 0 or

00:59:36.610 --> 00:59:39.780
something at this point.

00:59:39.780 --> 00:59:43.030
So I don't know what the value
of N in the N register is.

00:59:43.030 --> 00:59:45.640
I want the value of N that was
on the stack that I saved over

00:59:45.640 --> 00:59:49.520
here so that could restore
it over here.

00:59:49.520 --> 00:59:53.880
I saved up the value of N, which
is this value of N at

00:59:53.880 --> 00:59:56.340
this point, so that I could
restore it after computing Fib

00:59:56.340 --> 00:59:59.360
of N minus 1, so that I could
count that down to N minus 2

00:59:59.360 --> 01:00:01.810
and then compute Fib
of N minus 2.

01:00:01.810 --> 01:00:03.060
So let's restore that.

01:00:08.830 --> 01:00:11.130
Restore of N.

01:00:11.130 --> 01:00:16.200
Now I'm about to do something
which is superstitious, and we

01:00:16.200 --> 01:00:18.520
will remove it shortly.

01:00:18.520 --> 01:00:22.390
I am about to finish the
sequence of doing the

01:00:22.390 --> 01:00:24.800
subroutine call, if you will.

01:00:24.800 --> 01:00:28.510
I'm going to say, well, I also
saved up the continuation,

01:00:28.510 --> 01:00:31.600
since I'm going to
restore it now.

01:00:31.600 --> 01:00:32.970
But actually, I don't have
to, because I'm not

01:00:32.970 --> 01:00:34.610
going to need it.

01:00:34.610 --> 01:00:36.260
We'll fix that in a second.

01:00:36.260 --> 01:00:46.590
So we'll do a restore of
continue, which is what I

01:00:46.590 --> 01:00:48.020
would in general need to do.

01:00:48.020 --> 01:00:50.240
And we're just going to see
what you would call in the

01:00:50.240 --> 01:00:52.540
compiler world a peephole
optimization, which says,

01:00:52.540 --> 01:00:55.420
whoops, you didn't
have to do that.

01:00:55.420 --> 01:00:59.720
OK, so the next thing I see
here is that I have to get

01:00:59.720 --> 01:01:02.770
ready now to do Fibonacci
of N minus 2.

01:01:02.770 --> 01:01:05.050
But I don't have to
save N anymore.

01:01:05.050 --> 01:01:07.140
The reason why I don't have to
save N anymore is because I

01:01:07.140 --> 01:01:09.690
don't need N after I've done Fib
of N minus 2, because the

01:01:09.690 --> 01:01:13.540
next thing I do is add.

01:01:13.540 --> 01:01:16.500
So I'm just going to set
up my N that way.

01:01:16.500 --> 01:01:28.990
Assign N minus difference
of fetch N and 2.

01:01:31.850 --> 01:01:35.440
Now I have to finish the
setup for calling

01:01:35.440 --> 01:01:36.950
Fibonacci of N minus 2.

01:01:36.950 --> 01:01:48.330
Well, I have to save up continue
and assign continue,

01:01:48.330 --> 01:02:03.050
continue, to the place which is
after Fib N 2, that place

01:02:03.050 --> 01:02:05.320
over here somewhere.

01:02:05.320 --> 01:02:08.650
However, I've got to
be very careful.

01:02:08.650 --> 01:02:12.470
The old value, the value of Fib
of N minus 1, I'm going to

01:02:12.470 --> 01:02:15.300
need later.

01:02:15.300 --> 01:02:18.480
The value of Fibonacci of N
minus 1, I'm going to need.

01:02:18.480 --> 01:02:21.880
And I can't clobber it, because
I'm going to have to

01:02:21.880 --> 01:02:24.150
add it to the value of
Fib of N minus 2.

01:02:24.150 --> 01:02:27.720
That's in the value register,
so I'm going to save it.

01:02:27.720 --> 01:02:33.780
So I have to save this right
now, save up VAL.

01:02:33.780 --> 01:02:39.547
And now I can go off to my
subroutine, go to Fib loop.

01:02:44.220 --> 01:02:49.460
Now before I go any further
and finish this program, I

01:02:49.460 --> 01:02:52.340
just want to look at this
segment so far and see, oh

01:02:52.340 --> 01:02:55.520
yes, there's a sequence of
instructions here, if you

01:02:55.520 --> 01:03:01.580
will, that I can do
something about.

01:03:01.580 --> 01:03:06.010
Here I have a restore of
continue, a save of continue,

01:03:06.010 --> 01:03:09.200
and then an assign of continue,
with no other

01:03:09.200 --> 01:03:10.640
references to continue
in between.

01:03:13.840 --> 01:03:15.520
The restore followed
by the save

01:03:15.520 --> 01:03:16.770
leaves the stack unchanged.

01:03:19.090 --> 01:03:21.250
The only difference is that I
set the continue register to a

01:03:21.250 --> 01:03:24.330
value, which is the value
that was on the stack.

01:03:24.330 --> 01:03:27.360
Since I now clobber that value,
as in it was never

01:03:27.360 --> 01:03:31.710
referenced, these instructions
are unnecessary.

01:03:31.710 --> 01:03:35.390
So we will remove these.

01:03:38.550 --> 01:03:40.210
But I couldn't have seen
that unless I had

01:03:40.210 --> 01:03:41.460
written them down.

01:03:43.780 --> 01:03:45.590
Was that really true?

01:03:45.590 --> 01:03:48.610
Well, I don't know.

01:03:48.610 --> 01:03:51.560
OK, so we've now gone
off to compute

01:03:51.560 --> 01:03:53.660
Fibonacci of N minus 2.

01:03:53.660 --> 01:04:05.070
So after that, what are
we going to do?

01:04:05.070 --> 01:04:07.010
Well, I suppose the first
thing we have to do--

01:04:07.010 --> 01:04:07.960
we've got two things.

01:04:07.960 --> 01:04:09.460
We've got a thing in
the value register

01:04:09.460 --> 01:04:10.920
which is now valuable.

01:04:10.920 --> 01:04:12.610
We also have a thing on the
stack that can be restored

01:04:12.610 --> 01:04:14.815
into the value register.

01:04:14.815 --> 01:04:17.630
And what I have to be careful
with now is I want to shuffle

01:04:17.630 --> 01:04:19.470
this right so I can
do the multiply.

01:04:19.470 --> 01:04:21.600
Now there are various
conventions I might use, but

01:04:21.600 --> 01:04:24.510
I'm going to be very picky and
say, I'm only going to restore

01:04:24.510 --> 01:04:26.740
into a register I've
saved from.

01:04:26.740 --> 01:04:30.020
If that's the case, I have
to do a shuffle here.

01:04:30.020 --> 01:04:32.950
It's the same problem with how
many hands I have. So I'm

01:04:32.950 --> 01:04:37.800
going to assign to N, because
I'm not going to need N

01:04:37.800 --> 01:04:45.440
anymore, N is useless, the
current value of VAL, which

01:04:45.440 --> 01:04:47.340
was the value of Fib
of N minus 2.

01:04:52.950 --> 01:04:56.180
And I'm going to restore
the value register now.

01:05:01.850 --> 01:05:06.290
This restore matches this
save. And if you're very

01:05:06.290 --> 01:05:09.820
careful and examine very
carefully what goes on,

01:05:09.820 --> 01:05:13.840
restores and saves are
always matched.

01:05:13.840 --> 01:05:15.660
Now there's an outstanding save,
of course, that we have

01:05:15.660 --> 01:05:19.000
to get rid of soon.

01:05:19.000 --> 01:05:20.590
And so I restored the
value register.

01:05:20.590 --> 01:05:34.850
Now I restore the continue one,
which matches this one,

01:05:34.850 --> 01:05:41.300
dot, dot, dot, dot, dot, dot,
dot, down to here, restoring

01:05:41.300 --> 01:05:42.860
that continuation.

01:05:42.860 --> 01:05:46.600
That continuation is a
continuation of Fib of N,

01:05:46.600 --> 01:05:48.330
which is the problem I was
trying to solve, a major

01:05:48.330 --> 01:05:49.665
problem I'm trying to solve.

01:05:49.665 --> 01:05:52.670
So that's the guy I have to go
back to who wants Fib of N. I

01:05:52.670 --> 01:05:55.470
saved them all the way up here
when I realized N was

01:05:55.470 --> 01:05:57.360
not less than 2.

01:05:57.360 --> 01:06:00.840
And so I had to do a complicated
operation.

01:06:00.840 --> 01:06:03.240
Now I've got everything
I need to do it.

01:06:03.240 --> 01:06:17.470
So I'm going to restore that,
assign to VAL the sum of fetch

01:06:17.470 --> 01:06:28.335
VAL and fetch of N, and
go to continue.

01:06:38.260 --> 01:06:45.750
So now I've returned from
computing Fibonacci of N, the

01:06:45.750 --> 01:06:47.110
general case.

01:06:47.110 --> 01:06:51.230
Now what's left is we have to
fix up a few details, like

01:06:51.230 --> 01:07:03.750
there's the base case of this
induction, immediate answer,

01:07:03.750 --> 01:07:13.710
which is nothing more than
assign to VAL fetch of N,

01:07:13.710 --> 01:07:17.120
because N was less than 2, and
therefore, the answer is N in

01:07:17.120 --> 01:07:26.095
our original program, and
return continue--

01:07:31.460 --> 01:07:34.800
bobble, bobble almost--

01:07:34.800 --> 01:07:36.130
and finally Fib done.

01:07:43.460 --> 01:07:45.640
So that's a fairly complicated
program.

01:07:45.640 --> 01:07:47.950
And the reason I wanted you see
to that is because I want

01:07:47.950 --> 01:07:51.740
you to see the particular
flavors of stack discipline

01:07:51.740 --> 01:07:52.965
that I was obeying.

01:07:52.965 --> 01:07:57.240
It was first of all, I don't
want to take anything that I'm

01:07:57.240 --> 01:08:00.395
not going to need later.

01:08:00.395 --> 01:08:01.850
I was being very careful.

01:08:01.850 --> 01:08:03.940
And it's very important.

01:08:03.940 --> 01:08:07.095
And there are all sorts of other
disciplines people make

01:08:07.095 --> 01:08:10.520
with frames and things like that
of some sort, where you

01:08:10.520 --> 01:08:12.280
save all sorts of junk you're
not going to need later and

01:08:12.280 --> 01:08:15.830
restore it because, in some
sense, it's easier to do that.

01:08:15.830 --> 01:08:19.109
That's going to lead to various
disasters, which we'll

01:08:19.109 --> 01:08:21.740
see a little later.

01:08:21.740 --> 01:08:23.560
It's crucial to say exactly
what you're

01:08:23.560 --> 01:08:24.810
going to need later.

01:08:26.899 --> 01:08:29.859
It's an important idea.

01:08:29.859 --> 01:08:34.020
And the responsibility of that
is whoever saves something is

01:08:34.020 --> 01:08:36.930
the guy who restores it,
because he needs it.

01:08:36.930 --> 01:08:40.130
And in such discipline, you
can see what things are

01:08:40.130 --> 01:08:46.940
unnecessary, operations
that are unimportant.

01:08:46.940 --> 01:08:49.950
Now, one other thing I want to
tell you about that's very

01:08:49.950 --> 01:08:54.120
simple is that, of course, the
picture you see is not the

01:08:54.120 --> 01:08:55.350
whole picture.

01:08:55.350 --> 01:08:58.430
Supposing I had systems that
had things like other

01:08:58.430 --> 01:09:06.080
operations, CAR, CDR, cons,
building a vector and

01:09:06.080 --> 01:09:10.000
referencing the nth element of
it, or things like that.

01:09:10.000 --> 01:09:14.229
Well, at this level of detail,
whatever it is, we can

01:09:14.229 --> 01:09:15.520
conceptualize those
as primitive

01:09:15.520 --> 01:09:18.299
operations in the datapath.

01:09:18.299 --> 01:09:21.020
In other words, we could say
that some machine that, for

01:09:21.020 --> 01:09:25.460
example, has the append machine,
which has to do cons

01:09:25.460 --> 01:09:29.870
of the CAR of x with the append
of the CDR of x and y,

01:09:29.870 --> 01:09:31.149
well, gee, that's exactly
the same as

01:09:31.149 --> 01:09:33.630
the factorial structure.

01:09:33.630 --> 01:09:36.133
Well, it's got about
the same structure.

01:09:36.133 --> 01:09:37.270
And what do we have?

01:09:37.270 --> 01:09:41.590
We have some sort of things in
it which may be registers, x

01:09:41.590 --> 01:09:45.490
and y, and then x has to somehow
move to y sometimes, x

01:09:45.490 --> 01:09:46.939
has to get the value of y.

01:09:46.939 --> 01:09:48.000
And then we may have
to be able to do

01:09:48.000 --> 01:09:51.700
something which is a cons.

01:09:51.700 --> 01:09:57.760
I don't remember if I need to
like this is in this system,

01:09:57.760 --> 01:10:01.420
but cons is sort of like
subtract or add or something.

01:10:01.420 --> 01:10:03.800
It combines two things,
producing a thing which is the

01:10:03.800 --> 01:10:07.600
cons, which we may then
think goes into there.

01:10:07.600 --> 01:10:14.920
And then maybe a thing called
the CAR, which will produce--

01:10:14.920 --> 01:10:16.920
I can get the CAR
or something.

01:10:16.920 --> 01:10:20.150
And maybe I can get the CDR
of something, and so on.

01:10:20.150 --> 01:10:22.730
But we shouldn't be too afraid
of saying things this way,

01:10:22.730 --> 01:10:27.330
because the worst that could
happen is if we open up cons,

01:10:27.330 --> 01:10:31.770
what we're going to find
is some machine.

01:10:31.770 --> 01:10:33.750
And cons may in fact overlap
with CAR and CDR, and it

01:10:33.750 --> 01:10:38.660
always does, in the same way
that plus and minus overlap,

01:10:38.660 --> 01:10:41.210
and really the same business.

01:10:41.210 --> 01:10:42.950
Cons, CAR, and CDR are going to
overlap, and we're going to

01:10:42.950 --> 01:10:48.630
find a little controller, a
little datapath, which may

01:10:48.630 --> 01:10:53.300
have some registers in it,
some stuff like that.

01:10:53.300 --> 01:10:56.650
And maybe inside it, there may
also be an infinite part, a

01:10:56.650 --> 01:10:59.440
part that's semi-infinite or
something, which is a lot of

01:10:59.440 --> 01:11:02.030
very uniform stuff, which
we'll call memory.

01:11:06.570 --> 01:11:09.330
And I wouldn't be so horrified
if that were the way it works.

01:11:09.330 --> 01:11:13.320
In fact, it does, and we'll
talk about that later.

01:11:13.320 --> 01:11:14.570
So are there any questions?

01:11:24.340 --> 01:11:25.665
Gee, what an unquestioning
audience.

01:11:28.670 --> 01:11:30.330
Suppose I tell you a horrible
pile of lies.

01:11:39.690 --> 01:11:41.990
OK.

01:11:41.990 --> 01:11:42.520
Well, thank you.

01:11:42.520 --> 01:11:44.230
Let's take our break.

01:11:44.230 --> 01:11:47.230
[MUSIC PLAYING - "JESU, JOY OF
MAN'S DESIRING" BY JOHANN

01:11:47.230 --> 01:11:48.780
SEBASTIAN BACH]