1############################################################################## 2## 3#W gp2map.gi GAP4 package `XMod' Chris Wensley 4#W & Murat Alp 5## This file installs methods for 2DimensionalMappings 6## for crossed modules and cat1-groups. 7## 8#Y Copyright (C) 2001-2019, Chris Wensley et al, 9#Y School of Computer Science, Bangor University, U.K. 10 11############################################################################## 12## 13#M Is2DimensionalGroupMorphismData( <list> ) . . . . . . . . . . 2d-group map 14## 15## this functions tests that boundaries are ok but no checks on actions 16## 17InstallMethod( Is2DimensionalGroupMorphismData, 18 "for list [ 2d-group, 2d-group, homomorphism, homomorphism ]", true, 19 [ IsList ], 0, 20function( L ) 21 22 local src, rng, shom, rhom, mor, ok, sbdy, rbdy, st, sh, se, rt, rh, re, 23 sgen, rgen, im1, im2; 24 25 ok := ( Length(L) = 4 ); 26 if not ok then 27 Info( InfoXMod, 2, "require list with 2 2dgroups and 2 group homs" ); 28 return false; 29 fi; 30 src := L[1]; rng := L[2]; shom := L[3]; rhom := L[4]; 31 ok := ( Is2DimensionalGroup( src ) and Is2DimensionalGroup( rng ) 32 and IsGroupHomomorphism( shom) and IsGroupHomomorphism( rhom ) ); 33 if not ok then 34 Info( InfoXMod, 2, "require two 2dgroups and two group homs" ); 35 return false; 36 fi; 37 ok := ( ( Source( src ) = Source( shom ) ) 38 and ( Range( src ) = Source( rhom ) ) 39 and IsSubgroup( Source( rng ), Range( shom ) ) 40 and IsSubgroup( Range( rng ), Range( rhom ) ) ); 41 if not ok then 42 Info( InfoXMod, 2, "sources and ranges do not match" ); 43 return false; 44 fi; 45 sgen := GeneratorsOfGroup( Source(src) ); 46 rgen := GeneratorsOfGroup( Range(src) ); 47 if ( IsPreXMod( src ) and IsPreXMod( rng ) ) then 48 sbdy := Boundary( src ); 49 rbdy := Boundary( rng ); 50 im1 := List( sgen, g -> ImageElm( rbdy, ImageElm(shom,g) ) ); 51 im2 := List( sgen, g -> ImageElm( rhom, ImageElm(sbdy,g) ) ); 52 if not ( im1 = im2 ) then 53 Info( InfoXMod, 2, "boundaries and homs do not commute" ); 54 return false; 55 fi; 56 elif ( IsPreCat1Group( src ) and IsPreCat1Group( rng ) ) then 57 st := TailMap( src ); 58 rt := TailMap( rng ); 59 im1 := List( sgen, g -> ImageElm( rt, ImageElm(shom,g) ) ); 60 im2 := List( sgen, g -> ImageElm( rhom, ImageElm(st,g) ) ); 61 if not ( im1 = im2 ) then 62 Info( InfoXMod, 2, "tail maps and homs do not commute" ); 63 return false; 64 fi; 65 sh := HeadMap( src ); 66 rh := HeadMap( rng ); 67 im1 := List( sgen, g -> ImageElm( rh, ImageElm(shom,g) ) ); 68 im2 := List( sgen, g -> ImageElm( rhom, ImageElm(sh,g) ) ); 69 if not ( im1 = im2 ) then 70 Info( InfoXMod, 2, "head maps and homs do not commute" ); 71 return false; 72 fi; 73 se := RangeEmbedding( src ); 74 re := RangeEmbedding( rng ); 75 im1 := List( rgen, g -> ImageElm( re, ImageElm(rhom,g) ) ); 76 im2 := List( rgen, g -> ImageElm( shom, ImageElm(se,g) ) ); 77 if not ( im1 = im2 ) then 78 Info( InfoXMod, 2, "range embeddings and homs do not commute" ); 79 return false; 80 fi; 81 else 82 Info( InfoXMod, 2, "require 2 prexmods or precat1s, not one of each" ); 83 fi; 84 return true; 85end ); 86 87############################################################################## 88## 89#M Make2DimensionalGroupMorphism( <list> ) . . . . . . . . . . . 2d-group map 90## 91InstallMethod( Make2DimensionalGroupMorphism, 92 "for list [ 2d-group, 2d-group, homomorphism, homomorphism ]", true, 93 [ IsList ], 0, 94function( L ) 95 96 local mor; 97 98 if not Is2DimensionalGroupMorphismData( L ) then 99 return fail; 100 fi; 101 mor := rec(); 102 ObjectifyWithAttributes( mor, Type2DimensionalGroupMorphism, 103 Source, L[1], 104 Range, L[2], 105 SourceHom, L[3], 106 RangeHom, L[4] ); 107 return mor; 108end ); 109 110############################################################################# 111## 112#M IsPreXModMorphism check diagram of group homs commutes 113## 114InstallMethod( IsPreXModMorphism, "generic method for morphisms of 2d-groups", 115 true, [ Is2DimensionalGroupMorphism ], 0, 116function( mor ) 117 118 local PM, Pact, Pbdy, Prng, Psrc, QM, Qact, Qbdy, Qrng, Qsrc, 119 morsrc, morrng, x2, x1, y2, z2, y1, z1, gensrc, genrng; 120 121 PM := Source( mor ); 122 QM := Range( mor ); 123 if not ( IsPreXMod( PM ) and IsPreXMod( QM ) ) then 124 return false; 125 fi; 126 Psrc := Source( PM ); 127 Prng := Range( PM ); 128 Pbdy := Boundary( PM ); 129 Pact := XModAction( PM ); 130 Qsrc := Source( QM ); 131 Qrng := Range( QM ); 132 Qbdy := Boundary( QM ); 133 Qact := XModAction( QM ); 134 morsrc := SourceHom( mor ); 135 morrng := RangeHom( mor ); 136 # now check that the homomorphisms commute 137 gensrc := GeneratorsOfGroup( Psrc ); 138 genrng := GeneratorsOfGroup( Prng ); 139 Info( InfoXMod, 3, "Checking that the diagram commutes :- \n", 140 " boundary( morsrc( x ) ) = morrng( boundary( x ) )" ); 141 for x2 in gensrc do 142 y1 := ( x2 ^ morsrc ) ^ Qbdy; 143 z1 := ( x2 ^ Pbdy ) ^ morrng; 144 if not ( y1 = z1 ) then 145 Info( InfoXMod, 3, "Square does not commute! \n", 146 "when x2= ", x2, " Qbdy( morsrc(x2) )= ", y1, "\n", 147 " and morrng( Pbdy(x2) )= ", z1 ); 148 return false; 149 fi; 150 od; 151 # now check that the actions commute: 152 Info( InfoXMod, 3, 153 "Checking: morsrc(x2^x1) = morsrc(x2)^(morrng(x1))" ); 154 for x2 in gensrc do 155 for x1 in genrng do 156 y2 := ( x2 ^ ( x1 ^ Pact) ) ^ morsrc; 157 z2 := ( x2 ^ morsrc ) ^ ( ( x1 ^ morrng ) ^ Qact ); 158 if not ( y2 = z2 ) then 159 Info( InfoXMod, 2, "Actions do not commute! \n", 160 "When x2 = ", x2, " and x1 = ", x1, "\n", 161 " morsrc(x2^x1) = ", y2, "\n", 162 "and morsrc(x2)^(morrng(x1) = ", z2 ); 163 return false; 164 fi; 165 od; 166 od; 167 return true; 168end ); 169 170############################################################################# 171## 172#M IsXModMorphism 173## 174InstallMethod( IsXModMorphism, "generic method for pre-xmod morphisms", true, 175 [ IsPreXModMorphism ], 0, 176function( mor ) 177 return ( IsXMod( Source( mor ) ) and IsXMod( Range( mor ) ) ); 178end ); 179 180############################################################################# 181## 182#F MappingGeneratorsImages( <map> ) . . . . . . . for a 2DimensionalMapping 183## 184InstallOtherMethod( MappingGeneratorsImages, "for a 2DimensionalMapping", 185 true, [ Is2DimensionalMapping ], 0, 186function( map ) 187 return [ MappingGeneratorsImages( SourceHom( map ) ), 188 MappingGeneratorsImages( RangeHom( map ) ) ]; 189end ); 190 191############################################################################# 192## 193#F Display( <mor> ) . . . . print details of a (pre-)crossed module morphism 194## 195InstallMethod( Display, "display a morphism of pre-crossed modules", true, 196 [ IsPreXModMorphism ], 0, 197function( mor ) 198 199 local morsrc, morrng, gensrc, genrng, P, Q, name, ok; 200 201 name := Name( mor ); 202 P := Source( mor ); 203 Q := Range( mor ); 204 morsrc := SourceHom( mor ); 205 gensrc := GeneratorsOfGroup( Source( P ) ); 206 morrng := RangeHom( mor ); 207 genrng := GeneratorsOfGroup( Range( P ) ); 208 if IsXModMorphism( mor ) then 209 Print( "Morphism of crossed modules :- \n" ); 210 else 211 Print( "Morphism of pre-crossed modules :- \n" ); 212 fi; 213 Print( ": Source = ", P, " with generating sets:\n " ); 214 Print( gensrc, "\n ", genrng, "\n" ); 215 if ( Q = P ) then 216 Print( ": Range = Source\n" ); 217 else 218 Print( ": Range = ", Q, " with generating sets:\n " ); 219 Print( GeneratorsOfGroup( Source( Q ) ), "\n" ); 220 Print( " ", GeneratorsOfGroup( Range( Q ) ), "\n" ); 221 fi; 222 Print( ": Source Homomorphism maps source generators to:\n" ); 223 Print( " ", List( gensrc, s -> ImageElm( morsrc, s ) ), "\n" ); 224 Print( ": Range Homomorphism maps range generators to:\n" ); 225 Print( " ", List( genrng, r -> ImageElm( morrng, r ) ), "\n" ); 226end ); 227 228############################################################################# 229## 230#M IsPreCat1GroupMorphism . . . . . . . check diagram of group homs commutes 231## 232InstallMethod( IsPreCat1GroupMorphism, "generic method for morphisms of 2d-groups", 233 true, [ Is2DimensionalGroupMorphism ], 0, 234function( mor ) 235 236 local PCG, Prng, Psrc, Pt, Ph, Pe, QCG, Qrng, Qsrc, Qt, Qh, Qe, 237 morsrc, morrng, x2, x1, y2, z2, y1, z1, gensrc, genrng; 238 239 PCG := Source( mor ); 240 QCG := Range( mor ); 241 if not ( IsPreCat1Group( PCG ) and IsPreCat1Group( QCG ) ) then 242 return false; 243 fi; 244 Psrc := Source( PCG ); 245 Prng := Range( PCG ); 246 Pt := TailMap( PCG ); 247 Ph := HeadMap( PCG ); 248 Pe := RangeEmbedding( PCG ); 249 Qsrc := Source( QCG ); 250 Qrng := Range( QCG ); 251 Qt := TailMap( QCG ); 252 Qh := HeadMap( QCG ); 253 Qe := RangeEmbedding( QCG ); 254 morsrc := SourceHom( mor ); 255 morrng := RangeHom( mor ); 256 # now check that the homomorphisms commute 257 gensrc := GeneratorsOfGroup( Psrc ); 258 genrng := GeneratorsOfGroup( Prng ); 259 Info( InfoXMod, 3, 260 "Checking that the diagrams commute :- \n", 261 " tail/head( morsrc( x ) ) = morrng( tail/head( x ) )" ); 262 for x2 in gensrc do 263 y1 := ( x2 ^ morsrc ) ^ Qt; 264 z1 := ( x2 ^ Pt ) ^ morrng; 265 y2 := ( x2 ^ morsrc ) ^ Qh; 266 z2 := ( x2 ^ Ph ) ^ morrng; 267 if not ( ( y1 = z1 ) and ( y2 = z2 ) ) then 268 Info( InfoXMod, 3, "Square does not commute! \n", 269 "when x2= ", x2, " Qt( morsrc(x2) )= ", y1, "\n", 270 " and morrng( Pt(x2) )= ", z1, "\n", 271 " and Qh( morsrc(x2) )= ", y2, "\n", 272 " and morrng( Ph(x2) )= ", z2 ); 273 return false; 274 fi; 275 od; 276 for x2 in genrng do 277 y1 := ( x2 ^ morrng ) ^ Qe; 278 z1 := ( x2 ^ Pe ) ^ morsrc; 279 if not ( y1 = z1 ) then 280 Info( InfoXMod, 3, "Square does not commute! \n", 281 "when x2= ", x2, " Qe( morrng(x2) )= ", y1, "\n", 282 " and morsrc( Pe(x2) )= ", z1 ); 283 return false; 284 fi; 285 od; 286 return true; 287end ); 288 289############################################################################# 290## 291#M IsCat1GroupMorphism 292## 293InstallMethod( IsCat1GroupMorphism, "generic method for cat1-group homomorphisms", 294 true, [ IsPreCat1GroupMorphism ], 0, 295function( mor ) 296 return ( IsCat1Group( Source( mor ) ) and IsCat1Group( Range( mor ) ) ); 297end ); 298 299############################################################################# 300## 301#F Display( <mor> ) . . . . . . print details of a (pre-)cat1-group morphism 302## 303InstallMethod( Display, "display a morphism of pre-cat1 groups", true, 304 [ IsPreCat1GroupMorphism ], 0, 305function( mor ) 306 307 local morsrc, morrng, gensrc, genrng, P, Q, name, ok; 308 309 if not HasName( mor ) then 310 # name := PreCat1GroupMorphismName( mor ); 311 SetName( mor, "[..=>..]=>[..=>..]" ); 312 fi; 313 name := Name( mor ); 314 P := Source( mor ); 315 Q := Range( mor ); 316 morsrc := SourceHom( mor ); 317 gensrc := GeneratorsOfGroup( Source( P ) ); 318 morrng := RangeHom( mor ); 319 genrng := GeneratorsOfGroup( Range( P ) ); 320 if IsCat1GroupMorphism( mor ) then 321 Print( "Morphism of cat1-groups :- \n" ); 322 else 323 Print( "Morphism of pre-cat1 groups :- \n" ); 324 fi; 325 Print( ": Source = ", P, " with generating sets:\n " ); 326 Print( gensrc, "\n ", genrng, "\n" ); 327 if ( Q = P ) then 328 Print( ": Range = Source\n" ); 329 else 330 Print( ": Range = ", Q, " with generating sets:\n " ); 331 Print( GeneratorsOfGroup( Source( Q ) ), "\n" ); 332 Print( " ", GeneratorsOfGroup( Range( Q ) ), "\n" ); 333 fi; 334 Print( ": Source Homomorphism maps source generators to:\n" ); 335 Print( " ", List( gensrc, s -> ImageElm( morsrc, s ) ), "\n" ); 336 Print( ": Range Homomorphism maps range generators to:\n" ); 337 Print( " ", List( genrng, r -> ImageElm( morrng, r ) ), "\n" ); 338end ); 339 340############################################################################## 341## 342#M CompositionMorphism . . . . . . . . . . . . for two 2Dimensional-mappings 343## 344InstallOtherMethod( CompositionMorphism, "generic method for 2d-mappings", 345 IsIdenticalObj, [ Is2DimensionalMapping, Is2DimensionalMapping ], 0, 346function( mor2, mor1 ) 347 348 local srchom, rnghom, comp, ok; 349 350 if not ( Range( mor1 ) = Source( mor2 ) ) then 351 Info( InfoXMod, 2, "Range(mor1) <> Source(mor2)" ); 352 return fail; 353 fi; 354 srchom := CompositionMapping2( SourceHom( mor2 ), SourceHom( mor1 ) ); 355 rnghom := CompositionMapping2( RangeHom( mor2 ), RangeHom( mor1 ) ); 356 comp := Make2DimensionalGroupMorphism( 357 [ Source(mor1), Range(mor2), srchom, rnghom ]); 358 if IsPreCat1Group( Source( mor1 ) ) then 359 if ( IsPreCat1GroupMorphism( mor1 ) 360 and IsPreCat1GroupMorphism( mor2 ) ) then 361 SetIsPreCat1GroupMorphism( comp, true ); 362 fi; 363 if ( IsCat1GroupMorphism( mor1 ) and IsCat1GroupMorphism( mor2 ) ) then 364 SetIsCat1GroupMorphism( comp, true ); 365 fi; 366 else 367 if ( IsPreXModMorphism( mor1 ) and 368 IsPreXModMorphism( mor2 ) ) then 369 SetIsPreXModMorphism( comp, true ); 370 fi; 371 if ( IsXModMorphism( mor1 ) and IsXModMorphism( mor2 ) ) then 372 SetIsXModMorphism( comp, true ); 373 fi; 374 fi; 375 return comp; 376end ); 377 378############################################################################## 379## 380#M InverseGeneralMapping . . . . . . . . . . . . . for a 2Dimensional-mapping 381## 382InstallOtherMethod( InverseGeneralMapping, "generic method for 2d-mapping", 383 true, [ Is2DimensionalMapping ], 0, 384function( mor ) 385 386 local sinv, rinv, inv, ok; 387 388 if not IsBijective( mor ) then 389 Info( InfoXMod, 1, "mor is not bijective" ); 390 return fail; 391 fi; 392 sinv := InverseGeneralMapping( SourceHom( mor ) ); 393 rinv := InverseGeneralMapping( RangeHom( mor ) ); 394 inv := Make2DimensionalGroupMorphism( [Range(mor),Source(mor),sinv,rinv] ); 395 if IsPreXModMorphism( mor ) then 396 SetIsPreXModMorphism( inv, true ); 397 if IsXModMorphism( mor ) then 398 SetIsXModMorphism( inv, true ); 399 fi; 400 elif IsPreCat1GroupMorphism( mor ) then 401 SetIsPreCat1GroupMorphism( inv, true ); 402 if IsCat1GroupMorphism( mor ) then 403 SetIsCat1GroupMorphism( inv, true ); 404 fi; 405 fi; 406 SetIsInjective( inv, true ); 407 SetIsSurjective( inv, true ); 408 return inv; 409end ); 410 411############################################################################## 412## 413#M IdentityMapping( <obj> ) 414## 415InstallOtherMethod( IdentityMapping, "for 2d-group object", true, 416 [ Is2DimensionalDomain ], 0, 417function( obj ) 418 419 local shom, rhom; 420 421 shom := IdentityMapping( Source( obj ) ); 422 rhom := IdentityMapping( Range( obj ) ); 423 if IsPreXModObj( obj ) then 424 return PreXModMorphismByGroupHomomorphisms( obj, obj, shom, rhom ); 425 elif IsPreCat1Obj( obj ) then 426 return PreCat1GroupMorphismByGroupHomomorphisms( obj, obj, shom, rhom ); 427 else 428 return fail; 429 fi; 430end ); 431 432############################################################################## 433## 434#M InclusionMorphism2DimensionalDomains( <obj>, <sub> ) 435## 436InstallMethod( InclusionMorphism2DimensionalDomains, "one 2d-object in another", 437 true, [ Is2DimensionalDomain, Is2DimensionalDomain ], 0, 438function( obj, sub ) 439 440 local shom, rhom; 441 442 shom := InclusionMappingGroups( Source( obj ), Source( sub ) ); 443 rhom := InclusionMappingGroups( Range( obj ), Range( sub ) ); 444 if IsPreXModObj( obj ) then 445 return PreXModMorphismByGroupHomomorphisms( sub, obj, shom, rhom ); 446 elif IsPreCat1Obj( obj ) then 447 return PreCat1GroupMorphismByGroupHomomorphisms( sub, obj, shom, rhom ); 448 else 449 return fail; 450 fi; 451end ); 452 453############################################################################## 454## 455#F PreXModMorphism( <src>,<rng>,<srchom>,<rnghom> ) pre-crossed mod morphism 456## 457## (need to extend to other sets of parameters) 458## 459InstallGlobalFunction( PreXModMorphism, function( arg ) 460 461 local ok, mor, nargs; 462 463 nargs := Length( arg ); 464 # two pre-xmods and two homomorphisms 465 if ( nargs = 4 ) then 466 mor := Make2DimensionalGroupMorphism( [arg[1],arg[2],arg[3],arg[4] ] ); 467 else 468 # alternatives not allowed 469 Info( InfoXMod, 2, "usage: PreXModMorphism([src,rng,srchom,rnghom]);" ); 470 return fail; 471 fi; 472 ok := IsPreXModMorphism( mor ); 473 return mor; 474end ); 475 476############################################################################### 477## 478#F XModMorphism( <src>, <rng>, <srchom>, <rnghom> ) crossed module morphism 479## 480## (need to extend to other sets of parameters) 481## 482InstallGlobalFunction( XModMorphism, function( arg ) 483 484 local nargs; 485 486 nargs := Length( arg ); 487 # two xmods and two homomorphisms 488 if ( ( nargs = 4 ) and IsXMod( arg[1] ) and IsXMod( arg[2]) 489 and IsGroupHomomorphism( arg[3] ) 490 and IsGroupHomomorphism( arg[4] ) ) then 491 return XModMorphismByGroupHomomorphisms(arg[1],arg[2],arg[3],arg[4]); 492 fi; 493 # alternatives not allowed 494 Info( InfoXMod, 2, "usage: XModMorphism( src, rng, srchom, rnghom );" ); 495 return fail; 496end ); 497 498############################################################################### 499## 500#F PreCat1GroupMorphism( <src>,<rng>,<srchom>,<rnghom> ) pre-cat1-grp morphism 501## 502## (need to extend to other sets of parameters) 503## 504InstallGlobalFunction( PreCat1GroupMorphism, function( arg ) 505 506 local nargs; 507 508 nargs := Length( arg ); 509 # two pre-cat1s and two homomorphisms 510 if ( ( nargs = 4 ) and IsPreCat1Group( arg[1] ) and IsPreCat1Group( arg[2]) 511 and IsGroupHomomorphism( arg[3] ) 512 and IsGroupHomomorphism( arg[4] ) ) then 513 return PreCat1GroupMorphismByGroupHomomorphisms( 514 arg[1], arg[2], arg[3], arg[4] ); 515 fi; 516 # alternatives not allowed 517 Info( InfoXMod, 2, 518 "usage: PreCat1GroupMorphism( src, rng, srchom, rnghom );" ); 519 return fail; 520end ); 521 522############################################################################### 523## 524#F Cat1GroupMorphism( <src>, <rng>, <srchom>, <rnghom> ) cat1-group morphism 525## 526## (need to extend to other sets of parameters) 527## 528InstallGlobalFunction( Cat1GroupMorphism, function( arg ) 529 530 local nargs; 531 532 nargs := Length( arg ); 533 # two cat1s and two homomorphisms 534 if ( ( nargs = 4 ) and IsCat1Group( arg[1] ) and IsCat1Group( arg[2]) 535 and IsGroupHomomorphism( arg[3] ) 536 and IsGroupHomomorphism( arg[4] ) ) then 537 return Cat1GroupMorphismByGroupHomomorphisms( arg[1], arg[2], arg[3], arg[4] ); 538 fi; 539 # alternatives not allowed 540 Info( InfoXMod, 2, "usage: Cat1GroupMorphism( src, rng, srchom, rnghom );" ); 541 return fail; 542end ); 543 544############################################################################## 545## 546#M XModMorphismByGroupHomomorphisms( <Xs>, <Xr>, <hsrc>, <hrng> ) 547## . . . make an xmod morphism 548## 549InstallMethod( XModMorphismByGroupHomomorphisms, "for 2 xmods and 2 homs", 550 true, [ IsXMod, IsXMod, IsGroupHomomorphism, IsGroupHomomorphism ], 0, 551function( src, rng, srchom, rnghom ) 552 553 local mor, ok; 554 555 mor := PreXModMorphismByGroupHomomorphisms( src, rng, srchom, rnghom ); 556 ok := IsXModMorphism( mor ); 557 if not ok then 558 return fail; 559 fi; 560 return mor; 561end ); 562 563############################################################################## 564## 565#M InnerAutomorphismXMod( <XM>, <r> ) . . . . . . . . conjugation of an xmod 566## 567InstallMethod( InnerAutomorphismXMod, "method for crossed modules", true, 568 [ IsPreXMod, IsMultiplicativeElementWithInverse ], 0, 569function( XM, r ) 570 571 local Xrng, Xsrc, genrng, gensrc, rhom, shom, s; 572 573 Xrng := Range( XM ); 574 if not ( r in Xrng ) then 575 Info( InfoXMod, 2, "conjugating element must be in the range group" ); 576 return fail; 577 fi; 578 Xsrc := Source( XM ); 579 gensrc := GeneratorsOfGroup( Xsrc ); 580 genrng := GeneratorsOfGroup( Xrng ); 581 rhom := GroupHomomorphismByImages( Xrng, Xrng, genrng, 582 List( genrng, g -> g^r ) ); 583 s := ImageElm( XModAction( XM ), r ); 584 shom := GroupHomomorphismByImages( Xsrc, Xsrc, gensrc, 585 List( gensrc, g -> g^s ) ); 586 return XModMorphismByGroupHomomorphisms( XM, XM, shom, rhom ); 587end ); 588 589############################################################################## 590## 591#M InnerAutomorphismCat1Group( <C1G>, <r> ) . . . conjugation of a cat1-group 592## 593InstallMethod( InnerAutomorphismCat1Group, "method for cat1-groups", true, 594 [ IsPreCat1Group, IsMultiplicativeElementWithInverse ], 0, 595function( C1G, r ) 596 597 local Crng, Csrc, genrng, gensrc, rhom, shom, s; 598 599 Crng := Range( C1G ); 600 if not ( r in Crng ) then 601 Info( InfoXMod, 2, "conjugating element must be in the range group" ); 602 return fail; 603 fi; 604 Csrc := Source( C1G ); 605 gensrc := GeneratorsOfGroup( Csrc ); 606 genrng := GeneratorsOfGroup( Crng ); 607 rhom := GroupHomomorphismByImages( Crng, Crng, genrng, 608 List( genrng, g -> g^r ) ); 609 s := ImageElm( RangeEmbedding( C1G ), r ); 610 shom := GroupHomomorphismByImages( Csrc, Csrc, gensrc, 611 List( gensrc, g -> g^s ) ); 612 return Cat1GroupMorphismByGroupHomomorphisms( C1G, C1G, shom, rhom ); 613end ); 614 615############################################################################# 616## 617#M String, ViewString, PrintString, ViewObj, PrintObj 618## . . . . . . . . . . . . . . . . . for a morphism of pre-crossed modules 619## 620InstallMethod( String, "method for a morphism of pre-crossed modules", true, 621 [ IsPreXModMorphism ], 0, 622function( mor ) 623 return( STRINGIFY( "[", String( Source(mor) ), " => ", 624 String( Range(mor) ), "]" ) ); 625end ); 626 627InstallMethod( ViewString, "method for a morphism of pre-crossed modules", 628 true, [ IsPreXModMorphism ], 0, String ); 629 630InstallMethod( PrintString, "method for a morphism of pre-crossed modules", 631 true, [ IsPreXModMorphism ], 0, String ); 632 633InstallMethod( ViewObj, "method for a morphism of pre-crossed modules", true, 634 [ IsPreXModMorphism ], 0, 635function( mor ) 636 if HasName( mor ) then 637 Print( Name( mor ), "\n" ); 638 else 639 Print( "[", Source( mor ), " => ", Range( mor ), "]" ); 640 fi; 641end ); 642 643InstallMethod( PrintObj, "method for a morphism of pre-crossed modules", true, 644 [ IsPreXModMorphism ], 0, 645function( mor ) 646 if HasName( mor ) then 647 Print( Name( mor ), "\n" ); 648 else 649 Print( "[", Source( mor ), " => ", Range( mor ), "]" ); 650 fi; 651end ); 652 653############################################################################## 654## 655#M \*( <mor1>, <mor2> ) . . . . . . . . . for 2 pre-crossed module morphisms 656## 657InstallOtherMethod( \*, "for two morphisms of pre-crossed modules", 658 IsIdenticalObj, [ IsPreXModMorphism, IsPreXModMorphism ], 0, 659function( mor1, mor2 ) 660 661 local comp; 662 663 comp := CompositionMorphism( mor2, mor1 ); 664 ## need to do some checks here !? ## 665 return comp; 666end ); 667 668############################################################################## 669## 670#M \^( <mor>, <int> ) . . . . . . . . . . . . . . . for a 2DimensionalMapping 671## 672InstallOtherMethod( POW, "for a 2d mapping", true, 673 [ Is2DimensionalMapping, IsInt ], 0, 674function( map, n ) 675 676 local pow, i, ok; 677 678 if not ( Source( map ) = Range( map ) ) then 679 return fail; 680 elif ( n = 1 ) then 681 return map; 682 elif ( n = -1 ) then 683 ok := IsBijective( map ); 684 return InverseGeneralMapping( map ); 685 elif ( n < -1 ) then 686 return InverseGeneralMapping( map^(-n) ); 687 fi; 688 pow := map; 689 for i in [2..n] do 690 pow := CompositionMorphism( pow, map ); 691 od; 692 return pow; 693end ); 694 695############################################################################## 696## 697#M IsomorphismByIsomorphisms . . . . . . constructs isomorphic pre-cat1-group 698## 699InstallMethod( IsomorphismByIsomorphisms, "generic method for pre-cat1-groups", 700 true, [ IsPreCat1Group, IsList ], 0, 701function( PC, isos ) 702 703 local G, R, t, h, e, isoG, isoR, mgiG, mgiR, invG, invR, 704 G2, R2, t2, h2, e2, PC2, mor; 705 706 G := Source( PC ); 707 R := Range( PC ); 708 t := TailMap( PC ); 709 h := HeadMap( PC ); 710 e := RangeEmbedding( PC ); 711 isoG := isos[1]; 712 isoR := isos[2]; 713 if not ( ( Source(isoR) = R ) and ( Source(isoG) = G ) ) then 714 Error( "isomorphisms do not have G,R as source" ); 715 fi; 716 G2 := Range( isoG ); 717 R2 := Range( isoR ); 718 mgiG := MappingGeneratorsImages( isoG ); 719 invG := GroupHomomorphismByImages( G2, G, mgiG[2], mgiG[1] ); 720 mgiR := MappingGeneratorsImages( isoR ); 721 invR := GroupHomomorphismByImages( R2, R, mgiR[2], mgiR[1] ); 722 t2 := CompositionMapping( isoR, t, invG ); 723 h2 := CompositionMapping( isoR, h, invG ); 724 e2 := CompositionMapping( isoG, e, invR ); 725 PC2 := PreCat1GroupByTailHeadEmbedding( t2, h2, e2 ); 726 mor := PreCat1GroupMorphism( PC, PC2, isoG, isoR ); 727 return mor; 728end ); 729 730InstallMethod( IsomorphismByIsomorphisms, "generic method for pre-xmods", 731 true, [ IsPreXMod, IsList ], 0, 732function( PM, isos ) 733 734 local Psrc, Prng, Pbdy, Pact, Paut, Pautgen, siso, smgi, sinv, riso, 735 rmgi, rinv, Qsrc, Qrng, Qbdy, Qaut, Qautgen, ahom, Qact, QM, iso; 736 737 Psrc := Source( PM ); 738 Prng := Range( PM ); 739 Pbdy := Boundary( PM ); 740 siso := isos[1]; 741 Qsrc := ImagesSource( siso ); 742 smgi := MappingGeneratorsImages( siso ); 743 sinv := GroupHomomorphismByImages( Qsrc, Psrc, smgi[2], smgi[1] ); 744 riso := isos[2]; 745 Qrng := ImagesSource( riso ); 746 rmgi := MappingGeneratorsImages( riso ); 747 rinv := GroupHomomorphismByImages( Qrng, Prng, rmgi[2], rmgi[1] ); 748 if not ( ( Psrc = Source(siso) ) and ( Prng = Source(riso) ) ) then 749 Info( InfoXMod, 2, "groups of PM not sources of isomorphisms" ); 750 return fail; 751 fi; 752 Qbdy := CompositionMapping( riso, Pbdy, sinv ); 753 Pact := XModAction( PM ); 754 Paut := Range( Pact ); 755 Pautgen := GeneratorsOfGroup( Paut ); 756 Qautgen := List( Pautgen, a -> CompositionMapping( siso, a, sinv ) ); 757 Qaut := Group( Qautgen ); 758 ahom := GroupHomomorphismByImages( Paut, Qaut, Pautgen, Qautgen ); 759 Qact := CompositionMapping( ahom, Pact, rinv ); 760 QM := PreXModByBoundaryAndAction( Qbdy, Qact ); 761 iso := PreXModMorphismByGroupHomomorphisms( PM, QM, siso, riso ); 762 SetIsInjective( iso, true ); 763 SetIsSurjective( iso, true ); 764 SetImagesSource( iso, QM ); 765 if ( HasIsXMod( PM ) and IsXMod( PM ) ) then 766 SetIsXMod( QM, true ); 767 SetIsXModMorphism( iso, true ); 768 fi; 769 return iso; 770end ); 771 772############################################################################## 773## 774#M IsomorphismPerm2DimensionalGroup . . . constructs isomorphic perm pre-xmod 775#M IsomorphismPerm2DimensionalGroup . . . constructs isomorphic perm pre-cat1 776## 777InstallMethod( IsomorphismPerm2DimensionalGroup, 778 "generic method for pre-crossed modules", true, [ IsPreXMod ], 0, 779function( PM ) 780 781 local shom, rhom, Psrc, Psgen, Qsrc, Qsgen, Prng, Prgen, Qrng, Qrgen, 782 QM, iso; 783 784 if IsPermPreXMod( PM ) then 785 return IdentityMapping( PM ); 786 fi; 787 Psrc := Source( PM ); 788 if IsPermGroup( Psrc ) then 789 shom := IdentityMapping( Psrc ); 790 else 791 Psgen := GeneratorsOfGroup( Psrc ); 792 shom := IsomorphismPermGroup( Psrc ); 793 Qsrc := Image( shom ); 794 shom := shom * SmallerDegreePermutationRepresentation( Qsrc ); 795 Qsrc := ImagesSource( shom ); 796 Qsgen := List( Psgen, s -> ImageElm( shom, s ) ); 797 if HasName( Psrc ) then 798 SetName( Qsrc, Concatenation( "P", Name( Psrc ) ) ); 799 fi; 800 shom := GroupHomomorphismByImages( Psrc, Qsrc, Psgen, Qsgen ); 801 fi; 802 Prng := Range( PM ); 803 if IsPermGroup( Prng ) then 804 rhom := IdentityMapping( Prng ); 805 else 806 Prgen := GeneratorsOfGroup( Prng ); 807 rhom := IsomorphismPermGroup( Prng ); 808 Qrng := Image( rhom ); 809 rhom := rhom * SmallerDegreePermutationRepresentation( Qrng ); 810 Qrng := ImagesSource( rhom ); 811 Qrgen := List( Prgen, r -> ImageElm( rhom, r ) ); 812 if HasName( Prng ) then 813 SetName( Qrng, Concatenation( "P", Name( Prng ) ) ); 814 fi; 815 rhom := GroupHomomorphismByImages( Prng, Qrng, Prgen, Qrgen ); 816 fi; 817 iso := IsomorphismByIsomorphisms( PM, [ shom, rhom ] ); 818 QM := ImagesSource( iso ); 819 if HasName( PM ) then 820 SetName( QM, Concatenation( "P", Name( PM ) ) ); 821 fi; 822 iso := PreXModMorphism( PM, QM, shom, rhom ); 823 return iso; 824end ); 825 826InstallMethod( IsomorphismPerm2DimensionalGroup, 827 "generic method for pre-cat1-groups", true, [ IsPreCat1Group ], 0, 828function( PCG ) 829 830 local shom, rhom, Psrc, Psgen, Qsrc, Qsgen, Prng, Prgen, Qrng, Qrgen, 831 QCG, iso; 832 833 if IsPermPreCat1Group( PCG ) then 834 return IdentityMapping( PCG ); 835 fi; 836 Psrc := Source( PCG ); 837 if IsPermGroup( Psrc ) then 838 shom := IdentityMapping( Psrc ); 839 else 840 Psgen := GeneratorsOfGroup( Psrc ); 841 shom := IsomorphismPermGroup( Psrc ); 842 Qsrc := Image( shom ); 843 shom := shom * SmallerDegreePermutationRepresentation( Qsrc ); 844 Qsrc := ImagesSource( shom ); 845 Qsgen := List( Psgen, s -> ImageElm( shom, s ) ); 846 shom := GroupHomomorphismByImages( Psrc, Qsrc, Psgen, Qsgen ); 847 fi; 848 Prng := Range( PCG ); 849 if IsPermGroup( Prng ) then 850 rhom := IdentityMapping( Prng ); 851 else 852 Prgen := GeneratorsOfGroup( Prng ); 853 if IsPreCat1GroupByEndomorphisms( PCG ) then 854 rhom := RestrictedMapping( shom, Prng ); 855 else 856 rhom := IsomorphismPermGroup( Prng ); 857 Qrng := Image( rhom ); 858 rhom := rhom * SmallerDegreePermutationRepresentation( Qrng ); 859 fi; 860 Qrng := ImagesSource( rhom ); 861 Qrgen := List( Prgen, r -> ImageElm( rhom, r ) ); 862 rhom := GroupHomomorphismByImages( Prng, Qrng, Prgen, Qrgen ); 863 fi; 864 iso := IsomorphismByIsomorphisms( PCG, [ shom, rhom ] ); 865 QCG := ImagesSource( iso ); 866 if HasName( PCG ) then 867 SetName( QCG, Concatenation( "Pc", Name( PCG ) ) ); 868 fi; 869 iso := PreCat1GroupMorphism( PCG, QCG, shom, rhom ); 870 return iso; 871end ); 872 873############################################################################## 874## 875#M IsomorphismPc2DimensionalGroup . . . . . constructs isomorphic pc-pre-xmod 876#M IsomorphismPc2DimensionalGroup . . . . . constructs isomorphic pc-pre-cat1 877## 878InstallMethod( IsomorphismPc2DimensionalGroup, 879 "generic method for pre-crossed modules", true, [ IsPreXMod ], 0, 880function( PM ) 881 882 local shom, rhom, Psrc, Psgen, Qsrc, Qsgen, Prng, Prgen, Qrng, Qrgen, 883 QM, iso; 884 885 if IsPcPreXMod( PM ) then 886 return IdentityMapping( PM ); 887 fi; 888 Psrc := Source( PM ); 889 if IsPcGroup( Psrc ) then 890 shom := IdentityMapping( Psrc ); 891 else 892 Psgen := GeneratorsOfGroup( Psrc ); 893 shom := IsomorphismPcGroup( Psrc ); 894 if ( shom = fail ) then 895 return fail; 896 fi; 897 Qsrc := ImagesSource( shom ); 898 Qsgen := List( Psgen, s -> ImageElm( shom, s ) ); 899 shom := GroupHomomorphismByImages( Psrc, Qsrc, Psgen, Qsgen ); 900 fi; 901 Prng := Range( PM ); 902 if ( HasIsNormalSubgroup2DimensionalGroup(PM) 903 and IsNormalSubgroup2DimensionalGroup(PM) ) then 904 Print( "#! modify IsomorphismPc2DimensionalGroup to preserve the\n", 905 "#! property of being IsNormalSubgroup2DimensionalGroup\n" ); 906 fi; 907 if IsPcGroup( Prng ) then 908 rhom := IdentityMapping( Prng ); 909 else 910 Prgen := GeneratorsOfGroup( Prng ); 911 rhom := IsomorphismPcGroup( Prng ); 912 if ( rhom = false ) then 913 return false; 914 fi; 915 Qrng := ImagesSource( rhom ); 916 Qrgen := List( Prgen, r -> ImageElm( rhom, r ) ); 917 rhom := GroupHomomorphismByImages( Prng, Qrng, Prgen, Qrgen ); 918 fi; 919 iso := IsomorphismByIsomorphisms( PM, [ shom, rhom ] ); 920 QM := ImagesSource( iso ); 921 if HasName( PM ) then 922 SetName( QM, Concatenation( "Pc", Name( PM ) ) ); 923 fi; 924 iso := PreXModMorphism( PM, QM, shom, rhom ); 925 return iso; 926end ); 927 928InstallMethod( IsomorphismPc2DimensionalGroup, 929 "generic method for pre-cat1-groups", true, [ IsPreCat1Group ], 0, 930function( PCG ) 931 932 local shom, rhom, Psrc, Psgen, Qsrc, Qsgen, Prng, Prgen, Qrng, Qrgen, 933 QCG, iso; 934 935 if IsPcPreCat1Group( PCG ) then 936 return IdentityMapping( PCG ); 937 fi; 938 Psrc := Source( PCG ); 939 if IsPcGroup( Psrc ) then 940 shom := IdentityMapping( Psrc ); 941 else 942 Psgen := GeneratorsOfGroup( Psrc ); 943 shom := IsomorphismPcGroup( Psrc ); 944 if ( shom = fail ) then 945 return fail; 946 fi; 947 Qsrc := ImagesSource( shom ); 948 Qsgen := List( Psgen, s -> ImageElm( shom, s ) ); 949 shom := GroupHomomorphismByImages( Psrc, Qsrc, Psgen, Qsgen ); 950 fi; 951 Prng := Range( PCG ); 952 if IsPcGroup( Prng ) then 953 rhom := IdentityMapping( Prng ); 954 else 955 Prgen := GeneratorsOfGroup( Prng ); 956 rhom := IsomorphismPcGroup( Prng ); 957 if ( rhom = fail ) then 958 return fail; 959 fi; 960 Qrng := ImagesSource( rhom ); 961 Qrgen := List( Prgen, r -> ImageElm( rhom, r ) ); 962 rhom := GroupHomomorphismByImages( Prng, Qrng, Prgen, Qrgen ); 963 fi; 964 iso := IsomorphismByIsomorphisms( PCG, [ shom, rhom ] ); 965 QCG := ImagesSource( iso ); 966 if HasName( PCG ) then 967 SetName( QCG, Concatenation( "Pc", Name( PCG ) ) ); 968 fi; 969 iso := PreCat1GroupMorphism( PCG, QCG, shom, rhom ); 970 return iso; 971end ); 972 973############################################################################## 974## 975#M IsomorphismFp2DimensionalGroup . . . . . constructs isomorphic fp-pre-xmod 976#M IsomorphismFp2DimensionalGroup . . . . . constructs isomorphic fp-pre-cat1 977## 978InstallMethod( IsomorphismPc2DimensionalGroup, 979 "generic method for pre-crossed modules", true, [ IsPreXMod ], 0, 980function( PM ) 981 982 local shom, rhom, Psrc, Psgen, Qsrc, Qsgen, Prng, Prgen, Qrng, Qrgen, 983 QM, iso; 984 985 if IsFpPreXMod( PM ) then 986 return IdentityMapping( PM ); 987 fi; 988 Psrc := Source( PM ); 989 if IsFpGroup( Psrc ) then 990 shom := IdentityMapping( Psrc ); 991 else 992 Psgen := GeneratorsOfGroup( Psrc ); 993 shom := IsomorphismFpGroup( Psrc ); 994 if ( shom = fail ) then 995 return fail; 996 fi; 997 Qsrc := ImagesSource( shom ); 998 Qsgen := List( Psgen, s -> ImageElm( shom, s ) ); 999 shom := GroupHomomorphismByImages( Psrc, Qsrc, Psgen, Qsgen ); 1000 fi; 1001 Prng := Range( PM ); 1002 if ( HasIsNormalSubgroup2DimensionalGroup(PM) 1003 and IsNormalSubgroup2DimensionalGroup(PM) ) then 1004 Print( "#! modify IsomorphismFp2DimensionalGroup to preserve the\n", 1005 "#! property of being IsNormalSubgroup2DimensionalGroup\n" ); 1006 fi; 1007 if IsFpGroup( Prng ) then 1008 rhom := IdentityMapping( Prng ); 1009 else 1010 Prgen := GeneratorsOfGroup( Prng ); 1011 rhom := IsomorphismFpGroup( Prng ); 1012 if ( rhom = false ) then 1013 return false; 1014 fi; 1015 Qrng := ImagesSource( rhom ); 1016 Qrgen := List( Prgen, r -> ImageElm( rhom, r ) ); 1017 rhom := GroupHomomorphismByImages( Prng, Qrng, Prgen, Qrgen ); 1018 fi; 1019 iso := IsomorphismByIsomorphisms( PM, [ shom, rhom ] ); 1020 QM := ImagesSource( iso ); 1021 if HasName( PM ) then 1022 SetName( QM, Concatenation( "Pc", Name( PM ) ) ); 1023 fi; 1024 iso := PreXModMorphism( PM, QM, shom, rhom ); 1025 return iso; 1026end ); 1027 1028InstallMethod( IsomorphismFp2DimensionalGroup, 1029 "generic method for pre-cat1-groups", true, [ IsPreCat1Group ], 0, 1030function( PCG ) 1031 1032 local shom, rhom, Psrc, Psgen, Qsrc, Qsgen, Prng, Prgen, Qrng, Qrgen, 1033 QCG, iso; 1034 1035 if IsFpPreCat1Group( PCG ) then 1036 return IdentityMapping( PCG ); 1037 fi; 1038 Psrc := Source( PCG ); 1039 if IsFpGroup( Psrc ) then 1040 shom := IdentityMapping( Psrc ); 1041 else 1042 Psgen := GeneratorsOfGroup( Psrc ); 1043 shom := IsomorphismFpGroup( Psrc ); 1044 if ( shom = fail ) then 1045 return fail; 1046 fi; 1047 Qsrc := ImagesSource( shom ); 1048 Qsgen := List( Psgen, s -> ImageElm( shom, s ) ); 1049 shom := GroupHomomorphismByImages( Psrc, Qsrc, Psgen, Qsgen ); 1050 fi; 1051 Prng := Range( PCG ); 1052 if IsFpGroup( Prng ) then 1053 rhom := IdentityMapping( Prng ); 1054 else 1055 Prgen := GeneratorsOfGroup( Prng ); 1056 rhom := IsomorphismFpGroup( Prng ); 1057 if ( rhom = fail ) then 1058 return fail; 1059 fi; 1060 Qrng := ImagesSource( rhom ); 1061 Qrgen := List( Prgen, r -> ImageElm( rhom, r ) ); 1062 rhom := GroupHomomorphismByImages( Prng, Qrng, Prgen, Qrgen ); 1063 fi; 1064 iso := IsomorphismByIsomorphisms( PCG, [ shom, rhom ] ); 1065 QCG := ImagesSource( iso ); 1066 if HasName( PCG ) then 1067 SetName( QCG, Concatenation( "Fp", Name( PCG ) ) ); 1068 fi; 1069 iso := PreCat1GroupMorphism( PCG, QCG, shom, rhom ); 1070 return iso; 1071end ); 1072 1073############################################################################### 1074## 1075#M IsomorphismPreCat1Groups . . isomorphism between a pair of pre-cat1-groups 1076#M IsomorphismCat1Groups . . . isomorphism between a pair of cat1-groups 1077## 1078InstallMethod( IsomorphismPreCat1Groups, "generic method for 2 pre-cat1-groups", 1079 true, [ IsPreCat1Group, IsPreCat1Group ], 0, 1080function( C1, C2 ) 1081 1082 local t1, h1, e1, t2, h2, e2, G1, G2, R1, R2, phi, psi, alpha, gamma, rho; 1083 1084 G1 := Source( C1 ); 1085 G2 := Source( C2 ); 1086 if not ( G1 = G2 ) then 1087 phi := IsomorphismGroups( G1, G2 ); 1088 else 1089 phi := IdentityMapping( G1 ); 1090 fi; 1091 if ( phi = fail ) then 1092 Info( InfoXMod, 2, "G1,G2 not isomorphic" ); 1093 return fail; 1094 fi; 1095 R1 := Range( C1 ); 1096 R2 := Range( C2 ); 1097 if not ( R1 = R2 ) then 1098 psi := IsomorphismGroups( R1, R2 ); 1099 else 1100 psi := IdentityMapping( R1 ); 1101 fi; 1102 if ( psi = fail ) then 1103 Info( InfoXMod, 2, "R1,R2 not isomorphic" ); 1104 return fail; 1105 fi; 1106 t1 := TailMap( C1 ); 1107 h1 := HeadMap( C1 ); 1108 t2 := TailMap( C2 ); 1109 h2 := HeadMap( C2 ); 1110 e1 := RangeEmbedding( C1 ); 1111 e2 := RangeEmbedding( C2 ); 1112 for alpha in AutomorphismGroup( G1 ) do 1113 gamma := alpha * phi; 1114 rho := e1 * gamma * t2; 1115 if ( ( e1*gamma = rho*e2 ) and 1116 ( gamma*h2 = h1*rho ) and 1117 ( gamma*t2 = t1*rho ) ) then 1118 return PreCat1GroupMorphismByGroupHomomorphisms(C1,C2,gamma,rho); 1119 fi; 1120 od; 1121 Info( InfoXMod, 2, "no isomorphism found" ); 1122 return fail; 1123end ); 1124 1125InstallMethod( IsomorphismCat1Groups, "generic method for 2 cat1-groups", 1126 true, [ IsCat1Group, IsCat1Group ], 0, 1127function( C1, C2 ) 1128 1129 local iso, ok; 1130 1131 iso := IsomorphismPreCat1Groups( C1, C2 ); 1132 if ( iso = fail ) then 1133 return fail; 1134 fi; 1135 ok := IsCat1GroupMorphism( iso ); 1136 if not ok then 1137 Error( "found a pre-cat1 morphism which is not a cat1-morphism" ); 1138 fi; 1139 return iso; 1140end ); 1141 1142############################################################################# 1143## 1144#M Name for a pre-xmod 1145## 1146InstallMethod( Name, "method for a 2d-mapping", true, 1147 [ Is2DimensionalMapping ], 0, 1148function( mor ) 1149 1150 local nsrc, nrng, name; 1151 1152 if HasName( Source( mor ) ) then 1153 nsrc := Name( Source( mor ) ); 1154 else 1155 nsrc := "[..]"; 1156 fi; 1157 if HasName( Range( mor ) ) then 1158 nrng := Name( Range( mor ) ); 1159 else 1160 nrng := "[..]"; 1161 fi; 1162 name := Concatenation( "[", nsrc, " => ", nrng, "]" ); 1163 SetName( mor, name ); 1164 return name; 1165end ); 1166 1167############################################################################### 1168## 1169#M PreXModMorphismByGroupHomomorphisms( <P>, <Q>, <hsrc>, <hrng> ) 1170## . . . make a prexmod morphism 1171## 1172InstallMethod( PreXModMorphismByGroupHomomorphisms, 1173 "for pre-xmod, pre-xmod, homomorphism, homomorphism,", true, 1174 [ IsPreXMod, IsPreXMod, IsGroupHomomorphism, IsGroupHomomorphism ], 0, 1175function( src, rng, srchom, rnghom ) 1176 1177 local filter, fam, mor, ok, nsrc, nrng, name; 1178 1179 if not ( IsGroupHomomorphism(srchom) and IsGroupHomomorphism(rnghom) ) then 1180 Info( InfoXMod, 2, "source and range mappings must be group homs" ); 1181 return fail; 1182 fi; 1183 mor := Make2DimensionalGroupMorphism( [ src, rng, srchom, rnghom ] ); 1184 if not IsPreXModMorphism( mor ) then 1185 Info( InfoXMod, 2, "not a morphism of pre-crossed modules.\n" ); 1186 return fail; 1187 fi; 1188 if ( HasName( Source(src) ) and HasName( Range(src) ) ) then 1189 nsrc := Name( src ); 1190 else 1191 nsrc := "[..]"; 1192 fi; 1193 if ( HasName( Source(rng) )and HasName( Range(rng) ) ) then 1194 nrng := Name( rng ); 1195 else 1196 nrng := "[..]"; 1197 fi; 1198 name := Concatenation( "[", nsrc, " => ", nrng, "]" ); 1199 SetName( mor, name ); 1200 ok := IsXModMorphism( mor ); 1201 # ok := IsSourceMorphism( mor ); 1202 return mor; 1203end ); 1204 1205############################################################################## 1206## 1207#M PreCat1GroupMorphismByGroupHomomorphisms( <P>, <Q>, <hsrc>, <hrng> ) 1208## 1209InstallMethod( PreCat1GroupMorphismByGroupHomomorphisms, 1210 "for pre-cat1-group, pre-cat1-group, homomorphism, homomorphism,", true, 1211 [IsPreCat1Group,IsPreCat1Group,IsGroupHomomorphism,IsGroupHomomorphism], 0, 1212function( src, rng, srchom, rnghom ) 1213 1214 local filter, fam, mor, ok, nsrc, nrng, name; 1215 1216 mor := Make2DimensionalGroupMorphism( [ src, rng, srchom, rnghom ] ); 1217 if not ( ( mor <> fail ) and IsPreCat1GroupMorphism( mor ) ) then 1218 Info( InfoXMod, 2, "not a morphism of pre-cat1 groups\n" ); 1219 return fail; 1220 fi; 1221 if ( HasName( Source(src) ) and HasName( Range(src) ) ) then 1222 nsrc := Name( src ); 1223 else 1224 nsrc := "[..]"; 1225 fi; 1226 if ( HasName( Source(rng) ) and HasName( Range(rng) ) ) then 1227 nrng := Name( rng ); 1228 else 1229 nrng := "[..]"; 1230 fi; 1231 name := Concatenation( "[", nsrc, " => ", nrng, "]" ); 1232 SetName( mor, name ); 1233 ok := IsCat1GroupMorphism( mor ); 1234 return mor; 1235end ); 1236 1237############################################################################# 1238## 1239#M Cat1GroupMorphismByGroupHomomorphisms( <Cs>, <Cr>, <hsrc>, <hrng> ) . . . make cat1 morphism 1240## 1241InstallMethod( Cat1GroupMorphismByGroupHomomorphisms, "for 2 cat1s and 2 homomorphisms", true, 1242 [ IsCat1Group, IsCat1Group, IsGroupHomomorphism, IsGroupHomomorphism ], 0, 1243function( src, rng, srchom, rnghom ) 1244 1245 local mor, ok; 1246 1247 mor := PreCat1GroupMorphismByGroupHomomorphisms( src, rng, srchom, rnghom ); 1248 ok := not ( mor = fail ) and IsCat1GroupMorphism( mor ); 1249 if not ok then 1250 return fail; 1251 fi; 1252 return mor; 1253end ); 1254 1255############################################################################# 1256## 1257#M String, ViewString, PrintString, ViewObj, PrintObj 1258## . . . . . . . . . . . . . . . . . . . . for a morphism of pre-cat1 groups 1259## 1260InstallMethod( String, "method for a morphism of pre-cat1 groups", true, 1261 [ IsPreCat1GroupMorphism ], 0, 1262function( mor ) 1263 return( STRINGIFY( "[", String( Source(mor) ), " => ", 1264 String( Range(mor) ), "]" ) ); 1265end ); 1266 1267InstallMethod( ViewString, "method for a morphism of pre-cat1 groups", true, 1268 [ IsPreCat1GroupMorphism ], 0, String ); 1269 1270InstallMethod( PrintString, "fmethod for a morphism of pre-cat1 groups", true, 1271 [ IsPreCat1GroupMorphism ], 0, String ); 1272 1273InstallMethod( ViewObj, "method for a morphism of pre-cat1 groups", true, 1274 [ IsPreCat1GroupMorphism ], 0, 1275function( mor ) 1276 if HasName( mor ) then 1277 Print( Name( mor ), "\n" ); 1278 else 1279 Print( "[", Source( mor ), " => ", Range( mor ), "]" ); 1280 fi; 1281end ); 1282 1283InstallMethod( PrintObj, "method for a morphism of pre-cat1 groups", true, 1284 [ IsPreCat1GroupMorphism ], 0, 1285function( mor ) 1286 if HasName( mor ) then 1287 Print( Name( mor ), "\n" ); 1288 else 1289 Print( "[", Source( mor ), " => ", Range( mor ), "]" ); 1290 fi; 1291end ); 1292 1293############################################################################# 1294## 1295#M ReverseIsomorphism for a pre-cat1-group 1296## 1297InstallMethod( ReverseIsomorphism, "method for a cat1-group", true, 1298 [ IsPreCat1Group ], 0, 1299function( C1G ) 1300 1301 local rev, shom, rhom, src, gensrc, t, h, e, im; 1302 1303 rev := ReverseCat1Group( C1G ); 1304 src := Source( C1G ); 1305 gensrc := GeneratorsOfGroup( src ); 1306 t := TailMap( C1G ); 1307 h := HeadMap( C1G ); 1308 e := RangeEmbedding( C1G ); 1309 im := List( gensrc, 1310 g -> ImageElm( e, ImageElm(h,g) )*g^-1*ImageElm( e, ImageElm(t,g) ) ); 1311 shom := GroupHomomorphismByImages( src, src, gensrc, im ); 1312 rhom := IdentityMapping( Range( C1G ) ); 1313 return PreCat1GroupMorphismByGroupHomomorphisms( C1G, rev, shom, rhom ); 1314end ); 1315 1316############################################################################## 1317## 1318#M IsInjective( map ) . . . . . . . . . . . . . . for a 2Dimensional-mapping 1319## 1320InstallOtherMethod( IsInjective, 1321 "method for a 2d-mapping", true, [ Is2DimensionalMapping ], 0, 1322 map -> ( IsInjective( SourceHom( map ) ) 1323 and IsInjective( RangeHom( map ) ) ) ); 1324 1325############################################################################## 1326## 1327#M IsSurjective( map ) . . . . . . . . . . . . . . for a 2Dimensional-mapping 1328## 1329InstallOtherMethod( IsSurjective, 1330 "method for a 2d-mapping", true, [ Is2DimensionalMapping ], 0, 1331 map -> ( IsSurjective( SourceHom( map ) ) 1332 and IsSurjective( RangeHom( map ) ) ) ); 1333 1334############################################################################## 1335## 1336#M IsSingleValued( map ) . . . . . . . . . . . . . for a 2Dimensional-mapping 1337## 1338InstallOtherMethod( IsSingleValued, 1339 "method for a 2d-mapping", true, [ Is2DimensionalMapping ], 0, 1340 map -> ( IsSingleValued( SourceHom( map ) ) 1341 and IsSingleValued( RangeHom( map ) ) ) ); 1342 1343############################################################################## 1344## 1345#M IsTotal( map ) . . . . . . . . . . . . . . . . for a 2Dimensional-mapping 1346## 1347InstallOtherMethod( IsTotal, 1348 "method for a 2d-mapping", true, [ Is2DimensionalMapping ], 0, 1349 map -> ( IsTotal( SourceHom( map ) ) 1350 and IsTotal( RangeHom( map ) ) ) ); 1351 1352############################################################################## 1353## 1354#M IsBijective( map ) . . . . . . . . . . . . . . for a 2Dimensional-mapping 1355## 1356InstallOtherMethod( IsBijective, 1357 "method for a 2d-mapping", true, [ Is2DimensionalMapping ], 0, 1358 map -> ( IsBijective( SourceHom( map ) ) 1359 and IsBijective( RangeHom( map ) ) ) ); 1360 1361############################################################################## 1362## 1363#M IsEndomorphism2DimensionalDomain( map ) . . . . for a 2Dimensional-mapping 1364#? temporary fix 08/01/04 --- need to check correctness 1365#M IsAutomorphism2DimensionalDomain( map ) . . . . for a 2Dimensional-mapping 1366## 1367InstallMethod( IsEndomorphism2DimensionalDomain, 1368 "method for a 2d-mapping", true, [ Is2DimensionalMapping ], 0, 1369 map -> IsEndoMapping( SourceHom( map ) ) and 1370 IsEndoMapping( RangeHom( map ) ) ); 1371 1372InstallMethod( IsAutomorphism2DimensionalDomain, 1373 "method for a 2d-mapping", true, [ Is2DimensionalMapping ], 0, 1374 map -> IsEndomorphism2DimensionalDomain( map ) and IsBijective( map ) ); 1375 1376############################################################################## 1377## 1378#M IsSourceMorphism( mor ) . . . . . . . . . . . . . . . for an xmod morphism 1379## 1380InstallMethod( IsSourceMorphism, 1381 "method for a morphism of crossed modules", 1382 true, 1383 [ IsXModMorphism ], 0, 1384function( mor ) 1385 1386 local Srng, Rrng; 1387 1388 Srng := Range( Source( mor ) ); 1389 Rrng := Range( Range( mor ) ); 1390 return ( ( Srng = Rrng ) and 1391 ( RangeHom( mor ) = IdentityMapping( Srng ) ) ); 1392end ); 1393 1394############################################################################## 1395## 1396#M Kernel . . . . . . of morphisms of pre-crossed modules and pre-cat1-groups 1397## 1398InstallOtherMethod( Kernel, "generic method for 2d-mappings", 1399 true, [ Is2DimensionalMapping ], 0, 1400function( map ) 1401 1402 local kerS, kerR, K; 1403 1404 if HasKernel2DimensionalMapping( map ) then 1405 return Kernel2DimensionalMapping( map ); 1406 fi; 1407 kerS := Kernel( SourceHom( map ) ); 1408 kerR := Kernel( RangeHom( map ) ); 1409 K := Sub2DimensionalGroup( Source( map ), kerS, kerR ); 1410 SetKernel2DimensionalMapping( map, K ); 1411 return K; 1412end ); 1413 1414############################################################################## 1415## 1416#M PreXModBySourceHom top PreXMod from a morphism of crossed P-modules 1417## 1418InstallMethod( PreXModBySourceHom, "for a pre-crossed module morphism", 1419 true, [ IsPreXModMorphism ], 0, 1420function( mor ) 1421 1422 local X1, X2, src1, rng1, src2, rng2, bdy2, y, z, S, Sbdy, Saut, 1423 gensrc1, genrng1, gensrc2, ngrng1, ngsrc2, inn, innaut, 1424 act, images, idsrc1, idrng1, isconj; 1425 1426 X1 := Source( mor ); 1427 X2 := Range( mor ); 1428 src1 := Source( X1 ); 1429 src2 := Source( X2 ); 1430 rng1 := Range( X1 ); 1431 rng2 := Range( X2 ); 1432 idsrc1 := InclusionMappingGroups( src1, src1 ); 1433 idrng1 := InclusionMappingGroups( rng1, rng1 ); 1434 1435 if not ( rng1 = rng2 ) 1436 or not ( RangeHom( mor ) = idrng1 ) then 1437 Info( InfoXMod, 2, 1438 "Not a morphism of crossed modules having a common range" ); 1439 return fail; 1440 fi; 1441 gensrc1 := GeneratorsOfGroup( src1 ); 1442 genrng1 := GeneratorsOfGroup( rng1 ); 1443 gensrc2 := GeneratorsOfGroup( src2 ); 1444 ngrng1 := Length( genrng1 ); 1445 ngsrc2 := Length( gensrc2 ); 1446 bdy2 := Boundary( X2 ); 1447 innaut := [ ]; 1448 for y in gensrc2 do 1449 z := ImageElm( bdy2, y ); 1450 images := List( gensrc1, x -> x^z ); 1451 inn := GroupHomomorphismByImages( src1, src1, gensrc1, images ); 1452 Add( innaut, inn ); 1453 od; 1454 Saut := Group( innaut, idsrc1 ); 1455 act := GroupHomomorphismByImages( src2, Saut, gensrc2, innaut ); 1456 S := XModByBoundaryAndAction( SourceHom( mor ), act ); 1457 isconj := IsNormalSubgroup2DimensionalGroup( S ); 1458 return S; 1459end ); 1460 1461############################################################################ 1462## 1463#M XModMorphismOfCat1GroupMorphism 1464#M Cat1GroupMorphismOfXModMorphism 1465## 1466InstallMethod( XModMorphismOfCat1GroupMorphism, "for a cat1-group morphism", 1467 true, [ IsCat1GroupMorphism ], 0, 1468function( phi ) 1469 1470 local C1, C2, C1src, genC1src, e2, t2, proj2, 1471 X1, X2, X1src, X1rng, X2src, X2rng, 1472 genX1src, genX1rng, ek1, eksrc1, sphi, rphi, x, 1473 imrphi, imsphi, im, images, smor, mor, info1, info2; 1474 1475 C1 := Source( phi ); 1476 C2 := Range( phi ); 1477 C1src := Source( C1 ); 1478 X1 := XModOfCat1Group( C1 ); 1479 X2 := XModOfCat1Group( C2 ); 1480 X1src := Source( X1 ); 1481 X1rng := Range( X1 ); 1482 X2src := Source( X2 ); 1483 X2rng := Range( X2 ); 1484 ek1 := KernelEmbedding( C1 ); 1485 t2 := TailMap( C2 ); 1486 e2 := RangeEmbedding( C2 ); 1487 proj2 := Projection( Source( C2 ) ); 1488 genC1src := GeneratorsOfGroup( C1src ); 1489 genX1src := GeneratorsOfGroup( X1src ); 1490 genX1rng := GeneratorsOfGroup( X1rng ); 1491 sphi := SourceHom( phi ); 1492 rphi := RangeHom( phi ); 1493 imrphi := List( genX1rng, r -> ImageElm( rphi, r ) ); 1494# imgen := List( gensrc1, x -> SemidirectProductElement( (), (), x ) ); 1495 eksrc1 := List( genX1src, s -> ImageElm( ek1, s ) ); 1496 imsphi := List( eksrc1, g -> ImageElm( sphi, g ) ); 1497 im := List( imsphi, x -> ImageElm( sphi, x ) ); 1498 images := List( im, 1499 x -> ImageElm( proj2, ImageElm(e2,ImageElm(t2,x^-1)) * x ) ); 1500 smor := GroupHomomorphismByImages( X1src, X2src, genX1src, images ); 1501 mor := XModMorphismByGroupHomomorphisms( X1, X2, smor, rphi ); 1502 SetXModMorphismOfCat1GroupMorphism( phi, mor ); 1503 SetCat1GroupMorphismOfXModMorphism( mor, phi ); 1504 return mor; 1505end ); 1506 1507InstallMethod( Cat1GroupMorphismOfXModMorphism, "for an xmod morphism", 1508 true, [ IsXModMorphism ], 0, 1509function( mor ) 1510 1511 local X1, X2, rec1, rec2, C1, C2, G1, G2, smor, rmor, semb1, remb1, 1512 semb2, remb2, isemb1, iremb1, geneS1, geneR1, genG1, imeS1, imeR1, 1513 imsphi, sphi, phi; 1514 1515 X1 := Source( mor ); 1516 X2 := Range( mor ); 1517 rec1 := PreCat1GroupOfPreXMod( X1 ); 1518 rec2 := PreCat1GroupOfPreXMod( X2 ); 1519 C1 := rec1.precat1; 1520 C2 := rec2.precat1; 1521 G1 := Source( C1 ); 1522 G2 := Source( C2 ); 1523 smor := SourceHom( mor ); 1524 rmor := RangeHom( mor ); 1525 semb1 := rec1.xmodSourceEmbeddingIsomorphism; 1526 remb1 := rec1.xmodRangeEmbeddingIsomorphism; 1527 semb2 := rec2.xmodSourceEmbeddingIsomorphism; 1528 remb2 := rec2.xmodRangeEmbeddingIsomorphism; 1529 isemb1 := RestrictedInverseGeneralMapping( semb1 ); 1530 iremb1 := RestrictedInverseGeneralMapping( remb1 ); 1531 geneS1 := GeneratorsOfGroup( rec1.xmodSourceEmbedding ); 1532 geneR1 := GeneratorsOfGroup( rec1.xmodRangeEmbedding ); 1533 genG1 := Concatenation( geneR1, geneS1 ); 1534 imeS1 := List( geneS1, s -> ImageElm( semb2, 1535 ImageElm( smor, 1536 ImageElm( isemb1, s ) ) ) ); 1537 imeR1 := List( geneR1, r -> ImageElm( remb2, 1538 ImageElm( rmor, 1539 ImageElm( iremb1, r ) ) ) ); 1540 imsphi := Concatenation( imeR1, imeS1 ); 1541 sphi := GroupHomomorphismByImages( G1, G2, genG1, imsphi ); 1542 phi := Cat1GroupMorphismByGroupHomomorphisms( C1, C2, sphi, rmor ); 1543 SetCat1GroupMorphismOfXModMorphism( mor, phi ); 1544 SetXModMorphismOfCat1GroupMorphism( phi, mor ); 1545 return phi; 1546end ); 1547 1548############################################################################## 1549## 1550#F SmallerDegreePerm2DimensionalGroup( <obj> ) 1551## 1552InstallGlobalFunction( SmallerDegreePerm2DimensionalGroup, function( obj ) 1553 1554 local src, rng, sigma, rho, mor; 1555 1556 # for a PreXMod 1557 if ( IsPreXMod( obj ) and IsPermPreXMod( obj ) ) then 1558 src := Source( obj ); 1559 rng := Range( obj ); 1560 sigma := SmallerDegreePermutationRepresentation( src ); 1561 rho := SmallerDegreePermutationRepresentation( rng ); 1562 mor := IsomorphismByIsomorphisms( obj, [ sigma, rho ] ); 1563 return mor; 1564 fi; 1565 # alternatives not allowed 1566 Info( InfoXMod, 2, "at present only implemented for a PermPreXMod" ); 1567 return fail; 1568end ); 1569 1570############################################################################## 1571## 1572#M IsomorphismXModByNormalSubgroup 1573## 1574InstallMethod( IsomorphismXModByNormalSubgroup, 1575 "for xmod with injective boundary", true, [ IsXMod ], 0, 1576function( X0 ) 1577 1578 local S0, R, S1, bdy0, sigma, rho, ok; 1579 1580 S0 := Source( X0 ); 1581 R := Range( X0 ); 1582 bdy0 := Boundary( X0 ); 1583 if not IsInjective( bdy0 ) then 1584 Info( InfoXMod, 2, "boundary is not injective" ); 1585 return fail; 1586 fi; 1587 if IsSubgroup( S0, R ) then 1588 return IdentityMapping( X0 ); 1589 else 1590 S1 := ImagesSource( bdy0 ); 1591 sigma := GeneralRestrictedMapping( bdy0, S0, S1 ); 1592 rho := IdentityMapping( R ); 1593 ok := IsBijective( sigma ) and IsBijective( rho ); 1594 return IsomorphismByIsomorphisms( X0, [ sigma, rho ] ); 1595 fi; 1596end ); 1597 1598############################################################################## 1599## 1600#M Order . . . . . . . . . . . . . . . . . . . . . for a 2Dimensional-mapping 1601## 1602InstallOtherMethod( Order, "generic method for 2d-mapping", 1603 true, [ Is2DimensionalMapping ], 0, 1604function( mor ) 1605 if not ( IsEndomorphism2DimensionalDomain( mor ) 1606 and IsBijective( mor ) ) then 1607 Info( InfoXMod, 2, "mor is not an automorphism" ); 1608 return fail; 1609 fi; 1610 return Lcm( Order( SourceHom( mor ) ), Order( RangeHom( mor ) ) ); 1611end ); 1612 1613############################################################################# 1614## 1615#M ImagesSource( <mor> ) . . . . . . . . for pre-xmod and pre-cat1 morphisms 1616## 1617InstallOtherMethod( ImagesSource, "image for a pre-xmod or pre-cat1 morphism", 1618 true, [ Is2DimensionalMapping ], 0, 1619function( mor ) 1620 1621 local Shom, Rhom, imS, imR, sub; 1622 1623 Shom := SourceHom( mor ); 1624 Rhom := RangeHom( mor ); 1625 imS := ImagesSource( Shom ); 1626 imR := ImagesSource( Rhom ); 1627 sub := Sub2DimensionalGroup( Range(mor), imS, imR ); 1628 return sub; 1629end ); 1630 1631############################################################################### 1632## 1633#M AllCat1GroupMorphisms . . . . . . morphisms from one cat1-group to another 1634## 1635InstallMethod( AllCat1GroupMorphisms, "for two cat1-groups", true, 1636 [ IsCat1Group, IsCat1Group ], 0, 1637function( C1G1, C1G2 ) 1638 1639 local G1, R1, G2, R2, homG, homR, mors, gamma, rho, mor; 1640 1641 G1 := Source( C1G1 ); 1642 R1 := Range( C1G1 ); 1643 G2 := Source( C1G2 ); 1644 R2 := Range( C1G2 ); 1645 homG := AllHomomorphisms( G1, G2 ); 1646 homR := AllHomomorphisms( R1, R2 ); 1647 mors := [ ]; 1648 for gamma in homG do 1649 for rho in homR do 1650 mor := PreCat1GroupMorphismByGroupHomomorphisms( 1651 C1G1, C1G2, gamma, rho ); 1652 if ( not( mor = fail ) and IsCat1GroupMorphism( mor ) ) then 1653 Add( mors, mor ); 1654 fi; 1655 od; 1656 od; 1657 return mors; 1658end ); 1659