§
    º³Ùg-  ã                   óŽ   — d Z ddlZddlmZ ddlmZ ddlmZ ddlm	Z
 ddlmZ e
j        j         G d„ d	e¦  «        ¦   «         ZdS )
a  A pass for choosing a Layout of a circuit onto a Coupling graph, as a
Constraint Satisfaction Problem. It tries to find a solution that fully
satisfy the circuit, i.e. no further swap is needed. If no solution is
found, no ``property_set['layout']`` is set.
é    N)ÚLayout)ÚAnalysisPass)ÚTranspilerError)Ú	optionals)ÚTargetc                   ó2   ‡ — e Zd ZdZ	 	 	 	 dˆ fd„	Zd„ Zˆ xZS )	Ú	CSPLayoutz;If possible, chooses a Layout as a CSP, using backtracking.FNéè  é
   c                 ó  •— t          ¦   «                              ¦   «          t          |t          ¦  «        r&|| _        | j                             ¦   «         | _        nd| _        || _        || _        || _        || _	        || _
        dS )aë  If possible, chooses a Layout as a CSP, using backtracking.

        If not possible, does not set the layout property. In all the cases,
        the property `CSPLayout_stop_reason` will be added with one of the
        following values:

        * solution found: If a perfect layout was found.
        * nonexistent solution: If no perfect layout was found and every combination was checked.
        * call limit reached: If no perfect layout was found and the call limit was reached.
        * time limit reached: If no perfect layout was found and the time limit was reached.

        Args:
            coupling_map (Union[CouplingMap, Target]): Directed graph representing a coupling map.
            strict_direction (bool): If True, considers the direction of the coupling map.
                                     Default is False.
            seed (int): Sets the seed of the PRNG.
            call_limit (int): Amount of times that
                ``constraint.RecursiveBacktrackingSolver.recursiveBacktracking`` will be called.
                None means no call limit. Default: 1000.
            time_limit (int): Amount of seconds that the pass will try to find a solution.
                None means no time limit. Default: 10 seconds.
        N)ÚsuperÚ__init__Ú
