§
    º³Ùg£?  ã                   óº   — d 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 ddlmZ ddlmZmZmZ dd	lmZ ej        j         G d
„ de¦  «        ¦   «         ZdS )z*Pass for Hoare logic circuit optimization.é    )ÚTransformationPass)ÚQuantumRegisterÚControlledGateÚGate)Ú
DAGCircuit)ÚUnitaryGate)Úmatrix_equal)ÚCircuitError)ÚCZGateÚCU1GateÚMCU1Gate)Ú	optionalsc                   ó|   ‡ — e Zd ZdZdˆ fd„	Zd„ Zd„ Zd„ Zd„ Zd„ Z	d	„ Z
d
„ Zdd„Zd„ Zd„ Zdd„Zd„ Zd„ Zd„ Zˆ xZS )ÚHoareOptimizerz›This is a transpiler pass using Hoare logic circuit optimization.
    The inner workings of this are detailed in:
    https://arxiv.org/abs/1810.00375
    é
   c                 ó¨   •— ddl m} t          ¦   «                              ¦   «          d| _        d| _        d| _        d| _        d| _        || _	        dS )z­
        Args:
            size (int): size of gate cache, in number of gates
        Raises:
            MissingOptionalLibraryError: if unable to import z3 solver
        é   )Ú_gate_extensionN)
Ú r   ÚsuperÚ__init__ÚsolverÚ	variablesÚgatenumÚ	gatecacheÚvarnumÚsize)Úselfr   r   Ú	__class__s      €úe/granary/edev/quantum/lib/python3.11/site-packages/qiskit/transpiler/passes/optimization/hoare_opt.pyr   zHoareOptimizer.__init__   s[   ø€ ð 	&Ð%Ð%Ð%Ð%Ð%å‰Œ×ÒÑÔÐØˆŒØˆŒØˆŒØˆŒØˆŒØˆŒ	ˆ	ˆ	ó    c                 ó  — ddl }dt          |¦  «        z   dz   t          | j        |         ¦  «        z   }|                     |¦  «        }| j        |xx         dz  cc<   | j        |                              |¦  «         |S )ap  After each gate generate a new unique variable name for each of the
            qubits, using scheme: 'q[id]_[gatenum]', e.g. q1_0 -> q1_1 -> q1_2,
                                                          q2_0 -> q2_1
        Args:
            qubit (Qubit): qubit to generate new variable for
        Returns:
            BoolRef: z3 variable of qubit state
        r   NÚqÚ_r   )Úz3Ústrr   ÚBoolr   Úappend)r   Úqubitr%   ÚvarnameÚvars        r    Ú_gen_variablezHoareOptimizer._gen_variable1   s…   € ð 	ˆ	ˆ	ˆ	à�˜E™
œ
Ñ" SÑ(­3¨t¬|¸EÔ/BÑ+CÔ+CÑCˆØ�gŠg�gÑÔˆØŒ�UÐÐÔ˜qÑ ÐÐÑØŒ�uÔ×$Ò$ SÑ)Ô)Ð)Øˆ
r!   c                 óö   — ddl }|j        D ]l}d| j        |<   g | j        |<   g | j        |<   i | j        |<   |                      |¦  «        }| j                             | 	                    |¦  «        ¦  «         ŒmdS )z•create boolean variables for each qubit and apply qb == 0 condition
        Args:
            dag (DAGCircuit): input DAG to get qubits from
        r   N)
r%   Úqubitsr   r   r   r   r,   r   ÚaddÚNot)r   Údagr%   ÚqbtÚxs        r    Ú_initializezHoareOptimizer._initializeB   sŒ   € ð
 	ˆ	ˆ	ˆ	à”:ð 	'ð 	'ˆCØ !ˆDŒL˜ÑØ"$ˆDŒN˜3ÑØ"$ˆDŒN˜3ÑØ!ˆDŒK˜ÑØ×"Ò" 3Ñ'Ô'ˆAØŒK�OŠO˜BŸFšF 1™IœIÑ&Ô&Ð&Ð&ð	'ð 	'r!   c           	      óÂ  — ddl }g }|D ]*}|                     |                      |¦  «        ¦  «         Œ+	 | j                             |                     | |j        ||z   Ž ¦  «        ¦  «         n# t          $ r Y nw xY wt          |¦  «        D ]P\  }}	| j                             |                     | 	                    |¦  «        ||         |	k    ¦  «        ¦  «         ŒQdS )a^  create boolean variables for each qubit the gate is applied to
            and apply the relevant post conditions.
            a gate rotating out of the z-basis will not have any valid
            post-conditions, in which case the qubit state is unknown
        Args:
            gate (Gate): gate to inspect
            ctrl_ones (BoolRef): z3 condition asserting all control qubits to 1
            trgtqb (list((QuantumRegister, int))): list of target qubits
            trgtvar (list(BoolRef)): z3 variables corresponding to latest state
                                     of target qubits
        r   N)
