
    z	ivJ                    4   S r SSKJr  SSKrSSKrSSKrSSKJr  SSK	J
r
  SSKJr  SSKJr  SSK	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Jr  \R8                  (       a  SSK	JrJr  / \" \
R>                  SSS5      P\" \
R@                  SSS5      P\" \
RB                  SSS5      P\" \
RD                  SSS5      P\" \
RF                  SSS5      P\" \
RH                  SSS5      P\" \
RJ                  SSS5      P\" \
RL                  SSS5      P\" \
RN                  SSS5      P\" \
RP                  SSS5      P\" \
RR                  SSS5      P\" \
RT                  SSS5      P\" \
RV                  SSS5      P\" \
RX                  SSS	5      P\" \
RZ                  SSS	5      P\" \
R\                  SSS	5      P\" \
R^                  S SS	5      P\" \
R`                  S!SS	5      P\" \
Rb                  S"SS	5      P\" \
Rd                  S#SS	5      P\" \
Rf                  S$SS	5      P\" \
Rh                  S%SS	5      P\" \
Rj                  S&SS'5      P\" \
Rl                  S(SS'5      P\" \
Rn                  S)S*S	5      P\" \
RX                  S+SS	5      P\" \
R>                  S,SS5      P\" \
R^                  S-SS	5      P\" \
Rp                  S.SS5      P\" \
Rr                  S/SS5      P\" \
Rt                  S0S	S5      P\" \
Rv                  S1S'S5      P7r<SAS2 jr=SBS3 jr>\R~                  R                  S45      SSS5.       SCS6 jj5       rA\R~                  R                  S45      SSS5.       SDS7 jj5       rB\R                  " \R                  5      SSS8.S9 j5       rD\R                  " \R                  5      SSS8.S: j5       rE\R                  " \Rz                  5      SSS;S<S<S=S>.S? j5       rF\R                  " \R|                  5      SSS;S<S<S=S>.S@ j5       rGg)Ea  
================================
OpenQASM 3 (:mod:`qiskit.qasm3`)
================================

.. currentmodule:: qiskit.qasm3

Qiskit provides some tools for converting between `OpenQASM 3 <https://openqasm.com>`__
representations of quantum programs, and the :class:`.QuantumCircuit` class.  These will continue to
evolve as Qiskit's support for the dynamic-circuit capabilities expressed by OpenQASM 3 increases.


Exporting to OpenQASM 3
=======================

The high-level functions are simply :func:`dump` and :func:`dumps`, which respectively export to a
file (given as a filename) and to a Python string.

.. autofunction:: dump
.. autofunction:: dumps

Both of these exporter functions are single-use wrappers around the main :class:`Exporter` class.
For more complex exporting needs, including dumping multiple circuits in a single session, it may be
more convenient or faster to use the complete interface.

.. autoclass:: Exporter
    :members:

All of these interfaces will raise :exc:`QASM3ExporterError` on failure.

.. autoexception:: QASM3ExporterError

Experimental features
---------------------

The OpenQASM 3 language is still evolving as hardware capabilities improve, so there is no final
syntax that Qiskit can reliably target.  In order to represent the evolving language, we will
sometimes release features before formal standardization, which may need to change as the review
process in the OpenQASM 3 design committees progresses.  By default, the exporters will only support
standardised features of the language.  To enable these early-release features, use the
``experimental`` keyword argument of :func:`dump` and :func:`dumps`.  The available feature flags
are:

.. autoclass:: ExperimentalFeatures
    :members:

If you want to enable multiple experimental features, you should combine the flags using the ``|``
operator, such as ``flag1 | flag2``.

For example, to perform an export using the early semantics of ``switch`` support:

.. plot::
    :include-source:
    :nofigs:

    from qiskit import qasm3, QuantumCircuit, QuantumRegister, ClassicalRegister

    # Build the circuit
    qreg = QuantumRegister(3)
    creg = ClassicalRegister(3)
    qc = QuantumCircuit(qreg, creg)
    with qc.switch(creg) as case:
        with case(0):
            qc.x(0)
        with case(1, 2):
            qc.x(1)
        with case(case.DEFAULT):
            qc.x(2)

    # Export to an OpenQASM 3 string.
    qasm_string = qasm3.dumps(qc, experimental=qasm3.ExperimentalFeatures.SWITCH_CASE_V1)


.. note::

    All features enabled by the experimental flags are naturally transient.  If it becomes necessary
    to remove flags, they will be subject to `the standard Qiskit deprecation policy
    <https://github.com/Qiskit/qiskit/blob/main/DEPRECATION.md>`__.  We will leave these experimental
    flags in place for as long as is reasonable.

    However, we cannot guarantee any support windows for *consumers* of OpenQASM 3 code generated
    using these experimental flags, if the OpenQASM 3 language specification changes the proposal
    that the flag is based on.  It is possible that any tool you are using to consume OpenQASM 3
    code created using these flags may update or remove their support while Qiskit continues to
    offer the flag.  You should not rely on the resultant experimental OpenQASM 3 code for long-term
    storage of programs.


Importing from OpenQASM 3
=========================

Currently only two high-level functions are offered, as Qiskit support for importing from OpenQASM 3
is in its infancy, and the implementation is expected to change significantly.  The two functions
are :func:`load` and :func:`loads`, which are direct counterparts of :func:`dump` and :func:`dumps`,
respectively loading a program indirectly from a named file and directly from a given string.

.. note::

    While we are still in the exploratory release period, to use either function, the package
    ``qiskit_qasm3_import`` must be installed.  This can be done by installing Qiskit with the
    ``qasm3-import`` extra, such as by:

    .. code-block:: text

        pip install qiskit[qasm3-import]

    We expect that this functionality will eventually be merged into Qiskit, and no longer
    require an optional import, but we do not yet have a timeline for this.

.. autofunction:: load
.. autofunction:: loads

Both of these two functions raise :exc:`QASM3ImporterError` on failure.

.. autoexception:: QASM3ImporterError

For example, we can define a quantum program using OpenQASM 3, and use :func:`loads` to directly
convert it into a :class:`.QuantumCircuit`:

.. plot::
    :alt: Circuit diagram output by the previous code.
    :include-source:

    import qiskit.qasm3

    program = """
        OPENQASM 3.0;
        include "stdgates.inc";

        input float[64] a;
        qubit[3] q;
        bit[2] mid;
        bit[3] out;

        let aliased = q[0:1];

        gate my_gate(a) c, t {
          gphase(a / 2);
          ry(a) c;
          cx c, t;
        }
        gate my_phase(a) c {
          ctrl @ inv @ gphase(a) c;
        }

        my_gate(a * 2) aliased[0], q[{1, 2}][0];
        measure q[0] -> mid[0];
        measure q[1] -> mid[1];

        while (mid == "00") {
          reset q[0];
          reset q[1];
          my_gate(a) q[0], q[1];
          my_phase(a - pi/2) q[1];
          mid[0] = measure q[0];
          mid[1] = measure q[1];
        }

        if (mid[0]) {
          let inner_alias = q[{0, 1}];
          reset inner_alias;
        }

        out = measure q;
    """
    circuit = qiskit.qasm3.loads(program)
    circuit.draw("mpl")


Experimental import interface
-----------------------------

The import functions given above rely on the ANTLR-based reference parser from the OpenQASM project
itself, which is more intended as a language reference than a performant parser.  You need to have
the extension ``qiskit-qasm3-import`` installed to use it.

Qiskit is developing a native parser, written in Rust, which is available as part of the core Qiskit
package.  This parser is still in its early experimental stages, so is missing features and its
interface is changing and expanding, but it is typically orders of magnitude more performant for the
subset of OpenQASM 3 it currently supports, and its internals produce better error diagnostics on
parsing failures.

You can use the experimental interface immediately, with similar functions to the main interface
above:

.. autofunction:: load_experimental
.. autofunction:: loads_experimental

These two functions are both experimental, meaning they issue an :exc:`.ExperimentalWarning` on
usage, and their interfaces may be subject to change within the Qiskit 1.x release series.  In
particular, the native parser may be promoted to be the default version of :func:`load` and
:func:`loads`.  If you are happy to accept the risk of using the experimental interface, you can
disable the warning by doing::

    import warnings
    from qiskit.exceptions import ExperimentalWarning

    warnings.filterwarnings("ignore", category=ExperimentalWarning, module="qiskit.qasm3")

These two functions allow for specifying include paths as an iterable of paths, and for specifying
custom Python constructors to use for particular gates.  These custom constructors are specified by
using the :class:`CustomGate` object:

.. autoclass:: CustomGate
    :members:

In ``custom_gates`` is not given, Qiskit will attempt to use its standard-library gate objects for
the gates defined in OpenQASM 3 standard library file ``stdgates.inc``.  This sequence of gates is
available on this module, if you wish to build on top of it:

.. py:data:: STDGATES_INC_GATES

    A tuple of :class:`CustomGate` objects specifying the Qiskit constructors to use for the
    ``stdgates.inc`` include file.
    )annotationsN)qasm3)library)ExperimentalWarning)	optionals)Qubit   )
