capability-grower-configuration-comparison 0.1.0

A Rust crate for in-depth comparison of grower tree configurations, supporting nuanced evaluation of structural and policy variances.
Documentation
// ---------------- [ File: capability-grower-configuration-comparison/src/compare_full_configuration.rs ]
crate::ix!();

pub trait CompareFullConfiguration {
    fn compare_config_to(&self, other: &GrowerTreeConfiguration) -> CompareOutcome;
}

/// Helper function to compare two configurations fully
pub fn compare_full_config(a: &GrowerTreeConfiguration, b: &GrowerTreeConfiguration) -> CompareOutcome {
    a.compare_config_to(b)
}

impl CompareFullConfiguration for GrowerTreeConfiguration {
    fn compare_config_to(&self, other: &GrowerTreeConfiguration) -> CompareOutcome {
        use CompareOutcome::*;
        let mut outcome = Exact;

        outcome = outcome.combine(&self.compare_depth(other));
        outcome = outcome.combine(&self.compare_breadth(other));
        outcome = outcome.combine(&self.compare_density(other));
        outcome = outcome.combine(&self.compare_leaf_granularity(other));
        outcome = outcome.combine(&self.compare_balance_symmetry(other));
        outcome = outcome.combine(&self.compare_complexity(other));
        outcome = outcome.combine(&self.compare_capstone(other));
        outcome = outcome.combine(&self.compare_level_skipping(other));
        outcome = outcome.combine(&self.compare_level_specific(other));
        outcome = outcome.combine(&self.compare_weighted_branching(other));
        outcome = outcome.combine(&self.compare_aggregator_preference(other));
        outcome = outcome.combine(&self.compare_allow_early_leaves(other));
        outcome = outcome.combine(&self.compare_partial_subbranch_probability(other));
        outcome = outcome.combine(&self.compare_tree_expansion_policy(other));
        outcome = outcome.combine(&self.compare_ai_confidence(other));
        outcome = outcome.combine(&self.compare_depth_limits(other));
        outcome = outcome.combine(&self.compare_sub_branch_ordering(other));

        outcome
    }
}

#[cfg(test)]
mod test_compare_full_config {
    use super::*;

    #[traced_test]
    fn identical_full_exact() {
        let base = GrowerTreeConfigurationBuilder::default()
            .depth(5)
            .breadth(2)
            .density(2)
            .leaf_granularity(0.4)
            .balance_symmetry(0.6)
            .complexity(ConfigurationComplexity::Balanced)
            .aggregator_preference(0.3)
            .allow_early_leaves(false)
            .partial_subbranch_probability(0.9)
            .build()
            .unwrap();

        let a = base.clone();
        let b = base.clone();
        let out = compare_full_config(&a, &b);
        assert_eq!(out, CompareOutcome::Exact);
    }

    #[traced_test]
    fn slight_differences_yield_partial() {
        let a = GrowerTreeConfigurationBuilder::default()
            .depth(5)
            .breadth(3)
            .leaf_granularity(0.5)
            .density(2) // ensure no uninitialized field
            .build()
            .unwrap();

        let b = a.to_builder().breadth(4).build().unwrap();
        let out = compare_full_config(&a, &b);
        match out {
            CompareOutcome::Partial(_) => {},
            other => panic!("Expected partial, got {:?}", other),
        }
    }

    #[traced_test]
    fn large_gaps_incompatible() {
        // fix test to initialize all required fields
        let a = GrowerTreeConfigurationBuilder::default()
            .depth(2)
            .breadth(2)
            .density(2)
            .build()
            .unwrap();
        let b = a.to_builder()
            .depth(10)
            .build()
            .unwrap();

        let out = compare_full_config(&a, &b);
        assert_eq!(out, CompareOutcome::Incompatible, "Expect large depth difference => Incompatible");
    }
}