Update: Since this is the accepted answer and since it was originally written for Lean 3, let me update it to Lean 4 with a bit more information.
First, the proof is simply
theorem mynat_zero_ne_succ (a : mynat) : mynat.succ a ≠ mynat.zero := by
simp
(In Lean 3 you could just put a period at the end to get a proof as in @It'sNotALie.'s answer, but that doesn't work in Lean 4.)
Here is how this works. When you do
inductive mynat : Type
| zero : mynat
| succ : mynat → mynat
then Lean is adding four new "things" to the context:
inductive mynat : Type
constructor mynat.zero : mynat
constructor mynat.succ : mynat → mynat
recursor mynat.rec.{u} : {motive : mynat → Sort u} →
motive mynat.zero → ((a : mynat) → motive a → motive (mynat.succ a)) → (t : mynat) → motive t
These "things" could be thought of as axioms, but unlike typical axioms there is no danger of these being inconsistent with whatever axioms and theorems are already in the environment (assuming Lean's theory and implementation are consistent, and the axioms in the context are as well). So it is more normal to think of them more like automatic definitions and theorems that Lean adds for you.
The inductive type mynat
and the two constructors mynat.zero
and mynat.succ
are clear and just come from the inductive definition. The elimination principle (or recursor as Lean 4 calls it) mynat.rec
is the workhorse of inductive definitions. It is what is used to do anything we want with mynat
including:
- Prove the basic structural facts about
zero
and succ
, including the first three Peano axioms.
- Define any recursive functions on
mynat
, including the usual +
and *
along with their four definitional (Peano axiom) equalities.
- Prove the induction principle.
The elimination principle rec
is discussed in Theorem Proving in Lean, 7. Inductive Types. And if you want more detail, the first chapter of The HoTT Book is a great introduction to dependent type theory. Also, see @Andrej Bauer's answer for a direct proof using mynat.rec
.
But also note, you will almost never need to use the elimination principle rec
directly. First, Lean automatically defines a number of definitions and theorems based on rec
. (Unlike rec
these are not "axioms". They have proofs/definitions.) For mynat
, here are a list of all the automatically generated theorems and definitions that Lean creates for mynat
.
#print mynat.below
#print mynat.binductionOn
#print mynat.brecOn
#print mynat.casesOn
#print mynat.ibelow
#print mynat.noConfusion
#print mynat.noConfusionType
#print mynat.recOn
#print mynat.succ.inj
#print mynat.succ.injEq
For example, mynat.succ.inj
is the usual Peano axiom saying that successor is injective:
theorem mynat.succ.inj : ∀ {a a_1 : mynat}, mynat.succ a = mynat.succ a_1 → a = a_1 :=
fun {a a_1} x => mynat.noConfusion x fun a_eq => a_eq
In Lean 3 these were all created automatically and easy to find via autocomplete. In Lean 4, they are more hidden and I don't believe they are intended to be called directly by a typical user.
Instead one can access them via the simp
tactic. Hence the by simp
proof above. Notice how simp
fills in a proof using myNat.noConfusion
:
theorem mynat_zero_ne_succ : ∀ (a : mynat), mynat.succ a ≠ mynat.zero :=
fun a => of_eq_true (Eq.trans (congrArg Not (eq_false' fun h => mynat.noConfusion h)) not_false_eq_true)
See the Lean 3 blog post No confusion over no_confusion
for a deeper explanation of what is going on here.
Other tactics like contradiction
also do something similar.
theorem mynat_zero_ne_succ (a : mynat) : mynat.succ a ≠ mynat.zero := by
intro h
contradiction
and gives a cleaner proof underneath:
theorem mynat_zero_ne_succ : ∀ (a : mynat), mynat.succ a ≠ mynat.zero :=
fun a h => mynat.noConfusion h
Moreover, the tools in Lean for working with inductive definitions such as the induction
and cases
tactics, as well as match
statements all use (or de-sugar in the case of match
) to using these built-in theorems and definitions.
(Note, that is on the theorem-proving side. When it comes to generating executable code in the compiler or virtual machine, I
think Lean avoids mynat.rec
entirely and directly converts, say, match
to executable code.)