From e7c9f8cf6ae3260bf14826066694b8afd7ec57c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Sat, 5 Nov 2016 10:09:41 +0100 Subject: [PATCH 01/11] Reformat NAMES_OF_SMALL_GROUPS --- lib/grpnames.g | 681 +++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 552 insertions(+), 129 deletions(-) diff --git a/lib/grpnames.g b/lib/grpnames.g index 7143b4db05..56334c9e3a 100644 --- a/lib/grpnames.g +++ b/lib/grpnames.g @@ -13,135 +13,558 @@ ## NAMES_OF_SMALL_GROUPS := -[ [ "1" ], [ "C2" ], [ "C3" ], [ "C4", "C2 x C2" ], [ "C5" ], [ "S3", "C6" ], - [ "C7" ], [ "C8", "C4 x C2", "D8", "Q8", "C2 x C2 x C2" ], - [ "C9", "C3 x C3" ], [ "D10", "C10" ], [ "C11" ], - [ "C3 : C4", "C12", "A4", "D12", "C6 x C2" ], [ "C13" ], [ "D14", "C14" ], - [ "C15" ], - [ "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" ], [ "C17" ], - [ "D18", "C18", "C3 x S3", "(C3 x C3) : C2", "C6 x C3" ], [ "C19" ], - [ "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" ], - [ "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" ], - [ "C5 x S3", "C3 x D10", "D30", "C30" ], [ "C31" ], - [ "C32", "(C4 x C2) : C4", "C8 x C4", "C8 : C4", "(C8 x C2) : C2", - "((C4 x C2) : C2) : C2", "(C8 : C2) : C2", - "C2 . ((C4 x C2) : C2) = (C2 x C2) . (C4 x C2)", "(C8 x C2) : C2", - "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" ], - [ "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)", "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" ], - [ "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" ], - [ "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", - "(C9 : C3) : C2", "(C9 x C3) : C2", "((C3 x C3) : C3) : C2", - "C18 x C3", "C2 x ((C3 x C3) : C3)", "C2 x (C9 : C3)", "C3 x C3 x S3", - "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", - "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", - "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 : 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", - "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", - "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)", - "(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", - "(C3 x C3 x C3) : C3", "(C9 x C3) : C3", "(C9 x C3) : C3", - "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", - "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", - "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" ], - [ "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" ], - [ "C99", "C33 x C3" ], - [ "C25 : C4", "C100", "C25 : C4", "D100", "C50 x C2", "C5 x (C5 : C4)", - "(C5 x C5) : C4", "C20 x C5", "C5 x (C5 : C4)", "(C5 x C5) : C4", - "(C5 x C5) : C4", "(C5 x C5) : C4", "D10 x D10", "C10 x D10", - "C2 x ((C5 x C5) : C2)", "C10 x C10" ] ]; +[ [ "1" ], + [ "C2" ], + [ "C3" ], + [ "C4", + "C2 x C2" ], + [ "C5" ], + [ "S3", + "C6" ], + [ "C7" ], + [ "C8", + "C4 x C2", + "D8", + "Q8", + "C2 x C2 x C2" ], + [ "C9", + "C3 x C3" ], + [ "D10", + "C10" ], + [ "C11" ], + [ "C3 : C4", + "C12", + "A4", + "D12", + "C6 x C2" ], + [ "C13" ], + [ "D14", + "C14" ], + [ "C15" ], + [ "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" ], + [ "C17" ], + [ "D18", + "C18", + "C3 x S3", + "(C3 x C3) : C2", + "C6 x C3" ], + [ "C19" ], + [ "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" ], + [ "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" ], + [ "C5 x S3", + "C3 x D10", + "D30", + "C30" ], + [ "C31" ], + [ "C32", + "(C4 x C2) : C4", + "C8 x C4", + "C8 : C4", + "(C8 x C2) : C2", + "((C4 x C2) : C2) : C2", + "(C8 : C2) : C2", + "C2 . ((C4 x C2) : C2) = (C2 x C2) . (C4 x C2)", + "(C8 x C2) : C2", + "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" ], + [ "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)", + "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" ], + [ "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" ], + [ "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", + "(C9 : C3) : C2", + "(C9 x C3) : C2", + "((C3 x C3) : C3) : C2", + "C18 x C3", + "C2 x ((C3 x C3) : C3)", + "C2 x (C9 : C3)", + "C3 x C3 x S3", + "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", + "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", + "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 : 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", + "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", + "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)", + "(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", + "(C3 x C3 x C3) : C3", + "(C9 x C3) : C3", + "(C9 x C3) : C3", + "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", + "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", + "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" ], + [ "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" ], + [ "C99", + "C33 x C3" ], + [ "C25 : C4", + "C100", + "C25 : C4", + "D100", + "C50 x C2", + "C5 x (C5 : C4)", + "(C5 x C5) : C4", + "C20 x C5", + "C5 x (C5 : C4)", + "(C5 x C5) : C4", + "(C5 x C5) : C4", + "(C5 x C5) : C4", + "D10 x D10", + "C10 x D10", + "C2 x ((C5 x C5) : C2)", + "C10 x C10" ] ]; MakeReadOnlyGlobal( "NAMES_OF_SMALL_GROUPS" ); ############################################################################# From c3c33bd1ae9ffa010800b7316596bbe56c672e37 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 02/11] 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. Tests are aligned with the new behaviour, and not the old one. --- lib/grpnames.g | 130 +++++----- lib/grpnames.gd | 90 ++++--- lib/grpnames.gi | 236 ++++++++++-------- .../opers/SemidirectDecompositions.tst | 75 ++++++ .../opers/StructureDescription.tst | 69 +++++ 5 files changed, 409 insertions(+), 191 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 56334c9e3a..d6d33ee9dd 100644 --- a/lib/grpnames.g +++ b/lib/grpnames.g @@ -79,7 +79,7 @@ NAMES_OF_SMALL_GROUPS := "C4 x S3", "D24", "C2 x (C3 : C4)", - "(C6 x C2) : C2", + "C3 : D8", "C12 x C2", "C3 x D8", "C3 x Q8", @@ -132,14 +132,14 @@ NAMES_OF_SMALL_GROUPS := "(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 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", - "(C4 x C4) : C2", + "(C2 x D8) : C2", "C4 : Q8", "C8 x C2 x C2", "C2 x (C8 : C2)", @@ -147,15 +147,15 @@ NAMES_OF_SMALL_GROUPS := "C2 x D16", "C2 x QD16", "C2 x Q16", - "(C8 x C2) : C2", - "(C2 x D8) : C2", - "(C2 x Q8) : C2", + "(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", - "(C2 x Q8) : C2", + "(D8 : C2) : C2", "C2 x C2 x C2 x C2 x C2" ], [ "C33" ], [ "D34", @@ -187,7 +187,7 @@ NAMES_OF_SMALL_GROUPS := "C4 x D10", "D40", "C2 x (C5 : C4)", - "(C10 x C2) : C2", + "C5 : D8", "C20 x C2", "C5 x D8", "C5 x Q8", @@ -195,7 +195,7 @@ NAMES_OF_SMALL_GROUPS := "C2 x C2 x D10", "C10 x C2 x C2" ], [ "C41" ], - [ "(C7 : C3) : C2", + [ "C7 : C6", "C2 x (C7 : C3)", "C7 x S3", "C3 x D14", @@ -215,21 +215,21 @@ NAMES_OF_SMALL_GROUPS := "C48", "(C4 x C4) : C3", "C8 x S3", - "C24 : C2", - "C24 : C2", + "C3 : (C8 : C2)", + "C3 : QD16", "D48", "C3 : Q16", "C2 x (C3 : C8)", - "(C3 : C8) : C2", + "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 : (C4 : C4)", + "C3 : (C4 : C4)", + "C3 : ((C4 x C2) : C2)", + "C3 : D16", + "C3 : QD16", + "C3 : QD16", "C3 : Q16", - "(C2 x (C3 : C4)) : C2", + "C3 : ((C4 x C2) : C2)", "C12 x C4", "C3 x ((C4 x C2) : C2)", "C3 x (C4 : C4)", @@ -243,17 +243,17 @@ NAMES_OF_SMALL_GROUPS := "A4 : C4", "C4 x A4", "C2 x SL(2,3)", - "SL(2,3) : C2", + "((C4 x C2) : C2) : C3", "C2 x (C3 : Q8)", "C2 x C4 x S3", "C2 x D24", - "(C12 x C2) : C2", + "C3 : (D8 : C2)", "D8 x S3", - "(C4 x S3) : C2", + "C3 : (D8 : C2)", "Q8 x S3", - "(C3 x Q8) : C2", + "C3 : (D8 : C2)", "C2 x C2 x (C3 : C4)", - "C2 x ((C6 x C2) : C2)", + "C2 x (C3 : D8)", "C12 x C2 x C2", "C6 x D8", "C6 x Q8", @@ -300,7 +300,7 @@ NAMES_OF_SMALL_GROUPS := "C4 x D14", "D56", "C2 x (C7 : C4)", - "(C14 x C2) : C2", + "C7 : D8", "C28 x C2", "C7 x D8", "C7 x Q8", @@ -314,11 +314,11 @@ NAMES_OF_SMALL_GROUPS := [ "C59" ], [ "C5 x (C3 : C4)", "C3 x (C5 : C4)", - "C15 : C4", + "C3 : (C5 : C4)", "C60", "A5", "C3 x (C5 : C4)", - "C15 : C4", + "C3 : (C5 : C4)", "S3 x D10", "C5 x A4", "C6 x D10", @@ -357,7 +357,7 @@ NAMES_OF_SMALL_GROUPS := "C4 x D18", "D72", "C2 x (C9 : C4)", - "(C18 x C2) : C2", + "C9 : D8", "C36 x C2", "C9 x D8", "C9 x Q8", @@ -370,26 +370,26 @@ NAMES_OF_SMALL_GROUPS := "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) : (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 : D8)", "(C3 x C3) : Q8", "C4 x ((C3 x C3) : C2)", - "(C12 x C3) : C2", + "(C3 x C3) : D8", "C2 x ((C3 x C3) : C4)", - "(C6 x C6) : C2", + "(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) : D8", "(C3 x C3) : Q8", "C3 x S4", "(C3 x A4) : C2", @@ -411,7 +411,7 @@ NAMES_OF_SMALL_GROUPS := "D76", "C38 x C2" ], [ "C77" ], - [ "(C13 : C3) : C2", + [ "C13 : C6", "C2 x (C13 : C3)", "C13 x S3", "C3 x D26", @@ -422,21 +422,21 @@ NAMES_OF_SMALL_GROUPS := "C80", "C5 : C16", "C8 x D10", - "C40 : C2", - "C40 : C2", + "C5 : (C8 : C2)", + "C5 : QD16", "D80", "C5 : Q16", "C2 x (C5 : C8)", - "(C5 : C8) : C2", + "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 : (C4 : C4)", + "C5 : (C4 : C4)", + "C5 : ((C4 x C2) : C2)", + "C5 : D16", + "C5 : QD16", + "C5 : QD16", "C5 : Q16", - "(C2 x (C5 : C4)) : C2", + "C5 : ((C4 x C2) : C2)", "C20 x C4", "C5 x ((C4 x C2) : C2)", "C5 x (C4 : C4)", @@ -445,23 +445,23 @@ NAMES_OF_SMALL_GROUPS := "C5 x D16", "C5 x QD16", "C5 x Q16", - "(C5 : C8) : C2", - "(C5 : C8) : C2", + "C5 : (C8 x C2)", + "C5 : (C8 : C2)", "C4 x (C5 : C4)", - "C20 : C4", + "C5 : (C4 : C4)", "C2 x (C5 : C8)", - "(C5 : C8) : C2", - "(C2 x (C5 : C4)) : C2", + "C5 : (C8 : C2)", + "C5 : ((C4 x C2) : C2)", "C2 x (C5 : Q8)", "C2 x C4 x D10", "C2 x D40", - "(C20 x C2) : C2", + "C5 : (D8 : C2)", "D8 x D10", - "(C4 x D10) : C2", + "C5 : (D8 : C2)", "Q8 x D10", - "(C4 x D10) : C2", + "C5 : (D8 : C2)", "C2 x C2 x (C5 : C4)", - "C2 x ((C10 x C2) : C2)", + "C2 x (C5 : D8)", "C20 x C2 x C2", "C10 x D8", "C10 x Q8", @@ -488,17 +488,17 @@ NAMES_OF_SMALL_GROUPS := [ "D82", "C82" ], [ "C83" ], - [ "(C7 : C4) : C3", + [ "C7 : C12", "C4 x (C7 : C3)", "C7 x (C3 : C4)", "C3 x (C7 : C4)", - "C21 : C4", + "C3 : (C7 : C4)", "C84", - "C2 x ((C7 : C3) : C2)", + "C2 x (C7 : C6)", "S3 x D14", "C2 x C2 x (C7 : C3)", "C7 x A4", - "(C14 x C2) : C3", + "(C2 x C2) : (C7 : C3)", "C6 x D14", "C14 x S3", "D84", @@ -513,7 +513,7 @@ NAMES_OF_SMALL_GROUPS := "C4 x D22", "D88", "C2 x (C11 : C4)", - "(C22 x C2) : C2", + "C11 : D8", "C44 x C2", "C11 x D8", "C11 x Q8", @@ -528,7 +528,7 @@ NAMES_OF_SMALL_GROUPS := "C15 x S3", "C3 x D30", "C5 x ((C3 x C3) : C2)", - "(C15 x C3) : C2", + "(C3 x C3) : D10", "C30 x C3" ], [ "C91" ], [ "C23 : C4", diff --git a/lib/grpnames.gd b/lib/grpnames.gd index a5ea1d359f..8b4f926c26 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 ## @@ -286,17 +287,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. ## ## ## @@ -335,7 +375,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 ); ############################################################################# ## @@ -665,13 +705,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. ## @@ -692,28 +733,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. ## ## ## @@ -759,12 +791,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 a94b947b02..ff05b1e91b 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 ## @@ -709,56 +710,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); +#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; - # non-1-or-G normal subgroups - Ns := Reversed( Filtered(Hs, H -> IsNormal(G, H)) ); + 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; - # find first decomposition - firstHN := function () + 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; - local H, N, sizeNs; + # 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; - 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; + 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 ); ############################################################################# @@ -1495,10 +1577,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 ) @@ -1517,16 +1599,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 ) @@ -1568,8 +1648,6 @@ InstallMethod( StructureDescription, return name; end; - if not IsFinite(G) then TryNextMethod(); fi; - short := ValueOption("short") = true; # fetch name from precomputed list, if available @@ -1596,6 +1674,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; @@ -1691,49 +1771,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 0000000000..ac16071fcf --- /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 0000000000..e5ac042053 --- /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)", "5:D8", "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", "(3^2):D8", "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); From 6b1b2ba0e7f660a59281d4f2270d7e120e8f08a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Fri, 22 Apr 2016 23:44:57 +0200 Subject: [PATCH 03/11] Replace StructureDescription outputs to new ones in bugfix.tst --- tst/teststandard/bugfix.tst | 30 ++++++++++++++++-------------- 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/tst/teststandard/bugfix.tst b/tst/teststandard/bugfix.tst index 6e093d10fe..cb8577cf98 100644 --- a/tst/teststandard/bugfix.tst +++ b/tst/teststandard/bugfix.tst @@ -656,18 +656,20 @@ gap> z^5-z-1; 486192462527432755459620441970617283/ 14404247382319842421697357558805709031116987826242631261357 -# 2005/05/03 (SK) -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(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" +# These are already in tst/testintstall/opers/StructureDescription.tst, +# thus they are superfluous here. +## 2005/05/03 (SK) +#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(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" # 2005/05/03 (BE) gap> NumberSmallGroups(5^6); @@ -1092,11 +1094,11 @@ gap> testG := > return (Group(M1)); > end;; gap> StructureDescription(testG(8,2)); -"(C8 x C4) : C2" +"((C8 x C2) : C2) : C2" gap> StructureDescription(testG(8,3)); "C3 x QD16" gap> StructureDescription(testG(8,4)); -"(C16 x C4) : C2" +"((C16 x C2) : C2) : C2" # 2006/02/27 (AH) gap> RepresentativeAction(Group(()), [1], [2], OnSets);; From 01b73b82f6989a08cd6bdb09b86737aca6ba16f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Fri, 4 Nov 2016 18:42:03 +0100 Subject: [PATCH 04/11] Remove superfluous chunk --- tst/teststandard/bugfix.tst | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/tst/teststandard/bugfix.tst b/tst/teststandard/bugfix.tst index cb8577cf98..958dcaa0e0 100644 --- a/tst/teststandard/bugfix.tst +++ b/tst/teststandard/bugfix.tst @@ -656,21 +656,6 @@ gap> z^5-z-1; 486192462527432755459620441970617283/ 14404247382319842421697357558805709031116987826242631261357 -# These are already in tst/testintstall/opers/StructureDescription.tst, -# thus they are superfluous here. -## 2005/05/03 (SK) -#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(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" - # 2005/05/03 (BE) gap> NumberSmallGroups(5^6); 684 From f797987d007e588aa969fd53e54c0eee5a1ccfee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Fri, 4 Nov 2016 18:52:56 +0100 Subject: [PATCH 05/11] Add short explanation to commented tests --- tst/testinstall/opers/StructureDescription.tst | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tst/testinstall/opers/StructureDescription.tst b/tst/testinstall/opers/StructureDescription.tst index e5ac042053..7ccbe5f283 100644 --- a/tst/testinstall/opers/StructureDescription.tst +++ b/tst/testinstall/opers/StructureDescription.tst @@ -25,6 +25,10 @@ gap> G := Group([ (4,8)(6,10), (4,6,10,8,12), (2,4,12)(6,10,8), (3,9)(4,6,10,8,1 gap> StructureDescription(G); "A5 x A5" +## +## This example currently breaks, as both N and G/N are non-solvable. +## ComplementClassesRepresentatives currently does not handle such groups, +## and thus neither does SemidirectDecompositions or StructureDescription. ## ## 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); @@ -63,6 +67,8 @@ gap> List(AllSmallNonabelianSimpleGroups([1..1000000]), StructureDescription); gap> StructureDescription(AbelianGroup([0,2,3,4,5,6,7,8,9,10])); "C0 x C2520 x C60 x C6 x C2 x C2" +## +## Currently the value "short" does not work for infinite abelian groups. ## ##gap> StructureDescription(AbelianGroup([0,2,3,4,5,6,7,8,9,10]):short); ##"0x2520x60x6x2x2" From 1f35f6b6df3d2ae34ae030c086e63c8ec7e426e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Thu, 24 Nov 2016 19:25:47 +0100 Subject: [PATCH 06/11] Check if both N and G/N are not solvable in SemidirectDecompositions --- lib/grpnames.gi | 4 ++++ tst/testinstall/opers/StructureDescription.tst | 13 +++---------- 2 files changed, 7 insertions(+), 10 deletions(-) diff --git a/lib/grpnames.gi b/lib/grpnames.gi index ff05b1e91b..6100c06c80 100644 --- a/lib/grpnames.gi +++ b/lib/grpnames.gi @@ -809,6 +809,10 @@ InstallGlobalFunction(SemidirectDecompositionsOfFiniteGroup, function( arg ) NHs := [ ]; for N in Ns do + if not IsSolvableGroup(N) and not HasSolvableFactorGroup(G, N) then + # compute subgroup lattice, currently no other method for complement + ConjugacyClassesSubgroups(G);; + fi; H := ComplementClassesRepresentatives(G, N); if Length(H)>0 then if method in ["any", "str"] and not IsTrivial(N) diff --git a/tst/testinstall/opers/StructureDescription.tst b/tst/testinstall/opers/StructureDescription.tst index 7ccbe5f283..863b01472c 100644 --- a/tst/testinstall/opers/StructureDescription.tst +++ b/tst/testinstall/opers/StructureDescription.tst @@ -24,16 +24,9 @@ gap> StructureDescription(PSL(4,2)); 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" - -## -## This example currently breaks, as both N and G/N are non-solvable. -## ComplementClassesRepresentatives currently does not handle such groups, -## and thus neither does SemidirectDecompositions or StructureDescription. -## -## 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> 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" From 9c87c61455a9920756154e21a67a7eeb6e502eb1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Sat, 26 Nov 2016 11:14:12 +0100 Subject: [PATCH 07/11] Move some slower tests to teststandard --- tst/testinstall/opers/StructureDescription.tst | 3 --- tst/teststandard/opers/StructureDescription.tst | 6 ++++++ 2 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 tst/teststandard/opers/StructureDescription.tst diff --git a/tst/testinstall/opers/StructureDescription.tst b/tst/testinstall/opers/StructureDescription.tst index 863b01472c..2b4bc36917 100644 --- a/tst/testinstall/opers/StructureDescription.tst +++ b/tst/testinstall/opers/StructureDescription.tst @@ -24,9 +24,6 @@ gap> StructureDescription(PSL(4,2)); 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" diff --git a/tst/teststandard/opers/StructureDescription.tst b/tst/teststandard/opers/StructureDescription.tst new file mode 100644 index 0000000000..27d2de90ec --- /dev/null +++ b/tst/teststandard/opers/StructureDescription.tst @@ -0,0 +1,6 @@ +gap> START_TEST("StructureDescription.tst"); +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> for n in [1..100] do for i in [1..NumberSmallGroups(n)] do if n<>64 and n<>96 then G := SmallGroup(n,i); H := SmallGroup(n, i); if StructureDescription(G)<>StructureDescription(H:recompute) then Print(n, ", ", i, ", ", StructureDescription(H:recompute), "\n"); fi; fi; od; od; +gap> STOP_TEST("StructureDescription.tst", 10000); From c53e7623c30b7480a85c96e536638a5a6dd8a4e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Sat, 26 Nov 2016 17:09:44 +0100 Subject: [PATCH 08/11] Add test for error message --- tst/testinstall/opers/SemidirectDecompositions.tst | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tst/testinstall/opers/SemidirectDecompositions.tst b/tst/testinstall/opers/SemidirectDecompositions.tst index ac16071fcf..083e3d09a9 100644 --- a/tst/testinstall/opers/SemidirectDecompositions.tst +++ b/tst/testinstall/opers/SemidirectDecompositions.tst @@ -72,4 +72,6 @@ fail gap> N := PSL(2,32);; aut := SylowSubgroup(AutomorphismGroup(N),5);; gap> G := SemidirectProduct(aut, N);; StructureDescription(G); "PSL(2,32) : C5" +gap> SemidirectDecompositionsOfFiniteGroup(G, "any", "full"); +Error, usage: SemidirectDecompositionsOfFiniteGroup( [, ] [, ]) gap> STOP_TEST("Semidirectdecompositions.tst", 10000); From 3b5dc57b30924acd3993dcfb0476c3ff039f3e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Sat, 26 Nov 2016 22:33:19 +0100 Subject: [PATCH 09/11] Add option nice to StructureDescription This commit adds the old documented behaviour of StructureDescription. If option nice is set, then all SemidirectDecompositions are computed and one [N,H] will be chosen by the old preferences, namely abelian H, abelian N with the most abelian invariants and the most direct factors, and with H acting faithfully on N. --- lib/grpnames.gd | 32 +++++++++ lib/grpnames.gi | 71 +++++++++++++++++-- .../opers/StructureDescription.tst | 14 ++++ 3 files changed, 112 insertions(+), 5 deletions(-) diff --git a/lib/grpnames.gd b/lib/grpnames.gd index 8b4f926c26..49d87a48c6 100644 --- a/lib/grpnames.gd +++ b/lib/grpnames.gd @@ -748,6 +748,38 @@ DeclareGlobalFunction( "LinearGroupParameters" ); ## H. ## ## +## The option nice is recognized. If this option is set, then all +## semidirect products are computed in order to find a possibly nicer +## presentation. Note, that this may take a long time. +## If the option nice is set, then GAP would select a pair +## N, H with the following preferences: +## +## 1. +## +## H is abelian +## +## 2. +## +## N is abelian +## +## 2a. +## +## N has many abelian invariants +## +## 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. +## +## ## ## 6. ## diff --git a/lib/grpnames.gi b/lib/grpnames.gi index 6100c06c80..44b9828760 100644 --- a/lib/grpnames.gi +++ b/lib/grpnames.gi @@ -1604,10 +1604,15 @@ InstallMethod( StructureDescription, series, # series of simple groups parameter, # parameters of G in series NH, H, N, N1, # semidirect factors of G + NHs, # [N, H] decompositions + NHname, # name of NH + NHs1, # NH's with preferred N and H + NHs1Names, # names of products in NHs1 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 + nice, # nice output (slower) i, # counter primes, # prime divisors of Size(G) pi; # subset of primes @@ -1653,6 +1658,7 @@ InstallMethod( StructureDescription, end; short := ValueOption("short") = true; + nice := ValueOption("nice") = true; # fetch name from precomputed list, if available if ValueOption("recompute") <> true and Size(G) <= 2000 then @@ -1775,11 +1781,66 @@ InstallMethod( StructureDescription, fi; # semidirect product decomposition - NH := SemidirectDecompositionsOfFiniteGroup( G, "str" ); - if NH <> fail then - H := NH[2]; N := NH[1]; - return insertsep([StructureDescription(N), - StructureDescription(H)]," : ","x:."); + if not nice then + NH := SemidirectDecompositionsOfFiniteGroup( G, "str" ); + if NH <> fail then + H := NH[2]; N := NH[1]; + return insertsep([StructureDescription(N), + StructureDescription(H)]," : ","x:."); + fi; + else + NHs := [ ]; + for NH in SemidirectDecompositionsOfFiniteGroup( G, "all" ) do + if not IsTrivial( NH[1] ) and not IsTrivial( NH[2] ) then + AddSet(NHs, [ NH[1], NH[2] ]); + fi; + od; + if Length(NHs) > 0 then + + # prefer abelian H; abelian N; many direct factors in N; phi injective + NHs1 := Filtered(NHs, NH -> IsAbelian(NH[2])); + if Length(NHs1) > 0 then NHs := NHs1; fi; + NHs1 := Filtered(NHs, NH -> IsAbelian(NH[1])); + if Length(NHs1) > 0 then + NHs := NHs1; + len := Maximum( List(NHs, NH -> Length(AbelianInvariants(NH[1]))) ); + NHs := Filtered(NHs, NH -> Length(AbelianInvariants(NH[1])) = len); + fi; + NHs1 := Filtered(NHs, NH -> Length(DirectFactorsOfGroup(NH[1])) > 1); + if Length(NHs1) > 0 then + NHs := NHs1; + len := Maximum(List(NHs,NH -> Length(DirectFactorsOfGroup(NH[1])))); + NHs := Filtered(NHs,NH -> Length(DirectFactorsOfGroup(NH[1]))=len); + fi; + NHs1 := Filtered(NHs, NH -> IsTrivial(Centralizer(NH[2],NH[1]))); + if Length(NHs1) > 0 then NHs := NHs1; fi; + if Length(NHs) > 1 then + + # decompose the pairs [N, H] and remove isomorphic copies + NHs1 := []; + NHs1Names := []; + for NH in NHs do + NHname := insertsep([StructureDescription(NH[1]), + StructureDescription(NH[2])], + " : ","x:."); + if not NHname in NHs1Names then + Add(NHs1, NH); + Add(NHs1Names, NHname); + fi; + od; + NHs := NHs1; + + if Length(NHs) > 1 then + Info(InfoWarning,2,"Warning! Non-unique semidirect product:"); + Info(InfoWarning,2,List(NHs,NH -> List(NH,StructureDescription))); + fi; + fi; + + H := NHs[1][2]; N := NHs[1][1]; + + return insertsep([StructureDescription(N:nice), + StructureDescription(H:nice)]," : ","x:."); + fi; fi; # non-splitting, non-simple group diff --git a/tst/testinstall/opers/StructureDescription.tst b/tst/testinstall/opers/StructureDescription.tst index 2b4bc36917..3182b28944 100644 --- a/tst/testinstall/opers/StructureDescription.tst +++ b/tst/testinstall/opers/StructureDescription.tst @@ -31,8 +31,12 @@ gap> G := Group(GeneratorsOfGroup(G));; StructureDescription(G); "PSL(2,32) : C5" gap> StructureDescription(GL(2,3)); "GL(2,3)" +gap> StructureDescription(GL(2,3):recompute); +"GL(2,3)" gap> StructureDescription(SL(2,3)); "SL(2,3)" +gap> StructureDescription(SL(2,3):recompute); +"SL(2,3)" gap> StructureDescription(SL(3,3)); "PSL(3,3)" gap> StructureDescription(PerfectGroup(IsPermGroup, 960, 1)); @@ -56,6 +60,16 @@ gap> List(AllSmallNonabelianSimpleGroups([1..1000000]), StructureDescription); "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> infolevel:=InfoLevel(InfoWarning);; SetInfoLevel(InfoWarning,2); +gap> StructureDescription(SmallGroup(48,16):recompute,nice); +#I Warning! Non-unique semidirect product: +#I [ [ "C3 : Q8", "C2" ], [ "C3 : C8", "C2" ] ] +"(C3 : Q8) : C2" +gap> StructureDescription(SmallGroup(64,17):recompute,nice); +#I Warning! Non-unique semidirect product: +#I [ [ "C4 x C2", "C8" ], [ "C8 x C2", "C4" ] ] +"(C4 x C2) : C8" +gap> SetInfoLevel(InfoWarning,infolevel); ## ## Currently the value "short" does not work for infinite abelian groups. From 28e740bf69c0e9834527e3f03393aa0564d39f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Sun, 27 Nov 2016 10:17:20 +0100 Subject: [PATCH 10/11] Make test files more resilient to StructureDescription Further, grpnames.g contains the "nice" outputs of StructureDescription. --- lib/grpnames.g | 127 +++++++++--------- .../opers/SemidirectDecompositions.tst | 5 + .../opers/StructureDescription.tst | 22 ++- .../opers/StructureDescription.tst | 1 - tst/teststandard/small_groups2.tst | 2 +- 5 files changed, 80 insertions(+), 77 deletions(-) diff --git a/lib/grpnames.g b/lib/grpnames.g index d6d33ee9dd..0e268e7425 100644 --- a/lib/grpnames.g +++ b/lib/grpnames.g @@ -1,6 +1,7 @@ ############################################################################# ## -#W grpnames.g Stefan Kohl +#W grpnames.g Gábor Horváth +## Stefan Kohl ## ## #Y Copyright (C) 2004 The GAP Group @@ -79,7 +80,7 @@ NAMES_OF_SMALL_GROUPS := "C4 x S3", "D24", "C2 x (C3 : C4)", - "C3 : D8", + "(C6 x C2) : C2", "C12 x C2", "C3 x D8", "C3 x Q8", @@ -111,7 +112,7 @@ NAMES_OF_SMALL_GROUPS := "C8 x C4", "C8 : C4", "(C8 x C2) : C2", - "((C4 x C2) : C2) : C2", + "(C2 x C2 x C2) : C4", "(C8 : C2) : C2", "C2 . ((C4 x C2) : C2) = (C2 x C2) . (C4 x C2)", "(C8 x C2) : C2", @@ -132,14 +133,14 @@ NAMES_OF_SMALL_GROUPS := "(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 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", - "(C2 x D8) : C2", + "(C4 x C4) : C2", "C4 : Q8", "C8 x C2 x C2", "C2 x (C8 : C2)", @@ -147,15 +148,15 @@ NAMES_OF_SMALL_GROUPS := "C2 x D16", "C2 x QD16", "C2 x Q16", - "(D8 : C2) : C2", - "(D8 : C2) : C2", - "QD16 : C2", + "(C8 x C2) : C2", + "C8 : (C2 x 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", - "(D8 : C2) : C2", + "(C2 x C2 x C2) : (C2 x C2)", + "(C2 x Q8) : C2", "C2 x C2 x C2 x C2 x C2" ], [ "C33" ], [ "D34", @@ -187,7 +188,7 @@ NAMES_OF_SMALL_GROUPS := "C4 x D10", "D40", "C2 x (C5 : C4)", - "C5 : D8", + "(C10 x C2) : C2", "C20 x C2", "C5 x D8", "C5 x Q8", @@ -215,21 +216,21 @@ NAMES_OF_SMALL_GROUPS := "C48", "(C4 x C4) : C3", "C8 x S3", - "C3 : (C8 : C2)", - "C3 : QD16", + "C24 : C2", + "C24 : C2", "D48", "C3 : Q16", "C2 x (C3 : C8)", - "C3 : (C8 : C2)", + "(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 : C4) : C4", + "C12 : C4", + "(C12 x C2) : C2", + "(C3 x D8) : C2", + "(C3 : Q8) : C2", + "(C3 x Q8) : C2", "C3 : Q16", - "C3 : ((C4 x C2) : C2)", + "(C6 x C2) : C4", "C12 x C4", "C3 x ((C4 x C2) : C2)", "C3 x (C4 : C4)", @@ -247,13 +248,13 @@ NAMES_OF_SMALL_GROUPS := "C2 x (C3 : Q8)", "C2 x C4 x S3", "C2 x D24", - "C3 : (D8 : C2)", + "(C12 x C2) : C2", "D8 x S3", - "C3 : (D8 : C2)", + "(C4 x S3) : C2", "Q8 x S3", - "C3 : (D8 : C2)", + "(C4 x S3) : C2", "C2 x C2 x (C3 : C4)", - "C2 x (C3 : D8)", + "C2 x ((C6 x C2) : C2)", "C12 x C2 x C2", "C6 x D8", "C6 x Q8", @@ -281,8 +282,8 @@ NAMES_OF_SMALL_GROUPS := "C54", "C3 x D18", "C9 x S3", - "((C3 x C3) : C3) : C2", - "(C9 : C3) : C2", + "(C3 x C3) : C6", + "C9 : C6", "(C9 x C3) : C2", "((C3 x C3) : C3) : C2", "C18 x C3", @@ -300,7 +301,7 @@ NAMES_OF_SMALL_GROUPS := "C4 x D14", "D56", "C2 x (C7 : C4)", - "C7 : D8", + "(C14 x C2) : C2", "C28 x C2", "C7 x D8", "C7 x Q8", @@ -314,11 +315,11 @@ NAMES_OF_SMALL_GROUPS := [ "C59" ], [ "C5 x (C3 : C4)", "C3 x (C5 : C4)", - "C3 : (C5 : C4)", + "C15 : C4", "C60", "A5", "C3 x (C5 : C4)", - "C3 : (C5 : C4)", + "C15 : C4", "S3 x D10", "C5 x A4", "C6 x D10", @@ -357,7 +358,7 @@ NAMES_OF_SMALL_GROUPS := "C4 x D18", "D72", "C2 x (C9 : C4)", - "C9 : D8", + "(C18 x C2) : C2", "C36 x C2", "C9 x D8", "C9 x Q8", @@ -371,25 +372,25 @@ NAMES_OF_SMALL_GROUPS := "(C3 x C3) : C8", "(C3 : C4) x S3", "(C3 x C3) : (C4 x C2)", - "(C3 x C3) : D8", - "(C3 x C3) : D8", + "(C6 x S3) : C2", + "(C6 x S3) : C2", "(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 (C3 : D8)", + "C3 x ((C6 x C2) : C2)", "(C3 x C3) : Q8", "C4 x ((C3 x C3) : C2)", - "(C3 x C3) : D8", + "(C12 x C3) : C2", "C2 x ((C3 x C3) : C4)", - "(C3 x C3) : D8", + "(C6 x C6) : C2", "C12 x C6", "C3 x C3 x D8", "C3 x C3 x Q8", "(C3 x C3) : C8", - "(C3 x C3) : D8", + "(S3 x S3) : C2", "(C3 x C3) : Q8", "C3 x S4", "(C3 x A4) : C2", @@ -422,21 +423,21 @@ NAMES_OF_SMALL_GROUPS := "C80", "C5 : C16", "C8 x D10", - "C5 : (C8 : C2)", - "C5 : QD16", + "C40 : C2", + "C40 : C2", "D80", "C5 : Q16", "C2 x (C5 : C8)", - "C5 : (C8 : C2)", + "(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 : C4) : C4", + "C20 : C4", + "(C20 x C2) : C2", + "(C5 x D8) : C2", + "(C5 : Q8) : C2", + "(C5 x Q8) : C2", "C5 : Q16", - "C5 : ((C4 x C2) : C2)", + "(C10 x C2) : C4", "C20 x C4", "C5 x ((C4 x C2) : C2)", "C5 x (C4 : C4)", @@ -446,22 +447,22 @@ NAMES_OF_SMALL_GROUPS := "C5 x QD16", "C5 x Q16", "C5 : (C8 x C2)", - "C5 : (C8 : C2)", + "(C5 : C8) : C2", "C4 x (C5 : C4)", - "C5 : (C4 : C4)", + "C20 : C4", "C2 x (C5 : C8)", - "C5 : (C8 : C2)", - "C5 : ((C4 x C2) : C2)", + "(C5 : C8) : C2", + "(C10 x C2) : C4", "C2 x (C5 : Q8)", "C2 x C4 x D10", "C2 x D40", - "C5 : (D8 : C2)", + "(C20 x C2) : C2", "D8 x D10", - "C5 : (D8 : C2)", + "(C4 x D10) : C2", "Q8 x D10", - "C5 : (D8 : C2)", + "(C4 x D10) : C2", "C2 x C2 x (C5 : C4)", - "C2 x (C5 : D8)", + "C2 x ((C10 x C2) : C2)", "C20 x C2 x C2", "C10 x D8", "C10 x Q8", @@ -492,13 +493,13 @@ NAMES_OF_SMALL_GROUPS := "C4 x (C7 : C3)", "C7 x (C3 : C4)", "C3 x (C7 : C4)", - "C3 : (C7 : C4)", + "C21 : C4", "C84", "C2 x (C7 : C6)", "S3 x D14", "C2 x C2 x (C7 : C3)", "C7 x A4", - "(C2 x C2) : (C7 : C3)", + "(C14 x C2) : C3", "C6 x D14", "C14 x S3", "D84", @@ -513,7 +514,7 @@ NAMES_OF_SMALL_GROUPS := "C4 x D22", "D88", "C2 x (C11 : C4)", - "C11 : D8", + "(C22 x C2) : C2", "C44 x C2", "C11 x D8", "C11 x Q8", @@ -528,7 +529,7 @@ NAMES_OF_SMALL_GROUPS := "C15 x S3", "C3 x D30", "C5 x ((C3 x C3) : C2)", - "(C3 x C3) : D10", + "(C15 x C3) : C2", "C30 x C3" ], [ "C91" ], [ "C23 : C4", diff --git a/tst/testinstall/opers/SemidirectDecompositions.tst b/tst/testinstall/opers/SemidirectDecompositions.tst index 083e3d09a9..348434401e 100644 --- a/tst/testinstall/opers/SemidirectDecompositions.tst +++ b/tst/testinstall/opers/SemidirectDecompositions.tst @@ -74,4 +74,9 @@ gap> G := SemidirectProduct(aut, N);; StructureDescription(G); "PSL(2,32) : C5" gap> SemidirectDecompositionsOfFiniteGroup(G, "any", "full"); Error, usage: SemidirectDecompositionsOfFiniteGroup( [, ] [, ]) +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> infolevel:=InfoLevel(InfoPerformance);; SetInfoLevel(InfoPerformance,0); +gap> Length(SemidirectDecompositions(G)); +8 +gap> SetInfoLevel(InfoPerformance,infolevel); gap> STOP_TEST("Semidirectdecompositions.tst", 10000); diff --git a/tst/testinstall/opers/StructureDescription.tst b/tst/testinstall/opers/StructureDescription.tst index 3182b28944..e25acc706c 100644 --- a/tst/testinstall/opers/StructureDescription.tst +++ b/tst/testinstall/opers/StructureDescription.tst @@ -3,12 +3,8 @@ 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)", "5:D8", "20x2", +[ "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", @@ -18,12 +14,14 @@ gap> List(AllPrimitiveGroups(DegreeAction, 8), StructureDescription); "(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", "(3^2):D8", "S5", "A6", "S6" ] + "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> infolevel:=InfoLevel(InfoPerformance);; SetInfoLevel(InfoPerformance,0); gap> StructureDescription(G); "A5 x A5" +gap> SetInfoLevel(InfoPerformance,infolevel); gap> N := PSL(2,32);; aut := SylowSubgroup(AutomorphismGroup(N),5);; gap> G := SemidirectProduct(aut, N);; StructureDescription(G); "PSL(2,32) : C5" @@ -45,8 +43,8 @@ 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> StructureDescription(SmallGroup(32,15):recompute); +"C4 . D8 = C4 . (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)", @@ -58,8 +56,8 @@ gap> List(AllSmallNonabelianSimpleGroups([1..1000000]), StructureDescription); "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,0,0,2,3,4,5,6,7,8,9,10])); +"C0 x C0 x C0 x C2520 x C60 x C6 x C2 x C2" gap> infolevel:=InfoLevel(InfoWarning);; SetInfoLevel(InfoWarning,2); gap> StructureDescription(SmallGroup(48,16):recompute,nice); #I Warning! Non-unique semidirect product: @@ -74,6 +72,6 @@ gap> SetInfoLevel(InfoWarning,infolevel); ## ## Currently the value "short" does not work for infinite abelian groups. ## -##gap> StructureDescription(AbelianGroup([0,2,3,4,5,6,7,8,9,10]):short); -##"0x2520x60x6x2x2" +##gap> StructureDescription(AbelianGroup([0,0,0,2,3,4,5,6,7,8,9,10]):short); +##"0^3x2520x60x6x2^2" gap> STOP_TEST("StructureDescription.tst", 10000); diff --git a/tst/teststandard/opers/StructureDescription.tst b/tst/teststandard/opers/StructureDescription.tst index 27d2de90ec..390916d4ae 100644 --- a/tst/teststandard/opers/StructureDescription.tst +++ b/tst/teststandard/opers/StructureDescription.tst @@ -2,5 +2,4 @@ gap> START_TEST("StructureDescription.tst"); 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> for n in [1..100] do for i in [1..NumberSmallGroups(n)] do if n<>64 and n<>96 then G := SmallGroup(n,i); H := SmallGroup(n, i); if StructureDescription(G)<>StructureDescription(H:recompute) then Print(n, ", ", i, ", ", StructureDescription(H:recompute), "\n"); fi; fi; od; od; gap> STOP_TEST("StructureDescription.tst", 10000); diff --git a/tst/teststandard/small_groups2.tst b/tst/teststandard/small_groups2.tst index e278967ec5..175656b596 100644 --- a/tst/teststandard/small_groups2.tst +++ b/tst/teststandard/small_groups2.tst @@ -6,7 +6,7 @@ gap> for n in [1..Length(NAMES_OF_SMALL_GROUPS)] do > G := SmallGroup(n, i); > descA := NAMES_OF_SMALL_GROUPS[n][i]; > G := Subgroup(G, GeneratorsOfGroup(G)); -> descB := StructureDescription(G : recompute := true); +> descB := StructureDescription(G : recompute := true, nice := true); > if descA <> descB then > Print([n,i], ": bad description ", descB, ", should be ", descA, "\n"); > AddSet(bad, [n,i]); From 0ee8cf5d0066108a35c599fe33417bc1a7c9e956 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A1bor=20Horv=C3=A1th?= Date: Sun, 27 Nov 2016 14:18:55 +0100 Subject: [PATCH 11/11] Enhance short option in StructureDescription Now the option short works for infinite abelian groups. Further, it now recognizes nonprimepower duplicates, as well. E.g. the short StructureDescription for the group C6 x C6 is now 6^2. --- lib/grpnames.gi | 50 +++++++++++++------ .../opers/StructureDescription.tst | 12 ++--- 2 files changed, 40 insertions(+), 22 deletions(-) diff --git a/lib/grpnames.gi b/lib/grpnames.gi index 44b9828760..36b804c4da 100644 --- a/lib/grpnames.gi +++ b/lib/grpnames.gi @@ -1613,8 +1613,10 @@ InstallMethod( StructureDescription, id, # id of G in the library of perfect groups short, # short / long output format nice, # nice output (slower) - i, # counter + i,j, # counters primes, # prime divisors of Size(G) + d, # divisor of Size(G) + k, # maximal power of d in Size(G) pi; # subset of primes insertsep := function ( strs, sep, brack ) @@ -1637,22 +1639,24 @@ InstallMethod( StructureDescription, return s; end; - cycsaspowers := function ( name ) + cycsaspowers := function ( name, cycsizes ) - local p, k, q; + local d, k, j, n; if not short then return name; fi; RemoveCharacters(name," "); - for q in Filtered(Reversed(DivisorsInt(Size(G))), - IsPrimePowerInt) - do - p := SmallestRootInt(q); k := LogInt(q,p); - if k > 1 then - name := ReplacedString(name,insertsep(List([1..k], - i->Concatenation("C",String(p))),"x",""), - Concatenation(String(p),"^",String(k))); - fi; - od; + cycsizes := Collected(cycsizes); + for n in cycsizes + do + d := n[1]; k := n[2]; + if k > 1 then + for j in Reversed([2..k]) do + name := ReplacedString(name,insertsep(List([1..j], + i->Concatenation("C",String(d))),"x",""), + Concatenation(String(d),"^",String(j))); + od; + fi; + od; RemoveCharacters(name,"C"); return name; end; @@ -1666,7 +1670,21 @@ InstallMethod( StructureDescription, i := IdGroup(G)[2]; if IsBound(NAMES_OF_SMALL_GROUPS[Size(G)][i]) then name := ShallowCopy(NAMES_OF_SMALL_GROUPS[Size(G)][i]); - return cycsaspowers(name); + cycsizes := []; + if short then + # DivisorsInt is rather slow, but we only call it for small groups + for d in Reversed(DivisorsInt(Size(G))) do + if d >1 then + k := LogInt(Size(G), d); + if k>1 then + for j in [1..k] do + Add(cycsizes, d); + od; + fi; + fi; + od; + fi; + return cycsaspowers(name, cycsizes); fi; fi; fi; @@ -1681,7 +1699,7 @@ InstallMethod( StructureDescription, cycsizes := Filtered(cycsizes,n->n<>1); return cycsaspowers(insertsep(List(cycsizes, n->Concatenation("C",String(n))), - " x ","")); + " x ",""), cycsizes); fi; if not IsFinite(G) then TryNextMethod(); fi; @@ -1771,7 +1789,7 @@ InstallMethod( StructureDescription, cycsizes := Filtered(cycsizes,n->n<>1); cycname := cycsaspowers(insertsep(List(cycsizes, n->Concatenation("C",String(n))), - " x ",":.")); + " x ",":."), cycsizes); else cycname := ""; fi; noncyclics := Difference(Gs,cyclics); noncycname := insertsep(List(noncyclics,StructureDescription), diff --git a/tst/testinstall/opers/StructureDescription.tst b/tst/testinstall/opers/StructureDescription.tst index e25acc706c..e9fc8c19ae 100644 --- a/tst/testinstall/opers/StructureDescription.tst +++ b/tst/testinstall/opers/StructureDescription.tst @@ -5,6 +5,10 @@ gap> List(l, StructureDescription);; l; 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> StructureDescription(SmallGroup(36, 14):short); +"6^2" +gap> StructureDescription(SmallGroup(216, 174):short,recompute); +"6^2xS3" 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", @@ -58,6 +62,8 @@ gap> List(AllSmallNonabelianSimpleGroups([1..1000000]), StructureDescription); "O(5,4)" ] gap> StructureDescription(AbelianGroup([0,0,0,2,3,4,5,6,7,8,9,10])); "C0 x C0 x C0 x C2520 x C60 x C6 x C2 x C2" +gap> StructureDescription(AbelianGroup([0,0,0,2,3,4,5,6,7,8,9,10]):short); +"0^3x2520x60x6x2^2" gap> infolevel:=InfoLevel(InfoWarning);; SetInfoLevel(InfoWarning,2); gap> StructureDescription(SmallGroup(48,16):recompute,nice); #I Warning! Non-unique semidirect product: @@ -68,10 +74,4 @@ gap> StructureDescription(SmallGroup(64,17):recompute,nice); #I [ [ "C4 x C2", "C8" ], [ "C8 x C2", "C4" ] ] "(C4 x C2) : C8" gap> SetInfoLevel(InfoWarning,infolevel); - -## -## Currently the value "short" does not work for infinite abelian groups. -## -##gap> StructureDescription(AbelianGroup([0,0,0,2,3,4,5,6,7,8,9,10]):short); -##"0^3x2520x60x6x2^2" gap> STOP_TEST("StructureDescription.tst", 10000);