{
  "cells": [
    {
      "cell_type": "markdown",
      "id": "35492576-b15e-43e6-8b9b-293631c6b194",
      "metadata": {},
      "source": [
        "---\n",
        "title: \"OpenQASM 2 と Qiskit SDK\"\n",
        "description: \"OpenQASM 2 と Qiskit SDK 間のコード変換方法\"\n",
        "---\n",
        "\n",
        "<span id=\"openqasm-2-and-the-qiskit-sdk\" />\n",
        "\n",
        "# OpenQASM 2 と 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=\"パッケージ・バージョン\">\n",
        "    このページのコードは、以下の要件に基づいて開発された。\n",
        "    これらのバージョンまたは新しいバージョンの使用をお勧めします。\n",
        "\n",
        "    ```\n",
        "    qiskit[all]~=2.5.1\n",
        "    ```\n",
        "  </AccordionItem>\n",
        "</Accordion>\n",
        "\n"
      ]
    },
    {
      "cell_type": "markdown",
      "id": "328f6a16-5ec4-4d80-8507-f5d97aa02f26",
      "metadata": {},
      "source": [
        "Qiskit SDKは、量子プログラムの OpenQASM 表現の間で変換するためのいくつかのツールを提供します。 [QuantumCircuit](/docs/api/qiskit/qiskit.circuit.QuantumCircuit) クラスを提供します。\n",
        "\n",
        "<span id=\"qasm2-import\" />\n",
        "\n",
        "<span id=\"import-an-openqasm-2-program-into-qiskit\" />\n",
        "\n",
        "## OpenQASM 2プログラムをQiskitにインポートする\n",
        "\n",
        "OpenQASM 2のプログラムをQiskitにインポートする2つの関数。\n",
        "これらは [`qasm2.load()`](../api/qiskit/qasm2#load)ファイル名を取る [`qasm2.loads()`](../api/qiskit/qasm2#loads)は、 OpenQASM 2 プログラムを文字列として受け取ります。\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": [
        "詳しくは [OpenQASM 2 Qiskit APIを](/docs/api/qiskit/qasm2)ご覧ください。\n",
        "\n",
        "<span id=\"import-simple-programs\" />\n",
        "\n",
        "### 簡単なプログラムをインポートする\n",
        "\n",
        "ほとんどの OpenQASM 2プログラムでは、単純に `qasm2.load` と `qasm2.loads` を1つの引数で使うことができる。\n",
        "\n",
        "<span id=\"example-import-an-openqasm-2-program-as-a-string\" />\n",
        "\n",
        "#### 例: OpenQASM 2 プログラムを文字列としてインポートする\n",
        "\n",
        "`qasm2.loads()` を使って、 OpenQASM 2 プログラムを文字列としてインポートする。 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",
        "#### 例: ファイルから OpenQASM 2プログラムをインポートする\n",
        "\n",
        "`load()` を使って、 OpenQASM 2 プログラムをファイルからインポートする。 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",
        "### OpenQASM 2つのゲートをQiskitゲートで接続\n",
        "\n",
        "デフォルトでは、Qiskitの OpenQASM 2インポータはインクルードファイル `\"qelib1.inc\"` を*事実上の*標準ライブラリとして扱います。\n",
        "インポーターはこのファイルを、 [OpenQASM 2を定義した元の論文に](https://arxiv.org/abs/1707.03429)記述されているゲートを正確に含むものとして扱う。\n",
        "Qiskitは[回路ライブラリの](../api/qiskit/circuit_library)組み込みゲートを使用して、 `\"qelib1.inc\"` のゲートを表現します。\n",
        "マニュアル OpenQASM 2 `gate` ステートメントによってプログラム内で定義されたゲートは、デフォルトでは、カスタム [Qiskit `Gate` サブクラスとして](../api/qiskit/qiskit.circuit.Gate)構築されます。\n",
        "\n",
        "インポーターに特定の [`Gate`](../api/qiskit/qiskit.circuit.Gate)`gate` を使うように指示できます。\n",
        "このメカニズムを使って、追加のゲート名を「ビルトイン」、つまり明示的な定義を必要としないものとして扱うこともできる。\n",
        "`\"qelib1.inc\"` の外部で、 `gate` ステートメントに使用するゲート・クラスを指定すると、通常、結果の回路はより効率的に動作します。\n",
        "\n",
        "<Admonition type=\"warning\">\n",
        "  Qiskit SDK v1.0 の時点で、Qiskitの OpenQASM\\* 2エクスポーター\\* （ [OpenQASM 2へのQiskit回路のエクスポートを](#qasm2-export)参照）は、依然として実際のゲート数よりも多いゲート数 `\"qelib1.inc\"` があるかのように動作します。\n",
        "  これは、インポーターのデフォルト設定では、当社のインポーターでエクスポートされたプログラムをインポートできない可能性があることを意味します。\n",
        "  この問題を解決[するためのレガシーエクスポーターの使用方法については、具体的な例を](#qasm2-import-legacy)参照してください。\n",
        "\n",
        "  この矛盾はQiskitのレガシーな動作であり、 [Qiskitの後のリリースで解決される予定です](https://github.com/Qiskit/qiskit/issues/10737)。\n",
        "</Admonition>\n",
        "\n",
        "カスタム命令に関する情報を OpenQASM 2 インポータに渡すには、 [ `qasm2.CustomInstruction` クラスを](../api/qiskit/qasm2#qiskit.qasm2.CustomInstruction)使用します。\n",
        "これには4つの必須情報があり、順に説明する：\n",
        "\n",
        "* OpenQASM 2 プログラムで使用されるゲートの**名前**\n",
        "* ゲートが取る**角度パラメータの数**\n",
        "* ゲートが作用する**量子ビットの数**\n",
        "* Python ゲートの**コンストラクタ**クラスまたは関数。個々の引数としてゲートパラメータ（量子ビットは含まない）を取る\n",
        "\n",
        "インポーターは、指定されたカスタム命令と一致する `gate` 定義に遭遇した場合、そのカスタム情報を使用してゲート・オブジェクトを再構築する。\n",
        "カスタム命令の `name` と一致する `gate` ステートメントに遭遇したが、パラメータの数と量子ビットの数の両方と一致しない場合、インポーターは、提供された情報とプログラムとの不一致を示すために [`QASM2ParseError`](../api/qiskit/qasm2#qasm2parseerror)を発生させ、提供された情報とプログラムの不一致を示します。\n",
        "\n",
        "さらに、5番目の引数 `builtin` をオプションで `True` に設定すると、ゲートが明示的に定義されていなくても、 OpenQASM 2 プログラム内で自動的に利用できるようになる。\n",
        "インポーターが組み込みカスタム命令の明示的な `gate` 定義に遭遇した場合、それを黙って受け入れる。\n",
        "以前と同様、同じ名前の明示的な定義が、提供されたカスタム命令と互換性がない場合は [`QASM2ParseError`](../api/qiskit/qasm2#qasm2parseerror) が発生します。\n",
        "これは、古い OpenQASM 2 エクスポーターや、ハードウェアの「ベーシス・ゲート」を内蔵命令として扱う他の量子プラットフォームとの互換性を保つのに役立つ。\n",
        "\n",
        "Qiskit は、 [Qiskit の OpenQASM 2 エクスポート機能の](#qasm2-export)レガシーバージョンで作成された OpenQASM 2 プログラムを操作するためのデータ属性を提供します。\n",
        "これは [`qasm2.LEGACY_CUSTOM_INSTRUCTIONS`](../api/qiskit/qasm2#legacy-compatibility)の `custom_instructions` 引数として与えられる。 [`qasm2.load()`](../api/qiskit/qasm2#load) そして [`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",
        "#### 例: Qiskitのレガシーエクスポーターで作成されたプログラムをインポートする\n",
        "\n",
        "この OpenQASM 2プログラムでは、 `\"qelib1.inc\"` のオリジナル・バージョンにはないゲートを宣言せずに使用しているが、Qiskitのライブラリには標準的なゲートである。\n",
        "を使用することができます。 [`qasm2.LEGACY_CUSTOM_INSTRUCTIONS`](../api/qiskit/qasm2#legacy-compatibility) を使うと、Qiskitの OpenQASM 2 エクスポーターが以前使っていたのと同じゲートのセットを使うように、インポーターに簡単に指示できます。\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",
        "#### 例： OpenQASM 2プログラムをインポートする際に特定のゲートクラスを使用する\n",
        "\n",
        "Qiskitは一般的に、 OpenQASM 2 `gate` ステートメント内の定義がQiskit標準ライブラリゲートに正確に対応しているかどうかを検証することはできません。\n",
        "代わりにQiskitは、提供された正確な定義を使ってカスタムゲートを選択します。\n",
        "これは、内蔵の標準ゲートやユーザー定義のカスタムゲートを使うよりも効率が悪くなる可能性がある。\n",
        "`gate` ステートメントを特定のクラスで手動で定義することができます。\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",
        "#### 例： OpenQASM 2プログラムで新しい組み込みゲートを定義する\n",
        "\n",
        "引数 `builtin=True` が設定されている場合、カスタム・ゲートは関連する定義を持つ必要はない。\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",
        "### カスタムの古典関数を定義する\n",
        "\n",
        "OpenQASM 2には、ゲート引数で使用する古典的な関数がいくつか組み込まれている。\n",
        "の引数 `custom_classical` を使用することで、より多くの関数で言語を拡張することができる。 [`qasm2.load()`](../api/qiskit/qasm2#load) と [`qasm2.loads()`](../api/qiskit/qasm3#loads)引数を [`qasm2.CustomClassical`](../api/qiskit/qasm2#qiskit.qasm2.CustomClassical) クラスの引数で指定します。\n",
        "\n",
        "カスタム・クラシック関数を定義するには、以下のように指定する必要がある：\n",
        "\n",
        "* OpenQASM 2 プログラムに表示される関数*名*\n",
        "* 浮動小数点の引数の数\n",
        "* 関数を評価する、呼び出し可能な Python オブジェクト\n",
        "\n",
        "定義されたすべてのカスタム古典関数は、インポーターによって OpenQASM 2言語の組み込みとして扱われます。\n",
        "OpenQASM 2言語には、新しい関数を定義する公式な方法はありません。これはQiskitの拡張機能です。\n",
        "\n",
        "<span id=\"example-use-custom-classical-instructions\" />\n",
        "\n",
        "#### 例：カスタムの古典的命令を使用する\n",
        "\n",
        "ここでは、2つのカスタム・クラシック関数を提供する。\n",
        "最初は単純で、入力に1を加えるだけだ。\n",
        "2つ目は、四分円を意識した方法で数学演算 $\\arctan(y/x)$ を表す関数 `math.atan2`。\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",
        "### 厳密モード\n",
        "\n",
        "デフォルトでは、このパーサーは公式仕様よりも緩和されている。\n",
        "パラメータリストの末尾のカンマ、不要な（空の）ステートメントのセミコロン、 `OPENQASM 2.0;` バージョンステートメントの省略、その他いくつかの品質向上が、エラーを出さずにできるようになった。\n",
        "しかし、 `strict=True` で「letter-of-spec」モードを使うことができる。\n",
        "\n",
        "<span id=\"qasm2-export\" />\n",
        "\n",
        "<span id=\"export-a-qiskit-circuit-to-openqasm-2\" />\n",
        "\n",
        "## Qiskit回路を OpenQASM にエクスポートする 2\n",
        "\n",
        "Qiskitは [`QuantumCircuit`](../api/qiskit/qiskit.circuit.QuantumCircuit) を OpenQASM 2。\n",
        "関数 [`qasm2.dump()`](../api/qiskit/qasm2#dump) を使ってファイルに書き込み [`qasm2.dumps()`](../api/qiskit/qasm2#dumps) 文字列への書き込みには\n",
        "これらの関数は現在、非常にシンプルなインターフェースを持っている。 [`qasm2.dump()`](../api/qiskit/qasm2#dump)の場合のみ、出力を書き込む場所を指定する。\n",
        "\n",
        "<Admonition type=\"warning\">\n",
        "  Qiskit の OpenQASM 2 エクスポーターは、レガシーな非標準バージョンの `\"qelib1.inc\"` インクルードファイルをまだ想定しています。\n",
        "  [これはQiskitの後のリリースで解決される予定](https://github.com/Qiskit/qiskit/issues/10737)ですが、それまでの間、Qiskitで作成された OpenQASM 2プログラムを再インポートする必要がある場合は、 [インポーターにレガシーゲートについて伝える方法について上記の例を](#qasm2-import-legacy)使用してください。\n",
        "</Admonition>\n",
        "\n",
        "<span id=\"example-export-a-circuit-to-openqasm-2\" />\n",
        "\n",
        "### 例: 回路を 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",
        "## 次のステップ\n",
        "\n",
        "<Admonition type=\"tip\" title=\"推奨事項\">\n",
        "  * [IBM Quantum Composer](/docs/guides/composer) ガイドで、 OpenQASM コードを生成する方法を学んでください。\n",
        "  * [OpenQASM 2 Qiskit API](/docs/api/qiskit/qasm2) リファレンスを参照。\n",
        "  * 「[プログラムの確認](/docs/guides/debugging-tools) 」のトピックを確認してください。\n",
        "  * [OpenQASM ライブ仕様を](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
}