#############################################################################
##
#W  ctadmin.tbd         GAP character table library             Thomas Breuer
#W                                                               Ute Schiffer
##
#H  @(#)$Id: ctadmin.tbd,v 4.40 2002/01/14 16:46:02 gap Exp $
##
#Y  Copyright (C)  1997,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
##
##  This file contains the declaration part of the data of the {\GAP}
##  character table library that is not automatically produced from the
##  library files.
##
##  0. Global variables to handle the table library.
##  1. Representations of library tables
##  2. Functions used in the library files
##  3. Functions to construct library tables
##  4. Functions used as `construction' component of library tables
##  5. Selection functions for the table library
##  6. Functions to produce tables in library format
##
Revision.( "ctbllib/gap/ctadmin_tbd" ) :=
    "@(#)$Id: ctadmin.tbd,v 4.40 2002/01/14 16:46:02 gap Exp $";


#############################################################################
##
#1
##  The data files of the {\GAP} character table library
##  reside in the `data' directory of the `ctbllib' package.
##
##  The filenames start with `ct' (for ``character table''),
##  followed by either `o' (for ``ordinary''), `b' (for ``Brauer''),
##  or `g' (for ``generic''),
##  then a description of the contents (up to $5$ characters, e.g., `alter'
##  for the tables of alternating and related groups),
##  and the suffix `.tbl'.
##
##  The file `ctb<descr>.tbl' contains the known Brauer tables
##  corresponding to the ordinary tables in the file `cto<descr>.tbl'.
##
##  Each data file of the table library is supposed to consist of
##  \beginlist
##  \item{1.}
##      comment lines, starting with `#' in the first column,
##  \item{2.}
##      assignments to `ALN' (short for ``add library name'',
##      see~"NotifyNameOfCharacterTable")
##      and to a component of `Revision', at the beginning of the file,
##      for example in the file with name `ctoalter.tbl' a value is assigned
##      to `Revision.ctoalter_tbl',
##  \item{3.}
##      assignments to `ALN' and to a component of `LIBTABLE.LOADSTATUS',
##      at the end of the file, and
##  \item{4.}
##      function calls of the form
##      `SET_TABLEFILENAME( <filename> );',
##      `MBT( <name>, <data> );' (``make Brauer table''),
##      `MOT( <name>, <data> );' (``make ordinary table''),
##      `ALF( <from>, <to>, <map> );',
##      `ALF( <from>, <to>, <map>, <textlines> );' (``add library fusion''),
##      `ALN( <name>, <listofnames> );', and
##      `ARC( <name>, <component>, <compdata> );' (``add record component'').
##
##      Here <filename> must be a string corresponding to the filename but
##      without suffix, for example `\"ctoalter\"' if the file has the name
##      `ctoalter.tbl';
##      <name> must be the identifier value of the ordinary character table
##      corresponding to the table to which the command refers;
##      <data> must be a comma separated sequence of {\GAP} objects;
##      <from> and <to> must be identifier values of ordinary character
##      tables,
##      <map> a list of positive itegers,
##      <textlines> and <listofnames> lists list of strings,
##      <component> a string, and
##      <compdata> any {\GAP} object.
##
##      `MOT', `ALF', `ALN', and `ARC' occur only in files containing
##      ordinary character tables,
##      and `MBT' occurs only in files containing Brauer tables.
##  \endlist
##  Besides the above calls, the data in files containing ordinary and Brauer
##  tables may contain only the following {\GAP} functions.
##  (Files containing generic character tables may contain arbitrary
##  {\GAP} functions.)
##
##  `ACM',
##  `Concatenation',
##  `ConstructClifford',
##  `ConstructDirectProduct',
##  `ConstructFactor',
##  `ConstructGS3',
##  `ConstructIsoclinic',
##  `ConstructMixed',
##  `ConstructPermuted',
##  `ConstructProj',
##  `ConstructSubdirect',
##  `ConstructV4G',
##  `E',
##  `EvalChars',
##  `GALOIS',
##  `Length',
##  `NotifyCharTableName',
##  `ShallowCopy',
##  `TENSOR', and
##  `TransposedMat'.
##
##  The `awk' script `maketbl' in the `etc' directory of the `ctbllib'
##  package expects the file format described above,
##  and to some extent this format is checked by this script.
##
##  The function calls may be continued over several lines of a file.
##  The `;' is assumed to be the last character in its line if and only if
##  it terminates a function call.
##
##  Names of character tables are strings
##  (see Chapter~"ref:Strings and Characters" in the {\GAP} Reference Manual),
##  i.e., they are enclosed in double quotes;
##  strings in table library files must not be split over several lines,
##  because otherwise the `awk' script may get confused.
##  Additionally, no character table name is allowed to contain double
##  quotes.
##
##  The knowledge of {\GAP} about the ordinary tables in the table library
##  is contained in the file `ctprimar.tbl' (the ``primary file'' of the
##  table library).
##  This file is automatically produced from the library files by the script
##  `maketbl' in the `etc' directory of the `ctbllib' package.
##  The information is stored in the global variable `LIBLIST',
##  which is a record with the following components.
##  \beginitems
##  `firstnames' &
##      the list of `Identifier' (see~"ref:Identifier!for character tables"
##      in the {\GAP} Reference Manual) values of the ordinary tables,
##
##  `files' &
##      the list of filenames containing the data of ordinary tables,
##
##  `filenames' &
##      a list of positive integers, value $j$ at position $i$ means that the
##      table whose identifier is the $i$--th in the `firstnames' list is
##      contained in the $j$-th file of the `files' component,
##
##  `fusionsource' &
##      a list containing at position $i$ the list of names of tables that
##      store a fusion into the table whose identifier is the $i$--th in the
##      `firstnames' list,
##
##  `allnames' &
##      a list of all admissible names of ordinary library tables,
##
##  `position' &
##      a list that stores at position $i$ the position in `firstnames'
##      of the identifier of the table with the $i$--th admissible name in
##      `allnames',
##
##  `projections' &
##      a list of triples $[ <name>, <factname>, <map> ]$
##      describing a factor fusion <map> from the table with identifier
##      <name> to the table with identifier <factname>
##      (this is used to construct the table of <name> using the data of
##      the table of <factname>),
##
##  `simpleinfo' &
##      a list of triples $[ <m>, <name>, <a> ]$ describing the tables of
##      simple groups in the library; <name> is the identifier of the table,
##      `<m>.<name>' and `<name>.<a>' are admissible names for its
##      Schur multiplier and automorphism group, respectively,
##
##  `sporadicSimple' &
##      a list of identifiers of the tables of the $26$ sporadic simple
##      groups, and
##
##  `GENERIC' &
##      a record with information about generic tables
##      (see~"Generic Character Tables").
##  \enditems
##
##  There are three different ways how the table data can be stored in the
##  file.
##
##  *Full ordinary tables* are encoded by a call to the function `MOT',
##  where the arguments correspond to the relevant attribute values;
##  each fusion into another library table is added by a call to `ALF',
##  values to be stored in components of the table object are added with
##  `ARC', and admissible names are notified with `ALN'.
##  The argument of `MOT' that encodes the irreducible characters is
##  abbreviated as follows.
##  For each subset of characters that differ just by multiplication with a
##  linear character or by Galois conjugacy, only the first one is given by
##  its values, the others are replaced by
##  `[TENSOR,[<i>,<j>]]' (which means that the character is the tensor
##  product of the <i>-th and the <j>-th character in the list)
##  or `[GALOIS,[<i>,<j>]]' (which means that the character is obtained from
##  the <i>-th character by applying `GaloisCyc( ., <j> )' to it.
##
##  *Brauer tables* are stored relative to the corresponding ordinary tables;
##  attribute values that can be got by restriction from the ordinary table
##  to $p$--regular classes are not stored,
##  and instead of the irreducible characters the files contain (inverses of)
##  decomposition matrices or Brauer trees for the blocks of nonzero defects.
##
##  *Ordinary construction tables* have a component `construction',
##  with value a function of one argument that is called by `CharacterTable'
##  when the table is constructed
##  (*not* when the file containing the table is read).
##  The aim of this mechanism is to store structured character tables such as
##  tables of direct products and tables of central extensions of other
##  tables in a very compact way.
##

