Mathlib has many lemmas and theorems for us to use. We can also write our own.
Here we'll create a small but convenient lemma about the natural numbers.
Task
If we pick a natural number
The following illustrates this idea.
By the definition of natural numbers,
Our task is to create a lemma for natural numbers
Let's bring this to life with an example. If we say
Maths
To prove our lemma we'll try to make use of lemmas that also exist in Mathlib, not only to shorten the proof, but also to ease the transition to a Lean proof.
Lemma (1) is already very close to our proof objective. It says that
Lemma (2) says that
Both lemmas (1) and (2) exist in Mathlib.
Code
The following Lean code creates a lemma that says either
-- 16 - Writing Our Own Lemma
import Mathlib.Tactic
lemma Nat.le_or_succ_le (a b: ℕ): a ≤ b ∨ b + 1 ≤ a := by
rw [Nat.add_one_le_iff]
exact le_or_lt a b
example {c : ℕ} : c ≤ 2 ∨ 3 ≤ c := by
exact Nat.le_or_succ_le c 2
The lemma header starts with lemma Nat.le_or_succ_le to tell Lean we want to create a new lemma named Nat.le_or_succ_le.
The Nat. prefix is conventional for lemmas about natural numbers. The rest of the name le_or_succ_le tries to follow the naming convention to describe what the lemma is about.
The Lean proofs we've previously explored started with example and no name. They can be thought of as anonymous lemmas, anonymous because there was no need to refer to them after they'd been proved.
The remainder of the header declares a and b as natural numbers, and states the lemma's proposal a ≤ b ∨ b + 1 ≤ a. The round brackets around the variables (a b : ℕ) require anyone using the lemma to always provide a and b as parameters.
Our lemma is proved in just two lines of code by making effective use of existing Mathlib lemmas:
- The first line of the proof rewrites the goal using a Mathlib lemma Nat.add_one_le_iff. Let's check its header:
theorem add_one_le_iff : n + 1 ≤ m ↔ n < m :=
The rw tactic is akin to “find and replace”, so it looks at the goal a ≤ b ∨ b + 1 ≤ a and finds b + 1 ≤ a matches the left hand side of the Nat.add_one_le_iff lemma. The matched b + 1 ≤ a is rewritten with the right hand side of the lemma b < a.
- As we'll see in the Infoview, the goal is now a ≤ b ∨ b < a.
- The final line of the proof applies another Mathlib lemma le_or_lt. Let's check its header:
This lemma le_or_lt says that, given two numbers a and b, then a ≤ b ∨ b < a. This matches our current goal exactly, so we can use exact to resolve it and complete the proof.lemma le_or_lt (a b : α) : a ≤ b ∨ b < a :=
Notice how the header of the Mathlib lemma le_or_lt (a b : α) uses round brackets requiring us to provide a and b when we use it.
Infoview
Placing the cursor before rw [Nat.add_one_le_iff] shows the original proof goal.
⊢ a ≤ b ∨ b + 1 ≤ a
Moving the cursor to the start of the next line shows the rewritten goal.
⊢ a ≤ b ∨ b < a
Minimal Example
When writing your own lemmas, it is considerate to provide a minimal example showing how to use them.
The minimal example here illustrates how to use our lemma to prove
With a set to c, and b set to 2, our lemma becomes c ≤ 2 ∨ 3 ≤ c. This matches the proof goal exactly, allowing us to use exact to complete the proof neatly in one line.
Forwards & Backwards
Comparing the maths and Lean proofs, we can see they are similar, but not quite the same.
- The maths proof starts with a lemma
and uses another lemma to arrive at the goal . - The Lean proof starts with the goal
and uses another lemma to arrive at an equivalent statement, which happens to be a known lemma .
The proofs go in opposite directions. Where one starts, the other finishes.
Starting with the proof objective and resolving it down to known true facts, rather than building up from known facts to a proof objective, will be a little more common with Lean proofs because many of the tactics bias towards operating on the current goal.
Just for interest, the following is a Lean proof which follows the same path as the maths proof.
lemma Nat.le_or_succ_le (a b: ℕ): a ≤ b ∨ b + 1 ≤ a := by
have h : a ≤ b ∨ b < a := le_or_lt a b
rw [← Nat.succ_le] at h
exact h
The left arrow in rw [← Nat.succ_le] selects the reverse direction of the bidirectional lemma.
Easy Exercise
Write a lemma for integers
Create a minimal example illustrating how your lemma can prove the following for any integer