§
    ¹³Ùg‚b  ã                   óä   — d Z ddlZddlZddlmZmZmZ ddlmZm	Z	m
Z
mZ ddlZddlZddlmZmZmZmZmZmZ ddlmZ ddlmZ ddlmZ dd	lmZ dd
lm Z   edd¦  «        Z! G d„ d¦  «        Z"dS )zH_DAGDependencyV2 class for representing non-commutativity in a circuit.
é    N)ÚOrderedDictÚdefaultdictÚ
namedtuple)ÚDictÚListÚ	GeneratorÚAny)ÚQuantumRegisterÚClassicalRegisterÚQubitÚClbitÚGateÚParameterExpression)Úcondition_resources)ÚBit)Ú	DAGOpNode)ÚDAGDependencyError)ÚCommutationCheckerÚBitLocations)ÚindexÚ	registersc                   óŠ  — e Zd ZdZd„ Zed„ ¦   «         Zej        d„ ¦   «         Zed„ ¦   «         Zej        d„ ¦   «         Zd.d„Z	d	„ Z
d
„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zdedefd„Zd/d„Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd„ Zd.dee e!e!f         fd„Z"d.dee e!e!f         fd „Z#d!„ Z$d"„ Z%d#„ Z&d$„ Z'd%„ Z(d&„ Z)d'„ Z*d(„ Z+d0d+„Z,d1d-„Z-dS )2Ú_DAGDependencyV2uå  Object to represent a quantum circuit as a Directed Acyclic Graph (DAG)
    via operation dependencies (i.e. lack of commutation).

    .. warning::

        This is not part of the public API.

    The nodes in the graph are operations represented by quantum gates.
    The edges correspond to non-commutation between two operations
    (i.e. a dependency). A directed edge from node A to node B means that
    operation A does not commute with operation B.
    The object's methods allow circuits to be constructed.

    **Example:**

    Bell circuit with no measurement.

    .. code-block:: text

              â”Œâ”€â”€â”€â”�
        qr_0: â”¤ H â”œâ”€â”€â– â”€â”€
              â””â”€â”€â”€â”˜â”Œâ”€â”´â”€â”�
        qr_1: â”€â”€â”€â”€â”€â”¤ X â”œ
                   â””â”€â”€â”€â”˜

    The dependency DAG for the above circuit is represented by two nodes.
    The first one corresponds to Hadamard gate, the second one to the CNOT gate
    as the gates do not commute there is an edge between the two nodes.

    **Reference:**

    [1] Iten, R., Moyard, R., Metger, T., Sutter, D. and Woerner, S., 2020.
    Exact and practical pattern matching for quantum circuit optimization.
    `arXiv:1909.05270 <https://arxiv.org/abs/1909.05270>`_

    c                 ót  — d| _         i | _        i | _        t          j        ¦   «         | _        t          ¦   «         | _        t          ¦   «         | _        g | _	        g | _
        i | _        i | _        d| _        t          t          ¦  «        | _        i | _        d| _        d| _        t)          ¦   «         | _        dS )z3
        Create an empty _DAGDependencyV2.
        Nr   Údt)ÚnameÚmetadataÚ
_key_cacheÚrxÚPyDAGÚ_multi_graphr   ÚqregsÚcregsÚqubitsÚclbitsÚ_qubit_indicesÚ_clbit_indicesÚ_global_phaser   ÚdictÚ_calibrationsÚ	_op_namesÚdurationÚunitr   Úcomm_checker©Úselfs    úX/granary/edev/quantum/lib/python3.11/site-packages/qiskit/dagcircuit/dagdependency_v2.pyÚ__init__z_DAGDependencyV2.__init__P   sª   € ð
 ˆŒ	ð ˆŒð ˆŒõ œH™JœJˆÔõ !‘]”]ˆŒ
Ý ‘]”]ˆŒ
ð $&ˆŒØ#%ˆŒð :<ˆÔØ9;ˆÔàˆÔÝ(­Ñ.Ô.ˆÔð ˆŒàˆŒØˆŒ	å.Ñ0Ô0ˆÔÐÐó    c                 ó   — | j         S )z'Return the global phase of the circuit.)r(   r/   s    r1   Úglobal_phasez_DAGDependencyV2.global_phase{   s   € ð Ô!Ð!r3   c                 ó¤   — t          |t          ¦  «        r	|| _        dS t          |¦  «        }|s	d| _        dS |dt          j        z  z  | _        dS )zkSet the global phase of the circuit.

        Args:
            angle (float, ParameterExpression)
        r   é   N)Ú
