§
    º³Ùg  ã                  óº   — d Z ddlmZ ddlmZmZmZmZ ddlm	Z	 ddl
mZ ddlmZmZ ddlmZ ddlmZ dd	lmZ dd
lmZ  G d„ de¦  «        Zdd„Zdd„Zdd„ZdS )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                  ó4   ‡ — e Zd ZdZ	 	 	 ddˆ fd„Zdd„Zˆ xZS )ÚTranslateParameterizedGatesu¹	  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]) â”œ
                                              â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜â””â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”˜

    NÚsupported_gatesúlist[str] | NoneÚequivalence_libraryúEquivalenceLibrary | NoneÚtargetúTarget | NoneÚreturnÚNonec                óÜ   •— t          ¦   «                              ¦   «          |€ddlm} |}|�|j        }n|€t          d¦  «        ‚|| _        || _        t          |||¬¦  «        | _	        dS )a�  
        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.)r   )
ÚsuperÚ__init__Ú9qiskit.circuit.library.standard_gates.equivalence_libraryr   Úoperation_namesÚ
ValueErrorÚ_supported_gatesÚ_targetr   Ú_translator)Úselfr   r   r   r   Ú	__class__s        €úl/granary/edev/quantum/lib/python3.11/site-packages/qiskit/transpiler/passes/basis/translate_parameterized.pyr   z$TranslateParameterizedGates.__init__O   s�   ø€ õ& 	‰Œ×ÒÑÔÐð Ð&ØVÐVÐVÐVÐVÐVà"&Ðð ÐØ$Ô4ˆOˆOØÐ$ÝÐZÑ[Ô[Ð[à /ˆÔØˆŒÝ*Ð+>ÀÐX^Ð_Ñ_Ô_ˆÔÐÐó    Údagr
   c                óÀ  — |                      ¦   «         D ]È}t          |j        ¦  «        r²t          || j        | j        ¦  «        s—|j        j        }|�#|                      t          |¦  «        ¦  «        }nP	 | j	                             t          |j        ¦  «        ¦  «        }n"# t          $ r}t          d¦  «        |‚d}~ww xY w|                     ||¦  «         ŒÉ|S )a)  Run 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$   r(   Únoder.   ÚunrolledÚexcs         r&   r/   zTranslateParameterizedGates.runu   só   € ð —L’L‘N”Nð 	=ð 	=ˆDå  ¤Ñ)Ô)ð =µ-Ø�dÔ+¨T¬\ñ3ô 3ð =ð "œWÔ/�
àÐ)à#Ÿxšx­°zÑ(BÔ(BÑCÔC�H�HðWØ#'Ô#3×#7Ò#7Õ8KÈDÌGÑ8TÔ8TÑ#UÔ#U˜˜øÝ$ð Wð Wð WÝ)Ð*LÑMÔMÐSVÐVøøøøðWøøøð ×,Ò,¨T°8Ñ<Ô<Ð<øàˆ
s   Á8,B%Â%
CÂ/B?Â?C)NNN)r   r   r   r   r   r   r   r   )r(   r
   r   r
   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r/   Ú__classcell__)r%   s   @r&   r   r      st   ø€ € € € € ð1ð 1ðj -1Ø9=Ø $ð	$`ð $`ð $`ð $`ð $`ð $`ð $`ðL ð  ð  ð  ð  ð  ð  ð  r'   r   r,   r   r   Úboolc                ó>   — t          d„ | j        D ¦   «         ¦  «        S )Nc              3  óp   K  — | ]1}t          |t          ¦  «        ot          |j        ¦  «        d k    V — Œ2dS )r   N)Ú
isinstancer   ÚlenÚ
parameters)Ú.0Úparams     r&   ú	<genexpr>z$_is_parameterized.<locals>.<genexpr>™   sS   è è € ð ð ØQV�
�5Õ-Ñ.Ô.ÐLµ3°uÔ7GÑ3HÔ3HÈ1Ò3Lðð ð ð ð ð r'   )ÚanyÚparams)r,   s    r&   r+   r+   ˜   s3   € Ýð ð ØZ\ÔZcðñ ô ñ ô ð r'   r3   r   r   ú	list[str]r   r   c                ó`   — |�|                      | j        j        ¦  «        S | j        j        |v S )z‰Check whether the node is supported.

    If the target is provided, check using the target, otherwise the supported_gates are used.
    )Úinstruction_supportedr,   Úname)r3   r   r   s      r&   r-   r-   ž   s1   € ð
 ÐØ×+Ò+¨D¬G¬LÑ9Ô9Ð9àŒ7Œ<˜?Ð*Ð*r'   r
   c                ó,  — t          ¦   «         }|                     d„ t          | j        ¦  «        D ¦   «         ¦  «         |                     d„ t          | j        ¦  «        D ¦   «         ¦  «         |                     | |j        |j        d¬¦  «         |S )Nc                ó*   — g | ]}t          ¦   «         ‘ŒS © )r   ©rA   Ú_s     r&   ú
<listcomp>z'_instruction_to_dag.<locals>.<listcomp>«   ó   € Ð:Ð:Ð: •E‘G”GÐ:Ð:Ð:r'   c                ó*   — g | ]}t          ¦   «         ‘ŒS rL   )r   rM   s     r&   rO   z'_instruction_to_dag.<locals>.<listcomp>¬   rP   r'   F)Úcheck)r
   Ú
add_qubitsÚrangeÚ
num_qubitsÚ
num_clbitsÚapply_operation_backÚqubitsÚclbits)r,   r(   s     r&   r0   r0   ©   s‡   € Ý
‰,Œ,€CØ‡N‚NÐ:Ð:¥U¨2¬=Ñ%9Ô%9Ð:Ñ:Ô:Ñ;Ô;Ð;Ø‡N‚NÐ:Ð:¥U¨2¬=Ñ%9Ô%9Ð:Ñ:Ô:Ñ;Ô;Ð;Ø×Ò˜R ¤¨S¬Z¸uÐÑEÔEÐEà€Jr'   N)r,   r   r   r;   )r3   r   r   rF   r   r   r   r;   )r,   r   r   r
   )r9   Ú
__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-   r0   rL   r'   r&   ú<module>rc      sB  ðð HÐ Gà "Ð "Ð "Ð "Ð "Ð "à IÐ IÐ IÐ IÐ IÐ IÐ IÐ IÐ IÐ IÐ IÐ IØ AÐ AÐ AÐ AÐ AÐ AØ ,Ð ,Ð ,Ð ,Ð ,Ð ,Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø )Ð )Ð )Ð )Ð )Ð )Ø ;Ð ;Ð ;Ð ;Ð ;Ð ;Ø KÐ KÐ KÐ KÐ KÐ KØ +Ð +Ð +Ð +Ð +Ð +ðzð zð zð zð zÐ"4ñ zô zð zðzð ð ð ð+ð +ð +ð +ðð ð ð ð ð r'   