
    z	i                        S r SSKJr  SSKJrJr  SSKJr  SSKJ	r	  SSK
JrJr  SSKJr  SSKJr  \(       a  SS	KJr  SS
KJr   " S S5      r\ " S S5      5       rg)z
A two-ways dict to represent a layout.

Layout is the relation between virtual (qu)bits and physical (qu)bits.
Virtual (qu)bits are tuples, e.g. `(QuantumRegister(3, 'qr'), 2)` or simply `qr[2]`.
Physical (qu)bits are integers.
    )annotations)ListTYPE_CHECKING)	dataclass)circuit)QubitQuantumRegister)LayoutErrorisinstanceint)
DAGCircuit)PropertySetc                      \ rS rSrSrSrS S jrS rS r\	S 5       r
S	 rS
 rS rS rS rS rS rS rS S jrS rS rS rS rS rS rS!S jr\	S 5       r\	S 5       r\	S 5       rS"S jrS#S jrS$S jr Sr!g)%Layout#   z$Two-ways dict to represent a Layout.)_regs_p2v_v2pNc                    / U l         0 U l        0 U l        Ub2  [        U[        5      (       d  [        S5      eU R                  U5        gg)zYconstruct a Layout from a bijective dictionary, mapping
virtual qubits to physical qubitsNzLayout constructor takes a dict)r   r   r   
isinstancedictr
   	from_dict)self
input_dicts     R/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/transpiler/layout.py__init__Layout.__init__(   sI     
		!j$//!"CDDNN:& "    c                    / nU R                   R                  5        H  u  p#UR                  U SU S35        M     U(       a  US   SS US'   SSR                  U5      -   S-   $ )zRepresentation of a Layoutz: ,Nz	Layout({

z
}))r   itemsappendjoin)r   str_listkeyvals       r   __repr__Layout.__repr__3   sg    		)HCOOse2cU!,- *#B<,HRLdii11F::r   c                    UR                  5        H=  u  p#[        R                  X#5      u  pEX@R                  U'   Uc  M/  XPR                  U'   M?     g)a<  Populates a Layout from a dictionary.

The dictionary must be a bijective mapping between
virtual qubits (tuple) and physical qubits (int).

Args:
    input_dict (dict):
        e.g.::

        {(QuantumRegister(3, 'qr'), 0): 0,
         (QuantumRegister(3, 'qr'), 1): 1,
         (QuantumRegister(3, 'qr'), 2): 2}

        Can be written more concisely as follows:

        * virtual to physical::

            {qr[0]: 0,
             qr[1]: 1,
             qr[2]: 2}

        * physical to virtual::

            {0: qr[0],
             1: qr[1],
             2: qr[2]}
N)r#   r   order_based_on_typer   r   )r   r   r'   valuevirtualphysicals         r   r   Layout.from_dict<   sL    8 %**,JC & : :3 FG")IIh!)IIg -r   c                J   [        U 5      (       a0  [        U[        [        S5      45      (       a  [	        U 5      nUnX24$ [        U5      (       a0  [        U [        [        S5      45      (       a  [	        U5      nU nX24$ [        S[        U 5       S[        U5       S35      e)zTdecides which one is physical/virtual based on the type. Returns (virtual, physical)Nz	The map (z -> z7) has to be a (Bit -> integer) or the other way around.)r   r   r   typeintr
   )value1value2r/   r.   s       r   r,   Layout.order_based_on_type_   s       ZT