isinstancer   r(   ÚfloatÚmathÚpi)r0   Úangles     r1   r5   z_DAGDependencyV2.global_phase€   sa   € õ �eÕ0Ñ1Ô1ð 	;Ø!&ˆDÔÐÐõ ˜%‘L”LˆEØð ;Ø%&�Ô"Ð"Ð"à%*¨aµ$´'©kÑ%:�Ô"Ð"Ð"r3   c                 ó*   — t          | j        ¦  «        S )z¤Return calibration dictionary.

        The custom pulse definition of a given gate is of the form
        ``{'gate_name': {(qubits, params): schedule}}``.
        )r)   r*   r/   s    r1   Úcalibrationsz_DAGDependencyV2.calibrations‘   s   € õ �DÔ&Ñ'Ô'Ð'r3   c                 ó:   — t          t          |¦  «        | _        dS )zëSet the circuit calibration data from a dictionary of calibration definition.

        Args:
            calibrations (dict): A dictionary of input in the format
                {'gate_name': {(qubits, gate_params): schedule}}
        N)r   r)   r*   )r0   r>   s     r1   r>   z_DAGDependencyV2.calibrationsš   s   € õ )­¨|Ñ<Ô<ˆÔÐÐr3   Nc                 óÔ   — d„ }t          |t          ¦  «        r|j        }|j        }|�t	          t          ||¦  «        ¦  «        }nd}|| j        |         t	          |¦  «        |f<   dS )aÁ  Register a low-level, custom pulse definition for the given gate.

        Args:
            gate (Union[Gate, str]): Gate information.
            qubits (Union[int, Tuple[int]]): List of qubits to be measured.
            schedule (Schedule): Schedule information.
            params (Optional[List[Union[float, Parameter]]]): A list of parameters.

        Raises:
            Exception: if the gate is of type string and params is None.
        c                 óà   — 	 t          | ¦  «        }t          j        |¦  «        r7t          |j        ¦  «        }|                     ¦   «         rt          |¦  «        }|S # t          $ r | cY S w xY w©N)ÚcomplexÚnpÚisrealr9   ÚrealÚ
