Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346############################################################################# #### ## #W anupqid.gi ANUPQ package Werner Nickel #W Greg Gamble ## ## This file installs functions to do with evaluating identities. ## #Y Copyright (C) 2001 Lehrstuhl D fuer Mathematik, RWTH Aachen, Germany ## ############################################################################# ## #F PqEvalSingleRelation( <proc>, <r>, <instances> ) ## InstallGlobalFunction( PqEvalSingleRelation, function( proc, r, instances ) local w, datarec; # Print( instances, "\n" ); datarec := ANUPQDataRecord(proc); datarec.nwords := datarec.nwords + 1; w := CallFuncList( r, instances ); if w <> w^0 then # Print( w ); # Print( "\n" ); # PqSetOutputLevel( proc, 3 ); PqCollect( proc, String(w) ); PqEchelonise( proc ); # PqSetOutputLevel( proc, 0 ); fi; end ); ############################################################################# ## #F PqEnumerateWords( <proc>, <data>, <r> ) ## ## The parameters of PqEnumerateWords() have the following meaning: ## ## <r> a relation involving identical generators. ## <instances> the list of instances to be built up corresponding the ## identical generators. ## <n> the index of the current word in <instances> ## <g> the next generator in the current word ## <wt> the weight that can be spent on the next generators. ## InstallGlobalFunction( PqEnumerateWords, function( proc, data, r ) local n, g, wt, u, save_wt, save_u, save_g; n := data.currentinst; g := data.currentgen; wt := data.weightleft; u := data.instances[ n ]; save_wt := wt; save_u := u; save_g := g; if wt = 0 then PqEvalSingleRelation( proc, r, data.instances ); Info( InfoANUPQ, 3, "Instance: ", data.instances[ n ] ); return; fi; if g > Length( data.pcgens ) then return; fi; while g <= data.nrpcgens and data.pcweights[g] <= wt do while data.pcweights[g] <= wt do u := u * data.pcgens[g]; wt := wt - data.pcweights[g]; data.instances[ n ] := u; data.weightleft := wt; data.currentgen := g+1; PqEnumerateWords( proc, data, r ); if n < Length(data.instances) then data.currentinst := n+1; data.currentgen := 1; PqEnumerateWords( proc, data, r ); data.currentinst := n; fi; od; u := save_u; wt := save_wt; g := g+1; od; data.instances[ n ] := save_u; data.weightleft := save_wt; data.currentgen := save_g; end ); ############################################################################# ## #F PqEvaluateIdentity( <proc>, <r>, <arity> ) ## InstallGlobalFunction( PqEvaluateIdentity, function( proc, r, arity ) local n, class, gens, data, c; n := PqNrPcGenerators( proc ); class := PqWeight( proc, n ); if class > 1 then while n > 0 and PqWeight( proc, n ) = class do n := n-1; od; fi; if n = 0 then return; fi; gens := GeneratorsOfGroup( FreeGroup( n, "x" ) ); data := rec( instances := List( [1..arity], i->gens[1]^0 ), currentinst := 1, currentgen := 1, weightleft := 0, pcgens := gens, nrpcgens := n, pcweights := List( [1..n], i->PqWeight( proc, i ) ) ); for c in [1..class] do # Print( "words of class ", c, "\n" ); data.weightleft := c; PqEnumerateWords( proc, data, r ); od; end ); ############################################################################# ## #F PqWithIdentity( <G>, <p>, <Cl>, <identity> ) ## ## constructs a <p>-quotient <Q> of the fp or pc group <G> of class at most ## <Cl> that satisfies $<identity>(<w1>, \dots, <wn>) = 1$ for all words ## $<w1>, \dots, <wn>$ in the pc generators of <Q>. The following examples ## demonstrate its usage. ## ## \beginexample ### gap> F := FreeGroup(2); ## <free group on the generators [ f1, f2 ]> ## gap> f := w -> w^4; ## function( w ) ... end ## gap> PqWithIdentity( F, 2, 20, f ); ## #I Evaluated 5 instances. ## #I Class 2 with 5 generators. ## #I Evaluated 18 instances. ## #I Class 3 with 7 generators. ## #I Evaluated 44 instances. ## #I Class 4 with 10 generators. ## #I Evaluated 95 instances. ## #I Class 5 with 12 generators. ## #I Evaluated 192 instances. ## #I Class 6 with 12 generators. ## <pc group of size 4096 with 12 generators> ## gap> ## gap> G := F/[ F.1^11, F.2^11 ]; ## <fp group on the generators [ f1, f2 ]> ## gap> f := function(u, v) return PqLeftNormComm( [u, v, v, v] ); end; ## function( u, v ) ... end ## gap> H := PqWithIdentity( G, 11, 20, f ); ## #I Evaluated 14 instances. ## #I Class 2 with 3 generators. ## #I Evaluated 44 instances. ## #I Class 3 with 5 generators. ## #I Evaluated 122 instances. ## #I Class 4 with 5 generators. ## <pc group of size 161051 with 5 generators> ## gap> f( Random(H), Random(H) ); ## <identity> of ... ## gap> f( H.1, H.2 ); ## <identity> of ... ## \endexample ## ## Compare the above examples with those generated by: ## `PqExample("B2-4-Id");' and `PqExample("11gp-3-Engel-Id");' which do the ## same as above using the function `Pq' with the `Identities' option. ## ## `PqWithIdentity' and the functions it calls, with minor modifications, ## constitute the prototype provided by Werner Nickel, for constructing a ## quotient that satisfies an identity. The prototype functions have been ## merged into the single function `PQ_EVALUATE_IDENTITY' which is called by ## `PQ_EVALUATE_IDENTITIES' which in turn is called by ## `PQ_FINISH_NEXT_CLASS' which is called by `PQ_NEXT_CLASS' and ## `PQ_EPI_OR_PCOVER', if the `Identities' option has been set. ## `PQ_EPI_OR_PCOVER' is the function called by `Pq', `PqEpimorphism' or ## `PqPCover'. ## InstallGlobalFunction( PqWithIdentity, function( G, p, Cl, identity ) local proc, datarec, prev_n, class, grp, arity; arity := NumberArgumentsFunction( identity ); proc := PqStart( G : Prime := p ); datarec := ANUPQData.io[ proc ]; datarec.nwords := 0; prev_n := 0; Pq( proc : ClassBound := 1 ); class := 1; PqEvaluateIdentity( proc, identity, arity ); PqEliminateRedundantGenerators( proc ); if PqNrPcGenerators( proc ) = 0 then return TrivialGroup( IsPcGroup ); fi; while class < Cl and prev_n <> PqNrPcGenerators( proc ) do prev_n := PqNrPcGenerators( proc ); PqSetupTablesForNextClass( proc ); PqTails( proc, 0 ); PqDoConsistencyChecks( proc, 0, 0 ); PqCollectDefiningRelations( proc ); PqDoExponentChecks( proc ); datarec.nwords := 0; PqEvaluateIdentity( proc, identity, arity ); Info(InfoANUPQ, 2, "Evaluated ", datarec.nwords, " instances." ); PqEliminateRedundantGenerators( proc ); class := class + 1; Info(InfoANUPQ, 1, "Class ", class, " with ", PqNrPcGenerators(proc), " generators." ); od; grp := PqCurrentGroup( proc ); PqQuit( proc ); return grp; end ); ############################################################################# ## #F PQ_EVALUATE_IDENTITY( <proc>, <identity> ) ## InstallGlobalFunction( PQ_EVALUATE_IDENTITY, function( proc, identity ) local EnumerateWords, data, datarec, nwords, arity, c; EnumerateWords := function() local i, g, wt, u, w, save_wt, save_u, save_g; i := data.currentinst; g := data.currentgen; wt := data.weightleft; u := data.instances[ i ]; save_wt := wt; save_u := u; save_g := g; if wt = 0 then #evaluate a single relation nwords := nwords + 1; w := CallFuncList( identity, data.instances ); if w <> w^0 then # Print( w ); # Print( "\n" ); # PqSetOutputLevel( proc, 3 ); PqCollect( proc, String(w) ); PqEchelonise( proc ); # PqSetOutputLevel( proc, 0 ); fi; Info( InfoANUPQ, 3, "Instance: ", data.instances[ i ] ); return; fi; while g <= data.nrpcgens and data.pcweights[g] <= wt do while data.pcweights[g] <= wt do u := u * data.pcgens[g]; wt := wt - data.pcweights[g]; data.instances[ i ] := u; data.weightleft := wt; data.currentgen := g+1; EnumerateWords(); if i < Length(data.instances) then data.currentinst := i+1; data.currentgen := 1; EnumerateWords(); data.currentinst := i; fi; od; u := save_u; wt := save_wt; g := g+1; od; data.instances[ i ] := save_u; data.weightleft := save_wt; data.currentgen := save_g; end; data := rec( nrpcgens := PqNrPcGenerators( proc ) ); if data.nrpcgens = 0 then return; fi; datarec := ANUPQDataRecord( proc ); if datarec.class > 1 then data.nrpcgens := datarec.ngens[ Length(datarec.ngens) - 1 ]; fi; nwords := 0; arity := NumberArgumentsFunction(identity); data.pcgens := GeneratorsOfGroup( FreeGroup( data.nrpcgens, "x" ) ); data.instances := List( [1 .. arity], i -> data.pcgens[1]^0 ); data.currentinst := 1; data.currentgen := 1; data.pcweights := List( [1 .. data.nrpcgens], i -> PqWeight( proc, i ) ); for c in [1 .. datarec.class] do # Print( "words of class ", c, "\n" ); data.weightleft := c; EnumerateWords(); od; Info(InfoANUPQ, 2, "Evaluated ", nwords, " instances." ); end ); #E anupqid.gi . . . . . . . . . . . . . . . . . . . . . . . . . . ends here