It may be interesting to use the functions of the GAP interface also for representations or programs that are not part of the ATLAS of Group Representations. This chapter describes how to achieve this.
The main idea is that users can notify collections of "private" data files, which may consist of
new faithful representations and programs for groups that are declared already in the core part of the database that belongs to the "official" ATLAS of Group Representations (see Section 5.1),
the declaration of groups that are not declared in the ATLAS of Group Representations, and representations and programs for them (see Section 5.2), and
the definition of new kinds of representations and programs (see Section 7.5).
A test example of a local extension is given in Section 5.3. Another such example is the small collection of data that is distributed together with the package, in its datapkg
directory; its contents can be listed by calling DisplayAtlasInfo( "contents", "internal" )
.
Examples of extensions by files that can be downloaded from the internet can be found in the GAP packages MFER [BHM09] and CTBlocks [Bre14]. These extensions are automatically notified as soon as AtlasRep is available, via the default value of the user preference AtlasRepTOCData
, see Section 4.2-3; their contents can be listed by calling DisplayAtlasInfo( "contents", "mfer" )
and DisplayAtlasInfo( "contents", "ctblocks" )
, respectively.
Several of the sanity checks for the core part of the AtlasRep data make sense also for data extensions, see Section 7.9 for more information.
After the AtlasRep package has been loaded into the GAP session, one can extend the data which the interface can access by own representations and programs. The following two variants are supported.
The additional data files are locally available in some directory. Information about the declaration of new groups or about additional information such as the character names of representations can be provided in an optional JSON format file named toc.json
in this directory.
The data files can be downloaded from the internet. Both the list of available data and additional information as in the above case are given by either a local JSON format file or the URL of a JSON format file. This variant requires the user preference AtlasRepAccessRemoteFiles
(see Section 4.2-1) to have the value true
.
In both cases, AtlasOfGroupRepresentationsNotifyData
(5.1-1) can be used to make the private data available to the interface.
‣ AtlasOfGroupRepresentationsNotifyData ( dir, id[, test] ) | ( function ) |
‣ AtlasOfGroupRepresentationsNotifyData ( filename[, id][, test] ) | ( function ) |
‣ AtlasOfGroupRepresentationsNotifyData ( url[, id][, test] ) | ( function ) |
Returns: true
if the overview of the additional data can be evaluated and if the names of the data files in the extension are compatible with the data files that had been available before the call, otherwise false
.
The following variants are supported for notifying additional data.
The first argument dir must be either a local directory (see Reference: Directories) or a string denoting the path of a local directory, such that the GAP object describing this directory can be obtained by calling Directory
(Reference: Directory) with the argument dir; in the latter case, dir can be an absolute path or a path relative to the user's home directory (starting with a tilde character ~
) or a path relative to the directory where GAP was started. The files contained in this directory or in its subdirectories (only one level deep) are considered. If the directory contains a JSON document in a file with the name toc.json
then this file gets evaluated; its purpose is to provide additional information about the data files.
Calling AtlasOfGroupRepresentationsNotifyData
means to evaluate the contents of the directory and (if available) of the file toc.json
.
Accessing data means to read the locally available data files.
The argument id must be a string. It will be used in the identifier
components of the records that are returned by interface functions (see Section 3.5) for data contained in the directory dir. (Note that the directory name may be different in different GAP sessions or for different users who want to access the same data, whereas the identifier
components shall be independent of such differences.)
An example of a local extension is the contents of the datapkg
directory of the AtlasRep package. This extension gets notified automatically when AtlasRep gets loaded. For restricting data collections to this extension, one can use the identifier "internal"
.
The first argument filename must be the name of a local file whose content is a JSON document that lists the available data, additional information about these data, and an URL from where the data can be downloaded. The data format of this file is defined by the JSON schema file doc/atlasreptoc_schema.json
of the AtlasRep package.
Calling AtlasOfGroupRepresentationsNotifyData
means to evaluate the contents of the file filename, without trying to access the remote data. The id is then either given implicitly by the ID
component of the JSON document or can be given as the second argument.
Downloaded data files are stored in the subdirectory dataext/
id of the directory that is given by the user preference AtlasRepDataDirectory
, see Section 4.2-2.
Accessing data means to download remote files if necessary but to prefer files that are already locally available.
An example of such an extension is the set of permutation representations provided by the MFER package [BHM09]; due to the file sizes, these representations are not distributed together with the MFER package. For restricting data collections to this extension, one can use the identifier "mfer"
.
Another example is given by some of the data that belong to the CTBlocks package [Bre14]. These data are also distributed with that package, and notifying the extension in the situation that the CTBlocks package is available will make its local data available, via the component LocalDirectory
of the JSON document ctblocks.json
; notifying the extension in the situation that the CTBlocks package is not available will make the remote files available, via the component DataURL
of this JSON document. For restricting data collections to this extension, one can use the identifier "ctblocks"
.
(This variant works only if the IO package [Neu14] is available.)
The first argument url must be the URL of a JSON document as in the previous case.
Calling AtlasOfGroupRepresentationsNotifyData
in online mode (that is, the user preference AtlasRepAccessRemoteFiles
has the value true
) means to download this file and to evaluate it; the id is then given implicitly by the ID
component of the JSON document, and the contents of the document gets stored in a file with name dataext/
id/toc.json
, relative to the directory given by the value of the user preference AtlasRepDataDirectory
. Also downloaded files for this extension will be stored in the directory dataext/
id.
Calling AtlasOfGroupRepresentationsNotifyData
in offline mode requires that the argument id is explicitly given. In this case, it is checked whether the dataext
subdirectory contains a subdirectory with name id; if not then false
is returned, if yes then the contents of this local directory gets notified via the first form described above.
Accessing data in online mode means the same as in the case of a remote directory. Accessing data in offline mode means the same as in the case of a local directory.
Examples of such extension are again the data from the packages CTBlocks and MFER described above, but in the situation that these packages are not loaded, and that just the web URLs of their JSON documents are entered which describe the contents.
In all three cases, if the optional argument test is given then it must be either true
or false
. In the true
case, consistency checks are switched on during the notification. The default for test is false
.
The notification of an extension may happen as a side-effect when a GAP package gets loaded that provides the data in question. Besides that, one may collect the notifications of data extensions in one's gaprc
file (see Section Reference: The gap.ini and gaprc files).
‣ AtlasOfGroupRepresentationsForgetData ( dirid ) | ( function ) |
If dirid is the identifier of a database extension that has been notified with AtlasOfGroupRepresentationsNotifyData
(5.1-1) then AtlasOfGroupRepresentationsForgetData
undoes the notification; this means that from then on, the data of this extension cannot be accessed anymore in the current session.
‣ StringOfAtlasTableOfContents ( inforec ) | ( function ) |
For a record inforec with at least the component ID
, with value "core"
or the identifier of a data extension (see AtlasOfGroupRepresentationsNotifyData
(5.1-1)), this function returns a string that describes the part of AtlasRep data belonging to inforec.ID
.
Printed to a file, the returned string can be used as the table of contents of this part of the data. For that purpose, also the following components of inforec must be bound (all strings). Version
, SelfURL
(the internet address of the table of contents file itself). At least one of the following two components must be bound. DataURL
is the internet address of the directory from where the data in question can be downloaded. LocalDirectory
is a path relative to GAP's pkg
directory where the data may be stored locally (depending on whether some GAP package is installed). If the component DataURL
is bound then the returned string contains the information about the data files; this is not necessary if the data are only locally available. If both DataURL
and LocalDirectory
are bound then locally available data will be prefered at runtime.
Alternatively, inforec can also be the ID
string; in this case, the values of those of the supported components mentioned above that are defined in an available JSON file for this ID
are automatically inserted. (If there is no such file yet then entering the ID
string as inforec does not make sense.)
For an example how to use the function, see Section 5.3.
First suppose that only new groups or new data for known groups or for new groups are added.
In this case, DisplayAtlasInfo
(3.5-1) lists the additional representations and programs in the same way as other data known to AtlasRep, except that parts outside the core database are marked with the string that is the value of the user preference AtlasRepMarkNonCoreData
, see Section 4.2-12. The ordering of representations listed by DisplayAtlasInfo
(3.5-1) (and referred to by AtlasGenerators
(3.5-3)) will in general change whenever extensions get notified. For the other interface functions described in Chapter 3, the only difference is that also the additional data can be accessed.
If also new data types are introduced in an extension (see Section 7.5) then additional columns or rows can appear in the output of DisplayAtlasInfo
(3.5-1), and new inputs can become meaningful for all interface functions.
This section shows an extension by a few locally available files.
We set the info level of InfoAtlasRep
(7.1-1) to 1 in this section.
gap> locallevel:= InfoLevel( InfoAtlasRep );; gap> SetInfoLevel( InfoAtlasRep, 1 );
Let us assume that the local directory privdir
contains data for the cyclic group C_4 of order 4 and for the alternating group A_5 on 5 points, respectively. Note that it is obvious what the term "standard generators" means for the group C_4.
Further let us assume that privdir
contains the following files.
C4G1-p4B0.m1
a faithful permutation representation of C_4 on 4 points,
C4G1-max1W1
the straight line program that returns the square of its unique input,
C4G1-a2W1
the straight line program that raises its unique input to the third power,
C4G1-XtestW1
the straight line program that returns the square of its unique input,
A5G1-p60B0.m1
and A5G1-p60B0.m2
standard generators for A_5 in its regular permutation representation.
The directory and the files can be created as follows.
gap> prv:= DirectoryTemporary( "privdir" );; gap> FileString( Filename( prv, "C4G1-p4B0.m1" ), > MeatAxeString( [ (1,2,3,4) ], 4 ) );; gap> FileString( Filename( prv, "C4G1-max1W1" ), > "inp 1\npwr 2 1 2\noup 1 2\n" );; gap> FileString( Filename( prv, "C4G1-XtestW1" ), > "inp 1\npwr 2 1 2\noup 1 2\n" );; gap> FileString( Filename( prv, "C4G1-a2W1" ), > "inp 1\npwr 3 1 2\noup 1 2\n" );; gap> FileString( Filename( prv, "C4G1-Ar1aB0.g" ), > "return rec( generators:= [ [[E(4)]] ] );\n" );; gap> points:= Elements( AlternatingGroup( 5 ) );; gap> FileString( Filename( prv, "A5G1-p60B0.m1" ), > MeatAxeString( [ Permutation( (1,2)(3,4), points, OnRight ) ], 60 ) );; gap> FileString( Filename( prv, "A5G1-p60B0.m2" ), > MeatAxeString( [ Permutation( (1,3,5), points, OnRight ) ], 60 ) );;
(We could also introduce intermediate directories C4
and A5
, say, each with the data for one group only.)
The core part of the AtlasRep data does not contain information about C_4, so we first notify this group, in the file privdir/toc.json
. Besides the name of the group, we store the following information: the group order, the number of (classes of) maximal subgroups, their orders, their structures, and describing data about the three representations. The group A_5 is already known with name A5
in the core part of the AtlasRep data, so it need not and cannot be notified again.
gap> FileString( Filename( prv, "toc.json" ), Concatenation( [ "{\n", > "\"ID\":\"priv\",\n", > "\"Data\":[\n", > "[\"GNAN\",[\"C4\",\"C4\"]],\n", > "[\"GRS\",[\"C4\",4]],\n", > "[\"MXN\",[\"C4\",1]],\n", > "[\"MXO\",[\"C4\",[2]]],\n", > "[\"MXS\",[\"C4\",[\"C2\"]]],\n", > "[\"RNG\",[\"C4G1-Ar1aB0\",\"CF(4)\",", > "[\"QuadraticField\",-1],[1,0,1]]],\n", > "[\"API\",[\"C4G1-p4B0\",[1,4,\"imprim\",\"1 < C2\"]]],\n", > "[\"API\",[\"A5G1-p60B0\",[1,60,\"imprim\",\"1 < S3\"]]]\n", > "]\n", > "}\n" ] ) );;
Then we notify the extension.
gap> AtlasOfGroupRepresentationsNotifyData( prv, "priv", true ); true
Now we can use the interface functions for accessing the additional data.
gap> DisplayAtlasInfo( [ "C4" ] ); group | # | maxes | cl | cyc | out | fnd | chk | prs ------+---+-------+----+-----+-----+-----+-----+---- C4* | 2 | 1 | | | 2 | | | gap> DisplayAtlasInfo( "C4" ); Representations for G = C4: (all refer to std. generators 1) --------------------------- 1: G <= Sym(4)* rank 4, on cosets of 1 < C2 2: G <= GL(1a,CF(4))* Programs for G = C4: (all refer to std. generators 1) -------------------- - automorphisms*: 2* - maxes (all 1): 1*: C2 - other scripts*: "test"* gap> DisplayAtlasInfo( "C4", IsPermGroup, true ); Representations for G = C4: (all refer to std. generators 1) --------------------------- 1: G <= Sym(4)* rank 4, on cosets of 1 < C2 gap> DisplayAtlasInfo( "C4", IsMatrixGroup ); Representations for G = C4: (all refer to std. generators 1) --------------------------- 2: G <= GL(1a,CF(4))* gap> DisplayAtlasInfo( "C4", Dimension, 2 ); gap> DisplayAtlasInfo( "A5", NrMovedPoints, 60 ); Representations for G = A5: (all refer to std. generators 1) --------------------------- 4: G <= Sym(60)* rank 60, on cosets of 1 < S3 gap> info:= OneAtlasGeneratingSetInfo( "C4" ); rec( contents := "priv", groupname := "C4", id := "", identifier := [ "C4", [ [ "priv", "C4G1-p4B0.m1" ] ], 1, 4 ], isPrimitive := false, p := 4, rankAction := 4, repname := "C4G1-p4B0", repnr := 1, size := 4, stabilizer := "1 < C2", standardization := 1, transitivity := 1, type := "perm" ) gap> AtlasGenerators( info.identifier ); rec( contents := "priv", generators := [ (1,2,3,4) ], groupname := "C4", id := "", identifier := [ "C4", [ [ "priv", "C4G1-p4B0.m1" ] ], 1, 4 ], isPrimitive := false, p := 4, rankAction := 4, repname := "C4G1-p4B0", repnr := 1, size := 4, stabilizer := "1 < C2", standardization := 1, transitivity := 1, type := "perm" ) gap> AtlasProgram( "C4", 1 ); rec( groupname := "C4", identifier := [ "C4", [ [ "priv", "C4G1-max1W1" ] ], 1 ], program := <straight line program>, size := 2, standardization := 1, subgroupname := "C2", version := "1" ) gap> AtlasProgram( "C4", "maxes", 1 ); rec( groupname := "C4", identifier := [ "C4", [ [ "priv", "C4G1-max1W1" ] ], 1 ], program := <straight line program>, size := 2, standardization := 1, subgroupname := "C2", version := "1" ) gap> AtlasProgram( "C4", "maxes", 2 ); fail gap> AtlasGenerators( "C4", 1 ); rec( contents := "priv", generators := [ (1,2,3,4) ], groupname := "C4", id := "", identifier := [ "C4", [ [ "priv", "C4G1-p4B0.m1" ] ], 1, 4 ], isPrimitive := false, p := 4, rankAction := 4, repname := "C4G1-p4B0", repnr := 1, size := 4, stabilizer := "1 < C2", standardization := 1, transitivity := 1, type := "perm" ) gap> AtlasGenerators( "C4", 2 ); rec( contents := "priv", dim := 1, generators := [ [ [ E(4) ] ] ], groupname := "C4", id := "a", identifier := [ "C4", [ [ "priv", "C4G1-Ar1aB0.g" ] ], 1, 1 ], polynomial := [ 1, 0, 1 ], repname := "C4G1-Ar1aB0", repnr := 2, ring := GaussianRationals, size := 4, standardization := 1, type := "matalg" ) gap> AtlasGenerators( "C4", 3 ); fail gap> AtlasProgram( "C4", "other", "test" ); rec( groupname := "C4", identifier := [ "C4", [ [ "priv", "C4G1-XtestW1" ] ], 1 ], program := <straight line program>, standardization := 1, version := "1" )
We can restrict the data shown by DisplayAtlasInfo
(3.5-1) to our extension, as follows.
gap> DisplayAtlasInfo( "contents", "priv" ); group | # | maxes | cl | cyc | out | fnd | chk | prs ------+---+-------+----+-----+-----+-----+-----+---- A5* | 1 | | | | | | | C4* | 2 | 1 | | | 2 | | |
For checking the data in the extension, we apply the relevant sanity checks (see Section 7.9).
gap> AGR.Test.Words( "priv" ); true gap> AGR.Test.FileHeaders( "priv" ); true gap> AGR.Test.Files( "priv" ); true gap> AGR.Test.BinaryFormat( "priv" ); true gap> AGR.Test.Primitivity( "priv" : TryToExtendData ); true gap> AGR.Test.Characters( "priv" : TryToExtendData ); #I AGR.Test.Character: #I add new info ["CHAR",["A5","A5G1-p60B0", 0,[1,[2,3],[3,3],[4,4],[5,5]],"1a+3a^3b^3+4a^4+5a^5"]], #I AGR.Test.Character: #I add new info ["CHAR",["C4","C4G1-p4B0",0,[1,2,3,4],"1abcd"]], true
We did not store the character information in the file privdir/toc.json
, and GAP was able to identify the characters of the two permutation representations. (The identification of the character for the matrix representation fails because we cannot distinguish between the two Galois conjugate faithful characters.)
If we store the character information as proposed by GAP, this information will for example become part of the records returned by OneAtlasGeneratingSetInfo
(3.5-6). (Note that we have to enter "priv"
as the last argument of AGR.CHAR
when we call the function interactively, in order to assign the information to the right context.)
gap> AGR.CHAR("A5","A5G1-p60B0", > 0,[1,[2,3],[3,3],[4,4],[5,5]],"1a+3a^3b^3+4a^4+5a^5", "priv" ); gap> AGR.CHAR("C4","C4G1-p4B0",0,[1,2,3,4],"1abcd", "priv" ); gap> AGR.Test.Characters( "priv" ); true gap> OneAtlasGeneratingSetInfo( "C4" ); rec( charactername := "1abcd", constituents := [ 1, 2, 3, 4 ], contents := "priv", groupname := "C4", id := "", identifier := [ "C4", [ [ "priv", "C4G1-p4B0.m1" ] ], 1, 4 ], isPrimitive := false, p := 4, rankAction := 4, repname := "C4G1-p4B0", repnr := 1, size := 4, stabilizer := "1 < C2", standardization := 1, transitivity := 1, type := "perm" )
A string that describes the JSON format overview of the data extension can be created with StringOfAtlasTableOfContents
(5.1-3).
gap> Print( StringOfAtlasTableOfContents( "priv" ) ); { "ID":"priv", "Data":[ ["GNAN",["C4","C4"]], ["GRS",["C4",4]], ["MXN",["C4",1]], ["MXO",["C4",[2]]], ["MXS",["C4",["C2"]]], ["RNG",["C4G1-Ar1aB0","CF(4)",["QuadraticField",-1],[1,0,1]]], ["API",["A5G1-p60B0",[1,60,"imprim","1 < S3"]]], ["API",["C4G1-p4B0",[1,4,"imprim","1 < C2"]]], ["CHAR",["A5","A5G1-p60B0",0,[1,[2,3],[3,3],[4,4],[5,5]],"1a+3a^3b^3+4\ a^4+5a^5"]], ["CHAR",["C4","C4G1-p4B0",0,[1,2,3,4],"1abcd"]] ] }
If we prescribe a "DataURL"
component that starts with "http"
then also the "TOC"
lines are listed, in order to enable remote access to the data.
gap> Print( StringOfAtlasTableOfContents( > rec( ID:= "priv", DataURL:= "http://someurl" ) ) ); { "ID":"priv", "DataURL":"http://someurl", "Data":[ ["GNAN",["C4","C4"]], ["GRS",["C4",4]], ["MXN",["C4",1]], ["MXO",["C4",[2]]], ["MXS",["C4",["C2"]]], ["TOC",["perm","A5G1-p60B0.m",[118815263,24584221]]], ["TOC",["matalg","C4G1-Ar1aB0.g",[49815028]]], ["TOC",["otherscripts","C4G1-XtestW1",[-27672877]]], ["TOC",["out","C4G1-a2W1",[126435524]]], ["TOC",["maxes","C4G1-max1W1",[-27672877]]], ["TOC",["perm","C4G1-p4B0.m",[102601978]]], ["RNG",["C4G1-Ar1aB0","CF(4)",["QuadraticField",-1],[1,0,1]]], ["API",["A5G1-p60B0",[1,60,"imprim","1 < S3"]]], ["API",["C4G1-p4B0",[1,4,"imprim","1 < C2"]]], ["CHAR",["A5","A5G1-p60B0",0,[1,[2,3],[3,3],[4,4],[5,5]],"1a+3a^3b^3+4\ a^4+5a^5"]], ["CHAR",["C4","C4G1-p4B0",0,[1,2,3,4],"1abcd"]] ] }
Finally, we "uninstall" our extension, and reset the info level that had been set to 1 in the beginning. (Also the group name C4
is removed this way, which is an advantage of using a toc.json
file over calling AGR.GNAN
directly.),
gap> AtlasOfGroupRepresentationsForgetData( "priv" ); gap> SetInfoLevel( InfoAtlasRep, locallevel );
We need not care about removing the temporary directory and the files in it. GAP will try to remove directories created with DirectoryTemporary
(Reference: DirectoryTemporary) at the end of the GAP session.
generated by GAPDoc2HTML