bump mathlib and use Even/Odd.

pull/43/head
Jon Eugster 3 years ago
parent 6e0469d3bf
commit d2be90a8a0

@ -4,6 +4,7 @@ import TestGame.Levels.Proposition
import TestGame.Levels.Implication import TestGame.Levels.Implication
import TestGame.Levels.Predicate import TestGame.Levels.Predicate
import TestGame.Levels.Proving import TestGame.Levels.Proving
import TestGame.Levels.Prime
import TestGame.Levels.Naturals.L31_Sum import TestGame.Levels.Naturals.L31_Sum
@ -63,4 +64,6 @@ Conclusion
Path Proposition → Implication → Predicate → Proving Path Proposition → Implication → Predicate → Proving
Path Predicate → Prime
Path Predicate → Nat2 Path Predicate → Nat2

@ -37,13 +37,6 @@ LemmaDoc imp_iff_not_or as imp_iff_not_or in "Logic"
`(A B : Prop)` `(A B : Prop)`
" "
LemmaDoc zero_add as zero_add in "Addition" LemmaDoc zero_add as zero_add in "Addition"
"This lemma says `∀ a : , 0 + a = a`." "This lemma says `∀ a : , 0 + a = a`."
@ -62,13 +55,13 @@ LemmaDoc not_forall as not_forall in "Logic"
LemmaDoc not_exists as not_exists in "Logic" LemmaDoc not_exists as not_exists in "Logic"
"`∀ (A : Prop), ¬(∃ x, A) ↔ ∀x, (¬A)`." "`∀ (A : Prop), ¬(∃ x, A) ↔ ∀x, (¬A)`."
LemmaDoc even as even in "Nat" LemmaDoc Even as Even in "Nat"
" "
`even n` ist definiert als `∃ r, a = 2 * r`. `even n` ist definiert als `∃ r, a = 2 * r`.
Die Definition kann man mit `unfold even at *` einsetzen. Die Definition kann man mit `unfold even at *` einsetzen.
" "
LemmaDoc odd as odd in "Nat" LemmaDoc Odd as Odd in "Nat"
" "
`odd n` ist definiert als `∃ r, a = 2 * r + 1`. `odd n` ist definiert als `∃ r, a = 2 * r + 1`.
Die Definition kann man mit `unfold odd at *` einsetzen. Die Definition kann man mit `unfold odd at *` einsetzen.
@ -85,7 +78,7 @@ LemmaDoc even_square as even_square in "Nat"
LemmaSet natural : "Natürliche Zahlen" := LemmaSet natural : "Natürliche Zahlen" :=
even odd not_odd not_even Even Odd not_odd not_even
LemmaSet logic : "Logik" := LemmaSet logic : "Logik" :=
not_not not_forall not_exists not_not not_forall not_exists

@ -4,7 +4,7 @@ import Mathlib.Tactic.Contrapose
import Mathlib.Tactic.Use import Mathlib.Tactic.Use
import Mathlib.Tactic.Ring import Mathlib.Tactic.Ring
import TestGame.ToBePorted import Mathlib.Algebra.Parity
Game "TestGame" Game "TestGame"
World "Predicate" World "Predicate"
@ -16,17 +16,17 @@ Introduction
" "
Gerade/ungerade werden in Lean wie folgt definiert: Gerade/ungerade werden in Lean wie folgt definiert:
``` ```
def even (n : ) : Prop := ∃ r, n = 2 * r def Even (n : ) : Prop := ∃ r, n = r + r
def odd (n : ) : Prop := ∃ r, n = 2 * r + 1 def Odd (n : ) : Prop := ∃ r, n = r + r + 1
``` ```
Also dadurch, dass ein `(r : )` existiert sodass `n = 2 * r (+1)`. Also dadurch, dass ein `(r : )` existiert sodass `n = r + r (+1)`.
Beachte das Komma `,` welches die Variablen des `∃` (`\\exists`) von der Aussage trennen. Beachte das Komma `,` welches die Variablen des `∃` (`\\exists`) von der Aussage trennen.
Hierzu gibt es 3 wichtige Taktiken: Hierzu gibt es 3 wichtige Taktiken:
1) Definitionen wie `even` kann man mit `unfold even at *` im Infoview einsetzen. 1) Definitionen wie `Even` kann man mit `unfold even at *` im Infoview einsetzen.
Das ändert Lean-intern nichts und ist nur für den Benutzer. Man kann auch einen Das ändert Lean-intern nichts und ist nur für den Benutzer. Man kann auch einen
Term `(h : even x)` einfach so behandeln als wäre es ein Term `(h : ∃ r, x = 2 * r)`. Term `(h : Even x)` einfach so behandeln als wäre es ein Term `(h : ∃ r, x = 2 * r)`.
2) Bei einer Annahme `(h : ∃ r, ...)` kann man mit `rcases h with ⟨y, hy⟩` ein solches `y` 2) Bei einer Annahme `(h : ∃ r, ...)` kann man mit `rcases h with ⟨y, hy⟩` ein solches `y`
Auswählen, dass die Annahme `h` erfüllt. Auswählen, dass die Annahme `h` erfüllt.
3) Bei einem `∃` im Goal muss man ein Element `y` angeben, welches diese Aussage erfüllen 3) Bei einem `∃` im Goal muss man ein Element `y` angeben, welches diese Aussage erfüllen
@ -35,14 +35,14 @@ Hierzu gibt es 3 wichtige Taktiken:
Statement even_square Statement even_square
"Wenn $n$ gerade ist, dann ist $n^2$ gerade." "Wenn $n$ gerade ist, dann ist $n^2$ gerade."
(n : ) (h : even n) : even (n ^ 2) := by (n : ) (h : Even n) : Even (n ^ 2) := by
unfold even at * unfold Even at *
rcases h with ⟨x, hx⟩ rcases h with ⟨x, hx⟩
use 2 * x ^ 2 use 2 * x ^ 2
rw [hx] rw [hx]
ring ring
Message (n : ) (h : even n) : even (n ^ 2) => Message (n : ) (h : Even n) : Even (n ^ 2) =>
"Wenn du die Definition von `even` nicht kennst, kannst du diese mit `unfold even` oder "Wenn du die Definition von `even` nicht kennst, kannst du diese mit `unfold even` oder
`unfold even at *` ersetzen. `unfold even at *` ersetzen.
Note: Der Befehl macht erst mal nichts in Lean sondern nur in der Anzeige. Der Beweis funktioniert Note: Der Befehl macht erst mal nichts in Lean sondern nur in der Anzeige. Der Beweis funktioniert
@ -68,4 +68,4 @@ Message (n : ) (x : ) (hx : n = x + x) : (x + x) ^ 2 = 2 * x ^ 2 + 2 * x ^
"Die Taktik `ring` löst solche Gleichungen." "Die Taktik `ring` löst solche Gleichungen."
Tactics unfold rcases use rw ring Tactics unfold rcases use rw ring
Lemmas even odd Lemmas Even Odd

