Skip to content

Add binary decision ILP to SAT and fix solution validators - #1218

Merged
GiggleLiu merged 22 commits into
issue-1213-direct-qubo-phase4from
feat/binary-ilp-to-sat
Oct 29, 2026
Merged

GiggleLiu merged 22 commits into
issue-1213-direct-qubo-phase4from
feat/binary-ilp-to-sat

Conversation

@isPANN

@isPANN isPANN commented Oct 23, 2026

Copy link
Copy Markdown
Collaborator

Stacked on #1217. Base: issue-1213-direct-qubo-phase4.

Adds a registered Decision<ILP<bool, i64>> → Satisfiability reduction using binary adders, comparisons, and Tseitin clauses. It encodes signed constraints and the objective threshold, recovers the original binary assignment from a satisfying witness, and supplies parameter bounds and a manual proof. DecisionILP also gains construction metadata and a fixed ILP solver pipeline.

For example, with x₀ + x₁ + x₂ = 1 and objective 3x₀ + 2x₁ + x₂, minimizing with bound 1 yields [0, 0, 1]; bound 0 produces an unsatisfiable SAT instance. Maximizing with bound 3 yields [1, 0, 0]; bound 4 is unsatisfiable. This is a decision reduction; it adds no Turing edge and does not claim to merge the optimization problems into one mutually reducible class.

Also fixes MaximalIS and MinimumVertexCover public validators accepting truncated or oversized assignments. For a two-vertex edge, [true] previously passed the public validators while evaluate() rejected its length; both APIs now reject it. Removes redundant timetable reconstruction, internal index clamping, panic wrappers, and implementation-name tests. Existing reduction tests now check recovered witnesses and known optimal values instead of copied fields.

Validation:

  • make check passes: formatting, Clippy across all targets/features, and workspace tests including ignored tests and doctests.
  • The two existing validator tests failed on truncated assignments before the fix and pass afterward.
  • SAT encoding checks exercise both objective senses, feasible/infeasible thresholds, 432 pinned binary assignments with signed rows, and empty/full-width integer cases.
  • Paper build and persisted CLI reduce/solve workflow passed before the final cleanup; coverage and paper build were not rerun after that cleanup.

Each ILP rule's num_nonzeros upper bound was num_constraints * num_vars,
a dense-matrix bound that the corpus measured at under half of its
prediction on 55 rules. Derive the bound from each reduce_to's constraint
families instead, summing the terms each family contributes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
isPANN and others added 2 commits October 27, 2026 10:10
Canonical examples are sparse, so a constraint family missing from a
per-family nonzero count can go unnoticed. Reduce dense instances of five
rules with the most constraint families and require the measured count to
stay within the declared bound.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
StaffScheduling -> DecisionQUBO assumed 63 bits per worker count, and
SequencingWithReleaseTimesAndDeadlines -> DecisionQUBO assumed every task
may start anywhere in [0, time_horizon]. Neither source exposed the
quantity the construction actually depends on, so the bounds ran three to
four orders of magnitude above the corpus measurements.

Add num_workers_bits to StaffScheduling and max_start_slots to
SequencingWithReleaseTimesAndDeadlines, state both QUBO bounds in them,
and declare the new fields in the two rules that target these models.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
isPANN and others added 11 commits October 27, 2026 11:16
The sparse-support test kept the 63-bit StaffScheduling budget, so a
regression to the old formula would still pass. Tighten it to the new
prediction, add an SWRTD case, and restate both proofs' size bounds in
the new parameters, including the two incoming rules that declare them.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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>
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>
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 GiggleLiu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agentic Review Report

Reviewed head 0daa9a8265aefe40983beeba0464f8feea8c3316 against its stacked base 3d3b020c0d93f5e27ecce98eaf148321a7eced9d.

Structural and semantic

No blocking findings in this PR's changes. Both reduction endpoints have value Or; the objective sense is handled by Extremum::meets_bound. Signed normalization, constant rows, ripple adders, gate clauses and the complemented greater-than comparator preserve each binary assignment. Row normalization merges duplicate variables before encoding. Checked positive/negative totals bound the adder width by 64 and justify the declared variable, clause and literal bounds. Extraction validates the complete SAT witness before projecting its first source coordinates.

The public MaximalIS and MinimumVertexCover validators now check assignment length before indexing. The removed Lehmer clamp is internal to enumeration with valid dimensions. Decision construction and the ILP pipeline use existing registry mechanisms.

The new reference is traceable to the authors' paper, Translating Pseudo-Boolean Constraints into SAT. The proof in this PR supplies its own normalization, equivalence and size derivations.

Quality and verification

Built the exact PR head locally. All four new binary-ILP-to-SAT tests passed, including 432 signed assignment comparisons, both objective senses, infeasible bounds, empty rows, full-width coefficients, malformed witnesses and rejected arithmetic overflow. The complete library test executable then passed all 6,319 tests. This includes inherited stack changes and is not independent approval of those changes.

Feature test

Built the development CLI in the isolated checkout. Created and inspected the canonical DecisionILP instance, solved it with brute force, persisted its direct SAT route and reduction bundle, and solved the bundle through the SAT ILP pipeline. Both returned [0, 0, 1] and Or(true). No global CLI installation was changed.

Findings and disposition

No new blocking finding. Hold the PR until its prerequisite PRs are corrected and merged; this review does not authorize merging an unreviewed or defective base branch into main. No GitHub CI was recorded on this stacked PR at review time.

GitHub PR audit

GATE: PASS

  • harm.secrets: OK. No credentials or private data introduced.
  • harm.dangerous-files: OK. Source, tests and manual changes only.
  • harm.generated-artifacts: OK. No generated exports or build outputs.
  • harm.cache: OK. No caches committed.
  • harm.debug-leftovers: OK. No temporary probes in production code.
  • pr.description-quality: OK. Encoding, validator repairs and verification limits are described.
  • pr.traceable: OK. Purpose and dependency on #1217 are explicit.

Declare exact parameter counts that constructions always produce
Tighten ILP num_nonzeros bounds to per-constraint counts
Tighten StaffScheduling and SWRTD QUBO size bounds

@GiggleLiu GiggleLiu left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agentic Review Report: stack consolidation

Approved current head b84842c747657d8238bc6cbb89e341f873a66eab for merging into issue-1213-direct-qubo-phase4 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.

@GiggleLiu
GiggleLiu merged commit 2cd3218 into issue-1213-direct-qubo-phase4 Oct 29, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants