0:00

In this session we'll come back to what we did in the last one.

Namely, proving equational properties of programs using structural induction.

We will practice the newly learned techniques in a somewhat larger proof.

For a more difficult example let's consider the reverse function.

We pick its inefficient definition here because it's more amenable to equational

proofs. So as defining process we would have nil

reverses nil and x followed by XS reverse is the reversal of the list xs followed by

the element X. These two equations are as we know equivalent to the more efficient

version of fork left and closer to what we want to prove.

So we pick them which of course does not prevent us from using at one time the more

efficient definition of reverse. So what we would like to do is prove the

proposition that XS reverse of reverse is XS. So to prove this it's an obvious

induction on the list excess, the base case is really easy. Nil reverse, reverse

is the same thing as nil reverse by the first law of reverse which says that nil

dot reverse is nil and then we again invoke the first law To show that, that

expression now is the same as nil, which establishes the proposition.

Let's look at the induction step so here we would have X followed by XS, and then a

double reverse. What can we do with that?

Well, we can apply the second clause of reverse, which would mean that this

expression here would, can be rewritten to the right-hand side, excess.reverse

followed by X. And then we have our reverse on both sides

here. What else can we do?

Well, That doesn't seem to be anything obvious.

So let's turn to the right hand side. The right hand side would read simply X

followed by XS. So what can we do that?

Well, one thing we could do is apply the induction hypothesis which says that the

list xs is the same as the list xs reverse, reverse.

So then we are left with x followed by xs reverse, reverse and again, there's not

much we can do anymore to this side here. So both sides, unfortunately, have

simplified to different expressions. This expression here and I've that

expression there. So we still need to show that the two

sides are the same and proving it directly by induction doesn't work as we have seen.

What we can try instead is, we can generalize this equation.

So the idea is that, instead of just saying excess to dot reverse here and

here. We replace that with.

An arbitrary list ys. So our new lemma that we want to prove is

for, that for any list ys, ys followed by x reverse is the same as x followed by

ys.reverse. And to prove that equation, we can use a second induction argument, this

time on the list bias so let's try that. So, let's look at the base case first.

So here, YS equals nil and the equation we want to show is that nil followed by

x.reverse is the same as x followed by nil.reverse.

That's the instansation of the lemma that we want to show here.

So, what could we do with the left hand side here?

Well, By the first close of plus, plus, nil is a

left unit, so this thing simply simplifies to list of x.reverse. reverse.

Then the next step would be to expand what list of X is.

So list of X, as we know by its definition, is X followed by nil.

In the next step then, we would involve the second clause of reverse to arrive at

this expression here. When actually there's one intermediate

step that we have to do here. So by the second clause of reverse, what

would we get? We would get the list that follows the

head element first so there would be nil.reverse Followed by, this suffix and

now we can simply find nil.reverse by the first clause of reverse is just nil.

Where as list of x expands to x followed by nil.

So, that's how we arrive, at this expression here.

Now what we can do here is we can again invoke the first clause of plus, plus to

say nil is a left unit and we're just left with x followed by nil.

There's one more step to do. Again by the first clause of reverse we

know that nil.reverse is nil. Or we've just now used this equation

backwards from going from nil to nil.reverse And that's the right hand side

if you want to show here. So we get equality here and the base case

is established. Let's look at the inductive step.

What we need to do here is show that y followed by ys, that's our list, followed

by x reverse is the same as x followed by then y followed by ys reversed.

So let's see how we would go about that let's work on the left hand side here.

First thing we can do is we can pull out the y from its binding with the list YS,

using the second list of comcat. So we have the Y as a head element here,

and then the list YS, followed by list of X.

The next thing we can do is we can invoke the law of reverse, which says well

reverse of a list that starts with Y is the same as reversal of the rest of the

list here. And the y becomes the last element of the

new list. The next thing we can do is apply the

induction hypothesis because we see here that the expression ys followed by list x

reverse, that's the left hand side of the equation with just the list ys and we can

assume that, that, that, that equation holds.

So we can rewrite it to the right hand side of the equation which will be x

followed by yes.reverse. Now we can apply the first clause of plus, plus to pull out

the accelerant. And we can apply the second clause of

reverse to establish that Y followed by ys reverse, is the same as ys reverse

followed by a list of y. And again we have equality here.

7:01

So the auxiliary equation is established and because the auxiliary equation was the

last thing was needed to prove the main proposition, that accessory versus

success, we adapt. So the proof methodology you have seen

here, worked in essentially three steps We could apply a defining equation, either of

reverse or contact and we could apply it in two different ways.

So. What you've seen here, for instance, going

from here to here that was, we invoked the equation left to right.

The, that was the second clause of plus, plus, which says plus, plus on a list,

with a head element y is the same thing as, a list that starts with y.

So we can pull out the y. And that step is called typically, an

unfold step. The other, equation of resending step was

what you've seen here in the last step where we have applied an equation

backwards. The equation for reverse right.

Y followed by ys reverse is ys reverse followed by this stuff.

8:41

For equational proofs of functional programs.

So, we finish the session with an exercise, which is a bit more involved

than the previous ones, and, it's open ended, so I won't give you a solution

immediately. So what I want you to do is, prove another

law that's useful, that relates map, and concatenation.

So the law says that, essentially the, a, a, map distributes over concat.

For any lists XS, YS and function F, XS followed by YS and then map the function

is the same thing as mapping the function over XS, mapping it over YS, and

concatenating the results. What you need for the proofs is the

classes of plus, plus, that you've seen, as well as two classes for maps that you

see here. So, again, they derive directly from the

definition of map. First clause says to map a function over

the empty list, you would get the empty list.

The second clause says that to map a function over a list consisting of x

followed by xs. What you get is f applied to the head

element x followed by the result of mapping f over the rest of.