#############################################################################
##
##  0. Global variables to handle the table library.
##

#############################################################################
##
#V  LIBTABLE
##
##  is a record with the components
##  \beginitems
##  `LOADSTATUS' &
##     a record whose components are names of files in the table library,
##     with value one of `\"loaded\"', `\"unloaded\"', `\"userloaded\"',
##
##  `TABLEFILENAME' &
##     the name of the file that is currently read
##     (is set by `SET_TABLEFILENAME'),
##
##  `clmelab' &
##     the list for Clifford matrices of extensions by elementary abelian
##     normal subgroups
##
##  `clmexsp' &
##     the list for Clifford matrices of extensions by extraspecial normal
##     subgroups
##  \enditems
##  Additionally the filenames of loaded and userloaded files occur as
##  components, with values the lists of data stored in the files.
##
BindGlobal( "LIBTABLE", rec(
                 LOADSTATUS    := rec(),
                 TABLEFILENAME := "",
                 clmelab       := [],
                 clmexsp       := []
                ) );


#############################################################################
##
##  OrderCyc( <cyc> )
##
##  This is needed for backward compatibility.
##  A call of `OrderCyc' (with one argument) occurs in `ctgeneri.tbl',
##  it cannot be replaced by `Order' because {\GAP}~3 does not accept it.
##
DeclareSynonym( "OrderCyc", Order );


#############################################################################
##
##  1. Representations of library tables
##
##  All these are in the library now, because the library accesses these.


#############################################################################
##
#F  SET_TABLEFILENAME( <filename> )
##
DeclareGlobalFunction( "SET_TABLEFILENAME" );


#############################################################################
##
##  2. Functions used in the library files
##

#############################################################################
##
#F  GALOIS( <chars>, <list> )
#F  TENSOR( <chars>, <list> )
##
##  are global variables used to store the library tables in compressed form.
##
##  The entry `[GALOIS,[<i>,<j>]]' in the `irreducibles' or `projectives'
##  component of a library table means the <j>-th Galois conjugate of
##  the <i>-th character.
##
##  The entry `[TENSOR,[<i>,<j>]]' in the `irreducibles' or `projectives'
##  component of a library table means the tensor product of the <i>-th
##  and the <j>-th character.
##
#F  EvalChars( <chars> )
##
##  replaces all entries of the form `[<func>,<list>]' in the list <chars>
##  by the result `<func>( <chars>, <list> )'.
##
DeclareGlobalFunction( "GALOIS" );
DeclareGlobalFunction( "TENSOR" );
DeclareGlobalFunction( "EvalChars" );


#############################################################################
##
#F  ALF( <from>, <to>, <map>[, <text>] )
##
##  `ALF' stores the fusion map <map> between the ordinary character tables
##  with identifier strings <from> and <to> in the record encoding the table
##  with identifier <from>.
##  If the string <text> is given then it is added as `text' component of the
##  fusion.
##
##  `ALF' changes the global list `LIBLIST.fusionsource'.
##
##  Note that the `ALF' statement should be placed in the file containing the
##  data for the table with identifier <from>.
##
DeclareGlobalFunction( "ALF" );


#############################################################################
##
#F  ACM( <spec>, <dim>, <val> )
##     adds a Clifford matrix to the library.
##     <spec> is one of the strings "elab", "exsp".
##     <dim> is the dimension of the Clifford matrix,
##     <val> is the Clifford matrix itself.
##
#F  ARC( <name>, <comp>, <val> )
##     adds the record component <comp> with value <val> to the table record
##     with name <name>.
##
##  These functions are used in the library table files,
##  so they assume that it is not necessary to read such a file before the
##  data can be stored.
##
DeclareGlobalFunction( "ACM" );
DeclareGlobalFunction( "ARC" );