is_integerÚintÚ	TypeError)ÚoperandÚ	evaluateds     r1   Ú_formatz1_DAGDependencyV2.add_calibration.<locals>._format±   s€   € ðõ $ GÑ,Ô,�	Ý”9˜YÑ'Ô'ð 3Ý % i¤nÑ 5Ô 5�IØ ×+Ò+Ñ-Ô-ð 3Ý$'¨	¡N¤N˜	Ø Ð øÝð ð ð à���ðøøøs   ‚AA ÁA-Á,A-N© )r8   r   Úparamsr   ÚtupleÚmapr*   )r0   Úgater$   ÚschedulerN   rL   s         r1   Úadd_calibrationz _DAGDependencyV2.add_calibration¤   sz   € ð	ð 	ð 	õ" �d�DÑ!Ô!ð 	Ø”[ˆFØ”9ˆDØÐÝ�3˜w¨Ñ/Ô/Ñ0Ô0ˆFˆFàˆFà<DˆÔ˜4Ô ¥%¨¡-¤-°Ð!8Ñ9Ð9Ð9r3   c                 óš  ‡ — ‰ j         r|j        j        ‰ j         vrdS t          ˆ fd„|j        D ¦   «         ¦  «        }g }|j        j        D ]V}t          |t          ¦  «        r*|j        s#| 	                    t          |¦  «        ¦  «         ŒA| 	                    |¦  «         ŒWt          |¦  «        }||f‰ j         |j        j                 v S )z©Return True if the dag has a calibration defined for the node operation. In this
        case, the operation does not need to be translated to the device basis.
        Fc              3   óL   •K  — | ]}‰j                              |¦  «        V — Œd S rB   )r$   r   )Ú.0Úqubitr0   s     €r1   ú	<genexpr>z7_DAGDependencyV2.has_calibration_for.<locals>.<genexpr>Ò   s3   øè è € ÐHÐH°E�t”{×(Ò(¨Ñ/Ô/ÐHÐHÐHÐHÐHÐHr3   )r>   Úopr   rO   ÚqargsrN   r8   r   Ú
parametersÚappendr9   )r0   Únoder$   rN   Úps   `    r1   Úhas_calibration_forz$_DAGDependencyV2.has_calibration_forÌ   sÕ   ø€ ð Ô ð 	 D¤G¤L¸Ô8IÐ$IÐ$IØ�5ÝÐHÐHÐHÐH¸T¼ZÐHÑHÔHÑHÔHˆØˆØ””ð 	!ð 	!ˆAÝ˜!Õ0Ñ1Ô1ð !¸!¼,ð !Ø—’�e A™hœhÑ'Ô'Ð'Ð'à—’˜aÑ Ô Ð Ð Ý�v‘”ˆØ˜Ð 4Ô#4°T´W´\Ô#BÐBÐBr3   c                 ó*   — t          | j        ¦  «        S )z*Returns the number of gates in the circuit)Úlenr!   r/   s    r1   Úsizez_DAGDependencyV2.sizeÜ   s   € å�4Ô$Ñ%Ô%Ð%r3   c                 óH   — t          j        | j        ¦  «        }|dk    r|ndS )zVReturn the circuit depth.
        Returns:
            int: the circuit depth
        r   )r   Údag_longest_path_lengthr!   )r0   Údepths     r1   re   z_DAGDependencyV2.depthà   s)   € õ
 Ô*¨4Ô+<Ñ=Ô=ˆØ š
˜
ˆuˆu¨Ð)r3   c                 óT   — t          | j        ¦  «        t          | j        ¦  «        z   S )z?Return the total number of qubits + clbits used by the circuit.)ra   r$   r%   r/   s    r1   Úwidthz_DAGDependencyV2.widthè   s!   € å�4”;ÑÔ¥# d¤kÑ"2Ô"2Ñ2Ð2r3   c                 ó*   — t          | j        ¦  «        S )z6Return the total number of qubits used by the circuit.)ra   r$   r/   s    r1   Ú
num_qubitsz_DAGDependencyV2.num_qubitsì   ó   € å�4”;ÑÔÐr3   c                 ó*   — t          | j        ¦  «        S )z>Return the total number of classical bits used by the circuit.)ra   r%   r/   s    r1   Ú
num_clbitsz_DAGDependencyV2.num_clbitsð   rj   r3   c                 ód  — t          d„ |D ¦   «         ¦  «        rt          d¦  «        ‚t          | j        ¦  «                             |¦  «        }|rt          d|› �¦  «        ‚|D ]I}| j                             |¦  «         t          t          | j        ¦  «        dz
  g ¦  «        | j        |<   ŒJdS )zAdd individual qubit wires.c              3   óB   K  — | ]}t          |t          ¦  «         V — Œd S rB   )r8   r   )rV   rW   s     r1   rX   z._DAGDependencyV2.add_qubits.<locals>.<genexpr>ö   ó/   è è € Ð@Ð@°•:˜e¥UÑ+Ô+Ð+Ð@Ð@Ð@Ð@Ð@Ð@r3   znot a Qubit instance.zduplicate qubits é   N)	Úanyr   Úsetr$   Úintersectionr\   r   ra   r&   )r0   r$   Úduplicate_qubitsrW   s       r1   Ú
add_qubitsz_DAGDependencyV2.add_qubitsô   óË   € åÐ@Ð@¸Ð@Ñ@Ô@Ñ@Ô@ð 	>Ý$Ð%<Ñ=Ô=Ð=å˜tœ{Ñ+Ô+×8Ò8¸Ñ@Ô@ÐØð 	MÝ$Ð%KÐ9IÐ%KÐ%KÑLÔLÐLàð 	Pð 	PˆEØŒK×Ò˜uÑ%Ô%Ð%Ý)5µc¸$¼+Ñ6FÔ6FÈÑ6JÈBÑ)OÔ)OˆDÔ Ñ&Ð&ð	Pð 	Pr3   c                 ód  — t          d„ |D ¦   «         ¦  «        rt          d¦  «        ‚t          | j        ¦  «                             |¦  «        }|rt          d|› �¦  «        ‚|D ]I}| j                             |¦  «         t          t          | j        ¦  «        dz
  g ¦  «        | j        |<   ŒJdS )zAdd individual clbit wires.c              3   óB   K  — | ]}t          |t          ¦  «         V — Œd S rB   )r8   r   )rV   Úclbits     r1   rX   z._DAGDependencyV2.add_clbits.<locals>.<genexpr>  ro   r3   znot a Clbit instance.zduplicate clbits rp   N)	rq   r   rr   r%   rs   r\   r   ra   r'   )r0   r%   Úduplicate_clbitsry   s       r1   Ú
add_clbitsz_DAGDependencyV2.add_clbits  rv   r3   c                 óF  — t          |t          ¦  «        st          d¦  «        ‚|j        | j        v rt          d|j        › �¦  «        ‚|| j        |j        <   t          | j        ¦  «        }t          |j        ¦  «        D ]Ÿ}||         | j	        v r-| j	        ||                  j
                             ||f¦  «         ||         |vrW| j                             ||         ¦  «         t          t          | j        ¦  «        dz
  ||fg¬¦  «        | j	        ||         <   Œ dS )z!Add qubits in a quantum register.znot a QuantumRegister instance.úduplicate register rp   ©r   N)r8   r
   r   r   r"   rr   r$   Úrangerb   r&   r   r\   r   ra   )r0   ÚqregÚexisting_qubitsÚjs       r1   Úadd_qregz_DAGDependencyV2.add_qreg  s)  € å˜$¥Ñ0Ô0ð 	HÝ$Ð%FÑGÔGÐGØŒ9˜œ
Ð"Ð"Ý$Ð%F¸4¼9Ð%FÐ%FÑGÔGÐGØ $ˆŒ
�4”9ÑÝ˜dœkÑ*Ô*ˆÝ�t”yÑ!Ô!ð 	ð 	ˆAØ�AŒw˜$Ô-Ð-Ð-ØÔ# D¨¤GÔ,Ô6×=Ò=¸tÀQ¸iÑHÔHÐHØ�AŒw˜oÐ-Ð-Ø”×"Ò" 4¨¤7Ñ+Ô+Ð+Ý/;Ý˜œÑ$Ô$ qÑ(°d¸A°Y°Kð0ñ 0ô 0�Ô# D¨¤GÑ,øð	ð 	r3   c                 óF  — t          |t          ¦  «        st          d¦  «        ‚|j        | j        v rt          d|j        › �¦  «        ‚|| j        |j        <   t          | j        ¦  «        }t          |j        ¦  «        D ]Ÿ}||         | j	        v r-| j	        ||                  j
                             ||f¦  «         ||         |vrW| j                             ||         ¦  «         t          t          | j        ¦  «        dz
  ||fg¬¦  «        | j	        ||         <   Œ dS )z#Add clbits in a classical register.z!not a ClassicalRegister instance.r}   rp   r~   N)r8   r   r   r   r#   rr   r%   r   rb   r'   r   r\   r   ra   )r0   ÚcregÚexisting_clbitsr‚   s       r1   Úadd_cregz_DAGDependencyV2.add_creg  s*  € å˜$Õ 1Ñ2Ô2ð 	JÝ$Ð%HÑIÔIÐIØŒ9˜œ
Ð"Ð"Ý$Ð%F¸4¼9Ð%FÐ%FÑGÔGÐGØ $ˆŒ
�4”9ÑÝ˜dœkÑ*Ô*ˆÝ�t”yÑ!Ô!ð 	ð 	ˆAØ�AŒw˜$Ô-Ð-Ð-ØÔ# D¨¤GÔ,Ô6×=Ò=¸tÀQ¸iÑHÔHÐHØ�AŒw˜oÐ-Ð-Ø”×"Ò" 4¨¤7Ñ+Ô+Ð+Ý/;Ý˜œÑ$Ô$ qÑ(°d¸A°Y°Kð0ñ 0ô 0�Ô# D¨¤GÑ,øð	ð 	r3   ÚbitÚreturnc                 ó  — 	 t          |t          ¦  «        r| j        |         S t          |t          ¦  «        r| j        |         S t          dt          |¦  «        › �¦  «        ‚# t          $ r}t          d|› d�¦  «        |‚d}~ww xY w)a  
        Finds locations in the _DAGDependencyV2, by mapping the Qubit and Clbit to positional index
        BitLocations is defined as: BitLocations = namedtuple("BitLocations", ("index", "registers"))

        Args:
            bit (Bit): The bit to locate.

        Returns:
            namedtuple(int, List[Tuple(Register, int)]): A 2-tuple. The first element (``index``)
                contains the index at which the ``Bit`` can be found (in either
                :obj:`~_DAGDependencyV2.qubits`, :obj:`~_DAGDependencyV2.clbits`, depending on its
                type). The second element (``registers``) is a list of ``(register, index)``
                pairs with an entry for each :obj:`~Register` in the circuit which contains the
                :obj:`~Bit` (and the index in the :obj:`~Register` at which it can be found).

          Raises:
            DAGDependencyError: If the supplied :obj:`~Bit` was of an unknown type.
            DAGDependencyError: If the supplied :obj:`~Bit` could not be found on the circuit.
        z&Could not locate bit of unknown type: zCould not locate provided bit: z). Has it been added to the DAGDependency?N)r8   r   r&   r   r'   r   ÚtypeÚKeyError)r0   rˆ   Úerrs      r1   Úfind_bitz_DAGDependencyV2.find_bit0  s¬   € ð(
	Ý˜#�uÑ%Ô%ð _ØÔ*¨3Ô/Ð/Ý˜C¥Ñ'Ô'ð _ØÔ*¨3Ô/Ð/å(Ð)]ÕRVÐWZÑR[ÔR[Ð)]Ð)]Ñ^Ô^Ð^øÝð 	ð 	ð 	Ý$Ø`°#Ð`Ð`Ð`ñô àðøøøøð	øøøs"   ‚!A% ¤!A% ÁA% Á%
BÁ/BÂBrM   c                 óÄ   — t          |||¬¦  «        }| j                             |¦  «        |_        |                      ¦   «          |                      |j        ¦  «         dS )a:  Add a DAGOpNode to the graph and update the edges.

        Args:
            operation (qiskit.circuit.Operation): operation as a quantum gate
            qargs (list[~qiskit.circuit.Qubit]): list of qubits on which the operation acts
            cargs (list[Clbit]): list of classical wires to attach to
        )rY   rZ   ÚcargsN)r   r!   Úadd_nodeÚ_node_idÚ_update_edgesÚ_increment_oprY   )r0   Ú	operationrZ   r�   Únew_nodes        r1   Úapply_operation_backz%_DAGDependencyV2.apply_operation_backP  sj   € õ ØØØð
