use simular::engine::rng::SimRng;
use trueno::simulation::{BackendTolerance, JidokaGuard};
use trueno::{select_best_available_backend, Backend, Vector};
#[test]
fn test_b016_simrng_platform_independent() {
let mut rng = SimRng::new(42);
let seq: Vec<f64> = (0..10).map(|_| rng.gen_f64()).collect();
let mut rng2 = SimRng::new(42);
let seq2: Vec<f64> = (0..10).map(|_| rng2.gen_f64()).collect();
assert_eq!(seq, seq2, "B-016 FALSIFIED: Same seed must produce identical sequences");
}
#[test]
fn test_b017_deterministic_output() {
for _ in 0..100 {
let mut rng = SimRng::new(42);
let data: Vec<f32> = (0..1000).map(|_| rng.gen_f64() as f32).collect();
let a = Vector::from_slice(&data);
let b: Vec<f32> = (0..1000).map(|i| i as f32).collect();
let b_vec = Vector::from_slice(&b);
let result = a.add(&b_vec).expect("add failed");
let mut rng2 = SimRng::new(42);
let data2: Vec<f32> = (0..1000).map(|_| rng2.gen_f64() as f32).collect();
let a2 = Vector::from_slice(&data2);
let result2 = a2.add(&b_vec).expect("add failed");
for (i, (r1, r2)) in result.as_slice().iter().zip(result2.as_slice().iter()).enumerate() {
assert_eq!(
r1.to_bits(),
r2.to_bits(),
"B-017 FALSIFIED: Results differ at index {i}: {r1} != {r2}",
);
}
}
}
#[test]
fn test_b018_different_seeds_different_outputs() {
let sequences: Vec<Vec<f64>> = (0..1000)
.map(|seed| {
let mut rng = SimRng::new(seed);
(0..10).map(|_| rng.gen_f64()).collect()
})
.collect();
for i in 0..sequences.len() {
for j in (i + 1)..sequences.len() {
assert_ne!(
sequences[i], sequences[j],
"B-018 FALSIFIED: Seeds {} and {} produce same sequence",
i, j
);
}
}
}
#[test]
fn test_b019_parallel_determinism() {
let mut rng = SimRng::new(42);
let partitions = rng.partition(4);
let mut results: Vec<Vec<f64>> = Vec::new();
for mut partition in partitions {
let seq: Vec<f64> = (0..100).map(|_| partition.gen_f64()).collect();
results.push(seq);
}
let mut rng2 = SimRng::new(42);
let partitions2 = rng2.partition(4);
let mut results2: Vec<Vec<f64>> = Vec::new();
for mut partition in partitions2 {
let seq: Vec<f64> = (0..100).map(|_| partition.gen_f64()).collect();
results2.push(seq);
}
assert_eq!(results, results2, "B-019 FALSIFIED: Parallel partitions not deterministic");
}
#[test]
fn test_b020_gpu_determinism() {
let tolerance = BackendTolerance::relaxed();
let gpu_tolerance = tolerance.for_backends(Backend::GPU, Backend::GPU);
let mut rng1 = SimRng::new(12345);
let mut rng2 = SimRng::new(12345);
let result1: Vec<f32> = (0..100).map(|_| rng1.gen_f64() as f32).collect();
let result2: Vec<f32> = (0..100).map(|_| rng2.gen_f64() as f32).collect();
for (i, (r1, r2)) in result1.iter().zip(result2.iter()).enumerate() {
let diff = (r1 - r2).abs();
assert!(
diff <= gpu_tolerance,
"B-020 FALSIFIED: GPU results differ at index {i}: {} vs {} (diff: {})",
r1,
r2,
diff
);
}
}
#[test]
fn test_b022_system_load_independence() {
let data = Vector::from_slice(&[1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);
let scalar = 2.0f32;
let mut results: Vec<Vec<f32>> = Vec::new();
for _ in 0..10 {
let scaled = data.scale(scalar).expect("scale failed");
results.push(scaled.as_slice().to_vec());
}
let first = &results[0];
for (i, result) in results.iter().enumerate().skip(1) {
assert_eq!(
first, result,
"B-022 FALSIFIED: Run {i} produced different results under varying load"
);
}
}
#[test]
fn test_b023_memory_pressure_independence() {
let data = Vector::from_slice(&[1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);
let result1 = data.sum().expect("sum failed");
{
let _pressure: Vec<Vec<f32>> = (0..100).map(|_| vec![0.0f32; 10_000]).collect();
}
let result2 = data.sum().expect("sum failed");
assert!(
(result1 - result2).abs() < f32::EPSILON,
"B-023 FALSIFIED: Memory pressure affected results: {result1} vs {result2}"
);
}
#[test]
fn test_b021_test_isolation() {
let data = Vector::from_slice(&[1.0f32, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0]);
let b = Vector::from_slice(&[1.0f32, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]);
let add_result = data.add(&b).expect("add failed");
let mul_result = data.mul(&b).expect("mul failed");
let mul_result2 = data.mul(&b).expect("mul failed");
let add_result2 = data.add(&b).expect("add failed");
assert_eq!(
add_result.as_slice(),
add_result2.as_slice(),
"B-021 FALSIFIED: Test order affected add result"
);
assert_eq!(
mul_result.as_slice(),
mul_result2.as_slice(),
"B-021 FALSIFIED: Test order affected mul result"
);
}
#[test]
fn test_b024_determinism_all_sizes() {
let sizes = [1, 7, 8, 15, 16, 31, 32, 100, 1000, 10_000];
for size in sizes {
let a: Vec<f32> = (0..size).map(|i| i as f32).collect();
let b: Vec<f32> = (0..size).map(|i| (size - 1 - i) as f32).collect();
let vec_a = Vector::from_slice(&a);
let vec_b = Vector::from_slice(&b);
let result1 = vec_a.add(&vec_b).expect("add failed");
let result2 = vec_a.add(&vec_b).expect("add failed");
assert_eq!(
result1.as_slice(),
result2.as_slice(),
"B-024 FALSIFIED: Size {} not deterministic",
size
);
}
}
#[test]
fn test_b025_special_values_determinism() {
let special = vec![0.0f32, -0.0f32, f32::MIN, f32::MAX, f32::MIN_POSITIVE, -f32::MIN_POSITIVE];
let b = vec![1.0f32; special.len()];
let vec_special = Vector::from_slice(&special);
let vec_b = Vector::from_slice(&b);
for _ in 0..100 {
let result = vec_special.add(&vec_b).expect("add failed");
assert!(result.as_slice()[0] == 1.0, "B-025 FALSIFIED: 0.0 + 1.0 should equal 1.0");
assert!(result.as_slice()[1] == 1.0, "B-025 FALSIFIED: -0.0 + 1.0 should equal 1.0");
}
}
#[test]
fn test_b026_subnormal_determinism() {
let subnormal = f32::from_bits(1);
assert!(subnormal > 0.0 && subnormal < f32::MIN_POSITIVE);
let a = vec![subnormal; 8];
let b = vec![subnormal; 8];
let vec_a = Vector::from_slice(&a);
let vec_b = Vector::from_slice(&b);
let result1 = vec_a.add(&vec_b).expect("add failed");
let result2 = vec_a.add(&vec_b).expect("add failed");
for (r1, r2) in result1.as_slice().iter().zip(result2.as_slice().iter()) {
assert_eq!(
r1.to_bits(),
r2.to_bits(),
"B-026 FALSIFIED: Subnormal handling not deterministic"
);
}
}
#[test]
fn test_b027_nan_propagation() {
let nan_guard = JidokaGuard::nan_guard("B-027");
let a = vec![1.0f32, f32::NAN, 3.0, 4.0];
let b = vec![1.0f32, 1.0, 1.0, 1.0];
let vec_a = Vector::from_slice(&a);
let vec_b = Vector::from_slice(&b);
let result = vec_a.add(&vec_b).expect("add failed");
assert!(result.as_slice()[1].is_nan(), "B-027 FALSIFIED: NaN should propagate");
let check = nan_guard.check_output(result.as_slice());
assert!(check.is_err(), "B-027: Jidoka should detect NaN");
}
#[test]
fn test_b028_infinity_handling() {
let inf_guard = JidokaGuard::inf_guard("B-028");
let a = vec![1.0f32, f32::INFINITY, f32::NEG_INFINITY, 4.0];
let b = vec![1.0f32, 1.0, 1.0, 1.0];
let vec_a = Vector::from_slice(&a);
let vec_b = Vector::from_slice(&b);
let result = vec_a.add(&vec_b).expect("add failed");
assert!(
result.as_slice()[1].is_infinite() && result.as_slice()[1] > 0.0,
"B-028 FALSIFIED: +Inf should propagate"
);
assert!(
result.as_slice()[2].is_infinite() && result.as_slice()[2] < 0.0,
"B-028 FALSIFIED: -Inf should propagate"
);
let check = inf_guard.check_output(result.as_slice());
assert!(check.is_err(), "B-028: Jidoka should detect Infinity");
}
#[test]
fn test_b029_cross_process_determinism() {
let mut rng1 = SimRng::new(42);
let seq1: Vec<f64> = (0..100).map(|_| rng1.gen_f64()).collect();
let mut rng2 = SimRng::new(42);
let seq2: Vec<f64> = (0..100).map(|_| rng2.gen_f64()).collect();
assert_eq!(seq1, seq2, "B-029 FALSIFIED: RNG not deterministic across instances");
}
#[test]
fn test_b030_thread_local_isolation() {
let backend1 = select_best_available_backend();
let backend2 = select_best_available_backend();
assert_eq!(backend1, backend2, "B-030 FALSIFIED: Backend selection should be consistent");
}