#############################################################################
##
#F  NotifyNameOfCharacterTable( <firstname>, <newnames> )
#F  ALN( <firstname>, <newnames> )
##
##  notifies the strings in the list <newnames> as new admissible names for
##  the library table with `Identifier' value <firstname>,
##  see~"ref:Identifier!for character tables" in the {\GAP} Reference Manual.
##  If there is already another library table for which some of these names
##  are admissible then an error is signaled.
##
##  `NotifyNameOfCharacterTable' modifies the global variable `LIBLIST'.
##
##  `ALN' is a shorthand for `NotifyNameOfCharacterTable'.
##  In those library files for which the `maketbl' script has produced the
##  necessary information for `LIBLIST', `ALN' is set to `Ignore'
##  in the beginning and back to `NotifyNameOfCharacterTable' in the end.
##
DeclareGlobalFunction( "NotifyNameOfCharacterTable" );
ALN:= NotifyNameOfCharacterTable;  # We do not use `DeclareSynonym' here
                                   # because assignments are made to `ALN'
                                   # in data files.

#T because of the table files ...
NotifyCharTableName := NotifyNameOfCharacterTable;


#############################################################################
##
#F  NotifyCharacterTable( <firstname>, <filename>, <othernames> )
##
##  notifies a new ordinary table to the library.
##  This table has `identifier' component <firstname>,
##  it is contained (in library format, see~"PrintToLib") in the file with
##  name <filename>
##  (without suffix `.tbl', and relative to the `pkg/ctbllib/data' directory
##  of the {\GAP} installation),
##  and the names contained in the list <othernames> are admissible for it.
##
##  `NotifyCharacterTable' modifies the global variable `LIBLIST' for the
##  current {\GAP} session,
##  after having checked that there is no other library table yet with an
##  admissible name equal to <firstname> or contained in <othernames>.
##
DeclareGlobalFunction( "NotifyCharacterTable" );


#############################################################################
##
#F  NotifyCharTable( <firstname>, <filename>, <othernames> )
##
##  for compatibility with {\GAP}~3
##
DeclareSynonym( "NotifyCharTable", NotifyCharacterTable );


#############################################################################
##
#F  MBT( <arg> )
##
##  The library format of Brauer tables is a call to the function
##  `MBT', with the following arguments.
##
##   1. identifier of the table
##   2. field characteristic
##   3. text (list of lines)
##   4. block
##   5. defect
##   6. basic set
##   7. Brauer tree information
##   8. inverses of decomposition matrices restricted to basic sets
##   9. blocks of proper factor groups
##  10. list of generators for the group of table automorphisms
##  11. 2nd indicator (in characteristic 2 only)
##  12. (optional) record with additional components
##
##  `MBT' constructs a record and stores it in the record
##  `LIBTABLE.TABLEFILENAME'.
##
DeclareGlobalFunction( "MBT" );


#############################################################################
##
#F  MOT( <arg> )
##
##  The library format of ordinary character tables is a call to the function
##  `MOT', with the following arguments.
##
##   1. identifier of the table
##   2. text (list of lines)
##   3. list of centralizer orders
##   4. list of power maps
##   5. list of irreducibles
##   6. list of generators for the group of table automorphisms
##   7. (optional) construction of the table
##
##  Each fusion is added by `ALF', any other component of the table must be
##  added individually via `ARC( <identifier>, <compname>, <compval> )'.
##
##  `MOT' constructs a preliminary table record,
##  and puts it into the record `LIBTABLE.TABLEFILENAME'.
##  The `namesOfFusionSources' and `projections' are dealt with when the
##  table is constructed by `CharacterTableFromLibrary'.
##  Admissible names are notified by `ALN( <name>, <othernames> )'.
##
DeclareGlobalFunction( "MOT" );


#############################################################################
##
#V  GEN_Q_P
##
##  for prime powers <q>, at position <q> the unique prime divisor of <q>
##
#F  PrimeBase( <q> )  . . . . . . . . . . . . . . unique prime divisor of <q>
##
##  If <q> is a prime power, `PrimeBase' computes the prime of which it is
##  a power.  For the sake of speed, the results are stored
##  in the global list `GEN_Q_P'.
##
DeclareGlobalVariable( "GEN_Q_P",
    "list where the prime <p> is stored at position <p>^<n>, if bound" );

DeclareGlobalFunction( "PrimeBase" );


#############################################################################
##
##  3. Functions to construct library tables
##

#############################################################################
##
#F  LibInfoCharacterTable( <tblname> )
##
##  is a record with components
##  \beginitems
##  `firstName' &
##      the `Identifier' value (see~"ref:Identifier!for character tables"
##      in the {\GAP} Reference Manual) of the library table
##      for which <tblname> is an admissible name, and
##
##  `fileName' &
##      the name of the file in which the table data is stored.
##  \enditems
##  If no such table exists in the {\GAP} library then `fail' is returned.
##
##  If <tblname> contains the substring `\"mod\"' then it is regarded as the
##  name of a Brauer table.
##  In this case the result is computed from that for the corresponding
##  ordinary table and the characteristic.
##  So if the ordinary table exists then the result is a record although
##  the Brauer table in question need not be contained in the {\GAP} library.
##
DeclareGlobalFunction( "LibInfoCharacterTable" );


#############################################################################
##
#F  LibraryTables( <filename> )
##
##  is the list of data obtained on reading the file `<filename>.tbl',
##  which is understood relative to the `data' directory of the `ctbllib'
##  package.
##
DeclareGlobalFunction( "LibraryTables" );


#############################################################################
##
##  We replace the library function `CharacterTableFromLibrary' that just
##  issues a warning about nonavailability of the Character Table Library.
##
MakeReadWriteGlobal( "CharacterTableFromLibrary" );
UNBIND_GLOBAL( "CharacterTableFromLibrary" );