ñ 
ô 
ˆð
 !Ô-×6Ò6°xÑ@Ô@ˆÔØ×ÒÑÔÐØ×Ò˜8œ;Ñ'Ô'Ð'Ð'Ð'r3   c           	      ó²  — t          | j        ¦  «        dz
  }|                      |¦  «        }dg|z  }t          |dz
  dd¦  «        D �]}||         rº|                      |¦  «        }| j                             |j        |j        |j        |j        |j        |j        ¦  «        sg| j         	                    ||ddi¦  «         t          d„ |                      |                      |¦  «        ¦  «        D ¦   «         ¦  «        }|D ]}d||<   ŒŒÅt          d„ |                      |                      |¦  «        ¦  «        D ¦   «         ¦  «        }|D ]}d||<   Œ�ŒdS )	a�  
        Updates DagDependencyV2 by adding edges to the newly added node (max_node)
        from the previously added nodes.
        For each previously added node (prev_node), an edge from prev_node to max_node
        is added if max_node is "reachable" from prev_node (this means that the two
        nodes can be made adjacent by commuting them with other nodes), but the two nodes
        themselves do not commute.

        Currently. this function is only used when creating a new _DAGDependencyV2 from another
        representation of a circuit, and hence there are no removed nodes (this is why
        iterating over all nodes is fine).
        rp   TéÿÿÿÿÚcommuteFc                 ó   — g | ]	}|j         ‘Œ
