"""
@generated by mypy-protobuf.  Do not edit manually!
isort:skip_file
The result of solving a MathOpt model, both the Solution and metadata."""

import builtins
import collections.abc
import google.protobuf.descriptor
import google.protobuf.duration_pb2
import google.protobuf.internal.containers
import google.protobuf.internal.enum_type_wrapper
import google.protobuf.message
import ortools.service.v1.mathopt.solution_pb2
import sys
import typing

if sys.version_info >= (3, 10):
    import typing as typing_extensions
else:
    import typing_extensions

DESCRIPTOR: google.protobuf.descriptor.FileDescriptor

class _FeasibilityStatusProto:
    ValueType = typing.NewType("ValueType", builtins.int)
    V: typing_extensions.TypeAlias = ValueType

class _FeasibilityStatusProtoEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_FeasibilityStatusProto.ValueType], builtins.type):
    DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
    FEASIBILITY_STATUS_UNSPECIFIED: _FeasibilityStatusProto.ValueType  # 0
    """Guard value representing no status."""
    FEASIBILITY_STATUS_UNDETERMINED: _FeasibilityStatusProto.ValueType  # 1
    """Solver does not claim a status."""
    FEASIBILITY_STATUS_FEASIBLE: _FeasibilityStatusProto.ValueType  # 2
    """Solver claims the problem is feasible."""
    FEASIBILITY_STATUS_INFEASIBLE: _FeasibilityStatusProto.ValueType  # 3
    """Solver claims the problem is infeasible."""

class FeasibilityStatusProto(_FeasibilityStatusProto, metaclass=_FeasibilityStatusProtoEnumTypeWrapper):
    """Problem feasibility status as claimed by the solver (solver is not required
    to return a certificate for the claim).
    """

FEASIBILITY_STATUS_UNSPECIFIED: FeasibilityStatusProto.ValueType  # 0
"""Guard value representing no status."""
FEASIBILITY_STATUS_UNDETERMINED: FeasibilityStatusProto.ValueType  # 1
"""Solver does not claim a status."""
FEASIBILITY_STATUS_FEASIBLE: FeasibilityStatusProto.ValueType  # 2
"""Solver claims the problem is feasible."""
FEASIBILITY_STATUS_INFEASIBLE: FeasibilityStatusProto.ValueType  # 3
"""Solver claims the problem is infeasible."""
Global___FeasibilityStatusProto: typing_extensions.TypeAlias = FeasibilityStatusProto

class _TerminationReasonProto:
    ValueType = typing.NewType("ValueType", builtins.int)
    V: typing_extensions.TypeAlias = ValueType

class _TerminationReasonProtoEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_TerminationReasonProto.ValueType], builtins.type):
    DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
    TERMINATION_REASON_UNSPECIFIED: _TerminationReasonProto.ValueType  # 0
    TERMINATION_REASON_OPTIMAL: _TerminationReasonProto.ValueType  # 1
    """A provably optimal solution (up to numerical tolerances) has been found."""
    TERMINATION_REASON_INFEASIBLE: _TerminationReasonProto.ValueType  # 2
    """The primal problem has no feasible solutions."""
    TERMINATION_REASON_UNBOUNDED: _TerminationReasonProto.ValueType  # 3
    """The primal problem is feasible and arbitrarily good solutions can be
    found along a primal ray.
    """
    TERMINATION_REASON_INFEASIBLE_OR_UNBOUNDED: _TerminationReasonProto.ValueType  # 4
    """The primal problem is either infeasible or unbounded. More details on the
    problem status may be available in solve_stats.problem_status. Note that
    Gurobi's unbounded status may be mapped here.
    """
    TERMINATION_REASON_IMPRECISE: _TerminationReasonProto.ValueType  # 5
    """The problem was solved to one of the criteria above (Optimal, Infeasible,
    Unbounded, or InfeasibleOrUnbounded), but one or more tolerances was not
    met. Some primal/dual solutions/rays be present, but either they will be
    slightly infeasible, or (if the problem was nearly optimal) their may be
    a gap between the best solution objective and best objective bound.

    Users can still query primal/dual solutions/rays and solution stats, but
    they are responsible for dealing with the numerical imprecision.
    """
    TERMINATION_REASON_FEASIBLE: _TerminationReasonProto.ValueType  # 9
    """The optimizer reached some kind of limit and a primal feasible solution
    is returned. See SolveResultProto.limit_detail for detailed description of
    the kind of limit that was reached.
    """
    TERMINATION_REASON_NO_SOLUTION_FOUND: _TerminationReasonProto.ValueType  # 6
    """The optimizer reached some kind of limit and it did not find a primal
    feasible solution. See SolveResultProto.limit_detail for detailed
    description of the kind of limit that was reached.
    """
    TERMINATION_REASON_NUMERICAL_ERROR: _TerminationReasonProto.ValueType  # 7
    """The algorithm stopped because it encountered unrecoverable numerical
    error. No solution information is available.
    """
    TERMINATION_REASON_OTHER_ERROR: _TerminationReasonProto.ValueType  # 8
    """The algorithm stopped because of an error not covered by one of the
    statuses defined above. No solution information is available.
    """

