Checking Recursive Function Definitions


Hand simulation with recursion

In the previous page we saw that computing factorial(4) is a long process. The process that we went through is how the computer does the computation, but it turns out that you, the programmer, can avoid all of that work. (That is a good thing, right?)

Suppose that you write a definition of the factorial function by cases.

  case factorial(n) = 1                   when n == 1
  case factorial(n) = factorial(n-1) * n
Now we want to do some hand simulations to see whether this works. But we happen to know that we want factorial(n) to be n!. So let's try out factorial(4) again. But this time, if we encounter a use of factorial(x) for a value of x that is smaller than 4, we just presume that what we want to be true really is true! That is, for all values of x that are smaller than our starting value, factorial(x) = x!
  factorial(4) 
    = factorial(4-1) * 4     (by the second case, since 4 == 1 is false)
    = factorial(3) * 4
    = 6 * 4                  (by the presumption that factorial(3) = 3!,
                              and our knowledge that 3! = 1*2*3 = 6)
    = 24
Notice that this result is consistent with what we think is true, since 4! = 24. That is it.

It turns out that, if you verify your claim on the assumption that the claim holds for smaller values than the starting value, then the claim will have to be true, as long as your values are always nonnegative integers. (Mathematicians call that induction.)


Case study: powers

We defined the power function as follows.

  case power(x, n) = x                  when n == 1
  case power(x, n) = x * power(x, n-1)  when n > 1
Suppose that you think that power(x,n) = xn, as long as n is a positive integer.

When there are two or more arguments, you can select one of them, and assume that your belief is true whenever the value of that argument is smaller than the one that you started with. For the power function, it is a good idea to use the second argument, n. Let's try that to compute power(3,4).

  power(3,4)
    = 3*power(3, 4-1)
    = 3*power(3, 3)
    = 3*27              (since the the second argument 3 is smaller
                         than the starting value, 4)
    = 81
That is consistent with our claim that power(x,n) = xn.


Problems

  1. [solve] Do a hand simulation of factorial(5). But assume that factorial(k) = k! for all values of k that are less than 5. Just jump immediately to the answer for them.

  2. [solve] Suppose that sum(n) is defined as follows.

      case sum(n) = 1              when n == 1
      case sum(n) = sum(n-1) + n
    
    You would like to check that sum(n) = 1 + 2 + ... + n by trying it for sum(5). Do an evaluation of sum(5). But assume that sum(k) = 1 + 2 + ... + k for all values of k that are less than 5.


Summary

When checking a recursive definition, make sure that you first know what you think it does. Then, when doing a check, assume that you are right all arguments that are smaller than the argument that you started with.

If there are two or more arguments, choose one of them. You can assume that you are right when that one has decreased.


Review

The equations that define a function can use the same function that you are defining. Doing that is called using recursion.

Recursion allows you to write simple and elegant definitions of a wide variety of functions.

Recursion always relies on using more than one case.