Merge branch 'level-rewrite' of github.com:hhu-adam/NNG4 into level-rewrite
This commit is contained in:
@@ -4,3 +4,5 @@ h2 : x+5y=6
|
||||
⊢ x=1
|
||||
|
||||
?
|
||||
|
||||
example (x y : ℕ) (h1 : 2 * x + 3 * y = 5) (h2 : 4 * x + 5 * y = 9) : x = 1 := by
|
||||
|
||||
@@ -3,6 +3,9 @@ import Game.Levels.LessOrEqual.L01le_refl
|
||||
import Game.Levels.LessOrEqual.L02zero_le
|
||||
import Game.Levels.LessOrEqual.L03le_succ_self
|
||||
import Game.Levels.LessOrEqual.L04le_zero
|
||||
import Game.Levels.LessOrEqual.L05le_trans
|
||||
import Game.Levels.LessOrEqual.L06le_antisymm
|
||||
import Game.Levels.LessOrEqual.L07le_total
|
||||
|
||||
World "LessOrEqual"
|
||||
Title "≤ World"
|
||||
|
||||
@@ -14,8 +14,11 @@ how to prove `a ≤ b` is to `use b - a`. See how you get on with this level,
|
||||
which proves that every number in the game is at least 0.
|
||||
"
|
||||
|
||||
/-- If $x$ is a number, then $0 \\le x$. -/
|
||||
Statement le_refl (x : ℕ) : 0 ≤ x := by
|
||||
LemmaDoc MyNat.zero_le as "zero_le" in "≤" "
|
||||
`zero_le x` is a proof that `0 ≤ x`."
|
||||
|
||||
/-- If $x$ is a number, then $0 \le x$. -/
|
||||
Statement zero_le (x : ℕ) : 0 ≤ x := by
|
||||
use x
|
||||
rw [zero_add]
|
||||
rfl
|
||||
|
||||
@@ -10,14 +10,24 @@ LemmaDoc MyNat.le_succ_self as "le_succ_self" in "≤" "
|
||||
`le_succ_self x` is a proof that `x ≤ succ x`.
|
||||
"
|
||||
|
||||
/-- If $x$ is a number, then $x \\le \\mathoperator{succ}(x)$. -/
|
||||
Statement le_succ_self (x : ℕ) : x ≤ succ x := by
|
||||
/-- If $x$ is a number, then $x \le \operatorname{succ}(x)$. -/
|
||||
Statement (x : ℕ) : x ≤ succ x := by
|
||||
use 1
|
||||
rw [succ_eq_add_one]
|
||||
rfl
|
||||
|
||||
LemmaTab "≤"
|
||||
|
||||
Conclusion "
|
||||
Here's a two-liner:
|
||||
```
|
||||
use 1
|
||||
exact succ_eq_add_one x
|
||||
```
|
||||
|
||||
This works because `succ_eq_add_one x` is a proof of `succ x = x + 1`.
|
||||
"
|
||||
|
||||
/-
|
||||
Introduction
|
||||
"
|
||||
|
||||
@@ -12,24 +12,22 @@ LemmaDoc MyNat.le_zero as "le_zero" in "≤" "
|
||||
|
||||
Introduction "
|
||||
In this level, our inequality is a *hypothesis*. We have not seen this before.
|
||||
|
||||
The `rcases` tactic can be used to take `hx` apart.
|
||||
"
|
||||
|
||||
LemmaDoc MyNat.le_zero as "le_zero" in "≤"
|
||||
"`le_zero x` is a proof of the implication `x ≤ 0 → x = 0`. "
|
||||
|
||||
/-- If $x \leq 0$, then $x=0$. -/
|
||||
Statement le_zero (x : ℕ) (hx : x ≤ 0) : x = 0 := by
|
||||
Hint "Start with `cases hx with y hy`. You can get the funny pointy brackets with `\\<` and
|
||||
`\\>`, or `\\<>` will give you both at once."
|
||||
cases hx with y hy
|
||||
Hint "Now `y` is what you have to add to `x` to get `0`, and `hy` is the proof of this."
|
||||
Hint (hidden := true) "You want to use `eq_zero_of_add_right_eq_zero`, which you already
|
||||
proved, but you'll have to start with `symm at hy`."
|
||||
symm at hy
|
||||
apply eq_zero_of_add_right_eq_zero at hy
|
||||
exact hy
|
||||
|
||||
LemmaTab "≤"
|
||||
|
||||
/-
|
||||
Introduction
|
||||
"
|
||||
Because constanly rewriting `zero_add` and `add_zero` is a bit dull,
|
||||
let's unlock the `ring` tactic. This will prove any goal which is \"true
|
||||
in the language of ring theory\", for example `a + b + c = c + b + a`.
|
||||
It doesn't understand `succ` though, so use `succ_eq_add_one` in this
|
||||
level to get rid of it.
|
||||
"
|
||||
-/
|
||||
|
||||
49
Game/Levels/LessOrEqual/L05le_trans.lean
Normal file
49
Game/Levels/LessOrEqual/L05le_trans.lean
Normal file
@@ -0,0 +1,49 @@
|
||||
import Game.Levels.LessOrEqual.L04le_zero
|
||||
|
||||
World "LessOrEqual"
|
||||
Level 5
|
||||
Title "x ≤ y and y ≤ z implies x ≤ z"
|
||||
|
||||
namespace MyNat
|
||||
|
||||
Introduction "
|
||||
We have already proved that `x ≤ x`, i.e. that `≤` is *reflexive*. Now let's
|
||||
prove that it's *transitive*, i.e., that if `x ≤ y` and `y ≤ z` then `x ≤ z`.
|
||||
"
|
||||
|
||||
LemmaDoc MyNat.le_trans as "le_trans" in "≤" "
|
||||
`le_trans x y z` is a proof that if `x ≤ y` and `y ≤ z` then `x ≤ z`.
|
||||
More precisely, it is a proof that `x ≤ y → (y ≤ z → x ≤ z)`. In words,
|
||||
If $x \\le y$ then (pause) if $y \\le z$ then $x \\le z$.
|
||||
|
||||
## A note on associativity
|
||||
|
||||
In Lean, `a + b + c` means `(a + b) + c`, because `+` is left associative. However
|
||||
`→` is right associative, meaning that `x ≤ y → y ≤ z → x ≤ z` means
|
||||
exactly that `≤` is transitive.
|
||||
"
|
||||
|
||||
/-- If $x \leq y$ and $y \leq z$, then $x \leq z$. -/
|
||||
Statement le_trans (x y z : ℕ) (hxy : x ≤ y) (hyz : y ≤ z) : x ≤ z := by
|
||||
Hint "If you start with `rcases hxy with ⟨a, ha⟩` then `ha` will be a proof that `y = x + a`.
|
||||
If you want to instead *define* `y` to be `x + a` then you can do `rcases hxy with ⟨a, rfl⟩`.
|
||||
This is a time-saving trick. "
|
||||
rcases hxy with ⟨a, rfl⟩
|
||||
rcases hyz with ⟨b, rfl⟩
|
||||
use a + b
|
||||
exact add_assoc x a b
|
||||
|
||||
LemmaTab "≤"
|
||||
|
||||
Conclusion "
|
||||
Here's a four line proof:
|
||||
```
|
||||
rcases hxy with ⟨a, rfl⟩
|
||||
rcases hyz with ⟨b, rfl⟩
|
||||
use a + b
|
||||
exact add_assoc x a b
|
||||
```
|
||||
|
||||
A passing mathematician remarks that with reflexivity and transitivity out of the way,
|
||||
you have proved that `≤` is a *preorder* on `ℕ`.
|
||||
"
|
||||
50
Game/Levels/LessOrEqual/L06le_antisymm.lean
Normal file
50
Game/Levels/LessOrEqual/L06le_antisymm.lean
Normal file
@@ -0,0 +1,50 @@
|
||||
import Game.Levels.LessOrEqual.L05le_trans
|
||||
|
||||
World "LessOrEqual"
|
||||
Level 6
|
||||
Title "x ≤ y and y ≤ x implies x = y"
|
||||
|
||||
namespace MyNat
|
||||
|
||||
LemmaDoc MyNat.le_antisymm as "le_antisymm" in "≤" "
|
||||
`le_antisymm x y` is a proof that if `x ≤ y` and `y ≤ x` then `x = y`.
|
||||
"
|
||||
|
||||
Introduction "
|
||||
This level asks you to prove *antisymmetry* of $\\leq$.
|
||||
In other words, if $x \\leq y$ and $y \\leq x$ then $x = y$.
|
||||
It's the trickiest one so far. Good luck!
|
||||
"
|
||||
|
||||
/-- If $x \leq y$ and $y \leq x$, then $x = y$. -/
|
||||
Statement le_antisymm (x y : ℕ) (hxy : x ≤ y) (hyx : y ≤ x) : x = y := by
|
||||
rcases hxy with ⟨a, rfl⟩
|
||||
rcases hyx with ⟨b, hb⟩
|
||||
rw [add_assoc] at hb
|
||||
symm at hb
|
||||
apply add_right_eq_self at hb
|
||||
apply eq_zero_of_add_right_eq_zero at hb
|
||||
rw [hb, add_zero]
|
||||
rfl
|
||||
|
||||
LemmaTab "≤"
|
||||
|
||||
Conclusion "
|
||||
Here's my proof:
|
||||
```
|
||||
rcases hxy with ⟨a, rfl⟩
|
||||
rcases hyx with ⟨b, hb⟩
|
||||
rw [add_assoc] at hb
|
||||
symm at hb
|
||||
apply add_right_eq_self at hb
|
||||
apply eq_zero_of_add_right_eq_zero at hb
|
||||
rw [hb, add_zero]
|
||||
rfl
|
||||
```
|
||||
|
||||
A passing mathematician remarks that with antisymmetry as well,
|
||||
you have proved that `≤` is a *partial order* on `ℕ`.
|
||||
|
||||
The next level, the boss level of this world, is to prove
|
||||
that `≤` is a total order.
|
||||
"
|
||||
68
Game/Levels/LessOrEqual/L07le_total.lean
Normal file
68
Game/Levels/LessOrEqual/L07le_total.lean
Normal file
@@ -0,0 +1,68 @@
|
||||
import Game.Levels.LessOrEqual.L06le_antisymm
|
||||
|
||||
World "LessOrEqual"
|
||||
Level 7
|
||||
Title "x ≤ y or y ≤ x"
|
||||
|
||||
namespace MyNat
|
||||
|
||||
Introduction "
|
||||
This is I think the toughest level yet. We haven't talked about \"or\" at all,
|
||||
but here's everything you need to know.
|
||||
|
||||
1) The notation for \"or\" is `∨`. You won't need to type it, but you can
|
||||
type it with `\\or`.
|
||||
|
||||
2) If you have an \"or\" statement in the *goal*, then two tactics made
|
||||
progress: `left` and `right`. But don't choose a direction unless your
|
||||
hypotheses guarantee that it's the right one.
|
||||
|
||||
3) If you have an \"or\" statement as a *hypothesis* `h`, then
|
||||
`rcases h with (h1 | h2)` will create two goals, one where you went left,
|
||||
and the other where you went right.
|
||||
"
|
||||
|
||||
LemmaDoc MyNat.le_total as "le_total" in "≤" "
|
||||
`le_total x y` is a proof that `x ≤ y` or `y ≤ x`.
|
||||
"
|
||||
|
||||
/-- If $x \leq y$ and $y \leq z$, then $x \leq z$. -/
|
||||
Statement le_total (x y : ℕ) : x ≤ y ∨ y ≤ x := by
|
||||
induction y with d hd
|
||||
right
|
||||
exact zero_le x
|
||||
rcases hd with (h1 | h2)
|
||||
left
|
||||
rcases h1 with ⟨e, rfl⟩
|
||||
use e + 1
|
||||
rw [succ_eq_add_one, add_assoc]
|
||||
rfl
|
||||
rcases h2 with ⟨e, rfl⟩
|
||||
rcases e with ⟨f⟩
|
||||
left
|
||||
change d + 0 ≤ succ d
|
||||
rw [add_zero]
|
||||
use 1
|
||||
exact succ_eq_add_one d
|
||||
right
|
||||
use a
|
||||
rw [add_succ, succ_add, add_comm]
|
||||
rfl
|
||||
|
||||
|
||||
|
||||
|
||||
LemmaTab "≤"
|
||||
|
||||
Conclusion "
|
||||
Here's a four line proof:
|
||||
```
|
||||
rcases hxy with ⟨a, rfl⟩
|
||||
rcases hyz with ⟨b, rfl⟩
|
||||
use a + b
|
||||
exact add_assoc x a b
|
||||
```
|
||||
|
||||
A passing mathematician remarks that with reflexivity and transitivity out of the way,
|
||||
you have proved that `≤` is a *preorder* on `ℕ`.
|
||||
"
|
||||
@@ -1,99 +0,0 @@
|
||||
import Game.Levels.AdvAddition.L11add_right_eq_self
|
||||
|
||||
namespace MyNat
|
||||
|
||||
def le (a b : ℕ) : Prop := ∃ c, b = a + c
|
||||
|
||||
instance : LE MyNat := ⟨le⟩
|
||||
|
||||
example (x : ℕ) : 0 ≤ x := by
|
||||
use x -- **************** need `use` tactic
|
||||
rw [zero_add]
|
||||
rfl
|
||||
|
||||
example (x : ℕ) : x ≤ x := by
|
||||
use 0
|
||||
rw [add_zero]
|
||||
rfl
|
||||
|
||||
example (x : ℕ) : x ≤ succ x := by
|
||||
use 1
|
||||
rw [succ_eq_add_one]
|
||||
rfl
|
||||
|
||||
example (x y : Nat) : x + y = 0 → x = 0 := by exact?
|
||||
|
||||
-- **TODO** ask on Zulip: why is this not called eq_zero_of_add_left_eq_zero ?
|
||||
#check Nat.eq_zero_of_add_eq_zero_left -- (h : n + m = 0) : m = 0
|
||||
|
||||
#check add_right
|
||||
axiom eq_zero_of_add_eq_zero_right (x y : ℕ) (h : x + y = 0) : x = 0 -- ***************** need this
|
||||
|
||||
example (x : ℕ) (h : x ≤ 0) : x = 0 := by
|
||||
cases' h with n hn -- ************************ need `cases` tactic
|
||||
rw [eq_comm] at hn -- ************************ ouch, need `rw` with iffs
|
||||
apply eq_zero_of_add_eq_zero_right at hn
|
||||
assumption
|
||||
|
||||
example (x y z : ℕ) (h1 : x ≤ y) (h2 : y ≤ z) : x ≤ z := by
|
||||
cases' h1 with n hn
|
||||
cases' h2 with m hm
|
||||
rw [hm, hn]
|
||||
use n + m
|
||||
rw [add_assoc]
|
||||
rfl
|
||||
|
||||
example (x y : ℕ) (h1 : x ≤ y) (h2 : y ≤ x) : x = y := by
|
||||
cases' h1 with n hn
|
||||
cases' h2 with m hm
|
||||
rw [hm] at hn
|
||||
rw [add_assoc] at hn
|
||||
rw [eq_comm] at hn -- ***************** more rw with iff
|
||||
apply add_right_eq_self at hn
|
||||
apply add_eq_zero at hn
|
||||
rw [hn, add_zero] at hm
|
||||
assumption
|
||||
|
||||
example (x y : ℕ) : x ≤ y ∨ y ≤ x := by
|
||||
-- ******************************* need `∨`
|
||||
induction x with d hd
|
||||
left -- *********************** need `left`
|
||||
use y
|
||||
rw [zero_add]
|
||||
rfl
|
||||
cases' hd with h1 h2 -- ***************** cases on an or
|
||||
cases' h1 with n hn -- ***************** cases on a prop
|
||||
cases' n with n -- ******************* cases on a nat
|
||||
change y = d + 0 at hn
|
||||
rw [add_zero] at hn
|
||||
right -- ***************************** need `right`
|
||||
rw [hn]
|
||||
use 1
|
||||
rw [succ_eq_add_one]
|
||||
rfl
|
||||
rw [add_succ] at hn
|
||||
left
|
||||
rw [hn]
|
||||
-- succ a ≤ succ b ↔ a ≤ b would have been handy here
|
||||
rw [succ_eq_add_one, succ_eq_add_one]
|
||||
use n
|
||||
rw [add_right_comm]
|
||||
rfl
|
||||
right
|
||||
cases' h2 with n
|
||||
use n + 1
|
||||
rw [succ_eq_add_one, h]
|
||||
rw [add_assoc]
|
||||
rfl
|
||||
|
||||
|
||||
|
||||
#exit
|
||||
a) 0 ≤ x;
|
||||
b) x ≤ x;
|
||||
c) x ≤ S(x);
|
||||
d) If x ≤ 0 then x = 0.
|
||||
a) x ≤ x (reflexivity);
|
||||
b) If x ≤ y and y ≤ z then x ≤ z (transitivity);
|
||||
c) If x ≤ y and y ≤ x then x = y (antisymmetry);
|
||||
d) Either x ≤ y or y ≤ x (totality).
|
||||
Reference in New Issue
Block a user