@ -4,7 +4,8 @@ import Mathlib.Tactic.Contrapose
import Mathlib.Tactic.Use import Mathlib.Tactic.Use
import Mathlib.Tactic.Ring import Mathlib.Tactic.Ring
import TestGame.ToBePorted import Mathlib.Algebra.Parity
import Mathlib
Game "TestGame" Game "TestGame"
World "Predicate" World "Predicate"
@ -33,16 +34,16 @@ TODO: 1-2 Aufgaben mehr.
Statement Statement
" Für alle natürlichen Zahlen $x$ gilt, falls $x$ gerade ist, dann ist $x + 1$ " Für alle natürlichen Zahlen $x$ gilt, falls $x$ gerade ist, dann ist $x + 1$
ungerade." : ∀ (x : ), (even x) → odd (1 + x) := by ungerade." : ∀ (x : ), (Even x) → Odd (1 + x) := by
intro x h intro x h
unfold even at h unfold Even at h
unfold odd unfold Odd
rcases h with ⟨y, hy⟩ rcases h with ⟨y, hy⟩
use y use y
rw [hy] rw [hy]
ring ring
Message (n : ) (hn : odd n) (h : ∀ (x : ), (odd x) → even (x + 1)) : even (n + 1) => Message (n : ) (hn : Odd n) (h : ∀ (x : ), (Odd x) → Even (x + 1)) : Even (n + 1) =>
"`∀ (x : ), (odd x) → even (x + 1)` ist eigentlich das gleiche wie "`∀ (x : ), (odd x) → even (x + 1)` ist eigentlich das gleiche wie
`(x : ) → `" `(x : ) → `"

@ -2,6 +2,8 @@ import TestGame.Metadata
import Mathlib.Tactic.PushNeg import Mathlib.Tactic.PushNeg
import Mathlib import Mathlib
import Mathlib.Algebra.Parity
import TestGame.ToBePorted import TestGame.ToBePorted
Game "TestGame" Game "TestGame"
@ -25,31 +27,30 @@ Das braucht intern die Lemmas
Statement Statement
"Es existiert keine natürliche Zahl $n$, sodass $n + k$ immer ungerade ist.": "Es existiert keine natürliche Zahl $n$, sodass $n + k$ immer ungerade ist.":
¬ ∃ (n : ), ∀ (k : ) , odd (n + k) := by ¬ ∃ (n : ), ∀ (k : ) , Odd (n + k) := by
push_neg push_neg
intro n intro n
use n use n
rw [not_odd] rw [not_odd]
unfold even unfold Even
use n use n
ring
Message : ¬ ∃ (n : ), ∀ (k : ) , odd (n + k) => Message : ¬ ∃ (n : ), ∀ (k : ) , Odd (n + k) =>
"`push_neg` schiebt die Negierung an den Quantoren vorbei." "`push_neg` schiebt die Negierung an den Quantoren vorbei."
Message (n : ) : (∃ k, ¬odd (n + k)) => Message (n : ) : (∃ k, ¬Odd (n + k)) =>
"An dieser Stelle musst du nun ein `k` angeben, sodass `n + k` gerade ist... Benutze `use` "An dieser Stelle musst du nun ein `k` angeben, sodass `n + k` gerade ist... Benutze `use`
mit der richtigen Zahl." mit der richtigen Zahl."
Hint (n : ) : ¬odd (n + n) => Hint (n : ) : ¬Odd (n + n) =>
"Du kennst ein Lemma um mit `¬odd` umzugehen." "Du kennst ein Lemma um mit `¬odd` umzugehen."
-- Hint (n : ) (k : ) : ¬odd (n + k) => -- Hint (n : ) (k : ) : ¬odd (n + k) =>
-- "Du kennst ein Lemma um mit `¬odd` umzugehen." -- "Du kennst ein Lemma um mit `¬odd` umzugehen."
Hint (n : ) : even (n + n) => Hint (n : ) : Even (n + n) =>
"`unfold even` hilft, anzuschauen, was hinter `even` steckt. "`unfold even` hilft, anzuschauen, was hinter `even` steckt.
Danach musst du wieder mit `use r` ein `(r : )` angeben, dass du benützen möchtest." Danach musst du wieder mit `use r` ein `(r : )` angeben, dass du benützen möchtest."
@ -63,4 +64,4 @@ Conclusion ""
Tactics push_neg intro use rw unfold ring Tactics push_neg intro use rw unfold ring
Lemmas even odd not_even not_odd not_exists not_forall Lemmas Even Odd not_even not_odd not_exists not_forall

@ -57,4 +57,4 @@ Conclusion ""
Tactics push_neg intro use rw unfold ring Tactics push_neg intro use rw unfold ring
Lemmas even odd not_even not_odd not_exists not_forall Lemmas Even Odd not_even not_odd not_exists not_forall

