CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In

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

Path: gap4r8 / pkg / Browse / doc / chap6.txt
Views: 418346
1
2
6 Examples of Applications based on NCurses.BrowseGeneric
3
4
This chapter introduces the operation Browse (6.1-1) and lists several
5
examples how the function NCurses.BrowseGeneric (4.3-1) can be utilized for
6
rendering GAP related data or for playing games. Each section describes the
7
relevant GAP functions and briefly sketches the technical aspects of the
8
implementation; more details can be found in the GAP files, in the app
9
directory of the package.
10
11
Only Section 6.4 describes a standard application in the sense of the
12
introduction to Chapter 4, perhaps except for a special function that is
13
needed to compare table entries. The other examples in this chapter require
14
some of the programming described in Chapter 5.
15
16
The GAP examples in this chapter use the replay feature of
17
NCurses.BrowseGeneric (4.3-1), see Section 4.1. This means that the
18
NCurses.BrowseGeneric (4.3-1) based function is called between two calls of
19
BrowseData.SetReplay (5.4-2). If you want to paste these examples into the
20
GAP session with the mouse then do not paste the final BrowseData.SetReplay
21
(5.4-2) call, since NCurses.BrowseGeneric (4.3-1) would regard the
22
additional input as a user interrupt.
23
24
25
6.1 The Operation Browse
26
27
6.1-1 Browse
28
29
Browse( obj[, arec] )  operation
30
31
This operation displays the GAP object obj in a nice, formatted way, similar
32
to the operation Display (Reference: Display). The difference is that Browse
33
is intended to use ncurses facilities.
34
35
Currently there are methods for matrices (see Browse (6.2-2)), for character
36
tables (see Browse (6.3-1)) and for tables of marks (see Browse (6.4-1)).
37
38
39
6.2 Matrix Display
40
41
The GAP library provides several Display (Reference: Display) methods for
42
matrices. In order to cover the functionality of these methods, Browse
43
provides the function NCurses.BrowseDenseList (6.2-1) that uses the standard
44
facilities of the function NCurses.BrowseGeneric (4.3-1), i. e., one can
45
scroll in the matrix, searching and sorting are provided etc.
46
47
The idea is to customize this function for different special cases, and to
48
install corresponding Browse (6.1-1) methods. Examples are methods for
49
matrices over finite fields and residue class rings of the rational
50
integers, see Browse (6.2-2).
51
52
The code can be found in the file app/matdisp.g of the package.
53
54
6.2-1 NCurses.BrowseDenseList
55
56
NCurses.BrowseDenseList( list, arec )  function
57
Returns: nothing.
58
59
Let list be a dense list whose entries are lists, for example a matrix, and
60
let arec be a record. This function displays list in a window, as a
61
two-dimensional array with row and column positions as row and column
62
labels, respectively.
63
64
The following components of arec are supported.
65
66
header
67
If bound, the value must be a valid value of the work.header component
68
of a browse table, see BrowseData.IsBrowseTable (4.2-3); for example,
69
the value can be a list of strings. If this component is not bound
70
then the browse table has no header.
71
72
convertEntry
73
If bound, the value must be a unary function that returns a string
74
describing its argument. The default is the operation String
75
(Reference: String). Another possible value is
76
NCurses.ReplaceZeroByDot, which returns the string "." if the argument
77
is a zero element in the sense of IsZero (Reference: IsZero), and
78
returns the String (Reference: String) value otherwise. For each entry
79
in a row of list, the convertEntry value is shown in the browse table.
80
81
labelsRow
82
If bound, the value must be a list of row label rows for list, as
83
described in Section BrowseData.IsBrowseTable (4.2-3). The default is
84
[ [ "1" ], [ "2" ], ... ].
85
86
labelsCol
87
If bound, the value must be a list of column label rows for list, as
88
described in Section BrowseData.IsBrowseTable (4.2-3). The default is
89
[ [ "1", "2", ... ] ].
90
91
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is
92
available.
93
94
6.2-2 Browse
95
96
Browse( list )  method
97
Returns: nothing.
98
99
Several methods for the operation Browse (6.1-1) are installed for the case
100
that the argument is a list of lists. These methods cover a default method
101
for lists of lists and the Display (Reference: Display) methods for matrices
102
over finite fields and residue class rings of the rational integers. Note
103
that matrices over finite prime fields, small extension fields, and large
104
extension fields are displayed differently, and the same holds for the
105
corresponding Browse (6.1-1) methods.
106
107
 Example 
108
gap> n:= [ 14, 14, 14, 14 ];;
109
gap> input:= Concatenation( n, n, n, "Q" );; # ``do nothing and quit''
110
gap> BrowseData.SetReplay( input );
111
gap> Browse( RandomMat( 10, 10, Integers ) );
112
gap> BrowseData.SetReplay( input );
113
gap> Browse( RandomMat( 10, 10, GF(3) ) );
114
gap> BrowseData.SetReplay( input );
115
gap> Browse( RandomMat( 10, 10, GF(4) ) );
116
gap> BrowseData.SetReplay( input );
117
gap> Browse( RandomMat( 10, 10, Integers mod 6 ) );
118
gap> BrowseData.SetReplay( input );
119
gap> Browse( RandomMat( 10, 10, GF( NextPrimeInt( 2^16 ) ) ) );
120
gap> BrowseData.SetReplay( input );
121
gap> Browse( RandomMat( 10, 10, GF( 2^20 ) ) );
122
gap> BrowseData.SetReplay( false );
123

124
125
126
6.3 Character Table Display
127
128
The GAP library provides a Display (Reference: Display) method for character
129
tables that breaks the table into columns fitting on the screen. Browse
130
provides an alternative, using the standard facilities of the function
131
NCurses.BrowseGeneric (4.3-1), i. e., one can scroll in the matrix of
132
character values, searching and sorting are provided etc.
133
134
The Browse (6.1-1) method for character tables can be called instead of
135
Display (Reference: Display). For convenience, one can additionally make
136
this function the default Display (Reference: Display) method for character
137
tables, by assigning it to the Display component in the global record
138
CharacterTableDisplayDefaults.User, see 'Reference: Printing Character
139
Tables'; for example, one can do this in one's gaprc file, see 'Reference:
140
The gap.ini and gaprc files'. (This can be undone by unbinding the component
141
CharacterTableDisplayDefaults.User.Display.)
142
143
The function BrowseDecompositionMatrix (6.3-2) can be used to display
144
decomposition matrices for Brauer character tables.
145
146
6.3-1 Browse
147
148
Browse( tbl[, options] )  method
149
150
This method displays the character table tbl in a window. The optional
151
record options describes what shall be displayed, the supported components
152
and the default values are described in 'Reference: Printing Character
153
Tables'.
154
155
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is
156
available.
157
158
 Example 
159
gap> if TestPackageAvailability( "CTblLib" ) = true then
160
>  BrowseData.SetReplay( Concatenation(
161
>  # scroll in the table
162
>  "DRULdddddrrrrrlluu",
163
>  # select an entry and move it around
164
>  "seddrruuuddlll",
165
>  # search for the pattern 135 (six times)
166
>  "/135", [ NCurses.keys.ENTER ], "nnnnn",
167
>  # deselect the entry, select the first column
168
>  "qLsc",
169
>  # sort and categorize by this column
170
>  "sc",
171
>  # select the first row, move down the selection
172
>  "srdddd",
173
>  # expand the selected category, scroll the selection down
174
>  "xd",
175
>  # and quit the application
176
>  "Q" ) );
177
>  Browse( CharacterTable( "HN" ) );
178
>  BrowseData.SetReplay( false );
179
> fi;
180

181
182
Implementation remarks: The first part of the code in the Browse (6.1-1)
183
method for character tables is almost identical with the code for extracting
184
the data to be displayed from the input data in the GAP library function
185
CharacterTableDisplayDefault. The second part of the code transforms these
186
data into a browse table. Character names and (if applicable) indicator
187
values are used as row labels, and centralizer orders, power maps, and class
188
names are used as column labels. The identifier of the table is used as the
189
static header. When an irrational entry is selected, a description of this
190
entry is shown in the dynamic footer.
191
192
The standard modes in BrowseData (5.4-1) (except the help mode) have been
193
extended by three new actions. The first two of them open pagers giving an
194
overview of all irrationalities in the table, or of all those
195
irrationalities that have been shown on the screen in the current call,
196
respectively. The corresponding user inputs are the I and the i key. (The
197
names assigned to the irrationalities are generated column-wise. If one just
198
scrolls through the table, without jumping, then these names coincide with
199
the names generated by the default Display (Reference: Display) method for
200
character tables; this is in general not the case, for example when a
201
row-wise search in the table is performed.) The third new action, which is
202
associated with the p key, toggles the visibility status of the column label
203
rows for centralizer orders and power maps.
204
205
An individual minyx function does not only check whether the desired table
206
fits into the window but also whether a table with too high column labels
207
(centralizer orders and power maps) would fit if these labels get collapsed
208
via the p key. In this case, the labels are automatically collapsed, and the
209
p key is disabled.
210
211
In order to keep the required space small also for large character tables,
212
caching of formatted matrix entries is disabled, and the strings to be
213
displayed are computed on demand with a Main function in the work component
214
of the browse table. For the same reason, the constant height one for all
215
table rows is set in advance, so one need not inspect a whole character if
216
only a few values of it shall be shown.
217
218
Special functions are provided for sorting (concerning the comparison of
219
character values, which can be integers or irrationalities) and categorizing
220
the table by a column (the value in the category row involves the class name
221
of the column in question).
222
223
The code can be found in the file app/ctbldisp.g of the package.
224
225
6.3-2 BrowseDecompositionMatrix
226
227
BrowseDecompositionMatrix( modtbl[, b][, options] )  function
228
229
This method displays the decomposition matrix of (the b-th block of) the
230
Brauer character table modtbl in a window. The arguments are the same as for
231
LaTeXStringDecompositionMatrix (Reference: LaTeXStringDecompositionMatrix).
232
233
The positions of the ordinary and modular irreducible characters are shown
234
in the labels of the rows and columns, respectively, that are indexed by
235
these characters. When an entry in the decomposition matrix is selected then
236
information about the degrees of these characters is shown in the table
237
footer.
238
239
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is
240
available.
241
242
 Example 
