Skip to content

Fix GraphicMatroid.is_isomorphic ground set size check - #42574

Open
gouravchahar13 wants to merge 3 commits into
sagemath:developfrom
gouravchahar13:fix-graphic-matroid-isomorphism
Open

Fix GraphicMatroid.is_isomorphic ground set size check#42574
gouravchahar13 wants to merge 3 commits into
sagemath:developfrom
gouravchahar13:fix-graphic-matroid-isomorphism

Conversation

@gouravchahar13

@gouravchahar13 gouravchahar13 commented Jul 24, 2026

Copy link
Copy Markdown

This PR resolves #42556

Summary

Added an early check to GraphicMatroid._is_isomorphic to compare ground set sizes before testing for graph isomorphism.

Problem

GraphicMatroid._is_isomorphic simplifies underlying graphs by removing multiple edges and loops when comparing against a 3-connected graphic matroid. Because of this, M.is_isomorphic(M2) returned True even when M had more edges than M2 (e.g., $K_4$ with a parallel edge vs standard $K_4$).

Changes

  • Added an explicit self.size() != other.size() check at the top of _is_isomorphic.
  • Added a regression doctest covering this case in GraphicMatroid._is_isomorphic.

📝 Checklist

  • The title is concise and informative.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation and checked the documentation preview.

⌛ Dependencies

None

@gouravchahar13

Copy link
Copy Markdown
Author

@gmou3 Please Review this and add it

@gmou3

gmou3 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

I don't think this check suffices. You may have the same size, but non-isomorphic matroids before simplification.

@gouravchahar13

Copy link
Copy Markdown
Author

On it

@slnkno3

slnkno3 commented Jul 25, 2026

Copy link
Copy Markdown

This doesn't work if the ground set has size <4, see for example:

K = Graph(multiedges=True)
K.add_vertices(range(2))
K.add_edges([(0,1),(0,1)])
M1 = Matroid(K)

print(M1.is_3connected())

G = Graph(multiedges=True, loops=true)
G.add_vertices(range(2))
G.add_edges([(0,1),(0,0)])
M2 = Matroid(G)

print(M1.size(), M2.size())
print(M1.is_isomorphic(M2))
print(M2.is_isomorphic(M1))

Your fix should work as long as the ground set of M1 has size >= 4. By Oxley's Matroid Theory (2011), Proposition 8.1.9, a graph G with no isolated vertices and |E(G)| >= 4 has M(G) 3-connected iff G is simple and 3-connected. So if other is
3-connected with |E| >= 4, its graph is already simple and 3-connected, and dropping loops/multiedges does nothing.
If the ground sets also had the same size to begin with and the graphs come out isomorphic, then the graph of self had the same edge count as that simple graph, so it was simple too. Whitney's 2-isomorphism theorem then says: a loopless 3-connected graph is determined up to isomorphism by its cycle matroid (there are no non-trivial Whitney twists for a 3-connected graph, see page 146 in Oxley), so the matroids are isomorphic iff the graphs are. So adding a check that the ground set has size >= 4 should probaby fix it.

Or, instead of testing matroid connectivity, you could just test the corresponding graphs
directly for looplessness and vertex-3-connectivity (where 3-connected means kappa(G) >= 3,multiple edges are allowed).

  • If both graphs are loopless and 3-connected: by Whitney they are isomorphic
    iff their matroids are, so we just compare the graphs directly.
  • If exactly one is loopless and 3-connected and the other is not: their
    matroids can't be isomorphic.
  • If neither is loopless and 3-connected: fall back to the general matroid
    isomorphism test.

I hope this works out mathematically, I think it does but I'm not fully sure, and I also don't know which version would be more efficient.

@gmou3

gmou3 commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

@slnkno3 I think the 3 bullet-point approach is correct (@gouravchahar13 can you implement this?).

A nice idea for a future PR: implement an is_2isomorphic function for graphs.
This will help us avoid the suboptimal fallback of the general case.

@gouravchahar13

Copy link
Copy Markdown
Author

@slnkno3 I think the 3 bullet-point approach is correct (@gouravchahar13 can you implement this?).

A nice idea for a future PR: implement an is_2isomorphic function for graphs.
This will help us avoid the suboptimal fallback of the general case.

Yes , I have started already

@dcoudert

Copy link
Copy Markdown
Collaborator

A nice idea for a future PR: implement an is_2isomorphic function for graphs. This will help us avoid the suboptimal fallback of the general case.

What's the definition of 2isomorphic ?

@slnkno3

slnkno3 commented Jul 26, 2026

Copy link
Copy Markdown

What's the definition of 2isomorphic ?

@dcoudert Two graphs are 2-isomorphic if one graph can be transformed into the other by a sequence of three types of operations: vertex identification (when the vertices belong to different components), vertex cleaving (when the vertex is a cut vertex), and twisting (also called Whitney twists).

Vertex identification can be used to make a disconnected graph connected, while vertex cleaving can reverse this operation when a cut vertex is present.

A Whitney twist is performed on a graph with a 2-vertex cut. Let u and v be the two vertices of this cut. We split the graph at these vertices, replacing u by two vertices u_1,u_2 and v by two vertices v_1,v_2, thereby separating the graph into two parts. Instead of identifying the vertices back in the original way, we interchange the identifications: we identify u_1 with v_2 and u_2 with v_1. An example of this twisting and the definition of 2-isomorphism can be found in Oxley's Matroid Theory,
Chapter 5.3.

Whitney's 2-isomorphism theorem states that two graphs have the same graphic matroid if and only if they are 2-isomorphic.
We perform the check for 3-connectivity as above because a 3-connected graph does not admit vertex identification, vertex cleaving, or Whitney twists. Therefore, a 3-connected graph uniquely determines its graphic matroid.

@gouravchahar13

Copy link
Copy Markdown
Author

@slnkno3 @gmou3 I have updated the implementation, apart from the previous ground set size check (self.size() != other.size()) at the start I have added explicit invariant checks (loops and simplified matroid sizes) to handle small ground sets (E < 4) directly.
Also all local doctests pass with ./sage -t src/sage/matroids/graphic_matroid.pyx

@gmou3

gmou3 commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

I would recommend implementing the following approach (as suggested by @slnkno3), which seems more straightforward to me, and avoids the |E| < 4 case:

* If both graphs are loopless and 3-connected: by Whitney they are isomorphic
  iff their matroids are, so we just compare the graphs directly.

* If exactly one is loopless and 3-connected and the other is not: their
  matroids can't be isomorphic.

* If neither is loopless and 3-connected: fall back to the general matroid
  isomorphism test.

The overall structure would look something like this:

[size check]

if [other is also a GraphicMatroid]:
    [...]
    if [both loopless and 3-connected]:
        [direct isomorphism test between the graphs]
    elif [one loopless and 3-connected]:
        return False
    
# Fallback - general matroid isomorphism test
[...]

@gouravchahar13

gouravchahar13 commented Jul 29, 2026

Copy link
Copy Markdown
Author

@gmou3 Sure I will follow this and update the code then Thanks for the guidance, Also happy gurupurnima in india it is basically a festival to show respect to your gurus. @slnkno3 Happy gurupurnima

@gouravchahar13

Copy link
Copy Markdown
Author

@slnkno3 @gmou3 added the refactoring

@github-actions

github-actions Bot commented Aug 2, 2026

Copy link
Copy Markdown

Documentation preview for this PR (built with commit 3a68466; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

GraphicMatroid.is_isomorphic gives asymmetric/incorrect result with multiedges

4 participants