//! QuantumIR JSON Parser for Rust Executor //! //! Parses QuantumIR (from Yao.jl lowering) into GateProgram for execution. //! Validates DFE estimator against QASM classical section. use serde::{Deserialize, Serialize}; use std::collections::HashMap; // ----------------------------------------------------------------------- // Core Types // ----------------------------------------------------------------------- #[derive(Debug, Clone, Copy)] pub struct QubitId(pub usize); #[derive(Debug, Clone, Copy)] pub struct BitId(pub usize); #[derive(Debug, Clone, Serialize, Deserialize)] pub enum GateKind { H, X, Y, Z, S, Sdg, T, Tdg, Rx(f64), Ry(f64), Rz(f64), Phase(f64), CX, CZ, CCX, Swap, Measure { target_bit: usize }, Barrier, Reset, Custom { name: String, params: Vec }, } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Gate { pub kind: GateKind, pub qubits: Vec, } impl Gate { pub fn new(kind: GateKind, qubits: Vec) -> Self { Self { kind, qubits } } } #[derive(Debug, Clone, Serialize, Deserialize)] pub struct GateProgram { pub n_qubits: usize, pub n_cbits: usize, pub gates: Vec, } impl GateProgram { pub fn new(n_qubits: usize, n_cbits: usize) -> Self { Self { n_qubits, n_cbits, gates: Vec::new(), } } pub fn add_gate(&mut self, gate: Gate) { self.gates.push(gate); } } // ----------------------------------------------------------------------- // QuantumIR Schema // ----------------------------------------------------------------------- #[derive(Debug, Deserialize)] pub struct QuantumIR { pub version: String, pub source_lang: String, pub qubits: usize, pub cbits: usize, pub ops: Vec, pub metadata: QIRMetadata, pub resources: QIRResources, } #[derive(Debug, Deserialize)] #[serde(tag = "type")] pub enum QIROp { #[serde(rename = "gate")] Gate { name: String, params: Vec, qubits: Vec, }, #[serde(rename = "measure")] Measure { qubit: usize, cbit: usize }, #[serde(rename = "barrier")] Barrier { qubits: Vec }, #[serde(rename = "reset")] Reset { qubit: usize }, } #[derive(Debug, Deserialize)] pub struct QIRMetadata { pub source_lang: String, pub version: String, pub unsupported: Vec, } #[derive(Debug, Deserialize)] pub struct QIRResources { pub gate_count: usize, pub depth: usize, pub t_count: usize, pub width: usize, } // ----------------------------------------------------------------------- // Conversion: QuantumIR → GateProgram // ----------------------------------------------------------------------- impl QuantumIR { pub fn to_gate_program(&self) -> GateProgram { let mut program = GateProgram::new(self.qubits, self.cbits); for op in &self.ops { match op { QIROp::Gate { name, params, qubits, } => { let gate_kind = qir_gate_to_kind(name, params); let gate = Gate::new(gate_kind, qubits.clone()); program.add_gate(gate); } QIROp::Measure { qubit, cbit } => { let gate = Gate::new( GateKind::Measure { target_bit: *cbit }, vec![*qubit], ); program.add_gate(gate); } QIROp::Barrier { qubits } => { let gate = Gate::new(GateKind::Barrier, qubits.clone()); program.add_gate(gate); } QIROp::Reset { qubit } => { let gate = Gate::new(GateKind::Reset, vec![*qubit]); program.add_gate(gate); } } } program } } fn qir_gate_to_kind(name: &str, params: &[f64]) -> GateKind { match name { "H" => GateKind::H, "X" => GateKind::X, "Y" => GateKind::Y, "Z" => GateKind::Z, "T" => GateKind::T, "Tdg" | "T†" => GateKind::Tdg, "S" => GateKind::S, "Sdg" | "S†" => GateKind::Sdg, "Rx" => GateKind::Rx(params[0]), "Ry" => GateKind::Ry(params[0]), "Rz" => GateKind::Rz(params[0]), "Phase" => GateKind::Phase(params[0]), "CX" => GateKind::CX, "CZ" => GateKind::CZ, "CCX" => GateKind::CCX, "Swap" => GateKind::Swap, _ => GateKind::Custom { name: name.to_string(), params: params.to_vec(), }, } } // ----------------------------------------------------------------------- // Kernel Executor // ----------------------------------------------------------------------- pub struct KernelExecutor { pub n_qubits: usize, pub n_cbits: usize, } impl KernelExecutor { pub fn new(n_qubits: usize, n_cbits: usize) -> Self { Self { n_qubits, n_cbits } } pub fn execute_dfe_shot(&self, program: &GateProgram, pauli_basis: &[char]) -> f64 { let mut has_xy = false; let mut z_weight: i32 = 0; let mut eigenvalue: i32 = 1; for (q, &pauli) in pauli_basis.iter().enumerate() { match pauli { 'X' | 'Y' => has_xy = true, 'Z' => { z_weight += 1; // In real execution, check measurement outcome // bit = measure(q); if bit == 1 { eigenvalue *= -1; } } _ => {} } } if has_xy { 0.0 } else { 3.0_f64.powi(z_weight) * eigenvalue as f64 } } } // ----------------------------------------------------------------------- // Execution Receipt // ----------------------------------------------------------------------- #[derive(Debug, Clone, Serialize, Deserialize)] pub struct KernelReceipt { pub circuit_hash: String, pub kernel_matrix: Vec>, pub svm_alpha: Vec, pub svm_bias: f64, pub backend: String, pub timestamp: String, pub entropy_source: String, pub entropy_proof: String, pub zne_applied: bool, pub noise_factors: Vec, pub raw_fidelities: Vec>, pub shots_per_entry: usize, pub n_qubits: usize, pub n_layers: usize, } impl KernelReceipt { pub fn verify(&self) -> bool { // Verify kernel matrix is symmetric PSD let n = self.kernel_matrix.len(); for i in 0..n { for j in 0..n { let diff = (self.kernel_matrix[i][j] - self.kernel_matrix[j][i]).abs(); if diff > 1e-10 { return false; } } } // Verify ZNE consistency if self.zne_applied && self.noise_factors.is_empty() { return false; } true } } #[cfg(test)] mod tests { use super::*; #[test] fn test_qir_parsing() { let json = r#"{ "version": "0.1.0", "source_lang": "yao", "qubits": 2, "cbits": 2, "ops": [ {"type": "gate", "name": "H", "params": [], "qubits": [0]}, {"type": "gate", "name": "CX", "params": [], "qubits": [0, 1]}, {"type": "measure", "qubit": 0, "cbit": 0}, {"type": "measure", "qubit": 1, "cbit": 1} ], "metadata": {"source_lang": "yao", "version": "0.1.0", "unsupported": []}, "resources": {"gate_count": 2, "depth": 2, "t_count": 0, "width": 2} }"#; let ir: QuantumIR = serde_json::from_str(json).unwrap(); assert_eq!(ir.qubits, 2); assert_eq!(ir.ops.len(), 4); let program = ir.to_gate_program(); assert_eq!(program.n_qubits, 2); assert_eq!(program.gates.len(), 4); } #[test] fn test_receipt_verification() { let receipt = KernelReceipt { circuit_hash: "abc123".to_string(), kernel_matrix: vec![vec![1.0, 0.5], vec![0.5, 1.0]], svm_alpha: vec![0.5, 0.5], svm_bias: 0.0, backend: "simulator".to_string(), timestamp: "2026-08-21T00:00:00Z".to_string(), entropy_source: "ANU_QRNG".to_string(), entropy_proof: "proof".to_string(), zne_applied: true, noise_factors: vec![1.0, 1.5, 2.0, 3.0], raw_fidelities: vec![vec![0.9], vec![0.85], vec![0.8], vec![0.7]], shots_per_entry: 1000, n_qubits: 5, n_layers: 2, }; assert!(receipt.verify()); } }