use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct CognitiveState {
candidates: Vec<(u64, f64, f64)>, pub t2_cognitive: f64,
pub age: f64,
pub collapse_threshold: f64,
}
#[derive(Debug, Clone)]
pub struct CollapseResult {
pub collapsed_id: u64,
pub confidence: f64,
pub ticks_in_superposition: f64,
pub alternatives: Vec<(u64, f64)>,
}
impl CognitiveState {
pub fn new(t2: f64) -> Self {
Self {
candidates: Vec::new(),
t2_cognitive: t2,
age: 0.0,
collapse_threshold: 0.3,
}
}
pub fn load(&mut self, candidates: &[(u64, f64)]) {
let total_sq: f64 = candidates.iter().map(|(_, s)| s * s).sum::<f64>();
let norm = total_sq.sqrt().max(1e-10);
self.candidates = candidates
.iter()
.map(|&(id, score)| (id, score / norm, 0.0))
.collect();
self.age = 0.0;
}
pub fn interfere(&mut self, similarity_matrix: &HashMap<(u64, u64), f64>) {
let n = self.candidates.len();
if n == 0 {
return;
}
let mut new_re = vec![0.0f64; n];
let mut new_im = vec![0.0f64; n];
for (i, (id_i, _, _)) in self.candidates.iter().enumerate() {
for (j, (id_j, re_j, im_j)) in self.candidates.iter().enumerate() {
let sim = similarity_matrix
.get(&(*id_i.min(id_j), *id_i.max(id_j)))
.copied()
.unwrap_or(if i == j { 1.0 } else { 0.0 });
new_re[i] += sim * re_j / n as f64;
new_im[i] += sim * im_j / n as f64;
}
}
for (i, (_, re, im)) in self.candidates.iter_mut().enumerate() {
*re = new_re[i];
*im = new_im[i];
}
self.normalize();
}
fn normalize(&mut self) {
let norm = self
.candidates
.iter()
.map(|(_, r, i)| r * r + i * i)
.sum::<f64>()
.sqrt();
if norm > 1e-10 {
for (_, re, im) in self.candidates.iter_mut() {
*re /= norm;
*im /= norm;
}
}
}
pub fn decohere(&mut self, dt: f64) {
self.age += dt;
let t2_factor = (-self.age / self.t2_cognitive).exp();
for (_, re, im) in self.candidates.iter_mut() {
*re *= t2_factor;
*im *= t2_factor;
}
}
pub fn purity(&self) -> f64 {
self.candidates.iter().map(|(_, r, i)| r * r + i * i).sum()
}
pub fn collapse(&self) -> CollapseResult {
let probs: Vec<(u64, f64)> = self
.candidates
.iter()
.map(|&(id, re, im)| (id, re * re + im * im))
.collect();
let best = probs
.iter()
.max_by(|a, b| a.1.partial_cmp(&b.1).unwrap())
.copied()
.unwrap_or((0, 0.0));
let alternatives: Vec<(u64, f64)> = probs
.iter()
.filter(|&&(id, p)| id != best.0 && p > 0.05)
.copied()
.collect();
CollapseResult {
collapsed_id: best.0,
confidence: best.1,
ticks_in_superposition: self.age,
alternatives,
}
}
pub fn should_collapse(&self) -> bool {
self.purity() < self.collapse_threshold
}
}
pub struct QuantumSuperpositionExperiment {
pub t2_cognitive: f64,
pub n_candidates: usize,
pub interference_steps: usize,
}
pub struct SuperpositionResult {
pub superposition_accuracy: f64,
pub greedy_accuracy: f64,
pub avg_confidence: f64,
pub avg_superposition_duration: f64,
pub accuracy_advantage: f64,
}
impl QuantumSuperpositionExperiment {
pub fn new() -> Self {
Self {
t2_cognitive: 20.0,
n_candidates: 8,
interference_steps: 3,
}
}
pub fn run(&self, n_trials: usize) -> SuperpositionResult {
let mut superposition_correct = 0usize;
let mut greedy_correct = 0usize;
let mut total_confidence = 0.0f64;
let mut total_duration = 0.0f64;
for trial in 0..n_trials {
let correct_id = 0u64;
let correct_score = 0.8 + (trial as f64 * 0.01).sin() * 0.1;
let candidates: Vec<(u64, f64)> = (0..self.n_candidates as u64)
.map(|id| {
let score = if id == 0 {
correct_score
} else {
0.3 + (id as f64 * trial as f64 * 0.01).sin() * 0.2
};
(id, score.max(0.0))
})
.collect();
let greedy_choice = candidates
.iter()
.max_by(|a, b| a.1.partial_cmp(&b.1).unwrap())
.map(|(id, _)| *id)
.unwrap_or(0);
if greedy_choice == correct_id {
greedy_correct += 1;
}
let mut state = CognitiveState::new(self.t2_cognitive);
state.load(&candidates);
let mut sim_matrix = HashMap::new();
for i in 0..self.n_candidates as u64 {
for j in i..self.n_candidates as u64 {
let sim = if i == j {
1.0
} else if i == correct_id || j == correct_id {
0.6
} else {
0.2
};
sim_matrix.insert((i, j), sim);
}
}
for _ in 0..self.interference_steps {
state.interfere(&sim_matrix);
state.decohere(5.0);
if state.should_collapse() {
break;
}
}
let result = state.collapse();
if result.collapsed_id == correct_id {
superposition_correct += 1;
}
total_confidence += result.confidence;
total_duration += result.ticks_in_superposition;
}
let n = n_trials.max(1) as f64;
let sup_acc = superposition_correct as f64 / n;
let greed_acc = greedy_correct as f64 / n;
SuperpositionResult {
superposition_accuracy: sup_acc,
greedy_accuracy: greed_acc,
avg_confidence: total_confidence / n,
avg_superposition_duration: total_duration / n,
accuracy_advantage: sup_acc - greed_acc,
}
}
}
impl Default for QuantumSuperpositionExperiment {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cognitive_state_normalizes() {
let mut state = CognitiveState::new(20.0);
state.load(&[(0, 0.6), (1, 0.8), (2, 0.3)]);
let purity = state.purity();
assert!(
(purity - 1.0).abs() < 1e-9,
"State should be normalized: purity={}",
purity
);
}
#[test]
fn test_decoherence_reduces_purity() {
let mut state = CognitiveState::new(10.0);
state.load(&[(0, 0.7), (1, 0.3), (2, 0.5), (3, 0.2)]);
for _ in 0..5 {
state.decohere(5.0);
}
assert!(state.purity() < 0.9, "Decoherence should reduce purity");
}
#[test]
fn test_superposition_vs_greedy() {
let exp = QuantumSuperpositionExperiment::new();
let result = exp.run(50);
assert!(result.superposition_accuracy > 0.0);
assert!(result.greedy_accuracy > 0.0);
assert!(result.avg_confidence > 0.0 && result.avg_confidence <= 1.0);
}
#[test]
fn test_interference_changes_amplitudes() {
let mut state = CognitiveState::new(20.0);
state.load(&[(0, 0.6), (1, 0.4)]);
let pre_purity = state.purity();
let sim = HashMap::from([((0u64, 1u64), 0.9)]);
state.interfere(&sim);
let post_purity = state.purity();
assert!((pre_purity - post_purity).abs() > 1e-10 || pre_purity > 0.0);
}
}