Skip to content

[Merged by Bors] - chore: mark Submodule.toAddSubgroup @[reducible]#35761

Closed
kim-em wants to merge 10 commits intomasterfrom
submodule_implicit
Closed

[Merged by Bors] - chore: mark Submodule.toAddSubgroup @[reducible]#35761
kim-em wants to merge 10 commits intomasterfrom
submodule_implicit

Conversation

@kim-em
Copy link
Contributor

@kim-em kim-em commented Feb 25, 2026

This PR marks Submodule.toAddSubgroup as @[reducible], matching the reducibility that a real structure parent projection would have (Lean marks structure parent projections [reducible]). This resolves backward.isDefEq.respectTransparency failures where Lean needs to see that s.toAddSubgroup.toAddSubmonoid = s.toAddSubmonoid.

The motivating example is:

instance {V : Type} [AddCommGroup V] [Module ℝ V] {l : Submodule ℝ V} :
    Module.Free ℝ l := Module.Free.of_divisionRing ℝ l

which fails with backward.isDefEq.respectTransparency because synthesis of Module ℝ ↥l needs Submodule.module, whose AddCommMonoid comes through toAddSubgroup (a virtual parent), while the Module prerequisite expects AddCommMonoid from toAddSubmonoid (a real projection). Lean must unfold toAddSubgroup to see these agree, but as a plain def it was [semireducible] and invisible at instance transparency.

See #general > backward.isDefEq.respectTransparency and the synthetic test case in #35750.

@github-actions
Copy link

github-actions bot commented Feb 25, 2026

PR summary 9b1001cbdb

Import changes for modified files

No significant changes to the import graph

Import changes for all files
Files Import difference

Declarations diff

No declarations were harmed in the making of this PR! 🐙

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 scripts/declarations_diff.sh contains some details about this script.


Decrease in tech debt: (relative, absolute) = (25.25, 0.54)
Current number Change Type
11071 -790 backward.isDefEq
47 -22 backward.whnf

Current commit 416e79d87c
Reference commit 9b1001cbdb

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).

@github-actions github-actions bot added the t-algebra Algebra (groups, rings, fields, etc) label Feb 25, 2026
@github-actions
Copy link

Commit Verification Summary

Warning

Some verifications failed. See details below.

Commits to Review (2)

  • ccede82: chore: mark Submodule.toAddSubgroup implicit_reducible
  • e586b7a: let's just do one thing at a time

View PR diff

\u274c Automated commits (1) - 0/1 verified
Commit Command Status
46fccb0 x: scripts/rm_set_option.py ❌ Command failed with exit code 1

Generated by commit verification CI

@kim-em kim-em force-pushed the submodule_implicit branch from 46fccb0 to 2d59d24 Compare February 25, 2026 23:56
@eric-wieser
Copy link
Member

Can you explain what the repro for this was and why it is a good idea in the PR description?

@kim-em
Copy link
Contributor Author

kim-em commented Feb 26, 2026

Can you explain what the repro for this was and why it is a good idea in the PR description?

I would really prefer not to. It is explained in the Zulip threads.

@eric-wieser
Copy link
Member

My reading of that thread is "we should do this because it makes the error go away", I don't see any strong claim that this is actually the direction we want to go in or why. If you intend to make that claim, then the PR description is the place to put it.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@urkud
Copy link
Member

urkud commented Feb 26, 2026

Submodule.toAddSubgroup is not a structural projection, but it is used to construct some instances (e.g., AddCommGroup). My guess is that without this attribute, Lean fails to see that s.toAddSubgroup.toAddSubmonoid = s.toAddSubmonoid.

@eric-wieser
Copy link
Member

Is every extends parent of a structure marked as implicit_reducible by default, which justifies doing this for pseudo-parents?

I'd assumed that was only true of classes.

@eric-wieser eric-wieser added the awaiting-author A reviewer has asked the author a question or requested changes. label Feb 26, 2026
@kim-em
Copy link
Contributor Author

kim-em commented Feb 26, 2026

Is every extends parent of a structure marked as implicit_reducible by default, which justifies doing this for pseudo-parents?

I'd assumed that was only true of classes.

https://github.com/leanprover/lean4/blob/master/src/Lean/Meta/Structure.lean#L114C1-L116C49

