@@ -136,8 +136,8 @@ def control(
136136 if not annotated : # captures both None and False
137137 # pylint: disable=cyclic-import
138138
139- cgate = self ._control (
140- num_ctrl_qubits = num_ctrl_qubits , label = label , ctrl_state = ctrl_state
139+ cgate = Gate ._control (
140+ self , num_ctrl_qubits = num_ctrl_qubits , label = label , ctrl_state = ctrl_state
141141 )
142142 if self .label is not None :
143143 cgate .base_gate = cgate .base_gate .to_mutable ()
@@ -148,8 +148,9 @@ def control(
148148 self , ControlModifier (num_ctrl_qubits = num_ctrl_qubits , ctrl_state = ctrl_state )
149149 )
150150
151+ @staticmethod
151152 def _control (
152- self : Gate ,
153+ operation : Gate ,
153154 num_ctrl_qubits : int | None = 1 ,
154155 label : str | None = None ,
155156 ctrl_state : str | int | None = None ,
@@ -161,7 +162,7 @@ def _control(
161162 and `cx` gates.
162163
163164 Args:
164- self : The gate used to create the ControlledGate.
165+ operation : The gate used to create the ControlledGate.
165166 num_ctrl_qubits: The number of controls to add to gate (default=1).
166167 label: An optional gate label.
167168 ctrl_state: The control state in decimal or as
@@ -185,24 +186,24 @@ def _control(
185186 ctrl_state = _ctrl_state_to_int (ctrl_state , num_ctrl_qubits )
186187
187188 q_control = QuantumRegister (num_ctrl_qubits , name = "control" )
188- q_target = QuantumRegister (self .num_qubits , name = "target" )
189+ q_target = QuantumRegister (operation .num_qubits , name = "target" )
189190 q_ancillae = None # TODO: add
190- controlled_circ = QuantumCircuit (q_control , q_target , name = f"c_{ self .name } " )
191- if isinstance (self , controlledgate .ControlledGate ):
192- original_ctrl_state = self .ctrl_state
191+ controlled_circ = QuantumCircuit (q_control , q_target , name = f"c_{ operation .name } " )
192+ if isinstance (operation , controlledgate .ControlledGate ):
193+ original_ctrl_state = operation .ctrl_state
193194 global_phase = 0
194- if self .name == "x" or (
195- isinstance (self , controlledgate .ControlledGate ) and self .base_gate .name == "x"
195+ if operation .name == "x" or (
196+ isinstance (operation , controlledgate .ControlledGate ) and operation .base_gate .name == "x"
196197 ):
197198 controlled_circ .mcx (q_control [:] + q_target [:- 1 ], q_target [- 1 ], q_ancillae )
198- if self .definition is not None and self .definition .global_phase :
199- global_phase += self .definition .global_phase
199+ if operation .definition is not None and operation .definition .global_phase :
200+ global_phase += operation .definition .global_phase
200201 else :
201202 basis = ["p" , "u" , "x" , "z" , "rx" , "ry" , "rz" , "cx" ]
202- if isinstance (self , controlledgate .ControlledGate ):
203- self = self .to_mutable ()
204- self .ctrl_state = None
205- unrolled_gate = self ._unroll_gate (basis_gates = basis )
203+ if isinstance (operation , controlledgate .ControlledGate ):
204+ operation = operation .to_mutable ()
205+ operation .ctrl_state = None
206+ unrolled_gate = operation ._unroll_gate (basis_gates = basis )
206207 if unrolled_gate .definition .global_phase :
207208 global_phase += unrolled_gate .definition .global_phase
208209
@@ -305,17 +306,17 @@ def _control(
305306 controlled_circ .p (global_phase , q_control )
306307 else :
307308 controlled_circ .mcp (global_phase , q_control [:- 1 ], q_control [- 1 ])
308- if isinstance (self , controlledgate .ControlledGate ):
309- self .ctrl_state = original_ctrl_state
310- new_num_ctrl_qubits = num_ctrl_qubits + self .num_ctrl_qubits
311- new_ctrl_state = self .ctrl_state << num_ctrl_qubits | ctrl_state
312- base_name = self .base_gate .name
313- base_gate = self .base_gate
309+ if isinstance (operation , controlledgate .ControlledGate ):
310+ operation .ctrl_state = original_ctrl_state
311+ new_num_ctrl_qubits = num_ctrl_qubits + operation .num_ctrl_qubits
312+ new_ctrl_state = operation .ctrl_state << num_ctrl_qubits | ctrl_state
313+ base_name = operation .base_gate .name
314+ base_gate = operation .base_gate
314315 else :
315316 new_num_ctrl_qubits = num_ctrl_qubits
316317 new_ctrl_state = ctrl_state
317- base_name = self .name
318- base_gate = self
318+ base_name = operation .name
319+ base_gate = operation
319320 # In order to maintain some backward compatibility with gate names this
320321 # uses a naming convention where if the number of controls is <=2 the gate
321322 # is named like "cc<base_gate.name>", else it is named like
@@ -328,7 +329,7 @@ def _control(
328329 cgate = controlledgate .ControlledGate (
329330 new_name ,
330331 controlled_circ .num_qubits ,
331- self .params ,
332+ operation .params ,
332333 label = label ,
333334 num_ctrl_qubits = new_num_ctrl_qubits ,
334335 definition = controlled_circ ,
@@ -341,10 +342,16 @@ def _unroll_gate(self, basis_gates):
341342 """Unrolls a gate, possibly composite, to the target basis"""
342343 from qiskit .transpiler import PassManager
343344 from qiskit .transpiler .passes .basis import BasisTranslator , UnrollCustomDefinitions
344- from . add_control import _gate_to_circuit
345+ from qiskit import QuantumCircuit , QuantumRegister
345346 from qiskit .circuit .equivalence_library import SessionEquivalenceLibrary as sel
346347
347- circ = _gate_to_circuit (self )
348+ if hasattr (self , "definition" ) and self .definition is not None :
349+ circ = self .definition
350+ else :
351+ qr = QuantumRegister (self .num_qubits )
352+ circ = QuantumCircuit (qr , name = self .name )
353+ circ .append (self , qr )
354+
348355 pm = PassManager (
349356 [
350357 UnrollCustomDefinitions (sel , basis_gates = basis_gates ),
0 commit comments