class TerminationReasonProto(_TerminationReasonProto, metaclass=_TerminationReasonProtoEnumTypeWrapper):
    """The reason a call to Solve() terminates."""

TERMINATION_REASON_UNSPECIFIED: TerminationReasonProto.ValueType  # 0
TERMINATION_REASON_OPTIMAL: TerminationReasonProto.ValueType  # 1
"""A provably optimal solution (up to numerical tolerances) has been found."""
TERMINATION_REASON_INFEASIBLE: TerminationReasonProto.ValueType  # 2
"""The primal problem has no feasible solutions."""
TERMINATION_REASON_UNBOUNDED: TerminationReasonProto.ValueType  # 3
"""The primal problem is feasible and arbitrarily good solutions can be
found along a primal ray.
"""
TERMINATION_REASON_INFEASIBLE_OR_UNBOUNDED: TerminationReasonProto.ValueType  # 4
"""The primal problem is either infeasible or unbounded. More details on the
problem status may be available in solve_stats.problem_status. Note that
Gurobi's unbounded status may be mapped here.
"""
TERMINATION_REASON_IMPRECISE: TerminationReasonProto.ValueType  # 5
"""The problem was solved to one of the criteria above (Optimal, Infeasible,
Unbounded, or InfeasibleOrUnbounded), but one or more tolerances was not
met. Some primal/dual solutions/rays be present, but either they will be
slightly infeasible, or (if the problem was nearly optimal) their may be
a gap between the best solution objective and best objective bound.

Users can still query primal/dual solutions/rays and solution stats, but
they are responsible for dealing with the numerical imprecision.
"""
TERMINATION_REASON_FEASIBLE: TerminationReasonProto.ValueType  # 9
"""The optimizer reached some kind of limit and a primal feasible solution
is returned. See SolveResultProto.limit_detail for detailed description of
the kind of limit that was reached.
"""
TERMINATION_REASON_NO_SOLUTION_FOUND: TerminationReasonProto.ValueType  # 6
"""The optimizer reached some kind of limit and it did not find a primal
feasible solution. See SolveResultProto.limit_detail for detailed
description of the kind of limit that was reached.
"""
TERMINATION_REASON_NUMERICAL_ERROR: TerminationReasonProto.ValueType  # 7
"""The algorithm stopped because it encountered unrecoverable numerical
error. No solution information is available.
"""
TERMINATION_REASON_OTHER_ERROR: TerminationReasonProto.ValueType  # 8
"""The algorithm stopped because of an error not covered by one of the
statuses defined above. No solution information is available.
"""
Global___TerminationReasonProto: typing_extensions.TypeAlias = TerminationReasonProto

class _LimitProto:
    ValueType = typing.NewType("ValueType", builtins.int)
    V: typing_extensions.TypeAlias = ValueType

