1############################################################################# 2## 3## This file is part of GAP, a system for computational discrete algebra. 4## This file's authors include Alexander Hulpke. 5## 6## Copyright of GAP belongs to its developers, whose names are too numerous 7## to list here. Please refer to the COPYRIGHT file for details. 8## 9## SPDX-License-Identifier: GPL-2.0-or-later 10## 11## This file contains functions that deal with action on chief factors or 12## composition factors and the representation of such groups in a nice way 13## as permutation groups. 14## 15 16InstallMethod( FittingFreeLiftSetup, "permutation", true, [ IsPermGroup ],0, 17function( G ) 18local pcgs,r,hom,A,iso,p,i,depths,ords,b,mo,pc,limit,good,new,start,np; 19 20 r:=RadicalGroup(G); 21 if Size(r)=1 then 22 hom:=IdentityMapping(G); 23 else 24 hom:=NaturalHomomorphismByNormalSubgroup(G,r); 25 fi; 26 27 A:=Image(hom); 28 if IsPermGroup(A) and NrMovedPoints(A)/Size(A)*Size(Socle(A)) 29 >SufficientlySmallDegreeSimpleGroupOrder(Size(A)) then 30 A:=SmallerDegreePermutationRepresentation(A:cheap); 31 Info(InfoGroup,3,"Radical factor degree reduced ",NrMovedPoints(Image(hom)), 32 " -> ",NrMovedPoints(Image(A))); 33 hom:=hom*A; 34 fi; 35 36 pcgs := TryPcgsPermGroup( G,r, false, false, true ); 37 if not IsPcgs( pcgs ) then 38 return fail; 39 fi; 40 41 # do we have huge steps? Refine. 42 limit:=10^5; 43 depths:=IndicesEANormalSteps(pcgs); 44 ords:=RelativeOrders(pcgs); 45 46 # can we simply use the existing Pcgs? 47 A:=List([2..Length(depths)],x->Product(ords{[depths[x-1]..depths[x]-1]})); 48 good:=true; 49 while Length(A)>0 and Maximum(A)>limit and good do 50 A:=depths[Position(A,Maximum(A))]; 51 p:=Filtered([A+1..Length(pcgs)],x->IsNormal(G,SubgroupNC(G,pcgs{[x..Length(pcgs)]}))); 52 # maximal split in middle 53 if Length(p)>0 then 54 i:=List(p,x->[(x-A)*(18-x),x]); 55 Sort(i); 56 p:=i[Length(i)][2]; # best split 57 if not p in depths then 58 depths:=Concatenation(Filtered(depths,x->x<=A),[p], 59 Filtered(depths,x->x>A)); 60 else 61 good:=false; 62 fi; 63 else 64 good:=false; 65 fi; 66 A:=List([2..Length(depths)],x->Product(ords{[depths[x-1]..depths[x]-1]})); 67 od; 68 69 # still bad? 70 good:=true; 71 if Length(A)>0 and Maximum(A)>limit and good then 72 A:=depths[Position(A,Maximum(A))]; 73 p:=ords[A]; 74 A:=[A..depths[Position(depths,A)+1]-1]; 75 pc:=InducedPcgsByPcSequence(pcgs,pcgs{[A[1]..Length(pcgs)]}) mod 76 InducedPcgsByPcSequence(pcgs,pcgs{[A[Length(A)]+1..Length(pcgs)]}); 77 mo:=LinearActionLayer(G,pc); 78 mo:=GModuleByMats(mo,GF(p)); 79 b:=MTX.BasesCompositionSeries(mo); 80 if Length(b)>2 then 81 new:=[1]; 82 start:=1; 83 for i in [2..Length(b)] do 84 if p^Length(b[i])/start>limit then 85 if i-1 in new then 86 Add(new,i); 87 start:=p^Length(b[i]); 88 else 89 Add(new,i-1); 90 start:=p^Length(b[i-1]); 91 fi; 92 fi; 93 od; 94 if not Length(b) in new then 95 Add(new,Length(b)); 96 fi; 97 98 # now form pc elements 99 np:=[]; 100 for i in [2..Length(new)] do 101 start:=BaseSteinitzVectors(b[new[i]],b[new[i-1]]).factorspace; 102 start:=List(start,x->PcElementByExponents(pc,List(x,Int))); 103 Add(np,start); 104 od; 105 np:=Reversed(np); 106 b:=A[1]; 107 pc:=Concatenation(pcgs{[1..b-1]}, 108 Concatenation(np), 109 pcgs{[A[Length(A)]+1..Length(pcgs)]}); 110 111 pcgs:=PermgroupSuggestPcgs(G,pc); 112 #depths:=Concatenation(Filtered(depths,x->x<=b), 113# List([1..Length(np)-1],x->b+Sum(List(np{[1..x]},Length))), 114# Filtered(depths,x->x>A[Length(A)])); 115 depths:=IndicesEANormalSteps(pcgs); 116 ords:=RelativeOrders(pcgs); 117 else 118 good:=false; 119 fi; 120 A:=List([2..Length(depths)],x->Product(ords{[depths[x-1]..depths[x]-1]})); 121 fi; 122 123 if not HasPcgsElementaryAbelianSeries(r) then 124 SetPcgsElementaryAbelianSeries(r,pcgs); 125 fi; 126 127 A:=CreateIsomorphicPcGroup(pcgs,true,false); 128 129 iso := GroupHomomorphismByImagesNC( r, A, pcgs, GeneratorsOfGroup( A )); 130 SetIsBijective( iso, true ); 131 return rec(pcgs:=pcgs, 132 depths:=depths, 133 radical:=r, 134 pcisom:=iso, 135 factorhom:=hom); 136 137end ); 138 139 140#testfunction for AutomorphismRepresentingGroup 141#test:=function(start) 142#local it,g,a,r; 143# it:=SimpleGroupsIterator(start:NOPSL2); 144# repeat 145# g:=NextIterator(it); 146# Print("@ Trying ",g," ",Size(g),"\n"); 147# a:=AutomorphismGroup(g); 148# r:=AutomorphismRepresentingGroup(g,GeneratorsOfGroup(a)); 149# Print("@ Got ",NrMovedPoints(r[1])," from ",NrMovedPoints(g),"\n"); 150# until false; 151#end; 152InstallGlobalFunction(AutomorphismRepresentingGroup,function(G,autos) 153local G0,a0,tryrep,sel,selin,a,s,dom,iso,stabs,outs,map,i,j,p,found,seln, 154 sub,d; 155 156 tryrep:=function(rep,bound) 157 local Gi,repi,maps,v,w,cen,hom; 158 Gi:=Image(rep,G); 159 if not IsSubset(MovedPoints(Gi),[1..LargestMovedPoint(Gi)]) then 160 rep:=rep*ActionHomomorphism(Gi,MovedPoints(Gi),"surjective"); 161 Gi:=Image(rep,G); 162 fi; 163 Info(InfoGroup,2,"Trying degree ",NrMovedPoints(Gi)); 164 maps:=List(sel,x->InducedAutomorphism(rep,autos[x])); 165 #for v in maps do SetIsBijective(v,true); od; 166 if ForAll(maps,x->IsConjugatorAutomorphism(x:cheap)) then 167 # the representation extends 168 v:=List( maps, ConjugatorOfConjugatorIsomorphism ); 169 w:=ClosureGroup(Gi,v); 170 Info(InfoGroup,1,"all conjugator degree ",NrMovedPoints(w)); 171 172 maps:=[]; 173 maps{sel}:=v; 174 maps{selin}:=List(selin,x-> 175 Image(rep, 176 ConjugatorOfConjugatorIsomorphism(autos[x]))); 177 178 cen:=Centralizer(w,Gi); 179 if Size(cen)=1 then 180 return [w,rep,maps]; 181 else 182 Info(InfoGroup,2,"but centre"); 183 hom:=NaturalHomomorphismByNormalSubgroupNC(w,cen); 184 if IsPermGroup(Image(hom)) and 185 NrMovedPoints(Image(hom))<=bound then 186 187 #Print("QQQ\n"); 188 return [Image(hom,w),rep*hom,List(maps,x->Image(hom,x))]; 189 fi; 190 191 fi; 192 else 193 Info(InfoGroup,2,"Does not work"); 194 fi; 195 return fail; 196 end; 197 198 selin:=Filtered([1..Length(autos)],x->IsInnerAutomorphism(autos[x])); 199 sel:=Difference([1..Length(autos)],selin); 200 201 # first try given rep 202 if NrMovedPoints(G)^3>Size(G) then 203 # likely too high degree. Try to reduce first 204 a:=SmallerDegreePermutationRepresentation(G:cheap); 205 a:=tryrep(a,4*NrMovedPoints(Image(a))); 206 elif not IsSubset(MovedPoints(G),[1..LargestMovedPoint(G)]) then 207 a:=tryrep(ActionHomomorphism(G,MovedPoints(G),"surjective"), 208 4*NrMovedPoints(G)); 209 else 210 a:=tryrep(IdentityMapping(G),4*NrMovedPoints(G)); 211 if a=fail and ForAll(autos,x->IsConjugatorAutomorphism(x:cheap)) then 212 a:=tryrep(SmallerDegreePermutationRepresentation(G:cheap),4*NrMovedPoints(G)); 213 fi; 214 fi; 215 if a<>fail then return a;fi; 216 217 # then (assuming G simple) try transitive action of small degree 218 dom:=Set(Orbit(G,LargestMovedPoint(G))); 219 s:=Blocks(G,dom); 220 if Length(s)=1 then 221 if Set(dom)=[1..Length(dom)] then 222 Info(InfoGroup,2,"reduction is equal to G"); 223 iso:=fail; 224 else 225 Info(InfoHomClass,2,"point action"); 226 iso:=ActionHomomorphism(G,dom,"surjective"); 227 fi; 228 else 229 Info(InfoHomClass,2,"block refinement"); 230 iso:=ActionHomomorphism(G,s,OnSets,"surjective"); 231 fi; 232 233 if iso<>fail then 234 # try the new rep 235 a:=tryrep(iso,4*NrMovedPoints(G)); 236 if a<>fail then return a;fi; 237 238 # otherwise go to new small deg rep 239 G:=Image(iso,G); 240 autos:=List(autos,x->InducedAutomorphism(iso,x)); 241 fi; 242 243 # test the automorphisms that are not inner. (The conjugator automorphisms 244 # have no reason to be normal in all automoirphisms, so this will not 245 # work.) 246 seln:=Filtered(sel,x->not IsInnerAutomorphism(autos[x])); 247 248 # autos{seln} generates the non-perm automorphism group. Enumerate 249 # use that automorphism is conjugator is stabilizer is conjugate 250 stabs:=[Stabilizer(G,1)]; 251 outs:=[IdentityMapping(G)]; 252 i:=1; 253 while i<=Length(stabs) do 254 for j in seln do 255 sub:=Image(autos[j],stabs[i]); 256 p:=0; 257 found:=fail; 258 while found=fail and p<Length(stabs) do 259 p:=p+1; 260 found:=RepresentativeAction(G,sub,stabs[p]); 261 #Print(j," maps ",i," to ",p,"\n"); 262 od; 263 264 if found=fail then 265 # new copy 266 Add(stabs,sub); 267 map:=outs[i]*autos[j]; 268 Add(outs,map); 269 fi; 270 271 od; 272 i:=i+1; 273 od; 274 Info(InfoGroup,1,"Build ",Length(outs)," copies"); 275 if Length(stabs)=1 then 276 # the group is given in a representation in which there is a centralizer 277 # in Sn 278 a:=tryrep(IdentityMapping(G),infinity); 279 return a; 280 281 Error("why only one -- should have been found before"); 282 fi; 283 284 d:=DirectProduct(List(stabs,x->G)); 285 p:=[]; 286 for i in GeneratorsOfGroup(G) do 287 a:=One(d); 288 for j in [1..Length(stabs)] do 289 a:=a*Image(Embedding(d,j),PreImagesRepresentative(outs[j],i)); 290 od; 291 Add(p,a); 292 od; 293 294 a:=Subgroup(d,p); 295 SetSize(a,Size(G)); 296 p:=GroupHomomorphismByImagesNC(G,a,GeneratorsOfGroup(G),p); 297 298 a:=tryrep(p,4*NrMovedPoints(G)); 299 if a<>fail then 300 if iso<>fail then 301 a[2]:=iso*a[2]; 302 fi; 303 return a; 304 fi; 305 306 Info(InfoGroup,1,"Wreath embedding failed"); 307 Error("This should never happen"); 308 309end); 310 311InstallGlobalFunction(EmbedAutomorphisms,function(arg) 312local G,H,tg,th,hom, tga, Gemb, C, outs, auts, ar, Hemb; 313 314 G:=arg[1]; 315 H:=arg[2]; 316 tg:=arg[3]; 317 th:=arg[4]; 318 if Length(arg)>4 then 319 outs:=arg[4]; 320 else 321 outs:=fail; 322 fi; 323 if th=tg then 324 hom:=IdentityMapping(tg); 325 else 326 hom:=IsomorphismGroups(th,tg); 327 fi; 328 if hom=fail then 329 Error("nonisomorphic simple groups!"); 330 fi; 331 tga:=List(GeneratorsOfGroup(H), 332 i->GroupHomomorphismByImagesNC(tg,tg, 333 GeneratorsOfGroup(tg), 334 List(GeneratorsOfGroup(tg), 335 j->Image(hom,PreImagesRepresentative(hom,j)^i)))); 336 337 Gemb:=fail; 338 if ForAll(tga,IsConjugatorAutomorphism) then 339 Info(InfoHomClass,4,"All automorphism are conjugator"); 340 C:=ClosureGroup(G,List(tga,ConjugatorInnerAutomorphism)); 341 #reco:=ConstructiveRecognitionAlmostSimpleGroupTom(tg); 342 if outs=fail then 343 outs:=Size(AutomorphismGroup(tg))/Size(tg); 344 fi; 345 if Size(C)/Size(tg)=outs then 346 Info(InfoHomClass,2,"Automorphisms realize full automorphism group"); 347 Gemb:=IdentityMapping(G); 348 G:=C; 349 tga:=List(tga,ConjugatorInnerAutomorphism); 350 fi; 351 fi; 352 353 if Gemb=fail then 354 # not all realizable or too small -> build new group 355 Info(InfoHomClass,2,"Compute full automorphism group"); 356 auts:=AutomorphismGroup(tg); 357 auts:=GeneratorsOfGroup(auts); 358 ar:=AutomorphismRepresentingGroup(tg,Concatenation( 359 auts, 360 List(GeneratorsOfGroup(G),i->ConjugatorAutomorphism(tg,i)), 361 tga)); 362 363 tga:=ar[3]{[Length(ar[3])-Length(tga)+1..Length(ar[3])]}; 364 Gemb:=GroupHomomorphismByImagesNC(G,ar[1],GeneratorsOfGroup(G), 365 ar[3]{[Length(auts)+1..Length(auts)+Length(GeneratorsOfGroup(G))]}); 366 G:=ar[1]; 367 else 368 Gemb:=IdentityMapping(G); 369 fi; 370 Hemb:=GroupHomomorphismByImagesNC(H,Group(tga),GeneratorsOfGroup(H),tga); 371 return [G,Gemb,Hemb]; 372end); 373 374InstallGlobalFunction(WreathActionChiefFactor, 375function(G,M,N) 376local cs,i,k,u,o,norm,T,Thom,autos,ng,a,Qhom,Q,E,Ehom,genimages, 377 n,w,embs,reps,act,img,gimg,gens; 378 379 # get the simple factor(s) 380 cs:=CompositionSeries(M); 381 # the cs with N gives a cs for M/N. 382 # take the first subnormal subgroup that is not in N. This will be the 383 # subgroup 384 u:=fail; 385 if Size(N)=1 then 386 if Length(cs)=2 and Size(Centralizer(G,M))=1 then 387 return [G,IdentityMapping(G),G,M,1]; 388 fi; 389 u:=cs[2]; 390 else 391 i:=2; 392 u:=ClosureGroup(N,cs[i]); 393 while Size(u)=Size(M) do 394 i:=i+1; 395 u:=ClosureGroup(N,cs[i]); 396 od; 397 fi; 398 399 o:=OrbitStabilizer(G,u); 400 norm:=o.stabilizer; 401 o:=o.orbit; 402 n:=Length(o); 403 Info(InfoHomClass,1,"Factor: ",Index(u,N),"^",n); 404 Qhom:=ActionHomomorphism(G,o,"surjective"); 405 Q:=Image(Qhom,G); 406 Thom:=NaturalHomomorphismByNormalSubgroup(M,u); 407 T:=Image(Thom); 408 if IsSubset(M,norm) then 409 # nothing outer possible 410 a:=Image(Thom); 411 else 412 # get the induced automorphism action of elements 413 ng:=SmallGeneratingSet(norm); 414 autos:=List(ng,i->GroupHomomorphismByImagesNC(T,T, 415 GeneratorsOfGroup(T), 416 List(GeneratorsOfGroup(T), 417 j->Image(Thom,PreImagesRepresentative(Thom,j)^i)))); 418 a:=AutomorphismRepresentingGroup(T,autos); 419 Thom:=GroupHomomorphismByImagesNC(norm,a[1],ng,a[3]); 420 a:=a[1]; 421 fi; 422 423 # now embed into wreath 424 w:=WreathProduct(a,Q); 425 426 embs:=List([1..n+1],i->Embedding(w,i)); 427 428 # define isomorphisms between the components 429 reps:=List([1..n],i-> 430 PreImagesRepresentative(Qhom,RepresentativeAction(Q,1,i))); 431 432 genimages:=[]; 433 for i in GeneratorsOfGroup(G) do 434 img:=Image(Qhom,i); 435 gimg:=Image(embs[n+1],img); 436 for k in [1..n] do 437 # look at part of i's action on the k-th factor. 438 # we get this by looking at the action of 439 # reps[k] * i * reps[k^img]^-1 440 # 1 -> k -> k^img -> 1 441 # on the first component. 442 act:=reps[k]*i*(reps[k^img]^-1); 443 # this must be multiplied *before* permuting 444 gimg:=ImageElm(embs[k],ImageElm(Thom,act))*gimg; 445 od; 446 #gimg:=RestrictedPermNC(gimg,MovedPoints(w)); 447 Add(genimages,gimg); 448 od; 449 450 E:=Subgroup(w,genimages); 451 # allow also mapping of `a' by enlarging 452 gens:=GeneratorsOfGroup(G); 453 454 if AssertionLevel()>1 then 455 Ehom:=GroupHomomorphismByImages(G,w,gens,genimages); 456 Assert(1,fail<>Ehom); 457 else 458 Ehom:=GroupHomomorphismByImagesNC(G,w,gens,genimages); 459 fi; 460 461 return [w,Ehom,a,Image(Thom,M),n]; 462end); 463 464############################################################################# 465## 466#F PermliftSeries( <G> ) 467## 468InstallGlobalFunction(PermliftSeries,function(G) 469local limit, r, pcgs, ser, ind, m, p, l, l2, good, i, j,nser,hom; 470 471 # Do we limit factor size? 472 limit:=ValueOption("limit"); 473 474 if HasStoredPermliftSeries(G) then 475 ser:=StoredPermliftSeries(G); 476 if limit=fail or ForAll([2..Length(ser[1])], 477 i->Size(ser[1][i-1])/Size(ser[1][i])<=limit) then 478 return ser; 479 fi; 480 fi; 481 482 # it seems to be cleaner (and avoids deferring abelian factors) if we 483 # factor out the radical first. (Note: The radical method for perm groups 484 # stores the nat hom.!) 485 r:=RadicalGroup(G); 486 487 if Size(r)=1 then 488 return [[r],false]; 489 fi; 490 491 # try to improve the representation of G/r 492 hom:=NaturalHomomorphismByNormalSubgroup(G,r); 493 if IsPermGroup(Range(hom)) then 494 hom:=hom*SmallerDegreePermutationRepresentation(Range(hom):cheap); 495 fi; 496 AddNaturalHomomorphismsPool(G,r,hom); 497 498 # first try whether the pcgs found 499 # is good enough 500 pcgs:=PcgsElementaryAbelianSeries(r); 501 ser:=EANormalSeriesByPcgs(pcgs); 502 if not ForAll(ser,i->IsNormal(G,i)) then 503 # we have to get a better series 504 505 # do we want to reduce the degree? 506 m:=fail; 507 if IsPermGroup(r) then 508 m:=ReducedPermdegree(r); 509 fi; 510 if m<>fail then 511 p:=Image(m); 512 ser:=InvariantElementaryAbelianSeries(p, List( GeneratorsOfGroup( G ), 513 i -> GroupHomomorphismByImagesNC(p,p,GeneratorsOfGroup(p), 514 List(GeneratorsOfGroup(p), 515 j->Image(m,PreImagesRepresentative(m,j)^i)))), 516 TrivialSubgroup(p),true); 517 ser:=List(ser,i->PreImage(m,i)); 518 else 519 ser:=InvariantElementaryAbelianSeries(r, List( GeneratorsOfGroup( G ), 520 i -> ConjugatorAutomorphismNC( r, i ) ), 521 TrivialSubgroup(G),true); 522 fi; 523 524 # remember there is no universal parent pcgs 525 pcgs:=false; 526 ind:=false; 527 else 528 ind:=IndicesEANormalSteps(pcgs); 529 pcgs:=List([1..Length(ind)], 530 i->InducedPcgsByPcSequenceNC(pcgs,pcgs{[ind[i]..Length(pcgs)]})); 531 fi; 532 533 if limit<>fail then 534 nser:=[ser[1]]; 535 for i in [2..Length(ser)] do 536 if Size(ser[i-1])/Size(ser[i])>limit then 537 m:=ModuloPcgs(ser[i-1],ser[i]); 538 p:=RelativeOrders(m)[1]; 539 l:=GModuleByMats(LinearActionLayer(G,m),GF(p)); 540 l:=MTX.BasesCompositionSeries(l); 541 l2:=[[]]; 542 good:=false; 543 for j in [1..Length(l)] do 544 if p^(Length(l[j])-Length(l2[Length(l2)]))>limit then 545 if Length(good)>0 then 546 Add(l2,good); 547 fi; 548 fi; 549 good:=l[j]; 550 od; 551 l2:=List(l2,i->List(i,j->PcElementByExponentsNC(m,j))); 552 l2:=List(l2,j->ClosureGroup(ser[i],j)); 553 pcgs:=false; # if there was a pcgs is it wrong now 554 Append(nser,Reversed(l2)); 555 else 556 Add(nser,ser[i]); 557 fi; 558 od; 559 if nser<>ser then 560 ser:=nser; 561 fi; 562 fi; 563 564 ser:=[ser,pcgs]; 565 if not HasStoredPermliftSeries(G) then 566 SetStoredPermliftSeries(G,ser); 567 fi; 568 return ser; 569end); 570 571InstallMethod(StoredPermliftSeries,true,[IsGroup],0,PermliftSeries); 572 573InstallGlobalFunction(EmbeddingWreathInWreath,function(wnew,w,emb,start) 574local info, a, ai, n, gens, imgs, e, e2, shift, hom, i, j; 575 info:=WreathProductInfo(w); 576 a:=GeneratorsOfGroup(info.groups[1]); 577 ai:=List(a,i->Image(emb,i)); 578 n:=Length(info.components); 579 gens:=[]; 580 imgs:=[]; 581 # base 582 for i in [1..n] do 583 e:=Embedding(w,i); 584 e2:=Embedding(wnew,i+start-1); 585 for j in [1..Length(a)] do 586 Add(gens,Image(e,a[j])); 587 Add(imgs,Image(e2,ai[j])); 588 od; 589 od; 590 # complement embeddings 591 e:=Embedding(w,n+1); 592 e2:=Embedding(wnew,Length(WreathProductInfo(wnew).components)+1); 593 shift:=MappingPermListList([1..n],[start..start+n-1]); 594 for j in GeneratorsOfGroup(info.groups[2]) do 595 Add(gens,Image(e,j)); # component permutation in w 596 Add(imgs,Image(e2,j^shift)); 597 od; 598 hom:=GroupHomomorphismByImages(w,wnew,gens,imgs); 599 return hom; 600end); 601 602InstallGlobalFunction(EmbedFullAutomorphismWreath,function(w,a,t,n) 603local au, agens, agau, a2, w2, ogens, ngens, oe, ne, emb, i, j; 604 IsNaturalAlternatingGroup(t); 605 au:=AutomorphismGroup(t); 606 agens:=GeneratorsOfGroup(a); 607 agau:=List(agens,i->ConjugatorAutomorphism(t,i)); 608 a2:=AutomorphismRepresentingGroup(t, 609 # this way we get the images easily 610 Concatenation(agau,GeneratorsOfGroup(au))); 611 agau:=a2[3]{[1..Length(agau)]}; 612 if Index(a,t)=1 then 613 agau:=a2[2]; 614 else 615 agau:=GroupHomomorphismByImagesNC(a,a2[1],agens,agau); 616 fi; 617 w2:=WreathProduct(a2[1],Image(Projection(w))); 618 ogens:=[]; 619 ngens:=[]; 620 # for all w-generators take the corresponding w2 generators 621 for i in [1..n+1] do 622 oe:=Embedding(w,i); 623 ne:=Embedding(w2,i); 624 for j in GeneratorsOfGroup(Source(oe)) do 625 Add(ogens,Image(oe,j)); 626 if i<=n then 627 Add(ngens,Image(ne,Image(agau,j))); 628 else 629 Add(ngens,Image(ne,j)); 630 fi; 631 od; 632 od; 633 emb:=GroupHomomorphismByImagesNC(w,w2,ogens,ngens); 634 return [emb,w2,a2[1],Image(a2[2])]; 635end); 636