Zulip Chat Archive
Stream: general
Topic: Product of Group Actions
Yiming Xu (Nov 21 2024 at 09:19):
I want to prove the category of right actions of a monoid M
has exponentials. I wrote:
import Mathlib
import Mathlib.Algebra.Category.Grp.Basic
import Mathlib.CategoryTheory.SingleObj
import Mathlib.CategoryTheory.Limits.FunctorCategory.Basic
import Mathlib.CategoryTheory.Limits.Preserves.Basic
import Mathlib.CategoryTheory.Adjunction.Limits
import Mathlib.CategoryTheory.Conj
set_option autoImplicit false
set_option diagnostics true
open CategoryTheory Limits
universe u
variable {M : Type u} [Monoid M]
/-
Plan:
Start with (A : Action (Type u) (MonCat.of (MulOpposite M)))
construct the action A × M
construct the set of equivariant maps A × M → B, for any
(B : Action (Type u) (MonCat.of (MulOpposite M)))
then bundle these maps as a type.
construct an action of M on this type, make it an M action
use Action.ofMulAction.
-/
instance AtoB (A: Action (Type u) (MonCat.of (MulOpposite M)))
(B: Action (Type u) (MonCat.of (MulOpposite M))):
Action (Type u) (MonCat.of (MulOpposite M)) :=
{V := (Action.Hom (A × M) B) }
Lean complains by adding a red underscore under "V := (Action.Hom (A × M) B)", and says:
application type mismatch
Prod A
argument
A
has type
Action (Type u) (MonCat.of Mᵐᵒᵖ) : Type (u + 1)
but is expected to have type
Type ?u.1041 : Type (?u.1041 + 1)
Seems to be a universe problem. May I please ask for the reason and how to fix that? Thanks!
Eric Wieser (Nov 21 2024 at 11:43):
This doesn't look like a universe problem to me, the issue is that × works on Type
not Action _ _
Yiming Xu (Nov 21 2024 at 12:21):
But as Actions has products, as I can have instance:
instance : HasFiniteProducts ((Action (Type u) (MonCat.of (MulOpposite M)))) := inferInstance
The product should work as well I think? Or am I naive?
Yiming Xu (Nov 21 2024 at 12:22):
How should I construct product action then? And how can I check if the notion of product of actions is what I need? i.e. componentwise?
Edward van de Meent (Nov 21 2024 at 12:49):
i imagine you can choose
a product using HasFiniteProducts.out 2 ...
?
Yiming Xu (Nov 21 2024 at 12:52):
Thanks for brining up this issue! I went to talk to colleagues and got the problem solved.
What is happening here is that:
1.My notation is wrong: it should be \otimes
or \ox
, instead of \times
, for monoidal products.
2.I should open MonoidalCategory to get it work.
So in this case the error message is not helpful. Now the following works.
import Mathlib
import Mathlib.Algebra.Category.Grp.Basic
import Mathlib.CategoryTheory.SingleObj
import Mathlib.CategoryTheory.Limits.FunctorCategory.Basic
import Mathlib.CategoryTheory.Limits.Preserves.Basic
import Mathlib.CategoryTheory.Adjunction.Limits
import Mathlib.CategoryTheory.Conj
set_option autoImplicit false
set_option diagnostics true
open CategoryTheory Limits
open MonoidalCategory
universe u
variable {M : Type u} [Monoid M]
instance : Category (Action (Type u) (MonCat.of (MulOpposite M))) := inferInstance
#synth HasFiniteProducts ((Action (Type u) (MonCat.of (MulOpposite M))))
instance : HasFiniteProducts ((Action (Type u) (MonCat.of (MulOpposite M)))) := inferInstance
/-
Start with (A : Action (Type u) (MonCat.of (MulOpposite M)))
construct the action A × M
construct the set of equivariant maps A × M → B, for any
(B : Action (Type u) (MonCat.of (MulOpposite M)))
then bundle these maps as a type.
construct an action of M on this type, make it an M action
use Action.ofMulAction.
-/
/-instance (A: Action (Type u) (MonCat.of (MulOpposite M)))
(B: Action (Type u) (MonCat.of (MulOpposite M))):
MulAction (MulOpposite M) (Action.Hom (A × M) B) := sorry-/
variables (A: Action (Type u) (MonCat.of (MulOpposite M)))
(B: Action (Type u) (MonCat.of (MulOpposite M)))
#check (Action.leftRegular (MulOpposite M))
#check A
#check MulOpposite M
#check (Action.leftRegular (MulOpposite M)) ⊗ A
#check (Action.Hom (A ⊗ (Action.leftRegular (MulOpposite M))) B)
instance AtoB (A: Action (Type u) (MonCat.of (MulOpposite M)))
(B: Action (Type u) (MonCat.of (MulOpposite M))):
Action (Type u) (MonCat.of (MulOpposite M)) :=
{V := (Action.Hom (A ⊗ (Action.leftRegular (MulOpposite M))) B)
ρ := sorry
}
Yiming Xu (Nov 21 2024 at 12:54):
As for the issue for chosen product, there is an instance saying that the forgetful functor from actions to sets reflects limits. That is saying the choice of product structure should be up to isomorphism. So the choice does not matter. It is still important to know, since HasFiniteProducts only gives the product, in which case you can still use \otimes
, and Lean will choose a product for you. But ChosenFiniteProduct has the product encoded as a part of the structure.
Johan Commelin (Nov 22 2024 at 04:54):
As you can see, this requires you to write a lot of MonCat.of
etc... If what you are doing is not directly category theoretic in nature, it might be smoother to work in the unbundled world.
Yiming Xu (Nov 22 2024 at 05:03):
Johan Commelin said:
As you can see, this requires you to write a lot of
MonCat.of
etc... If what you are doing is not directly category theoretic in nature, it might be smoother to work in the unbundled world.
Thanks for this suggestion, I am indeed considering this. Maybe one way of doing that would be working with the unbundled world first and search for "transporting" to the bundled world. I would appreciate if there is some existing work on how to do this kind of transfer uniformly.
Johan Commelin (Nov 22 2024 at 05:17):
Hmmz, I don't think we have a tutorial on that.
What exactly would you like to do with products of group actions?
Yiming Xu (Nov 22 2024 at 06:17):
Johan Commelin said:
Hmmz, I don't think we have a tutorial on that.
What exactly would you like to do with products of group actions?
Thanks so much for trying to help!
I want to prove the category of right actions of a monoid has exponentials. My aim in the recent weeks is to get myself familiarized with Lean and the category theory part of the library as well.
Yiming Xu (Nov 22 2024 at 06:18):
Yiming Xu (Nov 22 2024 at 06:19):
This is the exercise I am doing. I was originally only would like a practice. But since it is not in mathlib yet. It might be better if it can be made to connectable with Mathlib.
Johan Commelin (Nov 23 2024 at 05:12):
I see. So yes, I think it would be good to first do think in the language of monoids and actions without category theory.
Johan Commelin (Nov 23 2024 at 05:13):
So just use (M : Type*) [Monoid M]
instead of (M : MonCat)
Yiming Xu (Nov 23 2024 at 05:18):
Johan Commelin said:
I see. So yes, I think it would be good to first do think in the language of monoids and actions without category theory.
Thanks! I will do it this way first. I do need to familiarize myself with the category theory library as well, but I can do it in parallel and try to put them together later.
Yiming Xu (Nov 25 2024 at 08:33):
Johan Commelin said:
I see. So yes, I think it would be good to first do think in the language of monoids and actions without category theory.
So I have defined the bijection and now to get access to the Lean definition of exponential, I am afraid that I do need to deal with MonCat. The exercise above uses a fixed finite product action, namely the pointwise one. But I failed to find out a precise definition of the product on (Action (Type u) (MonCat.of (MulOpposite M)))
. I can only get hat it has finite products.
instance : HasFiniteProducts (Action (Type u) (MonCat.of (MulOpposite M))) := inferInstance --fine
instance : ChosenFiniteProducts (Action (Type u) (MonCat.of (MulOpposite M))) := inferInstance --error
Yiming Xu (Nov 25 2024 at 08:37):
As products are unique up to isomorphism, it might be fine to construct an explicit product pointwisely, and then prove that it should be equivalent to the witness in HasFiniteProduct. But it would take a while to construct the product according to the definition, since the definition of product in Lean is in terms of limit. I will have to deal with the limit cone, like this...:
instance (X : Action (Type u) (MonCat.of (MulOpposite M)))
(Y : Action (Type u) (MonCat.of (MulOpposite M))):
Limits.LimitCone (Limits.pair X Y) where
cone := {
pt := PairwiseAction X Y
π := {
app := fun
| .mk as =>
match as with
| WalkingPair.left => {
hom := fun
| .mk fst snd => fst
}
| WalkingPair.right => {
hom := fun
| .mk fst snd => snd
}
naturality := by
simp
intros l r f
ext p
dsimp [PairwiseV_def' X Y] at p
--rw [PairwiseV_def' X Y] at p
--rw [show ((PairwiseAction X Y).V = (X.V × Y.V)) by rfl] at p
--rw [PairwiseV_def X Y] at p
cases' r with as
cases' as
simp
cases' l with as
cases' as
· dsimp
-- have a : f = 𝟙 ({ as := WalkingPair.left }: Discrete WalkingPair) := rfl
have a : f = 𝟙 (Discrete.mk WalkingPair.left) := rfl
simp[a]
· dsimp
nomatch f
· cases' p with x y
cases' l with as
cases as
· nomatch f
· dsimp
have a : f = 𝟙 (Discrete.mk WalkingPair.right) := rfl
simp[a]
}
}
isLimit := {
lift := sorry
fac := sorry
uniq := sorry
}
So does it seem like I have to do it that way?
Yiming Xu (Nov 25 2024 at 08:38):
I can indeed define the bijection, and prove the definition is indeed a bijection, purely in the unbundled world, like this:
import Mathlib.Algebra.Category.Grp.Basic
import Mathlib.CategoryTheory.SingleObj
import Mathlib.CategoryTheory.Limits.FunctorCategory.Basic
import Mathlib.CategoryTheory.Limits.Preserves.Basic
import Mathlib.CategoryTheory.Adjunction.Limits
import Mathlib.CategoryTheory.Conj
set_option autoImplicit false
set_option diagnostics true
#check MulOpposite
variable (M : Type*) [Monoid M] {X : Type*} {Y:Type*}
--#check @Monoid.toOppositeMulAction M h
#check ‹Monoid M›
#check Mul (Mᵐᵒᵖ)
#check @Monoid.toOppositeMulAction M ‹Monoid M›
#check @Monoid.toOppositeMulAction M inferInstance
open MulOpposite
--TODO maybe creat a class RSMul, for right action,and prove that
--for each left action, the property for the right action
@[ext]
structure EquivariantMaps (X : Type*) (Y:Type*)
[MulAction M X] [MulAction M Y] where
toFun: X → Y
comm_square : ∀ (x : X) (m : M), m • (toFun x) = toFun (m • x)
def OntoFun {X : Type*} {Y:Type*} (k : MulOpposite M) (e : M × X → Y) : M × X → Y :=
fun (g,x) => e ((unop k) * g, x)
theorem OntoFun_def (k : MulOpposite M) (e : M × X → Y) :
OntoFun M k e = fun (g,x) ↦ e ( (unop k) * g, x) :=by rfl
instance EquivariantMaps.SMul (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]:
SMul (MulOpposite M) (EquivariantMaps (MulOpposite M) (M × X) Y) where
smul k e := {
toFun := OntoFun M k e.toFun
comm_square := by
intros p opm
cases' p with m x
simp
simp[OntoFun_def]
simp [e.comm_square (unop k * m, x) opm]
simp[mul_assoc]
}
theorem smul_EquivariantMaps
(X : Type*) (Y:Type*)
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(k: MulOpposite M) (e : EquivariantMaps (MulOpposite M) (M × X) Y) (g : M) (x : X):
(k • e).toFun (g,x) = e.toFun ( (unop k) * g, x) := rfl
instance (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y] : MulAction (MulOpposite M) (EquivariantMaps (MulOpposite M) (M × X) Y)
where
smul k e := (EquivariantMaps.SMul M X Y).smul k e
one_smul := by
intros e
ext ⟨g,x⟩
simp[smul_EquivariantMaps]
mul_smul := by
intros k1 k2 e
ext ⟨g,x⟩
simp[smul_EquivariantMaps]
simp[mul_assoc]
--Hom(Z×X,Y)∼=Hom(Z,Hom(M×X, Y )).
def ActionTransposefun (Z:Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: Z × X → Y) (z : Z) : M × X → Y := fun
| .mk m x => f ⟨op m • z, x⟩
theorem ActionTransposefun_def
(Z : Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: Z × X → Y) (z : Z) (m : M) (x: X) :
ActionTransposefun M Z X Y f z ⟨m,x⟩ = f ⟨op m • z, x⟩ := rfl
def ActionTransposeEquivariantMap
(Z:Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: EquivariantMaps (MulOpposite M) (Z × X) Y) (z : Z) :
EquivariantMaps (MulOpposite M) (M × X) Y where
toFun := ActionTransposefun M Z X Y f.toFun z
comm_square := by
intros mx mop
cases' mx with m x
simp
simp[ActionTransposefun_def]
simp[f.comm_square]
simp[mul_smul] --how to invoke it on Z? I think I have an answer
theorem ActionTransposeEquivariantMap_toFun
(Z:Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: EquivariantMaps (MulOpposite M) (Z × X) Y) (z : Z):
(ActionTransposeEquivariantMap M Z X Y f z).toFun =
ActionTransposefun M Z X Y f.toFun z := rfl
def ActionTransposeEquivariantMapHom
(Z:Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: EquivariantMaps (MulOpposite M) (Z × X) Y):
EquivariantMaps (MulOpposite M)
Z
(EquivariantMaps (MulOpposite M) (M × X) Y) where
toFun z := ActionTransposeEquivariantMap M Z X Y f z
comm_square := by
intros z m
simp
ext ⟨m1,x⟩
simp[smul_EquivariantMaps]
simp[ActionTransposeEquivariantMap_toFun]
simp[ActionTransposefun_def]
simp[mul_smul]
theorem ActionTransposeEquivariantMapHom_toFun
(Z:Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: EquivariantMaps (MulOpposite M) (Z × X) Y):
(ActionTransposeEquivariantMapHom M Z X Y f).toFun =
fun z => ActionTransposeEquivariantMap M Z X Y f z := rfl
def ActionTransposefunr (Z:Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: Z → EquivariantMaps (MulOpposite M) (M × X) Y) : Z × X → Y := fun
| .mk z x => (f z).toFun ⟨ 1 , x⟩
theorem ActionTransposefunr_def
(Z : Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: Z → EquivariantMaps (MulOpposite M) (M × X) Y) (z : Z) (x: X):
ActionTransposefunr M Z X Y f ⟨ z,x⟩ = (f z).toFun ⟨1, x⟩ := rfl
theorem ActionTransposeEquivariantMapr_lemma
(Z:Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: EquivariantMaps (MulOpposite M)
Z (EquivariantMaps (MulOpposite M) (M × X) Y))
(mop : Mᵐᵒᵖ) (z : Z) (x : X) :
(f.toFun (mop • z)).toFun (1, x) =
(f.toFun z).toFun (unop mop, x) := by
have h0 : f.toFun (mop • z) = mop • f.toFun z := by
simp[f.comm_square]
simp[h0]
simp[smul_EquivariantMaps]
def ActionTransposeEquivariantMapr
(Z:Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: EquivariantMaps (MulOpposite M)
Z (EquivariantMaps (MulOpposite M) (M × X) Y)):
EquivariantMaps (MulOpposite M) (Z × X) Y where
toFun := ActionTransposefunr M Z X Y f.toFun
comm_square := by
intros zx mop
cases' zx with z x
simp
simp[ActionTransposefunr_def]
simp[(f.toFun z).comm_square]
have a : (f.toFun (mop • z)).toFun (1, mop • x) =
(f.toFun z).toFun (unop mop, mop • x) := by
have h0 : f.toFun (mop • z) = mop • f.toFun z := by
simp[f.comm_square]
simp[h0]
simp[smul_EquivariantMaps]
simp[a]
theorem ActionTransposeEquivariantMapr_toFun
(Z:Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: EquivariantMaps (MulOpposite M)
Z (EquivariantMaps (MulOpposite M) (M × X) Y)):
(ActionTransposeEquivariantMapr M Z X Y f).toFun =
ActionTransposefunr M Z X Y f.toFun := rfl
lemma ActionTransposeInverse
(Z:Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: EquivariantMaps (MulOpposite M) (Z × X) Y):
ActionTransposeEquivariantMapr M Z X Y
(ActionTransposeEquivariantMapHom M Z X Y f) = f := by
ext ⟨z,x⟩
simp[ActionTransposeEquivariantMapr_toFun]
simp[ActionTransposefunr_def]
simp[ActionTransposeEquivariantMapHom_toFun]
simp[ActionTransposeEquivariantMap_toFun]
simp[ActionTransposefun_def]
lemma ActionTransposeInverse'
(Z:Type*) (X : Type*) (Y:Type*)
[MulAction (MulOpposite M) Z]
[MulAction (MulOpposite M) X]
[MulAction (MulOpposite M) Y]
(f: EquivariantMaps (MulOpposite M)
Z (EquivariantMaps (MulOpposite M) (M × X) Y)):
ActionTransposeEquivariantMapHom M Z X Y
(ActionTransposeEquivariantMapr M Z X Y f) = f := by
ext z mx
cases' mx with m x
simp[ActionTransposeEquivariantMapHom_toFun]
simp[ActionTransposeEquivariantMap_toFun]
simp[ActionTransposefun_def]
simp[ActionTransposeEquivariantMapr_toFun]
simp[ActionTransposefunr_def]
simp[ActionTransposeEquivariantMapr_lemma]
Yiming Xu (Nov 25 2024 at 08:39):
The remaining is about the construction of adjoint functors and refers to the category library.
Yiming Xu (Nov 25 2024 at 08:50):
I think maybe one thing I can do is to define a product functor myself (instead of converting the existing product structure on MonCat into a functor of "taking product with"), and then construct the exponential functor, prove they are adjoints, and transfer along an isomorphism between "the product functor I defined" and "the product functor obtained via the instance HasFiniteProduct
".
Yiming Xu (Nov 25 2024 at 08:59):
(This is just something I set up for myself to get used to the standard algebra library and the category theory library and connect concrete examples to the categorical world. The plan is to first do the algebra world, then deal with the functors to prove it is indeed an exponential in the categorical world. Then prove presheaf categories are Cartesian closed and see if it will imply the algebraic version...). If the middle step sounds very messy, I may try the presheaf stuff first as well.
Last updated: May 02 2025 at 03:31 UTC