class _LimitProtoEnumTypeWrapper(google.protobuf.internal.enum_type_wrapper._EnumTypeWrapper[_LimitProto.ValueType], builtins.type):
    DESCRIPTOR: google.protobuf.descriptor.EnumDescriptor
    LIMIT_UNSPECIFIED: _LimitProto.ValueType  # 0
    """Used as a null value when we terminated not from a limit (e.g.
    TERMINATION_REASON_OPTIMAL).
    """
    LIMIT_UNDETERMINED: _LimitProto.ValueType  # 1
    """The underlying solver does not expose which limit was reached."""
    LIMIT_ITERATION: _LimitProto.ValueType  # 2
    """An iterative algorithm stopped after conducting the maximum number of
    iterations (e.g. simplex or barrier iterations).
    """
    LIMIT_TIME: _LimitProto.ValueType  # 3
    """The algorithm stopped after a user-specified computation time."""
    LIMIT_NODE: _LimitProto.ValueType  # 4
    """A branch-and-bound algorithm stopped because it explored a maximum number
    of nodes in the branch-and-bound tree.
    """
    LIMIT_SOLUTION: _LimitProto.ValueType  # 5
    """The algorithm stopped because it found the required number of solutions.
    This is often used in MIPs to get the solver to return the first feasible
    solution it encounters.
    """
    LIMIT_MEMORY: _LimitProto.ValueType  # 6
    """The algorithm stopped because it ran out of memory."""
    LIMIT_CUTOFF: _LimitProto.ValueType  # 12
    """The solver was run with a cutoff (e.g. SolveParameters.cutoff_limit was
    set) on the objective, indicating that the user did not want any solution
    worse than the cutoff, and the solver concluded there were no solutions at
    least as good as the cutoff. Typically no further solution information is
    provided.
    """
    LIMIT_OBJECTIVE: _LimitProto.ValueType  # 7
    """The algorithm stopped because it either found a solution or a bound better
    than a limit set by the user (see SolveParameters.objective_limit and
    SolveParameters.best_bound_limit).
    """
    LIMIT_NORM: _LimitProto.ValueType  # 8
    """The algorithm stopped because the norm of an iterate became too large."""
    LIMIT_INTERRUPTED: _LimitProto.ValueType  # 9
    """The algorithm stopped because of an interrupt signal or a user interrupt
    request.
    """
    LIMIT_SLOW_PROGRESS: _LimitProto.ValueType  # 10
    """The algorithm stopped because it was unable to continue making progress
    towards the solution.
    """
    LIMIT_OTHER: _LimitProto.ValueType  # 11
    """The algorithm stopped due to a limit not covered by one of the above. Note
    that LIMIT_UNDETERMINED is used when the reason cannot be determined, and
    LIMIT_OTHER is used when the reason is known but does not fit into any of
    the above alternatives.

    TerminationProto.detail may contain additional information about the limit.
    """

class LimitProto(_LimitProto, metaclass=_LimitProtoEnumTypeWrapper):
    """When a Solve() stops early with TerminationReasonProto FEASIBLE or
    NO_SOLUTION_FOUND, the specific limit that was hit.
    """

