
    z	i                        S r SSKJr  SSKJrJrJrJr  SSKJ	r	  SSK
Jr  SSKJrJr  SSKJr  SSKJr  SS	KJr  SS
KJr   " S S\5      rSS jrSS jrSS jrg)zATranslate parameterized gates only, and leave others as they are.    )annotations)InstructionParameterExpressionQubitClbit)EquivalenceLibrary)circuit_to_dag)
DAGCircuit	DAGOpNode)QiskitError)TransformationPass)BasisTranslator)Targetc                  R   ^  \ rS rSrSr   S       SU 4S jjjrSS jrSrU =r$ )	TranslateParameterizedGates   u)	  Translate parameterized gates to a supported basis set.

Once a parameterized instruction is found that is not in the ``supported_gates`` list,
the instruction is decomposed one level and the parameterized sub-blocks are recursively
decomposed. The recursion is stopped once all parameterized gates are in ``supported_gates``,
or if a gate has no definition and a translation to the basis is attempted (this might happen
e.g. for the ``UGate`` if it's not in the specified gate list).

Example:

    The following, multiply nested circuit::

        from qiskit.circuit import QuantumCircuit, ParameterVector
        from qiskit.transpiler.passes import TranslateParameterizedGates

        x = ParameterVector("x", 4)
        block1 = QuantumCircuit(1)
        block1.rx(x[0], 0)

        sub_block = QuantumCircuit(2)
        sub_block.cx(0, 1)
        sub_block.rz(x[2], 0)

        block2 = QuantumCircuit(2)
        block2.ry(x[1], 0)
        block2.append(sub_block.to_gate(), [0, 1])

        block3 = QuantumCircuit(3)
        block3.ccx(0, 1, 2)

        circuit = QuantumCircuit(3)
        circuit.append(block1.to_gate(), [1])
        circuit.append(block2.to_gate(), [0, 1])
        circuit.append(block3.to_gate(), [0, 1, 2])
        circuit.cry(x[3], 0, 2)

        supported_gates = ["rx", "ry", "rz", "cp", "crx", "cry", "crz"]
        unrolled = TranslateParameterizedGates(supported_gates)(circuit)

    is decomposed to::

             ┌──────────┐     ┌──────────┐┌─────────────┐
        q_0: ┤ Ry(x[1]) ├──■──┤ Rz(x[2]) ├┤0            ├─────■──────
             ├──────────┤┌─┴─┐└──────────┘│             │     │
        q_1: ┤ Rx(x[0]) ├┤ X ├────────────┤1 circuit-92 ├─────┼──────
             └──────────┘└───┘            │             │┌────┴─────┐
        q_2: ─────────────────────────────┤2            ├┤ Ry(x[3]) ├
                                          └─────────────┘└──────────┘

c                   > [         TU ]  5         Uc  SSKJn  UnUb  UR                  nOUc  [        S5      eXl        X0l        [        X!US9U l	        g)aE  
Args:
    supported_gates: A list of suppported basis gates specified as string. If ``None``,
        a ``target`` must be provided.
    equivalence_library: The equivalence library to translate the gates. Defaults
        to the equivalence library of all Qiskit standard gates.
    target: A :class:`.Target` containing the supported operations. If ``None``,
        ``supported_gates`` must be set. Note that this argument takes precedence over
        ``supported_gates``, if both are set.

Raises:
    ValueError: If neither of ``supported_gates`` and ``target`` are passed.
Nr   )_selz;One of ``supported_gates`` or ``target`` must be specified.)target)
super__init__9qiskit.circuit.library.standard_gates.equivalence_libraryr   operation_names
ValueError_supported_gates_targetr   _translator)selfsupported_gatesequivalence_libraryr   r   	__class__s        p/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/transpiler/passes/basis/translate_parameterized.pyr   $TranslateParameterizedGates.__init__O   sb    & 	 &V"& $44O$Z[[ /*+>X^_    c                   UR                  5        H  n[        UR                  5      (       d  M  [        X R                  U R
                  5      (       a  MF  UR                  R                  nUb  U R                  [        U5      5      nO/ U R                  R                  [        UR                  5      5      nUR                  X$5        M     U$ ! [         a  n[        S5      UeSnAff = f)zRun the transpiler pass.

Args:
    dag: The DAG circuit in which the parameterized gates should be unrolled.

Returns:
    A DAG where the parameterized gates have been unrolled.

Raises:
    QiskitError: If the circuit cannot be unrolled.
Nz Failed to translate final block.)op_nodes_is_parameterizedop_is_supportedr   r   
definitionrunr	   r   _instruction_to_dag	Exceptionr   substitute_node_with_dag)r   dagnoder*   unrolledexcs         r"   r+   TranslateParameterizedGates.runu   s     LLND ))-++T\\3 3 "WW//
)#xxz(BCHW#'#3#3#7#78KDGG8T#U
 ,,T<% #( 
 % W)*LMSVVWs   .C
C,C''C,)r   r   r   )NNN)r   zlist[str] | Noner    zEquivalenceLibrary | Noner   Target | NonereturnNone)r/   r
   r5   r
   )	__name__
__module____qualname____firstlineno____doc__r   r+   __static_attributes____classcell__)r!   s   @r"   r   r      sU    1j -19= $	$`)$` 7$` 	$`
 
$` $`L   r$   r   c                :    [        S U R                   5       5      $ )Nc              3     #    U  H4  n[        U[        5      =(       a    [        UR                  5      S :  v   M6     g7f)r   N)
isinstancer   len
parameters).0params     r"   	<genexpr>$_is_parameterized.<locals>.<genexpr>   s5      ZcQV
5-.L3u7G7G3H13LLZcs   <>)anyparams)r(   s    r"   r'   r'      s"     Z\ZcZc  r$   c                    Ub%  UR                  U R                  R                  5      $ U R                  R                  U;   $ )zCheck whether the node is supported.

If the target is provided, check using the target, otherwise the supported_gates are used.
)instruction_supportedr(   name)r0   r   r   s      r"   r)   r)      s6    
 ++DGGLL9977<<?**r$   c                l   [        5       nUR                  [        U R                  5       Vs/ s H  n[	        5       PM     sn5        UR                  [        U R
                  5       Vs/ s H  n[        5       PM     sn5        UR                  XR                  UR                  SS9  U$ s  snf s  snf )NF)check)
r
   
add_qubitsrange
num_qubitsr   
num_clbitsr   apply_operation_backqubitsclbits)r(   r/   _s      r"   r,   r,      s    
,CNNU2==%9:%9EG%9:;NNU2==%9:%9EG%9:;RSZZuEJ	 ;:s   B,*B1N)r(   r   r5   bool)r0   r   r   z	list[str]r   r4   r5   rV   )r(   r   r5   r
   )r;   
__future__r   qiskit.circuitr   r   r   r   "qiskit.circuit.equivalence_libraryr   qiskit.convertersr	   qiskit.dagcircuitr
   r   qiskit.exceptionsr   qiskit.transpiler.basepassesr   /qiskit.transpiler.passes.basis.basis_translatorr   qiskit.transpiler.targetr   r   r'   r)   r,    r$   r"   <module>ra      sH    H " I I A , 3 ) ; K +z"4 zz+r$   