move all WIP files to level-rewrite branch

This commit is contained in:
Kevin Buzzard
2023-10-14 19:57:20 +01:00
parent b260a53f82
commit 20bc9fe61d
26 changed files with 1137 additions and 0 deletions

View File

@@ -0,0 +1,41 @@
import Game.Metadata
import Game.MyNat.Addition
World "AdvProposition"
Level 1
Title "the `split` tactic"
open MyNat
Introduction
"
The logical symbol `∧` means \"and\". If $P$ and $Q$ are propositions, then
$P\\land Q$ is the proposition \"$P$ and $Q$\".
"
namespace MySet
/-- If $P$ and $Q$ are true, then $P\\land Q$ is true. -/
Statement
(P Q : Prop) (p : P) (q : Q) : P Q := by
Hint "If your *goal* is `P ∧ Q` then
you can make progress with the `constructor` tactic, which turns one goal `P ∧ Q`
into two goals, namely `P` and `Q`."
constructor
Hint "Now you have two goals. The first one is `P`, which you can proof now. The
second one is `Q` and you see it in the queue \"Other Goals\". You will have to prove it afterwards."
Hint (hidden := true) "This first goal can be proved with `exact p`."
exact p
-- Hint "Observe that now the first goal has been proved, so it disappears and you continue
-- proving the second goal."
-- Hint (hidden := true) "Like the first goal, this is a case for `exact`."
-- -- TODO: It looks like these hints get shown above as well, but weirdly the hints from
-- -- above to not get shown here.
exact q
NewTactic constructor
NewDefinition And
Conclusion
"
"

View File

@@ -0,0 +1,64 @@
import Game.Metadata
import Game.MyNat.Addition
World "AdvProposition"
Level 10
Title "The law of the excluded middle."
open MyNat
Introduction
"
We proved earlier that `(P → Q) → (¬ Q → ¬ P)`. The converse,
that `(¬ Q → ¬ P) → (P → Q)` is certainly true, but trying to prove
it using what we've learnt so far is impossible (because it is not provable in
constructive logic).
"
/-- If $P$ and $Q$ are true/false statements, then
$$(\\lnot Q\\implies \\lnot P)\\implies(P\\implies Q).$$
-/
Statement
(P Q : Prop) : (¬ Q ¬ P) (P Q) := by
Hint "For example, you could start as always with
```
intro h p
```
"
intro h p
Hint "From here there is no way to continue with the tactics you've learned so far.
Instead you can call `by_cases q : Q`. This creates **two goals**, once under the assumption
that `Q` is true, once assuming `Q` is false."
by_cases q : Q
Hint "This first case is trivial."
exact q
Hint "The second case needs a bit more work, but you can get there with the tactics you've already
learned beforehand!"
have j := h q
exfalso
apply j
exact p
NewTactic by_cases
Conclusion
"
This approach assumed that `P ¬ P` is true, which is called \"law of excluded middle\".
It cannot be proven using just tactics like `intro` or `apply`.
`by_cases p : P` just does `rcases` on this result `P ¬ P`.
OK that's enough logic -- now perhaps it's time to go on to Advanced Addition World!
Get to it via the main menu.
"
-- TODO: I cannot really import `tauto` because of the notation `` that's used
-- for `MyNat`.
-- ## Pro tip
-- In fact the tactic `tauto` just kills this goal (and many other logic goals) immediately. You'll be
-- able to use it from now on.

View File

@@ -0,0 +1,48 @@
import Game.Metadata
import Game.MyNat.Addition
World "AdvProposition"
Level 2
Title "the `rcases` tactic"
open MyNat
Introduction
"
If `P ∧ Q` is in the goal, then we can make progress with `constructor`.
But what if `P ∧ Q` is a hypothesis? In this case, the `rcases` tactic will enable
us to extract proofs of `P` and `Q` from this hypothesis.
"
/-- If $P$ and $Q$ are true/false statements, then $P\\land Q\\implies Q\\land P$. -/
Statement -- and_symm
(P Q : Prop) : P Q Q P := by
Hint "The lemma below asks us to prove `P ∧ Q → Q ∧ P`, that is,
symmetry of the \"and\" relation. The obvious first move is
```
intro h
```
because the goal is an implication and this tactic is guaranteed
to make progress."
intro h
Hint "Now `{h} : P ∧ Q` is a hypothesis, and
```
rcases {h} with ⟨p, q⟩
```
will change `{h}`, the proof of `P ∧ Q`, into two proofs `p : P`
and `q : Q`.
You can write `⟨p, q⟩` with `\\<>` or `\\<` and `\\>`. Note that `rcases h` by itself will just
automatically name the new assumptions."
rcases h with p, q
Hint "Now a combination of `constructor` and `exact` will get you home."
constructor
exact q
exact p
NewTactic rcases

View File

