Goto Chapter: Top 1 2 3 4 5 6 7 Bib Ind
 [Top of Book]  [Contents]   [Previous Chapter]   [Next Chapter] 

5 Extensions of the AtlasRep Package
 5.1 Notify Additional Data
 5.2 The Effect of Extensions on the User Interface
 5.3 An Example of Extending the AtlasRep Data

5 Extensions of the AtlasRep Package

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

  1. 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),

  2. 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

  3. 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.

5.1 Notify Additional Data

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.

In both cases, AtlasOfGroupRepresentationsNotifyData (5.1-1) can be used to make the private data available to the interface.

5.1-1 AtlasOfGroupRepresentationsNotifyData
‣ 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.

Contents of a local directory

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".

Local file describing the contents of a local or remote directory

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".

URL of a file

(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).

5.1-2 AtlasOfGroupRepresentationsForgetData
‣ 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.

5.1-3 StringOfAtlasTableOfContents
‣ 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.

5.2 The Effect of Extensions on the User Interface

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.

5.3 An Example of Extending the AtlasRep Data

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.

 [Top of Book]  [Contents]   [Previous Chapter]   [Next Chapter] 
Goto Chapter: Top 1 2 3 4 5 6 7 Bib Ind

generated by GAPDoc2HTML