Repository navigation
Declare exact parameter counts that constructions always produce - #1224
Conversation
The bound K counts selected columns, but try_new accepted any negative value. Such an instance panicked in parameters(), whose bound must fit u64, and its ILP reduction cast the bound with `as usize`. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The corpus measured 81 non-trivial upper-bound fields at exactly their prediction on every instance. Of those, 46 fields in 30 rules are exact by construction: every row family and variable block is emitted unconditionally, the source invariants (simple graphs, exactly-K clauses, n divisible by 3, 1 <= k <= n) rule out merged or dropped terms, and no early return builds a different target. The rest stay upper bounds: degenerate-input shortcuts, data-dependent zero coefficients or cancelled literals, and QUBO entries where penalty and objective terms can cancel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
KSatisfiability<K3>::new_allow_less admits clauses with fewer than three literals, so 3SAT -> KClique num_vertices and 3SAT -> DecisionMVC num_edges shrink below their formulas. Return both to upper_bound, pin the relations with short-clause instances, and lay out the transform declarations by nesting depth. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agentic Review ReportReviewed head Structural
Semantic: adversarial check of every promoted fieldFor each
Empirical probe. I ran a temporary Tests run ( Quality
Feature testI skipped FindingsCritical: none. I found no accepted source instance that violates any promoted Important
Minor
|
The exact claims for HamiltonianCircuit, MaximalIS, MinimumDominatingSet, MaximumMatching, Kernel, PartitionIntoPathsOfLength2, PartitionIntoPerfectMatchings and PartitionIntoCliques were checked only on canonical examples. Pin them on empty, path and complete graphs with up to three vertices, k = 1 and k = n, and antiparallel arcs. Also promote MinimumVertexCover -> EnsembleComputation num_subsets, one subset per edge, and convert the ConsecutiveOnesSubmatrix bound with try_from now that construction keeps it nonnegative. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Addressed the review in 0318bfd:
🤖 Generated with Claude Code |
MaxCut<SimpleGraph, i64> accepts negative weights, but the rule rejected
them, so every planned path through it (for example Max2SAT -> MaxCut ->
MinimumMatrixCover) failed on ordinary inputs. Replace each negative edge
{u, v} by an auxiliary vertex joined to v with |w| + 1 and to u with |w|:
every maximum cut separates the auxiliary vertex from v, so the gadget
shifts the cut by the constant 2|w| + 1 and preserves maximum cuts.
Extraction drops the auxiliary bits; num_rows becomes an upper bound.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- ConsecutiveOnesSubmatrix stores its column-count bound as usize, so serde and the CLI reject negatives by type and the model and ILP rule drop their conversions. - The MaxCut -> MinimumMatrixCover gadget computes |w| + 1 as 1 - w with one checked subtraction; module docs and the paper's duplicate extraction paragraph now describe the auxiliary vertices. - The PartitionIntoPathsOfLength2 comment states why its counts are exact. - The degenerate-graph test covers every valid k; transform layouts are consistent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
KSatisfiability<KN> was Satisfiability under another name: it checked no clause width and its only edges were identity casts into and out of it. Every path from K2 or K3 paid an extra hop through it. - Drop the KN variant; K2 and K3 now reduce directly to Satisfiability and K3 is the default variant. - Remove new_allow_less/try_new_allow_less. K2 and K3 always hold exactly K literals per clause, matching what serde and the CLI already enforced. - Delete the short- and empty-clause branches these constructors forced on 3-SAT rules, and declare 3SAT -> KClique num_vertices and 3SAT -> DecisionMVC num_edges exact again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e text SAT -> NAE turns every three-literal clause into a four-literal one, so the MonochromaticTriangle vertex, edge and triangle counts are equalities and its two-literal branch was dead. Also remove leftover short- and empty-clause wording and dead padding in OneInThree, QuadraticCongruences and Kernel. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Add a FixedK sub-trait implemented by K1..K5, and bound KSatisfiability and the SAT/K-SAT results by it, so KSatisfiability<KN> no longer type-checks instead of failing at construction. - Register each K-SAT aggregate mapping inside the macro that registers its witness edge, and take the SAT -> K-SAT clause width from the type. - Allocate CyclicOrdering's fresh padding variables with allocate_many. - Drop leftover braces in two tests and a stale QuadraticCongruences note. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Removing the KSatisfiability KN variant does not need a new variant trait. Keep KSatisfiability bounded by KValue with the runtime width check. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GiggleLiu
left a comment
There was a problem hiding this comment.
Agentic Review Report
PR #1224: Declare exact parameter counts that constructions always produce
Review date: 2026-10-29. Fresh-context read-only review of f95447ad2f1de5d37c020ad6ffc119460adebaff...ef18c7635bb68aa2bd36b41f995ed3c89c3db9db. Used the PR's own stack base, not origin/main. Local implementation evidence is diff-1224.patch; GitHub context is context-1224.txt in this directory.
Verdict: HOLD — newly accepted negative MaxCut weights can construct a target whose optimum cannot be evaluated.
Structural and semantic review
Reviewed all 45 promoted parameter fields across 29 rules, their constructor paths and degenerate cases, tests, and manual changes against exact #1222. Exact promotions are justified where the code allocates unconditional variable/constraint storage; fields affected by coefficient cancellation or optional terms remain upper bounds. SimpleGraph/SimpleDigraph invariants eliminate duplicate edges and loops where exact degree-count formulas require that property. Checked empty graphs, n=1 and n=2 cases, early infeasible targets, and k=1 partition parameters.
The ConsecutiveOnesSubmatrix bound changes from i64 to usize and rejects negative serde inputs, matching the nonnegative cardinality meaning. This is a public type change and should be disclosed separately from the user's acceptance of #1225's API break; that acceptance alone is not evidence of a decision on this constructor. No independent semantic error was found in this change.
The new MaxCut negative-edge gadget is algebraically sound over unbounded integers. For w<0, an auxiliary spin has a link of |w|+1 to one endpoint and |w| to the other; the stronger anchor forces it opposite the first endpoint in any optimum. Projecting source spins preserves max-cut optima up to a constant. However, representability of each link does not guarantee representability of the complete symmetric objective. The new supported negative-weight domain exposes the concrete failure below.
Quality review
Metadata promotions were traced to actual row/column construction rather than a finite tightness corpus. MaxCut tests include modest signed weights and reject weights whose anchor itself overflows, but omit signed weights whose links fit while the full matrix energy overflows. The added arithmetic guard only checks 1−w and therefore cannot establish the required target evaluation contract.
Feature tests and verification limits
Compiled and executed a standalone probe with problemreductions = { path = "/tmp/pr-review-1224", features = ["example-db"] } at exact head ef18c76. Build used two jobs, no debug info or incremental artifacts, and the shared local target directory. The probe uses the actual source/target constructors, ReduceTo implementation, evaluators, and BruteForce solver; it is not a reimplementation.
The source brute-force optimum is Ok(Max(Some(0))). Reduction succeeds. The target's mathematically optimal witness returns an IntegerOverflow evaluation error, and target brute-force solve also returns an evaluation error. Full output is numeric-probe.log; probe source is /tmp/pr-review-numeric-probe/src/main.rs.
Exact #1224 test-suite compilation was intentionally skipped after confirming the blocker so the shared build slot could validate an independent merge candidate. Own-base git diff --check passed. No current GitHub CI results were visible in the collected stack metadata.
Findings (severity order)
Critical — the negative-edge gadget can produce an unevaluable optimum
src/rules/maxcut_minimummatrixcover.rs:92-105 checks only the individual anchor coefficient and then returns the target without checking its aggregate arithmetic range.
Reproducer: MaxCut<SimpleGraph, i64> with 2 vertices, one edge (0,1), and weight -3000000000000000000. Every source configuration evaluates successfully, and source optimum is 0 when both endpoint bits agree. Reduction currently succeeds and constructs:
[[0, 0, 3000000000000000000],
[0, 0, 3000000000000000001],
[3000000000000000000, 3000000000000000001, 0]]
The target optimum has both endpoint spins equal and the auxiliary spin opposite, e.g. [true,true,false]. Its full symmetric quadratic form is -12000000000000000002, below i64::MIN. Row-major checked evaluation accumulates -3000000000000000000, -6000000000000000001, -9000000000000000001, then underflows. Native output:
maxcut source optimum [false, false] Ok(Max(Some(0)))
target optimum evaluate Err(IntegerOverflow("summing matrix-cover objective"))
target solve Err(Evaluation(IntegerOverflow("summing matrix-cover objective")))
Before this PR the reduction rejected negative weights, so this failure is newly introduced support, not merely an unrelated preexisting positive-weight edge case. Check complete target coefficient/prefix magnitude bounds in widened arithmetic and return a typed ReductionError when a safe i64 target cannot be represented (or normalize with a proved optimum-preserving construction). Add this signed single-edge regression. The inherited #1214 interval allocation panic also remains, but is not attributed to this diff.
GitHub PR Audit — #1224
GATE: PASS
Harm signals (blocking)
- harm.secrets (
security.no-secrets): OK — inspected added text; no credential/key/token or private-data additions found. - harm.dangerous-files (
git.harm-signals): OK — changed files are scoped source, tests, and manual material; no conflict markers, unexplained binaries/archives, scratch files, or local configuration. - harm.generated-artifacts (
code.generated-artifacts): OK — no generated example/schema/reduction-graph exports or build/dependency outputs are committed. - harm.cache (
code.generated-cache): OK — no cache directories added. - harm.debug-leftovers (
code.debug-leftovers): OK — no debugger, debug print, temporary probe, or WIP instrumentation in added production code.
PR legibility (advisory)
- pr.description-quality (
github.pr-description-quality): OK — body describes scope, purpose, validation, and limits; comments and reviews were read withgh-axi pr view --full --comments --reviews. - pr.traceable (
github.prs-traceable): OK — purpose and validation are stated and the series/issue context is identifiable.
Harm gate PASS does not clear correctness findings. No tracked file, commit, remote branch, PR comment, review, or merge was modified by this reviewer.
GiggleLiu
left a comment
There was a problem hiding this comment.
The objective-overflow blocker is fixed at 52bd171. Every constructed coefficient is nonnegative, so the complete coefficient sum is attained by an all-equal assignment and bounds every signed evaluation prefix. Checking that sum before construction gives the required i64 range guarantee. Independent review, all 15 MaxCut-to-matrix tests, make check (7,142 tests, formatting, and Clippy), and CLI regressions pass. The negative-weight reproducer now returns typed IntegerOverflow, while the largest safe positive and negative single-edge cases still round-trip. Fresh required CI will run on the combined stack against main.
[Critical] Remove KSatisfiability KN variant and short-clause constructors
GiggleLiu
left a comment
There was a problem hiding this comment.
Agentic Review Report: stack consolidation
Approved current head 3372d66b5b642ae6c99ccb42c61efd7e18477148 for merging into fix/ilp-nonzeros-bounds only. This contains the previously reviewed changes and, where applicable, the preceding recorded backend merges. The numeric blockers in #1214 and #1224 are fixed and reviewed at 2226ebec4 and 52bd171a0.
Rechecked inline comments, submitted reviews, PR conversation, linked-issue comments, and Codecov comments. No new unaddressed material issue. Harm gate remains PASS from the independent reviews. The old roadmap draft/hold instructions predate the user's current authorization; deferred rules and #1219/#1220/#1221 remain excluded.
The repaired aggregate passed 7,194 native tests, formatting, all-target/all-feature Clippy, and make paper at d96e7c8b8; the final website gate subsequently passed all 336 browser cases at 77774797e. These are aggregate gates, including the separately reviewed integration fixtures, not a claim that this branch head was independently retested unchanged. Required main-branch CI remains pending. This feature-branch merge preserves the individual PR record.
Summary
The corpus accuracy run (
pred-validation-corpus/scripts/verify_parameters.py) found 81 non-trivialupper_boundfields that equal their prediction on every corpus instance. Matching on the corpus doesn't make a field exact: SpinGlass → MaxCut, for example, adds its ancilla vertex only conditionally. So I read each construction and promoted a field only when every input produces exactly that count.Promoted, 45 fields in 29 rules. In each case:
Kept as upper bounds:
x,¬xin a clause), IntegerKnapsack (oversized items), PartitionIntoPerfectMatchingsnum_nonzeros(k = 1zeroes a coefficient), MVC → MinimumWeightAndOrGraph, SAT → NAE / IntegralFlowHomologousArcs (repeated literals)new_allow_less)num_vertices, 3SAT → DecisionMVCnum_edges(pinned bythree_sat_contracts_cover_short_clauses)num_quadratic_termsAlso in this PR
ConsecutiveOnesSubmatrixaccepted a negative bound K.pred inspectthen panicked, becauseboundmust fit u64, and the ILP rule cast the bound withas usize. The model now rejects a negative bound at construction (8523caa).MaxCut → MinimumMatrixCover with negative weights.
MaxCut<SimpleGraph, i64>accepts negative weights, but the rule rejected them, so planned paths through it failed. The corpus path run found 44 failures, for example DecisionMax2SAT → MaxCut → MinimumMatrixCover.{u, v}now becomes an auxiliary vertext, with weight|w| + 1tovand|w|tou. Every maximum cut separatestfromv, so the gadget shifts the cut by the constant2|w| + 1and preserves maximum cuts.num_rowsbecomesupper_bound num_vertices + num_edges.i64::MINoverflow. The previously failing paths now measure cleanly.Verification
cargo test --workspacepasses, and so does clippy. Every exact field equals the measured value on the canonical examples (every_executable_parameter_formula_matches_a_constructed_target).num_verticesto UpperBound. That pin dates from beforeSimpleGraphrejected repeated edges (394f3df), so it now asserts Exact.Stacked on #1222.
🤖 Generated with Claude Code