# What is OMMX?

OMMX (Open Mathematical prograMming eXchange) lets you describe **what you want to solve** separately from **how you solve it**. You can revise the formulation you send to a solver and still judge its candidates by the constraints and objective of the original problem.

A modeling tool expresses your requirements. OMMX provides a common data format and Python and Rust SDKs to transform the problem and evaluate candidates. An adapter connects that representation to the solver or sampler that searches for candidates. Implementing transformations on this common representation makes them reusable across modeling tools and solving methods.

## Why use OMMX today?

Until the 3.0.0 stable release, both this Book and the API Reference describe `main`. The [installation guide](./getting_started/install.md) covers the latest published prerelease and installation from `main`; use `main` for features that have not been released yet. The current implementation supports the following tasks on a common problem representation.

| Your goal | What OMMX can handle | What you decide |
|---|---|---|
| Try a different formulation or solver | Supported special-constraint conversions and integer encodings; exchange with backends through adapters | The method, permitted transformations, and solver settings |
| Check whether a candidate is usable | Evaluate variable domains, constraints, and the objective; reconstruct original variable values from information retained by supported transformations | How to model the requirements of your application and whether to accept the candidate |
| Pass problems and results to another process | Read and write a common format; save and share Artifacts; record settings and results in Experiments | What to record and what to compare |

You choose the requirements the model must satisfy, including when an AI tool helps write the model. You can use the SDK just to check a candidate from your own algorithm.

## Evaluate a candidate you already have

A production line can make up to 100 units per hour, but only 60 in reduced mode. A plan that calls for 65 units in an hour of reduced operation violates that limit, whether the plan came from a solver or from a colleague. OMMX can evaluate either plan against the same problem. [Evaluate candidates and interpret results](./user_guide/evaluate_and_interpret.md) explains how to distinguish checking this rule, checking the whole model, and establishing optimality. The {class}`Solution Reference <ommx.Solution>` shows how to evaluate a candidate and inspect the result.

## Separate a problem's meaning from its representation for solving

You can express the reduced-mode limit as an **indicator constraint**, which applies a condition when a binary variable takes a specified value. The {class}`PySCIPOpt Adapter <ommx_pyscipopt_adapter.OMMXPySCIPOptAdapter>` can pass this linear indicator directly to SCIP. You can also use the known upper bound on output to express the same rule as an ordinary inequality and try that formulation with SCIP. In either case, the planner specifies the production rule once. [Transform a problem and connect it to a solving method](./user_guide/transform_and_solve.md) derives the inequality and explains which guarantees to check for other transformations.

## Accumulate transformation techniques on a common representation

Implementing preprocessing and transformations against a common representation lets modeling tools and solving methods reuse them. A new method can connect its inputs and outputs to that representation and benefit from the techniques already available. This is why OMMX develops both data exchange and shared processing of that data.

Today, OMMX supplies specific operations and policies for selecting supported transformations and evaluating candidates. For example, it can {meth}`tighten variable bounds using constraints <ommx.Instance.tighten_bounds_simultaneously_once>`, but this operation performs one update; it does not automatically optimize an entire preprocessing workflow.

The development direction is to combine these techniques and select or repeat them according to a problem's structure. Accumulating both individual techniques and the knowledge of when to apply them should let the shared foundation take on more of the preparation that people perform manually today.

## Start with your purpose

| Your task | Start here | What you will learn |
|---|---|---|
| Solve a problem with a solver | {class}`PySCIPOpt Adapter Reference <ommx_pyscipopt_adapter.OMMXPySCIPOptAdapter>` | Create an Instance, solve it, and read the result |
| Evaluate a candidate you already have | [Evaluate candidates and interpret results](./user_guide/evaluate_and_interpret.md) | Align the problem, objective, and conditions being evaluated; distinguish feasibility from optimality |
| Evaluate metrics beyond the objective | {class}`~ommx.NamedFunction` | Compute distance or other reporting metrics for each candidate separately from the objective |
| Extract results by name and subscript | {meth}`Named variable values <ommx.Solution.extract_decision_variables>` | Obtain evaluated variable values as dictionaries or tables for further processing |
| Understand the problem representation | {class}`~ommx.Instance` | Describe variables, objectives, and constraints |
| Construct and evaluate expressions | {class}`~ommx.Function` | Build scalar expressions and distinguish their values from a candidate's feasibility |
| Inspect expressions using variable labels | {meth}`Expression formatting <ommx.Instance.format_function>` | Read expressions using the names and subscripts held by an Instance |
| Change numeric conditions in a fixed problem structure | {class}`~ommx.ParametricInstance` | Reuse the structure and variable/constraint IDs with different parameter values |
| Use special constraints | {class}`~ommx.IndicatorConstraint`, {class}`~ommx.OneHotConstraint`, {class}`~ommx.Sos1Constraint` | Understand Indicator, OneHot, and SOS1 constraints and their solver integration |
| Transform a problem and choose a method | [Transform a problem and connect it to a solving method](./user_guide/transform_and_solve.md) | Preserve structure and distinguish input conditions, transformation guarantees, and settings |
| Tighten variable bounds from constraints | {meth}`Bound tightening <ommx.Instance.tighten_bounds_simultaneously_once>` | Perform one update and inspect the changed bounds |
| Compare multiple candidates | {class}`~ommx.SampleSet` | Read sample evaluations and select among the candidates obtained |
| Sample with OpenJij | {class}`OpenJij SA Adapter Reference <ommx_openjij_adapter.OMMXOpenJijSAAdapter>` | Choose penalty weights, prepare a problem, and inspect the returned candidates |
| Obtain existing problems | {mod}`~ommx.dataset` | Download a problem as an OMMX Instance |
| Save and share problems, results, and trials | [Choose what to record](./user_guide/record_and_share.md) | Select a transfer format and the information needed to inspect or rerun work |
| Connect your own solving tool | [Implement an Adapter](./tutorial/implement_adapter.md) | Translate backend inputs and outputs through the common adapter interface |

