Skip to content

Commit 58255df

Browse files
committed
feat(LinearIndependent): more API for linearIndepOn (#22368)
We add a few more API lemmas for `linearIndepOn`, in many cases generalizing `id` versions of existing lemmas to arbitrary functions.
1 parent 4f7fb55 commit 58255df

File tree

6 files changed

+134
-22
lines changed

6 files changed

+134
-22
lines changed

Mathlib/LinearAlgebra/Dimension/Constructions.lean

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,16 +56,35 @@ theorem LinearIndependent.sumElim_of_quotient
5656
@[deprecated (since := "2025-02-21")]
5757
alias LinearIndependent.sum_elim_of_quotient := LinearIndependent.sumElim_of_quotient
5858

59-
theorem LinearIndepOn.union_of_quotient {M' : Submodule R M}
59+
theorem LinearIndepOn.union_of_quotient {s t : Set ι} {f : ι → M} (hs : LinearIndepOn R f s)
60+
(ht : LinearIndepOn R (mkQ (span R (f '' s)) ∘ f) t) : LinearIndepOn R f (s ∪ t) := by
61+
apply hs.union ht.of_comp
62+
convert (Submodule.range_ker_disjoint ht).symm
63+
· simp
64+
aesop
65+
66+
theorem LinearIndepOn.union_id_of_quotient {M' : Submodule R M}
6067
{s : Set M} (hs : s ⊆ M') (hs' : LinearIndepOn R id s) {t : Set M}
61-
(ht : LinearIndepOn R (Submodule.Quotient.mk (p := M')) t) : LinearIndepOn R id (s ∪ t) :=
62-
have h := (LinearIndependent.sumElim_of_quotient (f := Set.embeddingOfSubset s M' hs)
63-
(LinearIndependent.of_comp M'.subtype (by simpa using hs')) Subtype.val ht)
64-
h.linearIndepOn_id' <| by
65-
simp only [embeddingOfSubset_apply_coe, Sum.elim_range, Subtype.range_val]
68+
(ht : LinearIndepOn R (mkQ M') t) : LinearIndepOn R id (s ∪ t) :=
69+
hs'.union_of_quotient <| by
70+
rw [image_id]
71+
exact ht.of_comp ((span R s).mapQ M' (LinearMap.id) (span_le.2 hs))
6672

6773
@[deprecated (since := "2025-02-16")] alias LinearIndependent.union_of_quotient :=
68-
LinearIndepOn.union_of_quotient
74+
LinearIndepOn.union_id_of_quotient
75+
76+
theorem linearIndepOn_union_iff_quotient {s t : Set ι} {f : ι → M} (hst : Disjoint s t) :
77+
LinearIndepOn R f (s ∪ t) ↔
78+
LinearIndepOn R f s ∧ LinearIndepOn R (mkQ (span R (f '' s)) ∘ f) t := by
79+
refine ⟨fun h ↦ ⟨?_, ?_⟩, fun h ↦ h.1.union_of_quotient h.2
80+
· exact h.mono subset_union_left
81+
apply (h.mono subset_union_right).map
82+
simpa [← image_eq_range] using ((linearIndepOn_union_iff hst).1 h).2.2.symm
83+
84+
theorem LinearIndepOn.quotient_iff_union {s t : Set ι} {f : ι → M} (hs : LinearIndepOn R f s)
85+
(hst : Disjoint s t) :
86+
LinearIndepOn R (mkQ (span R (f '' s)) ∘ f) t ↔ LinearIndepOn R f (s ∪ t) := by
87+
rw [linearIndepOn_union_iff_quotient hst, and_iff_right hs]
6988

7089
theorem rank_quotient_add_rank_le [Nontrivial R] (M' : Submodule R M) :
7190
Module.rank R (M ⧸ M') + Module.rank R M' ≤ Module.rank R M := by

Mathlib/LinearAlgebra/Dimension/RankNullity.lean

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -92,19 +92,19 @@ theorem exists_linearIndepOn_of_lt_rank [StrongRankCondition R]
9292
{s : Set M} (hs : LinearIndepOn R id s) :
9393
∃ t, s ⊆ t ∧ #t = Module.rank R M ∧ LinearIndepOn R id t := by
9494
obtain ⟨t, ht, ht'⟩ := exists_set_linearIndependent R (M ⧸ Submodule.span R s)
95-
choose sec hsec using Submodule.Quotient.mk_surjective (Submodule.span R s)
96-
have hsec' : Submodule.Quotient.mk ∘ sec = _root_.id := funext hsec
95+
choose sec hsec using Submodule.mkQ_surjective (Submodule.span R s)
96+
have hsec' : (Submodule.mkQ _) ∘ sec = _root_.id := funext hsec
9797
have hst : Disjoint s (sec '' t) := by
9898
rw [Set.disjoint_iff]
9999
rintro _ ⟨hxs, ⟨x, hxt, rfl⟩⟩
100100
apply ht'.ne_zero ⟨x, hxt⟩
101-
rw [Subtype.coe_mk, ← hsec x, Submodule.Quotient.mk_eq_zero]
101+
rw [Subtype.coe_mk, ← hsec x,mkQ_apply, Quotient.mk_eq_zero]
102102
exact Submodule.subset_span hxs
103103
refine ⟨s ∪ sec '' t, subset_union_left, ?_, ?_⟩
104104
· rw [Cardinal.mk_union_of_disjoint hst, Cardinal.mk_image_eq, ht,
105105
← rank_quotient_add_rank (Submodule.span R s), add_comm, rank_span_set hs]
106106
exact HasLeftInverse.injective ⟨Submodule.Quotient.mk, hsec⟩
107-
· apply LinearIndepOn.union_of_quotient Submodule.subset_span hs
107+
· apply LinearIndepOn.union_id_of_quotient Submodule.subset_span hs
108108
rwa [linearIndepOn_iff_image (hsec'.symm ▸ injective_id).injOn.image_of_comp,
109109
← image_comp, hsec', image_id]
110110

Mathlib/LinearAlgebra/LinearIndependent/Basic.lean

Lines changed: 50 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,21 @@ theorem LinearIndepOn.id_image (hs : LinearIndepOn R v s) : LinearIndepOn R id (
152152
@[deprecated (since := "2025-02-14")] alias
153153
LinearIndependent.image := LinearIndepOn.id_image
154154

155+
theorem LinearIndepOn_iff_linearIndepOn_image_injOn [Nontrivial R] :
156+
LinearIndepOn R v s ↔ LinearIndepOn R id (v '' s) ∧ InjOn v s :=
157+
fun h ↦ ⟨h.id_image, h.injOn⟩, fun h ↦ (linearIndepOn_iff_image h.2).2 h.1
158+
159+
theorem linearIndepOn_congr {w : ι → M} (h : EqOn v w s) :
160+
LinearIndepOn R v s ↔ LinearIndepOn R w s := by
161+
rw [LinearIndepOn, LinearIndepOn]
162+
convert Iff.rfl using 2
163+
ext x
164+
exact h.symm x.2
165+
166+
theorem LinearIndepOn.congr {w : ι → M} (hli : LinearIndepOn R v s) (h : EqOn v w s) :
167+
LinearIndepOn R w s :=
168+
(linearIndepOn_congr h).1 hli
169+
155170
theorem LinearIndependent.group_smul {G : Type*} [hG : Group G] [DistribMulAction G R]
156171
[DistribMulAction G M] [IsScalarTower G R M] [SMulCommClass G R M] {v : ι → M}
157172
(hv : LinearIndependent R v) (w : ι → G) : LinearIndependent R (w • v) := by
@@ -453,14 +468,35 @@ theorem LinearIndependent.sum_type {v' : ι' → M} (hv : LinearIndependent R v)
453468
LinearIndependent R (Sum.elim v v') :=
454469
linearIndependent_sum.2 ⟨hv, hv', h⟩
455470

456-
-- TODO - generalize this to non-identity functions
457-
theorem LinearIndepOn.id_union {s t : Set M} (hs : LinearIndepOn R id s)
458-
(ht : LinearIndepOn R id t) (hst : Disjoint (span R s) (span R t)) :
459-
LinearIndepOn R id (s ∪ t) := by
460-
have h := hs.linearIndependent.sum_type ht.linearIndependent (by simpa)
461-
simpa [id_eq] using h.linearIndepOn_id
462-
463-
@[deprecated (since := "2025-02-14")] alias LinearIndependent.union := LinearIndepOn.id_union
471+
theorem LinearIndepOn.union {t : Set ι} (hs : LinearIndepOn R v s) (ht : LinearIndepOn R v t)
472+
(hdj : Disjoint (span R (v '' s)) (span R (v '' t))) : LinearIndepOn R v (s ∪ t) := by
473+
nontriviality R
474+
classical
475+
have hli := LinearIndependent.sum_type hs ht (by rwa [← image_eq_range, ← image_eq_range])
476+
have hdj := (hdj.of_span₀ hs.zero_not_mem_image).of_image
477+
rw [LinearIndepOn]
478+
convert (hli.comp _ (Equiv.Set.union hdj).injective) with ⟨x, hx | hx⟩
479+
· rw [comp_apply, Equiv.Set.union_apply_left _ hx, Sum.elim_inl]
480+
rw [comp_apply, Equiv.Set.union_apply_right _ hx, Sum.elim_inr]
481+
482+
theorem LinearIndepOn.id_union {s t : Set M} (hs : LinearIndepOn R id s) (ht : LinearIndepOn R id t)
483+
(hdj : Disjoint (span R s) (span R t)) : LinearIndepOn R id (s ∪ t) :=
484+
hs.union ht (by simpa)
485+
486+
theorem linearIndepOn_union_iff {t : Set ι} (hdj : Disjoint s t) :
487+
LinearIndepOn R v (s ∪ t) ↔
488+
LinearIndepOn R v s ∧ LinearIndepOn R v t ∧ Disjoint (span R (v '' s)) (span R (v '' t)) := by
489+
refine ⟨fun h ↦ ⟨h.mono subset_union_left, h.mono subset_union_right, ?_⟩,
490+
fun h ↦ h.1.union h.2.1 h.2.2
491+
convert h.disjoint_span_image (s := (↑) ⁻¹' s) (t := (↑) ⁻¹' t) (hdj.preimage _) <;>
492+
aesop
493+
494+
theorem linearIndepOn_id_union_iff {s t : Set M} (hdj : Disjoint s t) :
495+
LinearIndepOn R id (s ∪ t) ↔
496+
LinearIndepOn R id s ∧ LinearIndepOn R id t ∧ Disjoint (span R s) (span R t) := by
497+
rw [linearIndepOn_union_iff hdj, image_id, image_id]
498+
499+
@[deprecated (since := "2025-02-14")] alias LinearIndependent.union := LinearIndepOn.union
464500

465501
open LinearMap
466502

@@ -583,8 +619,12 @@ theorem linearIndependent_unique_iff (v : ι → M) [Unique ι] :
583619

584620
alias ⟨_, linearIndependent_unique⟩ := linearIndependent_unique_iff
585621

586-
theorem LinearIndepOn.singleton {v : ι → M} {i : ι} (hi : v i ≠ 0) : LinearIndepOn R v {i} :=
587-
linearIndependent_unique _ hi
622+
variable (R) in
623+
@[simp]
624+
theorem linearIndepOn_singleton_iff {i : ι} {v : ι → M} : LinearIndepOn R v {i} ↔ v i ≠ 0 :=
625+
fun h ↦ h.ne_zero rfl, fun h ↦ linearIndependent_unique _ h⟩
626+
627+
alias ⟨_, LinearIndepOn.singleton⟩ := linearIndepOn_singleton_iff
588628

589629
variable (R) in
590630
theorem LinearIndepOn.id_singleton {x : M} (hx : x ≠ 0) : LinearIndepOn R id {x} :=

Mathlib/LinearAlgebra/LinearIndependent/Defs.lean

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,9 @@ theorem LinearIndepOn.ne_zero [Nontrivial R] {i : ι} (hv : LinearIndepOn R v s)
142142
v i ≠ 0 :=
143143
LinearIndependent.ne_zero ⟨i, hi⟩ hv
144144

145+
theorem LinearIndepOn.zero_not_mem_image [Nontrivial R] (hs : LinearIndepOn R v s) : 0 ∉ v '' s :=
146+
fun ⟨_, hi, h0⟩ ↦ hs.ne_zero hi h0
147+
145148
theorem linearIndependent_empty_type [IsEmpty ι] : LinearIndependent R v :=
146149
injective_of_subsingleton _
147150

@@ -150,6 +153,10 @@ theorem linearIndependent_zero_iff [Nontrivial R] : LinearIndependent R (0 : ι
150153
fun h ↦ not_nonempty_iff.1 fun ⟨i⟩ ↦ (h.ne_zero i rfl).elim,
151154
fun _ ↦ linearIndependent_empty_type⟩
152155

156+
@[simp]
157+
theorem linearIndepOn_zero_iff [Nontrivial R] : LinearIndepOn R (0 : ι → M) s ↔ s = ∅ :=
158+
linearIndependent_zero_iff.trans isEmpty_coe_sort
159+
153160
variable (R M) in
154161
theorem linearIndependent_empty : LinearIndependent R (fun x => x : (∅ : Set M) → M) :=
155162
linearIndependent_empty_type

Mathlib/LinearAlgebra/LinearIndependent/Lemmas.lean

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ protected theorem LinearIndepOn.insert (hs : LinearIndepOn K id s) (hx : x ∉ s
415415
LinearIndepOn K id (insert x s) := by
416416
rw [← union_singleton]
417417
have x0 : x ≠ 0 := mt (by rintro rfl; apply zero_mem (span K s)) hx
418-
apply hs.id_union (LinearIndepOn.singleton x0)
418+
apply hs.id_union (LinearIndepOn.id_singleton _ x0)
419419
rwa [disjoint_span_singleton' x0]
420420

421421
@[deprecated (since := "2025-02-15")] alias LinearIndependent.insert := LinearIndepOn.insert
@@ -458,13 +458,48 @@ theorem linearIndepOn_id_insert (hxs : x ∉ s) :
458458

459459
@[deprecated (since := "2025-02-15")] alias linearIndependent_insert := linearIndepOn_insert
460460

461+
theorem linearIndepOn_insert_iff {s : Set ι} {a : ι} {f : ι → V} :
462+
LinearIndepOn K f (insert a s) ↔ LinearIndepOn K f s ∧ (f a ∈ span K (f '' s) → a ∈ s) := by
463+
by_cases has : a ∈ s
464+
· simp [insert_eq_of_mem has, has]
465+
simp [linearIndepOn_insert has, has]
466+
467+
theorem linearIndepOn_id_insert_iff {a : V} {s : Set V} :
468+
LinearIndepOn K id (insert a s) ↔ LinearIndepOn K id s ∧ (a ∈ span K s → a ∈ s) := by
469+
simpa using linearIndepOn_insert_iff (a := a) (f := id)
470+
471+
theorem LinearIndepOn.mem_span_iff {s : Set ι} {a : ι} {f : ι → V} (h : LinearIndepOn K f s) :
472+
f a ∈ Submodule.span K (f '' s) ↔ (LinearIndepOn K f (insert a s) → a ∈ s) := by
473+
by_cases has : a ∈ s
474+
· exact iff_of_true (subset_span <| mem_image_of_mem f has) fun _ ↦ has
475+
simp [linearIndepOn_insert_iff, h, has]
476+
477+
/-- A shortcut to a convenient form for the negation in `LinearIndepOn.mem_span_iff`. -/
478+
theorem LinearIndepOn.not_mem_span_iff {s : Set ι} {a : ι} {f : ι → V} (h : LinearIndepOn K f s) :
479+
f a ∉ Submodule.span K (f '' s) ↔ LinearIndepOn K f (insert a s) ∧ a ∉ s := by
480+
rw [h.mem_span_iff, _root_.not_imp]
481+
482+
theorem LinearIndepOn.mem_span_iff_id {s : Set V} {a : V} (h : LinearIndepOn K id s) :
483+
a ∈ Submodule.span K s ↔ (LinearIndepOn K id (insert a s) → a ∈ s) := by
484+
simpa using h.mem_span_iff (a := a)
485+
486+
theorem LinearIndepOn.not_mem_span_iff_id {s : Set V} {a : V} (h : LinearIndepOn K id s) :
487+
a ∉ Submodule.span K s ↔ LinearIndepOn K id (insert a s) ∧ a ∉ s := by
488+
rw [h.mem_span_iff_id, _root_.not_imp]
489+
461490
theorem linearIndepOn_id_pair {x y : V} (hx : x ≠ 0) (hy : ∀ a : K, a • x ≠ y) :
462491
LinearIndepOn K id {x, y} :=
463492
pair_comm y x ▸ (LinearIndepOn.id_singleton K hx).insert (x := y) <|
464493
mt mem_span_singleton.1 <| not_exists.2 hy
465494

466495
@[deprecated (since := "2025-02-15")] alias linearIndependent_pair := linearIndepOn_id_pair
467496

497+
theorem linearIndepOn_pair_iff {i j : ι} (v : ι → V) (hij : i ≠ j) (hi : v i ≠ 0):
498+
LinearIndepOn K v {i, j} ↔ ∀ (c : K), c • v i ≠ v j := by
499+
rw [pair_comm]
500+
convert linearIndepOn_insert (s := {i}) (a := j) hij.symm
501+
simp [hi, mem_span_singleton, linearIndependent_unique_iff]
502+
468503
/-- Also see `LinearIndependent.pair_iff` for the version over arbitrary rings. -/
469504
theorem LinearIndependent.pair_iff' {x y : V} (hx : x ≠ 0) :
470505
LinearIndependent K ![x, y] ↔ ∀ a : K, a • x ≠ y := by

Mathlib/LinearAlgebra/Span/Defs.lean

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,17 @@ theorem span_int_eq_addSubgroup_closure {M : Type*} [AddCommGroup M] (s : Set M)
225225
theorem span_int_eq {M : Type*} [AddCommGroup M] (s : AddSubgroup M) :
226226
(span ℤ (s : Set M)).toAddSubgroup = s := by rw [span_int_eq_addSubgroup_closure, s.closure_eq]
227227

228+
theorem _root_.Disjoint.of_span (hst : Disjoint (span R s) (span R t)) :
229+
Disjoint (s \ {0}) t := by
230+
rw [disjoint_iff_forall_ne]
231+
rintro v ⟨hvs, hv0 : v ≠ 0⟩ _ hvt rfl
232+
exact hv0 <| (disjoint_def.1 hst) v (subset_span hvs) (subset_span hvt)
233+
234+
theorem _root_.Disjoint.of_span₀ (hst : Disjoint (span R s) (span R t)) (h0s : 0 ∉ s) :
235+
Disjoint s t := by
236+
rw [← diff_singleton_eq_self h0s]
237+
exact hst.of_span
238+
228239
section
229240

230241
variable (R M)

0 commit comments

Comments
 (0)