{
  "nbformat": 4,
  "nbformat_minor": 5,
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "name": "python",
      "version": "3.10"
    }
  },
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# What Quorum Arithmetic Leaves Out\n",
        "\n",
        "Exhaustive finite-set checks and deterministic replica traces. The results show protocol counterexamples, not observed production failure frequencies. The code models fixed quorums, sloppy respondents, and the read write-back mechanism.\n",
        "\n",
        "Extract the complete package and run from this directory. Python 3.10+, standard library. No network calls."
      ],
      "id": "cell-01"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "from pathlib import Path\n",
        "import runpy, json, csv\n",
        "ROOT = Path.cwd()\n",
        "assert (ROOT / 'experiment.py').is_file(), 'Open this notebook from its extracted topic folder.'\n",
        "experiment = runpy.run_path(str(ROOT / 'experiment.py'))"
      ],
      "execution_count": 1,
      "outputs": [],
      "id": "cell-02"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Run and check\n",
        "The script executes the experiment and its assertions, then writes the data and figures."
      ],
      "id": "cell-03"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "summary = experiment['run'](ROOT)\n",
        "print(json.dumps(summary, indent=2))"
      ],
      "execution_count": 2,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "{\n",
            "  \"strict_pairs\": 9,\n",
            "  \"strict_disjoint\": 0,\n",
            "  \"expanded_pairs\": 100,\n",
            "  \"expanded_disjoint\": 30,\n",
            "  \"theorem_configurations_checked\": 140,\n",
            "  \"theorem_pairs_checked\": 21343,\n",
            "  \"writeback_pairs_checked\": 9,\n",
            "  \"sloppy_read_before_handoff\": 0,\n",
            "  \"sloppy_read_after_handoff\": 1,\n",
            "  \"sequential_reads_without_writeback\": [\n",
            "    1,\n",
            "    0\n",
            "  ],\n",
            "  \"sequential_reads_with_writeback\": [\n",
            "    1,\n",
            "    1\n",
            "  ],\n",
            "  \"measurement\": \"Exhaustive finite-set model plus explicit deterministic traces, not a database benchmark or failure probability\",\n",
            "  \"python\": \"3.12.14\",\n",
            "  \"run_date\": \"2026-11-06\"\n",
            "}\n"
          ]
        }
      ],
      "id": "cell-04"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Inspect disjoint respondent pairs\n",
        "The 30 disjoint pairs are structural counterexamples, not a probability estimate."
      ],
      "id": "cell-05"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "rows = experiment['pairs']('ABCDE')\n",
        "disjoint = [row for row in rows if row['overlap'] == 0]\n",
        "print('Disjoint pairs:', len(disjoint))\n",
        "print(disjoint[:10])\n",
        "assert len(disjoint) == 30"
      ],
      "execution_count": 3,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Disjoint pairs: 30\n",
            "[{'write': 'AB', 'read': 'CD', 'intersection': '', 'overlap': 0}, {'write': 'AB', 'read': 'CE', 'intersection': '', 'overlap': 0}, {'write': 'AB', 'read': 'DE', 'intersection': '', 'overlap': 0}, {'write': 'AC', 'read': 'BD', 'intersection': '', 'overlap': 0}, {'write': 'AC', 'read': 'BE', 'intersection': '', 'overlap': 0}, {'write': 'AC', 'read': 'DE', 'intersection': '', 'overlap': 0}, {'write': 'AD', 'read': 'BC', 'intersection': '', 'overlap': 0}, {'write': 'AD', 'read': 'BE', 'intersection': '', 'overlap': 0}, {'write': 'AD', 'read': 'CE', 'intersection': '', 'overlap': 0}, {'write': 'AE', 'read': 'BC', 'intersection': '', 'overlap': 0}]\n"
          ]
        }
      ],
      "id": "cell-06"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Compare the read protocol\n",
        "One pending write reaches A only. Without write-back, sequential reads AB then BC return 1 then 0. Synchronous majority write-back before returning changes this trace to 1 then 1."
      ],
      "id": "cell-07"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "for repair in [False, True]:\n",
        "    print('Synchronous write-back:', repair)\n",
        "    for row in experiment['inversion_trace'](repair):\n",
        "        print(row)"
      ],
      "execution_count": 4,
      "outputs": [
        {
          "output_type": "stream",
          "name": "stdout",
          "text": [
            "Synchronous write-back: False\n",
            "{'step': 0, 'event': 'Initial state', 'A': 0, 'B': 0, 'C': 0, 'result': ''}\n",
            "{'step': 1, 'event': 'Write v1 reaches A only; write is still pending', 'A': 1, 'B': 0, 'C': 0, 'result': ''}\n",
            "{'step': 2, 'event': 'Read 1 obtains A,B and selects newest version', 'A': 1, 'B': 0, 'C': 0, 'result': 'selected v1'}\n",
            "{'step': 4, 'event': 'Read 1 completes', 'A': 1, 'B': 0, 'C': 0, 'result': 'returns v1'}\n",
            "{'step': 5, 'event': 'Read 2 starts later and obtains B,C', 'A': 1, 'B': 0, 'C': 0, 'result': 'returns v0'}\n",
            "Synchronous write-back: True\n",
            "{'step': 0, 'event': 'Initial state', 'A': 0, 'B': 0, 'C': 0, 'result': ''}\n",
            "{'step': 1, 'event': 'Write v1 reaches A only; write is still pending', 'A': 1, 'B': 0, 'C': 0, 'result': ''}\n",
            "{'step': 2, 'event': 'Read 1 obtains A,B and selects newest version', 'A': 1, 'B': 0, 'C': 0, 'result': 'selected v1'}\n",
            "{'step': 3, 'event': 'Read 1 writes v1 back to A,B and waits for both acknowledgments', 'A': 1, 'B': 1, 'C': 0, 'result': ''}\n",
            "{'step': 4, 'event': 'Read 1 completes', 'A': 1, 'B': 1, 'C': 0, 'result': 'returns v1'}\n",
            "{'step': 5, 'event': 'Read 2 starts later and obtains B,C', 'A': 1, 'B': 1, 'C': 0, 'result': 'returns v1'}\n"
          ]
        }
      ],
      "id": "cell-08"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Generated figures"
      ],
      "id": "cell-09"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "from IPython.display import SVG, display\n",
        "display(SVG(filename=str(ROOT / 'figures/intersections.svg')))"
      ],
      "execution_count": 5,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/svg+xml": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"800\" height=\"425\" viewBox=\"0 0 800 425\" role=\"img\"><title>Fixed membership forces an overlap</title>\n<rect width=\"100%\" height=\"100%\" fill=\"#faf9f6\"/>\n<g font-family=\"Arial,sans-serif\" fill=\"#222\">\n<text x=\"26\" y=\"38\" font-size=\"24\" font-weight=\"600\">Fixed membership forces an overlap</text>\n<text x=\"26\" y=\"65\" font-size=\"14\" fill=\"#666\">Cells list shared respondents. Write acknowledgments are rows; read respondents are columns.</text>\n<text x=\"255\" y=\"110\" font-size=\"20\">AB</text>\n<text x=\"95\" y=\"163\" font-size=\"20\">AB</text>\n<text x=\"405\" y=\"110\" font-size=\"20\">AC</text>\n<text x=\"95\" y=\"238\" font-size=\"20\">AC</text>\n<text x=\"555\" y=\"110\" font-size=\"20\">BC</text>\n<text x=\"95\" y=\"313\" font-size=\"20\">BC</text>\n<rect x=\"205\" y=\"127\" width=\"135\" height=\"61\" fill=\"#ede1de\" rx=\"4\"/>\n<text x=\"272\" y=\"165\" text-anchor=\"middle\" font-size=\"22\">AB</text>\n<rect x=\"355\" y=\"127\" width=\"135\" height=\"61\" fill=\"#ede1de\" rx=\"4\"/>\n<text x=\"422\" y=\"165\" text-anchor=\"middle\" font-size=\"22\">A</text>\n<rect x=\"505\" y=\"127\" width=\"135\" height=\"61\" fill=\"#ede1de\" rx=\"4\"/>\n<text x=\"572\" y=\"165\" text-anchor=\"middle\" font-size=\"22\">B</text>\n<rect x=\"205\" y=\"202\" width=\"135\" height=\"61\" fill=\"#ede1de\" rx=\"4\"/>\n<text x=\"272\" y=\"240\" text-anchor=\"middle\" font-size=\"22\">A</text>\n<rect x=\"355\" y=\"202\" width=\"135\" height=\"61\" fill=\"#ede1de\" rx=\"4\"/>\n<text x=\"422\" y=\"240\" text-anchor=\"middle\" font-size=\"22\">AC</text>\n<rect x=\"505\" y=\"202\" width=\"135\" height=\"61\" fill=\"#ede1de\" rx=\"4\"/>\n<text x=\"572\" y=\"240\" text-anchor=\"middle\" font-size=\"22\">C</text>\n<rect x=\"205\" y=\"277\" width=\"135\" height=\"61\" fill=\"#ede1de\" rx=\"4\"/>\n<text x=\"272\" y=\"315\" text-anchor=\"middle\" font-size=\"22\">B</text>\n<rect x=\"355\" y=\"277\" width=\"135\" height=\"61\" fill=\"#ede1de\" rx=\"4\"/>\n<text x=\"422\" y=\"315\" text-anchor=\"middle\" font-size=\"22\">C</text>\n<rect x=\"505\" y=\"277\" width=\"135\" height=\"61\" fill=\"#ede1de\" rx=\"4\"/>\n<text x=\"572\" y=\"315\" text-anchor=\"middle\" font-size=\"22\">BC</text>\n<text x=\"95\" y=\"393\" font-size=\"16\" fill=\"#666\">All 9 pairs overlap when N=3 and R=W=2 use the same A,B,C.</text>\n</g></svg>"
          },
          "metadata": {}
        }
      ],
      "id": "cell-10"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "from IPython.display import SVG, display\n",
        "display(SVG(filename=str(ROOT / 'figures/read-inversion.svg')))"
      ],
      "execution_count": 6,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/svg+xml": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1000\" height=\"515\" viewBox=\"0 0 1000 515\" role=\"img\"><title>An unfinished write can produce a read\u2013read inversion</title>\n<rect width=\"100%\" height=\"100%\" fill=\"#faf9f6\"/>\n<g font-family=\"Arial,sans-serif\" fill=\"#222\">\n<text x=\"26\" y=\"38\" font-size=\"24\" font-weight=\"600\">An unfinished write can produce a read\u2013read inversion</text>\n<text x=\"26\" y=\"65\" font-size=\"14\" fill=\"#666\">All reads collect two home replicas. This version of the protocol omits synchronous write-back.</text>\n<text x=\"625\" y=\"108\" text-anchor=\"middle\" font-size=\"17\">A</text>\n<text x=\"687\" y=\"108\" text-anchor=\"middle\" font-size=\"17\">B</text>\n<text x=\"749\" y=\"108\" text-anchor=\"middle\" font-size=\"17\">C</text>\n<text x=\"28\" y=\"143\" font-size=\"14\">0 Initial state</text>\n<rect x=\"605\" y=\"125\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"625\" y=\"151\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"667\" y=\"125\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"687\" y=\"151\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"729\" y=\"125\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"151\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"215\" font-size=\"14\">1 Write v1 reaches A only; write is still pending</text>\n<rect x=\"605\" y=\"197\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"223\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"197\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"687\" y=\"223\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"729\" y=\"197\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"223\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"287\" font-size=\"14\">2 Read 1 obtains A,B and selects newest version</text>\n<text x=\"42\" y=\"324\" font-size=\"13\" fill=\"#8b4345\">selected v1</text>\n<rect x=\"605\" y=\"269\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"295\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"269\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"687\" y=\"295\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"729\" y=\"269\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"295\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"359\" font-size=\"14\">4 Read 1 completes</text>\n<text x=\"42\" y=\"396\" font-size=\"13\" fill=\"#8b4345\">returns v1</text>\n<rect x=\"605\" y=\"341\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"367\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"341\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"687\" y=\"367\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"729\" y=\"341\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"367\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"431\" font-size=\"14\">5 Read 2 starts later and obtains B,C</text>\n<text x=\"42\" y=\"468\" font-size=\"13\" fill=\"#8b4345\">returns v0</text>\n<rect x=\"605\" y=\"413\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"439\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"413\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"687\" y=\"439\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"729\" y=\"413\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"439\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n</g></svg>"
          },
          "metadata": {}
        }
      ],
      "id": "cell-11"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "from IPython.display import SVG, display\n",
        "display(SVG(filename=str(ROOT / 'figures/read-writeback.svg')))"
      ],
      "execution_count": 7,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/svg+xml": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1000\" height=\"587\" viewBox=\"0 0 1000 587\" role=\"img\"><title>Writing back before returning prevents this inversion</title>\n<rect width=\"100%\" height=\"100%\" fill=\"#faf9f6\"/>\n<g font-family=\"Arial,sans-serif\" fill=\"#222\">\n<text x=\"26\" y=\"38\" font-size=\"24\" font-weight=\"600\">Writing back before returning prevents this inversion</text>\n<text x=\"26\" y=\"65\" font-size=\"14\" fill=\"#666\">The selected version reaches a majority before Read 1 completes.</text>\n<text x=\"625\" y=\"108\" text-anchor=\"middle\" font-size=\"17\">A</text>\n<text x=\"687\" y=\"108\" text-anchor=\"middle\" font-size=\"17\">B</text>\n<text x=\"749\" y=\"108\" text-anchor=\"middle\" font-size=\"17\">C</text>\n<text x=\"28\" y=\"143\" font-size=\"14\">0 Initial state</text>\n<rect x=\"605\" y=\"125\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"625\" y=\"151\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"667\" y=\"125\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"687\" y=\"151\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"729\" y=\"125\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"151\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"215\" font-size=\"14\">1 Write v1 reaches A only; write is still pending</text>\n<rect x=\"605\" y=\"197\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"223\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"197\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"687\" y=\"223\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"729\" y=\"197\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"223\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"287\" font-size=\"14\">2 Read 1 obtains A,B and selects newest version</text>\n<text x=\"42\" y=\"324\" font-size=\"13\" fill=\"#8b4345\">selected v1</text>\n<rect x=\"605\" y=\"269\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"295\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"269\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"687\" y=\"295\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"729\" y=\"269\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"295\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"359\" font-size=\"14\">3 Read 1 writes v1 back to A,B and waits for both acknowledgments</text>\n<rect x=\"605\" y=\"341\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"367\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"341\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"687\" y=\"367\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"729\" y=\"341\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"367\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"431\" font-size=\"14\">4 Read 1 completes</text>\n<text x=\"42\" y=\"468\" font-size=\"13\" fill=\"#8b4345\">returns v1</text>\n<rect x=\"605\" y=\"413\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"439\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"413\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"687\" y=\"439\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"729\" y=\"413\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"439\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"503\" font-size=\"14\">5 Read 2 starts later and obtains B,C</text>\n<text x=\"42\" y=\"540\" font-size=\"13\" fill=\"#8b4345\">returns v1</text>\n<rect x=\"605\" y=\"485\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"511\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"485\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"687\" y=\"511\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"729\" y=\"485\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"511\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n</g></svg>"
          },
          "metadata": {}
        }
      ],
      "id": "cell-12"
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "from IPython.display import SVG, display\n",
        "display(SVG(filename=str(ROOT / 'figures/sloppy-trace.svg')))"
      ],
      "execution_count": 8,
      "outputs": [
        {
          "output_type": "display_data",
          "data": {
            "image/svg+xml": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"1000\" height=\"515\" viewBox=\"0 0 1000 515\" role=\"img\"><title>A completed write can miss a later read</title>\n<rect width=\"100%\" height=\"100%\" fill=\"#faf9f6\"/>\n<g font-family=\"Arial,sans-serif\" fill=\"#222\">\n<text x=\"26\" y=\"38\" font-size=\"24\" font-weight=\"600\">A completed write can miss a later read</text>\n<text x=\"26\" y=\"65\" font-size=\"14\" fill=\"#666\">Different reachability: write responds through A,D; later read responds through B,C.</text>\n<text x=\"625\" y=\"108\" text-anchor=\"middle\" font-size=\"17\">A</text>\n<text x=\"687\" y=\"108\" text-anchor=\"middle\" font-size=\"17\">B</text>\n<text x=\"749\" y=\"108\" text-anchor=\"middle\" font-size=\"17\">C</text>\n<text x=\"811\" y=\"108\" text-anchor=\"middle\" font-size=\"17\">D</text>\n<text x=\"873\" y=\"108\" text-anchor=\"middle\" font-size=\"17\">E</text>\n<text x=\"28\" y=\"143\" font-size=\"14\">0 Home replicas A,B,C start at v0; D,E are fallback nodes</text>\n<rect x=\"605\" y=\"125\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"625\" y=\"151\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"667\" y=\"125\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"687\" y=\"151\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"729\" y=\"125\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"151\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"791\" y=\"125\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"811\" y=\"151\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"853\" y=\"125\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"873\" y=\"151\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"215\" font-size=\"14\">1 Write targets A,D,E; A,D store v1 and acknowledge</text>\n<text x=\"42\" y=\"252\" font-size=\"13\" fill=\"#8b4345\">write completes: W=2</text>\n<rect x=\"605\" y=\"197\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"223\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"197\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"687\" y=\"223\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"729\" y=\"197\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"223\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"791\" y=\"197\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"811\" y=\"223\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"853\" y=\"197\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"873\" y=\"223\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"287\" font-size=\"14\">2 Later read coordinator receives B,C; handoff is delayed</text>\n<text x=\"42\" y=\"324\" font-size=\"13\" fill=\"#8b4345\">read returns v0: R=2</text>\n<rect x=\"605\" y=\"269\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"295\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"269\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"687\" y=\"295\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"729\" y=\"269\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"295\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"791\" y=\"269\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"811\" y=\"295\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"853\" y=\"269\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"873\" y=\"295\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"359\" font-size=\"14\">3 D hands its hinted v1 to home replica B</text>\n<rect x=\"605\" y=\"341\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"367\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"341\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"687\" y=\"367\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"729\" y=\"341\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"367\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"791\" y=\"341\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"811\" y=\"367\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"853\" y=\"341\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"873\" y=\"367\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<text x=\"28\" y=\"431\" font-size=\"14\">4 Read B,C again with newest-version selection</text>\n<text x=\"42\" y=\"468\" font-size=\"13\" fill=\"#8b4345\">read returns v1</text>\n<rect x=\"605\" y=\"413\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"625\" y=\"439\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"667\" y=\"413\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"687\" y=\"439\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"729\" y=\"413\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"749\" y=\"439\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n<rect x=\"791\" y=\"413\" width=\"40\" height=\"40\" fill=\"#8b4345\" rx=\"3\"/>\n<text x=\"811\" y=\"439\" text-anchor=\"middle\" font-size=\"15\" fill=\"#fff\">v1</text>\n<rect x=\"853\" y=\"413\" width=\"40\" height=\"40\" fill=\"#e8e4df\" rx=\"3\"/>\n<text x=\"873\" y=\"439\" text-anchor=\"middle\" font-size=\"15\" fill=\"#555\">v0</text>\n</g></svg>"
          },
          "metadata": {}
        }
      ],
      "id": "cell-13"
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## Sources\n",
        "- [Dynamo: Amazon\u2019s Highly Available Key-value Store](https://cdn.amazon.science/ac/1d/eb50c4064c538c8ac440ce6a1d91/dynamo-amazons-highly-available-key-value-store.pdf)\n",
        "- [Sharing Memory Robustly in Message-Passing Systems](https://groups.csail.mit.edu/tds/papers/Attiya/JACM95.pdf)\n",
        "- [Bigtable replication overview](https://docs.cloud.google.com/bigtable/docs/replication-overview)\n",
        "- [How DynamoDB global tables work](https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/V2globaltables_HowItWorks.html)"
      ],
      "id": "cell-14"
    }
  ]
}