243
gap> BrowseData.SetReplay( Concatenation(
244
>  # select the first entry
245
>  "se",
246
>  # scroll in the table
247
>  "drrrr",
248
>  # keep the table open for a while
249
>  [ 14, 14, 14, 14, 14 ],
250
>  # and quit the application
251
>  "Q" ) );
252
gap> BrowseDecompositionMatrix( CharacterTable( "J1" ) mod 2 );
253
gap> BrowseData.SetReplay( false );
254

255
256
The code can be found in the file app/ctbldisp.g of the package.
257
258
259
6.4 Table of Marks Display
260
261
The GAP library provides a Display (Reference: Display) method for tables of
262
marks that breaks the table into columns fitting on the screen. Similar to
263
the situation with character tables, see Section 6.3, but with a much
264
simpler implementation, Browse provides an alternative based on the function
265
NCurses.BrowseGeneric (4.3-1).
266
267
Browse (6.1-1) can be called instead of Display (Reference: Display) for
268
tables of marks, cf. 'Reference: Printing Tables of Marks'.
269
270
6.4-1 Browse
271
272
Browse( tom[, options] )  method
273
274
This method displays the table of marks tom in a window. The optional record
275
options describes what shall be displayed, the supported components and the
276
default values are described in 'Reference: Printing Tables of Marks'.
277
278
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is
279
available.
280
281
 Example 
282
gap> if TestPackageAvailability( "TomLib" ) = true then
283
>  BrowseData.SetReplay( Concatenation(
284
>  # scroll in the table
285
>  "DDRRR",
286
>  # search for the (exact) value 100 (three times)
287
>  "/100",
288
>  [ NCurses.keys.DOWN, NCurses.keys.DOWN, NCurses.keys.RIGHT ],
289
>  [ NCurses.keys.DOWN, NCurses.keys.DOWN, NCurses.keys.DOWN ],
290
>  [ NCurses.keys.RIGHT, NCurses.keys.ENTER ], "nn",
291
>  # no more occurrences of 100, confirm
292
>  [ NCurses.keys.ENTER ],
293
>  # and quit the application
294
>  "Q" ) );
295
>  Browse( TableOfMarks( "A10" ) );
296
>  BrowseData.SetReplay( false );
297
>  fi;
298

299
300
Implementation remarks: Rows and columns are indexed by their positions. The
301
identifier of the table is used as the static header, there is no footer.
302
303
In order to keep the required space small also for large tables of marks,
304
caching of formatted matrix entries is disabled, and the strings to be
305
displayed are computed on demand with a Main function in the work component
306
of the browse table. For the same reason, the constant height one for the
307
table rows is set in advance. (For example, the table of marks of the group
308
with identifier "O8+(2)", with 11171 rows and columns, can be shown with
309
Browse (6.1-1) in a GAP session requiring about 100 MB.)
310
311
The code can be found in the file app/tomdisp.g of the package.
312
313
314
6.5 Table of Contents of AtlasRep
315
316
The GAP package AtlasRep (see [WPN+07]) is an interface to a database of
317
representations and related data. The table of contents of this database can
318
be displayed via the function DisplayAtlasInfo (AtlasRep: DisplayAtlasInfo)
319
of this package. The Browse package provides an alternative based on the
320
function NCurses.BrowseGeneric (4.3-1); one can scroll, search, and fetch
321
data for later use.
322
323
324
6.5-1 BrowseAtlasInfo
325
326
BrowseAtlasInfo( [listofnames, ]["contents", sources, ][...] )  function
327
BrowseAtlasInfo( gapname[, std][, ...] )  function
328
Returns: the list of clicked info records.
329
330
This function shows the information available via the GAP package AtlasRep
331
in a browse table, cf. Section 'AtlasRep: Accessing Data of the AtlasRep
332
Package' in the AtlasRep manual.
333
334
The optional arguments can be used to restrict the table to public or
335
private data, or to show an overview for one particular group. The arguments
336
are the same as for DisplayAtlasInfo (AtlasRep: DisplayAtlasInfo), see the
337
documentation of this function for details. (Note that additional conditions
338
such as IsPermGroup (Reference: IsPermGroup) can be entered also in the case
339
that no gapname is given. In this situation, the additional conditions are
340
evaluated for the second level tables that are opened by clicking on a table
341
row or entry.)
342
343
When one clicks on one of the table rows or entries then a browse table with
344
an overview of the information available for this group is shown, and
345
clicking on one of the rows in these tables adds the corresponding info
346
record (see OneAtlasGeneratingSetInfo (AtlasRep: OneAtlasGeneratingSetInfo))
347
to the list of return values of BrowseAtlasInfo.
348
349
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is
350
available.
351
352
The following example shows how BrowseAtlasInfo can be used to fetch info
353
records about permutation representations of the alternating groups A_5 and
354
A_6: We search for the group name "A5" in the overview table, and the first
355
cell in the table row for A_5 becomes selected; hitting the Enter key causes
356
a new window to be opened, with an overview of the data available for A_5;
357
moving down two rows and hitting the Enter key again causes the second
358
representation to be added to the result list; hitting Q closes the second
359
window, and we are back in the overview table; we move the selection down
360
twice (to the row for the group A_6), and choose the first representation
361
for this group; finally we leave the table, and the return value is the list
362
with the data for the two representations.
363
364
 Example 
365
gap> d:= [ NCurses.keys.DOWN ];; r:= [ NCurses.keys.RIGHT ];;
366
gap> c:= [ NCurses.keys.ENTER ];;
367
gap> BrowseData.SetReplay( Concatenation(
368
>  "/A5", # Find the string A5 ...
369
>  d, d, r, # ... such that just the word matches,
370
>  c, # start the search,
371
>  c, # click the table entry A5,
372
>  d, d, # move down two rows,
373
>  c, # click the row for this representation,
374
>  "Q", # quit the second level table,
375
>  d, d, # move down two rows,
376
>  c, # click the table entry A6,
377
>  d, # move down one row,
378
>  c, # click the first row,
379
>  "Q", # quit the second level table,
380
>  "Q" ) ); # and quit the application.
381
gap> if IsBound( BrowseAtlasInfo ) and IsBound( AtlasProgramInfo ) then
382
>  tworeps:= BrowseAtlasInfo();
383
>  else
384
>  tworeps:= [ fail ];
385
>  fi;
386
gap> BrowseData.SetReplay( false );
387
gap> if fail in tworeps then
388
>  Print( "no access to the Web ATLAS\n" );
389
>  else
390
>  Print( List( tworeps, x -> x.identifier[1] ), "\n" );
391
[ "A5", "A6" ]
392
>  fi;
393

394
395
Implementation remarks: The first browse table shown has a static header, no
396
footer and row labels, one row of column labels describing the type of data
397
summarized in the columns.
398
399
Row and column separators are drawn as grids (cf. NCurses.Grid (2.2-8))
400
composed from the special characters described in Section 2.1-6, using the
401
component work.SpecialGrid of the browse table, see BrowseData (5.4-1).
402
403
When a row is selected, the click functionality opens a new window (via a
404
second level call to NCurses.BrowseGeneric (4.3-1)), in which a browse table
405
with the list of available data for the given group is shown; in this table,
406
click results in adding the info for the selected row to the result list,
407
and a message about this addition is shown in the footer row. One can choose
408
further data, return to the first browse table, and perhaps iterate the
409
process for other groups. When the first level table is left, the list of
410
info records for the chosen data is returned.
411
412
For the two kinds of browse tables, the standard modes in BrowseData (5.4-1)
413
(except the help mode) have been extended by a new action that opens a pager
414
giving an overview of all data that have been chosen in the current call.
415
The corresponding user input is the Y key.
416
417
This function is available only if the GAP package AtlasRep is available.
418
419
The code can be found in the file app/atlasbrowse.g of the package.
420
421
422
6.6 Access to GAP Manuals–a Variant
423
424
A Browse adapted way to access several manuals is to show the hierarchy of
425
books, chapters, sections, and subsections as collapsible category rows, and
426
to regard the contents of each subsection as a data row of a matrix with
427
only one column.
428
429
This application is mainly intended as an example with table cells that
430
exceed the screen, and as an example with several category levels.
431
432
6.6-1 BrowseGapManuals
433
434
BrowseGapManuals( [start] )  function
435
436
This function displays the contents of the GAP manuals (the main GAP manuals
437
as well as the loaded package manuals) in a window. The optional argument
438
start describes the initial status, admissible values are the strings
439
"inline/collapsed", "inline/expanded", "pager/collapsed", and
440
"pager/expanded".
441
442
In the inline cases, the parts of the manuals are shown in the browse table,
443
and in the pager case, the parts of the manuals are shown in a different
444
window when they are clicked, using the user's favourite help viewer, see
445
'Reference: Changing the Help Viewer'.
446
447
In the collapsed cases, all category rows are collapsed, and the first row
448
is selected; typical next steps are moving down the selection and expanding
449
single category rows. In the expanded cases, all category rows are expanded,
450
and nothing is selected; a typical next step in the inline/expanded case is
451
a search for a string in the manuals. (Note that searching in quite slow:
452
For viewing a part of a manual, the file with the corresponding section is
453
read into GAP, the text is formatted, the relevant part is cut out from the
454
section, perhaps markup is stripped off, and finally the search is performed
455
in the resulting strings.)
456
457
If no argument is given then the user is asked for selecting an initial
458
status, using NCurses.Select (3.1-2).
459
460
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is
461
available.
462
463
 Example 
