{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "35492576-b15e-43e6-8b9b-293631c6b194",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"OpenQASM 2 e o Qiskit SDK\"\n",
        "description: \"Como converter código entre o OpenQASM 2 e o Qiskit SDK.\"\n",
        "---\n",
        "\n",
        "<span id=\"openqasm-2-and-the-qiskit-sdk\" />\n",
        "\n",
        "# OpenQASM 2 e o Qiskit SDK\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "f1330cdd-036e-4a99-b2d1-0348a4d70cb3",
      "metadata": {
        "tags": [
          "version-info"
        ]
      },
      "source": [
        "{/*\n",
        "  DO NOT EDIT THIS CELL!!!\n",
        "  This cell's content is generated automatically by a script. Anything you add\n",
        "  here will be removed next time the notebook is run. To add new content, create\n",
        "  a new cell before or after this one.\n",
        "  */}\n",
        "\n",
        "<Accordion>\n",
        "  <AccordionItem title=\"Versões do pacote\">\n",
        "    O código desta página foi desenvolvido usando os seguintes requisitos.\n",
        "    Recomendamos o uso dessas versões ou de versões mais recentes.\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.0\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "328f6a16-5ec4-4d80-8507-f5d97aa02f26",
      "metadata": {},
      "source": [
        "O Qiskit SDK fornece algumas ferramentas para conversão entre OpenQASM representações de programas quânticos e a classe [QuantumCircuit](/docs/api/qiskit/qiskit.circuit.QuantumCircuit) classe.\n",
        "\n",
        "<span id=\"qasm2-import\" />\n",
        "\n",
        "<span id=\"import-an-openqasm-2-program-into-qiskit\" />\n",
        "\n",
        "## Importar um programa OpenQASM 2 para o Qiskit\n",
        "\n",
        "Duas funções importam programas do OpenQASM 2 para o Qiskit.\n",
        "Esses são [`qasm2.load()`](../api/qiskit/qasm2#load), que recebe um nome de arquivo, e [`qasm2.loads()`](../api/qiskit/qasm2#loads), que recebe o programa OpenQASM 2 como uma cadeia de caracteres.\n",
        "\n",
        "```python\n",
        "import qiskit.qasm2\n",
        "\n",
        "qiskit.qasm2.load(filename, include_path=('.',), include_input_directory='append', custom_instructions=(), custom_classical=(), strict=False)\n",
        "qiskit.qasm2.loads(program, include_path=('.',), custom_instructions=(), custom_classical=(), strict=False)\n",
        "```\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "52d909cd-6332-46a3-9a1a-330e1c4a66cf",
      "metadata": {},
      "source": [
        "Consulte a [API do Qiskit OpenQASM 2](/docs/api/qiskit/qasm2) para obter mais informações.\n",
        "\n",
        "<span id=\"import-simple-programs\" />\n",
        "\n",
        "### Importar programas simples\n",
        "\n",
        "Para a maioria dos programas do OpenQASM 2, basta usar `qasm2.load` e `qasm2.loads` com um único argumento.\n",
        "\n",
        "<span id=\"example-import-an-openqasm-2-program-as-a-string\" />\n",
        "\n",
        "#### Exemplo: importar um programa OpenQASM 2 como uma string\n",
        "\n",
        "Use o site `qasm2.loads()` para importar um programa OpenQASM 2 como uma string para um arquivo QuantumCircuit:\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "id": "f7d62945-1899-4b39-acee-6aaf6b37db09",
      "metadata": {},
      "outputs": [
        {
          "data": {
            "text/plain": [
              "     ┌───┐     ┌─┐   \n",
              "q_0: ┤ H ├──■──┤M├───\n",
              "     └───┘┌─┴─┐└╥┘┌─┐\n",
              "q_1: ─────┤ X ├─╫─┤M├\n",
              "          └───┘ ║ └╥┘\n",
              "c: 2/═══════════╩══╩═\n",
              "                0  1 "
            ]
          },
          "execution_count": 1,
          "metadata": {},
          "output_type": "execute_result"
        }
      ],
      "source": [
        "import qiskit.qasm2\n",
        "\n",
        "program = \"\"\"\n",
        "    OPENQASM 2.0;\n",
        "    include \"qelib1.inc\";\n",
        "    qreg q[2];\n",
        "    creg c[2];\n",
        "\n",
        "    h q[0];\n",
        "    cx q[0], q[1];\n",
        "\n",
        "    measure q -> c;\n",
        "\"\"\"\n",
        "circuit = qiskit.qasm2.loads(program)\n",
        "circuit.draw()"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "6556b10e-7d15-4c51-a917-a969a23babff",
      "metadata": {},
      "source": [
        "<span id=\"example-import-an-openqasm-2-program-from-a-file\" />\n",
        "\n",
        "#### Exemplo: importar um programa OpenQASM 2 de um arquivo\n",
        "\n",
        "Use o site `load()` para importar um programa OpenQASM 2 de um arquivo para um arquivo QuantumCircuit:\n",
        "\n",
        "```python\n",
        "import qiskit.qasm2\n",
        "circuit = qiskit.qasm2.load(\"myfile.qasm\")\n",
        "```\n",
        "\n",
        "<span id=\"custom-instructions\" />\n",
        "\n",
        "<span id=\"link-openqasm-2-gates-with-qiskit-gates\" />\n",
        "\n",
        "### Link OpenQASM 2 portas com portas Qiskit\n",
        "\n",
        "Por padrão, o importador OpenQASM 2 do Qiskit trata o arquivo de inclusão `\"qelib1.inc\"` como uma biblioteca padrão *de fato*.\n",
        "O importador trata esse arquivo como contendo exatamente as portas descritas no [documento original que define OpenQASM 2](https://arxiv.org/abs/1707.03429).\n",
        "O Qiskit usará as portas integradas na [biblioteca de circuitos](../api/qiskit/circuit_library) para representar as portas em `\"qelib1.inc\"`.\n",
        "As portas definidas no programa pelo manual OpenQASM 2 `gate` declarações serão, por padrão, construídas como [Qiskit `Gate` subclasses](../api/qiskit/qiskit.circuit.Gate) personalizadas.\n",
        "\n",
        "Você pode instruir o importador a usar classes [`Gate`](../api/qiskit/qiskit.circuit.Gate) específicas para as declarações `gate` que ele encontrar.\n",
        "Você também pode usar esse mecanismo para tratar nomes de portas adicionais como \"incorporados\", ou seja, que não exigem uma definição explícita.\n",
        "Se você especificar quais classes de porta usar para as instruções `gate` fora de `\"qelib1.inc\"`, o circuito resultante normalmente será mais eficiente para trabalhar.\n",
        "\n",
        "<Admonition type=\"warning\">\n",
        "  A partir de Qiskit SDKv1.0, *o exportador* OpenQASM 2 do Qiskit (consulte [Exportar um circuito Qiskit para OpenQASM 2](#qasm2-export) ) ainda se comporta como se `\"qelib1.inc\"` tivesse mais portas do que realmente tem.\n",
        "  Isso significa que as configurações padrão do importador podem não ser capazes de importar um programa exportado pelo nosso importador.\n",
        "  Veja [o exemplo específico sobre como trabalhar com o exportador legado](#qasm2-import-legacy) para resolver esse problema.\n",
        "\n",
        "  Essa discrepância é um comportamento herdado do Qiskit e [será resolvida em uma versão posterior do Qiskit](https://github.com/Qiskit/qiskit/issues/10737).\n",
        "</Admonition>\n",
        "\n",
        "Para passar informações sobre uma instrução personalizada para o importador do OpenQASM 2, use [a classe `qasm2.CustomInstruction` ](../api/qiskit/qasm2#qiskit.qasm2.CustomInstruction).\n",
        "Ele contém quatro informações obrigatórias, em ordem:\n",
        "\n",
        "* O **nome** do portão, usado no programa OpenQASM 2\n",
        "* O **número de parâmetros de ângulo** que a porta usa\n",
        "* O **número de qubits** em que a porta atua\n",
        "* A classe ou função **do construtor** Python para a porta, que recebe os parâmetros da porta (mas não os qubits) como argumentos individuais\n",
        "\n",
        "Se o importador encontrar uma definição de `gate` que corresponda a uma determinada instrução personalizada, ele usará essas informações personalizadas para reconstruir o objeto de porta.\n",
        "Se for encontrada uma instrução `gate` que corresponda ao `name` de uma instrução personalizada, mas que não corresponda ao número de parâmetros e ao número de qubits, o importador exibirá um [`QASM2ParseError`](../api/qiskit/qasm2#qasm2parseerror)para indicar a incompatibilidade entre as informações fornecidas e o programa.\n",
        "\n",
        "Além disso, um quinto argumento `builtin` pode ser opcionalmente definido como `True` para tornar a porta automaticamente disponível no programa OpenQASM 2, mesmo que não esteja explicitamente definida.\n",
        "Se o importador encontrar uma definição explícita do `gate` para uma instrução personalizada incorporada, ele a aceitará silenciosamente.\n",
        "Como antes, se uma definição explícita com o mesmo nome não for compatível com a instrução personalizada fornecida, será gerado um [`QASM2ParseError`](../api/qiskit/qasm2#qasm2parseerror) será gerado.\n",
        "Isso é útil para a compatibilidade com exportadores antigos do OpenQASM 2 e com algumas outras plataformas quânticas que tratam as \"portas básicas\" do hardware como instruções integradas.\n",
        "\n",
        "O Qiskit fornece um atributo de dados para trabalhar com programas OpenQASM 2 produzidos por versões antigas dos [recursos de exportação OpenQASM 2 do Qiskit](#qasm2-export).\n",
        "Isso é [`qasm2.LEGACY_CUSTOM_INSTRUCTIONS`](../api/qiskit/qasm2#legacy-compatibility)que pode ser fornecido como o argumento `custom_instructions` para [`qasm2.load()`](../api/qiskit/qasm2#load) e [`qasm2.loads()`](../api/qiskit/qasm2#loads).\n",
        "\n",
        "<span id=\"qasm2-import-legacy\" />\n",
        "\n",
        "<span id=\"example-import-a-program-created-by-qiskits-legacy-exporter\" />\n",
        "\n",
        "#### Exemplo: importar um programa criado pelo exportador legado do Qiskit\n",
        "\n",
        "Esse programa OpenQASM 2 usa portas que não estão na versão original do `\"qelib1.inc\"` sem declará-las, mas são portas padrão na biblioteca do Qiskit.\n",
        "Você pode usar [`qasm2.LEGACY_CUSTOM_INSTRUCTIONS`](../api/qiskit/qasm2#legacy-compatibility) para dizer facilmente ao importador para usar o mesmo conjunto de portas que o exportador OpenQASM 2 do Qiskit usou anteriormente.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "id": "a4b52b96-1b2d-48bb-8aa4-bd413aa3acea",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit import qasm2\n",
        "\n",
        "program = \"\"\"\n",
        "    OPENQASM 2.0;\n",
        "    include \"qelib1.inc\";\n",
        "\n",
        "    qreg q[4];\n",
        "    creg c[4];\n",
        "\n",
        "    h q[0];\n",
        "    cx q[0], q[1];\n",
        "\n",
        "    // 'rxx' is not actually in `qelib1.inc`,\n",
        "    // but Qiskit used to behave as if it were.\n",
        "    rxx(0.75) q[2], q[3];\n",
        "\n",
        "    measure q -> c;\n",
        "\"\"\"\n",
        "circuit = qasm2.loads(\n",
        "    program,\n",
        "    custom_instructions=qasm2.LEGACY_CUSTOM_INSTRUCTIONS,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "0de0c75d-3890-4138-a994-e8dcf728d7f3",
      "metadata": {},
      "source": [
        "<span id=\"example-use-a-particular-gate-class-when-importing-an-openqasm-2-program\" />\n",
        "\n",
        "#### Exemplo: use uma classe de porta específica ao importar um programa OpenQASM 2\n",
        "\n",
        "O Qiskit não pode, em geral, verificar se a definição em uma declaração OpenQASM 2 `gate` corresponde exatamente a uma porta da biblioteca padrão do Qiskit.\n",
        "Em vez disso, a Qiskit escolhe um portão personalizado usando a definição precisa fornecida.\n",
        "Isso pode ser menos eficiente do que usar uma das portas padrão integradas ou uma porta personalizada definida pelo usuário.\n",
        "Você pode definir manualmente as declarações `gate` com classes específicas.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "id": "73432f4a-c5c1-4cec-ba5d-85ad4787ef52",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit import qasm2\n",
        "from qiskit.circuit import Gate\n",
        "from qiskit.circuit.library import RZXGate\n",
        "\n",
        "\n",
        "# Define a custom gate that takes one qubit and two angles.\n",
        "class MyGate(Gate):\n",
        "    def __init__(self, theta, phi):\n",
        "        super().__init__(\"my\", 1, [theta, phi])\n",
        "\n",
        "\n",
        "custom_instructions = [\n",
        "    # Link the OpenQASM 2 name 'my' with our custom gate.\n",
        "    qasm2.CustomInstruction(\"my\", 2, 1, MyGate),\n",
        "    # Link the OpenQASM 2 name 'rzx' with Qiskit's\n",
        "    # built-in RZXGate.\n",
        "    qasm2.CustomInstruction(\"rzx\", 1, 2, RZXGate),\n",
        "]\n",
        "\n",
        "program = \"\"\"\n",
        "    OPENQASM 2.0;\n",
        "\n",
        "    gate my(theta, phi) q {\n",
        "        U(theta / 2, phi, -theta / 2) q;\n",
        "    }\n",
        "    gate rzx(theta) a, b {\n",
        "        // It doesn't matter what definition is\n",
        "        // supplied, if the parameters match;\n",
        "        // Qiskit will still use `RZXGate`.\n",
        "    }\n",
        "\n",
        "    qreg q[2];\n",
        "    my(0.25, 0.125) q[0];\n",
        "    rzx(pi) q[0], q[1];\n",
        "\"\"\"\n",
        "\n",
        "circuit = qasm2.loads(\n",
        "    program,\n",
        "    custom_instructions=custom_instructions,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "eb78c9cc-e600-4be0-8616-b9bc5ddad511",
      "metadata": {},
      "source": [
        "<span id=\"example-define-a-new-built-in-gate-in-an-openqasm-2-program\" />\n",
        "\n",
        "#### Exemplo: definir um novo gate integrado em um programa OpenQASM 2\n",
        "\n",
        "Se o argumento `builtin=True` for definido, um portão personalizado não precisará ter uma definição associada.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "id": "c37eb527-bed0-4c62-8404-f79e49d42318",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit import qasm2\n",
        "from qiskit.circuit import Gate\n",
        "\n",
        "\n",
        "# Define a custom gate that takes one qubit and two angles.\n",
        "class MyGate(Gate):\n",
        "    def __init__(self, theta, phi):\n",
        "        super().__init__(\"my\", 1, [theta, phi])\n",
        "\n",
        "\n",
        "custom_instructions = [\n",
        "    qasm2.CustomInstruction(\"my\", 2, 1, MyGate, builtin=True),\n",
        "]\n",
        "\n",
        "program = \"\"\"\n",
        "    OPENQASM 2.0;\n",
        "    qreg q[1];\n",
        "\n",
        "    my(0.25, 0.125) q[0];\n",
        "\"\"\"\n",
        "\n",
        "circuit = qasm2.loads(\n",
        "    program,\n",
        "    custom_instructions=custom_instructions,\n",
        ")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4145ce48-0001-42e2-be5e-83c2e31f0fd9",
      "metadata": {},
      "source": [
        "<span id=\"custom-classical\" />\n",
        "\n",
        "<span id=\"define-custom-classical-functions\" />\n",
        "\n",
        "### Defina funções clássicas personalizadas\n",
        "\n",
        "OpenQASM 2 inclui algumas funções clássicas incorporadas para uso em argumentos de porta.\n",
        "Você pode estender a linguagem com mais funções usando o argumento `custom_classical` para [`qasm2.load()`](../api/qiskit/qasm2#load) e [`qasm2.loads()`](../api/qiskit/qasm3#loads)com a classe [`qasm2.CustomClassical`](../api/qiskit/qasm2#qiskit.qasm2.CustomClassical) classe.\n",
        "\n",
        "Para definir uma função clássica personalizada, você deve fornecer:\n",
        "\n",
        "* O *nome* da função como aparece no programa OpenQASM 2\n",
        "* O número de argumentos de ponto flutuante que ele aceita\n",
        "* Um objeto Python chamável que avalia a função\n",
        "\n",
        "Todas as funções clássicas personalizadas definidas são tratadas como incorporadas à linguagem OpenQASM 2 pelo importador.\n",
        "Não há uma maneira oficial na linguagem OpenQASM 2 de definir novas funções; essa é uma extensão do Qiskit.\n",
        "\n",
        "<span id=\"example-use-custom-classical-instructions\" />\n",
        "\n",
        "#### Exemplo: use instruções clássicas personalizadas\n",
        "\n",
        "Aqui fornecemos duas funções clássicas personalizadas.\n",
        "O primeiro é simples e apenas adiciona um à sua entrada.\n",
        "A segunda é a função `math.atan2`, que representa a operação matemática $\\arctan(y/x)$ de forma sensível ao quadrante.\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "id": "b135de19-4b54-4820-8f9d-84a42494debe",
      "metadata": {},
      "outputs": [],
      "source": [
        "import math\n",
        "from qiskit import qasm2\n",
        "\n",
        "program = \"\"\"\n",
        "    include \"qelib1.inc\";\n",
        "    qreg q[2];\n",
        "    rx(arctan(pi, 3 + add_one(0.2))) q[0];\n",
        "    cx q[0], q[1];\n",
        "\"\"\"\n",
        "\n",
        "\n",
        "def add_one(x):\n",
        "    return x + 1\n",
        "\n",
        "\n",
        "customs = [\n",
        "    # Our `add_one` takes only one parameter.\n",
        "    qasm2.CustomClassical(\"add_one\", 1, add_one),\n",
        "    # `arctan` takes two parameters, and `math.atan2` implements it.\n",
        "    qasm2.CustomClassical(\"arctan\", 2, math.atan2),\n",
        "]\n",
        "circuit = qasm2.loads(program, custom_classical=customs)"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "4373999e-9df1-4078-ab83-d1c88a577aaf",
      "metadata": {},
      "source": [
        "<span id=\"strict\" />\n",
        "\n",
        "<span id=\"strict-mode\" />\n",
        "\n",
        "### Modo estrito\n",
        "\n",
        "Por padrão, esse analisador é mais relaxado do que a especificação oficial.\n",
        "Ele permite vírgulas finais em listas de parâmetros, pontos e vírgulas desnecessários (declaração vazia), omissão da declaração da versão `OPENQASM 2.0;` e várias outras melhorias de qualidade de vida sem emitir nenhum erro.\n",
        "No entanto, você pode usar o modo \"letter-of-the-spec\" com `strict=True`.\n",
        "\n",
        "<span id=\"qasm2-export\" />\n",
        "\n",
        "<span id=\"export-a-qiskit-circuit-to-openqasm-2\" />\n",
        "\n",
        "## Exportar um circuito Qiskit para OpenQASM 2\n",
        "\n",
        "O Qiskit também pode exportar um [`QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit) para OpenQASM 2.\n",
        "Você usa a função [`qasm2.dump()`](../api/qiskit/qasm2#dump) para gravar em um arquivo e [`qasm2.dumps()`](../api/qiskit/qasm2#dumps) para gravar em uma string.\n",
        "Atualmente, essas funções têm uma interface muito simples: elas aceitam um circuito e, somente no caso de [`qasm2.dump()`](../api/qiskit/qasm2#dump)um local para gravar a saída.\n",
        "\n",
        "<Admonition type=\"warning\">\n",
        "  O exportador OpenQASM 2 do Qiskit ainda assume uma versão antiga e não padrão do arquivo de inclusão `\"qelib1.inc\"` .\n",
        "  [Isso será resolvido em uma versão posterior do Qiskit](https://github.com/Qiskit/qiskit/issues/10737), mas, enquanto isso, se você precisar reimportar um programa OpenQASM 2 criado com o Qiskit, use [o exemplo acima para saber como informar o importador sobre as portas legadas](#qasm2-import-legacy).\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"example-export-a-circuit-to-openqasm-2\" />\n",
        "\n",
        "### Exemplo: exportar um circuito para OpenQASM 2\n",
        "\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "id": "70f4d657-8be3-400d-a793-d36962a855ef",
      "metadata": {},
      "outputs": [],
      "source": [
        "from qiskit import QuantumCircuit, qasm2\n",
        "\n",
        "# Define any circuit.\n",
        "circuit = QuantumCircuit(2, 2)\n",
        "circuit.h(0)\n",
        "circuit.cx(0, 1)\n",
        "circuit.measure([0, 1], [0, 1])\n",
        "\n",
        "# Export to a string.\n",
        "program = qasm2.dumps(circuit)\n",
        "\n",
        "# Export to a file.\n",
        "qasm2.dump(circuit, \"my_file.qasm\")"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "1c0fd601-51ec-4d82-8821-20e0554a3662",
      "metadata": {},
      "source": [
        "<span id=\"next-steps\" />\n",
        "\n",
        "## Próximas etapas\n",
        "\n",
        "<Admonition type=\"tip\" title=\"Recomendações\">\n",
        "  * Saiba como gerar o código OpenQASM no guia [IBM Quantum Composer](/docs/guides/composer).\n",
        "  * Consulte a referência [da API do Qiskit em OpenQASM 2](/docs/api/qiskit/qasm2).\n",
        "  * Consulte o tópico “[Verifique seu programa](/docs/guides/debugging-tools) ”.\n",
        "  * Visite o site [OpenQASM Live Specification](https://openqasm.com/).\n",
        "</Admonition>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "id": "a1b8767d",
      "source": "© IBM Corp., 2017-2026"
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 4
}