ommx.adapter
============

.. py:module:: ommx.adapter


Attributes
----------

.. autoapisummary::

   ommx.adapter.SamplerInput
   ommx.adapter.SamplerOutput
   ommx.adapter.SolverInput
   ommx.adapter.SolverOutput


Exceptions
----------

.. autoapisummary::

   ommx.adapter.AdapterNotApplicableError
   ommx.adapter.NoSolutionReturned
   ommx.adapter.UnboundedDetected


Classes
-------

.. autoapisummary::

   ommx.adapter.DiagnosticReport
   ommx.adapter.DiagnosticsSink
   ommx.adapter.SamplerAdapter
   ommx.adapter.SolverAdapter


Module Contents
---------------

.. py:exception:: AdapterNotApplicableError(adapter: str, report: ommx.InstanceClassMembershipReport)



   Raised when an instance is not applicable to an adapter.


   .. py:attribute:: adapter
      :type:  str


   .. py:attribute:: report
      :type:  ommx.InstanceClassMembershipReport


.. py:exception:: NoSolutionReturned



   Raised when no solution was returned.

   This indicates that the solver did not return any solution (whether feasible
   or not) (e.g., due to time limits).
   This does not prove that the mathematical model itself is infeasible.


.. py:exception:: UnboundedDetected



   Raised when the problem is proven to be unbounded.

   This corresponds to ``Optimality.OPTIMALITY_UNBOUNDED`` and indicates that
   the mathematical model itself is unbounded.
   Should not be used when unboundedness cannot be proven (e.g., heuristic solvers).


.. py:class:: DiagnosticReport



   Adapter diagnostic report convertible with ``dataclasses.asdict``.


.. py:class:: DiagnosticsSink



   Receiver for adapter-defined diagnostics emitted during a solve.

   Adapters may call ``record`` while the backend solver is still running,
   including from backend callbacks. Sink implementations should keep
   ``record`` append-only, defer validation or serialization until after the
   solve, and preserve the order in which diagnostics are received.

   A conforming sink must not raise from ``record``. If recording fails, the
   sink should log the failure and return normally. If ``record`` does raise,
   that is a sink contract violation; adapters may let the exception propagate
   and do not need to recover from it.


   .. py:method:: record(diagnostic: DiagnosticReport) -> None

      Record one adapter-defined dataclass diagnostic report or event.

      This method must not raise under normal sink failures. Custom sinks
      should log failures and return instead.



.. py:class:: SamplerAdapter



   An abstract interface for OMMX Sampler Adapters, defining how samplers should be used with OMMX.

   See the `implementation guide <https://jij-inc-ommx.readthedocs-hosted.com/en/latest/tutorial/implement_adapter.html>`_ for more details.


   .. py:method:: check_applicability(ommx_instance: ommx.Instance) -> ommx.InstanceClassMembershipReport
      :classmethod:


      Check ``INPUT_CLASS`` membership without mutation.



   .. py:method:: decode(data: SolverOutput) -> ommx.Solution

      Decode sampler output and return its best feasible solution.



   .. py:method:: decode_to_sampleset(data: SamplerOutput) -> ommx.SampleSet
      :abstractmethod:



   .. py:method:: recommended_preparation_policy() -> ommx.PreparationPolicy
      :classmethod:


      Return a fresh policy recommended for this Adapter's ``INPUT_CLASS``.

      The easy APIs apply it to an isolated copy. Advanced callers may edit
      and apply it explicitly before using a preparation-free API. This
      method itself neither prepares an instance nor guarantees
      applicability. The default policy is empty.



   .. py:method:: require_applicable(ommx_instance: ommx.Instance) -> ommx.InstanceClassMembershipReport
      :classmethod:


      Return the membership report or raise ``AdapterNotApplicableError``.



   .. py:method:: sample(ommx_instance: ommx.Instance, *, diagnostics: DiagnosticsSink | None = None) -> ommx.SampleSet
      :classmethod:


      Prepare and sample an isolated copy of an OMMX instance.

      The input ``ommx_instance`` is never modified. The copy is prepared for
      ``INPUT_CLASS`` with :meth:`recommended_preparation_policy`, then passed
      to :meth:`sample_without_preparation`.

      ``Run.log_sample`` owns the reserved ``diagnostics`` keyword and uses
      it the same way as ``Run.log_solve``. ``None`` means diagnostics are
      disabled.



   .. py:method:: sample_without_preparation(ommx_instance: ommx.Instance, *, diagnostics: DiagnosticsSink | None = None) -> ommx.SampleSet
      :classmethod:

      :abstractmethod:


      Sample an exact Adapter input without running ``Instance.prepare``.

      ``ommx_instance`` must belong to ``INPUT_CLASS``. Implementations must
      reject non-members with :class:`AdapterNotApplicableError` and must not
      prepare or otherwise modify the input instance.



   .. py:method:: solve(ommx_instance: ommx.Instance, *, diagnostics: DiagnosticsSink | None = None) -> ommx.Solution
      :classmethod:


      Prepare and solve an isolated copy of an OMMX instance.

      The input ``ommx_instance`` is never modified. The copy is prepared for
      ``INPUT_CLASS`` with :meth:`recommended_preparation_policy`, then passed
      to :meth:`solve_without_preparation`.

      ``Run.log_solve`` owns the reserved ``diagnostics`` keyword. When
      called with ``store_diagnostics=True``, it passes a sink to the adapter
      and stores recorded diagnostics with the Solve entry. Adapters may
      record adapter-defined dataclass diagnostics into the sink during the
      solve; ``None`` means diagnostics are disabled. Adapters do not need to
      catch exceptions raised by a non-conforming diagnostics sink.



   .. py:method:: solve_without_preparation(ommx_instance: ommx.Instance, *, diagnostics: DiagnosticsSink | None = None) -> ommx.Solution
      :classmethod:


      Return the best feasible result from :meth:`sample_without_preparation`.



   .. py:attribute:: INPUT_CLASS
      :type:  ClassVar[ommx.InstanceClass]

      Required condition for an exact Adapter input.



   .. py:property:: sampler_input
      :type: SamplerInput

      :abstractmethod:



   .. py:property:: solver_input
      :type: SolverInput


      Expose :attr:`sampler_input` through the SolverAdapter interface.



