Here are the proposed corrections—each illustrated with the minimal changed snippet—so you can integrate them directly.
Fixes by Jesus Carrasco
1. Fixing the “TK1” membership test in label_gates
Problem:
if labelled_command["op"]["type"] in ("TK1"):
This checks membership in the string "TK1" (i.e. {"T","K","1"}) rather than the OpType.
Correction:
from pytket.circuit import OpType
# …
if labelled_command["op"]["type"] == OpType.TK1:
labelled_command["opgroup"] = f"Computing {comp_count}"
comp_count += 1
elif labelled_command["op"]["type"] == OpType.CX:
labelled_command["opgroup"] = f"Frame {frame_count}"
frame_count += 1
else:
raise RuntimeError(
'Expected only TK1 or CX gates—please rebase first with PECRebase.'
)
2. Consistent “noop” creation for identity Pauli
Problem:
In str_to_pauli_op and in wrapping frames, raw dicts and "noop" strings are used.
Correction:
def str_to_pauli_op(pauli_str: str) -> Op:
assert pauli_str in ["I", "X", "Y", "Z"]
mapping = {
"I": OpType.Noop,
"X": OpType.X,
"Y": OpType.Y,
"Z": OpType.Z,
}
return Op.create(mapping[pauli_str])
And in wrap_frame_gates, replace the manual dict with:
identity_op = Op.create(OpType.Noop)
# …
labelled_EM_command = {
"op": identity_op.to_dict()["op"],
"args": [arg],
"opgroup": f"pre Pauli {frame_number} {qubit_i}"
}
3. Mapping qubits correctly (use Qubit, not Node)
Problem:
n_q_map[cc_qns[i]] = Node("q", i)
tket’s place_with_map expects Qubit-to-Qubit maps, not architecture Nodes.
Correction:
from pytket.unit_id import Qubit
# …
n_q_map = { old_q: Qubit(i) for i, old_q in enumerate(rand_cliff_circ.qubits) }
# Then use place_with_map(rand_cliff_circ, n_q_map)
4. Avoid reassigning circ.add_circuit (it returns None)
Problem:
circ = circ.add_circuit(cliff_circ, [...], [])
add_circuit mutates in place and returns None.
Correction:
circ.add_circuit(cliff_circ, list(range(n_qubits)), [])
5. Ensure full Pauli mapping in clifford_canonical_F
Problem: The doc said pauli_layer in {0,1,2,3}, but the code only handled 0,1,2.
Correction:
for i, gate in enumerate(pauli_layer):
if gate == 1: circ.X(i, opgroup="Clifford 1")
elif gate == 2: circ.Y(i, opgroup="Clifford 1")
elif gate == 3: circ.Z(i, opgroup="Clifford 1")
# gate == 0: identity—no action
Next Steps
- Apply these patches into your module where indicated.
- Run your unit tests (especially around
label_gates, wrapping logic, and your QubitPauliString expectations).
- Let me know if you encounter any lingering errors or need further refinements—happy to dive deeper.
Here are the proposed corrections—each illustrated with the minimal changed snippet—so you can integrate them directly.
Fixes by Jesus Carrasco
1. Fixing the “TK1” membership test in
label_gatesProblem:
This checks membership in the string
"TK1"(i.e.{"T","K","1"}) rather than theOpType.Correction:
2. Consistent “noop” creation for identity Pauli
Problem:
In
str_to_pauli_opand in wrapping frames, raw dicts and"noop"strings are used.Correction:
And in
wrap_frame_gates, replace the manual dict with:3. Mapping qubits correctly (use
Qubit, notNode)Problem:
tket’splace_with_mapexpectsQubit-to-Qubitmaps, not architectureNodes.Correction:
4. Avoid reassigning
circ.add_circuit(it returnsNone)Problem:
add_circuitmutates in place and returnsNone.Correction:
5. Ensure full Pauli mapping in
clifford_canonical_FProblem: The doc said
pauli_layerin{0,1,2,3}, but the code only handled 0,1,2.Correction:
Next Steps
label_gates, wrapping logic, and your QubitPauliString expectations).