Skip to content

submodule membership testing ( in operator)#41694

Merged
vbraun merged 2 commits into
sagemath:developfrom
rashadalsharpini:issue41671v2
Mar 22, 2026
Merged

submodule membership testing ( in operator)#41694
vbraun merged 2 commits into
sagemath:developfrom
rashadalsharpini:issue41671v2

Conversation

@rashadalsharpini

Copy link
Copy Markdown
Contributor

Description

Fixes #41671 — submodule membership testing (in operator) incorrectly returns True for elements not in the submodule, when the base ring is a quotient of a polynomial ring.

Changes

  • Added _groebner_basis_contains() to Submodule_free_ambient — performs submodule membership testing via Singular's std (Groebner basis) and reduce. For quotient rings, it lifts generators and the test vector to the covering polynomial ring and augments with ideal relation generators before computing the Groebner basis. Works for submodules over polynomial rings and quotients of polynomial rings.
  • Added _element_constructor_() override to Submodule_free_ambient — calls _groebner_basis_contains() when check=True and the base ring is exact, raising TypeError if the element is not in the submodule.

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.

@github-actions

github-actions Bot commented Feb 24, 2026

Copy link
Copy Markdown

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

@tscrim tscrim left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why are you directly calling Singular rather than going through the ring's implementation? In particular, it could be extended to work where the polynomial ring does not work in Singular but can compute a GB. (I think there are such rings that can be built, but not 100% sure off the top of my head.)

Comment thread src/sage/modules/submodule.py Outdated
Comment thread src/sage/modules/submodule.py Outdated
@rashadalsharpini

rashadalsharpini commented Mar 4, 2026

Copy link
Copy Markdown
Contributor Author

The reason I did is that Sage has a clean high-level API for ideals (.groebner_basis(), .reduce()), but I couldn't find an equivalent one for submodules of free modules over polynomial rings. So I ended up going to Singular's std and reduce at the low level.

@tscrim tscrim left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Ah, sorry. I misread and thought it was acting on polynomials. Okay, that should be fine.

Although I was looking a bit more. It seems like this is duplicating a fair bit of code from the base class's Module_free_ambient._element_constructor_. I'm thinking we should actually modify that code to add the extra case there.

Comment thread src/sage/modules/submodule.py Outdated
sage: N = M.submodule([vector([x - y, z]), vector([y*z, x*z])])
sage: Q = M.quotient_module(N)
sage: NQ = Q.submodule([Q([1, x])])
sage: NQ([1, x])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you for adding the test, but it would be good to have a more nontrivial example (i.e., not a generator of the submodule).

@rashadalsharpini

Copy link
Copy Markdown
Contributor Author

yes i have noticed the duplication and kind of solved it, i have moved the logic to the parent class and moved the tests there as well

@tscrim tscrim left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thank you. One last trivial cleanup thing then a positive review.

Comment thread src/sage/modules/submodule.py Outdated
@tscrim

tscrim commented Mar 6, 2026

Copy link
Copy Markdown
Collaborator

Oh, also, could you squash everything to a single commit and forcepush? (The thing I'm really after is having at least a bit better commit messages, but I figure this is the easiest way.)

@rashadalsharpini

rashadalsharpini commented Mar 6, 2026

Copy link
Copy Markdown
Contributor Author

i will try my mind simply fails when writing commits :) , sorry i forgot to pull your edits before force pushing but i have fixed it and deleted the unnecessary imports

@rashadalsharpini rashadalsharpini force-pushed the issue41671v2 branch 2 times, most recently from 678787a to f7dcc5f Compare March 6, 2026 02:13
@rashadalsharpini

Copy link
Copy Markdown
Contributor Author

is there anything i should do about the test that failed and kind of a wired thing
because i tested the entire repo on my device it took a while but everthing passed @tscrim

Comment thread src/sage/modules/submodule.py Outdated
@tscrim

tscrim commented Mar 9, 2026

Copy link
Copy Markdown
Collaborator

You still have an extra blank line added that doesn’t need to be there (as per the diff).

You can ignore that failing test as you can see in the log that it is unrelated to your changes.

@tscrim

tscrim commented Mar 10, 2026

Copy link
Copy Markdown
Collaborator

Thank you. This is now a positive review.

(Strictly speaking, it would be better to avoid repeating the doctests. Yes, they are technically different, but since they use the same rings/elements and code path, it becomes effectively the same test. It might also be good to avoid shortcuts like M.1. However, those are each a kind of triviality.)

@rashadalsharpini

Copy link
Copy Markdown
Contributor Author