Structure parents are reducible:

import Lean

-- Plain structures
structure Foo where
  x : Nat

structure Bar extends Foo where
  y : Nat

-- Classes
class Baz where
  z : Nat

class Qux extends Baz where
  w : Nat

-- Class extending a structure
class Quux extends Foo where
  v : Nat

-- Structure extending a class
structure Corge extends Baz where
  u : Nat

open Lean in
/-- info: Bar.toFoo (structure extends structure): Lean.ReducibilityStatus.reducible
---
info: Qux.toBaz (class extends class): Lean.ReducibilityStatus.implicitReducible
---
info: Quux.toFoo (class extends structure): Lean.ReducibilityStatus.semireducible
---
info: Corge.toBaz (structure extends class): Lean.ReducibilityStatus.reducible
-/
#guard_msgs in
#eval show CoreM Unit from do
  let env ← getEnv
  let check (name : Name) (desc : String) : CoreM Unit := do
    let status := getReducibilityStatusCore env name
    logInfo m!"{name} ({desc}): {repr status}"
  check `Bar.toFoo "structure extends structure"
  check `Qux.toBaz "class extends class"
  check `Quux.toFoo "class extends structure"
  check `Corge.toBaz "structure extends class"

This really needs to be in reference manual rather than digging through the code to understand. :-(

@kim-em
Copy link
Contributor Author

kim-em commented Feb 26, 2026

So maybe the right fix here is actually @[reducible] not @[implicit_reducible].

@eric-wieser
Copy link
Member

That seems like the right conclusion to me, thanks for the test-case.

@eric-wieser
Copy link
Member

Do we want to encourage abbrev instead of reducible for such cases?

@kim-em kim-em changed the title chore: mark Submodule.toAddSubgroup @[implicit_reducible] chore: mark Submodule.toAddSubgroup @[reducible] Feb 26, 2026
Structure parent projections are [reducible], so this
pseudo-parent should be too.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@eric-wieser
Copy link
Member

!bench

@leanprover-radar
Copy link

leanprover-radar commented Feb 26, 2026

Benchmark results for 52f499c against 02dfd80 are in! @eric-wieser

  • 🟥 main exited with code 1

No significant changes detected.

@kim-em kim-em removed the awaiting-author A reviewer has asked the author a question or requested changes. label Feb 26, 2026
@eric-wieser eric-wieser added the bench-after-CI Once the PR passes CI, comment `!bench` on the PR label Feb 26, 2026
…oup_inj

These are now provable by simp via unfolding the @[reducible] toAddSubgroup.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| _, _, h => SetLike.ext (SetLike.ext_iff.1 h :)

@[simp]
theorem toAddSubgroup_inj : p.toAddSubgroup = p'.toAddSubgroup ↔ p = p' :=
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a little asymmetric with toAddSubmonoid_inj, which is allowed by simp. I suppose if it were a "real" projection though (with overlapping base classes) we'd have the same behavior, so fixing the asymmetry is out of scope.

@fpvandoorn
Copy link
Member

This seems unobjectionable to me. This also fits within the scope of the library note reducible non-instances. Feel free to treat this as a bors d+ if the bench looks ok.

@mathlib-merge-conflicts
Copy link

This pull request has conflicts, please merge master and resolve them.

@mathlib-merge-conflicts mathlib-merge-conflicts bot added the merge-conflict The PR has a merge conflict with master, and needs manual merging. (this label is managed by a bot) label Feb 27, 2026
@eric-wieser
Copy link
Member

This also fits within the scope of the library note reducible non-instances.

Does it? That note is for things whose type is a class, am which AddSubgroup is not.

I'm not opposed to the PR, but this isn't the first time this confusion has come up in discussion about it

@fpvandoorn
Copy link
Member

Does it? That note is for things whose type is a class, am which AddSubgroup is not.

I'm not opposed to the PR, but this isn't the first time this confusion has come up in discussion about it

Oops, my bad. You're right. It still seems fine, though.

# Conflicts:
#	Mathlib/RingTheory/Flat/Equalizer.lean
#	Mathlib/RingTheory/Noetherian/Basic.lean
@github-actions github-actions bot removed the merge-conflict The PR has a merge conflict with master, and needs manual merging. (this label is managed by a bot) label Mar 2, 2026
…ntroduced by merge

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kim-em kim-em force-pushed the submodule_implicit branch from 4afb10d to 92305ea Compare March 2, 2026 02:43
…p_toAddSubmonoid

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@kim-em
Copy link
Contributor Author

kim-em commented Mar 2, 2026

!bench

@leanprover-radar
Copy link

leanprover-radar commented Mar 2, 2026

Benchmark results for 416e79d against 9b1001c are in! @kim-em

  • 🟥 build//instructions: +5.3G (+0.00%)

No significant changes detected.

@kim-em
Copy link
Contributor Author

kim-em commented Mar 2, 2026

I'm taking Floris' message about as now a bors d+, since the benchmark was fine.

bors merge

@mathlib-triage mathlib-triage bot added the ready-to-merge This PR has been sent to bors. label Mar 2, 2026
mathlib-bors bot pushed a commit that referenced this pull request Mar 2, 2026
This PR marks `Submodule.toAddSubgroup` as `@[reducible]`, matching the reducibility that a real structure parent projection would have (Lean marks structure parent projections `[reducible]`). This resolves `backward.isDefEq.respectTransparency` failures where Lean needs to see that `s.toAddSubgroup.toAddSubmonoid = s.toAddSubmonoid`.

The motivating example is:
```lean
instance {V : Type} [AddCommGroup V] [Module ℝ V] {l : Submodule ℝ V} :
    Module.Free ℝ l := Module.Free.of_divisionRing ℝ l
```
which fails with `backward.isDefEq.respectTransparency` because synthesis of `Module ℝ ↥l` needs `Submodule.module`, whose `AddCommMonoid` comes through `toAddSubgroup` (a virtual parent), while the `Module` prerequisite expects `AddCommMonoid` from `toAddSubmonoid` (a real projection). Lean must unfold `toAddSubgroup` to see these agree, but as a plain `def` it was `[semireducible]` and invisible at instance transparency.

See [#general > backward.isDefEq.respectTransparency](https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/backward.2EisDefEq.2ErespectTransparency/near/575748939) and the synthetic test case in #35750.
@mathlib-bors
Copy link
Contributor

mathlib-bors bot commented Mar 2, 2026

Pull request successfully merged into master.

Build succeeded:

@mathlib-bors mathlib-bors bot changed the title chore: mark Submodule.toAddSubgroup @[reducible] [Merged by Bors] - chore: mark Submodule.toAddSubgroup @[reducible] Mar 2, 2026
@mathlib-bors mathlib-bors bot closed this Mar 2, 2026
@mathlib-bors mathlib-bors bot deleted the submodule_implicit branch March 2, 2026 03:38
pfaffelh pushed a commit to pfaffelh/mathlib4 that referenced this pull request Mar 2, 2026
…y#35761)

This PR marks `Submodule.toAddSubgroup` as `@[reducible]`, matching the reducibility that a real structure parent projection would have (Lean marks structure parent projections `[reducible]`). This resolves `backward.isDefEq.respectTransparency` failures where Lean needs to see that `s.toAddSubgroup.toAddSubmonoid = s.toAddSubmonoid`.

The motivating example is:
```lean
instance {V : Type} [AddCommGroup V] [Module ℝ V] {l : Submodule ℝ V} :
    Module.Free ℝ l := Module.Free.of_divisionRing ℝ l
```
which fails with `backward.isDefEq.respectTransparency` because synthesis of `Module ℝ ↥l` needs `Submodule.module`, whose `AddCommMonoid` comes through `toAddSubgroup` (a virtual parent), while the `Module` prerequisite expects `AddCommMonoid` from `toAddSubmonoid` (a real projection). Lean must unfold `toAddSubgroup` to see these agree, but as a plain `def` it was `[semireducible]` and invisible at instance transparency.

See [#general > backward.isDefEq.respectTransparency](https://leanprover.zulipchat.com/#narrow/channel/113488-general/topic/backward.2EisDefEq.2ErespectTransparency/near/575748939) and the synthetic test case in leanprover-community#35750.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bench-after-CI Once the PR passes CI, comment `!bench` on the PR ready-to-merge This PR has been sent to bors. t-algebra Algebra (groups, rings, fields, etc)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants