Skip to content

Calling get_embedding() on subgraph of immutable graph results in LookupError #40054

@Ordoviz

Description

@Ordoviz

Steps To Reproduce

Paste this into a sage shell (e.g. via docker run -it sagemath/sagemath:9.7 sage):

G = Graph('A_', immutable=True)
G.set_embedding({0: [1], 1: [0]})
H = G.subgraph([0])
# assert H._embedding == {0: [1]}  # but vertex 1 does not exist in H
H.get_embedding() # LookupError

Expected Behavior

H.get_embedding() returns {0: []} or None without errors. The output stays the same if you change immutable=True to immutable=False.

Actual Behavior

If you change immutable=True to immutable=False, it returns {0: []}. Otherwise it produces an error:

$ sage
┌────────────────────────────────────────────────────────────────────┐
│ SageMath version 10.7.beta2, Release Date: 2025-04-29              │
│ Using Python 3.13.3. Type "help()" for help.                       │
└────────────────────────────────────────────────────────────────────┘
┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
┃ Warning: this is a prerelease version, and it may be unstable.     ┃
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┛
sage: G = Graph('A_', immutable=True)
....: G.set_embedding({0: [1], 1: [0]})
....: H = G.subgraph([0])
....: # assert H._embedding == {0: [1]}  # but vertex 1 does not exist in H
....: H.get_embedding() # LookupError
....: 
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
File /usr/lib/python3.13/site-packages/sage/graphs/base/static_sparse_backend.pyx:834, in sage.graphs.base.static_sparse_backend.StaticSparseBackend.has_edge (build/cythonized/sage/graphs/base/static_sparse_backend.c:20795)()
    833     u = self._vertex_to_int[u]
--> 834     v = self._vertex_to_int[v]
    835 except KeyError:

KeyError: 1

During handling of the above exception, another exception occurred:

LookupError                               Traceback (most recent call last)
Cell In[1], line 5
      3 H = G.subgraph([Integer(0)])
      4 # assert H._embedding == {0: [1]}  # but vertex 1 does not exist in H
----> 5 H.get_embedding() # LookupError

File /usr/lib/python3.13/site-packages/sage/graphs/generic_graph.py:3339, in GenericGraph.get_embedding(self)
   3337 while i < len(embedding[u]):
   3338     v = embedding[u][i]
-> 3339     if not (self.has_edge(u, v) or self.has_edge(v, u)):
   3340         del embedding[u][i]
   3341     else:

File /usr/lib/python3.13/site-packages/sage/graphs/generic_graph.py:13264, in GenericGraph.has_edge(self, u, v, label)
  13262             u, v = u
  13263             label = None
> 13264 return self._backend.has_edge(u, v, label)

File /usr/lib/python3.13/site-packages/sage/graphs/base/static_sparse_backend.pyx:836, in sage.graphs.base.static_sparse_backend.StaticSparseBackend.has_edge (build/cythonized/sage/graphs/base/static_sparse_backend.c:20841)()
    834     v = self._vertex_to_int[v]
    835 except KeyError:
--> 836     raise LookupError("one of the two vertices does not belong to the graph")
    837 
    838 return self._has_labeled_edge_unsafe(u, v, l)

LookupError: one of the two vertices does not belong to the graph

Additional Information

The embedding was produced by is_circular_planar().

Environment

  • OS: Arch Linux
  • Sage Version: 10.7.beta2

The behavior changed between Sage v9.6 and v9.7: In Sage v9.6, a more helpful error was produced "ValueError: Subgraph of () has been modified and the embedding is no longer valid". I think commit 36ffb23 by @videlec introduced the current behavior where the embedding is copied to the subgraph, see #33760.

Checklist

  • I have searched the existing issues for a bug report that matches the one I want to file, without success.
  • I have read the documentation and troubleshoot guide

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions