Skip to content

Commit

Permalink
Merge branch 'feature-unfuse-phase'
Browse files Browse the repository at this point in the history
  • Loading branch information
tuomas56 committed Nov 13, 2023
2 parents 72ac990 + e7a2c69 commit dba9c5d
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 11 deletions.
11 changes: 9 additions & 2 deletions zxlive/graphview.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ class GraphTool:
class WandTrace:
start: QPointF
end: QPointF
shift: bool
hit: dict[VItem | EItem, list[QPointF]]

def __init__(self, start: QPointF) -> None:
def __init__(self, start: QPointF, shift: bool = False) -> None:
self.start = start
self.hit = {}
self.end = start
self.shift = shift


WAND_COLOR = "#500050"
Expand Down Expand Up @@ -116,7 +118,8 @@ def mousePressEvent(self, e: QMouseEvent) -> None:
self.rubberband.show()
elif self.tool == GraphTool.MagicWand:
pos = self.mapToScene(e.pos())
self.wand_trace = WandTrace(pos)
shift = e.modifiers() & Qt.KeyboardModifier.ShiftModifier
self.wand_trace = WandTrace(pos, shift)
self.wand_path = QGraphicsPathItem()
self.graph_scene.addItem(self.wand_path)
pen = QPen(QColor(WAND_COLOR), WAND_WIDTH)
Expand All @@ -137,6 +140,8 @@ def mouseMoveEvent(self, e: QMouseEvent) -> None:
self.rubberband.setGeometry(QRect(self._rubberband_start, e.pos()).normalized())
elif self.tool == GraphTool.MagicWand:
if self.wand_trace is not None:
if not (e.modifiers() & Qt.KeyboardModifier.ShiftModifier):
self.wand_trace.shift = False
assert self.wand_path is not None
pos = self.mapToScene(e.pos())
prev = self.wand_trace.end
Expand Down Expand Up @@ -178,6 +183,8 @@ def mouseReleaseEvent(self, e: QMouseEvent) -> None:
it.setSelected(not (len(items) == 1 or e.modifiers() & Qt.KeyboardModifier.ShiftModifier) or not it.isSelected())
elif self.tool == GraphTool.MagicWand:
if self.wand_trace is not None:
if not (e.modifiers() & Qt.KeyboardModifier.ShiftModifier):
self.wand_trace.shift = False
assert self.wand_path is not None
if self.sparkle_mode:
self.sparkles.stop()
Expand Down
53 changes: 44 additions & 9 deletions zxlive/proof_panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import copy
import os
from fractions import Fraction
from typing import Iterator, Union, cast

import pyzx
Expand All @@ -12,7 +13,7 @@
from PySide6.QtWidgets import (QAbstractItemView, QHBoxLayout, QListView,
QStyle, QStyledItemDelegate,
QStyleOptionViewItem, QToolButton, QWidget,
QVBoxLayout, QTabWidget)
QVBoxLayout, QTabWidget, QInputDialog)
from pyzx import VertexType, basicrules
from pyzx.utils import get_z_box_label, set_z_box_label

Expand All @@ -23,11 +24,14 @@
from .common import (get_custom_rules_path, ET, SCALE, VT, GraphT, get_data,
pos_from_view, pos_to_view, colors)
from .custom_rule import CustomRule
from .dialogs import show_error_msg
from .eitem import EItem
from .graphscene import GraphScene
from .graphview import GraphTool, GraphView, WandTrace
from .proof import ProofModel
from .vitem import DragState, VItem
from .editor_base_panel import string_to_complex, string_to_fraction
from .poly import Poly


class ProofPanel(BasePanel):
Expand Down Expand Up @@ -219,10 +223,34 @@ def cross(a: QPointF, b: QPointF) -> float:
if self.graph.type(vertex) not in (VertexType.Z, VertexType.X, VertexType.Z_BOX):
return False

if basicrules.check_remove_id(self.graph, vertex):
if not trace.shift and basicrules.check_remove_id(self.graph, vertex):
self._remove_id(vertex)
return True


if trace.shift:
phase_is_complex = (self.graph.type(vertex) == VertexType.Z_BOX)
if phase_is_complex:
prompt = "Enter desired phase value (complex value):"
error_msg = "Please enter a valid input (e.g., -1+2j)."
else:
prompt = "Enter desired phase value (in units of pi):"
error_msg = "Please enter a valid input (e.g., 1/2, 2, 0.25, 2a+b)."
text, ok = QInputDialog().getText(self, "Choose Phase of one Spider", prompt)
if not ok:
return False
try:
def new_var(_):
raise ValueError()
phase = string_to_complex(text) if phase_is_complex else string_to_fraction(text, new_var)
except ValueError:
show_error_msg("Invalid Input", error_msg)
return False
else:
if self.graph.type(vertex) == VertexType.Z_BOX:
phase = get_z_box_label(self.graph, vertex)
else:
phase = self.graph.phase(vertex)

start = trace.hit[item][0]
end = trace.hit[item][-1]
if start.y() > end.y():
Expand All @@ -240,7 +268,7 @@ def cross(a: QPointF, b: QPointF) -> float:
else:
right.append(neighbor)
mouse_dir = ((start + end) * (1/2)) - pos
self._unfuse(vertex, left, mouse_dir)
self._unfuse(vertex, left, mouse_dir, phase)
return True

def _remove_id(self, v: VT) -> None:
Expand All @@ -250,7 +278,7 @@ def _remove_id(self, v: VT) -> None:
cmd = AddRewriteStep(self.graph_view, new_g, self.step_view, "id")
self.undo_stack.push(cmd, anim_before=anim)

def _unfuse(self, v: VT, left_neighbours: list[VT], mouse_dir: QPointF) -> None:
def _unfuse(self, v: VT, left_neighbours: list[VT], mouse_dir: QPointF, phase: Poly | complex | Fraction) -> None:
def snap_vector(v: QVector2D) -> None:
if abs(v.x()) > abs(v.y()):
v.setY(0.0)
Expand Down Expand Up @@ -302,11 +330,18 @@ def snap_vector(v: QVector2D) -> None:
new_g.add_edge((v, left_vert))
if phase_left:
if self.graph.type(v) == VertexType.Z_BOX:
set_z_box_label(new_g, left_vert, get_z_box_label(new_g, v))
set_z_box_label(new_g, v, 1)
set_z_box_label(new_g, left_vert, get_z_box_label(new_g, v) / phase)
set_z_box_label(new_g, v, phase)
else:
new_g.set_phase(left_vert, new_g.phase(v) - phase)
new_g.set_phase(v, phase)
else:
if self.graph.type(v) == VertexType.Z_BOX:
set_z_box_label(new_g, left_vert, phase)
set_z_box_label(new_g, v, get_z_box_label(new_g, v) / phase)
else:
new_g.set_phase(left_vert, new_g.phase(v))
new_g.set_phase(v, 0)
new_g.set_phase(left_vert, phase)
new_g.set_phase(v, new_g.phase(v) - phase)

anim = anims.unfuse(self.graph, new_g, v, self.graph_scene)
cmd = AddRewriteStep(self.graph_view, new_g, self.step_view, "unfuse")
Expand Down

0 comments on commit dba9c5d

Please sign in to comment.