This file is indexed.

/usr/share/gap/pkg/AtlasRep/gap/brmindeg.g is in gap-atlasrep 1.5.1-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
#############################################################################
##
#W  brmindeg.g           GAP 4 package AtlasRep                 Thomas Breuer
##
#Y  Copyright (C)  2007,  Lehrstuhl D fuer Mathematik,  RWTH Aachen,  Germany
##
##  This file contains a Browse application for showing the minimal degree
##  data in a table.
##


#############################################################################
##
#F  BrowseMinimalDegrees( [<groupnames>] )
##
##  <#GAPDoc Label="BrowseMinimalDegrees">
##  <ManSection>
##  <Func Name="BrowseMinimalDegrees" Arg='[groupnames]'/>
##  
##  <Returns>
##  the list of info records for the clicked representations.
##  </Returns>
##  <Description>
##  If the &GAP; package <Package>Browse</Package> (see <Cite Key="Browse"/>)
##  is loaded then this function is available.
##  It opens a browse table whose rows correspond to the groups for which the
##  <Package>ATLAS</Package> of Group Representations contains
##  some information about minimal degrees,
##  whose columns correspond to the characteristics that occur,
##  and whose entries are the known minimal degrees.
##  <P/>
##  <Example><![CDATA[
##  gap> if IsBound( BrowseMinimalDegrees ) then
##  >   down:= NCurses.keys.DOWN;;  DOWN:= NCurses.keys.NPAGE;;
##  >   right:= NCurses.keys.RIGHT;;  END:= NCurses.keys.END;;
##  >   enter:= NCurses.keys.ENTER;;  nop:= [ 14, 14, 14 ];;
##  >   # just scroll in the table
##  >   BrowseData.SetReplay( Concatenation( [ DOWN, DOWN, DOWN,
##  >          right, right, right ], "sedddrrrddd", nop, nop, "Q" ) );
##  >   BrowseMinimalDegrees();;
##  >   # restrict the table to the groups with minimal ordinary degree 6
##  >   BrowseData.SetReplay( Concatenation( "scf6",
##  >        [ down, down, right, enter, enter ] , nop, nop, "Q" ) );
##  >   BrowseMinimalDegrees();;
##  >   BrowseData.SetReplay( false );
##  > fi;
##  ]]></Example>
##  <P/>
##  If an argument <A>groupnames</A> is given then it must be a list of
##  group names of the <Package>ATLAS</Package> of Group Representations;
##  the browse table is then restricted to the rows corresponding to these
##  group names and to the columns that are relevant for these groups.
##  A perhaps interesting example is the subtable with the data concerning
##  sporadic simple groups and their covering groups,
##  which has been published in <Cite Key="Jan05"/>.
##  This table can be shown as follows.
##  <P/>
##  <Example><![CDATA[
##  gap> if IsBound( BrowseMinimalDegrees ) then
##  >   # just scroll in the table
##  >   BrowseData.SetReplay( Concatenation( [ DOWN, DOWN, DOWN, END ],
##  >          "rrrrrrrrrrrrrr", nop, nop, "Q" ) );
##  >   BrowseMinimalDegrees( BibliographySporadicSimple.groupNamesJan05 );;
##  > fi;
##  ]]></Example>
##  <P/>
##  The browse table does not contain rows for the groups
##  <M>6.M_{22}</M>, <M>12.M_{22}</M>, <M>6.Fi_{22}</M>.
##  Note that in spite of the title of <Cite Key="Jan05"/>, the entries in
##  Table 1 of this paper are in fact the minimal degrees of faithful
##  <E>irreducible</E> representations, and in the above three cases,
##  these degrees are larger than the minimal degrees of faithful
##  representations.
##  The underlying data of the browse table is about the minimal faithful
##  (but not necessarily irreducible) degrees.
##  <P/>
##  The return value of <Ref Func="BrowseMinimalDegrees"/> is the list of
##  <Ref Func="OneAtlasGeneratingSetInfo"/> values for those representations
##  that have been <Q>clicked</Q> in visual mode.
##  <P/>
##  The variant without arguments of this function is also available
##  in the menu shown by <Ref Func="BrowseGapData" BookName="Browse"/>.
##  </Description>
##  </ManSection>
##  <#/GAPDoc>
##
BindGlobal( "BrowseMinimalDegrees", function( arg )
    local data, name, char, lastj, labelsrow, mat, src, i, entry, pos, j,
          perm, info, file, parse, keys, modes, newactions, showaction, mode,
          table, result;

    if Length( arg ) = 0 then
      data:= MinimalRepresentationInfoData.datalist;
    elif Length( arg ) = 1 and IsList( arg[1] ) then
      data:= [];
      for name in arg[1] do
        Append( data, Filtered( MinimalRepresentationInfoData.datalist,
                                x -> x[1] = name ) );
      od;
      if IsEmpty( data ) then
        return [];
      fi;
    else
      Error( "usage: BrowseMinimalDegrees( [<groupnames>] )" );
    fi;

    char:= Set( List( Filtered( data, x -> x[2][1] = "Characteristic" ),
                      x -> x[2][2] ) );
    lastj:= Length( char ) + 1;
    labelsrow:= [];
    mat:= [];
    src:= [];
    for i in [ 1 .. Length( data ) ] do
      entry:= data[i];
      pos:= Position( labelsrow, entry[1] );
      if pos = fail then
        pos:= Length( labelsrow ) + 1;
        labelsrow[ pos ]:= entry[1];
        mat[ pos ]:= [];
        src[ pos ]:= [];
      fi;
      if   entry[2][1] = "Characteristic" and IsInt( entry[3] ) then
        j:= Position( char, entry[2][2] );
        if OneAtlasGeneratingSetInfo( labelsrow[ pos ],
               Characteristic, entry[2][2], Dimension, entry[3] ) = fail then
          mat[ pos ][j]:= String( entry[3] );
        else
          mat[ pos ][j]:= rec( rows:= [ [ NCurses.attrs.BOLD, true,
                  NCurses.ColorAttr( "blue", -1 ), true,
                  String( entry[3] ) ] ], align:= "r" );
        fi;
        if not IsBound( src[ pos ][j] ) then
          src[ pos ][j]:= [];
        fi;
        AddSet( src[ pos ][j], entry[4] );
      elif entry[2] = "NrMovedPoints" then
        if OneAtlasGeneratingSetInfo( labelsrow[ pos ],
               NrMovedPoints, entry[3] ) = fail then
          mat[ pos ][ lastj ]:= String( entry[3] );
        else
          mat[ pos ][ lastj ]:= rec( rows:= [ [ NCurses.attrs.BOLD, true,
                  NCurses.ColorAttr( "blue", -1 ), true,
                  String( entry[3] ) ] ], align:= "r" );
        fi;
        if not IsBound( src[ pos ][ lastj ] ) then
          src[ pos ][ lastj ]:= [];
        fi;
        AddSet( src[ pos ][ lastj ], entry[4] );
      fi;
    od;

    if Length( arg ) = 0 then
      # Sort the rows.
      perm:= Sortex( List( labelsrow,
                       BrowseData.SplitStringIntoNumbersAndNonnumbers ) );
#T really better than BrowseData.CompareAsNumbersAndNonnumbers?

      labelsrow:= Permuted( labelsrow, perm );
      mat:= Permuted( mat, perm );
      src:= Permuted( src, perm );
    fi;

    # Fill missing entries with a question mark.
    for i in [ 1 .. Length( mat ) ] do
      info:= First( AtlasOfGroupRepresentationsInfo.GAPnames,
                    x -> x[1] = labelsrow[i] );
      for j in [ 1 .. Length( char ) ] do
        if not IsBound( mat[i][j] ) then
          if char[j] = 0 or ( IsList( info ) and IsBound( info[3].size )
                              and info[3].size mod char[j] = 0 ) then
            mat[i][j]:= "?";
          fi;
        fi;
      od;
      # perm. degree
      if not IsBound( mat[i][ lastj ] ) then
        mat[i][ lastj ]:= "?";
      fi;
    od;

    # Load the bibliographic data.
    file:= Filename( DirectoriesPackageLibrary( "atlasrep", "bibl" ),
                     "mindegbib.xml" );
    parse:= ParseBibXMLextFiles( file );
    keys:= List( parse.entries,
                 e -> RecBibXMLEntry( e, "Text", parse.strings ).Label );

    # Construct the extended modes if necessary.
    if not IsBound( BrowseData.defaults.work.customizedModes.brmindeg ) then
      # Create a shallow copy of each default mode for `Browse', and add
      # new actions to those modes where an entry is selected:
      # - vb: Show BibTeX format of the selected entry in a pager
      # - vh: Show HTML format of the selected entry in a pager
      # - vt: Show text format of the selected entry in a pager
      modes:= List( BrowseData.defaults.work.availableModes,
                    BrowseData.ShallowCopyMode );
      BrowseData.defaults.work.customizedModes.brmindeg:= modes;
      newactions:= [ [ "vb", "BibTeX" ],
                     [ "vh", "HTML" ],
                     [ "vt", "Text" ] ];
      showaction:= pair -> [ [ pair[1] ],
        rec( helplines:= [ Concatenation( "show ", pair[2],
                             " format of bibl. info" ),
                           "for the selected entry in a pager" ],
             action:= function( t )
               local row, col, disp, i, pos;

               if t.dynamic.selectedEntry <> [ 0, 0 ] then
                 row:= t.dynamic.indexRow[ t.dynamic.selectedEntry[1] ] / 2;
                 col:= t.dynamic.indexCol[ t.dynamic.selectedEntry[2] ] / 2;
                 if IsBound( src[ row ][ col ] ) then
                   disp:= [];
                   for i in src[ row ][ col ] do
                     pos:= Position( keys, i );
                     if pos <> fail then
                       Add( disp, parse.entries[ pos ] );
                     fi;
                   od;
                   if not IsEmpty( disp ) then
                     NCurses.hide_panel( t.dynamic.statuspanel );
                     NCurses.Pager( JoinStringsWithSeparator( List( disp,
                       e -> BrowseData.SimplifiedString(
                            StringBibXMLEntry( e, pair[2],
                              parse.strings ) ) ), "\n" ) );
                     NCurses.show_panel( t.dynamic.statuspanel );
                   fi;
                 fi;
               fi;
               t.dynamic.changed:= true;
             end ) ];
      newactions:= List( newactions, showaction );
      for mode in modes do
        if mode.name in [ "select_entry", "select_row_and_entry",
                          "select_column_and_entry" ] then
          BrowseData.SetActions( mode, newactions );
        fi;
      od;
    else
      modes:= BrowseData.defaults.work.customizedModes.brmindeg;
    fi;

    # Construct the browse table.
    table:= rec(
      work:= rec(
        availableModes:= modes,
        align:= "ct",
        header:= t -> BrowseData.HeaderWithRowCounter( t,
                          "Minimal Degrees of Representations",
                          Length( mat ) ),
        footer:= rec(
          # Show the sources of the data.
          select_entry:= function( t )
            local entry, e, pos;

            entry:= "";
            if   t.dynamic.selectedEntry <> [ 0, 0 ] then
              e:= src[ t.dynamic.indexRow[ t.dynamic.selectedEntry[1] ] / 2 ];
              pos:= t.dynamic.indexCol[ t.dynamic.selectedEntry[2] ] / 2;
              if IsBound( e[ pos ] ) and not IsEmpty( e[ pos ] ) then
                entry:= Concatenation( "source: ",
                            JoinStringsWithSeparator( e[ pos ], ", " ) );
              fi;
            fi;
            return [ entry ];
          end ),
        footerLength:= rec(
          select_entry:= 1 ),
        CategoryValues:= function( t, i, j )
          local val;

          val:= t.work.main[ i/2 ][ j/2 ];
          if   NCurses.IsAttributeLine( val ) then
            val:= NCurses.SimpleString( val );
          else
            val:= Concatenation( List( val.rows, NCurses.SimpleString ) );
          fi;
          if   2 * Length( char ) < j then
            return [ Concatenation( "min. perm. degree = ", val ) ];
          else
            return [ Concatenation( "char. ", String( char[ j/2 ] ), ": ",
                         val ) ];
          fi;
        end,

        main:= mat,
        labelsRow:= List( labelsrow,
                          x -> [ rec( rows:= [ x ], align:= "l" ) ] ),
        labelsCol:= [ Concatenation( List( char,
                          x -> rec( rows:= [ String( x ) ], align:= "r" ) ),
                        [ "perm. degree" ] ) ],
        sepLabelsRow:= "|",
        sepLabelsCol:= "|",
        sepRow:= "-",
        sepCol:= Concatenation( [ "| " ],
                     List( [ 1 .. Length( char ) ], x -> " | " ), [ " |" ] ),

        SpecialGrid:= BrowseData.SpecialGridLineDraw,
        Click:= rec(
          select_entry:= rec(
            helplines:= [ "add the representation to the result list" ],
            action:= function( t )
              local i, j, entry;

              if t.dynamic.selectedEntry <> [ 0, 0 ] then
                i:= t.dynamic.indexRow[ t.dynamic.selectedEntry[1] ] / 2;
                j:= t.dynamic.indexCol[ t.dynamic.selectedEntry[2] ] / 2;
                if IsBound( mat[i][j] ) then
                  entry:= mat[i][j];
                  if IsRecord( entry ) then
                    entry:= First( entry.rows[1], IsString );
                  fi;
                  if j <= Length( char ) then
                    info:= OneAtlasGeneratingSetInfo( labelsrow[i],
                              Characteristic, char[j],
                              Dimension, Int( entry ) );
                  else
                    info:= OneAtlasGeneratingSetInfo( labelsrow[i],
                              NrMovedPoints, Int( entry ) );
                  fi;
                  if not info in t.dynamic.Return then
                    Add( t.dynamic.Return, info );
                  fi;
                fi;
              fi;
            end ),
        ),
      ),
      dynamic:= rec(
        sortFunctionsForColumns:= List( [ 0 .. Length( char ) ],
            x -> BrowseData.CompareLenLex ),
        Return:= [],
        activeModes:= [ First( modes, x -> x.name = "browse" ) ],
      ),
    );

    # Show the browse table.
    result:= NCurses.BrowseGeneric( table );

    # Construct the return value.
    return result;
    end );


#############################################################################
##
##  Add the Browse application to the list shown by `BrowseGapData'.
##
BrowseGapDataAdd( "Minimal Degrees of Representations",
    BrowseMinimalDegrees, true, "\
the list of known minimal degrees for the groups of the \
Atlas of Group Representations, \
shown in a browse table with one column for each characteristic \
plus a column for the minimal permutation degree; \
available representations are shown in boldface blue, \
clicking on the table cell of such a representation adds the \
info record for it to the result list; \
the inputs vb, vh, vt open a pager showing the bibliographic sources \
of the selected entry if available; \
try ?BrowseMinimalDegrees for details" );


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