LIMIT_UNSPECIFIED: LimitProto.ValueType  # 0
"""Used as a null value when we terminated not from a limit (e.g.
TERMINATION_REASON_OPTIMAL).
"""
LIMIT_UNDETERMINED: LimitProto.ValueType  # 1
"""The underlying solver does not expose which limit was reached."""
LIMIT_ITERATION: LimitProto.ValueType  # 2
"""An iterative algorithm stopped after conducting the maximum number of
iterations (e.g. simplex or barrier iterations).
"""
LIMIT_TIME: LimitProto.ValueType  # 3
"""The algorithm stopped after a user-specified computation time."""
LIMIT_NODE: LimitProto.ValueType  # 4
"""A branch-and-bound algorithm stopped because it explored a maximum number
of nodes in the branch-and-bound tree.
"""
LIMIT_SOLUTION: LimitProto.ValueType  # 5
"""The algorithm stopped because it found the required number of solutions.
This is often used in MIPs to get the solver to return the first feasible
solution it encounters.
"""
LIMIT_MEMORY: LimitProto.ValueType  # 6
"""The algorithm stopped because it ran out of memory."""
LIMIT_CUTOFF: LimitProto.ValueType  # 12
"""The solver was run with a cutoff (e.g. SolveParameters.cutoff_limit was
set) on the objective, indicating that the user did not want any solution
worse than the cutoff, and the solver concluded there were no solutions at
least as good as the cutoff. Typically no further solution information is
provided.
"""
LIMIT_OBJECTIVE: LimitProto.ValueType  # 7
"""The algorithm stopped because it either found a solution or a bound better
than a limit set by the user (see SolveParameters.objective_limit and
SolveParameters.best_bound_limit).
"""
LIMIT_NORM: LimitProto.ValueType  # 8
"""The algorithm stopped because the norm of an iterate became too large."""
LIMIT_INTERRUPTED: LimitProto.ValueType  # 9
"""The algorithm stopped because of an interrupt signal or a user interrupt
request.
"""
LIMIT_SLOW_PROGRESS: LimitProto.ValueType  # 10
"""The algorithm stopped because it was unable to continue making progress
towards the solution.
"""
LIMIT_OTHER: LimitProto.ValueType  # 11
"""The algorithm stopped due to a limit not covered by one of the above. Note
that LIMIT_UNDETERMINED is used when the reason cannot be determined, and
LIMIT_OTHER is used when the reason is known but does not fit into any of
the above alternatives.

TerminationProto.detail may contain additional information about the limit.
"""
Global___LimitProto: typing_extensions.TypeAlias = LimitProto

@typing.final
class ProblemStatusProto(google.protobuf.message.Message):
    """Feasibility status of the primal problem and its dual (or the dual of a
    continuous relaxation) as claimed by the solver. The solver is not required
    to return a certificate for the claim (e.g. the solver may claim primal
    feasibility without returning a primal feasible solutuion). This combined
    status gives a comprehensive description of a solver's claims about
    feasibility and unboundedness of the solved problem. For instance,

      * a feasible status for primal and dual problems indicates the primal is
        feasible and bounded and likely has an optimal solution (guaranteed for
        problems without non-linear constraints).
      * a primal feasible and a dual infeasible status indicates the primal
        problem is unbounded (i.e. has arbitrarily good solutions).

    Note that a dual infeasible status by itself (i.e. accompanied by an
    undetermined primal status) does not imply the primal problem is unbounded as
    we could have both problems be infeasible. Also, while a primal and dual
    feasible status may imply the existence of an optimal solution, it does not
    guarantee the solver has actually found such optimal solution.
    """

    DESCRIPTOR: google.protobuf.descriptor.Descriptor

    PRIMAL_STATUS_FIELD_NUMBER: builtins.int
    DUAL_STATUS_FIELD_NUMBER: builtins.int
    PRIMAL_OR_DUAL_INFEASIBLE_FIELD_NUMBER: builtins.int
    primal_status: Global___FeasibilityStatusProto.ValueType
    """Status for the primal problem."""
    dual_status: Global___FeasibilityStatusProto.ValueType
    """Status for the dual problem (or for the dual of a continuous relaxation)."""
    primal_or_dual_infeasible: builtins.bool
    """If true, the solver claims the primal or dual problem is infeasible, but
    it does not know which (or if both are infeasible). Can be true only when
    primal_problem_status = dual_problem_status = kUndetermined. This extra
    information is often needed when preprocessing determines there is no
    optimal solution to the problem (but can't determine if it is due to
    infeasibility, unboundedness, or both).
    """
    def __init__(
        self,
        *,
        primal_status: Global___FeasibilityStatusProto.ValueType = ...,
        dual_status: Global___FeasibilityStatusProto.ValueType = ...,
        primal_or_dual_infeasible: builtins.bool = ...,
    ) -> None: ...
    _ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["dual_status", b"dual_status", "primal_or_dual_infeasible", b"primal_or_dual_infeasible", "primal_status", b"primal_status"]
    def ClearField(self, field_name: _ClearFieldArgType) -> None: ...

