story world 2

pull/54/head
Jon Eugster 3 years ago
parent 6d93aa4752
commit 3ff3c7eb69

@ -201,3 +201,6 @@ LemmaDoc congrArg as congrArg in "Function"
"" ""
LemmaDoc congrFun as congrFun in "Function" LemmaDoc congrFun as congrFun in "Function"
"" ""
LemmaDoc Iff.symm as Iff.symm in "Logic"
""

@ -8,8 +8,9 @@ import TestGame.Levels.Implication.L07_Rw
import TestGame.Levels.Implication.L08_Iff import TestGame.Levels.Implication.L08_Iff
import TestGame.Levels.Implication.L09_Iff import TestGame.Levels.Implication.L09_Iff
import TestGame.Levels.Implication.L10_Apply import TestGame.Levels.Implication.L10_Apply
import TestGame.Levels.Implication.L11_Rw import TestGame.Levels.Implication.L11_ByCases
import TestGame.Levels.Implication.L12_Summary import TestGame.Levels.Implication.L12_Rw
import TestGame.Levels.Implication.L13_Summary
Game "TestGame" Game "TestGame"
World "Implication" World "Implication"

@ -27,7 +27,7 @@ Statement (A B : Prop) (hb : B) : A → (A ∧ B) := by
assumption assumption
assumption assumption
Conclusion "Der Operationsleiter nickt bedacht."
NewTactic intro NewTactic intro
DisabledTactic tauto DisabledTactic tauto
Conclusion "Der Operationsleiter nickt bedacht."

@ -11,7 +11,7 @@ Title "Revert"
Introduction Introduction
"Jemand aus der Gruppe gibt dir ein Blatt Papier mit einer Zeile Text:" "Jemand aus der Gruppe gibt dir ein Blatt Papier mit einer Zeile Text:"
Statement "" (A B : Prop) (ha : A) (h : A → B) : B := by Statement (A B : Prop) (ha : A) (h : A → B) : B := by
Hint "**Robo**: Mit `revert {ha}` kann man die Annahme `ha` als Hint "**Robo**: Mit `revert {ha}` kann man die Annahme `ha` als
Implikationsprämisse vorne ans Goal anhängen, dann ist das Goal `{A} → {B}`. Implikationsprämisse vorne ans Goal anhängen, dann ist das Goal `{A} → {B}`.
@ -21,10 +21,10 @@ Statement "" (A B : Prop) (ha : A) (h : A → B) : B := by
revert ha revert ha
assumption assumption
NewTactic revert
DisabledTactic tauto
Conclusion "**Du**: Aber das müsste doch auch anders gehen, ich hätte jetzt intuitiv Conclusion "**Du**: Aber das müsste doch auch anders gehen, ich hätte jetzt intuitiv
die Implikation $A \\Rightarrow B$ angewendet und behauptet, dass es genügt $A$ zu zeigen… die Implikation $A \\Rightarrow B$ angewendet und behauptet, dass es genügt $A$ zu zeigen…
Daraufhin lächelt der Fragende nur vorahnend." Daraufhin lächelt der Fragende nur vorahnend."
NewTactic revert
DisabledTactic tauto

@ -20,25 +20,21 @@ Wenn man eine Implikation `(g : A → B)` in den Annahmen hat, bei welcher die K
(also $B$) mit dem Goal übereinstimmt, kann man `apply g` genau dies machen. (also $B$) mit dem Goal übereinstimmt, kann man `apply g` genau dies machen.
" "
Statement "" (A B : Prop) (hA : A) (h : A → B) : B := by Statement (A B : Prop) (hA : A) (h : A → B) : B := by
Hint "**Robo**: Du hast natürlich recht, normalerweise ist es viel schöner mit
`apply {h}` die Implikation anzuwenden."
apply h apply h
Hint "**Du**: Und jetzt genügt es also `A` zu zeigen."
assumption assumption
NewTactic apply
DisabledTactic revert tauto
Hint (A : Prop) (B : Prop) (hA : A) (h : A → B) : B =>
"**Robo**: Du hast natürlich recht, normalerweise ist es viel schöner mit
`apply {h}` die Implikation anzuwenden."
Hint (A : Prop) (B : Prop) (hA : A) (g : A → B) : A =>
"**Du**: Und jetzt genügt es also `A` zu zeigen."
Conclusion "**Robo** Übrigens mit `apply LEMMA` kannst auch jedes Lemma anwenden, dessen Conclusion "**Robo** Übrigens mit `apply LEMMA` kannst auch jedes Lemma anwenden, dessen
Aussage mit dem Goal übereinstimmt. Aussage mit dem Goal übereinstimmt.
Die beiden Fragenden schauen das Blatt an und murmeln zustimmend." Die beiden Fragenden schauen das Blatt an und murmeln zustimmend."
NewTactic apply
DisabledTactic revert tauto
-- Katex notes -- Katex notes
-- `\\( \\)` or `$ $` for inline -- `\\( \\)` or `$ $` for inline
-- and `$$ $$` block. -- and `$$ $$` block.