S rM   ©r’   ©rV   r]   s     r1   ú
<listcomp>z2_DAGDependencyV2._update_edges.<locals>.<listcomp>‰  s   € ÐcÐcÐc¨4˜œÐcÐcÐcr3   c                 ó   — g | ]	}|j         ‘Œ
S rM   rœ   r�   s     r1   rž   z2_DAGDependencyV2._update_edges.<locals>.<listcomp>‘  s   € Ð_Ð_Ð_ t�T”]Ð_Ð_Ð_r3   N)ra   r!   Ú	_get_noder   r.   rš   rY   rZ   r�   Úadd_edgeÚsortedÚpredecessors)r0   Úmax_node_idÚmax_nodeÚ	reachableÚprev_node_idÚ	prev_nodeÚpredecessor_idsÚpredecessor_ids           r1   r“   z_DAGDependencyV2._update_edgesa  s•  € õ ˜$Ô+Ñ,Ô,¨qÑ0ˆØ—>’> +Ñ.Ô.ˆà�F˜[Ñ(ˆ	õ " +°¡/°2°rÑ:Ô:ð 	6ñ 	6ˆLØ˜Ô&ð 6Ø ŸNšN¨<Ñ8Ô8�	àÔ(×0Ò0Ø”LØ”OØ”OØ”KØ”NØ”Nñô ð :ð Ô%×.Ò.¨|¸[È9ÐV[ÐJ\Ñ]Ô]Ð]å&,ØcÐc°4×3DÒ3DÀTÇ^Â^ÐT`ÑEaÔEaÑ3bÔ3bÐcÑcÔcñ'ô '�Oð +:ð :ð :˜Ø49˜	 .Ñ1Ð1øõ #)Ø_Ð_¨t×/@Ò/@ÀÇÂÐP\ÑA]ÔA]Ñ/^Ô/^Ð_Ñ_Ô_ñ#ô #�ð '6ð 6ð 6�NØ05�I˜nÑ-Ð-ñ6ð9	6ð 	6r3   c                 ó6   — | j                              |¦  «        S )zŒ
        Args:
            node_id (int): label of considered node.

        Returns:
            node: corresponding to the label.
        )r!   Úget_node_data)r0   Únode_ids     r1   r    z_DAGDependencyV2._get_node–  s   € ð Ô ×.Ò.¨wÑ7Ô7Ð7r3   c                 óˆ   — g }| j                              ¦   «         D ]%}|j        j        |v r|                     |¦  «         Œ&|S )z.Get the set of "op" nodes with the given name.)r!   ÚnodesrY   r   r\   )r0   ÚnamesÚnamed_nodesr]   s       r1   r±   z_DAGDependencyV2.named_nodes   sO   € àˆØÔ%×+Ò+Ñ-Ô-ð 	)ð 	)ˆDØŒwŒ|˜uÐ$Ð$Ø×"Ò" 4Ñ(Ô(Ð(øØÐr3   c                 óx   — |j         | j        v r| j        |j         xx         dz  cc<   d S d| j        |j         <   d S ©Nrp   )r   r+   ©r0   rY   s     r1   r”   z_DAGDependencyV2._increment_op¨  sK   € ØŒ7�d”nÐ$Ð$ØŒN˜2œ7Ð#Ð#Ô# qÑ(Ð#Ð#Ñ#Ð#Ð#à&'ˆDŒN˜2œ7Ñ#Ð#Ð#r3   c                 ó„   — | j         |j                 dk    r| j         |j        = d S | j         |j        xx         dz  cc<   d S r³   )r+   r   r´   s     r1   Ú_decrement_opz_DAGDependencyV2._decrement_op®  sN   € ØŒ>˜"œ'Ô" aÒ'Ð'Ø”˜rœwÐ'Ð'Ð'àŒN˜2œ7Ð#Ð#Ô# qÑ(Ð#Ð#Ñ#Ð#Ð#r3   c                 ó   — | j         S )z)Count the occurrences of operation names.)r+   r/   s    r1   Ú	count_opsz_DAGDependencyV2.count_ops´  s
   € àŒ~Ðr3   c                 óN   — t          | j                             ¦   «         ¦  «        S )zT
        Returns:
            generator(dict): iterator over all the nodes.
        )Úiterr!   r¯   r/   s    r1   Úop_nodesz_DAGDependencyV2.op_nodes¸  s!   € õ
 �DÔ%×+Ò+Ñ-Ô-Ñ.Ô.Ð.r3   c                 óf   ‡ — ˆ fd„}|€|}t          t          j        ‰ j        |¬¦  «        ¦  «        S )a�  
        Yield nodes in topological order.

        Args:
            key (Callable): A callable which will take a DAGNode object and
                return a string sort key. If not specified the
                :attr:`~qiskit.dagcircuit.DAGNode.sort_key` attribute will be
                used as the sort key for each node.

        Returns:
            generator(DAGOpNode): node in topological order
        c                 ó€   •— d                      ˆfd„t          j        | j        | j        ¦  «        D ¦   «         ¦  «        S )Nú,c              3   óP   •K  — | ] }‰                      |¦  «        j        d ›V — Œ!dS )Ú04dN)rŽ   r   )rV   Úqr0   s     €r1   rX   zC_DAGDependencyV2.topological_nodes.<locals>._key.<locals>.<genexpr>Î  sI   øè è € ð ð Ø45�4—=’= Ñ#Ô#Ô)Ð/Ð/ðð ð ð ð ð r3   )ÚjoinÚ	itertoolsÚchainrZ   r�   )Úxr0   s    €r1   Ú_keyz0_DAGDependencyV2.topological_nodes.<locals>._keyÍ  sQ   ø€ Ø—8’8ð ð ð ð Ý9B¼ÈÌÐRSÔRYÑ9ZÔ9Zðñ ô ñ ô ð r3   N©Úkey)rº   r   Ú lexicographical_topological_sortr!   )r0   rÈ   rÆ   s   `  r1   Útopological_nodesz"_DAGDependencyV2.topological_nodes¿  sI   ø€ ð	ð 	ð 	ð 	ð 	ð
 ˆ;ØˆCå•BÔ7¸Ô8IÈsÐSÑSÔSÑTÔTÐTr3   c                 ó,   — |                       |¦  «        S )a<  
        Yield nodes in topological order. This is a wrapper for topological_nodes since
        all nodes are op nodes. It's here so that calls to dag.topological_op_nodes can
        use either DAGCircuit or _DAGDependencyV2.

        Returns:
            generator(DAGOpNode): nodes in topological order.
        )rÊ   )r0   rÈ   s     r1   Útopological_op_nodesz%_DAGDependencyV2.topological_op_nodes×  s   € ð ×%Ò% cÑ*Ô*Ð*r3   c                 óZ   — t          | j                             |j        ¦  «        ¦  «        S )z;Returns iterator of the successors of a node as DAGOpNodes.)rº   r!   Ú
