use super::*;
use crate::tests::common::{make_formula, rat};
use num_bigint::BigUint;
use num_rational::BigRational;
#[test]
fn mc_empty_formula_is_2_pow_n() {
let f = make_formula(3, vec![]);
assert_eq!(brute_force_mc(&f), BigUint::from(8u32));
}
#[test]
fn mc_single_unit() {
let f = make_formula(1, vec![vec![1]]);
assert_eq!(brute_force_mc(&f), BigUint::from(1u32));
}
#[test]
fn pmc_full_show_equals_mc() {
let f = make_formula(3, vec![vec![1, -2], vec![3]]);
let mc = brute_force_mc(&f);
let pmc = brute_force_pmc(&f, &[0, 1, 2]);
assert_eq!(pmc, mc);
}
#[test]
fn pmc_xor_diverges_from_pow2_division() {
let xor = make_formula(2, vec![vec![1, 2], vec![-1, -2]]);
let mc = brute_force_mc(&xor);
assert_eq!(mc, BigUint::from(2u32));
let pmc = brute_force_pmc(&xor, &[0]);
assert_eq!(pmc, BigUint::from(2u32)); assert_ne!(pmc, &mc / BigUint::from(2u32));
}
#[test]
fn pmc_free_var_matches_pow2_division() {
let f = make_formula(2, vec![vec![1]]);
let mc = brute_force_mc(&f); assert_eq!(mc, BigUint::from(2u32));
let pmc = brute_force_pmc(&f, &[0]); assert_eq!(pmc, BigUint::from(1u32));
assert_eq!(pmc, &mc / BigUint::from(2u32)); }
#[test]
fn pmc_three_var_handchecked() {
let f = make_formula(3, vec![vec![1, 2], vec![3]]);
assert_eq!(brute_force_pmc(&f, &[0, 1]), BigUint::from(3u32));
assert_eq!(brute_force_pmc(&f, &[0]), BigUint::from(2u32));
}
#[test]
fn pmc_forced_gate_projected_var_settles_late() {
let f = make_formula(3, vec![vec![1, 2], vec![1, 3]]);
assert_eq!(brute_force_mc(&f), BigUint::from(5u32));
assert_eq!(brute_force_pmc(&f, &[0]), BigUint::from(2u32));
assert_eq!(brute_force_pmc(&f, &[0, 1]), BigUint::from(3u32));
}
#[test]
fn pmc_two_disjoint_components_multiply() {
let joint = make_formula(4, vec![vec![1, 2], vec![3, 4]]);
let pmc_joint = brute_force_pmc(&joint, &[0, 1, 2]);
assert_eq!(pmc_joint, BigUint::from(6u32));
let comp_a = make_formula(2, vec![vec![1, 2]]);
let pmc_a = brute_force_pmc(&comp_a, &[0, 1]); let comp_b = make_formula(2, vec![vec![1, 2]]);
let pmc_b = brute_force_pmc(&comp_b, &[0]); assert_eq!(pmc_a, BigUint::from(3u32));
assert_eq!(pmc_b, BigUint::from(2u32));
assert_eq!(pmc_joint, pmc_a * pmc_b);
}
#[test]
fn pwmc_uniform_weight_one_equals_pmc() {
let f = make_formula(3, vec![vec![1, 2], vec![3]]);
let pmc = brute_force_pmc(&f, &[0, 1]); let pwmc = brute_force_pwmc(&f, &[0, 1], |_v, _val| rat(1, 1));
assert_eq!(
pwmc,
BigRational::from_integer(num_bigint::BigInt::from(pmc))
);
assert_eq!(pwmc, BigRational::from_integer(3.into()));
}
#[test]
fn pwmc_handchecked_distinct_weights() {
let f = make_formula(2, vec![vec![1, 2]]);
let w = |_v: u32, val: bool| if val { rat(2, 1) } else { rat(3, 1) };
let pwmc = brute_force_pwmc(&f, &[0, 1], w);
assert_eq!(pwmc, BigRational::from_integer(16.into()));
}
#[test]
fn pwmc_xor_dedupes_before_weighting() {
let xor = make_formula(2, vec![vec![1, 2], vec![-1, -2]]);
let w = |_v: u32, val: bool| if val { rat(1, 2) } else { rat(1, 3) };
let pwmc = brute_force_pwmc(&xor, &[0], w);
assert_eq!(pwmc, rat(5, 6));
}
#[test]
fn pwmc_disjoint_components_multiply() {
let joint = make_formula(4, vec![vec![1, 2], vec![3, 4]]);
let w = |_v: u32, val: bool| if val { rat(2, 1) } else { rat(3, 1) };
let pwmc_joint = brute_force_pwmc(&joint, &[0, 1, 2], w);
let comp_a = make_formula(2, vec![vec![1, 2]]);
let pwmc_a = brute_force_pwmc(&comp_a, &[0, 1], w); let comp_b = make_formula(2, vec![vec![1, 2]]);
let pwmc_b = brute_force_pwmc(&comp_b, &[0], w);
assert_eq!(pwmc_b, BigRational::from_integer(5.into()));
assert_eq!(pwmc_joint, pwmc_a * pwmc_b);
}