rename testgame to adam

This commit is contained in:
Alexander Bentkamp
2023-03-23 17:10:13 +01:00
parent a262cff63b
commit 5c73d3bddb
166 changed files with 0 additions and 0 deletions
@@ -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