Zulip Chat Archive
Stream: mathlib4
Topic: diamond in CommAlgCat
Michał Mrugała (Mar 24 2025 at 17:52):
I'm trying to prove that a commutative Hopf algebra over R : CommRingCat
defines an instance of a group object in (Under R)ᵒᵖ
, but I consistently run into an issue with type class inference. To illustrate the issue let's try defining the multiplication morphism:
open CategoryTheory Opposite
variable {R : CommRingCat} {A : Type*} [CommRing A] [HopfAlgebra R A]
noncomputable instance : Grp_Class <| op <| CommRingCat.mkUnder R A where
one := op <| (Bialgebra.counitAlgHom R A).toUnder
mul := op <| by
change R.mkUnder A ⟶ R.mkUnder _
simp
/-
⊢ R.mkUnder A ⟶ R.mkUnder (TensorProduct ↑R ↑(R.mkUnder A).right ↑(R.mkUnder A).right)
-/
refine (Bialgebra.comulAlgHom R A).toUnder
sorry
one_mul' := sorry
mul_one' := sorry
mul_assoc' := sorry
inv := sorry
left_inv' := sorry
right_inv' := sorry
The refine
fails due to a mismatch of the inferred typeclasses between Bialgebra.toAlgebra
and (CommRingCat.instAlgebraCarrierRightDiscretePUnit (R.mkUnder A))
. This can be solved by using the following:
noncomputable instance : Grp_Class <| op <| CommRingCat.mkUnder R A where
one := op <| (Bialgebra.counitAlgHom R A).toUnder
mul := op <| by
refine (Bialgebra.comulAlgHom R A).toUnder ≫ (Algebra.TensorProduct.map ?_ ?_).toUnder <;>
exact @AlgHom.mk _ _ _ _ _ _ _ (_) (.id _) fun _ ↦ rfl
However, this typeclass issue keeps consistently popping up in this context. Is there a way to prevent this mismatch from happening?
Yaël Dillies (Mar 24 2025 at 18:27):
For readers with less context than me, docs#CommRingCat.instAlgebraCarrierRightDiscretePUnit is constructed out of docs#RingHom.toAlgebra, which is known to cause non-defeq diamonds (because it makes up the redundant smul
field)
Yaël Dillies (Mar 24 2025 at 18:28):
Michał and I know why this mismatch is happening, so the question rather is: Can we design the code so as to avoid running into this mismatch?
Aaron Liu (Mar 24 2025 at 18:34):
Yaël Dillies said:
For readers with less context than me, docs#CommRingCat.instAlgebraCarrierRightDiscretePUnit is constructed out of docs#RingHom.toAlgebra, which is known to cause non-defeq diamonds (because it makes up the redundant
nsmul
,zsmul
, etc... fields)
I don't see those fields in docs#Algebra. Am I missing something?
Yaël Dillies (Mar 24 2025 at 18:36):
Sorry, I only mean docs#Algebra.smul. Edited. Same issue though ;-)
Kevin Buzzard (Mar 24 2025 at 19:27):
Is this a #mwe ? After import Mathlib
I get
failed to synthesize
ChosenFiniteProducts (Under R)ᵒᵖ
Is this what you're asking about? (I doubt it)
Michał Mrugała (Mar 24 2025 at 19:34):
This is not a mwe because of this instance not being in mathlib. I can post the code later.
Kevin Buzzard (Mar 24 2025 at 19:35):
Probably you can illustrate the diamond without posting the chosen finite products instance.
Kevin Buzzard (Mar 24 2025 at 19:45):
Is this your question:
import Mathlib
variable {R : CommRingCat} {A : Type*} [CommRing A] [Algebra R A]
example : A = ↑(CommRingCat.mkUnder R A) := rfl
def i1 : SMul R A := inferInstance
def i2 : SMul R ↑(CommRingCat.mkUnder R A) := inferInstance
example (r : R) (a : A) : @SMul.smul R A i1 r a = @SMul.smul R A i2 r a := rfl -- fails
? Yeah this is a common story in category theory, unfortunately. This sort of thing was the bane of Amelia's life when doing group cohomology.
Kevin Buzzard (Mar 24 2025 at 20:16):
As you say,
import Mathlib
variable {R : CommRingCat} {A : Type*} [CommRing A] [ia : Algebra R A]
example : A = ↑(CommRingCat.mkUnder R A) := rfl
def i1 : SMul R A := inferInstance
def i2 : SMul R ↑(CommRingCat.mkUnder R A) := inferInstance
example (r : R) (a : A) : @SMul.smul R A i1 r a = @SMul.smul R A i2 r a := by
change ia.1.1 r a = (algebraMap (↑R) A) r * a
sorry -- not rfl
Michał Mrugała (Mar 24 2025 at 21:29):
This looks like the same issue essentially, and it’s the bane of my existence because it makes simplifying and rewriting expressions a nightmare.
Kevin Buzzard (Mar 25 2025 at 16:28):
Yeah there is a fundamental problem with our set-up here. I still can't run your actual code to the see the problem because you still didn't post a #mwe so it's difficult to help. What happens if you remove the instance tag from CommRingCat.instAlgebraCarrierRightDiscretePUnit
?
Kevin Buzzard (Mar 25 2025 at 16:30):
You could also add something like instance [Algebra R A] : Algebra R ↑(CommRingCat.mkUnder R A) := inferInstanceAs (Algebra R A)
or whatever the syntax for that is.
Michał Mrugała (Mar 25 2025 at 16:42):
Here is the code for a working example:
import Mathlib
open CategoryTheory Limits Opposite
namespace CategoryTheory.Limits
variable {C : Type*} [Category C] {X Y Z : C} {f : X ⟶ Y} {g : X ⟶ Z}
@[simp]
def pushoutCocone.toBinaryCofan : PushoutCocone f g ⥤ BinaryCofan (Under.mk f) (.mk g) where
obj c := BinaryCofan.mk (Under.homMk (U := Under.mk f) c.inl rfl)
(Under.homMk (U := Under.mk g) (V := Under.mk (f ≫ c.inl)) c.inr c.condition.symm)
map {c1 c2} a := {
hom := Under.homMk a.hom
w := by rintro (_|_) <;> aesop_cat
}
@[simp]
def binaryCofanUnder.toPushoutCocone : BinaryCofan (Under.mk f) (.mk g) ⥤ PushoutCocone f g where
obj c := PushoutCocone.mk c.inl.right c.inr.right (c.inl.w.symm.trans c.inr.w)
map {c1 c2} a := {
hom := a.hom.right
w := by rintro (_|_|_) <;> simp [← Under.comp_right]
}
def aux_unit :
𝟭 (PushoutCocone f g) ≅ pushoutCocone.toBinaryCofan ⋙ binaryCofanUnder.toPushoutCocone :=
NatIso.ofComponents (fun c ↦ c.eta) (by aesop_cat)
def aux_counit :
binaryCofanUnder.toPushoutCocone ⋙ pushoutCocone.toBinaryCofan
≅ 𝟭 (BinaryCofan (Under.mk f) (Under.mk g)) :=
NatIso.ofComponents (fun X ↦ Limits.BinaryCofan.ext (Under.isoMk (Iso.refl _)
(by simpa using X.inl.w.symm)) (by aesop_cat) (by aesop_cat))
(by intros; ext; simp [BinaryCofan.ext])
@[simp]
def pushoutCoconeEquivBinaryCofan : PushoutCocone f g ≌ BinaryCofan (Under.mk f) (Under.mk g) :=
.mk pushoutCocone.toBinaryCofan binaryCofanUnder.toPushoutCocone aux_unit aux_counit
def pushoutCocone.IsColimit.toBinaryCofanIsColimit {c : PushoutCocone f g} (hc : IsColimit c) :
IsColimit <| pushoutCocone.toBinaryCofan.obj c :=
(IsColimit.ofCoconeEquiv pushoutCoconeEquivBinaryCofan).symm hc
end CategoryTheory.Limits
namespace CategoryTheory.Limits
variable {C : Type*} [Category C] {X Y P : C}
@[simps!]
def BinaryCofan.op (c : BinaryCofan X Y) : BinaryFan (.op X : Cᵒᵖ) (.op Y) :=
.mk (.op c.inl) (.op c.inr)
@[simps!]
def BinaryFan.unop (c : BinaryFan (.op X : Cᵒᵖ) (.op Y)) : BinaryCofan X Y :=
BinaryCofan.mk c.fst.unop c.snd.unop
@[simp] lemma BinaryCofan.op_mk (ι₁ : X ⟶ P) (ι₂ : Y ⟶ P) : op (mk ι₁ ι₂) = .mk ι₁.op ι₂.op := rfl
@[simp] lemma BinaryFan.unop_mk (ι₁ : op P ⟶ op X) (ι₂ : op P ⟶ op Y) :
unop (mk ι₁ ι₂) = .mk ι₁.unop ι₂.unop := rfl
lemma aux {D : Type*} [Category D] {F G : C ⥤ D} (α : F ⟶ G) :
(NatTrans.op α).app (.op X) = (α.app X).op := rfl
def BinaryCofan.IsColimit.op {c : BinaryCofan X Y} (hc : IsColimit c) : IsLimit <| c.op where
lift s := .op <| hc.desc (BinaryFan.unop s)
fac s := by rintro (_|_) <;> simp [← CategoryTheory.op_comp, hc.fac]
uniq s m h := by
replace h j : c.ι.app j ≫ m.unop = (BinaryFan.unop s).ι.app j := by
specialize h j; obtain ⟨_ | _⟩ := j <;> simpa using Quiver.Hom.op_inj h
simpa using congr($(hc.uniq (BinaryFan.unop s) m.unop h).op)
end CategoryTheory.Limits
namespace CommRingCat.Under
variable {R : CommRingCat}
/-- A choice of finite products of `(Under R)ᵒᵖ` for `R : CommRingCat` given by the tensor product.
-/
noncomputable instance chosenFiniteProducts : ChosenFiniteProducts (Under R)ᵒᵖ where
product X Y := {
cone := BinaryCofan.op <| pushoutCocone.toBinaryCofan.obj <|
pushoutCocone R (unop X).right (unop Y).right
isLimit := BinaryCofan.IsColimit.op <| pushoutCocone.IsColimit.toBinaryCofanIsColimit <|
CommRingCat.pushoutCoconeIsColimit R _ _
}
terminal := ⟨_, terminalOpOfInitial Under.mkIdInitial⟩
end CommRingCat.Under
variable {R : CommRingCat} {A : Type*} [CommRing A] [HopfAlgebra R A]
noncomputable instance : Grp_Class <| op <| CommRingCat.mkUnder R A where
one := op <| (Bialgebra.counitAlgHom R A).toUnder
mul := op <| by
change R.mkUnder A ⟶ R.mkUnder _
simp
/-
⊢ R.mkUnder A ⟶ R.mkUnder (TensorProduct ↑R ↑(R.mkUnder A).right ↑(R.mkUnder A).right)
-/
--refine (Bialgebra.comulAlgHom R A).toUnder
sorry
one_mul' := sorry
mul_one' := sorry
mul_assoc' := sorry
inv := sorry
left_inv' := sorry
right_inv' := sorry
Kevin Buzzard (Mar 25 2025 at 18:45):
Thanks. So just to summarise the issue:
If you remove the problematic instance with attribute [-instance] CommRingCat.instAlgebraCarrierRightDiscretePUnit
then the first thing that breaks is the instance for ChosenFiniteProducts (Under R)ᵒᵖ
, because given X : (Under R)ᵒᵖ
Lean needs to find an instance of Algebra ↑R ↑(unop X).right
and it can't do so. If you make this instance with docs#CommRingCat.instAlgebraCarrierRightDiscretePUnit then you'll get a diamond if you ever apply it with X = op (R.mkUnder A)
for some [Algebra R A]
because then ↑(unop X).right
is defeq to A
but the typeclass inference system finds different (i.e. definitionally different, but propeq) algebra instances on the two types. However if you try to avoid such A
s and just work with X
s of type (Under R)ᵒᵖ
then there is no way to say "I am actually a Hopf algebra" because HopfAlgebra
extends Algebra
.
In simple terms, if you start with [Algebra R A]
and then turn A
into a term of type Under R
and then back into a type, you end up with a definitionally different algebra instance on a definitionally equal type. This means that it's extremely annoying to do mathematics which relies on both constructions made in type-land (e.g. HopfAlgebra
) and in category-land (e.g. ChosenFiniteProducts
). A key example of such mathemtics is the theory of group schemes, which is absolutely essential for FLT. So we have a very interesting problem here!
Kevin Buzzard (Mar 25 2025 at 18:50):
Here's the diamond, as noted above, plus the proof that it's propeq:
import Mathlib
variable {R : CommRingCat} {A : Type*} [CommRing A] [Algebra R A]
example : A = ↑(CommRingCat.mkUnder R A) := rfl
def i1 : SMul R A := inferInstance
def i2 : SMul R ↑(CommRingCat.mkUnder R A) := inferInstance
example (r : R) (a : A) : @SMul.smul R A i1 r a = @SMul.smul R A i2 r a := by
change r • a = (algebraMap (↑R) A) r * a
exact Algebra.smul_def r a -- but not `rfl`
Michał Mrugała (Mar 25 2025 at 18:51):
Yeah this summary is pretty much what we've concluded as well. One idea that's been floated is to just define CommAlgCat
and work with that instead of Under R
. We've managed to deal with the diamonds for proofs of one_mul'
and mul_one'
but mul_comm'
seems extremely painful because this diamond happens internally in the triple tensor product.
Kevin Buzzard (Mar 25 2025 at 18:53):
This discussion needs to move to #mathlib4 so some expert eyes will see it (many of the people who might be able to say something helpful are not subscribed to this channel). I'll start a new thread.
Yaël Dillies (Mar 25 2025 at 19:03):
Can't you move the existing one? EDIT: I guess the point is that you get to write a better summary of the situation
Notification Bot (Mar 25 2025 at 19:06):
This topic was moved here from #new members > Algebra type class inference by Kevin Buzzard.
Eric Wieser (Mar 25 2025 at 19:09):
Fundamentally the issue here is that docs#CommRingCat.instAlgebraCarrierRightDiscretePUnit uses RingHom.toAlgebra
, which almost always creates diamonds
Eric Wieser (Mar 25 2025 at 19:09):
But in this case it has no other choice, because the SMul
instance which is carried by Algebra
to avoid the diamond cannot be carried by CategoryTheory.Under R
Kevin Buzzard (Mar 25 2025 at 19:09):
I wonder whether a way of fixing the issue is defining CommAlgCat R
so that the objects are (edit: types A equipped with) terms of type Algebra R A
Eric Wieser (Mar 25 2025 at 19:10):
Yes, I think this is an argument for not defining CommAlgCat
in terms of Under
Eric Wieser (Mar 25 2025 at 19:11):
@Kyle Miller, do you have any idea where nevermind, it's from expanding DiscretePUnit
is being inserted in the name from?Under
Kevin Buzzard (Mar 25 2025 at 19:12):
Is there another highly disruptive but possible approach, involving redefining Algebra R A
as a ring morphism and defining the SMul to be f(r) * a? Or is this impossible for other reasons?
Eric Wieser (Mar 25 2025 at 19:13):
That's impossible for other reasons, consider A := Matrix n n R
and the natural module structure on matrices: diagonal (algebraMap _ _ r) * M
is not possible to make defeq to r • M
Eric Wieser (Mar 25 2025 at 19:15):
Maybe CategoryTheory.Under
could take some extra [UnderData R]
assumption, which for CommRingCat
carries the smul action?
Michał Mrugała (Mar 25 2025 at 20:11):
CommAlgCat
seems to be working well
Kim Morrison (Mar 25 2025 at 21:37):
Can someone remind me why we wanted to avoid a hand-rolled CommAlgCat
in favour of using Under
? Just avoiding having two ways to say the same thing?
Andrew Yang (Apr 03 2025 at 16:00):
Yes. And to apply the general category theoretic machinery about Over
categories.
Last updated: May 02 2025 at 03:31 UTC