levels
This commit is contained in:
@@ -61,16 +61,16 @@ Conclusion
|
||||
"Fertig!"
|
||||
|
||||
|
||||
Path Proposition → Implication → Predicate → Predicate → Contradiction → Sum → Lean
|
||||
Path Proposition → Implication → Predicate → Predicate → Contradiction → Sum → Lean → Function
|
||||
Path Predicate → Inequality → Sum
|
||||
-- Path Inequality → Prime
|
||||
-- Path Sum → Inequality -- → Induction
|
||||
|
||||
Path Lean → SetTheory → SetTheory2 → SetFunction → Module
|
||||
Path Lean → Function → SetFunction
|
||||
|
||||
|
||||
-- Path SetTheory2 → Numbers
|
||||
|
||||
Path Lean → SetTheory → SetTheory2
|
||||
|
||||
Path SetTheory2 → SetFunction → Module
|
||||
Path Function → SetFunction
|
||||
Path Module → Basis → Module2
|
||||
|
||||
MakeGame
|
||||
|
||||
@@ -76,12 +76,37 @@ DefinitionDoc StrictMono as "StrictMono"
|
||||
|
||||
"
|
||||
|
||||
DefinitionDoc Symbol.Subset as "⊆" "
|
||||
|
||||
Auf Mengen (`Set`) ist `A ⊆ B` als `∀x, x ∈ A → x ∈ B` implementiert.
|
||||
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.
|
||||
"
|
||||
@@ -243,17 +243,45 @@ für eine verwandte Version.
|
||||
* 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 "union_assoc" in "Set"
|
||||
""
|
||||
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"
|
||||
"
|
||||
@@ -315,7 +343,7 @@ LemmaDoc Set.eq_empty_iff_forall_not_mem as "eq_empty_iff_forall_not_mem" in "Su
|
||||
* 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 "Sum"
|
||||
LemmaDoc Nat.zero_eq as "zero_eq" in "Nat"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
@@ -371,7 +399,7 @@ LemmaDoc Finset.sum_comm as "sum_comm" in "Sum"
|
||||
* Mathlib Doc: [#sum_comm](https://leanprover-community.github.io/mathlib4_docs/Mathlib/Algebra/BigOperators/Basic.html#Finset.sum_comm)
|
||||
"
|
||||
|
||||
LemmaDoc Function.comp_apply as "Function.comp_apply" in "Function"
|
||||
LemmaDoc Function.comp_apply as "comp_apply" in "Function"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
@@ -427,7 +455,7 @@ LemmaDoc Odd.strictMono_pow as "Odd.strictMono_pow" in "Function"
|
||||
* 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 "Function"
|
||||
LemmaDoc Exists.choose as "Exists.choose" in "Logic"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
@@ -435,21 +463,21 @@ LemmaDoc Exists.choose as "Exists.choose" in "Function"
|
||||
* 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 "Function"
|
||||
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 "Function"
|
||||
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 "Function"
|
||||
LemmaDoc congrFun as "congrFun" in "Logic"
|
||||
"
|
||||
|
||||
## Eigenschaften
|
||||
@@ -482,3 +510,127 @@ LemmaDoc Set.nonempty_iff_ne_empty as "nonempty_iff_ne_empty" in "Logic"
|
||||
|
||||
* 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"
|
||||
"
|
||||
``
|
||||
"
|
||||
@@ -573,3 +573,7 @@ mit dem man das Goal beweisen möchte.
|
||||
`use n` versucht zudem anschliessend `rfl` aufzurufen, und kann das Goal damit manchmal direkt
|
||||
schließen.
|
||||
"
|
||||
|
||||
TacticDoc ext
|
||||
"
|
||||
"
|
||||
@@ -7,7 +7,6 @@ import Adam.Levels.Function.L06_Injective
|
||||
import Adam.Levels.Function.L07_Surjective
|
||||
import Adam.Levels.Function.L08_Bijective
|
||||
import Adam.Levels.Function.L09_Inverse
|
||||
import Adam.Levels.Function.L11_Inverse
|
||||
|
||||
Game "Adam"
|
||||
World "Function"
|
||||
|
||||
@@ -15,47 +15,45 @@ dass sie euch gar nicht sagt, wo dieser zu finden sei.
|
||||
"
|
||||
|
||||
Statement "" : ∃ f : ℤ → ℤ, ∀ x, f x < x := by
|
||||
Hint
|
||||
"
|
||||
**Robo**: `f : ℤ → ℤ` ist die Notation für eine Funktion und `f x` ist diese Funktion
|
||||
angewendet auf ein Element `(x : ℤ)`.
|
||||
|
||||
**Du**: War `→` nicht eben noch eine Implikation?
|
||||
|
||||
**Robo**: Doch, die brauchen das gleiche Zeichen für beides.
|
||||
|
||||
**Du**: Dann ist `f : ℤ → ℤ` also einfach abstrakt irgendeine Funktion,
|
||||
wie definier ich aber jetzt konkret eine Abbildungsvorschrift?
|
||||
|
||||
**Robo**: Man kennt hier eine Notation für eine anonyme Funktion:
|
||||
`fun (x : ℤ) ↦ x ^ 2` ist
|
||||
|
||||
$$
|
||||
\\begin\{aligned}
|
||||
f : \\mathbb\{ℤ} &\\to \\mathbb\{ℤ} \\\\
|
||||
x &\\mapsto x ^ 2
|
||||
\\end\{aligned}
|
||||
$$
|
||||
|
||||
**Robo**: PS, `↦` ist `\\mapsto`. Aber man kann auch stattdessen `=>` benützen.
|
||||
"
|
||||
Hint (hidden := true)
|
||||
"
|
||||
**Du**: Ja aber was mach ich damit?
|
||||
|
||||
**Robo**: Wie immer gehst du ein `∃` mit `use …` an.
|
||||
"
|
||||
use (fun x ↦ x - 1)
|
||||
Hint (hidden := true) "**Du**: Zu was sich das wohl vereinfacht?"
|
||||
Branch
|
||||
intro x
|
||||
Hint (hidden := true) "**Du**: Zu was sich das wohl vereinfacht?"
|
||||
simp
|
||||
|
||||
Hint : ∃ f : ℤ → ℤ, ∀ x, f x < x =>
|
||||
"
|
||||
**Robo**: `f : ℤ → ℤ` ist die Notation für eine Funktion und `f x` ist diese Funktion
|
||||
angewendet auf ein Element `(x : ℤ)`.
|
||||
|
||||
**Du**: War `→` nicht eben noch eine Implikation?
|
||||
|
||||
**Robo**: Doch, die brauchen das gleiche Zeichen für beides.
|
||||
|
||||
**Du**: Dann ist `f : ℤ → ℤ` also einfach abstrakt irgendeine Funktion,
|
||||
wie definier ich aber jetzt konkret eine Abbildungsvorschrift?
|
||||
|
||||
**Robo**: Man kennt hier eine Notation für eine anonyme Funktion:
|
||||
`fun (x : ℤ) ↦ x ^ 2` ist
|
||||
|
||||
$$
|
||||
\\begin\{aligned}
|
||||
f : \\mathbb\{ℤ} &\\to \\mathbb\{ℤ} \\\\
|
||||
x &\\mapsto x ^ 2
|
||||
\\end\{aligned}
|
||||
$$
|
||||
|
||||
**Robo**: PS, `↦` ist `\\mapsto`. Aber man kann auch stattdessen `=>` benützen.
|
||||
"
|
||||
|
||||
HiddenHint : ∃ f : ℕ → ℤ, ∀ x, f x < x =>
|
||||
"
|
||||
**Du**: Ja aber was mach ich damit?
|
||||
|
||||
**Robo**: Wie immer gehst du ein `∃` mit `use …` an.
|
||||
"
|
||||
|
||||
-- TODO: Why does this not show?
|
||||
HiddenHint : ∀ (x : ℤ), (fun (y : ℤ) => y - 1) x < x =>
|
||||
"**Du**: Zu was sich das wohl vereinfacht?"
|
||||
|
||||
HiddenHint (x : ℤ) : (fun y => y - 1) x < x =>
|
||||
"**Du**: Zu was sich das wohl vereinfacht?"
|
||||
NewDefinition Symbol.function
|
||||
LemmaTab "Function"
|
||||
|
||||
Conclusion "Das Mädchen wird kurz ruhig, dann beginnt es zu lächeln und zeigt strahlend
|
||||
in eine Richtung. Ihr folgt ihrem Finger und euch fällt in weiter ferne eine pompöse Struktur
|
||||
|
||||
@@ -33,12 +33,35 @@ def f (x : ℤ) : ℤ := (x + 4)
|
||||
und:
|
||||
"
|
||||
|
||||
open Function
|
||||
|
||||
def f (x : ℤ) : ℤ := (x + 4)
|
||||
|
||||
Statement "" (x : ℤ) : ∃ (g : ℤ → ℤ), (g ∘ f) x = x + 1 := by
|
||||
Hint
|
||||
"**Du**: Ist `g ∘ f` Komposition von Funktionen?
|
||||
|
||||
**Robo**: Richtig! Das schreibt man mit `\\comp`.
|
||||
|
||||
**Du** Und hier könnte ich also zuerst
|
||||
`let g := fun (x : ℤ) ↦ _` definieren, anstatt direkt
|
||||
`use fun (x : ℤ) ↦ _`?
|
||||
|
||||
**Robo**: Genau! Das ist zwar praktisch das gleiche, aber kann manchmal nützlich sein."
|
||||
Branch
|
||||
use fun (x : ℤ) ↦ x - 3
|
||||
Hint "**Robo**: `((fun (x : ℤ) ↦ x - 3) ∘ f) x` ist per Definition `(fun (x : ℤ) ↦ x - 3) (f x)`, aber mit
|
||||
`rw [comp_apply]` kann man das explizit umschreiben, aber `simp` kennt das
|
||||
Lemma auch."
|
||||
let g := fun (x : ℤ) ↦ x - 3
|
||||
Hint "**Robo**: gute Wahl! Jetzt kannst du diese mit `use g` benützen."
|
||||
use g
|
||||
Hint "**Robo**: `({g} ∘ f) x` ist per Definition `{g} (f x)`, aber mit
|
||||
`rw [comp_apply]` kann man das explizit umschreiben, aber `simp` kennt das
|
||||
Lemma auch."
|
||||
simp
|
||||
Hint "**Robo**: Wie schon gehabt hat `ring` Schwierigkeiten, Definitionen zu öffnen.
|
||||
Du kannst mit `unfold f` oder `rw [f]` nachhelfen."
|
||||
unfold f
|
||||
ring
|
||||
|
||||
@@ -46,38 +69,9 @@ NewTactic «let»
|
||||
NewLemma Function.comp_apply
|
||||
LemmaTab "Function"
|
||||
|
||||
Hint (x : ℤ) : ∃ g, (g ∘ f) x = x + 1 =>
|
||||
"**Du**: Ist `g ∘ f` Komposition von Funktionen?
|
||||
|
||||
**Robo**: Richtig! Das schreibt man mit `\\comp`.
|
||||
|
||||
**Du** Und hier könnte ich also zuerst
|
||||
`let g := fun (x : ℤ) ↦ _` definieren, anstatt direkt
|
||||
`use fun (x : ℤ) ↦ _`?
|
||||
|
||||
**Robo**: Genau! Das ist zwar praktisch das gleiche, aber kann manchmal nützlich sein.
|
||||
"
|
||||
|
||||
-- TODO: Make some hints work here
|
||||
Hint (x : ℤ) : ((fun (x : ℤ) ↦ x - 3) ∘ f) x = x + 1 =>
|
||||
"**Robo**: Manchmal must du nachhelfen und Funktionen mit `unfold f` öffnen, manchmal nicht.
|
||||
Um erlich zu sein, sagt mein Programm nicht genau wann man das machen muss…"
|
||||
|
||||
-- TODO : Make this work
|
||||
Hint (x : ℤ) (g := (fun (x : ℤ) ↦ x - 3)) : (g ∘ f) x = x + 1 =>
|
||||
"**Robo**: `(g ∘ f) x` ist per Definition `g (f x)`, aber mit
|
||||
`rw [Function.comp_apply]` kann man das explizit umschreiben, aber `simp` kennt das
|
||||
Lemma auch."
|
||||
|
||||
Hint (x : ℤ) : f x - 3 = x + 1 =>
|
||||
"**Robo**: Manchmal must du nachhelfen und Definitionen mit `unfold f` öffnen, mamchmal klappts
|
||||
ohne.
|
||||
Um erlich zu sein, sagt mein Programm nicht genau wann man das machen muss…"
|
||||
|
||||
-- TODO: Block simp-Lemma
|
||||
|
||||
Conclusion "**Du**: Dann verstehst du etwas Mathe?
|
||||
|
||||
**Robo**: Ich hatte ja keine Ahnung ob die generierte Aufgabe beweisbar ist…
|
||||
**Robo**: Ich hatte ja keine Ahnung ob die generierte Aufgabe beweisbar ist… aber offenbar
|
||||
hatte ich Glück.
|
||||
|
||||
Und damit erreicht ihr den Hügel mit der Bibliothek."
|
||||
|
||||
@@ -25,7 +25,7 @@ def g : ℚ → ℚ := fun x ↦ if 0 ≤ x then 2*x else 0
|
||||
und gibt dir ein Blatt mit einer einzelnen Zeile am oberen Ende.
|
||||
"
|
||||
|
||||
open Set
|
||||
open Set Function
|
||||
|
||||
namespace LevelFunction4
|
||||
|
||||
@@ -34,62 +34,64 @@ def g : ℚ → ℚ := fun x ↦ if 0 ≤ x then 2*x else 0
|
||||
|
||||
Statement ""
|
||||
: f ∘ g = g ∘ f := by
|
||||
Hint "
|
||||
**Robo**: Schau mal, die beiden haben zwei Funktionen, eine davon mit stückweiser Definition.
|
||||
|
||||
**Du**: Und ich soll zeigen, dass die beiden vertauschbar sind?
|
||||
|
||||
**Robo**: Genau, am besten wählst du mit `funext x` ein beliebiges Element aus, und zeigst das
|
||||
dann für dieses.
|
||||
"
|
||||
funext x
|
||||
simp_rw [Function.comp_apply]
|
||||
Hint "
|
||||
**Du**: Ah und jetzt kann ich erst einmal `(g ∘ f) {x}` zu `g (f {x})` umschreiben?
|
||||
|
||||
**Robo**: Mit `simp` klappt das.
|
||||
"
|
||||
simp
|
||||
Hint "**Robo**: Jetzt würde ich einmal mit `unfold g` die Definition von `g` öffnen."
|
||||
unfold g
|
||||
by_cases 0 ≤ x
|
||||
have h' : 0 ≤ f x
|
||||
unfold f
|
||||
linarith
|
||||
rw [if_pos h', if_pos h]
|
||||
unfold f
|
||||
ring
|
||||
have h' : ¬ (0 ≤ f x)
|
||||
unfold f
|
||||
linarith
|
||||
rw [if_neg h, if_neg h']
|
||||
unfold f
|
||||
ring
|
||||
Hint "**Robo**: Jetzt kannst du nämlich eine Fallunterscheidung
|
||||
machen, `by_cases h : 0 ≤ {x}`.
|
||||
|
||||
**Du**: Damit krieg ich die Fälle `0 ≤ {x}` und `{x} < 0`?
|
||||
|
||||
**Robo**: Genau! Oder präziser `0 ≤ {x}` und `¬(0 ≤ {x})`. Das ist nicht ganz das gleiche, und man
|
||||
könnte mit dem Lemma `not_le` zwischen `¬(0 ≤ {x})` und `0 < {x}` wechseln."
|
||||
by_cases h : 0 ≤ x
|
||||
· Hint "**Robo**: Um das ausrechnen zu können, brauchst du nicht nur `0 ≤ x` sondern auch noch
|
||||
eine neue Annahme `0 ≤ f x`.
|
||||
|
||||
**Du**: Also `have h₂ : _`?"
|
||||
have h' : 0 ≤ f x
|
||||
· unfold f
|
||||
linarith
|
||||
rw [if_pos h]
|
||||
rw [if_pos h']
|
||||
unfold f
|
||||
ring
|
||||
· have h' : ¬ (0 ≤ f x)
|
||||
unfold f
|
||||
linarith
|
||||
rw [if_neg h]
|
||||
rw [if_neg h']
|
||||
unfold f
|
||||
ring
|
||||
|
||||
NewTactic funext by_cases simp_rw linarith
|
||||
|
||||
NewLemma not_le if_pos if_neg
|
||||
LemmaTab "Logic"
|
||||
|
||||
Hint : f ∘ g = g ∘ f =>
|
||||
"
|
||||
**Robo**: Schau mal, die beiden haben zwei Funktionen, eine davon mit stückweiser Definition.
|
||||
|
||||
**Du**: Und ich soll zeigen, dass die beiden vertauschbar sind?
|
||||
|
||||
**Robo**: Genau, am besten wählst du mit `funext x` ein beliebiges Element aus, und zeigst das
|
||||
dann für dieses.
|
||||
"
|
||||
|
||||
-- TODO : This does not trigger.
|
||||
-- TODO: These 5 hints should be mutually exclusive. i.e. they should not trigger
|
||||
-- if a assumption is missing.
|
||||
Hint (x : ℚ) : (f ∘ g) x = (g ∘ f) x =>
|
||||
"
|
||||
**Du**: Ah und jetzt kann ich erst einmal `(g ∘ f) {x}` zu `g (f {x})` umschreiben?
|
||||
Hint (x : ℚ) : (f ∘ g) x = (g ∘ f) x => ""
|
||||
|
||||
**Robo**: Mit `simp_rw` geht das übrigens schneller.
|
||||
|
||||
**Robo**: Und danach willst du eien Fallunterscheidung
|
||||
machen, `by_cases h : 0 ≤ {x}`.
|
||||
|
||||
**Du**: Damit krieg ich die Fälle `0 ≤ {x}` und `{x} < 0`?
|
||||
|
||||
**Robo**: Genau! Oder präziser `0 ≤ {x}` und `¬(0 ≤ {x})`. Das ist nicht ganz das gleiche, und man
|
||||
könnte mit dem Lemma `not_le` zwischen `¬(0 ≤ {x})` und `0 < {x}` wechseln.
|
||||
"
|
||||
|
||||
Hint (x : ℚ) (h : 0 ≤ x) : f (g x) = g (f x) =>
|
||||
"
|
||||
**Robo**: Um das ausrechnen zu können, brauchst du nicht nur `0 ≤ x` sondern auch noch
|
||||
eine neue Annahme `0 ≤ f x`.
|
||||
|
||||
**Du**: Also `have h₂ : _`?
|
||||
"
|
||||
|
||||
Hint (x : ℚ) (h : 0 ≤ x) (h₂ : 0 ≤ f x) : f (g x) = g (f x) =>
|
||||
|
||||
@@ -19,20 +19,16 @@ Plötzlich begegnet ihr einem älteren Wesen mit Fakel. Auf die Frage antwortet
|
||||
open Set Function
|
||||
|
||||
Statement "" : Injective (fun (n : ℤ) ↦ n + 3) := by
|
||||
Hint "**Robo**: `Injective` ist als `∀ \{a b : U}, f a = f b → a = b`
|
||||
definiert, also kannst du mit `intro` anfangen."
|
||||
intro a b
|
||||
Branch
|
||||
intro h
|
||||
Hint "**Robot**: Jetzt musst du wohl `{h}` vereinfachen."
|
||||
Hint (hidden := true) "**Du**: Kann man das wohl vereinfachen?"
|
||||
simp
|
||||
|
||||
NewDefinition Injective
|
||||
|
||||
Hint : Injective (fun (n : ℤ) ↦ n + 3) =>
|
||||
"**Robo**: `Injective` ist als `∀ \{a b : U}, f a = f b → a = b`
|
||||
definiert, also kannst du mit `intro` anfangen.
|
||||
"
|
||||
|
||||
Hint (a b : ℤ) : (fun n => n + 3) a = (fun n => n + 3) b → a = b =>
|
||||
"**Du**: Kann man das wohl vereinfachen?"
|
||||
|
||||
Hint (a b : ℤ) (hab : (fun n => n + 3) a = (fun n => n + 3) b) : a = b =>
|
||||
"**Robot**: Jetzt musst du wohl `{hab}` vereinfachen."
|
||||
LemmaTab "Function"
|
||||
|
||||
Conclusion "**Du** Woa das war ja einfach!"
|
||||
|
||||
@@ -22,10 +22,31 @@ example (f : ℤ → ℤ) (h : StrictMono f) : Injective f := by
|
||||
-- Odd.strictMono_pow
|
||||
|
||||
Statement "" : Injective (fun (n : ℤ) ↦ n^3 + (n + 3)) := by
|
||||
Hint "**Du**: Hmm, das ist etwas schwieriger…
|
||||
|
||||
**Robo**: Aber ich hab einen Trick auf Lager:
|
||||
Das Lemma `StrictMono.injective` sagt, dass jede strikt monotone Funktion injektive ist,
|
||||
und ich habe das Gefühl Monotonie ist hier einfacher zu zeigen."
|
||||
Hint (hidden := true) "**Robo**: `apply` ist wonach du suchst."
|
||||
Branch
|
||||
intro a b
|
||||
Hint "**Robo**: Ich glaube, dieser Weg ist zu steinig. Fang doch nochmals von vorne an!"
|
||||
intro ha
|
||||
Hint "**Robo**: Ich glaube, dieser Weg ist zu steinig. Fang doch nochmals von vorne an!"
|
||||
apply StrictMono.injective
|
||||
Hint "**Du**: Jetzt möchte ich strikte Monotonie von `n ^ 3` und `n + 3` separat zeigen,
|
||||
schliesslich scheint es mir als wär das zweite wieder einfach.
|
||||
|
||||
**Robo**: Dafür hab ich `StrictMono.add` bereit!"
|
||||
apply StrictMono.add
|
||||
Hint "**Du**: Hmm, darauf hab ich jetzt wenig Lust. Gibt's dafür auch was? Das gilt ja nur
|
||||
wenn der Exponent ungerade ist.
|
||||
|
||||
**Robo**: Du könntest mal `Odd.strictMono_pow` versuchen…"
|
||||
apply Odd.strictMono_pow
|
||||
Hint (hidden := true) "**Du**: Ist das nicht ne Trivialität? Warte mal!"
|
||||
trivial
|
||||
Hint "**Du**: Ha! Und dieser Teil funktioniert sicher gleich wie Injektivität vorhin!"
|
||||
intro a b
|
||||
simp
|
||||
|
||||
@@ -33,47 +54,6 @@ NewDefinition Injective
|
||||
NewLemma StrictMono.injective StrictMono.add Odd.strictMono_pow
|
||||
LemmaTab "Function"
|
||||
|
||||
Hint : Injective fun (n : ℤ) => n ^ 3 + (n + 3) =>
|
||||
"**Du**: Hmm, das ist etwas schwieriger…
|
||||
|
||||
**Robo**: Aber ich hab einen Trick auf Lager:
|
||||
Das Lemma `StrictMono.injective` sagt, dass jede strikt monotone Funktion injektive ist,
|
||||
und ich habe das Gefühl Monotonie ist hier einfacher zu zeigen."
|
||||
|
||||
HiddenHint : Injective fun (n : ℤ) => n ^ 3 + (n + 3) =>
|
||||
"**Robo**: `apply` ist wonach du suchst."
|
||||
|
||||
Hint : StrictMono fun (n : ℤ) => n ^ 3 + (n + 3) =>
|
||||
"**Du**: Jetzt möchte ich strikte Monotonie von `n ^ 3` und `n + 3` separat zeigen,
|
||||
schliesslich scheint es mir als wär das zweite wieder einfach.
|
||||
|
||||
**Robo**: Dafür hab ich `StrictMono.add` bereit!"
|
||||
|
||||
Hint : StrictMono fun (x : ℤ) => x ^ 3 =>
|
||||
"**Du**: Hmm, darauf hab ich jetzt wenig Lust. Gibt's dafür auch was? Das gilt ja nur
|
||||
wenn der Exponent ungerade ist.
|
||||
|
||||
**Robo**: Du könntest mal `Odd.strictMono_pow` versuchen…"
|
||||
|
||||
HiddenHint : Odd 3 =>
|
||||
"**Du**: Ist das nicht ne Trivialität? Warte mal!"
|
||||
|
||||
Hint : StrictMono fun (x : ℤ) => x + 3 =>
|
||||
"**Du**: Ha! Und dieser Teil funktioniert sicher gleich wie Injektivität vorhin!"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Hint (a b : ℤ) : a ^ 3 + (a + 3) = b ^ 3 + (b + 3) → a = b =>
|
||||
"**Robo**: Ich glaube, dieser Weg ist zu steinig. Fang doch nochmals von vorne an!
|
||||
"
|
||||
|
||||
Hint (a b : ℤ) (h : a ^ 3 + (a + 3) = b ^ 3 + (b + 3)) : a = b =>
|
||||
"**Robo**: Ich glaube, dieser Weg ist zu steinig. Fang doch nochmals von vorne an!
|
||||
"
|
||||
|
||||
Conclusion "**Du**: Danke vielmals!
|
||||
|
||||
Und damit lässt das Wesen mitten im Gang stehen, wo es weiter über Injektivität nachdenkt."
|
||||
|
||||
@@ -40,31 +40,23 @@ def f : ℕ → ℕ := fun n ↦ if Even n then n^2 else n+1
|
||||
|
||||
Statement "" : ¬ (f + f).Injective := by
|
||||
unfold Injective
|
||||
Hint "**Robo**: Das ist sicher ein Hinweis.
|
||||
|
||||
**Du**: Aber `¬ Injective` sagt mir nichts…
|
||||
|
||||
**Robo**: Könntest du etwas mit `¬ ∀` anfangen? Dann könntest du ja `Injektive` zuerst öffnen.
|
||||
|
||||
**Du**: Darüber haben wir doch mal was gelernt…"
|
||||
Hint (hidden := true) "**Robo**: Das war `push_neg`."
|
||||
push_neg
|
||||
Hint "**Du** Jetzt muss ich einfach ein Gegenbeispiel nennen, oder?
|
||||
|
||||
**Robo** Genau! Welche beiden Zahlen möchtest du denn verwenden?"
|
||||
use 2
|
||||
use 3
|
||||
simp
|
||||
|
||||
Hint : ¬ (Injective (f + f)) =>
|
||||
"
|
||||
**Robo**: Das ist sicher ein Hinweis.
|
||||
|
||||
**Du**: Aber `¬ Injective` sagt mir nichts…
|
||||
|
||||
**Robo**: Könntest du etwas mit `¬ ∀` anfangen? Dann könntest du ja `Injektive` zuerst öffnen.
|
||||
|
||||
**Du**: Darüber haben wir doch mal was gelernt…
|
||||
"
|
||||
|
||||
HiddenHint : ¬ (Injective (f + f)) =>
|
||||
"
|
||||
**Robo**: Das war `push_neg`.
|
||||
"
|
||||
|
||||
Hint : ∃ a b, (f + f) a = (f + f) b ∧ a ≠ b =>
|
||||
"**Du** Jetzt muss ich einfach ein Gegenbeispiel nennen, oder?
|
||||
|
||||
**Robo** Genau! Welche beiden Zahlen möchtest du denn verwenden?"
|
||||
LemmaTab "Function"
|
||||
|
||||
Conclusion
|
||||
"
|
||||
|
||||
@@ -20,18 +20,17 @@ Bevor er dieses aushändigt, will er aber folgendes wissen:
|
||||
open Function
|
||||
|
||||
Statement "" : Surjective (fun (n : ℤ) ↦ n + 1) := by
|
||||
Hint "**Robo**: Die Definition von `Surjective f` ist `∀ y, (∃ x, f x = y)`.
|
||||
|
||||
**Du**: Dann kann ich das auch einfach wie Quantifier behandeln?
|
||||
|
||||
**Robo**: Schieß drauf los!"
|
||||
intro y
|
||||
use y-1
|
||||
simp
|
||||
|
||||
NewDefinition Surjective
|
||||
|
||||
Hint : Surjective (fun (n : ℤ) ↦ n + 1) =>
|
||||
"**Robo**: Die Definition von `Surjective f` ist `∀ y, (∃ x, f x = y)`.
|
||||
|
||||
**Du**: Dann kann ich das auch einfach wie Quantifier behandeln?
|
||||
|
||||
**Robo**: Schieß drauf los!"
|
||||
LemmaTab "Function"
|
||||
|
||||
Conclusion
|
||||
"Der Gelehrte händigt euch schmunzelnd das Buch aus."
|
||||
|
||||
@@ -17,6 +17,10 @@ Introduction
|
||||
open Function
|
||||
|
||||
Statement "" : Bijective (fun (n : ℤ) ↦ n + 1) := by
|
||||
Hint "
|
||||
**Robo** *(flüsternd)*: `Bijectve f` ist als `Injective f ∧ Surjective f` definiert.
|
||||
|
||||
**Du**: Dann ist das ja ganz simpel!"
|
||||
unfold Bijective
|
||||
constructor
|
||||
intro a b
|
||||
@@ -25,14 +29,9 @@ Statement "" : Bijective (fun (n : ℤ) ↦ n + 1) := by
|
||||
use y-1
|
||||
simp
|
||||
|
||||
Hint : Bijective (fun (n : ℤ) ↦ n + 1) =>
|
||||
"**Robo** *(flüsternd)*: `Bijectve f` ist als `Injective f ∧ Surjective f` definiert.
|
||||
|
||||
**Du**: Dann ist das ja ganz simpel!
|
||||
"
|
||||
NewDefinition Bijective
|
||||
LemmaTab "Function"
|
||||
|
||||
Conclusion
|
||||
"Zufrieden drückt euch der Gelehrte eine neue Fackel in die Hand und
|
||||
zeigt euch den Weg nach draußen."
|
||||
|
||||
NewDefinition Bijective
|
||||
|
||||
@@ -7,6 +7,8 @@ Level 9
|
||||
|
||||
Title "Inverse"
|
||||
|
||||
set_option tactic.hygienic false
|
||||
|
||||
Introduction
|
||||
"
|
||||
Eigentlich hast du nur beiläufig Robo gefragt, ob bijektiv nicht auch bedeute, dass
|
||||
@@ -20,39 +22,86 @@ aber er möchte, dass du ihm das hier und jetzt nochmals von Grund auf zeigst.
|
||||
open Function
|
||||
|
||||
--TODO: This is a really hard proof
|
||||
-- bijective_iff_has_inverse
|
||||
Statement "" {A B : Type} (f : A → B) :
|
||||
Statement Function.bijective_iff_has_inverse "" {A B : Type} (f : A → B) :
|
||||
Bijective f ↔ ∃ g, LeftInverse g f ∧ RightInverse g f := by
|
||||
Hint "**Du**: Nah da sagt mir so manches nichts, aber ich kann ja mal mit dem `↔` anfangen,
|
||||
das kenn ich ja schon."
|
||||
constructor
|
||||
intro h
|
||||
use fun x => (h.2 x).choose
|
||||
constructor
|
||||
· intro x
|
||||
simp
|
||||
apply h.1
|
||||
apply Exists.choose_spec (h.2 (f x))
|
||||
· intro x
|
||||
simp
|
||||
apply Exists.choose_spec (h.2 x)
|
||||
intro ⟨g, h₁, h₂⟩
|
||||
constructor
|
||||
· intro a b hab
|
||||
have h : g (f a) = g (f b)
|
||||
· apply congrArg
|
||||
· intro h
|
||||
Hint "**Robo**: Tipp. Teil doch `Bijective` mit `rcases {h} with ⟨hI, hS⟩` in
|
||||
`Injective` und `Surjective` auf!"
|
||||
rcases h with ⟨hI, hS⟩
|
||||
Hint "**Du**: Ja was ist eigentlich die Inverse von `f`…?
|
||||
|
||||
**Robo**: Hast du eine Idee?
|
||||
|
||||
**Du**: Also von der Surjektivität weiss ich, dass für alle `y` ein Urbild existiert
|
||||
und mit der Injektivität könnte ich dann zeigen, dass dieses eindeutig ist.
|
||||
|
||||
**Robo**: Also Schritt für Schritt: Mit `fun y ↦ ({hS} y).choose ` kannst du eine Funktion
|
||||
definieren, die `y` irgendein Urbild zuweist.
|
||||
|
||||
**Du**: Die ist aber nicht wohldefiniert, oder?
|
||||
|
||||
**Robo**: In der Mathe nicht. In Lean geht das ganz gut, aber es ist dann unmöglich etwas
|
||||
darüber zu beweisen, wenn es mehrere Möglichkeiten gäbe."
|
||||
use fun x => (hS x).choose
|
||||
constructor
|
||||
· Hint "**Robo**: fang mal mit `intro` an."
|
||||
intro x
|
||||
Hint "**Du**: kompliziert.
|
||||
|
||||
**Robo**: Aber mit `simp` kannst du es ja etwas vereinfachen."
|
||||
simp
|
||||
Hint "**Du**: Das kann ich jetzt nicht zeigen solange ich nicht weiss, dass nur genau ein
|
||||
Urbild besteht.
|
||||
|
||||
**Robo**: Dann wende doch mit `apply {hI}` die Injektivität an!"
|
||||
apply hI
|
||||
Hint "**Robo**: Dies ist jetzt eine etwas tautologische Aussage. In Lean ist das
|
||||
`Exists.choose_spec`. Konkret `apply Exists.choose_spec (hS (f x))`."
|
||||
apply Exists.choose_spec (hS (f x))
|
||||
· Hint "**Robo**: Gut! Auf zum Rechtsinversen! Fang auch hier wieder mit `intro` an."
|
||||
intro x
|
||||
Hint "**Du**: Kann ich das vereinfachen?"
|
||||
simp
|
||||
Hint "**Du**: Also wieder `Exists.choose_spec`?
|
||||
|
||||
**Robo**: Genau! Diesmal mit dem Argument `(hS x)`."
|
||||
apply Exists.choose_spec (hS x)
|
||||
· Hint "**Robo**: Die eine Richtung ist gezeigt. Jetzt auf zur Rückrichtung!"
|
||||
intro h
|
||||
Hint "**Robo**: Zerlege {h} noch soweit du kannst!"
|
||||
rcases h with ⟨g, h⟩
|
||||
Hint "**Robo**: Das UND auch noch!"
|
||||
rcases h with ⟨hL, hR⟩
|
||||
Hint "**Robo**: Das `Bijective` kannst du auch aufteilen."
|
||||
constructor
|
||||
· Hint "**Robo**: Injektivität ist der schwierige Teil. Fang mal an mit `intro`."
|
||||
intro a b hab
|
||||
Hint "**Robo**: Im nächsten Schritt must du `LeftInverse` brauchen um das Goal
|
||||
zu `g (f a) = g (f b)` zu wechseln: benutze `rw [←{hL} {a}, …]`."
|
||||
rw [← hL a, ← hL b]
|
||||
Hint "**Du**: Wenn die Argumente `f a = f b` gleich sind, ist dann auch `g (f a) = g (f b)`,
|
||||
wie sag ich das?
|
||||
|
||||
**Robo**: Das heisst `apply congrArg`."
|
||||
apply congrArg
|
||||
assumption
|
||||
rw [h₁, h₁] at h
|
||||
assumption
|
||||
· intro x
|
||||
use g x
|
||||
rw [h₂]
|
||||
· Hint "Die Surjektivität sollte einfacher sein."
|
||||
intro x
|
||||
Hint (hidden := true) "**Robo**: Psst, mit `RightInverse g f` weisst du, dass `f (g x) = x`.
|
||||
Hilft das rauszufinden was du hier brauchen musst?"
|
||||
use g x
|
||||
Hint (hidden := true) "**Robo**: Du kannst die `RightInverse`-Annahme einfach mit `rw`
|
||||
benützen."
|
||||
rw [hR]
|
||||
|
||||
NewDefinition LeftInverse RightInverse
|
||||
NewLemma Exists.choose Exists.choose_spec congrArg congrFun
|
||||
DisabledLemma Function.bijective_iff_has_inverse
|
||||
LemmaTab "Logic"
|
||||
|
||||
Hint {A B : Type} (f : A → B) : Bijective f ↔ ∃ g, LeftInverse g f ∧ RightInverse g f =>
|
||||
"**Du**: Nah da sagt mir so manches nichts, aber ich kann ja mal mit dem `↔` anfangen, das kenn
|
||||
ich ja schon."
|
||||
|
||||
Conclusion
|
||||
"Endlich entkommt ihr der Bibliothek.
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
import Adam.Metadata
|
||||
import Mathlib
|
||||
|
||||
Game "Adam"
|
||||
World "Function"
|
||||
Level 10
|
||||
|
||||
Title "Inverse"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Eigentlich hast du nur beiläufig Robo gefragt, ob bijektiv nicht auch bedeute, dass
|
||||
eine Inverse Funktion bestehe. Jetzt steht ihr aber schon seit einer halben Stunde rum
|
||||
und der Gelehrte möchte wissen, wie das den genau ginge.
|
||||
|
||||
Offensichtlich kennt er diese Aussage als `Function.bijective_iff_has_inverse` aus seinen Büchern,
|
||||
aber er möchte, dass du ihm das hier und jetzt nochmals von Grund auf zeigst.
|
||||
"
|
||||
|
||||
open Function
|
||||
set_option pp.rawOnError true
|
||||
|
||||
-- bijective_iff_has_inverse
|
||||
Statement {A B : Type} (f : A → B) :
|
||||
Bijective f ↔ ∃ g, LeftInverse g f ∧ RightInverse g f := by
|
||||
Branch
|
||||
exfalso
|
||||
Hint "Das war eine blöde Idee
|
||||
dd
|
||||
|
||||
ddds
|
||||
"
|
||||
Hint (hidden := true) "constructor"
|
||||
constructor
|
||||
Hint "intro h" -- does not show
|
||||
intro h
|
||||
Hint "rcases h with ⟨h₁, h₂⟩" -- shows too late: 1, 2 after
|
||||
rcases h with ⟨h₁, h₂⟩
|
||||
Hint (strict := true) "let g := fun x => (h₂ x).choose" -- shows correct + 1 after
|
||||
let g := fun x => (h₂ x).choose
|
||||
Hint "use g"
|
||||
use g
|
||||
Hint "constructor" -- does not show
|
||||
constructor
|
||||
Hint "intro x" -- does not show
|
||||
intro x
|
||||
Hint "simp" -- Error updating: Error fetching goals: Rpc error: InternalError: unknown universe metavariable '?_uniq.286465'. Try again.
|
||||
simp
|
||||
Hint "apply h₁"
|
||||
apply h₁
|
||||
Hint "apply Exists.choose_spec (h₂ (f x))"
|
||||
apply Exists.choose_spec (h₂ (f x))
|
||||
Hint "intro y" -- Error updating: Error fetching goals: Rpc error: InternalError: unknown universe metavariable '?_uniq.286465'. Try again.
|
||||
intro y
|
||||
Hint "simp"
|
||||
simp
|
||||
Hint "apply Exists.choose_spec (h₂ y)"
|
||||
apply Exists.choose_spec (h₂ y)
|
||||
Hint "intro ⟨g, h₁, h₂⟩"
|
||||
intro ⟨g, h₁, h₂⟩
|
||||
Hint "constructor"
|
||||
constructor
|
||||
Hint "intro a b hab"
|
||||
intro a b hab
|
||||
Hint (strict := true) "have h : g (f a) = g (f b)"
|
||||
have h : g (f a) = g (f b)
|
||||
Hint "apply congrArg"
|
||||
apply congrArg
|
||||
Hint "assumption"
|
||||
assumption
|
||||
Hint "rw [h₁, h₁] at h"
|
||||
rw [h₁, h₁] at h
|
||||
Hint "assumption"
|
||||
assumption
|
||||
Hint "intro x"
|
||||
intro x
|
||||
Hint "use g x"
|
||||
use g x
|
||||
Hint "rw [h₂]"
|
||||
rw [h₂]
|
||||
|
||||
-- NewDefinition LeftInverse RightInverse
|
||||
-- NewLemma Exists.choose Exists.choose_spec congrArg congrFun
|
||||
-- DisabledLemma Function.bijective_iff_has_inverse
|
||||
|
||||
Hint (A B: Type) (f : A → B) (h : Bijective f) :
|
||||
(∃ g, LeftInverse g f ∧ RightInverse g f) → Bijective f =>
|
||||
"Test"
|
||||
|
||||
Conclusion
|
||||
"Endlich entkommt ihr dem Tempel.
|
||||
|
||||
**Robo**: Da würden mich keine zehn Pferde nochmals hineinbringen!
|
||||
|
||||
**Du**: Von wegen Pferden, wie viele PS hat eigentlich unser Raumschiff?"
|
||||
@@ -9,31 +9,38 @@ Title ""
|
||||
|
||||
open Set
|
||||
|
||||
set_option tactic.hygienic false
|
||||
|
||||
Introduction
|
||||
"
|
||||
Wenn man mit Abildungen auf Mengen arbeitet, muss man in Lean etwas aufpassen, um
|
||||
die Typen (z.B. `(U : Type _)`) und Mengen von diesen Typen (z.B. `(S : Set U)`)
|
||||
zu unterscheiden.
|
||||
|
||||
Abbildungen sind prinzipiell immer auf Typen definiert. Wenn eine Funktion nicht
|
||||
auf dem ganzen Typen definiert ist, hat man prinzipiell zwei Optionen:
|
||||
|
||||
1. Nach dem Motto \"Chunk in, chunk out\" werden in der Mathlib Funktionen
|
||||
oft einfach auf irgendwas gesetzt wenn sie nicht definiert sind, so gibt `1 / 0` in `ℕ`
|
||||
einfach `0`. Dies funktioniert, weil dann alle relevanten Theoreme, die von `x / n`
|
||||
handeln, dann Annahmen der Form `(h : n ≠ 0)` haben.
|
||||
2. Man kann auch Funktionen auf *Subtypen* definieren, also z.B. auf `ℕ+`.
|
||||
|
||||
Das Bild einer Funktion ist eine Menge, die als `f '' S` geschrieben wird.
|
||||
In der Mathe ist das normalerweise als $f(S)$ geschrieben.
|
||||
|
||||
Mit `ext i` kann man Gleichheit von Mengen angehen.
|
||||
"
|
||||
|
||||
|
||||
-- Wenn man mit Abildungen auf Mengen arbeitet, muss man in Lean etwas aufpassen, um
|
||||
-- die Typen (z.B. `(U : Type _)`) und Mengen von diesen Typen (z.B. `(S : Set U)`)
|
||||
-- zu unterscheiden.
|
||||
|
||||
-- Abbildungen sind prinzipiell immer auf Typen definiert. Wenn eine Funktion nicht
|
||||
-- auf dem ganzen Typen definiert ist, hat man prinzipiell zwei Optionen:
|
||||
|
||||
-- 1. Nach dem Motto \"Junk in, junk out\" werden in der Mathlib Funktionen
|
||||
-- oft einfach auf irgendwas gesetzt wenn sie nicht definiert sind, so gibt `1 / 0` in `ℕ`
|
||||
-- einfach `0`. Dies funktioniert, weil dann alle relevanten Theoreme, die von `x / n`
|
||||
-- handeln, dann Annahmen der Form `(h : n ≠ 0)` haben.
|
||||
-- 2. Man kann auch Funktionen auf *Subtypen* definieren, also z.B. auf `ℕ+`.
|
||||
|
||||
|
||||
-- /- Image of Union -/
|
||||
-- lemma image_unionₓ
|
||||
|
||||
Statement
|
||||
""
|
||||
(S T : Set ℕ) (f : ℕ → ℕ) : (f '' S) ∪ (f '' T) = f '' (S ∪ T) := by
|
||||
Hint "Fang mal mit `ext i` an."
|
||||
ext i
|
||||
rw [mem_union]
|
||||
simp_rw [mem_image]
|
||||
@@ -63,3 +70,6 @@ Statement
|
||||
constructor
|
||||
assumption
|
||||
assumption
|
||||
|
||||
NewTactic ext
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -7,15 +7,27 @@ Level 2
|
||||
|
||||
Title ""
|
||||
|
||||
open Set
|
||||
|
||||
Introduction
|
||||
"
|
||||
Das Urbild einer Menge `U` unter einer Funktion `f` ist mit `f ⁻¹' U` bezeichnet.
|
||||
|
||||
Note: `f ⁻¹` ist das abstrakte, gruppentheoretische Inverse von `f`, was generell nicht existieren muss,
|
||||
deshalb wurde die andere Notation hier gewählt
|
||||
|
||||
"
|
||||
|
||||
Statement
|
||||
""
|
||||
(U : Set ℕ) (f : ℕ → ℕ) : U ⊆ f ⁻¹' (f '' U) := by
|
||||
Hint "Fang wieder mal mit `intro` an."
|
||||
intro x hx
|
||||
Hint "Mit `rw [preimage]` kannst du sehen, wie das Urbild definiert ist."
|
||||
rw [preimage]
|
||||
Hint "Also musst du jetzt ein Element `y` angeben sodass `f y` in `f '' U` liegt."
|
||||
use x
|
||||
constructor
|
||||
assumption
|
||||
rfl
|
||||
|
||||
NewDefinition Set.preimage
|
||||
|
||||
@@ -9,6 +9,8 @@ Title ""
|
||||
|
||||
Introduction
|
||||
"
|
||||
Wenn man Aussagen über Familien von Mengen machen will, macht man das mit
|
||||
`(N : I → Set V)`, also also Funktionen von einer Indexmenge.
|
||||
"
|
||||
|
||||
Statement
|
||||
|
||||
@@ -14,17 +14,19 @@ import Adam.Levels.SetTheory.L13_Insert
|
||||
import Adam.Levels.SetTheory.L14_SetOf
|
||||
import Adam.Levels.SetTheory.L15_Powerset
|
||||
import Adam.Levels.SetTheory.L16_Disjoint
|
||||
import Adam.Levels.SetTheory.L17_SetOf
|
||||
import Adam.Levels.SetTheory.L18_SetOf
|
||||
import Adam.Levels.SetTheory.L19_Subtype
|
||||
|
||||
-- import Adam.Levels.SetTheory.L17_SetOf
|
||||
-- import Adam.Levels.SetTheory.L18_SetOf
|
||||
-- import Adam.Levels.SetTheory.L19_Subtype
|
||||
|
||||
Game "Adam"
|
||||
World "SetTheory"
|
||||
Title "Mengenlehre"
|
||||
|
||||
Introduction
|
||||
"Der größere der beiden Monde sieht dunkelrot und karg aus. Trotzdem sollen dort nomadische
|
||||
"[Note: von hier an sind die Levels leider noch nicht vollständig. Evt. müsst ihr etwas ausprobieren oder
|
||||
fragen, wenn ihr nicht weiterkommt.]
|
||||
|
||||
Der größere der beiden Monde sieht dunkelrot und karg aus. Trotzdem sollen dort nomadische
|
||||
Gesellschaften wohnen, die sich in der Einöde zurechtfinden.
|
||||
|
||||
Ihr steuert einen der wenigen befestigten Standorte am Fusse eines Berges an.
|
||||
|
||||
@@ -54,4 +54,6 @@ Statement Set.mem_univ "" {A : Type} (x : A) : x ∈ (univ : Set A) := by
|
||||
**Du**: Also das ist ja dann `trivial`. Hoffentlich sehen die das hier auch so…"
|
||||
trivial
|
||||
|
||||
LemmaTab "Set"
|
||||
|
||||
Conclusion "**Mengea**: Ja das stimmt schon. Dann wünsche ich euch viel Erfolg auf eurer Reise!"
|
||||
|
||||
@@ -27,6 +27,7 @@ Statement Set.not_mem_empty "" {A : Type} (x : A) :
|
||||
tauto
|
||||
|
||||
NewLemma Set.mem_univ
|
||||
LemmaTab "Set"
|
||||
|
||||
Conclusion "Der Junge rennt weiter.
|
||||
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace MySet
|
||||
|
||||
open Set
|
||||
|
||||
Statement (A : Set ℕ) : A ⊆ univ := by
|
||||
Statement Set.subset_univ (A : Set ℕ) : A ⊆ univ := by
|
||||
Hint "**Robo**: `A ⊆ B` ist als `∀ x, x ∈ A → x ∈ B` definiert.
|
||||
|
||||
**Du**: Also kann ich mit `intro` anfangen, wie ich das bei einem `∀` funktioniert?
|
||||
@@ -43,6 +43,7 @@ Statement (A : Set ℕ) : A ⊆ univ := by
|
||||
|
||||
DisabledTactic tauto simp
|
||||
NewDefinition Symbol.Subset
|
||||
LemmaTab "Set"
|
||||
|
||||
Conclusion "Damit drehen sich die beiden Mädchen um und folgen dem Jungen."
|
||||
|
||||
|
||||
@@ -52,4 +52,5 @@ Statement Set.subset_empty_iff {A : Type _} (s : Set A) :
|
||||
rw [h]
|
||||
|
||||
DisabledTactic tauto
|
||||
NewLemma Set.Subset.antisymm Set.Subset.antisymm_iff Set.empty_subset
|
||||
NewLemma Set.Subset.antisymm Set.Subset.antisymm_iff Set.empty_subset Set.subset_univ
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -32,3 +32,4 @@ Statement Set.eq_empty_iff_forall_not_mem
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
NewLemma Set.subset_empty_iff
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -34,3 +34,4 @@ Statement Set.nonempty_iff_ne_empty
|
||||
|
||||
NewLemma ne_eq Set.eq_empty_iff_forall_not_mem
|
||||
NewDefinition Set.Nonempty
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -27,3 +27,4 @@ Statement
|
||||
simp
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -12,12 +12,12 @@ Title "Schnittmenge und Vereinigung"
|
||||
|
||||
Introduction
|
||||
"
|
||||
Ansonsten gibt es jegliche Lemmas in
|
||||
|
||||
`import Mathlib.Data.Set.Basic`
|
||||
|
||||
Ansonsten gibt es jegliche Lemmas in der Mathlib
|
||||
die beim Umgang mit diesen Operationen weiterhelfen. Schaue in der Bibliothek auf
|
||||
der Seite nach Lemmas, die dir hier weiterhelfen!
|
||||
|
||||
Denk daran, die lemma Namen sind blockweise aus der Aussage konstruiert. Ein lemma mit
|
||||
der Aussage `C \\ (A ∩ B) + …` wird vermutlich mit `diff_inter_…` anfangen.
|
||||
"
|
||||
|
||||
open Set
|
||||
@@ -26,9 +26,15 @@ Statement
|
||||
""
|
||||
(A B : Set ℕ) : univ \ (A ∩ B) = (univ \ A) ∪ (univ \ B) ∪ (A \ B) := by
|
||||
rw [diff_inter]
|
||||
Hint (hidden := true) "mit `union_assoc` und `union_diff_distrib` kannst du
|
||||
auf der rechten Seite weiterkommen."
|
||||
rw [union_assoc]
|
||||
rw [←union_diff_distrib]
|
||||
rw [univ_union]
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
DisabledTactic tauto
|
||||
NewLemma Set.diff_inter Set.union_assoc Set.union_diff_distrib Set.univ_union
|
||||
LemmaTab "Set"
|
||||
|
||||
Conclusion "Wie du vielleicht bemerkt hast, könnte `tauto` sowas automatisch lösen."
|
||||
|
||||
@@ -16,18 +16,25 @@ sind `not_mem_compl_iff` und `compl_eq_univ_diff`.
|
||||
|
||||
open Set
|
||||
|
||||
#check not_mem_compl_iff
|
||||
#check compl_eq_univ_diff
|
||||
|
||||
Statement
|
||||
""
|
||||
(A : Set ℕ) (h : Aᶜ ⊆ A) : A = univ := by
|
||||
Hint "Start doch mit `apply Subset.antisymm`."
|
||||
apply Subset.antisymm
|
||||
simp only [subset_univ]
|
||||
Hint "Da `⊆` als `∀x, x ∈ A → x ∈ B ` definiert ist, fängst du
|
||||
am besten mit `intro` an."
|
||||
intros x hx
|
||||
Hint "Eine Möglichkeit ist, eine Fallunterscheidung zu machen: `by_cases g: {x} ∈ {A}ᶜ`."
|
||||
by_cases h4 : x ∈ Aᶜ
|
||||
exact mem_of_subset_of_mem h h4
|
||||
rw [←not_mem_compl_iff]
|
||||
exact h4
|
||||
Hint "Hier könnte `mem_of_subset_of_mem` hilfreich werden."
|
||||
apply mem_of_subset_of_mem h
|
||||
assumption
|
||||
Hint "Diese Richtung geben wir als Lemma: `not_mem_compl_iff`."
|
||||
rw [not_mem_compl_iff] at h4
|
||||
assumption
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
NewLemma Set.not_mem_compl_iff Set.mem_of_subset_of_mem Set.compl_eq_univ_diff
|
||||
DisabledTactic tauto
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -43,6 +43,9 @@ open Set
|
||||
|
||||
Statement
|
||||
(A B C : Set ℕ) : (A \ B)ᶜ ∩ (C \ B)ᶜ = ((univ \ A) \ C) ∪ (univ \ Bᶜ) := by
|
||||
Hint "Oft kann es auch nützlich sein, mit `rw [← …]` rückwärts umzuschreiben.
|
||||
Der ganze Level ist mit `rw`/`simp_rw` und den Lemmas in deiner Bibliothek
|
||||
lösbar."
|
||||
rw [←compl_union]
|
||||
rw [←union_diff_distrib]
|
||||
rw [diff_diff]
|
||||
@@ -51,7 +54,8 @@ Statement
|
||||
rw [diff_eq_compl_inter]
|
||||
rw [inter_comm]
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
|
||||
-- TODOs
|
||||
-- Lemmas compl_union compl_inter mem_compl_iff
|
||||
OnlyTactic rw simp_rw tauto trivial assumption rfl «have» «suffices»
|
||||
NewTactic simp_rw
|
||||
LemmaTab "Set"
|
||||
NewLemma Set.mem_compl_iff Set.compl_union Set.diff_diff Set.compl_inter
|
||||
Set.diff_eq_compl_inter Set.inter_comm
|
||||
|
||||
@@ -19,18 +19,20 @@ Zudem kann man mit `rw [ssubset_def]` explizit die Definition einsetzen.
|
||||
Note: `rw [subset_def]` macht das gleiche für `⊆`.
|
||||
"
|
||||
|
||||
--open Set
|
||||
open Set
|
||||
|
||||
Statement
|
||||
""
|
||||
(A B : Set ℕ) (h : A ⊂ B) : ∃ x, x ∈ B \ A := by
|
||||
cases' h with h₁ h₂
|
||||
rw [Set.subset_def] at h₂
|
||||
rw [subset_def] at h₂
|
||||
rw [not_forall] at h₂
|
||||
cases' h₂ with x hx
|
||||
use x
|
||||
rw [not_imp] at hx
|
||||
rw [Set.mem_diff]
|
||||
rw [mem_diff]
|
||||
exact hx
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
NewLemma Set.subset_def Set.ssubset_def not_imp Set.mem_diff
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -12,7 +12,7 @@ Introduction
|
||||
"
|
||||
Nun schauen wir uns konkrete Mengen an. Man schreibt diese mit
|
||||
geschweiften Klammern: `{0, 4, 117, 3}`. Meistens muss man
|
||||
den Typ explizit angeben, weil lein nicht weiss, ob man mit `Set` (Mengen)
|
||||
den Typ explizit angeben, weil Lean nicht weiss, ob man mit `Set` (Mengen)
|
||||
oder `Finset` (endliche Mengen) arbeiten möchte: `({4, 9} : Set ℕ)`.
|
||||
|
||||
`Finset` schauen wir uns später an.
|
||||
@@ -28,8 +28,9 @@ Die folgende Aufgabe ist entsprechend mit `rfl` lösbar.
|
||||
open Set
|
||||
|
||||
Statement
|
||||
"Die Menge $\\{4, 9\\}}$ ist per Definition \\{4}\\cup\\{9\\}." :
|
||||
"Die Menge $\\{4, 9\\}$ ist per Definition $\\{4}\\cup\\{9\\}$." :
|
||||
({4, 9} : Set ℕ) = Set.insert 4 {9} := by
|
||||
rfl
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
OnlyTactic rfl
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -18,7 +18,7 @@ einfaches Rezept:
|
||||
simp_rw [mem_insert_iff, mem_singleton_iff] at *
|
||||
```
|
||||
|
||||
vereinfacht Aussagen der Form `6 ∈ { 0, 6, 1}` zu `(6 = 0) ∨ (6 = 6) ∨ (6 = 1)`,
|
||||
vereinfacht Aussagen der Form `6 ∈ {0, 6, 1}` zu `(6 = 0) ∨ (6 = 6) ∨ (6 = 1)`,
|
||||
und dann kann `tauto` diese Aussage beweisen.
|
||||
|
||||
Bei `⊆` kann man wie schon vorher zuerst mit `intro x hx` die Definition
|
||||
@@ -28,12 +28,12 @@ auseinandernehmen und dann gleich vorgehen.
|
||||
|
||||
open Set
|
||||
|
||||
Statement
|
||||
"" :
|
||||
Statement :
|
||||
({2, 3, 5} : Set ℕ) ⊆ {4, 2, 5, 7, 3} := by
|
||||
Hint "Fang wieder mit `rw [subset_def]` oder direkt mit `intro` an."
|
||||
intro x hx
|
||||
simp_rw [mem_insert_iff, mem_singleton_iff] at *
|
||||
tauto
|
||||
|
||||
NewTactic simp_rw intro tauto rw
|
||||
--Lemmas Subset.antisymm_iff empty_subset
|
||||
NewLemma Set.mem_insert_iff Set.mem_singleton_iff
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -25,11 +25,14 @@ dieses Element erfüllt ist.
|
||||
|
||||
open Set
|
||||
|
||||
Statement
|
||||
"" :
|
||||
3 ∈ {n : ℕ | Odd n} := by
|
||||
Statement : 3 ∈ {n : ℕ | Odd n} := by
|
||||
rw [mem_setOf]
|
||||
Hint (hidden := true) "**Robo**: Zur Erinnerung, wenn du nicht mehr weisst, wie `Odd` definiert
|
||||
ist, benutze `rw [Odd]`."
|
||||
Branch
|
||||
rw [Odd]
|
||||
use 1
|
||||
ring
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
NewLemma Set.mem_setOf
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -27,14 +27,24 @@ open Set
|
||||
Statement
|
||||
"" (X Y : Set ℕ):
|
||||
𝒫 X ∪ 𝒫 Y ⊆ 𝒫 (X ∪ Y) := by
|
||||
Hint "**Robo**: Fang mal mit `intro` an, wie das bei `⊆` fast immer der Fall ist."
|
||||
intro A hA
|
||||
Hint "**Robo**: Als nächstes must du noch die Annahme `{A} ∈ 𝒫 X ∪ 𝒫 Y` zu
|
||||
`{A} ∈ (𝒫 X) ∨ {A} ∈ (𝒫 Y)` wechseln. Dafür kennst du schon ein Lemma."
|
||||
rw [mem_union] at hA
|
||||
Hint "**Robo**: Jetzt wär der Zeitpunkt um `mem_powerset_iff` mal überall anzuwenden."
|
||||
simp_rw [mem_powerset_iff] at *
|
||||
rcases hA with hA | hA
|
||||
apply subset_union_of_subset_left
|
||||
assumption
|
||||
apply subset_union_of_subset_right
|
||||
assumption
|
||||
Hint "**Robo**: Jetzt kann `tauto` den rest übernehmen, vielleicht solltest du diese
|
||||
Hilfe annehmen.
|
||||
Wenn nicht, brauchst du vermutlich die Lemmas `Set.subset_union_of_subset_left`
|
||||
und `Set.subset_union_of_subset_right`"
|
||||
Branch
|
||||
rcases hA with hA | hA
|
||||
apply subset_union_of_subset_left
|
||||
assumption
|
||||
apply subset_union_of_subset_right
|
||||
assumption
|
||||
tauto
|
||||
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
NewLemma Set.mem_powerset_iff Set.subset_union_of_subset_left Set.subset_union_of_subset_right
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -25,15 +25,23 @@ das gleiche.
|
||||
|
||||
open Set
|
||||
|
||||
Statement
|
||||
"" :
|
||||
Statement :
|
||||
¬Disjoint ({n : ℤ | ∃ k, n = 2 * k} : Set ℤ) ({3, 5, 6, 9, 11} : Set ℤ) := by
|
||||
unfold Disjoint
|
||||
rw [not_forall] -- why not `push_neg`?
|
||||
Hint "**Robo**: Öffne als erstes mal `Disjoint`."
|
||||
rw [Disjoint]
|
||||
Branch
|
||||
rw [not_forall] -- why not `push_neg`?
|
||||
push_neg
|
||||
Hint "**Robo**: Das sieht jetzt ein bisschen gefürchig aus, aber das ist einfach ein `∃`.
|
||||
Was du jetzt angeben musst, ist eine Menge, die Teilmenge beider Mengen
|
||||
`\{n : ℤ | ∃ k, n = 2 * k}` und `\{3, 5, 6, 9, 11}` ist.
|
||||
"
|
||||
Hint (hidden := true) "**Robo**: Versuch einmal `use \{6}`."
|
||||
use {6}
|
||||
Hint "**Robo**: Schau mal wie weit `simp` kommt."
|
||||
simp
|
||||
use 3
|
||||
ring
|
||||
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
NewDefinition Disjoint
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -33,5 +33,5 @@ Statement
|
||||
rw [hx]
|
||||
ring
|
||||
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
NewLemma Set.setOf_or Set.setOf_and Set.mem_inter_iff
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -26,6 +26,6 @@ open Set
|
||||
Statement
|
||||
"" (S : Set ℤ) :
|
||||
{ x ∈ (S : Set ℤ) | 0 ≤ x} ⊆ S := by
|
||||
library_search
|
||||
simp
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -24,3 +24,4 @@ Statement
|
||||
ring
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -23,3 +23,4 @@ Statement
|
||||
"" : True := sorry
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -24,3 +24,4 @@ Statement
|
||||
ring
|
||||
|
||||
NewTactic constructor intro rw assumption rcases simp tauto trivial
|
||||
LemmaTab "Set"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import GameServer.Commands
|
||||
import Adam.TacticDocs
|
||||
import Adam.LemmaDocs
|
||||
import Adam.DefinitionDocs
|
||||
import Adam.Doc.Tactics
|
||||
import Adam.Doc.Lemmas
|
||||
import Adam.Doc.Definitions
|
||||
import Mathlib.Init.Data.Nat.Basic -- Imports the notation ℕ.
|
||||
import Adam.Modification.Tactic
|
||||
|
||||
Reference in New Issue
Block a user