
    z	iQ                        S r SSKJr  SSKrSSKJr  SSKrSSKJr  SSK	r	SSK
Jr  SSKJr  SSKJr  SS	KJrJr  S
r " S S\5      rg)a  
A generic quantum instruction.

Instructions can be implementable on hardware (u, cx, etc.) or in simulation
(snapshot, noise, etc.).

Instructions can be unitary (a.k.a Gate) or non-unitary.

Instructions are identified by the following:

    name: A string to identify the type of instruction.
          Used to request a specific instruction on the backend, or in visualizing circuits.

    num_qubits, num_clbits: dimensions of the instruction.

    params: List of parameters to specialize a specific instruction instance.

Instructions do not have any context about where they are in a circuit (which qubits/clbits).
The circuit itself keeps this context.
    )annotationsN)zip_longest)Type)CircuitError)ParameterExpression)	Operation)AnnotatedOperationInverseModifier绽|=c                  >   \ rS rSrSrSrSrS'S jr\S(S j5       r	\S)S j5       r
S rS	 rS*S
 jrS+S jrS r\S 5       r\R"                  S 5       rS rS r\S 5       r\R"                  S 5       r\S 5       r\R"                  S 5       rS r\S*S j5       r\R"                  S,S j5       rS rS-S.S jjrS'S jrS'S jrS rS rS r\S 5       r\R"                  S  5       r\S! 5       r \ R"                  S" 5       r \S# 5       r!\!R"                  S$ 5       r!S% r"S&r#g)/Instruction4   zGeneric quantum instruction.FNc                j   [        U[        5      (       a  [        U[        5      (       d  [        S5      eUS:  d  US:  a  [        SU SU S35      eXl        X l        X0l        / U l        [        U S5      (       d)  Ub   [        U[        5      (       d  [        S5      eXPl
        SU l        X@l        g)	a  
.. deprecated:: 1.3
   The parameters ``duration`` and ``unit`` are deprecated since
   Qiskit 1.3, and they will be removed in 2.0 or later.
   An instruction's duration is defined in a backend's Target object.

Args:
    name (str): instruction name
    num_qubits (int): instruction's qubit width
    num_clbits (int): instruction's clbit width
    params (list[int|float|complex|str|ndarray|list|ParameterExpression]):
        list of parameters
    label (str or None): An optional label for identifying the instruction.

Raises:
    CircuitError: when the register is not in the correct format.
    TypeError: when the optional label is provided, but it is not a string.
z*num_qubits and num_clbits must be integer.r   zbad instruction dimensions: z	 qubits, z clbits._labelNlabel expects a string or None)
isinstanceintr   _name_num_qubits_num_clbits_paramshasattrstr	TypeErrorr   _definitionparams)selfname
num_qubits
num_clbitsr   labels         T/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/circuit/instruction.py__init__Instruction.__init__<   s    & *c***Z2M2MKLL>Z!^.zl)J<xX  
%%
 tX&& E3)?)? @AAK      c                    [        U 5      $ )a  Get the base class of this instruction.  This is guaranteed to be in the inheritance tree
of ``self``.

The "base class" of an instruction is the lowest class in its inheritance tree that the
object should be considered entirely compatible with for _all_ circuit applications.  This
typically means that the subclass is defined purely to offer some sort of programmer
convenience over the base class, and the base class is the "true" class for a behavioral
perspective.  In particular, you should *not* override :attr:`base_class` if you are
defining a custom version of an instruction that will be implemented differently by
hardware, such as an alternative measurement strategy, or a version of a parametrized gate
with a particular set of parameters for the purposes of distinguishing it in a
:class:`.Target` from the full parametrized gate.

This is often exactly equivalent to ``type(obj)``, except in the case of singleton instances
of standard-library instructions.  These singleton instances are special subclasses of their
base class, and this property will return that base.  For example::

    >>> isinstance(XGate(), XGate)
    True
    >>> type(XGate()) is XGate
    False
    >>> XGate().base_class is XGate
    True

In general, you should not rely on the precise class of an instruction; within a given
circuit, it is expected that :attr:`Instruction.name` should be a more suitable
discriminator in most situations.
)typer   s    r"   
base_classInstruction.base_classh   s    < Dzr%   c                    g)zIs this instance is a mutable unique instance or not.

If this attribute is ``False`` the gate instance is a shared singleton
and is not mutable.
T r(   s    r"   mutableInstruction.mutable   s     r%   c                "    U R                  5       $ )a  Return a mutable copy of this gate.

