diff --git a/hpcgap/lib/coll.gd b/hpcgap/lib/coll.gd deleted file mode 100644 index 42adf031142..00000000000 --- a/hpcgap/lib/coll.gd +++ /dev/null @@ -1,3233 +0,0 @@ -############################################################################# -## -#W coll.gd GAP library Martin Schönert -#W & Thomas Breuer -## -## -#Y Copyright (C) 1997, Lehrstuhl D für Mathematik, RWTH Aachen, Germany -#Y (C) 1998 School Math and Comp. Sci., University of St Andrews, Scotland -#Y Copyright (C) 2002 The GAP Group -## -## This file declares the operations for collections. -## - -#T change the installation of isomorphism and factor maintained methods -#T in the same way as that of subset maintained methods! - - -############################################################################# -## -## <#GAPDoc Label="[1]{coll}"> -## A collection in &GAP; consists of elements in the same family -## (see ). -## The most important kinds of collections are homogeneous lists -## (see ) -## and domains (see ). -## Note that a list is never a domain, and a domain is never a list. -## A list is a collection if and only if it is nonempty and homogeneous. -##

-## Basic operations for collections are -## and ; -## for finite collections, -## admits to delegate the other -## operations for collections -## (see  -## and ) -## to functions for lists (see ). -## Obviously, special methods depending on the arguments are needed for -## the computation of e.g. the intersection of two infinite -## domains. -## <#/GAPDoc> -## - - -############################################################################# -## -#C IsListOrCollection( ) -## -## <#GAPDoc Label="IsListOrCollection"> -## -## -## -## -## Several functions are defined for both lists and collections, -## for example , -## , -## and . -## is a supercategory of -## and -## (that is, all lists and collections lie in this category), -## which is used to describe the arguments of functions such as the ones -## listed above. -## -## -## <#/GAPDoc> -## -DeclareCategory( "IsListOrCollection", IsObject ); - - -############################################################################# -## -#C IsCollection( ) . . . . . . . . . test if an object is a collection -## -## <#GAPDoc Label="IsCollection"> -## -## -## -## -## tests whether an object is a collection. -##

-## Some of the functions for lists and collections are described in the -## chapter about lists, -## mainly in Section . -## In the current chapter, we describe those functions for which the -## collection aspect seems to be more important than the -## list aspect. -## -## -## <#/GAPDoc> -## -DeclareCategory( "IsCollection", IsListOrCollection ); - - -############################################################################# -## -#A CollectionsFamily( ) . . . . . . . . . . make a collections family -## -## <#GAPDoc Label="CollectionsFamily"> -## -## -## -## -## For a family Fam, returns the -## family of all collections over Fam, -## that is, of all dense lists and domains that consist of objects in -## Fam. -##

-## The call in the standard method of -## is executed with second argument -## , -## since every object in the collections family must be a collection, -## and with third argument the collections categories of the involved -## categories in the implied filter of Fam. -##

-## Note that families (see ) -## are used to describe relations between objects. -## Important such relations are that between an element e and each -## collection of elements that lie in the same family as e, -## and that between two collections whose elements lie in the same family. -## Therefore, all collections of elements in the family Fam form the -## new family CollectionsFamily( Fam ). -## -## -## <#/GAPDoc> -## -DeclareAttribute( "CollectionsFamily", IsFamily ); - - -############################################################################# -## -#C IsCollectionFamily( ) test if an object is a family of collections -## -## <#GAPDoc Label="IsCollectionFamily"> -## -## -## -## -## is true if Fam is a family of collections, -## and false otherwise. -## -## -## <#/GAPDoc> -## -DeclareCategoryFamily( "IsCollection" ); - - -############################################################################# -## -#A ElementsFamily( ) . . . . . . . . . . . . fetch the elements family -## -## <#GAPDoc Label="ElementsFamily"> -## -## -## -## -## If Fam is a collections family -## (see ) -## then -## returns the family from which Fam was created -## by . -## The way a collections family is created, it always has its elements -## family stored. -## If Fam is not a collections family then an error is signalled. -##

-## fam:= FamilyObj( (1,2) );; -## gap> collfam:= CollectionsFamily( fam );; -## gap> fam = collfam; fam = ElementsFamily( collfam ); -## false -## true -## gap> collfam = FamilyObj( [ (1,2,3) ] ); -## true -## gap> collfam = FamilyObj( Group( () ) ); -## true -## gap> collfam = CollectionsFamily( collfam ); -## false -## ]]> -## -## -## <#/GAPDoc> -## -DeclareAttribute( "ElementsFamily", IsFamily ); - - -############################################################################# -## -#V CATEGORIES_COLLECTIONS . . . . . . global list of collections categories -## -## -## -## -## -## -## -## -BIND_GLOBAL( "CATEGORIES_COLLECTIONS", [] ); -ShareSpecialObj(CATEGORIES_COLLECTIONS); - -############################################################################# -## -#F CategoryCollections( ) . . . . . . . . . . collections category -## -## <#GAPDoc Label="CategoryCollections"> -## -## -## -## -## Let filter be a filter that is true for all elements of a -## family Fam, by the construction of Fam. -## Then returns the -## collections category of filter. -## This is a category that is true for all elements in -## CollectionsFamily( Fam ). -##

-## For example, the construction of -## guarantees that -## each of its elements lies in the filter -## , -## and each collection of permutations (permutation group or dense list of -## permutations) lies in the category CategoryCollections( IsPerm ). -## CategoryCollections( IsPerm ). -## Note that this works only if the collections category is created -## before the collections family. -## So it is necessary to construct interesting collections categories -## immediately after the underlying category has been created. -## -## -## <#/GAPDoc> -## -BIND_GLOBAL( "CategoryCollections", function ( elms_filter ) - local pair, super, flags, name, coll_filter, len; - - # check once with read lock -- common case - atomic readonly CATEGORIES_COLLECTIONS do - # Check whether the collections category is already defined. - for pair in CATEGORIES_COLLECTIONS do - if IsIdenticalObj( pair[1], elms_filter ) then - return pair[2]; - fi; - od; - len := LENGTH(CATEGORIES_COLLECTIONS); - od; # end atomic - - # that failed, so get exclusive lock as we may need to modify - atomic readwrite CATEGORIES_COLLECTIONS do - # Check whether in the meantime another thread defined the collections category - if LENGTH(CATEGORIES_COLLECTIONS) > len then - for pair in CATEGORIES_COLLECTIONS do - if IsIdenticalObj( pair[1], elms_filter ) then - return pair[2]; - fi; - od; - fi; - - # Find the super category among the known collections categories. - super := IsCollection; - flags := WITH_IMPS_FLAGS( FLAGS_FILTER( elms_filter ) ); - for pair in CATEGORIES_COLLECTIONS do - if IS_SUBSET_FLAGS( flags, FLAGS_FILTER( pair[1] ) ) then - super := super and pair[2]; - fi; - od; - - # Construct the name of the category. - name := "CategoryCollections("; - APPEND_LIST_INTR( name, SHALLOW_COPY_OBJ( NameFunction(elms_filter) ) ); - APPEND_LIST_INTR( name, ")" ); - CONV_STRING( name ); - - # Construct the collections category. - coll_filter:= NewCategory( name, super ); - ADD_LIST( CATEGORIES_COLLECTIONS, MakeImmutable([ elms_filter, coll_filter ]) ); - return coll_filter; - od; # end atomic -end ); - - -############################################################################# -## -#f DeclareCategoryCollections( ) -## -## binds the collections category of the category that is bound to the -## global variable with name to the global variable associated to the -## name . -## If is of the form `Collection' then is equal to -## `CollColl', -## if is of the form `Coll' then is equal to -## `CollColl', -## otherwise we have equal to `Collection'. -## -BIND_GLOBAL( "DeclareCategoryCollections", function( name ) - local len, coll_name; - - len:= LEN_LIST( name ); - if 3 < len and name{ [ len-3 .. len ] } = "Coll" then - coll_name:= SHALLOW_COPY_OBJ( name ); - APPEND_LIST_INTR( coll_name, "Coll" ); - elif 9 < len and name{ [ len-9 .. len ] } = "Collection" then - coll_name:= name{ [ 1 .. len-6 ] }; - APPEND_LIST_INTR( coll_name, "Coll" ); - else - coll_name:= SHALLOW_COPY_OBJ( name ); - APPEND_LIST_INTR( coll_name, "Collection" ); - fi; - - BIND_GLOBAL( coll_name, CategoryCollections( VALUE_GLOBAL( name ) ) ); -end ); - - -############################################################################# -## -#F DeclareSynonym( , ) -#F DeclareSynonymAttr( , ) -## -## <#GAPDoc Label="DeclareSynonym"> -## -## -## -## -## -## assigns the string name to a global -## variable as a synonym for value. -## Two typical intended usages are to declare an and-filter, e.g. -##

-## -##

-## and to provide a previously declared global function with an alternative -## name, e.g. -##

-## -##

-## Note: Before using in the way of this -## second example, -## one should determine whether the synonym is really needed. -## Perhaps an extra index entry in the documentation would be sufficient. -##

-## When value is actually an attribute then -## should be used; -## this binds also globals variables Setname and -## Hasname for its setter and tester, respectively. -##

-## -## -## -## <#/GAPDoc> -## -BIND_GLOBAL( "DeclareSynonym", function( name, value ) - if ISBOUND_GLOBAL(name) and IS_IDENTICAL_OBJ(VALUE_GLOBAL(name), value) then - if not REREADING then - INFO_DEBUG( 1, "multiple declarations for synonym `", name, "'\n" ); - fi; - else - BIND_GLOBAL( name, value ); - fi; -end ); - -BIND_GLOBAL( "DeclareSynonymAttr", function( name, value ) - local nname; - DeclareSynonym( name, value ); - nname:= "Set"; - APPEND_LIST_INTR( nname, name ); - DeclareSynonym( nname, Setter( value ) ); - nname:= "Has"; - APPEND_LIST_INTR( nname, name ); - DeclareSynonym( nname, Tester( value ) ); -end ); - - -############################################################################# -## -#V SUBSET_MAINTAINED_INFO -## -## -## -## -## -## is a list of length two. -## At the first position, a list of lists of the form -## [ filtsuper, filtsub, opr, testopr, settopr ] -## is stored, -## which is used for calls of UseSubsetRelation( super, sub ). -## At the second position, a corresponding list of lists of the form -## [ flagsopr, flagssub, rank ] -## is stored, which is used for choosing an appropriate ordering of the -## entries when the lists are enlarged in a call to -## InstallSubsetMaintenance. -##

