At the start of Part III we used Mathlib's definition of odd and even numbers.
Here we'll create our own definition of triangle numbers.
Task
The following picture illustrates triangle numbers. The first few are 1, 3, 6, 10, 15, 21 and 28.
In general, the $n$th triangle number is
$$\frac{n \cdot (n+1)}{2}$$
We saw previously the Mathlib definition of Odd didn't produce the $n$th odd number. Instead the definition is a proposition about a supplied number. So Odd 3 is true, but Odd 4 is false.
Our task is to create a definition of triangle numbers that is a proposition, true only if the supplied number is actually a triangle number.
Maths
A proposition for a triangle number $T$ could be:
$$\exists n\in\mathbb{N}\quad[\;T=\frac{n\cdot(n+1)}{2}\;]$$
This proposition is only true if $T$ is a triangle number. That is, if $T$ can be expressed in the form $n\cdot(n+1)/2$ for some natural number $n$.
When working with natural numbers, we should be cautious about dividing them. In this case division is safe because either $n$ or $(n+1)$ is an even number, and so $n \cdot (n+1)$ is divisible by $2$.
Even so, let's avoid division of natural numbers as good practice. We'll adjust the proposition to the equivalent:
$$\exists n\in\mathbb{N}\quad[\;2 T=n\cdot(n+1)\;]$$
That is, $T$ is a triangle number if $2 T$ can be expressed in the form $n\cdot(n+1)$ for some natural number $n$.
Code
The following Lean code creates a definition of triangle numbers.
-- 18 - Our Own Definition
import Mathlib.Tactic
def Triangle (a : ℕ) : Prop := ∃ n, 2 * a = n * (n + 1)
example : Triangle 10 := by
dsimp [Triangle]
use 4
The keyword def signals we're about to create a named definition. Here the name is Triangle.
After that is a declaration of variables, here a as a natural number. The round brackets require anyone using the definition to provide a as a parameter.
The Prop specifies that Triangle will be a proposition, a statement that can be true or false.
After the := is the actual detail of the definition of a triangle number, ∃ n, 2 * a = n * (n + 1).
The following picture summarises the structure of simple definitions.
When creating our own definitions, it is considerate to provide a minimal example that illustrates how to use the definition.
Here the example is a proof of Triangle 10, a proposition that says $10$ is a triangle number. The dsimp [Triangle] unfolds the definition in the Infoview. Because the definition is a “there exists” statement, the proof is resolved by a simple use 4.
Infoview
Placing the cursor before dsimp [Triangle] in the illustrative example shows the proof objective.
⊢ Triangle 10
Moving the cursor to the start of the next line shows the goal with the definition of Triangle unfolded.
⊢ ∃ n, 20 = n * (n + 1)
Types & Terms
Let's take a first peek at the hierarchy of objects in Lean.
Compare the definition of Triangle with a definition of Triple that I just made up:
def Triangle (a : ℕ) : Prop := ∃ n, 2 * a = n * (n + 1)
def Triple (a : ℕ) : ℕ := 3 * a
The type of Triangle is Prop, a proposition. The type of Triple is ℕ, a natural number.
We say the detail ∃ n, 2 * a = n * (n + 1) is a term of type Prop. Similarly, 3 * a is a term of type ℕ.
Appendix A illustrates the hierarchy of objects in Lean and Mathlib. The diagram there shows 13 is a term of type ℕ. What may be surprising is that proofs are terms of type Prop.
Knowing this isn't crucial at this stage of our learning, but it can help us read and write Lean proofs with an additional level of understanding.
Easy Exercise
Create a definition of square numbers named Square. It should be a proposition which is only true if a given number can be written in the form $n^{2}$, for some natural number $n$.
Write a proof showing 25 is a square number, illustrating the use of Square.