Global___ProblemStatusProto: typing_extensions.TypeAlias = ProblemStatusProto

@typing.final
class SolveStatsProto(google.protobuf.message.Message):
    DESCRIPTOR: google.protobuf.descriptor.Descriptor

    SOLVE_TIME_FIELD_NUMBER: builtins.int
    PROBLEM_STATUS_FIELD_NUMBER: builtins.int
    SIMPLEX_ITERATIONS_FIELD_NUMBER: builtins.int
    BARRIER_ITERATIONS_FIELD_NUMBER: builtins.int
    FIRST_ORDER_ITERATIONS_FIELD_NUMBER: builtins.int
    NODE_COUNT_FIELD_NUMBER: builtins.int
    simplex_iterations: builtins.int
    barrier_iterations: builtins.int
    first_order_iterations: builtins.int
    node_count: builtins.int
    @property
    def solve_time(self) -> google.protobuf.duration_pb2.Duration:
        """Elapsed wall clock time as measured by math_opt, roughly the time inside
        Solver::Solve(). Note: this does not include work done building the model.
        """

    @property
    def problem_status(self) -> Global___ProblemStatusProto:
        """Feasibility statuses for primal and dual problems."""

    def __init__(
        self,
        *,
        solve_time: google.protobuf.duration_pb2.Duration | None = ...,
        problem_status: Global___ProblemStatusProto | None = ...,
        simplex_iterations: builtins.int = ...,
        barrier_iterations: builtins.int = ...,
        first_order_iterations: builtins.int = ...,
        node_count: builtins.int = ...,
    ) -> None: ...
    _HasFieldArgType: typing_extensions.TypeAlias = typing.Literal["problem_status", b"problem_status", "solve_time", b"solve_time"]
    def HasField(self, field_name: _HasFieldArgType) -> builtins.bool: ...
    _ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["barrier_iterations", b"barrier_iterations", "first_order_iterations", b"first_order_iterations", "node_count", b"node_count", "problem_status", b"problem_status", "simplex_iterations", b"simplex_iterations", "solve_time", b"solve_time"]
    def ClearField(self, field_name: _ClearFieldArgType) -> None: ...

Global___SolveStatsProto: typing_extensions.TypeAlias = SolveStatsProto

@typing.final
class ObjectiveBoundsProto(google.protobuf.message.Message):
    """Bounds on the optimal objective value."""

    DESCRIPTOR: google.protobuf.descriptor.Descriptor

    PRIMAL_BOUND_FIELD_NUMBER: builtins.int
    DUAL_BOUND_FIELD_NUMBER: builtins.int
    primal_bound: builtins.float
    """Solver claims the optimal value is equal or better (smaller for
    minimization and larger for maximization) than primal_bound up to the
    solvers primal feasibility tolerance (see warning below):
      * primal_bound is trivial (+inf for minimization and -inf
        maximization) when the solver does not claim to have such bound.
      * primal_bound can be closer to the optimal value than the objective
        of the best primal feasible solution. In particular, primal_bound
        may be non-trivial even when no primal feasible solutions are returned.
    Warning: The precise claim is that there exists a primal solution that:
     * is numerically feasible (i.e. feasible up to the solvers tolerance), and
     * has an objective value primal_bound.
    This numerically feasible solution could be slightly infeasible, in which
    case primal_bound could be strictly better than the optimal value.
    Translating a primal feasibility tolerance to a tolerance on
    primal_bound is non-trivial, specially when the feasibility tolerance
    is relatively large (e.g. when solving with PDLP).
    """
    dual_bound: builtins.float
    """Solver claims the optimal value is equal or worse (larger for
    minimization and smaller for maximization) than dual_bound up to the
    solvers dual feasibility tolerance (see warning below):
      * dual_bound is trivial (-inf for minimization and +inf
        maximization) when the solver does not claim to have such bound.
        Similarly to primal_bound, this may happen for some solvers even
        when returning optimal. MIP solvers will typically report a bound even
        if it is imprecise.
      * for continuous problems dual_bound can be closer to the optimal
        value than the objective of the best dual feasible solution. For MIP
        one of the first non-trivial values for dual_bound is often the
        optimal value of the LP relaxation of the MIP.
      * dual_bound should be better (smaller for minimization and larger
        for maximization) than primal_bound up to the solvers tolerances
        (see warning below).
    Warning:
     * For continuous problems, the precise claim is that there exists a
       dual solution that:
         * is numerically feasible (i.e. feasible up to the solvers tolerance),
           and
         * has an objective value dual_bound.
       This numerically feasible solution could be slightly infeasible, in
       which case dual_bound could be strictly worse than the optimal
       value and primal_bound. Similar to the primal case, translating a
       dual feasibility tolerance to a tolerance on dual_bound is
       non-trivial, specially when the feasibility tolerance is relatively
       large. However, some solvers provide a corrected version of
       dual_bound that can be numerically safer. This corrected version
       can be accessed through the solver's specific output (e.g. for PDLP,
       pdlp_output.convergence_information.corrected_dual_objective).
     * For MIP solvers, dual_bound may be associated to a dual solution
       for some continuous relaxation (e.g. LP relaxation), but it is often a
       complex consequence of the solvers execution and is typically more
       imprecise than the bounds reported by LP solvers.
    """
    def __init__(
        self,
        *,
        primal_bound: builtins.float = ...,
        dual_bound: builtins.float = ...,
    ) -> None: ...
    _ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["dual_bound", b"dual_bound", "primal_bound", b"primal_bound"]
    def ClearField(self, field_name: _ClearFieldArgType) -> None: ...

Global___ObjectiveBoundsProto: typing_extensions.TypeAlias = ObjectiveBoundsProto

@typing.final
class TerminationProto(google.protobuf.message.Message):
    """All information regarding why a call to Solve() terminated."""

    DESCRIPTOR: google.protobuf.descriptor.Descriptor

    REASON_FIELD_NUMBER: builtins.int
    LIMIT_FIELD_NUMBER: builtins.int
    DETAIL_FIELD_NUMBER: builtins.int
    PROBLEM_STATUS_FIELD_NUMBER: builtins.int
    OBJECTIVE_BOUNDS_FIELD_NUMBER: builtins.int
    reason: Global___TerminationReasonProto.ValueType
    """Additional information in `limit` when value is TERMINATION_REASON_FEASIBLE
    or TERMINATION_REASON_NO_SOLUTION_FOUND, see `limit` for details.
    """
    limit: Global___LimitProto.ValueType
    """Is LIMIT_UNSPECIFIED unless reason is TERMINATION_REASON_FEASIBLE or
    TERMINATION_REASON_NO_SOLUTION_FOUND. Not all solvers can always determine
    the limit which caused termination, LIMIT_UNDETERMINED is used when the
    cause cannot be determined.
    """
    detail: builtins.str
    """Additional typically solver specific information about termination."""
    @property
    def problem_status(self) -> Global___ProblemStatusProto:
        """Feasibility statuses for primal and dual problems.
        As of July 18, 2023 this message may be missing. If missing, problem_status
        can be found in SolveResultProto.solve_stats.
        """

    @property
    def objective_bounds(self) -> Global___ObjectiveBoundsProto:
        """Bounds on the optimal objective value.
        As of July 18, 2023 this message may be missing. If missing,
        objective_bounds.primal_bound can be found in
        SolveResultProto.solve.stats.best_primal_bound and
        objective_bounds.dual_bound can be found in
        SolveResultProto.solve.stats.best_dual_bound
        """

    def __init__(
        self,
        *,
        reason: Global___TerminationReasonProto.ValueType = ...,
        limit: Global___LimitProto.ValueType = ...,
        detail: builtins.str = ...,
        problem_status: Global___ProblemStatusProto | None = ...,
        objective_bounds: Global___ObjectiveBoundsProto | None = ...,
    ) -> None: ...
    _HasFieldArgType: typing_extensions.TypeAlias = typing.Literal["objective_bounds", b"objective_bounds", "problem_status", b"problem_status"]
    def HasField(self, field_name: _HasFieldArgType) -> builtins.bool: ...
    _ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["detail", b"detail", "limit", b"limit", "objective_bounds", b"objective_bounds", "problem_status", b"problem_status", "reason", b"reason"]
    def ClearField(self, field_name: _ClearFieldArgType) -> None: ...