successorsr’   ©r0   r]   s     r1   rÎ   z_DAGDependencyV2.successorsâ  s#   € å�DÔ%×0Ò0°´Ñ?Ô?Ñ@Ô@Ð@r3   c                 óZ   — t          | j                             |j        ¦  «        ¦  «        S )z=Returns iterator of the predecessors of a node as DAGOpNodes.)rº   r!   r£   r’   rÏ   s     r1   r£   z_DAGDependencyV2.predecessorsæ  s#   € å�DÔ%×2Ò2°4´=ÑAÔAÑBÔBÐBr3   c                 óL   — | j                              |j        |j        ¦  «        S )z5Checks if a second node is in the successors of node.©r!   Úhas_edger’   )r0   r]   Ú	node_succs      r1   Úis_successorz_DAGDependencyV2.is_successorê  s    € àÔ ×)Ò)¨$¬-¸Ô9KÑLÔLÐLr3   c                 óL   — | j                              |j        |j        ¦  «        S )z7Checks if a second node is in the predecessors of node.rÒ   )r0   r]   Ú	node_preds      r1   Úis_predecessorz_DAGDependencyV2.is_predecessorî  s    € àÔ ×)Ò)¨)Ô*<¸d¼mÑLÔLÐLr3   c                 óZ   ‡ — ˆ fd„t          j        ‰ j        |j        ¦  «        D ¦   «         S )z5Returns set of the ancestors of a node as DAGOpNodes.c                 ó*   •— h | ]}‰j         |         ’ŒS rM   ©r!   ©rV   rÅ   r0   s     €r1   ú	<setcomp>z-_DAGDependencyV2.ancestors.<locals>.<setcomp>ô  s!   ø€ Ð]Ð]Ð]¨�Ô! !Ô$Ð]Ð]Ð]r3   )r   Ú	ancestorsr!   r’   rÏ   s   ` r1   rÞ   z_DAGDependencyV2.ancestorsò  s.   ø€ à]Ð]Ð]Ð]­b¬l¸4Ô;LÈdÌmÑ.\Ô.\Ð]Ñ]Ô]Ð]r3   c                 óZ   ‡ — ˆ fd„t          j        ‰ j        |j        ¦  «        D ¦   «         S )z7Returns set of the descendants of a node as DAGOpNodes.c                 ó*   •— h | ]}‰j         |         ’ŒS rM   rÛ   rÜ   s     €r1   rÝ   z/_DAGDependencyV2.descendants.<locals>.<setcomp>ø  s!   ø€ Ð_Ð_Ð_¨�Ô! !Ô$Ð_Ð_Ð_r3   )r   Údescendantsr!   r’   rÏ   s   ` r1   rá   z_DAGDependencyV2.descendantsö  s0   ø€ à_Ð_Ð_Ð_­b¬n¸TÔ=NÐPTÔP]Ñ.^Ô.^Ð_Ñ_Ô_Ð_r3   c                 óZ   — t          t          j        | j        |j        ¦  «        ¦  «        S )z­
        Returns an iterator of tuples of (DAGOpNode, [DAGOpNodes]) where the DAGOpNode is the
        current node and [DAGOpNode] is its successors in  BFS order.
        )rº   r   Úbfs_successorsr!   r’   rÏ   s     r1   rã   z_DAGDependencyV2.bfs_successorsú  s$   € õ
 •BÔ% dÔ&7¸¼ÑGÔGÑHÔHÐHr3   c                 óö  — t          ¦   «         }| j        |_        | j        |_        | j        |_        | j        |_        | j        |_        | j        |_        | j        |_        |                     | j	        ¦  «         | 
                    | j        ¦  «         | j                             ¦   «         D ]}|                     |¦  «         Œ| j                             ¦   «         D ]}|                     |¦  «         Œ|S )aD  Return a copy of self with the same structure but empty.

        That structure includes:
            * name and other metadata
            * global phase
            * duration
            * all the qubits and clbits, including the registers.

        Returns:
            _DAGDependencyV2: An empty copy of self.
        )r   r   r(   r,   r-   r   r   r.   ru   r$   r{   r%   r"   Úvaluesrƒ   r#   r‡   )r0   Ú
target_dagr€   r…   s       r1   Úcopy_empty_likez _DAGDependencyV2.copy_empty_like  sï   € õ &Ñ'Ô'ˆ
Øœ)ˆ
ŒØ#'Ô#5ˆ
Ô Ø"œmˆ
ÔØœ)ˆ
ŒØ"œmˆ
ÔØ $¤ˆ
ÔØ"&Ô"3ˆ
Ôà×Ò˜dœkÑ*Ô*Ð*Ø×Ò˜dœkÑ*Ô*Ð*à”J×%Ò%Ñ'Ô'ð 	&ð 	&ˆDØ×Ò Ñ%Ô%Ð%Ð%Ø”J×%Ò%Ñ'Ô'ð 	&ð 	&ˆDØ×Ò Ñ%Ô%Ð%Ð%àÐr3   çffffffæ?Úcolorc                 ó,   — ddl m}  || |||¬¦  «        S )aF  
        Draws the _DAGDependencyV2 graph.

        This function needs `pydot <https://github.com/erocarrera/pydot>`, which in turn needs
        Graphviz <https://www.graphviz.org/>` to be installed.

        Args:
            scale (float): scaling factor
            filename (str): file path to save image to (format inferred from name)
            style (str): 'plain': B&W graph
                         'color' (default): color input/output/op nodes

        Returns:
            Ipython.display.Image: if in Jupyter notebook and not saving to file, otherwise None.
        r   )Ú
