
    z	i                   v	   S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
JrJrJrJr  SSKJ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JrJrJrJ r J!r!  SSK"J#r#J$r$  SSK%J&r&J'r'  SS	K(J)r)J*r*J+r+J,r,J-r-J.r.J/r/J0r0J1r1  SS
K2J3r3  SSK4J5r5  SSK6J7r7  SSK8J9r9  SSK:J;r;  \Rx                  " SS9 " S S5      5       r=\>" 1 Sk5      r?\	R                  " S\	R                  S9rB\	R                  " S\	R                  S9rC\	R                  " S\	R                  S9rD " S S5      rE\" S5      \" S5      \" S5      \" S5      4rF\R                  " 5        V s0 s H2  n U R                  (       a  M  X R                  " \FSU R                   6 _M4     sn rK\R                  " 5        V Vs0 s HZ  n U R                  (       d  M  U \L" SU R                  -  5       Vs/ s H"  nU R                  " \FSU R                   SU06PM$     sn_M\     snn rNS 0 S!\K\R                     _S"\K\R                     _S#\K\R                     _S$\K\R                     _S%\K\R                     _S&\K\R                     _S'\K\R                     _S(\K\R                     _S)\K\R                     _S*\K\R                     _S+\K\R                     _S,\K\R                     _S-\K\R                     _S.\N\R                     S   _S/\N\R                     S   _S0\N\R                     S   _S1\N\R                     S   _\N\R                     S   \N\R                     S   \N\R                     S   \N\R                     S   \K\R                     \N\R                     S2   \N\R                     S   \N\R                     S   \N\R                     S   \K\R                     \N\R                     S   \K\R                     \K\R                     \K\R                     \K\R                     S3.E0rlS4\K\R                     0rm\Rx                   " S5 S65      5       rn " S7 S85      roSCS9 jrp\Rx                   " S: S;5      5       rq " S< S=5      rr        SDS> jrsS? rtSES@ jru " SA SB\&R                  \5R                     5      rxgs  sn f s  snf s  snn f )FzQASM3 Exporter    annotationsN)IterableListSequenceUnion)StandardGate)library
AnnotationBarrierCircuitInstructionClbitGateMeasure	ParameterParameterExpressionQuantumCircuitQubitResetDelayStoreBitRegister)iter_namespacesOpenQASM3Serializer)exprtypes)	BoxOpIfElseOp	ForLoopOpWhileLoopOpSwitchCaseOpControlFlowOpBreakLoopOpContinueLoopOpCASE_DEFAULT)pi_check   )ast)ExperimentalFeatures)QASM3ExporterError)BasicPrinterT)frozenc                  H    \ rS rSr% SrS\S'    S\S'    S\S'    S\S	'   S
rg)DefcalInstructionB   a  An instruction that should be assumed by the exporter to have an associated ``defcal``
statement for it.

.. note::

    This is not a complete implementation of ``defcal``\ s in OpenQASM 3, and might require
    expansion in the future to support a broader set of statements.

    For example:

    .. code-block:: openqasm3

        // We support statements that look like these:

        defcal my_measure q -> bit {}
        defcal my_reset q {}
        defcal my_rz(angle phase) q {}

        // ... and _not_ ones that look like these:

        // Uses a non-angle argument.
        defcal my_multiplied_rz(angle phase, uint amount) q;
        // Only applies to fixed hardware qubits.
        defcal my_cx $0, $1 {}
strnameint
parametersqubitsztypes.Type | Nonereturn_type N__name__
__module____qualname____firstlineno____doc____annotations____static_attributes__r7       O/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/qasm3/exporter.pyr/   r/   B   s4    4 I"O K #"r@   r/   >/   ifinbitboxcaldefendforr3   invletpowboolcregctrlelsegateqreguintanglearraybreakconstdelayfloatinputqubitresetwhiledefcalexterngphaseoutputreturnsizeofbarriercomplexincludemeasuremutablenegctrlstretchOPENQASMcontinueduration
durationofdefcalgrammarz([\w][\w\d]*))flagsz\$[\d]+z[^\w\d]c            	      r    \ rS rSrSrSSSSSS\" S5      SS4	                 SS	 jjrS
 rS rSr	g)Exporter   zQASM3 exporter main class.)stdgates.inc)UFNz  r   c
                    X l         X0l        Ub  UO
