This commit is contained in:
Jon
2022-12-18 02:28:50 +01:00
parent ac29c83e79
commit 44b8edbec3
32 changed files with 332 additions and 121 deletions
@@ -22,8 +22,13 @@ Der einfachste Widerspruch ist wenn man einen Beweis von `False` hat:
"
Statement
"Ein Widerspruch impliziert alles."
"Sei $A$ eine Aussage und angenommen man hat einen Beweis für `False`.
Zeige, dass daraus $A$ folgt."
(A : Prop) (h : False) : A := by
contradiction
Message (A : Prop) (h : False) : A =>
"Wenn man einen Beweis von `False` hat, kann man mit `contradiction` das Goal beweisen,
unabhängig davon, was das Goal ist."
Tactics contradiction
@@ -16,9 +16,10 @@ Introduction
also `(h : A)` und `(g : ¬ A)`. (`\\not`)
"
Statement
"Ein Widerspruch impliziert alles."
(n : ℕ) (h : even n) (g : ¬ (even n)) : n = 128 := by
Statement absurd
"Sei $n$ eine natürliche Zahl die sowohl gerade wie auch nicht gerade ist.
Zeige, dass daraus $n = 42$ folgt. (oder, tatsächlich $n = x$ für jedes beliebige $x$)"
(n : ℕ) (h : even n) (g : ¬ (even n)) : n = 42 := by
contradiction
Conclusion
@@ -14,28 +14,24 @@ Level 3
Title "Ad absurdum"
Introduction
"
Aber, die Aussagen müssen wirklich exakte Gegenteile sein.
"Aber, die Aussagen müssen wirklich exakte Gegenteile sein.
Hier musst du zuerst eines der Lemmas `not_odd : ¬ odd n ↔ even n` oder
`not_even : ¬ even n ↔ odd n` benützen, um einer der Terme umzuschreiben.
"
Hier musst du zuerst eines der Lemmas `(not_odd : ¬ odd n ↔ even n)` oder
`(not_even : ¬ even n ↔ odd n)` benützen, um einer der Terme umzuschreiben."
Statement
"Ein Widerspruch impliziert alles."
(n : ℕ) (h₁ : even n) (h₂ : odd n) : n = 128 := by
rw [← not_even] at h₂
"Sei $n$ eine natürliche Zahl die sowohl gerade wie auch ungerade ist.
Zeige, dass daraus $n = 42$ folgt. (oder, tatsächlich $n = x$ für jedes beliebige $x$)."
(n : ℕ) (h_even : even n) (h_odd : odd n) : n = 42 := by
rw [← not_even] at h_odd
contradiction
Message (n : ℕ) (h₁ : even n) (h₂ : odd n) : n = 128 =>
"Schreibe zuerst eine der Aussagen mit `rw [←not_even] at h₂` um, damit diese genaue
Gegenteile sind."
Message (n : ℕ) (h_even : even n) (h_odd : odd n) : n = 42 =>
"Schreibe zuerst eine der Aussagen mit `rw [←not_even] at h_odd` um, damit diese genaue
Gegenteile werden."
Conclusion
"
Detail: `¬ A` ist übrigens als `A → false` implementiert, was aussagt, dass
\"falls `A` wahr ist, impliziert das `false` und damit einen Widerspruch\".
"
-- TODO: Oder doch ganz entfernen?
Conclusion ""
Tactics contradiction
Tactics contradiction rw
Lemmas even odd not_even not_odd
@@ -11,21 +11,25 @@ Title "Ad absurdum"
Introduction
"
Im weiteren kann man auch Widersprüche erhalten, wenn man Annahmen der Form
`A = B` hat, wo Lean weiss, dass `A und `B` unterschiedlich sind, z.B. `0 = 1` in `ℕ`
oder auch Annahmen der Form `A ≠ A` (`\\ne`).
`A ≠ A` (`\\ne`) hat, oder Aussagen der Form
`A = B` hat, wo Lean weiss, dass `A` und `B` unterschiedlich sind, wie zum Beispiel `0 = 1` in `ℕ`.
*Bemerkung:* `X ≠ Y` muss man als `¬ (X = Y)` lesen, und auch so behandeln.
"
Statement
"Ein Widerspruch impliziert alles."
"Angenommen man hat $a = b = c$ und $a \\ne c$ natürliche Zahlen $a, b, c$.
Zeige, dass man daraus jede beliebige Aussage beweisen kann."
(A : Prop) (a b c : ℕ) (g₁ : a = b) (g₂ : b = c) (h : a ≠ c) : A := by
rw [g₁] at h
contradiction
Message (A : Prop) (a : ℕ) (b : ℕ) (c : ℕ) (g₁ : a = b) (g₂ : b = c) (h : a ≠ c) : A =>
"Recap: `rw [...] at h` hilft dir hier."
"Benütze `rw [...] at ...` um zwei Aussagen zu bekommen die genau das Gegenteil
aussagen."
Message (A : Prop) (a : ℕ) (b : ℕ) (c : ℕ) (g₁ : a = b) (g₂ : b = c) (h : b ≠ c) : A =>
"`b ≠ c` muss man als `¬ (b = c)` lesen. Deshalb findet `contradiction` hier direkt
Hint (A : Prop) (a : ℕ) (b : ℕ) (g₁ : a = b) (h : a ≠ b) : A =>
"`X ≠ Y` muss man als `¬ (X = Y)` lesen. Deshalb findet `contradiction` hier direkt
einen Widerspruch."
Tactics contradiction
@@ -11,14 +11,23 @@ Introduction
"
Wenn man ein Nicht (`¬`) im Goal hat, will man meistens einen Widerspruch starten,
wie im nächsten Level dann gezeigt wird. Manchmal aber hat man Terme der Form
`¬ (¬ A)`, in welchem Fall das Lemma `not_not` nützlich ist.
`¬ (¬ A)`, in welchem Fall das Lemma `not_not` nützlich ist, welches du mit
`rw` oder `apply` benützen kannst.
"
Statement
""
"Zeige, dass $\\neg(\\neg A)$ äquivalent zu $A$ ist."
(A : Prop) : ¬ (¬ A) ↔ A := by
rw [not_not]
Tactics rw
Message (A : Prop) : ¬ (¬ A) ↔ A => "Da `not_not` ein Lemma der Form `X ↔ Y` ist,
kannst du wahlweise `rw [not_not]` oder `apply not_not` benützen.
- `rw` ersetzt `¬ (¬ A)` mit `A` und schliesst dann `A ↔ A` mit `rfl`.
- `apply` hingegen funktioniert hier nur, weil das gesamte Goal
genau mit der Aussage des Lemmas übereinstimmt.
"
Tactics rw apply
Lemmas not_not
@@ -14,35 +14,68 @@ Title "Widerspruch"
Introduction
"
Zwei wichtige Beweisformen sind per Widerspruch und per Kontraposition. Hier
schauen wir beide an und auch den Unterschied.
Um einen Beweis per Widerspruch zu führen, kann man mit `by_contra h` annehmen,
dass das Gegenteil des Goals wahr sei, und dann einen Widerspruch erzeugen.
**Bemerkung:** Besonders beim Beweis durch Widerspruch ist es hilfreich, wenn man
Zwischenresultate erstellen kann.
`suffices h₁ : ¬(odd (n ^ 2))` erstellt zwei neue Goals:
1) Ein Beweis, wieso es genügt `¬(odd (n ^ 2))` zu zeigen (\"weil das einen Widerspruch zu
`h` bewirkt\").
2) Einen Beweis des Zwischenresultats `suffices h₁ : ¬(odd (n ^ 2))`
Alternativ macht `have h₁ : ¬(odd (n ^ 2))` genau das gleiche, vertauscht aber die
Beweise (1) und (2), so dass man zuerst `h₁` beweist, und dann den eigentlichen Beweis
fortsetzt.
"
Statement
"Ist n² ungerade, so ist auch n ungerade. Beweise durch Widerspruch."
(n : ℕ) (h : odd (n ^ 2)) : odd n := by
by_contra g
suffices d : ¬ odd (n ^ 2) -- TODO: I don't like this
contradiction
rw [not_odd] at g
suffices ¬ odd (n ^ 2) by contradiction -- TODO: I don't like this
rw [not_odd]
apply even_square
assumption
Message : false =>
"Es gibt mehrere Möglichkeiten, wie man nach einem `by_contra` weitergeht.
Message (n : ℕ) (h : odd (n^2)) : odd n =>
"Schreibe `by_contra h₁` um einen Beweis durch Widerspruch zu starten."
Hier wollen wir einen Widerspruch zu `h` machen. Wir machen das mit
`suffices ¬ odd (n ^ 2) by contradiction`, worauf man dann nur noch `¬ odd (n ^ 2)`
zeigen muss."
Message (n : ℕ) (g : ¬ odd n) (h : odd (n^2)) : False =>
"Nun *genügt es zu zeigen, dass* `¬odd (n ^ 2)` wahr ist,
denn dann erhalten wir einen Widerspruch zu `h`.
Hint (n : ℕ) : ¬ (odd (n ^ 2)) =>
"Das Lemma `not_odd` ist hilfreich."
Benütze dafür `suffices h₂ : ¬odd (n ^ 2)`.
"
Message (n : ℕ) (g : ¬ odd (n^2)) (h : odd (n^2)) : False =>
"Hier musst du rechtfertigen, wieso das genügt. In unserem Fall, weil
dadurch einen Widerspruch entsteht."
Hint (n : ℕ) (g : ¬ odd (n^2)) (h : odd (n^2)) : False =>
"Also `contradiction`..."
Message (n : ℕ) (g : ¬ odd n) (h : odd (n^2)) : ¬ odd (n^2) =>
"Das Zwischenresultat `¬odd (n^2)` muss auch bewiesen werden.
Hier ist wieder das Lemma `not_odd` hilfreich."
Hint (n : ℕ) (g : ¬ odd n) (h : odd (n^2)) : even (n^2) =>
"Mit `rw [not_odd] at *` kannst du im Goal und allen Annahmen gleichzeitig umschreiben."
Message (n: ℕ) (h : odd (n ^ 2)) (g : even n) : even (n ^ 2) =>
"Das haben wir schon gezeigt. Mit `apply even_square` kannst du das Lemma anwenden."
"Diese Aussage hast du bereits als Lemma bewiesen."
Tactics contradiction by_contra rw apply assumption -- TODO: suffices
Hint (n: ℕ) (h : odd (n ^ 2)) (g : even n) : even (n ^ 2) =>
"Probiers mit `apply ...`"
Tactics contradiction by_contra rw apply assumption -- TODO: suffices, have
Lemmas odd even not_odd not_even even_square
@@ -29,5 +29,22 @@ Statement
rw [not_odd]
apply even_square
Message (n : ℕ) (h : odd (n ^ 2)) : odd n =>
"`intro` wär generell ein guter Ansatz! Aber hier wollen wir `contrapose` benützen, was eine
Implikation benötigt, deshalb ist `intro` hier der falsche Weg!"
Message (n : ℕ) : odd (n ^ 2) → odd n =>
"Mit `contrapose` kann man die Implikation zu
`¬ (even n) → ¬ (even n^2)` umkehren."
Hint (n : ℕ) : ¬odd n → ¬odd (n ^ 2) => "Du kennst bereits ein Lemma um `¬ odd ...` mit `rw`
umzuschreiben"
Message (n : ℕ) : even n → ¬odd (n ^ 2) => "rw [not_odd] muss hier zweimal angewendet werden,
da rw das erste Mal `not_odd n` gebraucht hat und das zweite Mal `not_odd (n^2)` benützt."
Message (n : ℕ) : even n → even (n ^ 2) => "Diese Aussage hast du bereits als Lemma bewiesen."
Tactics contrapose rw apply
Lemmas even odd not_even not_odd even_square
@@ -13,20 +13,25 @@ Level 8
Title "Kontraposition"
Introduction
"
Lean Trick: Wenn das Goal nicht bereits eine Implikation ist, sondern man eine Annahme `h` hat, die
"**Lean Trick:** Wenn das Goal nicht bereits eine Implikation ist, sondern man eine Annahme `h` hat, die
Man gerne für die Kontraposition benützen würde, kann man mit `revert h` diese als
Implikationsannahme ins Goal schreiben.
"
Statement
"Ist n² ungerade, so ist auch n ungerade. Beweise durch Kontraposition."
(n : ℕ) (h : odd (n ^ 2)): odd n := by
(n : ℕ) (h : odd (n ^ 2)) : odd n := by
revert h
contrapose
rw [not_odd]
rw [not_odd]
apply even_square
Hint (n : ℕ) (h : odd (n ^ 2)) : odd n =>
"Benutze `revert h` um das Goal in eine Implikation umzuschreiben."
Message (n : ℕ) : odd (n ^ 2) → odd n =>
"Jetzt ist es genau das gleiche wie bei der letzten Aufgabe."
Tactics contrapose rw apply revert
Lemmas even odd not_even not_odd even_square
@@ -14,23 +14,53 @@ Introduction
"
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.)
"
Statement
"Es existiert keine natürliche Zahl, die grösser als alle anderen.":
"Es existiert keine natürliche Zahl $n$, sodass $n + k$ immer ungerade ist.":
¬ ∃ (n : ℕ), ∀ (k : ℕ) , odd (n + k) := by
push_neg
intro n
use 3*n + 6
use n
rw [not_odd]
unfold even
use 2*n + 3
use n
ring
Message (n : ℕ) : (Exists fun k ↦ ¬odd (n + k)) =>
"An dieser Stelle musst du nun ein `k` angeben, sodass `n + k` gerade ist... Benutz `use ...`
Message : ¬ ∃ (n : ℕ), ∀ (k : ℕ) , odd (n + k) =>
"`push_neg` schiebt die Negierung an den Quantoren vorbei."
Message (n : ℕ) : (∃ k, ¬odd (n + k)) =>
"An dieser Stelle musst du nun ein `k` angeben, sodass `n + k` gerade ist... Benutze `use`
mit der richtigen Zahl."
Hint (n : ℕ) : ¬odd (n + n) =>
"Du kennst ein Lemma um mit `¬odd` umzugehen."
-- Hint (n : ℕ) (k : ℕ) : ¬odd (n + k) =>
-- "Du kennst ein Lemma um mit `¬odd` umzugehen."
Hint (n : ℕ) : even (n + n) =>
"`unfold even` hilft, anzuschauen, was hinter `even` steckt.
Danach musst du wieder mit `use r` ein `(r : ℕ)` angeben, dass du benützen möchtest."
-- Hint (n : ℕ) (k : ℕ) : even (n + k) =>
-- "`unfold even` hilft hier weiter."
Message (n : ℕ) : n + n = 2 * n => "Recap: `ring` löst Gleichungen in `ℕ`."
Conclusion ""
Tactics push_neg intro use rw unfold ring
Lemmas even odd not_even not_odd not_exists not_forall