dag_drawer)ÚdagÚscaleÚfilenameÚstyle)Ú&qiskit.visualization.dag_visualizationrë   )r0   rí   rî   rï   rë   s        r1   Údrawz_DAGDependencyV2.draw   s0   € ð  	FÐEÐEÐEÐEÐEàˆz˜d¨%¸(È%ÐPÑPÔPÐPr3   Tc           	      óÊ  ‡— t          ¦   «         }t          ¦   «         }d„ |D ¦   «         }|st          d¦  «        ‚|D ]o}|t          |j        ¦  «        z  }|t          |j        ¦  «        z  }t	          |j        dd¦  «        }	|	�'|                     t          |	¦  «        j        ¦  «         Œpt          |t          |ˆfd„¬¦  «        t          |ˆfd„¬¦  «        | ¬¦  «        }
	 | j                             ||
|¬	¦  «        |
_        n'# t          j        $ r}t          d
¦  «        |‚d}~ww xY w|                      |¦  «         |D ]}|                      |j        ¦  «         Œ|
S )a
  Replace a block of nodes with a single node.

        This is used to consolidate a block of DAGOpNodes into a single
        operation. A typical example is a block of CX and SWAP gates consolidated
        into a LinearFunction. This function is an adaptation of a similar
        function from DAGCircuit.

        It is important that such consolidation preserves commutativity assumptions
        present in _DAGDependencyV2. As an example, suppose that every node in a
        block [A, B, C, D] commutes with another node E. Let F be the consolidated
        node, F = A o B o C o D. Then F also commutes with E, and thus the result of
        replacing [A, B, C, D] by F results in a valid _DAGDependencyV2. That is, any
        deduction about commutativity in consolidated _DAGDependencyV2 is correct.
        On the other hand, suppose that at least one of the nodes, say B, does not commute
        with E. Then the consolidated _DAGDependencyV2 would imply that F does not commute
        with E. Even though F and E may actually commute, it is still safe to assume that
        they do not. That is, the current implementation of consolidation may lead to
        suboptimal but not to incorrect results.

        Args:
            node_block (List[DAGOpNode]): A list of dag nodes that represents the
                node block to be replaced
            op (qiskit.circuit.Operation): The operation to replace the
                block with
            wire_pos_map (Dict[~qiskit.circuit.Qubit, int]): The dictionary mapping the qarg to
                the position. This is necessary to reconstruct the qarg order
                over multiple gates in the combined single op node.
            cycle_check (bool): When set to True this method will check that
                replacing the provided ``node_block`` with a single node
                would introduce a cycle (which would invalidate the
                ``_DAGDependencyV2``) and will raise a ``DAGDependencyError`` if a cycle
                would be introduced. This checking comes with a run time
                penalty. If you can guarantee that your input ``node_block`` is
                a contiguous block and won't introduce a cycle when it's
                contracted to a single node, this can be set to ``False`` to
                improve the runtime performance of this method.
        Raises:
            DAGDependencyError: if ``cycle_check`` is set to ``True`` and replacing
                the specified block introduces a cycle or if ``node_block`` is
                empty.
        c                 ó   — g | ]	}|j         ‘Œ