r%   r(   r,   r   r/   ÚImpliesÚ_postconditionsÚAttributeErrorÚ	enumerater0   )
r   ÚgateÚ	ctrl_onesÚtrgtqbÚtrgtvarr%   Únew_varsr2   ÚiÚtvars
             r    Ú_add_postconditionsz"HoareOptimizer._add_postconditionsQ   s  € ð 	ˆ	ˆ	ˆ	àˆØð 	5ð 	5ˆCØ�OŠO˜D×.Ò.¨sÑ3Ô3Ñ4Ô4Ð4Ð4ð	ØŒK�OŠO˜BŸJšJ yÐ2F°$Ô2FÈÐS[ÑI[Ð2]Ñ^Ô^Ñ_Ô_Ð_Ð_øÝð 	ð 	ð 	ØˆDð	øøøõ ! Ñ)Ô)ð 	Pð 	P‰GˆAˆtØŒK�OŠO˜BŸJšJ r§v¢v¨iÑ'8Ô'8¸(À1¼+ÈÒ:MÑNÔNÑOÔOÐOÐOð	Pð 	Ps   µ9A/ Á/
A<Á;A<c           	      ó0  — ddl }d}| j                             ¦   «          	  |j        |Ž }t	          |t
          ¦  «        �r|�rt          |¦  «        dk    rõ| j                             |                     | 	                    ||d         ¦  «        ¦  «        ¦  «         | j         
                    ¦   «         |j        k    }| j                             ¦   «          | j                             ¦   «          | j                             | 	                    ||d         ¦  «        ¦  «         | j         
                    ¦   «         |j        k    }|p|}n°| j                             | 	                    ||                     |¦  «        ¦  «        ¦  «         | j         
                    ¦   «         |j        k    }nL# t          $ r? | j                             |¦  «         | j         
                    ¦   «         |j        k    }Y nw xY w| j                             ¦   «          |S )a}  use z3 sat solver to determine triviality of gate
        Args:
            gate (Gate): gate to inspect
            ctrl_ones (BoolRef): z3 condition asserting all control qubits to 1
            trgtvar (list(BoolRef)): z3 variables corresponding to latest state
                                     of target qubits
        Returns:
            bool: if gate is trivial
        r   NFr   )r%   r   ÚpushÚ_trivial_ifÚ
isinstanceÚboolÚlenr/   r0   ÚAndÚcheckÚunsatÚpopr8   )	r   r:   r;   r=   r%   ÚtrivialÚ	triv_condÚsol1Úsol2s	            r    Ú
_test_gatezHoareOptimizer._test_gatek   sÔ  € ð 	ˆ	ˆ	ˆ	àˆØŒ×ÒÑÔÐð	:Ø(˜Ô(¨'Ð2ˆIõ
 ˜)¥TÑ*Ô*ñ :Øñ +¥ W¡¤°Ò!2Ð!2Ø”K—O’O B§F¢F¨2¯6ª6°)¸WÀQ¼ZÑ+HÔ+HÑ$IÔ$IÑJÔJÐJØœ;×,Ò,Ñ.Ô.°"´(Ò:�DØ”K—O’OÑ%Ô%Ð%Ø”K×$Ò$Ñ&Ô&Ð&Ø”K—O’O B§F¢F¨9°g¸a´jÑ$AÔ$AÑBÔBÐBØœ;×,Ò,Ñ.Ô.°"´(Ò:�DØ"˜l d�Gøà”—’ §¢ y°"·&²&¸Ñ2CÔ2CÑ DÔ DÑEÔEÐEØœ+×+Ò+Ñ-Ô-°´Ò9��øõ ð 	6ð 	6ð 	6ØŒK�OŠO˜IÑ&Ô&Ð&Ø”k×'Ò'Ñ)Ô)¨R¬XÒ5ˆGˆGˆGð	6øøøð" 	Œ�ŠÑÔÐØˆs   ¡
