Skip to content

Conversation

@ThomasBreuer
Copy link
Member

Be careful if the matrix group is not suported by GAP.

resolves #5661

Be careful if the matrix group is not suported by GAP.
@ThomasBreuer ThomasBreuer added bug Something isn't working topic: groups release notes: not needed PRs introducing changes that are wholly irrelevant to the release notes bug: unexpected error labels Dec 18, 2025
@lgoettgens lgoettgens removed the bug Something isn't working label Dec 18, 2025
Comment on lines 343 to 346
G = GL(2, 3)
@test !has_gens(G)
GapObj(G)
@test has_gens(G)
Copy link
Member

Choose a reason for hiding this comment

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

This kind of violates against the groups conformance tests (cf https://github.com/Nemocas/AbstractAlgebra.jl/blob/fccef26d4c7d226ed8a141d5dbe55e9c415b0b3e/ext/TestExt/Groups-conformance-tests.jl#L61-L73) as there it is tested that gens throws if has_gens returns false. For GL(2, 3) that would not be the case

Copy link
Member

Choose a reason for hiding this comment

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

IMHO, the group conformance tests are simply wrong and need to be adjusted. This part has to be removed:

          else
              # TODO: throw something more specific
              @test_throws ErrorException gens(G)
              @test_throws ErrorException ngens(G)

Because it contradicts the has_gens documentation, which says:

Note that the result of this function when applied to a specific group instance can change over time, as side
effect of a generating set becoming available for the group.

In particular, one of the function which may have this side effect is gens, another is ngens.

This is not to say we shouldn't also adjust this PR, though.

Copy link
Member

Choose a reason for hiding this comment

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

Comment on lines 129 to 133
function has_gens(G::MatrixGroup)
isdefined(G,:gens) && return true
isdefined(G, :X) || return false
return GAP.Globals.HasGeneratorsOfGroup(GapObj(G))::Bool
end
Copy link
Member

@lgoettgens lgoettgens Dec 18, 2025

Choose a reason for hiding this comment

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

Suggested change
function has_gens(G::MatrixGroup)
isdefined(G,:gens) && return true
isdefined(G, :X) || return false
return GAP.Globals.HasGeneratorsOfGroup(GapObj(G))::Bool
end
function has_gens(G::MatrixGroup)
isdefined(G, :gens) && return true
F = codomain(_ring_iso(G))
GAP.Globals.IsBaseRingSupportedForClassicalMatrixGroup(F, GapObj(G.descr)) || return false
return GAP.Globals.HasGeneratorsOfGroup(GapObj(G))::Bool
end

what about something like this?

@ThomasBreuer
Copy link
Member Author

This kind of violates against the groups conformance tests [...] as there it is tested that gens throws if has_gens returns false.

Hmm, all has_something functions that are related to GAP objects have the meaning "is the something value already stored".
The value may change in the sense that first no something is stored and later it gets stored, typically by explicitly calling something.

There are two docstrings for has_gens(::Group), and both of them seem to fit to this interpretation.

@ThomasBreuer
Copy link
Member Author

@lgoettgens @fingolfin

The question seems to be what we want:

If has_gens shall express that "calling gens(G) will be successful (if and) only if has_gens(G) returns true" then we will have to change the documentation and the implementation.

But is this really what we want?
What about situations with finitely presented groups where certain subgroups initially do not know generators?
Asking GAP for generators of the subgroup will cause a coset enumeration --if this is successful then generators can be constructed.
Here is an example.

gap> F:= FreeGroup( 2 );;
gap> G:= F / [ F.1^2, F.2^3, (F.1*F.2)^6 ];
<fp group on the generators [ f1, f2 ]>
gap> U:= DerivedSubgroup( G );
Group(<fp, no generators known>)
gap> HasGeneratorsOfGroup( U );
false
gap> GeneratorsOfGroup( U );
[ f2*f1*f2^-1*f1^-1, f2^-1*f1*f2*f1^-1 ]

If no `GapObj` value is known for a matrix group then
regard it as cheap to compute the `GapObj` value if possible
and then to check whether this `GapObj` stores generators.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug: unexpected error release notes: not needed PRs introducing changes that are wholly irrelevant to the release notes topic: groups

Projects

None yet

Development

Successfully merging this pull request may close these issues.

has_gens errors because generators are not known

3 participants