rename testgame to adam
This commit is contained in:
@@ -0,0 +1,36 @@
|
||||
import TestGame.Metadata
|
||||
import Mathlib.Tactic.Ring
|
||||
|
||||
--set_option tactic.hygienic false
|
||||
|
||||
Game "TestGame"
|
||||
World "Predicate"
|
||||
Level 1
|
||||
|
||||
Title "Natürliche Zahlen"
|
||||
|
||||
Introduction
|
||||
"
|
||||
**Evenine**: Willkommen Reisende! Wir leben hier in Einklang mit der Natur und allem natürlichen,
|
||||
so sagt mir, könnt ihr mit natürlichen Zahlen umgehen?
|
||||
"
|
||||
|
||||
Statement (x y : ℕ) : (x + y) ^ 2 = x ^ 2 + 2 * x * y + y ^ 2 := by
|
||||
Hint "**Du**: Das hab ich in der Schule gelernt, man rechnet das einfach aus,
|
||||
indem man die Terme umsortiert.
|
||||
|
||||
**Robo**: Behaupte doch mit `ring`, dass das so ist.
|
||||
|
||||
**Du**: Aber `ℕ` ist doch gar kein Ring?
|
||||
|
||||
**Robo**: `ring` funktioniert schon für Halbringe, aber sie heisst ring, weil sie auf
|
||||
(kommutativen) Ringen am besten funktioniert.
|
||||
"
|
||||
ring
|
||||
|
||||
Conclusion
|
||||
"
|
||||
*Evenine: Ja das stimmt schon. Und das genügt uns auf diesem Planet auch als Antwort.*
|
||||
"
|
||||
|
||||
NewTactic ring
|
||||
@@ -0,0 +1,39 @@
|
||||
import TestGame.Metadata
|
||||
import Mathlib
|
||||
|
||||
Game "TestGame"
|
||||
World "Predicate"
|
||||
Level 2
|
||||
|
||||
Title "Rewrite"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Robo spuckt den Brief aus, den er dabei hatte, und gibt ihn *Evenine*.
|
||||
|
||||
**Evenine**: Das verstehe ich nicht, wisst ihr was damit gemeint ist?
|
||||
|
||||
Und sie händigt Dir den Brief:
|
||||
"
|
||||
|
||||
Statement (a b c d : ℕ) (h₁ : c = d) (h₂ : a = b) (h₃ : a = d) : b = c := by
|
||||
Hint "**Du**: Schau mal, das ist ja fast genau, was wir auf *Implis* gemacht haben,
|
||||
nur jetzt mit Gleichheiten von Zahlen anstatt Genau-Dann-Wenn-Aussagen!
|
||||
|
||||
**Robo**: `=` und `↔` kannst du praktisch gleich behandeln wenns um `rw` geht."
|
||||
Hint (hidden := true) "**Du**: Also auch `rw [hₓ]` und `rw [← hₓ]`?
|
||||
|
||||
**Robo**: Probiers doch einfach."
|
||||
rw [h₁]
|
||||
Hint (hidden := true) "**Du**: Wie war das nochmals mit rückwärts umschreiben?
|
||||
|
||||
**Robo**: `←` ist `\\l`. Und dann `rw [← hₓ]`"
|
||||
rw [←h₂]
|
||||
assumption
|
||||
|
||||
Conclusion
|
||||
"
|
||||
**Evenine**: Danke viemals, das hilft uns vermutlich, jetzt Frage ich mich aber…
|
||||
"
|
||||
|
||||
NewTactic assumption rw
|
||||
@@ -0,0 +1,36 @@
|
||||
import TestGame.Metadata
|
||||
import Mathlib
|
||||
|
||||
Game "TestGame"
|
||||
World "Predicate"
|
||||
Level 3
|
||||
|
||||
Title "Rewrite"
|
||||
|
||||
Introduction
|
||||
"
|
||||
**Evenine**: Mit diesem neuen Wissen, könnt ihr mir bei folgendem helfen:
|
||||
"
|
||||
|
||||
Statement
|
||||
"
|
||||
$$
|
||||
\\begin{aligned}
|
||||
a &= b \\\\
|
||||
a + a ^ 2 &= b + 1 \\\\
|
||||
\\vdash b + b ^ 2 = b + 1
|
||||
\\end{aligned}
|
||||
$$
|
||||
"
|
||||
(a b : ℕ) (h : a = b) (g : a + a ^ 2 = b + 1) : b + b ^ 2 = b + 1 := by
|
||||
Hint "**Du**: Ah da ersetzt man ja einfach `{a}` durch `{b}` in der anderen Annahme!
|
||||
|
||||
**Robo**: Genau! Das machst du mit `rw [{h}] at {g}`."
|
||||
rw [h] at g
|
||||
Hint (hidden := true) "**Robo**: Schau mal durch die Annahmen."
|
||||
assumption
|
||||
|
||||
Conclusion "
|
||||
**Robo**: Noch ein Trick: Mit `rw [h] at *` kann man im weiteren `h` in **allen** Annahmen und
|
||||
dem Goal umschreiben.
|
||||
"
|
||||
@@ -0,0 +1,35 @@
|
||||
import TestGame.Metadata
|
||||
import Mathlib.Tactic.Ring
|
||||
|
||||
Game "TestGame"
|
||||
World "Predicate"
|
||||
Level 4
|
||||
|
||||
Title "Natürliche Zahlen"
|
||||
|
||||
Introduction
|
||||
"
|
||||
*Evenines* Berater meldet sich.
|
||||
|
||||
**Berater**: Das stimmt wohl, aber das Problem, das uns eigentlich beschäftigt hat, eure
|
||||
Natürlichkeit, war folgendes:
|
||||
"
|
||||
|
||||
Statement
|
||||
(x y z : ℕ) (h : x = 2 * y + 1) (g : z = 3 * y + 1): x ^ 2 = 4 * y ^ 2 + z + y := by
|
||||
Hint "**Du**: Ich versteh das Pattern. Wenn ich zuerst alles so umschreibe, dass
|
||||
das Goal nur noch rechnen und umsortieren ist, dann kann `ring` den Rest machen!
|
||||
|
||||
**Robo**: Noch ein Trick: Entweder kannst du zwei Befehle `rw [h₁]` und `rw [h₂]` schreiben,
|
||||
oder du kannst das gleich in einem machen : rw [h₁, h₂]."
|
||||
rw [h, g]
|
||||
ring
|
||||
|
||||
|
||||
Conclusion
|
||||
"
|
||||
*Evenine* bedankt sich nochmals für die Botschaft und ihr werdet zu einem kleineren Busch geführt,
|
||||
der ein gemütlich warmes Innenleben an den Tag legt.
|
||||
"
|
||||
|
||||
NewTactic ring rw
|
||||
@@ -0,0 +1,36 @@
|
||||
import TestGame.Metadata
|
||||
|
||||
Game "TestGame"
|
||||
World "Predicate"
|
||||
Level 5
|
||||
|
||||
Title "Definitionally equal"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Müde ruht ihr euch in eurer Bleibe aus. Du schaust doch eine Lücke in den Blättern vielen
|
||||
kleinen Vögeln bei der Nahrungssuche zu.
|
||||
|
||||
**Du**: Sag mal Robo, ich hab vorhin ein Kind überhört, dass seinem Spielgefährten erklärt hat,
|
||||
folgendes sei mit `rfl` zu beweisen:
|
||||
"
|
||||
|
||||
Statement : 1 + 1 = 2 := by
|
||||
Hint "**Du**: Wieso nicht `ring`?
|
||||
|
||||
**Robo**: Klar, `ring` geht auch und ist intuitiver.
|
||||
Für `rfl` kommt es darauf an, wie die Sachen genau definiert sind: `1 + 1` ist als
|
||||
`(0.succ).succ` definiert und `2` halt ebenfalls.
|
||||
"
|
||||
rfl
|
||||
|
||||
OnlyTactic rfl
|
||||
|
||||
Conclusion
|
||||
"
|
||||
**Du**: Dann war das mehr Glück?
|
||||
|
||||
**Robo**: Das ist eine Art die Welt zu sehen…
|
||||
|
||||
Damit fällst du in einen ruhigen Schlaf.
|
||||
"
|
||||
@@ -0,0 +1,73 @@
|
||||
import TestGame.Metadata
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.Contrapose
|
||||
import Mathlib.Tactic.Use
|
||||
import Mathlib.Tactic.Ring
|
||||
|
||||
import Mathlib.Algebra.Parity
|
||||
|
||||
set_option tactic.hygienic false
|
||||
|
||||
Game "TestGame"
|
||||
World "Predicate"
|
||||
Level 6
|
||||
|
||||
Title "Gerade/Ungerade"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Am nächsten Tag erklärt euch *Evenine*, dass es auf dem Mond zwei Gruppierungen gibt,
|
||||
ihre und die ihres Halbbruders *Oddeus*. Die Mottos sind
|
||||
|
||||
```
|
||||
def Even (n : ℕ) : Prop := ∃ r, n = r + r
|
||||
```
|
||||
|
||||
und
|
||||
|
||||
```
|
||||
def Odd (n : ℕ) : Prop := ∃ r, n = 2 * r + 1
|
||||
```
|
||||
|
||||
**Evenine**: Hier, ich zeige euch mal etwas was man bei uns machen kann:
|
||||
"
|
||||
|
||||
Statement even_square (n : ℕ) (h : Even n) : Even (n ^ 2) := by
|
||||
Branch
|
||||
unfold Even
|
||||
Hint "Rob**: Am besten machst du auch noch `unfold Even at h`, damit du verstehst was los ist."
|
||||
Hint "**Robo**: Wie du oben siehst, ist `Even n` dadurch definiert,
|
||||
dass ein `r` existiert so dass `r + r = n`. Am besten
|
||||
öffnest du diese Definition mit `unfold Even at *` einmal, dann siehst du besser, was los ist. "
|
||||
unfold Even at *
|
||||
Hint "**Du**: Also von `{h}` weiss ich jetzt dass ein `r` existiert, so dass `r + r = n`…
|
||||
|
||||
**Robo**: Mit `rcases h with ⟨r, hr⟩` kannst du dieses `r` tatsächlich einführen."
|
||||
rcases h with ⟨r, hr⟩
|
||||
Hint "**Du**: Und jetzt muss ich eine passende Zahl finden, so dass `x + x = n^2`?
|
||||
|
||||
**Robo**: Genau. Und mit `use _` gibst du diese Zahl an."
|
||||
Hint (hidden := true) "**Robo**: Also sowas ähnliches wie `use 4 * r ^ 3`, aber ich kann
|
||||
dir leider nicht sagen, welche Zahl passt.
|
||||
"
|
||||
Branch
|
||||
rw [hr]
|
||||
Hint "**Robo**: Das geht auch, jetzt musst du aber wirklich `use` verwenden."
|
||||
use 2 * r ^ 2
|
||||
ring
|
||||
use 2 * r ^ 2
|
||||
Hint "**Du**: Ah und jetzt `ring`!
|
||||
|
||||
**Robo**: Aber zuerst must du noch mit
|
||||
`rw` `n` durch `r + r` ersetzen, da `ring` das sonst nicht weiss."
|
||||
rw [hr]
|
||||
ring
|
||||
|
||||
-- TODO: [Comment] For me the expected behaviour of `(strict := true)` would
|
||||
-- be that it distinguishes between the defEq states while `(strict := false)`
|
||||
-- would show the hint regardless of a `unfold Even`.
|
||||
|
||||
NewTactic unfold use
|
||||
NewDefinition Even Odd
|
||||
|
||||
Conclusion "**Evenine**: Seht ihr?"
|
||||
@@ -0,0 +1,43 @@
|
||||
import TestGame.Metadata
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.Contrapose
|
||||
import Mathlib.Tactic.Use
|
||||
import Mathlib.Tactic.Ring
|
||||
|
||||
import Mathlib.Algebra.Parity
|
||||
|
||||
set_option tactic.hygienic false
|
||||
|
||||
Game "TestGame"
|
||||
World "Predicate"
|
||||
Level 7
|
||||
|
||||
Title "Gerade/Ungerade"
|
||||
|
||||
Introduction
|
||||
"
|
||||
**Du**: Aber, das sagt doch gar nichts aus, genau das gleiche könnte ich für `Odd`
|
||||
auch sagen. Hier seht!
|
||||
"
|
||||
|
||||
Statement odd_square (n : ℕ) (h : Odd n) : Odd (n ^ 2) := by
|
||||
unfold Odd at *
|
||||
rcases h with ⟨r, hr⟩
|
||||
Hint "**Robo**: Ich hab noch einen Trick auf Lager:
|
||||
Wenn du jetzt herausfinden willst, welche Zahl du einsetzen musst, könntest
|
||||
du schon jetzt mit `rw [{hr}]` weitermachen…"
|
||||
rw [hr]
|
||||
Hint "**Robo**: Wenn du jetzt `ring` benötigst, dann schreibt es einfach alles in
|
||||
Normalform um, das hilft beim vergleichen."
|
||||
ring
|
||||
Hint "**Du**: Was bedeutet `ring_nf`?
|
||||
|
||||
**Robo**: Wenn man `ring` nicht am Schluss benützt, sollte man stattdessen `ring_nf`
|
||||
schreiben, aber die funktionieren praktisch gleich."
|
||||
use 2 * (r + r ^ 2)
|
||||
ring
|
||||
|
||||
-- TODO: Allow `ring_nf` as part of `ring`.
|
||||
|
||||
Conclusion "**Evenine**: Tatsächlich. Vielleicht sind wir gar nich tso unterschiedlich. Könntet
|
||||
ihr mal mit ihm reden gehen?"
|
||||
@@ -0,0 +1,53 @@
|
||||
import TestGame.Metadata
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.Contrapose
|
||||
import Mathlib.Tactic.Use
|
||||
import Mathlib.Tactic.Ring
|
||||
|
||||
import Mathlib.Algebra.Parity
|
||||
import Mathlib
|
||||
|
||||
Game "TestGame"
|
||||
World "Predicate"
|
||||
Level 8
|
||||
|
||||
Title "Für alle"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Ihr macht euch also auf den Weg. Unterwegs trefft ihr einen Händler und ihr lässt euch von
|
||||
ihm den Weg zeigen, sowie einige Tipps zu den beiden Geschwistern geben.
|
||||
|
||||
**Händler**: Also seht, die beiden sind gar nicht so verschieden. Ein altes Sprichwort sagt:
|
||||
"
|
||||
|
||||
-- Zum `∃` gehört auch das \"für alle\" `∀` (`\\forall`).
|
||||
|
||||
-- Der Syntax ist `∀ (n : ℕ), 0 ≤ n` also wie beim `∃` trennt ein Komma die Annahmen von der Aussage.
|
||||
|
||||
-- Eine `∀`-Aussage in den Annahmen verhält sich so wie ein Lemma. Das heisst man kann
|
||||
-- auch diese mit `apply` und `rw` anwenden, je nachdem was die Aussage nach dem Komma ist.
|
||||
|
||||
-- Also folgende Annahme und Lemma sind genau :
|
||||
-- - `(le_square : ∀ (n : ℕ), n ≤ n^2)`
|
||||
-- - `lemma le_square (n : ℕ) : n ≤ n^2`
|
||||
|
||||
-- Ein `∀` im Goal kann man mit `intro` angehen, genau wie bei einer Implikation `→`.
|
||||
|
||||
|
||||
-- TODO: 1-2 Aufgaben mehr.
|
||||
|
||||
Statement : ∀ (x : ℕ), (Even x) → Odd (1 + x) := by
|
||||
Hint "**Du**: Das `∀` heisst sicher \"für alle\".
|
||||
|
||||
**Robo**: Und man schreibt `\\forall`. Ein `∀ x, …` im Goal kannst du wie eine
|
||||
Implikation mit `intro x` angehen."
|
||||
intro x h
|
||||
unfold Even at h
|
||||
unfold Odd
|
||||
rcases h with ⟨y, hy⟩
|
||||
use y
|
||||
rw [hy]
|
||||
ring
|
||||
|
||||
Conclusion "**Händler**: Sichere Reise!"
|
||||
@@ -0,0 +1,109 @@
|
||||
import TestGame.Metadata
|
||||
import Mathlib.Tactic.PushNeg
|
||||
import Mathlib
|
||||
|
||||
import Mathlib.Algebra.Parity
|
||||
|
||||
import TestGame.ToBePorted
|
||||
|
||||
Game "TestGame"
|
||||
World "Predicate"
|
||||
Level 9
|
||||
|
||||
Title "PushNeg"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Das Dorf von *Oddeus* scheint stärker befestigt zu sein, all jenes von *Evenine*. Ihr kommt
|
||||
and eine Wand aus Dornenranken. Beim Eingang steht eine Wache, die auch zuruft:
|
||||
|
||||
"
|
||||
|
||||
-- Zum Schluss, immer wenn man irgendwo eine Verneinung `¬∃` oder `¬∀` sieht (`\\not`), kann man
|
||||
-- mit `push_neg` das `¬` durch den Quantor hindurchschieben.
|
||||
|
||||
-- Das braucht intern die Lemmas
|
||||
|
||||
-- - `not_exists (A : Prop) : ¬ (∃ x, A) ↔ ∀x, (¬A)`
|
||||
-- - `not_forall (A : Prop) : ¬ (∀ x, A) ↔ ∃x, (¬A)`
|
||||
|
||||
-- (welche man auch mit `rw` explizit benutzen könnte.)
|
||||
|
||||
open Nat
|
||||
|
||||
Statement : ¬ ∃ (n : ℕ), ∀ (k : ℕ) , Odd (n + k) := by
|
||||
Hint "**Du**: Also ich kann mal das `¬` durch die Quantifier hindurchschieben.
|
||||
|
||||
**Robo**: `push_neg` macht genau das!
|
||||
|
||||
**Robo**: Intern braucht das zwei Lemmas
|
||||
|
||||
```
|
||||
not_exists (A : Prop) : ¬ (∃ x, A) ↔ ∀x, (¬A)
|
||||
not_forall (A : Prop) : ¬ (∀ x, A) ↔ ∃x, (¬A)
|
||||
```
|
||||
die du natürlich auch mit `rw` gebrauchen könntest."
|
||||
Branch
|
||||
unfold Odd
|
||||
push_neg
|
||||
Hint "**Robo**: Der Weg ist etwas schwieriger. Ich würde nochmals zurück und schauen,
|
||||
dass du irgendwann `¬Odd` kriegst, was du dann mit `rw [←even_iff_not_odd]`
|
||||
zu `Even` umwandeln.
|
||||
kannst."
|
||||
push_neg
|
||||
intro n
|
||||
Hint "**Robo**: Welche Zahl du jetzt mit `use` brauchst, danach wirst du vermutlich das
|
||||
Lemma `←even_iff_not_odd` brauchen.
|
||||
|
||||
**Du**: Könnte ich jetzt schon `rw [←even_iff_not_odd]` machen?
|
||||
|
||||
**Robo**: Ne, `rw` kann nicht innerhalb von Quantifiern umschreiben.
|
||||
|
||||
**Du**: Aber wie würde ich das machen?
|
||||
|
||||
**Robo**: Zeig ich dir später, die Wache wird schon ganz ungeduldig!
|
||||
Im Moment würde ich zuerst mit `use` eine richtige Zahl angeben, und danach umschreiben."
|
||||
Branch
|
||||
use n + 2
|
||||
Hint "**Robo**: Gute Wahl! Jetzt kannst du `←even_iff_not_odd` verwenden."
|
||||
Branch
|
||||
use n + 4
|
||||
Hint "**Robo**: Gute Wahl! Jetzt kannst du `←even_iff_not_odd` verwenden."
|
||||
use n
|
||||
Hint "**Robo**: Gute Wahl! Jetzt kannst du `←even_iff_not_odd` verwenden."
|
||||
rw [←even_iff_not_odd]
|
||||
unfold Even
|
||||
use n
|
||||
--ring
|
||||
|
||||
Conclusion "Damit werdet ihr eingelassen.
|
||||
|
||||
**Robo**: Entweder wir suchen direkt diesen *Oddeus*, oder wir schauen uns einmal um. Die Wahl
|
||||
ist deine!
|
||||
|
||||
**Du**: Kannst du mir nochmals einen Überblick geben, was wir gelernt haben?
|
||||
|
||||
**Robo**:
|
||||
|
||||
| | Beschreibung |
|
||||
|:--------------|:----------------------------|
|
||||
| `ℕ` | Die natürlichen Zahlen. |
|
||||
| `∃` | Existential-Quantifier |
|
||||
| `∀` | Forall-Quantifier |
|
||||
| `Even n` | `n` ist gerade |
|
||||
| `Odd n` | `n` ist ungerade |
|
||||
|
||||
| | Taktik | Beispiel |
|
||||
|:------|:--------------------------|:-------------------------------------------------------|
|
||||
| *12ᶜ* | `rw` | Umschreiben mit Gleichungen. |
|
||||
| 13 | `ring` | Löst Gleichungen mit `+, -, *, ^`. |
|
||||
| 14 | `unfold` | Setzt visuell die Bedeutung einer Definition ein. |
|
||||
| 15 | `use` | Um ein `∃` im Goal anzugehen. |
|
||||
| *7ᶜ* | `rcases h with ⟨x, hx⟩` | Um ein `∃` in den Annahmen zu zerlegen. |
|
||||
| *8ᵇ* | `intro` | Um ein `∀` im Goal anzugehen. |
|
||||
| 16 | `push_neg` | Für `¬∃` und `¬∀` im Goal. |
|
||||
|
||||
"
|
||||
|
||||
NewTactic push_neg
|
||||
NewLemma Nat.even_iff_not_odd Nat.odd_iff_not_even not_exists not_forall
|
||||
Reference in New Issue
Block a user