Conversation
Codecov Report❌ Patch coverage is ❌ Your patch status has failed because the patch coverage (94.11%) is below the target coverage (95.00%). You can increase the patch coverage or adjust the target coverage. Additional details and impacted files@@ Coverage Diff @@
## main #1147 +/- ##
==========================================
+ Coverage 95.93% 96.30% +0.37%
==========================================
Files 1074 1072 -2
Lines 132106 135540 +3434
==========================================
+ Hits 126730 130537 +3807
+ Misses 5376 5003 -373 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
15 tasks
isPANN
marked this pull request as draft
September 13, 2026 15:34
Separate enumeration capabilities from model semantics and preserve checked arithmetic across reductions. Share executed reduction results for witness and value recovery, and replace dense QUBO storage with sprs CSR throughout construction and consumption. Update callers, regression tests, and contributor documentation. Validation: workspace checks, MCP tests, paper build, and changed-line coverage at 95.70%.
Route deserialization through fallible construction, rebuild derived state, and update callers and regression tests. Reuse native graph routines and ILP row storage, and preserve merged-loop extraction in the PCSF-to-Steiner mapping.
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.
This PR separates mathematical model/reduction semantics from backend execution and brute-force search limits. Each executed reduction owns one target instance and the state needed to recover source solutions and interpret target optima. It also fixes affected mathematical constructions and replaces dense QUBO storage with
sprsCSR matrices.This includes behavior and public API changes, not only performance improvements.
Reduction construction, solving, and recovery
The typed mathematical API remains
reduce_to() -> ReductionResult, withtarget_problem()andextract_solution().Problem::evaluate()remains the model's feasibility/objective operation. A trait declares the methods an implementation supplies; it does not itself run a solver.For a path
a—b—c, reducing minimum vertex cover to maximum independent set produces a target optimum{a,c}.extract_solution()complements that assignment to recover the minimum cover{b}, whose source cost is 1.Previously, solver completion could invoke the aggregate reduction constructor again after constructing the witness reduction.
ExecutedStepnow shares one result throughRcwitness/value views and an optionalinterpret_optimumoperation. The target and reverse-mapping state are constructed once. Executed-path prefix caches retain individual steps instead of copying whole chains for every prefix.For
Decision<MinimumVertexCover>on the same path with bound 0, the target optimizer returns cost 1. The stored bound establishes NO before witness extraction. A timeout or backend error remains an error; it does not become NO. Penalty reductions such as ILP→QUBO similarly use their mathematical energy relationship to distinguish source infeasibility from a recoverable target optimum.AggregateReductionResultmaps target values to source values.SolutionAggregate, which compares candidate values with an aggregate optimum, now belongs only to brute-force witness selection. Dynamic model evaluation no longer requires it.Direct
extract_solution()andpred extractassume the rule's documented witness premises, including optimality when needed. They map the supplied solution; they do not certify feasibility/optimality or repair arbitrary assignments. Redundant extractor validation and forwarding branches are removed. Typed, dynamic, and JSON recovery share the same reverse mapping.Native ILP execution and numerical boundaries
HighsAdapterowns backend encoding, execution, decoding, and original-ILP validation.highsdirectly. Explicit integer-to-float mathematical reduction edges remain available independently of backend transport.2^53 + 1is valid model data but cannot be transported exactly into a backendf64; the adapter reportsInexactTransportinstead of rejecting the mathematical model or reporting infeasibility.1 <= 0.9999999995is false; the old model tolerance could accept it.Solver availability still comes from exact-variant registrations and fixed pipelines, not arbitrary reduction-graph reachability. Once a solver is selected, execution failures are returned without fallback.
Model evaluation and enumeration
BruteForceProblem::dimensions() -> Vec<usize>is replaced by falliblenum_variables()anddimension(variable)methods. Models and callers are migrated together. Mixed-radix iteration no longer requires the total Cartesian product to fitusize.For 100 Boolean coordinates, the model can evaluate a supplied assignment and the iterator can generate a prefix even though
2^100does not fit a machine-size count. This does not make exhaustive solving practical. Unrepresentable coordinates, masks, or search tables report errors in their owning search/construction layer.CVP now evaluates exact squared distance as
Min<BigRational>and checks basis rank with arbitrary-precision integers. Its existing rational sphere-enumeration solver consumes stored coordinates directly without the previous float-transport restrictions. A displacement(3,4)has value 25 instead of the previous floating-point distance 5. Squaring preserves the mathematical minimizers but changes objective values, return types, serialized values, and numerical computation costs. Dependent thresholds and QUBO mappings are updated accordingly.Mathematical construction and domain fixes
(1,2),beta=1, and component charge 5, every target optimum has cost 15 and extracts to source cost 3 after the offset 12.SteinerTreeis canonical; duplicateSteinerTreeInGraphsand its rule are removed. Signed weights are accepted, terminals must be nonempty and distinct, and selected edges must form one tree containing the terminals. A single-terminal empty tree is feasible.Rule tests include tied qualifying optima, not just one solver-selected witness. Construction/evaluation/representation errors stay separate from backend limitations.
Sparse QUBO storage
QUBO stores
sprs::CsMat<W>in CSR order. Inbound rules, casts, evaluation, and outgoing reductions consume sparse coefficients directly. Coefficient accumulation, checked integer arithmetic, floating-point summation order, andQUBO::newlast-assignment semantics are preserved.For
E(x) = 3x0 + 5x0*x2 - 2x2, the three nonzero coefficients replace a 3×3 dense matrix; evaluating(1,0,1)still gives 6.For a complete 100-city unit-cost TSP construction:
This experiment constructed the QUBO and evaluated/extracted a known tour; it did not solve the 10,000-variable QUBO. CSR does not guarantee lower memory for genuinely dense matrices.
Compatibility and review scope
QUBO::matrix()returns&CsMat<W>;get(i,j)returns an owned coefficient, with zero for an unstored in-bounds entry.from_matrixand CLI--matrixstill accept dense construction input;from_sparseaccepts CSR/CSC input and normalizes storage.sprsmatrix object (storage,nrows,ncols,indptr,indices,data). Variable count comes from matrix dimensions. Old dense QUBO JSON is not supported.The broad file count largely reflects coordinated model/caller migrations. Review the lifecycle and contracts first, then mathematical/numerical changes, and finally mechanical migrations and storage changes.
Validation
make check,make mcp-test, andmake paperpassed during implementation.597ba9fc, focused QUBO tests (116), all-target Clippy, formatting, and the full coverage workflow passed.origin/main: 5,765 / 6,024 lines, 95.70%, without lowering the threshold or excluding changed files.These checks establish regression coverage and backend integration; they do not substitute for reviewing the mathematical guarantees of the changed rules.