U=(       d    SU l        [        U5      U l        X`l        Xpl        Uc  0 OUU l        U	c  0 U l        gU	U l        g)a
  
Args:
    includes: the filenames that should be emitted as includes.

        .. note::

            At present, only the standard-library file ``stdgates.inc`` is properly
            understood by the exporter, in the sense that it knows the gates it defines.
            You can specify other includes, but you will need to pass the names of the gates
            they define in the ``basis_gates`` argument to avoid the exporter outputting a
            separate ``gate`` definition.

    basis_gates: the basic defined gate set of the backend.
    disable_constants: if ``True``, always emit floating-point constants for numeric
        parameter values.  If ``False`` (the default), then values close to multiples of
        OpenQASM 3 constants (``pi``, ``euler``, and ``tau``) will be emitted in terms of those
        constants instead, potentially improving accuracy in the output.
    alias_classical_registers: If ``True``, then bits may be contained in more than one
        register.  If so, the registers will be emitted using "alias" definitions, which
        might not be well supported by consumers of OpenQASM 3.

        .. seealso::
            Parameter ``allow_aliasing``
                A value for ``allow_aliasing`` overrides any value given here, and
                supersedes this parameter.
    allow_aliasing: If ``True``, then bits may be contained in more than one register.  If
        so, the registers will be emitted using "alias" definitions, which might not be
        well supported by consumers of OpenQASM 3.  Defaults to ``False`` or the value of
        ``alias_classical_registers``.

        .. versionadded:: 0.25.0
    indent: the indentation string to use for each level within an indented block.  Can be
        set to the empty string to disable indentation.
    experimental: any experimental features to enable during the export.  See
        :class:`ExperimentalFeatures` for more details.
    annotation_handlers: a mapping of namespaces to annotation serializers.  When an
        :class:`.Annotation` object is encountered, the most specific namespace in this
        mapping that matches the annotation's :attr:`~.Annotation.namespace` attribute will
        be used to serialize it.
    implicit_defcals: mapping of :attr:`.Instruction.name`\ s to an associated
        :class:`.DefcalInstruction` object.  All instructions with the key name in the input
        circuit should be output as if there is a ``defcal`` statement corresponding to the
        given :class:`.DefcalInstruction` defined.  The key name and the
        :attr:`.DefcalInstruction.name` do not need to match.  The ``defcal`` name cannot
        collide with an OpenQASM 3 keyword.
NF)	basis_gatesdisable_constantsallow_aliasinglistincludesindentexperimentalannotation_handlersimplicit_defcals)
selfr{   rw   rx   alias_classical_registersry   r|   r}   r~   r   s
             rA   __init__Exporter.__init__   sg    t '!2,8N?X?a\a 	 X()<)D2J] &6&>DTr@   c                    [         R                  " 5        nU R                  X5        UR                  5       sSSS5        $ ! , (       d  f       g= f)zDConvert the circuit to OpenQASM 3, returning the result as a string.N)ioStringIOdumpgetvalue)r   circuitstreams      rA   dumpsExporter.dumps  s-    [[]fIIg&??$ ]]s   !A
Ac                &   [        UU R                  U R                  U R                  U R                  U R
                  U R                  U R                  S9n[        X R                  U R
                  S9R                  UR                  5       5        g)zOConvert the circuit to OpenQASM 3, dumping the result to a file or text stream.)includeslistrw   rx   ry   r}   r~   r   )r|   r}   N)QASM3Builderr{   rw   rx   ry   r}   r~   r   r,   r|   visitbuild_program)r   r   r   builders       rA   r   Exporter.dump  sy    (("44..** $ 8 8!22	
 	VKKd>O>OPVV!!#	
r@   )ry   r~   rw   rx   r}   r   r{   r|   )r{   Sequence[str]rw   r   rx   rM   r   rM   ry   rM   r|   r1   r}   r*   r~   z%dict[str, OpenQASM3Serializer] | Noner   z#dict[str, DefcalInstruction] | None)
r9   r:   r;   r<   r=   r*   r   r   r   r?   r7   r@   rA   rr   rr      s    $ #4%+"'*.#-A!-DEI@DCUCU #CU  	CU
 $(CU CU CU +CU CCU >CUJ%
r@   rr   p0p1p2p3
ctrl_statert   pxyzhssdgttdgsxrxryrzcxcyczcp   )crxcrycrzchswapccxcswapcuCXphasecphaseidu1u2u3ru   c                  0    \ rS rSr% SrS\S'    S\S'   Srg)	GateInfoiV  z#Symbol-table information on a gate.Gate | None	canonicalz ast.QuantumGateDefinition | Nonenoder7   Nr8   r7   r@   rA   r   r   V  s    -@ +*Fr@   r   c                      \ rS rSrSrS rS rS rSS jrSS jr	SS jr
S	S
.SS jjrS	S	S.           SS jjrSS jrSS jrSS jr            SS jrSS jrSS jrSrg) SymbolTableig  zCTrack Qiskit objects and the OQ3 identifiers used to refer to them.c                    0 U l          0 U l         0 U l         0 /U l         0 /U l         [
        R                  " 5       U l        g N)gatesstandard_gate_identsuser_gate_idents	variablesobjects	itertoolscount_counterr   s    rA   r   SymbolTable.__init__j  sX    *,
	 IK!a;=M35$	e =?4	e ")r@   c                p    U R                   R                  0 5        U R                  R                  0 5        g)zEnter a new variable scope.N)r   appendr   r   s    rA   
push_scopeSymbolTable.push_scope  s&    b!Br@   c                l    U R                   R                  5         U R                  R                  5         g)z6Exit the current scope, returning to a previous scope.N)r   popr   r   s    rA   	pop_scopeSymbolTable.pop_scope  s"    r@   c                    [        5       nU R                  Ul        U R                  Ul        U R                  Ul        U$ )zCreate a new context, such as for a gate definition.

Contexts share the same set of globally defined gates, but have no access to other variables
defined in any scope.)r   r   r   r   )r   outs     rA   new_contextSymbolTable.new_context  s7    
 mJJ	#'#<#< #44
r@   c                    U[         ;   =(       dJ    XR                  ;   =(       d5    U[        R                  R	                  [        U R                  5      5      ;   $ )z6Whether this identifier has a defined meaning already.)_RESERVED_KEYWORDSr   r   chainfrom_iterablereversedr   r   r2   s     rA   symbol_definedSymbolTable.symbol_defined  sH     && Ozz!Oy44Xdnn5MNN	
r@   c                n    XR                   S   ;  =(       a    XR                  ;  =(       a	    U[        ;  $ )zZWhether a new definition of this symbol can be made within the OpenQASM 3 shadowing
rules.)r   r   r   r   s     rA   can_shadow_symbolSymbolTable.can_shadow_symbol  s5     r** /JJ&/..	
r@   F)uniquec                 ^  U(       a  U 4S jOT R                   n[        nU(       ai  UR                  U5      (       d  S[        R	                  SU5      -   nUnU" U5      (       d)  U S[        T R                  5       3nU" U5      (       d  M)  U$ UR                  U5      (       d  [        SU S35      eU[        ;   a  [        SU S35      eU" U5      (       d~  T R                  R                  U5      b  [        SU S35      e[        T R                  5       H  nUR                  U5      =nc  M    O   [        S	U S
35      e[        SU SU S
35      eU$ )zGet an identifier based on ``name`` that can be safely shadowed within this scope.

If ``unique`` is ``True``, then the name is required to be unique across all live scopes,
not just able to be redefined.c                0   > TR                  U 5      (       + $ r   )r   )r2   r   s    rA   <lambda>5SymbolTable.escaped_declarable_name.<locals>.<lambda>  s    d11$77r@   _zcannot use 'z)' as a name; it is not a valid identifierzcannot use the keyword 'z' as a variable namezcannot shadow variable 'z%', as it is already defined as a gatez/internal error: could not locate unshadowable ''z ', as it is already defined as ')r   _VALID_DECLARABLE_IDENTIFIER	fullmatch_BAD_IDENTIFIER_CHARACTERSsubnextr   r+   r   r   getr   r   RuntimeError)	r   r2   allow_renamer   name_allowedvalid_identifierbasescopeothers	   `        rA   escaped_declarable_name#SymbolTable.escaped_declarable_name  su    =C7H^H^ 	 8#--d337;;CFFD"4((qdmm!4 56 #4((K))$//$|D69b%cdd%%$'?vEY%Z[[D!!zz~~d#/(.tf4YZ  "$..1"YYt_,E9 2 #%TUYTZZ[#\]]$*4&0PQVPWWXY  r@   )force_globalallow_hardware_qubitc               >   U(       a  SOSnU(       a?  [         R                  U5      (       a%  U R                  U5      (       a  [        SU 35      eOU R	                  XUS9n[
        R                  " U5      nX R                  U   U'   Ub  XpR                  U   U'   U$ )a  Register a variable in the symbol table for the given scope, returning the name that
should be used to refer to the variable.  The same name will be returned by subsequent calls
to :meth:`get_variable` within the same scope.

Args:
    name: the name to base the identifier on.
    variable: the Qiskit object this refers to.  This can be ``None`` in the case of
        reserving a dummy variable name that does not actually have a Qiskit object backing
        it.
    allow_rename: whether to allow the name to be mutated to escape it and/or make it safe
        to define (avoiding keywords, subject to shadowing rules, etc).
    force_global: force this declaration to be in the global scope.
    allow_hardware_qubit: whether to allow hardware qubits to pass through as identifiers.
        Hardware qubits are a dollar sign followed by a non-negative integer, and cannot be
        declared, so are not suitable identifiers for most objects.
r   r   z0internal error: cannot redeclare hardware qubit r   r   )	_VALID_HARDWARE_QUBITr   r   r+   r   r)   
Identifierr   r   )r   r2   variabler   r   r   scope_index
identifiers           rA   register_variableSymbolTable.register_variable  s    2 (aR
  $9$C$CD$I$I""4(((+[\`[a)bcc ) // 0 D ^^D)
,4{#D)2<LL%h/r@   c                &    XR                   S   U'   g)a4  Set the identifier used to refer to a given object for this scope.

This overwrites any previously set identifier, such as during the original registration.

This is generally only useful for tracking "sub" objects, like bits out of a register, which
will have an `SubscriptedIdentifier` as their identifier.r   N)r   )r   identr  s      rA   set_object_identSymbolTable.set_object_ident  s     &+R"r@   c                    [        U R                  5       H  nUR                  U5      =nc  M  Us  $    [        SU S35      e)z/Lookup a non-gate variable in the symbol table.r   z'' is not defined in the current context)r   r   r   KeyError)r   r  r   r   s       rA   get_variableSymbolTable.get_variable  sE    dll+Eyy**7
 , 8*$KLMMr@   c                T   U R                  USSS9n[        R                  " U5      nUc  [        SS5      U R                  U'   U$ [        U5      n[        US5      U R                  U'   UR                  b  X0R                  UR                  '   U$ X0R                  [        U5      '   U$ )a  Register a gate that does not require an OQ3 definition.

If the ``gate`` is given, it will be used to validate that a call to it is compatible (such
as a known gate from an included file).  If it is not given, it is treated as a user-defined
"basis gate" that assumes that all calling signatures are valid and that all gates of this
name are exactly compatible, which is somewhat dangerous.Fr   N)
r   r)   r  r   r   _gate_canonical_form_standard_gater   r   r   )r   r2   rQ   r  r   s        rA    register_gate_without_definition,SymbolTable.register_gate_without_definition  s     ++DuU+St$<'d3DJJt  -T2I'	48DJJt''3FK)))*B*BC  8=%%bm4r@   c           
     T   U R                  USSS9n[        R                  " U5      n[        U[        R                  " U[        U5      [        U5      U5      5      U R                  U'   UR                  b  X`R                  UR                  '   U$ X`R                  [        U5      '   U$ )zlRegister the given gate in the symbol table, using the given components to build up the
full AST definition.TFr   )r   r)   r  r   QuantumGateDefinitiontupler   r  r   r   r   )r   r2   sourceparamsr5   bodyr  s          rA   register_gateSymbolTable.register_gate   s     ++DtE+Rt$#C--eU6]E&MSWX


4   ,?D%%f&;&;<  16!!"V*-r@   c                <    U R                  UR                  S5        g)z4Register a ``defcal`` statement in the symbol table.N)r  r2   )r   r^   s     rA   register_defcalSymbolTable.register_defcal8  s     	--fkk4@r@   c                
   [        U5      nU R                  R                  UR                  5      =nbL  UR                  UL d  UR                  b  UR                  U:X  a   [
        R                  " UR                  5      $ UR                  bT  U R                  R                  UR                  5      =nc  gU R                  UR                     R                  U:X  a  U$ S$ U R                  R                  [        U5      5      $ )z7Lookup the identifier for a given `Gate`, if it exists.N)r  r   r   r2   r   r)   r  r  r   stringr   r   )r   rQ   r   our_defn	our_idents        rA   get_gateSymbolTable.get_gate>  s    (.	

tyy11H> )+!!)!!Y.>>$)),,##/!66::9;S;STT	] $

