Zulip Chat Archive
Stream: new members
Topic: Proof over indexed? sum and indexed? set...
Arien Malec (May 21 2024 at 21:27):
Sorry for the double ?? but I don't know how to set up the following.
Axler, in LADL, wants to prove:
Linear Algebra Done Right
"Suppose 𝑉_1, ..., 𝑉_𝑚 are subspaces of 𝑉. Then 𝑉_1 + ⋯ + 𝑉_𝑚 is a direct sum if and only if the only way to write
0 as a sum
𝑣_1+⋯+𝑣_𝑚, where each
𝑣_𝑘 ∈𝑉_𝑘, is by taking each
𝑣_𝑘 equal to
0`."
Translating to a Mathlib context, we want instead to prove that if for any V_i
and V_j
, Disjoint V_i V_j
then v_1 + ... + v_m = 0 \iff \forall i, v_i = 0
. (or something like that).
The proof over 2 elements is:
import Mathlib.Algebra.Module.Submodule.Lattice
variable {R : Type*} {M : Type*}
variable [Ring R] [AddCommGroup M] [Module R M]
example {y z : M} {p : Submodule R M} {p' : Submodule R M}
(ymem: y ∈ p) (zmem: z ∈ p') (h': Disjoint p p'):
y + z = 0 ↔ y = 0 ∧ z = 0 := by
constructor
. intro h''
rw [add_eq_zero_iff_neg_eq] at h''
constructor
. have := (Submodule.disjoint_def.mp h') _ (Submodule.neg_mem p ymem) (by rwa [h''])
exact neg_eq_zero.mp this
. rw [neg_eq_iff_eq_neg] at h''
have := (Submodule.disjoint_def.mp h'.symm) _ (Submodule.neg_mem p' zmem) (by rwa [← h''])
exact neg_eq_zero.mp this
. rintro ⟨rfl, rfl⟩; simp only [add_zero]
And I assume we want an indexed foo (Σ i
?) in the general proof, but I also want to index into the submodules?
What would the natural "shape" of the theorem look like here?
Ruben Van de Velde (May 21 2024 at 21:42):
Probably the first thing to take into account is that the explicit numeric indexing V_1 ··· V_m is probably going to be annoying in lean and you'd rather work with an arbitrary Finset
of V
s
Ruben Van de Velde (May 21 2024 at 21:49):
Actually, not sure that fully made sense
Arien Malec (May 21 2024 at 21:51):
I think I can visualize how docs#Finset.sum works with that?
Arien Malec (May 21 2024 at 21:52):
I guess I can't....
Ruben Van de Velde (May 21 2024 at 21:58):
import Mathlib.Algebra.Module.Submodule.Lattice
variable {R : Type*} {M : Type*}
variable [Ring R] [AddCommGroup M] [Module R M]
example {y z : M} {p : Submodule R M} {p' : Submodule R M}
(ymem: y ∈ p) (zmem: z ∈ p') (h': Disjoint p p'):
y + z = 0 ↔ y = 0 ∧ z = 0 := by
constructor
. intro h''
rw [add_eq_zero_iff_neg_eq] at h''
constructor
. have := (Submodule.disjoint_def.mp h') _ (Submodule.neg_mem p ymem) (by rwa [h''])
exact neg_eq_zero.mp this
. rw [neg_eq_iff_eq_neg] at h''
have := (Submodule.disjoint_def.mp h'.symm) _ (Submodule.neg_mem p' zmem) (by rwa [← h''])
exact neg_eq_zero.mp this
. rintro ⟨rfl, rfl⟩; simp only [add_zero]
open BigOperators
example {ι : Type} [Fintype ι] {ys : ι → M} {Vs : ι → Submodule R M}
(mem : ∀ i, ys i ∈ Vs i) (h': Pairwise (Disjoint on Vs)) :
∑ i, ys i = 0 ↔ ∀ i, ys i = 0 := by
sorry
Arien Malec (May 21 2024 at 21:59):
Perfect! Now for the fun bit :-)
Arien Malec (May 22 2024 at 02:39):
I can't seem to make induction work on Finset.sum
-- is there a trick here (I get dependent elimination errors which usually indicated a track)? Or perhaps there's a different way to go at this -- my thought is to follow the shape of the proof above -- for a Finset
of length 0/1, the proof is trivially true, and for any other length, induction + the above proof should get me there?
Yakov Pechersky (May 22 2024 at 03:31):
Which induction principle did you use? This usually calls for docs#Finset.cons_induction_on
Arien Malec (May 22 2024 at 03:35):
Tried docs#Finset.sum_induction
Arien Malec (May 22 2024 at 03:37):
But it turns out I was doing induction on an equality. Oops.
Arien Malec (May 23 2024 at 14:43):
So how do I reason over ∑ i, ys i = 0
? The CS in me wants to say there's a trivial zero and one length case, and the general case has an induction hypothesis that resolves to the pair proof above, but I don't know what object in Mathlib allows that...
Arien Malec (May 23 2024 at 15:43):
I tried induction
/cases
over ∑ i, ys i
but Lean says that's an M
-- so how do I get at the sum
?
Yakov Pechersky (May 23 2024 at 18:26):
When you say "reason over" the sum, what do you mean? I think you have the right case. You should induct like this:
import Mathlib
variable {R : Type*} {M : Type*}
variable [Ring R] [AddCommGroup M] [Module R M]
lemma foo {y z : M} {p : Submodule R M} {p' : Submodule R M}
(ymem: y ∈ p) (zmem: z ∈ p') (h': Disjoint p p'):
y + z = 0 ↔ y = 0 ∧ z = 0 := by
constructor
. intro h''
rw [add_eq_zero_iff_neg_eq] at h''
constructor
. have := (Submodule.disjoint_def.mp h') _ (Submodule.neg_mem p ymem) (by rwa [h''])
exact neg_eq_zero.mp this
. rw [neg_eq_iff_eq_neg] at h''
have := (Submodule.disjoint_def.mp h'.symm) _ (Submodule.neg_mem p' zmem) (by rwa [← h''])
exact neg_eq_zero.mp this
. rintro ⟨rfl, rfl⟩; simp only [add_zero]
open BigOperators
lemma Submodule.sum_eq_iSup (s : Finset ι) (f : ι → Submodule R M) :
∑ i ∈ s, f i = ⨆ i ∈ s, f i := by
induction s using Finset.cons_induction_on with
| h₁ => simp
| h₂ ha IH =>
simp only [Finset.sum_cons, add_eq_sup, IH, Finset.mem_cons, iSup_or, iSup_sup_eq]
congr
simp
lemma Submodule.mem_sum_of_mem {s : Finset ι} {f : ι → Submodule R M} (x : M) (hi : ∃ i ∈ s, x ∈ f i) :
x ∈ ∑ i ∈ s, f i := by
rw [sum_eq_iSup, mem_iSup]
intro N hN
obtain ⟨i, hi, hx⟩ := hi
exact hN i (mem_iSup_of_mem hi hx)
lemma Submodule.sum_mem_sum_of_forall_mem (s : Finset ι) {f : ι → Submodule R M} {g : ι → M} (h : ∀ i ∈ s, g i ∈ f i):
∑ i ∈ s, g i ∈ ∑ i ∈ s, f i := by
rw [sum_eq_iSup, mem_iSup]
intro N hN
exact sum_mem fun i hi => hN i (mem_iSup_of_mem hi (h i hi))
lemma bar (s : Finset ι) {ys : ι → M} {Vs : ι → Submodule R M}
(mem : ∀ i ∈ s, ys i ∈ Vs i) (h': Pairwise (Disjoint on Vs)) :
∑ i ∈ s, ys i = 0 ↔ ∀ i ∈ s, ys i = 0 := by
induction s using Finset.cons_induction_on with
| h₁ => simp
| h₂ ha IH =>
specialize IH (fun i hi => mem i (by simp [hi]))
simp only [Finset.sum_cons, Finset.mem_cons, forall_eq_or_imp, ← IH]
rename_i a s
convert foo (R := R) _ _ _
· infer_instance
· exact (Vs a)
· exact (∑ i ∈ s, Vs i) -- failed to synthesize instance AddCommMonoid (Submodule R M)
· exact (mem a (by simp))
· refine Submodule.sum_mem_sum_of_forall_mem (f := Vs) ?_ ?_
intro i hi
simp only [Finset.mem_cons, forall_eq_or_imp] at mem
exact mem.right _ hi
rw [Submodule.sum_eq_iSup]
intro N hN hN'
sorry
example {ι : Type} [Fintype ι] {ys : ι → M} {Vs : ι → Submodule R M}
(mem : ∀ i, ys i ∈ Vs i) (h': Pairwise (Disjoint on Vs)) :
∑ i, ys i = 0 ↔ ∀ i, ys i = 0 := by
rw [bar _ _ h']
· simp
· simpa using mem
Yakov Pechersky (May 23 2024 at 18:27):
I didn't do the Disjoint
goal of the split sum. The pairwise disjoint hypothesis for that lemma can likely be weakened. @Yaël Dillies are submodules an Order.Frame? I was hoping to use docs#disjoint_iSup_iff
Yaël Dillies (May 23 2024 at 18:30):
No, they are not. In ℝ²
consider the three submodules U = ⟨(0, 1)⟩, V = ⟨(1, 0)⟩, W = ⟨(1, 1)⟩
(subspaces generated by one vector). Then Disjoint U W
, Disjoint V W
but ¬ Disjoint (U ⊔ V) W
.
Yaël Dillies (May 23 2024 at 18:30):
See https://leanprover.zulipchat.com/#narrow/stream/217875-Is-there-code-for-X.3F/topic/lattice.20in.20which.20atoms.20are.20spanning.20and.20independent for more relevant discussion
Yakov Pechersky (May 23 2024 at 18:32):
Then likely, pairwise disjoint on Vs isn't strong enough?
Yaël Dillies (May 23 2024 at 18:33):
Indeed. My counterexample also works as a counterexample to your statement
Yaël Dillies (May 23 2024 at 18:33):
You need to assume something like docs#CompleteLattice.SetIndependent
Arien Malec (May 23 2024 at 19:42):
is that the right answer to the question: all the members of a basis are?
Arien Malec (May 23 2024 at 19:43):
I'm doing this thing where Axler is going from his definition of Direct Sum, and I'm trying to go from the right Mathlib starting point...
Arien Malec (May 23 2024 at 19:45):
Also, I see that I'm trying to do induction on the sum, and I need to be doing induction on the Finset
of course.
Arien Malec (May 23 2024 at 19:50):
Arien Malec said:
is that the right answer to the question: all the members of a basis are?
or rather, the span of all the elements of a basis are....
Yakov Pechersky (May 23 2024 at 21:16):
OK now with Yael's suggestion:
import Mathlib
variable {R : Type*} {M : Type*}
variable [Ring R] [AddCommGroup M] [Module R M]
lemma foo {y z : M} {p : Submodule R M} {p' : Submodule R M}
(ymem: y ∈ p) (zmem: z ∈ p') (h': Disjoint p p'):
y + z = 0 ↔ y = 0 ∧ z = 0 := by
constructor
. intro h''
rw [add_eq_zero_iff_neg_eq] at h''
constructor
. have := (Submodule.disjoint_def.mp h') _ (Submodule.neg_mem p ymem) (by rwa [h''])
exact neg_eq_zero.mp this
. rw [neg_eq_iff_eq_neg] at h''
have := (Submodule.disjoint_def.mp h'.symm) _ (Submodule.neg_mem p' zmem) (by rwa [← h''])
exact neg_eq_zero.mp this
. rintro ⟨rfl, rfl⟩; simp only [add_zero]
open BigOperators
lemma Submodule.sum_eq_iSup (s : Finset ι) (f : ι → Submodule R M) :
∑ i ∈ s, f i = ⨆ i ∈ s, f i := by
induction s using Finset.cons_induction_on with
| h₁ => simp
| h₂ ha IH =>
simp only [Finset.sum_cons, add_eq_sup, IH, Finset.mem_cons, iSup_or, iSup_sup_eq]
congr
simp
lemma Submodule.mem_sum_of_mem {s : Finset ι} {f : ι → Submodule R M} (x : M) (hi : ∃ i ∈ s, x ∈ f i) :
x ∈ ∑ i ∈ s, f i := by
rw [sum_eq_iSup, mem_iSup]
intro N hN
obtain ⟨i, hi, hx⟩ := hi
exact hN i (mem_iSup_of_mem hi hx)
lemma Submodule.sum_mem_sum_of_forall_mem (s : Finset ι) {f : ι → Submodule R M} {g : ι → M} (h : ∀ i ∈ s, g i ∈ f i):
∑ i ∈ s, g i ∈ ∑ i ∈ s, f i := by
rw [sum_eq_iSup, mem_iSup]
intro N hN
exact sum_mem fun i hi => hN i (mem_iSup_of_mem hi (h i hi))
lemma bar (s : Finset ι) {ys : ι → M} {Vs : ι → Submodule R M}
(mem : ∀ i ∈ s, ys i ∈ Vs i) (h': CompleteLattice.SetIndependent (Vs '' s)) :
∑ i ∈ s, ys i = 0 ↔ ∀ i ∈ s, ys i = 0 := by
induction s using Finset.cons_induction_on with
| h₁ => simp
| h₂ ha IH =>
rename_i a s
simp only [Finset.coe_cons, Set.image_insert_eq] at h'
specialize IH (fun i hi => mem i (by simp [hi])) ?_
· -- TODO: factor out
intro N hN
specialize @h' N (by simp [hN])
simp_rw [Set.insert_eq, Set.union_diff_distrib, sSup_union] at h'
-- can't use disjoint_sup_iff, Submodule isn't a DistribLattice
intro M hM hM'
exact h' hM (le_sup_of_le_right hM')
simp only [Finset.sum_cons, Finset.mem_cons, forall_eq_or_imp]
rw [foo (R := R) (p := Vs a) (p' := ∑ i ∈ s, Vs i), IH]
· exact (mem a (by simp))
· refine Submodule.sum_mem_sum_of_forall_mem (f := Vs) ?_ ?_
intro i hi
simp only [Finset.mem_cons, forall_eq_or_imp] at mem
exact mem.right _ hi
·
have : ⨆ i ∈ s, Vs i = sSup (Vs '' s) := by
rw [sSup_image]
simp
rw [Submodule.sum_eq_iSup, this]
apply h'.disjoint_sSup (x := Vs a) (y := (Vs '' s))
· simp
· simp
lemma CompleteLattice.Independent.setIndependent_image {ι : Type*} {α : Type*} [CompleteLattice α] {t : ι → α}
(h : CompleteLattice.Independent t) (s : Set ι) :
CompleteLattice.SetIndependent (t '' s) := by
apply h.setIndependent_range.mono
simp
example {ι : Type} [Fintype ι] {ys : ι → M} {Vs : ι → Submodule R M}
(mem : ∀ i, ys i ∈ Vs i) (h': CompleteLattice.Independent Vs) :
∑ i, ys i = 0 ↔ ∀ i, ys i = 0 := by
rw [bar (Finset.univ : Finset ι) (ys := ys) (Vs := Vs) ?_ (h'.setIndependent_image _)]
simp
Yakov Pechersky (May 23 2024 at 21:16):
can use some cleanup
Yakov Pechersky (May 23 2024 at 21:16):
Crucially, it's nicer to operate on the iSup
(maybe even the sSup
) than the \Sum
Arien Malec (May 23 2024 at 21:18):
A lot to dig into here -- thanks!
Arien Malec (May 24 2024 at 00:58):
I'm getting elaboration function for 'BigOperators.bigsum' has not been implemented
-- does this mean update Mathlib or??
Ruben Van de Velde (May 24 2024 at 06:34):
What's bigsum?
Yaël Dillies (May 24 2024 at 06:59):
Arien Malec said:
I'm getting
elaboration function for 'BigOperators.bigsum' has not been implemented
-- does this mean update Mathlib or??
Yes
Yaël Dillies (May 24 2024 at 07:00):
... or alternatively use the deprecated \sum i in s, f i
notation (instead of the new one \sum i \in s, f i
), but I advise you against it
Yaël Dillies (May 24 2024 at 07:00):
Ruben Van de Velde said:
What's bigsum?
That's the name of the elaborator
Last updated: May 02 2025 at 03:31 UTC