Skip to content
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] - refactor(Algebra/Category): turn homs in AlgebraCat into a structure #19065

Closed
wants to merge 25 commits into from

Conversation

chrisflav
Copy link
Collaborator

@chrisflav chrisflav commented Nov 15, 2024

In the current design of concrete categories in mathlib, there are two sources of erws:

  • Def-Eq abuse of A ⟶ B and A →ₐ [R] B: The type of A ⟶ B is by definition A →ₐ[R] B, but not at reducible transparency. So it happens that one rw lemma transforms a term in a form, where the next rw expects A →ₐ B. By supplying explicit show lines (copying the output of the pretty-printer), Lean correctly re-synthesizes the type to be A →ₐ B and the rw succeeds. This def-eq abuse hence always causes issues in the case where a lemma from the non-category theoretic part of the library should be applied. An insightful example is the following proof excerpt from current master (proof of AlgebraCat.adj):
import Mathlib.Algebra.Category.AlgebraCat.Basic
open CategoryTheory AlgebraCat
variable {R : Type u} [CommRing R]
set_option pp.analyze true

example : free.{u} R ⊣ forget (AlgebraCat.{u} R) :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun _ _ => (FreeAlgebra.lift _).symm
      homEquiv_naturality_left_symm := by
        intro X Y Z f g
        apply FreeAlgebra.hom_ext
        ext x
        simp only [Equiv.symm_symm, Function.comp_apply, free_map]
        /- Eq (α := Z)
             (((FreeAlgebra.lift R) (f ≫ g) :
               Prefunctor.obj (Functor.toPrefunctor (free R)) X ⟶ Z) (FreeAlgebra.ι R x) : ↑Z) _
        -/
        erw [FreeAlgebra.lift_ι_apply]
        sorry
      homEquiv_naturality_right := sorry }

The simp lemma FreeAlgebra.lift_ι_apply expects an AlgHom, but as the pp.analyze shows, the type is synthesized as a . With a show line before the erw, Lean correctly synthesizes the type as an AlgHom again and the rw succeeds. The solution is to strictly distinguish between A ⟶ B and A →ₐ[R] B: We define a new AlgebraCat.Hom structure with a single field hom : A →ₐ[R] B. The above proof is mostly solved by ext; simp then, except for the ext lemma FreeAlgebra.hom_ext not applying. This is because now the type is AlgebraCat.of R (FreeAlgebra R X) →ₐ[R] _ and Lean can't see through the AlgebraCat.of at reducible transparency. Hence the solution is to make AlgebraCat.of an abbrev. Finally, the proof is by ext; simp or even by aesop.

  • FunLike: An intermediate design adapted the changes from the first point, but with keeping a FunLike and an AlgHomClass instance on A ⟶ B. This lead to many additional coe lemmas for composition of morphisms, where it mattered which of the three appearing terms of AlgebraCat where of the form AlgebraCat.of R A. Eric Wieser suggested to replace the FunLike by a CoeFun which is inlined, so an invocation of f x turns into f.hom x. This has then worked very smoothly.

So the key points are:

  • Homs in concrete categories should be one-field structures to maintain a strict type distinction.
  • Use CoeFun instead of FunLike, since the latter is automatically inlined.
  • Make .of constructors an abbrev to obtain the def-eq ↑(AlgebraCat.of R A) = A at reducible transparency.

For more details, see the Zulip discussion.


Open in Gitpod

@chrisflav chrisflav added t-category-theory Category theory t-algebra Algebra (groups, rings, fields, etc) RFC Request for comment labels Nov 15, 2024
Copy link

github-actions bot commented Nov 15, 2024

PR summary 04c436374e

Import changes for modified files

No significant changes to the import graph

Import changes for all files
Files Import difference

Declarations diff

+ Hom
+ comp_apply
+ forget_map
+ forget_obj
+ hom_comp
+ hom_ext
+ hom_id
+ hom_inv_apply
+ hom_ofHom
+ instance {M N : AlgebraCat.{v} R} : CoeFun (M ⟶ N) (fun _ ↦ M → N)
+ inv_hom_apply
+ ofHom_comp
+ ofHom_hom
+ ofHom_id
- AlgHom.comp_id_algebraCat
- AlgHom.id_algebraCat_comp
- coe_comp
- instance {M N : AlgebraCat.{v} R} : AlgHomClass (M ⟶ N) R M N
- instance {M N : AlgebraCat.{v} R} : FunLike (M ⟶ N) M N

You can run this locally as follows
## summary with just the declaration names:
./scripts/declarations_diff.sh <optional_commit>

## more verbose report:
./scripts/declarations_diff.sh long <optional_commit>

