File: chap6_mj.html

package info (click to toggle)
gap-browse 1.8.21%2Bdfsg-1
  • links: PTS
  • area: main
  • in suites: forky, sid, trixie
  • size: 8,296 kB
  • sloc: xml: 1,961; ansic: 1,342; makefile: 163; javascript: 155; sh: 20
file content (1544 lines) | stat: -rw-r--r-- 163,310 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
         "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<script type="text/javascript"
  src="https://cdn.jsdelivr.net/npm/mathjax@2/MathJax.js?config=TeX-AMS-MML_HTMLorMML">
</script>
<title>GAP (Browse) - Chapter 6: Examples of Applications based on NCurses.BrowseGeneric
</title>
<meta http-equiv="content-type" content="text/html; charset=UTF-8" />
<meta name="generator" content="GAPDoc2HTML" />
<link rel="stylesheet" type="text/css" href="manual.css" />
<script src="manual.js" type="text/javascript"></script>
<script type="text/javascript">overwriteStyle();</script>
</head>
<body class="chap6"  onload="jscontent()">


<div class="chlinktop"><span class="chlink1">Goto Chapter: </span><a href="chap0_mj.html">Top</a>  <a href="chap1_mj.html">1</a>  <a href="chap2_mj.html">2</a>  <a href="chap3_mj.html">3</a>  <a href="chap4_mj.html">4</a>  <a href="chap5_mj.html">5</a>  <a href="chap6_mj.html">6</a>  <a href="chapA_mj.html">A</a>  <a href="chapBib_mj.html">Bib</a>  <a href="chapInd_mj.html">Ind</a>  </div>

<div class="chlinkprevnexttop">&nbsp;<a href="chap0_mj.html">[Top of Book]</a>&nbsp;  <a href="chap0_mj.html#contents">[Contents]</a>&nbsp;  &nbsp;<a href="chap5_mj.html">[Previous Chapter]</a>&nbsp;  &nbsp;<a href="chapA_mj.html">[Next Chapter]</a>&nbsp;  </div>

<p id="mathjaxlink" class="pcenter"><a href="chap6.html">[MathJax off]</a></p>
<p><a id="X78D4F8EA79405AF9" name="X78D4F8EA79405AF9"></a></p>
<div class="ChapSects"><a href="chap6_mj.html#X78D4F8EA79405AF9">6 <span class="Heading">Examples of Applications based on <code class="code">NCurses.BrowseGeneric</code>
</span></a>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X813F90F7815AB5B3">6.1 <span class="Heading">The Operation <code class="code">Browse</code></span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7FDD696B7DD54A6E">6.1-1 Browse</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X7F6EE19480D10E2B">6.2 <span class="Heading">Matrix Display</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X8295F85D87118C83">6.2-1 NCurses.BrowseDenseList</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7AD78A0B7BEDBB20">6.2-2 Browse</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X8720923F7FDE5223">6.3 <span class="Heading">Character Table Display</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X870C744182073CF6">6.3-1 Browse</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7D80A56D853C9655">6.3-2 BrowseDecompositionMatrix</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X80E9A03780DE8891">6.4 <span class="Heading">Table of Marks Display</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7F4BD9C580BBBAA4">6.4-1 Browse</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X80370827793813FD">6.5 <span class="Heading">Table of Contents of <strong class="pkg">AtlasRep</strong></span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X8411AF928194C5AB">6.5-1 <span class="Heading">BrowseAtlasInfo</span></a>
</span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X7CF999297B331E01">6.6 <span class="Heading">Access to <strong class="pkg">GAP</strong> Manuals–a Variant</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7D79DF9181A15EDF">6.6-1 BrowseGapManuals</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X846751CC7F54F51D">6.7 <span class="Heading">Overview of Bibliographies</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7F0FE4CC7F46ABF3">6.7-1 BrowseBibliography</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7E4B5E277D08987B">6.7-2 BrowseBibliographyGapPackages</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X81F1558678ACDB4A">6.7-3 BrowseMSC</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X837BDF547FF0EA31">6.8 <span class="Heading">Profiling <strong class="pkg">GAP</strong> functions–a Variant</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7B42091982DE7AE7">6.8-1 BrowseProfile</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X87B30F7387C0E531">6.9 <span class="Heading">Variables defined in <strong class="pkg">GAP</strong> packages–a Variant</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X8030B1688335783D">6.9-1 BrowsePackageVariables</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X7CD025147D528741">6.10 <span class="Heading">Configuring User preferences–a Variant</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7A7B712E7A06449F">6.10-1 BrowseUserPreferences</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X86C730A07855238D">6.11 <span class="Heading">Overview of <strong class="pkg">GAP</strong> Data</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X850C786C87A4877B">6.11-1 BrowseGapData</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7FC24FCE7A0C6058">6.11-2 BrowseGapDataAdd</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X7E3FDA927E62D963">6.12 <span class="Heading">Navigating in a Directory Tree</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X859682DE8397261E">6.12-1 BrowseDirectory</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X7FAE33037D09CC4E">6.13 <span class="Heading">A Puzzle</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7EF5FCBD7DAFFAF3">6.13-1 BrowsePuzzle</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X7FFF943D78A403C9">6.14 <span class="Heading">Peg Solitaire</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X82C8691380FCB674">6.14-1 PegSolitaire</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X862CB73B7E0BE170">6.15 <span class="Heading">Rubik's Cube</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X8100659E81FFE9A2">6.15-1 BrowseRubiksCube</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X7ADD618186541123">6.16 <span class="Heading">Changing Sides</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7FCFC5858584F46E">6.16-1 BrowseChangeSides</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X7DDE46668321B5E9">6.17 <span class="Heading">Sudoku</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X789D3D4C818F4BC2">6.17-1 Sudoku.Init</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X86A5C6CE79DD67EE">6.17-2 Sudoku.Place</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X8401B31A879F9F9F">6.17-3 Sudoku.RandomGame</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X86917AC57C25A68F">6.17-4 Sudoku.SimpleDisplay</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X81F98C6C7C8415AB">6.17-5 Sudoku.DisplayString</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7C73C6D08293B3B8">6.17-6 Sudoku.OneSolution</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X865DDBDC7E16217F">6.17-7 Sudoku.UniqueSolution</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7D19224478E86BB4">6.17-8 PlaySudoku</a></span>
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X804D66D67B908F30">6.17-9 Sudoku.HTMLGame</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X78E8DF8381626623">6.18 <span class="Heading">Managing simple Workflows</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X7E47FC2378C276C6">6.18-1 <span class="Heading">BrowseWizard</span></a>
</span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss">&nbsp;</span><a href="chap6_mj.html#X7BCE1AE37EFCE91D">6.19 <span class="Heading">Utility for <strong class="pkg">GAP</strong> Demos</span></a>
</span>
<div class="ContSSBlock">
<span class="ContSS"><br /><span class="nocss">&nbsp;&nbsp;</span><a href="chap6_mj.html#X80F418C5835C62BA">6.19-1 LoadDemoFile</a></span>
</div></div>
</div>

<h3>6 <span class="Heading">Examples of Applications based on <code class="code">NCurses.BrowseGeneric</code>
</span></h3>

<p>This chapter introduces the operation <code class="func">Browse</code> (<a href="chap6_mj.html#X7FDD696B7DD54A6E"><span class="RefLink">6.1-1</span></a>) and lists several examples how the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) can be utilized for rendering <strong class="pkg">GAP</strong> related data or for playing games. Each section describes the relevant <strong class="pkg">GAP</strong> functions and briefly sketches the technical aspects of the implementation; more details can be found in the <strong class="pkg">GAP</strong> files, in the <code class="file">app</code> directory of the package.</p>

<p>Only Section <a href="chap6_mj.html#X80E9A03780DE8891"><span class="RefLink">6.4</span></a> describes a standard application in the sense of the introduction to Chapter <a href="chap4_mj.html#X877E60DE7F53FDEC"><span class="RefLink">4</span></a>, perhaps except for a special function that is needed to compare table entries. The other examples in this chapter require some of the programming described in Chapter <a href="chap5_mj.html#X82DDDC1783B4CA30"><span class="RefLink">5</span></a>.</p>

<p>The <strong class="pkg">GAP</strong> examples in this chapter use the "replay" feature of <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>), see Section <a href="chap4_mj.html#X869EDB308717F199"><span class="RefLink">4.1</span></a>. This means that the <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) based function is called between two calls of <code class="func">BrowseData.SetReplay</code> (<a href="chap5_mj.html#X791FB5BA7A9951F4"><span class="RefLink">5.4-2</span></a>). If you want to paste these examples into the <strong class="pkg">GAP</strong> session with the mouse then do not paste the final <code class="func">BrowseData.SetReplay</code> (<a href="chap5_mj.html#X791FB5BA7A9951F4"><span class="RefLink">5.4-2</span></a>) call, since <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) would regard the additional input as a user interrupt.</p>

<p><a id="X813F90F7815AB5B3" name="X813F90F7815AB5B3"></a></p>

<h4>6.1 <span class="Heading">The Operation <code class="code">Browse</code></span></h4>

<p><a id="X7FDD696B7DD54A6E" name="X7FDD696B7DD54A6E"></a></p>

<h5>6.1-1 Browse</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Browse</code>( <var class="Arg">obj</var>[, <var class="Arg">arec</var>] )</td><td class="tdright">(&nbsp;operation&nbsp;)</td></tr></table></div>
<p>This operation displays the <strong class="pkg">GAP</strong> object <var class="Arg">obj</var> in a nice, formatted way, similar to the operation <code class="func">Display</code> (<a href="../../../doc/ref/chap6_mj.html#X83A5C59278E13248"><span class="RefLink">Reference: Display</span></a>). The difference is that <code class="func">Browse</code> is intended to use <code class="code">ncurses</code> facilities.</p>

<p>Currently there are methods for matrices (see <code class="func">Browse</code> (<a href="chap6_mj.html#X7AD78A0B7BEDBB20"><span class="RefLink">6.2-2</span></a>)), for character tables (see <code class="func">Browse</code> (<a href="chap6_mj.html#X870C744182073CF6"><span class="RefLink">6.3-1</span></a>)) and for tables of marks (see <code class="func">Browse</code> (<a href="chap6_mj.html#X7F4BD9C580BBBAA4"><span class="RefLink">6.4-1</span></a>)).</p>

<p><a id="X7F6EE19480D10E2B" name="X7F6EE19480D10E2B"></a></p>

<h4>6.2 <span class="Heading">Matrix Display</span></h4>

<p>The <strong class="pkg">GAP</strong> library provides several <code class="func">Display</code> (<a href="../../../doc/ref/chap6_mj.html#X83A5C59278E13248"><span class="RefLink">Reference: Display</span></a>) methods for matrices. In order to cover the functionality of these methods, <strong class="pkg">Browse</strong> provides the function <code class="func">NCurses.BrowseDenseList</code> (<a href="chap6_mj.html#X8295F85D87118C83"><span class="RefLink">6.2-1</span></a>) that uses the standard facilities of the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>), i. e., one can scroll in the matrix, searching and sorting are provided etc.</p>

<p>The idea is to customize this function for different special cases, and to install corresponding <code class="func">Browse</code> (<a href="chap6_mj.html#X7FDD696B7DD54A6E"><span class="RefLink">6.1-1</span></a>) methods. Examples are methods for matrices over finite fields and residue class rings of the rational integers, see <code class="func">Browse</code> (<a href="chap6_mj.html#X7AD78A0B7BEDBB20"><span class="RefLink">6.2-2</span></a>).</p>

<p>The code can be found in the file <code class="file">app/matdisp.g</code> of the package.</p>

<p><a id="X8295F85D87118C83" name="X8295F85D87118C83"></a></p>

<h5>6.2-1 NCurses.BrowseDenseList</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; NCurses.BrowseDenseList</code>( <var class="Arg">list</var>, <var class="Arg">arec</var> )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: nothing.</p>

<p>Let <var class="Arg">list</var> be a dense list whose entries are lists, for example a matrix, and let <var class="Arg">arec</var> be a record. This function displays <var class="Arg">list</var> in a window, as a two-dimensional array with row and column positions as row and column labels, respectively.</p>

<p>The following components of <var class="Arg">arec</var> are supported.</p>


<dl>
<dt><strong class="Mark"><code class="code">header</code></strong></dt>
<dd><p>If bound, the value must be a valid value of the <code class="code">work.header</code> component of a browse table, see <code class="func">BrowseData.IsBrowseTable</code> (<a href="chap4_mj.html#X81007E2F8552523B"><span class="RefLink">4.2-3</span></a>); for example, the value can be a list of strings. If this component is not bound then the browse table has no header.</p>

</dd>
<dt><strong class="Mark"><code class="code">footer</code></strong></dt>
<dd><p>If bound, the value must be a valid value of the <code class="code">work.footer</code> component of a browse table, see <code class="func">BrowseData.IsBrowseTable</code> (<a href="chap4_mj.html#X81007E2F8552523B"><span class="RefLink">4.2-3</span></a>); for example, the value can be a list of strings. If this component is not bound then the browse table has no footer.</p>

</dd>
<dt><strong class="Mark"><code class="code">convertEntry</code></strong></dt>
<dd><p>If bound, the value must be a unary function that returns a string describing its argument. The default is the operation <code class="func">String</code> (<a href="../../../doc/ref/chap27_mj.html#X81FB5BE27903EC32"><span class="RefLink">Reference: String</span></a>). Another possible value is <code class="code">NCurses.ReplaceZeroByDot</code>, which returns the string <code class="code">"."</code> if the argument is a zero element in the sense of <code class="func">IsZero</code> (<a href="../../../doc/ref/chap31_mj.html#X82BDA47282F9BBA7"><span class="RefLink">Reference: IsZero</span></a>), and returns the <code class="func">String</code> (<a href="../../../doc/ref/chap27_mj.html#X81FB5BE27903EC32"><span class="RefLink">Reference: String</span></a>) value otherwise. For each entry in a row of <var class="Arg">list</var>, the <code class="code">convertEntry</code> value is shown in the browse table.</p>

</dd>
<dt><strong class="Mark"><code class="code">labelsRow</code></strong></dt>
<dd><p>If bound, the value must be a list of row label rows for <var class="Arg">list</var>, as described in Section <code class="func">BrowseData.IsBrowseTable</code> (<a href="chap4_mj.html#X81007E2F8552523B"><span class="RefLink">4.2-3</span></a>). The default is <code class="code">[ [ "1" ], [ "2" ], ... ]</code>.</p>

</dd>
<dt><strong class="Mark"><code class="code">labelsCol</code></strong></dt>
<dd><p>If bound, the value must be a list of column label rows for <var class="Arg">list</var>, as described in Section <code class="func">BrowseData.IsBrowseTable</code> (<a href="chap4_mj.html#X81007E2F8552523B"><span class="RefLink">4.2-3</span></a>). The default is <code class="code">[ [ "1", "2", ... ] ]</code>.</p>

</dd>
</dl>
<p>The full functionality of the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) is available.</p>

<p><a id="X7AD78A0B7BEDBB20" name="X7AD78A0B7BEDBB20"></a></p>

<h5>6.2-2 Browse</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Browse</code>( <var class="Arg">list</var> )</td><td class="tdright">(&nbsp;method&nbsp;)</td></tr></table></div>
<p>Returns: nothing.</p>