.. py:class:: SolverAdapter



   An abstract interface for OMMX Solver Adapters, defining how solvers should be used with OMMX.

   See the `implementation guide <https://jij-inc-ommx.readthedocs-hosted.com/en/latest/tutorial/implement_adapter.html>`_ for more details.

   Concrete subclasses define applicability with ``INPUT_CLASS``. The easy
   :meth:`solve` API prepares an isolated copy with the Adapter's recommended
   policy. Use :meth:`solve_without_preparation` when the caller owns preparation and wants
   the Adapter to require an exact input without modifying it.


   .. py:method:: check_applicability(ommx_instance: ommx.Instance) -> ommx.InstanceClassMembershipReport
      :classmethod:


      Check ``INPUT_CLASS`` membership without mutation.



   .. py:method:: decode(data: SolverOutput) -> ommx.Solution
      :abstractmethod:



   .. py:method:: recommended_preparation_policy() -> ommx.PreparationPolicy
      :classmethod:


      Return a fresh policy recommended for this Adapter's ``INPUT_CLASS``.

      The easy APIs apply it to an isolated copy. Advanced callers may edit
      and apply it explicitly before using a preparation-free API. This
      method itself neither prepares an instance nor guarantees
      applicability. The default policy is empty.



   .. py:method:: require_applicable(ommx_instance: ommx.Instance) -> ommx.InstanceClassMembershipReport
      :classmethod:


      Return the membership report or raise ``AdapterNotApplicableError``.



   .. py:method:: solve(ommx_instance: ommx.Instance, *, diagnostics: DiagnosticsSink | None = None) -> ommx.Solution
      :classmethod:


      Prepare and solve an isolated copy of an OMMX instance.

      The input ``ommx_instance`` is never modified. The copy is prepared for
      ``INPUT_CLASS`` with :meth:`recommended_preparation_policy`, then passed
      to :meth:`solve_without_preparation`.

      ``Run.log_solve`` owns the reserved ``diagnostics`` keyword. When
      called with ``store_diagnostics=True``, it passes a sink to the adapter
      and stores recorded diagnostics with the Solve entry. Adapters may
      record adapter-defined dataclass diagnostics into the sink during the
      solve; ``None`` means diagnostics are disabled. Adapters do not need to
      catch exceptions raised by a non-conforming diagnostics sink.



   .. py:method:: solve_without_preparation(ommx_instance: ommx.Instance, *, diagnostics: DiagnosticsSink | None = None) -> ommx.Solution
      :classmethod:

      :abstractmethod:


      Solve an exact Adapter input without running ``Instance.prepare``.

      ``ommx_instance`` must belong to ``INPUT_CLASS``. Implementations must
      reject non-members with :class:`AdapterNotApplicableError` and must not
      prepare or otherwise modify the input instance.



   .. py:attribute:: INPUT_CLASS
      :type:  ClassVar[ommx.InstanceClass]

      Required condition for an exact Adapter input.



   .. py:property:: solver_input
      :type: SolverInput

      :abstractmethod:



.. py:data:: SamplerInput

.. py:data:: SamplerOutput

.. py:data:: SolverInput

.. py:data:: SolverOutput

