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 isoclinic.gi GAP4 package `XMod' Alper Odabas #W & Enver Uslu #Y Copyright (C) 2001-2017, Chris Wensley et al #Y ## This file contains generic methods for finding isoclinism classes ## of crossed modules. ## ############################################################################# ## #M FixedPointSubgroupXMod . . . . elements of the range fixed by the source ## InstallMethod( FixedPointSubgroupXMod, "generic method for precrossed modules", true, [ IsPreXMod, IsGroup, IsGroup ], 0, function( XM, T, Q ) local genQ, act, ext, orb, elts, fix, gens; if not ( IsSubgroup( Source(XM), T ) and IsSubgroup( Range(XM), Q ) ) then Error( "T,Q not subgroups of S,R" ); fi; genQ := GeneratorsOfGroup( Q ); act := XModAction( XM ); ext := ExternalSet( Q, T, genQ, List( genQ, g -> Image(act,g) ) ); orb := Orbits( ext ); elts := Concatenation( Filtered( orb, o -> Length(o) = 1) ); fix := Subgroup( T, elts ); gens := SmallGeneratingSet( fix ); return Subgroup( T, gens ); end ); ############################################################################# ## #M StabilizerSubgroupXMod . . . . elements of Q<=R which fix T<=S pointwise ## InstallMethod( StabilizerSubgroupXMod, "generic method for a crossed module and subgroups of source, range", true, [ IsPreXMod, IsGroup, IsGroup ], 0, function( XM, T, Q ) local alpha, sonuc, t, q, list, sgp; if not ( IsSubgroup( Source(XM), T ) and IsSubgroup( Range(XM), Q ) ) then Error( "T,Q not subgroups of S,R" ); fi; alpha := XModAction( XM ); list := []; for q in Q do if ForAll( T, t -> Image(Image(alpha,q),t)=t ) then Add( list, q ); fi; od; ## if the lists consist only the identity element then there is a bug ## in the function AsMagma. if ( Length( Set(list) ) = 1 ) then return TrivialSubgroup( Q ); fi; sgp := Subgroup( Q, list ); sgp := Subgroup( Q, SmallGeneratingSet(sgp) ); return sgp; end ); ############################################################################# ## #M CentreXMod . . . . . . . . . the centre of a crossed module ## InstallMethod( CentreXMod, "generic method for crossed modules", true, [ IsXMod ], 0, function( XM ) local T, G, K, fix; T := Source( XM ); G := Range( XM ); K := Intersection( Centre(G), StabilizerSubgroupXMod( XM, T, G ) ); fix := FixedPointSubgroupXMod( XM, T, G ); return SubXMod( XM, fix, K ); end ); ############################################################################# ## #M Centralizer . . . . . . . . for a subcrossed module of a crossed module ## InstallOtherMethod( Centralizer, "generic method for crossed modules", true, [ IsXMod, IsXMod ], 0, function( XM, YM ) local srcX, rngY, genR, actY, ext, orb, elts, fix, gens, srcC, rngC; if not IsSubXMod( XM, YM ) then Error( "YM is not a subcrossed module of XM" ); fi; srcX := Source( XM ); rngY := Range( YM ); genR := GeneratorsOfGroup( rngY ); actY := XModAction( YM ); ext := ExternalSet( rngY, srcX, genR, List( genR, g -> Image(actY,g) ) ); orb := Orbits( ExternalSetXMod( XM ) ); elts := Concatenation( Filtered( orb, o -> Length(o) = 1) ); fix := Subgroup( srcX, elts ); gens := SmallGeneratingSet( fix ); srcC := Subgroup( srcX, gens ); rngC := Intersection( StabilizerSubgroupXMod( XM, srcX, rngY ), Centralizer( Range( XM ), rngY ) ); if ( srcC = srcX ) then srcC := srcX; if ( rngC = Range( XM ) ) then return XM; fi; fi; return SubXMod( XM, srcC, rngC ); end ); ############################################################################# ## #M Displacement ## InstallMethod( Displacement, "generic method for hom, element, element", true, [ IsGroupHomomorphism, IsObject, IsObject ], 0, function( alpha, r, s ) local a; if not ( r in Source(alpha) ) then Error( "r not in Source(alpha)" ); fi; a := Image( alpha, r ); if not ( ( Range(a) = Source(a) ) and ( s in Source(a) ) ) then Error( "alpha not an automorphism of group containing s" ); fi; return Image( a, s^-1 ) * s; end ); ############################################################################# ## #M DisplacementSubgroup . . . subgroup of source generated by displacements ## InstallMethod( DisplacementSubgroup, "generic method for crossed modules", true, [ IsXMod ], 0, function( XM ) local alpha, alp, sonuc, T, G, t, t0, g, list, one; T := Source( XM ); G := Range( XM ); alpha := XModAction( XM ); list := []; one := One( T ); for g in GeneratorsOfGroup( G ) do alp := Image( alpha, g ); for t in GeneratorsOfGroup( T ) do t0 := Image( alp, t^-1 ) * t; if ( ( t0 <> one ) and ( Position(list,t0) = fail ) ) then Add( list, t0 ); fi; od; od; if ( Length( Set(list) ) = 0 ) then list := [ one ]; fi; sonuc := Subgroup( T, list ); return Subgroup( T, SmallGeneratingSet( sonuc ) ); end ); ############################################################################# ## #M Normalizer . . . . . . . . . for a subcrossed module of a crossed module ## InstallOtherMethod( Normalizer, "generic method for crossed modules", true, [ IsXMod, IsXMod ], 0, function( XM, YM ) local act, T, G, S, H, t, h, d, pos, elts, gens, srcN, rngN; if not IsSubXMod( XM, YM ) then Error( "YM is not a subcrossed module of XM" ); fi; elts := [ ]; act := XModAction( XM ); T := Source( XM ); G := Range( XM ); S := Source( YM ); H := Range( YM ); ## is there a more efficient method, just using generators? for t in T do for h in H do d := Displacement( act, h, t ); if ( d in S ) then pos := Position( elts, d ); if ( pos = fail ) then Add( elts, d ); fi; fi; od; od; srcN := Subgroup( S, elts ); gens := SmallGeneratingSet( srcN ); srcN := Subgroup( S, gens ); rngN := Intersection( Normalizer( G, H ), StabilizerSubgroupXMod( XM, S, G ) ); rngN := Subgroup( G, SmallGeneratingSet( rngN ) ); return SubXMod( XM, srcN, rngN ); end ); ############################################################################# ## #M CrossActionSubgroup . . . . . . . . . source group for CommutatorSubXMod ## InstallMethod( CrossActionSubgroup, "generic method for two normal subxmods", true, [ IsXMod, IsXMod, IsXMod ], 0, function( TG, SH, RK ) local alpha, alp, T, s, s0, k, r, r0, h, list, one, cas; ## if not ( IsSub2DimensionalDomain(TG,SH) ## and IsSub2DimensionalDomain(TG,RK) ) then ## Error( "SH,RK not subcrossed modules of TG" ); ## fi; T := Source(TG); alpha := XModAction(TG); list := []; one := One( T ); for k in GeneratorsOfGroup( Range(RK) ) do alp := Image( alpha, k ); for s in GeneratorsOfGroup( Source(SH) ) do s0 := s^-1 * Image( alp, s ); if ( ( s0 <> one ) and ( Position(list,s0) = fail ) ) then Add( list, s0 ); fi; od; od; for h in GeneratorsOfGroup( Range(SH) ) do alp := Image( alpha, h ); for r in GeneratorsOfGroup( Source(RK) ) do r0 := Image( alp, r^-1 ) * r; if ( ( r0 <> one ) and ( Position(list,r0) = fail ) ) then Add( list, r0 ); fi; od; od; if ( Length( Set(list) ) = 0 ) then list := [ one ]; fi; cas := Subgroup( T, list ); cas := Subgroup( T, SmallGeneratingSet( cas ) ); return cas; end ); ############################################################################# ## #M IntersectionSubXMods . . . . intersection of subcrossed modules SH and RK ## InstallMethod( IntersectionSubXMods, "generic method for crossed modules", true, [ IsXMod, IsXMod, IsXMod ], 0, function( XM, SH, RK) local alpha, T, G, S, H, R, K, bdy, k_bdy, k_alpha, SR, HK; T := Source( XM ); G := Range( XM ); alpha := XModAction( XM ); bdy := Boundary( XM ); S := Source(SH); H := Range(SH); R := Source(RK); K := Range(RK); SR := Intersection(S,R); HK := Intersection(H,K); return SubXMod(XM,SR,HK); end ); ############################################################################# ## #M NaturalMorphismByNormalSubPreXMod . . . . . the quotient prexmod morphism ## InstallMethod( NaturalMorphismByNormalSubPreXMod, "generic method for crossed modules", true, [ IsPreXMod, IsPreXMod ], 0, function( XM, SM ) local actX, bdyX, nhomQ, nhomF, T, G, S, H, Q, F, sgQ, sgF, imbdy, bdy, lenF, psgQ, psgF, asgF, i, autF, aut, act, FM; if not IsNormal( XM, SM ) then Error( "not a normal subcrossed module" ); fi; actX := XModAction( XM ); bdyX := Boundary( XM ); T := Source( XM ); S := Source( SM ); nhomQ := NaturalHomomorphismByNormalSubgroup( T, S ); Q := ImagesSource( nhomQ ); sgQ := SmallGeneratingSet( Q ); Q := GroupWithGenerators( sgQ, One(Q) ); # T/S bölüm grubu psgQ := List( sgQ, q -> PreImagesRepresentative( nhomQ, q ) ); G := Range( XM ); H := Range( SM ); if IsTrivial( H ) then F := G; nhomF := IdentityMapping( G ); sgF := SmallGeneratingSet( G ); psgF := SmallGeneratingSet( G ); else nhomF := NaturalHomomorphismByNormalSubgroup( G, H ); F := ImagesSource( nhomF ); sgF := SmallGeneratingSet( F ); F := GroupWithGenerators( sgF, One(F) ); # G/H bölüm grubu psgF := List( sgF, f -> PreImagesRepresentative( nhomF, f ) ); fi; imbdy := List( sgQ, q -> Image( nhomF, Image( bdyX, PreImagesRepresentative( nhomQ, q ) ) ) ); bdy := GroupHomomorphismByImages( Q, F, sgQ, imbdy ); lenF := Length( psgF ); asgF := List( psgF, g -> Image( actX, g ) ); autF := ListWithIdenticalEntries( lenF, 0 ); for i in [1..lenF] do autF[i] := GroupHomomorphismByImages( Q, Q, sgQ, List( psgQ, t -> Image( nhomQ, Image(asgF[i],t) ) ) ); od; if ( lenF = 0 ) then aut := Group( IdentityMapping( Q ) ); else aut := Group( autF ); fi; SetIsGroupOfAutomorphisms( aut, true ); act := GroupHomomorphismByImages( F, aut, sgF, autF ); FM := XModByBoundaryAndAction( bdy, act ); if ( HasName( XM ) and HasName( SM ) ) then SetName( FM, Concatenation( Name( XM ), "/", Name( SM ) ) ); fi; return PreXModMorphismByHoms( XM, FM, nhomQ, nhomF ); end ); ############################################################################# ## #M FactorPreXMod . . . . . . . . . . . . . . the quotient precrossed module ## InstallMethod( FactorPreXMod, "generic method for precrossed modules", true, [ IsPreXMod, IsPreXMod ], 0, function( XM, SM ) local nat, FM; nat := NaturalMorphismByNormalSubPreXMod( XM, SM ); FM := Range( nat ); SetProjectionOfFactorPreXMod( FM, nat ); return FM; end ); ############################################################################# ## #M DerivedSubXMod . . . . . . . . . . the commutator of the crossed module ## InstallMethod( DerivedSubXMod, "generic method for crossed modules", true, [ IsXMod ], 0, function( XM ) local D, dgt; D := DerivedSubgroup( Range( XM ) ); dgt := DisplacementSubgroup( XM ); return SubXMod( XM, dgt, D ); end ); ############################################################################# ## #M CommutatorSubXMod . . . . . . . commutator subxmod of two normal subxmods ## InstallMethod( CommutatorSubXMod, "generic method for crossed modules", true, [ IsXMod, IsXMod, IsXMod ], 0, function( TG, SH, RK ) local cas, com; cas := CrossActionSubgroup( TG, SH, RK ); com := CommutatorSubgroup( Range(SH), Range(RK) ); return SubXMod( TG, cas, com ); end ); ############################################################################# ## #M LowerCentralSeries . . . . . . . . . the lower central series of an xmod ## InstallOtherMethod( LowerCentralSeries, "generic method for crossed modules", true, [ IsXMod ], 0, function( XM ) local list, C; list := [ XM ]; C := DerivedSubXMod( XM ); while ( C <> list[ Length(list) ] ) do Add( list, C ); C := CommutatorSubXMod( XM, C, XM ); od; return list; end ); ############################################################################# ## #M IsAbelian2DimensionalGroup . . . . check that a crossed module is abelian ## InstallMethod( IsAbelian2DimensionalGroup, "generic method for crossed modules", true, [ IsXMod ], 0, function( XM ) return ( XM = CentreXMod( XM ) ); end ); ############################################################################# ## #M IsAspherical2DimensionalGroup . check that a crossed module is aspherical ## InstallMethod( IsAspherical2DimensionalGroup, "generic method for crossed modules", true, [ IsXMod ], 0, function( XM ) return ( Size( Kernel( Boundary( XM ) ) ) = 1 ); end ); ############################################################################# ## #M IsSimplyConnected2DimensionalGroup . . check an xmod is simply connected ## InstallMethod( IsSimplyConnected2DimensionalGroup, "generic method for crossed modules", true, [ IsXMod ], 0, function( XM ) return ( Size( CoKernel( Boundary( XM ) ) ) = 1 ); end ); ############################################################################# ## #M IsFaithful2DimensionalGroup . . . check that a crossed module is faithful ## InstallMethod( IsFaithful2DimensionalGroup, "generic method for crossed modules", true, [ IsXMod ], 0, function( XM ) return ( Size( StabilizerSubgroupXMod( XM, Source( XM ), Range( XM ) ) ) = 1 ); end ); ############################################################################# ## #M IsNilpotent2DimensionalGroup . . . . . . check that an xmod is nilpotent ## InstallMethod( IsNilpotent2DimensionalGroup, "generic method for crossed modules", true, [ IsXMod ], 0, function( XM ) local S, n, sonuc; S := LowerCentralSeries( XM ); n := Length(S); if ( Size(S[n]) = [1,1] ) then sonuc := true; else sonuc := false; fi; return sonuc; end ); ############################################################################# ## #M NilpotencyClassOf2DimensionalGroup . nilpotency degree of a crossed module ## InstallMethod( NilpotencyClassOf2DimensionalGroup, "generic method for crossed modules", true, [ IsXMod ], 0, function( XM ) if not IsNilpotent2DimensionalGroup( XM ) then return 0; else return Length( LowerCentralSeries( XM ) ) - 1; fi; end ); ############################################################################# ## #M IsomorphismXMods . . check that the given crossed modules are isomorphic ## InstallMethod( IsomorphismXMods, "generic method for crossed modules", true, [ Is2DimensionalGroup, Is2DimensionalGroup ], 0, function(XM1,XM2) local T1, G1, T2, G2, isoT, isoG, iterT, iterG, alp, ph, mor; T1 := Source(XM1); G1 := Range(XM1); T2 := Source(XM2); G2 := Range(XM2); isoT := IsomorphismGroups(T1,T2); isoG := IsomorphismGroups(G1,G2); if ( ( isoT = fail ) or ( isoG = fail ) ) then return fail; fi; iterT := Iterator( AllAutomorphisms( T2 ) ); while not IsDoneIterator( iterT ) do iterG := Iterator( AllAutomorphisms( G2 ) ); alp := isoT * NextIterator( iterT ); while not IsDoneIterator( iterG ) do ph := isoG * NextIterator( iterG ); mor := Make2DimensionalGroupMorphism( [ XM1, XM2, alp, ph ] ); if ( not( mor = fail ) and IsPreXModMorphism( mor ) and IsXModMorphism( mor ) ) then return mor; fi; od; od; return fail; end ); ############################################################################# ## #M AllXModsWithGroups . . . . . . . . all xmods with given source and range ## InstallMethod( AllXModsWithGroups, "generic method for a pair of groups", true, [ IsGroup, IsGroup ], 0, function( T, G ) local list, A, itTG, itGA, b1, a1, obj; list := [ ]; A := AutomorphismGroup(T); itTG := Iterator( AllHomomorphisms(T,G) ); while not IsDoneIterator( itTG ) do b1 := NextIterator( itTG ); itGA := Iterator( AllHomomorphisms(G,A) ); while not IsDoneIterator( itGA ) do a1 := NextIterator( itGA ); obj := PreXModObj( b1, a1 ); if ( IsPreXMod( obj ) and IsXMod( obj ) ) then Add( list, obj ); fi; od; od; return list; end ); InstallMethod( AllXModsWithGroups0, "generic method for a pair of groups", true, [ IsGroup, IsGroup ], 0, function( T, G ) local list, A, allTG, allGA, b1, a1, obj; list := [ ]; A := AutomorphismGroup(T); allTG := AllHomomorphisms(T,G); allGA := AllHomomorphisms(G,A); for b1 in allTG do for a1 in allGA do obj := PreXModObj( b1, a1 ); if ( IsPreXMod( obj ) and IsXMod( obj ) ) then Add( list, obj ); fi; od; od; return list; end ); InstallMethod( AllXModsWithGroups1, "generic method for a pair of groups", true, [ IsGroup, IsGroup ], 0, function( T, G ) local list, A, itTG, itGA, b1, a1, obj; list := [ ]; A := AutomorphismGroup(T); itTG := Iterator( AllHomomorphismClasses(T,G) ); while not IsDoneIterator( itTG ) do b1 := NextIterator( itTG ); itGA := Iterator( AllHomomorphisms(G,A) ); while not IsDoneIterator( itGA ) do a1 := NextIterator( itGA ); obj := PreXModObj( b1, a1 ); if ( IsPreXMod( obj ) and IsXMod( obj ) ) then Add( list, obj ); fi; od; od; return list; end ); InstallMethod( AllXModsWithGroups2, "generic method for a pair of groups", true, [ IsGroup, IsGroup ], 0, function( T, G ) local list, A, itTG, itGA, b1, a1, obj; list := [ ]; A := AutomorphismGroup(T); itTG := Iterator( AllHomomorphisms(T,G) ); while not IsDoneIterator( itTG ) do b1 := NextIterator( itTG ); itGA := Iterator( AllHomomorphismClasses(G,A) ); while not IsDoneIterator( itGA ) do a1 := NextIterator( itGA ); obj := PreXModObj( b1, a1 ); if ( IsPreXMod( obj ) and IsXMod( obj ) ) then Add( list, obj ); fi; od; od; return list; end ); InstallMethod( AllXModsWithGroups3, "generic method for a pair of groups", true, [ IsGroup, IsGroup ], 0, function( T, G ) local list, A, itTG, itGA, b1, a1, obj; list := [ ]; A := AutomorphismGroup(T); itTG := Iterator( AllHomomorphismClasses(T,G) ); while not IsDoneIterator( itTG ) do b1 := NextIterator( itTG ); itGA := Iterator( AllHomomorphismClasses(G,A) ); while not IsDoneIterator( itGA ) do a1 := NextIterator( itGA ); obj := PreXModObj( b1, a1 ); if ( IsPreXMod( obj ) and IsXMod( obj ) ) then Add( list, obj ); fi; od; od; return list; end ); ############################################################################# ## #F AllXMods( <T>, <G> ) xmods with given source and range #F AllXMods( <size> ) xmods with a given size #F AllXMods( <order> ) xmods whose cat1-group has a given order ## InstallGlobalFunction( AllXMods, function( arg ) local nargs, a, list, s1, j1, s2, j2, T, G, sizes; nargs := Length( arg ); if ( nargs = 2 ) then ## given source and range if ( IsGroup( arg[1] ) and IsGroup( arg[2] ) ) then return AllXModsWithGroups( arg[1], arg[2] ); fi; elif ( nargs = 1 ) then a := arg[1]; ## given size if ( IsList(a) and (Length(a)=2) and IsInt(a[1]) and IsInt(a[2]) ) then list := [ ]; s1 := NumberSmallGroups( a[1] ); for j1 in [1..s1] do T := SmallGroup( a[1], j1 ); s2 := NumberSmallGroups( a[2] ); for j2 in [1..s2] do G := SmallGroup( a[2], j2 ); Append( list, AllXModsWithGroups( T, G ) ); od; od; return list; ## given total size elif IsInt(a) then sizes := List( DivisorsInt(a), d -> [d,a/d] ); list := [ ]; for s1 in sizes do Append( list, AllXMods( s1 ) ); od; return list; fi; fi; Error( "standard usage: AllXMods(S,R), AllXMods([n,m]), AllXMods(n)" ); end ); ############################################################################# ##### FUNCTIONS FOR ISOCLINISM OF GROUPS ##### ############################################################################# ############################################################################# ## #M IsStemDomain . . . check that the centre is a subgroup of the derived group ## InstallMethod( IsStemDomain, "generic method for groups", true, [ IsGroup ], 0, function(G) return IsSubgroup( DerivedSubgroup(G), Centre(G) ); end ); ############################################################################# ## #M AllStemGroupIds . . . list of all IdGroup's of stem groups of chosen order ## InstallMethod( AllStemGroupIds, "generic method for posint", true, [ IsPosInt ], 0, function(a) local g, i, j, sonuc, sayi; sonuc := [ ]; for g in AllSmallGroups( a ) do if IsStemDomain( g ) then Add( sonuc, IdGroup( g ) ); fi; od; return sonuc; end ); ############################################################################# ## #M AllStemGroupFamilies . . . split stem groups of chosen order into families ## InstallMethod( AllStemGroupFamilies, "generic method for posint", true, [ IsPosInt ], 0, function(a) local ids, len, found, id, gi, g, i, j, sonuc, new, sayi; ids := AllStemGroupIds( a ); len := Length( ids ); found := ListWithIdenticalEntries( len, false ); sonuc := [ ]; for i in [1..len] do if not found[i] then found[i] := true; id := ids[i]; new := [ id ]; gi := SmallGroup( id ); for j in [i+1..len] do if not found[j] then if AreIsoclinicDomains( gi, SmallGroup( ids[j] ) ) then found[j] := true; Add( new, ids[j] ); fi; fi; od; Add( sonuc, ShallowCopy( new ) ); fi; od; return sonuc; end ); ############################################################################# ## #M CentralQuotient . . . . . . . . . . . . . . . . . . . . (G -> G/Z(G)) ## InstallMethod( CentralQuotient, "generic method for groups", true, [ IsGroup ], 0, function( G ) local ZG, Q, nat, XQ; ZG := Centre( G ); Q := FactorGroup( G, ZG ); if HasName(G) then if not HasName(ZG) then SetName( ZG, Concatenation( "Z(", Name(G), ")" ) ); fi; SetName( Q, Concatenation( Name(G), "/", Name(ZG) ) ); fi; nat := NaturalHomomorphismByNormalSubgroup( G, ZG ); XQ := XModByCentralExtension( nat ); return XQ; end ); InstallOtherMethod( CentralQuotient, "generic method for crossed modules", true, [ IsXMod ], 0, function( XM ) local act, ZM, QM, ul, ur, dl, dr, nat, up, dn, gdl, gdr, iul, adg, prod, proj1, proj2, map, xp, CrossedSquare; act := XModAction( XM ); ZM := CentreXMod( XM ); QM := FactorPreXMod( XM, ZM ); ul := Source( XM ); dl := Range( XM ); ur := Source( QM ); dr := Range( QM ); if ( HasName( XM ) and not HasName(ZM) ) then SetName( ZM, Concatenation( "Z(", Name( XM ), ")" ) ); fi; nat := NaturalMorphismByNormalSubPreXMod( XM, ZM ); up := XModByCentralExtension( SourceHom(nat) ); dn := XModByCentralExtension( RangeHom(nat) ); gdl := GeneratorsOfGroup( dl ); gdr := List( gdl, r -> Image( Boundary(dn), r ) ); iul := List( gdl, r -> Image( act, r ) ); adg := GroupHomomorphismByImages( dr, Range(act), gdr, iul ); prod := DirectProduct( dl, ur ); proj1 := Projection( prod, 1 ); proj2 := Projection( prod, 2 ); map := MappingByFunction( prod, ul, function(c) local a,s; a := Image( act, Image(proj1,c) ); s := PreImagesRepresentative( Boundary(up), Image(proj2,c) ); return Image(a,s^-1)*s; end ); xp := CrossedPairingObj( [dl,ur], ul, map ); CrossedSquare := PreCrossedSquareObj( up, XM, dn, QM, adg, xp ); SetIsCrossedSquare( CrossedSquare, true ); if HasName( XM ) then SetName( QM, Concatenation( Name( XM ), "/", Name(ZM) ) ); fi; return CrossedSquare; end ); ############################################################################# ## #M AreIsoclinicDomains . . . . . . . . . . . for two domains: groups or xmods ## InstallMethod( AreIsoclinicDomains, "generic method for two groups or xmods", true, [ IsDomain, IsDomain ], 0, function( D1, D2 ) local iso; if not ( ( IsGroup(D1) and IsGroup(D2) ) or ( Is2DimensionalGroup(D1) and Is2DimensionalGroup(D2) ) ) then Error( "D1 and D2 should be groups or 2DimensionalGroups" ); fi; iso := Isoclinism( D1, D2 ); if ( ( iso = fail ) or ( iso = false ) ) then return false; else return true; fi; end ); ############################################################################# ## #M Isoclinism . . . ## InstallMethod( Isoclinism, "generic method for two groups", true, [ IsGroup, IsGroup ], 0, function( G1, G2 ) local CQ1, CQ2, Q1, Q2, D1, D2, nhom1, nhom2, sgQ1, lsgQ1, itAQ2, itAD2, isoQ, isoD, p1, q1, p2, q2, i, iq1, iq2, j, g1, h1, g2, h2, gor1, gor2, ok; if ( IsomorphismGroups(G1,G2) <> fail ) then Error( "not yet implemented" ); return true; fi; CQ1 := CentralQuotient(G1); Q1 := Range(CQ1); CQ2 := CentralQuotient(G2); Q2 := Range(CQ2); D1 := DerivedSubgroup(G1); D2 := DerivedSubgroup(G2); isoQ := IsomorphismGroups(Q1,Q2); isoD := IsomorphismGroups(D1,D2); if ( ( isoQ = fail ) or ( isoD = fail ) ) then return fail; fi; nhom1 := Boundary( CQ1 ); nhom2 := Boundary( CQ2 ); itAQ2 := Iterator( AllAutomorphisms(Q2) ); ## there is a problem here! ## examples have been found where using SmallGeneratingSet ## gives an incorrect answer! ## perhaps GeneratorsOfGroup would be insuffient, but, ## to play safe, we use Elements(Q1) for now, though very slow! ## sgQ1 := SmallGeneratingSet( Q1 ); ## sgQ1 := GeneratorsOfGroup( Q1 ); sgQ1 := Elements( Q1 ); lsgQ1 := Length( sgQ1 ); while not IsDoneIterator( itAQ2 ) do i := isoQ * NextIterator( itAQ2 ); ok := true; itAD2 := Iterator( AllAutomorphisms(D2) ); while not IsDoneIterator( itAD2 ) do j := isoD * NextIterator(itAD2); ok := true; p1 := 0; while ( ok and ( p1 < lsgQ1 ) ) do p1 := p1+1; q1 := sgQ1[p1]; g1 := PreImagesRepresentative( nhom1, q1 ); iq1 := Image( i, q1 ); h1 := PreImagesRepresentative( nhom2, iq1 ); p2 := 0; while ( ok and ( p2 < lsgQ1 ) ) do p2 := p2+1; q2 := sgQ1[p2]; g2 := PreImagesRepresentative( nhom1, q2 ); iq2 := Image( i, q2 ); h2 := PreImagesRepresentative( nhom2, iq2 ); gor1 := Image( j, Comm(g1,g2) ); gor2 := Comm( h1, h2 ); ok := ( gor1 = gor2 ); od; od; if ok then return [i,j]; fi; od; od; return fail; end ); ############################################################################# ## #M IsoclinicStemDomain . . . ?? is this really the best way ?? ## InstallMethod( IsoclinicStemDomain, "generic method for a group", true, [ IsGroup ], 0, function(G) local i, len, divs, id, gi; if ( HasIsAbelian(G) and IsAbelian(G) ) then return [ [ 1, 1 ] ]; fi; if IsStemDomain(G) then return G; fi; divs := DivisorsInt( Size(G) ); len := Length( divs ); for i in divs{[2..len-1]} do for gi in AllSmallGroups( i ) do if IsStemDomain( gi ) then if AreIsoclinicDomains( G, gi ) then return gi; fi; fi; od; od; return fail; end ); ############################################################################# ##### FUNCTIONS FOR ISOCLINISM OF CROSSED MODULES ##### ############################################################################# ############################################################################# ## #M IsStemDomain . check that the centre xmod is a subxmod of the derived xmod ## InstallOtherMethod( IsStemDomain, "generic method for crossed modules", true, [ IsXMod ], 0, function(X0) return IsSubXMod( DerivedSubXMod(X0), CentreXMod(X0) ); end ); InstallOtherMethod( Isoclinism, "generic method for crossed modules", true, [ IsXMod, IsXMod ], 0, function( X1, X2 ) local SX1, RX1, SX2, RX2, D1, D2, isoD, autD2, CX1, Q1, CX2, Q2, isoQ, SQ1, RQ1, SQ2, RQ2, actX1, actX2, autQ2, nhom1, shom1, rhom1, nhom2, shom2, rhom2, sgRQ1, lsgRQ1, sgSQ1, lsgSQ1, a, i, si, ri, ok, b, j, sj, rj, p1, r1, x1, ir1, d1, p2, r2, x2, ir2, d2, gor1, gor2, p3, s1, y1, is1, e1; SX1 := Source(X1); RX1 := Range(X1); SX2 := Source(X2); RX2 := Range(X2); actX1 := XModAction( X1 ); actX2 := XModAction( X2 ); D1 := DerivedSubXMod(X1); D2 := DerivedSubXMod(X2); ## check condition 2 : require D1 ~ D2 isoD := IsomorphismXMods( D1, D2 ); if ( isoD = fail ) then Info( InfoXMod, 1, "derived subcrossed modules are not isomorphic" ); return fail; fi; autD2 := AutomorphismPermGroup( D2 ); CX1 := CentralQuotient( X1 ); Q1 := Right2DimensionalGroup( CX1 ); CX2 := CentralQuotient( X2 ); Q2 := Right2DimensionalGroup( CX2 ); ## check condition 1 : require Q1 ~ Q2 isoQ := IsomorphismXMods( Q1, Q2 ); if ( isoQ = fail ) then Info( InfoXMod, 1, "factor crossed modules X/ZX are not isomorphic" ); return fail; fi; SQ1 := Source(Q1); RQ1 := Range(Q1); SQ2 := Source(Q2); RQ2 := Range(Q2); autQ2 := AutomorphismPermGroup( Q2 ); nhom1 := LeftRightMorphism( CX1 ); shom1 := SourceHom( nhom1 ); rhom1 := RangeHom( nhom1 ); nhom2 := LeftRightMorphism( CX2 ); shom2 := SourceHom( nhom2 ); rhom2 := RangeHom( nhom2 ); sgRQ1 := SmallGeneratingSet( RQ1 ); lsgRQ1 := Length( sgRQ1 ); sgSQ1 := SmallGeneratingSet( SQ1 ); lsgSQ1 := Length( sgSQ1 ); for a in autQ2 do i := isoQ * PermAutomorphismAsXModMorphism( Q2, a ); si := SourceHom( i ); ri := RangeHom( i ); ok := true; for b in autD2 do j := isoD * PermAutomorphismAsXModMorphism( D2, b ); sj := SourceHom( j ); rj := RangeHom( j ); ok := true; p1 := 0; while ( ok and ( p1 < lsgRQ1 ) ) do p1 := p1+1; r1 := sgRQ1[p1]; x1 := PreImagesRepresentative( rhom1, r1 ); ir1 := Image( ri, r1 ); d1 := PreImagesRepresentative( rhom2, ir1 ); p2 := 0; while ( ok and ( p2 < lsgRQ1 ) ) do p2 := p2+1; r2 := sgRQ1[p2]; x2 := PreImagesRepresentative( rhom1, r2 ); ir2 := Image( ri, r2 ); d2 := PreImagesRepresentative( rhom2, ir2 ); gor1 := Image( rj, Comm(x1,x2) ); gor2 := Comm( d1, d2 ); ok := ( gor1 = gor2 ); od; p3 := 0; while ( ok and ( p3 < lsgSQ1 ) ) do p3 := p3+1; s1 := sgSQ1[p3]; y1 := PreImagesRepresentative( shom1, s1 ); is1 := Image( si, s1 ); e1 := PreImagesRepresentative( shom2, is1 ); gor1 := Image( sj, Displacement( actX1, x1, y1 ) ); gor2 := Displacement( actX2, d1, e1 ); ok := ( gor1 = gor2 ); od; od; if ok then return [i,j]; fi; od; od; Info( InfoXMod, 1, "no morphism exists satisfying the conditions" ); return fail; end ); ############################################################################# ## #M IsoclinicXModFamily . . . . all xmods in the list isoclinic to the xmod ## InstallMethod( IsoclinicXModFamily, "generic method for crossed modules", true, [ Is2DimensionalGroup, IsList ], 0, function( XM, XM1_ler ) local sonuc, XM1; sonuc := [ ]; for XM1 in XM1_ler do if AreIsoclinicDomains( XM, XM1 ) then Info( InfoXMod, 2, XM, " ~ ", XM1 ); Add( sonuc, Position(XM1_ler,XM1) ); else Info( InfoXMod, 2, XM, " |~ ", XM1 ); fi; od; return sonuc; end ); ############################################################################# ## #M IsomorphicXModFamily . . . all xmods in the list isomorphic to the xmod ## InstallMethod( IsomorphicXModFamily, "generic method for crossed modules", true, [ Is2DimensionalGroup, IsList ], 0, function( XM, XM1_ler ) local sonuc, iso, XM1; sonuc := [ ]; for XM1 in XM1_ler do iso := IsomorphismXMods( XM, XM1 ); if ( iso <> fail ) then Add( sonuc, Position(XM1_ler,XM1) ); fi; od; return sonuc; end ); ############################################################################# ## #M AllXModsUpToIsomorphism . . . . . all crossed modules up to isomorphism ## InstallMethod( AllXModsUpToIsomorphism, "generic method for list of xmods", true, [ IsList ], 0, function( allxmods ) local n, found, all, i, j, k, isolar, list; n := Length( allxmods ); found := ListWithIdenticalEntries( n, 0 ); all := ShallowCopy( allxmods ); list := []; for i in [1..n] do if ( found[i] = 0 ) then Add( list, allxmods[i] ); isolar := IsomorphicXModFamily( allxmods[i], all ); for j in isolar do k := Position( allxmods, all[j] ); found[k] := 1; od; fi; od; return list; end ); ############################################################################# ## #M IsoclinicMiddleLength . . the middle length of a group or crossed module #M IsoclinicRank . . . . . . . . . . . the rank of a group or crossed module ## InstallMethod( IsoclinicRank, "generic method for groups", true, [ IsGroup ], 0, function(G) local ZG, DG, QG, KG; if not IsPrimePowerInt( Size(G) ) then return fail; fi; ZG := Centre(G); DG := DerivedSubgroup(G); QG := G/ZG; KG := Intersection( ZG, DG ); return Tau( Size(KG) ) + Tau( Size(QG) ) - 2; end ); InstallOtherMethod( IsoclinicRank, "generic method for crossed modules", true, [ Is2DimensionalGroup ], 0, function( XM ) local size, ZXMod, DXMod, QXMod, KXMod, m1, m2, l1, l2; size := Size( XM ); if not ( IsPrimePowerInt(size[1]) and IsPrimePowerInt(size[2]) ) then return fail; fi; ZXMod := CentreXMod( XM ); DXMod := DerivedSubXMod( XM ); QXMod := FactorPreXMod(XM,ZXMod); KXMod := IntersectionSubXMods(XM,ZXMod,DXMod); m1 := Size(QXMod); m2 := Size(KXMod); l1 := Tau( m1[1] ) + Tau( m2[1] ) - 2; l2 := Tau( m1[2] ) + Tau( m2[2] ) - 2; return [l1,l2]; end ); InstallMethod( IsoclinicMiddleLength, "generic method for groups", true, [ IsGroup ], 0, function(G) local ZG, DG, QG, KG; if not IsPrimePowerInt( Size(G) ) then return fail; fi; ZG := Centre(G); DG := DerivedSubgroup(G); KG := Intersection( ZG, DG ); QG := DG/KG; return Tau( Size(QG) ) - 1; end ); InstallOtherMethod( IsoclinicMiddleLength, "generic method for crossed modules", true, [ Is2DimensionalGroup ], 0, function( XM ) local size, ZXMod, DXMod, QXMod, KXMod; size := Size( XM ); if not ( IsPrimePowerInt(size[1]) and IsPrimePowerInt(size[2]) ) then Info( InfoXMod, 1, "not a crossed module of prime power order" ); return fail; fi; ZXMod := CentreXMod( XM ); DXMod := DerivedSubXMod( XM ); KXMod := IntersectionSubXMods(XM,ZXMod,DXMod); QXMod := FactorPreXMod(DXMod,KXMod); size := Size(QXMod); return [ Tau(size[1])-1, Tau(size[2])-1 ]; end ); ############################################################################# ## #M TableRowXMod . .. . table row for isoclinism families of crossed modules ## InstallMethod( TableRowXMod, "generic method for crossed modules", true, [ Is2DimensionalGroup, IsList ], 0, function(XM,XM_ler) local Eler, Iler, i, j, sinif, B; sinif := IsoclinicXModFamily( XM, XM_ler ); B := LowerCentralSeries( XM ); Print("---------------------------------------------------------------------------------------------------------------------------------- \n"); Print("---------------------------------------------------------------------------------------------------------------------------------- \n"); Print("Number","\t","Rank","\t\t","M. L.","\t\t","Class","\t","|G/Z|","\t\t", "|g2|","\t\t","|g3|","\t\t","|g4|","\t\t","|g5| \n"); Print("---------------------------------------------------------------------------------------------------------------------------------- \n"); Print( Length(sinif), "\t", IsoclinicRank( XM ), "\t", IsoclinicMiddleLength( XM ), "\t", NilpotencyClassOf2DimensionalGroup( XM ), "\t", Size( FactorPreXMod( XM, CentreXMod( XM ) ) ) ); if Length(B) > 1 then for i in [2..Length(B)] do Print("\t"); Print(Size(B[i])); od; fi; Print("\n---------------------------------------------------------------------------------------------------------------------------------- \n"); return sinif; end );