use num_traits::Pow;
use transfinite::{CnfTerm, Ordinal, OrdinalError};
#[test]
fn test_cnf_term_zero_multiplicity_error() {
let result = CnfTerm::new(&Ordinal::one(), 0);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
OrdinalError::CnfTermConstructionError
));
}
#[test]
fn test_cnf_term_max_multiplicity() {
let result = CnfTerm::new(&Ordinal::one(), u32::MAX);
assert!(result.is_ok());
let term = result.unwrap();
assert_eq!(term.multiplicity(), u32::MAX);
}
#[test]
fn test_transfinite_empty_terms_error() {
let result = Ordinal::new_transfinite(&[]);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
OrdinalError::TransfiniteConstructionError
));
}
#[test]
fn test_transfinite_unsorted_terms_error() {
let term1 = CnfTerm::new(&Ordinal::new_finite(1), 1).unwrap();
let term2 = CnfTerm::new(&Ordinal::new_finite(2), 1).unwrap();
let result = Ordinal::new_transfinite(&[term1, term2]);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
OrdinalError::TransfiniteConstructionError
));
}
#[test]
fn test_transfinite_equal_exponents_error() {
let term1 = CnfTerm::new(&Ordinal::new_finite(2), 1).unwrap();
let term2 = CnfTerm::new(&Ordinal::new_finite(2), 2).unwrap();
let result = Ordinal::new_transfinite(&[term1, term2]);
assert!(result.is_err());
assert!(matches!(
result.unwrap_err(),
OrdinalError::TransfiniteConstructionError
));
}
#[test]
fn test_transfinite_finite_leading_term_error() {
let finite_term = CnfTerm::new_finite(5);
let omega_term = CnfTerm::new(&Ordinal::one(), 1).unwrap();
let result = Ordinal::new_transfinite(&[finite_term, omega_term]);
assert!(result.is_err());
}
#[test]
fn test_addition_with_zero() {
let zero = Ordinal::zero();
let five = Ordinal::new_finite(5);
let omega = Ordinal::omega();
assert_eq!(zero.clone() + five.clone(), five);
assert_eq!(zero.clone() + omega.clone(), omega);
assert_eq!(five.clone() + zero.clone(), five);
assert_eq!(omega.clone() + zero, omega);
}
#[test]
fn test_multiplication_with_zero() {
let zero = Ordinal::zero();
let five = Ordinal::new_finite(5);
let omega = Ordinal::omega();
assert_eq!(zero.clone() * five.clone(), zero);
assert_eq!(zero.clone() * omega.clone(), zero);
assert_eq!(five * zero.clone(), zero);
assert_eq!(omega * zero.clone(), zero);
}
#[test]
fn test_multiplication_with_one() {
let one = Ordinal::one();
let five = Ordinal::new_finite(5);
let omega = Ordinal::omega();
assert_eq!(one.clone() * five.clone(), five);
assert_eq!(one.clone() * omega.clone(), omega);
assert_eq!(five.clone() * one.clone(), five);
assert_eq!(omega.clone() * one, omega);
}
#[test]
fn test_exponentiation_zero_base() {
let zero = Ordinal::zero();
let one = Ordinal::one();
let five = Ordinal::new_finite(5);
let omega = Ordinal::omega();
assert_eq!(zero.clone().pow(zero.clone()), one);
assert_eq!(zero.clone().pow(one), zero);
assert_eq!(zero.clone().pow(five), zero);
assert_eq!(zero.clone().pow(omega), zero);
}
#[test]
fn test_exponentiation_zero_exponent() {
let zero = Ordinal::zero();
let one = Ordinal::one();
let five = Ordinal::new_finite(5);
let omega = Ordinal::omega();
assert_eq!(zero.clone().pow(zero.clone()), one);
assert_eq!(one.clone().pow(zero.clone()), one);
assert_eq!(five.pow(zero.clone()), one);
assert_eq!(omega.pow(zero), one);
}
#[test]
fn test_exponentiation_one_base() {
let one = Ordinal::one();
let zero = Ordinal::zero();
let five = Ordinal::new_finite(5);
let omega = Ordinal::omega();
assert_eq!(one.clone().pow(zero), one);
assert_eq!(one.clone().pow(one.clone()), one);
assert_eq!(one.clone().pow(five), one);
assert_eq!(one.clone().pow(omega), one);
}
#[test]
fn test_exponentiation_one_exponent() {
let one = Ordinal::one();
let zero = Ordinal::zero();
let five = Ordinal::new_finite(5);
let omega = Ordinal::omega();
assert_eq!(zero.clone().pow(one.clone()), zero);
assert_eq!(one.clone().pow(one.clone()), one);
assert_eq!(five.clone().pow(one.clone()), five);
assert_eq!(omega.clone().pow(one), omega);
}
#[test]
fn test_large_finite_addition() {
let max_half = Ordinal::new_finite(u32::MAX / 2);
let result = max_half.clone() + max_half;
assert!(result.is_finite());
}
#[test]
fn test_large_finite_multiplication() {
let large = Ordinal::new_finite(u32::MAX / 2);
let two = Ordinal::new_finite(2);
let result = large * two;
assert!(result.is_finite());
}
#[test]
fn test_very_large_exponentiation() {
let base = Ordinal::new_finite(2);
let exp = Ordinal::new_finite(20);
let result = base.pow(exp);
assert_eq!(result, Ordinal::new_finite(1048576));
}
#[test]
fn test_self_equality() {
let zero = Ordinal::zero();
let omega = Ordinal::omega();
let complex = Ordinal::new_transfinite(&[
CnfTerm::new(&Ordinal::new_finite(2), 1).unwrap(),
CnfTerm::new(&Ordinal::one(), 3).unwrap(),
])
.unwrap();
assert_eq!(zero, zero);
assert_eq!(omega, omega);
assert_eq!(complex, complex);
}
#[test]
fn test_transitivity() {
let one = Ordinal::one();
let five = Ordinal::new_finite(5);
let ten = Ordinal::new_finite(10);
assert!(one < five);
assert!(five < ten);
assert!(one < ten);
}
#[test]
fn test_antisymmetry() {
let five = Ordinal::new_finite(5);
let ten = Ordinal::new_finite(10);
assert!(five < ten);
assert!((ten >= five));
}
#[test]
fn test_zero_is_limit() {
assert!(Ordinal::zero().is_limit());
assert!(!Ordinal::zero().is_successor());
}
#[test]
fn test_successor_of_limit() {
let omega = Ordinal::omega();
let omega_plus_one = omega.successor();
assert!(omega.is_limit());
assert!(omega_plus_one.is_successor());
}
#[test]
fn test_repeated_successor() {
let mut ord = Ordinal::zero();
for _ in 0..10 {
let next = ord.successor();
assert!(next > ord);
ord = next;
}
}
#[test]
fn test_reference_arithmetic() {
let five = Ordinal::new_finite(5);
let three = Ordinal::new_finite(3);
assert_eq!(&five + &three, Ordinal::new_finite(8));
assert_eq!(five.clone() + &three, Ordinal::new_finite(8));
assert_eq!(&five + three.clone(), Ordinal::new_finite(8));
assert_eq!(five + three, Ordinal::new_finite(8));
}
#[test]
fn test_reference_multiplication() {
let five = Ordinal::new_finite(5);
let three = Ordinal::new_finite(3);
assert_eq!(&five * &three, Ordinal::new_finite(15));
assert_eq!(five.clone() * &three, Ordinal::new_finite(15));
assert_eq!(&five * three.clone(), Ordinal::new_finite(15));
assert_eq!(five * three, Ordinal::new_finite(15));
}
#[test]
fn test_reference_exponentiation() {
let two = Ordinal::new_finite(2);
let three = Ordinal::new_finite(3);
assert_eq!((&two).pow(&three), Ordinal::new_finite(8));
assert_eq!(two.clone().pow(&three), Ordinal::new_finite(8));
assert_eq!((&two).pow(three.clone()), Ordinal::new_finite(8));
assert_eq!(two.pow(three), Ordinal::new_finite(8));
}