Modified starter level.
parent
b02d55de34
commit
1eb0ac63e3
@ -1,90 +0,0 @@
|
||||
import TestGame.Metadata
|
||||
import Std.Tactic.RCases
|
||||
|
||||
set_option tactic.hygienic false
|
||||
|
||||
Game "TestGame"
|
||||
World "Logic"
|
||||
Level 14
|
||||
|
||||
Title "Und"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Das logische UND `A ∧ B` (`\\and`) funktioniert sehr ähnlich zum Iff (`↔`).
|
||||
Grund dafür ist, dass `A ∧ B` auch eine Struktur aus zwei Teilen ist, nämlich
|
||||
der linken und rechten Seite.
|
||||
|
||||
Man can also genau gleich `constructor` und `rcases` anwenden, ebenso kann man
|
||||
`.1` und `.2` für die Einzelteile brauchen, diese heissen lediglich
|
||||
`h.left` und `h.right` anstatt `.mp` und `.mpr`.
|
||||
"
|
||||
|
||||
Statement
|
||||
"Zeige $(A \\land (A \\Rightarrow B)) \\iff (A \\land B)$."
|
||||
(A B : Prop) : (A ∧ (A → B)) ↔ (A ∧ B) := by
|
||||
constructor
|
||||
intro h
|
||||
rcases h with ⟨h₁, h₂⟩
|
||||
constructor
|
||||
assumption
|
||||
apply h₂
|
||||
assumption
|
||||
intro h
|
||||
rcases h with ⟨h₁, h₂⟩
|
||||
constructor
|
||||
assumption
|
||||
intro
|
||||
assumption
|
||||
|
||||
Message (A : Prop) (B : Prop) : A ∧ (A → B) ↔ A ∧ B =>
|
||||
"`↔` oder `∧` im Goal kann man mit `constructor` zerlegen."
|
||||
|
||||
Message (A : Prop) (B : Prop) : A ∧ (A → B) → A ∧ B =>
|
||||
"Hier würdest du mit `intro` die Implikation angehen.
|
||||
|
||||
(Experten können mit `intro ⟨h₁, h₂⟩` im gleichen Schritt noch ein `rcases` auf
|
||||
das UND in der Implikationsannahme)"
|
||||
|
||||
-- if they don't use `intro ⟨_, _⟩`.
|
||||
Message (A : Prop) (B : Prop) (h : A ∧ (A → B)) : A ∧ B =>
|
||||
"Jetzt erst mal noch schnell die Annahme `A ∧ (A → B)` mit `rcases` aufteilen."
|
||||
|
||||
Hint (A : Prop) (B : Prop) (hA : A) (h : A → B) : B =>
|
||||
"Wie wär's mit `apply`? Hast du ne Implikation, die anwendbar ist?"
|
||||
|
||||
-- Rückrichtung
|
||||
Message (A : Prop) (B : Prop) : A ∧ B → A ∧ (A → B) =>
|
||||
"Das Goal ist ne Implikation $\\ldots \\Rightarrow \\ldots$
|
||||
Da hilft `intro`.
|
||||
|
||||
(auch hier kann man wieder mit `intro ⟨ha, hb⟩` gleich noch die Premisse zerlegen.)"
|
||||
|
||||
|
||||
|
||||
|
||||
-- if they don't use `intro ⟨_, _⟩`.
|
||||
Message (A : Prop) (B : Prop) (h : A ∧ B) : A ∧ (A → B) =>
|
||||
"Jetzt erst mal noch schnell die Annahme `A ∧ B` mit `rcases` zerlegen."
|
||||
|
||||
Message (A : Prop) (B : Prop) (hA : A) (h : A → B) : A ∧ B =>
|
||||
"Wieder in Einzelteile zerlegen..."
|
||||
|
||||
Message (A : Prop) (B : Prop) (ha : A) (hb : B) : A ∧ (A → B) =>
|
||||
"Immer das gleiche ... noch mehr zerlegen."
|
||||
|
||||
-- Message (A : Prop) (B : Prop) (h₁: A) (h₂: B) : A → B =>
|
||||
-- "Das ist jetzt vielleicht etwas verwirrend: Wir wollen die Implikation `A → B` zeigen,
|
||||
-- wissen aber, dass `B` immer wahr ist (habe eine Annahme der Form `(hB : B)`).
|
||||
|
||||
-- Mit intro können wir einfach nochmal annehmen, dass `A` wahr ist. Es stört uns nicht,
|
||||
-- dass wir das schon wissen und auch gar nicht brauchen. Damit müssen wir nur noch zeigen,
|
||||
-- dass `B` wahr ist."
|
||||
|
||||
|
||||
|
||||
-- TODO
|
||||
|
||||
|
||||
Tactics apply rcases
|
||||
Tactics assumption
|
@ -0,0 +1,14 @@
|
||||
import TestGame.Levels.Proposition.L01_Rfl
|
||||
import TestGame.Levels.Proposition.L02_Assumption
|
||||
import TestGame.Levels.Proposition.L03_Assumption
|
||||
import TestGame.Levels.Proposition.L04_True
|
||||
import TestGame.Levels.Proposition.L05_Not
|
||||
import TestGame.Levels.Proposition.L06_False
|
||||
import TestGame.Levels.Proposition.L07_ContraNotEq
|
||||
import TestGame.Levels.Proposition.L08_Contra
|
||||
import TestGame.Levels.Proposition.L09_And
|
||||
import TestGame.Levels.Proposition.L10_And
|
||||
import TestGame.Levels.Proposition.L11_Or
|
||||
import TestGame.Levels.Proposition.L12_Or
|
||||
import TestGame.Levels.Proposition.L13_Or
|
||||
import TestGame.Levels.Proposition.L14_Summary
|
@ -0,0 +1,34 @@
|
||||
import TestGame.Metadata
|
||||
|
||||
Game "TestGame"
|
||||
World "Proposition"
|
||||
Level 4
|
||||
|
||||
Title "True/False"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Unter den logischen Aussagen gibt es zwei spezielle Aussagen:
|
||||
|
||||
- `True` ist eine Aussage, die immer und bedingungslos wahr ist.
|
||||
- `False` ist eine Aussage, die nie wahr ist.
|
||||
|
||||
Die Aussage `True` werden wir kaum brauchen, die Aussage `False` ist jedoch wichtig, sie
|
||||
repräsentiert einen Widerspruch. Mehr dazu in den nächsten Levels.
|
||||
|
||||
**Beachte**, dass beide gross geschrieben werden. In Lean gibt es auf das klein geschriebene
|
||||
`true` und `false`, diese sind aber etwas anderes (Typ `Bool` und nicht `Prop`)
|
||||
und werden erst mal nicht gebraucht.
|
||||
|
||||
Wir können `True` aus dem nichts mit der Taktik `trivial` beweisen.
|
||||
|
||||
*Bemerkung: Was die Taktik `trivial` kann und nicht kann bleibt in diesem Spiel ein bisschen eine Blackbox,
|
||||
aber manchmal ist sie nützlich.*
|
||||
"
|
||||
|
||||
Statement "" : True := by
|
||||
trivial
|
||||
|
||||
Conclusion ""
|
||||
|
||||
Tactics trivial
|
@ -0,0 +1,22 @@
|
||||
import TestGame.Metadata
|
||||
|
||||
Game "TestGame"
|
||||
World "Proposition"
|
||||
Level 5
|
||||
|
||||
Title "Not"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Wenn eine Aussage `(A : Prop)` wahr oder falsch ist, dann ist die Umkehrung \"nicht $A$\",
|
||||
geschrieben `¬A` (`\\not`), gegenteilig falsch oder wahr.
|
||||
|
||||
Da die Aussage `False` nie wahr ist, ist die Aussage `¬False` immer wahr, genau wie `True`.
|
||||
"
|
||||
|
||||
Statement "Zeige dass die Aussage `¬False` immer wahr ist." : ¬False := by
|
||||
trivial
|
||||
|
||||
Conclusion ""
|
||||
|
||||
Tactics trivial
|
@ -0,0 +1,105 @@
|
||||
import TestGame.Metadata
|
||||
import Std.Tactic.RCases
|
||||
|
||||
set_option tactic.hygienic false
|
||||
|
||||
Game "TestGame"
|
||||
World "Proposition"
|
||||
Level 10
|
||||
|
||||
Title "Und"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Hat man ein UND `(h : A ∧ B)` in den Annahmen, möchte man normalerweise die einzelnen Felder
|
||||
(linke/rechte Seite) einzeln verwenden. Dazu hat man zwei Möglichkeiten:
|
||||
|
||||
1. Mit `h.left` und `h.right` (oder `h.1` und `h.2`) kann man die Felder direkt auswählen.
|
||||
2. Mit `rcases h with ⟨h₁, h₂⟩` kann man die Struktur `h` zerlegen und man erhält zwei
|
||||
separate Annahmen `(h₁ : A)` und `(h₂ : B)`
|
||||
|
||||
Die Klammern `⟨·,·⟩` sind `\\<` und `\\>` oder `\\<>` als Paar.
|
||||
"
|
||||
|
||||
Statement "Benutze `rcases` um das UND in `(h : A ∧ (B ∧ C))` zu zerlegen und beweise, dass $B$ wahr ist."
|
||||
(A B C : Prop) (h : A ∧ (B ∧ C)) : B := by
|
||||
rcases h with ⟨_, ⟨g , _⟩⟩
|
||||
assumption
|
||||
|
||||
Message (A : Prop) (B : Prop) (C : Prop) (h : A ∧ (B ∧ C)) : B =>
|
||||
"Du kannst mit `rcases` auch verschachtelt mehrere Strukturen in einem Schritt zerlegen:
|
||||
`rcases h with ⟨h₁, ⟨h₂ , h₃⟩⟩`."
|
||||
|
||||
Hint (A : Prop) (hA : A) : A =>
|
||||
"Du hast einen Beweis dafür in den *Annahmen*."
|
||||
|
||||
Tactics constructor assumption
|
||||
|
||||
-- Statement
|
||||
-- "Zeige $(A \\land (A \\Rightarrow B)) \\iff (A \\land B)$."
|
||||
-- (A B : Prop) : (A ∧ (A → B)) ↔ (A ∧ B) := by
|
||||
-- constructor
|
||||
-- intro h
|
||||
-- rcases h with ⟨h₁, h₂⟩
|
||||
-- constructor
|
||||
-- assumption
|
||||
-- apply h₂
|
||||
-- assumption
|
||||
-- intro h
|
||||
-- rcases h with ⟨h₁, h₂⟩
|
||||
-- constructor
|
||||
-- assumption
|
||||
-- intro
|
||||
-- assumption
|
||||
|
||||
-- Message (A : Prop) (B : Prop) : A ∧ (A → B) ↔ A ∧ B =>
|
||||
-- "`↔` oder `∧` im Goal kann man mit `constructor` zerlegen."
|
||||
|
||||
-- Message (A : Prop) (B : Prop) : A ∧ (A → B) → A ∧ B =>
|
||||
-- "Hier würdest du mit `intro` die Implikation angehen.
|
||||
|
||||
-- (Experten können mit `intro ⟨h₁, h₂⟩` im gleichen Schritt noch ein `rcases` auf
|
||||
-- das UND in der Implikationsannahme)"
|
||||
|
||||
-- -- if they don't use `intro ⟨_, _⟩`.
|
||||
-- Message (A : Prop) (B : Prop) (h : A ∧ (A → B)) : A ∧ B =>
|
||||
-- "Jetzt erst mal noch schnell die Annahme `A ∧ (A → B)` mit `rcases` aufteilen."
|
||||
|
||||
-- Hint (A : Prop) (B : Prop) (hA : A) (h : A → B) : B =>
|
||||
-- "Wie wär's mit `apply`? Hast du ne Implikation, die anwendbar ist?"
|
||||
|
||||
-- -- Rückrichtung
|
||||
-- Message (A : Prop) (B : Prop) : A ∧ B → A ∧ (A → B) =>
|
||||
-- "Das Goal ist ne Implikation $\\ldots \\Rightarrow \\ldots$
|
||||
-- Da hilft `intro`.
|
||||
|
||||
-- (auch hier kann man wieder mit `intro ⟨ha, hb⟩` gleich noch die Premisse zerlegen.)"
|
||||
|
||||
|
||||
|
||||
|
||||
-- -- if they don't use `intro ⟨_, _⟩`.
|
||||
-- Message (A : Prop) (B : Prop) (h : A ∧ B) : A ∧ (A → B) =>
|
||||
-- "Jetzt erst mal noch schnell die Annahme `A ∧ B` mit `rcases` zerlegen."
|
||||
|
||||
-- Message (A : Prop) (B : Prop) (hA : A) (h : A → B) : A ∧ B =>
|
||||
-- "Wieder in Einzelteile zerlegen..."
|
||||
|
||||
-- Message (A : Prop) (B : Prop) (ha : A) (hb : B) : A ∧ (A → B) =>
|
||||
-- "Immer das gleiche ... noch mehr zerlegen."
|
||||
|
||||
-- -- Message (A : Prop) (B : Prop) (h₁: A) (h₂: B) : A → B =>
|
||||
-- -- "Das ist jetzt vielleicht etwas verwirrend: Wir wollen die Implikation `A → B` zeigen,
|
||||
-- -- wissen aber, dass `B` immer wahr ist (habe eine Annahme der Form `(hB : B)`).
|
||||
|
||||
-- -- Mit intro können wir einfach nochmal annehmen, dass `A` wahr ist. Es stört uns nicht,
|
||||
-- -- dass wir das schon wissen und auch gar nicht brauchen. Damit müssen wir nur noch zeigen,
|
||||
-- -- dass `B` wahr ist."
|
||||
|
||||
|
||||
|
||||
-- -- TODO
|
||||
|
||||
|
||||
-- Tactics apply rcases
|
||||
-- Tactics assumption
|
Loading…
Reference in New Issue