Files
AlgebraInLean/Book/Degrees.lean
T
2026-08-12 17:05:26 +02:00

280 lines
12 KiB
Lean4
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import VersoManual
import Manual.Meta
-- Minimal-Imports statt `import Mathlib`, ermittelt mit
-- `#min_imports`.
import Mathlib.LinearAlgebra.FreeModule.PID
import Mathlib.RingTheory.Flat.TorsionFree
import Mathlib.RingTheory.Henselian
import Mathlib.RingTheory.RegularLocalRing.Defs
import Mathlib.RingTheory.SimpleRing.Principal
open Verso.Genre
open Verso.Genre.Manual.InlineLean
set_option pp.rawOnError true
set_option verso.docstring.allowMissing true
#doc (Manual) "Körpererweiterungen und die Gradformel" =>
%%%
htmlSplit := .never
tag := "gradformel"
file := "gradformel"
%%%
Dieses Kapitel übersetzt die Gradformel aus Kapitel 3 des Skripts nach
Lean unsere erste Begegnung mit linearer Algebra: Basen, Dimensionen
und Körpererweiterungen als Vektorräume.
# Das Mathlib-Wörterbuch
* Eine Körpererweiterung $`L/K` ist in Mathlib eine
`Algebra K L`-Instanz zwischen zwei Körpern $`L` wird damit
insbesondere ein $`K`-Vektorraum, genau wie im Skript.
* Eine Kette $`K \subseteq L \subseteq M` besteht aus drei
Algebra-Instanzen und der Verträglichkeitsbedingung
`IsScalarTower K L M` (erst nach $`L`, dann nach $`M` einbetten
ist dasselbe wie direkt nach $`M`“).
* Der Grad $`[L:K]` heißt `Module.finrank K L`. Achtung, hier weicht
die Konvention vom Skript ab: `finrank` hat Werte in $`\mathbb{N}`,
und unendlichdimensionale Erweiterungen bekommen den Wert 0 wo
das Skript in seiner Fußnote mit $`\infty` rechnet, rechnet Mathlib
mit 0. „$`[L:K]` ist endlich ist die Typklasse
`FiniteDimensional K L`.
# Die Gradformel
Satz 3.6.1 des Skripts, mit Beweis:
> *Satz 3.6.1 (Gradformel).* Es sei $`K \subseteq L \subseteq M` eine
Kette von Körpererweiterungen. Dann gilt die Gleichung
$`[M:K] = [M:L] \cdot [L:K]`.
> _Beweis._ Wir kümmern uns zuerst um die unendlichen Fälle. Es
seien jetzt also $`a := [L:K]` und $`b := [M:L]` beide endlich.
Wähle Basen $`\ell_1, \dots, \ell_a` von $`L` als
$`K`-Vektorraum und $`m_1, \dots, m_b` von $`M` als
$`L`-Vektorraum. Ich behaupte, dass die $`a \cdot b` Produkte
$`(\ell_i \cdot m_j)` eine Basis von $`M` als $`K`-Vektorraum
bilden; damit ist dann sofort $`[M:K] = a \cdot b` gezeigt.
Die unendlichen Fälle entfallen in unserer Fassung, weil wir
Endlichkeit voraussetzen; in Mathlibs 0-Konvention gilt die Formel
sogar uneingeschränkt (`Module.finrank_mul_finrank`).
Die Behauptung mit den beiden Beweisschritten Die Produkte bilden
ein Erzeugendensystem und Die Produkte sind linear unabhängig
ist in Mathlib die Konstruktion `Basis.smulTower`: Aus einer Basis
$`\ell` von $`L/K` und einer Basis $`m` von $`M/L` baut sie die
Basis $`(\ell_i \cdot m_j)` von $`M/K` (das Lemma
`Basis.smulTower_apply` bestätigt,
dass die Basiselemente wirklich die Produkte sind). Der Rest ist
Abzählen der Indexmenge. Wer der Mathlib nicht trauen will, findet
im letzten Abschnitt dieses Kapitels den vollständigen Beweis, Satz
für Satz aus dem Skript übersetzt.
```lean
theorem gradformel (K L M : Type*) [Field K] [Field L]
[Field M] [Algebra K L] [Algebra L M] [Algebra K M]
[IsScalarTower K L M]
[FiniteDimensional K L] [FiniteDimensional L M] :
Module.finrank K M
= Module.finrank L M * Module.finrank K L := by
-- „Wähle Basen ℓ₁, …, _a von L als K-Vektorraum und
-- m₁, …, m_b von M als L-Vektorraum.“
let := Module.finBasis K L
let m := Module.finBasis L M
-- „Ich behaupte, dass die a·b Produkte (ℓᵢ·mⱼ) eine
-- Basis von M als K-Vektorraum bilden …“
let basis := .smulTower m
-- „… damit ist dann sofort [M:K] = a·b gezeigt.“
rw [Module.finrank_eq_card_basis basis, Fintype.card_prod,
Fintype.card_fin, Fintype.card_fin, mul_comm]
```
# Bemerkungen
Die beiden Beweisschritte des Skripts stecken im Beweis von
`Basis.smulTower`: Das Einsetzen im Erzeugendensystem-Schritt und
das Umsortieren im Unabhängigkeits-Schritt werden dort durch die
Komposition der Koordinatenabbildungen erledigt
`Basis.smulTower_repr` sagt, dass die (i,j)-Koordinate von `x` gerade
die i-te Koordinate der j-ten Koordinate ist: exakt das `μᵢⱼ` aus dem
Skript.
# Übungsaufgabe
Das erste Korollar des Skripts zur Gradformel:
> Es sei $`K \subseteq L \subseteq M` eine Kette von
Körpererweiterungen. Wenn $`[M:K]` endlich ist, dann ist
$`[L:K]` endlich, und sogar ein Teiler von $`[M:K]`.
Der erste Teil ist `Module.Finite.left` (und `Module.Finite.right`
liefert die Endlichkeit von $`[M:L]`) beide müssen mit `have := …`
in den Kontext geholt werden, damit die Instanzsuche sie sieht. Der
Teiler-Teil ist die Übung: Öffnen Sie `AlgebraInLean/Degrees.lean`
und ersetzen Sie das `sorry` durch einen Beweis mit `gradformel`.
```lean
theorem grad_teilt (K L M : Type*) [Field K] [Field L]
[Field M] [Algebra K L] [Algebra L M] [Algebra K M]
[IsScalarTower K L M] [FiniteDimensional K M] :
Module.finrank K L Module.finrank K M := by
sorry
```
# Der vollständige Beweis
Der Beweis oben ist ehrlich, aber kurz: Die eigentliche Arbeit
die Behauptung über die Produkte haben wir bei `Basis.smulTower`
eingekauft. Zum Abschluss führen wir den Skript-Beweis selbst aus,
Satz für Satz. Die unendlichen Fälle entfallen wie zuvor, weil wir
Endlichkeit voraussetzen.
Wir formulieren die beiden Beweisschritte als eigenständige Lemmata.
Statt der nummerierten Basen $`\ell_1, \dots, \ell_a` und
$`m_1, \dots, m_b` des Skripts sprechen wir von Basen `` und `m`,
die über die Indexmengen `Fin a` und `Fin b` laufen; die Familie der
Produkte $`(\ell_i \cdot m_j)` ist dann über Paare
`p : Fin a × Fin b` indiziert.
Der erste Schritt des Skripts:
> _Schritt 1: Die Produkte bilden ein Erzeugendensystem._ Es sei ein
Element $`m M` gegeben. Schreibe $`m` als $`L`-Linearkombination
der Basis $`m_1, , m_b`, nämlich $`m = \sum_j λ_j \cdot m_j` mit
$`λ_j L`, und schreibe danach jeden der Koeffizienten $`λ_j` als
$`K`-Linearkombination der Basis $`\ell_1, , \ell_a`, nämlich
$`λ_j = \sum_i μ_{ij} \cdot \ell_i` mit $`μ_{ij} K`. Einsetzen
liefert $`m = \sum_{i,j} μ_{ij} \cdot (\ell_i \cdot m_j)`.
In Lean heißen die Koeffizienten $`λ_j` und $`μ_{ij}` gerade
`m.repr x j` und `.repr (m.repr x j) i` das Schreibe als
Linearkombination des Skripts ist das Lemma `Basis.sum_repr`. Das
Einsetzen ist eine kleine Rechnung mit dem Distributivgesetz
`Finset.sum_smul` und der Turmbedingung `smul_assoc`,
$`(μ \cdot \ell) \cdot m = μ \cdot (\ell \cdot m)`.
```lean
theorem produkte_erzeugen {K L M : Type*} [Field K]
[Field L] [Field M] [Algebra K L] [Algebra L M]
[Algebra K M] [IsScalarTower K L M] {a b : }
( : Module.Basis (Fin a) K L)
(m : Module.Basis (Fin b) L M) :
Submodule.span K
(Set.range
fun p : Fin a × Fin b => p.1 m p.2) := by
-- „Es sei ein Element m ∈ M gegeben.“
intro x _
-- „Schreibe m als L-Linearkombination der Basis
-- m₁, …, m_b, und schreibe danach jeden der
-- Koeffizienten λⱼ als K-Linearkombination der Basis
-- ℓ₁, …, _a. Einsetzen liefert m = ∑ μᵢⱼ·(ℓᵢ·mⱼ).“
have einsetzen : x = j, i,
.repr (m.repr x j) i ( i m j) := by
conv_lhs => rw [ m.sum_repr x]
refine Finset.sum_congr rfl fun j _ => ?_
conv_lhs => rw [ .sum_repr (m.repr x j)]
rw [Finset.sum_smul]
exact Finset.sum_congr rfl fun i _ => smul_assoc ..
-- Eine K-Linearkombination der Produkte liegt im
-- Erzeugnis.
rw [einsetzen]
exact Submodule.sum_mem _ fun j _ =>
Submodule.sum_mem _ fun i _ =>
Submodule.smul_mem _ _
(Submodule.subset_span (i, j), rfl)
```
Der zweite Schritt:
> _Schritt 2: Die Produkte sind linear unabhängig._ Es sei eine
$`K`-lineare Relation gegeben, das heißt
$`0 = \sum_{i,j} μ_{ij} \cdot (\ell_i \cdot m_j)` mit
$`μ_{ij} K`. Umsortieren liefert
$`0 = \sum_j \bigl(\sum_i μ_{ij} \cdot \ell_i\bigr) \cdot m_j`.
Dies ist eine $`L`-lineare Relation unter den Basiselementen
$`m_j`, also verschwinden alle Koeffizienten: Für jeden Index
$`j` ist $`\sum_i μ_{ij} \cdot \ell_i = 0`. Das wiederum ist
jeweils eine $`K`-lineare Relation unter den Basiselementen
$`\ell_i`, also ist $`μ_{ij} = 0` für alle Indizes $`i` und $`j`.
Das Lemma `Fintype.linearIndependent_iff` übersetzt linear
unabhängig in genau die Sprechweise des Skripts: Jede Relation hat
verschwindende Koeffizienten. Wir benutzen es dreimal einmal in
jede Richtung für die Basen `m` und ``, und einmal für die zu
beweisende Aussage selbst.
```lean
theorem produkte_unabhaengig {K L M : Type*} [Field K]
[Field L] [Field M] [Algebra K L] [Algebra L M]
[Algebra K M] [IsScalarTower K L M] {a b : }
( : Module.Basis (Fin a) K L)
(m : Module.Basis (Fin b) L M) :
LinearIndependent K
fun p : Fin a × Fin b => p.1 m p.2 := by
-- „Es sei eine K-lineare Relation gegeben, das heißt
-- 0 = ∑ μᵢⱼ·(ℓᵢ·mⱼ), wobei μᵢⱼ ∈ K.“
rw [Fintype.linearIndependent_iff]
intro μ relation p
-- Schreibe die Summe über alle Paare als Doppelsumme.
have relation' :
i, j, μ (i, j) ( i m j) = 0 := by
simpa [Fintype.sum_prod_type] using relation
-- „Umsortieren liefert 0 = ∑ⱼ (∑ᵢ μᵢⱼ·ℓᵢ)·mⱼ.“
have umsortiert :
j, ( i, μ (i, j) i) m j = 0 := by
calc j, ( i, μ (i, j) i) m j
= j, i, μ (i, j) ( i m j) := by
simp_rw [Finset.sum_smul, smul_assoc]
_ = i, j, μ (i, j) ( i m j) :=
Finset.sum_comm
_ = 0 := relation'
-- „Dies ist eine L-lineare Relation unter den Basis-
-- elementen mⱼ, also verschwinden alle Koeffizienten:
-- Für jeden Index j ist ∑ᵢ μᵢⱼ·ℓᵢ = 0.“
have koeff : j, i, μ (i, j) i = 0 :=
Fintype.linearIndependent_iff.mp m.linearIndependent _
umsortiert
-- „Das wiederum ist jeweils eine K-lineare Relation
-- unter den Basiselementen ℓᵢ, also ist μᵢⱼ = 0 für
-- alle Indizes.“
exact Fintype.linearIndependent_iff.mp
.linearIndependent _ (koeff p.2) p.1
```
Zum Schluss der Zusammenbau, wie im Skript angekündigt:
> Ich behaupte, dass die $`a \cdot b` Produkte
$`(\ell_i \cdot m_j)_{1 i a,\ 1 j b}` eine Basis von $`M`
als $`K`-Vektorraum bilden; damit ist dann sofort
$`[M:K] = a \cdot b` gezeigt.
Die Konstruktion `Module.Basis.mk` baut aus unseren beiden Lemmata
linear unabhängig und erzeugend eine Basis; das sofort gezeigt
ist wieder das Abzählen der Indexmenge `Fin a × Fin b`.
```lean
theorem gradformel_vollstaendig
(K L M : Type*) [Field K] [Field L] [Field M]
[Algebra K L] [Algebra L M] [Algebra K M]
[IsScalarTower K L M]
[FiniteDimensional K L] [FiniteDimensional L M] :
Module.finrank K M
= Module.finrank L M * Module.finrank K L := by
-- „Wähle Basen ℓ₁, …, _a von L als K-Vektorraum und
-- m₁, …, m_b von M als L-Vektorraum.“
let := Module.finBasis K L
let m := Module.finBasis L M
-- „Ich behaupte, dass die a·b Produkte (ℓᵢ·mⱼ) eine Basis
-- von M als K-Vektorraum bilden …“
let basis : Module.Basis (Fin _ × Fin _) K M :=
Module.Basis.mk (produkte_unabhaengig m)
(produkte_erzeugen m)
-- „… damit ist dann sofort [M:K] = a·b gezeigt.“
rw [Module.finrank_eq_card_basis basis, Fintype.card_prod,
Fintype.card_fin, Fintype.card_fin, mul_comm]
```