F1 Æ1AG:Ç9G:c                 ó˜  ‡	— d}t          |j        ¦  «        Š	t          ¦   «         }|                     ‰	¦  «         t	          t          t          |¦  «        |j        ¦  «        ¦  «        }t          |t          ¦  «        r|  	                    |¦  «        }t          |t          t          t          f¦  «        rf|sd|d         dk    rX|d         dz
  |d<   |d|d         …         ||d         dz   d…         z   |z   }|  	                    |¦  «        }|s|d         dk    °X|r)ˆ	fd„|D ¦   «         }|                     |j        |¦  «         |||fS )aµ  use z3 sat solver to determine if all control qubits are in 1 state,
             and if so replace the Controlled - U by U.
        Args:
            gate (Gate): gate to inspect
            ctrlvar (list(BoolRef)): z3 variables corresponding to latest state
                                     of control qubits
            trgtvar (list(BoolRef)): z3 variables corresponding to latest state
                                     of target qubits
        Returns:
            Tuple(bool, DAGCircuit, List)::
              * bool:if controlled gate can be replaced.
              * DAGCircuit: with U applied to the target qubits.
              * List: with indices of target qubits.
        Fr   r   Nc                 ó    •— g | ]
}‰|         ‘ŒS © rS   )Ú.0ÚqiÚqargs     €r    ú
<listcomp>z2HoareOptimizer._remove_control.<locals>.<listcomp>²   s   ø€ Ð,Ð,Ð, 2�d˜2”hÐ,Ð,Ð,r!   )r   Ú
num_qubitsr   Úadd_qregÚlistÚrangerG   rE   r   Ú_check_removalr   r   r   Úapply_operation_backÚ	base_gate)
r   r:   Úctrlvarr=   Úremover1   ÚqbÚ	ctrl_varsr.   rV   s
            @r    Ú_remove_controlzHoareOptimizer._remove_control�   sU  ø€ ð ˆå˜tœÑ/Ô/ˆÝ‰lŒlˆØ�Š�TÑÔÐå•%�˜G™œ d¤oÑ6Ô6Ñ7Ô7ˆå�d�NÑ+Ô+ð 	2Ø×(Ò(¨Ñ1Ô1ˆFõ �d�V¥W­hÐ7Ñ8Ô8ð 	8Øð 8  A¤¨¢ Ø˜1œ ™	��1‘Ø# G b¨¤e GÔ,¨w°r¸!´u¸q±y°{°{Ô/CÑCÀgÑM�	Ø×,Ò,¨YÑ7Ô7�ð ð 8  A¤¨¢ ð
 ð 	=Ø,Ð,Ð,Ð,¨Ð,Ñ,Ô,ˆFØ×$Ò$ T¤^°VÑ<Ô<Ð<à�s˜BˆÐr!   c                 ó$  — dd l } |j        |Ž }| j                             ¦   «          | j                             |                     |¦  «        ¦  «         | j                             ¦   «         |j        k    }| j                             ¦   «          |S )Nr   )	r%   rH   r   rC   r/   r0   rI   rJ   rK   )r   r_   r%   r;   r`   s        r    r\   zHoareOptimizer._check_removal·   s~   € Øˆ	ˆ	ˆ	à�B”F˜GÐ$ˆ	àŒ×ÒÑÔÐØŒ�Š˜Ÿš˜yÑ)Ô)Ñ*Ô*Ð*Ø”×"Ò"Ñ$Ô$¨¬Ò0ˆØŒ�ŠÑÔÐàˆr!   c                 ó†  — ddl }t          |                     ¦   «         ¦  «        }|D �]—}|j        }|                      |¦  «        \  }}}}	 |j        |Ž }
|                      |||	¦  «        \  }}}|ro|                     ||¦  «        }t          t          | 
                    ¦   «         ¦  «        ¦  «        }|j        }|                      |¦  «        \  }}}}	 |j        |Ž }
|                      ||
|	¦  «        }|r|                     |¦  «         n–| j        dk    r‹|j        D ]@}| j        |                              |¦  «         | j        |         dz
  | j        |         |<   ŒA|j        D ];}t'          | j        |         ¦  «        | j        k    r|                      ||¦  «         Œ<|                      ||
||	¦  «         �Œ™dS )aG  traverse DAG in topological order
            for each gate check: if any control is 0, or
                                 if triviality conditions are satisfied
            if yes remove gate from dag
            apply postconditions of gate
        Args:
            dag (DAGCircuit): input DAG to optimize in place
        r   Nr   )r%   rZ   Útopological_op_nodesÚopÚ_seperate_ctrl_trgtrH   rc   Úsubstitute_node_with_dagÚnextÚiterÚvaluesrP   Úremove_op_noder   Úqargsr   r(   r   r   rG   Ú_multigate_optrA   )r   r1   r%   ÚnodesÚnoder:   r$   r_   r<   r=   r;   Úremove_ctrlÚnew_dagÚmapped_nodesrL   r2   s                   r    Ú_traverse_dagzHoareOptimizer._traverse_dagÃ   só  € ð 	ˆ	ˆ	ˆ	õ �S×-Ò-Ñ/Ô/Ñ0Ô0ˆØð 	Gñ 	GˆDØ”7ˆDØ*.×*BÒ*BÀ4Ñ*HÔ*HÑ'ˆAˆw˜ à˜œ Ð(ˆIà&*×&:Ò&:¸4ÀÈ'Ñ&RÔ&RÑ#ˆK˜ !àð 	-ð  #×;Ò;¸DÀ'ÑJÔJ�Ý�D ×!4Ò!4Ñ!6Ô!6Ñ7Ô7Ñ8Ô8�Ø”w�Ø.2×.FÒ.FÀtÑ.LÔ.LÑ+��7˜F Gà"˜BœF GÐ,�	à—o’o d¨I°wÑ?Ô?ˆGØð 6Ø×"Ò" 4Ñ(Ô(Ð(Ð(Ø”˜Q’�Øœ:ð Cð C�CØ”N 3Ô'×.Ò.¨tÑ4Ô4Ð4Ø-1¬\¸#Ô->ÀÑ-B�D”K Ô$ TÑ*Ð*Øœ:ð 6ð 6�CÝ˜4œ>¨#Ô.Ñ/Ô/°4´9Ò<Ð<Ø×+Ò+¨C°Ñ5Ô5Ð5øà×$Ò$ T¨9°f¸gÑFÔFÐFÑFð=	Gð 	Gr!   Nc                 ó^  — d}|t          | j        |         ¦  «        dz
  k     �rˆd}| j        |         |         }| j        |         |dz            }|                      |¦  «        d         }|                      |¦  «        d         }	|dz  }||	k    rŒ�	 |D ]<}
| j        |
                              |¦  «        }| j        |
         |dz            |urd}Œ=n# t          t
          f$ r Y Œãw xY w||g}|r™|                      |¦  «        r„|                      |¦  «        ro|dz  }|D ]g}|                     |¦  «         |�$| j        |                              |¦  «        |k    r*|j	        D ]"}
| j        |
          
                    |¦  «         Œ#Œh|t          | j        |         ¦  «        dz
  k     �°†dS dS )aÝ  remove gates that have the same set of target qubits, follow each
            other immediately on these target qubits, and combine to the
            identity (consider sequences of length 2 for now)
        Args:
            dag (DAGCircuit): the directed acyclic graph to run on.
            qubit (Qubit): qubit cache to inspect
            from_idx (int): only gates whose indexes in the cache are larger
                            than this value can be removed
        r   r   Té   FN)rG   r   rh   ÚindexÚ
IndexErrorÚ
ValueErrorÚ_is_identityÚ_seq_as_onerm   rn   r`   )r   r1   r)   Úfrom_idxr?   r(   Únode1Únode2Útrgtqb1Útrgtqb2r2   ÚidxÚseqrq   s                 r    Ú_remove_successive_identityz*HoareOptimizer._remove_successive_identityñ   s   € ð ˆØ•#�d”n UÔ+Ñ,Ô,¨qÑ0Ò0Ñ0ØˆFØ”N 5Ô)¨!Ô,ˆEØ”N 5Ô)¨!¨a©%Ô0ˆEØ×.Ò.¨uÑ5Ô5°aÔ8ˆGØ×.Ò.¨uÑ5Ô5°aÔ8ˆGØ�‰FˆAà˜'Ò!Ð!ØðØ"ð 'ð '�CØœ.¨Ô-×3Ò3°EÑ:Ô:�CØ”~ cÔ*¨3°©7Ô3¸5Ð@Ð@Ø!&˜øð'øõ ¥
Ð+ð ð ð Ø�ðøøøð ˜%�.ˆCØð =˜$×+Ò+¨CÑ0Ô0ð =°T×5EÒ5EÀcÑ5JÔ5Jð =Ø�Q‘�Øð =ð =�DØ×&Ò& tÑ,Ô,Ð,ØÐ'¨4¬>¸%Ô+@×+FÒ+FÀtÑ+LÔ+LÈxÒ+WÐ+WØ#'¤:ð =ð =˜CØ œN¨3Ô/×6Ò6°tÑ<Ô<Ð<Ð<øð3 •#�d”n UÔ+Ñ,Ô,¨qÑ0Ò0Ñ0Ð0Ð0Ð0Ð0s   Â?C ÃC'Ã&C'c                 ó  — t          |¦  «        dk    sJ ‚	 |d         j        |d         j                             ¦   «         }}n# t          $ r Y dS w xY w|j        |j        }}|j        |j        }}t          |t          ¦  «        r|j        }|j	        }t          |t          ¦  «        r|j        }|j	        }|t          u r|t          u r
||k    o|o|S |t          u r'|t          u rt          |d         |d         d¬¦  «        S ||k    o||k    S )a  determine whether the sequence of gates combines to the identity
            (consider sequences of length 2 for now)
        Args:
            sequence (list(DAGOpNode)): gate sequence to inspect
        Returns:
            bool: if gate sequence combines to identity
        rw   r   r   FT)Úignore_phase)rG   rg   Úinverser
   ÚparamsÚ