8K%L%L6{HG    6""z&5$t*:M'N'N6{HG   	 DL>d6l^ <, , r   c                    XR                   ;   a  U R                   U   $ XR                  ;   a  U R                  U   $ [        SU S35      e)Nz	The item z does not exist in the Layout)r   r   KeyErrorr   items     r   __getitem__Layout.__getitem__o   sG    9999T?"9999T?"4&(EFGGr   c                H    XR                   ;   =(       d    XR                  ;   $ N)r   r   r9   s     r   __contains__Layout.__contains__v   s    yy 5DII$55r   c                T    [         R                  X5      u  p4U R                  X45        g r>   )r   r,   _set_type_checked_item)r   r'   r-   r.   r/   s        r   __setitem__Layout.__setitem__y   s#    "66sB##G6r   c                $   U R                   R                  US 5      nU R                  R                  US 5        U R                  R                  US 5      nU R                   R                  US 5        XR                  U'   Ub  X R                   U'   g g r>   )r   popr   )r   r.   r/   olds       r   rB   Layout._set_type_checked_item}   sq    iimmGT*		c4 iimmHd+		c4 %		(!)IIg r   c                &   [        U[        5      (       a(  U R                  U R                  U   	 U R                  U	 g [        U[        5      (       a(  U R                  U R                  U   	 U R                  U	 g [        S[        U5       S35      e)Nz>The key to remove should be of the form Qubit or integer) and z was provided)r   r3   r   r   r   r
   r2   )r   r'   s     r   __delitem__Layout.__delitem__   s}    c3		$))C.)		#U##		$))C.)		#**.s)MC r   c                ,    [        U R                  5      $ r>   )lenr   r   s    r   __len__Layout.__len__   s    499~r   c                    [        U[        5      (       a9  U R                  UR                  :H  =(       a    U R                  UR                  :H  $ g)NF)r   r   r   r   )r   others     r   __eq__Layout.__eq__   s7    eV$$99

