CMPUT-272 · Lesson 10 of 12 · 42 min
Mathematical induction and recursion
Mathematical induction is the main tool for proving that a statement holds for every natural number, and so for every input size, every list length and every number of loop iterations. It is the mathematical twin of recursion: a recursive function solves a problem by solving a smaller instance, and an inductive proof proves a statement by relying on a smaller instance. This lesson covers ordinary induction, strong induction, recursive definitions and structural induction, and shows how each one proves facts about programs.
The principle of induction
Let \(P(n)\) be a statement about natural numbers. To prove \(\forall n \ge b\, P(n)\), it is enough to prove two things. The base case: \(P(b)\) is true. The inductive step: for every \(k \ge b\), if \(P(k)\) is true then \(P(k+1)\) is true. In the inductive step, the assumption \(P(k)\) is called the inductive hypothesis.
The image of dominoes makes it convincing. The base case knocks over the first domino. The inductive step guarantees that each falling domino knocks over the next. Together they topple every domino, however long the line. Logically, the base case and inductive step give \(P(b)\), then \(P(b+1)\) by modus ponens, then \(P(b+2)\), and so on with no exceptions. Induction is accepted as an axiom about the natural numbers, equivalent to the well-ordering principle: every non-empty set of natural numbers has a least element.
Worked problem
The sum of the first n integers
Prove: for every n ≥ 1, 1 + 2 + ... + n = n(n + 1)/2.
Show solution
- Let P(n) be the statement 1 + 2 + ... + n = n(n + 1)/2.
- Base case, n = 1: the left side is 1 and the right side is 1 · 2/2 = 1. True.
- Inductive step: let k ≥ 1 and assume P(k): 1 + ... + k = k(k + 1)/2.
- Then 1 + ... + k + (k + 1) = k(k + 1)/2 + (k + 1), using the inductive hypothesis.
- = (k(k + 1) + 2(k + 1))/2 = (k + 1)(k + 2)/2, which is P(k + 1).
- By induction, P(n) holds for all n ≥ 1.
Answer: The formula holds for every n ≥ 1. This sum gives the number of comparisons in selection sort, which you met in CMPUT-174.
The inductive step is where the work happens, and it always has the same shape: write the statement for \(k+1\), find the statement for \(k\) inside it, replace that part using the inductive hypothesis, and simplify to the required form. If you never used the inductive hypothesis, either the statement was easy without induction or the proof has a gap.
from fractions import Fraction
# Evidence first: check the formulas we will prove for many n
print(all(sum(range(1, n + 1)) == n * (n + 1) // 2 for n in range(1, 2001)))
print(all(sum(i * i for i in range(1, n + 1)) == n * (n + 1) * (2 * n + 1) // 6 for n in range(1, 2001)))
print(all(sum(2 ** i for i in range(n + 1)) == 2 ** (n + 1) - 1 for n in range(0, 200)))
print(all(sum(Fraction(1, i * (i + 1)) for i in range(1, n + 1)) == Fraction(n, n + 1) for n in range(1, 200)))True True True True
Worked problem
A geometric sum
Prove: for every n ≥ 0, 2⁰ + 2¹ + ... + 2ⁿ = 2ⁿ⁺¹ − 1.
Show solution
- Base case, n = 0: left side 1, right side 2 − 1 = 1. True.
- Inductive step: assume 2⁰ + ... + 2ᵏ = 2ᵏ⁺¹ − 1.
- Then 2⁰ + ... + 2ᵏ + 2ᵏ⁺¹ = (2ᵏ⁺¹ − 1) + 2ᵏ⁺¹ = 2 · 2ᵏ⁺¹ − 1 = 2ᵏ⁺² − 1.
- That is the statement for k + 1, so the formula holds for all n ≥ 0.
Answer: Proved. In computing terms: a binary number of n + 1 ones equals 2ⁿ⁺¹ − 1, and a complete binary tree of height n has 2ⁿ⁺¹ − 1 nodes.
Induction for inequalities and divisibility
Induction is not only for sums. In lesson 1 we explored the claim \(2^n > n^2\) and found it holds from \(n = 5\). Induction proves it, with the base case at 5.
Worked problem
An inequality with a later base case
Prove: for every integer n ≥ 5, 2ⁿ > n².
Show solution
- Base case, n = 5: 32 > 25. True.
- Inductive step: let k ≥ 5 and assume 2ᵏ > k².
- Then 2ᵏ⁺¹ = 2 · 2ᵏ > 2k², by the hypothesis.
- It remains to show 2k² ≥ (k + 1)² = k² + 2k + 1, that is, k² ≥ 2k + 1. For k ≥ 5, k² = k · k ≥ 5k = 2k + 3k > 2k + 1.
- So 2ᵏ⁺¹ > 2k² ≥ (k + 1)², and P(k + 1) holds.
Answer: Proved for all n ≥ 5. The inductive step needed k ≥ 5 at one point; that is why the base case cannot be earlier.
Worked problem
Divisibility by induction
Prove: for every n ≥ 0, 3 divides n³ + 2n.
Show solution
- Base case, n = 0: 0 is divisible by 3.
- Inductive step: assume 3 | (k³ + 2k).
- (k + 1)³ + 2(k + 1) = k³ + 3k² + 3k + 1 + 2k + 2 = (k³ + 2k) + 3(k² + k + 1).
- The first part is divisible by 3 by hypothesis and the second is 3 times an integer, so the sum is divisible by 3.
Answer: 3 divides n³ + 2n for all n ≥ 0.
Strong induction
In ordinary induction, the step from \(k\) to \(k+1\) uses only \(P(k)\). In strong induction, the step may use \(P(b), P(b+1), \ldots, P(k)\): all earlier cases. Strong induction is no more powerful logically, but it is far more convenient when \(P(k+1)\) depends on a case several steps back, as happens with recursive algorithms that split a problem in half or with sequences defined by more than one earlier term.
Worked problem
Every integer greater than 1 is a product of primes
Prove: every integer n ≥ 2 can be written as a product of one or more primes.
Show solution
- Base case, n = 2: 2 is prime, so it is a product of one prime.
- Inductive step: let k ≥ 2 and assume every integer from 2 to k is a product of primes. Consider k + 1.
- Case 1: k + 1 is prime. Then it is a product of one prime.
- Case 2: k + 1 is composite, so k + 1 = ab with 2 ≤ a, b ≤ k.
- By the strong inductive hypothesis, a and b are each products of primes, so their product k + 1 is too.
Answer: Proved. Ordinary induction would not work: knowing k is a product of primes says nothing useful about k + 1. Euclid's proof in lesson 6 relied on this fact.
Worked problem
The postage stamp problem
Prove: every amount of postage of 12 cents or more can be made using 4-cent and 5-cent stamps.
Show solution
- Base cases: 12 = 4 + 4 + 4; 13 = 4 + 4 + 5; 14 = 4 + 5 + 5; 15 = 5 + 5 + 5.
- Inductive step: let k ≥ 15 and assume every amount from 12 to k can be made. Consider k + 1.
- Since k + 1 ≥ 16, the amount k + 1 − 4 = k − 3 is at least 12, so it can be made by hypothesis.
- Add one 4-cent stamp to make k + 1.
Answer: Proved. Four base cases were needed because the step reaches back 4 amounts. The program below checks the amounts and finds an actual combination for each.
def stamps(n):
"""Return (fours, fives) with 4*fours + 5*fives == n, or None."""
for fives in range(n // 5 + 1):
rest = n - 5 * fives
if rest % 4 == 0:
return rest // 4, fives
return None
print("cannot make:", [n for n in range(1, 12) if stamps(n) is None])
for n in [12, 13, 14, 15, 16, 31, 100]:
print(n, "=", stamps(n))
print("all of 12..10000 possible:", all(stamps(n) for n in range(12, 10001)))cannot make: [1, 2, 3, 6, 7, 11] 12 = (3, 0) 13 = (2, 1) 14 = (1, 2) 15 = (0, 3) 16 = (4, 0) 31 = (4, 3) 100 = (25, 0) all of 12..10000 possible: True
Recursive definitions
A recursive definition defines an object in terms of smaller versions of itself. It has two parts, just like an inductive proof: base cases, and a recursive rule. The factorial function is defined by \(0! = 1\) and \(n! = n \cdot (n-1)!\) for \(n \ge 1\). The Fibonacci numbers are defined by \(F_0 = 0\), \(F_1 = 1\) and \(F_n = F_{n-1} + F_{n-2}\) for \(n \ge 2\). Because recursive definitions build each value from earlier ones, induction is the natural way to prove things about them.
Worked problem
A Fibonacci bound by strong induction
Prove: for every n ≥ 0, Fₙ < 2ⁿ.
Show solution
- Base cases: F₀ = 0 < 1 = 2⁰ and F₁ = 1 < 2 = 2¹.
- Inductive step: let k ≥ 1 and assume Fᵢ < 2ⁱ for all i ≤ k.
- Then F_{k+1} = F_k + F_{k−1} < 2ᵏ + 2ᵏ⁻¹ < 2ᵏ + 2ᵏ = 2ᵏ⁺¹.
- So F_{k+1} < 2ᵏ⁺¹.
Answer: Fₙ < 2ⁿ for all n. Two base cases were needed because the rule uses the two previous terms. A sharper argument shows Fₙ grows like φⁿ with φ = (1 + √5)/2 ≈ 1.618.
def fib(n):
a, b = 0, 1
for _ in range(n):
a, b = b, a + b
return a
print([fib(n) for n in range(15)])
print("F_n < 2^n for n < 500:", all(fib(n) < 2 ** n for n in range(500)))
phi = (1 + 5 ** 0.5) / 2
for n in (10, 20, 30):
print(f"F_{n} = {fib(n):7d} phi^{n}/sqrt(5) = {phi ** n / 5 ** 0.5:10.1f}")[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377] F_n < 2^n for n < 500: True F_10 = 55 phi^10/sqrt(5) = 55.0 F_20 = 6765 phi^20/sqrt(5) = 6765.0 F_30 = 832040 phi^30/sqrt(5) = 832040.0
Recursion and induction are the same idea
A recursive function is correct for exactly the reason an inductive proof works. To show that a recursive function returns the right answer for every input, prove by induction on the input size: the base case of the function returns the right answer, and if every recursive call on a smaller input returns the right answer (the inductive hypothesis), then the combination step produces the right answer.
Worked problem
Proving a recursive function correct
Prove that power(x, n) below returns xⁿ for every n ≥ 0: if n == 0 return 1; else return x * power(x, n − 1).
Show solution
- Induction on n. Base case n = 0: the function returns 1 = x⁰.
- Inductive step: assume power(x, k) returns xᵏ. Call power(x, k + 1).
- Since k + 1 ≠ 0, it returns x * power(x, k) = x · xᵏ = xᵏ⁺¹, by the hypothesis.
- Termination: each call reduces n by 1, so the recursion reaches n = 0.
Answer: Correct for all n ≥ 0. A full correctness proof needs both parts: the right answer if it stops, and a proof that it stops.
A faster version, fast exponentiation, computes \(x^n\) by squaring: if \(n\) is even, \(x^n = (x^{n/2})^2\); if odd, \(x^n = x \cdot x^{n-1}\). Its correctness proof needs strong induction, because the recursive call is on \(n/2\), not \(n - 1\). This algorithm makes RSA encryption practical, as lesson 11 shows.
def fast_pow(x, n):
if n == 0:
return 1
if n % 2 == 0:
half = fast_pow(x, n // 2) # strong induction: n // 2 < n
return half * half
return x * fast_pow(x, n - 1)
calls = 0
def counted(x, n):
global calls
calls += 1
if n == 0: return 1
if n % 2 == 0:
h = counted(x, n // 2); return h * h
return x * counted(x, n - 1)
print(all(fast_pow(3, n) == 3 ** n for n in range(200)))
counted(3, 1000)
print("calls for n = 1000:", calls, " versus 1001 for the simple version")True calls for n = 1000: 16 versus 1001 for the simple version
Structural induction
Many data structures are defined recursively. A list is either empty or an element followed by a list. A binary tree is either empty or a node with a left subtree and a right subtree. Structural induction proves a property for every such structure: prove it for the base structures, then prove that whenever the parts have the property, the structure built from them does too.
Worked problem
Nodes and leaves in full binary trees
A full binary tree is either a single leaf, or a root with two full binary subtrees. Prove that a full binary tree with L leaves has exactly L − 1 internal nodes.
Show solution
- Base case: a single leaf has L = 1 leaf and 0 internal nodes, and 1 − 1 = 0.
- Inductive step: let T have a root and subtrees T₁, T₂ with L₁ and L₂ leaves, and assume they have L₁ − 1 and L₂ − 1 internal nodes.
- T has L = L₁ + L₂ leaves and (L₁ − 1) + (L₂ − 1) + 1 = L₁ + L₂ − 1 internal nodes, counting the root.
- So T has L − 1 internal nodes.
Answer: Proved for every full binary tree. A knockout tournament with 64 teams therefore has 63 games.
Common pitfalls
Induction proofs go wrong in predictable ways. The most famous fake proof claims that all horses are the same color. The base case, one horse, is fine. The inductive step takes a set of \(k+1\) horses, removes one to get \(k\) horses of the same color, removes a different one to get another \(k\) horses of the same color, and argues that the two groups overlap, so all \(k+1\) match. The overlap argument fails when \(k + 1 = 2\): the two groups of one horse each do not overlap. The step from 1 to 2 is broken, so the whole chain collapses.
| Pitfall | Symptom | Fix |
|---|---|---|
| Missing or wrong base case | Step proved but nothing starts the chain | Check the base case explicitly, at the right starting value |
| Step not valid for every k | Horses: the step fails at k = 1 | Check the step works for the smallest k it must cover |
| Hypothesis not used | The step proves P(k + 1) from scratch | Find P(k) inside P(k + 1) |
| Assuming P(k + 1) | The step starts from what it must prove | Start from P(k) and derive P(k + 1) |
| Too few base cases for strong induction | Step reaches back further than the base covers | Provide as many base cases as the step reaches back |
Common mistakes
MistakeSkipping the base case because it looks obvious.
InsteadAlways prove the base case; without it, the inductive step proves nothing.
MistakeAssuming P(k + 1) in the inductive step.
InsteadAssume P(k) (or all earlier cases) and derive P(k + 1).
MistakeUsing ordinary induction when P(k + 1) depends on a case further back.
InsteadUse strong induction, with enough base cases.
MistakeProving a recursive function correct without showing it terminates.
InsteadShow each call works on a smaller input that reaches the base case.
MistakeWriting an inductive step valid only for large k while the base case is small.
InsteadMake sure the step works from the base case onward, or move the base case.
MistakeTreating a computer check of the first thousand cases as an induction proof.
InsteadChecks give evidence; induction gives proof for every n.
Summary and key terms
- Induction proves ∀n ≥ b P(n) from a base case P(b) and an inductive step P(k) → P(k + 1).
- The inductive step must use the inductive hypothesis and hold for every k ≥ b.
- Strong induction assumes all earlier cases; it suits recursions that reach back more than one step.
- Recursive definitions have base cases and a rule, and induction proves their properties.
- Proving a recursive function correct is induction on input size, plus a termination argument.
- Structural induction proves properties of recursively defined structures such as lists and trees.
- Fake proofs like 'all horses are the same color' fail because the step breaks at one value.
- Mathematical induction
- Proving P(n) for all n ≥ b by a base case and an inductive step.
- Base case
- The first value, or values, for which the statement is checked directly.
- Inductive step
- The proof that P(k) implies P(k + 1).
- Inductive hypothesis
- The assumption P(k), or all earlier cases, used in the inductive step.
- Strong induction
- Induction in which the step may use every earlier case.
- Well-ordering principle
- Every non-empty set of natural numbers has a least element.
- Recursive definition
- A definition by base cases and a rule that uses smaller instances.
- Structural induction
- Induction over recursively defined structures such as lists and trees.
- Fibonacci numbers
- The sequence F₀ = 0, F₁ = 1, Fₙ = Fₙ₋₁ + Fₙ₋₂.
- Termination
- The property that a recursive process reaches a base case.
Practice problems
Work each problem on paper first, then reveal the answer to check.
Prove: 1 + 3 + 5 + ... + (2n − 1) = n² for n ≥ 1.
Show answer
Base 1 = 1. Step: n² + (2n + 1) = (n + 1)².
Prove: n! ≥ 2ⁿ⁻¹ for n ≥ 1.
Show answer
Base 1 ≥ 1. Step: (k + 1)! = (k + 1)k! ≥ 2 · 2ᵏ⁻¹ = 2ᵏ since k + 1 ≥ 2.
Prove: 6 divides n³ − n for n ≥ 0.
Show answer
Base 0. Step: (k + 1)³ − (k + 1) = (k³ − k) + 3k(k + 1), and k(k + 1) is even.
Which amounts below 12 cannot be made from 4- and 5-cent stamps?
Show answer
1, 2, 3, 6, 7 and 11.
Why does the Fibonacci bound need two base cases?
Show answer
The rule uses the two previous terms, so the step from k needs cases k and k − 1.
Prove that a list built by n appends has length n.
Show answer
Base: empty list, length 0. Step: appending to a list of length k gives length k + 1.
Find the flaw: 'every n ≥ 1 satisfies n = n + 1, because if k = k + 1 then k + 1 = k + 2'.
Show answer
There is no base case; 1 = 2 is false.
How many games are in a knockout tournament of 128 teams?
Show answer
127, one fewer than the number of leaves.
Prove that fast_pow terminates.
Show answer
Each call reduces n (to n // 2 or n − 1) and n is a non-negative integer, so it reaches 0.
State the inductive hypothesis for proving 2ⁿ > n² for n ≥ 5.
Show answer
For some k ≥ 5, 2ᵏ > k².
Lesson quiz · 5 questions
Score 60% or more to complete this lesson.
Create a free account to save your progress, take quizzes and earn a certificate.