datarec := ANUPQDataRecord(proc);
datarec.nwords := datarec.nwords + 1;
w := CallFuncList( r, instances ); if w <> w^0then # 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 = 0then
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 );
n := PqNrPcGenerators( proc );
class := PqWeight( proc, n ); if class > 1then while n > 0 and PqWeight( proc, n ) = class do n := n-1; od; fi;
if n = 0then 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;
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 );
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.