9+;+; < F F) S9]Y]]$$((I77r@   )r   r   r   r   r   r   N)rb   r   )r2   r1   rb   rM   )r2   r1   r   rM   r   rM   )r2   r1   r  objectr   rM   r   rM   r   rM   rb   ast.Identifier)r  r&  r  r%  )r  r%  rb   r&  )r2   r1   rQ   r   rb   r&  )r2   r1   r  r   r  Iterable[ast.Identifier]r5   r'  r  zast.QuantumBlockrb   r&  )r^   r/   )rQ   r   rb   zast.Identifier | None)r9   r:   r;   r<   r=   r   r   r   r   r   r   r   r  r	  r  r  r  r  r#  r?   r7   r@   rA   r   r   g  s    M*: 

	

 X] !R #%*)) )
 ) ) #) 
)V+N*  )	
 )  
0A8r@   r   c                    U R                   nUc  U $ UR                  (       a  [        U   U R                     $ [        U   $ )ag  Get the canonical form of a gate.

This is the gate object that should be used to provide the OpenQASM 3 definition of a gate (but
not the call site; that's the input object).  This lets us return a re-parametrised gate in
terms of general parameters, in cases where we can be sure that that is valid.  This is
currently only Qiskit standard gates.  This lets multiple call-site gates match the same symbol,
in the case of parametric gates.

The definition source provides the number of qubits, the parameter signature and the body of the
`gate` statement.  It does not provide the name of the symbol being defined.)r  is_controlled_gate$_CANONICAL_CONTROLLED_STANDARD_GATESr   _CANONICAL_STANDARD_GATES)rQ   standards     rA   r  r  S  sL     ""H && 	-X6tG 'x0r@   c                  0    \ rS rSr% SrS\S'    S\S'   Srg)	
BuildScopeik  zThe structure used in the builder to store the contexts and re-mappings of bits from the
top-level scope where the bits were actually defined.r   r   zdict[Bit, Bit]bit_mapr7   Nr8   r7   r@   rA   r.  r.  k  s    = F8r@   r.  c                     \ rS rSrSr\\\\\	\
\4rSrSrSrSr\" S5      SS4S	 jr\R(                  S'S
 j5       r\R(                  S(S j5       rS)S jrS rS rS*S jrS rS rS rS rS rS+S jr S,S jr!S-S jr"S.S jr#S/S jr$S0S jr%S1S jr&S2S jr'S r(S3S jr)S4S jr*S5S  jr+S6S! jr,S" r-S7S# jr.S8S$ jr/S9S% jr0S&r1g):r   iw  z6QASM3 builder constructs an AST from a QuantumCircuit._bit_qubit_gate_p_gate_qr   Nc	                V   [        U[        R                  " UR                  UR                  5       V	s0 s H  oU	_M     sn	5      U l        [        5       U l        / U l        / U l	        X@l
        XPl        X l        X0l        X`l        Uc  0 OUU l        Uc  0 U l        g UU l        g s  sn	f r   )r.  r   r   r5   clbitsr   r   symbols_global_io_declarations&_global_classical_forward_declarationsrx   ry   r{   rw   r}   r~   r   )
r   quantumcircuitr   rw   rx   ry   r}   r~   r   r   s
             rA   r   QASM3Builder.__init__  s      $??>+@+@.BWBWXYXaTXY

 #} (*$683!2,$&()<)D2J] &6&>DT# Zs   B&
c           	   #    ^#    U R                   R                  m[        U4S jU 5       5      n[        U4S jU 5       5      nUR                  [	        U5      :w  a%  [        SUR                   S[	        U5       S35      eUR                  [	        U5      :w  a%  [        SUR                   S[	        U5       S35      e[        [        R                  " [        UR                  U5      [        UR                  U5      5      5      nU R                  R                  5         U R                   [        X5      soPl         U R                   v   XPl         U R                  R!                  5         g7f)	zoContext manager that pushes a new scope (like a ``for`` or ``while`` loop body) onto the
current context stack.c              3  .   >#    U  H
  nTU   v   M     g 7fr   r7   ).0r[   current_maps     rA   	<genexpr>)QASM3Builder.new_scope.<locals>.<genexpr>       >ve{5)v   c              3  .   >#    U  H
  nTU   v   M     g 7fr   r7   )r>  clbitr?  s     rA   r@  rA    rB  rC  z*Tried to push a scope whose circuit needs z qubits, but only provided z qubits to create the mapping.z clbits, but only provided z clbits to create the mapping.N)r   r/  r  
num_qubitslenr+   
num_clbitsdictr   r   zipr5   r6  r7  r   r.  r   )r   r   r5   r6  mapping	old_scoper?  s         @rA   	new_scopeQASM3Builder.new_scope  s5     jj((>v>>>v>>V,$<W=O=O<P Q [M)GI  V,$<W=O=O<P Q [M)GI  ys7>>6'BCX^D_`a! $

Jw,H	:jj
 s   E*E-c              #  N  #    [         R                  " UR                  UR                  5       Vs0 s H  o"U_M     nnU R                  U R                  R                  5       so@l        U R                  [        X5      soPl        U R                  v   XPl        X@l        gs  snf 7f)zHPush a new context (like for a ``gate`` or ``def`` body) onto the stack.N)r   r   r5   r6  r7  r   r   r.  )r   r  rD   rK  old_symbolsrL  s         rA   r   QASM3Builder.new_context  s~      (1t{{DKK'PQ'P8'PQ$(LL$,,2J2J2L!\ $

Jt,E	:jj
" Rs   .B%B A)B%c                f    U R                   R                  U R                  R                  U   5      $ )zLookup a Qiskit bit within the current context, and return the name that should be
used to represent it in OpenQASM 3 programmes.)r7  r  r   r/  )r   rD   s     rA   _lookup_bitQASM3Builder._lookup_bit  s(     ||((););C)@AAr@   c           	        U R                   R                  nUR                  (       d  UR                  (       a  [	        S5      e[
        R                  5        H   u  p#U R                  R                  X#5        M"     S[        R                  " 5       4nU R                  R                  5        HX  u  pVUR                  U;  a(  [	        SUR                   SU SUR                   35      eU R                  R                  U5        MZ     U R                   H,  nU[
        ;   a  M   U R                  R                  US5        M.     [         R"                  " [         R$                  " S5      ['        U R)                  5       5      5      nU R+                  5         U R-                  5         U R/                  5         U R1                  5       n	U R3                  5       n
U R4                  S	 U R                  R6                  R9                  5        5       U R:                  U	U
4 VVs/ s H  nU  H  nUPM     M     nnn[         R<                  " X5      $ ! [         a  n[	        SU S35      UeSnAff = fs  snnf )
zBuilds a ProgramzKcannot export an inner scope with captured variables as a top-level programNThe defcal '*' associated with instructions with name ')' returns an unsupported classical type: zCannot use 'z' as a basis gate for the reason in the prior exception. Consider renaming the gate if needed, or omitting this basis gate if not.z3.0c              3  V   #    U  H  oR                   c  M  UR                   v   M!     g 7fr   )r   )r>  rQ   s     rA   r@  -QASM3Builder.build_program.<locals>.<genexpr>  s     \'Btii'Bs   )))r   r   num_captured_varsnum_captured_stretchesr+   _BUILTIN_GATESitemsr7  r  r   Boolr   r6   r2   r  rw   r)   HeaderVersionrz   build_includes#hoist_global_parameter_declarations%hoist_classical_register_declarations#hoist_classical_io_var_declarationsbuild_quantum_declarationsbuild_current_scoper8  r   valuesr9  Program)r   r   builtinrQ   allowed_defcal_typesr2   r^   excheaderquantum_declarationsmain_statementsr  	statement
statementss                 rA   r   QASM3Builder.build_program  sH   **$$$$(F(F$] & ,113MGLL99'H 4
 !%ejjl3 11779LD!!)==("6;;-/YZ^Y_ `??E?Q?Q>RT  LL((0 : ''G.(==gtL ( CKK.T5H5H5J0KL 	002 	224 	002  $>>@ 224 ,,\t||'9'9'@'@'B\;;$
 $	  $  	 
 {{6..U & ("7) ,a a :
s   %II/
I,I''I,c              #     #    U R                    Hc  n[        R                  U0 5      R                  5        H   u  p#U R                  R                  X#5        M"     [        R                  " U5      v   Me     g7f)z Builds a list of included files.N)r{   _KNOWN_INCLUDESr   r^  r7  r  r)   Include)r   filenamer2   rQ   s       rA   rb  QASM3Builder.build_includes  sY     H .11(B?EEG
==dI H++h'' &s   A5A7c                <   [        UR                  [        R                  5      (       GaR  UR                  S:X  GaA  [
        R                  " S5      [
        R                  " S5      p2[
        R                  " [
        R                  " U R                  R                  [        R                  " [        R                  S[        R                  5      5      X#/[
        R                  R                  [
        R                   " S5      [
        R                  R                  /[
        R"                  " [
        R$                  R&                  5      /S9/5      nU R                  R)                  UR*                  USX#4U5      $ UR,                  c  [/        SUR*                   S	35      e[1        U5      nU R3                  UR,                  5         U R4                  R6                  nUR8                  S:  a  UR8                  [;        UR<                  5      :w  a.  [/        S
[;        UR<                  5       SUR8                   35      eUR>                   Vs/ s H(  nU R                  RA                  UR*                  USS9PM*     nnOV[C        [;        UR<                  5      5       V	s/ s H-  n	U R                  RA                  U RD                   SU	 3SSS9PM/     nn	[G        URH                  5       V	V
s/ s H/  u  pU R                  RA                  U RJ                   SU	 3U
SS9PM1     nn	n
[
        R                  " U RM                  5       5      nSSS5        U R                  R)                  UR*                  UWWW5      $ s  snf s  sn	f s  sn
n	f ! , (       d  f       NG= f)zDefine a gate in the symbol table, including building the gate-definition statement for
it.

This recurses through gate-definition statements.r(   cr   r   )r4   	modifiersr7   Nzfailed to export gate 'z' that has no definitionz7parameter mismatch in definition of '{gate}': call has z, definition has Tr   r   )'
issubclass
base_classr
   CXGater   r)   r  QuantumBlockQuantumGateCallr7  r#  UGatemathpiConstantPIIntegerLiteralQuantumGateModifierQuantumGateModifierNameCTRLr  r2   
definitionr+   r  r   r   r   num_parametersrG  r  r4   r  rangegate_parameter_prefix	enumerater5   gate_qubit_prefixrg  )r   rQ   controltargetr  r   defnparamr  ir[   r5   s               rA   define_gateQASM3Builder.define_gate'  s   
 doow~~664??a;O
 "nnS13>>#3FV##''--gmmDGGQ.PQ )$'LLOOS5G5G5JCLLOO#\#&#:#:3;V;V;[;[#\"]		D <<--diirGCTVZ[[??"$'>tyykIa%bcc(.	i223::%%D ""Q&&&#dkk*::,%%(%5$66GH[H[G\^  "&!0 LL225::uSW2X!0   #3t{{#34	 5 LL22556as;TPT 3  5	   !*$++ 6	 !7HA ..--.as3U /  !7	   ##D$<$<$>?DI 4P ||)))..)VVUYZZ/= 43s7   	BN/M=>#N!4NN/6N%'N=N
Nc                `    [        U R                  R                  5      S:  a  [        S5      eg)zIRaise an error if we are not in the global scope, as a defensive measure.r(   z!not currently in the global scopeN)rG  r7  r   r   r   s    rA   assert_global_scope QASM3Builder.assert_global_scopej  s*    t||%%&*BCC +r@   c                   U R                  5         U R                  R                  nUR                   H  nU R                  R                  UR                  USS9n[        XU5      nUc  M9  [        U[        R                  5      (       a  U R                  R                  U5        Mu  U R                  R                  U5        M     g)zExtend ``self._global_io_declarations`` and ``self._global_classical_declarations`` with
any implicit declarations used to support the early IBM efforts to use :class:`.Parameter`
as an input variable.Tr{  N)r  r   r   r4   r7  r  r2   _infer_variable_declaration
isinstancer)   IODeclarationr8  r   r9  )r   r   	parameterparameter_namedeclarations        rA   rc  0QASM3Builder.hoist_global_parameter_declarationso  s     	  "**$$ ++I!\\;;	 < N 6g.YK"+s'8'899,,33K@;;BB;O ,r@   c           
       ^ ^ T R                  5         T R                  R                  m[        U4S jTR                   5       5      (       a  T R
                  (       d  [        S5      eU 4S j[        TR                  5       5       nT R                  R                  U5        T R                  R                  T R                  TR                  5      5        gT R                  R                  UU 4S j[        TR                  5       5       5        TR                   H  nT R                  R                  UR                  USS9n[        U5       HT  u  pET R                  R                  [         R"                  " UR$                  [         R&                  " U5      5      U5        MV     T R                  R)                  [         R*                  " [         R,                  " [/        U5      5      U5      5        M     g)a  Extend the global classical declarations with AST nodes declaring all the global-scope
circuit :class:`.Clbit` and :class:`.ClassicalRegister` instances.  Qiskit's data model
doesn't involve the declaration of *new* bits or registers in inner scopes; only the
:class:`.expr.Var` mechanism allows that.

The behavior of this function depends on the setting ``allow_aliasing``. If this
is ``True``, then the output will be in the same form as the output of
:meth:`.build_classical_declarations`, with the registers being aliases.  If ``False``, it
will instead return a :obj:`.ast.ClassicalDeclaration` for each classical register, and one
for the loose :obj:`.Clbit` instances, and will raise :obj:`QASM3ExporterError` if any
registers overlap.
c              3  r   >#    U  H,  n[        TR                  U5      R                  5      S :  v   M.     g7fr(   NrG  find_bit	registersr>  qr   s     rA   r@  EQASM3Builder.hoist_classical_register_declarations.<locals>.<genexpr>  ,     N~!s7##A&001A5~   47zlSome classical registers in this circuit overlap and need aliases to express, but 'allow_aliasing' is false.c           
   3     >#    U  HX  u  p[         R                  " [         R                  " 5       TR                  R	                  TR
                   U 3US S95      v   MZ     g7fTr{  N)r)   ClassicalDeclarationBitTyper7  r  loose_bit_prefix)r>  r  rE  r   s      rA   r@  r    se       !:HA ((KKMLL22001!5u4 3   !:s   A A#Nc           
   3    >#    U  Hz  u  pTR                  U5      R                  (       a  M'  [        R                  " [        R                  " 5       TR
                  R                  TR                   U 3US S95      v   M|     g7fr  )r  r  r)   r  r  r7  r  r  )r>  r  rE  r   r   s      rA   r@  r    s{      	;
 6##E*44C$$..,,-aS15t /   6s   &BABTr{  )r  r   r   anyr6  ry   r+   r  r9  extendbuild_aliasescregsr7  r  r2   r	  r)   SubscriptedIdentifierr   r  r   r  BitArrayTyperG  )r   r6  registerr2   r  rD   r   s   `     @rA   rd  2QASM3Builder.hoist_classical_register_declarations  s    	  "**$$Nw~~NNN&&(6  !*'.. 9F 77>>vF77>>t?Q?QRYR_R_?`a 	33:: 	;
 &gnn5	;
 		
  H<<11(--X\1]D#H-----dkk3;M;Ma;PQSV . 77>>(()9)9#h-)H$O &r@   c                |   U R                  5         U R                  R                  nUR                  5        H  nU R                  R                  [        R                  " [        R                  R                  [        UR                  5      U R                  R                  UR                  USS95      5        M     g)a-  Hoist the declarations of classical IO :class:`.expr.Var` nodes into the global state.

Local :class:`.expr.Var` declarations are handled by the regular local-block scope builder,
and the :class:`.QuantumCircuit` data model ensures that the only time an IO variable can
occur is in an outermost block.Tr{  N)r  r   r   iter_input_varsr8  r   r)   r  
IOModifierINPUT_build_ast_typetyper7  r  r2   )r   r   vars      rA   re  0QASM3Builder.hoist_classical_io_var_declarations  s     	  "**$$**,C((//!!NN((#CHH-LL22388St2T -r@   c                ~  ^	 U R                  5         U R                  R                  m	T	R                  b?  [	        T	R
                  5       H$  u  pU R                  R                  SU 3USSS9  M&     / $ [        U	4S jT	R
                   5       5      (       a  U R                  (       d  [        S5      e[	        T	R
                  5       VVs/ s HB  u  p[        R                  " U R                  R                  U R                   U 3USS95      PMD     nnnX@R                  T	R                  5      -   $ [	        T	R
                  5       VVs/ s Hd  u  pT	R!                  U5      R"                  (       a  M'  [        R                  " U R                  R                  U R                   U 3USS95      PMf     nnn/ nT	R                   H  nU R                  R                  UR$                  USS9n[	        U5       HT  u  pU R                  R'                  [        R(                  " UR*                  [        R,                  " U5      5      U5        MV     UR/                  [        R                  " U[        R0                  " [        R,                  " [3        U5      5      5      5      5        M     XV-   $ s  snnf s  snnf )zzReturn a list of AST nodes declaring all the qubits in the current scope, and all the
alias declarations for these qubits.$FT)r   r   c              3  r   >#    U  H,  n[        TR                  U5      R                  5      S :  v   M.     g7fr  r  r  s     rA   r@  :QASM3Builder.build_quantum_declarations.<locals>.<genexpr>  r  r  zjSome quantum registers in this circuit overlap and need aliases to express, but 'allow_aliasing' is false.r{  )r  r   r   layoutr  r5   r7  r  r  ry   r+   r)   QuantumDeclarationloose_qubit_prefixr  qregsr  r  r2   r	  r  r   r  r   
DesignatorrG  )
r   r  rD   r[   r5   loose_qubitsr  r  r2   r   s
            @rA   rf  'QASM3Builder.build_quantum_declarations  sj    	  "**$$>>% $GNN3..sGSu4 /  4 INw~~NNN&&(6  !*'.. 9 !:HA &&LL22223A37T 3 
 !:   ..w}}=== &gnn5
 6##E*44C""..../s3U / 
 6 	 
 	H<<11(--X\1]D#H-----dkk3;M;Ma;PQSV . &&tS^^C<N<NsS[}<]-^_ & ''=
s   A	J3&J97AJ9c           
        / nU H  nU R                   R                  UR                  USS9nU Vs/ s H  oPR                  U5      PM     nn[	        U5       HT  u  puU R                   R                  [        R                  " UR                  [        R                  " U5      5      U5        MV     UR                  [        R                  " U[        R                  " U5      5      5        M     U$ s  snf )zoReturn a list of alias declarations for the given registers.  The registers can be either
classical or quantum.Tr{  )r7  r  r2   rS  r  r	  r)   r  r   r  r   AliasStatementIndexSet)r   r  r   r  r2   rD   elementsr  s           rA   r  QASM3Builder.build_aliases  s     !H<<11(--X\1]D9AB#((-HB#H-----dkk3;M;Ma;PQSV .
 JJs))$X0FGH " 
 Cs   C0c                x   U R                   R                  R                  5        Vs/ s HP  n[        R                  " [        UR                  5      U R                  R                  UR                  USS95      PMR     nnU R                   R                  R                  5        HK  nUR                  [        R                  " U R                  R                  UR                  USS95      5        MM     U R                   R                  R                   GH  n[        UR                  [         5      (       Ga\  [        UR                  ["        5      (       a"  UR                  U R%                  U5      5        GO[        UR                  [&        5      (       a!  UR                  U R)                  U5      5        O[        UR                  [*        5      (       a!  UR                  U R-                  U5      5        O[        UR                  [.        5      (       a!  UR1                  U R3                  U5      5        OX[        UR                  [4        5      (       a!  UR                  U R7                  U5      5        O[9        SUR                   35      eGM  U R:                  R=                  UR                  S5      =nb  U R?                  XE5      /nGO[        UR                  [@        5      (       a  U RC                  U5      /nGO[        UR                  [D        5      (       aC  URF                   Vs/ s H  opRI                  U5      PM     nn[        RJ                  " U5      /nGO+[        UR                  [L        5      (       av  [        RN                  " URF                   Vs/ s H  opRI                  U5      PM     sn5      n	U RI                  URP                  S   5      n
[        RR                  " X5      /nGO[        UR                  [T        5      (       aA  URF                   Vs/ s H(  n[        RV                  " U RI                  U5      5      PM*     nnGO6[        UR                  [X        5      (       a  U R[                  U5      /nGO[        UR                  [\        5      (       a_  [        R^                  " U Ra                  UR                  Rb                  5      U Ra                  UR                  Rd                  5      5      /nO[        UR                  [f        5      (       a  [        Rh                  " 5       /nOO[        UR                  [j        5      (       a  [        Rl                  " 5       /nO[o        SUR                   S35      eUR1                  U5        GM     U$ s  snf s  snf s  snf s  snf )zBuild the instructions that occur in the current scope.

In addition to everything literally in the circuit's ``data`` field, this also includes
declarations for any local :class:`.expr.Var` nodes.
Tr{  z"unhandled control-flow construct: Nr   zBnon-unitary subroutine calls are not yet supported, but received 'r   )8r   r   iter_declared_varsr)   r  r  r  r7  r  r2   iter_declared_stretchesr   StretchDeclarationdatar  	operationr#   r    build_for_loopr!   build_while_loopr   build_if_statementr"   r  build_switch_statementr   	build_boxr   r   r   build_defcal_callr   build_gate_callr   r5   rS  QuantumBarrierr   QuantumMeasurementr6  QuantumMeasurementAssignmentr   QuantumResetr   build_delayr   AssignmentStatementbuild_expressionlvaluervaluer$   BreakStatementr%   ContinueStatementr+   )r   r  rq  rj   instructionr^   nodesoperandoperandsmeasurementrE  s              rA   rg   QASM3Builder.build_current_scope  s   & zz))<<>

 ?	 $$)..sxx4.P ? 	 
 zz))AACG&&LL227<<W[2\ D  ::--22K+//??k33Y??%%d&9&9+&FG 5 5{CC%%d&;&;K&HI 5 5x@@%%d&=&=k&JK 5 5|DD%%d&A&A+&NO 5 5u==%%dnn[&AB&)KKLaLaKb'cdd//33K4D4DdKKX//DEK11488--k:;K117;;EPEWEWXEW',,W5EWX++H56K117;;!44>I>P>PQ>P7%%g.>PQ ((););A)>?99%MNK11599OZOaOaOaGC$$T%5%5g%>?Oa   K11599))+67K11599++--k.C.C.J.JK--k.C.C.J.JK K11;??++-.K11>BB..01(&&1&;&;%<A? 
 e$i 3j I
H Y R
s   AV(0V-"V2
'/V7c                   U R                  [        UR                  R                  5      5      nUR                  R                  S   nU R                  X1R                  UR                  5         [        R                  " U R                  5       5      nSSS5        [        UR                  R                  5      S:X  a  [        R                  " UWS5      $ UR                  R                  S   nU R                  XQR                  UR                  5         [        R                  " U R                  5       5      nSSS5        [        R                  " UWW5      $ ! , (       d  f       N= f! , (       d  f       N7= f)z@Build an :obj:`.IfElseOp` into a :obj:`.ast.BranchingStatement`.r   Nr(   )r  _lift_conditionr  	conditionblocksrM  r5   r6  r)   ProgramBlockrg  rG  BranchingStatement)r   r  r  true_circuit	true_bodyfalse_circuit
false_bodys          rA   r  QASM3Builder.build_if_statementa  s   ))/+:O:O:Y:Y*Z[	",,33A6^^L*<*<k>P>PQ(()A)A)CDI R{$$++,1)))YEE#--44Q7^^M+=+={?Q?QR))$*B*B*DEJ S%%iJGG RQ SRs   .%E%E+
E(+
E9c           	       ^ ^^
 T R                  [        R                  " TR                  R                  5      5      nT R
                  R                  SSSSS9nT R                  R                  [        R                  " [        R                  " 5       US5      5        [        R                  T R                  ;   aV  UU 4S jm
[        R                  " X25      [        R                   " UU
4S jTR                  R#                  5        5       5      /$ / nSnTR                  R#                  5        H  u  pgT R%                  UTR&                  TR(                  5         [        R*                  " T R-                  5       5      nSSS5        [.        U;   a  WnMg  UR                  U V	s/ s H  n	T R1                  U	5      PM     sn	W45        M     [        R                  " X25      [        R2                  " X4US9/$ ! , (       d  f       N~= fs  sn	f )zBBuild a :obj:`.SwitchCaseOp` into a :class:`.ast.SwitchStatement`.switch_dummyNT)r   r   c                b  > U  Vs/ s H2  nU[         L a  [        R                  " 5       OTR                  U5      PM4     n nTR	                  UTR
                  TR                  5         [        R                  " TR                  5       5      nS S S 5        X4$ s  snf ! , (       d  f       U W4$ = fr   )	r&   r)   DefaultCasebuild_integerrM  r5   r6  r  rg  )rh  
case_blockv	case_bodyr  r   s       rA   case1QASM3Builder.build_switch_statement.<locals>.case}  s     $# *+l):COO%@R@RST@UU#   ^^J0B0BKDVDVW # 0 01I1I1K LI X(( XWy((s   9B(%B
B.c              3  8   >#    U  H  u  pT" X5      v   M     g 7fr   r7   )r>  rh  blockr  s      rA   r@  6QASM3Builder.build_switch_statement.<locals>.<genexpr>  s"      -TMF V++-Ts   )default)r  r   liftr  r  r7  r  r9  r   r)   r  IntTyper*   SWITCH_CASE_V1r}   r  SwitchStatementPreviewcases_specifierrM  r5   r6  r  rg  r&   r   SwitchStatement)r   r  real_targetr  casesr	  rh  r  r  valuer  s   ``        @rA   r  #QASM3Builder.build_switch_statementp  s   ++DIIk6K6K6R6R,ST//Dt$ 0 
 	33::$$S[[]FDA	
  ..$2C2CC) ''<**-8-B-B-R-R-T	 	 (22BBDMF{'9'9;;M;MN,,T-E-E-GH	 Ov% $LL&I&4--e4&I9UV E ##F8w?
 	
 ON Js   %G8%H	
8
H	c                   U R                  UR                  R                  UR                  R                  5      nUR                  R                  S   nUR                  R
                   Vs/ s H  o@R                  U5      PM     nnU R                  X1R                  UR                  5         [        R                  " U R                  5       5      nSSS5        [        R                  " WX%S9$ s  snf ! , (       d  f       N(= f)z:Build a :class:`.BoxOp` into a :class:`.ast.BoxStatement`.r   Nr   )build_durationr  rm   unitr  r   build_annotationrM  r5   r6  r)   r  rg  BoxStatement)r   r  rm   body_circuit
annotationr   r  s          rA   r  QASM3Builder.build_box  s    &&{'<'<'E'E{G\G\GaGab",,33A6@K@U@U@a@a
@a*!!*-@a 	 
 ^^L*<*<k>P>PQ##D$<$<$>?D R hHH
 RQs   ,C0.%C55
Dc                   U R                  [        UR                  R                  5      5      nUR                  R                  S   nU R                  X1R                  UR                  5         [        R                  " U R                  5       5      nSSS5        [        R                  " UW5      $ ! , (       d  f       N%= f)zBBuild a :obj:`.WhileLoopOp` into a :obj:`.ast.WhileLoopStatement`.r   N)r  r  r  r  r  rM  r5   r6  r)   r  rg  WhileLoopStatement)r   r  r  loop_circuit	loop_bodys        rA   r  QASM3Builder.build_while_loop  s    ))/+:O:O:Y:Y*Z[	",,33A6^^L*<*<k>P>PQ(()A)A)CDI R%%i;; RQs   .%B22
C c           	     L   UR                   R                  u  p#nU R                  XAR                  UR                  5         Uc  SOUR
                  nU R                  R                  XSSS9n[        U[        5      (       aw  [        R                  " U R                  UR                  5      U R                  UR                  S-
  5      UR                  S:w  a  U R                  UR                  5      OSS9nO6 [        R                   " U Vs/ s H  oR                  U5      PM     sn5      n[        R$                  " U R'                  5       5      n	SSS5        [        R(                  " WWW	5      $ s  snf ! ["         a    [#        SU S35      Sef = f! , (       d  f       NI= f)	z>Build a :obj:`.ForLoopOp` into a :obj:`.ast.ForLoopStatement`.Nr   Tr{  r(   )startrH   stepzIThe values in OpenQASM 3 'for' loops must all be integers, but received ''.)r  r  rM  r5   r6  r2   r7  r  r  r  r)   Ranger   r"  stopr#  r  r+   r  rg  ForLoopStatement)
r   r  indexsetloop_parameterr  r2   loop_parameter_astindexset_astr  body_asts
             rA   r  QASM3Builder.build_for_loop  ss   1<1F1F1M1M.,^^L*<*<k>P>PQ(03n6I6ID!%!?!?4 "@ " (E**"yy,,X^^<**8==1+<=>Fmmq>P++HMM:VZ  #&<<X`0aX`u1C1CE1JX`0a#bL ''(@(@(BCH) R* ##L2DhOO 1b)  ,%Jb*     RQs7    B8F9E7E2
'E7.$F2E77FF
F#c                   [        UR                  5       Ha  nU R                  R                  US5      =nc  M$  UR	                  U5      =n[
        Ld  M@  [        R                  " UR                  U5      s  $    [        SU 35      e)z=Use the custom serializers to construct an annotation object.Nz1No configured annotation serializer could handle )	r   	namespacer~   r   r   NotImplementedr)   r   r+   )r   r  r/  
serializerpayloads        rA   r  QASM3Builder.build_annotation  s    ()=)=>I"66::9dKK
X%??:66#^$ ~~j&:&:GDD	 ?
 !#TU_T`!abbr@   c                    [        U[        5      (       a  U R                  U5      $ U R                  R	                  U5      $ r   )r  r   rS  r7  r  )r   r  s     rA   _lookup_variable_for_expression,QASM3Builder._lookup_variable_for_expression  s5    c3##C((||((--r@   c                J    UR                  [        U R                  5      5      $ )zBuild an expression.)accept_ExprBuilderr5  r   r   s     rA   r  QASM3Builder.build_expression  s    {{<(L(LMNNr@   c           	     <   UR                   (       a  [        SU 35      eU R                  UR                  R                  UR                  R
                  5      n[        R                  " X!R                   Vs/ s H  o0R                  U5      PM     sn5      $ s  snf )z!Build a built-in delay statement.z4Found a delay instruction acting on classical bits: )
r6  r+   r  r  rm   r  r)   QuantumDelayr5   rS  )r   r  rm   r[   s       rA   r  QASM3Builder.build_delay  s    $F{mT  &&{'<'<'E'E{G\G\GaGabPbPb*cPbu+;+;E+BPb*cdd*cs   8B
c                   Uc  gUS:X  a  U R                  U5      $ US:X  a2  [        R                  " US-  [        R                  R                  5      $ [        R                  R                  [        R                  R
                  [        R                  R                  [        R                  R                  [        R                  R                  S.n[        R                  " XU   5      $ )z;Build the expression of a given duration (if not ``None``).Nr   ps  )nsusmsr   dt)	r  r)   DurationLiteralDurationUnit
NANOSECONDMICROSECONDMILLISECONDSECONDSAMPLE)r   rm   r  unit_maps       rA   r  QASM3Builder.build_duration  s    6>((224<&&x$8H8H8S8STT""--""..""..!!((""))
 ""8d^<<r@   c                    [        U[        R                  5      (       d  [        SU S35      e[        R
                  " [        U5      5      $ )zgBuild an integer literal, raising a :obj:`.QASM3ExporterError` if the input is not
actually an
integer.r   z' is not an integer)r  numbersIntegralr+   r)   r  r3   )r   r  s     rA   r   QASM3Builder.build_integer  sC     %!1!122 %q/B%CDD!!#e*--r@   c                r   [        U[        5      (       d  U$ [        U[        5      (       a%  U R                  R	                  U5      R
                  $ UR                  UR                   Vs0 s H;  nU[        U R                  R	                  U5      R
                  UR                  S9_M=     sn5      $ s  snf )zIf the input is a :class:`.ParameterExpression`, rebind any internal
:class:`.Parameter`\ s so that their names match their names in the scope.  Other inputs
are returned unchanged.)uuid)	r  r   r   r7  r  r   subsr4   rT  )r   
expressionr  s      rA   _rebind_scoped_parameters&QASM3Builder._rebind_scoped_parameters  s     *&9::j),,<<,,Z8??? (222E y!:!:5!A!H!HuzzZZ2
 	
s   +AB4c                    U Vs/ s H(  n[         R                  " U R                  U5      5      PM*     nnU R                  (       d"  U H  n[	        UR
                  SS9Ul        M     U$ s  snf )Nqasm)ra   )r)   StringifyAndPrayrW  rx   r'   obj)r   r4   r  r  s       rA   _build_quantum_call_parameters+QASM3Builder._build_quantum_call_parameters  sg    U_
U_EC  !?!?!FGU_ 	 
 %%'	 (v F	 (
s   /A+c           
        S[         R                  " 5       4nUR                  U;  a2  [        SUR                   SUR                   SUR                   35      eUR                  SLn[        UR                  5      UR                  :w  dE  [        UR                  5      UR                  :w  d"  [        UR                  5      [        U5      :w  a  [        SU< SU< S35      e[        R                  " [        R                  " UR                  5      U R                  UR                  5      UR                   Vs/ s H  oPR                  U5      PM     snU(       a   U R                  UR                  S   5      S	9$ SS	9$ s  snf )
z7Build a statement associated with a defcal instruction.NrV  rW  rX  zInstruction 'zI' has a call signature that is inconsistent with its associated defcal: 'r$  r   )r  r4   r5   r  )r   r_  r6   r+   r2   rG  r5   r  r4   r6  r3   r)   DefcalCallStatementr  r]  rS  )r   r  r^   rk  returns_bitr[   s         rA   r  QASM3Builder.build_defcal_call"  st    !%ejjl3%99$v{{m+UVaVfVfUg h;;A;M;M:NP  ((4 ""#v}}4;%%&&*;*;; ;%%&#k*::$ /,,2:R9  &&..-::;;M;MN9D9K9KL9K$$U+9KL>I4##K$6$6q$9:	
 	
 PT	
 	
 Ms   ;Fc                x   UR                   n[        US5      (       a  UR                  5       nU R                  R	                  U5      nUc  U R                  U5      nUR                   Vs/ s H  o@R                  U5      PM     nnU R                  UR                  5      n[        R                  " X5US9$ s  snf )zBuilds a gate-call AST node.

This will also push the gate into the symbol table (if required), including recursively
defining the gate blocks.

If the operation identifier is found in the symbol table, symbol-resolution will be skipped.
_qasm_decomposition)r4   )r  hasattrrd  r7  r#  r  r5   rS  r]  r  r)   r  )r   r  r  r  r[   r5   r4   s          rA   r  QASM3Builder.build_gate_callA  s      ))	9344!557I%%i0=$$Y/E7B7I7IJ7Ie""5)7IJ889K9KL
""5ZHH Ks   +B7)r9  r8  ry   r~   rw   rx   r}   r   r{   r   r7  )r   r   r5   zIterable[Qubit]r6  zIterable[Clbit])r  r   )rb   r&  )rQ   r   rb   r&  )r  zIterable[Register]rb   zList[ast.AliasStatement])rb   zList[ast.Statement])r  r   rb   zast.BranchingStatement)r  r   rb   zIterable[ast.Statement])r  r   rb   zast.BoxStatement)r  r   rb   zast.WhileLoopStatement)r  r   rb   zast.ForLoopStatement)r  r   rb   zast.Annotation)r   z	expr.Exprrb   zast.Expression)r  r   rb   zast.QuantumDelay)rb   zast.Expression | None)rb   zast.IntegerLiteral)rb   zlist[ast.Expression])r  r   r^   r/   )r  r   )2r9   r:   r;   r<   r=   r   r   r   r   r$   r%   r   builtinsr  r  r  r  r*   r   
contextlibcontextmanagerrM  r   rS  r   rb  r  r  rc  rd  re  rf  r  rg  r  r  r  r  r  r  r5  r  r  r  r   rW  r]  r  r  r?   r7   r@   rA   r   r   w  s   @%^USH!%! *!, U@ ! !. # #B
T/l(A[FD
P$6p"2(hRhH2
h
I<P4c.
Oe=".
"
>Ir@   r   c                   ^ U4S jmT" X5      (       a  g[         R                  " [         R                  R                  [         R                  R
                  U5      $ )a)  Attempt to infer what type a parameter should be declared as to work with a circuit.

This is very simplistic; it assumes all parameters are real numbers that need to be input to the
program, unless one is used as a loop variable, in which case it shouldn't be declared at all,
because the ``for`` loop declares it implicitly (per the Qiskit/qe-compiler reading of the
OpenQASM spec at openqasm/openqasm@8ee55ec).

.. note::

    This is a hack around not having a proper type system implemented in Terra, and really this
    whole function should be removed in favour of proper symbol-table building and lookups.
    This function is purely to try and hack the parameters for ``for`` loops into the exporter
    for now.

Args:
    circuit: The global-scope circuit, which is the base of the exported program.
    parameter: The parameter to infer the type of.
    parameter_name: The name of the parameter to use in the declaration.

Returns:
    A suitable :obj:`.ast.ClassicalDeclaration` node, or, if the parameter should *not* be
    declared, then ``None``.
c                ,  > U R                   R                  U5       Ht  u  p#Uc  M
  U R                  U   R                  n[	        U[
        5      (       a  US:X  a    g[	        U[        5      (       d  MW  T" UR                  U   U5      (       d  Mt    g   g)zRecurse into the instructions a parameter is used in, checking at every level if it is
used as the loop variable of a ``for`` loop.r(   TF)_data_raw_parameter_table_entryr  r  r  r    r#   r  )r   r  instr_indexindexr  is_loop_variables        rA   rp  5_infer_variable_declaration.<locals>.is_loop_variableo  s     #*--"J"J9"UK"!,,{3==K+y11A:+}55#K$6$6u$=yII #V r@   N)r)   r  r  r  	FloatTypeDOUBLE)r   r  r  rp  s      @rA   r  r  T  sC    6( ++ S^^113==3G3GXXr@   c                p    [        U [        R                  5      (       a  U $ [        R                  " U 5      $ r   )r  r   Exprlift_legacy_condition)r  s    rA   r  r    s*    )TYY''%%i00r@   c                   U R                   [        R                  L a  [        R                  " 5       $ U R                   [        R
                  L a   [        R                  " U R                  5      $ U R                   [        R                  L a  [        R                  R                  $ U R                   [        R                  L a  [        R                  " 5       $ [        SU  S35      e)Nzunhandled expr type 'r   )kindr   r_  r)   BoolTypeUintUintTypewidthFloatrr  rs  DurationDurationTyper   )type_s    rA   r  r    s    zzUZZ||~zzUZZ||EKK((zzU[[ }}###zzU^^#!!
.ugQ7
88r@   c                  H    \ rS rSrSrS rS rS rS rS r	S r
S	 rS
 rSrg)r9  i  lookupc                    Xl         g r   r  )r   r  s     rA   r   _ExprBuilder.__init__  s    r@   c               |    UR                   (       a  U R                  U5      $ U R                  UR                  5      $ r   )
standaloner  r  r:  s     rA   	visit_var_ExprBuilder.visit_var  s)    $(OOt{{4 NTXX9NNr@   c               $    U R                  U5      $ r   r  r:  s     rA   visit_stretch_ExprBuilder.visit_stretch  s    {{4  r@   c                  UR                   R                  [        R                  L a   [        R
                  " UR                  5      $ UR                   R                  [        R                  L a   [        R                  " UR                  5      $ UR                   R                  [        R                  L a   [        R                  " UR                  5      $ UR                   R                  [        R                  L Ga  UR                  R                  5       nUS:X  aG  [        R                  " UR                  R                  5       [        R                  R                  5      $ US:X  aJ  [        R                  " UR                  R                  5       S-  [        R                  R                   5      $ US:X  aG  [        R                  " UR                  R                  5       [        R                  R                   5      $ US:X  aG  [        R                  " UR                  R                  5       [        R                  R"                  5      $ US:X  aG  [        R                  " UR                  R                  5       [        R                  R$                  5      $ US:X  aG  [        R                  " UR                  R                  5       [        R                  R&                  5      $ [)        SU S	35      e)
NrE  r@  rA  rB  rC  rD  r   zunhandled Value type 'r   )r  rx  r   r_  r)   BooleanLiteralr  rz  r  r}  FloatLiteralr~  r  rF  rG  rL  rH  rI  rJ  rK  r   )r   r   r  s      rA   visit_value_ExprBuilder.visit_value  s   99>>UZZ'%%djj1199>>UZZ'%%djj1199>>U[[(##DJJ//99>>U^^+::??$Dt|**4::+;+;+=s?O?O?V?VWWt|**4::+;+;+=+DcFVFVFaFabbt|**4::+;+;+=s?O?O?Z?Z[[t|**4::+;+;+=s?O?O?[?[\\t|**4::+;+;+=s?O?O?[?[\\s{**4::+;+;+=s?O?O?V?VWW3D6;<<r@   c                   UR                   (       a  UR                  R                  U 5      $ [        R                  " [        UR                  5      UR                  R                  U 5      5      $ r   )implicitr  r8  r)   Castr  r  r:  s     rA   
visit_cast_ExprBuilder.visit_cast  sG    ==<<&&t,,xx		2DLL4G4G4MNNr@   c                   [         R                  " [         R                  R                  UR                  R                     UR
                  R                  U 5      5      $ r   )r)   UnaryOpopr2   r  r8  r:  s     rA   visit_unary_ExprBuilder.visit_unary  s7    yydggll3T\\5H5H5NOOr@   c                   [         R                  " [         R                  R                  UR                  R                     UR
                  R                  U 5      UR                  R                  U 5      5      $ r   )r)   Binaryr  r  r2   leftr8  rightr:  s     rA   visit_binary_ExprBuilder.visit_binary  sN    zzJJMM$'',,')9)9$)?ARARSWAX
 	
r@   c                   [         R                  " UR                  R                  U 5      UR                  R                  U 5      5      $ r   )r)   Indexr  r8  ro  r:  s     rA   visit_index_ExprBuilder.visit_index  s1    yy++D14::3D3DT3JKKr@   N)r9   r:   r;   r<   	__slots__r   r  r  r  r  r  r  r  r?   r7   r@   rA   r9  r9    s3    IO!=0O
P

Lr@   r9  )rQ   r   rb   r   )r   r   r  r   r  r&  rb   z%Union[ast.ClassicalDeclaration, None])r  z
types.Typerb   zast.ClassicalType)yr=   
__future__r   rh  dataclassesr   r   r  rP  retypingr   r   r   r   qiskit._accelerate.circuitr	   qiskit.circuitr
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   qiskit.circuit.annotationr   r   qiskit.circuit.classicalr   r   qiskit.circuit.controlflowr   r   r    r!   r"   r#   r$   r%   r&   qiskit.circuit.toolsr'    r)   r}   r*   
exceptionsr+   printerr,   	dataclassr/   	frozensetr   compileru   r   r   r   rr   _FIXED_PARAMETERS	all_gatesr)  
gate_class
num_paramsr+  r  num_ctrl_qubitsr*  PhaseXYZHSSdgTTdgSXRXRYRZr   CYCZCPhaseCRXCRYCRZCHSwapCCXCSwapCUIU1U2U3rt  r]  r   r   r  r.  r   r  r  r  ExprVisitor
Expressionr9  )r,  r   s   00rA   <module>r     se    "   	    	 2 2 3    $ K 0
 
 
 *  . * ! d#4 4 $4t 02 n  "zz*:"$$G 

:RTT: ZZ
"$$? \
 \
D t_ioy	RVX  !**,,&& MH!!#45Jx7J7J#KLL,  !**,(
 -""HX%=%= =>>J 	./D1D1DE]R\]>  -( $  !&|'9'9:!&|~~6! 	&|~~6! 	&|~~6	!
 	&|~~6! 	&|~~6! 	()9)9:! 	&|~~6! 	()9)9:! 	'8! 	'8! 	'8! 	'8! 	2<??CAF! 	2<??CAF!  	2<??CAF!!" 	2<3F3FGJ#!$ 4L4D4DEaH3L4D4DEaH3L4D4DEaH2<??CAF),*;*;<3L4D4DEaH5l6H6HI!L2<??CAF2<??CAF*<+=+=>6|7J7JKAN'7'8'8'8A!#L 	"<>>	2
 F F F i8 i8X0 8 8 8ZI ZIz3Y3Y(13YCQ3Y*3Yl1	97L4##CNN3 7L#(s*   R++ R+"R5;R5)R0<R50R5