This Book explains what OMMX can do, why and when to use it, what to choose, and how to interpret results. Use small examples to understand the meaning, then consult the {doc}`API Reference <api/index>` for detailed calls, arguments, preconditions, and guarantees. You do not need to read every page in order.

If you already have a problem and candidate values, begin with [Evaluate candidates and interpret results](./user_guide/evaluate_and_interpret.md). Use {class}`~ommx.Solution` for evaluation examples or {func}`~ommx.qplib.load_solution` to check a published assignment. To start SCIP from a candidate, see {meth}`~ommx_pyscipopt_adapter.OMMXPySCIPOptAdapter.solve`. You can evaluate candidates independently of an Adapter.

## Use or implement an Adapter

After [installing the SDK and an Adapter](./getting_started/install.md), choose a complete example from its Reference. {class}`PySCIPOpt <ommx_pyscipopt_adapter.OMMXPySCIPOptAdapter>` covers a knapsack model, native special constraints, and explicit preparation. {class}`HiGHS <ommx_highs_adapter.OMMXHighsAdapter>` shows how OMMX rewrites a special constraint as ordinary constraints that HiGHS can accept. {class}`OpenJij SA <ommx_openjij_adapter.OMMXOpenJijSAAdapter>` covers caller-chosen penalty weights, sampling, and selecting among returned candidates. Each example supplies its own model. The {doc}`Adapter packages and input contracts </api/adapters>` page lists the available integrations.

To compare solvers, use the {mod}`complete Adapter comparison example <ommx.adapter>` in the API Reference. The [OpenJij TSP example](./tutorial/tsp_sampling_with_openjij_adapter) is an optional application that includes route visualization.

If you are connecting your own solving tool, the [adapter implementation guide](./tutorial/implement_adapter.md) explains how to translate its input and output through OMMX's common interface.

## Support data exchange and sharing

Giving problems and results common meanings helps both software and people work with the same data. OMMX supports these handoffs through the following components:

| Component | Role |
|---|---|
| OMMX Message | A language- and OS-independent data format for problems and results |
| OMMX SDK | Construction, evaluation, transformation, reading, and writing of problems and results |
| OMMX Adapter | Connection between OMMX and a solver's inputs and outputs |
| OMMX Artifact | A package for saving and sharing problems, results, and attachments with metadata |

Message schemas are defined with [Protocol Buffers](https://protobuf.dev/), with SDKs provided for Python and Rust. In Python user code, use the public API, such as `from ommx import Instance`. The [schema sources](https://github.com/Jij-Inc/ommx/tree/main/proto/ommx) define the wire formats; a [generated v1 Message Schema](https://jij-inc.github.io/ommx/protobuf.html) is also available.

```{figure} ./assets/introduction_02.png
:alt: Multiple software tools connected through a common OMMX representation
:width: 70%

Connect software through a common representation of problems and results.
```

Alongside problems and results, Artifacts can record what was solved and with which settings. They use [OCI standards](https://opencontainers.org/), so they can also be distributed through existing registries such as GitHub Container Registry. OMMX uses this mechanism to publish MIPLIB and QPLIB problems. The [Artifact format specification](https://github.com/Jij-Inc/ommx/blob/main/rust/ommx/doc/artifact_design.md) defines manifests, layers, and media types for tools that need to read or write the format directly.

```{toctree}
:caption: Get started
:maxdepth: 1
:hidden:

getting_started/install
```

```{toctree}
:caption: Examples
:maxdepth: 1
:hidden:

tutorial/tsp_sampling_with_openjij_adapter
examples/published_benchmarks
```

```{toctree}
:caption: Adapter development
:maxdepth: 1
:hidden:

tutorial/implement_adapter
```

```{toctree}
:caption: Transform problems and connect solvers
:maxdepth: 1
:hidden:

user_guide/transform_and_solve
```

```{toctree}
:caption: Evaluate candidates and interpret results
:maxdepth: 1
:hidden:

user_guide/evaluate_and_interpret
```

```{toctree}
:caption: Save and share problems, results, and trials
:maxdepth: 1
:hidden:

user_guide/record_and_share
```

```{toctree}
:caption: User Guide
:maxdepth: 1
:hidden:

user_guide/cli
how_to/manage_local_registry
how_to/share_artifact_registry
user_guide/agent_skills
user_guide/adapter_diagnostics
user_guide/tracing
```

```{toctree}
:caption: API Reference
:maxdepth: 2
:hidden:

api/index
```

```{toctree}
:caption: Migration Guide
:maxdepth: 1
:hidden:

migration/python_sdk_v2_to_v3
migration/python_sdk_v1_to_v2
```

```{toctree}
:caption: Release Note
:maxdepth: 1
:hidden:

release_note/ommx-3.0
release_note/ommx-2.5
release_note/ommx-2.4
release_note/ommx-2.3
release_note/ommx-2.2
release_note/ommx-2.1
release_note/ommx-2.0
release_note/ommx-1.9
release_note/ommx-1.8
release_note/ommx-1.7
release_note/ommx-1.6
release_note/ommx-1.5
```