@@ -0,0 +1,46 @@
import Game.Metadata
import Game.MyNat.Addition
World "AdvProposition"
Level 3
Title "and_trans"
open MyNat
Introduction
"
Here is another exercise to `rcases` and `constructor`.
"
/-- If $P$, $Q$ and $R$ are true/false statements, then $P\\land Q$ and
$Q\\land R$ together imply $P\\land R$. -/
Statement --and_trans
(P Q R : Prop) : P Q Q R P R := by
Hint "Here's a trick:
Your first steps would probably be
```
intro h
rcases h with ⟨p, q⟩
```
i.e. introducing a new assumption and then immediately take it appart.
In that case you could do that in a single step:
```
intro ⟨p, q⟩
```
"
intro hpq
rcases hpq with p, q
intro hqr
rcases hqr with q', r
constructor
exact p
exact r
Conclusion
"
"

View File

@@ -0,0 +1,45 @@
import Game.Metadata
import Game.MyNat.Addition
World "AdvProposition"
Level 4
Title ""
open MyNat
Introduction
"
The mathematical statement $P\\iff Q$ is equivalent to $(P\\implies Q)\\land(Q\\implies P)$. The `rcases`
and `constructor` tactics work on hypotheses and goals (respectively) of the form `P ↔ Q`. If you need
to write an `↔` arrow you can do so by typing `\\iff`, but you shouldn't need to.
"
/-- If $P$, $Q$ and $R$ are true/false statements, then
$P\\iff Q$ and $Q\\iff R$ together imply $P\\iff R$. -/
Statement --iff_trans
(P Q R : Prop) : (P Q) (Q R) (P R) := by
Hint "Similar to \"and\", you can use `intro` and `rcases` to add the `P ↔ Q` to your
assumptions and split it into its constituent parts."
Branch
intro hpq
intro hqr
Hint "Now you want to use `rcases {hpq} with ⟨pq, qp⟩`."
rcases hpq with hpq, hqp
rcases hqr with hqr, hrq
intro pq, qp
intro qr, rq
Hint "If you want to prove an iff-statement, you can use `constructor` to split it
into its two implications."
constructor
· intro p
apply qr
apply pq
exact p
· intro r
apply qp
apply rq
exact r
NewDefinition Iff

View File

