induction

Summary

The induction tactic will turn a goal of the form P n (with P a predicate on naturals, and n a natural) into two goals P 0 and d, P d P d.succ.

Overview

The induction tactic does exactly what you think it will do; it’s a tactic which reduces a goal which depends on a natural to two goals, the base case (always zero, in Lean) and the step case. In computer science it is very common to see a lot of other so-called inductive types (for example list and expr) and the induction tactic can get quite a lot of use; however in this course we only ever use induction on naturals.

Example

We show \(\sum_{i=0}^{n-1}i^2=n(n-1)(2n-1)/6\) by induction on \(n\).

import tactic

open_locale big_operators -- ∑ notation

open finset -- so I can say `range n` for the finite set `{0,1,2,...,n-1}`

-- sum from i = 0 to n - 1 of i^2 is n(n-1)(2n-1)/6
-- note that I immediately coerce into rationals in the statement to get the correct subtraction and
-- division (natural number subtraction and division are pathological functions)
example (n : ) :  i in range n, (i : )^2 = n * (n - 1) * (2 * n - 1) / 6 :=
begin
  induction n with d hd,
  { -- base case says that an empty sum is zero times something, and this sort of goal
    -- is perfect for the simplifier
    simp, },
  { -- inductive step
    rw finset.sum_range_succ, -- the lemma saying
                              -- `∑ i in range (n.succ), f i = (∑ i in range n, f i) + f n`
    rw hd, -- the inductive hypothesis
    simp, -- change `d.succ` into `d + 1`
    ring,
  }
end

Details

The definition of the natural numbers in Lean is this:

inductive nat
| zero : nat
| succ (n : nat) : nat

When this code is run, four new objects are created: the type nat, the term nat.zero, the function succ : nat nat and the recursor for the naturals, a statement automatically generated from the definition and which can be described as saying that to do something for all naturals, you only have to do it for zero and succ n, and in the succ n case you can assume you already did it for n. The induction tactic applies this recursor and then does some tidying up. This is why you end up with goals containing n.succ rather than the more mathematically natural n + 1. In the example above I use simp to change n.succ to n + 1 (and also to push casts as far in as possible).