#############################################################################
##
#F  CharacterTableFromLibrary( <tblname> )
#F  CharacterTableFromLibrary( <series>, <param1>[, <param2>] )
##
##  If the only argument is a string <tblname> and if this is an admissible
##  name (see below) of a library character table then
##  `CharacterTableFromLibrary' returns this library table, otherwise `fail'.
##
##  If `CharacterTableFromLibrary' is called with more than one argument
##  then the first must be a string <series> specifying a series of groups
##  which is implemented via a generic character table,
##  for example `\"Symmetric\"' for symmetric groups;
##  the remaining arguments specialise then the desired member of the series
##  (see~"Generic Character Tables" for a list of available generic tables).
##  If no generic table with name <series> is available or if the parameters
##  are not admissible then `CharacterTableFromLibrary' returns `fail'.
##
##  A call of `CharacterTableFromLibrary' may cause to read some library
##  files and to construct the table object from the data stored in these
##  files,
##  so fetching a library table may take more time than on expects.
##
##  `CharacterTableFromLibrary' is called by `CharacterTable' if the first
##  argument is a string, so one may also call `CharacterTable'.
##
##  Admissible names for the *ordinary character table* $t$ of the group $G$
##  are
##  \beginlist
##  \item{-}
##      an {\ATLAS} like name if $t$ is an {\ATLAS} table
##      (see~"ATLAS Tables"), for example
##      `\"M22\"' for the table of the Mathieu group $M_{22}$,
##      `\"L2(13).2\"' for $L_2(13):2$, and
##      `\"12_1.U4(3).2_1\"' for $12_1\.U_4(3)\.2_1$,
##
##      (The difference to the name printed in the {\ATLAS} is that
##      subscripts and superscripts are omitted except if they are used to
##      qualify integer values,
##      and double dots are replaced by a single dot.)
##  \item{-}
##      the names that were admissible for tables of $G$ in {\sf CAS}
##      if the {\sf CAS} table library contained a table of $G$,
##      for example `sl42' for the table of the alternating group $A_8$,
##
##      (But note that the {\GAP} table may be different from that in
##      {\sf CAS}, see~"CAS Tables".)
##  \item{-}
##      some ``relative'' names, as follows.
##
##      If $G$ is the <n>--th maximal subgroup (in decreasing group order)
##      of a group whose library table $s$ is available in {\GAP} and stores
##      the `Maxes' value (see~"Maxes"),
##      and if <name> is an admissible name for $s$
##      then `<name>M<n>' is admissible for $t$.
##      For example, the name `\"J3M2\"' can be used to access the second
##      maximal subgroup of the sporadic simple Janko group $J_3$
##      which has the admissible name `J3'.
##
##      If $G$ is a nontrivial Sylow $p$ normalizer in a sporadic simple
##      group with admissible name <name>,
##      --where nontrivial means that $G$ is not isomorphic to a subgroup of
##      $p:(p-1)$--
##      then `<name>N<p>' is an admissible name of $t$.
##      For example, the name `\"J4N11\"' can be used to access the table of
##      the Sylow $11$ normalizer in the sporadic simple Janko group $J_4$.
##
##      In a few cases, the table of the Sylow $p$ subgroup of $G$ is
##      accessible via the name `<name>Syl<p>' where <name> is an admissible
##      name of the table of $G$.
##      For example, `\"A11Syl2\"' is an admissible name for the table of the
##      Sylow $2$ subgroup of the alternating group $A_{11}$.
##
##      In a few cases, the table of an element centralizer in $G$ is
##      accessible via the name `<name>C<cl>'
##      where <name> is an admissible name of the table of $G$.
##      For example, `\"M11C2\"' is an admissible name for the table of an
##      involution centralizer in the Mathieu group $M_{11}$.
##  \endlist
##
##  The recommended way to access *Brauer tables* from the library is via the
##  `mod' operator from the ordinary table and the desired characteristic
##  (see~"ref:BrauerTable" and "ref:Operators for Character Tables"
##  in the {\GAP} Reference Manual),
##  so it is not necessary to define admissible names of Brauer tables.
##
##  A *generic character table* (see~"Generic Character Tables") is
##  accessible only by the name given by its `Identifier' value
##  (see~"ref:Identifier!for character tables"
##  in the {\GAP} Reference Manual).
##
##  Case is not significant for character table names.
##  For example, both `\"suzm3\"' and `\"SuzM3\"' are admissible names for
##  the third maximal subgroup of the sporadic simple Suzuki group.
##
DeclareGlobalFunction( "CharacterTableFromLibrary" );


#############################################################################
##
#F  PartsBrauerTableName( <modname> )
##
##  is a record with components
##  `ordname'
##      substring up to the occurrence of `mod' in <modname>,
##  `prime'
##      the integer of the string after `mod'.
##
DeclareGlobalFunction( "PartsBrauerTableName" );


#############################################################################
##
#F  BasicSetBrauerTree( <brauertree> )
##
##  returns a basic set of the Brauer tree <brauertree>.
##  *Note* that this is a list of positions relative to the block, so it is
##  not compatible with the `basicset' components of blocks in Brauer tables.
##
DeclareGlobalFunction( "BasicSetBrauerTree" );


#############################################################################
##
#F  DecMatBrauerTree( <brauertree> )
##
##  In the {\GAP} table library, a Brauer tree <brauertree> is a list where
##  `<brauertree>[i]' contains the positions of `1' in the `i'-th column
##  of the decomposition matrix of the corresponding block.
##  So `<brauertree>[i]' has length 2 or 3 (in the case of exceptional
##  characters).
##
##  `DecMatBrauerTree' returns the decomposition matrix of the block with
##  given Brauer tree.
##
DeclareGlobalFunction( "DecMatBrauerTree" );


#############################################################################
##
#F  BrauerTree( <decmat> )
##
##  returns the Brauer tree of the decomposition matrix <decmat>, if exists,
##  and `fail' otherwise.
##
DeclareGlobalFunction( "BrauerTree" );


#############################################################################
##
#F  BrauerTableFromLibrary( <ordtbl>, <p> )
##
##  is the <p>-modular Brauer table of the ordinary library table <ordtbl>.
##
DeclareGlobalFunction( "BrauerTableFromLibrary" );


#############################################################################
##
#F  CharacterTableSpecialized( <generic_table>, <q> )  . . . . specialise <q>
##
##  For a record <generic_table> representing a generic character table,
##  and a parameter value <q>,
##  `CharacterTableSpecialized' returns a character table object computed by
##  evaluating <generic_table> at <q>.
##
DeclareGlobalFunction( "CharacterTableSpecialized" );


#############################################################################
##
#F  CharTableSpecialized( <gentbl>, <param> )
##
##  for compatibility with {\GAP}~3
##
DeclareSynonym( "CharTableSpecialized", CharacterTableSpecialized );


#############################################################################
##
##  4. Functions used as `construction' component of library tables
##
##  Note that in all construction functions, the table under construction is
##  a plain record, *not* a table object.
##

