Skip to content

gh-40301: Fix submodule containment over polynomial rings#42171

Open
cxzhong wants to merge 3 commits into
sagemath:developfrom
cxzhong:fix/40301-submodule-containment
Open

gh-40301: Fix submodule containment over polynomial rings#42171
cxzhong wants to merge 3 commits into
sagemath:developfrom
cxzhong:fix/40301-submodule-containment

Conversation

@cxzhong
Copy link
Copy Markdown
Contributor

@cxzhong cxzhong commented May 13, 2026

Issue: Containment test "vec in G" returned True for vectors not in G when the base ring was a multivariate polynomial ring (and several other cases), because the existing fallback element constructor in Module_free_ambient performed no actual membership check.

This commit completes and extends the prior partial fix:

  1. free_module.py: in Module_free_ambient.element_constructor, always call _check_element_membership (not only over exact coordinate rings). Inexact rings such as CC[x,y] previously skipped the check entirely, leading to the original Incorrect containment test for submodule over multivariable polynomial ring #40301 bug for the zero submodule.

  2. free_module.py: guard is_submodule against infinite recursion when self.ambient_module() is self, which happens for QuotientModule instances and caused stack overflows for subquotients.

  3. submodule.py: rework Submodule_free_ambient._groebner_basis_contains so that

    • zero submodules are decided directly (works over any ring, including inexact ones),
    • univariate polynomial rings are wrapped into libsingular multivariate rings with one variable so that Singular can compute module Groebner bases (fixes ZZ[x], number field polynomial rings, etc.),
    • quotient module ambients (subquotients) include the relations of the quotient as additional generators,
    • Singular failures over unsupported coefficient rings now raise NotImplementedError so that the calling code falls back gracefully.
  4. submodule.py: override contains in Submodule_free_ambient to use the membership check directly instead of relying on cross-parent equality (no coercion is registered between a submodule of a quotient module and the quotient itself).

  5. Added regression doctests covering the original bug example, the ZZ[x] case from the issue comments, the inexact-ring zero submodule case, and the quotient module subquotient case.

Fixes #40301.

📝 Checklist

  • The title is concise and informative.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation and checked the documentation preview.

⌛ Dependencies

cxzhong added 3 commits May 13, 2026 16:47
Issue: Containment test "vec in G" returned True for vectors not in G
when the base ring was a multivariate polynomial ring (and several
other cases), because the existing fallback element constructor in
Module_free_ambient performed no actual membership check.

This commit completes and extends the prior partial fix:

1. free_module.py: in Module_free_ambient._element_constructor_, always
   call _check_element_membership (not only over exact coordinate
   rings).  Inexact rings such as CC[x,y] previously skipped the check
   entirely, leading to the original sagemath#40301 bug for the zero submodule.

2. free_module.py: guard is_submodule against infinite recursion when
   self.ambient_module() is self, which happens for QuotientModule
   instances and caused stack overflows for subquotients.

3. submodule.py: rework Submodule_free_ambient._groebner_basis_contains
   so that
   - zero submodules are decided directly (works over any ring,
     including inexact ones),
   - univariate polynomial rings are wrapped into libsingular
     multivariate rings with one variable so that Singular can compute
     module Groebner bases (fixes ZZ[x], number field polynomial rings,
     etc.),
   - quotient module ambients (subquotients) include the relations of
     the quotient as additional generators,
   - Singular failures over unsupported coefficient rings now raise
     NotImplementedError so that the calling code falls back gracefully.

4. submodule.py: override __contains__ in Submodule_free_ambient to use
   the membership check directly instead of relying on cross-parent
   equality (no coercion is registered between a submodule of a
   quotient module and the quotient itself).

5. Added regression doctests covering the original bug example, the
   ZZ[x] case from the issue comments, the inexact-ring zero submodule
   case, and the quotient module subquotient case.

Fixes sagemath#40301.
…tainment

Expand the docstring of Submodule_free_ambient._groebner_basis_contains
to document and test nonzero submodules over

* univariate polynomial rings that are not PIDs (e.g. ZZ[x]),
  including ZZ[x]-linear combinations and the ZZ[x] vs QQ(x)
  distinction;

* multivariate polynomial rings over ZZ (e.g. ZZ[x, y]), exercising
  integer multiples, polynomial-coefficient combinations, and the
  rejection of (1, 1) which lies in the QQ(x, y)-span but not in the
  ZZ[x, y]-span.
… over CC[]

Add doctests to Submodule_free_ambient._groebner_basis_contains
showing that, over inexact coefficient rings such as CC[x, y],
nonzero submodule containment queries correctly raise
NotImplementedError instead of returning a possibly wrong answer.
This is exercised both for rank-2 free modules with the standard
basis generators and for a single non-trivial generator (x, y),
covering the 'v in <v>' style of query.
@github-actions
Copy link
Copy Markdown

Documentation preview for this PR (built with commit 552a915; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

@cxzhong cxzhong marked this pull request as ready for review May 13, 2026 13:04
@cxzhong cxzhong requested review from nbruin and tscrim May 13, 2026 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Incorrect containment test for submodule over multivariable polynomial ring

1 participant