What does it mean for a function program to be correct? One possible answer would be that the definitions in the program satisfy certain laws. Often these laws are represented as equalities between terms. In this session and the next, you're going to see proof techniques that can show that a given set of operations satisfy certain laws. The material in these two sessions is an important dimension of functional programming because it demonstrates one of the core claims of FP, Namely, that it is more amenable to reasoning about programs. On the other hand, the programming parts in this course are not dependent on it, and none of the assignments that we are going to do will test this. So, if you want to go fast, you can skip the material in the next two sessions. On the other hand, EPFL students are required to learn this material because it will be used in the physical exams that we do here at EPFL. Recall the concatenation operation plus, plus on lists. What would it mean to say that plus, plus or the version concat that we've written is correct? When one criterion for correctness would be to say that plus, plus satisfies certain laws that we would expect from concatenation. The laws are that concatenation is associative, so I can put the parentheses here either to the left or to the right of a double concatenation, And that Nil is right unit and a left unit. That means, for any list xs, xs followed by Nil is xs, and Nil followed by xs is second xs. The question is, Given properties like these, how can we prove them? And the answer is, by a new proof principle that we're going to introduce now which is called structural induction on lists. So to introduce structural induction, it's good to first look at its close sibling natural induction. Natural induction is a proof principle that you apply when you want to proof something for all integers greater or equal some smallest integer b. The idea there is that to show a property that the property will hold for all such integers, you just need to show that it holds for the smallest element, b, for the base case, And then for all other integers, you need to show the induction step. The induction step is that if you have P of n, if you assume P of n, then you can conclude that P of n plus one also holds. If you have proven that, then, the principle of natural induction says that the property P holds for all integers greater or equal to b. So, here's an example to recap natural induction. We are looking again at factorial. So here's the usual definition of factorial. And we want to show that for all n greater or equal to four, we have that factorial of n is greater or equal to the power of two to the nth. So, instead of power, we also could use the mathematical notation two to the nth. So, we do that by proof of natural induction. The base case obviously is n4. = four, that's the smallest number we have to consider, And there we can just do it by simple calculation. Factorial of four is 24, and power of two to the fourth is sixteen, 24 is greater than or equal to sixteen. So, the case is established. For the induction step then, we assume that the property holds for n. So, we would assume that factorial of n is greater or equal to twonth. To The nth, and we have to prove the same thing for n plus one. So, let's see what we do. Factorial of n plus one is equal, or here, if we've widened that to greater or equal two n plus one times factorial of n, because that's how we have defined factorial, That's just in second clause in the factorial definition. And that is definitely greater than two times factorial n because we know that n is greater equal to four, so n plus one is greater equal to five. And finally, by the induction hypothesis, we know that two times factorial n is greater or equal than two times power of two to the nth, because our induction hypothesis was that factorial of n is greater or equal to power of two to the nth. And we can use that induction hypothesis freely in our proof. So finally, in the last step, we just simplify power, so, two times two to the nth is, as we know, the same as two to the n plus one. So, this is power two to the n plus one and that's precisely what we want to prove. Factorial n plus one is proven to be greater or equal to power of 2n plus one. So, it follows that the property holds for all integers n greater equal to four. So, one thing we've used here implicitly and quite liberally is that we have applied reduction steps as equalities to parts of terms. So, we have used a reduction in our proof of saying left-hand side equals right-hand side. That works because pure functional programs don't have side effects, so reducing a term is really equivalent to rewriting that term. There's no other effect to be taken account of. That principle is called referential transparency, It's an important tool for equational proofs of functional programs. So, let's look at structural induction now. The principle of structural induction is analogous to natural induction. The idea is that we want to prove a property, P, for all lists, xs. And to do that, we just need to show that P of the empty list holds, That would be the base case. And that second, for any list xs and any element x, we show the induction step which says, assume P of the list xs holds, then you need to show that P of x followed by the list xs also holds. So, instead of constructing numbers starting from a base case and adding one, we construct lists starting from the empty list and consing elements to the top of the list. So, back to our comcat example. We'd like to show that, for any lists xs, ys, zs, concatenation is associative. That means, we can put the parentheses here to the left or to the right. To do this, we use a structure induction on the list xs. From the previous implementation of concat that you see here, we can distill two defining clauses for plus, plus. We can say, well, if the first element xs is Nil and is followed by a list ys, then we get ys here. And the second clause would say, well, if the first list is x followed by xs1, and then ys, then the answer would be x followed by the concatenation of xs1 and ys. So, these two clauses here, they're directly derived from the implementation. Essentially, they codify what the implementation does. So, lets now look at the structure induction. The best case would be that our list xs equals Nil. So here, we would have, for the left-hand side, of our equation Nil, followed by ys, followed by zs. And that can simp, can be simplified to just ys, followed by zs. Why? Because of the first clause of plus, plus which says, Nil, followed by ys is ys. Let's look at the right-hand side of the equation, there we would have Nil follow up by, the parenthesis to the right, ys and zs. But, of course, again, we can evoke the first clause of plus, plus and simplify to ys plus za. So, we have an equality here, and here, and the cases is established. So, let's now turn to the induction step. As the left most list, we would have x followed by xs, and then ys, and then zs, and the left-hand side has all parenthesis going to the left. How can we simplify that? Well, one thing we can do is, we can pull the x out of the parenthasis with the xs. So now, xs would go with ys, And the x would be outside of that list. That we can do by the second clause of concat which says, concatinating a list that starts with x is a list that starts with x and contanition of the rest of the list. So, it was the second clause of concat that said that. Once we have that, what's the next step? Well, x is still within another head list, so we can involved the second clause of concat again. And now, we would have x leading the whole result of the concatination. So, what's the next step? Well, the next step would be that, look here, what you see is xs followed by ys, followed by zs. That's actually the left-hand side of our induction hypothesis which says, assume you have proven the equation already for the list xs. So, we can invoke the induction hypothesis and rewrite this expression here to the expression on the right-hand side. So, parenthesis here, now go to the right. And that's all we're going to do with the left-hand side. Let's now turn to the right-hand side. So here, we would have the parenthesis go to the right, ys and zs, let's concanatinate it and then we have on the left x followed by xs. What can we do with that expression? Well, one thing we can do is, again, involve the second clause of plus, plus to pull out the X from the first list here, And that gives x followed by xs, followed by ys and zs. And that is exactly the same as what we simplified the left-hand side to. So, the case and with it the property is established. Let's do an exercise. Let's look at the second law for concat, namely that Nil is the right unit for xs. Can you show by induction that, that law holds? And how many equations do you need for the inductive step? Two? Three? Or four? So, let's see how we would prove this. Let's do the base case first. So, the base case would be that the list xs equals Nil. Then we have on the left-hand side, Nil plus, plus Nil, and that is the same as Nil by the first clause of concat, and that is already what we need. So, we have a when, if xs equals Nil, xs plus Nil is the same as xs. So, let's have a look at the induction step. That will be x followed by xs. So, what we need to prove is that x followed by xs plus, plus Nil, that should be the same as x followed by xs. So, how would we go about that? Well, we have x inside a, a com, a cons here, so we can involve the first clause of plus, plus to put it out. So, that would be the x followed by xs plus, plus Nil. Second clause. And that can be simplified to just x followed by xs by the induction hypothesis because we know we can be allowed to assume that xs followed by Nil is xs, And that is what we wanted to achieve here. So, we have established the case. So, the answer to the question was, we need two steps to establish the inductive