flattenRing rebuilds a raw ring it already has, and applying a ring map never short-circuits
Nobody has claimed this yet.
- Dominant language
- Macaulay2
- Stars
- 435
- Forks
- 297
- Avg merge
- 4d 20h
- Merged PRs (30d)
- 11
Description
This issue was triaged from [`bugs/dan/1-flattenRing-can-save-time`](https://github.com/Macaulay2/M2/blob/388c1ff0ce30d83751dea7bc7eac77fdc1305dd7/bugs/dan/1-flattenRing-can-save-time), one of the 857 files removed from the pre-GitHub `bugs/` tree by [`d2c8d27826`](https://github.com/Macaulay2/M2/commit/d2c8d27826) and catalogued in [#36](https://github.com/Macaulay2/M2/issues/36). **The commentary below was written by Claude (Claude Opus 5, via Claude Code)**, not by @d-torrance, whose account posted it -- please weigh it accordingly.
### The original file, verbatim
```text
flattenRing can save time by :
using the same raw ring when appropriate
then ring map application can save time when the source and target are the same raw ring
```
### Where it stands today
Both halves unmet, and the second is measurable without the first — so it is the easier one to act on.
### Ring-map application never short-circuits
`ringmap.m2` contains no raw-ring comparison, and `RingMap RingElement` (`:169-175`) always calls
`rawRingMapEval`. So `map(zzB, zzB)` — which satisfies `zzid == 1`, `source === target` and
`zzid === id_zzB`, and note that `ringmap.m2:31` already computes exactly that predicate for comparison
purposes — still costs **2.55 ms per application** on a 210-term polynomial, to return its argument.
### The first half is real but small
For a tower, `flattenRing` builds a fresh raw ring rather than reusing `R.FlatMonoid`:
`raw zzS =!= raw zzR` and `zzR.FlatMonoid =!= monoid zzS`, even though `describe` of the two monoids is
character-identical. But caching from `b25a44b6d1` (2008-10-24) already amortizes it — 4.0 ms on the
first call for a 16-variable tower, 4.1 µs afterwards.
### The unsettled part, which is what "when appropriate" is doing in the file
Whether reusing `R.FlatMonoid` is sound for Weyl algebras, `Inverses`, `SkewCommutative` or
`Join => false`. That needs a guard rather than a comparison, and it is the reason the first half is not
simply an optimization.
### Related
**#2133** is the adjacent caching issue.
`open` · disposition `issue` · source of truth: [`bug-triage/catalog.tsv`](https://github.com/d-torrance/M2/blob/bug-triage/bug-triage/catalog.tsv)
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in ringmap.m2, especially RingMap RingElement at lines 169-175 and the comparison predicate around line 31, then inspect rawRingMapEval. Reproduce the identity-map timing described for map(zzB, zzB) and confirm that the argument is returned without unnecessary evaluation. The flattenRing reuse portion remains conditional on behavior such as Weyl algebras, Inverses, SkewCommutative, and Join => false.
Written by the indexing model from the issue text.
Assessment
- Domain
- performance
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100