Skip to content

Design JuMP/MOI constrained optimization integration - #103

Merged
iagoleal merged 4 commits into
mainfrom
pr-10-jump-moi-design
Jul 21, 2026
Merged

Design JuMP/MOI constrained optimization integration#103
iagoleal merged 4 commits into
mainfrom
pr-10-jump-moi-design

Conversation

@bernalde

@bernalde bernalde commented Jul 16, 2026

Copy link
Copy Markdown
Member

Summary

  • add an internal architecture document for lowering JuMP/MOI function-in-set constraints into TenSolver's native projection-constraint IR
  • keep TenSolver.Optimizer as the single JuMP entry point, backed by a TenSolver-owned full MOI model store rather than a Boolean-QUBO-only copy path
  • define finite-domain normalization, backend/objective handoff, supported constraint mappings, projection costs, fixed-variable handling, typed errors, and infeasibility results
  • retain QUBODrivers as the compatibility adapter for existing Boolean quadratic models, attributes, samples, and result behavior
  • index the design note from the repository documentation guide

This PR is design-only. It does not add functional JuMP constraint support or new dependencies.

Key decisions

  • MOI sets are the user-facing modeling abstraction; AbstractConstraint subtypes remain the compact, projection-aware lowering targets.
  • The MOI store makes no blanket ZeroOne, quadratic-objective, or DMRG assumption. The first backend adapter targets DMRG's current uniform finite-domain contract and leaves heterogeneous domains to Epic: DMRG optimization over non-Boolean domains #67.
  • TenSolver owns domains, objective/constraint normalization, backend selection, and status mapping. QUBODrivers remains a narrow Boolean-QUBO compatibility adapter; generally useful hooks may be contributed upstream without moving TenSolver-specific semantics there.
  • Two-sided weighted sums extend SumConstraint with an interval relation and one capped DFA instead of introducing a redundant constraint type.
  • Domain-specific compact patterns are selected only after domain normalization. The mapping table covers nonnegative-integer sums and domain-independent relation, all-different, exactly-one-value, and forbidden-assignment targets.
  • Add optional SpinGlassPEPS backend #44 backend selection and Polynomial objectives using JuMP API #68 polynomial objectives reuse the same stored MOI model and normalization boundary.
  • Unsupported constraints fail explicitly. There is no implicit penalty-QUBO or exhaustive feasible-assignment fallback.
  • MOI infeasibility surfaces as MOI.INFEASIBLE with zero results and no primal values.

Coordination

Validation

  • julia +release --startup-file=no -e 'using Markdown; for file in ARGS; Markdown.parse(read(file, String)); println("parsed ", file); end' docs/internal/jump_moi_constraints.md docs/DOCUMENTATION.md
  • julia +release --project=docs/ docs/make.jl local
  • julia +release --project=. -e 'using Pkg; Pkg.test()'
  • git diff --check

All checks pass locally with Julia 1.12.0.

Branch Hygiene

@bernalde
bernalde marked this pull request as ready for review July 16, 2026 23:48

@bernalde bernalde left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Maintainer review — design-only PR for #65

Docs-only change: adds docs/internal/jump_moi_constraints.md (+358) and three lines to docs/DOCUMENTATION.md. No code, no dependencies. I authored this PR, so it posts as COMMENT (GitHub rejects author APPROVE); main is not branch-protected and GitHub reports no review gate, so no formal approval is enforced — but a second maintainer's read is worthwhile for a design that will steer an implementation epic.

