-
Notifications
You must be signed in to change notification settings - Fork 25
fix: emit fresh operand nodes from gate decompositions #335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -19,6 +19,7 @@ | |
|
|
||
| """ | ||
|
|
||
| from copy import deepcopy | ||
| from typing import Callable | ||
|
|
||
| import numpy as np | ||
|
|
@@ -30,6 +31,17 @@ | |
| from pyqasm.maps.expressions import CONSTANTS_MAP | ||
|
|
||
|
|
||
| def _fresh_qubits(*qubits: IndexedIdentifier) -> list[IndexedIdentifier | Identifier]: | ||
| """Deep-copy qubit operands so every emitted statement owns its nodes. | ||
|
|
||
| Decomposition functions pass the same operand nodes to each statement they | ||
| emit; without copies, transforms that later rewrite qubit indices in place | ||
| (e.g. ``remove_idle_qubits``, ``reverse_qubit_order``) would mutate a | ||
| shared node once per referencing statement. | ||
| """ | ||
| return [deepcopy(qubit) for qubit in qubits] | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does an |
||
|
|
||
|
|
||
| def u3_gate( | ||
| theta: int | float, | ||
| phi: int | float, | ||
|
|
@@ -113,7 +125,9 @@ def global_phase_gate(theta: float, qubit_list: list[IndexedIdentifier]) -> list | |
| """ | ||
| return [ | ||
| QuantumPhase( | ||
| argument=FloatLiteral(value=theta), qubits=qubit_list, modifiers=[] # type: ignore | ||
| argument=FloatLiteral(value=theta), | ||
| qubits=_fresh_qubits(*qubit_list), # type: ignore | ||
| modifiers=[], | ||
| ) | ||
| ] | ||
|
|
||
|
|
@@ -702,7 +716,7 @@ def ccx_gate_op( | |
| modifiers=[], | ||
| name=Identifier(name="ccx"), | ||
| arguments=[], | ||
| qubits=[qubit0, qubit1, qubit2], | ||
| qubits=_fresh_qubits(qubit0, qubit1, qubit2), | ||
| ) | ||
| ] | ||
|
|
||
|
|
@@ -905,7 +919,7 @@ def one_qubit_gate_op(gate_name: str, qubit_id: IndexedIdentifier) -> list[Quant | |
| modifiers=[], | ||
| name=Identifier(name=gate_name), | ||
| arguments=[], | ||
| qubits=[qubit_id], | ||
| qubits=_fresh_qubits(qubit_id), | ||
| ) | ||
| ] | ||
|
|
||
|
|
@@ -918,7 +932,7 @@ def one_qubit_rotation_op( | |
| modifiers=[], | ||
| name=Identifier(name=gate_name), | ||
| arguments=[FloatLiteral(value=rotation)], | ||
| qubits=[qubit_id], | ||
| qubits=_fresh_qubits(qubit_id), | ||
| ) | ||
| ] | ||
|
|
||
|
|
@@ -931,7 +945,7 @@ def two_qubit_gate_op( | |
| modifiers=[], | ||
| name=Identifier(name=gate_name.lower()), | ||
| arguments=[], | ||
| qubits=[qubit_id1, qubit_id2], | ||
| qubits=_fresh_qubits(qubit_id1, qubit_id2), | ||
| ) | ||
| ] | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not use
_fresh_qubitshere too?