From af1452363089087f392172c824d15261fa9b0825 Mon Sep 17 00:00:00 2001 From: Transaction Science Date: Mon, 19 Oct 2026 11:17:46 -0400 Subject: [PATCH] wai-quantum-service: two worked examples that measure in the middle Teleportation (the state vector, four branches weighed) and the three-qubit bit-flip code with its syndrome read mid-circuit and the correction chosen by if (the stabilizer tableau). A test runs both and holds them to what their descriptions say. Co-Authored-By: Claude Opus 5.5 --- wai/wai-quantum-service/src/discovery.rs | 14 ++++++++++++++ wai/wai-quantum-service/src/run.rs | 19 +++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/wai/wai-quantum-service/src/discovery.rs b/wai/wai-quantum-service/src/discovery.rs index 80b2cdf9d..01ba21291 100644 --- a/wai/wai-quantum-service/src/discovery.rs +++ b/wai/wai-quantum-service/src/discovery.rs @@ -58,6 +58,18 @@ pub fn examples() -> Value { "shows": "The same pair with gate errors and readout flips: 01 and 10 appear, and ⟨Z0 Z1⟩ falls below 1. With noise on few qubits the exact density matrix runs.", "job": { "qasm": ghz(2), "shots": 4000, "observables": ["Z0 Z1"], "noise": { "depolarizing_1q": 0.01, "depolarizing_2q": 0.03, "readout": 0.02 } } }, + { + "name": "teleport", + "title": "Teleporting a qubit", + "shows": "ry(0.7) on q0 arrives on q2: two qubits are measured in the middle, and if applies the corrections they select. ⟨Z2⟩ = cos 0.7 and ⟨X2⟩ = sin 0.7 exactly, weighed over all four branches; the shots split at each measurement as independent runs would.", + "job": { "qasm": "OPENQASM 3.0;\nqubit[3] q;\nbit[3] c;\nry(0.7) q[0];\nh q[1];\ncx q[1], q[2];\ncx q[0], q[1];\nh q[0];\nc[0] = measure q[0];\nc[1] = measure q[1];\nif (c[1]) x q[2];\nif (c[0]) z q[2];\nc[2] = measure q[2];", "shots": 1000, "observables": ["Z2", "X2"] } + }, + { + "name": "bit-flip-code", + "title": "A bit flip found and undone", + "shows": "The three-qubit bit-flip code holding |+⟩, with a flip on the middle qubit. Two ancillas, measured in the middle, name the flip (the syndrome reads 11 on every shot), and if undoes it, so ⟨X0⟩ = 1 after decoding. Every gate is Clifford, so the stabilizer tableau runs.", + "job": { "qasm": "OPENQASM 3.0;\nqubit[5] q;\nbit[2] s;\nbit r;\nh q[0];\ncx q[0], q[1];\ncx q[0], q[2];\nx q[1];\ncx q[0], q[3];\ncx q[1], q[3];\ncx q[1], q[4];\ncx q[2], q[4];\ns[0] = measure q[3];\ns[1] = measure q[4];\nif (s == 1) x q[0];\nif (s == 3) x q[1];\nif (s == 2) x q[2];\ncx q[0], q[1];\ncx q[0], q[2];\nr = measure q[0];", "shots": 1000, "observables": ["X0"] } + }, { "name": "ghz-1000", "title": "A thousand-qubit GHZ state", @@ -196,6 +208,8 @@ mod tests { ("rotation", "statevector"), ("qaoa-ring", "statevector"), ("noisy-bell", "density_matrix"), + ("teleport", "statevector"), + ("bit-flip-code", "stabilizer"), ("ghz-1000", "stabilizer"), ("noisy-ghz-500", "stabilizer"), ("chain-100-dynamics", "pauli"), diff --git a/wai/wai-quantum-service/src/run.rs b/wai/wai-quantum-service/src/run.rs index f8b46883f..9bacd9cc4 100644 --- a/wai/wai-quantum-service/src/run.rs +++ b/wai/wai-quantum-service/src/run.rs @@ -866,6 +866,25 @@ mod tests { } } + /// The two worked examples that measure in the middle do what their + /// `shows` says. + #[test] + fn the_measuring_examples_show_what_they_say() { + let ex = crate::discovery::examples(); + let job = |name: &str| ex.as_array().unwrap().iter().find(|e| e["name"] == name).unwrap()["job"].clone(); + let t = go(job("teleport")); + assert_eq!(t["method"], "statevector", "{t}"); + assert!((t["expectations"][0]["value"].as_f64().unwrap() - 0.7f64.cos()).abs() < 1e-12, "{t}"); + assert!((t["expectations"][1]["value"].as_f64().unwrap() - 0.7f64.sin()).abs() < 1e-12, "{t}"); + assert_eq!(t["dynamic"]["branches_weighed"], 4, "{t}"); + let b = go(job("bit-flip-code")); + assert_eq!(b["method"], "stabilizer", "{b}"); + assert_eq!(b["expectations"][0]["value"], 1.0, "{b}"); + let counts = b["counts"].as_object().unwrap(); + assert!(counts.keys().all(|k| k.ends_with("11")), "the syndrome names the middle qubit on every shot: {b}"); + assert_eq!(counts.values().map(|v| v.as_u64().unwrap()).sum::(), 1000); + } + #[test] fn dynamic_runs_repeat_with_their_seed() { let qasm = TELEPORT.replace("THETA", "1.1"); -- 2.54.0 (Apple Git-157)