| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| pub mod primitive; |
| pub mod boolean; |
| pub mod conflicts; |
| pub mod filter; |
|
|
| |
| pub use primitive::{nand, not, and, or, xor, implies, nor, xnor}; |
| pub use boolean::{BoolExpr, eval, truth_table, lower_to_nand, functionally_equivalent}; |
| pub use conflicts::{ExpertId, ConflictRegistry}; |
| pub use filter::{ExpertActivation, NANDFilter}; |
|
|
| #[cfg(test)] |
| mod integration_tests { |
| use super::*; |
|
|
| #[test] |
| fn test_primitive_matches_ast_evaluation() { |
| |
| |
| for &a in &[false, true] { |
| for &b in &[false, true] { |
| let bindings = &[a, b]; |
|
|
| |
| let nand_expr = BoolExpr::nand(BoolExpr::Var(0), BoolExpr::Var(1)); |
| assert_eq!(nand(a, b), eval(&nand_expr, bindings)); |
|
|
| |
| let and_expr = BoolExpr::from_and(BoolExpr::Var(0), BoolExpr::Var(1)); |
| assert_eq!(and(a, b), eval(&and_expr, bindings)); |
|
|
| |
| let or_expr = BoolExpr::from_or(BoolExpr::Var(0), BoolExpr::Var(1)); |
| assert_eq!(or(a, b), eval(&or_expr, bindings)); |
|
|
| |
| let xor_expr = BoolExpr::from_xor(BoolExpr::Var(0), BoolExpr::Var(1)); |
| assert_eq!(xor(a, b), eval(&xor_expr, bindings)); |
|
|
| |
| let imp_expr = BoolExpr::from_implies(BoolExpr::Var(0), BoolExpr::Var(1)); |
| assert_eq!(implies(a, b), eval(&imp_expr, bindings)); |
| } |
| } |
| } |
|
|
| #[test] |
| fn test_not_primitive_matches_ast() { |
| for &a in &[false, true] { |
| let not_expr = BoolExpr::from_not(BoolExpr::Var(0)); |
| assert_eq!(not(a), eval(¬_expr, &[a])); |
| } |
| } |
|
|
| #[test] |
| fn test_full_pipeline_conflict_resolution() { |
| |
| let mut reg = ConflictRegistry::new(); |
| reg.register_conflict(ExpertId(10), ExpertId(20)); |
| reg.register_conflict(ExpertId(30), ExpertId(40)); |
|
|
| let filter = NANDFilter::new(reg); |
|
|
| let activations = vec![ |
| ExpertActivation::new(ExpertId(10), 0.9), |
| ExpertActivation::new(ExpertId(20), 0.4), |
| ExpertActivation::new(ExpertId(30), 0.6), |
| ExpertActivation::new(ExpertId(40), 0.6), |
| ]; |
|
|
| let result = filter.filter(&activations); |
|
|
| |
| |
| let ids: Vec<ExpertId> = result.iter().map(|a| a.id).collect(); |
| assert!(ids.contains(&ExpertId(10))); |
| assert!(!ids.contains(&ExpertId(20))); |
| assert!(!ids.contains(&ExpertId(30))); |
| assert!(ids.contains(&ExpertId(40))); |
| } |
|
|
| #[test] |
| fn test_validity_predicate_as_nand_tree() { |
| |
| |
| |
| let a_and_b = BoolExpr::from_and(BoolExpr::Var(0), BoolExpr::Var(1)); |
| let not_c = BoolExpr::from_not(BoolExpr::Var(2)); |
| let not_c_or_d = BoolExpr::from_or(not_c, BoolExpr::Var(3)); |
| let predicate = BoolExpr::from_implies(a_and_b, not_c_or_d); |
|
|
| |
| assert!(predicate.is_pure_nand()); |
|
|
| |
| let table = truth_table(&predicate, 4); |
| assert_eq!(table.len(), 16); |
|
|
| |
| |
| assert_eq!(eval(&predicate, &[true, true, true, false]), false); |
|
|
| |
| |
| assert_eq!(eval(&predicate, &[true, true, false, false]), true); |
|
|
| |
| |
| assert_eq!(eval(&predicate, &[false, true, true, false]), true); |
| } |
|
|
| #[test] |
| fn test_nand_lowering_complex_expression() { |
| |
| let expr = BoolExpr::from_or( |
| BoolExpr::from_and( |
| BoolExpr::from_not(BoolExpr::Var(0)), |
| BoolExpr::Var(1), |
| ), |
| BoolExpr::from_xor(BoolExpr::Var(2), BoolExpr::Var(3)), |
| ); |
|
|
| let lowered = lower_to_nand(&expr); |
| assert!(lowered.is_pure_nand()); |
| assert!(functionally_equivalent(&expr, &lowered, 4)); |
| } |
| } |
|
|