use rand::Rng;
use std::collections::{HashMap, HashSet};
pub struct QMem {
state: u64,
superposition: u64,
entangled: HashMap<usize, usize>,
entangled_groups: HashMap<usize, HashSet<usize>>,
}
impl QMem {
pub fn new() -> Self {
QMem {
state: 0,
superposition: u64::MAX, entangled: HashMap::new(),
entangled_groups: HashMap::new(),
}
}
pub fn set_bit(&mut self, index: usize, value: Option<bool>) {
if index >= 64 {
return; }
if let Some(v) = value {
self.superposition &= !(1 << index); if v {
self.state |= 1 << index; } else {
self.state &= !(1 << index); }
self.collapse_entangled_group(index, v);
} else {
self.superposition |= 1 << index;
}
}
pub fn hadamard(&mut self, index: usize) {
self.set_bit(index, None);
}
pub fn cnot(&mut self, control: usize, target: usize) {
if self.measure(control) {
let target_value = !self.measure(target); self.set_bit(target, Some(target_value));
}
}
pub fn pauli_x(&mut self, index: usize) {
let current_value = self.measure(index);
self.set_bit(index, Some(!current_value));
}
pub fn swap(&mut self, a: usize, b: usize) {
if a == b {
return; }
let temp_a = self.measure(a);
let temp_b = self.measure(b);
self.set_bit(a, Some(temp_b));
self.set_bit(b, Some(temp_a));
}
pub fn entangle(&mut self, a: usize, b: usize) {
if a != b {
self.entangled.insert(a, b);
self.entangled.insert(b, a);
}
}
pub fn entangle_group(&mut self, indices: &[usize]) {
if indices.len() < 2 {
return; }
let mut group = HashSet::new();
for &index in indices {
group.insert(index);
if let Some(existing) = self.entangled_groups.get(&index) {
for &member in existing {
group.insert(member);
}
}
}
let group_clone = group.clone();
for &index in &group {
self.entangled_groups.insert(index, group_clone.clone());
}
}
fn collapse_entangled_group(&mut self, index: usize, value: bool) {
if let Some(group) = self.entangled_groups.get(&index).cloned() {
for &entangled_bit in &group {
if entangled_bit != index && (self.superposition >> entangled_bit) & 1 == 1 {
self.superposition &= !(1 << entangled_bit);
if value {
self.state |= 1 << entangled_bit;
} else {
self.state &= !(1 << entangled_bit);
}
}
}
}
if let Some(&pair) = self.entangled.get(&index) {
if (self.superposition >> pair) & 1 == 1 {
self.superposition &= !(1 << pair);
if value {
self.state |= 1 << pair;
} else {
self.state &= !(1 << pair);
}
}
}
}
pub fn measure(&mut self, index: usize) -> bool {
if index >= 64 {
return false; }
if (self.superposition >> index) & 1 == 1 {
let mut rng = rand::rng();
let value = rng.random_bool(0.5);
self.set_bit(index, Some(value));
value
} else {
(self.state >> index) & 1 == 1
}
}
pub fn bells_test(&mut self, a: usize, b: usize) -> (bool, bool, bool) {
let a_measured = self.measure(a);
let b_measured = self.measure(b);
let correlated = a_measured == b_measured;
println!("\nRunning Bell's Test on qubits {} and {}:", a, b);
println!("Qubit {}: {}, Qubit {}: {}", a, a_measured, b, b_measured);
if correlated {
println!("✅ Correlated (Entanglement Verified)");
} else {
println!("❌ Not Correlated (Possible Decoherence)");
}
(a_measured, b_measured, correlated)
}
pub fn print(&self) {
println!("State: {:064b}", self.state);
println!("Superposition: {:064b}", self.superposition);
println!("Entanglements: {:?}", self.entangled);
println!("Entanglement groups: {:?}", self.entangled_groups);
}
pub fn get_state(&self) -> u64 {
self.state
}
pub fn get_superposition(&self) -> u64 {
self.superposition
}
pub fn get_entangled_pairs(&self) -> &HashMap<usize, usize> {
&self.entangled
}
pub fn get_entangled_groups(&self) -> &HashMap<usize, HashSet<usize>> {
&self.entangled_groups
}
}
impl Default for QMem {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new_qmem() {
let qmem = QMem::new();
assert_eq!(qmem.state, 0);
assert_eq!(qmem.superposition, u64::MAX);
assert!(qmem.entangled.is_empty());
assert!(qmem.entangled_groups.is_empty());
}
#[test]
fn test_set_bit() {
let mut qmem = QMem::new();
qmem.set_bit(0, Some(true));
assert_eq!(qmem.state & 1, 1);
assert_eq!(qmem.superposition & 1, 0);
}
#[test]
fn test_entangle_and_measure() {
let mut qmem = QMem::new();
qmem.entangle(0, 1);
qmem.set_bit(0, Some(true));
assert_eq!(qmem.measure(1), true);
}
}