From 9c038e44e4d460267cb89d4c8ca2610a19d39745 Mon Sep 17 00:00:00 2001 From: Sergio Siccha Date: Tue, 22 Jun 2021 11:16:30 +0200 Subject: [PATCH 01/12] Improve RECOG_ViewObj --- gap/base/recognition.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gap/base/recognition.gi b/gap/base/recognition.gi index 5c4f6057e..50ca7d787 100644 --- a/gap/base/recognition.gi +++ b/gap/base/recognition.gi @@ -23,7 +23,7 @@ RECOG_ViewObj := function( level, ri ) if IsReady(ri) then Print(" Date: Tue, 22 Jun 2021 12:44:07 +0200 Subject: [PATCH 02/12] Some more factor -> image --- gap/base/recognition.gi | 9 +++++++-- tst/working/quick/bugfix.tst | 12 ++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/gap/base/recognition.gi b/gap/base/recognition.gi index 50ca7d787..f7a81c3f4 100644 --- a/gap/base/recognition.gi +++ b/gap/base/recognition.gi @@ -56,7 +56,7 @@ RECOG_ViewObj := function( level, ri ) Print(" Field=",Size(ri!.field)); fi; if not IsLeaf(ri) then - Print("\n",String("",level)," F:"); + Print("\n",String("",level)," I:"); if HasImageRecogNode(ri) then RECOG_ViewObj(level+3, ImageRecogNode(ri)); else @@ -530,13 +530,18 @@ InstallGlobalFunction( RecogniseGeneric, return fail; fi; - Add(depthString,'F'); + Add(depthString,'I'); rifac := RecogniseGeneric( Group(List(GeneratorsOfGroup(H), x->ImageElm(Homom(ri),x))), methodsforfactor(ri), depthString, forfactor(ri) ); # TODO: change forfactor to hintsForFactor??) Remove(depthString); +<<<<<<< HEAD PrintTreePos("F",depthString,H); SetImageRecogNode(ri,rifac); +======= + PrintTreePos("I",depthString,H); + SetRIFac(ri,rifac); +>>>>>>> 74ba82d... Some more factor -> image SetRIParent(rifac,ri); if IsMatrixGroup(H) then diff --git a/tst/working/quick/bugfix.tst b/tst/working/quick/bugfix.tst index bb03aa115..fcdc3f0b0 100644 --- a/tst/working/quick/bugfix.tst +++ b/tst/working/quick/bugfix.tst @@ -34,27 +34,27 @@ gap> old:=InfoLevel(InfoRecog);; gap> SetInfoLevel(InfoRecog, 0); gap> RecogniseGroup(SL(2,2)); K: gap> RecogniseGroup(SL(2,3)); K: + I: K:> gap> RecogniseGroup(SL(2,4)); K: gap> RecogniseGroup(SL(2,5)); K: + I: K:> gap> SetInfoLevel(InfoRecog, old); From 015331104eea5988d075faa1167fae787f56de65 Mon Sep 17 00:00:00 2001 From: Sergio Siccha Date: Sat, 19 Jun 2021 11:41:07 +0200 Subject: [PATCH 03/12] Turn CalcNiceGens(r,g) into NiceGens(r,g) That is install it as a method for `NiceGens` with two arguments. Also improves the documentation of `NiceGens`. --- doc/recognition.xml | 3 +-- gap/base/recognition.gd | 41 +++++++++++++---------------------- gap/base/recognition.gi | 28 ++++++++++-------------- gap/generic/KnownNilpotent.gi | 4 ++-- misc/colva/DPleaf.g | 2 +- misc/colva/Evaluate.g | 2 +- 6 files changed, 32 insertions(+), 48 deletions(-) diff --git a/doc/recognition.xml b/doc/recognition.xml index 92060023e..c7832939e 100644 --- a/doc/recognition.xml +++ b/doc/recognition.xml @@ -264,7 +264,7 @@ returns true. -The following two attributes are concerned with the relation between +The following four attributes are concerned with the relation between the original generators and the nice generators for a node. They are used to transport this information from a successful find homomorphism method up to the recursive recognition function: @@ -272,7 +272,6 @@ homomorphism method up to the recursive recognition function: <#Include Label="calcnicegens"> <#Include Label="CalcNiceGensGeneric"> <#Include Label="CalcNiceGensHomNode"> -<#Include Label="CalcNiceGens"> <#Include Label="slptonice"> The following three attributes are concerned with the administration of the diff --git a/gap/base/recognition.gd b/gap/base/recognition.gd index cf463517b..0adc13045 100644 --- a/gap/base/recognition.gd +++ b/gap/base/recognition.gd @@ -99,23 +99,24 @@ DeclareAttribute( "Homom", IsRecogNode, "mutable" ); ## <#GAPDoc Label="NiceGens"> ## ## +## ## -## The value of this attribute must be set for all nodes and contains -## the nice generators. The function of the +## The value of this attribute contains the nice generators and must be set +## for all nodes. The function of the ## node will write its straight line program in terms of these nice -## generators. For leaf nodes, the find homomorphism method is responsible -## to set the value of . By default, the original -## generators of the group at this node are taken. For a homomorphism -## (or isomorphism), the will be the concatenation -## of preimages of the of the image group +## generators. +##

+## For a leaf node, can be any list of generators. +##

+## For a splitting node, is the concatenation +## of preimages of the of the factor group ## (see ) and -## the of the kernel. A find homomorphism method -## does not have to set if it finds a homomorphism. -## Note however, that such a find homomorphism method has to ensure somehow, -## that preimages of the of the image group -## can be acquired. See , -## and -## for instructions. +## the of the kernel. +##

+## To compute the nice generators, a method with two-arguments is installed +## for which takes the value of the attribute +## and calls it with the arguments ri and +## origgens. For more information see . ## ## ## <#/GAPDoc> @@ -547,18 +548,6 @@ DeclareGlobalFunction( "TryFindHomMethod" ); # Helper functions for the generic part: -## <#GAPDoc Label="CalcNiceGens"> -## -## -## a list of preimages of the nice generators -## -## This is a wrapper function which extracts the value of the attribute -## and calls that function with the arguments -## ri and origgens. -## -## -## <#/GAPDoc> -DeclareGlobalFunction( "CalcNiceGens" ); DeclareGlobalFunction( "ValidateHomomInput" ); ## <#GAPDoc Label="CalcNiceGensGeneric"> diff --git a/gap/base/recognition.gi b/gap/base/recognition.gi index f7a81c3f4..9faf02d7e 100644 --- a/gap/base/recognition.gi +++ b/gap/base/recognition.gi @@ -81,6 +81,12 @@ InstallMethod( ViewObj, "for recognition nodes", [IsRecogNode], RECOG_ViewObj(0, ri); end); +InstallOtherMethod( NiceGens, "for a recognition node and a list", +[IsRecogNode, IsList], + function(ri,origgens) + return calcnicegens(ri)(ri,origgens); + end ); + ############################################################################# # The main recursive function: @@ -535,13 +541,8 @@ InstallGlobalFunction( RecogniseGeneric, Group(List(GeneratorsOfGroup(H), x->ImageElm(Homom(ri),x))), methodsforfactor(ri), depthString, forfactor(ri) ); # TODO: change forfactor to hintsForFactor??) Remove(depthString); -<<<<<<< HEAD - PrintTreePos("F",depthString,H); - SetImageRecogNode(ri,rifac); -======= PrintTreePos("I",depthString,H); - SetRIFac(ri,rifac); ->>>>>>> 74ba82d... Some more factor -> image + SetImageRecogNode(ri,rifac); SetRIParent(rifac,ri); if IsMatrixGroup(H) then @@ -560,7 +561,7 @@ InstallGlobalFunction( RecogniseGeneric, # Now we want to have preimages of the new generators in the image: Info(InfoRecog,2,"Calculating preimages of nice generators."); - ri!.pregensfacwithmem := CalcNiceGens(rifac, ri!.gensHmem); + ri!.pregensfacwithmem := NiceGens(rifac, ri!.gensHmem); Setpregensfac(ri, StripMemory(ri!.pregensfacwithmem)); # Now create the kernel generators with the stored method: @@ -683,11 +684,6 @@ InstallGlobalFunction( ValidateHomomInput, fi; end ); -InstallGlobalFunction( CalcNiceGens, - function(ri,origgens) - return calcnicegens(ri)(ri,origgens); - end ); - InstallGlobalFunction( CalcNiceGensGeneric, # generic function using an slp: function(ri,origgens) @@ -703,14 +699,14 @@ InstallGlobalFunction( CalcNiceGensHomNode, function(ri, origgens) local nicegens, kernelgens; # compute preimages of the nicegens of the image group - nicegens := CalcNiceGens(ImageRecogNode(ri), origgens); + nicegens := NiceGens(ImageRecogNode(ri), origgens); # Is there a non-trivial kernel? then add its nicegens if HasKernelRecogNode(ri) and KernelRecogNode(ri) <> fail then # we cannot just use gensN(KernelRecogNode(ri)) here, as those values are defined # relative to the original generators we used during recognition; but # the origgens passed to this function might differ kernelgens := ResultOfStraightLineProgram(gensNslp(ri), origgens); - Append(nicegens, CalcNiceGens(KernelRecogNode(ri), kernelgens)); + Append(nicegens, NiceGens(KernelRecogNode(ri), kernelgens)); fi; return nicegens; end ); @@ -863,7 +859,7 @@ InstallGlobalFunction( "SLPforNiceGens", function(ri) local l,ll,s; l := List( [1..Length(GeneratorsOfGroup(Grp(ri)))], x->() ); l := GeneratorsWithMemory(l); - ll := CalcNiceGens(ri,l); + ll := NiceGens(ri,l); s := SLPOfElms(ll); if s <> fail then SlotUsagePattern(s); @@ -960,7 +956,7 @@ RECOG.TestGroup := function(g,proj,size, optionlist...) if IsEmpty(gens) then gens := [One(g)]; fi; - l := CalcNiceGens(ri,gens); + l := NiceGens(ri,gens); repeat count := count + 1; #Print(".\c"); diff --git a/gap/generic/KnownNilpotent.gi b/gap/generic/KnownNilpotent.gi index a4525459f..88923560e 100644 --- a/gap/generic/KnownNilpotent.gi +++ b/gap/generic/KnownNilpotent.gi @@ -66,8 +66,8 @@ RECOG.CalcNiceGensKnownNilpotent := function(ri,origgens) local kernelgens; kernelgens := List([1..Length(ri!.decompositionExponents)], i -> origgens[i]^ri!.decompositionExponents[i]); - return Concatenation(CalcNiceGens(ImageRecogNode(ri), origgens), - CalcNiceGens(KernelRecogNode(ri), kernelgens)); + return Concatenation(NiceGens(ImageRecogNode(ri), origgens), + NiceGens(KernelRecogNode(ri), kernelgens)); end; #! @BeginChunk KnownNilpotent diff --git a/misc/colva/DPleaf.g b/misc/colva/DPleaf.g index 8d00a8fe5..7ebe6f06e 100644 --- a/misc/colva/DPleaf.g +++ b/misc/colva/DPleaf.g @@ -320,7 +320,7 @@ SolveLeafDP := function(ri,rifac,name) blkdata := RecogniseLeaf(riH1,blk,name);; # Get the inverse images of the nice generators of blk in H1 - invims := CalcNiceGens(blkdata,GeneratorsOfGroup(H1)); + invims := NiceGens(blkdata,GeneratorsOfGroup(H1)); Yhat := ShallowCopy(invims); blktoH1 := GroupHomomorphismByFunction(blk,Grp(ri),g-> ResultOfStraightLineProgram( SLPforElement(blkdata,g),invims)); diff --git a/misc/colva/Evaluate.g b/misc/colva/Evaluate.g index 967275608..5eebdaf22 100644 --- a/misc/colva/Evaluate.g +++ b/misc/colva/Evaluate.g @@ -242,7 +242,7 @@ InstallGlobalFunction( NormalTree, # Now we want to have preimages of the new generators in the image: if not IsBound(ri!.pregensfac) then Info(InfoRecognition,1,"Calculating preimages of nice generators."); - Setpregensfac( ri, CalcNiceGens(rifac,GeneratorsOfGroup(H))); + Setpregensfac( ri, NiceGens(rifac,GeneratorsOfGroup(H))); fi; Setcalcnicegens(ri,CalcNiceGensHomNode); From c44afadf6dc37c7db8b40bb159f4a525b8d11b15 Mon Sep 17 00:00:00 2001 From: Sergio Siccha Date: Sat, 19 Jun 2021 12:17:05 +0200 Subject: [PATCH 04/12] WIP Remove a line duplicating CalcNiceGensHomNode --- gap/base/recognition.gi | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/gap/base/recognition.gi b/gap/base/recognition.gi index 9faf02d7e..200eaed34 100644 --- a/gap/base/recognition.gi +++ b/gap/base/recognition.gi @@ -660,14 +660,8 @@ InstallGlobalFunction( RecogniseGeneric, fi; until done; - if IsReady(riker) then # we are only ready when the kernel is - # Now make the two projection slps: - SetNiceGens(ri,Concatenation(pregensfac(ri), NiceGens(riker))); - #ll := List([1..Length(NiceGens(rifac))],i->[i,1]); - #ri!.proj1 := StraightLineProgramNC([ll],Length(NiceGens(ri))); - #ll := List([1..Length(NiceGens(riker))], - # i->[i+Length(NiceGens(rifac)),1]); - #ri!.proj2 := StraightLineProgramNC([ll],Length(NiceGens(ri))); + # we are only ready when the kernel is + if IsReady(riker) then SetFilterObj(ri,IsReady); fi; if InfoLevel(InfoRecog) = 1 and depth = 0 then Print("\n"); fi; From 58ac8351eb0966b587927ee9f1b719cf5e09a85f Mon Sep 17 00:00:00 2001 From: Sergio Siccha Date: Sat, 19 Jun 2021 10:16:13 +0200 Subject: [PATCH 05/12] WIP Improve documentation of calcnicegens --- gap/base/recognition.gd | 39 ++++++++++++++++++++++++--------------- 1 file changed, 24 insertions(+), 15 deletions(-) diff --git a/gap/base/recognition.gd b/gap/base/recognition.gd index 0adc13045..1c1fb30c9 100644 --- a/gap/base/recognition.gd +++ b/gap/base/recognition.gd @@ -203,21 +203,30 @@ DeclareAttribute( "validatehomominput", IsRecogNode); ## ## ## -## To make the recursion work, we have to acquire preimages of the -## nice generators in image groups under the homomorphism found. -## But we want to keep the information, how the nice generators -## were found, locally at the node where they were found. This -## attribute solves this problem of acquiring preimages in the following -## way: Its value must be a function, taking the recognition -## node ri as first argument, and a list origgens of -## preimages of the -## original generators of the current node, and has to -## return corresponding preimages of the nice generators. Usually this -## task can be done by storing a straight line program writing the -## nice generators in terms of the original generators and executing -## this with inputs origgens. Therefore the default value of -## this attribute is the function -## described below. +## Stores a function func(ri2, gens2) which computes group elements +## of ri2 by evaluating words in gens2. +## These words must be chosen such that, if ri2 is equal to +## ri and gens2 is equal to +## GeneratorsOfGroup(Grp(ri)), then func returns the nice +## generators of ri. +## Correspondingly, if gens2 is another list of group elements, then +## the words which yield the nice generators of ri are evaluated in +## gens2. +##

+## This us used by the recursive group recognition to compute preimages of +## nice generators as follows: +## if imagenode is the image node of a node node and +## nodegens are the generators of Grp(node), +## then func(imagenode, nodegens) computes the preimages of the +## nice generators of imagenode. +##

+## Usually func stores a straight line program writing the nice +## generators in terms of the generators of the group represented +## by ri and executes this with inputs gens2. +##

+## The default values of this attribute are the functions +## and +## . ## ## ## <#/GAPDoc> From 191e45852cb45100ee644011509595b0bac78c2f Mon Sep 17 00:00:00 2001 From: Sergio Siccha Date: Mon, 21 Jun 2021 15:38:41 +0200 Subject: [PATCH 06/12] WIP Improve CalcNiceGensHomNode --- gap/base/recognition.gi | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/gap/base/recognition.gi b/gap/base/recognition.gi index 200eaed34..25d89b309 100644 --- a/gap/base/recognition.gi +++ b/gap/base/recognition.gi @@ -699,8 +699,15 @@ InstallGlobalFunction( CalcNiceGensHomNode, # we cannot just use gensN(KernelRecogNode(ri)) here, as those values are defined # relative to the original generators we used during recognition; but # the origgens passed to this function might differ - kernelgens := ResultOfStraightLineProgram(gensNslp(ri), origgens); - Append(nicegens, NiceGens(KernelRecogNode(ri), kernelgens)); + if origgens = GeneratorsOfGroup(Grp(ri)) then + Print("HIT\n"); + Error("break"); + nicekernelgens := NiceGens(KernelRecogNode(ri)); + else + kernelgens := ResultOfStraightLineProgram(gensNslp(ri), origgens); + nicekernelgens := NiceGens(KernelRecogNode(ri), kernelgens); + fi; + Append(nicegens, nicekernelgens); fi; return nicegens; end ); From f0516616793a7c8662ea13360890e09025f348ab Mon Sep 17 00:00:00 2001 From: Sergio Siccha Date: Wed, 23 Jun 2021 08:57:49 +0200 Subject: [PATCH 07/12] Remove outdated comment CalcNiceGensGeneric is the method for leaf nodes. So that it doesn't make sense to set this for every node by default. Maybe it once had a different function? --- gap/base/recognition.gi | 1 - 1 file changed, 1 deletion(-) diff --git a/gap/base/recognition.gi b/gap/base/recognition.gi index 25d89b309..f4254b381 100644 --- a/gap/base/recognition.gi +++ b/gap/base/recognition.gi @@ -452,7 +452,6 @@ InstallGlobalFunction( RecogniseGeneric, else ri := EmptyRecognitionInfoRecord(knowledge,H,false); fi; - # was here earlier: Setcalcnicegens(ri,CalcNiceGensGeneric); Setmethodsforfactor(ri,methoddb); # Find a possible homomorphism (or recognise this group as leaf) From 29aa19b736b306cec54b04d4df1af13854fec5c8 Mon Sep 17 00:00:00 2001 From: Sergio Siccha Date: Wed, 23 Jun 2021 09:26:39 +0200 Subject: [PATCH 08/12] Remove TODO Will be handled during the renaming project. --- gap/base/recognition.gi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gap/base/recognition.gi b/gap/base/recognition.gi index f4254b381..7645b6783 100644 --- a/gap/base/recognition.gi +++ b/gap/base/recognition.gi @@ -538,7 +538,7 @@ InstallGlobalFunction( RecogniseGeneric, Add(depthString,'I'); rifac := RecogniseGeneric( Group(List(GeneratorsOfGroup(H), x->ImageElm(Homom(ri),x))), - methodsforfactor(ri), depthString, forfactor(ri) ); # TODO: change forfactor to hintsForFactor??) + methodsforfactor(ri), depthString, forfactor(ri) ); Remove(depthString); PrintTreePos("I",depthString,H); SetImageRecogNode(ri,rifac); From 42c7821a013f88fb9f924ef89151eb537f0c5674 Mon Sep 17 00:00:00 2001 From: Sergio Siccha Date: Wed, 23 Jun 2021 11:46:05 +0200 Subject: [PATCH 09/12] Add README.md to misc/colva --- misc/colva/README.md | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 misc/colva/README.md diff --git a/misc/colva/README.md b/misc/colva/README.md new file mode 100644 index 000000000..a694782a2 --- /dev/null +++ b/misc/colva/README.md @@ -0,0 +1,4 @@ +This is probably an attempt by Colva Roney-Dougal to port an implementation of +Mark Stather (a PhD Student of Derek Holt) for computing sylow subgroups of +matrix groups. That may have needed "normal trees" and chief series. The main +file might be `NSM.g`? From 83701ab061d9fb10edfbe1b73575c5424a4c286d Mon Sep 17 00:00:00 2001 From: Sergio Siccha Date: Wed, 23 Jun 2021 11:57:42 +0200 Subject: [PATCH 10/12] WIP --- gap/base/recognition.gi | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/gap/base/recognition.gi b/gap/base/recognition.gi index 7645b6783..5a8c15e70 100644 --- a/gap/base/recognition.gi +++ b/gap/base/recognition.gi @@ -81,6 +81,12 @@ InstallMethod( ViewObj, "for recognition nodes", [IsRecogNode], RECOG_ViewObj(0, ri); end); +InstallMethod( NiceGens, "for a recognition node", +[IsRecogNode], + function(ri) + return NiceGens(ri, GeneratorsOfGroup(Grp(ri))); + end ); + InstallOtherMethod( NiceGens, "for a recognition node and a list", [IsRecogNode, IsList], function(ri,origgens) @@ -690,7 +696,7 @@ InstallGlobalFunction( CalcNiceGensGeneric, InstallGlobalFunction( CalcNiceGensHomNode, # function for the situation on a homomorphism node (non-Leaf): function(ri, origgens) - local nicegens, kernelgens; + local nicegens, nicekernelgens, x, kernelgens; # compute preimages of the nicegens of the image group nicegens := NiceGens(ImageRecogNode(ri), origgens); # Is there a non-trivial kernel? then add its nicegens @@ -699,10 +705,19 @@ InstallGlobalFunction( CalcNiceGensHomNode, # relative to the original generators we used during recognition; but # the origgens passed to this function might differ if origgens = GeneratorsOfGroup(Grp(ri)) then - Print("HIT\n"); - Error("break"); + # Print("HIT\n"); + #Error("break"); nicekernelgens := NiceGens(KernelRecogNode(ri)); + if IsObjWithMemory(origgens[1]) then + nicekernelgens := GeneratorsWithMemory(nicekernelgens); + # HACK! + for x in nicekernelgens do + x!.slp := origgens[1]!.slp; + od; + fi; else + # when recognizing, origgens have memory. When recognition is finished, + # these are usually without memory? kernelgens := ResultOfStraightLineProgram(gensNslp(ri), origgens); nicekernelgens := NiceGens(KernelRecogNode(ri), kernelgens); fi; From 7e2e91fd736483c37d53f58518b3b35ba5aec180 Mon Sep 17 00:00:00 2001 From: Sergio Siccha Date: Wed, 23 Jun 2021 12:36:57 +0200 Subject: [PATCH 11/12] WIP --- gap/base/recognition.gi | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gap/base/recognition.gi b/gap/base/recognition.gi index 5a8c15e70..1045a9bf8 100644 --- a/gap/base/recognition.gi +++ b/gap/base/recognition.gi @@ -972,6 +972,8 @@ RECOG.TestGroup := function(g,proj,size, optionlist...) gens := [One(g)]; fi; l := NiceGens(ri,gens); + l := NiceGens(ri,gens); + # Test whether SLPForNiceGens gives the same slps repeat count := count + 1; #Print(".\c"); From c125c8cb4fa91f9994ca84bfaef97dc8cceb23aa Mon Sep 17 00:00:00 2001 From: Sergio Siccha Date: Wed, 23 Jun 2021 12:37:44 +0200 Subject: [PATCH 12/12] add a PLAN.md --- PLAN.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 PLAN.md diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 000000000..beabcbd20 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,6 @@ +CachedSLPToNiceGenerators +Completely independent implementation. Computes an SLP and maybe also the +nicegens, then stores it. Then, whenever someone needs another +SLPToNiceGenerators, this can be taken and evaluated. +Wherever this is called, assert that this and `CalcNiceGens` return the same +group elements, maybe even SLPs with equal `LinesOfSLP`.