@ -1,4 +1,6 @@
import TestGame.Metadata import TestGame.Metadata
import Mathlib.Data.Nat.Prime
import Std.Tactic.RCases import Std.Tactic.RCases
import Mathlib.Tactic.LeftRight import Mathlib.Tactic.LeftRight
import Mathlib.Tactic.Contrapose import Mathlib.Tactic.Contrapose
@ -8,44 +10,30 @@ import Mathlib.Tactic.Ring
import TestGame.ToBePorted import TestGame.ToBePorted
Game "TestGame" Game "TestGame"
World "Proving" World "Prime"
Level 1 Level 1
Title "Ad absurdum" Title "Primzahlen"
Introduction Introduction
" "
In diesem Kapitel lernen wir die wichtigsten Beweistechniken kennen.
Zuerst repetieren wir, dass man vorhandene Lemmas mit `rw` und `apply` benützen kann.
Aber, die Aussagen müssen wirklich exakte Gegenteile sein.
Hier musst du zuerst eines der folgenden Lemmas benützen, um einer der Terme umzuschreiben.
```
lemma not_odd (n : ): ¬ odd n ↔ even n := by
...
lemma not_even (n : ): ¬ even n ↔ odd n := by
...
```
" "
Statement Statement
"Sei $n$ eine natürliche Zahl die sowohl gerade wie auch ungerade ist. "TODO"
Zeige, dass daraus $n = 42$ folgt. (oder, tatsächlich $n = x$ für jedes beliebige $x$)." (n : ) : ∃! (n : ), Nat.Prime n ∧ Even n := by
(n : ) (h_even : even n) (h_odd : odd n) : n = 42 := by use (2 : )
rw [← not_even] at h_odd constructor
contradiction simp only [true_and]
use 1
Message (n : ) (h_even : even n) (h_odd : odd n) : n = 42 => intro y
"Schreibe zuerst eine der Aussagen mit `rw [←not_even] at h_odd` um, damit diese genaue rintro ⟨h₁, h₂⟩
Gegenteile werden." rw [← Nat.Prime.even_iff]
assumption
assumption
Conclusion "" Conclusion ""
Tactics contradiction rw Tactics
Lemmas even odd not_even not_odd Lemmas

@ -36,11 +36,11 @@ lemma not_even (n : ): ¬ even n ↔ odd n := by
Statement Statement
"Sei $n$ eine natürliche Zahl die sowohl gerade wie auch ungerade ist. "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$)." 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 (n : ) (h_even : Even n) (h_odd : Odd n) : n = 42 := by
rw [← not_even] at h_odd rw [← not_even] at h_odd
contradiction contradiction
Message (n : ) (h_even : even n) (h_odd : odd n) : n = 42 => 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 "Schreibe zuerst eine der Aussagen mit `rw [←not_even] at h_odd` um, damit diese genaue
Gegenteile werden." Gegenteile werden."
@ -48,4 +48,4 @@ Conclusion ""
Tactics contradiction rw Tactics contradiction rw
Lemmas even odd not_even not_odd Lemmas Even Odd not_even not_odd