The doc-module for script/declarations_diff.sh contains some details about this script.


Decrease in tech debt: (relative, absolute) = (1.78, 0.01)
Current number Change Type
5090 -6 porting notes
219 -1 disabled simpNF lints
1547 -6 erw

Current commit 04c436374e
Reference commit 54d12203eb

You can run this locally as

./scripts/technical-debt-metrics.sh pr_summary
  • The relative value is the weighted sum of the differences with weight given by the inverse of the current value of the statistic.
  • The absolute value is the relative value divided by the total sum of the inverses of the current values (i.e. the weighted average of the differences).

@chrisflav
Copy link
Collaborator Author

!bench

@leanprover-bot
Copy link
Collaborator

Here are the benchmark results for commit 58ebaf4.
There were no significant changes against commit daed990.

Copy link

File Instructions %
build +2.845⬝10⁹ (+0.00%)
lint +87.816⬝10⁹ (+1.22%)
Mathlib.Algebra.Category.AlgebraCat.Basic +4.433⬝10⁹ (+14.84%)
Mathlib.Algebra.Category.AlgebraCat.Limits +3.916⬝10⁹ (+6.49%)
Mathlib.CategoryTheory.Monoidal.Internal.Module -6.176⬝10⁹ (-3.96%)

@leanprover-community-bot-assistant leanprover-community-bot-assistant added the merge-conflict The PR has a merge conflict with master, and needs manual merging. (this label is managed by a bot) label Nov 15, 2024
@leanprover-community-bot-assistant leanprover-community-bot-assistant removed the merge-conflict The PR has a merge conflict with master, and needs manual merging. (this label is managed by a bot) label Nov 15, 2024
@chrisflav
Copy link
Collaborator Author

!bench

@leanprover-bot
Copy link
Collaborator

Here are the benchmark results for commit 11940cd.
There were significant changes against commit 54d1220:

  Benchmark                                     Metric         Change
  ===================================================================
- ~Mathlib.Algebra.Category.AlgebraCat.Limits   instructions    24.8%

Copy link

File Instructions %
build +16.249⬝10⁹ (+0.01%)
lint +87.406⬝10⁹ (+1.21%)
Mathlib.Algebra.Category.AlgebraCat.Limits +13.984⬝10⁹ (+24.76%)
Mathlib.Algebra.Category.AlgebraCat.Basic +7.228⬝10⁹ (+24.17%)
Mathlib.CategoryTheory.Monoidal.Internal.Module -6.285⬝10⁹ (-4.03%)

@chrisflav
Copy link
Collaborator Author

!bench

@leanprover-bot
Copy link
Collaborator

Here are the benchmark results for commit ebd530e.
There were significant changes against commit 54d1220:

  Benchmark                                     Metric         Change
  ===================================================================
- ~Mathlib.Algebra.Category.AlgebraCat.Limits   instructions    24.8%

Copy link

File Instructions %
build +15.950⬝10⁹ (+0.00%)
lint +87.436⬝10⁹ (+1.21%)
Mathlib.Algebra.Category.AlgebraCat.Limits +14.9⬝10⁹ (+24.81%)
Mathlib.Algebra.Category.AlgebraCat.Basic +7.553⬝10⁹ (+25.26%)
Mathlib.CategoryTheory.Monoidal.Internal.Module -6.278⬝10⁹ (-4.03%)

@chrisflav chrisflav removed the RFC Request for comment label Nov 18, 2024
@chrisflav
Copy link
Collaborator Author

!bench

@leanprover-bot
Copy link
Collaborator

Here are the benchmark results for commit 73bd116.
There were significant changes against commit 54d1220:

  Benchmark                                     Metric         Change
  ===================================================================
- ~Mathlib.Algebra.Category.AlgebraCat.Limits   instructions    32.5%

Copy link

File Instructions %
build +22.295⬝10⁹ (+0.01%)
lint +87.380⬝10⁹ (+1.20%)
Mathlib.Algebra.Category.AlgebraCat.Limits +18.355⬝10⁹ (+32.50%)
Mathlib.Algebra.Category.AlgebraCat.Basic +8.854⬝10⁹ (+29.61%)
Mathlib.CategoryTheory.Monoidal.Internal.Module -5.744⬝10⁹ (-3.69%)

@chrisflav
Copy link
Collaborator Author

So apparently, using the anonymous constructor even made it worse?

This reverts commit 73bd116.
@mattrobball
Copy link
Collaborator

mattrobball commented Nov 19, 2024

Can you update your PR description to explain the changes and reasoning for posterity?

Let's also do one more run of benchmarking.

@chrisflav
Copy link
Collaborator Author

!bench

@chrisflav
Copy link
Collaborator Author