definitionrE   r   r^   Ú
base_classr   r   r	   )r   ÚsequenceÚgate1Úgate2Úpar1Úpar2Údef1Údef2s           r    r{   zHoareOptimizer._is_identity  s/  € õ �8‰}Œ} Ò!Ð!Ð!Ð!ð	Ø# Aœ;œ>¨8°A¬;¬>×+AÒ+AÑ+CÔ+C�5ˆEˆEøÝð 	ð 	ð 	Ø�5�5ð	øøøà”\ 5¤<ˆdˆØÔ% uÔ'7ˆdˆå�e�^Ñ,Ô,ð 	$Ø”OˆEØÔ ˆÝ�e�^Ñ,Ô,ð 	$Ø”OˆEØÔ ˆð
 •Dˆ=ˆ=˜U¥d˜]˜]Ø˜4’<Ð1 DÐ1¨TÐ1Ø•kÐ!Ð! e­{Ð&:Ð&:Ý  Q¤¨¨a¬¸tÐDÑDÔDÐDà˜Š~Ð. $¨$¢,Ð.s   —,A Á
AÁAc                 ó$  — ddl m}m}m} ddl }t	          |¦  «        dk    sJ ‚|                      |d         ¦  «        d         }|                      |d         ¦  «        d         }| j                             ¦   «          | j                              | | ||Ž  | ||Ž ¦  «        ¦  «         | | ||Ž ¦  «         ||Ž ¦  «        ¦  «        ¦  «         | j         	                    ¦   «         |j
        k    }| j                             ¦   «          |S )a|  use z3 solver to determine if the gates in the sequence are either
            all executed or none of them are executed, based on control qubits
            (consider sequences of length 2 for now)
        Args:
            sequence (list(DAGOpNode)): gate sequence to inspect
        Returns:
            bool: if gate sequence is only executed completely or not at all
        r   )ÚOrrH   r0   Nrw   r   )r%   r“   rH   r0   rG   rh   r   rC   r/   rI   rJ   rK   )	r   r‹   r“   rH   r0   r%   Úctrlvar1Úctrlvar2Úress	            r    r|   zHoareOptimizer._seq_as_one9  s0  € ð 	$Ð#Ð#Ð#Ð#Ð#Ð#Ð#Ð#Ð#Øˆ	ˆ	ˆ	å�8‰}Œ} Ò!Ð!Ð!Ð!Ø×+Ò+¨H°Q¬KÑ8Ô8¸Ô;ˆØ×+Ò+¨H°Q¬KÑ8Ô8¸Ô;ˆàŒ×ÒÑÔÐØŒ�ŠØˆBˆsˆs�3�3˜�> 3 3 s s¨H ~Ñ#6Ô#6Ñ7Ô7¸¸¸S¸SÀÀÀhÀÑ=PÔ=PÐRUÐRUÐW_ÐR`Ñ9aÔ9aÑbÔbñ	