-## The meaning of the entries is as follows. -## -## filtsuper -## -## required filter for super, -## -## filtsub -## -## required filter for sub, -## -## opr -## -## operation whose value is inherited from super to sub, -## -## testopr -## -## tester filter of opr, -## -## settopr -## -## setter filter of opr, -## -## flagsopr -## -## list of those true flags of opr -## that belong neither to categories nor to representations, -## -## flagssub -## -## list of those true flags of filtsub -## that belong neither to categories nor to representations, -## -## rank -## -## a rational number that denotes the priority of the information -## in the list; SUBSET_MAINTAINED_INFO is sorted according to -## decreasing rank value. -## -## -## -## -## -## -## -## -## -## -## -## -## -## -## -## -BIND_GLOBAL( "SUBSET_MAINTAINED_INFO", ShareSpecialObj([ [], [] ], - "SUBSET_MAINTAINED_INFO") ); - - -############################################################################# -## -#O UseSubsetRelation( , ) -## -## <#GAPDoc Label="UseSubsetRelation"> -## -## -## -## -## Methods for this operation transfer possibly useful information from the -## domain super to its subset sub, and vice versa. -##

-## is designed to be called automatically -## whenever substructures of domains are constructed. -## So the methods must be cheap, and the requirements should be as -## sharp as possible! -##

-## To achieve that all applicable methods are executed, all methods for -## this operation except the default method must end with TryNextMethod(). -## This default method deals with the information that is available by -## the calls of in the &GAP; library. -##

-## g:= Group( (1,2), (3,4), (5,6) );; h:= Group( (1,2), (3,4) );; -## gap> IsAbelian( g ); HasIsAbelian( h ); -## true -## false -## gap> UseSubsetRelation( g, h );; HasIsAbelian( h ); IsAbelian( h ); -## true -## true -## ]]> -## -## -## <#/GAPDoc> -## -DeclareOperation( "UseSubsetRelation", [ IsCollection, IsCollection ] ); - -InstallMethod( UseSubsetRelation, - "default method that checks maintenances and then returns `true'", - IsIdenticalObj, - [ IsCollection, IsCollection ], - # Make sure that this method is installed with ``real'' rank zero. - - 2 * RankFilter( IsCollection ), - function( super, sub ) - - local entry; - - atomic readonly SUBSET_MAINTAINED_INFO do - for entry in SUBSET_MAINTAINED_INFO[1] do - if entry[1]( super ) and entry[2]( sub ) and not entry[4]( sub ) then - entry[5]( sub, entry[3]( super ) ); - fi; - od; - od; # end atomic - - return true; - end ); - - -############################################################################# -## -#F InstallSubsetMaintenance( , , ) -## -## <#GAPDoc Label="InstallSubsetMaintenance"> -## -## -## -## -## opr must be a property or an attribute. -## The call of has the effect that -## for a domain D in the filter super_req, -## and a domain S in the filter sub_req, -## the call UseSubsetRelation( D, S ) -## (see ) -## sets a known value of opr for D as value of opr also -## for S. -## A typical example for which is -## applied is given by opr = IsFinite, -## super_req = IsCollection and IsFinite, -## and sub_req = IsCollection. -##

-## If opr is a property and the filter super_req lies in the -## filter opr then we can use also the following inverse implication. -## If D is in the filter whose intersection with opr is -## super_req and if S is in the filter sub_req, -## S is a subset of D, and the value of opr for -## S is false then the value of opr for D is -## also false. -## -## -## -## <#/GAPDoc> -## -BIND_GLOBAL( "InstallSubsetMaintenance", - function( operation, super_req, sub_req ) - - local setter, # setter filter of `operation' - tester, # tester filter of `operation' - upper, - lower, - attrprop, # id `operation' an attribute/property? - rank, - filtssub, # property and attribute flags of `sub_req' - filtsopr, # property and attribute flags of `operation' - triple, # loop over `SUBSET_MAINTAINED_INFO[2]' - req, - flag, - filt1, - filt2, - i; - - setter:= Setter( operation ); - tester:= Tester( operation ); - - # Are there methods that may give us some of the requirements? - upper:= SUM_FLAGS; - - # (We must not call `SUBTR_SET' here because the lists types may be - # not yet defined.) - filtssub:= []; - atomic readwrite SUBSET_MAINTAINED_INFO do - for flag in TRUES_FLAGS( FLAGS_FILTER( sub_req ) ) do - if not INFO_FILTERS[flag] in FNUM_CATS_AND_REPS then - ADD_LIST_DEFAULT( filtssub, flag ); - fi; - od; - - for triple in SUBSET_MAINTAINED_INFO[2] do - req:= SHALLOW_COPY_OBJ( filtssub ); - INTER_SET( req, triple[1] ); - if LEN_LIST( req ) <> 0 and triple[3] < upper then - upper:= triple[3]; - fi; - od; - - # Are there methods that require `operation'? - lower:= 0; - attrprop:= true; - filt1:= FLAGS_FILTER( operation ); - if filt1 = false then - - # `operation' is an attribute. - filt1:= FLAGS_FILTER( tester ); - - else - - # Special treatment of categories, representations (makes sense?), - # and filters created by `NewFilter'. - if FLAG2_FILTER( operation ) = 0 then - attrprop:= false; - fi; - - fi; - - # (We must not call `SUBTR_SET' here because the lists types may be - # not yet defined.) - filtsopr:= []; - for flag in TRUES_FLAGS( filt1 ) do - if not INFO_FILTERS[flag] in FNUM_CATS_AND_REPS then - ADD_LIST_DEFAULT( filtsopr, flag ); - fi; - od; - for triple in SUBSET_MAINTAINED_INFO[2] do - req:= SHALLOW_COPY_OBJ( filtsopr ); - INTER_SET( req, triple[2] ); - if LEN_LIST( req ) <> 0 and lower < triple[3] then - lower:= triple[3]; - fi; - od; - - # Compute the ``rank'' of the maintenance. - # (Do we have a cycle?) - if upper <= lower then - Print( "#W warning: cycle in `InstallSubsetMaintenance'\n" ); - rank:= lower; - else - rank:= ( upper + lower ) / 2; - fi; - - filt1:= IsCollection and Tester( super_req ) and super_req and tester; - filt2:= IsCollection and Tester( sub_req ) and sub_req; - - # Update the info list. - i:= LEN_LIST( SUBSET_MAINTAINED_INFO[2] ); - while 0 < i and SUBSET_MAINTAINED_INFO[2][i][3] < rank do - SUBSET_MAINTAINED_INFO[1][ i+1 ]:= SUBSET_MAINTAINED_INFO[1][ i ]; - SUBSET_MAINTAINED_INFO[2][ i+1 ]:= SUBSET_MAINTAINED_INFO[2][ i ]; - i:= i-1; - od; - SUBSET_MAINTAINED_INFO[2][ i+1 ]:= - MakeImmutable([ filtsopr, filtssub, rank ]); - if attrprop then - SUBSET_MAINTAINED_INFO[1][ i+1 ]:= - MakeImmutable([ filt1, filt2, operation, tester, setter ]); - else - SUBSET_MAINTAINED_INFO[1][ i+1 ]:= MakeImmutable( - [ filt1, filt2, operation, operation, - function( sub, val ) - SetFeatureObj( sub, operation, val ); - end ]); - fi; - od; # end atomic - -#T missing in new implementation! -# # Install the method. -# if FLAGS_FILTER( operation ) <> false -# and IS_EQUAL_FLAGS( FLAGS_FILTER( operation and sub_req ), -# FLAGS_FILTER( super_req ) ) then -# InstallMethod( UseSubsetRelation, infostring, IsIdenticalObj, -# [ sub_req, sub_req ], 0, -# function( super, sub ) -# if tester( sub ) and not operation( sub ) then -# setter( super, false ); -# fi; -# TryNextMethod(); -# end ); -# fi; -end ); - - -############################################################################# -## -#V ISOMORPHISM_MAINTAINED_INFO -## -## -## -## -## -## is a list of lists of the form -## [ filtsold, filtsnew, opr, testopr, settopr, old_req, -## new-req ] -## which is used for calls of UseIsomorphismRelation( old, new ). -## This list is enlarged by calls to InstallIsomorphismMaintenance. -##

-## The meaning of the entries is as follows. -## -## filtsold -## -## required filter for old, -## -## filtsnew -## -## required filter for new, -## -## opr -## -## operation whose value is inherited from old to new, -## -## testopr -## -## tester filter of opr, -## -## settopr -## -## setter filter of opr, -## -## old-req -## -## requirements for old in the InstallIsomorphismMaintenance call, -## -## new-req -## -## requirements for new in the InstallIsomorphismMaintenance call. -## -## -## -## -## -BIND_GLOBAL( "ISOMORPHISM_MAINTAINED_INFO", ShareSpecialObj([], - "ISOMORPHISM_MAINTAINED_INFO")); - - -############################################################################# -## -#O UseIsomorphismRelation( , ) -## -## <#GAPDoc Label="UseIsomorphismRelation"> -## -## -## -## -## Methods for this operation transfer possibly useful information from the -## domain old to the isomorphic domain new. -##

-## is designed to be called -## automatically whenever isomorphic structures of domains are constructed. -## So the methods must be cheap, and the requirements should be as -## sharp as possible! -##

-## To achieve that all applicable methods are executed, all methods -## for this operation except the default method must end with a call to -## . -## This default method deals with the information that is available by -## the calls of in the &GAP; -## library. -##

-## g:= Group( (1,2) );; h:= Group( [ [ -1 ] ] );; -## gap> Size( g ); HasSize( h ); -## 2 -## false -## gap> UseIsomorphismRelation( g, h );; HasSize( h ); Size( h ); -## true -## 2 -## ]]> -## -## -## <#/GAPDoc> -## -DeclareOperation( "UseIsomorphismRelation", [ IsCollection, IsCollection ] ); - -InstallMethod( UseIsomorphismRelation, - "default method that checks maintenances and then returns `true'", - [ IsCollection, IsCollection ], - # Make sure that this method is installed with ``real'' rank zero. - - 2 * RankFilter( IsCollection ), - function( old, new ) - local entry; - - atomic readonly ISOMORPHISM_MAINTAINED_INFO do - for entry in ISOMORPHISM_MAINTAINED_INFO do - if entry[1]( old ) and entry[2]( new ) and not entry[4]( new ) then - entry[5]( new, entry[3]( old ) ); - fi; - od; - od; # end atomic - - return true; - end ); - - -############################################################################# -## -#F InstallIsomorphismMaintenance( , , ) -## -## <#GAPDoc Label="InstallIsomorphismMaintenance"> -## -## -## -## -## opr must be a property or an attribute. -## The call of has the effect -## that for a domain D in the filter old_req, -## and a domain E in the filter new_req, -## the call UseIsomorphismRelation( D, E ) -## (see ) -## sets a known value of opr for D as value of opr also -## for E. -## A typical example for which -## is applied is given by opr = Size, -## old_req = IsCollection, -## and new_req = IsCollection. -## -## -## -## -## -## <#/GAPDoc> -## -BIND_GLOBAL( "InstallIsomorphismMaintenance", - function( opr, old_req, new_req ) - local tester; - - tester:= Tester( opr ); - - atomic ISOMORPHISM_MAINTAINED_INFO do - ADD_LIST( ISOMORPHISM_MAINTAINED_INFO, MakeImmutable( - [ IsCollection and Tester( old_req ) and old_req and tester, - IsCollection and Tester( new_req ) and new_req, - opr, - tester, - Setter( opr ), - old_req, - new_req ] ) ); - od; # end atomic -end ); - - -############################################################################# -## -#V FACTOR_MAINTAINED_INFO -## -## -## -## -## -## is a list of lists of the form -## [ filtsnum, filtsden, filtsfac, opr, testopr, settopr ] -## which is used for calls of UseFactorRelation( num, den, fac ). -## This list is enlarged by calls to InstallFactorMaintenance. -##

