 Hello and welcome back in this final lecture about iteration constructs. We are going to look at how to reason about loops in a program. Here is a quick recap of some of the things we have already studied earlier. We have looked at sequential and conditional execution of statements in a program. We have looked at iteration or looping constructs in a program and we have seen how to solve some simple problems with iteration constructs in C++. In this lecture, we are going to see how we can reason about loops or iteration constructs in a program both as a design activity and as a post design activity. And in that context, we are going to learn about preconditions of loops, post conditions of loops, loop invariance and loop variance and soon you will see that these play a very important role when you try to reason about loops before you have written down your program when you are trying to plan out your program or even after you have written your program if you want to make sure that the loop that you have written is indeed doing what it is intended to do preconditions, post conditions, loop invariance and loop invariance have a very crucial role to play. What is a loop? A loop is a part of a program with an iterative construct and as far as this discussion goes, we are not going to make any distinction between the three different looping constructs in C++ that we have studied. What does a loop compute? When we entered the loop for the first time, there is some relation among the variables of the program. This is often called the precondition before entering the loop and when you exit the loop, the loop would have done some transformations in between and so some potentially different relation might hold among the variables of the program and this relation which holds after the loop has been iterated and once we have exited from the loop is also called the post condition of the loop and what the loop effectively does, it incrementally changes in each iteration the values of various program variables such that we move from a state of the program where the precondition is satisfied to a state of the program where the post condition is satisfied. Remember the precondition and post condition are simply relations among various variables of the program prior to the loop being executed and immediately after the loop being executed. So let us recall the min max example that we had seen in an earlier lecture. In that example, we were given positive integers m and n and we were required to find the value of 3 raise to min mn and also the value of 2 raise to max mn. What I am going to show now is really a fragment of the program that we had seen earlier to solve this problem and I am going to show only that only a fragment because this is the fragment that will involve the loop and that is the interesting part that we want to reason about in this lecture. So if you recall, we had some variable declarations, they were integer variables called min mn and max mn. It is obvious what they are trying to represent the minimum value of mn and the maximum value of mn. They were both initialized to 0. We also had 2 variables called 3 raise to min and 2 raise to max. They were both initialized to 1 and we also had mn, the integers that are going to be provided by the user and we also had 2 variables i and j which were to be used as counters and then we had a loop like this. Now I am not going to go into the details of this loop right now but this is just to refresh your memory that we basically used a for loop which iterated max mn times and within the for loop we had an if condition which made these statements conditionally execute min mn times whereas the other statements outside the if block executed max mn times. So let us not get into the details of these statements we have already discussed these in detail in an earlier lecture. What we want to focus on in this lecture is that there is a for loop here and we want to do some reasoning about it. Now these integer variable declarations and their initializations can be conveniently captured by a precondition where we are saying that there are these integers m which has to be greater than equal to 1 and has to be greater than equal to 1. The problem specification itself says that they must be positive min mn and max mn were both initialized to 0, 2 raise to max and 3 raise to min were both initialized to 1. So this is the precondition these are the relations on the variables that holds prior to entering the loop and after I have executed the loop I want this post condition to hold that min of mn should indeed be equal to the minimum of mn, max of mn should indeed be equal to the maximum of mn, 2 raise to max should be equal to 2 raise to the max of mn and 3 raise to min should be really equal to the value of 3 raise to min mn. The loop that we saw in between what it is really doing is it is incrementally changing values of variables such that starting from the precondition before the loop is entered I finally end up in values of variables that satisfy the post condition. Now you know one can say that suppose I did not give you this loop I just gave you the precondition and the post condition and I said that design a loop which would allow us to go from the precondition to the post condition. So this is a design activity basically we are asking how do we incrementally change variables to affect a transformation from the precondition to the post condition. Alternatively I could give you this loop and then ask well is it the case that this loop really affects the desired transformation from the precondition to the post condition. So this activity is also called verifying a loop and as you will realize it is a post design activity once you have designed and written down your program we can ask this question is this program really doing what we wanted it to do. Now it turns out that both designing and verifying loops requires very similar kind of reasoning and so we are going to look at both these activities together in this lecture. What a loop is really doing is it is iteratively changing values of variables so that the relations between these variables changes in the following way. The relations between these variables satisfies the precondition when we start iterating for the first time immediately after exiting the loop the values between the variables satisfies the post condition and I want to view both this precondition and post condition as special cases of a relation that holds every time we are about to iterate and I will call this a loop invariant for obvious reason this relation holds invariantly every time we are about to iterate. So right at the beginning of the first iteration the loop invariant is really similar to the precondition and the last time the loop iterated and when we went back and checked the loop condition found that it was false and came out the loop invariant at that point should be similar to the post condition. In addition it is also desirable that a loop terminates we do not want infinite loops in most cases. So in order to ensure termination it is desirable to have a certain metric which is integer valued for example the value of a counter and we want to ensure that the value of this metric monotonically changes towards a fixed value so that we know that after some time it will reach that fixed value and at that time the loop will terminate. So such a metric whose value monotonically changes towards the fixed value as the loop iterates is also called the loop variant we will see examples of this right away. So here is our min max loop we have the precondition and the post condition here and I have written loop invariant and loop variant but kept them blank because we want to see how to arrive at a possible loop invariant and the loop variant in this particular case. Now let us see what we want to do here we have two given values to us let us say m and n these are represented by the heights of these two blue vertical bars. We want to initialize i and j to the values of m and n initially so initially the maximum of i and j is this the minimum of i and j is this and we also know that initially min mn and max mn have both been initialized to 0 so they are here. Now as the loop iterates what is going to happen this is how we begin the loop i set to m j set to n min mn and max mn are both set to 0. Now as the loop iterates i and j both reduce whereas min mn and max mn both increase now in this picture the red arrows show the values of max ij min ij at any point of time the blue arrow shows the value of min mn as well as max mn in this case and please note that this blue arrow is the same as the blue arrow over here so the amount by which min mn and max mn has increased is exactly the same as the amount by which both i and j have reduced and as the loop iterates basically the i and j arrows will come down and the min mn max mn arrows will go up so we have this then we have this then we have this and then we have this and at this point notice that j has become 0 and so we want to stop the iteration at this point and say that now we have obtained the minimum value of m and n. So now let us see how we might get a loop invariant from the little animation that we have seen just now. Now if you look at this animation what you find is that the length of this red arrow which is max ij plus the length of the blue arrow which is really the value of min mn as well as max mn gives the whole of m that is the maximum of the two values whereas the length of this red arrow which is min ij plus the length of the blue arrow which is once again the value of min mn as well as max mn gives the minimum of the two values m and n and this is what we want to utilize we want to say that at every point as the loop iterated the value of min ij plus the value of the blue arrow which is the value of min mn actually gives us the minimum of m and n the two inputs that we read in. So we want to write that as an invariant that min ij plus min mn is the minimum of m and n of course when both i and j are greater than equal to 0. So that becomes an invariant that is true every time that we iterate around the loop and now what you observe is that when one of i or j becomes 0 for the first time then min of ij becomes 0 and therefore at that point 0 plus min mn becomes minimum of m and n which means min mn gets truly the value minimum of m and n and this is the time that we want to stop changing the value of min mn any further and we now want to go and calculate max mn. So how do we do that? So this is the time when j has become 0 i is still not 0 we have got the value of minimum mn let us stop changing min mn any further and let us try to get max mn. So what do we do? We get rid of the j part and then we keep decrementing i just like before until i becomes 0 and if you see what happened here once again the value of this red arrow which is max ij plus this blue arrow which is max mn equals the maximum of m and n. So max ij plus max mn equals maximum of m and n and that holds at every point as we iterate and therefore that should give us the next loop invariant that max of ij plus max mn is max of m comma n when at least one of i or j is greater than equal to 0. So clearly when the last of i or j becomes 0 then max ij becomes 0 and I get 0 plus max mn is max of mn which is exactly what I wanted max mn should be truly the maximum value of m and n. Now you know we had this little complication here about when both i and j are greater than equal to 0 then I can use this relation how do we get rid of that? We basically can use something like this saying do not let min ij fall below 0 cap it at 0. So this basically takes care of that little artifact when both ij are greater than equal to 0 and of course here when we said that when at least one of ij is greater than equal to 0 this is exactly how we iterate around the loop when both of them have become less than 0 you know we stop the loop we stop the iteration of the loop and therefore we can say that this relation holds at every time when the loop is iterating. And now of course you know what is the value of 3 raise to min and 2 raise to max we want the value of 3 raise to min to be 3 raise to min mn we want the value of 2 raise to max to be 2 raise to max mn and we have just seen that when min mn becomes equal to min of mn then of course this variable will get the value of 3 raise to min of m and n and when max mn becomes equal to the max of m and n then 2 raise to max will become the value of 2 raise to max of m and n. So this is basically what is happening in this loop i and j were both initialized to m and n they were both decremented we iterated the loop as long as we had greater than equal to 1 for at least one of them when both of them finally became less than or equal to 0 we stopped the iteration and min mn and 3 raise to min were basically incremented and updated as long as both of them were greater than equal to 1. So this is really the loop invariant in our case what is the loop variant in our case remember it has to be an integer valued metric that monotonically changes towards a fixed value. So in this case we have a non-negative integer valued metric which is max of ij that monotonically decreases towards 0 in every iteration. So since in every iteration this is monotonically decreasing towards 0 it must reach 0 at some point and at that point the loop terminates. So this is the loop variant once we have identified this and we know that this changes in every iteration monotonically towards a fixed value and we know that it is going to reach the fixed value after finite number of times we know that the loop is going to terminate. Now obtaining the right loop invariant or variant after you have completed the design is not always an easy step however it is crucial if you have to reason about loops. So the best practice is to write preconditions post conditions invariance and variance as comments when you are programming. So in summary in this lecture we have seen how to reason about loops in programs we have looked at preconditions post conditions loop invariance and loop variance and we have also seen the importance of comments to express preconditions post conditions loop invariance and loop variance. Thank you.