add NNG
This commit is contained in:
@@ -0,0 +1,93 @@
|
||||
import NNG.Metadata
|
||||
import NNG.MyNat.Addition
|
||||
|
||||
Game "NNG"
|
||||
World "Addition"
|
||||
Level 1
|
||||
Title "the induction tactic."
|
||||
|
||||
open MyNat
|
||||
|
||||
set_option tactic.hygienic false
|
||||
|
||||
Introduction
|
||||
"
|
||||
OK so let's see induction in action. We're going to prove
|
||||
|
||||
```
|
||||
zero_add (n : ℕ) : 0 + n = n
|
||||
```
|
||||
|
||||
Wait… what is going on here? Didn't we already prove that adding zero to $n$ gave us $n$?
|
||||
|
||||
No we didn't! We proved $n + 0 = n$, and that proof was called `add_zero`. We're now
|
||||
trying to establish `zero_add`, the proof that $0 + n = n$.
|
||||
|
||||
But aren't these two theorems the same?
|
||||
|
||||
No they're not! It is *true* that `x + y = y + x`, but we haven't *proved* it yet,
|
||||
and in fact we will need both `add_zero` and `zero_add` in order
|
||||
to prove this. In fact `x + y = y + x` is the boss level for addition world,
|
||||
and `induction` is the only other tactic you'll need to beat it.
|
||||
|
||||
Now `add_zero` is one of Peano's axioms, so we don't need to prove it, we already have it.
|
||||
To prove `0 + n = n` we need to use induction on $n$. While we're here,
|
||||
note that `zero_add` is about zero add something, and `add_zero` is about something add zero.
|
||||
The names of the proofs tell you what the theorems are. Anyway, let's prove `0 + n = n`.
|
||||
"
|
||||
|
||||
Statement zero_add
|
||||
"For all natural numbers $n$, we have $0 + n = n$."
|
||||
(n : ℕ) : 0 + n = n := by
|
||||
Hint "You can start a proof by induction over `n` by typing:
|
||||
`induction n with d hd`.
|
||||
|
||||
If you use the `with` part, you can name your variable and induction hypothesis, otherwise
|
||||
they get default names."
|
||||
induction n with n hn
|
||||
· Hint "Now you have two goals. Once you proved the first, you will jump to the second one.
|
||||
This first goal is the base case $n = 0$.
|
||||
|
||||
Recall that you can use all lemmas that are visible in your inventory."
|
||||
Hint (hidden := true) "try using `add_zero`."
|
||||
rw [add_zero]
|
||||
rfl
|
||||
· Hint "Now you jumped to the second goal. Here you have the induction hypothesis
|
||||
`{hn} : 0 + {n} = {n}` and you need to prove the statement for `succ {n}`."
|
||||
Hint (hidden := true) "look at `add_succ`."
|
||||
rw [add_succ]
|
||||
Hint (hidden := true) "At this point you see the term `0 + {n}`, so you can use the
|
||||
induction hypothesis with `rw [{hn}]`."
|
||||
rw [hn]
|
||||
rfl
|
||||
|
||||
NewTactic induction
|
||||
|
||||
Conclusion
|
||||
"
|
||||
## Now venture off on your own.
|
||||
|
||||
Those three tactics:
|
||||
|
||||
* `induction n with d hd`
|
||||
* `rw [h]`
|
||||
* `rfl`
|
||||
|
||||
will get you quite a long way through this game. Using only these tactics
|
||||
you can beat Addition World level 4 (the boss level of Addition World),
|
||||
all of Multiplication World including the boss level `a * b = b * a`,
|
||||
and even all of Power World including the fiendish final boss. This route will
|
||||
give you a good grounding in these three basic tactics; after that, if you
|
||||
are still interested, there are other worlds to master, where you can learn
|
||||
more tactics.
|
||||
|
||||
But we're getting ahead of ourselves, you still have to beat the rest of Addition World.
|
||||
We're going to stop explaining stuff carefully now. If you get stuck or want
|
||||
to know more about Lean (e.g. how to do much harder maths in Lean),
|
||||
ask in `#new members` at
|
||||
[the Lean chat](https://leanprover.zulipchat.com)
|
||||
(login required, real name preferred). Kevin or Mohammad or one of the other
|
||||
people there might be able to help.
|
||||
|
||||
Good luck! Click on \"Next\" to solve some levels on your own.
|
||||
"
|
||||
@@ -0,0 +1,70 @@
|
||||
import NNG.Metadata
|
||||
import NNG.MyNat.Addition
|
||||
|
||||
Game "NNG"
|
||||
World "Addition"
|
||||
Level 2
|
||||
Title "add_assoc (associativity of addition)"
|
||||
|
||||
open MyNat
|
||||
|
||||
theorem MyNat.zero_add (n : ℕ) : 0 + n = n := by
|
||||
induction n with n hn
|
||||
· rw [add_zero]
|
||||
rfl
|
||||
· rw [add_succ]
|
||||
rw [hn]
|
||||
rfl
|
||||
|
||||
Introduction
|
||||
"
|
||||
It's well-known that $(1 + 2) + 3 = 1 + (2 + 3)$; if we have three numbers
|
||||
to add up, it doesn't matter which of the additions we do first. This fact
|
||||
is called *associativity of addition* by mathematicians, and it is *not*
|
||||
obvious. For example, subtraction really is not associative: $(6 - 2) - 1$
|
||||
is really not equal to $6 - (2 - 1)$. We are going to have to prove
|
||||
that addition, as defined the way we've defined it, is associative.
|
||||
|
||||
See if you can prove associativity of addition.
|
||||
"
|
||||
|
||||
Statement add_assoc
|
||||
"On the set of natural numbers, addition is associative.
|
||||
In other words, for all natural numbers $a, b$ and $c$, we have
|
||||
$ (a + b) + c = a + (b + c). $"
|
||||
(a b c : ℕ) : (a + b) + c = a + (b + c) := by
|
||||
Hint "Because addition was defined by recursion on the right-most variable,
|
||||
use induction on the right-most variable (try other variables at your peril!).
|
||||
|
||||
Note that when Lean writes `a + b + c`, it means `(a + b) + c`. If it wants to talk
|
||||
about `a + (b + c)` it will put the brackets in explictly."
|
||||
Branch
|
||||
induction a
|
||||
Hint "Good luck with that…"
|
||||
rw [zero_add, zero_add]
|
||||
rfl
|
||||
Branch
|
||||
induction b
|
||||
Hint "Good luck with that…"
|
||||
induction c with c hc
|
||||
Hint (hidden := true) "look at the lemma `add_zero`."
|
||||
rw [add_zero]
|
||||
Hint "`rw [add_zero]` only rewrites one term of the form `… + 0`, so you might to
|
||||
use it multiple times."
|
||||
rw [add_zero]
|
||||
rfl
|
||||
Hint (hidden := true) "`add_succ` might help here."
|
||||
rw [add_succ]
|
||||
rw [add_succ]
|
||||
rw [add_succ]
|
||||
Hint (hidden := true) "Now you can use the induction hypothesis."
|
||||
rw [hc]
|
||||
rfl
|
||||
|
||||
|
||||
Conclusion
|
||||
"
|
||||
|
||||
"
|
||||
|
||||
NewLemma MyNat.zero_add
|
||||
@@ -0,0 +1,66 @@
|
||||
import NNG.Metadata
|
||||
import NNG.MyNat.Addition
|
||||
import NNG.Levels.Addition.Level_2
|
||||
|
||||
Game "NNG"
|
||||
World "Addition"
|
||||
Level 3
|
||||
Title "succ_add"
|
||||
|
||||
open MyNat
|
||||
|
||||
theorem MyNat.add_assoc (a b c : ℕ) : (a + b) + c = a + (b + c) := by
|
||||
induction c with c hc
|
||||
· rw [add_zero]
|
||||
rw [add_zero]
|
||||
rfl
|
||||
· rw [add_succ]
|
||||
rw [add_succ]
|
||||
rw [add_succ]
|
||||
rw [hc]
|
||||
rfl
|
||||
|
||||
|
||||
Introduction
|
||||
"
|
||||
Oh no! On the way to `add_comm`, a wild `succ_add` appears. `succ_add`
|
||||
is the proof that `succ(a) + b = succ(a + b)` for `a` and `b` in your
|
||||
natural number type. We need to prove this now, because we will need
|
||||
to use this result in our proof that `a + b = b + a` in the next level.
|
||||
|
||||
NB: think about why computer scientists called this result `succ_add` .
|
||||
There is a logic to all the names.
|
||||
|
||||
Note that if you want to be more precise about exactly where you want
|
||||
to rewrite something like `add_succ` (the proof you already have),
|
||||
you can do things like `rw [add_succ (succ a)]` or
|
||||
`rw [add_succ (succ a) d]`, telling Lean explicitly what to use for
|
||||
the input variables for the function `add_succ`. Indeed, `add_succ`
|
||||
is a function: it takes as input two variables `a` and `b` and outputs a proof
|
||||
that `a + succ(b) = succ(a + b)`. The tactic `rw [add_succ]` just says to Lean \"guess
|
||||
what the variables are\".
|
||||
"
|
||||
|
||||
Statement succ_add
|
||||
"For all natural numbers $a, b$, we have
|
||||
$ \\operatorname{succ}(a) + b = \\operatorname{succ}(a + b)$."
|
||||
(a b : ℕ) : succ a + b = succ (a + b) := by
|
||||
Hint (hidden := true) "You might again want to start by induction
|
||||
on the right-most variable."
|
||||
Branch
|
||||
induction a
|
||||
Hint "Induction on `a` will not work."
|
||||
induction b with d hd
|
||||
· rw [add_zero]
|
||||
rfl
|
||||
· rw [add_succ]
|
||||
rw [hd]
|
||||
rw [add_succ]
|
||||
rfl
|
||||
|
||||
NewLemma MyNat.add_assoc
|
||||
|
||||
Conclusion
|
||||
"
|
||||
|
||||
"
|
||||
@@ -0,0 +1,60 @@
|
||||
import NNG.Metadata
|
||||
import NNG.MyNat.Addition
|
||||
import NNG.Levels.Addition.Level_3
|
||||
|
||||
Game "NNG"
|
||||
World "Addition"
|
||||
Level 4
|
||||
Title "`add_comm` (boss level)"
|
||||
|
||||
open MyNat
|
||||
|
||||
theorem MyNat.succ_add (a b : ℕ) : succ a + b = succ (a + b) := by
|
||||
induction b with d hd
|
||||
· rw [add_zero]
|
||||
rfl
|
||||
· rw [add_succ]
|
||||
rw [hd]
|
||||
rw [add_succ]
|
||||
rfl
|
||||
|
||||
Introduction
|
||||
"
|
||||
[boss battle music]
|
||||
|
||||
Look in your inventory to see the proofs you have available.
|
||||
These should be enough.
|
||||
"
|
||||
|
||||
Statement add_comm
|
||||
"On the set of natural numbers, addition is commutative.
|
||||
In other words, for all natural numbers $a$ and $b$, we have
|
||||
$a + b = b + a$."
|
||||
(a b : ℕ) : a + b = b + a := by
|
||||
Branch
|
||||
induction a with d hd
|
||||
· rw [zero_add]
|
||||
rw [add_zero]
|
||||
rfl
|
||||
· rw [succ_add]
|
||||
rw [hd]
|
||||
rw [add_succ]
|
||||
rfl
|
||||
induction b with d hd
|
||||
· rw [zero_add]
|
||||
rw [add_zero]
|
||||
rfl
|
||||
· rw [add_succ]
|
||||
rw [hd]
|
||||
rw [succ_add]
|
||||
rfl
|
||||
|
||||
NewLemma MyNat.succ_add
|
||||
|
||||
Conclusion
|
||||
"
|
||||
If you got this far -- nice! You're nearly ready to make a choice:
|
||||
Multiplication World or Function World. But there are just a couple
|
||||
more useful lemmas in Addition World which you should prove first.
|
||||
Press on to level 5.
|
||||
"
|
||||
@@ -0,0 +1,54 @@
|
||||
import NNG.Metadata
|
||||
import NNG.MyNat.Addition
|
||||
import NNG.Levels.Addition.Level_4
|
||||
|
||||
Game "NNG"
|
||||
World "Addition"
|
||||
Level 5
|
||||
Title "succ_eq_add_one"
|
||||
|
||||
open MyNat
|
||||
|
||||
theorem MyNat.add_comm (a b : ℕ) : a + b = b + a := by
|
||||
induction b with d hd
|
||||
· rw [zero_add]
|
||||
rw [add_zero]
|
||||
rfl
|
||||
· rw [add_succ]
|
||||
rw [hd]
|
||||
rw [succ_add]
|
||||
rfl
|
||||
|
||||
theorem MyNat.one_eq_succ_zero : (1 : ℕ) = succ 0 := by
|
||||
rfl
|
||||
|
||||
NewLemma MyNat.add_comm MyNat.one_eq_succ_zero
|
||||
|
||||
Introduction
|
||||
"
|
||||
I've just added `one_eq_succ_zero` (a proof of $1 = \\operatorname{succ}(0)$)
|
||||
to your list of theorems; this is true
|
||||
by definition of $1$, but we didn't need it until now.
|
||||
|
||||
Levels 5 and 6 are the two last levels in Addition World.
|
||||
Level 5 involves the number $1$. When you see a $1$ in your goal,
|
||||
you can write `rw [one_eq_succ_zero]` to get back
|
||||
to something which only mentions `0`. This is a good move because $0$ is easier for us to
|
||||
manipulate than $1$ right now, because we have
|
||||
some theorems about $0$ (`zero_add`, `add_zero`), but, other than `1 = succ 0`,
|
||||
no theorems at all which mention $1$. Let's prove one now.
|
||||
"
|
||||
|
||||
Statement succ_eq_add_one
|
||||
"For any natural number $n$, we have
|
||||
$ \\operatorname{succ}(n) = n+1$ ."
|
||||
(n : ℕ) : succ n = n + 1 := by
|
||||
rw [one_eq_succ_zero]
|
||||
rw [add_succ]
|
||||
rw [add_zero]
|
||||
rfl
|
||||
|
||||
Conclusion
|
||||
"
|
||||
Well done! On to the last level!
|
||||
"
|
||||
@@ -0,0 +1,47 @@
|
||||
import NNG.Metadata
|
||||
import NNG.MyNat.Addition
|
||||
import NNG.Levels.Addition.Level_5
|
||||
|
||||
Game "NNG"
|
||||
World "Addition"
|
||||
Level 6
|
||||
Title "add_right_comm"
|
||||
|
||||
open MyNat
|
||||
|
||||
Introduction
|
||||
"
|
||||
Lean sometimes writes `a + b + c`. What does it mean? The convention is
|
||||
that if there are no brackets displayed in an addition formula, the brackets
|
||||
are around the left most `+` (Lean's addition is \"left associative\").
|
||||
So the goal in this level is `(a + b) + c = (a + c) + b`. This isn't
|
||||
quite `add_assoc` or `add_comm`, it's something you'll have to prove
|
||||
by putting these two theorems together.
|
||||
|
||||
If you hadn't picked up on this already, `rw [add_assoc]` will
|
||||
change `(x + y) + z` to `x + (y + z)`, but to change it back
|
||||
you will need `rw [← add_assoc]`. Get the left arrow by typing `\\l`
|
||||
then the space bar (note that this is L for left, not a number 1).
|
||||
Similarly, if `h : a = b` then `rw [h]` will change `a`'s to `b`'s
|
||||
and `rw [← h]` will change `b`'s to `a`'s.
|
||||
|
||||
Also, you can be (and will need to be, in this level) more precise
|
||||
about where to rewrite theorems. `rw add_comm,` will just find the
|
||||
first `? + ?` it sees and swap it around. You can target more specific
|
||||
additions like this: `rw add_comm a` will swap around
|
||||
additions of the form `a + ?`, and `rw add_comm a b,` will only
|
||||
swap additions of the form `a + b`.
|
||||
"
|
||||
|
||||
Statement add_right_comm
|
||||
"For all natural numbers $a, b$ and $c$, we have
|
||||
$a + b + c = a + c + b$."
|
||||
(a b c : ℕ) : a + b + c = a + c + b := by
|
||||
rw [add_assoc]
|
||||
rw [add_comm b c]
|
||||
rw [←add_assoc]
|
||||
rfl
|
||||
|
||||
Conclusion
|
||||
"
|
||||
"
|
||||
Reference in New Issue
Block a user