§
    ¹³Ùgë0  ã                  óÂ   — d Z ddlmZ ddlZddlmZ ddlmZ ddlm	Z	m
Z
mZ ddlmZ ddlmZ d	d
lmZ  G d„ de¦  «        Z G d„ de¦  «        Z G d„ de	¦  «        ZdS )z'Multiple-Control, Multiple-Target Gate.é    )ÚannotationsN)ÚCallable)Úcircuit)ÚControlledGateÚGateÚQuantumCircuit)Ú_ctrl_state_to_int)Údeprecate_funcé   )Úget_standard_gate_name_mappingc                  ó|   ‡ — e Zd ZdZ edd¬¦  «        dˆ fd„¦   «         Zd„ Zed„ ¦   «         Zdˆ fd„	Z	ddd„Z
ˆ xZS )ÚMCMTuƒ  The multi-controlled multi-target gate, for an arbitrary singly controlled target gate.

    For example, the H gate controlled on 3 qubits and acting on 2 target qubit is represented as:

    .. code-block:: text

        â”€â”€â”€â– â”€â”€â”€â”€
           â”‚
        â”€â”€â”€â– â”€â”€â”€â”€
           â”‚
        â”€â”€â”€â– â”€â”€â”€â”€
        â”Œâ”€â”€â”´â”€â”€â”€â”�
        â”¤0     â”œ
        â”‚  2-H â”‚
        â”¤1     â”œ
        â””â”€â”€â”€â”€â”€â”€â”˜

    This default implementations requires no ancilla qubits, by broadcasting the target gate
    to the number of target qubits and using Qiskit's generic control routine to control the
    broadcasted target on the control qubits. If ancilla qubits are available, a more efficient
    variant using the so-called V-chain decomposition can be used. This is implemented in
    :class:`~qiskit.circuit.library.MCMTVChain`.
    ú1.4zUse MCMTGate instead.©ÚsinceÚadditional_msgÚgateúTGate | Callable[[QuantumCircuit, circuit.Qubit, circuit.Qubit], circuit.Instruction]Únum_ctrl_qubitsÚintÚnum_target_qubitsÚreturnÚNonec                ó  •— |dk    s|dk    rt          d¦  «        ‚t          |¦  «        r$t          j        dt          d¬¦  «         |j        }nEt          |t          ¦  «        r0t          j        dt          d¬¦  «         |                     ¦   «         }t           
                    |¦  «        | _        || _        || _        ||z   | j        z   }t          ¦   «                              |d¬¦  «         |                      ¦   «          d	S )
aK  Create a new multi-control multi-target gate.

        Args:
            gate: The gate to be applied controlled on the control qubits and applied to the target
                qubits. Can be either a Gate or a circuit method.
                If it is a callable, it will be casted to a Gate.
            num_ctrl_qubits: The number of control qubits.
            num_target_qubits: The number of target qubits.

        Raises:
            AttributeError: If the gate cannot be casted to a controlled gate.
            AttributeError: If the number of controls or targets is 0.
        r   z/Need at least one control and one target qubit.z�Passing a callable to MCMT is pending deprecation since Qiskit 1.3. Pass a gate instance or the gate name instead, e.g. pass 'h' instead of QuantumCircuit.h.r   ©ÚcategoryÚ