Thank you for the review and the positive feedback! I appreciate the notes on the redundant doctests and the use of shortcuts. I'll keep those points in mind to ensure cleaner code in my future contributions.

rashadalsharpini and others added 2 commits March 11, 2026 23:15
    Remove the groebner_basis_contains check from Submodule_free_ambient
    as there is no algorithm to verify element membership.
Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com>
@rashadalsharpini

rashadalsharpini commented Mar 11, 2026

Copy link
Copy Markdown
Contributor Author

@tscrim i have rebased the code because it was out of sync with the develop branch, could you add the tag back please?
i did this because i think it's good practice if not i am sorry

@tscrim

tscrim commented Mar 12, 2026

Copy link
Copy Markdown
Collaborator

@rashadalsharpini Please don't do such things after a positive review unless there is an absolute need to (i.e., a merge conflict). It can cause trouble with merging (and it means someone needs to look over it again to check an error didn't get introduced).

vbraun pushed a commit to vbraun/sage that referenced this pull request Mar 15, 2026
sagemathgh-41694: submodule membership testing ( in operator)
    
### Description

Fixes sagemath#41671 — submodule membership testing (`in` operator) incorrectly
returns `True` for elements not in the submodule, when the base ring is
a quotient of a polynomial ring.

###  Changes

- Added `_groebner_basis_contains()` to `Submodule_free_ambient` —
performs submodule membership testing via Singular's `std` (Groebner
basis) and `reduce`. For quotient rings, it lifts generators and the
test vector to the covering polynomial ring and augments with ideal
relation generators before computing the Groebner basis. Works for
submodules over polynomial rings and quotients of polynomial rings.
- Added `_element_constructor_()` override to `Submodule_free_ambient` —
calls `_groebner_basis_contains()` when `check=True` and the base ring
is exact, raising `TypeError` if the element is not in the submodule.
### Checklist
- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation and checked the documentation
preview.
    
URL: sagemath#41694
Reported by: Rashad Alsharpini
Reviewer(s): Rashad Alsharpini, Travis Scrimshaw
vbraun pushed a commit to vbraun/sage that referenced this pull request Mar 18, 2026
sagemathgh-41694: submodule membership testing ( in operator)
    
### Description

Fixes sagemath#41671 — submodule membership testing (`in` operator) incorrectly
returns `True` for elements not in the submodule, when the base ring is
a quotient of a polynomial ring.

###  Changes

- Added `_groebner_basis_contains()` to `Submodule_free_ambient` —
performs submodule membership testing via Singular's `std` (Groebner
basis) and `reduce`. For quotient rings, it lifts generators and the
test vector to the covering polynomial ring and augments with ideal
relation generators before computing the Groebner basis. Works for
submodules over polynomial rings and quotients of polynomial rings.
- Added `_element_constructor_()` override to `Submodule_free_ambient` —
calls `_groebner_basis_contains()` when `check=True` and the base ring
is exact, raising `TypeError` if the element is not in the submodule.
### Checklist
- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation and checked the documentation
preview.
    
URL: sagemath#41694
Reported by: Rashad Alsharpini
Reviewer(s): Rashad Alsharpini, Travis Scrimshaw
vbraun pushed a commit to vbraun/sage that referenced this pull request Mar 21, 2026
sagemathgh-41694: submodule membership testing ( in operator)
    
### Description

Fixes sagemath#41671 — submodule membership testing (`in` operator) incorrectly
returns `True` for elements not in the submodule, when the base ring is
a quotient of a polynomial ring.

###  Changes

- Added `_groebner_basis_contains()` to `Submodule_free_ambient` —
performs submodule membership testing via Singular's `std` (Groebner
basis) and `reduce`. For quotient rings, it lifts generators and the
test vector to the covering polynomial ring and augments with ideal
relation generators before computing the Groebner basis. Works for
submodules over polynomial rings and quotients of polynomial rings.
- Added `_element_constructor_()` override to `Submodule_free_ambient` —
calls `_groebner_basis_contains()` when `check=True` and the base ring
is exact, raising `TypeError` if the element is not in the submodule.
### Checklist
- [x] The title is concise and informative.
- [x] The description explains in detail what this PR is about.
- [x] I have linked a relevant issue or discussion.
- [x] I have created tests covering the changes.
- [x] I have updated the documentation and checked the documentation
preview.
    
URL: sagemath#41694
Reported by: Rashad Alsharpini
Reviewer(s): Rashad Alsharpini, Travis Scrimshaw
@vbraun vbraun merged commit 86e7f4c into sagemath:develop Mar 22, 2026
23 checks passed
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.

membership testing in modules over rings with zero divisors

3 participants