
    z	izy                   ~   S r SSKJr  SSKrSSKrSSKrSSKJ	r	  SSK
Jr  SSKJrJrJrJrJrJrJrJrJrJrJrJrJrJrJr  SSKJrJrJrJ r J!r!J"r"  SSK#J$r$  SS	K%J&r&J'r'J(r(  SS
K)J*r*J+r+J,r,J-r-J.r.J/r/  SSK0J1r1J2r2J3r3  SSK4J5r5  SSK6J7r7J8r8J9r9  SSK:J;r;J<r<  SSK=J>r>J?r?J@r@JArAJBrBJCrCJDrDJErEJFrFJGrGJHrHJIrI  SSKJJKrKJLrL  SSK%JMrMJNrNJOrOJPrPJQrQJRrRJSrS  SSKTJUrU  SSKVJWrW  SSKXJYrY  SSKZJ[r[  SSK\J]r]  SSK^J_r_J`r`  SSKaJbrb   " S S\b5      rc " S S\b5      rd " S S\b5      re " S  S!\b5      rf " S" S#\b5      rg " S$ S%\b5      rh " S& S'\b5      ri " S( S)\b5      rj " S* S+\b5      rk " S, S-\b5      rl " S. S/\b5      rm " S0 S1\b5      rn " S2 S3\b5      ro " S4 S5\b5      rp " S6 S7\b5      rq " S8 S9\b5      rr " S: S;\b5      rs " S< S=\b5      rt " S> S?\b5      ru " S@ SA\b5      rv " SB SC\b5      rw " SD SE\b5      rx " SF SG\b5      ry " SH SI\b5      rz " SJ SK\b5      r{ " SL SM\b5      r| " SN SO\b5      r} " SP SQ\b5      r~ " SR SS\b5      r " ST SU\b5      r " SV SW\b5      r " SX SY\b5      r " SZ S[\b5      r " S\ S]\b5      r " S^ S_\b5      r " S` Sa\b5      r " Sb Sc\b5      r " Sd Se\b5      r " Sf Sg\b5      r " Sh Si\b5      r " Sj Sk\b5      r " Sl Sm\b5      r " Sn So\b5      r " Sp Sq\b5      r " Sr Ss\b5      r " St Su\b5      r " Sv Sw\b5      r " Sx Sy\b5      r " Sz S{\b5      r " S| S}\b5      r " S~ S\b5      r " S S\b5      r " S S\b5      rg)a0  

High Level Synthesis Plugins
-----------------------------

Clifford Synthesis
''''''''''''''''''

