Zulip Chat Archive
Stream: mathlib4
Topic: Simp normal form in category of types
Christian Merten (Feb 09 2024 at 17:42):
When I want to simplify some term in the category of types, because of docs#CategoryTheory.types_comp_apply, simp often turns the term in something that it can't work with afterwards. Example:
import Mathlib
open CategoryTheory Limits
example {α β γ : Type} (f : α → γ) (g : β → γ) (a : α) (b : β) (h : f a = g b) :
(pullback.fst : _ ⟶ α) ((Types.pullbackIsoPullback f g).inv ⟨(a, b), h⟩) = a := by
simp -- does not work
example {α β γ : Type} (f : α → γ) (g : β → γ) (a : α) (b : β) (h : f a = g b) :
(pullback.fst : _ ⟶ α) ((Types.pullbackIsoPullback f g).inv ⟨(a, b), h⟩) = a := by
-- manually rewriting to apply the necessary lemma
show ((Types.pullbackIsoPullback f g).inv ≫ pullback.fst) ⟨(a, b), h⟩ = a
-- rw with this explicit lemma (using simp here undoes the above line)
rw [Types.pullbackIsoPullback_inv_fst]
How can I circumvent that? Can I locally disable usage of types_comp_apply? (which does not help if the statement is already in the applied form)
Or should the simp lemmas in docs#CategoryTheory.Limits.Shapes.Types be formulated in the applied form?
Adam Topaz (Feb 09 2024 at 17:46):
The structured answer is that we are supposed to use the "elementwise" tag to generate good simp lemmas when working in concrete categories. But in reality, I have also found working in the category of types to be quite annoying at time, for essentially this reason.
Christian Merten (Feb 09 2024 at 17:47):
Where would I use the "elementwise" tag? On docs#Types.pullbackIsoPullback ?
Adam Topaz (Feb 09 2024 at 17:48):
Adam Topaz (Feb 09 2024 at 17:51):
Personally I think we should redefine the category of types along the following lines:
import Mathlib.CategoryTheory.Category.Basic
open CategoryTheory
universe u
structure BundledFunction (A B : Type*) where
toFun : A → B
instance {A B} : FunLike (BundledFunction A B) A (fun _ => B) where
coe f := f.toFun
coe_injective' := fun ⟨f⟩ ⟨g⟩ _ => by congr
instance : Category (Type u) where
Hom := BundledFunction
id X := ⟨id⟩
comp f g := .mk <| g.toFun ∘ f.toFun
Christian Merten (Feb 09 2024 at 17:54):
Can you explain how that would solve this issue?
Adam Topaz (Feb 09 2024 at 17:57):
It would provide a layer of separation that distinguishes between morphisms and functions. So if you have a morphism f in Type u, the function would be f.toFun. In most cases where I've been annoyed by this the issue seemed that lean can't distinguish between when f should be a morphism and when it should be a function. This approach would add a syntactic separation between the two.
Adam Topaz (Feb 09 2024 at 17:58):
We had a similar issue with morphisms in the category of sheaves being defined as natural transformations, and making docs#CategoryTheory.Sheaf.Hom made it much better
Christian Merten (Feb 09 2024 at 17:59):
Adding
@[simp, elementwise]
to pullbackIsoPullback_inv_fst strangely yields this lemma
CategoryTheory.Limits.Types.pullbackIsoPullback_inv_fst_apply.{u} {X Y Z : Type u} (f : X ⟶ Z) (g : Y ⟶ Z)
(x : (Types.pullbackCone f g).pt) : pullback.fst ((Types.pullbackConeIsoPullback f g).inv.hom x) = (fun p ↦ (↑p).1) x
which says something about Types.pullbackConeIsoPullback f g instead of Types.pullbackIsoPullback f g. Is this expected?
Adam Topaz (Feb 09 2024 at 18:00):
this might be a bug in the elementwise attribute. probably one should apply docs#Lean.Expr.headBeta at some point
Christian Merten (Feb 09 2024 at 18:01):
Adam Topaz said:
It would provide a layer of separation that distinguishes between morphisms and functions. So if you have a morphism
finType u, the function would bef.toFun. In most cases where I've been annoyed by this the issue seemed that lean can't distinguish between whenfshould be a morphism and when it should be a function. This approach would add a syntactic separation between the two.
Makes sense, would you still want a types_comp_apply style lemma? If yes, it would probably not solve this issue, right?
Adam Topaz (Feb 09 2024 at 18:14):
Yes, there would still be such lemmas so you can use the simplifier to go back and forth between morphisms and functions.
Christian Merten (Feb 09 2024 at 18:16):
So also with your approach, we would need to tag everything as elementwise to have it work with types_comp_apply?
Adam Topaz (Feb 09 2024 at 18:18):
It's possible that elementwise wouldn't be needed anymore, but I don't know. I think the only way to see if this is a good solution is to try it out and see if things become easier!
Adam Topaz (Feb 09 2024 at 18:19):
FWIW I think it would make sense to do similar things for other "bundled" categories like Top, GroupCat, etc.
Adam Topaz (Feb 09 2024 at 18:20):
Especially in TopCat I found that lean often gets confused by the fact that morphisms are defined as terms of C(X,Y).
Kyle Miller (Feb 09 2024 at 18:22):
There's an elementwise_of% term elaborator for transforming lemmas by the way, but it doesn't do a final simp on the LHS and RHS. (@Adam Topaz @[elementwise] is supposed to do simp on its result, so I'm not sure why the RHS is (fun p ↦ (↑p).1) x.)
Christian Merten (Feb 09 2024 at 18:23):
I am more irritated about the appearance of Types.pullbackConeIsoPullback instead of Types.pullbackIsoPullback. Or can this be circumvented by using elementwise_of?
Kyle Miller (Feb 09 2024 at 18:25):
I'm guessing it's being caused by @[elementwise] doing simp and there's some simp lemma doing that transformation. The reason for simp by the way is that @[simp] lemmas need a LHS in simp normal form.
elementwise_of% should help you circumvent this, though I don't know if it will give you a lemma in a usable form.
Christian Merten (Feb 09 2024 at 18:31):
Kyle Miller said:
I'm guessing it's being caused by
@[elementwise]doingsimpand there's some simp lemma doing that transformation. The reason forsimpby the way is that@[simp]lemmas need a LHS in simp normal form.
elementwise_of%should help you circumvent this, though I don't know if it will give you a lemma in a usable form.
This does indeed generate the correct lemma. Can I tag pullbackIsoPullback_inv_fst somehow like for the elementwise attribute or do I have to write the lemma myself and use
rw [elementwise_of% pullbackIsoPullback_inv_fst]
as the proof?
Christian Merten (Feb 09 2024 at 18:36):
I am confused by this line in the docstring:
@[elementwise nosimp] to not use simp on both sides of the generated lemma
If I do this, the result is even worse, so apparently there is still some rewriting going on that is beyond CategoryTheory.coe_comp and CategoryTheory.coe_id?
Last updated: Feb 28 2026 at 14:05 UTC