Can you update your PR description to explain the changes and reasoning for posterity?

Let's also do one more run of benchmarking. I think I am satisfied.

Updated the PR description.

@leanprover-bot
Copy link
Collaborator

Here are the benchmark results for commit 24c84a4.
There were significant changes against commit 54d1220:

  Benchmark                                    Metric         Change
  ==================================================================
- ~Mathlib.Algebra.Category.AlgebraCat.Basic   instructions    73.0%

Copy link

File Instructions %
build +25.510⬝10⁹ (+0.01%)
Mathlib.Algebra.Category.AlgebraCat.Basic +21.816⬝10⁹ (+72.97%)
Mathlib.Algebra.Category.AlgebraCat.Limits +8.722⬝10⁹ (+15.44%)
Mathlib.LinearAlgebra.CliffordAlgebra.CategoryTheory +1.237⬝10⁹ (+26.14%)
Mathlib.CategoryTheory.Monoidal.Internal.Module -6.52⬝10⁹ (-3.88%)

@mattrobball
Copy link
Collaborator

It seems like instructions have crept up again.

@chrisflav
Copy link
Collaborator Author

chrisflav commented Nov 19, 2024

It seems like instructions have crept up again.

I think this is mostly because we now use aesop in a few place where we had explicit proofs before, so I think this is fine? Will do another bench without anonymous deconstructors.

@chrisflav
Copy link
Collaborator Author

!bench

@leanprover-bot
Copy link
Collaborator

Here are the benchmark results for commit 04c4363.
There were significant changes against commit 54d1220:

  Benchmark                                    Metric         Change
  ==================================================================
- ~Mathlib.Algebra.Category.AlgebraCat.Basic   instructions    69.1%

Copy link

File Instructions %
build +19.958⬝10⁹ (+0.01%)
Mathlib.Algebra.Category.AlgebraCat.Basic +20.670⬝10⁹ (+69.14%)
Mathlib.Algebra.Category.AlgebraCat.Limits +4.721⬝10⁹ (+8.36%)
Mathlib.LinearAlgebra.CliffordAlgebra.CategoryTheory +1.230⬝10⁹ (+25.97%)
Mathlib.CategoryTheory.Monoidal.Internal.Module -6.200⬝10⁹ (-3.98%)

@chrisflav
Copy link
Collaborator Author

What is needed to get this merged? For the slowdown: When replacing every aesop by a variation of by ext; simp, on my machine the build time for the Basic file goes from 5.69 s to 3.00 s while master is at 2.94 s. So the slowdown is only caused by replacing explicit proofs by automation, which I think is good and I would accept the slowdown in exchange. Do you agree?

@Vierkantor
Copy link
Contributor

I agree that the slowdown is a worthy tradeoff. So I still stand by my desire to merge this. @mattrobball, what do you think?

@Vierkantor
Copy link
Contributor

Since Matt gave this a thumbs up, let's get this merged. Thank you so much for this work and your nice results!

bors r+

@leanprover-community-mathlib4-bot leanprover-community-mathlib4-bot added the ready-to-merge This PR has been sent to bors. label Nov 25, 2024
mathlib-bors bot pushed a commit that referenced this pull request Nov 25, 2024
#19065)

In the current design of concrete categories in mathlib, there are two sources of `erw`s:

- Def-Eq abuse of `A ⟶ B` and `A →ₐ [R] B`: The type of `A ⟶ B` is by definition `A →ₐ[R] B`, but not at reducible transparency. So it happens that one `rw` lemma transforms a term in a form, where the next `rw` expects `A →ₐ B`. By supplying explicit `show` lines (copying the output of the pretty-printer), Lean correctly re-synthesizes the type to be `A →ₐ B` and the `rw` succeeds. This def-eq abuse hence always causes issues in the case where a lemma from the non-category theoretic part of the library should be applied. An insightful example is the following proof excerpt from current master (proof of `AlgebraCat.adj`):
```lean
import Mathlib.Algebra.Category.AlgebraCat.Basic
open CategoryTheory AlgebraCat
variable {R : Type u} [CommRing R]
set_option pp.analyze true

example : free.{u} R ⊣ forget (AlgebraCat.{u} R) :=
  Adjunction.mkOfHomEquiv
    { homEquiv := fun _ _ => (FreeAlgebra.lift _).symm
      homEquiv_naturality_left_symm := by
        intro X Y Z f g
        apply FreeAlgebra.hom_ext
        ext x
        simp only [Equiv.symm_symm, Function.comp_apply, free_map]
        /- Eq (α := Z)
             (((FreeAlgebra.lift R) (f ≫ g) :
               Prefunctor.obj (Functor.toPrefunctor (free R)) X ⟶ Z) (FreeAlgebra.ι R x) : ↑Z) _
        -/
        erw [FreeAlgebra.lift_ι_apply]
        sorry
      homEquiv_naturality_right := sorry }
```
The `simp` lemma `FreeAlgebra.lift_ι_apply` expects an `AlgHom`, but as the `pp.analyze` shows, the type is synthesized as a `⟶`. With a show line before the `erw`, Lean correctly synthesizes the type as an `AlgHom` again and the `rw` succeeds. The solution is to strictly distinguish between `A ⟶ B` and `A →ₐ[R] B`: We define a new `AlgebraCat.Hom` structure with a single field `hom : A →ₐ[R] B`. The above proof is mostly solved by `ext; simp` then, except for the `ext` lemma `FreeAlgebra.hom_ext` not applying. This is because now the type is `AlgebraCat.of R (FreeAlgebra R X) →ₐ[R] _` and Lean can't see through the `AlgebraCat.of` at reducible transparency. Hence the solution is to make `AlgebraCat.of` an `abbrev`. Finally, the proof is `by ext; simp` or even `by aesop`.

