Zulip Chat Archive
Stream: new members
Topic: golf request: `PushoutCocone ≌ BinaryCofan`
Michał Mrugała (Mar 14 2025 at 14:57):
Hiya, there has to be a cleaner way of doing this, but I'm not familiar enough with the category theory API to spot it:
import Mathlib
open CategoryTheory Opposite Limits
section
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) (Under.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 (_|_)
repeat
ext
exact a.w _
}
@[simp]
def binaryCofanUnder.toPushoutCocone :
BinaryCofan (Under.mk f) (Under.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 where
hom.app c := c.eta.hom
inv.app c := c.eta.inv
inv.naturality {c1 c2} a := by ext; simp
@[simp]
def aux_hom :
binaryCofanUnder.toPushoutCocone ⋙ pushoutCocone.toBinaryCofan
⟶ 𝟭 (BinaryCofan (Under.mk f) (Under.mk g)) where
app c := {
hom := {
left := 𝟙 c.pt.left
right := 𝟙 c.pt.right
w := by simpa using c.inl.w
}
w := by rintro (_|_) <;> { ext; simp }
}
@[simp]
def aux_inv :
𝟭 (BinaryCofan (Under.mk f) (Under.mk g))
⟶ binaryCofanUnder.toPushoutCocone ⋙ pushoutCocone.toBinaryCofan where
app c := {
hom := {
left := 𝟙 c.pt.left
right := 𝟙 c.pt.right
w := by simpa using c.inl.w.symm
}
w := by rintro (_|_) <;> { ext; simp }
}
def aux_counit :
binaryCofanUnder.toPushoutCocone ⋙ pushoutCocone.toBinaryCofan
≅ 𝟭 (BinaryCofan (Under.mk f) (Under.mk g)) where
hom := aux_hom
inv := aux_inv
hom_inv_id := by ext; simp
inv_hom_id := by ext; simp
def pushoutCoconeEquivBinaryCofan : PushoutCocone f g ≌ BinaryCofan (Under.mk f) (Under.mk g) :=
.mk pushoutCocone.toBinaryCofan binaryCofanUnder.toPushoutCocone aux_unit aux_counit
end
Andrew Yang (Mar 14 2025 at 15:23):
The unit is NatIso.ofComponents (fun c ↦ c.eta) (by aesop_cat)
, and the counit is
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])
And you should use mk'
instead of mk
in the final construction of equivalences.
Michał Mrugała (Mar 14 2025 at 15:24):
Is there a reason to use mk'
instead of mk
here? It just requires strictly more information.
Andrew Yang (Mar 14 2025 at 15:43):
mk'
gives better defeqs. You can see how mk
is done.
Michał Mrugała (Mar 14 2025 at 15:45):
I know that it adjoinifies, but @Bhavik Mehta seemed to think mk
is preferable to use here, unless we care about the half-adjunction.
Bhavik Mehta (Mar 14 2025 at 15:50):
I don't know that the defeqs actually matter here? The other benefit of mk
here was that it's faster (particularly because the version of this code I saw was very close to timing out), but now that it's split up, perhaps that's no longer a factor.
Joël Riou (Mar 14 2025 at 15:54):
Michał Mrugała said:
I know that it adjoinifies, but Bhavik Mehta seemed to think
mk
is preferable to use here, unless we care about the half-adjunction.
I think it is better not to bet that nobody will ever need reasonably good definitional properties for unit/counit isomorphisms. In order to make #12728 work, I had to fix unnecessary uses of Equivalence.mk
in #15919. When there is no difficulty showing functor_unitIso_comp
, we should always use Equivalence.mk'
.
Bhavik Mehta (Mar 14 2025 at 15:56):
Perhaps it would be sensible to add this to the docstrings
Michał Mrugała (Mar 14 2025 at 16:08):
I'll add this to the golf request as well (goes after the first code block)
def pushoutCocone.IsColimit.toBinaryCofanIsColimit (c : PushoutCocone f g) (hc : IsColimit c) :
IsColimit <| pushoutCocone.toBinaryCofan.obj c :=
BinaryCofan.isColimitMk (fun s ↦
Under.homMk (hc.desc <| binaryCofanUnder.toPushoutCocone.obj s) (by simpa using s.inl.w.symm))
(by aesop_cat) (by aesop_cat) (fun s m h₁ h₂ ↦
(by
ext
simp
apply hc.uniq (binaryCofanUnder.toPushoutCocone.obj s) m.right
rintro (_|_|_)
· simp [← h₁]
· simp [← h₁]
simp [← h₂]
))
Michał Mrugała (Mar 14 2025 at 16:10):
It feels like I'm doing something wrong since I'm reusing the same arguments I used for the equivalence
Andrew Yang (Mar 14 2025 at 16:13):
You should use docs#CategoryTheory.Limits.IsColimit.ofCoconeEquiv
Michał Mrugała (Mar 14 2025 at 16:23):
Much better, though it still feels like I'm missing a way to simplify the end
def pushoutCocone.IsColimit.toBinaryCofanIsColimit (c : PushoutCocone f g) (hc : IsColimit c) :
IsColimit <| pushoutCocone.toBinaryCofan.obj c :=
.ofCoconeEquiv pushoutCoconeEquivBinaryCofan.symm (.ofIsoColimit hc (by simp; exact c.eta))
Last updated: May 02 2025 at 03:31 UTC