feat!: split NoBnbSolution into infeasible vs round-limit variants#55
Merged
evanlinjin merged 1 commit intoJul 8, 2026
Merged
Conversation
Collaborator
|
conceptACK |
`run_bnb` failing conflated three different cases behind one struct. Make
`NoBnbSolution` an enum that says which happened:
- `InsufficientFunds` — the candidates can't cover the target value.
- `MaxWeightExceeded` — the value is coverable, but every selection busts
`max_weight` (mirrors `SelectError`).
- `RoundLimit { max_rounds, rounds }` — hit the round cap; a solution may
still exist with more rounds.
The distinction is derivable in `run_bnb` without giving `BnbMetric` an error
channel: if the search runs to completion (rounds < max_rounds, or a final
pull drains the iterator) then no selection satisfies the target — a genuine
infeasibility — and a cheap `is_fundable` value check splits it into value vs
weight. Otherwise we merely ran out of rounds.
Breaking: `NoBnbSolution` is now an enum; its `max_rounds`/`rounds` fields move
under the `RoundLimit` variant.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
evanlinjin
force-pushed
the
feat/bnb-infeasible-error
branch
from
July 8, 2026 07:57
b3366a0 to
4d5349e
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
run_bnb's failure is currently a singleNoBnbSolution { max_rounds, rounds }, which conflates three different situations. This makes it an enum:InsufficientFunds— the candidates can't cover the target value.MaxWeightExceeded— the value is coverable, but every selection bustsmax_weight(mirrors theSelectErrorfromselect_until_target_met).RoundLimit { max_rounds, rounds }— hit the round cap; a solution may still exist with more rounds.How — without touching
BnbMetricThe metric returning
Nonejust means "prune"; it never needs an error channel. All the information already lives inrun_bnb: if the search runs to completion (rounds < max_rounds, or a final pull drains the iterator) then the tree was fully explored and no selection satisfies the target — a genuine infeasibility. A cheapis_fundablevalue check then splits that into value (InsufficientFunds) vs weight (MaxWeightExceeded). If instead we stopped on the round cap, it'sRoundLimit.The
MaxWeightExceededattribution is sound for the crate's metrics: a cap-blind metric can only exhaust-empty when the value itself is unreachable (otherwise it would have returned an over-cap selection, not failed), so you never falsely land there.Breaking
NoBnbSolutionbecomes an enum; themax_rounds/roundsfields move under theRoundLimitvariant.Display/Errorstill hold.Tests
Deterministic tests for each variant:
run_bnb_reports_{insufficient_funds,max_weight_exceeded,round_limit}.🤖 Generated with Claude Code