Skip to content

Make the is_isomorphic method for AbelianGroup and PermutationGroup work for more groups #40268

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from

Conversation

reiniscirpons
Copy link

This PR fixes #39893, see also #39890. The crux of the issue is that the G.is_isomorphic(H) method of AbelianGroup returns False if the group H is not an instance of AbelianGroup_class, which caused quite confusing behavior in combination with permutation_group, where G.is_isomorphic(G.permutation_group()) returns False, even though permutation_group in its documentation states that it "Return the permutation group isomorphic to this abelian group".
This seems undesirable, so I've fixed it by making the method use the GAP group isomorphism method when both groups are not instances of AbelianGroup.

Similarly, the PermutationGroup is_isomorphic method seems to reject non-permutation group instances, and then uses the GAP isomorphism function anyway. Since the GAP isomorphism checking function can handle isomorphisms between permutation and non-permutation groups, I relaxed the constraint there, so now G.permutation_group().is_isomorphic(G) also returns true for an AbelianGroup instance G.

📝 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

No PR dependencies

@reiniscirpons reiniscirpons changed the title Make the is_isomorphic method for AbelianGroup and PermutationGroup word for more groups Make the is_isomorphic method for AbelianGroup and PermutationGroup work for more groups Jun 18, 2025
sage: G.is_isomorphic(H)
Traceback (most recent call last):
...
sage.libs.gap.util.GAPError: Error, cannot test isomorphism of infinite groups
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest catch it and re-raise NotImplementedError. Avoid exposing too much implementation detail, especially since we don't want upstream catch GAPError.

Copy link
Author

Choose a reason for hiding this comment

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

Good point. I did see some other parts of the library do throw a GAPError, e.g. the PrimitiveGroups function from permgroups_named.py throws a GAPError when called with too large a degree:

sage: PrimitiveGroups(2^12).cardinality()
Traceback (most recent call last):
...
GAPError: Error, Primitive groups of degree 4096 are not known!

But I see the utility of making the error message more user friendly. I could wrap the isomorphism check in a try-except block as follows:

try:
    iso = left._libgap_().IsomorphismGroups(right)
except GAPError as e:
    raise NotImplementedError(e) from None

This would catch any GAPError and retype it as a NotImplementedError hiding the original exception context. The only issue is that this would catch all GAPErrors indiscriminately, which might cause weird and confusing error messages if there are GAPErrors unrelated to isomorphisms checking of infinite groups. What are your thoughts on this?

if not isinstance(right, AbelianGroup_class):
return False
iso = left._libgap_().IsomorphismGroups(right)
return str(iso) != "fail"
Copy link
Contributor

Choose a reason for hiding this comment

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

is there a way to check if an object is fail in gap itself instead of converting it to str?

Copy link
Author

Choose a reason for hiding this comment

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

Yes, fail is a boolean in gap so the equality check x = fail; in gap would do this. I took the str(iso) != "fail" code from the is_isomorphic method of PermutationGroup:

return str(iso) != 'fail'

Similar checking by conversion to string also appears to happen in:
if str(ret) == 'fail':

if x == 'fail':

Looking around in the codebase, I could avoid the conversion to string if I do iso == libgap.eval('fail') instead. I can implement the change here + in the relevant places in PermutationGroup. Do you think that would be preferable to doing a string conversion?

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.

is_isomorphic for groups can give the wrong answer
2 participants