Zulip Chat Archive

Stream: Is there code for X?

Topic: Tensor product over noncommutative ring


Gareth Ma (Nov 05 2024 at 13:28):

Is there tensor product over noncommutative rings? TensorProduct requires [CommRing R] and so does ModuleCat.monoidalCategory

Kevin Buzzard (Nov 05 2024 at 13:33):

Can you be more precise? What are you tensoring and what isn't commutative? There are three types involved here

Gareth Ma (Nov 05 2024 at 13:35):

I want MRNM \otimes_R N where MM is a left RR-module and NN is a right RR-module, and RR isn't necessarily commutative, which should be an abelian group

Gareth Ma (Nov 05 2024 at 13:36):

I don't know how "right RR-module" works in Lean either, I'm not familiar with the algebra side of Mathlib at all, hence the question :0

Kevin Buzzard (Nov 05 2024 at 13:37):

My understanding is that if R isn't commutative then to make a right R-module you just make it a left R^op module. If you import mathlib and open TensorProduct does it Just Work? Sorry, not at a computer right now

Gareth Ma (Nov 05 2024 at 13:38):

I see, but then R still isn't commutative so the TensorProduct doesn't work

Gareth Ma (Nov 05 2024 at 13:38):

#docs4 TensorProduct

Gareth Ma (Nov 05 2024 at 13:38):

how do you use this again

Gareth Ma (Nov 05 2024 at 13:38):

docs4#TensorProduct

Gareth Ma (Nov 05 2024 at 13:39):

It requires

noncomputable def TensorProduct (R : Type u_1) [CommSemiring R] (M : Type u_4) (N : Type u_5) [AddCommMonoid M] [AddCommMonoid N] [Module R M] [Module R N] :
Type (max u_4 u_5)

Kevin Buzzard (Nov 05 2024 at 13:39):

docs#TensorProduct

Kevin Buzzard (Nov 05 2024 at 13:43):

Huh, do we really not have this?

Gareth Ma (Nov 05 2024 at 13:45):

:sad: i want to tensor over k[G]k[G] for non-commutative GG

Gareth Ma (Nov 05 2024 at 13:45):

seems like a massive task to work on as well...

Gareth Ma (Nov 05 2024 at 13:46):

Oh there is a draft PR #8638. @Junyan Xu hello :eyes:

Kevin Buzzard (Nov 05 2024 at 13:47):

Oh I disagree -- sounds like a nice project! Just copy the commutative case and do 150 lines and then stop. You'll make the world a better place!

Kevin Buzzard (Nov 05 2024 at 13:48):

You can just start by making NonCommTensorProduct and then do the refactor of TensorProduct later

Gareth Ma (Nov 05 2024 at 13:49):

That's true, I guess the work is just copying the commutative case and mess around with stuff. But since there's a draft PR I'll wait for the (co)author and see if they're working on it :eyes:

Joël Riou (Nov 05 2024 at 14:45):

Gareth Ma said:

:sad: i want to tensor over k[G]k[G] for non-commutative GG

Just to be sure, do you want to take the tensor product over k[G] (which is going to be a k-vector space), or take the tensor product over k and define a linear action of G? (These two are not the same. A certain formulation of the latter is in the file Mathlib.RepresentationTheory.Action.Monoidal.)

Gareth Ma (Nov 05 2024 at 15:11):

It's the former, for e.g. induced representations

Kevin Buzzard (Nov 05 2024 at 16:05):

If all you want is induced representations then you can just make them as something like functions from G to V (an H-rep) satisfying f(hg)=h.f(g) or whatever.

Gareth Ma (Nov 05 2024 at 16:07):

Oh yeah, I don't think defining induced rep with this tensor product is "natural" anyways, but you want it as a theorem

Gareth Ma (Nov 05 2024 at 16:08):

that the (Rep.induced something something).\rho.asModule is isomorphic to the tensor product construction

Junyan Xu (Nov 06 2024 at 00:31):

The nice thing about defining induced rep as a tensor product is that you get Frobenius reciprocity as a special case of docs#ModuleCat.extendRestrictScalarsAdj, which is immediate from uncurryEquiv here. This adjunction has been a major motivation of my draft PR.

Currently, TensorProduct uses R-action on both factors and require them be Modules, but the left factor should really be a R^mop-Module by mathematical convention. For a commutative ring R, R^mop and R are isomorphic rings by the identity map, and a R^mop-Module is the same as an R-Module. But for a noncommutative ring R, a R^mop-MulAction will not give rise to a R-MulAction.

In #8638 I changed TensorProduct to require R^mop-Module on left factor and generalized results when possible, and I plan to define the "commutative tensor product" that takes two R-Modules in another file, by making the left R-Module a R^mop-Module using commutativity. Note that this can't be a global instance, because there are existing R- and R^mop-Module instances on R itself defined for [Semiring R], which are propositionally but not definitionally equal for commutative R, because one is left multiplication and the other is right multiplication.

