{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# tket (pytket) quickstart\n",
    "\n",
    "pytket is the compiler lane: build a circuit, rebase to Quantinuum natives, compile offline against `QuantinuumBackend(\"H2-2\")` with no credentials and no HQCs, and use it as an independent check on any gate-count reduction claim.\n",
    "\n",
    "Generated from the crawled `tket-user-guide` corpus (crawl date 2026-08-24) by `python -m quantum.docs_crawler.notebooks`. Do not edit by hand — edit the generator or pin a snippet out via `notebook_manifest.json`.\n",
    "\n",
    "```bash\n",
    "pip install pytket pytket-quantinuum\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Environment check\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket import Circuit\n",
    "import pytket\n",
    "\n",
    "print('pytket', pytket.__version__)\n",
    "\n",
    "# Half-turn convention check: Ry(0.5) is a pi/2 rotation, exactly like Guppy's\n",
    "# angle(). Never multiply by pi when porting a formula between the two.\n",
    "u = Circuit(1).Ry(0.5, 0).get_unitary()   # (angle, qubit) — the index is required\n",
    "print(u.round(3))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Core examples\n",
    "\n",
    "Each cell below is an upstream example, linked to its source page.\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Getting Started](https://docs.quantinuum.com/tket/user-guide/index.html)** — `index` block 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket import Circuit\n",
    "\n",
    "ghz_circ = Circuit(3)\n",
    "ghz_circ.H(0)\n",
    "ghz_circ.CX(0, 1)\n",
    "ghz_circ.CX(1, 2)\n",
    "ghz_circ.add_barrier(ghz_circ.qubits)\n",
    "ghz_circ.measure_all()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Getting Started](https://docs.quantinuum.com/tket/user-guide/index.html)** — `index` block 2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket.qasm import circuit_from_qasm\n",
    "\n",
    "w_state_circ = circuit_from_qasm(\"examples/qasm/W-state.qasm\")\n",
    "render_circuit_jupyter(w_state_circ)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Circuit Construction](https://docs.quantinuum.com/tket/user-guide/manual/manual_circuit.html)** — `manual/manual_circuit` block 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket import Circuit\n",
    "\n",
    "trivial_circ = Circuit()        # no qubits or bits\n",
    "quantum_circ = Circuit(4)       # 4 qubits and no bits\n",
    "mixed_circ   = Circuit(4, 2)    # 4 qubits and 2 bits\n",
    "named_circ   = Circuit(2, 2, \"my_circ\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Circuit Construction](https://docs.quantinuum.com/tket/user-guide/manual/manual_circuit.html)** — `manual/manual_circuit` block 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket import Circuit\n",
    "\n",
    "circ = Circuit(4)   # qubits are numbered 0-3\n",
    "circ.X(0)           # first apply an X gate to qubit 0\n",
    "circ.CX(1, 3)       # and apply a CX gate with control qubit 1 and target qubit 3\n",
    "circ.Z(3)           # then apply a Z gate to qubit 3\n",
    "circ.get_commands() # show the commands of the built circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Circuit analysis](https://docs.quantinuum.com/tket/user-guide/examples/circuit_construction/circuit_analysis_example.html)** — `examples/circuit_construction/circuit_analysis_example` block 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c = Circuit(4, name=\"example\")\n",
    "c.add_gate(OpType.CU1, 0.5, [0, 1])\n",
    "c.H(0).X(1).Y(2).Z(3)\n",
    "c.X(0).CX(1, 2).Y(1).Z(2).H(3)\n",
    "c.Y(0).Z(1)\n",
    "c.add_gate(OpType.CU1, 0.5, [2, 3])\n",
    "c.H(2).X(3)\n",
    "c.Z(0).H(1).X(2).Y(3).CX(3, 0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Circuit analysis](https://docs.quantinuum.com/tket/user-guide/examples/circuit_construction/circuit_analysis_example.html)** — `examples/circuit_construction/circuit_analysis_example` block 18\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cmd0 = cmds[0]\n",
    "op0 = cmd0.op\n",
    "print(op0)\n",
    "qubits0 = cmd0.args\n",
    "print(qubits0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Compilation](https://docs.quantinuum.com/tket/user-guide/manual/manual_compiler.html)** — `manual/manual_compiler` block 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket import Circuit, OpType\n",
    "from pytket.predicates import GateSetPredicate, NoMidMeasurePredicate\n",
    "\n",
    "circ = Circuit(2, 2)\n",
    "circ.Rx(0.2, 0).CX(0, 1).Rz(-0.7, 1).measure_all()\n",
    "\n",
    "gateset = GateSetPredicate({OpType.Rx, OpType.CX, OpType.Rz, OpType.Measure})\n",
    "midmeasure = NoMidMeasurePredicate()\n",
    "\n",
    "print(gateset.verify(circ))\n",
    "print(midmeasure.verify(circ))\n",
    "\n",
    "circ.S(0)\n",
    "\n",
    "print(gateset.verify(circ))\n",
    "print(midmeasure.verify(circ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Compilation](https://docs.quantinuum.com/tket/user-guide/manual/manual_compiler.html)** — `manual/manual_compiler` block 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket.circuit import Circuit, OpType\n",
    "from pytket.predicates import UserDefinedPredicate\n",
    "\n",
    "def max_cx_count(circ: Circuit) -> bool:\n",
    "    return circ.n_gates_of_type(OpType.CX) < 3\n",
    "\n",
    "# Now construct our predicate using the function defined above\n",
    "my_predicate = UserDefinedPredicate(max_cx_count)\n",
    "\n",
    "test_circ = Circuit(2).CX(0, 1).Rz(0.25, 1).CX(0, 1) # Define a test Circuit\n",
    "\n",
    "my_predicate.verify(test_circ)\n",
    "# test_circ satisfies predicate as it contains only 2 CX gates"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Compilation passes](https://docs.quantinuum.com/tket/user-guide/examples/circuit_compilation/compilation_example.html)** — `examples/circuit_compilation/compilation_example` block 3\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "circ = Circuit(3)\n",
    "circ.CRz(0.5, 0, 1)\n",
    "circ.T(2)\n",
    "circ.CSWAP(2, 0, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Compilation passes](https://docs.quantinuum.com/tket/user-guide/examples/circuit_compilation/compilation_example.html)** — `examples/circuit_compilation/compilation_example` block 5\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "cu = CompilationUnit(circ)\n",
    "pass1.apply(cu)\n",
    "circ1 = cu.circuit"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Qubit mapping and routing](https://docs.quantinuum.com/tket/user-guide/examples/circuit_compilation/mapping_example.html)** — `examples/circuit_compilation/mapping_example` block 2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def draw_graph(coupling_map: List[Union[Tuple[int, int], Tuple[Node, Node]]]):\n",
    "    coupling_graph = nx.Graph(coupling_map)\n",
    "    nx.draw(coupling_graph, labels={node: node for node in coupling_graph.nodes()})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Qubit mapping and routing](https://docs.quantinuum.com/tket/user-guide/examples/circuit_compilation/mapping_example.html)** — `examples/circuit_compilation/mapping_example` block 3\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "simple_coupling_map = [(0, 1), (1, 2), (2, 3)]\n",
    "simple_architecture = Architecture(simple_coupling_map)\n",
    "draw_graph(simple_coupling_map)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Running on Backends](https://docs.quantinuum.com/tket/user-guide/manual/manual_backend.html)** — `manual/manual_backend` block 2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket import Circuit, OpType\n",
    "from pytket.extensions.qiskit import AerBackend\n",
    "\n",
    "circ = Circuit(3, 2)\n",
    "circ.H(0).Ry(0.25, 1)\n",
    "circ.add_gate(OpType.CnRy, [0.74], [0, 1, 2]) # CnRy not in AerBackend gate set\n",
    "circ.measure_all()\n",
    "\n",
    "backend = AerBackend()\n",
    "print(\"Circuit valid for AerBackend?\", backend.valid_circuit(circ))\n",
    "compiled_circ = backend.get_compiled_circuit(circ) # Compile circuit to AerBackend\n",
    "\n",
    "print(\"Compiled circuit valid for AerBackend?\", backend.valid_circuit(compiled_circ))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Running on Backends](https://docs.quantinuum.com/tket/user-guide/manual/manual_backend.html)** — `manual/manual_backend` block 3\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket import Circuit\n",
    "from pytket.extensions.qiskit import AerStateBackend\n",
    "\n",
    "circ = Circuit(2, 2)\n",
    "circ.Rx(0.3, 0).Ry(0.5, 1).CRz(-0.6, 1, 0)\n",
    "backend = AerStateBackend()\n",
    "compiled_circ = backend.get_compiled_circuit(circ)\n",
    "handle = backend.process_circuit(compiled_circ)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[TKET `Backend` tutorial](https://docs.quantinuum.com/tket/user-guide/examples/backends/backends_example.html)** — `examples/backends/backends_example` block 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket.extensions.qiskit import (\n",
    "    AerStateBackend,\n",
    "    AerBackend,\n",
    "    AerUnitaryBackend,\n",
    "    IBMQBackend,\n",
    "    IBMQEmulatorBackend,\n",
    ")\n",
    "from pytket.extensions.projectq import ProjectQBackend"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[TKET `Backend` tutorial](https://docs.quantinuum.com/tket/user-guide/examples/backends/backends_example.html)** — `examples/backends/backends_example` block 2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "circ = Circuit(2)\n",
    "circ.H(0)\n",
    "circ.CX(0, 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Expectation values](https://docs.quantinuum.com/tket/user-guide/examples/algorithms_and_protocols/expectation_value_example.html)** — `examples/algorithms_and_protocols/expectation_value_example` block 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ansatz = Circuit()\n",
    "qubits = ansatz.add_q_register(\"q\", 4)\n",
    "args = symbols(\"a0 a1 a2 a3 a4 a5 a6 a7\")\n",
    "for i in range(4):\n",
    "    ansatz.Ry(args[i], qubits[i])\n",
    "for i in range(3):\n",
    "    ansatz.CX(qubits[i], qubits[i + 1])\n",
    "for i in range(4):\n",
    "    ansatz.Ry(args[4 + i], qubits[i])\n",
    "ansatz.measure_all()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Expectation values](https://docs.quantinuum.com/tket/user-guide/examples/algorithms_and_protocols/expectation_value_example.html)** — `examples/algorithms_and_protocols/expectation_value_example` block 3\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "arg_values = [\n",
    "    7.17996183e-02,\n",
    "    2.95442468e-08,\n",
    "    1.00000015e00,\n",
    "    1.00000086e00,\n",
    "    9.99999826e-01,\n",
    "    1.00000002e00,\n",
    "    9.99999954e-01,\n",
    "    1.13489747e-06,\n",
    "]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Advanced expectation values and measurement reduction](https://docs.quantinuum.com/tket/user-guide/examples/algorithms_and_protocols/measurement_reduction_example.html)** — `examples/algorithms_and_protocols/measurement_reduction_example` block 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket.circuit import Circuit, Qubit\n",
    "from pytket.pauli import Pauli, QubitPauliString\n",
    "from pytket.utils import QubitPauliOperator\n",
    "from pytket.utils.expectations import get_operator_expectation_value\n",
    "from pytket.extensions.qiskit import AerBackend, AerStateBackend"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Advanced expectation values and measurement reduction](https://docs.quantinuum.com/tket/user-guide/examples/algorithms_and_protocols/measurement_reduction_example.html)** — `examples/algorithms_and_protocols/measurement_reduction_example` block 2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "c = Circuit(5)\n",
    "c.H(4)\n",
    "c.V(2)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Bridge: the offline H2-2 compile lane\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# quantum/tket/ compiles each circuit family raw vs Nadarasa-reduced against an\n",
    "# offline Quantinuum backend — no credentials, no job, no HQCs:\n",
    "#\n",
    "#     from pytket.extensions.quantinuum import QuantinuumBackend\n",
    "#     from pytket.extensions.quantinuum.backends.api_wrappers import QuantinuumAPIOffline\n",
    "#     backend = QuantinuumBackend(device_name='H2-2', api_handler=QuantinuumAPIOffline())\n",
    "#     compiled = backend.get_compiled_circuit(circ, optimisation_level=2)\n",
    "#\n",
    "# Every count is gated on a global-phase-free unitary oracle:\n",
    "#     ||a - (<a,b>/|<a,b>|) * b|| <= 1e-9\n",
    "# An optimiser that changes semantics otherwise looks like the best optimiser.\n",
    "print('see quantum/tket/compile.py and quantum/tket/verify.py')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Pitfalls\n",
    "\n",
    "1. TKET **drops idle wires**. Pad with `add_blank_wires` before comparing circuits or sampling, or the TVD reads 1.0 for a perfectly correct circuit.\n",
    "2. `Ry`/`Rz`/`ZZPhase` parameters are half-turns, exactly like Guppy's `angle()`. Verify in one line: `Circuit(1).Ry(0.5).get_unitary()`.\n",
    "3. Gate every reported gate count on a global-phase-free unitary equivalence oracle at 1e-9.\n",
    "4. Never score approximation families (AQFT band truncation) against a compiler — a correctness-preserving compiler cannot find them, so the comparison is meaningless.\n",
    "5. Native ops (`PhasedX`, `Rz`, `ZZPhase`, `ZZMax`) map one-to-one onto `guppylang.std.qsystem`, both in half-turns, so a compiled circuit round-trips onto Selene with no angle conversion.\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.12"
  },
  "title": "tket (pytket) quickstart"
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
