
    z	ikb                        S r SSKrSSKJr  SSKJr  SSKrSSKJ	r	J
r
JrJrJrJrJrJrJrJrJr  SSKJrJrJr  SSKJr  SSKJrJrJr  SS	KJr  SS
K J!r!  SSK"J#r$  SSK%J&r&  S r'S S jr(S!S jr)S r*S r+S r,S"S jr-S r.S r/\$R`                  Rc                  S5      S 5       r2S r3      S#S jr4S r5S r6S r7Sq8 " S S\95      r:g)$z'Common circuit visualization utilities.    N)OrderedDict)warn)BoxOpClassicalRegisterClbitControlFlowOpControlledGateDelayGateInstructionMeasureQuantumCircuitQubit)AnnotatedOperationInverseModifierPowerModifier)condition_resources)PauliEvolutionGatePhaseOracleGateBitFlipOracleGate)pi_check)circuit_to_dag)	optionals   )VisualizationErrorc                 X    [        U[        [        45      =(       a    XR                  :H  $ N)
isinstancer   r   label)	gate_textops     ]/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/visualization/circuit/_utils.py_is_boolean_expressionr#   ,   s#    b?,=>?YIQYQYDYY    c           
         US:X  a  [        U [        5      (       a  gUS:X  a  [        U [        5      (       a  g/ nSn[        U [        5      (       a  U R                  (       a  U R                   Hv  n[        U[        5      (       a  UR                  S5        M+  [        U[        5      (       d  MB  UR                  S[        [        UR                  S5      5      -   S	-   5        Mx     S
R                  U5      n[        U SS5      n[        U 5      nS=n=p[        U S5      (       aA  U R                  R                  nU R                  R                   n	[        U R                  5      n
[        U S5      (       a  U R"                  R                  nSnU	(       a  U	nUnOAU(       a  [        U [$        5      (       a  UnUnO U(       a  UnOU(       a  UnOU R                  nX:X  a  U R                  OUnUS:w  a>  XS   ;   a6  US   U   S   S:X  a  US   U   S   S:X  a
  US   U   nGO/SUS   U    S3nGO!US:X  a  ['        X5      (       a)  UR)                  SS5      R)                  SS5      nSU S3nOXR                  :X  a  U[*        [,        4;  d  X:X  a.  U
[*        [,        4;  a  U[.        La  SUR1                  5        S3nO<SU S3nUR)                  SS5      nUR)                  SS5      nUR)                  SS 5      nSU S3nOMXR                  :X  a  U[*        [,        4;  d  X:X  a)  U
[*        [,        4;  a  U[.        La  UR1                  5       nU(       a  US!U-   -  nXU4$ )"zBLoad the gate_text and ctrl_text strings based on names and labelsmpl) r'   r'   text)zM-r'   r'   r'   InvzPow(   ), r   N	base_gatebase_opdisptexr   $z	$\mathrm{z}$latex~z$\neg$&z\&z	$\texttt{_\_^z\string^-z\mbox{-}z - )r   r   r   	modifiersr   appendr   strroundpowerjoingetattrtypehasattrr-   namer   r.   r	   r#   replacer   r   r   
capitalize)r!   drawerstyle	anno_list	anno_textmodifierop_labelop_type	base_name
base_label	base_type	ctrl_textr    raw_gate_texts                 r"   get_gate_ctrl_textrQ   0   s2    :b'22	6	jW55II"())bllH(O44  'Hm44  #eHNNA.F*G!G#!MN	 %
 IIi(	r7D)H2hG)--I-
r;LL%%	\\''
&	r9JJOO	I			j^44						GG	  )5BGG9M Iy)99 I&q)S0U95Ei5PQS5TX[5[i(3I%eI&6y&A%B#FI	7	!)00!))#y9AA#uMI%i[4I ''!gdK5H&H&9T;<O+O00%i&:&:&<%=SAI%i[4I!))#u5I!))#{;I!))#{;I!)C0	 
gg	'$1D"D"y{8K'K,,((*	UY&&	..r$   c           	         [        U S5      (       aB  [        S U R                   5       5      (       d!  [        S U R                   5       5      (       a  g[        U [        5      (       a!  U R                  S    SU R
                   S3/nOe/ n[        U R                  5       HJ  u  pEUS:X  a  US	:  d  US
:X  a  US:  a  UR                  S5          O UR                  [        XQUS95        ML     SnU(       a\  US:X  a  SSR                  U5       S3nU$ US
:X  a$  SR                  U5       R                  SS5      nU$ SSR                  U5       S3nU$ ! [         a    UR                  [        U5      5         M  f = f)z:Get the params as a string to add to the gate text displayparamsc              3   V   #    U  H  n[        U[        R                  5      v   M!     g 7fr   )r   npndarray.0params     r"   	<genexpr> get_param_str.<locals>.<genexpr>   s     D)z%,,)s   ')c              3   B   #    U  H  n[        U[        5      v   M     g 7fr   )r   r   rW   s     r"   rZ   r[      s     HiUz%00is   r'   r   []r2      r&      z...)outputndigitsz\,(\mathrm{,z})r,   r8   z$-$(r+   )rA   anyrS   r   r
   unit	enumerater:   r   	TypeErrorr;   r>   rC   )r!   rE   rb   
param_listcountrY   	param_strs          r"   get_param_strrl      sr    B!!D"))DDDHbiiHHH"e1ay23

%bii0LE '!eaiVu_QS!!%(.!!(5"QR 1 IW(*)=(>cBI  u_99Z01::3FI  CHHZ013I  .!!#e*-.s   E$E?>E?c                     SnSn0 nU HX  n[        X5      nUb  [        U[        5      (       a  U(       d  XEU'   US-  nM8  Uc  M=  U(       d  MF  Xs:w  d  MM  UnXEU'   US-  nMZ     U$ )a  Map the bits and registers to the index from the top of the drawing.
The key to the dict is either the (Qubit, Clbit) or if cregbundle True,
the register that is being bundled.

Args:
    circuit (QuantumCircuit): the circuit being drawn
    bits (list(Qubit, Clbit)): the Qubit's and Clbit's in the circuit
    cregbundle (bool): if True bundle classical registers. Default: ``True``.

Returns:
    dict((Qubit, Clbit, ClassicalRegister): index): map of bits/registers
        to index
Nr   r*   )get_bit_registerr   r   )circuitbits
cregbundleprev_reg
wire_indexwire_mapbitregisters           r"   get_wire_maprw      sw     HJH#G1:c5#9#9&SM!OJ!jjX5IH!+X!OJ  Or$   c                 n    U R                  U5      nUR                  (       a  UR                  S   S   $ S$ )zGet the register for a bit if there is one

Args:
    circuit (QuantumCircuit): the circuit being drawn
    bit (Qubit, Clbit): the bit to use to find the register and indexes

Returns:
    ClassicalRegister: register associated with the bit
r   N)find_bit	registers)ro   ru   bit_locs      r"   rn   rn      s7     s#G&-&7&77Q"ATAr$   c                     U R                  U5      nUR                  nUR                  (       a  UR                  S   OSu  pEXCU4$ )a  Get the register for a bit if there is one, and the index of the bit
from the top of the circuit, or the index of the bit within a register.

Args:
    circuit (QuantumCircuit): the circuit being drawn
    bit (Qubit, Clbit): the bit to use to find the register and indexes

Returns:
    (ClassicalRegister, None): register associated with the bit
    int: index of the bit from the top of the circuit
    int: index of the bit within the register, if there is a register
r   )NN)ry   indexrz   )ro   ru   r{   	bit_indexrv   	reg_indexs         r"   get_bit_reg_indexr      sE     s#GI292C2C'++A.H	))r$   c                   ^
 U S:X  a  U OSU S3nUc  UnU$ U S:X  a  UR                    nUR                    SU 3nO!S[        UR                   5       S3nU SU S3n[        U[        5      (       a;  U(       a  U S:w  a  UR                    nU$ UR                  S:X  d  U(       a  UnU$ UnU$ UR                  S:X  a  UnU$ Uc  UnU$ X2   (       a  X2   m
 [        U
4S	 jUR                  5        5       5      n	U S:X  a'  U	R                    SU	SS R                  T
5       S
U 3nO)SU	R                    SU	SS R                  T
5       SU S3n U S:w  a  UR                  SS5      nU$ UnU$ ! [         a    T
R                  bd  T
R                  n	U S:X  a(  U	R                    SU	SS R                  T
5       S
U 3n NoSU	R                    SU	SS R                  T
5       SU S3n NU S:X  a	  U S
U 3n NU SU S3n Nf = f)a  Get the bit labels to display to the left of the wires.

Args:
    drawer (str): which drawer is calling ("text", "mpl", or "latex")
    register (QuantumRegister or ClassicalRegister): get wire_label for this register
    index (int): index of bit in register
    layout (Layout): Optional. mapping of virtual to physical bits
    cregbundle (bool): Optional. if set True bundle classical registers.
        Default: ``True``.

Returns:
    str: label to display for the register/index
r(   {}Nr5   z_{r2   r*   c              3   8   >#    U  H  nTU;   d  M  Uv   M     g 7fr    )rX   regvirt_bits     r"   rZ   !get_wire_label.<locals>.<genexpr>  s     U+ACXQT_CC+A   
	z -> z}_{z} \mapsto {z
 \mapsto { \;)rB   fix_special_charactersr   r   sizenextget_registersr}   StopIteration	_registerrC   )rE   rv   r}   layoutrq   	index_str
wire_labelreg_namereg_name_indexvirt_regr   s             @r"   get_wire_labelr      s    %.5'brNI
mm_$MM?!E73.x}}=>bA$:Sr2 (-..&G+$MM?J==A!J  (J }}
D C 
#
@ ? 
=	EU6+?+?+AUUH (a0A0A(0K/LDQVPWX
 uXa[->->x-H,IX]W^^`a & V#++C7J  
