passagemath-graphs 10.6.1rc1__cp310-cp310-musllinux_1_2_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. passagemath_graphs-10.6.1rc1.dist-info/METADATA +292 -0
  2. passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
  3. passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
  4. passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
  5. passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
  6. passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
  7. passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
  8. sage/all__sagemath_graphs.py +39 -0
  9. sage/combinat/abstract_tree.py +2723 -0
  10. sage/combinat/all__sagemath_graphs.py +34 -0
  11. sage/combinat/binary_tree.py +5306 -0
  12. sage/combinat/cluster_algebra_quiver/all.py +22 -0
  13. sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
  14. sage/combinat/cluster_algebra_quiver/interact.py +124 -0
  15. sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
  16. sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
  17. sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
  18. sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
  19. sage/combinat/designs/MOLS_handbook_data.py +570 -0
  20. sage/combinat/designs/all.py +58 -0
  21. sage/combinat/designs/bibd.py +1655 -0
  22. sage/combinat/designs/block_design.py +1071 -0
  23. sage/combinat/designs/covering_array.py +269 -0
  24. sage/combinat/designs/covering_design.py +530 -0
  25. sage/combinat/designs/database.py +5615 -0
  26. sage/combinat/designs/design_catalog.py +122 -0
  27. sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  28. sage/combinat/designs/designs_pyx.pxd +21 -0
  29. sage/combinat/designs/designs_pyx.pyx +993 -0
  30. sage/combinat/designs/difference_family.py +3951 -0
  31. sage/combinat/designs/difference_matrices.py +279 -0
  32. sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
  33. sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
  34. sage/combinat/designs/ext_rep.py +1064 -0
  35. sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
  36. sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
  37. sage/combinat/designs/group_divisible_designs.py +361 -0
  38. sage/combinat/designs/incidence_structures.py +2357 -0
  39. sage/combinat/designs/latin_squares.py +581 -0
  40. sage/combinat/designs/orthogonal_arrays.py +2244 -0
  41. sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
  42. sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
  43. sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
  44. sage/combinat/designs/resolvable_bibd.py +815 -0
  45. sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
  46. sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
  47. sage/combinat/designs/subhypergraph_search.pyx +530 -0
  48. sage/combinat/designs/twographs.py +306 -0
  49. sage/combinat/finite_state_machine.py +14874 -0
  50. sage/combinat/finite_state_machine_generators.py +2006 -0
  51. sage/combinat/graph_path.py +448 -0
  52. sage/combinat/interval_posets.py +3908 -0
  53. sage/combinat/nu_tamari_lattice.py +269 -0
  54. sage/combinat/ordered_tree.py +1446 -0
  55. sage/combinat/posets/all.py +46 -0
  56. sage/combinat/posets/bubble_shuffle.py +247 -0
  57. sage/combinat/posets/cartesian_product.py +493 -0
  58. sage/combinat/posets/d_complete.py +182 -0
  59. sage/combinat/posets/elements.py +273 -0
  60. sage/combinat/posets/forest.py +30 -0
  61. sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
  62. sage/combinat/posets/hasse_cython.pyx +174 -0
  63. sage/combinat/posets/hasse_diagram.py +3672 -0
  64. sage/combinat/posets/hochschild_lattice.py +158 -0
  65. sage/combinat/posets/incidence_algebras.py +794 -0
  66. sage/combinat/posets/lattices.py +5117 -0
  67. sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
  68. sage/combinat/posets/linear_extension_iterator.pyx +292 -0
  69. sage/combinat/posets/linear_extensions.py +1037 -0
  70. sage/combinat/posets/mobile.py +275 -0
  71. sage/combinat/posets/moebius_algebra.py +776 -0
  72. sage/combinat/posets/poset_examples.py +2178 -0
  73. sage/combinat/posets/posets.py +9360 -0
  74. sage/combinat/rooted_tree.py +1070 -0
  75. sage/combinat/shard_order.py +239 -0
  76. sage/combinat/tamari_lattices.py +384 -0
  77. sage/combinat/yang_baxter_graph.py +923 -0
  78. sage/databases/all__sagemath_graphs.py +1 -0
  79. sage/databases/knotinfo_db.py +1231 -0
  80. sage/ext_data/all__sagemath_graphs.py +1 -0
  81. sage/ext_data/graphs/graph_plot_js.html +330 -0
  82. sage/ext_data/kenzo/CP2.txt +45 -0
  83. sage/ext_data/kenzo/CP3.txt +349 -0
  84. sage/ext_data/kenzo/CP4.txt +4774 -0
  85. sage/ext_data/kenzo/README.txt +49 -0
  86. sage/ext_data/kenzo/S4.txt +20 -0
  87. sage/graphs/all.py +42 -0
  88. sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
  89. sage/graphs/asteroidal_triples.pyx +320 -0
  90. sage/graphs/base/all.py +1 -0
  91. sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  92. sage/graphs/base/boost_graph.pxd +106 -0
  93. sage/graphs/base/boost_graph.pyx +3045 -0
  94. sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  95. sage/graphs/base/c_graph.pxd +106 -0
  96. sage/graphs/base/c_graph.pyx +5096 -0
  97. sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  98. sage/graphs/base/dense_graph.pxd +28 -0
  99. sage/graphs/base/dense_graph.pyx +801 -0
  100. sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
  101. sage/graphs/base/graph_backends.pxd +5 -0
  102. sage/graphs/base/graph_backends.pyx +797 -0
  103. sage/graphs/base/overview.py +85 -0
  104. sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  105. sage/graphs/base/sparse_graph.pxd +90 -0
  106. sage/graphs/base/sparse_graph.pyx +1653 -0
  107. sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  108. sage/graphs/base/static_dense_graph.pxd +5 -0
  109. sage/graphs/base/static_dense_graph.pyx +1032 -0
  110. sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
  111. sage/graphs/base/static_sparse_backend.pxd +27 -0
  112. sage/graphs/base/static_sparse_backend.pyx +1583 -0
  113. sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  114. sage/graphs/base/static_sparse_graph.pxd +37 -0
  115. sage/graphs/base/static_sparse_graph.pyx +1375 -0
  116. sage/graphs/bipartite_graph.py +2732 -0
  117. sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
  118. sage/graphs/centrality.pyx +1038 -0
  119. sage/graphs/cographs.py +519 -0
  120. sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
  121. sage/graphs/comparability.pyx +851 -0
  122. sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
  123. sage/graphs/connectivity.pxd +157 -0
  124. sage/graphs/connectivity.pyx +4813 -0
  125. sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
  126. sage/graphs/convexity_properties.pxd +16 -0
  127. sage/graphs/convexity_properties.pyx +870 -0
  128. sage/graphs/digraph.py +4754 -0
  129. sage/graphs/digraph_generators.py +1993 -0
  130. sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
  131. sage/graphs/distances_all_pairs.pxd +12 -0
  132. sage/graphs/distances_all_pairs.pyx +2938 -0
  133. sage/graphs/domination.py +1363 -0
  134. sage/graphs/dot2tex_utils.py +100 -0
  135. sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
  136. sage/graphs/edge_connectivity.pyx +1215 -0
  137. sage/graphs/generators/all.py +1 -0
  138. sage/graphs/generators/basic.py +1769 -0
  139. sage/graphs/generators/chessboard.py +538 -0
  140. sage/graphs/generators/classical_geometries.py +1611 -0
  141. sage/graphs/generators/degree_sequence.py +235 -0
  142. sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
  143. sage/graphs/generators/distance_regular.pyx +2846 -0
  144. sage/graphs/generators/families.py +4759 -0
  145. sage/graphs/generators/intersection.py +565 -0
  146. sage/graphs/generators/platonic_solids.py +262 -0
  147. sage/graphs/generators/random.py +2623 -0
  148. sage/graphs/generators/smallgraphs.py +5741 -0
  149. sage/graphs/generators/world_map.py +724 -0
  150. sage/graphs/generic_graph.py +26867 -0
  151. sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  152. sage/graphs/generic_graph_pyx.pxd +34 -0
  153. sage/graphs/generic_graph_pyx.pyx +1673 -0
  154. sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
  155. sage/graphs/genus.pyx +622 -0
  156. sage/graphs/graph.py +9645 -0
  157. sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
  158. sage/graphs/graph_coloring.pyx +2284 -0
  159. sage/graphs/graph_database.py +1177 -0
  160. sage/graphs/graph_decompositions/all.py +1 -0
  161. sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
  162. sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
  163. sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
  164. sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
  165. sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
  166. sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
  167. sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
  168. sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
  169. sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
  170. sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
  171. sage/graphs/graph_decompositions/graph_products.pyx +508 -0
  172. sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  173. sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
  174. sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
  175. sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  176. sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
  177. sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
  178. sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  179. sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
  180. sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
  181. sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
  182. sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
  183. sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
  184. sage/graphs/graph_editor.py +82 -0
  185. sage/graphs/graph_generators.py +3314 -0
  186. sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  187. sage/graphs/graph_generators_pyx.pyx +95 -0
  188. sage/graphs/graph_input.py +812 -0
  189. sage/graphs/graph_latex.py +2064 -0
  190. sage/graphs/graph_list.py +410 -0
  191. sage/graphs/graph_plot.py +1756 -0
  192. sage/graphs/graph_plot_js.py +338 -0
  193. sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
  194. sage/graphs/hyperbolicity.pyx +1704 -0
  195. sage/graphs/hypergraph_generators.py +364 -0
  196. sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
  197. sage/graphs/independent_sets.pxd +13 -0
  198. sage/graphs/independent_sets.pyx +402 -0
  199. sage/graphs/isgci.py +1033 -0
  200. sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
  201. sage/graphs/isoperimetric_inequalities.pyx +489 -0
  202. sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  203. sage/graphs/line_graph.pyx +743 -0
  204. sage/graphs/lovasz_theta.py +77 -0
  205. sage/graphs/matching.py +1633 -0
  206. sage/graphs/matching_covered_graph.py +3590 -0
  207. sage/graphs/orientations.py +1489 -0
  208. sage/graphs/partial_cube.py +459 -0
  209. sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
  210. sage/graphs/path_enumeration.pyx +2040 -0
  211. sage/graphs/pq_trees.py +1129 -0
  212. sage/graphs/print_graphs.py +201 -0
  213. sage/graphs/schnyder.py +865 -0
  214. sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
  215. sage/graphs/spanning_tree.pyx +1457 -0
  216. sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
  217. sage/graphs/strongly_regular_db.pyx +3340 -0
  218. sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
  219. sage/graphs/traversals.pxd +9 -0
  220. sage/graphs/traversals.pyx +1872 -0
  221. sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
  222. sage/graphs/trees.pxd +15 -0
  223. sage/graphs/trees.pyx +310 -0
  224. sage/graphs/tutte_polynomial.py +713 -0
  225. sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
  226. sage/graphs/views.pyx +794 -0
  227. sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
  228. sage/graphs/weakly_chordal.pyx +604 -0
  229. sage/groups/all__sagemath_graphs.py +1 -0
  230. sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
  231. sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
  232. sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
  233. sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
  234. sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
  235. sage/knots/all.py +6 -0
  236. sage/knots/free_knotinfo_monoid.py +507 -0
  237. sage/knots/gauss_code.py +291 -0
  238. sage/knots/knot.py +682 -0
  239. sage/knots/knot_table.py +284 -0
  240. sage/knots/knotinfo.py +2900 -0
  241. sage/knots/link.py +4715 -0
  242. sage/sandpiles/all.py +13 -0
  243. sage/sandpiles/examples.py +225 -0
  244. sage/sandpiles/sandpile.py +6365 -0
  245. sage/topology/all.py +22 -0
  246. sage/topology/cell_complex.py +1214 -0
  247. sage/topology/cubical_complex.py +1976 -0
  248. sage/topology/delta_complex.py +1806 -0
  249. sage/topology/filtered_simplicial_complex.py +744 -0
  250. sage/topology/moment_angle_complex.py +823 -0
  251. sage/topology/simplicial_complex.py +5160 -0
  252. sage/topology/simplicial_complex_catalog.py +92 -0
  253. sage/topology/simplicial_complex_examples.py +1680 -0
  254. sage/topology/simplicial_complex_homset.py +205 -0
  255. sage/topology/simplicial_complex_morphism.py +836 -0
  256. sage/topology/simplicial_set.py +4102 -0
  257. sage/topology/simplicial_set_catalog.py +55 -0
  258. sage/topology/simplicial_set_constructions.py +2954 -0
  259. sage/topology/simplicial_set_examples.py +865 -0
  260. sage/topology/simplicial_set_morphism.py +1464 -0
