{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# lambeq quickstart\n",
    "\n",
    "lambeq turns sentences into string diagrams and then into parameterised quantum circuits, with its own training loop. It is the one library in this set with an end-to-end pipeline of its own rather than a role inside ours.\n",
    "\n",
    "Generated from the crawled `lambeq` 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 lambeq\n",
    "```\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Environment check\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import lambeq\n",
    "\n",
    "print('lambeq', lambeq.__version__)\n",
    "# The parser downloads a model on first use; run this notebook with network access.\n",
    "print([n for n in ('BobcatParser', 'IQPAnsatz', 'AtomicType') if hasattr(lambeq, n)])"
   ]
  },
  {
   "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": [
    "**[Parse the sentence and convert it into a string diagram](https://docs.quantinuum.com/lambeq/_code/sentence-input.html)** — `_code/sentence-input` block 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from lambeq import SpacyTokeniser\n",
    "\n",
    "tokeniser = SpacyTokeniser()\n",
    "sentence = \"This sentence isn't worth Â£100 (or is it?).\"\n",
    "tokens = tokeniser.tokenise_sentence(sentence)\n",
    "tokens"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Parse the sentence and convert it into a string diagram](https://docs.quantinuum.com/lambeq/_code/sentence-input.html)** — `_code/sentence-input` block 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from lambeq import BobcatParser\n",
    "\n",
    "parser = BobcatParser(verbose='suppress')\n",
    "diagram = parser.sentence2diagram(tokens, tokenised=True)\n",
    "\n",
    "diagram.draw(figsize=(23,4), fontsize=12)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Parse the sentence and convert it into a string diagram](https://docs.quantinuum.com/lambeq/_code/sentence-input.html)** — `_code/sentence-input` block 2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "sentences = [\"This is a sentence.\", \"This is (another) sentence!\"]\n",
    "\n",
    "tok_sentences = tokeniser.tokenise_sentences(sentences)\n",
    "tok_sentences"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Parse the sentence](https://docs.quantinuum.com/lambeq/_code/rewrite.html)** — `_code/rewrite` block 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from lambeq import BobcatParser\n",
    "\n",
    "# Parse the sentence\n",
    "parser = BobcatParser(verbose='suppress')\n",
    "diagram = parser.sentence2diagram(\"John walks in the park\")\n",
    "\n",
    "diagram.draw(figsize=(11,5), fontsize=13)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Parse the sentence](https://docs.quantinuum.com/lambeq/_code/rewrite.html)** — `_code/rewrite` block 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from lambeq import Rewriter\n",
    "\n",
    "# Apply rewrite rule for prepositional phrases\n",
    "\n",
    "rewriter = Rewriter(['prepositional_phrase', 'determiner'])\n",
    "rewritten_diagram = rewriter(diagram)\n",
    "\n",
    "rewritten_diagram.draw(figsize=(11,5), fontsize=13)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Parse the sentence](https://docs.quantinuum.com/lambeq/_code/rewrite.html)** — `_code/rewrite` block 3\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "curry_functor = Rewriter(['curry'])\n",
    "curried_diagram = curry_functor(normalised_diagram)\n",
    "curried_diagram.draw(figsize=(9,4), fontsize=13)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Get a string diagram](https://docs.quantinuum.com/lambeq/_code/parameterise.html)** — `_code/parameterise` block 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from lambeq import BobcatParser\n",
    "\n",
    "sentence = 'John walks in the park'\n",
    "\n",
    "# Get a string diagram\n",
    "parser = BobcatParser(verbose='text')\n",
    "diagram = parser.sentence2diagram(sentence)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Get a string diagram](https://docs.quantinuum.com/lambeq/_code/parameterise.html)** — `_code/parameterise` block 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from lambeq import AtomicType, IQPAnsatz\n",
    "\n",
    "# Define atomic types\n",
    "N = AtomicType.NOUN\n",
    "S = AtomicType.SENTENCE\n",
    "\n",
    "# Convert string diagram to quantum circuit\n",
    "ansatz = IQPAnsatz({N: 1, S: 1}, n_layers=2)\n",
    "circuit = ansatz(diagram)\n",
    "circuit.draw(figsize=(15,10))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Get a string diagram](https://docs.quantinuum.com/lambeq/_code/parameterise.html)** — `_code/parameterise` block 2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket.circuit.display import render_circuit_jupyter\n",
    "\n",
    "tket_circuit = circuit.to_tk()\n",
    "\n",
    "render_circuit_jupyter(tket_circuit)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Define atomic types](https://docs.quantinuum.com/lambeq/_code/training-symbols.html)** — `_code/training-symbols` block 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "from lambeq import AtomicType, BobcatParser, TensorAnsatz\n",
    "from lambeq.backend.tensor import Dim\n",
    "\n",
    "# Define atomic types\n",
    "N = AtomicType.NOUN\n",
    "S = AtomicType.SENTENCE\n",
    "\n",
    "# Parse a sentence\n",
    "parser = BobcatParser(verbose='suppress')\n",
    "diagram = parser.sentence2diagram('John walks in the park')\n",
    "\n",
    "# Apply a tensor ansatz\n",
    "ansatz = TensorAnsatz({N: Dim(4), S: Dim(2)})\n",
    "tensor_diagram = ansatz(diagram)\n",
    "tensor_diagram.draw(figsize=(12,5), fontsize=12)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Define atomic types](https://docs.quantinuum.com/lambeq/_code/training-symbols.html)** — `_code/training-symbols` block 3\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from lambeq import IQPAnsatz\n",
    "\n",
    "iqp_ansatz = IQPAnsatz({N: 1, S: 1}, n_layers=1)\n",
    "circuit = iqp_ansatz(diagram)\n",
    "circuit.draw(figsize=(12,8), fontsize=12)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Define atomic types](https://docs.quantinuum.com/lambeq/_code/training-symbols.html)** — `_code/training-symbols` block 6\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "tensors = [np.random.rand(p.size) for p in parameters]\n",
    "print(tensors[0])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Using the builtin binary cross-entropy error from lambeq](https://docs.quantinuum.com/lambeq/_code/trainer-quantum.html)** — `_code/trainer-quantum` block 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import warnings\n",
    "\n",
    "warnings.filterwarnings('ignore')\n",
    "os.environ['TOKENIZERS_PARALLELISM'] = 'true'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Using the builtin binary cross-entropy error from lambeq](https://docs.quantinuum.com/lambeq/_code/trainer-quantum.html)** — `_code/trainer-quantum` block 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "BATCH_SIZE = 10\n",
    "EPOCHS = 100\n",
    "SEED = 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Using the builtin binary cross-entropy error from lambeq](https://docs.quantinuum.com/lambeq/_code/trainer-quantum.html)** — `_code/trainer-quantum` block 2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def read_data(filename):\n",
    "    labels, sentences = [], []\n",
    "    with open(filename) as f:\n",
    "        for line in f:\n",
    "            t = int(line[0])\n",
    "            labels.append([t, 1-t])\n",
    "            sentences.append(line[1:].strip())\n",
    "    return labels, sentences\n",
    "\n",
    "\n",
    "train_labels, train_data = read_data('../examples/datasets/rp_train_data.txt')\n",
    "val_labels, val_data = read_data('../examples/datasets/rp_test_data.txt')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Circuit](https://docs.quantinuum.com/lambeq/examples/circuit.html)** — `examples/circuit` block 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pytket.circuit.display import render_circuit_jupyter\n",
    "\n",
    "from lambeq import AtomicType, BobcatParser, IQPAnsatz\n",
    "\n",
    "N = AtomicType.NOUN\n",
    "S = AtomicType.SENTENCE"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Circuit](https://docs.quantinuum.com/lambeq/examples/circuit.html)** — `examples/circuit` block 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "parser = BobcatParser()\n",
    "diagram = parser.sentence2diagram('Alice runs')\n",
    "diagram.draw()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Circuit](https://docs.quantinuum.com/lambeq/examples/circuit.html)** — `examples/circuit` block 2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "ansatz = IQPAnsatz({N: 1, S: 1}, n_layers=2)\n",
    "circuit = ansatz(diagram)\n",
    "circuit.draw(figsize=(8, 8))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Quantum pipeline using the Quantum Trainer](https://docs.quantinuum.com/lambeq/examples/quantum-pipeline.html)** — `examples/quantum-pipeline` block 0\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "\n",
    "import os\n",
    "os.environ[\"TOKENIZERS_PARALLELISM\"] = \"false\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Quantum pipeline using the Quantum Trainer](https://docs.quantinuum.com/lambeq/examples/quantum-pipeline.html)** — `examples/quantum-pipeline` block 1\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "\n",
    "BATCH_SIZE = 30\n",
    "EPOCHS = 120\n",
    "SEED = 2"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Quantum pipeline using the Quantum Trainer](https://docs.quantinuum.com/lambeq/examples/quantum-pipeline.html)** — `examples/quantum-pipeline` block 2\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def read_data(filename):\n",
    "    labels, sentences = [], []\n",
    "    with open(filename) as f:\n",
    "        for line in f:\n",
    "            t = int(line[0])\n",
    "            labels.append([t, 1-t])\n",
    "            sentences.append(line[1:].strip())\n",
    "    return labels, sentences\n",
    "\n",
    "\n",
    "train_labels, train_data = read_data('datasets/mc_train_data.txt')\n",
    "dev_labels, dev_data = read_data('datasets/mc_dev_data.txt')\n",
    "test_labels, test_data = read_data('datasets/mc_test_data.txt')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Step 2. Diagram rewriting](https://docs.quantinuum.com/lambeq/tutorials/rewrite.html)** — `tutorials/rewrite` block 5\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from lambeq.backend.grammar import Diagram, Word, Ty, Cup\n",
    "from lambeq import AtomicType\n",
    "\n",
    "n = AtomicType.NOUN\n",
    "s = AtomicType.SENTENCE\n",
    "\n",
    "words = [Word('do', n.r @ s @ n.l), Word('your', n @ n.l),\n",
    "         Word('homework', n), Word('now', s.r @ s)]\n",
    "morphisms = [(Cup, 2, 3), (Cup, 4, 5), (Cup, 1, 6)]\n",
    "diagram = Diagram.create_pregroup_diagram(words, morphisms)\n",
    "diagram.draw(figsize=(5,2))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**[Step 2. Diagram rewriting](https://docs.quantinuum.com/lambeq/tutorials/rewrite.html)** — `tutorials/rewrite` block 6\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from lambeq import UnifyCodomainRewriter\n",
    "\n",
    "rewriter = UnifyCodomainRewriter(output_type=s)\n",
    "\n",
    "rewriter(diagram).draw(figsize=(5,4))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Bridge: where lambeq would meet this stack\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# lambeq is not in this repo's dependency set — it is included here because its\n",
    "# output is a pytket Circuit, which is exactly the object the tket lane already\n",
    "# compiles and the Selene lane already runs:\n",
    "#\n",
    "#     circuit = ansatz(diagram).to_pytket()\n",
    "#     compiled = backend.get_compiled_circuit(circuit, optimisation_level=2)\n",
    "#\n",
    "# Anything generated or variational must be split at its rotation boundaries before\n",
    "# the Clifford canonicaliser touches it — see references/rewriter-composition.md.\n",
    "print('lambeq -> pytket Circuit -> quantum/tket/compile.py')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Pitfalls\n",
    "\n",
    "1. lambeq is not installed in this repo's `.pydeps`; these cells are syntax-checked, not executed.\n",
    "2. The parser downloads a model on first use — the first cell that parses a sentence needs network access and is slow.\n",
    "3. Only Clifford segments of a generated ansatz may go through our rule-(N/M/P) canonicaliser; leave `Ry(θ)`/`Rz(θ)` cores opaque and verify them with the dense matrix oracle.\n"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "name": "python",
   "version": "3.12"
  },
  "title": "lambeq quickstart"
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
