This commit is contained in:
Jon Eugster
2023-03-26 14:29:13 +02:00
parent 6cd71c93fe
commit 6e8911e5da
114 changed files with 3381 additions and 5 deletions
@@ -0,0 +1,42 @@
import NNG.Metadata
import NNG.MyNat.Multiplication
Game "NNG"
World "Tutorial"
Level 1
Title "The rfl tactic"
Introduction
"
Each level in this game involves proving a mathematical statement. In this first level
you have three natural numbers $x, y, z$ (listed under \"Objects\") and you want to prove
$x \\cdot y + z = x \\cdot y + z$ (displayed under \"Goal\").
You can modify the Goal using *Tactics* until you can close (i.e. prove) it.
The first tactic is called `rfl`, which stands for \"reflexivity\",
a fancy way of saying that it will prove any goal of the form `A = A`. It doesn't matter how
complicated `A` is, all that matters is that the left hand side is exactly equal to the right hand
side (a computer scientist would say \"definitionally equal\"). I really mean \"press the same buttons
on your computer in the same order\" equal. For example, `x * y + z = x * y + z` can be proved by `rfl`,
but `x + y = y + x` cannot.
"
Statement
"For all natural numbers $x, y$ and $z$, we have $xy + z = xy + z$."
(x y z : ℕ) : x * y + z = x * y + z := by
Hint "In order to use the tactic `rfl` you can enter it above and hit \"Execute\"."
rfl
NewTactic rfl
NewDefinition MyNat
Conclusion
"
Congratulations! You completed your first verified proof!
If you want to be reminded about the `rfl` tactic, your inventory on the right contains useful
information about things you've learned.
Now click on \"Next\" to continue the journey.
"
@@ -0,0 +1,46 @@
import NNG.Metadata
import NNG.MyNat.Multiplication
Game "NNG"
World "Tutorial"
Level 2
Title "the rewrite (rw) tactic"
Introduction
"
In this level, you also get \"Assumptions\" about your objects. These are hypotheses of which
you assume (or know) that they are true.
The `rewrite` tactic is the way to \"substitute in\" the value of a variable.
If you have a hypothesis of the form `A = B`, and your goal mentions
the left hand side `A` somewhere,
then the rewrite tactic will replace the `A` in your goal with a `B`.
*(Note: For this game, `rw` is a shorthand for `rewrite`. Out in the real world, `rw` tries to call
`rfl` automatically afterwards.)*
"
Statement
"If $x$ and $y$ are natural numbers, and $y = x + 7$, then $2y = 2(x + 7)$."
(x y : ℕ) (h : y = x + 7) : 2 * y = 2 * (x + 7) := by
Hint "You can use `rewrite [h]` to replace the `{y}` with `x + 7`.
Note that the assumption `h` is written
inside square brackets: `[h]`."
rw [h]
Hint "In this game not all hints are directly shown. If you need help finishing the proof, click
on \"More Help\" below!"
Hint (hidden := true)
"Now both sides are identical, so you can use `rfl` to close the goal."
rfl
NewTactic rewrite rw
Conclusion
"
If you want to see the entire proof you created, toggle \"Editor mode\" above.
There you can also move your cursor around the proof to see the \"state\" of the proof at this point.
Each tactic is written on a new line and Lean is sensitive to indentation (i.e. there must be no
spaces before any of the tactics)
"
@@ -0,0 +1,71 @@
import NNG.Metadata
import NNG.MyNat.Definition
Game "NNG"
World "Tutorial"
Level 3
Title "Peano axioms"
open MyNat
Introduction
"
Now we start from the beginning, where we don't know about addition or multiplication on `ℕ`.
All we get is the following data:
* a term `(0 : ℕ)`, interpreted as the zero number.
* a function `succ : ℕ → ℕ`, with `succ n` interpreted as \"the number after $n$\".
* the principle of mathematical induction.
These axioms are essentially the axioms isolated by Peano which uniquely characterise the natural
numbers (we also need recursion, but we can ignore it for now).
The first axiom says that $0$ is a natural number.
The second says that there is a $\\operatorname{succ}$ function which eats a number and spits out
the number after it, so $\\operatorname{succ}(0)=1$, $\\operatorname{succ}(1)=2$ and so on.
Peano's last axiom is the principle of mathematical induction. This is a deeper fact.
It says that if we have infinitely many true/false statements $P(0)$, $P(1)$, $P(2)$ and so on,
and if $P(0)$ is true, and if for every natural number $d$ we know that $P(d)$ implies
$P(\\operatorname{succ}(d))$, then $P(n)$ must be true for every natural number $n$.
It's like saying that if you have a long line of dominoes, and if you knock the first
one down, and if you know that if a domino falls down then the one after it will fall
down too, then you can deduce that all the dominos will fall down. One can also think
of it as saying that every natural number can be built by starting at $0$ and then applying
$\\operatorname{succ}$ a finite number of times.
Peano's insights were firstly that these axioms completely characterise the natural numbers,
and secondly that these axioms alone can be used to build a whole bunch of other structure
on the natural numbers, for example addition, multiplication and so on.
This game is all about seeing how far these axioms of Peano can take us.
Now let us practise the use of `rewrite` with this new function `succ`:
"
Statement
"If $\\operatorname{succ}(a) = b$, then $\\operatorname{succ}(\\operatorname{succ}(a)) = \\operatorname{succ}(a)$."
(a b : ℕ) (h : (succ a) = b) : succ (succ a) = succ b := by
Hint "You can use `rewrite` and your assumption `{h}` to substitute `succ a` with `b`.
Notes:
1) We do not need brackets for function application the way we would write
them in mathematics: `succ b` means $\\operatorname\{succ}(b)$.
2) If you would want to substitute instead `b` with `succ a`, you can do that
writing a small `←` (`\\l`, i.e. backslash + small letter L + space)
before `h` like this: `rewrite [← h]`."
Branch
rewrite [← h]
Hint (hidden := true) "Now both sides are identical…"
rewrite [h]
Hint (hidden := true) "Now both sides are identical…"
rfl
Conclusion
"
You may also be wondering why we keep writing `succ b` instead of `b + 1`.
This is because we haven't defined addition yet!
On the next level, the final level of Tutorial World,
we will introduce addition, and then we'll be ready to enter Addition World.
"
@@ -0,0 +1,68 @@
import NNG.Metadata
import NNG.MyNat.Addition
Game "NNG"
World "Tutorial"
Level 4
Title "addition"
open MyNat
Introduction
"
Peano defined addition $a + b$ by induction on $b$, or, more precisely, by *recursion* on $b$.
He first explained how to add $0$ to a number: this is the base case.
* `add_zero (a : ℕ) : a + 0 = a`
We will call this theorem `add_zero`.
More precisely, `add_zero` is the name of the *proof* of the
theorem. Note the name of this proof. Mathematicians sometimes call it
\"Lemma 2.1\" or \"Hypothesis P6\" or something.
But computer scientists call it `add_zero` because it tells you what the answer to
\"x add zero\" is. It's a much better name than \"Lemma 2.1\".
Even better, you can use the `rewrite` tactic
with `add_zero`. If you ever see `x + 0` in your goal,
`rewrite [add_zero]` should simplify it to `x`. This is
because `add_zero` is a proof that `x + 0 = x`
(more precisely, `add_zero x` is a proof that `x + 0 = x` but
Lean can figure out the `x` from the context).
Now here's the inductive step. If you know how to add $d$ to $a$, then Peano
tells you how to add $\\operatorname{succ} (d)$ to $a$. It looks like this:
- `add_succ (a d : ℕ) : a + (succ d) = succ (a + d)`
What's going on here is that we assume `a + d` is already defined, and we define
`a + (succ d)` to be the number after it.
Note the name of this proof too: `add_succ` tells you how to add a successor
to something.
If you ever see `… + succ …` in your goal, you should be able to use
`rewrite [add_succ]`, to make progress.
"
Statement
"For all natural numbers $a$, we have $a + \\operatorname{succ}(0) = a$."
(a : ℕ) : a + succ 0 = succ a := by
Hint "You find `{a} + succ …` in the goal, so you can use `rewrite` and `add_succ`
to make progress."
Hint (hidden := true) "Explicitely, type `rewrite [add_succ]`!"
rewrite [add_succ]
Hint "Now you see a term of the form `… + 0`, so you can use `add_zero`."
Hint (hidden := true) "Explicitely, type `rewrite [add_zero]`!"
rewrite [add_zero]
Hint (hidden := true) "Finally both sides are identical."
rfl
NewLemma MyNat.add_succ MyNat.add_zero
Conclusion
"
You have finished tutorial world! If you're happy, let's move onto Addition World,
and learn about proof by induction.
## Inspection time
If you want to examine the proof, toggle \"Editor mode\" and click somewhere
inside the proof to see the state at that point!
"