ô 	
ð 	
ð Œk×ÒÑ!Ô! R¤XÒ-ˆØŒ�ŠÑÔÐàˆ
r!   c                 ó\  ‡— | j         |         sdS |                      |||¦  «         t          | j         |         ¦  «        | j        k     r|€dS |€:d}t	          ¦   «         Š‰                     |¦  «         | j         |         d         g}n| j         |         |dd…         }|D ]h}ˆfd„|j        D ¦   «         }‰                     |¦  «         |D ];}| j         |                              |¦  «        }	|  	                    |||	‰¬¦  «         Œ<Œi| j         |         |dz   d…         | j         |<   dS )a  
        Args:
            dag (DAGCircuit): the directed acyclic graph to run on.
            qubit (Qubit): qubit whose gate cache is to be optimized
            max_idx (int): a value indicates a recursive call, optimize
                           and remove gates up to this point in the cache
            dnt_rec (list(int)): don't recurse on these qubit caches (again)
        Nr   éÿÿÿÿc                 ó   •— g | ]}|‰v¯|‘Œ	S rS   rS   )rT   r3   Údnt_recs     €r    rW   z1HoareOptimizer._multigate_opt.<locals>.<listcomp>o  s#   ø€ Ð@Ð@Ð@˜A¨q¸Ð/?Ð/?�aÐ/?Ð/?Ð/?r!   )Úmax_idxrš   r   )