@ -22,22 +22,22 @@ dass das Gegenteil des Goals wahr sei, und dann einen Widerspruch erzeugen.
**Bemerkung:** Besonders beim Beweis durch Widerspruch ist es hilfreich, wenn man **Bemerkung:** Besonders beim Beweis durch Widerspruch ist es hilfreich, wenn man
Zwischenresultate erstellen kann. Zwischenresultate erstellen kann.
`suffices h₁ : ¬(odd (n ^ 2))` erstellt zwei neue Goals: `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 1) Ein Beweis, wieso es genügt `¬(Odd (n ^ 2))` zu zeigen (\"weil das einen Widerspruch zu
`h` bewirkt\"). `h` bewirkt\").
2) Einen Beweis des Zwischenresultats `suffices h₁ : ¬(odd (n ^ 2))` 2) Einen Beweis des Zwischenresultats `suffices h₁ : ¬(Odd (n ^ 2))`
Alternativ macht `have h₁ : ¬(odd (n ^ 2))` genau das gleiche, vertauscht aber die 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 Beweise (1) und (2), so dass man zuerst `h₁` beweist, und dann den eigentlichen Beweis
fortsetzt. fortsetzt.
" "
Statement Statement
"Ist n² ungerade, so ist auch n ungerade. Beweise durch Widerspruch." "Ist n² ungerade, so ist auch n ungerade. Beweise durch Widerspruch."
(n : ) (h : odd (n ^ 2)) : odd n := by (n : ) (h : Odd (n ^ 2)) : Odd n := by
by_contra g by_contra g
suffices d : ¬ odd (n ^ 2) -- TODO: I don't like this suffices d : ¬ Odd (n ^ 2) -- TODO: I don't like this
contradiction contradiction
rw [not_odd] at g rw [not_odd] at g
@ -45,37 +45,37 @@ Statement
apply even_square apply even_square
assumption assumption
Message (n : ) (h : odd (n^2)) : odd n => Message (n : ) (h : Odd (n^2)) : Odd n =>
"Schreibe `by_contra h₁` um einen Beweis durch Widerspruch zu starten." "Schreibe `by_contra h₁` um einen Beweis durch Widerspruch zu starten."
Message (n : ) (g : ¬ odd n) (h : odd (n^2)) : False => Message (n : ) (g : ¬ Odd n) (h : Odd (n^2)) : False =>
"Nun *genügt es zu zeigen, dass* `¬odd (n ^ 2)` wahr ist, "Nun *genügt es zu zeigen, dass* `¬Odd (n ^ 2)` wahr ist,
denn dann erhalten wir einen Widerspruch zu `h`. denn dann erhalten wir einen Widerspruch zu `h`.
Benütze dafür `suffices h₂ : ¬odd (n ^ 2)`. Benütze dafür `suffices h₂ : ¬Odd (n ^ 2)`.
" "
Message (n : ) (g : ¬ odd (n^2)) (h : odd (n^2)) : False => Message (n : ) (g : ¬ Odd (n^2)) (h : Odd (n^2)) : False =>
"Hier musst du rechtfertigen, wieso das genügt. In unserem Fall, weil "Hier musst du rechtfertigen, wieso das genügt. In unserem Fall, weil
dadurch einen Widerspruch entsteht." dadurch einen Widerspruch entsteht."
Hint (n : ) (g : ¬ odd (n^2)) (h : odd (n^2)) : False => Hint (n : ) (g : ¬ Odd (n^2)) (h : Odd (n^2)) : False =>
"Also `contradiction`..." "Also `contradiction`..."
Message (n : ) (g : ¬ odd n) (h : odd (n^2)) : ¬ odd (n^2) => Message (n : ) (g : ¬ Odd n) (h : Odd (n^2)) : ¬ Odd (n^2) =>
"Das Zwischenresultat `¬odd (n^2)` muss auch bewiesen werden. "Das Zwischenresultat `¬Odd (n^2)` muss auch bewiesen werden.
Hier ist wieder das Lemma `not_odd` hilfreich." Hier ist wieder das Lemma `not_Odd` hilfreich."
Hint (n : ) (g : ¬ odd n) (h : odd (n^2)) : even (n^2) => 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." "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) => Message (n: ) (h : Odd (n ^ 2)) (g : Even n) : Even (n ^ 2) =>
"Diese Aussage hast du bereits als Lemma bewiesen." "Diese Aussage hast du bereits als Lemma bewiesen."
Hint (n: ) (h : odd (n ^ 2)) (g : even n) : even (n ^ 2) => Hint (n: ) (h : Odd (n ^ 2)) (g : Even n) : Even (n ^ 2) =>
"Probiers mit `apply ...`" "Probiers mit `apply ...`"
Tactics contradiction by_contra rw apply assumption -- TODO: suffices, have Tactics contradiction by_contra rw apply assumption -- TODO: suffices, have
Lemmas odd even not_odd not_even even_square Lemmas Odd Even not_odd not_even even_square

@ -23,28 +23,28 @@ Wenn das Goal eine Implikation ist, kann man `contrapose` anwenden.
Statement Statement
"Ist n² ungerade, so ist auch n ungerade. Beweise durch Kontraposition." "Ist n² ungerade, so ist auch n ungerade. Beweise durch Kontraposition."
(n : ) : odd (n ^ 2) → odd n := by (n : ) : Odd (n ^ 2) → Odd n := by
contrapose contrapose
rw [not_odd] rw [not_odd]
rw [not_odd] rw [not_odd]
apply even_square apply even_square
Message (n : ) (h : odd (n ^ 2)) : odd n => Message (n : ) (h : Odd (n ^ 2)) : Odd n =>
"`intro` wär generell ein guter Ansatz! Aber hier wollen wir `contrapose` benützen, was eine "`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!" Implikation benötigt, deshalb ist `intro` hier der falsche Weg!"
Message (n : ) : odd (n ^ 2) → odd n => Message (n : ) : Odd (n ^ 2) → Odd n =>
"Mit `contrapose` kann man die Implikation zu "Mit `contrapose` kann man die Implikation zu
`¬ (even n) → ¬ (even n^2)` umkehren." `¬ (even n) → ¬ (even n^2)` umkehren."
Hint (n : ) : ¬odd n → ¬odd (n ^ 2) => "Du kennst bereits ein Lemma um `¬ odd ...` mit `rw` Hint (n : ) : ¬Odd n → ¬Odd (n ^ 2) => "Du kennst bereits ein Lemma um `¬ odd ...` mit `rw`
umzuschreiben" umzuschreiben"
Message (n : ) : even n → ¬odd (n ^ 2) => "rw [not_odd] muss hier zweimal angewendet werden, 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." 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." Message (n : ) : Even n → Even (n ^ 2) => "Diese Aussage hast du bereits als Lemma bewiesen."
Tactics contrapose rw apply Tactics contrapose rw apply
Lemmas even odd not_even not_odd even_square Lemmas Even Odd not_even not_odd even_square

