§
    º³ÙgM  ã                   óÂ   — 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 ddlmZ dd	lmZ dd
lmZmZmZ ddlmZ ddlmZ ddlmZmZmZ  G d„ de¦  «        ZdS )aj  
Given a template and a circuit: it applies template matching and substitutes
all compatible maximal matches that reduces the size of the circuit.

**Reference:**

[1] Iten, R., Moyard, R., Metger, T., Sutter, D. and Woerner, S., 2020.
Exact and practical pattern matching for quantum circuit optimization.
`arXiv:1909.05270 <https://arxiv.org/abs/1909.05270>`_
é    N)ÚQuantumCircuit)ÚDAGDependency)Úcircuit_to_dagdependency)Údagdependency_to_circuit)Údag_to_dagdependency)Údagdependency_to_dag)ÚTransformationPass)Útemplate_nct_2a_1Útemplate_nct_2a_2Útemplate_nct_2a_3)ÚOperator)ÚTranspilerError)ÚTemplateMatchingÚTemplateSubstitutionÚMaximalMatchesc                   ó2   ‡ — e Zd ZdZ	 	 	 	 dˆ fd„	Zd„ Zˆ xZS )ÚTemplateOptimizationz3
    Class for the template optimization pass.
    Nc                 óæ   •— t          ¦   «                              ¦   «          |€)t          ¦   «         t          ¦   «         t	          ¦   «         g}|| _        |�|ng | _        |�|ng | _        || _        dS )a‹  
        Args:
            template_list (list[QuantumCircuit()]): list of the different template circuit to apply.
            heuristics_backward_param (list[int]): [length, survivor] Those are the parameters for
                applying heuristics on the backward part of the algorithm. This part of the
                algorithm creates a tree of matching scenario. This tree grows exponentially. The
                heuristics evaluate which scenarios have the longest match and keep only those.
                The length is the interval in the tree for cutting it and survivor is the number
                of scenarios that are kept. We advise to use l=3 and s=1 to have serious time
                advantage. We remind that the heuristics implies losing a part of the maximal
                matches. Check reference for more details.
            heuristics_qubits_param (list[int]): [length] The heuristics for the qubit choice make
                guesses from the dag dependency of the circuit in order to limit the number of
                qubit configurations to explore. The length is the number of successors or not
                predecessors that will be explored in the dag dependency of the circuit, each
                qubits of the nodes are added to the set of authorized qubits. We advise to use
                length=1. Check reference for more details.
            user_cost_dict (Dict[str, int]): quantum cost dictionary passed to TemplateSubstitution
                to configure its behavior. This will override any default values if None
                is not given. The key is the name of the gate and the value its quantum cost.
        N)	ÚsuperÚ__init__r
   r   r   Útemplate_listÚheuristics_qubits_paramÚheuristics_backward_paramÚuser_cost_dict)Úselfr   r   r   r   Ú	__class__s        €úq/granary/edev/quantum/lib/python3.11/site-packages/qiskit/transpiler/passes/optimization/template_optimization.pyr   zTemplateOptimization.__init__/   sŠ   ø€ õ8 	‰Œ×ÒÑÔÐàÐ Ý.Ñ0Ô0Õ2CÑ2EÔ2EÕGXÑGZÔGZÐ[ˆMØ*ˆÔà'>Ð'JÐ#Ð#ÐPRð 	Ô$ð *CÐ)NÐ%Ð%ÐTVð 	Ô&ð -ˆÔÐÐó    c                 ó   — |}t          |¦  «        }| j        D �]Ô}t          |t          t          f¦  «        st          d¦  «        ‚t          |j        ¦  «        t          |j        ¦  «        k    rŒYt          j	        dt          |j        ¦  «        z  t          ¬¦  «        }	 t          |t          ¦  «        r"t          t          |¦  «        ¦  «        j        }nt          |¦  «        j        }t          j        ||¦  «        }|st          d¦  «        ‚n# t          $ r Y nw xY wt          |t          ¦  «        rt!          |¦  «        }n|}t#          ||| j        | j        ¦  «        }	|	                     ¦   «          |	j        }
|
rht-          |
¦  «        }|                     ¦   «          |j        }t3          ||	j        |	j        | j        ¦  «        }|                     ¦   «          |j        }�ŒÔ�ŒÖt?          |¦  «        }|S )a"  
        Args:
            dag(DAGCircuit): DAG circuit.
        Returns:
            DAGCircuit: optimized DAG circuit.
        Raises:
            TranspilerError: If the template has not the right form or
             if the output circuit acts differently as the input circuit.
        z1A template is a Quantumciruit or a DAGDependency.é   )Údtypez;A template is a Quantumciruit() that performs the identity.) r   r   Ú
