Zulip Chat Archive
Stream: new members
Topic: Direct Sums over vector spaces
Arien Malec (Mar 01 2024 at 05:05):
Sorry to do this again, but I can't make heads or tails of the DirectSum
notation.
The goal in Axler is to show that the direct sum of subspaces in F^3
{<x, y, 0>} ⊕ {<0, 0,z>} = F^3`
Here's where I got to, where the example
is completely borked because I can't grok the syntax of direct sums in Mathlib
import Mathlib.Algebra.Module.Submodule.Basic
import Mathlib.Algebra.DirectSum.Basic
import Mathlib.Data.Fin.VecNotation
variable (F: Type*) [Field F]
def ex1_42_U: Submodule F (Fin 3 → F) where
carrier := { ![x, y, y] | (x: F) (y: F) }
add_mem' := by aesop
smul_mem' := by aesop
zero_mem' := by simp
def ex1_42_V: Submodule F (Fin 3 → F) where
carrier := { ![0, 0, z] | (z: F)}
add_mem' := by aesop
smul_mem' := by aesop
zero_mem' := by simp
open DirectSum
-- example: (⨁ (ex1_42_U) (ex1_42_V), f ex1_42_U ex1_42_V) = (Fin 3 → F) := by sorry
Timo Carlin-Burns (Mar 01 2024 at 05:41):
DirectSum
operates on an indexed family of spaces. To use it on just two, use an indexing type of cardinality 2, such as Bool
or Fin 2
. You can express U ⨁ V
as ⨁ i: Bool, if i then U else V
Timo Carlin-Burns (Mar 01 2024 at 05:44):
Or ⨁ i, ![U, V] i
. Or DirectSum _ ![U, V]
Timo Carlin-Burns (Mar 01 2024 at 05:44):
Not sure what's preferred
Eric Wieser (Mar 01 2024 at 08:01):
Or U × V
Eric Wieser (Mar 01 2024 at 08:03):
Or since we're talking about subspaces, this is U ⊔ V
, or perhaps IsCompl U V
Kevin Buzzard (Mar 01 2024 at 11:37):
@Arien Malec the definitions of things like sums, direct sums etc in mathlib are different to the ones used in Axler and this is a great example of the kind of problem you run into when you want to "go through a textbook in Lean". One approach which avoids all this confusion would be to just write your own definitions. Of course, if you do this, you'll discover why Lean's definitions are different -- Lean's definitions are chosen to be the ones which cause the least pain when using them in Lean. This is the problem you face with formalising a maths book.
Patrick Massot (Mar 01 2024 at 13:08):
This has nothing to do with Lean, Axler is using a very standard abuse of notations and here you simply need to be precise.
Patrick Massot (Mar 01 2024 at 13:10):
We could use the confusing notation in Lean but there is not much point doing it.
Arien Malec (Mar 01 2024 at 15:44):
It's funny -- I see any number of Github repositories of people trying to do the same thing as I, and generally bomb out at the end of Chapter 1.... I'm following a thread, which I can't find in the Zulip, that the most interesting way to do this would be to cover the same ground in Lean rather than translate too closely. This kind of gear meshing is the inevitable result.
Arien Malec (Mar 01 2024 at 15:49):
My approach is what @Scott Morrison recommended here: https://leanprover.zulipchat.com/#narrow/stream/113489-new-members/topic/Showing.20a.20subset.20that's.20a.20vector.20space.20contains.20zero/near/365098675
Arien Malec (Mar 01 2024 at 15:53):
(which is the thread I was thinking of).
Arien Malec (Mar 01 2024 at 16:31):
And perhaps direct sums are not the right construct -- the definition Axler is looking for is something like: U ⊔ V ∧ U ∩ V = ∅
Eric Wieser (Mar 01 2024 at 16:53):
The LHS of your ∧
is not a proposition; it doesn't mean anything for "U ⊔ V
" to be true.
Eric Wieser (Mar 01 2024 at 16:54):
And the RHS is always false, because even the "empty" vector space has a zero, so is not the empty set
Eric Wieser (Mar 01 2024 at 16:54):
docs#IsCompl is probably what you meant
Arien Malec (Mar 01 2024 at 16:54):
Probably -- the sense is that a vector space is composed of multiple disjoint vector spaces.
Arien Malec (Mar 01 2024 at 16:55):
Building to an intuition of a basis.
Arien Malec (Mar 01 2024 at 16:56):
Right, instead of empty I should have written {0}
Eric Wieser (Mar 01 2024 at 16:57):
U ∩ V = {0}
would be written in mathlib as Disjoint U V
(see docs#disjoint_iff for a proof this is the same)
Arien Malec (Mar 01 2024 at 16:57):
We want something like W = U ⊔ V ∧ U ∩ V = {0}
then
Eric Wieser (Mar 01 2024 at 16:58):
Yes, and I told you how to spell exactly that in mathlib :)
Arien Malec (Mar 01 2024 at 17:01):
I'm still struggling with the setup to Axler's example above.... , that F^3
is the combination of the two disjoint subsets.
Arien Malec (Mar 01 2024 at 17:04):
So maybe the statement is: example: ((ex1_42_U ⊔ ex1_42_V) = Fin 3 → F) ∧ Disjoint ex1_42_U ex1_42_V := by sorry
? But I can't get this to typecheck. Perhaps I'm missing an import...
Arien Malec (Mar 01 2024 at 17:08):
Parentheses and stuff, but Mathlib/Lean doesn't like turning a collection of Submodule
s into a Module
Patrick Massot (Mar 01 2024 at 17:32):
Arien I think you would have a much easier job if you could accept to first learn a bit about mathlib and then come back to your project. Guessing everything is not so fun. A lot of things are not documented but what you are struggling with is documented. I think there is not much point doing what you are doing without first reading the algebra chapter of #mil or some other resource covering the same material.
Richard Copley (Mar 01 2024 at 17:33):
With those defs, ex1_42_U
isn't a submodule, ex1_42_U F
is.
Arien Malec (Mar 01 2024 at 18:36):
Patrick Massot said:
Arien I think you would have a much easier job if you could accept to first learn a bit about mathlib and then come back to your project. Guessing everything is not so fun. A lot of things are not documented but what you are struggling with is documented. I think there is not much point doing what you are doing without first reading the algebra chapter of #mil or some other resource covering the same material.
I've read though #mil but not done the exercises. I'll commit to doing so. At the same time, I suspect that knowing the abstract algebra hierarchy will not lead to clarity in the gear meshing I'm working through...
Patrick Massot (Mar 01 2024 at 18:37):
It should be enough to get you to understand why (ex1_42_U ⊔ ex1_42_V) = Fin 3 → F
is wrong.
Patrick Massot (Mar 01 2024 at 18:37):
I mean it stays wrong even after inserting the missing arguments.
Arien Malec (Mar 01 2024 at 18:38):
When I look at it, it's obviously wrong -- I should have written Module F (Fin 3 → F)
Arien Malec (Mar 01 2024 at 18:40):
Which is probably still wrong, but at least a more right sort of wrong.
Arien Malec (Mar 01 2024 at 18:42):
Perhaps I can approach this problem in a different direction. How would one say that (span(<1, 0, 0>) +span(<0,1,0>) + span(<0,0,1>)) = ℝ^3
Patrick Massot (Mar 01 2024 at 18:47):
This is not the issue, the issue is the right hand side of your (ex1_42_U ⊔ ex1_42_V) = Fin 3 → F
Patrick Massot (Mar 01 2024 at 18:48):
You need to put a submodule there.
Arien Malec (Mar 01 2024 at 20:15):
OK, now I'm super confused. The exercise that Axler is leading us through is to show that vector spaces are "composed of" subspaces each of which can be generated by a basis vector. In Mathlib, can we show that composition of subspaces that form the required vector space? We'd then want submodules on the LHS and a module on the RHS....
Arien Malec (Mar 01 2024 at 20:15):
I guess I've been super confused all along and now I just have a new dimension of confusion added.
Patrick Massot (Mar 01 2024 at 20:20):
I can see you are confused, that’s why I told you to read the explanations instead of trying to guess.
Patrick Massot (Mar 01 2024 at 20:21):
Or watch the lecture I mentioned earlier.
Patrick Massot (Mar 01 2024 at 20:22):
There is a submodule whose elements are all the elements of the ambiant module, and it’s name is Top.
Patrick Massot (Mar 01 2024 at 20:23):
So the statement you want is example: ex1_42_U F ⊔ ex1_42_V F = ⊤ ∧ Disjoint ex1_42_U ex1_42_V
Patrick Massot (Mar 01 2024 at 20:23):
where ⊤
is the notation for top.
Arien Malec (Mar 01 2024 at 20:25):
And ⊥
would be the submodule {0}
?
Eric Wieser (Mar 01 2024 at 20:45):
Patrick Massot said:
So the statement you want is
example: ex1_42_U F ⊔ ex1_42_V F = ⊤ ∧ Disjoint ex1_42_U ex1_42_V
Another spelling In mathlib for ex1_42_U F ⊔ ex1_42_V F = ⊤
is Codisjoint (ex1_42_U F) (ex1_42_V F)
, and combined with the ∧ Disjoint _ _
this is exactly IsCompl (ex1_42_U F) (ex1_42_V F)
Eric Wieser (Mar 01 2024 at 20:56):
(Not something you should care about now, but: the original problem in this thread of showing a vector space "is" a direct sum of two subspaces ends up being more complicated if you start talking about semimodules instead of vector spaces, and the sup / inf / IsCompl spellings no longer work! I can say more once you've solved your current exercise)
Arien Malec (Mar 01 2024 at 21:43):
I made things slightly easier on myself to see the shape of the proof rather than faffing with the right use
and have this down to
import Mathlib
variable (F: Type*) [Field F]
def ex1_42_U: Submodule F (Fin 3 → F) where
carrier := { ![x, y, 0] | (x: F) (y: F) }
add_mem' := by aesop
smul_mem' := by aesop
zero_mem' := by simp
def ex1_42_V: Submodule F (Fin 3 → F) where
carrier := { ![0, 0, z] | (z: F)}
add_mem' := by aesop
smul_mem' := by aesop
zero_mem' := by simp
example: (ex1_42_U F ⊔ ex1_42_V F) = ⊤ ∧ Disjoint (ex1_42_U F) (ex1_42_V F) := by
constructor
. rw [Submodule.eq_top_iff']
intro x
rw [Submodule.mem_sup]
use ![x 0, x 1, 0]
constructor
. sorry
. use ![0, 0, x 2]
constructor
. sorry
. simp
ext f
fin_cases f <;> simp ; aesop
. rw [disjoint_iff, Submodule.eq_bot_iff (ex1_42_U F ⊓ ex1_42_V F)]
intro x h
cases' h with h1 h2
ext f
fin_cases f <;>
simp <;>
rcases h1 with ⟨x₁, x₂, h1⟩ <;>
rcases h2 with ⟨x₃, h2⟩
. rw [←h2]; simp
. rw [←h2]; simp
. rw [←h1]; simp
where the two sorry
s have the same shape: proof of membership in the subset....
Arien Malec (Mar 01 2024 at 21:47):
But I don't know how to prove membership in a Submodule
Eric Wieser (Mar 01 2024 at 22:03):
Your issue is that you made a new def
, but didn't tell Lean anything about it
Richard Osborn (Mar 01 2024 at 22:03):
You'll want to unfold ex1_42_U
and unfold ex1_42_V
.
Eric Wieser (Mar 01 2024 at 22:03):
Or better yet,
theorem mem_ex1_42_U_iff {x} : x ∈ ex1_42_U F ↔ x ∈ { ![x, y, 0] | (x: F) (y: F) } := Iff.rfl
Eric Wieser (Mar 01 2024 at 22:03):
Unfolding gives you a monstrosity thanks to nested structures, and set_option pp.proofs.withType false
not being the default
Richard Osborn (Mar 01 2024 at 22:04):
Yea, though simp
or aesop
clean it up nicely.
Arien Malec (Mar 01 2024 at 22:26):
Eric Wieser said:
Or better yet,
theorem mem_ex1_42_U_iff {x} : x ∈ ex1_42_U F ↔ x ∈ { ![x, y, 0] | (x: F) (y: F) } := Iff.rfl
Is there any way to make this generic over Submodule F (Fin 3 → F)
Eric Wieser (Mar 01 2024 at 22:28):
No, in the same way that it's not possible to generalize:
def foo : Set Nat := {1, 2, 3}
theorem mem_foo (n : Nat) : n ∈ foo ↔ n ∈ {1, 2, 3}
Eric Wieser (Mar 01 2024 at 22:28):
It would be reasonable to ask something to autogenerate mem_foo
and mem_ex1_42_U_iff
, but that's not the same as generalization
Arien Malec (Mar 01 2024 at 22:35):
I see -- at some point we need to expand the definition of the carrier....
Eric Wieser (Mar 01 2024 at 22:46):
Yes, exactly; either by unfold
, which makes a mess, or by writing a lemma that does exactly the expansion you want
Eric Wieser (Mar 01 2024 at 22:47):
In many cases @[simps]
could do this, but it doesn't know about \mem
Arien Malec (Mar 01 2024 at 22:49):
OK, can I repeat back what I've learned here, to check for understanding:
Mathlib uses the fact that the submodules of a module form a complete lattice to generalize the proofs around modules to proofs of lattice structures; in particular, Mathlib uses the ⊔
(least upper bound) operator, or lattice join, to represent sums of submodules. What Axler terms the Direct Sum is, in Mathlib, the statement that the least upper bound of submodules is ⊤
(AKA the submodule identical to the module) along with the assertion that the submodules are disjoint.
Arien Malec (Mar 01 2024 at 22:50):
(these last are packaged into the statement IsCompl
)
Eric Wieser (Mar 01 2024 at 22:59):
Note that you're not using the fact that the lattice is complete in this case, as you only used finite lattice meets / joins
Eric Wieser (Mar 01 2024 at 22:59):
That sounds like a fair summary to me
Arien Malec (Mar 01 2024 at 23:00):
We'd use the complete versions if we were dealing with infinite dimensional vector spaces?
Eric Wieser (Mar 01 2024 at 23:01):
No, only if you were talking about an infinite family of submodules rather than just two
Arien Malec (Mar 02 2024 at 17:30):
I'd like to recover Axler's original definition: "The sum 𝑉_1 + ⋯ + 𝑉_𝑚
is called a direct sum if each element of 𝑉_1 + ⋯ + 𝑉_𝑚
can be written in only one way as a sum 𝑣_1 + ⋯ + 𝑣_𝑚
, where each 𝑣_𝑘 ∈ 𝑉_𝑘
"
The existence of such a sum is given in docs#Submodule.mem_sup -- is there any ready made proof for the uniqueness of that sum? (My intuition is that if the existence runs through Codisjoint
the uniqueness runs through Disjoint
but where I see a proof that the left and right of IsCompl
are unique (e.g., docs#IsCompl.right_unique) I don't see anything obvious that leads to the proof that the sum is unique).
Eric Wieser (Mar 02 2024 at 20:32):
I think the literal interpretation of this is to show that Function.bijective (LinearMap.coprod P.subtype Q.subtype : P × Q →ₗ[R] M)
Eric Wieser (Mar 02 2024 at 20:33):
Eric Wieser (Mar 02 2024 at 20:34):
Which says "there is a two-sided inverse to the map that adds together the two pieces"
Eric Wieser (Mar 02 2024 at 20:34):
(this is also the solution to the semimodule version I alluded to above)
Last updated: May 02 2025 at 03:31 UTC