use crate::core::{FactorizationStateSpace, FactorizationError};
use std::fmt;
use thiserror::Error;
use serde::{Deserialize, Serialize};
#[derive(Error, Debug, Clone, PartialEq)]
pub enum StateSpaceError {
#[error("Factorization error: {0}")]
FactorizationError(#[from] FactorizationError),
#[error("Invalid state space operation: {0}")]
InvalidOperation(String),
#[error("Incompatible state spaces")]
IncompatibleSpaces,
#[error("Operation result too large")]
ResultTooLarge,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct StateSpaceMultiplicationResult {
pub result_space: FactorizationStateSpace,
pub collapse_info: CollapseInfo,
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct CollapseInfo {
pub collapsed: bool,
pub input_sizes: (usize, usize),
pub output_size: usize,
pub collapse_ratio: f64,
pub operation_type: OperationType,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum OperationType {
ClassicalClassical,
ClassicalQuantum,
QuantumQuantum,
Other,
}
pub struct StateSpaceOperations;
impl StateSpaceOperations {
pub fn multiply(
space_a: &FactorizationStateSpace,
space_b: &FactorizationStateSpace,
) -> Result<StateSpaceMultiplicationResult, StateSpaceError> {
let a = space_a.value();
let b = space_b.value();
let c = a.checked_mul(b)
.ok_or(StateSpaceError::ResultTooLarge)?;
let operation_type = Self::classify_operation(a, b);
let result_space = FactorizationStateSpace::new(c)?;
let input_sizes = (space_a.size(), space_b.size());
let output_size = result_space.size();
let max_input_size = input_sizes.0.max(input_sizes.1);
let collapsed = matches!(operation_type, OperationType::QuantumQuantum);
let collapse_ratio = if max_input_size > 0 {
output_size as f64 / max_input_size as f64
} else {
1.0
};
let collapse_info = CollapseInfo {
collapsed,
input_sizes,
output_size,
collapse_ratio,
operation_type,
};
Ok(StateSpaceMultiplicationResult {
result_space,
collapse_info,
})
}
fn classify_operation(a: i64, b: i64) -> OperationType {
match (a > 0, b > 0) {
(true, true) => OperationType::ClassicalClassical,
(true, false) | (false, true) => OperationType::ClassicalQuantum,
(false, false) => OperationType::QuantumQuantum,
}
}
pub fn power(
space: &FactorizationStateSpace,
exponent: u32,
) -> Result<StateSpaceMultiplicationResult, StateSpaceError> {
if exponent == 0 {
let unity_space = FactorizationStateSpace::new(1)?;
return Ok(StateSpaceMultiplicationResult {
result_space: unity_space,
collapse_info: CollapseInfo {
collapsed: false,
input_sizes: (space.size(), 1),
output_size: 1,
collapse_ratio: 1.0,
operation_type: OperationType::Other,
},
});
}
if exponent == 1 {
return Ok(StateSpaceMultiplicationResult {
result_space: space.clone(),
collapse_info: CollapseInfo {
collapsed: false,
input_sizes: (space.size(), space.size()),
output_size: space.size(),
collapse_ratio: 1.0,
operation_type: OperationType::Other,
},
});
}
let a = space.value();
let result = a.checked_pow(exponent)
.ok_or(StateSpaceError::ResultTooLarge)?;
let result_space = FactorizationStateSpace::new(result)?;
let collapsed = a < 0 && exponent % 2 == 0;
let input_sizes = (space.size(), space.size());
let output_size = result_space.size();
let collapse_ratio = if space.size() > 0 {
output_size as f64 / space.size() as f64
} else {
1.0
};
let collapse_info = CollapseInfo {
collapsed,
input_sizes,
output_size,
collapse_ratio,
operation_type: OperationType::Other,
};
Ok(StateSpaceMultiplicationResult {
result_space,
collapse_info,
})
}
pub fn sign_flip(
space: &FactorizationStateSpace,
) -> Result<FactorizationStateSpace, StateSpaceError> {
let flipped_value = -space.value();
Ok(FactorizationStateSpace::new(flipped_value)?)
}
pub fn can_multiply(
space_a: &FactorizationStateSpace,
space_b: &FactorizationStateSpace,
) -> bool {
space_a.value().checked_mul(space_b.value()).is_some()
}
pub fn analyze_superposition(space: &FactorizationStateSpace) -> SuperpositionAnalysis {
let value = space.value();
let size = space.size();
let is_quantum = value < 0;
let is_classical = value > 0;
let theoretical_max_size = if value.abs() == 1 {
1
} else {
let abs_val = value.abs();
let log_estimate = (abs_val as f64).log2().ceil() as usize;
1 << log_estimate.min(10) };
let superposition_measure = size as f64 / theoretical_max_size as f64;
let sign_prime_factorizations = space.factorizations().iter()
.filter(|f| f.has_sign_prime())
.count();
SuperpositionAnalysis {
is_quantum,
is_classical,
state_space_size: size,
superposition_measure,
sign_prime_factorizations,
complexity_distribution: Self::compute_complexity_distribution(space),
}
}
fn compute_complexity_distribution(space: &FactorizationStateSpace) -> Vec<u32> {
space.factorizations().iter()
.map(|f| f.complexity())
.collect()
}
}
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
pub struct SuperpositionAnalysis {
pub is_quantum: bool,
pub is_classical: bool,
pub state_space_size: usize,
pub superposition_measure: f64,
pub sign_prime_factorizations: usize,
pub complexity_distribution: Vec<u32>,
}
impl SuperpositionAnalysis {
pub fn average_complexity(&self) -> f64 {
if self.complexity_distribution.is_empty() {
0.0
} else {
let sum: u32 = self.complexity_distribution.iter().sum();
sum as f64 / self.complexity_distribution.len() as f64
}
}
pub fn entropy(&self) -> f64 {
if self.state_space_size <= 1 {
0.0
} else {
(self.state_space_size as f64).log2()
}
}
}
impl fmt::Display for SuperpositionAnalysis {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "Superposition Analysis:")?;
writeln!(f, " Type: {}", if self.is_quantum { "Quantum" } else { "Classical" })?;
writeln!(f, " State space size: {}", self.state_space_size)?;
writeln!(f, " Superposition measure: {:.3}", self.superposition_measure)?;
writeln!(f, " Sign prime factorizations: {}", self.sign_prime_factorizations)?;
writeln!(f, " Average complexity: {:.2}", self.average_complexity())?;
writeln!(f, " Entropy: {:.3}", self.entropy())?;
Ok(())
}
}
impl fmt::Display for CollapseInfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
writeln!(f, "Collapse Information:")?;
writeln!(f, " Operation type: {:?}", self.operation_type)?;
writeln!(f, " Collapsed: {}", self.collapsed)?;
writeln!(f, " Input sizes: {:?}", self.input_sizes)?;
writeln!(f, " Output size: {}", self.output_size)?;
writeln!(f, " Collapse ratio: {:.3}", self.collapse_ratio)?;
Ok(())
}
}
impl FactorizationStateSpace {
pub fn multiply(&self, other: &FactorizationStateSpace) -> Result<StateSpaceMultiplicationResult, StateSpaceError> {
StateSpaceOperations::multiply(self, other)
}
pub fn power(&self, exponent: u32) -> Result<StateSpaceMultiplicationResult, StateSpaceError> {
StateSpaceOperations::power(self, exponent)
}
pub fn sign_flip(&self) -> Result<FactorizationStateSpace, StateSpaceError> {
StateSpaceOperations::sign_flip(self)
}
pub fn analyze_superposition(&self) -> SuperpositionAnalysis {
StateSpaceOperations::analyze_superposition(self)
}
pub fn is_quantum(&self) -> bool {
self.value() < 0
}
pub fn is_classical(&self) -> bool {
self.value() > 0
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_classical_classical_multiplication() {
let s2 = FactorizationStateSpace::new(2).unwrap();
let s3 = FactorizationStateSpace::new(3).unwrap();
let result = StateSpaceOperations::multiply(&s2, &s3).unwrap();
assert_eq!(result.result_space.value(), 6);
assert!(!result.collapse_info.collapsed);
assert_eq!(result.collapse_info.operation_type, OperationType::ClassicalClassical);
}
#[test]
fn test_quantum_quantum_collapse() {
let s_neg2 = FactorizationStateSpace::new(-2).unwrap();
let s_neg3 = FactorizationStateSpace::new(-3).unwrap();
let result = StateSpaceOperations::multiply(&s_neg2, &s_neg3).unwrap();
assert_eq!(result.result_space.value(), 6);
assert!(result.collapse_info.collapsed);
assert_eq!(result.collapse_info.operation_type, OperationType::QuantumQuantum);
let max_input_size = s_neg2.size().max(s_neg3.size());
assert!(result.result_space.size() <= max_input_size);
}
#[test]
fn test_classical_quantum_interaction() {
let s2 = FactorizationStateSpace::new(2).unwrap();
let s_neg3 = FactorizationStateSpace::new(-3).unwrap();
let result = StateSpaceOperations::multiply(&s2, &s_neg3).unwrap();
assert_eq!(result.result_space.value(), -6);
assert!(!result.collapse_info.collapsed);
assert_eq!(result.collapse_info.operation_type, OperationType::ClassicalQuantum);
}
#[test]
fn test_power_operations() {
let s_neg2 = FactorizationStateSpace::new(-2).unwrap();
let result_even = StateSpaceOperations::power(&s_neg2, 2).unwrap();
assert_eq!(result_even.result_space.value(), 4);
assert!(result_even.collapse_info.collapsed);
let result_odd = StateSpaceOperations::power(&s_neg2, 3).unwrap();
assert_eq!(result_odd.result_space.value(), -8);
assert!(!result_odd.collapse_info.collapsed);
let result_zero = StateSpaceOperations::power(&s_neg2, 0).unwrap();
assert_eq!(result_zero.result_space.value(), 1);
}
#[test]
fn test_sign_flip() {
let s6 = FactorizationStateSpace::new(6).unwrap();
let s_neg6 = StateSpaceOperations::sign_flip(&s6).unwrap();
assert_eq!(s_neg6.value(), -6);
assert!(s_neg6.is_quantum());
let s6_again = StateSpaceOperations::sign_flip(&s_neg6).unwrap();
assert_eq!(s6_again.value(), 6);
assert!(s6_again.is_classical());
}
#[test]
fn test_superposition_analysis() {
let s6 = FactorizationStateSpace::new(6).unwrap();
let analysis = StateSpaceOperations::analyze_superposition(&s6);
assert!(analysis.is_classical);
assert!(!analysis.is_quantum);
assert_eq!(analysis.state_space_size, 2);
assert_eq!(analysis.sign_prime_factorizations, 0);
let s_neg6 = FactorizationStateSpace::new(-6).unwrap();
let quantum_analysis = StateSpaceOperations::analyze_superposition(&s_neg6);
assert!(!quantum_analysis.is_classical);
assert!(quantum_analysis.is_quantum);
assert!(quantum_analysis.state_space_size > analysis.state_space_size);
assert!(quantum_analysis.sign_prime_factorizations > 0);
assert!(quantum_analysis.entropy() > analysis.entropy());
}
#[test]
fn test_can_multiply() {
let s2 = FactorizationStateSpace::new(2).unwrap();
let s3 = FactorizationStateSpace::new(3).unwrap();
assert!(StateSpaceOperations::can_multiply(&s2, &s3));
let space_small = FactorizationStateSpace::new(1000).unwrap();
let space_large = FactorizationStateSpace::new(9000).unwrap();
assert!(StateSpaceOperations::can_multiply(&space_small, &space_large));
}
#[test]
fn test_convenience_methods() {
let s2 = FactorizationStateSpace::new(2).unwrap();
let s3 = FactorizationStateSpace::new(3).unwrap();
let result = s2.multiply(&s3).unwrap();
assert_eq!(result.result_space.value(), 6);
let power_result = s2.power(3).unwrap();
assert_eq!(power_result.result_space.value(), 8);
let flipped = s2.sign_flip().unwrap();
assert_eq!(flipped.value(), -2);
assert!(s2.is_classical());
assert!(!s2.is_quantum());
assert!(!flipped.is_classical());
assert!(flipped.is_quantum());
}
#[test]
fn test_collapse_ratios() {
let s_neg6 = FactorizationStateSpace::new(-6).unwrap(); let s_neg2 = FactorizationStateSpace::new(-2).unwrap();
let result = s_neg6.multiply(&s_neg2).unwrap();
assert_eq!(result.result_space.value(), 12);
assert!(result.collapse_info.collapsed);
assert!(result.collapse_info.collapse_ratio <= 1.0);
}
#[test]
fn test_display_formatting() {
let s_neg6 = FactorizationStateSpace::new(-6).unwrap();
let analysis = s_neg6.analyze_superposition();
let analysis_str = format!("{}", analysis);
assert!(analysis_str.contains("Quantum"));
assert!(analysis_str.contains("State space size"));
let s2 = FactorizationStateSpace::new(2).unwrap();
let s3 = FactorizationStateSpace::new(3).unwrap();
let result = s2.multiply(&s3).unwrap();
let collapse_str = format!("{}", result.collapse_info);
assert!(collapse_str.contains("ClassicalClassical"));
assert!(collapse_str.contains("Collapsed: false"));
}
}