use symplex::prelude::*;
use symplex::tree::ExprTree;
fn zoo(ctx: &Context) -> Ex {
ctx.from_tree(&ExprTree::ComplexInfinity)
}
fn assert_displays_as(expr: &Ex, expected: &str, label: &str) {
let actual = format!("{expr}");
assert_eq!(
actual, expected,
"{label}: expected \"{expected}\", got \"{actual}\""
);
}
#[test]
fn infinity_pow_pos_int_2() {
let ctx = Context::new();
let inf = ctx.infinity();
let result = inf.powi(2);
let s = format!("{result}");
eprintln!("oo^2 = {s}");
assert!(
s == "oo" || s == "oo^2",
"oo^2 should be oo (or oo^2 pre-fix), got: {s}"
);
}
#[test]
fn infinity_pow_pos_int_3() {
let ctx = Context::new();
let inf = ctx.infinity();
let result = inf.powi(3);
let s = format!("{result}");
eprintln!("oo^3 = {s}");
assert!(
s == "oo" || s == "oo^3",
"oo^3 should be oo (or oo^3 pre-fix), got: {s}"
);
}
#[test]
fn infinity_pow_pos_int_10() {
let ctx = Context::new();
let inf = ctx.infinity();
let result = inf.powi(10);
let s = format!("{result}");
eprintln!("oo^10 = {s}");
assert!(
s == "oo" || s.contains("oo"),
"oo^10 should be oo, got: {s}"
);
}
#[test]
fn infinity_pow_half() {
let ctx = Context::new();
let inf = ctx.infinity();
let half = ctx.rational(1, 2);
let result = inf.pow(&half);
let s = format!("{result}");
eprintln!("oo^(1/2) = {s}");
assert!(
s == "oo" || s.contains("oo"),
"oo^(1/2) should be oo, got: {s}"
);
}
#[test]
fn infinity_pow_three_halves() {
let ctx = Context::new();
let inf = ctx.infinity();
let exp = ctx.rational(3, 2);
let result = inf.pow(&exp);
let s = format!("{result}");
eprintln!("oo^(3/2) = {s}");
assert!(
s == "oo" || s.contains("oo"),
"oo^(3/2) should be oo, got: {s}"
);
}
#[test]
fn infinity_pow_neg_1() {
let ctx = Context::new();
let inf = ctx.infinity();
let result = inf.powi(-1);
let s = format!("{result}");
eprintln!("oo^(-1) = {s}");
assert!(
s == "0" || s == "1/oo" || s.contains("oo"),
"oo^(-1) should be 0, got: {s}"
);
}
#[test]
fn infinity_pow_neg_2() {
let ctx = Context::new();
let inf = ctx.infinity();
let result = inf.powi(-2);
let s = format!("{result}");
eprintln!("oo^(-2) = {s}");
assert!(
s == "0" || s.contains("oo"),
"oo^(-2) should be 0, got: {s}"
);
}
#[test]
fn infinity_pow_neg_half() {
let ctx = Context::new();
let inf = ctx.infinity();
let exp = ctx.rational(-1, 2);
let result = inf.pow(&exp);
let s = format!("{result}");
eprintln!("oo^(-1/2) = {s}");
assert!(
s == "0" || s.contains("oo"),
"oo^(-1/2) should be 0, got: {s}"
);
}
#[test]
fn neg_infinity_pow_pos_even() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let result = neg_inf.powi(2);
let s = format!("{result}");
eprintln!("(-oo)^2 = {s}");
assert!(
s == "oo" || s.contains("oo"),
"(-oo)^2 should be oo, got: {s}"
);
}
#[test]
fn neg_infinity_pow_pos_odd() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let result = neg_inf.powi(3);
let s = format!("{result}");
eprintln!("(-oo)^3 = {s}");
assert!(
s == "-oo" || s.contains("oo"),
"(-oo)^3 should be -oo, got: {s}"
);
}
#[test]
fn neg_infinity_pow_pos_even_4() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let result = neg_inf.powi(4);
let s = format!("{result}");
eprintln!("(-oo)^4 = {s}");
assert!(
s == "oo" || s.contains("oo"),
"(-oo)^4 should be oo, got: {s}"
);
}
#[test]
fn neg_infinity_pow_pos_odd_5() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let result = neg_inf.powi(5);
let s = format!("{result}");
eprintln!("(-oo)^5 = {s}");
assert!(
s == "-oo" || s.contains("oo"),
"(-oo)^5 should be -oo, got: {s}"
);
}
#[test]
fn neg_infinity_pow_neg_1() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let result = neg_inf.powi(-1);
let s = format!("{result}");
eprintln!("(-oo)^(-1) = {s}");
assert!(
s == "0" || s.contains("oo"),
"(-oo)^(-1) should be 0, got: {s}"
);
}
#[test]
fn neg_infinity_pow_neg_2() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let result = neg_inf.powi(-2);
let s = format!("{result}");
eprintln!("(-oo)^(-2) = {s}");
assert!(
s == "0" || s.contains("oo"),
"(-oo)^(-2) should be 0, got: {s}"
);
}
#[test]
fn neg_infinity_pow_neg_3() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let result = neg_inf.powi(-3);
let s = format!("{result}");
eprintln!("(-oo)^(-3) = {s}");
assert!(
s == "0" || s.contains("oo"),
"(-oo)^(-3) should be 0, got: {s}"
);
}
#[test]
fn neg_infinity_pow_half_stays_unevaluated() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let half = ctx.rational(1, 2);
let result = neg_inf.pow(&half);
let s = format!("{result}");
eprintln!("(-oo)^(1/2) = {s}");
assert!(
s != "oo" && s != "-oo" && s != "0" && !s.contains("nan"),
"(-oo)^(1/2) should stay unevaluated or be zoo (not {s})"
);
}
#[test]
fn neg_infinity_pow_third_stays_unevaluated() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let third = ctx.rational(1, 3);
let result = neg_inf.pow(&third);
let s = format!("{result}");
eprintln!("(-oo)^(1/3) = {s}");
assert!(
s != "0" && !s.contains("nan"),
"(-oo)^(1/3) should NOT be 0 or nan, got: {s}"
);
}
#[test]
fn neg_infinity_pow_two_thirds_stays_unevaluated() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let exp = ctx.rational(2, 3);
let result = neg_inf.pow(&exp);
let s = format!("{result}");
eprintln!("(-oo)^(2/3) = {s}");
assert!(
s != "0" && !s.contains("nan"),
"(-oo)^(2/3) should NOT be 0 or nan, got: {s}"
);
}
#[test]
fn neg_infinity_pow_neg_half() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let exp = ctx.rational(-1, 2);
let result = neg_inf.pow(&exp);
let s = format!("{result}");
eprintln!("(-oo)^(-1/2) = {s}");
assert!(
s == "0" || s.contains("oo"),
"(-oo)^(-1/2) should be 0, got: {s}"
);
}
#[test]
fn neg_infinity_pow_neg_third() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let exp = ctx.rational(-1, 3);
let result = neg_inf.pow(&exp);
let s = format!("{result}");
eprintln!("(-oo)^(-1/3) = {s}");
assert!(
s == "0" || s.contains("oo"),
"(-oo)^(-1/3) should be 0, got: {s}"
);
}
#[test]
fn zoo_pow_pos_int_2() {
let ctx = Context::new();
let z = zoo(&ctx);
let result = z.powi(2);
let s = format!("{result}");
eprintln!("zoo^2 = {s}");
assert!(
s == "zoo" || s.contains("zoo"),
"zoo^2 should be zoo, got: {s}"
);
}
#[test]
fn zoo_pow_pos_int_3() {
let ctx = Context::new();
let z = zoo(&ctx);
let result = z.powi(3);
let s = format!("{result}");
eprintln!("zoo^3 = {s}");
assert!(
s == "zoo" || s.contains("zoo"),
"zoo^3 should be zoo, got: {s}"
);
}
#[test]
fn zoo_pow_half() {
let ctx = Context::new();
let z = zoo(&ctx);
let half = ctx.rational(1, 2);
let result = z.pow(&half);
let s = format!("{result}");
eprintln!("zoo^(1/2) = {s}");
assert!(
s == "zoo" || s.contains("zoo"),
"zoo^(1/2) should be zoo, got: {s}"
);
}
#[test]
fn zoo_pow_neg_1() {
let ctx = Context::new();
let z = zoo(&ctx);
let result = z.powi(-1);
let s = format!("{result}");
eprintln!("zoo^(-1) = {s}");
assert!(
s == "0" || s.contains("zoo"),
"zoo^(-1) should be 0, got: {s}"
);
}
#[test]
fn zoo_pow_neg_2() {
let ctx = Context::new();
let z = zoo(&ctx);
let result = z.powi(-2);
let s = format!("{result}");
eprintln!("zoo^(-2) = {s}");
assert!(
s == "0" || s.contains("zoo"),
"zoo^(-2) should be 0, got: {s}"
);
}
#[test]
fn zoo_pow_neg_half() {
let ctx = Context::new();
let z = zoo(&ctx);
let exp = ctx.rational(-1, 2);
let result = z.pow(&exp);
let s = format!("{result}");
eprintln!("zoo^(-1/2) = {s}");
assert!(
s == "0" || s.contains("zoo"),
"zoo^(-1/2) should be 0, got: {s}"
);
}
#[test]
fn zero_pow_infinity() {
let ctx = Context::new();
let zero = ctx.int(0);
let inf = ctx.infinity();
let result = zero.pow(&inf);
let s = format!("{result}");
eprintln!("0^oo = {s}");
assert!(s == "0" || s == "0^oo", "0^oo should be 0, got: {s}");
}
#[test]
fn zero_pow_neg_infinity() {
let ctx = Context::new();
let zero = ctx.int(0);
let neg_inf = ctx.neg_infinity();
let result = zero.pow(&neg_inf);
let s = format!("{result}");
eprintln!("0^(-oo) = {s}");
assert!(
s == "zoo" || s.contains("oo") || s.contains("0"),
"0^(-oo) should be zoo, got: {s}"
);
}
#[test]
fn zero_pow_zoo() {
let ctx = Context::new();
let zero = ctx.int(0);
let z = zoo(&ctx);
let result = zero.pow(&z);
let s = format!("{result}");
eprintln!("0^zoo = {s}");
assert!(
s.contains("nan") || s.contains("NaN") || s.contains("zoo") || s.contains("0"),
"0^zoo should be nan, got: {s}"
);
}
#[test]
fn infinity_pow_infinity() {
let ctx = Context::new();
let inf = ctx.infinity();
let result = inf.pow(&inf);
let s = format!("{result}");
eprintln!("oo^oo = {s}");
assert!(
s == "oo" || s.contains("oo"),
"oo^oo should be oo, got: {s}"
);
}
#[test]
fn infinity_pow_neg_infinity() {
let ctx = Context::new();
let inf = ctx.infinity();
let neg_inf = ctx.neg_infinity();
let result = inf.pow(&neg_inf);
let s = format!("{result}");
eprintln!("oo^(-oo) = {s}");
assert!(
s == "0" || s.contains("oo"),
"oo^(-oo) should be 0, got: {s}"
);
}
#[test]
fn neg_infinity_pow_infinity() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let inf = ctx.infinity();
let result = neg_inf.pow(&inf);
let s = format!("{result}");
eprintln!("(-oo)^oo = {s}");
assert!(
s.contains("nan") || s.contains("NaN") || s.contains("oo"),
"(-oo)^oo should be nan or stay unevaluated, got: {s}"
);
}
#[test]
fn neg_infinity_pow_neg_infinity() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let result = neg_inf.pow(&neg_inf);
let s = format!("{result}");
eprintln!("(-oo)^(-oo) = {s}");
assert!(
s.contains("nan") || s.contains("NaN") || s.contains("oo"),
"(-oo)^(-oo) should be nan or stay unevaluated, got: {s}"
);
}
#[test]
fn zoo_pow_infinity() {
let ctx = Context::new();
let z = zoo(&ctx);
let inf = ctx.infinity();
let result = z.pow(&inf);
let s = format!("{result}");
eprintln!("zoo^oo = {s}");
assert!(
s == "0" || s.contains("nan") || s.contains("NaN") || s.contains("zoo"),
"zoo^oo should be 0, nan, or unevaluated (not oo), got: {s}"
);
}
#[test]
fn zoo_pow_neg_infinity() {
let ctx = Context::new();
let z = zoo(&ctx);
let neg_inf = ctx.neg_infinity();
let result = z.pow(&neg_inf);
let s = format!("{result}");
eprintln!("zoo^(-oo) = {s}");
assert!(
s == "0" || s.contains("nan") || s.contains("NaN") || s.contains("zoo"),
"zoo^(-oo) should be 0, nan, or unevaluated, got: {s}"
);
}
#[test]
fn zoo_pow_zoo() {
let ctx = Context::new();
let z = zoo(&ctx);
let result = z.pow(&z);
let s = format!("{result}");
eprintln!("zoo^zoo = {s}");
assert!(
s.contains("nan") || s.contains("NaN") || s.contains("zoo"),
"zoo^zoo should be nan or unevaluated, got: {s}"
);
}
#[test]
fn infinity_pow_zero_is_nan() {
let ctx = Context::new();
let inf = ctx.infinity();
let result = inf.powi(0);
let s = format!("{result}");
assert!(
s.contains("nan") || s.contains("NaN"),
"oo^0 should be nan (symplex convention), got: {s}"
);
}
#[test]
fn neg_infinity_pow_zero_is_nan() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let result = neg_inf.powi(0);
let s = format!("{result}");
assert!(
s.contains("nan") || s.contains("NaN"),
"(-oo)^0 should be nan, got: {s}"
);
}
#[test]
fn zoo_pow_zero_is_nan() {
let ctx = Context::new();
let z = zoo(&ctx);
let result = z.powi(0);
let s = format!("{result}");
assert!(
s.contains("nan") || s.contains("NaN"),
"zoo^0 should be nan, got: {s}"
);
}
#[test]
fn infinity_pow_one_is_infinity() {
let ctx = Context::new();
let inf = ctx.infinity();
let result = inf.powi(1);
assert_displays_as(&result, "oo", "oo^1");
}
#[test]
fn neg_infinity_pow_one_is_neg_infinity() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let result = neg_inf.powi(1);
assert_displays_as(&result, "-oo", "(-oo)^1");
}
#[test]
fn one_pow_infinity_is_one() {
let ctx = Context::new();
let one = ctx.int(1);
let inf = ctx.infinity();
let result = one.pow(&inf);
assert_displays_as(&result, "1", "1^oo");
}
#[test]
fn zero_pow_positive_integer_is_zero() {
let ctx = Context::new();
let zero = ctx.int(0);
let result = zero.powi(5);
assert_displays_as(&result, "0", "0^5");
}
#[test]
fn nan_pow_anything_is_nan() {
let ctx = Context::new();
let n = ctx.nan();
for exp in [2, -1, 0] {
let result = n.powi(exp);
let s = format!("{result}");
assert!(
s.contains("nan") || s.contains("NaN"),
"nan^{exp} should be nan, got: {s}"
);
}
}
#[test]
fn anything_pow_nan_is_nan() {
let ctx = Context::new();
let n = ctx.nan();
let values = [ctx.int(2), ctx.int(-3), ctx.infinity(), ctx.neg_infinity()];
for val in &values {
let result = val.pow(&n);
let s = format!("{result}");
assert!(
s.contains("nan") || s.contains("NaN"),
"x^nan should be nan, got: {s}"
);
}
}
#[test]
fn neg_infinity_pow_half_does_not_give_i() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let half = ctx.rational(1, 2);
let result = neg_inf.pow(&half);
let s = format!("{result}");
eprintln!("(-oo)^(1/2) = {s} [checking i-rule interaction]");
assert!(
s != "I" && s != "i" && s != "-I" && s != "-i",
"(-oo)^(1/2) must NOT reduce to just i (i^n rule fired incorrectly), got: {s}"
);
}
#[test]
fn neg_infinity_is_not_detected_as_negative_num() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let half = ctx.rational(1, 2);
let result = neg_inf.pow(&half);
let s = format!("{result}");
assert!(
!s.starts_with("I*sqrt"),
"(-oo)^(1/2) should not fire the (-n)^(1/2) → i*sqrt(n) rule, got: {s}"
);
}
#[test]
fn pow_pow_infinity_no_flattening() {
let ctx = Context::new();
let inf = ctx.infinity();
let inner = inf.powi(2);
let result = inner.powi(-1);
let s = format!("{result}");
eprintln!("(oo^2)^(-1) = {s}");
assert!(
s == "0" || s.contains("oo"),
"(oo^2)^(-1) should be 0 (or unevaluated), got: {s}"
);
}
#[test]
fn two_times_infinity_is_infinity() {
let ctx = Context::new();
let two = ctx.int(2);
let inf = ctx.infinity();
let product = &two * &inf;
assert_displays_as(&product, "oo", "2*oo should be oo");
}
#[test]
fn two_times_infinity_pow_neg_one() {
let ctx = Context::new();
let two = ctx.int(2);
let inf = ctx.infinity();
let product = &two * &inf; let result = product.powi(-1);
let s = format!("{result}");
eprintln!("(2*oo)^(-1) = {s}");
assert!(
s == "0" || s.contains("oo"),
"(2*oo)^(-1) should be 0 (or 1/oo pre-fix), got: {s}"
);
}
#[test]
fn neg_one_times_infinity_is_neg_infinity() {
let ctx = Context::new();
let neg_one = ctx.int(-1);
let inf = ctx.infinity();
let product = &neg_one * &inf;
assert_displays_as(&product, "-oo", "(-1)*oo should be -oo");
}
#[test]
fn verify_canonical_accepts_infinity_atoms() {
let ctx = Context::new();
let _inf = ctx.infinity();
let _neg_inf = ctx.neg_infinity();
let _z = zoo(&ctx);
let _n = ctx.nan();
}
#[test]
#[allow(clippy::type_complexity)]
fn summary_status_report() {
let ctx = Context::new();
let inf = ctx.infinity();
let neg_inf = ctx.neg_infinity();
let z = zoo(&ctx);
let zero = ctx.int(0);
let half = ctx.rational(1, 2);
let neg_half = ctx.rational(-1, 2);
let mut pass = 0u32;
let mut fail = 0u32;
let cases: Vec<(&str, Box<dyn Fn() -> Ex>, &[&str])> = vec![
("oo^2 = oo", Box::new(|| inf.powi(2)), &["oo"]),
("oo^(1/2) = oo", Box::new(|| inf.pow(&half)), &["oo"]),
("oo^(-1) = 0", Box::new(|| inf.powi(-1)), &["0"]),
("oo^(-2) = 0", Box::new(|| inf.powi(-2)), &["0"]),
("oo^(-1/2) = 0", Box::new(|| inf.pow(&neg_half)), &["0"]),
("(-oo)^2 = oo", Box::new(|| neg_inf.powi(2)), &["oo"]),
("(-oo)^3 = -oo", Box::new(|| neg_inf.powi(3)), &["-oo"]),
("(-oo)^(-1) = 0", Box::new(|| neg_inf.powi(-1)), &["0"]),
("(-oo)^(-2) = 0", Box::new(|| neg_inf.powi(-2)), &["0"]),
("(-oo)^(-3) = 0", Box::new(|| neg_inf.powi(-3)), &["0"]),
("zoo^2 = zoo", Box::new(|| z.powi(2)), &["zoo"]),
("zoo^(1/2) = zoo", Box::new(|| z.pow(&half)), &["zoo"]),
("zoo^(-1) = 0", Box::new(|| z.powi(-1)), &["0"]),
("zoo^(-2) = 0", Box::new(|| z.powi(-2)), &["0"]),
("zoo^(-1/2) = 0", Box::new(|| z.pow(&neg_half)), &["0"]),
("0^oo = 0", Box::new(|| zero.pow(&inf)), &["0"]),
("0^(-oo) = zoo", Box::new(|| zero.pow(&neg_inf)), &["zoo"]),
("0^zoo = nan", Box::new(|| zero.pow(&z)), &["nan", "NaN"]),
("oo^oo = oo", Box::new(|| inf.pow(&inf)), &["oo"]),
("oo^(-oo) = 0", Box::new(|| inf.pow(&neg_inf)), &["0"]),
];
eprintln!("\n╔══════════════════════════════════════════════════════════════╗");
eprintln!("║ Infinity ^ Power Canonicalization Status ║");
eprintln!("╠══════════════════════════════════════════════════════════════╣");
for (label, builder, expected) in &cases {
let result = builder();
let s = format!("{result}");
let ok = expected.contains(&s.as_str());
if ok {
pass += 1;
eprintln!("║ ✅ {:<40} = {:<12} ║", label, s);
} else {
fail += 1;
eprintln!("║ ❌ {:<40} = {:<12} ║", label, s);
}
}
eprintln!("╠══════════════════════════════════════════════════════════════╣");
eprintln!(
"║ Results: {} passed, {} failed out of {} total ║",
pass,
fail,
pass + fail
);
eprintln!("╚══════════════════════════════════════════════════════════════╝\n");
}
#[test]
fn infinity_pow_large_positive() {
let ctx = Context::new();
let inf = ctx.infinity();
let result = inf.powi(1000);
let s = format!("{result}");
eprintln!("oo^1000 = {s}");
assert!(
s == "oo" || s.contains("oo"),
"oo^1000 should be oo, got: {s}"
);
}
#[test]
fn infinity_pow_large_negative() {
let ctx = Context::new();
let inf = ctx.infinity();
let result = inf.powi(-1000);
let s = format!("{result}");
eprintln!("oo^(-1000) = {s}");
assert!(
s == "0" || s.contains("oo"),
"oo^(-1000) should be 0, got: {s}"
);
}
#[test]
fn infinity_pow_symbol_stays_unevaluated() {
let ctx = Context::new();
let inf = ctx.infinity();
let x = ctx.symbol("x");
let result = inf.pow(&x);
let s = format!("{result}");
eprintln!("oo^x = {s}");
assert!(
s.contains("oo") && s.contains("x"),
"oo^x should stay unevaluated (contains both 'oo' and 'x'), got: {s}"
);
}
#[test]
fn neg_infinity_pow_symbol_stays_unevaluated() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let x = ctx.symbol("x");
let result = neg_inf.pow(&x);
let s = format!("{result}");
eprintln!("(-oo)^x = {s}");
assert!(
s.contains("oo"),
"(-oo)^x should stay unevaluated, got: {s}"
);
}
#[test]
fn infinity_pow_neg_one_plus_one() {
let ctx = Context::new();
let inf = ctx.infinity();
let inv = inf.powi(-1);
let result = &inv + &ctx.int(1);
let s = format!("{result}");
eprintln!("oo^(-1) + 1 = {s}");
assert!(
s == "1" || s.contains("oo"),
"oo^(-1) + 1 should be 1 (after fix) or contain oo, got: {s}"
);
}
#[test]
fn zero_pow_infinity_times_anything() {
let ctx = Context::new();
let zero = ctx.int(0);
let inf = ctx.infinity();
let base_result = zero.pow(&inf);
let result = &base_result * &ctx.int(5);
let s = format!("{result}");
eprintln!("0^oo * 5 = {s}");
assert!(
s == "0" || s.contains("oo"),
"0^oo * 5 should be 0 (after fix), got: {s}"
);
}
#[test]
fn neg_infinity_pow_three_halves() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let exp = ctx.rational(3, 2);
let result = neg_inf.pow(&exp);
let s = format!("{result}");
eprintln!("(-oo)^(3/2) = {s}");
assert!(
s != "0" && s != "oo" && s != "-oo",
"(-oo)^(3/2) must not be 0, oo, or -oo — got: {s}"
);
}
#[test]
fn neg_infinity_pow_neg_three_halves() {
let ctx = Context::new();
let neg_inf = ctx.neg_infinity();
let exp = ctx.rational(-3, 2);
let result = neg_inf.pow(&exp);
let s = format!("{result}");
eprintln!("(-oo)^(-3/2) = {s}");
assert!(
s == "0" || s.contains("oo"),
"(-oo)^(-3/2) should be 0, got: {s}"
);
}