*FtyyEJJ/FFr   c                    [        U 5      " 5       nU R                  R                  5       Ul        U R                  R                  5       Ul        U R                  R                  5       Ul        U$ )z$Returns a copy of a Layout instance.)r2   r   copyr   r   )r   layout_copys     r   rV   Layout.copy   sL    4jl JJOO-99>>+99>>+r   c                    Uc[  [        U R                  5      S:X  a  SnO?[        U R                  5      n[        U5       H  nX@R                  ;  d  M  Un  O   US-   nX U'   g)a  
Adds a map element between `bit` and `physical_bit`. If `physical_bit` is not
defined, `bit` will be mapped to a new physical bit.

Args:
    virtual_bit (tuple): A (qu)bit. For example, (QuantumRegister(3, 'qr'), 2).
    physical_bit (int): A physical bit. For example, 3.
Nr      )rM   r   maxrange)r   virtual_bitphysical_bitmax_physicalphysical_candidates        r   add
Layout.add   sb     499~" "499~*/*=&):'9 +> $0!#3L([r   c                |    U R                   R                  U5        U H  nX ;  d  M
  U R                  U5        M     g)zAdds at the end physical_qubits that map each bit in reg.

Args:
    reg (Register): A (qu)bit Register. For example, QuantumRegister(3, 'qr').
N)r   r$   ra   )r   regbits      r   add_registerLayout.add_register   s0     	

#C r   c                ,    [        U R                  5      $ )z
Returns the registers in the layout [QuantumRegister(2, 'qr0'), QuantumRegister(3, 'qr1')]
Returns:
    Set: A set of Registers in the layout
)setr   rN   s    r   get_registersLayout.get_registers   s     4::r   c                    U R                   $ )zb
Returns the dictionary where the keys are virtual (qu)bits and the
values are physical (qu)bits.
)r   rN   s    r   get_virtual_bitsLayout.get_virtual_bits       
 yyr   c                    U R                   $ )zb
Returns the dictionary where the keys are physical (qu)bits and the
values are virtual (qu)bits.
)r   rN   s    r   get_physical_bitsLayout.get_physical_bits   ro   r   c                d    [        U5      [        U5      La  [        S5      eX   nX   X'   X0U'   g)zSwaps the map between left and right.

Args:
    left (tuple or int): Item to swap with right.
    right (tuple or int): Item to swap with left.
Raises:
    LayoutError: If left and right have not the same type.
z:The method swap only works with elements of the same type.N)r2   r
   )r   leftrighttemps       r   swapLayout.swap   s7     :T%[(Z[[z[
Ur   c                    0 nU R                   R                  5        H%  u  p4XAR                  ;  a  [        S5      eX   X#'   M'     U$ )a  Combines self and another_layout into an "edge map".

For example::

      self       another_layout  resulting edge map
   qr_1 -> 0        0 <- q_2         qr_1 -> q_2
   qr_2 -> 2        2 <- q_1         qr_2 -> q_1
   qr_3 -> 3        3 <- q_0         qr_3 -> q_0

The edge map is used to compose dags via, for example, compose.

Args:
    another_layout (Layout): The other layout to combine.
Returns:
    dict: A "edge map".
Raises:
    LayoutError: another_layout can be bigger than self, but not smaller.
        Otherwise, raises.
zfThe wire_map_from_layouts() method does not support when the other layout (another_layout) is smaller.)r   r#   r   r
   )r   another_layoutedge_mapr.   r/   s        r   combine_into_edge_mapLayout.combine_into_edge_map   sT    ( !%!2G222!A  !/ 8H "3 r   c                \    S/[        U5      -  n[        U5       H  u  p4X   nXRU'   M     U$ )zGiven an ordered list of bits, reorder them according to this layout.

The list of bits must exactly match the virtual bits in this layout.

Args:
    bits (list[Bit]): the bits to reorder.

Returns:
    List: ordered bits.
r   )rM   	enumerate)r   bitsorderivjs         r   reorder_bitsLayout.reorder_bits  s:     c$i dODAA!H $ r   c                     [        5       nU  H<  n[        U[        5      (       a  UR                  U5        M+  UR	                  U5        M>     U$ )zCreates a trivial ("one-to-one") Layout with the registers and qubits in `regs`.

Args:
    *regs (Registers, Qubits): registers and qubits to include in the layout.
Returns:
    Layout: A layout with all the `regs` in the given order.
)r   r   r	   rf   ra   )regslayoutrd   s      r   generate_trivial_layoutLayout.generate_trivial_layout#  sB     C#//##C(

3	 
 r   c           	        [        S U  5       5      (       d  [        S5      e[        U 5      [        [        U 5      5      :w  a  [        S5      e[	        S U 5       5      n[        U 5      U:w  a  [        S[        U 5       SU SU  S35      e[        5       nS	nU H>  n[        UR                  5       H  nX   X5U   '   US
-  nM     UR                  U5        M@     U[        U 5      :w  a  XS  H  nSX7'   M	     U$ )ac  Converts a list of integers to a Layout
mapping virtual qubits (index of the list) to
physical qubits (the list values).

Args:
    int_list (list): A list of integers.
    *qregs (QuantumRegisters): The quantum registers to apply
        the layout to.
Returns:
    Layout: The corresponding Layout object.
Raises:
    LayoutError: Invalid input layout.
c              3  8   #    U  H  n[        U5      v   M     g 7fr>   r   ).0r   s     r   	<genexpr>&Layout.from_intlist.<locals>.<genexpr>C  s     6X=##X   zExpected a list of ints4Duplicate values not permitted; Layout is bijective.c              3  8   #    U  H  oR                   v   M     g 7fr>   )size)r   rd   s     r   r   r   G  s     3UcUr   zInteger list length (z*) must equal number of qubits in circuit (z): .r   rZ   N)	allr
   rM   ri   sumr   r\   r   rf   )int_listqregs
num_qubitsoutmain_idxqregidxint_items           r   from_intlistLayout.from_intlist4  s    6X666788x=CH..TUU3U33
x=J&'H 7)l#hZq:  hDTYY'!)!3IA ( T"	 
 s8}$$Y/ $ 0
r   c                    [        5       n[        U 5       HH  u  p4Uc  M
  [        U[        5      (       a   XBR                  ;   a  [        S5      eX2U'   M?  [        S5      e   U H  nUR                  U5        M     U$ )a[  
Populates a Layout from a list containing virtual
qubits, Qubit or None.

Args:
    qubit_list (list):
        e.g.: [qr[0], None, qr[2], qr[3]]
    *qregs (QuantumRegisters): The quantum registers to apply
        the layout to.
Returns:
    Layout: the corresponding Layout object
Raises:
    LayoutError: If the elements are not Qubit or None
r   z9The list should contain elements of the Bits or NoneTypes)r   r   r   r   r   r
   rf   )
qubit_listr   r   r/   r.   r   s         r   from_qubit_listLayout.from_qubit_listZ  sz      h!*:!6H'5))hh&%&\]]'G!"]^^ "7 DT" 
r   c           
         UR                  5       n[        U R                  R                  5        VVs0 s H  u  pEXCX%      _M     snn5      $ s  snnf )a  Compose this layout with another layout.

If this layout represents a mapping from the P-qubits to the positions of the Q-qubits,
and the other layout represents a mapping from the Q-qubits to the positions of
the R-qubits, then the composed layout represents a mapping from the P-qubits to the
positions of the R-qubits.

Args:
    other: The existing :class:`.Layout` to compose this :class:`.Layout` with.
    qubits: A list of :class:`.Qubit` objects over which ``other`` is defined,
        used to establish the correspondence between the positions of the ``other``
        qubits and the actual qubits.

Returns:
    A new layout object the represents this layout composed with the ``other`` layout.
)rm   r   r   r#   )r   rR   qubits	other_v2pvirtphyss         r   composeLayout.composex  sH    " **,	tyyGXYGXtv|44GXYZZYs   A
c           	         [        U5       VVs0 s H  u  p4XC_M	     nnn[        U R                  R                  5        VVs0 s H  u  pgX'   XV   _M     snn5      $ s  snnf s  snnf )a  Finds the inverse of this layout.

This is possible when the layout is a bijective mapping, however the input
and the output qubits may be different (in particular, this layout may be
the mapping from the extended-with-ancillas virtual qubits to physical qubits).
Thus, if this layout represents a mapping from the P-qubits to the positions
of the Q-qubits, the inverse layout represents a mapping from the Q-qubits
to the positions of the P-qubits.

Args:
    source_qubits: A list of :class:`.Qubit` objects representing the domain
        of the layout.
    target_qubits: A list of :class:`.Qubit` objects representing the image
        of the layout.

Returns:
    A new layout object the represents the inverse of this layout.
)r   r   r   r#   )r   source_qubitstarget_qubitspqsource_qubit_to_positionr   pos_physs           r   inverseLayout.inverse  sr    & 6?}5M#N5MTQAD5M #N '+iioo&7&7ND ')A)GG&7
 	
 $Os   AA#
c                r    S/[        U5      -  n[        U5       H  u  p4U R                  U   nX2U'   M     U$ )a  Creates a permutation corresponding to this layout.

This is possible when the layout is a bijective mapping with the same
source and target qubits (for instance, a "final_layout" corresponds
to a permutation of the physical circuit qubits). If this layout is
a mapping from qubits to their new positions, the resulting permutation
describes which qubits occupy the positions 0, 1, 2, etc. after
applying the permutation.

For example, suppose that the list of qubits is ``[qr_0, qr_1, qr_2]``,
and the layout maps ``qr_0`` to ``2``, ``qr_1`` to ``0``, and
``qr_2`` to ``1``. In terms of positions in ``qubits``, this maps ``0``
to ``2``, ``1`` to ``0`` and ``2`` to ``1``, with the corresponding
permutation being ``[1, 2, 0]``.
N)rM   r   r   )r   r   permr   r   poss         r   to_permutationLayout.to_permutation  s@    " vF#f%DA))A,CI & r   )r   r   r   r>   )returnz	list[int])rR   r   r   List[Qubit]r   r   )r   r   r   r   )r   r   )"__name__
__module____qualname____firstlineno____doc__	__slots__r   r)   r   staticmethodr,   r;   r?   rC   rB   rJ   rO   rS   rV   ra   rf   rj   rm   rq   rw   r|   r   r   r   r   r   r   r   __static_attributes__ r   r   r   r   #   s    .)I	';!*F ! !H67*
)2	@(    # #J  :[(
6r   r   c                      \ rS rSr% SrS\S'   S\S'   SrS\S	'   SrS
\S'   SrS\S'   SSS jjr	SSS jjr
SS jrSSS jjrSSS jjr\      SS j5       rSS jrSrg)TranspileLayouti  a+  Layout attributes for the output circuit from transpiler.

The :mod:`~qiskit.transpiler` is unitary-preserving up to the "initial layout"
and "final layout" permutations. The initial layout permutation is caused by
setting and applying the initial layout during the :ref:`transpiler-preset-stage-layout`.
The final layout permutation is caused by :class:`~.SwapGate` insertion during
the :ref:`transpiler-preset-stage-routing`. This class provides an interface to reason about
these permutations using a variety of helper methods.

During the layout stage, the transpiler can potentially remap the order of the
qubits in the circuit as it fits the circuit to the target backend. For example,
let the input circuit be:

.. plot::
   :alt: Circuit diagram output by the previous code.
   :include-source:

   from qiskit.circuit import QuantumCircuit, QuantumRegister

   qr = QuantumRegister(3, name="MyReg")
   qc = QuantumCircuit(qr)
   qc.h(0)
   qc.cx(0, 1)
   qc.cx(0, 2)
   qc.draw("mpl")


Suppose that during the layout stage the transpiler reorders the qubits to be:

.. plot::
   :alt: Circuit diagram output by the previous code.
   :include-source:

   from qiskit import QuantumCircuit

   qc = QuantumCircuit(3)
   qc.h(2)
   qc.cx(2, 1)
   qc.cx(2, 0)
   qc.draw("mpl")

Then the output of the :meth:`.initial_virtual_layout` method is
equivalent to::

    Layout({
        qr[0]: 2,
        qr[1]: 1,
        qr[2]: 0,
    })

(it is also this attribute in the :meth:`.QuantumCircuit.draw` and
:func:`.circuit_drawer` which is used to display the mapping of qubits to
positions in circuit visualizations post-transpilation).

Building on the above example, suppose that during the routing stage
the transpiler needs to insert swap gates, and the output circuit
becomes:

.. plot::
   :alt: Circuit diagram output by the previous code.
   :include-source:

   from qiskit import QuantumCircuit

   qc = QuantumCircuit(3)
   qc.h(2)
   qc.cx(2, 1)
   qc.swap(0, 1)
   qc.cx(2, 1)
   qc.draw("mpl")

Then the output of the :meth:`routing_permutation` method is::

    [1, 0, 2]

which maps positions of qubits before routing to their final positions
after routing.

There are three public attributes associated with the class, however these
are mostly provided for backwards compatibility and represent the internal
state from the transpiler. They are defined as:

  * :attr:`initial_layout` - This attribute is used to model the
    permutation caused by the :ref:`transpiler-preset-stage-layout`. It is a
    :class:`~.Layout` object that maps the input :class:`~.QuantumCircuit`\s
    :class:`~.circuit.Qubit` objects to the position in the output
    :class:`.QuantumCircuit.qubits` list.
  * :attr:`input_qubit_mapping` - This attribute is used to retain
    input ordering of the original :class:`~.QuantumCircuit` object. It
    maps the virtual :class:`~.circuit.Qubit` object from the original circuit
    (and :attr:`initial_layout`) to its corresponding position in
    :attr:`.QuantumCircuit.qubits` in the original circuit. This
    is needed when computing the permutation of the :class:`Operator` of
    the circuit (and used by :meth:`.Operator.from_circuit`).
  * :attr:`final_layout` - This attribute is used to model the
    permutation caused by the :ref:`transpiler-preset-stage-routing`. It is a
    :class:`~.Layout` object that maps the output circuit's qubits from
    :class:`.QuantumCircuit.qubits` in the output circuit to their final
    positions after routing. Importantly, this only represents the
    permutation caused by inserting :class:`~.SwapGate`\s into
    the :class:`~.QuantumCircuit` during the :ref:`transpiler-preset-stage-routing`.
    It is **not** a mapping from the original input circuit's position
    to the final position at the end of the transpiled circuit.
    If you need this, you can use the :meth:`.final_index_layout` to generate this.
    If :attr:`final_layout` is set to ``None``, this indicates that routing was not
    run, and can be considered equivalent to a trivial layout with the qubits from
    the output circuit's :attr:`~.QuantumCircuit.qubits` list.
r   initial_layoutzdict[circuit.Qubit, int]input_qubit_mappingNzLayout | Nonefinal_layoutz
int | None_input_qubit_countzList[Qubit] | None_output_qubit_listc                    U(       d  U R                   $ [        U R                   R                  5       R                  5        VVs0 s H&  u  p#U R                  U   U R
                  :  d  M$  X#_M(     snn5      $ s  snnf )ax  Return a :class:`.Layout` object for the initial layout.

This returns a mapping of virtual :class:`~.circuit.Qubit` objects in the input
circuit to the positions of the physical qubits selected during layout.
This is analogous to the :attr:`.initial_layout` attribute.

Args:
    filter_ancillas: If set to ``True`` only qubits in the input circuit
        will be in the returned layout. Any ancilla qubits added to the
        output circuit will be filtered from the returned object.
Returns:
    A layout object mapping the input circuit's :class:`~.circuit.Qubit`
    objects to the positions of the selected physical qubits.
)r   r   rm   r#   r   r   )r   filter_ancillaskr   s       r   initial_virtual_layout&TranspileLayout.initial_virtual_layout4  sy     &&& !//@@BHHJJDA++A.1H1HH J
 	
s   #A9
+A9
c                   U R                   R                  5       nU(       a  S/U R                  -  nOS/[        U5      -  nUR	                  5        H0  u  pEU R
                  U   nU(       a  X`R                  :  a  M,  XSU'   M2     U$ )a'  Generate an initial layout as an array of integers.

Args:
    filter_ancillas: If set to ``True`` any ancilla qubits added
        to the transpiler will not be included in the output.

Return:
    A layout array that maps a position in the array to its new position in the output
    circuit.
N)r   rm   r   rM   r#   r   )r   r   virtual_mapoutputr   r   r   s          r   initial_index_layout$TranspileLayout.initial_index_layoutM  s     ))::<Vd555FVc+..F%++-JD**40C3*A*A#A3K	 .
 r   c                    U R                   c'  [        [        [        U R                  5      5      5      $ U R                   R                  5       nU R                   Vs/ s H  o!U   PM	     sn$ s  snf )a  Generate a final layout as an array of integers.

If there is no :attr:`.final_layout` attribute present then that indicates
there was no output permutation caused by routing or other transpiler
transforms. In this case the function will return a list of ``[0, 1, 2, .., n]``.

Returns:
    A layout array that maps a position in the array to its new position in the output
    circuit.
)r   listr\   rM   r   rm   )r   r   r   s      r   routing_permutation#TranspileLayout.routing_permutatione  sb     $c$"9"9:;<<''88:.2.E.EF.EdD!.EFFFs   A.c           
        U R                   cJ  [        U R                   Vs/ s H(  n[        USS5      R	                  S5      (       d  M&  UPM*     sn5      nOU R                   nU R
                  c$  [        U R                  R                  5       5      nOU R
                  nU R                  R                  5        VVs0 s H  u  pVXe_M	     nnn/ nU(       a  Un	O[        U R
                  5      n	[        U	5       HC  n
U R                  Xz      nU R                  b  U R                  XK      nUR                  U5        ME     U$ s  snf s  snnf )aZ  Generate the final layout as an array of integers.

This method will generate an array of final positions for each qubit in the input circuit.
For example, if you had an input circuit like::

    qc = QuantumCircuit(3)
    qc.h(0)
    qc.cx(0, 1)
    qc.cx(0, 2)

and the output from the transpiler was::

    tqc = QuantumCircuit(3)
    tqc.h(2)
    tqc.cx(2, 1)
    tqc.swap(0, 1)
    tqc.cx(2, 1)

then the :meth:`.final_index_layout` method returns::

    [2, 0, 1]

This can be seen as follows. Qubit 0 in the original circuit is mapped to qubit 2
in the output circuit during the layout stage, which is mapped to qubit 2 during the
routing stage. Qubit 1 in the original circuit is mapped to qubit 1 in the output
circuit during the layout stage, which is mapped to qubit 0 during the routing
stage. Qubit 2 in the original circuit is mapped to qubit 0 in the output circuit
during the layout stage, which is mapped to qubit 1 during the routing stage.
The output list length will be as wide as the input circuit's number of qubits,
as the output list from this method is for tracking the permutation of qubits in the
original circuit caused by the transpiler.

Args:
    filter_ancillas: If set to ``False`` any ancillas allocated in the output circuit will be
        included in the layout.

Returns:
    A list of final positions for each input circuit qubit.
	_register ancilla)r   rM   r   getattr
startswithr   r   r   rm   r#   r\   r   r$   )r   r   xnum_source_qubitscircuit_qubitsr   r   pos_to_virtqubit_indicesr   index	qubit_idxs               r   final_index_layout"TranspileLayout.final_index_layoutu  s>   P ""* !$ "555q+r2==iH 5! !% 7 7""*!$"3"3"D"D"FGN!44N(,(@(@(F(F(HI(Hqt(HI*JT445J:&E++K,>?I  , --n.GH	  +	 '
 1 Js   %E
E>E	c                    U R                  US9nU R                  R                  5        VVs0 s H  u  p4XC_M	     nnn[        [	        U5       VVs0 s H
  u  pgXV   U_M     snn5      $ s  snnf s  snnf )a  Generate the final layout as a :class:`.Layout` object.

This method will generate an array of final positions for each qubit in the input circuit.
For example, if you had an input circuit like::

    qc = QuantumCircuit(3)
    qc.h(0)
    qc.cx(0, 1)
    qc.cx(0, 2)

and the output from the transpiler was::

    tqc = QuantumCircuit(3)
    tqc.h(2)
    tqc.cx(2, 1)
    tqc.swap(0, 1)
    tqc.cx(2, 1)

then the return from this function would be a layout object::

    Layout({
        qc.qubits[0]: 2,
        qc.qubits[1]: 0,
        qc.qubits[2]: 1,
    })

This can be seen as follows. Qubit 0 in the original circuit is mapped to qubit 2
in the output circuit during the layout stage, which is mapped to qubit 2 during the
routing stage. Qubit 1 in the original circuit is mapped to qubit 1 in the output
circuit during the layout stage, which is mapped to qubit 0 during the routing
stage. Qubit 2 in the original circuit is mapped to qubit 0 in the output circuit
during the layout stage, which is mapped to qubit 1 during the routing stage.
The output list length will be as wide as the input circuit's number of qubits,
as the output list from this method is for tracking the permutation of qubits in the
original circuit caused by the transpiler.

Args:
    filter_ancillas: If set to ``False`` any ancillas allocated in the output circuit will be
        included in the layout.

Returns:
    A layout object mapping to the final positions for each qubit.
)r   )r   r   r#   r   r   )r   r   resr   r   r   r   r   s           r   final_virtual_layout$TranspileLayout.final_virtual_layout  sr    X %%o%F(,(@(@(F(F(HI(Hqt(HI9S>R>KE{)4/>RSS JRs   A*A0
c           	     D  ^^^ US   mUS   nUS   mUS   nUS   n[        UR                  5      nTc  Uc  Uc  gTb  Uc  U " TTX5U5      $ Tc'  [        [        [	        UR                  5      5      5      mUc  [        T5      nUc'  [        [        [	        UR                  5      5      5      n[        TTR                  S9m[        UR                  5      nTSU  Vs/ s H  nXH   PM	     n	nU[        U	5      :  a$  U	R                  [        [        U	5      U5      5        S
UU4S jjn
SUU4S	 jjn[        U5       Vs/ s H  nU
" X" U5         5      PM     nn[        U5       Vs/ s H  oR                  X<   5      R                  PM!     nn[        U5       Vs/ s H
  nXU      PM     nn[        [	        U5       VVs0 s H  u  nnUUR                  U   _M     snn5      nU " TTX5[        UR                  5      5      $ s  snf s  snf s  snf s  snf s  snnf )a
  Construct the :class:`TranspileLayout` by reading out the fields from the given
:class:`.PropertySet`.  Returns ``None`` if there are no layout-setting keys present.

This includes combining the different keys of the property set into the full set of initial
and final layouts, including virtual permutations.

This does not invalidate or in any way mutate the given property set.  In order to
"canonicalize" the property set afterwards, call :meth:`write_into_property_set`.

This reads the following property-set keys:

``layout``
    **Required**. The :class:`.Layout` object mapping virtual qubits (potentially expanded
    with ancillas) to physical-qubit indices.  This corresponds directly to
    :attr:`initial_layout`.

    .. note::
        In all standard use, this is a required field.  However, if
        ``virtual_permutation_layout`` is set, then a "trivial" layout will be inferred,
        even if the circuit is not actually laid out to hardware.  This is an unfortunate
        limitation of this class's data model, where it is not possible to specify a final
        permutation without also having an initial layout. This deficiency will be corrected
        in Qiskit 3.0.

``original_qubit_indices``
    **Required** (but automatically set by the :class:`.PassManager`).  The mapping
    ``{virtual: index}`` that indicates which relative index each incoming virtual qubit
    was, in the input circuit.  This can be expanded with ancillas too (in which case the
    ancilla indices don't mean much, since they weren't in the incoming circuit).

``num_input_qubits``
    **Required** (but automatically set by the :class:`.PassManager`).  The number of
    explicit virtual qubits in the input circuit (i.e. not including implicit ancillas).

``final_layout``
    **Optional**.  The effective final permutation, in terms of the current qubits of the
    :class:`.DAGCircuit`.  This corresponds directly to :attr:`final_layout`.

``virtual_permutation_layout``
    **Optional**.  This is set by certain optimization passes that run before layout
    selection, such as :class:`.ElidePermutations`.  It is similar in spirit to
    ``final_layout``, but typically only applies to the input virtual qubits.

    .. warning::
        This object uses the opposite permutation convention to ``final_layout`` due to an
        oversight in Qiskit during its introduction.  In other words,
        ``virtual_permutation_layout`` maps a :class:`.Qubit` instance at the end of the
        circuit to its integer index at the start of the circuit.

Args:
    dag: the current state of the :class:`.DAGCircuit`.
    property_set: the current transpiler's property set.  This must at least have the
        ``layout`` key set.
r   r   original_qubit_indicesvirtual_permutation_layoutnum_input_qubitsN)r'   c                   > TTU       $ r>   r   )virtual_indexr   input_qubitss    r   relabel_virtual_to_physicalFTranspileLayout.from_property_set.<locals>.relabel_virtual_to_physicalw  s    !,}"=>>r   c                   > TTU       $ r>   r   )physical_indexr   input_qubit_indicess    r   relabel_physical_to_virtualFTranspileLayout.from_property_set.<locals>.relabel_physical_to_virtualz  s    &~n'EFFr   )r   r3   )r   r3   )r   r   r   r   r   sortedgetrM   extendr\   find_bitr   )clsdagproperty_setr   r   r   output_qubitsr   r]   undo_elided_on_virtualsr   r   r   undo_elided_on_physicalsundo_routing_on_physicalsundo_total_on_physicalsqubit_index	is_set_tor   r   r   s                     @@@r   from_property_set!TranspileLayout.from_property_set  s   t &h/#N3*+CD%12N%O"'(:;SZZ(!&@&H\Ma%*D*L  3\Ub  !#D3::)>$?@N%-)/0C)D&!$y'<"=>L17J7N7NO_
\  ,,=-=>#
> '3> 	  #
 344#**55L1Mz+Z[	? 	?	G 	G #(
"3	$
 #4 ('(CN(ST #4	 	! $
 TYYcSd%
SdLL56<<Sd 	" %

 #(
"3#
"3 %~%NO"3 	  #
  /88O.P.P*K SZZ	22.P
 /QUVYV`V`Qa
 	
_#
&$
%
#
s   HH*&HHH
c                <   S H  nUR                  US5        M     U R                  R                  5       US'   U R                  R                  5       US'   U R                  b  U R                  R                  5       US'   U R
                  b  U R
                  US'   gg)a;  'Unpack' this layout into the loose-constraints form of the ``property_set``.

This is the inverse method of :meth:`from_property_set`.

This always writes the follow property-set keys, overwriting them if they were already set:

``layout``
    Directly corresponds to :attr:`initial_layout`.

``original_qubit_indices``
    Directly corresponds to :attr:`input_qubit_mapping`.

``final_layout``
    Directly corresponds to :attr:`final_layout`.  Note that this might not be identical to
    the ``final_layout`` from before a call to :meth:`from_property_set`, because the
    effects of ``virtual_permutation_layout`` will have been combined into it.

``virtual_permutation_layout``
    Deleted from the property set; :class:`TranspileLayout` "finalizes" the multiple
    separate permutations into one single permutation, to retain the canonical form.

In addition, the following keys are updated, if this :class:`TranspileLayout` has a known
value for them.  They are left as-is if not, to handle cases where this class was manually
constructed without setting certain optional fields.

``num_input_qubits``
    The number of non-ancilla virtual qubits in the input circuit.

Args:
    property_set: the :class:`.PropertySet` (or general :class:`dict`) that the output
        should be written into.  This mutates the input in place.
)r   r   r   r   Nr   r   r   r   )rF   r   rV   r   r   r   )r   r  always_overwrites      r   write_into_property_set'TranspileLayout.write_into_property_set  s    B!
 -t4!
 "&!4!4!9!9!;X151I1I1N1N1P-.(+/+<+<+A+A+CL(""./3/F/FL+, /r   r   )F)r   boolr   r   )r   r  r   	List[int])r   r  )T)r  r   r  r   r   zTranspileLayout | None)r  zdict[str, object])r   r   r   r   r   __annotations__r   r   r   r   r   r   r   r   classmethodr
  r  r   r   r   r   r   r     s    kZ 11"&L-&%)
)-1*1
20G DL.T` s
s
,7s
	s
 s
j.Gr   r   N)r   
__future__r   typingr   r   dataclassesr   qiskitr   qiskit.circuitr   r	   qiskit.transpiler.exceptionsr
   qiskit.convertersr   qiskit.dagcircuitr   qiskit.transpilerr   r   r   r   r   r   <module>r     sV    # & !  1 4 +,-Y Yx OG OG OGr   