吾輩は量子プログラミング言語である。名前はまだ無い。 Microsoftで生れ量子テレポーテーションした事だけは記憶している。

Microsoftが2017年内に、量子コンピュータのための新しいプログラミング言語を公開するそうですね！
量子力学……波動関数……シュレディンガーの猫……。ええ、よく ~~中二病~~ SFで耳にする、なんかヤバいやつです。量子コンピュータが実用化されると、現在のインターネットで使われてる暗号はすぐに解けてしまうとか。 ~~ちょっとネットで調べただけで知ったかぶらないでよ！~~

量子プログラミング言語自体はすでに幾つもありますが、今回のものはVisual Studioで開発・デバッグできてAzureのシミュレータでも動くとのことで、Microsoftの本気を感じます。言語的には、C#、Python、F#の要素を取り入れているらしく、モダンなものになるでしょう。まだ名前は決まってないそうですが。
ということで、夢の量子コンピュータがいよいよ実用的なソフトウェア領域にやってきそうな予感がしたので、付け焼刃の勢いでサンプルコードを読んでみました。  ~~BGMは量子の海のリンドヴルムです。ニャ!~~ 

# 量子ビット計算

量子コンピュータには、NASAやGoogleが利用しているD-WAVEの量子アニーリング方式、IBMがクラウド公開しているIBM Qの量子ゲート方式、の二種類あります。そして、Microsoftの言語は量子ゲート用です。
量子ゲートは、量子ビットに作用します。普通のビットは０か１のどちらかしか表せませんが、量子ビットは０と１を重ね合わせた状態を取ることができます。たとえば、

```math
\newcommand{\ket}[1]{\left| #1 \right\rangle}
\frac{1}{\sqrt{2}}\ket{00} + \frac{1}{\sqrt{2}}\ket{11}
```

は、量子ビットの一つ目が０で二つ目も０という状態と、量子ビットの一つ目が１で二つ目も１という状態が、同じ確率で重なり合った状態を表しています。このように複数の状態を重ね合わせたまま量子ゲートを作用させることで、普通のコンピュータを遥かに凌駕しうる超並列計算ができるというわけですね。 ~~あとヨルムンガンドも発動します。~~

重ね合わせが物理的にどういう意味を持つのか、というところに踏みこむためには量子力学が必要ですが、量子ビットの計算自体はいくつかのルールを抑えてしまえば大丈夫です。
そのルールも簡単で、式変形を眺めているうちに自然と理解できると思うので、まずはサンプルコードに登場する量子ゲートを紹介します。

## ビット反転ゲート X

```math
\begin{align}
\mathrm{X}\ket{0} &= \ket{1} \\
\mathrm{X}\ket{1} &= \ket{0} \\
\end{align}
```

## 位相反転ゲート Z

```math
\begin{align}
\mathrm{Z}\ket{0} &= \ket{0} \\
\mathrm{Z}\ket{1} &= -\ket{1} \\
\end{align}
```

## アダマールゲート H

```math
\begin{align}
\mathrm{H}\ket{0} &= \frac{1}{\sqrt{2}}\ket{0} + \frac{1}{\sqrt{2}}\ket{1} \\
\mathrm{H}\ket{1} &= \frac{1}{\sqrt{2}}\ket{0} - \frac{1}{\sqrt{2}}\ket{1}
\end{align}
```

## 制御ノットゲート CNOT

```math
\begin{align}
\mathrm{CNOT}\ket{00} &= \ket{00} \\
\mathrm{CNOT}\ket{01} &= \ket{01} \\
\mathrm{CNOT}\ket{10} &= \ket{11} \\
\mathrm{CNOT}\ket{11} &= \ket{10}
\end{align}
```

# サンプルコード