-## The meaning of the entries is as follows. -## -## filtsnum -## -## required filter for num, -## -## filtsden -## -## required filter for den, -## -## filtsfac -## -## required filter for fac, -## -## opr -## -## operation whose value is inherited from num to fac, -## -## testopr -## -## tester filter of opr, -## -## settopr -## -## setter filter of opr. -## -## -## -## -## -BIND_GLOBAL( "FACTOR_MAINTAINED_INFO", ShareSpecialObj([], "FACTOR_MAINTAINED_INFO") ); - - -############################################################################# -## -#O UseFactorRelation( , , ) -## -## <#GAPDoc Label="UseFactorRelation"> -## -## -## -## -## Methods for this operation transfer possibly useful information from the -## domain numer or its subset denom to the domain -## factor that is isomorphic to the factor of numer by -## denom, and vice versa. -## denom may be fail, for example if factor is just -## known to be a factor of numer but denom is not available as -## a &GAP; object; -## in this case those factor relations are used that are installed without -## special requirements for denom. -##

-## is designed to be called automatically -## whenever factor structures of domains are constructed. -## So the methods must be cheap, and the requirements should be as -## sharp as possible! -##

-## To achieve that all applicable methods are executed, all methods -## for this operation except the default method must end with a call to -## . -## This default method deals with the information that is available by -## the calls of in the &GAP; library. -##

-## g:= Group( (1,2,3,4), (1,2) );; h:= Group( (1,2,3), (1,2) );; -## gap> IsSolvableGroup( g ); HasIsSolvableGroup( h ); -## true -## false -## gap> UseFactorRelation(g, Subgroup( g, [ (1,2)(3,4), (1,3)(2,4) ] ), h);; -## gap> HasIsSolvableGroup( h ); IsSolvableGroup( h ); -## true -## true -## ]]> -## -## -## <#/GAPDoc> -## -DeclareOperation( "UseFactorRelation", - [ IsCollection, IsObject, IsCollection ] ); - -InstallMethod( UseFactorRelation, - "default method that checks maintenances and then returns `true'", - true, - [ IsCollection, IsObject, IsCollection ], - # Make sure that this method is installed with ``real'' rank zero. - - 2 * RankFilter( IsCollection )-RankFilter(IsObject), - function( num, den, fac ) - - local entry; - - atomic readonly FACTOR_MAINTAINED_INFO do - for entry in FACTOR_MAINTAINED_INFO do - if entry[1]( num ) and entry[2]( den ) and entry[3]( fac ) - and not entry[5]( fac ) then - entry[6]( fac, entry[4]( num ) ); - fi; - od; - od; # end atomic - - return true; - end ); - - -############################################################################# -## -#F InstallFactorMaintenance( , , , ) -## -## <#GAPDoc Label="InstallFactorMaintenance"> -## -## -## -## -## opr must be a property or an attribute. -## The call of has the effect that -## for collections N, D, F in the filters -## numer_req, denom_req, and factor_req, respectively, -## the call UseFactorRelation( N, D, F ) -## (see ) -## sets a known value of opr for N as value of opr also -## for F. -## A typical example for which is -## applied is given by opr = IsFinite, -## numer_req = IsCollection and IsFinite, -## denom_req = IsCollection, -## and factor_req = IsCollection. -##

-## For the other direction, if numer_req involves the filter -## opr then a known false value of opr for F -## implies a false value for D provided that D lies in -## the filter obtained from numer_req by removing opr. -##

-## Note that an implication of a factor relation holds in particular for the -## case of isomorphisms. -## So one need not install an isomorphism maintained method when -## a factor maintained method is already installed. -## For example, -## will transfer a known value because of the -## installed factor maintained method. -## -## -## <#/GAPDoc> -## -BIND_GLOBAL( "InstallFactorMaintenance", - function( opr, numer_req, denom_req, factor_req ) - - local tester; - - # Information that is maintained under taking factors - # is especially maintained under isomorphisms. - InstallIsomorphismMaintenance( opr, numer_req, factor_req ); - - tester:= Tester( opr ); - - atomic FACTOR_MAINTAINED_INFO do - ADD_LIST( FACTOR_MAINTAINED_INFO, MakeImmutable( - [ IsCollection and Tester( numer_req ) and numer_req and tester, - Tester( denom_req ) and denom_req, - IsCollection and Tester( factor_req ) and factor_req, - opr, - tester, - Setter( opr ) ] ) ); - od; # end atomic - -#T not yet available in the new implementation -# if FLAGS_FILTER( opr ) <> false -# and IS_EQUAL_FLAGS( FLAGS_FILTER( opr and factor_req ), -# FLAGS_FILTER( numer_req ) ) then -# InstallMethod( UseFactorRelation, infostring, IsFamFamX, -# [ factor_req, denom_req, factor_req ], 0, -# function( numer, denom, factor ) -# if tester( factor ) and not opr( factor ) then -# setter( numer, false ); -# fi; -# TryNextMethod(); -# end ); -# fi; -end ); - - -############################################################################# -## -#O Iterator( ) . . . . . . . iterator for a list or collection -## -## <#GAPDoc Label="Iterator"> -## -## -## -## -## -## Iterators provide a possibility to loop over the elements of a -## (countable) collection or list listorcoll, without repetition. -## For many collections C, -## an iterator of C need not store all elements of C, -## for example it is possible to construct an iterator of some infinite -## domains, such as the field of rational numbers. -##

-## returns a mutable iterator iter for -## its argument. -## If this argument is a list (which may contain holes), -## then iter iterates over the elements (but not the holes) of this -## list in the same order (see  for details). -## If this argument is a collection but not a list then iter iterates -## over the elements of this collection in an unspecified order, -## which may change for repeated calls of . -## Because iterators returned by are mutable -## (see ), -## each call of for the same argument returns a -## new iterator. -## Therefore is not an attribute -## (see ). -##

-## The only operations for iterators are , -## , and . -## In particular, it is only possible to access the next element of the -## iterator with if there is one, -## and this can be checked with -## For an iterator iter, returns a -## mutable iterator new that iterates over the remaining elements -## independent of iter; -## the results of for iter and -## new are equal, -## and if iter is mutable then also the results of -## for iter and new are equal; -## note that = is not defined for iterators, -## so the equality of two iterators cannot be checked with =. -##

-## When is called for a mutable collection -## C then it is not defined whether iter respects changes to -## C occurring after the construction of iter, -## except if the documentation explicitly promises a certain behaviour. -## The latter is the case if the argument is a mutable list -## (see  for subtleties in this case). -##

-## It is possible to have for-loops run over mutable iterators -## instead of lists. -##

-## In some situations, one can construct iterators with a special -## succession of elements, -## see  for the possibility to loop over -## the elements of a vector space w.r.t. a given basis. -## -##

-## For lists, is implemented by -## . -## For collections C that are not lists, the default method is -## IteratorList( Enumerator( C ) ). -## Better methods depending on C should be provided if possible. -##

-## For random access to the elements of a (possibly infinite) collection, -## enumerators are used. -## See  for the facility to compute a list -## from C, which provides a (partial) mapping from C to the -## positive integers. -##

-## The filter means that the iterator is -## implemented as a component object and has components IsDoneIterator -## and NextIterator which are bound to the methods of the operations of -## the same name for this iterator. -## -## -## -## -## -## -## -## -## -## iter:= Iterator( GF(5) ); -## -## gap> l:= [];; -## gap> for i in iter do Add( l, i ); od; l; -## [ 0*Z(5), Z(5)^0, Z(5), Z(5)^2, Z(5)^3 ] -## gap> iter:= Iterator( [ 1, 2, 3, 4 ] );; l:= [];; -## gap> for i in iter do -## > new:= ShallowCopy( iter ); -## > for j in new do Add( l, j ); od; -## > od; l; -## [ 2, 3, 4, 3, 4, 4 ] -## ]]> -## -## -## <#/GAPDoc> -## -DeclareFilter("IsStandardIterator"); -DeclareOperation( "Iterator", [ IsListOrCollection ] ); - - -############################################################################# -## -#O IteratorSorted( ) . . . . . . . . . . . set iterator for a collection -#O IteratorSorted( ) . . . . . . . . . . . . set iterator for a list -## -## <#GAPDoc Label="IteratorSorted"> -## -## -## -## -## returns a mutable iterator. -## The argument must be a collection or a list that is not -## necessarily dense but whose elements lie in the same family -## (see ). -## It loops over the different elements in sorted order. -##

-## For a collection C that is not a list, the generic method is -## IteratorList( EnumeratorSorted( C ) ). -## -## -## <#/GAPDoc> -## -DeclareOperation( "IteratorSorted", [ IsListOrCollection ] ); - - -############################################################################# -## -#C IsIterator( ) . . . . . . . . . . test if an object is an iterator -## -## <#GAPDoc Label="IsIterator"> -## -## -## -## -## Every iterator lies in the category IsIterator. -## -## -## <#/GAPDoc> -## -DeclareCategory( "IsIterator", IsObject ); - - -############################################################################# -## -#O IsDoneIterator( ) . . . . . . . test if an iterator is exhausted -## -## <#GAPDoc Label="IsDoneIterator"> -## -## -## -## -## If iter is an iterator for the list or collection C then -## IsDoneIterator( iter ) is true if all elements of -## C have been returned already by NextIterator( iter ), -## and false otherwise. -## -## -## <#/GAPDoc> -## -DeclareOperation( "IsDoneIterator", [ IsIterator ] ); - - -############################################################################# -## -#O NextIterator( ) . . . . . . . . . . next element from an iterator -## -## <#GAPDoc Label="NextIterator"> -## -## -## -## -## Let iter be a mutable iterator for the list or collection C. -## If IsDoneIterator( iter ) is false then -## is applicable to iter, -## and the result is the next element of C, -## according to the succession defined by iter. -##

-## If IsDoneIterator( iter ) is true then it is not -## defined what happens when is called for -## iter; -## that is, it may happen that an error is signalled or that something -## meaningless is returned, or even that &GAP; crashes. -##

