Add diff highlighting for proof step differences in the graph view#435
Add diff highlighting for proof step differences in the graph view#435Kitsunp wants to merge 19 commits intozxcalc:masterfrom
Conversation
|
Hi, thanks for the PR. I have started testing it, and it seems that incorrect vertices and edges are being highlighted with simple rewrites: Screen.Recording.2026-02-17.at.15.18.56.mov |
|
Thanks for catching this @boldar99! I tracked down the root cause. Display graph: replaced get_graph() with copy.deepcopy() which preserves the original vertex IDs exactly (consistent with how every other graph-copy in the codebase works).
|
|
Thanks for the update. It seems you have accidentally run some automated formatting on the entire codebase. Please undo this. I have done some more testing. Fusion definitely looks a lot nicer, but it is still a bit odd. In particular, when two spiders are fused, it is the nodes and the connecting edge that should be highlighted. Same when un-fusing, then the spider that is being transformed. Screen.Recording.2026-02-18.at.14.21.56.mov |
|
Hi @Kitsunp, in addition to the request to revert all unnecessary formatting changes to unrelated files to this issue, I tested both the fusion and the "Unfuse spider" rules in your latest commit and found the highlighting to still not be as intended. As Boldi described above:
and likewise for the "Unfuse spider" rule. |
|
@lia-approves Currently, the latest changes are specific to the code. I did not rewrite the format. The previous formatting correction I had made was expressed so that what is currently visible refers to the current code, and I relied on mypy for some corrections, but I will also look into the mentioned issue. |
|
Hi @Kitsunp unfortunately there are many changes not related to the issue. For you convenience, I have highlighted some of them below. |
| import pytest | ||
| # import pytest | ||
| from datetime import datetime, timedelta | ||
| from unittest.mock import Mock, patch |
There was a problem hiding this comment.
why are these lines commented out?
zxlive/animations.py
Outdated
| QEasingCurve(QEasingCurve.Type.OutQuad)) | ||
|
|
||
| return anim_before, anim_after | ||
| return anim_before, anim_after No newline at end of file |
There was a problem hiding this comment.
blank line removed here
zxlive/common.py
Outdated
| if _type is bool: | ||
| val = str(val) == "True" or str(val) == "true" | ||
| if _type == int: | ||
| if _type is int: | ||
| val = int(str(val)) | ||
| if _type == float: | ||
| if _type is float: |
There was a problem hiding this comment.
why do you change "==" to "is"?
There was a problem hiding this comment.
all the changes in this file are not related to the diff highlighting for proof steps
There was a problem hiding this comment.
all the changes in this file are not related to the diff highlighting for proof steps
zxlive/eitem.py
Outdated
|
|
||
| if self.refresh: | ||
| self.it.refresh() | ||
| self.it.refresh() No newline at end of file |
There was a problem hiding this comment.
new line at the end of file removed
zxlive/graphscene.py
Outdated
| @staticmethod | ||
| def _phases_semantically_equal(old_phase: object, new_phase: object) -> bool: | ||
| """Check whether two phase values represent the same rotation. | ||
|
|
||
| ``GraphDiff`` compares phases with Python's ``!=`` operator which | ||
| is sensitive to representation: ``Fraction(1, 4) != 0.25`` is | ||
| ``True`` even though both encode the same angle. This helper | ||
| converts both values to ``float`` and compares with a small | ||
| tolerance so that purely representational differences (e.g. | ||
| ``Fraction`` vs ``float``) do not produce false‑positive | ||
| highlights. | ||
|
|
||
| For symbolic phases (``Poly`` objects or other non‑numeric types) | ||
| the function falls back to exact equality, which is the correct | ||
| behaviour since we cannot numerically evaluate free variables. | ||
| """ | ||
| try: | ||
| return abs(float(old_phase) - float(new_phase)) < 1e-12 # type: ignore[arg-type] | ||
| except (TypeError, ValueError): | ||
| # Symbolic / non-numeric phases — fall back to exact equality | ||
| return old_phase == new_phase |
There was a problem hiding this comment.
I don't think this is necessary and it's best handled by PyZX rather than ZXLive. In ZXLive, we do not use float angles, they are always converted to Fractions.
There was a problem hiding this comment.
all the changes in this file are not related to the diff highlighting for proof steps
|
Thanks for the feedback @RazinShaikh, @lia-approves ! I've updated the PR with the following changes:
Let me know if everything looks good now!
|
|
Hi again, Thanks for cleaning up the rest of the project. Screen.Recording.2026-02-27.at.17.58.16.mov |
|
I have not had a look at the recent changes but I wanted to suggest if you could work on making it look pretty. It should have better colours and it should look good in light mode, dark mode and all the color schemes. |
















Addresses #190
Adds visual highlighting of vertices and edges that will change between
proof steps. When navigating to a step in proof mode, elements affected
by the next rewrite are highlighted with coloured outlines and tinted
fills, making it easy to spot the difference without manual comparison.
What it does:
cosmetic changes like repositioning are excluded to avoid visual noise
How to test:
Files changed:
settings.py— diff colour scheme + toggle settingsettings_dialog.py— checkbox for "Highlight proof step differences"vitem.py— diff highlight rendering for verticeseitem.py— diff highlight rendering for edgesgraphscene.py—highlight_diff()andclear_diff_highlights()methodsproof.py— calls highlighting inmove_to_step()Leverages the existing
pyzx.graph.diff.GraphDiffalready used inGraphScene.update_graph(). No new dependencies. Toggleable via Settings.