 Welcome back. In the last segment, we discussed Virahanka's problem. This was about finding the number of poetic meters having duration D. In this segment, we are going to discuss a program to calculate V of D. So it seems that it is natural to use a recursive function. So since we were told that for D greater than 2, V of D equals V of D minus 1 plus V of D minus 2 will match the recursion sort of stares as in the face. And we were also told that for D equal to 1, what the values were for D equal to 1 and D equal to 2 and therefore D should be the base cases. So this might be a natural program to write. So V of D which is what we want to calculate where the precondition is that D is bigger than 0. So if D is equal to 1, then we return 1. If D equals 2, then we return 2. Else we use this relationship. That is it. So the question is, is this a reasonable program? We just wrote it. But can we be sure or can we somehow check whether this is a good program? Well, so here is our program and in the last lecture, we listed out some four requirements that we should check when we write a recursive function. So what were those? So first of all, our concern was, is the correct value returned for the base cases? First of all, are there base cases? So are there base cases? Yes, there are two base cases. Before that, this is one base case and is the correct value being returned? Yes, because that was specified in the problem definition or we worked it out. And for D equal to 2, is the correct value being returned? Yes, we worked that out and that was 2. Now does the level 1 call satisfy the precondition? So which are the level 1 calls? So this is one level 1 call, this is another level 1 call. And what is the precondition? D should be bigger than 0. So when we make this level 1 call, is this satisfied? Well, originally this was satisfied for D. If D was 1, then we would have returned 1. If D was 2, we would have returned. So when we come to this point, we know that D has to be bigger than 3 or 3 or bigger. So then, V of 3 minus 1 or something bigger than 3 even, this number will be positive. So then, that means this precondition will be satisfied. And this number will also be positive because we said that D has to be bigger than or equal to 3 at this point. So even for this case, the precondition will be satisfied. Now does the problem size reduce? Can it reduce indefinitely? So clearly in this case, the problem size is D. There is no other candidate really. So does it reduce when we make the recursive calls? Is it reducing in the level 1 calls? Yes, it has gone to D minus 1 and D minus 2. But as it reduces, can it go below 1? Can it go to 0? Well, we just said that, that when we make the recursive calls, the preconditions are satisfied. And therefore, 0 is a limit. So the recursive, the size cannot go to 0, cannot go below 1. And therefore, this set of recursive calls will have to terminate in some sense. Final, the last check that we need to make is that if we assume that the level 1 calls return the correct value, then can you argue that the top level calls with the top level call is correct? So this is the top level call, V of D. And we are assuming that these values are correct, V of D minus 1. So V of D minus 1 plus V of D minus 2. So this is correct and this is correct. So in that case, are we supposed to return this? Well, we got to this only if D is bigger than 2 and in that case, indeed we are supposed to return this. And therefore, the top level call is going to be correct if our level 1 calls are correct. So this really does look like a good recursive function. So that is what I have written down over here. So let us now do a demo. So this is the program that I showed to you and I have the main program and I am calling V of I. So I am just doing this for all values of I between 1 and 50. So let us see how this goes. So let us run it. So it is calculating answers pretty fast but well, now it seems to have slowed down. So let me terminate it over here. Oh no, no, 45, I think 44 it took a long time, 45 maybe it will take even longer and then even longer for 46. So let me not make you wait through all of this but clearly the program has slowed down over here. So let me terminate. And I forgot to tell you one thing which is that when we write this program we are going to use long end. Why? Because as you saw the numbers were getting bigger than what can be held in a single word. So this would be long ends and because of that you could print you could get all those numbers correctly. So at this point we have a puzzle. We wanted to calculate the first 50 Virahanka numbers but the program seemed to be taking too much time at about 45. So we need to figure out why that is the case. Beyond equal to 45 the time for V of D seems to increase a lot. So for that why that is happening let us try to understand the execution of V of D. Now the execution of any recursive program can be visualized by drawing its execution tree or in this case what might be called its recursion tree. The execution tree is really like the trees seen earlier. The root corresponds to the original call say V of 10. Then V of 10 will make recursive calls to V of 9 and V of 8. So we will have branches going out to nodes for V of 9 and V of 8. From those we will have further branches going according to the further recursive calls that get made. And V of 1 and V of 2 return without recursion. So no branches leave the nodes corresponding to V of 1 and V of 2. So what I am going to do now is to show you this recursion tree. So for some execution of Viranka and in fact that I am going to do by running another program. So I have written a program which will draw the execution tree or the recursion tree of Viranka. So let us see how it gets drawn. So this is the recursion tree. Let me explain what is going on. So there are two sets of numbers appearing on every node. So the red numbers are the numbers which are the arguments to the call. So this is asking for V of 8 to be calculated. In order to calculate V of 8 there is a call made to V of 7 and also to V of 6. Then to calculate V of 7 there is a call is made to V of 6 and also to V of 5 and so on. And the blue numbers are the results. So these are the arguments. The red numbers are the arguments to Viranka and the blue numbers are the results of the calls or this is V of 8. This is V of 7. This is V of 6 and so on. Let me run it again so that you can see the order in which the numbers get printed. So first all the red numbers will get printed. That is because first I will know only the arguments. So in order to calculate V of 8 I need to calculate V of 7. But the blue numbers will get printed then from bottom up so to say. As soon as this Viranka returns then you know that the result over here is a 1. When this returns you know that that V of 3 is 3 and so on. So here finally when everything is done 34 will get printed indicating that V of 8 is 34. So let me just run it again so that you can see the order in which things are happening. So right now only on the left side only the arguments are known and now as things get built up then the results are also known, the values of V are also known. So now let us look at this and let us see if we can find anything interesting. Indeed there is something very interesting in this. So we want to calculate V of 7 and this subtree is what is useful for calculating V of 7. So this subtree is responsible for calculating V of 6. But even while calculating V of 7 we had to calculate V of 6, we did calculate V of 6. So this is that calculation and what I want you to notice is that this calculation is exactly the same as this calculation. Now that is really not good because this work is exactly the same as this work and we duplicated it over here but that is not all, things get much worse. So for example let us look at V of 5, this subtree let us look at V of what this number is V of 4. So let us look at V of 4. So we want to calculate V of 4 so that is what this subtree is doing. But V of 4 is being calculated here as well and here and here and here. So V of 4, the calculation of V of 4 is being done in many, many, many places. So clearly something is wrong. I mean if you want to calculate V of 45 in this manner several, several Virahanka numbers will be calculated far too many times and in fact that is why it was taking so long to calculate Virahanka of 45. Of course everything is taking long but that length really shows up when you get to 45. So what can we do? First of all let us go back to our slides. So we said that several subtrees are doing the same calculation and so what have we discussed at this point? We have discussed recursive function to calculate Virahanka numbers V of d and we observed that the function takes a lot of time for d greater than 45 and when we plotted the execution tree or the recursion tree it shows that we are performing the same calculation several times. So in the next segment we are going to see how to avoid this duplication of work. So before that we will take a quick break.