<p>Several methods for the operation <code class="func">Browse</code> (<a href="chap6_mj.html#X7FDD696B7DD54A6E"><span class="RefLink">6.1-1</span></a>) are installed for the case that the argument is a list of lists. These methods cover a default method for lists of lists and the <code class="func">Display</code> (<a href="../../../doc/ref/chap6_mj.html#X83A5C59278E13248"><span class="RefLink">Reference: Display</span></a>) methods for matrices over finite fields and residue class rings of the rational integers. Note that matrices over finite prime fields, small extension fields, and large extension fields are displayed differently, and the same holds for the corresponding <code class="func">Browse</code> (<a href="chap6_mj.html#X7FDD696B7DD54A6E"><span class="RefLink">6.1-1</span></a>) methods.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">n:= [ 14, 14, 14, 14 ];;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">input:= Concatenation( n, n, n, "Q" );;  # ``do nothing and quit''</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( input );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">Browse( RandomMat( 10, 10, Integers ) );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( input );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">Browse( RandomMat( 10, 10, GF(3) ) );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( input );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">Browse( RandomMat( 10, 10, GF(4) ) );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( input );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">Browse( RandomMat( 10, 10, Integers mod 6 ) );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( input );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">Browse( RandomMat( 10, 10, GF( NextPrimeInt( 2^16 ) ) ) );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( input );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">Browse( RandomMat( 10, 10, GF( 2^20 ) ) );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
</pre></div>

<p><a id="X8720923F7FDE5223" name="X8720923F7FDE5223"></a></p>

<h4>6.3 <span class="Heading">Character Table Display</span></h4>

<p>The <strong class="pkg">GAP</strong> library provides a <code class="func">Display</code> (<a href="../../../doc/ref/chap6_mj.html#X83A5C59278E13248"><span class="RefLink">Reference: Display</span></a>) method for character tables that breaks the table into columns fitting on the screen. <strong class="pkg">Browse</strong> provides an alternative, using the standard facilities of the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>), i. e., one can scroll in the matrix of character values, searching and sorting are provided etc.</p>

<p>The <code class="func">Browse</code> (<a href="chap6_mj.html#X7FDD696B7DD54A6E"><span class="RefLink">6.1-1</span></a>) method for character tables can be called instead of <code class="func">Display</code> (<a href="../../../doc/ref/chap6_mj.html#X83A5C59278E13248"><span class="RefLink">Reference: Display</span></a>). For convenience, one can additionally make this function the default <code class="func">Display</code> (<a href="../../../doc/ref/chap6_mj.html#X83A5C59278E13248"><span class="RefLink">Reference: Display</span></a>) method for character tables, by assigning it to the <code class="code">Display</code> component in the global record <code class="code">CharacterTableDisplayDefaults.User</code>, see <a href="../../../doc/ref/chap71_mj.html#X7C1941F17BE9FC21"><span class="RefLink">Reference: Printing Character Tables</span></a>; for example, one can do this in one's <code class="file">gaprc</code> file, see <a href="../../../doc/ref/chap3_mj.html#X7FD66F977A3B02DF"><span class="RefLink">Reference: The gap.ini and gaprc files</span></a>. (This can be undone by unbinding the component <code class="code">CharacterTableDisplayDefaults.User.Display</code>.)</p>

<p>The function <code class="func">BrowseDecompositionMatrix</code> (<a href="chap6_mj.html#X7D80A56D853C9655"><span class="RefLink">6.3-2</span></a>) can be used to display decomposition matrices for Brauer character tables.</p>

<p><a id="X870C744182073CF6" name="X870C744182073CF6"></a></p>

<h5>6.3-1 Browse</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Browse</code>( <var class="Arg">tbl</var>[, <var class="Arg">options</var>] )</td><td class="tdright">(&nbsp;method&nbsp;)</td></tr></table></div>
<p>This method displays the character table <var class="Arg">tbl</var> in a window. The optional record <var class="Arg">options</var> describes what shall be displayed, the supported components and the default values are described in <a href="../../../doc/ref/chap71_mj.html#X7C1941F17BE9FC21"><span class="RefLink">Reference: Printing Character Tables</span></a>.</p>

<p>The full functionality of the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) is available.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">if TestPackageAvailability( "CTblLib" ) = true then</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # scroll in the table</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "DRULdddddrrrrrlluu",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # select an entry and move it around</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "seddrruuuddlll",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # search for the pattern 135 (six times)</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "/135", [ NCurses.keys.ENTER ], "nnnnn",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # deselect the entry, select the first column</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "qLsc",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # sort and categorize by this column</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "sc",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # select the first row, move down the selection</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "srdddd",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # expand the selected category, scroll the selection down</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "xd",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # and quit the application</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "Q" ) );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     Browse( CharacterTable( "HN" ) );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     BrowseData.SetReplay( false );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">fi;</span>
</pre></div>

<p><em>Implementation remarks</em>: The first part of the code in the <code class="func">Browse</code> (<a href="chap6_mj.html#X7FDD696B7DD54A6E"><span class="RefLink">6.1-1</span></a>) method for character tables is almost identical with the code for extracting the data to be displayed from the input data in the <strong class="pkg">GAP</strong> library function <code class="code">CharacterTableDisplayDefault</code>. The second part of the code transforms these data into a browse table. Character names and (if applicable) indicator values are used as row labels, and centralizer orders, power maps, and class names are used as column labels. The identifier of the table is used as the static header. When an irrational entry is selected, a description of this entry is shown in the dynamic footer.</p>

<p>The standard modes in <code class="func">BrowseData</code> (<a href="chap5_mj.html#X86E80E578085F137"><span class="RefLink">5.4-1</span></a>) (except the <code class="code">help</code> mode) have been extended by three new actions. The first two of them open pagers giving an overview of all irrationalities in the table, or of all those irrationalities that have been shown on the screen in the current call, respectively. The corresponding user inputs are the <strong class="button">I</strong> and the <strong class="button">i</strong> key. (The names assigned to the irrationalities are generated column-wise. If one just scrolls through the table, without jumping, then these names coincide with the names generated by the default <code class="func">Display</code> (<a href="../../../doc/ref/chap6_mj.html#X83A5C59278E13248"><span class="RefLink">Reference: Display</span></a>) method for character tables; this is in general <em>not</em> the case, for example when a row-wise search in the table is performed.) The third new action, which is associated with the <strong class="button">p</strong> key, toggles the visibility status of the column label rows for centralizer orders and power maps.</p>

<p>An individual <code class="code">minyx</code> function does not only check whether the desired table fits into the window but also whether a table with too high column labels (centralizer orders and power maps) would fit if these labels get collapsed via the <strong class="button">p</strong> key. In this case, the labels are automatically collapsed, and the <strong class="button">p</strong> key is disabled.</p>

<p>In order to keep the required space small also for large character tables, caching of formatted matrix entries is disabled, and the strings to be displayed are computed on demand with a <code class="code">Main</code> function in the <code class="code">work</code> component of the browse table. For the same reason, the constant height one for all table rows is set in advance, so one need not inspect a whole character if only a few values of it shall be shown.</p>

<p>Special functions are provided for sorting (concerning the comparison of character values, which can be integers or irrationalities) and categorizing the table by a column (the value in the category row involves the class name of the column in question).</p>

<p>The code can be found in the file <code class="file">app/ctbldisp.g</code> of the package.</p>

<p><a id="X7D80A56D853C9655" name="X7D80A56D853C9655"></a></p>

<h5>6.3-2 BrowseDecompositionMatrix</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseDecompositionMatrix</code>( <var class="Arg">modtbl</var>[, <var class="Arg">b</var>][, <var class="Arg">options</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>This method displays the decomposition matrix of (the <var class="Arg">b</var>-th block of) the Brauer character table <var class="Arg">modtbl</var> in a window. The arguments are the same as for <code class="func">LaTeXStringDecompositionMatrix</code> (<a href="../../../doc/ref/chap71_mj.html#X83EC921380AF9B3B"><span class="RefLink">Reference: LaTeXStringDecompositionMatrix</span></a>).</p>

<p>The positions of the ordinary and modular irreducible characters are shown in the labels of the rows and columns, respectively, that are indexed by these characters. When an entry in the decomposition matrix is selected then information about the degrees of these characters is shown in the table footer.</p>

<p>The full functionality of the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) is available.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # select the first entry</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "se",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # scroll in the table</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "drrrr",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # keep the table open for a while</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        [ 14, 14, 14, 14, 14 ],</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # and quit the application</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "Q" ) );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseDecompositionMatrix( CharacterTable( "J1" ) mod 2 );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
</pre></div>

<p>The code can be found in the file <code class="file">app/ctbldisp.g</code> of the package.</p>

<p><a id="X80E9A03780DE8891" name="X80E9A03780DE8891"></a></p>

<h4>6.4 <span class="Heading">Table of Marks Display</span></h4>

<p>The <strong class="pkg">GAP</strong> library provides a <code class="func">Display</code> (<a href="../../../doc/ref/chap6_mj.html#X83A5C59278E13248"><span class="RefLink">Reference: Display</span></a>) method for tables of marks that breaks the table into columns fitting on the screen. Similar to the situation with character tables, see Section <a href="chap6_mj.html#X8720923F7FDE5223"><span class="RefLink">6.3</span></a>, but with a much simpler implementation, <strong class="pkg">Browse</strong> provides an alternative based on the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>).</p>

<p><code class="func">Browse</code> (<a href="chap6_mj.html#X7FDD696B7DD54A6E"><span class="RefLink">6.1-1</span></a>) can be called instead of <code class="func">Display</code> (<a href="../../../doc/ref/chap6_mj.html#X83A5C59278E13248"><span class="RefLink">Reference: Display</span></a>) for tables of marks, cf. <a href="../../../doc/ref/chap70_mj.html#X7AC0FB9685DCBCFD"><span class="RefLink">Reference: Printing Tables of Marks</span></a>.</p>

<p><a id="X7F4BD9C580BBBAA4" name="X7F4BD9C580BBBAA4"></a></p>

<h5>6.4-1 Browse</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Browse</code>( <var class="Arg">tom</var>[, <var class="Arg">options</var>] )</td><td class="tdright">(&nbsp;method&nbsp;)</td></tr></table></div>
<p>This method displays the table of marks <var class="Arg">tom</var> in a window. The optional record <var class="Arg">options</var> describes what shall be displayed, the supported components and the default values are described in <a href="../../../doc/ref/chap70_mj.html#X7AC0FB9685DCBCFD"><span class="RefLink">Reference: Printing Tables of Marks</span></a>.</p>

<p>The full functionality of the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) is available.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">if TestPackageAvailability( "TomLib" ) = true then</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # scroll in the table</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "DDRRR",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # search for the (exact) value 100 (three times)</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "/100",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        [ NCurses.keys.DOWN, NCurses.keys.DOWN, NCurses.keys.RIGHT ],</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        [ NCurses.keys.DOWN, NCurses.keys.DOWN, NCurses.keys.DOWN ],</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        [ NCurses.keys.RIGHT, NCurses.keys.ENTER ], "nn",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # no more occurrences of 100, confirm</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        [ NCurses.keys.ENTER ],</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        # and quit the application</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">        "Q" ) );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     Browse( TableOfMarks( "A10" ) );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     BrowseData.SetReplay( false );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">   fi;</span>
</pre></div>

<p><em>Implementation remarks</em>: Rows and columns are indexed by their positions. The identifier of the table is used as the static header, there is no footer.</p>

<p>In order to keep the required space small also for large tables of marks, caching of formatted matrix entries is disabled, and the strings to be displayed are computed on demand with a <code class="code">Main</code> function in the <code class="code">work</code> component of the browse table. For the same reason, the constant height one for the table rows is set in advance. (For example, the table of marks of the group with identifier <code class="code">"O8+(2)"</code>, with <span class="SimpleMath">\(11171\)</span> rows and columns, can be shown with <code class="func">Browse</code> (<a href="chap6_mj.html#X7FDD696B7DD54A6E"><span class="RefLink">6.1-1</span></a>) in a <strong class="pkg">GAP</strong> session requiring about <span class="SimpleMath">\(100\)</span> MB.)</p>

<p>The code can be found in the file <code class="file">app/tomdisp.g</code> of the package.</p>

<p><a id="X80370827793813FD" name="X80370827793813FD"></a></p>

<h4>6.5 <span class="Heading">Table of Contents of <strong class="pkg">AtlasRep</strong></span></h4>

<p>The <strong class="pkg">GAP</strong> package <strong class="pkg">AtlasRep</strong> (see <a href="chapBib_mj.html#biBAtlasRep">[WPN+19]</a>) is an interface to a database of representations and related data. The table of contents of this database can be displayed via the function <code class="func">DisplayAtlasInfo</code> (<a href="../../../pkg/atlasrep/doc/chap3_mj.html#X79DACFFA7E2D1A99"><span class="RefLink">AtlasRep: DisplayAtlasInfo</span></a>) of this package. The <strong class="pkg">Browse</strong> package provides an alternative based on the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>); one can scroll, search, and fetch data for later use.</p>

<p><a id="X8411AF928194C5AB" name="X8411AF928194C5AB"></a></p>