+  	E!!-#--V#$,MM?!HQK4E4Eh4O3PPTUZT[!\J X]]O ,%a[..x89 :&&+WB0  V#$-;d5'!:J$-;l5'!DJ	Es,   AE. '(E. .AH?(H)H8HHc                    [        [        U S   [        5      5      n[        U S   5      n[        U S   [        5      (       a,  U(       d%  [        USU S   R                   S3 5      SSS2   nO[        [        U5      5      nSnU(       a;  U(       a4  [        XS   5      u  pxn	Ub  UR                   SU	 S	[        U5       3nXe4$ U(       d  [        U5      nXe4$ )
ay  Get the label and value list to display a condition

Args:
    condition (Union[Clbit, ClassicalRegister], int): classical condition
    circuit (QuantumCircuit): the circuit that is being drawn
    cregbundle (bool): if set True bundle classical registers

Returns:
    str: label to display for the condition
    list(str): list of 1's and 0's indicating values of condition
r   r*   0bNr1   r'   r5   =)boolr   r   intr   listr   r;   r   rB   hex)
	conditionro   rq   cond_is_bitcond_valval_bitsr   rv   r5   r   s
             r"   get_condition_label_valr   8  s     z)A,67K9Q< H )A, 122:8Ail&7&7%8#9:<TrTBH&Ez!27aL!IY}}oQyk3x=/BE ? H?r$   c                 J    U R                  SS5      R                  SS5      n U $ )z
