capability_grower_configuration_comparison/
compare_full_configuration.rs

1// ---------------- [ File: capability-grower-configuration-comparison/src/compare_full_configuration.rs ]
2crate::ix!();
3
4pub trait CompareFullConfiguration {
5    fn compare_config_to(&self, other: &GrowerTreeConfiguration) -> CompareOutcome;
6}
7
8/// Helper function to compare two configurations fully
9pub fn compare_full_config(a: &GrowerTreeConfiguration, b: &GrowerTreeConfiguration) -> CompareOutcome {
10    a.compare_config_to(b)
11}
12
13impl CompareFullConfiguration for GrowerTreeConfiguration {
14    fn compare_config_to(&self, other: &GrowerTreeConfiguration) -> CompareOutcome {
15        use CompareOutcome::*;
16        let mut outcome = Exact;
17
18        outcome = outcome.combine(&self.compare_depth(other));
19        outcome = outcome.combine(&self.compare_breadth(other));
20        outcome = outcome.combine(&self.compare_density(other));
21        outcome = outcome.combine(&self.compare_leaf_granularity(other));
22        outcome = outcome.combine(&self.compare_balance_symmetry(other));
23        outcome = outcome.combine(&self.compare_complexity(other));
24        outcome = outcome.combine(&self.compare_capstone(other));
25        outcome = outcome.combine(&self.compare_level_skipping(other));
26        outcome = outcome.combine(&self.compare_level_specific(other));
27        outcome = outcome.combine(&self.compare_weighted_branching(other));
28        outcome = outcome.combine(&self.compare_aggregator_preference(other));
29        outcome = outcome.combine(&self.compare_allow_early_leaves(other));
30        outcome = outcome.combine(&self.compare_partial_subbranch_probability(other));
31        outcome = outcome.combine(&self.compare_tree_expansion_policy(other));
32        outcome = outcome.combine(&self.compare_ai_confidence(other));
33        outcome = outcome.combine(&self.compare_depth_limits(other));
34        outcome = outcome.combine(&self.compare_sub_branch_ordering(other));
35
36        outcome
37    }
38}
39
40#[cfg(test)]
41mod test_compare_full_config {
42    use super::*;
43
44    #[traced_test]
45    fn identical_full_exact() {
46        let base = GrowerTreeConfigurationBuilder::default()
47            .depth(5)
48            .breadth(2)
49            .density(2)
50            .leaf_granularity(0.4)
51            .balance_symmetry(0.6)
52            .complexity(ConfigurationComplexity::Balanced)
53            .aggregator_preference(0.3)
54            .allow_early_leaves(false)
55            .partial_subbranch_probability(0.9)
56            .build()
57            .unwrap();
58
59        let a = base.clone();
60        let b = base.clone();
61        let out = compare_full_config(&a, &b);
62        assert_eq!(out, CompareOutcome::Exact);
63    }
64
65    #[traced_test]
66    fn slight_differences_yield_partial() {
67        let a = GrowerTreeConfigurationBuilder::default()
68            .depth(5)
69            .breadth(3)
70            .leaf_granularity(0.5)
71            .density(2) // ensure no uninitialized field
72            .build()
73            .unwrap();
74
75        let b = a.to_builder().breadth(4).build().unwrap();
76        let out = compare_full_config(&a, &b);
77        match out {
78            CompareOutcome::Partial(_) => {},
79            other => panic!("Expected partial, got {:?}", other),
80        }
81    }
82
83    #[traced_test]
84    fn large_gaps_incompatible() {
85        // fix test to initialize all required fields
86        let a = GrowerTreeConfigurationBuilder::default()
87            .depth(2)
88            .breadth(2)
89            .density(2)
90            .build()
91            .unwrap();
92        let b = a.to_builder()
93            .depth(10)
94            .build()
95            .unwrap();
96
97        let out = compare_full_config(&a, &b);
98        assert_eq!(out, CompareOutcome::Incompatible, "Expect large depth difference => Incompatible");
99    }
100}