use super::*;
#[test]
fn falsify_by_001_beta_posterior_mean() {
let mut model = BetaBinomial::uniform(); model.update(7, 10);
let mean = model.posterior_mean();
let expected = 8.0 / 12.0;
assert!(
(mean - expected).abs() < 1e-5,
"FALSIFIED BY-001: mean={mean}, expected {expected}"
);
}
#[test]
fn falsify_by_002_beta_mean_bounded() {
let mut model = BetaBinomial::uniform();
model.update(100, 100);
let mean = model.posterior_mean();
assert!(
(0.0..=1.0).contains(&mean),
"FALSIFIED BY-002: mean={mean}, expected in [0,1]"
);
}
#[test]
fn falsify_by_003_beta_more_data_less_variance() {
let mut few = BetaBinomial::uniform();
few.update(7, 10);
let mut many = BetaBinomial::uniform();
many.update(70, 100);
assert!(
many.posterior_variance() < few.posterior_variance(),
"FALSIFIED BY-003: variance(100 trials)={} >= variance(10 trials)={}",
many.posterior_variance(),
few.posterior_variance()
);
}
#[test]
fn falsify_by_004_gamma_posterior_mean() {
let mut model = GammaPoisson::noninformative();
model.update(&[3, 5, 4, 6, 2]);
let mean = model.posterior_mean();
assert!(
(mean - 4.0).abs() < 0.5,
"FALSIFIED BY-004: GammaPoisson mean={mean}, expected ~4.0"
);
}
#[test]
fn falsify_by_005_dirichlet_probs_sum_to_one() {
let mut model = DirichletMultinomial::uniform(3);
model.update(&[10, 5, 3]);
let probs = model.posterior_mean();
let sum: f32 = probs.iter().sum();
assert!(
(sum - 1.0).abs() < 1e-5,
"FALSIFIED BY-005: Dirichlet probs sum={sum}, expected 1.0"
);
}
#[test]
fn falsify_by_006_dirichlet_probs_nonneg() {
let mut model = DirichletMultinomial::uniform(4);
model.update(&[1, 0, 3, 2]);
let probs = model.posterior_mean();
for (i, &p) in probs.iter().enumerate() {
assert!(p >= 0.0, "FALSIFIED BY-006: prob[{i}]={p}, expected >= 0.0");
}
}
mod by_proptest_falsify {
use super::*;
use proptest::prelude::*;
proptest! {
#![proptest_config(ProptestConfig::with_cases(30))]
#[test]
fn falsify_by_002_prop_beta_mean_bounded(
successes in 0..100u32,
trials in 1..200u32,
) {
let successes = successes.min(trials);
let mut model = BetaBinomial::uniform();
model.update(successes, trials);
let mean = model.posterior_mean();
prop_assert!(
(0.0..=1.0).contains(&mean),
"FALSIFIED BY-002-prop: mean={} not in [0,1] (successes={}, trials={})",
mean, successes, trials
);
}
}
proptest! {
#![proptest_config(ProptestConfig::with_cases(20))]
#[test]
fn falsify_by_005_prop_dirichlet_sum(
k in 2..=5usize,
seed in 0..500u32,
) {
let mut model = DirichletMultinomial::uniform(k);
let counts: Vec<u32> = (0..k).map(|i| ((seed + i as u32) % 20) + 1).collect();
model.update(&counts);
let probs = model.posterior_mean();
let sum: f32 = probs.iter().sum();
prop_assert!(
(sum - 1.0).abs() < 1e-4,
"FALSIFIED BY-005-prop: Dirichlet sum={}, expected ~1.0",
sum
);
}
}
}