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"> <a href="chap0_mj.html">[Top of Book]</a> <a href="chap0_mj.html#contents">[Contents]</a> <a href="chap5_mj.html">[Previous Chapter]</a> <a href="chapA_mj.html">[Next Chapter]</a> </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"> </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"> </span><a href="chap6_mj.html#X7FDD696B7DD54A6E">6.1-1 Browse</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X8295F85D87118C83">6.2-1 NCurses.BrowseDenseList</a></span>
<span class="ContSS"><br /><span class="nocss"> </span><a href="chap6_mj.html#X7AD78A0B7BEDBB20">6.2-2 Browse</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X870C744182073CF6">6.3-1 Browse</a></span>
<span class="ContSS"><br /><span class="nocss"> </span><a href="chap6_mj.html#X7D80A56D853C9655">6.3-2 BrowseDecompositionMatrix</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X7F4BD9C580BBBAA4">6.4-1 Browse</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </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"> </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"> </span><a href="chap6_mj.html#X7D79DF9181A15EDF">6.6-1 BrowseGapManuals</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X7F0FE4CC7F46ABF3">6.7-1 BrowseBibliography</a></span>
<span class="ContSS"><br /><span class="nocss"> </span><a href="chap6_mj.html#X7E4B5E277D08987B">6.7-2 BrowseBibliographyGapPackages</a></span>
<span class="ContSS"><br /><span class="nocss"> </span><a href="chap6_mj.html#X81F1558678ACDB4A">6.7-3 BrowseMSC</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X7B42091982DE7AE7">6.8-1 BrowseProfile</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X8030B1688335783D">6.9-1 BrowsePackageVariables</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X7A7B712E7A06449F">6.10-1 BrowseUserPreferences</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X850C786C87A4877B">6.11-1 BrowseGapData</a></span>
<span class="ContSS"><br /><span class="nocss"> </span><a href="chap6_mj.html#X7FC24FCE7A0C6058">6.11-2 BrowseGapDataAdd</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X859682DE8397261E">6.12-1 BrowseDirectory</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X7EF5FCBD7DAFFAF3">6.13-1 BrowsePuzzle</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X82C8691380FCB674">6.14-1 PegSolitaire</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X8100659E81FFE9A2">6.15-1 BrowseRubiksCube</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X7FCFC5858584F46E">6.16-1 BrowseChangeSides</a></span>
</div></div>
<div class="ContSect"><span class="tocline"><span class="nocss"> </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"> </span><a href="chap6_mj.html#X789D3D4C818F4BC2">6.17-1 Sudoku.Init</a></span>
<span class="ContSS"><br /><span class="nocss"> </span><a href="chap6_mj.html#X86A5C6CE79DD67EE">6.17-2 Sudoku.Place</a></span>
<span class="ContSS"><br /><span class="nocss"> </span><a href="chap6_mj.html#X8401B31A879F9F9F">6.17-3 Sudoku.RandomGame</a></span>
<span class="ContSS"><br /><span class="nocss"> </span><a href="chap6_mj.html#X86917AC57C25A68F">6.17-4 Sudoku.SimpleDisplay</a></span>
<span class="ContSS"><br /><span class="nocss"> </span><a href="chap6_mj.html#X81F98C6C7C8415AB">6.17-5 Sudoku.DisplayString</a></span>
<span class="ContSS"><br /><span class="nocss"> </span><a href="chap6_mj.html#X7C73C6D08293B3B8">6.17-6 Sudoku.OneSolution</a></span>
<span class="ContSS"><br /><span class="nocss"> </span><a href="chap6_mj.html#X865DDBDC7E16217F">6.17-7 Sudoku.UniqueSolution</a></span>
<span class="ContSS"><br /><span class="nocss"> </span><a href="chap6_mj.html#X7D19224478E86BB4">6.17-8 PlaySudoku</a></span>
<span class="ContSS"><br /><span class="nocss"> </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"> </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"> </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"> </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"> </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">‣ Browse</code>( <var class="Arg">obj</var>[, <var class="Arg">arec</var>] )</td><td class="tdright">( operation )</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">‣ NCurses.BrowseDenseList</code>( <var class="Arg">list</var>, <var class="Arg">arec</var> )</td><td class="tdright">( function )</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">‣ Browse</code>( <var class="Arg">list</var> )</td><td class="tdright">( method )</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></span> <span class="GAPinput">n:= [ 14, 14, 14, 14 ];;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">input:= Concatenation( n, n, n, "Q" );; # ``do nothing and quit''</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( input );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">Browse( RandomMat( 10, 10, Integers ) );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( input );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">Browse( RandomMat( 10, 10, GF(3) ) );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( input );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">Browse( RandomMat( 10, 10, GF(4) ) );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( input );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">Browse( RandomMat( 10, 10, Integers mod 6 ) );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( input );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">Browse( RandomMat( 10, 10, GF( NextPrimeInt( 2^16 ) ) ) );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( input );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">Browse( RandomMat( 10, 10, GF( 2^20 ) ) );</span>
<span class="GAPprompt">gap></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">‣ Browse</code>( <var class="Arg">tbl</var>[, <var class="Arg">options</var>] )</td><td class="tdright">( method )</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></span> <span class="GAPinput">if TestPackageAvailability( "CTblLib" ) = true then</span>
<span class="GAPprompt">></span> <span class="GAPinput"> BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # scroll in the table</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "DRULdddddrrrrrlluu",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # select an entry and move it around</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "seddrruuuddlll",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # search for the pattern 135 (six times)</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "/135", [ NCurses.keys.ENTER ], "nnnnn",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # deselect the entry, select the first column</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "qLsc",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # sort and categorize by this column</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "sc",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # select the first row, move down the selection</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "srdddd",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # expand the selected category, scroll the selection down</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "xd",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # and quit the application</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "Q" ) );</span>
<span class="GAPprompt">></span> <span class="GAPinput"> Browse( CharacterTable( "HN" ) );</span>
<span class="GAPprompt">></span> <span class="GAPinput"> BrowseData.SetReplay( false );</span>
<span class="GAPprompt">></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">‣ BrowseDecompositionMatrix</code>( <var class="Arg">modtbl</var>[, <var class="Arg">b</var>][, <var class="Arg">options</var>] )</td><td class="tdright">( function )</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></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # select the first entry</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "se",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # scroll in the table</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "drrrr",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # keep the table open for a while</span>
<span class="GAPprompt">></span> <span class="GAPinput"> [ 14, 14, 14, 14, 14 ],</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # and quit the application</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "Q" ) );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseDecompositionMatrix( CharacterTable( "J1" ) mod 2 );</span>
<span class="GAPprompt">gap></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">‣ Browse</code>( <var class="Arg">tom</var>[, <var class="Arg">options</var>] )</td><td class="tdright">( method )</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></span> <span class="GAPinput">if TestPackageAvailability( "TomLib" ) = true then</span>
<span class="GAPprompt">></span> <span class="GAPinput"> BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # scroll in the table</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "DDRRR",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # search for the (exact) value 100 (three times)</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "/100",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> [ NCurses.keys.DOWN, NCurses.keys.DOWN, NCurses.keys.RIGHT ],</span>
<span class="GAPprompt">></span> <span class="GAPinput"> [ NCurses.keys.DOWN, NCurses.keys.DOWN, NCurses.keys.DOWN ],</span>
<span class="GAPprompt">></span> <span class="GAPinput"> [ NCurses.keys.RIGHT, NCurses.keys.ENTER ], "nn",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # no more occurrences of 100, confirm</span>
<span class="GAPprompt">></span> <span class="GAPinput"> [ NCurses.keys.ENTER ],</span>
<span class="GAPprompt">></span> <span class="GAPinput"> # and quit the application</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "Q" ) );</span>
<span class="GAPprompt">></span> <span class="GAPinput"> Browse( TableOfMarks( "A10" ) );</span>
<span class="GAPprompt">></span> <span class="GAPinput"> BrowseData.SetReplay( false );</span>
<span class="GAPprompt">></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">‣ 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">( function )</td></tr></table></div>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ BrowseAtlasInfo</code>( <var class="Arg">gapname</var>[, <var class="Arg">std</var>][, <var class="Arg">...</var>] )</td><td class="tdright">( function )</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></span> <span class="GAPinput">d:= [ NCurses.keys.DOWN ];; r:= [ NCurses.keys.RIGHT ];;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">c:= [ NCurses.keys.ENTER ];;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "/A5", # Find the string A5 ...</span>
<span class="GAPprompt">></span> <span class="GAPinput"> d, d, r, # ... such that just the word matches,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # start the search,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # click the table entry A5,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> d, d, # move down two rows,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # click the row for this representation,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "Q", # quit the second level table,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> d, d, # move down two rows,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # click the table entry A6,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> d, # move down one row,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # click the first row,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "Q", # quit the second level table,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "Q" ) ); # and quit the application.</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">if IsBound( BrowseAtlasInfo ) and IsBound( AtlasProgramInfo ) then</span>
<span class="GAPprompt">></span> <span class="GAPinput"> SetUserPreference( "AtlasRep", "AtlasRepMarkNonCoreData", "" );</span>
<span class="GAPprompt">></span> <span class="GAPinput"> tworeps:= BrowseAtlasInfo();</span>
<span class="GAPprompt">></span> <span class="GAPinput"> else</span>
<span class="GAPprompt">></span> <span class="GAPinput"> tworeps:= [ fail ];</span>
<span class="GAPprompt">></span> <span class="GAPinput"> fi;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">if fail in tworeps then</span>
<span class="GAPprompt">></span> <span class="GAPinput"> Print( "no access to the Web ATLAS\n" );</span>
<span class="GAPprompt">></span> <span class="GAPinput"> else</span>
<span class="GAPprompt">></span> <span class="GAPinput"> Print( List( tworeps, x -> x.identifier[1] ), "\n" );</span>
<span class="GAPprompt">></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">‣ BrowseGapManuals</code>( [<var class="Arg">start</var>] )</td><td class="tdright">( function )</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></span> <span class="GAPinput">n:= [ 14, 14, 14 ];; # ``do nothing''</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "xdxd", # expand a Tutorial section</span>
<span class="GAPprompt">></span> <span class="GAPinput"> n, "Q" ) ); # and quit</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseGapManuals( "inline/collapsed" );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "/Browse", [ NCurses.keys.ENTER ], # search for "Browse"</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "xdxddxd", # expand a section</span>
<span class="GAPprompt">></span> <span class="GAPinput"> n, "Q" ) ); # and quit</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseGapManuals( "inline/collapsed" );</span>
<span class="GAPprompt">gap></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">‣ BrowseBibliography</code>( [<var class="Arg">bibfiles</var>] )</td><td class="tdright">( function )</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></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></span> <span class="GAPinput"># sort and categorize by year, scroll down, expand a category row</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( "scrrscsedddddxdddddQ" );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseBibliography();;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput"># sort & categorize by authors, expand all category rows, scroll down</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( "scscXseddddddQ" );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseBibliography();;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput"># sort and categorize by journal, search for a journal name, expand</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation( "scrrrsc/J. Algebra",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> [ NCurses.keys.ENTER ], "nxdddQ" ) );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseBibliography();;</span>
<span class="GAPprompt">gap></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">‣ BrowseBibliographyGapPackages</code>( )</td><td class="tdright">( function )</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">‣ BrowseMSC</code>( [<var class="Arg">version</var>] )</td><td class="tdright">( function )</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">‣ BrowseProfile</code>( [<var class="Arg">functions</var>][,] [<var class="Arg">mincount</var>, <var class="Arg">mintime</var>] )</td><td class="tdright">( function )</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></span> <span class="GAPinput">n:= [ 14, 14, 14, 14, 14 ];; # ``do nothing''</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">ProfileOperationsAndMethods( true ); # collect some data</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">ConjugacyClasses( PrimitiveGroup( 24, 1 ) );;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">ProfileOperationsAndMethods( false );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "e", # edit threshold paras</span>
<span class="GAPprompt">></span> <span class="GAPinput"> [ NCurses.keys.DC ], "2", "\t", # replace 10000 by 20000</span>
<span class="GAPprompt">></span> <span class="GAPinput"> [ NCurses.keys.DC ], "2", # replace 30 by 20</span>
<span class="GAPprompt">></span> <span class="GAPinput"> [ NCurses.keys.ENTER ], # commit the changes</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "scso", # sort by column 1,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> n,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "rso", # sort by column 2,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> n,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "rso", # sort by column 3,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> n,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "q", # deselect the column,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "/Normalizer", [ NCurses.keys.ENTER ], # search for a function,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> n, n, n, "Q" ) ); # and quit</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseProfile();</span>
<span class="GAPprompt">gap></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">‣ BrowsePackageVariables</code>( <var class="Arg">pkgname</var>[, <var class="Arg">version</var>][, <var class="Arg">arec</var>] )</td><td class="tdright">( function )</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></span> <span class="GAPinput">pkgname:= "Browse";;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">info:= PackageVariablesInfo( pkgname, "" );;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">LoadPackage( "Browse" );;</span>
<span class="GAPprompt">gap></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">‣ BrowseUserPreferences</code>( <var class="Arg">package1</var>, <var class="Arg">package2</var>, <var class="Arg">...</var> )</td><td class="tdright">( function )</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></span> <span class="GAPinput">d:= [ NCurses.keys.DOWN ];; </span>
<span class="GAPprompt">gap></span> <span class="GAPinput">c:= [ NCurses.keys.ENTER ];; </span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "/PackagesToLoad", # enter a search string,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # start the search,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # edit the entry (a list of choices),</span>
<span class="GAPprompt">></span> <span class="GAPinput"> " ", d, # toggle the first four values,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> " ", d, #</span>
<span class="GAPprompt">></span> <span class="GAPinput"> " ", d, #</span>
<span class="GAPprompt">></span> <span class="GAPinput"> " ", d, #</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # submit the values,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "Q", # quit the table,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c ) ); # choose "cancel": do not apply the changes.</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseUserPreferences();</span>
<span class="GAPprompt">gap></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">‣ BrowseGapData</code>( )</td><td class="tdright">( function )</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></span> <span class="GAPinput">n:= [ 14, 14, 14 ];; # ``do nothing''</span>
<span class="GAPprompt">gap></span> <span class="GAPinput"># open the overview of Conway polynomials</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation( "/Conway Polynomials",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> [ NCurses.keys.ENTER, NCurses.keys.ENTER ], "srdddd", n, "Q" ) );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseGapData();;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput"># open the overview of GAP packages</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation( "/GAP Packages",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> [ NCurses.keys.ENTER, NCurses.keys.ENTER ], "/Browse",</span>
<span class="GAPprompt">></span> <span class="GAPinput"> [ NCurses.keys.ENTER ], "n", n, "Q" ) );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseGapData();;</span>
<span class="GAPprompt">gap></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">‣ 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">( function )</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">‣ BrowseDirectory</code>( [<var class="Arg">dir</var>] )</td><td class="tdright">( function )</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></span> <span class="GAPinput">n:= [ 14, 14, 14 ];; # ``do nothing''</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "q", # leave the selection</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "X", # expand all categories</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "/filetree", [ NCurses.keys.ENTER ], # search for "filetree"</span>
<span class="GAPprompt">></span> <span class="GAPinput"> n, "Q" ) ); # and quit</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">dir:= DirectoriesPackageLibrary( "Browse", "" )[1];;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">if IsBound( BrowseDirectory ) then</span>
<span class="GAPprompt">></span> <span class="GAPinput"> BrowseDirectory( dir );</span>
<span class="GAPprompt">></span> <span class="GAPinput"> fi;</span>
<span class="GAPprompt">gap></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">‣ BrowsePuzzle</code>( [<var class="Arg">m</var>, <var class="Arg">n</var>[, <var class="Arg">pi</var>]] )</td><td class="tdright">( function )</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></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> BrowsePuzzleSolution.steps, "Q" ) );</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowsePuzzle( 4, 4, BrowsePuzzleSolution.init );;</span>
<span class="GAPprompt">gap></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">‣ PegSolitaire</code>( [<var class="Arg">format</var>][,] [<var class="Arg">nrholes</var>][,] [<var class="Arg">twoModes</var>] )</td><td class="tdright">( function )</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></span> <span class="GAPinput">for n in [ 33, 37, 45 ] do</span>
<span class="GAPprompt">></span> <span class="GAPinput"> BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> PegSolitaireSolutions.( String( n ) ), "Q" ) );</span>
<span class="GAPprompt">></span> <span class="GAPinput"> PegSolitaire( n );</span>
<span class="GAPprompt">></span> <span class="GAPinput"> PegSolitaire( "large", n );</span>
<span class="GAPprompt">></span> <span class="GAPinput"> PegSolitaire( n, true );</span>
<span class="GAPprompt">></span> <span class="GAPinput"> PegSolitaire( "large", n, true );</span>
<span class="GAPprompt">></span> <span class="GAPinput">od;</span>
<span class="GAPprompt">gap></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></span> <span class="GAPinput">cubegens := [</span>
<span class="GAPprompt">></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">></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">></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">></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">></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">></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">></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">‣ BrowseRubiksCube</code>( [<var class="Arg">format</var>][,] [<var class="Arg">pi</var>] )</td><td class="tdright">( function )</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></span> <span class="GAPinput">choice:= List( [ 1 .. 30 ], i -> Random( [ 1 .. 6 ] ) );;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">input:= List( "tlfrbd", IntChar ){ choice };;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> input{ [ 1 .. 20 ] },</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "s", # switch to number display</span>
<span class="GAPprompt">></span> <span class="GAPinput"> input{ [ 21 .. 25 ] },</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "s", # switch to color display</span>
<span class="GAPprompt">></span> <span class="GAPinput"> input{ [ 26 .. 30 ] },</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "Q" ) );; # quit the browse table</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseRubiksCube( Product( cubegens{ choice } ) );;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseRubiksCube( "large", Product( cubegens{ choice } ) );;</span>
<span class="GAPprompt">gap></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">‣ BrowseChangeSides</code>( )</td><td class="tdright">( function )</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></span> <span class="GAPinput">for entry in BrowseChangeSidesSolutions do</span>
<span class="GAPprompt">></span> <span class="GAPinput"> BrowseData.SetReplay( Concatenation( entry, "Q" ) );</span>
<span class="GAPprompt">></span> <span class="GAPinput"> BrowseChangeSides();</span>
<span class="GAPprompt">></span> <span class="GAPinput">od;</span>
<span class="GAPprompt">gap></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">‣ Sudoku.Init</code>( [<var class="Arg">arg</var>] )</td><td class="tdright">( function )</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></span> <span class="GAPinput">game := Sudoku.Init(" 3 68 | 85 1 69| 97 53| 79 |\</span>
<span class="GAPprompt">></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">‣ Sudoku.Place</code>( <var class="Arg">game</var>, <var class="Arg">i</var>, <var class="Arg">n</var> )</td><td class="tdright">( function )</td></tr></table></div>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ Sudoku.Remove</code>( <var class="Arg">game</var>, <var class="Arg">i</var> )</td><td class="tdright">( function )</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></span> <span class="GAPinput">game := Sudoku.Init(" 3 68 | 85 1 69| 97 53| 79 |\</span>
<span class="GAPprompt">></span> <span class="GAPinput"> 6 47 |45 2 |89 2 1 | 4 8 7 | ");;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">Sudoku.Place(game, 1, 3);; # 3 is already in first row</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">IsBound(game.impossible);</span>
true
<span class="GAPprompt">gap></span> <span class="GAPinput">Sudoku.Place(game, 1, 2);; # 2 is not in row, col or subsquare</span>
<span class="GAPprompt">gap></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">‣ Sudoku.RandomGame</code>( [<var class="Arg">seed</var>] )</td><td class="tdright">( function )</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></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></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">‣ Sudoku.SimpleDisplay</code>( <var class="Arg">game</var> )</td><td class="tdright">( function )</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></span> <span class="GAPinput">game := Sudoku.Init(" 3 68 | 85 1 69| 97 53| 79 |\</span>
<span class="GAPprompt">></span> <span class="GAPinput"> 6 47 |45 2 |89 2 1 | 4 8 7 | ");;</span>
<span class="GAPprompt">gap></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">‣ Sudoku.DisplayString</code>( <var class="Arg">game</var> )</td><td class="tdright">( function )</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></span> <span class="GAPinput">game := Sudoku.Init(" 3 68 | 85 1 69| 97 53| 79 |\</span>
<span class="GAPprompt">></span> <span class="GAPinput"> 6 47 |45 2 |89 2 1 | 4 8 7 | ");;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">str:= Sudoku.DisplayString( game );;</span>
<span class="GAPprompt">gap></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">‣ Sudoku.OneSolution</code>( <var class="Arg">game</var> )</td><td class="tdright">( function )</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></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">‣ Sudoku.UniqueSolution</code>( <var class="Arg">game</var> )</td><td class="tdright">( function )</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></span> <span class="GAPinput">s := " 5 | 154 6 2 |9 5 3 |6 4 | 8 |8 9 53\</span>
<span class="GAPprompt">></span> <span class="GAPinput">| 5 | 4 7 2| 91 8 ";;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">sol := Sudoku.UniqueSolution(Sudoku.Init(s));;</span>
<span class="GAPprompt">gap></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">‣ PlaySudoku</code>( [<var class="Arg">arg</var>] )</td><td class="tdright">( function )</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">‣ Sudoku.HTMLGame</code>( <var class="Arg">game</var> )</td><td class="tdright">( function )</td></tr></table></div>
<div class="func"><table class="func" width="100%"><tr><td class="tdleft"><code class="func">‣ Sudoku.LaTeXGame</code>( <var class="Arg">game</var> )</td><td class="tdright">( function )</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">‣ BrowseWizard</code>( <var class="Arg">data</var> )</td><td class="tdright">( function )</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></span> <span class="GAPinput">d:= [ NCurses.keys.DOWN ];; r:= [ NCurses.keys.RIGHT ];;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">c:= [ NCurses.keys.ENTER ];;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( Concatenation(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # confirm the initial message</span>
<span class="GAPprompt">></span> <span class="GAPinput"> d, # enter the first step</span>
<span class="GAPprompt">></span> <span class="GAPinput"> d, d, # go to the choice of classical groups</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # confirm this choice</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # enter the next step</span>
<span class="GAPprompt">></span> <span class="GAPinput"> d, d, # go to the choice of unitary groups</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # confirm this choice</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # enter the next step</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "5", c, # enter the dimension and confirm</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c, # enter the next step</span>
<span class="GAPprompt">></span> <span class="GAPinput"> "3", c, # enter the field size and confirm</span>
<span class="GAPprompt">></span> <span class="GAPinput"> c ) ); # confirm all choices (closes the table)</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">res:= BrowseWizard( rec(</span>
<span class="GAPprompt">></span> <span class="GAPinput"> steps:= BrowseData.ChooseSimpleGroupQuestions,</span>
<span class="GAPprompt">></span> <span class="GAPinput"> defaults:= rec(),</span>
<span class="GAPprompt">></span> <span class="GAPinput"> header:= "Choose a finite simple group" ) );;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">BrowseData.SetReplay( false );</span>
<span class="GAPprompt">gap></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">‣ LoadDemoFile</code>( <var class="Arg">demoname</var>, <var class="Arg">demofile</var>[, <var class="Arg">singleline</var>] )</td><td class="tdright">( function )</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></span> <span class="GAPinput">dirs := DirectoriesPackageLibrary("Browse");;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">demofile := Filename(dirs, "../app/demo.demo");;</span>
<span class="GAPprompt">gap></span> <span class="GAPinput">if IsBound(GAPInfo.UseReadline) and GAPInfo.UseReadline = true then</span>
<span class="GAPprompt">></span> <span class="GAPinput"> LoadDemoFile("My first demo", demofile);</span>
<span class="GAPprompt">></span> <span class="GAPinput"> LoadDemoFile("My first demo (single lines)", demofile, true);</span>
<span class="GAPprompt">></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"> <a href="chap0_mj.html">[Top of Book]</a> <a href="chap0_mj.html#contents">[Contents]</a> <a href="chap5_mj.html">[Previous Chapter]</a> <a href="chapA_mj.html">[Next Chapter]</a> </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>
|