それでは、『[Microsoft makes play for next wave of computing with quantum computing toolkit](https://arstechnica.com/gadgets/2017/09/microsoft-quantum-toolkit/)』で紹介されている、42行のサンプルコードを読んでいきましょう。量子アルゴリズム界隈におけるハローワールド、量子テレポーテーションをテストするコードです。量子テレポーテーション……かっこいい響き! ~~Y軸を傾ければ時間も跳躍できますからね。~~
なお今のところ言語仕様は不明で、サンプルコードそのものしか手掛かりがないので、以下の説明は全て推測でしかないです。答え合わせが楽しみですね？

## EPRペア関数

```
operation () EPR (Qubit q1, Qubit q2) {
    Body {
        H (q1)
        CNOT (q1, q2)
    }
}
```

EPRペアという、二つの量子ビットをもつれさせる関数です。
そうです、量子ビットはもつれたり重ね合わさったりする、可愛いやつなんです。
一行ずつ追っていきましょう。

```
operation () EPR (Qubit q1, Qubit q2) {
```

二つの量子ビット `q1` `q2` の状態を操作する関数 `EPR` を宣言しています。
`q1` `q2` ともに $\ket{0}$ である量子ビットが与えられたとして、 $\ket{\mathrm{q1}\ \mathrm{q2}}$ の状態変化を追ってみましょう。

```math
\ket{00}
```

```
H (q1)
```

`q1` にアダマールゲートを作用させます。

```math
(\mathrm{H}\ket{0})\ket{0} = \frac{1}{\sqrt{2}}\ket{00} + \frac{1}{\sqrt{2}}\ket{10}
```

```
CNOT (q1, q2)
```

`q1` `q2` に制御ノットゲートを作用させます。

```math
\frac{1}{\sqrt{2}}(\mathrm{CNOT} \ket{00}) + \frac{1}{\sqrt{2}}(\mathrm{CNOT} \ket{10}) = \frac{1}{\sqrt{2}}\ket{00} + \frac{1}{\sqrt{2}}\ket{11}
```

## 量子テレポーテーション関数

```
operation() Teleport (Qubit msg, Qubit here, Qubit there) {
    Body {
        EPR (here, there)
        CNOT (msg, here)
        H (msg)

        let m_here = M (here)
        if (m_here == One) {
           X (there)
        }

        let m_msg = M (msg)
        if (m_msg == One) {
           Z (there)
        }
    }
}
```

おまちかね、量子テレポーテーションを行う関数です！

```
operation() Teleport (Qubit msg, Qubit here, Qubit there) {
```

三つの量子ビット `msg` `here` `there` の状態を操作する関数 `EPR` を宣言しています。
`msg` に $a\ket{0} + b\ket{1}$ `here` `there` には $\ket{0}$ である量子ビットが与えられたとして、 $\ket{\mathrm{msg}\ \mathrm{here}\ \mathrm{there}}$ の状態変化を追ってみましょう。
なお $a$ $b$ は $|a|^2 + |b|^2 = 1$ を満たす複素数です。

```
EPR (here, there)
```

```math
\begin{align}
&a\ket{0}(\mathrm{EPR} \ket{00}) + b\ket{1}(\mathrm{EPR} \ket{00}) \\
=\quad &\frac{a}{\sqrt{2}}\ket{000} + \frac{a}{\sqrt{2}}\ket{011} + \frac{b}{\sqrt{2}}\ket{100} + \frac{b}{\sqrt{2}}\ket{111}
\end{align}
```

```
CNOT (msg, here)
```

```math
\begin{align}
&\frac{a}{\sqrt{2}}(\mathrm{CNOT} \ket{00})\ket{0} + \frac{a}{\sqrt{2}}(\mathrm{CNOT} \ket{01})\ket{1} \\
&+ \frac{b}{\sqrt{2}}(\mathrm{CNOT} \ket{10})\ket{0} + \frac{b}{\sqrt{2}}(\mathrm{CNOT} \ket{11})\ket{1} \\
=\quad &\frac{a}{\sqrt{2}}\ket{000} + \frac{a}{\sqrt{2}}\ket{011} + \frac{b}{\sqrt{2}}\ket{110} + \frac{b}{\sqrt{2}}\ket{101}
\end{align}
```

```
H (msg)
```

```math
\begin{align}
&\frac{a}{\sqrt{2}}(\mathrm{H}\ket{0})\ket{00} + \frac{a}{\sqrt{2}}(\mathrm{H}\ket{0})\ket{11} \\
&+ \frac{b}{\sqrt{2}}(\mathrm{H}\ket{1})\ket{10} + \frac{b}{\sqrt{2}}(\mathrm{H}\ket{1})\ket{01} \\
=\quad &\frac{a}{2}\ket{000} + \frac{a}{2}\ket{100} + \frac{a}{2}\ket{011} + \frac{a}{2}\ket{111} \\
&+ \frac{b}{2}\ket{010} - \frac{b}{2}\ket{110} + \frac{b}{2}\ket{001} - \frac{b}{2}\ket{101}
\end{align}
```

```
let m_here = M (here)
if (m_here == One) {
    X (there)
}
```

if文による条件分岐が出てきました！
と、その前に `M` ですが、これは観測を行います。観測すると、もつれも重ね合わせも壊れてしまい、 `here` は $\ket{0}$ か $\ket{1}$ のどちらかに収束してしまいます。かわいーくなーい。
どちらになるかは神が振るサイコロ任せなので、それぞれ追ってみましょう。

- `m_here == Zero` の場合

```math
\begin{align}
&\sqrt{2}(\frac{a}{2}\ket{000} + \frac{a}{2}\ket{100} + \frac{b}{2}\ket{001} - \frac{b}{2}\ket{101}) \\
=\quad & \frac{a}{\sqrt{2}}\ket{000} + \frac{a}{\sqrt{2}}\ket{100} + \frac{b}{\sqrt{2}}\ket{001} - \frac{b}{\sqrt{2}}\ket{101}
\end{align}
```

- `m_here == One` の場合

```math
\begin{align}
&\sqrt{2}(\frac{a}{2}\ket{01}(\mathrm{X} \ket{1}) + \frac{a}{2}\ket{11}(\mathrm{X} \ket{1}) + \frac{b}{2}\ket{01}(\mathrm{X} \ket{0}) - \frac{b}{2}\ket{11}(\mathrm{X} \ket{0})) \\
=\quad &\frac{a}{\sqrt{2}}\ket{010} + \frac{a}{\sqrt{2}}\ket{110} + \frac{b}{\sqrt{2}}\ket{011} - \frac{b}{\sqrt{2}}\ket{111}
\end{align}
```

```
let m_msg = M (msg)
if (m_msg == One) {
    Z (there)
}
```

- `m_msg == Zero` & `m_here == Zero` の場合

```math
\begin{align}
&\sqrt{2}(\frac{a}{\sqrt{2}}\ket{000} + \frac{b}{\sqrt{2}}\ket{001}) \\
=\quad &a\ket{000} + b\ket{001} \\
=\quad &\ket{00}(a\ket{0} + b\ket{1})
\end{align}
```

- `m_msg == One` & `m_here == Zero` の場合

```math
\begin{align}
&\sqrt{2}(\frac{a}{\sqrt{2}}\ket{10}(\mathrm{Z} \ket{0}) - \frac{b}{\sqrt{2}}\ket{10}(\mathrm{Z} \ket{1})) \\
=\quad &a\ket{100} + b\ket{101} \\
=\quad &\ket{10}(a\ket{0} + b\ket{1})
\end{align}
```

- `m_msg == Zero` & `m_here == One` の場合

```math
\begin{align}
&\sqrt{2}(\frac{a}{\sqrt{2}}\ket{010} + \frac{b}{\sqrt{2}}\ket{011}) \\
=\quad &a\ket{010} + b\ket{011} \\
=\quad &\ket{01}(a\ket{0} + b\ket{1})
\end{align}
```

- `m_msg == One` & `m_here == One` の場合

```math
\begin{align}
&\sqrt{2}(\frac{a}{\sqrt{2}}\ket{11}(\mathrm{Z} \ket{0}) - \frac{b}{\sqrt{2}}\ket{11}(\mathrm{Z} \ket{1})) \\
=\quad &a\ket{110} + b\ket{111} \\
=\quad &\ket{11}(a\ket{0} + b\ket{1})
\end{align}
```

やりました！
`msg` `here` の観測結果に関わらず `there` の状態は $a\ket{0} + b\ket{1}$ になりました。
`msg` の量子的な状態が `there` にテレポートしたので、量子テレポーテーションというわけです。

## テスト関数

```
operation (Result) TeleportTest (Result msg) {
    Body {
        mutable res = Zero
        using (qubits = Qubit[3]) {
            let msgQ = qubits[0]

            // Set msgQ to message state
            SetQubit (msg, msgQ)

            Teleport (msgQ, qubits[1], qubits[2])

            set res = M(qubits[2])
        }
        return res
    }
}
```

見てのとおりテスト関数ですねっ。

```
operation (Result) TeleportTest (Result msg) {
```

`Result` 型の `msg` を受け取って、`Result` 型の値を返す関数 `TeleportTest` を宣言しています。
`Result` 型の値は `Zero` と `One` があります。

```
using (qubits = Qubit[3]) {
```

長さ３の量子ビット列を確保しています。
`using` のスコープ抜けるとリソース解放されます。

```
let msgQ = qubits[0]
```

量子ビット列 `qubits` の１番目の要素を変数束縛しています。

```
SetQubit (msg, msgQ)
Teleport (msgQ, qubits[1], qubits[2])
set res = M(qubits[2])
```

`Result` 型の `msg` の状態を `Qubit` 型の `msgQ` にセットして、 `qubits` の３番目の要素に量子テレポーテーションして、その観測結果を `Result` 型の `res` に代入します。

```
return res
```

最後に `res` を返します。めでたし、めでたし。

# IBM Q

ちなみに今回の量子テレポーテーションを、IBM Qのシミュレータで実装すると次のようになります。
実機では、まだif文対応していないみたいですね。残念。

## 量子回路

![IBM Q 量子テレポーテーション](https://qiita-image-store.s3.amazonaws.com/0/55208/af0730ea-6d44-1b6c-e9ac-468fade0d50a.png)

##  OpenQASM

```
OPENQASM 2.0;
include "qelib1.inc";

qreg q[3];
creg c[1];

h q[1];
cx q[1],q[2];
cx q[0],q[1];
h q[0];
measure q[1] -> c[0];
if(c==1) x q[2];
measure q[0] -> c[0];
if(c==1) z q[2];
```

# 参考

- [量子コンピュータ―超並列計算のからくり (ブルーバックス) | Amazon](https://www.amazon.co.jp/gp/product/4062574691)
- [IBM Quantum Computing で計算してみよう](https://www.ibm.com/developerworks/jp/cloud/library/cl-quantum-computing/index.html)
- [中学レベルの数学で量子テレポーテーションを理解してみよう](https://misatopology.wordpress.com/2012/10/14/quantum_transportation/)
- [Quantum gate | Wikipedia](https://en.wikipedia.org/wiki/Quantum_gate)