<h5>6.5-1 <span class="Heading">BrowseAtlasInfo</span></h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseAtlasInfo</code>( [<var class="Arg">listofnames</var>][,] [<var class="Arg">"contents"</var>, <var class="Arg">sources</var>][,] [<var class="Arg">...</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseAtlasInfo</code>( <var class="Arg">gapname</var>[, <var class="Arg">std</var>][, <var class="Arg">...</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: the list of "clicked" info records.</p>

<p>This function shows the information available via the <strong class="pkg">GAP</strong> package <strong class="pkg">AtlasRep</strong> in a browse table, cf. Section <a href="../../../pkg/atlasrep/doc/chap3_mj.html#X7CC88B2287A72204"><span class="RefLink">AtlasRep: Accessing Data via AtlasRep</span></a> in the <strong class="pkg">AtlasRep</strong> manual.</p>

<p>The optional arguments can be used to restrict the table to core data or data extensions, or to show an overview for one particular group. The arguments are the same as for <code class="func">DisplayAtlasInfo</code> (<a href="../../../pkg/atlasrep/doc/chap3_mj.html#X79DACFFA7E2D1A99"><span class="RefLink">AtlasRep: DisplayAtlasInfo</span></a>), see the documentation of this function for details. (Note that additional conditions such as <code class="func">IsPermGroup</code> (<a href="../../../doc/ref/chap43_mj.html#X7879877482F59676"><span class="RefLink">Reference: IsPermGroup</span></a>) can be entered also in the case that no <var class="Arg">gapname</var> is given. In this situation, the additional conditions are evaluated for the "second level tables" that are opened by "clicking" on a table row or entry.)</p>

<p>When one "clicks" 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 "clicking" on one of the rows in these tables adds the corresponding info record (see <code class="func">OneAtlasGeneratingSetInfo</code> (<a href="../../../pkg/atlasrep/doc/chap3_mj.html#X841478AB7CD06D44"><span class="RefLink">AtlasRep: OneAtlasGeneratingSetInfo</span></a>)) to the list of return values of <code class="func">BrowseAtlasInfo</code>.</p>

<p>The full functionality of the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) is available.</p>

<p>The following example shows how <code class="func">BrowseAtlasInfo</code> can be used to fetch info records about permutation representations of the alternating groups <span class="SimpleMath">\(A_5\)</span> and <span class="SimpleMath">\(A_6\)</span>: We search for the group name <code class="code">"A5"</code> in the overview table, and the first cell in the table row for <span class="SimpleMath">\(A_5\)</span> becomes selected; hitting the <strong class="button">Enter</strong> key causes a new window to be opened, with an overview of the data available for <span class="SimpleMath">\(A_5\)</span>; moving down two rows and hitting the <strong class="button">Enter</strong> key again causes the second representation to be added to the result list; hitting <strong class="button">Q</strong> closes the second window, and we are back in the overview table; we move the selection down twice (to the row for the group <span class="SimpleMath">\(A_6\)</span>), 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>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">d:= [ NCurses.keys.DOWN ];;  r:= [ NCurses.keys.RIGHT ];;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">c:= [ NCurses.keys.ENTER ];;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "/A5",         # Find the string A5 ...</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       d, d, r,       # ... such that just the word matches,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,             # start the search,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,             # click the table entry A5,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       d, d,          # move down two rows,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,             # click the row for this representation,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "Q",           # quit the second level table,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       d, d,          # move down two rows,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,             # click the table entry A6,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       d,             # move down one row,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,             # click the first row,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "Q",           # quit the second level table,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "Q" ) );       # and quit the application.</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">if IsBound( BrowseAtlasInfo ) and IsBound( AtlasProgramInfo ) then</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     SetUserPreference( "AtlasRep", "AtlasRepMarkNonCoreData", "" );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     tworeps:= BrowseAtlasInfo();</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">   else</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     tworeps:= [ fail ];</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">   fi;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">if fail in tworeps then</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     Print( "no access to the Web ATLAS\n" );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">   else</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     Print( List( tworeps, x -&gt; x.identifier[1] ), "\n" );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">   fi;</span>
[ "A5", "A6" ]
</pre></div>

<p><em>Implementation remarks</em>: 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>

<p>Row and column separators are drawn as grids (cf. <code class="func">NCurses.Grid</code> (<a href="chap2_mj.html#X790715F683BF1E66"><span class="RefLink">2.2-8</span></a>)) composed from the special characters described in Section <a href="chap2_mj.html#X8091936586CCD248"><span class="RefLink">2.1-6</span></a>, using the component <code class="code">work.SpecialGrid</code> of the browse table, see <code class="func">BrowseData</code> (<a href="chap5_mj.html#X86E80E578085F137"><span class="RefLink">5.4-1</span></a>).</p>

<p>When a row is selected, the "click" functionality opens a new window (via a second level call to <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>)), in which a browse table with the list of available data for the given group is shown; in this table, "click" 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>

<p>For the two kinds of browse tables, the standard modes in <code class="func">BrowseData</code> (<a href="chap5_mj.html#X86E80E578085F137"><span class="RefLink">5.4-1</span></a>) (except the <code class="code">help</code> 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 <strong class="button">Y</strong> key.</p>

<p>This function is available only if the <strong class="pkg">GAP</strong> package <strong class="pkg">AtlasRep</strong> is available.</p>

<p>The code can be found in the file <code class="file">app/atlasbrowse.g</code> of the package.</p>

<p><a id="X7CF999297B331E01" name="X7CF999297B331E01"></a></p>

<h4>6.6 <span class="Heading">Access to <strong class="pkg">GAP</strong> Manuals–a Variant</span></h4>

<p>A <strong class="pkg">Browse</strong> adapted way to access several manuals is to show the hierarchy of books, chapters, sections, and subsections as collapsible category rows, and to regard the contents of each subsection as a data row of a matrix with only one column.</p>

<p>This application is mainly intended as an example with table cells that exceed the screen, and as an example with several category levels.</p>

<p><a id="X7D79DF9181A15EDF" name="X7D79DF9181A15EDF"></a></p>

<h5>6.6-1 BrowseGapManuals</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseGapManuals</code>( [<var class="Arg">start</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>This function displays the contents of the <strong class="pkg">GAP</strong> manuals (the main <strong class="pkg">GAP</strong> manuals as well as the loaded package manuals) in a window. The optional argument <var class="Arg">start</var> describes the initial status, admissible values are the strings <code class="code">"inline/collapsed"</code>, <code class="code">"inline/expanded"</code>, <code class="code">"pager/collapsed"</code>, and <code class="code">"pager/expanded"</code>.</p>

<p>In the <code class="code">inline</code> cases, the parts of the manuals are shown in the browse table, and in the <code class="code">pager</code> case, the parts of the manuals are shown in a different window when they are "clicked", using the user's favourite help viewer, see <a href="../../../doc/ref/chap2_mj.html#X863FF9087EDA8DF9"><span class="RefLink">Reference: Changing the Help Viewer</span></a>.</p>

<p>In the <code class="code">collapsed</code> cases, all category rows are collapsed, and the first row is selected; typical next steps are moving down the selection and expanding single category rows. In the <code class="code">expanded</code> cases, all category rows are expanded, and nothing is selected; a typical next step in the <code class="code">inline/expanded</code> case is a search for a string in the manuals. (Note that searching in quite slow: For viewing a part of a manual, the file with the corresponding section is read into <strong class="pkg">GAP</strong>, the text is formatted, the relevant part is cut out from the section, perhaps markup is stripped off, and finally the search is performed in the resulting strings.)</p>

<p>If no argument is given then the user is asked for selecting an initial status, using <code class="func">NCurses.Select</code> (<a href="chap3_mj.html#X833D321E86528981"><span class="RefLink">3.1-2</span></a>).</p>

<p>The full functionality of the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) is available.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">n:= [ 14, 14, 14 ];;  # ``do nothing''</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "xdxd",                             # expand a Tutorial section</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       n, "Q" ) );                         # and quit</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseGapManuals( "inline/collapsed" );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "/Browse", [ NCurses.keys.ENTER ],  # search for "Browse"</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "xdxddxd",                          # expand a section</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       n, "Q" ) );                         # and quit</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseGapManuals( "inline/collapsed" );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
</pre></div>

<p><em>Implementation remarks</em>: The browse table has a dynamic header showing the name of the currently selected manual, no footer, no row or column labels, and exactly one column of fixed width equal to the screen width. The category rows are precomputed, i. e., they do not arise from a table column; this way, the contents of each data cell can be computed on demand, as soon as it is shown on the screen, in particular the category hierarchy is computed without reading the manuals into <strong class="pkg">GAP</strong>. Also, the data rows are not cached. There is no return value. The heights of many cells are bigger than the screen height, so scrolling is a mixture of scrolling to the next cell and scrolling inside a cell. The different initial states are realized via executing different initial steps before the table is shown to the user.</p>

<p>For the variants that show the manuals in a pager, the code temporarily replaces the <code class="code">show</code> function of the default viewer <code class="code">"screen"</code> (see <a href="../../../doc/ref/chap2_mj.html#X863FF9087EDA8DF9"><span class="RefLink">Reference: Changing the Help Viewer</span></a>) by a function that uses <code class="func">NCurses.Pager</code> (<a href="chap3_mj.html#X87E1B2787F588CC0"><span class="RefLink">3.1-4</span></a>). Note that in the case that the manual bit in question fits into one screen, the default <code class="code">show</code> function writes this text directly to the screen, but this is used already by the browse table.</p>

<p>The implementation should be regarded as a sketch.</p>

<p>For example, the markup available in the text file format of <strong class="pkg">GAPDoc</strong> manuals (using <strong class="button">Esc</strong> sequences) is stripped off instead of being transferred to the attribute lines that arise, because of the highlighting problem mentioned in Section <a href="chap2_mj.html#X81D1FC927C455AEB"><span class="RefLink">2.2-3</span></a>.</p>

<p>Some heuristics used in the code are due to deficiencies of the manual formats.</p>

<p>For the inline variant of the browse table, the titles of chapters, sections, and subsections are <em>not</em> regarded as parts of the actual text since they appear already as category rows; however, the functions of the <strong class="pkg">GAP</strong> help system deliver the text <em>together with</em> these titles, so these lines must be stripped off afterwards.</p>

<p>The category hierarchy representing the tables of contents is created from the <code class="file">manual.six</code> files of the manuals. These files do not contain enough information for determining whether several functions define the same subsection, in the sense that there is a common description text after a series of manual lines introducing different functions. In such cases, the browse table contains a category row for each of these functions (with its own number), but the corresponding text appears only under the <em>last</em> of these category rows, the data rows for the others are empty. (This problem does not occur in the <strong class="pkg">GAPDoc</strong> manual format because this introduces explicit subsection titles, involving only the <em>first</em> of several function definitions.)</p>

<p>Also, index entries and sectioning entries in <code class="file">manual.six</code> files of manuals in <strong class="pkg">GAPDoc</strong> format are not explicitly distinguished.</p>

<p>The code can be found in the file <code class="file">app/manual.g</code> of the package.</p>

<p><a id="X846751CC7F54F51D" name="X846751CC7F54F51D"></a></p>

<h4>6.7 <span class="Heading">Overview of Bibliographies</span></h4>

<p>The function <code class="func">BrowseBibliography</code> (<a href="chap6_mj.html#X7F0FE4CC7F46ABF3"><span class="RefLink">6.7-1</span></a>) can be used to turn the contents of bibliography files in BibTeX or BibXMLext format (see <a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X7FB8F6BD80D859D1"><span class="RefLink">GAPDoc: The BibXMLext Format</span></a>) into a Browse table, such that one can scroll in the list, search for entries, sort by year, sort and categorize by authors etc.</p>

<p>The default bibliography used by <code class="func">BrowseBibliography</code> (<a href="chap6_mj.html#X7F0FE4CC7F46ABF3"><span class="RefLink">6.7-1</span></a>) is the bibliography of <strong class="pkg">GAP</strong> related publications, see <a href="chapBib_mj.html#biBGAPBibliography">[GAP]</a>. The <strong class="pkg">Browse</strong> package contains a (perhaps outdated) version of this bibliography. One can get an updated version as follows.</p>

<p><code class="code">wget -N http://www.gap-system.org/Doc/Bib/gap-publishednicer.bib</code></p>

<p>The columns of the Browse table that is shown by <code class="func">BrowseBibliography</code> (<a href="chap6_mj.html#X7F0FE4CC7F46ABF3"><span class="RefLink">6.7-1</span></a>) can be customized, two examples for that are given by the functions <code class="func">BrowseBibliographySporadicSimple</code> (<a href="../../../pkg/atlasrep/doc/chap3_mj.html#X84ED4FC182C28198"><span class="RefLink">AtlasRep: BrowseBibliographySporadicSimple</span></a>) and <code class="func">BrowseBibliographyGapPackages</code> (<a href="chap6_mj.html#X7E4B5E277D08987B"><span class="RefLink">6.7-2</span></a>).</p>

<p>The function <code class="func">BrowseMSC</code> (<a href="chap6_mj.html#X81F1558678ACDB4A"><span class="RefLink">6.7-3</span></a>) shows an overview of the AMS Mathematics Subject Classification codes.</p>

<p><a id="X7F0FE4CC7F46ABF3" name="X7F0FE4CC7F46ABF3"></a></p>

<h5>6.7-1 BrowseBibliography</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseBibliography</code>( [<var class="Arg">bibfiles</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: a record as returned by <code class="func">ParseBibXMLExtFiles</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X86BD29AE7A453721"><span class="RefLink">GAPDoc: ParseBibXMLextFiles</span></a>).</p>

<p>This function shows the list of bibliography entries in the files given by <var class="Arg">bibfiles</var>, which may be a string or a list of strings (denoting a filename or a list of filenames, respectively) or a record (see below for the supported components).</p>

<p>If no argument is given then the file <code class="file">bibl/gap-publishednicer.bib</code> in the <strong class="pkg">Browse</strong> package directory is taken, and <code class="code">"GAP Bibliography"</code> is used as the header.</p>

<p>Another perhaps interesting data file that should be available in the <strong class="pkg">GAP</strong> distribution is <code class="file">doc/manualbib.xml</code>. This file can be located as follows.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">file:= Filename( DirectoriesLibrary( "doc" ), "manualbib.xml" );;</span>
</pre></div>

<p>Both BibTeX format and the <strong class="pkg">XML</strong> based extended format provided by the <strong class="pkg">GAPDoc</strong> package are supported by <code class="func">BrowseBibliography</code>, see Chapter <a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X7EB94CE97ABF7192"><span class="RefLink">GAPDoc: Utilities for Bibliographies</span></a>.</p>

<p>In the case of BibTeX format input, first a conversion to the extended format takes place, via <code class="func">StringBibAsXMLext</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X85F33C64787A00B7"><span class="RefLink">GAPDoc: StringBibAsXMLext</span></a>) and <code class="func">ParseBibXMLextString</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X86BD29AE7A453721"><span class="RefLink">GAPDoc: ParseBibXMLextString</span></a>). Note that syntactically incorrect entries are rejected in this conversion –this is signaled with <code class="func">InfoBibTools</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X85C1D50F7E37A99A"><span class="RefLink">GAPDoc: InfoBibTools</span></a>) warnings– and that only a subset of the possible LaTeX markup is recognized –other markup appears in the browse table except that the leading backslash is removed.</p>

<p>In both cases of input, the problem arises that in visual mode, currently we can show only ASCII characters (and the symbols in <code class="code">NCurses.lineDraw</code>, but these are handled differently, see Section <a href="chap2_mj.html#X8091936586CCD248"><span class="RefLink">2.1-6</span></a>). Therefore, we use the function <code class="func">SimplifiedUnicodeString</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap6_mj.html#X818A31567EB30A39"><span class="RefLink">GAPDoc: SimplifiedUnicodeString</span></a>) for replacing other unicode characters by ASCII text.</p>

<p>The return value is a record as returned by <code class="func">ParseBibXMLExtFiles</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X86BD29AE7A453721"><span class="RefLink">GAPDoc: ParseBibXMLextFiles</span></a>), its <code class="code">entries</code> component corresponds to the bibliography entries that have been "clicked" in visual mode. This record can be used as input for <code class="func">WriteBibFile</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X7C2B2F65851EAA0B"><span class="RefLink">GAPDoc: WriteBibFile</span></a>) or <code class="func">WriteBibXMLextFile</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X7811108C7E5B1709"><span class="RefLink">GAPDoc: WriteBibXMLextFile</span></a>), in order to produce a bibliography file, or it can be used as input for <code class="func">StringBibXMLEntry</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X790A295680F7CD24"><span class="RefLink">GAPDoc: StringBibXMLEntry</span></a>), in order to produce strings from the entries, in various formats.</p>

<p>The full functionality of the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) is available.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput"># sort and categorize by year, scroll down, expand a category row</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( "scrrscsedddddxdddddQ" );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseBibliography();;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput"># sort &amp; categorize by authors, expand all category rows, scroll down</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( "scscXseddddddQ" );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseBibliography();;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput"># sort and categorize by journal, search for a journal name, expand</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation( "scrrrsc/J. Algebra",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       [ NCurses.keys.ENTER ], "nxdddQ" ) );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseBibliography();;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
</pre></div>

<p><em>Implementation remarks</em>: The browse table has a dynamic header (showing the number of entries, which can vary when the table is restricted), no footer and row labels; one row of column labels is given by the descriptions of the table columns (authors, title, year, journal, MSC code).</p>

<p>Row and column separators are drawn as grids (cf. <code class="func">NCurses.Grid</code> (<a href="chap2_mj.html#X790715F683BF1E66"><span class="RefLink">2.2-8</span></a>)) composed from the special characters described in Section <a href="chap2_mj.html#X8091936586CCD248"><span class="RefLink">2.1-6</span></a>, using the component <code class="code">work.SpecialGrid</code> of the browse table, see <code class="func">BrowseData</code> (<a href="chap5_mj.html#X86E80E578085F137"><span class="RefLink">5.4-1</span></a>).</p>

<p>For categorizing by authors (or by MSC codes), the sort parameter <code class="code">"split rows on categorizing"</code> is set to <code class="code">"yes"</code>, so the authors (codes) are distributed to different category rows, hence each entry appears once for each of its authors (or its MSC codes) in the categorized table. When a data row or an entry in a data row is selected, "click" adds the corresponding bibliographhy entry to the result.</p>

<p>The width of the title column is preset; usually titles are too long for one line, and the contents of this column is formatted as a paragraph, using the function <code class="func">FormatParagraph</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap6_mj.html#X812058CE7C8E9022"><span class="RefLink">GAPDoc: FormatParagraph</span></a>). For the authors and journal columns, maximal widths are prescribed, and <code class="func">FormatParagraph</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap6_mj.html#X812058CE7C8E9022"><span class="RefLink">GAPDoc: FormatParagraph</span></a>) is used for longer entries.</p>

<p>For four columns, the sort parameters are defined as follows: The <em>authors</em> and <em>MSC code</em> columns do not become hidden when the table is categorized according to this column, sorting by the <em>year</em> yields a <em>de</em>scending order, and the category rows arising from these columns and the <em>journal</em> column show the numbers of the data rows that belong to them.</p>

<p>Those standard modes in <code class="func">BrowseData</code> (<a href="chap5_mj.html#X86E80E578085F137"><span class="RefLink">5.4-1</span></a>) where an entry or a row of the table is selected have been extended by three new actions, which open a pager showing the BibTeX, HTML, and Text format of the selected entry, respectively. The corresponding user inputs are the <strong class="button">vb</strong>, <strong class="button">vh</strong>, and <strong class="button">vt</strong>. If the <em>MSC code</em> column is available then also the user input <strong class="button">vm</strong> is admissible; it opens a pager showing the descriptions of the MSC codes attached to the selected entry.</p>

<p>This function requires some of the utilities provided by the <strong class="pkg">GAP</strong> package <strong class="pkg">GAPDoc</strong> (see <a href="chapBib_mj.html#biBGAPDoc">[LN07]</a>), such as <code class="func">FormatParagraph</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap6_mj.html#X812058CE7C8E9022"><span class="RefLink">GAPDoc: FormatParagraph</span></a>), <code class="func">NormalizeNameAndKey</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X7C9F0C337A0A0FF0"><span class="RefLink">GAPDoc: NormalizeNameAndKey</span></a>), <code class="func">NormalizedNameAndKey</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X7C9F0C337A0A0FF0"><span class="RefLink">GAPDoc: NormalizedNameAndKey</span></a>), <code class="func">ParseBibFiles</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X82555C307FDC1817"><span class="RefLink">GAPDoc: ParseBibFiles</span></a>), <code class="func">ParseBibXMLextFiles</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X86BD29AE7A453721"><span class="RefLink">GAPDoc: ParseBibXMLextFiles</span></a>), <code class="func">ParseBibXMLextString</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X86BD29AE7A453721"><span class="RefLink">GAPDoc: ParseBibXMLextString</span></a>), <code class="func">RecBibXMLEntry</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X786C33ED79F425F1"><span class="RefLink">GAPDoc: RecBibXMLEntry</span></a>), and <code class="func">StringBibAsXMLext</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X85F33C64787A00B7"><span class="RefLink">GAPDoc: StringBibAsXMLext</span></a>).</p>

<p>The code can be found in the file <code class="file">app/gapbibl.g</code> of the package.</p>

<p>The browse table can be customized by entering a record as the argument of <code class="func">BrowseBibliography</code>, with the following supported components.</p>


<dl>
<dt><strong class="Mark"><code class="code">files</code></strong></dt>
<dd><p>a nonempty list of filenames containing the data to be shown; there is no default for this component.</p>

</dd>
<dt><strong class="Mark"><code class="code">filesshort</code></strong></dt>
<dd><p>a list of the same length as the <code class="code">files</code> component, the entries are strings which are shown in the <code class="code">"sourcefilename"</code> column of the table (if this column is present); the default is the list of filenames.</p>

</dd>
<dt><strong class="Mark"><code class="code">filecontents</code></strong></dt>
<dd><p>a list of the same length as the <code class="code">files</code> component, the entries are strings which are shown as category values when the table is categorized by the <code class="code">"sourcefilename"</code> column; the default is the list of filenames.</p>

</dd>
<dt><strong class="Mark"><code class="code">header</code></strong></dt>
<dd><p>is the constant part of the header shown above the browse table, the default is the first filename.</p>

</dd>
<dt><strong class="Mark"><code class="code">columns</code></strong></dt>
<dd><p>is a list of records that are valid as the second argument of <code class="func">DatabaseAttributeAdd</code> (<a href="chapA_mj.html#X8573522782D939FE"><span class="RefLink">A.1-5</span></a>), where the first argument is a database id enumerator created from the bibliography entries in the files in question. Each entry (and also the corresponding identifier) of this database id enumerator is a list of records obtained from <code class="func">ParseBibXMLextFiles</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X86BD29AE7A453721"><span class="RefLink">GAPDoc: ParseBibXMLextFiles</span></a>) and <code class="func">RecBibXMLEntry</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X786C33ED79F425F1"><span class="RefLink">GAPDoc: RecBibXMLEntry</span></a>), or from <code class="func">ParseBibFiles</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X82555C307FDC1817"><span class="RefLink">GAPDoc: ParseBibFiles</span></a>), such that the list elements are regarded as equal, in the sense that their fingerprints (see below) are equal. The records in the <code class="code">columns</code> list are available for constructing the desired browse table, the actual appearance is controlled by the <code class="code">choice</code> component described below. Columns showing authors, title, year, journal, MSC code, and filename are predefined and need not be listed here.</p>

</dd>
<dt><strong class="Mark"><code class="code">choice</code></strong></dt>
<dd><p>a list of strings denoting the <code class="code">identifier</code> components of those columns that shall actually be shown in the table, the default is <code class="code">[ "authors", "title", "year", "journal", "mrclass" ]</code>.</p>

</dd>
<dt><strong class="Mark"><code class="code">fingerprint</code></strong></dt>
<dd><p>a list of strings denoting component names of the entries of the database id enumerator that is constructed from the data (see above); two data records are regarded as equal if the values of these components are equal; the default is <code class="code">[ "mrnumber", "title", "authorAsList", "editorAsList", "author" ]</code>.</p>

</dd>
<dt><strong class="Mark"><code class="code">sortKeyFunction</code></strong></dt>
<dd><p>either <code class="keyw">fail</code> or a function that takes a record as returned by <code class="func">RecBibXMLEntry</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap7_mj.html#X786C33ED79F425F1"><span class="RefLink">GAPDoc: RecBibXMLEntry</span></a>) and returns a list that is used for comparing and thus sorting the records; the default is <code class="keyw">fail</code>, which means that the rows of the table appear in the same ordering as in the source files.</p>

</dd>
</dl>
<p><a id="X7E4B5E277D08987B" name="X7E4B5E277D08987B"></a></p>

<h5>6.7-2 BrowseBibliographyGapPackages</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseBibliographyGapPackages</code>(  )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: a record as returned by <code class="func">BrowseBibliography</code> (<a href="chap6_mj.html#X7F0FE4CC7F46ABF3"><span class="RefLink">6.7-1</span></a>).</p>

<p>This function collects the information from the <code class="code">*.bib</code> and <code class="code">*bib.xml</code> files in those subdirectories of installed <strong class="pkg">GAP</strong> packages which contain the package documentation, and shows it in a Browse table, using the function <code class="func">BrowseBibliography</code> (<a href="chap6_mj.html#X7F0FE4CC7F46ABF3"><span class="RefLink">6.7-1</span></a>).</p>

<p><em>This function is experimental.</em> The result is not really satisfactory, for the following reasons.</p>


<ul>
<li><p>Duplicate entries may occur, due to subtle differences in various source files.</p>

</li>
<li><p>The source files may contain more than what is actually cited in the package manuals.</p>

</li>
<li><p>It may happen that some <code class="code">*.bib</code> or <code class="code">*bib.xml</code> file is accidentally distributed with the package but is not intended to serve as package bibliography.</p>

</li>
<li><p>The heuristics for rewriting LaTeX code is of course not perfect; thus strange symbols may occur in the Browse table.</p>

</li>
</ul>
<p><a id="X81F1558678ACDB4A" name="X81F1558678ACDB4A"></a></p>

<h5>6.7-3 BrowseMSC</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseMSC</code>( [<var class="Arg">version</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: nothing.</p>

<p>This function shows the valid MSC codes in a browse table that is categorized by the <code class="code">..-XX</code> and the <code class="code">...xx</code> codes. (Use <strong class="button">X</strong> for expanding all categories or <strong class="button">x</strong> for expanding the currently selected category.) Due to the categorization, only two columns of the table are visible, showing the codes and their descriptions.</p>

<p>If <var class="Arg">version</var> is given then it must be one of the numbers <span class="SimpleMath">\(2010\)</span> or <span class="SimpleMath">\(2020\)</span>, meaning that the MSC2010 or MSC2020 codes are shown; the default for <var class="Arg">version</var> is <span class="SimpleMath">\(2020\)</span>.</p>

<p><a id="X837BDF547FF0EA31" name="X837BDF547FF0EA31"></a></p>

<h4>6.8 <span class="Heading">Profiling <strong class="pkg">GAP</strong> functions–a Variant</span></h4>

<p>A <strong class="pkg">Browse</strong> adapted way to evaluate profiling results is to show the overview that is printed by the <strong class="pkg">GAP</strong> function <code class="func">DisplayProfile</code> (<a href="../../../doc/ref/chap7_mj.html#X80FEA6A08775A48E"><span class="RefLink">Reference: DisplayProfile</span></a>) in a <strong class="pkg">Browse</strong> table, which allows one to sort the profiled functions according to the numbers of calls, the time spent, etc., and to search for certain functions one is interested in.</p>

<p><a id="X7B42091982DE7AE7" name="X7B42091982DE7AE7"></a></p>

<h5>6.8-1 BrowseProfile</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseProfile</code>( [<var class="Arg">functions</var>][,] [<var class="Arg">mincount</var>, <var class="Arg">mintime</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>The arguments and their meaning are the same as for the function <code class="func">DisplayProfile</code> (<a href="../../../doc/ref/chap7_mj.html#X80FEA6A08775A48E"><span class="RefLink">Reference: DisplayProfile</span></a>), in the sense that the lines printed by that function correspond to the rows of the list that is shown by <code class="func">BrowseProfile</code>. Initially, the table is sorted in the same way as the list shown by <code class="func">BrowseProfile</code>; sorting the table by any of the first five columns will yield a non-increasing order of the rows.</p>

<p>The threshold values <var class="Arg">mincount</var> and <var class="Arg">mintime</var> can be changed in visual mode via the user input <strong class="button">e</strong>. If mouse events are enabled (see <code class="func">NCurses.UseMouse</code> (<a href="chap2_mj.html#X799C033A7AB582D7"><span class="RefLink">2.2-10</span></a>)) then one can also use a mouse click on the current parameter value shown in the table header in order to enter the mode for changing the parameters.</p>

<p>When a row or an entry in a row is selected, "click" shows the code of the corresponding function in a pager (see <code class="func">NCurses.Pager</code> (<a href="chap3_mj.html#X87E1B2787F588CC0"><span class="RefLink">3.1-4</span></a>)) whenever this is possible, as follows. If the function was read from a file then this file is opened, if the function was entered interactively then the code of the function is shown in the format produced by <code class="func">Print</code> (<a href="../../../doc/ref/chap6_mj.html#X7AFA64D97A1F39A3"><span class="RefLink">Reference: Print</span></a>); other functions (for example <strong class="pkg">GAP</strong> kernel functions) cannot be shown, one gets an alert message (see <code class="func">NCurses.Alert</code> (<a href="chap3_mj.html#X83E95B4A83BC473E"><span class="RefLink">3.1-1</span></a>)) in such a case.</p>

<p>The full functionality of the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) is available.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">n:= [ 14, 14, 14, 14, 14 ];;  # ``do nothing''</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">ProfileOperationsAndMethods( true );    # collect some data</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">ConjugacyClasses( PrimitiveGroup( 24, 1 ) );;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">ProfileOperationsAndMethods( false );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "e",                                    # edit threshold paras</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       [ NCurses.keys.DC ], "2", "\t",         # replace 10000 by 20000</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       [ NCurses.keys.DC ], "2",               # replace 30 by 20</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       [ NCurses.keys.ENTER ],                 # commit the changes</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "scso",                                 # sort by column 1,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       n,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "rso",                                  # sort by column 2,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       n,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "rso",                                  # sort by column 3,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       n,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "q",                                    # deselect the column,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "/Normalizer", [ NCurses.keys.ENTER ],  # search for a function,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       n, n, n, "Q" ) );                       # and quit</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseProfile();</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
</pre></div>

<p><em>Implementation remarks</em>: The browse table has a dynamic header, which shows the current values of <var class="Arg">mincount</var> and <var class="Arg">mintime</var>, and a dynamic footer, which shows the sums of counts and timings for the rows in the table (label <code class="code">TOTAL</code>) and if applicable the sums for the profiled functions not shown in the table (label <code class="code">OTHER</code>). There are no row labels, and the obvious column labels. There is no return value.</p>

<p>The standard modes in <code class="func">BrowseData</code> (<a href="chap5_mj.html#X86E80E578085F137"><span class="RefLink">5.4-1</span></a>) (except the <code class="code">help</code> mode) have been modified by adding a new action for changing the threshold parameters <var class="Arg">mincount</var> and <var class="Arg">mintime</var> (user input <strong class="button">e</strong>). The way how this in implemented made it necessary to change the standard "reset" action (user input <strong class="button">!</strong>) of the table; note that resetting (a sorting or filtering of) the table must not make those rows visible that shall be hidden because of the threshold parameters.</p>

<p>The code can be found in the file <code class="file">app/profile.g</code> of the package.</p>

<p><a id="X87B30F7387C0E531" name="X87B30F7387C0E531"></a></p>

<h4>6.9 <span class="Heading">Variables defined in <strong class="pkg">GAP</strong> packages–a Variant</span></h4>

<p>A <strong class="pkg">Browse</strong> adapted way to list the variables that are defined in a <strong class="pkg">GAP</strong> package is to show the overview that is printed by the <strong class="pkg">GAP</strong> function <code class="func">ShowPackageVariables</code> (<a href="../../../doc/ref/chap76_mj.html#X7D34AC3287611B15"><span class="RefLink">Reference: ShowPackageVariables</span></a>) in a <strong class="pkg">Browse</strong> table.</p>

<p><a id="X8030B1688335783D" name="X8030B1688335783D"></a></p>

<h5>6.9-1 BrowsePackageVariables</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowsePackageVariables</code>( <var class="Arg">pkgname</var>[, <var class="Arg">version</var>][, <var class="Arg">arec</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: nothing.</p>

<p>The arguments can be the same as for <code class="func">ShowPackageVariables</code> (<a href="../../../doc/ref/chap76_mj.html#X7D34AC3287611B15"><span class="RefLink">Reference: ShowPackageVariables</span></a>), that is, <var class="Arg">pkgname</var> is the name of a <strong class="pkg">GAP</strong> package, and the optional arguments <var class="Arg">version</var> and <var class="Arg">arec</var> are a version number of this package and a record used for customizing the output, respectively.</p>

<p>Alternatively, the second argument can be the output <code class="code">info</code> of <code class="func">PackageVariablesInfo</code> (<a href="../../../doc/ref/chap76_mj.html#X7D34AC3287611B15"><span class="RefLink">Reference: PackageVariablesInfo</span></a>) for the package in question, instead of the version number.</p>

<p><code class="func">BrowsePackageVariables</code> opens a browse table that shows the global variables that become bound and the methods that become installed when <strong class="pkg">GAP</strong> loads the package <var class="Arg">pkgname</var>.</p>

<p>The table is categorized by the kinds of variables (new or redeclared operations, methods, info classes, synonyms, other globals). The column "Doc.?" distinguishes undocumented and documented variables, so one can use this column as a filter or for categorizing. The column "Filename" shows the names of the package files. Clicking a selected row of the table opens the relevant package file at the code in question.</p>

<p>The idea behind the argument <code class="code">info</code> is that using the same arguments as for <code class="func">ShowPackageVariables</code> (<a href="../../../doc/ref/chap76_mj.html#X7D34AC3287611B15"><span class="RefLink">Reference: ShowPackageVariables</span></a>) does not allow one to apply <code class="func">BrowsePackageVariables</code> to packages that have been loaded before the <strong class="pkg">Browse</strong> package. Thus one can compute the underlying data <code class="code">info</code> first, using <code class="func">PackageVariablesInfo</code> (<a href="../../../doc/ref/chap76_mj.html#X7D34AC3287611B15"><span class="RefLink">Reference: PackageVariablesInfo</span></a>), then load the <strong class="pkg">Browse</strong> package, and finally call <code class="func">BrowsePackageVariables</code>.</p>

<p>For example, the overview of package variables for <strong class="pkg">Browse</strong> can be shown by starting <strong class="pkg">GAP</strong> without packages and then entering the following lines.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">pkgname:= "Browse";;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">info:= PackageVariablesInfo( pkgname, "" );;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">LoadPackage( "Browse" );;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowsePackageVariables( pkgname, info );</span>
</pre></div>

<p>If the arguments are the same as for <code class="func">ShowPackageVariables</code> (<a href="../../../doc/ref/chap76_mj.html#X7D34AC3287611B15"><span class="RefLink">Reference: ShowPackageVariables</span></a>) then this function is actually called, with the consequence that the package gets loaded when <code class="func">BrowsePackageVariables</code> is called. This is not the case if the output of <code class="func">PackageVariablesInfo</code> (<a href="../../../doc/ref/chap76_mj.html#X7D34AC3287611B15"><span class="RefLink">Reference: PackageVariablesInfo</span></a>) is entered as the second argument.</p>

<p><a id="X7CD025147D528741" name="X7CD025147D528741"></a></p>

<h4>6.10 <span class="Heading">Configuring User preferences–a Variant</span></h4>

<p>A <strong class="pkg">Browse</strong> adapted way to show and edit <strong class="pkg">GAP</strong>'s user preferences is to show the overview that is printed by the <strong class="pkg">GAP</strong> function <code class="func">ShowUserPreferences</code> (<a href="../../../doc/ref/chap3_mj.html#X7B0AD104839B6C3C"><span class="RefLink">Reference: ShowUserPreferences</span></a>) in a <strong class="pkg">Browse</strong> table.</p>

<p><a id="X7A7B712E7A06449F" name="X7A7B712E7A06449F"></a></p>

<h5>6.10-1 BrowseUserPreferences</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseUserPreferences</code>( <var class="Arg">package1</var>, <var class="Arg">package2</var>, <var class="Arg">...</var> )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: nothing.</p>

<p>The arguments are the same as for <code class="func">ShowUserPreferences</code> (<a href="../../../doc/ref/chap3_mj.html#X7B0AD104839B6C3C"><span class="RefLink">Reference: ShowUserPreferences</span></a>), that is, calling the function with no argument yields an overview of all known user preferences, and if one or more strings <var class="Arg">package1</var>, <span class="SimpleMath">\(\ldots\)</span> are given then only the user preferences for these packages are shown.</p>

<p><code class="func">BrowseUserPreferences</code> opens a browse table with the following columns:</p>


<dl>
<dt><strong class="Mark">"Package"</strong></dt>
<dd><p>contains the names of the <strong class="pkg">GAP</strong> packages to which the user preferences belong,</p>

</dd>
<dt><strong class="Mark">"Pref. names"</strong></dt>
<dd><p>contains the names of the user preferences, and</p>

</dd>
<dt><strong class="Mark">"Description"</strong></dt>
<dd><p>contains the <code class="code">description</code> texts from the <code class="func">DeclareUserPreference</code> (<a href="../../../doc/ref/chap3_mj.html#X7F1DF6757B248014"><span class="RefLink">Reference: DeclareUserPreference</span></a>) calls and the default values (if applicable), and the actual values.</p>

</dd>
</dl>
<p>When one "clicks" on one of the table rows or entries then the values of the user preference in question can be edited. If a list of admissible values is known then this means that one can choose from this list via <code class="func">NCurses.Select</code> (<a href="chap3_mj.html#X833D321E86528981"><span class="RefLink">3.1-2</span></a>), otherwise one can enter the desired value as text.</p>

<p>The values of the user preferences are not changed before one closes the browse table. When the table is left and if one has changed at least one value, one is asked whether the changes shall be applied.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">d:= [ NCurses.keys.DOWN ];;  </span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">c:= [ NCurses.keys.ENTER ];; </span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "/PackagesToLoad",  # enter a search string,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,                  # start the search,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,                  # edit the entry (a list of choices),</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       " ", d,             # toggle the first four values,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       " ", d,             #</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       " ", d,             #</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       " ", d,             #</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,                  # submit the values,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "Q",                # quit the table,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c ) );              # choose "cancel": do not apply the changes.</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseUserPreferences();</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
</pre></div>

<p>The code can be found in the file <code class="file">app/userpref.g</code> of the package.</p>

<p><a id="X86C730A07855238D" name="X86C730A07855238D"></a></p>

<h4>6.11 <span class="Heading">Overview of <strong class="pkg">GAP</strong> Data</span></h4>

<p>The <strong class="pkg">GAP</strong> system contains several data collections such as libraries of groups and character tables. Clearly the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) can be used to visualize interesting information about such data collections, in the form of an "overview table" whose rows correspond to the objects in the collection; each column of the table shows a piece of information about the objects. (One possibility to create such overviews is given by <code class="func">BrowseTableFromDatabaseIdEnumerator</code> (<a href="chapA_mj.html#X7F25A3E586653911"><span class="RefLink">A.2-2</span></a>).)</p>

<p><a id="X850C786C87A4877B" name="X850C786C87A4877B"></a></p>

<h5>6.11-1 BrowseGapData</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseGapData</code>(  )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: the return value of the chosen application if there is one.</p>

<p>The function <code class="func">BrowseGapData</code> shows the choices in the list <code class="code">BrowseData.GapDataOverviews</code>, in a browse table with one column. When an entry is "clicked" then the associated function is called, and the table of choices is closed.</p>

<p>The idea is that each entry of <code class="code">BrowseData.GapDataOverviews</code> describes an overview of a data collection.</p>

<p>The <strong class="pkg">Browse</strong> package provides overviews of</p>


<ul>
<li><p>the current AMS Mathematics Subject Classification codes (see <code class="func">BrowseMSC</code> (<a href="chap6_mj.html#X81F1558678ACDB4A"><span class="RefLink">6.7-3</span></a>)),</p>

</li>
<li><p>the contents of the <strong class="pkg">AtlasRep</strong> package <a href="chapBib_mj.html#biBAtlasRep">[WPN+19]</a> (only if this package is loaded, see Section <a href="chap6_mj.html#X80370827793813FD"><span class="RefLink">6.5</span></a>),</p>

</li>
<li><p>the Conway polynomials in <strong class="pkg">GAP</strong> (calls <code class="code">BrowseConwayPolynomials()</code>),</p>

</li>
<li><p>profile information for <strong class="pkg">GAP</strong> functions (see Section <a href="chap6_mj.html#X837BDF547FF0EA31"><span class="RefLink">6.8</span></a>),</p>

</li>
<li><p>the list of <strong class="pkg">GAP</strong> related bibliography entries in the file <code class="file">bibl/gap-publishednicer.bib</code> of the <strong class="pkg">Browse</strong> package (see Section <a href="chap6_mj.html#X846751CC7F54F51D"><span class="RefLink">6.7</span></a>),</p>

</li>
<li><p>the <strong class="pkg">GAP</strong> manuals (see Section <a href="chap6_mj.html#X7CF999297B331E01"><span class="RefLink">6.6</span></a>),</p>

</li>
<li><p><strong class="pkg">GAP</strong> operations and methods (calls <code class="code">BrowseGapMethods()</code>),</p>

</li>
<li><p>the installed <strong class="pkg">GAP</strong> packages (calls <code class="code">BrowseGapPackages()</code>),</p>

</li>
<li><p><strong class="pkg">GAP</strong>'s user preferences (see Section <a href="chap6_mj.html#X7CD025147D528741"><span class="RefLink">6.10</span></a>),</p>

</li>
<li><p>the contents of the <strong class="pkg">TomLib</strong> package <a href="chapBib_mj.html#biBTomLib">[NMP13]</a> (only if this package is loaded, see Section <a href="chapA_mj.html#X8628EF6981A524B3"><span class="RefLink">A.4</span></a>),</p>

</li>
</ul>
<p>Other <strong class="pkg">GAP</strong> packages may add more overviews, using the function <code class="func">BrowseGapDataAdd</code> (<a href="chap6_mj.html#X7FC24FCE7A0C6058"><span class="RefLink">6.11-2</span></a>). For example, there are overviews of</p>


<ul>
<li><p>the bibliographies in the <strong class="pkg">ATLAS</strong> of Finite Groups <a href="chapBib_mj.html#biBCCN85">[CCN+85]</a> and in the <strong class="pkg">ATLAS</strong> of Brauer Characters <a href="chapBib_mj.html#biBJLPW95">[JLPW95]</a> (see <code class="func">BrowseBibliographySporadicSimple</code> (<a href="../../../pkg/atlasrep/doc/chap3_mj.html#X84ED4FC182C28198"><span class="RefLink">AtlasRep: BrowseBibliographySporadicSimple</span></a>)),</p>

</li>
<li><p>atomic irrationalities that occur in character tables in the <strong class="pkg">ATLAS</strong> of Finite Groups <a href="chapBib_mj.html#biBCCN85">[CCN+85]</a> or the <strong class="pkg">ATLAS</strong> of Brauer Characters <a href="chapBib_mj.html#biBJLPW95">[JLPW95]</a> (see Section <code class="func">BrowseCommonIrrationalities</code> (<a href="../../../pkg/ctbllib/doc/chap3_mj.html#X83FDD44E7E0AE885"><span class="RefLink">CTblLib: BrowseCommonIrrationalities</span></a>)),</p>

</li>
<li><p>the differences between the versions of the character table data in the <strong class="pkg">CTblLib</strong> package (see Section <code class="func">BrowseCTblLibDifferences</code> (<a href="../../../pkg/ctbllib/doc/chap3_mj.html#X87CA74CF7B533CC6"><span class="RefLink">CTblLib: BrowseCTblLibDifferences</span></a>)),</p>

</li>
<li><p>the information in the <strong class="pkg">GAP</strong> Character Table Library (see Section <code class="func">BrowseCTblLibInfo</code> (<a href="../../../pkg/ctbllib/doc/chap3_mj.html#X7A038A267CD17032"><span class="RefLink">CTblLib: BrowseCTblLibInfo</span></a>)),</p>

</li>
<li><p>an overview of minimal degrees of representations of groups from the <strong class="pkg">ATLAS</strong> of Group Representations (see Section <code class="func">BrowseMinimalDegrees</code> (<a href="../../../pkg/atlasrep/doc/chap3_mj.html#X7F31A7CB841FE63F"><span class="RefLink">AtlasRep: BrowseMinimalDegrees</span></a>)).</p>

</li>
</ul>
<p>Except that always one table cell is selected, the full functionality of the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) is available.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">n:= [ 14, 14, 14 ];;  # ``do nothing''</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput"># open the overview of Conway polynomials</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation( "/Conway Polynomials",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     [ NCurses.keys.ENTER, NCurses.keys.ENTER ], "srdddd", n, "Q" ) );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseGapData();;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput"># open the overview of GAP packages</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation( "/GAP Packages",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     [ NCurses.keys.ENTER, NCurses.keys.ENTER ], "/Browse",</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     [ NCurses.keys.ENTER ], "n", n, "Q" ) );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseGapData();;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
</pre></div>

<p><em>Implementation remarks</em>: The browse table has a static header, a dynamic footer showing the description of the currently selected entry, no row or column labels, and exactly one column of fixed width equal to the screen width. If the chosen application has a return value then this is returned by <code class="func">BrowseGapData</code>, otherwise nothing is returned. The component <code class="code">work.SpecialGrid</code> of the browse table is used to draw a border around the list of choices and another border around the footer. Only one mode is needed in which an entry is selected.</p>

<p>The code can be found in the file <code class="file">app/gapdata.g</code> of the package.</p>

<p><a id="X7FC24FCE7A0C6058" name="X7FC24FCE7A0C6058"></a></p>

<h5>6.11-2 BrowseGapDataAdd</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseGapDataAdd</code>( <var class="Arg">title</var>, <var class="Arg">call</var>[, <var class="Arg">ret</var>], <var class="Arg">documentation</var> )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>This function extends the list <code class="code">BrowseData.GapDataOverviews</code> by a new entry. The list is used by <code class="func">BrowseGapData</code> (<a href="chap6_mj.html#X850C786C87A4877B"><span class="RefLink">6.11-1</span></a>).</p>

<p><var class="Arg">title</var> must be a string of length at most <span class="SimpleMath">\(76\)</span>; it will be shown in the browse table that is opened by <code class="func">BrowseGapData</code> (<a href="chap6_mj.html#X850C786C87A4877B"><span class="RefLink">6.11-1</span></a>). <var class="Arg">call</var> must be a function that takes no arguments; it will be called when <var class="Arg">title</var> is "clicked". <var class="Arg">ret</var>, if given, must be <code class="keyw">true</code> if <var class="Arg">call</var> has a return value and if <code class="func">BrowseGapData</code> (<a href="chap6_mj.html#X850C786C87A4877B"><span class="RefLink">6.11-1</span></a>) shall return this value, and <code class="keyw">false</code> otherwise. <var class="Arg">documentation</var> must be a string that describes what happens when the function <var class="Arg">call</var> is called; it will be shown in the footer of the table opened by <code class="func">BrowseGapData</code> (<a href="chap6_mj.html#X850C786C87A4877B"><span class="RefLink">6.11-1</span></a>) when <var class="Arg">title</var> is selected.</p>

<p><a id="X7E3FDA927E62D963" name="X7E3FDA927E62D963"></a></p>

<h4>6.12 <span class="Heading">Navigating in a Directory Tree</span></h4>

<p>A natural way to visualize the contents of a directory is via a tree whose leaves denote plain files, and the other vertices denote subdirectories. <strong class="pkg">Browse</strong> provides a function based on <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) for displaying such trees; the leaves correspond to the data rows, and the other vertices correspond to category rows.</p>

<p><a id="X859682DE8397261E" name="X859682DE8397261E"></a></p>

<h5>6.12-1 BrowseDirectory</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseDirectory</code>( [<var class="Arg">dir</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: a list of the "clicked" filenames.</p>

<p>If no argument is given then the contents of the current directory is shown, see <code class="func">DirectoryCurrent</code> (<a href="../../../doc/ref/chap9_mj.html#X7BAD8036849E8430"><span class="RefLink">Reference: DirectoryCurrent</span></a>). If a directory object <var class="Arg">dir</var> (see <code class="func">Directory</code> (<a href="../../../doc/ref/chap9_mj.html#X86A71E927EEC7EAD"><span class="RefLink">Reference: Directory</span></a>)) is given as the only argument then the contents of this directory is shown; alternatively, <var class="Arg">dir</var> may also be a string which is then understood as a directory path.</p>

<p>The full functionality of the function <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) is available.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">n:= [ 14, 14, 14 ];;  # ``do nothing''</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "q",                                  # leave the selection</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "X",                                  # expand all categories</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "/filetree", [ NCurses.keys.ENTER ],  # search for "filetree"</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       n, "Q" ) );                           # and quit</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">dir:= DirectoriesPackageLibrary( "Browse", "" )[1];;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">if IsBound( BrowseDirectory ) then</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     BrowseDirectory( dir );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">   fi;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
</pre></div>

<p><em>Implementation remarks</em>: The browse table has a static header, no footer, no row or column labels, and exactly one data column. The category rows are precomputed, i. e., they do not arise from a table column. The tree structure is visualized via a special grid that is shown in the separator column in front of the table column; the width of this column is computed from the largest nesting depth of files. For technical reasons, category rows representing <em>empty</em> directories are realized via "dummy" table rows; a special <code class="code">ShowTables</code> function guarantees that these rows are always hidden.</p>

<p>When a data row or an entry in this row is selected, "click" adds the corresponding filename to the result list. Initially, the first row is selected. (So if you want to search in the whole tree then you should quit this selection by hitting the <strong class="button">q</strong> key.)</p>

<p>The category hierarchy is computed using <code class="func">DirectoryContents</code> (<a href="../../../doc/ref/chap9_mj.html#X7B225E5282534EDA"><span class="RefLink">Reference: DirectoryContents</span></a>).</p>

<p>This function is available only if the <strong class="pkg">GAP</strong> package <strong class="pkg">IO</strong> (see <a href="chapBib_mj.html#biBIO">[Neu07]</a>) is available, because the check for cycles uses the function <code class="func">IO_stat</code> (<a href="../../../pkg/io/doc/chap3_mj.html#X7F7D23867B45D525"><span class="RefLink">IO: IO_stat</span></a>) from this package.</p>

<p>The code can be found in the file <code class="file">app/filetree.g</code> of the package.</p>

<p><a id="X7FAE33037D09CC4E" name="X7FAE33037D09CC4E"></a></p>

<h4>6.13 <span class="Heading">A Puzzle</span></h4>

<p>We consider an <span class="SimpleMath">\(m\)</span> by <span class="SimpleMath">\(n\)</span> rectangle of squares numbered from <span class="SimpleMath">\(1\)</span> to <span class="SimpleMath">\(m n - 1\)</span>, the bottom right square is left empty. The numbered squares are permuted by successively exchanging the empty square and a neighboring square such that in the end, the empty cell is again in the bottom right corner.</p>

<div class="pcenter"><table class="GAPDocTable">
<tr>
<td class="tdcenter"><span class="SimpleMath">\( 7\)</span></td>
<td class="tdcenter"><span class="SimpleMath">\(13\)</span></td>
<td class="tdcenter"><span class="SimpleMath">\(14\)</span></td>
<td class="tdcenter"><span class="SimpleMath">\( 2\)</span></td>
</tr>
<tr>
<td class="tdcenter"><span class="SimpleMath">\( 1\)</span></td>
<td class="tdcenter"><span class="SimpleMath">\( 4\)</span></td>
<td class="tdcenter"><span class="SimpleMath">\(15\)</span></td>
<td class="tdcenter"><span class="SimpleMath">\(11\)</span></td>
</tr>
<tr>
<td class="tdcenter"><span class="SimpleMath">\( 6\)</span></td>
<td class="tdcenter"><span class="SimpleMath">\( 8\)</span></td>
<td class="tdcenter"><span class="SimpleMath">\( 3\)</span></td>
<td class="tdcenter"><span class="SimpleMath">\( 9\)</span></td>
</tr>
<tr>
<td class="tdcenter"><span class="SimpleMath">\(10\)</span></td>
<td class="tdcenter"><span class="SimpleMath">\( 5\)</span></td>
<td class="tdcenter"><span class="SimpleMath">\(12\)</span></td>
<td class="tdcenter"><span class="SimpleMath">\( \)</span></td>
</tr>
</table><br />
</div>

<p>The aim of the game is to order the numbered squares via these moves.</p>

<p>For the case <span class="SimpleMath">\(m = n = 4\)</span>, the puzzle is (erroneously?) known under the name "Sam Loyd's Fifteen", see <a href="chapBib_mj.html#biBLoydFifteenWeb">[Bog]</a> and <a href="chapBib_mj.html#biBHistGames">[OR]</a> for more information and references.</p>

<p><a id="X7EF5FCBD7DAFFAF3" name="X7EF5FCBD7DAFFAF3"></a></p>

<h5>6.13-1 BrowsePuzzle</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowsePuzzle</code>( [<var class="Arg">m</var>, <var class="Arg">n</var>[, <var class="Arg">pi</var>]] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: a record describing the initial and final status of the puzzle.</p>

<p>This function shows the rectangle in a window.</p>

<p>The arguments <var class="Arg">m</var> and <var class="Arg">n</var> are the dimensions of the rectangle, the default for both values is <span class="SimpleMath">\(4\)</span>. The initial distribution of the numbers in the squares can be prescribed via a permutation <var class="Arg">pi</var>, the default is a random element in the alternating group on the points <span class="SimpleMath">\(1, 2, \ldots, \textit{m} \textit{n} - 1\)</span>. (Note that the game has not always a solution.)</p>

<p>In any case, the empty cell is selected, and the selection can be moved to neighboring cells via the arrow keys, or to any place in the same row or column via a mouse click.</p>

<p>The return value is a record with the components <code class="code">dim</code> (the pair <code class="code">[ m, n ]</code>), <code class="code">init</code> (the initial permutation), <code class="code">final</code> (the final permutation), and <code class="code">steps</code> (the number of transpositions that were needed).</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       BrowsePuzzleSolution.steps, "Q" ) );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowsePuzzle( 4, 4, BrowsePuzzleSolution.init );;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
</pre></div>

<p>An implementation using only mouse clicks but no key strokes is available in the <strong class="pkg">GAP</strong> package <strong class="pkg">XGAP</strong> (see <a href="chapBib_mj.html#biBXGAP">[CN04]</a>).</p>

<p><em>Implementation remarks</em>: The game board is implemented via a browse table, without row and column labels, with static header, dynamic footer, and individual <code class="code">minyx</code> function. Only one mode is needed in which one cell is selected, and besides the standard actions for quitting the table, asking for help, and saving the current window contents, only the four moves via the arrow keys and mouse clicks are admissible.</p>

<p>Some standard <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) functionality, such as scrolling, selecting, and searching, are not available in this application.</p>

<p>The code can be found in the file <code class="file">app/puzzle.g</code> of the package.</p>

<p><a id="X7FFF943D78A403C9" name="X7FFF943D78A403C9"></a></p>

<h4>6.14 <span class="Heading">Peg Solitaire</span></h4>

<p>Peg solitaire is a board game for one player. The game board consists of several holes some of which contain pegs. In each step of the game, one peg is moved horizontally or vertically to an empty hole at distance two, by jumping over a neighboring peg which is then removed from the board. </p><div style="text-align:center;"> <img src="solitair.png" alt="[solitaire image]"/> </div><p></p>

<p>We consider the game that in the beginning, exactly one hole is empty, and in the end, exactly one peg is left.</p>

<p><a id="X82C8691380FCB674" name="X82C8691380FCB674"></a></p>

<h5>6.14-1 PegSolitaire</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; PegSolitaire</code>( [<var class="Arg">format</var>][,] [<var class="Arg">nrholes</var>][,] [<var class="Arg">twoModes</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>This function shows the game board in a window.</p>

<p>If the argument <var class="Arg">format</var> is one of the strings <code class="code">"small"</code> or <code class="code">"large"</code> then small or large pegs are shown, the default is <code class="code">"small"</code>.</p>

<p>Three shapes of the game board are supported, with <span class="SimpleMath">\(33\)</span>, <span class="SimpleMath">\(37\)</span>, and <span class="SimpleMath">\(45\)</span> holes, respectively; this number can be specified via the argument <var class="Arg">nrholes</var>, the default is <span class="SimpleMath">\(33\)</span>. In the cases of <span class="SimpleMath">\(33\)</span> and <span class="SimpleMath">\(45\)</span> holes, the position of both the initial hole and the destination of the final peg is the middle cell, whereas in the case of <span class="SimpleMath">\(37\)</span> holes, the initial hole is in the top left position and the final peg has to be placed in the bottom right position.</p>

<p>If a Boolean <var class="Arg">twoModes</var> is entered as an argument then it determines whether a browse table with one or two modes is used; the default <code class="keyw">false</code> yields a browse table with only one mode.</p>

<p>In any case, one cell of the board is selected, and the selection can be moved to neighboring cells via the arrow keys. A peg in the selected cell jumps over a neighboring peg to an adjacent hole via the <code class="code">j</code> key followed by the appropriate arrow key.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">for n in [ 33, 37, 45 ] do</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">         PegSolitaireSolutions.( String( n ) ), "Q" ) );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     PegSolitaire( n );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     PegSolitaire( "large", n );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     PegSolitaire( n, true );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     PegSolitaire( "large", n, true );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">od;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
</pre></div>

<p>For more information such as variations of the game and references, see <a href="chapBib_mj.html#biBPegSolitaireWeb">[Köla]</a>. Also the solutions stored in the variable <code class="code">PegSolitaireSolutions</code> have been taken from this web page.</p>

<p><em>Implementation remarks</em>: The game board is implemented via a browse table, without row and column labels, with static header, dynamic footer, and individual <code class="code">minyx</code> function. In fact, two implementations are provided. The first one needs only one mode in which one cell is selected; moving the selection and jumping with the peg in the selected cell in one of the four directions are the supported user actions. The second implementation needs two modes, one for moving the selection and one for jumping.</p>

<p>Some standard <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) functionality, such as scrolling, selecting, and searching, are not available in this application.</p>

<p>The code can be found in the file <code class="file">app/solitair.g</code> of the package.</p>

<p><a id="X862CB73B7E0BE170" name="X862CB73B7E0BE170"></a></p>

<h4>6.15 <span class="Heading">Rubik's Cube</span></h4>

<p>We visualize the transformations of Rubik's magic cube in a model that is given by "unfolding" the faces and numbering them as follows. </p><div style="text-align:center;"> <img src="rubik.png" alt="[unfolded Rubik's cube image]"/> </div><p></p>

<p>Clockwise turns of the six layers (top, left, front, right, back, and down) are represented by the following permutations.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">cubegens := [</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">  ( 1, 3, 8, 6)( 2, 5, 7, 4)( 9,33,25,17)(10,34,26,18)(11,35,27,19),</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">  ( 9,11,16,14)(10,13,15,12)( 1,17,41,40)( 4,20,44,37)( 6,22,46,35),</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">  (17,19,24,22)(18,21,23,20)( 6,25,43,16)( 7,28,42,13)( 8,30,41,11),</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">  (25,27,32,30)(26,29,31,28)( 3,38,43,19)( 5,36,45,21)( 8,33,48,24),</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">  (33,35,40,38)(34,37,39,36)( 3, 9,46,32)( 2,12,47,29)( 1,14,48,27),</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">  (41,43,48,46)(42,45,47,44)(14,22,30,38)(15,23,31,39)(16,24,32,40)</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">];;</span>
</pre></div>

