Skip to content

Make the Algebra and Module traits multigrading-capable - #268

Open
JoeyBF wants to merge 2 commits into
SpectralSequences:masterfrom
JoeyBF:claude/259-phase1-multigrade
Open

Make the Algebra and Module traits multigrading-capable#268
JoeyBF wants to merge 2 commits into
SpectralSequences:masterfrom
JoeyBF:claude/259-phase1-multigrade

Conversation

@JoeyBF

@JoeyBF JoeyBF commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator

What & why

Generalize the Algebra/Module trait family to be multigrading-capable, so a bigraded object (like Ext) can implement them directly. This is groundwork for #259 (splitting ExtAlgebra into a ring Ext(k, k) and a module Ext(M, k) that are an Algebra and a Module); on its own it is a pure generalization with zero behavior change for all existing single-graded code.

The grading types already exist in the sseq crate (MultiDegree<N>, with Bidegree = MultiDegree<2>); this PR just makes the traits consume them.

How

  • trait Algebra<const N: usize = 1> and trait Module<const N: usize = 1>. The defaulted const generic means every existing A: Algebra / M: Module bound and the Arc<dyn Module> alias keep working unchanged — only future bigraded code writes <2>.
  • Degree inputs take impl Into<MultiDegree<N>>. With From<i32> for MultiDegree<1>, every existing i32 call site (~350 of them) compiles unchanged; the method .into()s at the top. Degree returns stay i32 (the distinguished filtration direction), so the resolution engine's degree arithmetic is entirely untouched.
  • Object safety. Module is used as dyn Module, and impl Into<…> arguments are not object-safe. So the object-safe core methods take a concrete MultiDegree<N> and are suffixed _multi (dimension_multi, act_on_basis_multi, …); a blanket ModuleExt extension trait re-exposes the ergonomic names (dimension, act_on_basis, …) taking impl Into<MultiDegree<N>>, and works even on dyn Module. Downstream code just gains use algebra::module::ModuleExt.
  • enum_dispatch. It cannot dispatch a const-generic trait parameter, so Algebra is removed from SteenrodAlgebra's #[enum_dispatch(...)] list and hand-dispatched via the existing dispatch_steenrod! macro (the same pattern PairAlgebra already uses for its associated type). UnstableAlgebra/GeneratedAlgebra/MuAlgebra stay singly graded and keep #[enum_dispatch].

Only the ~3 concrete algebras (Milnor, Adem, Field) and ~8 module implementors gain impl Into + a one-line .into() per method; the bulk of the diff is those mechanical signature updates plus ModuleExt imports at call sites.

Testing

  • cargo test --features concurrent --lib --tests --workspace, cargo test --examples, and doctests: green (the lone test_tempdir_lock failure is a pre-existing sandbox/permissions artifact, unrelated — it fails on master too).
  • Nightly cargo fmt --check, the clippy matrix (--no-default-features / --all-targets, -D warnings), and rustdoc (-D warnings, private items, all features): clean.
  • The single-graded code path is byte-for-byte identical; this PR adds no new behavior.

Follow-ups

The actual #259 split (ExtAlgebra ring / ExtModule module implementing these traits) builds on this and will come as a separate PR, followed by the secondary-layer split. This PR intentionally does not close #259.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Nk9J57zb6GpvZxrduhGSdY


Generated by Claude Code

Summary by CodeRabbit

  • New Features
    • Added support for multi-dimensional grading across algebra and module operations.
    • APIs now accept flexible degree representations for dimensions, actions, basis generation, and element formatting.
    • Added convenient helper methods for common module operations.
    • Extended support for concurrent processing and odd-prime calculations.
  • Compatibility
    • Existing singly graded workflows continue to work with the updated interfaces.

@coderabbitai

coderabbitai Bot commented Jul 13, 2026

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 97fb68ab-780f-4a0d-8680-300cd550628a

📥 Commits

Reviewing files that changed from the base of the PR and between df73512 and ae0b613.

