<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="http://www.pokutta.com/blog/feed.xml" rel="self" type="application/atom+xml" /><link href="http://www.pokutta.com/blog/" rel="alternate" type="text/html" /><updated>2026-07-17T14:06:45+02:00</updated><id>http://www.pokutta.com/blog/feed.xml</id><title type="html">One trivial observation at a time</title><subtitle>Everything Mathematics, Optimization, Machine Learning, and Artificial Intelligence</subtitle><author><name>Sebastian Pokutta</name></author><entry><title type="html">Neural Concept Verifiers: Proving with Concepts, not Pixels</title><link href="http://www.pokutta.com/blog/neural-concept-verifier/" rel="alternate" type="text/html" title="Neural Concept Verifiers: Proving with Concepts, not Pixels" /><published>2026-07-09T00:00:00+02:00</published><updated>2026-07-09T00:00:00+02:00</updated><id>http://www.pokutta.com/blog/neural-concept-verifier</id><content type="html" xml:base="http://www.pokutta.com/blog/neural-concept-verifier/"><![CDATA[<p><em>TL;DR: This is a short summary of our paper <a href="https://arxiv.org/abs/2507.07532">Neural Concept Verifier: Scaling Prover-Verifier Games via Concept Encodings</a> by <a href="https://b-turan.github.io/">Berkant Turan</a>, <a href="https://openreview.net/profile?id=~Suhrab_Asadulla1">Suhrab Asadulla</a>, <a href="https://openreview.net/profile?id=~David_Steinmann1">David Steinmann</a>, <a href="https://www.ml.informatik.tu-darmstadt.de/people/kkersting/index.html">Kristian Kersting</a>, <a href="https://wolfstam.github.io/">Wolfgang Stammer</a>, and <a href="https://www.pokutta.com/">Sebastian Pokutta</a>. The paper was accepted as a spotlight at ICML 2026 (top ~2.2% of submissions). In a nutshell, we move Prover-Verifier Games from pixel space to concept space: a prover selects a sparse set of human-readable concepts, a verifier must classify using only those concepts, and an adversarial prover tests whether the verifier can be fooled. The result is a scalable route to verifiable, nonlinear concept-based classification on datasets such as CLEVR-Hans, CIFAR-100, ImageNet-1k, and COCOLogic.</em></p>

<!--more-->

<h2 id="why-another-interpretability-model">Why another interpretability model?</h2>

<p>Interpretability in machine learning has a slightly uncomfortable failure mode: the explanation is often easier to look at than to trust. A heatmap may highlight part of an image, but it is not obvious whether the highlighted pixels are actually needed for the decision, whether the model would behave differently under a competing explanation, or whether the visual saliency is mostly a correlation artifact. This is particularly problematic in settings where we care about being <em>right for the right reasons</em>, not merely about having a plausible-looking explanation.</p>

<p>Prover-Verifier Games (PVGs) give a clean abstraction for this. A prover provides evidence; a verifier is forced to decide from that evidence; and an adversarial prover tries to construct misleading evidence. The idea has a long lineage: it descends from interactive proof systems in complexity theory <a href="https://doi.org/10.1145/22145.22178">[GMR85]</a>, entered machine learning as a game between learning agents <a href="https://arxiv.org/abs/2108.12099">[AZWG21]</a>, is closely related to debate-style oversight <a href="https://arxiv.org/abs/1805.00899">[ICA18]</a>, and has recently been used to make LLM outputs easier to check <a href="https://arxiv.org/abs/2407.13692">[KCELMB24]</a>. In earlier work on Merlin-Arthur classifiers, we instantiated this structure for classification and obtained formal interpretability guarantees by selecting sparse input features and measuring completeness and soundness <a href="https://proceedings.mlr.press/v238/waldchen24a.html">[WSTZP24]</a>. However, doing this directly on pixels creates a very practical bottleneck: high-dimensional images are hard to optimize over, and pixel masks are often not the units humans actually reason with.</p>

<p>Concept Bottleneck Models (CBMs) go in the opposite direction <a href="https://proceedings.mlr.press/v119/koh20a.html">[KNTMPKL20]</a>. They map an input into an intermediate layer of concepts and then classify from those concepts. This is attractive because the interface is no longer raw pixels; it is something like “red object”, “metal sphere”, “handle”, or “striped texture”. The usual catch is that many CBMs use a linear classifier on top of the concept layer, which is interpretable but also brittle when the task requires nonlinear interactions among concepts. Counting, XOR-like rules, and permutation-invariant object relations are the standard examples.</p>

<p>Neural Concept Verifier (NCV) combines these two ideas. We keep the concept layer, but replace the simple classifier by a prover-verifier game over sparse concept subsets. Put differently: the proof is not a pixel mask, but a small set of concepts.</p>

<h2 id="the-setup">The setup</h2>

<p>NCV has four moving parts:</p>

<ol>
  <li>A concept extractor maps the input image to a concept encoding.</li>
  <li>Merlin, the cooperative prover, selects a sparse subset of concepts that should support the correct class.</li>
  <li>Morgana, the adversarial prover, selects a sparse subset of concepts that tries to mislead the verifier.</li>
  <li>Arthur, the verifier, predicts using only the selected concepts, and may reject when the evidence is not good enough.</li>
</ol>

<p>The important shift is that Merlin and Morgana no longer play in pixel space. They play in concept space. This reduces dimensionality and makes the evidence more meaningful; it also lets Arthur be nonlinear without giving up the prover-verifier structure. In our experiments, the concept extractor is instantiated either through Neural Concept Binder (NCB) for CLEVR-Hans <a href="https://proceedings.neurips.cc/paper_files/paper/2024/hash/8402cf3031d649066ada24514739f0dd-Abstract-Conference.html">[SWSK24]</a>, or through CLIP/SpLiCE-style concept scores for CIFAR-100, ImageNet-1k, and COCOLogic <a href="https://proceedings.neurips.cc/paper_files/paper/2024/hash/996bef37d8a638f37bdfcac2789e835d-Abstract-Conference.html">[BOSCL24]</a>. Sparsity is enforced at selection time: per input, the provers select 12 of the NCB slot encodings on CLEVR-Hans, and 32 concepts out of a 10,000-term CLIP vocabulary (derived from LAION captions) on the natural-image datasets.</p>

<style>
.ncv-widget{
  margin:22px 0;
  background:#f8f9fa;
  border:1px solid #e0e0e0;
  border-radius:8px;
  padding:16px;
}
.ncv-header{
  display:flex;
  justify-content:space-between;
  gap:12px;
  align-items:flex-start;
  margin-bottom:12px;
}
.ncv-title{font-weight:700}
.ncv-sub{font-size:12px;color:#6b7280;text-align:right}
.ncv-controls{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  gap:12px;
  margin-bottom:14px;
}
.ncv-control label{
  display:block;
  font-size:12px;
  font-weight:700;
  color:#374151;
  margin-bottom:4px;
}
.ncv-control select,
.ncv-control input{width:100%}
.ncv-panel{
  background:#fff;
  border:1px solid #e5e7eb;
  border-radius:6px;
  padding:12px;
}
.ncv-chip-line{
  display:flex;
  flex-wrap:wrap;
  gap:6px;
}
.ncv-chip{
  display:inline-block;
  padding:4px 7px;
  border:1px solid #cbd5e1;
  border-radius:5px;
  background:#fff;
  font-size:12px;
  line-height:1.2;
}
.ncv-chip.good{border-color:#86efac;background:#f0fdf4}
.ncv-chip.bad{border-color:#fecaca;background:#fff7f7}
.ncv-chip.muted{color:#6b7280;background:#f9fafb}
.ncv-kpis{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(145px,1fr));
  gap:10px;
  margin:12px 0;
}
.ncv-kpi{
  background:#fff;
  border:1px solid #e5e7eb;
  border-radius:6px;
  padding:10px;
}
.ncv-kpi-label{font-size:11px;color:#6b7280;margin-bottom:4px}
.ncv-kpi-value{font-size:17px;font-weight:700;color:#111827}
.ncv-chip.rule{border-color:#0f766e;box-shadow:inset 0 0 0 1px #0f766e}
.ncv-note{font-size:12px;color:#555;margin-top:8px}
</style>

<div id="ncv-game" class="ncv-widget">
  <div class="ncv-header">
    <div>
      <div class="ncv-title">A tiny prover-verifier game in concept space</div>
      <div style="font-size:12px;color:#555;">Pick a scenario, a prover, and a concept budget, then see what Arthur does with the evidence.</div>
    </div>
    <div class="ncv-sub">Illustrative widget<br />not live model output</div>
  </div>
  <div class="ncv-controls">
    <div class="ncv-control">
      <label for="ncv-scenario">Scenario</label>
      <select id="ncv-scenario"></select>
    </div>
    <div class="ncv-control">
      <label for="ncv-player">Evidence source</label>
      <select id="ncv-player">
        <option value="merlin">Merlin: helpful proof</option>
        <option value="morgana">Morgana: misleading proof</option>
      </select>
    </div>
    <div class="ncv-control">
      <label for="ncv-mask">Concept budget: <span id="ncv-mask-label">3</span></label>
      <input id="ncv-mask" type="range" min="1" max="5" step="1" value="3" />
    </div>
  </div>
  <svg id="ncv-game-svg" viewBox="0 0 760 230" style="width:100%;height:auto;background:#fff;border:1px solid #e5e7eb;border-radius:6px;"></svg>
  <div class="ncv-kpis">
    <div class="ncv-kpi">
      <div class="ncv-kpi-label">Arthur's decision</div>
      <div id="ncv-verdict" class="ncv-kpi-value">accept</div>
    </div>
    <div class="ncv-kpi">
      <div class="ncv-kpi-label">Concepts shown to Arthur</div>
      <div id="ncv-visible-count" class="ncv-kpi-value">3</div>
    </div>
    <div class="ncv-kpi">
      <div class="ncv-kpi-label">Property probed</div>
      <div id="ncv-test" class="ncv-kpi-value">completeness</div>
    </div>
  </div>
  <div class="ncv-panel">
    <div style="font-size:12px;font-weight:700;color:#374151;margin-bottom:8px;">Selected concepts <span id="ncv-rule-hint" style="font-weight:400;color:#6b7280;"></span></div>
    <div id="ncv-selected" class="ncv-chip-line"></div>
  </div>
  <div id="ncv-game-note" class="ncv-note"></div>
  <div class="ncv-note">In the paper itself, the provers select 12 concepts per input on CLEVR-Hans (NCB slots) and 32 on the natural-image datasets (CLIP vocabulary); the budget here is shrunk for readability.</div>
</div>

<script>
(function(){
  const scenarios = [
    {
      name:'CLEVR-Hans3: class rule',
      image:'CLEVR scene',
      extractor:'NCB, object slots',
      classLabel:'class 1',
      rule:['small cube','small metal sphere'],
      merlin:['small metal sphere','small cube','metal material','small size','sphere shape'],
      morgana:['gray cylinder','rubber material','background','large cube','scene layout'],
      note:'With an object-centric extractor (NCB), concepts correspond to object-level factors. Merlin recovers the class rule reported in the paper, i.e., small cube plus small metal sphere; Morgana points at distractors.'
    },
    {
      name:'ImageNet-1k: coffee mug',
      image:'photo of a mug',
      extractor:'CLIP vocabulary, 10k terms',
      classLabel:'coffee mug',
      rule:['mugs','cups'],
      merlin:['mugs','cups','cappuchino','extend','support'],
      morgana:['keyboard','desk','wood grain','shadow','person'],
      note:'Merlin\'s pool here is the actual top-5 concept selection for the coffee-mug class from the paper, including the vocabulary\'s creative spelling of "cappuchino". Open-vocabulary concepts are noisier, but the interface is unchanged: Arthur decides from a sparse, named subset.'
    },
    {
      name:'Confounded CLEVR-Hans: shortcut trap',
      image:'confounded scene',
      extractor:'NCB, object slots',
      classLabel:'class 1',
      rule:['small cube','small metal sphere'],
      merlin:['small cube','small metal sphere','metal material','small size','sphere shape'],
      morgana:['gray color','background texture','corner artifact','rubber material','large object'],
      note:'In the confounded training split, gray objects correlate with class 1. Morgana exploits exactly such shortcut concepts; soundness is high when Arthur stays correct or rejects instead of being lured into the wrong class.'
    }
  ];

  const scenarioSel = document.getElementById('ncv-scenario');
  const playerSel = document.getElementById('ncv-player');
  const mask = document.getElementById('ncv-mask');
  const maskLabel = document.getElementById('ncv-mask-label');
  const svg = document.getElementById('ncv-game-svg');
  const selected = document.getElementById('ncv-selected');
  const verdict = document.getElementById('ncv-verdict');
  const visibleCount = document.getElementById('ncv-visible-count');
  const test = document.getElementById('ncv-test');
  const note = document.getElementById('ncv-game-note');
  const ruleHint = document.getElementById('ncv-rule-hint');

  scenarios.forEach((s, i) => {
    const opt = document.createElement('option');
    opt.value = i;
    opt.textContent = s.name;
    scenarioSel.appendChild(opt);
  });

  function esc(x){ return x.replace(/&/g,'&amp;').replace(/</g,'&lt;'); }

  function draw(s, state) {
    const helpful = state.player === 'merlin';
    const color = helpful ? '#0f766e' : '#dc2626';
    const bg = helpful ? '#ecfdf5' : '#fef2f2';
    let html = '';
    html += '<text x="24" y="24" font-size="13" font-weight="700" fill="#111">The game is played over concepts, not pixels</text>';
    const boxes = [
      {x:30, y:74, w:140, h:64, title:'image', sub:s.image, active:true, c:'#6b7280'},
      {x:212, y:74, w:158, h:64, title:'concept extractor', sub:s.extractor, active:true, c:'#6b7280'},
      {x:412, y:40, w:150, h:52, title:'Merlin', sub:'helpful subset', active:helpful, c:'#0f766e'},
      {x:412, y:120, w:150, h:52, title:'Morgana', sub:'misleading subset', active:!helpful, c:'#dc2626'},
      {x:604, y:74, w:130, h:64, title:'Arthur', sub:state.arthurSub, active:true, c:state.verdictColor}
    ];
    boxes.forEach(b => {
      const isProver = b.title === 'Merlin' || b.title === 'Morgana';
      html += `<g opacity="${b.active ? 1 : 0.42}">`;
      html += `<rect x="${b.x}" y="${b.y}" width="${b.w}" height="${b.h}" rx="7" fill="${b.active && isProver ? bg : '#fff'}" stroke="${b.active ? b.c : '#d1d5db'}" stroke-width="${b.active ? 1.8 : 1}"/>`;
      html += `<text x="${b.x + b.w/2}" y="${b.y + (isProver ? 22 : 26)}" text-anchor="middle" font-size="13" font-weight="700" fill="#111">${b.title}</text>`;
      html += `<text x="${b.x + b.w/2}" y="${b.y + (isProver ? 40 : 45)}" text-anchor="middle" font-size="11" fill="#555">${esc(b.sub)}</text>`;
      html += '</g>';
    });
    html += '<defs><marker id="ncvarrow" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0,0 L8,4 L0,8 Z" fill="#6b7280"/></marker></defs>';
    function arrow(x1,y1,x2,y2,c,w,o){
      html += `<line x1="${x1}" y1="${y1}" x2="${x2}" y2="${y2}" stroke="${c}" stroke-width="${w}" opacity="${o}" marker-end="url(#ncvarrow)"/>`;
    }
    arrow(170,106,210,106,'#6b7280',2,1);
    arrow(370,106,410,68,'#6b7280',2, helpful ? 1 : 0.45);
    arrow(370,106,410,144,'#6b7280',2, helpful ? 0.45 : 1);
    arrow(562,66,602,98, color, helpful ? 2.5 : 1.5, helpful ? 1 : 0.35);
    arrow(562,146,602,114, color, helpful ? 1.5 : 2.5, helpful ? 0.35 : 1);
    html += `<text x="30" y="210" font-size="11.5" fill="#555">${helpful ? 'Completeness: how often Arthur recovers the true label from Merlin\u2019s sparse evidence.' : 'Soundness: how often Arthur avoids a wrong label under Morgana\u2019s evidence, by staying correct or rejecting.'}</text>`;
    svg.innerHTML = html;
  }

  function update() {
    const s = scenarios[parseInt(scenarioSel.value, 10)];
    const player = playerSel.value;
    const k = parseInt(mask.value, 10);
    const helpful = player === 'merlin';
    const pool = helpful ? s.merlin : s.morgana;
    const concepts = pool.slice(0, k);
    const ruleCovered = s.rule.every(r => concepts.indexOf(r) >= 0);

    let verdictText, verdictColor, arthurSub;
    if (helpful && ruleCovered) {
      verdictText = 'accept: ' + s.classLabel;
      verdictColor = '#0f766e';
      arthurSub = 'evidence suffices';
    } else if (helpful) {
      verdictText = 'reject (\u22A5)';
      verdictColor = '#b45309';
      arthurSub = 'evidence too sparse';
    } else {
      verdictText = 'reject (\u22A5) or stay correct';
      verdictColor = '#0f766e';
      arthurSub = 'not fooled';
    }

    maskLabel.textContent = k;
    selected.innerHTML = concepts.map(c => {
      const isRule = helpful && s.rule.indexOf(c) >= 0;
      return `<span class="ncv-chip ${helpful ? 'good' : 'bad'}${isRule ? ' rule' : ''}">${esc(c)}</span>`;
    }).join('');
    ruleHint.textContent = helpful ? '(outlined chips form the class rule)' : '';
    verdict.textContent = verdictText;
    verdict.style.color = verdictColor;
    visibleCount.textContent = concepts.length.toString();
    test.textContent = helpful ? 'completeness' : 'soundness';
    note.textContent = s.note;
    draw(s, {player:player, verdictColor:verdictColor, arthurSub:arthurSub});
  }

  scenarioSel.addEventListener('change', update);
  playerSel.addEventListener('change', update);
  mask.addEventListener('input', update);
  update();
})();
</script>

<h2 id="what-changes-empirically">What changes empirically?</h2>

<p>The short version is that pixel-level PVGs scale poorly on real images, while NCV remains competitive and often improves over both linear CBMs and black-box baselines. The table in the paper is dense, so the widget below lets you inspect one dataset at a time. Completeness is the cooperative side of the game, essentially accuracy under Merlin’s selected concepts. Soundness is the adversarial side, i.e., whether Arthur avoids a wrong answer under Morgana’s misleading concepts, possibly by rejecting.</p>

<div id="ncv-results" class="ncv-widget">
  <div class="ncv-header">
    <div>
      <div class="ncv-title">Completeness and soundness by dataset</div>
      <div style="font-size:12px;color:#555;">Mean &#177; standard deviation from the paper's main results table.</div>
    </div>
    <div class="ncv-sub">Higher is better<br />soundness only where applicable</div>
  </div>
  <div class="ncv-controls">
    <div class="ncv-control">
      <label for="ncv-data">Dataset</label>
      <select id="ncv-data"></select>
    </div>
  </div>
  <svg id="ncv-results-svg" viewBox="0 0 760 408" style="width:100%;height:auto;background:#fff;border:1px solid #e5e7eb;border-radius:6px;"></svg>
  <div id="ncv-results-note" class="ncv-note"></div>
</div>

<script>
(function(){
  const datasets = {
    'CLEVR-Hans3': [
      {model:'ResNet-18', feature:'pixel', tag:'black box', comp:97.87, cs:0.24, sound:null, ss:null, opaque:true},
      {model:'CBM (nonlin.)', feature:'NCB', tag:'opaque head', comp:98.13, cs:0.37, sound:null, ss:null, opaque:true},
      {model:'Pixel-MAC', feature:'pixel', tag:'PVG', comp:96.59, cs:0.72, sound:99.99, ss:0.01, opaque:false},
      {model:'CBM (linear)', feature:'NCB', tag:'linear head', comp:95.44, cs:0.08, sound:null, ss:null, opaque:false},
      {model:'NCV', feature:'NCB', tag:'concept PVG', comp:98.92, cs:0.32, sound:100.00, ss:0.00, opaque:false}
    ],
    'CLEVR-Hans7': [
      {model:'ResNet-18', feature:'pixel', tag:'black box', comp:98.71, cs:0.24, sound:null, ss:null, opaque:true},
      {model:'CBM (nonlin.)', feature:'NCB', tag:'opaque head', comp:97.83, cs:0.25, sound:null, ss:null, opaque:true},
      {model:'Pixel-MAC', feature:'pixel', tag:'PVG', comp:97.61, cs:0.38, sound:99.88, ss:0.28, opaque:false},
      {model:'CBM (linear)', feature:'NCB', tag:'linear head', comp:89.12, cs:0.12, sound:null, ss:null, opaque:false},
      {model:'NCV', feature:'NCB', tag:'concept PVG', comp:97.89, cs:0.31, sound:100.00, ss:0.00, opaque:false}
    ],
    'CIFAR-100': [
      {model:'ResNet-50', feature:'pixel', tag:'black box', comp:81.45, cs:0.60, sound:null, ss:null, opaque:true},
      {model:'CBM (nonlin.)', feature:'SpLiCE', tag:'opaque head', comp:79.29, cs:0.42, sound:null, ss:null, opaque:true},
      {model:'Pixel-MAC', feature:'pixel', tag:'PVG', comp:15.27, cs:4.78, sound:96.31, ss:4.12, opaque:false},
      {model:'CBM (linear)', feature:'SpLiCE', tag:'linear head', comp:75.42, cs:0.04, sound:null, ss:null, opaque:false},
      {model:'NCV', feature:'CLIP-Sim', tag:'concept PVG', comp:83.32, cs:0.28, sound:99.99, ss:0.01, opaque:false}
    ],
    'ImageNet-1k': [
      {model:'ResNet-50', feature:'pixel', tag:'black box', comp:76.01, cs:0.02, sound:null, ss:null, opaque:true},
      {model:'CBM (nonlin.)', feature:'SpLiCE', tag:'opaque head', comp:69.02, cs:0.38, sound:null, ss:null, opaque:true},
      {model:'Pixel-MAC', feature:'pixel', tag:'PVG', comp:35.06, cs:3.20, sound:99.65, ss:0.26, opaque:false},
      {model:'CBM (linear)', feature:'SpLiCE', tag:'linear head', comp:68.59, cs:0.01, sound:null, ss:null, opaque:false},
      {model:'NCV', feature:'CLIP-Sim', tag:'concept PVG', comp:67.04, cs:0.16, sound:99.94, ss:0.02, opaque:false}
    ],
    'COCOLogic': [
      {model:'ResNet-50', feature:'pixel', tag:'black box', comp:65.80, cs:3.41, sound:null, ss:null, opaque:true},
      {model:'CBM (nonlin.)', feature:'SpLiCE', tag:'opaque head', comp:70.09, cs:0.56, sound:null, ss:null, opaque:true},
      {model:'Pixel-MAC', feature:'pixel', tag:'PVG', comp:42.57, cs:3.13, sound:97.70, ss:0.61, opaque:false},
      {model:'CBM (linear)', feature:'SpLiCE', tag:'linear head', comp:58.84, cs:0.09, sound:null, ss:null, opaque:false},
      {model:'NCV', feature:'CLIP-Sim', tag:'concept PVG', comp:75.42, cs:3.21, sound:97.87, ss:0.47, opaque:false}
    ]
  };
  const notes = {
    'CLEVR-Hans3':'NCV reaches the strongest completeness of all models, including the black-box ResNet-18, with perfect soundness.',
    'CLEVR-Hans7':'The linear CBM loses almost 10 points here; NCV recovers the level of the opaque nonlinear head (97.89 vs. 97.83) and keeps soundness at 100%.',
    'CIFAR-100':'Pixel-level PVGs collapse in completeness. NCV beats the ResNet-50 and both CBM variants while retaining near-perfect soundness.',
    'ImageNet-1k':'The conservative case: both CBM variants are slightly ahead of NCV in completeness; NCV adds the adversarial soundness measurement.',
    'COCOLogic':'Compositional class rules. NCV outperforms ResNet-50 by ~10 points, the linear CBM by ~17, and even the opaque nonlinear head by ~5.'
  };
  const sel = document.getElementById('ncv-data');
  const svg = document.getElementById('ncv-results-svg');
  const note = document.getElementById('ncv-results-note');
  Object.keys(datasets).forEach(k => {
    const opt = document.createElement('option');
    opt.value = k;
    opt.textContent = k;
    sel.appendChild(opt);
  });
  sel.value = 'COCOLogic';

  function draw(name) {
    const rows = datasets[name];
    const W = 760, H = 408;
    const left = 150, right = 78, top = 70, rowH = 60;
    const plotW = W - left - right;
    const x = v => left + (v / 100) * plotW;
    let html = '';
    html += `<text x="18" y="28" font-size="14" font-weight="700" fill="#111">${name}</text>`;
    html += '<text x="18" y="47" font-size="11" fill="#555">solid: completeness (accuracy) &#183; striped: soundness &#183; gray names: non-interpretable baselines</text>';
    for (let t = 0; t <= 100; t += 25) {
      const xx = x(t);
      html += `<line x1="${xx}" y1="${top-12}" x2="${xx}" y2="${top + rows.length * rowH - 8}" stroke="#e5e7eb" stroke-width="1"/>`;
      html += `<text x="${xx}" y="${top + rows.length * rowH + 8}" text-anchor="middle" font-size="10" fill="#555">${t}</text>`;
    }
    html += '<defs><pattern id="ncvdiag" width="6" height="6" patternUnits="userSpaceOnUse" patternTransform="rotate(45)"><rect width="3" height="6" fill="#38bdf8"/></pattern></defs>';
    rows.forEach((r, i) => {
      const y = top + i * rowH;
      const isNcv = r.model === 'NCV';
      if (isNcv) html += `<rect x="6" y="${y - 4}" width="${W - 12}" height="${rowH - 6}" fill="#f0fdfa" rx="5"/>`;
      html += `<text x="${left - 12}" y="${y + 16}" text-anchor="end" font-size="12" font-weight="${isNcv ? 700 : 500}" fill="${r.opaque ? '#9ca3af' : '#111'}">${r.model}</text>`;
      html += `<text x="${left - 12}" y="${y + 31}" text-anchor="end" font-size="9.5" fill="#9ca3af">${r.feature} &#183; ${r.tag}</text>`;
      const barColor = isNcv ? '#0f766e' : (r.opaque ? '#a8b3c2' : '#64748b');
      html += `<rect x="${left}" y="${y + 2}" width="${plotW}" height="16" fill="#f3f4f6"/>`;
      html += `<rect x="${left}" y="${y + 2}" width="${Math.max(x(r.comp) - left, 1.5)}" height="16" fill="${barColor}" opacity="0.9"/>`;
      html += `<text x="${W - 6}" y="${y + 15}" text-anchor="end" font-size="10.5" fill="#111">${r.comp.toFixed(2)}&#177;${r.cs.toFixed(2)}</text>`;
      if (r.sound !== null) {
        html += `<rect x="${left}" y="${y + 23}" width="${plotW}" height="13" fill="#f3f4f6"/>`;
        html += `<rect x="${left}" y="${y + 23}" width="${Math.max(x(r.sound) - left, 1.5)}" height="13" fill="url(#ncvdiag)" opacity="0.95"/>`;
        html += `<text x="${W - 6}" y="${y + 34}" text-anchor="end" font-size="10.5" fill="#111">${r.sound.toFixed(2)}&#177;${r.ss.toFixed(2)}</text>`;
      } else {
        html += `<text x="${left}" y="${y + 34}" font-size="9.5" fill="#9ca3af">soundness n/a (no prover-verifier game)</text>`;
      }
    });
    html += `<text x="${left + plotW/2}" y="${H - 10}" text-anchor="middle" font-size="11" fill="#555">score in percent</text>`;
    svg.innerHTML = html;
    note.textContent = notes[name];
  }
  sel.addEventListener('change', () => draw(sel.value));
  draw(sel.value);
})();
</script>

<p>There are three observations that are worth keeping separate.</p>

<p>First, the pixel-level PVG baseline works on the synthetic CLEVR-Hans setting, but it does not scale gracefully to natural images. On CIFAR-100, for example, Pixel-MAC has high soundness but very poor completeness, which means that it is hard to recover the correct class from the selected pixel evidence. This is precisely the failure mode one expects when the game is played on the wrong representation.</p>

<p>Second, NCV narrows the interpretability-accuracy gap of concept bottleneck models. On CLEVR-Hans3 it reaches about 99% completeness, compared with about 95% for the linear CBM. On COCOLogic, where the target rules require more compositional reasoning, NCV reaches about 75% completeness versus about 59% for the linear CBM and about 66% for ResNet-50. The paper’s table also contains a nonlinear (but opaque) classifier head on the same concepts as a control; on COCOLogic, NCV beats even that baseline by about five points, so the gain is not merely about adding nonlinearity. Note that ImageNet is more nuanced: the linear CBM is slightly better in raw completeness there, while NCV still provides the adversarial soundness side of the game.</p>

<p>Third, NCV appears to help with shortcut learning. On the confounded CLEVR-Hans versions, adding even a small amount of clean data reduces the validation-test gap more sharply for NCV than for the CBM baselines. This is not because NCV was designed as a shortcut-mitigation method; rather, Morgana makes shortcuts visible to Arthur during training by trying to exploit misleading concept subsets.</p>

<h2 id="what-the-game-actually-guarantees">What the game actually guarantees</h2>

<p>Completeness and soundness are not only performance numbers. In the Merlin-Arthur framework they carry an information-theoretic reading, and NCV inherits it. The original guarantee <a href="https://proceedings.mlr.press/v238/waldchen24a.html">[WSTZP24]</a> was formulated for binary classification tasks; we extend it to the multi-class setting by reading it one class at a time, one-vs-rest, so that high completeness and soundness for a class become a lower bound on the mutual information between that class and Merlin’s selected concepts. The bound is conditional and cleanest for discrete, moderate-size concept vocabularies, so we treat the bound as the justification for our faithfulness criterion rather than a quantity we compute directly. But it is what makes the evidence provably informative rather than merely suggestive, and it is why the verification step is more than a metric.</p>

<h2 id="why-this-fits-the-broader-story">Why this fits the broader story</h2>

<p>There is a simple rule-of-thumb behind the paper: if the proof object is meant to be inspected by humans, then it should live in a representation that humans can understand. Pixels are not that representation. Concepts are not perfect either, and we are very explicit about this limitation, but they are a much better interface for classification evidence.</p>

<p>This also illustrates a broader Math-to-AI pattern that we keep returning to in our group. The underlying prover-verifier structure is mathematical and game-theoretic; it gives us language for completeness, soundness, rejection, sparse evidence, and adversarial testing. The concept extractor is modern AI infrastructure; it gives us a compressed and semantically meaningful representation of high-dimensional data. NCV is the hybrid: use the representation power of learned systems, but wrap the decision in a structured verification game.</p>

<p>For me this also closes a personal loop. Back in 2011, together with <a href="https://sites.gatech.edu/santanu-dey/">Santanu Dey</a>, I proposed a scheme for generating cutting planes in integer programming by means of verification, called <em>design and verify</em> <a href="https://doi.org/10.1007/s10107-013-0645-0">[DP14]</a>: instead of restricting cut generation to procedures that are simple enough to be analyzed in closed form, one allows an essentially arbitrary generation process and pairs it with a separate, efficient verification step that certifies validity of whatever is produced. NCV follows the same division of labor, one abstraction level up: the prover may be an arbitrary learned system, as long as the verifier can check its output. Good proof systems decouple the cost of finding a proof from the cost of checking it; that asymmetry is what makes verification practical.</p>

<p><strong>NB.</strong> Concept quality remains the bottleneck. If the concept extractor produces noisy, entangled, or culturally biased concepts, NCV inherits this. The framework improves where the concept space is good enough to support classification and inspection. It does not magically turn bad concepts into good ones.</p>

<h2 id="closing">Closing</h2>

<p>The main point is not that NCV solves interpretability. It does something more modest and, in my view, more useful: it moves verifiable classification from pixel masks, which only hold up on small synthetic images, to concepts, which scale to real-world vision tasks. This makes the proof object smaller, more semantic, and easier to test adversarially.</p>

<p>Put differently, NCV asks the classifier to show its work, but in concepts rather than pixels. For interpretable AI, that is a much better place to start.</p>

<h2 id="references">References</h2>

<p>[TASKSP26] Turan, B., Asadulla, S., Steinmann, D., Kersting, K., Stammer, W., &amp; Pokutta, S. (2026). Neural Concept Verifier: Scaling Prover-Verifier Games via Concept Encodings. <em>ICML 2026 (spotlight)</em>. <a href="https://arxiv.org/abs/2507.07532">arxiv</a></p>

<p>[AZWG21] Anil, C., Zhang, G., Wu, Y., &amp; Grosse, R. (2021). Learning to Give Checkable Answers with Prover-Verifier Games. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/2108.12099">arxiv</a></p>

<p>[BOSCL24] Bhalla, U., Oesterling, A., Srinivas, S., Calmon, F., &amp; Lakkaraju, H. (2024). Interpreting CLIP with Sparse Linear Concept Embeddings (SpLiCE). <em>NeurIPS 2024</em>. <a href="https://proceedings.neurips.cc/paper_files/paper/2024/hash/996bef37d8a638f37bdfcac2789e835d-Abstract-Conference.html">paper</a></p>

<p>[DP14] Dey, S.S. &amp; Pokutta, S. (2014). Design and Verify: A New Scheme for Generating Cutting-Planes. <em>Mathematical Programming</em>, 145, 199–222 (conference version in IPCO 2011). <a href="https://doi.org/10.1007/s10107-013-0645-0">paper</a></p>

<p>[GMR85] Goldwasser, S., Micali, S., &amp; Rackoff, C. (1985). The Knowledge Complexity of Interactive Proof-Systems. <em>STOC 1985</em>. <a href="https://doi.org/10.1145/22145.22178">paper</a></p>

<p>[ICA18] Irving, G., Christiano, P., &amp; Amodei, D. (2018). AI Safety via Debate. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/1805.00899">arxiv</a></p>

<p>[KCELMB24] Kirchner, J.H., Chen, Y., Edwards, H., Leike, J., McAleese, N., &amp; Burda, Y. (2024). Prover-Verifier Games Improve Legibility of LLM Outputs. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/2407.13692">arxiv</a></p>

<p>[KNTMPKL20] Koh, P.W., Nguyen, T., Tang, Y.S., Mussmann, S., Pierson, E., Kim, B., &amp; Liang, P. (2020). Concept Bottleneck Models. <em>ICML 2020</em>. <a href="https://proceedings.mlr.press/v119/koh20a.html">paper</a></p>

<p>[SWSK24] Stammer, W., Wuest, A., Steinmann, D., &amp; Kersting, K. (2024). Neural Concept Binder. <em>NeurIPS 2024</em>. <a href="https://proceedings.neurips.cc/paper_files/paper/2024/hash/8402cf3031d649066ada24514739f0dd-Abstract-Conference.html">paper</a></p>

<p>[WSTZP24] Waeldchen, S., Sharma, K., Turan, B., Zimmer, M., &amp; Pokutta, S. (2024). Interpretability Guarantees with Merlin-Arthur Classifiers. <em>AISTATS 2024</em>. <a href="https://proceedings.mlr.press/v238/waldchen24a.html">paper</a></p>]]></content><author><name>Sebastian Pokutta</name></author><category term="research" /><category term="ai" /><category term="interpretability" /><summary type="html"><![CDATA[TL;DR: This is a short summary of our paper Neural Concept Verifier: Scaling Prover-Verifier Games via Concept Encodings by Berkant Turan, Suhrab Asadulla, David Steinmann, Kristian Kersting, Wolfgang Stammer, and Sebastian Pokutta. The paper was accepted as a spotlight at ICML 2026 (top ~2.2% of submissions). In a nutshell, we move Prover-Verifier Games from pixel space to concept space: a prover selects a sparse set of human-readable concepts, a verifier must classify using only those concepts, and an adversarial prover tests whether the verifier can be fooled. The result is a scalable route to verifiable, nonlinear concept-based classification on datasets such as CLEVR-Hans, CIFAR-100, ImageNet-1k, and COCOLogic.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" /><media:content medium="image" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">The Zeroth World: A Seven-Year Update</title><link href="http://www.pokutta.com/blog/zeroth-world-update/" rel="alternate" type="text/html" title="The Zeroth World: A Seven-Year Update" /><published>2026-06-12T00:00:00+02:00</published><updated>2026-06-12T00:00:00+02:00</updated><id>http://www.pokutta.com/blog/zeroth-world-update</id><content type="html" xml:base="http://www.pokutta.com/blog/zeroth-world-update/"><![CDATA[<p><em>TL;DR: Seven years ago I argued that AI could enable a zeroth world: economies operating at a multiple of first-world productivity, the way the first world operates at a multiple of the third. The update: the technology arrived faster than I expected, the productivity gains are real but unevenly distributed, and the zeroth world is being built right now, in the US and in China. Europe is perfectly on track to watch from the sidelines, which is particularly bitter because, demographically, Europe needs it more than anyone else. The newest twist: frontier cyber-defense capability is now allocated by invitation and Europe is mostly not on the list.</em>
<!--more--></p>

<div style="text-align:center; font-size:20px; color:#9ca3af; margin:12px 0;">∗ ∗ ∗</div>

<p><strong>Note for German readers:</strong> <em>there is a full <a href="#german-version">German version of this post</a> at the bottom, AI-generated with zero touch-ups; take it or leave it.</em></p>

<p><strong>Hinweis für deutsche Leser:</strong> <em>Ganz unten gibt es eine vollständige <a href="#german-version">deutsche Version dieses Beitrags</a>, KI-generiert und ohne jede Nachbearbeitung; take it or leave it.</em></p>

<div style="text-align:center; font-size:20px; color:#9ca3af; margin:12px 0;">∗ ∗ ∗</div>

<p>In my <a href="/blog/random/2019/02/06/zeroth-world.html">previous post</a> on the zeroth world, I discussed the impact of artificial intelligence on society and the economy, emphasizing its current and latent capabilities rather than speculative future scenarios. I defined AI as systems that gather information, learn, decide, and act autonomously, similar to the OODA loop. I highlighted the need for hybridization, where AI systems teamed up with humans to enhance productivity and scale operations. Examples included autonomous driving, call center operations, and investment portfolio management. I also explored the potential for AI to create a “Zeroth World” with unprecedented economic output and productivity levels; basically, the zeroth world is to the first world what the first world is to the third world in terms of economic output. I also discussed to some extent the risks of job displacement and the concentration of power.</p>

<p>That was <em>seven</em> years ago, written while I was still living in the US, before relocating to Europe (Germany to be more precise). A lot has happened since then and this is the update. Full disclosure: I started writing the update on January 28, 2025 (it was meant to be a six-year update), the week DeepSeek R1 dropped. It then sat in my drafts folder for almost a year and a half, during which everything in it became <em>more</em> true.</p>

<p>The backdrop to finally shipping the post is too obvious to ignore: Today, 12th of June 2026, SpaceX is going public after <a href="https://www.cnbc.com/2026/06/11/spacex-raises-75-billion-in-record-setting-ipo-ahead-of-nasdaq-debut.html">raising $75 billion</a> at a roughly $1.8 trillion valuation, the largest IPO in history and about two and a half times Saudi Aramco’s old record; Anthropic and OpenAI <a href="https://techcrunch.com/2026/06/08/following-anthropic-openai-files-confidentially-for-ipo/">filed to follow</a> within the same two weeks. With this the <em>zeroth world</em> is now a tradeable asset class.</p>

<p><strong>NOTE.</strong> Stating the obvious or the most likely outcome is <em>not</em> an endorsement.</p>

<h2 id="what-the-2019-post-got-right-and-wrong">What the 2019 post got right (and wrong)</h2>

<p>Before making a new set of predictions for the future, let us settle my old ones from 2019 first.</p>

<p><strong>What hit:</strong></p>

<ul>
  <li><strong>Hybridization was the right call.</strong> The 2019 thesis was that we do not need full autonomy, we need a human paired with an AI handling “90% of the basics with human override”. That is, almost verbatim, the deployment pattern of 2023-2026: copilots, assistants, agents with escalation. <a href="https://www.klarna.com/international/press/klarna-ai-assistant-handles-two-thirds-of-customer-service-chats-in-its-first-month/">Klarna’s assistant</a> took over two-thirds of customer-service chats in its first month, the workload of several hundred agents. The best-studied call-center deployment showed <a href="https://www.nber.org/papers/w31161">~14% average productivity gains, ~34% for novices</a>. Call centers were literally the first example on my 2019 list.</li>
  <li><strong>The control-center driving model.</strong> In 2019 I sketched two use cases: remote operators supervising multiple vehicles, and hub-to-hub highway autonomy for trucking. Waymo now does <a href="https://techcrunch.com/2026/03/27/waymo-skyrocketing-ridership-in-one-chart/">500,000 paid robotaxi rides per week</a> across ten US cities (with a stated target of a million per week by end of 2026), supported by exactly the kind of remote fleet-assistance layer described back then. Aurora started driverless freight runs between Dallas and Houston in 2025, hub-to-hub, exactly as sketched. And my favorite footnote: teledriving, the purest form of the control-center idea, is offered commercially by <a href="https://vay.io/">Vay</a>… a company founded in Berlin, operating in Las Vegas. Remember that one for later.</li>
  <li><strong>“In a few years you will download such a bot in the App Store.”</strong> ChatGPT launched in November 2022, three and a half years after that sentence, and became the fastest-adopted consumer application in history. The companion prediction, that we would soon teach building such systems end-to-end at universities as senior-design projects, is now just called the curriculum.</li>
  <li><strong>Concentration of power.</strong> The 2019 post speculated that “the next category of scale will be defined by AI companies, with an insane concentration of resources, wealth, and power that pales current concentration levels in the valley.” NVIDIA became the first $4 trillion company; a handful of US firms now spend on the order of half a trillion dollars <em>per year</em> on AI infrastructure; the top of the S&amp;P 500 is, functionally, an AI index. And as of this week, the “next category of scale” has tickers: SpaceX’s record listing makes it one of the largest companies in America on day one, with OpenAI and Anthropic filed right behind it, roughly four trillion dollars of zeroth-world equity heading for the public markets at once. I will take that one.</li>
  <li><strong>The compute trend.</strong> The “3.5-month doubling” of training compute obviously could not continue at that exact rate (every exponential is a sigmoid), but the underlying point, that we were moving faster than any prior technology cycle, held. Training compute for frontier models kept growing at multiples per year, financed by the capex numbers above.</li>
</ul>

<p><strong>What missed:</strong></p>

<ul>
  <li><strong>The mechanism.</strong> I was watching reinforcement learning and self-play (AlphaStar et al.). The actual breakthrough came from self-supervised learning on text at scale. The <em>shape</em> of the prediction (capability via compute scaling, no fundamental roadblock) was right; the mechanism was not. I count that as lucky in the way that matters and wrong in the way that doesn’t.</li>
  <li><strong>Timelines for the physical world.</strong> Driving took longer than the disengagement-rate extrapolation suggested (though it did arrive). Robo-advisors stayed mediocre. Atoms remain harder than bits.</li>
  <li><strong>The aggregate numbers (so far).</strong> You still cannot see the zeroth world in GDP statistics. Productivity statistics move slowly, diffusion is lumpy, and we are early. This is the classic Solow problem “computers everywhere except in the productivity statistics”. What you <em>can</em> already see is divergence between blocs, and that is the actual subject of this update.</li>
</ul>

<h2 id="agents-the-ooda-loop-par-excellence">Agents: the OODA loop par excellence</h2>

<p>Re-reading the 2019 definition of an AI system, (1) senses, (2) learns, (3) decides, (4) acts, with some autonomy, it is hard not to smile: that is simply a description of a 2026 agent. Tool use, computer use, coding agents, deep-research agents: the OODA loop commercially at scale. What was an abstraction borrowed from military doctrine is now a product category.</p>

<p>And the productivity gains are real, if uneven. I will not review the vast amount of studies here beyond two calibration points: novice-heavy, well-scoped work shows large gains (the call-center numbers above), while <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/">METR’s 2025 study</a> found experienced open-source developers were actually <em>slower</em> with AI tools on their own familiar codebases, while believing they were faster. Both results are true; the distribution of gains is the key point. My own experience, see the <a href="/blog/agentic-researcher/">The Agentic Researcher</a> post, is that with verification-first workflows the gains in research work are very substantial; and for good measure to balance perspectives, <a href="/blog/not-every-discovery-needs-an-llm/">not every discovery needs an LLM</a>.</p>

<p>One of the main hypotheses from 2019 was the <em>automate-and-elevate</em> cycle: automate the basics, operate one level higher, repeat. This is real now, with appropriately scoped and tooled agents. The individual contributor of 2026 increasingly behaves like a manager of processes that happen to <em>in silico</em>; being basically a solo-entrepreneur. That was the mechanism by which I argued a 10x in output per person becomes plausible. I see no reason to retract that claim, rather to ask <em>where</em> it will happen and whether it will compound. Which brings us to the actual update.</p>

<h2 id="the-race-is-between-blocs-now-us-china-europe">The race is between blocs now: US, China, Europe</h2>

<p>In 2019 I framed the zeroth world in terms of countries pulling away on GDP per person employed. In 2026, the better way to resolve things is in blocs, because the inputs that matter are bloc-level: compute, energy, data, regulation, capital, talent.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Factor</th>
      <th style="text-align: center">US</th>
      <th style="text-align: center">China</th>
      <th style="text-align: center">Europe</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">Frontier compute</td>
      <td style="text-align: center">✓✓</td>
      <td style="text-align: center">~ (constrained, compensating, changing fast though)</td>
      <td style="text-align: center">✗</td>
    </tr>
    <tr>
      <td style="text-align: left">Energy (price &amp; buildout)</td>
      <td style="text-align: center">~ (cheap, grid-limited)</td>
      <td style="text-align: center">✓✓</td>
      <td style="text-align: center">✗</td>
    </tr>
    <tr>
      <td style="text-align: left">Data</td>
      <td style="text-align: center">✓</td>
      <td style="text-align: center">✓✓</td>
      <td style="text-align: center">✗ (by design)</td>
    </tr>
    <tr>
      <td style="text-align: left">Regulation (for builders)</td>
      <td style="text-align: center">✓</td>
      <td style="text-align: center">✓ (pragmatic)</td>
      <td style="text-align: center">✗</td>
    </tr>
    <tr>
      <td style="text-align: left">Capital</td>
      <td style="text-align: center">✓✓</td>
      <td style="text-align: center">✓</td>
      <td style="text-align: center">✗ (exists, risk-averse)</td>
    </tr>
    <tr>
      <td style="text-align: left">Talent</td>
      <td style="text-align: center">✓✓ (imports)</td>
      <td style="text-align: center">✓✓ (volume)</td>
      <td style="text-align: center">✓ (exports)</td>
    </tr>
  </tbody>
</table>

<p><strong>The US</strong> is playing the closed frontier game: a handful of labs, essentially unlimited capital, and compute buildouts that have crossed from “data center” into “industrial program”. <a href="https://openai.com/index/announcing-the-stargate-project/">Stargate</a> was announced at $500 billion the very week I started this draft; xAI’s first Memphis cluster, which I originally cited at 100k GPUs as an outrageous number, passed 200k and the successor site is marketed in gigawatts rather than chip counts. The binding constraint in the US is no longer money or chips; it is electricity and interconnects.</p>

<p><strong>China</strong> is playing the open and deployed game, and the DeepSeek moment was not a one-off. Qwen, Kimi, GLM, MiniMax: the most-used open-weight models in the world are now, by a comfortable margin, Chinese, which means the <em>default substrate</em> for everyone outside the frontier labs is increasingly Chinese. Compute is the constraining input (export controls work, partially), but the response has been efficiency engineering plus a domestic accelerator stack maturing fast. And the effort goes all the way down the stack: Reuters has documented a state-orchestrated <a href="https://www.reuters.com/world/china/how-china-built-its-manhattan-project-rival-west-ai-chips-2025-12-17/">“Manhattan Project”</a> centered on Huawei to replicate the chip-making toolchain itself, up to and including the one machine everyone agreed was un-replicable, ASML’s EUV lithography. Domestic EUV prototypes are reportedly under testing, with AI-chip output targeted for 2028 (insiders say 2030; analysts used to say a decade). Discount the boasts as you like, serious assessments do, but the direction is unambiguous: the chokepoint is being engineered around. Europe should sit with that for a moment, because ASML in Veldhoven is the continent’s single genuine piece of AI-relevant leverage, and the countdown to end this leverage has started. On energy, there is no contest: China added more generating capacity last year than Germany operates in total, it <a href="https://electrek.co/2025/09/02/h1-2025-china-installs-more-solar-than-rest-of-the-world-combined/">installed more than twice as much solar in the first half of 2025 as the rest of the world combined</a>, and its cumulative solar fleet crossed the terawatt mark in 2025, much of it in desert megabases like the Kubuqi “Solar Great Wall”, the kind of infrastructure you can watch grow from space. And crucially, China dominates the layer where zeroth-world productivity touches the physical economy: industrial robots (roughly half of global installations), EVs, batteries, electrified manufacturing. If the US owns the brains, China owns the metabolism.</p>

<p><strong>Europe</strong> is playing the customer game while describing it as the values game. The EU AI Act entered into force in 2024; by November 2025 the Commission was already proposing, via the <a href="https://digital-strategy.ec.europa.eu/en/policies/digital-omnibus">digital omnibus</a>, to delay and soften the very rules it had just finished celebrating, after the predictable realization that they were unimplementable. Regulate first, retreat later, build never. On compute, Europe’s proudest machine, JUPITER in Jülich (Europe’s first exascale system, roughly 24k superchips), is a fine scientific instrument and a rounding error against a single US site. The headline response, <a href="https://digital-strategy.ec.europa.eu/en/news/eu-launches-investai-initiative-mobilise-eu200-billion-investment-artificial-intelligence">InvestAI</a> with €200 billion and “AI gigafactories”, remains, as of this writing, largely a press-release asset class. The <a href="https://commission.europa.eu/topics/eu-competitiveness/draghi-report_en">Draghi report</a> said everything that needed saying in September 2024, in officialese, with numbers; remarkably little has happened since. Mistral exists and is genuinely good, which makes it the exception that proves the rule; Aleph Alpha, the German frontier hope, pivoted out of the frontier race in 2024.</p>

<p>The absorbing state seems obvious: the zeroth world will not be a country club you can apply to join. It is shaping up as two ecosystems, a US-led closed frontier and a China-led open/deployment stack, plus customers. Europe is currently choosing, with great procedural diligence and the unwavering exactness of bureaucracy, to be a customer.</p>

<p>And being a customer, it turns out, now comes in tiers as well.</p>

<h2 id="the-glasswing-asymmetry-security-by-invitation">The Glasswing asymmetry: security by invitation</h2>

<p>In April 2026, Anthropic announced <a href="https://www.anthropic.com/project/glasswing">Project Glasswing</a>, an initiative to “secure the world’s most critical software”, built around early access to its newest frontier model, Claude Mythos Preview. The model’s defining capability is finding and fixing software vulnerabilities at machine speed; it had “already identified thousands of zero-day vulnerabilities across critical infrastructure” at announcement, and within weeks the launch partners reported <a href="https://www.anthropic.com/news/expanding-project-glasswing">more than 10,000 high- or critical-severity flaws</a> found in their codebases. Now think about this for a second: the find-and-fix loop of cybersecurity now runs at AI speed, the window from vulnerability to exploit shrinks from months to minutes, and the same class of capability will be in attackers’ hands roughly one open-weight release cycle later. Everyone’s exposure clock started ticking at once: but who gets hardened first?</p>

<p>The eleven named launch partners: Amazon Web Services, Apple, Broadcom, Cisco, CrowdStrike, Google, JPMorganChase, the Linux Foundation, Microsoft, NVIDIA, Palo Alto Networks; not just America first but exclusive. The expansion to roughly 150 further organizations in fifteen-plus countries was decided, in Anthropic’s own words, “following several weeks of close collaboration” with partners, the security industry, open-source maintainers, <em>and the US government</em>. Individual European organizations do get in (BT joined in June, in an expansion round, after meeting Anthropic’s security requirements), but invitation-by-exception is the point here: access to the defensive frontier is discretionary, revocable, and runs through San Francisco and Washington. Privileged access has become industrial policy and hardening is (a new layer of) export control. Nobody banned Europe from anything, they just ended up last in line.</p>

<p>For the zeroth-world narrative this adds a second dimension. The first dimension was productivity; this one is <em>exposure</em>. The US is using frontier AI to systematically harden its own stack first: its clouds, its chips, its banks, its open-source substrate. Europe runs on much of that same software, so it inherits patches downstream, on the vendors’ schedule and according to the vendors’ priorities. But Europe’s <em>own</em> stack, the SAPs and the Siemens control systems, the utilities, the hospital IT, the government systems, the long tail of European code produced in fragmented sovereignty-knee-jerk-reactions, that nobody in Memphis cares about, has no seat at that table and no access to frontier hardening capabilities. No problem, just do your own Project Glasswing in Europe? Europe cannot simply run its own Glasswing, because a Glasswing requires a Mythos, and Europe has no frontier model to gate in order to create such a hardening advantage. Put differently, the capability gap turned into a security gap and there is basically no fix to this.</p>

<p>What is also worth noting is that this episode is more illuminating than a decade of sovereignty white papers outlining hypotheticals; comically, so much has been written and yet no one saw this one coming. While Europe spent years drafting horizontal AI regulation, the actual allocation of AI-era security, arguably the most sovereignty-relevant resource there is, happened via a partner list assembled by a private American company in consultation with its home government, in a matter of weeks. That is what shaping the technology looks like when you are at the table. And this is the definition of being an NPC (not even occuring as an afterthought) if you are not.</p>

<h2 id="why-europe-is-never-going-to-catch-up-in-the-ai-race">Why Europe is never going to catch up in the AI race</h2>

<p>I will use Germany as my running example here, partly because I know the system (and live here) and partly because Germany is the largest economy of the bloc and directionally representative; the argument transfers to most others the continent with minor touch-ups.</p>

<p>Let’s start with a quick time capsule moment: On January 28, 2025, when I started this draft, DeepSeek had just released its open models (V3, R1, Janus-Pro), bringing Chinese models up to par with the best in the West, trained on export-controlled, dumbed-down GPUs at a fraction of the usual price point. It sent the stock market spiraling down (“AI in the US is doomed”) just to recover most of it the next day (“wait a sec, cheaper AI means more users and more users means more money”); same story as with the steam engines. Someone sent me a meme that week that still summarizes the situation:</p>

<div class="center">
  <img src="http://www.pokutta.com/blog/assets/zeroth-world-update/what-did-you-do-recently.png" alt="what-did-you-do-recently" style="width:80%" />
  <p style="clear: both;"></p>
</div>
<p class="figcap"><strong>Figure 1:</strong> A summary of the state of AI in Germany, and more broadly in Europe. Unchanged since January 2025, which is the problem.</p>

<p>There are five critical factors you need in order to get an invitation to the AI game:</p>
<ol>
  <li>High-end GPUs, and lots of them</li>
  <li>Cheap energy</li>
  <li>High-quality data</li>
  <li>A favorable regulatory environment</li>
  <li>Talent</li>
</ol>

<p>You can probably get away with 4 out of 5, or even 3 out of 5 if they are the right ones, but Germany would need 5 miracles; the same holds for most of Europe.</p>

<p><strong>High-end GPUs.</strong> Germany’s position in the GPU arms race is behind by at least one order of magnitude, more realistically two to three, and the gap is <em>widening</em>. The current flagship, JUPITER at Jülich with its roughly 24k superchips, is celebrated as a continental achievement, and within the scientific computing world it is one. But the unit of account at the frontier has changed: xAI’s Memphis site, which I cited at 100k GPUs when starting this draft (and which was already five times the German flagship), has since doubled and been superseded by a successor site marketed in gigawatts; Stargate is a $500B program; the US hyperscalers collectively spend on the order of half a trillion dollars per year. Against that, Europe’s gigafactory initiative earmarks ~€20B for five sites, to be energized at some future date, pending procurement. Some might argue DeepSeek proves you do not need frontier-scale GPUs. Partially true, and worth taking seriously, but note what DeepSeek actually had: exceptional engineering talent <em>and</em> still-substantial compute (their V3 training run alone consumed <a href="https://arxiv.org/pdf/2412.19437">2.788 million GPU hours</a>; and the famous “$5.6M” figure prices a single pretraining run, not the program around it). “GPU-poor” by US standards is still GPU-rich by German ones.</p>

<p>And note the access regime itself, because it is its own lesson. Outside the US, frontier GPUs come in exactly two flavors: nerfed or unavailable. China gets the nerfed flavor, deliberately degraded export models (H800s, H20s, whatever the deal of the season permits), and answered with smuggling, ruthless efficiency engineering, and a domestic accelerator stack (Huawei’s Ascend line and friends) that improves every quarter. China has a solution. Europe gets the other flavor: nothing is formally banned, you are simply not getting allocation. NVIDIA’s production is pre-sold years ahead to US hyperscalers, whatever reaches the market is rationed, and when Washington briefly formalized the hierarchy in the January 2025 “AI diffusion framework”, several EU member states (Poland and Portugal among them) woke up in Tier 2 with hard GPU quotas, to Brussels’ considerable fury, before the rule was rescinded in favor of deal-by-deal diplomacy. The reality remained the same though: GPU access is a privilege administered elsewhere. China’s answer is to build its own. Europe’s answer is a working group.</p>

<p><strong>Cheap energy.</strong> Germany’s industrial electricity prices are among the highest of any major economy; for data centers the comparison is brutal (approximate, large industrial users, 2024/25; cf. <a href="https://www.iea.org/data-and-statistics/charts/estimated-final-electricity-price-for-large-industrial-customers-in-energy-intensive-industries-2019-2024">IEA data</a>):</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Country</th>
      <th style="text-align: right">~USD/kWh (industrial)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">Germany</td>
      <td style="text-align: right">0.19</td>
    </tr>
    <tr>
      <td style="text-align: left">France</td>
      <td style="text-align: right">0.13</td>
    </tr>
    <tr>
      <td style="text-align: left">United States</td>
      <td style="text-align: right">0.08</td>
    </tr>
    <tr>
      <td style="text-align: left">China</td>
      <td style="text-align: right">0.08</td>
    </tr>
    <tr>
      <td style="text-align: left">Norway</td>
      <td style="text-align: right">0.06</td>
    </tr>
  </tbody>
</table>

<p>And price is only half of it; the other half is buildout velocity. AI compute is, physically, an energy-conversion industry: whoever can connect gigawatts fastest wins. China connects a Germany’s worth of capacity per year; the US fast-tracks gas turbines and restarts nuclear plants next to data centers; Germany debates. So that’s a no, twice.</p>

<p><strong>High-quality data.</strong> Germany faces structural barriers to accessing and using data at AI scale. GDPR, whatever its merits for individual privacy, created a data-scarce environment: explicit-consent regimes, retention and transfer restrictions, and compliance overhead that discourages exactly the kind of large-scale data aggregation that modern AI training requires. Cultural attitudes amplify the law: the population is unusually privacy-anxious, participation in data-sharing initiatives is low, and every digitization project ships with a built-in opposition committee. The result is a data ecosystem that is limited in scope, fragmented by design, and fundamentally misaligned with how AI systems are built. Meanwhile, the clinical, industrial, and administrative data that Europe <em>does</em> uniquely have sits in silos that even European researchers cannot use.</p>

<p><strong>Favorable regulatory environment.</strong> Germany is known for a strong regulatory environment, just not the right one. The instinct is to regulate the risks of a technology before having the technology. The AI Act is the monument to this instinct: years of negotiation, a compliance industry spun up before a single European frontier model existed, and then, within fifteen months of entry into force, a Commission “omnibus” to delay and dilute it because reality refused to cooperate. The damage of such regulation is not even the direct compliance cost; it is the <em>uncertainty tax</em> and the signal. Founders price in that the rules can change twice before their Series B; many simply incorporate elsewhere. Regulation is drying out innovation, turning what could be a thriving tech ecosystem into a compliance landscape that only incumbents can afford to navigate.</p>

<p><strong>Talent.</strong> The one factor where Europe genuinely competes, which makes the outcome more damning. Germany still produces excellent researchers and engineers (the education system’s last compounding asset), but it produces them <em>for export</em>. The brightest go where the compute, capital, and ambition are: historically the US, increasingly also Chinese labs. Student numbers in STEM are declining, the demographic pipeline is shrinking (more below), immigration processes remain a bureaucratic obstacle course, and the domestic ecosystem offers no gravitational pull: no critical mass of frontier work, no scale-ups, thin early-stage funding, and exit environments that make ambitious founders leave before they start. Funding, where it exists, is administered in homeopathic doses: tens of millions, spread across dozens of recipients, announced as strategy. The canonical example: <a href="https://openeurollm.eu/launch-press-release">OpenEuroLLM</a>, Europe’s flagship answer to the DeepSeek moment, announced the very same week: €52 million, spread across a consortium of <em>twenty</em> research institutions, companies, and computing centers, complete with work packages, deliverables, and reporting obligations. That is roughly €2.6 million per partner before coordination overhead, deployed against labs whose weekly electricity bills run higher. A single US lab raises more in a week, for one idea, than such programs disburse in a year across a continent.</p>

<p>And on top of all of it sits culture. There is no nice of saying this: Germany does not currently have a culture of building. Economic growth itself has become suspect (“do we even want this?” is a serious question in serious newspapers), risk-taking is socially penalized, failure is disqualifying, and the comfortable default is to be an NPC in someone else’s game: consume the platforms, rent the models, regulate the externalities, and call the resulting role “digital sovereignty”. NGMI, as the kids say. The kids, incidentally, have mostly stopped saying it here; they said it from Palo Alto, Zurich, or Shenzhen.</p>

<h2 id="what-remains-niches-on-shrinking-product-maps">What remains: niches, on shrinking product maps</h2>

<p>So what is the realistic European AI play? Niches. And to be clear, some of them are excellent: DeepL built a world-class translation business in Cologne; Helsing became one of Europe’s most valuable startups doing defense AI; Black Forest Labs in Freiburg trains some of the best image models in the world; Mistral holds the credible-open-European-model franchise. Europe will get vertical wins in industrial AI, pharma, legal tech, defense, embedded systems. These are real companies with real revenue, and I am happy they exist.</p>

<p>But notice three things. First, niches live downstream of somebody else’s frontier. They fine-tune, distill, and deploy on chips, models, and clouds owned elsewhere; they are tenants, and tenants do not set the rent. Second, the niche outcome is the <em>good</em> scenario, and it also follows the pattern from above: great research upstream, disaster downstream. Another canonical example in plain sight. Latent diffusion, the technique underneath the entire image-generation industry, was invented in the CompVis group at Heidelberg/LMU Munich; the platform value was captured by Stability, Midjourney, and OpenAI, and only years later did some of the original authors found Black Forest Labs to claw a piece back. Same story one generation earlier: the LSTM was invented in Munich in the 1990s and powered Google’s speech and translation stack for a decade. Europe invents; others compound. The rock star plays; the audience, and the box office, are elsewhere.</p>

<p>Third, and this should worry even the comfortable: while Europe debates catching up, the products are quietly leaving. Apple is shipping its new Siri AI everywhere except the EU, with <a href="https://www.reuters.com/business/apple-failed-make-its-ai-tool-comply-eu-regulations-eu-commission-says-2026-06-09/">Cupertino and Brussels blaming each other</a> for the delay. Google launched <a href="https://9to5google.com/2026/04/06/google-ai-edge-eloquent-app/">AI Edge Eloquent</a>, a free on-device dictation app, in the US and most of the world, <a href="https://innovation-village.com/google-launches-offline-ai-dictation-app-ai-edge-eloquent/">but not in the EEA</a>; a <em>fully offline</em> app, so much for a privacy argument going berserk. Meta <a href="https://www.axios.com/2024/07/17/meta-future-multimodal-ai-models-eu">withheld its multimodal models</a> from the EU back in 2024, and that was a precedent, not an exception. The sequel made it explicit: Llama 4’s license <a href="https://www.llama.com/llama4/use-policy/">excludes anyone domiciled in the EU</a> from its multimodal models outright, region-locking written directly into an “open” license. Apple Intelligence itself reached EU iPhones <a href="https://9to5mac.com/2025/04/01/apple-intelligence-is-now-fully-supported-in-the-eu-with-ios-18-4/">half a year late</a>. OpenAI shipped (the now discontinued) Sora everywhere except Europe. None of this is a dramatic market exit: it is simply a region toggle in a release checklist, set to “skip” because expected compliance pain exceeds expected revenue; no f*#!s are given, and none are taken. And that is what makes this very dangerous. Each individual feature is dispensable, “not so important”, etc but the sum is a continent drifting product generations behind: nerfed, late, or never… as a way of life. And that capability gap compounds, so that a 5-year gap turns quickly into a 10-year gap and so on…</p>

<h2 id="the-four-horsemen-this-time-they-hit-twice">The four horsemen (this time they hit twice)</h2>

<p>Underneath the policy failures sits something slower, worse, and much more fundamental. Four factors that shape a lot of what is to come as third-order or fourth-order effects. I call them the four horsemen, with effects through the individual (micro) and through the continent (macro).</p>

<p><strong>1. Demography.</strong></p>

<p><em>Micro:</em> people vote with the most consequential ballot there is, by not having children. In the 2019 post I mused, half-jokingly, that “one might contemplate whether populations in several developed countries are shrinking in early anticipation of the times ahead.” It reads less like a joke now. Unfortunately.</p>

<p><em>Macro:</em> inverted population pyramids, exploding old-age dependency ratios, and a shrinking workforce that must fund an expanding welfare state. More on this in the next section.</p>

<p><strong>2. Attention.</strong></p>

<p><em>Micro:</em> the TikTok-formatted mind. Average sustained attention is collapsing into sub-minute fragments; long-form reading, the entry ticket to every hard skill, is in free fall among the young. If you have read this far, congratulations, you are statistically remarkable.</p>

<p><em>Macro:</em> institutional attention collapsed to the election cycle and the news cycle. Compute buildouts, grids, and research ecosystems are decade-scale commitments; a system that re-litigates its energy policy every legislative period cannot make decade-scale commitments. A continent with a fried attention span gets exactly the infrastructure it can concentrate on: none.</p>

<p><strong>3. Skill.</strong></p>

<p><em>Micro:</em> outsourcing thinking before having learned to think. Used well, AI is the greatest skill-amplifier ever built; used as a crutch from day one, it produces graduates with credentials and without capabilities, and early cognitive-offloading studies are not reassuring. (Jana wrote about the schools’ side of this <a href="/blog/research/2025/12/15/school-ai.html">here</a> and see also the article <a href="https://just-a-tourist.bearblog.dev/cognitive-slowdown/">The Great Cognitive Slowdown: Are We Getting Dumber?</a>)</p>

<p><em>Macro:</em> this is where the <em>rock star without an audience</em> lives. Europe still produces world-class researchers, rock stars by any technical measure, but there is no ecosystem around them: no labs at scale to join, no capital to build with, no industrial base that absorbs what they know; they perform, brilliantly, to an empty room, until they leave for a full one. And one generation further out it gets darker: an audience that no longer <em>understands</em> the performance. A next generation trained on fragments, with skills outsourced, lacks the depth to appreciate, use, or leverage the expertise of the generation before it. The transmission of competence (master to student, senior to junior) is broken not because the masters disappeared, but because the apprenticeship did.</p>

<p><strong>4. Hyper-individualism.</strong></p>

<p><em>Micro:</em> the optimization of the self as the only remaining project; identity over contribution, wellness over works. A mindset of scarcity as modus operandi. And understandably so: in many respects this is the only rational answer to the current state of affairs.</p>

<p><em>Macro:</em> it aggregates into a politics of refusal. Degrowth as a moral position, NIMBY as a default, and the quiet exits. People voting with their feet, with companies now having an easy, even fashionable, excuse to relocate to the US, and the current US administration is actively rolling out the red carpet. People voting with their money: European savings finance, with impressive reliability, everyone else’s buildouts. After all, who would want to put their money into Europe? NIMBY in the morning, and US equities in the afternoon when US markets open, to get at least some piece of the pie. Each individual decision is perfectly rational, as a whole though Europe is shorting itself.</p>

<p>And there is a somewhat degenerate coupling: AI amplifies horsemen two and three (it is the attention economy’s strongest drug and the skill-crutch par excellence) while being the only realistic antidote to horseman one:</p>

<h2 id="ai-against-the-demographic-cliff">AI against the demographic cliff</h2>

<p>Here is Germany’s population structure, today and projected:</p>

<div class="center">
  <img src="http://www.pokutta.com/blog/assets/zeroth-world-update/Germany_Population_Pyramid_2024_portrait.png" alt="Germany population pyramid 2024" style="width:32%; display:inline-block; vertical-align:top;" />
  <img src="http://www.pokutta.com/blog/assets/zeroth-world-update/Germany_2034_projection.png" alt="Germany population projection 2034" style="width:32%; display:inline-block; vertical-align:top;" />
  <img src="http://www.pokutta.com/blog/assets/zeroth-world-update/Germany_2044_projection.png" alt="Germany population projection 2044" style="width:32%; display:inline-block; vertical-align:top;" />
  <p style="clear: both;"></p>
</div>
<p class="figcap"><strong>Figure 2:</strong> Germany’s population pyramid, 2024, and projections for 2034 and 2044. The boomer bulge moves from “working and paying” to “retired and drawing”, and nothing refills from below. Very optimistic projection with steady (i.e., optimistic) roll-forward.</p>

<p>The math is unforgiving: the German labor force shrinks by millions over the next decade as the boomers retire, while the number of pensioners and care recipients grows. Output is workers times output-per-worker. If the first factor falls structurally, the second must rise structurally, or the welfare state, healthcare, pensions, and ultimately political stability go with it. There is no third option; productivity is not a nice-to-have here, it is the pillar everything rests on. Former German foreign minister and vice chancellor Joschka Fischer (Green Party, of all people) <a href="https://www.welt.de/politik/deutschland/article6a1174f7be29d4b4607a46d4/rentendebatte-buhrufe-aendern-mathematik-nicht-joschka-fischer-fordert-grundlegende-reformen-im-sozialsystem.html">put it bluntly</a> in this spring’s (May 2026) pension debate, after Chancellor Merz had been booed at the trade-union congress for suggesting reform:</p>

<blockquote>
  <p>Buhrufe ändern die Mathematik nicht. (“Booing does not change the math.”)</p>
</blockquote>

<p>And this is where the usual framing (“AI replaces labor and that is a cost story”) misses the point. <em>It is not about labor cost; it is about friction.</em> A shrinking workforce does not primarily make labor expensive, it makes it <em>unavailable</em>: positions unfilled for a year, projects unstaffed, care undelivered, permits unprocessed. AI’s economic magic is the removal of friction, not just cost: no hiring lag, no scarcity in the relevant skill, scaling on demand, around the clock. Hybridization, the 2019 thesis, is exactly the mechanism by which 70-year-olds’ pensions get paid by 40-year-olds operating at 3x: the AI handles the basics, the scarce human handles the rest. Japan understood this years ago and put robots (with mixed success) in care homes without a culture war. China, facing its own demographic cliff one decade behind ours, is betting on robots and AI at national scale, explicitly. The US solves it the old way, by importing and welcoming(!!!) people, including Europeans.</p>

<p>This is actually the bitterest irony of this whole story: <strong>the one bloc that needs the zeroth world the most is the one regulating and fighting it the hardest.</strong> Europe is demographically doomed to need a productivity miracle and culturally committed to preventing one. The 2019 post asked whether AI <em>could</em> create a zeroth world. The 2026 question is only <em>who lives in it</em> as it is being built either way.</p>

<h2 id="seven-predictions-for-the-next-seven-years">Seven predictions for the next seven years</h2>

<p>The 2019 post earned its update by making claims that could fail. Same rules again: seven predictions for 2033.</p>

<ol>
  <li><strong>No European frontier lab.</strong> By 2033, no EU-headquartered lab operates within an order of magnitude of frontier training compute. Mistral ends up acquired, consolidated into sovereign-cloud contracts, or excellent-but-niche.</li>
  <li><strong>Feature lag stops being news.</strong> Flagship AI products launching in the EU six to twenty-four months late, feature-reduced, or never becomes standard practice; at least one defining consumer AI product of the early 2030s simply never ships in the EEA, and nobody is surprised.</li>
  <li><strong>The gap reaches the statistics.</strong> US labor-productivity growth exceeds the euro area’s by a full percentage point or more on average over the period, and the transatlantic GDP-per-capita gap is wider in 2033 than today; the first unambiguous zeroth-world signatures show up in US sectoral data (software, professional services, parts of admin-heavy healthcare) around 2030.</li>
  <li><strong>Europe’s AI-security shock.</strong> Before 2033, a major European infrastructure incident (a utility, a hospital group, a government system) is traced to a vulnerability class that Glasswing-tier organizations had already found and fixed on their own stacks. The response is emergency procurement from a US lab: sovereignty by invoice.</li>
  <li><strong>China cashes the deployment dividend.</strong> China leads robot density and lights-out manufacturing by a comfortable margin, its open-weight stack becomes the default AI infrastructure of the Global South, and it becomes the first large economy to visibly offset a shrinking workforce with AI-plus-robotics in official statistics.</li>
  <li><strong>Germany adopts AI through the back door.</strong> The care, administration, and SME-succession crunch forces mass AI adoption around 2029-2031, on imported stacks, faster than any digitization program ever managed, and without a single strategy paper being implemented as written.</li>
  <li><strong>Gigafactory theater.</strong> EU AI gigafactories get inaugurated, with speeches and ribbons; by 2033 not one of them has hosted a frontier-scale training run, and the EU’s total public AI compute remains smaller than a single US hyperscaler’s annual <em>addition</em>.</li>
</ol>

<p>If at least four of these turn out wrong, Europe will have surprised me in the best possible way, and nobody will be happier to write that scorecard.</p>

<h2 id="some-final-thoughts">Some final thoughts</h2>

<p>I ended the 2019 post by writing that “in order to enable sustainable progress we need to not just be aware but prepare and actively shape the use of these new technologies.” I stand by the sentence, more than ever, with one amendment learned the hard way: <em>shaping requires being at the table.</em></p>

<p>The zeroth world is no longer a thought experiment; the gap between it and the first world is opening in real time, in real numbers, in real locations, in real capabilities, in Memphis and Abilene and Shanghai. Seven years ago I asked what that gap would look like. The sobering 2026 answer is that Germany (and Europe) has decided to be a “Reallabor” (real-world laboratory), finding it out empirically in real-time… from the other side.</p>

<p><br /><br /></p>

<div style="text-align:center; font-size:20px; color:#9ca3af; margin:12px 0;">∗ ∗ ∗</div>

<p><br /></p>

<p><strong>GERMAN TRANSLATION - AI-GENERATED, ZERO TOUCH-UPS</strong></p>

<p>If you want to understand why the translation is worse than the English original, read “<a href="/blog/hidden-cost-tokenization/">The hidden cost of tokenization</a>”</p>

<p><br /></p>

<div style="text-align:center; font-size:20px; color:#9ca3af; margin:12px 0;">∗ ∗ ∗</div>

<p><br /><br /></p>

<h2 id="german-version" class="no_toc">Die Nullte Welt: ein Update nach sieben Jahren</h2>

<p><em>TL;DR: Vor sieben Jahren habe ich argumentiert, dass KI eine nullte Welt ermöglichen könnte: Volkswirtschaften, die mit einem Vielfachen der Produktivität der Ersten Welt operieren, so wie die Erste Welt mit einem Vielfachen der Dritten operiert. Das Update: Die Technologie kam schneller, als ich erwartet hatte, die Produktivitätsgewinne sind real, aber ungleich verteilt, und die nullte Welt wird gerade gebaut, in den USA und in China. Europa ist bestens auf Kurs, von der Seitenlinie aus zuzuschauen, was besonders bitter ist, weil Europa sie demografisch nötiger hat als irgendwer sonst. Die neueste Wendung: Cyber-Abwehrfähigkeiten auf Frontier-Niveau werden jetzt auf Einladung vergeben, und Europa steht überwiegend nicht auf der Liste.</em></p>

<p>In meinem <a href="/blog/random/2019/02/06/zeroth-world.html">früheren Beitrag</a> über die Nullte Welt habe ich die Auswirkungen künstlicher Intelligenz auf Gesellschaft und Wirtschaft diskutiert, mit Betonung auf den bereits vorhandenen und latenten Fähigkeiten statt auf spekulativen Zukunftsszenarien. Ich definierte KI als Systeme, die Informationen sammeln, lernen, entscheiden und autonom handeln, ähnlich der OODA-Schleife. Ich betonte die Notwendigkeit der Hybridisierung, bei der sich KI-Systeme mit Menschen zusammentun, um die Produktivität zu steigern und Abläufe zu skalieren. Beispiele waren autonomes Fahren, Callcenter und Portfoliomanagement. Außerdem ging es um das Potenzial von KI, eine „Nullte Welt“ mit beispiellosem Wirtschaftsoutput und Produktivitätsniveau zu schaffen; im Kern: Die nullte Welt verhält sich zur Ersten Welt, wie sich die Erste Welt beim Wirtschaftsoutput zur Dritten Welt verhält. Und ich habe, zumindest in Ansätzen, die Risiken von Jobverdrängung und Machtkonzentration diskutiert.</p>

<p>Das war vor <em>sieben</em> Jahren, geschrieben, als ich noch in den USA lebte, vor meinem Umzug nach Europa (genauer: Deutschland). Seitdem ist viel passiert, und das hier ist das Update. Volle Transparenz: Ich habe mit dem Update am 28. Januar 2025 begonnen (eigentlich als Sechs-Jahres-Update gedacht), in der Woche, in der DeepSeek R1 erschien. Dann lag es fast anderthalb Jahre im Entwurfsordner, während alles darin <em>wahrer</em> wurde.</p>

<p>Die Kulisse, vor der dieser Beitrag nun endlich erscheint, ist zu offensichtlich, um sie zu ignorieren: Heute, am 12. Juni 2026, geht SpaceX an die Börse, nachdem das Unternehmen <a href="https://www.cnbc.com/2026/06/11/spacex-raises-75-billion-in-record-setting-ipo-ahead-of-nasdaq-debut.html">75 Milliarden Dollar eingesammelt hat</a>, bei einer Bewertung von rund 1,8 Billionen Dollar, der größte Börsengang der Geschichte und etwa das Zweieinhalbfache des alten Rekords von Saudi Aramco; Anthropic und OpenAI <a href="https://techcrunch.com/2026/06/08/following-anthropic-openai-files-confidentially-for-ipo/">haben ihre Börsenanträge eingereicht</a>, innerhalb derselben zwei Wochen. Damit ist die <em>nullte Welt</em> jetzt eine handelbare Anlageklasse.</p>

<p><strong>ANMERKUNG.</strong> Das Offensichtliche oder das wahrscheinlichste Ergebnis zu benennen ist <em>keine</em> Befürwortung.</p>

<h2 class="no_toc" id="was-der-2019er-beitrag-richtig-sah-und-was-nicht">Was der 2019er-Beitrag richtig sah (und was nicht)</h2>

<p>Bevor ich neue Vorhersagen für die Zukunft mache, rechnen wir zuerst meine alten von 2019 ab.</p>

<p><strong>Was saß:</strong></p>

<ul>
  <li><strong>Hybridisierung war der richtige Call.</strong> Die These von 2019 war: Wir brauchen keine volle Autonomie, sondern einen Menschen im Gespann mit einer KI, die „90 % der Routine mit menschlichem Override“ erledigt. Das ist, fast wörtlich, das Deployment-Muster von 2023–2026: Copilots, Assistenten, Agenten mit Eskalation. <a href="https://www.klarna.com/international/press/klarna-ai-assistant-handles-two-thirds-of-customer-service-chats-in-its-first-month/">Klarnas Assistent</a> übernahm im ersten Monat zwei Drittel aller Kundenservice-Chats, die Arbeitslast mehrerer hundert Servicemitarbeiter. Das am besten untersuchte Callcenter-Deployment zeigte <a href="https://www.nber.org/papers/w31161">rund 14 % durchschnittlichen Produktivitätsgewinn, rund 34 % bei Anfängern</a>. Callcenter waren buchstäblich das erste Beispiel auf meiner 2019er-Liste.</li>
  <li><strong>Das Leitstellen-Modell fürs Fahren.</strong> 2019 skizzierte ich zwei Use Cases: Fernoperatoren, die mehrere Fahrzeuge überwachen, und Hub-zu-Hub-Autobahnautonomie für Lkw. Waymo fährt heute <a href="https://techcrunch.com/2026/03/27/waymo-skyrocketing-ridership-in-one-chart/">500.000 bezahlte Robotaxi-Fahrten pro Woche</a> in zehn US-Städten (mit dem erklärten Ziel von einer Million pro Woche bis Ende 2026), gestützt auf genau die Art von Remote-Flottenassistenz, die damals beschrieben wurde. Aurora startete 2025 fahrerlose Frachtfahrten zwischen Dallas und Houston, Hub-zu-Hub, exakt wie skizziert. Und meine Lieblingsfußnote: Teledriving, die reinste Form der Leitstellen-Idee, wird kommerziell von <a href="https://vay.io/">Vay</a> angeboten… einem in Berlin gegründeten Unternehmen, das in Las Vegas operiert. Den merken wir uns für später.</li>
  <li><strong>„In ein paar Jahren werdet ihr so einen Bot im App Store herunterladen.“</strong> ChatGPT erschien im November 2022, dreieinhalb Jahre nach diesem Satz, und wurde die am schnellsten adoptierte Consumer-Anwendung der Geschichte. Die Schwester-Vorhersage, dass wir den Bau solcher Systeme bald Ende-zu-Ende als studentisches Abschlussprojekt an Universitäten lehren würden, heißt heute einfach: Curriculum.</li>
  <li><strong>Machtkonzentration.</strong> Der 2019er-Beitrag spekulierte, dass „die nächste Größenkategorie von KI-Unternehmen definiert wird, mit einer wahnwitzigen Konzentration von Ressourcen, Reichtum und Macht, gegen die die heutige Konzentration im Valley verblasst“. NVIDIA wurde das erste Vier-Billionen-Dollar-Unternehmen; eine Handvoll US-Firmen gibt inzwischen in der Größenordnung von einer halben Billion Dollar <em>pro Jahr</em> für KI-Infrastruktur aus; die Spitze des S&amp;P 500 ist, funktional betrachtet, ein KI-Index. Und seit dieser Woche hat die „nächste Größenkategorie“ Ticker: SpaceXs Rekord-Listing macht das Unternehmen vom ersten Tag an zu einem der größten Amerikas, mit OpenAI und Anthropic direkt dahinter, grob vier Billionen Dollar Nullte-Welt-Equity auf dem Weg an die öffentlichen Märkte, auf einmal. Diesen Punkt verbuche ich für mich.</li>
  <li><strong>Der Compute-Trend.</strong> Die „Verdopplung alle 3,5 Monate“ beim Trainings-Compute konnte offensichtlich nicht in genau diesem Tempo weitergehen (jede Exponentialfunktion ist eine Sigmoide), aber der Kernpunkt hielt: dass wir schneller unterwegs waren als in jedem früheren Technologiezyklus. Der Trainings-Compute für Frontier-Modelle wuchs weiter um Vielfache pro Jahr, finanziert durch die Capex-Zahlen von oben.</li>
</ul>

<p><strong>Was daneben lag:</strong></p>

<ul>
  <li><strong>Der Mechanismus.</strong> Ich schaute auf Reinforcement Learning und Self-Play (AlphaStar et al.). Der eigentliche Durchbruch kam aus selbstüberwachtem Lernen auf Text, in großem Maßstab. Die <em>Form</em> der Vorhersage (Fähigkeiten durch Compute-Skalierung, kein fundamentales Hindernis) stimmte; der Mechanismus nicht. Ich verbuche das als Glück an der Stelle, die zählt, und als Irrtum an der Stelle, die nicht zählt.</li>
  <li><strong>Zeitpläne für die physische Welt.</strong> Das Fahren dauerte länger, als die Extrapolation der Disengagement-Raten nahelegte (kam aber). Robo-Advisors blieben mittelmäßig. Atome bleiben härter als Bits.</li>
  <li><strong>Die Aggregatzahlen (bislang).</strong> Man sieht die nullte Welt noch immer nicht in den BIP-Statistiken. Produktivitätsstatistiken bewegen sich langsam, Diffusion ist klumpig, und wir sind früh dran. Das ist das klassische Solow-Problem: „Computer überall, außer in den Produktivitätsstatistiken.“ Was man aber <em>bereits</em> sehen kann, ist die Divergenz zwischen Blöcken, und genau die ist das eigentliche Thema dieses Updates.</li>
</ul>

<h2 class="no_toc" id="agenten-die-ooda-schleife-par-excellence">Agenten: die OODA-Schleife par excellence</h2>

<p>Wer die 2019er-Definition eines KI-Systems heute wieder liest, (1) wahrnehmen, (2) lernen, (3) entscheiden, (4) handeln, mit einem Maß an Autonomie, kann sich ein Lächeln kaum verkneifen: Das ist schlicht die Beschreibung eines Agenten des Jahres 2026. Tool Use, Computer Use, Coding-Agenten, Deep-Research-Agenten: die OODA-Schleife, kommerziell und in großem Maßstab. Was eine aus der Militärdoktrin entliehene Abstraktion war, ist jetzt eine Produktkategorie.</p>

<p>Und die Produktivitätsgewinne sind real, wenn auch ungleich verteilt. Ich werde die riesige Studienlage hier nicht referieren, nur zwei Kalibrierungspunkte: Anfängerlastige, klar umrissene Arbeit zeigt große Gewinne (die Callcenter-Zahlen oben), während <a href="https://metr.org/blog/2025-07-10-early-2025-ai-experienced-os-dev-study/">METRs Studie von 2025</a> fand, dass erfahrene Open-Source-Entwickler mit KI-Tools auf ihren eigenen, vertrauten Codebasen tatsächlich <em>langsamer</em> waren, während sie sich schneller glaubten. Beide Ergebnisse stimmen; die Verteilung der Gewinne ist der entscheidende Punkt. Meine eigene Erfahrung, siehe den Beitrag <a href="/blog/agentic-researcher/">The Agentic Researcher</a>, ist, dass mit Verification-first-Workflows die Gewinne in der Forschungsarbeit sehr substanziell sind; und der Ausgewogenheit halber: <a href="/blog/not-every-discovery-needs-an-llm/">nicht jede Entdeckung braucht ein LLM</a>.</p>

<p>Eine der Kernhypothesen von 2019 war der <em>Automate-and-Elevate</em>-Zyklus: die Routine automatisieren, eine Ebene höher arbeiten, wiederholen. Das ist jetzt real, mit passend zugeschnittenen und passend betoolten Agenten. Der Individual Contributor des Jahres 2026 verhält sich zunehmend wie ein Manager von Prozessen, die zufällig <em>in silico</em> laufen; im Grunde ein Solo-Unternehmer. Das war der Mechanismus, über den ich ein 10x im Output pro Person für plausibel erklärte. Ich sehe keinen Grund, diese Behauptung zurückzunehmen, eher die Frage, <em>wo</em> es passieren wird und ob es sich aufzinst. Womit wir beim eigentlichen Update wären.</p>

<h2 class="no_toc" id="das-rennen-läuft-jetzt-zwischen-blöcken-usa-china-europa">Das Rennen läuft jetzt zwischen Blöcken: USA, China, Europa</h2>

<p>2019 dachte ich die nullte Welt in Ländern, die sich beim BIP pro Erwerbstätigem absetzen. 2026 ist die bessere Auflösung die in Blöcken, denn die Inputs, auf die es ankommt, liegen auf Block-Ebene: Compute, Energie, Daten, Regulierung, Kapital, Talent.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Faktor</th>
      <th style="text-align: center">USA</th>
      <th style="text-align: center">China</th>
      <th style="text-align: center">Europa</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">Frontier-Compute</td>
      <td style="text-align: center">✓✓</td>
      <td style="text-align: center">~ (beschränkt, kompensierend, ändert sich aber schnell)</td>
      <td style="text-align: center">✗</td>
    </tr>
    <tr>
      <td style="text-align: left">Energie (Preis &amp; Ausbau)</td>
      <td style="text-align: center">~ (billig, netzlimitiert)</td>
      <td style="text-align: center">✓✓</td>
      <td style="text-align: center">✗</td>
    </tr>
    <tr>
      <td style="text-align: left">Daten</td>
      <td style="text-align: center">✓</td>
      <td style="text-align: center">✓✓</td>
      <td style="text-align: center">✗ (per Design)</td>
    </tr>
    <tr>
      <td style="text-align: left">Regulierung (für Builder)</td>
      <td style="text-align: center">✓</td>
      <td style="text-align: center">✓ (pragmatisch)</td>
      <td style="text-align: center">✗</td>
    </tr>
    <tr>
      <td style="text-align: left">Kapital</td>
      <td style="text-align: center">✓✓</td>
      <td style="text-align: center">✓</td>
      <td style="text-align: center">✗ (vorhanden, risikoscheu)</td>
    </tr>
    <tr>
      <td style="text-align: left">Talent</td>
      <td style="text-align: center">✓✓ (importiert)</td>
      <td style="text-align: center">✓✓ (Masse)</td>
      <td style="text-align: center">✓ (exportiert)</td>
    </tr>
  </tbody>
</table>

<p><strong>Die USA</strong> spielen das geschlossene Frontier-Spiel: eine Handvoll Labore, im Wesentlichen unbegrenztes Kapital und Compute-Ausbauten, die die Kategorie „Rechenzentrum“ hinter sich gelassen haben und zum „Industrieprogramm“ geworden sind. <a href="https://openai.com/index/announcing-the-stargate-project/">Stargate</a> wurde mit 500 Milliarden Dollar angekündigt, in genau der Woche, in der ich diesen Entwurf begann; xAIs erster Memphis-Cluster, den ich ursprünglich mit 100.000 GPUs als unerhörte Zahl zitierte, hat die 200.000 überschritten, und der Nachfolgestandort wird in Gigawatt vermarktet statt in Chip-Zahlen. Die bindende Restriktion in den USA ist nicht mehr Geld oder Chips; es sind Strom und Netzanschlüsse.</p>

<p><strong>China</strong> spielt das offene und das Deployment-Spiel, und der DeepSeek-Moment war kein Einzelfall. Qwen, Kimi, GLM, MiniMax: Die meistgenutzten Open-Weight-Modelle der Welt sind heute, mit komfortablem Abstand, chinesisch, was bedeutet, dass das <em>Default-Substrat</em> für alle außerhalb der Frontier-Labore zunehmend chinesisch ist. Compute ist der limitierende Input (Exportkontrollen wirken, teilweise), aber die Antwort darauf waren Effizienz-Engineering plus ein heimischer Beschleuniger-Stack, der schnell reift. Und der Vorstoß geht den ganzen Stack hinunter: Reuters hat ein staatlich orchestriertes <a href="https://www.reuters.com/world/china/how-china-built-its-manhattan-project-rival-west-ai-chips-2025-12-17/">„Manhattan-Projekt“</a> um Huawei dokumentiert, das die Chip-Werkzeugkette selbst replizieren soll, bis hin zu der einen Maschine, von der alle dachten, sie sei nicht replizierbar: ASMLs EUV-Lithografie. Heimische EUV-Prototypen sind Berichten zufolge im Test, mit KI-Chip-Produktion angepeilt für 2028 (Insider sagen 2030; Analysten sagten früher: ein Jahrzehnt). Man darf die Prahlerei gern diskontieren, seriöse Einschätzungen tun das, aber die Richtung ist eindeutig: Der Engpass wird ingenieurtechnisch umgangen. Europa sollte das einen Moment sacken lassen, denn ASML in Veldhoven ist das einzige echte KI-relevante Druckmittel des Kontinents, und der Countdown, dieses Druckmittel zu beenden, läuft. Bei Energie gibt es keinen Wettbewerb: China hat letztes Jahr mehr Erzeugungskapazität zugebaut, als Deutschland insgesamt betreibt, hat <a href="https://electrek.co/2025/09/02/h1-2025-china-installs-more-solar-than-rest-of-the-world-combined/">im ersten Halbjahr 2025 mehr als doppelt so viel Solar installiert wie der Rest der Welt zusammen</a>, und seine kumulierte Solarflotte überschritt 2025 die Terawatt-Marke, vieles davon in Wüsten-Megabasen wie der „Großen Solarmauer“ von Kubuqi, der Art Infrastruktur, der man vom Weltall aus beim Wachsen zusehen kann. Und entscheidend: China dominiert die Schicht, in der Nullte-Welt-Produktivität die physische Ökonomie berührt: Industrieroboter (rund die Hälfte der globalen Installationen), E-Autos, Batterien, elektrifizierte Fertigung. Wenn die USA das Hirn besitzen, besitzt China den Stoffwechsel.</p>

<p><strong>Europa</strong> spielt das Kunden-Spiel und nennt es das Werte-Spiel. Der EU AI Act trat 2024 in Kraft; im November 2025 schlug die Kommission per <a href="https://digital-strategy.ec.europa.eu/en/policies/digital-omnibus">Digital Omnibus</a> bereits vor, genau die Regeln zu verschieben und aufzuweichen, deren Verabschiedung sie gerade noch gefeiert hatte, nach der vorhersehbaren Erkenntnis, dass sie nicht umsetzbar waren. Erst regulieren, dann zurückrudern, niemals bauen. Beim Compute ist Europas stolzeste Maschine, JUPITER in Jülich (Europas erstes Exascale-System, rund 24.000 Superchips), ein feines wissenschaftliches Instrument und ein Rundungsfehler gegen einen einzelnen US-Standort. Die Schlagzeilen-Antwort, <a href="https://digital-strategy.ec.europa.eu/en/news/eu-launches-investai-initiative-mobilise-eu200-billion-investment-artificial-intelligence">InvestAI</a> mit 200 Milliarden Euro und „KI-Gigafabriken“, bleibt, Stand heute, im Wesentlichen eine Anlageklasse aus Pressemitteilungen. Der <a href="https://commission.europa.eu/topics/eu-competitiveness/draghi-report_en">Draghi-Bericht</a> hat im September 2024 alles gesagt, was zu sagen war, in Amtsprosa, mit Zahlen; bemerkenswert wenig ist seitdem passiert. Mistral existiert und ist wirklich gut, was es zur Ausnahme macht, die die Regel bestätigt; Aleph Alpha, die deutsche Frontier-Hoffnung, stieg 2024 aus dem Frontier-Rennen aus.</p>

<p>Der absorbierende Zustand scheint offensichtlich: Die nullte Welt wird kein Country Club, bei dem man einen Aufnahmeantrag stellen kann. Es läuft auf zwei Ökosysteme hinaus, eine US-geführte geschlossene Frontier und einen chinesisch geführten Open/Deployment-Stack, plus Kunden. Europa entscheidet sich gerade, mit großer prozeduraler Sorgfalt und der unbeirrbaren Exaktheit der Bürokratie, Kunde zu sein.</p>

<p>Und das Kundendasein gibt es, wie sich herausstellt, jetzt auch in Stufen.</p>

<h2 class="no_toc" id="die-glasswing-asymmetrie-sicherheit-auf-einladung">Die Glasswing-Asymmetrie: Sicherheit auf Einladung</h2>

<p>Im April 2026 kündigte Anthropic <a href="https://www.anthropic.com/project/glasswing">Project Glasswing</a> an, eine Initiative zur „Absicherung der kritischsten Software der Welt“, gebaut um frühen Zugang zu seinem neuesten Frontier-Modell, Claude Mythos Preview. Die definierende Fähigkeit des Modells ist das Finden und Beheben von Software-Schwachstellen in Maschinengeschwindigkeit; es hatte zur Ankündigung „bereits Tausende Zero-Day-Schwachstellen in kritischer Infrastruktur identifiziert“, und binnen Wochen meldeten die Startpartner <a href="https://www.anthropic.com/news/expanding-project-glasswing">über 10.000 Schwachstellen hoher oder kritischer Schwere</a> in ihren Codebasen. Man halte hier kurz inne: Die Find-and-Fix-Schleife der Cybersicherheit läuft jetzt in KI-Geschwindigkeit, das Fenster von Schwachstelle zu Exploit schrumpft von Monaten auf Minuten, und dieselbe Fähigkeitsklasse wird ungefähr einen Open-Weight-Release-Zyklus später in den Händen von Angreifern sein. Die Verwundbarkeitsuhr hat für alle gleichzeitig zu ticken begonnen: Aber wer wird zuerst gehärtet?</p>

<p>Die elf benannten Startpartner: Amazon Web Services, Apple, Broadcom, Cisco, CrowdStrike, Google, JPMorganChase, die Linux Foundation, Microsoft, NVIDIA, Palo Alto Networks; nicht nur America first, sondern exklusiv. Die Erweiterung auf rund 150 weitere Organisationen in über fünfzehn Ländern wurde, in Anthropics eigenen Worten, „nach mehreren Wochen enger Zusammenarbeit“ mit Partnern, der Sicherheitsindustrie, Open-Source-Maintainern <em>und der US-Regierung</em> entschieden. Einzelne europäische Organisationen kommen rein (BT trat im Juni bei, in einer Erweiterungsrunde, nach Erfüllung von Anthropics Sicherheitsanforderungen), aber Einladung-als-Ausnahme ist hier der Punkt: Zugang zur defensiven Frontier ist diskretionär, widerruflich und läuft über San Francisco und Washington. Privilegierter Zugang ist Industriepolitik geworden, und Härtung ist (eine neue Schicht von) Exportkontrolle. Niemand hat Europa irgendetwas verboten, es ist nur ganz hinten in der Schlange gelandet.</p>

<p>Für die Nullte-Welt-Erzählung kommt damit eine zweite Dimension hinzu. Die erste Dimension war Produktivität; diese hier ist <em>Verwundbarkeit</em>. Die USA nutzen Frontier-KI, um systematisch zuerst den eigenen Stack zu härten: ihre Clouds, ihre Chips, ihre Banken, ihr Open-Source-Substrat. Europa läuft auf weiten Teilen derselben Software, also erbt es Patches flussabwärts, nach dem Zeitplan der Anbieter und gemäß deren Prioritäten. Aber Europas <em>eigener</em> Stack, die SAPs und Siemens-Steuerungen, die Versorger, die Krankenhaus-IT, die Behördensysteme, der Long Tail europäischen Codes aus fragmentierten Souveränitäts-Reflexreaktionen, der niemanden in Memphis interessiert, hat keinen Platz an diesem Tisch und keinen Zugang zu Frontier-Härtungsfähigkeiten. Kein Problem, machen wir eben unser eigenes Project Glasswing in Europa? Europa kann nicht einfach sein eigenes Glasswing fahren, denn ein Glasswing setzt ein Mythos voraus, und Europa hat kein Frontier-Modell, über dessen Zugang es einen solchen Härtungsvorsprung erzeugen könnte. Anders gesagt: Die Fähigkeitslücke ist zur Sicherheitslücke geworden, und dafür gibt es im Grunde keinen Fix.</p>

<p>Bemerkenswert ist auch, dass diese Episode erhellender ist als ein Jahrzehnt von Souveränitäts-Weißbüchern voller Hypothesen; die Komik dabei: Es wurde so viel geschrieben, und trotzdem hat diesen Fall niemand kommen sehen. Während Europa Jahre damit verbrachte, horizontale KI-Regulierung zu entwerfen, geschah die tatsächliche Allokation von Sicherheit im KI-Zeitalter, der wohl souveränitätsrelevantesten Ressource überhaupt, über eine Partnerliste, zusammengestellt von einem privaten amerikanischen Unternehmen in Abstimmung mit seiner Heimatregierung, binnen Wochen. So sieht Technikgestaltung aus, wenn man am Tisch sitzt. Und das ist die Definition davon, ein NPC zu sein (nicht einmal als Nachgedanke vorzukommen), wenn man es nicht tut.</p>

<h2 class="no_toc" id="warum-europa-im-ki-rennen-nie-aufholen-wird">Warum Europa im KI-Rennen nie aufholen wird</h2>

<p>Ich nehme Deutschland als durchgehendes Beispiel, teils weil ich das System kenne (und hier lebe), teils weil Deutschland die größte Volkswirtschaft des Blocks und richtungsweisend repräsentativ ist; das Argument überträgt sich mit kleinen Anpassungen auf die meisten anderen Länder des Kontinents.</p>

<p>Zum Einstieg ein kurzer Zeitkapsel-Moment: Am 28. Januar 2025, als ich diesen Entwurf begann, hatte DeepSeek gerade seine offenen Modelle veröffentlicht (V3, R1, Janus-Pro) und chinesische Modelle damit auf Augenhöhe mit den besten des Westens gebracht, trainiert auf exportkontrollierten, kastrierten GPUs zu einem Bruchteil des üblichen Preispunkts. Es schickte die Börse auf Talfahrt („KI in den USA ist erledigt“), nur damit sie am nächsten Tag das meiste wieder aufholte („Moment mal, billigere KI heißt mehr Nutzer, und mehr Nutzer heißt mehr Geld“); dieselbe Geschichte wie bei den Dampfmaschinen. Jemand schickte mir in jener Woche ein Meme, das die Lage bis heute zusammenfasst:</p>

<div class="center">
  <img src="http://www.pokutta.com/blog/assets/zeroth-world-update/what-did-you-do-recently.png" alt="what-did-you-do-recently" style="width:80%" />
  <p style="clear: both;"></p>
</div>
<p class="figcap"><strong>Abbildung 1:</strong> Eine Zusammenfassung des Stands von KI in Deutschland und, allgemeiner, in Europa. Unverändert seit Januar 2025, was genau das Problem ist.</p>

<p>Es gibt fünf kritische Faktoren, die man braucht, um eine Einladung zum KI-Spiel zu bekommen:</p>
<ol>
  <li>High-End-GPUs, und zwar viele</li>
  <li>Billige Energie</li>
  <li>Hochwertige Daten</li>
  <li>Ein günstiges regulatorisches Umfeld</li>
  <li>Talent</li>
</ol>

<p>Mit 4 von 5 kommt man vermutlich durch, vielleicht sogar mit 3 von 5, wenn es die richtigen sind, aber Deutschland bräuchte 5 Wunder; dasselbe gilt für den Großteil Europas.</p>

<p><strong>High-End-GPUs.</strong> Deutschlands Position im GPU-Wettrüsten liegt mindestens eine Größenordnung zurück, realistischer zwei bis drei, und die Lücke <em>wächst</em>. Das aktuelle Flaggschiff, JUPITER in Jülich mit seinen rund 24.000 Superchips, wird als kontinentale Errungenschaft gefeiert, und innerhalb des wissenschaftlichen Rechnens ist es eine. Aber die Maßeinheit an der Frontier hat sich geändert: xAIs Memphis-Standort, den ich zu Beginn dieses Entwurfs mit 100.000 GPUs zitierte (und der damals schon das Fünffache des deutschen Flaggschiffs war), hat sich seitdem verdoppelt und wurde von einem Nachfolgestandort abgelöst, der in Gigawatt vermarktet wird; Stargate ist ein 500-Milliarden-Dollar-Programm; die US-Hyperscaler geben zusammen in der Größenordnung von einer halben Billion Dollar pro Jahr aus. Dagegen reserviert Europas Gigafabrik-Initiative rund 20 Milliarden Euro für fünf Standorte, ans Netz zu gehen zu einem zukünftigen Datum, vorbehaltlich Vergabeverfahren. Manche wenden ein, DeepSeek beweise, dass man keine GPUs im Frontier-Maßstab braucht. Teilweise wahr, und ernst zu nehmen, aber man beachte, was DeepSeek tatsächlich hatte: außergewöhnliches Engineering-Talent <em>und</em> immer noch substanziellen Compute (allein ihr V3-Trainingslauf verbrauchte <a href="https://arxiv.org/pdf/2412.19437">2,788 Millionen GPU-Stunden</a>; und die berühmten „5,6 Millionen Dollar“ bepreisen einen einzelnen Pretraining-Lauf, nicht das Programm drumherum). „GPU-arm“ nach US-Maßstäben ist nach deutschen immer noch GPU-reich.</p>

<p>Und man beachte das Zugangsregime selbst, denn es ist eine eigene Lektion. Außerhalb der USA gibt es Frontier-GPUs in genau zwei Geschmacksrichtungen: generft oder nicht verfügbar. China bekommt die generfte Sorte, absichtlich gedrosselte Exportmodelle (H800er, H20er, was der Deal der Saison gerade erlaubt), und antwortete mit Schmuggel, kompromisslosem Effizienz-Engineering und einem heimischen Beschleuniger-Stack (Huaweis Ascend-Linie und Verwandte), der jedes Quartal besser wird. China hat eine Lösung. Europa bekommt die andere Sorte: Nichts ist formal verboten, man bekommt nur schlicht keine Zuteilung. NVIDIAs Produktion ist auf Jahre an US-Hyperscaler vorverkauft, was den Markt erreicht, wird rationiert, und als Washington die Hierarchie im Januar 2025 mit dem „AI Diffusion Framework“ kurzzeitig formalisierte, wachten mehrere EU-Mitgliedstaaten (darunter Polen und Portugal) in Tier 2 mit harten GPU-Quoten auf, zu Brüssels erheblichem Zorn, bevor die Regel zugunsten von Deal-für-Deal-Diplomatie kassiert wurde. Die Realität blieb dieselbe: GPU-Zugang ist ein Privileg, das anderswo verwaltet wird. Chinas Antwort ist, eigene zu bauen. Europas Antwort ist eine Arbeitsgruppe.</p>

<p><strong>Billige Energie.</strong> Deutschlands Industriestrompreise gehören zu den höchsten aller großen Volkswirtschaften; für Rechenzentren ist der Vergleich brutal (näherungsweise, große Industrieabnehmer, 2024/25; vgl. <a href="https://www.iea.org/data-and-statistics/charts/estimated-final-electricity-price-for-large-industrial-customers-in-energy-intensive-industries-2019-2024">IEA-Daten</a>):</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Land</th>
      <th style="text-align: right">~USD/kWh (Industrie)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">Deutschland</td>
      <td style="text-align: right">0,19</td>
    </tr>
    <tr>
      <td style="text-align: left">Frankreich</td>
      <td style="text-align: right">0,13</td>
    </tr>
    <tr>
      <td style="text-align: left">USA</td>
      <td style="text-align: right">0,08</td>
    </tr>
    <tr>
      <td style="text-align: left">China</td>
      <td style="text-align: right">0,08</td>
    </tr>
    <tr>
      <td style="text-align: left">Norwegen</td>
      <td style="text-align: right">0,06</td>
    </tr>
  </tbody>
</table>

<p>Und der Preis ist nur die Hälfte; die andere Hälfte ist Ausbaugeschwindigkeit. KI-Compute ist, physikalisch betrachtet, eine Energieumwandlungsindustrie: Wer am schnellsten Gigawatt anschließen kann, gewinnt. China schließt pro Jahr ein ganzes Deutschland an Kapazität an; die USA beschleunigen Gasturbinen und reaktivieren Kernkraftwerke neben Rechenzentren; Deutschland debattiert. Also: zweimal Nein.</p>

<p><strong>Hochwertige Daten.</strong> Deutschland hat strukturelle Hürden beim Zugang zu und der Nutzung von Daten im KI-Maßstab. Die DSGVO, was immer ihre Verdienste für die individuelle Privatsphäre sind, hat ein datenarmes Umfeld geschaffen: Einwilligungsregimes, Speicher- und Übertragungsbeschränkungen und Compliance-Aufwand, der genau die Art großskaliger Datenaggregation entmutigt, die modernes KI-Training erfordert. Kulturelle Haltungen verstärken das Gesetz: Die Bevölkerung ist ungewöhnlich datenschutzängstlich, die Beteiligung an Daten-Initiativen niedrig, und jedes Digitalisierungsprojekt wird mit eingebautem Oppositionskomitee ausgeliefert. Das Ergebnis ist ein Datenökosystem, das in der Reichweite begrenzt, per Design fragmentiert und fundamental quer zu der Art liegt, wie KI-Systeme gebaut werden. Derweil liegen die klinischen, industriellen und administrativen Daten, die Europa <em>tatsächlich</em> einzigartig hat, in Silos, die nicht einmal europäische Forscher nutzen können.</p>

<p><strong>Günstiges regulatorisches Umfeld.</strong> Deutschland ist bekannt für ein starkes regulatorisches Umfeld, nur eben nicht das richtige. Der Instinkt ist, die Risiken einer Technologie zu regulieren, bevor man die Technologie hat. Der AI Act ist das Denkmal dieses Instinkts: Jahre der Verhandlung, eine Compliance-Industrie hochgezogen, bevor ein einziges europäisches Frontier-Modell existierte, und dann, binnen fünfzehn Monaten nach Inkrafttreten, ein Kommissions-„Omnibus“ zum Verschieben und Verwässern, weil die Realität nicht kooperieren wollte. Der Schaden solcher Regulierung ist nicht einmal primär der direkte Compliance-Aufwand; es ist die <em>Unsicherheitssteuer</em> und das Signal. Gründer preisen ein, dass sich die Regeln vor ihrer Series B zweimal ändern können; viele inkorporieren einfach woanders. Regulierung trocknet die Innovation aus und verwandelt, was ein blühendes Tech-Ökosystem sein könnte, in eine Compliance-Landschaft, die sich nur Incumbents leisten können.</p>

<p><strong>Talent.</strong> Der eine Faktor, bei dem Europa wirklich konkurrenzfähig ist, was das Ergebnis umso vernichtender macht. Deutschland bildet weiterhin exzellente Forscher und Ingenieure aus (der letzte Zinseszins-Aktivposten des Bildungssystems), aber es bildet sie <em>für den Export</em> aus. Die Besten gehen dorthin, wo Compute, Kapital und Ambition sind: historisch die USA, zunehmend auch chinesische Labore. Die Studierendenzahlen in MINT sinken, die demografische Pipeline schrumpft (mehr dazu unten), Einwanderungsprozesse bleiben ein bürokratischer Hindernislauf, und das heimische Ökosystem entwickelt keine Anziehungskraft: keine kritische Masse an Frontier-Arbeit, keine Scale-ups, dünne Frühphasenfinanzierung und Exit-Umgebungen, die ambitionierte Gründer gehen lassen, bevor sie anfangen. Förderung, wo es sie gibt, wird in homöopathischen Dosen verabreicht: zweistellige Millionenbeträge, verteilt über Dutzende Empfänger, verkündet als Strategie. Das kanonische Beispiel: <a href="https://openeurollm.eu/launch-press-release">OpenEuroLLM</a>, Europas Flaggschiff-Antwort auf den DeepSeek-Moment, angekündigt in genau derselben Woche: 52 Millionen Euro, verteilt auf ein Konsortium von <em>zwanzig</em> Forschungseinrichtungen, Unternehmen und Rechenzentren, komplett mit Arbeitspaketen, Deliverables und Berichtspflichten. Das sind rund 2,6 Millionen Euro pro Partner vor Koordinations-Overhead, ins Feld geführt gegen Labore, deren wöchentliche Stromrechnungen höher liegen. Ein einzelnes US-Labor sammelt in einer Woche, für eine Idee, mehr ein, als solche Programme in einem Jahr über einen Kontinent ausschütten.</p>

<p>Und über allem sitzt Kultur. Es gibt keine nette Art, das zu sagen: Deutschland hat derzeit keine Kultur des Bauens. Wirtschaftswachstum selbst ist suspekt geworden („Wollen wir das überhaupt?“ ist eine ernsthafte Frage in ernsthaften Zeitungen), Risikobereitschaft wird sozial bestraft, Scheitern disqualifiziert, und der bequeme Default ist, NPC im Spiel von jemand anderem zu sein: die Plattformen konsumieren, die Modelle mieten, die Externalitäten regulieren und die resultierende Rolle „digitale Souveränität“ nennen. NGMI, wie die Kids sagen. Die Kids haben übrigens größtenteils aufgehört, es hier zu sagen; sie sagten es aus Palo Alto, Zürich oder Shenzhen.</p>

<h2 class="no_toc" id="was-bleibt-nischen-auf-schrumpfenden-produktkarten">Was bleibt: Nischen, auf schrumpfenden Produktkarten</h2>

<p>Was ist also der realistische europäische KI-Play? Nischen. Und um fair zu sein, einige davon sind exzellent: DeepL hat in Köln ein Weltklasse-Übersetzungsgeschäft aufgebaut; Helsing wurde mit Verteidigungs-KI zu einem der wertvollsten Start-ups Europas; Black Forest Labs in Freiburg trainiert einige der besten Bildmodelle der Welt; Mistral hält die Franchise „glaubwürdiges offenes europäisches Modell“. Europa wird vertikale Erfolge bekommen, in Industrie-KI, Pharma, Legal Tech, Verteidigung, eingebetteten Systemen. Das sind echte Unternehmen mit echten Umsätzen, und ich bin froh, dass es sie gibt.</p>

<p>Aber man beachte drei Dinge. Erstens: Nischen leben flussabwärts von der Frontier eines anderen. Sie finetunen, destillieren und deployen auf Chips, Modellen und Clouds, die anderswo gehören; sie sind Mieter, und Mieter setzen nicht die Miete. Zweitens: Das Nischen-Ergebnis ist das <em>gute</em> Szenario, und auch es folgt dem Muster von oben: große Forschung flussaufwärts, Desaster flussabwärts. Noch ein kanonisches Beispiel in Sichtweite. Latent Diffusion, die Technik unter der gesamten Bildgenerierungsindustrie, wurde in der CompVis-Gruppe in Heidelberg/an der LMU München erfunden; den Plattformwert ernteten Stability, Midjourney und OpenAI, und erst Jahre später gründeten einige der ursprünglichen Autoren Black Forest Labs, um sich ein Stück zurückzuholen. Dieselbe Geschichte eine Generation früher: Das LSTM wurde in den 1990ern in München erfunden und trieb ein Jahrzehnt lang Googles Sprach- und Übersetzungsstack an. Europa erfindet; andere zinsen auf. Der Rockstar spielt; das Publikum, und die Abendkasse, sind woanders.</p>

<p>Drittens, und das sollte selbst die Bequemen beunruhigen: Während Europa übers Aufholen debattiert, verlassen die Produkte leise den Kontinent. Apple liefert sein neues Siri AI überallhin außer in die EU, während <a href="https://www.reuters.com/business/apple-failed-make-its-ai-tool-comply-eu-regulations-eu-commission-says-2026-06-09/">Cupertino und Brüssel sich gegenseitig die Schuld</a> an der Verzögerung zuweisen. Google hat <a href="https://9to5google.com/2026/04/06/google-ai-edge-eloquent-app/">AI Edge Eloquent</a> gestartet, eine kostenlose On-Device-Diktier-App, in den USA und fast überall sonst, <a href="https://innovation-village.com/google-launches-offline-ai-dictation-app-ai-edge-eloquent/">aber nicht im EWR</a>; eine <em>vollständig offline</em> laufende App, wohlgemerkt; so viel zum Amok laufenden Datenschutzargument. Meta <a href="https://www.axios.com/2024/07/17/meta-future-multimodal-ai-models-eu">hielt seine multimodalen Modelle</a> 2024 von der EU zurück, und das war ein Präzedenzfall, keine Ausnahme. Die Fortsetzung machte es explizit: Llama 4s Lizenz <a href="https://www.llama.com/llama4/use-policy/">schließt jeden mit Sitz in der EU</a> von seinen multimodalen Modellen rundheraus aus, Region-Locking, direkt in eine „offene“ Lizenz geschrieben. Apple Intelligence selbst erreichte EU-iPhones <a href="https://9to5mac.com/2025/04/01/apple-intelligence-is-now-fully-supported-in-the-eu-with-ios-18-4/">mit einem halben Jahr Verspätung</a>. OpenAI lieferte (das inzwischen eingestellte) Sora überallhin außer nach Europa. Nichts davon ist ein dramatischer Marktaustritt: Es ist schlicht ein Regionen-Schalter in einer Release-Checkliste, gesetzt auf „skip“, weil erwartete Compliance-Schmerzen den erwarteten Umsatz übersteigen; keine F*#!s werden gegeben, und keine genommen. Und genau das macht es so gefährlich. Jedes einzelne Feature ist verzichtbar, „nicht so wichtig“ etc., aber die Summe ist ein Kontinent, der Produktgenerationen zurückfällt: generft, verspätet oder gar nicht… als Lebensweise. Und diese Fähigkeitslücke zinst sich auf, sodass aus einer 5-Jahres-Lücke schnell eine 10-Jahres-Lücke wird und so weiter…</p>

<h2 class="no_toc" id="die-vier-reiter-diesmal-treffen-sie-doppelt">Die vier Reiter (diesmal treffen sie doppelt)</h2>

<p>Unter den Politikversagen liegt etwas Langsameres, Schlimmeres und viel Fundamentaleres. Vier Faktoren, die als Effekte dritter und vierter Ordnung vieles von dem prägen, was kommt. Ich nenne sie die vier Reiter, mit Wirkung durch das Individuum (mikro) und durch den Kontinent (makro).</p>

<p><strong>1. Demografie.</strong></p>

<p><em>Mikro:</em> Menschen stimmen mit dem folgenreichsten Stimmzettel ab, den es gibt, indem sie keine Kinder bekommen. Im 2019er-Beitrag sinnierte ich, halb im Scherz, dass „man darüber nachdenken könnte, ob die Bevölkerungen mehrerer entwickelter Länder in früher Vorwegnahme der kommenden Zeiten schrumpfen“. Es liest sich heute weniger wie ein Scherz. Leider.</p>

<p><em>Makro:</em> invertierte Bevölkerungspyramiden, explodierende Altenquotienten und eine schrumpfende Erwerbsbevölkerung, die einen expandierenden Wohlfahrtsstaat finanzieren muss. Mehr dazu im nächsten Abschnitt.</p>

<p><strong>2. Aufmerksamkeit.</strong></p>

<p><em>Mikro:</em> der TikTok-formatierte Geist. Die durchschnittliche Daueraufmerksamkeit kollabiert in Sub-Minuten-Fragmente; Langform-Lesen, das Eintrittsticket zu jeder anspruchsvollen Fähigkeit, ist bei den Jungen im freien Fall. Wer bis hierher gelesen hat: Glückwunsch, das ist statistisch bemerkenswert.</p>

<p><em>Makro:</em> Institutionelle Aufmerksamkeit ist auf den Wahlzyklus und den Nachrichtenzyklus kollabiert. Compute-Ausbauten, Netze und Forschungsökosysteme sind Dekaden-Commitments; ein System, das seine Energiepolitik jede Legislaturperiode neu verhandelt, kann keine Dekaden-Commitments eingehen. Ein Kontinent mit frittierter Aufmerksamkeitsspanne bekommt genau die Infrastruktur, auf die er sich konzentrieren kann: keine.</p>

<p><strong>3. Können.</strong></p>

<p><em>Mikro:</em> das Denken auslagern, bevor man denken gelernt hat. Gut eingesetzt ist KI der größte Fähigkeitsverstärker, der je gebaut wurde; als Krücke vom ersten Tag an produziert sie Absolventen mit Abschlüssen und ohne Fähigkeiten, und die frühen Studien zum Cognitive Offloading sind nicht beruhigend. (Jana hat über die Schulseite davon <a href="/blog/research/2025/12/15/school-ai.html">hier</a> geschrieben; siehe auch den Artikel <a href="https://just-a-tourist.bearblog.dev/cognitive-slowdown/">The Great Cognitive Slowdown: Are We Getting Dumber?</a>)</p>

<p><em>Makro:</em> Hier wohnt der <em>Rockstar ohne Publikum</em>. Europa produziert weiterhin Weltklasse-Forscher, Rockstars nach jedem fachlichen Maßstab, aber es gibt kein Ökosystem um sie herum: keine Labore im großen Maßstab zum Andocken, kein Kapital zum Bauen, keine industrielle Basis, die aufnimmt, was sie wissen; sie spielen, brillant, vor leerem Saal, bis sie in einen vollen wechseln. Und eine Generation weiter wird es dunkler: ein Publikum, das die Darbietung nicht mehr <em>versteht</em>. Eine nächste Generation, trainiert auf Fragmenten, mit ausgelagerten Fähigkeiten, hat nicht die Tiefe, die Expertise der Generation davor zu würdigen, zu nutzen, zu hebeln. Die Weitergabe von Kompetenz (Meister zu Schüler, Senior zu Junior) bricht nicht, weil die Meister verschwanden, sondern weil die Lehre verschwand.</p>

<p><strong>4. Hyper-Individualismus.</strong></p>

<p><em>Mikro:</em> die Optimierung des Selbst als letztes verbliebenes Projekt; Identität über Beitrag, Wellness über Werk. Eine Knappheitsmentalität als Modus Operandi. Und verständlicherweise: In vieler Hinsicht ist das die einzig rationale Antwort auf den gegenwärtigen Zustand der Dinge.</p>

<p><em>Makro:</em> Im Aggregat wird daraus eine Politik der Verweigerung. Degrowth als moralische Position, NIMBY als Default, und die leisen Abgänge. Menschen stimmen mit den Füßen ab, Unternehmen haben jetzt eine bequeme, geradezu modische Ausrede für den Umzug in die USA, und die aktuelle US-Regierung rollt aktiv den roten Teppich aus. Menschen stimmen mit ihrem Geld ab: Europäische Ersparnisse finanzieren, mit beeindruckender Zuverlässigkeit, die Ausbauten aller anderen. Wer würde sein Geld auch in Europa anlegen wollen? NIMBY am Vormittag, US-Aktien am Nachmittag, wenn die US-Märkte öffnen, um wenigstens ein Stück vom Kuchen abzubekommen. Jede Einzelentscheidung ist vollkommen rational, in Summe aber shortet Europa sich selbst.</p>

<p>Und es gibt eine etwas degenerierte Kopplung: KI verstärkt die Reiter zwei und drei (sie ist die stärkste Droge der Aufmerksamkeitsökonomie und die Fähigkeits-Krücke par excellence), während sie das einzige realistische Gegenmittel gegen Reiter eins ist:</p>

<h2 class="no_toc" id="ki-gegen-die-demografische-klippe">KI gegen die demografische Klippe</h2>

<p>Hier ist Deutschlands Bevölkerungsstruktur, heute und projiziert:</p>

<div class="center">
  <img src="http://www.pokutta.com/blog/assets/zeroth-world-update/Germany_Population_Pyramid_2024_portrait.png" alt="Bevölkerungspyramide Deutschland 2024" style="width:32%; display:inline-block; vertical-align:top;" />
  <img src="http://www.pokutta.com/blog/assets/zeroth-world-update/Germany_2034_projection.png" alt="Bevölkerungsprojektion Deutschland 2034" style="width:32%; display:inline-block; vertical-align:top;" />
  <img src="http://www.pokutta.com/blog/assets/zeroth-world-update/Germany_2044_projection.png" alt="Bevölkerungsprojektion Deutschland 2044" style="width:32%; display:inline-block; vertical-align:top;" />
  <p style="clear: both;"></p>
</div>
<p class="figcap"><strong>Abbildung 2:</strong> Deutschlands Bevölkerungspyramide 2024 und Projektionen für 2034 und 2044. Der Boomer-Bauch wandert von „arbeitet und zahlt ein“ zu „in Rente und bezieht“, und von unten füllt nichts nach. Sehr optimistische Projektion mit stetiger (d. h. optimistischer) Fortschreibung.</p>

<p>Die Mathematik ist unerbittlich: Die deutsche Erwerbsbevölkerung schrumpft im nächsten Jahrzehnt um Millionen, während die Boomer in Rente gehen und die Zahl der Rentner und Pflegebedürftigen wächst. Output ist Erwerbstätige mal Output pro Erwerbstätigem. Fällt der erste Faktor strukturell, muss der zweite strukturell steigen, oder Wohlfahrtsstaat, Gesundheitswesen, Renten und am Ende die politische Stabilität gehen mit. Eine dritte Option gibt es nicht; Produktivität ist hier kein Nice-to-have, sie ist der Pfeiler, auf dem alles ruht. Der frühere Außenminister und Vizekanzler Joschka Fischer (ausgerechnet ein Grüner) <a href="https://www.welt.de/politik/deutschland/article6a1174f7be29d4b4607a46d4/rentendebatte-buhrufe-aendern-mathematik-nicht-joschka-fischer-fordert-grundlegende-reformen-im-sozialsystem.html">brachte es</a> in der Rentendebatte dieses Frühjahrs (Mai 2026) unverblümt auf den Punkt, nachdem Kanzler Merz auf dem Gewerkschaftskongress für Reformvorschläge ausgebuht worden war:</p>

<blockquote>
  <p>Buhrufe ändern die Mathematik nicht.</p>
</blockquote>

<p>Und genau hier geht der übliche Frame („KI ersetzt Arbeit, also ist das eine Kostengeschichte“) am Punkt vorbei. <em>Es geht nicht um Arbeitskosten; es geht um Reibung.</em> Eine schrumpfende Erwerbsbevölkerung macht Arbeit nicht primär teuer, sie macht sie <em>unverfügbar</em>: Stellen, die ein Jahr unbesetzt bleiben, Projekte ohne Besetzung, Pflege, die nicht geleistet wird, Genehmigungen, die nicht bearbeitet werden. Die ökonomische Magie der KI ist das Entfernen von Reibung, nicht nur von Kosten: kein Einstellungs-Lag, keine Knappheit bei der relevanten Fähigkeit, Skalierung auf Abruf, rund um die Uhr. Hybridisierung, die These von 2019, ist exakt der Mechanismus, über den die Renten der 70-Jährigen von 40-Jährigen bezahlt werden, die mit 3x operieren: Die KI übernimmt die Routine, der knappe Mensch den Rest. Japan hat das vor Jahren verstanden und Roboter (mit gemischtem Erfolg) in Pflegeheime gebracht, ohne Kulturkampf. China, dessen eigene demografische Klippe ein Jahrzehnt hinter unserer liegt, setzt explizit auf Roboter und KI im nationalen Maßstab. Die USA lösen es auf die alte Art, indem sie Menschen importieren und willkommen heißen(!!!), auch Europäer.</p>

<p>Das ist tatsächlich die bitterste Ironie dieser ganzen Geschichte: <strong>Der eine Block, der die nullte Welt am nötigsten hat, ist der, der sie am härtesten reguliert und bekämpft.</strong> Europa ist demografisch dazu verdammt, ein Produktivitätswunder zu brauchen, und kulturell darauf festgelegt, eines zu verhindern. Der 2019er-Beitrag fragte, ob KI eine nullte Welt schaffen <em>könnte</em>. Die Frage von 2026 ist nur noch, <em>wer darin lebt</em>, denn gebaut wird sie so oder so.</p>

<h2 class="no_toc" id="sieben-vorhersagen-für-die-nächsten-sieben-jahre">Sieben Vorhersagen für die nächsten sieben Jahre</h2>

<p>Der 2019er-Beitrag hat sich sein Update verdient, indem er Behauptungen aufstellte, die scheitern konnten. Gleiche Regeln noch einmal: sieben Vorhersagen für 2033.</p>

<ol>
  <li><strong>Kein europäisches Frontier-Labor.</strong> 2033 operiert kein Labor mit EU-Hauptsitz auch nur innerhalb einer Größenordnung der Trainingsrechenleistung an der Frontier. Mistral endet übernommen, in Sovereign-Cloud-Verträge konsolidiert oder exzellent-aber-Nische.</li>
  <li><strong>Feature-Verspätung ist keine Nachricht mehr.</strong> Dass Flaggschiff-KI-Produkte in der EU sechs bis vierundzwanzig Monate später, funktionsreduziert oder gar nicht erscheinen, wird Standardpraxis; mindestens ein prägendes Consumer-KI-Produkt der frühen 2030er erscheint schlicht nie im EWR, und niemand ist überrascht.</li>
  <li><strong>Die Lücke erreicht die Statistiken.</strong> Das US-Arbeitsproduktivitätswachstum übertrifft das des Euroraums im Schnitt um einen vollen Prozentpunkt oder mehr, und die transatlantische Pro-Kopf-BIP-Lücke ist 2033 größer als heute; die ersten eindeutigen Nullte-Welt-Signaturen zeigen sich um 2030 in US-Sektordaten (Software, professionelle Dienstleistungen, Teile des verwaltungslastigen Gesundheitswesens).</li>
  <li><strong>Europas KI-Sicherheitsschock.</strong> Vor 2033 wird ein großer europäischer Infrastruktur-Vorfall (ein Versorger, ein Klinikverbund, ein Behördensystem) auf eine Schwachstellenklasse zurückgeführt, die Organisationen der Glasswing-Liga auf ihren eigenen Stacks längst gefunden und behoben hatten. Die Antwort ist Notbeschaffung bei einem US-Labor: Souveränität per Rechnung.</li>
  <li><strong>China kassiert die Deployment-Dividende.</strong> China führt bei Roboterdichte und Lights-out-Fertigung mit komfortablem Abstand, sein Open-Weight-Stack wird die Default-KI-Infrastruktur des Globalen Südens, und es wird die erste große Volkswirtschaft, die eine schrumpfende Erwerbsbevölkerung sichtbar mit KI plus Robotik in den offiziellen Statistiken ausgleicht.</li>
  <li><strong>Deutschland adoptiert KI durch die Hintertür.</strong> Die Krise in Pflege, Verwaltung und Unternehmensnachfolge im Mittelstand erzwingt um 2029–2031 massenhafte KI-Adoption, auf importierten Stacks, schneller als jedes Digitalisierungsprogramm es je geschafft hat, und ohne dass ein einziges Strategiepapier wie geschrieben umgesetzt würde.</li>
  <li><strong>Gigafabrik-Theater.</strong> EU-KI-Gigafabriken werden eingeweiht, mit Reden und Bändern; bis 2033 hat keine von ihnen einen Trainingslauf im Frontier-Maßstab beherbergt, und die gesamte öffentliche KI-Rechenkapazität der EU bleibt kleiner als der jährliche <em>Zubau</em> eines einzelnen US-Hyperscalers.</li>
</ol>

<p>Wenn mindestens vier davon falsch liegen, hat Europa mich auf die bestmögliche Art überrascht, und niemand wird diese Bilanz lieber schreiben als ich.</p>

<h2 class="no_toc" id="einige-abschließende-gedanken">Einige abschließende Gedanken</h2>

<p>Ich beendete den 2019er-Beitrag mit dem Satz, dass wir, „um nachhaltigen Fortschritt zu ermöglichen, nicht nur aufmerksam sein, sondern den Einsatz dieser neuen Technologien vorbereiten und aktiv gestalten müssen“. Ich stehe zu dem Satz, mehr denn je, mit einem auf die harte Tour gelernten Zusatz: <em>Gestalten setzt voraus, am Tisch zu sitzen.</em></p>

<p>Die nullte Welt ist kein Gedankenexperiment mehr; die Lücke zwischen ihr und der Ersten Welt öffnet sich in Echtzeit, in echten Zahlen, an echten Orten, in echten Fähigkeiten, in Memphis und Abilene und Shanghai. Vor sieben Jahren fragte ich, wie diese Lücke aussehen würde. Die ernüchternde Antwort von 2026 ist, dass Deutschland (und Europa) sich entschieden hat, „Reallabor“ zu sein und es empirisch herauszufinden, in Echtzeit… von der anderen Seite.</p>]]></content><author><name>Sebastian Pokutta</name></author><category term="random" /><category term="ai" /><category term="ml" /><category term="economics" /><category term="europe" /><summary type="html"><![CDATA[TL;DR: Seven years ago I argued that AI could enable a zeroth world: economies operating at a multiple of first-world productivity, the way the first world operates at a multiple of the third. The update: the technology arrived faster than I expected, the productivity gains are real but unevenly distributed, and the zeroth world is being built right now, in the US and in China. Europe is perfectly on track to watch from the sidelines, which is particularly bitter because, demographically, Europe needs it more than anyone else. The newest twist: frontier cyber-defense capability is now allocated by invitation and Europe is mostly not on the list.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" /><media:content medium="image" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">The Hidden Cost of Tokenization</title><link href="http://www.pokutta.com/blog/hidden-cost-tokenization/" rel="alternate" type="text/html" title="The Hidden Cost of Tokenization" /><published>2026-05-14T00:00:00+02:00</published><updated>2026-05-14T00:00:00+02:00</updated><id>http://www.pokutta.com/blog/hidden-cost-tokenization</id><content type="html" xml:base="http://www.pokutta.com/blog/hidden-cost-tokenization/"><![CDATA[<p><em>TL;DR: This is a short summary of our position paper <a href="https://zenodo.org/records/18416605">The Hidden Cost of Tokenization: Why (most) Non-English Speakers Pay More for Less</a> by <a href="https://www.weizenbaum-institut.de/portrait/p/jennifer-haase/">Jennifer Haase</a> and <a href="https://www.pokutta.com/">Sebastian Pokutta</a>. The basic point is simple: tokenization is not a neutral preprocessing step. It determines how much users pay, how much context they get, how much compute is burned, and potentially how well a model can reason in a language. The same semantic content can require 1.3x, 5x, or even more than 10x as many tokens depending on the language-tokenizer pairing.</em></p>

<!--more-->

<h2 id="the-invisible-tax">The invisible tax</h2>

<p>Most users never see the tokenizer. They see an input box, a model name, maybe a price per million tokens, and then a response. Somewhere between the text and the model, however, the text is chopped into model-readable units. Those units are what commercial APIs count and charge for. They are also what determines how much of a document fits into a context window and how much work the transformer has to do.</p>

<p>This would be mostly harmless if tokenizers were language-neutral. They are not. A tokenizer trained mostly on English-like text learns English-like chunks: common words, common morphemes, common byte patterns, common whitespace structure. When this tokenizer sees a language with a different script, different morphology, or simply much less representation in the training corpus, the same meaning can fragment into many more tokens.</p>

<p>In the paper we make the following point:</p>

<div class="tok-callout">
<strong>Key point.</strong> Tokenizer design is a first-order concern for fair and efficient multilingual AI.
</div>

<p>This sounds like a technical detail until you remember that the entire business model of many LLM services is token-metered. If English needs 100 tokens and Arabic, Bengali, Burmese, Amharic, or Dzongkha need substantially more tokens for the same content, then non-English users are paying a hidden language tax. Not because their tasks are harder, but because the infrastructure has encoded a preference. However it is not only about cost but also about capability.</p>

<style>
.tok-callout{
  border-left:4px solid #0f766e;
  border-right:4px solid #0f766e;
  background:#f3faf8;
  padding:12px 16px;
  margin:1em 0;
}
.tok-widget{
  margin:22px 0;
  background:#f8f9fa;
  border:1px solid #e0e0e0;
  border-radius:8px;
  padding:16px;
}
.tok-widget-header{
  display:flex;
  justify-content:space-between;
  align-items:flex-start;
  gap:12px;
  margin-bottom:12px;
}
.tok-widget-title{
  font-weight:700;
}
.tok-widget-sub{
  font-size:12px;
  color:#6b7280;
  text-align:right;
}
.tok-controls{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(210px,1fr));
  gap:12px;
  margin-bottom:14px;
}
.tok-control label{
  display:block;
  font-size:12px;
  font-weight:600;
  color:#374151;
  margin-bottom:4px;
}
.tok-control select,
.tok-control input[type="range"]{
  width:100%;
}
.tok-kpis{
  display:grid;
  grid-template-columns:repeat(auto-fit,minmax(160px,1fr));
  gap:10px;
  margin:10px 0 14px 0;
}
.tok-kpi{
  background:#fff;
  border:1px solid #e5e7eb;
  border-radius:6px;
  padding:10px;
}
.tok-kpi-label{
  font-size:11px;
  color:#6b7280;
  margin-bottom:4px;
}
.tok-kpi-value{
  font-size:20px;
  font-weight:700;
  color:#111827;
}
.tok-kpi-value.small{
  font-size:17px;
}
.tok-pill{
  display:inline-block;
  border:1px solid #d1d5db;
  border-radius:999px;
  background:#fff;
  color:#374151;
  padding:3px 8px;
  font-size:11px;
  font-weight:700;
  white-space:nowrap;
}
.tok-note{
  font-size:12px;
  color:#555;
  margin-top:8px;
}
.tok-chip-line{
  display:flex;
  flex-wrap:wrap;
  gap:6px;
  align-items:center;
  min-height:36px;
}
.tok-chip{
  display:inline-block;
  background:#fff;
  border:1px solid #cbd5e1;
  border-radius:5px;
  padding:4px 7px;
  font-size:13px;
  line-height:1.2;
}
.tok-chip.bad{
  border-color:#fecaca;
  background:#fff7f7;
}
.tok-chip.good{
  border-color:#bbf7d0;
  background:#f0fdf4;
}
.tok-split-row{
  background:#fff;
  border:1px solid #e5e7eb;
  border-radius:6px;
  padding:10px;
  margin-bottom:10px;
}
.tok-split-label{
  display:flex;
  justify-content:space-between;
  gap:8px;
  font-size:12px;
  font-weight:700;
  margin-bottom:8px;
  color:#374151;
}
</style>

<h2 id="what-tokenization-actually-does">What tokenization actually does</h2>

<p>Modern LLMs do not process text as characters or words. They process integer IDs. A tokenizer maps a string to those IDs. Most common systems use variants of byte pair encoding (BPE), unigram tokenization, or related subword schemes. In a BPE-like tokenizer, frequent character sequences are merged into larger units. Very frequent chunks become single tokens; rare chunks remain fragmented.</p>

<p>This is a reasonable compression trick, but it has an uncomfortable consequence: <em>the tokenizer’s training distribution becomes part of the model’s access layer.</em> If the tokenizer sees English constantly, “tokenization” may be a single token or a small number of tokens. If it sees a morphologically rich or underrepresented language rarely, it may fall back to smaller pieces, sometimes even byte-like fragments.</p>

<p>The choice of this “fragmentation” impacts four things at the same time:</p>

<ol>
  <li><strong>Cost.</strong> API pricing is usually per input and output token.</li>
  <li><strong>Latency.</strong> More tokens mean more transformer steps over a longer sequence.</li>
  <li><strong>Effective context.</strong> A 128k-token window is not the same semantic window in every language.</li>
  <li><strong>Representational quality.</strong> Poor boundaries can cut across meaningful units, forcing the model to reconstruct meaning from pieces that were not designed to stand alone.</li>
</ol>

<p>The first three points are already enough to make tokenization a fairness issue. The fourth is more subtle, but at the same time maybe the most interesting one.</p>

<h2 id="same-meaning-different-budget">Same meaning, different budget</h2>

<p>To understand the impact, the (deliberately simple) widget allows to compare different scenarios. Pick a reported language-tokenizer situation and compare it with an English baseline. The multipliers are rounded examples from the paper and the literature we discuss in our paper <a href="https://doi.org/10.5281/zenodo.18416605">[HP26]</a>; they should be read as order-of-magnitude signals or indications, while the exact overhead heavily depends on scenarios, use and exact tokenizer. Identical context is assumed and was benchmarked/calibrated from multilingual corpora.</p>

<div id="tok-bill-widget" class="tok-widget">
  <div class="tok-widget-header">
    <div>
      <div class="tok-widget-title">Language tax at 100k tokens</div>
      <div style="font-size:12px;color:#555;">Take a task that is 100k tokens in English and compare the token budget under another language-tokenizer pairing.</div>
    </div>
    <div class="tok-widget-sub">Rounded multipliers<br />relative to English</div>
  </div>
  <div class="tok-controls">
    <div class="tok-control">
      <label for="tb-case">Language-tokenizer situation</label>
      <select id="tb-case"></select>
    </div>
  </div>
  <div class="tok-kpis">
    <div class="tok-kpi">
      <div class="tok-kpi-label">Multiplier</div>
      <div id="tb-mult" class="tok-kpi-value">1.0x</div>
    </div>
    <div class="tok-kpi">
      <div class="tok-kpi-label">Tokens for same content</div>
      <div id="tb-tokens" class="tok-kpi-value small">100,000</div>
    </div>
    <div class="tok-kpi">
      <div class="tok-kpi-label">Extra tokens</div>
      <div id="tb-extra" class="tok-kpi-value small">0</div>
    </div>
    <div class="tok-kpi">
      <div class="tok-kpi-label">100k context carries</div>
      <div id="tb-context" class="tok-kpi-value small">100,000</div>
    </div>
  </div>
  <svg id="tb-bars" viewBox="0 0 760 280" style="width:100%;height:auto;background:#fff;border:1px solid #e5e7eb;border-radius:6px;"></svg>
  <div id="tb-note" class="tok-note"></div>
</div>

<script>
(function(){
  const cases = [
    {name:'English under an English-optimized tokenizer', mult:1.0, note:'Baseline: one unit of semantic content is charged as one unit of tokens.'},
    {name:'Spanish/French under common GPT-style tokenizers', mult:1.3, note:'A mild but persistent premium already becomes visible at scale.'},
    {name:'German under an English-adjacent tokenizer', mult:1.5, note:'Compounding and inflection push many words into extra subword pieces.'},
    {name:'Chinese under a Chinese-aware tokenizer such as Qwen', mult:1.0, note:'Targeted tokenizer design can bring a major non-English language close to parity.'},
    {name:'Chinese under an English-adjacent tokenizer', mult:3.0, note:'The same language can move from near-parity to a large premium depending on tokenizer design.'},
    {name:'Korean under English-optimized tokenizers', mult:2.6, note:'Korean is a typical example where language-specific tokenization matters.'},
    {name:'Telugu or Georgian in reported commercial-tokenizer studies', mult:5.0, note:'At this level a nominal 128k context behaves more like 25.6k English-equivalent tokens.'},
    {name:'Bengali in healthcare-tokenization examples', mult:6.0, note:'The penalty can become material for latency-sensitive or high-volume deployments.'},
    {name:'Myanmar-script examples', mult:7.0, note:'Script effects and underrepresentation can combine into severe token inflation.'},
    {name:'Burmese or Amharic in reported tokenizer studies', mult:10.0, note:'A tenfold multiplier means a 100k-token budget carries only 10k English-equivalent content.'},
    {name:'Dzongkha or Santali in double-jeopardy studies', mult:14.0, note:'This is the regime where the language tax becomes almost prohibitive.'},
    {name:'Shan in tokenizer-parity studies', mult:15.0, note:'Some reported premiums reach about fifteen times the English baseline.'}
  ];

  const sel = document.getElementById('tb-case');
  const mult = document.getElementById('tb-mult');
  const tokens = document.getElementById('tb-tokens');
  const extra = document.getElementById('tb-extra');
  const context = document.getElementById('tb-context');
  const note = document.getElementById('tb-note');
  const svg = document.getElementById('tb-bars');
  const comma = new Intl.NumberFormat('en-US');
  const baseTokens = 100000;

  cases.forEach((c, i) => {
    const opt = document.createElement('option');
    opt.value = i;
    opt.textContent = c.name;
    sel.appendChild(opt);
  });
  sel.value = 4;

  function severity(multiplier) {
    if (multiplier < 1.5) return {label:'near parity', color:'#0f766e', bg:'#ecfdf5'};
    if (multiplier < 3) return {label:'mild tax', color:'#2563eb', bg:'#eff6ff'};
    if (multiplier < 6) return {label:'large tax', color:'#d97706', bg:'#fffbeb'};
    return {label:'severe tax', color:'#dc2626', bg:'#fef2f2'};
  }

  function draw(c, inflatedTokens, effectiveTokens) {
    const W = 760, H = 280;
    const left = 178, right = 34;
    const maxTokens = Math.max(baseTokens, inflatedTokens) * 1.12;
    const scale = v => left + (v / maxTokens) * (W - left - right);
    const sev = severity(c.mult);
    const plotW = W - left - right;
    const contextFill = Math.max(2, Math.min(1, effectiveTokens / baseTokens) * plotW);
    const needWidth = Math.max(2, scale(inflatedTokens) - left);
    const baseWidth = Math.max(2, scale(baseTokens) - left);
    let html = '';
    html += '<text x="18" y="26" font-size="13" font-weight="700" fill="#111">Same content: token budget required</text>';
    html += `<rect x="632" y="10" rx="11" ry="11" width="104" height="22" fill="${sev.bg}" stroke="${sev.color}" stroke-width="1"/>`;
    html += `<text x="684" y="25" font-size="11" text-anchor="middle" fill="${sev.color}" font-weight="700">${sev.label}</text>`;

    html += `<text x="${left - 12}" y="69" font-size="12" text-anchor="end" fill="#111">English</text>`;
    html += `<rect x="${left}" y="50" width="${plotW}" height="28" fill="#f3f4f6"/>`;
    html += `<rect x="${left}" y="50" width="${baseWidth}" height="28" fill="#0f766e" opacity="0.86"/>`;
    html += `<text x="${W-right-6}" y="69" font-size="12" text-anchor="end" fill="#111">${comma.format(baseTokens)} tokens</text>`;

    html += `<text x="${left - 12}" y="117" font-size="12" text-anchor="end" fill="#111">Selected case</text>`;
    html += `<rect x="${left}" y="98" width="${plotW}" height="28" fill="#f3f4f6"/>`;
    html += `<rect x="${left}" y="98" width="${needWidth}" height="28" fill="#ef4444" opacity="0.84"/>`;
    html += `<text x="${W-right-6}" y="117" font-size="12" text-anchor="end" fill="#111">${comma.format(Math.round(inflatedTokens))} tokens</text>`;

    html += '<text x="18" y="170" font-size="13" font-weight="700" fill="#111">Fixed 100k context: semantic content that fits</text>';
    html += `<text x="${left - 12}" y="214" font-size="12" text-anchor="end" fill="#111">Usable content</text>`;
    html += `<rect x="${left}" y="195" width="${plotW}" height="28" fill="#fee2e2"/>`;
    html += `<rect x="${left}" y="195" width="${contextFill}" height="28" fill="#0f766e" opacity="0.86"/>`;
    html += `<line x1="${left + plotW}" y1="190" x2="${left + plotW}" y2="228" stroke="#111" stroke-width="1.2"/>`;
    html += `<text x="${left + plotW}" y="243" font-size="10" text-anchor="middle" fill="#555">100k token limit</text>`;
    html += `<text x="${W-right-6}" y="214" font-size="12" text-anchor="end" fill="#111">${comma.format(Math.round(effectiveTokens))} English-equivalent tokens</text>`;

    html += `<text x="18" y="266" font-size="11" fill="#555">${c.note}</text>`;
    svg.innerHTML = html;
  }

  function update() {
    const c = cases[parseInt(sel.value, 10)];
    const inflatedTokens = baseTokens * c.mult;
    const effectiveTokens = baseTokens / c.mult;
    mult.textContent = c.mult.toFixed(c.mult % 1 === 0 ? 0 : 1) + 'x';
    tokens.textContent = comma.format(Math.round(inflatedTokens));
    extra.textContent = comma.format(Math.round(inflatedTokens - baseTokens));
    context.textContent = comma.format(Math.round(effectiveTokens));
    note.innerHTML = '<span class="tok-pill">' + Math.round(100 / c.mult) + '% effective context</span> Interpretation: a 100k-token context window carries about ' + comma.format(Math.round(effectiveTokens)) + ' English-equivalent tokens for this multiplier.';
    draw(c, inflatedTokens, effectiveTokens);
  }

  sel.addEventListener('change', update);
  update();
})();
</script>

<p>What this reveals is that while many models have “multilingual support”, without without qualification it does not tell us how “well” a target language is supported. A model may technically accept a language and still its output might be subpar. If a language needs five times as many tokens, it receives one fifth of the effective context window, costs five times as much to serve, and uses roughly five times as much token-side inference work for the same amount of content. Support is not the same as parity.</p>

<h2 id="not-just-a-billing-problem">Not just a billing problem</h2>

<p>The cost issue is easy to understand and therefore easy to trivialize: yes, some users pay more, but perhaps this is just how compression works? There is some truth in that. Languages are different. Scripts differ. Morphology differs. Some languages are more compact in characters, some less. A fixed vocabulary is a scarce resource. A tokenizer cannot allocate the same vocabulary slots to English, German compounds, Chinese characters, Arabic morphology, Indic scripts, and every low-resource language simultaneously. But precisely because it is a limited resource, design choice matters.</p>

<p>In our paper we compare three tokenizer families: OpenAI’s GPT o200k tokenizer, Alibaba’s Qwen tokenizer, and EuroLLM’s tokenizer <a href="https://doi.org/10.5281/zenodo.18416605">[HP26]</a>. The patterns are quite revealing: The English-adjacent tokenizer is excellent for English and much worse for many other languages. Qwen shows that targeted optimization can make Chinese highly efficient while remaining competitive for English. EuroLLM is a cautionary case: broad multilingual ambition does not automatically imply efficient multilingual representation; it basically underperforms in all its languages simultaneously when it comes to tokenization efficiency.</p>

<p>I would like to stress that this is not about one tokenizer being morally good and the other one being morally bad. Rather the point is that tokenization outcomes are <em>design outcomes</em>. Chinese under a Chinese-aware tokenizer and Chinese under an English-adjacent tokenizer are not the same experience. That means the disparity is not a law of nature. It is a result of vocabulary allocation, data mixture, encoding choices, and what the system was optimized to do.</p>

<h2 id="fragmentation-as-cognitive-friction">Fragmentation as cognitive friction</h2>

<p>So far we have only looked at the question of costs and efficiency. However there is a second component that we suspect being even more important although currently still a bit of speculative part of the paper. We call this <em>cognitive friction</em>. This is not meant as a mystical claim that LLMs think like humans. It is an analogy: if a representation cuts through the meaningful units of a language, the model has to reconstruct meaning through a worse interface, which impairs performance.</p>

<div class="callout">
From a Sapir-Whorfian perspective, tokenization that fragments non-English languages through English-centric segmentation is not merely inefficient, it is a form of <strong>linguistic imperialism</strong> encoded in infrastructure.
</div>

<style>
.callout{border-left:4px solid #2563eb;border-right:4px solid #2563eb;background:#f5f7ff;padding:12px 16px;margin:1em 0}
</style>

<p>For English, a tokenizer may learn convenient chunks such as “reasoning”, “tokenization”, “pre”, “-ing”, or common whitespace-prefixed words. For Turkish, Finnish, Arabic, Ukrainian, or many Indic languages, meaningful morphology can be distributed differently. For Chinese and Japanese, word boundaries do not behave like whitespace-separated English words. For byte-level fallback behavior, non-Latin scripts can be represented through byte fragments that are very far from the linguistic units a speaker would recognize.</p>

<p><strong>Interlude.</strong> Coincidentally, after we wrote our paper, Anthropic changed the tokenizer for Claude Opus 4.7 compared to 4.6; <a href="https://www.anthropic.com/news/claude-opus-4-7#migrating-from-opus-46-to-opus-47">[Anthropic’s Claude Opus 4.7 announcement]</a>, <a href="https://simonwillison.net/2026/apr/20/claude-token-counts/">[efficiency comparison]</a>. It became much less efficient, same input requires roughly 1.3x amount of tokens, but was meant to improve instruction following. Such a move is somewhat unusual as it “breaks” compatibility across model stacks etc. Now, the opinion on Opus 4.7 are somehwat mixed with many reporting it being a regression from 4.6. This may or may not be related to the tokenizer change but is certainly a thought to entertain.</p>

<p>The widget below schematicatically demonstrates this; note this is <em>not</em> an actual tokenizer emulator. It is meant to make the representational issue visible: the same string can be broken into fragments that either align reasonably with semantic units or cut across them awkwardly.</p>

<div id="tok-split-widget" class="tok-widget">
  <div class="tok-widget-header">
    <div>
      <div class="tok-widget-title">Tokenizer anatomy lab</div>
      <div style="font-size:12px;color:#555;">A schematic view of aligned vs. fragmented token boundaries.</div>
    </div>
    <div class="tok-widget-sub">Illustrative splits<br />not exact model output</div>
  </div>
  <div class="tok-controls">
    <div class="tok-control">
      <label for="ts-example">Example string</label>
      <select id="ts-example"></select>
    </div>
  </div>
  <div class="tok-split-row">
    <div class="tok-split-label"><span>Original</span><span id="ts-script"></span></div>
    <div id="ts-original" style="font-size:18px;line-height:1.4;"></div>
  </div>
  <div class="tok-split-row">
    <div class="tok-split-label"><span>Fragmented split</span><span id="ts-bad-count"></span></div>
    <div id="ts-bad" class="tok-chip-line"></div>
  </div>
  <div class="tok-split-row">
    <div class="tok-split-label"><span>More aligned split</span><span id="ts-good-count"></span></div>
    <div id="ts-good" class="tok-chip-line"></div>
  </div>
  <svg id="ts-meter" viewBox="0 0 760 130" style="width:100%;height:auto;background:#fff;border:1px solid #e5e7eb;border-radius:6px;"></svg>
  <div id="ts-note" class="tok-note"></div>
</div>

<script>
(function(){
  const examples = [
    {
      name:'English: tokenization',
      script:'Latin',
      original:'Tokenization is not a neutral detail.',
      bad:['Token', 'ization', ' is', ' not', ' a', ' neutral', ' detail', '.'],
      good:['Tokenization', ' is', ' not', ' a', ' neutral', ' detail', '.'],
      note:'Even in English there are many possible segmentations, but high-resource patterns are usually well covered.'
    },
    {
      name:'German: compounds and inflection',
      script:'Latin, compounding',
      original:'Tokenisierung ist kein neutrales Detail.',
      bad:['Token', 'is', 'ierung', ' ist', ' kein', ' neutral', 'es', ' Detail', '.'],
      good:['Tokenisierung', ' ist', ' kein', ' neutrales', ' Detail', '.'],
      note:'German compounds and inflected forms can be split into pieces that are not the natural semantic units.'
    },
    {
      name:'Turkish: agglutination',
      script:'Latin, agglutinative',
      original:'Evlerimizden geliyorsunuz.',
      bad:['Ev', 'ler', 'im', 'iz', 'den', ' gel', 'iyor', 'sun', 'uz', '.'],
      good:['Evlerimizden', ' geliyorsunuz', '.'],
      note:'Agglutinative morphology packs a lot into a single word; arbitrary fragmentation can create extra reconstruction work.'
    },
    {
      name:'Chinese: no whitespace word boundary',
      script:'Han',
      original:'分词不是中性的。',
      bad:['分', '词', '不', '是', '中', '性', '的', '。'],
      good:['分词', '不是', '中性的', '。'],
      note:'A whitespace-oriented intuition is a poor fit for languages where word boundaries are not written as spaces.'
    },
    {
      name:'Arabic: non-Latin script and morphology',
      script:'Arabic',
      original:'الترميز ليس تفصيلا محايدا.',
      bad:['ا', 'ل', 'تر', 'ميز', ' ليس', ' ت', 'فص', 'يلا', ' م', 'حا', 'يدا', '.'],
      good:['الترميز', ' ليس', ' تفصيلا', ' محايدا', '.'],
      note:'For non-Latin scripts, byte-level or poorly allocated vocabularies can move the model away from linguistically meaningful chunks.'
    }
  ];

  const sel = document.getElementById('ts-example');
  const original = document.getElementById('ts-original');
  const script = document.getElementById('ts-script');
  const bad = document.getElementById('ts-bad');
  const good = document.getElementById('ts-good');
  const badCount = document.getElementById('ts-bad-count');
  const goodCount = document.getElementById('ts-good-count');
  const meter = document.getElementById('ts-meter');
  const note = document.getElementById('ts-note');

  examples.forEach((ex, i) => {
    const opt = document.createElement('option');
    opt.value = i;
    opt.textContent = ex.name;
    sel.appendChild(opt);
  });
  sel.value = 3;

  function chipHtml(parts, klass) {
    return parts.map(p => `<span class="tok-chip ${klass}">${p.replace(/&/g,'&amp;').replace(/</g,'&lt;')}</span>`).join('');
  }

  function drawMeter(ex) {
    const W = 760, H = 130;
    const left = 180, right = 40, barH = 22;
    const max = Math.max(ex.bad.length, ex.good.length) * 1.15;
    const scale = v => left + (v / max) * (W - left - right);
    const ratio = ex.bad.length / ex.good.length;
    let html = '';
    html += '<text x="16" y="24" font-size="13" font-weight="700" fill="#111">Fragmentation ratio</text>';
    [
      {label:'Fragmented', value:ex.bad.length, color:'#ef4444', y:42},
      {label:'Aligned', value:ex.good.length, color:'#0f766e', y:78}
    ].forEach(r => {
      html += `<text x="${left - 12}" y="${r.y + 16}" font-size="12" text-anchor="end" fill="#111">${r.label}</text>`;
      html += `<rect x="${left}" y="${r.y}" width="${W-left-right}" height="${barH}" fill="#f3f4f6"/>`;
      html += `<rect x="${left}" y="${r.y}" width="${Math.max(2, scale(r.value)-left)}" height="${barH}" fill="${r.color}" opacity="0.84"/>`;
      html += `<text x="${scale(r.value)+8}" y="${r.y + 16}" font-size="12" fill="#111">${r.value} pieces</text>`;
    });
    html += `<text x="16" y="118" font-size="11" fill="#555">Here the fragmented split uses ${ratio.toFixed(2)}x as many pieces as the aligned split.</text>`;
    meter.innerHTML = html;
  }

  function update() {
    const ex = examples[parseInt(sel.value, 10)];
    original.textContent = ex.original;
    script.textContent = ex.script;
    bad.innerHTML = chipHtml(ex.bad, 'bad');
    good.innerHTML = chipHtml(ex.good, 'good');
    badCount.textContent = ex.bad.length + ' pieces';
    goodCount.textContent = ex.good.length + ' pieces';
    note.textContent = ex.note + ' This is a visualization of the mechanism, not a claim about one exact production tokenizer.';
    drawMeter(ex);
  }

  sel.addEventListener('change', update);
  update();
})();
</script>

<p>Why does this matter for reasoning? One very mundane reason is sequence length. Longer sequences are harder and more expensive to process, attention needs to span more tokens, and long-context models are not uniformly reliable across positions; the “lost in the middle” phenomenon is one example <a href="https://doi.org/10.1162/tacl_a_00638">[LLHPBPL24]</a>. But there is also a representational reason: if the model consistently sees a language through awkward subword fragments, then the basic units of prediction and attention are misaligned with the units that carry meaning.</p>

<p>There is already quite a bit of evidence in this direction. Prior work documents cost disparities across languages <a href="https://aclanthology.org/2023.emnlp-main.614/">[AKGKMT23]</a>, tokenizer parity failures <a href="https://proceedings.neurips.cc/paper_files/paper/2023/hash/74bb24dca8334adce292883b4b651eda-Abstract-Conference.html">[BLPT23]</a>, performance differences from tokenizer choice alone <a href="https://aclanthology.org/2024.findings-naacl.247/">[AFTRL24]</a>, and even arithmetic failures caused by number-tokenization choices <a href="https://arxiv.org/abs/2402.14903">[SS24]</a>. To be clear we do not claim that tokenization is the only thing that matters, however these observations fit nicely into one argument: tokenization sits early enough in the stack that its consequences compound.</p>

<h2 id="the-double-jeopardy-pattern">The double-jeopardy pattern</h2>

<p>A poorly served language does not merely cost more. It can also receive less utility for the cost: this is known as <em>double jeopardy</em> <a href="https://arxiv.org/abs/2410.10665">[SVKD24]</a>.</p>

<p>Suppose an English user and a Bengali user both have access to an 8,000-token context window. If the Bengali text needs roughly six times as many tokens for comparable content under a given tokenizer, then the Bengali user has about one sixth of the usable semantic budget. Fewer examples fit. Less document context fits. Longer reasoning traces hit the limit sooner. If latency matters, the Bengali user also waits longer. If the provider pays for compute, the provider has an incentive to serve that user less aggressively or charge more.</p>

<p>This is where the fairness issue becomes embedeed into infrastructure: not a single subpar output, but rather a quiet degradation of service quality mediated through pricing, context length, latency, and model internals.</p>

<h2 id="the-obvious-counterarguments">The obvious counterarguments</h2>

<p>There are two reasonable objections.</p>

<p>First, languages really are different. A sentence is not a unit of equal information across languages, and a word is even worse. Some translations are longer than others. Some scripts encode differently in Unicode. Some languages have rich morphology. So a perfect one-tokenization-fits-all parity metric is too naive.</p>

<p>I agree. But that is an argument for measuring carefully, not for ignoring the gap. Parallel corpora are not perfect, but they are good enough to reveal large disparities. A 10x or 15x premium is not explained away by translation style.</p>

<p>Second, tokenization is compression under a fixed vocabulary budget. If you give more vocabulary to one language, you take it away from another. Again, true. But the relevant question is not whether tradeoffs exist. The question is whether today’s tradeoffs are defensible, transparent, and aligned with the users who bear their costs or receive subpar model performance.</p>

<p>There are already promising directions: parity-aware BPE <a href="https://arxiv.org/abs/2508.04796">[FMPNABS25]</a>, adaptive tokenization <a href="https://proceedings.neurips.cc/paper_files/paper/2024/hash/cdf00c97c0cb2cc35179f03363da6c4f-Abstract-Conference.html">[CGWXZZZ24]</a>, language-specific tokenizers, tokenizer replacement or extension, and language-specific foundation models. None of these is free. All of them force us to be explicit about the allocation problem.</p>

<h2 id="what-should-change">What should change</h2>

<p>At minimum, model providers should report tokenizer efficiency, not just benchmark scores. A model card that says “supports 100+ languages” should also tell us the token multiplier by language, by domain, and preferably by script and dialectal variation. This is simple benchmarking across parallel corpora. Otherwise “support” hides a large cost-quality gradient.</p>

<p>For research papers, I would like to see “tokenizer fertility” and effective-context ratios become standard diagnostics for multilingual experiments. Accuracy without token count is incomplete. If two models get the same score, but one needs four times as many tokens in Arabic, they are not equivalent systems from a user perspective.</p>

<p>For deployments and use, the practical advice is simple:</p>

<ol>
  <li>Audit real token counts before launching a multilingual product.</li>
  <li>Compare providers by language, not only by headline model quality.</li>
  <li>Treat high-volume non-English use cases as tokenizer-sensitive infrastructure decisions.</li>
  <li>Budget by <em>task</em> and <em>language</em>, not just by global average tokens.</li>
  <li>Consider language-specific or language-adaptive models when the multiplier is large.</li>
</ol>

<p>For the community more broadly: stop treating the tokenizer as an implementation footnote. It is part of the model’s interface to language, and therefore part of the product, the economics, and the fairness story.</p>

<p>And the last, most obvious, and most powerful one for the user: <strong>use llms only in english (or chinese)</strong>. This provides the most bang for the buck.</p>

<h2 id="so-where-do-we-go-from-here">So where do we go from here</h2>

<p>The optimistic reading is that this problem is fixable. The Qwen example shows that targeted design can substantially improve efficiency for a major non-English language. Work on parity-aware and adaptive tokenization suggests that we are not at a theoretical wall <a href="https://arxiv.org/abs/2508.04796">[FMPNABS25]</a>, <a href="https://proceedings.neurips.cc/paper_files/paper/2024/hash/cdf00c97c0cb2cc35179f03363da6c4f-Abstract-Conference.html">[CGWXZZZ24]</a>. Better reporting alone would already change incentives, because the language tax would become visible.</p>

<p>The pessimistic reading is that visibility is exactly what the current ecosystem lacks. Users do not choose tokenizers. They choose models and providers. The tokenizer is bundled into the system, and the bill arrives in tokens. That makes this sublety easy to miss.</p>

<h2 id="references">References</h2>

<p>[HP26] Haase, J. &amp; Pokutta, S. (2026). <em>The Hidden Cost of Tokenization: Why (most) Non-English Speakers Pay More for Less</em>. Zenodo preprint. <a href="https://doi.org/10.5281/zenodo.18416605">doi</a></p>

<p>[AKGKMT23] Ahia, O., Kumar, S., Gonen, H., Kasai, J., Mortensen, D.R., Smith, N.A., &amp; Tsvetkov, Y. (2023). Do All Languages Cost the Same? Tokenization in the Era of Commercial Language Models. <em>EMNLP 2023</em>. <a href="https://aclanthology.org/2023.emnlp-main.614/">paper</a></p>

<p>[AFTRL24] Ali, M., Fromm, M., Thellmann, K., Rutmann, R., Lübbering, M., Leveling, J., Klug, K., Ebert, J., Doll, N., Schulze Buschhoff, J., et al. (2024). Tokenizer Choice For LLM Training: Negligible or Crucial? <em>Findings of NAACL 2024</em>. <a href="https://aclanthology.org/2024.findings-naacl.247/">paper</a></p>

<p>[FMPNABS25] Foroutan, N., Meister, C., Paul, D., Niklaus, J., Ahmadi, S., Bosselut, A., &amp; Sennrich, R. (2025). Parity-Aware Byte-Pair Encoding: Improving Cross-lingual Fairness in Tokenization. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/2508.04796">arxiv</a></p>

<p>[LLHPBPL24] Liu, N.F., Lin, K., Hewitt, J., Paranjape, A., Bevilacqua, M., Petroni, F., &amp; Liang, P. (2024). Lost in the Middle: How Language Models Use Long Contexts. <em>Transactions of the Association for Computational Linguistics</em>, 12, 157–173. <a href="https://doi.org/10.1162/tacl_a_00638">doi</a></p>

<p>[BLPT23] Bibi, A., La Malfa, E., Petrov, A., &amp; Torr, P. (2023). Language Model Tokenizers Introduce Unfairness Between Languages. <em>NeurIPS 2023</em>. <a href="https://proceedings.neurips.cc/paper_files/paper/2023/hash/74bb24dca8334adce292883b4b651eda-Abstract-Conference.html">paper</a></p>

<p>[SS24] Singh, A.K. &amp; Strouse, D.J. (2024). Tokenization Counts: The Impact of Tokenization on Arithmetic in Frontier LLMs. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/2402.14903">arxiv</a></p>

<p>[SVKD24] Solatorio, A.V., Vicente, G.S., Krambeck, H., &amp; Dupriez, O. (2024). Double Jeopardy and Climate Impact in the Use of Large Language Models: Socio-economic Disparities and Reduced Utility for Non-English Speakers. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/2410.10665">arxiv</a></p>

<p>[CGWXZZZ24] Chen, H., Guo, T., Wang, Y., Xu, C., Zheng, B., Zheng, M., &amp; Zhu, C. (2024). Enhancing Large Language Models through Adaptive Tokenizers. <em>NeurIPS 2024</em>. <a href="https://proceedings.neurips.cc/paper_files/paper/2024/hash/cdf00c97c0cb2cc35179f03363da6c4f-Abstract-Conference.html">paper</a></p>]]></content><author><name>Sebastian Pokutta</name></author><category term="research" /><category term="ai" /><category term="tokenization" /><category term="llms" /><category term="multilinguality" /><category term="fairness" /><summary type="html"><![CDATA[TL;DR: This is a short summary of our position paper The Hidden Cost of Tokenization: Why (most) Non-English Speakers Pay More for Less by Jennifer Haase and Sebastian Pokutta. The basic point is simple: tokenization is not a neutral preprocessing step. It determines how much users pay, how much context they get, how much compute is burned, and potentially how well a model can reason in a language. The same semantic content can require 1.3x, 5x, or even more than 10x as many tokens depending on the language-tokenizer pairing.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" /><media:content medium="image" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Not every discovery needs an LLM</title><link href="http://www.pokutta.com/blog/not-every-discovery-needs-an-llm/" rel="alternate" type="text/html" title="Not every discovery needs an LLM" /><published>2026-04-23T00:00:00+02:00</published><updated>2026-04-23T00:00:00+02:00</updated><id>http://www.pokutta.com/blog/not-every-discovery-needs-an-llm</id><content type="html" xml:base="http://www.pokutta.com/blog/not-every-discovery-needs-an-llm/"><![CDATA[<p><em>TL;DR: AI-driven scientific discovery with systems such as AlphaTensor, AlphaEvolve, etc is en vogue and we are also heavily invested in that space. However, these LLM- and RL-driven approaches, while impressive often in themselves, are not always the right tool to get the job done. In this post I will talk about three recent projects from our group that take different angles on LLM- and RL-driven mathematical discovery systems. Two of them revisit classical problems made famous through these AI systems and show that classical structured search matches or beats them on these specific problem classes; with a tiny fraction of the compute. The third example goes the other way around: AI not as discovery engine, but an AI-accelerated subroutine sits inside a classical structured search and lets us settle a thirty-year-old conjecture on real algebraic plane curves of degree seven. This points to an interesting shift in the recent AI vs. classical discussion: it is not so much about whether or not to use AI, but where in the stack AI belongs.</em></p>

<!--more-->

<h2 id="not-a-takedown">Not a takedown</h2>

<p>When <a href="https://www.nature.com/articles/s41586-022-05172-4">AlphaTensor</a> [AT] landed in 2022 and <a href="https://arxiv.org/abs/2506.13131">AlphaEvolve</a> [AE] in 2025, several of my colleagues in the optimization community quietly asked themselves the same uncomfortable question: <em>are we obsolete now?</em> AlphaTensor found better tensor decompositions for matrix multiplication, a problem that had been a textbook example of algebraic complexity for more than fifty years. AlphaEvolve, later, produced new best-known solutions for circle packing, hexagon packing, and minimum-distance configurations, also problems that go back to Bateman and Erdős in 1951. In both cases, a DeepMind-scale AI system took a classical problem, applied a lot of compute, and came out with a new record; making headlines in the process.</p>

<p>Now, the <a href="https://www.zib.de/">Zuse Institute Berlin (ZIB)</a> is a research institute with a significant focus on AI, optimization, model-based simulation, etc. and it is our goal to push that even further. Also, my <a href="https://iol.zib.de/">group</a> and I have spent a considerable amount of time working at the intersection of optimization and machine learning, so that the AI-person in me celebrates these successes while the optimization-person in me is maybe a little bit more reserved. 
These systems are genuinely impressive, and the broader agenda of using strong learned models to help propose, search, and evaluate mathematical constructions, is something I strongly believe in but at the same time it seems to me that it is crucial where we apply AI in the stack:</p>

<div class="callout">
<strong>Thesis.</strong> There is now a sweet spot to be found that places AI alongside classical approaches and human reasoning. The key is to assign each component to the right position in the stack.
</div>

<style>
.callout{border-left:4px solid #2563eb;border-right:4px solid #2563eb;background:#f5f7ff;padding:12px 16px;margin:1em 0}
</style>

<p>For example, in some cases the right position for AI in the stack can be the formulation of the optimization problem, that is then solved with a classical optimization solver, rather than solving the actual problem itself. Similarly, sometimes the right position in the stack can be the design of an improved subroutine in a search that everything hinges on, rather than forcing the actual search through the AI system.</p>

<p><strong>Full Disclosure.</strong> I am a co-author on all three of the projects I am about to discuss: the flip-graph paper on structured matrix multiplication <a href="https://arxiv.org/abs/2511.10786">[KGP26]</a> which was just accepted for <a href="https://www.issac-conference.org/2026/">ISSAC 2026</a>, the global-optimization paper on AlphaEvolve’s benchmark problems <a href="https://arxiv.org/abs/2601.05943">[BKMPP26]</a>, and the two companion papers on patchworked real plane curves of degree seven <a href="https://arxiv.org/abs/2602.06888">[GJKMPSWZ26a]</a>, <a href="https://arxiv.org/abs/2604.09221">[GJKMPSWZ26b]</a>. So read this post with that in mind: I have skin in the game, just not always sure which side I’m on.</p>

<h2 id="two-modes-of-search-three-placements-for-ai">Two modes of search, three placements for AI</h2>

<p>Both AI-driven discovery and classical optimization are, at the end of the day, <em>search over a large space</em>. The difference is what each method is able to exploit, which often is a function of how structured the space is.</p>

<p>AlphaTensor searches the space of candidate low-rank tensor decompositions using deep reinforcement learning. AlphaEvolve searches the space of programs by having an LLM propose code edits that an evaluator then scores in an evolutionary loop. <a href="https://www.nature.com/articles/s41586-023-06924-6">FunSearch</a> [FS], <a href="https://www.nature.com/articles/s41586-023-06004-9">AlphaDev</a> [AD], and <a href="https://www.nature.com/articles/s41586-023-06747-5">AlphaGeometry</a> [AG] operate along related axes. The common structure is: a strong learned model generates candidates, an external evaluator or environment checks them, and the loop is long enough for compute to discover behavior that was not explicitly programmed in.</p>

<p>Classical structured search looks different. It does not treat the search space as a black box. It uses decades, sometimes centuries, of theoretical development to constrain where to look: in the flip-graph setting, by only visiting <em>provably correct</em> tensor decompositions and only moving between them via <em>rank-preserving or rank-reducing rewrites</em>; in the global-optimization setting, by writing the problem as a nonlinear program and handing it to a spatial branch-and-bound solver that prunes entire regions using mathematical bounds. The same bitter-lesson machinery that <em>helps</em> RL and LLMs on unstructured problems becomes <em>overhead</em> when the problem’s structure is already available in closed form.</p>

<p>Once you think of it this way, the question is not really “AI or classical?” but <em>where does AI sit in the stack?</em> The answer highly depends on the problem and the three case studies below make that point by providing three different answers to that question:</p>

<ol>
  <li><strong>AI as the search engine, no human structure injected.</strong> The AlphaTensor / AlphaEvolve default, which our first two cases revisit and find wanting on structured problems.</li>
  <li><strong>Classical structured search, no AI at all.</strong> What flip-graph random walks and off-the-shelf NLP solvers actually look like, and what makes them hard to beat on these problem classes (Case 1, Case 2).</li>
  <li><strong>AI inside a classical structured search, providing a fast learned subroutine.</strong> How we settled a thirty-year-old conjecture on degree-seven plane curves (Case 3).</li>
</ol>

<h2 id="case-1-matrix-multiplication-schemes-via-flip-graphs">Case 1: matrix multiplication schemes via flip graphs</h2>

<p>The first paper is <em><a href="https://arxiv.org/abs/2511.10786">Faster Algorithms for Structured Matrix Multiplication via Flip Graph Search</a></em> <a href="https://arxiv.org/abs/2511.10786">[KGP26]</a> by Kirill Khoruzhii, Patrick Gelß, and me, to appear at ISSAC 2026.</p>

<p><strong>Background.</strong> Since Strassen showed in 1969 that the naive $O(n^3)$ algorithm for matrix multiplication is suboptimal, researchers have chased two different goals. One is the asymptotic exponent $\omega$, currently pushed below $2.372$ via laser-method refinements; the other is the <em>constant-factor</em> story for <em>small</em> base sizes, where an improved low-rank decomposition recursed on itself yields faster practical algorithms. AlphaTensor aimed for this second goal, for <em>general</em> (unstructured) matrix multiplication. But much of what numerical libraries actually do is not general matmul. It is <a href="https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms">Level-3 BLAS</a> primitives with specific structure. For example, SYRK computes $AA^T$ and TRMM multiplies a triangular by a general matrix. These show up everywhere, from Gram matrices in statistics to Newton-Schulz updates in modern LLM training to causal-attention masks.</p>

<p><strong>The flip graph idea.</strong> The search space is the set of correct decompositions of a target tensor. Its nodes are rank-$r$ decompositions that <em>really do compute</em> the target bilinear operation; its edges are local rewrites, “flips”,  that take one correct decomposition to another, potentially decreasing $r$. Because edges preserve correctness by construction, every node we visit is a valid algorithm. A random walk on this graph becomes a remarkably efficient way to find low-rank schemes, introduced by Kauers and Moosbauer in 2023 <a href="https://doi.org/10.1145/3597066.3597120">[KM23]</a>.</p>

<div style="margin: 20px 0;">
<div style="background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 8px; padding: 16px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
  <strong>Interactive flip-graph CP-decomposition (Khoruzhii et al.)</strong>
  <span style="font-size: 12px; color: #6b7280;">Live demo at <a href="https://qdiag.xyz/cpd/">qdiag.xyz/cpd</a></span>
</div>
<iframe src="/blog/assets/not-every-discovery/flip-cpd/" style="width:100%; height:640px; border:1px solid #e5e7eb; border-radius:4px; background:#fff;" loading="lazy" title="CP decomposition flip-graph demo"></iframe>
<div style="font-size:12px; color:#555; margin-top:8px;">
  Live demo from the <a href="https://github.com/khoruzhii/flip-cpd"><code>flip-cpd</code></a> repository (Kirill Khoruzhii). The 3D view shows the target tensor as a cube of entries, and the decomposition as a sum of rank-1 outer products. Try the presets (Strassen, Laderman) and press <em>Reduce</em> to run 1,000,000 flips — you can watch the rank decrease as the random walk finds lower-rank representations of the same bilinear operation.
</div>
</div>
</div>

<p><strong>What we added.</strong> Two technical ingredients. First, we search over $\mathbb{F}_2$ <em>and</em> $\mathbb{F}_3$, not just $\mathbb{F}_2$; $\mathbb{F}_3$ lets us discover schemes that fundamentally require the inverse of 2, and we then Hensel-lift them to $\mathbb{Z}$ or $\mathbb{Q}$. Second, for transpose products we introduce a corner-zeroing technique that increases the fraction of recursive calls, tightening the asymptotic factor.</p>

<p><strong>Headline numbers.</strong> We systematically searched the 15 distinct structured format combinations that arise for base sizes $n \in {2,3,4,5}$ and <em>improved the asymptotic complexity factor for 13 of them</em>. A few concrete entries:</p>

<ul>
  <li>$4 \times 4$ symmetric rank-k update ($AA^T$): rank 34, giving an asymptotic factor $\gamma = 22/37 \approx 0.595$, improving on the previous best $8/13 \approx 0.615$.</li>
  <li>$2 \times 2$ symmetric-symmetric: rank <strong>5</strong>, improving on the previous rank-6 construction.</li>
  <li>$3 \times 3$ skew-symmetric $\times$ general: rank <strong>14</strong>, improving on AlphaTensor’s rank <strong>15</strong> for the same problem.</li>
</ul>

<p><strong>Compute budget.</strong> The search used commodity 48-core Intel Xeon Gold nodes, 24-hour time limits per configuration, 1007 core-days in total. The headline $\langle 4,4,4:34 \rangle$ SYRK scheme was found in <em>10 minutes</em> of wall-clock time on one node. The implementation sustains about $5 \times 10^6$ flips per second per thread. Code and schemes are released at <a href="https://github.com/khoruzhii/flip-cpd">github.com/khoruzhii/flip-cpd</a>.</p>

<p><strong>The right way to read this.</strong> It is not “random walks beat deep RL”: AlphaTensor solves a strictly harder problem (general matrix multiplication) on which this paper explicitly does <em>not</em> try to improve. What flip graphs do is encode the <em>algebraic structure</em> of correctness directly into the graph: every neighbor is a valid algorithm, so the search never wastes steps on invalid candidates, and the neighborhood relation is tailored to rank-reducing moves. A deep-RL agent that does not start with this structure has to learn, implicitly, to avoid the entire ocean of incorrect decompositions, which is most of the space. That is compute spent on a problem the flip-graph formulation eliminates by construction.</p>

<h2 id="case-2-combinatorial-geometry-with-off-the-shelf-nlp-solvers">Case 2: combinatorial geometry with off-the-shelf NLP solvers</h2>

<p>The second paper is <em><a href="https://arxiv.org/abs/2601.05943">Global Optimization for Combinatorial Geometry Problems Revisited in the Era of LLMs</a></em> <a href="https://arxiv.org/abs/2601.05943">[BKMPP26]</a> by Timo Berthold, Dominik Kamp, Gioni Mexi, me, and Imre Pólik.</p>

<p><strong>Background.</strong> AlphaEvolve’s mathematical-discovery paper reports new best-known solutions for several classical problems, including circle packing (pack $n$ circles with variable radii into a unit square, maximize the sum of radii), hexagon packing (pack $n$ unit hexagons into a regular hexagon, minimize the side length of the container), and minimum-distance-ratio configurations (place $n$ points in the plane, minimize the ratio of max to min pairwise distance). These are classical extremal-geometry problems; best-known solutions were mostly due to Erich Friedman, David Cantrell, and related work, and some have been open since the 1950s. AlphaEvolve improved the state-of-the-art for several of them.</p>

<p><strong>Our approach.</strong> We wrote the same problems as compact nonlinear programs, basically a few nonlinear constraints expressing non-overlap or containment together with some linear bookkeeping. Then we ran them through two off-the-shelf global NLP solvers: FICO’s commercial <a href="https://www.fico.com/en/products/fico-xpress-optimization">Xpress</a> and the open-source <a href="https://www.scipopt.org/">SCIP</a>. We used <em>default settings with zero tuning</em>. We wanted to see what generic global-optimization technology delivers on these problems, not some handcrafted problem-specific technique. In some sense this is the optimization “analog” to using an LLM: a <em>general purpose technology (= solver) + problem formulation</em> here in form of an NLP.</p>

<p><strong>Results.</strong> With unmodified out-of-the-box solvers we reproduce/match every benchmark result we attempted, and in several cases we strictly improve upon AlphaEvolve’s best-known solution. A condensed view:</p>

<table>
  <thead>
    <tr>
      <th>Problem</th>
      <th>Instance</th>
      <th>Our result</th>
      <th>Previous best</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Circle packing, square</td>
      <td>$n = 32$</td>
      <td><strong>2.93957</strong></td>
      <td>2.93794 (AE 2025)</td>
    </tr>
    <tr>
      <td>Circle packing, rectangle</td>
      <td>$n = 26$</td>
      <td><strong>2.63930</strong></td>
      <td>2.638 (Cantrell 2011)</td>
    </tr>
    <tr>
      <td>Circle packing, rectangle</td>
      <td>$n = 27$</td>
      <td><strong>2.69015</strong></td>
      <td>2.687 (Cantrell 2011)</td>
    </tr>
    <tr>
      <td>Hexagon packing</td>
      <td>$n = 11$</td>
      <td><strong>3.92485</strong></td>
      <td>3.93010 (AE 2025)</td>
    </tr>
    <tr>
      <td>Hexagon packing</td>
      <td>$n = 12$</td>
      <td><strong>3.94165</strong></td>
      <td>3.94192 (AE 2025)</td>
    </tr>
    <tr>
      <td>Hexagon packing</td>
      <td>$n = 14$</td>
      <td><strong>4.26900</strong></td>
      <td>4.27240 (Friedman 2015)</td>
    </tr>
    <tr>
      <td>Hexagon packing</td>
      <td>$n = 15$</td>
      <td><strong>4.44769</strong></td>
      <td>4.45406 (Friedman 2015)</td>
    </tr>
    <tr>
      <td>Hexagon packing</td>
      <td>$n = 16$</td>
      <td><strong>4.52788</strong></td>
      <td>4.53633 (Friedman 2015)</td>
    </tr>
  </tbody>
</table>

<p><strong>Note.</strong> For <em>Circle packing</em> the objective is max sum of radii, so larger is better, whereas for <em>Hexagon packing</em> the objective is min side length of the outer hexagon, so smaller is better.</p>

<p>Wall-clock times are seconds to minutes on commodity hardware. Compare this with AlphaEvolve’s pipeline of LLM-driven code generation, execution, and evolutionary refinement per instance.</p>

<div id="widget-pack" style="margin: 20px 0;">
<div style="background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 8px; padding: 16px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
  <strong>Circle packing: AlphaEvolve vs. our NLP solution</strong>
</div>
<div style="display:flex; gap: 18px; flex-wrap: wrap; justify-content: center; align-items:flex-start;">
  <div style="flex:1; min-width:260px; max-width:360px;">
    <div style="text-align:center; font-weight:600; margin-bottom:6px;">AlphaEvolve best known</div>
    <img src="http://www.pokutta.com/blog/assets/not-every-discovery/svg/circlepacking_n32_alphaevolve.svg" alt="AlphaEvolve circle packing n=32" style="width:100%;height:auto;border:1px solid #e5e7eb;background:#fff;" />
    <div style="text-align:center; font-size:13px; margin-top:6px;">$n = 32$, sum of radii &nbsp;=&nbsp; <strong>2.93794</strong></div>
  </div>
  <div style="flex:1; min-width:260px; max-width:360px;">
    <div style="text-align:center; font-weight:600; margin-bottom:6px; color:#0f766e;">Xpress / SCIP default</div>
    <img src="http://www.pokutta.com/blog/assets/not-every-discovery/svg/circlepacking_n32_nlp.svg" alt="MINLP circle packing n=32" style="width:100%;height:auto;border:1px solid #0f766e;background:#fff;" />
    <div style="text-align:center; font-size:13px; margin-top:6px;">$n = 32$, sum of radii &nbsp;=&nbsp; <strong style="color:#0f766e;">2.93957</strong> &nbsp; <span style="color:#0f766e;">(+0.00163)</span></div>
  </div>
</div>
<div style="font-size:12px; color:#555; margin-top:10px; text-align:center;">
  The two packings are visually nearly identical — the improvement is in the fifth decimal. These are not numerical inaccuracies but the typical regime in which one expects to find improvements.
</div>
</div>
</div>

<p><strong>Constraint density matters.</strong> One observation from the paper is quite interesting. The smallest improvements over AlphaEvolve were on the <em>least</em> constrained problem (min-max distance ratio). The largest improvements were on the <em>most</em> constrained one (hexagon packing, with its trigonometric rotations and Farkas-based non-overlap). So it seems: <em>the optimization advantage grows with constraint density</em>.</p>

<p><strong>The OpenEvolve footnote.</strong> The paper flags a particularly instructive anecdote. In an OpenEvolve experiment on packing 26 circles, the LLM-driven evolutionary loop converged to generating code that calls SciPy’s Sequential Least Squares Programming solver (SLSQP). The LLM, given freedom, chose to be a thin wrapper around a classical local NLP solver.</p>

<p><strong>A 3D extension.</strong> The same NLP machinery extends to 3D. As an illustration, the widget below shows the <a href="https://erich-friedman.github.io/packing/cubincub/">current best-known</a> solution (which is due to us) to the <em>cube-in-cube</em> packing problem from Erich Friedman’s classical <a href="https://erich-friedman.github.io/packing/cubincub/">packing benchmarks</a>: pack $n = 11$ unit cubes (rotations allowed) into the smallest containing cube. Every cube is independently positioned <em>and</em> rotated in $\mathrm{SO}(3)$; the non-overlap constraints are pairwise separations between rotated boxes; the objective is to minimize the side length of the container.</p>

<div style="margin: 22px 0;">
<div style="background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 8px; padding: 16px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
  <strong>Packing 11 unit cubes in a cube (container side $s = 2.89444\ldots$)</strong>
  <span style="font-size: 12px; color: #6b7280;">Drag to rotate · scroll to zoom</span>
</div>
<iframe src="/blog/assets/not-every-discovery/cube-packing-n11.html" style="width:100%; height:520px; border:1px solid #e5e7eb; border-radius:4px; background:#fff;" loading="lazy" title="3D cube-in-cube packing (n=11)"></iframe>
</div>
</div>

<h2 id="case-3-patchworked-curves-and-ai-as-a-subroutine">Case 3: patchworked curves and AI as a <em>subroutine</em></h2>

<p>The first two cases aim at the “classical beats AI-driven discovery” narrative, at the top level of the stack. The third case is complementary in some sense, as it moves the question one layer down in the stack: a problem where AI <em>is</em> genuinely useful, but as a <em>component inside</em> a classical structured search, not as the search engine itself. The associated papers are <em><a href="https://arxiv.org/abs/2602.06888">121 Patchworked Curves of Degree Seven</a></em> <a href="https://arxiv.org/abs/2602.06888">[GJKMPSWZ26a]</a> and its companion <em><a href="https://arxiv.org/abs/2604.09221">Fast Isotopy Computation for T-Curves</a></em> <a href="https://arxiv.org/abs/2604.09221">[GJKMPSWZ26b]</a>, with the same eight authors (Geiselmann, Joswig, Kastner, Mundinger, me, Spiegel, Wack, Zimmer) from our <a href="https://mathplus.de/">Algebraic Curves MATH+ project</a>.</p>

<p><strong>The question.</strong> Hilbert’s <a href="https://en.wikipedia.org/wiki/Hilbert%27s_sixteenth_problem">16th problem</a> asks for the topological classification of smooth real plane projective algebraic curves. Viro <a href="https://doi.org/10.1007/BFb0099934">[V84]</a> classified the 121 real schemes (ambient isotopy types) of smooth degree-$7$ curves in 1984. A natural, much harder question was left open: <em>can every one of the 121 real schemes actually be realized by a T-curve, i.e., constructed via Viro’s patchworking?</em> This question was raised explicitly by Itenberg and Viro in 1996, and was open for almost thirty years.</p>

<p><strong>Why it is hard.</strong> A T-curve of degree $d$ is specified by a regular unimodular triangulation of the dilated triangle $d \cdot \Delta_2$ together with a sign distribution on its lattice points. By the Patchworking Theorem, this combinatorial datum pins down the isotopy type of a smooth real plane curve of degree $d$. Settling the 121-classes question in the constructive direction is, at bottom, a structured search: enumerate triangulations and sign distributions, compute the resulting isotopy type, and check that every one of the 121 classes is hit.</p>

<p><strong>Where AI came in.</strong> The bottleneck was not the search framework itself but the actual <em>isotopy-type computation</em>. This subroutine is at the core of the search, mapping  “triangulation + signs” to “which of the 121 classes this is”. Classical implementations were far too slow to run at the scale needed. Using AI in the design process, we built a new, near-quadratic algorithm together with a highly-efficient GPU implementation, that evaluates roughly $10^9$ real schemes per second <a href="https://arxiv.org/abs/2604.09221">[GJKMPSWZ26b]</a>. Equipped with that subroutine, the structured search (deemed impossible by many) became suddenly feasible, and the companion paper <a href="https://arxiv.org/abs/2602.06888">[GJKMPSWZ26a]</a> provides explicit patchworks (and hence explicit polynomials) for every one of the 121 real schemes, settling the Itenberg–Viro question in the positive.</p>

<p>To understand the scale a little better, for a degree-$8$ triangulation there are $2^{42}$ sign distributions to check, which is about $12.64$ base-10 OOMs. A compute-day buys us $4.9$ OOMs and for degree $8$, the “hash rate” drops to about $10^8$ real schemes/sec, so $8$ OOMs. This means that we roughly need one gpu-day to check a single degree $8$ triangulation exhaustively. In contrast, when we started out (with what was already pretty optimized code) we were roughly running at $4-5$ OOMs, which means roughly somewhere between $2.7$ and $27.4$ <em>years</em> for a single triangulation of degree-$8$.</p>

<p><strong>What is the difference?</strong> Notice what did and did not happen here. The AI component did <em>not</em> propose the curves, guide the enumeration, or rank candidates: a patchwork is either valid or not and the isotopy-type answer is exact. The AI component replaced a slow but conceptually classical subroutine with a much faster one. The discovery engine on top is a classical, exhaustive, structured search.</p>

<p>The widget gives an idea of how Viro patchworking works.</p>

<div style="margin: 22px 0;">
<div style="background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 8px; padding: 16px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
  <strong>Patchwork GUI — explore T-curves of low degree</strong>
  <span style="font-size: 12px; color: #6b7280;">Live demo at <a href="https://algebraic-curves.pages.zib.de/patchwork-gui/">algebraic-curves.pages.zib.de</a></span>
</div>
<iframe src="/blog/assets/not-every-discovery/patchwork-gui/" style="width:100%; height:560px; border:1px solid #e5e7eb; border-radius:4px; background:#fff;" loading="lazy" title="Patchwork GUI"></iframe>
<div style="font-size:12px; color:#555; margin-top:8px;">
  Each patchwork (a triangulation of $d\cdot\Delta_2$ with a $\pm$ sign at every lattice point) produces, via Viro's Patchworking Theorem, a smooth real plane curve of degree $d$. The curve's topology (real scheme) is what the fast isotopy subroutine extracts in near-quadratic time.
</div>
</div>
</div>

<h2 id="the-pattern">The pattern</h2>

<p>The three case studies point in the same direction. Rich Sutton’s <a href="http://www.incompleteideas.net/IncIdeas/BitterLesson.html">bitter lesson</a> [BL] says that general methods that scale with compute eventually beat methods relying on human-crafted knowledge. On problems where structure is hard to exploit, e.g., image recognition, protein folding, natural-language understanding, game play with sparse and shifting heuristics, etc. this has now been proven empirically more than once, and I would not argue with it.</p>

<p>But there is an <em>inverse</em> of this lesson on problems where structure is <em>cheap</em> to exploit. Tensor decomposition has a theory of correctness and a theory of local rewrites that preserve correctness. Circle packing has 200 years of extremal geometry behind it, and hexagon packing can be written as a compact NLP that a modern solver prunes very effectively. Real algebraic plane curves have a century of patchworking and tropical geometry behind them. When a problem’s structure is already available in closed form, an AI system that has to rediscover it by exploration is paying the compute tax without getting the benefit. It can succeed (as shown by the AlphaTensor and AlphaEvolve results) but it succeeds <em>in spite of</em> not using the structure, not <em>because</em> of it.</p>

<p>At the same time, benefiting from this inverse lesson depends on someone (or something) formulating the problem in code or as an optimization problem in the first place. This is exactly what was observed in the OpenEvolve anecdote, where the AI formulated the actual optimization problem and then solved it with a classical solver. This is also the paradigm that we have been observing to be very powerful: the AI/LLM as meta-orchestrator of tools (e.g., special-purpose solvers) to solve the actual problem of interest.</p>

<p>Below for comparison a rough estimate of utilized compute; take these numbers with a grain of salt (see description).</p>

<div id="widget-compute" style="margin: 22px 0;">
<div style="background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 8px; padding: 16px;">
<div style="margin-bottom: 10px;">
  <strong>Approximate compute budgets.</strong>
  <span style="font-size: 12px; color: #6b7280; margin-left: 8px;">Log scale in accelerator- or core-hours. AI-side figures are public-report estimates; see note below.</span>
</div>
<svg id="svg-compute" viewBox="0 0 760 320" style="width:100%;height:auto;"></svg>
<div style="font-size:11px; color:#666; margin-top:8px;">
  Notes: <em>AlphaTensor training</em> is a rough public-estimate figure for the end-to-end RL training that produced the released schemes. <em>AlphaEvolve per instance</em> reflects dozens to hundreds of LLM + evaluator iterations per packing problem; exact budgets are not broken out in the paper. <em>Flip graph total</em> is the 1007 core-days reported for 15 format combinations; the <em>headline solve</em> bar is the 10-minute wall-clock for the 4×4 SYRK scheme on a 48-core node. <em>NLP solve</em> is seconds-to-minutes on a single core for the packing instances. The point is the order-of-magnitude spread, not the precise values.
</div>
</div>
</div>

<script>
(function(){
  const svg = document.getElementById('svg-compute');
  const W = 760, H = 320;
  const padL = 260, padR = 20, padT = 40, padB = 50;
  const plotW = W - padL - padR, plotH = H - padT - padB;

  // Log scale: 10^-2 to 10^6
  const xmin = -2, xmax = 6;
  const xPx = v => padL + (v - xmin) / (xmax - xmin) * plotW;

  const bars = [
    {label: 'AlphaTensor training (general matmul)',        sub: 'DeepMind RL, estimated',       hours: 1e5,   color: '#ef4444'},
    {label: 'Flip graph total (15 structured formats)',     sub: '1007 core-days, 48-core Xeon', hours: 24168, color: '#3b82f6'},
    {label: 'AlphaEvolve per packing instance',             sub: 'LLM + evaluator iterations',   hours: 80,    color: '#ef4444'},
    {label: 'Flip graph headline solve (4×4 SYRK)',         sub: '10 min on 48 cores ≈ 8 h',     hours: 8,     color: '#3b82f6'},
    {label: 'NLP solve per packing instance',               sub: 'Xpress/SCIP default settings', hours: 0.05,  color: '#0f766e'},
  ];

  const rowH = plotH / bars.length;

  let html = '';

  // Axis gridlines + labels (powers of 10)
  for (let p = xmin; p <= xmax; p++) {
    const x = xPx(p);
    html += `<line x1="${x}" y1="${padT}" x2="${x}" y2="${padT + plotH}" stroke="#e5e7eb" stroke-width="1"/>`;
    html += `<text x="${x}" y="${H - padB + 18}" font-size="11" text-anchor="middle" fill="#555">10<tspan dy="-4" font-size="9">${p}</tspan></text>`;
  }
  html += `<text x="${padL + plotW/2}" y="${H - 8}" font-size="12" text-anchor="middle" fill="#333">hours (log scale)</text>`;

  // Baseline
  html += `<line x1="${padL}" y1="${padT + plotH}" x2="${padL + plotW}" y2="${padT + plotH}" stroke="#333" stroke-width="1.2"/>`;

  // Bars
  bars.forEach((b, i) => {
    const y = padT + i * rowH + 6;
    const h = rowH - 14;
    const xStart = xPx(xmin);
    const xEnd = xPx(Math.log10(b.hours));
    // Label
    html += `<text x="${padL - 12}" y="${y + h/2 - 2}" font-size="12" text-anchor="end" fill="#111" font-weight="600">${b.label}</text>`;
    html += `<text x="${padL - 12}" y="${y + h/2 + 12}" font-size="10" text-anchor="end" fill="#666">${b.sub}</text>`;
    // Bar
    html += `<rect x="${xStart}" y="${y}" width="${Math.max(2, xEnd - xStart)}" height="${h}" fill="${b.color}" opacity="0.8"/>`;
    // Value label at bar end
    const formatted = b.hours >= 1000 ? b.hours.toLocaleString() : (b.hours >= 1 ? b.hours.toString() : b.hours.toFixed(2));
    html += `<text x="${xEnd + 8}" y="${y + h/2 + 4}" font-size="11" fill="#111">${formatted} h</text>`;
  });

  // Title
  html += `<text x="${padL + plotW/2}" y="${padT - 14}" font-size="13" font-weight="600" text-anchor="middle" fill="#111">Compute to deliver the results in each case study</text>`;

  svg.innerHTML = html;
})();
</script>

<h2 id="what-this-means-for-ai--math">What this means for AI × math</h2>

<p>I want to be careful here because I think the <em>weak</em> version of this story (“AI is overrated; pick up a solver”) is wrong, unhelpful, and just plain stupid. The <em>strong</em> version could be more along the following lines though:</p>

<p>Mathematics has, at this point, a several-thousand-year head start on taxonomy, methods, and approaches. Whole subfields (algebraic complexity, global optimization, polyhedral geometry, numerical linear algebra) are each a century or more of accumulated answers to the question <em>what structure does this problem have, and how do I exploit it?</em> What somehow seems to be missing the point is having an LLM/AI rederive everything that we know each time. This is not just wasteful but also highly inefficient and error-prone. An enormous amount of the “AI for math” debate, in my view, is really a debate about taxonomy: <em>for a given problem, which tool fits?</em> and a lot of these <em>see what my LLM can do!</em> demonstrations. LLMs are <em>spectacularly good</em> at orchestrating the tools we already have, from a “soft” input down to progressively harder formulations such as an optimization problem. A lot of the benefit comes from leveraging this incredible power to “harden” softer inputs into formal(ized) representations that can then be processed with more “formal” tools, such as solvers, formal verifiers, etc.</p>

<p>As such, AI fits naturally into the stack between the researcher and formal science by “hardening” soft “human thought”. This leads to hybrid systems that use strong learned models for the part they are good at (exploration, hypothesis generation, problem formulation, heuristic guidance) and then interface with downstream (sometimes more) classical methods. For those of you interested, this is precisely the approach we follow in our <a href="/blog/agentic-researcher/">agentic researcher workflow</a>.</p>

<h2 id="open-questions">Open questions</h2>

<p>At least two questions seem to be very immediate.</p>

<ol>
  <li><strong>Meta-level routing.</strong> Given a new problem, can an AI system <em>choose</em> the right approach, i.e., determine the handover point? In some sense the AI becomes the “glue code” between the researcher and the downstream formal, classical, etc. methods.</li>
  <li><strong>Formulation as the hybrid interface.</strong> The OpenEvolve-to-SLSQP anecdote suggests a pattern in which an LLM’s main job on a well-structured problem is <em>to write the model</em>, and a classical solver’s job is to <em>solve</em> it. This is exactly the direction of <a href="https://arxiv.org/abs/2501.08406">OptiChat</a> [OC], <a href="https://doi.org/10.1287/opre.2024.1233">ORLM</a> [ORLM], and related work.</li>
</ol>

<h2 id="references">References</h2>

<p>[AT] Alhussein Fawzi, Matej Balog, Aja Huang, Thomas Hubert, Bernardino Romera-Paredes, Mohammadamin Barekatain, Alexander Novikov, Francisco J. R. Ruiz, Julian Schrittwieser, Grzegorz Swirszcz, David Silver, Demis Hassabis, Pushmeet Kohli, <em>Discovering faster matrix multiplication algorithms with reinforcement learning</em>, Nature 2022. <a href="https://www.nature.com/articles/s41586-022-05172-4">link</a></p>

<p>[AE] Alexander Novikov, Ngân Vũ, Marvin Eisenberger, Emilien Dupont, Po-Sen Huang, Adam Zsolt Wagner, Sergey Shirobokov, Borislav Kozlovskii, Francisco J. R. Ruiz, Abbas Mehrabian, M. Pawan Kumar, Abigail See, Swarat Chaudhuri, George Holland, Alex Davies, Sebastian Nowozin, Pushmeet Kohli, Matej Balog, <em>AlphaEvolve: a coding agent for scientific and algorithmic discovery</em>, 2025. <a href="https://arxiv.org/abs/2506.13131">link</a></p>

<p>[FS] Bernardino Romera-Paredes, Mohammadamin Barekatain, Alexander Novikov, Matej Balog, M. Pawan Kumar, Emilien Dupont, Francisco J. R. Ruiz, Jordan S. Ellenberg, Pengming Wang, Omar Fawzi, Pushmeet Kohli, Alhussein Fawzi, <em>Mathematical discoveries from program search with large language models</em>, Nature 2023. <a href="https://www.nature.com/articles/s41586-023-06924-6">link</a></p>

<p>[AD] Daniel J. Mankowitz, Andrea Michi, Anton Zhernov, Marco Gelmi, Marco Selvi, Cosmin Paduraru, Edouard Leurent, Shariq Iqbal, Jean-Baptiste Lespiau, Alex Ahern, Thomas Köppe, Kevin Millikin, Stephen Gaffney, Sophie Elster, Jackson Broshear, Chris Gamble, Kieran Milan, Robert Tung, Minjae Hwang, Taylan Cemgil, Mohammadamin Barekatain, Yujia Li, Amol Mandhane, Thomas Hubert, Julian Schrittwieser, Demis Hassabis, Pushmeet Kohli, Martin Riedmiller, Oriol Vinyals, David Silver, <em>Faster sorting algorithms discovered using deep reinforcement learning</em>, Nature 2023. <a href="https://www.nature.com/articles/s41586-023-06004-9">link</a></p>

<p>[AG] Trieu H. Trinh, Yuhuai Wu, Quoc V. Le, He He, Thang Luong, <em>Solving olympiad geometry without human demonstrations</em>, Nature 2024. <a href="https://www.nature.com/articles/s41586-023-06747-5">link</a></p>

<p>[KM23] Manuel Kauers, Jakob Moosbauer, <em>Flip Graphs for Matrix Multiplication</em>, in <em>Proceedings of the 2023 International Symposium on Symbolic and Algebraic Computation (ISSAC ‘23)</em>, ACM, 2023. <a href="https://doi.org/10.1145/3597066.3597120">link</a></p>

<p>[KGP26] Kirill Khoruzhii, Patrick Gelß, Sebastian Pokutta, <em>Faster Algorithms for Structured Matrix Multiplication via Flip Graph Search</em>, ISSAC 2026. <a href="https://arxiv.org/abs/2511.10786">link</a></p>

<p>[BKMPP26] Timo Berthold, Dominik Kamp, Gioni Mexi, Sebastian Pokutta, Imre Pólik, <em>Global Optimization for Combinatorial Geometry Problems Revisited in the Era of LLMs</em>, 2026. <a href="https://arxiv.org/abs/2601.05943">link</a></p>

<p>[GJKMPSWZ26a] Zoe Geiselmann, Michael Joswig, Lars Kastner, Konrad Mundinger, Sebastian Pokutta, Christoph Spiegel, Marcel Wack, Max Zimmer, <em>121 Patchworked Curves of Degree Seven</em>, 2026. <a href="https://arxiv.org/abs/2602.06888">link</a></p>

<p>[GJKMPSWZ26b] Zoe Geiselmann, Michael Joswig, Lars Kastner, Konrad Mundinger, Sebastian Pokutta, Christoph Spiegel, Marcel Wack, Max Zimmer, <em>Fast Isotopy Computation for T-Curves</em>, 2026. <a href="https://arxiv.org/abs/2604.09221">link</a></p>

<p>[V84] Oleg Viro, <em>Gluing of plane real algebraic curves and constructions of curves of degrees 6 and 7</em>, in <em>Topology (Leningrad, 1982)</em>, Lecture Notes in Mathematics 1060, Springer, 1984. <a href="https://doi.org/10.1007/BFb0099934">link</a></p>

<p>[BL] Richard S. Sutton, <em>The Bitter Lesson</em>, 2019. <a href="http://www.incompleteideas.net/IncIdeas/BitterLesson.html">link</a></p>

<p>[OC] Hao Chen, Gonzalo Esteban Constante-Flores, Krishna Sri Ipsit Mantri, Sai Madhukiran Kompalli, Akshdeep Singh Ahluwalia, Can Li, <em>OptiChat: Bridging Optimization Models and Practitioners with Large Language Models</em>, 2025. <a href="https://arxiv.org/abs/2501.08406">link</a></p>

<p>[ORLM] Chenyu Huang, Zhengyang Tang, Shixi Hu, Ruoqing Jiang, Xin Zheng, Dongdong Ge, Benyou Wang, Zizhuo Wang, <em>ORLM: A Customizable Framework in Training Large Models for Automated Optimization Modeling</em>, <em>Operations Research</em> 73(6), 2025. <a href="https://doi.org/10.1287/opre.2024.1233">link</a></p>]]></content><author><name>Sebastian Pokutta</name></author><category term="research" /><category term="ai" /><category term="optimization" /><category term="matrix-multiplication" /><category term="circle-packing" /><summary type="html"><![CDATA[TL;DR: AI-driven scientific discovery with systems such as AlphaTensor, AlphaEvolve, etc is en vogue and we are also heavily invested in that space. However, these LLM- and RL-driven approaches, while impressive often in themselves, are not always the right tool to get the job done. In this post I will talk about three recent projects from our group that take different angles on LLM- and RL-driven mathematical discovery systems. Two of them revisit classical problems made famous through these AI systems and show that classical structured search matches or beats them on these specific problem classes; with a tiny fraction of the compute. The third example goes the other way around: AI not as discovery engine, but an AI-accelerated subroutine sits inside a classical structured search and lets us settle a thirty-year-old conjecture on real algebraic plane curves of degree seven. This points to an interesting shift in the recent AI vs. classical discussion: it is not so much about whether or not to use AI, but where in the stack AI belongs.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" /><media:content medium="image" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">An uncommon approach to lower bounds for Frank-Wolfe on strongly convex sets</title><link href="http://www.pokutta.com/blog/fw-lower-bounds-sc/" rel="alternate" type="text/html" title="An uncommon approach to lower bounds for Frank-Wolfe on strongly convex sets" /><published>2026-04-13T00:00:00+02:00</published><updated>2026-04-13T00:00:00+02:00</updated><id>http://www.pokutta.com/blog/fw-lower-bounds-sc</id><content type="html" xml:base="http://www.pokutta.com/blog/fw-lower-bounds-sc/"><![CDATA[<p><em>TL;DR: This is a short summary of our paper <a href="https://arxiv.org/abs/2602.04378">Lower Bounds for Frank-Wolfe on Strongly Convex Sets</a> by <a href="https://jannishalbey.github.io/">Jannis Halbey</a>, <a href="https://dezadaniel.github.io/">Daniel Deza</a>, <a href="https://maxzimmer.org/">Max Zimmer</a>, <a href="https://christopheroux.de/">Christophe Roux</a>, <a href="https://stellato.io/">Bartolomeo Stellato</a>, and <a href="https://www.pokutta.com/">Sebastian Pokutta</a>. We prove a matching $\Omega(1/\sqrt{\varepsilon})$ lower bound for Frank-Wolfe on strongly convex sets, showing that Garber and Hazan’s 2015 upper bound is tight. The construction of the lower bound deviates from the standard route quite a bit: instead of searching for worst-case initializations, we build them backward from the optimum.</em></p>

<!--more-->

<h2 id="a-question-that-has-been-open-for-a-decade">A question that has been open for a decade</h2>

<p>Frank-Wolfe has been central to our group’s work for over 10 years, from algorithmic variants to large-scale applications to the recent <a href="https://doi.org/10.1137/1.9781611978568">MOS-SIAM monograph</a>. So when a fundamental (and seemingly simple) question about its convergence rate stays open, it is highly unsatisfactory. I remember quite well when I first discussed this question with Gábor Braun in my office at Georgia Tech: Consider Frank-Wolfe with line search or short steps. On general convex sets, Frank-Wolfe converges at a rate of $\mathcal{O}(1/\varepsilon)$, and this is known to be tight. But when the constraint set is <em>strongly convex</em> (think of a ball or an ellipsoid rather than a polytope) Garber and Hazan <a href="https://arxiv.org/abs/1406.1305">[GH15]</a> showed that Frank-Wolfe achieves a faster rate of convergence of $\mathcal{O}(1/\sqrt{\varepsilon})$. The obvious question was: is this the best one can do, or is there still room for improvement? In particular, this has to be contrasted with the two cases where the constrained optimum lies in the strict (relative) interior or when the unconstrained optimum lies outside of the feasible set; in both cases Frank-Wolfe achieves <em>linear rates of convergence</em> for strongly convex objectives, when the feasible region is strongly convex.</p>

<p>For ten years, nobody had a matching lower bound. Actually, for quite some time the folklore belief was that the rate might be higher than $\mathcal{O}(1/\sqrt{\varepsilon})$. This was supported by numerics, where from random starting points Frank-Wolfe often seemed to converge (much) faster than $1/\sqrt{\varepsilon}$. At the same time, general-purpose worst-case search methods like performance estimation problems (PEPs) could not reach long enough horizons to see the true rate. At the horizons they could access, the scaling looked often closer to $\mathcal{O}(1/\varepsilon^{1/1.44})$, which is faster than $1/\sqrt{\varepsilon}$.</p>

<p>It turns out however, that the answer is in the negative: <strong>the upper bound is tight.</strong> Frank-Wolfe with exact line search or short steps can require $\Omega(1/\sqrt{\varepsilon})$ iterations on strongly convex sets, and this holds even from dimension $n = 2$ onwards. While the result itself is interesting the underlying construction might be even more so.</p>

<p><strong>NB.</strong> Shortly after our work, there was a second paper, by Grimmer and Liu <a href="https://arxiv.org/abs/2602.22608">[GL26]</a> using a technique reminiscent of Jaggi <a href="http://proceedings.mlr.press/v28/jaggi13.html">[J13]</a>, proving a very nice result complementing ours: They showed that any LMO-based methods requires $\Omega(1/\sqrt{\varepsilon})$ LMO-oracle calls in the worst-case for strongly convex objectives over strongly convex sets. In contrast to our result, their result only applies to the high-dimensional regime (their threshold is essentially $n/2$) and their strongly convex set is non-smooth. So broader methods coverage but reduced coverage of regimes.</p>

<h2 id="the-setup-a-quadratic-over-the-ball">The setup: a quadratic over the ball</h2>

<p>The model problem is as simple as it gets: minimize a quadratic over the Euclidean unit ball; and not just <em>any</em> quadratic but the most basic one, one can imagine:</p>

\[\min_{x \in B_1(0)} \norm{x - p}^2,\]

<p>where the target point $p$ lies on the boundary of the ball, i.e., $\norm{p} = 1$. Both the objective and the constraint set are strongly convex and smooth. The problem has a closed-form solution $x^* = p$, and yet we will see, that the Frank-Wolfe algorithm struggles on this instance, depending on where you start, i.e., your choice of $x_0 \in B_1(0).$</p>

<p>The key structural observation is that the iterates stay in a two-dimensional invariant subspace spanned by $p$ and the initial point $x_0$. So the dynamics can be fully described by two quantities: the residual $r_t = \norm{x_t - p}$ and an angle parameter $\theta_t$, basically allowing us to switch to polar coordinates. Moreover, this reduction to the $2$-dimensional space makes the problem analytically tractable while still capturing the essential difficulty.</p>

<p>To give you a feel for the setup and the dynamic, check out the widget below. It shows what the Frank-Wolfe iterates actually look like on the ball. Click inside the ball to set a starting point and see the actual trajectory the algorithm would take. Each step, the LMO picks a point on the boundary (the “vertex”), and the iterate moves along the line toward it. You can see, how the iterates alternate toward the optimizer and how the approach slows down  dramatically near the boundary; can you also check out the worst-case trajectory although at this point it is not clear yet why it is special.</p>

<div id="widget-ball" style="margin: 20px 0;">
<div style="background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 8px; padding: 16px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
  <strong>Frank-Wolfe iterates on the unit ball</strong>
  <span style="font-size: 12px; color: #6b7280;">Click inside the ball to set x₀</span>
</div>
<div style="display: flex; gap: 16px; flex-wrap: wrap;">
  <div style="flex: 1; min-width: 300px;">
    <canvas id="cv-ball" width="480" height="480" style="width:100%; height:auto; cursor:crosshair; border: 1px solid #e5e7eb; border-radius: 4px;"></canvas>
  </div>
  <div style="width: 180px; font-size: 13px;">
    <div id="ball-info" style="padding:8px; background:#fff; border-radius:4px; border:1px solid #e5e7eb; margin-bottom:10px; font-size:12px;">
      Click inside the ball to start.
    </div>
    <div style="margin-bottom: 10px;">
      <label>Iterations:</label><br />
      <input type="range" id="sl-ball-iters" min="5" max="200" step="1" value="40" style="width:100%;" />
      <div id="lbl-ball-iters" style="text-align:center;">40 steps</div>
    </div>
    <div style="margin-bottom: 10px;">
      <label>Show:</label><br />
      <input type="checkbox" id="cb-ball-vertices" checked="" /> <span style="font-size:12px;">LMO vertices</span><br />
      <input type="checkbox" id="cb-ball-lines" /> <span style="font-size:12px;">FW directions</span>
    </div>
    <button id="btn-ball-worst" style="width:100%; padding:8px; cursor:pointer; border-radius:4px; border:1px solid #ccc; background:#fff; margin-bottom:6px;">Show worst-case</button>
    <button id="btn-ball-clear" style="width:100%; padding:8px; cursor:pointer; border-radius:4px; border:1px solid #ccc; background:#fff;">Clear</button>
    <div style="margin-top:12px; font-size:11px; color:#888;">
      <div><span style="display:inline-block;width:10px;height:10px;background:#ef4444;border-radius:50%;vertical-align:middle;"></span> Optimizer $p = (0, 1)$</div>
      <div><span style="display:inline-block;width:10px;height:10px;background:#3b82f6;border-radius:50%;vertical-align:middle;"></span> Iterates $x_t$</div>
      <div><span style="display:inline-block;width:10px;height:10px;background:#a855f6;border-radius:50%;vertical-align:middle;"></span> LMO vertices $v_t$</div>
    </div>
  </div>
</div>
</div>
</div>

<script>
// Retina scaling: call once per canvas to make it crisp on high-DPI screens.
function retinaScale(canvas) {
  const dpr = window.devicePixelRatio || 1;
  const w = canvas.width, h = canvas.height;
  canvas.logicalW = w;
  canvas.logicalH = h;
  canvas.width = w * dpr;
  canvas.height = h * dpr;
  canvas.style.width = '100%';
  canvas.style.height = 'auto';
  const ctx = canvas.getContext('2d');
  ctx.scale(dpr, dpr);
  return ctx;
}
</script>

<script>
(function(){
  // === Widget: FW trajectory on the unit ball ===
  const cv = document.getElementById('cv-ball');
  const ctx = retinaScale(cv);
  const W = cv.logicalW || cv.width, H = cv.logicalH || cv.height;
  const slIters = document.getElementById('sl-ball-iters');
  const lblIters = document.getElementById('lbl-ball-iters');
  const cbVertices = document.getElementById('cb-ball-vertices');
  const cbLines = document.getElementById('cb-ball-lines');
  const btnClear = document.getElementById('btn-ball-clear');
  const btnWorst = document.getElementById('btn-ball-worst');
  const info = document.getElementById('ball-info');

  slIters.oninput = () => { lblIters.textContent = slIters.value + ' steps'; };

  const cx0 = W / 2, cy0 = H / 2, R = W / 2 - 30;
  const px = 0, py = 1; // optimizer on boundary

  function toC(x, y) { return [cx0 + x * R, cy0 - y * R]; }
  function fromC(cx, cy) { return [(cx - cx0) / R, -(cy - cy0) / R]; }

  let trajectories = [];

  function drawBall() {
    ctx.clearRect(0, 0, W, H);
    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, W, H);

    // Ball fill
    ctx.fillStyle = '#f8fafc';
    ctx.beginPath(); ctx.arc(cx0, cy0, R, 0, 2 * Math.PI); ctx.fill();

    // Ball boundary
    ctx.strokeStyle = '#333'; ctx.lineWidth = 2;
    ctx.beginPath(); ctx.arc(cx0, cy0, R, 0, 2 * Math.PI); ctx.stroke();

    // Axes (faint)
    ctx.strokeStyle = '#e5e7eb'; ctx.lineWidth = 1;
    ctx.beginPath(); ctx.moveTo(cx0 - R, cy0); ctx.lineTo(cx0 + R, cy0); ctx.stroke();
    ctx.beginPath(); ctx.moveTo(cx0, cy0 - R); ctx.lineTo(cx0, cy0 + R); ctx.stroke();

    // Optimizer
    const [opx, opy] = toC(px, py);
    ctx.fillStyle = '#ef4444';
    ctx.beginPath(); ctx.arc(opx, opy, 6, 0, 2 * Math.PI); ctx.fill();
    ctx.fillStyle = '#ef4444'; ctx.font = '11px sans-serif'; ctx.textAlign = 'left';
    ctx.fillText('p', opx + 9, opy + 4);
  }

  function fwTrajectory(x0, y0, T) {
    const iterates = [{ x: x0, y: y0 }];
    const vertices = [];
    let xx = x0, yy = y0;

    for (let t = 0; t < T; t++) {
      const dx = xx - px, dy = yy - py;
      const gn = Math.sqrt(dx * dx + dy * dy) * 2;
      if (gn < 1e-14) break;
      // LMO: v = -grad/||grad||
      const vx = -dx / (gn / 2), vy = -dy / (gn / 2);
      vertices.push({ x: vx, y: vy });
      // Exact line search
      const ddx = vx - xx, ddy = vy - yy;
      const a = ddx * ddx + ddy * ddy;
      const b = 2 * ((xx - px) * ddx + (yy - py) * ddy);
      if (a < 1e-15) break;
      const gamma = Math.max(0, Math.min(1, -b / (2 * a)));
      xx += gamma * ddx;
      yy += gamma * ddy;
      iterates.push({ x: xx, y: yy });
    }
    return { iterates, vertices };
  }

  function drawAll() {
    drawBall();
    const showV = cbVertices.checked;
    const showL = cbLines.checked;

    const colors = ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ec4899'];

    for (let ti = 0; ti < trajectories.length; ti++) {
      const traj = trajectories[ti];
      const col = traj._color || colors[ti % colors.length];
      const its = traj.iterates;
      const vts = traj.vertices;

      // FW direction lines (iterate → vertex)
      if (showL) {
        ctx.strokeStyle = 'rgba(168,85,246,0.2)'; ctx.lineWidth = 1;
        for (let i = 0; i < vts.length && i < its.length; i++) {
          const [x1, y1] = toC(its[i].x, its[i].y);
          const [x2, y2] = toC(vts[i].x, vts[i].y);
          ctx.beginPath(); ctx.moveTo(x1, y1); ctx.lineTo(x2, y2); ctx.stroke();
        }
      }

      // Trajectory line
      ctx.strokeStyle = col; ctx.lineWidth = 1.5; ctx.globalAlpha = 0.6;
      ctx.beginPath();
      for (let i = 0; i < its.length; i++) {
        const [cx, cy] = toC(its[i].x, its[i].y);
        i === 0 ? ctx.moveTo(cx, cy) : ctx.lineTo(cx, cy);
      }
      ctx.stroke();
      ctx.globalAlpha = 1.0;

      // Iterate dots
      for (let i = 0; i < its.length; i++) {
        const [cx, cy] = toC(its[i].x, its[i].y);
        const sz = i === 0 ? 5 : (i === its.length - 1 ? 4 : 2.5);
        ctx.fillStyle = i === 0 ? col : (i === its.length - 1 ? col : col);
        ctx.globalAlpha = i === 0 || i === its.length - 1 ? 1.0 : 0.5;
        ctx.beginPath(); ctx.arc(cx, cy, sz, 0, 2 * Math.PI); ctx.fill();
      }
      ctx.globalAlpha = 1.0;

      // Vertex dots on boundary
      if (showV) {
        for (let i = 0; i < vts.length; i++) {
          const [cx, cy] = toC(vts[i].x, vts[i].y);
          ctx.fillStyle = 'rgba(168,85,246,0.35)';
          ctx.beginPath(); ctx.arc(cx, cy, 2, 0, 2 * Math.PI); ctx.fill();
        }
      }

      // Label start
      if (its.length > 0) {
        const [sx, sy] = toC(its[0].x, its[0].y);
        ctx.fillStyle = col; ctx.font = '10px sans-serif'; ctx.textAlign = 'center';
        ctx.fillText('x₀', sx, sy + 15);
      }
    }
  }

  cv.addEventListener('click', function(e) {
    const rect = cv.getBoundingClientRect();
    const scaleX = W / rect.width;
    const scaleY = H / rect.height;
    const mx = (e.clientX - rect.left) * scaleX;
    const my = (e.clientY - rect.top) * scaleY;
    const [x, y] = fromC(mx, my);
    if (x * x + y * y > 0.99) return; // must be inside ball

    const T = parseInt(slIters.value);
    const traj = fwTrajectory(x, y, T);
    trajectories.push(traj);
    drawAll();

    const last = traj.iterates[traj.iterates.length - 1];
    const errFinal = (last.x - px) * (last.x - px) + (last.y - py) * (last.y - py);
    info.innerHTML = '<strong>Start:</strong> (' + x.toFixed(2) + ', ' + y.toFixed(2) + ')<br>' +
      '<strong>Steps:</strong> ' + traj.iterates.length + '<br>' +
      '<strong>Final error:</strong> ' + errFinal.toExponential(2);
  });

  cbVertices.onchange = drawAll;
  cbLines.onchange = drawAll;

  // Worst-case trajectory via backward construction
  btnWorst.onclick = function() {
    // Backward dynamics in (r, s) space
    function bwStep(r, s) {
      const X = (1 + r) * s * s - r;
      const inner1 = 1 - s * s;
      const inner2 = 1 - (1 + r) * (1 + r) * s * s;
      if (inner1 < 0 || inner2 < 0) return null;
      const Y = Math.sqrt(inner1 * inner2);
      const sPrev = X + Y;
      if (sPrev < 1e-12) return null;
      return { r: r / sPrev, s: sPrev };
    }

    // Build backward trajectory in (r, s)
    let r = 0.01, s = 1 - (4/3) * 0.01 + 2 * 0.01 * 0.01;
    const bwPoints = [{ r, s }];
    for (let i = 0; i < 500; i++) {
      const prev = bwStep(r, s);
      if (!prev || prev.r > 1) break;
      bwPoints.push(prev);
      r = prev.r;
      s = prev.s;
    }
    bwPoints.reverse();

    // Recover theta_0 from (r_0, s_0) via bisection, then run FW forward.
    // theta is defined as: theta = <x-p, p> / ||x-p|| ∈ [-1, 0]
    // Given (r, s), we bisect for theta such that the exact line search
    // FW step produces contraction ratio s.
    const r0 = bwPoints[0].r;
    const s0 = bwPoints[0].s;
    let lo = -1, hi = -0.001;
    for (let i = 0; i < 60; i++) {
      const mid = (lo + hi) / 2;
      const denom = (1 + r0) * (1 + r0) + 1 + 2 * (1 + r0) * mid;
      if (denom < 1e-15) { lo = mid; continue; }
      const gamma = Math.max(0, Math.min(1, r0 * (1 + r0 + mid) / denom));
      const a = (1 - gamma) * r0 - gamma;
      const rn = Math.sqrt(Math.max(0, a * a - 2 * gamma * a * mid + gamma * gamma));
      const sCur = r0 > 1e-15 ? rn / r0 : 0;
      if (sCur > s0) hi = mid;
      else lo = mid;
    }
    const theta0 = (lo + hi) / 2;

    // Convert (r0, theta0) to Cartesian. p = (0, 1).
    // theta = <x-p, p>/||x-p|| = (y-1)/r  =>  y = 1 + r*theta
    // x^2 + y^2 <= 1, and x = sqrt(r^2 - (r*theta)^2)
    const y0 = 1 + r0 * theta0;
    const x0 = Math.sqrt(Math.max(0, r0 * r0 - (r0 * theta0) * (r0 * theta0)));

    // Run FW forward from the reconstructed start
    const T = parseInt(slIters.value);
    const worstTraj = fwTrajectory(x0, y0, T);
    worstTraj._color = '#ef4444';
    trajectories.push(worstTraj);
    drawAll();
    const last = worstTraj.iterates[worstTraj.iterates.length - 1];
    const fe = last.x * last.x + (last.y - 1) * (last.y - 1);
    info.innerHTML = '<strong style="color:#ef4444;">Worst-case trajectory</strong><br>' +
      'Start: (' + x0.toFixed(3) + ', ' + y0.toFixed(3) + ')<br>' +
      worstTraj.iterates.length + ' iterates<br>' +
      'Final error: ' + fe.toExponential(2);
  };

  btnClear.onclick = function() {
    trajectories = [];
    drawAll();
    info.innerHTML = 'Click inside the ball to start.';
  };

  drawBall();
})();
</script>

<p class="figcap"><strong>Figure 1.</strong> Frank-Wolfe iterates on the unit ball with $p = (0,1)$ on the boundary. Click to place a starting point and watch the trajectory. The iterates alternate sides of the optimizer and progress slows down dramatically as they approach the boundary.</p>

<p>As mentioned earlier, what makes the problem hard for Frank-Wolfe is the boundary. When the optimizer sits in the interior, the algorithm converges linearly. When the unconstrained(!) optimizer sits outside the feasible set, the gradient is bounded away from zero over the feasible set and we again get linear convergence. But when the optimizer is <em>on</em> the boundary, i.e., when $\norm{p} = 1$, the gradient vanishes at the optimum and the curvature of the constraint set and the objective interact in a non-trivial way. This can be also seen below in the widget. You can see how the position of the optimizer relative to the ball completely determines the convergence behavior.</p>

<div id="widget-convergence" style="margin: 20px 0;">
<div style="background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 8px; padding: 16px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
  <strong>Frank-Wolfe convergence: optimizer position matters</strong>
  <span style="font-size: 12px; color: #6b7280;">Click "Run" or adjust ‖p‖</span>
</div>
<div style="display: flex; gap: 16px; flex-wrap: wrap;">
  <div style="flex: 1; min-width: 280px;">
    <canvas id="cv-convergence" width="560" height="380" style="width:100%; height:auto; border: 1px solid #e5e7eb; border-radius: 4px;"></canvas>
  </div>
  <div style="width: 200px; font-size: 13px;">
    <div style="margin-bottom: 12px;">
      <label>‖p‖ (optimizer position):</label><br />
      <input type="range" id="sl-pnorm" min="0.3" max="1.5" step="0.01" value="1.0" style="width:100%;" />
      <div style="display:flex; justify-content:space-between; font-size:11px; color:#888;">
        <span>interior</span><span>boundary</span><span>exterior</span>
      </div>
      <div id="lbl-pnorm" style="text-align:center; font-weight:600;">‖p‖ = 1.00</div>
    </div>
    <div style="margin-bottom: 12px;">
      <label>Iterations:</label><br />
      <input type="range" id="sl-iters" min="50" max="2000" step="10" value="500" style="width:100%;" />
      <div id="lbl-iters" style="text-align:center;">T = 500</div>
    </div>
    <div style="margin-bottom: 12px;">
      <label>Random starts:</label><br />
      <input type="range" id="sl-nruns" min="1" max="8" step="1" value="4" style="width:100%;" />
      <div id="lbl-nruns" style="text-align:center;">4 trajectories</div>
    </div>
    <button id="btn-run-conv" style="width:100%; padding:8px; cursor:pointer; border-radius:4px; border:1px solid #ccc; background:#fff;">Run</button>
    <div id="info-rate" style="margin-top:10px; padding:8px; background:#fff; border-radius:4px; border:1px solid #e5e7eb; font-size:12px;"></div>
  </div>
</div>
</div>
</div>

<script>
(function(){
  // === Widget 1: Convergence comparison ===
  const cv = document.getElementById('cv-convergence');
  const ctx = retinaScale(cv);
  const slP = document.getElementById('sl-pnorm');
  const slI = document.getElementById('sl-iters');
  const slN = document.getElementById('sl-nruns');
  const lblP = document.getElementById('lbl-pnorm');
  const lblI = document.getElementById('lbl-iters');
  const lblN = document.getElementById('lbl-nruns');
  const btnRun = document.getElementById('btn-run-conv');
  const infoRate = document.getElementById('info-rate');

  slP.oninput = () => { lblP.textContent = '‖p‖ = ' + parseFloat(slP.value).toFixed(2); };
  slI.oninput = () => { lblI.textContent = 'T = ' + slI.value; };
  slN.oninput = () => { lblN.textContent = slN.value + ' trajectories'; };

  // FW in Cartesian coordinates — works correctly for any ‖p‖.
  // f(x) = ||x - p||^2, constraint = unit ball, p = (0, pNorm).
  function fwOnBall(pNorm, x0, y0, T) {
    let xx = x0, yy = y0;
    const py = pNorm;
    // Optimum: if p inside/on ball x*=p; if outside x*=p/||p||
    const optY = pNorm <= 1 ? pNorm : 1;
    const fStar = (optY - py) * (optY - py);
    const err0 = xx * xx + (yy - py) * (yy - py);
    const errors = [Math.max(0, err0 - fStar)];

    for (let t = 0; t < T; t++) {
      const dx = xx, dy = yy - py;
      const err = dx * dx + dy * dy;
      if (err - fStar < 1e-20) { errors.push(0); continue; }
      // gradient = 2(x - p)
      const gx = 2 * dx, gy = 2 * dy;
      const gn = Math.sqrt(gx * gx + gy * gy);
      if (gn < 1e-15) { errors.push(0); continue; }
      // LMO on unit ball: v = -grad/||grad||
      const vx = -gx / gn, vy = -gy / gn;
      // Exact line search: min_gamma f(x + gamma*(v-x)), gamma in [0,1]
      const ddx = vx - xx, ddy = vy - yy;
      const a = ddx * ddx + ddy * ddy;
      const b = 2 * (dx * ddx + dy * ddy);
      if (a < 1e-15) { errors.push(Math.max(0, err - fStar)); continue; }
      const gamma = Math.max(0, Math.min(1, -b / (2 * a)));
      xx += gamma * ddx;
      yy += gamma * ddy;
      const dx2 = xx, dy2 = yy - py;
      errors.push(Math.max(0, dx2 * dx2 + dy2 * dy2 - fStar));
    }
    return errors;
  }

  function randomInit() {
    // Random point in the unit ball (2D)
    const angle = Math.random() * 2 * Math.PI;
    const rad = Math.sqrt(Math.random()) * 0.95;
    return { x: rad * Math.cos(angle), y: rad * Math.sin(angle) };
  }

  function draw() {
    const pNorm = parseFloat(slP.value);
    const T = parseInt(slI.value);
    const N = parseInt(slN.value);
    const W = cv.logicalW || cv.width, H = cv.logicalH || cv.height;
    const pad = { l: 60, r: 20, t: 30, b: 40 };
    const pw = W - pad.l - pad.r;
    const ph = H - pad.t - pad.b;

    ctx.clearRect(0, 0, W, H);
    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, W, H);

    // Run trajectories
    const trajectories = [];
    for (let i = 0; i < N; i++) {
      const init = randomInit();
      trajectories.push(fwOnBall(pNorm, init.x, init.y, T));
    }

    // Compute axis ranges (log-log)
    const xMin = 0, xMax = Math.log10(T + 1);
    let yMin = -12, yMax = 1;

    // Reference lines
    const refSqrt = []; // O(1/t^2) = O(1/sqrt(eps)) rate
    const refLinear = []; // O(exp(-ct)) linear rate
    for (let t = 1; t <= T; t++) {
      refSqrt.push({ x: Math.log10(t), y: Math.log10(1.0 / (t * t)) });
      refLinear.push({ x: Math.log10(t), y: -0.3 * t * Math.LOG10E });
    }

    function toCanvas(lx, ly) {
      return [
        pad.l + (lx - xMin) / (xMax - xMin) * pw,
        pad.t + (yMax - ly) / (yMax - yMin) * ph
      ];
    }

    // Grid
    ctx.strokeStyle = '#f0f0f0';
    ctx.lineWidth = 1;
    for (let y = yMin; y <= yMax; y += 2) {
      const [cx, cy] = toCanvas(xMin, y);
      const [cx2] = toCanvas(xMax, y);
      ctx.beginPath(); ctx.moveTo(cx, cy); ctx.lineTo(cx2, cy); ctx.stroke();
    }

    // Axes
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 1.5;
    ctx.beginPath();
    ctx.moveTo(pad.l, pad.t);
    ctx.lineTo(pad.l, H - pad.b);
    ctx.lineTo(W - pad.r, H - pad.b);
    ctx.stroke();

    // Axis labels
    ctx.fillStyle = '#333';
    ctx.font = '12px sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText('log₁₀(iteration)', W / 2, H - 5);
    ctx.save();
    ctx.translate(15, H / 2);
    ctx.rotate(-Math.PI / 2);
    ctx.fillText('log₁₀(f(xₜ) − f*)', 0, 0);
    ctx.restore();

    // Tick labels
    ctx.font = '10px sans-serif';
    ctx.textAlign = 'center';
    for (let x = 0; x <= xMax; x += 0.5) {
      const [cx, cy] = toCanvas(x, yMin);
      ctx.fillText(x.toFixed(1), cx, cy + 14);
    }
    ctx.textAlign = 'right';
    for (let y = yMin; y <= yMax; y += 2) {
      const [cx, cy] = toCanvas(xMin, y);
      ctx.fillText(y.toString(), cx - 6, cy + 4);
    }

    // Reference: 1/t^2 line
    ctx.strokeStyle = 'rgba(80,80,80,0.7)';
    ctx.lineWidth = 2;
    ctx.setLineDash([6, 4]);
    ctx.beginPath();
    for (let i = 0; i < refSqrt.length; i++) {
      const [cx, cy] = toCanvas(refSqrt[i].x, refSqrt[i].y);
      if (cy < pad.t || cy > H - pad.b) continue;
      i === 0 ? ctx.moveTo(cx, cy) : ctx.lineTo(cx, cy);
    }
    ctx.stroke();
    ctx.setLineDash([]);

    // Label for reference
    const [rx, ry] = toCanvas(refSqrt[Math.min(40, refSqrt.length - 1)].x, refSqrt[Math.min(40, refSqrt.length - 1)].y);
    ctx.fillStyle = '#999';
    ctx.font = '11px sans-serif';
    ctx.textAlign = 'left';
    if (ry > pad.t && ry < H - pad.b) ctx.fillText('O(1/t²)', rx + 5, ry - 5);

    // Draw trajectories
    const colors = ['#3b82f6', '#10b981', '#f59e0b', '#ef4444', '#8b5cf6', '#ec4899', '#14b8a6', '#f97316'];
    for (let j = 0; j < trajectories.length; j++) {
      const errs = trajectories[j];
      ctx.strokeStyle = colors[j % colors.length];
      ctx.lineWidth = 1.5;
      ctx.globalAlpha = 0.7;
      ctx.beginPath();
      let started = false;
      for (let t = 1; t < errs.length; t++) {
        if (errs[t] <= 0) continue;
        const lx = Math.log10(t);
        const ly = Math.log10(errs[t]);
        const [cx, cy] = toCanvas(lx, ly);
        if (cy < pad.t || cy > H - pad.b) continue;
        if (!started) { ctx.moveTo(cx, cy); started = true; }
        else ctx.lineTo(cx, cy);
      }
      ctx.stroke();
      ctx.globalAlpha = 1.0;
    }

    // Info
    const regime = pNorm < 0.98 ? 'interior → linear convergence' :
                   pNorm > 1.02 ? 'exterior → linear convergence' :
                   'boundary → O(1/√ε) convergence';
    infoRate.innerHTML = '<strong>Regime:</strong> ' + regime +
      '<br><span style="color:#999">Dashed: O(1/t²) reference</span>';
  }

  btnRun.onclick = draw;
  slP.onchange = draw;
  draw();
})();
</script>

<p class="figcap"><strong>Figure 2.</strong> Frank-Wolfe convergence on the unit ball for different optimizer positions. Interior ($\norm{p} &lt; 1$) and exterior ($\norm{p} &gt; 1$) give linear convergence. On the boundary ($\norm{p} = 1$), convergence slows to $\mathcal{O}(1/\sqrt{\varepsilon})$ and the trajectories develop a characteristic plateau-and-jump pattern.</p>

<h2 id="plateaus-and-jumps">Plateaus and jumps</h2>

<p>Another peculiar aspect of the log-log convergence plots in Figure 2 is that when $\norm{p} = 1$, then the trajectories exhibit a weird plateau and jump dynamic. We have long basically flat plateaus where Frank-Wolfe barely makes progress, interrupted by sudden <em>jumps</em>, where the error decreases dramatically in a single step. To the expert, this might look like restart trajectories but the situation is different here. Even more surprising: how fast Frank-Wolfe converges has almost nothing to do with how <em>close</em> the starting point is to the optimum, but <em>where</em> you start. The heatmap below shows the number of iterations to reach a target accuracy from every point in the unit ball (with $p = (0,1)$ on the top of the boundary). The heatmap exhibits some weird “highways” (the darker areas), and once an iterate hits such a highway, convergence is almost immediate; in particular, starting points further away but on such a highway lead to much faster convergence to the optimum than points close to the optimum but in the lighter areas.</p>

<div id="widget-heatmap" style="margin: 20px 0;">
<div style="background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 8px; padding: 16px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
  <strong>Convergence landscape: iterations to reach ε = 10⁻²</strong>
  <span style="font-size: 12px; color: #6b7280;">Hover to see iteration count</span>
</div>
<div style="display: flex; gap: 16px; flex-wrap: wrap;">
  <div style="flex: 1; min-width: 300px;">
    <canvas id="cv-heatmap" width="440" height="440" style="width:100%; height:auto; cursor:crosshair; border: 1px solid #e5e7eb; border-radius: 4px;"></canvas>
  </div>
  <div style="width: 180px; font-size: 13px;">
    <div id="heatmap-info" style="padding:8px; background:#fff; border-radius:4px; border:1px solid #e5e7eb; margin-bottom:10px; font-size:12px;">
      Hover over the ball to see iteration counts.
    </div>
    <div style="margin-bottom: 10px;">
      <label>Target accuracy:</label><br />
      <select id="sel-eps" style="width:100%; padding:4px;">
        <option value="0.01" selected="">ε = 10⁻²</option>
        <option value="0.0001">ε = 10⁻⁴</option>
        <option value="0.000001">ε = 10⁻⁶</option>
      </select>
    </div>
    <button id="btn-heatmap-recompute" style="width:100%; padding:8px; cursor:pointer; border-radius:4px; border:1px solid #ccc; background:#fff;">Recompute</button>
    <div style="margin-top:12px;">
      <canvas id="cv-colorbar" width="160" height="20" style="width:100%; height:20px; border:1px solid #e5e7eb; border-radius:2px;"></canvas>
      <div style="display:flex; justify-content:space-between; font-size:10px; color:#888;">
        <span>few iters</span><span>many iters</span>
      </div>
    </div>
    <div style="margin-top:8px; font-size:11px; color:#888;">
      Red dot: optimizer $p = (0,1)$.<br />
      Gray: did not converge within max iterations.
    </div>
  </div>
</div>
</div>
</div>

<script>
(function(){
  // === Widget 4: Convergence heatmap over the unit ball ===
  const cv = document.getElementById('cv-heatmap');
  const ctx = retinaScale(cv);
  const selEps = document.getElementById('sel-eps');
  const btnRecompute = document.getElementById('btn-heatmap-recompute');
  const hInfo = document.getElementById('heatmap-info');
  const cvBar = document.getElementById('cv-colorbar');
  const ctxBar = cvBar.getContext('2d');

  const S = cv.logicalW || cv.width; // logical size
  const cx0 = S / 2, cy0 = S / 2, R = S / 2 - 20;
  const maxIters = 2000;
  const res = 120; // grid resolution

  // p = (0, 1) in math coords → (cx0, cy0 - R) on canvas
  const px = 0, py = 1;

  // Color map: viridis-like
  function viridis(t) {
    t = Math.max(0, Math.min(1, t));
    const r = Math.round(255 * Math.max(0, Math.min(1, 0.267004 + t * (0.003299 + t * (-0.227411 + t * (0.520343 + t * (-0.726934 + t * 0.329415)))))));
    const g = Math.round(255 * Math.max(0, Math.min(1, 0.004874 + t * (1.014816 + t * (-0.067728 + t * (-0.368142 + t * (0.416694 + t * -0.094889)))))));
    const b = Math.round(255 * Math.max(0, Math.min(1, 0.329415 + t * (1.561964 + t * (-4.005691 + t * (7.473592 + t * (-6.335778 + t * 1.976613)))))));
    return [r, g, b];
  }

  let heatData = null; // Store for hover lookup

  function fwItersFromPoint(x0, y0, eps) {
    // FW on unit ball: f(x) = ||x - p||^2, p = (0,1)
    let xx = x0, yy = y0;
    for (let t = 0; t < maxIters; t++) {
      const dx = xx - px, dy = yy - py;
      const err = dx * dx + dy * dy;
      if (err < eps) return t;
      // gradient = 2(x - p)
      const gx = 2 * dx, gy = 2 * dy;
      const gn = Math.sqrt(gx * gx + gy * gy);
      if (gn < 1e-15) return t;
      // LMO: v = -grad/||grad||
      const vx = -gx / gn, vy = -gy / gn;
      // Exact line search: minimize f(x + gamma*(v - x))
      const ddx = vx - xx, ddy = vy - yy;
      const a = ddx * ddx + ddy * ddy;
      const b = 2 * (dx * ddx + dy * ddy);
      if (a < 1e-15) continue;
      const gamma = Math.max(0, Math.min(1, -b / (2 * a)));
      xx += gamma * ddx;
      yy += gamma * ddy;
    }
    return -1; // did not converge
  }

  function computeHeatmap() {
    const eps = parseFloat(selEps.value);
    // Store grid data for hover lookup (keyed by grid cell)
    const grid = [];
    const counts = [];
    for (let gi = 0; gi < res; gi++) {
      for (let gj = 0; gj < res; gj++) {
        const mx = -1 + (2 * gi + 1) / res;
        const my = -1 + (2 * gj + 1) / res;
        if (mx * mx + my * my > 1) { grid.push(-2); continue; }
        const iters = fwItersFromPoint(mx, my, eps);
        grid.push(iters);
        if (iters >= 0) counts.push(iters);
      }
    }
    heatData = grid; // store for hover

    const cMax = counts.length > 0 ? Math.max(...counts) : 1;
    const cMin = counts.length > 0 ? Math.min(...counts) : 0;

    // Clear and draw using fillRect (respects retina ctx.scale)
    ctx.clearRect(0, 0, S, S);
    const cellSize = (2 * R) / res;
    for (let gi = 0; gi < res; gi++) {
      for (let gj = 0; gj < res; gj++) {
        const iters = grid[gi * res + gj];
        if (iters === -2) continue;
        let c;
        if (iters === -1) c = [180, 180, 180];
        else {
          const t = cMax > cMin ? (iters - cMin) / (cMax - cMin) : 0;
          c = viridis(t);
        }
        const px2 = cx0 - R + gi * cellSize;
        const py2 = cy0 - R + (res - 1 - gj) * cellSize;
        ctx.fillStyle = 'rgb(' + c[0] + ',' + c[1] + ',' + c[2] + ')';
        ctx.fillRect(px2, py2, cellSize + 0.5, cellSize + 0.5);
      }
    }

    // Ball boundary
    ctx.strokeStyle = '#333'; ctx.lineWidth = 2;
    ctx.beginPath(); ctx.arc(cx0, cy0, R, 0, 2 * Math.PI); ctx.stroke();

    // Optimizer dot
    ctx.fillStyle = '#ef4444';
    ctx.beginPath(); ctx.arc(cx0 + px * R, cy0 - py * R, 6, 0, 2 * Math.PI); ctx.fill();

    // Colorbar (simple gradient via fillRect)
    const barW = 160, barH = 20;
    for (let x = 0; x < barW; x++) {
      const c = viridis(x / barW);
      ctxBar.fillStyle = 'rgb(' + c[0] + ',' + c[1] + ',' + c[2] + ')';
      ctxBar.fillRect(x, 0, 1, barH);
    }

    // Update title with current epsilon
    const epsLabel = eps === 0.01 ? '10⁻²' : eps === 0.0001 ? '10⁻⁴' : '10⁻⁶';
    document.querySelector('#widget-heatmap strong').textContent =
      'Convergence landscape: iterations to reach ε = ' + epsLabel;
  }

  cv.addEventListener('mousemove', function(e) {
    if (!heatData) return;
    const rect = cv.getBoundingClientRect();
    // Convert mouse position to math coords
    const canvasX = (e.clientX - rect.left) / rect.width * S;
    const canvasY = (e.clientY - rect.top) / rect.height * S;
    const mathX = (canvasX - cx0) / R;
    const mathY = -(canvasY - cy0) / R;
    if (mathX * mathX + mathY * mathY > 1) { hInfo.innerHTML = 'Outside the ball.'; return; }
    // Find grid cell
    const gi = Math.floor((mathX + 1) / 2 * res);
    const gj = Math.floor((mathY + 1) / 2 * res);
    if (gi < 0 || gi >= res || gj < 0 || gj >= res) return;
    const iters = heatData[gi * res + gj];
    if (iters === -2) { hInfo.innerHTML = 'Outside the ball.'; return; }
    if (iters === -1) hInfo.innerHTML = '<strong>(' + mathX.toFixed(2) + ', ' + mathY.toFixed(2) + ')</strong><br>Did not converge in ' + maxIters + ' iters';
    else hInfo.innerHTML = '<strong>(' + mathX.toFixed(2) + ', ' + mathY.toFixed(2) + ')</strong><br>Converged in <strong>' + iters + '</strong> iterations';
  });

  btnRecompute.onclick = computeHeatmap;
  selEps.onchange = computeHeatmap;
  computeHeatmap();
})();
</script>

<p class="figcap"><strong>Figure 3.</strong> Convergence landscape of Frank-Wolfe on the unit ball with optimizer $p = (0,1)$ (red dot). Colors show the number of iterations to reach the target accuracy. The pattern is non-monotone: starting points close to the optimum do not necessarily converge faster. Note that the “highways” are hard to see at higher accuracies due to the reduced rendering resolution but they are equally visible for smaller $\varepsilon$ once the resolution is bumped up, which is beyond what the widget can handle.</p>

<p>This phenomenon is not noise but highly structured and an artifact of the (deterministic) dynamic that drives the optimization process. During a plateau, the Frank-Wolfe direction is nearly orthogonal to the gradient, so each step makes tiny progress. Then, at some point, the iterate reaches a configuration where the direction aligns favorably and the error drops sharply. Understanding <em>when</em> these jumps happen and whether they can be delayed is the key to the lower bound construction.</p>

<p>To make this precise, we introduce the <em>contraction factor</em> $s_t = r_{t+1}/r_t$. When $s_t$ is close to 1, the algorithm barely moves. When $s_t$ is small, we get a jump. The dynamics of $(r_t, s_t)$ satisfy a closed-form recurrence (whose derivation was somewhat painful):</p>

\[s_{t+1}^2 = \frac{1 - (1+r_t)^2 s_t^2}{2 - 2s_t - (2+r_t) r_t s_t^2}.\]

<h2 id="the-phase-space">The phase space</h2>

<p>Once equipped with the recurrence, we can analyze it. In fact, what can be seen numerically and analytically, is that the recurrence partitions the $(r, s)$ plane into two regimes and there is a critical curve $s = g(r)$ that separates the two:</p>

<ul>
  <li><em>The stable regime.</em> (below the curve): the contraction factor <em>increases</em> at each step, i.e., convergence is slowing down. The algorithm eventually plateaus.</li>
  <li><em>The unstable regime.</em> (above the curve): the contraction factor <em>decreases</em> sharply and a jump is about to happen.</li>
</ul>

<p>To get slow convergence for our lower bound, our goal is to keep the trajectory in the stable regime for as long as possible, basically converging to the critical curve from below without crossing it. This can be also nicely seen in the widget below: click anywhere in the phase space (below the black line) to set an initial $(r, s)$ and see how the trajectory evolves. Points in the stable regime (red colors) lead to long plateaus. Points in the unstable regime (blue colors) jump quickly to smaller errors back into the stable regime.</p>

<div id="widget-phase" style="margin: 20px 0;">
<div style="background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 8px; padding: 16px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
  <strong>Phase space explorer: stable vs. unstable regimes</strong>
  <span style="font-size: 12px; color: #6b7280;">Click to set (r, s) and trace trajectory</span>
</div>
<div style="display: flex; gap: 16px; flex-wrap: wrap;">
  <div style="flex: 1; min-width: 300px;">
    <canvas id="cv-phase" width="560" height="440" style="width:100%; height:auto; cursor:crosshair; border: 1px solid #e5e7eb; border-radius: 4px;"></canvas>
  </div>
  <div style="width: 180px; font-size: 13px;">
    <div id="phase-info" style="padding:8px; background:#fff; border-radius:4px; border:1px solid #e5e7eb; margin-bottom:10px;">
      <div style="font-size:11px; color:#888;">Click to start</div>
    </div>
    <div style="margin-bottom: 10px;">
      <label>Steps to trace:</label><br />
      <input type="range" id="sl-phase-steps" min="10" max="200" step="5" value="60" style="width:100%;" />
      <div id="lbl-phase-steps" style="text-align:center;">60 steps</div>
    </div>
    <button id="btn-phase-worst" style="width:100%; padding:8px; cursor:pointer; border-radius:4px; border:1px solid #ccc; background:#fff; margin-bottom:6px;">Show worst-case trajectory</button>
    <button id="btn-phase-clear" style="width:100%; padding:8px; cursor:pointer; border-radius:4px; border:1px solid #ccc; background:#fff;">Clear</button>
    <div style="margin-top:12px; font-size:11px; color:#888;">
      <div><span style="display:inline-block;width:12px;height:12px;background:rgba(239,68,68,0.15);border:1px solid #eee;vertical-align:middle;"></span> Stable ($s$ increases)</div>
      <div><span style="display:inline-block;width:12px;height:12px;background:rgba(59,130,246,0.15);border:1px solid #eee;vertical-align:middle;"></span> Unstable ($s$ decreases)</div>
      <div><span style="display:inline-block;width:12px;height:2px;background:#333;vertical-align:middle;"></span> Boundary $s = 1/(1+r)$</div>
      <div><span style="display:inline-block;width:12px;height:2px;background:#ef4444;vertical-align:middle;border-top:1px dashed #ef4444;"></span> Monotonicity curve $g(r)$</div>
    </div>
  </div>
</div>
</div>
</div>

<script>
(function(){
  // === Widget 2: Phase space explorer ===
  const cv = document.getElementById('cv-phase');
  const ctx = retinaScale(cv);
  const slSteps = document.getElementById('sl-phase-steps');
  const lblSteps = document.getElementById('lbl-phase-steps');
  const btnWorst = document.getElementById('btn-phase-worst');
  const btnClear = document.getElementById('btn-phase-clear');
  const phaseInfo = document.getElementById('phase-info');

  slSteps.oninput = () => { lblSteps.textContent = slSteps.value + ' steps'; };

  const W = cv.logicalW || cv.width, H = cv.logicalH || cv.height;
  const pad = { l: 50, r: 15, t: 15, b: 40 };
  const pw = W - pad.l - pad.r;
  const ph = H - pad.t - pad.b;

  // Phase space bounds
  const rMin = 0, rMax = 1.0;
  const sMin = 0.5, sMax = 1.0;

  function toCanvas(r, s) {
    return [
      pad.l + (r - rMin) / (rMax - rMin) * pw,
      pad.t + (sMax - s) / (sMax - sMin) * ph
    ];
  }

  function fromCanvas(cx, cy) {
    return [
      rMin + (cx - pad.l) / pw * (rMax - rMin),
      sMax - (cy - pad.t) / ph * (sMax - sMin)
    ];
  }

  // Forward dynamics: given (r, s), compute next (r', s')
  function fwStep(r, s) {
    if (r < 1e-12) return { r: 0, s: 0 };
    const rNext = s * r;
    const s2num = 1 - (1 + r) * (1 + r) * s * s;
    const s2den = 2 - 2 * s - (2 + r) * r * s * s;
    if (s2den < 1e-15 || s2num < 0) return { r: rNext, s: 0 };
    const sNext = Math.sqrt(s2num / s2den);
    return { r: rNext, s: Math.min(sNext, 1.0 / (1 + rNext)) };
  }

  // Backward dynamics: given (r_t, s_t), compute (r_{t-1}, s_{t-1})
  function bwStep(r, s) {
    const X = (1 + r) * s * s - r;
    const inner1 = 1 - s * s;
    const inner2 = 1 - (1 + r) * (1 + r) * s * s;
    if (inner1 < 0 || inner2 < 0) return null;
    const Y = Math.sqrt(inner1 * inner2);
    const sPrev = X + Y;
    if (sPrev < 1e-12) return null;
    const rPrev = r / sPrev;
    return { r: rPrev, s: sPrev };
  }

  // Monotonicity threshold g(r): s_{t+1} = s_t curve (numerical)
  function gCurve(r) {
    // Find s such that fwStep(r,s).s == s via bisection
    let lo = 0.5, hi = 1.0 / (1 + r);
    for (let i = 0; i < 50; i++) {
      const mid = (lo + hi) / 2;
      const next = fwStep(r, mid);
      if (next.s > mid) lo = mid;
      else hi = mid;
    }
    return (lo + hi) / 2;
  }

  let trajectories = [];

  function drawBackground() {
    ctx.clearRect(0, 0, W, H);
    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, W, H);

    // Color the stable/unstable regions using fillRect (respects retina scaling)
    const gridRes = 100;
    const cellW = pw / gridRes, cellH = ph / gridRes;
    for (let gi = 0; gi < gridRes; gi++) {
      const r = rMin + (gi + 0.5) / gridRes * (rMax - rMin);
      for (let gj = 0; gj < gridRes; gj++) {
        const s = sMax - (gj + 0.5) / gridRes * (sMax - sMin);
        const boundary = 1.0 / (1 + r);
        if (s > boundary || s < 0) {
          ctx.fillStyle = '#f5f5f5';
        } else {
          const next = fwStep(r, s);
          ctx.fillStyle = next.s > s
            ? 'rgba(239,68,68,0.10)'    // Stable (warm)
            : 'rgba(59,130,246,0.10)';  // Unstable (cool)
        }
        ctx.fillRect(pad.l + gi * cellW, pad.t + gj * cellH, cellW + 0.5, cellH + 0.5);
      }
    }

    // Boundary curve s = 1/(1+r)
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 2;
    ctx.beginPath();
    for (let r = 0.01; r <= rMax; r += 0.005) {
      const s = 1.0 / (1 + r);
      const [cx, cy] = toCanvas(r, s);
      r < 0.02 ? ctx.moveTo(cx, cy) : ctx.lineTo(cx, cy);
    }
    ctx.stroke();

    // Monotonicity curve g(r)
    ctx.strokeStyle = '#ef4444';
    ctx.lineWidth = 1.5;
    ctx.setLineDash([5, 3]);
    ctx.beginPath();
    let started = false;
    for (let r = 0.01; r <= rMax; r += 0.005) {
      const s = gCurve(r);
      if (s < sMin || s > sMax) continue;
      const [cx, cy] = toCanvas(r, s);
      if (!started) { ctx.moveTo(cx, cy); started = true; }
      else ctx.lineTo(cx, cy);
    }
    ctx.stroke();
    ctx.setLineDash([]);

    // Axes
    ctx.strokeStyle = '#333';
    ctx.lineWidth = 1.5;
    ctx.beginPath();
    ctx.moveTo(pad.l, pad.t);
    ctx.lineTo(pad.l, H - pad.b);
    ctx.lineTo(W - pad.r, H - pad.b);
    ctx.stroke();

    // Labels
    ctx.fillStyle = '#333';
    ctx.font = '12px sans-serif';
    ctx.textAlign = 'center';
    ctx.fillText('residual r', W / 2, H - 5);
    ctx.save();
    ctx.translate(14, H / 2);
    ctx.rotate(-Math.PI / 2);
    ctx.fillText('contraction s = r_{t+1}/r_t', 0, 0);
    ctx.restore();

    // Ticks
    ctx.font = '10px sans-serif';
    ctx.textAlign = 'center';
    for (let r = 0; r <= rMax; r += 0.2) {
      const [cx, cy] = toCanvas(r, sMin);
      ctx.fillText(r.toFixed(1), cx, cy + 14);
    }
    ctx.textAlign = 'right';
    for (let s = sMin; s <= sMax; s += 0.1) {
      const [cx, cy] = toCanvas(rMin, s);
      ctx.fillText(s.toFixed(1), cx - 6, cy + 4);
    }

    // Curve labels
    ctx.font = '11px sans-serif';
    const [bx, by] = toCanvas(0.6, 1.0 / 1.6);
    ctx.fillStyle = '#333';
    ctx.textAlign = 'left';
    ctx.fillText('s = 1/(1+r)', bx + 4, by - 6);

    const gVal = gCurve(0.5);
    const [gx, gy] = toCanvas(0.5, gVal);
    ctx.fillStyle = '#ef4444';
    ctx.fillText('g(r)', gx + 4, gy - 6);
  }

  function drawTrajectories() {
    drawBackground();
    for (const traj of trajectories) {
      ctx.strokeStyle = traj.color;
      ctx.lineWidth = 2;
      ctx.globalAlpha = 0.8;
      ctx.beginPath();
      for (let i = 0; i < traj.points.length; i++) {
        const [cx, cy] = toCanvas(traj.points[i].r, traj.points[i].s);
        if (cx < pad.l || cx > W - pad.r || cy < pad.t || cy > H - pad.b) continue;
        i === 0 ? ctx.moveTo(cx, cy) : ctx.lineTo(cx, cy);
      }
      ctx.stroke();
      ctx.globalAlpha = 1.0;

      // Start dot + label
      if (traj.points.length > 0) {
        const p0 = traj.points[0];
        const [sx, sy] = toCanvas(p0.r, p0.s);
        ctx.fillStyle = traj.color;
        ctx.beginPath();
        ctx.arc(sx, sy, 5, 0, 2 * Math.PI);
        ctx.fill();
        // Label with coordinates
        ctx.font = '10px sans-serif';
        ctx.textAlign = 'left';
        ctx.textAlign = 'center';
        ctx.fillText('(' + p0.r.toFixed(2) + ', ' + p0.s.toFixed(3) + ')', sx, sy + 16);
      }
      // End dot
      if (traj.points.length > 1) {
        const pN = traj.points[traj.points.length - 1];
        const [ex, ey] = toCanvas(pN.r, pN.s);
        ctx.fillStyle = traj.color;
        ctx.beginPath();
        ctx.arc(ex, ey, 3, 0, 2 * Math.PI);
        ctx.fill();
      }
    }
  }

  function traceTrajectory(r0, s0, steps, color) {
    const points = [{ r: r0, s: s0 }];
    let r = r0, s = s0;
    for (let i = 0; i < steps; i++) {
      const next = fwStep(r, s);
      if (next.r < 1e-12) break;
      points.push(next);
      r = next.r;
      s = next.s;
    }
    return { points, color };
  }

  cv.addEventListener('click', function(e) {
    const rect = cv.getBoundingClientRect();
    const scaleX = W / rect.width;
    const scaleY = H / rect.height;
    const cx = (e.clientX - rect.left) * scaleX;
    const cy = (e.clientY - rect.top) * scaleY;
    const [r, s] = fromCanvas(cx, cy);

    if (r < 0.01 || r > rMax || s < sMin || s > 1.0 / (1 + r)) return;

    const steps = parseInt(slSteps.value);
    const colors = ['#3b82f6', '#10b981', '#f59e0b', '#8b5cf6', '#ec4899', '#14b8a6'];
    const color = colors[trajectories.length % colors.length];
    trajectories.push(traceTrajectory(r, s, steps, color));
    drawTrajectories();

    const next = fwStep(r, s);
    const regime = next.s > s ? 'stable (plateau)' : 'unstable (jump)';
    phaseInfo.innerHTML = '<div style="font-size:11px;"><strong>Start:</strong> r=' + r.toFixed(3) + ', s=' + s.toFixed(3) + '<br><strong>Regime:</strong> ' + regime + '<br><strong>Steps:</strong> ' + trajectories[trajectories.length-1].points.length + '</div>';
  });

  btnWorst.onclick = function() {
    // Build worst-case trajectory backward from a visible starting point.
    // Starting at r=0.01 gives ~2% growth per step, producing a trajectory
    // of ~200 points that spans the full phase space.
    let r = 0.01, s = 1 - (4/3) * 0.01 + 2 * 0.01 * 0.01;
    const bwPoints = [{ r, s }];
    for (let i = 0; i < 500; i++) {
      const prev = bwStep(r, s);
      if (!prev || prev.r > 1 || prev.r < 0) break;
      bwPoints.push(prev);
      r = prev.r;
      s = prev.s;
    }
    bwPoints.reverse(); // now index 0 = large r (start), last = small r (near optimum)
    trajectories.push({ points: bwPoints, color: '#ef4444' });
    drawTrajectories();
    phaseInfo.innerHTML = '<div style="font-size:11px;"><strong style="color:#ef4444;">Worst-case trajectory</strong><br>Built backward from near (0, 1)<br>' + bwPoints.length + ' points on the stable manifold<br>Hugs monotonicity curve g(r)</div>';
  };

  btnClear.onclick = function() {
    trajectories = [];
    drawTrajectories();
    phaseInfo.innerHTML = '<div style="font-size:11px; color:#888;">Click to start</div>';
  };

  drawBackground();
})();
</script>

<p class="figcap"><strong>Figure 4.</strong> The phase space $(r, s)$ of the Frank-Wolfe dynamics. The red region is the <em>stable regime</em> where contraction worsens at each step (plateaus). The blue region is the <em>unstable regime</em> where jumps happen. The worst-case trajectory (red) convergence to the threshold $g(r)$ from below but stays in the stable regime without crossing into the blue region, inducing slow convergence.</p>

<h2 id="the-key-insight-roll-the-dynamic-backwards">The key insight: roll the dynamic backwards</h2>

<p>So how do you find the initialization that produces the longest possible plateau? The obvious approach, searching forward from many starting points, does not work well. In fact, the dynamics are extremely sensitive to initial conditions. Two starting points that are nearly identical can produce wildly different trajectories; one might plateau for 50 iterations while the other jumps after 10. Moreover, numerical inaccuracies compound very quickly. Just for reference, our longest trajectories that we constructed numerically required <em>several thousand bits</em> of precision; thanks to Julia’s multiprecision capabilities this was easy to do.</p>

<p>So how do you get good initial points $x_0$ that induce slow convergence? The key insight is to reverse the question and dynamics and doing things backwards. Start at a point very close to the optimum compatible with the dynamic from above, do some second-order corrections for errors and then, roll the dynamic backwards. More precisely, our <em>backward construction</em> is as follows: We initialize at a point $(r_T, s_T)$ very close to the optimum with $r_T = \varepsilon \ll 1$ and $s_T \approx 1 - \frac{4}{3}\varepsilon$, which we know lies on the stable trajectory (after some second order corrections). Then we invert the dynamics:</p>

\[\begin{aligned}
s_{t-1} &amp;= (1+r_t)s_t^2 - r_t + \sqrt{(1-s_t^2)(1-(1+r_t)^2 s_t^2)}, \\
r_{t-1} &amp;= r_t / s_{t-1}.
\end{aligned}\]

<p>Each backward step recovers the previous iterate. There is a subtlety here that the root induces two branches; however, one can show that always taking the negative branch is sufficient. Now we unroll the dynamic, until $r_t$ is large enough, basically until some point $t_0$, where $r_{t_0}$ just left the feasible region and then we do one step forward back into the feasible to obtain $r_{t_0-1}$ and the associated $s_{t_0-1}$, which can then be converted back into a valid starting point $x_0$.</p>

<p>This backwards-forward construction works quite well: with 1000-bit arithmetic precision (small errors destroy the stable phase), we can construct worst-case trajectories over thousands of iterations, far beyond what general-purpose PEP methods can reach. Check out the following widget to explore the backward-forward process. The backward pass starts at $r = 0.002$ (near the optimum) and rolls back until $r &gt; 1$. Then the forward pass replays Frank-Wolfe from that start. Note that the browser uses standard 64-bit floating point, while the paper used 1000-bit arithmetic precision to keep trajectories stable over thousands of steps. In the browser, the forward and backward traces will start to diverge after ~50-100 steps, which emphasizes how sensitive the stable manifold is to numerical precision.</p>

<div id="widget-construction" style="margin: 20px 0;">
<div style="background: #f8f9fa; border: 1px solid #e0e0e0; border-radius: 8px; padding: 16px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
  <strong>Backward-then-forward construction</strong>
  <span id="construction-mode" style="font-size: 12px; padding: 2px 8px; border-radius: 10px; background: #fee2e2; color: #991b1b;">Backward</span>
</div>
<div style="display: flex; gap: 16px; flex-wrap: wrap;">
  <div style="flex: 1; min-width: 300px;">
    <canvas id="cv-construction" width="560" height="360" style="width:100%; height:auto; border: 1px solid #e5e7eb; border-radius: 4px;"></canvas>
    <div style="margin-top: 8px;">
      <input type="range" id="sl-time" min="0" max="200" step="1" value="0" style="width:100%;" />
      <div style="display:flex; justify-content:space-between; font-size:11px; color:#888;">
        <span>← Backward (build)</span><span>Forward (verify) →</span>
      </div>
    </div>
  </div>
  <div style="width: 180px; font-size: 13px;">
    <div id="construction-info" style="padding:8px; background:#fff; border-radius:4px; border:1px solid #e5e7eb; margin-bottom:10px; font-size: 12px;">
      Drag the slider to step through the construction.
    </div>
    <div style="margin-bottom: 10px;">
      <label>Trajectory length:</label><br />
      <input type="range" id="sl-traj-len" min="20" max="2000" step="10" value="2000" style="width:100%;" />
      <div id="lbl-traj-len" style="text-align:center;">2000 steps</div>
    </div>
    <button id="btn-animate" style="width:100%; padding:8px; cursor:pointer; border-radius:4px; border:1px solid #ccc; background:#fff; margin-bottom:6px;">▶ Animate</button>
    <button id="btn-reset-construction" style="width:100%; padding:8px; cursor:pointer; border-radius:4px; border:1px solid #ccc; background:#fff;">Reset</button>
    <div style="margin-top:12px; font-size:11px; color:#888;">
      <div><span style="display:inline-block;width:12px;height:2px;background:#ef4444;vertical-align:middle;"></span> Backward (built so far)</div>
      <div><span style="display:inline-block;width:12px;height:2px;background:#3b82f6;vertical-align:middle;"></span> Forward (verified so far)</div>
      <div style="margin-top:4px;">The backward pass builds right-to-left. The forward pass replays left-to-right.</div>
    </div>
  </div>
</div>
</div>
</div>

<script>
(function(){
  // === Widget 3: Backward-then-forward construction ===
  const cv = document.getElementById('cv-construction');
  const ctx = retinaScale(cv);
  const slTime = document.getElementById('sl-time');
  const slLen = document.getElementById('sl-traj-len');
  const lblLen = document.getElementById('lbl-traj-len');
  const btnAnimate = document.getElementById('btn-animate');
  const btnReset = document.getElementById('btn-reset-construction');
  const modeLabel = document.getElementById('construction-mode');
  const info = document.getElementById('construction-info');

  const W = cv.logicalW || cv.width, H = cv.logicalH || cv.height;
  const pad = { l: 55, r: 15, t: 25, b: 40 };
  const pw = W - pad.l - pad.r;
  const ph = H - pad.t - pad.b;

  slLen.oninput = () => { lblLen.textContent = slLen.value + ' steps'; recompute(); };

  // Backward dynamics
  function bwStep(r, s) {
    const X = (1 + r) * s * s - r;
    const inner1 = 1 - s * s;
    const inner2 = 1 - (1 + r) * (1 + r) * s * s;
    if (inner1 < 0 || inner2 < 0) return null;
    const Y = Math.sqrt(inner1 * inner2);
    const sPrev = X + Y;
    if (sPrev < 1e-12) return null;
    return { r: r / sPrev, s: sPrev };
  }

  // Forward dynamics
  function fwStep(r, s) {
    if (r < 1e-12) return { r: 0, s: 0 };
    const rNext = s * r;
    const num = 1 - (1 + r) * (1 + r) * s * s;
    const den = 2 - 2 * s - (2 + r) * r * s * s;
    if (den < 1e-15 || num < 0) return { r: rNext, s: 0 };
    return { r: rNext, s: Math.sqrt(num / den) };
  }

  let bwTraj = [];
  let fwTraj = [];

  function recompute() {
    const N = parseInt(slLen.value);
    // Backward: start near optimum
    const eps = 0.002;
    let r = eps, s = 1 - (4/3) * eps + 2 * eps * eps;
    bwTraj = [{ r, s, err: r * r }];
    for (let i = 0; i < N; i++) {
      const prev = bwStep(r, s);
      if (!prev || prev.r > 1) break;
      bwTraj.push(prev);
      r = prev.r;
      s = prev.s;
    }
    bwTraj.reverse(); // now index 0 = start, last = endpoint

    // Forward: verify from the reconstructed start
    r = bwTraj[0].r;
    s = bwTraj[0].s;
    fwTraj = [{ r, s, err: r * r }];
    for (let i = 0; i < N; i++) {
      const next = fwStep(r, s);
      if (next.r < 1e-14) break;
      fwTraj.push({ r: next.r, s: next.s, err: next.r * next.r });
      r = next.r;
      s = next.s;
    }

    slTime.max = bwTraj.length + fwTraj.length;
    slTime.value = 0;
    draw();
  }

  function draw() {
    const t = parseInt(slTime.value);
    const bwLen = bwTraj.length;
    const totalLen = bwLen + fwTraj.length;

    ctx.clearRect(0, 0, W, H);
    ctx.fillStyle = '#fff';
    ctx.fillRect(0, 0, W, H);

    // Determine axis range from all points
    const allErrs = bwTraj.map(p => p.r * p.r).concat(fwTraj.map(p => p.r * p.r)).filter(e => e > 0);
    const xMax = Math.log10(Math.max(bwTraj.length, fwTraj.length) + 1);
    const yMin = Math.floor(Math.log10(Math.min(...allErrs)) - 0.5);
    const yMax = Math.ceil(Math.log10(Math.max(...allErrs)) + 0.5);

    function toC(lx, ly) {
      return [
        pad.l + (lx / xMax) * pw,
        pad.t + (yMax - ly) / (yMax - yMin) * ph
      ];
    }

    // Grid
    ctx.strokeStyle = '#f0f0f0';
    ctx.lineWidth = 1;
    for (let y = yMin; y <= yMax; y++) {
      const [,cy] = toC(0, y);
      ctx.beginPath(); ctx.moveTo(pad.l, cy); ctx.lineTo(W - pad.r, cy); ctx.stroke();
    }

    // Axes
    ctx.strokeStyle = '#333'; ctx.lineWidth = 1.5;
    ctx.beginPath();
    ctx.moveTo(pad.l, pad.t); ctx.lineTo(pad.l, H - pad.b); ctx.lineTo(W - pad.r, H - pad.b);
    ctx.stroke();

    ctx.fillStyle = '#333'; ctx.font = '12px sans-serif'; ctx.textAlign = 'center';
    ctx.fillText('iteration', W / 2, H - 5);
    ctx.save(); ctx.translate(14, H / 2); ctx.rotate(-Math.PI / 2);
    ctx.fillText('log₁₀(error)', 0, 0); ctx.restore();

    // Tick labels
    ctx.font = '10px sans-serif'; ctx.textAlign = 'center';
    for (let x = 0; x <= xMax; x += 0.5) {
      const [cx, cy] = toC(x, yMin);
      ctx.fillText(x.toFixed(1), cx, cy + 14);
    }
    ctx.textAlign = 'right';
    for (let y = yMin; y <= yMax; y++) {
      const [cx, cy] = toC(0, y);
      ctx.fillText(y.toString(), cx - 6, cy + 4);
    }

    // Reference line: 1/t^2
    ctx.strokeStyle = 'rgba(80,80,80,0.7)'; ctx.lineWidth = 2; ctx.setLineDash([8, 4]);
    ctx.beginPath();
    for (let i = 1; i < bwTraj.length; i++) {
      const lx = Math.log10(i);
      const ly = Math.log10(1.0 / (i * i));
      const [cx, cy] = toC(lx, ly);
      if (cy < pad.t || cy > H - pad.b) continue;
      i === 1 ? ctx.moveTo(cx, cy) : ctx.lineTo(cx, cy);
    }
    ctx.stroke(); ctx.setLineDash([]);

    // Phase 1: backward (show points being revealed right-to-left)
    const bwShow = Math.min(t, bwLen);
    if (bwShow > 0) {
      // Show the backward trajectory: reveal from end toward start
      ctx.strokeStyle = '#ef4444'; ctx.lineWidth = 2.5; ctx.globalAlpha = 0.8;
      ctx.beginPath();
      const startIdx = bwLen - bwShow;
      for (let i = startIdx; i < bwLen; i++) {
        const err = bwTraj[i].r * bwTraj[i].r;
        if (err <= 0) continue;
        const lx = Math.log10(i + 1);
        const ly = Math.log10(err);
        const [cx, cy] = toC(lx, ly);
        if (cy < pad.t || cy > H - pad.b) continue;
        i === startIdx ? ctx.moveTo(cx, cy) : ctx.lineTo(cx, cy);
      }
      ctx.stroke(); ctx.globalAlpha = 1.0;

      // Current point marker
      const curIdx = bwLen - bwShow;
      const curErr = bwTraj[curIdx].r * bwTraj[curIdx].r;
      if (curErr > 0) {
        const [cx, cy] = toC(Math.log10(curIdx + 1), Math.log10(curErr));
        ctx.fillStyle = '#ef4444';
        ctx.beginPath(); ctx.arc(cx, cy, 5, 0, 2 * Math.PI); ctx.fill();
      }
    }

    // Phase 2: forward verification
    const fwShow = Math.max(0, t - bwLen);
    if (fwShow > 0) {
      ctx.strokeStyle = '#3b82f6'; ctx.lineWidth = 2.5; ctx.globalAlpha = 0.8;
      ctx.beginPath();
      for (let i = 0; i < fwShow && i < fwTraj.length; i++) {
        const err = fwTraj[i].r * fwTraj[i].r;
        if (err <= 0) continue;
        const lx = Math.log10(i + 1);
        const ly = Math.log10(err);
        const [cx, cy] = toC(lx, ly);
        if (cy < pad.t || cy > H - pad.b) continue;
        i === 0 ? ctx.moveTo(cx, cy) : ctx.lineTo(cx, cy);
      }
      ctx.stroke(); ctx.globalAlpha = 1.0;

      // Current point
      const ci = Math.min(fwShow - 1, fwTraj.length - 1);
      const curErr = fwTraj[ci].r * fwTraj[ci].r;
      if (curErr > 0) {
        const [cx, cy] = toC(Math.log10(ci + 1), Math.log10(curErr));
        ctx.fillStyle = '#3b82f6';
        ctx.beginPath(); ctx.arc(cx, cy, 5, 0, 2 * Math.PI); ctx.fill();
      }
    }

    // Mode indicator
    if (t <= bwLen) {
      modeLabel.textContent = 'Backward';
      modeLabel.style.background = '#fee2e2'; modeLabel.style.color = '#991b1b';
      info.innerHTML = '<strong>Step ' + bwShow + '/' + bwLen + '</strong><br>Building backward from r=0.001.<br>Stops when r > 1.<br>Current r = ' + (bwShow > 0 ? bwTraj[bwLen - bwShow].r.toFixed(6) : '—');
    } else {
      modeLabel.textContent = 'Forward';
      modeLabel.style.background = '#dbeafe'; modeLabel.style.color = '#1e40af';
      const fi = Math.min(fwShow - 1, fwTraj.length - 1);
      info.innerHTML = '<strong>Step ' + fwShow + '/' + fwTraj.length + '</strong><br>Verifying trajectory forward from reconstructed start.<br>Current r = ' + fwTraj[fi].r.toFixed(4);
    }
  }

  slTime.oninput = draw;

  let animId = null;
  btnAnimate.onclick = function() {
    if (animId) { cancelAnimationFrame(animId); animId = null; btnAnimate.textContent = '▶ Animate'; return; }
    btnAnimate.textContent = '⏸ Pause';
    slTime.value = 0;
    function step() {
      const v = parseInt(slTime.value);
      if (v >= parseInt(slTime.max)) { animId = null; btnAnimate.textContent = '▶ Animate'; return; }
      slTime.value = v + 1;
      draw();
      animId = requestAnimationFrame(step);
    }
    animId = requestAnimationFrame(step);
  };

  btnReset.onclick = function() {
    if (animId) { cancelAnimationFrame(animId); animId = null; }
    btnAnimate.textContent = '▶ Animate';
    slTime.value = 0;
    recompute();
  };

  recompute();
})();
</script>

<p class="figcap"><strong>Figure 5.</strong> The backward-then-forward construction. The backward pass (red) starts near the optimum and reconstructs the worst-case initialization by inverting the dynamics. The forward pass (blue) verifies the trajectory by running Frank-Wolfe from the reconstructed start forward; the dashed line is the $1/t^2$ target. The red and blue line overlap perfectly, until they break apart due to lost precision.</p>

<h2 id="the-theorem">The theorem</h2>

<p>This is all fine but so far everything we did is <em>numerical</em>. We are however interested in an actual analytical proof. To obtain such a proof, we follow exactly the same logic as the numerical backward construction: going backwards. The key technical step is showing that if the contraction factor satisfies</p>

\[s_t = 1 - \frac{4}{3} r_t + c_t r_t^2\]

<p>with $c_t \in [1, \frac{5}{2}]$, then after a backward step $c_{t-1}$ stays in $[1, \frac{5}{2}]$. This means the entire trajectory remains on the stable manifold. By induction from the endpoint, the trajectory satisfies $s_t \geq 1 - \frac{4}{3} r_t$ for all $t$, which gives the bound $r_t \geq r_0 / (1 + \frac{8}{3} r_0 t)$ and therefore:</p>

<p class="mathcol"><strong>Theorem.</strong> <em>There exists a smooth and strongly convex set $\mathcal{X}$ and a smooth and strongly convex function $f$ such that for all $T \in \mathbb{N}$ there exists a starting point $x_0 \in \mathcal{X}$ with</em>
\(f(x_t) - f(x^*) \geq \Omega\left(\frac{1}{t^2}\right)\)
<em>for all $t = 1, \ldots, T$. Equivalently, $T = \Omega(1/\sqrt{\varepsilon})$.</em></p>

<p>Two features of this lower bound are worth highlighting:</p>

<p><strong>It is dimension-free.</strong> Because the iterates stay in a two-dimensional subspace, the lower bound holds in any dimension $d \geq 2$. This is in contrast to the classical lower bounds by Jaggi (2013) <a href="http://proceedings.mlr.press/v28/jaggi13.html">[J13]</a> (see also Lan (2013) <a href="https://arxiv.org/abs/1309.5550">[L13]</a>) on the simplex, which require $t &lt; d$ as well as the complementary result by Grimmer and Liu <a href="https://arxiv.org/abs/2602.22608">[GL26]</a> for strongly convex sets.</p>

<p><strong>Smoothness of the set does not help.</strong> The unit ball is as smooth as a constraint set can be. The lower bound shows that even with this additional regularity, the $\mathcal{O}(1/\sqrt{\varepsilon})$ rate cannot be improved; the strongly convex set in Grimmer and Liu <a href="https://arxiv.org/abs/2602.22608">[GL26]</a> is non-smooth.</p>

<h2 id="what-this-tells-us-about-frank-wolfe">What this tells us about Frank-Wolfe</h2>

<p>This result settles the convergence landscape for Frank-Wolfe on strongly convex sets. Here is where things stand now:</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">Setting</th>
      <th style="text-align: center">Upper bound</th>
      <th style="text-align: center">Lower bound</th>
      <th style="text-align: center">Gap?</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left">$f$ SC, $\mathcal{X}$ SC, optimizer in interior</td>
      <td style="text-align: center">$\mathcal{O}(\log \frac{1}{\varepsilon})$</td>
      <td style="text-align: center">$\Omega(\log \frac{1}{\varepsilon})$</td>
      <td style="text-align: center"><strong>Tight</strong></td>
    </tr>
    <tr>
      <td style="text-align: left">$f$ SC, $\mathcal{X}$ SC, optimizer on boundary</td>
      <td style="text-align: center">$\mathcal{O}(\frac{1}{\sqrt{\varepsilon}})$</td>
      <td style="text-align: center">$\Omega(\frac{1}{\sqrt{\varepsilon}})$</td>
      <td style="text-align: center"><strong>Tight</strong> (this paper)</td>
    </tr>
    <tr>
      <td style="text-align: left">$f$ convex, $\mathcal{X}$ convex</td>
      <td style="text-align: center">$\mathcal{O}(\frac{1}{\varepsilon})$</td>
      <td style="text-align: center">$\Omega(\frac{1}{\varepsilon})$</td>
      <td style="text-align: center"><strong>Tight</strong></td>
    </tr>
  </tbody>
</table>

<p>In a nutshell, the position of the optimizer is a genuine structural barrier, not an artifact of the analysis. When the optimizer lies on the boundary, the rate drops from exponential to polynomial.</p>

<p>Several questions remain open. For example:</p>

<ul>
  <li><strong>Can FW variants break through?</strong> Away-step, pairwise, and fully-corrective variants are designed for polytopes. Can analogous variants for strongly convex sets beat $\mathcal{O}(1/\sqrt{\varepsilon})$? We know that at least in the high-dimensional regime this is not possible due to <a href="https://arxiv.org/abs/2602.22608">[GL26]</a>. At the same time often acceleration can be obtained beyond the dimension <a href="https://arxiv.org/abs/1906.07867">[DCP20]</a>, <a href="https://arxiv.org/abs/2102.06806">[CDLP21]</a>, so it is not ruled out that beyond $n/2$ or $n$, we can find a faster algorithm.</li>
  <li><strong>Smoothed complexity.</strong> Our numerical experiments show that small perturbations to the initialization kick the trajectory off the stable manifold, leading to much faster convergence. Can we obtain better rates in a smoothed complexity sense or can we establish an $\Omega(1/\sqrt{\varepsilon})$ smoothed-complexity lower bound?</li>
  <li><strong>Other algorithms.</strong> The backward construction methodology — start from the end, invert the dynamics — seems applicable beyond Frank-Wolfe. It should work whenever the algorithm’s dynamics are locally invertible and exhibit sensitivity to initial conditions.</li>
</ul>

<h2 id="sneak-peek-beyond-strongly-convex-sets">Sneak Peek: beyond strongly convex sets</h2>

<p>Our analysis can also be extended to uniformly convex sets and sharp functions. This result was obtained based on our original argument using our <a href="https://arxiv.org/pdf/2603.15914">Agentic Researcher</a> (see Section 4.4 in <a href="https://arxiv.org/pdf/2603.15914">[ZPRP26]</a>), an agentic AI co-creation framework. If you are interested in this you can check the <a href="/blog/agentic-researcher/">recent blog post</a> on the topic.</p>

<h2 id="references">References</h2>

<p>[BCCHHKMP25] Braun, G., Carderera, A., Combettes, C.W., Hassani, H., Karbasi, A., Mokhtari, A., &amp; Pokutta, S. (2025). Conditional Gradient Methods: From Core Principles to AI Applications. <em>MOS-SIAM Series on Optimization</em>. <a href="https://doi.org/10.1137/1.9781611978568">doi</a></p>

<p>[CC68] Canon, M.D. &amp; Cullum, C.D. (1968). A Tight Upper Bound on the Rate of Convergence of Frank-Wolfe Algorithm. <em>SIAM Journal on Control</em>, 6(4), 509–516.</p>

<p>[CDLP21] Carderera, A., Diakonikolas, J., Lin, C.Y., &amp; Pokutta, S. (2021). Parameter-Free Locally Accelerated Conditional Gradients. <em>ICML 2021</em>. <a href="https://arxiv.org/abs/2102.06806">arxiv</a></p>

<p>[DCP20] Diakonikolas, J., Carderera, A., &amp; Pokutta, S. (2020). Locally Accelerated Conditional Gradients. <em>AISTATS 2020</em>. <a href="https://arxiv.org/abs/1906.07867">arxiv</a></p>

<p>[GH15] Garber, D. &amp; Hazan, E. (2015). Faster Rates for the Frank-Wolfe Method over Strongly-Convex Sets. <em>ICML 2015</em>. <a href="http://proceedings.mlr.press/v37/garbera15.html">paper</a></p>

<p>[GL26] Grimmer, B. &amp; Liu, N. (2026). Lower Bounds for Linear Minimization Oracle Methods Optimizing over Strongly Convex Sets. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/2602.22608">arxiv</a></p>

<p>[HDZRSP26] Halbey, J., Deza, D., Zimmer, M., Roux, C., Stellato, B., &amp; Pokutta, S. (2026). Lower Bounds for Frank-Wolfe on Strongly Convex Sets. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/2602.04378">arxiv</a></p>

<p>[J13] Jaggi, M. (2013). Revisiting Frank-Wolfe: Projection-Free Sparse Convex Optimization. <em>ICML 2013</em>. <a href="http://proceedings.mlr.press/v28/jaggi13.html">paper</a></p>

<p>[L13] Lan, G. (2013). The Complexity of Large-Scale Convex Programming under a Linear Optimization Oracle. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/1309.5550">arxiv</a></p>

<p>[LG24] Luner, A. &amp; Grimmer, B. (2024). Performance Estimation for Smooth and Strongly Convex Sets. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/2410.14811">arxiv</a></p>

<p>[NY83] Nemirovski, A.S. &amp; Yudin, D.B. (1983). Problem Complexity and Method Efficiency in Optimization. <em>Wiley</em>.</p>

<p>[ZPRP26] Zimmer, M., Pelleriti, N., Roux, C., &amp; Pokutta, S. (2026). The Agentic Researcher: A Practical Guide to AI-Assisted Research in Mathematics and Machine Learning. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/2603.15914">arxiv</a></p>]]></content><author><name>Sebastian Pokutta</name></author><category term="research" /><category term="optimization" /><category term="Frank-Wolfe" /><category term="lower bounds" /><category term="strongly convex sets" /><summary type="html"><![CDATA[TL;DR: This is a short summary of our paper Lower Bounds for Frank-Wolfe on Strongly Convex Sets by Jannis Halbey, Daniel Deza, Max Zimmer, Christophe Roux, Bartolomeo Stellato, and Sebastian Pokutta. We prove a matching $\Omega(1/\sqrt{\varepsilon})$ lower bound for Frank-Wolfe on strongly convex sets, showing that Garber and Hazan’s 2015 upper bound is tight. The construction of the lower bound deviates from the standard route quite a bit: instead of searching for worst-case initializations, we build them backward from the optimum.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" /><media:content medium="image" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">The Agentic Researcher</title><link href="http://www.pokutta.com/blog/agentic-researcher/" rel="alternate" type="text/html" title="The Agentic Researcher" /><published>2026-03-18T00:00:00+01:00</published><updated>2026-03-18T00:00:00+01:00</updated><id>http://www.pokutta.com/blog/agentic-researcher</id><content type="html" xml:base="http://www.pokutta.com/blog/agentic-researcher/"><![CDATA[<p><em>TL;DR: This is a summary of our recent paper <a href="https://arxiv.org/abs/2603.15914">The Agentic Researcher: A Practical Guide to AI-Assisted Research in Mathematics and Machine Learning</a> by <a href="https://maxzimmer.org/">Max Zimmer</a>, <a href="https://www.pelleriti.org/">Nico Pelleriti</a>, <a href="https://christopheroux.de/">Christophe Roux</a>, and <a href="https://www.pokutta.com/">Sebastian Pokutta</a> augmented with some personal perspectives and thoughts. The main point is not that AI can now “do research” in some vague science-fiction sense. The more useful point is that, with the right workflow, general CLI coding agents can already act like research associates: they can write proofs, formulate conjectures, implement ideas, run experiments, document failures, verify intermediate claims, and keep going for hours, while the researcher remains responsible for idea generation, creativity, direction, judgment, and final verification.</em></p>

<!--more-->

<style>
.callout{border-left:4px solid #2563eb;border-right:4px solid #2563eb;background:#f5f7ff;padding:12px 16px;margin:1em 0}
</style>

<h2 id="introduction">Introduction</h2>

<p>Over the last year, the discussion around AI and research has become increasingly confused. We jump between olympiad medals, benchmark wins, flashy demos, and vague claims about autonomous science and “fully-automatic end-to-end research pipelines”. Many of these flashy claims do not hold up or do not generalize; and most importantly in my book this should also not be the point. The useful question for me is a different, more practical one:</p>

<blockquote>
  <p>If I am an actual researcher in, say, Math or ML, how can I use these systems in my daily work?</p>
</blockquote>

<p>That is the question our paper tries to (partially) answer and in some sense it is an amalgamation of research efforts, best practices, and approaches that we have collected over the last roughly 1.5 years in the MATH+ project “Agentic AI in Mathematics”, although our learnings go significantly beyond mathematics.</p>

<p>The backdrop is, of course, quite remarkable with several high-profile achievements. Systems such as <a href="https://www.nature.com/articles/s41586-023-06747-5">AlphaGeometry</a> [AG], <a href="https://www.nature.com/articles/s41586-025-09833-y">AlphaProof</a> [AP], <a href="https://arxiv.org/abs/2506.13131v1">AlphaEvolve</a> [AE], and more recently <a href="https://arxiv.org/abs/2602.10177">Aletheia</a> [ALET] have pushed AI much further into mathematical reasoning and discovery than most people expected only a short while ago. The picture is broader than just these headline systems and includes AlphaGeometry2 [AG2], Aristotle [ARI], Mathematical Exploration and Discovery at Scale [MEDS], and the autonomous Aletheia follow-up on First Proof [ALET2]. On the benchmark side, there is now a growing ecosystem around research-level evaluation, e.g., <a href="https://arxiv.org/abs/2602.05192">First Proof</a> [FP], <a href="https://arxiv.org/abs/2411.04872">FrontierMath</a> [FM], and <a href="https://arxiv.org/abs/2505.12575">RealMath</a> [RM]. At the same time, there is a parallel line of work around agentic experimentation and end-to-end “scientific” pipelines, such as <a href="https://arxiv.org/abs/2408.06292">The AI Scientist</a> [AIS], <a href="https://arxiv.org/abs/2410.05080">ScienceAgentBench</a> [SAB], Karpathy’s <a href="https://github.com/karpathy/autoresearch">autoresearch</a> [AR], and, in a somewhat different flavor, FunSearch [FS]. There is also now a small but growing literature on mathematicians and researchers using these systems in practice, e.g., Avigad [AV], Henkel [H], Dobriban [D], Liu et al. [LCP], and Carbone [C].</p>

<p>All of this is very interesting and inspiring, but the main question remains: How do we <em>unlock</em> “AI for research” in a <em>practical</em> way that supports day-to-day research activities? Most researchers do not want to build a giant bespoke<sup id="fnref:1"><a href="#fn:1" class="footnote" rel="footnote" role="doc-noteref">1</a></sup> discovery system from scratch. They want to know which tools are already useful <em>today</em>, where the actual leverage is, and which guardrails are needed so that the system does not quietly produce nonsense while sounding very confident. Moreover, they need support in <em>open-ended</em> research endeavors and not merely round-trip IMO problems, which have “one correct answer”. In some sense, the core claim of our paper is simple:</p>

<div class="callout">
<strong>Takeaway.</strong> The real bottleneck is not "having an AI", but having a disciplined and repeatable workflow that turns a strong reasoning LLM into something closer to a research associate.
</div>

<p><strong>NB.</strong> I would like to stress one point here, as this is often confused. Neither do we claim nor aim for fully-automatic end-to-end research. On the contrary, we look at the use of AI as augmentation. Not oracle. Not autopilot. Not replacement. A research associate. Moreover, we are interested in AI systems for <em>open-ended</em> research questions rather than benchmark problems.</p>

<h2 id="refutation-and-verification">Refutation and verification</h2>

<p>Our approach operationalizes (or better: tries to operationalize) a very old and, in my view, still very fundamental scientific principle: most attempts are wrong. That sounds banal, but AI systems used “straight-up” have the tendency to produce enough wrong things fast enough (i.e., the failure rate went down but the speed went up, so that the inter-arrival rate of blow-ups is roughly constant) that it erodes trust in the system. Moreover, there is a total lack of calibration: the AI typically does not know where it is unsure and where it could be wrong; in an optimal world the system would attach a well-calibrated probability of correctness to its output, but that seems out of reach, at least at the moment. This has real consequences for how one should use these systems. If an agent only writes polished explanations, tidy derivations, or plausible-looking code, then it is mostly helping you produce surface area: it looks good but has little substance. What actually matters in research is the ability to rule out bad ideas, broken proof strategies, buggy implementations, and misleading empirical wins quickly and cleanly: we need conjectures, refutation, and falsifiability, which brings us straight to Popper (see <a href="https://plato.stanford.edu/entries/popper/">Stanford Encyclopedia of Philosophy entry on Karl Popper</a> [POP]) and his philosophy (see Britannica’s discussion of <a href="https://www.britannica.com/topic/philosophy-of-science/Eliminativism-and-falsification">eliminativism and falsification</a> [FAL]). No worries, we will skip the philosophy discourse today. The key point is that it is not indulgence but naturally induces a working research habit underneath it: propose something, expose it to failure, and only keep it around provisionally if it survives. Now what survives might still be wrong, but much less so, and that is then where the Human-AI Co-Creativity [HP] takes place.</p>

<p>In practice, this means the agent needs tools for both <em>refutation</em> and <em>verification</em>. That can be a numerical sanity check, a brute-force search for a counterexample, a symbolic derivation, a randomized stress test, a Julia script, a Python script, or some small utility wired into a simulator, etc. Today this is more straightforward than ever: tons of very strong, localized package managers, such as <code class="language-plaintext highlighter-rouge">bun</code>, <code class="language-plaintext highlighter-rouge">npm</code>, <code class="language-plaintext highlighter-rouge">uv</code>, <code class="language-plaintext highlighter-rouge">cargo</code>, <code class="language-plaintext highlighter-rouge">Pkg</code>, that align perfectly with agents in CLIs being able to write small refutation and verification scripts against their own reasoning to harden it. Once the agent can actually run those checks, we are no longer asking it merely to <em>talk</em> about a hypothesis. We are asking it to try to break it.</p>

<p>This makes a fundamental difference and the consistency and correctness of the output changes dramatically. Verification catches arithmetic mistakes, implementation bugs, and overclaimed results. Refutation-oriented checks kill wrong turns early and force the system to document why an idea failed. In my experience, this is exactly where these agents start becoming useful for real research: not when they sound convincing, but when they can help eliminate what is false.</p>

<h2 id="five-levels-of-ai-integration">Five levels of AI integration</h2>

<p>To put things into perspective, inspired by the taxonomy in [HP], we distinguish five levels of AI integration, starting at zero, “research without AI”, which is still the default mode, probably one of the most robust modes out there, and the all-important baseline.</p>

<table>
  <thead>
    <tr>
      <th style="text-align: right">Level</th>
      <th>Name</th>
      <th>What it looks like</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: right">0</td>
      <td>Classical</td>
      <td>Normal research without AI: LaTeX, code, math software, papers, whiteboards, coffee, despair, and hopefully eventually progress.</td>
    </tr>
    <tr>
      <td style="text-align: right">1</td>
      <td>Consultant</td>
      <td>The chatbot regime: explanations, brainstorming, literature pointers, debugging, and other targeted questions. Useful, but episodic and reactive.</td>
    </tr>
    <tr>
      <td style="text-align: right">2</td>
      <td>Typist</td>
      <td>The AI writes code or text for you, but does not really execute or iterate. Think completion, drafting, or small prompt-based generation.</td>
    </tr>
    <tr>
      <td style="text-align: right">3</td>
      <td>Collaborator</td>
      <td>CLI coding agents such as <a href="https://code.claude.com/docs/en/overview">Claude Code</a> [CC], <a href="https://openai.com/codex/">Codex CLI</a> [CX], <a href="https://github.com/anomalyco/opencode">OpenCode</a> [OC], or <a href="https://geminicli.com/">Gemini CLI</a> [GC] can read files, edit them, run code, inspect outputs, and iterate inside a project context. At this level, the human says <em>what</em> to do and the agent handles much of <em>how</em> to do it.</td>
    </tr>
    <tr>
      <td style="text-align: right">4</td>
      <td>Research associate</td>
      <td>The researcher provides the problem, context, constraints, codebase, prior attempts, and evaluation criteria. The agent then runs an actual research loop: <code class="language-plaintext highlighter-rouge">explore -&gt; plan -&gt; implement -&gt; evaluate -&gt; analyze -&gt; record -&gt; commit -&gt; iterate</code>, with the human stepping in periodically for steering, review, and correction.</td>
    </tr>
  </tbody>
</table>

<p>The key difference from Level 3 is that the agent does not stop after every experiment to ask what to do next. It continues autonomously within a carefully bounded workflow, and the human intervenes periodically for steering, review, and correction. This is exactly the boundary point where “AI as tool” becomes “AI as research associate”.</p>

<div class="center">
  <img src="http://www.pokutta.com/blog/assets/agentic-researcher/agentic-inputs-overview.svg" alt="Overview of the main inputs to an agentic research setup" style="width:99%" />
  <p style="clear: both;"></p>
</div>
<p class="figcap"><strong>Figure 1.</strong> A useful way to think about the research-associate setup: the agent gets a concrete research question, the relevant tools and data, and the prior work or domain knowledge needed to operate in context.</p>

<h2 id="the-actual-contribution-is-the-workflow">The actual contribution is the workflow</h2>

<p>While the taxonomy is useful, the important part of the paper is the actual workflow. The paper’s main claim is that one does <em>not</em> need a highly specialized custom-built system to get meaningful agentic research behavior. Instead, one can take strong existing CLI agents and wrap them in a disciplined environment:</p>

<ul>
  <li>persistent instructions</li>
  <li>sandboxed execution</li>
  <li>a structured report</li>
  <li>a live <code class="language-plaintext highlighter-rouge">TODO.md</code></li>
  <li>Git-based experiment tracking</li>
  <li>a set of explicit methodological rules</li>
</ul>

<p>The result is a system that is much less magical than the hype suggests, but also much more useful in practice. It just works. And it is highly customizable to the research needs of the individual researcher. It is <em>your</em> tool.</p>

<p>The workflow in the paper runs inside a sandboxed container, keeps all progress in inspectable artifacts such as <code class="language-plaintext highlighter-rouge">report.tex</code> (which I, for example, often have open simultaneously in VS Code so I can regularly compile the PDF and preview it) and <code class="language-plaintext highlighter-rouge">TODO.md</code>, and can scale from a laptop to multi-node Slurm experiments. The longest autonomous session reported in the paper ran for more than 20 hours; we have much longer sessions with repeated calls to downstream tools for subproblems. That sounds dramatic, but the important part is not the wall-clock number. The important part is that the agent keeps a disciplined experimental loop alive over long horizons without silently discarding context, changing metrics, or forgetting what it already tried. I would go one step further: this kind of “external memory” is one of the main reasons long sessions are usable at all. In other words: the secret sauce is not some mystical “agent architecture”. It is mostly methodology (e.g., refutation and verification) and workflow (e.g., persistency); granted, for high-profile applications we do rely on SOTA LLMs (current favorites being Claude Opus 4.6 and GPT-5.4).</p>

<div class="center">
  <img src="http://www.pokutta.com/blog/assets/agentic-researcher/agentic-workflow-overview.png" alt="Overview of the agentic research workflow" style="width:99%" />
  <p style="clear: both;"></p>
</div>
<p class="figcap"><strong>Figure 2.</strong> The workflow view from the paper: persistent instructions, a CLI agent running inside a sandbox, and an explicit experiment loop with reporting, verification, and Git-based memory.</p>

<h2 id="the-commandments">The commandments</h2>

<p>We have encoded the “rules” that guide the systems’ behavior as “ten commandments”, which sounds a bit theatrical but follows the <em>language escalation paradigm</em> to harden rule-following; yes, it does make a difference. The underlying rule-of-thumb is: if a behavior matters, make it explicit. Do not rely on vague hopes like “the model will probably know what I mean”. I will not list all ten in full here and I grouped them by the overarching goal. In the following the term <em>experiment</em> is used broadly, to mean one agentic-loop iteration, e.g., proof attempt, one numerical experiment, one design attempt, etc.</p>

<p><strong>1. Integrity and trust.</strong></p>

<p>The first group is basic research hygiene:</p>

<ul>
  <li>do not promise work and then quietly skip it</li>
  <li>do not change the evaluation because the original setup looks inconvenient</li>
  <li>do not invent bibliography</li>
</ul>

<p>This sounds trivial until you actually let these systems run for hours. Then it stops sounding trivial very quickly.</p>

<p><strong>2. Autonomy and efficiency.</strong></p>

<p>The second group is about making the agent actually useful rather than merely interactive:</p>

<ul>
  <li>finish autonomous work before reporting back</li>
  <li>treat crashes as bugs unless proven otherwise</li>
</ul>

<p>This addresses one of the most common failure modes: the agent stops too early, asks for permission too often, or mistakes implementation bugs for failed research ideas. “Dangerously skipping all permissions” does not solve your problem here; you need to “unleash” the agent.</p>

<p><strong>3. Scientific rigor.</strong></p>

<p>The third group is the most important “research-specific” one:</p>

<ul>
  <li>change one variable per experiment</li>
  <li>evaluate in tiers</li>
  <li>bound the best-case improvement before celebrating a heuristic</li>
</ul>

<p>The “one variable per experiment” rule is particularly powerful. It sounds almost embarrassingly obvious, but it prevents a huge amount of pseudo-progress and conflation of factors. If two things change and the metric improves, you often do not know what actually helped.</p>

<p>The staged evaluation rule is equally important. A fast sanity check is for catching bugs, not for drawing conclusions. This is exactly the kind of thing researchers understand intuitively and agents do not unless told very explicitly.</p>

<p><strong>4. Documentation and reproducibility.</strong></p>

<p>The last group is what makes the whole system robust over long sessions:</p>

<ul>
  <li>record everything</li>
  <li>verify before claiming</li>
</ul>

<p>This means that failed experiments go into the report as well, not only the good-looking ones. It also means that a claim is not “explained” into existence but should be stress-tested, checked numerically, or challenged through a verification script whenever possible. Everything not fully “verified” is considered “unverified” and “unproven”.</p>

<p>The three meta-principles behind this go back to our refutation discussion at the beginning:</p>

<ol>
  <li>explicit over implicit</li>
  <li>falsifiable over aspirational</li>
  <li>failure-driven over theory-driven</li>
</ol>

<p>“Be rigorous” is not a usable instruction. “Change exactly one variable per experiment” is. Similarly, “failure-driven over theory-driven” ensures that things are constantly stress-tested and hardened, rather than endless proof-attempts over pages where the mistake is in the assumptions or right at the beginning.</p>

<h2 id="three-sample-case-studies">Three sample case studies</h2>

<p>The paper contains six case studies across ML and mathematics. I will only discuss three here, because they already show most of the pattern; for the others, check the paper. All figures below marked with <em>[sic]</em> are <em>verbatim, unaltered output</em> from the agent.</p>

<h3 id="1-optimizer-exploration-for-llm-pretraining">1. Optimizer exploration for LLM pretraining</h3>

<p>The first case study starts from a concrete and very ML-style question. <a href="https://arxiv.org/abs/1711.05101">AdamW</a> uses two extra buffers per parameter, while <a href="https://kellerjordan.github.io/posts/muon">Muon</a> only uses one. The natural question is whether the spare memory budget can be used to make Muon better.</p>

<p>This is exactly the kind of problem where our agentic workflow shines: there is a nontrivial design space, the experiments are expensive, and the researcher mostly wants disciplined exploration rather than one-shot “creativity”. For this case study, the agent ran more than 40 experiments, changing one thing at a time, and discovered two largely independent improvements:</p>

<ul>
  <li>a normalization before orthogonalization</li>
  <li>weight decay for Muon’s matrix parameters</li>
</ul>

<p>The combined result is about a <em>5% improvement in validation perplexity over Muon</em> and about <em>8% over AdamW</em> at the same memory budget, i.e., basically for free. Even more interestingly, the agent also found a nearly matching zero-overhead variant. This application demonstrates what Level 4 autonomy looks like in a compute-heavy setting: multiple GPUs, long runs, careful ablations, literature checks, and a report that keeps all of this coherent over a session lasting more than 20 hours.</p>

<div class="center">
  <img src="http://www.pokutta.com/blog/assets/agentic-researcher/agentic-cli-session.png" alt="Terminal view of a long-running agentic research session" style="width:99%" />
  <p style="clear: both;"></p>
</div>
<p class="figcap"><strong>Figure 3.</strong> A terminal view from a long-running session. Multiple training jobs, timed checks, and verification tasks stay alive in parallel while the agent keeps an inspectable record of what is running.</p>

<div class="center">
  <img src="http://www.pokutta.com/blog/assets/agentic-researcher/paper_final_perplexity.svg" alt="Validation perplexity for Muon variants and baselines" style="width:99%" />
  <p style="clear: both;"></p>
</div>
<p class="figcap"><strong>Figure 4.</strong> [sic] Final validation perplexity for the optimizer exploration case study. Lower is better; the best learned variant improves over both Muon and AdamW at the same memory budget.</p>

<h3 id="2-weight-reconstruction-in-llm-pruning">2. Weight reconstruction in LLM pruning</h3>

<p>The second case study, while still in the LLM space, highlights a different aspect that we encountered quite regularly: <em>serendipity</em>. The original task was to fix a broken pruning-mask idea. The agent eventually concluded that the original approach was mathematically flawed. But instead of just discarding the project and moving on, it analyzed <em>why</em> the approach failed. During that analysis, it observed a strong imbalance in post-layer activation distortion after pruning and proposed a very simple reconstruction step to compensate for it.</p>

<p>The resulting method is almost comically lightweight:</p>

<ul>
  <li>about 10 lines of code</li>
  <li>less than 1% computational overhead</li>
  <li>no hyperparameter tuning</li>
</ul>

<p>Yet it reduces perplexity by <em>18–50%</em> across multiple model scales, architectures, and pruning methods, and captures about <em>92% of the gain of a least-squares oracle reconstruction</em>.</p>

<div style="text-align:center; margin-bottom: 20px;">
  <img src="http://www.pokutta.com/blog/assets/agentic-researcher/scaling_model_size.svg" alt="Relative pruning reconstruction improvement across model sizes" style="width:49%;" />
  <img src="http://www.pokutta.com/blog/assets/agentic-researcher/scaling_absolute_ppl.svg" alt="Absolute perplexity comparison for pruning reconstruction" style="width:49%;" />
  <p style="clear: both;"></p>
</div>
<p class="figcap"><strong>Figure 5.</strong> [sic] The pruning reconstruction idea transfers across model scales. Left: relative improvement versus model size. Right: absolute perplexity comparison against the baseline.</p>

<h3 id="3-frank-wolfe-lower-bounds-on-uniformly-convex-sets">3. Frank-Wolfe lower bounds on uniformly convex sets</h3>

<p>The third case study comes from optimization, more precisely (as you might have guessed) from the Frank-Wolfe and conditional gradients domain. The problem <del>is</del> was an open lower-bound question for vanilla Frank-Wolfe on uniformly convex sets. For $p$-uniformly convex sets, an upper bound of $\mathcal{O}(1/T^{p/(p-1)})$ was known due to [KDP21], but no matching lower bound was available in the relevant regime; this became in particular striking after the recent lower bounds for strongly convex sets (see [HDZRSP26] and [GL26]).</p>

<p>The agent first tried to generalize an existing high-dimensional lower-bound construction and failed. Importantly, this failure was documented rather than hidden. It then pivoted to a more direct dynamical analysis of the Frank-Wolfe iterates on $\ell_p$-balls, used numerical exploration to identify the right pattern, and eventually assembled a proof showing a lower bound of</p>

\[\Omega(1/T^{p/(p-1)})\]

<p>for $p \geq 3$, matching the known upper bound in that regime. This particular application touched on each step of the research loop for mathematics:</p>

<ol>
  <li>try a proof strategy</li>
  <li>fail</li>
  <li>document the obstruction</li>
  <li>switch to computation-guided exploration</li>
  <li>identify structure</li>
  <li>derive the proof</li>
  <li>verify numerically along the way</li>
  <li>verify once more symbolically</li>
</ol>

<div class="center">
  <img src="http://www.pokutta.com/blog/assets/agentic-researcher/explicit-slow-init-convergence.svg" alt="Frank-Wolfe convergence plot on uniformly convex sets" style="width:99%" />
  <p style="clear: both;"></p>
</div>
<p class="figcap"><strong>Figure 6.</strong> [sic] Log-log convergence for the Frank-Wolfe lower-bound case study. The empirical behavior matches the rate suggested by the analysis.</p>

<p><strong>There are three more case studies.</strong></p>

<p>I am not going through the remaining three in detail here, but they are also worth reading:</p>

<ul>
  <li><a href="https://arxiv.org/abs/2210.17323">GPTQ</a> column ordering in LLM quantization</li>
  <li>multi-variable dual tightening for Boscia and mixed-integer convex optimization</li>
  <li>extremal search for maximal real solutions in $K_7$ power networks</li>
</ul>

<p>They essentially make the same basic point: the agent is most useful when it can combine implementation, experimentation, proof attempts, verification, and structured reporting inside a single inspectable loop.</p>

<h2 id="limitations-what-this-does-not-solve">Limitations: What this does not solve</h2>

<p><strong>Verification remains the central problem.</strong> Natural-language proofs still require human inspection; we think of this more as a feature than a bug. Code is easier to check (syntax, types, compile checks, unit tests, integration tests, etc.), but subtle bugs remain dangerous. Citations remain a known weak point; tools such as OpenAlex can help a lot but are not a silver bullet. There are formal verification tools such as Lean 4 available, but in our experience this often does not scale (yet?!) to actual research workflows; in particular when paradigm changes are present (e.g., numerics vs. symbolics vs. computational exploration vs. writing a SAT program as proof). So yes, the researcher still owns final verification (and responsibility).</p>

<p><strong>Novelty is not automatically solved.</strong> An agent can search the literature and reduce the burden, but it cannot guarantee novelty. This is especially important now that many groups are exploring similar design spaces with similar tools. The researcher still has to do the serious prior-art work.</p>

<p><strong>Context remains fragile.</strong> Long sessions eventually hit context-window limits. This is why the persistent external memory in <code class="language-plaintext highlighter-rouge">report.tex</code> and <code class="language-plaintext highlighter-rouge">TODO.md</code> matters so much. Without it, the system will forget, repeat itself, or silently lose important information. Nonetheless, this does not fix all cases of context churn. Also, simply more context like Claude Opus 4.6’s 1m token window is not an immediate fix either: the context needs to be actively managed with <em>meaningful</em> information and simply having a larger context window also increases the risk of context pollution. As with (human) researchers, focus and concentration are key.</p>

<p><strong>Cost is real, but often not the main issue.</strong> Long frontier-model sessions are not free. But in many Level 4 setups, much of the wall-clock time is actually spent waiting for code, experiments, or training runs, not generating tokens. So the real bottleneck is often compute time and workflow quality, not just API cost.</p>

<h2 id="a-couple-of-final-thoughts">A couple of final thoughts</h2>

<p>My overall view is quite positive. Used in the right way, these systems are already good enough to impact how research is done, potentially opening up new avenues. They are particularly strong on the wide, messy, implementation-heavy part of research: exploring various proof directions, setting up experiments, checking boundary cases, writing and revising code, keeping notes, running ablations, and simply pushing several lines of attack in parallel for much longer than a human would do manually. This is not the same as “fully autonomous science”, but it is absolutely real leverage.</p>

<p>At the same time, I do not believe in unbounded speedups either. Research is not one isolated task; it is a workflow. And workflows obey Amdahl’s law [AL26]. Even if the agent becomes extremely fast at some parts of the loop, the remaining serial parts still cap the total gain: choosing the problem, deciding what actually matters, judging novelty, interpreting ambiguous evidence, and performing final verification. These pieces do not go away just because code generation or argument generation got faster. So no, I do not expect 100x researcher productivity. In many realistic settings the true ceiling is much lower.</p>

<p>Then there is the rework problem, which in practice is at least as important. Every wrong derivation, flaky script, plausible-but-false citation, or misleading empirical win creates a tax that has to be paid later by the researcher. Local speed does not automatically turn into global speed. If the system saves you two hours and then costs you ninety minutes of checking, cleanup, and reinterpretation, the headline gain is mostly fiction. This is one reason why disciplined workflows matter so much: they reduce the rework tax before it compounds.</p>

<p>There is also a more subtle downside risk. If you use the agent to outsource the core thinking, you may get more text, more code, and less understanding. In that sense there is indeed a “thinking tax” if the tool is used lazily [TT26]. But if you use it to harden your own reasoning, by searching for counterexamples, stress-testing claims, implementing verification scripts, and documenting failed attempts, then the system becomes genuinely valuable. That distinction is crucial.</p>

<p>So my expectation is neither “AI changes nothing” nor “AI gives us fully autonomous science”. However, the realistic middle ground is already quite useful: better exploration, broader search, faster implementation, more systematic verification, and the ability to sustain open-ended research loops for longer. Even a fairly mundane 2x on the right parts of research would be enormous over the course of a few years. But to get there, we have to be honest about the downside risks as well: overtrust, cognitive atrophy, workflow bloat, and rework. The researcher remains the one who has to decide what is important and what is worth believing.</p>

<h2 id="references">References</h2>

<p>(for a more complete list, see our paper [ZPRP26] and the references contained therein)</p>

<p><strong>Main paper.</strong></p>

<p>[ZPRP26] Zimmer, M., Pelleriti, N., Roux, C., Pokutta, S.: <a href="https://arxiv.org/abs/2603.15914">The Agentic Researcher: A Practical Guide to AI-Assisted Research in Mathematics and Machine Learning</a> (2026)</p>

<p><strong>AI for mathematics and mathematical discovery.</strong></p>

<p>[AG] Trinh, T. et al.: <a href="https://www.nature.com/articles/s41586-023-06747-5">Solving olympiad geometry without human demonstrations</a> (2024)</p>

<p>[AP] Hubert, T. et al.: <a href="https://www.nature.com/articles/s41586-025-09833-y">Olympiad-level formal mathematical reasoning with reinforcement learning</a> (2025)</p>

<p>[AG2] Chervonyi, Y. et al.: <a href="https://arxiv.org/abs/2502.03544">Gold-medalist Performance in Solving Olympiad Geometry with AlphaGeometry2</a> (2025)</p>

<p>[ARI] Achim, T. et al.: <a href="https://arxiv.org/abs/2510.01346v2">Aristotle: IMO-level Automated Theorem Proving</a> (2025)</p>

<p>[AE] Novikov, A. et al.: <a href="https://arxiv.org/abs/2506.13131v1">AlphaEvolve: A coding agent for scientific and algorithmic discovery</a> (2025)</p>

<p>[MEDS] Georgiev, A., Gómez-Serrano, J., Tao, T., Wagner, S.: <a href="https://arxiv.org/abs/2511.02864v3">Mathematical exploration and discovery at scale</a> (2025)</p>

<p>[ALET] Feng, Y. et al.: <a href="https://arxiv.org/abs/2602.10177">Towards Autonomous Mathematics Research</a> (2026)</p>

<p>[ALET2] Feng, Y. et al.: <a href="https://arxiv.org/abs/2602.21201">Aletheia tackles FirstProof autonomously</a> (2026)</p>

<p>[FP] Abouzaid, M. et al.: <a href="https://arxiv.org/abs/2602.05192">First Proof</a> (2026)</p>

<p>[FM] Glazer, D. et al.: <a href="https://arxiv.org/abs/2411.04872">FrontierMath: A Benchmark for Evaluating Advanced Mathematical Reasoning in AI</a> (2024)</p>

<p>[RM] Zhang, Y. et al.: <a href="https://arxiv.org/abs/2505.12575">RealMath: A Continuous Benchmark for Evaluating Language Models on Research-Level Mathematics</a> (2025)</p>

<p><strong>AI-assisted mathematical research and human-AI collaboration.</strong></p>

<p>[AV] Avigad, J.: <a href="https://arxiv.org/abs/2603.03684">Mathematicians in the age of AI</a> (2026)</p>

<p>[H] Henkel, C.: <a href="https://arxiv.org/abs/2508.20236">The Mathematician’s Assistant: Integrating AI into Research Practice</a> (2025)</p>

<p>[D] Dobriban, E.: <a href="https://arxiv.org/abs/2511.18828">Solving a Research Problem in Mathematical Statistics with AI Assistance</a> (2025)</p>

<p>[LCP] Liu, Z. et al.: <a href="https://arxiv.org/abs/2510.26380">AI Mathematician as a Partner in Advancing Mathematical Discovery – A Case Study in Homogenization Theory</a> (2025)</p>

<p>[C] Carbone, A.: <a href="https://arxiv.org/abs/2511.07420">Advancing mathematics research with generative AI</a> (2025)</p>

<p>[HP] Haase, J., Pokutta, S.: <a href="https://arxiv.org/abs/2411.12527">Human-AI Co-Creativity: Exploring Synergies Across Levels of Creative Collaboration</a> (2024)</p>

<p><strong>Optimization and conditional gradients.</strong></p>

<p>[KDP21] Kerdreux, T., d’Aspremont, A., Pokutta, S.: <a href="https://proceedings.mlr.press/v130/kerdreux21a.html">Projection-Free Optimization on Uniformly Convex Sets</a>. <em>Proceedings of AISTATS</em> (2021)</p>

<p>[HDZRSP26] Halbey, J., Deza, D., Zimmer, M., Roux, C., Stellato, B., Pokutta, S.: <a href="https://arxiv.org/abs/2602.04378">Lower Bounds for Frank-Wolfe on Strongly Convex Sets</a>. <em>arXiv preprint arXiv:2602.04378</em> (2026)</p>

<p>[GL26] Grimmer, B., Liu, N.: <a href="https://arxiv.org/abs/2602.22608">Lower Bounds for Linear Minimization Oracle Methods Optimizing over Strongly Convex Sets</a>. <em>arXiv preprint arXiv:2602.22608</em> (2026)</p>

<p><strong>Agentic workflows and evaluation.</strong></p>

<p>[AIS] Lu, C. et al.: <a href="https://arxiv.org/abs/2408.06292">The AI Scientist: Towards Fully Automated Open-Ended Scientific Discovery</a> (2024)</p>

<p>[SAB] Chen, X. et al.: <a href="https://arxiv.org/abs/2410.05080">ScienceAgentBench: Toward Rigorous Assessment of Language Agents for Data-Driven Scientific Discovery</a> (2024)</p>

<p>[AR] Karpathy, A.: <a href="https://github.com/karpathy/autoresearch">autoresearch</a></p>

<p>[FS] Romera-Paredes, B. et al.: <a href="https://www.nature.com/articles/s41586-023-06924-6">Mathematical discoveries from program search with large language models</a> (2023)</p>

<p><strong>Philosophy of science.</strong></p>

<p>[POP] Stanford Encyclopedia of Philosophy: <a href="https://plato.stanford.edu/entries/popper/">Karl Popper</a></p>

<p>[FAL] Encyclopaedia Britannica: <a href="https://www.britannica.com/topic/philosophy-of-science/Eliminativism-and-falsification">Philosophy of science - Eliminativism, Falsification, Theory</a></p>

<p><strong>AI productivity and cognition.</strong></p>

<p>[AL26] just a tourist: <a href="https://just-a-tourist.bearblog.dev/amdahl-law-ai-speedup/">The 20x Ceiling: Amdahl’s Law and the Limits of AI Speedup</a> (2026)</p>

<p>[TT26] just a tourist: <a href="https://just-a-tourist.bearblog.dev/thinking-tax/">The Thinking Tax: When AI Tools Cost More Than They Save</a> (2026)</p>

<p><strong>Tools.</strong></p>

<p>[CC] Anthropic: <a href="https://code.claude.com/docs/en/overview">Claude Code overview</a></p>

<p>[CX] OpenAI: <a href="https://openai.com/codex/">Codex</a></p>

<p>[OC] Anomaly: <a href="https://github.com/anomalyco/opencode">OpenCode / The open source coding agent</a></p>

<p>[GC] Google: <a href="https://geminicli.com/">Gemini CLI</a></p>

<h2 id="footnotes">Footnotes</h2>

<div class="footnotes" role="doc-endnotes">
  <ol>
    <li id="fn:1">
      <p>This is purely for internal amusement: yes I did use the word. <a href="#fnref:1" class="reversefootnote" role="doc-backlink">&#8617;</a></p>
    </li>
  </ol>
</div>]]></content><author><name>Sebastian Pokutta</name></author><category term="research" /><category term="ai" /><category term="agents" /><category term="mathematics" /><category term="machine-learning" /><category term="workflow" /><summary type="html"><![CDATA[TL;DR: This is a summary of our recent paper The Agentic Researcher: A Practical Guide to AI-Assisted Research in Mathematics and Machine Learning by Max Zimmer, Nico Pelleriti, Christophe Roux, and Sebastian Pokutta augmented with some personal perspectives and thoughts. The main point is not that AI can now “do research” in some vague science-fiction sense. The more useful point is that, with the right workflow, general CLI coding agents can already act like research associates: they can write proofs, formulate conjectures, implement ideas, run experiments, document failures, verify intermediate claims, and keep going for hours, while the researcher remains responsible for idea generation, creativity, direction, judgment, and final verification.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" /><media:content medium="image" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">The Box You Can’t Open Twice: Newcomb’s Paradox Through Four Mathematical Lenses</title><link href="http://www.pokutta.com/blog/newcomb-four-lenses/" rel="alternate" type="text/html" title="The Box You Can’t Open Twice: Newcomb’s Paradox Through Four Mathematical Lenses" /><published>2026-03-10T00:00:00+01:00</published><updated>2026-03-10T00:00:00+01:00</updated><id>http://www.pokutta.com/blog/newcomb-four-lenses</id><content type="html" xml:base="http://www.pokutta.com/blog/newcomb-four-lenses/"><![CDATA[<p><em>TL;DR: Newcomb’s paradox — should you take one box or two? — splits rational decision-makers almost evenly. There are four natural mathematical frameworks (causal inference, algorithmic self-reference, statistical counterfactuals, and online learning) that give different answers, and the disagreement reveals deep structural tensions in what it means to choose rationally.</em></p>

<!--more-->

<p>In 1960, physicist William Newcomb invented a thought experiment so divisive that when Robert Nozick published it in 1969, he noted that “to almost everyone, it is perfectly clear and obvious what should be done. The difficulty is that these people seem to divide almost evenly on the problem, with large numbers thinking that the opposing half is just being silly.”</p>

<p>Sixty-six years later, they still do. The 2020 PhilPapers survey of ~2,000 professional philosophers found 39% favor two-boxing and 31% favor one-boxing, with the rest undecided. Among decision theory specialists, the lean is stronger: 61% two-box, 26% one-box. The general public and the AI alignment community tilt the other way.</p>

<p>The puzzle is simple. You face two boxes. Box A is transparent and holds \$1,000. Box B is opaque and holds either \$1,000,000 or nothing. A highly reliable predictor, right about 99% of the time, has already examined you and made a prediction. If it predicted you’d take only Box B, it put the million in. If it predicted you’d take both, it left Box B empty. The predictor is done. The money is placed. You choose.</p>

<p>The paradox is that two ironclad principles of rational choice give opposite answers. And the real interest isn’t in which answer is right. It’s in <em>why</em> we can’t tell.</p>

<style>
.ncb-widget{margin:2em 0;padding:1.5em;border:1px solid #e5e7eb;border-radius:12px;background:#f9fafb}
.ncb-controls{display:flex;flex-wrap:wrap;gap:16px;margin-top:1em;align-items:flex-end}
.ncb-control{display:flex;flex-direction:column;gap:4px}
.ncb-control label{font-size:.85em;color:#4b5563;font-weight:500}
.ncb-control input[type="range"]{width:180px}
.ncb-stats{display:flex;flex-wrap:wrap;gap:10px;margin-top:.75em;font-size:.9em}
.ncb-stat{padding:5px 12px;background:#fff;border:1px solid #e5e7eb;border-radius:8px}
.ncb-val{font-weight:600;color:#111827}
.ncb-btn{padding:6px 16px;border:1px solid #d1d5db;border-radius:6px;background:#fff;cursor:pointer;font-size:.85em;font-family:inherit}
.ncb-btn:hover{background:#f3f4f6}
.ncb-readout{margin-top:.5em;padding:10px 14px;background:#fff;border:1px solid #e5e7eb;border-radius:8px;font-size:.9em;line-height:1.6}
.ncb-chart-wrap{position:relative;width:100%}
.ncb-evo-grid{display:flex;flex-wrap:wrap;gap:16px}
.ncb-evo-grid>div{flex:1;min-width:260px}
@media(max-width:640px){.ncb-control input[type="range"]{width:140px}.ncb-controls{gap:12px}}
.callout{border-left:4px solid #2563eb;border-right:4px solid #2563eb;background:#f5f7ff;padding:12px 16px;margin:1em 0}
.callout-anecdote{border-left:4px solid #ea580c;border-right:4px solid #ea580c;background:#fff7ed;padding:12px 16px;margin:1em 0}
</style>

<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>

<p>The payoff matrix is simple:</p>

<table>
  <thead>
    <tr>
      <th> </th>
      <th>Box B full (\$1,000,000)</th>
      <th>Box B empty (\$0)</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td><strong>One-box</strong> (B only)</td>
      <td>\$1,000,000</td>
      <td>\$0</td>
    </tr>
    <tr>
      <td><strong>Two-box</strong> (A + B)</td>
      <td>\$1,001,000</td>
      <td>\$1,000</td>
    </tr>
  </tbody>
</table>

<p>Two-boxing strictly dominates: it pays \$1,000 more in every cell. But the predictor ties the column you’re in to the row you choose. Write $M = 1{,}000{,}000$ for the big prize, $K = 1{,}000$ for the small one, and $q = 0.99$ for the predictor’s accuracy. Four frameworks handle this coupling differently:</p>

<p><strong>EDT</strong> (Evidential Decision Theory) conditions on the action:</p>

\[E_{\text{EDT}}[a] = P(\text{B full} \mid a) \cdot (M + K \cdot \mathbf{1}_{a = \text{two-box}}) + P(\text{B empty} \mid a) \cdot K \cdot \mathbf{1}_{a = \text{two-box}}\]

<p>With our numbers:</p>

\[E_{\text{EDT}}[\text{one-box}] = 0.99 \times 1{,}000{,}000 = 990{,}000\]

\[E_{\text{EDT}}[\text{two-box}] = 0.01 \times 1{,}001{,}000 + 0.99 \times 1{,}000 = 11{,}000\]

<p>EDT one-boxes. Your action is evidence about which column you’re in.</p>

<p><strong>CDT</strong> (Causal Decision Theory) intervenes on the action:</p>

\[E_{\text{CDT}}[a] = P(B\text{ full}) \cdot V(a, \text{full}) + P(B\text{ empty}) \cdot V(a, \text{empty})\]

<p>Since $V(\text{two-box}, s) = V(\text{one-box}, s) + K$ for every box state $s$:</p>

\[E_{\text{CDT}}[\text{two-box}] &gt; E_{\text{CDT}}[\text{one-box}]\]

<p>for every prior over the box state. CDT two-boxes. Your action can’t <em>cause</em> the column to change.</p>

<p><strong>FDT</strong> (Functional Decision Theory) optimizes over algorithm outputs:</p>

\[a^* = \arg\max_{a} \; U(\text{world where all instances of my algorithm output } a)\]

<p>If your algorithm outputs “one-box”, the predictor fills B: payoff $M = 1{,}000{,}000$.
If your algorithm outputs “two-box”, the predictor empties B: payoff $K = 1{,}000$.
FDT one-boxes. Your algorithm <em>is</em> the column selector.</p>

<p><strong>Regret-based</strong> (online learning) asks what kind of adversary the predictor is:</p>

<ul>
  <li>If <em>oblivious</em> (box contents fixed before you act): swap regret says two-box.</li>
  <li>If <em>adaptive</em> (box contents respond to your policy): policy regret says one-box.</li>
</ul>

<p>The answer depends on how you classify the predictor.</p>

<p>We will now look at these four frameworks from four different lenses.</p>

<h2 id="lens-1-observation-vs-intervention">Lens 1: Observation vs. Intervention</h2>

<p>The cleanest formalization comes from Judea Pearl’s causal framework. Pearl distinguishes between <em>observing</em> that something is the case and <em>intervening</em> to make it the case. In his notation, $P(Y \mid X = x)$ is the probability of $Y$ given that we <em>observe</em> $X = x$. But $P(Y \mid do(X = x))$ is the probability of $Y$ given that we <em>set</em> $X$ to $x$, surgically, from outside the system. These are not the same thing.</p>

<p>In Newcomb’s problem, the underlying causal graph looks like this:</p>

<div style="text-align:center;margin:1.5em 0;">
<svg viewBox="0 0 540 170" style="max-width:540px;width:100%;height:auto;" xmlns="http://www.w3.org/2000/svg">
<defs><marker id="ncb-arr" viewBox="0 0 10 10" refX="9" refY="5" markerWidth="7" markerHeight="7" orient="auto"><path d="M0 0L10 5L0 10z" fill="#4b5563" /></marker></defs>
<rect x="160" y="8" width="220" height="38" rx="10" fill="#f3f4f6" stroke="#9ca3af" stroke-width="1.5" />
<text x="270" y="33" text-anchor="middle" font-size="15" fill="#1f2937" font-family="inherit">Your disposition (θ)</text>
<line x1="215" y1="46" x2="105" y2="108" stroke="#4b5563" stroke-width="1.5" marker-end="url(#ncb-arr)" />
<line x1="325" y1="46" x2="355" y2="108" stroke="#4b5563" stroke-width="1.5" marker-end="url(#ncb-arr)" />
<rect x="10" y="112" width="180" height="38" rx="10" fill="#dbeafe" stroke="#93c5fd" stroke-width="1.5" />
<text x="100" y="137" text-anchor="middle" font-size="15" fill="#1e40af" font-family="inherit">Your action</text>
<rect x="250" y="112" width="180" height="38" rx="10" fill="#fef3c7" stroke="#fcd34d" stroke-width="1.5" />
<text x="340" y="137" text-anchor="middle" font-size="14" fill="#92400e" font-family="inherit">Predictor's prediction</text>
<line x1="430" y1="131" x2="450" y2="131" stroke="#4b5563" stroke-width="1.5" marker-end="url(#ncb-arr)" />
<rect x="455" y="112" width="80" height="38" rx="10" fill="#fecaca" stroke="#f87171" stroke-width="1.5" />
<text x="495" y="130" text-anchor="middle" font-size="12" fill="#991b1b" font-family="inherit">Box</text>
<text x="495" y="145" text-anchor="middle" font-size="12" fill="#991b1b" font-family="inherit">contents</text>
</svg>
</div>

<p>Your disposition $\theta$, the kind of decision-maker you are, is a common cause of both your action and the prediction. This is a classic confounding structure. And the entire paradox lives in one inequality:</p>

\[P(\text{B full} \mid \text{one-box}) \neq P(\text{B full} \mid do(\text{one-box}))\]

<p>The left side is observational. If we <em>observe</em> you one-boxing, that’s strong evidence you’re the kind of person the predictor expected to one-box, so Box B is probably full. This gives:</p>

\[E[U \mid a = 1] = 0.99 \times 1{,}000{,}000 = 990{,}000\]

<p>The right side is interventional. If we <em>intervene</em> on your action, surgically setting it to one-box regardless of your disposition, the arrow from $\theta$ to your action is severed. The intervention carries no information about the prediction. Whatever is in Box B is already there. So taking both boxes gets you an extra \$1,000 regardless:</p>

\[U(a = 2, p) &gt; U(a = 1, p) \quad \text{for every fixed } p\]

<p>Evidential decision theory (EDT) uses the left side and says: one-box. Causal decision theory (CDT) uses the right side and says: two-box. Pearl himself sided firmly with the interventionists, arguing that treating actions as mere observations, as EDT does, is precisely what generates the paradox. “The confusion between actions and acts,” he wrote in <em>Causality</em>, “has led to Newcomb’s paradox and other oddities.”</p>

<div class="callout-anecdote">
<strong>Anecdote.</strong> This confusion is not limited to philosophy. I once had a project with a company that wanted to optimize their workforce scheduling. They had years of data: staffing levels, demand, productivity. When they ran their optimizer against this data, it concluded that the existing schedule was already near-optimal. Problem solved? <br /> <br />

Not at all. The data had been <em>generated under the old schedule</em>. Demand patterns, no-show rates, even which shifts workers preferred were all shaped by the very scheduling policy the company wanted to replace. The optimizer was computing $P(\text{outcome} \mid \text{old schedule observed})$ when what it needed was $P(\text{outcome} \mid do(\text{new schedule}))$. The confounding structure is identical to Newcomb's problem: the policy that generated the data is a common cause of both the "action" (schedule) and the "outcome" (observed performance), and naively conditioning on the data mistakes correlation for causation.
</div>

<p>But Pearl’s resolution has a cost. To see this cost, we plot the expected payoff as a function of the predictor’s accuracy $q$:</p>

<div class="ncb-widget">
<div class="ncb-chart-wrap" style="height:360px;">
<canvas id="ncb-payoff-chart"></canvas>
</div>
<div class="ncb-controls">
<div class="ncb-control">
<label>Highlight accuracy: <strong><span id="ncb-q1-val">0.99</span></strong></label>
<input type="range" id="ncb-q1" min="50" max="100" step="1" value="99" />
</div>
</div>
<div class="ncb-readout" id="ncb-payoff-readout">
At <em>q</em> = 0.99: One-box earns <strong><span>$</span>990,000</strong> · Two-box earns <strong><span>$</span>11,000</strong> · Ratio: <strong>90 : 1</strong>
</div>
</div>

<script>
(function(){
var M=1000000,K=1000;
function oneBox(q){return q*M}
function twoBox(q){return(1-q)*(M+K)+q*K}
function fmt(n){
  if(n>=1e6)return'<span>$</span>'+(n/1e6).toFixed(n%1e6===0?0:1)+'M';
  if(n>=1e3)return'<span>$</span>'+(n/1e3).toFixed(n%1e3===0?0:1)+'K';
  return'<span>$</span>'+n.toFixed(0);
}
function fmtD(n){return'<span>$</span>'+n.toLocaleString('en-US',{maximumFractionDigits:0})}
var pts=[];for(var i=0;i<=100;i++){var q=0.5+i*0.005;pts.push(q)}
var d1=pts.map(function(q){return{x:q,y:oneBox(q)/1000}});
var d2=pts.map(function(q){return{x:q,y:twoBox(q)/1000}});
var currentQ=0.99;
var chart=new Chart(document.getElementById('ncb-payoff-chart'),{
  type:'scatter',
  data:{datasets:[
    {label:'One-box',data:d1,showLine:true,borderColor:'#2563eb',backgroundColor:'rgba(37,99,235,0.08)',borderWidth:2.5,pointRadius:0,fill:true,tension:0},
    {label:'Two-box',data:d2,showLine:true,borderColor:'#dc2626',backgroundColor:'rgba(220,38,38,0.08)',borderWidth:2.5,pointRadius:0,fill:true,tension:0},
    {label:'Current',data:[{x:currentQ,y:oneBox(currentQ)/1000},{x:currentQ,y:twoBox(currentQ)/1000}],
     pointRadius:7,pointBackgroundColor:['#2563eb','#dc2626'],pointBorderColor:'#fff',pointBorderWidth:2,showLine:false}
  ]},
  options:{
    responsive:true,maintainAspectRatio:false,animation:false,
    scales:{
      x:{type:'linear',min:0.5,max:1.0,title:{display:true,text:'Predictor accuracy (q)',font:{size:13}},
         ticks:{callback:function(v){return v.toFixed(2)}}},
      y:{title:{display:true,text:'Expected payoff ($K)',font:{size:13}},min:0,max:1050}
    },
    plugins:{
      legend:{position:'top',labels:{usePointStyle:true,pointStyle:'line',font:{size:12},
        filter:function(item){return item.datasetIndex<2}}},
      tooltip:{enabled:false}
    }
  },
  plugins:[{
    id:'crossover',
    afterDraw:function(ch){
      var xA=ch.scales.x,yA=ch.scales.y,ctx=ch.ctx;
      var cx=xA.getPixelForValue(1001000/2000000);
      ctx.save();ctx.strokeStyle='#9ca3af';ctx.lineWidth=1;ctx.setLineDash([5,5]);
      ctx.beginPath();ctx.moveTo(cx,yA.top);ctx.lineTo(cx,yA.bottom);ctx.stroke();
      ctx.fillStyle='#6b7280';ctx.font='11px sans-serif';ctx.textAlign='left';
      ctx.fillText('q ≈ 0.5005',cx+4,yA.top+14);
      var qx=xA.getPixelForValue(currentQ);
      ctx.strokeStyle='#f59e0b';ctx.lineWidth=1.5;ctx.setLineDash([4,4]);
      ctx.beginPath();ctx.moveTo(qx,yA.top);ctx.lineTo(qx,yA.bottom);ctx.stroke();
      ctx.restore();
    }
  }]
});
function update(){
  var q=parseInt(document.getElementById('ncb-q1').value)/100;
  currentQ=q;
  document.getElementById('ncb-q1-val').textContent=q.toFixed(2);
  chart.data.datasets[2].data=[{x:q,y:oneBox(q)/1000},{x:q,y:twoBox(q)/1000}];
  chart.update('none');
  var o=oneBox(q),t=twoBox(q);
  var ratio=o>t?Math.round(o/t)+' : 1':'1 : '+Math.round(t/o);
  if(Math.abs(o-t)<100)ratio='≈ 1 : 1';
  document.getElementById('ncb-payoff-readout').innerHTML=
    'At <em>q</em> = '+q.toFixed(2)+': One-box earns <strong>'+fmtD(o)+'</strong> · Two-box earns <strong>'+fmtD(t)+'</strong> · Ratio: <strong>'+ratio+'</strong>';
}
document.getElementById('ncb-q1').addEventListener('input',update);
})();
</script>

<p>The crossover is at $q \approx 0.5005$, essentially a coin flip. For <em>any</em> predictor even marginally better than chance, one-boxing yields a higher expected payoff. At $q = 0.99$, one-boxers average \$990,000 while two-boxers average \$11,000. Being “causally rational” makes you poorer. That’s uncomfortable to say the least.</p>

<h2 id="lens-2-algorithmic-correlation-and-self-reference">Lens 2: Algorithmic Correlation and Self-Reference</h2>

<p>The second lens comes from an unexpected direction: the logic of self-reference.</p>

<p>If the predictor is accurate because it <em>modeled</em> your decision process, say by running a simulation, analyzing your algorithm, or examining a sufficiently detailed model of your brain, then there are two instantiations of your decision-making procedure: the one in your head and the one the predictor evaluated. They aren’t causally connected (the predictor is done), but they are <em>logically</em> connected: they produce the same output because they implement the same function.</p>

<p>This is the insight behind Functional Decision Theory (FDT), proposed by Eliezer Yudkowsky and Nate Soares in 2017. FDT says: don’t ask what your action <em>causes</em> (CDT) or what it <em>provides evidence for</em> (EDT). Ask what the best <em>output of your decision algorithm</em> would be, across all instances where that algorithm is evaluated.</p>

\[\text{FDT: } \arg\max_a \sum_{\text{instances } i} U_i(a)\]

<p>Your algorithm is evaluated in two places: your head (where the output determines your action) and the predictor’s model (where the output determined the prediction). If your algorithm outputs “one-box,” you get \$1,000,000. If it outputs “two-box,” you get \$1,000. FDT one-boxes.</p>

<p>This connects to the <strong>Self-Sampling Assumption (SSA)</strong> in anthropic reasoning. Bostrom’s SSA says you should reason as if you’re randomly selected from your reference class of observers. In Newcomb’s problem, the analogous move is reasoning as if you’re randomly selected from the set of all instantiations of your algorithm. The predictor’s model of you and the actual you are both running the same code: different instantiations, same function.</p>

<p>The structural parallel is pretty much straightforward:</p>

<table>
  <thead>
    <tr>
      <th>Anthropic reasoning</th>
      <th>Newcomb’s problem</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Which observer am I?</td>
      <td>Which instance of my algorithm is this?</td>
    </tr>
    <tr>
      <td>Reference class of observers</td>
      <td>Reference class of algorithm evaluations</td>
    </tr>
    <tr>
      <td>My observations are evidence about the world</td>
      <td>My decision is evidence about the prediction</td>
    </tr>
  </tbody>
</table>

<p>This framing dissolves the paradox, but at the price of accepting a notion of “logical causation” that most decision theorists find metaphysically suspect. The predictor’s model and your brain don’t share any causal arrows. The correlation comes from mathematical identity, not physical interaction. Whether that should count as a reason to act is itself an open question.</p>

<p>This can be also seen also with a simple monte-carlo style simulation: We initialize a population of 500 agents, each carrying a single parameter: its one-box probability $p \in [0,1]$, drawn uniformly at random. Each generation proceeds in three steps. First, every agent plays 20 rounds of Newcomb’s game against a predictor with accuracy $q$; the agent one-boxes with probability $p$ in each round and its fitness is its average payoff. Second, we form the next generation by sampling 500 agents with replacement, proportional to fitness (roulette-wheel selection). Third, each offspring’s $p$ is perturbed by Gaussian noise with standard deviation 0.03, clipped to $[0,1]$. This is pretty much a textbook evolutionary algorithm: selection amplifies high-payoff strategies, mutation explores nearby variants. The key question is whether the population converges to one-boxing or two-boxing, and how fast.</p>

<div class="ncb-widget">
<div class="ncb-evo-grid">
<div>
<canvas id="ncb-evo-hist" style="width:100%;height:300px;display:block;"></canvas>
</div>
<div>
<div style="height:300px;">
<canvas id="ncb-evo-line"></canvas>
</div>
</div>
</div>
<div class="ncb-stats">
<div class="ncb-stat">Generation: <span class="ncb-val" id="ncb-evo-gen">0</span> / 80</div>
<div class="ncb-stat">Avg <em>p</em>: <span class="ncb-val" id="ncb-evo-avgp">0.500</span></div>
<div class="ncb-stat">Avg payoff: <span class="ncb-val" id="ncb-evo-pay">—</span></div>
</div>
<div class="ncb-controls">
<div class="ncb-control">
<label>Predictor accuracy: <strong><span id="ncb-evo-q-val">0.95</span></strong></label>
<input type="range" id="ncb-evo-q" min="51" max="99" step="1" value="95" />
</div>
<div class="ncb-control">
<label>Speed: <strong><span id="ncb-evo-speed-val">120</span></strong> ms/gen</label>
<input type="range" id="ncb-evo-speed" min="30" max="500" step="10" value="120" />
</div>
<div class="ncb-control" style="flex-direction:row;gap:8px;align-items:flex-end;">
<button class="ncb-btn" id="ncb-evo-play">▶ Play</button>
<button class="ncb-btn" id="ncb-evo-step">Step</button>
<button class="ncb-btn" id="ncb-evo-reset">Reset</button>
</div>
</div>
</div>

<script>
(function(){
var POP=500,ROUNDS=20,MAX_GEN=80,MUT=0.03,BINS=20,M=1000000,K=1000;
var pop,gen,hist,q,running,timer,speed;
var histCvs=document.getElementById('ncb-evo-hist');
var histCtx;

function setupCanvas(){
  var dpr=window.devicePixelRatio||1;
  var rect=histCvs.getBoundingClientRect();
  histCvs.width=rect.width*dpr;histCvs.height=rect.height*dpr;
  histCtx=histCvs.getContext('2d');histCtx.scale(dpr,dpr);
  histCvs._w=rect.width;histCvs._h=rect.height;
}

function gauss(){var u=0,v=0;while(!u)u=Math.random();while(!v)v=Math.random();return Math.sqrt(-2*Math.log(u))*Math.cos(2*Math.PI*v)}
function avg(a){var s=0;for(var i=0;i<a.length;i++)s+=a[i];return s/a.length}

function playN(ob,qq){
  var correct=Math.random()<qq;
  var predOB=correct?ob:!ob;
  var boxB=predOB?M:0;
  return ob?boxB:K+boxB;
}

function init(){
  q=parseInt(document.getElementById('ncb-evo-q').value)/100;
  speed=parseInt(document.getElementById('ncb-evo-speed').value);
  pop=new Array(POP);for(var i=0;i<POP;i++)pop[i]=Math.random();
  gen=0;hist=[{g:0,p:avg(pop)}];
  stop();
  setupCanvas();
  updateDisplay();
  resetLine();
}

function runGen(){
  if(gen>=MAX_GEN){stop();return}
  var fit=new Float64Array(POP);
  for(var i=0;i<POP;i++){var t=0;for(var r=0;r<ROUNDS;r++){var ob=Math.random()<pop[i];t+=playN(ob,q)}fit[i]=t/ROUNDS}
  var tF=0;for(var i=0;i<POP;i++)tF+=fit[i];
  var cum=new Float64Array(POP);cum[0]=fit[0]/tF;
  for(var i=1;i<POP;i++)cum[i]=cum[i-1]+fit[i]/tF;
  var np=new Array(POP);
  for(var i=0;i<POP;i++){
    var rv=Math.random(),lo=0,hi=POP-1;
    while(lo<hi){var mid=(lo+hi)>>1;if(cum[mid]<rv)lo=mid+1;else hi=mid}
    var c=pop[lo]+gauss()*MUT;np[i]=Math.max(0,Math.min(1,c));
  }
  pop=np;gen++;
  var ap=avg(pop);
  var avgPay=0;for(var i=0;i<POP;i++){var ob=Math.random()<pop[i];avgPay+=playN(ob,q)}avgPay/=POP;
  hist.push({g:gen,p:ap,pay:avgPay});
  updateDisplay();
}

function drawHist(){
  var w=histCvs._w,h=histCvs._h,ctx=histCtx;
  ctx.clearRect(0,0,w,h);
  var bins=new Array(BINS).fill(0);
  for(var i=0;i<POP;i++){var b=Math.floor(pop[i]*BINS);if(b>=BINS)b=BINS-1;bins[b]++}
  var mx=0;for(var i=0;i<BINS;i++)if(bins[i]>mx)mx=bins[i];
  if(mx<1)mx=1;
  var mg={t:28,r:16,b:38,l:40};
  var pw=w-mg.l-mg.r,ph=h-mg.t-mg.b,bw=pw/BINS;
  ctx.fillStyle='#374151';ctx.font='bold 12px sans-serif';ctx.textAlign='center';
  ctx.fillText('Population Distribution, Generation '+gen,w/2,16);
  ctx.strokeStyle='#e5e7eb';ctx.lineWidth=1;
  for(var i=1;i<=4;i++){var y=mg.t+ph-ph*i/4;ctx.beginPath();ctx.moveTo(mg.l,y);ctx.lineTo(mg.l+pw,y);ctx.stroke()}
  for(var i=0;i<BINS;i++){
    var bh=bins[i]/mx*ph,x=mg.l+i*bw,y=mg.t+ph-bh;
    var t=(i+.5)/BINS;
    var cr=Math.round(220*(1-t)+37*t),cg=Math.round(38*(1-t)+99*t),cb=Math.round(38*(1-t)+235*t);
    ctx.fillStyle='rgb('+cr+','+cg+','+cb+')';
    ctx.beginPath();
    var rad=Math.min(3,bh/2);
    if(bh>0){
      ctx.moveTo(x+1,mg.t+ph);ctx.lineTo(x+1,y+rad);
      ctx.quadraticCurveTo(x+1,y,x+1+rad,y);
      ctx.lineTo(x+bw-1-rad,y);
      ctx.quadraticCurveTo(x+bw-1,y,x+bw-1,y+rad);
      ctx.lineTo(x+bw-1,mg.t+ph);
    }
    ctx.fill();
  }
  ctx.strokeStyle='#9ca3af';ctx.lineWidth=1;
  ctx.beginPath();ctx.moveTo(mg.l,mg.t);ctx.lineTo(mg.l,mg.t+ph);ctx.lineTo(mg.l+pw,mg.t+ph);ctx.stroke();
  ctx.fillStyle='#6b7280';ctx.font='11px sans-serif';ctx.textAlign='center';
  for(var i=0;i<=4;i++){var v=(i*.25).toFixed(2);var x=mg.l+i*.25*pw;ctx.fillText(v,x,mg.t+ph+14)}
  ctx.fillText('One-box probability (p)',w/2,mg.t+ph+30);
  ctx.textAlign='right';
  for(var i=0;i<=4;i++){var v=Math.round(mx*i/4);var y=mg.t+ph-ph*i/4;ctx.fillText(v,mg.l-5,y+4)}
  var ap=avg(pop);
  ctx.strokeStyle='#f59e0b';ctx.lineWidth=2;ctx.setLineDash([4,4]);
  var ax=mg.l+ap*pw;
  ctx.beginPath();ctx.moveTo(ax,mg.t);ctx.lineTo(ax,mg.t+ph);ctx.stroke();ctx.setLineDash([]);
  ctx.fillStyle='#f59e0b';ctx.font='bold 11px sans-serif';ctx.textAlign=ap>0.5?'right':'left';
  ctx.fillText('avg='+ap.toFixed(3),ax+(ap>0.5?-4:4),mg.t+10);
}

var lineChart;
function resetLine(){
  if(lineChart)lineChart.destroy();
  lineChart=new Chart(document.getElementById('ncb-evo-line'),{
    type:'scatter',
    data:{datasets:[{data:[{x:0,y:hist[0].p}],showLine:true,borderColor:'#2563eb',borderWidth:2,pointRadius:0,tension:.3,fill:false}]},
    options:{responsive:true,maintainAspectRatio:false,animation:false,
      scales:{x:{type:'linear',min:0,max:MAX_GEN,title:{display:true,text:'Generation',font:{size:13}},ticks:{stepSize:10}},
              y:{min:0,max:1,title:{display:true,text:'Avg one-box probability',font:{size:13}}}},
      plugins:{legend:{display:false},tooltip:{enabled:false}}
    },
    plugins:[{id:'refline',afterDraw:function(ch){
      var yA=ch.scales.y,ctx=ch.ctx,py=yA.getPixelForValue(0.5);
      ctx.save();ctx.strokeStyle='#d1d5db';ctx.lineWidth=1;ctx.setLineDash([4,4]);
      ctx.beginPath();ctx.moveTo(ch.scales.x.left,py);ctx.lineTo(ch.scales.x.right,py);ctx.stroke();ctx.restore();
    }}]
  });
}

function updateDisplay(){
  drawHist();
  if(lineChart){
    lineChart.data.datasets[0].data=hist.map(function(h){return{x:h.g,y:h.p}});
    lineChart.update('none');
  }
  document.getElementById('ncb-evo-gen').textContent=gen;
  document.getElementById('ncb-evo-avgp').textContent=avg(pop).toFixed(3);
  var lastPay=hist.length>1?hist[hist.length-1].pay:null;
  document.getElementById('ncb-evo-pay').innerHTML=lastPay?'<span>$</span>'+(lastPay/1000).toFixed(0)+'K':'—';
}

function start(){
  if(running)return;running=true;
  document.getElementById('ncb-evo-play').textContent='⏸ Pause';
  timer=setInterval(function(){runGen();if(gen>=MAX_GEN)stop()},speed);
}
function stop(){
  running=false;document.getElementById('ncb-evo-play').textContent='▶ Play';
  if(timer){clearInterval(timer);timer=null}
}

document.getElementById('ncb-evo-play').addEventListener('click',function(){running?stop():start()});
document.getElementById('ncb-evo-step').addEventListener('click',function(){stop();runGen()});
document.getElementById('ncb-evo-reset').addEventListener('click',init);
document.getElementById('ncb-evo-q').addEventListener('input',function(){
  q=parseInt(this.value)/100;document.getElementById('ncb-evo-q-val').textContent=q.toFixed(2);
});
document.getElementById('ncb-evo-speed').addEventListener('input',function(){
  speed=parseInt(this.value);document.getElementById('ncb-evo-speed-val').textContent=speed;
  if(running){clearInterval(timer);timer=setInterval(function(){runGen();if(gen>=MAX_GEN)stop()},speed)}
});
window.addEventListener('resize',function(){if(!running){setupCanvas();drawHist()}});
init();
})();
</script>

<p>When the predictor is 70% accurate or better, populations evolve toward near-pure one-boxing within ~20 generations ($p &gt; 0.9$). Even at $q = 0.51$, barely better than a coin, there’s a slow drift upward. Evolution doesn’t care about causal philosophy; it follows the payoff gradient.</p>

<h2 id="lens-3-data-vs-counterfactuals">Lens 3: Data vs. Counterfactuals</h2>

<p>The third lens is the most empirical. Suppose you’re not a philosopher but a statistician. You observe 10,000 people play Newcomb’s game. The data is unambiguous: one-boxers average \$990,000. Two-boxers average \$11,000. The observational conditional $E[\text{payoff} \mid \text{action} = a]$, the average payoff grouped by observed action, overwhelmingly favors one-boxing.</p>

<p>The two-boxer’s defense is a counterfactual: “Those one-boxers <em>would have</em> gotten \$1,001,000 if they had two-boxed.” This claim may be true. But it is unobservable. You never see the same person both one-box and two-box under the same prediction. This is the <strong>fundamental problem of causal inference</strong>: the impossibility of observing both potential outcomes for the same unit. In fact, the structure is identical to treatment effect estimation, where the same gap between observed and counterfactual outcomes makes naively comparing treated and untreated groups unreliable:</p>

<table>
  <thead>
    <tr>
      <th>Causal inference</th>
      <th>Newcomb’s problem</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Treatment assignment</td>
      <td>Your action</td>
    </tr>
    <tr>
      <td>Outcome under treatment</td>
      <td>Payoff if one-box</td>
    </tr>
    <tr>
      <td>Outcome under control</td>
      <td>Payoff if two-box</td>
    </tr>
    <tr>
      <td>Confounder</td>
      <td>Disposition $\theta$</td>
    </tr>
    <tr>
      <td>Fundamental problem</td>
      <td>Same person can’t do both</td>
    </tr>
  </tbody>
</table>

<p>The expected payoffs can be computed in closed form. Plotting them as a function of the predictor’s accuracy makes the gap visible, and shows exactly where it hides:</p>

<div class="ncb-widget">
<div class="ncb-chart-wrap" style="height:360px;">
<canvas id="ncb-gap-chart"></canvas>
</div>
<div class="ncb-controls">
<div class="ncb-control">
<label>Highlight accuracy: <strong><span id="ncb-q3-val">0.99</span></strong></label>
<input type="range" id="ncb-q3" min="95" max="99" step="1" value="99" />
</div>
</div>
<div class="ncb-readout" id="ncb-gap-readout"></div>
</div>

<script>
(function(){
var M=1000000,K=1000;
function oneObs(q){return q*M}
function twoObs(q){return(1-q)*(M+K)+q*K}
function counter(q){return q*M+K}
function fmtD(n){return'<span>$</span>'+n.toLocaleString('en-US',{maximumFractionDigits:0})}

var qs=[];for(var i=95;i<=100;i+=0.5)qs.push(i/100);
var d1=qs.map(function(q){return{x:q,y:oneObs(q)/1000}});
var d3=qs.map(function(q){return{x:q,y:counter(q)/1000}});
var d2=qs.map(function(q){return{x:q,y:twoObs(q)/1000}});
var currentQ=0.99;

var chart=new Chart(document.getElementById('ncb-gap-chart'),{
  type:'scatter',
  data:{datasets:[
    {label:'One-box (observed)',data:d1,yAxisID:'y',showLine:true,borderColor:'#2563eb',borderWidth:2.5,pointRadius:0,tension:0,order:2},
    {label:'One-box (counterfactual)',data:d3,yAxisID:'y',showLine:true,borderColor:'#16a34a',borderWidth:2,borderDash:[6,4],pointRadius:0,tension:0,
     fill:{target:0,above:'rgba(22,163,106,0.18)'},order:1},
    {label:'Two-box (observed)',data:d2,yAxisID:'y1',showLine:true,borderColor:'#dc2626',borderWidth:2.5,pointRadius:0,tension:0,order:3},
    {label:'_hl1',data:[{x:currentQ,y:oneObs(currentQ)/1000},{x:currentQ,y:counter(currentQ)/1000}],
     yAxisID:'y',pointRadius:7,pointBackgroundColor:['#2563eb','#16a34a'],pointBorderColor:'#fff',pointBorderWidth:2,showLine:false,order:0},
    {label:'_hl2',data:[{x:currentQ,y:twoObs(currentQ)/1000}],
     yAxisID:'y1',pointRadius:7,pointBackgroundColor:['#dc2626'],pointBorderColor:'#fff',pointBorderWidth:2,showLine:false,order:0}
  ]},
  options:{
    responsive:true,maintainAspectRatio:false,animation:false,
    scales:{
      x:{type:'linear',min:0.95,max:1.00,title:{display:true,text:'Predictor accuracy (q)',font:{size:13}},
         ticks:{callback:function(v){return v.toFixed(2)},stepSize:0.01}},
      y:{type:'linear',position:'left',min:945,max:1005,
         title:{display:true,text:'One-box payoff ($K)',font:{size:13},color:'#2563eb'},
         ticks:{color:'#2563eb',callback:function(v){return'$'+v+'K'}},
         grid:{drawOnChartArea:true}},
      y1:{type:'linear',position:'right',min:0,max:60,
          title:{display:true,text:'Two-box payoff ($K)',font:{size:13},color:'#dc2626'},
          ticks:{color:'#dc2626',callback:function(v){return'$'+v+'K'}},
          grid:{drawOnChartArea:false}}
    },
    plugins:{
      legend:{position:'top',labels:{usePointStyle:true,pointStyle:'line',font:{size:12},
        filter:function(item){return item.text.charAt(0)!=='_'}}},
      tooltip:{enabled:false},
      filler:{propagate:true}
    }
  },
  plugins:[{
    id:'gapLabel',
    afterDraw:function(ch){
      var xA=ch.scales.x,yA=ch.scales.y,ctx=ch.ctx;
      var px=xA.getPixelForValue(currentQ);
      ctx.save();ctx.strokeStyle='#f59e0b';ctx.lineWidth=1.5;ctx.setLineDash([4,4]);
      ctx.beginPath();ctx.moveTo(px,yA.top);ctx.lineTo(px,yA.bottom);ctx.stroke();
      var y1=yA.getPixelForValue(oneObs(currentQ)/1000);
      var y2=yA.getPixelForValue(counter(currentQ)/1000);
      if(Math.abs(y1-y2)>2){
        ctx.strokeStyle='#16a34a';ctx.lineWidth=2;ctx.setLineDash([]);
        ctx.beginPath();ctx.moveTo(px+12,y1);ctx.lineTo(px+12,y2);ctx.stroke();
        ctx.beginPath();ctx.moveTo(px+9,y1);ctx.lineTo(px+15,y1);ctx.stroke();
        ctx.beginPath();ctx.moveTo(px+9,y2);ctx.lineTo(px+15,y2);ctx.stroke();
        ctx.fillStyle='#16a34a';ctx.font='bold 11px sans-serif';ctx.textAlign='left';
        ctx.fillText('$1K gap',px+18,(y1+y2)/2+4);
      }
      ctx.restore();
    }
  }]
});

function update(){
  var q=parseInt(document.getElementById('ncb-q3').value)/100;
  currentQ=q;
  document.getElementById('ncb-q3-val').textContent=q.toFixed(2);
  chart.data.datasets[3].data=[{x:q,y:oneObs(q)/1000},{x:q,y:counter(q)/1000}];
  chart.data.datasets[4].data=[{x:q,y:twoObs(q)/1000}];
  chart.update('none');
  var gap=counter(q)-oneObs(q);
  document.getElementById('ncb-gap-readout').innerHTML=
    'At <em>q</em> = '+q.toFixed(2)+': One-boxers earn <strong>'+fmtD(oneObs(q))+
    '</strong> · Two-boxers earn <strong>'+fmtD(twoObs(q))+
    '</strong> · Counterfactual: <strong>'+fmtD(counter(q))+
    '</strong><br>The <span style="color:#16a34a;font-weight:600">green band</span> is the unobservable gap: <strong>'+fmtD(gap)+
    '</strong>. You\'d need to observe the same person doing both to see it.';
}
document.getElementById('ncb-q3').addEventListener('input',update);
update();
})();
</script>

<p>The top dashed line is the two-boxer’s counterfactual claim: one-boxers <em>would have</em> earned \$1,001,000 if they had grabbed both boxes with the same prediction. That line is real, and invisible. At $q = 0.99$, the gap between the observed one-box payoff (\$990,000) and the counterfactual (\$991,000) is exactly \$1,000. You’d need to observe the same person doing both to see it. You can’t.</p>

<p>If you’re a frequentist who follows the data, you one-box. If you’re a structural modeler who trusts your causal graph over the observed conditional, you two-box. Neither is obviously wrong. They’re optimizing different things: one follows the joint distribution the agent is <em>embedded</em> in, the other follows the causal structure the agent can <em>manipulate</em>.</p>

<div class="callout-anecdote">
<strong>Remark.</strong> This tension shows up everywhere, not just in philosophical musing. <br /><br />

A hospital observes that patients who receive a new drug have better outcomes, but sicker patients were more likely to be prescribed it; the raw conditional favors the drug, but the causal effect might be zero. <br /><br />

A company sees that employees who attend a leadership program get promoted faster, but the same ambition that drives attendance also drives promotion; conditioning on attendance overstates the program's value. <br /><br />

A spam filter flags emails based on features that spammers also select for; blocking those emails changes what spammers send next, invalidating the very distribution the filter was trained on. <br /><br />

In each case the question is the same: do you trust the pattern in the data, or the causal story behind it?
</div>

<h2 id="lens-4-oblivious-vs-adaptive-adversaries">Lens 4: Oblivious vs. Adaptive Adversaries</h2>

<p>The fourth lens comes from online learning and the theory of multi-armed bandits. In this setting, a learner repeatedly chooses actions, and an adversary determines the losses. The central question is: <em>what kind of adversary are you facing?</em></p>

<p>An <strong>oblivious</strong> adversary commits to the entire loss sequence before the game begins. It doesn’t see or react to the learner’s actions. Against an oblivious adversary, the natural performance measure is <strong>swap regret</strong>: “Holding the loss sequence fixed, could I have earned more by switching my action?” If yes, you have regret. The optimal response is straightforward: play the dominant action, since the environment won’t change.</p>

<p>An <strong>adaptive</strong> adversary observes the learner’s policy (or past behavior) and adjusts losses accordingly. Against an adaptive adversary, swap regret is misleading: the losses <em>would have been different</em> under a different policy. The right measure becomes <strong>policy regret</strong>: “Would a different <em>policy</em> have produced better outcomes, accounting for how the adversary would have responded to that policy?”</p>

<p>Linking this back to Newcomb’s problem:</p>

<table>
  <thead>
    <tr>
      <th>Online learning</th>
      <th>Newcomb’s problem</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Learner’s policy $\pi$</td>
      <td>Your decision algorithm</td>
    </tr>
    <tr>
      <td>Adversary’s loss sequence</td>
      <td>Box contents</td>
    </tr>
    <tr>
      <td>Oblivious adversary</td>
      <td>CDT: contents are fixed</td>
    </tr>
    <tr>
      <td>Adaptive adversary</td>
      <td>EDT/FDT: contents respond to your policy</td>
    </tr>
    <tr>
      <td>Swap regret</td>
      <td>“I’d get \$1,000 more by switching to two-box”</td>
    </tr>
    <tr>
      <td>Policy regret</td>
      <td>“A two-box <em>policy</em> leads to an empty Box B”</td>
    </tr>
  </tbody>
</table>

<p>CDT treats the predictor as oblivious. The money is placed, the game state is fixed, and two-boxing is the dominant action, exactly the swap-regret argument. The two-boxer says: “Holding Box B fixed, I always get \$1,000 more.”</p>

<p>EDT and FDT treat the predictor as adaptive. The predictor responded to your algorithm, so the box contents are a <em>function</em> of your policy. Switching from a one-box policy to a two-box policy doesn’t just change your action; it changes the adversary’s response. The one-boxer says: “A two-box <em>policy</em> faces an empty Box B.”</p>

<p>The precise role of anticipation, i.e., the adversary’s ability to foresee not just the learner’s policy but also their realization of randomness, has been studied in detail in the online learning setting (see e.g., <a href="https://arxiv.org/abs/2101.11443">Pokutta and Xu, 2021</a>, where we looked at this in particular in the context of robust optimization). When the adversary can anticipate the learner’s random coin flips, even randomized strategies lose their hedging value. The Newcomb predictor, with 99% accuracy, sits squarely in this regime: it anticipates not just your policy but your execution.</p>

<p>This reframing is clarifying because the online learning community has precise theorems about when each regret notion applies. Against a truly oblivious adversary, swap regret is tight and achievable. Against an adaptive adversary, minimizing swap regret can be catastrophically wrong; you need policy regret, which accounts for how the environment co-adapts. The entire Newcomb debate reduces to a classification question: <strong>is the predictor oblivious or adaptive?</strong></p>

<p>The answer, of course, depends on your ontology. If you believe the box contents are a physical fact determined before your choice (oblivious), CDT follows. If you believe the predictor adapted to your decision algorithm and the contents are therefore policy-dependent (adaptive), one-boxing follows. The bandit framework doesn’t resolve the paradox, but it reveals its skeleton: the same structural ambiguity that separates oblivious from adaptive adversaries in online learning separates two-boxers from one-boxers in Newcomb’s problem.</p>

<h2 id="the-mixed-strategy-flipping-a-coin">The Mixed Strategy: Flipping a Coin</h2>

<p>The first three lenses assume a deterministic chooser (the bandit lens already allows randomized policies, but there the focus was on regret notions, not on what randomization does to the predictor). So what if you flip a biased coin: one-box with probability $p$, two-box with probability $1-p$?</p>

<p>This breaks the predictor. A predictor that’s 99% accurate against deterministic strategies can’t beat $\max(p, 1-p)$ against a genuinely random (but biased) coin (i.e., private randomness as the boxes have been set up already). The predictor’s best response is simple: predict “one-box” (and fill Box B) if $p \geq 0.5$, predict “two-box” (and leave Box B empty) if $p &lt; 0.5$. Under this best response, the predictor’s effective accuracy is</p>

\[q^*(p) = \max(p, 1-p)\]

<p>which hits its minimum of $50\%$ at $p = 0.5$: a fair coin reduces the “99% accurate” predictor to a coin flip. The expected payoff works out to:</p>

\[E[\text{payoff}] = \begin{cases} M + (1-p) \cdot K &amp; \text{if } p &gt; 0.5 \text{ (predictor fills B)} \\ (1-p) \cdot K &amp; \text{if } p &lt; 0.5 \text{ (predictor empties B)} \end{cases}\]

<p>This creates a phase transition, a million-dollar cliff:</p>

<div class="ncb-widget">
<div class="ncb-chart-wrap" style="height:380px;">
<canvas id="ncb-mixed-chart"></canvas>
</div>
<div class="ncb-controls">
<div class="ncb-control">
<label>One-box probability: <strong><span id="ncb-p4-val">0.51</span></strong></label>
<input type="range" id="ncb-p4" min="0" max="100" step="1" value="51" />
</div>
</div>
<div class="ncb-readout" id="ncb-mixed-readout"></div>
</div>

<script>
(function(){
var M=1000000,K=1000;
function payoff(p){return p>0.5?M+(1-p)*K:p<0.5?(1-p)*K:M+0.5*K}
function predAcc(p){return Math.max(p,1-p)}
function fmtD(n){return'<span>$</span>'+n.toLocaleString('en-US',{maximumFractionDigits:0})}

var lowD=[],highD=[],cliff=[],accD=[];
for(var i=0;i<=98;i++){var p=i/200;lowD.push({x:p,y:(1-p)*K/1000})}
lowD.push({x:0.499,y:0.501*K/1000});
cliff.push({x:0.499,y:0.501*K/1000});
cliff.push({x:0.501,y:(M+0.499*K)/1000});
highD.push({x:0.501,y:(M+0.499*K)/1000});
for(var i=102;i<=200;i++){var p=i/200;highD.push({x:p,y:(M+(1-p)*K)/1000})}
for(var i=0;i<=200;i++){var p=i/200;accD.push({x:p,y:Math.max(p,1-p)*100})}

var currentP=0.51;

var chart=new Chart(document.getElementById('ncb-mixed-chart'),{
  type:'scatter',
  data:{datasets:[
    {label:'Predictor empties Box B',data:lowD,showLine:true,borderColor:'#dc2626',borderWidth:2.5,pointRadius:0,tension:0,fill:false},
    {label:'Predictor fills Box B',data:highD,showLine:true,borderColor:'#2563eb',borderWidth:2.5,pointRadius:0,tension:0,fill:false},
    {label:'Phase transition',data:cliff,showLine:true,borderColor:'#9ca3af',borderWidth:1.5,borderDash:[5,4],pointRadius:0,tension:0},
    {label:'Predictor accuracy',data:accD,yAxisID:'y1',showLine:true,borderColor:'#9333ea',borderWidth:1.5,borderDash:[4,3],pointRadius:0,tension:0},
    {label:'_pos',data:[{x:currentP,y:payoff(currentP)/1000}],pointRadius:8,pointBackgroundColor:'#f59e0b',pointBorderColor:'#fff',pointBorderWidth:2,showLine:false}
  ]},
  options:{
    responsive:true,maintainAspectRatio:false,animation:false,
    scales:{
      x:{type:'linear',min:0,max:1,title:{display:true,text:'One-box probability (p)',font:{size:13}},
         ticks:{callback:function(v){return v.toFixed(1)}}},
      y:{type:'linear',position:'left',title:{display:true,text:'Expected payoff ($K)',font:{size:13}},min:0,max:1100,
         ticks:{callback:function(v){return v>=1000?'$'+v/1000+'M':'$'+v+'K'}},
         grid:{drawOnChartArea:true}},
      y1:{type:'linear',position:'right',min:50,max:100,
          title:{display:true,text:'Predictor accuracy (%)',font:{size:13},color:'#9333ea'},
          ticks:{color:'#9333ea',callback:function(v){return v+'%'}},
          grid:{drawOnChartArea:false}}
    },
    plugins:{
      legend:{position:'top',labels:{usePointStyle:true,pointStyle:'line',font:{size:12},
        filter:function(item){return item.text.charAt(0)!=='_'&&item.text!=='Phase transition'}}},
      tooltip:{enabled:false}
    }
  },
  plugins:[{
    id:'pLine',
    afterDraw:function(ch){
      var xA=ch.scales.x,yA=ch.scales.y,ctx=ch.ctx;
      var px=xA.getPixelForValue(currentP);
      ctx.save();ctx.strokeStyle='#f59e0b';ctx.lineWidth=1.5;ctx.setLineDash([4,4]);
      ctx.beginPath();ctx.moveTo(px,yA.top);ctx.lineTo(px,yA.bottom);ctx.stroke();
      var tx=xA.getPixelForValue(0.5);
      ctx.strokeStyle='#d1d5db';ctx.lineWidth=1;ctx.setLineDash([3,3]);
      ctx.beginPath();ctx.moveTo(tx,yA.top);ctx.lineTo(tx,yA.bottom);ctx.stroke();
      ctx.fillStyle='#9ca3af';ctx.font='11px sans-serif';ctx.textAlign='center';
      ctx.fillText('p = 0.5',tx,yA.bottom+30);
      ctx.restore();
    }
  }]
});

function update(){
  var p=parseInt(document.getElementById('ncb-p4').value)/100;
  currentP=p;
  document.getElementById('ncb-p4-val').textContent=p.toFixed(2);
  chart.data.datasets[4].data=[{x:p,y:payoff(p)/1000}];
  chart.update('none');
  var pay=payoff(p),acc=predAcc(p);
  var resp=p>=0.5?'Fill Box B (predicts one-box)':'Empty Box B (predicts two-box)';
  var vs1=pay-M,vs0=pay-K;
  document.getElementById('ncb-mixed-readout').innerHTML=
    '<strong>Strategy:</strong> One-box with probability '+p.toFixed(2)+', two-box with probability '+(1-p).toFixed(2)+
    '<br><strong>Predictor best response:</strong> '+resp+' · Effective accuracy: '+(acc*100).toFixed(1)+'%'+
    '<br><strong>Expected payoff:</strong> '+fmtD(pay)+
    (p>=0.5?' (vs. pure one-box '+fmtD(M)+': '+(vs1>=0?'+':'')+fmtD(vs1)+')':
            ' (vs. pure two-box '+fmtD(K)+': '+(vs0>=0?'+':'')+fmtD(vs0)+')');
}
document.getElementById('ncb-p4').addEventListener('input',update);
update();
})();
</script>

<p>At $p = 0.49$, the predictor leaves Box B empty and you average \$510. At $p = 0.51$, the predictor fills Box B and you average \$1,000,490. A 2% shift in coin bias produces a \$999,980 jump in expected payoff.</p>

<p>The optimal mixed strategy is $p$ just above $0.5$: one-box slightly more than half the time. This earns approximately \$1,000,500, which <em>beats</em> pure one-boxing (\$1,000,000) by \$500. You get the million (the predictor fills Box B because you’re majority one-box) while occasionally grabbing the extra \$1,000 when the coin lands on two-box; it is a bit like reaping the extra \$1,000 from an occasional counterfactual switch.</p>

<table>
  <thead>
    <tr>
      <th>Strategy</th>
      <th>Expected payoff</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>Pure two-box ($p = 0$)</td>
      <td>\$1,000</td>
    </tr>
    <tr>
      <td>Pure one-box ($p = 1$)</td>
      <td>\$1,000,000</td>
    </tr>
    <tr>
      <td>Optimal mixed ($p \approx 0.51$)</td>
      <td>\$1,000,490</td>
    </tr>
  </tbody>
</table>

<p>But the optimal mixed strategy is fragile in a way that pure one-boxing is not. It depends on the predictor having a sharp threshold at $p = 0.5$ and not being able to anticipate the randomization itself. A predictor that models coin-flipping agents might demand $p &gt; 0.9$ (i.e., the predictor’s stated accuracy also determines which $p$ are admissible) before filling Box B, and then the optimal response shifts to $p$ just above 0.9, recovering less of the two-boxing bonus. In the limit where the predictor demands certainty (i.e., full anticipation of the random outcome of the coin flip), you’re back to pure one-boxing.</p>

<p>In some sense, mixed strategies reveal that Newcomb’s problem is really a <em>game</em> between the chooser and the predictor, and the payoff landscape has the structure of a game-theoretic discontinuity. In particular, the predictor isn’t just a feature of the environment; it’s a player.</p>

<h2 id="the-fixed-point">The Fixed Point</h2>

<p>There’s a final mathematical observation that cuts across all four lenses. The predictor’s accuracy creates a self-referential loop: the prediction depends on your reasoning, which depends on what you expect the predictor predicted, and so on… At equilibrium, this must be a <strong>fixed point</strong>: your strategy $\sigma$ and the predictor’s model $\hat{\sigma}$ must satisfy $\hat{\sigma} = \sigma$.</p>

<p>At any such fixed point, the “I’ll trick the predictor” intuition behind two-boxing is unstable. If your strategy is to two-box, the predictor knows, and Box B is empty. If your strategy is to one-box, the predictor knows, and Box B is full. You can’t deviate profitably <em>because the prediction already accounts for your reasoning about the prediction</em>. The fixed point is self-enforcing.</p>

<p>There is a useful game-theoretic way to see this. In the original setup, the move order is: predictor fills boxes (move 1), then you choose (move 2). Two-boxing exploits last-mover advantage: you observe a fixed game state and pick the dominant action. But as the predictor’s accuracy $q \to 1$, the effective move order <em>inverts</em>. A near-perfect predictor reacts to your strategy as if it moved <em>after</em> you, not before. The temporal sequence stays the same (boxes first, choice second), but the strategic sequence flips: the predictor’s move is now essentially a best response to yours. At $q = 1$ the game is equivalent to one where you commit to a strategy first and the predictor fills the boxes second. In that game, one-boxing is obviously correct and two-boxing is obviously foolish.</p>

<p>This is why Newcomb’s problem feels so different from ordinary strategic interaction. In a standard game, you choose against a fixed opponent. In Newcomb’s problem, you choose against a mirror. The four lenses, causal, algorithmic, empirical, adversarial, are four ways of formalizing what it means to make a decision when the universe has already priced in the fact that you’re going to make it.</p>

<div class="callout">
<strong>Takeaway.</strong> The real disagreement between CDT, EDT, and FDT is not about utility calculations; it is about whether the predictor is <em>anticipatory</em>. If the prediction is fixed before you deliberate, two-boxing strictly dominates. If the predictor anticipates your decision procedure, one-boxing is the only stable strategy. Newcomb's problem persists because each decision theory hard-codes a different answer to this question, and the problem statement is carefully silent on which one is right.
</div>

<h2 id="references">References</h2>

<p>[N] Nozick, R. (1969). Newcomb’s Problem and Two Principles of Choice. In N. Rescher et al. (eds.), <em>Essays in Honor of Carl G. Hempel</em>, pp. 114-146. D. Reidel, Dordrecht. <a href="https://danielhoek.com/wp-content/uploads/2020/02/Nozick-Newcombs-Problem-and-Two-Principles-of-Choice.pdf">PDF</a></p>

<p>[P] Pearl, J. (2009). <em>Causality: Models, Reasoning, and Inference</em>. 2nd ed. Cambridge University Press.</p>

<p>[YS] Yudkowsky, E. &amp; Soares, N. (2017). Functional Decision Theory: A New Theory of Instrumental Rationality. <a href="https://arxiv.org/abs/1710.05060">arXiv:1710.05060</a></p>

<p>[B] Bostrom, N. (2002). <em>Anthropic Bias: Observation Selection Effects in Science and Philosophy</em>. Routledge.</p>

<p>[CBL] Cesa-Bianchi, N. &amp; Lugosi, G. (2006). <em>Prediction, Learning, and Games</em>. Cambridge University Press.</p>

<p>[PX] Pokutta, S. &amp; Xu, H. (2021). Adversaries in Online Learning Revisited: with applications in Robust Optimization and Adversarial training. <a href="https://arxiv.org/abs/2101.11443">arXiv:2101.11443</a></p>

<p>[GH] Gibbard, A. &amp; Harper, W. (1978). Counterfactuals and Two Kinds of Expected Utility. In C.A. Hooker, J.J. Leach &amp; E.F. McClennen (eds.), <em>Foundations and Applications of Decision Theory, Vol. II</em>, pp. 125-162. D. Reidel, Dordrecht.</p>

<p>[SEP] Stanford Encyclopedia of Philosophy. <a href="https://plato.stanford.edu/entries/decision-causal/">Causal Decision Theory</a>.</p>

<p>[PP] PhilPeople. <a href="https://survey2020.philpeople.org/survey/results/4886">2020 PhilPapers Survey: Newcomb’s Problem</a>.</p>

<p>[O] Oesterheld, C. (2017). <a href="https://casparoesterheld.com/2017/06/27/a-survey-of-polls-on-newcombs-problem/">A Survey of Polls on Newcomb’s Problem</a>.</p>

<p>[W] Wikipedia. <a href="https://en.wikipedia.org/wiki/Newcomb%27s_problem">Newcomb’s Problem</a>.</p>]]></content><author><name>Sebastian Pokutta</name></author><category term="random" /><category term="decision-theory" /><category term="game-theory" /><category term="philosophy" /><category term="causality" /><category term="online-learning" /><summary type="html"><![CDATA[TL;DR: Newcomb’s paradox — should you take one box or two? — splits rational decision-makers almost evenly. There are four natural mathematical frameworks (causal inference, algorithmic self-reference, statistical counterfactuals, and online learning) that give different answers, and the disagreement reveals deep structural tensions in what it means to choose rationally.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" /><media:content medium="image" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Do LLM Outputs Mirror Their Internal Semantic Maps? A Large-Scale Behavioral Probing Study</title><link href="http://www.pokutta.com/blog/research/2026/03/06/neural-semantic-geometry.html" rel="alternate" type="text/html" title="Do LLM Outputs Mirror Their Internal Semantic Maps? A Large-Scale Behavioral Probing Study" /><published>2026-03-06T00:00:00+01:00</published><updated>2026-03-06T00:00:00+01:00</updated><id>http://www.pokutta.com/blog/research/2026/03/06/neural-semantic-geometry</id><content type="html" xml:base="http://www.pokutta.com/blog/research/2026/03/06/neural-semantic-geometry.html"><![CDATA[<p><em>TL;DR: How faithfully does an LLM’s text output reflect the semantic geometry encoded in its hidden states? Forced-choice behavioral probing recovers substantially more internal similarity structure than open-ended generation, and behavioral features improve prediction of unseen hidden-state similarities above lexical and cross-model baselines.</em></p>

<!--more-->

<p><em>Written by <a href="https://schiekiera.github.io/">Louis Schiekiera</a>.</em></p>

<h2 id="the-core-question">The core question</h2>

<p>Cognitive scientists have long inferred semantic structure from observable behavior: show someone the word <em>dog</em>, record what they associate with it (<em>cat</em>, <em>leash</em>, <em>bark</em>), repeat across many cues, and the resulting response patterns sketch an approximate map of an otherwise hidden meaning system (De Deyne et al., 2019). LLMs offer a model system to test this logic. Unlike human participants, a language model’s internal representations are directly accessible alongside its behavioral output. So we can ask a sharper question: <strong>when we probe an LLM with word-association tasks, how much of its hidden-state semantic geometry actually shows up in the responses it produces?</strong></p>

<p>That is the focus of our recent preprint, <a href="https://arxiv.org/abs/2602.00628"><em>From Associations to Activations</em></a> led by <a href="https://schiekiera.github.io/">Louis Schiekiera</a>. Rather than comparing model behavior to human norms, we compare each model’s behavior to its <em>own</em> layerwise hidden states—treating the model as both the subject and the ground truth.</p>

<div style="text-align:center; margin-bottom: 20px;">
    <img src="http://www.pokutta.com/blog/assets/neural-semantic-geometry/conceptual.svg" alt="Conceptual overview of the framework" style="width:80%;" />
    <p style="font-size: small; font-style: italic;">Figure 1: Overview of the approach. A shared vocabulary feeds two pipelines: (i) layerwise hidden-state extraction produces a hidden-state similarity matrix, and (ii) behavioral association tasks (forced choice or free association) yield a behavioral similarity matrix. Representational similarity analysis (RSA) then quantifies how well the two geometries match.</p>
</div>

<h2 id="experimental-setup-at-a-glance">Experimental setup at a glance</h2>

<h3 id="models-under-study">Models under study</h3>

<p>We tested eight instruction-tuned decoder-only transformers spanning 7B to 14B parameters: Falcon3, Gemma-2, Llama-3.1, Mistral-7B, Mistral-Nemo, Phi-4, Qwen2.5, and rnj-1. All experiments share a single 5,000-noun vocabulary drawn from the SUBTLEX-US frequency list (Brysbaert et al., 2012).</p>

<h3 id="two-ways-to-elicit-semantic-behavior">Two ways to elicit semantic behavior</h3>

<p>We borrowed two classic paradigms from psycholinguistics.</p>

<div style="text-align:center; margin-bottom: 20px;">
    <img src="http://www.pokutta.com/blog/assets/neural-semantic-geometry/both_paradigms.svg" alt="Forced choice and free association paradigms" style="width:99%;" />
    <p style="font-size: small; font-style: italic;">Figure 2: Illustration of the two behavioral paradigms. In forced choice (left), a cue word is paired with a candidate set and the model picks the most related items. In free association (right), the model generates associates from scratch. Both produce cue–response count matrices whose row-wise cosine similarities define behavioral semantic geometries.</p>
</div>

<p><strong>Forced choice (FC).</strong> Each cue appears with 16 candidate words; the model selects exactly two that are most semantically related. A deterministic shuffle of the remaining vocabulary produces 313 unique candidate sets per cue.</p>

<p><strong>Free association (FA).</strong> Each cue is presented alone and the model generates five single-word associates. We repeat this across 126 stochastic runs per cue to accumulate stable response distributions.</p>

<p>Responses from both paradigms are aggregated into sparse cue–response count matrices. We apply positive pointwise mutual information (PPMI) reweighting to down-weight globally frequent responses, then compute cue–cue similarity via cosine between PPMI-weighted row vectors. Altogether, the dataset spans more than <strong>17.5 million trials</strong> across both paradigms and all eight models.</p>

<h3 id="extracting-hidden-state-geometry">Extracting hidden-state geometry</h3>

<p>For every model and every word in the vocabulary, we pulled layerwise hidden states under four contextual embedding strategies:</p>

<ul>
  <li><strong>Averaged</strong> — the word embedded in 50 naturally occurring C4 sentences (Raffel et al., 2020), hidden states averaged across contexts (Bommasani et al., 2020).</li>
  <li><strong>Meaning</strong> — a fixed definitional prompt (<em>“What is the meaning of the word {w}?”</em>).</li>
  <li><strong>Task (FC)</strong> — the word embedded in the forced-choice instruction prompt, minus the candidate list.</li>
  <li><strong>Task (FA)</strong> — the word embedded in the free-association instruction prompt.</li>
</ul>

<p>Cosine similarity between mean-centered layerwise vectors (Ethayarajh et al., 2019) yields a hidden-state similarity matrix for each model, layer, and extraction strategy.</p>

<h3 id="reference-baselines">Reference baselines</h3>

<p>Three external baselines anchor the comparison: <strong>FastText</strong> static word vectors (Bojanowski et al., 2017), <strong>BERT</strong> contextual embeddings (Devlin et al., 2019), and a <strong>cross-model consensus</strong> geometry that averages hidden-state similarities from all <em>other</em> models—motivated by evidence for a shared semantic subspace across architectures (Huh et al., 2024).</p>

<h3 id="how-we-measure-alignment">How we measure alignment</h3>

<p>We employed three complementary metrics:</p>

<ol>
  <li>
    <p><strong>RSA</strong> (Kriegeskorte et al., 2008; Nili et al., 2014) — Pearson correlation between vectorized upper-triangular entries of the hidden-state and reference similarity matrices, computed per layer.</p>
  </li>
  <li>
    <p><strong>Nearest-neighbor overlap</strong> ($\mathrm{NN@}k$) — fraction of shared $k$-nearest neighbors between hidden-state and reference similarity spaces.</p>
  </li>
  <li>
    <p><strong>Held-out-words ridge regression</strong> — can behavioral similarity predict hidden-state similarities for words the model never saw during training of the regression? This tests generalization beyond lexical baselines and cross-model consensus.</p>
  </li>
</ol>

<h2 id="key-findings">Key findings</h2>

<h3 id="constrained-tasks-recover-far-more-internal-structure">Constrained tasks recover far more internal structure</h3>

<p>The gap between paradigms is substantial. Forced-choice behavior aligns with hidden-state geometry far more strongly than free association—consistently, across every model and evaluation metric.</p>

<p>Under the best extraction strategy (Task FC), mean RSA reaches $r = .463$ for forced choice versus only $r = .199$ for free association. Even the weakest FC condition (Averaged extraction, $r = .346$) outperforms the strongest FA condition.</p>

<div style="text-align:center; margin-bottom: 20px;">
    <img src="http://www.pokutta.com/blog/assets/neural-semantic-geometry/rsa_nn_grid_1x2.svg" alt="Summary RSA and nearest-neighbor overlap results" style="width:99%;" />
    <p style="font-size: small; font-style: italic;">Figure 3: Aggregate alignment across models. Left: RSA correlation by layer. Right: nearest-neighbor overlap as a function of neighborhood size $k$ (log scale). Forced-choice behavior (green) tracks hidden-state structure far more closely than free association (red). Cross-model consensus (black) sets the ceiling.</p>
</div>

<p>Why does FC win so decisively? Its controlled candidate sets force every response to emerge from an explicit comparison, concentrating observations onto shared supports and producing a denser, less noisy cue–response matrix (Roads et al., 2021). Free association, by contrast, disperses probability mass across a long tail of idiosyncratic responses, yielding sparser vectors with lower signal-to-noise for recovering geometric structure.</p>

<h3 id="extraction-context-shifts-where-alignment-peaks">Extraction context shifts where alignment peaks</h3>

<p>The choice of how hidden states are extracted determines <em>which layers</em> show the strongest match.</p>

<div style="text-align:center; margin-bottom: 20px;">
    <img src="http://www.pokutta.com/blog/assets/neural-semantic-geometry/rsa_line_plot_1x2_grid_fc_fa.svg" alt="Layerwise RSA for FC and FA under different extraction strategies" style="width:99%;" />
    <p style="font-size: small; font-style: italic;">Figure 4: Layerwise RSA profiles under different extraction strategies. Task-aligned and meaning-focused prompts peak at earlier, mid-depth layers. Averaging over natural contexts shifts the peak to later layers.</p>
</div>

<p>Task-aligned and meaning-based prompts push the model into a comparable semantically focused processing mode, and peak alignment appears at earlier to mid-depth layers—consistent with evidence that core lexical-semantic representations crystallize in intermediate transformer blocks. Averaging over diverse natural contexts, by contrast, mixes senses and topics, diluting the word-level signal and shifting alignment peaks toward the final layers.</p>

<h3 id="the-paradigm-advantage-holds-across-all-eight-models">The paradigm advantage holds across all eight models</h3>

<p>Model-by-model heatmaps confirm that the FC superiority is universal, though its magnitude varies with architecture:</p>

<div style="text-align:center; margin-bottom: 20px;">
    <img src="http://www.pokutta.com/blog/assets/neural-semantic-geometry/rsa_fc_fa_2x4_grid.svg" alt="RSA heatmap across models" style="width:99%;" />
    <p style="font-size: small; font-style: italic;">Figure 5: Per-model RSA heatmaps. Each panel contrasts forced-choice (left sub-panel) and free-association (right sub-panel) behavioral similarity against hidden states, broken down by extraction strategy and summarized across layers.</p>
</div>

<h3 id="behavior-predicts-hidden-structure-on-unseen-words">Behavior predicts hidden structure on unseen words</h3>

<p>The held-out regression provides the most stringent test. After controlling for FastText, BERT, and cross-model consensus, adding FC behavioral similarity still improves mean test $R^2$ by $+.022$; FA adds a marginal $+.002$. The full model achieves mean $R^2 = .587$ (baseline: $.569$), peaking at $R^2 = .844$ for Llama-3.1-8B-Instruct.</p>

<div style="text-align:center; margin-bottom: 20px;">
    <img src="http://www.pokutta.com/blog/assets/neural-semantic-geometry/rr_model_performance_grid_2x4.svg" alt="Ridge regression performance across models" style="width:99%;" />
    <p style="font-size: small; font-style: italic;">Figure 6: Held-out ridge regression results for all eight models. Bold values indicate $R^2$ for the full predictor set (behavioral + baselines); parenthetical values show the baseline without behavioral features.</p>
</div>

<p>This means that behavioral probing captures something about a model’s internal semantic organization that lexical vectors and cross-model structure alone do not—especially when the behavioral measurement is carefully constrained.</p>

<h2 id="broader-implications">Broader implications</h2>

<h3 id="black-box-interpretability">Black-box interpretability</h3>

<p>When logits and activations are unavailable, behavioral probing remains an important path to interpretability. Forced-choice paradigms are especially promising: their constrained response sets act as structured measurement instruments that concentrate informative signal.</p>

<h3 id="lessons-for-cognitive-science">Lessons for cognitive science</h3>

<p>Our fully transparent LLM setup lets us rigorously test a foundational cognitive-science assumption—that structured behavior is constrained by, and therefore partially reveals, internal states. The sharp FC–FA divergence demonstrates that <em>whether</em> behavior reveals internal structure depends critically on the measurement protocol. Open-ended tasks are not inherently less informative; they simply distribute responses too thinly for cosine-based geometry recovery. Protocol design is itself a variable.</p>

<h3 id="a-shared-semantic-substrate">A shared semantic substrate</h3>

<p>One of the most important observations is the strength of cross-model consensus. Similarity structure aggregated from the other seven models explains a large share of variance in any target model’s hidden-state geometry, lending further support to the hypothesis of a common, low-dimensional semantic subspace across diverse LLM architectures (Huh et al., 2024).</p>

<h2 id="references">References</h2>

<ul>
  <li>
    <p>Bojanowski, P., Grave, E., Joulin, A., &amp; Mikolov, T. (2017). Enriching word vectors with subword information. <em>Transactions of the Association for Computational Linguistics, 5</em>, 135–146. <a href="https://doi.org/10.1162/tacl_a_00051">doi:10.1162/tacl_a_00051</a></p>
  </li>
  <li>
    <p>Bommasani, R., Davis, K., &amp; Cardie, C. (2020). Interpreting pretrained contextualized representations via reductions to static embeddings. In <em>Proceedings of the 58th Annual Meeting of the Association for Computational Linguistics</em> (pp. 4758–4781). <a href="https://doi.org/10.18653/v1/2020.acl-main.431">doi:10.18653/v1/2020.acl-main.431</a></p>
  </li>
  <li>
    <p>Brysbaert, M., New, B., &amp; Keuleers, E. (2012). Adding part-of-speech information to the SUBTLEX-US word frequencies. <em>Behavior Research Methods, 44</em>(4), 991–997. <a href="https://doi.org/10.3758/s13428-012-0190-4">doi:10.3758/s13428-012-0190-4</a></p>
  </li>
  <li>
    <p>De Deyne, S., Navarro, D. J., Perfors, A., Brysbaert, M., &amp; Storms, G. (2019). The Small World of Words: English word association norms for over 12,000 cue words. <em>Behavior Research Methods, 51</em>(3), 987–1006. <a href="https://doi.org/10.3758/s13428-018-1115-7">doi:10.3758/s13428-018-1115-7</a></p>
  </li>
  <li>
    <p>Devlin, J., Chang, M.-W., Lee, K., &amp; Toutanova, K. (2019). BERT: Pre-training of deep bidirectional transformers for language understanding. In <em>Proceedings of NAACL-HLT 2019</em> (pp. 4171–4186). <a href="https://doi.org/10.18653/v1/N19-1423">doi:10.18653/v1/N19-1423</a></p>
  </li>
  <li>
    <p>Ethayarajh, K. (2019). How contextual are contextualized word representations? Comparing the geometry of BERT, ELMo, and GPT-2 embeddings. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/1909.00512">arxiv:1909.00512</a></p>
  </li>
  <li>
    <p>Huh, M., Cheung, B., Wang, T., &amp; Isola, P. (2024). The platonic representation hypothesis. <em>arXiv preprint</em>. <a href="https://arxiv.org/abs/2405.07987">arxiv:2405.07987</a></p>
  </li>
  <li>
    <p>Kriegeskorte, N., Mur, M., &amp; Bandettini, P. A. (2008). Representational similarity analysis—connecting the branches of systems neuroscience. <em>Frontiers in Systems Neuroscience, 2</em>, 4. <a href="https://doi.org/10.3389/neuro.06.004.2008">doi:10.3389/neuro.06.004.2008</a></p>
  </li>
  <li>
    <p>Nili, H., Wingfield, C., Walther, A., Su, L., Marslen-Wilson, W., &amp; Kriegeskorte, N. (2014). A toolbox for representational similarity analysis. <em>PLoS Computational Biology, 10</em>(4), e1003553. <a href="https://doi.org/10.1371/journal.pcbi.1003553">doi:10.1371/journal.pcbi.1003553</a></p>
  </li>
  <li>
    <p>Raffel, C., Shazeer, N., Roberts, A., Lee, K., Narang, S., Matena, M., Zhou, Y., Li, W., &amp; Liu, P. J. (2020). Exploring the limits of transfer learning with a unified text-to-text transformer. <em>Journal of Machine Learning Research, 21</em>(140), 1–67. <a href="http://jmlr.org/papers/v21/20-074.html">jmlr.org</a></p>
  </li>
  <li>
    <p>Roads, B. D., &amp; Love, B. C. (2021). Enriching ImageNet with human similarity judgments and psychological embeddings. In <em>Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)</em> (pp. 3547–3557). <a href="https://doi.org/10.1109/CVPR46437.2021.00355">doi:10.1109/CVPR46437.2021.00355</a></p>
  </li>
</ul>]]></content><author><name>Louis Schiekiera</name></author><category term="research" /><category term="interpretability" /><category term="representation-learning" /><category term="llm-behavior" /><category term="semantic-geometry" /><summary type="html"><![CDATA[TL;DR: How faithfully does an LLM’s text output reflect the semantic geometry encoded in its hidden states? Forced-choice behavioral probing recovers substantially more internal similarity structure than open-ended generation, and behavioral features improve prediction of unseen hidden-state similarities above lexical and cross-model baselines.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" /><media:content medium="image" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Between Theory and Reality: How Schools Grapple with Heterogeneity and Where AI Fits</title><link href="http://www.pokutta.com/blog/research/2025/12/15/school-ai.html" rel="alternate" type="text/html" title="Between Theory and Reality: How Schools Grapple with Heterogeneity and Where AI Fits" /><published>2025-12-15T00:00:00+01:00</published><updated>2025-12-15T00:00:00+01:00</updated><id>http://www.pokutta.com/blog/research/2025/12/15/school-ai</id><content type="html" xml:base="http://www.pokutta.com/blog/research/2025/12/15/school-ai.html"><![CDATA[<p><em>TL;DR: Rising classroom heterogeneity and workload make AI in schools inevitable; with FACET we explore how evidence-based, teacher-centered AI can support meaningful differentiation and AI literacy without replacing human judgment.</em></p>

<!--more-->

<p><em>Written by Jana Gonnermann-Müller.</em></p>

<h2 id="recognizing-the-need-for-ai-in-schools">Recognizing the Need for AI in Schools</h2>

<p>On November 26, school principals from primary and secondary schools gathered with regional authorities for the annual <em>KI-Fachtag der Schulen</em>. The theme this year: <strong>Artificial Intelligence in Education</strong>.</p>

<p>The spotlight was firmly on concrete use cases: how Artificial intelligence (AI) can support schools today, but also on the fear that AI is used without verification or cross-checking, potentially leading to a loss of skill and knowledge. At the center of the discussion was a dual question. On the one hand, how do we ensure that AI use becomes meaningful, so that it augments, rather than replaces, core competencies, which includes fostering AI literacy, critical thinking, and verification skills so that students learn not simply to consume AI outputs, but to evaluate, challenge, and integrate them in ways that support long-term skill development. On the other hand, how can AI help schools address structural pressures such as rising workload due to classroom heterogeneity and teacher shortages?</p>

<p>As part of the event, our team from the <a href="https://www.zib.de/iol/">IOL Lab</a> at the <a href="https://www.zib.de/">Zuse Institute Berlin</a> was invited to give a talk and to lead two hands-on workshops. In the keynote, we outlined the structural pressures that make AI integration in schools necessary: demographic change, Germany’s lag in technological adoption, and the growing information overload that increasingly requires students to critically evaluate and interpret information sources. In such a context, AI literacy and critical thinking become foundational competences. The workshop discussions quickly revealed just how acute these pressures have become. School leaders described rising heterogeneity in their classrooms, the growing need for differentiated instruction, and the challenges of ensuring meaningful and responsible AI use in everyday teaching. Their questions and concerns underscored the urgency of developing approaches that are not only technically feasible but also pedagogically sound. Yet meaningful AI integration depends on supporting teachers with practical, research-grounded tools that address for example diverse learning needs without adding to their workload.</p>

<p>This post situates these discussions within a broader research context, where we see our work as one puzzle piece in a much larger effort: working directly with schools to understand their needs, translate them into researchable questions, and offer evidence-based opportunities to address them. We therefore collaborate with schools to empirically examine where AI can support teaching, such as in differentiation under increasing heterogeneity, where it cannot, and how it must be designed to strengthen rather than undermine students’ skill acquisition. By co-developing and rigorously evaluating an AI-supported tool with practitioners, we aim to move the conversation away from emotion-driven expectations and fears and toward an evidence-informed understanding of what works in real classroom conditions.</p>

<h2 id="the-bigger-picture-what-ai-and-school-encompasses">The Bigger Picture: What ‘AI and School’ Encompasses</h2>

<p>Schools constitute the first structured environment in which young people interact with broader social and technological systems. As such, they are expected to cultivate foundational competencies, such as critical thinking, judgment and collaboration, while simultaneously preparing students for rapidly evolving technological conditions. Contemporary education systems therefore face a multi-layered mandate: to enable engagement with AI, support cognitive and socio-emotional development, and contribute to the reduction rather than the reproduction of socio-economic disparities. Within this broader mandate, AI emerges not as an optional add-on but as an integral part of the technological landscape and decision-making contexts, students will have to navigate. The central question is thus not whether AI should be present in schools, but <strong>how</strong> it can be integrated in ways that reinforce, rather than erode, core cognitive and analytical skills.</p>

<p>We outline that ‘AI in schools’ comprises two interdependent domains. The first is <em>education about AI</em>, encompassing digital literacy, data literacy, and increasingly AI literacy. These competencies enable students to interpret uncertainty, understand model behavior, and critically evaluate algorithmic outputs—skills that underpin agency in AI-mediated environments.</p>

<p>The second is <em>education with AI</em>, referring to the use of AI tools within teaching and learning processes. In this domain, AI can help address structural challenges such as teacher shortages, the need for differentiated instruction, and unequal access to tutoring. Practical examples include teacher-facing support for generating differentiated materials, student-facing tutoring systems that may mitigate socio-economic disparities, and in-class assistants that scaffold reasoning without displacing human pedagogical judgment.</p>

<p>From this perspective, the objective is not AI adoption per se, but competence-oriented integration, ensuring that students develop AI literacy, critical analysis, and robust domain skills, while teachers receive effective, research-grounded support to manage rising workload and heterogeneity without compromising didactical quality.</p>

<p>While public discussions about AI in education often remain abstract, empirical research highlights several concrete structural challenges. One emerging issue is the need to handle the massive increase of (AI-generated) information, which requires students to learn verification and critical evaluation of information. A second, persistent challenge is rising heterogeneity within classrooms <a href="https://doi.org/10.1080/13670050.2021.1981821">[Siepmann et al. (2023). Attention to diversity in German CLIL classrooms: multi-perspective research on students’ and teachers’ perceptions.International Journal of Bilingual Education and Bilingualism]</a>. Students in schools differ substantially in prior knowledge, linguistic background, cognitive profiles, motivational orientations, and emotional needs, patterns documented widely in international research and in German data from the <a href="https://deutsches-schulportal.de/bildungswesen/iqb-bildungstrend-die-wichtigsten-ergebnisse/#die-wichtigsten-ergebnisse-zum-iqb-bildungstrend-2024">IQB Bildungstrend 2024</a>. Many classrooms include both high-achieving students and learners requiring significant support, including those with reading and spelling difficulties or ADHD, whose prevalence has increased in recent years <a href="https://www.nature.com/articles/d41586-025-03855-2">[Pearson (2025). ADHD diagnoses are growing. What’s going on?. Nature]</a>. Educational theory has long shown that addressing such diversity requires differentiated instruction <a href="https://www.scirp.org/reference/referencespapers?referenceid=2055060">[Tomlinson (2014). The Differentiated Classroom: Responding to the Needs of All Learners. 2nd Edition, ASCD, Alexandria]</a>. This entails providing tasks at varying levels of complexity, offering scaffolded support, giving individualized hints and stepwise explanations, and supplying feedback aligned with learners’ needs. Motivational research further demonstrates that effective instruction must integrate cognitive challenge with emotional support, self-efficacy building, and relevance cues, as cognitive and affective processes are tightly intertwined <a href="https://doi.org/10.1007/s11618-010-0113-z">[Pietsch (2010). Evaluation von Unterrichtsstandards. Zeitschrift für Erziehungswissenschaften]</a>.</p>

<p>Yet teachers face what research describes as an <em>implementation gap</em>: the discrepancy between pedagogical requirements and what is feasible given limited time, class sizes, and workload <a href="https://www.bosch-stiftung.de/de/publikation/deutsches-schulbarometer-lehrkraefte-2025">[Jude (2025). Deutsches Schulbarometer Lehrkräfte 2025]</a>. Although differentiated instruction is theoretically well understood, its practical implementation is difficult. Creating multiple versions of tasks, adjusting scaffolds, and providing targeted feedback for diverse learner profiles is time-intensive, and most available materials still assume an ‘average learner’, a construct increasingly disconnected from classroom reality.</p>

<p>Other countries are already responding to these pressures in structured and systematic ways: In the United States, <a href="https://de.khanacademy.org/"><em>Khan Academy’s Khanmigo</em></a> uses large language models (LLMs) to provide individualized guidance, task variation, and adaptive hints. In China, <a href="https://squirrelai.com/employs"><em>Squirrel AI</em></a> diagnostic engines that map knowledge gaps and generate highly personalized learning paths for learners. Singapore integrates adaptive learning systems directly into its national Student Learning Space under the <a href="https://www.moe.gov.sg/education-in-sg/educational-technology-journey/edtech-masterplan"><em>EdTech Masterplan 2030</em></a>, enabling teachers to deliver levelled tasks and automated feedback aligned with curriculum structures.</p>

<h2 id="our-approach-the-facet-framework">Our approach: The FACET Framework</h2>

<p>Against the backdrop of rising heterogeneity, motivational disparities, and persistent teacher shortages, our work on the FACET aims to contribute an evidence-based component to the debate about AI integration in German schools. <a href="https://arxiv.org/abs/2508.11401">FACET is a research framework</a> designed to systematically examine how AI can support the described need for differentiation under real classroom constraints. Its overarching goal is to help teachers create differentiated teaching materials for diverse learner groups and, at the same time, to generate empirical insights into when AI meaningfully supports teaching and learning, where it falls short, and how it must be designed so that it strengthens rather than undermines skill acquisition.</p>

<p>The FACET is implemented as a multi-agent system with four interconnected layers:</p>

<ol>
  <li>
    <p><strong>Learner agents</strong> simulate student behavior based on profiles that teachers themselves can define and instantiate—reflecting varying prior knowledge, low motivation, reading and writing difficulties, ADHD-related challenges, or other characteristics observed in their classes. These agents attempt tasks, reveal misconceptions, and produce reasoning traces and emotional cues. As tasks, teachers can upload their own materials or rely on tasks predefined by curriculum.</p>
  </li>
  <li>
    <p>The <strong>assessment agent</strong> analyzes how these simulated learners interact with instructional materials—whether uploaded by the teacher or prescribed by the curriculum. It evaluates both their reasoning processes and their affective responses to provide the basis for adapting the materials.</p>
  </li>
  <li>
    <p>The <strong>generator agent</strong> creates differentiated teaching materials based on these diagnostics. This includes levelled tasks aligned with the curriculum’s ‘areas of competence’, scaffolded steps, hints, and motivational feedback tailored to each simulated learner profile. This layer integrates curriculum structures as well as diagnostic and didactical concepts, allowing the system to identify where learners with different profiles are likely to experience cognitive or motivational difficulties.</p>
  </li>
  <li>
    <p>The <strong>evaluator agent</strong> reviews the generated output along dimensions such as didactical coherence, clarity, creativity, and suitability for the specified learners. Teachers can then inspect, adjust, or reject the materials as they see fit. They can also download the finalized materials as Word, PDF, or LaTeX documents.</p>
  </li>
</ol>

<p>The FACET architecture is not intended to replace teachers. Instead, it provides structured starting points for differentiation, aiming to reduce workload while preserving pedagogical control.</p>

<div style="text-align:center; margin-bottom: 20px;">
    <img src="http://www.pokutta.com/blog/assets/ai-school/Facet_LandingPage.png" alt="FACET 1" style="width:49%;" />
    <img src="http://www.pokutta.com/blog/assets/ai-school/Facet_1.png" alt="FACET 2" style="width:49%;" />
    <p style="font-size: small; font-style: italic;">Figure 1: FACET's landing page and a screenshot of the worksheet generator</p>
</div>

<h2 id="facet-meets-reality-insights-from-practice">FACET Meets Reality: Insights From Practice</h2>

<p>During the ‘KI-Fachtag der Schulen’, parts of our team — Konstantin Fackeldey, Jana Gonnermann-Müller, and Nicolas Leins — conducted two workshops with around 30 school principals to test the FACET under real-world conditions. The discussions provided a clear picture of the pressures schools face and offered feedback that will directly inform the next stages of FACET’s development.</p>

<p>Principals consistently emphasized the urgency of supporting differentiation in increasingly heterogeneous classrooms. Many reported rising numbers of students with reading and spelling difficulties, varying language proficiencies, and large performance gaps within the same class. Teachers report that one way they try to address differences in learning pace is by allowing faster-learning students to move on to new topics while slower-learning students remain with the current one. However, this forced form of differentiation, driven by the lack of time to create differentiated materials for a shared topic, makes working as a unified class group difficult. As a result, the class ends up working on different topics, or with some students become bored, while others still need significantly more time to complete their tasks.</p>

<p>In addition, inclusion schools in particular expressed strong interest, noting that the current staffing conditions make meaningful differentiation nearly impossible. As one principal described: ‘We have so many different children in our schools … we are labeled an inclusion school, yet we only have one teacher for an entire class. We don’t know how we’re supposed to meet all children’s needs.’ The possibility of generating differentiated materials tailored to specific learner profiles resonated strongly. Principals already aknowledged the quality of FACET’s outputs — ‘much more thoughtfully constructed than what we can produce ourselves under time pressure’— while also highlighting important requirements for classroom use. At the same time, they stressed that differentiated materials must be aligned with the curriculum and that teachers need to integrate FACET’s outputs into the broader workflow of lesson planning and classroom management. Importantly, this real-world feedback is crucial for ensuring that FACET evolves in line with the actual needs of teachers. It underscored that any AI-supported tool must be tightly coordinated with curricular structures and flexible enough to fit into existing teaching practices. Principals also contributed new use cases, such as using FACET as an AI-in-class assistant that scaffold material for diverse students, which we had not previously considered. In sum, these insights are invaluable. They allow us to refine FACET not as an abstract technological experiment but as a research framework developed with schools and oriented toward the real demands of everyday teaching. Many principals expressed interest in long-term testing, and we look forward to continuing this collaborative process as FACET evolves.</p>

<div style="text-align:center; margin-bottom: 20px;">
    <img src="http://www.pokutta.com/blog/assets/ai-school/Fachtag_Talk.jpg" alt="KI Fachtag" style="width:99%;" />
    <p style="font-size: small; font-style: italic;">Figure 2: Sebastian Pokutta delivering a keynote at the KI Fachtag on AI in Schools (<a href="https://www.ki-fachtag-schulen.de/2025/de/programm/KI-Fachtag-2025/" target="_blank" rel="noopener">more information</a>).</p>
</div>

<h2 id="the-weizenbaum-debate-on-ai-in-schools">The Weizenbaum Debate on AI in Schools</h2>

<p>Just days earlier, on November 18, our team took part in the <a href="https://www.weizenbaum-institut.de/news/detail/welche-ki-gehoert-ins-klassenzimmer-rueckblick-auf-die-weizenbaum-debate/">4th Weizenbaum Debate</a>, a packed and lively evening at the Quatsch Comedy Club that brought together researchers, teachers, and students to explore what AI in the school of the future should look like. We were invited to join the debate, sharing insights from research on the FACET and discussing how AI can be meaningfully integrated into everyday teaching. Again, we discussed pressing questions, such as when AI genuinely supports learning and when it slips into mere ‘cognitive offloading’, how generative AI must be designed so that it strengthens understanding rather than undermining it, and what competencies students need to use AI in a self-determined, responsible way. Teachers and students challenged long-standing assumptions about exams, resources, and the role of human educators, grounding the debate in lived reality.</p>

<div style="text-align:center; margin-bottom: 20px;">
    <img src="http://www.pokutta.com/blog/assets/ai-school/WI_Debate.jpeg" alt="Weizenbaum Debate" style="width:99%;" />
    <p style="font-size: small; font-style: italic;">Figure 3: Jana Gonnermann-Müller on stage at the Weizenbaum Debate on AI in Schools (<a href="https://www.weizenbaum-institut.de/events/weizenbaum-debate-ki-gehoert-ins-klassenzimmer/" target="_blank" rel="noopener">more information)</a>.</p>
</div>

<h2 id="the-bigger-picture---why-all-of-this-matters">The Bigger Picture - Why All of This Matters</h2>

<p>The underlying core challenge is structural: without scalable support for differentiation, rising learner heterogeneity will continue to outstrip schools’ capacity and deepen educational inequality. Recent assessments already show widening gaps in competencies, motivation, and socio-economic background—pressures intensified by persistent teacher shortages, where <em>education with AI</em> can offer targeted relief. At the same time, students must learn to navigate environments saturated with information, misinformation, and rapidly changing knowledge, underscoring the need for <em>education about AI</em>. Frameworks like FACET cannot solve these systemic issues, but they can offer research solutions that ease critical bottlenecks and free teachers to focus on what cannot be automated: cultivating critical thinking, guiding inquiry, and preparing students to participate responsibly in an AI-shaped society.</p>

<p>Interested in our FACET? Read our paper on FACET at <a href="https://arxiv.org/abs/2508.11401">arxiv.org/abs/2508.11401</a> or reach out to us anytime.
This research by Konstantin Fackeldey, Jana Gonnermann-Müller, Jennifer Haase, Nicolas Leins, and Sebastian Pokutta is part of our ongoing work of the <a href="https://iol.zib.de/research/iol-human.html/">Humans and AI</a> research thrust, which is part of the IOL Lab at the Zuse Institute Berlin.</p>]]></content><author><name>Jana Gonnermann-Müller</name></author><category term="research" /><category term="ai" /><category term="education" /><summary type="html"><![CDATA[TL;DR: Rising classroom heterogeneity and workload make AI in schools inevitable; with FACET we explore how evidence-based, teacher-centered AI can support meaningful differentiation and AI literacy without replacing human judgment.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" /><media:content medium="image" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">SCIP Optimization Suite 10.0: Exact Solving, Better Decompositions, and a More Productive Ecosystem</title><link href="http://www.pokutta.com/blog/research/2025/12/02/scip-10.html" rel="alternate" type="text/html" title="SCIP Optimization Suite 10.0: Exact Solving, Better Decompositions, and a More Productive Ecosystem" /><published>2025-12-02T00:00:00+01:00</published><updated>2025-12-02T00:00:00+01:00</updated><id>http://www.pokutta.com/blog/research/2025/12/02/scip-10</id><content type="html" xml:base="http://www.pokutta.com/blog/research/2025/12/02/scip-10.html"><![CDATA[<p><em>TL;DR: SCIP Optimization Suite 10.0 brings a numerically exact solving mode for rational MILPs, noticeable performance gains for MILP/MINLP, stronger presolving and symmetry handling, better heuristics and conflict analysis, IIS detection, and major updates to GCG, PaPILO, PySCIPOpt, and MIP-DD.</em></p>

<!--more-->

<p><em>Written by <a href="https://iol.zib.de/team/dominik-kamp.html">Dominik Kamp</a>, <a href="https://gionimexi.com/">Gioni Mexi</a>, and <a href="https://www.pokutta.com">Sebastian Pokutta</a>.</em></p>

<style>
  .callout {
    border-left: 4px solid #2563eb;
    border-right: 4px solid #2563eb;
    background: #f5f7ff;
    padding: 12px 16px;
    margin: 1em 0;
  }
</style>

<h2 id="introduction">Introduction</h2>

<p>The SCIP Optimization Suite 10.0 is now available. The new release updates the entire stack:</p>

<ul>
  <li><strong>SCIP</strong> 10.0 (core solver)</li>
  <li><strong>SoPlex</strong> 8.0 (LP solver)</li>
  <li><strong>PaPILO</strong> 3.0 (presolving library)</li>
  <li><strong>GCG</strong> 4.0 (automatic decomposition solver)</li>
  <li><strong>Zimpl</strong> 3.7 (modeling language)</li>
  <li><strong>UG</strong> 1.0 (parallel framework)</li>
  <li>plus <strong>SCIP-SDP</strong>, <strong>PySCIPOpt</strong>, <strong>MIP-DD</strong>, and the new <strong>PBSolver</strong> application.</li>
</ul>

<p>At a high level:</p>

<ul>
  <li>SCIP 10.0 is <strong>faster and more robust</strong> on both MILPs and MINLPs than 9.x, with the largest gains on harder instances.</li>
  <li>A new <strong>exact solving mode</strong> can solve rational MILPs without numerical tolerances and produce verifiable certificates.</li>
  <li><strong>IIS detection</strong> for MIPs is now integrated directly into SCIP, enabling users to extract irreducible infeasible subsystems for debugging and model analysis.</li>
  <li>Decomposition, presolving, symmetry handling, and conflict analysis all received substantial upgrades.</li>
  <li>The ecosystem around SCIP (GCG, PaPILO, SCIP-SDP, interfaces, and tooling) has matured further.</li>
</ul>

<p>For full technical details see the <a href="https://optimization-online.org/2025/11/the-scip-optimization-suite-10-0/">SCIP 10.0 release report</a>.</p>

<h2 id="faster-and-more-reliable-core-solver">Faster and More Reliable Core Solver</h2>

<h3 id="performance-what-changes-in-practice">Performance: What Changes in Practice?</h3>

<p>The team benchmarked SCIP 10.0 against SCIP 9.0 and 9.2.4 on large MILP/MINLP test sets (MIPLIB, COR@L, MINLPLib).</p>

<ul>
  <li>On MILPs, SCIP 10.0 is <strong>about 4% faster</strong> overall than 9.2.4, with <strong>up to ~10% speed-ups</strong> on harder instances (≥ 100–1000 seconds).</li>
  <li>On MINLPs, the gains are larger: <strong>≈9% faster on average</strong> and <strong>20%+ speed-ups</strong> on the hardest problems, while also solving more instances within the time limit.</li>
</ul>

<p>This may sound incremental, but for real workloads (e.g., nightly planning runs, large-scale research experiments) a 5–20% speed-up with improved robustness delivers tangible, hassle-free gains simply by upgrading.</p>

<h3 id="numerically-exact-solving-mode-for-milps">Numerically Exact Solving Mode for MILPs</h3>

<p>The headline feature of SCIP 10.0 is a <strong>numerically exact solving mode</strong> for rational MILPs:</p>

<ul>
  <li>MILP data (MPS/LP/CIP/OPB/ZIMPL) can be read <strong>in exact rational arithmetic</strong>.</li>
  <li>SCIP maintains floating-point and rational views and uses a hybrid strategy:
    <ul>
      <li>Safe dual bounds and cut generation via directed rounding.</li>
      <li>Exact LP solves via SoPlex or QSopt_ex only when necessary.</li>
    </ul>
  </li>
  <li>You can log a <strong>VIPR certificate</strong> that captures the full branch-and-bound proof. Its correctness can be verified with a C++ proof checker included in the SCIP Optimization Suite VIPR repository, or with a formally verified checker built on CakeML/HOL4 for maximum rigor.</li>
</ul>

<p>Why this matters:</p>

<ul>
  <li>For <strong>safety-critical</strong> or <strong>audited</strong> applications, you can now <em>prove</em> optimality of MILPs with rational data instead of trusting floating-point tolerances.</li>
  <li>For <strong>research</strong>, this is a playground for exact algorithms, certified MIP technology, and proof logging workflows.</li>
</ul>

<p>The trade-off is performance: exact mode is currently roughly <strong>3–4× slower</strong> than a comparable floating-point configuration and ~<strong>7–10×</strong> slower than the default configuration, depending on the test set. The fundamental benefit is that the exact objective bounds are actually guaranteed.</p>

<h2 id="extended-presolving-symmetry-handling-and-cuts">Extended Presolving, Symmetry Handling, and Cuts</h2>

<h3 id="smarter-detection-of-implied-integrality">Smarter Detection of Implied Integrality</h3>

<p>SCIP 10.0 adds a new <strong>Total Unimodularity-based implied integrality detector</strong> that uses network submatrices to infer when some variables can be seen as integers even if they are declared continuous.</p>

<ul>
  <li>On MIPLIB 2017, it detects implied integrality for <strong>~19% of variables</strong> on average, compared to ~3% before.</li>
</ul>

<p>This extra structure can feed into branching, cutting, and propagation, and is particularly relevant for models with network-like structure. It’s not yet enabled by default, but it’s an important building block for future performance gains (and fun for people who like to tinker with advanced settings).</p>

<h3 id="better-symmetry-handling-including-reflections">Better Symmetry Handling (Including Reflections)</h3>

<p>SCIP’s symmetry machinery has taken a major step forward:</p>

<ul>
  <li><strong>Reflection symmetries</strong> (e.g., flipping binary variables 0↔1 or reflecting coordinates) are better detected and exploited.</li>
  <li>Schreier-Sims cuts, orbitopes, double-lex matrices, and small but effective symmetry handling inequalities have all been extended to handle these reflections.</li>
</ul>

<p>For highly structured models (graph coloring, packing, disk packing, many combinatorial designs), this can significantly reduce search by eliminating symmetric parts of the tree.</p>

<h3 id="cut-based-conflict-analysis-and-flower-cuts">Cut-Based Conflict Analysis and Flower Cuts</h3>

<p>Two new pieces in the cut/propagation story:</p>

<ul>
  <li><strong>Cut-based conflict analysis</strong>: instead of analyzing conflicts purely via implication graphs, SCIP 10.0 can operate directly on linear inequalities, which can theoretically provide exponentially stronger reasoning than classical SAT-style conflict analysis, which is based on the resolution proof system and CNF encodings.</li>
  <li><strong>Flower inequalities</strong>: a new separator for products of nonnegative variables (e.g., logical ANDs) generates so-called <em>k-flower</em> inequalities over a multilinear hypergraph representation. The implementation focuses on k=1 or 2 neighboring edges, for efficiency, and is near-neutral when no multilinear structure is present, but can be a noticeable win on affected instances.</li>
</ul>

<p>In practice, both features help SCIP <strong>learn more from infeasibilities and nonlinear structure</strong>, translating into fewer nodes and more solved instances.</p>

<h2 id="heuristics-branching-benders-and-explainability">Heuristics, Branching, Benders, and Explainability</h2>

<p>Several “everyday” parts of the solver got smarter:</p>

<ul>
  <li><strong>New decomposition-aware heuristics</strong>: two primal heuristics (including a kernel search variant) exploit user-provided decompositions to search promising subspaces first. This is particularly useful when you already know the structure of your problem (e.g., time periods, locations, or scenario blocks).</li>
  <li><strong>Improved branching strategies</strong>: reliability pseudocost branching was made safe for exact mode and further tuned for floating-point runs. This mainly shows up as more stable performance on hard instances.</li>
  <li><strong>Enhanced Benders’ decomposition framework</strong>: more flexible ways to define master and subproblems and better automatic detection of linking variables. This lowers the barrier to using Benders’ decomposition in real models.</li>
  <li><strong>Infeasibility explanations (IIS)</strong>: a new tool can compute irreducible infeasible subsystems, giving more interpretable explanations of why a model is infeasible. This is useful for model debugging and communicating with non-optimization stakeholders.</li>
  <li><strong>CONOPT interface</strong>: you can now use CONOPT as the NLP solver. It’s not uniformly faster than Ipopt, but on the hardest MINLPs it yields substantial reductions in runtime and node count, and can solve some instances that stall with Ipopt.</li>
</ul>

<p>Taken together, these features make SCIP 10.0 not just faster, but also <strong>better at telling you what’s going on when things fail</strong>.</p>

<h2 id="ecosystem-updates-gcg-papilo-scip-sdp-soplex-ug-zimpl">Ecosystem Updates: GCG, PaPILO, SCIP-SDP, SoPlex, UG, Zimpl</h2>

<h3 id="gcg-40-decomposition-solver">GCG 4.0: Decomposition Solver</h3>

<p>GCG’s new release focuses on usability and performance:</p>

<ul>
  <li>Harmonized <strong>Apache 2.0</strong> licensing with SCIP.</li>
  <li>New <strong>GCG object</strong> to simplify the C API and unify access to original/master models.</li>
  <li>Easier integration of external pricing solvers (HiGHS, Cliquer-based specialized pricing).</li>
  <li><strong>Parallel pricing</strong> enabled by default (with a parameter to control thread count).</li>
  <li>New <strong>IPColGen</strong> primal matheuristic for set covering/packing/partitioning master problems.</li>
  <li>Decomposition scores refactored into plugins for easier experimentation.</li>
</ul>

<p>In short: if you’re doing branch-cut-and-price/Dantzig-Wolfe, GCG 4.0 is a more pleasant and capable environment.</p>

<h3 id="papilo-30-faster-presolving-with-less-memory">PaPILO 3.0: Faster Presolving with Less Memory</h3>

<p>PaPILO 3.0 brings:</p>

<ul>
  <li>Significant improvements in performance and memory usage for the <strong>dominated columns</strong> presolver.</li>
  <li>A new <strong>parallel clique-merging</strong> presolver that extends and cleans up clique structures more efficiently.</li>
</ul>

<p>These low-level improvements are easy to overlook, but they directly affect large instances where presolving used to dominate runtime or exceed memory.</p>

<h3 id="scip-sdp-soplex-80-ug-and-zimpl">SCIP-SDP, SoPlex 8.0, UG, and Zimpl</h3>

<ul>
  <li><strong>SCIP-SDP 4.4.0</strong> updates to SCIP 10.0 and adds the ability to export original and transformed MISDPs in <strong>CBF</strong> format for use with the Conic Benchmark Library.</li>
  <li><strong>SoPlex 8.0</strong> is a major version bump reflecting build system and API changes; it remains the default LP solver and is central for exact LP solving in the new exact mode.</li>
  <li><strong>UG framework</strong> now includes an application for parallel Pseudo-Boolean solving with FiberSCIP, featuring 2024 PB competition–tuned settings and optional DIMACS-style log output.</li>
  <li><strong>Zimpl 3.7.0</strong> adds support for permutations (<code class="language-plaintext highlighter-rouge">permutate(A)</code>) and better handling of implied integral variables, which are now recognized by SCIP.</li>
</ul>

<h2 id="interfaces-developer-tooling-and-pbsolver">Interfaces, Developer Tooling, and PBSolver</h2>

<h3 id="interfaces-pyscipopt-rust-and-more">Interfaces: PySCIPOpt, Rust, and More</h3>

<p>Interface highlights:</p>

<ul>
  <li><strong>PySCIPOpt</strong> now supports <strong>matrix variables</strong> based on <code class="language-plaintext highlighter-rouge">numpy.ndarray</code>, making it much more natural to write matrix-centric models (think: SDP-like structures, network flows, control). The documentation and tutorials have also been significantly improved, including exercises and “recipes” for common modeling tasks.</li>
  <li>The <strong>Rust interface (russcip)</strong> has a more ergonomic and type-safe API with builder-style variable/constraint creation and safe access to separators and constraint handlers.</li>
  <li>Other interfaces (Matlab, AMPL, SCIPpp C++, PySoPlex, PyGCGOpt, PaPILO’s Julia interface) were updated and documented.</li>
</ul>

<p>From a user perspective, this makes it easy to access the full solver functionality in your favorite language.</p>

<h3 id="mip-dd-20-delta-debugging-for-mip-solvers">MIP-DD 2.0: Delta Debugging for MIP Solvers</h3>

<p><strong>MIP-DD</strong> is the first open-source, solver-independent delta debugger for MIP solvers.</p>

<ul>
  <li>It automatically shrinks a failing instance while preserving the bug, often down to models with just a handful of variables and constraints.</li>
  <li>Version 2.0 adapts modification batch sizes automatically, limits solving effort intelligently, and supports both real and exact solving modes of SCIP and SoPlex.</li>
</ul>

<p>If you develop solvers or serious extension plugins, MIP-DD is a powerful way to turn pathological “customer instances” into minimal test cases, while also removing sensitive information.</p>

<h3 id="pbsolver-dedicated-pseudo-boolean-application">PBSolver: Dedicated Pseudo-Boolean Application</h3>

<p>SCIP 10.0 introduces <strong>PBSolver</strong>, a SCIP-based application tailored to Pseudo-Boolean optimization and the Pseudo-Boolean Competition format.</p>

<ul>
  <li>Emits competition-compliant DIMACS-style logs and solution lines.</li>
  <li>Handles OPB/WBO instances out of the box, with parameters to control input limits.</li>
  <li>SCIP/FiberSCIP-based solvers using these features won several categories of the 2024 PB competition.</li>
</ul>

<p>If you work with Pseudo-Boolean benchmarks or SAT+PB hybrids, PBSolver gives you a supported, competition-ready entry point.</p>

<h2 id="availability-and-getting-started">Availability and Getting Started</h2>

<h3 id="core-distribution">Core Distribution</h3>

<p>The SCIP Optimization Suite 10.0 (SCIP, SoPlex, PaPILO, GCG, Zimpl, UG, SCIP-SDP, interfaces, and applications) is available as usual via the project website and GitHub repositories. Licensing is now more unified:</p>

<ul>
  <li><strong>SCIP 10.0, SoPlex 8.0, PaPILO 3.0, GCG 4.0</strong> under <strong>Apache 2.0</strong>.</li>
  <li><strong>Zimpl 3.7.0 and UG 1.0</strong> under <strong>LGPL</strong>.</li>
</ul>

<p>You can download the latest release from the <a href="https://www.scipopt.org/">SCIP Optimization Suite website</a> or from our <a href="https://github.com/scipopt">GitHub repositories</a>.</p>

<h3 id="new-docker-images-web-service-and-jupyter-lab">New Docker Images: Web Service and Jupyter Lab</h3>

<p>To make the suite easier to adopt in teaching, prototyping, and production, we provide two official Docker images (described in detail on the dedicated Docker page):</p>

<ul>
  <li>
    <p><strong><code class="language-plaintext highlighter-rouge">scip-webservice</code></strong>: a FastAPI-based web service for solving problem instances in common formats (e.g., .lp, .mps, .cip, .cnf, .fzn, .nl, .opb, .osil, .pip, .wbo, .zpl) via HTTP.</p>

    <ul>
      <li>Single-command startup, with endpoints for status, uploads, and auto-generated API docs.</li>
      <li>Environment variables to control concurrency, retention, and upload limits; Docker flags for CPU/memory caps.</li>
      <li>Designed so you can go from “no SCIP installed” to a working REST API in a minute.</li>
    </ul>
  </li>
  <li>
    <p><strong><code class="language-plaintext highlighter-rouge">scip-jupyterlab</code></strong>: a pre-configured Jupyter Lab environment with</p>

    <ul>
      <li>SCIP 10.0, PySCIPOpt 6.0, and Python 3.11,</li>
      <li>plus a standard data-science stack (NumPy, Pandas, Matplotlib, scikit-learn, etc.).</li>
      <li>Mount a local directory into <code class="language-plaintext highlighter-rouge">/app</code> and you have a ready-to-use notebook environment for teaching, demoing, or exploratory modeling.</li>
    </ul>
  </li>
</ul>

<p>Think of these as the modern replacement for the older “Dockerized SCIP for Teaching” setup: less friction, more batteries included.</p>

<p>(For details, examples, and recommended resource settings, see the <a href="/blog/pages/scip/scip-teaching-webservice.html">SCIP Optimization Suite 10 Docker page</a>)</p>

<h3 id="who-should-upgrade">Who Should Upgrade?</h3>

<ul>
  <li><strong>Practitioners</strong> get a faster, more reliable solver with better decomposition and PB capabilities, plus easier deployment via Docker.</li>
  <li><strong>Researchers</strong> get exact solving, proof logging, extended symmetry and presolving, and richer interfaces.</li>
  <li><strong>Teachers</strong> can run everything from a browser via the Jupyter Lab image, avoiding per-student installation pain.</li>
</ul>

<p>If you experiment with the new exact mode, MIP-DD, or the Docker images and find interesting use cases (or rough edges), feedback is very welcome on <a href="https://github.com/scipopt">GitHub</a> or <a href="gitlabgit+integer-scipoptsuite-support-3311-issue-@zib.de">via email</a>; this release is meant as both a robust workhorse and a platform for the next wave of MIP/MINLP research.</p>]]></content><author><name>Dominik Kamp, Gioni Mexi, Sebastian Pokutta</name></author><category term="research" /><category term="optimization" /><category term="scip" /><category term="mip" /><category term="minlp" /><summary type="html"><![CDATA[TL;DR: SCIP Optimization Suite 10.0 brings a numerically exact solving mode for rational MILPs, noticeable performance gains for MILP/MINLP, stronger presolving and symmetry handling, better heuristics and conflict analysis, IIS detection, and major updates to GCG, PaPILO, PySCIPOpt, and MIP-DD.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" /><media:content medium="image" url="http://www.pokutta.com/blog/assets/images/iol-logo.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>