<p><strong class="pkg">GAP</strong> computations analyzing this permutation group have been part of the announcements of <strong class="pkg">GAP</strong> 3 releases. For a <strong class="pkg">GAP</strong> 4 equivalent, see <a href="chapBib_mj.html#biBRubiksCubeGAPWeb">[Sch]</a>. For more information and references (not <strong class="pkg">GAP</strong> related) about Rubik's cube, see <a href="chapBib_mj.html#biBRubiksCubeWeb">[Kölb]</a>.</p>

<p><a id="X8100659E81FFE9A2" name="X8100659E81FFE9A2"></a></p>

<h5>6.15-1 BrowseRubiksCube</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseRubiksCube</code>( [<var class="Arg">format</var>][,] [<var class="Arg">pi</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>This function shows the model of the cube in a window.</p>

<p>If the argument <var class="Arg">format</var> is one of the strings <code class="code">"small"</code> or <code class="code">"large"</code> then small or large cells are shown, the default is <code class="code">"small"</code>.</p>

<p>The argument <var class="Arg">pi</var> is the initial permutation of the faces, the default is a random permutation in the cube group, see <a href="../../../doc/ref/chap30_mj.html#X7FF906E57D6936F8"><span class="RefLink">Reference: Random</span></a>.</p>

<p>Supported user inputs are the keys <strong class="button">t</strong>, <strong class="button">l</strong>, <strong class="button">f</strong>, <strong class="button">r</strong>, <strong class="button">b</strong>, and <strong class="button">d</strong> for clockwise turns of the six layers, and the corresponding capital letters for counter-clockwise turns. If the terminal supports colors, according to the global variable <code class="func">NCurses.attrs.has_colors</code> (<a href="chap2_mj.html#X83ADB4E37C105B8C"><span class="RefLink">2.2-1</span></a>), the input <strong class="button">s</strong> switches between a screen that shows only the colors of the faces and a screen that shows the numbers; the color screen is the default.</p>

<p>The return value is a record with the components <code class="code">inputs</code> (a string describing the user inputs), <code class="code">init</code>, and <code class="code">final</code> (the initial and final permutation of the faces, respectively). (The <code class="code">inputs</code> component can be used for the replay feature, see the example below.)</p>

<p>In the following example, a word in terms of the generators is used to initialize the browse table, and then the letters in this word are used as a series of input steps, except that in between, the display is switched once from colors to numbers and back.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">choice:= List( [ 1 .. 30 ], i -&gt; Random( [ 1 .. 6 ] ) );;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">input:= List( "tlfrbd", IntChar ){ choice };;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       input{ [ 1 .. 20 ] },</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "s",                    # switch to number display</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       input{ [ 21 .. 25 ] },</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "s",                    # switch to color display</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       input{ [ 26 .. 30 ] },</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "Q" ) );;               # quit the browse table</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseRubiksCube( Product( cubegens{ choice } ) );;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseRubiksCube( "large", Product( cubegens{ choice } ) );;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
</pre></div>

<p><em>Implementation remarks</em>: The cube is implemented via a browse table, without row and column labels, with static header, dynamic footer, and individual <code class="code">minyx</code> function. Only one mode is needed, and besides the standard actions for quitting the table, asking for help, and saving the current window contents, only the twelve moves and the switch between color and number display are admissible.</p>

<p>Switching between the two display formats is implemented via a function <code class="code">work.Main</code>, so this relies on <em>not</em> caching the formatted cells in <code class="code">work.main</code>.</p>

<p>Row and column separators of the browse table are whitespace of height and width one. The separating lines are drawn using an individual <code class="code">SpecialGrid</code> function in the browse table. Note that the relevant cells do not form a rectangular array.</p>

<p>Some standard <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) functionality, such as scrolling, selecting, and searching, are not available in this application.</p>

<p>The code can be found in the file <code class="file">app/rubik.g</code> of the package.</p>

<p><a id="X7ADD618186541123" name="X7ADD618186541123"></a></p>

<h4>6.16 <span class="Heading">Changing Sides</span></h4>

<p>We consider a <span class="SimpleMath">\(5\)</span> by <span class="SimpleMath">\(5\)</span> board of squares filled with two types of stones, as follows. The square in the middle is left empty.</p>

<p></p><table class="sudokuin"> <tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td></tr> <tr><td>O</td><td>X</td><td>X</td><td>X</td><td>X</td></tr> <tr><td>O</td><td>O</td><td></td><td>X</td><td>X</td></tr> <tr><td>O</td><td>O</td><td>O</td><td>O</td><td>X</td></tr> <tr><td>O</td><td>O</td><td>O</td><td>O</td><td>O</td></tr> </table><p></p>

<p>The aim of the game is to exchange the two types of stones via a sequence of single steps that move one stone to the empty position on the board. Only those moves are allowed that increase or decrease one coordinate by <span class="SimpleMath">\(2\)</span> and increase or decrease the other by <span class="SimpleMath">\(1\)</span>; these are the allowed moves of the knight in chess.</p>

<p>This game has been part of the MacTutor system <a href="chapBib_mj.html#biBMacTutor">[OR00]</a>.</p>

<p><a id="X7FCFC5858584F46E" name="X7FCFC5858584F46E"></a></p>

<h5>6.16-1 BrowseChangeSides</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseChangeSides</code>(  )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>This function shows the game board in a window.</p>

<p>Each move is encoded as a sequence of three arrow keys; there are <span class="SimpleMath">\(24\)</span> admissible inputs.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">for entry in BrowseChangeSidesSolutions do</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     BrowseData.SetReplay( Concatenation( entry, "Q" ) );</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     BrowseChangeSides();</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">od;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
</pre></div>

<p><em>Implementation remarks</em>: The game board is implemented via a browse table, without row and column labels, with static header, dynamic footer, and individual <code class="code">minyx</code> function. Only one mode is needed, and besides the standard actions for quitting the table, asking for help, and saving the current window contents, only moves via combinations of the four arrow keys are admissible.</p>

<p>The separating lines are drawn using an individual <code class="code">SpecialGrid</code> function in the browse table.</p>

<p>Some standard <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) functionality, such as scrolling, selecting, and searching, are not available in this application.</p>