This method will return a new mutable copy of this gate instance.
If a singleton instance is being used this will be a new unique
instance that can be mutated. If the instance is already mutable it
will be a deepcopy of that instance.
)copyr(   s    r"   
to_mutableInstruction.to_mutable   s     yy{r%   c                   [        U[        5      (       a  U R                  UR                  Ldh  U R                  UR                  :w  dN  U R                  UR                  :w  d4  U R
                  UR
                  :w  d  U R                  UR                  :w  a  g[        U R                  UR                  5       H  u  p#[        U[        R                  5      (       a  [        R                  " X#5      (       a  MA  OX#:X  a  MI   [        R                  " U5      n[        R                  " U5      n[        R                  " U5      [        R                  " U5      :X  a!  [        R                  " X#[        SS9(       a  M   [        R$                  " ['        U5      ['        U5      [        SS9(       a  M     g   g! [         ["        4 a     NMf = f! ["         a       gf = f)zTwo instructions are the same if they have the same name,
same dimensions, and same params.

Args:
    other (instruction): other instruction

Returns:
    bool: are self and other equal.
Fr   )atolrtolT)r   r   r)   r   r   r    
definitionr   r   numpyndarrayarray_equalasarrayshapeallclose_CUTOFF_PRECISION
ValueErrorr   isclosefloat)r   other
self_paramother_paramself_asarrayother_asarrays         r"   __eq__Instruction.__eq__   s{    5+..e&6&66yyEJJ&%"2"22%"2"22%"2"22'24;;'M#J*emm44$$Z== > ,$}}Z8 %k :;;|,M0JJu~~2C!P ==*%u['9@QXY  5 (N8  	*   s%   A9F8>2G8G
G
GGc           	     p    SU R                    SU R                   SU R                   SU R                   S3	$ )zGenerates a representation of the Instruction object instance
Returns:
    str: A representation of the Instruction instance with the name,
         number of qubits, classical bits and params( if any )
zInstruction(name='z', num_qubits=z, num_clbits=z	, params=)r   r   r    r   r(   s    r"   __repr__Instruction.__repr__   sA     !>$//9J K//*)DKK=C	
r%   c                &   U R                   UR                   :w  d`  U R                  UR                  :w  dF  U R                  UR                  :w  d,  [        U R                  5      [        UR                  5      :w  a  g[        U R                  UR                  5       H  u  p#[        U[        5      (       d  [        U[        5      (       a  M1  [        U[        R                  5      (       ao  [        U[        R                  5      (       aP  [        R                  " U5      [        R                  " U5      :X  a   [        R                  " X#[        S9(       a  M    g [        R                  " X#[        S9(       a  M     g   g! [         a       gf = f)af  
Soft comparison between gates. Their names, number of qubits, and classical
bit numbers must match. The number of parameters must match. Each parameter
is compared. If one is a ParameterExpression then it is not taken into
account.

Args:
    other (instruction): other instruction.

Returns:
    bool: are self and other equal up to parameter expressions.
F)r4   T)r   r   r    lenr   r   r   r   r7   r8   r;   r<   r=   r?   r   )r   rA   rB   rC   s       r"   soft_compareInstruction.soft_compare   s/    II#%"2"22%"2"224;;3u||#44'24;;'M#J*&9::j0? ? *emm44KQVQ^Q^9_9_;;z*ekk+.FF5>>2CL  }}ZCTU  V
 # (N&  ! s   F
FFc                    g)ag  Populate the cached :attr:`_definition` field of this :class:`Instruction`.

Subclasses should implement this method to provide lazy construction of their public
:attr:`definition` attribute.  A subclass can use its :attr:`params` at the time of the
call.  The method should populate :attr:`_definition` with a :class:`.QuantumCircuit` and
not return a value.Nr,   r(   s    r"   _defineInstruction._define  s     	r%   c                    U R                   $ )zPThe parameters of this :class:`Instruction`.  Ideally these will be gate angles.)r   r(   s    r"   r   Instruction.params  s     ||r%   c                    / U l         U H_  n[        U[        5      (       a  U R                   R                  U5        M5  U R                   R                  U R	                  U5      5        Ma     g N)r   r   r   appendvalidate_parameter)r   
parameterssingle_params      r"   r   rU     sP    &L,(;<<##L1##D$;$;L$IJ	 'r%   c                    U$ )z9Instruction parameter has no validation or normalization.r,   )r   	parameters     r"   rY   Instruction.validate_parameter  s    r%   c                :    [        S U R                   5       5      $ )zrReturn whether the :class:`Instruction` contains :ref:`compile-time parameters
<circuit-compile-time-parameters>`.c              3  h   #    U  H(  n[        U[        5      =(       a    UR                  v   M*     g 7frW   )r   r   rZ   ).0params     r"   	<genexpr>/Instruction.is_parameterized.<locals>.<genexpr>   s*      
UaEJu12Gu7G7GGUas   02)anyr   r(   s    r"   is_parameterizedInstruction.is_parameterized  s$      
UYUaUa
 
 	
r%   c                T    U R                   c  U R                  5         U R                   $ )z0Return definition in terms of other basic gates.)r   rR   r(   s    r"   r6   Instruction.definition$  s%     #LLNr%   c                    Xl         g)zSet gate representationN)r   )r   arrays     r"   r6   ri   +  s
     !r%   c                0    SSK Jn  UR                  U 5      $ )zMGet the decompositions of the instruction from the SessionEquivalenceLibrary.r   SessionEquivalenceLibrary)"qiskit.circuit.equivalence_libraryrn   	get_entry)r   sels     r"   decompositionsInstruction.decompositions0  s     	X}}T""r%   c                2    SSK Jn  UR                  X5        g)zMSet the decompositions of the instruction from the SessionEquivalenceLibrary.r   rm   N)ro   rn   	set_entry)r   rr   rq   s      r"   rr   rs   8  s     	Xd+r%   c                2    SSK Jn  UR                  X5        g)zHAdd a decomposition of the instruction to the SessionEquivalenceLibrary.r   rm   N)ro   rn   add_equivalence)r   decompositionrq   s      r"   add_decompositionInstruction.add_decomposition@  s     	XD0r%   c                    U R                   $ )zReturn instruction label)r   r(   s    r"   r!   Instruction.labelG  s     {{r%   c                f    [        U[        [        S5      45      (       a  Xl        g[	        S5      e)zSet instruction label to name

Args:
    name (str or None): label to assign instruction

Raises:
    TypeError: name is not string or None.
Nr   )r   r   r'   r   r   r   r   s     r"   r!   r|   L  s+     dS$t*-..K<==r%   c                   U R                   (       a  U R                  (       d  U R                  5       $ U R                  U R                  S-   S9nU R                   R	                  5       n[        U R                   5       HB  nUR                  UR                  R                  5       UR                  UR                  5        MD     X!l        U$ )a  For a composite instruction, reverse the order of sub-instructions.

This is done by recursively reversing all sub-instructions.
It does not invert any gate.

Returns:
    qiskit.circuit.Instruction: a new instruction with
        sub-instructions reversed.
_reverse)r   )r   r-   r0   r   copy_empty_likereversedrX   	operationreverse_opsqubitsclbitsr6   )r   reverse_instreversed_definitioninsts       r"   r   Instruction.reverse_ops[  s      t||99;yydii*&<y="..>>@T--.D&&t~~'A'A'CT[[RVR]R]^ /"5r%   c                   U(       a  [        U [        5       5      $ U R                  c  [        SU R                   S35      eSSKJn  U R                  R                  S5      (       a  U R                  SS nOU R                  S-   nU R                  (       a9  [        UU R                  U R                  U R                  R                  5       S9nO)U" X0R                  U R                  R                  5       S	9nU R                  R                  5       nUR                  * Ul        [!        U R                  5       HB  nUR#                  UR$                  R'                  5       UR(                  UR*                  5        MD     XTl        U$ )
a  Invert this instruction.

If `annotated` is `False`, the inverse instruction is implemented as
a fresh instruction with the recursively inverted definition.

If `annotated` is `True`, the inverse instruction is implemented as
:class:`.AnnotatedOperation`, and corresponds to the given instruction
annotated with the "inverse modifier".

Special instructions inheriting from Instruction can
implement their own inverse (e.g. T and Tdg, Barrier, etc.)
In particular, they can choose how to handle the argument ``annotated``
which may include ignoring it and always returning a concrete gate class
if the inverse is defined as a standard gate.

Args:
    annotated: if set to `True` the output inverse gate will be returned
        as :class:`.AnnotatedOperation`.

Returns:
    The inverse operation.

Raises:
    CircuitError: if the instruction is not composite
        and an inverse has not been implemented for it.
Nzinverse() not implemented for .r   )Gate_dgrJ   )r   r   r   )r	   r
   r6   r   r   qiskit.circuitr   endswithr    r   r   r   r0   r   r   global_phaser   _appendr   inverser   r   )r   	annotatedr   r   inverse_gateinverse_definitionr   s          r"   r   Instruction.inverseu  s/   6 %dO,=>>??"!?		{!LMM'99e$$99Sb>D99u$D??&????{{'')	L  ToodkkN^N^N`aL!--==?+=+J+J*J'T--.D&&t~~'='='?dkkZ /"4r%   c                @    U R                  5       nU(       a  Xl        U$ )z
Copy of the instruction.

Args:
    name (str): name to be given to the copied circuit, if ``None`` then the name stays the same.

Returns:
    qiskit.circuit.Instruction: a copy of the current instruction, with the name updated if it
    was provided
)__deepcopy__r   )r   r   cpys      r"   r0   Instruction.copy  s     !H
r%   c                    [         R                   " U 5      n[         R                  " U R                  U5      Ul        U R                  (       a&  [         R                  " U R                  U5      Ul        U$ rW   )r0   deepcopyr   r   )r   memor   s      r"   r   Instruction.__deepcopy__  sK    iiommDLL$7"mmD,<,<dCCO
r%   c              #    #    [        U5      U R                  :w  a%  [        S[        U5       SU R                   S35      e[        U5      U R                  :w  a%  [        S[        U5       SU R                   S35      eU VVs/ s H  o3  H  oDPM     M     nnnU VVs/ s H  o3  H  ofPM     M     nnnXW4v   gs  snnf s  snnf 7f)aP  
Validation of the arguments.

Args:
    qargs (List): List of quantum bit arguments.
    cargs (List): List of classical bit arguments.

Yields:
    Tuple(List, List): A tuple with single arguments.

Raises:
    CircuitError: If the input is not valid. For example, the number of
        arguments does not match the gate expectation.
zThe amount of qubit arguments z- does not match the instruction expectation (z).zThe amount of clbit arguments N)rN   r   r   r    )r   qargscargssublistqarg
flat_qargscarg
flat_cargss           r"   broadcast_argumentsInstruction.broadcast_arguments  s      u:(0U =1150AE  u:(0U =1150AE  +0D%wGDdGd%
D*/D%wGDdGd%
D$$ EDs   BC	B=C	 C4C	c                t    [        U R                   SU 3U R                  U R                  U R                  S9$ )N*rJ   )r   r   r   r    r   )r   exponents     r"   _return_repeatInstruction._return_repeat  s6    II;az*;;	
 	