CustomGate   )
QASM3ErrorQASM3ExporterErrorQASM3ImporterError)ExperimentalFeatures)ExporterDefcalInstruction)
annotationQuantumCircuit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u3c                6    [        S0 UD6R                  U 5      $ )zSerialize a :class:`~qiskit.circuit.QuantumCircuit` object in an OpenQASM 3 string.

Args:
    circuit (QuantumCircuit): Circuit to serialize.
    **kwargs: Arguments for the :obj:`.Exporter` constructor.

Returns:
    str: The OpenQASM 3 serialization
 )r   dumps)circuitkwargss     O/home/james-whalen/.local/lib/python3.13/site-packages/qiskit/qasm3/__init__.pyr8   r8     s     f##G,,    c                8    [        S0 UD6R                  X5        g)a3  Serialize a :class:`~qiskit.circuit.QuantumCircuit` object as an OpenQASM 3 stream to
file-like object.

Args:
    circuit (QuantumCircuit): Circuit to serialize.
    stream (TextIOBase): stream-like object to dump the OpenQASM 3 serialization
    **kwargs: Arguments for the :obj:`.Exporter` constructor.

Nr7   )r   dump)r9   streamr:   s      r;   r>   r>   *  s     vG,r<   zloading from OpenQASM 3
num_qubitsannotation_handlersc                   [        U S5       nUR                  5       nSSS5        [        WXS9$ ! , (       d  f       N= f)a  Load an OpenQASM 3 program from the file ``filename``.

Args:
    filename: the filename to load the program from.
    num_qubits: keyword argument which provides number of physical/virtual qubits.
    annotation_handlers: a mapping whose keys are (parent) namespaces and values are serializers
        that can handle children of those namesapces.  Requires ``qiskit_qasm3_import>=0.6.0``.
Returns:
    QuantumCircuit: a circuit representation of the OpenQASM 3 program.

Raises:
    QASM3ImporterError: if the OpenQASM 3 file is invalid, or cannot be represented by a
        :class:`.QuantumCircuit`.

.. versionadded:: 2.1
    The ``annotation_handlers`` argument.  This requires ``qiskit_qasm3_import>=0.6.0``.
rNr@   )openreadloads)filenamerA   rB   fptrprograms        r;   loadrK   7  s6    2 
h	))+ 
ZYY 
	s   0