<p>The code can be found in the file <code class="file">app/knight.g</code> of the package.</p>

<p><a id="X7DDE46668321B5E9" name="X7DDE46668321B5E9"></a></p>

<h4>6.17 <span class="Heading">Sudoku</span></h4>

<p>We consider a <span class="SimpleMath">\(9\)</span> by <span class="SimpleMath">\(9\)</span> board of squares. Some squares are initially filled with numbers from <span class="SimpleMath">\(1\)</span> to <span class="SimpleMath">\(9\)</span>. The aim of the game is to fill the empty squares in such a way that each row, each column, and each of the marked <span class="SimpleMath">\(3\)</span> by <span class="SimpleMath">\(3\)</span> subsquares contains all numbers from <span class="SimpleMath">\(1\)</span> to <span class="SimpleMath">\(9\)</span>. A <em>proper Sudoku game</em> is defined as one with a unique solution. Here is an example.</p>

<p></p><table class="sudokuout"> <tr> <td><table class="sudokuin"> <tr> <td></td><td></td><td></td></tr> <tr> <td></td><td>1</td> <td>5</td> </tr> <tr> <td>9</td> <td></td><td></td></tr> </table></td> <td><table class="sudokuin"> <tr> <td></td><td></td><td></td></tr> <tr> <td>4</td> <td></td><td>6</td> </tr> <tr> <td></td><td>5</td> <td></td></tr> </table></td> <td><table class="sudokuin"> <tr> <td>5</td> <td></td><td></td></tr> <tr> <td></td><td>2</td> <td></td></tr> <tr> <td>3</td> <td></td><td></td></tr> </table></td> </tr> <tr> <td><table class="sudokuin"> <tr> <td>6</td> <td></td><td>4</td> </tr> <tr> <td></td><td></td><td></td></tr> <tr> <td>8</td> <td></td><td></td></tr> </table></td> <td><table class="sudokuin"> <tr> <td></td><td></td><td></td></tr> <tr> <td>8</td> <td></td><td></td></tr> <tr> <td>9</td> <td></td><td></td></tr> </table></td> <td><table class="sudokuin"> <tr> <td></td><td></td><td></td></tr> <tr> <td></td><td></td><td></td></tr> <tr> <td></td><td>5</td> <td>3</td> </tr> </table></td> </tr> <tr> <td><table class="sudokuin"> <tr> <td></td><td></td><td></td></tr> <tr> <td></td><td>4</td> <td></td></tr> <tr> <td></td><td></td><td>9</td> </tr> </table></td> <td><table class="sudokuin"> <tr> <td></td><td></td><td>5</td> </tr> <tr> <td></td><td></td><td>7</td> </tr> <tr> <td>1</td> <td></td><td></td></tr> </table></td> <td><table class="sudokuin"> <tr> <td></td><td></td><td></td></tr> <tr> <td></td><td></td><td>2</td> </tr> <tr> <td>8</td> <td></td><td></td></tr> </table></td> </tr> </table><p> The <strong class="pkg">Browse</strong> package contains functions to create, play and solve these games. There are basic command line functions for this, which we describe first, and there is a user interface <code class="func">PlaySudoku</code> (<a href="chap6_mj.html#X7D19224478E86BB4"><span class="RefLink">6.17-8</span></a>) which is implemented using the generic browse functionality described in Chapter <a href="chap4_mj.html#X877E60DE7F53FDEC"><span class="RefLink">4</span></a>.</p>