r%   c                   [        U5      U:w  d  US:  a  [        S5      e[        U5      nU R                  U5      nUR                  c  SSKJnJn  U" U R                  U R                  5      n[        UR                  5      n[        UR                  5      nU R                  5       nS/U-   H  n	UR                  U" XU5      5        M     XRl        U$ )zCreates an instruction with ``self`` repeated :math`n` times.

Args:
    n (int): Number of times to repeat the instruction

Returns:
    qiskit.circuit.Instruction: Containing the definition.

Raises:
    CircuitError: If n < 1.
   z9Repeat can only be called with strictly positive integer.Nr   )QuantumCircuitCircuitInstruction)r   r   r   r6   r   r   r   r   r    tupler   r   r0   r   )
r   ninstructionr   r   qcr   r   base_s
             r"   repeatInstruction.repeat  s     q6Q;!a%Z[[F))!,!!)IAB"))$E"))$E99;DVaZ

-d5AB   &("r%   c                    U R                   $ )zReturn the name.r   r(   s    r"   r   Instruction.name  s     zzr%   c                    Xl         g)zSet the name.Nr   r~   s     r"   r   r     s	     
r%   c                    U R                   $ )zReturn the number of qubits.r   r(   s    r"   r   Instruction.num_qubits       r%   c                    Xl         g)zSet num_qubits.Nr   )r   r   s     r"   r   r     
     &r%   c                    U R                   $ )zReturn the number of clbits.r   r(   s    r"   r    Instruction.num_clbits!  r   r%   c                    Xl         g)zSet num_clbits.Nr   )r   r    s     r"   r    r   &  r   r%   c                    [        U R                  UR                  5       H#  u  p# [        R                  " X#SSS9(       d    gM%     g! [         a    X#:w  a     g M=  f = f)Nr   r   )rel_tolabs_tolFT)zipr   mathr?   r   )r   rA   xys       r"   _compare_parametersInstruction._compare_parameters+  s^    U\\2DA!||A!UC  D 3   !6  !s   A		AA)r   r   r   r   r   r   r   rW   )returnzType[Instruction])r   bool)r   r   )rA   z'Instruction'r   r   )r   r   )F)r   r   )$__name__
__module____qualname____firstlineno____doc__
_directive_standard_gater#   propertyr)   r-   r1   rF   rK   rO   rR   r   setterrY   rf   r6   rr   ry   r!   r   r   r0   r   r   r   r   r   r   r    r   __static_attributes__r,   r%   r"   r   r   4   s   & JN*X  >  0d	
(T   ]]K K
     ! ! # # , ,1   \\> >47r"%>
@   
[[      & &     & &r%   r   )r   
__future__r   r0   	itertoolsr   r   typingr   r7   qiskit.circuit.exceptionsr   "qiskit.circuit.parameterexpressionr   qiskit.circuit.operationr   "qiskit.circuit.annotated_operationr	   r
   r=   r   r,   r%   r"   <module>r      s>   * #  !    2 B . R ) r%   