Skip to content

Recursion support for CircuitOperation in map_clean_and_borrowable_qubits #7840

@Vivek1106-04

Description

@Vivek1106-04

Describe the issue

The [map_clean_and_borrowable_qubits] transformer in [qubit_management_transformers.py] does not support recursive mapping for nested CircuitOperations.

As documented in the code (line 81):

Since this is not implemented using the cirq transformers infrastructure, we currently do not support recursive mapping within sub-circuits and that is left as a future TODO.

While the transformer attaches a [qubit_map] to the outer CircuitOperation, it does not traverse into the underlying FrozenCircuit to replace CleanQubit or BorrowableQubit instances. This results in the inner circuit retaining abstract placeholder qubits, which can cause failures in downstream operations that expect physical qubits.

Expected behavior: The transformer should recursively process nested CircuitOperations and replace all CleanQubit/BorrowableQubit placeholders with actual qubits.

Actual behavior: The inner FrozenCircuit retains its original placeholder qubits; only a [qubit_map] is applied to the outer CircuitOperation.

Explain how to reproduce the bug or problem

import cirq
from cirq.transformers.qubit_management_transformers import map_clean_and_borrowable_qubits

# Create a sub-circuit containing a CleanQubit placeholder
clean_qubit = cirq.ops.CleanQubit(0)
sub_circuit = cirq.Circuit(cirq.X(clean_qubit))

# Wrap in a CircuitOperation (nested circuit)
main_circuit = cirq.Circuit(cirq.CircuitOperation(sub_circuit.freeze()))

print("Original circuit:")
print(main_circuit)

# Apply the transformer
result = map_clean_and_borrowable_qubits(main_circuit)

print("Transformed circuit:")
print(result)

# Verify: check if placeholder was replaced in the inner circuit
circuit_op = list(result.all_operations())[0]
inner_qubit = list(circuit_op.circuit.all_operations())[0].qubits[0]

print(f"Inner qubit: {inner_qubit!r}")
print(f"Inner qubit type: {type(inner_qubit).__name__}")

Output:

Original circuit:
_c(0): ───[ _c(0): ───X─── ]───

Transformed circuit:
ancilla_0: ───[ _c(0): ───X─── ](qubit_map={_c(0): ancilla_0})───

Inner qubit: cirq.ops.CleanQubit(0)
Inner qubit type: CleanQubit

Tell us the version of Cirq where this happens

1.7.0.dev0

Metadata

Metadata

Assignees

Labels

kind/bug-reportSomething doesn't seem to work.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions