
    z	i                        S r SSKJr  SSKJr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KJr  SS	KJrJr   " S
 S\5      rg)zG
A generic InverseCancellation pass for any set of gate-inverse pairs.
    )annotations)ListTupleUnion)Gate)
DAGCircuit)TransformationPass)TranspilerError)control_flow)inverse_cancellation'run_inverse_cancellation_standard_gatesc                  f   ^  \ rS rSrSr  S   SU 4S jjjr\R                  SS j5       rSr	U =r
$ )	InverseCancellation    zUCancel specific Gates which are inverses of each other when they occur back-to-
back.c                  > / U l         / U l        [        5       U l        [        5       U l        X l        Uc	  SU l        GOSU l        U H  n[        U[        5      (       a.  X3R                  5       :w  a  [        SUR                   S35      eMF  [        U[        5      (       af  [        U5      S:w  a  [        SU S35      eUS	   US
   R                  5       :w  a,  [        SUS	   R                   SUS
   R                   S35      eM  [        S[        U5       S35      e   U H  n[        U[        5      (       aB  U R                   R                  U5        U R                  R!                  UR                  5        MZ  U R                  R                  U5        U R                  R#                  S U 5       5        M     [$        TU ]M  5         g)a  Initialize InverseCancellation pass.

Args:
    gates_to_cancel: List describing the gates to cancel. Each element of the
        list is either a single gate or a pair of gates. If a single gate, then
        it should be self-inverse. If a pair of gates, then the gates in the
        pair should be inverses of each other. If ``None`` a default list of
        self-inverse gates and a default list of inverse gate pairs will be used.
        The current default list of self-inverse gates is:

          * :class:`.CXGate`
          * :class:`.ECRGate`
          * :class:`.CYGate`
          * :class:`.CZGate`
          * :class:`.XGate`
          * :class:`.YGate`
          * :class:`.ZGate`
          * :class:`.HGate`
          * :class:`.SwapGate`
          * :class:`.CHGate`
          * :class:`.CCXGate`
          * :class:`.CCZGate`
          * :class:`.RCCXGate`
          * :class:`.CSwapGate`
          * :class:`.C3XGate`

        and the default list of inverse gate pairs is:

          * :class:`.TGate` and :class:`.TdgGate`
          * :class:`.SGate` and :class:`.SdgGate`
          * :class:`.SXGate` and :class:`.SXdgGate`
          * :class:`.CSGate` and :class:`.CSdgGate`

    run_default: If set to true and ``gates_to_cancel`` is set to a list then in
        addition to the gates listed in ``gates_to_cancel`` the default list of gate
        inverses (the same as when ``gates_to_cancel`` is set to ``None``) will be
        run. The order of evaluation is significant in how sequences of gates are
        cancelled and the default gates will be evaluated after the provided gates
        in ``gates_to_cancel``. If ``gates_to_cancel`` is ``None`` this option has
        no impact.

Raises:
    TranspilerError: Input is not a self-inverse gate or a pair of inverse gates.
NTFzGate z is not self-inverse   zToo many or too few inputs: z. Only two are allowed.r      z and z are not inverse.z2InverseCancellation pass does not take input type z. Input must be a Gate.c              3  8   #    U  H  oR                   v   M     g 7f)N)name).0xs     t/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/transpiler/passes/optimization/inverse_cancellation.py	<genexpr>/InverseCancellation.__init__.<locals>.<genexpr>w   s     8OAs   )self_inverse_gatesinverse_gate_pairssetself_inverse_gate_namesinverse_gate_pairs_names_also_default_use_standard_gates
isinstancer   inverser
   r   tuplelentypeappendaddupdatesuper__init__)selfgates_to_cancelrun_defaultgates	__class__s       r   r+   InverseCancellation.__init__$   s   b #%"$'*u$(+%("'+D$',D$(eT**/-ejj\AU.VWW 0u--5zQ-:5'AXY  Qx58#3#3#55-#E!HMM?%aFWX  6
 *LTRW[M Z# #  )& )eT**++22590044UZZ@++225911888O8OO ) 	    c                    U R                   (       a  [        U5        U$ [        UU R                  U R                  U R
                  U R                  U R                  5        U$ )zRun the InverseCancellation pass on `dag`.

Args:
    dag: the directed acyclic graph to run on.

Returns:
    DAGCircuit: Transformed DAG.
)r!   r   r   r   r   r   r   r    )r,   dags     r   runInverseCancellation.runz   s]     ##3C8 
 !''''--,,"" 
r2   )r    r!   r   r   r   r   )NF)r-   z+List[Union[Gate, Tuple[Gate, Gate]]] | Noner.   bool)r4   r   )__name__
__module____qualname____firstlineno____doc__r+   r   trivial_recurser5   __static_attributes____classcell__)r0   s   @r   r   r       sM    
 HL!TDT T Tl !! "r2   r   N)r<   
__future__r   typingr   r   r   qiskit.circuitr   qiskit.dagcircuitr   qiskit.transpiler.basepassesr	   qiskit.transpiler.exceptionsr
   qiskit.transpiler.passes.utilsr   'qiskit._accelerate.inverse_cancellationr   r   r    r2   r   <module>rI      s8    # % %  ( ; 8 7o, or2   