Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
| Download
GAP 4.8.9 installation with standard packages -- copy to your CoCalc project to get it
Project: cocalc-sagemath-dev-slelievre
Views: 418346############################################################################# ## #W atlasbrowse.g GAP 4 package `browse' Thomas Breuer ## #Y Copyright (C) 2006, Lehrstuhl D für Mathematik, RWTH Aachen, Germany ## ############################################################################# ## #V BrowseData.AtlasInfoActionShowOverview ## ## is used in the tables constructed by `BrowseData.AtlasInfoGroupTable' and ## `BrowseData.AtlasInfoOverview'. ## BrowseData.AtlasInfoActionShowOverview:= [ [ [ "Y" ], rec( helplines := [ "show an overview of selected entries" ], action := function( t ) local str, grps, grp, line; str:= ""; grps:= Set( List( t.dynamic.viewReturn, x -> x[1] ) ); for grp in grps do Append( str, "G = " ); Append( str, grp ); Append( str, ":\n" ); for line in Filtered( t.dynamic.viewReturn, x -> x[1] = grp ) do Append( str, " " ); Append( str, line[2] ); Append( str, "\n" ); od; Append( str, "\n" ); od; if IsEmpty( str ) then str:= "(nothing was chosen yet)"; fi; if BrowseData.IsDoneReplay( t.dynamic.replay ) then NCurses.Pager( str ); NCurses.update_panels(); NCurses.doupdate(); NCurses.curs_set( 0 ); fi; return t.dynamic.changed; end ) ], ]; ############################################################################# ## #F BrowseData.AtlasInfoGroupTable( <conditions>, <log>, <replay>, <t> ) ## ## This function is called by `BrowseData.AtlasInfoOverview' when a row in ## the overview table is clicked. ## It returns a browse table with the details for the chosen group, ## which is shown via a second level `Browse' call. ## BrowseData.AtlasInfoGroupTable:= function( conditions, log, replay, t ) local gapname, cats, labelsRow, info, inforeps, name, infoprgs, prgslist, i, entry, sel_action, header, footer, showTables, modes, mode, table; gapname:= AGR.GAPName( conditions[1] ); cats:= []; labelsRow:= []; info:= []; # Construct the information about representations for `gapname'. inforeps:= AGR.InfoReps( conditions ); if 0 < Length( inforeps.list ) then Add( cats, rec( pos:= 2, level:= 1, value:= Concatenation( inforeps.header ), separator:= "", isUnderCollapsedCategory:= false, isRejectedCategory:= false ) ); Append( labelsRow, List( inforeps.list, x -> [ Concatenation( x[1] ) ] ) ); Append( info, List( inforeps.list, x -> [ rec( rows:= [ BrowseData.SimplifiedString( Concatenation( x[2] ) ) ], align:= "l" ), rec( rows:= [ BrowseData.SimplifiedString( Concatenation( x[3] ) ) ], align:= "l" ) ] ) ); fi; # Construct the information about scripts for `gapname'. infoprgs:= AGR.InfoPrgs( conditions ); if ForAny( infoprgs.list, x -> not IsEmpty( x ) ) then Add( cats, rec( pos:= 2 * Length( info ) + 2, level:= 1, value:= Concatenation( infoprgs.header ), separator:= "", isUnderCollapsedCategory:= false, isRejectedCategory:= false ) ); prgslist:= []; for i in [ 1 .. Length( infoprgs.list ) ] do entry:= infoprgs.list[i]; if not IsEmpty( entry ) then if IsString( entry[2] ) then Add( info, List( entry{ [ 1, 2 ] }, x -> rec( rows:= [ x ], align:= "l" ) ) ); Add( labelsRow, [ "" ] ); Add( prgslist, [ i, entry ] ); else Add( cats, rec( pos:= 2 * Length( info ) + 2, level:= 2, value:= entry[1], separator:= "", isUnderCollapsedCategory:= false, isRejectedCategory:= false ) ); Append( info, List( entry{ [ 2 .. Length( entry ) ] }, x -> List( x{ [ 1, 2 ] }, y -> rec( rows:= [ y ], align:= "l" ) ) ) ); Append( labelsRow, List( [ 2 .. Length( entry ) ], x -> [ "" ] ) ); Append( prgslist, List( entry{ [ 2 .. Length( entry ) ] }, x -> [ i, x ] ) ); fi; fi; od; fi; # Provide functionality for the `Click' function, the header, the footer, # and a modified `showTables' function. sel_action:= rec( helplines:= [ "add the selected entry to the result" ], action:= function( t ) local info, pos, line, i, data, choice; if t.dynamic.selectedEntry <> [ 0, 0 ] then # Set the return value and close the window. pos:= t.dynamic.indexRow[ t.dynamic.selectedEntry[1] ] / 2; if pos <= Length( inforeps.list ) then info:= inforeps.list[ pos ]; pos:= t.work.labelsRow[ pos ][1]; pos:= pos{ [ 1 .. Length( pos ) - 1 ] }; line:= Concatenation( info[2] ); if not IsEmpty( info[3] ) then Append( line, " (" ); Append( line, Concatenation( info[3] ) ); Append( line, ")" ); fi; choice:= [ gapname, Int( pos ) ]; else pos:= pos - Length( inforeps.list ); i:= prgslist[ pos ][1]; data:= prgslist[ pos ][2]; choice:= data[3]; if ForAll( infoprgs.list[i], IsString ) then line:= JoinStringsWithSeparator( Filtered( data{ [ 1, 2 ] }, x -> x <> "" ), " " ); elif infoprgs.nams[i] = "maxes" then line:= NormalizedWhitespace( Concatenation( "max. no. ", data[1] ) ); else line:= data[1]; fi; fi; if choice in t.dynamic.Return then t.dynamic.currentFooterRow:= Concatenation( line, " was already chosen" ); else Add( t.dynamic.Return, choice ); Add( t.dynamic.viewReturn, [ gapname, line ] ); t.dynamic.currentFooterRow:= Concatenation( line, " added to the result" ); fi; fi; end ); header:= Concatenation( "AtlasRep info for ", gapname ); if 1 < Length( conditions ) then Append( header, " (selected entries)" ); fi; footer:= t -> [ [ NCurses.attrs.UNDERLINE, true, RepeatedString( " ", BrowseData.HeightWidthWindow( t )[2] ) ], t.dynamic.currentFooterRow ]; showTables:= function( t ) BrowseData.ShowTables( t ); t.dynamic.currentFooterRow:= ""; end; # Construct the modified modes if necessary. if not IsBound( BrowseData.defaults.work.customizedModes.atlasbrowse2 ) then # Create a shallow copy of each default mode for `Browse', # modify the `showTables' function, # and add a new action to all available modes (except the help mode): # - Y: Show a pager with the entries that have been selected. modes:= List( BrowseData.defaults.work.availableModes, BrowseData.ShallowCopyMode ); for mode in modes do if mode.name in [ "select_entry", "select_row", "select_row_and_entry", "select_column_and_entry" ] then mode.ShowTables:= showTables; fi; if mode.name <> "help" then BrowseData.SetActions( mode, BrowseData.AtlasInfoActionShowOverview ); fi; od; BrowseData.defaults.work.customizedModes.atlasbrowse2:= modes; else modes:= BrowseData.defaults.work.customizedModes.atlasbrowse2; fi; # Construct the browse table. table:= rec( work:= rec( align:= "tl", header:= [ "", [ NCurses.attrs.UNDERLINE, true, header ], "" ], footer:= rec( select_entry:= footer, select_row:= footer, select_row_and_entry:= footer, select_column_and_entry:= footer, ), availableModes:= modes, main:= info, labelsRow:= labelsRow, sepLabelsRow:= [ " ", "" ], sepCol:= [ " ", " ", "" ], Click:= rec( select_entry:= sel_action, select_row:= sel_action, select_row_and_entry:= sel_action, select_column_and_entry:= sel_action, ), ), dynamic:= rec( categories:= [ List( cats, x -> x.pos ), cats, [ 1 ] ], initialSteps:= [ 115, 114 ], Return:= [], currentFooterRow:= "", viewReturn:= [], ), ); if log <> fail then table.dynamic.log:= log; table.dynamic.replay:= replay; fi; if t <> fail then table.dynamic.Return:= t.dynamic.Return; table.dynamic.viewReturn:= t.dynamic.viewReturn; fi; return table; end; ############################################################################# ## #F BrowseData.AtlasInfoOverview( <gapnames>, <conditions>, <log>, <replay> ) ## ## Part of the code is analogous to `AGR.StringAtlasInfoOverview'. ## BrowseData.AtlasInfoOverview:= function( gapnames, conditions, log, replay ) local tocs, rep_rest_funs, only_if_rep, columns, len, type, choice, i, sel_action, header, modes, mode, table; tocs:= AGR.TablesOfContents( conditions ); # Consider only those names for which actually information is available. # (The ordering shall be the same as in the input.) if gapnames = "all" then gapnames:= AtlasOfGroupRepresentationsInfo.GAPnamesSortDisp; else gapnames:= Filtered( List( gapnames, AGR.InfoForName ), x -> x <> fail ); fi; gapnames:= Filtered( gapnames, x -> ForAny( tocs, toc -> IsBound( toc.( x[2] ) ) ) ); if IsEmpty( gapnames ) then return []; fi; # If 'conditions' restricts the representations then omit rows # with empty representations part. rep_rest_funs:= [ Characteristic, Dimension, Identifier, IsMatrixGroup, IsPermGroup, IsPrimitive, IsTransitive, NrMovedPoints, RankAction, Ring, Transitivity ]; only_if_rep:= ForAny( conditions, x -> x in rep_rest_funs ); # Compute the data of the columns. columns:= [ [ "G", "l", List( gapnames, x -> [ x[1], false ] ) ] ]; for type in AGR.DataTypes( "rep", "prg" ) do if type[2].DisplayOverviewInfo <> fail then Add( columns, [ type[2].DisplayOverviewInfo[1], type[2].DisplayOverviewInfo[2], List( gapnames, n -> type[2].DisplayOverviewInfo[3]( Concatenation( [ n ], conditions ) ) ) ] ); if only_if_rep then if type[3] = "rep" then len:= Length( columns ); fi; else len:= Length( columns ); fi; fi; od; # Restrict the lists to the nonempty rows. choice:= []; for i in [ 1 .. Length( gapnames ) ] do if ForAny( [ 2 .. len ], c -> columns[c][3][i][1] <> "" ) then Add( choice, i ); # Evaluate the privacy flag. if ForAny( columns, x -> x[3][i][2] ) then columns[1][3][i][1]:= Concatenation( columns[1][3][i][1], AtlasOfGroupRepresentationsInfo.markprivate ); fi; fi; od; if IsEmpty( choice ) then return []; fi; sel_action:= function( t ) local name, tt; if t.dynamic.selectedEntry <> [ 0, 0 ] then name:= gapnames[ choice[ t.dynamic.indexRow[ t.dynamic.selectedEntry[1] ] / 2 ] ][1]; tt:= BrowseData.AtlasInfoGroupTable( Concatenation( [ name ], conditions ), t.dynamic.log, t.dynamic.replay, t ); if IsEmpty( tt.work.main ) then BrowseData.AlertWithReplay( t, Concatenation( "There are no data for the group", name, "." ), NCurses.attrs.BOLD ); else NCurses.BrowseGeneric( tt ); if tt.dynamic.interrupt then BrowseData.actions.QuitTable.action( t ); else t.dynamic.Return:= tt.dynamic.Return; t.dynamic.viewReturn:= tt.dynamic.viewReturn; fi; fi; fi; end; header:= "Atlas Of Group Representations: Overview"; if gapnames <> "all" or not IsEmpty( conditions ) then Append( header, " (selected entries)" ); fi; # Construct the modified modes if necessary. if not IsBound( BrowseData.defaults.work.customizedModes.atlasbrowse1 ) then # Create a shallow copy of each default mode for `Browse' # and add a new action to all available modes (except the help mode): # - Y: Show a pager with the entries that have been selected. modes:= List( BrowseData.defaults.work.availableModes, BrowseData.ShallowCopyMode ); for mode in modes do if mode.name <> "help" then BrowseData.SetActions( mode, BrowseData.AtlasInfoActionShowOverview ); fi; od; BrowseData.defaults.work.customizedModes.atlasbrowse1:= modes; else modes:= BrowseData.defaults.work.customizedModes.atlasbrowse1; fi; # Construct and show the browse table. table:= rec( work:= rec( align:= "tl", header:= t -> BrowseData.HeaderWithRowCounter( t, header, Length( gapnames ) ), availableModes:= modes, main:= List( choice, i -> List( columns, col -> rec( rows:= [ col[3][i][1] ], align:= col[2] ) ) ), labelsCol:= [ List( columns, col -> rec( rows:= [ col[1] ], align:= col[2] ) ) ], sepLabelsCol:= [ "-" ], sepCol:= Concatenation( [ "| " ], List( [ 1 .. Length( columns ) - 1 ], i -> " | " ), [ " |" ] ), SpecialGrid:= BrowseData.SpecialGridLineDraw, Click:= rec( select_entry:= rec( helplines:= [ "open an overview for the selected entry" ], action:= sel_action ), select_row:= rec( helplines:= [ "open an overview for the selected row" ], action:= sel_action ), select_row_and_entry:= rec( helplines:= [ "open an overview for the selected entry" ], action:= sel_action ), select_column_and_entry:= rec( helplines:= [ "open an overview for the selected entry" ], action:= sel_action ), ), ), dynamic:= rec( Return:= [], viewReturn:= [], ), ); if log <> fail then table.dynamic.log:= log; table.dynamic.replay:= replay; fi; return NCurses.BrowseGeneric( table ); end; ############################################################################# ## #F BrowseData.AtlasInfoGroup( <conditions>, <log>, <replay>, <t> ) ## BrowseData.AtlasInfoGroup:= function( conditions, log, replay, t ) local table; table:= BrowseData.AtlasInfoGroupTable( conditions, log, replay, t ); if IsEmpty( table.work.main ) then BrowseData.AlertWithReplay( table, Concatenation( "There are no data for the group ", conditions[1], "." ), NCurses.attrs.BOLD ); return []; fi; return NCurses.BrowseGeneric( table ); end; ############################################################################# ## #F BrowseAtlasInfo( [...] ) ## ## <#GAPDoc Label="AtlasRep_section"> ## <Section Label="sec:atlasdisp"> ## <Heading>Table of Contents of <Package>AtlasRep</Package></Heading> ## ## The &GAP; package <Package>AtlasRep</Package> ## (see <Cite Key="AtlasRep"/>) is an interface to a database ## of representations and related data. ## The table of contents of this database can be displayed via the function ## <Ref Func="DisplayAtlasInfo" BookName="atlasrep"/> of this package. ## The &Browse; package provides an alternative based on the function ## <Ref Func="NCurses.BrowseGeneric"/>; ## one can scroll, search, and fetch data for later use. ## ## <ManSection> ## <Heading>BrowseAtlasInfo</Heading> ## <Func Name="BrowseAtlasInfo" ## Arg='[listofnames, ]["contents", sources][, ...]' ## Label="overview of groups"/> ## <Func Name="BrowseAtlasInfo" Arg="gapname[, std][, ...]" ## Label="overview for one group"/> ## ## <Returns> ## the list of <Q>clicked</Q> info records. ## </Returns> ## ## <Description> ## This function shows the information available via the &GAP; package ## <Package>AtlasRep</Package> in a browse table, ## cf. Section <Ref Sect="Accessing Data of the AtlasRep Package" ## BookName="atlasrep"/> in the <Package>AtlasRep</Package> manual. ## <P/> ## The optional arguments can be used to restrict the table to public or ## private data, or to show an overview for one particular group. ## The arguments are the same as for ## <Ref Func="DisplayAtlasInfo" BookName="AtlasRep"/>, ## see the documentation of this function for details. ## (Note that additional conditions such as ## <Ref Func="IsPermGroup" BookName="ref"/> can be entered also in the case ## that no <A>gapname</A> is given. ## In this situation, the additional conditions are evaluated for the ## <Q>second level tables</Q> that are opened by <Q>clicking</Q> on a ## table row or entry.) ## <P/> ## When one <Q>clicks</Q> on one of the table rows or entries then a ## browse table with an overview of the information available for this ## group is shown, and <Q>clicking</Q> on one of the rows in these tables ## adds the corresponding info record ## (see <Ref Func="OneAtlasGeneratingSetInfo" BookName="AtlasRep"/>) ## to the list of return values of ## <Ref Func="BrowseAtlasInfo" Label="overview of groups"/>. ## <P/> ## The full functionality of the function ## <Ref Func="NCurses.BrowseGeneric"/> is available. ## <P/> ## The following example shows how ## <Ref Func="BrowseAtlasInfo" Label="overview of groups"/> can be ## used to fetch info records about permutation representations of the ## alternating groups <M>A_5</M> and <M>A_6</M>: ## We search for the group name <C>"A5"</C> in the overview table, and the ## first cell in the table row for <M>A_5</M> becomes selected; ## hitting the <B>Enter</B> key causes a new window to be opened, with an ## overview of the data available for <M>A_5</M>; ## moving down two rows and hitting the <B>Enter</B> key again causes the ## second representation to be added to the result list; ## hitting <B>Q</B> closes the second window, and we are back in the ## overview table; ## we move the selection down twice (to the row for the group <M>A_6</M>), ## and choose the first representation for this group; ## finally we leave the table, and the return value is the list with the ## data for the two representations. ## <P/> ## <Example><![CDATA[ ## gap> d:= [ NCurses.keys.DOWN ];; r:= [ NCurses.keys.RIGHT ];; ## gap> c:= [ NCurses.keys.ENTER ];; ## gap> BrowseData.SetReplay( Concatenation( ## > "/A5", # Find the string A5 ... ## > d, d, r, # ... such that just the word matches, ## > c, # start the search, ## > c, # click the table entry A5, ## > d, d, # move down two rows, ## > c, # click the row for this representation, ## > "Q", # quit the second level table, ## > d, d, # move down two rows, ## > c, # click the table entry A6, ## > d, # move down one row, ## > c, # click the first row, ## > "Q", # quit the second level table, ## > "Q" ) ); # and quit the application. ## gap> if IsBound( BrowseAtlasInfo ) and IsBound( AtlasProgramInfo ) then ## > tworeps:= BrowseAtlasInfo(); ## > else ## > tworeps:= [ fail ]; ## > fi; ## gap> BrowseData.SetReplay( false ); ## gap> if fail in tworeps then ## > Print( "no access to the Web ATLAS\n" ); ## > else ## > Print( List( tworeps, x -> x.identifier[1] ), "\n" ); ## [ "A5", "A6" ] ## > fi; ## ]]></Example> ## <P/> ## <E>Implementation remarks</E>: ## The first browse table shown has a static header, ## no footer and row labels, ## one row of column labels describing the type of data summarized in the ## columns. ## <P/> ## Row and column separators are drawn as grids ## (cf. <Ref Func="NCurses.Grid"/>) composed from the special characters ## described in Section <Ref Subsect="ssec:ncursesLines"/>, ## using the component <C>work.SpecialGrid</C> of the browse table, ## see <Ref Var="BrowseData"/>. ## <P/> ## When a row is selected, the <Q>click</Q> functionality opens a new window ## (via a second level call to <Ref Func="NCurses.BrowseGeneric"/>), ## in which a browse table with the list of available data for ## the given group is shown; ## in this table, <Q>click</Q> results in adding the info for the selected ## row to the result list, and a message about this addition is shown in the ## footer row. ## One can choose further data, return to the first browse table, ## and perhaps iterate the process for other groups. ## When the first level table is left, the list of info records for the ## chosen data is returned. ## <P/> ## For the two kinds of browse tables, ## the standard modes in <Ref Var="BrowseData"/> (except the <C>help</C> ## mode) have been extended by a new action that opens a pager giving an ## overview of all data that have been chosen in the current call. ## The corresponding user input is the <B>Y</B> key. ## <P/> ## This function is available only if the &GAP; package ## <Package>AtlasRep</Package> is available. ## <P/> ## The code can be found in the file <F>app/atlasbrowse.g</F> of the package. ## </Description> ## </ManSection> ## </Section> ## <#/GAPDoc> ## BindGlobal( "BrowseAtlasInfo", function( arg ) local log, replay, result, i, pos, pos2; # A record at the first position may prescribe the replay with history. log:= fail; replay:= fail; if Length( arg ) <> 0 and IsRecord( arg[1] ) and IsBound( arg[1].log ) and IsBound( arg[1].replay ) then log:= arg[1].log; replay:= arg[1].replay; arg:= arg{ [ 2 .. Length( arg ) ] }; fi; # Distinguish the summary overview for at least one group # from the detailed overview for exactly one group. if Length( arg ) = 0 then result:= BrowseData.AtlasInfoOverview( "all", arg, log, replay ); elif IsList( arg[1] ) and ForAll( arg[1], IsString ) then result:= BrowseData.AtlasInfoOverview( arg[1], arg{ [ 2 .. Length( arg ) ] }, log, replay ); elif not IsString( arg[1] ) or arg[1] = "contents" then result:= BrowseData.AtlasInfoOverview( "all", arg, log, replay ); else result:= BrowseData.AtlasInfoGroup( arg, log, replay, fail ); fi; # Evaluate the return value. for i in [ 1 .. Length( result ) ] do if IsInt( result[i][2] ) then # a representation, identified by its number result[i]:= OneAtlasGeneratingSetInfo( result[i][1], Position, result[i][2] ); else # a program, identified by its identifier list result[i]:= AtlasProgramInfo( result[i] ); fi; od; return result; end ); ############################################################################# ## ## Add the Browse application to the list shown by `BrowseGapData'. ## BrowseGapDataAdd( "AtlasRep Overview", BrowseAtlasInfo, true, "\ an overview of the information provided by the \ Atlas of Group Representations, \ the return value is the list of records \ encoding the clicked entries" ); ############################################################################# ## #E