ppflib 0.1.0

Advanced computational library for Physics-Prime Factorization (PPF): quantum mechanics through number theory, featuring Sign Prime (-1), state space collapse, topological analysis, and IOT geometric realizations
Documentation
//! Sign Prime (-1) implementation
//!
//! This module implements -1 as a special prime in the PPF framework, providing
//! unique arithmetic properties and validation functions for P-prime classification.

use num_bigint::BigInt;
use std::fmt;
use thiserror::Error;

/// The Sign Prime constant (-1)
pub const SIGN_PRIME: i64 = -1;

/// Errors that can occur during Sign Prime operations
#[derive(Error, Debug, Clone, PartialEq)]
pub enum SignPrimeError {
    /// An invalid operation was attempted
    #[error("Invalid operation: {0}")]
    InvalidOperation(String),
    /// Sign Prime power must be non-negative
    #[error("Sign Prime power must be non-negative")]
    InvalidPower,
}

/// Represents the Sign Prime (-1) with its special properties
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct SignPrime;

impl SignPrime {
    /// Create a new Sign Prime instance
    pub fn new() -> Self {
        SignPrime
    }

    /// Get the integer value of the Sign Prime
    pub fn value(&self) -> i64 {
        SIGN_PRIME
    }

    /// Check if this is the Sign Prime
    pub fn is_sign_prime(&self) -> bool {
        true
    }

    /// Multiply Sign Prime by itself n times
    /// 
    /// # Arguments
    /// * `n` - Non-negative exponent
    /// 
    /// # Returns
    /// * `1` if n is even, `-1` if n is odd
    /// 
    /// # Examples
    /// ```
    /// use ppflib::core::SignPrime;
    /// 
    /// let sp = SignPrime::new();
    /// assert_eq!(sp.power(0).unwrap(), 1);
    /// assert_eq!(sp.power(1).unwrap(), -1);
    /// assert_eq!(sp.power(2).unwrap(), 1);
    /// assert_eq!(sp.power(3).unwrap(), -1);
    /// ```
    pub fn power(&self, n: u32) -> Result<i64, SignPrimeError> {
        if n % 2 == 0 {
            Ok(1)
        } else {
            Ok(-1)
        }
    }

    /// Multiply Sign Prime with another integer
    /// 
    /// # Arguments
    /// * `other` - Integer to multiply with
    /// 
    /// # Returns
    /// * Negative of the input integer
    /// 
    /// # Examples
    /// ```
    /// use ppflib::core::SignPrime;
    /// 
    /// let sp = SignPrime::new();
    /// assert_eq!(sp.multiply(5), -5);
    /// assert_eq!(sp.multiply(-3), 3);
    /// ```
    pub fn multiply(&self, other: i64) -> i64 {
        -other
    }

    /// Multiply Sign Prime with a BigInt
    pub fn multiply_bigint(&self, other: &BigInt) -> BigInt {
        -other
    }

    /// Check if Sign Prime divides an integer
    /// 
    /// The Sign Prime (-1) divides any integer, as every integer n can be written as (-1) * (-n)
    /// 
    /// # Arguments
    /// * `n` - Integer to check divisibility
    /// 
    /// # Returns
    /// * Always `true` for non-zero integers
    /// 
    /// # Examples
    /// ```
    /// use ppflib::core::SignPrime;
    /// 
    /// let sp = SignPrime::new();
    /// assert!(sp.divides(42));
    /// assert!(sp.divides(-17));
    /// assert!(!sp.divides(0)); // Division by zero case
    /// ```
    pub fn divides(&self, n: i64) -> bool {
        n != 0
    }

    /// Get the quotient when dividing an integer by the Sign Prime
    /// 
    /// # Arguments
    /// * `n` - Integer to divide
    /// 
    /// # Returns
    /// * The negative of the input integer
    /// 
    /// # Examples
    /// ```
    /// use ppflib::core::SignPrime;
    /// 
    /// let sp = SignPrime::new();
    /// assert_eq!(sp.divide(6).unwrap(), -6);
    /// assert_eq!(sp.divide(-8).unwrap(), 8);
    /// ```
    pub fn divide(&self, n: i64) -> Result<i64, SignPrimeError> {
        if n == 0 {
            Err(SignPrimeError::InvalidOperation("Division by zero".to_string()))
        } else {
            Ok(-n)
        }
    }
}

impl Default for SignPrime {
    fn default() -> Self {
        Self::new()
    }
}

impl fmt::Display for SignPrime {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "-1")
    }
}

/// Check if a given integer is the Sign Prime
/// 
/// # Arguments
/// * `n` - Integer to check
/// 
/// # Returns
/// * `true` if n == -1, `false` otherwise
/// 
/// # Examples
/// ```
/// use ppflib::core::is_sign_prime;
/// 
/// assert!(is_sign_prime(-1));
/// assert!(!is_sign_prime(1));
/// assert!(!is_sign_prime(-2));
/// ```
pub fn is_sign_prime(n: i64) -> bool {
    n == SIGN_PRIME
}

/// Check if a BigInt is the Sign Prime
pub fn is_sign_prime_bigint(n: &BigInt) -> bool {
    n == &BigInt::from(SIGN_PRIME)
}

/// Sign Prime arithmetic operations
impl std::ops::Mul<i64> for SignPrime {
    type Output = i64;

    fn mul(self, rhs: i64) -> Self::Output {
        self.multiply(rhs)
    }
}

