//! Criterio de éxito del hito M1 (§8): A da 0, B da ≠0, y la localización de B //! apunta al ciclo correcto (entre las réplicas 1 y 2). use sheafsync::cohomology::{compute, compute_with}; use sheafsync::gf2::Gf2Backend; use sheafsync::linalg::F64Backend; use sheafsync::nerve::ReplicaId; use sheafsync::sheaf::Sheaf; use sheafsync::verdict::Verdict; #[test] fn corrida_a_corre_libre() { // G-Counter compartido en camino acíclico (stalk = vector ℤ³). let sheaf = Sheaf::constant(3, &[(0, 1), (1, 2)], 3); let coho = compute(&sheaf).unwrap(); assert_eq!(coho.dim_h1, 0, "el caso monótono no tiene obstrucción"); assert_eq!(Verdict::diagnose(&sheaf, &coho), Verdict::RunsFree); } #[test] fn corrida_b_coordina_con_nudo_localizado() { // ResettableRegister: enlace doble irreconciliable entre réplicas 1 y 2. let sheaf = Sheaf::constant(3, &[(0, 1), (1, 2), (1, 2)], 1); let coho = compute(&sheaf).unwrap(); assert_eq!(coho.dim_h1, 1, "el ciclo produce una obstrucción"); let verdict = Verdict::diagnose(&sheaf, &coho); let knots = match verdict { Verdict::NeedsCoordination { knots } => knots, Verdict::RunsFree => panic!("debería necesitar coordinación"), }; assert_eq!(knots.len(), 1, "un único nudo"); let knot = &knots[0]; // El nudo está entre las réplicas 1 y 2, NO involucra a la réplica 0. assert_eq!(knot.replicas, vec![ReplicaId(1), ReplicaId(2)]); // Y son las dos aristas del enlace doble (índices 1 y 2), no la 0. assert_eq!(knot.edges, vec![1, 2]); } /// El veredicto de M1 no depende de la aritmética: `f64` (con epsilon) y `GF(2)` /// (exacta) coinciden en A y en B. Migración a exacto de T3. #[test] fn m1_coincide_en_f64_y_gf2() { let sheaf_a = Sheaf::constant(3, &[(0, 1), (1, 2)], 3); let sheaf_b = Sheaf::constant(3, &[(0, 1), (1, 2), (1, 2)], 1); for (sheaf, esperado_h1) in [(&sheaf_a, 0), (&sheaf_b, 1)] { let a = compute_with(sheaf, &F64Backend::new()).unwrap(); let b = compute_with(sheaf, &Gf2Backend).unwrap(); assert_eq!(a.dim_h1, esperado_h1); assert_eq!(a.dim_h1, b.dim_h1); assert_eq!(a.dim_h0, b.dim_h0); // La localización coincide en ambos backends. assert_eq!(Verdict::diagnose(sheaf, &a), Verdict::diagnose(sheaf, &b)); } }