isinstancer   r   r   ÚlenÚqubitsÚnpÚidentityÚcomplexr   r   ÚdataÚallcloseÚ	TypeErrorr   r   r   r   Úrun_template_matchingÚ
match_listr   Úrun_maximal_matchesÚmax_match_listr   Úcircuit_dag_depÚtemplate_dag_depr   Úrun_dag_optÚdag_dep_optimizedr   )r   ÚdagÚcircuit_dagr/   Útemplater&   r(   Ú
comparisonr0   Ú
template_mÚmatchesÚmaximalÚmax_matchesÚsubstitutions                 r   ÚrunzTemplateOptimization.runY   s  € ð ˆÝ.¨{Ñ;Ô;ˆàÔ*ð 6	ñ 6	ˆHÝ˜h­½Ð(GÑHÔHð [Ý%Ð&YÑZÔZÐZå�8”?Ñ#Ô#¥c¨/Ô*@Ñ&AÔ&AÒAÐAØå”{ 1­¨H¬OÑ(<Ô(<Ñ#<ÅGÐLÑLÔLˆHðÝ˜h­Ñ6Ô6ð 3Ý#Õ$<¸XÑ$FÔ$FÑGÔGÔL�D�Då# HÑ-Ô-Ô2�Dåœ[¨¨xÑ8Ô8�
à!ð Ý)ØUñô ð ðøõ ð ð ð Ø�ðøøøõ ˜(¥NÑ3Ô3ð ,Ý#;¸HÑ#EÔ#EÐ Ð à#+Ð å)ØØ ØÔ,ØÔ.ñ	ô ˆJð ×,Ò,Ñ.Ô.Ð.à Ô+ˆGàð Ý(¨Ñ1Ô1�Ø×+Ò+Ñ-Ô-Ð-Ø%Ô4�å3ØØÔ.ØÔ/ØÔ'ñ	 ô  �ð ×(Ò(Ñ*Ô*Ð*à".Ô"@�‘áÝ*¨?Ñ;Ô;ˆØÐs   Â#A1DÄ
D"Ä!D")NNNN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r<   Ú__classcell__)r   s   @r   r   r   *   sl   ø€ € € € € ðð ð Ø $Ø"&Øð(-ð (-ð (-ð (-ð (-ð (-ðTEð Eð Eð Eð Eð Eð Er   r   )r@   Únumpyr%   Úqiskit.circuit.quantumcircuitr   Úqiskit.dagcircuitr   Ú*qiskit.converters.circuit_to_dagdependencyr   Ú*qiskit.converters.dagdependency_to_circuitr   Ú&qiskit.converters.dag_to_dagdependencyr   Ú&qiskit.converters.dagdependency_to_dagr   Úqiskit.transpiler.basepassesr	   Ú qiskit.circuit.library.templatesr
   r   r   Ú&qiskit.quantum_info.operators.operatorr   Úqiskit.transpiler.exceptionsr   Ú7qiskit.transpiler.passes.optimization.template_matchingr   r   r   r   © r   r   ú<module>rO      sN  ðð	ð 	ð Ð Ð Ð à 8Ð 8Ð 8Ð 8Ð 8Ð 8Ø +Ð +Ð +Ð +Ð +Ð +Ø OÐ OÐ OÐ OÐ OÐ OØ OÐ OÐ OÐ OÐ OÐ OØ GÐ GÐ GÐ GÐ GÐ GØ GÐ GÐ GÐ GÐ GÐ GØ ;Ð ;Ð ;Ð ;Ð ;Ð ;Ø dÐ dÐ dÐ dÐ dÐ dÐ dÐ dÐ dÐ dØ ;Ð ;Ð ;Ð ;Ð ;Ð ;Ø 8Ð 8Ð 8Ð 8Ð 8Ð 8ðð ð ð ð ð ð ð ð ð ðtð tð tð tð tÐ-ñ tô tð tð tð tr   