-## iter:= Iterator( [ 1, 2, 3, 4 ] ); -## -## gap> sum:= 0;; -## gap> while not IsDoneIterator( iter ) do -## > sum:= sum + NextIterator( iter ); -## > od; -## gap> IsDoneIterator( iter ); sum; -## true -## 10 -## gap> ir:= Iterator( Rationals );; -## gap> l:= [];; for i in [1..20] do Add( l, NextIterator( ir ) ); od; l; -## [ 0, 1, -1, 1/2, 2, -1/2, -2, 1/3, 2/3, 3/2, 3, -1/3, -2/3, -3/2, -3, -## 1/4, 3/4, 4/3, 4, -1/4 ] -## gap> for i in ir do -## > if DenominatorRat( i ) > 10 then break; fi; -## > od; -## gap> i; -## 1/11 -## ]]> -## -## -## <#/GAPDoc> -## -DeclareOperation( "NextIterator", [ IsIterator and IsMutable ] ); - - -############################################################################# -## -#F TrivialIterator( ) -## -## <#GAPDoc Label="TrivialIterator"> -## -## -## -## -## is a mutable iterator for the collection [ elm ] that -## consists of exactly one element elm -## (see ). -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "TrivialIterator" ); - - -############################################################################# -## -#F IteratorByFunctions( ) -## -## <#GAPDoc Label="IteratorByFunctions"> -## -## -## -## -## returns a (mutable) iterator -## iter for which , -## , -## and -## are computed via prescribed functions. -##

-## Let record be a record with at least the following components. -## -## NextIterator -## -## a function taking one argument iter, -## which returns the next element of iter -## (see ); -## for that, the components of iter are changed, -## -## IsDoneIterator -## -## a function taking one argument iter, -## which returns the value of iter, -## -## ShallowCopy -## -## a function taking one argument iter, -## which returns a record for which -## can be called in order to create a new iterator that is independent -## of iter but behaves like iter w.r.t. the operations -## and . -## -## ViewObj and PrintObj -## -## two functions that print what one wants to be printed when -## View( iter ) or Print( item ) is called -## (see ), -## if the ViewObj component is missing then the PrintObj -## method is used as a default. -## -## -## Further (data) components may be contained in record which can be -## used by these function. -##

-## does not make a shallow copy of -## record, this record is changed in place -## (see Section  ). -##

-## Iterators constructed with are in the -## filter . -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "IteratorByFunctions" ); - - -############################################################################# -## -#P IsEmpty( ) . . . . . . . . . . . . . . test if a collection is empty -#P IsEmpty( ) . . . . . . . . . . . . . test if a collection is empty -## -## <#GAPDoc Label="IsEmpty"> -## -## -## -## -## returns true if the collection or list -## listorcoll is empty (that is it contains no elements), -## and false otherwise. -## -## -## <#/GAPDoc> -## -DeclareProperty( "IsEmpty", IsListOrCollection ); - - -############################################################################# -## -#P IsTrivial( ) . . . . . . . . . . . . test if a collection is trivial -## -## <#GAPDoc Label="IsTrivial"> -## -## -## -## -## returns true if the collection C -## consists of exactly one element. -## -## -## -## <#/GAPDoc> -## -DeclareProperty( "IsTrivial", IsCollection ); - -InstallFactorMaintenance( IsTrivial, - IsCollection and IsTrivial, IsObject, IsCollection ); - - -############################################################################# -## -#P IsNonTrivial( ) . . . . . . . . . test if a collection is nontrivial -## -## <#GAPDoc Label="IsNonTrivial"> -## -## -## -## -## returns true if the collection C -## is empty or consists of at least two elements -## (see ). -##

-## -## -## -## IsEmpty( [] ); IsEmpty( [ 1 .. 100 ] ); IsEmpty( Group( (1,2,3) ) ); -## true -## false -## false -## gap> IsFinite( [ 1 .. 100 ] ); IsFinite( Integers ); -## true -## false -## gap> IsTrivial( Integers ); IsTrivial( Group( () ) ); -## false -## true -## gap> IsNonTrivial( Integers ); IsNonTrivial( Group( () ) ); -## true -## false -## ]]> -## -## -## <#/GAPDoc> -## -DeclareProperty( "IsNonTrivial", IsCollection ); - - -############################################################################# -## -#P IsFinite( ) . . . . . . . . . . . . . test if a collection is finite -## -## <#GAPDoc Label="IsFinite"> -## -## -## -## -## finiteness test -## returns true if the collection C -## is finite, and false otherwise. -##

-## The default method for checks the size -## (see ) of C. -##

-## Methods for may call , -## but methods for must not call -## . -## -## -## <#/GAPDoc> -## -DeclareProperty( "IsFinite", IsCollection ); - -InstallSubsetMaintenance( IsFinite, - IsCollection and IsFinite, IsCollection ); -InstallFactorMaintenance( IsFinite, - IsCollection and IsFinite, IsObject, IsCollection ); - -InstallTrueMethod( IsFinite, IsTrivial ); - - -############################################################################# -## -#P IsWholeFamily( ) . . test if a collection contains the whole family -## -## <#GAPDoc Label="IsWholeFamily"> -## -## -## -## -## returns true if the collection -## C contains the whole family (see ) -## of its elements. -##

-## IsWholeFamily( Integers ) -## > ; # all rationals and cyclotomics lie in the family -## false -## gap> IsWholeFamily( Integers mod 3 ) -## > ; # all finite field elements in char. 3 lie in this family -## false -## gap> IsWholeFamily( Integers mod 4 ); -## true -## gap> IsWholeFamily( FreeGroup( 2 ) ); -## true -## ]]> -## -## -## <#/GAPDoc> -## -DeclareProperty( "IsWholeFamily", IsCollection ); - - -############################################################################# -## -#A Size( ) . . . . . . . . . . . . . . . . . . . . size of a collection -#A Size( ) . . . . . . . . . . . . . . . . . . size of a collection -## -## <#GAPDoc Label="Size"> -## -## -## -## -## size -## order -## returns the size of the list or collection -## listorcoll, which is either an integer or . -## If the argument is a list then the result is its length -## (see ). -##

-## The default method for checks the length of an -## enumerator of listorcoll. -##

-## Methods for may call , -## but methods for must not call . -##

-## Size( [1,2,3] ); Size( Group( () ) ); Size( Integers ); -## 3 -## 1 -## infinity -## ]]> -## -## -## <#/GAPDoc> -## -DeclareAttribute( "Size", IsListOrCollection ); - -InstallIsomorphismMaintenance( Size, IsCollection, IsCollection ); - - -############################################################################# -## -#A Representative( ) . . . . . . . . . . . . one element of a collection -## -## <#GAPDoc Label="Representative"> -## -## -## -## -## returns a representative -## of the collection C. -##

-## Note that is free in choosing -## a representative if there are several elements in C. -## It is not even guaranteed that returns -## the same representative if it is called several times for one collection. -## The main difference between and -## -## is that is free -## to choose a value that is cheap to compute, -## while -## must make an effort to randomly distribute its answers. -##

-## If C is a domain then there are methods for -## that try -## to fetch an element from any known generator list of C, -## see . -## Note that does not try to compute -## generators of C, -## thus may give up and signal an error -## if C has no generators stored at all. -## -## -## <#/GAPDoc> -## -DeclareAttribute( "Representative", IsListOrCollection ); - - -############################################################################# -## -#A RepresentativeSmallest( ) . . . . . smallest element of a collection -## -## <#GAPDoc Label="RepresentativeSmallest"> -## -## -## -## -## representative -## returns the smallest element in the collection C, w.r.t. the -## ordering . -## While the operation defaults to comparing all elements, -## better methods are installed for some collections. -##

-## Representative( Rationals ); -## 0 -## gap> Representative( [ -1, -2 .. -100 ] ); -## -1 -## gap> RepresentativeSmallest( [ -1, -2 .. -100 ] ); -## -100 -## ]]> -## -## -## <#/GAPDoc> -## -DeclareAttribute( "RepresentativeSmallest", IsListOrCollection ); - - -############################################################################# -## -#O Random( ) . . . . . . . . . . random element of a list or collection -#O Random( ) . . . . . . . . random element of a list or collection -#O Random( , ) -## -## <#GAPDoc Label="Random:coll"> -## -## -## -## -## -## -## -## returns a -## (pseudo-)random element of the list or collection listorcoll. -##

-## As lists or ranges are restricted in length (2^{28}-1 or -## 2^{60}-1 depending on your system), the second form returns a -## random integer in the range from to to (inclusive) for -## arbitrary integers from and to. -##

-## The distribution of elements returned by -## depends -## on the argument. -## For a list the distribution is uniform (all elements are equally likely). -## The same holds usually for finite collections that are -## not lists. -## For infinite collections some reasonable distribution is used. -##

-## See the chapters of the various collections to find out -## which distribution is being used. -##

-## For some collections ensuring a reasonable distribution can be -## difficult and require substantial runtime (for example for large -## finite groups). If speed is more important than a guaranteed -## distribution, -## the operation should be used instead. -##

-## Note that -## is of course not an attribute. -##

-## Random([1..6]); -## 6 -## gap> Random(1, 2^100); -## 866227015645295902682304086250 -## gap> g:= Group( (1,2,3) );; Random( g ); Random( g ); -## (1,3,2) -## () -## gap> Random(Rationals); -## -4 -## ]]> -## -## -## <#/GAPDoc> -## -DeclareOperation( "Random", [ IsListOrCollection ] ); -DeclareOperation( "Random", [ IS_INT, IS_INT ] ); - - -############################################################################# -## -## <#GAPDoc Label="[2]{coll}"> -## The method used by &GAP; to obtain random elements may depend on the -## type object. -##

-## Most methods which produce random elements in &GAP; use a global random -## number generator (see ). -## This random number generator is (deliberately) initialized to the same -## values when &GAP; is started, so different runs of &GAP; with the same -## input will always produce the same result, even if random calculations -## are involved. -##

-## See for a description of how to reset the -## random number generator to a previous state. -##

-## <#/GAPDoc> -## - - -############################################################################# -## -#F RandomList( ) -## -## <#GAPDoc Label="RandomList"> -## -## -## -## -## random seed -## For a dense list list, -## returns a (pseudo-)random element with equal -## distribution. -##

-## The random source rs is used to choose a random number. -## If rs is absent, -## this function uses the to produce the -## random elements (a source of high quality random numbers). -##

-## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "RandomList" ); - - -############################################################################# -## -#O PseudoRandom( ) . . . . . . . . pseudo random element of a collection -#O PseudoRandom( ) . . . . . . . . . pseudo random element of a list -## -## <#GAPDoc Label="PseudoRandom"> -## -## -## -## -## returns a pseudo random element -## of the list or collection listorcoll, -## which can be roughly described as follows. -## For a list, returns the same as -## . -## For collections that are not lists, -## the elements returned by are -## not necessarily equally distributed, -## even for finite collections; -## the idea is that -## returns elements according to -## a reasonable distribution, returns elements -## that are cheap to compute but need not satisfy this strong condition, and -## returns arbitrary elements, -## probably the same element for each call. -## -## -## <#/GAPDoc> -## -DeclareOperation( "PseudoRandom", [ IsListOrCollection ] ); - - -############################################################################# -## -#A PseudoRandomSeed( ) -## -## -## -## -## -## -## -## -DeclareAttribute( "PseudoRandomSeed", IsListOrCollection, "mutable" ); - - -############################################################################# -## -#A Enumerator( ) . . . . . . . . . . . list of elements of a collection -#A Enumerator( ) . . . . . . . . . . . . list of elements of a list -## -## <#GAPDoc Label="Enumerator"> -## -## -## -## -## returns an immutable list enum. -## If the argument is a list (which may contain holes), -## then Length( enum ) is the length of this list, -## and enum contains the elements (and holes) of this list in the -## same order. -## If the argument is a collection that is not a list, -## then Length( enum ) is the number of different -## elements of C, -## and enum contains the different elements of the collection in an -## unspecified order, which may change for repeated calls of -## . -## enum[pos] may not execute in constant time -## (see ), -## and the size of enum in memory is as small as is feasible. -##

-## For lists, the default method is . -## For collections that are not lists, there is no default method. -## -## -## <#/GAPDoc> -## -DeclareAttribute( "Enumerator", IsListOrCollection ); - - -############################################################################# -## -#A EnumeratorSorted( ) . . . . . proper set of elements of a collection -#A EnumeratorSorted( ) . . . . . . proper set of elements of a list -## -## <#GAPDoc Label="EnumeratorSorted"> -## -## -## -## -## returns an immutable list enum. -## The argument must be a collection or a list listorcoll -## which may contain holes but whose elements lie in the same family -## (see ). -## Length( enum ) is the number of different elements -## of the argument, -## and enum contains the different elements in sorted order, -## w.r.t. <. -## enum[pos] may not execute in constant time -## (see ), -## and the size of enum in memory is as small as is feasible. -##

-## Enumerator( [ 1, 3,, 2 ] ); -## [ 1, 3,, 2 ] -## gap> enum:= Enumerator( Rationals );; elm:= enum[ 10^6 ]; -## -69/907 -## gap> Position( enum, elm ); -## 1000000 -## gap> IsMutable( enum ); IsSortedList( enum ); -## false -## false -## gap> IsConstantTimeAccessList( enum ); -## false -## gap> EnumeratorSorted( [ 1, 3,, 2 ] ); -## [ 1, 2, 3 ] -## ]]> -## -## -## <#/GAPDoc> -## -DeclareAttribute( "EnumeratorSorted", IsListOrCollection ); - - -############################################################################# -## -#F EnumeratorOfSubset( , [, ] ) -## -## -## -## -## -## Let list be a list, and blist a Boolean list of the same -## length (see ). -## returns a list new of length -## equal to the number of true entries in blist, -## such that new[i], if bound, equals the entry of list -## at the i-th true position in blist. -##

-## If list is homogeneous then also new is homogeneous. -## If list is not homogeneous then the third argument -## ishomog must be present and equal to true or false, -## saying whether or not new is homogeneous. -##

-## This construction is used for example in the situation that list -## is an enumerator of a large set, -## and blist describes a union of orbits in an action on this set. -## -## -## -DeclareGlobalFunction( "EnumeratorOfSubset" ); - - -############################################################################# -## -#F EnumeratorByFunctions( , ) -#F EnumeratorByFunctions( , ) -## -## <#GAPDoc Label="EnumeratorByFunctions"> -## EnumeratorByFunctions -## -## -## -## -## -## -## returns an immutable, dense, and duplicate-free list enum for -## which , -## element access via , -## , and -## are computed via prescribed functions. -##

-## Let record be a record with at least the following components. -## -## ElementNumber -## -## a function taking two arguments enum and pos, -## which returns enum[ pos ] -## (see ); -## it can be assumed that the argument pos is a positive integer, -## but pos may be larger than the length of enum -## (in which case an error must be signalled); -## note that the result must be immutable since enum itself is -## immutable, -## -## NumberElement -## -## a function taking two arguments enum and elm, -## which returns Position( enum, elm ) -## (see ); -## it cannot be assumed that elm is really contained in -## enum (and fail must be returned if not); -## note that for the three argument version of , -## the method that is available for duplicate-free lists suffices. -## -## -##

-## Further (data) components may be contained in record -## which can be used by these function. -##

-## If the first argument is a domain D then enum lists the -## elements of D (in general enum is not sorted), -## and methods for , -## , -## and may use D. -## -##

-## If one wants to describe the result without creating a domain then the -## elements are given implicitly by the functions in record, -## and the first argument must be a family Fam which will become the -## family of enum; -## if enum is not homogeneous then Fam must be -## ListsFamily, -## otherwise it must be the collections family of any element in enum. -## In this case, additionally the following component in record is -## needed. -##

-## -## Length -## -## a function taking the argument enum, -## which returns the length of enum -## (see ). -## -## -##

-## The following components are optional; they are used if they are present -## but default methods are installed for the case that they are missing. -## -## IsBound\[\] -## -## a function taking two arguments enum and k, -## which returns IsBound( enum[ k ] ) -## (see ); -## if this component is missing then is used for -## computing the result, -## -## Membership -## -## a function taking two arguments elm and enum, -## which returns true is elm is an element of enum, -## and false otherwise -## (see ); -## if this component is missing then NumberElement is used -## for computing the result, -## -## AsList -## -## a function taking one argument enum, which returns a list with -## the property that the access to each of its elements will take -## roughly the same time -## (see ); -## if this component is missing then -## is used for computing the result, -## -## ViewObj and PrintObj -## -## two functions that print what one wants to be printed when -## View( enum ) or Print( enum ) is called -## (see ), -## if the ViewObj component is missing then the PrintObj -## method is used as a default. -## -## -##

-## If the result is known to have additional properties such as being -## strictly sorted (see ) then it can be -## useful to set these properties after the construction of the enumerator, -## before it is used for the first time. -## And in the case that a new sorted enumerator of a domain is implemented -## via , -## and this construction is -## installed as a method for the operation , -## then it should be installed also as a method for -## . -##

-## Note that it is not checked that -## -## really returns a dense and duplicate-free list. -## -## does not make a shallow copy of record, -## this record is changed in place, -## see . -##

-## It would be easy to implement a slightly generalized setup for -## enumerators that need not be duplicate-free (where the three argument -## version of is supported), -## but the resulting overhead for the methods seems not to be justified. -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "EnumeratorByFunctions" ); - - -############################################################################# -## -#A UnderlyingCollection( ) -## -## -## -## -## -## An enumerator of a domain can delegate the task to compute its length to -## Size for the underlying domain, and ViewObj and PrintObj methods -## may refer to this domain. -## -## -## -DeclareAttribute( "UnderlyingCollection", IsListOrCollection ); - - -############################################################################# -## -#F List( [, ] ) . . . . . . . list of elements of a collection -#F List( ) -## -## <#GAPDoc Label="List:list"> -## -## -## -## -## This function returns a new mutable list new of the same length -## as the list list (which may have holes). The entry new[i] -## is unbound if list[i] is unbound. Otherwise -## new[i] = func(list[i]). If the argument func is -## omitted, its default is , so this function does the -## same as (see also -## ). -##

-## List( [1,2,3], i -> i^2 ); -## [ 1, 4, 9 ] -## gap> List( [1..10], IsPrime ); -## [ false, true, true, false, true, false, true, false, false, false ] -## gap> List([,1,,3,4], x-> x > 2); -## [ , false,, true, true ] -## ]]> -##

-## (See also .) -## -## -## <#/GAPDoc> -## -## <#GAPDoc Label="List:coll"> -## -## -## -## -## For a collection C (see ) -## that is not a list, returns -## a new mutable list new such that Length( new ) -## is the number of different elements of C, -## and new contains the different elements of C in an -## unspecified order which may change for repeated calls. -## new[pos] executes in constant time -## (see ), -## and the size of new is proportional to its length. -## The generic method for this case is -## ShallowCopy( Enumerator( C ) ). -## -## -##

-## l:= List( Group( (1,2,3) ) ); -## [ (), (1,3,2), (1,2,3) ] -## gap> IsMutable( l ); IsSortedList( l ); IsConstantTimeAccessList( l ); -## true -## false -## true -## ]]> -##

-## (See also .) -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "List" ); - -DeclareOperation( "ListOp", [ IsListOrCollection ] ); -DeclareOperation( "ListOp", [ IsListOrCollection, IsFunction ] ); - - -############################################################################# -## -#O SortedList( ) -#O SortedList( ) -## -## <#GAPDoc Label="SortedList"> -## -## -## -## -## returns a new mutable and dense list new. -## The argument must be a collection or list listorcoll which may -## contain holes but whose elements lie in the same family -## (see ). -## Length( new ) is the number of elements of -## listorcoll, -## and new contains the elements in sorted order, -## w.r.t. <=. -## new[pos] executes in constant time -## (see ), -## and the size of new in memory is proportional to its length. -##

-## l:= SortedList( Group( (1,2,3) ) ); -## [ (), (1,2,3), (1,3,2) ] -## gap> IsMutable( l ); IsSortedList( l ); IsConstantTimeAccessList( l ); -## true -## true -## true -## gap> SortedList( [ 1, 2, 1,, 3, 2 ] ); -## [ 1, 1, 2, 2, 3 ] -## ]]> -## -## -## <#/GAPDoc> -## -DeclareOperation( "SortedList", [ IsListOrCollection ] ); - - -############################################################################# -## -#O SSortedList( ) . . . . . . . . . . . set of elements of a collection -#O SSortedList( ) . . . . . . . . . . . . . set of elements of a list -#O Set( ) -## -## <#GAPDoc Label="SSortedList"> -## -## -## -## -## -## (strictly sorted list) returns a new -## dense, mutable, and duplicate free list new. -## The argument must be a collection or list listorcoll -## which may contain holes but whose elements lie in the same family -## (see ). -## Length( new ) is the number of different elements of -## listorcoll, -## and new contains the different elements in strictly sorted order, -## w.r.t. . -## new[pos] executes in constant time -## (see ), -## and the size of new in memory is proportional to its length. -##

-## is simply a synonym for . -## -## -## -##

-## l:= SSortedList( Group( (1,2,3) ) ); -## [ (), (1,2,3), (1,3,2) ] -## gap> IsMutable( l ); IsSSortedList( l ); IsConstantTimeAccessList( l ); -## true -## true -## true -## gap> SSortedList( [ 1, 2, 1,, 3, 2 ] ); -## [ 1, 2, 3 ] -## ]]> -## -## -## <#/GAPDoc> -## -DeclareOperation( "SSortedList", [ IsListOrCollection ] ); -DeclareSynonym( "Set", SSortedList ); - - -############################################################################# -## -#A AsList( ) . . . . . . . . . . . . . list of elements of a collection -#A AsList( ) . . . . . . . . . . . . . . list of elements of a list -## -## <#GAPDoc Label="AsList"> -## -## -## -## -## returns a immutable list imm. -## If the argument is a list (which may contain holes), -## then Length( imm ) is the value of -## this list, -## and imm contains the elements (and holes) of of the list -## in the same order. -## If the argument is a collection that is not a list, -## then Length( imm ) is the number of different elements -## of this collection, and imm contains the different elements of -## the collection in an unspecified order, -## which may change for repeated calls of . -## imm[pos] executes in constant time -## (see ), -## and the size of imm in memory is proportional to its length. -##

