nng levels
This commit is contained in:
@@ -1,22 +1,55 @@
|
||||
import NNG.Metadata
|
||||
import NNG.MyNat.Addition
|
||||
import NNG.MyNat.Multiplication
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.LeftRight
|
||||
|
||||
Game "NNG"
|
||||
World "AdvMultiplication"
|
||||
Level 1
|
||||
Title ""
|
||||
Title "mul_pos"
|
||||
|
||||
open MyNat
|
||||
|
||||
Introduction
|
||||
"
|
||||
Welcome to Advanced Multiplication World! Before attempting this
|
||||
world you should have completed seven other worlds, including
|
||||
Multiplication World and Advanced Addition World. There are four
|
||||
levels in this world.
|
||||
|
||||
Recall that if `b : mynat` is a hypothesis and you do `cases b with n`,
|
||||
your one goal will split into two goals,
|
||||
namely the cases `b = 0` and `b = succ(n)`. So `cases` here is like
|
||||
a weaker version of induction (you don't get the inductive hypothesis).
|
||||
|
||||
## Tricks
|
||||
|
||||
1) if your goal is `⊢ X ≠ Y` then `intro h` will give you `h : X = Y` and
|
||||
a goal of `⊢ false`. This is because `X ≠ Y` *means* `(X = Y) → false`.
|
||||
Conversely if your goal is `false` and you have `h : X ≠ Y` as a hypothesis
|
||||
then `apply h` will turn the goal into `X = Y`.
|
||||
|
||||
2) if `hab : succ (3 * x + 2 * y + 1) = 0` is a hypothesis and your goal is `⊢ false`,
|
||||
then `exact succ_ne_zero _ hab` will solve the goal, because Lean will figure
|
||||
out that `_` is supposed to be `3 * x + 2 * y + 1`.
|
||||
|
||||
"
|
||||
|
||||
Statement
|
||||
""
|
||||
: true := by
|
||||
trivial
|
||||
"The product of two non-zero natural numbers is non-zero."
|
||||
(a b : ℕ) : a ≠ 0 → b ≠ 0 → a * b ≠ 0 := by
|
||||
intro ha hb
|
||||
intro hab
|
||||
induction b with b
|
||||
apply hb
|
||||
rfl
|
||||
rw [mul_succ] at hab
|
||||
apply ha
|
||||
induction a with a
|
||||
rfl
|
||||
rw [add_succ] at hab
|
||||
exfalso
|
||||
exact succ_ne_zero _ hab
|
||||
|
||||
Conclusion
|
||||
"
|
||||
|
||||
@@ -1,22 +1,34 @@
|
||||
import NNG.Metadata
|
||||
import NNG.MyNat.Addition
|
||||
import NNG.MyNat.Multiplication
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.LeftRight
|
||||
|
||||
Game "NNG"
|
||||
World "AdvMultiplication"
|
||||
Level 2
|
||||
Title ""
|
||||
Title "eq_zero_or_eq_zero_of_mul_eq_zero"
|
||||
|
||||
open MyNat
|
||||
|
||||
Introduction
|
||||
"
|
||||
|
||||
A variant on the previous level.
|
||||
"
|
||||
|
||||
Statement
|
||||
""
|
||||
: true := by
|
||||
trivial
|
||||
Statement -- eq_zero_or_eq_zero_of_mul_eq_zero
|
||||
"If $ab = 0$, then at least one of $a$ or $b$ is equal to zero."
|
||||
(a b : ℕ) (h : a * b = 0) :
|
||||
a = 0 ∨ b = 0 := by
|
||||
induction a with d
|
||||
left
|
||||
rfl
|
||||
induction b with e he
|
||||
right
|
||||
rfl
|
||||
exfalso
|
||||
rw [mul_succ] at h
|
||||
rw [add_succ] at h
|
||||
exact succ_ne_zero _ h
|
||||
|
||||
Conclusion
|
||||
"
|
||||
|
||||
@@ -1,22 +1,39 @@
|
||||
import NNG.Metadata
|
||||
import NNG.MyNat.Addition
|
||||
import NNG.MyNat.Multiplication
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.LeftRight
|
||||
|
||||
Game "NNG"
|
||||
World "AdvMultiplication"
|
||||
Level 3
|
||||
Title ""
|
||||
Title "mul_eq_zero_iff"
|
||||
|
||||
open MyNat
|
||||
|
||||
Introduction
|
||||
"
|
||||
|
||||
Now you have `eq_zero_or_eq_zero_of_mul_eq_zero` this is pretty straightforward.
|
||||
"
|
||||
|
||||
axiom eq_zero_or_eq_zero_of_mul_eq_zero (a b : ℕ) (h : a * b = 0) : a = 0 ∨ b = 0
|
||||
axiom zero_mul (a : ℕ) : 0 * a = 0
|
||||
|
||||
Statement
|
||||
""
|
||||
: true := by
|
||||
trivial
|
||||
"$ab = 0$, if and only if at least one of $a$ or $b$ is equal to zero.
|
||||
"
|
||||
(a b : ℕ): a * b = 0 ↔ a = 0 ∨ b = 0 := by
|
||||
constructor
|
||||
intro h
|
||||
exact eq_zero_or_eq_zero_of_mul_eq_zero a b h
|
||||
intro hab
|
||||
rcases hab with hab | hab
|
||||
rw [hab]
|
||||
rw [zero_mul]
|
||||
rfl
|
||||
rw [hab]
|
||||
rw [mul_zero]
|
||||
rfl
|
||||
|
||||
|
||||
Conclusion
|
||||
"
|
||||
|
||||
@@ -1,22 +1,63 @@
|
||||
import NNG.Metadata
|
||||
import NNG.MyNat.Addition
|
||||
import NNG.MyNat.Multiplication
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.LeftRight
|
||||
|
||||
Game "NNG"
|
||||
World "AdvMultiplication"
|
||||
Level 4
|
||||
Title ""
|
||||
Title "mul_left_cancel"
|
||||
|
||||
open MyNat
|
||||
|
||||
Introduction
|
||||
"
|
||||
This is the last of the bonus multiplication levels.
|
||||
`mul_left_cancel` will be useful in inequality world.
|
||||
|
||||
People find this level hard. I have probably had more questions about this
|
||||
level than all the other levels put together, in fact. Many levels in this
|
||||
game can just be solved by \"running at it\" -- do induction on one of the
|
||||
variables, keep your head, and you're done. In fact, if you like a challenge,
|
||||
it might be instructive if you stop reading after the end of this paragraph and try solving this level now by induction,
|
||||
seeing the trouble you run into, and reading the rest of these comments afterwards. This level
|
||||
has a sting in the tail. If you are a competent mathematician, try
|
||||
and figure out what is going on. Write down a maths proof of the
|
||||
theorem in this level. Exactly what statement do you want to prove
|
||||
by induction? It is subtle.
|
||||
|
||||
Ok so here are some spoilers. The problem with naively running at it, is that if you try induction on,
|
||||
say, $c$, then you are imagining a and b as fixed, and your inductive
|
||||
hypothesis $P(c)$ is $ab=ac \\implies b=c$. So for your inductive step
|
||||
you will be able to assume $ab=ad \\implies b=d$ and your goal will
|
||||
be to show $ab=a(d+1) \\implies b=d+1$. When you also assume $ab=a(d+1)$
|
||||
you will realise that your inductive hypothesis is *useless*, because
|
||||
$ab=ad$ is not true! The statement $P(c)$ (with $a$ and $b$ regarded
|
||||
as constants) is not provable by induction.
|
||||
|
||||
What you *can* prove by induction is the following *stronger* statement.
|
||||
Imagine $a\not=0$ as fixed, and then prove \"for all $b$, if $ab=ac$ then $b=c$\"
|
||||
by induction on $c$. This gives us the extra flexibility we require.
|
||||
Note that we are quantifying over all $b$ in the inductive hypothesis -- it
|
||||
is essential that $b$ is not fixed.
|
||||
|
||||
You can do this in two ways in Lean -- before you start the induction
|
||||
you can write `revert b,`. The `revert` tactic is the opposite of the `intro`
|
||||
tactic; it replaces the `b` in the hypotheses with \"for all $b$\" in the goal.
|
||||
|
||||
Alternatively, you can write `induction c with d hd
|
||||
generalizing b` as the first line of the proof.
|
||||
|
||||
If you do not modify your technique in this way, then this level seems
|
||||
to be impossible (judging by the comments I've had about it!)
|
||||
"
|
||||
|
||||
Statement
|
||||
""
|
||||
: true := by
|
||||
trivial
|
||||
"If $a \\neq 0$, $b$ and $c$ are natural numbers such that
|
||||
$ ab = ac, $
|
||||
then $b = c$."
|
||||
(a b c : ℕ) (ha : a ≠ 0) : a * b = a * c → b = c := by
|
||||
sorry
|
||||
|
||||
Conclusion
|
||||
"
|
||||
|
||||
Reference in New Issue
Block a user