diff --git a/lib/grp.gi b/lib/grp.gi index 1f1386b476..dbe91d7595 100644 --- a/lib/grp.gi +++ b/lib/grp.gi @@ -5059,6 +5059,9 @@ InstallMethod( KnowsHowToDecompose, ## InstallGlobalFunction(HasAbelianFactorGroup,function(G,N) local gen; + if HasIsAbelian(G) and IsAbelian(G) then + return true; + fi; Assert(2,IsNormal(G,N) and IsSubgroup(G,N)); gen:=Filtered(GeneratorsOfGroup(G),i->not i in N); return ForAll([1..Length(gen)], @@ -5070,11 +5073,29 @@ end); #M HasSolvableFactorGroup(,) test whether G/N is solvable ## InstallGlobalFunction(HasSolvableFactorGroup,function(G,N) -local s,l; +local gen, D, s, l; + + if HasIsSolvableGroup(G) and IsSolvableGroup(G) then + return true; + fi; Assert(2,IsNormal(G,N) and IsSubgroup(G,N)); - s := DerivedSeriesOfGroup(G); - l := Length(s); - return IsSubgroup(N,s[l]); + if HasDerivedSeriesOfGroup(G) then + s := DerivedSeriesOfGroup(G); + l := Length(s); + return IsSubgroup(N,s[l]); + fi; + D := G; + repeat + gen:=Filtered(GeneratorsOfGroup(D),i->not i in N); + if ForAll([1..Length(gen)], + i->ForAll([1..i-1],j->Comm(gen[i],gen[j]) in N)) then + return true; + fi; + D := DerivedSubgroup(D); + until IsPerfectGroup(D); + # this may be dangerous if N does not contain the identity of G + SetIsSolvableGroup(G, false); + return false; end); ############################################################################# @@ -5083,10 +5104,16 @@ end); ## InstallGlobalFunction(HasElementaryAbelianFactorGroup,function(G,N) local gen,p; + if HasIsElementaryAbelian(G) and IsElementaryAbelian(G) then + return true; + fi; if not HasAbelianFactorGroup(G,N) then return false; fi; gen:=Filtered(GeneratorsOfGroup(G),i->not i in N); + if gen = [] then + return true; + fi; p:=First([2..Order(gen[1])],i->gen[1]^i in N); return IsPrime(p) and ForAll(gen{[2..Length(gen)]},i->i^p in N); end); diff --git a/tst/testinstall/grpperm.tst b/tst/testinstall/grpperm.tst new file mode 100644 index 0000000000..a4b486683e --- /dev/null +++ b/tst/testinstall/grpperm.tst @@ -0,0 +1,62 @@ +gap> START_TEST("grpperm.tst"); +gap> G := Group((1,2),(1,2,3,4));; +gap> HasAbelianFactorGroup(G,G); +true +gap> HasElementaryAbelianFactorGroup(G,G); +true +gap> HasSolvableFactorGroup(G,G); +true +gap> N := Group((1,2)(3,4),(1,3)(2,4));; +gap> HasAbelianFactorGroup(G,N); +false +gap> HasElementaryAbelianFactorGroup(G,N); +false +gap> HasSolvableFactorGroup(G,N); +true +gap> IsAbelian(N); +true +gap> HasAbelianFactorGroup(N, Group((1,2))); +true +gap> IsElementaryAbelian(N); +true +gap> HasElementaryAbelianFactorGroup(N, Group((1,2))); +true +gap> N := Group((1,2)(3,4),(1,2,3));; +gap> HasAbelianFactorGroup(G,N); +true +gap> HasElementaryAbelianFactorGroup(G,N); +true +gap> HasSolvableFactorGroup(G,N); +true +gap> IsSolvable(G); +true +gap> HasSolvableFactorGroup(G,N); +true +gap> F := FreeGroup("x","y");; x := F.1;; y:=F.2;; +gap> G := F/[x^18,y];; +gap> HasElementaryAbelianFactorGroup(G, Group(G.1^2)); +true +gap> HasElementaryAbelianFactorGroup(G, Group(G.1^3)); +true +gap> HasElementaryAbelianFactorGroup(G, Group(G.1^6)); +false +gap> HasElementaryAbelianFactorGroup(G, Group(G.1^9)); +false +gap> HasSolvableFactorGroup(SymmetricGroup(5), Group(())); +false +gap> HasSolvableFactorGroup(SymmetricGroup(5), SymmetricGroup(5)); +true +gap> HasSolvableFactorGroup(SymmetricGroup(5), AlternatingGroup(5)); +true +gap> HasSolvableFactorGroup(AlternatingGroup(5), AlternatingGroup(5)); +true +gap> cube := Group(( 1, 3, 8, 6)( 2, 5, 7, 4)( 9,33,25,17)(10,34,26,18)(11,35,27,19),( 9,11,16,14)(10,13,15,12)( 1,17,41,40)( 4,20,44,37)( 6,22,46,35),(17,19,24,22)(18,21,23,20)( 6,25,43,16)( 7,28,42,13)( 8,30,41,11),(25,27,32,30)(26,29,31,28)( 3,38,43,19)( 5,36,45,21)( 8,33,48,24),(33,35,40,38)(34,37,39,36)( 3, 9,46,32)( 2,12,47,29)( 1,14,48,27),(41,43,48,46)(42,45,47,44)(14,22,30,38)(15,23,31,39)(16,24,32,40) );; +gap> HasSolvableFactorGroup(cube, Center(cube)); +false +gap> HasSolvableFactorGroup(cube, DerivedSeriesOfGroup(cube)[2]); +true +gap> G := SylowSubgroup(SymmetricGroup(2^7),2);; +gap> N := Center(G);; +gap> HasSolvableFactorGroup(G,N); +true +gap> STOP_TEST( "grpperm.tst", 1);