-## If you expect to do many element tests in the resulting list, it might -## be worth to use a sorted list instead, using . -## -## -## -##

-## l:= AsList( [ 1, 3, 3,, 2 ] ); -## [ 1, 3, 3,, 2 ] -## gap> IsMutable( l ); IsSortedList( l ); IsConstantTimeAccessList( l ); -## false -## false -## true -## gap> AsList( Group( (1,2,3), (1,2) ) ); -## [ (), (2,3), (1,2), (1,2,3), (1,3,2), (1,3) ] -## ]]> -## -## -## <#/GAPDoc> -## -DeclareAttribute( "AsList", IsListOrCollection ); - - -############################################################################# -## -#A AsSortedList( ) -#A AsSortedList( ) -## -## <#GAPDoc Label="AsSortedList"> -## -## -## -## -## returns a dense and immutable list imm. -## The argument must be a collection or list listorcoll -## which may contain holes but whose elements lie in the same family -## (see ). -## Length( imm ) is the number of elements of the argument, -## and imm contains the elements in sorted order, -## w.r.t. <=. -## new[pos] executes in constant time -## (see ), -## and the size of imm in memory is proportional to its length. -##

-## The only difference to the operation -## is that returns an immutable list. -##

-## l:= AsSortedList( [ 1, 3, 3,, 2 ] ); -## [ 1, 2, 3, 3 ] -## gap> IsMutable( l ); IsSortedList( l ); IsConstantTimeAccessList( l ); -## false -## true -## true -## gap> IsSSortedList( l ); -## false -## ]]> -## -## -## <#/GAPDoc> -## -DeclareAttribute( "AsSortedList", IsListOrCollection ); - - -############################################################################# -## -#A AsSSortedList( ) . . . . . . . . . . set of elements of a collection -#A AsSSortedList( ) . . . . . . . . . . . . set of elements of a list -#A AsSet( ) -## -## <#GAPDoc Label="AsSSortedList"> -## -## -## -## -## -## elements -## (as strictly sorted list) returns -## a dense, immutable, and duplicate free list imm. -## The argument must be a collection or list listorcoll -## which may contain holes but whose elements lie in the same family -## (see ). -## Length( imm ) is the number of different elements -## of listorcoll, -## and imm contains the different elements in strictly sorted order, -## w.r.t. . -## imm[pos] executes in constant time -## (see ), -## and the size of imm in memory is proportional to its length. -##

-## Because the comparisons required for sorting can be very expensive for -## some kinds of objects, you should use instead -## if you do not require the result to be sorted. -##

-## The only difference to the operation -## is that returns an immutable list. -##

-## is simply a synonym for . -##

-## In general a function that returns a set of elements is free, in fact -## encouraged, to return a domain instead of the proper set of its elements. -## This allows one to keep a given structure, and moreover the -## representation by a domain object is usually more space efficient. -## must of course not do this, -## its only purpose is to create the proper set of elements. -## -## -## -##

-## l:= AsSSortedList( l ); -## [ 1, 2, 3 ] -## gap> IsMutable( l ); IsSSortedList( l ); IsConstantTimeAccessList( l ); -## false -## true -## true -## gap> AsSSortedList( Group( (1,2,3), (1,2) ) ); -## [ (), (2,3), (1,2), (1,2,3), (1,3,2), (1,3) ] -## ]]> -## -## -## <#/GAPDoc> -## -DeclareAttribute( "AsSSortedList", IsListOrCollection ); -DeclareSynonym( "AsSet", AsSSortedList ); - - -############################################################################# -## -#A AsSSortedListNonstored( ) -## -## -## -## -## -## returns the value of the list or collection -## C but ensures that this list -## (nor a permutation or substantial subset) will not be -## stored in attributes of C unless such a list is already stored. -## This permits to obtain an element list once -## without danger of clogging up memory in the long run. -##

-## Because of this guarantee of nonstorage, methods for -## may not default to -## , but only vice versa. -## -## -## -DeclareOperation( "AsSSortedListNonstored", [IsListOrCollection] ); - - -############################################################################# -## -#F Elements( ) -## -## <#GAPDoc Label="Elements"> -## -## -## -## -## does the same as , -## that is, the return value is a strictly sorted list of the elements in -## the list or collection C. -##

-## is only supported for backwards compatibility. -## In many situations, the sortedness of the element list for a -## collection is in fact not needed, and one can save a lot of time by -## asking for a list that is not necessarily sorted, -## using . -## If one is really interested in the strictly sorted list of elements in -## C then one should use or -## instead. -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "Elements" ); - - -############################################################################# -## -#F Sum( [, ] ) . . . . . . . . . . sum of the elements of a list -#F Sum( [, ] ) . . . . . . . . sum of the elements of a collection -#F Sum( , [, ] ) . . . . . sum of images under a function -#F Sum( , [, ] ) . . . . . . sum of images under a function -## -## <#GAPDoc Label="Sum"> -## -## -## -## -## Called with one argument, a dense list or collection listorcoll, -## returns the sum of the elements of listorcoll -## (see ). -##

-## Called with a dense list or collection listorcoll and a function -## func, which must be a function taking one argument, -## applies the function func -## to the elements of listorcoll, and returns the sum of the results. -## In either case returns 0 if the first argument -## is empty. -##

-## The general rules for arithmetic operations apply -## (see ), -## so the result is immutable if and only if all summands are immutable. -##

-## If listorcoll contains exactly one element then this element -## (or its image under func if applicable) itself is returned, -## not a shallow copy of this element. -##

-## If an additional initial value init is given, -## returns the sum of init and the elements of the -## first argument resp. of their images under the function func. -## This is useful for example if the first argument is empty and a different -## zero than 0 is desired, in which case init is returned. -##

-## Sum( [ 2, 3, 5, 7, 11, 13, 17, 19 ] ); -## 77 -## gap> Sum( [1..10], x->x^2 ); -## 385 -## gap> Sum( [ [1,2], [3,4], [5,6] ] ); -## [ 9, 12 ] -## gap> Sum( GF(8) ); -## 0*Z(2) -## ]]> -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "Sum" ); - - -############################################################################# -## -#O SumOp( ) -#O SumOp( , ) -#O SumOp( , ) -#O SumOp( , , ) -## -## -## -## -## -## -## -## -## SumOp is the operation called by Sum -## if C is not an internal list. -## -## -## -DeclareOperation( "SumOp", [ IsListOrCollection ] ); - - -############################################################################# -## -#F Product( [, ] ) . . . . . . product of the elements of a list -#F Product( [, ] ) . . . . product of the elements of a collection -#F Product( , [, ] ) . product of images under a function -#F Product( , [, ] ) . . product of images under a function -## -## <#GAPDoc Label="Product"> -## -## -## -## -## Called with one argument, a dense list or collection listorcoll, -## returns the product of the elements of -## listorcoll (see ). -##

-## Called with a dense list or collection listorcoll and a function -## func, which must be a function taking one argument, -## applies the function func -## to the elements of listorcoll, and returns the product of the -## results. -## In either case returns 1 if the first -## argument is empty. -##

-## The general rules for arithmetic operations apply -## (see ), -## so the result is immutable if and only if all summands are immutable. -##

-## If listorcoll contains exactly one element then this element -## (or its image under func if applicable) itself is returned, -## not a shallow copy of this element. -##

-## If an additional initial value init is given, -## returns the product of init and the elements -## of the first argument resp. of their images under the function -## func. -## This is useful for example if the first argument is empty and a different -## identity than 1 is desired, in which case init is returned. -##

-## Product( [ 2, 3, 5, 7, 11, 13, 17, 19 ] ); -## 9699690 -## gap> Product( [1..10], x->x^2 ); -## 13168189440000 -## gap> Product( [ (1,2), (1,3), (1,4), (2,3), (2,4), (3,4) ] ); -## (1,4)(2,3) -## gap> Product( GF(8) ); -## 0*Z(2) -## ]]> -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "Product" ); - - -############################################################################# -## -#O ProductOp( ) -#O ProductOp( , ) -#O ProductOp( , ) -#O ProductOp( , , ) -## -## -## -## -## -## -## -## -## ProductOp is the operation called by Product -## if C is not an internal list. -## -## -## -DeclareOperation( "ProductOp", [ IsListOrCollection ] ); - - -############################################################################# -## -#F Filtered( , ) . . . . extract elements that have a property -#F Filtered( , ) . . . . . . extract elements that have a property -## -## <#GAPDoc Label="Filtered"> -## -## -## -## -## returns a new list that contains those elements of the list or collection -## listorcoll (see ), respectively, -## for which the unary function func returns true. -##

-## If the first argument is a list, the order of the elements in the result -## is the same as the order of the corresponding elements of this list. -## If an element for which func returns true appears several -## times in the list it will also appear the same number of times -## in the result. -## The argument list may contain holes, -## they are ignored by . -##

-## For each element of listorcoll, -## func must return either true or false, -## otherwise an error is signalled. -##

-## The result is a new list that is not identical to any other list. -## The elements of that list however are identical to the corresponding -## elements of the argument list (see ). -##

-## List assignment using the operator -## (see ) can be used to extract -## elements of a list according to indices given in another list. -##

-## Filtered( [1..20], IsPrime ); -## [ 2, 3, 5, 7, 11, 13, 17, 19 ] -## gap> Filtered( [ 1, 3, 4, -4, 4, 7, 10, 6 ], IsPrimePowerInt ); -## [ 3, 4, 4, 7 ] -## gap> Filtered( [ 1, 3, 4, -4, 4, 7, 10, 6 ], -## > n -> IsPrimePowerInt(n) and n mod 2 <> 0 ); -## [ 3, 7 ] -## gap> Filtered( Group( (1,2), (1,2,3) ), x -> Order( x ) = 2 ); -## [ (2,3), (1,2), (1,3) ] -## ]]> -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "Filtered" ); - - -############################################################################# -## -#O FilteredOp( , ) -## -## -## -## -## -## FilteredOp is the operation called by Filtered -## if C is not an internal list. -## -## -## -DeclareOperation( "FilteredOp", [ IsListOrCollection, IsFunction ] ); - - -############################################################################# -## -#F Number( ) -#F Number( , ) . . . . . . count elements that have a property -#F Number( , ) . . . . . . . . count elements that have a property -## -## <#GAPDoc Label="Number"> -## -## -## -## -## Called with a list listorcoll, returns the -## number of bound entries in this list. -## For dense lists , , -## and return the same value; -## for lists with holes returns the number of bound -## entries, returns the largest index of a bound entry, -## and signals an error. -##