@@ -0,0 +1,76 @@
import Game.Metadata
import Game.MyNat.Addition
World "AdvProposition"
Level 5
Title "Easter eggs."
open MyNat
Introduction
"
Let's try this again. Try proving it in other ways. (Note that `rcases` is temporarily disabled.)
### A trick.
Instead of using `rcases` on `h : P ↔ Q` you can just access the proofs of `P → Q` and `Q → P`
directly with `h.1` and `h.2`. So you can solve this level with
```
intro hpq hqr
constructor
intro p
apply hqr.1
```
### Another trick
Instead of using `rcases` on `h : P ↔ Q`, you can just `rw [h]`, and this will change all `P`s to `Q`s
in the goal. You can use this to create a much shorter proof. Note that
this is an argument for *not* running the `rcases` tactic on an iff statement;
you cannot rewrite one-way implications, but you can rewrite two-way implications.
"
-- TODO
-- ### Another trick
-- `cc` works on this sort of goal too.
/-- If $P$, $Q$ and $R$ are true/false statements, then `P ↔ Q` and `Q ↔ R` together imply `P ↔ R`.
-/
Statement --iff_trans
(P Q R : Prop) : (P Q) (Q R) (P R) := by
intro hpq hqr
Hint "Make a choice and continue either with `constructor` or `rw`.
* if you use `constructor`, you will use `{hqr}.1, {hqr}.2, …` later.
* if you use `rw`, you can replace all `P`s with `Q`s using `rw [{hpq}]`"
Branch
rw [hpq]
Branch
exact hqr
rw [hqr]
Hint "Now `rfl` can close this goal.
TODO: Note that the current modification of `rfl` is too weak to prove this. For now, you can
use `simp` instead (which calls the \"real\" `rfl` internally)."
simp
constructor
intro p
Hint "Now you can directly `apply {hqr}.1`"
apply hqr.1
apply hpq.1
exact p
intro r
apply hpq.2
apply hqr.2
exact r
DisabledTactic rcases
Conclusion
"
"

View File

@@ -0,0 +1,38 @@
import Game.Metadata
import Game.MyNat.Addition
World "AdvProposition"
Level 6
Title "Or, and the `left` and `right` tactics."
open MyNat
Introduction
"
`P Q` means \"$P$ or $Q$\". So to prove it, you
need to choose one of `P` or `Q`, and prove that one.
If `P Q` is your goal, then `left` changes this
goal to `P`, and `right` changes it to `Q`.
"
-- Note that you can take a wrong turn here. Let's
-- start with trying to prove $Q\\implies (P\\lor Q)$.
-- After the `intro`, one of `left` and `right` leads
-- to an impossible goal, the other to an easy finish.
/-- If $P$ and $Q$ are true/false statements, then $Q\\implies(P\\lor Q)$. -/
Statement
(P Q : Prop) : Q (P Q) := by
Hint (hidden := true) "Let's start with an initial `intro` again."
intro q
Hint "Now you need to choose if you want to prove the `left` or `right` side of the goal."
Branch
left
-- TODO: This message is also shown on the correct track. Need strict hints.
-- Hint "That was an unfortunate choice, you entered a dead end that cannot be proved anymore.
-- Hit \"Undo\"!"
right
exact q
NewTactic left right
NewDefinition Or

View File

@@ -0,0 +1,55 @@
import Game.Metadata
import Game.MyNat.Addition
World "AdvProposition"
Level 7
Title "`or_symm`"
open MyNat
Introduction
"
Proving that $(P\\lor Q)\\implies(Q\\lor P)$ involves an element of danger.
"
/-- If $P$ and $Q$ are true/false statements, then
$$P\\lor Q\\implies Q\\lor P.$$ -/
Statement --or_symm
(P Q : Prop) : P Q Q P := by
Hint "`intro h` is the obvious start."
intro h
Branch
left
Hint "This is a dead end that is not provable anymore. Hit \"undo\"."
Branch
right
Hint "This is a dead end that is not provable anymore. Hit \"undo\"."
Hint "But now, even though the goal is an `` statement, both `left` and `right` put
you in a situation with an impossible goal. Fortunately,
you can do `rcases h with p | q`. (that is a normal vertical slash)
"
rcases h with p | q
Hint " Something new just happened: because
there are two ways to prove the assumption `P Q` (namely, proving `P` or proving `Q`),
the `rcases` tactic turns one goal into two, one for each case.
So now you proof the goal under the assumption that `P` is true, and waiting under \"Other Goals\"
there is the same goal but under the assumption that `Q` is true.
You should be able to make it home from there. "
right
exact p
Hint "Note how now you finished the first goal and jumped to the one, where you assume `Q`."
left
exact q
Conclusion
"
Well done! Note that the syntax for `rcases` is different whether it's an \"or\" or an \"and\".
* `rcases h with ⟨p, q⟩` splits an \"and\" in the assumptions into two parts. You get two assumptions
but still only one goal.
* `rcases h with p | q` splits an \"or\" in the assumptions. You get **two goals** which have different
assumptions, once assumping the lefthand-side of the dismantled \"or\"-assumption, once the righthand-side.
"

View File

@@ -0,0 +1,53 @@
import Game.Metadata
import Game.MyNat.Addition
World "AdvProposition"
Level 8
Title "`and_or_distrib_left`"
open MyNat
Introduction
"
We know that $x(y+z)=xy+xz$ for numbers, and this
is called distributivity of multiplication over addition.
The same is true for `∧` and `` -- in fact `∧` distributes
over `` and `` distributes over `∧`. Let's prove one of these.
"
/-- If $P$. $Q$ and $R$ are true/false statements, then
$$P\\land(Q\\lor R)\\iff(P\\land Q)\\lor (P\\land R).$$ -/
Statement --and_or_distrib_left
(P Q R : Prop) : P (Q R) (P Q) (P R) := by
constructor
intro h
rcases h with hp, hqr
rcases hqr with q | r
left
constructor
exact hp
exact q
right
constructor
exact hp
exact r
intro h
rcases h with hpq | hpr
rcases hpq with p, q
constructor
exact p
left
exact q
rcases hpr with hp, hr
constructor
exact hp
right
exact hr
Conclusion
"
You already know enough to embark on advanced addition world. But the next two levels comprise
just a couple more things.
"

View File

@@ -0,0 +1,52 @@
import Game.Metadata
import Game.MyNat.Addition
World "AdvProposition"
Level 9
Title "`exfalso` and proof by contradiction. "
open MyNat
Introduction
"
It's certainly true that $P\\land(\\lnot P)\\implies Q$ for any propositions $P$
and $Q$, because the left hand side of the implication is false. But how do
we prove that `False` implies any proposition $Q$? A cheap way of doing it in
Lean is using the `exfalso` tactic, which changes any goal at all to `False`.
You might think this is a step backwards, but if you have a hypothesis `h : ¬ P`
then after `rw not_iff_imp_false at h,` you can `apply h,` to make progress.
Try solving this level without using `cc` or `tauto`, but using `exfalso` instead.
"
/-- If $P$ and $Q$ are true/false statements, then
$$(P\\land(\\lnot P))\\implies Q.$$ -/
Statement --contra
(P Q : Prop) : (P ¬ P) Q := by
Hint "Start as usual with `intro ⟨p, np⟩`."
Branch
exfalso
-- TODO: This hint needs to be strict
-- Hint "Not so quick! Now you just threw everything away."
intro h
Hint "You should also call `rcases` on your assumption `{h}`."
rcases h with p, np
-- TODO: This hint should before the last `exact p` step again.
Hint "Now you can call `exfalso` to throw away your goal `Q`. It will be replaced with `False` and
which means you will have to prove a contradiction."
Branch
-- TODO: Would `contradiction` not be more useful to introduce than `exfalso`?
contradiction
exfalso
Hint "Recall that `{np} : ¬ P` means `np : P → False`, which means you can simply `apply {np}` now.
You can also first call `rw [Not] at {np}` to make this step more explicit."
Branch
rw [Not] at np
apply np
exact p
-- TODO: `contradiction`?
NewTactic exfalso
-- DisabledTactic cc
LemmaTab "Prop"