diff --git a/zxlive/common.py b/zxlive/common.py index e2db7a82..76e5644f 100644 --- a/zxlive/common.py +++ b/zxlive/common.py @@ -35,6 +35,7 @@ class ToolType(IntEnum): "path/custom-rules": "lemmas/", "color-scheme": "modern-red-green", "snap-granularity": '4', + "input-circuit-format": 'openqasm', "tikz/boundary-export": pyzx.settings.tikz_classes['boundary'], "tikz/Z-spider-export": pyzx.settings.tikz_classes['Z'], @@ -82,6 +83,11 @@ class ToolType(IntEnum): 'gidney': "Gidney's Black & White", } +input_circuit_formats = { + 'openqasm': "standard OpenQASM", + 'sqasm': "Spider QASM", + 'sqasm-no-simplification': "Spider QASM (no simplification)", +} # Initialise settings settings = QSettings("zxlive", "zxlive") @@ -145,7 +151,7 @@ class Colors(object): w_output_pressed: QColor = QColor("#444444") outline: QColor = QColor("#000000") - def __init__(self, color_scheme:str='modern-red-green'): + def __init__(self, color_scheme:str): self.set_color_scheme(color_scheme) def set_color_scheme(self, color_scheme: str) -> None: @@ -187,7 +193,7 @@ def set_color_scheme(self, color_scheme: str) -> None: settings = QSettings("zxlive", "zxlive") color_scheme = settings.value("color-scheme") -if color_scheme is None: color_scheme = 'modern-red-green' +if color_scheme is None: color_scheme = str(defaults["color-scheme"]) else: color_scheme = str(color_scheme) colors = Colors(color_scheme) diff --git a/zxlive/dialogs.py b/zxlive/dialogs.py index 72f94ee8..969c4c8c 100644 --- a/zxlive/dialogs.py +++ b/zxlive/dialogs.py @@ -102,15 +102,9 @@ def import_diagram_dialog(parent: QWidget) -> Optional[ImportGraphOutput | Impor return import_diagram_from_file(file_path, selected_filter) -def create_circuit_dialog(parent: QWidget) -> Optional[str]: - """Shows a dialog to input a circuit in QASM format.""" - explanation = """Write a circuit in QASM format. Example: - qreg q[3]; - cx q[0], q[1]; - h q[2]; - ccx q[0], q[1], q[2]; - """ - s, success = QInputDialog.getMultiLineText(parent, "Circuit input", explanation, "qreg q[3];\n") +def create_circuit_dialog(explanation: str, example: str, parent: QWidget) -> Optional[str]: + """Shows a dialog to input a circuit.""" + s, success = QInputDialog.getMultiLineText(parent, "Circuit input", explanation, example) return s if success else None diff --git a/zxlive/edit_panel.py b/zxlive/edit_panel.py index 1bf64b54..f17e29d0 100644 --- a/zxlive/edit_panel.py +++ b/zxlive/edit_panel.py @@ -3,16 +3,16 @@ import copy from typing import Iterator -from PySide6.QtCore import Signal +from PySide6.QtCore import Signal, QSettings from PySide6.QtGui import QAction from PySide6.QtWidgets import (QToolButton) -from pyzx import EdgeType, VertexType +from pyzx import EdgeType, VertexType, sqasm from pyzx.circuit.qasmparser import QASMParser from pyzx.symbolic import Poly from .base_panel import ToolbarSection from .commands import UpdateGraph -from .common import GraphT +from .common import GraphT, input_circuit_formats from .dialogs import show_error_msg, create_circuit_dialog from .editor_base_panel import EditorBasePanel from .graphscene import EditGraphScene @@ -73,20 +73,36 @@ def _start_derivation(self) -> None: self.start_derivation_signal.emit(new_g) def _input_circuit(self) -> None: - qasm = create_circuit_dialog(self) + settings = QSettings("zxlive", "zxlive") + circuit_format = str(settings.value("input-circuit-format")) + explanations = { + 'openqasm': "Write a circuit in QASM format.", + 'sqasm': "Write a circuit in Spider QASM format.", + 'sqasm-no-simplification': "Write a circuit in Spider QASM format. No simplification will be performed.", + } + examples = { + 'openqasm': "qreg q[3];\ncx q[0], q[1];\nh q[2];\nccx q[0], q[1], q[2];", + 'sqasm': "qreg q[1];\nqreg A[2];\n;s A[1];\n;cx q[0], A[0];\n;cx q[0], A[1];", + 'sqasm-no-simplification': "qreg q[1];\nqreg Z[2];\ncx q[0], Z[0];\ncx q[0], Z[1];\ns Z[1];", + } + qasm = create_circuit_dialog(explanations[circuit_format], examples[circuit_format], self) if qasm is not None: new_g = copy.deepcopy(self.graph_scene.g) try: - circ = QASMParser().parse(qasm, strict=False).to_graph() + if circuit_format == 'sqasm': + circ = sqasm(qasm) + elif circuit_format == 'sqasm-no-simplification': + circ = sqasm(qasm, simplify=False) + else: + circ = QASMParser().parse(qasm, strict=False).to_graph() except TypeError as err: show_error_msg("Invalid circuit", str(err)) return except Exception: - show_error_msg("Invalid circuit", "Couldn't parse QASM code") + show_error_msg("Invalid circuit", f"Couldn't parse code as {input_circuit_formats[circuit_format]}.") return new_verts, new_edges = new_g.merge(circ) cmd = UpdateGraph(self.graph_view, new_g) self.undo_stack.push(cmd) self.graph_scene.select_vertices(new_verts) - diff --git a/zxlive/settings_dialog.py b/zxlive/settings_dialog.py index c1a88147..089d772b 100644 --- a/zxlive/settings_dialog.py +++ b/zxlive/settings_dialog.py @@ -27,7 +27,7 @@ import pyzx -from .common import set_pyzx_tikz_settings, colors, setting, color_schemes, defaults +from .common import set_pyzx_tikz_settings, colors, setting, color_schemes, input_circuit_formats, defaults if TYPE_CHECKING: from .mainwindow import MainWindow @@ -63,6 +63,7 @@ def __init__(self, main_window: MainWindow) -> None: self.add_setting(form_general, "color-scheme", "Color scheme", 'combo',data=color_schemes) self.add_setting(form_general, "snap-granularity", "Snap-to-grid granularity", 'combo', data = {'2': "2", '4': "4", '8': "8", '16': "16"}) + self.add_setting(form_general, "input-circuit-format", "Input Circuit as", 'combo', data=input_circuit_formats) self.prev_color_scheme = self.settings.value("color-scheme") vlayout.addStretch()