@ -20,20 +20,19 @@ Gesteuert werden diese über Panels, und hier hab ich das Übungspanel, mit dem
Ingeneure ausbilden: Ingeneure ausbilden:
" "
Statement "" (A B C : Prop) (f : A → B) (g : B → C) : A → C := by Statement (A B C : Prop) (f : A → B) (g : B → C) : A → C := by
Hint "**Du**: Ich soll Implikationen $A \\Rightarrow B \\Rightarrow C$ zu $A \\Rightarrow C$
kombinieren?
**Robo**: Am besten fängst du mit `intro` an und arbeitest dich dann rückwärts durch."
intro hA intro hA
Hint (hidden := true) "**Robo**: Das ist wieder eine Anwendung von `apply`."
apply g apply g
apply f apply f
assumption assumption
Hint (A B C : Prop) (f : A → B) (g : B → C) : A → C => Conclusion "**Du**: Ich hab das Konzept verstanden.
"**Du**: Ich soll Implikationen $A \\Rightarrow B \\Rightarrow C$ zu $A \\Rightarrow C$
kombinieren?
**Robo**: Am besten fängst du mit `intro` an und arbeitest dich dann rückwärts durch.
"
HiddenHint (A : Prop) (B : Prop) (C : Prop) (hA : A) (f : A → B) (g : B → C) : C => Die Mitarbeiterin ist zufrieden und wünscht euch Glück auf der Mission."
"**Robo**: Das ist wieder eine Anwendung von `apply`."
DisabledTactic tauto DisabledTactic tauto

@ -22,43 +22,32 @@ $$
" "
Statement Statement
"Beweise $A \\Rightarrow F$."
(A B C D E F G H I : Prop) (A B C D E F G H I : Prop)
(f : A → B) (g : C → B) (h : B → E) (i : D → E) (k : E → F) (m : G → D) (f : A → B) (g : C → B) (h : B → E) (i : D → E) (k : E → F) (m : G → D)
(n : H → E) (p : F → I) (q : H → G) (r : H → I) : A → I := by (n : H → E) (p : F → I) (q : H → G) (r : H → I) : A → I := by
Hint "**Du**: Also ich muss einen Pfad von Implikationen $A \\Rightarrow I$ finden.
**Robo**: Und dann fängst du am besten wieder mit `intro` an."
intro ha intro ha
Branch
apply r
Hint "**Robo**: Das sieht nach einer Sackgasse aus…"
Hint (hidden := true) "**Robo**: Na wieder `apply`, was sonst."
apply p apply p
apply k apply k
apply h apply h
Branch
apply g
Hint "**Robo**: Nah, da stimmt doch was nicht…"
apply f apply f
assumption assumption
Hint (A B C D E F G H I : Prop) Conclusion
(f : A → B) (g : C → B) (h : B → E) (i : D → E) (k : E → F) (m : G → D) "Mit einem lauten Ratteln springen die Förderbänder wieder an.
(n : H → E) (p : F → I) (q : H → G) (r : H → I) : A → I =>
"**Du**: Also ich muss einen Pfad von Implikationen $A \\Rightarrow I$ finden.
**Robo**: Und dann fängst du am besten wieder mit `intro` an."
HiddenHint (A B C D E F G H I : Prop)
(f : A → B) (g : C → B) (h : B → E) (i : D → E) (k : E → F) (m : G → D)
(n : H → E) (p : F → I) (q : H → G) (r : H → I) (a : A) : I =>
"**Robo**: Na wieder `apply`, was sonst."
-- TODO: Dieser wird falscherweise bei `F` angezeigt
Hint (A B C D E F G H I : Prop)
(f : A → B) (g : C → B) (h : B → E) (i : D → E) (k : E → F) (m : G → D)
(n : H → E) (p : F → I) (q : H → G) (r : H → I) (a : A) : H =>
"**Robo**: Das sieht nach einer Sackgasse aus…"
Hint (A B C D E F G H I : Prop) **Operationsleiter**: Vielen Dank euch! Kommt ich geb euch eine Führung und stell euch den
(f : A → B) (g : C → B) (h : B → E) (i : D → E) (k : E → F) (m : G → D) Technikern hier vor."
(n : H → E) (p : F → I) (q : H → G) (r : H → I) (a : A) : C =>
"**Robo**: Nah, da stimmt doch was nicht…"
DisabledTactic tauto DisabledTactic tauto
Conclusion
"Mit einem lauten Ratteln springen die Förderbänder wieder an."
-- https://www.jmilne.org/not/Mamscd.pdf -- https://www.jmilne.org/not/Mamscd.pdf