-## Called with two arguments, a list or collection listorcoll and a -## unary function func, returns the number of -## elements of listorcoll for which func returns true. -## If an element for which func returns true appears several -## times in listorcoll it will also be counted the same number of -## times. -##

-## For each element of listorcoll, -## func must return either true or false, -## otherwise an error is signalled. -##

-## allows you to extract the elements of a list -## that have a certain property. -##

-## Number( [ 2, 3, 5, 7 ] ); -## 4 -## gap> Number( [, 2, 3,, 5,, 7,,,, 11 ] ); -## 5 -## gap> Number( [1..20], IsPrime ); -## 8 -## gap> Number( [ 1, 3, 4, -4, 4, 7, 10, 6 ], IsPrimePowerInt ); -## 4 -## gap> Number( [ 1, 3, 4, -4, 4, 7, 10, 6 ], -## > n -> IsPrimePowerInt(n) and n mod 2 <> 0 ); -## 2 -## gap> Number( Group( (1,2), (1,2,3) ), x -> Order( x ) = 2 ); -## 3 -## ]]> -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "Number" ); - - -############################################################################# -## -#O NumberOp( , ) -## -## -## -## -## -## NumberOp is the operation called by Number -## if C is not an internal list. -## -## -## -DeclareOperation( "NumberOp", [ IsListOrCollection, IsFunction ] ); - - -############################################################################# -## -#F ForAll( , ) -#F ForAll( , ) -## -## <#GAPDoc Label="ForAll"> -## -## -## -## -## tests whether the unary function func returns true -## for all elements in the list or collection listorcoll. -##

-## ForAll( [1..20], IsPrime ); -## false -## gap> ForAll( [2,3,4,5,8,9], IsPrimePowerInt ); -## true -## gap> ForAll( [2..14], n -> IsPrimePowerInt(n) or n mod 2 = 0 ); -## true -## gap> ForAll( Group( (1,2), (1,2,3) ), i -> SignPerm(i) = 1 ); -## false -## ]]> -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "ForAll" ); - - -############################################################################# -## -#O ForAllOp( , ) -## -## -## -## -## -## ForAllOp is the operation called by ForAll -## if C is not an internal list. -## -## -## -DeclareOperation( "ForAllOp", [ IsListOrCollection, IsFunction ] ); - - -############################################################################# -## -#F ForAny( , ) -#F ForAny( , ) -## -## <#GAPDoc Label="ForAny"> -## -## -## -## -## tests whether the unary function func returns true -## for at least one element in the list or collection listorcoll. -##

-## ForAny( [1..20], IsPrime ); -## true -## gap> ForAny( [2,3,4,5,8,9], IsPrimePowerInt ); -## true -## gap> ForAny( [2..14], -## > n -> IsPrimePowerInt(n) and n mod 5 = 0 and not IsPrime(n) ); -## false -## gap> ForAny( Integers, i -> i > 0 -## > and ForAll( [0,2..4], j -> IsPrime(i+j) ) ); -## true -## ]]> -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "ForAny" ); - - -############################################################################# -## -#O ForAnyOp( , ) -## -## -## -## -## -## ForAnyOp is the operation called by ForAny -## if C is not an internal list. -## -## -## -DeclareOperation( "ForAnyOp", [ IsListOrCollection, IsFunction ] ); - - -############################################################################# -## -#O ListX( , , ... , ) -## -## <#GAPDoc Label="ListX"> -## -## -## -## -## returns a new list constructed from the arguments. -##

-## Each of the arguments arg1, arg2, \ldots argn -## must be one of the following: -## -## a list or collection -## -## this introduces a new for-loop in the sequence of nested -## for-loops and if-statements; -## -## a function returning a list or collection -## -## this introduces a new for-loop in the sequence of nested -## for-loops and if-statements, where the loop-range depends on -## the values of the outer loop-variables; or -## -## a function returning true or false -## -## this introduces a new if-statement in the sequence of nested -## for-loops and if-statements. -## -## -##

-## The last argument func must be a function, -## it is applied to the values of the loop-variables -## and the results are collected. -##

-## Thus ListX( list, func ) is the same as -## List( list, func ), -## and ListX( list, func, x -> x ) is the same as -## Filtered( list, func ). -##

-## As a more elaborate example, assume arg1 is a list or collection, -## arg2 is a function returning true or false, -## arg3 is a function returning a list or collection, and -## arg4 is another function returning true or false, -## then -##

-## result := ListX( arg1, arg2, arg3, -## arg4, func ); -##

-## is equivalent to -##

-##

-##

-## The following example shows how can be used to -## compute all pairs and all strictly sorted pairs of elements in a list. -##

-## l:= [ 1, 2, 3, 4 ];; -## gap> pair:= function( x, y ) return [ x, y ]; end;; -## gap> ListX( l, l, pair ); -## [ [ 1, 1 ], [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 1 ], [ 2, 2 ], -## [ 2, 3 ], [ 2, 4 ], [ 3, 1 ], [ 3, 2 ], [ 3, 3 ], [ 3, 4 ], -## [ 4, 1 ], [ 4, 2 ], [ 4, 3 ], [ 4, 4 ] ] -## ]]> -##

-## In the following example, is the comparison -## operation: -##

-## ListX( l, l, \<, pair ); -## [ [ 1, 2 ], [ 1, 3 ], [ 1, 4 ], [ 2, 3 ], [ 2, 4 ], [ 3, 4 ] ] -## ]]> -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "ListX" ); - - -############################################################################# -## -#O SetX( , , ... ) -## -## <#GAPDoc Label="SetX"> -## -## -## -## -## The only difference between and -## is that the result list of is strictly sorted. -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "SetX" ); - - -############################################################################# -## -#O SumX( , , ... ) -## -## <#GAPDoc Label="SumX"> -## -## -## -## -## returns the sum of the elements in the list obtained -## by when this is called with the same arguments. -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "SumX" ); - - -############################################################################# -## -#O ProductX( , , ... ) -## -## <#GAPDoc Label="ProductX"> -## -## -## -## -## returns the product of the elements in the list -## obtained by when this is called with the same -## arguments. -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "ProductX" ); - - -############################################################################# -## -#O Perform( , ) -## -## <#GAPDoc Label="Perform"> -## -## -## -## -## applies the function func to every element -## of the list list, discarding any return values. -## It does not return a value. -##

-## l := [1, 2, 3];; Perform(l, -## > function(x) if IsPrimeInt(x) then Print(x,"\n"); fi; end); -## 2 -## 3 -## ]]> -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "Perform" ); - - -############################################################################# -## -#O IsSubset( , ) . . . . . . . . . test for subset of collections -## -## <#GAPDoc Label="IsSubset"> -## -## -## -## -## subset test -## returns true if C2, -## which must be a collection, is a subset of C1, -## which also must be a collection, and false otherwise. -##

-## C2 is considered a subset of C1 if and only if each element -## of C2 is also an element of C1. -## That is behaves as if implemented as -## IsSubsetSet( AsSSortedList( C1 ), AsSSortedList( C2 ) ), -## except that it will also sometimes, but not always, -## work for infinite collections, -## and that it will usually work much faster than the above definition. -## Either argument may also be a proper set -## (see ). -##

-## IsSubset( Rationals, Integers ); -## true -## gap> IsSubset( Integers, [ 1, 2, 3 ] ); -## true -## gap> IsSubset( Group( (1,2,3,4) ), [ (1,2,3) ] ); -## false -## ]]> -## -## -## <#/GAPDoc> -## -DeclareOperation( "IsSubset", [ IsListOrCollection, IsListOrCollection ] ); - - -############################################################################# -## -#F Intersection( , ... ) . . . . . . . intersection of collections -#F Intersection( ) . . . . . . . . . . . intersection of collections -#O Intersection2( , ) . . . . . . . . . intersection of collections -## -## <#GAPDoc Label="Intersection"> -## -## Intersection -## -## -## -## -## -## intersection -## In the first form -## returns the -## intersection of the collections C1, C2, etc. -## In the second form list must be a nonempty list of -## collections and returns -## the intersection of those collections. -## Each argument or element of list respectively may also be a -## homogeneous list that is not a proper set, -## in which case silently -## applies to it first. -##

-## The result of is the set -## of elements that lie in every of the collections C1, C2, -## etc. -## If the result is a list then it is mutable and new, i.e., not identical -## to any of C1, C2, etc. -##

-## Methods can be installed for the operation -## that takes only two arguments. -## calls -## . -##

-## Methods for should try to maintain as much -## structure as possible, for example the intersection of two permutation -## groups is again a permutation group. -##

-## # this is one of the rare cases where the intersection of two -## gap> # infinite domains works ('CF' is a shorthand for 'CyclotomicField'): -## gap> Intersection( CyclotomicField(9), CyclotomicField(12) ); -## CF(3) -## gap> D12 := Group( (2,6)(3,5), (1,2)(3,6)(4,5) );; -## gap> Intersection( D12, Group( (1,2), (1,2,3,4,5) ) ); -## Group([ (1,5)(2,4) ]) -## gap> Intersection( D12, [ (1,3)(4,6), (1,2)(3,4) ] ) -## > ; # note that the second argument is not a proper set -## [ (1,3)(4,6) ] -## gap> # although the result is mathematically a group it is returned as a -## gap> # proper set because the second argument is not regarded as a group: -## gap> Intersection( D12, [ (), (1,2)(3,4), (1,3)(4,6), (1,4)(5,6) ] ); -## [ (), (1,3)(4,6) ] -## gap> Intersection( Group( () ), [1,2,3] ); -## [ ] -## gap> Intersection( [2,4,6,8,10], [3,6,9,12,15], [5,10,15,20,25] ) -## > ; # two or more lists or collections as arguments are legal -## [ ] -## gap> Intersection( [ [1,2,4], [2,3,4], [1,3,4] ] ) -## > ; # or one list of lists or collections -## [ 4 ] -## ]]> -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "Intersection" ); - -DeclareOperation( "Intersection2", - [ IsListOrCollection, IsListOrCollection ] ); - - -############################################################################# -## -#F Union( , ... ) . . . . . . . . . . . . . . union of collections -#F Union( ) . . . . . . . . . . . . . . . . . . union of collections -#O Union2( , ) . . . . . . . . . . . . . . . union of collections -## -## <#GAPDoc Label="Union"> -## -## Union -## -## -## -## -## -## union -## In the first form -## returns the union of the collections C1, C2, etc. -## In the second form list must be a list of collections -## and returns the union of those -## collections. -## Each argument or element of list respectively may also be a -## homogeneous list that is not a proper set, -## in which case silently applies -## to it first. -##

-## The result of is the set of -## elements that lie in any of the collections C1, C2, etc. -## If the result is a list then it is mutable and new, i.e., not identical -## to any of C1, C2, etc. -##

-## Methods can be installed for the operation -## that takes only two arguments. -## calls . -##