<p><a id="X789D3D4C818F4BC2" name="X789D3D4C818F4BC2"></a></p>

<h5>6.17-1 Sudoku.Init</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Sudoku.Init</code>( [<var class="Arg">arg</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: A record describing a Sudoku board or <code class="keyw">fail</code>.</p>

<p>This function constructs a record describing a Sudoku game. This is used by the other functions described below. There a several possibilities for the argument <var class="Arg">arg</var>.</p>


<dl>
<dt><strong class="Mark"><var class="Arg">arg</var> is a string</strong></dt>
<dd><p>The entries of a Sudoku board are numbered row-wise from 1 to 81. A board is encoded as a string as follows. If one of the numbers 1 to 9 is in entry <span class="SimpleMath">\(i\)</span> then the corresponding digit character is written in position <span class="SimpleMath">\(i\)</span> of the string. If an entry is empty any character, except <code class="code">'1'</code> to <code class="code">'9'</code> or <code class="code">'|'</code> is written in position <span class="SimpleMath">\(i\)</span> of the string. Trailing empty entries can be left out. Afterwards <code class="code">'|'</code>-characters can be inserted in the string (for example to mark line ends). Such strings can be used for <var class="Arg">arg</var>.</p>

</dd>
<dt><strong class="Mark"><var class="Arg">arg</var> is a matrix</strong></dt>
<dd><p>A Sudoku board can also be encoded as a 9 by 9-matrix, that is a list of 9 lists of length 9, whose (i,j)-th entry is the (i,j)-th entry of the board as integer if it is not empty. Empty entries of the board correspond to unbound entries in the matrix.</p>

</dd>
<dt><strong class="Mark"><var class="Arg">arg</var> is a list of integers</strong></dt>
<dd><p>Instead of the matrix just described the argument can also be given by the concatenation of the rows of the matrix (so, a list of integers and holes).</p>

</dd>
</dl>

<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">game := Sudoku.Init(" 3   68  | 85  1 69|  97   53|      79 |\</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput"> 6  47   |45  2    |89   2 1 | 4   8 7 | ");;</span>
</pre></div>

<p><a id="X86A5C6CE79DD67EE" name="X86A5C6CE79DD67EE"></a></p>

<h5>6.17-2 Sudoku.Place</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Sudoku.Place</code>( <var class="Arg">game</var>, <var class="Arg">i</var>, <var class="Arg">n</var> )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Sudoku.Remove</code>( <var class="Arg">game</var>, <var class="Arg">i</var> )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: The changed <var class="Arg">game</var>.</p>

<p>Here <var class="Arg">game</var> is a record describing a Sudoku board, as returned by <code class="func">Sudoku.Init</code> (<a href="chap6_mj.html#X789D3D4C818F4BC2"><span class="RefLink">6.17-1</span></a>). The argument <var class="Arg">i</var> is the number of an entry, counted row-wise from 1 to 81, and <var class="Arg">n</var> is an integer from 1 to 9 to be placed on the board. These functions change <var class="Arg">game</var>.</p>

<p><code class="func">Sudoku.Place</code> tries to place number <var class="Arg">n</var> on entry <var class="Arg">i</var>. It is an error if entry <var class="Arg">i</var> is not empty. The number is not placed if <var class="Arg">n</var> is already used in the row, column or subsquare of entry <var class="Arg">i</var>. In this case the component <code class="code">game.impossible</code> is bound.</p>

<p><code class="func">Sudoku.Remove</code> tries to remove the number placed on position <var class="Arg">i</var> of the board. It does not change the board if entry <var class="Arg">i</var> is empty, or if entry <var class="Arg">i</var> was given when the board <var class="Arg">game</var> was created. In the latter case <code class="code">game.impossible</code> is bound.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">game := Sudoku.Init(" 3   68  | 85  1 69|  97   53|      79 |\</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput"> 6  47   |45  2    |89   2 1 | 4   8 7 | ");;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">Sudoku.Place(game, 1, 3);; # 3 is already in first row</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">IsBound(game.impossible);</span>
true
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">Sudoku.Place(game, 1, 2);; # 2 is not in row, col or subsquare</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">IsBound(game.impossible);</span>
false
</pre></div>

