This demo runs a simplified CHSH experiment. Two detectors, far apart, each randomly choose one of two angles and measure an entangled pair. We tally how often the two outcomes agree, combine four such correlations into a single score S, and watch where it lands.
<p class="hint">Two far-apart detectors each pick one of two angles and measure an entangled pair. We combine four correlations into one score <b>S</b>. Any <b>local, pre-decided</b> universe obeys <b>S ≤ 2</b>. Quantum mechanics reaches <b>2√2 ≈ 2.83</b>. Pick a model and run the trials.</p>
<div class="controls">
<label><input type="radio" name="model" value="quantum" checked> Quantum (entangled)</label>
<label><input type="radio" name="model" value="classical"> Classical (hidden script)</label>
</div>
<div class="meter">
<div class="scale">
<div class="zone-ok" style="width:70.7%"></div>
<div class="bound" style="left:70.7%"><span>S = 2</span></div>
<div class="tsirelson" style="left:100%"><span>2√2</span></div>
<div id="bar" class="bar" style="width:0%"></div>
</div>
</div>
<div class="status" id="status">Choose a model and press Run.</div>
<div class="btns">
<button id="run" type="button">Run 20000 pairs</button>
<button id="reset" type="button" class="ghost">Clear</button>
</div>
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; color: #222; margin: 0; }
.hint { font-size: .9rem; color: #444; margin: 0 0 .8rem; line-height: 1.45; }
.controls { display: flex; gap: 1.2rem; flex-wrap: wrap; margin: .3rem 0 1rem; font-size: .92rem; }
.controls label { cursor: pointer; }
.meter { margin: 1rem 0 .6rem; }
.scale { position: relative; height: 34px; background: #eef2f6; border: 1px solid #cdd9e3;
border-radius: 8px; overflow: visible; }
.zone-ok { position: absolute; top: 0; left: 0; height: 100%; background: #dceede;
border-right: 2px dashed #0a7d33; border-radius: 8px 0 0 8px; }
.bar { position: absolute; top: 0; left: 0; height: 100%; background: #1d3557;
opacity: .82; border-radius: 8px; transition: width .5s ease; }
.bound, .tsirelson { position: absolute; top: -20px; transform: translateX(-50%);
font-size: .72rem; font-weight: 700; color: #0a7d33; white-space: nowrap; }
.tsirelson { color: #c92f3c; }
.status { font-size: 1rem; font-weight: 600; margin: 1.1rem 0 .6rem; min-height: 1.4em; line-height: 1.4; }
.status.ok { color: #0a7d33; }
.status.bad { color: #c92f3c; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; }
button { font: 600 14px system-ui, sans-serif; padding: .45rem .9rem; border: 1px solid #1d3557;
background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
button.ghost { background: #fff; color: #1d3557; }
const fmt = (s, v) => s.replace(/%(\w+)%/g, (_, k) => String(v[k] ?? ''));
// CHSH Bell test. Two detectors choose a setting (a in {0, 45 deg}, b in
// {22.5, 67.5 deg}). The "score" S = E(a0,b0) - E(a0,b1) + E(a1,b0) + E(a1,b1),
// * Local hidden-variable theories are PROVEN bounded by S <= 2 (Bell 1964).
// * Quantum entangled pairs reach S = 2*sqrt(2) ~ 2.828 (Tsirelson bound).
// We simulate both and watch the bar cross 2 only for the quantum model.
const DEG = Math.PI / 180;
const A = [0 * DEG, 45 * DEG]; // Alice's two settings
const B = [22.5 * DEG, 67.5 * DEG]; // Bob's two settings
const SCALE = 100 / (2 * Math.sqrt(2)); // map S onto the 0..2sqrt2 bar (%)
// --- Quantum model: outcomes +/-1 with correlation E = cos(2*(a-b)).
// For a singlet-like pair, P(agree) = cos^2(a-b). Sample a shared random "phase" lambda and apply the quantum rule honestly per trial.
function quantumOutcome(a, b) {
// Use the singlet correlation directly: agree with prob cos^2(a-b).
const pAgree = Math.cos(a - b) ** 2;
const agree = Math.random() < pAgree;
const alice = Math.random() < 0.5 ? 1 : -1;
const bob = agree ? alice : -alice;
return [alice, bob];
}
// --- Classical model: a local hidden variable. Each particle carries a
// pre-set answer fixed at the source, independent of the far detector. Best deterministic strategy still cannot beat S = 2.
function classicalOutcome(a, b) {
// Shared hidden variable: a random source angle. Each side answers sign(cos(2*(setting - lambda))) -- a fixed local rule, no communication.
const lambda = classicalOutcome._lambda;
const alice = Math.cos(2 * (a - lambda)) >= 0 ? 1 : -1;
const bob = Math.cos(2 * (b - lambda)) >= 0 ? 1 : -1;
return [alice, bob];
}
function correlation(model, a, b, n) {
let sum = 0;
for (let i = 0; i < n; i++) {
if (model === 'classical') classicalOutcome._lambda = Math.random() * Math.PI;
const [x, y] = model === 'quantum' ? quantumOutcome(a, b) : classicalOutcome(a, b);
sum += x * y;
}
return sum / n;
}
function computeS(model, n) {
const e00 = correlation(model, A[0], B[0], n);
const e01 = correlation(model, A[0], B[1], n);
const e10 = correlation(model, A[1], B[0], n);
const e11 = correlation(model, A[1], B[1], n);
return Math.abs(e00 - e01 + e10 + e11);
}
function selectedModel() {
return document.querySelector('input[name="model"]:checked').value;
}
function setStatus(t, cls) {
const s = document.getElementById('status'); s.textContent = t; s.className = 'status ' + cls;
}
function setBar(S) {
document.getElementById('bar').style.width = Math.min(100, S * SCALE) + '%';
}
function run() {
const model = selectedModel();
const N = 5000; // per correlation -> 20000 pairs total
const S = computeS(model, N);
setBar(S);
if (S > 2.01) {
setStatus(fmt('S = %S% -> beats 2! No local hidden-variable theory can do this.', { S: S.toFixed(3) }), 'ok');
} else {
setStatus(fmt('S = %S% -> stuck at or below 2, exactly as local realism predicts.', { S: S.toFixed(3) }), 'bad');
}
console.log(model, 'CHSH S =', S.toFixed(4));
}
document.getElementById('run').addEventListener('click', run);
document.getElementById('reset').addEventListener('click', () => {
setBar(0); setStatus('Choose a model and press Run.', '');
});
document.querySelectorAll('input[name="model"]').forEach(r =>
r.addEventListener('change', () => { setBar(0); setStatus('Press Run to measure.', ''); }));
<p class="hint">Two far-apart detectors each pick one of two angles and measure an entangled pair. We combine four correlations into one score <b>S</b>. Any <b>local, pre-decided</b> universe obeys <b>S ≤ 2</b>. Quantum mechanics reaches <b>2√2 ≈ 2.83</b>. Pick a model and run the trials.</p>
<div class="controls">
<label><input type="radio" name="model" value="quantum" checked> Quantum (entangled)</label>
<label><input type="radio" name="model" value="classical"> Classical (hidden script)</label>
</div>
<div class="meter">
<div class="scale">
<div class="zone-ok" style="width:70.7%"></div>
<div class="bound" style="left:70.7%"><span>S = 2</span></div>
<div class="tsirelson" style="left:100%"><span>2√2</span></div>
<div id="bar" class="bar" style="width:0%"></div>
</div>
</div>
<div class="status" id="status">Choose a model and press Run.</div>
<div class="btns">
<button id="run" type="button">Run 20000 pairs</button>
<button id="reset" type="button" class="ghost">Clear</button>
</div>
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; color: #222; margin: 0; }
.hint { font-size: .9rem; color: #444; margin: 0 0 .8rem; line-height: 1.45; }
.controls { display: flex; gap: 1.2rem; flex-wrap: wrap; margin: .3rem 0 1rem; font-size: .92rem; }
.controls label { cursor: pointer; }
.meter { margin: 1rem 0 .6rem; }
.scale { position: relative; height: 34px; background: #eef2f6; border: 1px solid #cdd9e3;
border-radius: 8px; overflow: visible; }
.zone-ok { position: absolute; top: 0; left: 0; height: 100%; background: #dceede;
border-right: 2px dashed #0a7d33; border-radius: 8px 0 0 8px; }
.bar { position: absolute; top: 0; left: 0; height: 100%; background: #1d3557;
opacity: .82; border-radius: 8px; transition: width .5s ease; }
.bound, .tsirelson { position: absolute; top: -20px; transform: translateX(-50%);
font-size: .72rem; font-weight: 700; color: #0a7d33; white-space: nowrap; }
.tsirelson { color: #c92f3c; }
.status { font-size: 1rem; font-weight: 600; margin: 1.1rem 0 .6rem; min-height: 1.4em; line-height: 1.4; }
.status.ok { color: #0a7d33; }
.status.bad { color: #c92f3c; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; }
button { font: 600 14px system-ui, sans-serif; padding: .45rem .9rem; border: 1px solid #1d3557;
background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
button.ghost { background: #fff; color: #1d3557; }
const fmt = (s, v) => s.replace(/%(\w+)%/g, (_, k) => String(v[k] ?? ''));
// CHSH Bell test. Two detectors choose a setting (a in {0, 45 deg}, b in
// {22.5, 67.5 deg}). The "score" S = E(a0,b0) - E(a0,b1) + E(a1,b0) + E(a1,b1),
// * Local hidden-variable theories are PROVEN bounded by S <= 2 (Bell 1964).
// * Quantum entangled pairs reach S = 2*sqrt(2) ~ 2.828 (Tsirelson bound).
// We simulate both and watch the bar cross 2 only for the quantum model.
const DEG = Math.PI / 180;
const A = [0 * DEG, 45 * DEG]; // Alice's two settings
const B = [22.5 * DEG, 67.5 * DEG]; // Bob's two settings
const SCALE = 100 / (2 * Math.sqrt(2)); // map S onto the 0..2sqrt2 bar (%)
// --- Quantum model: outcomes +/-1 with correlation E = cos(2*(a-b)).
// For a singlet-like pair, P(agree) = cos^2(a-b). Sample a shared random "phase" lambda and apply the quantum rule honestly per trial.
function quantumOutcome(a, b) {
// Use the singlet correlation directly: agree with prob cos^2(a-b).
const pAgree = Math.cos(a - b) ** 2;
const agree = Math.random() < pAgree;
const alice = Math.random() < 0.5 ? 1 : -1;
const bob = agree ? alice : -alice;
return [alice, bob];
}
// --- Classical model: a local hidden variable. Each particle carries a
// pre-set answer fixed at the source, independent of the far detector. Best deterministic strategy still cannot beat S = 2.
function classicalOutcome(a, b) {
// Shared hidden variable: a random source angle. Each side answers sign(cos(2*(setting - lambda))) -- a fixed local rule, no communication.
const lambda = classicalOutcome._lambda;
const alice = Math.cos(2 * (a - lambda)) >= 0 ? 1 : -1;
const bob = Math.cos(2 * (b - lambda)) >= 0 ? 1 : -1;
return [alice, bob];
}
function correlation(model, a, b, n) {
let sum = 0;
for (let i = 0; i < n; i++) {
if (model === 'classical') classicalOutcome._lambda = Math.random() * Math.PI;
const [x, y] = model === 'quantum' ? quantumOutcome(a, b) : classicalOutcome(a, b);
sum += x * y;
}
return sum / n;
}
function computeS(model, n) {
const e00 = correlation(model, A[0], B[0], n);
const e01 = correlation(model, A[0], B[1], n);
const e10 = correlation(model, A[1], B[0], n);
const e11 = correlation(model, A[1], B[1], n);
return Math.abs(e00 - e01 + e10 + e11);
}
function selectedModel() {
return document.querySelector('input[name="model"]:checked').value;
}
function setStatus(t, cls) {
const s = document.getElementById('status'); s.textContent = t; s.className = 'status ' + cls;
}
function setBar(S) {
document.getElementById('bar').style.width = Math.min(100, S * SCALE) + '%';
}
function run() {
const model = selectedModel();
const N = 5000; // per correlation -> 20000 pairs total
const S = computeS(model, N);
setBar(S);
if (S > 2.01) {
setStatus(fmt('S = %S% -> beats 2! No local hidden-variable theory can do this.', { S: S.toFixed(3) }), 'ok');
} else {
setStatus(fmt('S = %S% -> stuck at or below 2, exactly as local realism predicts.', { S: S.toFixed(3) }), 'bad');
}
console.log(model, 'CHSH S =', S.toFixed(4));
}
document.getElementById('run').addEventListener('click', run);
document.getElementById('reset').addEventListener('click', () => {
setBar(0); setStatus('Choose a model and press Run.', '');
});
document.querySelectorAll('input[name="model"]').forEach(r =>
r.addEventListener('change', () => { setBar(0); setStatus('Press Run to measure.', ''); }));
Any local hidden-variable universe is bound by S ≤ 2 — no clever pre-arranged script can do better. Run the simulator with the quantum correlations and S climbs to about 2.83 (the value 2√2, Tsirelson's bound). That extra 0.83 is the gap Einstein's worldview cannot cover. Switch to the classical model and you will see S stay pinned at or below 2, no matter how you tune it.
Comments
Loading comments...