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.
- passagemath_graphs-10.6.1rc1.dist-info/METADATA +292 -0
- passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
- passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
- passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
- passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
- passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
- passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
- sage/all__sagemath_graphs.py +39 -0
- sage/combinat/abstract_tree.py +2723 -0
- sage/combinat/all__sagemath_graphs.py +34 -0
- sage/combinat/binary_tree.py +5306 -0
- sage/combinat/cluster_algebra_quiver/all.py +22 -0
- sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
- sage/combinat/cluster_algebra_quiver/interact.py +124 -0
- sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
- sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
- sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
- sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
- sage/combinat/designs/MOLS_handbook_data.py +570 -0
- sage/combinat/designs/all.py +58 -0
- sage/combinat/designs/bibd.py +1655 -0
- sage/combinat/designs/block_design.py +1071 -0
- sage/combinat/designs/covering_array.py +269 -0
- sage/combinat/designs/covering_design.py +530 -0
- sage/combinat/designs/database.py +5615 -0
- sage/combinat/designs/design_catalog.py +122 -0
- sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/designs_pyx.pxd +21 -0
- sage/combinat/designs/designs_pyx.pyx +993 -0
- sage/combinat/designs/difference_family.py +3951 -0
- sage/combinat/designs/difference_matrices.py +279 -0
- sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
- sage/combinat/designs/ext_rep.py +1064 -0
- sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
- sage/combinat/designs/group_divisible_designs.py +361 -0
- sage/combinat/designs/incidence_structures.py +2357 -0
- sage/combinat/designs/latin_squares.py +581 -0
- sage/combinat/designs/orthogonal_arrays.py +2244 -0
- sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
- sage/combinat/designs/resolvable_bibd.py +815 -0
- sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
- sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/subhypergraph_search.pyx +530 -0
- sage/combinat/designs/twographs.py +306 -0
- sage/combinat/finite_state_machine.py +14874 -0
- sage/combinat/finite_state_machine_generators.py +2006 -0
- sage/combinat/graph_path.py +448 -0
- sage/combinat/interval_posets.py +3908 -0
- sage/combinat/nu_tamari_lattice.py +269 -0
- sage/combinat/ordered_tree.py +1446 -0
- sage/combinat/posets/all.py +46 -0
- sage/combinat/posets/bubble_shuffle.py +247 -0
- sage/combinat/posets/cartesian_product.py +493 -0
- sage/combinat/posets/d_complete.py +182 -0
- sage/combinat/posets/elements.py +273 -0
- sage/combinat/posets/forest.py +30 -0
- sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/hasse_cython.pyx +174 -0
- sage/combinat/posets/hasse_diagram.py +3672 -0
- sage/combinat/posets/hochschild_lattice.py +158 -0
- sage/combinat/posets/incidence_algebras.py +794 -0
- sage/combinat/posets/lattices.py +5117 -0
- sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/linear_extension_iterator.pyx +292 -0
- sage/combinat/posets/linear_extensions.py +1037 -0
- sage/combinat/posets/mobile.py +275 -0
- sage/combinat/posets/moebius_algebra.py +776 -0
- sage/combinat/posets/poset_examples.py +2178 -0
- sage/combinat/posets/posets.py +9360 -0
- sage/combinat/rooted_tree.py +1070 -0
- sage/combinat/shard_order.py +239 -0
- sage/combinat/tamari_lattices.py +384 -0
- sage/combinat/yang_baxter_graph.py +923 -0
- sage/databases/all__sagemath_graphs.py +1 -0
- sage/databases/knotinfo_db.py +1231 -0
- sage/ext_data/all__sagemath_graphs.py +1 -0
- sage/ext_data/graphs/graph_plot_js.html +330 -0
- sage/ext_data/kenzo/CP2.txt +45 -0
- sage/ext_data/kenzo/CP3.txt +349 -0
- sage/ext_data/kenzo/CP4.txt +4774 -0
- sage/ext_data/kenzo/README.txt +49 -0
- sage/ext_data/kenzo/S4.txt +20 -0
- sage/graphs/all.py +42 -0
- sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/asteroidal_triples.pyx +320 -0
- sage/graphs/base/all.py +1 -0
- sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/boost_graph.pxd +106 -0
- sage/graphs/base/boost_graph.pyx +3045 -0
- sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/c_graph.pxd +106 -0
- sage/graphs/base/c_graph.pyx +5096 -0
- sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/dense_graph.pxd +28 -0
- sage/graphs/base/dense_graph.pyx +801 -0
- sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/graph_backends.pxd +5 -0
- sage/graphs/base/graph_backends.pyx +797 -0
- sage/graphs/base/overview.py +85 -0
- sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/sparse_graph.pxd +90 -0
- sage/graphs/base/sparse_graph.pyx +1653 -0
- sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_dense_graph.pxd +5 -0
- sage/graphs/base/static_dense_graph.pyx +1032 -0
- sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_backend.pxd +27 -0
- sage/graphs/base/static_sparse_backend.pyx +1583 -0
- sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_graph.pxd +37 -0
- sage/graphs/base/static_sparse_graph.pyx +1375 -0
- sage/graphs/bipartite_graph.py +2732 -0
- sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/centrality.pyx +1038 -0
- sage/graphs/cographs.py +519 -0
- sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/comparability.pyx +851 -0
- sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/connectivity.pxd +157 -0
- sage/graphs/connectivity.pyx +4813 -0
- sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/convexity_properties.pxd +16 -0
- sage/graphs/convexity_properties.pyx +870 -0
- sage/graphs/digraph.py +4754 -0
- sage/graphs/digraph_generators.py +1993 -0
- sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/distances_all_pairs.pxd +12 -0
- sage/graphs/distances_all_pairs.pyx +2938 -0
- sage/graphs/domination.py +1363 -0
- sage/graphs/dot2tex_utils.py +100 -0
- sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/edge_connectivity.pyx +1215 -0
- sage/graphs/generators/all.py +1 -0
- sage/graphs/generators/basic.py +1769 -0
- sage/graphs/generators/chessboard.py +538 -0
- sage/graphs/generators/classical_geometries.py +1611 -0
- sage/graphs/generators/degree_sequence.py +235 -0
- sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generators/distance_regular.pyx +2846 -0
- sage/graphs/generators/families.py +4759 -0
- sage/graphs/generators/intersection.py +565 -0
- sage/graphs/generators/platonic_solids.py +262 -0
- sage/graphs/generators/random.py +2623 -0
- sage/graphs/generators/smallgraphs.py +5741 -0
- sage/graphs/generators/world_map.py +724 -0
- sage/graphs/generic_graph.py +26867 -0
- sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/generic_graph_pyx.pxd +34 -0
- sage/graphs/generic_graph_pyx.pyx +1673 -0
- sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/genus.pyx +622 -0
- sage/graphs/graph.py +9645 -0
- sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_coloring.pyx +2284 -0
- sage/graphs/graph_database.py +1177 -0
- sage/graphs/graph_decompositions/all.py +1 -0
- sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
- sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
- sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
- sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/graph_products.pyx +508 -0
- sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
- sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
- sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
- sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
- sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
- sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
- sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
- sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
- sage/graphs/graph_editor.py +82 -0
- sage/graphs/graph_generators.py +3314 -0
- sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_generators_pyx.pyx +95 -0
- sage/graphs/graph_input.py +812 -0
- sage/graphs/graph_latex.py +2064 -0
- sage/graphs/graph_list.py +410 -0
- sage/graphs/graph_plot.py +1756 -0
- sage/graphs/graph_plot_js.py +338 -0
- sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/hyperbolicity.pyx +1704 -0
- sage/graphs/hypergraph_generators.py +364 -0
- sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/independent_sets.pxd +13 -0
- sage/graphs/independent_sets.pyx +402 -0
- sage/graphs/isgci.py +1033 -0
- sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/isoperimetric_inequalities.pyx +489 -0
- sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/line_graph.pyx +743 -0
- sage/graphs/lovasz_theta.py +77 -0
- sage/graphs/matching.py +1633 -0
- sage/graphs/matching_covered_graph.py +3590 -0
- sage/graphs/orientations.py +1489 -0
- sage/graphs/partial_cube.py +459 -0
- sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/path_enumeration.pyx +2040 -0
- sage/graphs/pq_trees.py +1129 -0
- sage/graphs/print_graphs.py +201 -0
- sage/graphs/schnyder.py +865 -0
- sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/spanning_tree.pyx +1457 -0
- sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/strongly_regular_db.pyx +3340 -0
- sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/traversals.pxd +9 -0
- sage/graphs/traversals.pyx +1872 -0
- sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/trees.pxd +15 -0
- sage/graphs/trees.pyx +310 -0
- sage/graphs/tutte_polynomial.py +713 -0
- sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/views.pyx +794 -0
- sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/graphs/weakly_chordal.pyx +604 -0
- sage/groups/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
- sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
- sage/knots/all.py +6 -0
- sage/knots/free_knotinfo_monoid.py +507 -0
- sage/knots/gauss_code.py +291 -0
- sage/knots/knot.py +682 -0
- sage/knots/knot_table.py +284 -0
- sage/knots/knotinfo.py +2900 -0
- sage/knots/link.py +4715 -0
- sage/sandpiles/all.py +13 -0
- sage/sandpiles/examples.py +225 -0
- sage/sandpiles/sandpile.py +6365 -0
- sage/topology/all.py +22 -0
- sage/topology/cell_complex.py +1214 -0
- sage/topology/cubical_complex.py +1976 -0
- sage/topology/delta_complex.py +1806 -0
- sage/topology/filtered_simplicial_complex.py +744 -0
- sage/topology/moment_angle_complex.py +823 -0
- sage/topology/simplicial_complex.py +5160 -0
- sage/topology/simplicial_complex_catalog.py +92 -0
- sage/topology/simplicial_complex_examples.py +1680 -0
- sage/topology/simplicial_complex_homset.py +205 -0
- sage/topology/simplicial_complex_morphism.py +836 -0
- sage/topology/simplicial_set.py +4102 -0
- sage/topology/simplicial_set_catalog.py +55 -0
- sage/topology/simplicial_set_constructions.py +2954 -0
- sage/topology/simplicial_set_examples.py +865 -0
- 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
|