>c                  SSK n0 nUb-  [        USS5      S:  a  [        SUR                  -   5      eX$S'    UR                  " U 40 UD6nUGbl  UR                  U:  a  [        S5      eXR                  -
  =nS:  Ga<  UR                  b  UR                  Ssol
        [        UR                  R                  5       R                  5       S	S
9n	[        U	S-   U5       H'  n
UR                  R!                  [#        5       U
5        M)     0 n[        U	S-   U5       H  nXUR                  U   '   M     UR$                  R'                  U5        UR)                  [        U5       Vs/ s H  n[#        5       PM     sn5        Xl
        U$ UR)                  [        U5       Vs/ s H  n[#        5       PM     sn5        U$ ! UR
                   a  n[        [        U5      5      UeSnAff = fs  snf s  snf )a[  Load an OpenQASM 3 program from the given string.

Examples:

    Load a OpenQASM3 string into a quantum circuit with/without `num_qubits` argument.

    .. plot::
       :alt: Circuit diagram output by the previous code.
       :include-source:

       from qiskit import qasm3

       # An OpenQASM 3 program that only uses 2 physical qubits.
       prog = '''
           OPENQASM 3.0;
           include "stdgates.inc";
           h $0;
           cx $0, $1;
       '''
       # The importer can be supplied with the number of qubits in the target backend.
       # so the result is full width.
       qc = qasm3.loads(prog, num_qubits=5)
       assert qc.num_qubits == 5

Args:
    program: the OpenQASM 3 program.
    num_qubits: provides number of physical/virtual qubits.
    annotation_handlers: a mapping whose keys are (parent) namespaces and values are serializers
        that can handle children of those namesapces.  Requires ``qiskit_qasm3_import>=0.6.0``.
Returns:
    QuantumCircuit: a circuit representation of the OpenQASM 3 program.

Raises:
    QASM3ImporterError: if the OpenQASM 3 file is invalid, or cannot be represented by a
        :class:`.QuantumCircuit`.
    ValueError: if number of qubits in qasm3_ckt is more than num_qubits.

.. versionadded:: 2.1
    The ``annotation_handlers`` argument.  This requires ``qiskit_qasm3_import>=0.6.0``.
r   NVERSION_PARTS)r   r   )r      zFneed 'qiskit_qasm3_import>=0.6.0' to handle annotations, but you have rB   zTNumber of qubits cannot be more than the provided number of physical/virtual qubits.)defaultr   )qiskit_qasm3_importgetattrr   __version__parseConversionErrorstrrA   
ValueErrorlayout_layoutmaxinitial_layoutget_physical_bitskeysrangeaddr   input_qubit_mappingupdateadd_bits)rJ   rA   rB   rQ   r:   	qasm3_cktexc
differencerX   lastkmapping_dictii_s                 r;   rG   rG   U  s   ` F&&@6I$X%112  )<$%4'--g@@	 *,f  %';';;;Jq@+,5,=,=t)) 600BBDIIKUWXtax4A))--egq9 5  "q*5B>@!6!6r!:; 6**11,? ""U:5F#G5FEG5F#GH %+!  ""U:5F#G5FEG5F#GHE .. 4 S*342 $H $Hs#   F= %G* G/=G'G""G'custom_gatesinclude_pathc              ^    [         R                  " S[        S9  [        R                  " XUS9$ <overridden by functools.wraps>zThis is an experimental native version of the OpenQASM 3 importer. Beware that its interface might change, and it might be missing features.categoryrk   )warningswarnr   _qasm3rG   )sourcerl   rm   s      r;   loads_experimentalrw     s,     MM	U$
 <<UUr<   c              ^    [         R                  " S[        S9  [        R                  " XUS9$ ro   )rs   rt   r   ru   rK   )pathlike_or_filelikerl   rm   s      r;   load_experimentalrz     s.     MM	U$
 ;;+Uabbr<   TFz  includesbasis_gatesdisable_constantsalias_classical_registersallow_aliasingindentc          
         [         R                  " S[        S9  Uc  S/nUc  S/n[        R                  " U UUUUUUS.5      $ rp   zThis is an experimental version of serialization of a :class:`~qiskit.circuit.QuantumCircuit` object in an OpenQASM 3 string. Beware that its interface might change, and it might be missing features.rq   zstdgates.incUr{   )rs   rt   r   ru   r8   )r9   r|   r}   r~   r   r   r   s          r;   dumps_experimentalr     sc     MM	U %	 "#e<< &!2)B,	

 
r<   c                   [         R                  " S[        S9  Uc  S/nUc  S/n[        R                  " U UUUUUUUS.5      $ r   )rs   rt   r   ru   r>   )r9   r?   r|   r}   r~   r   r   r   s           r;   dump_experimentalr     sf     MM	U %	 "#e;; &!2)B,	
 r<   )returnrV   )r   None)rH   rV   rA   
int | NonerB   0dict[str, annotation.OpenQASM3Serializer] | Noner   r   )rJ   rV   rA   r   rB   r   r   r   )H__doc__
__future__r   	functoolstypingrs   qiskit._accelerater   ru   qiskit.circuitr   qiskit.exceptionsr   qiskit.utilsr   
_optionalsr   _accelerate.qasm3r
   
exceptionsr   r   r   experimentalr   exporterr   r   TYPE_CHECKINGr   r   	PhaseGateXGateYGateZGateHGateSGateSdgGateTGateTdgGateSXGateRXGateRYGateRZGateCXGateCYGateCZGate
CPhaseGateCRXGateCRYGateCRZGateCHGateSwapGateCCXGate	CSwapGateCUGateIGateU1GateU2GateU3GateSTDGATES_INC_GATESr8   r>   HAS_QASM3_IMPORTrequire_in_callrK   rG   wrapsrw   rz   r   r   r7   r<   r;   <module>r      s  Vp #    . " 1 0   * J J . 1	9!w  #q!,!w}}c1a(! w}}c1a(! w}}c1a(	!
 w}}c1a(! w}}c1a(! wq!,! w}}c1a(! wq!,! w~~tQ*! w~~tQ*! w~~tQ*! w~~tQ*! w~~tQ*! w~~tQ*!  w~~tQ*!!" w!!4A.#!$ wq!,%!& wq!,'!( wq!,)!* w~~tQ*+!, wA.-!. wq!,/!0 w  '1a01!2 w~~tQ*3!4 w~~tQ*5!6 w  '1a07!8 w!!8Q29!: w}}dAq);!< w~~tQ*=!> w~~tQ*?!@ w~~tQ*A! H
-
- ,,-FG "LP	ZZ Z J	Z
 Z HZ: ,,-FG "LP	^^ ^ J	^
 ^ H^B 26T V V ?CRV c c  # D 
 #" "r<   