impl std::ops::Mul<SignPrime> for i64 {
    type Output = i64;

    fn mul(self, rhs: SignPrime) -> Self::Output {
        rhs.multiply(self)
    }
}

impl std::ops::Mul<SignPrime> for SignPrime {
    type Output = i64;

    fn mul(self, _rhs: SignPrime) -> Self::Output {
        1 // (-1) * (-1) = 1
    }
}

/// Sign Prime parity operations for factorization state spaces
impl SignPrime {
    /// Apply sign prime to create sign parity in factorizations
    /// 
    /// This is fundamental to PPF where negative integers have factorizations
    /// involving an odd number of negative factors or the explicit Sign Prime
    /// 
    /// # Arguments
    /// * `factors` - Vector of prime factors
    /// 
    /// # Returns
    /// * Modified factors with sign prime applied
    pub fn apply_to_factorization(&self, factors: &[i64]) -> Vec<i64> {
        let mut result = vec![SIGN_PRIME];
        result.extend_from_slice(factors);
        result
    }

    /// Remove sign prime from factorization by absorbing into magnitude primes
    /// 
    /// This converts explicit Sign Prime representation to implicit negative factors
    /// 
    /// # Arguments
    /// * `factors` - Vector of factors including potential Sign Prime
    /// 
    /// # Returns
    /// * Factors with Sign Prime absorbed into magnitude primes
    pub fn absorb_from_factorization(&self, factors: &[i64]) -> Vec<i64> {
        let mut result = Vec::new();
        let mut has_sign_prime = false;
        
        for &factor in factors {
            if factor == SIGN_PRIME {
                has_sign_prime = true;
            } else {
                result.push(factor);
            }
        }
        
        if has_sign_prime && !result.is_empty() {
            // Absorb sign prime into the first magnitude prime
            result[0] = -result[0];
        }
        
        result
    }

    /// Count the number of Sign Primes in a factorization
    /// 
    /// # Arguments
    /// * `factors` - Vector of factors
    /// 
    /// # Returns
    /// * Number of Sign Prime occurrences
    pub fn count_in_factorization(&self, factors: &[i64]) -> usize {
        factors.iter().filter(|&&f| f == SIGN_PRIME).count()
    }
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_sign_prime_creation() {
        let sp = SignPrime::new();
        assert_eq!(sp.value(), -1);
        assert!(sp.is_sign_prime());
    }

    #[test]
    fn test_sign_prime_power() {
        let sp = SignPrime::new();
        assert_eq!(sp.power(0).unwrap(), 1);
        assert_eq!(sp.power(1).unwrap(), -1);
        assert_eq!(sp.power(2).unwrap(), 1);
        assert_eq!(sp.power(3).unwrap(), -1);
        assert_eq!(sp.power(100).unwrap(), 1);
        assert_eq!(sp.power(101).unwrap(), -1);
    }

    #[test]
    fn test_sign_prime_multiplication() {
        let sp = SignPrime::new();
        assert_eq!(sp.multiply(5), -5);
        assert_eq!(sp.multiply(-3), 3);
        assert_eq!(sp.multiply(0), 0);
    }

    #[test]
    fn test_sign_prime_division() {
        let sp = SignPrime::new();
        assert_eq!(sp.divide(6).unwrap(), -6);
        assert_eq!(sp.divide(-8).unwrap(), 8);
        assert!(sp.divide(0).is_err());
    }

    #[test]
    fn test_sign_prime_divisibility() {
        let sp = SignPrime::new();
        assert!(sp.divides(42));
        assert!(sp.divides(-17));
        assert!(!sp.divides(0));
    }

    #[test]
    fn test_is_sign_prime() {
        assert!(is_sign_prime(-1));
        assert!(!is_sign_prime(1));
        assert!(!is_sign_prime(-2));
        assert!(!is_sign_prime(0));
    }

    #[test]
    fn test_sign_prime_operators() {
        let sp = SignPrime::new();
        assert_eq!(sp * 5, -5);
        assert_eq!(5 * sp, -5);
        assert_eq!(sp * sp, 1);
    }

    #[test]
    fn test_factorization_operations() {
        let sp = SignPrime::new();
        
        // Test applying sign prime to factorization
        let factors = vec![2, 3, 5];
        let with_sign = sp.apply_to_factorization(&factors);
        assert_eq!(with_sign, vec![-1, 2, 3, 5]);
        
        // Test absorbing sign prime from factorization
        let factors_with_sign = vec![-1, 2, 3, 5];
        let absorbed = sp.absorb_from_factorization(&factors_with_sign);
        assert_eq!(absorbed, vec![-2, 3, 5]);
        
        // Test counting sign primes
        assert_eq!(sp.count_in_factorization(&vec![-1, 2, -1, 3]), 2);
        assert_eq!(sp.count_in_factorization(&vec![2, 3, 5]), 0);
    }

    #[test]
    fn test_bigint_operations() {
        let sp = SignPrime::new();
        let big_num = BigInt::from(12345);
        let result = sp.multiply_bigint(&big_num);
        assert_eq!(result, BigInt::from(-12345));
        
        assert!(is_sign_prime_bigint(&BigInt::from(-1)));
        assert!(!is_sign_prime_bigint(&BigInt::from(1)));
    }

    #[test]
    fn test_display() {
        let sp = SignPrime::new();
        assert_eq!(format!("{}", sp), "-1");
    }
}