-
Notifications
You must be signed in to change notification settings - Fork 378
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Merged by Bors] - feat: heterogenize TensorProduct.congr and friends #6035
Conversation
…asic-TensorProduct.congr
There is a reasonably-sized section on modules over two rings before we actual reach tensor products of rings. The motivation for splitting here is to make room for the results in #6035. The declarations are copied without modification, the module docstring has been adapted.
…asic-TensorProduct.congr
There is a reasonably-sized section on modules over two rings before we actual reach tensor products of rings. The motivation for splitting here is to make room for the results in #6035. The declarations are copied without modification, the module docstring has been adapted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I get the impression that this work is a lot more impressive than it lets on: I tried mildly generalising some of the results and immediately got into all sorts of problems. All the proofs are very succinct and to be quite frank I think I might struggle with some of them on paper; if everything is R-linear and tensor products are all over R then everything is easy, but once you start throwing around more rings then things seem to become a lot more delicate. Well done! I left a host of comments, some of which don't need acting on and can just be resolved after you've read them if you agree that nothing needs doing. Thanks a lot!
variable (R A B M N P Q) | ||
|
||
/-- Heterobasic version of `TensorProduct.map_bilinear` -/ | ||
def mapBilinear : (M →ₗ[A] P) →ₗ[B] (N →ₗ[R] Q) →ₗ[R] (M ⊗[R] N →ₗ[A] P ⊗[R] Q) := |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a candidate for @[simps]
? I'm only just getting the hang of @[simps]
. Or is the idea that you're safer writing your own simp lemmas for declarations as complicated as this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
simps
generates something with implicit type arguments, which aren't really needed here; though I'll admit I don't remember if that was my reason.
In generaly my rule is "use simps
if I'm feeling lazy, write the lemma manually if I'm feeling picky or simps screws up". The important thing is to have some simp
lemma, the API doesn't really care whether it's generated with simps
.
/-- Heterobasic version of `TensorProduct.assoc`: | ||
|
||
Linear equivalence between `(M ⊗[A] N) ⊗[R] P` and `M ⊗[A] (N ⊗[R] P)`. -/ | ||
def assoc : (M ⊗[A] P) ⊗[R] N ≃ₗ[A] M ⊗[A] P ⊗[R] N := | ||
def assoc : (M ⊗[A] P) ⊗[R] Q ≃ₗ[B] M ⊗[A] (P ⊗[R] Q) := |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you think there's a version of this where [IsScalarTower A B M]
is replaced by [IsScalarTower A B P]
? Note that I'm not suggesting that you add it, but if you think that there's some merit to this suggestion then you could leave a comment. This seems to be the only def where you need to assume B is an A-algebra.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know. This was one where the "obvious" implementation required more typeclasses than the statement. I think I recall places in mathlib where the "clever" bundling approach requires more typeclasses than the dumb but annoying induction
approach, but I was pretty maximally annoyed by this point and didn't want to think much more about generalization!
I'll try to reflect this in an update to the PR description :)
Frankly |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, this looks very clean.
I did not think at all about whether/how this could possibly be generalized. As you indicate, it is probably possible. But we can do that when we need it.
bors merge
The summary is that this PR: * generalizes a handful of results to non-commutative algebras (simply by moving them to an earlier section) * adds heterogenous versions of `map`, `congr`, `mapBilinear`, `homTensorHom`, `leftComm`, `tensorTensorTensorComm` * generalizes `lcurry`, `uncurry`, and `assoc` to take an extra algebra, such that the `A`s in the two different places can separately be replaced with `R` The punchline here is really: ```lean def tensorTensorTensorComm : (M ⊗[R] N) ⊗[A] (P ⊗[R] Q) ≃ₗ[A] (M ⊗[A] P) ⊗[R] (N ⊗[R] Q) := ``` which is valuable for a base change / tensor product of bilinear forms when instantiated as ```lean (M ⊗[R] N) ⊗[A] (Dual A M ⊗[R] Dual R N) ≃ₗ[A] (M ⊗[A] Dual A M) ⊗[R] (N ⊗[R] Dual R N) ``` It would not surprise me if it's possible to introduce a third ring into `tensorTensorTensorComm`, but for now I'd prefer to assume that for that particular definition, two rings is enough for anybody! Unfortunately, this was not the case for `lcurry`, `uncurry`, and `assoc`, which really do need to work over three rings so that the `A`s in the two different places can separately be replaced with `R`; both permutations are needed in the construction of `tensorTensorTensorComm`, and it seemed preferable to not have a plethora of primed variants. I make no claim that the pile of `IsScalarTower` and `SMulCommClass` arguments here are in any sense optimal, besides the fact they specifically enable the use-case I have for the base change of bilinear forms.
Pull request successfully merged into master. Build succeeded! The publicly hosted instance of bors-ng is deprecated and will go away soon. If you want to self-host your own instance, instructions are here. If you want to switch to GitHub's built-in merge queue, visit their help page. |
There is a reasonably-sized section on modules over two rings before we actual reach tensor products of rings. The motivation for splitting here is to make room for the results in #6035. The declarations are copied without modification, the module docstring has been adapted.
The summary is that this PR: * generalizes a handful of results to non-commutative algebras (simply by moving them to an earlier section) * adds heterogenous versions of `map`, `congr`, `mapBilinear`, `homTensorHom`, `leftComm`, `tensorTensorTensorComm` * generalizes `lcurry`, `uncurry`, and `assoc` to take an extra algebra, such that the `A`s in the two different places can separately be replaced with `R` The punchline here is really: ```lean def tensorTensorTensorComm : (M ⊗[R] N) ⊗[A] (P ⊗[R] Q) ≃ₗ[A] (M ⊗[A] P) ⊗[R] (N ⊗[R] Q) := ``` which is valuable for a base change / tensor product of bilinear forms when instantiated as ```lean (M ⊗[R] N) ⊗[A] (Dual A M ⊗[R] Dual R N) ≃ₗ[A] (M ⊗[A] Dual A M) ⊗[R] (N ⊗[R] Dual R N) ``` It would not surprise me if it's possible to introduce a third ring into `tensorTensorTensorComm`, but for now I'd prefer to assume that for that particular definition, two rings is enough for anybody! Unfortunately, this was not the case for `lcurry`, `uncurry`, and `assoc`, which really do need to work over three rings so that the `A`s in the two different places can separately be replaced with `R`; both permutations are needed in the construction of `tensorTensorTensorComm`, and it seemed preferable to not have a plethora of primed variants. I make no claim that the pile of `IsScalarTower` and `SMulCommClass` arguments here are in any sense optimal, besides the fact they specifically enable the use-case I have for the base change of bilinear forms.
The summary is that this PR:
map
,congr
,mapBilinear
,homTensorHom
,leftComm
,tensorTensorTensorComm
lcurry
,uncurry
, andassoc
to take an extra algebra, such that theA
s in the two different places can separately be replaced withR
The punchline here is really:
which is valuable for a base change / tensor product of bilinear forms when instantiated as
It would not surprise me if it's possible to introduce a third ring into
tensorTensorTensorComm
, but for now I'd prefer to assume that for that particular definition, two rings is enough for anybody!Unfortunately, this was not the case for
lcurry
,uncurry
, andassoc
, which really do need to work over three rings so that theA
s in the two different places can separately be replaced withR
; both permutations are needed in the construction oftensorTensorTensorComm
, and it seemed preferable to not have a plethora of primed variants.I make no claim that the pile of
IsScalarTower
andSMulCommClass
arguments here are in any sense optimal, besides the fact they specifically enable the use-case I have for the base change of bilinear forms.RingTheory/TensorProduct
#6187Extracted from pygae/lean-ga#31. There is more I want to extract from that patch (most notably the heterobasic
BilinForm.tensorDistrib
, but the rest will come in a future PR.