Skip to content

Commit a42986d

Browse files
author
Release Manager
committed
gh-39932: add parameter immutable to method `is_planar` Add parameter immutable to method `is_planar` to control the returned Kuratowski subgraphs. This is also related to discussions in #39177, i.e., ensure a correct behavior with immutable graphs. ### 📝 Checklist <!-- Put an `x` in all the boxes that apply. --> - [x] The title is concise and informative. - [x] The description explains in detail what this PR is about. - [x] I have linked a relevant issue or discussion. - [x] I have created tests covering the changes. - [ ] I have updated the documentation and checked the documentation preview. ### ⌛ Dependencies <!-- List all open PRs that this PR logically depends on. For example, --> <!-- - #12345: short description why this is a dependency --> <!-- - #34567: ... --> URL: #39932 Reported by: David Coudert Reviewer(s): David Coudert, Frédéric Chapoton
2 parents 23f4309 + 5553bd3 commit a42986d

File tree

2 files changed

+51
-6
lines changed

2 files changed

+51
-6
lines changed

src/sage/graphs/generic_graph.py

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5742,7 +5742,8 @@ def minimum_cycle_basis(self, algorithm=None, weight_function=None, by_weight=Fa
57425742

57435743
# Planarity
57445744

5745-
def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, set_pos=False):
5745+
def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False,
5746+
set_pos=False, immutable=None):
57465747
r"""
57475748
Check whether the graph is planar.
57485749

@@ -5796,6 +5797,11 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se
57965797
set to False. Also, the position dictionary will only be updated if a
57975798
planar embedding is found.
57985799

5800+
- ``immutable`` -- boolean (default: ``None``); whether to create a
5801+
mutable/immutable graph. ``immutable=None`` (default) means that the
5802+
graph and the Kuratowski subgraph will behave the same way.
5803+
This parameter is ignored when ``kuratowski=False``.
5804+
57995805
EXAMPLES::
58005806

58015807
sage: g = graphs.CubeGraph(4)
@@ -5956,6 +5962,21 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se
59565962
True
59575963
sage: Graph(1).is_planar()
59585964
True
5965+
5966+
Check the behavior of parameter ``immutable``::
5967+
5968+
sage: G = graphs.PetersenGraph()
5969+
sage: G.is_planar(kuratowski=True)
5970+
(False, Kuratowski subgraph of (Petersen graph): Graph on 9 vertices)
5971+
sage: G.is_planar(kuratowski=True)[1].is_immutable()
5972+
False
5973+
sage: G.is_planar(kuratowski=True, immutable=True)[1].is_immutable()
5974+
True
5975+
sage: G = G.copy(immutable=True)
5976+
sage: G.is_planar(kuratowski=True)[1].is_immutable()
5977+
True
5978+
sage: G.is_planar(kuratowski=True, immutable=False)[1].is_immutable()
5979+
False
59595980
"""
59605981
# Quick check first
59615982
if (on_embedding is None and not kuratowski and not set_embedding and not set_pos
@@ -5979,10 +6000,11 @@ def is_planar(self, on_embedding=None, kuratowski=False, set_embedding=False, se
59796000
return (0 == self.genus(minimal=False, set_embedding=False, on_embedding=on_embedding))
59806001

59816002
# We take the underlying undirected and simple graph
5982-
G = self.to_simple(to_undirected=True, immutable=False)
6003+
G = self.to_simple(to_undirected=True)
59836004
# And check if it is planar
59846005
from sage.graphs.planarity import is_planar
5985-
planar = is_planar(G, kuratowski=kuratowski, set_pos=set_pos, set_embedding=set_embedding)
6006+
planar = is_planar(G, kuratowski=kuratowski, set_pos=set_pos,
6007+
set_embedding=set_embedding, immutable=immutable)
59866008
if kuratowski:
59876009
bool_result = planar[0]
59886010
else:

src/sage/graphs/planarity.pyx

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ cdef extern from "planarity/graph.h":
3030
cdef int gp_SortVertices(graphP theGraph)
3131

3232

33-
def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False):
33+
def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False, immutable=None):
3434
r"""
3535
Check whether ``g`` is planar using Boyer's planarity algorithm.
3636
@@ -55,6 +55,11 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False):
5555
combinatorial embedding returned (see
5656
:meth:`~sage.graphs.generic_graph.GenericGraph.get_embedding`)
5757
58+
- ``immutable`` -- boolean (default: ``None``); whether to create a
59+
mutable/immutable graph. ``immutable=None`` (default) means that
60+
the graph and the Kuratowski subgraph will behave the same way.
61+
This parameter is ignored when ``kuratowski=False``.
62+
5863
EXAMPLES::
5964
6065
sage: G = graphs.DodecahedralGraph()
@@ -94,6 +99,21 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False):
9499
....: assert is_planar(G, set_embedding=set_embedding, set_pos=set_pos)
95100
....: assert (hasattr(G, '_embedding') and G._embedding is not None) == set_embedding, (set_embedding, set_pos)
96101
....: assert (hasattr(G, '_pos') and G._pos is not None) == set_pos, (set_embedding, set_pos)
102+
103+
Check the behavior of parameter ``immutable``::
104+
105+
sage: G = graphs.PetersenGraph()
106+
sage: G.is_planar(kuratowski=True)
107+
(False, Kuratowski subgraph of (Petersen graph): Graph on 9 vertices)
108+
sage: G.is_planar(kuratowski=True)[1].is_immutable()
109+
False
110+
sage: G.is_planar(kuratowski=True, immutable=True)[1].is_immutable()
111+
True
112+
sage: G = G.copy(immutable=True)
113+
sage: G.is_planar(kuratowski=True)[1].is_immutable()
114+
True
115+
sage: G.is_planar(kuratowski=True, immutable=False)[1].is_immutable()
116+
False
97117
"""
98118
g._scream_if_not_simple()
99119
if set_pos and not g.is_connected():
@@ -137,7 +157,7 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False):
137157
gp_Free(&theGraph)
138158
return False
139159
# With just the current edges, we have a nonplanar graph,
140-
# so to isolate a kuratowski subgraph, just keep going.
160+
# so to isolate a Kuratowski subgraph, just keep going.
141161
break
142162

143163
status = gp_Embed(theGraph, EMBEDFLAGS_PLANAR)
@@ -161,11 +181,14 @@ def is_planar(g, kuratowski=False, set_pos=False, set_embedding=False):
161181
j = theGraph.E[j].link[1]
162182
if linked_list:
163183
g_dict[to[i]] = linked_list
184+
if immutable is None:
185+
immutable = g.is_immutable()
164186
gp_Free(&theGraph)
165187
G = g.__class__(data=g_dict, weighted=g._weighted,
166188
loops=g.allows_loops(),
167189
multiedges=g.allows_multiple_edges(),
168-
name="Kuratowski subgraph of (%s)" % g.name())
190+
name="Kuratowski subgraph of (%s)" % g.name(),
191+
immutable=immutable)
169192
if g.get_pos():
170193
G.set_pos({u: g._pos[u] for u in g_dict})
171194
return (False, G)

0 commit comments

Comments
 (0)