passagemath-graphs 10.6.1rc1__cp310-cp310-musllinux_1_2_aarch64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. passagemath_graphs-10.6.1rc1.dist-info/METADATA +292 -0
  2. passagemath_graphs-10.6.1rc1.dist-info/RECORD +260 -0
  3. passagemath_graphs-10.6.1rc1.dist-info/WHEEL +5 -0
  4. passagemath_graphs-10.6.1rc1.dist-info/top_level.txt +2 -0
  5. passagemath_graphs.libs/libgcc_s-69c45f16.so.1 +0 -0
  6. passagemath_graphs.libs/libgmp-8e78bd9b.so.10.5.0 +0 -0
  7. passagemath_graphs.libs/libstdc++-1f1a71be.so.6.0.33 +0 -0
  8. sage/all__sagemath_graphs.py +39 -0
  9. sage/combinat/abstract_tree.py +2723 -0
  10. sage/combinat/all__sagemath_graphs.py +34 -0
  11. sage/combinat/binary_tree.py +5306 -0
  12. sage/combinat/cluster_algebra_quiver/all.py +22 -0
  13. sage/combinat/cluster_algebra_quiver/cluster_seed.py +5208 -0
  14. sage/combinat/cluster_algebra_quiver/interact.py +124 -0
  15. sage/combinat/cluster_algebra_quiver/mutation_class.py +625 -0
  16. sage/combinat/cluster_algebra_quiver/mutation_type.py +1555 -0
  17. sage/combinat/cluster_algebra_quiver/quiver.py +2290 -0
  18. sage/combinat/cluster_algebra_quiver/quiver_mutation_type.py +2468 -0
  19. sage/combinat/designs/MOLS_handbook_data.py +570 -0
  20. sage/combinat/designs/all.py +58 -0
  21. sage/combinat/designs/bibd.py +1655 -0
  22. sage/combinat/designs/block_design.py +1071 -0
  23. sage/combinat/designs/covering_array.py +269 -0
  24. sage/combinat/designs/covering_design.py +530 -0
  25. sage/combinat/designs/database.py +5615 -0
  26. sage/combinat/designs/design_catalog.py +122 -0
  27. sage/combinat/designs/designs_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  28. sage/combinat/designs/designs_pyx.pxd +21 -0
  29. sage/combinat/designs/designs_pyx.pyx +993 -0
  30. sage/combinat/designs/difference_family.py +3951 -0
  31. sage/combinat/designs/difference_matrices.py +279 -0
  32. sage/combinat/designs/evenly_distributed_sets.cpython-310-aarch64-linux-gnu.so +0 -0
  33. sage/combinat/designs/evenly_distributed_sets.pyx +661 -0
  34. sage/combinat/designs/ext_rep.py +1064 -0
  35. sage/combinat/designs/gen_quadrangles_with_spread.cpython-310-aarch64-linux-gnu.so +0 -0
  36. sage/combinat/designs/gen_quadrangles_with_spread.pyx +339 -0
  37. sage/combinat/designs/group_divisible_designs.py +361 -0
  38. sage/combinat/designs/incidence_structures.py +2357 -0
  39. sage/combinat/designs/latin_squares.py +581 -0
  40. sage/combinat/designs/orthogonal_arrays.py +2244 -0
  41. sage/combinat/designs/orthogonal_arrays_build_recursive.py +1780 -0
  42. sage/combinat/designs/orthogonal_arrays_find_recursive.cpython-310-aarch64-linux-gnu.so +0 -0
  43. sage/combinat/designs/orthogonal_arrays_find_recursive.pyx +967 -0
  44. sage/combinat/designs/resolvable_bibd.py +815 -0
  45. sage/combinat/designs/steiner_quadruple_systems.py +1306 -0
  46. sage/combinat/designs/subhypergraph_search.cpython-310-aarch64-linux-gnu.so +0 -0
  47. sage/combinat/designs/subhypergraph_search.pyx +530 -0
  48. sage/combinat/designs/twographs.py +306 -0
  49. sage/combinat/finite_state_machine.py +14874 -0
  50. sage/combinat/finite_state_machine_generators.py +2006 -0
  51. sage/combinat/graph_path.py +448 -0
  52. sage/combinat/interval_posets.py +3908 -0
  53. sage/combinat/nu_tamari_lattice.py +269 -0
  54. sage/combinat/ordered_tree.py +1446 -0
  55. sage/combinat/posets/all.py +46 -0
  56. sage/combinat/posets/bubble_shuffle.py +247 -0
  57. sage/combinat/posets/cartesian_product.py +493 -0
  58. sage/combinat/posets/d_complete.py +182 -0
  59. sage/combinat/posets/elements.py +273 -0
  60. sage/combinat/posets/forest.py +30 -0
  61. sage/combinat/posets/hasse_cython.cpython-310-aarch64-linux-gnu.so +0 -0
  62. sage/combinat/posets/hasse_cython.pyx +174 -0
  63. sage/combinat/posets/hasse_diagram.py +3672 -0
  64. sage/combinat/posets/hochschild_lattice.py +158 -0
  65. sage/combinat/posets/incidence_algebras.py +794 -0
  66. sage/combinat/posets/lattices.py +5117 -0
  67. sage/combinat/posets/linear_extension_iterator.cpython-310-aarch64-linux-gnu.so +0 -0
  68. sage/combinat/posets/linear_extension_iterator.pyx +292 -0
  69. sage/combinat/posets/linear_extensions.py +1037 -0
  70. sage/combinat/posets/mobile.py +275 -0
  71. sage/combinat/posets/moebius_algebra.py +776 -0
  72. sage/combinat/posets/poset_examples.py +2178 -0
  73. sage/combinat/posets/posets.py +9360 -0
  74. sage/combinat/rooted_tree.py +1070 -0
  75. sage/combinat/shard_order.py +239 -0
  76. sage/combinat/tamari_lattices.py +384 -0
  77. sage/combinat/yang_baxter_graph.py +923 -0
  78. sage/databases/all__sagemath_graphs.py +1 -0
  79. sage/databases/knotinfo_db.py +1231 -0
  80. sage/ext_data/all__sagemath_graphs.py +1 -0
  81. sage/ext_data/graphs/graph_plot_js.html +330 -0
  82. sage/ext_data/kenzo/CP2.txt +45 -0
  83. sage/ext_data/kenzo/CP3.txt +349 -0
  84. sage/ext_data/kenzo/CP4.txt +4774 -0
  85. sage/ext_data/kenzo/README.txt +49 -0
  86. sage/ext_data/kenzo/S4.txt +20 -0
  87. sage/graphs/all.py +42 -0
  88. sage/graphs/asteroidal_triples.cpython-310-aarch64-linux-gnu.so +0 -0
  89. sage/graphs/asteroidal_triples.pyx +320 -0
  90. sage/graphs/base/all.py +1 -0
  91. sage/graphs/base/boost_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  92. sage/graphs/base/boost_graph.pxd +106 -0
  93. sage/graphs/base/boost_graph.pyx +3045 -0
  94. sage/graphs/base/c_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  95. sage/graphs/base/c_graph.pxd +106 -0
  96. sage/graphs/base/c_graph.pyx +5096 -0
  97. sage/graphs/base/dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  98. sage/graphs/base/dense_graph.pxd +28 -0
  99. sage/graphs/base/dense_graph.pyx +801 -0
  100. sage/graphs/base/graph_backends.cpython-310-aarch64-linux-gnu.so +0 -0
  101. sage/graphs/base/graph_backends.pxd +5 -0
  102. sage/graphs/base/graph_backends.pyx +797 -0
  103. sage/graphs/base/overview.py +85 -0
  104. sage/graphs/base/sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  105. sage/graphs/base/sparse_graph.pxd +90 -0
  106. sage/graphs/base/sparse_graph.pyx +1653 -0
  107. sage/graphs/base/static_dense_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  108. sage/graphs/base/static_dense_graph.pxd +5 -0
  109. sage/graphs/base/static_dense_graph.pyx +1032 -0
  110. sage/graphs/base/static_sparse_backend.cpython-310-aarch64-linux-gnu.so +0 -0
  111. sage/graphs/base/static_sparse_backend.pxd +27 -0
  112. sage/graphs/base/static_sparse_backend.pyx +1583 -0
  113. sage/graphs/base/static_sparse_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  114. sage/graphs/base/static_sparse_graph.pxd +37 -0
  115. sage/graphs/base/static_sparse_graph.pyx +1375 -0
  116. sage/graphs/bipartite_graph.py +2732 -0
  117. sage/graphs/centrality.cpython-310-aarch64-linux-gnu.so +0 -0
  118. sage/graphs/centrality.pyx +1038 -0
  119. sage/graphs/cographs.py +519 -0
  120. sage/graphs/comparability.cpython-310-aarch64-linux-gnu.so +0 -0
  121. sage/graphs/comparability.pyx +851 -0
  122. sage/graphs/connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
  123. sage/graphs/connectivity.pxd +157 -0
  124. sage/graphs/connectivity.pyx +4813 -0
  125. sage/graphs/convexity_properties.cpython-310-aarch64-linux-gnu.so +0 -0
  126. sage/graphs/convexity_properties.pxd +16 -0
  127. sage/graphs/convexity_properties.pyx +870 -0
  128. sage/graphs/digraph.py +4754 -0
  129. sage/graphs/digraph_generators.py +1993 -0
  130. sage/graphs/distances_all_pairs.cpython-310-aarch64-linux-gnu.so +0 -0
  131. sage/graphs/distances_all_pairs.pxd +12 -0
  132. sage/graphs/distances_all_pairs.pyx +2938 -0
  133. sage/graphs/domination.py +1363 -0
  134. sage/graphs/dot2tex_utils.py +100 -0
  135. sage/graphs/edge_connectivity.cpython-310-aarch64-linux-gnu.so +0 -0
  136. sage/graphs/edge_connectivity.pyx +1215 -0
  137. sage/graphs/generators/all.py +1 -0
  138. sage/graphs/generators/basic.py +1769 -0
  139. sage/graphs/generators/chessboard.py +538 -0
  140. sage/graphs/generators/classical_geometries.py +1611 -0
  141. sage/graphs/generators/degree_sequence.py +235 -0
  142. sage/graphs/generators/distance_regular.cpython-310-aarch64-linux-gnu.so +0 -0
  143. sage/graphs/generators/distance_regular.pyx +2846 -0
  144. sage/graphs/generators/families.py +4759 -0
  145. sage/graphs/generators/intersection.py +565 -0
  146. sage/graphs/generators/platonic_solids.py +262 -0
  147. sage/graphs/generators/random.py +2623 -0
  148. sage/graphs/generators/smallgraphs.py +5741 -0
  149. sage/graphs/generators/world_map.py +724 -0
  150. sage/graphs/generic_graph.py +26867 -0
  151. sage/graphs/generic_graph_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  152. sage/graphs/generic_graph_pyx.pxd +34 -0
  153. sage/graphs/generic_graph_pyx.pyx +1673 -0
  154. sage/graphs/genus.cpython-310-aarch64-linux-gnu.so +0 -0
  155. sage/graphs/genus.pyx +622 -0
  156. sage/graphs/graph.py +9645 -0
  157. sage/graphs/graph_coloring.cpython-310-aarch64-linux-gnu.so +0 -0
  158. sage/graphs/graph_coloring.pyx +2284 -0
  159. sage/graphs/graph_database.py +1177 -0
  160. sage/graphs/graph_decompositions/all.py +1 -0
  161. sage/graphs/graph_decompositions/bandwidth.cpython-310-aarch64-linux-gnu.so +0 -0
  162. sage/graphs/graph_decompositions/bandwidth.pyx +428 -0
  163. sage/graphs/graph_decompositions/clique_separators.cpython-310-aarch64-linux-gnu.so +0 -0
  164. sage/graphs/graph_decompositions/clique_separators.pyx +616 -0
  165. sage/graphs/graph_decompositions/cutwidth.cpython-310-aarch64-linux-gnu.so +0 -0
  166. sage/graphs/graph_decompositions/cutwidth.pyx +753 -0
  167. sage/graphs/graph_decompositions/fast_digraph.cpython-310-aarch64-linux-gnu.so +0 -0
  168. sage/graphs/graph_decompositions/fast_digraph.pxd +13 -0
  169. sage/graphs/graph_decompositions/fast_digraph.pyx +212 -0
  170. sage/graphs/graph_decompositions/graph_products.cpython-310-aarch64-linux-gnu.so +0 -0
  171. sage/graphs/graph_decompositions/graph_products.pyx +508 -0
  172. sage/graphs/graph_decompositions/modular_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  173. sage/graphs/graph_decompositions/modular_decomposition.pxd +27 -0
  174. sage/graphs/graph_decompositions/modular_decomposition.pyx +1536 -0
  175. sage/graphs/graph_decompositions/slice_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  176. sage/graphs/graph_decompositions/slice_decomposition.pxd +18 -0
  177. sage/graphs/graph_decompositions/slice_decomposition.pyx +1106 -0
  178. sage/graphs/graph_decompositions/tree_decomposition.cpython-310-aarch64-linux-gnu.so +0 -0
  179. sage/graphs/graph_decompositions/tree_decomposition.pxd +17 -0
  180. sage/graphs/graph_decompositions/tree_decomposition.pyx +1996 -0
  181. sage/graphs/graph_decompositions/vertex_separation.cpython-310-aarch64-linux-gnu.so +0 -0
  182. sage/graphs/graph_decompositions/vertex_separation.pxd +5 -0
  183. sage/graphs/graph_decompositions/vertex_separation.pyx +1963 -0
  184. sage/graphs/graph_editor.py +82 -0
  185. sage/graphs/graph_generators.py +3314 -0
  186. sage/graphs/graph_generators_pyx.cpython-310-aarch64-linux-gnu.so +0 -0
  187. sage/graphs/graph_generators_pyx.pyx +95 -0
  188. sage/graphs/graph_input.py +812 -0
  189. sage/graphs/graph_latex.py +2064 -0
  190. sage/graphs/graph_list.py +410 -0
  191. sage/graphs/graph_plot.py +1756 -0
  192. sage/graphs/graph_plot_js.py +338 -0
  193. sage/graphs/hyperbolicity.cpython-310-aarch64-linux-gnu.so +0 -0
  194. sage/graphs/hyperbolicity.pyx +1704 -0
  195. sage/graphs/hypergraph_generators.py +364 -0
  196. sage/graphs/independent_sets.cpython-310-aarch64-linux-gnu.so +0 -0
  197. sage/graphs/independent_sets.pxd +13 -0
  198. sage/graphs/independent_sets.pyx +402 -0
  199. sage/graphs/isgci.py +1033 -0
  200. sage/graphs/isoperimetric_inequalities.cpython-310-aarch64-linux-gnu.so +0 -0
  201. sage/graphs/isoperimetric_inequalities.pyx +489 -0
  202. sage/graphs/line_graph.cpython-310-aarch64-linux-gnu.so +0 -0
  203. sage/graphs/line_graph.pyx +743 -0
  204. sage/graphs/lovasz_theta.py +77 -0
  205. sage/graphs/matching.py +1633 -0
  206. sage/graphs/matching_covered_graph.py +3590 -0
  207. sage/graphs/orientations.py +1489 -0
  208. sage/graphs/partial_cube.py +459 -0
  209. sage/graphs/path_enumeration.cpython-310-aarch64-linux-gnu.so +0 -0
  210. sage/graphs/path_enumeration.pyx +2040 -0
  211. sage/graphs/pq_trees.py +1129 -0
  212. sage/graphs/print_graphs.py +201 -0
  213. sage/graphs/schnyder.py +865 -0
  214. sage/graphs/spanning_tree.cpython-310-aarch64-linux-gnu.so +0 -0
  215. sage/graphs/spanning_tree.pyx +1457 -0
  216. sage/graphs/strongly_regular_db.cpython-310-aarch64-linux-gnu.so +0 -0
  217. sage/graphs/strongly_regular_db.pyx +3340 -0
  218. sage/graphs/traversals.cpython-310-aarch64-linux-gnu.so +0 -0
  219. sage/graphs/traversals.pxd +9 -0
  220. sage/graphs/traversals.pyx +1872 -0
  221. sage/graphs/trees.cpython-310-aarch64-linux-gnu.so +0 -0
  222. sage/graphs/trees.pxd +15 -0
  223. sage/graphs/trees.pyx +310 -0
  224. sage/graphs/tutte_polynomial.py +713 -0
  225. sage/graphs/views.cpython-310-aarch64-linux-gnu.so +0 -0
  226. sage/graphs/views.pyx +794 -0
  227. sage/graphs/weakly_chordal.cpython-310-aarch64-linux-gnu.so +0 -0
  228. sage/graphs/weakly_chordal.pyx +604 -0
  229. sage/groups/all__sagemath_graphs.py +1 -0
  230. sage/groups/perm_gps/all__sagemath_graphs.py +1 -0
  231. sage/groups/perm_gps/partn_ref/all__sagemath_graphs.py +1 -0
  232. sage/groups/perm_gps/partn_ref/refinement_graphs.cpython-310-aarch64-linux-gnu.so +0 -0
  233. sage/groups/perm_gps/partn_ref/refinement_graphs.pxd +38 -0
  234. sage/groups/perm_gps/partn_ref/refinement_graphs.pyx +1666 -0
  235. sage/knots/all.py +6 -0
  236. sage/knots/free_knotinfo_monoid.py +507 -0
  237. sage/knots/gauss_code.py +291 -0
  238. sage/knots/knot.py +682 -0
  239. sage/knots/knot_table.py +284 -0
  240. sage/knots/knotinfo.py +2900 -0
  241. sage/knots/link.py +4715 -0
  242. sage/sandpiles/all.py +13 -0
  243. sage/sandpiles/examples.py +225 -0
  244. sage/sandpiles/sandpile.py +6365 -0
  245. sage/topology/all.py +22 -0
  246. sage/topology/cell_complex.py +1214 -0
  247. sage/topology/cubical_complex.py +1976 -0
  248. sage/topology/delta_complex.py +1806 -0
  249. sage/topology/filtered_simplicial_complex.py +744 -0
  250. sage/topology/moment_angle_complex.py +823 -0
  251. sage/topology/simplicial_complex.py +5160 -0
  252. sage/topology/simplicial_complex_catalog.py +92 -0
  253. sage/topology/simplicial_complex_examples.py +1680 -0
  254. sage/topology/simplicial_complex_homset.py +205 -0
  255. sage/topology/simplicial_complex_morphism.py +836 -0
  256. sage/topology/simplicial_set.py +4102 -0
  257. sage/topology/simplicial_set_catalog.py +55 -0
  258. sage/topology/simplicial_set_constructions.py +2954 -0
  259. sage/topology/simplicial_set_examples.py +865 -0
  260. sage/topology/simplicial_set_morphism.py +1464 -0
@@ -0,0 +1,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