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 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 1624 1625 1626 1627 1628 1629 1630 1631 1632 1633 1634 1635 1636 1637 1638 1639 1640 1641 1642 1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 1655 1656 1657 1658 1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690 1691 1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 1703 1704 1705 1706 1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 1717 1718 1719 1720 1721 1722 1723 1724 1725 1726 1727 1728 1729 1730 1731 1732 1733 1734 1735 1736 1737 1738 1739 1740 1741 1742 1743 1744 1745 1746 1747 1748 1749 1750 1751 1752 1753 1754 1755 1756 1757 1758 1759 1760 1761 1762 1763 1764 1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775 1776 1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825 1826 1827 1828 1829 1830 1831 1832 1833 1834 1835 1836 1837 1838 1839 1840
|
/*
This file contains docstrings for use in the Python bindings.
Do not edit! They were automatically extracted by ../gendoc.sh.
*/
#if defined(__GNUG__)
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
#endif
namespace regina::python::doc {
// Docstring regina::python::doc::GraphConstraint
static const char *GraphConstraint =
R"doc(Represents different classes of graph embeddings that one might want
to generate. Specifically, this enumeration type is used with the
routine ModelLinkGraph::generateAllEmbeddings().
These values can be combined using the bitwise OR operator, resulting
in an object of type ``Flags<GraphConstraint>``. If a graph generation
function takes an argument of type ``Flags<GraphConstraint>``, then it
will only generate those graphs that satisfy _all_ of the constraints
that have been ORed together. For such an argument, you can pass a
single GraphConstraint constant, or a bitwise combination of such
constants ``(flag1 | flag2)``, or empty braces ``{}`` to indicate no
flags at all (which is equivalent to passing
``GraphConstraint::All``).)doc";
// Docstring regina::python::doc::ModelLinkGraph
static const char *ModelLinkGraph =
R"doc(Represents an undirected 4-valent graph with a specific embedding in
some closed orientable surface. This class only stores the graph and a
local description of the embedding (i.e., a cyclic ordering of arcs
around each node). It does not store the surface explicitly, though
the surface is implied from the embedding - if you need it you can
always access a full description of the surface by calling cells().
In particular, the surface is assumed to be the minimal genus surface
in which the graph embeds. Each connected component of the graph is
embedded in a separate connected component of the surface, and each
component of the surface is formed from a collection of discs (or
_cells_) whose boundaries follow the nodes and arcs of the graph
according to the local embedding.
Regina uses graphs like these as model graphs for classical or virtual
link diagrams, where each node of the graph becomes a classical
crossing. If the surface is a collection of 2-spheres, then the graph
is planar and models a _classical_ link diagram. If the surface has
genus, then the graph is non-planar and instead models a _virtual_
link diagram.
Currently this class does not support circular graph components
(which, in a link diagram, would correspond to zero-crossing unknot
components of the link).
For Boost users: if you wish to study the underlying graph of an
existing link, you do not need to create a ModelLinkGraph - instead
you can include link/graph.h and then use Link directly as a directed
graph type with the Boost Graph Library.
This class implements C++ move semantics and adheres to the C++
Swappable requirement. It is designed to avoid deep copies wherever
possible, even when passing or returning objects by value.)doc";
// Docstring regina::python::doc::ModelLinkGraphArc
static const char *ModelLinkGraphArc =
R"doc(A reference to an outgoing edge from a node of a model graph for a
knot or link.
Edges of model graphs are not directed, and so the same edge will
appear twice as a ModelLinkGraphArc (once from each of its endpoints).
This class is a simple wrapper that stores (i) a pointer to the
relevant node of the graph; and (ii) an integer to denote which of the
four outgoing arcs we are using from that node. Recall that the four
outgoing arcs for each node are indexed in clockwise order.
A "null arc" is one whose node is the null pointer.
These objects are small enough to pass by value and swap with
std::swap(), with no need for any specialised move operations or swap
functions.)doc";
// Docstring regina::python::doc::ModelLinkGraphCells
static const char *ModelLinkGraphCells =
R"doc(Describes the cellular decomposition of a closed orientable surface
induced by a 4-valent graph embedded within it.
The graph is represented by an object of type ModelLinkGraph, which
encodes a local embedding of the graph within the surface (i.e., a
cyclic ordering of arcs around each graph node). The nodes and arcs of
this graph form the vertices and edges of the cellular decomposition,
and the 2-cells are topological discs whose boundaries follow these
nodes and arcs according to their local embeddings. The main purpose
of this class is to deduce and describe those 2-cells.
As of Regina 7.4, this class can now work with graphs that are non-
planar (resulting in a surface with positive genus), disconnected
(resulting in a surface that is likewise disconnected), and/or empty
(resulting in an empty surface).
Cellular decompositions do not support value semantics: they cannot be
copied, swapped, or manually constructed. Instead they are computed
properties of model graphs, and are only accessible via const
reference through the member function ModelLinkGraph::cells().)doc";
// Docstring regina::python::doc::ModelLinkGraphNode
static const char *ModelLinkGraphNode =
R"doc(Represents a single node in a model graph for a knot or link.
If a graph has *n* nodes, then these are numbered 0,...,*n*-1. The
number assigned to this node can be accessed by calling index(). Note
that nodes may be reindexed when other nodes are added or removed - if
you wish to track a particular node through such operations then you
should use a pointer to the relevant ModelLinkGraphNode instead.
Graph nodes do not support value semantics: they cannot be copied,
swapped, or manually constructed. Their location in memory defines
them, and they are often passed and compared by pointer. End users are
never responsible for their memory management; this is all taken care
of by the ModelLinkGraph to which they belong.)doc";
// Docstring regina::python::doc::__bor
static const char *__bor =
R"doc(Returns the bitwise OR of the two given flags.
Parameter ``lhs``:
the first flag to combine.
Parameter ``rhs``:
the second flag to combine.
Returns:
the combination of both flags.)doc";
namespace GraphConstraint_ {
// Docstring regina::python::doc::GraphConstraint_::All
static const char *All = R"doc(Indicates that all graph embeddings should be generated.)doc";
// Docstring regina::python::doc::GraphConstraint_::NoTwists
static const char *NoTwists =
R"doc(Indicates that only graph embeddings without twists should be
generated.
By a _twist_, we mean that the embedding has some node with two
adjacent arcs connected together. An embedding that fails this
constraint must always model knot or links with twists that can be
undone using type I Reidemeister moves.)doc";
// Docstring regina::python::doc::GraphConstraint_::SingleTraversal
static const char *SingleTraversal =
R"doc(Indicates that only graph embeddings with a single traversal should be
generated. That is, for every embedding *e* that is generated,
``e.countTraversals()`` should be precisely 1.
An embedding that satisfies this constraint must always model knots
(classical or virtual). An embedding that fails this constraint must
either be empty, or must always model multiple-component links.)doc";
}
namespace ModelLinkGraphArc_ {
// Docstring regina::python::doc::ModelLinkGraphArc_::__as_bool
static const char *__as_bool =
R"doc(Tests whether this is a non-null arc.
Returns:
``True`` if this is not a null arc (i.e., node() does not return a
null pointer), or ``False`` if this is a null arc.)doc";
// Docstring regina::python::doc::ModelLinkGraphArc_::__copy
static const char *__copy = R"doc(Creates a new copy of the given arc reference.)doc";
// Docstring regina::python::doc::ModelLinkGraphArc_::__dec
static const char *__dec =
R"doc(Changes to the previous outgoing link arc from the same node.
This effectively rotates the arc in an anticlockwise direction around
the node. In particular, it decrements the value returned by arc(),
modulo 4.
This is a postdecrement operator: the object will be changed, but a
copy of the original arc will be returned.
Precondition:
This is not a null arc, i.e., node() does not return ``None``.
Python:
This routine is available under the name dec().
Returns:
a copy of this object before the change took place.)doc";
// Docstring regina::python::doc::ModelLinkGraphArc_::__default
static const char *__default =
R"doc(Initialises this to a null arc.
The pointer returned by node() will be ``None``, and the integer
returned by arc() will be 0.)doc";
// Docstring regina::python::doc::ModelLinkGraphArc_::__eq
static const char *__eq =
R"doc(Tests whether this and the given arc reference are identical.
Two references are identical if and only if they return the same
values for both node() and arc().
.. warning::
If you create a null arc by calling ModelLinkGraphArc(``None``,
*i*) for some non-zero *i*, then this will _not_ be considered
equal to the null arc created by calling ModelLinkGraphArc(),
since the latter is equivalent to calling
ModelLinkGraphArc(``None``, 0).
Returns:
``True`` if and only if this and the given arc reference are
identical.)doc";
// Docstring regina::python::doc::ModelLinkGraphArc_::__inc
static const char *__inc =
R"doc(Changes to the next outgoing link arc from the same node.
This effectively rotates the arc in a clockwise direction around the
node. In particular, it increments the value returned by arc(), modulo
4.
This is a postincrement operator: the object will be changed, but a
copy of the original arc will be returned.
Precondition:
This is not a null arc, i.e., node() does not return ``None``.
Python:
This routine is available under the name inc().
Returns:
a copy of this object before the change took place.)doc";
// Docstring regina::python::doc::ModelLinkGraphArc_::__init
static const char *__init =
R"doc(Initialises this to the given arc exiting the given node of a model
graph.
Recall that the four arcs exiting a node are numbered 0,1,2,3 in a
clockwise order around the node.
The given node may be ``None``, in which case this will become a null
arc. If you are creating a null arc, then it is highly recommended
that you pass *arc* as 0 also, so that comparison tests treat this
null reference as equal to a null reference created by the zero-
argument constructor.
Parameter ``node``:
the node of the model graph that this arc exits.
Parameter ``arc``:
an integer in the range 0 to 3 inclusive, indicating which of the
four arcs exiting *node* this represents.)doc";
// Docstring regina::python::doc::ModelLinkGraphArc_::arc
static const char *arc =
R"doc(Indicates which arc this is amongst the four arcs exiting the
underlying node of the model graph.
For each node of a model graph, the four arcs exiting that node are
numbered 0,1,2,3 in a clockwise order.
Returns:
an integer between 0 and 3 inclusive indicating one of the four
arcs exiting node().)doc";
// Docstring regina::python::doc::ModelLinkGraphArc_::next
static const char *next =
R"doc(Returns the next arc after this when walking through the graph as
though it were a link, in a direction away from the current node.
This routine will move to the other endpoint of the graph edge
described by this arc, and will then return the *opposite* arc at the
resulting node (i.e., not just pointing backwards along the same
edge).
For any arc *a*, calling ``a.next()`` is equivalent to calling
``a.traverse().opposite()``.
Precondition:
This is not a null arc, i.e., node() does not return ``None``.
Returns:
the next arc after this when walking through the graph as though
it were a link.)doc";
// Docstring regina::python::doc::ModelLinkGraphArc_::node
static const char *node =
R"doc(The node of the model graph from which this arc exits.
Returns:
the corresponding node, or ``None`` if this is a null arc.)doc";
// Docstring regina::python::doc::ModelLinkGraphArc_::opposite
static const char *opposite =
R"doc(Returns the arc that exits the same node as this, but from the
opposite side.
Recall that the four arcs exiting each node are numbered in clockwise
order. The return value will therefore have the same node() as this,
but its arc() value will be two more than this (modulo 4).
Note that, for any arc *a*, ``a.opposite().opposite()`` is identical
to *a*.
Precondition:
This is not a null arc, i.e., node() does not return ``None``.
Returns:
the opposite arc exiting the same node.)doc";
// Docstring regina::python::doc::ModelLinkGraphArc_::prev
static const char *prev =
R"doc(Returns the previous arc before this when walking through the graph as
though it were a link, in a direction away from the current node.
This routine will jump to the opposite arc at the current node, and
then move to the other endpoint of the graph edge described by that
opposite arc.
For any arc *a*, calling ``a.prev()`` is equivalent to calling
``a.opposite().traverse()``.
Precondition:
This is not a null arc, i.e., node() does not return ``None``.
Returns:
the previous arc before this when walking through the graph as
though it were a link.)doc";
// Docstring regina::python::doc::ModelLinkGraphArc_::traverse
static const char *traverse =
R"doc(Returns the same edge of the model graph, but seen from the other
endpoint.
Recall that each undirected edge of a model graph has two
corresponding ModelLinkGraphArc objects, one for each of its
endpoints. If this object represents one of these arcs for some
underlying edge of the graph, then then return value represents the
other.
Note that, for any arc *a*, ``a.traverse().traverse()`` is identical
to *a*.
Precondition:
This is not a null arc, i.e., node() does not return ``None``.
Returns:
the arc at the other end of the underlying edge of the model
graph.)doc";
}
namespace ModelLinkGraphCells_ {
// Docstring regina::python::doc::ModelLinkGraphCells_::__eq
static const char *__eq =
R"doc(Determines if this and the given cellular decomposition are
combinatorially identical.
Here "identical" means that both decompositions have the same number
of cells, these cells are presented in the same order, and their
boundaries enter and exit the same numbered arcs of the same numbered
nodes, using the same directions of traversal and the same starting
points on each cell boundary.
Parameter ``other``:
the cellular decomposition to compare with this.
Returns:
``True`` if and only if the two cellular decompositions are
combinatorially identical.)doc";
// Docstring regina::python::doc::ModelLinkGraphCells_::arc
static const char *arc =
R"doc(Returns the given arc along the boundary of the given 2-cell.
For each cell, the arcs along the boundary are given in order as you
walk anticlockwise around the cell (so the cell is on the left of each
arc as you walk around the cell boundary).
Each arc is described in the form of an _outgoing_ arc from some node
of the underlying graph (so if the return ModelLinkGraphArc is *a*
then this describes an outgoing arc from a.node()). It follows that,
if the underlying graph has *n* nodes, then each of the 4*n* possible
ModelLinkGraphArc values appears exactly once as ``arc(cell, which)``
for some integers *cell* and *which*.
Parameter ``cell``:
indicates which cell to query; this must be between 0 and
countCells()-1 inclusive.
Parameter ``which``:
indicates which arc along the boundary of the corresponding cell
to return; this must be between 0 and ``size(cell)-1`` inclusive.
Returns:
the requested arc on the boundary of the given 2-cell.)doc";
// Docstring regina::python::doc::ModelLinkGraphCells_::arcs
static const char *arcs =
R"doc(Returns an object that allows iteration through and random access to
all arcs along the boundary of the given 2-cell.
Suppose that the *i*th cell is a *k*-gon. Then this object gives
access to the *k* arcs along the boundary of the *i*th cell in the
same order as described by arc(); that is, walking anticlockwise
around the cell boundary with the cell to the left of each arc.
The object that is returned is lightweight, and can be happily copied
by value. The C++ type of the object is subject to change, so C++
users should use ``auto`` (just like this declaration does).
The returned object is guaranteed to be an instance of ListView, which
means it offers basic container-like functions and supports range-
based ``for`` loops. The elements of the list will be read-only
objects of type ModelLinkGraphArc, and so your code might look like:
```
for (const ModelLinkGraphArc& a : cells.arcs(cell)) { ... }
```
Using ``arcs(cell)`` is equivalent to iterating over the iterator
range (``begin(cell)``, ``end(cell)``). Using arcs() generates a tiny
amount of extra overhead, but you may also find it more readable.
Parameter ``cell``:
indicates which cell to query; this must be between 0 and
countCells()-1 inclusive.
Returns:
access to the list of all arcs along the boundary of the given
cell.)doc";
// Docstring regina::python::doc::ModelLinkGraphCells_::cell
static const char *cell =
R"doc(Returns the 2-cell that lies to the left of the given arc.
Specifically, this function returns the number of the cell that lies
to the left of the given arc as you walk along it away from
``arc.node()``.
For any arc *a*, calling ``arc(cell(a), cellPos(a))`` will return the
same arc *a* again.
Parameter ``arc``:
the given arc of the underlying graph.
Returns:
the number of the cell that lies to the left of the given arc;
this will be an integer between 0 and ``countCells()-1``
inclusive.)doc";
// Docstring regina::python::doc::ModelLinkGraphCells_::cellPos
static const char *cellPos =
R"doc(Returns where the given arc appears along the boundary of the 2-cell
to its left.
Consider the cell *c* to the left of the given arc as you follow the
arc away from ``arc.node()``. The routine arc() can be used to
enumerate the sequence of arcs along the boundary of this cell *c*, in
order as you walk anticlockwise around the cell boundary. The purpose
of this routine is to identify _where_ in this sequence the given arc
occurs.
For any arc *a*, calling ``arc(cell(a), cellPos(a))`` will return the
same arc *a* again.
Parameter ``arc``:
the given arc of the underlying graph.
Returns:
the position of the given arc on the boundary of the cell to its
left; this will be an integer between 0 and ``size(cell(arc))-1``
inclusive.)doc";
// Docstring regina::python::doc::ModelLinkGraphCells_::countArcs
static const char *countArcs =
R"doc(Returns the total number of directed arcs in the underlying graph.
This is always four times the number of nodes in the graph.
Recall that each undirected edge of the graph corresponds to two
directed arcs (one exiting each endpoint of the edge).
Returns:
the total number of directed arcs.)doc";
// Docstring regina::python::doc::ModelLinkGraphCells_::countCells
static const char *countCells =
R"doc(Returns the total number of 2-cells in this cellular decomposition.
In the common case where this surface is the 2-sphere (i.e., the
underlying graph models a knot diagram), this will be exactly two more
than the number of nodes in the underlying graph.
.. note::
As of Regina 7.4, this routine will only return 0 when the
underlying graph is empty (and so this surface is empty also). In
previous versions of Regina, this routine also returned 0 if the
graph was non-planar (a scenario that was previously unsupported).
Returns:
the total number of 2-cells.)doc";
// Docstring regina::python::doc::ModelLinkGraphCells_::countComponents
static const char *countComponents =
R"doc(Returns the number of connected components in this surface. This will
be the same as the number of components of the underlying graph.
Returns:
the number of connected components.)doc";
// Docstring regina::python::doc::ModelLinkGraphCells_::countEdges
static const char *countEdges =
R"doc(Returns the total number of (undirected) edges in this cellular
decomposition. This is always twice the number of nodes in the
underlying graph.
Returns:
the total number of edges.)doc";
// Docstring regina::python::doc::ModelLinkGraphCells_::countNodes
static const char *countNodes =
R"doc(Returns the total number of vertices in this cellular decomposition;
that is, the total number of nodes in the underlying graph.
Returns:
the total number of nodes.)doc";
// Docstring regina::python::doc::ModelLinkGraphCells_::genus
static const char *genus =
R"doc(Returns the genus of this closed orientable surface. If the surface
has multiple components then this will sum the genus over each
component.
Returns:
the genus of this surface.)doc";
// Docstring regina::python::doc::ModelLinkGraphCells_::size
static const char *size =
R"doc(Returns the number of arcs aloung the boundary of the given 2-cell. If
the given cell is a *k*-gon, then this routine returns the integer
*k*.
Parameter ``cell``:
indicates which cell to query; this must be between 0 and
countCells()-1 inclusive.
Returns:
the size of the correpsonding 2-cell.)doc";
}
namespace ModelLinkGraphNode_ {
// Docstring regina::python::doc::ModelLinkGraphNode_::adj
static const char *adj =
R"doc(Returns the arc at the other end of the given graph edge that exits
this node.
Let *e* be the undirected edge of the underlying model graph that
corresponds to the given outgoing arc from this node. Recall that
there are two ModelLinkGraphArc objects corresponding to *e*, one for
each of its endpoints. One of these will be
ModelLinkGraphArc(``this``, *which*); this routine returns the _other_
object, which is the ModelLinkGraphArc describing the other endpoint
of *e*.
Note that for a node *n*, calling ``n.adj(i)`` is equivalent to
calling ``n.arc(i).traverse()``.
Parameter ``which``:
an integer in the range 0 to 3 inclusive, indicating which of the
four arcs exiting this node we should examine.
Returns:
a reference to the other end of the same undirected edge of the
underlying model graph.)doc";
// Docstring regina::python::doc::ModelLinkGraphNode_::arc
static const char *arc =
R"doc(Returns a reference to one of the four arcs of the graph that exit
this node. This is equivalent to directly constructing
ModelLinkGraphArc(``this``, *which*).
The four arcs exiting this node are numbered 0,1,2,3 in a clockwise
order around the node.
Parameter ``which``:
an integer in the range 0 to 3 inclusive, indicating which of the
four arcs exiting this node we should return.
Returns:
a reference to the corresponding arc exiting this node.)doc";
// Docstring regina::python::doc::ModelLinkGraphNode_::bigons
static const char *bigons =
R"doc(Returns the number of embedded bigons in the dual cell decomposition
that are incident with this node.
Here _embedded_ means that we do not count bigons where both vertices
are the same. Note that a _non-embedded_ incident bigon would imply
that all four arcs at this node were joined together to form two
loops, each bounding its own 1-gon (which models a 1-crossing unknot
component of a link diagram).
Returns:
The number of incident embedded bigons, which will be between 0
and 4 inclusive.)doc";
// Docstring regina::python::doc::ModelLinkGraphNode_::index
static const char *index =
R"doc(Returns the index of this node within the overall graph. If the graph
contains *n* nodes, then the index will be a number between 0 and
*n*-1 inclusive.
.. warning::
The index of this node might change if other nodes are added or
removed.
Returns:
the index of this node.)doc";
// Docstring regina::python::doc::ModelLinkGraphNode_::loops
static const char *loops =
R"doc(Returns the number of loops incident with this node.
Regarding loops versus 1-gons:
* For a planar 4-valent graph (i.e., a graph that models a classical
link diagram), every loop bounds a 1-gon in the dual cell
decomposition, and vice versa. In particular, for a planar graph, at
every node we have ``0 ≤ monogons() == loops() ≤ 2``.
* For a non-planar graph (which could be used to model a virtual link
diagram), there could be loops that do not bound 1-gons. So, for a
non-planar graph, the only guarantee we have at each node is that
``0 ≤ monogons() ≤ loops() ≤ 2``.
Returns:
The number of incident loops, which will be between 0 and 2
inclusive.)doc";
// Docstring regina::python::doc::ModelLinkGraphNode_::monogons
static const char *monogons =
R"doc(Returns the number of 1-gons in the dual cell decomposition that are
incident with this node.
Regarding loops versus 1-gons:
* For a planar 4-valent graph (i.e., a graph that models a classical
link diagram), every loop bounds a 1-gon in the dual cell
decomposition, and vice versa. In particular, for a planar graph, at
every node we have ``0 ≤ monogons() == loops() ≤ 2``.
* For a non-planar graph (which could be used to model a virtual link
diagram), there could be loops that do not bound 1-gons. So, for a
non-planar graph, the only guarantee we have at each node is that
``0 ≤ monogons() ≤ loops() ≤ 2``.
Returns:
The number of incident 1-gons, which will be between 0 and 2
inclusive.)doc";
// Docstring regina::python::doc::ModelLinkGraphNode_::triangles
static const char *triangles =
R"doc(Returns the number of embedded triangles in the dual cell
decomposition that are incident with this node.
Here _embedded_ means that we do not count triangles where two
vertices are the same. Note that a _non-embedded_ incident triangle
would imply that the underlying graph contains a loop bounding a 1-gon
(which models a trivial twist in a link diagram).
Returns:
The number of incident embedded triangles, which will be between 0
and 4 inclusive.)doc";
}
namespace ModelLinkGraph_ {
// Docstring regina::python::doc::ModelLinkGraph_::__copy
static const char *__copy =
R"doc(Constructs a new copy of the given graph.
Parameter ``copy``:
the graph to copy.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::__default
static const char *__default = R"doc(Constructs an empty graph.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::__eq
static const char *__eq =
R"doc(Determines if this graph is combinatorially identical to the given
graph.
Here "identical" means that both graphs have the same number of nodes,
and in both graphs the same pairs of outgoing arcs of numbered nodes
are connected by edges.
Parameter ``other``:
the graph to compare with this.
Returns:
``True`` if and only if the two graphs are combinatorially
identical.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::__init
static const char *__init =
R"doc(Constructs the graph that models the given link.
Any zero-component unknot components of the link will be ignored.
The nodes of this graph will be numbered in the same way as the
crossings of *link*. For each node, arc 0 will represent the outgoing
lower strand of the corresponding crossing.
Using this constructor is identical to calling Link::graph().
Parameter ``link``:
the link that this new graph will model.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::__init_2
static const char *__init_2 =
R"doc("Magic" constructor that tries to find some way to interpret the given
string as a 4-valent graph with embedding.
At present, Regina understands the following types of strings (and
attempts to parse them in the following order):
* Regina's variants of the _plantri_ format, including the default
format as well as the tight and extended variants, as produced by
plantri(), canonicalPlantri() and extendedPlantri().
This list may grow in future versions of Regina.
Exception ``InvalidArgument``:
Regina could not interpret the given string as representing a
graph using any of the supported string types.
Parameter ``description``:
a string that describes a 4-valent graph with embedding.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::canonical
static const char *canonical =
R"doc(Returns the canonical relabelling of this graph.
Here "relabelling" allows for any combination of:
* a relabelling of the nodes;
* a relabelling of the arcs around each node, whilst preserving the
cyclic order;
* if *allowReflection* is ``True``, a reversal of the cyclic order of
the arcs around _every_ node (i.e., a reflection of the surface in
which the graph embeds).
Two graphs are related under such a relabelling if and only if their
canonical relabellings are identical.
There is no promise that this will be the same canonical labelling as
used by canonicalPlantri().
The running time for this routine is quadratic in the size of the
graph.
Precondition:
This graph is connected.
Parameter ``allowReflection``:
``True`` if we allow reflection of the surface in which the graph
embeds; that is, a graph and its reflection should produce the
same canonical relabelling.
Returns:
the canonical relabelling of this graph.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::canonicalPlantri
static const char *canonicalPlantri =
R"doc(Outputs a text representation of this graph in a variant of the
_plantri_ ASCII format, using a canonical relabelling of nodes and
arcs, and with optional compression.
This routine is similar to plantri(), but with two significant
differences:
* This routine uses a canonical relabelling of the graph.
Specifically, two graphs will have the same canonicalPlantri()
output if and only if they are related under some combination of:
(i) relabelling nodes; (ii) relabelling the arcs around each node
whilst preserving their cyclic order; and (iii) if *allowReflection*
is ``True``, optionally reversing the cyclic order of the arcs
around _every_ node. This corresponds to a homeomorphism between the
surfaces in which the graphs embed that maps one graph to the other;
the argument *allowReflection* indicates whether this homeomorphism
is allowed to reverse orientation. While this has a similar aim to
canonical(), there is no promise that both routines will use the
same "canonical relabelling".
* If the argument *tight* is ``True``, then this routine uses an
abbreviated output format. The resulting compression is only trivial
(it reduces the length by roughly 40%), but the resulting string is
still human-parseable (though with a little more effort required).
This compression will simply remove the commas, and for each node it
will suppress the destination of the first arc (since this can be
deduced from the canonical labelling).
Regardless of whether *tight* is ``True`` or ``False``, the resulting
string can be parsed by fromPlantri() to reconstruct the original
graph. Note however that, due to the canonical labelling, the
resulting graph might be a relabelling of the original (and might even
be a reflection of the original, if *allowReflection* was passed as
``True``).
See plantri() for further details on the ASCII format itself,
including how Regina's implementation differs from _plantri_'s for
graphs with more than 26 nodes.
The running time for this routine is quadratic in the size of the
graph.
Precondition:
This graph is connected.
Precondition:
This graph has between 1 and 52 nodes inclusive.
Precondition:
The dual to this graph is a _simple_ quadrangulation of the
surface in which it embeds; see plantri() for a discussion on why
this condition is needed.
Exception ``FailedPrecondition``:
This graph is empty or has more than 52 nodes.
Parameter ``allowReflection``:
``True`` if a graph and its reflection should be considered the
same (i.e., produce the same canonical output), or ``False`` if
they should be considered different. Of course, if a graph is
symmetric under reflection then the graph and its reflection will
produce the same canonical output regardless of this parameter.
Parameter ``tight``:
``False`` if the usual _plantri_ ASCII format should be used (as
described by plantri() and fromPlantri()), or ``True`` if the
abbreviated format should be used as described above.
Returns:
an optionally compressed _plantri_ ASCII representation of this
graph.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::cells
static const char *cells =
R"doc(Returns the cellular decomposition of the closed orientable surface in
which this graph embeds. This will be the decomposition induced by
this graph; in particular, it will be formed from discs bounded by the
nodes and arcs of this graph.
This cellular decomposition will only be computed on demand. This
means that the first call to this function will take linear time (as
the decomposition is computed), but subsequent calls will be constant
time (since the decomposition is cached).
Note that, as of Regina 7.4, you can call this routine even if the
graph is non-planar and/or disconnected.
.. warning::
This routine is not thread-safe.
Exception ``InvalidArgument``:
This graph induces more cells than should ever be possible. This
should never occur unless the graph is malformed in some way.
Returns:
the induced cellular decomposition of the surface in which this
graph embeds.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::countComponents
static const char *countComponents =
R"doc(Returns the number of connected components in this graph.
.. warning::
This routine is not thread-safe, since it caches the number of
components after computing it for the first time.
.. note::
These are components in the graph theoretical sense, not link
components. So, for example, the graph that models the Hopf link
is considered to be connected with just one component.
Returns:
the number of connected components.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::countTraversals
static const char *countTraversals =
R"doc(Returns the number of traversals in this graph.
A _traversal_ is a closed path through the graph that always enters
and exits a node through opposite arcs. If this graph models a diagram
for some link *L*, then the number of traversals in this graph will be
precisely the number of link components in *L*.
This routine runs in linear time (and the result is not cached).
Returns:
the number of traversals.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::extendedPlantri
static const char *extendedPlantri =
R"doc(Outputs this graph using Regina's extended variant of the _plantri_
text format, which is better suited for non-planar graphs.
See plantri() for a discussion of the _plantri_ text format. A
limitation of the _plantri_ format is that it requires the graph to be
dual to a _simple_ quadrangulation of the surface in which it embeds.
This is a reasonable requirement for planar graphs, but not so for
non-planar graphs (which, in particular, are used to model virtual
link diagrams).
This routine extends the _plantri_ format to more explicitly encode
the embedding of the graph, which means we can remove the problematic
requirement on the dual quadrangulation. The format is Regina's own
(i.e., it is not compatible with the Brinkmann-McKay _plantri_
software).
The output will be a comma-separated sequence of alphanumeric strings.
The *i*th such string will consist of four letter-number pairs,
encoding the endpoints of the four edges in clockwise order that leave
node *i*. The letters represent nodes (with ``a..zA..Z`` representing
nodes 0 to 51 respectively). The numbers represent arcs (with ``0..3``
representing the four arcs around each node in clockwise order). An
example of such a string (describing a genus one graph that models the
virtual trefoil) is:
```
b3b2b0b1,a2a3a1a0
```
This routine is an inverse to fromExtendedPlantri(). That is, for any
graph *g* of a supported size,
``fromExtendedPlantri(g.extendedPlantri())`` will be identical to *g*.
Likewise, for any string *s* that satisfies the preconditions for
fromExtendedPlantri(), calling
``fromExtendedPlantri(s).extendedPlantri()`` will recover the original
string *s*.
Precondition:
This graph has between 1 and 52 nodes inclusive.
Exception ``FailedPrecondition``:
This graph is empty or has more than 52 nodes.
Returns:
a representation of this graph in the extended _plantri_ format.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::findFlype
static const char *findFlype =
R"doc(Identifies the smallest flype that can be performed on this graph from
the given starting location.
Here we use the same notation as in the three-argument flype()
function, where you perform a flype by passing three arcs *from*,
*left* and *right*. Read the flype() documentation now if you have not
done so already; this includes a full description of the flype
operation as well as diagrams with the arcs *from*, *left* and *right*
clearly marked.
The given arc *from* identifies the node to the left of the flype
disc. The aim of this routine is to identify two suitable arcs *left*
and *right* that exit through the right of the flype disc. Together,
these three arcs uniquely identify the entire flype disc, and
therefore prescribe the operation precisely.
Here, by "suitable arcs", we mean a pair of arcs (*left*, *right*) for
which the three arcs (*from*, *left*, *right*) together satisfy the
preconditions for the flype() routine.
There are several possible outcomes:
* It is possible that there are _no_ suitable arcs *left* and *right*.
In this case, this routine returns a pair of null arcs.
* It is possible that there is exactly one pair of suitable arcs
(*left*, *right*). In this case, this pair will be returned.
* It is possible that there are _many_ pairs of suitable arcs. In this
case, it can be shown that the suitable pairs have an ordering
*P_1*, ..., *P_k* in which the flype disc for *P_i* is completely
contained within the flype disc for *P_j* whenever *i* < *j*. In
this case, this routine returns the _smallest_ pair *P_1*; that is,
the pair (*left*, *right*) that gives the smallest possible flype
disc.
It should be noted that choosing only the smallest flype is not a
serious restriction: assuming the graph does not model a composition
of non-trivial knot diagrams, _any_ suitable flype can be expressed as
a composition of minimal flypes in this sense.
Precondition:
This graph is planar.
Parameter ``from``:
the arc that indicates where the flype disc should begin. This is
the arc labelled *from* in the diagrams for the three-argument
flype() function: it is the lower of the two arcs that enter the
flype disc from the node *X* to the left of the disc. This should
be presented as an arc of the node *X*.
Returns:
the pair (*left*, *right*) representing the smallest suitable
flype beginning at *from*, or a pair of null arcs if there are no
suitable pairs (*left*, *right*).)doc";
// Docstring regina::python::doc::ModelLinkGraph_::flype
static const char *flype =
R"doc(Performs a flype on this graph at the given location.
A _flype_ is an operation on a disc in the plane. The boundary of the
disc must cut through four arcs of the graph (and otherwise must not
meet the graph at all), as indicated in the diagram below. Moreover,
the two arcs that exit the disc on the left must meet at a common node
just outside the disc. (The punctuation symbols drawn inside the disc
are just to help illustrate how the transformation works.)
```
______ ______
/ \ / \
__ __| ## ** |_______ _______| :: <> |__ __
\ / | | | | \ /
X | Disc | ==> | | X
__/ \__| |_______ _______| |__/ \__
| :: <> | | ## ** |
\______/ \______/
```
The operation involves:
* reflecting this disc in a horizontal axis (so the two arcs on the
left switch places, and the two arcs on the right switch places);
* removing the node outside the disc on the left, where the two arcs
meet;
* introducing a new node on the right instead, where the two arcs on
the right will now meet.
The equivalent operation on a knot diagram involves twisting the
entire region inside the disc about a horizontal axis, in a way that
undoes the crossing on the left but introduces a new crossing on the
right instead.
You will need to pass arguments to indicate where the flype should
take place. For this, we will label some of the features of the
initial diagram (before the move takes place): see the diagram below.
Here the labels *from*, *left* and *right* all refer to arcs. The
labels *A*, *B*, *C* and *D* all refer to dual 2-cells in the plane;
these are not passed as arguments, but they do appear in the list of
preconditions for this routine.
```
______
Cell A / \
__ __________| |_________ left
\ / | |
X Cell B | | Cell D
__/ \__________| |_________ right
from | |
Cell C \______/
```
The arc *from* must be given as an arc of the node *outside* the disc
(i.e., the node to the left of cell *B*). The arcs *left* and *right*
must be given as arcs of their respective nodes *inside* the disc.
Precondition:
This graph is planar.
Precondition:
The arcs *from*, *left* and *right* are laid out as in the diagram
above. In particular: *from* and *right* have the same cell to
their right (cell *C*); *left* and the arc to the left of *from*
have the same cell to their left (cell *A*); and *left* and
*right* have the same cell between them (cell *D*).
Precondition:
Neither of the arcs *left* or *right*, when followed in the
direction away from the disc, end back at the node on the left of
the diagram. That is, neither ``left.traverse().node()`` nor
``right.traverse().node()`` is equal to ``from.node()``. (If this
fails, then either the flype simply reflects the entire graph, or
else the graph models a composition of two non-trivial knot
diagrams.)
Precondition:
Cells *A* and *C* are distinct (that is, the node on the left of
the diagram is not a cut-vertex of the graph).
Precondition:
Cells *B* and *D* are distinct (that is, the disc actually
contains one or more nodes, and the graph does not model a
composition of two non-trivial knot diagrams).
Exception ``InvalidArgument``:
One or more of the preconditions above fails to hold. Be warned
that the connectivity and planarity preconditions will not be
checked - these are the user's responsibility - but all other
preconditions _will_ be checked, and an exception will be thrown
if any of them fails.
Parameter ``from``:
the first arc that indicates where the flype should take place, as
labelled on the diagram above. This should be presented as an arc
of the node outside the disc, to the left.
Parameter ``left``:
the second arc that indicates where the flype should take place,
as labelled on the diagram above. This should be presented as an
arc of the node that it meets inside the disc.
Parameter ``right``:
the third arc that indicates where the flype should take place, as
labelled on the diagram above. This should be presented as an arc
of the node that it meets inside the disc.
Returns:
the graph obtained by performing the flype.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::flype_2
static const char *flype_2 =
R"doc(Performs the smallest possible flype on this graph from the given
starting location.
This is a convenience routine that simply calls findFlype() to
identify the smallest possible flype from the given starting location,
and then calls the three-argument flype() to actually perform it. If
there is no possible flype from the given starting location then this
routine throws an exception.
See the documentation for the three-argument flype() for further
details on the flype operation, and see findFlype() for a discussion
on what is meant by "smallest possible".
Precondition:
This graph is planar.
Exception ``InvalidArgument``:
There is no suitable flype on this graph from the given starting
location (that is, findFlype() returns a pair of null arcs).
Parameter ``from``:
the arc that indicates where the flype disc should begin. This is
the arc labelled *from* in the diagrams for the three-argument
flype() function: it is the lower of the two arcs that enter the
flype disc from the node *X* to the left of the disc. This should
be presented as an arc of the node *X*.
Returns:
the graph obtained by performing the flype.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::fromExtendedPlantri
static const char *fromExtendedPlantri =
R"doc(Builds a graph from a text representation using Regina's extended
variant of the _plantri_ format, which is better suited for non-planar
graphs.
See extendedPlantri() for a detailed description of Regina's extended
_plantri_ text format. In essence, this extends the original
Brinkmann-McKay _plantri_ format to more explicitly encode the
embedding of the graph, thereby removing the original _plantri_
requirement that the graph be dual to a simple quadrangulation of the
surface in which it embeds. Removing this requirement is important for
non-planar graphs (which are used to model virtual link diagrams).
As an example, the string below is the extended _plantri_
representation of a genus one graph that models the virtual trefoil:
```
b3b2b0b1,a2a3a1a0
```
Exception ``InvalidArgument``:
The input was not a valid representation of a graph using Regina's
extended _plantri_ format.
Parameter ``text``:
the representation of a graph using Regina's extended _plantri_
format, as described in extendedPlantri().
Returns:
the resulting graph.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::fromPlantri
static const char *fromPlantri =
R"doc(Builds a graph from a line of _plantri_ output, using Regina's variant
of the _plantri_ ASCII format.
The software _plantri_, by Gunnar Brinkmann and Brendan McKay, can be
used to enumerate 4-valent planar graphs (amongst many other things).
This routine converts a piece of output from _plantri_, or the
encoding of a graph using Regina's more general plantri() or
canonicalPlantri() functions, into a ModelLinkGraph object that Regina
can work with directly.
Graphs encoded using Regina's plantri() or canonicalPlantri()
functions may be disconnected and/or non-planar. However, such a graph
must be dual to a simple quadrangulation of the surface in which it
embeds - otherwise the _plantri_ format does not contain enough
information to recover the embedding of the graph. This in particular
is a problem for non-planar graphs (which model virtual links). If
this is an issue for you, you can use Regina's extended _plantri_
format instead; see extendedPlantri() and fromExtendedPlantri().
If you are working with output directly from the software _plantri_,
this output must be in ASCII format, and must likewise be the dual
graph of a simple quadrangulation of the sphere. The flags that must
be passed to _plantri_ to obtain such output are ``-adq`` (although
you may wish to pass additional flags to expand or restrict the
classes of graphs that _plantri_ builds).
When run with these flags, _plantri_ produces output in the following
form:
```
6 bbcd,adca,abee,affb,cffc,deed
6 bcdd,aeec,abfd,acfa,bffb,ceed
6 bcde,affc,abfd,acee,addf,becb
```
Each line consists of an integer (the number of nodes in the graph),
followed by a comma-separated sequence of alphabetical strings that
encode the edges leaving each node.
This function _only_ takes the comma-separated sequence of
alphabetical strings. So, for example, to construct the graph
corresponding to the second line of output above, you could call:
```
fromPlantri("bcdd,aeec,abfd,acfa,bffb,ceed");
```
Regina uses its own variant of _plantri_'s output format, which is
identical for smaller graphs but which differs from _plantri_'s own
output format for larger graphs. In particular:
* For graphs with ≤ 26 nodes, Regina and _plantri_ use identical
formats. Here Regina can happily recognise the output from _plantri_
as described above, as well as the output from Regina's own
plantri() and canonicalPlantri() functions.
* For graphs with 27-52 nodes, Regina's and _plantri_'s formats
differ: whereas _plantri_ uses punctuation for higher-index nodes,
Regina uses the upper-case letters ``A,...,Z``. For these larger
graphs, Regina can only recognise Regina's own plantri() and
canonicalPlantri() output, not _plantri_'s punctuation-based
encodings.
* For graphs with 53 nodes or more, Regina cannot encode or decode
such graphs using _plantri_ format at all.
Note that, whilst the software _plantri_ always outputs graphs using a
particular canonical labelling, this function has no such restriction:
it can accept an arbitrary ordering of nodes and arcs - in particular,
it can accept the string ``g.plantri()`` for any graph *g* that meets
the preconditions below.
This routine can also interpret the "tight" format that is optionally
produced by the member function canonicalPlantri() (even though such
output would certainly _not_ be produced by the software _plantri_).
Note that, by design, the tight format can only represented connected
graphs.
.. warning::
While this routine does some basic error checking on the input,
these checks are not exhaustive. In particular, it does _not_ test
that the graph is dual to a simple quadrangulation.
Precondition:
The graph being described is dual to a _simple_ quadrangulation of
the surface in which it embeds; see plantri() for further
discussion on why this condition is needed.
Exception ``InvalidArgument``:
The input was not a valid representation of a graph using the
_plantri_ output format.
Parameter ``plantri``:
a string containing the comma-separated sequence of alphabetical
strings in _plantri_ format, as described above.
Returns:
the resulting graph.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::generateAllEmbeddings
static const char *generateAllEmbeddings =
R"doc(Generates all possible local embeddings of the given 4-valent graph
into some closed orientable surface.
The input 4-valent graph (which does _not_ contain any embedding data)
should be presented as a closed 3-dimensional facet pairing (since
these can be generated efficiently using Regina).
This routine will, up to canonical relabelling, generate all local
embeddings of the given graph into a closed orientable surface (i.e.,
all ModelLinkGraph objects corresponding to the input graph), each
exactly once.
The graphs that are generated will be labelled canonically as
described by canonical(). This means that the nodes of the graph might
use a different labelling from the simplices of the given facet
pairing. The argument *allowReflection* will be passed through to
canonical().
This routine is a work in progress. Currently it is _very_ inefficient
and memory-hungry; the algorithm will be improved over time if/when it
becomes important to do so.
If *allowReflection* is ``False``, then if we run all possible facet
pairings through this routine, the combined results should be
precisely those graphs described by OEIS sequence A292206. If
*allowReflection* is ``True``, then (once we reach three nodes or
more) the output set should be smaller.
For each graph that is generated, this routine will call *action*
(which must be a function or some other callable object).
* The first argument passed to *action* will be the graph that was
generated (of type ModelLinkGraph). This will be passed as an
rvalue; a typical action could (for example) take it by const
reference and query it, or take it by value and modify it, or take
it by rvalue reference and move it into more permanent storage.
* If there are any additional arguments supplied in the list *args*,
then these will be passed as subsequent arguments to *action*.
* *action* must return ``void``.
.. warning::
The API for this class or function has not yet been finalised.
This means that the interface may change in new versions of
Regina, without maintaining backward compatibility. If you use
this class directly in your own code, please check the detailed
changelog with each new release to see if you need to make changes
to your code.
Precondition:
The given facet pairing is connected, and is also closed (i.e.,
has no unmatched facets).
Python:
This function is available in Python, and the *action* argument
may be a pure Python function. However, its form is more
restricted: the argument *args* is removed, so you simply call it
as ``generateAllEmbeddings(pairing, allowReflection, action)``.
Moreover, *action* must take exactly one argument (the graph).
Exception ``InvalidArgument``:
The given pairing is disconnected and/or has unmatched facets.
Parameter ``pairing``:
the 4-valent graph for which we wish to produce local embeddings.
Parameter ``allowReflection``:
``True`` if we consider a reflection of the surface in which the
graph embeds to produce the same embedding.
Parameter ``constraints``:
indicates any constraints that the embeddings that we generate
must satisfy. This should be a bitwise OR of constants from the
GraphConstraint enumeration, or else ``GraphConstraint::All`` (or
just empty braces ``{}``) if we should generate every possible
embedding. If several constraints are ORed together, then only
embeddings that satisfy _all_ of the these constraints will be
produced.
Parameter ``action``:
a function (or other callable object) to call for each graph that
is generated.
Parameter ``args``:
any additional arguments that should be passed to *action*,
following the initial graph argument.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::generateAllLinks
static const char *generateAllLinks =
R"doc(Exhaustively generates all link diagrams that are modelled by this
graph, up to reversal of individual link components. If this graph has
*n* nodes, then there will be ``2^n`` link diagrams generated in
total.
This routine is provided mainly to help with exhaustive testing. If
you are not interested in "obviously" non-minimal link diagrams, then
you should call generateMinimalLinks() instead.
Labelled diagrams are only generated once up to reversal of each
component. Specifically, this routine will fix the orientation of each
link component (always following the smallest numbered available arc
away from the smallest index graph node in each link component).
In each link diagram that is generated, crossing *k* will always
correspond to node *k* of this graph. If this graph is non-planar,
then the resulting link diagrams will all be virtual.
For each link diagram that is generated, this routine will call
*action* (which must be a function or some other callable object).
* The first argument passed to *action* will be the link diagram that
was generated (of type Link). This will be passed as an rvalue; a
typical action could (for example) take it by const reference and
query it, or take it by value and modify it, or take it by rvalue
reference and move it into more permanent storage.
* If there are any additional arguments supplied in the list *args*,
then these will be passed as subsequent arguments to *action*.
* *action* must return ``void``.
.. warning::
The API for this class or function has not yet been finalised.
This means that the interface may change in new versions of
Regina, without maintaining backward compatibility. If you use
this class directly in your own code, please check the detailed
changelog with each new release to see if you need to make changes
to your code.
Python:
This function is available in Python, and the *action* argument
may be a pure Python function. However, its form is more
restricted: the argument *args* is removed, so you simply call it
as generateAllLinks(action). Moreover, *action* must take exactly
one argument (the link diagram).
Parameter ``action``:
a function (or other callable object) to call for each link
diagram that is generated.
Parameter ``args``:
any additional arguments that should be passed to *action*,
following the initial link diagram argument.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::generateAnyLink
static const char *generateAnyLink =
R"doc(Generates an arbitrary link diagram that is modelled by this graph.
All link diagrams modelled by this graph are identical up to switching
of individual crossings and/or reversal of individual link components.
This routine will generate just one of these many possible link
diagrams. If you wish to generate _all_ such diagrams, consider
whether generateMinimalLinks() might be more appropriate for what you
need.
Unlike generateMinimalLinks(), there is no guarantee that the diagram
produced by this routine is minimal or even locally minimal in any
sense. For example, it is entirely possible that the link diagram
returned by this routine will have a reducing Reidemeister move.
In the link diagram that is generated, crossing *k* will always
correspond to node *k* of this graph. If this graph is non-planar,
then the resulting link diagram will be virtual.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::generateMinimalLinks
static const char *generateMinimalLinks =
R"doc(Exhaustively generates potentially-minimal link diagrams that are
modelled by this graph.
Here _potentially-minimal_ means there are no "obvious" simplification
moves (such as a simplifying type II Reidemeister move, for example).
The list of "obvious" moves considered here is subject to change in
future versions of Regina.
By _exhaustive_, we mean:
* Every minimal link diagram modelled by this graph will be generated
by this routine, up to reflection and/or reversal (as explained
below).
* If a link diagram is non-minimal and modelled by this graph, it
_might_ still be generated by this routine.
In other words, this routine will generate all minimal link diagrams
modelled by this graph, but there is no promise that all of the
diagrams generated are minimal.
Labelled diagrams are only generated once up to reflection of the
diagram and/or reversal of each component. Here "reflection"
corresponds to the function Link::changeAll(), which reflects the link
diagram in the surface that contains it. Specifically, this routine
will fix the orientation of each link component (always following the
smallest numbered available arc away from the smallest index graph
node in each link component), and it will fix the upper and lower
strands at node 0 so that the corresponding crossing is always
positive.
In each link diagram that is generated, crossing *k* will always
correspond to node *k* of this graph. If this graph is non-planar,
then the resulting link diagrams will all be virtual.
For each link diagram that is generated, this routine will call
*action* (which must be a function or some other callable object).
* The first argument passed to *action* will be the link diagram that
was generated (of type Link). This will be passed as an rvalue; a
typical action could (for example) take it by const reference and
query it, or take it by value and modify it, or take it by rvalue
reference and move it into more permanent storage.
* If there are any additional arguments supplied in the list *args*,
then these will be passed as subsequent arguments to *action*.
* *action* must return ``void``.
.. warning::
The API for this class or function has not yet been finalised.
This means that the interface may change in new versions of
Regina, without maintaining backward compatibility. If you use
this class directly in your own code, please check the detailed
changelog with each new release to see if you need to make changes
to your code.
Precondition:
The cell decomposition induced by this graph has no 1-gons (which,
in any link diagram that the graph models, would yield a reducing
type I Reidemeister move).
Python:
This function is available in Python, and the *action* argument
may be a pure Python function. However, its form is more
restricted: the argument *args* is removed, so you simply call it
as generateMinimalLinks(action). Moreover, *action* must take
exactly one argument (the link diagram).
Exception ``FailedPrecondition``:
There is a 1-gon in the cell decomposition induced by this graph.
Parameter ``action``:
a function (or other callable object) to call for each link
diagram that is generated.
Parameter ``args``:
any additional arguments that should be passed to *action*,
following the initial link diagram argument.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::genus
static const char *genus =
R"doc(Returns the genus of the closed orientable surface in which this graph
embeds.
As described in the class notes, this surface is chosen to have the
smallest possible genus: it is built from a collection of discs whose
boundaries follow the nodes and arcs of this graph according to the
local embedding.
If this graph is disconnected (and therefore the surface is also
disconnected), then this routine will return the sum of the genus over
all components.
Returns:
the genus of the surface in which this graph embeds.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::global_swap
static const char *global_swap =
R"doc(Swaps the contents of the two given graphs.
This global routine simply calls ModelLinkGraph::swap(); it is
provided so that ModelLinkGraph meets the C++ Swappable requirements.
See ModelLinkGraph::swap() for more details.
Parameter ``lhs``:
the graph whose contents should be swapped with *rhs*.
Parameter ``rhs``:
the graph whose contents should be swapped with *lhs*.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::insertGraph
static const char *insertGraph =
R"doc(Inserts a copy of the given graph into this graph.
The nodes of *source* will be copied into this graph, and placed after
any pre-existing nodes. Specifically, if the original number of nodes
in this graph was *N*, then node *i* of *source* will be copied to a
new node ``N+i`` of this graph.
This routine behaves correctly when *source* is this graph.
Parameter ``source``:
the graph whose copy will be inserted.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::isConnected
static const char *isConnected =
R"doc(Identifies whether this graph is connected.
For the purposes of this routine, an empty graph is considered to be
connected.
.. warning::
This routine is not thread-safe, since it caches the number of
components after computing it for the first time.
Returns:
``True`` if and only if this graph is connected.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::isEmpty
static const char *isEmpty =
R"doc(Determines whether this graph is empty. An empty graph is one with no
nodes at all.
Returns:
``True`` if and only if this graph is empty.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::isSimple
static const char *isSimple =
R"doc(Identifies whether this graph is simple; that is, has no loops or
multiple edges.
Returns:
``True`` if and only if this graph is simple.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::moveContentsTo
static const char *moveContentsTo =
R"doc(Moves the contents of this graph into the given destination graph,
leaving this graph empty but otherwise usable.
The nodes of this graph will be moved directly into *dest*, and placed
after any pre-existing nodes. Specifically, if the original number of
nodes in *dest* was *N*, then node *i* of this graph will become node
``N+i`` of *dest*.
This graph will become empty as a result, but it will otherwise remain
a valid and usable ModelLinkGraph object. Any arc references or node
pointers that referred to either this graph or *dest* will remain
valid (and will all now refer to *dest*), though if they originally
referred to this graph then they will now return different numerical
node indices.
Calling ``graph.moveContentsTo(dest)`` is similar to calling
``dest.insertGraph(std::move(graph))``; it is a little slower but it
comes with the benefit of leaving this graph in a usable state.
Precondition:
*dest* is not this graph.
Parameter ``dest``:
the graph into which the contents of this graph should be moved.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::node
static const char *node =
R"doc(Returns the node at the given index within this graph.
For a graph with *n* nodes, the nodes are numbered from 0 to *n*-1
inclusive.
.. warning::
If some nodes are added or removed then the indices of other nodes
might change. If you wish to track a particular node through such
operations then you should use the pointer to the relevant
ModelLinkGraphNode object instead.
Parameter ``index``:
the index of the requested node. This must be between 0 and
size()-1 inclusive.
Returns:
the node at the given index.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::nodes
static const char *nodes =
R"doc(Returns an object that allows iteration through and random access to
all nodes in this graph.
The object that is returned is lightweight, and can be happily copied
by value. The C++ type of the object is subject to change, so C++
users should use ``auto`` (just like this declaration does).
The returned object is guaranteed to be an instance of ListView, which
means it offers basic container-like functions and supports range-
based ``for`` loops. Note that the elements of the list will be
pointers, so your code might look like:
```
for (ModelLinkGraphNode* n : graph.nodes()) { ... }
```
The object that is returned will remain up-to-date and valid for as
long as the graph exists: even if nodes are added and/or removed, it
will always reflect the nodes that are currently in the graph.
Nevertheless, it is recommended to treat this object as temporary
only, and to call nodes() again each time you need it.
Returns:
access to the list of all nodes.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::plantri
static const char *plantri =
R"doc(Outputs this graph in a variant of the ASCII text format used by
_plantri_.
The software _plantri_, by Gunnar Brinkmann and Brendan McKay, can be
used to enumerate 4-valent planar graphs (amongst many other things).
This routine outputs this graph in a format that mimics _plantri_'s
own dual ASCII format (i.e., the format that _plantri_ outputs when
run with the flags ``-adq``).
Specifically, the output will be a comma-separated sequence of
alphabetical strings. The *i*th such string will consist of four
letters, encoding the endpoints of the four edges in clockwise order
that leave node *i*. The lower-case letters ``a``,``b``,...,``z``
represent nodes 0,1,...,25 respectively, and the upper-case letters
``A``,``B``,...,``Z`` represent nodes 26,27,...,51 respectively. An
example of such a string is:
```
bcdd,aeec,abfd,acfa,bffb,ceed
```
For graphs with at most 26 nodes, this is identical to _plantri_'s own
dual ASCII format. For larger graphs, this format differs: _plantri_
uses punctuation to represent higher-index nodes, whereas Regina uses
upper-case letters.
Although _plantri_ is designed to work with graphs that are connected
and planar, this routine will happily produce output for disconnected
and/or non-planar graphs. However, there remains an unavoidable
requirement: the graph must be dual to a _simple_ quadrangulation. In
detail:
* The dual to this 4-valent graph will be a quadrangulation of the
surface in which it embeds. The _plantri_ format inherently requires
that this quadrangulation is _simple_: that is, the dual must have
no loops or parallel edges.
* This requirement exists because, if the dual is _not_ simple, the
embedding of the original graph cannot be uniquely reconstructed
from its _plantri_ output. In particular, the embedding becomes
ambiguous around parallel edges in the original 4-valent graph.
* For _planar_ graphs, this requirement is relatively harmless: a
parity condition shows that loops in the dual are impossible, and
parallel edges in the dual mean that any link diagram that this
graph models is an "obvious" connected sum.
* For _non-planar_ graphs, this requirement is more problematic. For
example, consider the graph that models the virtual trefoil: the
dual quadrangulation of the torus contains both loops and parallel
edges. This makes the _plantri_ format unusable in practice for
graps that model virtual links.
If this constraint is too onerous (e.g., you are working with virtual
links), you could use extendedPlantri() instead, which is not
compatible with the Brinkmann-McKay _plantri_ software but which
removes this requirement for the dual quadrangulation to be simple.
For graphs that the _plantri_ format _does_ support, this routine is
an inverse to fromPlantri(). That is, for any graph *g* that satisfies
the preconditions below, ``fromPlantri(g.plantri())`` is identical to
*g*. Likewise, for any string *s* that satisfies the preconditions for
fromPlantri(), calling ``fromPlantri(s).plantri()`` will recover the
original string *s*.
.. note::
The output of this function might not correspond to any possible
output from the program _plantri_ itself, even if the graph is
connected and planar, the dual quadrangulation is simple, and only
lower-case letters are used. This is because _plantri_ only
outputs graphs with a certain canonical labelling. In contrast,
plantri() can be called on any graph that satisfies the
preconditions below, and it will preserve the labels of the nodes
and the order of the arcs around each node.
Precondition:
This graph has between 1 and 52 nodes inclusive.
Precondition:
The dual to this graph is a _simple_ quadrangulation of the
surface in which it embeds.
Exception ``FailedPrecondition``:
This graph is empty or has more than 52 nodes.
Returns:
a _plantri_ format ASCII representation of this graph.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::randomise
static const char *randomise =
R"doc(Randomly relabels this graph in an orientation-preserving manner.
The nodes will be relabelled arbitrarily. Around each node, the four
outgoing arcs will be relabelled in a random way that preserves their
cyclic order (thereby preserving the local embedding of the graph,
without reflection).
This routine is thread-safe, and uses RandomEngine for its random
number generation.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::reflect
static const char *reflect =
R"doc(Converts this graph into its reflection.
This routine simply reverses (and also cycles) the order of outgoing
arcs around every node.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::size
static const char *size =
R"doc(Returns the number of nodes in this graph.
Returns:
the number of nodes.)doc";
// Docstring regina::python::doc::ModelLinkGraph_::swap
static const char *swap =
R"doc(Swaps the contents of this and the given graph.
All nodes that belong to this graph will be moved to *other*, and all
nodes that belong to *other* will be moved to this graph.
In particular, any ModelLinkGraphNode pointers or references and any
ModelLinkGraphArc objects will remain valid.
This routine will behave correctly if *other* is in fact this graph.
Parameter ``other``:
the graph whose contents should be swapped with this.)doc";
}
} // namespace regina::python::doc
#if defined(__GNUG__)
#pragma GCC diagnostic pop
#endif
|