diff --git a/lib/ctbl.gd b/lib/ctbl.gd index efc7baaae31..7fe335e6251 100644 --- a/lib/ctbl.gd +++ b/lib/ctbl.gd @@ -357,20 +357,18 @@ BindGlobal( "NearlyCharacterTablesFamily", ## is a list that contains ## at position 3i-2 an attribute getter function, ## at position 3i-1 the name of this attribute, -## and at position 3i a list containing one or two of the -## strings "class", "character", +## and at position 3i a list containing a subset of +## [ "character", "class", "mutable" ], ## depending on whether the attribute value relies on the ordering of -## classes or characters. -## This allows one to set exactly the components with these names in the -## record that is later converted to the new table, -## in order to use the values as attribute values. -## So the record components that shall not be regarded as attribute -## values can be ignored. -## Also other attributes of the old table are ignored. -##

-## is used when (ordinary or -## Brauer) character table objects are created from records, using -## . +## characters or classes, or whether the attribute value is a mutable +## list or record. +##

+## When (ordinary or Brauer) character table objects are created from +## records, using , +## specifies those +## record components that shall be used as attribute values; +## other record components are not be regarded as attribute +## values in the conversion process. ##

## New attributes and properties can be notified to ## by creating them with @@ -387,12 +385,12 @@ BindGlobal( "SupportedCharacterTableInfo", [] ); ############################################################################# ## #F DeclareAttributeSuppCT( , [, "mutable"], ) -#F DeclarePropertySuppCT( , [, "mutable"] ) +#F DeclarePropertySuppCT( , ) ## ## ## -## +## ## ## ## do the same as and @@ -402,46 +400,50 @@ BindGlobal( "SupportedCharacterTableInfo", [] ); ## ## ## -BindGlobal( "DeclareAttributeSuppCT", function( arg ) - local attr; +BindGlobal( "DeclareAttributeSuppCT", function( name, filter, arg... ) + local mutflag, depend; # Check the arguments. - if not ( Length( arg ) in [ 3, 4 ] and IsString( arg[1] ) and - IsFilter( arg[2] ) and ( IsHomogeneousList( arg[3] ) or - ( arg[3] = "mutable" and IsHomogeneousList( arg[4] ) ) ) ) then + if not ( IsString( name ) and IsFilter( filter ) ) then + Error( " must be a string, must be a filter" ); + elif Length( arg ) = 1 and IsList( arg[1] ) then + mutflag:= false; + depend:= arg[1]; + elif Length( arg ) = 2 and arg[1] = "mutable" and IsList( arg[2] ) then + mutflag:= true; + depend:= arg[2]; + else Error( "usage: DeclareAttributeSuppCT( ,\n", " [, \"mutable\"], )" ); - elif not ForAll( arg[ Length( arg ) ], - str -> str in [ "class", "character" ] ) then + fi; + if not ForAll( depend, str -> str in [ "class", "character" ] ) then Error( " must contain only \"class\", \"character\"" ); fi; # Create/change the attribute as `DeclareAttribute' does. - CallFuncList( DeclareAttribute, arg{ [ 1 .. Length( arg )-1 ] } ); + if mutflag then + DeclareAttribute( name, filter, "mutable" ); + depend:= Concatenation( depend, [ "mutable" ] ); + else + DeclareAttribute( name, filter ); + fi; # Do the additional magic. - attr:= ValueGlobal( arg[1] ); Append( SupportedCharacterTableInfo, - [ attr, arg[1], arg[ Length( arg ) ] ] ); + [ ValueGlobal( name ), name, depend ] ); end ); -BindGlobal( "DeclarePropertySuppCT", function( arg ) - local prop; - +BindGlobal( "DeclarePropertySuppCT", function( name, filter ) # Check the arguments. - if not ( Length( arg ) in [ 2, 3 ] and IsString( arg[1] ) and - IsFilter( arg[2] ) and ( Length( arg ) = 2 or - arg[3] = "mutable" ) ) then - Error( "usage: DeclarePropertySuppCT( ,\n", - " [, \"mutable\"] )" ); + if not ( IsString( name ) and IsFilter( filter ) ) then + Error( " must be a string, must be a filter" ); fi; # Create/change the property as `DeclareProperty' does. - CallFuncList( DeclareProperty, arg ); + DeclareProperty( name, filter ); # Do the additional magic. - prop:= ValueGlobal( arg[1] ); - Append( SupportedCharacterTableInfo, [ prop, arg[1], [] ] ); + Append( SupportedCharacterTableInfo, [ ValueGlobal( name ), name, [] ] ); end ); @@ -968,7 +970,7 @@ InstallIsomorphismMaintenance( CharacterDegrees, DeclareAttribute( "Irr", IsGroup ); DeclareOperation( "Irr", [ IsGroup, IsInt ] ); DeclareAttributeSuppCT( "Irr", IsNearlyCharacterTable, - [ "class", "character" ] ); + [ "character", "class" ] ); ############################################################################# @@ -1656,7 +1658,7 @@ fi; ############################################################################# ## -#A InfoText( ) +#M InfoText( ) ## ## <#GAPDoc Label="InfoText_ctbl"> ## @@ -1684,7 +1686,16 @@ fi; ## ## <#/GAPDoc> ## -DeclareAttributeSuppCT( "InfoText", IsNearlyCharacterTable, "mutable", [] ); +## Do not call 'DeclareAttributeSuppCT', +## since the attribute has already been declared for arbitrary GAP objects. +## A second declaration with requirement 'IsNearlyCharacterTable' would +## make the installation of a method with 'InstallMethod' impossible. +## +## We want, however, to add 'InfoText' to the list +## 'SupportedCharacterTableInfo'. +## +Append( SupportedCharacterTableInfo, + [ InfoText, "InfoText", [ "mutable" ] ] ); ############################################################################# diff --git a/lib/ctbl.gi b/lib/ctbl.gi index a1c90f82a46..a6a32c63e9b 100644 --- a/lib/ctbl.gi +++ b/lib/ctbl.gi @@ -97,6 +97,8 @@ InstallGlobalFunction( CharacterTableWithStoredGroup, function( arg ) rec( UnderlyingCharacteristic := 0 ) ); # Set the supported attribute values. + # We may assume that the subobjects of mutable attribute values + # are already immutable. for i in [ 3, 6 .. Length( SupportedCharacterTableInfo ) ] do if Tester( SupportedCharacterTableInfo[ i-2 ] )( tbl ) and SupportedCharacterTableInfo[ i-1 ] <> "Irr" then @@ -2752,7 +2754,7 @@ InstallMethod( PrimeBlocks, # This avoids errors if a calculation had been interrupted. if not IsBound( known[p] ) then erg:= PrimeBlocksOp( tbl, p ); - known[p]:= erg; + known[p]:= MakeImmutable( erg ); fi; return known[p]; @@ -3859,7 +3861,7 @@ InstallMethod( Indicator, # This avoids errors if a calculation had been interrupted. if not IsBound( known[n] ) then erg:= IndicatorOp( tbl, Irr( tbl ), n ); - known[n]:= erg; + known[n]:= MakeImmutable( erg ); fi; return known[n]; @@ -4260,7 +4262,6 @@ InstallMethod( ComputedBrauerTables, ## InstallGlobalFunction( CharacterTableRegular, function( ordtbl, prime ) - local fusion, inverse, orders, @@ -4300,12 +4301,14 @@ InstallGlobalFunction( CharacterTableRegular, power:= ComputedPowerMaps( ordtbl ); for i in [ 1 .. Length( power ) ] do if IsBound( power[i] ) then - regular.ComputedPowerMaps[i]:= inverse{ power[i]{ fusion } }; + regular.ComputedPowerMaps[i]:= MakeImmutable( + inverse{ power[i]{ fusion } } ); fi; od; regular:= ConvertToCharacterTableNC( regular ); - StoreFusion( regular, rec( map:= fusion, type:= "choice" ), ordtbl ); + StoreFusion( regular, + rec( map:= MakeImmutable( fusion ), type:= "choice" ), ordtbl ); return regular; end ); @@ -4317,9 +4320,7 @@ InstallGlobalFunction( CharacterTableRegular, #F ConvertToCharacterTableNC( ) . . . create character table object ## InstallGlobalFunction( ConvertToCharacterTableNC, function( record ) - - local names, # list of component names - i; # loop over `SupportedCharacterTableInfo' + local names, i, name, val, entry; names:= RecNames( record ); @@ -4337,18 +4338,32 @@ InstallGlobalFunction( ConvertToCharacterTableNC, function( record ) fi; # Enter the properties and attributes. + # For mutable attributes, if the value is a list but not a string + # then make the list entries immutable. for i in [ 1, 4 .. Length( SupportedCharacterTableInfo ) - 2 ] do - if SupportedCharacterTableInfo[ i+1 ] in names - and SupportedCharacterTableInfo[ i+1 ] <> "Irr" then - Setter( SupportedCharacterTableInfo[i] )( record, - record!.( SupportedCharacterTableInfo[ i+1 ] ) ); + name:= SupportedCharacterTableInfo[ i+1 ]; + if name in names and name <> "Irr" then + val:= record!.( name ); + if "mutable" in SupportedCharacterTableInfo[ i+2 ] then + if IsList( val ) and not IsString( val ) then + # Store a mutable list with immutable entries. + for entry in val do + MakeImmutable( entry ); + od; + fi; + else + # Avoid making a copy. + MakeImmutable( val ); + fi; + Setter( SupportedCharacterTableInfo[i] )( record, val ); fi; od; - # Make the lists of character values into character objects. + # Turn the lists of character values into character objects. if "Irr" in names then - SetIrr( record, List( record!.Irr, - chi -> Character( record, chi ) ) ); + SetIrr( record, MakeImmutable( List( record!.Irr, + chi -> Character( record, + MakeImmutable( chi ) ) ) ) ); fi; # Return the object. @@ -5358,14 +5373,15 @@ InstallMethod( CharacterTableDirectProduct, powermap_k[ j + ncc2_i ]:= vals2[j] + ncc2 * ( vals1[i] - 1 ); od; od; - vals_direct[k]:= powermap_k; + vals_direct[k]:= MakeImmutable( powermap_k ); od; # Compute the irreducibles. SetIrr( direct, List( KroneckerProduct( List( Irr( tbl1 ), ValuesOfClassFunction ), List( Irr( tbl2 ), ValuesOfClassFunction ) ), - vals -> Character( direct, vals ) ) ); + vals -> Character( direct, + MakeImmutable( vals ) ) ) ); # Form character parameters if they exist for the irreducibles # in both tables. @@ -5387,7 +5403,7 @@ InstallMethod( CharacterTableDirectProduct, for j in [ 1 .. ncc2 ] do fus[ ( i - 1 ) * ncc2 + j ]:= i; od; od; StoreFusion( direct, - rec( map := fus, specification := "1" ), + rec( map := MakeImmutable( fus ), specification := "1" ), tbl1 ); fus:= []; @@ -5395,18 +5411,18 @@ InstallMethod( CharacterTableDirectProduct, for j in [ 1 .. ncc2 ] do fus[ ( i - 1 ) * ncc2 + j ]:= j; od; od; StoreFusion( direct, - rec( map := fus, specification := "2" ), + rec( map := MakeImmutable( fus ), specification := "2" ), tbl2 ); # Store embeddings. StoreFusion( tbl1, - rec( map := [ 1, ncc2+1 .. (ncc1-1)*ncc2+1 ], + rec( map := MakeImmutable( [ 1, ncc2+1 .. (ncc1-1)*ncc2+1 ] ), specification := "1" ), direct ); StoreFusion( tbl2, - rec( map := [ 1 .. ncc2 ], - specification := "2" ), + rec( map := MakeImmutable( [ 1 .. ncc2 ] ), + specification := "2" ), direct ); # Store the argument list as the value of `FactorsOfDirectProduct'. @@ -5456,22 +5472,22 @@ InstallMethod( CharacterTableDirectProduct, for i in [ 1 .. ncc1 ] do for j in [ 1 .. ncc2 ] do fus[ ( i - 1 ) * ncc2 + j ]:= i; od; od; - StoreFusion( reg, fus, tbl1 ); + StoreFusion( reg, MakeImmutable( fus ), tbl1 ); fus:= []; for i in [ 1 .. ncc1 ] do for j in [ 1 .. ncc2 ] do fus[ ( i - 1 ) * ncc2 + j ]:= j; od; od; - StoreFusion( reg, fus, tbl2 ); + StoreFusion( reg, MakeImmutable( fus ), tbl2 ); StoreFusion( tbl1, - rec( map := [ 1, ncc2+1 .. (ncc1-1)*ncc2+1 ], - specification := "1" ), + MakeImmutable( rec( map := [ 1, ncc2+1 .. (ncc1-1)*ncc2+1 ], + specification := "1" ) ), reg ); StoreFusion( tbl2, - rec( map := [ 1 .. ncc2 ], - specification := "2" ), + MakeImmutable( rec( map := [ 1 .. ncc2 ], + specification := "2" ) ), reg ); # Return the table. @@ -5518,22 +5534,22 @@ InstallMethod( CharacterTableDirectProduct, for i in [ 1 .. ncc1 ] do for j in [ 1 .. ncc2 ] do fus[ ( i - 1 ) * ncc2 + j ]:= i; od; od; - StoreFusion( reg, fus, tbl1 ); + StoreFusion( reg, MakeImmutable( fus ), tbl1 ); fus:= []; for i in [ 1 .. ncc1 ] do for j in [ 1 .. ncc2 ] do fus[ ( i - 1 ) * ncc2 + j ]:= j; od; od; - StoreFusion( reg, fus, tbl2 ); + StoreFusion( reg, MakeImmutable( fus ), tbl2 ); StoreFusion( tbl1, - rec( map := [ 1, ncc2+1 .. (ncc1-1)*ncc2+1 ], - specification := "1" ), + MakeImmutable( rec( map := [ 1, ncc2+1 .. (ncc1-1)*ncc2+1 ], + specification := "1" ) ), reg ); StoreFusion( tbl2, - rec( map := [ 1 .. ncc2 ], - specification := "2" ), + MakeImmutable( rec( map := [ 1 .. ncc2 ], + specification := "2" ) ), reg ); # Return the table. @@ -5583,27 +5599,27 @@ InstallMethod( CharacterTableDirectProduct, for j in [ 1 .. ncc2 ] do fus[ ( i - 1 ) * ncc2 + j ]:= i; od; od; StoreFusion( reg, - rec( map := fus, - specification := "1" ), + MakeImmutable( rec( map := fus, + specification := "1" ) ), tbl1 ); fus:= []; for i in [ 1 .. ncc1 ] do for j in [ 1 .. ncc2 ] do fus[ ( i - 1 ) * ncc2 + j ]:= j; od; od; StoreFusion( reg, - rec( map := fus, - specification := "2" ), + MakeImmutable( rec( map := fus, + specification := "2" ) ), tbl2 ); # Store embeddings. StoreFusion( tbl1, - rec( map := [ 1, ncc2+1 .. (ncc1-1)*ncc2+1 ], - specification := "1" ), + MakeImmutable( rec( map := [ 1, ncc2+1 .. (ncc1-1)*ncc2+1 ], + specification := "1" ) ), reg ); StoreFusion( tbl2, - rec( map := [ 1 .. ncc2 ], - specification := "2" ), + MakeImmutable( rec( map := [ 1 .. ncc2 ], + specification := "2" ) ), reg ); # Return the table. @@ -5671,7 +5687,8 @@ InstallGlobalFunction( CharacterTableHeadOfFactorGroupByFusion, for p in [ 1 .. Length( ComputedPowerMaps( tbl ) ) ] do if IsBound( ComputedPowerMaps( tbl )[p] ) then map:= ComputedPowerMaps( tbl )[p]; - F.ComputedPowerMaps[p]:= factorfusion{ map{ inverse } }; + F.ComputedPowerMaps[p]:= MakeImmutable( + factorfusion{ map{ inverse } } ); fi; od; @@ -5719,14 +5736,15 @@ InstallMethod( CharacterTableFactorGroup, F:= CharacterTableHeadOfFactorGroupByFusion( tbl, factorfusion ); # Set the irreducibles. - SetIrr( F, List( factirr, chi -> Character( F, chi ) ) ); + SetIrr( F, List( factirr, chi -> Character( F, MakeImmutable( chi ) ) ) ); # Transfer necessary power maps of `tbl' to `F'. inverse:= ProjectionMap( factorfusion ); maps:= ComputedPowerMaps( F ); for p in PrimeDivisors( Size( F ) ) do if not IsBound( maps[p] ) then - maps[p]:= factorfusion{ PowerMap( tbl, p ){ inverse } }; + maps[p]:= MakeImmutable( + factorfusion{ PowerMap( tbl, p ){ inverse } } ); fi; od; @@ -5766,7 +5784,8 @@ InstallMethod( CharacterTableFactorGroup, factirr:= Filtered( List( Irr( modtbl ), ValuesOfClassFunction ), x -> Length( Set( x{ kernel } ) ) = 1 ); proj:= ProjectionMap( fus ); - SetIrr( modfact, List( factirr, x -> Character( modfact, x{ proj } ) ) ); + SetIrr( modfact, List( factirr, x -> Character( modfact, + MakeImmutable( x{ proj } ) ) ) ); # Return the result. return modfact; @@ -5988,7 +6007,7 @@ InstallOtherMethod( CharacterTableIsoclinic, OrdersClassRepresentatives := orders, ComputedClassFusions := [], ComputedPowerMaps := [], - Irr := irreds.all ); + Irr := List( irreds.all, MakeImmutable ) ); # Get the fusion map onto the factor group modulo the central subgroup. # We assume that the first class of element order two or four in the @@ -6052,7 +6071,7 @@ InstallOtherMethod( CharacterTableIsoclinic, od; fi; - isoclinic.ComputedPowerMaps[p]:= map; + isoclinic.ComputedPowerMaps[p]:= MakeImmutable( map ); od; @@ -6161,7 +6180,8 @@ InstallOtherMethod( CharacterTableIsoclinic, irreducibles:= List( irreducibles, x -> Permuted( x, pi ) ); fi; - SetIrr( reg, List( irreducibles, vals -> Character( reg, vals ) ) ); + SetIrr( reg, List( irreducibles, + vals -> Character( reg, MakeImmutable( vals ) ) ) ); # Return the result. return reg; @@ -6226,9 +6246,9 @@ InstallGlobalFunction( CharacterTableOfNormalSubgroup, for p in [ 1 .. Length( ComputedPowerMaps( tbl ) ) ] do if IsBound( ComputedPowerMaps( tbl )[p] ) then - result.ComputedPowerMaps[p]:= + result.ComputedPowerMaps[p]:= MakeImmutable( CompositionMaps( inverse, - CompositionMaps( ComputedPowerMaps( tbl )[p], classes ) ); + CompositionMaps( ComputedPowerMaps( tbl )[p], classes ) ) ); fi; od; @@ -6242,7 +6262,7 @@ InstallGlobalFunction( CharacterTableOfNormalSubgroup, i -> sizesclasses[i] * char[i] * GaloisCyc(char[i],-1), 0 ) = size and not char in irreducibles then - Add( irreducibles, char ); + Add( irreducibles, MakeImmutable( char ) ); fi; od; @@ -6551,8 +6571,7 @@ InstallMethod( CharacterTableWithSortedClasses, "for an ordinary character table, and a permutation", [ IsOrdinaryTable, IsPerm ], function( tbl, perm ) - - local new, i, attr, fus, tblmaps, permmap, inverse, k; + local new, i, attr, fus, copy, tblmaps, permmap, inverse, k; # Catch trivial cases. if 1^perm <> 1 then @@ -6583,21 +6602,24 @@ InstallMethod( CharacterTableWithSortedClasses, SizesConjugacyClasses, ] do if Tester( attr )( tbl ) then - Setter( attr )( new, Permuted( attr( tbl ), perm ) ); + Setter( attr )( new, MakeImmutable( Permuted( attr( tbl ), perm ) ) ); fi; od; # For each fusion, the map must be permuted. for fus in ComputedClassFusions( tbl ) do - Add( ComputedClassFusions( new ), - rec( name:= fus.name, map:= Permuted( fus.map, perm ) ) ); + copy:= ShallowCopy( fus ); + copy.map:= MakeImmutable( Permuted( fus.map, perm ) ); + Add( ComputedClassFusions( new ), MakeImmutable( copy ) ); od; # Each irreducible character must be permuted. if HasIrr( tbl ) then SetIrr( new, - List( Irr( tbl ), chi -> Character( new, - Permuted( ValuesOfClassFunction( chi ), perm ) ) ) ); + List( Irr( tbl ), + chi -> Character( new, + MakeImmutable( Permuted( + ValuesOfClassFunction( chi ), perm ) ) ) ) ); fi; # Power maps must be ``conjugated''. @@ -6612,8 +6634,9 @@ InstallMethod( CharacterTableWithSortedClasses, od; for k in [ 1 .. Length( tblmaps ) ] do if IsBound( tblmaps[k] ) then - ComputedPowerMaps( new )[k]:= CompositionMaps( permmap, - CompositionMaps( tblmaps[k], inverse ) ); + ComputedPowerMaps( new )[k]:= MakeImmutable( + CompositionMaps( permmap, + CompositionMaps( tblmaps[k], inverse ) ) ); fi; od; diff --git a/lib/ctblfuns.gi b/lib/ctblfuns.gi index 52f3ab97571..1b0d2105cb8 100644 --- a/lib/ctblfuns.gi +++ b/lib/ctblfuns.gi @@ -640,7 +640,7 @@ InstallMethod( GlobalPartitionOfClasses, # The number of root classes is by definition invariant under # table automorphisms. for map in Compacted( ComputedPowerMaps( tbl ) ) do - inv:= 0 * map; + inv:= ZeroMutable( map ); for j in map do inv[j]:= inv[j] + 1; od; @@ -3616,7 +3616,7 @@ InstallOtherMethod( Symmetrizations, [ IsCharacterTable, IsHomogeneousList, IsRecord ], function( tbl, characters, arec ) local i, j, l, n, - tbl_powermap, # computed power maps of 'tbl' + powermap, cyclestruct, classparam, symmirreds, @@ -3626,7 +3626,6 @@ InstallOtherMethod( Symmetrizations, symmetrizations, chi, psi, - powermap, prodmatrix, single, value, @@ -3651,17 +3650,14 @@ InstallOtherMethod( Symmetrizations, od; od; - tbl_powermap:= ShallowCopy( ComputedPowerMaps( tbl ) ); -#T better do the computation of necessary power maps only once! - # Compute necessary power maps. + powermap:= ComputedPowerMaps( tbl ); for i in [ 1 .. n ] do - if not IsBound( tbl_powermap[i] ) then - tbl_powermap[i]:= PowerMap( tbl, i ); + if not IsBound( powermap[i] ) then + powermap[i]:= MakeImmutable( PowerMap( tbl, i ) ); fi; od; - powermap:= tbl_powermap; symmetrizations:= []; for chi in characters do @@ -3761,7 +3757,7 @@ InstallGlobalFunction( SymmetricParts, function( tbl, characters, n ) powermap:= ComputedPowerMaps( tbl ); for i in [ 1 .. n ] do if not IsBound( powermap[i] ) then - powermap[i]:= PowerMap( tbl, i ); + powermap[i]:= MakeImmutable( PowerMap( tbl, i ) ); fi; od; @@ -3843,7 +3839,7 @@ InstallGlobalFunction( AntiSymmetricParts, function( tbl, characters, n ) powermap:= ComputedPowerMaps( tbl ); for i in [ 1 .. n ] do if not IsBound( powermap[i] ) then - powermap[i]:= PowerMap( tbl, i ); + powermap[i]:= MakeImmutable( PowerMap( tbl, i ) ); fi; od; diff --git a/lib/ctblgrp.gi b/lib/ctblgrp.gi index 4ce2359bc64..f3986c806c0 100644 --- a/lib/ctblgrp.gi +++ b/lib/ctblgrp.gi @@ -144,7 +144,7 @@ local p,primes,i,cl,spr,j,allpowermaps,pm,ex; D.inversemap:=p; allpowermaps:=ComputedPowerMaps(D.characterTable); - allpowermaps[1]:=D.classrange; + allpowermaps[1]:= Immutable( D.classrange ); D.powermap:=allpowermaps; # get all primes smaller than the largest element order @@ -214,8 +214,8 @@ fi; fi; od; + MakeImmutable( pm ); od; - end; ############################################################################# diff --git a/lib/ctblmaps.gd b/lib/ctblmaps.gd index 165169f36df..4474ebc049f 100644 --- a/lib/ctblmaps.gd +++ b/lib/ctblmaps.gd @@ -970,7 +970,7 @@ DeclareAttributeSuppCT( "NamesOfFusionSources", ## parameters ## ## a record with components maxamb, minamb and maxlen -## which control the subroutine +## (and perhaps some optional components) which control the subroutine ## ; ## it only uses characters with current indeterminateness up to ## maxamb, @@ -2368,13 +2368,21 @@ DeclareGlobalFunction( "ConsiderTableAutomorphisms" ); ## characters of subtbl and tbl, respectively, ## approxmap a parametrized map that is an approximation of the class ## fusion of subtbl in tbl, -## and parameters a record with components +## and parameters a record with the mandatory components ## maxlen, minamb, maxamb (three integers), ## quick (a Boolean), -## and contained (a function). -## Usual values of contained are +## and contained (a function, usual values are ## or -## . +## ); +## optional components of the parameters record are +## testdec (the function that tests the decomposability, +## the default is ), +## powermaps (the power paps of subtbl that shall be used for +## compatibility checks, the default is the +## value), +## subpowermaps (the power paps of tbl that shall be used for +## compatibility checks, the default is the +## value). ##

## replaces the entries of ## approxmap by improved values, diff --git a/lib/ctblmaps.gi b/lib/ctblmaps.gi index 0d7c8b42969..aa0b0301c99 100644 --- a/lib/ctblmaps.gi +++ b/lib/ctblmaps.gi @@ -43,7 +43,7 @@ InstallMethod( PowerMap, # compute the -th power map if not IsBound( known[n] ) then erg:= PowerMapOp( tbl, n ); - known[n]:= erg; + known[n]:= MakeImmutable( erg ); fi; # return the

-th power map @@ -129,7 +129,7 @@ InstallMethod( PowerMapOp, if Length( pmap ) <> 1 then return fail; elif IsSmallIntRep( i ) then - powermap[i]:= pmap[1]; + powermap[i]:= MakeImmutable( pmap[1] ); fi; nth_powermap:= nth_powermap{ pmap[1] }; fi; @@ -168,11 +168,11 @@ InstallOtherMethod( PowerMapOp, image:= class; for i in Factors(Integers, n ) do - # Here we use that `n' is a small integer. + # Here we use that `i' is a small integer. if not IsBound( powermap[i] ) then # Compute the missing power map. - powermap[i]:= PowerMap( tbl, i ); + powermap[i]:= MakeImmutable( PowerMap( tbl, i ) ); #T if the group is available, better ask it directly? #T (careful: No maps are stored by the three-argument call, #T this may slow down the computation if many calls are done ...) @@ -471,9 +471,10 @@ InstallOtherMethod( PossiblePowerMaps, local ordtbl, poss, fus, inv; ordtbl:= OrdinaryCharacterTable( modtbl ); if IsBound( ComputedPowerMaps( ordtbl )[ prime ] ) then - return [ ComputedPowerMaps( ordtbl )[ prime ] ]; + poss:= [ ComputedPowerMaps( ordtbl )[ prime ] ]; + else + poss:= PossiblePowerMaps( ordtbl, prime, rec() ); fi; - poss:= PossiblePowerMaps( ordtbl, prime, rec() ); fus:= GetFusionMap( modtbl, ordtbl ); inv:= InverseMap( fus ); return Set( List( poss, @@ -492,21 +493,22 @@ InstallMethod( PossiblePowerMaps, local ordtbl, poss, fus, inv, quick, decompose; ordtbl:= OrdinaryCharacterTable( modtbl ); if IsBound( ComputedPowerMaps( ordtbl )[ prime ] ) then - return [ ComputedPowerMaps( ordtbl )[ prime ] ]; - fi; - quick:= IsBound( arec.quick ) and ( arec.quick = true ); - decompose:= IsBound( arec.decompose ) and ( arec.decompose = true ); - if IsBound( arec.parameters ) then - poss:= PossiblePowerMaps( ordtbl, prime, + poss:= [ ComputedPowerMaps( ordtbl )[ prime ] ]; + else + quick:= IsBound( arec.quick ) and ( arec.quick = true ); + decompose:= IsBound( arec.decompose ) and ( arec.decompose = true ); + if IsBound( arec.parameters ) then + poss:= PossiblePowerMaps( ordtbl, prime, rec( quick := quick, decompose := decompose, parameters := rec( maxamb:= arec.parameters.maxamb, minamb:= arec.parameters.minamb, maxlen:= arec.parameters.maxlen ) ) ); - else - poss:= PossiblePowerMaps( ordtbl, prime, + else + poss:= PossiblePowerMaps( ordtbl, prime, rec( quick := quick, decompose := decompose ) ); + fi; fi; fus:= GetFusionMap( modtbl, ordtbl ); inv:= InverseMap( fus ); @@ -1101,9 +1103,8 @@ InstallGlobalFunction( StoreFusion, function( source, fusion, destination ) # Adjust the map to the stored permutation. if HasClassPermutation( destination ) then - fusion.map:= OnTuples( fusion.map, - Inverse( ClassPermutation( destination ) ) ); - MakeImmutable( fusion.map ); + fusion.map:= MakeImmutable( OnTuples( fusion.map, + Inverse( ClassPermutation( destination ) ) ) ); fi; # Check that different stored fusions into the same table @@ -1121,11 +1122,9 @@ InstallGlobalFunction( StoreFusion, function( source, fusion, destination ) if not IsBound( fusion.specification ) or ( IsBound( fus.specification ) and fusion.specification = fus.specification ) then - Error( "fusion to already stored on ;\n", - " to store another one, assign different specifications", - " to both fusions" ); - + " to store another one, assign a different specification", + " to the new fusion record " ); fi; fi; @@ -3684,8 +3683,7 @@ InstallGlobalFunction( PowerMapsAllowedBySymmetrizations, for j in pow[ class ] do newpow:= List( pow, ShallowCopy ); newpow[ class ]:= j; - copy:= StructuralCopy( ComputedPowerMaps( tbl ) ); -#T really? + copy:= ShallowCopy( ComputedPowerMaps( tbl ) ); Unbind( copy[ prime ] ); if TestConsistencyMaps( copy, newpow, copy ) then newindet:= List( indeterminateness, ShallowCopy ); @@ -4201,7 +4199,6 @@ InstallGlobalFunction( FusionsAllowedByRestrictions, else powermaps:= ComputedPowerMaps( tbl ); fi; -#T document new parameters `testdec', `subpowermaps', `powermaps' # May we return immediately? if quick and Indeterminateness( fus ) < minamb then diff --git a/lib/ctblsymm.gi b/lib/ctblsymm.gi index bd9fa97f7f1..256eb81f15c 100644 --- a/lib/ctblsymm.gi +++ b/lib/ctblsymm.gi @@ -1187,8 +1187,8 @@ InstallGlobalFunction( CharacterTableWreathSymmetric, function( sub, n ) powermap:= tbl.ComputedPowerMaps; for prime in PrimeDivisors( tbl.Size ) do spm:= PowerMap( sub, prime ); - powermap[prime]:= List( [ 1 .. nccl ], - i -> Position(parts, PowerWreath(spm, parts[i], prime)) ); + powermap[prime]:= MakeImmutable( List( [ 1 .. nccl ], + i -> Position(parts, PowerWreath(spm, parts[i], prime)) ) ); od; # \ldots and `Irr'. @@ -1252,7 +1252,8 @@ InstallMethod( Irr, fun:= gentbl.powermap[1]; for p in PrimeDivisors( Size( G ) ) do if not IsBound( pow[p] ) then - pow[p]:= List( cp, x -> Position( cp, fun( deg, x[2], p ) ) ); + pow[p]:= MakeImmutable( + List( cp, x -> Position( cp, fun( deg, x[2], p ) ) ) ); fi; od; @@ -1837,6 +1838,7 @@ InstallValue( CharTableDoubleCoverSymmetric, MakeImmutable ( rec( fi; fi; od; + MakeImmutable( pow[p] ); od; # Make the character parameters unique. @@ -1861,9 +1863,10 @@ InstallValue( CharTableDoubleCoverSymmetric, MakeImmutable ( rec( OrdersClassRepresentatives:= ord, ComputedClassFusions:= [ rec( name:= Concatenation("Sym(",String(n),")"), - map:= fus ) ], - Irr:= Concatenation( CharTableSymmetric.matrix( n ) - { [ 1 .. nrparts ] }{ fus }, chars ) ); + map:= MakeImmutable( fus ) ) ], + Irr:= MakeImmutable( Concatenation( + CharTableSymmetric.matrix( n ) + { [ 1 .. nrparts ] }{ fus }, chars ) ) ); end, domain:= IsPosInt ) ) ); @@ -2125,6 +2128,7 @@ InstallValue( CharTableDoubleCoverAlternating, MakeImmutable( rec( fi; fi; od; + MakeImmutable( pow[p] ); od; # add the characters of Alt_n @@ -2160,12 +2164,12 @@ InstallValue( CharTableDoubleCoverAlternating, MakeImmutable( rec( ComputedClassFusions:= [ rec( name:= Concatenation( "Alt(", String( n ), ")" ), - map:= fus1 ), + map:= MakeImmutable( fus1 ) ), rec( name:= Concatenation( "2.Sym(", String( n ), ")" ), - map:= fus2 ) ], - Irr:= Concatenation( tbl.Irr{ - [ 1 .. Length( tbl.Irr ) ] }{ fus1 }, chars ) ); + map:= MakeImmutable( fus2 ) ) ], + Irr:= MakeImmutable( Concatenation( tbl.Irr{ + [ 1 .. Length( tbl.Irr ) ] }{ fus1 }, chars ) ) ); end, domain:= IsPosInt ) ) );