<p><a id="X8401B31A879F9F9F" name="X8401B31A879F9F9F"></a></p>

<h5>6.17-3 Sudoku.RandomGame</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Sudoku.RandomGame</code>( [<var class="Arg">seed</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: A pair <code class="code">[str, seed]</code> of string and seed.</p>

<p>The optional argument <var class="Arg">seed</var>, if given, must be an integer. If not given some random integer from the current <strong class="pkg">GAP</strong> session is used. This function returns a random proper Sudoku game, where the board is described by a string <code class="code">str</code>, as explained in <code class="func">Sudoku.Init</code> (<a href="chap6_mj.html#X789D3D4C818F4BC2"><span class="RefLink">6.17-1</span></a>). With the same <var class="Arg">seed</var> the same board is returned.</p>

<p>The games computed by this function have the property that after removing any given entry the puzzle does no longer have a unique solution.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">Sudoku.RandomGame(5833750);</span>
[ " 1         2     43  2   68   72    8     6 2   1 9 8  8 3   9     \
47 3   7  18  ", 5833750 ]
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">last = Sudoku.RandomGame(last[2]);</span>
true
</pre></div>

<p><a id="X86917AC57C25A68F" name="X86917AC57C25A68F"></a></p>

<h5>6.17-4 Sudoku.SimpleDisplay</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Sudoku.SimpleDisplay</code>( <var class="Arg">game</var> )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Displays a Sudoku board on the terminal. (But see <code class="func">PlaySudoku</code> (<a href="chap6_mj.html#X7D19224478E86BB4"><span class="RefLink">6.17-8</span></a>) for a fancier interface.)</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">game := Sudoku.Init(" 3   68  | 85  1 69|  97   53|      79 |\</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput"> 6  47   |45  2    |89   2 1 | 4   8 7 | ");;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">Sudoku.SimpleDisplay(game);</span>
 3 |  6|8  
 85|  1| 69
  9|7  | 53
-----------
   |   |79 
 6 | 47|   
45 | 2 |   
-----------
89 |  2| 1 
 4 |  8| 7 
   |   |   
</pre></div>

<p><a id="X81F98C6C7C8415AB" name="X81F98C6C7C8415AB"></a></p>

<h5>6.17-5 Sudoku.DisplayString</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Sudoku.DisplayString</code>( <var class="Arg">game</var> )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>The string returned by this function can be used to display the Sudoku board <var class="Arg">game</var> on the terminal, using <code class="func">PrintFormattedString</code> (<a href="../../../pkg/GAPDoc.dev/doc/chap6_mj.html#X812A8326844BC910"><span class="RefLink">GAPDoc: PrintFormattedString</span></a>). The result depends on the value of <code class="code">GAPInfo.TermEncoding</code>.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">game := Sudoku.Init(" 3   68  | 85  1 69|  97   53|      79 |\</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput"> 6  47   |45  2    |89   2 1 | 4   8 7 | ");;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">str:= Sudoku.DisplayString( game );;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">PrintFormattedString( str );</span>
                     ┏━━━┯━━━┯━━━┳━━━┯━━━┯━━━┳━━━┯━━━┯━━━┓
                     ┃   │ 3 │   ┃   │   │ 6 ┃ 8 │   │   ┃
                     ┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
                     ┃   │ 8 │ 5 ┃   │   │ 1 ┃   │ 6 │ 9 ┃
                     ┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
                     ┃   │   │ 9 ┃ 7 │   │   ┃   │ 5 │ 3 ┃
                     ┣━━━┿━━━┿━━━╋━━━┿━━━┿━━━╋━━━┿━━━┿━━━┫
                     ┃   │   │   ┃   │   │   ┃ 7 │ 9 │   ┃
                     ┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
                     ┃   │ 6 │   ┃   │ 4 │ 7 ┃   │   │   ┃
                     ┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
                     ┃ 4 │ 5 │   ┃   │ 2 │   ┃   │   │   ┃
                     ┣━━━┿━━━┿━━━╋━━━┿━━━┿━━━╋━━━┿━━━┿━━━┫
                     ┃ 8 │ 9 │   ┃   │   │ 2 ┃   │ 1 │   ┃
                     ┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
                     ┃   │ 4 │   ┃   │   │ 8 ┃   │ 7 │   ┃
                     ┠───┼───┼───╂───┼───┼───╂───┼───┼───┨
                     ┃   │   │   ┃   │   │   ┃   │   │   ┃
                     ┗━━━┷━━━┷━━━┻━━━┷━━━┷━━━┻━━━┷━━━┷━━━┛
</pre></div>

<p><a id="X7C73C6D08293B3B8" name="X7C73C6D08293B3B8"></a></p>

<h5>6.17-6 Sudoku.OneSolution</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Sudoku.OneSolution</code>( <var class="Arg">game</var> )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: A completed Sudoku board that solves <var class="Arg">game</var>, or <code class="keyw">fail</code>.</p>

<p>Here <var class="Arg">game</var> must be a Sudoku board as returned by <code class="func">Sudoku.Init</code> (<a href="chap6_mj.html#X789D3D4C818F4BC2"><span class="RefLink">6.17-1</span></a>). It is not necessary that <var class="Arg">game</var> describes a proper Sudoku game (has a unique solution). It may have several solutions, then one random solution is returned. Or it may have no solution, then <code class="keyw">fail</code> is returned.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">Sudoku.SimpleDisplay(Sudoku.OneSolution(Sudoku.Init("  3")));</span>
493|876|251
861|542|739
527|193|648
-----------
942|618|573
156|739|482
738|425|916
-----------
289|354|167
375|961|824
614|287|395
</pre></div>

<p><a id="X865DDBDC7E16217F" name="X865DDBDC7E16217F"></a></p>

<h5>6.17-7 Sudoku.UniqueSolution</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Sudoku.UniqueSolution</code>( <var class="Arg">game</var> )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: A completed Sudoku board that solves <var class="Arg">game</var>, or <code class="keyw">false</code>, or <code class="keyw">fail</code>.</p>

<p>Here <var class="Arg">game</var> must be a Sudoku board as returned by <code class="func">Sudoku.Init</code> (<a href="chap6_mj.html#X789D3D4C818F4BC2"><span class="RefLink">6.17-1</span></a>). It is not necessary that <var class="Arg">game</var> describes a proper Sudoku game. If it has several solutions, then <code class="keyw">false</code> is returned. If it has no solution, then <code class="keyw">fail</code> is returned. Otherwise a board with the unique solution is returned.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">s := "      5  | 154 6 2 |9   5 3  |6 4      |   8     |8  9   53\</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">|     5   | 4   7  2|  91  8  ";;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">sol := Sudoku.UniqueSolution(Sudoku.Init(s));;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">Sudoku.SimpleDisplay(sol);</span>
438|219|576
715|436|928
962|758|314
-----------
694|573|281
153|862|749
827|941|653
-----------
281|695|437
546|387|192
379|124|865
</pre></div>

<p><a id="X7D19224478E86BB4" name="X7D19224478E86BB4"></a></p>