sage/knots/all.py ADDED
@@ -0,0 +1,6 @@
1
+ # sage_setup: distribution = sagemath-graphs
2
+ from sage.misc.lazy_import import lazy_import
3
+
4
+ lazy_import('sage.knots.knot', ['Knot', 'Knots'])
5
+ lazy_import('sage.knots.link', 'Link')
6
+ lazy_import('sage.knots.knotinfo', ['KnotInfo', 'KnotInfoSeries'])
@@ -0,0 +1,507 @@
1
+ # sage_setup: distribution = sagemath-graphs
2
+ r"""
3
+ Free monoid generated by prime knots available via the
4
+ :class:`~sage.knots.knotinfo.KnotInfoBase` class.
5
+
6
+ A generator of this free abelian monoid is a prime knot according to
7
+ the list at `KnotInfo <https://knotinfo.math.indiana.edu/>`__. A fully
8
+ amphicheiral prime knot is represented by exactly one generator with
9
+ the corresponding name. For non-chiral prime knots, there are
10
+ additionally one or three generators with the suffixes ``m``, ``r``
11
+ and ``c`` which specify the mirror and reverse images according to
12
+ their symmetry type.
13
+
14
+ AUTHORS:
15
+
16
+ - Sebastian Oehms June 2024: initial version
17
+ """
18
+
19
+ # ############################################################################
20
+ # Copyright (C) 2024 Sebastian Oehms <seb.oehms@gmail.com>
21
+ #
22
+ # This program is free software: you can redistribute it and/or modify
23
+ # it under the terms of the GNU General Public License as published by
24
+ # the Free Software Foundation, either version 2 of the License, or
25
+ # (at your option) any later version.
26
+ # https://www.gnu.org/licenses/
27
+ # ############################################################################
28
+
29
+ from sage.knots.knotinfo import SymmetryMutant
30
+ from sage.monoids.indexed_free_monoid import (IndexedFreeAbelianMonoid,
31
+ IndexedFreeAbelianMonoidElement)
32
+ from sage.misc.cachefunc import cached_method
33
+ from sage.structure.unique_representation import UniqueRepresentation
34
+
35
+
36
+ class FreeKnotInfoMonoidElement(IndexedFreeAbelianMonoidElement):
37
+ """
38
+ An element of an indexed free abelian monoid.
39
+ """
40
+ def as_knot(self):
41
+ r"""
42
+ Return the knot represented by ``self``.
43
+
44
+ EXAMPLES::
45
+
46
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
47
+ sage: FKIM = FreeKnotInfoMonoid()
48
+ sage: FKIM.inject_variables(select=3)
49
+ Defining K3_1
50
+ Defining K3_1m
51
+ sage: K = K3_1^2 * K3_1m
52
+ sage: K.as_knot()
53
+ Knot represented by 9 crossings
54
+ """
55
+ wl = self.to_word_list()
56
+ P = self.parent()
57
+ if len(wl) == 1:
58
+ name = wl[0]
59
+ L = P._index_dict[name][0].link()
60
+ if name.endswith(SymmetryMutant.mirror_image.value):
61
+ return L.mirror_image()
62
+ if name.endswith(SymmetryMutant.reverse.value):
63
+ return L.reverse()
64
+ if name.endswith(SymmetryMutant.concordance_inverse.value):
65
+ return L.mirror_image().reverse()
66
+ return L
67
+ else:
68
+ from sage.misc.misc_c import prod
69
+ return prod(P.gen(wl[i]).as_knot() for i in range(len(wl)))
70
+
71
+ def to_knotinfo(self):
72
+ r"""
73
+ Return a word representing ``self`` as a list of pairs.
74
+
75
+ Each pair ``(ki, sym)`` consists of a
76
+ :class:`~sage.knots.knotinfo.KnotInfoBase` instance ``ki`` and
77
+ :class:`~sage.knots.knotinfo.SymmetryMutant` instance ``sym``.
78
+
79
+ EXAMPLES::
80
+
81
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
82
+ sage: FKIM = FreeKnotInfoMonoid()
83
+ sage: FKIM.inject_variables(select=3)
84
+ Defining K3_1
85
+ Defining K3_1m
86
+ sage: K = K3_1^2 * K3_1m
87
+ sage: K.to_knotinfo()
88
+ [(<KnotInfo.K3_1: '3_1'>, <SymmetryMutant.itself: 's'>),
89
+ (<KnotInfo.K3_1: '3_1'>, <SymmetryMutant.itself: 's'>),
90
+ (<KnotInfo.K3_1: '3_1'>, <SymmetryMutant.mirror_image: 'm'>)]
91
+ """
92
+ wl = self.to_word_list()
93
+ P = self.parent()
94
+ return [P._index_dict[w] for w in wl]
95
+
96
+
97
+ class FreeKnotInfoMonoid(IndexedFreeAbelianMonoid):
98
+
99
+ Element = FreeKnotInfoMonoidElement
100
+
101
+ @staticmethod
102
+ def __classcall_private__(cls, max_crossing_number=6, prefix=None, **kwds):
103
+ r"""
104
+ Normalize input to ensure a unique representation.
105
+
106
+ EXAMPLES::
107
+
108
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
109
+ sage: FreeKnotInfoMonoid()
110
+ Free abelian monoid of knots with at most 6 crossings
111
+ sage: FreeKnotInfoMonoid(5)
112
+ Free abelian monoid of knots with at most 5 crossings
113
+ """
114
+ if not prefix:
115
+ prefix = 'KnotInfo'
116
+ # We skip the IndexedMonoid__classcall__
117
+ return UniqueRepresentation.__classcall__(cls, max_crossing_number,
118
+ prefix=prefix, **kwds)
119
+
120
+ def __init__(self, max_crossing_number, category=None, prefix=None, **kwds):
121
+ r"""
122
+ Initialize ``self`` with generators belonging to prime knots with
123
+ at most ``max_crossing_number`` crossings.
124
+
125
+ TESTS:
126
+
127
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
128
+ sage: FKIM = FreeKnotInfoMonoid()
129
+ sage: FKIM4 = FreeKnotInfoMonoid(4)
130
+ sage: TestSuite(FKIM).run()
131
+ sage: TestSuite(FKIM4).run()
132
+ """
133
+ self._max_crossing_number = None
134
+ self._set_index_dictionary(max_crossing_number=max_crossing_number)
135
+ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
136
+ indices = FiniteEnumeratedSet(self._index_dict)
137
+ super().__init__(indices, prefix)
138
+
139
+ def _from_knotinfo(self, knotinfo, symmetry_mutant):
140
+ r"""
141
+ Return the name on the generator for the given ``symmetry_mutant``
142
+ of the given entry ``knotinfo`` if the KnotInfo database.
143
+
144
+ EXAMPLES::
145
+
146
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
147
+ sage: from sage.knots.knotinfo import SymmetryMutant
148
+ sage: FKIM = FreeKnotInfoMonoid()
149
+ sage: ki = KnotInfo.K5_2
150
+ sage: FKIM._from_knotinfo(ki, SymmetryMutant.itself)
151
+ 'K5_2'
152
+ sage: FKIM._from_knotinfo(ki, SymmetryMutant.concordance_inverse)
153
+ 'K5_2c'
154
+ """
155
+ if symmetry_mutant == SymmetryMutant.itself:
156
+ return knotinfo.name
157
+ else:
158
+ return '%s%s' % (knotinfo.name, symmetry_mutant.value)
159
+
160
+ def _set_index_dictionary(self, max_crossing_number=6):
161
+ r"""
162
+ Set or expand the set of generators.
163
+ EXAMPLES::
164
+
165
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
166
+ sage: FreeKnotInfoMonoid()
167
+ Free abelian monoid of knots with at most 6 crossings
168
+
169
+ TESTS::
170
+
171
+ sage: from sage.features.databases import DatabaseKnotInfo
172
+ sage: F = DatabaseKnotInfo()
173
+ sage: F.hide()
174
+ sage: FreeKnotInfoMonoid(7) # indirect doctest
175
+ Traceback (most recent call last):
176
+ ...
177
+ sage.features.FeatureNotPresentError: database_knotinfo is not available.
178
+ Feature `database_knotinfo` is hidden.
179
+ Use method `unhide` to make it available again.
180
+ sage: F.unhide()
181
+ """
182
+ if max_crossing_number > 6:
183
+ from sage.features.databases import DatabaseKnotInfo
184
+ DatabaseKnotInfo().require()
185
+
186
+ current_max_crossing_number = self._max_crossing_number
187
+ if not current_max_crossing_number:
188
+ current_max_crossing_number = - 1
189
+ self._index_dict = {}
190
+ self._max_crossing_number = max_crossing_number
191
+
192
+ def add_index(ki, sym):
193
+ self._index_dict[self._from_knotinfo(ki, sym)] = (ki, sym)
194
+
195
+ from sage.knots.knotinfo import KnotInfo
196
+ for K in KnotInfo:
197
+ ncr = K.crossing_number()
198
+ if ncr <= current_max_crossing_number:
199
+ continue
200
+ if ncr > self._max_crossing_number:
201
+ break
202
+ for sym in SymmetryMutant:
203
+ if sym.is_minimal(K):
204
+ add_index(K, sym)
205
+ if current_max_crossing_number > 0:
206
+ from sage.sets.finite_enumerated_set import FiniteEnumeratedSet
207
+ self._indices = FiniteEnumeratedSet(self._index_dict)
208
+
209
+ def _repr_(self):
210
+ """
211
+ Return a string representation of ``self``.
212
+
213
+ EXAMPLES::
214
+
215
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
216
+ sage: FreeKnotInfoMonoid(4)
217
+ Free abelian monoid of knots with at most 4 crossings
218
+ """
219
+ return "Free abelian monoid of knots with at most %s crossings" % self._max_crossing_number
220
+
221
+ def _element_constructor_(self, x=None):
222
+ """
223
+ Create an element of this abelian monoid from ``x``.
224
+
225
+ EXAMPLES::
226
+
227
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
228
+ sage: FKIM = FreeKnotInfoMonoid()
229
+ sage: K = KnotInfo.K5_1.link().mirror_image()
230
+ sage: FKIM(K) # needs libhomfly sage.modules
231
+ KnotInfo['K5_1m']
232
+ """
233
+ if isinstance(x, tuple):
234
+ if len(x) == 2:
235
+ ki, sym = x
236
+ from sage.knots.knotinfo import KnotInfoBase
237
+ if isinstance(ki, KnotInfoBase) and isinstance(sym, SymmetryMutant):
238
+ mcr = ki.crossing_number()
239
+ if mcr > self._max_crossing_number:
240
+ self._set_index_dictionary(max_crossing_number=mcr)
241
+
242
+ sym_min = min([sym] + sym.matches(ki))
243
+ return self.gen(self._from_knotinfo(ki, sym_min))
244
+
245
+ from sage.knots.knot import Knot
246
+ from sage.knots.link import Link
247
+ if not isinstance(x, Knot):
248
+ if isinstance(x, Link):
249
+ x = Knot(x.pd_code())
250
+ if isinstance(x, Knot):
251
+ return self.from_knot(x)
252
+ return self.element_class(self, x)
253
+
254
+ @cached_method
255
+ def _check_elements(self, knot, elems):
256
+ r"""
257
+ Return a matching item from the list in ``elems`` if it exists.
258
+ Elsewise return ``None``. This is a helper method for .meth:`from_knot`.
259
+
260
+ INPUT:
261
+
262
+ - ``knot`` -- an instance of :class:`~sage.knots.knot.Knot`
263
+ - ``elems`` -- a tuple of elements of ``self``
264
+
265
+ EXAMPLES::
266
+
267
+ sage: # needs sage.groups
268
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
269
+ sage: FKIM = FreeKnotInfoMonoid()
270
+ sage: FKIM.inject_variables(select=3)
271
+ Defining K3_1
272
+ Defining K3_1m
273
+ sage: elems = (K3_1, K3_1m)
274
+ sage: K = Knots().from_table(3, 1)
275
+ sage: FKIM._check_elements(K, elems)
276
+ KnotInfo['K3_1m']
277
+ sage: K = Knots().from_table(4, 1)
278
+ sage: FKIM._check_elements(K, elems) is None
279
+ True
280
+ """
281
+ for e in elems:
282
+ k = e.as_knot()
283
+ if knot.pd_code() == k.pd_code():
284
+ return e
285
+ if knot._markov_move_cmp(k.braid()):
286
+ return e
287
+ return None
288
+
289
+ @cached_method
290
+ def _search_composition(self, max_cr, knot, hpoly):
291
+ r"""
292
+ Add KnotInfo items to the list of candidates that have
293
+ matching Homfly polynomial.
294
+
295
+ INPUT:
296
+
297
+ - ``max_cr`` -- max number of crossing to stop searching
298
+ - ``knot`` -- instance of :class:`~sage.knots.knot.Knot`
299
+ - ``hpoly`` -- Homfly polynomial to search for a component
300
+
301
+ OUTPUT:
302
+
303
+ A tuple of elements of ``self`` that match a (not necessarily prime or
304
+ proper) component of the given knot having the given Homfly polynomial.
305
+
306
+ EXAMPLES::
307
+
308
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
309
+ sage: FKIM = FreeKnotInfoMonoid()
310
+ sage: FKIM.inject_variables(select=3)
311
+ Defining K3_1
312
+ Defining K3_1m
313
+ sage: KI = K3_1 * K3_1m
314
+ sage: K = KI.as_knot()
315
+ sage: h = K3_1.to_knotinfo()[0][0].homfly_polynomial() # needs libhomfly sage.modules
316
+ sage: FKIM._search_composition(3, K, h) # needs libhomfly sage.modules
317
+ (KnotInfo['K3_1'],)
318
+ """
319
+ from sage.knots.knotinfo import KnotInfo
320
+
321
+ def hp_mirr(hp):
322
+ v, z = hp.parent().gens()
323
+ return hp.subs({v: ~v, z: z})
324
+
325
+ former_cr = 3
326
+ res = []
327
+ for K in KnotInfo:
328
+ if not K.is_knot():
329
+ break
330
+ c = K.crossing_number()
331
+ if c < 3:
332
+ continue
333
+ if c > max_cr:
334
+ break
335
+ hp = K.homfly_polynomial()
336
+ hp_sym = {s: hp for s in SymmetryMutant if s.is_minimal(K)}
337
+ hpm = hp_mirr(hp)
338
+ if hp != hpm:
339
+ hp_sym[SymmetryMutant.mirror_image] = hpm
340
+ if SymmetryMutant.concordance_inverse in hp_sym.keys():
341
+ hp_sym[SymmetryMutant.concordance_inverse] = hpm
342
+
343
+ for sym_mut, hps in hp_sym.items():
344
+ if hps.divides(hpoly):
345
+ Kgen = self((K, sym_mut))
346
+ h = hpoly // hps
347
+ if h.is_unit():
348
+ res += [Kgen]
349
+ else:
350
+ res_rec = self._search_composition(max_cr - c, knot, h)
351
+ if res_rec:
352
+ res += [Kgen * k for k in res_rec]
353
+ if c > former_cr and res:
354
+ k = self._check_elements(knot, tuple(res))
355
+ if k:
356
+ # matching item found
357
+ return tuple([k])
358
+ former_cr = c
359
+
360
+ return tuple(sorted(set(res)))
361
+
362
+ @cached_method
363
+ def _from_knot(self, knot):
364
+ """
365
+ Create a tuple of element of this abelian monoid which possibly
366
+ represent ``knot``. This method caches the performance relevant
367
+ part of :meth:`from_knot`.
368
+
369
+ INPUT:
370
+
371
+ - ``knot`` -- an instance of :class:`~sage.knots.knot.Knot`
372
+
373
+ EXAMPLES::
374
+
375
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
376
+ sage: FKIM = FreeKnotInfoMonoid()
377
+ sage: K = KnotInfo.K5_1.link().mirror_image()
378
+ sage: FKIM._from_knot(K) # needs sage.groups sage.modules
379
+ (KnotInfo['K5_1m'],)
380
+ """
381
+ hp = knot.homfly_polynomial(normalization='vz')
382
+ return self._search_composition(13, knot, hp)
383
+
384
+ def from_knot(self, knot, unique=True):
385
+ """
386
+ Create an element of this abelian monoid from ``knot``.
387
+
388
+ INPUT:
389
+
390
+ - ``knot`` -- an instance of :class:`~sage.knots.knot.Knot`
391
+
392
+ - ``unique`` -- boolean (default is ``True``). This only affects the case
393
+ where a unique identification is not possible. If set to ``False`` you
394
+ can obtain a matching list (see explanation of the output below)
395
+
396
+ OUTPUT:
397
+
398
+ An instance of the element class of ``self`` per default. If the keyword
399
+ argument ``unique`` then a list of such instances is returned.
400
+
401
+ EXAMPLES::
402
+
403
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
404
+ sage: FKIM = FreeKnotInfoMonoid()
405
+ sage: K = KnotInfo.K5_1.link().mirror_image()
406
+ sage: FKIM.from_knot(K) # needs libhomfly sage.modules
407
+ KnotInfo['K5_1m']
408
+
409
+ sage: # optional - database_knotinfo
410
+ sage: K = Knot(KnotInfo.K9_12.braid())
411
+ sage: FKIM.from_knot(K) # long time # optional - database_knotinfo
412
+ Traceback (most recent call last):
413
+ ...
414
+ NotImplementedError: this (possibly non prime) knot cannot be
415
+ identified uniquely by KnotInfo
416
+ use keyword argument `unique` to obtain more details
417
+ sage: FKIM.from_knot(K, unique=False) # long time # optional - database_knotinfo
418
+ [KnotInfo['K4_1']*KnotInfo['K5_2'], KnotInfo['K9_12']]
419
+ """
420
+ hp = knot.homfly_polynomial(normalization='vz')
421
+ num_summands = sum(e for _, e in hp.factor())
422
+ if num_summands == 1:
423
+ return knot.get_knotinfo()
424
+
425
+ res = self._from_knot(knot)
426
+ if res:
427
+ if len(res) == 1:
428
+ if unique:
429
+ return res[0]
430
+ return [res[0]] # to be consistent with get_knotinfo
431
+ k = self._check_elements(knot, res)
432
+ if k:
433
+ if unique:
434
+ return k
435
+ return [k] # to be consistent with get_knotinfo
436
+
437
+ if res and not unique:
438
+ return sorted(set(res))
439
+ if unique and len(res) > 1:
440
+ non_unique_hint = '\nuse keyword argument `unique` to obtain more details'
441
+ raise NotImplementedError('this (possibly non prime) knot cannot be identified uniquely by KnotInfo%s' % non_unique_hint)
442
+ raise NotImplementedError('this (possibly non prime) knot cannot be identified by KnotInfo')
443
+
444
+ def inject_variables(self, select=None, verbose=True):
445
+ """
446
+ Inject ``self`` with its name into the namespace of the
447
+ Python code from which this function is called.
448
+
449
+ INPUT:
450
+
451
+ - ``select`` -- instance of :class:`~sage.knots.knotinfo.KnotInfoBase`,
452
+ :class:`~sage.knots.knotinfo.KnotInfoSeries` or an integer. In all
453
+ cases the input is used to restrict the injected generators to the
454
+ according subset (number of crossings in the case of integer)
455
+ - ``verbose`` -- boolean (optional, default ``True``) to suppress
456
+ the message printed on the invocation
457
+
458
+ EXAMPLES::
459
+
460
+ sage: from sage.knots.free_knotinfo_monoid import FreeKnotInfoMonoid
461
+ sage: FKIM = FreeKnotInfoMonoid(5)
462
+ sage: FKIM.inject_variables(select=3)
463
+ Defining K3_1
464
+ Defining K3_1m
465
+ sage: FKIM.inject_variables(select=KnotInfo.K5_2)
466
+ Defining K5_2
467
+ Defining K5_2m
468
+ sage: FKIM.inject_variables(select=KnotInfo.K5_2.series())
469
+ Defining K5_1
470
+ Defining K5_1m
471
+ sage: FKIM.inject_variables()
472
+ Defining K0_1
473
+ Defining K4_1
474
+ """
475
+ from sage.knots.knotinfo import KnotInfoBase, KnotInfoSeries
476
+ from sage.rings.integer import Integer
477
+ gen_list = []
478
+ idx_dict = self._index_dict
479
+ max_crn = self._max_crossing_number
480
+ gens = self.gens()
481
+ if select:
482
+ if isinstance(select, KnotInfoBase):
483
+ crn = select.crossing_number()
484
+ if crn > max_crn:
485
+ self._set_index_dictionary(max_crossing_number=crn)
486
+ gen_list += [k for k, v in idx_dict.items() if v[0] == select]
487
+ elif isinstance(select, KnotInfoSeries):
488
+ for v in select:
489
+ self.inject_variables(select=v)
490
+ return
491
+ elif type(select) is int or isinstance(select, Integer):
492
+ crn = select
493
+ if crn > max_crn:
494
+ self._set_index_dictionary(max_crossing_number=crn)
495
+ gen_list += [k for k, v in idx_dict.items()
496
+ if v[0].crossing_number() == crn]
497
+ else:
498
+ raise TypeError('cannot select generators by %s' % select)
499
+ else:
500
+ gen_list = list(idx_dict.keys())
501
+
502
+ from sage.repl.user_globals import set_global, get_globals
503
+ for name in gen_list:
504
+ if name not in get_globals().keys():
505
+ set_global(name, gens[name])
506
+ if verbose:
507
+ print("Defining %s" % (name))