📒 Files selected for processing (40)
  • ext/crates/algebra/Cargo.toml
  • ext/crates/algebra/benches/common/mod.rs
  • ext/crates/algebra/src/algebra/adem_algebra.rs
  • ext/crates/algebra/src/algebra/algebra_trait.rs
  • ext/crates/algebra/src/algebra/field.rs
  • ext/crates/algebra/src/algebra/milnor_algebra.rs
  • ext/crates/algebra/src/algebra/steenrod_algebra.rs
  • ext/crates/algebra/src/module/finite_dimensional_module.rs
  • ext/crates/algebra/src/module/finitely_presented_module.rs
  • ext/crates/algebra/src/module/free_module.rs
  • ext/crates/algebra/src/module/hom_module.rs
  • ext/crates/algebra/src/module/homomorphism/free_module_homomorphism.rs
  • ext/crates/algebra/src/module/homomorphism/full_module_homomorphism.rs
  • ext/crates/algebra/src/module/homomorphism/hom_pullback.rs
  • ext/crates/algebra/src/module/homomorphism/mod.rs
  • ext/crates/algebra/src/module/homomorphism/quotient_homomorphism.rs
  • ext/crates/algebra/src/module/mod.rs
  • ext/crates/algebra/src/module/module_trait.rs
  • ext/crates/algebra/src/module/quotient_module.rs
  • ext/crates/algebra/src/module/rpn.rs
  • ext/crates/algebra/src/module/suspension_module.rs
  • ext/crates/algebra/src/module/tensor_module.rs
  • ext/crates/sseq/src/coordinates/degree.rs
  • ext/examples/bruner.rs
  • ext/examples/ext_m_n.rs
  • ext/examples/lift_hom.rs
  • ext/examples/resolution_size.rs
  • ext/examples/sq0.rs
  • ext/examples/steenrod.rs
  • ext/src/chain_complex/chain_homotopy.rs
  • ext/src/chain_complex/finite_chain_complex.rs
  • ext/src/chain_complex/mod.rs
  • ext/src/nassau.rs
  • ext/src/resolution.rs
  • ext/src/resolution_homomorphism.rs
  • ext/src/secondary.rs
  • ext/src/yoneda.rs
  • ext/tests/extend_identity.rs
  • ext/tests/non_zero_min_degree.rs
  • web_ext/sseq_gui/src/actions.rs

📝 Walkthrough

Walkthrough

The algebra crate adopts const-generic MultiDegree APIs for algebras and modules. Scalar conversions preserve singly graded behavior. Implementations, dispatch, examples, and integrations use the updated trait methods.

Changes

Multi-degree API migration