#############################################################################
##
#F  TransferComponentsToLibraryTableRecord( <t>, <tbl> )
##
##  <t> must be a library character table, and <tbl> a record that will be
##  converted to a library character table later.
##  `TransferComponentsToLibraryTableRecord' transfers all those values
##  from <t> to <tbl> that are described by `SupportedOrdinaryTableInfo'
##  and `SupportedLibraryTableComponents'.
##
DeclareGlobalFunction( "TransferComponentsToLibraryTableRecord" );


#############################################################################
##
#V  TABLE_CONSTRUCTORS
#F  DeclareTableConstructor( <name> )
##
##  `TABLE_CONSTRUCTORS' is a list of length 2, the first containing the
##  functions that are used as `construction' components of library tables,
##  and the second containing the corresponding names of these function.
##  This list is used for example by `PrintToLib'.
##
##  `DeclareTableConstructor' calls `DeclareGlobalFunction'
##  and stores the corresponding global variable and <name>
##  in the global variable `TABLE_CONSTRUCTORS'.
##
BindGlobal( "TABLE_CONSTRUCTORS", [ [], [] ] );

BindGlobal( "DeclareTableConstructor", function( name )
    DeclareGlobalFunction( name );
    Add( TABLE_CONSTRUCTORS[1], ValueGlobal( name ) );
    Add( TABLE_CONSTRUCTORS[2], name );
end );


#############################################################################
##
#F  ConstructMixed( <tbl>, <subname>, <factname>, <plan>, <perm> )
##
##  `ConstructMixed' constructs the ordinary character table <tbl> of a group
##  $m\.G\.a$ where the automorphism $a$ (a group of prime order) of $m\.G$
##  acts notrivially on the central subgroup $m$ of $m\.G$.
##  <subname> is the name of the subgroup $m\.G$ which is a (not necessarily
##  cyclic) central extension of the (not necessarily simple) group $G$,
##  <factname> is the name of the factor group $G\.a$.
##  Then the faithful characters of <tbl> are induced characters of $m\.G$.
##
##  <plan> is a list, each entry being a list containing positions of
##  characters of $m\.G$ that form an orbit under the action of $a$
##  (so the induction of characters is simulated).
##
##  <perm> is the permutation that must be applied to the list of characters
##  that is obtained on appending the faithful characters to the
##  inflated characters of the factor group.
##  A nonidentity permutation occurs for example for groups of structure
##  $12\.G\.2$ that are encoded via the subgroup $12\.G$ and the factor group
##  $6\.G\.2$, where the faithful characters of $4\.G\.2$ shall precede those
##  of $6\.G\.2$.
##
##  Examples where `ConstructMixed' is used to encode library tables are the
##  tables of $3\.F_{3+}\.2$ (subgroup $3\.F_{3+}$, factor group $F_{3+}\.2$)
##  and $12_1\.U_4(3)\.2_2$ (subgroup $12_1\.U_4(3)$, factor group
##  $6_1\.U_4(3)\.2_2$).
##
DeclareTableConstructor( "ConstructMixed" );


#############################################################################
##
#F  ConstructMixedInfo( <tblmGa>, <tblmG>, <tblGa> )
##
##  Let <tblmGa> be the ordinary character table of a group of structure
##  $m\.G\.a$ where the factor group of prime order $a$ acts nontrivially on
##  the normal subgroup of order $m$ that is central in $m\.G$,
##  <tblmG> the character table of $m\.G$, and <tblGa> the character table of
##  the factor group $G\.a$.
##
##  `ConstructMixedInfo' returns a record with components `subname',
##  `factname', `plan', and `perm',
##  which are the arguments of `ConstructMixed' (see~"ConstructMixed").
##
DeclareGlobalFunction( "ConstructMixedInfo" );


#############################################################################
##
#F  ConstructProj( <tbl> )
#F  ConstructProjInfo( <tbl>, <kernel> )
##
##  `ConstructProj' constructs the irreducible characters of record encoding
##  the ordinary character table <tbl> from projective characters of tables
##  of factor groups,
##  which are stored in the `projectives' component of the smallest factor;
##  the information about the name of this factor and the projectives to
##  take is stored in the `Irr' component of <tbl>.
##
##  `ConstructProjInfo' takes an ordinary character table <tbl> and a list
##  <kernel> of class positions of a cyclic kernel of order dividing $12$,
##  and returns a record with the components
##  \beginitems
##  `projectives' &
##      a record being the entry for the `projectives' list of the table of
##      the factor of <tbl> by <kernel>,
##      describing the irreducibles of <tbl>, and
##
##  `info' &
##      the value of the `Irr' component of the library version of <tbl>
##      before applying `ConstructProj'.
##  \enditems
##
##  In order to encode a library table $t$ as a ``projective table'' relative
##  to another library table $f$, say, one has to do the following.
##  First the factor fusion from $t$ to $f$ must be stored on the table of
##  $t$, and $t$ is written to a library file.
##  Then the result of `ConstructProjInfo', called for $t$ and the kernel of
##  the factor fusion is used.
##  Its `info' component replaces the irreducibles in the library version of
##  $t$, and `ConstructProj' is added as last entry of the `MOT' call for this
##  library version.
##  The `projectives' component is added to the list $f$`!.projectives',
##  and a new library version of $f$ is produced (this contains the new
##  projectives via an `ARC' call).
##  Finally, `etc/maketbl' is called in order to store the projection for the
##  factor fusion in the `ctprimar.tbl' data.
##
DeclareTableConstructor( "ConstructProj" );

DeclareGlobalFunction( "ConstructProjInfo" );


#############################################################################
##
#F  ConstructDirectProduct( <tbl> )
#F  ConstructDirectProduct( <tbl>, <permclasses>, <permchars> )
##
##  is a special case of a `construction' call for a library table <tbl>.
##
##  The direct product of the tables described in the list `<tbl>.factors' is
##  constructed, and all its components stored not yet in <tbl> are
##  added to <tbl>.
##
##  The `computedClassFusions' component of <tbl> is enlarged
##  by the factor fusions from the direct product to the factors.
##
##  If the optional arguments <permclasses>, <permchars> are given then
##  classes and characters of the result are sorted accordingly.
##
DeclareTableConstructor( "ConstructDirectProduct" );


