{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Conditional gates\n",
"\n",
"**Download this notebook - {nb-download}`conditional_gate_example.ipynb`**"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Whilst any quantum process can be created by performing \"pure\" operations delaying all measurements to the end, this is not always practical and can greatly increase the resource requirements. It is much more convenient to alternate quantum gates and measurements, especially if we can use the measurement results to determine which gates to apply (we refer to this more generic circuit model as \"mixed\" circuits, against the usual \"pure\" circuits). This is especially crucial for error correcting codes, where the correction gates are applied only if an error is detected.
\n",
"
\n",
"Measurements on many NISQ devices are often slow and it is hard to maintain other qubits in a quantum state during the measurement operation. Hence they may only support a single round of measurements at the end of the circuit, removing the need for conditional gate support. However, the ability to work with mid-circuit measurement and conditional gates is a feature in high demand for the future, and tket is ready for it.
\n",
"
\n",
"Not every circuit language specification supports conditional gates in the same way. The most popular circuit model at the moment is that provided by the OpenQASM language. This permits a very restricted model of classical logic, where we can apply a gate conditionally on the exact value of a classical register. There is no facility in the current spec for Boolean logic or classical operations to apply any function to the value prior to the equality check.
\n",
"
\n",
"For example, quantum teleportation can be performed by the following QASM:
\n",
"`OPENQASM 2.0;`
\n",
"`include \"qelib1.inc\";`
\n",
"`qreg a[2];`
\n",
"`qreg b[1];`
\n",
"`creg c[2];`
\n",
"`// Bell state between Alice and Bob`
\n",
"`h a[1];`
\n",
"`cx a[1],b[0];`
\n",
"`// Bell measurement of Alice's qubits`
\n",
"`cx a[0],a[1];`
\n",
"`h a[0];`
\n",
"`measure a[0] -> c[0];`
\n",
"`measure a[1] -> c[1];`
\n",
"`// Correction of Bob's qubit`
\n",
"`if(c==1) z b[0];`
\n",
"`if(c==3) z b[0];`
\n",
"`if(c==2) x b[0];`
\n",
"`if(c==3) x b[0];`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"tket supports a slightly more general form of conditional gates, where the gate is applied conditionally on the exact value of any list of bits. When adding a gate to a `Circuit` object, pass in the kwargs `condition_bits` and `condition_value` and the gate will only be applied if the state of the bits yields the binary representation of the value."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"from pytket import Circuit\n",
"from pytket.circuit.display import render_circuit_jupyter"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"