<h5>6.17-8 PlaySudoku</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; PlaySudoku</code>( [<var class="Arg">arg</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: A record describing the latest status of a Sudoku board.</p>

<p>This function allows one to solve Sudoku puzzles interactively. There are several possibilities for the optional argument <var class="Arg">arg</var>. It can either be a string, matrix or list of holes and integers as described in <code class="func">Sudoku.Init</code> (<a href="chap6_mj.html#X789D3D4C818F4BC2"><span class="RefLink">6.17-1</span></a>), or a board as returned by <code class="func">Sudoku.Init</code> (<a href="chap6_mj.html#X789D3D4C818F4BC2"><span class="RefLink">6.17-1</span></a>). Furthermore <var class="Arg">arg</var> can be an integer or not be given, in that case <code class="func">Sudoku.RandomGame</code> (<a href="chap6_mj.html#X8401B31A879F9F9F"><span class="RefLink">6.17-3</span></a>) is called to produce a random game.</p>

<p>The usage of this function is self-explanatory, pressing the <strong class="button">?</strong> key displays a help screen. Here, we mention two keys with a particular action: Pressing the <strong class="button">h</strong> key you get a hint, either an empty entry is filled or the program tells you that there is no solution (so you must delete some entries and try others). Pressing the <strong class="button">s</strong> key the puzzle is solved by the program or it tells you that there is no or no unique solution.</p>

<p><em>Implementation remarks</em>: The game board is implemented via a browse table, without row and column labels, with static header, dynamic footer, and individual <code class="code">minyx</code> function. Two modes are supported, with the standard actions for quitting the table and asking for help; one cell is selected in each mode. The first mode provides actions for moving the selected cell via arrow keys, for changing the value in the selected cell, for getting a hint or the (unique) solution. (Initial entries of the matrix cannot be changed via user input. They are shown in boldface.) The second mode serves for error handling: When the user enters an invalid number, i. e., a number that occurs already in the current row or column or subsquare, then the application switches to this mode, which causes that a message is shown in the footer, and the invalid entry is shown in red and blinking; similarly, error mode is entered if a hint or solution does not exist.</p>

<p>The separating lines are drawn using an individual <code class="code">SpecialGrid</code> function in the browse table, since they cannot be specified within the generic browse table functions.</p>

<p>Some standard <code class="func">NCurses.BrowseGeneric</code> (<a href="chap4_mj.html#X85FC163D87FAFD12"><span class="RefLink">4.3-1</span></a>) functionality, such as scrolling, selecting, and searching, are not available in this application.</p>

<p>The code can be found in the file <code class="file">app/sudoku.g</code> of the package.</p>

<p><a id="X804D66D67B908F30" name="X804D66D67B908F30"></a></p>

<h5>6.17-9 Sudoku.HTMLGame</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Sudoku.HTMLGame</code>( <var class="Arg">game</var> )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; Sudoku.LaTeXGame</code>( <var class="Arg">game</var> )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: A string with HTML or LaTeX code, respectively.</p>

<p>The argument of these functions is a record describing a Sudoku game. These functions return code for including the current status of the board into a webpage or a LaTeX document.</p>

<p><a id="X78E8DF8381626623" name="X78E8DF8381626623"></a></p>

<h4>6.18 <span class="Heading">Managing simple Workflows</span></h4>

<p>The idea behind the function <code class="func">BrowseWizard</code> (<a href="chap6_mj.html#X7E47FC2378C276C6"><span class="RefLink">6.18-1</span></a>) is that one wants to collect interactively information from a user, by asking a series of questions. Default answers for these questions can be provided, perhaps depending on the answers to earlier questions. The questions and answers are shown in a browse table, the current question is highlighted, and this selection is automatically moved to the next question after a valid answer has been entered. One may move up in the table, in order to change previous answers, but one can move down only to the first unanswered question. When the browse table gets closed (by submitting or canceling), a record with the collected information is returned.</p>

<p><a id="X7E47FC2378C276C6" name="X7E47FC2378C276C6"></a></p>

<h5>6.18-1 <span class="Heading">BrowseWizard</span></h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; BrowseWizard</code>( <var class="Arg">data</var> )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: a record.</p>

<p>The argument <var class="Arg">data</var> must be a record with the components <code class="code">steps</code> (a list of records, each representing one step in the questionnaire) and <code class="code">defaults</code> (a record). The component <code class="code">header</code>, if present, must be a string that is used as a header line; the default for it is <code class="code">"BrowseWizard"</code>.</p>

<p><code class="func">BrowseWizard</code> opens a browse table whose rows correspond to the entries of <var class="Arg">data</var><code class="code">.steps</code>. The components of <var class="Arg">data</var><code class="code">.defaults</code> are used as default values if they are present.</p>

<p>Beginning with the first entry, the user is asked to enter information, one record component per entry; this may be done by entering some text, by choosing keys from a given list of choices, or by editing a list of tabular data. Then one can go to the next step by hitting the <strong class="button">ArrowDown</strong> key (or by entering <strong class="button">d</strong>), and edit this step by hitting the <strong class="button">Enter</strong> key. One can also go back to previous steps and edit them again.</p>

<p>Some steps may be hidden from the user, depending on the information that has been entered for the previous steps. The hide conditions are evaluated after each step.</p>

<p>An implementation of a questionnaire is given by <code class="code">BrowseData.ChooseSimpleGroupQuestions</code>, which is used in the following example. The idea is to choose the description of a finite simple group by entering first the type (cyclic, alternating, classical, exceptional, or sporadic) and then the relevant parameter values. The information is then evaluated by <code class="code">BrowseData.InterpretSimpleGroupDescription</code>, which returns a description that fits to the return values of <code class="func">IsomorphismTypeInfoFiniteSimpleGroup</code> (<a href="../../../doc/ref/chap39_mj.html#X7C6AA6897C4409AC"><span class="RefLink">Reference: IsomorphismTypeInfoFiniteSimpleGroup</span></a>). For example, this function identifies the group <code class="code">PSL</code><span class="SimpleMath">\((4,2)\)</span> as <span class="SimpleMath">\(A_8\)</span>.)</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">d:= [ NCurses.keys.DOWN ];;  r:= [ NCurses.keys.RIGHT ];;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">c:= [ NCurses.keys.ENTER ];;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,             # confirm the initial message</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       d,             # enter the first step</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       d, d,          # go to the choice of classical groups</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,             # confirm this choice</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,             # enter the next step</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       d, d,          # go to the choice of unitary groups</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,             # confirm this choice</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,             # enter the next step</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "5", c,        # enter the dimension and confirm</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c,             # enter the next step</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       "3", c,        # enter the field size and confirm</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">       c ) );         # confirm all choices (closes the table)</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">res:= BrowseWizard( rec(</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     steps:= BrowseData.ChooseSimpleGroupQuestions,</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     defaults:= rec(),</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">     header:= "Choose a finite simple group" ) );;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">BrowseData.InterpretSimpleGroupDescription( res );</span>
rec( parameter := [ 4, 3 ], requestedname := "U5(3)", series := "2A", 
  shortname := "U5(3)" )
</pre></div>

<p>The supported components of each entry in <var class="Arg">data</var><code class="code">.steps</code> are as follows.</p>


<dl>
<dt><strong class="Mark"><code class="code">key</code></strong></dt>
<dd><p>a string, the name of the component of the result record that gets bound for this entry.</p>

</dd>
<dt><strong class="Mark"><code class="code">description</code></strong></dt>
<dd><p>a string describing what information shall be entered.</p>

</dd>
<dt><strong class="Mark"><code class="code">type</code></strong></dt>
<dd><p>one of <code class="code">"editstring"</code>, <code class="code">"edittable"</code>, <code class="code">"key"</code>, <code class="code">"keys"</code>, <code class="code">"ok"</code>, <code class="code">"okcancel"</code>, <code class="code">"submitcancelcontinue"</code>.</p>

</dd>
<dt><strong class="Mark"><code class="code">keys</code>
      (only if <code class="code">type</code> is <code class="code">"key"</code> or <code class="code">"keys"</code>)</strong></dt>
<dd><p>either the list of pairs <code class="code">[ key, alias ]</code> such that the user shall choose from the list of <code class="code">key</code> values (strings), and the <code class="code">alias</code> values (any <strong class="pkg">GAP</strong> object) corresponding to the chosen values are entered into the result record, or a function that takes <var class="Arg">steps</var> and the current result record as its arguments and returns the desired list of pairs.</p>

</dd>
<dt><strong class="Mark"><code class="code">validation</code> (optional)</strong></dt>
<dd><p>a function that takes <var class="Arg">steps</var>, the current result record, and a result candidate for the current step as its arguments; it returns <code class="keyw">true</code> if the result candidate is valid, and a string describing the reason for the failure otherwise.</p>

</dd>
<dt><strong class="Mark"><code class="code">default</code> (optional)</strong></dt>
<dd><p>depending on the <code class="code">type</code> value, the alias part(s) of the chosen key(s) or the string or the list of data records, or alternatively a function that takes <var class="Arg">steps</var> and the current result record as its arguments and returns the desired value. If the <code class="code">key</code> component of <var class="Arg">data</var><code class="code">.defaults</code> is bound and valid (according to the <code class="code">validation</code> function) then this value is taken as the default; otherwise, the <code class="code">default</code> component of the entry is taken as the default.</p>

</dd>
<dt><strong class="Mark"><code class="code">isVisible</code> (optional)</strong></dt>
<dd><p>a function that takes <var class="Arg">steps</var> and the current result record as its arguments and returns <code class="keyw">true</code> if the step shall be visible, and <code class="keyw">false</code> otherwise,</p>

</dd>
</dl>
<p>If the <code class="code">type</code> value of a step is <code class="code">"edittable"</code> then also the following components are mandatory.</p>


<dl>
<dt><strong class="Mark"><code class="code">list</code></strong></dt>
<dd><p>the current list of records to be edited; only strings are supported as the values of the record components.</p>

</dd>
<dt><strong class="Mark"><code class="code">mapping</code></strong></dt>
<dd><p>a list of pairs <code class="code">[ component, label ]</code> such that <code class="code">component</code> is the name of a component in the entries in <code class="code">list</code>, and <code class="code">label</code> is the label shown in the dialog box for editing the record.</p>

</dd>
<dt><strong class="Mark"><code class="code">choices</code> (optional)</strong></dt>
<dd><p>a list of records which can be added to <code class="code">list</code>.</p>

</dd>
<dt><strong class="Mark"><code class="code">rectodisp</code></strong></dt>
<dd><p>a function that takes a record from <code class="code">list</code> and returns a string that is shown in the browse table.</p>

</dd>
<dt><strong class="Mark"><code class="code">title</code></strong></dt>
<dd><p>a string, the header line of the dialog box for editing an entry.</p>

</dd>
</dl>
<p>The code of <code class="func">BrowseWizard</code>, <code class="code">BrowseData.ChooseSimpleGroupQuestions</code>, and <code class="code">BrowseData.InterpretSimpleGroupDescription</code> can be found in the file <code class="file">app/wizard.g</code> of the package.</p>

<p><a id="X7BCE1AE37EFCE91D" name="X7BCE1AE37EFCE91D"></a></p>

<h4>6.19 <span class="Heading">Utility for <strong class="pkg">GAP</strong> Demos</span></h4>

<p>This application can be used with <strong class="pkg">GAP</strong> if the user interface has <code class="code">readline</code> support. The purpose is to simplify the typing during a demonstration of <strong class="pkg">GAP</strong> commands.</p>

<p>The file format to specify <strong class="pkg">GAP</strong> code for a demonstration is very simple: it contains blocks of lines with <strong class="pkg">GAP</strong> input, separated by lines starting with the sequence <code class="code">#%</code>. Comments in such a file can be added to one or several lines starting with <code class="code">#%</code>. Here is the content of an example file <code class="file">demo.demo</code>:</p>


<pre class="normal">

#% Add comments after #% characters at the beginning of a line.
#% A comment can have several lines.
#% Here is a multi-line input block:
g := MathieuGroup(11);;
cl := ConjugacyClasses(g);
#% Calling a help page
?MathieuGroup
#% The next line contains a comment in the GAP session:
a := 12;; b := 13;; # assign two numbers
#%
a*b;
#%

</pre>

<p>(Single <code class="code">%</code> in the beginning of a line will also work as separators.)</p>

<p>A demonstration can be loaded into a <strong class="pkg">GAP</strong> session with the command</p>

<p><a id="X80F418C5835C62BA" name="X80F418C5835C62BA"></a></p>

<h5>6.19-1 LoadDemoFile</h5>

<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">&#8227; LoadDemoFile</code>( <var class="Arg">demoname</var>, <var class="Arg">demofile</var>[, <var class="Arg">singleline</var>] )</td><td class="tdright">(&nbsp;function&nbsp;)</td></tr></table></div>
<p>Returns: Nothing.</p>

<p>This function loads a demo file in the format described above. The argument <var class="Arg">demoname</var> is a string containing a name for the demo, and <var class="Arg">demofile</var> is the file name containing the demo.</p>

<p>If the optional argument <var class="Arg">singleline</var> is given and its value is <code class="keyw">true</code>, the demo behaves differently with respect to input blocks that span several lines. By default full blocks are treated as a single input line for <code class="code">readline</code> (maybe spanning several physical lines in the terminal). If <var class="Arg">singleline</var> is <code class="keyw">true</code> then all input lines of a block except the last one are sent to <strong class="pkg">GAP</strong> and are evaluated automatically before the last line of the block is displayed.</p>


<div class="example"><pre>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">dirs := DirectoriesPackageLibrary("Browse");;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">demofile := Filename(dirs, "../app/demo.demo");;</span>
<span class="GAPprompt">gap&gt;</span> <span class="GAPinput">if IsBound(GAPInfo.UseReadline) and GAPInfo.UseReadline = true then</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">  LoadDemoFile("My first demo", demofile);</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">  LoadDemoFile("My first demo (single lines)", demofile, true);</span>
<span class="GAPprompt">&gt;</span> <span class="GAPinput">fi;</span>
</pre></div>

<p>Many demos can be loaded at the same time. They are used with the <strong class="button">PageDown</strong> and <strong class="button">PageUp</strong> keys.</p>

<p>The <strong class="button">PageUp</strong> key leads to a (Browse) menu which allows one to choose a demo to start (if several are loaded), to stop a demo or to move to another position in the current demo (e.g., to go back to a previous point or to skip part of a demo).</p>

<p>The next input block of the current demo is copied into the current input line of the <strong class="pkg">GAP</strong> session by pressing the <strong class="button">PageDown</strong> key. This line is not yet sent to <strong class="pkg">GAP</strong>, use the <strong class="button">Return</strong> key if you want to evaluate the input. (You can also still edit the input line before evaluation.)</p>

<p>So, in the simplest case a demo can be done by just pressing <strong class="button">PageDown</strong> and <strong class="button">Return</strong> in turns. But it is always possible to type extra input during a demo by hand or to change the input lines from the demo file before evaluation. It is no problem if commands are interrupted by <strong class="button">Ctrl-C</strong>. During a demo you are in a normal <strong class="pkg">GAP</strong> session, this application only saves you some typing. The input lines from the demo are put into the history of the session as if they were typed by hand.</p>

<p>Try it yourself with the two demos loaded in the example. This also shows the different behaviour between default and single line mode.</p>


<div class="chlinkprevnextbot">&nbsp;<a href="chap0_mj.html">[Top of Book]</a>&nbsp;  <a href="chap0_mj.html#contents">[Contents]</a>&nbsp;  &nbsp;<a href="chap5_mj.html">[Previous Chapter]</a>&nbsp;  &nbsp;<a href="chapA_mj.html">[Next Chapter]</a>&nbsp;  </div>


<div class="chlinkbot"><span class="chlink1">Goto Chapter: </span><a href="chap0_mj.html">Top</a>  <a href="chap1_mj.html">1</a>  <a href="chap2_mj.html">2</a>  <a href="chap3_mj.html">3</a>  <a href="chap4_mj.html">4</a>  <a href="chap5_mj.html">5</a>  <a href="chap6_mj.html">6</a>  <a href="chapA_mj.html">A</a>  <a href="chapBib_mj.html">Bib</a>  <a href="chapInd_mj.html">Ind</a>  </div>

<hr />
<p class="foot">generated by <a href="https://www.math.rwth-aachen.de/~Frank.Luebeck/GAPDoc">GAPDoc2HTML</a></p>
</body>
</html>