.. list-table:: Plugins for :class:`qiskit.quantum_info.Clifford` (key = ``"clifford"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Targeted connectivity
      - Description
    * - ``"ag"``
      - :class:`~.AGSynthesisClifford`
      - all-to-all
      - greedily optimizes CX-count
    * - ``"bm"``
      - :class:`~.BMSynthesisClifford`
      - all-to-all
      - optimal count for `n=2,3`; used in ``"default"`` for `n=2,3`
    * - ``"greedy"``
      - :class:`~.GreedySynthesisClifford`
      - all-to-all
      - greedily optimizes CX-count; used in ``"default"`` for `n>=4`
    * - ``"layers"``
      - :class:`~.LayerSynthesisClifford`
      - all-to-all
      -
    * - ``"lnn"``
      - :class:`~.LayerLnnSynthesisClifford`
      - linear
      - many CX-gates but guarantees CX-depth of at most `7*n+2`
    * - ``"default"``
      - :class:`~.DefaultSynthesisClifford`
      - all-to-all
      - usually best for optimizing CX-count (and optimal CX-count for `n=2,3`)

.. autosummary::
   :toctree: ../stubs/

   AGSynthesisClifford
   BMSynthesisClifford
   GreedySynthesisClifford
   LayerSynthesisClifford
   LayerLnnSynthesisClifford
   DefaultSynthesisClifford


Linear Function Synthesis
'''''''''''''''''''''''''

.. list-table:: Plugins for :class:`.LinearFunction` (key = ``"linear"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Targeted connectivity
      - Description
    * - ``"kms"``
      - :class:`~.KMSSynthesisLinearFunction`
      - linear
      - many CX-gates but guarantees CX-depth of at most `5*n`
    * - ``"pmh"``
      - :class:`~.PMHSynthesisLinearFunction`
      - all-to-all
      - greedily optimizes CX-count; used in ``"default"``
    * - ``"default"``
      - :class:`~.DefaultSynthesisLinearFunction`
      - all-to-all
      - best for optimizing CX-count

.. autosummary::
   :toctree: ../stubs/

   KMSSynthesisLinearFunction
   PMHSynthesisLinearFunction
   DefaultSynthesisLinearFunction


Permutation Synthesis
'''''''''''''''''''''

.. list-table:: Plugins for :class:`.PermutationGate` (key = ``"permutation"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Targeted connectivity
      - Description
    * - ``"basic"``
      - :class:`~.BasicSynthesisPermutation`
      - all-to-all
      - optimal SWAP-count; used in ``"default"``
    * - ``"acg"``
      - :class:`~.ACGSynthesisPermutation`
      - all-to-all
      - guarantees SWAP-depth of at most `2`
    * - ``"kms"``
      - :class:`~.KMSSynthesisPermutation`
      - linear
      - many SWAP-gates, but guarantees SWAP-depth of at most `n`
    * - ``"token_swapper"``
      - :class:`~.TokenSwapperSynthesisPermutation`
      - any
      - greedily optimizes SWAP-count for arbitrary connectivity
    * - ``"default"``
      - :class:`~.BasicSynthesisPermutation`
      - all-to-all
      - best for optimizing SWAP-count

.. autosummary::
   :toctree: ../stubs/

   BasicSynthesisPermutation
   ACGSynthesisPermutation
   KMSSynthesisPermutation
   TokenSwapperSynthesisPermutation


QFT Synthesis
'''''''''''''

.. list-table:: Plugins for :class:`.QFTGate` (key = ``"qft"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Targeted connectivity
    * - ``"full"``
      - :class:`~.QFTSynthesisFull`
      - all-to-all
    * - ``"line"``
      - :class:`~.QFTSynthesisLine`
      - linear
    * - ``"default"``
      - :class:`~.QFTSynthesisFull`
      - all-to-all

.. autosummary::
   :toctree: ../stubs/

   QFTSynthesisFull
   QFTSynthesisLine


MCX Synthesis
'''''''''''''

The following table lists synthesis plugins available for an :class:`.MCXGate` gate
with `k` control qubits. If the available number of clean/dirty auxiliary qubits is
not sufficient, the corresponding synthesis method will return `None`.

.. list-table:: Plugins for :class:`.MCXGate` (key = ``"mcx"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Number of clean ancillas
      - Number of dirty ancillas
      - Description
    * - ``"gray_code"``
      - :class:`~.MCXSynthesisGrayCode`
      - `0`
      - `0`
      - exponentially many CX gates; use only for small values of `k`
    * - ``"noaux_v24"``
      - :class:`~.MCXSynthesisNoAuxV24`
      - `0`
      - `0`
      - quadratic number of CX gates
    * - ``"noaux_hp24"``
      - :class:`~.MCXSynthesisNoAuxHP24`
      - `0`
      - `0`
      - linear number of CX gates; use instead of ``"noaux_v24"`` or ``"gray_code"`` for `k>5`
    * - ``"n_clean_m15"``
      - :class:`~.MCXSynthesisNCleanM15`
      - `k-2`
      - `0`
      - at most `6*k-6` CX gates
    * - ``"n_dirty_i15"``
      - :class:`~.MCXSynthesisNDirtyI15`
      - `0`
      - `k-2`
      - at most `8*k-6` CX gates
    * - ``"2_clean_kg24"``
      - :class:`~.MCXSynthesis2CleanKG24`
      - `2`
      - `0`
      - at most `6*k-6` CX gates
    * - ``"2_dirty_kg24"``
      - :class:`~.MCXSynthesis2DirtyKG24`
      - `0`
      - `2`
      - at most `12*k-18` CX gates
    * - ``"1_clean_kg24"``
      - :class:`~.MCXSynthesis1CleanKG24`
      - `1`
      - `0`
      - at most `6*k-6` CX gates
    * - ``"1_dirty_kg24"``
      - :class:`~.MCXSynthesis1DirtyKG24`
      - `0`
      - `1`
      - at most `12*k-18` CX gates
    * - ``"1_clean_b95"``
      - :class:`~.MCXSynthesis1CleanB95`
      - `1`
      - `0`
      - at most `16*k-8` CX gates
    * - ``"default"``
      - :class:`~.MCXSynthesisDefault`
      - any
      - any
      - chooses the best algorithm based on the ancillas available

.. autosummary::
   :toctree: ../stubs/

   MCXSynthesisGrayCode
   MCXSynthesisNoAuxV24
   MCXSynthesisNoAuxHP24
   MCXSynthesisNCleanM15
   MCXSynthesisNDirtyI15
   MCXSynthesis2CleanKG24
   MCXSynthesis2DirtyKG24
   MCXSynthesis1CleanKG24
   MCXSynthesis1DirtyKG24
   MCXSynthesis1CleanB95
   MCXSynthesisDefault


MCMT Synthesis
''''''''''''''

.. list-table:: Plugins for :class:`.MCMTGate` (key = ``"mcmt"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Number of clean ancillas
      - Number of dirty ancillas
      - Description
    * - ``"vchain"``
      - :class:`.MCMTSynthesisVChain`
      - `k-1`
      - `0`
      - uses a linear number of Toffoli gates
    * - ``"noaux"``
      - :class:`~.MCMTSynthesisNoAux`
      - `0`
      - `0`
      - uses Qiskit's standard control mechanism
    * - ``"xgate"``
      - :class:`.MCMTSynthesisXGate`
      - `0`
      - `0`
      - uses a linear number of Toffoli gates
    * - ``"default"``
      - :class:`~.MCMTSynthesisDefault`
      - any
      - any
      - chooses the best algorithm based on the ancillas available

.. autosummary::
   :toctree: ../stubs/

   MCMTSynthesisVChain
   MCMTSynthesisNoAux
   MCMTSynthesisXGate
   MCMTSynthesisDefault

   
Integer comparators
'''''''''''''''''''

.. list-table:: Plugins for :class:`.IntegerComparatorGate` (key = ``"IntComp"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Description
      - Auxiliary qubits
    * - ``"twos"``
      - :class:`~.IntComparatorSynthesis2s`
      - use addition with two's complement 
      - ``n - 1`` clean 
    * - ``"noaux"``
      - :class:`~.IntComparatorSynthesisNoAux`
      - flip the target controlled on all :math:`O(2^l)` allowed integer values
      - none
    * - ``"default"``
      - :class:`~.IntComparatorSynthesisDefault`
      - use the best algorithm depending on the available auxiliary qubits
      - any

.. autosummary::
   :toctree: ../stubs/

   IntComparatorSynthesis2s
   IntComparatorSynthesisNoAux
   IntComparatorSynthesisDefault

   
Sums
''''

.. list-table:: Plugins for :class:`.WeightedSumGate` (key = ``"WeightedSum"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Description
      - Auxiliary qubits
    * - ``"default"``
      - :class:`.WeightedSumSynthesisDefault`
      - use a V-chain based synthesis
      - given ``s`` sum qubits, used ``s - 1 + int(s > 2)`` clean auxiliary qubits

.. autosummary::
   :toctree: ../stubs/

   WeightedSumSynthesisDefault


Pauli Evolution Synthesis
'''''''''''''''''''''''''

.. list-table:: Plugins for :class:`.PauliEvolutionGate` (key = ``"PauliEvolution"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Description
      - Targeted connectivity
    * - ``"rustiq"``
      - :class:`~.PauliEvolutionSynthesisRustiq`
      - use the synthesis method from `Rustiq circuit synthesis library 
        <https://github.com/smartiel/rustiq-core>`_
      - all-to-all
    * - ``"default"``
      - :class:`~.PauliEvolutionSynthesisDefault`
      - use a diagonalizing Clifford per Pauli term
      - all-to-all

.. autosummary::
   :toctree: ../stubs/

   PauliEvolutionSynthesisDefault
   PauliEvolutionSynthesisRustiq


Modular Adder Synthesis
'''''''''''''''''''''''

.. list-table:: Plugins for :class:`.ModularAdderGate` (key = ``"ModularAdder"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Number of clean ancillas
      - Description
    * - ``"modular_v17"``
      - :class:`.ModularAdderSynthesisV17`
      - 0
      - a modular adder without any ancillary qubits
    * - ``"ripple_cdkm"``
      - :class:`.ModularAdderSynthesisC04`
      - 1
      - a ripple-carry adder
    * - ``"ripple_vbe"``
      - :class:`.ModularAdderSynthesisV95`
      - :math:`n-1`, for :math:`n`-bit numbers
      - a ripple-carry adder
    * - ``"qft"``
      - :class:`.ModularAdderSynthesisD00`
      - 0
      - a QFT-based adder
    * - ``"default"``
      - :class:`~.ModularAdderSynthesisDefault`
      - any
      - chooses the best algorithm based on the ancillas available

.. autosummary::
   :toctree: ../stubs/

   ModularAdderSynthesisV17
   ModularAdderSynthesisC04
   ModularAdderSynthesisD00
   ModularAdderSynthesisV95
   ModularAdderSynthesisDefault

Half Adder Synthesis
''''''''''''''''''''

.. list-table:: Plugins for :class:`.HalfAdderGate` (key = ``"HalfAdder"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Number of clean ancillas
      - Description
    * - ``"ripple_cdkm"``
      - :class:`.HalfAdderSynthesisC04`
      - 1
      - a ripple-carry adder
    * - ``"ripple_r25"``
      - :class:`.HalfAdderSynthesisR25`
      - 0
      - a ripple-carry adder with no ancillas
    * - ``"ripple_vbe"``
      - :class:`.HalfAdderSynthesisV95`
      - :math:`n-1`, for :math:`n`-bit numbers
      - a ripple-carry adder
    * - ``"qft"``
      - :class:`.HalfAdderSynthesisD00`
      - 0
      - a QFT-based adder
    * - ``"default"``
      - :class:`~.HalfAdderSynthesisDefault`
      - any
      - chooses the best algorithm based on the ancillas available

.. autosummary::
   :toctree: ../stubs/

   HalfAdderSynthesisC04
   HalfAdderSynthesisD00
   HalfAdderSynthesisV95
   HalfAdderSynthesisR25
   HalfAdderSynthesisDefault

Full Adder Synthesis
''''''''''''''''''''

.. list-table:: Plugins for :class:`.FullAdderGate` (key = ``"FullAdder"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Number of clean ancillas
      - Description
    * - ``"ripple_cdkm"``
      - :class:`.FullAdderSynthesisC04`
      - 0
      - a ripple-carry adder
    * - ``"ripple_vbe"``
      - :class:`.FullAdderSynthesisV95`
      - :math:`n-1`, for :math:`n`-bit numbers
      - a ripple-carry adder
    * - ``"default"``
      - :class:`~.FullAdderSynthesisDefault`
      - any
      - chooses the best algorithm based on the ancillas available

.. autosummary::
   :toctree: ../stubs/

   FullAdderSynthesisC04
   FullAdderSynthesisV95
   FullAdderSynthesisDefault


Multiplier Synthesis
''''''''''''''''''''

.. list-table:: Plugins for :class:`.MultiplierGate` (key = ``"Multiplier"``)
    :header-rows: 1

    * - Plugin name
      - Plugin class
      - Number of clean ancillas
      - Description
    * - ``"cumulative"``
      - :class:`.MultiplierSynthesisH18`
      - depending on the :class:`.AdderGate` used
      - a cumulative adder based on controlled adders
    * - ``"qft"``
      - :class:`.MultiplierSynthesisR17`
      - 0
      - a QFT-based multiplier
    * - ``"default"``
      - :class:`~.MultiplierSynthesisDefault`
      - any
      - chooses the best algorithm based on the ancillas available

.. autosummary::
   :toctree: ../stubs/

   MultiplierSynthesisH18
   MultiplierSynthesisR17
   MultiplierSynthesisDefault

    )annotationsN)QuantumCircuit)	Operation)LinearFunctionQFTGateXGateMCXGateC3XGateC4XGatePauliEvolutionGatePermutationGateMCMTGateModularAdderGateHalfAdderGateFullAdderGateMultiplierGateWeightedSumGateGlobalPhaseGate)AnnotatedOperationModifierControlModifierInverseModifierPowerModifier_canonicalize_modifiers)CouplingMap)synth_integer_comparator_2ssynth_integer_comparator_greedysynth_weighted_sum_carry)synth_clifford_fullsynth_clifford_layerssynth_clifford_depth_lnnsynth_clifford_greedysynth_clifford_agsynth_clifford_bm)synth_cnot_count_full_pmhsynth_cnot_depth_line_kmscalc_inverse_matrix)transpose_cx_circ)synth_permutation_basicsynth_permutation_acgsynth_permutation_depth_lnn_kms)synth_qft_fullsynth_qft_line)synth_mcx_n_dirty_i15synth_mcx_2_dirty_kg24synth_mcx_1_dirty_kg24synth_mcx_n_clean_m15synth_mcx_2_clean_kg24synth_mcx_1_clean_kg24synth_mcx_1_clean_b95synth_mcx_gray_codesynth_mcx_noaux_v24synth_mcx_noaux_hp24synth_mcmt_vchainsynth_mcmt_xgate)ProductFormulasynth_pauli_network_rustiq)adder_ripple_c04adder_qft_d00adder_ripple_v95adder_ripple_r25adder_modular_v17multiplier_qft_r17multiplier_cumulative_h18)Clifford)ApproximateTokenSwapper)TranspilerError)EFFICIENTLY_CONTROLLED_GATES)OptimizationMetric)synthesize_operationHighLevelSynthesisData   )HighLevelSynthesisPluginc                  "    \ rS rSrSrSS jrSrg)DefaultSynthesisCliffordia  a  The default clifford synthesis plugin.

For N <= 3 qubits this is the optimal CX cost decomposition by Bravyi, Maslov.
For N > 3 qubits this is done using the general non-optimal greedy compilation
routine from reference by Bravyi, Hu, Maslov, Shaydulin.

This plugin name is :``clifford.default`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                H    [        U[        5      (       d  g[        U5      nU$ %Run synthesis for the given Clifford.N)
isinstancerC   r   selfhigh_level_objectcoupling_maptargetqubitsoptionsdecompositions          h/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/transpiler/passes/synthesis/hls_plugins.pyrunDefaultSynthesisClifford.runl  s$    +X66+,=>     NNN__name__
__module____qualname____firstlineno____doc__r[   __static_attributes__r^   r]   rZ   rM   rM   a  s    r]   rM   c                  "    \ rS rSrSrSS jrSrg)AGSynthesisCliffordiu  zClifford synthesis plugin based on the Aaronson-Gottesman method.

This plugin name is :``clifford.ag`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                H    [        U[        5      (       d  g[        U5      nU$ rO   )rQ   rC   r#   rR   s          rZ   r[   AGSynthesisClifford.run|  s$    +X66)*;<r]   r^   r_   r`   r^   r]   rZ   rh   rh   u      r]   rh   c                  "    \ rS rSrSrSS jrSrg)BMSynthesisCliffordi  aO  Clifford synthesis plugin based on the Bravyi-Maslov method.

The method only works on Cliffords with at most 3 qubits, for which it
constructs the optimal CX cost decomposition.

This plugin name is :``clifford.bm`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                p    [        U[        5      (       d  gUR                  S::  a  [        U5      nU$ SnU$ )rP   N   )rQ   rC   
num_qubitsr$   rR   s          rZ   r[   BMSynthesisClifford.run  sA    +X66''1,-.?@M  !Mr]   r^   r_   r`   r^   r]   rZ   rm   rm     s    
r]   rm   c                  "    \ rS rSrSrSS jrSrg)GreedySynthesisCliffordi  zClifford synthesis plugin based on the greedy synthesis
Bravyi-Hu-Maslov-Shaydulin method.

This plugin name is :``clifford.greedy`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                H    [        U[        5      (       d  g[        U5      nU$ rO   )rQ   rC   r"   rR   s          rZ   r[   GreedySynthesisClifford.run  $    +X66-.?@r]   r^   r_   r`   r^   r]   rZ   rs   rs         r]   rs   c                  "    \ rS rSrSrSS jrSrg)LayerSynthesisCliffordi  a  Clifford synthesis plugin based on the Bravyi-Maslov method
to synthesize Cliffords into layers.

This plugin name is :``clifford.layers`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                H    [        U[        5      (       d  g[        U5      nU$ rO   )rQ   rC   r    rR   s          rZ   r[   LayerSynthesisClifford.run  rv   r]   r^   r_   r`   r^   r]   rZ   ry   ry     rw   r]   ry   c                  "    \ rS rSrSrSS jrSrg)LayerLnnSynthesisCliffordi  a8  Clifford synthesis plugin based on the Bravyi-Maslov method
to synthesize Cliffords into layers, with each layer synthesized
adhering to LNN connectivity.

This plugin name is :``clifford.lnn`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                H    [        U[        5      (       d  g[        U5      nU$ rO   )rQ   rC   r!   rR   s          rZ   r[   LayerLnnSynthesisClifford.run  s$    +X6601BCr]   r^   r_   r`   r^   r]   rZ   r}   r}     s    r]   r}   c                  "    \ rS rSrSrSS jrSrg)DefaultSynthesisLinearFunctioni  zThe default linear function synthesis plugin.

This plugin name is :``linear_function.default`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                \    [        U[        5      (       d  g[        UR                  5      nU$ )+Run synthesis for the given LinearFunction.N)rQ   r   r%   linearrR   s          rZ   r[   "DefaultSynthesisLinearFunction.run  s*    +^<<12C2J2JKr]   r^   r_   r`   r^   r]   rZ   r   r     rk   r]   r   c                  "    \ rS rSrSrSS jrSrg)KMSSynthesisLinearFunctioni  a  Linear function synthesis plugin based on the Kutin-Moulton-Smithline method.

This plugin name is :``linear_function.kms`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

The plugin supports the following plugin-specific options:

* use_inverted: Indicates whether to run the algorithm on the inverse matrix
    and to invert the synthesized circuit.
    In certain cases this provides a better decomposition than the direct approach.
* use_transposed: Indicates whether to run the algorithm on the transposed matrix
    and to invert the order of CX gates in the synthesized circuit.
    In certain cases this provides a better decomposition than the direct approach.

Nc                |   [        U[        5      (       d  gUR                  SS5      nUR                  SS5      nUR                  R	                  [
        SS9nU(       a  [        R                  " U5      nU(       a  [        U5      n[        U5      n	U(       a  [        U	5      n	U(       a  U	R                  5       n	U	$ )r   Nuse_invertedFuse_transposedcopy)rQ   r   getr   astypeboolnp	transposer'   r&   r(   inverse)
rS   rT   rU   rV   rW   rX   r   r   matrY   s
             rZ   r[   KMSSynthesisLinearFunction.run  s    +^<<{{>59 %5u=&&--d-?,,s#C%c*C1#6-m<M)113Mr]   r^   r_   r`   r^   r]   rZ   r   r     s     r]   r   c                  "    \ rS rSrSrSS jrSrg)PMHSynthesisLinearFunctioni
  uP  Linear function synthesis plugin based on the Patel-Markov-Hayes method.

This plugin name is :``linear_function.pmh`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

The plugin supports the following plugin-specific options:

* section size: The size of each section used in the Patel–Markov–Hayes algorithm [1].
* use_inverted: Indicates whether to run the algorithm on the inverse matrix
    and to invert the synthesized circuit.
    In certain cases this provides a better decomposition than the direct approach.
* use_transposed: Indicates whether to run the algorithm on the transposed matrix
    and to invert the order of CX gates in the synthesized circuit.
    In certain cases this provides a better decomposition than the direct approach.

References:
    1. Patel, Ketan N., Igor L. Markov, and John P. Hayes,
       *Optimal synthesis of linear reversible circuits*,
       Quantum Information & Computation 8.3 (2008): 282-294.
       `arXiv:quant-ph/0302002 [quant-ph] <https://arxiv.org/abs/quant-ph/0302002>`_
Nc                   [        U[        5      (       d  gUR                  SS5      nUR                  SS5      nUR                  SS5      nUR                  R	                  [
        SS9n	U(       a  [        R                  " U	5      n	U(       a  [        U	5      n	[        XS9n
U(       a  [        U
5      n
U(       a  U
R                  5       n
U
$ )	r   Nsection_size   r   Fr   r   )r   )rQ   r   r   r   r   r   r   r   r'   r%   r(   r   )rS   rT   rU   rV   rW   rX   r   r   r   r   rY   s              rZ   r[   PMHSynthesisLinearFunction.run!  s    +^<<{{>15{{>59 %5u=&&--d-?,,s#C%c*C1#Q-m<M)113Mr]   r^   r_   r`   r^   r]   rZ   r   r   
  s    ,r]   r   c                  "    \ rS rSrSrSS jrSrg)KMSSynthesisPermutationi;  zThe permutation synthesis plugin based on the Kutin, Moulton, Smithline method.

This plugin name is :``permutation.kms`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                \    [        U[        5      (       d  g[        UR                  5      nU$ (Run synthesis for the given Permutation.N)rQ   r   r+   patternrR   s          rZ   r[   KMSSynthesisPermutation.runB  s*    +_==78I8Q8QRr]   r^   r_   r`   r^   r]   rZ   r   r   ;  rk   r]   r   c                  "    \ rS rSrSrSS jrSrg)BasicSynthesisPermutationiK  zThe permutation synthesis plugin based on sorting.

This plugin name is :``permutation.basic`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                \    [        U[        5      (       d  g[        UR                  5      nU$ r   )rQ   r   r)   r   rR   s          rZ   r[   BasicSynthesisPermutation.runR  s*    +_==/0A0I0IJr]   r^   r_   r`   r^   r]   rZ   r   r   K  rk   r]   r   c                  "    \ rS rSrSrSS jrSrg)ACGSynthesisPermutationi[  zThe permutation synthesis plugin based on the Alon, Chung, Graham method.

This plugin name is :``permutation.acg`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                \    [        U[        5      (       d  g[        UR                  5      nU$ r   )rQ   r   r*   r   rR   s          rZ   r[   ACGSynthesisPermutation.runb  s*    +_==-.?.G.GHr]   r^   r_   r`   r^   r]   rZ   r   r   [  rk   r]   r   c                  "    \ rS rSrSrSS jrSrg)QFTSynthesisFullik  u  Synthesis plugin for QFT gates using all-to-all connectivity.

This plugin name is :``qft.full`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

Note that the plugin mechanism is not applied if the gate is called ``qft`` but
is not an instance of ``QFTGate``. This allows users to create custom gates with
name ``qft``.

The plugin supports the following additional options:

* reverse_qubits (bool): Whether to synthesize the "QFT" operation (if ``False``,
    which is the default) or the "QFT-with-reversal" operation (if ``True``).
    Some implementation of the ``QFTGate`` include a layer of swap gates at the end
    of the synthesized circuit, which can in principle be dropped if the ``QFTGate``
    itself is the last gate in the circuit.
* approximation_degree (int): The degree of approximation (0 for no approximation).
    It is possible to implement the QFT approximately by ignoring
    controlled-phase rotations with the angle beneath a threshold. This is discussed
    in more detail in [1] or [2].
* insert_barriers (bool): If True, barriers are inserted as visualization improvement.
* inverse (bool): If True, the inverse Fourier transform is constructed.
* name (str): The name of the circuit.

References:
    1. Adriano Barenco, Artur Ekert, Kalle-Antti Suominen, and Päivi Törmä,
       *Approximate Quantum Fourier Transform and Decoherence*,
       Physical Review A (1996).
       `arXiv:quant-ph/9601018 [quant-ph] <https://arxiv.org/abs/quant-ph/9601018>`_
    2. Donny Cheung,
       *Improved Bounds for the Approximate QFT* (2004),
       `arXiv:quant-ph/0403071 [quant-ph] <https://https://arxiv.org/abs/quant-ph/0403071>`_
Nc           	         [        U[        5      (       d  gUR                  SS5      nUR                  SS5      nUR                  SS5      nUR                  SS5      n	UR                  SS5      n
[        UR                  U(       + UUU	U
S	9nU$ )
$Run synthesis for the given QFTGate.Nreverse_qubitsFapproximation_degreer   insert_barriersr   name)rp   do_swapsr   r   r   r   )rQ   r   r   r,   rp   )rS   rT   rU   rV   rW   rX   r   r   r   r   r   rY   s               rZ   r[   QFTSynthesisFull.run  s    
 +W55 %5u=&{{+A1E!++&7?++i/{{64(&(33''!5+
 r]   r^   r_   r`   r^   r]   rZ   r   r   k  s     Dr]   r   c                  "    \ rS rSrSrSS jrSrg)QFTSynthesisLinei  u  Synthesis plugin for QFT gates using linear connectivity.

This plugin name is :``qft.line`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

Note that the plugin mechanism is not applied if the gate is called ``qft`` but
is not an instance of ``QFTGate``. This allows users to create custom gates with
name ``qft``.

The plugin supports the following additional options:

* reverse_qubits (bool): Whether to synthesize the "QFT" operation (if ``False``,
    which is the default) or the "QFT-with-reversal" operation (if ``True``).
    Some implementation of the ``QFTGate`` include a layer of swap gates at the end
    of the synthesized circuit, which can in principle be dropped if the ``QFTGate``
    itself is the last gate in the circuit.
* approximation_degree (int): the degree of approximation (0 for no approximation).
    It is possible to implement the QFT approximately by ignoring
    controlled-phase rotations with the angle beneath a threshold. This is discussed
    in more detail in [1] or [2].

References:
    1. Adriano Barenco, Artur Ekert, Kalle-Antti Suominen, and Päivi Törmä,
       *Approximate Quantum Fourier Transform and Decoherence*,
       Physical Review A (1996).
       `arXiv:quant-ph/9601018 [quant-ph] <https://arxiv.org/abs/quant-ph/9601018>`_
    2. Donny Cheung,
       *Improved Bounds for the Approximate QFT* (2004),
       `arXiv:quant-ph/0403071 [quant-ph] <https://https://arxiv.org/abs/quant-ph/0403071>`_
Nc                    [        U[        5      (       d  gUR                  SS5      nUR                  SS5      n[        UR                  U(       + US9nU$ )r   Nr   Fr   r   )rp   r   r   )rQ   r   r   r-   rp   )	rS   rT   rU   rV   rW   rX   r   r   rY   s	            rZ   r[   QFTSynthesisLine.run  s\    
 +W55 %5u=&{{+A1E&(33''!5

 r]   r^   r_   r`   r^   r]   rZ   r   r     s    >r]   r   c                  "    \ rS rSrSrSS jrSrg) TokenSwapperSynthesisPermutationi  a3  The permutation synthesis plugin based on the token swapper algorithm.

This plugin name is :``permutation.token_swapper`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

In more detail, this plugin is used to synthesize objects of type `PermutationGate`.
When synthesis succeeds, the plugin outputs a quantum circuit consisting only of swap
gates. When synthesis does not succeed, the plugin outputs `None`.

If either `coupling_map` or `qubits` is None, then the synthesized circuit
is not required to adhere to connectivity constraints, as is the case
when the synthesis is done before layout/routing.

On the other hand, if both `coupling_map` and `qubits` are specified, the synthesized
circuit is supposed to adhere to connectivity constraints. At the moment, the
plugin only creates swap gates between qubits in `qubits`, i.e. it does not use
any other qubits in the coupling map (if such synthesis is not possible, the
plugin  outputs `None`).

The plugin supports the following plugin-specific options:

* trials: The number of trials for the token swapper to perform the mapping. The
  circuit with the smallest number of SWAPs is returned.
* seed: The argument to the token swapper specifying the seed for random trials.
* parallel_threshold: The argument to the token swapper specifying the number of nodes
  in the graph beyond which the algorithm will use parallel processing.

For more details on the token swapper algorithm, see to the paper:
`arXiv:1902.09102 <https://arxiv.org/abs/1902.09102>`__.
Nc                   [        U[        5      (       d  gUR                  SS5      nUR                  SS5      nUR                  SS5      nUR                  n	[	        U	5       V
Vs0 s H  u  pX_M	     nn
nUb  Uc   [
        R                  " [        U	5      5      nOUR                  USS	9nUR                  R                  5       n[        XS
9n UR                  XUS9nUb<  [        [        UR!                  5       5      5      nU H  nUR"                  " U6   M     U$ gs  snn
f ! [        R                   a    Sn N^f = f)r   Ntrials   seedr   parallel_threshold2   F)check_if_connected)r   )r   )rQ   r   r   r   	enumerater   	from_fulllenreducegraphto_undirectedrD   maprxInvalidMappingr   node_indicesswap)rS   rT   rU   rV   rW   rX   r   r   r   r   ijpattern_as_dictused_coupling_mapr   swapperswapper_resultrY   r   s                      rZ   r[   $TokenSwapperSynthesisPermutation.run  sL    +_==Xq){{61%$[[)=rB#++,5g,>?,>DA14,>? 6> !, 5 5c'l C !- 3 3Fu 3 U!''557)%;	"$[[<N ) N %*3u/A/A/C+DEM&""D) '  C @0    	"!N	"s   'D"D( (E Er^   r_   r`   r^   r]   rZ   r   r     s    >,r]   r   c                  "    \ rS rSrSrSS jrSrg)MCXSynthesisNDirtyI15i)  a  Synthesis plugin for a multi-controlled X gate based on the paper
by Iten et al. (2016).

See [1] for details.

This plugin name is :``mcx.n_dirty_i15`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

For a multi-controlled X gate with :math:`k\ge 4` control qubits this synthesis
method requires :math:`k - 2` additional dirty auxiliary qubits. The synthesized
circuit consists of :math:`2 * k - 1` qubits and at most :math:`8 * k - 6` CX gates.
For :math:`k\le 3` explicit efficient circuits are used instead.

The plugin supports the following plugin-specific options:

* num_clean_ancillas: The number of clean auxiliary qubits available.
* num_dirty_ancillas: The number of dirty auxiliary qubits available.
* relative_phase: When set to ``True``, the method applies the optimized multi-controlled
  X gate up to a relative phase, in a way that, by lemma 8 of [1], the relative
  phases of the ``action part`` cancel out with the phases of the ``reset part``.
* action_only: when set to ``True``, the method applies only the ``action part``
  of lemma 8 of [1].

References:
    1. Iten et. al., *Quantum Circuits for Isometries*, Phys. Rev. A 93, 032318 (2016),
       `arXiv:1501.06911 <http://arxiv.org/abs/1501.06911>`_
Nc                ,   [        U[        [        [        45      (       d  gUR                  nUR                  SS5      nUR                  SS5      nUR                  SS5      n	UR                  SS5      n
US:  a  X-   US	-
  :  a  g[        XiU
5      nU$ )
%Run synthesis for the given MCX gate.Nnum_clean_ancillasr   num_dirty_ancillasrelative_phaseFactions_onlyro   r   )rQ   r	   r
   r   num_ctrl_qubitsr   r.   )rS   rT   rU   rV   rW   rX   r   r   r   r   action_onlyrY   s               rZ   r[   MCXSynthesisNDirtyI15.runF  s     +gw-HII
 +;;$[[)=qA$[[)=qA %5u=kk.%8a$6$Ko`aNa$a-o{[r]   r^   r_   r`   r^   r]   rZ   r   r   )  s    8r]   r   c                  "    \ rS rSrSrSS jrSrg)MCXSynthesisNCleanM15i^  a  Synthesis plugin for a multi-controlled X gate based on the paper by
Maslov (2016).

See [1] for details.

This plugin name is :``mcx.n_clean_m15`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

For a multi-controlled X gate with :math:`k\ge 3` control qubits this synthesis
method requires :math:`k - 2` additional clean auxiliary qubits. The synthesized
circuit consists of :math:`2 * k - 1` qubits and at most :math:`6 * k - 6` CX gates.

The plugin supports the following plugin-specific options:

* num_clean_ancillas: The number of clean auxiliary qubits available.

References:
    1. Maslov., Phys. Rev. A 93, 022311 (2016),
       `arXiv:1508.03273 <https://arxiv.org/pdf/1508.03273>`_
Nc                    [        U[        [        [        45      (       d  gUR                  nUR                  SS5      nUS:  a	  XvS-
  :  a  g[        U5      nU$ )r   Nr   r   ro   r   )rQ   r	   r
   r   r   r   r1   	rS   rT   rU   rV   rW   rX   r   r   rY   s	            rZ   r[   MCXSynthesisNCleanM15.runt  sa     +gw-HII
 +;;$[[)=qAa$619L$L-o>r]   r^   r_   r`   r^   r]   rZ   r   r   ^  s    *r]   r   c                  "    \ rS rSrSrSS jrSrg)MCXSynthesis1CleanB95i  a:  Synthesis plugin for a multi-controlled X gate based on the paper by
Barenco et al. (1995).

See [1] for details.

This plugin name is :``mcx.1_clean_b95`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

For a multi-controlled X gate with :math:`k\ge 5` control qubits this synthesis
method requires a single additional clean auxiliary qubit. The synthesized
circuit consists of :math:`k + 2` qubits and at most :math:`16 * k - 24` CX gates.

The plugin supports the following plugin-specific options:

* num_clean_ancillas: The number of clean auxiliary qubits available.

References:
    1. Barenco et. al., *Elementary gates for quantum computation*, Phys.Rev. A52 3457 (1995),
       `arXiv:quant-ph/9503016 <https://arxiv.org/abs/quant-ph/9503016>`_
Nc                    [        U[        [        [        45      (       d  gUR                  nUS::  a  gUR                  SS5      nUS:  a  US:X  a  g[        U5      nU$ )r   Nr   r   r   r   )rQ   r	   r
   r   r   r   r4   r   s	            rZ   r[   MCXSynthesis1CleanB95.run  si     +gw-HII
 +;;a$[[)=qAa$6!$;-o>r]   r^   r_   r`   r^   r]   rZ   r   r     s    *r]   r   c                  "    \ rS rSrSrSS jrSrg)MCXSynthesis2CleanKG24i  a1  Synthesis plugin for a multi-controlled X gate based on the paper by Khattar and
Gidney (2024).

See [1] for details.

The plugin name is :``mcx.2_clean_kg24`` which can be used as the key on an :class:`~.HLSConfig`
object to use this method with :class:`~.HighLevelSynthesis`.

For a multi-controlled X gate with :math:`k\ge 3` control qubits this synthesis method requires
:math:`2` additional clean ancillary qubits. The synthesized circuit consists of :math:`k + 3`
qubits and at most :math:`6 * k - 6` CX gates.

The plugin supports the following plugin-specific options:

* num_clean_ancillas: The number of clean ancillary qubits available.

References:
    1. Khattar and Gidney, Rise of conditionally clean ancillae for optimizing quantum circuits
    `arXiv:2407.17966 <https://arxiv.org/abs/2407.17966>`__
Nc                    [        U[        [        [        45      (       d  gUR                  nUR                  SS5      nUS:  a  g[        U5      nU$ )r   Nr   r   r   )rQ   r	   r
   r   r   r   r2   r   s	            rZ   r[   MCXSynthesis2CleanKG24.run  V     +gw-HII
 +;;$[[)=qA!.?r]   r^   r_   r`   r^   r]   rZ   r   r         *r]   r   c                  "    \ rS rSrSrSS jrSrg)MCXSynthesis2DirtyKG24i  a3  Synthesis plugin for a multi-controlled X gate based on the paper by Khattar and
Gidney (2024).

See [1] for details.

The plugin name is :``mcx.2_dirty_kg24`` which can be used as the key on an :class:`~.HLSConfig`
object to use this method with :class:`~.HighLevelSynthesis`.

For a multi-controlled X gate with :math:`k\ge 3` control qubits this synthesis method requires
:math:`2` additional dirty ancillary qubits. The synthesized circuit consists of :math:`k + 3`
qubits and at most :math:`12 * k - 18` CX gates.

The plugin supports the following plugin-specific options:

* num_clean_ancillas: The number of clean ancillary qubits available.

References:
    1. Khattar and Gidney, Rise of conditionally clean ancillae for optimizing quantum circuits
    `arXiv:2407.17966 <https://arxiv.org/abs/2407.17966>`__
Nc                    [        U[        [        [        45      (       d  gUR                  nUR                  SS5      UR                  SS5      -   nUS:  a  g[        U5      nU$ )r   Nr   r   r   r   )rQ   r	   r
   r   r   r   r/   	rS   rT   rU   rV   rW   rX   r   r   rY   s	            rZ   r[   MCXSynthesis2DirtyKG24.run  n     +gw-HII
 +;;$[[)=qAGKK !E
 
 !.?r]   r^   r_   r`   r^   r]   rZ   r   r         *r]   r   c                  "    \ rS rSrSrSS jrSrg)MCXSynthesis1CleanKG24i  a0  Synthesis plugin for a multi-controlled X gate based on the paper by Khattar and
Gidney (2024).

See [1] for details.

The plugin name is :``mcx.1_clean_kg24`` which can be used as the key on an :class:`~.HLSConfig`
object to use this method with :class:`~.HighLevelSynthesis`.

For a multi-controlled X gate with :math:`k\ge 3` control qubits this synthesis method requires
:math:`1` additional clean ancillary qubit. The synthesized circuit consists of :math:`k + 2`
qubits and at most :math:`6 * k - 6` CX gates.

The plugin supports the following plugin-specific options:

* num_clean_ancillas: The number of clean ancillary qubits available.

References:
    1. Khattar and Gidney, Rise of conditionally clean ancillae for optimizing quantum circuits
    `arXiv:2407.17966 <https://arxiv.org/abs/2407.17966>`__
Nc                    [        U[        [        [        45      (       d  gUR                  nUR                  SS5      nUS:  a  g[        U5      nU$ )r   Nr   r   rJ   )rQ   r	   r
   r   r   r   r3   r   s	            rZ   r[   MCXSynthesis1CleanKG24.run%  r   r]   r^   r_   r`   r^   r]   rZ   r   r     r   r]   r   c                  "    \ rS rSrSrSS jrSrg)MCXSynthesis1DirtyKG24i9  a2  Synthesis plugin for a multi-controlled X gate based on the paper by Khattar and
Gidney (2024).

See [1] for details.

The plugin name is :``mcx.1_dirty_kg24`` which can be used as the key on an :class:`~.HLSConfig`
object to use this method with :class:`~.HighLevelSynthesis`.

For a multi-controlled X gate with :math:`k\ge 3` control qubits this synthesis method requires
:math:`1` additional dirty ancillary qubit. The synthesized circuit consists of :math:`k + 2`
qubits and at most :math:`12 * k - 18` CX gates.

The plugin supports the following plugin-specific options:

* num_clean_ancillas: The number of clean ancillary qubits available.

References:
    1. Khattar and Gidney, Rise of conditionally clean ancillae for optimizing quantum circuits
    `arXiv:2407.17966 <https://arxiv.org/abs/2407.17966>`__
Nc                    [        U[        [        [        45      (       d  gUR                  nUR                  SS5      UR                  SS5      -   nUS:  a  g[        U5      nU$ )r   Nr   r   r   rJ   )rQ   r	   r
   r   r   r   r0   r   s	            rZ   r[   MCXSynthesis1DirtyKG24.runO  r   r]   r^   r_   r`   r^   r]   rZ   r   r   9  r   r]   r   c                  "    \ rS rSrSrSS jrSrg)MCXSynthesisGrayCodeie  a  Synthesis plugin for a multi-controlled X gate based on the Gray code.

This plugin name is :``mcx.gray_code`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

For a multi-controlled X gate with :math:`k` control qubits this synthesis
method requires no additional clean auxiliary qubits. The synthesized
circuit consists of :math:`k + 1` qubits.

It is not recommended to use this method for large values of :math:`k + 1`
as it produces exponentially many gates.
Nc                v    [        U[        [        [        45      (       d  gUR                  n[        U5      nU$ r   N)rQ   r	   r
   r   r   r5   rS   rT   rU   rV   rW   rX   r   rY   s           rZ   r[   MCXSynthesisGrayCode.runs  9     +gw-HII
 +;;+O<r]   r^   r_   r`   r^   r]   rZ   r   r   e  s    r]   r   c                  "    \ rS rSrSrSS jrSrg)MCXSynthesisNoAuxV24i  a  Synthesis plugin for a multi-controlled X gate based on the
implementation for MCPhaseGate, which is in turn based on the
paper by Vale et al. (2024).

See [1] for details.

This plugin name is :``mcx.noaux_v24`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

For a multi-controlled X gate with :math:`k` control qubits this synthesis
method requires no additional clean auxiliary qubits. The synthesized
circuit consists of :math:`k + 1` qubits. The number of CX-gates is quadratic in
:math:`k`.

References:
    1. Vale et. al., *Circuit Decomposition of Multicontrolled Special Unitary
       Single-Qubit Gates*, IEEE TCAD 43(3) (2024),
       `arXiv:2302.06377 <https://arxiv.org/abs/2302.06377>`_
Nc                v    [        U[        [        [        45      (       d  gUR                  n[        U5      nU$ r   )rQ   r	   r
   r   r   r6   r   s           rZ   r[   MCXSynthesisNoAuxV24.run  r  r]   r^   r_   r`   r^   r]   rZ   r  r    s    (r]   r  c                  "    \ rS rSrSrSS jrSrg)MCXSynthesisNoAuxHP24i  a  Synthesis plugin for a multi-controlled X gate based on the
paper by Huang and Palsberg.

See [1] for details.

This plugin name is :``mcx.noaux_hp24`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

For a multi-controlled X gate with :math:`k` control qubits this synthesis
method requires no additional clean auxiliary qubits. The synthesized
circuit consists of :math:`k + 1` qubits. The number of CX-gates is linear in
:math:`k`.

References:
    1. Huang and Palsberg, *Compiling Conditional Quantum Gates without Using
       Helper Qubits*, PLDI (2024),
       <https://dl.acm.org/doi/10.1145/3656436>`_
Nc                v    [        U[        [        [        45      (       d  gUR                  n[        U5      nU$ r   )rQ   r	   r
   r   r   r7   r   s           rZ   r[   MCXSynthesisNoAuxHP24.run  s9     +gw-HII
 +;;,_=r]   r^   r_   r`   r^   r]   rZ   r  r    s    &r]   r  c                  "    \ rS rSrSrSS jrSrg)MCXSynthesisDefaulti  a{  The default synthesis plugin for a multi-controlled X gate.

This plugin name is :``mcx.default`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.


The plugin supports the following plugin-specific options:

* ``optimization_metric``: The optimization metric, indicating the property
  of the output circuit (e.g., the 2-qubit gate count or the T-count) that should
  be minimized. See :class:`.OptimizationMetric`.
* ``num_clean_ancillas``: The number of clean ancillary qubits available.
* ``num_dirty_ancillas``: The number of dirty ancillary qubits available.

Nc           	        [        U[        [        [        45      (       d  gUR	                  S[
        R                  5      nU[
        R                  :X  aA  [        [        [        [        [        [        [        UR                  S::  a  [         O["        /nO@[        [        [        [        [        [        [        UR                  S::  a  [         O["        /nU H$  nU" 5       R$                  " XX440 UD6=n	 c  M"  U	s  $    g)r   Noptimization_metricr   )rQ   r	   r
   r   r   rG   COUNT_2QCOUNT_Tr   r   r   r   r   r   r   r   r  r  r[   
rS   rT   rU   rV   rW   rX   metricmethodsmethodrY   s
             rZ   r[   MCXSynthesisDefault.run  s     +gw-HII
 24F4O4OP'/// '&&&%%% )88A= ).G$ '&%%&&% )88A= ).G F!'%V"GN"  	
 %$  r]   r^   r_   r`   r^   r]   rZ   r  r    s     6r]   r  c                  "    \ rS rSrSrSS jrSrg)MCMTSynthesisDefaulti  z'A default decomposition for MCMT gates.Nc                    [        U[        5      (       d  g [        [        4 H$  nU" 5       R                  " XX440 UD6=n c  M"  Us  $    [        5       R                  " XX440 UD6$ N)rQ   r   MCMTSynthesisXGateMCMTSynthesisVChainr[   MCMTSynthesisNoAux)rS   rT   rU   rV   rW   rX   synthesis_methodrY   s           rZ   r[   MCMTSynthesisDefault.run  s    +X66 !

 "2!3!7!7%V"GN"  	
 %$!
 "#''(9c[bccr]   r^   r_   r`   r^   r]   rZ   r  r    s    1dr]   r  c                  "    \ rS rSrSrSS jrSrg)r  i(  +A V-chain based synthesis for ``MCMTGate``.Nc                *   [        U[        5      (       d  g UR                  nUR                  SS 5      nUR                  S:X  aY  [        UR                  5      nUR                  UR                  UR                  US9UR                  5        UR                  5       $ [        UR                  UR                  S9n	[        UR                  5       H  n
U	R                  Xj// 5        M     U	R                  UR                  US9nUR                  5       $ )N
ctrl_staterJ   )r"  )r   )rQ   r   	base_gater   num_target_qubitsr   rp   appendcontrolr   rW   labelrange	decompose)rS   rT   rU   rV   rW   rX   r#  r"  circuitbaser   s              rZ   r[   MCMTSynthesisNoAux.run+  s    +X66%//	[[t4
..!3$%6%A%ABGNN!!"3"C"CPZ![   "" ""3"E"EL]LcLcdD,>>?IsB/ @ ll#4#D#DQ[l\G  ""r]   r^   r_   r`   r^   r]   rZ   r  r  (  s
    5#r]   r  c                  "    \ rS rSrSrSS jrSrg)r  iD  r   Nc                    [        U[        5      (       d  g UR                  SS5      UR                  S-
  :  a  g UR                  SS 5      n[	        UR
                  UR                  UR                  U5      $ )Nr   r   rJ   r"  )rQ   r   r   r   r8   r#  r$  rS   rT   rU   rV   rW   rX   r"  s          rZ   r[   MCMTSynthesisVChain.runG  sr    +X66;;+Q/2C2S2SVW2WW[[t4
 ''--//	
 	
r]   r^   r_   r`   r^   r]   rZ   r  r  D  s
    5
r]   r  c                  "    \ rS rSrSrSS jrSrg)r  iX  z:A synthesis for ``MCMTGate`` with X gate as the base gate.Nc                    [        U[        5      (       d  g [        UR                  [        5      (       d  g UR	                  SS 5      n[        UR                  UR                  U5      $ )Nr"  )rQ   r   r#  r   r   r9   r   r$  r/  s          rZ   r[   MCMTSynthesisXGate.run[  s\    +X66+55u==[[t4
--/@/R/RT^
 	
r]   r^   r_   r`   r^   r]   rZ   r  r  X  s
    D

r]   r  c                  "    \ rS rSrSrSS jrSrg)IntComparatorSynthesisDefaultih  zxThe default synthesis for ``IntegerComparatorGate``.

Currently this is only supporting an ancilla-based decomposition.
Nc                    UR                   S-
  nUS-
  nUR                  SS5      U:  a   [        XaR                  UR                  5      $ [        XaR                  UR                  5      $ NrJ   r   r   )rp   r   r   valuegeqr   )rS   rT   rU   rV   rW   rX   num_state_qubitsnum_auxs           rZ   r[   !IntComparatorSynthesisDefault.runn  sq    ,77!;"Q&;;+Q/'92 "9"9;L;P;P  +557H7L7L
 	
r]   r^   r_   r`   r^   r]   rZ   r5  r5  h  s    


r]   r5  c                  "    \ rS rSrSrSS jrSrg)IntComparatorSynthesisNoAuxi{  zFA potentially exponentially expensive comparison w/o auxiliary qubits.Nc                X    [        UR                  UR                  UR                  5      $ r  )r   r:  r8  r9  rS   rT   rU   rV   rW   rX   s         rZ   r[   IntComparatorSynthesisNoAux.run~  s*    ...0A0G0GIZI^I^
 	
r]   r^   r_   r`   r^   r]   rZ   r>  r>  {  s
    P
r]   r>  c                  "    \ rS rSrSrSS jrSrg)IntComparatorSynthesis2si  z-An integer comparison based on 2s complement.Nc                    UR                   S-
  nUR                  SS5      U:  a  g [        UR                   UR                  UR                  5      $ r7  )r:  r   r   r8  r9  )rS   rT   rU   rV   rW   rX   r;  s          rZ   r[   IntComparatorSynthesis2s.run  sQ    #44q8;;+Q/'9*..0A0G0GIZI^I^
 	
r]   r^   r_   r`   r^   r]   rZ   rC  rC    s
    7
r]   rC  c                  "    \ rS rSrSrSS jrSrg)ModularAdderSynthesisDefaulti  a  The default modular adder (no carry in, no carry out qubit) synthesis.

This plugin name is:``ModularAdder.default`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

The plugin supports the following plugin-specific options:

* ``optimization_metric``: The optimization metric, indicating the property
  of the output circuit (e.g., the 2-qubit gate count or the T-count) that should
  be minimized. See :class:`.OptimizationMetric`.
* ``num_clean_ancillas``: The number of clean ancillary qubits available.
* ``num_dirty_ancillas``: The number of dirty ancillary qubits available.

Nc                   [        U[        5      (       d  g UR                  S[        R                  5      nU[        R                  :X  aG  / nSUR
                  s=::  a  S::  a  O  OUR                  [        5        UR                  [        5        O[        /nU H$  nU" 5       R                  " XX440 UD6=n	 c  M"  U	s  $    g )Nr  r      )
rQ   r   r   rG   r  r:  r%  ModularAdderSynthesisD00ModularAdderSynthesisV17r[   r  s
             rZ   r[    ModularAdderSynthesisDefault.run  s    +-=>>24F4O4OP'000G%66;!;78NN34 00GF!'%V"GN"  	
 %$  r]   r^   r_   r`   r^   r]   rZ   rG  rG    s    r]   rG  c                  "    \ rS rSrSrSS jrSrg)rK  i  a  A modular adder (modulo :math:`2^n`) without any ancillary qubits.

The plugin name is :``ModularAdder.v17`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

This plugin requires no auxiliary qubits.

Nc                \    [        U[        5      (       d  g UR                  n[        U5      $ r  )rQ   r   r:  r@   rS   rT   rU   rV   rW   rX   r:  s          rZ   r[   ModularAdderSynthesisV17.run  s,    +-=>>,== !122r]   r^   r_   r`   r^   r]   rZ   rK  rK    s    3r]   rK  c                  "    \ rS rSrSrSS jrSrg)ModularAdderSynthesisC04i  a  A ripple-carry adder, modulo :math:`2^n`.

This plugin name is:``ModularAdder.ripple_c04`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

This plugin requires at least one clean auxiliary qubit.

The plugin supports the following plugin-specific options:

* ``num_clean_ancillas``: The number of clean auxiliary qubits available.

Nc                    [        U[        5      (       d  g UR                  SS5      S:  a  g [        UR                  SS9$ )Nr   r   rJ   fixedkind)rQ   r   r   r<   r:  r@  s         rZ   r[   ModularAdderSynthesisC04.run  sA    +-=>> ;;+Q/!3 1 B BQQr]   r^   r_   r`   r^   r]   rZ   rR  rR    s    Rr]   rR  c                  "    \ rS rSrSrSS jrSrg)ModularAdderSynthesisV95i  a  A ripple-carry adder, modulo :math:`2^n`.

This plugin name is:``ModularAdder.ripple_v95`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

For an adder on 2 registers with :math:`n` qubits each, this plugin requires at
least :math:`n-1` clean auxiliary qubit.

The plugin supports the following plugin-specific options:

* ``num_clean_ancillas``: The number of clean auxiliary qubits available.

Nc                    [        U[        5      (       d  g UR                  nUS-
  UR                  SS5      :  a  g [	        USS9$ )NrJ   r   r   rT  rU  )rQ   r   r:  r   r>   rO  s          rZ   r[   ModularAdderSynthesisV95.run  sL    +-=>>,== a'++.BA"FF 0w??r]   r^   r_   r`   r^   r]   rZ   rY  rY    s    
@r]   rY  c                  "    \ rS rSrSrSS jrSrg)rJ  i  zA QFT-based adder, modulo :math:`2^n`.

This plugin name is:``ModularAdder.qft_d00`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                X    [        U[        5      (       d  g [        UR                  SSS9$ )NrT  TrV  	annotated)rQ   r   r=   r:  r@  s         rZ   r[   ModularAdderSynthesisD00.run
  s+    +-=>>.??gY]^^r]   r^   r_   r`   r^   r]   rZ   rJ  rJ    s    _r]   rJ  c                  "    \ rS rSrSrSS jrSrg)HalfAdderSynthesisDefaulti  aC  The default half-adder (no carry in, but a carry out qubit) synthesis.

If we have an auxiliary qubit available, the Cuccaro ripple-carry adder uses
:math:`O(n)` CX gates and 1 auxiliary qubit, whereas the Vedral ripple-carry uses more CX
and :math:`n-1` auxiliary qubits. The QFT-based adder uses no auxiliary qubits, but
:math:`O(n^2)`, hence it is only used if no auxiliary qubits are available.

This plugin name is:``HalfAdder.default`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

If at least one clean auxiliary qubit is available, the :class:`HalfAdderSynthesisC04`
is used, otherwise :class:`HalfAdderSynthesisD00`.

The plugin supports the following plugin-specific options:

* ``num_clean_ancillas``: The number of clean auxiliary qubits available.

Nc                   [        U[        5      (       d  g UR                  S::  a"  [        5       R                  " XX440 UD6=n b  U$ [        5       R                  " XX440 UD6=n b  U$ [        5       R                  " XX440 UD6$ )Nro   )rQ   r   r:  HalfAdderSynthesisR25r[   HalfAdderSynthesisC04rR   s          rZ   r[   HalfAdderSynthesisDefault.run%  s    +];; ..!3!6!8!<!<%V"GN"   !  3488!CJ M 	
 !  %&**V
?F
 	
r]   r^   r_   r`   r^   r]   rZ   rb  rb    s    &
r]   rb  c                  "    \ rS rSrSrSS jrSrg)re  iC  a  A ripple-carry adder with a carry-out bit.

This plugin name is:``HalfAdder.ripple_c04`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

This plugin requires at least one clean auxiliary qubit.

The plugin supports the following plugin-specific options:

* ``num_clean_ancillas``: The number of clean auxiliary qubits available.

Nc                    [        U[        5      (       d  g UR                  SS5      S:  a  g [        UR                  SS9$ )Nr   r   rJ   halfrU  )rQ   r   r   r<   r:  r@  s         rZ   r[   HalfAdderSynthesisC04.runQ  s@    +];; ;;+Q/!3 1 B BPPr]   r^   r_   r`   r^   r]   rZ   re  re  C  s    Qr]   re  c                  "    \ rS rSrSrSS jrSrg)HalfAdderSynthesisV95i\  a  A ripple-carry adder with a carry-out bit.

This plugin name is:``HalfAdder.ripple_v95`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

For an adder on 2 registers with :math:`n` qubits each, this plugin requires at
least :math:`n-1` clean auxiliary qubit.

The plugin supports the following plugin-specific options:

* ``num_clean_ancillas``: The number of clean auxiliary qubits available.
Nc                    [        U[        5      (       d  g UR                  nUS-
  UR                  SS5      :  a  g [	        USS9$ )NrJ   r   r   ri  rU  )rQ   r   r:  r   r>   rO  s          rZ   r[   HalfAdderSynthesisV95.runj  K    +];;,== a'++.BA"FF 0v>>r]   r^   r_   r`   r^   r]   rZ   rl  rl  \      
?r]   rl  c                  "    \ rS rSrSrSS jrSrg)rd  iw  zA ripple-carry adder with a carry-out bit with no ancillary qubits.

This plugin name is:``HalfAdder.ripple_r25`` which can be used as the key on an
:class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

Nc                \    [        U[        5      (       d  g UR                  n[        U5      $ r  )rQ   r   r:  r?   rO  s          rZ   r[   HalfAdderSynthesisR25.run  s+    +];;,== 011r]   r^   r_   r`   r^   r]   rZ   rd  rd  w  s    2r]   rd  c                  "    \ rS rSrSrSS jrSrg)HalfAdderSynthesisD00i  zA QFT-based adder with a carry-in and a carry-out bit.

This plugin name is:``HalfAdder.qft_d00`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                X    [        U[        5      (       d  g [        UR                  SSS9$ )Nri  Tr^  )rQ   r   r=   r:  r@  s         rZ   r[   HalfAdderSynthesisD00.run  s*    +];;.??fX\]]r]   r^   r_   r`   r^   r]   rZ   ru  ru    s    ^r]   ru  c                  "    \ rS rSrSrSS jrSrg)FullAdderSynthesisDefaulti  zA ripple-carry adder with a carry-in and a carry-out bit.

This plugin name is:``FullAdder.default`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                    [        U[        5      (       d  g UR                  S:X  a!  [        5       R                  " XX440 UD6nUb  U$ [        5       R                  " XX440 UD6$ )NrJ   )rQ   r   r:  FullAdderSynthesisV95r[   FullAdderSynthesisC04rR   s          rZ   r[   FullAdderSynthesisDefault.run  st    +];; --21377!CJM ($$$&**V
?F
 	
r]   r^   r_   r`   r^   r]   rZ   ry  ry    s    
r]   ry  c                  "    \ rS rSrSrSS jrSrg)r|  i  a	  A ripple-carry adder with a carry-in and a carry-out bit.

This plugin name is:``FullAdder.ripple_c04`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

This plugin requires no auxiliary qubits.
Nc                V    [        U[        5      (       d  g [        UR                  SS9$ )NfullrU  )rQ   r   r<   r:  r@  s         rZ   r[   FullAdderSynthesisC04.run  s'    +];; 1 B BPPr]   r^   r_   r`   r^   r]   rZ   r|  r|    s    Qr]   r|  c                  "    \ rS rSrSrSS jrSrg)r{  i  a  A ripple-carry adder with a carry-in and a carry-out bit.

This plugin name is:``FullAdder.ripple_v95`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

For an adder on 2 registers with :math:`n` qubits each, this plugin requires at
least :math:`n-1` clean auxiliary qubits.

The plugin supports the following plugin-specific options:

* ``num_clean_ancillas``: The number of clean auxiliary qubits available.
Nc                    [        U[        5      (       d  g UR                  nUS-
  UR                  SS5      :  a  g [	        USS9$ )NrJ   r   r   r  rU  )rQ   r   r:  r   r>   rO  s          rZ   r[   FullAdderSynthesisV95.run  ro  r]   r^   r_   r`   r^   r]   rZ   r{  r{    rp  r]   r{  c                  "    \ rS rSrSrSS jrSrg)MultiplierSynthesisH18i  zA cumulative multiplier based on controlled adders.

This plugin name is:``Multiplier.cumulative_h18`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                n    [        U[        5      (       d  g [        UR                  UR                  5      $ r  rQ   r   rB   r:  num_result_qubitsr@  s         rZ   r[   MultiplierSynthesisH18.run  s2    +^<<(..0A0S0S
 	
r]   r^   r_   r`   r^   r]   rZ   r  r        
r]   r  c                  "    \ rS rSrSrSS jrSrg)MultiplierSynthesisR17i  zA QFT-based multiplier.

This plugin name is:``Multiplier.qft_r17`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                n    [        U[        5      (       d  g [        UR                  UR                  5      $ r  )rQ   r   rA   r:  r  r@  s         rZ   r[   MultiplierSynthesisR17.run  s2    +^<<!..0A0S0S
 	
r]   r^   r_   r`   r^   r]   rZ   r  r    r  r]   r  c                  "    \ rS rSrSrSS jrSrg)MultiplierSynthesisDefaulti  zTHe default multiplier plugin.

This plugin name is:``Multiplier.default`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                n    [        U[        5      (       d  g [        UR                  UR                  5      $ r  r  r@  s         rZ   r[   MultiplierSynthesisDefault.run   s4    +^<< )..0A0S0S
 	
r]   r^   r_   r`   r^   r]   rZ   r  r    s    
r]   r  c                  "    \ rS rSrSrSS jrSrg)PauliEvolutionSynthesisDefaulti
  a  Synthesize a :class:`.PauliEvolutionGate` using the default synthesis algorithm.

This plugin name is:``PauliEvolution.default`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

The following plugin option can be set:

* preserve_order: If ``False``, allow re-ordering the Pauli terms in the Hamiltonian to
    reduce the circuit depth of the decomposition.

Nc                    [        U[        5      (       d  g UR                  nUR                  nSU;   a  [        U[        5      (       a
  US   Ul        UR                  U5      nXvl        U$ )Npreserve_order)rQ   r   	synthesisr  r:   
synthesize)	rS   rT   rU   rV   rW   rX   algooriginal_preserve_ordersynth_objects	            rZ   r[   "PauliEvolutionSynthesisDefault.run  sj    +-?@@  **"&"5"5w&:dN+K+K")*:";D'895r]   r^   r_   r`   r^   r]   rZ   r  r  
  s    
r]   r  c                  "    \ rS rSrSrSS jrSrg)PauliEvolutionSynthesisRustiqi'  u  Synthesize a :class:`.PauliEvolutionGate` using Rustiq.

This plugin name is :``PauliEvolution.rustiq`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

The Rustiq synthesis algorithm is described in [1], and is implemented in
Rust-based quantum circuit synthesis library available at
https://github.com/smartiel/rustiq-core.

On large circuits the plugin may take a significant runtime.

The plugin supports the following additional options:

* optimize_count (bool): if `True` the synthesis algorithm will try to optimize
    the 2-qubit gate count; and if `False` then the 2-qubit depth.
* preserve_order (bool): whether the order of paulis should be preserved, up to
    commutativity.
* upto_clifford (bool): if `True`, the final Clifford operator is not synthesized.
* upto_phase (bool): if `True`, the global phase of the returned circuit may
    differ from the global phase of the given pauli network.
* resynth_clifford_method (int): describes the strategy to synthesize the final
    Clifford operator. Allowed values are `0` (naive approach), `1` (qiskit
    greedy synthesis), `2` (rustiq isometry synthesis).

References:
    1. Timothée Goubault de Brugière and Simon Martiel,
       *Faster and shorter synthesis of Hamiltonian simulation circuits*,
       `arXiv:2404.03280 [quant-ph] <https://arxiv.org/abs/2404.03280>`_

Nc           
     "   [        U[        5      (       d  g SSKJnJn  [        UR
                  U5      (       a  UR
                  nO[        UR
                  U5      (       a  UR                  UR
                  5      nO[        UR
                  [        5      (       aY  / nUR
                   HF  n	[        X5      (       a"  UR                  UR                  U	5      5        M5  UR                  U	5        MH     O[        S5      e[        UUR                  UR                  UR                  S9n
U
R                  n[        U[        5      (       d  [        R                  " SS[         S9  g UR"                  nSU;   a
  US   Ul        U
R$                  nUR'                  U
5      nUR)                  S	S
5      nUR)                  SS
5      nUR)                  SS5      nUR)                  SS5      nUR)                  SS5      n[+        UUUUUUUS9nXl        U$ )Nr   )SparsePauliOpSparseObservablezInvalid PauliEvolutionGate.)timer'  r  zNCannot apply Rustiq if the evolution synthesis does not implement ``expand``. r   )
stacklevelcategoryr  optimize_countTupto_cliffordF
upto_phaseresynth_clifford_methodrJ   )rp   pauli_networkr  r  r  r  r  )rQ   r   qiskit.quantum_infor  r  operatorfrom_sparse_observablelistr%  rE   r  r'  r  r:   warningswarnRuntimeWarningr  rp   expandr   r;   )rS   rT   rU   rV   rW   rX   r  r  pauli_opopevor  r  rp   r  r  r  r  r  r  r  s                        rZ   r[   !PauliEvolutionSynthesisRustiq.runG  s   +-?@@ G '00-@@(11H)224DEE$;;<M<V<VWH)22D99H'00b33OOM$H$H$LMOOB'	 1 ""?@@ "''#))'11	
 }}$//MM`'
 "&"5"5w&")*:";D^^
C( %5t< %5t<OU;[[u5
")++.G"K1!'))'!$;
 6r]   r^   r_   r`   r^   r]   rZ   r  r  '  s    >Ar]   r  c                      \ rS rSrSrSS jr\SS j5       r\SS j5       r\SS j5       r\SS j5       r	\SS	 j5       r
\    SS
 j5       rSrg)AnnotatedSynthesisDefaulti  zSynthesize an :class:`.AnnotatedOperation` using the default synthesis algorithm.

This plugin name is:``annotated.default`` which can be used as the key on
an :class:`~.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.
Nc                   [        U[        5      (       d  g U R                  U5      n[        U[        5      (       d  U R                  U5      $ UnUR                  nUR                  SS 5      nUR                  SS 5      n	UR                  SS 5      n
U	b  U
c  [        S5      e[        [        / SQ-   5      n[        U	R                  U	R                  S S U	R                  U	R                  UU	R                  SU	R                  U	R                   S9n[#        S U 5       5      n[#        S	 U 5       5      n[#        S
 U 5       5      S-  nUR%                  5       nU
S U nXS  nUR'                  U5        US:w  d  U(       a  UR)                  U5        [+        UR,                  UUU5      nUc  U R                  UR,                  5      nO[.        R0                  " US   5      nUR)                  U5        U R3                  U5      nUc  U R5                  UUR                  5      nU$ Uu  nnn[/        UR6                  5      nUR9                  UUR:                  XR6                   SS9  UR9                  U R5                  UUR                  5      UR:                  SS9  UR9                  UUR:                  XR6                   SS9  U$ )Nqubit_trackerhls_datainput_qubitszVThe AnnotatedSynthesisDefault plugin should receive data and input_qubits via options.)r_  mcxqftr   )
hls_confighls_plugin_managerrU   rV   equivalence_libraryhls_op_namesdevice_instsuse_physical_indices
min_qubitsunroll_definitionsoptimize_clifford_tc              3  h   #    U  H(  n[        U[        5      (       d  M  UR                  v   M*     g 7fr  )rQ   r   r   .0mods     rZ   	<genexpr>0AnnotatedSynthesisDefault.run.<locals>.<genexpr>  s#     dis:cSbCc*s**i   22c              3  h   #    U  H(  n[        U[        5      (       d  M  UR                  v   M*     g 7fr  )rQ   r   powerr  s     rZ   r  r    s     U#jm6TICIIr  c              3  T   #    U  H  n[        U[        5      (       d  M  S v   M      g7f)rJ   N)rQ   r   r  s     rZ   r  r    s     UyJsO4T!!ys   (	(r   T)inplace)rQ   r   _canonicalize_op_instruction_to_circuit	modifiersr   rE   setrF   rI   r  r  r  r  r  r  r  sumr   disable	set_dirtyrH   base_opr   _from_circuit_data_conjugate_decomposition_apply_annotationsrp   composerW   )rS   rT   rU   rV   rW   rX   	operationr  trackerdatar  basisbase_synthesis_datanum_ctrlr  is_invertedannotated_trackercontrol_qubitsbase_qubitssynthesized_base_op_resultsynthesized_base_opconjugate_decompsynthesizedfrontmiddlebacks                             rZ   r[   AnnotatedSynthesisDefault.run  s    +-?@@ !112CD+-?@@//0ABB%	%//	
 ++ot4{{:t,{{>48<</!h $ 03NNO4#66 $ 8 8**!%!:!:#66 $ 8 8
 diddUUUUyUUXYY, $LLN%ix0"9-!!.1A:''4 &:{,?AR&
" &-"&">">y?P?P"Q"0"C"CD^_`Da"b+&  889LM# 112EyGZGZ[K"  %5!UFD()=)=>K{))(5I5IJTX    ''	0C0CD""   
 k((4H4HISW    r]   c           
     4   U GH  n[        U[        5      (       a  U R                  5       n M+  [        U[        5      (       Ga  U R                  S:  a  [        S5      e[        UR                  U R                  -   5      nU R                  S:w  ai  [        U R                  5      R                  UR                  SUR                  SS9n[        [        SUR                  5      5      nUR                  XE5        U  H  nUR                   nUR"                  nUR                  UR                  SUR                  SS9n[        [        SUR                  5      5      U V	s/ s H*  oR                  U R%                  U	5      R&                  -   PM,     sn	-   nUR                  XE5        M     Un [        U [(        5      (       a  [        S5      eGM  [        U[*        5      (       a  U R-                  UR,                  5      n GM  [        SU S35      e   U $ s  sn	f )	z)
Applies modifiers to a quantum circuit.
r   zHAnnotatedSynthesisDefault: cannot control a circuit with classical bits.NF)r   r'  r"  r_  zEAnnotatedSynthesisDefault: failed to synthesize the control modifier.z,AnnotatedSynthesisDefault: Unknown modifier .)rQ   r   r   r   
num_clbitsrE   r   r   rp   global_phaser   r&  r"  r  r(  r%  r  rW   find_bitindexr   r   r  )
r*  r  modifiercontrolled_circuitcontrolled_opcontrolled_qubitsinstinst_opinst_qubitsqs
             rZ   r  ,AnnotatedSynthesisDefault._apply_annotations	  s   
 "H(O44!//+Ho66%%))b 
 &4H4L4LwOaOa4a%b"''1,$3G4H4H$I$Q$Q(0(@(@"#+#6#6"'	 %R %M )-U1h6N6N-O(P%&--mO#D"nnG"&++K$+OO(0(@(@"#+#6#6"'	 %4 %M )-U1h6N6N-O(PVaTVaQR0073C3CA3F3L3LLVaT )% '--mO $ -g'9::)_  ;
 Hm44!--7 &(TU]T^^_&`aa] "` %Ts   1H
c                    [        U R                  U R                  5      nUR                  XR                  UR
                  5        U$ z0Wraps a single operation into a quantum circuit.r   rp   r  r%  rW   clbitsr  r*  s     rZ   r  1AnnotatedSynthesisDefault._instruction_to_circuitN	  3     !>r>>7>>:r]   c                    [        U R                  U R                  5      nUR                  XR                  UR
                  5        U$ r  r  r  s     rZ   r  r  U	  r  r]   c                2   U n/ n[        U[        5      (       a>  UR                  UR                  5        UR                  n[        U[        5      (       a  M>  / nUSSS2    H  nUR                  U5        M     [        U5      nU(       d  U$ [        X5      $ )zF
Combines recursive annotated operations and canonicalizes modifiers.
N)rQ   r   r%  r  r  extendr   )r  curall_modifiersnew_modifiersr  canonical_modifierss         rZ   r  *AnnotatedSynthesisDefault._canonicalize_op\	  s    
 011  /++C 011 &tt,I  + - 6mD"J!#;;r]   c                Z   SnU R                   UR                   :w  dF  U R                  UR                  :w  d,  [        U R                  5      [        UR                  5      :w  a  gU R                  nUR                  n[        U[        5      n[        U[        5      nU(       d  U(       d  X4R                  5       :H  nU$ U(       d0  U(       a)  UR                  [        5       /:X  a  X4R                  :H  nU$ U(       d/  U(       a(  UR                  [        5       /:X  a  UR                  U:H  nU$ )zA very naive function that checks whether two circuit instructions are inverse of
each other. The main use-case covered is a ``QFTGate`` and its inverse, represented as
an ``AnnotatedOperation`` with a single ``InverseModifier``.
F)rW   r  r   paramsr  rQ   r   r   r  r   r  )inst1inst2resop1op2ann1ann2s          rZ   _are_inverse_ops*AnnotatedSynthesisDefault._are_inverse_opss	  s      LLELL(||u||+5<< C$55oooo#12#12D&C 
 $3==_5F4G#G$C 
 $3==_5F4G#G++$C
r]   c                   U R                  5       nSnUS-
  n X#:  a  O-[        R                  X   X   5      (       a  US-  nUS-  nOOM3  US:X  a  gU R                  5       nSUl        [        SU5       H  nUR                  X   5        M     U R                  5       n[        X#S-   5       H  nUR                  X   5        M     U R                  5       nSUl        [        US-   U5       H  nUR                  X   5        M     XFU4$ )a  
Decomposes a circuit ``A`` into 3 sub-circuits ``P``, ``Q``, ``R`` such that
``A = P -- Q -- R`` and ``R = P^{-1}``.

This is accomplished by iteratively finding inverse nodes at the front and at the back of the
circuit.

The function returns ``None`` when ``P`` and ``R`` are empty.
r   rJ   N)sizer  r  copy_empty_liker  r(  r%  )r*  	num_gatesidxridxfront_circuitr   middle_circuitback_circuits           rZ   r  2AnnotatedSynthesisDefault._conjugate_decomposition	  s    LLN	1}{(99',VVq	  !8//1%&"q#A  ,  002s1H%A!!'*- &..0$%!tax+A
+ ,|<<r]   r^   r_   )r*  r   r  zlist[Modifier]returnr   )r  r   r%  r   )r  r   r%  r   )r  'CircuitInstruction'r  r&  )r*  r   r%  z<tuple[QuantumCircuit, QuantumCircuit, QuantumCircuit] | None)ra   rb   rc   rd   re   r[   staticmethodr  r  r  r  r  rf   r^   r]   rZ   r  r    s    CJ 4 4l     < <,  : (=(=	E(= (=r]   r  c                  "    \ rS rSrSrSS jrSrg)WeightedSumSynthesisDefaulti	  a}  Synthesize a :class:`.WeightedSumGate` using the default synthesis algorithm.

This plugin name is:``WeightedSum.default`` which can be used as the key on
an :class:`.HLSConfig` object to use this method with :class:`~.HighLevelSynthesis`.

.. note::

    This default plugin requires auxiliary qubits. There is currently no implementation
    available without auxiliary qubits.

Nc           	        [        U[        5      (       d  g UR                  S-
  [        UR                  S:  5      -   nUR	                  SS5      =ov:  a+  [
        R                  " SUR                   SU SU S35        g [        U5      $ )	NrJ   r   r   r   z'Cannot synthesize a WeightedSumGate on z state qubits with less than z clean auxiliary qubits. Only zG are available. This will likely lead to a error in HighLevelSynthesis.)	rQ   r   num_sum_qubitsintr   r  r  r:  r   )rS   rT   rU   rV   rW   rX   required_auxiliaries	num_cleans           rZ   r[   WeightedSumSynthesisDefault.run	  s    +_== ,,q037H7W7WZ[7[3\\ 	 !%91==IUMM9:K:\:\9] ^))=(>>\+df
 '(9::r]   r^   r_   r`   r^   r]   rZ   r)  r)  	  s    
;r]   r)  )re   
__future__r   r  numpyr   	rustworkxr   qiskit.circuit.quantumcircuitr   qiskit.circuit.operationr   qiskit.circuit.libraryr   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   "qiskit.circuit.annotated_operationr   r   r   r   r   r   qiskit.transpiler.couplingr   qiskit.synthesis.arithmeticr   r   r   qiskit.synthesis.cliffordr   r    r!   r"   r#   r$   qiskit.synthesis.linearr%   r&   r'   -qiskit.synthesis.linear.linear_circuits_utilsr(   qiskit.synthesis.permutationr)   r*   r+   qiskit.synthesis.qftr,   r-   !qiskit.synthesis.multi_controlledr.   r/   r0   r1   r2   r3   r4   r5   r6   r7   r8   r9   qiskit.synthesis.evolutionr:   r;   r<   r=   r>   r?   r@   rA   rB   qiskit.quantum_info.operatorsrC   +qiskit.transpiler.passes.routing.algorithmsrD   qiskit.transpiler.exceptionsrE   qiskit.circuit._add_controlrF   %qiskit.transpiler.optimization_metricrG   'qiskit._accelerate.high_level_synthesisrH   rI   pluginrK   rM   rh   rm   rs   ry   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  r5  r>  rC  rG  rK  rR  rY  rJ  rb  re  rl  rd  ru  ry  r|  r{  r  r  r  r  r  r  r)  r^   r]   rZ   <module>rG     s  pd #    8 .    "  3 
  
 L 
    R   3 O 8 D D ` ,7 (2  2 .6 "5 " 8 $%=  '!9 'T.!9 .b6   8  6  9/ 9x0/ 0fL'? L^24 2j(4 (V-4 -`'5 'T)5 )X'5 'T)5 )X3 :!3 !H 4  FG2 GTd3 d*#1 #8
2 
(
1 
 
$< 
&
": 


7 

'#; 'T37 3&R7 R2@7 @8_7 _/
 8 /
dQ4 Q2?4 ?624 2 ^4 ^
 8 
2Q4 Q ?4 ?6
5 
 
5 
 
!9 
"%= :a$< aHo= 8 o=d	;": ;r]   