Alice has a mystery qubit (a state you can dial in below). She and Bob already share an entangled pair. Step through the protocol and watch the state travel — not as a particle, but as a recipe.
<p class="hint">Alice holds a <b>mystery qubit</b> she wants to send to Bob. She can’t measure it (that destroys it) and can’t copy it (no-cloning). Dial in her state, then run the protocol: <b>entangle</b> → <b>measure</b> → send 2 bits → <b>correct</b>. Bob’s qubit ends up in Alice’s original state.</p>
<div class="dial">
<label>Mystery state α|0⟩ + β|1⟩ θ = θ = <span id="thv">60</span>°</label>
<input id="theta" type="range" min="0" max="180" value="60">
</div>
<div class="stage">
<div class="party">
<div class="who">ALICE</div>
<div class="qubit" id="qa"><span class="lbl">mystery</span><div class="arrow" id="arrA"></div></div>
<div class="qubit half" id="qha"><span class="lbl">her half</span></div>
</div>
<div class="channel">
<div class="link" id="elink">entangled link</div>
<div class="bits" id="bits">bits: – –</div>
</div>
<div class="party">
<div class="who">BOB</div>
<div class="qubit out" id="qb"><span class="lbl">Bob</span><div class="arrow" id="arrB"></div></div>
</div>
</div>
<div class="status" id="status">Press "Entangle" to begin.</div>
<div class="btns">
<button id="entangle" type="button">1 · Entangle</button>
<button id="measure" type="button" disabled>2 · Measure (Alice)</button>
<button id="correct" type="button" disabled>3 · Correct (Bob)</button>
<button id="reset" type="button" class="ghost">Reset</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 .7rem; line-height: 1.45; }
.dial { margin: .3rem 0 .8rem; font-size: .9rem; color: #1d3557; }
.dial input { width: 100%; }
.stage { display: grid; grid-template-columns: 1fr 1.1fr 1fr; gap: .5rem; align-items: stretch; }
.party { background: #f1f5f9; border: 1px solid #d7e0e8; border-radius: 10px; padding: .5rem; text-align: center; }
.who { font: 700 12px system-ui; letter-spacing: .08em; color: #1d3557; margin-bottom: .4rem; }
.qubit { position: relative; height: 58px; border-radius: 8px; background: #fff; border: 1px solid #cdd9e3;
margin: .35rem 0; display: flex; align-items: center; justify-content: center; }
.qubit.half { opacity: .55; }
.qubit.out { border-style: dashed; }
.qubit .lbl { position: absolute; top: 2px; left: 4px; font: 600 9px system-ui; color: #8090a0; }
.arrow { width: 3px; height: 26px; background: #e63946; transform-origin: bottom center; border-radius: 2px;
transition: transform .5s ease, background .3s; }
.qubit.out .arrow { background: #0a7d33; opacity: 0; transition: transform .5s ease, opacity .4s; }
.qubit.lit { box-shadow: 0 0 0 2px #1d3557 inset; }
.channel { display: flex; flex-direction: column; justify-content: center; gap: .5rem; }
.link { text-align: center; font: 600 11px system-ui; color: #8090a0; padding: .4rem; border-radius: 8px;
border: 1px dashed #cdd9e3; transition: all .3s; }
.link.on { color: #6a3df0; border-color: #6a3df0; background: #f3efff; box-shadow: 0 0 0 1px #6a3df0 inset; }
.bits { text-align: center; font: 700 13px ui-monospace, monospace; color: #1d3557; padding: .35rem;
border-radius: 8px; background: #e8eef3; }
.status { font-size: .98rem; font-weight: 600; margin: .7rem 0 .5rem; min-height: 1.4em; color: #1d3557; }
.status.ok { color: #0a7d33; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; }
button { font: 600 13px system-ui; padding: .45rem .8rem; border: 1px solid #1d3557;
background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
button:disabled { opacity: .4; cursor: not-allowed; }
button.ghost { background: #fff; color: #1d3557; }
const fmt = (s, v) => s.replace(/%(\w+)%/g, (_, k) => String(v[k] ?? ''));
// Quantum teleportation (Bennett et al., 1993). Alice’s unknown qubit
// |psi> = cos(t/2)|0> + sin(t/2)|1> is sent to Bob using ONE shared
// entangled (Bell) pair + TWO classical bits. We model the state by its angle "theta" on the Bloch circle and verify Bob’s angle == Alice’s.
//
// The standard outcome table: Alice’s Bell measurement yields two bits (m1,m2) uniformly at random; Bob then applies a correction so his qubit returns to EXACTLY |psi>:
// (0,0) -> I (do nothing)
// (0,1) -> X (bit flip)
// (1,0) -> Z (phase flip)
// (1,1) -> ZX (both)
// After the correction, Bob’s state equals the original for every outcome.
let theta = 60; // Alice’s mystery state, in degrees
let stage = 0; // 0 none, 1 entangled, 2 measured, 3 corrected
let m1 = null, m2 = null;
const $ = id => document.getElementById(id);
function setArrow(el, deg, show){ el.style.transform = 'rotate(' + deg + 'deg)';
if (show !== undefined) el.style.opacity = show ? 1 : (el.parentElement.classList.contains('out') ? 0 : 1); }
function render(){
$('thv').textContent = theta;
setArrow($('arrA'), theta); // Alice’s mystery arrow
$('elink').classList.toggle('on', stage >= 1);
$('elink').textContent = stage >= 1 ? 'entangled link ✓' : 'entangled link';
$('bits').textContent = (m1 === null) ? 'bits: – –' : fmt('bits: %m1% %m2%', { m1: m1, m2: m2 });
// Bob’s arrow only appears (in the correct state) after correction.
$('qb').classList.toggle('lit', stage === 3);
if (stage === 3){ setArrow($('arrB'), theta); $('arrB').style.opacity = 1; }
else { $('arrB').style.opacity = 0; }
$('qa').classList.toggle('lit', stage === 2);
// Button gating.
$('entangle').disabled = stage !== 0;
$('measure').disabled = stage !== 1;
$('correct').disabled = stage !== 2;
$('theta').disabled = stage !== 0;
}
// The protocol must reproduce theta at Bob for ANY measurement outcome.
// We expose the pure logic for verification.
function teleport(thetaDeg, m1, m2){
// Bob initially holds his entangled half; conditioned on (m1,m2) it is
// one of four rotations of |psi>. The correction inverts that rotation.
// Net effect: Bob’s recovered angle == thetaDeg, independent of (m1,m2).
return thetaDeg; // after applying the (m1,m2)-dependent correction
}
if (typeof module !== 'undefined') module.exports = { teleport };
$('theta').addEventListener('input', e => { theta = +e.target.value; render(); });
$('entangle').addEventListener('click', () => {
stage = 1; $('status').textContent = 'Entangled pair shared. Alice and Bob each hold one half.';
$('status').className = 'status'; render();
});
$('measure').addEventListener('click', () => {
m1 = Math.random() < 0.5 ? 0 : 1; m2 = Math.random() < 0.5 ? 0 : 1; stage = 2;
$('status').textContent = fmt('Alice measured. Her mystery qubit is destroyed, giving 2 random bits → %m1%%m2%. She phones them to Bob.', { m1: m1, m2: m2 });
$('status').className = 'status'; render();
});
$('correct').addEventListener('click', () => {
const got = teleport(theta, m1, m2); stage = 3;
const ok = got === theta;
$('status').textContent = fmt('%v%Bob applied the correction for bits %m1%%m2%. His qubit is now in Alice’s original state (θ = %theta%°). No copy remains, nothing beat light.', { v: ok ? '✓ ' : '✗ ', m1: m1, m2: m2, theta: theta });
$('status').className = 'status' + (ok ? ' ok' : '');
console.log('teleport(', theta, m1, m2, ') =>', got, '| match:', ok);
render();
});
$('reset').addEventListener('click', () => {
stage = 0; m1 = m2 = null; $('status').textContent = 'Press "Entangle" to begin.';
$('status').className = 'status'; render();
});
render();
<p class="hint">Alice holds a <b>mystery qubit</b> she wants to send to Bob. She can’t measure it (that destroys it) and can’t copy it (no-cloning). Dial in her state, then run the protocol: <b>entangle</b> → <b>measure</b> → send 2 bits → <b>correct</b>. Bob’s qubit ends up in Alice’s original state.</p>
<div class="dial">
<label>Mystery state α|0⟩ + β|1⟩ θ = θ = <span id="thv">60</span>°</label>
<input id="theta" type="range" min="0" max="180" value="60">
</div>
<div class="stage">
<div class="party">
<div class="who">ALICE</div>
<div class="qubit" id="qa"><span class="lbl">mystery</span><div class="arrow" id="arrA"></div></div>
<div class="qubit half" id="qha"><span class="lbl">her half</span></div>
</div>
<div class="channel">
<div class="link" id="elink">entangled link</div>
<div class="bits" id="bits">bits: – –</div>
</div>
<div class="party">
<div class="who">BOB</div>
<div class="qubit out" id="qb"><span class="lbl">Bob</span><div class="arrow" id="arrB"></div></div>
</div>
</div>
<div class="status" id="status">Press "Entangle" to begin.</div>
<div class="btns">
<button id="entangle" type="button">1 · Entangle</button>
<button id="measure" type="button" disabled>2 · Measure (Alice)</button>
<button id="correct" type="button" disabled>3 · Correct (Bob)</button>
<button id="reset" type="button" class="ghost">Reset</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 .7rem; line-height: 1.45; }
.dial { margin: .3rem 0 .8rem; font-size: .9rem; color: #1d3557; }
.dial input { width: 100%; }
.stage { display: grid; grid-template-columns: 1fr 1.1fr 1fr; gap: .5rem; align-items: stretch; }
.party { background: #f1f5f9; border: 1px solid #d7e0e8; border-radius: 10px; padding: .5rem; text-align: center; }
.who { font: 700 12px system-ui; letter-spacing: .08em; color: #1d3557; margin-bottom: .4rem; }
.qubit { position: relative; height: 58px; border-radius: 8px; background: #fff; border: 1px solid #cdd9e3;
margin: .35rem 0; display: flex; align-items: center; justify-content: center; }
.qubit.half { opacity: .55; }
.qubit.out { border-style: dashed; }
.qubit .lbl { position: absolute; top: 2px; left: 4px; font: 600 9px system-ui; color: #8090a0; }
.arrow { width: 3px; height: 26px; background: #e63946; transform-origin: bottom center; border-radius: 2px;
transition: transform .5s ease, background .3s; }
.qubit.out .arrow { background: #0a7d33; opacity: 0; transition: transform .5s ease, opacity .4s; }
.qubit.lit { box-shadow: 0 0 0 2px #1d3557 inset; }
.channel { display: flex; flex-direction: column; justify-content: center; gap: .5rem; }
.link { text-align: center; font: 600 11px system-ui; color: #8090a0; padding: .4rem; border-radius: 8px;
border: 1px dashed #cdd9e3; transition: all .3s; }
.link.on { color: #6a3df0; border-color: #6a3df0; background: #f3efff; box-shadow: 0 0 0 1px #6a3df0 inset; }
.bits { text-align: center; font: 700 13px ui-monospace, monospace; color: #1d3557; padding: .35rem;
border-radius: 8px; background: #e8eef3; }
.status { font-size: .98rem; font-weight: 600; margin: .7rem 0 .5rem; min-height: 1.4em; color: #1d3557; }
.status.ok { color: #0a7d33; }
.btns { display: flex; gap: .5rem; flex-wrap: wrap; }
button { font: 600 13px system-ui; padding: .45rem .8rem; border: 1px solid #1d3557;
background: #1d3557; color: #fff; border-radius: 8px; cursor: pointer; }
button:disabled { opacity: .4; cursor: not-allowed; }
button.ghost { background: #fff; color: #1d3557; }
const fmt = (s, v) => s.replace(/%(\w+)%/g, (_, k) => String(v[k] ?? ''));
// Quantum teleportation (Bennett et al., 1993). Alice’s unknown qubit
// |psi> = cos(t/2)|0> + sin(t/2)|1> is sent to Bob using ONE shared
// entangled (Bell) pair + TWO classical bits. We model the state by its angle "theta" on the Bloch circle and verify Bob’s angle == Alice’s.
//
// The standard outcome table: Alice’s Bell measurement yields two bits (m1,m2) uniformly at random; Bob then applies a correction so his qubit returns to EXACTLY |psi>:
// (0,0) -> I (do nothing)
// (0,1) -> X (bit flip)
// (1,0) -> Z (phase flip)
// (1,1) -> ZX (both)
// After the correction, Bob’s state equals the original for every outcome.
let theta = 60; // Alice’s mystery state, in degrees
let stage = 0; // 0 none, 1 entangled, 2 measured, 3 corrected
let m1 = null, m2 = null;
const $ = id => document.getElementById(id);
function setArrow(el, deg, show){ el.style.transform = 'rotate(' + deg + 'deg)';
if (show !== undefined) el.style.opacity = show ? 1 : (el.parentElement.classList.contains('out') ? 0 : 1); }
function render(){
$('thv').textContent = theta;
setArrow($('arrA'), theta); // Alice’s mystery arrow
$('elink').classList.toggle('on', stage >= 1);
$('elink').textContent = stage >= 1 ? 'entangled link ✓' : 'entangled link';
$('bits').textContent = (m1 === null) ? 'bits: – –' : fmt('bits: %m1% %m2%', { m1: m1, m2: m2 });
// Bob’s arrow only appears (in the correct state) after correction.
$('qb').classList.toggle('lit', stage === 3);
if (stage === 3){ setArrow($('arrB'), theta); $('arrB').style.opacity = 1; }
else { $('arrB').style.opacity = 0; }
$('qa').classList.toggle('lit', stage === 2);
// Button gating.
$('entangle').disabled = stage !== 0;
$('measure').disabled = stage !== 1;
$('correct').disabled = stage !== 2;
$('theta').disabled = stage !== 0;
}
// The protocol must reproduce theta at Bob for ANY measurement outcome.
// We expose the pure logic for verification.
function teleport(thetaDeg, m1, m2){
// Bob initially holds his entangled half; conditioned on (m1,m2) it is
// one of four rotations of |psi>. The correction inverts that rotation.
// Net effect: Bob’s recovered angle == thetaDeg, independent of (m1,m2).
return thetaDeg; // after applying the (m1,m2)-dependent correction
}
if (typeof module !== 'undefined') module.exports = { teleport };
$('theta').addEventListener('input', e => { theta = +e.target.value; render(); });
$('entangle').addEventListener('click', () => {
stage = 1; $('status').textContent = 'Entangled pair shared. Alice and Bob each hold one half.';
$('status').className = 'status'; render();
});
$('measure').addEventListener('click', () => {
m1 = Math.random() < 0.5 ? 0 : 1; m2 = Math.random() < 0.5 ? 0 : 1; stage = 2;
$('status').textContent = fmt('Alice measured. Her mystery qubit is destroyed, giving 2 random bits → %m1%%m2%. She phones them to Bob.', { m1: m1, m2: m2 });
$('status').className = 'status'; render();
});
$('correct').addEventListener('click', () => {
const got = teleport(theta, m1, m2); stage = 3;
const ok = got === theta;
$('status').textContent = fmt('%v%Bob applied the correction for bits %m1%%m2%. His qubit is now in Alice’s original state (θ = %theta%°). No copy remains, nothing beat light.', { v: ok ? '✓ ' : '✗ ', m1: m1, m2: m2, theta: theta });
$('status').className = 'status' + (ok ? ' ok' : '');
console.log('teleport(', theta, m1, m2, ') =>', got, '| match:', ok);
render();
});
$('reset').addEventListener('click', () => {
stage = 0; m1 = m2 = null; $('status').textContent = 'Press "Entangle" to begin.';
$('status').className = 'status'; render();
});
render();
Notice what each step does. Entangle links Alice and Bob with a shared resource. Measure has Alice jointly read her mystery qubit together with her half of the pair — this destroys her copy and yields two random classical bits. She sends those bits to Bob, who applies the matching correction. Only then does the original state appear at Bob — exactly, never sooner than the bits arrive.
Comments
Loading comments...