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
Binary file
|
@@ -0,0 +1,604 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
# cython: binding=True
|
3
|
+
r"""
|
4
|
+
Weakly chordal graphs
|
5
|
+
|
6
|
+
This module deals with everything related to weakly chordal graphs. It currently
|
7
|
+
contains the following functions:
|
8
|
+
|
9
|
+
.. csv-table::
|
10
|
+
:class: contentstable
|
11
|
+
:widths: 30, 70
|
12
|
+
:delim: |
|
13
|
+
|
14
|
+
:meth:`~sage.graphs.weakly_chordal.is_long_hole_free` | Test whether ``g`` contains an induced cycle of length at least 5.
|
15
|
+
:meth:`~sage.graphs.weakly_chordal.is_long_antihole_free` | Test whether ``g`` contains an induced anticycle of length at least 5.
|
16
|
+
:meth:`~sage.graphs.weakly_chordal.is_weakly_chordal` | Test whether ``g`` is weakly chordal.
|
17
|
+
|
18
|
+
Author:
|
19
|
+
|
20
|
+
- Birk Eisermann (initial implementation)
|
21
|
+
- Nathann Cohen (some doc and optimization)
|
22
|
+
- David Coudert (remove recursion)
|
23
|
+
|
24
|
+
|
25
|
+
Methods
|
26
|
+
-------
|
27
|
+
"""
|
28
|
+
|
29
|
+
# ****************************************************************************
|
30
|
+
# Copyright (c) 2012 Birk Eisermann <eisermbi@fastmail.fm>
|
31
|
+
#
|
32
|
+
# This program is free software: you can redistribute it and/or modify
|
33
|
+
# it under the terms of the GNU General Public License as published by
|
34
|
+
# the Free Software Foundation, either version 2 of the License, or
|
35
|
+
# (at your option) any later version.
|
36
|
+
# https://www.gnu.org/licenses/
|
37
|
+
# ****************************************************************************
|
38
|
+
|
39
|
+
from memory_allocator cimport MemoryAllocator
|
40
|
+
from sage.data_structures.bitset_base cimport *
|
41
|
+
from sage.graphs.base.static_sparse_backend cimport StaticSparseCGraph
|
42
|
+
from sage.graphs.base.static_sparse_backend cimport StaticSparseBackend
|
43
|
+
from sage.graphs.base.static_sparse_graph cimport short_digraph
|
44
|
+
from sage.graphs.base.static_sparse_graph cimport init_short_digraph
|
45
|
+
from sage.graphs.base.static_sparse_graph cimport free_short_digraph
|
46
|
+
from sage.graphs.base.static_sparse_graph cimport out_degree
|
47
|
+
|
48
|
+
|
49
|
+
cdef inline int has_edge(bitset_t bs, int u, int v, int n) noexcept:
|
50
|
+
return bitset_in(bs, u * n + v)
|
51
|
+
|
52
|
+
|
53
|
+
cdef inline is_long_hole_free_process(g, short_digraph sd, bitset_t dense_graph,
|
54
|
+
list id_label, int* path, int* InPath,
|
55
|
+
int* neighbor_index, set VisitedP3,
|
56
|
+
bint certificate,
|
57
|
+
int a, int b, int c, int n):
|
58
|
+
"""
|
59
|
+
This method is part of method ``is_long_hole_free``.
|
60
|
+
|
61
|
+
EXAMPLES::
|
62
|
+
|
63
|
+
sage: g = graphs.PetersenGraph()
|
64
|
+
sage: g.is_long_hole_free()
|
65
|
+
False
|
66
|
+
"""
|
67
|
+
cdef int d, u, v, i
|
68
|
+
cdef Py_ssize_t path_top = 2
|
69
|
+
cdef list C
|
70
|
+
cdef dict C_index
|
71
|
+
|
72
|
+
path[2] = c
|
73
|
+
InPath[c] = path_top # c is the (i+1)-th vertex at position i
|
74
|
+
neighbor_index[c] = 0
|
75
|
+
VisitedP3.add((a, b, c))
|
76
|
+
VisitedP3.add((c, b, a))
|
77
|
+
|
78
|
+
while path_top >= 2:
|
79
|
+
a = path[path_top - 2]
|
80
|
+
b = path[path_top - 1]
|
81
|
+
c = path[path_top]
|
82
|
+
|
83
|
+
if neighbor_index[c] < out_degree(sd, c):
|
84
|
+
d = sd.neighbors[c][neighbor_index[c]]
|
85
|
+
neighbor_index[c] += 1
|
86
|
+
if not has_edge(dense_graph, d, a, n) and not has_edge(dense_graph, d, b, n):
|
87
|
+
# a-b-c-d form an induced path P_4
|
88
|
+
|
89
|
+
if InPath[d] != -1:
|
90
|
+
# d is already contained in InPath
|
91
|
+
# HOLE FOUND !!!
|
92
|
+
if certificate:
|
93
|
+
# We extract the hole and relabel it on-the-fly with the
|
94
|
+
# vertices' real name
|
95
|
+
C = [id_label[path[i]] for i in range(InPath[d], path_top + 1)]
|
96
|
+
C_index = {label: i for i, label in enumerate(C)}
|
97
|
+
|
98
|
+
# At this step C[0]C[1]..... is a cycle such that any 4
|
99
|
+
# consecutive vertices induce a P4. C may not be an
|
100
|
+
# induced cycle, so we extract one from it.
|
101
|
+
|
102
|
+
# To do so, we look for the *shortest* edge C[i]C[j]
|
103
|
+
# between two nonconsecutive vertices of C, where the
|
104
|
+
# length is the difference |i-j|.
|
105
|
+
#
|
106
|
+
# C[i]...C[j] is necessarily an induced cycle.
|
107
|
+
|
108
|
+
gg = g.subgraph(C, immutable=False)
|
109
|
+
gg.delete_edges(zip(C[:-1], C[1:]))
|
110
|
+
|
111
|
+
def dist(X):
|
112
|
+
return abs(C_index[X[0]] - C_index[X[1]])
|
113
|
+
|
114
|
+
label_u, label_v = min(gg.edge_iterator(labels=False), key=dist)
|
115
|
+
u, v = C_index[label_u], C_index[label_v]
|
116
|
+
|
117
|
+
# Return the answer
|
118
|
+
return False, g.subgraph(C[min(u, v): max(u, v) + 1])
|
119
|
+
|
120
|
+
else:
|
121
|
+
return False, None
|
122
|
+
|
123
|
+
elif (b, c, d) not in VisitedP3:
|
124
|
+
# search for another P_4
|
125
|
+
path_top += 1
|
126
|
+
path[path_top] = d
|
127
|
+
InPath[d] = path_top
|
128
|
+
neighbor_index[d] = 0
|
129
|
+
VisitedP3.add((b, c, d))
|
130
|
+
VisitedP3.add((d, c, b))
|
131
|
+
|
132
|
+
else:
|
133
|
+
# We are done with c. We trackback
|
134
|
+
path_top -= 1
|
135
|
+
InPath[c] = -1
|
136
|
+
|
137
|
+
return True, []
|
138
|
+
|
139
|
+
|
140
|
+
def is_long_hole_free(g, certificate=False):
|
141
|
+
r"""
|
142
|
+
Test whether ``g`` contains an induced cycle of length at least 5.
|
143
|
+
|
144
|
+
INPUT:
|
145
|
+
|
146
|
+
- ``certificate`` -- boolean (default: ``False``)
|
147
|
+
|
148
|
+
Whether to return a certificate. When ``certificate = True``, then
|
149
|
+
the function returns
|
150
|
+
|
151
|
+
* ``(True, [])`` if ``g`` does not contain such a cycle.
|
152
|
+
For this case, it is not known how to provide a certificate.
|
153
|
+
* ``(False, Hole)`` if ``g`` contains an induced cycle of length at
|
154
|
+
least 5. ``Hole`` returns this cycle.
|
155
|
+
|
156
|
+
If ``certificate = False``, the function returns just ``True`` or
|
157
|
+
``False`` accordingly.
|
158
|
+
|
159
|
+
ALGORITHM:
|
160
|
+
|
161
|
+
This algorithm tries to find a cycle in the graph of all induced `P_4` of
|
162
|
+
`g`, where two copies `P` and `P'` of `P_4` are adjacent if there exists a
|
163
|
+
(not necessarily induced) copy of `P_5=u_1u_2u_3u_4u_5` such that
|
164
|
+
`P=u_1u_2u_3u_4` and `P'=u_2u_3u_4u_5`.
|
165
|
+
|
166
|
+
This is done through a depth-first-search. For efficiency, the auxiliary
|
167
|
+
graph is constructed on-the-fly and never stored in memory.
|
168
|
+
|
169
|
+
The run time of this algorithm is `O(n+m^2)` for ``SparseGraph`` and
|
170
|
+
`O(n^2 + m^2)` for ``DenseGraph`` [NP2007]_ (where `n` is the number of
|
171
|
+
vertices and `m` is the number of edges of the graph).
|
172
|
+
|
173
|
+
EXAMPLES:
|
174
|
+
|
175
|
+
The Petersen Graph contains a hole::
|
176
|
+
|
177
|
+
sage: g = graphs.PetersenGraph()
|
178
|
+
sage: g.is_long_hole_free()
|
179
|
+
False
|
180
|
+
|
181
|
+
The following graph contains a hole, which we want to display::
|
182
|
+
|
183
|
+
sage: g = graphs.FlowerSnark()
|
184
|
+
sage: r,h = g.is_long_hole_free(certificate=True)
|
185
|
+
sage: r
|
186
|
+
False
|
187
|
+
sage: Graph(h).is_isomorphic(graphs.CycleGraph(h.order()))
|
188
|
+
True
|
189
|
+
|
190
|
+
TESTS:
|
191
|
+
|
192
|
+
Another graph with vertices 2, ..., 8, 10::
|
193
|
+
|
194
|
+
sage: g = Graph({2:[3,8],3:[2,4],4:[3,8,10],5:[6,10],6:[5,7],7:[6,8],8:[2,4,7,10],10:[4,5,8]})
|
195
|
+
sage: r,hole = g.is_long_hole_free(certificate=True)
|
196
|
+
sage: r
|
197
|
+
False
|
198
|
+
sage: hole
|
199
|
+
Subgraph of (): Graph on 5 vertices
|
200
|
+
sage: hole.is_isomorphic(graphs.CycleGraph(hole.order()))
|
201
|
+
True
|
202
|
+
|
203
|
+
sage: graphs.EmptyGraph().is_long_hole_free()
|
204
|
+
True
|
205
|
+
|
206
|
+
Immutable graphs::
|
207
|
+
|
208
|
+
sage: G = graphs.RandomGNP(10, .7)
|
209
|
+
sage: G._backend
|
210
|
+
<sage.graphs.base.sparse_graph.SparseGraphBackend ...>
|
211
|
+
sage: H = Graph(G, immutable=True)
|
212
|
+
sage: H._backend
|
213
|
+
<sage.graphs.base.static_sparse_backend.StaticSparseBackend ...>
|
214
|
+
sage: G.is_long_hole_free() == H.is_long_hole_free()
|
215
|
+
True
|
216
|
+
"""
|
217
|
+
g._scream_if_not_simple()
|
218
|
+
|
219
|
+
if g.order() < 5:
|
220
|
+
return (True, []) if certificate else True
|
221
|
+
|
222
|
+
cdef int u, v, w, vv, ww
|
223
|
+
|
224
|
+
# Make a copy of the graph as a short_digraph. This data structure is well
|
225
|
+
# documented in the module sage.graphs.base.static_sparse_graph.
|
226
|
+
# Vertices are relabeled in 0..n-1
|
227
|
+
cdef int n = g.order()
|
228
|
+
cdef list id_label
|
229
|
+
cdef StaticSparseCGraph cg
|
230
|
+
cdef short_digraph sd
|
231
|
+
if isinstance(g, StaticSparseBackend):
|
232
|
+
cg = <StaticSparseCGraph> g._cg
|
233
|
+
sd = <short_digraph> cg.g
|
234
|
+
id_label = cg._vertex_to_labels
|
235
|
+
else:
|
236
|
+
id_label = list(g)
|
237
|
+
init_short_digraph(sd, g, edge_labelled=False, vertex_list=id_label)
|
238
|
+
|
239
|
+
# Make a dense copy of the graph for quick adjacency tests
|
240
|
+
cdef bitset_t dense_graph
|
241
|
+
bitset_init(dense_graph, n * n)
|
242
|
+
bitset_set_first_n(dense_graph, 0)
|
243
|
+
for u in range(n):
|
244
|
+
for vv in range(out_degree(sd, u)):
|
245
|
+
v = sd.neighbors[u][vv]
|
246
|
+
bitset_add(dense_graph, u * n + v)
|
247
|
+
bitset_add(dense_graph, v * n + u)
|
248
|
+
|
249
|
+
# Allocate some data structures
|
250
|
+
cdef MemoryAllocator mem = MemoryAllocator()
|
251
|
+
cdef int* path = <int*> mem.allocarray(n, sizeof(int))
|
252
|
+
cdef int* InPath = <int*> mem.allocarray(n, sizeof(int))
|
253
|
+
for u in range(n):
|
254
|
+
InPath[u] = -1
|
255
|
+
|
256
|
+
cdef int* neighbor_index = <int*> mem.allocarray(n, sizeof(int))
|
257
|
+
|
258
|
+
cdef set VisitedP3 = set() # stores triples (u,v,w) which represent visited paths of length 3
|
259
|
+
|
260
|
+
# main algorithm
|
261
|
+
# For all triples u,v,w of vertices such that uvw is a P_3
|
262
|
+
for u in range(n):
|
263
|
+
# u is the first vertex of the path, at position 0
|
264
|
+
path[0] = u
|
265
|
+
InPath[u] = 0
|
266
|
+
for vv in range(out_degree(sd, u)):
|
267
|
+
v = sd.neighbors[u][vv]
|
268
|
+
# v is the second vertex of the path, at position 1
|
269
|
+
path[1] = v
|
270
|
+
InPath[v] = 1
|
271
|
+
for ww in range(out_degree(sd, v)):
|
272
|
+
w = sd.neighbors[v][ww]
|
273
|
+
if u != w and not has_edge(dense_graph, u, w, n) and (u, v, w) not in VisitedP3:
|
274
|
+
|
275
|
+
res, hole = is_long_hole_free_process(g, sd, dense_graph, id_label,
|
276
|
+
path, InPath, neighbor_index, VisitedP3,
|
277
|
+
certificate, u, v, w, n)
|
278
|
+
|
279
|
+
if not res:
|
280
|
+
# We release memory before returning the result
|
281
|
+
if not isinstance(g, StaticSparseBackend):
|
282
|
+
free_short_digraph(sd)
|
283
|
+
bitset_free(dense_graph)
|
284
|
+
|
285
|
+
if certificate:
|
286
|
+
return False, hole
|
287
|
+
return False
|
288
|
+
|
289
|
+
InPath[v] = -1
|
290
|
+
InPath[u] = -1
|
291
|
+
|
292
|
+
# Release memory
|
293
|
+
if not isinstance(g, StaticSparseBackend):
|
294
|
+
free_short_digraph(sd)
|
295
|
+
bitset_free(dense_graph)
|
296
|
+
|
297
|
+
if certificate:
|
298
|
+
return True, []
|
299
|
+
return True
|
300
|
+
|
301
|
+
|
302
|
+
cdef inline is_long_antihole_free_process(g, short_digraph sd, bitset_t dense_graph,
|
303
|
+
list id_label, int* path, int* InPath,
|
304
|
+
int* neighbor_index, set VisitedP3,
|
305
|
+
bint certificate,
|
306
|
+
int a, int b, int c, int n):
|
307
|
+
"""
|
308
|
+
This method is part of method ``is_long_antihole_free``.
|
309
|
+
|
310
|
+
EXAMPLES::
|
311
|
+
|
312
|
+
sage: g = graphs.PetersenGraph()
|
313
|
+
sage: g.is_long_antihole_free()
|
314
|
+
False
|
315
|
+
"""
|
316
|
+
cdef int d, u, v, i
|
317
|
+
cdef Py_ssize_t path_top = 2
|
318
|
+
cdef list C
|
319
|
+
cdef dict C_index
|
320
|
+
|
321
|
+
path[2] = c
|
322
|
+
InPath[c] = 2 # c is the (i+1)-th vertex at position i
|
323
|
+
neighbor_index[b] = 0
|
324
|
+
VisitedP3.add((a, b, c))
|
325
|
+
VisitedP3.add((c, b, a))
|
326
|
+
|
327
|
+
while path_top >= 2:
|
328
|
+
# We consider the antichain a,b,c
|
329
|
+
a = path[path_top - 2]
|
330
|
+
b = path[path_top - 1]
|
331
|
+
c = path[path_top]
|
332
|
+
|
333
|
+
if neighbor_index[b] < out_degree(sd, b):
|
334
|
+
d = sd.neighbors[b][neighbor_index[b]]
|
335
|
+
neighbor_index[b] += 1
|
336
|
+
if has_edge(dense_graph, d, a, n) and not has_edge(dense_graph, d, c, n):
|
337
|
+
# We found a neighbor of a and b that is not adjacent to c
|
338
|
+
if InPath[d] != -1:
|
339
|
+
if certificate:
|
340
|
+
# Calculation of induced cycle in complement
|
341
|
+
# Relabel it on-the-fly with the vertices' real name
|
342
|
+
C = [id_label[path[i]] for i in range(InPath[d], path_top + 1)]
|
343
|
+
C_index = {label: i for i, label in enumerate(C)}
|
344
|
+
|
345
|
+
# At this step C[0]C[1]..... is an anticycle such that
|
346
|
+
# any 4 consecutive vertices induce the complement of a
|
347
|
+
# P4. C may not be an induced anticycle, so we extract
|
348
|
+
# one from it.
|
349
|
+
|
350
|
+
# To do so, we look for the *shortest* nonedge C[i]C[j]
|
351
|
+
# between two nonconsecutive vertices of C, where the
|
352
|
+
# length is the difference |i-j|.
|
353
|
+
#
|
354
|
+
# C[i]...C[j] is necessarily an induced anticycle.
|
355
|
+
|
356
|
+
gg = g.subgraph(C, immutable=False).complement()
|
357
|
+
gg.delete_edges(zip(C[:-1], C[1:]))
|
358
|
+
|
359
|
+
def dist(X):
|
360
|
+
return abs(C_index[X[0]] - C_index[X[1]])
|
361
|
+
|
362
|
+
label_u, label_v = min(gg.edge_iterator(labels=False), key=dist)
|
363
|
+
u, v = C_index[label_u], C_index[label_v]
|
364
|
+
|
365
|
+
# Return the answer
|
366
|
+
return False, g.subgraph(C[min(u, v): max(u, v) + 1])
|
367
|
+
|
368
|
+
else:
|
369
|
+
return False, []
|
370
|
+
|
371
|
+
elif (b, c, d) not in VisitedP3:
|
372
|
+
path_top += 1
|
373
|
+
path[path_top] = d
|
374
|
+
InPath[d] = path_top
|
375
|
+
neighbor_index[c] = 0
|
376
|
+
VisitedP3.add((b, c, d))
|
377
|
+
VisitedP3.add((d, c, b))
|
378
|
+
|
379
|
+
else:
|
380
|
+
# We trackback
|
381
|
+
path_top -= 1
|
382
|
+
InPath[c] = -1
|
383
|
+
|
384
|
+
return True, []
|
385
|
+
|
386
|
+
|
387
|
+
def is_long_antihole_free(g, certificate=False):
|
388
|
+
r"""
|
389
|
+
Test whether the given graph contains an induced subgraph that is
|
390
|
+
isomorphic to the complement of a cycle of length at least 5.
|
391
|
+
|
392
|
+
INPUT:
|
393
|
+
|
394
|
+
- ``certificate`` -- boolean (default: ``False``)
|
395
|
+
|
396
|
+
Whether to return a certificate. When ``certificate = True``, then
|
397
|
+
the function returns
|
398
|
+
|
399
|
+
* ``(False, Antihole)`` if ``g`` contains an induced complement
|
400
|
+
of a cycle of length at least 5 returned as ``Antihole``.
|
401
|
+
* ``(True, [])`` if ``g`` does not contain an induced complement of
|
402
|
+
a cycle of length at least 5.
|
403
|
+
For this case it is not known how to provide a certificate.
|
404
|
+
|
405
|
+
When ``certificate = False``, the function returns just ``True`` or
|
406
|
+
``False`` accordingly.
|
407
|
+
|
408
|
+
ALGORITHM:
|
409
|
+
|
410
|
+
This algorithm tries to find a cycle in the graph of all induced
|
411
|
+
`\overline{P_4}` of `g`, where two copies `\overline{P}` and `\overline{P'}`
|
412
|
+
of `\overline{P_4}` are adjacent if there exists a (not necessarily induced)
|
413
|
+
copy of `\overline{P_5}=u_1u_2u_3u_4u_5` such that
|
414
|
+
`\overline{P}=u_1u_2u_3u_4` and `\overline{P'}=u_2u_3u_4u_5`.
|
415
|
+
|
416
|
+
This is done through a depth-first-search. For efficiency, the auxiliary
|
417
|
+
graph is constructed on-the-fly and never stored in memory.
|
418
|
+
|
419
|
+
The run time of this algorithm is `O(n+m^2)` for ``SparseGraph`` and
|
420
|
+
`O(n^2\log{m} + m^2)` for ``DenseGraph`` [NP2007]_ (where `n` is the number
|
421
|
+
of vertices and `m` is the number of edges of the graph).
|
422
|
+
|
423
|
+
EXAMPLES:
|
424
|
+
|
425
|
+
The Petersen Graph contains an antihole::
|
426
|
+
|
427
|
+
sage: g = graphs.PetersenGraph()
|
428
|
+
sage: g.is_long_antihole_free()
|
429
|
+
False
|
430
|
+
|
431
|
+
The complement of a cycle is an antihole::
|
432
|
+
|
433
|
+
sage: g = graphs.CycleGraph(6).complement()
|
434
|
+
sage: r,a = g.is_long_antihole_free(certificate=True)
|
435
|
+
sage: r
|
436
|
+
False
|
437
|
+
sage: a.complement().is_isomorphic(graphs.CycleGraph(6))
|
438
|
+
True
|
439
|
+
|
440
|
+
TESTS:
|
441
|
+
|
442
|
+
Further tests::
|
443
|
+
|
444
|
+
sage: g = Graph({0:[6,7],1:[7,8],2:[8,9],3:[9,10],4:[10,11],5:[11,6],6:[0,5,7],7:[0,1,6],8:[1,2,9],9:[2,3,8],10:[3,4,11],11:[4,5,10]}).complement()
|
445
|
+
sage: r,a = g.is_long_antihole_free(certificate=True)
|
446
|
+
sage: r
|
447
|
+
False
|
448
|
+
sage: a.complement().is_isomorphic(graphs.CycleGraph(9))
|
449
|
+
True
|
450
|
+
|
451
|
+
sage: graphs.EmptyGraph().is_long_hole_free()
|
452
|
+
True
|
453
|
+
|
454
|
+
Immutable graphs::
|
455
|
+
|
456
|
+
sage: G = graphs.RandomGNP(10, .7)
|
457
|
+
sage: G._backend
|
458
|
+
<sage.graphs.base.sparse_graph.SparseGraphBackend ...>
|
459
|
+
sage: H = Graph(G, immutable=True)
|
460
|
+
sage: H._backend
|
461
|
+
<sage.graphs.base.static_sparse_backend.StaticSparseBackend ...>
|
462
|
+
sage: G.is_long_antihole_free() == H.is_long_antihole_free()
|
463
|
+
True
|
464
|
+
"""
|
465
|
+
g._scream_if_not_simple()
|
466
|
+
|
467
|
+
if g.order() < 5:
|
468
|
+
return (True, []) if certificate else True
|
469
|
+
|
470
|
+
cdef int u, v, w, vv, ww
|
471
|
+
|
472
|
+
# Make a copy of the graph as a short_digraph. This data structure is well
|
473
|
+
# documented in the module sage.graphs.base.static_sparse_graph.
|
474
|
+
# Vertices are relabeled in 0..n-1
|
475
|
+
cdef int n = g.order()
|
476
|
+
cdef list id_label
|
477
|
+
cdef StaticSparseCGraph cg
|
478
|
+
cdef short_digraph sd
|
479
|
+
if isinstance(g, StaticSparseBackend):
|
480
|
+
cg = <StaticSparseCGraph> g._cg
|
481
|
+
sd = <short_digraph> cg.g
|
482
|
+
id_label = cg._vertex_to_labels
|
483
|
+
else:
|
484
|
+
id_label = list(g)
|
485
|
+
init_short_digraph(sd, g, edge_labelled=False, vertex_list=id_label)
|
486
|
+
|
487
|
+
# Make a dense copy of the graph for quick adjacency tests
|
488
|
+
cdef bitset_t dense_graph
|
489
|
+
bitset_init(dense_graph, n * n)
|
490
|
+
bitset_set_first_n(dense_graph, 0)
|
491
|
+
for u in range(n):
|
492
|
+
for vv in range(out_degree(sd, u)):
|
493
|
+
v = sd.neighbors[u][vv]
|
494
|
+
bitset_add(dense_graph, u * n + v)
|
495
|
+
bitset_add(dense_graph, v * n + u)
|
496
|
+
|
497
|
+
# Allocate some data structures
|
498
|
+
cdef MemoryAllocator mem = MemoryAllocator()
|
499
|
+
cdef int* path = <int*> mem.allocarray(n, sizeof(int))
|
500
|
+
cdef int* InPath = <int*> mem.allocarray(n, sizeof(int))
|
501
|
+
for u in range(n):
|
502
|
+
InPath[u] = -1
|
503
|
+
|
504
|
+
cdef int* neighbor_index = <int*> mem.allocarray(n, sizeof(int))
|
505
|
+
|
506
|
+
cdef set VisitedP3 = set() # stores triples (u,v,w) which represent visited paths of length 3
|
507
|
+
|
508
|
+
# main algorithm
|
509
|
+
# For all triples u,v,w of vertices such that uvw is a complement of P_3
|
510
|
+
for u in range(n):
|
511
|
+
# u is the first vertex of the path, at position 0
|
512
|
+
path[1] = u
|
513
|
+
InPath[u] = 1
|
514
|
+
for v in range(n):
|
515
|
+
if v == u or has_edge(dense_graph, u, v, n):
|
516
|
+
continue
|
517
|
+
path[0] = v
|
518
|
+
InPath[v] = 0
|
519
|
+
for ww in range(out_degree(sd, v)):
|
520
|
+
w = sd.neighbors[v][ww]
|
521
|
+
if v < w and not has_edge(dense_graph, u, w, n) and (v, u, w) not in VisitedP3:
|
522
|
+
|
523
|
+
res, antihole = is_long_antihole_free_process(g, sd, dense_graph, id_label,
|
524
|
+
path, InPath, neighbor_index,
|
525
|
+
VisitedP3, certificate,
|
526
|
+
v, u, w, n)
|
527
|
+
|
528
|
+
if not res:
|
529
|
+
# We release memory before returning the result
|
530
|
+
if not isinstance(g, StaticSparseBackend):
|
531
|
+
free_short_digraph(sd)
|
532
|
+
bitset_free(dense_graph)
|
533
|
+
|
534
|
+
if certificate:
|
535
|
+
return False, antihole
|
536
|
+
return False
|
537
|
+
|
538
|
+
InPath[v] = -1
|
539
|
+
InPath[u] = -1
|
540
|
+
|
541
|
+
# Release memory
|
542
|
+
if not isinstance(g, StaticSparseBackend):
|
543
|
+
free_short_digraph(sd)
|
544
|
+
bitset_free(dense_graph)
|
545
|
+
|
546
|
+
if certificate:
|
547
|
+
return True, []
|
548
|
+
return True
|
549
|
+
|
550
|
+
|
551
|
+
def is_weakly_chordal(g, certificate=False):
|
552
|
+
r"""
|
553
|
+
Test whether the given graph is weakly chordal, i.e., the graph and its
|
554
|
+
complement have no induced cycle of length at least 5.
|
555
|
+
|
556
|
+
INPUT:
|
557
|
+
|
558
|
+
- ``certificate`` -- boolean (default: ``False``); whether to
|
559
|
+
return a certificate. If ``certificate = False``, return ``True`` or
|
560
|
+
``False`` according to the graph. If ``certificate = True``, return
|
561
|
+
|
562
|
+
* ``(False, forbidden_subgraph)`` when the graph contains a
|
563
|
+
forbidden subgraph H, this graph is returned.
|
564
|
+
* ``(True, [])`` when the graph is weakly chordal.
|
565
|
+
For this case, it is not known how to provide a certificate.
|
566
|
+
|
567
|
+
ALGORITHM:
|
568
|
+
|
569
|
+
This algorithm checks whether the graph ``g`` or its complement
|
570
|
+
contain an induced cycle of length at least 5.
|
571
|
+
|
572
|
+
Using is_long_hole_free() and is_long_antihole_free() yields a run time
|
573
|
+
of `O(n+m^2)` for ``SparseGraph`` and `O(n^2 + m^2)` for ``DenseGraph``
|
574
|
+
(where `n` is the number of vertices and `m` is the number of edges of the
|
575
|
+
graph).
|
576
|
+
|
577
|
+
EXAMPLES:
|
578
|
+
|
579
|
+
The Petersen Graph is not weakly chordal and contains a hole::
|
580
|
+
|
581
|
+
sage: g = graphs.PetersenGraph()
|
582
|
+
sage: r,s = g.is_weakly_chordal(certificate=True)
|
583
|
+
sage: r
|
584
|
+
False
|
585
|
+
sage: l = s.order()
|
586
|
+
sage: s.is_isomorphic(graphs.CycleGraph(l))
|
587
|
+
True
|
588
|
+
|
589
|
+
TESTS::
|
590
|
+
|
591
|
+
sage: graphs.EmptyGraph().is_weakly_chordal()
|
592
|
+
True
|
593
|
+
"""
|
594
|
+
if g.order() < 5:
|
595
|
+
return (True, []) if certificate else True
|
596
|
+
|
597
|
+
if certificate:
|
598
|
+
r, forbid_subgr = g.is_long_hole_free(certificate=True)
|
599
|
+
if not r:
|
600
|
+
return False, forbid_subgr
|
601
|
+
|
602
|
+
return g.is_long_antihole_free(certificate=True)
|
603
|
+
|
604
|
+
return g.is_long_hole_free() and g.is_long_antihole_free()
|
@@ -0,0 +1 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
@@ -0,0 +1 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
@@ -0,0 +1 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# sage_setup: distribution = sagemath-graphs
|
2
|
+
#*****************************************************************************
|
3
|
+
# Copyright (C) 2006 - 2011 Robert L. Miller <rlmillster@gmail.com>
|
4
|
+
#
|
5
|
+
# This program is free software: you can redistribute it and/or modify
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
7
|
+
# the Free Software Foundation, either version 2 of the License, or
|
8
|
+
# (at your option) any later version.
|
9
|
+
# http://www.gnu.org/licenses/
|
10
|
+
#*****************************************************************************
|
11
|
+
|
12
|
+
from sage.groups.perm_gps.partn_ref.data_structures cimport *
|
13
|
+
from sage.graphs.base.c_graph cimport CGraph
|
14
|
+
from sage.groups.perm_gps.partn_ref.automorphism_group_canonical_label cimport (
|
15
|
+
get_aut_gp_and_can_lab, aut_gp_and_can_lab, agcl_work_space,
|
16
|
+
allocate_agcl_output, deallocate_agcl_output,
|
17
|
+
allocate_agcl_work_space, deallocate_agcl_work_space)
|
18
|
+
from sage.groups.perm_gps.partn_ref.canonical_augmentation cimport (iterator,
|
19
|
+
canonical_generator_data, allocate_cgd, deallocate_cgd,
|
20
|
+
canonical_generator_next,
|
21
|
+
setup_canonical_generator, start_canonical_generator)
|
22
|
+
from sage.groups.perm_gps.partn_ref.refinement_sets cimport (subset, free_subset, all_set_children_are_equivalent,
|
23
|
+
refine_set, compare_sets, generate_child_subsets, apply_subset_aug,
|
24
|
+
canonical_set_parent, allocate_sgd, deallocate_sgd, allocate_subset_gen, free_subset_gen,
|
25
|
+
setup_set_gen, subset_generator_next, subset_generator_data, allocate_subset_gen_2)
|
26
|
+
|
27
|
+
|
28
|
+
cdef class GraphStruct:
|
29
|
+
cdef CGraph G
|
30
|
+
cdef bint directed
|
31
|
+
cdef bint loops
|
32
|
+
cdef bint use_indicator
|
33
|
+
cdef int *scratch # length 3n+1
|
34
|
+
|
35
|
+
|
36
|
+
cdef struct dg_edge_gen_data:
|
37
|
+
iterator *edge_iterator
|
38
|
+
void *graph
|