S rM   rœ   )rV   rÅ   s     r1   rž   z:_DAGDependencyV2.replace_block_with_op.<locals>.<listcomp>`  s   € Ð4Ð4Ð4 A�Q”ZÐ4Ð4Ð4r3   z!Can't replace an empty node_blockÚ	conditionNc                 ó   •— ‰|          S rB   rM   ©rÅ   Úwire_pos_maps    €r1   ú<lambda>z8_DAGDependencyV2.replace_block_with_op.<locals>.<lambda>p  ó   ø€ °LÀ´O€ r3   rÇ   c                 ó   •— ‰|          S rB   rM   rö   s    €r1   rø   z8_DAGDependencyV2.replace_block_with_op.<locals>.<lambda>q  rù   r3   )rZ   r�   rì   )Úcheck_cyclez:Replacing the specified node block would introduce a cycle)rr   r   rZ   r�   ÚgetattrrY   Úupdater   r%   r   r¢   r!   Úcontract_nodesr’   r   ÚDAGWouldCycler”   r¶   )r0   Ú
node_blockrY   r÷   Úcycle_checkÚblock_qargsÚblock_cargsÚ	block_idsÚndÚcondr–   Úexs      `        r1   Úreplace_block_with_opz&_DAGDependencyV2.replace_block_with_op4  s³  ø€ õT ‘e”eˆÝ‘e”eˆØ4Ð4¨Ð4Ñ4Ô4ˆ	ð ð 	JÝ$Ð%HÑIÔIÐIàð 	Eð 	EˆBØ�3˜rœx™=œ=Ñ(ˆKØ�3˜rœx™=œ=Ñ(ˆKÝ˜2œ5 +¨tÑ4Ô4ˆDØÐØ×"Ò"Õ#6°tÑ#<Ô#<Ô#CÑDÔDÐDøõ ØÝ˜Ð*CÐ*CÐ*CÐ*CÐDÑDÔDÝ˜Ð*CÐ*CÐ*CÐ*CÐDÑDÔDØð	
ñ 
ô 
ˆð	Ø $Ô 1× @Ò @Ø˜8°ð !Añ !ô !ˆHÔÐøõ Ôð 	ð 	ð 	Ý$ØLñô àðøøøøð	øøøð
 	×Ò˜2ÑÔÐàð 	&ð 	&ˆBØ×Ò˜rœuÑ%Ô%Ð%Ð%àˆs   Ã%"D ÄD,ÄD'Ä'D,rB   )rM   rM   )rè   Nré   )T).Ú__name__Ú
__module__Ú__qualname__Ú__doc__r2   Úpropertyr5   Úsetterr>   rS   r_   rb   re   rg   ri   rl   ru   r{   rƒ   r‡   r   r   rŽ   r—   r“   r    r±   r”   r¶   r¸   r»   r   r   r	   rÊ   rÌ   rÎ   r£   rÕ   rØ   rÞ   rá   rã   rç   rñ   r  rM   r3   r1   r   r   *   s  € € € € € ð#ð #ðJ)1ð )1ð )1ðV ð"ð "ñ „Xð"ð Ôð;ð ;ñ Ôð;ð  ð(ð (ñ „Xð(ð Ôð=ð =ñ Ôð=ð&Eð &Eð &Eð &EðPCð Cð Cð &ð &ð &ð*ð *ð *ð3ð 3ð 3ð ð  ð  ð ð  ð  ðPð Pð PðPð Pð Pðð ð ð"ð ð ð"˜Cð  Lð ð ð ð ð@(ð (ð (ð (ð"36ð 36ð 36ðj8ð 8ð 8ðð ð ð(ð (ð (ð)ð )ð )ðð ð ð/ð /ð /ðUð U¨Y°yÀ#ÀsÐ7JÔ-Kð Uð Uð Uð Uð0	+ð 	+°	¸)ÀSÈ#Ð:MÔ0Nð 	+ð 	+ð 	+ð 	+ðAð Að AðCð Cð CðMð Mð MðMð Mð Mð^ð ^ð ^ð`ð `ð `ðIð Ið Iðð ð ð>Qð Qð Qð Qð(Oð Oð Oð Oð Oð Or3   r   )#r  rÃ   r:   Úcollectionsr   r   r   Útypingr   r   r   r	   ÚnumpyrD   Ú	rustworkxr   Úqiskit.circuitr
   r   r   r   r   r   Úqiskit.circuit.controlflowr   Úqiskit.circuit.bitr   Úqiskit.dagcircuit.dagnoder   Úqiskit.dagcircuit.exceptionsr   Ú"qiskit.circuit.commutation_checkerr   r   r   rM   r3   r1   ú<module>r     s|  ððð ð Ð Ð Ð Ø €€€Ø <Ð <Ð <Ð <Ð <Ð <Ð <Ð <Ð <Ð <Ø -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -Ð -à Ð Ð Ð Ø Ð Ð Ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ;Ð :Ð :Ð :Ð :Ð :Ø "Ð "Ð "Ð "Ð "Ð "Ø /Ð /Ð /Ð /Ð /Ð /Ø ;Ð ;Ð ;Ð ;Ð ;Ð ;Ø AÐ AÐ AÐ AÐ AÐ Að ˆz˜.Ð*@ÑAÔA€ðY	ð Y	ð Y	ð Y	ð Y	ñ Y	ô Y	ð Y	ð Y	ð Y	r3   