@ -1,16 +1,12 @@
import Mathlib import Mathlib
-- TODO: `even`/`odd` sind in Algebra.Parity. Not ported yet lemma not_odd {n : } : ¬ Odd n ↔ Even n := by sorry
def even (a : ) : Prop := ∃ r, a = 2 * r
def odd (a : ) : Prop := ∃ k, a = 2 * k + 1
lemma not_odd {n : } : ¬ odd n ↔ even n := by sorry lemma not_even {n : } : ¬ Even n ↔ Odd n := by sorry
lemma not_even {n : } : ¬ even n ↔ odd n := by sorry lemma even_square (n : ) : Even n → Even (n ^ 2) := by
lemma even_square (n : ) : even n → even (n ^ 2) := by
intro ⟨x, hx⟩ intro ⟨x, hx⟩
unfold even at * unfold Even at *
use 2 * x ^ 2 use 2 * x ^ 2
rw [hx] rw [hx]
ring ring

@ -28,7 +28,7 @@
{"git": {"git":
{"url": "https://github.com/leanprover-community/mathlib4.git", {"url": "https://github.com/leanprover-community/mathlib4.git",
"subDir?": null, "subDir?": null,
"rev": "1771130ddfb56ca04da3296cf3693a9e58eb00c6", "rev": "8176e5d663db861cccf6fed6db2f9e5669fe6c5b",
"name": "mathlib", "name": "mathlib",
"inputRev?": "master"}}, "inputRev?": "master"}},
{"git": {"git":

Loading…
Cancel
Save