#############################################################################
##
#F  ConstructSubdirect( <tbl>, <factors>, <choice> )
##
##  The library table <tbl> is completed with help of the table got from
##  taking the direct product of the tables with names in the list <factors>,
##  and then taking the table consisting of the classes in the list <choice>.
##
DeclareTableConstructor( "ConstructSubdirect" );


#############################################################################
##
#F  ConstructIsoclinic( <tbl> )
#F  ConstructIsoclinic( <tbl>, <nsg> )
##
##  constructs first the direct product of library tables as given by the
##  list `<tbl>.factors', and then constructs the isoclinic table of the
##  result.
##  All components of this table that are missing in <tbl> are added
##  to <tbl>.
##
DeclareTableConstructor( "ConstructIsoclinic" );


#############################################################################
##
#F  ConstructV4G( <tbl>, <facttbl>, <aut>[, <ker>] )
##
##  Let <tbl> be the character table of a group of type $2^2\.G$
##  where an outer automorphism of order 3 permutes the three involutions
##  in the central $2^2$.
##  Let <aut> be the permutation of classes of <tbl> induced by that
##  automorphism, and <facttbl> the name of the character table
##  of the factor group $2\.G$.
##  Then `ConstructV4G' constructs the irreducible characters of <tbl> from
##  that information.
##
##  The optional argument <ker> is an integer denoting the position of the
##  nontrivial class of the table of $2\.G$ that lies in the kernel of the
##  epimorphism onto $G$; the default for <ker> is $2$.
##
DeclareTableConstructor( "ConstructV4G" );


#############################################################################
##
#F  InducedLibraryCharacters( <subtbl>, <tblrec>, <chars>, <fusionmap> )
##
##  is the list of class function values lists
##
DeclareGlobalFunction( "InducedLibraryCharacters" );


#############################################################################
##
#F  ConstructGS3( <tbls3>, <tbl2>, <tbl3>, <ind2>, <ind3>, <ext>, <perm> )
#F  ConstructGS3Info( <tbl2>, <tbl3>, <tbls3> )
##
##  `ConstructGS3' constructs the irreducibles of a table <tbls3> of type
##  $G\.S_3$ from the tables with names <tbl2> and <tbl3>, corresponding to
##  the groups $G\.2$ and $G\.3$, respectively.
##  <ind2> is a list of numbers referring to irreducibles of <tbl2>.
##  <ind3> is a list of pairs, each referring to irreducibles of <tbl3>.
##  <ext>  is a list of pairs, each referring to one irreducible of <tbl2>
##                             and one of <tbl3>.
##  <perm> is a permutation that must be applied to the irreducibles
##  after the construction.
##
##  `ConstructGS3Info' returns a record with the components `ind2', `ind3',
##  `ext', and `perm', as needed for `ConstructGS3'.
##
DeclareTableConstructor( "ConstructGS3" );

DeclareGlobalFunction( "ConstructGS3Info" );


#############################################################################
##
#F  ConstructPermuted( <tbl>, <libnam>, <prmclasses>, <prmchars> )
##
##  The library table <tbl> is completed with help of the library table with
##  name <libnam>, whose classes and characters must be permuted by the
##  permutations <prmclasses> and <prmchars>, respectively.
##
DeclareTableConstructor( "ConstructPermuted" );


#############################################################################
##
#F  ConstructFactor( <tbl>, <libnam>, <kernel> )
##
##  The library table <tbl> is completed with help of the library table with
##  name <libnam>, by factoring out the classes in the list <kernel>.
##
DeclareTableConstructor( "ConstructFactor" );


#############################################################################
##
#F  ConstructClifford( <tbl> )
##
##  constructs the irreducibles of the ordinary character table <tbl> from
##  the Clifford matrices stored in `<tbl>.cliffordTable'.
##
DeclareTableConstructor( "ConstructClifford" );


#############################################################################
##
#F  UnpackedCll( <cll> )
##
##  is a record with the components `mat', `inertiagrps', `fusionclasses',
##  and perhaps `libname'.
##  These are the only components used in the construction of library
##  character tables encoded by Clifford matrices.
##
##  The meaning of <cll> is the same as in `CllToClf'.
##
DeclareGlobalFunction( "UnpackedCll" );


#############################################################################
##
#F  CllToClf( <tbl>, <cll> )
##
##  is a Clifford matrix for the table <tbl>.
##  It is constructed from the list <cll> that contains
##  the following entries.
##  1. list of indices of inertia factors
##  2. list of classes fusing in the factor group
##  3. identification of the matrix,
##     either unbound (then the matrix has dimension <= 2)
##     or a list containing
##       a. string `"elab"' or `"exsp"'
##       b. size of the Clifford matrix
##       c. index in the library file
##       d. (optional) necessary permutation of columns
##     or a list containing
##       a. the Clifford matrix itself and
##       b. the column weights.
##  4. (case `"exsp"') a list with items of record `splitinfos':
##       a. classindex
##       b. p
##       c. numclasses
##       d. root
##
DeclareGlobalFunction( "CllToClf" );


#############################################################################
##
##  5. Selection functions for the table library
##

#############################################################################
##
#F  OfThose()
#F  IsSporadicSimple( <G> )
##
##  dummy functions for selection function
##
DeclareGlobalFunction( "OfThose" );
DeclareGlobalFunction( "IsSporadicSimple" );
#T make this a proper property?