stacklevelz”Passing a QuantumCircuit is pending deprecation since Qiskit 1.3. Pass a gate or turn the circuit into a gate using the ``to_gate`` method, instead.Úmcmt)ÚnameN)ÚAttributeErrorÚcallableÚwarningsÚwarnÚDeprecationWarningÚ__name__Ú
isinstancer   Úto_gateÚMCMTGateÚ_identify_base_gater   r   r   Únum_ancilla_qubitsÚsuperÚ__init__Ú_build)Úselfr   r   r   Ú
num_qubitsÚ	__class__s        €úc/granary/edev/quantum/lib/python3.11/site-packages/qiskit/circuit/library/generalized_gates/mcmt.pyr,   zMCMT.__init__4   s  ø€ ð( ˜aÒÐÐ#4¸Ò#9Ð#9Ý Ð!RÑSÔSÐSå�D‰>Œ>ð 	"ÝŒMðeå+Øð	ñ ô ð ð ”=ˆDˆDÝ˜�nÑ-Ô-ð 	"ÝŒMðYå+Øð	ñ ô ð ð —<’<‘>”>ˆDå×0Ò0°Ñ6Ô6ˆŒ	Ø.ˆÔØ!2ˆÔð %Ð'8Ñ8¸4Ô;RÑRˆ
Ý‰Œ×Ò˜¨&ÐÑ1Ô1Ð1Ø�Š‰Œˆˆˆó    c                ó|   — t          | j        | j        | j        ¦  «        }|                      || j        ¦  «         d S ©N)r(   r   r   r   ÚappendÚqubits)r.   r   s     r1   r-   zMCMT._builde   s7   € Ý˜œ	 4Ô#7¸Ô9OÑPÔPˆØ�Š�D˜$œ+Ñ&Ô&Ð&Ð&Ð&r2   c                ó   — dS )zReturn the number of ancillas.r   © ©r.   s    r1   r*   zMCMT.num_ancilla_qubitsi   s	   € ð ˆqr2   é   NFc                ó¢   •— |s&|€$t          | j        | j        |z   | j        ¦  «        }n%t	          ¦   «                              ||||¬¦  «        }|S )ú2Return the controlled version of the MCMT circuit.N©Ú	annotated)r   r   r   r   r+   Úcontrol)r.   r   ÚlabelÚ
ctrl_stater>   r   r0   s         €r1   r?   zMCMT.controln   sT   ø€ àð 	\˜ZÐ/Ý˜œ	 4Ô#7¸/Ñ#IÈ4ÔKaÑbÔbˆDˆDå‘7”7—?’? ?°E¸:ÐQZ�?Ñ[Ô[ˆDØˆr2   r>   Úboolc                óB   — t          | j        | j        | j        ¦  «        S )z1Return the inverse MCMT circuit, which is itself.)r   r   r   r   ©r.   r>   s     r1   ÚinversezMCMT.inversev   s   € å�D”I˜tÔ3°TÔ5KÑLÔLÐLr2   ©r   r   r   r   r   r   r   r   ©r:   NNF©F©r>   rB   )r%   Ú
__module__Ú__qualname__Ú__doc__r
   r,   r-   Úpropertyr*   r?   rE   Ú__classcell__©r0   s   @r1   r   r      sÐ   ø€ € € € € ðð ð0 €^˜%Ð0GÐHÑHÔHð.ð .ð .ð .ð .ñ IÔHð.ð`'ð 'ð 'ð ðð ñ „Xððð ð ð ð ð ðMð Mð Mð Mð Mð Mð Mð Mð Mr2   r   c                  óp   ‡ — e Zd ZdZ edd¬¦  «        dˆ fd„¦   «         Zd„ Zed„ ¦   «         Zddd„Z	ˆ xZ
S )Ú
MCMTVChainu:  The MCMT implementation using the CCX V-chain.

    This implementation requires ancillas but is decomposed into a much shallower circuit
    than the default implementation in :class:`~qiskit.circuit.library.MCMT`.

    **Expanded Circuit:**

    .. plot::
       :alt: Diagram illustrating the previously described circuit.

       from qiskit.circuit.library import MCMTVChain, ZGate
       from qiskit.visualization.library import _generate_circuit_library_visualization
       circuit = MCMTVChain(ZGate(), 2, 2)
       _generate_circuit_library_visualization(circuit.decompose())

    **Examples:**

        >>> from qiskit.circuit.library import HGate
        >>> MCMTVChain(HGate(), 3, 2).draw()

        q_0: â”€â”€â– â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â– â”€â”€
               â”‚                        â”‚
        q_1: â”€â”€â– â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â– â”€â”€
               â”‚                        â”‚
        q_2: â”€â”€â”¼â”€â”€â”€â”€â– â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â”€â– â”€â”€â”€â”€â”¼â”€â”€
               â”‚    â”‚  â”Œâ”€â”€â”€â”�       â”‚    â”‚
        q_3: â”€â”€â”¼â”€â”€â”€â”€â”¼â”€â”€â”¤ H â”œâ”€â”€â”€â”€â”€â”€â”€â”¼â”€â”€â”€â”€â”¼â”€â”€
               â”‚    â”‚  â””â”€â”¬â”€â”˜â”Œâ”€â”€â”€â”�  â”‚    â”‚
        q_4: â”€â”€â”¼â”€â”€â”€â”€â”¼â”€â”€â”€â”€â”¼â”€â”€â”¤ H â”œâ”€â”€â”¼â”€â”€â”€â”€â”¼â”€â”€
             â”Œâ”€â”´â”€â”�  â”‚    â”‚  â””â”€â”¬â”€â”˜  â”‚  â”Œâ”€â”´â”€â”�
        q_5: â”¤ X â”œâ”€â”€â– â”€â”€â”€â”€â”¼â”€â”€â”€â”€â”¼â”€â”€â”€â”€â– â”€â”€â”¤ X â”œ
             â””â”€â”€â”€â”˜â”Œâ”€â”´â”€â”�  â”‚    â”‚  â”Œâ”€â”´â”€â”�â””â”€â”€â”€â”˜
        q_6: â”€â”€â”€â”€â”€â”¤ X â”œâ”€â”€â– â”€â”€â”€â”€â– â”€â”€â”¤ X â”œâ”€â”€â”€â”€â”€
                  â””â”€â”€â”€â”˜          â””â”€â”€â”€â”˜
    r   z7Use MCMTGate with the V-chain synthesis plugin instead.r   r   r   r   r   r   r   r   c                óN   •— t          ¦   «                              |||¦  «         d S r4   )r+   r,   )r.   r   r   r   r0   s       €r1   r,   zMCMTVChain.__init__    s(   ø€ õ 	‰Œ×Ò˜˜Ð0AÑBÔBÐBÐBÐBr2   c                óz   — ddl m}  || j        | j        | j        ¦  «        }|                      |dd¬¦  «         d S )Nr   )Úsynth_mcmt_vchainTF)ÚinplaceÚcopy)Ú!qiskit.synthesis.multi_controlledrT   r   r   r   Úcompose)r.   rT   Úsynthesizeds      r1   r-   zMCMTVChain._build¬   sN   € àGÐGÐGÐGÐGÐGà'Ð'¨¬	°4Ô3GÈÔI_Ñ`Ô`ˆØ�Š�[¨$°UˆÑ;Ô;Ð;Ð;Ð;r2   c                ó2   — t          d| j        dz
  ¦  «        S )z-Return the number of ancilla qubits required.r   r:   )Úmaxr   r9   s    r1   r*   zMCMTVChain.num_ancilla_qubits³   s   € õ �1�dÔ*¨QÑ.Ñ/Ô/Ð/r2   Fr>   rB   c                óB   — t          | j        | j        | j        ¦  «        S r4   )rQ   r   r   r   rD   s     r1   rE   zMCMTVChain.inverse¸   s   € Ý˜$œ) TÔ%9¸4Ô;QÑRÔRÐRr2   rF   rH   rI   )r%   rJ   rK   rL   r
   r,   r-   rM   r*   rE   rN   rO   s   @r1   rQ   rQ   {   sÀ   ø€ € € € € ð"ð "ðH €^ØØPðñ ô ðCð Cð Cð Cð Cñ	ô ðCð<ð <ð <ð ð0ð 0ñ „Xð0ðSð Sð Sð Sð Sð Sð Sð Sð Sr2   rQ   c                  ó\   ‡ — e Zd ZdZ	 	 ddˆ fd„Zd„ Zed„ ¦   «         Zdˆ fd„	Zddd„Z	ˆ xZ
S )r(   uA  The multi-controlled multi-target gate, for an arbitrary singly controlled target gate.

    For example, the H gate controlled on 3 qubits and acting on 2 target qubit is represented as:

    .. parsed-literal::

        â”€â”€â”€â– â”€â”€â”€â”€
           â”‚
        â”€â”€â”€â– â”€â”€â”€â”€
           â”‚
        â”€â”€â”€â– â”€â”€â”€â”€
        â”Œâ”€â”€â”´â”€â”€â”€â”�
        â”¤0     â”œ
        â”‚  2-H â”‚
        â”¤1     â”œ
        â””â”€â”€â”€â”€â”€â”€â”˜

    Depending on the number of available auxiliary qubits, this operation can be synthesized
    using different methods. For example, if :math:`n - 1` clean auxiliary qubits are available
    (where :math:`n` is the number of control qubits), a V-chain decomposition can be used whose
    depth is linear in :math:`n`. See also :func:`.synth_mcmt_chain`.
    Nr   r   r   r   r   rA   úint | str | Noner@   ú
str | Noner   r   c           	     ó8  •— |dk     rt          d¦  «        ‚|dk     rt          d¦  «        ‚|| _        |                      |¦  «        }||z   }|€|› d|j                             ¦   «         › �}t          ¦   «                              d|||j        |||¬¦  «         dS )aÇ  
        Args:
            gate: The base gate to apply on multiple target qubits, controlled by other qubits.
                This must be a single-qubit gate or a controlled single-qubit gate.
            num_ctrl_qubits: The number of control qubits.
            num_target_qubits: The number of target qubits.
            ctrl_state: The control state of the control qubits. Defaults to all closed controls.
            label: The gate label.
        r:   zNeed at least one target qubit.z Need at least one control qubit.Nú-r   )Ú	base_gater/   Úparamsr   rA   r@   )Ú
ValueErrorr   r)   r   Ú
capitalizer+   r,   rc   )	r.   r   r   r   rA   r@   rb   r/   r0   s	           €r1   r,   zMCMTGate.__init__Ô   sÇ   ø€ ð" ˜qÒ Ð ÝÐ>Ñ?Ô?Ð?à˜QÒÐÝÐ?Ñ@Ô@Ð@à!2ˆÔà×,Ò,¨TÑ2Ô2ˆ	Ø$Ð'8Ñ8ˆ
àˆ=Ø(ÐCÐC¨4¬9×+?Ò+?Ñ+AÔ+AÐCÐCˆEå‰Œ×ÒØØØ!Ø”;Ø+Ø!Øð 	ñ 	
ô 	
ð 	
ð 	
ð 	
r2   c                óV   — ddl m}  |¦   «                              | ¦  «        | _        dS )zSDefault definition relying on gate.control. Control state is handled by superclass.r   )ÚMCMTSynthesisDefaultN)Ú.qiskit.transpiler.passes.synthesis.hls_pluginsrg   ÚrunÚ
definition)r.   rg   s     r1   Ú_definezMCMTGate._defineý   s9   € ð 	XÐWÐWÐWÐWÐWà.Ð.Ñ0Ô0×4Ò4°TÑ:Ô:ˆŒˆˆr2   c           	     óô  — t          | t          ¦  «        rNt          ¦   «         }| |v r	||          } n3t          d| › dt	          t          j        ¦   «         ¦  «        › �¦  «        ‚t          | t          ¦  «        r$t          j        dt          d¬¦  «         | j
        }n8t          | t          ¦  «        r| }n t          dt          | ¦  «        › d�¦  «        ‚|j        dk    rt          d	|j        › d�¦  «        ‚|S )
zAGet the control base gate. Note this must be a single qubit gate.zUnknown gate z. Available: z¥Passing a controlled gate to MCMT is pending deprecation since Qiskit 1.3. Pass a single-qubit gate instance or the gate name instead, e.g. pass 'h' instead of 'ch'.r   r   zInvalid gate type ú.r:   z;MCMTGate requires a base gate with a single qubit, but got )r&   Ústrr   r    ÚlistÚkeysr   r"   r#   r$   rb   r   Ú	TypeErrorÚtyper/   rd   )r   Ústandard_gatesrb   s      r1   r)   zMCMTGate._identify_base_gate  s'  € õ
 �d�CÑ Ô ð 	Ý;Ñ=Ô=ˆNØ�~Ð%Ð%Ø% dÔ+��å$Ød DÐdÐdµtÕ<ZÔ<_Ñ<aÔ<aÑ7bÔ7bÐdÐdñô ð õ
 �d�NÑ+Ô+ð 	@ÝŒMðfå+Øð	ñ ô ð ð œˆIˆIÝ˜�dÑ#Ô#ð 	@ØˆIˆIåÐ>µ°d±´Ð>Ð>Ð>Ñ?Ô?Ð?àÔ 1Ò$Ð$ÝØeÈiÔNbÐeÐeÐeñô ð ð Ðr2   r:   Fc                óÜ   •— |sCt          ||¦  «        }| j        |z  |z  }t          | j        | j        |z   | j        |¬¦  «        }n%t          ¦   «                              ||||¬¦  «        }|S )r<   )rA   r=   )r	   rA   r(   rb   r   r   r+   r?   )r.   r   r@   rA   r>   Únew_ctrl_stater   r0   s          €r1   r?   zMCMTGate.control'  s€   ø€ àð 	\Ý+¨J¸ÑHÔHˆJØ"œo°Ñ@ÀJÑNˆNåØ”ØÔ$ Ñ6ØÔ&Ø)ð	ñ ô ˆDˆDõ ‘7”7—?’? ?°E¸:ÐQZ�?Ñ[Ô[ˆDàˆr2   r>   rB   c                ór   — t          | j                             ¦   «         | j        | j        | j        ¦  «        S )z Return the inverse MCMT circuit.)r(   rb   rE   r   r   rA   rD   s     r1   rE   zMCMTGate.inverse8  s5   € åØŒN×"Ò"Ñ$Ô$ dÔ&:¸DÔ<RÐTXÔTcñ
ô 
ð 	
r2   )NN)r   r   r   r   r   r   rA   r^   r@   r_   r   r   rG   rH   rI   )r%   rJ   rK   rL   r,   rk   Ústaticmethodr)   r?   rE   rN   rO   s   @r1   r(   r(   ¼   s·   ø€ € € € € ðð ð8 (,Ø ð'
ð '
ð '
ð '
ð '
ð '
ð '
ðR;ð ;ð ;ð ð ð  ñ „\ð ðDð ð ð ð ð ð"
ð 
ð 
ð 
ð 
ð 
ð 
ð 
ð 
r2   r(   )rL   Ú
__future__r   r"   Úcollections.abcr   Úqiskitr   Úqiskit.circuitr   r   r   Úqiskit.circuit._utilsr	   Úqiskit.utils.deprecationr
   rs   r   r   rQ   r(   r8   r2   r1   ú<module>r~      sL  ðð .Ð -à "Ð "Ð "Ð "Ð "Ð "à €€€Ø $Ð $Ð $Ð $Ð $Ð $à Ð Ð Ð Ð Ð Ø ?Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ð ?Ø 4Ð 4Ð 4Ð 4Ð 4Ð 4Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ø ;Ð ;Ð ;Ð ;Ð ;Ð ;ð]Mð ]Mð ]Mð ]Mð ]Mˆ>ñ ]Mô ]Mð ]Mð@>Sð >Sð >Sð >Sð >S�ñ >Sô >Sð >SðB@
ð @
ð @
ð @
ð @
ˆ~ñ @
ô @
ð @
ð @
ð @
r2   