464
gap> n:= [ 14, 14, 14 ];; # ``do nothing''
465
gap> BrowseData.SetReplay( Concatenation(
466
>  "xdxd", # expand a Tutorial section
467
>  n, "Q" ) ); # and quit
468
gap> BrowseGapManuals( "inline/collapsed" );
469
gap> BrowseData.SetReplay( Concatenation(
470
>  "/Browse", [ NCurses.keys.ENTER ], # search for "Browse"
471
>  "xdxddxd", # expand a section
472
>  n, "Q" ) ); # and quit
473
gap> BrowseGapManuals( "inline/collapsed" );
474
gap> BrowseData.SetReplay( false );
475

476
477
Implementation remarks: The browse table has a dynamic header showing the
478
name of the currently selected manual, no footer, no row or column labels,
479
and exactly one column of fixed width equal to the screen width. The
480
category rows are precomputed, i. e., they do not arise from a table column;
481
this way, the contents of each data cell can be computed on demand, as soon
482
as it is shown on the screen, in particular the category hierarchy is
483
computed without reading the manuals into GAP. Also, the data rows are not
484
cached. There is no return value. The heights of many cells are bigger than
485
the screen height, so scrolling is a mixture of scrolling to the next cell
486
and scrolling inside a cell. The different initial states are realized via
487
executing different initial steps before the table is shown to the user.
488
489
For the variants that show the manuals in a pager, the code temporarily
490
replaces the show function of the default viewer "screen" (see 'Reference:
491
Changing the Help Viewer') by a function that uses NCurses.Pager (3.1-4).
492
Note that in the case that the manual bit in question fits into one screen,
493
the default show function writes this text directly to the screen, but this
494
is used already by the browse table.
495
496
The implementation should be regarded as a sketch.
497
498
For example, the markup available in the text file format of GAPDoc manuals
499
(using Esc sequences) is stripped off instead of being transferred to the
500
attribute lines that arise, because of the highlighting problem mentioned in
501
Section 2.2-3.
502
503
Some heuristics used in the code are due to deficiencies of the manual
504
formats.
505
506
For the inline variant of the browse table, the titles of chapters,
507
sections, and subsections are not regarded as parts of the actual text since
508
they appear already as category rows; however, the functions of the GAP help
509
system deliver the text together with these titles, so these lines must be
510
stripped off afterwards.
511
512
The category hierarchy representing the tables of contents is created from
513
the manual.six files of the manuals. These files do not contain enough
514
information for determining whether several functions define the same
515
subsection, in the sense that there is a common description text after a
516
series of manual lines introducing different functions. In such cases, the
517
browse table contains a category row for each of these functions (with its
518
own number), but the corresponding text appears only under the last of these
519
category rows, the data rows for the others are empty. (This problem does
520
not occur in the GAPDoc manual format because this introduces explicit
521
subsection titles, involving only the first of several function
522
definitions.)
523
524
Also, index entries and sectioning entries in manual.six files of manuals in
525
GAPDoc format are not explicitly distinguished.
526
527
The code can be found in the file app/manual.g of the package.
528
529
530
6.7 Overview of Bibliographies
531
532
The function BrowseBibliography (6.7-1) can be used to turn the contents of
533
bibliography files in BibTeX or BibXMLext format (see 'GAPDoc: The BibXMLext
534
Format') into a Browse table, such that one can scroll in the list, search
535
for entries, sort by year, sort and categorize by authors etc.
536
537
The default bibliography used by BrowseBibliography (6.7-1) is the
538
bibliography of GAP related publications, see [GAP]. The Browse package
539
contains a (perhaps outdated) version of this bibliography. One can get an
540
updated version as follows.
541
542
wget -N http://www.gap-system.org/Doc/Bib/gap-publishednicer.bib
543
544
The columns of the Browse table that is shown by BrowseBibliography (6.7-1)
545
can be customized, two examples for that are given by the functions
546
BrowseBibliographySporadicSimple (AtlasRep:
547
BrowseBibliographySporadicSimple) and BrowseBibliographyGapPackages (6.7-2).
548
549
The function BrowseMSC (6.7-3) shows an overview of the AMS Mathematics
550
Subject Classification codes.
551
552
6.7-1 BrowseBibliography
553
554
BrowseBibliography( [bibfiles] )  function
555
Returns: a record as returned by ParseBibXMLExtFiles (GAPDoc:
556
ParseBibXMLextFiles).
557
558
This function shows the list of bibliography entries in the files given by
559
bibfiles, which may be a string or a list of strings (denoting a filename or
560
a list of filenames, respectively) or a record (see below for the supported
561
components).
562
563
If no argument is given then the file bibl/gap-publishednicer.bib in the
564
Browse package directory is taken, and "GAP Bibliography" is used as the
565
header.
566
567
Another perhaps interesting data file that should be available in the GAP
568
distribution is doc/manualbib.xml. This file can be located as follows.
569
570
 Example 
571
gap> file:= Filename( DirectoriesLibrary( "doc" ), "manualbib.xml" );;
572

573
574
Both BibTeX format and the XML based extended format provided by the GAPDoc
575
package are supported by BrowseBibliography, see Chapter 'GAPDoc: Utilities
576
for Bibliographies'.
577
578
In the case of BibTeX format input, first a conversion to the extended
579
format takes place, via StringBibAsXMLext (GAPDoc: StringBibAsXMLext) and
580
ParseBibXMLextString (GAPDoc: ParseBibXMLextString). Note that syntactically
581
incorrect entries are rejected in this conversion –this is signaled with
582
InfoBibTools (GAPDoc: InfoBibTools) warnings– and that only a subset of the
583
possible LaTeX markup is recognized –other markup appears in the browse
584
table except that the leading backslash is removed.
585
586
In both cases of input, the problem arises that in visual mode, currently we
587
can show only ASCII characters (and the symbols in NCurses.lineDraw, but
588
these are handled differently, see Section 2.1-6). Therefore, we use the
589
function SimplifiedUnicodeString (GAPDoc: SimplifiedUnicodeString) for
590
replacing other unicode characters by ASCII text.
591
592
The return value is a record as returned by ParseBibXMLExtFiles (GAPDoc:
593
ParseBibXMLextFiles), its entries component corresponds to the bibliography
594
entries that have been clicked in visual mode. This record can be used as
595
input for WriteBibFile (GAPDoc: WriteBibFile) or WriteBibXMLextFile (GAPDoc:
596
WriteBibXMLextFile), in order to produce a bibliography file, or it can be
597
used as input for StringBibXMLEntry (GAPDoc: StringBibXMLEntry), in order to
598
produce strings from the entries, in various formats.
599
600
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is
601
available.
602
603
 Example 
604
gap> # sort and categorize by year, scroll down, expand a category row
605
gap> BrowseData.SetReplay( "scrrscsedddddxdddddQ" );
606
gap> BrowseBibliography();;
607
gap> # sort & categorize by authors, expand all category rows, scroll down
608
gap> BrowseData.SetReplay( "scscXseddddddQ" );
609
gap> BrowseBibliography();;
610
gap> # sort and categorize by journal, search for a journal name, expand
611
gap> BrowseData.SetReplay( Concatenation( "scrrrsc/J. Algebra",
612
>  [ NCurses.keys.ENTER ], "nxdddQ" ) );
613
gap> BrowseBibliography();;
614
gap> BrowseData.SetReplay( false );
615

616
617
Implementation remarks: The browse table has a dynamic header (showing the
618
number of entries, which can vary when the table is restricted), no footer
619
and row labels; one row of column labels is given by the descriptions of the
620
table columns (authors, title, year, journal, MSC code).
621
622
Row and column separators are drawn as grids (cf. NCurses.Grid (2.2-8))
623
composed from the special characters described in Section 2.1-6, using the
624
component work.SpecialGrid of the browse table, see BrowseData (5.4-1).
625
626
For categorizing by authors (or by MSC codes), the sort parameter "split
627
rows on categorizing" is set to "yes", so the authors (codes) are
628
distributed to different category rows, hence each entry appears once for
629
each of its authors (or its MSC codes) in the categorized table. When a data
630
row or an entry in a data row is selected, click adds the corresponding
631
bibliographhy entry to the result.
632
633
The width of the title column is preset; usually titles are too long for one
634
line, and the contents of this column is formatted as a paragraph, using the
635
function FormatParagraph (GAPDoc: FormatParagraph). For the authors and
636
journal columns, maximal widths are prescribed, and FormatParagraph (GAPDoc:
637
FormatParagraph) is used for longer entries.
638
639
For four columns, the sort parameters are defined as follows: The authors
640
and MSC code columns do not become hidden when the table is categorized
641
according to this column, sorting by the year yields a descending order, and
642
the category rows arising from these columns and the journal column show the
643
numbers of the data rows that belong to them.
644
645
Those standard modes in BrowseData (5.4-1) where an entry or a row of the
646
table is selected have been extended by three new actions, which open a
647
pager showing the BibTeX, HTML, and Text format of the selected entry,
648
respectively. The corresponding user inputs are the vb, vh, and vt. If the
649
MSC code column is available then also the user input vm is admissible; it
650
opens a pager showing the descriptions of the MSC codes attached to the
651
selected entry.
652
653
This function requires some of the utilities provided by the GAP package
654
GAPDoc (see [LN07]), such as FormatParagraph (GAPDoc: FormatParagraph),
655
NormalizeNameAndKey (GAPDoc: NormalizeNameAndKey), NormalizedNameAndKey
656
(GAPDoc: NormalizedNameAndKey), ParseBibFiles (GAPDoc: ParseBibFiles),
657
ParseBibXMLextFiles (GAPDoc: ParseBibXMLextFiles), ParseBibXMLextString
658
(GAPDoc: ParseBibXMLextString), RecBibXMLEntry (GAPDoc: RecBibXMLEntry), and
659
StringBibAsXMLext (GAPDoc: StringBibAsXMLext).
660
661
The code can be found in the file app/gapbibl.g of the package.
662
663
The browse table can be customized by entering a record as the argument of
664
BrowseBibliography, with the following supported components.
665
666
files
667
a nonempty list of filenames containing the data to be shown; there is
668
no default for this component.
669
670
filesshort
671
a list of the same length as the files component, the entries are
672
strings which are shown in the "sourcefilename" column of the table
673
(if this column is present); the default is the list of filenames.
674
675
filecontents
676
a list of the same length as the files component, the entries are
677
strings which are shown as category values when the table is
678
categorized by the "sourcefilename" column; the default is the list of
679
filenames.
680
681
header
682
is the constant part of the header shown above the browse table, the
683
default is the first filename.
684
685
columns
686
is a list of records that are valid as the second argument of
687
DatabaseAttributeAdd (A.1-5), where the first argument is a database
688
id enumerator created from the bibliography entries in the files in
689
question. Each entry (and also the corresponding identifier) of this
690
database id enumerator is a list of records obtained from
691
ParseBibXMLextFiles (GAPDoc: ParseBibXMLextFiles) and RecBibXMLEntry
692
(GAPDoc: RecBibXMLEntry), or from ParseBibFiles (GAPDoc:
693
ParseBibFiles), such that the list elements are regarded as equal, in
694
the sense that their fingerprints (see below) are equal. The records
695
in the columns list are available for constructing the desired browse
696
table, the actual appearance is controlled by the choice component
697
described below. Columns showing authors, title, year, journal, MSC
698
code, and filename are predefined and need not be listed here.
699
700
choice
701
a list of strings denoting the identifier components of those columns
702
that shall actually be shown in the table, the default is [ "authors",
703
"title", "year", "journal", "mrclass" ].
704
705
fingerprint
706
a list of strings denoting component names of the entries of the
707
database id enumerator that is constructed from the data (see above);
708
two data records are regarded as equal if the values of these
709
components are equal; the default is [ "mrnumber", "title",
710
"authorAsList", "editorAsList", "author" ].
711
712
sortKeyFunction
713
either fail or a function that takes a record as returned by
714
RecBibXMLEntry (GAPDoc: RecBibXMLEntry) and returns a list that is
715
used for comparing and thus sorting the records; the default is fail,
716
which means that the rows of the table appear in the same ordering as
717
in the source files.
718
719
6.7-2 BrowseBibliographyGapPackages
720
721
BrowseBibliographyGapPackages( )  function
722
Returns: a record as returned by BrowseBibliography (6.7-1).
723
724
This function collects the information from the *.bib and *bib.xml files in
725
those subdirectories of installed GAP packages which contain the package
726
documentation, and shows it in a Browse table, using the function
727
BrowseBibliography (6.7-1).
728
729
This function is experimental. The result is not really satisfactory, for
730
the following reasons.
731
732
 Duplicate entries may occur, due to subtle differences in various
733
source files.
734
735
 The source files may contain more than what is actually cited in the
736
package manuals.
737
738
 It may happen that some *.bib or *bib.xml file is accidentally
739
distributed with the package but is not intended to serve as package
740
bibliography.
741
742
 The heuristics for rewriting LaTeX code is of course not perfect; thus
743
strange symbols may occur in the Browse table.
744
745
6.7-3 BrowseMSC
746
747
BrowseMSC( )  function
748
Returns: nothing.
749
750
This function shows the currently valid MSC codes in a browse table that is
751
categorized by the ..-XX and the ...xx codes. (Use X for expanding all
752
categories or x for expanding the currently selected category.) Due to the
753
categorization, only two columns of the table are visible, showing the codes
754
and their descriptions.
755
756
757
6.8 Profiling GAP functions–a Variant
758
759
A Browse adapted way to evaluate profiling results is to show the overview
760
that is printed by the GAP function DisplayProfile (Reference:
761
DisplayProfile) in a Browse table, which allows one to sort the profiled
762
functions according to the numbers of calls, the time spent, etc., and to
763
search for certain functions one is interested in.
764
765
6.8-1 BrowseProfile
766
767
BrowseProfile( [functions, ][mincount, mintime] )  function
768
769
The arguments and their meaning are the same as for the function
770
DisplayProfile (Reference: DisplayProfile), in the sense that the lines
771
printed by that function correspond to the rows of the list that is shown by
772
BrowseProfile. Initially, the table is sorted in the same way as the list
773
shown by BrowseProfile; sorting the table by any of the first five columns
774
will yield a non-increasing order of the rows.
775
776
The threshold values mincount and mintime can be changed in visual mode via
777
the user input e. If mouse events are enabled (see NCurses.UseMouse
778
(2.2-10)) then one can also use a mouse click on the current parameter value
779
shown in the table header in order to enter the mode for changing the
780
parameters.
781
782
When a row or an entry in a row is selected, click shows the code of the
783
corresponding function in a pager (see NCurses.Pager (3.1-4)) whenever this
784
is possible, as follows. If the function was read from a file then this file
785
is opened, if the function was entered interactively then the code of the
786
function is shown in the format produced by Print (Reference: Print); other
787
functions (for example GAP kernel functions) cannot be shown, one gets an
788
alert message (see NCurses.Alert (3.1-1)) in such a case.
789
790
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is
791
available.
792
793
 Example 
794
gap> n:= [ 14, 14, 14, 14, 14 ];; # ``do nothing''
795
gap> ProfileOperationsAndMethods( true ); # collect some data
796
gap> ConjugacyClasses( PrimitiveGroup( 24, 1 ) );;
797
gap> ProfileOperationsAndMethods( false );
798
gap> BrowseData.SetReplay( Concatenation(
799
>  "scso", # sort by column 1,
800
>  n,
801
>  "rso", # sort by column 2,
802
>  n,
803
>  "rso", # sort by column 3,
804
>  n,
805
>  "q", # deselect the column,
806
>  "/Centralizer", [ NCurses.keys.ENTER ], # search for a function,
807
>  n, "Q" ) ); # and quit
808
gap> BrowseProfile();
809
gap> BrowseData.SetReplay( false );
810

811
812
Implementation remarks: The browse table has a dynamic header, which shows
813
the current values of mincount and mintime, and a dynamic footer, which
814
shows the sums of counts and timings for the rows in the table (label TOTAL)
815
and if applicable the sums for the profiled functions not shown in the table
816
(label OTHER). There are no row labels, and the obvious column labels. There
817
is no return value.
818
819
The standard modes in BrowseData (5.4-1) (except the help mode) have been
820
modified by adding a new action for changing the threshold parameters
821
mincount and mintime (user input e). The way how this in implemented made it
822
necessary to change the standard reset action (user input !) of the table;
823
note that resetting (a sorting or filtering of) the table must not make
824
those rows visible that shall be hidden because of the threshold parameters.
825
826
The code can be found in the file app/profile.g of the package.
827
828
829
6.9 Variables defined in GAP packages–a Variant
830
831
A Browse adapted way to list the variables that are defined in a GAP package
832
is to show the overview that is printed by the GAP function
833
ShowPackageVariables (Reference: ShowPackageVariables) in a Browse table.
834
835
6.9-1 BrowsePackageVariables
836
837
BrowsePackageVariables( pkgname[, version][, arec] )  function
838
Returns: nothing.
839
840
The arguments can be the same as for ShowPackageVariables (Reference:
841
ShowPackageVariables), that is, pkgname is the name of a GAP package, and
842
the optional arguments version and arec are a version number of this package
843
and a record used for customizing the output, respectively.
844
845
Alternatively, the second argument can be the output info of
846
PackageVariablesInfo (Reference: PackageVariablesInfo) for the package in
847
question, instead of the version number.
848
849
BrowsePackageVariables opens a browse table that shows the global variables
850
that become bound and the methods that become installed when GAP loads the
851
package pkgname.
852
853
The table is categorized by the kinds of variables (new or redeclared
854
operations, methods, info classes, synonyms, other globals). The column
855
Doc.? distinguishes undocumented and documented variables, so one can use
856
this column as a filter or for categorizing. The column Filename shows the
857
names of the package files. Clicking a selected row of the table opens the
858
relevant package file at the code in question.
859
860
The idea behind the argument info is that using the same arguments as for
861
ShowPackageVariables (Reference: ShowPackageVariables) does not allow one to
862
apply BrowsePackageVariables to packages that have been loaded before the
863
Browse package. Thus one can compute the underlying data info first, using
864
PackageVariablesInfo (Reference: PackageVariablesInfo), then load the Browse
865
package, and finally call BrowsePackageVariables.
866
867
For example, the overview of package variables for Browse can be shown by
868
starting GAP without packages and then entering the following lines.
869
870
 Example 
871
gap> pkgname:= "Browse";;
872
gap> info:= PackageVariablesInfo( pkgname, "" );;
873
gap> LoadPackage( "Browse" );;
874
gap> BrowsePackageVariables( pkgname, info );
875

876
877
If the arguments are the same as for ShowPackageVariables (Reference:
878
ShowPackageVariables) then this function is actually called, with the
879
consequence that the package gets loaded when BrowsePackageVariables is
880
called. This is not the case if the output of PackageVariablesInfo
881
(Reference: PackageVariablesInfo) is entered as the second argument.
882
883
884
6.10 Configuring User preferences–a Variant
885
886
A Browse adapted way to show and edit GAP's user preferences is to show the
887
overview that is printed by the GAP function ShowUserPreferences (Reference:
888
ShowUserPreferences) in a Browse table.
889
890
6.10-1 BrowseUserPreferences
891
892
BrowseUserPreferences( package1, package2, ... )  function
893
Returns: nothing.
894
895
The arguments are the same as for ShowUserPreferences (Reference:
896
ShowUserPreferences), that is, calling the function with no argument yields
897
an overview of all known user preferences, and if one or more strings
898
package1, ... are given then only the user preferences for these packages
899
are shown.
900
901
BrowseUserPreferences opens a browse table with the following columns:
902
903
Package
904
contains the names of the GAP packages to which the user preferences
905
belong,
906
907
Pref. names
908
contains the names of the user preferences, and
909
910
Description
911
contains the description texts from the DeclareUserPreference
912
(Reference: DeclareUserPreference) calls and the default values (if
913
applicable), and the actual values.
914
915
When one clicks on one of the table rows or entries then the values of the
916
user preference in question can be edited. If a list of admissible values is
917
known then this means that one can choose from this list via NCurses.Select
918
(3.1-2), otherwise one can enter the desired value as text.
919
920
The values of the user preferences are not changed before one closes the
921
browse table. When the table is left and if one has changed at least one
922
value, one is asked whether the changes shall be applied.
923
924
 Example 
925
gap> d:= [ NCurses.keys.DOWN ];; 
926
gap> c:= [ NCurses.keys.ENTER ];; 
927
gap> BrowseData.SetReplay( Concatenation(
928
>  "/PackagesToLoad", # enter a search string,
929
>  c, # start the search,
930
>  c, # edit the entry (a list of choices),
931
>  " ", d, # toggle the first four values,
932
>  " ", d, #
933
>  " ", d, #
934
>  " ", d, #
935
>  c, # submit the values,
936
>  "Q", # quit the table,
937
>  c ) ); # choose "cancel": do not apply the changes.
938
gap> BrowseUserPreferences();
939
gap> BrowseData.SetReplay( false );
940

941
942
The code can be found in the file app/userpref.g of the package.
943
944
945
6.11 Overview of GAP Data
946
947
The GAP system contains several data collections such as libraries of groups
948
and character tables. Clearly the function NCurses.BrowseGeneric (4.3-1) can
949
be used to visualize interesting information about such data collections, in
950
the form of an overview table whose rows correspond to the objects in the
951
collection; each column of the table shows a piece of information about the
952
objects. (One possibility to create such overviews is given by
953
BrowseTableFromDatabaseIdEnumerator (A.2-2).)
954
955
6.11-1 BrowseGapData
956
957
BrowseGapData( )  function
958
Returns: the return value of the chosen application if there is one.
959
960
The function BrowseGapData shows the choices in the list
961
BrowseData.GapDataOverviews, in a browse table with one column. When an
962
entry is clicked then the associated function is called, and the table of
963
choices is closed.
964
965
The idea is that each entry of BrowseData.GapDataOverviews describes an
966
overview of a data collection.
967
968
The Browse package provides overviews of
969
970
 the current AMS Mathematics Subject Classification codes (see
971
BrowseMSC (6.7-3)),
972
973
 the contents of the AtlasRep package [WPN+07] (only if this package is
974
loaded, see Section 6.5),
975
976
 the Conway polynomials in GAP (calls BrowseConwayPolynomials()),
977
978
 profile information for GAP functions (see Section 6.8),
979
980
 the list of GAP related bibliography entries in the file
981
bibl/gap-publishednicer.bib of the Browse package (see Section 6.7),
982
983
 the GAP manuals (see Section 6.6),
984
985
 GAP operations and methods (calls BrowseGapMethods()),
986
987
 the installed GAP packages (calls BrowseGapPackages()),
988
989
 GAP's user preferences (see Section 6.10),
990
991
 the contents of the TomLib package [NMP13] (only if this package is
992
loaded, see Section A.4),
993
994
Other GAP packages may add more overviews, using the function
995
BrowseGapDataAdd (6.11-2). For example, there are overviews of
996
997
 the bibliographies in the ATLAS of Finite Groups [CCN+85] and in the
998
ATLAS of Brauer Characters [JLPW95] (see
999
BrowseBibliographySporadicSimple (AtlasRep:
1000
BrowseBibliographySporadicSimple)),
1001
1002
 atomic irrationalities that occur in character tables in the ATLAS of
1003
Finite Groups [CCN+85] or the ATLAS of Brauer Characters [JLPW95] (see
1004
Section BrowseCommonIrrationalities (CTblLib:
1005
BrowseCommonIrrationalities)),
1006
1007
 the differences between the versions of the character table data in
1008
the CTblLib package (see Section BrowseCTblLibDifferences (CTblLib:
1009
BrowseCTblLibDifferences)),
1010
1011
 the information in the GAP Character Table Library (see Section
1012
BrowseCTblLibInfo (CTblLib: BrowseCTblLibInfo)),
1013
1014
 an overview of minimal degrees of representations of groups from the
1015
ATLAS of Group Representations (see Section BrowseMinimalDegrees
1016
(AtlasRep: BrowseMinimalDegrees)).
1017
1018
Except that always one table cell is selected, the full functionality of the
1019
function NCurses.BrowseGeneric (4.3-1) is available.
1020
1021
 Example 
1022
gap> n:= [ 14, 14, 14 ];; # ``do nothing''
1023
gap> # open the overview of Conway polynomials
1024
gap> BrowseData.SetReplay( Concatenation( "/Conway Polynomials",
1025
>  [ NCurses.keys.ENTER, NCurses.keys.ENTER ], "srdddd", n, "Q" ) );
1026
gap> BrowseGapData();;
1027
gap> # open the overview of GAP packages
1028
gap> BrowseData.SetReplay( Concatenation( "/GAP Packages",
1029
>  [ NCurses.keys.ENTER, NCurses.keys.ENTER ], "/Browse",
1030
>  [ NCurses.keys.ENTER ], "n", n, "Q" ) );
1031
gap> BrowseGapData();;
1032
gap> BrowseData.SetReplay( false );
1033

1034
1035
Implementation remarks: The browse table has a static header, a dynamic
1036
footer showing the description of the currently selected entry, no row or
1037
column labels, and exactly one column of fixed width equal to the screen
1038
width. If the chosen application has a return value then this is returned by
1039
BrowseGapData, otherwise nothing is returned. The component work.SpecialGrid
1040
of the browse table is used to draw a border around the list of choices and
1041
another border around the footer. Only one mode is needed in which an entry
1042
is selected.
1043
1044
The code can be found in the file app/gapdata.g of the package.
1045
1046
6.11-2 BrowseGapDataAdd
1047
1048
BrowseGapDataAdd( title, call, ret, documentation )  function
1049
1050
This function extends the list BrowseData.GapDataOverviews by a new entry.
1051
The list is used by BrowseGapData (6.11-1).
1052
1053
title must be a string of length at most 76; it will be shown in the browse
1054
table that is opened by BrowseGapData (6.11-1). call must be a function that
1055
takes no arguments; it will be called when title is clicked. ret must be
1056
true if call has a return value and if BrowseGapData (6.11-1) shall return
1057
this value, and false otherwise. documentation must be a string that
1058
describes what happens when the function call is called; it will be shown in
1059
the footer of the table opened by BrowseGapData (6.11-1) when title is
1060
selected.
1061
1062
1063
6.12 Navigating in a Directory Tree
1064
1065
A natural way to visualize the contents of a directory is via a tree whose
1066
leaves denote plain files, and the other vertices denote subdirectories.
1067
Browse provides a function based on NCurses.BrowseGeneric (4.3-1) for
1068
displaying such trees; the leaves correspond to the data rows, and the other
1069
vertices correspond to category rows.
1070
1071
6.12-1 BrowseDirectory
1072
1073
BrowseDirectory( [dir] )  function
1074
Returns: a list of the clicked filenames.
1075
1076
If no argument is given then the contents of the current directory is shown,
1077
see DirectoryCurrent (Reference: DirectoryCurrent). If a directory object
1078
dir (see Directory (Reference: Directory)) is given as the only argument
1079
then the contents of this directory is shown; alternatively, dir may also be
1080
a string which is then understood as a directory path.
1081
1082
The full functionality of the function NCurses.BrowseGeneric (4.3-1) is
1083
available.
1084
1085
 Example 
1086
gap> n:= [ 14, 14, 14 ];; # ``do nothing''
1087
gap> BrowseData.SetReplay( Concatenation(
1088
>  "q", # leave the selection
1089
>  "X", # expand all categories
1090
>  "/filetree", [ NCurses.keys.ENTER ], # search for "filetree"
1091
>  n, "Q" ) ); # and quit
1092
gap> dir:= DirectoriesPackageLibrary( "Browse", "" )[1];;
1093
gap> if IsBound( BrowseDirectory ) then
1094
>  BrowseDirectory( dir );
1095
>  fi;
1096
gap> BrowseData.SetReplay( false );
1097

1098
1099
Implementation remarks: The browse table has a static header, no footer, no
1100
row or column labels, and exactly one data column. The category rows are
1101
precomputed, i. e., they do not arise from a table column. The tree
1102
structure is visualized via a special grid that is shown in the separator
1103
column in front of the table column; the width of this column is computed
1104
from the largest nesting depth of files. For technical reasons, category
1105
rows representing empty directories are realized via dummy table rows; a
1106
special ShowTables function guarantees that these rows are always hidden.
1107
1108
When a data row or an entry in this row is selected, click adds the
1109
corresponding filename to the result list. Initially, the first row is
1110
selected. (So if you want to search in the whole tree then you should quit
1111
this selection by hitting the q key.)
1112
1113
The category hierarchy is computed using DirectoryContents (Reference:
1114
DirectoryContents).
1115
1116
This function is available only if the GAP package IO (see [Neu07]) is
1117
available, because the check for cycles uses the function IO_stat (IO:
1118
IO_stat) from this package.
1119
1120
The code can be found in the file app/filetree.g of the package.
1121
1122
1123
6.13 A Puzzle
1124
1125
We consider an m by n rectangle of squares numbered from 1 to m n - 1, the
1126
bottom right square is left empty. The numbered squares are permuted by
1127
successively exchanging the empty square and a neighboring square such that
1128
in the end, the empty cell is again in the bottom right corner.
1129
1130
┌────┬────┬────┬────┐
1131
│ 7 │ 13 │ 14 │ 2 │
1132
├────┼────┼────┼────┤
1133
│ 1 │ 4 │ 15 │ 11 │
1134
├────┼────┼────┼────┤
1135
│ 6 │ 8 │ 3 │ 9 │
1136
├────┼────┼────┼────┤
1137
│ 10 │ 5 │ 12 │  │
1138
└────┴────┴────┴────┘
1139
1140
The aim of the game is to order the numbered squares via these moves.
1141
1142
For the case m = n = 4, the puzzle is (erroneously?) known under the name
1143
Sam Loyd's Fifteen, see [Bog] and [OR] for more information and references.
1144
1145
6.13-1 BrowsePuzzle
1146
1147
BrowsePuzzle( [m, n[, pi]] )  function
1148
Returns: a record describing the initial and final status of the puzzle.
1149
1150
This function shows the rectangle in a window.
1151
1152
The arguments m and n are the dimensions of the rectangle, the default for
1153
both values is 4. The initial distribution of the numbers in the squares can
1154
be prescribed via a permutation pi, the default is a random element in the
1155
alternating group on the points 1, 2, ..., m n - 1. (Note that the game has
1156
not always a solution.)
1157
1158
In any case, the empty cell is selected, and the selection can be moved to
1159
neighboring cells via the arrow keys, or to any place in the same row or
1160
column via a mouse click.
1161
1162
The return value is a record with the components dim (the pair [ m, n ]),
1163
init (the initial permutation), final (the final permutation), and steps
1164
(the number of transpositions that were needed).
1165
1166
 Example 
1167
gap> BrowseData.SetReplay( Concatenation(
1168
>  BrowsePuzzleSolution.steps, "Q" ) );
1169
gap> BrowsePuzzle( 4, 4, BrowsePuzzleSolution.init );;
1170
gap> BrowseData.SetReplay( false );
1171

1172
1173
An implementation using only mouse clicks but no key strokes is available in
1174
the GAP package XGAP (see [CN04]).
1175
1176
Implementation remarks: The game board is implemented via a browse table,
1177
without row and column labels, with static header, dynamic footer, and
1178
individual minyx function. Only one mode is needed in which one cell is
1179
selected, and besides the standard actions for quitting the table, asking
1180
for help, and saving the current window contents, only the four moves via
1181
the arrow keys and mouse clicks are admissible.
1182
1183
Some standard NCurses.BrowseGeneric (4.3-1) functionality, such as
1184
scrolling, selecting, and searching, are not available in this application.
1185
1186
The code can be found in the file app/puzzle.g of the package.
1187
1188
1189
6.14 Peg Solitaire
1190
1191
Peg solitaire is a board game for one player. The game board consists of
1192
several holes some of which contain pegs. In each step of the game, one peg
1193
is moved horizontally or vertically to an empty hole at distance two, by
1194
jumping over a neighboring peg which is then removed from the board.
1195
1196
┌───┬───┬───┐
1197
│ o │ o │ o │
1198
├───┼───┼───┤
1199
│ o │ o │ o │
1200
┌───┬───┼───┼───┼───┼───┬───┐
1201
│ o │ o │ o │ o │ o │ o │ o │
1202
├───┼───┼───┼───┼───┼───┼───┤
1203
│ o │ o │ o │ │ o │ o │ o │
1204
├───┼───┼───┼───┼───┼───┼───┤
1205
│ o │ o │ o │ o │ o │ o │ o │
1206
└───┴───┼───┼───┼───┼───┴───┘
1207
│ o │ o │ o │
1208
├───┼───┼───┤
1209
│ o │ o │ o │
1210
└───┴───┴───┘
1211
1212
We consider the game that in the beginning, exactly one hole is empty, and
1213
in the end, exactly one peg is left.
1214
1215
6.14-1 PegSolitaire
1216
1217
PegSolitaire( [format, ][nrholes, ][twoModes] )  function
1218
1219
This function shows the game board in a window.
1220
1221
If the argument format is one of the strings "small" or "large" then small
1222
or large pegs are shown, the default is "small".
1223
1224
Three shapes of the game board are supported, with 33, 37, and 45 holes,
1225
respectively; this number can be specified via the argument nrholes, the
1226
default is 33. In the cases of 33 and 45 holes, the position of both the
1227
initial hole and the destination of the final peg is the middle cell,
1228
whereas in the case of 37 holes, the initial hole is in the top left
1229
position and the final peg has to be placed in the bottom right position.
1230
1231
If a Boolean twoModes is entered as an argument then it determines whether a
1232
browse table with one or two modes is used; the default false yields a
1233
browse table with only one mode.
1234
1235
In any case, one cell of the board is selected, and the selection can be
1236
moved to neighboring cells via the arrow keys. A peg in the selected cell
1237
jumps over a neighboring peg to an adjacent hole via the j key followed by
1238
the appropriate arrow key.
1239
1240
 Example 
1241
gap> for n in [ 33, 37, 45 ] do
1242
>  BrowseData.SetReplay( Concatenation(
1243
>  PegSolitaireSolutions.( String( n ) ), "Q" ) );
1244
>  PegSolitaire( n );
1245
>  PegSolitaire( "large", n );
1246
>  PegSolitaire( n, true );
1247
>  PegSolitaire( "large", n, true );
1248
> od;
1249
gap> BrowseData.SetReplay( false );
1250

1251
1252
For more information such as variations of the game and references,
1253
see [Köla]. Also the solutions stored in the variable PegSolitaireSolutions
1254
have been taken from this web page.
1255
1256
Implementation remarks: The game board is implemented via a browse table,
1257
without row and column labels, with static header, dynamic footer, and
1258
individual minyx function. In fact, two implementations are provided. The
1259
first one needs only one mode in which one cell is selected; moving the
1260
selection and jumping with the peg in the selected cell in one of the four
1261
directions are the supported user actions. The second implementation needs
1262
two modes, one for moving the selection and one for jumping.
1263
1264
Some standard NCurses.BrowseGeneric (4.3-1) functionality, such as
1265
scrolling, selecting, and searching, are not available in this application.
1266
1267
The code can be found in the file app/solitair.g of the package.
1268
1269
1270
6.15 Rubik's Cube
1271
1272
We visualize the transformations of Rubik's magic cube in a model that is
1273
given by unfolding the faces and numbering them as follows.
1274
1275
┌──────────────┐
1276
│ 1 2 3 │
1277
│ 4 top 5 │
1278
│ 6 7 8 │
1279
┌──────────────┼──────────────┼──────────────┬──────────────┐
1280
│ 9 10 11 │ 17 18 19 │ 25 26 27 │ 33 34 35 │
1281
│ 12 left 13 │ 20 front 21 │ 28 right 29 │ 36 back 37 │
1282
│ 14 15 16 │ 22 23 24 │ 30 31 32 │ 38 39 40 │
1283
└──────────────┼──────────────┼──────────────┴──────────────┘
1284
│ 41 42 43 │
1285
│ 44 down 45 │
1286
│ 46 47 48 │
1287
└──────────────┘
1288
1289
Clockwise turns of the six layers (top, left, front, right, back, and down)
1290
are represented by the following permutations.
1291
1292
 Example 
1293
gap> cubegens := [
1294
>  ( 1, 3, 8, 6)( 2, 5, 7, 4)( 9,33,25,17)(10,34,26,18)(11,35,27,19),
1295
>  ( 9,11,16,14)(10,13,15,12)( 1,17,41,40)( 4,20,44,37)( 6,22,46,35),
1296
>  (17,19,24,22)(18,21,23,20)( 6,25,43,16)( 7,28,42,13)( 8,30,41,11),
1297
>  (25,27,32,30)(26,29,31,28)( 3,38,43,19)( 5,36,45,21)( 8,33,48,24),
1298
>  (33,35,40,38)(34,37,39,36)( 3, 9,46,32)( 2,12,47,29)( 1,14,48,27),
1299
>  (41,43,48,46)(42,45,47,44)(14,22,30,38)(15,23,31,39)(16,24,32,40)
1300
> ];;
1301

1302
1303
GAP computations analyzing this permutation group have been part of the
1304
announcements of GAP 3 releases. For a GAP 4 equivalent, see [Sch]. For more
1305
information and references (not GAP related) about Rubik's cube, see [Kölb].
1306
1307
6.15-1 BrowseRubiksCube
1308
1309
BrowseRubiksCube( [format, ][pi] )  function
1310
1311
This function shows the model of the cube in a window.
1312
1313
If the argument format is one of the strings "small" or "large" then small
1314
or large cells are shown, the default is "small".
1315
1316
The argument pi is the initial permutation of the faces, the default is a
1317
random permutation in the cube group, see 'Reference: Random'.
1318
1319
Supported user inputs are the keys t, l, f, r, b, and d for clockwise turns
1320
of the six layers, and the corresponding capital letters for
1321
counter-clockwise turns. If the terminal supports colors, according to the
1322
global variable NCurses.attrs.has_colors (2.2-1), the input s switches
1323
between a screen that shows only the colors of the faces and a screen that
1324
shows the numbers; the color screen is the default.
1325
1326
The return value is a record with the components inputs (a string describing
1327
the user inputs), init, and final (the initial and final permutation of the
1328
faces, respectively). (The inputs component can be used for the replay
1329
feature, see the example below.)
1330
1331
In the following example, a word in terms of the generators is used to
1332
initialize the browse table, and then the letters in this word are used as a
1333
series of input steps, except that in between, the display is switched once
1334
from colors to numbers and back.
1335
1336
 Example 
1337
gap> choice:= List( [ 1 .. 30 ], i -> Random( [ 1 .. 6 ] ) );;
1338
gap> input:= List( "tlfrbd", IntChar ){ choice };;
1339
gap> BrowseData.SetReplay( Concatenation(
1340
>  input{ [ 1 .. 20 ] },
1341
>  "s", # switch to number display
1342
>  input{ [ 21 .. 25 ] },
1343
>  "s", # switch to color display
1344
>  input{ [ 26 .. 30 ] },
1345
>  "Q" ) );; # quit the browse table
1346
gap> BrowseRubiksCube( Product( cubegens{ choice } ) );;
1347
gap> BrowseRubiksCube( "large", Product( cubegens{ choice } ) );;
1348
gap> BrowseData.SetReplay( false );
1349

1350
1351
Implementation remarks: The cube is implemented via a browse table, without
1352
row and column labels, with static header, dynamic footer, and individual
1353
minyx function. Only one mode is needed, and besides the standard actions
1354
for quitting the table, asking for help, and saving the current window
1355
contents, only the twelve moves and the switch between color and number
1356
display are admissible.
1357
1358
Switching between the two display formats is implemented via a function
1359
work.Main, so this relies on not caching the formatted cells in work.main.
1360
1361
Row and column separators of the browse table are whitespace of height and
1362
width one. The separating lines are drawn using an individual SpecialGrid
1363
function in the browse table. Note that the relevant cells do not form a
1364
rectangular array.
1365
1366
Some standard NCurses.BrowseGeneric (4.3-1) functionality, such as
1367
scrolling, selecting, and searching, are not available in this application.
1368
1369
The code can be found in the file app/rubik.g of the package.
1370
1371
1372
6.16 Changing Sides
1373
1374
We consider a 5 by 5 board of squares filled with two types of stones, as
1375
follows. The square in the middle is left empty.
1376
1377
┌───┬───┬───┬───┬───┐
1378
│ x │ x │ x │ x │ x │
1379
├───┼───┼───┼───┼───┤
1380
│ o │ x │ x │ x │ x │
1381
├───┼───┼───┼───┼───┤
1382
│ o │ o │ │ x │ x │
1383
├───┼───┼───┼───┼───┤
1384
│ o │ o │ o │ o │ x │
1385
├───┼───┼───┼───┼───┤
1386
│ o │ o │ o │ o │ o │
1387
└───┴───┴───┴───┴───┘
1388
1389
The aim of the game is to exchange the two types of stones via a sequence of
1390
single steps that move one stone to the empty position on the board. Only
1391
those moves are allowed that increase or decrease one coordinate by 2 and
1392
increase or decrease the other by 1; these are the allowed moves of the
1393
knight in chess.
1394
1395
This game has been part of the MacTutor system [OR00].
1396
1397
6.16-1 BrowseChangeSides
1398
1399
BrowseChangeSides( )  function
1400
1401
This function shows the game board in a window.
1402
1403
Each move is encoded as a sequence of three arrow keys; there are 24
1404
admissible inputs.
1405
1406
 Example 
1407
gap> for entry in BrowseChangeSidesSolutions do
1408
>  BrowseData.SetReplay( Concatenation( entry, "Q" ) );
1409
>  BrowseChangeSides();
1410
> od;
1411
gap> BrowseData.SetReplay( false );
1412

1413
1414
Implementation remarks: The game board is implemented via a browse table,
1415
without row and column labels, with static header, dynamic footer, and
1416
individual minyx function. Only one mode is needed, and besides the standard
1417
actions for quitting the table, asking for help, and saving the current
1418
window contents, only moves via combinations of the four arrow keys are
1419
admissible.
1420
1421
The separating lines are drawn using an individual SpecialGrid function in
1422
the browse table.
1423
1424
Some standard NCurses.BrowseGeneric (4.3-1) functionality, such as
1425
scrolling, selecting, and searching, are not available in this application.
1426
1427
The code can be found in the file app/knight.g of the package.
1428
1429
1430
6.17 Sudoku
1431
1432
We consider a 9 by 9 board of squares. Some squares are initially filled
1433
with numbers from 1 to 9. The aim of the game is to fill the empty squares
1434
in such a way that each row, each column, and each of the marked 3 by 3
1435
subsquares contains all numbers from 1 to 9. A proper Sudoku game is defined
1436
as one with a unique solution. Here is an example.
1437
1438
┏━━━┯━━━┯━━━┳━━━┯━━━┯━━━┳━━━┯━━━┯━━━┓
1439
┃ │ │ ┃ │ │ ┃ 5 │ │ ┃
1440
┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
1441
┃ │ 1 │ 5 ┃ 4 │ │ 6 ┃ │ 2 │ ┃
1442
┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
1443
┃ 9 │ │ ┃ │ 5 │ ┃ 3 │ │ ┃
1444
┣━━━┿━━━┿━━━╋━━━┿━━━┿━━━╋━━━┿━━━┿━━━┫
1445
┃ 6 │ │ 4 ┃ │ │ ┃ │ │ ┃
1446
┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
1447
┃ │ │ ┃ 8 │ │ ┃ │ │ ┃
1448
┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
1449
┃ 8 │ │ ┃ 9 │ │ ┃ │ 5 │ 3 ┃
1450
┣━━━┿━━━┿━━━╋━━━┿━━━┿━━━╋━━━┿━━━┿━━━┫
1451
┃ │ │ ┃ │ │ 5 ┃ │ │ ┃
1452
┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
1453
┃ │ 4 │ ┃ │ │ 7 ┃ │ │ 2 ┃
1454
┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
1455
┃ │ │ 9 ┃ 1 │ │ ┃ 8 │ │ ┃
1456
┗━━━┷━━━┷━━━┻━━━┷━━━┷━━━┻━━━┷━━━┷━━━┛
1457
1458
The Browse package contains functions to create, play and solve these games.
1459
There are basic command line functions for this, which we describe first,
1460
and there is a user interface PlaySudoku (6.17-8) which is implemented using
1461
the generic browse functionality described in Chapter 4.
1462
1463
6.17-1 Sudoku.Init
1464
1465
Sudoku.Init( [arg] )  function
1466
Returns: A record describing a Sudoku board or fail.
1467
1468
This function constructs a record describing a Sudoku game. This is used by
1469
the other functions described below. There a several possibilities for the
1470
argument arg.
1471
1472
arg is a string
1473
The entries of a Sudoku board are numbered row-wise from 1 to 81. A
1474
board is encoded as a string as follows. If one of the numbers 1 to 9
1475
is in entry i then the corresponding digit character is written in
1476
position i of the string. If an entry is empty any character, except
1477
'1' to '9' or '|' is written in position i of the string. Trailing
1478
empty entries can be left out. Afterwards '|'-characters can be
1479
inserted in the string (for example to mark line ends). Such strings
1480
can be used for arg.
1481
1482
arg is a matrix
1483
A Sudoku board can also be encoded as a 9 by 9-matrix, that is a list
1484
of 9 lists of length 9, whose (i,j)-th entry is the (i,j)-th entry of
1485
the board as integer if it is not empty. Empty entries of the board
1486
correspond to unbound entries in the matrix.
1487
1488
arg is a list of integers
1489
Instead of the matrix just described the argument can also be given by
1490
the concatenation of the rows of the matrix (so, a list of integers
1491
and holes).
1492
1493
 Example 
1494
gap> game := Sudoku.Init(" 3 68 | 85 1 69| 97 53| 79 |\
1495
>  6 47 |45 2 |89 2 1 | 4 8 7 | ");;
1496

1497
1498
6.17-2 Sudoku.Place
1499
1500
Sudoku.Place( game, i, n )  function
1501
Sudoku.Remove( game, i )  function
1502
Returns: The changed game.
1503
1504
Here game is a record describing a Sudoku board, as returned by Sudoku.Init
1505
(6.17-1). The argument i is the number of an entry, counted row-wise from 1
1506
to 81, and n is an integer from 1 to 9 to be placed on the board. These
1507
functions change game.
1508
1509
Sudoku.Place tries to place number n on entry i. It is an error if entry i
1510
is not empty. The number is not placed if n is already used in the row,
1511
column or subsquare of entry i. In this case the component game.impossible
1512
is bound.
1513
1514
Sudoku.Remove tries to remove the number placed on position i of the board.
1515
It does not change the board if entry i is empty, or if entry i was given
1516
when the board game was created. In the latter case game.impossible is
1517
bound.
1518
1519
 Example 
1520
gap> game := Sudoku.Init(" 3 68 | 85 1 69| 97 53| 79 |\
1521
>  6 47 |45 2 |89 2 1 | 4 8 7 | ");;
1522
gap> Sudoku.Place(game, 1, 3);; # 3 is already in first row
1523
gap> IsBound(game.impossible);
1524
true
1525
gap> Sudoku.Place(game, 1, 2);; # 2 is not in row, col or subsquare
1526
gap> IsBound(game.impossible);
1527
false
1528

1529
1530
6.17-3 Sudoku.RandomGame
1531
1532
Sudoku.RandomGame( [seed] )  function
1533
Returns: A pair [str, seed] of string and seed.
1534
1535
The optional argument seed, if given, must be an integer. If not given some
1536
random integer from the current GAP session is used. This function returns a
1537
random proper Sudoku game, where the board is described by a string str, as
1538
explained in Sudoku.Init (6.17-1). With the same seed the same board is
1539
returned.
1540
1541
The games computed by this function have the property that after removing
1542
any given entry the puzzle does no longer have a unique solution.
1543
1544
 Example 
1545
gap> Sudoku.RandomGame(5833750);
1546
[ " 1 2 43 2 68 72 8 6 2 1 9 8 8 3 9 \
1547
47 3 7 18 ", 5833750 ]
1548
gap> last = Sudoku.RandomGame(last[2]);
1549
true
1550

1551
1552
6.17-4 Sudoku.SimpleDisplay
1553
1554
Sudoku.SimpleDisplay( game )  function
1555
1556
Displays a Sudoku board on the terminal. (But see PlaySudoku (6.17-8) for a
1557
fancier interface.)
1558
1559
 Example 
1560
gap> game := Sudoku.Init(" 3 68 | 85 1 69| 97 53| 79 |\
1561
>  6 47 |45 2 |89 2 1 | 4 8 7 | ");;
1562
gap> Sudoku.SimpleDisplay(game);
1563
 3 | 6|8 
1564
 85| 1| 69
1565
 9|7 | 53
1566
-----------
1567
 | |79 
1568
 6 | 47| 
1569
45 | 2 | 
1570
-----------
1571
89 | 2| 1 
1572
 4 | 8| 7 
1573
 | | 
1574

1575
1576
6.17-5 Sudoku.DisplayString
1577
1578
Sudoku.DisplayString( game )  function
1579
1580
The string returned by this function can be used to display the Sudoku board
1581
game on the terminal, using PrintFormattedString (GAPDoc:
1582
PrintFormattedString). The result depends on the value of
1583
GAPInfo.TermEncoding.
1584
1585
 Example 
1586
gap> game := Sudoku.Init(" 3 68 | 85 1 69| 97 53| 79 |\
1587
>  6 47 |45 2 |89 2 1 | 4 8 7 | ");;
1588
gap> str:= Sudoku.DisplayString( game );;
1589
gap> PrintFormattedString( str );
1590
 ┏━━━┯━━━┯━━━┳━━━┯━━━┯━━━┳━━━┯━━━┯━━━┓
1591
 ┃ │ 3 │ ┃ │ │ 6 ┃ 8 │ │ ┃
1592
 ┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
1593
 ┃ │ 8 │ 5 ┃ │ │ 1 ┃ │ 6 │ 9 ┃
1594
 ┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
1595
 ┃ │ │ 9 ┃ 7 │ │ ┃ │ 5 │ 3 ┃
1596
 ┣━━━┿━━━┿━━━╋━━━┿━━━┿━━━╋━━━┿━━━┿━━━┫
1597
 ┃ │ │ ┃ │ │ ┃ 7 │ 9 │ ┃
1598
 ┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
1599
 ┃ │ 6 │ ┃ │ 4 │ 7 ┃ │ │ ┃
1600
 ┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
1601
 ┃ 4 │ 5 │ ┃ │ 2 │ ┃ │ │ ┃
1602
 ┣━━━┿━━━┿━━━╋━━━┿━━━┿━━━╋━━━┿━━━┿━━━┫
1603
 ┃ 8 │ 9 │ ┃ │ │ 2 ┃ │ 1 │ ┃
1604
 ┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
1605
 ┃ │ 4 │ ┃ │ │ 8 ┃ │ 7 │ ┃
1606
 ┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
1607
 ┃ │ │ ┃ │ │ ┃ │ │ ┃
1608
 ┗━━━┷━━━┷━━━┻━━━┷━━━┷━━━┻━━━┷━━━┷━━━┛
1609

1610
1611
6.17-6 Sudoku.OneSolution
1612
1613
Sudoku.OneSolution( game )  function
1614
Returns: A completed Sudoku board that solves game, or fail.
1615
1616
Here game must be a Sudoku board as returned by Sudoku.Init (6.17-1). It is
1617
not necessary that game describes a proper Sudoku game (has a unique
1618
solution). It may have several solutions, then one random solution is
1619
returned. Or it may have no solution, then fail is returned.
1620
1621
 Example 
1622
gap> Sudoku.SimpleDisplay(Sudoku.OneSolution(Sudoku.Init(" 3")));
1623
493|876|251
1624
861|542|739
1625
527|193|648
1626
-----------
1627
942|618|573
1628
156|739|482
1629
738|425|916
1630
-----------
1631
289|354|167
1632
375|961|824
1633
614|287|395
1634

1635
1636
6.17-7 Sudoku.UniqueSolution
1637
1638
Sudoku.UniqueSolution( game )  function
1639
Returns: A completed Sudoku board that solves game, or false, or fail.
1640
1641
Here game must be a Sudoku board as returned by Sudoku.Init (6.17-1). It is
1642
not necessary that game describes a proper Sudoku game. If it has several
1643
solutions, then false is returned. If it has no solution, then fail is
1644
returned. Otherwise a board with the unique solution is returned.
1645
1646
 Example 
1647
gap> s := " 5 | 154 6 2 |9 5 3 |6 4 | 8 |8 9 53\
1648
> | 5 | 4 7 2| 91 8 ";;
1649
gap> sol := Sudoku.UniqueSolution(Sudoku.Init(s));;
1650
gap> Sudoku.SimpleDisplay(sol);
1651
438|219|576
1652
715|436|928
1653
962|758|314
1654
-----------
1655
694|573|281
1656
153|862|749
1657
827|941|653
1658
-----------
1659
281|695|437
1660
546|387|192
1661
379|124|865
1662

1663
1664
6.17-8 PlaySudoku
1665
1666
PlaySudoku( [arg] )  function
1667
Returns: A record describing the latest status of a Sudoku board.
1668
1669
This function allows one to solve Sudoku puzzles interactively. There are
1670
several possibilities for the optional argument arg. It can either be a
1671
string, matrix or list of holes and integers as described in Sudoku.Init
1672
(6.17-1), or a board as returned by Sudoku.Init (6.17-1). Furthermore arg
1673
can be an integer or not be given, in that case Sudoku.RandomGame (6.17-3)
1674
is called to produce a random game.
1675
1676
The usage of this function is self-explanatory, pressing the ? key displays
1677
a help screen. Here, we mention two keys with a particular action: Pressing
1678
the h key you get a hint, either an empty entry is filled or the program
1679
tells you that there is no solution (so you must delete some entries and try
1680
others). Pressing the s key the puzzle is solved by the program or it tells
1681
you that there is no or no unique solution.
1682
1683
Implementation remarks: The game board is implemented via a browse table,
1684
without row and column labels, with static header, dynamic footer, and
1685
individual minyx function. Two modes are supported, with the standard
1686
actions for quitting the table and asking for help; one cell is selected in
1687
each mode. The first mode provides actions for moving the selected cell via
1688
arrow keys, for changing the value in the selected cell, for getting a hint
1689
or the (unique) solution. (Initial entries of the matrix cannot be changed
1690
via user input. They are shown in boldface.) The second mode serves for
1691
error handling: When the user enters an invalid number, i. e., a number that
1692
occurs already in the current row or column or subsquare, then the
1693
application switches to this mode, which causes that a message is shown in
1694
the footer, and the invalid entry is shown in red and blinking; similarly,
1695
error mode is entered if a hint or solution does not exist.
1696
1697
The separating lines are drawn using an individual SpecialGrid function in
1698
the browse table, since they cannot be specified within the generic browse
1699
table functions.
1700
1701
Some standard NCurses.BrowseGeneric (4.3-1) functionality, such as
1702
scrolling, selecting, and searching, are not available in this application.
1703
1704
The code can be found in the file app/sudoku.g of the package.
1705
1706
6.17-9 Sudoku.HTMLGame
1707
1708
Sudoku.HTMLGame( game )  function
1709
Sudoku.LaTeXGame( game )  function
1710
Returns: A string with HTML or LaTeX code, respectively.
1711
1712
The argument of these functions is a record describing a Sudoku game. These
1713
functions return code for including the current status of the board into a
1714
webpage or a LaTeX document.
1715
1716
1717
6.18 Utility for GAP Demos
1718
1719
This application can be used with GAP if the user interface has readline
1720
support. The purpose is to simplify the typing during a demonstration of GAP
1721
commands.
1722
1723
The file format to specify GAP code for a demonstration is very simple: it
1724
contains blocks of lines with GAP input, separated by lines starting with a
1725
% character. Comments in such a file can be added to one or several lines
1726
starting with %. Here is the content of an example file demo.demo:
1727
1728
% Add comments after a % character at the beginning of a line.
1729
% A comment can have several lines.
1730
% Here is a multi-line input block:
1731
g := MathieuGroup(11);;
1732
cl := ConjugacyClasses(g);
1733
% Calling a help page
1734
?MathieuGroup
1735
% The next line contains a comment in the GAP session:
1736
a := 12;; b := 13;; # assign two numbers
1737
%
1738
a*b;
1739
%
1740
1741
A demonstration can be loaded into a GAP session with the command
1742
1743
6.18-1 LoadDemoFile
1744
1745
LoadDemoFile( demoname, demofile[, singleline] )  function
1746
Returns: Nothing.
1747
1748
This function loads a demo file in the format described above. The argument
1749
demoname is a string containing a name for the demo, and demofile is the
1750
file name containing the demo.
1751
1752
If the optional argument singleline is given and its value is true, the demo
1753
behaves differently with respect to input blocks that span several lines. By
1754
default full blocks are treated as a single input line for readline (maybe
1755
spanning several physical lines in the terminal). If singleline is true then
1756
all input lines of a block except the last one are sent to GAP and are
1757
evaluated automatically before the last line of the block is displayed.
1758
1759
 Example 
1760
gap> dirs := DirectoriesPackageLibrary("Browse");;
1761
gap> demofile := Filename(dirs, "../app/demo.demo");;
1762
gap> LoadDemoFile("My first demo", demofile);
1763
gap> LoadDemoFile("My first demo (single lines)", demofile, true);
1764

1765
1766
Many demos can be loaded at the same time. They are used with the PageDown
1767
and PageUp keys.
1768
1769
The PageUp key leads to a (Browse) menu which allows one to choose a demo to
1770
start (if several are loaded), to stop a demo or to move to another position
1771
in the current demo (e.g., to go back to a previous point or to skip part of
1772
a demo).
1773
1774
The next input block of the current demo is copied into the current input
1775
line of the GAP session by pressing the PageDown key. This line is not yet
1776
sent to GAP, use the Return key if you want to evaluate the input. (You can
1777
also still edit the input line before evaluation.)
1778
1779
So, in the simplest case a demo can be done by just pressing PageDown and
1780
Return in turns. But it is always possible to type extra input during a demo
1781
by hand or to change the input lines from the demo file before evaluation.
1782
It is no problem if commands are interrupted by Ctrl-C. During a demo you
1783
are in a normal GAP session, this application only saves you some typing.
1784
The input lines from the demo are put into the history of the session as if
1785
they were typed by hand.
1786
1787
Try it yourself with the two demos loaded in the example. This also shows
1788
the different behaviour between default and single line mode.
1789
1790
1791