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
sage/graphs/isgci.py ADDED
@@ -0,0 +1,1033 @@
1
+ # sage_setup: distribution = sagemath-graphs
2
+ # sage.doctest: needs database_graphs
3
+ r"""
4
+ ISGCI: Information System on Graph Classes and their Inclusions
5
+
6
+ This module implements an interface to the
7
+ `ISGCI <http://www.graphclasses.org/>`_ database in Sage.
8
+
9
+ This database gathers information on graph classes and their inclusions in each
10
+ other. It also contains information on the complexity of several computational
11
+ problems.
12
+
13
+ It is available on the `GraphClasses.org <http://www.graphclasses.org/>`_
14
+ website maintained by H.N. de Ridder et al.
15
+
16
+ How to use it?
17
+ --------------
18
+
19
+ Presently, it is possible to use this database through the variables and methods
20
+ present in the :obj:`graph_classes <GraphClasses>` object.
21
+ For instance::
22
+
23
+ sage: Trees = graph_classes.Tree
24
+ sage: Chordal = graph_classes.Chordal
25
+
26
+ Inclusions
27
+ ^^^^^^^^^^
28
+
29
+ It is then possible to check the inclusion of classes inside of others, if the
30
+ information is available in the database::
31
+
32
+ sage: Trees <= Chordal
33
+ True
34
+
35
+ And indeed, trees are chordal graphs.
36
+
37
+ The ISGCI database is not all-knowing, and so comparing two classes can return
38
+ ``True``, ``False``, or ``Unknown`` (see the :mod:`documentation of the Unknown
39
+ truth value <sage.misc.unknown>`).
40
+
41
+ An *unknown* answer to ``A <= B`` only means that ISGCI cannot deduce from the
42
+ information in its database that ``A`` is a subclass of ``B`` nor that it is
43
+ not. For instance, ISGCI does not know at the moment that some chordal graphs
44
+ are not trees::
45
+
46
+ sage: graph_classes.Chordal <= graph_classes.Tree
47
+ Unknown
48
+
49
+ Descriptions
50
+ ^^^^^^^^^^^^
51
+
52
+ Given a graph class, one can obtain its associated information in the ISGCI
53
+ database with the :meth:`~GraphClass.description` method::
54
+
55
+ sage: Chordal.description()
56
+ Class of graphs : Chordal
57
+ -------------------------
58
+ id : gc_32
59
+ name : chordal
60
+ ...
61
+ Problems :
62
+ -----------
63
+ 3-Colourability : Linear
64
+ Clique : Polynomial
65
+ Clique cover : Polynomial
66
+ ...
67
+
68
+ It is possible to obtain the complete list of the classes stored in ISGCI by
69
+ calling the :meth:`~GraphClasses.show_all` method (beware -- long output)::
70
+
71
+ sage: graph_classes.show_all()
72
+ id | name | type | smallgraph
73
+ ----------------------------------------------------------------------------------------------------------------------
74
+ gc_309 | $K_4$--minor--free | base |
75
+ gc_541 | $N^*$ | base |
76
+ gc_215 | $N^*$--perfect | base |
77
+ gc_5 | $P_4$--bipartite | base |
78
+ gc_3 | $P_4$--brittle | base |
79
+ gc_6 | $P_4$--comparability | base |
80
+ gc_7 | $P_4$--extendible | base |
81
+ ...
82
+
83
+ Until a proper search method is implemented, this lets one find classes which do
84
+ not appear in :obj:`graph_classes.* <GraphClasses>`.
85
+
86
+ To retrieve a class of graph from its ISGCI ID one may use
87
+ the :meth:`~GraphClasses.get_class` method::
88
+
89
+ sage: GC = graph_classes.get_class("gc_5")
90
+ sage: GC
91
+ $P_4$--bipartite graphs
92
+
93
+ Recognition of graphs
94
+ ^^^^^^^^^^^^^^^^^^^^^
95
+
96
+ The graph classes represented by the ISGCI database can alternatively be used to
97
+ access recognition algorithms. For instance, in order to check that a given
98
+ graph is a tree one has the following the options ::
99
+
100
+ sage: graphs.PathGraph(5) in graph_classes.Tree
101
+ True
102
+
103
+ or::
104
+
105
+ sage: graphs.PathGraph(5).is_tree()
106
+ True
107
+
108
+ Furthermore, all ISGCI graph classes which are defined by the exclusion of a
109
+ finite sequence of induced subgraphs benefit from a generic recognition
110
+ algorithm. For instance ::
111
+
112
+ sage: g = graphs.PetersenGraph()
113
+ sage: g in graph_classes.ClawFree
114
+ False
115
+ sage: g.line_graph() in graph_classes.ClawFree
116
+ True
117
+
118
+ Or directly from ISGCI ::
119
+
120
+ sage: gc = graph_classes.get_class("gc_441")
121
+ sage: gc
122
+ diamond--free graphs
123
+ sage: graphs.PetersenGraph() in gc
124
+ True
125
+
126
+ Predefined classes
127
+ ------------------
128
+
129
+ :obj:`graph_classes <GraphClasses>` currently predefines the following graph classes
130
+
131
+ .. list-table::
132
+ :widths: 20 30
133
+ :header-rows: 1
134
+
135
+ * - Class
136
+ - Related methods
137
+
138
+ * - Apex
139
+
140
+ - :meth:`~sage.graphs.graph.Graph.is_apex`,
141
+ :meth:`~sage.graphs.graph.Graph.apex_vertices`
142
+
143
+ * - AT_free
144
+
145
+ - :meth:`~sage.graphs.graph.Graph.is_asteroidal_triple_free`
146
+
147
+ * - Biconnected
148
+
149
+ - :meth:`~sage.graphs.graph.Graph.is_biconnected`,
150
+ :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices`,
151
+ :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cuts_tree`
152
+
153
+ * - BinaryTrees
154
+
155
+ - :meth:`~sage.graphs.graph_generators.GraphGenerators.BalancedTree`,
156
+ :meth:`~sage.graphs.graph.Graph.is_tree`
157
+
158
+ * - Bipartite
159
+
160
+ - :meth:`~sage.graphs.graph_generators.GraphGenerators.BalancedTree`,
161
+ :meth:`~sage.graphs.generic_graph.GenericGraph.is_bipartite`
162
+
163
+ * - Block
164
+
165
+ - :meth:`~sage.graphs.graph.Graph.is_block_graph`,
166
+ :meth:`~sage.graphs.generic_graph.GenericGraph.blocks_and_cut_vertices`,
167
+ :meth:`~sage.graphs.graph_generators.GraphGenerators.RandomBlockGraph`
168
+
169
+ * - Chordal
170
+
171
+ - :meth:`~sage.graphs.generic_graph.GenericGraph.is_chordal`
172
+
173
+ * - Claw-Free
174
+ - :meth:`~sage.graphs.graph_generators.GraphGenerators.ClawGraph`
175
+
176
+ * - Comparability
177
+ -
178
+
179
+ * - Gallai
180
+
181
+ - :meth:`~sage.graphs.generic_graph.GenericGraph.is_gallai_tree`
182
+
183
+ * - Grid
184
+
185
+ - :meth:`~sage.graphs.graph_generators.GraphGenerators.Grid2dGraph`,
186
+ :meth:`~sage.graphs.graph_generators.GraphGenerators.GridGraph`
187
+
188
+ * - Interval
189
+
190
+ - :meth:`~sage.graphs.graph_generators.GraphGenerators.RandomIntervalGraph`,
191
+ :meth:`~sage.graphs.graph_generators.GraphGenerators.IntervalGraph`,
192
+ :meth:`~sage.graphs.generic_graph.GenericGraph.is_interval`
193
+
194
+ * - Line
195
+
196
+ - :meth:`~sage.graphs.graph_generators.GraphGenerators.line_graph_forbidden_subgraphs`,
197
+ :meth:`~sage.graphs.graph.Graph.is_line_graph`
198
+
199
+ * - Modular
200
+
201
+ - :meth:`~sage.graphs.graph.Graph.modular_decomposition`
202
+
203
+ * - Outerplanar
204
+
205
+ - :meth:`~sage.graphs.generic_graph.GenericGraph.is_circular_planar`
206
+
207
+ * - Perfect
208
+
209
+ - :meth:`~sage.graphs.graph.Graph.is_perfect`
210
+
211
+ * - Planar
212
+
213
+ - :meth:`~sage.graphs.generic_graph.GenericGraph.is_planar`
214
+
215
+ * - Polyhedral
216
+
217
+ - :meth:`~sage.graphs.graph.Graph.is_polyhedral`
218
+
219
+ * - Split
220
+
221
+ - :meth:`~sage.graphs.graph.Graph.is_split`
222
+
223
+ * - Tree
224
+
225
+ - :meth:`~sage.graphs.graph_generators.GraphGenerators.trees`,
226
+ :meth:`~Graph.is_tree`
227
+
228
+ * - UnitDisk
229
+ - :meth:`~sage.graphs.graph_generators.GraphGenerators.IntervalGraph`
230
+
231
+ * - UnitInterval
232
+ - :meth:`~sage.graphs.generic_graph.GenericGraph.is_interval`
233
+
234
+ Sage's view of ISGCI
235
+ --------------------
236
+
237
+ The database is stored by Sage in two ways.
238
+
239
+ **The classes**: the list of all graph classes and their properties is stored
240
+ in a huge dictionary (see :meth:`~sage.graphs.isgci.GraphClasses.classes`).
241
+ Below is what Sage knows of ``gc_249``::
242
+
243
+ sage: graph_classes.classes()['gc_249'] # random
244
+ {'problem':
245
+ {'Independent set': 'Polynomial',
246
+ 'Treewidth': 'Unknown',
247
+ 'Weighted independent set': 'Polynomial',
248
+ 'Cliquewidth expression': 'NP-complete',
249
+ 'Weighted clique': 'Polynomial',
250
+ 'Clique cover': 'Unknown',
251
+ 'Domination': 'NP-complete',
252
+ 'Clique': 'Polynomial',
253
+ 'Colourability': 'NP-complete',
254
+ 'Cliquewidth': 'Unbounded',
255
+ '3-Colourability': 'NP-complete',
256
+ 'Recognition': 'Linear'},
257
+ 'type': 'base',
258
+ 'id': 'gc_249',
259
+ 'name': 'line'}
260
+
261
+ **The class inclusion digraph**: Sage remembers the class inclusions through
262
+ the inclusion digraph (see :meth:`~sage.graphs.isgci.GraphClasses.inclusion_digraph`).
263
+ Its nodes are ID of ISGCI classes::
264
+
265
+ sage: d = graph_classes.inclusion_digraph()
266
+ sage: d.vertices(sort=True)[-10:]
267
+ ['gc_990', 'gc_991', 'gc_992', 'gc_993', 'gc_994', 'gc_995', 'gc_996', 'gc_997', 'gc_998', 'gc_999']
268
+
269
+ An arc from ``gc1`` to ``gc2`` means that ``gc1`` is a superclass of ``gc2``.
270
+ This being said, not all edges are stored ! To ensure that a given class is
271
+ included in another one, we have to check whether there is in the digraph a
272
+ ``path`` from the first one to the other::
273
+
274
+ sage: bip_id = graph_classes.Bipartite._gc_id
275
+ sage: perfect_id = graph_classes.Perfect._gc_id
276
+ sage: d.has_edge(perfect_id, bip_id)
277
+ False
278
+ sage: d.distance(perfect_id, bip_id)
279
+ 2
280
+
281
+ Hence bipartite graphs are perfect graphs. We can see how ISGCI obtains this
282
+ result ::
283
+
284
+ sage: p = d.shortest_path(perfect_id, bip_id)
285
+ sage: len(p) - 1
286
+ 2
287
+ sage: print(p) # random
288
+ ['gc_56', 'gc_76', 'gc_69']
289
+ sage: for c in p:
290
+ ....: print(graph_classes.get_class(c))
291
+ perfect graphs
292
+ ...
293
+ bipartite graphs
294
+
295
+ What ISGCI knows is that perfect graphs contain unimodular graph which contain
296
+ bipartite graphs. Therefore bipartite graphs are perfect !
297
+
298
+ .. NOTE::
299
+
300
+ The inclusion digraph is **NOT ACYCLIC**. Indeed, several entries exist in
301
+ the ISGCI database which represent the same graph class, for instance
302
+ Perfect graphs and Berge graphs::
303
+
304
+ sage: graph_classes.inclusion_digraph().is_directed_acyclic()
305
+ False
306
+ sage: Berge = graph_classes.get_class("gc_274"); Berge
307
+ Berge graphs
308
+ sage: Perfect = graph_classes.get_class("gc_56"); Perfect
309
+ perfect graphs
310
+ sage: Berge <= Perfect
311
+ True
312
+ sage: Perfect <= Berge
313
+ True
314
+ sage: Perfect == Berge
315
+ True
316
+
317
+ Information for developers
318
+ --------------------------
319
+
320
+ * The database is loaded not *so* large, but it is still preferable to
321
+ only load it on demand. This is achieved through the cached methods
322
+ :meth:`~sage.graphs.isgci.GraphClasses.classes` and
323
+ :meth:`~sage.graphs.isgci.GraphClasses.inclusion_digraph`.
324
+
325
+ * Upon the first access to the database, the information is extracted
326
+ from the XML file and stored in the cache of three methods:
327
+
328
+ * ``sage.graphs.isgci._classes`` (dictionary)
329
+ * ``sage.graphs.isgci._inclusions`` (list of dictionaries)
330
+ * ``sage.graphs.isgci._inclusion_digraph`` (DiGraph)
331
+
332
+ Note that the digraph is only built if necessary (for instance if
333
+ the user tries to compare two classes).
334
+
335
+ .. TODO::
336
+
337
+ Technical things:
338
+
339
+ * Query the database for non-inclusion results so that comparisons can
340
+ return ``False``, and implement strict inclusions.
341
+
342
+ * Implement a proper search method for the classes not listed in
343
+ :obj:`graph_classes <GraphClasses>`
344
+
345
+ .. SEEALSO:: :func:`sage.graphs.isgci.show_all`.
346
+
347
+ * Some of the graph classes appearing in :obj:`graph_classes
348
+ <GraphClasses>` already have a recognition
349
+ algorithm implemented in Sage. It would be so nice to be able to
350
+ write ``g in Trees``, ``g in Perfect``, ``g in Chordal``, ... :-)
351
+
352
+ Long-term stuff:
353
+
354
+ * Implement simple accessors for all the information in the ISGCI
355
+ database (as can be done from the website)
356
+
357
+ * Implement intersection of graph classes
358
+
359
+ * Write generic recognition algorithms for specific classes (when a graph
360
+ class is defined by the exclusion of subgraphs, one can write a generic
361
+ algorithm checking the existence of each of the graphs, and this method
362
+ already exists in Sage).
363
+
364
+ * Improve the performance of Sage's graph library by letting it take
365
+ advantage of the properties of graph classes. For example,
366
+ :meth:`Graph.independent_set` could use the library to detect that a given
367
+ graph is, say, a tree or a planar graph, and use a specialized algorithm
368
+ for finding an independent set.
369
+
370
+ AUTHORS:
371
+ --------
372
+
373
+ * H.N. de Ridder et al. (ISGCI database)
374
+ * Nathann Cohen (Sage implementation)
375
+
376
+ Methods
377
+ -------
378
+ """
379
+
380
+ from sage.structure.sage_object import SageObject
381
+ from sage.structure.unique_representation import CachedRepresentation, UniqueRepresentation
382
+ from sage.misc.unknown import Unknown
383
+ from sage.features.databases import DatabaseGraphs
384
+ from sage.misc.cachefunc import cached_method
385
+
386
+ import os
387
+ import zipfile
388
+ from urllib.request import urlopen
389
+ from ssl import create_default_context as default_context
390
+
391
+ # ****************************************************************************
392
+ # Copyright (C) 2011 Nathann Cohen <nathann.cohen@gmail.com>
393
+ #
394
+ # Distributed under the terms of the GNU General Public License (GPL)
395
+ # https://www.gnu.org/licenses/
396
+ # ****************************************************************************
397
+
398
+ _XML_FILE = "isgci_sage.xml"
399
+ _SMALLGRAPHS_FILE = "smallgraphs.txt"
400
+
401
+
402
+ class GraphClass(SageObject, CachedRepresentation):
403
+ r"""
404
+ An instance of this class represents a Graph Class, matching some entry in
405
+ the ISGCI database.
406
+
407
+ EXAMPLES:
408
+
409
+ Testing the inclusion of two classes::
410
+
411
+ sage: Chordal = graph_classes.Chordal
412
+ sage: Trees = graph_classes.Tree
413
+ sage: Trees <= Chordal
414
+ True
415
+ sage: Chordal <= Trees
416
+ Unknown
417
+
418
+ TESTS::
419
+
420
+ sage: Trees >= Chordal
421
+ Unknown
422
+ sage: Chordal >= Trees
423
+ True
424
+ """
425
+ def __init__(self, name, gc_id, recognition_function=None):
426
+ r"""
427
+ Class constructor.
428
+
429
+ INPUT:
430
+
431
+ - ``gc_id`` -- the ISGCI class ID
432
+
433
+ - ``recognition_function`` -- a function of one argument `g`, which
434
+ return boolean answers to the question : *does ``g`` belong to the
435
+ class represented by ``gc_id`` ?*
436
+
437
+ EXAMPLES::
438
+
439
+ sage: graph_classes.Chordal # indirect doctest
440
+ Chordal graphs
441
+ """
442
+ self._name = name
443
+ self._gc_id = gc_id
444
+
445
+ if recognition_function is not None:
446
+ self._recognition_function = recognition_function
447
+
448
+ def _repr_(self):
449
+ r"""
450
+ Return a short description of the class.
451
+
452
+ EXAMPLES::
453
+
454
+ sage: graph_classes.Chordal # indirect doctest
455
+ Chordal graphs
456
+ """
457
+ return self._name + " graphs"
458
+
459
+ def __hash__(self):
460
+ r"""
461
+ Return the class' ID hash.
462
+
463
+ EXAMPLES::
464
+
465
+ sage: hash(graph_classes.Chordal) == hash(graph_classes.Chordal)
466
+ True
467
+ """
468
+ return hash(self._gc_id)
469
+
470
+ def __le__(self, other):
471
+ r"""
472
+ <= operator.
473
+
474
+ EXAMPLES::
475
+
476
+ sage: graph_classes.Chordal <= graph_classes.Tree
477
+ Unknown
478
+ """
479
+ return other >= self
480
+
481
+ def __ge__(self, other):
482
+ r"""
483
+ >= operator.
484
+
485
+ EXAMPLES::
486
+
487
+ sage: graph_classes.Chordal >= graph_classes.Tree
488
+ True
489
+ """
490
+ inclusion_digraph = GraphClasses().inclusion_digraph()
491
+ if inclusion_digraph.shortest_path(self._gc_id, other._gc_id):
492
+ return True
493
+ else:
494
+ return Unknown
495
+
496
+ def __eq__(self, other):
497
+ r"""
498
+ == operator.
499
+
500
+ EXAMPLES::
501
+
502
+ sage: graph_classes.Chordal == graph_classes.Tree
503
+ Unknown
504
+ """
505
+ return self >= other >= self
506
+
507
+ def __lt__(self, other):
508
+ r"""
509
+ >, !=, and < operators.
510
+
511
+ EXAMPLES::
512
+
513
+ sage: graph_classes.Chordal > graph_classes.Tree
514
+ Traceback (most recent call last):
515
+ ...
516
+ NotImplementedError
517
+ sage: graph_classes.Chordal < graph_classes.Tree
518
+ Traceback (most recent call last):
519
+ ...
520
+ NotImplementedError
521
+ sage: graph_classes.Chordal != graph_classes.Tree
522
+ Traceback (most recent call last):
523
+ ...
524
+ NotImplementedError
525
+ """
526
+ raise NotImplementedError
527
+
528
+ __gt__ = __ne__ = __lt__
529
+
530
+ def forbidden_subgraphs(self):
531
+ r"""
532
+ Return the list of forbidden induced subgraphs defining the class.
533
+
534
+ If the graph class is not defined by a *finite* list of forbidden
535
+ induced subgraphs, ``None`` is returned instead.
536
+
537
+ EXAMPLES::
538
+
539
+ sage: graph_classes.Perfect.forbidden_subgraphs()
540
+ sage: gc = graph_classes.get_class('gc_62')
541
+ sage: gc
542
+ claw--free graphs
543
+ sage: gc.forbidden_subgraphs()
544
+ [Graph on 4 vertices]
545
+ sage: gc.forbidden_subgraphs()[0].is_isomorphic(graphs.ClawGraph())
546
+ True
547
+ """
548
+ classes = GraphClasses().classes()
549
+ gc = classes[self._gc_id]
550
+
551
+ if gc.get("type", None) != "forbidden":
552
+ return None
553
+
554
+ excluded = gc.get("smallgraph", None)
555
+
556
+ if not excluded:
557
+ return None
558
+
559
+ if not isinstance(excluded, list):
560
+ excluded = [excluded]
561
+
562
+ smallgraphs = GraphClasses().smallgraphs()
563
+
564
+ if not all(g in smallgraphs for g in excluded):
565
+ return None
566
+
567
+ return [smallgraphs[g] for g in excluded]
568
+
569
+ def __contains__(self, g):
570
+ r"""
571
+ Check if ``g`` belongs to the graph class represented by ``self``.
572
+
573
+ EXAMPLES::
574
+
575
+ sage: graphs.CompleteBipartiteGraph(3,3) in graph_classes.Bipartite
576
+ True
577
+ sage: graphs.CompleteGraph(4) in graph_classes.Chordal
578
+ True
579
+ sage: graphs.CompleteGraph(4) in graph_classes.Comparability
580
+ True
581
+ sage: graphs.CompleteGraph(4) in graph_classes.Interval
582
+ True
583
+ sage: graphs.CompleteGraph(4) in graph_classes.Line
584
+ True
585
+ sage: graphs.CompleteGraph(4) in graph_classes.Perfect
586
+ True
587
+ sage: graphs.CompleteGraph(4) in graph_classes.Planar # needs planarity
588
+ True
589
+ sage: graphs.CompleteGraph(4) in graph_classes.Split
590
+ True
591
+ sage: graphs.PathGraph(4) in graph_classes.Tree
592
+ True
593
+ """
594
+ from sage.graphs.graph import Graph
595
+
596
+ if not isinstance(g, Graph):
597
+ return False
598
+
599
+ if hasattr(self, "_recognition_function"):
600
+ return self._recognition_function(g)
601
+
602
+ excluded = self.forbidden_subgraphs()
603
+
604
+ if excluded is None:
605
+ raise NotImplementedError("No recognition algorithm is available "
606
+ "for this class.")
607
+
608
+ for gg in excluded:
609
+ if g.subgraph_search(gg, induced=True):
610
+ return False
611
+
612
+ return True
613
+
614
+ def description(self):
615
+ r"""
616
+ Print the information of ISGCI about the current class.
617
+
618
+ EXAMPLES::
619
+
620
+ sage: graph_classes.Chordal.description()
621
+ Class of graphs : Chordal
622
+ -------------------------
623
+ id : gc_32
624
+ name : chordal
625
+ ...
626
+ Problems :
627
+ -----------
628
+ 3-Colourability : Linear
629
+ Clique : Polynomial
630
+ Clique cover : Polynomial
631
+ ...
632
+ Recognition : Linear
633
+ ...
634
+ """
635
+ classes = GraphClasses().classes()
636
+ cls = classes[self._gc_id]
637
+
638
+ print("Class of graphs : " + self._name)
639
+ print("-" * (len(self._name) + 18))
640
+
641
+ for key, value in sorted(cls.items()):
642
+ if value != "" and key != "problem":
643
+ print("{:30} : {}".format(key, value))
644
+
645
+ print("\nProblems :")
646
+ print("-" * 11)
647
+
648
+ for pbname, data in sorted(cls["problem"].items()):
649
+ if "complexity" in data:
650
+ print("{:30} : {}".format(pbname, data["complexity"]))
651
+
652
+
653
+ class GraphClasses(UniqueRepresentation):
654
+ def get_class(self, id):
655
+ r"""
656
+ Return the class corresponding to the given id in the ISGCI database.
657
+
658
+ INPUT:
659
+
660
+ - ``id`` -- string; the desired class' ID
661
+
662
+ .. SEEALSO::
663
+
664
+ :meth:`~sage.graphs.isgci.GraphClasses.show_all`
665
+
666
+ EXAMPLES:
667
+
668
+ With an existing id::
669
+
670
+ sage: Cographs = graph_classes.get_class("gc_151")
671
+ sage: Cographs
672
+ cograph graphs
673
+
674
+ With a wrong id::
675
+
676
+ sage: graph_classes.get_class(-1)
677
+ Traceback (most recent call last):
678
+ ...
679
+ ValueError: The given class id does not exist in the ISGCI database. Is the db too old ? You can update it with graph_classes.update_db().
680
+ """
681
+ classes = self.classes()
682
+ if id in classes:
683
+ c = classes[id]
684
+
685
+ if c.get("name", ""):
686
+ name = c["name"]
687
+ else:
688
+ name = "class " + str(id)
689
+
690
+ return GraphClass(name, id)
691
+ else:
692
+ raise ValueError("The given class id does not exist in the ISGCI "
693
+ "database. Is the db too old ? You can update it "
694
+ "with graph_classes.update_db().")
695
+
696
+ @cached_method
697
+ def classes(self):
698
+ r"""
699
+ Return the graph classes, as a dictionary.
700
+
701
+ Upon the first call, this loads the database from the local XML
702
+ file. Subsequent calls are cached.
703
+
704
+ EXAMPLES::
705
+
706
+ sage: t = graph_classes.classes()
707
+ sage: type(t)
708
+ <... 'dict'>
709
+ sage: sorted(t["gc_151"].keys())
710
+ ['id', 'name',... 'problem',... 'type']
711
+ sage: t["gc_151"]['name']
712
+ 'cograph'
713
+ sage: t["gc_151"]['problem']['Clique']
714
+ {'complexity': 'Linear'}
715
+ """
716
+ self._get_ISGCI()
717
+ return self.classes()
718
+
719
+ @cached_method
720
+ def inclusions(self):
721
+ r"""
722
+ Return the graph class inclusions.
723
+
724
+ OUTPUT: list of dictionaries
725
+
726
+ Upon the first call, this loads the database from the local XML file.
727
+ Subsequent calls are cached.
728
+
729
+ EXAMPLES::
730
+
731
+ sage: t = graph_classes.inclusions()
732
+ sage: type(t)
733
+ <... 'list'>
734
+ sage: t[0]
735
+ {'sub': 'gc_1', 'super': 'gc_2'}
736
+ """
737
+ self._get_ISGCI()
738
+ return self.inclusions()
739
+
740
+ @cached_method
741
+ def smallgraphs(self):
742
+ r"""
743
+ Return a dictionary associating a graph to a graph description string.
744
+
745
+ Upon the first call, this loads the database from the local XML files.
746
+ Subsequent calls are cached.
747
+
748
+ EXAMPLES::
749
+
750
+ sage: t = graph_classes.smallgraphs()
751
+ sage: t['2C_4']
752
+ Graph on 8 vertices
753
+ sage: t['2K_3 + e']
754
+ Graph on 6 vertices
755
+ sage: t['fish']
756
+ Graph on 6 vertices
757
+ sage: t['bull']
758
+ Graph on 5 vertices
759
+ """
760
+ self._get_ISGCI()
761
+ return self.smallgraphs()
762
+
763
+ @cached_method
764
+ def inclusion_digraph(self):
765
+ r"""
766
+ Return the class inclusion digraph.
767
+
768
+ Upon the first call, this loads the database from the local XML file.
769
+ Subsequent calls are cached.
770
+
771
+ EXAMPLES::
772
+
773
+ sage: g = graph_classes.inclusion_digraph(); g
774
+ Digraph on ... vertices
775
+ """
776
+ classes = self.classes()
777
+ inclusions = self.inclusions()
778
+
779
+ from sage.graphs.digraph import DiGraph
780
+ inclusion_digraph = DiGraph()
781
+ inclusion_digraph.add_vertices(classes.keys())
782
+
783
+ for edge in inclusions:
784
+ if edge.get("confidence", "") == "unpublished":
785
+ continue
786
+ inclusion_digraph.add_edge(edge['super'], edge['sub'])
787
+
788
+ return inclusion_digraph
789
+
790
+ def _download_db(self):
791
+ r"""
792
+ Download the current version of the ISGCI db.
793
+
794
+ EXAMPLES::
795
+
796
+ sage: graph_classes._download_db() # optional - internet
797
+ """
798
+ import tempfile
799
+ data_dir = os.path.dirname(DatabaseGraphs().absolute_filename())
800
+ u = urlopen('https://www.graphclasses.org/data.zip',
801
+ context=default_context())
802
+ with tempfile.NamedTemporaryFile(suffix='.zip') as f:
803
+ f.write(u.read())
804
+ z = zipfile.ZipFile(f.name)
805
+
806
+ # Save a systemwide updated copy whenever possible
807
+ try:
808
+ z.extract(_XML_FILE, data_dir)
809
+ z.extract(_SMALLGRAPHS_FILE, data_dir)
810
+ except OSError:
811
+ pass
812
+
813
+ def _parse_db(self):
814
+ r"""
815
+ Parse the ISGCI database and stores its content in ``self``.
816
+
817
+ EXAMPLES::
818
+
819
+ sage: graph_classes._parse_db()
820
+ """
821
+ import xml.etree.ElementTree as ET
822
+ from sage.graphs.graph import Graph
823
+
824
+ data_dir = os.path.dirname(DatabaseGraphs().absolute_filename())
825
+ xml_file = os.path.join(data_dir, _XML_FILE)
826
+ tree = ET.ElementTree(file=xml_file)
827
+ root = tree.getroot()
828
+ DB = _XML_to_dict(root)
829
+
830
+ classes = {c['id']: c for c in DB['GraphClasses']["GraphClass"]}
831
+ for c in classes.values():
832
+ c["problem"] = {pb.pop("name"): pb for pb in c["problem"]}
833
+
834
+ inclusions = DB['Inclusions']['incl']
835
+
836
+ # Parses the list of ISGCI small graphs
837
+ smallgraph_file = open(os.path.join(data_dir, _SMALLGRAPHS_FILE))
838
+ smallgraphs = {}
839
+
840
+ for line in smallgraph_file.readlines():
841
+ key, string = line.split("\t")
842
+ smallgraphs[key] = Graph(string)
843
+
844
+ smallgraph_file.close()
845
+
846
+ self.inclusions.set_cache(inclusions)
847
+ self.classes.set_cache(classes)
848
+ self.smallgraphs.set_cache(smallgraphs)
849
+
850
+ def update_db(self):
851
+ r"""
852
+ Update the ISGCI database by downloading the latest version from
853
+ internet.
854
+
855
+ This method downloads the ISGCI database from the website
856
+ `GraphClasses.org <http://www.graphclasses.org/>`_. It then extracts the
857
+ zip file and parses its XML content. The XML file is saved in the directory
858
+ controlled by the :class:`DatabaseGraphs` class (usually, ``$HOME/.sage/db``).
859
+
860
+ EXAMPLES::
861
+
862
+ sage: graph_classes.update_db() # optional - internet
863
+ Database downloaded
864
+ """
865
+ self._download_db()
866
+
867
+ print("Database downloaded")
868
+
869
+ self.classes.clear_cache()
870
+ self.inclusions.clear_cache()
871
+ self.inclusion_digraph.clear_cache()
872
+
873
+ def _get_ISGCI(self):
874
+ r"""
875
+ Return the contents of the ISGCI database.
876
+
877
+ This method is mostly for internal use, but often provides useful
878
+ information during debugging operations.
879
+
880
+ OUTPUT:
881
+
882
+ A pair ``(classes, inclusions)`` where ``classes`` is a dict of dict,
883
+ and ``inclusions`` is a list of dicts.
884
+
885
+ .. NOTE::
886
+
887
+ This method returns the data contained in the most recent ISGCI
888
+ database present on the computer. See :meth:`update_db` to update
889
+ the latter.
890
+
891
+ EXAMPLES::
892
+
893
+ sage: graph_classes._get_ISGCI() # long time (4s on sage.math, 2012)
894
+ """
895
+ self._parse_db()
896
+
897
+ def show_all(self):
898
+ r"""
899
+ Print all graph classes stored in ISGCI.
900
+
901
+ EXAMPLES::
902
+
903
+ sage: graph_classes.show_all()
904
+ id | name | type | smallgraph
905
+ ----------------------------------------------------------------------------------------------------------------------
906
+ gc_309 | $K_4$--minor--free | base |
907
+ gc_541 | $N^*$ | base |
908
+ gc_215 | $N^*$--perfect | base |
909
+ gc_5 | $P_4$--bipartite | base |
910
+ gc_3 | $P_4$--brittle | base |
911
+ gc_6 | $P_4$--comparability | base |
912
+ gc_7 | $P_4$--extendible | base |
913
+ ...
914
+ """
915
+ classes = self.classes()
916
+
917
+ # We want to print the different fields, and this dictionary stores the
918
+ # maximal number of characters of each field.
919
+ MAX = {
920
+ "id": 0,
921
+ "type": 0,
922
+ "smallgraph": 0,
923
+ "name": 0
924
+ }
925
+
926
+ # We sort the classes alphabetically, though we would like to display
927
+ # the meaningful classes at the top of the list
928
+ def sort_key(x):
929
+ name = x.get("name", "zzzzz")
930
+ return "{}{:4}".format(name, int(x["id"].split('_')[1]))
931
+
932
+ classes_list = sorted(classes.values(), key=sort_key)
933
+
934
+ # Maximum width of a field
935
+ MAX_LEN = 40
936
+
937
+ # Computing the max of each field with the database
938
+ for key in MAX:
939
+ MAX[key] = len(max((str(x.get(key, "")) for x in classes_list), key=len))
940
+
941
+ # At most MAX characters per field
942
+ for key, length in MAX.items():
943
+ MAX[key] = min(length, MAX_LEN)
944
+
945
+ # Head of the table
946
+ st = ("{:" + str(MAX["id"]) + "}").format("id")
947
+ st += (" | {:" + str(MAX["name"]) + "}").format("name")
948
+ st += (" | {:" + str(MAX["type"]) + "}").format("type")
949
+ st += (" | {:" + str(MAX["smallgraph"]) + "}").format("smallgraph")
950
+ print(st)
951
+ print("-" * (sum(MAX.values())+9))
952
+
953
+ # Entries
954
+ for entry in classes_list:
955
+ ID = entry.get("id", "")
956
+ name = entry.get("name", "")
957
+ typ = entry.get("type", "")
958
+ smallgraph = entry.get("smallgraph", "")
959
+ st = ("{:" + str(MAX["id"]) + "}").format(ID)
960
+ st += (" | {:" + str(MAX["name"]) + "}").format(name[:MAX_LEN])
961
+ st += (" | {:" + str(MAX["type"]) + "}").format(typ[:MAX_LEN])
962
+ st += " | " + str(smallgraph)[:MAX_LEN]
963
+ print(st)
964
+
965
+
966
+ def _XML_to_dict(root):
967
+ r"""
968
+ Return the XML data as a dictionary.
969
+
970
+ INPUT:
971
+
972
+ - ``root`` -- an ``xml.etree.cElementTree.ElementTree`` object
973
+
974
+ OUTPUT: a dictionary representing the XML data
975
+
976
+ EXAMPLES::
977
+
978
+ sage: graph_classes.Perfect.description() # indirect doctest
979
+ Class of graphs : Perfect
980
+ -------------------------
981
+ id : gc_56
982
+ name : perfect
983
+ ...
984
+ """
985
+ ans = root.attrib.copy()
986
+ for child in root:
987
+ if child.tag in ans:
988
+ if not isinstance(ans[child.tag], list):
989
+ ans[child.tag] = [ans[child.tag]]
990
+ ans[child.tag].append(_XML_to_dict(child))
991
+ else:
992
+ ans[child.tag] = _XML_to_dict(child)
993
+
994
+ # If the dictionary is empty, perhaps the only content is a text, and we
995
+ # return this instead. Useful sometimes in the ISGCI db, for graph names.
996
+ if not ans:
997
+ return root.text
998
+ return ans
999
+
1000
+
1001
+ graph_classes = GraphClasses()
1002
+
1003
+ # Any object added to this list should also appear in the class' documentation, at the top of the file.
1004
+ graph_classes.Apex = GraphClass("Apex", "gc_1181", recognition_function=lambda x: x.is_apex())
1005
+ graph_classes.AT_free = GraphClass("AT-free", "gc_61", recognition_function=lambda x: x.is_asteroidal_triple_free())
1006
+ graph_classes.Biconnected = GraphClass("Biconnected", "gc_771", recognition_function=lambda x: x.is_biconnected())
1007
+ graph_classes.BinaryTrees = GraphClass("BinaryTrees", "gc_847")
1008
+ graph_classes.Bipartite = GraphClass("Bipartite", "gc_69", recognition_function=lambda x: x.is_bipartite())
1009
+ graph_classes.Block = GraphClass("Block", "gc_93", recognition_function=lambda x: x.is_block_graph())
1010
+ graph_classes.Cactus = GraphClass("Cactus", "gc_108", recognition_function=lambda x: x.is_cactus())
1011
+ graph_classes.Chordal = GraphClass("Chordal", "gc_32", recognition_function=lambda x: x.is_chordal())
1012
+ graph_classes.ClawFree = GraphClass("Claw-free", "gc_62")
1013
+ graph_classes.CoGraph = GraphClass("CoGraph", "gc_151", recognition_function=lambda x: x.is_cograph())
1014
+ graph_classes.Comparability = GraphClass("Comparability", "gc_72", recognition_function=lambda x: x.is_comparability())
1015
+ graph_classes.DistanceRegular = GraphClass("Distance Regular", "gc_1148", recognition_function=lambda x: x.is_distance_regular())
1016
+ graph_classes.Gallai = GraphClass("Gallai", "gc_73")
1017
+ graph_classes.Grid = GraphClass("Grid", "gc_464")
1018
+ graph_classes.Hamiltonian = GraphClass("Hamiltonian", "gc_1092", recognition_function=lambda x: x.is_hamiltonian())
1019
+ graph_classes.Interval = GraphClass("Interval", "gc_234", recognition_function=lambda x: x.is_interval())
1020
+ graph_classes.Line = GraphClass("Line", "gc_249", recognition_function=lambda x: x.is_line_graph())
1021
+ graph_classes.Modular = GraphClass("Modular", "gc_50")
1022
+ graph_classes.Outerplanar = GraphClass("Outerplanar", "gc_110")
1023
+ graph_classes.Perfect = GraphClass("Perfect", "gc_56", recognition_function=lambda x: x.is_perfect())
1024
+ graph_classes.Permutation = GraphClass("Permutation", "gc_23", recognition_function=lambda x: x.is_permutation())
1025
+ graph_classes.Planar = GraphClass("Planar", "gc_43", recognition_function=lambda x: x.is_planar())
1026
+ graph_classes.Polyhedral = GraphClass("Polyhedral", "gc_986", recognition_function=lambda x: x.is_polyhedral())
1027
+ graph_classes.Split = GraphClass("Split", "gc_39", recognition_function=lambda x: x.is_split())
1028
+ graph_classes.StronglyRegular = GraphClass("Strongly Regular", "gc_1185", recognition_function=lambda x: x.is_strongly_regular())
1029
+ graph_classes.Tree = GraphClass("Tree", "gc_342", recognition_function=lambda x: x.is_tree())
1030
+ graph_classes.TriangleFree = GraphClass("Triangle Free", "gc_371", recognition_function=lambda x: x.is_triangle_free())
1031
+ graph_classes.UnitDisk = GraphClass("UnitDisk", "gc_389")
1032
+ graph_classes.UnitInterval = GraphClass("UnitInterval", "gc_299")
1033
+ graph_classes.WeaklyChordal = GraphClass("Weakly Chordal", "gc_14", recognition_function=lambda x: x.is_weakly_chordal())