Global___TerminationProto: typing_extensions.TypeAlias = TerminationProto

@typing.final
class SolveResultProto(google.protobuf.message.Message):
    """The contract of when primal/dual solutions/rays is complex, see
    termination_reasons.md for a complete description.

    Until an exact contract is finalized, it is safest to simply check if a
    solution/ray is present rather than relying on the termination reason.
    """

    DESCRIPTOR: google.protobuf.descriptor.Descriptor

    TERMINATION_FIELD_NUMBER: builtins.int
    SOLUTIONS_FIELD_NUMBER: builtins.int
    PRIMAL_RAYS_FIELD_NUMBER: builtins.int
    DUAL_RAYS_FIELD_NUMBER: builtins.int
    SOLVE_STATS_FIELD_NUMBER: builtins.int
    @property
    def termination(self) -> Global___TerminationProto:
        """The reason the solver stopped."""

    @property
    def solutions(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[ortools.service.v1.mathopt.solution_pb2.SolutionProto]:
        """ Basic solutions use, as of Nov 2021:
           * All convex optimization solvers (LP, convex QP) return only one
             solution as a primal dual pair.
           * Only MI(Q)P solvers return more than one solution. MIP solvers do not
             return any dual information, or primal infeasible solutions. Solutions
             are returned in order of best primal objective first. Gurobi solves
             nonconvex QP (integer or continuous) as MIQP.

        The general contract for the order of solutions that future solvers should
        implement is to order by:
          1. The solutions with a primal feasible solution, ordered by best primal
             objective first.
          2. The solutions with a dual feasible solution, ordered by best dual
               objective (unknown dual objective is worst)
          3. All remaining solutions can be returned in any order.
        """

    @property
    def primal_rays(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[ortools.service.v1.mathopt.solution_pb2.PrimalRayProto]:
        """Directions of unbounded primal improvement, or equivalently, dual
        infeasibility certificates. Typically provided for TerminationReasonProtos
        UNBOUNDED and DUAL_INFEASIBLE
        """

    @property
    def dual_rays(self) -> google.protobuf.internal.containers.RepeatedCompositeFieldContainer[ortools.service.v1.mathopt.solution_pb2.DualRayProto]:
        """Directions of unbounded dual improvement, or equivalently, primal
        infeasibility certificates. Typically provided for TerminationReasonProto
        INFEASIBLE.
        """

    @property
    def solve_stats(self) -> Global___SolveStatsProto:
        """Statistics on the solve process, e.g. running time, iterations."""

    def __init__(
        self,
        *,
        termination: Global___TerminationProto | None = ...,
        solutions: collections.abc.Iterable[ortools.service.v1.mathopt.solution_pb2.SolutionProto] | None = ...,
        primal_rays: collections.abc.Iterable[ortools.service.v1.mathopt.solution_pb2.PrimalRayProto] | None = ...,
        dual_rays: collections.abc.Iterable[ortools.service.v1.mathopt.solution_pb2.DualRayProto] | None = ...,
        solve_stats: Global___SolveStatsProto | None = ...,
    ) -> None: ...
    _HasFieldArgType: typing_extensions.TypeAlias = typing.Literal["solve_stats", b"solve_stats", "termination", b"termination"]
    def HasField(self, field_name: _HasFieldArgType) -> builtins.bool: ...
    _ClearFieldArgType: typing_extensions.TypeAlias = typing.Literal["dual_rays", b"dual_rays", "primal_rays", b"primal_rays", "solutions", b"solutions", "solve_stats", b"solve_stats", "termination", b"termination"]
    def ClearField(self, field_name: _ClearFieldArgType) -> None: ...

Global___SolveResultProto: typing_extensions.TypeAlias = SolveResultProto