#############################################################################
##
#F  AllCharacterTableNames( {<func>, <val>} )
#F  AllCharacterTableNames( <func>, <val>, ...{, OfThose, <func>} )
##
##  Similar to group libraries (see Chapter~"ref:Group Libraries" in the
##  {\GAP} Reference Manual),
##  the {\GAP} character table library can be used to search for ordinary
##  character tables with prescribed properties.
##
##  A specific library table can be selected by an admissible name
##  (see~"CharacterTableFromLibrary").
##
##  The selection function for character tables with certain abstract
##  properties is `AllCharacterTableNames'.
##  Contrary to the situation in the case of group libraries,
##  the selection function returns a list not of library character tables
##  but of their names;
##  using `CharacterTable' one can then access the tables themselves.
##
##  `AllCharacterTableNames' takes an arbitrary even number of arguments.
##  The argument at each odd position must be a function, and
##  the argument at the subsequent even position must be a value that this
##  function must return when called for the character table in question,
##  in order to have the name of the table included in the selection,
##  or a list of such values.
##  For example,
##  \beginexample
##  gap> names:= AllCharacterTableNames();;
##  \endexample
##  returns a list containing one admissible name of each ordinary character
##  table in the {\GAP} library, and
##  \beginexample
##  gap> simpnames:= AllCharacterTableNames( IsSimple, true );;
##  gap> AllCharacterTableNames( IsSimple, true, Size, [ 1 .. 100 ] );
##  [ "A5" ]
##  \endexample
##  return lists containing an admissible name of each ordinary character
##  table in the {\GAP} library whose groups are simple or are simple and
##  have order at most $100$, respectively.
##
##  For the sake of efficiency,
##  the arguments `IsSimple' and `IsSporadicSimple' followed by `true' are
##  handled in a special way, {\GAP} need not read all files of the table
##  library in these cases in order to find the desired names.
##
##  If the function `OfThose' is an argument at an odd position then the
##  following argument <func> must be a function that takes a character table
##  and returns a name of a character table or a list of names;
##  this is interpreted as replacement of the names computed up to this
##  position by the union of names returned by <func>.
##  For example, <func> may be `Maxes' (see~"Maxes") or
##  `NamesOfFusionSources' (see~"ref:NamesOfFusionSources" in the {\GAP}
##  Reference Manual).
##  \beginexample
##  gap> maxesnames:= AllCharacterTableNames( IsSporadicSimple, true,
##  >                                         HasMaxes, true,
##  >                                         OfThose, Maxes );;
##  \endexample
##  returns the union of names of ordinary tables of those maximal subgroups
##  of sporadic simple groups that are contained in the table library.
##
DeclareGlobalFunction( "AllCharacterTableNames" );


#############################################################################
##
#F  AllCharTableNames( ... )
##
##  for compatibility with {\GAP}~3
##
DeclareSynonym( "AllCharTableNames", AllCharacterTableNames );


#############################################################################
##
##  6. Functions to produce tables in library format
##

#############################################################################
##
#F  ShrinkClifford( <tbl> )
##
##  shrinks the `cliffordTable' component.
##  The Clifford records are changed to library format using `ClfToCll'.
##  In the library format, only the component `ident' of the inertia factor
##  groups are stored.
##
DeclareGlobalFunction( "ShrinkClifford" );


#############################################################################
##
#F  TextString( <text> )
##
##  returns a string that is printed as
##
##  [
##  "<line_1>\n",
##  "<line_1>\n",
##  ...
##  "<line_n>"
##  ]
##
##  where <line_i> is the <i>-th line of the output of `Print( <text> )',
##  except that the doublequotes are escaped.
##
##  *Note* that the `]' is the last output character.
##
DeclareGlobalFunction( "TextString" );


#############################################################################
##
#F  BlanklessPrintTo( <stream>, <obj> )
##
##  appends <obj> to the output stream <stream>,
##  thereby trying to avoid unnecessary blanks.
##  For the subobjects of <obj>, the function `PrintTo' is used.
##  (So the subobjects are appended only if <stream> is of the appropriate
##  type, see~"PrintTo".)
##
##  If <obj> is a record then the component `text' and strings in an `irr'
##  list are *not* treated in a special way!
##
##  This function is used by the libraries of character tables and of tables
##  of marks.
##
DeclareGlobalFunction( "BlanklessPrintTo" );
#T better use WriteAll?


#############################################################################
##
#F  ShrinkChars( <chars> )
##
##  returns the list corresponding to the list <chars> where
##
##  each `<chars>[<k>]' that is the tensor product of `<chars>[<i>]'
##  and a linear character `<chars>[j]' with $i, j \leq k$ is replaced by
##  the string `\"[TENSOR,[<i>,<j>]]\"', and
##
##  each `<chars>[<k>]' that is the <j>-th Galois conjugate of `<chars>[<i>]'
##  with $i \leq k$ is replaced by the string `\"[GALOIS,[<i>,<j>]]\"'.
##
##  This function is used by `PrintToLib'.
##
DeclareGlobalFunction( "ShrinkChars" );


#############################################################################
##
#F  ClfToCll( <clf> )
##
##  is a list encoding the information in the Clifford matrix record <clf>.
##  <clf> must contain the components `mat', `inertiagrps', `fusionclasses'.
##
##  See `CllToClf' for the meaning of the entries.
##
DeclareGlobalFunction( "ClfToCll" );
#T up to now no function is installed


#############################################################################
##
#F  LibraryFusion( <name>, <fus> )
##
##  For a string <name> that is an `Identifier' value
##  (see~"ref:Identifier!for character tables" in the {\GAP} Reference
##  Manual)  of an ordinary character table in the {\GAP} library,
##  and a record <fus> with components `name' (the identifier of the
##  destination table), `map' (the fusion map, a list of image positions),
##  and optionally `text' (a string containing information about the fusion),
##  `LibraryFusion' returns a string whose printed value can be used to add
##  the fusion in question to the library file containing the data for the
##  table with identifier <name>.
##
##  <name> may also be a character table, in this case its `Identifier' value
##  is used as string.
##
DeclareGlobalFunction( "LibraryFusion" );


#############################################################################
##
#F  PrintToLib( <file>, <tbl> )
##
##  prints the (ordinary or Brauer) character table <tbl> in library format
##  to the file `<file>.tbl' or <file>
##  (if this has already the suffix `.tbl'), respectively.
##
##  If <tbl> is an ordinary table then the value of the attribute
##  `NamesOfFusionSources' is ignored by `PrintToLib',
##  since for library tables this information is extracted from the source
##  files by the `maketbl' script.
##
DeclareGlobalFunction( "PrintToLib" );


#############################################################################
##
#F  PrintClmsToLib( <file>, <clms> )
##
##  prints the Clifford matrices in library format in a list on the file
##  <file> which are not yet in the Clifford matrix library or in this list.
##
##  <clms> must be a Clifford table or a list of Clifford records.
##  In case of splitting, each Clifford record must contain `splitinfos'.
##
DeclareGlobalFunction( "PrintClmsToLib" );
#T up to now no function is installed


