gap-system / gap

Main development repository for GAP - Groups, Algorithms, Programming, a System for Computational Discrete Algebra
https://www.gap-system.org
GNU General Public License v2.0
798 stars 162 forks source link

a problem with nice monomorphisms #5422

Open ThomasBreuer opened 1 year ago

ThomasBreuer commented 1 year ago

Suppose we have a bijective map f: G -> H that was created with GroupHomomorphismByFunction, such that H is a group in IsHandledByNiceMonomorphism. Then the function from the construction allows us to compute images, and we can compute preimages by composing n:= NiceMonomorphism( H ) with a GroupHomomorphismByImages map that is defined by mapping the images of the generators of G under the composition of f with n to the generators of G. (This works only if the image of n is really nice, for example if n is an action homomorphism, but let us assume that this is the case.)

The available implementation in GAP does in principle support this, for example if f is an isomorphism defined by a function from a permutation group to a matrix group over a finite field. I do not understand why the result of GroupHomomorphismByFunction has always the filter IsPreimagesByAsGroupGeneralMappingByImages; in the above situation, there is no need for computing an additional AsGroupGeneralMappingByImages map, the nice monomorphism of H can be used to compute the inverse of f without that. But this is not really a problem.

However, if f is itself a nice monomorphism then the above mechanism does not work, because the GroupGeneralMappingByImagesNC method that is expected to create the inverse as a composition calls TryNextMethod(), in order to avoid recursion, and then one ends up in a generic method that wants to store lists of elements and images --if the groups are not very small then here one gets stuck.

Here is an example.

gap> G1:= AtlasGroup( "M11", IsPermGroup );;
gap> G2:= AtlasGroup( "M11", Characteristic, 2 );;
gap> isoBI:= GroupHomomorphismByImages( G1, G2, GeneratorsOfGroup( G1 ), GeneratorsOfGroup( G2 ) );;
gap> isoBF1:= GroupHomomorphismByFunction( G1, G2, x -> ImagesRepresentative( isoBI, x ) );;
gap> isoBF2:= GroupHomomorphismByFunction( G1, G2, x -> ImagesRepresentative( isoBI, x ) );;
gap> SetFilterObj( isoBF2, IsNiceMonomorphism );
gap> # compute a preimage
gap> x:= Product( GeneratorsOfGroup( G2 ) );;
gap> PreImagesRepresentative( isoBI, x );;
gap> PreImagesRepresentative( isoBF1, x );;
gap> PreImagesRepresentative( isoBF2, x );;   # takes much longer ...
gap> # inspect the internal data of the maps
gap> REC_NAMES_COMOBJ( RestrictedInverseGeneralMapping( AsGroupGeneralMappingByImages( isoBF1 ) ) );
[ "RestrictedInverseGeneralMapping", "map1", "map2" ]
gap> REC_NAMES_COMOBJ( RestrictedInverseGeneralMapping( AsGroupGeneralMappingByImages( isoBF2 ) ) );
[ "Range", "Source", "RestrictedInverseGeneralMapping", "ImagesSource", 
  "PreImagesRange", "MappingGeneratorsImages", "images", "elements" ]

A preliminary workaround in my situation is to reset the filter IsNiceMonomorphism until the inverse is known. Any hint for a proper solution is welcome.

hulpke commented 1 year ago

This is likely a relic from times when a) All nice monomorphism were to permutation groups and b) PreImage methods for action homomorphisms tended to find an element acting in the right way. I suspect the implication can be killed by now.

ThomasBreuer commented 1 year ago

Thanks, @ahulpke. Thus we can decide that GroupHomomorphismByFunction sets IsPreimagesByAsGroupGeneralMappingByImages only if the range is a permutation group. I will make some experiments what the consequences of such a change are (w.r.t. the GAP test suite). Or we could be more "conservative", and keep GroupHomomorphismByFunction setting IsPreimagesByAsGroupGeneralMappingByImages in all cases except if the range is handled via a nice monomorphism.

Perhaps it makes sense to change also the setup for action homomorphisms; note that IsPreimagesByAsGroupGeneralMappingByImages is implied by IsActionHomomorphism. (But I will not try this now.) As far as I understand the setup, having a GroupHomomorphismByFunction with known MappingGeneratorsImages is at least as good as having its AsGroupGeneralMappingByImages, thus it would be better to work without an auxiliary ByImages mapping.