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
@@ -0,0 +1,275 @@
1
+ # sage_setup: distribution = sagemath-graphs
2
+ """
3
+ Mobile posets
4
+ """
5
+ # ****************************************************************************
6
+ # Copyright (C) 2020 Stefan Grosser <stefan.grosser1@gmail.com>
7
+ #
8
+ # This program is free software: you can redistribute it and/or modify
9
+ # it under the terms of the GNU General Public License as published by
10
+ # the Free Software Foundation, either version 2 of the License, or
11
+ # (at your option) any later version.
12
+ # https://www.gnu.org/licenses/
13
+ # ****************************************************************************
14
+
15
+ from sage.combinat.posets.posets import Poset, FinitePoset
16
+ from sage.misc.lazy_attribute import lazy_attribute
17
+ from .linear_extensions import LinearExtensionsOfMobile
18
+
19
+
20
+ class MobilePoset(FinitePoset):
21
+ r"""
22
+ A mobile poset.
23
+
24
+ Mobile posets are an extension of d-complete posets which permit a determinant
25
+ formula for counting linear extensions. They are formed by having a ribbon
26
+ poset with d-complete posets 'hanging' below it and at most one
27
+ d-complete poset above it, known as the anchor. See [GGMM2020]_
28
+ for the definition.
29
+
30
+ EXAMPLES::
31
+
32
+ sage: P = posets.MobilePoset(posets.RibbonPoset(7, [1,3]), # needs sage.combinat sage.modules
33
+ ....: {1: [posets.YoungDiagramPoset([3, 2], dual=True)],
34
+ ....: 3: [posets.DoubleTailedDiamond(6)]},
35
+ ....: anchor=(4, 2, posets.ChainPoset(6)))
36
+ sage: len(P._ribbon) # needs sage.combinat sage.modules
37
+ 8
38
+ sage: P._anchor # needs sage.combinat sage.modules
39
+ (4, 5)
40
+
41
+ This example is Example 5.9 in [GGMM2020]_::
42
+
43
+ sage: P1 = posets.MobilePoset(posets.RibbonPoset(8, [2,3,4]),
44
+ ....: {4: [posets.ChainPoset(1)]},
45
+ ....: anchor=(3, 0, posets.ChainPoset(1)))
46
+ sage: sorted([P1._element_to_vertex(i) for i in P1._ribbon])
47
+ [0, 1, 2, 6, 7, 9]
48
+ sage: P1._anchor
49
+ (3, 2)
50
+
51
+ sage: P2 = posets.MobilePoset(posets.RibbonPoset(15, [1,3,5,7,9,11,13]),
52
+ ....: {}, anchor=(8, 0, posets.ChainPoset(1)))
53
+ sage: sorted(P2._ribbon)
54
+ [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
55
+ sage: P2._anchor
56
+ (8, (8, 0))
57
+ sage: P2.linear_extensions().cardinality() # needs sage.modules
58
+ 21399440939
59
+
60
+ sage: EP = posets.MobilePoset(posets.ChainPoset(0), {})
61
+ Traceback (most recent call last):
62
+ ...
63
+ ValueError: the empty poset is not a mobile poset
64
+ """
65
+ _lin_ext_type = LinearExtensionsOfMobile
66
+ _desc = 'Finite mobile poset'
67
+
68
+ def __init__(self, hasse_diagram, elements, category, facade, key, ribbon=None, check=True) -> None:
69
+ r"""
70
+ Initialize ``self``.
71
+
72
+ EXAMPLES::
73
+
74
+ sage: P = posets.MobilePoset(posets.RibbonPoset(15, [1,3,5,7,9,11,13]),
75
+ ....: {}, anchor=(8, 0, posets.ChainPoset(1)))
76
+ sage: TestSuite(P).run()
77
+ """
78
+ FinitePoset.__init__(self, hasse_diagram=hasse_diagram, elements=elements,
79
+ category=category, facade=facade, key=key)
80
+ if not self._hasse_diagram:
81
+ raise ValueError("the empty poset is not a mobile poset")
82
+
83
+ if ribbon:
84
+ if check and not self._is_valid_ribbon(ribbon):
85
+ raise ValueError("invalid ribbon")
86
+ self._ribbon = ribbon
87
+
88
+ def _is_valid_ribbon(self, ribbon):
89
+ r"""
90
+ Return ``True`` if a ribbon has at most one anchor, no vertex has two
91
+ or more anchors, and every hanging poset is d-complete.
92
+
93
+ INPUT:
94
+
95
+ - ``ribbon`` -- list of elements that form a ribbon in your poset
96
+
97
+ TESTS::
98
+
99
+ sage: P = posets.RibbonPoset(5, [2])
100
+ sage: P._is_valid_ribbon([0,1,2,3,4])
101
+ True
102
+ sage: P._is_valid_ribbon([2])
103
+ False
104
+ sage: P._is_valid_ribbon([2,3,4])
105
+ True
106
+ sage: P._is_valid_ribbon([2,3])
107
+ True
108
+ """
109
+ ribbon = [self._element_to_vertex(x) for x in ribbon]
110
+ G = self._hasse_diagram
111
+ G_un = G.to_undirected().copy(immutable=False)
112
+ R = G.subgraph(ribbon)
113
+ num_anchors = 0
114
+
115
+ for r in ribbon:
116
+ anchor_neighbors = set(G.neighbor_out_iterator(r)).difference(set(R.neighbor_out_iterator(r)))
117
+ if len(anchor_neighbors) == 1:
118
+ num_anchors += 1
119
+ elif len(anchor_neighbors) > 1:
120
+ return False
121
+
122
+ for lc in G.neighbor_in_iterator(r):
123
+ if lc in ribbon:
124
+ continue
125
+
126
+ G_un.delete_edge(lc, r)
127
+ P = Poset(G.subgraph(G_un.connected_component_containing_vertex(lc, sort=False)))
128
+ if P.top() != lc or not P.is_d_complete():
129
+ return False
130
+ G_un.add_edge(lc, r)
131
+
132
+ return True
133
+
134
+ @lazy_attribute
135
+ def _anchor(self):
136
+ r"""
137
+ The anchor of the mobile poset.
138
+
139
+ TESTS::
140
+
141
+ sage: from sage.combinat.posets.mobile import MobilePoset
142
+ sage: M = MobilePoset(DiGraph([[0,1,2,3,4,5,6,7,8],
143
+ ....: [(1,0),(3,0),(2,1),(2,3),(4,3), (5,4),(5,6),(7,4),(7,8)]]))
144
+ sage: M._anchor
145
+ (4, 3)
146
+ """
147
+ ribbon = [self._element_to_vertex(x) for x in self._ribbon]
148
+ H = self._hasse_diagram
149
+ R = H.subgraph(ribbon)
150
+
151
+ anchor = None
152
+
153
+ # Find the anchor vertex, if it exists, and return the edge
154
+ for r in ribbon:
155
+ anchor_neighbors = set(H.neighbor_out_iterator(r)).difference(set(R.neighbor_out_iterator(r)))
156
+ if len(anchor_neighbors) == 1:
157
+ anchor = (r, anchor_neighbors.pop())
158
+ break
159
+ return (self._vertex_to_element(anchor[0]), self._vertex_to_element(anchor[1])) if anchor is not None else None
160
+
161
+ @lazy_attribute
162
+ def _ribbon(self):
163
+ r"""
164
+ The ribbon of the mobile poset.
165
+
166
+ TESTS::
167
+
168
+ sage: from sage.combinat.posets.mobile import MobilePoset
169
+ sage: M = MobilePoset(DiGraph([[0,1,2,3,4,5,6,7,8],
170
+ ....: [(1,0),(3,0),(2,1),(2,3),(4,3), (5,4),(5,6),(7,4),(7,8)]]))
171
+ sage: sorted(M._ribbon)
172
+ [4, 5, 6, 7, 8]
173
+ sage: M._is_valid_ribbon(M._ribbon)
174
+ True
175
+ sage: M2 = MobilePoset(Poset([[0,1,2,3,4,5,6,7,8],
176
+ ....: [(1,0),(3,0),(2,1),(2,3),(4,3),(5,4),(7,4),(7,8)]]))
177
+ sage: sorted(M2._ribbon)
178
+ [4, 7, 8]
179
+ sage: M2._is_valid_ribbon(M2._ribbon)
180
+ True
181
+ """
182
+ H = self._hasse_diagram
183
+ H_un = H.to_undirected()
184
+ max_elmts = H.sinks()
185
+ # Compute anchor, ribbon
186
+ ribbon = [] # In order list of elements on zigzag
187
+
188
+ if len(max_elmts) == 1:
189
+ return [self._vertex_to_element(max_elmts[0])]
190
+ # Compute max element tree by merging shortest paths
191
+ start = max_elmts[0]
192
+
193
+ zigzag_elmts = set()
194
+ for m in max_elmts[1:]:
195
+ sp = H_un.shortest_path(start, m)
196
+ zigzag_elmts.update(sp)
197
+ max_elmt_graph = H.subgraph(zigzag_elmts)
198
+ G = max_elmt_graph.to_undirected()
199
+
200
+ if G.is_path():
201
+ # Check if there is a anchor by seeing if there is more than one acyclic path to the next max
202
+ ends = max_elmt_graph.vertices(sort=True, degree=1)
203
+ # Form ribbon
204
+ ribbon = G.shortest_path(ends[0], ends[1])
205
+ for end_count, end in enumerate(ends):
206
+ if not (H_un.is_cut_vertex(end) or H_un.degree(end) == 1):
207
+ traverse_ribbon = ribbon if end_count == 0 else ribbon[::-1]
208
+ for ind, p in enumerate(traverse_ribbon):
209
+ if H_un.is_cut_edge(p, traverse_ribbon[ind + 1]):
210
+ return [self._vertex_to_element(r)
211
+ for r in G.shortest_path(ends[(end_count + 1) % 2], traverse_ribbon[ind + 1])]
212
+ return [self._vertex_to_element(r) for r in ribbon]
213
+
214
+ # First check path counts between ends and deg3 vertex
215
+ # Then check if more than one max elmt on way to degree 3 vertex.
216
+ # Then check if the edge going to a max element is down from the degree 3 vertex
217
+ # Arbitrarily choose between ones with just 1
218
+
219
+ ends = max_elmt_graph.vertices(sort=True, degree=1)
220
+ deg3 = max_elmt_graph.vertices(sort=True, degree=3)[0]
221
+
222
+ anchoredEnd = None
223
+ for end in ends:
224
+ if not (H_un.is_cut_vertex(end) or H_un.degree(end) == 1):
225
+ anchoredEnd = end
226
+ break
227
+
228
+ if anchoredEnd is not None:
229
+ ends.remove(anchoredEnd)
230
+ return [self._vertex_to_element(r) for r in G.shortest_path(ends[0], ends[1])]
231
+
232
+ possible_anchors = ends[:]
233
+ for end in ends:
234
+ path = G.shortest_path(end, deg3)
235
+ if sum(bool(z in max_elmts) for z in path) != 1:
236
+ possible_anchors.remove(end)
237
+
238
+ for p in possible_anchors:
239
+ path = G.shortest_path(p, deg3)
240
+ if max_elmt_graph.has_edge(path[-2], path[-1]):
241
+ possible_anchors.remove(p)
242
+
243
+ anchoredEnd = possible_anchors[0]
244
+ ends.remove(anchoredEnd)
245
+ return [self._vertex_to_element(r) for r in G.shortest_path(ends[0], ends[1])]
246
+
247
+ def ribbon(self):
248
+ r"""
249
+ Return the ribbon of the mobile poset.
250
+
251
+ EXAMPLES::
252
+
253
+ sage: from sage.combinat.posets.mobile import MobilePoset
254
+ sage: M3 = MobilePoset(Posets.RibbonPoset(5, [1,2]))
255
+ sage: sorted(M3.ribbon())
256
+ [1, 2, 3, 4]
257
+ """
258
+ return self._ribbon
259
+
260
+ def anchor(self):
261
+ r"""
262
+ Return the anchor of the mobile poset.
263
+
264
+ EXAMPLES::
265
+
266
+ sage: from sage.combinat.posets.mobile import MobilePoset
267
+ sage: M2 = MobilePoset(Poset([[0,1,2,3,4,5,6,7,8],
268
+ ....: [(1,0),(3,0),(2,1),(2,3),(4,3),(5,4),(7,4),(7,8)]]))
269
+ sage: M2.anchor()
270
+ (4, 3)
271
+ sage: M3 = MobilePoset(Posets.RibbonPoset(5, [1,2]))
272
+ sage: M3.anchor() is None
273
+ True
274
+ """
275
+ return self._anchor