passagemath-graphs 10.5.43__cp39-cp39-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.5.43.dist-info/METADATA +293 -0
- passagemath_graphs-10.5.43.dist-info/RECORD +258 -0
- passagemath_graphs-10.5.43.dist-info/WHEEL +5 -0
- passagemath_graphs-10.5.43.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 +2552 -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 +125 -0
- sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
- sage/combinat/cluster_algebra_quiver/mutation_type.py +1556 -0
- sage/combinat/cluster_algebra_quiver/quiver.py +2262 -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 +534 -0
- sage/combinat/designs/database.py +5614 -0
- sage/combinat/designs/design_catalog.py +122 -0
- sage/combinat/designs/designs_pyx.cpython-39-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-39-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-39-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 +548 -0
- sage/combinat/designs/orthogonal_arrays.py +2243 -0
- sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +966 -0
- sage/combinat/designs/resolvable_bibd.py +781 -0
- sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
- sage/combinat/designs/subhypergraph_search.cpython-39-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/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-39-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/hasse_cython.pyx +174 -0
- sage/combinat/posets/hasse_diagram.py +3678 -0
- sage/combinat/posets/incidence_algebras.py +796 -0
- sage/combinat/posets/lattices.py +5119 -0
- sage/combinat/posets/linear_extension_iterator.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/combinat/posets/linear_extension_iterator.pyx +292 -0
- sage/combinat/posets/linear_extensions.py +1039 -0
- sage/combinat/posets/mobile.py +275 -0
- sage/combinat/posets/moebius_algebra.py +776 -0
- sage/combinat/posets/poset_examples.py +2131 -0
- sage/combinat/posets/posets.py +9169 -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 +1230 -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-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/asteroidal_triples.pyx +299 -0
- sage/graphs/base/all.py +1 -0
- sage/graphs/base/boost_graph.cpython-39-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-39-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-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/dense_graph.pxd +26 -0
- sage/graphs/base/dense_graph.pyx +757 -0
- sage/graphs/base/graph_backends.cpython-39-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-39-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-39-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-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_backend.pxd +27 -0
- sage/graphs/base/static_sparse_backend.pyx +1580 -0
- sage/graphs/base/static_sparse_graph.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/base/static_sparse_graph.pxd +37 -0
- sage/graphs/base/static_sparse_graph.pyx +1304 -0
- sage/graphs/bipartite_graph.py +2709 -0
- sage/graphs/centrality.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/centrality.pyx +965 -0
- sage/graphs/cographs.py +519 -0
- sage/graphs/comparability.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/comparability.pyx +813 -0
- sage/graphs/connectivity.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/connectivity.pxd +157 -0
- sage/graphs/connectivity.pyx +4813 -0
- sage/graphs/convexity_properties.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/convexity_properties.pxd +16 -0
- sage/graphs/convexity_properties.pyx +827 -0
- sage/graphs/digraph.py +4410 -0
- sage/graphs/digraph_generators.py +1921 -0
- sage/graphs/distances_all_pairs.cpython-39-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-39-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-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/generators/distance_regular.pyx +2846 -0
- sage/graphs/generators/families.py +4749 -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 +26395 -0
- sage/graphs/generic_graph_pyx.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/generic_graph_pyx.pxd +34 -0
- sage/graphs/generic_graph_pyx.pyx +1626 -0
- sage/graphs/genus.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/genus.pyx +623 -0
- sage/graphs/graph.py +9362 -0
- sage/graphs/graph_coloring.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_coloring.pyx +2284 -0
- sage/graphs/graph_database.py +1122 -0
- sage/graphs/graph_decompositions/all.py +1 -0
- sage/graphs/graph_decompositions/bandwidth.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
- sage/graphs/graph_decompositions/clique_separators.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/clique_separators.pyx +595 -0
- sage/graphs/graph_decompositions/cutwidth.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
- sage/graphs/graph_decompositions/fast_digraph.cpython-39-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-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/graph_products.pyx +462 -0
- sage/graphs/graph_decompositions/modular_decomposition.cpython-39-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-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
- sage/graphs/graph_decompositions/slice_decomposition.pyx +1080 -0
- sage/graphs/graph_decompositions/tree_decomposition.cpython-39-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-39-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 +3301 -0
- sage/graphs/graph_generators_pyx.cpython-39-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 +367 -0
- sage/graphs/graph_plot.py +1749 -0
- sage/graphs/graph_plot_js.py +338 -0
- sage/graphs/hyperbolicity.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/hyperbolicity.pyx +1702 -0
- sage/graphs/hypergraph_generators.py +364 -0
- sage/graphs/independent_sets.cpython-39-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-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/isoperimetric_inequalities.pyx +453 -0
- sage/graphs/line_graph.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/line_graph.pyx +627 -0
- sage/graphs/lovasz_theta.py +77 -0
- sage/graphs/matching.py +1633 -0
- sage/graphs/matching_covered_graph.py +3566 -0
- sage/graphs/orientations.py +1504 -0
- sage/graphs/partial_cube.py +459 -0
- sage/graphs/path_enumeration.cpython-39-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-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/spanning_tree.pyx +1457 -0
- sage/graphs/strongly_regular_db.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/strongly_regular_db.pyx +3340 -0
- sage/graphs/traversals.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/traversals.pxd +9 -0
- sage/graphs/traversals.pyx +1871 -0
- sage/graphs/trees.cpython-39-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-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/views.pyx +794 -0
- sage/graphs/weakly_chordal.cpython-39-aarch64-linux-gnu.so +0 -0
- sage/graphs/weakly_chordal.pyx +562 -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-39-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 +2880 -0
- sage/knots/link.py +4682 -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 +1977 -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 +5161 -0
- sage/topology/simplicial_complex_catalog.py +86 -0
- sage/topology/simplicial_complex_examples.py +1692 -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,182 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
# sage.doctest: needs sage.combinat sage.modules
|
3
|
+
r"""
|
4
|
+
D-complete posets
|
5
|
+
|
6
|
+
AUTHORS:
|
7
|
+
|
8
|
+
- Stefan Grosser (06-2020): initial implementation
|
9
|
+
"""
|
10
|
+
|
11
|
+
# ****************************************************************************
|
12
|
+
# Copyright (C) 2020 Stefan Grosser <stefan.grosser1@gmail.com>
|
13
|
+
#
|
14
|
+
# This program is free software: you can redistribute it and/or modify
|
15
|
+
# it under the terms of the GNU General Public License as published by
|
16
|
+
# the Free Software Foundation, either version 2 of the License, or
|
17
|
+
# (at your option) any later version.
|
18
|
+
# https://www.gnu.org/licenses/
|
19
|
+
# ****************************************************************************
|
20
|
+
|
21
|
+
from sage.misc.lazy_attribute import lazy_attribute
|
22
|
+
from .linear_extensions import LinearExtensionsOfPosetWithHooks
|
23
|
+
from .lattices import FiniteJoinSemilattice
|
24
|
+
from collections import deque
|
25
|
+
from sage.rings.integer_ring import ZZ
|
26
|
+
from sage.misc.misc_c import prod
|
27
|
+
|
28
|
+
|
29
|
+
class DCompletePoset(FiniteJoinSemilattice):
|
30
|
+
r"""
|
31
|
+
A d-complete poset.
|
32
|
+
|
33
|
+
D-complete posets are a class of posets introduced by Proctor
|
34
|
+
in [Proc1999]_. It includes common families such as shapes, shifted
|
35
|
+
shapes, and rooted forests. Proctor showed in [PDynk1999]_ that
|
36
|
+
d-complete posets have decompositions in *irreducible* posets,
|
37
|
+
and showed in [Proc2014]_ that d-complete posets admit a hook-length
|
38
|
+
formula (see :wikipedia:`Hook_length_formula`). A complete proof of
|
39
|
+
the hook-length formula can be found in [KY2019]_.
|
40
|
+
|
41
|
+
EXAMPLES::
|
42
|
+
|
43
|
+
sage: from sage.combinat.posets.poset_examples import Posets
|
44
|
+
sage: P = Posets.DoubleTailedDiamond(2)
|
45
|
+
sage: TestSuite(P).run()
|
46
|
+
"""
|
47
|
+
_lin_ext_type = LinearExtensionsOfPosetWithHooks
|
48
|
+
_desc = "Finite d-complete poset"
|
49
|
+
|
50
|
+
@lazy_attribute
|
51
|
+
def _hooks(self):
|
52
|
+
r"""
|
53
|
+
The hook lengths of the elements of the d-complete poset.
|
54
|
+
|
55
|
+
See [KY2019]_ for the definition of hook lengths for d-complete posets.
|
56
|
+
|
57
|
+
TESTS::
|
58
|
+
|
59
|
+
sage: from sage.combinat.posets.d_complete import DCompletePoset
|
60
|
+
sage: P = DCompletePoset(DiGraph({0: [1, 2], 1: [3], 2: [3], 3: []}))
|
61
|
+
sage: P._hooks
|
62
|
+
{0: 1, 1: 2, 2: 2, 3: 3}
|
63
|
+
sage: from sage.combinat.posets.poset_examples import Posets
|
64
|
+
sage: P = DCompletePoset(Posets.YoungDiagramPoset(Partition([3,2,1]))._hasse_diagram.reverse())
|
65
|
+
sage: P._hooks
|
66
|
+
{0: 5, 1: 3, 2: 1, 3: 3, 4: 1, 5: 1}
|
67
|
+
"""
|
68
|
+
hooks = {}
|
69
|
+
|
70
|
+
min_diamond = {} # Maps max of double-tailed diamond to min of double-tailed diamond
|
71
|
+
max_diamond = {} # Maps min of double-tailed diamond to max of double-tailed diamond
|
72
|
+
|
73
|
+
H = self._hasse_diagram
|
74
|
+
|
75
|
+
diamonds, _ = H.diamonds() # Tuples of four elements that are diamonds
|
76
|
+
|
77
|
+
diamond_index = {} # Map max elmt of double tailed diamond to index of diamond
|
78
|
+
|
79
|
+
# Find all the double-tailed diamonds and map the mins and maxes
|
80
|
+
for index, d in enumerate(diamonds):
|
81
|
+
min_diamond[d[3]] = d[0]
|
82
|
+
max_diamond[d[0]] = d[3]
|
83
|
+
diamond_index[d[3]] = index
|
84
|
+
|
85
|
+
min_elmt = d[0]
|
86
|
+
max_elmt = d[3]
|
87
|
+
|
88
|
+
while True:
|
89
|
+
potential_min = H.neighbors_in(min_elmt)
|
90
|
+
potential_max = H.neighbors_out(max_elmt)
|
91
|
+
|
92
|
+
# Check if any of these make a longer double tailed diamond
|
93
|
+
found_diamond = False
|
94
|
+
for mx in potential_max:
|
95
|
+
if H.in_degree(mx) != 1:
|
96
|
+
continue
|
97
|
+
for mn in potential_min:
|
98
|
+
if len(H.all_paths(mn, mx)) == 2:
|
99
|
+
# Success
|
100
|
+
min_elmt = mn
|
101
|
+
max_elmt = mx
|
102
|
+
min_diamond[mx] = mn
|
103
|
+
max_diamond[mn] = mx
|
104
|
+
diamond_index[mx] = index
|
105
|
+
found_diamond = True
|
106
|
+
break
|
107
|
+
if found_diamond:
|
108
|
+
break
|
109
|
+
if not found_diamond:
|
110
|
+
break
|
111
|
+
# Compute the hooks
|
112
|
+
queue = deque(H.sources())
|
113
|
+
enqueued = set()
|
114
|
+
while queue:
|
115
|
+
elmt = queue.popleft()
|
116
|
+
if elmt not in diamond_index:
|
117
|
+
hooks[elmt] = H.order_ideal_cardinality([elmt])
|
118
|
+
else:
|
119
|
+
diamond = diamonds[diamond_index[elmt]]
|
120
|
+
side1 = diamond[1]
|
121
|
+
side2 = diamond[2]
|
122
|
+
hooks[elmt] = hooks[side1] + hooks[side2] - hooks[min_diamond[elmt]]
|
123
|
+
enqueued.add(elmt)
|
124
|
+
|
125
|
+
for c in H.neighbors_out(elmt):
|
126
|
+
if c not in enqueued:
|
127
|
+
queue.append(c)
|
128
|
+
enqueued.add(c)
|
129
|
+
|
130
|
+
poset_hooks = {self._vertex_to_element(key): ZZ(value) for (key, value) in hooks.items()}
|
131
|
+
return poset_hooks
|
132
|
+
|
133
|
+
def get_hook(self, elmt):
|
134
|
+
r"""
|
135
|
+
Return the hook length of the element ``elmt``.
|
136
|
+
|
137
|
+
EXAMPLES::
|
138
|
+
|
139
|
+
sage: from sage.combinat.posets.d_complete import DCompletePoset
|
140
|
+
sage: P = DCompletePoset(DiGraph({0: [1], 1: [2]}))
|
141
|
+
sage: P.get_hook(1)
|
142
|
+
2
|
143
|
+
"""
|
144
|
+
return self._hooks[elmt]
|
145
|
+
|
146
|
+
def get_hooks(self):
|
147
|
+
r"""
|
148
|
+
Return all the hook lengths as a dictionary.
|
149
|
+
|
150
|
+
EXAMPLES::
|
151
|
+
|
152
|
+
sage: from sage.combinat.posets.d_complete import DCompletePoset
|
153
|
+
sage: P = DCompletePoset(DiGraph({0: [1, 2], 1: [3], 2: [3], 3: []}))
|
154
|
+
sage: P.get_hooks()
|
155
|
+
{0: 1, 1: 2, 2: 2, 3: 3}
|
156
|
+
sage: from sage.combinat.posets.poset_examples import Posets
|
157
|
+
sage: YDP321 = Posets.YoungDiagramPoset(Partition([3,2,1]))
|
158
|
+
sage: P = DCompletePoset(YDP321._hasse_diagram.reverse())
|
159
|
+
sage: P.get_hooks()
|
160
|
+
{0: 5, 1: 3, 2: 1, 3: 3, 4: 1, 5: 1}
|
161
|
+
"""
|
162
|
+
return dict(self._hooks)
|
163
|
+
|
164
|
+
def hook_product(self):
|
165
|
+
r"""
|
166
|
+
Return the hook product for the poset.
|
167
|
+
|
168
|
+
TESTS::
|
169
|
+
|
170
|
+
sage: from sage.combinat.posets.d_complete import DCompletePoset
|
171
|
+
sage: P = DCompletePoset(DiGraph({0: [1, 2], 1: [3], 2: [3], 3: []}))
|
172
|
+
sage: P.hook_product()
|
173
|
+
12
|
174
|
+
sage: P = DCompletePoset(posets.YoungDiagramPoset(Partition([3,2,1]),
|
175
|
+
....: dual=True))
|
176
|
+
sage: P.hook_product()
|
177
|
+
45
|
178
|
+
"""
|
179
|
+
if not self._hasse_diagram:
|
180
|
+
return ZZ.one()
|
181
|
+
|
182
|
+
return ZZ(prod(self._hooks.values()))
|
@@ -0,0 +1,273 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
# sage.doctest: needs sage.modules
|
3
|
+
r"""
|
4
|
+
Elements of posets, lattices, semilattices, etc.
|
5
|
+
"""
|
6
|
+
# ****************************************************************************
|
7
|
+
# Copyright (C) 2008 Peter Jipsen <jipsen@chapman.edu>,
|
8
|
+
# Franco Saliola <saliola@gmail.com>
|
9
|
+
#
|
10
|
+
# Distributed under the terms of the GNU General Public License (GPL)
|
11
|
+
#
|
12
|
+
# This code is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
15
|
+
# General Public License for more details.
|
16
|
+
#
|
17
|
+
# The full text of the GPL is available at:
|
18
|
+
#
|
19
|
+
# https://www.gnu.org/licenses/
|
20
|
+
# ****************************************************************************
|
21
|
+
from sage.structure.element import Element
|
22
|
+
from sage.structure.element import have_same_parent
|
23
|
+
|
24
|
+
|
25
|
+
class PosetElement(Element):
|
26
|
+
|
27
|
+
def __init__(self, poset, element, vertex) -> None:
|
28
|
+
r"""
|
29
|
+
Establish the parent-child relationship between ``poset``
|
30
|
+
and ``element``, where ``element`` is associated to the
|
31
|
+
vertex ``vertex`` of the Hasse diagram of the poset.
|
32
|
+
|
33
|
+
INPUT:
|
34
|
+
|
35
|
+
- ``poset`` -- a poset object
|
36
|
+
|
37
|
+
- ``element`` -- any object
|
38
|
+
|
39
|
+
- ``vertex`` -- a vertex of the Hasse diagram of the poset
|
40
|
+
|
41
|
+
TESTS::
|
42
|
+
|
43
|
+
sage: from sage.combinat.posets.elements import PosetElement
|
44
|
+
sage: P = Poset([[1,2],[4],[3],[4],[]], facade = False)
|
45
|
+
sage: e = P(0)
|
46
|
+
sage: e.parent() is P
|
47
|
+
True
|
48
|
+
sage: TestSuite(e).run()
|
49
|
+
"""
|
50
|
+
Element.__init__(self, poset)
|
51
|
+
if isinstance(element, self.parent().element_class):
|
52
|
+
self.element = element.element
|
53
|
+
else:
|
54
|
+
self.element = element
|
55
|
+
self.vertex = vertex
|
56
|
+
|
57
|
+
def __hash__(self):
|
58
|
+
r"""
|
59
|
+
TESTS::
|
60
|
+
|
61
|
+
sage: P = Poset([[1,2],[4],[3],[4],[]], facade = False)
|
62
|
+
sage: e = P(0)
|
63
|
+
sage: hash(e)
|
64
|
+
0
|
65
|
+
"""
|
66
|
+
return hash(self.element)
|
67
|
+
|
68
|
+
def _repr_(self):
|
69
|
+
"""
|
70
|
+
TESTS::
|
71
|
+
|
72
|
+
sage: Poset([[1,2],[4],[3],[4],[]], facade = False)(0)._repr_()
|
73
|
+
'0'
|
74
|
+
"""
|
75
|
+
return "%s" % str(self.element)
|
76
|
+
|
77
|
+
def _latex_(self):
|
78
|
+
r"""
|
79
|
+
Return the latex code of the poset element.
|
80
|
+
|
81
|
+
EXAMPLES::
|
82
|
+
|
83
|
+
sage: m = matrix(2, [1,2,3,4])
|
84
|
+
sage: m.set_immutable()
|
85
|
+
sage: P = Poset(([m],[]), facade=False)
|
86
|
+
sage: [e] = P
|
87
|
+
sage: type(e)
|
88
|
+
<class 'sage.combinat.posets.posets.FinitePoset_with_category.element_class'>
|
89
|
+
sage: latex(e) #indirect doctest
|
90
|
+
\left(\begin{array}{rr}
|
91
|
+
1 & 2 \\
|
92
|
+
3 & 4
|
93
|
+
\end{array}\right)
|
94
|
+
"""
|
95
|
+
from sage.misc.latex import latex
|
96
|
+
return latex(self.element)
|
97
|
+
|
98
|
+
def __eq__(self, other):
|
99
|
+
"""
|
100
|
+
TESTS::
|
101
|
+
|
102
|
+
sage: P = Poset([["a","b"],["d"],["c"],["d"],[]], facade = False)
|
103
|
+
sage: Q = Poset([["a","b"],["d"],["c"],[],[]], facade = False)
|
104
|
+
sage: P(0).__eq__(P(4))
|
105
|
+
False
|
106
|
+
sage: from sage.combinat.posets.elements import PosetElement
|
107
|
+
sage: PosetElement(P,0,"c") == PosetElement(P,0,"c")
|
108
|
+
True
|
109
|
+
sage: PosetElement(P,0,"c") == PosetElement(Q,0,"c")
|
110
|
+
False
|
111
|
+
sage: PosetElement(P,0,"b") == PosetElement(P,0,"c")
|
112
|
+
False
|
113
|
+
|
114
|
+
.. warning:: as an optimization, this only compares the parent
|
115
|
+
and vertex, using the invariant that, in a proper poset
|
116
|
+
element, ``self.element == other.element`` if and only
|
117
|
+
``self.vertex == other.vertex``::
|
118
|
+
|
119
|
+
sage: PosetElement(P,1,"c") == PosetElement(P,0,"c")
|
120
|
+
True
|
121
|
+
|
122
|
+
Test that :issue:`12351` is fixed::
|
123
|
+
|
124
|
+
sage: P(0) == int(0)
|
125
|
+
False
|
126
|
+
"""
|
127
|
+
# This should instead exploit unique representation, using
|
128
|
+
# self is other, or best inherit __eq__ from there. But there
|
129
|
+
# are issues around pickling and rich comparison functions.
|
130
|
+
return have_same_parent(self, other) \
|
131
|
+
and self.vertex == other.vertex
|
132
|
+
|
133
|
+
def __ne__(self, other):
|
134
|
+
r"""
|
135
|
+
TESTS::
|
136
|
+
|
137
|
+
sage: P = Poset([[1,2],[4],[3],[4],[]])
|
138
|
+
sage: P = Poset([["a","b"],["d"],["c"],["d"],[]])
|
139
|
+
sage: P(0).__ne__(P(4))
|
140
|
+
True
|
141
|
+
sage: from sage.combinat.posets.elements import PosetElement
|
142
|
+
sage: PosetElement(P,0,"c") != PosetElement(P,0,"c")
|
143
|
+
False
|
144
|
+
sage: PosetElement(P,0,"b") != PosetElement(P,0,"c")
|
145
|
+
True
|
146
|
+
|
147
|
+
For this one, see comment in :meth:`__eq__`::
|
148
|
+
|
149
|
+
sage: PosetElement(P,1,"c") != PosetElement(P,0,"c")
|
150
|
+
False
|
151
|
+
"""
|
152
|
+
return not self == other
|
153
|
+
|
154
|
+
def _cmp(self, other):
|
155
|
+
"""
|
156
|
+
TESTS::
|
157
|
+
|
158
|
+
sage: P = Poset([[1,2],[4],[3],[4],[]], facade = False)
|
159
|
+
sage: P(0)._cmp(P(4))
|
160
|
+
-1
|
161
|
+
sage: P(4)._cmp(P(0))
|
162
|
+
1
|
163
|
+
sage: P(0)._cmp(P(0))
|
164
|
+
0
|
165
|
+
sage: P(1)._cmp(P(2))
|
166
|
+
"""
|
167
|
+
return self.parent().compare_elements(self, other)
|
168
|
+
|
169
|
+
def __lt__(self, other):
|
170
|
+
"""
|
171
|
+
TESTS::
|
172
|
+
|
173
|
+
sage: dag = DiGraph({0:[2,3], 1:[3,4], 2:[5], 3:[5], 4:[5]})
|
174
|
+
sage: P = Poset(dag, facade = False)
|
175
|
+
sage: P(0) < P(1)
|
176
|
+
False
|
177
|
+
sage: P(4) < P(1)
|
178
|
+
False
|
179
|
+
sage: P(0) < P(0)
|
180
|
+
False
|
181
|
+
"""
|
182
|
+
return self._cmp(other) == -1 or False
|
183
|
+
|
184
|
+
def __le__(self, other):
|
185
|
+
"""
|
186
|
+
TESTS::
|
187
|
+
|
188
|
+
sage: dag = DiGraph({0:[2,3], 1:[3,4], 2:[5], 3:[5], 4:[5]})
|
189
|
+
sage: P = Poset(dag, facade = False)
|
190
|
+
sage: P(1) <= P(0)
|
191
|
+
False
|
192
|
+
sage: P(0) <= P(1)
|
193
|
+
False
|
194
|
+
sage: P(0) <= P(3)
|
195
|
+
True
|
196
|
+
sage: P(0) <= P(0)
|
197
|
+
True
|
198
|
+
"""
|
199
|
+
return self == other or self._cmp(other) == -1 or False
|
200
|
+
|
201
|
+
def __gt__(self, other):
|
202
|
+
"""
|
203
|
+
TESTS::
|
204
|
+
|
205
|
+
sage: dag = DiGraph({0:[2,3], 1:[3,4], 2:[5], 3:[5], 4:[5]})
|
206
|
+
sage: P = Poset(dag)
|
207
|
+
sage: P(0).__gt__(P(5))
|
208
|
+
False
|
209
|
+
sage: P(5).__gt__(P(0))
|
210
|
+
True
|
211
|
+
sage: P(0).__gt__(P(0))
|
212
|
+
False
|
213
|
+
"""
|
214
|
+
return self._cmp(other) == 1 or False
|
215
|
+
|
216
|
+
def __ge__(self, other):
|
217
|
+
"""
|
218
|
+
TESTS::
|
219
|
+
|
220
|
+
sage: dag = DiGraph({0:[2,3], 1:[3,4], 2:[5], 3:[5], 4:[5]})
|
221
|
+
sage: P = Poset(dag)
|
222
|
+
sage: P(0).__ge__(P(5))
|
223
|
+
False
|
224
|
+
sage: P(5).__ge__(P(0))
|
225
|
+
True
|
226
|
+
sage: P(0).__ge__(P(0))
|
227
|
+
True
|
228
|
+
"""
|
229
|
+
return self == other or self._cmp(other) == 1 or False
|
230
|
+
|
231
|
+
|
232
|
+
class MeetSemilatticeElement(PosetElement):
|
233
|
+
def __mul__(self, other):
|
234
|
+
r"""
|
235
|
+
Return the meet of ``self`` and ``other`` in the lattice.
|
236
|
+
|
237
|
+
EXAMPLES::
|
238
|
+
|
239
|
+
sage: D = posets.DiamondPoset(5, facade=False)
|
240
|
+
sage: D(1) * D(2)
|
241
|
+
0
|
242
|
+
sage: D(1) * D(1)
|
243
|
+
1
|
244
|
+
sage: D(1) * D(0)
|
245
|
+
0
|
246
|
+
sage: D(1) * D(4)
|
247
|
+
1
|
248
|
+
"""
|
249
|
+
return self.parent().meet(self, other)
|
250
|
+
|
251
|
+
|
252
|
+
class JoinSemilatticeElement(PosetElement):
|
253
|
+
def __add__(self, other):
|
254
|
+
r"""
|
255
|
+
Return the join of ``self`` and ``other`` in the lattice.
|
256
|
+
|
257
|
+
EXAMPLES::
|
258
|
+
|
259
|
+
sage: D = posets.DiamondPoset(5,facade=False)
|
260
|
+
sage: D(1) + D(2)
|
261
|
+
4
|
262
|
+
sage: D(1) + D(1)
|
263
|
+
1
|
264
|
+
sage: D(1) + D(4)
|
265
|
+
4
|
266
|
+
sage: D(1) + D(0)
|
267
|
+
1
|
268
|
+
"""
|
269
|
+
return self.parent().join(self, other)
|
270
|
+
|
271
|
+
|
272
|
+
class LatticePosetElement(MeetSemilatticeElement, JoinSemilatticeElement):
|
273
|
+
pass
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
r"""
|
3
|
+
Forest posets
|
4
|
+
|
5
|
+
AUTHORS:
|
6
|
+
|
7
|
+
- Stefan Grosser (06-2020): initial implementation
|
8
|
+
"""
|
9
|
+
|
10
|
+
# ****************************************************************************
|
11
|
+
# Copyright (C) 2020 Stefan Grosser <stefan.grosser1@gmail.com>
|
12
|
+
#
|
13
|
+
# This program is free software: you can redistribute it and/or modify
|
14
|
+
# it under the terms of the GNU General Public License as published by
|
15
|
+
# the Free Software Foundation, either version 2 of the License, or
|
16
|
+
# (at your option) any later version.
|
17
|
+
# https://www.gnu.org/licenses/
|
18
|
+
# ****************************************************************************
|
19
|
+
|
20
|
+
from sage.combinat.posets.posets import FinitePoset
|
21
|
+
from sage.combinat.posets.linear_extensions import LinearExtensionsOfForest
|
22
|
+
|
23
|
+
|
24
|
+
class ForestPoset(FinitePoset):
|
25
|
+
r"""
|
26
|
+
A forest poset is a poset where the underlying Hasse diagram and is
|
27
|
+
directed acyclic graph.
|
28
|
+
"""
|
29
|
+
_lin_ext_type = LinearExtensionsOfForest
|
30
|
+
_desc = 'Finite forest poset'
|
Binary file
|
@@ -0,0 +1,174 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
# cython: binding=True
|
3
|
+
r"""
|
4
|
+
Some fast computations for finite posets
|
5
|
+
"""
|
6
|
+
# ****************************************************************************
|
7
|
+
# Copyright (C) 2020 Frédéric Chapoton <chapoton@unistra.fr>
|
8
|
+
#
|
9
|
+
# This program is free software: you can redistribute it and/or modify
|
10
|
+
# it under the terms of the GNU General Public License as published by
|
11
|
+
# the Free Software Foundation, either version 2 of the License, or
|
12
|
+
# (at your option) any later version.
|
13
|
+
# https://www.gnu.org/licenses/
|
14
|
+
# ****************************************************************************
|
15
|
+
from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets
|
16
|
+
from sage.misc.lazy_import import LazyImport
|
17
|
+
from sage.sets.recursively_enumerated_set import RecursivelyEnumeratedSet_forest
|
18
|
+
|
19
|
+
coxeter_matrix_fast = LazyImport('sage.combinat.posets.hasse_cython_flint', 'coxeter_matrix_fast',
|
20
|
+
deprecation=35741)
|
21
|
+
moebius_matrix_fast = LazyImport('sage.combinat.posets.hasse_cython_flint', 'moebius_matrix_fast',
|
22
|
+
deprecation=35741)
|
23
|
+
|
24
|
+
|
25
|
+
class IncreasingChains(RecursivelyEnumeratedSet_forest):
|
26
|
+
r"""
|
27
|
+
The enumerated set of increasing chains.
|
28
|
+
|
29
|
+
INPUT:
|
30
|
+
|
31
|
+
- ``positions`` -- list of sets of integers describing the poset,
|
32
|
+
as given by the lazy attribute ``_leq_storage`` of Hasse diagrams
|
33
|
+
|
34
|
+
- ``element_constructor`` -- used to determine the type of chains,
|
35
|
+
for example :class:`list` or :class:`tuple`
|
36
|
+
|
37
|
+
- ``exclude`` -- list of integers that should not belong to the chains
|
38
|
+
|
39
|
+
- ``conversion`` -- (optional) list of elements of the poset
|
40
|
+
|
41
|
+
If ``conversion`` is provided, it is used to convert chain elements
|
42
|
+
to elements of this list.
|
43
|
+
|
44
|
+
EXAMPLES::
|
45
|
+
|
46
|
+
sage: from sage.combinat.posets.hasse_cython import IncreasingChains
|
47
|
+
sage: D = IncreasingChains([{0,1},{1}], list, []); D
|
48
|
+
An enumerated set with a forest structure
|
49
|
+
sage: D.cardinality()
|
50
|
+
4
|
51
|
+
sage: list(D)
|
52
|
+
[[], [0], [0, 1], [1]]
|
53
|
+
"""
|
54
|
+
def __init__(self, list positions, element_constructor,
|
55
|
+
list exclude, conversion=None):
|
56
|
+
"""
|
57
|
+
The enumerated set of increasing chains.
|
58
|
+
|
59
|
+
TESTS::
|
60
|
+
|
61
|
+
sage: from sage.combinat.posets.hasse_cython import IncreasingChains
|
62
|
+
sage: D = IncreasingChains([{0,1},{1}], list, [])
|
63
|
+
sage: TestSuite(D).run(skip='_test_pickling')
|
64
|
+
"""
|
65
|
+
cdef int i
|
66
|
+
cdef Py_ssize_t n = len(positions)
|
67
|
+
self._n = n
|
68
|
+
if exclude is not None:
|
69
|
+
self._greater_than = [gti.difference(exclude) for gti in positions]
|
70
|
+
self._vertices = [u for u in range(n) if u not in exclude]
|
71
|
+
else:
|
72
|
+
self._greater_than = positions
|
73
|
+
self._vertices = list(range(n))
|
74
|
+
|
75
|
+
self._constructor = element_constructor
|
76
|
+
self._conversion = conversion
|
77
|
+
if conversion is not None:
|
78
|
+
self._from_poset = {elt: i for i, elt in enumerate(conversion)}
|
79
|
+
|
80
|
+
self._roots = (tuple(),)
|
81
|
+
|
82
|
+
RecursivelyEnumeratedSet_forest.__init__(self, algorithm='depth',
|
83
|
+
category=FiniteEnumeratedSets())
|
84
|
+
|
85
|
+
def __contains__(self, tup):
|
86
|
+
"""
|
87
|
+
Membership testing.
|
88
|
+
|
89
|
+
If ``conversion`` was provided, it first converts elements of ``tup``
|
90
|
+
to integers.
|
91
|
+
|
92
|
+
EXAMPLES::
|
93
|
+
|
94
|
+
sage: from sage.combinat.posets.hasse_cython import IncreasingChains
|
95
|
+
sage: D = IncreasingChains([{0,1},{1}], list, [])
|
96
|
+
sage: all(x in D for x in D)
|
97
|
+
True
|
98
|
+
sage: [2] in D
|
99
|
+
False
|
100
|
+
sage: [1,1] in D
|
101
|
+
False
|
102
|
+
|
103
|
+
sage: P = Poset({'a':['b'],'b':[]})
|
104
|
+
sage: ['a'] in P.chains()
|
105
|
+
True
|
106
|
+
|
107
|
+
TESTS::
|
108
|
+
|
109
|
+
sage: from sage.combinat.posets.hasse_cython import IncreasingChains
|
110
|
+
sage: D = IncreasingChains([{0,1},{1}], list, [])
|
111
|
+
sage: all(tuple(x) in D for x in D)
|
112
|
+
True
|
113
|
+
"""
|
114
|
+
cdef int k
|
115
|
+
cdef Py_ssize_t i, x, y
|
116
|
+
if not tup:
|
117
|
+
return True
|
118
|
+
if self._conversion is not None:
|
119
|
+
tup = [self._from_poset[elt] for elt in tup]
|
120
|
+
if any(not(0 <= i < self._n) for i in tup):
|
121
|
+
return False
|
122
|
+
y = tup[0]
|
123
|
+
for k in range(1, len(tup)):
|
124
|
+
x = y
|
125
|
+
y = tup[k]
|
126
|
+
if x == y or y not in self._greater_than[x]:
|
127
|
+
return False
|
128
|
+
return True
|
129
|
+
|
130
|
+
def post_process(self, chain):
|
131
|
+
"""
|
132
|
+
Create a chain from the internal object.
|
133
|
+
|
134
|
+
If ``conversion`` was provided, it first converts elements of the
|
135
|
+
chain to elements of this list.
|
136
|
+
|
137
|
+
Then the given ``element_constructor`` is applied to the chain.
|
138
|
+
|
139
|
+
EXAMPLES::
|
140
|
+
|
141
|
+
sage: from sage.combinat.posets.hasse_cython import IncreasingChains
|
142
|
+
sage: D = IncreasingChains([{0,1},{1}], list, [])
|
143
|
+
sage: D.post_process((0,1))
|
144
|
+
[0, 1]
|
145
|
+
|
146
|
+
sage: P = Poset({'a':['b'],'b':[]})
|
147
|
+
sage: list(P.chains())
|
148
|
+
[[], ['a'], ['a', 'b'], ['b']]
|
149
|
+
"""
|
150
|
+
cdef Py_ssize_t i
|
151
|
+
if self._conversion is not None:
|
152
|
+
return self._constructor(self._conversion[i] for i in chain)
|
153
|
+
return self._constructor(chain)
|
154
|
+
|
155
|
+
def children(self, chain):
|
156
|
+
"""
|
157
|
+
Return the children of a chain, by adding one largest element.
|
158
|
+
|
159
|
+
EXAMPLES::
|
160
|
+
|
161
|
+
sage: from sage.combinat.posets.hasse_cython import IncreasingChains
|
162
|
+
sage: D = IncreasingChains([{0,1},{1}], list, [])
|
163
|
+
sage: D.children((0,))
|
164
|
+
[(0, 1)]
|
165
|
+
|
166
|
+
sage: P = Poset({'a':['b'],'b':[]})
|
167
|
+
sage: next(iter(P.chains()))
|
168
|
+
[]
|
169
|
+
"""
|
170
|
+
cdef Py_ssize_t x, y
|
171
|
+
if not chain:
|
172
|
+
return [(x,) for x in self._vertices]
|
173
|
+
x = chain[-1]
|
174
|
+
return [chain + (y,) for y in self._greater_than[x] if x != y]
|