Skip to content

Commit 89e3baf

Browse files
committed
chore(LinearAlgebra/Dimension): generalize and golf (leanprover-community#32339)
LinearAlgebra/Dimension/Finite.lean: generalize Ring/AddCommGroup to Semiring/AddCommMonoid whenever possible LinearAlgebra/Dimension/DivisionRing.lean: generalize DivisionRing to OrzechProperty, move to new file OrzechProperty.lean
1 parent 7a95488 commit 89e3baf

10 files changed

Lines changed: 130 additions & 143 deletions

File tree

Mathlib.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4502,6 +4502,7 @@ public import Mathlib.LinearAlgebra.Dimension.Free
45024502
public import Mathlib.LinearAlgebra.Dimension.FreeAndStrongRankCondition
45034503
public import Mathlib.LinearAlgebra.Dimension.LinearMap
45044504
public import Mathlib.LinearAlgebra.Dimension.Localization
4505+
public import Mathlib.LinearAlgebra.Dimension.OrzechProperty
45054506
public import Mathlib.LinearAlgebra.Dimension.RankNullity
45064507
public import Mathlib.LinearAlgebra.Dimension.StrongRankCondition
45074508
public import Mathlib.LinearAlgebra.Dimension.Subsingleton

Mathlib/Algebra/Module/ZLattice/Basic.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Authors: Xavier Roblot
66
module
77

88
public import Mathlib.LinearAlgebra.Countable
9+
public import Mathlib.LinearAlgebra.Dimension.OrzechProperty
910
public import Mathlib.LinearAlgebra.FreeModule.PID
1011
public import Mathlib.MeasureTheory.Group.FundamentalDomain
1112
public import Mathlib.MeasureTheory.Measure.Lebesgue.EqHaar

Mathlib/FieldTheory/PerfectClosure.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ module
77

88
public import Mathlib.Algebra.CharP.Lemmas
99
public import Mathlib.FieldTheory.Perfect
10+
public import Mathlib.LinearAlgebra.Dimension.OrzechProperty
1011

1112
/-!
1213

Mathlib/FieldTheory/PurelyInseparable/PerfectClosure.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ module
88
public import Mathlib.Algebra.CharP.Lemmas
99
public import Mathlib.Algebra.CharP.IntermediateField
1010
public import Mathlib.FieldTheory.PurelyInseparable.Basic
11+
public import Mathlib.LinearAlgebra.Dimension.OrzechProperty
1112

1213
/-!
1314

Mathlib/LinearAlgebra/AffineSpace/FiniteDimensional.lean

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ public import Mathlib.FieldTheory.Finiteness
99
public import Mathlib.LinearAlgebra.AffineSpace.Basis
1010
public import Mathlib.LinearAlgebra.AffineSpace.Simplex.Basic
1111
public import Mathlib.LinearAlgebra.FiniteDimensional.Lemmas
12+
public import Mathlib.LinearAlgebra.Dimension.OrzechProperty
1213

1314
/-!
1415
# Finite-dimensional subspaces of affine spaces.

Mathlib/LinearAlgebra/Dimension/DivisionRing.lean

Lines changed: 2 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ noncomputable section
3535

3636
universe u₀ u v v' v'' u₁' w w'
3737

38-
variable {K R : Type u} {V V₁ V₂ V₃ : Type v} {V' V'₁ : Type v'} {V'' : Type v''}
39-
variable {ι : Type w} {ι' : Type w'} {η : Type u₁'} {φ : η → Type*}
38+
variable {K : Type u} {V V₁ V₂ V₃ : Type v}
39+
variable {ι : Type w}
4040

4141
open Cardinal Basis Submodule Function Set
4242

@@ -46,7 +46,6 @@ section DivisionRing
4646

4747
variable [DivisionRing K]
4848
variable [AddCommGroup V] [Module K V]
49-
variable [AddCommGroup V'] [Module K V']
5049
variable [AddCommGroup V₁] [Module K V₁]
5150

5251
/-- If a vector space has a finite dimension, the index set of `Basis.ofVectorSpace` is finite. -/
@@ -106,110 +105,3 @@ end
106105
end DivisionRing
107106

108107
end Module
109-
110-
section Basis
111-
112-
open Module
113-
114-
variable [DivisionRing K] [AddCommGroup V] [Module K V]
115-
116-
theorem linearIndependent_of_top_le_span_of_card_eq_finrank {ι : Type*} [Fintype ι] {b : ι → V}
117-
(spans : ⊤ ≤ span K (Set.range b)) (card_eq : Fintype.card ι = finrank K V) :
118-
LinearIndependent K b :=
119-
linearIndependent_iff'.mpr fun s g dependent i i_mem_s => by
120-
classical
121-
by_contra gx_ne_zero
122-
-- We'll derive a contradiction by showing `b '' (univ \ {i})` of cardinality `n - 1`
123-
-- spans a vector space of dimension `n`.
124-
refine not_le_of_gt (span_lt_top_of_card_lt_finrank
125-
(show (b '' (Set.univ \ {i})).toFinset.card < finrank K V from ?_)) ?_
126-
· calc
127-
(b '' (Set.univ \ {i})).toFinset.card = ((Set.univ \ {i}).toFinset.image b).card := by
128-
rw [Set.toFinset_card, Fintype.card_ofFinset]
129-
_ ≤ (Set.univ \ {i}).toFinset.card := Finset.card_image_le
130-
_ = (Finset.univ.erase i).card := (congr_arg Finset.card (Finset.ext (by simp [and_comm])))
131-
_ < Finset.univ.card := Finset.card_erase_lt_of_mem (Finset.mem_univ i)
132-
_ = finrank K V := card_eq
133-
-- We already have that `b '' univ` spans the whole space,
134-
-- so we only need to show that the span of `b '' (univ \ {i})` contains each `b j`.
135-
refine spans.trans (span_le.mpr ?_)
136-
rintro _ ⟨j, rfl, rfl⟩
137-
-- The case that `j ≠ i` is easy because `b j ∈ b '' (univ \ {i})`.
138-
by_cases j_eq : j = i
139-
swap
140-
· refine subset_span ⟨j, (Set.mem_diff _).mpr ⟨Set.mem_univ _, ?_⟩, rfl⟩
141-
exact mt Set.mem_singleton_iff.mp j_eq
142-
-- To show `b i ∈ span (b '' (univ \ {i}))`, we use that it's a weighted sum
143-
-- of the other `b j`s.
144-
rw [j_eq, SetLike.mem_coe, show b i = -((g i)⁻¹ • (s.erase i).sum fun j => g j • b j) from _]
145-
· refine neg_mem (smul_mem _ _ (sum_mem fun k hk => ?_))
146-
obtain ⟨k_ne_i, _⟩ := Finset.mem_erase.mp hk
147-
refine smul_mem _ _ (subset_span ⟨k, ?_, rfl⟩)
148-
simp_all only [Set.mem_univ, Set.mem_diff, Set.mem_singleton_iff, and_self, not_false_eq_true]
149-
-- To show `b i` is a weighted sum of the other `b j`s, we'll rewrite this sum
150-
-- to have the form of the assumption `dependent`.
151-
apply eq_neg_of_add_eq_zero_left
152-
calc
153-
(b i + (g i)⁻¹ • (s.erase i).sum fun j => g j • b j) =
154-
(g i)⁻¹ • (g i • b i + (s.erase i).sum fun j => g j • b j) := by
155-
rw [smul_add, ← mul_smul, inv_mul_cancel₀ gx_ne_zero, one_smul]
156-
_ = (g i)⁻¹ • (0 : V) := congr_arg _ ?_
157-
_ = 0 := smul_zero _
158-
-- And then it's just a bit of manipulation with finite sums.
159-
rwa [← Finset.insert_erase i_mem_s, Finset.sum_insert (Finset.notMem_erase _ _)] at dependent
160-
161-
/-- A finite family of vectors is linearly independent if and only if
162-
its cardinality equals the dimension of its span. -/
163-
theorem linearIndependent_iff_card_eq_finrank_span {ι : Type*} [Fintype ι] {b : ι → V} :
164-
LinearIndependent K b ↔ Fintype.card ι = (Set.range b).finrank K := by
165-
constructor
166-
· intro h
167-
exact (finrank_span_eq_card h).symm
168-
· intro hc
169-
let f := Submodule.subtype (span K (Set.range b))
170-
let b' : ι → span K (Set.range b) := fun i =>
171-
⟨b i, mem_span.2 fun p hp => hp (Set.mem_range_self _)⟩
172-
have hs : ⊤ ≤ span K (Set.range b') := by
173-
intro x
174-
have h : span K (f '' Set.range b') = map f (span K (Set.range b')) := span_image f
175-
have hf : f '' Set.range b' = Set.range b := by
176-
ext x
177-
simp [f, b', Set.mem_image, Set.mem_range]
178-
rw [hf] at h
179-
have hx : (x : V) ∈ span K (Set.range b) := x.property
180-
simp_rw [h] at hx
181-
simpa [f, mem_map] using hx
182-
have hi : LinearMap.ker f = ⊥ := ker_subtype _
183-
convert (linearIndependent_of_top_le_span_of_card_eq_finrank hs hc).map' _ hi
184-
185-
theorem linearIndependent_iff_card_le_finrank_span {ι : Type*} [Fintype ι] {b : ι → V} :
186-
LinearIndependent K b ↔ Fintype.card ι ≤ (Set.range b).finrank K := by
187-
rw [linearIndependent_iff_card_eq_finrank_span, (finrank_range_le_card _).ge_iff_eq']
188-
189-
/-- A family of `finrank K V` vectors forms a basis if they span the whole space. -/
190-
noncomputable def basisOfTopLeSpanOfCardEqFinrank {ι : Type*} [Fintype ι] (b : ι → V)
191-
(le_span : ⊤ ≤ span K (Set.range b)) (card_eq : Fintype.card ι = finrank K V) : Basis ι K V :=
192-
Basis.mk (linearIndependent_of_top_le_span_of_card_eq_finrank le_span card_eq) le_span
193-
194-
@[simp]
195-
theorem coe_basisOfTopLeSpanOfCardEqFinrank {ι : Type*} [Fintype ι] (b : ι → V)
196-
(le_span : ⊤ ≤ span K (Set.range b)) (card_eq : Fintype.card ι = finrank K V) :
197-
⇑(basisOfTopLeSpanOfCardEqFinrank b le_span card_eq) = b :=
198-
Basis.coe_mk _ _
199-
200-
/-- A finset of `finrank K V` vectors forms a basis if they span the whole space. -/
201-
@[simps! repr_apply]
202-
noncomputable def finsetBasisOfTopLeSpanOfCardEqFinrank {s : Finset V}
203-
(le_span : ⊤ ≤ span K (s : Set V)) (card_eq : s.card = finrank K V) : Basis {x // x ∈ s} K V :=
204-
basisOfTopLeSpanOfCardEqFinrank ((↑) : ↥(s : Set V) → V)
205-
((@Subtype.range_coe_subtype _ fun x => x ∈ s).symm ▸ le_span)
206-
(_root_.trans (Fintype.card_coe _) card_eq)
207-
208-
/-- A set of `finrank K V` vectors forms a basis if they span the whole space. -/
209-
@[simps! repr_apply]
210-
noncomputable def setBasisOfTopLeSpanOfCardEqFinrank {s : Set V} [Fintype s]
211-
(le_span : ⊤ ≤ span K s) (card_eq : s.toFinset.card = finrank K V) : Basis s K V :=
212-
basisOfTopLeSpanOfCardEqFinrank ((↑) : s → V) ((@Subtype.range_coe_subtype _ s).symm ▸ le_span)
213-
(_root_.trans s.toFinset_card.symm card_eq)
214-
215-
end Basis

Mathlib/LinearAlgebra/Dimension/Finite.lean

Lines changed: 37 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ noncomputable section
2424

2525
universe u v v' w
2626

27-
variable {R : Type u} {M M₁ : Type v} {M' : Type v'} {ι : Type w}
28-
variable [Ring R] [AddCommGroup M] [AddCommGroup M'] [AddCommGroup M₁]
29-
variable [Module R M] [Module R M'] [Module R M₁]
27+
variable {R : Type u} {M : Type v} {ι : Type w}
28+
variable [Semiring R] [AddCommMonoid M]
29+
variable [Module R M]
3030

3131
attribute [local instance] nontrivial_of_invariantBasisNumber
3232

@@ -56,7 +56,7 @@ theorem rank_le {n : ℕ}
5656
section RankZero
5757

5858
/-- See `rank_zero_iff` for a stronger version with `NoZeroSMulDivisor R M`. -/
59-
lemma rank_eq_zero_iff :
59+
lemma rank_eq_zero_iff {R M} [Ring R] [AddCommGroup M] [Module R M] :
6060
Module.rank R M = 0 ↔ ∀ x : M, ∃ a : R, a ≠ 0 ∧ a • x = 0 := by
6161
nontriviality R
6262
constructor
@@ -77,7 +77,7 @@ lemma rank_eq_zero_iff :
7777
apply ha
7878
simpa using DFunLike.congr_fun (linearIndependent_iff.mp hs (Finsupp.single i a) (by simpa)) i
7979

80-
variable [Nontrivial R]
80+
variable {R M : Type*} [Ring R] [AddCommGroup M] [Module R M] [Nontrivial R]
8181

8282
section
8383
variable [NoZeroSMulDivisors R M]
@@ -101,6 +101,12 @@ theorem rank_pos_iff_nontrivial : 0 < Module.rank R M ↔ Nontrivial M :=
101101
theorem rank_pos [Nontrivial M] : 0 < Module.rank R M :=
102102
rank_pos_iff_nontrivial.mpr ‹_›
103103

104+
omit [Nontrivial R] in
105+
theorem Module.finite_of_rank_eq_zero (h : Module.rank R M = 0) : Module.Finite R M := by
106+
nontriviality R
107+
rw [rank_zero_iff] at h
108+
infer_instance
109+
104110
end
105111

106112
theorem exists_mem_ne_zero_of_rank_pos {s : Submodule R M} (h : 0 < Module.rank R s) :
@@ -119,13 +125,6 @@ theorem Module.finite_of_rank_eq_nat [Module.Free R M] {n : ℕ} (h : Module.ran
119125
b.linearIndependent.cardinal_le_rank |>.trans_eq h |>.trans_lt <| nat_lt_aleph0 n
120126
exact Module.Finite.of_basis b
121127

122-
theorem Module.finite_of_rank_eq_zero [NoZeroSMulDivisors R M]
123-
(h : Module.rank R M = 0) :
124-
Module.Finite R M := by
125-
nontriviality R
126-
rw [rank_zero_iff] at h
127-
infer_instance
128-
129128
theorem Module.finite_of_rank_eq_one [Module.Free R M] (h : Module.rank R M = 1) :
130129
Module.Finite R M :=
131130
Module.finite_of_rank_eq_nat <| h.trans Nat.cast_one.symm
@@ -240,7 +239,7 @@ theorem Module.Finite.not_linearIndependent_of_infinite {ι : Type*} [Infinite
240239
(v : ι → M) : ¬LinearIndependent R v := mt LinearIndependent.finite <| @not_finite _ _
241240

242241
section
243-
variable [NoZeroSMulDivisors R M]
242+
variable {R : Type u} {M : Type v} [Ring R] [AddCommGroup M] [Module R M] [NoZeroSMulDivisors R M]
244243

245244
theorem iSupIndep.subtype_ne_bot_le_rank [Nontrivial R]
246245
{V : ι → Submodule R M} (hV : iSupIndep V) :
@@ -289,6 +288,7 @@ theorem iSupIndep.subtype_ne_bot_le_finrank
289288

290289
end
291290

291+
variable {R M : Type*} [Ring R] [AddCommGroup M] [Module R M]
292292
variable [Module.Finite R M] [StrongRankCondition R]
293293

294294
section
@@ -357,21 +357,16 @@ theorem Module.finrank_zero_of_subsingleton [Subsingleton M] :
357357
lemma LinearIndependent.finrank_eq_zero_of_infinite {ι} [Infinite ι] {v : ι → M}
358358
(hv : LinearIndependent R v) : finrank R M = 0 := toNat_eq_zero.mpr <| .inr hv.aleph0_le_rank
359359

360-
section
361-
variable [NoZeroSMulDivisors R M]
362-
363360
/-- A finite-dimensional space is nontrivial if it has positive `finrank`. -/
364-
theorem Module.nontrivial_of_finrank_pos (h : 0 < finrank R M) : Nontrivial M :=
365-
rank_pos_iff_nontrivial.mp (lt_rank_of_lt_finrank h)
361+
theorem Module.nontrivial_of_finrank_pos (h : 0 < finrank R M) : Nontrivial M := by
362+
contrapose! h; exact finrank_zero_of_subsingleton.le
366363

367364
/-- A finite-dimensional space is nontrivial if it has `finrank` equal to the successor of a
368365
natural number. -/
369366
theorem Module.nontrivial_of_finrank_eq_succ {n : ℕ}
370367
(hn : finrank R M = n.succ) : Nontrivial M :=
371368
nontrivial_of_finrank_pos (R := R) (by rw [hn]; exact n.succ_pos)
372369

373-
end
374-
375370
variable (R M)
376371

377372
@[simp]
@@ -382,6 +377,7 @@ end
382377

383378
section StrongRankCondition
384379

380+
variable {R M : Type*} [Ring R] [AddCommGroup M] [Module R M]
385381
variable [StrongRankCondition R] [Module.Finite R M]
386382

387383
/-- A finite rank torsion-free module has positive `finrank` iff it has a nonzero element. -/
@@ -430,6 +426,10 @@ theorem Module.finrank_eq_zero_of_rank_eq_zero (h : Module.rank R M = 0) :
430426
delta finrank
431427
rw [h, zero_toNat]
432428

429+
section
430+
431+
variable {R M : Type*} [Ring R] [AddCommGroup M] [Module R M]
432+
433433
theorem Submodule.bot_eq_top_of_rank_eq_zero [NoZeroSMulDivisors R M] (h : Module.rank R M = 0) :
434434
(⊥ : Submodule R M) = ⊤ := by
435435
nontriviality R
@@ -459,6 +459,8 @@ lemma Submodule.one_le_finrank_iff [StrongRankCondition R] [NoZeroSMulDivisors R
459459
1 ≤ finrank R S ↔ S ≠ ⊥ := by
460460
contrapose!; rw [Nat.lt_one_iff, finrank_eq_zero]
461461

462+
end
463+
462464
@[simp]
463465
theorem Set.finrank_empty [Nontrivial R] :
464466
Set.finrank R (∅ : Set M) = 0 := by
@@ -499,6 +501,7 @@ end FinrankZero
499501

500502
section RankOne
501503

504+
variable {R : Type u} {M : Type v} [Ring R] [AddCommGroup M] [Module R M]
502505
variable [NoZeroSMulDivisors R M] [StrongRankCondition R]
503506

504507
/-- If there is a nonzero vector and every other vector is a multiple of it,
@@ -514,20 +517,22 @@ then the module has dimension one. -/
514517
theorem finrank_eq_one (v : M) (n : v ≠ 0) (h : ∀ w : M, ∃ c : R, c • v = w) : finrank R M = 1 :=
515518
finrank_eq_of_rank_eq (rank_eq_one v n h)
516519

517-
/-- If every vector is a multiple of some `v : M`, then `M` has dimension at most one.
518-
-/
520+
end RankOne
521+
522+
section
523+
524+
variable [StrongRankCondition R]
525+
526+
theorem rank_le_one (v : M) (h : ∀ w : M, ∃ c : R, c • v = w) : Module.rank R M ≤ 1 := by
527+
simpa using LinearMap.lift_rank_le_of_surjective _
528+
(id h : Surjective (LinearMap.toSpanSingleton R M v))
529+
530+
/-- If every vector is a multiple of some `v : M`, then `M` has dimension at most one. -/
519531
theorem finrank_le_one (v : M) (h : ∀ w : M, ∃ c : R, c • v = w) : finrank R M ≤ 1 := by
520-
haveI := nontrivial_of_invariantBasisNumber R
521-
rcases eq_or_ne v 0 with (rfl | hn)
522-
· haveI :=
523-
_root_.subsingleton_of_forall_eq (0 : M) fun w => by
524-
obtain ⟨c, rfl⟩ := h w
525-
simp
526-
rw [finrank_zero_of_subsingleton]
527-
exact zero_le_one
528-
· exact (finrank_eq_one v hn h).le
532+
rw [← map_one toNat, finrank]
533+
exact toNat_le_toNat (rank_le_one v h) one_lt_aleph0
529534

530-
end RankOne
535+
end
531536

532537
namespace Module
533538
variable {ι : Type*}

0 commit comments

Comments
 (0)