r   r„   rG   r   Úsetr/   rn   Úupdaterx   ro   )
r   r1   r)   r›   rš   Ú	gates_tbrrq   Únew_qbr2   r‚   s
       `     r    ro   zHoareOptimizer._multigate_optR  sc  ø€ ð Œ~˜eÔ$ð 	ØˆFð 	×(Ò(¨¨e°WÑ=Ô=Ð=ÝˆtŒ~˜eÔ$Ñ%Ô%¨¬	Ò1Ð1°g°oàˆFØˆ_àˆGÝ‘e”eˆGØ�KŠK˜ÑÔÐØœ¨Ô.¨qÔ1Ð2ˆIˆIð œ uÔ-¨g¨k°r¨kÔ:ˆIàð 	Lð 	LˆDà@Ð@Ð@Ð@ ¤Ð@Ñ@Ô@ˆFØ�NŠN˜6Ñ"Ô"Ð"Øð Lð L�Ø”n SÔ)×/Ò/°Ñ5Ô5�à×#Ò# C¨°cÀ7Ð#ÑKÔKÐKÐKðLð
 !%¤¨uÔ 5°gÀ±k°m°mÔ DˆŒ�uÑÐÐr!   c                 ó2  ‡ ‡— ‰j         }t          |t          ¦  «        r|j        }nd}‰j        d|…         }‰j        |d…         }	 ˆˆ fd„|D ¦   «         }ˆˆ fd„|D ¦   «         }n,# t
          $ r ˆ fd„|D ¦   «         }ˆ fd„|D ¦   «         }Y nw xY w||||fS )zqGet the target qubits and control qubits if available,
        as well as their respective z3 variables.
        r   Nc                 óX   •— g | ]&}‰j         |         ‰j        |         ‰                  ‘Œ'S rS   ©r   r   ©rT   ra   rq   r   s     €€r    rW   z6HoareOptimizer._seperate_ctrl_trgt.<locals>.<listcomp>„  ó0   ø€ ÐRÐRÐRÀR�t”~ bÔ)¨$¬+°b¬/¸$Ô*?Ô@ÐRÐRÐRr!   c                 óX   •— g | ]&}‰j         |         ‰j        |         ‰                  ‘Œ'S rS   r¢   r£   s     €€r    rW   z6HoareOptimizer._seperate_ctrl_trgt.<locals>.<listcomp>…  r¤   r!   c                 ó6   •— g | ]}‰j         |         d          ‘ŒS ©r˜   ©r   ©rT   ra   r   s     €r    rW   z6HoareOptimizer._seperate_ctrl_trgt.<locals>.<listcomp>‡  ó%   ø€ Ð?Ð?Ð?°"�t”~ bÔ)¨"Ô-Ð?Ð?Ð?r!   c                 ó6   •— g | ]}‰j         |         d          ‘ŒS r§   r¨   r©   s     €r    rW   z6HoareOptimizer._seperate_ctrl_trgt.<locals>.<listcomp>ˆ  rª   r!   )rg   rE   r   Únum_ctrl_qubitsrn   ÚKeyError)r   rq   r:   ÚnumctrlÚctrlqbr<   r_   r=   s   ``      r    rh   z"HoareOptimizer._seperate_ctrl_trgtx  sô   øø€ ð ŒwˆÝ�d�NÑ+Ô+ð 	ØÔ*ˆGˆGàˆGØ”˜H˜W˜HÔ%ˆØ”˜G˜H˜HÔ%ˆð	@ØRÐRÐRÐRÐRÈ6ÐRÑRÔRˆGØRÐRÐRÐRÐRÈ6ÐRÑRÔRˆGˆGøÝð 	@ð 	@ð 	@Ø?Ð?Ð?Ð?¸Ð?Ñ?Ô?ˆGØ?Ð?Ð?Ð?¸Ð?Ñ?Ô?ˆGˆGˆGð	@øøøð ˜ ¨Ð1Ð1s   ÁA' Á'&BÂBc                 óx   — ddl }|                     ¦   «         | _        i | _        i | _        i | _        i | _        dS )zUReset HoareOptimize internal state,
        so it can be run multiple times.
        r   N)r%   ÚSolverr   r   r   r   r   )r   r%   s     r    Ú_resetzHoareOptimizer._reset‹  s<   € ð 	ˆ	ˆ	ˆ	à—i’i‘k”kˆŒØˆŒØˆŒØˆŒØˆŒˆˆr!   c                 óØ   — |                       ¦   «          |                      |¦  «         |                      |¦  «         | j        dk    r |j        D ]}|                      ||¦  «         Œ|S )z•
        Args:
            dag (DAGCircuit): the directed acyclic graph to run on.
        Returns:
            DAGCircuit: Transformed DAG.
        r   )r²   r4   ru   r   r.   ro   )r   r1   r2   s      r    ÚrunzHoareOptimizer.run—  ss   € ð 	�Š‰ŒˆØ×Ò˜ÑÔÐØ×Ò˜3ÑÔÐØŒ9�qŠ=ˆ=Ø”zð .ð .�Ø×#Ò# C¨Ñ-Ô-Ð-Ð-Øˆ
r!   )r   )N)NN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r,   r4   rA   rP   rc   r\   ru   r„   r{   r|   ro   rh   r²   r´   Ú__classcell__)r   s   @r    r   r      s3  ø€ € € € € ðð ð
ð ð ð ð ð ð$ð ð ð"'ð 'ð 'ðPð Pð Pð4#ð #ð #ðJ%ð %ð %ðN
ð 
ð 
ð,Gð ,Gð ,Gð\$=ð $=ð $=ð $=ðL /ð  /ð  /ðDð ð ð2$Eð $Eð $Eð $EðL2ð 2ð 2ð&
ð 
ð 
ðð ð ð ð ð ð r!   r   N)r¸   Úqiskit.transpiler.basepassesr   Úqiskit.circuitr   r   r   Úqiskit.dagcircuitr   Úqiskit.circuit.libraryr   Ú(qiskit.quantum_info.operators.predicatesr	   Úqiskit.circuit.exceptionsr
   Ú%qiskit.circuit.library.standard_gatesr   r   r   Úqiskit.utilsr   Ú
_optionalsÚHAS_Z3Úrequire_in_instancer   rS   r!   r    ú<module>rÅ      s  ðð 1Ð 0Ø ;Ð ;Ð ;Ð ;Ð ;Ð ;Ø @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ð @Ø (Ð (Ð (Ð (Ð (Ð (Ø .Ð .Ð .Ð .Ð .Ð .Ø AÐ AÐ AÐ AÐ AÐ AØ 2Ð 2Ð 2Ð 2Ð 2Ð 2Ø KÐ KÐ KÐ KÐ KÐ KÐ KÐ KÐ KÐ KØ 0Ð 0Ð 0Ð 0Ð 0Ð 0ð ÔÔ&ðKð Kð Kð Kð KÐ'ñ Kô Kñ 'Ô&ðKð Kð Kr!   