From 8377194440bd02c88630d604d352b3be29df3256 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Thu, 21 Apr 2016 02:17:55 +0200 Subject: [PATCH] Add SemidirectDecompositions and change StructureDescription !!! WARNING !!! This changes the behaviour of StructureDescription compared to the previous state, which was inconsistent with the manual. SemidirectDecompositionsOfFiniteGroup is added. This computes all or some semidirect decompositions of a group. An optional second argument can be given as the normal subgroups for which complements should be sought. Complements for normal subgroups are found by ComplementClassesRepresentatives. Unfortunately, this does not work if both N and G/N are nonsolvable. Further, an optional argument "any" is recognized, when it should return only one nontrivial semidirect decomposition if exists and fail otherwise. This is mostly implemented by applying Schur-Zassenhaus by checking if any nontrivial normal Hall subgroups exist. Another optional argument "str" is recognized, when it does not necessarily compute the complement to the normal subgroup if Schur-Zassenhaus applies. The reason is that computing the complement might be expensive and for StructureDescription only the isomorphism type of the complement is interesting. SemidirectDecompositions is a new attribute, computing all semidirect decompositions. SemidirectFactorsOfGroup is removed completely. It computed all conjugacy classes of all subgroups and therefore was rather inefficient. Further, it did not compute _all_ semidirect decompositions, but only the ones with subgroups having the same size as the first subgroup having a normal complement. This yielded inconsistent behaviour with the manual, the smallest example for such a group was SmallGroup(504,7). StructureDescription now works for infinite abelian groups, as well. Further, for semidirect decompositions it calls SemidirectDecompositionsOfFiniteGroup with "str" argument. NOTE that if the group G has a nonsolvable normal subgroup N such that G/N is nonsolvable, as well, then ComplementClassesRepresentatives errors with "No method found", and thus so do SemidirectDecompositions and StructureDescription. Previously computations for such groups did not error with "No method found", but probably took a long time. #563 tries to remedy this using the old and inefficient method, however whether it should be merged or not is currently under debate. In the meantime, for such groups we throw an error. StructureDescription of groups having size at most 100 are recomputed, and the manual of StructureDescription is rewritten to match current behaviour. Tests are added. All lines of SemidirectDecompositions are run. Not all lines of StructureDescription are run, some examples for the missing lines should be found later. --- lib/grpnames.g | 114 ++++---- lib/grpnames.gd | 90 +++++-- lib/grpnames.gi | 244 ++++++++++-------- .../opers/SemidirectDecompositions.tst | 75 ++++++ .../opers/StructureDescription.tst | 69 +++++ 5 files changed, 405 insertions(+), 187 deletions(-) create mode 100644 tst/testinstall/opers/SemidirectDecompositions.tst create mode 100644 tst/testinstall/opers/StructureDescription.tst diff --git a/lib/grpnames.g b/lib/grpnames.g index 7143b4db05e..f193ad9e121 100644 --- a/lib/grpnames.g +++ b/lib/grpnames.g @@ -25,8 +25,8 @@ NAMES_OF_SMALL_GROUPS := [ "C5 : C4", "C20", "C5 : C4", "D20", "C10 x C2" ], [ "C7 : C3", "C21" ], [ "D22", "C22" ], [ "C23" ], [ "C3 : C8", "C24", "SL(2,3)", "C3 : Q8", "C4 x S3", "D24", - "C2 x (C3 : C4)", "(C6 x C2) : C2", "C12 x C2", "C3 x D8", "C3 x Q8", - "S4", "C2 x A4", "C2 x C2 x S3", "C6 x C2 x C2" ], [ "C25", "C5 x C5" ], + "C2 x (C3 : C4)", "C3 : D8", "C12 x C2", "C3 x D8", "C3 x Q8", "S4", + "C2 x A4", "C2 x C2 x S3", "C6 x C2 x C2" ], [ "C25", "C5 x C5" ], [ "D26", "C26" ], [ "C27", "C9 x C3", "(C3 x C3) : C3", "C9 : C3", "C3 x C3 x C3" ], [ "C7 : C4", "C28", "D28", "C14 x C2" ], [ "C29" ], @@ -37,39 +37,39 @@ NAMES_OF_SMALL_GROUPS := "Q8 : C4", "(C4 x C4) : C2", "C4 : C8", "C8 : C4", "C8 : C4", "C4 . D8 = C4 . (C4 x C2)", "C16 x C2", "C16 : C2", "D32", "QD32", "Q32", "C4 x C4 x C2", "C2 x ((C4 x C2) : C2)", "C2 x (C4 : C4)", - "(C4 x C4) : C2", "C4 x D8", "C4 x Q8", "(C2 x C2 x C2 x C2) : C2", - "(C4 x C2 x C2) : C2", "(C2 x Q8) : C2", "(C4 x C2 x C2) : C2", - "(C4 x C4) : C2", "(C2 x C2) . (C2 x C2 x C2)", "(C4 x C4) : C2", - "(C4 x C4) : C2", "C4 : Q8", "C8 x C2 x C2", "C2 x (C8 : C2)", - "(C8 x C2) : C2", "C2 x D16", "C2 x QD16", "C2 x Q16", "(C8 x C2) : C2", - "(C2 x D8) : C2", "(C2 x Q8) : C2", "C4 x C2 x C2 x C2", - "C2 x C2 x D8", "C2 x C2 x Q8", "C2 x ((C4 x C2) : C2)", - "(C2 x D8) : C2", "(C2 x Q8) : C2", "C2 x C2 x C2 x C2 x C2" ], - [ "C33" ], [ "D34", "C34" ], [ "C35" ], + "(C4 x C4) : C2", "C4 x D8", "C4 x Q8", "(C2 x D8) : C2", + "(C2 x D8) : C2", "(C4 : C4) : C2", "((C4 x C2) : C2) : C2", + "((C4 x C2) : C2) : C2", "(C2 x C2) . (C2 x C2 x C2)", "(C4 x C4) : C2", + "(C2 x D8) : C2", "C4 : Q8", "C8 x C2 x C2", "C2 x (C8 : C2)", + "(C8 x C2) : C2", "C2 x D16", "C2 x QD16", "C2 x Q16", "(D8 : C2) : C2", + "(D8 : C2) : C2", "QD16 : C2", "C4 x C2 x C2 x C2", "C2 x C2 x D8", + "C2 x C2 x Q8", "C2 x ((C4 x C2) : C2)", "(C2 x D8) : C2", + "(D8 : C2) : C2", "C2 x C2 x C2 x C2 x C2" ], [ "C33" ], + [ "D34", "C34" ], [ "C35" ], [ "C9 : C4", "C36", "(C2 x C2) : C9", "D36", "C18 x C2", "C3 x (C3 : C4)", "(C3 x C3) : C4", "C12 x C3", "(C3 x C3) : C4", "S3 x S3", "C3 x A4", "C6 x S3", "C2 x ((C3 x C3) : C2)", "C6 x C6" ], [ "C37" ], [ "D38", "C38" ], [ "C13 : C3", "C39" ], [ "C5 : C8", "C40", "C5 : C8", "C5 : Q8", "C4 x D10", "D40", - "C2 x (C5 : C4)", "(C10 x C2) : C2", "C20 x C2", "C5 x D8", "C5 x Q8", + "C2 x (C5 : C4)", "C5 : D8", "C20 x C2", "C5 x D8", "C5 x Q8", "C2 x (C5 : C4)", "C2 x C2 x D10", "C10 x C2 x C2" ], [ "C41" ], - [ "(C7 : C3) : C2", "C2 x (C7 : C3)", "C7 x S3", "C3 x D14", "D42", "C42" ], + [ "C7 : C6", "C2 x (C7 : C3)", "C7 x S3", "C3 x D14", "D42", "C42" ], [ "C43" ], [ "C11 : C4", "C44", "D44", "C22 x C2" ], [ "C45", "C15 x C3" ], [ "D46", "C46" ], [ "C47" ], - [ "C3 : C16", "C48", "(C4 x C4) : C3", "C8 x S3", "C24 : C2", "C24 : C2", - "D48", "C3 : Q16", "C2 x (C3 : C8)", "(C3 : C8) : C2", "C4 x (C3 : C4)", - "(C3 : C4) : C4", "C12 : C4", "(C12 x C2) : C2", "(C3 x D8) : C2", - "(C3 : C8) : C2", "(C3 x Q8) : C2", "C3 : Q16", "(C2 x (C3 : C4)) : C2", - "C12 x C4", "C3 x ((C4 x C2) : C2)", "C3 x (C4 : C4)", "C24 x C2", - "C3 x (C8 : C2)", "C3 x D16", "C3 x QD16", "C3 x Q16", - "C2 . S4 = SL(2,3) . C2", "GL(2,3)", "A4 : C4", "C4 x A4", - "C2 x SL(2,3)", "SL(2,3) : C2", "C2 x (C3 : Q8)", "C2 x C4 x S3", - "C2 x D24", "(C12 x C2) : C2", "D8 x S3", "(C4 x S3) : C2", - "Q8 x S3", "(C3 x Q8) : C2", "C2 x C2 x (C3 : C4)", - "C2 x ((C6 x C2) : C2)", "C12 x C2 x C2", "C6 x D8", "C6 x Q8", - "C3 x ((C4 x C2) : C2)", "C2 x S4", "C2 x C2 x A4", - "(C2 x C2 x C2 x C2) : C3", "C2 x C2 x C2 x S3", "C6 x C2 x C2 x C2" ], - [ "C49", "C7 x C7" ], + [ "C3 : C16", "C48", "(C4 x C4) : C3", "C8 x S3", "C3 : (C8 : C2)", + "C3 : QD16", "D48", "C3 : Q16", "C2 x (C3 : C8)", "C3 : (C8 : C2)", + "C4 x (C3 : C4)", "C3 : (C4 : C4)", "C3 : (C4 : C4)", + "C3 : ((C4 x C2) : C2)", "C3 : D16", "C3 : QD16", "C3 : QD16", + "C3 : Q16", "C3 : ((C4 x C2) : C2)", "C12 x C4", + "C3 x ((C4 x C2) : C2)", "C3 x (C4 : C4)", "C24 x C2", "C3 x (C8 : C2)", + "C3 x D16", "C3 x QD16", "C3 x Q16", "C2 . S4 = SL(2,3) . C2", + "GL(2,3)", "A4 : C4", "C4 x A4", "C2 x SL(2,3)", + "((C4 x C2) : C2) : C3", "C2 x (C3 : Q8)", "C2 x C4 x S3", "C2 x D24", + "C3 : (D8 : C2)", "D8 x S3", "C3 : (D8 : C2)", "Q8 x S3", + "C3 : (D8 : C2)", "C2 x C2 x (C3 : C4)", "C2 x (C3 : D8)", + "C12 x C2 x C2", "C6 x D8", "C6 x Q8", "C3 x ((C4 x C2) : C2)", + "C2 x S4", "C2 x C2 x A4", "(C2 x C2 x C2 x C2) : C3", + "C2 x C2 x C2 x S3", "C6 x C2 x C2 x C2" ], [ "C49", "C7 x C7" ], [ "D50", "C50", "C5 x D10", "(C5 x C5) : C2", "C10 x C5" ], [ "C51" ], [ "C13 : C4", "C52", "C13 : C4", "D52", "C26 x C2" ], [ "C53" ], [ "D54", "C54", "C3 x D18", "C9 x S3", "((C3 x C3) : C3) : C2", @@ -78,45 +78,45 @@ NAMES_OF_SMALL_GROUPS := "C3 x ((C3 x C3) : C2)", "(C3 x C3 x C3) : C2", "C6 x C3 x C3" ], [ "C11 : C5", "C55" ], [ "C7 : C8", "C56", "C7 : Q8", "C4 x D14", "D56", "C2 x (C7 : C4)", - "(C14 x C2) : C2", "C28 x C2", "C7 x D8", "C7 x Q8", - "(C2 x C2 x C2) : C7", "C2 x C2 x D14", "C14 x C2 x C2" ], - [ "C19 : C3", "C57" ], [ "D58", "C58" ], [ "C59" ], - [ "C5 x (C3 : C4)", "C3 x (C5 : C4)", "C15 : C4", "C60", "A5", - "C3 x (C5 : C4)", "C15 : C4", "S3 x D10", "C5 x A4", "C6 x D10", + "C7 : D8", "C28 x C2", "C7 x D8", "C7 x Q8", "(C2 x C2 x C2) : C7", + "C2 x C2 x D14", "C14 x C2 x C2" ], [ "C19 : C3", "C57" ], + [ "D58", "C58" ], [ "C59" ], + [ "C5 x (C3 : C4)", "C3 x (C5 : C4)", "C3 : (C5 : C4)", "C60", "A5", + "C3 x (C5 : C4)", "C3 : (C5 : C4)", "S3 x D10", "C5 x A4", "C6 x D10", "C10 x S3", "D60", "C30 x C2" ], [ "C61" ], [ "D62", "C62" ], [ "C7 : C9", "C63", "C3 x (C7 : C3)", "C21 x C3" ],, [ "C65" ], [ "C11 x S3", "C3 x D22", "D66", "C66" ], [ "C67" ], [ "C17 : C4", "C68", "C17 : C4", "D68", "C34 x C2" ], [ "C69" ], [ "C7 x D10", "C5 x D14", "D70", "C70" ], [ "C71" ], [ "C9 : C8", "C72", "Q8 : C9", "C9 : Q8", "C4 x D18", "D72", - "C2 x (C9 : C4)", "(C18 x C2) : C2", "C36 x C2", "C9 x D8", "C9 x Q8", + "C2 x (C9 : C4)", "C9 : D8", "C36 x C2", "C9 x D8", "C9 x Q8", "C3 x (C3 : C8)", "(C3 x C3) : C8", "C24 x C3", "((C2 x C2) : C9) : C2", "C2 x ((C2 x C2) : C9)", "C2 x C2 x D18", "C18 x C2 x C2", - "(C3 x C3) : C8", "(C3 : C4) x S3", "(C3 x (C3 : C4)) : C2", - "(C6 x S3) : C2", "(C6 x S3) : C2", "(C3 x C3) : Q8", "C3 x SL(2,3)", + "(C3 x C3) : C8", "(C3 : C4) x S3", "(C3 x C3) : (C4 x C2)", + "(C3 x C3) : D8", "(C3 x C3) : D8", "(C3 x C3) : Q8", "C3 x SL(2,3)", "C3 x (C3 : Q8)", "C12 x S3", "C3 x D24", "C6 x (C3 : C4)", - "C3 x ((C6 x C2) : C2)", "(C3 x C3) : Q8", "C4 x ((C3 x C3) : C2)", - "(C12 x C3) : C2", "C2 x ((C3 x C3) : C4)", "(C6 x C6) : C2", + "C3 x (C3 : D8)", "(C3 x C3) : Q8", "C4 x ((C3 x C3) : C2)", + "(C3 x C3) : D8", "C2 x ((C3 x C3) : C4)", "(C3 x C3) : D8", "C12 x C6", "C3 x C3 x D8", "C3 x C3 x Q8", "(C3 x C3) : C8", - "(S3 x S3) : C2", "(C3 x C3) : Q8", "C3 x S4", "(C3 x A4) : C2", + "(C3 x C3) : D8", "(C3 x C3) : Q8", "C3 x S4", "(C3 x A4) : C2", "A4 x S3", "C2 x ((C3 x C3) : C4)", "C2 x S3 x S3", "C6 x A4", "C2 x C6 x S3", "C2 x C2 x ((C3 x C3) : C2)", "C6 x C6 x C2" ], [ "C73" ], [ "D74", "C74" ], [ "C75", "(C5 x C5) : C3", "C15 x C5" ], [ "C19 : C4", "C76", "D76", "C38 x C2" ], [ "C77" ], - [ "(C13 : C3) : C2", "C2 x (C13 : C3)", "C13 x S3", "C3 x D26", "D78", - "C78" ], [ "C79" ], - [ "C5 : C16", "C80", "C5 : C16", "C8 x D10", "C40 : C2", "C40 : C2", "D80", - "C5 : Q16", "C2 x (C5 : C8)", "(C5 : C8) : C2", "C4 x (C5 : C4)", - "(C5 : C4) : C4", "C20 : C4", "(C20 x C2) : C2", "(C5 x D8) : C2", - "(C5 : C8) : C2", "(C5 x Q8) : C2", "C5 : Q16", "(C2 x (C5 : C4)) : C2", - "C20 x C4", "C5 x ((C4 x C2) : C2)", "C5 x (C4 : C4)", "C40 x C2", - "C5 x (C8 : C2)", "C5 x D16", "C5 x QD16", "C5 x Q16", "(C5 : C8) : C2", - "(C5 : C8) : C2", "C4 x (C5 : C4)", "C20 : C4", "C2 x (C5 : C8)", - "(C5 : C8) : C2", "(C2 x (C5 : C4)) : C2", "C2 x (C5 : Q8)", - "C2 x C4 x D10", "C2 x D40", "(C20 x C2) : C2", "D8 x D10", - "(C4 x D10) : C2", "Q8 x D10", "(C4 x D10) : C2", - "C2 x C2 x (C5 : C4)", "C2 x ((C10 x C2) : C2)", "C20 x C2 x C2", - "C10 x D8", "C10 x Q8", "C5 x ((C4 x C2) : C2)", + [ "C13 : C6", "C2 x (C13 : C3)", "C13 x S3", "C3 x D26", "D78", "C78" ], + [ "C79" ], + [ "C5 : C16", "C80", "C5 : C16", "C8 x D10", "C5 : (C8 : C2)", "C5 : QD16", + "D80", "C5 : Q16", "C2 x (C5 : C8)", "C5 : (C8 : C2)", "C4 x (C5 : C4)", + "C5 : (C4 : C4)", "C5 : (C4 : C4)", "C5 : ((C4 x C2) : C2)", + "C5 : D16", "C5 : QD16", "C5 : QD16", "C5 : Q16", + "C5 : ((C4 x C2) : C2)", "C20 x C4", "C5 x ((C4 x C2) : C2)", + "C5 x (C4 : C4)", "C40 x C2", "C5 x (C8 : C2)", "C5 x D16", + "C5 x QD16", "C5 x Q16", "C5 : (C8 x C2)", "C5 : (C8 : C2)", + "C4 x (C5 : C4)", "C5 : (C4 : C4)", "C2 x (C5 : C8)", "C5 : (C8 : C2)", + "C5 : ((C4 x C2) : C2)", "C2 x (C5 : Q8)", "C2 x C4 x D10", "C2 x D40", + "C5 : (D8 : C2)", "D8 x D10", "C5 : (D8 : C2)", "Q8 x D10", + "C5 : (D8 : C2)", "C2 x C2 x (C5 : C4)", "C2 x (C5 : D8)", + "C20 x C2 x C2", "C10 x D8", "C10 x Q8", "C5 x ((C4 x C2) : C2)", "(C2 x C2 x C2 x C2) : C5", "C2 x C2 x (C5 : C4)", "C2 x C2 x C2 x D10", "C10 x C2 x C2 x C2" ], [ "C81", "C9 x C9", "(C9 x C3) : C3", "C9 : C9", "C27 x C3", "C27 : C3", @@ -124,16 +124,16 @@ NAMES_OF_SMALL_GROUPS := "C3 . ((C3 x C3) : C3) = (C3 x C3) . (C3 x C3)", "C9 x C3 x C3", "C3 x ((C3 x C3) : C3)", "C3 x (C9 : C3)", "(C9 x C3) : C3", "C3 x C3 x C3 x C3" ], [ "D82", "C82" ], [ "C83" ], - [ "(C7 : C4) : C3", "C4 x (C7 : C3)", "C7 x (C3 : C4)", "C3 x (C7 : C4)", - "C21 : C4", "C84", "C2 x ((C7 : C3) : C2)", "S3 x D14", - "C2 x C2 x (C7 : C3)", "C7 x A4", "(C14 x C2) : C3", "C6 x D14", + [ "C7 : C12", "C4 x (C7 : C3)", "C7 x (C3 : C4)", "C3 x (C7 : C4)", + "C3 : (C7 : C4)", "C84", "C2 x (C7 : C6)", "S3 x D14", + "C2 x C2 x (C7 : C3)", "C7 x A4", "(C2 x C2) : (C7 : C3)", "C6 x D14", "C14 x S3", "D84", "C42 x C2" ], [ "C85" ], [ "D86", "C86" ], [ "C87" ], [ "C11 : C8", "C88", "C11 : Q8", "C4 x D22", "D88", "C2 x (C11 : C4)", - "(C22 x C2) : C2", "C44 x C2", "C11 x D8", "C11 x Q8", "C2 x C2 x D22", + "C11 : D8", "C44 x C2", "C11 x D8", "C11 x Q8", "C2 x C2 x D22", "C22 x C2 x C2" ], [ "C89" ], [ "C5 x D18", "C9 x D10", "D90", "C90", "C3 x C3 x D10", "C15 x S3", - "C3 x D30", "C5 x ((C3 x C3) : C2)", "(C15 x C3) : C2", "C30 x C3" ], + "C3 x D30", "C5 x ((C3 x C3) : C2)", "(C3 x C3) : D10", "C30 x C3" ], [ "C91" ], [ "C23 : C4", "C92", "D92", "C46 x C2" ], [ "C31 : C3", "C93" ], [ "D94", "C94" ], [ "C95" ],, [ "C97" ], [ "D98", "C98", "C7 x D14", "(C7 x C7) : C2", "C14 x C7" ], diff --git a/lib/grpnames.gd b/lib/grpnames.gd index 29ebe722741..c0982eb6904 100644 --- a/lib/grpnames.gd +++ b/lib/grpnames.gd @@ -1,6 +1,7 @@ ############################################################################# ## -#W grpnames.gd Stefan Kohl +#W grpnames.gd Gábor Horváth +## Stefan Kohl ## Markus Püschel ## Sebastian Egner ## @@ -267,17 +268,56 @@ DeclareGlobalFunction( "DirectFactorsOfGroupKN", IsGroup ); ############################################################################# ## -#A SemidirectFactorsOfGroup( ) . decomposition into a semidirect product +#F SemidirectDecompositionsOfFiniteGroup( [, ][, ] ) ## ## -## +## ## ## -## A list [[H1, N1], .., [Hr, Nr]] of all -## direct or semidirect decompositions with minimal H: -## G = Hi semidirect Ni and |Hi| = |Hj| -## is minimal with respect to all semidirect products. -## Note that this function also recognizes direct products. +## Computes all conjugacy classes of complements to the normal subgroups +## in the list L. If L is not given, then it is considered +## to be the list of all normal subgroups of G. +## +## Sometimes it is not desirable to compute complements to all normal +## subgroups, but rather to some. The user can express such a wish by +## using the method "any". +## +## With the method , +## SemidirectDecompositionsOfFiniteGroup computes all conjugacy classes +## of complement subgroups to all normal subgroups in L, and +## returns a list [[N1, H1], .., [Nr, Hr]] of +## all direct or semidirect decompositions, where Ni are from +## L. +## +## If method "any" is used, then +## SemidirectDecompositionsOfFiniteGroup returns [ N, H ] +## for some nontrivial N in L if exists, and returns fail +## otherwise. In particular, it first looks if $G is defined as a +## nontrivial semidirect product, and if yes, then it returns the two +## factors. Second, it looks for a nontrivial normal Hall subgroup, and +## if finds any, then will compute a complement to it. Otherwise it goes +## through the list L. +## +## The method "str" differs from the method +## "any by not computing normal complement to a normal Hall +## subgroup N, and in this case returns [ N, G/N ]. +## +## +## +DeclareGlobalFunction( "SemidirectDecompositionsOfFiniteGroup", IsGroup ); + +############################################################################# +## +#A SemidirectDecompositions( ) +## +## +## +## +## +## A list [[N1, H1], .., [Nr, Hr]] of all +## direct or semidirect decompositions up to conjugacy classes of +## Hi. Note that this function also recognizes direct products, +## and it may take a very long time to run for particular groups. ## ## ## @@ -316,7 +356,7 @@ DeclareGlobalFunction( "DirectFactorsOfGroupKN", IsGroup ); ## 3. Die Form von psi wie oben angegeben kann durch berechnen ## von psi(h)(n) nachgepr"uft werden. ## -DeclareAttribute( "SemidirectFactorsOfGroup", IsGroup ); +DeclareAttribute( "SemidirectDecompositions", IsGroup ); ############################################################################# ## @@ -646,13 +686,14 @@ DeclareGlobalFunction( "LinearGroupParameters" ); ## 1. ## ## Lookup in a precomputed list, if the order of G is not -## larger than 100 and not equal to 64. +## larger than 100 and not equal to 64 or 96. ## ## 2. ## ## If G is abelian, then decompose it into cyclic factors ## in elementary divisors style. For example, ## "C2 x C3 x C3" is "C6 x C3". +## For infinite abelian groups, "C0" denotes the group of integers. ## ## 3. ## @@ -673,28 +714,19 @@ DeclareGlobalFunction( "LinearGroupParameters" ); ## ## 1. ## -## H is abelian +## if G is defined as a semidirect product of N, H +## then select N, H, ## ## 2. ## -## N is abelian -## -## 2a. -## -## N has many abelian invariants +## if G is solvable, then select a solvable normal Hall subgroup +## N, if exists, and consider the semidirect decomposition of +## N and G/N, ## ## 3. ## -## N is a direct product -## -## 3a. -## -## N has many direct factors -## -## 4. -## -## \phi: H \rightarrow Aut(N), -## h \mapsto (n \mapsto n^h) is injective. +## find any nontrivial normal subgroup N which has a complement +## H. ## ## ## @@ -740,12 +772,14 @@ DeclareGlobalFunction( "LinearGroupParameters" ); ## gap> List(l,StructureDescription);; l; ## [ C3 : C4, C12, A4, D12, C6 x C2 ] ## gap> List(AllSmallGroups(40),G->StructureDescription(G:short)); -## [ "5:8", "40", "5:8", "5:Q8", "4xD10", "D40", "2x(5:4)", "(10x2):2", +## [ "5:8", "40", "5:8", "5:Q8", "4xD10", "D40", "2x(5:4)", "5:D8", ## "20x2", "5xD8", "5xQ8", "2x(5:4)", "2^2xD10", "10x2^2" ] ## gap> List(AllTransitiveGroups(DegreeAction,6), ## > G->StructureDescription(G:short)); ## [ "6", "S3", "D12", "A4", "3xS3", "2xA4", "S4", "S4", "S3xS3", -## "(3^2):4", "2xS4", "A5", "(S3xS3):2", "S5", "A6", "S6" ] +## "(3^2):4", "2xS4", "A5", "(3^2):D8", "S5", "A6", "S6" ] +## gap> StructureDescription(AbelianGroup([0,2,3])); +## "C0 x C6" ## gap> StructureDescription(PSL(4,2)); ## "A8" ## ]]> diff --git a/lib/grpnames.gi b/lib/grpnames.gi index fbf04c772e2..ef098a4b3b0 100644 --- a/lib/grpnames.gi +++ b/lib/grpnames.gi @@ -1,6 +1,7 @@ ############################################################################# ## -#W grpnames.gi Stefan Kohl +#W grpnames.gi Gábor Horváth +## Stefan Kohl ## Markus Püschel ## Sebastian Egner ## @@ -670,56 +671,137 @@ InstallGlobalFunction(DirectFactorsOfGroupKN, ############################################################################# ## -#M SemidirectFactorsOfGroup( ) . . . . . . . . . . . . . generic method -## -InstallMethod( SemidirectFactorsOfGroup, - "generic method", true, [ IsGroup ], 0, - - function ( G ) - - local Hs, Ns, H, N, sizeH, sizeN, firstHN, HNs; - - if not IsFinite(G) then TryNextMethod(); fi; - - # representatives of non-1-or-G subgroups - Hs := ConjugacyClassesSubgroups(G); - Hs := List(Hs{[2..Length(Hs)-1]}, Representative); - - # non-1-or-G normal subgroups - Ns := Reversed( Filtered(Hs, H -> IsNormal(G, H)) ); - - # find first decomposition - firstHN := function () - - local H, N, sizeNs; - - sizeNs := List(Ns, Size); - for H in Hs do - if Size(G)/Size(H) in sizeNs then - for N in Filtered(Ns, N -> Size(N) = Size(G)/Size(H)) do - if IsTrivial(NormalIntersection(N, H)) then - return Size(H); - fi; - od; - fi; - od; - return 0; - end; +#M SemidirectDecompositions( ) . . . . . . . . . . . . . generic method +## +InstallGlobalFunction(SemidirectDecompositionsOfFiniteGroup, function( arg ) + + local G, Ns, fullNs, method, NHs, i, N, H, NH; #, sizes; + + method := "all"; + if Length(arg) = 1 and IsGroup(arg[1]) then + G := arg[1]; + fullNs := true; + elif Length(arg) = 2 and IsGroup(arg[1]) and arg[2] in ["all", + "any", "str"] then + G := arg[1]; + method := arg[2]; + fullNs := true; + elif Length(arg) = 2 and IsGroup(arg[1]) and IsList(arg[2]) + and ForAll( Set(arg[2]), N -> + IsSubgroup(arg[1], N) and IsNormal(arg[1], N)) + then + G := arg[1]; + Ns := ShallowCopy(arg[2]); + fullNs := false; + elif Length(arg) = 3 and IsGroup(arg[1]) and IsList(arg[2]) + and ForAll( Set(arg[2]), N -> + IsSubgroup(arg[1], N) and IsNormal(arg[1], N)) + and arg[3] in ["all", "any", "str"] then + G := arg[1]; + Ns := ShallowCopy(arg[2]); + method := arg[3]; + fullNs := false; + else + Error("usage: SemidirectDecompositionsOfFiniteGroup( [, ] [, ])"); + fi; + + if HasSemidirectDecompositions(G) then + NHs := [ ]; + for NH in SemidirectDecompositions(G) do + N := NH[1]; + H := NH[2]; + if method in [ "any", "str" ] and not IsTrivial(N) + and not IsTrivial(H) and + ( not IsBound(Ns) or N in Ns ) then + return [ N, H ]; + elif method="all" and + ( not IsBound(Ns) or N in Ns ) then + AddSet(NHs, [ N, H ]); + fi; + od; + if method in [ "any", "str" ] then + return fail; + elif method = "all" then + return NHs; + fi; + fi; + + if method in [ "any", "str" ] then + if HasSemidirectProductInfo(G) then + N := Image(Embedding(G, 2)); + H := Image(Embedding(G, 1)); + if not IsTrivial(N) and not IsTrivial(H) and + ( not IsBound(Ns) or N in Ns ) then + return [ N, H ]; + fi; + fi; + N := NormalHallSubgroupsFromSylows(G, "any"); + if N <> fail then + # by the Schur-Zassenhaus theorem there must exist a complement + if method = "any" then + H := ComplementClassesRepresentatives(G, N)[1]; + return [ N, H ]; + # only the isomorphism type of the complement is interesting + elif method = "str" then + Assert(1, Length( ComplementClassesRepresentatives(G, N) ) > 0); + return [ N, G/N ]; + fi; + fi; + fi; + + # simple groups have no nontrivial normal subgroups + if IsSimpleGroup(G) then + if method in [ "any", "str" ] then + return fail; + elif method = "all" then + return [ [TrivialSubgroup(G), G], [G, TrivialSubgroup(G)] ]; + fi; + fi; + + if not IsBound(Ns) then + Ns := ShallowCopy(NormalSubgroups(G)); + fi; +# does not seem to make things faster +# if method in [ "any", "str" ] then +# sizes := List(Ns, Size); +# SortParallel(sizes, Ns); +# Ns := Reversed(Ns); +# fi; + + NHs := [ ]; + for N in Ns do + H := ComplementClassesRepresentatives(G, N); + if Length(H)>0 then + if method in ["any", "str"] and not IsTrivial(N) + and not IsTrivial(H[1]) then + return [ N, H[1] ]; + else + for i in [1..Length(H)] do + AddSet( NHs, [ N, H[i] ] ); + od; + fi; + fi; + od; + if method in [ "any", "str" ] then + # no nontrivial decompositions exist + if fullNs then + SetSemidirectDecompositions(G, + [ [TrivialSubgroup(G), G], [G, TrivialSubgroup(G)] ]); + fi; + return fail; + else + if fullNs then + SetSemidirectDecompositions(G, NHs); + fi; + return NHs; + fi; +end); - sizeH := firstHN(); - if sizeH = 0 then return [ ]; fi; +InstallMethod( SemidirectDecompositions, + "generic method", true, [ IsGroup and IsFinite ], 0, - # find all minimal decompositions - sizeN := Size(G)/sizeH; - HNs := [ ]; - for H in Filtered(Hs, H -> Size(H) = sizeH) do - for N in Filtered(Ns, N -> Size(N) = sizeN) do - if IsTrivial(NormalIntersection(N, H)) then - Add(HNs, [H, N]); - fi; - od; - od; - return HNs; + function( G ) + return SemidirectDecompositionsOfFiniteGroup(G); end ); ############################################################################# @@ -1456,10 +1538,10 @@ InstallMethod( GLUnderlyingField, ############################################################################# ## -#M StructureDescription( ) . . . . . . . . . . . . . . for finite group +#M StructureDescription( ) . . . . . . . . . for abelian or finite group ## InstallMethod( StructureDescription, - "for finite groups", true, [ IsGroup ], 0, + "for abelian or finite groups", true, [ IsGroup ], 0, function ( G ) @@ -1478,16 +1560,14 @@ InstallMethod( StructureDescription, dname, # name for derived subgroup of G series, # series of simple groups parameter, # parameters of G in series - HNs, # minimal [H, N] decompositions - HNs1, # HN's with prefered H or N - HNs1Names, # names of products in HNs1 - HN, H, N, # semidirect factors of G - HNname, # name of HN + NH, H, N, N1, # semidirect factors of G len, # maximal number of direct factors g, # an element of G id, # id of G in the library of perfect groups short, # short / long output format - i; # counter + i, # counter + primes, # prime divisors of Size(G) + pi; # subset of primes insertsep := function ( strs, sep, brack ) @@ -1529,8 +1609,6 @@ InstallMethod( StructureDescription, return name; end; - if not IsFinite(G) then TryNextMethod(); fi; - short := ValueOption("short") = true; # fetch name from precomputed list, if available @@ -1557,6 +1635,8 @@ InstallMethod( StructureDescription, " x ","")); fi; + if not IsFinite(G) then TryNextMethod(); fi; + # special case alternating group if IsAlternatingGroup(G) then return Concatenation("A",String(AlternatingDegree(G))); fi; @@ -1652,49 +1732,9 @@ InstallMethod( StructureDescription, fi; # semidirect product decomposition - HNs := SemidirectFactorsOfGroup( G ); - if Length(HNs) > 0 then - - # prefer abelian H; abelian N; many direct factors in N; phi injective - HNs1 := Filtered(HNs, HN -> IsAbelian(HN[1])); - if Length(HNs1) > 0 then HNs := HNs1; fi; - HNs1 := Filtered(HNs, HN -> IsAbelian(HN[2])); - if Length(HNs1) > 0 then - HNs := HNs1; - len := Maximum( List(HNs, HN -> Length(AbelianInvariants(HN[2]))) ); - HNs := Filtered(HNs, HN -> Length(AbelianInvariants(HN[2])) = len); - fi; - HNs1 := Filtered(HNs, HN -> Length(DirectFactorsOfGroup(HN[2])) > 1); - if Length(HNs1) > 0 then - HNs := HNs1; - len := Maximum(List(HNs,HN -> Length(DirectFactorsOfGroup(HN[2])))); - HNs := Filtered(HNs,HN -> Length(DirectFactorsOfGroup(HN[2]))=len); - fi; - HNs1 := Filtered(HNs, HN -> IsTrivial(Centralizer(HN[1],HN[2]))); - if Length(HNs1) > 0 then HNs := HNs1; fi; - if Length(HNs) > 1 then - - # decompose the pairs [H, N] and remove isomorphic copies - HNs1 := []; - HNs1Names := []; - for HN in HNs do - HNname := Concatenation(StructureDescription(HN[1]), - StructureDescription(HN[2])); - if not HNname in HNs1Names then - Add(HNs1, HN); - Add(HNs1Names, HNname); - fi; - od; - HNs := HNs1; - - if Length(HNs) > 1 then - Info(InfoWarning,2,"Warning! Non-unique semidirect product:"); - Info(InfoWarning,2,List(HNs,HN -> List(HN,StructureDescription))); - fi; - fi; - - H := HNs[1][1]; N := HNs[1][2]; - + NH := SemidirectDecompositionsOfFiniteGroup( G, "str" ); + if NH <> fail then + H := NH[2]; N := NH[1]; return insertsep([StructureDescription(N), StructureDescription(H)]," : ","x:."); fi; diff --git a/tst/testinstall/opers/SemidirectDecompositions.tst b/tst/testinstall/opers/SemidirectDecompositions.tst new file mode 100644 index 00000000000..ac16071fcf9 --- /dev/null +++ b/tst/testinstall/opers/SemidirectDecompositions.tst @@ -0,0 +1,75 @@ +gap> START_TEST("Semidirectdecompositions.tst"); +gap> List(AllSmallGroups(12),G->List(SemidirectDecompositions(G), NH->[IdGroup(NH[1]), IdGroup(NH[2])])); +[ [ [ [ 1, 1 ], [ 12, 1 ] ], [ [ 3, 1 ], [ 4, 1 ] ], [ [ 12, 1 ], [ 1, 1 ] ] ] + , + [ [ [ 1, 1 ], [ 12, 2 ] ], [ [ 3, 1 ], [ 4, 1 ] ], [ [ 4, 1 ], [ 3, 1 ] ], + [ [ 12, 2 ], [ 1, 1 ] ] ], + [ [ [ 1, 1 ], [ 12, 3 ] ], [ [ 4, 2 ], [ 3, 1 ] ], [ [ 12, 3 ], [ 1, 1 ] ] ] + , + [ [ [ 1, 1 ], [ 12, 4 ] ], [ [ 2, 1 ], [ 6, 1 ] ], [ [ 2, 1 ], [ 6, 1 ] ], + [ [ 3, 1 ], [ 4, 2 ] ], [ [ 6, 1 ], [ 2, 1 ] ], [ [ 6, 1 ], [ 2, 1 ] ], + [ [ 6, 2 ], [ 2, 1 ] ], [ [ 6, 2 ], [ 2, 1 ] ], [ [ 12, 4 ], [ 1, 1 ] ], + [ [ 6, 1 ], [ 2, 1 ] ], [ [ 6, 1 ], [ 2, 1 ] ] ], + [ [ [ 1, 1 ], [ 12, 5 ] ], [ [ 2, 1 ], [ 6, 2 ] ], [ [ 2, 1 ], [ 6, 2 ] ], + [ [ 2, 1 ], [ 6, 2 ] ], [ [ 2, 1 ], [ 6, 2 ] ], [ [ 4, 2 ], [ 3, 1 ] ], + [ [ 3, 1 ], [ 4, 2 ] ], [ [ 6, 2 ], [ 2, 1 ] ], [ [ 6, 2 ], [ 2, 1 ] ], + [ [ 6, 2 ], [ 2, 1 ] ], [ [ 6, 2 ], [ 2, 1 ] ], [ [ 12, 5 ], [ 1, 1 ] ], + [ [ 6, 2 ], [ 2, 1 ] ], [ [ 6, 2 ], [ 2, 1 ] ], [ [ 2, 1 ], [ 6, 2 ] ], + [ [ 2, 1 ], [ 6, 2 ] ] ] ] +gap> n := 60;; for k in [1..NumberSmallGroups(n)] do G := SmallGroup(n,k);; NH := SemidirectDecompositionsOfFiniteGroup(G, "any");; if NH=fail then Print("fail\n"); else Print(List(NH, IdGroup),"\n"); fi; od; +[ [ 3, 1 ], [ 20, 2 ] ] +[ [ 3, 1 ], [ 20, 1 ] ] +[ [ 3, 1 ], [ 20, 1 ] ] +[ [ 4, 1 ], [ 15, 1 ] ] +fail +[ [ 3, 1 ], [ 20, 3 ] ] +[ [ 3, 1 ], [ 20, 3 ] ] +[ [ 3, 1 ], [ 20, 4 ] ] +[ [ 4, 2 ], [ 15, 1 ] ] +[ [ 3, 1 ], [ 20, 4 ] ] +[ [ 3, 1 ], [ 20, 5 ] ] +[ [ 3, 1 ], [ 20, 4 ] ] +[ [ 4, 2 ], [ 15, 1 ] ] +gap> n := 12;; for k in [1..NumberSmallGroups(n)] do G := SmallGroup(n,k);; NH := SemidirectDecompositionsOfFiniteGroup(G, "str");; if NH=fail then Print("fail\n"); else Print(List(NH, IdGroup),"\n"); fi; od; +[ [ 3, 1 ], [ 4, 1 ] ] +[ [ 4, 1 ], [ 3, 1 ] ] +[ [ 4, 2 ], [ 3, 1 ] ] +[ [ 3, 1 ], [ 4, 2 ] ] +[ [ 4, 2 ], [ 3, 1 ] ] +gap> G := Group((1,2,3),(2,3,4));; +gap> List(SemidirectDecompositionsOfFiniteGroup(G,NormalSubgroups(G)),NH->[IdGroup(NH[1]), IdGroup(NH[2])]); +[ [ [ 1, 1 ], [ 12, 3 ] ], [ [ 12, 3 ], [ 1, 1 ] ], [ [ 4, 2 ], [ 3, 1 ] ] ] +gap> List(SemidirectDecompositionsOfFiniteGroup(G,"all"),NH->[IdGroup(NH[1]), IdGroup(NH[2])]); +[ [ [ 1, 1 ], [ 12, 3 ] ], [ [ 12, 3 ], [ 1, 1 ] ], [ [ 4, 2 ], [ 3, 1 ] ] ] +gap> List(SemidirectDecompositionsOfFiniteGroup(G, "any"), IdGroup); +[ [ 4, 2 ], [ 3, 1 ] ] +gap> List(SemidirectDecompositionsOfFiniteGroup(G, "str"), IdGroup); +[ [ 4, 2 ], [ 3, 1 ] ] +gap> G := Group((1,2),(1,2,3,4));; Ns := [Group((1,2)(3,4),(1,3)(2,4))];; +gap> List(SemidirectDecompositionsOfFiniteGroup(G, Ns, "any"),IdGroup); +[ [ 4, 2 ], [ 6, 1 ] ] +gap> List(SemidirectDecompositions(G),NH->[IdGroup(NH[1]), IdGroup(NH[2])]); +[ [ [ 1, 1 ], [ 24, 12 ] ], [ [ 24, 12 ], [ 1, 1 ] ], [ [ 12, 3 ], [ 2, 1 ] ], + [ [ 4, 2 ], [ 6, 1 ] ] ] +gap> List(SemidirectDecompositionsOfFiniteGroup(G,"all"),NH->[IdGroup(NH[1]), IdGroup(NH[2])]); +[ [ [ 1, 1 ], [ 24, 12 ] ], [ [ 24, 12 ], [ 1, 1 ] ], [ [ 12, 3 ], [ 2, 1 ] ], + [ [ 4, 2 ], [ 6, 1 ] ] ] +gap> List(SemidirectDecompositionsOfFiniteGroup(G, "any"), IdGroup); +[ [ 12, 3 ], [ 2, 1 ] ] +gap> List(SemidirectDecompositionsOfFiniteGroup(G, "str"), IdGroup); +[ [ 12, 3 ], [ 2, 1 ] ] +gap> G := Group((1,2,3),(3,4,5));; +gap> List(SemidirectDecompositions(G),NH->[IdGroup(NH[1]), IdGroup(NH[2])]); +[ [ [ 1, 1 ], [ 60, 5 ] ], [ [ 60, 5 ], [ 1, 1 ] ] ] +gap> SemidirectDecompositionsOfFiniteGroup(G, "any"); +fail +gap> SemidirectDecompositionsOfFiniteGroup(G, "str"); +fail +gap> G := Group((1,2),(1,2,3,4,5));; List(SemidirectDecompositionsOfFiniteGroup(G, "any"), IdGroup); +[ [ 60, 5 ], [ 2, 1 ] ] +gap> G := SmallGroup(32,8);; SemidirectDecompositionsOfFiniteGroup(G, "any"); +fail +gap> N := PSL(2,32);; aut := SylowSubgroup(AutomorphismGroup(N),5);; +gap> G := SemidirectProduct(aut, N);; StructureDescription(G); +"PSL(2,32) : C5" +gap> STOP_TEST("Semidirectdecompositions.tst", 10000); diff --git a/tst/testinstall/opers/StructureDescription.tst b/tst/testinstall/opers/StructureDescription.tst new file mode 100644 index 00000000000..1e51b6c50af --- /dev/null +++ b/tst/testinstall/opers/StructureDescription.tst @@ -0,0 +1,69 @@ +gap> START_TEST("StructureDescription.tst"); +gap> l := AllSmallGroups(12);; +gap> List(l, StructureDescription);; l; +[ C3 : C4, C12, A4, D12, C6 x C2 ] +gap> List(AllSmallGroups(40),G->StructureDescription(G:short)); +[ "5:8", "40", "5:8", "5:Q8", "4xD10", "D40", "2x(5:4)", "(10x2):2", "20x2", + "5xD8", "5xQ8", "2x(5:4)", "2^2xD10", "10x2^2" ] +gap> List(AllSmallGroups(16), G -> StructureDescription(G:recompute)); +[ "C16", "C4 x C4", "(C4 x C2) : C2", "C4 : C4", "C8 x C2", "C8 : C2", "D16", + "QD16", "Q16", "C4 x C2 x C2", "C2 x D8", "C2 x Q8", "(C4 x C2) : C2", + "C2 x C2 x C2 x C2" ] +gap> List(AllSmallGroups(60), G -> StructureDescription(G:recompute)); +[ "C5 x (C3 : C4)", "C3 x (C5 : C4)", "C3 : (C5 : C4)", "C60", "A5", + "C3 x (C5 : C4)", "C3 : (C5 : C4)", "S3 x D10", "C5 x A4", "C6 x D10", + "C10 x S3", "D60", "C30 x C2" ] +gap> List(AllPrimitiveGroups(DegreeAction, 8), StructureDescription); +[ "(C2 x C2 x C2) : C7", "(C2 x C2 x C2) : (C7 : C3)", + "(C2 x C2 x C2) : PSL(3,2)", "PSL(3,2)", "PSL(3,2) : C2", "A8", "S8" ] +gap> List(AllTransitiveGroups(DegreeAction, 6), G -> StructureDescription(G:short)); +[ "6", "S3", "D12", "A4", "3xS3", "2xA4", "S4", "S4", "S3xS3", "(3^2):4", + "2xS4", "A5", "(S3xS3):2", "S5", "A6", "S6" ] +gap> StructureDescription(PSL(4,2)); +"A8" +gap> G := Group([ (4,8)(6,10), (4,6,10,8,12), (2,4,12)(6,10,8), (3,9)(4,6,10,8,12)(7,11), (3,5)(4,6,10,8,12)(9,11), (1,3,11,9,5)(4,6,10,8,12) ]);; +gap> StructureDescription(G); +"A5 x A5" + +## +## gap> G := Group([ (6,7,8,9,10), (8,9,10), (1,2)(6,7), (1,2,3,4,5)(6,7,8,9,10) ]);; +## gap> StructureDescription(G); +## "A5 : S5" +## +gap> N := PSL(2,32);; aut := SylowSubgroup(AutomorphismGroup(N),5);; +gap> G := SemidirectProduct(aut, N);; StructureDescription(G); +"PSL(2,32) : C5" +gap> G := Group(GeneratorsOfGroup(G));; StructureDescription(G); +"PSL(2,32) : C5" +gap> StructureDescription(GL(2,3)); +"GL(2,3)" +gap> StructureDescription(SL(2,3)); +"SL(2,3)" +gap> StructureDescription(SL(3,3)); +"PSL(3,3)" +gap> StructureDescription(PerfectGroup(IsPermGroup, 960, 1)); +"(C2 x C2 x C2 x C2) : A5" +gap> G := PerfectGroup(IsPermGroup,1344,1);; StructureDescription(G); +"(C2 x C2 x C2) : PSL(3,2)" +gap> G := PerfectGroup(IsPermGroup,1344,2);; StructureDescription(G); +"(C2 x C2 x C2) . PSL(3,2)" +gap> StructureDescription(SmallGroup(32,8):recompute); +"C2 . ((C4 x C2) : C2) = (C2 x C2) . (C4 x C2)" +gap> List(AllSmallNonabelianSimpleGroups([1..1000000]), StructureDescription); +[ "A5", "PSL(3,2)", "A6", "PSL(2,8)", "PSL(2,11)", "PSL(2,13)", "PSL(2,17)", + "A7", "PSL(2,19)", "PSL(2,16)", "PSL(3,3)", "PSU(3,3)", "PSL(2,23)", + "PSL(2,25)", "M11", "PSL(2,27)", "PSL(2,29)", "PSL(2,31)", "A8", + "PSL(3,4)", "PSL(2,37)", "O(5,3)", "Sz(8)", "PSL(2,32)", "PSL(2,41)", + "PSL(2,43)", "PSL(2,47)", "PSL(2,49)", "PSU(3,4)", "PSL(2,53)", "M12", + "PSL(2,59)", "PSL(2,61)", "PSU(3,5)", "PSL(2,67)", "J1", "PSL(2,71)", "A9", + "PSL(2,73)", "PSL(2,79)", "PSL(2,64)", "PSL(2,81)", "PSL(2,83)", + "PSL(2,89)", "PSL(3,5)", "M22", "PSL(2,97)", "PSL(2,101)", "PSL(2,103)", + "HJ", "PSL(2,107)", "PSL(2,109)", "PSL(2,113)", "PSL(2,121)", "PSL(2,125)", + "O(5,4)" ] +gap> StructureDescription(AbelianGroup([0,2,3,4,5,6,7,8,9,10])); +"C0 x C2520 x C60 x C6 x C2 x C2" + +## +##gap> StructureDescription(AbelianGroup([0,2,3,4,5,6,7,8,9,10]):short); +##"0x2520x60x6x2x2" +gap> STOP_TEST("StructureDescription.tst", 10000);