levels
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
import GameServer.Commands
|
||||
|
||||
/-! ## Definitions -/
|
||||
|
||||
DefinitionDoc Even as "Even"
|
||||
"
|
||||
`even n` ist definiert als `∃ r, a = 2 * r`.
|
||||
Die Definition kann man mit `unfold even at *` einsetzen.
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#Even](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/Parity.html#Even)"
|
||||
|
||||
DefinitionDoc Odd as "Odd"
|
||||
"
|
||||
`odd n` ist definiert als `∃ r, a = 2 * r + 1`.
|
||||
Die Definition kann man mit `unfold odd at *` einsetzen.
|
||||
|
||||
* Mathlib Doc: [Odd](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/Parity.html#Odd)"
|
||||
|
||||
DefinitionDoc Injective as "Injective"
|
||||
"
|
||||
`Injective f` ist definiert als
|
||||
|
||||
```
|
||||
∀ a b, f a = f b → a = b
|
||||
```
|
||||
definiert.
|
||||
|
||||
* Mathlib Doc: [Injective](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Init/Function.html#Function.Injective)"
|
||||
|
||||
DefinitionDoc Surjective as "Surjective"
|
||||
"
|
||||
`Surjective f` ist definiert als
|
||||
|
||||
```
|
||||
∀ a, (∃ b, f a = b)
|
||||
```
|
||||
|
||||
* Mathlib Doc: [Surjective](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Init/Function.html#Function.Surjective)"
|
||||
|
||||
DefinitionDoc Bijective as "Bijective"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#Bijective](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Init/Function.html#Function.Bijective)
|
||||
"
|
||||
|
||||
DefinitionDoc LeftInverse as "LeftInverse"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#LeftInverse](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Init/Function.html#Function.LeftInverse)
|
||||
"
|
||||
|
||||
DefinitionDoc RightInverse as "RightInverse"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#RightInverse](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Init/Logic.html#RightInverse)
|
||||
"
|
||||
|
||||
DefinitionDoc StrictMono as "StrictMono"
|
||||
"
|
||||
`StrictMono f` ist definiert als
|
||||
|
||||
```
|
||||
∀ a b, a < b → f a < f b
|
||||
```
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#StrictMono](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Order/Monotone/Basic.html#StrictMono)
|
||||
|
||||
"
|
||||
|
||||
DefinitionDoc Disjoint as "Disjoint"
|
||||
"
|
||||
"
|
||||
|
||||
|
||||
DefinitionDoc Set.preimage as "preimage"
|
||||
"
|
||||
"
|
||||
|
||||
|
||||
DefinitionDoc Set.Nonempty as "Nonempty" "
|
||||
|
||||
`A.Nonemty` ist als `∃ x, x ∈ A` definiert.
|
||||
"
|
||||
|
||||
|
||||
DefinitionDoc Symbol.Subset as "⊆" "
|
||||
|
||||
Auf Mengen (`Set`) ist `A ⊆ B` als `∀x, x ∈ A → x ∈ B` implementiert.
|
||||
|
||||
Im goal kann man direkt `intro x hx` machen, in einer Annahme, kann man mit `rcases`
|
||||
loslegen.
|
||||
|
||||
Alternativ kann man mit `rw[Set.subset_def]` die Definition explizit einsetzen.
|
||||
"
|
||||
|
||||
|
||||
DefinitionDoc Symbol.function as "fun x => _" "
|
||||
|
||||
Anonyme funktionen kann man mit `fun (x : ℤ) => 2 * x` definieren und
|
||||
wie andere Objekte verwenden.
|
||||
|
||||
Note: `=>` wird in mathlib oft auch `↦` (`\\maps`) geschrieben.
|
||||
"
|
||||
@@ -0,0 +1,636 @@
|
||||
import GameServer.Commands
|
||||
|
||||
-- Wird im Level "Implication 11" ohne Beweis angenommen.
|
||||
LemmaDoc Classical.not_not as "not_not" in "Logic"
|
||||
"
|
||||
`not_not {A : Prop} : ¬¬A ↔ A`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Ja
|
||||
* Namespace: `Classical`
|
||||
* Minimal Import: `Std.Logic`
|
||||
* Mathlib Doc: [#not_not](https://leanprover-community.github.io/mathlib4_docs/Std/Logic.html#Classical.not_not)
|
||||
"
|
||||
|
||||
-- Wird im Level "Implication 10" ohne Beweis angenommen.
|
||||
LemmaDoc not_or_of_imp as "not_or_of_imp" in "Logic"
|
||||
"
|
||||
`not_or_of_imp {A B : Prop} : (A → B) → ¬A ∨ B`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* Namespace: `-`
|
||||
* Minimal Import: `Mathlib.Logic.Basic`
|
||||
* Mathlib Doc: [#not_or_of_imp](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Logic/Basic.html#not_or_of_imp)
|
||||
"
|
||||
|
||||
-- Wird im Level "Implication 12" bewiesen.
|
||||
LemmaDoc imp_iff_not_or as "imp_iff_not_or" in "Logic"
|
||||
"
|
||||
`imp_iff_not_or {A B : Prop} : (A → B) ↔ (¬A ∨ B)`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* Namespace: `-`
|
||||
* Minimal Import: `Mathlib.Logic.Basic`
|
||||
* Mathlib Doc: [#imp_iff_not_or](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Logic/Basic.html#imp_iff_not_or)
|
||||
"
|
||||
|
||||
LemmaDoc Nat.succ_pos as "succ_pos" in "Nat"
|
||||
"
|
||||
`Nat.succ_pos (n : ℕ) : 0 < n.succ`
|
||||
|
||||
$n + 1$ ist strikt grösser als Null.
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp` Lemma: Nein
|
||||
* Namespace: `Nat`
|
||||
* Minimal Import: `Mathlib.Init.Prelude`
|
||||
* Mathlib Doc: [#Nat.succ_pos](https://leanprover-community.github.io/mathlib4_docs/Init/Prelude.html#Nat.succ_pos)
|
||||
"
|
||||
|
||||
LemmaDoc Nat.pos_iff_ne_zero as "pos_iff_ne_zero" in "Nat"
|
||||
"
|
||||
`Nat.pos_iff_ne_zero {n : ℕ} : 0 < n ↔ n ≠ 0`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* Namespace: `Nat`
|
||||
* Minimal Import: `Std.Data.Nat.Lemmas`
|
||||
* Mathlib Doc: [#Nat.pos_iff_ne_zero](https://leanprover-community.github.io/mathlib4_docs/Std/Data/Nat/Lemmas.html#Nat.pos_iff_ne_zero)
|
||||
"
|
||||
|
||||
-- TODO: Not minimal description
|
||||
LemmaDoc zero_add as "zero_add" in "Addition"
|
||||
"
|
||||
`zero_add (a : ℕ) : 0 + a = a`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Ja
|
||||
* Namespace: `-`
|
||||
* Import: `Mathlib.Nat.Basic`
|
||||
* Mathlib Doc: [#zero_add](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/Group/Defs.html#zero_add)
|
||||
"
|
||||
|
||||
LemmaDoc add_zero as "add_zero" in "Addition"
|
||||
"
|
||||
This lemma says `∀ a : ℕ, a + 0 = a`.
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc"
|
||||
|
||||
LemmaDoc add_succ as "add_succ" in "Addition"
|
||||
"This lemma says `∀ a b : ℕ, a + succ b = succ (a + b)`.
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#]()"
|
||||
|
||||
LemmaDoc not_forall as "not_forall" in "Logic"
|
||||
"
|
||||
`not_forall {α : Sort _} {P : α → Prop} : ¬(∀ x, → P x) ↔ ∃ x, ¬P x`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Ja
|
||||
* Namespace: `-`
|
||||
* Minimal Import: `Mathlib.Logic.Basic`
|
||||
* Mathlib Doc: [#not_forall](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Logic/Basic.html#not_forall)
|
||||
"
|
||||
|
||||
LemmaDoc not_exists as "not_exists" in "Logic"
|
||||
"
|
||||
`not_exists {α : Sort _} {P : α → Prop} : (¬∃ x, P x) ↔ ∀ (x : α), ¬P x.
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Ja
|
||||
* Namespace: `-`
|
||||
* Minimal Import: `Std.Logic`
|
||||
* Mathlib Doc: [#not_exists](https://leanprover-community.github.io/mathlib4_docs/Std/Logic.html#not_exists)"
|
||||
|
||||
LemmaDoc Nat.even_iff_not_odd as "even_iff_not_odd" in "Nat"
|
||||
"
|
||||
`even_iff_not_odd {n : ℕ} : Even n ↔ ¬Odd n`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* Namespace: `Nat`
|
||||
* Minimal Import: `Mathlib.Data.Nat.Parity`
|
||||
* Mathlib Doc: [#Nat.even_iff_not_odd](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Nat/Parity.html#Nat.even_iff_not_odd)"
|
||||
|
||||
LemmaDoc Nat.odd_iff_not_even as "odd_iff_not_even" in "Nat"
|
||||
"
|
||||
`Nat.odd_iff_not_even {n : ℕ} : Odd n ↔ ¬Even n`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Ja
|
||||
* Namespace: `Nat`
|
||||
* Minimal Import: `Mathlib.Data.Nat.Parity`
|
||||
* Mathlib Doc: [#Nat.odd_iff_not_even](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Nat/Parity.html#Nat.odd_iff_not_even)"
|
||||
|
||||
LemmaDoc even_square as "even_square" in "Nat"
|
||||
"
|
||||
`even_square : (n : ℕ), Even n → Even (n ^ 2)`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* *Nicht in Mathlib*
|
||||
"
|
||||
|
||||
|
||||
|
||||
|
||||
LemmaDoc Set.mem_univ as "mem_univ" in "Set"
|
||||
"
|
||||
`Set.mem_univ {α : Type _} (x : α) : x ∈ @univ α`
|
||||
|
||||
Jedes Element ist in `univ`, der Menge aller Elemente eines Typs `α`.
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Ja
|
||||
* Namespace: `Set`
|
||||
* Minimal Import: `Mathlib.Data.Set.Basic`
|
||||
* Mathlib Doc: [#mem_univ](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.mem_univ)
|
||||
"
|
||||
|
||||
LemmaDoc Set.not_mem_empty as "not_mem_empty" in "Set"
|
||||
"
|
||||
`Set.not_mem_empty {α : Type _} (x : α) : x ∉ ∅`
|
||||
|
||||
Kein Element ist in der leeren Menge.
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* Namespace: `Set`
|
||||
* Mathlib Doc: [#not_mem_empty](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.not_mem_empty)
|
||||
"
|
||||
|
||||
LemmaDoc Set.subset_empty_iff as "subset_empty_iff" in "Set"
|
||||
"
|
||||
`Set.subset_empty_iff.{u} {α : Type u} {s : Set α} : s ⊆ ∅ ↔ s = ∅`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* Namespace: `Set`
|
||||
* Mathlib Doc: [#empty_subset](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.subset_empty_iff)
|
||||
"
|
||||
|
||||
LemmaDoc Set.empty_subset as "empty_subset" in "Set"
|
||||
"
|
||||
`Set.empty_subset {α : Type u} (s : Set α) : ∅ ⊆ s`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Ja
|
||||
* Namespace: `Set`
|
||||
* Mathlib Doc: [#empty_subset](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.empty_subset)
|
||||
"
|
||||
|
||||
LemmaDoc Set.Subset.antisymm as "Subset.antisymm" in "Set"
|
||||
"
|
||||
`Set.Subset.antisymm {α : Type u} {a : Set α} {b : Set α} (h₁ : a ⊆ b) (h₂ : b ⊆ a) : a = b`
|
||||
|
||||
Zwei Mengen sind identisch, wenn sowohl $A \\subseteq B$ wie auch $B \\subseteq A$.
|
||||
## Details
|
||||
|
||||
`apply Subset.antisymm` ist eine Möglichkeit Gleichungen von Mengen zu zeigen.
|
||||
eine andere ist `ext i`, welches Elementweise funktiniert.
|
||||
Siehe auch
|
||||
[`#Subset.antisymm_iff`](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.Subset.antisymm_iff)
|
||||
für die Iff-Version.
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* Namespace: `Set.Subset`
|
||||
* Minimal Import: `Mathlib.Data.Set.Basic`
|
||||
* Mathlib Doc: [#Subset.antisymm](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.Subset.antisymm)
|
||||
"
|
||||
|
||||
LemmaDoc Set.Subset.antisymm_iff as "Subset.antisymm_iff" in "Set"
|
||||
"
|
||||
`Set.Subset.antisymm_iff {α : Type u} {a : Set α} {b : Set α} : a = b ↔ a ⊆ b ∧ b ⊆ a`
|
||||
|
||||
Zwei Mengen sind identisch, wenn sowohl $A \\subseteq B$ wie auch $B \\subseteq A$.
|
||||
|
||||
## Details
|
||||
|
||||
`rw [Subset.antisymm_iff]` ist eine Möglichkeit Gleichungen von Mengen zu zeigen.
|
||||
eine andere ist `ext i`, welches Elementweise funktiniert.
|
||||
Siehe auch
|
||||
[`#Subset.antisymm`](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.Subset.antisymm)
|
||||
für eine verwandte Version.
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* Namespace: `Set.Subset`
|
||||
* Minimal Import: `Mathlib.Data.Set.Basic`
|
||||
* Mathlib Doc: [#Subset.antisymm_iff](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.Subset.antisymm_iff)
|
||||
"
|
||||
|
||||
LemmaDoc Set.diff_inter as "diff_inter" in "Set"
|
||||
"
|
||||
`{α : Type u} {s t u : Set α} : s \\ (t ∩ u) = s \\ t ∪ s \\ u`
|
||||
|
||||
## Eigenschaften
|
||||
* Namespace: `Set`
|
||||
* Mathlib Doc: [#Set.diff_inter](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.diff_inter)
|
||||
|
||||
"
|
||||
|
||||
LemmaDoc Set.union_assoc as "union_assoc" in "Set"
|
||||
"
|
||||
` {α : Type u} (a b c : Set α) : a ∪ b ∪ c = a ∪ (b ∪ c)`
|
||||
|
||||
## Eigenschaften
|
||||
* Namespace: `Set`
|
||||
* Mathlib Doc: [#Set.union_assoc](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.union_assoc)
|
||||
|
||||
"
|
||||
|
||||
LemmaDoc Set.union_diff_distrib as "union_diff_distrib" in "Set"
|
||||
"
|
||||
`{α : Type u} {s t u : Set α} : (s ∪ t) \\ u = s \\ u ∪ t \\ u`
|
||||
|
||||
## Eigenschaften
|
||||
* Namespace: `Set`
|
||||
* Mathlib Doc: [#Set.union_diff_distrib](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.union_diff_distrib)
|
||||
|
||||
"
|
||||
|
||||
LemmaDoc Set.univ_union as "univ_union" in "Set"
|
||||
"
|
||||
` {α : Type u} {s : Set α} : Set.univ ∪ s = Set.univ`
|
||||
|
||||
## Eigenschaften
|
||||
* Namespace: `Set`
|
||||
* Mathlib Doc: [#Set.univ_union](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.univ_union)
|
||||
|
||||
"
|
||||
|
||||
LemmaDoc Nat.prime_def_lt'' as "prime_def_lt''" in "Nat"
|
||||
"
|
||||
`Nat.prime_def_lt'' {p : ℕ} :
|
||||
Nat.Prime p ↔ 2 ≤ p ∧ ∀ (m : ℕ), m ∣ p → m = 1 ∨ m = p`
|
||||
|
||||
Die bekannte Definition einer Primmzahl in `ℕ`: Eine Zahl (`p ≥ 2`) mit genau zwei Teilern.
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* Namespace: `Nat`
|
||||
* Mathlib Doc: [#Nat.prime_def_lt''](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Nat/Prime.html#Nat.prime_def_lt'')
|
||||
"
|
||||
|
||||
LemmaDoc Finset.sum_add_distrib as "sum_add_distrib" in "Sum"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* Namespace: `Finset`
|
||||
* Mathlib Doc: [#Finset.sum_add_distrib](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/BigOperators/Basic.html#Finset.sum_add_distrib)
|
||||
"
|
||||
|
||||
LemmaDoc Fin.sum_univ_castSucc as "sum_univ_castSucc" in "Sum"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* Namespace: `Fin`
|
||||
* Mathlib Doc: [#sum_univ_castSucc](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/BigOperators/Fin.html#Fin.sum_univ_castSucc)
|
||||
"
|
||||
|
||||
LemmaDoc Nat.succ_eq_add_one as "succ_eq_add_one" in "Sum"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* `simp`-Lemma: Nein
|
||||
* Namespace: `Nat`
|
||||
* Mathlib Doc: [#succ_eq_add_one](https://leanprover-community.github.io/mathlib4_docs/Init/Data/Nat/Basic.html#Nat.succ_eq_add_one)
|
||||
"
|
||||
|
||||
LemmaDoc ne_eq as "ne_eq" in "Logic"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#ne_eq](https://leanprover-community.github.io/mathlib4_docs/Init/SimpLemmas.html#ne_eq)
|
||||
"
|
||||
|
||||
LemmaDoc Set.eq_empty_iff_forall_not_mem as "eq_empty_iff_forall_not_mem" in "Sum"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#eq_empty_iff_forall_not_mem](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.eq_empty_iff_forall_not_mem)
|
||||
"
|
||||
|
||||
LemmaDoc Nat.zero_eq as "zero_eq" in "Nat"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#zero_eq](https://leanprover-community.github.io/mathlib4_docs/Init/Data/Nat/Basic.html#Nat.zero_eq)
|
||||
"
|
||||
|
||||
LemmaDoc add_comm as "add_comm" in "Nat"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#add_comm](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/Group/Defs.html#add_comm)
|
||||
"
|
||||
|
||||
LemmaDoc mul_add as "mul_add" in "Nat"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#mul_add](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/Ring/Defs.html#mul_add)
|
||||
"
|
||||
|
||||
LemmaDoc add_mul as "add_mul" in "Nat"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#add_mul](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/Ring/Defs.html#add_mul)
|
||||
"
|
||||
|
||||
LemmaDoc arithmetic_sum as "arithmetic_sum" in "Sum"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Not a mathlib lemma.
|
||||
"
|
||||
|
||||
LemmaDoc add_pow_two as "add_pow_two" in "Nat"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#add_pow_two](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/GroupPower/Ring.html#add_pow_two)
|
||||
"
|
||||
|
||||
LemmaDoc Finset.sum_comm as "sum_comm" in "Sum"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#sum_comm](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/BigOperators/Basic.html#Finset.sum_comm)
|
||||
"
|
||||
|
||||
LemmaDoc Function.comp_apply as "comp_apply" in "Function"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#comp_apply](https://leanprover-community.github.io/mathlib4_docs/Init/Core.html#Function.comp_apply)
|
||||
"
|
||||
|
||||
LemmaDoc not_le as "not_le" in "Logic"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#not_le](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Init/Algebra/Order.html#not_le)
|
||||
"
|
||||
|
||||
LemmaDoc if_pos as "if_pos" in "Logic"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#if_pos](https://leanprover-community.github.io/mathlib4_docs/Init/Core.html#if_pos)
|
||||
"
|
||||
|
||||
LemmaDoc if_neg as "if_neg" in "Logic"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#if_neg](https://leanprover-community.github.io/mathlib4_docs/Init/Core.html#if_neg)
|
||||
"
|
||||
|
||||
LemmaDoc StrictMono.injective as "StrictMono.injective" in "Function"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#StrictMono.injective](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Order/Monotone/Basic.html#StrictMono.injective)
|
||||
"
|
||||
|
||||
LemmaDoc StrictMono.add as "StrictMono.add" in "Function"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#StrictMono.add](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/Order/Monoid/Lemmas.html#StrictMono.add)
|
||||
"
|
||||
|
||||
LemmaDoc Odd.strictMono_pow as "Odd.strictMono_pow" in "Function"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#Odd.strictMono_pow](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/Parity.html#Odd.strictMono_pow)
|
||||
"
|
||||
|
||||
LemmaDoc Exists.choose as "Exists.choose" in "Logic"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#Exists.choose](https://leanprover-community.github.io/mathlib4_docs/Std/Logic.html#Exists.choose)
|
||||
"
|
||||
|
||||
LemmaDoc Exists.choose_spec as "Exists.choose_spec" in "Logic"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#Exists.choose_spec](https://leanprover-community.github.io/mathlib4_docs/Std/Logic.html#Exists.choose_spec)
|
||||
"
|
||||
LemmaDoc congrArg as "congrArg" in "Logic"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#congrArg](https://leanprover-community.github.io/mathlib4_docs/Init/Prelude.html#congrArg)
|
||||
"
|
||||
LemmaDoc congrFun as "congrFun" in "Logic"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#congrFun](https://leanprover-community.github.io/mathlib4_docs/Init/Prelude.html#congrFun)
|
||||
"
|
||||
|
||||
LemmaDoc Iff.symm as "Iff.symm" in "Logic"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#Iff.symm](https://leanprover-community.github.io/mathlib4_docs/Init/Core.html#Iff.symm)
|
||||
"
|
||||
|
||||
LemmaDoc not_imp_not as "not_imp_not" in "Logic"
|
||||
"
|
||||
`theorem not_imp_not {a : Prop} {b : Prop} : ¬a → ¬b ↔ b → a`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#not_imp_not](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Logic/Basic.html#not_imp_not)
|
||||
"
|
||||
|
||||
LemmaDoc Set.nonempty_iff_ne_empty as "nonempty_iff_ne_empty" in "Logic"
|
||||
"
|
||||
`theorem Set.nonempty_iff_ne_empty {α : Type u} {s : Set α} : Set.Nonempty s ↔ s ≠ ∅`
|
||||
|
||||
## Eigenschaften
|
||||
|
||||
* Mathlib Doc: [#nonempty_iff_ne_empty](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Data/Set/Basic.html#Set.nonempty_iff_ne_empty)
|
||||
"
|
||||
|
||||
LemmaDoc Set.subset_univ as "subset_univ" in "Set"
|
||||
"
|
||||
`{α : Type u} {s : Set α} : s ⊆ univ`
|
||||
"
|
||||
|
||||
LemmaDoc Set.not_mem_compl_iff as "not_mem_compl_iff" in "Set"
|
||||
"
|
||||
` {α : Type u} {s : Set α} {x : α} : ¬x ∈ sᶜ ↔ x ∈ s`
|
||||
"
|
||||
|
||||
LemmaDoc Set.mem_of_subset_of_mem as "mem_of_subset_of_mem" in "Set"
|
||||
"
|
||||
`{α : Type u} {s₁ : Set α} {s₂ : Set α} {a : α} (h : s₁ ⊆ s₂) :
|
||||
a ∈ s₁ → a ∈ s₂`
|
||||
"
|
||||
|
||||
LemmaDoc Set.compl_eq_univ_diff as "compl_eq_univ_diff" in "Set"
|
||||
"
|
||||
` {α : Type u} (s : Set α) :
|
||||
sᶜ = Set.univ \\ s`
|
||||
"
|
||||
|
||||
LemmaDoc Set.compl_union as "compl_union" in "Set"
|
||||
"
|
||||
` {α : Type u} (s t : Set α) :
|
||||
(s ∪ t)ᶜ = sᶜ ∩ tᶜ`
|
||||
"
|
||||
|
||||
LemmaDoc Set.diff_diff as "diff_diff" in "Set"
|
||||
"
|
||||
` {α : Type u} {s t u : Set α} :
|
||||
(s \\ t) \\ u = s \\ (t ∪ u)`
|
||||
"
|
||||
|
||||
LemmaDoc Set.compl_inter as "compl_inter" in "Set"
|
||||
"
|
||||
` {α : Type u} (s t : Set α) :
|
||||
(s ∩ t)ᶜ = sᶜ ∪ tᶜ`
|
||||
"
|
||||
|
||||
LemmaDoc Set.diff_eq_compl_inter as "diff_eq_compl_inter" in "Set"
|
||||
"
|
||||
`{α : Type u} {s t : Set α} : s \\ t = tᶜ ∩ s`
|
||||
"
|
||||
|
||||
LemmaDoc Set.inter_comm as "inter_comm" in "Set"
|
||||
"
|
||||
`{α : Type u} (a b : Set α) : a ∩ b = b ∩ a`
|
||||
"
|
||||
|
||||
LemmaDoc Set.mem_compl_iff as "mem_compl_iff" in "Set"
|
||||
"
|
||||
`{α : Type u} (s : Set α) (x : α) : x ∈ sᶜ ↔ ¬x ∈ s`
|
||||
"
|
||||
|
||||
LemmaDoc Set.subset_def as "subset_def" in "Set"
|
||||
"
|
||||
``
|
||||
"
|
||||
|
||||
LemmaDoc Set.ssubset_def as "ssubset_def" in "Set"
|
||||
"
|
||||
``
|
||||
"
|
||||
|
||||
LemmaDoc not_imp as "not_imp" in "Logic"
|
||||
"
|
||||
`{a : Prop} {b : Prop} : (a → b) ↔ a ∧ ¬b`
|
||||
"
|
||||
|
||||
LemmaDoc Set.mem_diff as "mem_diff" in "Set"
|
||||
"
|
||||
``
|
||||
"
|
||||
|
||||
LemmaDoc Set.mem_insert_iff as "mem_insert_iff" in "Logic"
|
||||
"
|
||||
``
|
||||
"
|
||||
|
||||
LemmaDoc Set.mem_singleton_iff as "mem_singleton_iff" in "Set"
|
||||
"
|
||||
``
|
||||
"
|
||||
|
||||
LemmaDoc Function.bijective_iff_has_inverse as "bijective_iff_has_inverse" in "Function"
|
||||
"
|
||||
``
|
||||
"
|
||||
|
||||
LemmaDoc Set.mem_setOf as "mem_setOf" in "Set"
|
||||
"
|
||||
``
|
||||
"
|
||||
|
||||
LemmaDoc Set.mem_powerset_iff as "mem_powerset_iff" in "Set"
|
||||
"
|
||||
``
|
||||
"
|
||||
|
||||
LemmaDoc Set.subset_union_of_subset_left as "subset_union_of_subset_left" in "Set"
|
||||
"
|
||||
``
|
||||
"
|
||||
|
||||
LemmaDoc Set.subset_union_of_subset_right as "subset_union_of_subset_right" in "Set"
|
||||
"
|
||||
``
|
||||
"
|
||||
|
||||
LemmaDoc Set.setOf_or as "setOf_or" in "Set"
|
||||
"
|
||||
``
|
||||
"
|
||||
|
||||
LemmaDoc Set.setOf_and as "setOf_and" in "Set"
|
||||
"
|
||||
``
|
||||
"
|
||||
LemmaDoc Set.mem_inter_iff as "mem_inter_iff" in "Set"
|
||||
"
|
||||
``
|
||||
"
|
||||
@@ -0,0 +1,579 @@
|
||||
import GameServer.Commands
|
||||
import Adam.Tactics
|
||||
|
||||
TacticDoc assumption
|
||||
"
|
||||
`assumption` sucht nach einer Annahme, die genau dem Goal entspricht.
|
||||
|
||||
## Beispiel
|
||||
|
||||
`assumption` sucht durch die Annahmen und merkt dass `h` genau mit dem Goal übereinstimmt.
|
||||
|
||||
```
|
||||
Objekte
|
||||
a b c d : ℕ
|
||||
h : a + b = c
|
||||
g : a * b = 16
|
||||
t : c = 12
|
||||
Goal
|
||||
a + b = c
|
||||
```
|
||||
"
|
||||
|
||||
TacticDoc apply
|
||||
"
|
||||
`apply my_lemma` Versucht das Goal mit der Aussage des Lemmas zu unifizieren
|
||||
und erstellt ein neues Goal pro Annahme des Lemmas, die noch zu zeigen ist.
|
||||
|
||||
## Details
|
||||
`apply` funktioniert gleichermassen für Lemmas wie für Implikationen
|
||||
wie z.B. `(h : A → B)`.
|
||||
|
||||
## Beispiel
|
||||
|
||||
Gegeben folgendes Lemma:
|
||||
```
|
||||
lemma Nat.eq_zero_of_le_zero {n : ℕ} (h : n ≤ 0) : n = 0 := by sorry
|
||||
```
|
||||
|
||||
Und folgendes Problem:
|
||||
|
||||
```
|
||||
|
||||
Objekte
|
||||
n : ℕ
|
||||
...
|
||||
Goal
|
||||
n = 0
|
||||
```
|
||||
|
||||
Hier ändert `apply Nat.eq_zero_of_le_zero` das Goal zu `n ≤ 0` durch Anwendung
|
||||
des Lemmas.
|
||||
"
|
||||
|
||||
TacticDoc by_cases
|
||||
"
|
||||
`by_cases h : P` macht eine Fallunterscheidung. Im ersten Goal wird eine Annahme
|
||||
`(h : P)` hinzugefügt, im zweiten `(h : ¬P)`.
|
||||
|
||||
## Details
|
||||
|
||||
`P` kann eine beliegige Aussage sein, die als entweder wahr oder falsch angenommen wird.
|
||||
|
||||
## Beispiel
|
||||
|
||||
```
|
||||
example (A : Prop) : A ∨ ¬ A := by
|
||||
by_cases h : A
|
||||
· left
|
||||
assumption
|
||||
· right
|
||||
assumption
|
||||
```
|
||||
"
|
||||
|
||||
TacticDoc by_contra
|
||||
"
|
||||
`by_contra h` startet einen Widerspruchsbeweis.
|
||||
|
||||
## Details
|
||||
Sei `P` das aktuelle Goal. `by_contra h` fügt eine neue Annahme `(h : ¬P)` hinzu
|
||||
und setzt das Goal auf `False`.
|
||||
|
||||
Oft will man `by_contra` nutzen wenn das Goal von der Form `¬ P` ist.
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* `contradiction` schliesst den Widerspruchsbeweis wenn sich (zwei) Annahmen
|
||||
widersprechen.
|
||||
* `contrapose` führt einen Beweis durch Kontraposition und ist entsprechend
|
||||
in ähnlichen Situationen nutzbar wie `by_contra`
|
||||
"
|
||||
|
||||
TacticDoc change
|
||||
"
|
||||
`change t` ändert das Goal zu `t`. Voraussetzung ist, dass `t` und das alte Goal defEq sind.
|
||||
|
||||
## Details
|
||||
|
||||
Dies ist insbesonder hilfreich wenn eine Taktik nicht merkt, dass das Goal defEq ist zu einem
|
||||
Term, der eigentlich gebraucht würde.
|
||||
|
||||
## Beispiel
|
||||
|
||||
Aktuelles Goal:
|
||||
|
||||
```
|
||||
b: ℝ
|
||||
⊢ 1 • b = b
|
||||
```
|
||||
Wobei die Skalarmultiplikation als `fun (a : ℚ) (r : ℝ) => ↑a * r` definiert war. Dann
|
||||
kann man mit `change (1 : ℚ) * b = b` das Goal umschreiben und anschliessend mit Lemmas
|
||||
über die Multiplikation beweisen.
|
||||
"
|
||||
|
||||
TacticDoc constructor
|
||||
"
|
||||
`constructor` teilt ein Goal auf, wenn das Goal eine Struktur ist
|
||||
|
||||
## Detail
|
||||
Wenn das Goal eine Struktur ist, wie z.B. `A ∧ B` welches zwei Felder hat `⟨A, B⟩`, dann
|
||||
erzeugt `constructor` ein Goal pro Feld der Struktur.
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* Das Gegenteil von `constructor` ist `⟨_, _⟩` (`\\<>`), der *anonyme Konstructor*.
|
||||
Dieser enspricht ungefähr der Tupel-Notation in
|
||||
\"eine Gruppe ist ein Tupel $(G, 0, +)$, sodass …\".
|
||||
|
||||
## Beispiel
|
||||
|
||||
```
|
||||
example {A B : Prop} (h : A) (g : B) : A ∧ B := by
|
||||
constructor
|
||||
· assumption
|
||||
· assumption
|
||||
```
|
||||
"
|
||||
|
||||
TacticDoc contradiction
|
||||
"
|
||||
`contradiction` schliesst den Beweis wenn es einen Widerspruch in den Annahmen findet.
|
||||
|
||||
## Details
|
||||
Ein Widerspruch in den Annahmen kann unter anderem folgendermassen aussehen:
|
||||
|
||||
* `(h : n ≠ n)`
|
||||
* `(h : A)` und `(h' : ¬A)`
|
||||
* `(h : False)` (i.e. ein Beweis von `False`)
|
||||
|
||||
## Beispiel
|
||||
|
||||
Folgenes Goal wird von `contradiction` bewiesen
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* Normalerweise wird `contradiction` gebraucht um einen Widerspruchsbeweis zu
|
||||
schliessen, der mit `by_contra` eröffnet wurde.
|
||||
* Ein Beweis von `False` representiert in Lean einen Widerspruch.
|
||||
|
||||
```
|
||||
Objekte:
|
||||
(n m : ℕ)
|
||||
(h : n = m)
|
||||
(g : n ≠ m)
|
||||
Goal
|
||||
37 = 60
|
||||
```
|
||||
nach dem Motto \"ein Widerspruch beweist alles.\"
|
||||
"
|
||||
|
||||
TacticDoc contrapose
|
||||
"
|
||||
`contrapose` ändert ein Goal der Form `A → B` zu `¬B → ¬A` und führt damit
|
||||
eine Beweis durch Kontraposition.
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* `revert h` kann nützlich sein um eine Annahme als Implikationsprämisse zu schreiben bevor man
|
||||
`contrapose` verwendet.
|
||||
"
|
||||
|
||||
TacticDoc exact
|
||||
"
|
||||
`exact h` schliesst das Goal wenn der Term `h` mit dem Goal übereinstimmt.
|
||||
"
|
||||
|
||||
TacticDoc fin_cases
|
||||
"
|
||||
`fin_cases i` führt eine Fallunterscheidung wenn `i` ein endlicher Typ ist.
|
||||
|
||||
## Details
|
||||
`fin_cases i` ist insbesondere nützlich für `(i : Fin n)`, zum Beispiel als Index in
|
||||
endlich dimensionalen Vektorräumen.
|
||||
|
||||
In diesem Fall bewirkt `fin_cases i` dass man Komponentenweise arbeitet.
|
||||
"
|
||||
|
||||
TacticDoc funext
|
||||
"
|
||||
`funext x` wird bei Gleichungen von Funktionen `f = g` gebraucht. Das Goal wird zu
|
||||
`f x = g x`.
|
||||
|
||||
## Details
|
||||
Nach dem Motto `f = g ↔ ∀ x, f x = g x` sind zwei Funktionen dann identisch, wenn sie
|
||||
angewendet auf jedes Element identisch sind. `funext x` benützt dieses Argument.
|
||||
"
|
||||
|
||||
TacticDoc «have»
|
||||
"
|
||||
`have h : P` führt ein Zwischenresultat ein.
|
||||
|
||||
## Details
|
||||
Anschliessend muss man zuerst dieses Zwischenresultat beweisen bevor man mit dem Beweis
|
||||
weitermachen und das Zwischenresultat verwenden kann.
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* `suffices h : P` funktioniert genau gleich, aussert das die beiden entstehenden Beweise
|
||||
vertauscht sind.
|
||||
* `let h : Prop := A ∧ B` ist verwandt mit `have`, mit Unterschied, dass man mit `let`
|
||||
eine temporäre Definition einführt.
|
||||
"
|
||||
|
||||
TacticDoc induction
|
||||
"
|
||||
`induction n` führt einen Induktionsbeweis über `n`.
|
||||
|
||||
## Detail
|
||||
|
||||
Diese Taktik erstellt zwei Goals:
|
||||
* Induktionsanfang, wo `n = 0` ersetzt wird.
|
||||
* Induktionsschritt, in dem man die Induktionshypothese `n_ih` zur Verfügung hat.
|
||||
|
||||
## Modifikationen in diesem Spiel
|
||||
|
||||
* `induction n with d hd` benennt Induktionsvariable und -hypothese. (das ist Lean3-Syntax)
|
||||
und funktioniert ausserhalb vom Spiel nicht genau so.
|
||||
* Ausserhalb des Spiels kriegst du `Nat.zero` und `Nat.succ n` anstatt `0` und `n + 1`
|
||||
als Fälle. Diese
|
||||
Terme sind DefEq, aber manchmal benötigt man die lemmas `zero_eq` und `Nat.succ_eq_add_one`
|
||||
um zwischen den schreibweisen zu wechseln
|
||||
|
||||
Der richtige Lean4-Syntax für `with` streckt sich über mehrere Zeilen und ist:
|
||||
|
||||
```
|
||||
induction n with
|
||||
| zero =>
|
||||
sorry
|
||||
| succ m m_ih =>
|
||||
sorry
|
||||
```
|
||||
|
||||
da dieser sich über mehrere Zeilen erstreckt wird er im Spiel nicht eingeführt.
|
||||
|
||||
## Hifreiche Resultate
|
||||
|
||||
* `Nat.succ_eq_add_one`: schreibt `n.succ = n + 1` um.
|
||||
* `Nat.zero_eq`: schreibt `Nat.zero = 0` um.
|
||||
|
||||
Beide sind DefEq, aber manche Taktiken können nicht damit umgehen
|
||||
|
||||
* Siehe Definition `∑` für Hilfe mit Induktion über Summen.
|
||||
* `rcases n` ist sehr ähnlich zu `induction n`. Der Unterschied ist, dass bei
|
||||
`rcases` keine Induktionshypothese im Fall `n + 1` zur Verfügung steht.
|
||||
|
||||
## Beispiel
|
||||
|
||||
```
|
||||
example (n : ℕ) : 4 ∣ 5^n + 7 := by
|
||||
induction n
|
||||
sorry -- Fall `n = 0`
|
||||
sorry -- Fall `n + 1`
|
||||
```
|
||||
"
|
||||
|
||||
TacticDoc intro
|
||||
"
|
||||
`intro x` wird für Goals der Form `A → B` oder `∀ x, P x` verwendet.
|
||||
Dadurch wird die Implikationsprämisse (oder das Objekt `x`) den Annahmen hinzugefügt.
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* `revert h` macht das Gegenteil von `intro`.
|
||||
"
|
||||
|
||||
TacticDoc left
|
||||
"
|
||||
Wenn das Goal von der Form `A ∨ B` ist, enscheidet man mit `left` die linke Seite zu zeigen.
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* `right` entscheidet sich für die linke Seite.
|
||||
"
|
||||
|
||||
TacticDoc «let»
|
||||
"
|
||||
`let x : ℕ := 5 ^ 2` führt eine neue temporäre Definition ein.
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* `have x : ℕ := 5 ^ 2` führt ebenfalls eine neue natürliche Zahle `x` ein, aber
|
||||
Lean vergisst sofort, wie die Zahl definiert war. D.h. `x = 25` wäre dann nicht
|
||||
beweisbar. Mit `let x : ℕ := 5 ^ 2` ist `x = 25` durch `rfl` beweisbar.
|
||||
"
|
||||
|
||||
TacticDoc linarith
|
||||
"
|
||||
`linarith` löst Systeme linearer (Un-)Gleichungen.
|
||||
|
||||
## Detail
|
||||
`linarith` kann lineare Gleichungen und Ungleichungen beweisen indem
|
||||
es das Gegenteil vom Goal annimmt und versucht einen Widerspruch in den
|
||||
Annahmen zu erzeugen (Widerspruchsbeweis). Es braucht ein `≤` definiert um
|
||||
zu funktionieren.
|
||||
|
||||
## Beispiel
|
||||
|
||||
Folgendes kann `linarith` beweisen.
|
||||
```
|
||||
Objekte
|
||||
x y : ℤ
|
||||
h₁ : 5 * y ≤ 35 - 2 * x
|
||||
h₂ : 2 * y ≤ x + 3
|
||||
Goal
|
||||
y ≤ 5
|
||||
```
|
||||
"
|
||||
|
||||
TacticDoc push_neg
|
||||
"
|
||||
`push_neg` schreibt `¬∀ x, _` zu `∃ x, ¬ _` und `¬∃ x, _` zu `∀x, ¬ _` um.
|
||||
|
||||
## Details
|
||||
|
||||
`psuh_neg` schiebt das `¬` soweit nach innen wie möglich.
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* Die beiden Lemmas heissen `not_forall` und `not_exists` und können mit `rw` einzeln angewendet
|
||||
werden.
|
||||
"
|
||||
|
||||
TacticDoc rcases
|
||||
"
|
||||
`rcases h` teilt eine Annahme `h` in ihre Einzelteile auf.
|
||||
|
||||
## Details
|
||||
Für Annahmen die Strukturen sind, wie z.B. `h : A ∧ B` (oder `∃x, P x`) kann man die
|
||||
Einzelteile mit `rcases h with ⟨a, b⟩` (oder `rcases h with ⟨x, hx⟩`) benennen.
|
||||
|
||||
Für eine Annahme der Form `h : A ∨ B` kann man mit `rcases h with ha | hb` zwei Goals
|
||||
erzeugen, einmal unter Annahme der linken Seite, einmal unter Annahme der Rechten.
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* Für `n : ℕ` hat `rcases n` einen ähnlichen Effekt wie `induction n` mit dem Unterschied,
|
||||
dass im Fall `n + 1` keine Induktionshypothese zur Verfügung steht.
|
||||
* In Lean gibt es auch die Taktik `cases`, die gleich funktioniert wie `rcases` aber
|
||||
einen mehrzeiligen Syntax hat:
|
||||
```
|
||||
cases h with
|
||||
| inl ha =>
|
||||
sorry
|
||||
| inr hb =>
|
||||
sorry
|
||||
```
|
||||
Hier sind `inl`/`inr` die Namen der Fälle und `ha`/`hb` sind frei gewählte Namen für die
|
||||
freien Variablen
|
||||
"
|
||||
|
||||
TacticDoc refine
|
||||
"
|
||||
`refine { ?..! }` wird benötigt um eine Struktur (z.B. ein $R$-Modul) im Taktikmodus in einzelne
|
||||
Goals aufzuteilen. Danach hat man ein Goal pro Strukturfeld.
|
||||
|
||||
(*Bemerkung*: Es gibt in Lean verschiedenste bessere Varianten dies zu erreichen,
|
||||
z.B. \"Term Modus\" oder \"anonyme Konstruktoren\", aber für den Zweck des Spieles bleiben wir
|
||||
bei diesem Syntax.)
|
||||
"
|
||||
|
||||
TacticDoc revert
|
||||
"
|
||||
`revert h` fügt die Annahme `h` als Implikationsprämisse vorne ans Goal an.
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* `revert` ist das Gegenteil von `intro`.
|
||||
* `revert` kann insbesondere nützlich sein, um anschliessend `contrapose` zu verwenden.
|
||||
|
||||
## Beispiel
|
||||
|
||||
```
|
||||
Objekte
|
||||
A P : Prop
|
||||
h : P
|
||||
Goal
|
||||
A
|
||||
```
|
||||
|
||||
hier ändert `revert h` den Status zu
|
||||
|
||||
```
|
||||
Objekte
|
||||
A P : Prop
|
||||
Goal
|
||||
P → A
|
||||
```
|
||||
"
|
||||
|
||||
TacticDoc rfl
|
||||
"
|
||||
`rfl` beweist ein Goal der Form `X = X`.
|
||||
|
||||
## Detail
|
||||
|
||||
`rfl` beweist jedes Goal `A = B` wenn `A` und `B` per Definition das gleiche sind (DefEq).
|
||||
Andere Taktiken rufen `rfl` oft am Ende versteckt
|
||||
automatisch auf um zu versuchen, den Beweis zu schliessen.
|
||||
|
||||
|
||||
## Beispiel
|
||||
`rfl` kann folgende Goals beweisen:
|
||||
|
||||
```
|
||||
Objekte
|
||||
a b c : ℕ
|
||||
Goal:
|
||||
(a + b) * c = (a + b) * c
|
||||
```
|
||||
|
||||
```
|
||||
Objekte
|
||||
n : ℕ
|
||||
Goal
|
||||
1 + 1 = 2
|
||||
```
|
||||
denn Lean liest dies intern als `0.succ.succ = 0.succ.succ`.
|
||||
"
|
||||
|
||||
TacticDoc right
|
||||
"
|
||||
Wenn das Goal von der Form `A ∨ B` ist, enscheidet man mit `right` die rechte Seite zu zeigen.
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* `left` entscheidet sich für die linke Seite.
|
||||
"
|
||||
|
||||
TacticDoc ring
|
||||
"
|
||||
Löst Gleichungen mit den Operationen `+, -, *, ^`.
|
||||
|
||||
## Details
|
||||
Insbesondere funktioniert `ring` in Ringen/Semiringen wie z.B. `ℕ, ℤ, ℚ, …`
|
||||
(i.e. Typen `R` mit Instanzen `Ring R` oder `Semiring R`).
|
||||
Die Taktik ist besonders auf kommutative Ringe (`CommRing R`) ausgelegt.
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* `ring` kann nicht wirklich mit Division (`/`) oder Inversen (`⁻¹`) umgehen. Dafür ist die
|
||||
Taktik `field_simp` gedacht, und die typische Sequenz ist
|
||||
```
|
||||
field_simp
|
||||
ring
|
||||
```
|
||||
* Wenn `ring` nicht abschliesst, sagt es man solle `ring_nf` verwenden. Normalerweise heisst
|
||||
das aber, dass man was falsch gemacht hat und die Seiten der Gleichung noch nicht gleich sind.
|
||||
"
|
||||
|
||||
TacticDoc rw
|
||||
"
|
||||
Wenn man eine Annahme `(h : X = Y)` hat, kann man mit
|
||||
`rw [h]` alle `X` im Goal durch `Y` ersetzen.
|
||||
|
||||
## Details
|
||||
|
||||
* `rw [←h]` wendet `h` rückwärts an und ersetzt alle `Y` durch `X`.
|
||||
* `rw [h, g, ←f]`: Man kann auch mehrere `rw` zusammenfassen.
|
||||
* `rw [h] at h₂` ersetzt alle `X` in `h₂` zu `Y` (anstatt im Goal).
|
||||
|
||||
`rw` funktioniert gleichermassen mit Annahmen `(h : X = Y)` also auch
|
||||
mit Theoremen/Lemmas der Form `X = Y`
|
||||
"
|
||||
|
||||
TacticDoc simp
|
||||
"
|
||||
`simp` versucht alle Vereinfachungslemmas anzuwenden, die in der `mathlib` mit `@[simp]`
|
||||
gekennzeichnet sind.
|
||||
|
||||
## Details
|
||||
|
||||
* `simp?` zeigt welche Lemmas verwendet wurden.
|
||||
* `simp [my_lemma]` fügt zudem `my_lemma` temporär zur Menge der `simp`-Lemmas hinzu.
|
||||
* ein `simp`, das nicht am Ende des Beweis steht sollte durch eine entsprechende
|
||||
`simp only [...]` Aussage ersetzt werden, um den Beweis stabiler zu machen.
|
||||
"
|
||||
|
||||
TacticDoc simp_rw
|
||||
"
|
||||
`simp_rw [h₁, h₂, h₃]` versucht wie `rw` jedes Lemma der Reihe nach zu Umschreiben zu verwenden,
|
||||
verwendet aber jedes Lemma so oft es kann.
|
||||
|
||||
## Details
|
||||
|
||||
Es bestehen aber drei grosse Unterschiede zu `rw`:
|
||||
|
||||
* `simp_rw` wendet jedes Lemma so oft an wie es nur kann.
|
||||
* `simp_rw` kann besser unter Quantifiern umschreiben als `rw`.
|
||||
* `simp_rw` führt nach jedem Schritt ein `simp only []` aus und vereinfacht dadurch grundlegenste
|
||||
Sachen.
|
||||
"
|
||||
|
||||
TacticDoc «suffices»
|
||||
"
|
||||
`suffices h : P` führt ein neues Zwischenresultat ein, aus dem das Goal direkt folgen soll.
|
||||
|
||||
## Details
|
||||
|
||||
Der einzige Unterschied zu `have h : P` ist, dass die beiden resultierenden Goals vertauscht sind.
|
||||
|
||||
Mathematisch braucht man diese in ein bisschen unterschiedlichen Fällen:
|
||||
|
||||
* `suffices h : P` : \"Es genügt zu zeigen, dass …\". Als erstes folgt die Erklärung wieso
|
||||
das genügt, danach muss man nur noch `P` beweisen.
|
||||
* `have h : P` : Ein (kleines) Zwischenresultat. Als erstes folgt dann der Beweis dieses
|
||||
Resultats, anschliessend setzt man den Beweis mit Hilfe des Zwischenresultats fort.
|
||||
"
|
||||
|
||||
TacticDoc tauto
|
||||
"
|
||||
## Beschreibung
|
||||
|
||||
TODO
|
||||
"
|
||||
|
||||
TacticDoc trivial
|
||||
"
|
||||
`trivial` versucht durch Kombination von wenigen simplen Taktiken das Goal zu schliessen.
|
||||
|
||||
## Details
|
||||
Die Taktiken, die verwendet werden sind:
|
||||
|
||||
* `assumption`
|
||||
* `rfl`
|
||||
* `contradiction`
|
||||
* und noch 3 andere, die hier nicht behandelt werden
|
||||
(`decide`, `apply True.intro`, `apply And.intro`).
|
||||
"
|
||||
|
||||
TacticDoc unfold
|
||||
"
|
||||
`unfold myDef` öffnet eine Definition im Goal.
|
||||
|
||||
## Details
|
||||
Bis auf DefEq (definitinal equality) ändert `unfold` nichts, manche Taktiken
|
||||
(z.B. `push_neg`, `rw`) brauchen aber manchmal die Hilfe.
|
||||
|
||||
`unfold myDef at h` kann auch Definitionen in Annahmen öffnen
|
||||
|
||||
## Hilfreiche Resultate
|
||||
|
||||
* `change P` ist eine andere Taktik, die das aktuelle Goal in einen DefEq-Ausdruck umschreibt.
|
||||
Diese Taktik braucht man auch manchmal um zu hacken, wenn Lean Mühe hat etwas zu verstehen.
|
||||
"
|
||||
|
||||
TacticDoc use
|
||||
"
|
||||
Wenn das Goal von der Form `∃x, P x` ist, kann man mit `use n` ein konkretes Element angeben
|
||||
mit dem man das Goal beweisen möchte.
|
||||
|
||||
## Details
|
||||
|
||||
`use n` versucht zudem anschliessend `rfl` aufzurufen, und kann das Goal damit manchmal direkt
|
||||
schließen.
|
||||
"
|
||||
|
||||
TacticDoc ext
|
||||
"
|
||||
"
|
||||
Reference in New Issue
Block a user