diff --git a/src/metrics.rs b/src/metrics.rs index 4e7d90d..3bd35eb 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -65,7 +65,7 @@ macro_rules! impl_for_tuple { } #[allow(unused)] fn requires_ordering_by_descending_value_pwu(&self) -> bool { - [$(self.$b.0.requires_ordering_by_descending_value_pwu()),*].iter().all(|x| *x) + [$(self.$b.0.requires_ordering_by_descending_value_pwu()),*].iter().any(|x| *x) } } }; diff --git a/tests/bnb.rs b/tests/bnb.rs index d8c975e..6a2f437 100644 --- a/tests/bnb.rs +++ b/tests/bnb.rs @@ -52,6 +52,36 @@ impl BnbMetric for MinExcessThenWeight { } } +#[derive(Clone, Copy)] +struct OrderSensitive; + +impl BnbMetric for OrderSensitive { + fn score(&mut self, _cs: &CoinSelector<'_>) -> Option { + Some(Ordf32(0.0)) + } + + fn bound(&mut self, _cs: &CoinSelector<'_>) -> Option { + Some(Ordf32(0.0)) + } + + fn requires_ordering_by_descending_value_pwu(&self) -> bool { + true + } +} + +#[derive(Clone, Copy)] +struct NoOrderMetric; + +impl BnbMetric for NoOrderMetric { + fn score(&mut self, _cs: &CoinSelector<'_>) -> Option { + Some(Ordf32(0.0)) + } + + fn bound(&mut self, _cs: &CoinSelector<'_>) -> Option { + Some(Ordf32(0.0)) + } +} + #[test] /// Detect regressions/improvements by making sure it always finds the solution in the same /// number of iterations. @@ -139,6 +169,24 @@ fn bnb_finds_solution_if_possible_in_n_iter() { assert_eq!(excess, 0); } +#[test] +fn bnb_tuple_metric_respects_ordering_requirement() { + assert!( + ((OrderSensitive, 1.0), (OrderSensitive, 1.0)).requires_ordering_by_descending_value_pwu(), + "both require ordering, so ordering should be required" + ); + + assert!( + ((OrderSensitive, 1.0), (NoOrderMetric, 1.0)).requires_ordering_by_descending_value_pwu(), + "one requires ordering, so ordering should be required" + ); + + assert!( + !((NoOrderMetric, 1.0), (NoOrderMetric, 1.0)).requires_ordering_by_descending_value_pwu(), + "none require ordering, so ordering should not be required" + ); +} + proptest! { #[test] fn bnb_always_finds_solution_if_possible(num_inputs in 1usize..18, target_value in 0u64..10_000) {