Convert any special characters for mpl and latex drawers.
Currently only checks for multiple underscores in register names
and uses wider space for mpl and latex drawers.

Args:
    label (str): the label to fix

Returns:
    str: label to display
r5   r6   r   r   )rC   )r   s    r"   r   r   Y  s&     MM#u%--c59ELr$   z*the latex and latex_source circuit drawersc                    SSK Jn  [        R                  " S5      nUR	                  U 5      nU(       d  U R                  SS5      n U" U SS9nO|UR                  S5      R                  SS5      nU S	UR                  5        nUR                  SS5      nXR                  5       S	 nUR                  SS5      nU" USS9U-   U" USS9-   nUR                  S
S5      $ )z(Convert a label to a valid latex string.r   )utf8tolatexz(?<!\\)\$(.*)(?<!\\)\$z\$r0   T)non_ascii_onlyr*   Nr   z\,)	pylatexenc.latexencoder   recompilesearchrC   groupstartend)r   r   regexmatch	final_strmathmode_stringbefore_matchafter_matchs           r"   generate_latex_labelr   i  s     3JJ01ELLEeS)d;	++a.00<_u{{}-#++E37IIKM*!))%5T:+d;< 	
 S%((r$   c                     [        U [        5      (       a  U R                  5       n U c  Sn U S;  a  [        SU  S3[        S5        Sn U $ )z9Returns a valid `justify` argument, warning if necessary.left)r   rightnoneuJ   Setting QuantumCircuit.draw()’s or circuit_drawer()'s justify argument: z, to a value other than 'left', 'right', 'none' or None (='left'). Default 'left' will be used. Support for invalid justify arguments is deprecated as of Qiskit 1.2.0. Starting no earlier than 3 months after the release date, invalid arguments will error.r   )r   r;   lowerr   DeprecationWarning)justifys    r"   _get_valid_justify_argr     s_    '3--///XY`Xa bZ Z 	
 Nr$   c                 >  ^ [        U5      nUb+  U Vs/ s H  n[        U[        5      (       d  M  UPM     snmOU R                  R	                  5       mU R
                  R	                  5       n/ n	[        U V
s/ s H  oS4PM     sn
5      nU(       a  Ub  [        S5      eU(       a!  TR                  5         UR                  5         OXUbU  / n/ nU HG  nU[        T5      :  a  UR                  TU   5        M(  UR                  X[        T5      -
     5        MI     UmUn[        U 5      nUS:X  a*  UR                  5        H  nU	R                  U/5        M     O[        UTXX5      n	U(       dH  UR                  SS/S9 H3  nUT;   a  TR                  U5        UU;   d  M"  UR                  U5        M5     U	 VVs/ s H<  nU Vs/ s H+  n[!        U4S jUR"                   5       5      (       d  M)  UPM-     snPM>     n	nnTX4$ s  snf s  sn
f s  snf s  snnf )aZ  
Given a circuit, return a tuple (qubits, clbits, nodes) where
qubits and clbits are the quantum and classical registers
in order (based on reverse_bits or wire_order) and nodes
is a list of DAGOpNodes.

Args:
    circuit (QuantumCircuit): From where the information is extracted.
    reverse_bits (bool): If true the order of the bits in the registers is
        reversed.
    justify (str) : `left`, `right` or `none`. Defaults to `left`. Says how
        the circuit should be justified. If an invalid value is provided,
        default `left` will be used.
    idle_wires (bool): Include idle wires. Default is True.
    wire_order (list): A list of ints that modifies the order of the bits.

Returns:
    Tuple(list,list,list): To be consumed by the visualizer directly.

Raises:
    VisualizationError: if both reverse_bits and wire_order are entered.
r1   z@Cannot set both reverse_bits and wire_order in the same drawing.r   barrierdelay)ignorec              3   ,   >#    U  H	  oT;   v   M     g 7fr   r   )rX   qqubitss     r"   rZ   ,_get_layered_instructions.<locals>.<genexpr>  s     +LAKs   )r   r   r   r   copyclbitsr   r   reverselenr:   r   topological_op_nodes_LayerSpooler
idle_wiresremovere   qargs)ro   reverse_bitsr   r   
wire_orderrt   measure_arrowsru   r   nodescmeasure_map
new_qubits
new_clbitsdagnodewirelayerr   s                     @r"   _get_layered_instructionsr     s   > %W-G!)D#ZU-C#D$$&^^  "FE
 712w78K
. !cdd		

CS[ !!&+.!!&s6{):";<	 
 

!C&,,.DLL$  / c66KX NN9g*>N?Dv~d#v~d#	 @ \aa[`RWuMut+L+L(LduM[`Ea6  _ E 8H Nas.   H
H
:H 
H
(H6H<HHc                 L    U S   R                  5       nUR                  S S9  U$ )zJConvert DAG layer into list of nodes sorted by node_id
qiskit-terra #2802
graphc                     U R                   $ r   )_node_id)nds    r"   <lambda>_sorted_nodes.<locals>.<lambda>  s    bkkr$   )key)op_nodessort)	dag_layerr   s     r"   _sorted_nodesr     s+     g'')E	JJ)J*Lr$   c                    [        U 5      nSnUR                   H$  nU R                  U5      nXc:  a  UnXd:  d  M"  UnM&     [        UR                  [
        5      (       a#  [        UR                  [        5      (       d  U nU$ UR                  (       aQ  U(       a  [        UR                  [        5      (       d  [        UR                  SS5      (       a  X[        U 5       nU$ XUS-    nU$ )zHGet the list of qubits drawing this gate would cover
qiskit-terra #2802
r   r   Nr*   )
r   r   r}   r   r!   r   r   cargsr   r?   )r   r   r   	min_index	max_indexqregr}   spans           r"   _get_gate_spanr     s     FII

T"II  $''=))*TWWe2L2L  K 
	Jtww88WTWWk[_=`=`#f+. K )a-0Kr$   c           	      x   ^ ^ [        [        [        T UT5      5      R                  UU 4S jU 5       5      5      $ )z2Return True .IFF. 'node' crosses over any 'nodes'.c              3   R   >#    U  H  n[        TUT5        H  nUv   M	     M     g 7fr   )r   )rX   
check_noderu   r   r   s      r"   rZ   !_any_crossover.<locals>.<genexpr>  s/      G
#
%fj.I I #s   $')r   setr   intersection)r   r   r   r   s   `  `r"   _any_crossoverr     s;    N6489FF G
#G
 	
 r$   c                   J   ^  \ rS rSrSrU 4S jrS rS rS rS r	S r
S	rU =r$ )
r   i!  z=Manipulate list of layer dicts for _get_layered_instructions.c                   > [         TU ]  5         Xl        X l        X0l        X@l        XPl        X`l        U R                  R                   Vs/ s H  opR                  R                  U   PM     snU l        U R
                  S:X  aK  UR                  5        H6  n[        U 5      S-
  n	[        U5      n
U
 H  nU R                  X5        M     M8     g/ nUR                  5        H  nUR                  U5        M     UR                  5         U H*  nSn	[        U5      n
U
 H  nU R                  X5        M     M,     gs  snf )zCreate spoolr   r*   r   N)super__init__r   r   r   justificationr   r   cregslayersr   r   addr:   r   )selfr   r   r   r   r   r   r   r   current_index	dag_nodesr   
dag_layers	__class__s                r"   r   _LayerSpooler.__init__$  s   *&,59XX^^D^chhnnS)^D
' ZZ\	 #D	A))4	%DHHT1 & * J ZZ\	!!), *  '	 !))4	%DHHT1 & (! Es   "D<c                    ^ / nU H'  nUR                    H  nUR                  U5        M     M)     [        U4S jU 5       5      $ )z*Is any qreq in node found in any of nodes?c              3   @   >#    U  H  oTR                   ;   v   M     g 7fr   )r   )rX   ir   s     r"   rZ   ,_LayerSpooler.is_found_in.<locals>.<genexpr>I  s     6Iq

?Is   )r   r:   re   )r   r   r   	all_qargsa_nodeqargs    `    r"   is_found_in_LayerSpooler.is_found_inC  sA    	F  & %  6I666r$   c                 N    [        U R                  XU R                  5      (       + $ )z-True .IFF. we can add 'node' to layer 'nodes')r   r   r   )r   r   r   s      r"   
insertable_LayerSpooler.insertableK  s    !$++tD<O<OPPPr$   c                   ^ ^^ Sn[        TR                  [        5      (       a  [        U4S jT R                   5       5      nT (       d  SnT R                  T/5        GOtSnUnSnSn[        TR                  SS5      =n	b'  [        U 4S j[        U	5      R                   5       US9nTR                  (       aW  TR                   HG  m [        U4S	 jT R                   5       5      n
T R                  U
   U:  a  T R                  U
   nMG  MI     Xh:  aC  T R                  TT U   5      (       a  O(T R                  TT U   5      (       a  UnUS
-
  nXh:  a  MC  US:  a  SnT U   R                  T5        UnO\SnUnU[        T 5      :  aI  T R                  TT U   5      (       a  T U   R                  T5        UnSnOUS
-   nU[        T 5      :  a  MI  U(       d  T R                  T/5        [        TR                  [        5      (       a9  U(       d  [        T 5      S
-
  nUT R                  W   :  a  UT R                  U'   ggg! [         a     GM  f = f)zCInsert node into first layer where there is no conflict going l > rNc              3   R   >#    U  H  nTR                   S    U:X  d  M  Uv   M     g7f)r   N)r   )rX   ru   r   s     r"   rZ   0_LayerSpooler.slide_from_left.<locals>.<genexpr>S  s%     W.>s$**Q-SVBVss.>s   '	'TFr1   r   c              3   B   >#    U  H  nTR                   U   v   M     g 7fr   )r   )rX   ru   r   s     r"   rZ   r  `  s     \6[sT%%c*6[s   )defaultc              3   8   >#    U  H  nTU:X  d  M  Uv   M     g 7fr   r   )rX   ru   cargs     r"   rZ   r  f  s     'W7G4SV;7Gr   r*   r   )r   r!   r   r   r   r:   r?   maxr   r   r   r   r  r  r   )r   r   r}   measure_layermeasure_bitinserted
curr_indexlast_insertable_index
index_stopr   carg_bitr  s   ``         @r"   slide_from_left_LayerSpooler.slide_from_leftO  s>   dggw''Wd.>.>WWKHKKHJ$&!J$TWWk4@@	M \6I)6T6[6[\&
 zz JJD#''Wt7G7G'W#W++H5
B)-)9)9()CJ C ' )##D$z*:;;??4j)9::,6)'!^
 ) %)*+2248 5 "
 3t9,tT*-=>>Z(//5(2#'!+aJ !3t9, KKdggw''  #D	At//<<0=  - = (7 ) s   AI
IIc                    U (       d  U R                  SU/5        SnOSnUnSnU[        U 5      :  aK  U R                  XU   5      (       a  O1U R                  XU   5      (       a  UnUS-   nU[        U 5      :  a  MK  U(       a  X   R	                  U5        SnODUnUS:  a<  U R                  XU   5      (       a  X   R	                  U5        SnOUS-
  nUS:  a  M<  U(       d  U R                  SU/5        gg)z>Insert node into rightmost layer as long there is no conflict.r   TFNr*   r1   )insertr   r  r  r:   )r   r   r}   r  r  r  s         r"   slide_from_right_LayerSpooler.slide_from_right  s    KKD6"HHJ$(!s4y(##Dz*:;;??4j)9::,6)'!^
 s4y( %+2248"
 2ot*-=>>(//5#'!+aJ !2o KKD6" r$   c                     [         Ul        [         S-  q U R                  S:X  a  U R                  X5        gU R	                  X5        g)z9Add 'node' where it belongs, starting the try at 'index'.r*   r   N)_GLOBAL_NIDr   r   r!  r%  )r   r   r}   s      r"   r   _LayerSpooler.add  s?     $q'  -!!$.r$   )r   r   r   r   r   r   r   )__name__
__module____qualname____firstlineno____doc__r   r  r  r!  r%  r   __static_attributes____classcell__)r  s   @r"   r   r   !  s,    G2>7Q9>v#@/ /r$   r   r   )r_   )NT)FNTNNT);r.  r   collectionsr   warningsr   numpyrU   qiskit.circuitr   r   r   r   r	   r
   r   r   r   r   r   "qiskit.circuit.annotated_operationr   r   r   qiskit.circuit.controlflowr   qiskit.circuit.libraryr   r   r   qiskit.circuit.toolsr   qiskit.convertersr   qiskit.utilsr   
_optionals
exceptionsr   r#   rQ   rl   rw   rn   r   r   r   r   HAS_PYLATEXrequire_in_callr   r   r   r   r   r   r(  r   r   r   r$   r"   <module>r?     s    . 	 #      b a : Y Y ) , 0 +ZU/p!H<B*&JZB  ''(TU) V).2 Q!h: W/D W/r$   