zxcalc / zxlive Goto Github PK
View Code? Open in Web Editor NEWA graphical tool for the ZX calculus
License: Apache License 2.0
A graphical tool for the ZX calculus
License: Apache License 2.0
We want to make zxlive look more like TIKZIT, which most of the ZX community are already familiar with using. Their GUI is implemented using Qt, so hopefully it isn't too hard to port the interface to zxlive.
Features:
We discussed having the following features for dragging based gestures:
changing an edge type doesn't update the edge rendering (but does allow the rules to apply).
For consistency (and generally not getting weird-looking code), I suggest we adopt PEP 8 naming conventions where ever possible/reasonable:
https://peps.python.org/pep-0008/#naming-conventions
The main exception to this is the Qt bindings, which are all C++ style. The accepted convention is to use Python naming for your own code and Qt conventions just for calling/overriding Qt things.
In particular, capital letters and underscores should (almost) never go together. This looks very strange to me.
Also, I suggest avoiding writing the type of a thing in variable names, e.g. the many variables called Button_....
. The exception to this is if there is only one thing of a given type around, e.g. a graph_view
of type GraphView
.
Move a single vertex. Then select all vertices and move them around together: you'll see some jumpy behaviour of the first vertex.
In general, vertices don't seem to snap to the grid properly
I guess this probably is some rounding error
Support adding a single disconnected node to the graph.
Similar to issue #49, when drawing a diagram and changing a spider to an Hbox, the color is updated but the shape remains round.
This is probably because the vitem path needs to be changed to a rectangle rather than an ellipse.
Right now most of the rewrite commands are implemented by SetGraph, which just replaces the entire graph. This is undesirable for various reasons. We should probably use some smarter GraphDiff functionality. This should probably be implemented in PyZX itself, and then interfaced in ZXLive to do a command more smartly.
Small things:
Medium things:
Big things:
If you enable sparkles of the magic wand (with Ctrl+Alt+Shift+S), and you do it for a long time and release you will see that the memory usage of ZXLive is now a couple MB more. In my experiments when I did this three times in a row, the program would just crash without an exception.
When dragging for a long time, the framerate also goes way down, probably because the sparkle objects are not getting destroyed or cleaned up properly.
We would like to import and export diagrams from pyzx and other formats. pyzx has converters for some of these libraries so not all of this has to be done from scratch.
Requirements:
We potentially want to inherit the graph class in pyzx
to handle parallel and directed edges.
Currently selection behaviour is a bit shonky. I suggest we:
I think adding nodes and edges using right click should only work in edit mode.
Allow users to define their own rewrite rules or prove lemmas, which they can apply in the proofs. This requires more thinking and is not urgent, but I am opening this issue as I think this is an important feature for a realistic use-case of zxlive.
To reproduce: select a bunch of spiders of which more than 1 can fuse. Then press the 'fuse spiders' button when in Proof mode.
The bug: spiders move around somewhat randomly instead of smoothly moving to where they should go.
Adding proper undo support early is a good way to avoid a lot of pain/bugs later on. I suggest we replace the ad hoc implementation with a QUndoStack
. Have a look at the Qt Undo Framework: https://doc.qt.io/qt-6/qundo.html
The normal way this is done is to create a new class extending QUndoCommand for every user-initiated change to a graph. This class should override redo
and undo
for making the graph change and undo-in the graph change, respectively. Since you usually need some extra data to undo/redo a change, pass this in to the constructor and store it in the object. Note it is (usually) not necessary to keep a whole copy of the graph.
n.b. when you call QUndoStack.push
, it automatically calls redo
on the command being pushed, so the only place you should be changing the graph is in the undo
/redo
methods.
I know this seems a bit heavy duty, but it will save trouble in the long run. A couple of things to watch out for:
Drawing an edge requires right clicking and dragging. This is not possible on most laptop touchpads.
As an extension of #3, we want the ability to import and export proofs.
I see there's a bunch of places in the code where an event is captured but not used (for instance because the right mouse button is not used). If I understand correctly, in this case you should call QEvent.ignore() (https://doc.qt.io/qt-5/qevent.html#ignore) in order to allow Qt to propagate the event to the parent. This will probably prevent future bugs.
So for instance the current mousePressEvent
is implemented as
def mousePressEvent(self, e: QGraphicsSceneMouseEvent) -> None:
super().mousePressEvent(e)
if e.button() != Qt.LeftButton:
return
...
I think here before the return, you should be calling e.ignore()
.
When fusing spiders with symbolic angles the following exception is raised:
Traceback (most recent call last):
File "C:\Users\jvdwe\Documents\Projects\zxlive\zxlive\proof_panel.py", line 122, in _vertex_dropped_onto
pyzx.basicrules.fuse(g, w, v)
File "C:\Users\jvdwe\Documents\Projects\zxlive\../pyzx\pyzx\basicrules.py", line 202, in fuse
g.add_to_phase(v1, g.phase(v2))
File "C:\Users\jvdwe\Documents\Projects\zxlive\../pyzx\pyzx\graph\graph_s.py", line 257, in add_to_phase
self._phase[vertex] = old_phase + phase
TypeError: unsupported operand type(s) for +: 'FunctionClass' and 'Symbol'
Traceback (most recent call last):
File "C:\Users\jvdwe\Documents\Projects\zxlive\../pyzx\pyzx\graph\graph_s.py", line 255, in add_to_phase
self._phase[vertex] = (old_phase + Fraction(phase)) % 2
TypeError: unsupported operand type(s) for +: 'FunctionClass' and 'Fraction'
Things like undo and redo should definitely be using the ctrl+Z / ctrl+shift+Z keyboard shortcuts. I'm guessing this shouldn't be too hard to implement using builtin Qt features.
We discussed the features the magic wand should have. They are:
UI:
Currently after user presses reset it is impossible to undo the reset. Adding this functionality is important.
If you click an edge in Edit mode, it should be selected. Then you can change the type of the edge or delete it.
We want the ability to evaluate diagrams using a tensor network library. This can allow us to directly check the semantic equality of 2 ZX diagrams.
When diagram contains a symbolic/non-numeric angle the following issue is raised:
Traceback (most recent call last):
File "C:\Users\jvdwe\Documents\Projects\zxlive\zxlive\mainwindow.py", line 224, in save_file
return self.save_as()
File "C:\Users\jvdwe\Documents\Projects\zxlive\zxlive\mainwindow.py", line 249, in save_as
out = export_diagram_dialog(self.active_panel.graph_scene.g, self)
File "C:\Users\jvdwe\Documents\Projects\zxlive\zxlive\dialogs.py", line 137, in export_diagram_dialog
data = graph.to_json()
File "C:\Users\jvdwe\Documents\Projects\zxlive\../pyzx\pyzx\graph\base.py", line 459, in to_json
return graph_to_json(self, include_scalar)
File "C:\Users\jvdwe\Documents\Projects\zxlive\../pyzx\pyzx\graph\jsonparser.py", line 195, in graph_to_json
phase = _phase_to_quanto_value(g.phase(v))
File "C:\Users\jvdwe\Documents\Projects\zxlive\../pyzx\pyzx\graph\jsonparser.py", line 41, in _phase_to_quanto_value
p = Fraction(p)
File "C:\Users\jvdwe\AppData\Local\Programs\Python\Python39\lib\fractions.py", line 139, in __new__
raise TypeError("argument should be a string "
TypeError: argument should be a string or a Rational instance
Traceback (most recent call last):
File "C:\Users\jvdwe\Documents\Projects\zxlive\../pyzx\pyzx\graph\graph_s.py", line 255, in add_to_phase
self._phase[vertex] = (old_phase + Fraction(phase)) % 2
File "C:\Users\jvdwe\AppData\Local\Programs\Python\Python39\lib\fractions.py", line 139, in __new__
raise TypeError("argument should be a string "
TypeError: argument should be a string or a Rational instance
Currently tabs have a generic name. If you save a diagram to file it should remember the name. And then when you save again, it shouldn't open the dialog box, but just overwrite the previously saved to file.
Using the new drag to add edge feature to add the same edge twice raises an exception when trying to undo or reset.
That is because the AddEdge
command always calls remove_edge
when undoing, even if no actual edge was added.
When you are working with a tablet, it's not very nice to have to go to the Edit menu to click undo/redo, and it might be hard to use the keyboard to ctrl+Z. I suggest adding buttons in the toolbar (for instance next to the select/vertex/edge buttons in edit mode, and next to the select/magic wand tools in Proof mode). These should also have nice icons.
When you add an identity spider with the magic wand, it looks like the vertex is added with just a slight vertical offset. This dissapears as soon as you move the vertex as it is then fit to the grid.
I'm not sure this is desired behaviour.
We should decide on a minimum Python version to support and add it to pyproject.toml
For example, I'd like to use match statements from Python 3.10
Currently, most of the brains of ZX live are in rules.py
, which contains a mix of graph editing code and graph rewrite rules and in MainWindow.__init__
. I think this organisation could be improved.
Here are my suggestions:
GraphEditPanel
for now which just does GUI graph editing (no ZX rules), with the idea that we'll add a ProofPanel
later for rewrite. These can extend QWidget
and be added to the mainwindow in a QTabWidget
GraphEditPanel
should maintain its own undo stack (I'll make a separate issue about undo)It might be worth breaking some of these into separate issues, but I think it's useful to have some design principles in one place. Feel free to comment here or on discord to discuss.
Interface can be improved to both make the application more elegant and intuitive to use. Adding right click context menus for some actions would de-clutter the interface.
As discussed, here is an idea for a nice minimal implementation of parametric angles:
This should be sufficient to prove simple examples like teleportation, magic state injection, etc.
The side panel can have the rewrites, simplification routines and the proof steps. The code for sidebar of edit mode might be useful for implementing this.
Currently all the PyZX simplification routines are shown and can be applied from the "Simplify" menu. But some simplifications would not change the current diagram, for instance, in the case when the same routine was applied previously. We want to disable menu buttons for simplifications that are not possible.
Right now we can only apply bialgebra in only one direction, which reduces the number of nodes.
Sometimes the other direction is desirable.
We want to save a proof in a json format. The main idea is to store the initial graph and for each proof step, we store a GraphDiff.
For loading, we need to apply a sequence of rewrites based on the GraphDiffs to the initial graph.
Currently there is no way to zoom in and out, and there is also no way to pan the screen.
Probably we want to have a dedicated tool for panning, as well as a keyboard shortcut, like spacebar+dragging to pan and control+scroll to zoom.
I think deletion of edges/nodes in the edit mode should be supported.
We probably want to have some nice little animations for all the basic types of rewrites. In particular:
Suggestions are welcome for what these animations should look like.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.