merge necessary as upstream developed while storyline slept
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import Adam.Metadata
|
||||
import Mathlib.Tactic.Tauto
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 1
|
||||
|
||||
Title "Automatisierung"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Gerade seid Ihr auf Königin *Logisindes* Planeten. Sie kommt ohne Umschweife zum Punkt:
|
||||
|
||||
**Logisinde** Werte Wesen aus fremden Welten, gestatten Sie eine Frage. Warum gilt …
|
||||
|
||||
Und sie kritzelt etwas auf ein Stück Papier: oben ein paar Annahmen, unten eine Schlussfolgerung.
|
||||
Dazwischen sollst Du offenbar einen Beweis eintragen.
|
||||
Du siehst Robo hilflos an.
|
||||
"
|
||||
|
||||
Statement ""
|
||||
(A B C : Prop) :
|
||||
¬((¬B ∨ ¬ C) ∨ (A → B)) → (¬A ∨ B) ∧ ¬ (B ∧ C) := by
|
||||
Hint "**Robo** Das ist ganz einfach. Mit `{A} {B} {C} : Prop` meint sie:
|
||||
`{A}`, `{B}` und `{C}` sind irgendwelche Aussagen (*propositions*).
|
||||
Und mit `→` meint sie ⇒, also “impliziert”. Die anderen Symbole kennst Du, oder?
|
||||
|
||||
**Du** Ehhm, ja. Aber da muss ich jetzt trotzdem erst einmal überlegen.
|
||||
|
||||
**Robo** (flüsternd) Behaupte doch einfach, dass sei eine Tautologie.
|
||||
|
||||
**Du** Ernsthaft?
|
||||
|
||||
**Robo** Ja. Schreib einfach `tauto`.
|
||||
|
||||
**Robo** Mach schon …"
|
||||
tauto
|
||||
|
||||
Conclusion
|
||||
"
|
||||
**Logisinde** (etwas konsterniert) Ja, das ist streng genommen richtig.
|
||||
Aber glaubt bloß nicht, dass Ihr damit auf *diesem* Planeten viel weiterkommt!
|
||||
Meine Untertanen verstehen `tauto` nicht. Da müsst Ihr Euch schon etwas mehr anstrengen.
|
||||
"
|
||||
|
||||
NewTactic tauto
|
||||
@@ -0,0 +1,32 @@
|
||||
import Adam.Metadata
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 2
|
||||
|
||||
Title "Aller Anfang ist... ein Einzeiler?"
|
||||
|
||||
Introduction
|
||||
"
|
||||
In der Zwischenzeit hat bereits sich eine lange Schlange Untertanen gebildet, die gern ihren
|
||||
Fragen stellen würden. Logisinde winkt den ersten nach vorn. Er räuspert sich.
|
||||
|
||||
**Untertan** Warum ist $42 = 42$?
|
||||
|
||||
Du schaust ihn fassungslos an.
|
||||
Er schreibt es Dir wieder auf.
|
||||
"
|
||||
|
||||
Statement "" :
|
||||
42 = 42 := by
|
||||
Hint " **Robo** Ist doch klar. Du musst ihn einfach daran erinnern,
|
||||
dass Gleichheit *reflexiv* ist. Probier mal `rfl`."
|
||||
rfl
|
||||
|
||||
Conclusion
|
||||
"
|
||||
**Untertan** Ah, richtig. Ja, Sie haben ja so recht. Das vergesse ich immer. Rfl, rfl, rfl …
|
||||
"
|
||||
|
||||
NewTactic rfl
|
||||
DisabledTactic tauto
|
||||
@@ -0,0 +1,43 @@
|
||||
import Adam.Metadata
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 3
|
||||
|
||||
Title "Annahmen"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Während der erste Untertan noch rfl, rfl, rfl murmelt, tritt schon der nächste nach vorne. Es ist schüchtern und schreibt bloß.
|
||||
"
|
||||
|
||||
Statement ""
|
||||
(n : ℕ) (h₁ : 10 > n) (h₂ : 1 < n) (h₃ : n ≠ 5) : 1 < n := by
|
||||
Hint "
|
||||
**Robo** `{n} : ℕ` bedeutet, `{n}` ist eine natürliche Zahl.
|
||||
|
||||
**Du** Warum schreibt er dann nicht `{n} ∈ ℕ`??
|
||||
|
||||
**Robo** Weil das hier alles komische Typen sind … Ich kann Dir das später mal in Ruhe erklären.
|
||||
Jetzt will ich erst einmal die Frage entschlüsseln.
|
||||
|
||||
**Robo** Also, `{h₁}`, `{h₂}`, `{h₃}` sind einfach nur Namen für verschiedene Annahmen, und zwar
|
||||
für die Annahme `n < 10`, `1 < n` und `n ≠ 5`. Beweisen sollen wir: `1 < n`.
|
||||
|
||||
**Du** Aber das war doch gerade eine der Annahmen.
|
||||
|
||||
**Robo** Ja, stimmt.
|
||||
|
||||
**Du** ???
|
||||
|
||||
**Robo** Du musst ihm das halt explizit sagen. Probiers mal mit `assumption`."
|
||||
assumption
|
||||
|
||||
Conclusion
|
||||
"
|
||||
**Untertan** Ja richtig! Wenn Ihr nur wüsstet, was ich mir an dieser Frage schon den Kopf
|
||||
zerbrochen habe!
|
||||
"
|
||||
|
||||
NewTactic assumption
|
||||
DisabledTactic tauto
|
||||
@@ -0,0 +1,36 @@
|
||||
import Adam.Metadata
|
||||
import Mathlib.Data.Nat.Basic -- TODO
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 4
|
||||
|
||||
Title "Logische Aussagen"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Ein dritter Untertan kommt mit folgendem Problem.
|
||||
"
|
||||
|
||||
Statement ""
|
||||
(A : Prop) (hA : A) : A := by
|
||||
Hint "
|
||||
**Robo** Hier bedeutet `{A} : Prop` wieder, dass `{A}` irgendeine Aussage ist.
|
||||
Und `{hA}` ist eine Name für die Annahme, dass `{A}` wahr ist.
|
||||
|
||||
**Du** Und unter dieser Annahme sollen wir jetzt `{A}` beweisen?
|
||||
|
||||
**Robo** Ja. Da kommst Du jetzt selbst drauf, wie das geht, oder?
|
||||
"
|
||||
Hint (hidden := true) "**Robo**: Ist doch genau wie eben:
|
||||
die Aussage, die zu beweisen ist, gehört selbst zu den Annahmen.
|
||||
Also wird `assumption` auch wieder funktionieren."
|
||||
assumption
|
||||
|
||||
Conclusion
|
||||
"
|
||||
**Untertan** Das ging ja schnell. Super! Vielen Dank.
|
||||
"
|
||||
|
||||
NewTactic assumption
|
||||
DisabledTactic tauto
|
||||
@@ -0,0 +1,37 @@
|
||||
import Adam.Metadata
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 5
|
||||
|
||||
Title "True/False"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Der nächste Untertan in der Reihe ist ein Schelm.
|
||||
"
|
||||
|
||||
Statement "" : True := by
|
||||
Hint "
|
||||
**Robo** Dieses `True` ist eine spezielle Aussage, nämlich die Aussage, die immer und
|
||||
bedingungslos wahr ist.
|
||||
|
||||
**Du** Und was genau ist dann zu beweisen?
|
||||
|
||||
**Robo** Ich glaube, nichts. Ich glaube, Du kannst einfach `trivial` schreiben.
|
||||
"
|
||||
trivial
|
||||
|
||||
Conclusion
|
||||
"
|
||||
**Schelm** Wollte nur mal sehen, dass Ihr nicht auf den Kopf gefallen seid …
|
||||
|
||||
**Du** *(zu Robo)* Können wir nicht einfach immer dieses `trivial` verwenden?
|
||||
Wie in einer Mathe-Vorlesung?
|
||||
|
||||
**Robo** Nein, das `trivial` hier hat eine ziemlich spezielle Bedeutung.
|
||||
Das funktioniert nur in einer Handvoll Situationen.
|
||||
"
|
||||
|
||||
NewTactic trivial
|
||||
DisabledTactic tauto
|
||||
@@ -0,0 +1,34 @@
|
||||
import Adam.Metadata
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 6
|
||||
|
||||
Title "Not"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Der Schelm hat noch eine Schwester dabei.
|
||||
"
|
||||
|
||||
Statement "" : ¬False := by
|
||||
Hint "
|
||||
**Robo** Dieses Zeichen `¬` bedeutet Negation. Also wenn eine Aussage `(A : Prop)`
|
||||
wahr ist, dann ist `¬A` falsch, und umgekehrt.
|
||||
|
||||
**Du** Und `False` ist wahrscheinlich die Aussage, die immer falsch ist?
|
||||
|
||||
**Robo** Ja, richtig.
|
||||
|
||||
**Du** Ist das jetzt nicht doch wieder trivial?
|
||||
|
||||
**Robo** Probier mal!"
|
||||
trivial
|
||||
|
||||
Conclusion
|
||||
"
|
||||
Die Schwester lacht und eilt ihrem Bruder hinterher.
|
||||
"
|
||||
|
||||
NewTactic trivial
|
||||
DisabledTactic tauto
|
||||
@@ -0,0 +1,45 @@
|
||||
import Adam.Metadata
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.LeftRight
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 7
|
||||
|
||||
Title "Aus Falschem folgt vieles."
|
||||
|
||||
Introduction
|
||||
"
|
||||
Als nächstes kommen drei Querulanten. Der erste hat folgendes Problem:
|
||||
"
|
||||
|
||||
Statement ""
|
||||
(A : Prop) (h : False) : A := by
|
||||
Hint "**Du** Wenn ich das jetzt richtig lese, ist `{A}` eine Aussage,
|
||||
und wir haben außerdem eine Annahme names `{h}`, die besagt …
|
||||
|
||||
**Robo** … die besagt, dass `False` gilt.
|
||||
|
||||
**Du** Ich dachte, `False` gilt nie?
|
||||
|
||||
**Robo** Ja, genau. Die Annahme ist `False`, also falsch.
|
||||
Und aus einer falschen Annahme kann man bekanntlich alles beweisen!
|
||||
Insbesondere die gesuchte Aussage `{A}`.
|
||||
|
||||
**Du** Und wie erkläre ich das jetzt diesem Formalosophen?
|
||||
|
||||
**Robo** Ich glaube, Du musst ihn darauf hinweisen, dass zwischen der allgemeingültigen
|
||||
Annahme `True` und seiner Annahme `False` ein Widerspruch besteht. Probier mal `contradiction`."
|
||||
contradiction
|
||||
|
||||
Conclusion
|
||||
"Der erste Querulant ist offenbar zufrieden.
|
||||
|
||||
**Du** War das jetzt ein Widerspruchsbeweis?
|
||||
|
||||
**Robo** Nein, nein, ein Widerspruchsbeweis sieht anders aus. Das Argument hier war:
|
||||
wir haben eine `contradiction` in unserem Annahmen, also folgt jede beliebige Aussage.
|
||||
"
|
||||
|
||||
NewTactic contradiction
|
||||
DisabledTactic tauto
|
||||
@@ -0,0 +1,39 @@
|
||||
import Adam.Metadata
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.LeftRight
|
||||
|
||||
import Adam.ToBePorted
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 8
|
||||
|
||||
Title "Aus Falschem folgt vieles."
|
||||
|
||||
Introduction
|
||||
"
|
||||
Auftritt zweiter Querulant.
|
||||
"
|
||||
|
||||
Statement ""
|
||||
(n : ℕ) (h : n ≠ n) : n = 37 := by
|
||||
Hint "**Du** Ist `{n} ≠ {n}` nicht auch ein Widerspruch?
|
||||
|
||||
**Robo** Probiers mal!"
|
||||
contradiction
|
||||
|
||||
Conclusion
|
||||
"
|
||||
**Du** Ja, scheint funktioniert zu haben.
|
||||
|
||||
**Du** Aber irgendwie kommt mir das immer noch ein wenig suspekt vor.
|
||||
Jetzt habe ich bewiesen, dass eine beliebige natürliche Zahl gleich 37 ist?
|
||||
|
||||
**Robo** Nein, nicht doch. Nur eine beliebige Zahl, die ungleich sich selbst ist, ist gleich 37.
|
||||
Und gleich 38, und gleich 39, …
|
||||
|
||||
**Du** Ok, ok, verstehe.
|
||||
"
|
||||
|
||||
NewTactic contradiction
|
||||
DisabledTactic tauto
|
||||
@@ -0,0 +1,35 @@
|
||||
import Adam.Metadata
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.LeftRight
|
||||
|
||||
import Adam.ToBePorted
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 9
|
||||
|
||||
Title "Aus Falschem folgt vieles."
|
||||
|
||||
Introduction
|
||||
"
|
||||
Auftritt dritter Querulant.
|
||||
"
|
||||
|
||||
Statement ""
|
||||
(n : ℕ) (h : n = 10) (g : n ≠ 10) : n = 42 := by
|
||||
Hint "**Du** Wieder ein Widerspruch in den Annahmen?
|
||||
|
||||
**Robo** Ich sehe, du hast langsam den Dreh raus."
|
||||
contradiction
|
||||
|
||||
|
||||
|
||||
Conclusion
|
||||
"
|
||||
**Robo** Gut gemacht. Bei dieser Frage ist auch ein bisschen offensichtlicher,
|
||||
worin der Widerspruch besteht: Die Annahme `n ≠ 10` ist genau die Negation von `n = 10`.
|
||||
Man muss `≠` immer als `¬(· = ·)` lesen.
|
||||
"
|
||||
|
||||
NewTactic contradiction
|
||||
DisabledTactic tauto
|
||||
@@ -0,0 +1,70 @@
|
||||
import Adam.Metadata
|
||||
import Std.Tactic.RCases
|
||||
|
||||
set_option tactic.hygienic false
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 10
|
||||
|
||||
Title "Und"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Der nächste Formalosoph in der Reihe hat seine Frage bereìts mitgebracht.
|
||||
Er legt sie uns vor, setzt sich hin und häkelt.
|
||||
"
|
||||
Statement "" (A B : Prop) (hA : A) (hB : B) : A ∧ B := by
|
||||
Hint
|
||||
"
|
||||
**Du**: Also, wir haben zwei Annahmen: `{A}` gilt, und `{B}` gilt auch. Und beweisen sollen wir
|
||||
dass `{A} und {B}` gilt. Ich glaube, diese Formalospinner treiben mich noch zur Verzweiflung.
|
||||
Kann ich nicht wieder `trivial` sagen?
|
||||
|
||||
**Robo**: Nee, diesmal wird das nicht funktionieren.
|
||||
Du musst das Beweisziel einfach in zwei Teile zerlegen. Probier mal `constructor`.
|
||||
|
||||
**Du**: Du meinst, `destructor`??
|
||||
|
||||
**Robo**: Nein, `constructor`. Ich weiß das ist verwirrend,
|
||||
aber die nennen das hier so weil man die Aussage aus mehreren Teilen
|
||||
konstruieren kann.
|
||||
"
|
||||
constructor
|
||||
-- TODO: (BUG) Hier werden beide der folgenden Hints angezeigt.
|
||||
-- Das logiste Verhalten wäre, wenn jeder nur am richtigen Ort
|
||||
-- angezeigt würde.
|
||||
-- Ein cooles Feature wäre, wenn man nur diesen ersten Hint schreiben könnte
|
||||
-- und dieser dann automatisch auch beim zweiten Goal angezeigt wird, aber dann mit `B` statt `A`.
|
||||
Hint (hidden := true)
|
||||
"
|
||||
**Robo**: Schau mal, das ist Zauberpapier.
|
||||
Jetzt haben wir auf einmal zwei Beweisziele.
|
||||
Hier ist dast Ziel `{A}`.
|
||||
Ich glaube, Du weißt schon, wie man die jeweils erreicht.
|
||||
Die Ziele stehen ja jeweils in den *Annahmen*.
|
||||
"
|
||||
assumption
|
||||
Hint (hidden := true)
|
||||
"
|
||||
**Robo**: Schau mal, das ist Zauberpapier.
|
||||
Jetzt haben wir auf einmal zwei Beweisziele.
|
||||
Hier ist dast Ziel `{B}`.
|
||||
Ich glaube, Du weißt schon, wie man die jeweils erreicht.
|
||||
Die Ziele stehen ja jeweils in den *Annahmen*.
|
||||
"
|
||||
assumption
|
||||
|
||||
|
||||
Conclusion
|
||||
"
|
||||
**Robo** Super!
|
||||
|
||||
Ihm scheinen diese Fragen inzwischen Spaß zu machen.
|
||||
|
||||
**Robo** Meinst Du, dieser Hebel, an dem \"Editor mode\" steht, ist echt?
|
||||
Oder ist der nur gemalt? Probier mal!
|
||||
"
|
||||
|
||||
NewTactic constructor
|
||||
DisabledTactic tauto
|
||||
@@ -0,0 +1,44 @@
|
||||
import Adam.Metadata
|
||||
import Std.Tactic.RCases
|
||||
|
||||
set_option tactic.hygienic false
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 11
|
||||
|
||||
Title "Und"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Langsam wird die Schlange kürzer. Die nächste Formalosophin, ebenfalls häkelnd, hat folgendes Anliegen.
|
||||
"
|
||||
|
||||
Statement ""
|
||||
(A B C : Prop) (h : A ∧ (B ∧ C)) : B := by
|
||||
Hint "
|
||||
**Du** Jetzt müssen wir wohl die Annahme de-konstruieren.
|
||||
|
||||
**Robo** Ja, genau. Das geht am einfachsten mit `rcases {h} with ⟨h₁, h₂⟩`.
|
||||
|
||||
**Du** Moment, wie schreib ich *das* denn hier auf?
|
||||
|
||||
**Robo** Die bleiden Klammern schreibst Du als `\\<` und `\\>`, oder gleichzeitig als `\\<>`.
|
||||
Und h₁ schreibst Du einfach als `h\\1`. Aber Du kannst Dir auch einfach andere Namen
|
||||
für `h₁` und `h₂`, zum Beispiel `rcases {h} with ⟨hA, hBC⟩`
|
||||
"
|
||||
Branch
|
||||
rcases h with ⟨h₁, h₂⟩
|
||||
Hint "**Robo** Das sieht doch schon besser aus! Gleich nochmal!"
|
||||
rcases h with ⟨_, ⟨g , _⟩⟩
|
||||
Hint (hidden := true) "**Robo** Du hast einen Beweis dafür in den *Annahmen*."
|
||||
assumption
|
||||
|
||||
Conclusion
|
||||
"
|
||||
**Robo** Du hättest das übrigens auch direkt verschachtelt schreiben können:
|
||||
`rcases h with ⟨h₁, ⟨h₂ , h₃⟩⟩`.
|
||||
"
|
||||
|
||||
NewTactic rcases
|
||||
DisabledTactic tauto
|
||||
@@ -0,0 +1,42 @@
|
||||
import Adam.Metadata
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.LeftRight
|
||||
|
||||
--set_option tactic.hygienic false
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 12
|
||||
|
||||
Title "Oder"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Der nächste bitte …
|
||||
"
|
||||
|
||||
Statement
|
||||
""
|
||||
(A B : Prop) (hA : A) : A ∨ (¬ B) := by
|
||||
Hint "**Du** Muss ich jetzt wieder das Beweisziel de-konstruieren?
|
||||
|
||||
**Robo** Nein, viel einfacher. Wenn Du eine Oder-Aussage beweisen sollst, musst Du Dich
|
||||
einfach entscheiden, ob Du die linke oder rechte Seite beweisen willst.
|
||||
|
||||
**Du** Und wie erkläre ich meinem Formalosophen, welche Seite ich gern beweisen würde?
|
||||
Ich will natürlich `{A}` beweisen!
|
||||
|
||||
**Robo** Mit `left` bzw. `right`. Ist doch logisch, oder?"
|
||||
Branch
|
||||
right
|
||||
Hint "**Robo** Wusste gar nicht, dass Du eine Links-Rechts-Schwäche hast. Probier's nochmal."
|
||||
left
|
||||
assumption
|
||||
|
||||
Conclusion
|
||||
"
|
||||
Auch dieser Formalosoph zieht zufrieden von dannen.
|
||||
"
|
||||
|
||||
NewTactic left right assumption
|
||||
DisabledTactic tauto
|
||||
@@ -0,0 +1,112 @@
|
||||
import Adam.Metadata
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.LeftRight
|
||||
|
||||
set_option tactic.hygienic false
|
||||
|
||||
--set_option autoImplicit false
|
||||
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 13
|
||||
|
||||
Title "Oder"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Der nächste bitte …
|
||||
"
|
||||
|
||||
Statement ""
|
||||
(A B : Prop) (h : (A ∧ B) ∨ A) : A := by
|
||||
Hint "**Robo** Schau mal, wenn du mit dem Finger eine Annahme berührst, zeigt es dir,
|
||||
wie die Klammern gesetzt sind. Irre…
|
||||
|
||||
**Du** Ah ich sehe, also `({A} ∧ {B}) ∨ {A}`!
|
||||
|
||||
**Du** Ich glaube den ganzen Zircus hier langsam nicht mehr:
|
||||
Zuerst ein \"Und\" im Ziel, dann \"Und\" in der Annahme, dann \"Oder\" im Ziel und jetzt
|
||||
\"Oder\" in der Annahme, die haben sich doch abgesprochen!
|
||||
|
||||
**Robo** Lass ihnen doch ihren Spaß.
|
||||
Wir sind ja gleich hier fertig, und können zu einem interessanteren Planeten weiterfliegen.
|
||||
|
||||
**Du** Also, wieder `rcases …`?
|
||||
|
||||
**Robo** Ja, aber diesmal nicht `rcases {h} with ⟨h₁, h₂⟩`, sondern `rcases {h} with h | h`."
|
||||
rcases h with h | h
|
||||
Hint "**Robo**
|
||||
Jetzt musst Du Dein Ziel zweimal beweisen:
|
||||
Einmal unter Annahme der linken Seite `{A} ∨ {B}`,
|
||||
und einmal unter Annahme der rechten Seite `{A}`.
|
||||
Hier haben nehmen wir an, die linke Seite
|
||||
sei wahr."
|
||||
Hint (hidden := true) " **Robo** Wie man mit einem Und in den Annahmen umgeht,
|
||||
weißt Du doch schon:
|
||||
`rcases h with ⟨h₁, h₂⟩`. Zur Erinnerung: Für die Klammern schreibst Du `\\<>`."
|
||||
rcases h with ⟨h₁, h₂⟩
|
||||
Hint "**Robo** Jetzt musst Du Dein Ziel zweimal beweisen:
|
||||
Einmal unter Annahme der linken Seite `{A}`,
|
||||
und einmal unter Annahme der rechten Seite `{A} ∨ {B}`. Hier haben nehmen wir an, die linke Seite
|
||||
sei wahr."
|
||||
assumption
|
||||
assumption
|
||||
|
||||
Conclusion
|
||||
"**Du** Ok, das scheint ihn zufriedenzustellen. Nur noch eine Seele…
|
||||
Kannst Du mir vorher noch einmal kurz alles Leansch zusammenfassen,
|
||||
das Du mir bis hierher beigebracht hast?
|
||||
|
||||
Robo strahlt überglücklich. Noch *nie* warst Du so auf ihn angewiesen.
|
||||
|
||||
**Robo** Na klar, schau her!
|
||||
|
||||
## Notationen / Begriffe
|
||||
|
||||
| | Beschreibung |
|
||||
|:--------------|:-------------------------------------------------------------------------|
|
||||
| *Goal* | Was aktuell zu beweisen ist. |
|
||||
| *Annahme* | Objekte & Resultate, die man zur Verfügung hat. |
|
||||
| *Taktik* | Befehl im Beweis. Entspricht einem Beweisschritt. |
|
||||
| `ℕ` | Typ aller natürlichen Zahlen. |
|
||||
| `0, 1, 2, …` | Explizite natürliche Zahlen. |
|
||||
| `=` | Gleichheit. |
|
||||
| `≠` | Ungleichheit. Abkürzung für `¬(·=·)`. |
|
||||
| `Prop` | Typ aller logischen Aussagen. |
|
||||
| `True` | Die logische Aussage `(True : Prop)` ist bedingungslos wahr. |
|
||||
| `False` | Die logische Aussage `(False : Prop)` ist bedingungslos falsch. |
|
||||
| `¬` | Logische Negierung. |
|
||||
| `∧` | Logisch UND. |
|
||||
| `∨` | Logisch ODER. |
|
||||
| `(n : ℕ)` | Eine natürliche Zahl. |
|
||||
| `(A : Prop)` | Eine logische Aussage. |
|
||||
| `(ha : A)` | Ein Beweis, dass die logische Aussage `(A : Prop)` wahr ist. |
|
||||
| `(h : A ∧ B)` | Eine Annahme, die den Namen `h` bekommen hat. |
|
||||
| `⟨·,·⟩` | Schreibweise für Struktur mit mehreren Feldern (kommt später im Detail). |
|
||||
| `h.1, h.2, …` | Die einzelnen Felder der Stuktur. Auch `h.[Name des Feldes]` |
|
||||
|
||||
|
||||
## Taktiken
|
||||
|
||||
Die Worte, die Du aktiv gebrauchen musst, heißen zusammengefasst `Taktiken`. Hier sind alle Taktiken, die wir auf diesem Planeten gebraucht haben:
|
||||
|
||||
| | Taktik | Beispiel |
|
||||
|:---|:--------------------------|:--------------------------------------------------|
|
||||
| 1 | `rfl` | Beweist `A = A`. |
|
||||
| 2 | `assumption` | Sucht das Goal in den Annahmen. |
|
||||
| 3 | `contradiction` | Sucht einen Widerspruch. |
|
||||
| 4 | `trivial` | Kombiniert die obigen drei Taktiken (und mehr). |
|
||||
| 5 | `constructor` | Teilt ein UND im Goal auf. |
|
||||
| 6 | `left`/`right` | Beweist eine Seite eines ODER im Goal. |
|
||||
| 7ᵃ | `rcases h with ⟨h₁, h₂⟩` | Teilt ein UND in den Annahmen auf. |
|
||||
| 7ᵇ | `rcases h with h \\| h` | Teilt ein ODER in den Annahmen in zwei Fälle auf. |
|
||||
|
||||
**Du** Woher weißt Du das eigentlich alles?
|
||||
|
||||
**Robo** Keine Ahnung. War, glaube ich, vorinstalliert.
|
||||
"
|
||||
|
||||
|
||||
NewTactic assumption rcases
|
||||
DisabledTactic tauto
|
||||
@@ -0,0 +1,117 @@
|
||||
import Adam.Metadata
|
||||
import Std.Tactic.RCases
|
||||
import Mathlib.Tactic.LeftRight
|
||||
|
||||
set_option tactic.hygienic false
|
||||
|
||||
Game "Adam"
|
||||
World "Proposition"
|
||||
Level 14
|
||||
|
||||
Title "Zusammenfassung"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Der letzte Untertan tritt vor. Ihr Anliegen ist etwas komplizierter als die vorherigen.
|
||||
|
||||
**Robo** Wirf einfach alles drauf, was Du gelernt hast.
|
||||
Hier, ich bin sogar so nett und zeig Dir noch einmal die vier
|
||||
wichtigsten Taktiken für diese Situation an.
|
||||
|
||||
| (Übersicht) | Und (`∧`) | Oder (`∨`) |
|
||||
|-------------|:-------------------------|:------------------------|
|
||||
| Annahme | `rcases h with ⟨h₁, h₂⟩` | `rcases h with h \\| h` |
|
||||
| Goal | `constructor` | `left`/`right` |
|
||||
"
|
||||
|
||||
-- Note: The other direction would need arguing by cases.
|
||||
|
||||
Statement ""
|
||||
(A B C : Prop) (h : A ∨ (B ∧ C)) : (A ∨ B) ∧ (A ∨ C) := by
|
||||
Hint (hidden := true)
|
||||
"**Robo**: Ich würd zuerst die Annahme {h} mit `rcases {h}` aufteilen."
|
||||
Branch
|
||||
constructor
|
||||
· rcases h with h' | h'
|
||||
· left
|
||||
assumption
|
||||
· rcases h' with ⟨h₁, h₂⟩
|
||||
right
|
||||
assumption
|
||||
· rcases h with h' | h'
|
||||
· left
|
||||
assumption
|
||||
· rcases h' with ⟨h₁, h₂⟩
|
||||
right
|
||||
assumption
|
||||
rcases h
|
||||
Hint (hidden := true) "**Robo**: Jetzt kannst Du das `∧` im Goal mit `constructor` angehen."
|
||||
· constructor
|
||||
· left
|
||||
assumption
|
||||
· left
|
||||
assumption
|
||||
· Hint (hidden := true)
|
||||
"**Robo**: Hier würde ich die Annahme {h} nochmals mit `rcases` aufteilen."
|
||||
Branch
|
||||
constructor
|
||||
· Hint "**Robo**: Der Nachteil an der Reihenfolge ist, dass du jetzt in jedem Untergoal
|
||||
`rcases h` aufrufen musst."
|
||||
Branch
|
||||
right
|
||||
rcases h with ⟨h₁, h₂⟩
|
||||
assumption
|
||||
rcases h with ⟨h₁, h₂⟩
|
||||
right
|
||||
assumption
|
||||
· Branch
|
||||
right
|
||||
rcases h with ⟨h₁, h₂⟩
|
||||
assumption
|
||||
rcases h with ⟨h₁, h₂⟩
|
||||
right
|
||||
assumption
|
||||
rcases h with ⟨h₁, h₂⟩
|
||||
constructor
|
||||
· right
|
||||
assumption
|
||||
· right
|
||||
assumption
|
||||
|
||||
|
||||
-- HiddenHint (A : Prop) (B : Prop) (C : Prop) (h : B ∧ C) : (A ∨ B) ∧ (A ∨ C) =>
|
||||
-- "**Robo** Das `∧` in der Annahme kannst Du mit `rcases {h} with ⟨h₁, h₂⟩` zerlegen."
|
||||
|
||||
-- HiddenHint (A : Prop) (B : Prop) (C : Prop) : (A ∨ B) ∧ (A ∨ C) =>
|
||||
-- "**Robo** Das `∧` im Goal kannst Du mit `constructor` zerlegen."
|
||||
|
||||
-- HiddenHint (A : Prop) (B : Prop) (C : Prop) (h : A ∨ (B ∧ C)) : (A ∨ B) ∧ (A ∨ C) =>
|
||||
-- "**Robo** Das `∨` in der Annahme kannst Du mit `rcases h with h | h` zerlegen."
|
||||
|
||||
-- HiddenHint (A : Prop) (B : Prop) (C : Prop) (h : A ∨ (B ∧ C)) : (A ∨ B) =>
|
||||
-- "**Robo** Das `∨` in der Annahme kannst Du mit `rcases h with h | h` zerlegen."
|
||||
|
||||
-- HiddenHint (A : Prop) (B : Prop) (C : Prop) (h : A ∨ (B ∧ C)) : (A ∨ C) =>
|
||||
-- "**Robo** Das `∨` in der Annahme kannst Du mit `rcases h with h | h` zerlegen."
|
||||
|
||||
|
||||
-- HiddenHint (A : Prop) (B : Prop) (C : Prop) (h : B ∧ C) : (A ∨ B) =>
|
||||
-- "**Robo** Das `∧` in der Annahme kannst Du mit `rcases h with ⟨h₁, h₂⟩` zerlegen."
|
||||
|
||||
-- HiddenHint (A : Prop) (B : Prop) (C : Prop) (h : B ∧ C) : (A ∨ C) =>
|
||||
-- "**Robo** Das `∧` in der Annahme kannst Du mit `rcases {h} with ⟨h₁, h₂⟩` zerlegen."
|
||||
|
||||
-- -- TODO: Hint nur Anhand der Annahmen?
|
||||
|
||||
-- HiddenHint (A : Prop) (B : Prop) : A ∨ B =>
|
||||
-- "**Robo** `left` oder `right`?"
|
||||
|
||||
Conclusion
|
||||
"
|
||||
**Robo** Bravo! Jetzt aber nichts wie weg hier, bevor sich eine neue Schlange bildet!
|
||||
|
||||
Königin *Logisinde* ist in der Zwischenzeit eingeschlafen, und ihr stehlt euch heimlich davon.
|
||||
"
|
||||
|
||||
NewTactic left right assumption constructor rcases rfl contradiction trivial
|
||||
DisabledTactic tauto
|
||||
Reference in New Issue
Block a user