@ -8,36 +8,37 @@ Title "Genau dann wenn"
Introduction Introduction
" "
Genau-dann-wenn, $A \\Leftrightarrow B$, wird als `A ↔ B` (`\\iff`) geschrieben. Als erstes kommt ihr in einen kleinen Raum mit ganz vielen Bildschirmen.
`A ↔ B` ist eine Struktur (ähnlich wie das logische UND), die aus zwei Teilen besteht:
- `mp`: die Implikation $A \\Rightarrow B$. Ein junges Wesen dreht sich auf dem Stuhl um, und sagt:
- `mpr`: die Implikation $B \\Rightarrow A$.
Hat man ein $\\Leftrightarrow$ im Goal, nimmt man dieses ebenfalls mit der Taktik **Mitarbeiter**: Oh hallo! Schaut euch mal das hier an!
`constructor` auseinander und zeigt dann beide Richtungen einzeln.
" "
Statement Statement (A B : Prop) (mp : A → B) (mpr : B → A) : A ↔ B := by
"Zeige dass `B ↔ C`." Hint "**Robo**: Das ist ein genau-dann-wenn Pfeil: `\\iff`. Er besteht aus zwei Teilen:
(A B : Prop) (mp : A → B) (mpr : B → A) : A ↔ B := by `A ↔ B` ist als `⟨A → B, B → A⟩` definiert.
**Du**: Also ganz ähnlich wie das UND, `A ∧ B`?
**Robo**: Genau. Entsprechend kannst du hier auch mit `constructor` anfangen."
constructor constructor
Hint "**Du**: Ah und die beiden hab ich schon in den Annahmen."
assumption assumption
assumption assumption
HiddenHint (A : Prop) (B : Prop) : A ↔ B =>
"Eine Struktur wie `A ↔ B` kann man mit `constructor` zerlegen."
HiddenHint (A : Prop) (B : Prop) (h : A → B) : A → B =>
"Such mal in den Annahmen."
Conclusion Conclusion
" "
Die Taktik `constructor` heisst so, weil `↔` als \"Struktur\" definiert ist, die **Robo**: Übrigens, bei `(h : A ∧ B)` haben die beiden Teile `h.left` und `h.right` geheissen,
aus mehreren Einzelteilen besteht: `⟨A → B, B → A⟩`. Man sagt also Lean, es soll versuchen, hier bei `(h : A ↔ B)` heissen sie `h.mp` und `h.mpr`.
ob das Goal aus solchen Einzelteilen \"konstruiert\" werden kann.
**Du**: Also `h.mp` ist `A → B`? Wieso `mp`?
**Operationsleiter**: Das steht Modulo Ponens, aber das ist doch nicht wichtig. Und das \"r\"
steht für \"reverse\" weils die Gegenrichtung ist.
" "
NewTactic constructor assumption NewTactic constructor
DisabledTactic tauto rw
-- TODO : `case mpr =>` ist mathematisch noch sinnvoll. -- TODO : `case mpr =>` ist mathematisch noch sinnvoll.

@ -11,64 +11,35 @@ Title "Genau dann wenn"
Introduction Introduction
" "
Hat man ein `(h : A ↔ B)` in den Annahmen, hat man die gleichen beiden Optionen wie beim Als nächstes begenet ihr jemandem im Flur.
logischen UND plus noch eine neue:
1. Mit `h.mp` und `h.mpr` (oder `h.1` und `h.2`) kann man die einzelnen Implikationen Dieser hat schon von euch gehört und will sofort wissen, ob ihr ihm helfen könnt:
direkt auswählen.
2. Mit `rcases h with ⟨h₁, h₂⟩` könnte man die Struktur `h` zerlegen und man erhält zwei
separate Annahmen `(h₁ : A → B)` und `(h₂ : B → A)`
3. **Mit** `rw [h]` **kann man im Goal `A` durch `B` ersetzen.**
Wir widmen uns zuerst `rw`. Dies steht für \"rewrite\". Da $A$ und $B$ logisch äquivalent
sind, kann man beliebig das eine mit dem anderen vertauschen.
`rw [h]` ersetzt $A$ durch $B$.
Dabei gibt es noch einige Tricks:
- `rw [← h]` ersetzt umgekehrt $B$ durch $A$ (`\\l`, kleines L).
- `rw [h, g]` ist das gleiche wie `rw [h]` gefolgt von `rw [g]`.
" "
Statement Statement (A B C D : Prop) (h₁ : C ↔ D) (h₂ : A ↔ B) (h₃ : A ↔ D) : B ↔ C := by
"Zeige dass `B ↔ C`." Hint "**Du**: $B \\iff A \\iff D \\iff C$, die sind doch alle äquivalent…
(A B C D : Prop) (h₁ : C ↔ D) (h₂ : A ↔ B) (h₃ : A ↔ D) : B ↔ C := by
rw [h₁]
rw [←h₂]
assumption
HiddenHint (A : Prop) (B : Prop) (C : Prop) (D : Prop) (h₁ : C ↔ D) (h₂ : A ↔ B) (h₃ : A ↔ D) : B ↔ C =>
"Im Goal kommt `C` vor und `h₁` sagt `C ↔ D`.
Probiers doch mit `rw [h₁]`."
HiddenHint (A : Prop) (B : Prop) (C : Prop) (D : Prop) (h₁ : C ↔ D) (h₂ : A ↔ B) (h₃ : A ↔ D) : A ↔ C =>
"Im Goal kommt `C` vor und `h₁` sagt `C ↔ D`.
Probiers doch mit `rw [h₁]`."
Hint (A : Prop) (B : Prop) (C : Prop) (D : Prop) (h₁ : C ↔ D) (h₂ : A ↔ B) (h₃ : A ↔ D) : B ↔ D => **Robo**: Ja aber du musst ihm helfen umzuschreiben. Mit `rw [h₁]` kannst du `C` durch `D`
"Man kann auch rückwärts umschreiben: ersetzen."
`rw [←h₂]` ersetzt man im Goal `B` durch `a` (`\\l`, also ein kleines L)" rw [h₁]
Hint "**Du** Und wenn ich in die andere Richtung umschreiben möchte?
HiddenHint (A : Prop) (B : Prop) (h : A ↔ B) : A ↔ B =>
"Schau mal durch die Annahmen durch."
-- These should not be necessary if they don't use `rw [] at`.
HiddenHint (A : Prop) (B : Prop) (C : Prop) (D : Prop) (h₁ : C ↔ D) (h₂ : A ↔ B) (h₃ : A ↔ C) : B ↔ C =>
"Auch eine Möglichkeit... Kannst du das Goal so umschreiben,
dass es mit einer Annahme übereinstimmt?"
HiddenHint (A : Prop) (B : Prop) (C : Prop) (D : Prop) (h₁ : C ↔ D) (h₂ : A ↔ B) (h₃ : B ↔ D) : B ↔ C =>
"Auch eine Möglichkeit.. Kannst du das Goal so umschreiben, dass es mit einer Annahme übereinstimmt?"
Hint (A : Prop) (B : Prop) (h : B ↔ A) : A ↔ B => **Robo**: Dann schreibst du ein `←` vor den Namen, also `rw [← hₓ]`."
"Naja auch Umwege führen ans Ziel... Wenn du das Goal zu `A ↔ A` umschreibst, kann man es mit Branch
`rfl` beweisen (rsp. das passiert automatisch.)" rw [← h₃]
Hint "**Du**: Ehm, das ist verkehrt.
Hint (A : Prop) (B : Prop) (C : Prop) (D : Prop) (h₁ : C ↔ D) (h₂ : D ↔ B) (h₃ : D ↔ A) : B ↔ C => **Robo**: Andersrum wär's besser gewesen, aber wenn du jetzt einfach weitermachst bis du
"Das ist nicht der optimale Weg..." sowas wie `A ↔ A` kriegst, kann `rfl` das beweisen.
Hint (A : Prop) (B : Prop) (C : Prop) (D : Prop) (h₁ : C ↔ D) (h₂ : D ↔ B) (h₃ : A ↔ D) : B ↔ C => **Robo: Da fällt mir ein, `rw` versucht automatisch `rfl` am Ende. Das heisst, du musst
"Das ist nicht der optimale Weg..." das nicht einmal mehr schreiben."
rw [h₂]
rw [←h₂]
assumption
Conclusion "Ihr geht weiter und der Operationsleiter zeigt euch die Küche."
NewTactic rw assumption NewTactic rw assumption
DisabledTactic tauto
-- NewLemma Iff.symm

@ -10,35 +10,35 @@ Title "Genau dann wenn"
Introduction Introduction
" "
Nun schauen wir uns Option 1) an, die du schon von UND kennst: Der Koch kommt erfreut hinter einem grossen Topf hervor.
1. Mit `h.mp` und `h.mpr` (oder `h.1` und `h.2`) kann man die einzelnen Implikationen **Koch**: Sagt mal, gestern hat mir jemand was erzählt und es will einfach nicht aus
direkt auswählen. meinem Kopf…
`h.mp` und `h.mpr` (oder `h.1` und `h.2`) sind die einzelnen Implikationen, und du kannst
mit denen ensprechend arbeiten. Insbesondere kannst du mit `apply h.mp` die Implikation
$A \\Rightarrow B$ anwenden, wenn das Goal $B$ ist.
*(PS: das `.mp` kommt von \"Modus Ponens\", ein Ausdruck as der Logik.)*
" "
Statement Statement (A B C : Prop) (h : A ↔ B) (g : B → C) : A → C := by
"Angenommen man hat $A \\iff B$ und $B \\Rightarrow C$, zeige $A \\Rightarrow C$." Hint "**Du**: Naja ich kann wohl immerhin mal mit `intro` anfangen und annehmen,
(A B C : Prop) (h : A ↔ B) (g : B → C) : A → C := by dass `{A}` wahr sei…
**Robo**: und dann schauen wir weiter!"
intro hA intro hA
Hint "**Robo**: Also eine Implikation wendet man mit apply an…
**Du**: Weiss ich ja!"
apply g apply g
apply h.mp Hint "**Robo**: …und du kannst die Implikation `{A} → {B}` genau gleich mit
assumption `apply {h}.mp` anwenden.
HiddenHint (A : Prop) (B : Prop) (C : Prop) (h : A ↔ B) (g : B → C) : A → C => **Du**: Aber ich könnte hier auch `rw [← h]` sagen, oder?
"Fange wie immer mit `intro` an."
HiddenHint (A : Prop) (B : Prop) (C : Prop) (h : A ↔ B) (g : B → C) (hA : A) : C => **Robo**: Klar, aber offenbar versteht der Koch das `rw` nicht.
"Wie im Implikationen-Level kannst du nun `apply` verwenden." "
apply h.mp
assumption
Hint (A : Prop) (B : Prop) (C : Prop) (h : A ↔ B) (g : B → C) (hA : A) : B => Conclusion "**Koch**: Danke vielmals! Jetzt muss ich aber schauen dass die Suppe nicht verkocht!
"Mit `apply h.mp` kannst du nun die Implikation `A → B` anwenden."
Conclusion "Im nächsten Level findest du die zweite Option." Und er eilt davon."
NewTactic apply assumption NewTactic apply assumption
DisabledTactic tauto rw

@ -10,33 +10,30 @@ Title "Genau dann wenn"
Introduction Introduction
" "
Und noch die letzte Option: Noch während der Koch wieder zu seiner Suppe geht, kommt sein erster Gehilfe hervor.
2. Mit `rcases h with ⟨h₁, h₂⟩` könnte man die Struktur `h` zerlegen und man erhält zwei **Gehilfe**: Ich hab gestern noch was anderes gehört, könnt ihr mir da auch helfen?
separate Annahmen `(h₁ : A → B)` und `(h₂ : B → A)` Aber ich versteh nicht ganz was ihr meinem Chef erklärt habt.
Als letzte Option kannst du `rcases h with ⟨h₁, h₂⟩` auch auf eine Annahme `(h : A ↔ B)`
anwenden, genau wie du dies bei einer Annahme `(h' : A ∧ B)` gemacht hast.
" "
Statement
"Angenommen man hat $A \\iff B$ und $B \\Rightarrow C$, zeige $A \\Rightarrow C$."
(A B : Prop) : (A ↔ B) → (A → B) := by
intro h
rcases h
assumption
HiddenHint (A : Prop) (B : Prop) : (A ↔ B) → A → B => Statement (A B : Prop) : (A ↔ B) → (A → B) := by
"Angefangen mit `intro h` kannst du annehmen, dass `(h : A ↔ B)` wahr ist." Hint "**Du**: Hmm, mindestens mit der Implikation kann ich anfangen."
Hint (hidden := true) "**Robo**: Genau, das war `intro`."
HiddenHint (A : Prop) (B : Prop) (h : A ↔ B) : A → B => intro h
"Mit `rcases h with ⟨h₁, h₂⟩` kannst du jetzt die Annahme `(h : A ↔ B)` zerlegen." Hint "**Du**: Also ich kenn `rw [h]` und `apply h.mp`, aber das will er wohl nicht hören.
**Robo**: Was du machen könntest ist mit `rcases h with ⟨mp, mpr⟩` die Annahme in zwei
Teile aufteilen."
rcases h with ⟨mp, mpr⟩
Hint (hidden := true) "**Du**: Ah und jetzt ist das Resultat in den Annahmen."
assumption
Conclusion Conclusion
" "
**Gehilfe**: Ah danke! Und jetzt versteh ich auch die Zusammenhänge!
" "
NewTactic intro apply rcases assumption DisabledTactic rw apply tauto
-- -- TODO: The new `cases` works differntly. There is also `cases'` -- -- TODO: The new `cases` works differntly. There is also `cases'`
-- example (A B : Prop) : (A ↔ B) → (A → B) := by -- example (A B : Prop) : (A ↔ B) → (A → B) := by

@ -11,6 +11,12 @@ Title "Lemmas"
Introduction Introduction
" "
Ihr setzt euch hin und der Gehilfe bringt euch allen Suppe. Neben euch sitzt eine Mechanikerin
über ihre Suppe geneigt.
**Mechanikerin**: Sagt mal, ich hab unten über folgendes tiefgründiges Problem nachgedacht:
Bewiesene Resultate möchte man in späteren Aufgaben als Sätze wieder verwenden. Bewiesene Resultate möchte man in späteren Aufgaben als Sätze wieder verwenden.
In Lean sind das Lemmas und Theoreme (wobei es keinen Unterschied zwischen `lemma` und `theorem` In Lean sind das Lemmas und Theoreme (wobei es keinen Unterschied zwischen `lemma` und `theorem`
@ -33,23 +39,21 @@ Wenn also dein Goal `¬A B` ist, kannst du mit `apply not_or_of_imp` dieses
Lemma anwenden. Danach musst du noch alle Annahmen zeigen. Lemma anwenden. Danach musst du noch alle Annahmen zeigen.
" "
Statement Statement (A : Prop) : ¬A A := by
"Benutze `not_or_of_imp` um zu zeigen, dass $\\neg A \\lor A$ wahr ist." Hint "**Du**: Das scheint ziemlich offensichtlich.
(A : Prop) : ¬A A := by
**Robo**: Ich glaube, sie will eine detailierte Antwort. Ich kenne ein Lemma
`not_or_of_imp`, was sagt `(A → B) → ¬ A B`. Da das Resultat des Lemmas mit
deinem Goal übreinstimmt, kannst du es mit `apply not_or_of_imp` anwenden."
apply not_or_of_imp apply not_or_of_imp
Hint (hidden := true) "**Robo**: Ich würd wieder mit `intro` weitermachen."
intro intro
assumption assumption
HiddenHint (A : Prop) : ¬A A =>
"Das Lemma wendest du mit `apply not_or_of_imp` an."
HiddenHint (A : Prop) : A → A =>
"Wie immer, `intro` ist dein Freund."
Conclusion Conclusion
" "
**Mechanikerin**: Danke vielmals, jetzt bin ich schon viel ruhiger.
" "
NewTactic apply left right assumption
NewLemma not_or_of_imp NewLemma not_or_of_imp
DisabledTactic tauto

@ -0,0 +1,38 @@
import TestGame.Metadata
import Std.Tactic.RCases
import Mathlib.Tactic.Cases
import Mathlib
Game "TestGame"
World "Implication"
Level 11
Title "by_cases"
Introduction
"
**Du**: Sagt mal, hätte ich da nicht auch einfach zwei Fälle anschauen können:
Wenn `A` wahr ist, beweis ich die rechte Seite, sonst die Linke.
**Robo**: Tatsächlich, `by_cases h : A` würde genau das machen!
"
Statement (A : Prop) : ¬A A := by
Hint (hidden := true) "**Du**: Wie?
**Robo**: Also `by_cases h : A` erstellt zwei Goals. Im ersten hast Du `(h : A)` zur
Verfügung, im zweiten `(h : ¬ A)`."
by_cases h : A
Hint "**Du**: "
right
assumption
left
assumption
Conclusion
"
**Du**: Das kann noch ganz nützlich sein.
"
NewTactic by_cases
DisabledTactic tauto

@ -1,39 +0,0 @@
import TestGame.Metadata
import Std.Tactic.RCases
import Mathlib.Tactic.Cases
import Mathlib.Logic.Basic
Game "TestGame"
World "Implication"
Level 11
Title "Lemmas"
Introduction
"
Wenn die Aussage eines Lemmas eine Äquivalenz ist, kann man dieses auch mit `rw` brauchen,
wie du es von Äquivalenzen kennst.
Ein wichtiges Lemma ist dass $\\neg(\\neg A))$ und $A$ äquivalent sind:
```
lemma not_not (A : Prop) : ¬¬A ↔ A := by
...
```
Mit `rw [not_not]` sucht Lean also im Goal ein Term `¬¬(·)` und entfernt dort das `¬¬`.
"
Statement
"Zeige, dass $A (¬¬B) ∧ C$ und $A B ∧ C$ äquivalent sind."
(A B C : Prop) : A (¬¬B) ∧ C ↔ A B ∧ C := by
rw [not_not]
Conclusion
"
`rw` hat automatisch `rfl` ausgeführt und dadurch den Beweis beendet.
"
NewTactic rw
NewLemma not_not not_or_of_imp

@ -0,0 +1,50 @@
import TestGame.Metadata
import Std.Tactic.RCases
import Mathlib.Tactic.Cases
import Mathlib.Logic.Basic
Game "TestGame"
World "Implication"
Level 12
Title "Lemmas"
Introduction
"
Der Arbeitskollegin der Mechanikerin, der die ganze Zeit gespannt zugehört hat, dreht sich zu
euch.
Er ist offensichtlich interessiert and existierenden Resultaten zu sein, aber offenbar
kann er nicht viel mit `apply` anfangen.
Er hat aber folgendes Resultat bereit:
```
lemma not_not (A : Prop) : ¬¬A ↔ A
```
und stellt euch folgende Frage:
"
Statement (A B C : Prop) : (A ∧ (¬¬C)) (¬¬B) ∧ C ↔ (A ∧ C) B ∧ (¬¬C) := by
Hint "**Robo**: Ein Lemma, das wie `not_not` ein `↔` oder `=` im Statement hat, kann
auch mit `rw [not_not]` verwendet werden."
rw [not_not]
Hint "**Du**: Häh, wieso hat das jetzt 2 von 3 der `¬¬` umgeschrieben?
**Robo**: `rw` schreibt nur das erste um, das es findet, also `¬¬C`. Aber weil dieses
mehrmals vorkommt, werden die alle ersetzt…
**Du**: Ah, und `¬¬B` ist was anderes, also brauch ich das Lemma nochmals."
rw [not_not]
Conclusion
"
**Du**: Ah und wir sind fertig…?
**Robo**: Ja, `rw` versucht immer anschliessend `rfl` aufzurufen, und das hat hier
funktioniert.
"
DisabledTactic tauto apply
NewLemma not_not

@ -1,81 +0,0 @@
import TestGame.Metadata
import Std.Tactic.RCases
import Mathlib.Tactic.LeftRight
import Mathlib
set_option tactic.hygienic false
Game "TestGame"
World "Implication"
Level 12
Title "Zusammenfassung"
Introduction
"
Damit bist du am Ende der zweiten Lektion angekommen.
Hier ein Überblick über alles was in diesem Kapitel eingeführt wurde und eine
Abschlussaufgabe.
## Notationen / Begriffe
| | Beschreibung |
|:--------------|:---------------------------------------------------------|
| → | Eine Implikation. |
| ↔ | Genau-dann-wenn / Äquivalenz. |
| `lemma` | Ein Resultat mit einem Namen. |
| `theorem` | Das gleiche wie ein Lemma. |
| `example` | Wie ein Lemma aber ohne Namen (nicht weiter verwendbar.) |
## Taktiken
| | Taktik | Beispiel |
|:----|:--------------------------|:-------------------------------------------------------|
| 8 | `intro` | Für eine Implikation im Goal. |
| 9 | `revert` | Umkehrung von `intro`. |
| 10 | `apply` | Wendet eine Implikation auf das Goal an. |
| 10ᵇ | `apply` | Wendet ein Lemma an. |
| 11 | `rw` | Umschreiben zweier äquivalenter Aussagen. |
| 11ᵇ | `rw` | Benutzt ein Lemma, dessen Aussage eine Äquivalenz ist. |
Als Abschlussübung kannst du folgende Äquivalenz zeigen:
"
Statement imp_iff_not_or
"$A \\Rightarrow B$ ist äquivalent zu $\\neg A \\lor B$."
(A B : Prop) : (A → B) ↔ ¬ A B := by
constructor
apply not_or_of_imp
intro h ha
rcases h with h | h
contradiction
assumption
HiddenHint (A : Prop) (B: Prop) : (A → B) ↔ ¬ A B =>
"Eine Äquivalenz im Goal geht man immer mit `constructor` an."
HiddenHint (A : Prop) (B: Prop) : (A → B) → ¬ A B =>
"Diese Aussage hast du vorhin bereits als Lemma kennengelernt und angewendet."
HiddenHint (A : Prop) (B: Prop) (h : A → B) : ¬ A B =>
"Diese Aussage hast du vorhin bereits als Lemma kennengelernt und angewendet."
HiddenHint (A : Prop) (B: Prop) : ¬ A B → (A → B) =>
"Eine Implikation geht man fast immer mit `intro h` an."
HiddenHint (A : Prop) (B: Prop) (h : ¬ A B) : (A → B) =>
"Nochmals `intro`."
HiddenHint (A : Prop) (B: Prop) (h : ¬ A B) : (A → B) =>
"Das ODER in den Annahmen kannst du mit `rcases h with h | h` aufteilen."
HiddenHint (A : Prop) (B: Prop) (h : ¬ A B) (ha : A) : B =>
"Das ODER in den Annahmen kannst du mit `rcases h with h | h` aufteilen."
HiddenHint (A : Prop) (B: Prop) (ha : A) (ha' : ¬A) : B =>
"Findest du einen Widerspruch?"
NewTactic rfl assumption trivial left right constructor rcases
NewLemma not_not not_or_of_imp

@ -0,0 +1,63 @@
import TestGame.Metadata
import Std.Tactic.RCases
import Mathlib.Tactic.LeftRight
import Mathlib
set_option tactic.hygienic false
Game "TestGame"
World "Implication"
Level 13
Title "Zusammenfassung"
Introduction
"
**Operationsleiter**: Damit endet unsere Führung langsam. Bevor ihr weitergeht
habe ich noch ein Problem, an dem ich mir die Zähne ausbeisse. Wir haben die
Herleitung eines unserer Programme `imp_iff_not_or` verloren, und wissen nicht mehr
ob es einwandfrei funktioniert.
**Du**: Nah gut, al sehen. Robo, was hab ich denn alles hier gelernt?
**Robo**: Hier ist die Übersicht:
## Notationen / Begriffe
| | Beschreibung |
|:--------------|:---------------------------------------------------------|
| → | Eine Implikation. |
| ↔ | Genau-dann-wenn / Äquivalenz. |
## Taktiken
| | Taktik | Beispiel |
|:----|:--------------------------|:-------------------------------------------------------|
| 8 | `intro` | Für eine Implikation im Goal. |
| 9 | `revert` | Umkehrung von `intro`. |
| 10 | `apply` | Wendet eine Implikation auf das Goal an. |
| 10ᵇ | `apply` | Wendet ein Lemma an. |
| 11 | `by_cases` | Fallunterscheidung `P` und `¬P` |
| 12 | `rw` | Umschreiben zweier äquivalenter Aussagen. |
| 12ᵇ | `rw` | Benutzt ein Lemma, dessen Aussage eine Äquivalenz ist. |
"
Statement imp_iff_not_or (A B : Prop) : (A → B) ↔ ¬ A B := by
constructor
Hint "**Du**: Das sieht kompliziert aus…
**Robo** *(flüsternd)*: Ja, aber die Richtung kennst du ja schon also Lemma,
wend doch einfach das an."
apply not_or_of_imp
Hint "**Du**: Gibt es für die Gegenrichtung auch ein Lemma?
**Robo**: Leider nicht. Da musst du manuell ran."
Hint (hidden := true) "**Robo**: Na Implikationen fangst du immer mit `intro` an."
intro h
intro ha
Hint (hidden := true) "**Robo**: Ich wür mal die Annahme `h` mit `rcases` aufteilen."
rcases h with h | h
contradiction
assumption
DisabledTactic tauto
Loading…
Cancel
Save