#############################################################################
##
#F  OrbitsResidueClass( <pq>, <set> )
##
##  is used in the generic character table of the groups $p \colon q$.
##  <pq> must be a list of length 2, the first entry being $p$, the second
##  being $q$.
##  <set> is the set of points to act on.
##
DeclareGlobalFunction( "OrbitsResidueClass" );


#############################################################################
##
#A  CASInfo( <tbl> )
##
##  Let <tbl> be an ordinary character table <tbl> in the {\GAP} library
##  that was contained already in the {\sf CAS} table library.
##  When one fetches <tbl> from the library, one does in general not get the
##  original {\sf CAS} table.
##  Namely, in many cases (mostly {\ATLAS} tables, see~"ATLAS Tables")
##  the identifier of the table (see~"ref:Identifier!for character tables"
##  in the {\GAP} Reference Manual) as well as the ordering of classes and
##  characters are different for the {\sf CAS} table and its {\GAP} version.
##
##  Note that in several cases, the {\sf CAS} library contains different
##  tables of the same group,
##  in particular these tables may have different names and orderings of
##  classes and characters.
##
##  The `CASInfo' value of <tbl>, if stored, is a list of records,
##  each describing the relation between <tbl> and a character table in the
##  {\sf CAS} library.
##  The records have the components
##  \beginitems
##  `name' &
##      the name of the {\sf CAS} table,
##
##  `permchars' and `permclasses' &
##      permutations of the `Irr' values and the classes of <tbl>,
##      respectively, that must be applied in order to get the orderings in
##      the original {\sf CAS} table, and
##
##  `text' &
##      the text that was stored on the {\sf CAS} table
##      (which may contain incorrect statements).
##  \enditems
##
DeclareAttributeSuppCT( "CASInfo", IsNearlyCharacterTable,
    [ "class", "character" ] );


#############################################################################
##
#A  Maxes( <tbl> )
##
##  is a list of identifiers of the tables of all maximal subgroups of <tbl>.
##  This is meaningful usually only for library tables,
##  and there is no default method to compute the value.
##
##  If the `Maxes' value of <tbl> is stored then it lists exactly one
##  representative for each conjugacy class of maximal subgroups of the group
##  of <tbl>;
##  the tables of these maximal subgroups are then available in the {\GAP}
##  table library, and the fusions to <tbl> are stored on these tables.
##
DeclareAttributeSuppCT( "Maxes", IsNearlyCharacterTable, [] );


#############################################################################
##
#F  GaloisPartnersOfIrreducibles( <tbl>, <characters>, <n> )
##
DeclareGlobalFunction( "GaloisPartnersOfIrreducibles" );


#############################################################################
##
#F  AtlasLabelsOfIrreducibles( <tbl>[, "short"] )
##
##  Let <tbl> be the (ordinary or Brauer) character table of a bicyclic
##  extension of a simple group that occurs in the
##  {\ATLAS} of Finite Groups~\cite{CCN85} or the
##  {\ATLAS} of Brauer Characters~\cite{JLPW95}.
##  `AtlasLabelsOfIrreducibles' returns a list of strings, the $i$-th entry
##  being a label for the $i$-th irreducible character of <tbl>.
##
##  The labels have the following form.
##  We state the rules only for ordinary characters,
##  the rules for Brauer characters are obtained by replacing $\chi$
##  by $\varphi$.
##
##  First consider only downward extensions $m\.G$ of a simple group $G$.
##  If $m \leq 2$ then only labels of the form $\chi_i$ occur,
##  which denotes the $i$-th ordinary character shown in the {\ATLAS}.
##
##  The labels of faithful ordinary characters of groups $m\.G$ with $m\geq 3$
##  are of the form $\chi_i$, $\chi_i^{\ast}$, or $\chi_i^{\ast k}$,
##  which means the $i$-th character printed in the {\ATLAS},
##  the unique character that is not printed and for which $\chi_i$ acts as
##  proxy
##  (see~Sections~8 and~19 of Chapter~7 in the {\ATLAS} of Finite Groups),
##  and the image of the printed character $\chi_i$ under the algebraic
##  conjugacy operator $\ast k$, respectively.
##
##  For groups $m\.G\.a$ with $a > 1$, the labels of the irreducible characters
##  are derived from the labels of the irreducible constituents of their
##  restrictions to $m\.G$, as follows.
##  \beginlist
##  \item{1.}
##      If the ordinary irreducible character $\chi_i$ of $m\.G$ extends to
##      $m\.G\.a$ then the $a^{\prime}$ extensions are denoted by
##      $\chi_{i,0}, \chi_{i,1}, \ldots, \chi_{i,a^{\prime}}$,
##      where $\chi_{i,0}$ is the character whose values are printed in the
##      {\ATLAS}.
##  \item{2.}
##      The label $\chi_{i_1 + i_2 + \cdots + i_a}$ means that $a$ different
##      characters $\chi_{i_1}, \chi_{i_2}, \ldots, \chi_{i_a}$ of $m\.G$
##      induce to an irreducible character of $m\.G\.a$ with this label.
##
##      If the string `\"short\"' was entered as the second argument then the
##      label has the short form $\chi_{i_1+}$.
##      Note that $i_2, i_3, \ldots, i_a$ can be read off from the
##      fusion signs in the {\ATLAS}.
##  \item{3.}
##      Finally, the label
##      $\chi_{i_1,j_1 + i_2,j_2 + \cdots + i_{a^{\prime}},j_{a^{\prime}}}$
##      means that the characters
##      $\chi_{i_1}, \chi_{i_2}, \ldots, \chi_{i_{a^{\prime}}}$ of $m\.G$
##      extend to a group that lies properly between $m\.G$ and $m\.G\.a$,
##      and the extensions $\chi_{i_1,j_1}, \chi_{i_2,j_2}, \ldots
##      \chi_{i_{a^{\prime}},j_{a^{\prime}}}$
##      induce to an irreducible character of $m\.G\.a$ with this label.
##
##      Again, if the string `\"short\"' was entered as the second argument
##      then the label has a short form, namely $\chi_{i,j+}$.
##  \endlist
##
DeclareGlobalFunction( "AtlasLabelsOfIrreducibles" );


#############################################################################
##
#E