Acceptance criteria (#65) — all met

  • Specific enough for a follow-up epic: yes — a staged 5-part implementation plan plus a design acceptance checklist.
  • Separates native Julia API from MOI bridge: yes — "Current Boundary" and "Public API Decision".
  • Native types as lowering targets for MOI sets/bridges, incl. point-on-set: yes — "Point-on-Set Versus Projection MPOs" correctly distinguishes distance_to_set/MathOptSetDistances (numeric point projection) from TenSolver's Hilbert-space diagonal projector P, and declines the extra dependency.
  • Lists unsupported constraints + fallback: yes — explicit hard-error policy, no implicit penalty-QUBO or generic-enumeration fallback.
  • References CoTenN: yes.

Verified technical claims

Checked the load-bearing claims against the resolved dependency versions rather than taking them on faith:

  • QUBODrivers status override — correct and load-bearing. Against QUBODrivers v0.6.5, the generic AbstractSampler getter MOI.get(_, ::MOI.TerminationStatus) (src/library/sampler/wrappers/moi.jl:477) returns MOI.OTHER_ERROR for an empty sample set with nonempty metadata and does not read metadata["termination_status"]. So the doc's instruction to add a concrete TerminationStatus override is necessary, not optional — and it mirrors what QUBODrivers' own MIPSampler driver does (reads metadata["termination_status"] first). Good to have this pinned in the design.
  • Mapping-table rows all check out: sum(x)==n-1ExactlyOne(·,0); x_i+x_j<=1NotEquals([i,j],[1,1]); AllDifferent(2)Relation(!=) with >2 binary statically infeasible; SOS1sum<=1 (bond 3, correctly "at most one", all-zero feasible so not exactly-one); the x_i−x_j relation rows; and the nonnegative-integer canonicalization (sign-flip reverses <=/>=, mixed-sign rejected unless pairwise). RelationConstraint does accept :(!=) (src/constraints.jl).
  • Infeasibility status contract matches the landed #97 behavior and tensolver_status returning MOI.INFEASIBLE.

Findings

Two Nonblocking notes inline; no blocking issues.

Tests / CI

Docs-only. CI on ec343ab is green across all 10 checks (build, Documentation, and the 9-way Julia matrix). The note lives under docs/internal/ and is not in docs/make.jl's page list, so Documenter does not process it — consistent with the existing spinglasspeps_integration.md.

Merge-readiness

No blocking findings; the two inline notes are optional polish for the follow-up epic. One coordination item (already called out in the PR description): PR #46 also appends to the internal-notes list in docs/DOCUMENTATION.md; the edits are disjoint, so whichever lands second needs a one-line resync. This account cannot post a formal APPROVE on its own PR, and no approval gate is reported as required.

Comment thread docs/internal/jump_moi_constraints.md Outdated
Comment thread docs/internal/jump_moi_constraints.md Outdated
@bernalde

Copy link
Copy Markdown
Member Author

Addressed both nonblocking review notes in 12e59bc.

Changes:

  • Replaced the two-projector Interval lowering with a future SumIntervalConstraint backed by one capped, two-sided partial-sum DFA. The design now records bond upper + 2, one-sided simplification, and static-infeasibility handling, and the mapping table and implementation stages agree.
  • Replaced Documenter-only @ref syntax in the internal note with plain code spans.

Verification:

  • git diff --check
  • Parsed docs/internal/jump_moi_constraints.md with Julia's Markdown.parse
  • Independently enumerated representative weighted assignments to confirm the capped DFA accepts exactly l <= sum <= u
  • julia +1.12 --project=docs/ docs/make.jl local
  • julia --project -e 'using Pkg; Pkg.test()'
  • All current-head GitHub checks are green, including Documentation, documenter/deploy, and the nine-job Julia matrix.

No review comments were intentionally left unaddressed. The two threads remain unresolved for reviewer confirmation; there is no formal CHANGES_REQUESTED decision. The existing coordination note for PR #46 still applies if its nearby documentation-list edit lands first.

@iagoleal iagoleal left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Its mostly good to go. I've left some comments.

The most important point to keep in mind:

  • This design document should coordinate/take into account the changes in #44 (multiple backends), #105 (non-binary data) and #68 (polynomial objectives via JuMP). Even if some are not implemented here, the interface should be extensible enough to account for those changes. In particular, #105 already landed.

Comment thread docs/internal/jump_moi_constraints.md
Comment thread docs/internal/jump_moi_constraints.md Outdated
Comment thread docs/internal/jump_moi_constraints.md Outdated
Comment thread docs/internal/jump_moi_constraints.md Outdated
Comment thread docs/internal/jump_moi_constraints.md Outdated
Comment thread docs/internal/jump_moi_constraints.md Outdated
Comment thread docs/internal/jump_moi_constraints.md Outdated
@bernalde

Copy link
Copy Markdown
Member Author

Addressed the current review feedback and refreshed PR 103 against main.

Commits pushed:

  • 6ddd51f — append-only merge of main at 2a7a600
  • 988bef5 — generalize the JuMP/MOI constraint design

Main changes:

Verification:

  • Markdown parsing for both internal documentation files — passed;
  • julia +release --project=docs/ docs/make.jl local — passed;
  • julia +release --project=. -e 'using Pkg; Pkg.test()' — passed;
  • git diff --check — passed;
  • current-head GitHub CI — documentation plus all nine Julia matrix jobs passed.

No actionable comments were intentionally left unaddressed. The positive informational thread required no code change and is acknowledged separately. The formal review decision remains APPROVED; review threads remain unresolved for reviewer confirmation. PR #46 still requires a refresh check if it lands before this PR.

@iagoleal
iagoleal merged commit 2c67e16 into main Jul 21, 2026
11 checks passed
@iagoleal
iagoleal deleted the pr-10-jump-moi-design branch July 21, 2026 03:20
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.

Design JuMP/MOI constrained optimization integration

2 participants