- `FunLike`: An intermediate design adapted the changes from the first point, but with keeping a `FunLike` and an `AlgHomClass` instance on `A ⟶ B`. This lead to many additional `coe` lemmas for composition of morphisms, where it mattered which of the three appearing terms of `AlgebraCat` where of the form `AlgebraCat.of R A`. Eric Wieser suggested to replace the `FunLike` by a `CoeFun` which is inlined, so an invocation of `f x` turns into `f.hom x`. This has then worked very smoothly.

So the key points are:
- Homs in concrete categories should be one-field structures to maintain a strict type distinction.
- Use `CoeFun` instead of `FunLike`, since the latter is automatically inlined.
- Make `.of` constructors an `abbrev` to obtain the def-eq `↑(AlgebraCat.of R A) = A` at reducible transparency.

For more details, see the [Zulip discussion](https://leanprover.zulipchat.com/#narrow/channel/287929-mathlib4/topic/Fixing.20the.20.60erw.60.20hell.20around.20concrete.20categories).
@mathlib-bors
Copy link
Contributor

mathlib-bors bot commented Nov 25, 2024

Pull request successfully merged into master.

Build succeeded:

@mathlib-bors mathlib-bors bot changed the title refactor(Algebra/Category): turn homs in AlgebraCat into a structure [Merged by Bors] - refactor(Algebra/Category): turn homs in AlgebraCat into a structure Nov 25, 2024
@mathlib-bors mathlib-bors bot closed this Nov 25, 2024
@mathlib-bors mathlib-bors bot deleted the chrisflav-commringcat branch November 25, 2024 10:13
Vierkantor added a commit that referenced this pull request Nov 26, 2024
This PR follows the approach of #19065 to solve painful definitional equalities problems by forbidding the identification of `A ⟶ B` and `A →ₗ[R] B`. These are not equal reducibly, so tactics get confused if one is replaced by the other.

Currently the PR consists mostly of me playing "type tetris" to get everything to compile again: I haven't looked for which proofs can be cleaned up as a result.

This commit is not quite finished, please see the Zulip thread for more details.
Vierkantor added a commit that referenced this pull request Dec 3, 2024
This PR follows the approach of #19065 to solve painful definitional equalities problems by forbidding the identification of `A ⟶ B` and `A →ₗ[R] B`. These are not equal reducibly, so tactics get confused if one is replaced by the other.

Currently the PR consists mostly of me playing "type tetris" to get everything to compile again: I haven't looked for which proofs can be cleaned up as a result.

This commit is not quite finished, please see the Zulip thread for more details.
mathlib-bors bot pushed a commit that referenced this pull request Dec 5, 2024
#19511)

This PR follows the approach of #19065 to solve painful definitional equalities problems by forbidding the identification of `A ⟶ B` and `A →ₗ[R] B`. These are not equal reducibly, so tactics get confused if one is replaced by the other.

There seem to be a few regressions caused by defeq abuse that we were able to get away with previously, but some subtle elaboration differences made it evident. Otherwise the cost is inserting many `.hom`s and `asHom`s.

A few steps that might clean up the diff, but would be too much work to incorporate in this PR:
 * Make the `ext` tactic pick up `TensorProduct.ext` again.
 * Replace the defeq abuse between `(restrictScalars f).obj M` and `M` with explicit maps going back and forth.

Overall quite a few proofs could be cleaned up at the cost of more bookkeeping.



Co-authored-by: Christian Merten <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ready-to-merge This PR has been sent to bors. t-algebra Algebra (groups, rings, fields, etc) t-category-theory Category theory
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants