Induction is closely related to recursion in several ways. In proving a
recursive algorithm correct, it's natural to use induction on the argument
as in our examples earlier. Here our predicate P(n), in the case where the
argument to the algorithm is a `natural`

,
might be ``the algorithm terminates with the correct output
on input n''. If the algorithm calls itself only with an argument that
is the predecessor of the original argument, you can complete the inductive
step by assuming the correctness of the algorithm for input n and verifying
it for input n+1.
The base step is generally explicit in the
algorithm. This method
is particularly useful for proving that a recursive algorithm
explicitly follows a recursive definition.

If the recursive algorithm calls itself with arguments smaller than the original one, though not necessarily just the predecessor of the original argument, we can use strong induction (as in Section 4.4). For the inductive step, we would assume the correctness of the algorithm for all inputs i≤n, and then prove correctness for input n+1.

In this Excursion we are going to look at two fundamental functions, one that converts binary strings to naturals, and the other that converts naturals to binary strings. (Are these two functions actually inverses of each other?) We'll begin with the recursive definitions of how a string represents a number and vice versa.

- The string λ represents the natural 0.
- If w represents n, then w0 represents 2n and w1 represents 2n+1.

- The natural 0 is represented by the string 0.
- The natural 1 is represented by the string 1.
- If n>1, we divide n by two,
let w represent the quotient (Java
`n/2`

), let a represent the remainder (Java`n%2`

), and represent n by wa.

A few examples
should convince you that these definitions correspond to the
usual representation of naturals as binary strings. For one example, the
representation of 7 is that of 3 followed by a one, that of 3 is that
of 1 followed by a one, that of 1 *is* a one by the base case, giving
us 111, the correct binary for 7.

So now we try to code these up as Java-syntax algorithms,
given our standard procedures
for both naturals and strings (Again, recall that we are using our mathematical
`string`

primitive
type rather than the Java `String`

class:

```
natural value (string w)
{// Returns natural number value of the given binary string.
if (w == emptystring) return 0;
string abl = allButLast(w);
if (last(w) == '0')
return 2 * value (abl);
else return (2 * value (abl)) + 1;}
```

```
string rep (natural n)
{// Returns canonical binary string representing the given natural.
if (n == 0) return "0";
if (n == 1) return "1";
string w = rep (n/2);
if (n%2 == 0)
return append (w, "0");
else return append (w, "1");}
```

- Show by induction for all binary strings w that
`value(w)`

terminates and outputs the correct natural according to the definitions. - Show by (strong) induction for all naturals
n that
`rep(n)`

terminates and outputs the correct string according to the definitions. You will need two separate base cases for n=0 and n=1.

Last modified 21 October 2004