Layer / File(s) Summary
Algebra contracts and implementations
ext/crates/algebra/Cargo.toml, ext/crates/algebra/src/algebra/*, ext/crates/sseq/src/coordinates/degree.rs
Algebra becomes const-generic and accepts MultiDegree inputs. Algebra implementations convert inputs to scalar degrees internally.
Module trait and extension wrappers
ext/crates/algebra/src/module/module_trait.rs, ext/crates/algebra/src/module/mod.rs
Module gains const-generic multi-degree hooks. ModuleExt provides conversion-based convenience methods.
Module implementations
ext/crates/algebra/src/module/*
Concrete modules migrate basis, dimension, action, and formatting hooks to multi-degree variants.
Dispatch and integration updates
ext/crates/algebra/src/module/homomorphism/*, ext/examples/*, ext/src/*, ext/tests/*, web_ext/sseq_gui/src/actions.rs
Dispatch code, examples, homomorphisms, chain-complex code, benchmarks, tests, and GUI imports use the updated APIs.

Estimated code review effort: 4 (Complex) | ~60 minutes

Possibly related PRs

Suggested reviewers: hoodmane

Poem

A rabbit maps each degree’s way,
From scalar paths to tuples gray.
Algebra and modules align,
With wrappers keeping calls fine.
New hooks hop through every sign.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR adds prerequisite multigrading support but does not implement the ExtAlgebra/ExtModule split described in issue #259. Implement the ExtAlgebra/ExtModule split, or link this preparatory change to a dedicated groundwork issue and keep #259 linked to the split implementation.
Docstring Coverage ⚠️ Warning Docstring coverage is 55.79% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the main change: making the Algebra and Module traits support multigrading.
Out of Scope Changes check ✅ Passed The changes consistently implement multigrading support and update its required implementations and call sites; no unrelated code changes are identified.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ext/crates/algebra/src/module/module_trait.rs (1)

67-148: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Validate the target degree before promising a non-panicking action.

Both methods delegate without computing the target basis or validating result against op_degree + input_degree. A valid source/index with a mismatched output slice can therefore still panic inside implementations.

Proposed validation
+        let output_degree = op_degree + mod_degree;
+        self.compute_basis_multi(output_degree);
+        let output_dim = self.dimension_multi(output_degree);
+        if result.as_slice().len() != output_dim {
+            return Err(ActError::InvalidInput(format!(
+                "result length {} does not match module dimension {output_dim} in degree {output_degree}",
+                result.as_slice().len()
+            )));
+        }

Apply the equivalent check using op_degree + input_degree in try_act_multi.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@ext/crates/algebra/src/module/module_trait.rs` around lines 67 - 148, Update
try_act_multi to compute and validate the target degree, op_degree +
input_degree, before delegating to act_multi: ensure the target degree is
supported and result has the required target dimension, returning the
appropriate ActError instead of allowing implementation panics. Apply the
equivalent target-basis and result validation in try_act_on_basis_multi using
op_degree + mod_degree before calling act_on_basis_multi.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@ext/crates/algebra/src/module/module_trait.rs`:
- Around line 153-158: Update the default Module trait method is_unit to return
false whenever the grading has more than one component (N > 1), before applying
the existing degree and dimension checks. Retain the current checks for the
single-component case, allowing multigraded implementations to provide accurate
behavior by overriding is_unit.

---

Outside diff comments:
In `@ext/crates/algebra/src/module/module_trait.rs`:
- Around line 67-148: Update try_act_multi to compute and validate the target
degree, op_degree + input_degree, before delegating to act_multi: ensure the
target degree is supported and result has the required target dimension,
returning the appropriate ActError instead of allowing implementation panics.
Apply the equivalent target-basis and result validation in
try_act_on_basis_multi using op_degree + mod_degree before calling
act_on_basis_multi.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 126d7619-142a-4309-b461-21e59fc2559b

📥 Commits

Reviewing files that changed from the base of the PR and between a3a63cb and df73512.

📒 Files selected for processing (38)
  • ext/crates/algebra/Cargo.toml
  • ext/crates/algebra/src/algebra/adem_algebra.rs
  • ext/crates/algebra/src/algebra/algebra_trait.rs
  • ext/crates/algebra/src/algebra/field.rs
  • ext/crates/algebra/src/algebra/milnor_algebra.rs
  • ext/crates/algebra/src/algebra/steenrod_algebra.rs
  • ext/crates/algebra/src/module/finite_dimensional_module.rs
  • ext/crates/algebra/src/module/finitely_presented_module.rs
  • ext/crates/algebra/src/module/free_module.rs
  • ext/crates/algebra/src/module/hom_module.rs
  • ext/crates/algebra/src/module/homomorphism/free_module_homomorphism.rs
  • ext/crates/algebra/src/module/homomorphism/full_module_homomorphism.rs
  • ext/crates/algebra/src/module/homomorphism/hom_pullback.rs
  • ext/crates/algebra/src/module/homomorphism/mod.rs
  • ext/crates/algebra/src/module/homomorphism/quotient_homomorphism.rs
  • ext/crates/algebra/src/module/mod.rs
  • ext/crates/algebra/src/module/module_trait.rs
  • ext/crates/algebra/src/module/quotient_module.rs
  • ext/crates/algebra/src/module/rpn.rs
  • ext/crates/algebra/src/module/suspension_module.rs
  • ext/crates/algebra/src/module/tensor_module.rs
  • ext/crates/sseq/src/coordinates/degree.rs
  • ext/examples/bruner.rs
  • ext/examples/ext_m_n.rs
  • ext/examples/lift_hom.rs
  • ext/examples/resolution_size.rs
  • ext/examples/sq0.rs
  • ext/examples/steenrod.rs
  • ext/src/chain_complex/chain_homotopy.rs
  • ext/src/chain_complex/finite_chain_complex.rs
  • ext/src/chain_complex/mod.rs
  • ext/src/nassau.rs
  • ext/src/resolution.rs
  • ext/src/resolution_homomorphism.rs
  • ext/src/secondary.rs
  • ext/src/yoneda.rs
  • ext/tests/extend_identity.rs
  • ext/tests/non_zero_min_degree.rs

Comment thread ext/crates/algebra/src/module/module_trait.rs
@JoeyBF
JoeyBF force-pushed the claude/259-phase1-multigrade branch from df73512 to a6b6947 Compare July 13, 2026 06:53

JoeyBF commented Jul 13, 2026

Copy link
Copy Markdown
Collaborator Author

Pushed a6b6947 addressing the review + a CI fix:

  • is_unit for N > 1 — applied the guard (returns false for multigraded modules, overridable), since min_degree/max_degree are the single i32 filtration and can't characterize the unit when degrees share a t. N = 1 behavior is unchanged.
  • sseq_gui build fixweb_ext/sseq_gui/src/actions.rs needed use algebra::module::ModuleExt for the renamed dimension/basis_element_to_string methods. This is what broke the lint and webserver jobs; a downstream consumer of the rename I'd missed. (The sseq.rs dimension calls are on a different type and are unaffected.)

I did not add the suggested output validation to try_act_multi / try_act_on_basis_multi. Those methods are unchanged from master (a3a63cb) apart from the _multi rename, so adding it is out of scope for this zero-behavior-change PR — and a strict result-length check would contradict the documented contract that "the length of input need not be equal to the dimension of the module" (the flexibility resolution-to-a-stem relies on). Happy to tackle output validation as a separate change if you'd like it.

Context: this PR is deliberately just the multigrading groundwork; the ExtAlgebra/ExtModule split for #259 (which CodeRabbit's "Linked Issues" check flags as missing) is the follow-up PR that builds on this one.


Generated by Claude Code

claude added 2 commits August 1, 2026 07:06
Generalize the `Algebra` trait family to be multigrading-capable, as the
foundation for treating Ext(k,k) as a genuine bigraded algebra (issue SpectralSequences#259).

- `Algebra<const N: usize = 1>`: degree *inputs* now take
  `impl Into<MultiDegree<N>>`, so singly-graded callers keep passing bare
  `i32`s (via new `From<i32> for MultiDegree<1>`). The default `N = 1` keeps
  every existing `A: Algebra` bound and `dyn` usage working unchanged.
- `enum_dispatch` cannot handle a generic trait, so `Algebra` is removed from
  `SteenrodAlgebra`'s dispatch list and hand-rolled via `dispatch_steenrod!`
  (the pattern already used for `PairAlgebra`). `UnstableAlgebra`,
  `GeneratedAlgebra`, and `MuAlgebra` stay singly-graded and keep enum_dispatch.
- Milnor, Adem, and Field implement `Algebra` (default `N = 1`), converting the
  incoming degree to `i32` at each method boundary.
- Degree-returning methods stay `i32` (the distinguished filtration direction),
  so the resolution engine's degree arithmetic is untouched.
- `algebra` now depends on `sseq` for `MultiDegree` (no dependency cycle).

Behavior is unchanged for the singly-graded path; all 51 algebra tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nk9J57zb6GpvZxrduhGSdY
Second half of the multigrading foundation for issue SpectralSequences#259: generalize the
`Module` trait to bigraded (and N-graded) modules, so Ext(M, k) can be a genuine
`Module` over the ring Ext(k, k).

- `Module<const N: usize = 1>` with `type Algebra: Algebra<N>`. The default
  `N = 1` keeps every existing `M: Module` bound and the `dyn Module` /
  `SteenrodModule` alias working unchanged.
- `Module` must stay object-safe (`SteenrodModule = Arc<dyn Module>`), so its
  degree-taking methods take concrete `MultiDegree<N>` and are suffixed `_multi`
  (e.g. `dimension_multi`, `act_on_basis_multi`). A blanket `ModuleExt` trait
  provides the canonical ergonomic names (`dimension`, `act_on_basis`, …) taking
  `impl Into<MultiDegree<N>>`, forwarding to the core methods. It is implemented
  for every module including `dyn Module`, so callers keep passing bare `i32`s.
- All eight module implementors (free, FD, FP, hom, quotient, RPn, suspension,
  tensor) implement the `_multi` methods, converting to `i32` at the boundary.
- Degree-returning methods (`min_degree`, `max_degree`, `max_computed_degree`)
  stay `i32` (the distinguished filtration direction), so the resolution
  engine's degree arithmetic is untouched.
- Downstream call sites (resolution, nassau, yoneda, secondary, chain complexes,
  examples, tests) gain a `use algebra::module::ModuleExt` import; no logic
  changes.
- Also corrects a pre-existing latent bug in the `sq0` example: `DoubleModule`
  (which represents degree 2n) forwarded the full degree to the inner module in
  `element_to_string`, unlike every sibling method; now halves it like
  `basis_element_to_string`.

Behavior is unchanged for the singly-graded path: all algebra and ext tests pass
(the one failing test, `test_tempdir_lock`, is a pre-existing environment issue
about read-only file permissions under root, unrelated to this change).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Nk9J57zb6GpvZxrduhGSdY
@JoeyBF
JoeyBF force-pushed the claude/259-phase1-multigrade branch from f96524d to ae0b613 Compare August 1, 2026 07:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Split ExtAlgebra into a ring ExtAlgebra (over k) and an ExtModule (over M)

2 participants