-## Union( [ (1,2,3), (1,2,3,4) ], Group( (1,2,3), (1,2) ) ); -## [ (), (2,3), (1,2), (1,2,3), (1,2,3,4), (1,3,2), (1,3) ] -## gap> Union( [2,4,6,8,10], [3,6,9,12,15], [5,10,15,20,25] ) -## > ; # two or more lists or collections as arguments are legal -## [ 2, 3, 4, 5, 6, 8, 9, 10, 12, 15, 20, 25 ] -## gap> Union( [ [1,2,4], [2,3,4], [1,3,4] ] ) -## > ; # or one list of lists or collections -## [ 1 .. 4 ] -## gap> Union( [ ] ); -## [ ] -## ]]>

-## When computing the Union of lists or sets of small integers and ranges, -## every attempt is made to return the result as a range and to avoid expanding -## ranges provided as input. -## -## -## <#/GAPDoc> -## -DeclareGlobalFunction( "Union" ); - -DeclareOperation( "Union2", [ IsListOrCollection, IsListOrCollection ] ); - - -############################################################################# -## -#O Difference( , ) . . . . . . . . . . . difference of collections -## -## <#GAPDoc Label="Difference"> -## -## -## -## -## set difference -## returns the set difference of the collections -## C1 and C2. -## Either argument may also be a homogeneous list that is not a proper set, -## in which case silently applies -## to it first. -##

-## The result of is the set of elements that lie in -## C1 but not in C2. -## Note that C2 need not be a subset of C1. -## The elements of C2, however, that are not elements of C1 -## play no role for the result. -## If the result is a list then it is mutable and new, i.e., not identical -## to C1 or C2. -##

-## Difference( [ (1,2,3), (1,2,3,4) ], Group( (1,2,3), (1,2) ) ); -## [ (1,2,3,4) ] -## ]]> -## -## -## <#/GAPDoc> -## -DeclareOperation( "Difference", [ IsListOrCollection, IsListOrCollection ] ); - - -############################################################################# -## -#P CanEasilyCompareElements( ) -#F CanEasilyCompareElementsFamily( ) -#P CanEasilySortElements( ) -#F CanEasilySortElementsFamily( ) -## -## <#GAPDoc Label="CanEasilyCompareElements"> -## -## -## -## -## -## -## -## For some objects a normal form is hard to compute -## and thus equality of elements of a domain might be expensive to test. -## Therefore &GAP; provides a (slightly technical) property with which an -## algorithm can test whether an efficient equality test is available -## for elements of a certain kind. -##

-## indicates whether the elements in -## the family fam of obj can be easily compared with -## . -##

-## The default method for this property is to ask the family of obj, -## the default method for the family is to return false. -##

-## The ability to compare elements may depend on the successful computation -## of certain information. (For example for finitely presented groups it -## might depend on the knowledge of a faithful permutation representation.) -## This information might change over time and thus it might not be a good -## idea to store a value false too early in a family. Instead the -## function should be called -## for the family of obj which returns false if the value of -## is not known for the family -## without computing it. (This is in fact what the above mentioned family -## dispatch does.) -##

-## If a family knows ab initio that it can compare elements this property -## should be set as implied filter and filter for the family -## (the 3rd and 4th argument of -## respectively). -## This guarantees that code which directly asks the family gets a right -## answer. -##

-## The property and the function -## behave exactly in the same way, -## except that they indicate that objects can be compared via -## . -## This property implies , -## as the ordering must be total. -## -## -## <#/GAPDoc> -## -DeclareProperty( "CanEasilyCompareElements", IsObject ); -DeclareGlobalFunction( "CanEasilyCompareElementsFamily" ); -DeclareProperty( "CanEasilySortElements", IsObject ); -DeclareGlobalFunction( "CanEasilySortElementsFamily" ); - -InstallTrueMethod(CanEasilyCompareElements,CanEasilySortElements); - - -############################################################################# -## -#O CanComputeIsSubset( , ) -## -## <#GAPDoc Label="CanComputeIsSubset"> -## -## -## -## -## This filter indicates that &GAP; can test (via ) -## whether B is a subset of A. -## -## -## <#/GAPDoc> -## -DeclareOperation( "CanComputeIsSubset", [IsObject,IsObject] ); - - -############################################################################# -## -#F CanComputeSize( ) -## -## <#GAPDoc Label="CanComputeSize"> -## -## -## -## -## This filter indicates that we know that the size of the domain dom -## (which might be ) can be computed reasonably -## easily. It doesn't imply as quick a computation as HasSize would -## but its absence does not imply that the size cannot be computed. -## -## -## <#/GAPDoc> -## -DeclareFilter( "CanComputeSize" ); - -InstallTrueMethod( CanComputeSize, HasSize ); - -############################################################################# -## -#E - diff --git a/lib/coll.gd b/lib/coll.gd index 51ff1aef107..0f02c4662de 100644 --- a/lib/coll.gd +++ b/lib/coll.gd @@ -193,6 +193,9 @@ DeclareAttribute( "ElementsFamily", IsFamily ); ## ## BIND_GLOBAL( "CATEGORIES_COLLECTIONS", [] ); +if IsHPCGAP then + ShareSpecialObj(CATEGORIES_COLLECTIONS, "CATEGORIES_COLLECTIONS"); +fi; ############################################################################# @@ -227,15 +230,34 @@ BIND_GLOBAL( "CATEGORIES_COLLECTIONS", [] ); ## <#/GAPDoc> ## BIND_GLOBAL( "CategoryCollections", function ( elms_filter ) - local pair, super, flags, name, coll_filter; - + local pair, super, flags, name, coll_filter, len; + + # check once with read lock -- common case + atomic readonly CATEGORIES_COLLECTIONS do # Check whether the collections category is already defined. for pair in CATEGORIES_COLLECTIONS do if IsIdenticalObj( pair[1], elms_filter ) then return pair[2]; fi; od; - + if IsHPCGAP then + len := LENGTH(CATEGORIES_COLLECTIONS); + fi; + od; # end atomic + + # that failed, so get exclusive lock as we may need to modify + atomic readwrite CATEGORIES_COLLECTIONS do + if IsHPCGAP then + # Check whether in the meantime another thread defined the collections category + if LENGTH(CATEGORIES_COLLECTIONS) > len then + for pair in CATEGORIES_COLLECTIONS do + if IsIdenticalObj( pair[1], elms_filter ) then + return pair[2]; + fi; + od; + fi; + fi; + # Find the super category among the known collections categories. super := IsCollection; flags := WITH_IMPS_FLAGS( FLAGS_FILTER( elms_filter ) ); @@ -255,6 +277,7 @@ BIND_GLOBAL( "CategoryCollections", function ( elms_filter ) coll_filter:= NewCategory( name, super ); ADD_LIST( CATEGORIES_COLLECTIONS, MakeImmutable([ elms_filter, coll_filter ]) ); return coll_filter; + od; # end atomic end ); @@ -431,6 +454,9 @@ end ); ## ## BIND_GLOBAL( "SUBSET_MAINTAINED_INFO", [ [], [] ] ); +if IsHPCGAP then + ShareSpecialObj(SUBSET_MAINTAINED_INFO, "SUBSET_MAINTAINED_INFO"); +fi; ############################################################################# @@ -480,11 +506,13 @@ InstallMethod( UseSubsetRelation, local entry; + atomic readonly SUBSET_MAINTAINED_INFO do for entry in SUBSET_MAINTAINED_INFO[1] do if entry[1]( super ) and entry[2]( sub ) and not entry[4]( sub ) then entry[5]( sub, entry[3]( super ) ); fi; od; + od; # end atomic return true; end ); @@ -552,6 +580,7 @@ BIND_GLOBAL( "InstallSubsetMaintenance", # (We must not call `SUBTR_SET' here because the lists types may be # not yet defined.) filtssub:= []; + atomic readwrite SUBSET_MAINTAINED_INFO do for flag in TRUES_FLAGS( FLAGS_FILTER( sub_req ) ) do if not INFO_FILTERS[flag] in FNUM_CATS_AND_REPS then ADD_LIST_DEFAULT( filtssub, flag ); @@ -632,6 +661,7 @@ BIND_GLOBAL( "InstallSubsetMaintenance", SetFeatureObj( sub, operation, val ); end ]); fi; + od; # end atomic #T missing in new implementation! # # Install the method. @@ -699,6 +729,9 @@ end ); ## ## BIND_GLOBAL( "ISOMORPHISM_MAINTAINED_INFO", [] ); +if IsHPCGAP then + ShareSpecialObj(ISOMORPHISM_MAINTAINED_INFO, "ISOMORPHISM_MAINTAINED_INFO"); +fi; ############################################################################# @@ -748,11 +781,13 @@ InstallMethod( UseIsomorphismRelation, function( old, new ) local entry; + atomic readonly ISOMORPHISM_MAINTAINED_INFO do for entry in ISOMORPHISM_MAINTAINED_INFO do if entry[1]( old ) and entry[2]( new ) and not entry[4]( new ) then entry[5]( new, entry[3]( old ) ); fi; od; + od; # end atomic return true; end ); @@ -792,6 +827,7 @@ BIND_GLOBAL( "InstallIsomorphismMaintenance", tester:= Tester( opr ); + atomic ISOMORPHISM_MAINTAINED_INFO do ADD_LIST( ISOMORPHISM_MAINTAINED_INFO, MakeImmutable( [ IsCollection and Tester( old_req ) and old_req and tester, IsCollection and Tester( new_req ) and new_req, @@ -800,6 +836,7 @@ BIND_GLOBAL( "InstallIsomorphismMaintenance", Setter( opr ), old_req, new_req ] ) ); + od; # end atomic end ); @@ -847,6 +884,9 @@ end ); ## ## BIND_GLOBAL( "FACTOR_MAINTAINED_INFO", [] ); +if IsHPCGAP then + ShareSpecialObj(FACTOR_MAINTAINED_INFO, "FACTOR_MAINTAINED_INFO"); +fi; ############################################################################# @@ -906,12 +946,14 @@ InstallMethod( UseFactorRelation, local entry; + atomic readonly FACTOR_MAINTAINED_INFO do for entry in FACTOR_MAINTAINED_INFO do if entry[1]( num ) and entry[2]( den ) and entry[3]( fac ) and not entry[5]( fac ) then entry[6]( fac, entry[4]( num ) ); fi; od; + od; # end atomic return true; end ); @@ -968,6 +1010,7 @@ BIND_GLOBAL( "InstallFactorMaintenance", tester:= Tester( opr ); + atomic FACTOR_MAINTAINED_INFO do ADD_LIST( FACTOR_MAINTAINED_INFO, MakeImmutable( [ IsCollection and Tester( numer_req ) and numer_req and tester, Tester( denom_req ) and denom_req, @@ -975,6 +1018,7 @@ BIND_GLOBAL( "InstallFactorMaintenance", opr, tester, Setter( opr ) ] ) ); + od; # end atomic #T not yet available in the new implementation # if FLAGS_FILTER( opr ) <> false