
    z	i                     N    S r SSKJr  SSKJr  SSKJr  SSKJr   " S S\5      r	g)	zGAllocate all idle nodes from the coupling map as ancilla on the layout.    )QuantumRegister)AnalysisPassTranspilerError)Targetc                   B   ^  \ rS rSrSrU 4S jrS r\S 5       rSr	U =r
$ )FullAncillaAllocation   a  Allocate all idle nodes from the coupling map or target as ancilla on the layout.

A pass for allocating all idle physical qubits (those that exist in coupling
map or target but not the dag circuit) as ancilla. It will also choose new
virtual qubits to correspond to those physical ancilla.

Note:
    This is an analysis pass, and only responsible for choosing physical
    ancilla locations and their corresponding virtual qubits.
    A separate transformation pass must add those virtual qubits to the
    circuit.
c                    > [         TU ]  5         [        U[        5      (       a&  Xl        U R                  R                  5       U l        OSU l        Xl        SU l        g)zFullAncillaAllocation initializer.

Args:
    coupling_map (Union[CouplingMap, Target]): directed graph representing a coupling map.
Nancilla)super__init__
isinstancer   targetbuild_coupling_mapcoupling_mapancilla_name)selfr   	__class__s     q/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/transpiler/passes/layout/full_ancilla_allocation.pyr   FullAncillaAllocation.__init__#   sL     	lF++&K $ > > @DDK ,%    c                    U R                   R                  S5      nUc  [        S5      eUR                  5       nUR	                  5       nU(       aJ  [
        R                  U[        UR                  5      5        [        [        [        U5      S-   5      5      nO/ nU Vs/ s H  ofU;  d  M
  UPM     nnU R                  bN  U R                  R                  b7  [        U R                  R                  5       Vs/ s H  ofU;  d  M
  UPM     nnO>U R                  (       a-  U R                  R                   Vs/ s H  ofU;  d  M
  UPM     nnU(       a  U R                   UR"                  ;   a+  [$        R&                  " [)        U5      U R                   5      nO[%        [)        U5      U R                   S9n[+        U5       H  u  pX   U R                   S   U
'   M     U R                   S   R-                  U5        U$ s  snf s  snf s  snf )aF  Run the FullAncillaAllocation pass on `dag`.

Extend the layout with new (physical qubit, virtual qubit) pairs.
The dag signals which virtual qubits are already in the circuit.
This pass will allocate new virtual qubits such that no collision occurs
(i.e. Layout bijectivity is preserved)

The coupling_map and layout together determine which physical qubits are free.

Args:
    dag (DAGCircuit): circuit to analyze

Returns:
    DAGCircuit: returns the same dag circuit, unmodified

Raises:
    TranspilerError: If there is not layout in the property set or not set at init time.
layoutz;FullAncillaAllocation pass requires property_set["layout"].   )name)property_setgetr   get_virtual_bitsget_physical_bitsr	   validate_layoutsetqubitslistrangemaxr   
num_qubitsr   physical_qubitsr   qregsr   _new_with_prefixlen	enumerateadd_register)r   dagr   virtual_bitsphysical_bitslayout_physical_qubitsqidle_physical_qubitsqregidxidle_qs              r   runFullAncillaAllocation.run2   s   & ""&&x0>!"_``..0002!11,CJJP%)%M0BQ0F*G%H"%'"+A\+AamE[+A\;;"t{{'='='I !7!78$8a]<R8 ! $  ,,<<$<a@V< ! $    CII-&77,-t/@/@ 's+?'@tGXGXY()=>6:i!!(+F3  ?h'44T:
-  ]$$s$   !	H .H ;	HH:	H
H
c                 6    U  H  nX!;  d  M
  [        S5      e   g)z_
Checks if all the qregs in ``layout_qregs`` already exist in ``dag_qregs``. Otherwise, raise.
zSFullAncillaAllocation: The layout refers to a qubit that does not exist in circuit.Nr   )layout_qubits
dag_qubitsr4   s      r   r!   %FullAncillaAllocation.validate_layoutj   s&    
 "D%%6  "r   )r   r   r   )__name__
__module____qualname____firstlineno____doc__r   r7   staticmethodr!   __static_attributes____classcell__)r   s   @r   r	   r	      s'    &6p 	 	r   r	   N)
rA   qiskit.circuitr   qiskit.transpiler.basepassesr   qiskit.transpiler.exceptionsr   qiskit.transpiler.targetr   r	    r   r   <module>rJ      s%    N * 5 8 +_L _r   