The current state of #8638 is mostly my experiment to see which results generalize to the noncommutative setting and in which ways they generalize. The type of many declarations are changed (e.g. R-LinearMap is changed to R^mop-LinearMap), which will be disruptive downstream in Mathlib. I think a better approach is to create a new file TensorProduct.General, and put the generalized declarations under the TensorProduct.General namespace. In the current file TensorProduct.Basic, we don't add or remove declarations, but change the constructions / proofs to use the generalized declarations when possible. I might try to implement this this weekend.

(Remark: If we relax [Module] to [SMul] in TensorProduct, we could avoid changing one of the R to R^mop, because a R^mop-SMul does give rise to a R-SMul, and if you make this a local/temporary instance, you can "define the general/noncommutative tensor product in terms of the existing/commutative tensor product", but I think this approach is mathematically dubious.)

Eric Wieser (Nov 06 2024 at 15:53):

There was a very long thread about this in the past, which culminated in a refactor of Algebra to imply actions on both sides (so that we don't need separate types for tensor products of noncommutative algebras). The PR was mostly lost to the porting tide.

Yuyang Zhao (Nov 06 2024 at 17:45):

(See #maths > left vs right modules in tensor products and #mathlib4 > Noncommutative ring things )

Junyan Xu (Nov 07 2024 at 05:12):

Here's a new idea: similar to semilinear maps, we can generalize TensorProduct to take a R-module M and a S-module N together with a RingHom σ from S to R^dma (defeq to R^mop with same ring structure). In this setting, the tensor-Hom adjunction becomes the correspondence between M ⊗[σ] N →+ P and N →ₛₗ[σ] M →+ P. One can take σ to be RingEquiv.toOpposite if R=S is commutative, or RingEquiv.opOp if R is S^mop. This generalized TensorProduct isn't quite symmetric in the two factors, and RingHomInvPair can be used to express the necessary condition for TensorProduct.comm ...

Eric Wieser (Nov 07 2024 at 09:29):

Is there any precedent for doing this with σ = star?

Johan Commelin (Nov 07 2024 at 12:37):

I think there is precedent when \sigma = Frob.

Gareth Ma (Jul 10 2025 at 06:21):

Hey, it seems I stumbled across this again, but I am not 100% sure, so I will ask here just to confirm my understanding. I saw this TODO in the file RepresentationTheory/Rep.lean:

def equivalenceModuleMonoidAlgebra : Rep k G  ModuleCat.{u} (MonoidAlgebra k G) where ...
-- TODO Verify that the equivalence with `ModuleCat (MonoidAlgebra k G)` is a monoidal functor.

But then I realised that Mathlib doesn't know the RHS (k[G]-Mod) is a monoidal category at all:

#synth MonoidalCategory (ModuleCat.{u} (MonoidAlgebra k G)) -- fail
variable {G' : Type u} [CommMonoid G']
#check ModuleCat.monoidalCategory -- requires [CommRing R]
#synth MonoidalCategory (ModuleCat.{u} (MonoidAlgebra k G')) -- ok

I assume this thread (us not having tensor product over noncommutative rings) is why Mathlib doesn't know R-Mod is monoidal right?

If so, my other observation is that Mathlib knows the LHS (Rep_k(G)) is a monoidal category:

#check Action.instMonoidalCategory
#synth MonoidalCategory (Rep k G) -- ok

So can we just Monoidal.transport it over to k[G]-Mod or is that silly/recursive/bad/incorrect?

Gareth Ma (Jul 10 2025 at 06:26):

The assumptions are {k G : Type u} [CommRing k] [Monoid G] by the way.

Junyan Xu (Jul 10 2025 at 07:15):

Presumably the monoidal structure on Rep k G takes the tensor product over k and put a certain G-action on it; if you want to work with representations, transporting it to k[G]-Mod is the right choice. If you have tensor product over a noncommutative ring R you can get a monoidal structure on R-R-bimodules, but ModuleCat R is just left R-modules.

Kevin Buzzard (Jul 10 2025 at 07:20):

Yes this has nothing to do with tensor products over noncommutative rings. Modules over a general noncommutative ring are not naturally monoidal.

I think that rather than transferring the instance across the equivalence it would be more helpful to define the monoidal structure intrinsically by putting a G-action on the tensor product over k.

Gareth Ma (Jul 10 2025 at 07:30):

Thanks for the clarification, I am really bad at thinking about these when things are noncommutative :joy:

Kevin Buzzard (Jul 10 2025 at 07:32):

The monoidal structure must depend on more than just the abstract ring k[G] because you can recover a group from its tannakian category of representations (via automorphisms of the fibre functor) but different groups can have the same character table and thus the same group ring

Robin Carlier (Jul 10 2025 at 07:46):

I think if you view representations as functors from SingleObj G to ModuleCat k, then the tensor product of representations is the pointwise tensor product of functors. I don't think this helps much in this situation though as I'm not sure Mathlib knows of the first equivalence I mentionned (between representations and functors from SingleObj)

Gareth Ma (Jul 10 2025 at 07:47):

It does, that’s how Action.instMonoidal or whatever is defined

Gareth Ma (Jul 10 2025 at 07:47):

It’s transferred from SingleObj G => ModuleCat k

Robin Carlier (Jul 10 2025 at 07:48):

Oh well, I should have read that part of the library more before posting.


Last updated: Dec 20 2025 at 21:32 UTC