These 36 commits are when the Protocol Buffers files have changed:
| Commit: | 0aa862c | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Unify OMMX annotations across protobuf and artifacts (#939) ## Summary - Makes OMMX domain objects the source of truth for annotations, with protobuf payloads carrying OMMX metadata fields and user extension annotations. - Projects domain annotations into OCI layer descriptors when writing artifacts, and merges legacy descriptor-only annotations back into domain objects when reading artifacts. - Updates Rust and Python SDK APIs so typed metadata is accessed through domain fields, user annotations are read-only mapping views with explicit replacement/add helpers, and raw v1 artifact add paths are removed. - Extends Instance, ParametricInstance, Solution, and SampleSet protobuf schemas and generated bindings to persist user annotations and process metadata. - Updates dataset/catalog helpers, experiments, examples, tests, and documentation to use the unified annotation model. ## Notes - Descriptor annotations remain a compatibility and OCI projection layer; protobuf/domain metadata wins when both protobuf and descriptor data provide the same OMMX-defined field. - Low-level raw artifact layer APIs still accept explicit descriptor annotations, while high-level user annotation helpers reject the reserved `org.ommx.v1.*` namespace.
The documentation is generated from this commit.
| Commit: | 71288b2 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Add format_version field and forward compatibility check (v3 port) (#838) ## Summary Ports the `format_version` forward-compatibility check from the v2 maintenance release (#835, on `dev-2.x`) onto the v3 main branch, so v3 ships with the same infrastructure for rejecting data produced by future SDKs with semantic-breaking format changes. ## Forward compatibility policy - `ommx.v1` backward compatibility is unchanged — old data remains readable by new SDKs. - Non-semantic-breaking proto additions continue to rely on protobuf's standard forward compatibility (unknown fields are ignored). - Semantic-breaking format changes bump `format_version` (major-only, single `uint32`; no minor/patch). - A single `CURRENT_FORMAT_VERSION` constant serves both sides: the SDK writes that value on all outgoing messages and accepts any `<= CURRENT_FORMAT_VERSION` on parse. Data with a higher `format_version` produces `RawParseError::UnsupportedFormatVersion` with a clear upgrade message. ## Changes - Proto: add `uint32 format_version = 100` to `Instance`, `Solution`, `SampleSet`, `ParametricInstance`. - Rust: add `pub const CURRENT_FORMAT_VERSION: u32 = 0`, the `UnsupportedFormatVersion { data_version, current_version }` variant on `RawParseError`, and a `check_format_version` helper called at the start of each of the four `Parse` implementations. All three writer sites (`From<Instance>`, `From<ParametricInstance>`, `From<Solution>` for their v1 counterparts) stamp `format_version: crate::CURRENT_FORMAT_VERSION` rather than a literal so bumping the version is a one-line change. - Tests: four new Rust tests verify that `format_version = 1` is rejected with the expected error message on each message type. ## Naming difference vs. #835 The v2 maintenance PR (#835) introduced this constant as `ACCEPTED_FORMAT_VERSION`. Review feedback on this PR pointed out that the written and accepted versions are equal by construction, so they were unified into one constant and renamed to `CURRENT_FORMAT_VERSION` here. The v2 side is left as-is (released API surface); only v3 uses the new name. ## v3-specific adjustments during cherry-pick - `rust/ommx/src/instance/parse.rs`: conflicts resolved to keep v3's `constraint_hints: None` in `From<Instance>` / `From<ParametricInstance>` (v3 absorbs hints into first-class `OneHot`/`SOS1` collections and does not currently serialize them back to the v1 proto), while adding `format_version: crate::CURRENT_FORMAT_VERSION`. - The v2 patch touched `rust/ommx/src/v1_ext/parametric_instance.rs` and the generated `python/ommx/ommx/v1/*_pb2.py*` stubs; neither exists in v3 (v1_ext removed; Python-side protobuf dependency removed), so those file changes were dropped. ## Note on the writer-side `format_version` This PR keeps `CURRENT_FORMAT_VERSION = 0` — matching the v2 maintenance release exactly. Whether v3 should bump it to `1` depends on whether any of the v3 changes constitute a semantic-breaking format change (as opposed to purely in-memory API changes). That decision is intentionally deferred to a follow-up; when it is made, flipping the constant is a single-line change and all three writer sites update together. ## Test plan - [x] `cargo test -p ommx --lib` passes (463 tests). - [x] `task python:test` passes. - [x] `task format` applied. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | e68db01 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Add format_version field and forward compatibility check (#835) ## Summary Introduces a `format_version` field on the four top-level OMMX exchange messages (`Instance`, `Solution`, `SampleSet`, `ParametricInstance`) and a corresponding reader-side check, so that future SDKs that ship semantic-breaking format changes cannot be silently misread by this SDK. This is the v2 maintenance release that must ship before v3 so that users upgrading to v3-produced data get a clear error rather than a silently-wrong parse. ## Forward compatibility policy - `ommx.v1` backward compatibility is unchanged — old data remains readable by new SDKs. - Non-semantic-breaking proto additions continue to rely on protobuf's standard forward compatibility (unknown fields are ignored). - Semantic-breaking format changes bump `format_version` (major-only, single `uint32`; no minor/patch). - Each SDK declares an `ACCEPTED_FORMAT_VERSION` constant. Reading data with a higher `format_version` produces `RawParseError::UnsupportedFormatVersion` with a clear upgrade message. ## Changes - Proto: add `uint32 format_version = 100` to `Instance`, `Solution`, `SampleSet`, `ParametricInstance`. Field number 100 is reserved across all four messages for future coherence with v3. - Rust: add `pub const ACCEPTED_FORMAT_VERSION: u32 = 0`, a `UnsupportedFormatVersion { data_version, accepted_version }` variant on `RawParseError`, and a `check_format_version` helper invoked at the start of each of the four `Parse` implementations. - Tests: four new Rust tests verify that `format_version = 1` is rejected with the expected error message on each message type. ## Test plan - [x] `cargo test -p ommx --lib` passes (429 tests). - [x] `task rust:test` passes (including doctests). - [x] `task python:test` passes (pyright + ruff + pytest for main package and all adapters). - [x] `task format` applied. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
| Commit: | 81caf0f | |
|---|---|---|
| Author: | Hiromi Ishii | |
| Committer: | GitHub | |
Introduces `NamedFunction` to instance, solution, sample_set, and parametric_instance (#748) ## Summary Introduces `NamedFunction` to track and evaluate named mathematical functions within optimization instances. This allows users to define auxiliary functions (e.g., costs, penalties, metrics) that are evaluated alongside the main objective and constraints. ## Changes ### Protocol Buffers - Add `NamedFunction`, `EvaluatedNamedFunction`, `SampledNamedFunction` messages - Integrate into `Instance`, `ParametricInstance`, `Solution`, `SampleSet` - Fix typos in `constraint.proto` ("constains" → "contains", "evalute" → "evaluate") ### Rust SDK **New Types:** - `NamedFunction`: A named function with ID, name, subscripts, parameters, and a `Function` body - `EvaluatedNamedFunction`: A named function evaluated at a specific state - `SampledNamedFunction`: A named function evaluated across multiple samples **Instance Integration:** - Add `named_functions` field to `Instance` and `ParametricInstance` - Support in `evaluate()`, `partial_evaluate()`, `evaluate_samples()` - Builder methods: `add_named_function()`, `get_named_function_by_name()` **Solution Integration:** - Add `evaluated_named_functions` field - Extract methods: `named_function_ids()`, `named_function_names()`, `extract_named_functions()`, `extract_all_named_functions()` **SampleSet Integration:** - Add `named_functions` field - Extract methods similar to Solution - **API Change**: Deprecate `SampleSet::new()` in favor of `SampleSet::builder().build()` (consistent with `Solution`) - Add `SampleSetBuilder::build_unchecked()` for construction without validation - Add key/id consistency validation **Invariants:** - `named_functions` keys must match value's `id()` - `named_functions` may contain fixed or dependent variable IDs (like `removed_constraints`) - Variable IDs in `named_functions` must be registered in `decision_variables` - **Important**: `named_functions` are NOT included in the "used" set calculation (similar to `removed_constraints`) ### Python SDK - Add `NamedFunction`, `EvaluatedNamedFunction`, `SampledNamedFunction` classes - Add `__repr__`, `__copy__`, `__deepcopy__` methods for all named function classes - Add `used_decision_variable_ids` getter to `EvaluatedNamedFunction` and `SampledNamedFunction` - Add `named_functions_df` property to `Instance`, `ParametricInstance`, `Solution`, `SampleSet` - Add `NamedFunction._as_pandas_entry()` for DataFrame integration - Integrate with `Instance`, `Solution`, `SampleSet` ## Breaking Changes - `SampleSet::new()` is now deprecated (use `SampleSet::builder().build()`) ## Test Plan - [x] Rust unit tests for NamedFunction evaluate/partial_evaluate - [x] Rust tests for SampleSet extract methods - [x] Rust test for named functions with fixed/dependent/irrelevant variables - [x] Property-based tests for Instance with NamedFunction - [x] SampledNamedFunction serialization round-trip test - [x] Python integration tests 🤖 Generated with [Claude Code](https://claude.ai/code) --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Toshiki Teramura <toshiki.teramura@gmail.com>
| Commit: | 7858e2a | |
|---|---|---|
| Author: | NY57 | |
| Committer: | GitHub | |
Add the `.sense` property to `ommx.v1.Solution` and `ommx.v1.SampleSet`. (#530) Co-authored-by: Toshiki Teramura <toshiki.teramura@gmail.com>
| Commit: | d6a63f2 | |
|---|---|---|
| Author: | Hiromi Ishii | |
fix: updates docs
| Commit: | d6595be | |
|---|---|---|
| Author: | Devin AI | |
| Committer: | Devin AI | |
Fix buf.yaml version and format protobuf files Co-Authored-By: h.ishii@j-ij.com <h.ishii@j-ij.com>
| Commit: | b6f0cd2 | |
|---|---|---|
| Author: | Devin AI | |
| Committer: | Devin AI | |
Add support for k-hot constraints Co-Authored-By: h.ishii@j-ij.com <h.ishii@j-ij.com>
| Commit: | e540d20 | |
|---|---|---|
| Author: | Hiromi Ishii | |
| Committer: | GitHub | |
Supports SOS1 Detection (#301) This adds the following things: - [x] Adds slots for SOS1 constraints - [x] Adds SOS1 support in PySCIPOpt We DID NOT add SOS1 support for `Python-MIP` for the time being.
| Commit: | 4a651ee | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Deprecate `feasible_unrelaxed` in `*.proto`, and introduce `feasible_relaxed` (#280) - The meaning of `feasible` changed - Before this PR, `feasible` field in `ommx.v1.Solution` and `ommx.v1.SampleSet` means the feasibility about the remaining constraint in `ommx.v1.Instance`, ignoring `removed_constraints` in `ommx.v1.Instance` - After this PR, previous `feasible` field is renamed into `feasible_relaxed`, and `feasible` field means unrelaxed feasibility, i.e. it also looks `removed_constraints`. In other words, `feasible_unrelaxed` is renamed into `feasible`. - The `feasible_unrelaxed` field in `*.proto` becomes deprecated. - On API level, `feasible_unrelaxed` is kept.
| Commit: | 2754571 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Add `decision_variable_dependency` to represent polynomial dependency between decision variables (#257) Ready for binary encoding of integer variables. - When an integer variable $x \in [0, 3]$ is binary encoded as $x = b_1 + 2 b_2$ with $b_1, b_2 \in \{0, 1\}$, $x$ will disappear from objective function and constraints. - Thus, $x$ is not passed to solver which only solve with $b_1$ and $b_2$. So we have to reconstruct $x$ from $b_1$ and $b_2$, but how? - `decision_variable_dependency` field in `ommx.v1.Instance` stores this relation, i.e. $x = b_1 + 2 b_2$ as a set of the ID of $x$ and a polynomial $b_1 + 2 b_2$.
| Commit: | 47d2894 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
`feasible_unrelaxed` field representing the feasibility including the removed constraints (#251) - As removed constraints has been introduced in #189, this PR adds `feasible_unrelaxed` field in `ommx.v1.Solution` and `SampleSet` to represent the `State` is feasible in terms of removed constraints. - `Instance.relax_constraint` and `Instance.restore_constraint` has been exposed in Python SDK
| Commit: | fc54992 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
OMMX Adapter for OpenJij, introduce `ommx.v1.SampleSet` (#236) OMMX Message Schema -------------------- - Introduce `ommx.v1.SampleSet`, `ommx.v1.Samples`, its components including `SampledValue`. Python SDK ---------- - Add `ommx-openjij-adapter` as a reference for QUBO sampler Rust SDK ---------- - Add `Evaluate::evaluate_samples`
| Commit: | e2bba8c | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Removed constraints (#189) - Introduce `ommx.v1.RemovedConstraint` message - This consists of `ommx.v1.Constraint` and removed reason, and stored in `ommx.v1.Instance` and `ommx.v1.ParametricInstance`. - This is created when the constraint is relaxed. This PR introduces new API `Instance::relax_constraint` to create a relaxed instance, and revert it with `Instance::restore_constraint`. - Removed reason is stored as short string `removed_reason` and string-string pair `removed_reason_parameters` because these are designed for human-readability rather than API re-usability - `Instance::evaluate` converts `RemovedConstraint` into `EvaluatedConstraint` as usual `Constraint`s. These are merged into `ommx.v1.Solution` since users would also want to show the breakage of removed constraints with non-removed constraints
| Commit: | 6362b56 | |
|---|---|---|
| Author: | Hiromi Ishii | |
| Committer: | GitHub | |
feat: adds `constraint_hints` field to instance and provide a scheme for one-hot constraints (#180) This PR adds the following field to `ommx.v1.instance`: - `constraint_hints`: A list of constraint hints to be used by solver to gain performance. They are derived from one-or-more constraints in the instance and typically contains information of special types of constraints (e.g. one-hot, SOS, ...). This is expressed as a `ConstraintHint` messag, which is a pair of originating constraints and parameters specific to each special constraint types. Currently, there is only one constraint type supported: `OneHot`, which expresses a one-hot constraint. --------- Co-authored-by: Toshiki Teramura <toshiki.teramura@gmail.com>
| Commit: | 36d227d | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
`substituted_value` in `ommx.v1.DecisionVariable` (#173) This field stores the value within the `partial_evaluate`
| Commit: | e6099be | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
ParametricInstance (#146) - Introduce `ommx.v1.ParametricInstance` message to represent QUBO without fixing penalty weight.
| Commit: | 912bf96 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Revert "`dual_variable` and `penalty_weight` in `Constraint` message for QUBO (#144)" (#149) This reverts commit a0d0707a01c953988381b76243b7c18ef8b3586c #144 - The strategy for implementing QUBO and PUBO conversion has been changed to use #146, which conflicts with #144
| Commit: | a0d0707 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
`dual_variable` and `penalty_weight` in `Constraint` message for QUBO (#144) # Summary - Add optional fields, `dual_variable` and `penalty_weight` in `Constraint` message. - This will be used in #143 to create unconstrained problem. #143 will support two way to create QUBO and PUBO, penalty method and augmented Lagrangian method # Detail For a problem $$ \begin{align*} \min & f(x) \\ \text{s.t.} & g(x) = 0 \end{align*} $$ - Penalty method try to minimize $f(x) + \rho |g(x)|^2$, where $\rho$ is called penalty weight. - Augmented Lagrangian method try to minimize $f(x) + \lambda g(x) + \rho |g(x)|^2$, where $\lambda$ is current dual variable and $\rho$ is also a penalty weight. `dual_variable` field is intended to store $\lambda$, and `penalty_weight` stores $\rho$ in this sense.
| Commit: | 64ecf6e | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Add `subscripts` field into `Constraint` message (#92) Split from #88 It is rather natural also for `Constraint` message to use `subscripts` for integer parameter and `parameters` for string parameters as `DecisionVariable` does.
| Commit: | 7dab7ef | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Store dual variable in `EvaluatedConstraint` (#78) - `EvaluatedConstraint.dual_variable` to store Lagrangian dual variables - `ommx_python_mip_adapter.solve` stores the dual variable if `mip.Constr.pi` exists.
| Commit: | b598637 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Introduce `ommx.v1.Result` and `Optimality` enum (#77) - ⚠️ `option bool optimal` is encoded into single `bool` in Python, i.e. `None` and `False` are not distinguished. Instead, this PR introduces `Optimality` enum to explicitly distinguish them. - To represent the error case of solvers, `ommx.v1.Result` has been introduced. `ommx_python_mip_adapter.solve` returns this object.
| Commit: | 5411563 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Flatten descriptions of decision variables and constraints (#71) - `DecisionVariable.Description` and `ConstraintDescription` are flattened. - New `description` fields are added to `DecisionVariable` and `Constraint` to write long human-readable description - `subscripts` are split from `parameters` in `DecisionVariable`
| Commit: | 193d2d8 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Add document for quadratic function (#46) Resolve #45
| Commit: | 0b69c90 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Store decision variable IDs used to evaluating constraint (#39)
| Commit: | 57bab47 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Rename `RawSolution` to `State` (#38) - `RawSolution` is renamed into `State` - `SolutionList` and `RawSolutionList` are removed
| Commit: | d5bfb9f | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Store descriptions of decision variables and constraints in Solution (#37) - Move `EvaluatedConstraint` message from `Solution.*` to `ommx.v1.*` - Move `Constraint.Description` into `ommx.v1.ConstraintDescription`, and revise `forall` field into `parameters` which stores string-string map instead of `repeated int64` - Add `decision_variables` in `Solution` message
| Commit: | 1ed91b1 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Move feasible and optimal fields to Solution message instead of RawSolution (#36) Fix of #32, split from #34 - Make `RawSolution` "pure" solution state
| Commit: | 209d05c | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Add evaluated values in `Solution` message, rename old message as `RawSolution` (#32) - Rename current `Solution` into `RawSolution` - New `Solution` is added. This contains `RawSolution` and the objective and constraints values evaluated with the `RawSolution`. - Evaluated constraints consist of evaluated value of `Function` and its equality, not the violation of constraint. - For example, it has different meaning if a constraint `f(x) = 0` is violated as `f(x) = 1` and `f(x) = -1`. We should keep this difference on `Solution` level, and thus it is stored as a pair (`1`, `=0`) or (`-1`, `=0`).
| Commit: | e0f5114 | |
|---|---|---|
| Author: | NY57 | |
| Committer: | GitHub | |
Add `sense` field to `Instance` (#28) # 変更点 OMMX::Instanceが意味する最適化問題が最小化問題であるか最大化問題であるかが判別できないという課題があった為、senseを追加しました。 # 確認事項 こちらの変更後、Pythonパッケージをv0.1.2として、Rustクレートをv0.1.1としてリリースしても良いでしょうか?(バージョニングは適切でしょうか?) --------- Co-authored-by: Toshiki Teramura <toshiki.teramura@gmail.com>
| Commit: | 148ca07 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Brush up `ommx::v1::Instance` design in Rust side (#10) - Add `decision_variables` in `Instance` message - Add `Bound` message in `DecisionVariable` message - Integrate `SparseMatrix` message into `Quadratic` since only this message uses it
| Commit: | 7c59e07 | |
|---|---|---|
| Author: | NY57 | |
| Committer: | GitHub | |
Prototyping OMMX::Result (#11)
| Commit: | 3ac3e16 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
`Instance` message (#5)
| Commit: | e3babc1 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Revise directory structure of `proto` based on `buf` default settings (#4) - Reconstruct `proto/` directory as `buf` does - `ommx.v1` namespace is created. - Setup workflow to check `proto/**/*.proto` files using `buf` - Breaking change check is omitted since it is not released.
| Commit: | f55391b | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Schema for decision variable attributes, better protogen (#2)
| Commit: | 2b30bb0 | |
|---|---|---|
| Author: | Toshiki Teramura | |
| Committer: | GitHub | |
Setup Rust workspace and GitHub Actions (#1)