isinstancer   ÚtargetÚbuild_coupling_mapÚcoupling_mapÚstrict_directionÚ
call_limitÚ
time_limitÚseed)Úselfr   r   r   r   r   Ú	__class__s         €ú`/granary/edev/quantum/lib/python3.11/site-packages/qiskit/transpiler/passes/layout/csp_layout.pyr   zCSPLayout.__init__   s}   ø€ õ< 	‰Œ×ÒÑÔÐÝ�l¥FÑ+Ô+ð 	-Ø&ˆDŒKØ $¤× >Ò >Ñ @Ô @ˆDÔÐàˆDŒKØ ,ˆDÔà 0ˆÔØ$ˆŒØ$ˆŒØˆŒ	ˆ	ˆ	ó    c                 ó¤  ‡‡— | j                              ¦   «         st          d¦  «        ‚|j        Št	          ¦   «         }ddlm}m}m} ddl	m
} |                     ¦   «         D ]U}|                     ‰                     |j        d         ¦  «        ‰                     |j        d         ¦  «        f¦  «         ŒVt	          | j                              ¦   «         ¦  «        Š| j        €| j        € |¦   «         }n || j        | j        ¬¦  «        }t%          t'          t)          ‰¦  «        ¦  «        ¦  «        }	t%          | j         j        ¦  «        }
t-          j        | j        ¦  «                             |
¦  «          ||¦  «        }|                     |	|
¦  «         |                      |¦   «         ¦  «         | j        rˆfd„}nˆfd	„}|D ]&}|                     ||d         |d         g¦  «         Œ'|                     ¦   «         }|€Fd
}t=          ||¦  «        r3|j        �|j        | j        k    rd}n�|j         �|j         | j        k    rd}nsd}tC          ˆfd„| "                    ¦   «         D ¦   «         ¦  «        | j#        d<   |j$         %                    ¦   «         D ]"}| j#        d          &                    |¦  «         Œ#|| j#        d<   dS )zrun the layout methodzSCoupling Map is disjoint, this pass can't be used with a disconnected coupling map.r   )ÚProblemÚAllDifferentConstraintÚRecursiveBacktrackingSolver)ÚCustomSolveré   N)r   r   c                 ó   •— | |f‰v S ©N© ©Úcontrolr   Úedgess     €r   Ú
constraintz!CSPLayout.run.<locals>.constraintj   s   ø€ Ø Ð(¨EÐ1Ð1r   c                 ó   •— | |f‰v p|| f‰v S r"   r#   r$   s     €r   r'   z!CSPLayout.run.<locals>.constrainto   s"   ø€ Ø Ð(¨EÐ1ÐO°f¸gÐ5FÈ%Ð5OÐOr   znonexistent solutionztime limit reachedzcall limit reachedzsolution foundc                 ó(   •— i | ]\  }}|‰|         “ŒS r#   r#   )Ú.0ÚkÚvÚqubitss      €r   ú
<dictcomp>z!CSPLayout.run.<locals>.<dictcomp>€   s#   ø€ Ð1\Ð1\Ð1\Á4À1Àa°!°V¸A´YÐ1\Ð1\Ð1\r   ÚlayoutÚCSPLayout_stop_reason)'r   Úis_connectedr   r-   Úsetr'   r   r   r   Ú2qiskit.transpiler.passes.layout._csp_custom_solverr   Útwo_qubit_opsÚaddÚindexÚqargsÚ	get_edgesr   r   ÚlistÚrangeÚlenÚphysical_qubitsÚrandomÚRandomr   ÚshuffleÚaddVariablesÚaddConstraintr   ÚgetSolutionr   Útime_currentÚcall_currentr   ÚitemsÚproperty_setÚqregsÚvaluesÚadd_register)r   ÚdagÚcxsr   r   r   r   ÚgateÚsolverÚ	variablesÚvariable_domainsÚproblemr'   ÚpairÚsolutionÚstop_reasonÚregr&   r-   s                    @@r   ÚrunzCSPLayout.runJ   s+  øø€ àÔ ×-Ò-Ñ/Ô/ð 	Ý!ðñô ð ð ”ˆÝ‰eŒeˆà[Ð[Ð[Ð[Ð[Ð[Ð[Ð[Ð[Ð[ØSÐSÐSÐSÐSÐSà×%Ò%Ñ'Ô'ð 	Pð 	PˆDØ�GŠG�V—\’\ $¤*¨Q¤-Ñ0Ô0°&·,²,¸t¼zÈ!¼}Ñ2MÔ2MÐNÑOÔOÐOÐOÝ�DÔ%×/Ò/Ñ1Ô1Ñ2Ô2ˆàŒ?Ð" t¤Ð'>Ø0Ð0Ñ2Ô2ˆFˆFà!�\¨T¬_ÈÌÐYÑYÔYˆFå��s 6™{œ{Ñ+Ô+Ñ,Ô,ˆ	Ý Ô 1Ô AÑBÔBÐÝŒ�d”iÑ Ô ×(Ò(Ð)9Ñ:Ô:Ð:à�'˜&‘/”/ˆØ×Ò˜YÐ(8Ñ9Ô9Ð9Ø×ÒÐ4Ð4Ñ6Ô6Ñ7Ô7Ð7àÔ ð 	Pð2ð 2ð 2ð 2ð 2ð 2ð
Pð Pð Pð Pð Pð ð 	Bð 	BˆDØ×!Ò! *¨t°A¬w¸¸Q¼Ð.@ÑAÔAÐAÐAà×&Ò&Ñ(Ô(ˆàÐØ0ˆKÝ˜& ,Ñ/Ô/ð 7ØÔ&Ð2°vÔ7JÈdÌoÒ7]Ð7]Ø"6�K�KØÔ(Ð4¸Ô9LÐPTÔP_Ò9_Ð9_Ø"6�Køà*ˆKÝ*0Ð1\Ð1\Ð1\Ð1\È8Ï>Ê>ÑK[ÔK[Ð1\Ñ1\Ô1\Ñ*]Ô*]ˆDÔ˜hÑ'Ø”y×'Ò'Ñ)Ô)ð >ð >�ØÔ! (Ô+×8Ò8¸Ñ=Ô=Ð=Ð=à5@ˆÔÐ1Ñ2Ð2Ð2r   )FNr
   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   rU   Ú__classcell__)r   s   @r   r	   r	      sh   ø€ € € € € àEÐEð
 ØØØð)ð )ð )ð )ð )ð )ðV:Að :Að :Að :Að :Að :Að :Ar   r	   )rY   r=   Úqiskit.transpiler.layoutr   Úqiskit.transpiler.basepassesr   Úqiskit.transpiler.exceptionsr   Úqiskit.utilsr   Ú
_optionalsÚqiskit.transpiler.targetr   ÚHAS_CONSTRAINTÚrequire_in_instancer	   r#   r   r   ú<module>rc      sÏ   ððð ð
 €€€à +Ð +Ð +Ð +Ð +Ð +Ø 5Ð 5Ð 5Ð 5Ð 5Ð 5Ø 8Ð 8Ð 8Ð 8Ð 8Ð 8Ø 0Ð 0Ð 0Ð 0Ð 0Ð 0Ø +Ð +Ð +Ð +Ð +Ð +ð ÔÔ.ðhAð hAð hAð hAð hA�ñ hAô hAñ /Ô.ðhAð hAð hAr   