Skip to content

Conversation

eumiro
Copy link
Contributor

@eumiro eumiro commented Apr 4, 2025

I realized the lexicographical_topological_sort method does not raise DAGHasCycle if it gets a graph with cycles. It just ignores the participating nodes and returns the rest.

For instance:

G = rx.PyDiGraph()
G.add_nodes_from(["A", "B"])
G.add_edges_from_no_data([(0, 1), (1, 0)])
rx.lexicographical_topological_sort(G, key=str)

returns an empty list.

I tried to add a check into the code, but did not succeed. The test in would be:

tests/digraph/test_nodes.py (line 611)

    def test_lexicographical_topological_sort_with_cycle(self):
        G = rustworkx.PyDiGraph()
        G.add_nodes_from(("A", "B"))
        G.add_edges_from_no_data(((0, 1), (1, 0)))
        self.assertRaises(rustworkx.DAGHasCycle, rustworkx.lexicographical_topological_sort, G, str)

Copy link
Collaborator

@IvanIsCoding IvanIsCoding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is blocked until I merge a fix for clippy lints, which hopefully is soon

Copy link
Collaborator

@IvanIsCoding IvanIsCoding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM with a minor caveat

Comment on lines 362 to 363
/// >>> G.add_nodes_from(["A", "B", "C", "D", "E", "F", "G"])
/// >>> G.add_edges_from_no_data([(0, 6), (1, 6), (2, 6), (3, 6), (4, 6), (5, 6)])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpicking, but you can unpack this as:

a, b, c, d, e, f, g = .add_nodes_from(["A", "B", "C", "D", "E", "F", "G"])

And then do e.g. edges_from_no_data[(a, g)...]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this case it seems to be useful. Updated, thanks.

/// :param PyDiGraph graph: The DAG to get the topological generations from
/// >>> G = rx.PyDiGraph()
/// >>> G.add_nodes_from([0, 1, 2, 3, 4])
/// >>> G.add_edges_from_no_data([(0, 1), (0, 2), (1, 3), (2, 3), (3, 4)])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same as below. Here even more: perfectly matching numbers only.

///
/// >>> G = rx.PyDiGraph()
/// >>> G.add_nodes_from(["A", "B", "C", "D", "E", "F", "G"])
/// >>> G.add_edges_from_no_data([(0, 1),(1, 2), (2, 3), (3, 4), (5, 2), (6, 3)])
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is true for many of other examples and I'll be happy to update them later.

However, since this method returns a numerical list of indices NodeIndices[6, 5, 0, 1, 2, 3, 4], I find it easier for the reader to match these numbers and the arguments to add_edges_from_no_data.

@IvanIsCoding
Copy link
Collaborator

And about raising an error: that would probably be the correct behaviour. It should be pretty easy to check after the fact as well, if the rustworxk-core lexicographical topological sort did not return all the nodes we'd raise.

@coveralls
Copy link

coveralls commented Apr 5, 2025

Pull Request Test Coverage Report for Build 14289021126

Details

  • 0 of 0 changed or added relevant lines in 0 files are covered.
  • No unchanged relevant lines lost coverage.
  • Overall coverage remained the same at 95.34%

Totals Coverage Status
Change from base Build 14284910943: 0.0%
Covered Lines: 18515
Relevant Lines: 19420

💛 - Coveralls

@eumiro eumiro force-pushed the topological-sorts branch 2 times, most recently from 5c65617 to c3baa27 Compare April 5, 2025 04:55
@eumiro
Copy link
Contributor Author

eumiro commented Apr 5, 2025

And about raising an error: that would probably be the correct behaviour. It should be pretty easy to check after the fact as well, if the rustworxk-core lexicographical topological sort did not return all the nodes we'd raise.

Actually, it is unfortunately correct, as it is. Because of the optional initial argument, we cannot expect to have all nodes of the graph returned. And with initial, it will “only include those nodes and any nodes that are dominated by them”, so the rest should not be tested for cycles at all.

@IvanIsCoding
Copy link
Collaborator

Just FYI, I think the error from the CI is actionable:

/home/runner/work/rustworkx/rustworkx/.nox/docs-3/lib/python3.10/site-packages/rustworkx/__init__.py:docstring of rustworkx.topological_generations:16:Unknown interpreted text role "cls".

If the fix is trivial, I can try patching it after I merge #1403

@eumiro eumiro force-pushed the topological-sorts branch from c3baa27 to 0ef6e00 Compare April 6, 2025 04:28
@eumiro eumiro force-pushed the topological-sorts branch from 0ef6e00 to ba25dd2 Compare April 6, 2025 04:32
@IvanIsCoding
Copy link
Collaborator

Once https://status.coveralls.io/ is back we should be able to merge this

@IvanIsCoding IvanIsCoding added this to the 0.17.0 milestone Apr 6, 2025
@IvanIsCoding IvanIsCoding enabled auto-merge April 6, 2025 23:25
@IvanIsCoding IvanIsCoding added this pull request to the merge queue Apr 6, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 7, 2025
@IvanIsCoding IvanIsCoding added this pull request to the merge queue Apr 7, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 7, 2025
@IvanIsCoding IvanIsCoding added this pull request to the merge queue Apr 7, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 7, 2025
@IvanIsCoding IvanIsCoding added this pull request to the merge queue Apr 7, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 7, 2025
@IvanIsCoding IvanIsCoding added this pull request to the merge queue Apr 7, 2025
@IvanIsCoding IvanIsCoding removed this pull request from the merge queue due to a manual request Apr 7, 2025
@IvanIsCoding IvanIsCoding added this pull request to the merge queue Apr 7, 2025
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Apr 7, 2025
@IvanIsCoding IvanIsCoding added this pull request to the merge queue Apr 7, 2025
Merged via the queue into Qiskit:main with commit 51b7c72 Apr 7, 2025
31 checks passed
@eumiro eumiro deleted the topological-sorts branch April 7, 2025 17:07
SILIZ4 pushed a commit to SILIZ4/rustworkx that referenced this pull request Jul 4, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants