From 40ff9caa8883d184ad3ac14b826e7d11b006f249 Mon Sep 17 00:00:00 2001 From: Guillaume Chatelet Date: Thu, 18 Dec 2025 22:38:22 +0100 Subject: [PATCH] Propagate nullability (#4959) --- ortools/math_opt/core/BUILD.bazel | 2 + ortools/math_opt/core/base_solver.h | 5 +- ortools/math_opt/core/solver_interface.h | 8 +-- ortools/math_opt/core/solver_interface_mock.h | 11 ++-- ortools/math_opt/cpp/BUILD.bazel | 3 + .../compute_infeasible_subsystem_arguments.h | 3 +- ortools/math_opt/cpp/message_callback.cc | 1 + ortools/math_opt/cpp/solve_arguments.cc | 7 +-- ortools/math_opt/cpp/solve_arguments.h | 9 ++- ortools/math_opt/cpp/solve_arguments_test.cc | 27 ++------- ortools/math_opt/cpp/solve_impl.cc | 18 +++--- ortools/math_opt/cpp/solve_impl.h | 15 +++-- ortools/math_opt/cpp/solve_impl_test.cc | 60 ------------------- ortools/math_opt/cpp/solve_test.cc | 26 ++++---- ortools/math_opt/cpp/update_tracker.cc | 1 + ortools/math_opt/solvers/BUILD.bazel | 8 ++- ortools/math_opt/solvers/cp_sat_solver.cc | 4 +- ortools/math_opt/solvers/cp_sat_solver.h | 9 +-- ortools/math_opt/solvers/glop_solver.cc | 10 ++-- ortools/math_opt/solvers/glop_solver.h | 12 ++-- ortools/math_opt/solvers/glpk_solver.cc | 11 ++-- ortools/math_opt/solvers/glpk_solver.h | 9 +-- ortools/math_opt/solvers/gscip_solver.cc | 5 +- ortools/math_opt/solvers/gscip_solver.h | 9 +-- ortools/math_opt/solvers/gurobi_solver.cc | 22 +++---- ortools/math_opt/solvers/gurobi_solver.h | 26 ++++---- ortools/math_opt/solvers/highs_solver.cc | 5 +- ortools/math_opt/solvers/highs_solver.h | 9 +-- ortools/math_opt/solvers/pdlp_solver.cc | 5 +- ortools/math_opt/solvers/pdlp_solver.h | 9 +-- 30 files changed, 153 insertions(+), 196 deletions(-) diff --git a/ortools/math_opt/core/BUILD.bazel b/ortools/math_opt/core/BUILD.bazel index fb2968f4c9..cee25b1af6 100644 --- a/ortools/math_opt/core/BUILD.bazel +++ b/ortools/math_opt/core/BUILD.bazel @@ -210,6 +210,7 @@ cc_library( "//ortools/math_opt:result_cc_proto", "//ortools/util:solve_interrupter", "@abseil-cpp//absl/base:core_headers", + "@abseil-cpp//absl/base:nullability", "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/log:die_if_null", @@ -455,6 +456,7 @@ cc_library( "//ortools/math_opt:parameters_cc_proto", "//ortools/math_opt:result_cc_proto", "//ortools/util:solve_interrupter", + "@abseil-cpp//absl/base:nullability", "@abseil-cpp//absl/status:statusor", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/strings:string_view", diff --git a/ortools/math_opt/core/base_solver.h b/ortools/math_opt/core/base_solver.h index 2c26b270f3..d7c2e9c3d1 100644 --- a/ortools/math_opt/core/base_solver.h +++ b/ortools/math_opt/core/base_solver.h @@ -19,6 +19,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/status/statusor.h" #include "ortools/math_opt/callback.pb.h" #include "ortools/math_opt/infeasible_subsystem.pb.h" @@ -78,7 +79,7 @@ class BaseSolver { // An optional interrupter that the solver can use to interrupt the solve // early. - const SolveInterrupter* interrupter = nullptr; + const SolveInterrupter* absl_nullable interrupter = nullptr; friend std::ostream& operator<<(std::ostream& out, const SolveArgs& args); }; @@ -96,7 +97,7 @@ class BaseSolver { // An optional interrupter that the solver can use to interrupt the solve // early. - const SolveInterrupter* interrupter = nullptr; + const SolveInterrupter* absl_nullable interrupter = nullptr; friend std::ostream& operator<<(std::ostream& out, const ComputeInfeasibleSubsystemArgs& args); diff --git a/ortools/math_opt/core/solver_interface.h b/ortools/math_opt/core/solver_interface.h index 845a7f1f11..1127ad0cd8 100644 --- a/ortools/math_opt/core/solver_interface.h +++ b/ortools/math_opt/core/solver_interface.h @@ -146,7 +146,7 @@ class SolverInterface { const ModelSolveParametersProto& model_parameters, MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, Callback cb, - const SolveInterrupter* interrupter) = 0; + const SolveInterrupter* absl_nullable interrupter) = 0; // Updates the model to solve and returns true, or returns false if this // update is not supported. @@ -173,9 +173,9 @@ class SolverInterface { // When parameter `message_cb` is not null and the underlying solver does not // supports message callbacks, it should ignore it. virtual absl::StatusOr - ComputeInfeasibleSubsystem(const SolveParametersProto& parameters, - MessageCallback message_cb, - const SolveInterrupter* interrupter) = 0; + ComputeInfeasibleSubsystem( + const SolveParametersProto& parameters, MessageCallback message_cb, + const SolveInterrupter* absl_nullable interrupter) = 0; }; class AllSolversRegistry { diff --git a/ortools/math_opt/core/solver_interface_mock.h b/ortools/math_opt/core/solver_interface_mock.h index 4f69ac903e..6a9683d69c 100644 --- a/ortools/math_opt/core/solver_interface_mock.h +++ b/ortools/math_opt/core/solver_interface_mock.h @@ -71,6 +71,8 @@ #include #include +#include "absl/base/attributes.h" +#include "absl/base/nullability.h" #include "absl/base/thread_annotations.h" #include "absl/log/die_if_null.h" #include "absl/status/statusor.h" @@ -98,7 +100,7 @@ class SolverInterfaceMock : public SolverInterface { const ModelSolveParametersProto& model_parameters, MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, - Callback cb, const SolveInterrupter* interrupter), + Callback cb, const SolveInterrupter* absl_nullable interrupter), (override)); MOCK_METHOD(absl::StatusOr, Update, @@ -107,7 +109,8 @@ class SolverInterfaceMock : public SolverInterface { MOCK_METHOD(absl::StatusOr, ComputeInfeasibleSubsystem, (const SolveParametersProto& parameters, - MessageCallback message_cb, const SolveInterrupter* interrupter), + MessageCallback message_cb, + const SolveInterrupter* absl_nullable interrupter), (override)); }; @@ -136,7 +139,7 @@ class DelegatingSolver : public SolverInterface { const ModelSolveParametersProto& model_parameters, MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, Callback cb, - const SolveInterrupter* const interrupter) override { + const SolveInterrupter* absl_nullable const interrupter) override { return solver_->Solve(parameters, model_parameters, std::move(message_cb), callback_registration, std::move(cb), interrupter); }; @@ -148,7 +151,7 @@ class DelegatingSolver : public SolverInterface { absl::StatusOr ComputeInfeasibleSubsystem( const SolveParametersProto& parameters, MessageCallback message_cb, - const SolveInterrupter* const interrupter) override { + const SolveInterrupter* absl_nullable const interrupter) override { return solver_->ComputeInfeasibleSubsystem( parameters, std::move(message_cb), interrupter); } diff --git a/ortools/math_opt/cpp/BUILD.bazel b/ortools/math_opt/cpp/BUILD.bazel index 762002f206..3ea9efc9b7 100644 --- a/ortools/math_opt/cpp/BUILD.bazel +++ b/ortools/math_opt/cpp/BUILD.bazel @@ -517,6 +517,7 @@ cc_library( "//ortools/math_opt:model_cc_proto", "//ortools/math_opt:model_update_cc_proto", "//ortools/math_opt/storage:model_storage", + "@abseil-cpp//absl/log:die_if_null", "@abseil-cpp//absl/status", "@abseil-cpp//absl/status:statusor", "@abseil-cpp//absl/strings", @@ -531,6 +532,7 @@ cc_library( "//ortools/base:logging", "//ortools/base:source_location", "@abseil-cpp//absl/base:core_headers", + "@abseil-cpp//absl/log:die_if_null", "@abseil-cpp//absl/strings", "@abseil-cpp//absl/synchronization", "@abseil-cpp//absl/types:span", @@ -559,6 +561,7 @@ cc_library( "//ortools/base:status_macros", "//ortools/math_opt/storage:model_storage", "//ortools/util:solve_interrupter", + "@abseil-cpp//absl/base:nullability", "@abseil-cpp//absl/container:flat_hash_set", "@abseil-cpp//absl/status", ], diff --git a/ortools/math_opt/cpp/compute_infeasible_subsystem_arguments.h b/ortools/math_opt/cpp/compute_infeasible_subsystem_arguments.h index 405a11abfd..f5a46e22ce 100644 --- a/ortools/math_opt/cpp/compute_infeasible_subsystem_arguments.h +++ b/ortools/math_opt/cpp/compute_infeasible_subsystem_arguments.h @@ -14,6 +14,7 @@ #ifndef ORTOOLS_MATH_OPT_CPP_COMPUTE_INFEASIBLE_SUBSYSTEM_ARGUMENTS_H_ #define ORTOOLS_MATH_OPT_CPP_COMPUTE_INFEASIBLE_SUBSYSTEM_ARGUMENTS_H_ +#include "absl/base/nullability.h" #include "ortools/math_opt/cpp/message_callback.h" // IWYU pragma: export #include "ortools/math_opt/cpp/parameters.h" // IWYU pragma: export #include "ortools/util/solve_interrupter.h" // IWYU pragma: export @@ -59,7 +60,7 @@ struct ComputeInfeasibleSubsystemArguments { // ComputeInfeasibleSubsystem(model, SolverType::kGurobi, // { .interrupter = interrupter.get() }); // - const SolveInterrupter* interrupter = nullptr; + const SolveInterrupter* absl_nullable interrupter = nullptr; }; } // namespace operations_research::math_opt diff --git a/ortools/math_opt/cpp/message_callback.cc b/ortools/math_opt/cpp/message_callback.cc index b9d6959691..566d190d05 100644 --- a/ortools/math_opt/cpp/message_callback.cc +++ b/ortools/math_opt/cpp/message_callback.cc @@ -20,6 +20,7 @@ #include #include "absl/base/thread_annotations.h" +#include "absl/log/die_if_null.h" #include "absl/strings/string_view.h" #include "absl/synchronization/mutex.h" #include "absl/types/span.h" diff --git a/ortools/math_opt/cpp/solve_arguments.cc b/ortools/math_opt/cpp/solve_arguments.cc index c2df0d6b7a..ab17e4f062 100644 --- a/ortools/math_opt/cpp/solve_arguments.cc +++ b/ortools/math_opt/cpp/solve_arguments.cc @@ -24,17 +24,12 @@ namespace operations_research::math_opt { -absl::Status SolveArguments::CheckModelStorageAndCallback( +absl::Status SolveArguments::CheckModelStorage( const ModelStorageCPtr expected_storage) const { RETURN_IF_ERROR(model_parameters.CheckModelStorage(expected_storage)) << "invalid model_parameters"; RETURN_IF_ERROR(callback_registration.CheckModelStorage(expected_storage)) << "invalid callback_registration"; - - if (callback == nullptr && !callback_registration.events.empty()) { - return absl::InvalidArgumentError( - "no callback was provided to run, but callback events were registered"); - } return absl::OkStatus(); } diff --git a/ortools/math_opt/cpp/solve_arguments.h b/ortools/math_opt/cpp/solve_arguments.h index 115b5529e1..eb3128b3b3 100644 --- a/ortools/math_opt/cpp/solve_arguments.h +++ b/ortools/math_opt/cpp/solve_arguments.h @@ -17,6 +17,7 @@ #ifndef ORTOOLS_MATH_OPT_CPP_SOLVE_ARGUMENTS_H_ #define ORTOOLS_MATH_OPT_CPP_SOLVE_ARGUMENTS_H_ +#include "absl/base/nullability.h" #include "absl/status/status.h" #include "ortools/math_opt/cpp/callback.h" // IWYU pragma: export #include "ortools/math_opt/cpp/message_callback.h" // IWYU pragma: export @@ -82,13 +83,11 @@ struct SolveArguments { // Solve(model, SolverType::kGlop, // { .interrupter = interrupter.get() }); // - const SolveInterrupter* interrupter = nullptr; + const SolveInterrupter* absl_nullable interrupter = nullptr; // Returns a failure if the referenced variables and constraints don't belong - // to the input expected_storage (which must not be nullptr). Also returns a - // failure if callback events are registered but no callback is provided. - absl::Status CheckModelStorageAndCallback( - ModelStorageCPtr expected_storage) const; + // to the input expected_storage (which must not be nullptr). + absl::Status CheckModelStorage(ModelStorageCPtr expected_storage) const; }; } // namespace operations_research::math_opt diff --git a/ortools/math_opt/cpp/solve_arguments_test.cc b/ortools/math_opt/cpp/solve_arguments_test.cc index 0451cd3872..efdcdeb7e7 100644 --- a/ortools/math_opt/cpp/solve_arguments_test.cc +++ b/ortools/math_opt/cpp/solve_arguments_test.cc @@ -27,7 +27,7 @@ namespace { using ::testing::HasSubstr; using ::testing::status::StatusIs; -TEST(CheckModelStorageAndCallbackTest, CorrectModelAndCallback) { +TEST(CheckModelStorageTest, CorrectModelAndCallback) { Model model; const Variable x = model.AddVariable("x"); @@ -41,10 +41,10 @@ TEST(CheckModelStorageAndCallbackTest, CorrectModelAndCallback) { .callback = [](const CallbackData&) { return CallbackResult{}; }, }; - EXPECT_OK(args.CheckModelStorageAndCallback(model.storage())); + EXPECT_OK(args.CheckModelStorage(model.storage())); } -TEST(CheckModelStorageAndCallbackTest, WrongModelInModelParameters) { +TEST(CheckModelStorageTest, WrongModelInModelParameters) { Model model; const Variable x = model.AddVariable("x"); @@ -53,12 +53,12 @@ TEST(CheckModelStorageAndCallbackTest, WrongModelInModelParameters) { }; Model other_model; - EXPECT_THAT(args.CheckModelStorageAndCallback(other_model.storage()), + EXPECT_THAT(args.CheckModelStorage(other_model.storage()), StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("model_parameters"))); } -TEST(CheckModelStorageAndCallbackTest, WrongModelInCallbackRegistration) { +TEST(CheckModelStorageTest, WrongModelInCallbackRegistration) { Model model; const Variable x = model.AddVariable("x"); @@ -72,26 +72,11 @@ TEST(CheckModelStorageAndCallbackTest, WrongModelInCallbackRegistration) { }; Model other_model; - EXPECT_THAT(args.CheckModelStorageAndCallback(other_model.storage()), + EXPECT_THAT(args.CheckModelStorage(other_model.storage()), StatusIs(absl::StatusCode::kInvalidArgument, AllOf(HasSubstr("callback_registration"), HasSubstr("mip_solution_filter")))); } -TEST(CheckModelStorageAndCallbackTest, NoCallbackWithRegisteredEvents) { - Model model; - - const SolveArguments args = { - .callback_registration = - { - .events = {CallbackEvent::kMipSolution}, - }, - }; - - EXPECT_THAT( - args.CheckModelStorageAndCallback(model.storage()), - StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("no callback"))); -} - } // namespace } // namespace operations_research::math_opt diff --git a/ortools/math_opt/cpp/solve_impl.cc b/ortools/math_opt/cpp/solve_impl.cc index 0586b2e7f5..7853821304 100644 --- a/ortools/math_opt/cpp/solve_impl.cc +++ b/ortools/math_opt/cpp/solve_impl.cc @@ -17,6 +17,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/functional/any_invocable.h" #include "absl/log/check.h" #include "absl/memory/memory.h" @@ -44,7 +45,7 @@ absl::StatusOr CallSolve(BaseSolver& solver, const ModelStorageCPtr expected_storage, const SolveArguments& arguments, SolveInterrupter& local_canceller) { - RETURN_IF_ERROR(arguments.CheckModelStorageAndCallback(expected_storage)); + RETURN_IF_ERROR(arguments.CheckModelStorage(expected_storage)); BaseSolver::Callback cb = nullptr; absl::Mutex mutex; @@ -124,7 +125,8 @@ absl::StatusOr CallComputeInfeasibleSubsystem( absl::StatusOr SolveImpl( const BaseSolverFactory solver_factory, const Model& model, const SolverType solver_type, const SolveArguments& solve_args, - const SolveInterrupter* const user_canceller, const bool remove_names) { + const SolveInterrupter* absl_nullable const user_canceller, + const bool remove_names) { SolveInterrupter local_canceller; const ScopedSolveInterrupterCallback user_canceller_cb( user_canceller, [&]() { local_canceller.Interrupt(); }); @@ -139,7 +141,8 @@ absl::StatusOr ComputeInfeasibleSubsystemImpl( const BaseSolverFactory solver_factory, const Model& model, const SolverType solver_type, const ComputeInfeasibleSubsystemArguments& compute_args, - const SolveInterrupter* const user_canceller, const bool remove_names) { + const SolveInterrupter* absl_nullable const user_canceller, + const bool remove_names) { SolveInterrupter local_canceller; const ScopedSolveInterrupterCallback user_canceller_cb( user_canceller, [&]() { local_canceller.Interrupt(); }); @@ -152,10 +155,11 @@ absl::StatusOr ComputeInfeasibleSubsystemImpl( } absl::StatusOr> -IncrementalSolverImpl::New(BaseSolverFactory solver_factory, Model* const model, - const SolverType solver_type, - const SolveInterrupter* const user_canceller, - const bool remove_names) { +IncrementalSolverImpl::New( + BaseSolverFactory solver_factory, Model* const model, + const SolverType solver_type, + const SolveInterrupter* absl_nullable const user_canceller, + const bool remove_names) { if (model == nullptr) { return absl::InvalidArgumentError("input model can't be null"); } diff --git a/ortools/math_opt/cpp/solve_impl.h b/ortools/math_opt/cpp/solve_impl.h index 9c410b4ee2..221fccd6ba 100644 --- a/ortools/math_opt/cpp/solve_impl.h +++ b/ortools/math_opt/cpp/solve_impl.h @@ -16,6 +16,7 @@ #include +#include "absl/base/nullability.h" #include "absl/functional/any_invocable.h" #include "absl/status/statusor.h" #include "ortools/math_opt/core/base_solver.h" @@ -55,12 +56,10 @@ using BaseSolverFactory = // Solves the input model. // // The `user_canceller` parameter is optional. -absl::StatusOr SolveImpl(BaseSolverFactory solver_factory, - const Model& model, - SolverType solver_type, - const SolveArguments& solve_args, - const SolveInterrupter* user_canceller, - bool remove_names); +absl::StatusOr SolveImpl( + BaseSolverFactory solver_factory, const Model& model, + SolverType solver_type, const SolveArguments& solve_args, + const SolveInterrupter* absl_nullable user_canceller, bool remove_names); // ComputeInfeasibleSubsystems the input model in a subprocess. // @@ -69,7 +68,7 @@ absl::StatusOr ComputeInfeasibleSubsystemImpl( BaseSolverFactory solver_factory, const Model& model, SolverType solver_type, const ComputeInfeasibleSubsystemArguments& compute_args, - const SolveInterrupter* user_canceller, bool remove_names); + const SolveInterrupter* absl_nullable user_canceller, bool remove_names); // Incremental solve of a model. class IncrementalSolverImpl : public IncrementalSolver { @@ -79,7 +78,7 @@ class IncrementalSolverImpl : public IncrementalSolver { // The `user_canceller` parameter is optional. static absl::StatusOr> New( BaseSolverFactory solver_factory, Model* model, SolverType solver_type, - const SolveInterrupter* user_canceller, bool remove_names); + const SolveInterrupter* absl_nullable user_canceller, bool remove_names); absl::StatusOr Update() override; diff --git a/ortools/math_opt/cpp/solve_impl_test.cc b/ortools/math_opt/cpp/solve_impl_test.cc index 12f264ddc7..903e8b4ed0 100644 --- a/ortools/math_opt/cpp/solve_impl_test.cc +++ b/ortools/math_opt/cpp/solve_impl_test.cc @@ -484,32 +484,6 @@ TEST(SolveImplTest, FailingSolve) { StatusIs(absl::StatusCode::kInternal, "solve failed")); } -TEST(SolveImplTest, NullCallback) { - BasicLp basic_lp; - - SolveArguments args; - args.parameters.enable_output = true; - - args.model_parameters = - ModelSolveParameters::OnlySomePrimalVariables({basic_lp.a}); - - args.callback_registration.add_lazy_constraints = true; - args.callback_registration.events.insert(CallbackEvent::kMipSolution); - - BaseSolverFactoryMock factory_mock; - BaseSolverMock solver; - EXPECT_CALL(factory_mock, Call(SOLVER_TYPE_GLOP, - EquivToProto(basic_lp.model.ExportModel()), _)) - .WillOnce( - Return(ByMove(std::make_unique(&solver)))); - - EXPECT_THAT( - SolveImpl(factory_mock.AsStdFunction(), basic_lp.model, SolverType::kGlop, - args, /*user_canceller=*/nullptr, /*remove_names=*/false), - StatusIs(absl::StatusCode::kInvalidArgument, - HasSubstr("no callback was provided"))); -} - TEST(SolveImplTest, WrongModelInModelParameters) { BasicLp basic_lp; BasicLp other_basic_lp; @@ -1593,40 +1567,6 @@ TEST(IncrementalSolverImplTest, UpdateAndSolveWithFailingSolverUpdate) { HasSubstr("update failed")))); } -TEST(IncrementalSolverImplTest, NullCallback) { - BasicLp basic_lp; - - SolveArguments args; - args.parameters.enable_output = true; - - args.model_parameters = - ModelSolveParameters::OnlySomePrimalVariables({basic_lp.a}); - - args.callback_registration.add_lazy_constraints = true; - args.callback_registration.events.insert(CallbackEvent::kMipSolution); - - BaseSolverFactoryMock factory_mock; - BaseSolverMock solver_interface; - - EXPECT_CALL(factory_mock, Call(SOLVER_TYPE_GLOP, - EquivToProto(basic_lp.model.ExportModel()), _)) - .WillOnce(Return( - ByMove(std::make_unique(&solver_interface)))); - - ASSERT_OK_AND_ASSIGN( - std::unique_ptr solver, - IncrementalSolverImpl::New( - factory_mock.AsStdFunction(), &basic_lp.model, SolverType::kGlop, - /*user_canceller=*/nullptr, /*remove_names=*/false)); - - Mock::VerifyAndClearExpectations(&factory_mock); - Mock::VerifyAndClearExpectations(&solver_interface); - - EXPECT_THAT(solver->SolveWithoutUpdate(args), - StatusIs(absl::StatusCode::kInvalidArgument, - HasSubstr("no callback was provided"))); -} - TEST(IncrementalSolverImplTest, WrongModelInModelParameters) { BasicLp basic_lp; BasicLp other_basic_lp; diff --git a/ortools/math_opt/cpp/solve_test.cc b/ortools/math_opt/cpp/solve_test.cc index fc591aade6..ae5948290a 100644 --- a/ortools/math_opt/cpp/solve_test.cc +++ b/ortools/math_opt/cpp/solve_test.cc @@ -19,6 +19,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/container/flat_hash_set.h" #include "absl/status/status.h" #include "absl/status/statusor.h" @@ -53,7 +54,6 @@ using ::testing::HasSubstr; using ::testing::InSequence; using ::testing::Mock; using ::testing::Ne; -using ::testing::Optional; using ::testing::Pair; using ::testing::Return; using ::testing::UnorderedElementsAre; @@ -184,7 +184,7 @@ TEST(SolveTest, SuccessfulSolveWithCallback) { [&](const SolveParametersProto&, const ModelSolveParametersProto&, const MessageCallback message_cb, const CallbackRegistrationProto&, SolverInterface::Callback cb, - const SolveInterrupter* const interrupter) + const SolveInterrupter* absl_nullable const interrupter) -> absl::StatusOr { CallbackDataProto cb_data; cb_data.set_event(CALLBACK_EVENT_MIP_SOLUTION); @@ -345,10 +345,10 @@ TEST(SolveTest, NullCallback) { EXPECT_CALL(factory_mock, Call(EquivToProto(basic_lp.model.ExportModel()), _)) .WillOnce(Return(ByMove(std::make_unique(&solver)))); - EXPECT_THAT(Solve(basic_lp.model, - EnumFromProto(registration.solver_type()).value(), args), - StatusIs(absl::StatusCode::kInvalidArgument, - HasSubstr("no callback was provided"))); + EXPECT_THAT( + Solve(basic_lp.model, EnumFromProto(registration.solver_type()).value(), + args), + StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("no callback"))); } TEST(SolveTest, WrongModelInModelParameters) { @@ -416,7 +416,7 @@ TEST(SolveTest, WrongModelInCallbackResult) { [&](const SolveParametersProto&, const ModelSolveParametersProto&, const MessageCallback message_cb, const CallbackRegistrationProto&, SolverInterface::Callback cb, - const SolveInterrupter* const interrupter) + const SolveInterrupter* absl_nullable const interrupter) -> absl::StatusOr { CallbackDataProto cb_data; cb_data.set_event(CALLBACK_EVENT_MIP_SOLUTION); @@ -961,7 +961,7 @@ TEST(IncrementalSolverTest, SuccessfulSolveWithCallback) { [&](const SolveParametersProto&, const ModelSolveParametersProto&, const MessageCallback message_cb, const CallbackRegistrationProto&, SolverInterface::Callback cb, - const SolveInterrupter* const interrupter) + const SolveInterrupter* absl_nullable const interrupter) -> absl::StatusOr { CallbackDataProto cb_data; cb_data.set_event(CALLBACK_EVENT_MIP_SOLUTION); @@ -1137,7 +1137,7 @@ TEST(IncrementalSolverTest, UpdateAndSolve) { [&](const SolveParametersProto&, const ModelSolveParametersProto&, const MessageCallback message_cb, const CallbackRegistrationProto&, SolverInterface::Callback cb, - const SolveInterrupter* const interrupter) + const SolveInterrupter* absl_nullable const interrupter) -> absl::StatusOr { CallbackDataProto cb_data; cb_data.set_event(CALLBACK_EVENT_MIP_SOLUTION); @@ -1306,9 +1306,9 @@ TEST(IncrementalSolverTest, NullCallback) { Mock::VerifyAndClearExpectations(&factory_mock); Mock::VerifyAndClearExpectations(&solver_interface); - EXPECT_THAT(solver->SolveWithoutUpdate(args), - StatusIs(absl::StatusCode::kInvalidArgument, - HasSubstr("no callback was provided"))); + EXPECT_THAT( + solver->SolveWithoutUpdate(args), + StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("no callback"))); } TEST(IncrementalSolverTest, WrongModelInModelParameters) { @@ -1395,7 +1395,7 @@ TEST(IncrementalSolverTest, WrongModelInCallbackResult) { [&](const SolveParametersProto&, const ModelSolveParametersProto&, const MessageCallback message_cb, const CallbackRegistrationProto&, SolverInterface::Callback cb, - const SolveInterrupter* const interrupter) + const SolveInterrupter* absl_nullable const interrupter) -> absl::StatusOr { CallbackDataProto cb_data; cb_data.set_event(CALLBACK_EVENT_MIP_SOLUTION); diff --git a/ortools/math_opt/cpp/update_tracker.cc b/ortools/math_opt/cpp/update_tracker.cc index c96a6f9fb1..1a9339c02e 100644 --- a/ortools/math_opt/cpp/update_tracker.cc +++ b/ortools/math_opt/cpp/update_tracker.cc @@ -16,6 +16,7 @@ #include #include +#include "absl/log/die_if_null.h" #include "absl/status/status.h" #include "absl/status/statusor.h" #include "ortools/base/logging.h" diff --git a/ortools/math_opt/solvers/BUILD.bazel b/ortools/math_opt/solvers/BUILD.bazel index 277a971804..bd18d2953c 100644 --- a/ortools/math_opt/solvers/BUILD.bazel +++ b/ortools/math_opt/solvers/BUILD.bazel @@ -54,6 +54,7 @@ cc_library( "//ortools/math_opt/validators:callback_validator", "//ortools/port:proto_utils", "//ortools/util:solve_interrupter", + "@abseil-cpp//absl/base:nullability", "@abseil-cpp//absl/cleanup", "@abseil-cpp//absl/container:flat_hash_map", "@abseil-cpp//absl/container:flat_hash_set", @@ -141,12 +142,12 @@ cc_library( "//ortools/util:solve_interrupter", "//ortools/util:testing_utils", "@abseil-cpp//absl/algorithm:container", + "@abseil-cpp//absl/base:nullability", "@abseil-cpp//absl/container:flat_hash_map", "@abseil-cpp//absl/container:flat_hash_set", "@abseil-cpp//absl/log", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/memory", - "@abseil-cpp//absl/meta:type_traits", "@abseil-cpp//absl/status", "@abseil-cpp//absl/status:statusor", "@abseil-cpp//absl/strings", @@ -193,6 +194,7 @@ cc_library( "//ortools/util:solve_interrupter", "//ortools/util:strong_integers", "//ortools/util:time_limit", + "@abseil-cpp//absl/base:nullability", "@abseil-cpp//absl/cleanup", "@abseil-cpp//absl/container:flat_hash_map", "@abseil-cpp//absl/log", @@ -387,6 +389,7 @@ cc_library( "//ortools/pdlp:solvers_cc_proto", "//ortools/port:proto_utils", "//ortools/util:solve_interrupter", + "@abseil-cpp//absl/base:nullability", "@abseil-cpp//absl/log", "@abseil-cpp//absl/memory", "@abseil-cpp//absl/status", @@ -469,6 +472,7 @@ cc_library( "//ortools/third_party_solvers/glpk:glpk_env_deleter", "//ortools/third_party_solvers/glpk:glpk_formatters", "//ortools/util:solve_interrupter", + "@abseil-cpp//absl/base:nullability", "@abseil-cpp//absl/cleanup", "@abseil-cpp//absl/container:flat_hash_map", "@abseil-cpp//absl/log", @@ -568,6 +572,7 @@ cc_library( "//ortools/util:solve_interrupter", "//ortools/util:status_macros", "@abseil-cpp//absl/algorithm:container", + "@abseil-cpp//absl/base:nullability", "@abseil-cpp//absl/cleanup", "@abseil-cpp//absl/container:flat_hash_map", "@abseil-cpp//absl/log:check", @@ -706,6 +711,7 @@ cc_library( "//ortools/port:proto_utils", "//ortools/third_party_solvers:xpress_environment", "//ortools/util:solve_interrupter", + "@abseil-cpp//absl/base:nullability", "@abseil-cpp//absl/log:check", "@abseil-cpp//absl/memory", "@abseil-cpp//absl/status", diff --git a/ortools/math_opt/solvers/cp_sat_solver.cc b/ortools/math_opt/solvers/cp_sat_solver.cc index c4da11cb14..67f0345650 100644 --- a/ortools/math_opt/solvers/cp_sat_solver.cc +++ b/ortools/math_opt/solvers/cp_sat_solver.cc @@ -503,7 +503,7 @@ absl::StatusOr CpSatSolver::Solve( const ModelSolveParametersProto& model_parameters, const MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, const Callback cb, - const SolveInterrupter* const interrupter) { + const SolveInterrupter* absl_nullable interrupter) { RETURN_IF_ERROR(ModelSolveParametersAreSupported( model_parameters, kCpSatSupportedStructures, "CP-SAT")); const absl::Time start = absl::Now(); @@ -675,7 +675,7 @@ InvertedBounds CpSatSolver::ListInvertedBounds() const { absl::StatusOr CpSatSolver::ComputeInfeasibleSubsystem(const SolveParametersProto&, MessageCallback, - const SolveInterrupter*) { + const SolveInterrupter* absl_nullable) { return absl::UnimplementedError( "CPSAT does not provide a method to compute an infeasible subsystem"); } diff --git a/ortools/math_opt/solvers/cp_sat_solver.h b/ortools/math_opt/solvers/cp_sat_solver.h index a7c0dbe9cf..d2bbbae968 100644 --- a/ortools/math_opt/solvers/cp_sat_solver.h +++ b/ortools/math_opt/solvers/cp_sat_solver.h @@ -18,6 +18,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/status/statusor.h" #include "absl/types/span.h" #include "ortools/linear_solver/linear_solver.pb.h" @@ -46,12 +47,12 @@ class CpSatSolver : public SolverInterface { const ModelSolveParametersProto& model_parameters, MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, Callback cb, - const SolveInterrupter* interrupter) override; + const SolveInterrupter* absl_nullable interrupter) override; absl::StatusOr Update(const ModelUpdateProto& model_update) override; absl::StatusOr - ComputeInfeasibleSubsystem(const SolveParametersProto& parameters, - MessageCallback message_cb, - const SolveInterrupter* interrupter) override; + ComputeInfeasibleSubsystem( + const SolveParametersProto& parameters, MessageCallback message_cb, + const SolveInterrupter* absl_nullable interrupter) override; private: CpSatSolver(MPModelProto cp_sat_model, std::vector variable_ids, diff --git a/ortools/math_opt/solvers/glop_solver.cc b/ortools/math_opt/solvers/glop_solver.cc index 8b5379ba97..cdb666989d 100644 --- a/ortools/math_opt/solvers/glop_solver.cc +++ b/ortools/math_opt/solvers/glop_solver.cc @@ -21,6 +21,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/cleanup/cleanup.h" #include "absl/container/flat_hash_map.h" #include "absl/log/check.h" @@ -87,7 +88,8 @@ absl::string_view SafeName(const LinearConstraintsProto& linear_constraints, } absl::StatusOr BuildTermination( - const glop::ProblemStatus status, const SolveInterrupter* const interrupter, + const glop::ProblemStatus status, + const SolveInterrupter* absl_nullable const interrupter, const bool is_maximize, const double objective_value) { switch (status) { case glop::ProblemStatus::OPTIMAL: @@ -730,7 +732,7 @@ absl::Status GlopSolver::FillSolveStats(const absl::Duration solve_time, absl::StatusOr GlopSolver::MakeSolveResult( const glop::ProblemStatus status, const ModelSolveParametersProto& model_parameters, - const SolveInterrupter* const interrupter, + const SolveInterrupter* absl_nullable const interrupter, const absl::Duration solve_time) { SolveResultProto solve_result; ASSIGN_OR_RETURN(*solve_result.mutable_termination(), @@ -765,7 +767,7 @@ absl::StatusOr GlopSolver::Solve( const ModelSolveParametersProto& model_parameters, const MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, const Callback, - const SolveInterrupter* const interrupter) { + const SolveInterrupter* absl_nullable const interrupter) { RETURN_IF_ERROR(ModelSolveParametersAreSupported( model_parameters, kGlopSupportedStructures, "Glop")); RETURN_IF_ERROR(CheckRegisteredCallbackEvents(callback_registration, @@ -886,7 +888,7 @@ absl::StatusOr GlopSolver::Update(const ModelUpdateProto& model_update) { absl::StatusOr GlopSolver::ComputeInfeasibleSubsystem(const SolveParametersProto&, MessageCallback, - const SolveInterrupter*) { + const SolveInterrupter* absl_nullable) { return absl::UnimplementedError( "GLOP does not implement a method to compute an infeasible subsystem"); } diff --git a/ortools/math_opt/solvers/glop_solver.h b/ortools/math_opt/solvers/glop_solver.h index b80893ab27..1778974ac2 100644 --- a/ortools/math_opt/solvers/glop_solver.h +++ b/ortools/math_opt/solvers/glop_solver.h @@ -18,6 +18,7 @@ #include +#include "absl/base/nullability.h" #include "absl/container/flat_hash_map.h" #include "absl/status/status.h" #include "absl/status/statusor.h" @@ -53,12 +54,12 @@ class GlopSolver : public SolverInterface { const ModelSolveParametersProto& model_parameters, MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, Callback cb, - const SolveInterrupter* interrupter) override; + const SolveInterrupter* absl_nullable interrupter) override; absl::StatusOr Update(const ModelUpdateProto& model_update) override; absl::StatusOr - ComputeInfeasibleSubsystem(const SolveParametersProto& parameters, - MessageCallback message_cb, - const SolveInterrupter* interrupter) override; + ComputeInfeasibleSubsystem( + const SolveParametersProto& parameters, MessageCallback message_cb, + const SolveInterrupter* absl_nullable interrupter) override; // Returns the merged parameters and a list of warnings from any parameter // settings that are invalid for this solver. @@ -93,7 +94,8 @@ class GlopSolver : public SolverInterface { absl::StatusOr MakeSolveResult( glop::ProblemStatus status, const ModelSolveParametersProto& model_parameters, - const SolveInterrupter* interrupter, absl::Duration solve_time); + const SolveInterrupter* absl_nullable interrupter, + absl::Duration solve_time); absl::Status FillSolveStats(absl::Duration solve_time, SolveStatsProto& solve_stats); diff --git a/ortools/math_opt/solvers/glpk_solver.cc b/ortools/math_opt/solvers/glpk_solver.cc index 1195b7a0c2..a41bdc4b28 100644 --- a/ortools/math_opt/solvers/glpk_solver.cc +++ b/ortools/math_opt/solvers/glpk_solver.cc @@ -27,6 +27,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/cleanup/cleanup.h" #include "absl/container/flat_hash_map.h" #include "absl/log/check.h" @@ -490,7 +491,8 @@ absl::Status SetLPParameters(const SolveParametersProto& parameters, class MipCallbackData { public: - explicit MipCallbackData(const SolveInterrupter* const interrupter) + explicit MipCallbackData( + const SolveInterrupter* absl_nullable const interrupter) : interrupter_(interrupter) {} void Callback(glp_tree* const tree) { @@ -540,7 +542,7 @@ class MipCallbackData { private: // Optional interrupter. - const SolveInterrupter* const interrupter_; + const SolveInterrupter* absl_nullable const interrupter_; // Set to true if glp_ios_terminate() has been called due to the interrupter. std::atomic interrupted_by_interrupter_ = false; @@ -1059,7 +1061,8 @@ absl::StatusOr GlpkSolver::Solve( const ModelSolveParametersProto& model_parameters, MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, - const Callback /*cb*/, const SolveInterrupter* const interrupter) { + const Callback /*cb*/, + const SolveInterrupter* absl_nullable const interrupter) { RETURN_IF_ERROR(ModelSolveParametersAreSupported( model_parameters, kGlpkSupportedStructures, "GLPK")); RETURN_IF_ERROR(CheckCurrentThread()); @@ -1808,7 +1811,7 @@ std::optional GlpkSolver::EmptyIntegerBoundsResult() { absl::StatusOr GlpkSolver::ComputeInfeasibleSubsystem( const SolveParametersProto& parameters, MessageCallback message_cb, - const SolveInterrupter* const interrupter) { + const SolveInterrupter* absl_nullable const interrupter) { return absl::UnimplementedError( "GLPK does not provide a method to compute an infeasible subsystem"); } diff --git a/ortools/math_opt/solvers/glpk_solver.h b/ortools/math_opt/solvers/glpk_solver.h index 790ae48e68..57512f0e37 100644 --- a/ortools/math_opt/solvers/glpk_solver.h +++ b/ortools/math_opt/solvers/glpk_solver.h @@ -20,6 +20,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/container/flat_hash_map.h" #include "absl/log/log.h" #include "absl/status/status.h" @@ -55,12 +56,12 @@ class GlpkSolver : public SolverInterface { const ModelSolveParametersProto& model_parameters, MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, Callback cb, - const SolveInterrupter* interrupter) override; + const SolveInterrupter* absl_nullable interrupter) override; absl::StatusOr Update(const ModelUpdateProto& model_update) override; absl::StatusOr - ComputeInfeasibleSubsystem(const SolveParametersProto& parameters, - MessageCallback message_cb, - const SolveInterrupter* interrupter) override; + ComputeInfeasibleSubsystem( + const SolveParametersProto& parameters, MessageCallback message_cb, + const SolveInterrupter* absl_nullable interrupter) override; private: // The columns of the GPLK problem. diff --git a/ortools/math_opt/solvers/gscip_solver.cc b/ortools/math_opt/solvers/gscip_solver.cc index 85193b55b7..800e2a88f9 100644 --- a/ortools/math_opt/solvers/gscip_solver.cc +++ b/ortools/math_opt/solvers/gscip_solver.cc @@ -23,6 +23,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/cleanup/cleanup.h" #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" @@ -1013,7 +1014,7 @@ absl::StatusOr GScipSolver::Solve( const ModelSolveParametersProto& model_parameters, const MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, Callback cb, - const SolveInterrupter* const interrupter) { + const SolveInterrupter* absl_nullable const interrupter) { RETURN_IF_ERROR(ModelSolveParametersAreSupported( model_parameters, kGscipSupportedStructures, "SCIP")); const absl::Time start = absl::Now(); @@ -1353,7 +1354,7 @@ absl::StatusOr GScipSolver::Update(const ModelUpdateProto& model_update) { absl::StatusOr GScipSolver::ComputeInfeasibleSubsystem(const SolveParametersProto&, MessageCallback, - const SolveInterrupter*) { + const SolveInterrupter* absl_nullable) { return absl::UnimplementedError( "SCIP does not provide a method to compute an infeasible subsystem"); } diff --git a/ortools/math_opt/solvers/gscip_solver.h b/ortools/math_opt/solvers/gscip_solver.h index d31b05e18b..21d3586b45 100644 --- a/ortools/math_opt/solvers/gscip_solver.h +++ b/ortools/math_opt/solvers/gscip_solver.h @@ -20,6 +20,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/status/status.h" @@ -58,12 +59,12 @@ class GScipSolver : public SolverInterface { const ModelSolveParametersProto& model_parameters, MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, Callback cb, - const SolveInterrupter* interrupter) override; + const SolveInterrupter* absl_nullable interrupter) override; absl::StatusOr Update(const ModelUpdateProto& model_update) override; absl::StatusOr - ComputeInfeasibleSubsystem(const SolveParametersProto& parameters, - MessageCallback message_cb, - const SolveInterrupter* interrupter) override; + ComputeInfeasibleSubsystem( + const SolveParametersProto& parameters, MessageCallback message_cb, + const SolveInterrupter* absl_nullable interrupter) override; // Returns the merged parameters and a list of warnings for unsupported // parameters. diff --git a/ortools/math_opt/solvers/gurobi_solver.cc b/ortools/math_opt/solvers/gurobi_solver.cc index 136919e7f2..e13c4d01c8 100644 --- a/ortools/math_opt/solvers/gurobi_solver.cc +++ b/ortools/math_opt/solvers/gurobi_solver.cc @@ -26,6 +26,7 @@ #include #include "absl/algorithm/container.h" +#include "absl/base/nullability.h" #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/log/check.h" @@ -2145,8 +2146,8 @@ absl::Status GurobiSolver::ChangeCoefficients( } absl::Status GurobiSolver::UpdateDoubleListAttribute( - const SparseDoubleVectorProto& update, const char* attribute_name, - const IdHashMap& id_hash_map) { + const SparseDoubleVectorProto& update, + const char* absl_nonnull attribute_name, const IdHashMap& id_hash_map) { if (update.ids_size() == 0) { return absl::OkStatus(); } @@ -2159,8 +2160,8 @@ absl::Status GurobiSolver::UpdateDoubleListAttribute( } absl::Status GurobiSolver::UpdateInt32ListAttribute( - const SparseInt32VectorProto& update, const char* attribute_name, - const IdHashMap& id_hash_map) { + const SparseInt32VectorProto& update, + const char* absl_nonnull attribute_name, const IdHashMap& id_hash_map) { if (update.ids_size() == 0) { return absl::OkStatus(); } @@ -2782,11 +2783,10 @@ absl::StatusOr> GurobiSolver::New( } absl::StatusOr> -GurobiSolver::RegisterCallback(const CallbackRegistrationProto& registration, - const Callback cb, - const MessageCallback message_cb, - const absl::Time start, - SolveInterrupter* const local_interrupter) { +GurobiSolver::RegisterCallback( + const CallbackRegistrationProto& registration, const Callback cb, + const MessageCallback message_cb, const absl::Time start, + SolveInterrupter* absl_nullable const local_interrupter) { const absl::flat_hash_set events = EventSet(registration); // Note that IS_MIP does not necessarily mean the problem has integer @@ -2971,7 +2971,7 @@ absl::StatusOr GurobiSolver::Solve( const ModelSolveParametersProto& model_parameters, const MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, const Callback cb, - const SolveInterrupter* const interrupter) { + const SolveInterrupter* absl_nullable const interrupter) { RETURN_IF_ERROR(ModelSolveParametersAreSupported( model_parameters, kGurobiSupportedStructures, "Gurobi")); const absl::Time start = absl::Now(); @@ -3102,7 +3102,7 @@ absl::StatusOr GurobiSolver::Solve( absl::StatusOr GurobiSolver::ComputeInfeasibleSubsystem( const SolveParametersProto& parameters, MessageCallback message_cb, - const SolveInterrupter* const interrupter) { + const SolveInterrupter* absl_nullable const interrupter) { const absl::Time start = absl::Now(); // Need to run GRBupdatemodel before: diff --git a/ortools/math_opt/solvers/gurobi_solver.h b/ortools/math_opt/solvers/gurobi_solver.h index 9cacb995df..0fd2c4b4ae 100644 --- a/ortools/math_opt/solvers/gurobi_solver.h +++ b/ortools/math_opt/solvers/gurobi_solver.h @@ -21,6 +21,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/container/flat_hash_map.h" #include "absl/container/flat_hash_set.h" #include "absl/status/status.h" @@ -60,17 +61,18 @@ class GurobiSolver : public SolverInterface { const ModelSolveParametersProto& model_parameters, MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, Callback cb, - const SolveInterrupter* interrupter) override; + const SolveInterrupter* absl_nullable interrupter) override; absl::StatusOr Update(const ModelUpdateProto& model_update) override; absl::StatusOr - ComputeInfeasibleSubsystem(const SolveParametersProto& parameters, - MessageCallback message_cb, - const SolveInterrupter* interrupter) override; + ComputeInfeasibleSubsystem( + const SolveParametersProto& parameters, MessageCallback message_cb, + const SolveInterrupter* absl_nullable interrupter) override; private: struct GurobiCallbackData { - explicit GurobiCallbackData(GurobiCallbackInput callback_input, - SolveInterrupter* const local_interrupter) + explicit GurobiCallbackData( + GurobiCallbackInput callback_input, + SolveInterrupter* absl_nullable const local_interrupter) : callback_input(std::move(callback_input)), local_interrupter(local_interrupter) {} const GurobiCallbackInput callback_input; @@ -83,7 +85,7 @@ class GurobiSolver : public SolverInterface { // // It is optional; it is not null when either we have a LP/MIP callback or a // user interrupter. But it can be null if we only have a message callback. - SolveInterrupter* const local_interrupter; + SolveInterrupter* absl_nullable const local_interrupter; MessageCallbackData message_callback_data; @@ -305,11 +307,11 @@ class GurobiSolver : public SolverInterface { const SparseDoubleMatrixProto& terms); absl::Status LoadModel(const ModelProto& input_model); - absl::Status UpdateDoubleListAttribute(const SparseDoubleVectorProto& update, - const char* attribute_name, - const IdHashMap& id_hash_map); + absl::Status UpdateDoubleListAttribute( + const SparseDoubleVectorProto& update, + const char* absl_nonnull attribute_name, const IdHashMap& id_hash_map); absl::Status UpdateInt32ListAttribute(const SparseInt32VectorProto& update, - const char* attribute_name, + const char* absl_nonnull attribute_name, const IdHashMap& id_hash_map); struct DeletedIndices { @@ -354,7 +356,7 @@ class GurobiSolver : public SolverInterface { absl::StatusOr> RegisterCallback( const CallbackRegistrationProto& registration, Callback cb, MessageCallback message_cb, absl::Time start, - SolveInterrupter* local_interrupter); + SolveInterrupter* absl_nullable local_interrupter); // Returns the ids of variables and linear constraints with inverted bounds. absl::StatusOr ListInvertedBounds() const; diff --git a/ortools/math_opt/solvers/highs_solver.cc b/ortools/math_opt/solvers/highs_solver.cc index 0bf7506b27..88fd2cd757 100644 --- a/ortools/math_opt/solvers/highs_solver.cc +++ b/ortools/math_opt/solvers/highs_solver.cc @@ -31,6 +31,7 @@ #include "Highs.h" #include "absl/algorithm/container.h" +#include "absl/base/nullability.h" #include "absl/cleanup/cleanup.h" #include "absl/container/flat_hash_map.h" #include "absl/log/check.h" @@ -912,7 +913,7 @@ absl::StatusOr HighsSolver::Solve( const SolveParametersProto& parameters, const ModelSolveParametersProto& model_parameters, MessageCallback message_cb, const CallbackRegistrationProto&, Callback, - const SolveInterrupter* const) { + const SolveInterrupter* absl_nullable const) { RETURN_IF_ERROR(ModelSolveParametersAreSupported( model_parameters, kHighsSupportedStructures, "Highs")); const absl::Time start = absl::Now(); @@ -1031,7 +1032,7 @@ absl::StatusOr HighsSolver::Update(const ModelUpdateProto&) { absl::StatusOr HighsSolver::ComputeInfeasibleSubsystem(const SolveParametersProto&, MessageCallback, - const SolveInterrupter*) { + const SolveInterrupter* absl_nullable) { return absl::UnimplementedError( "HiGHS does not provide a method to compute an infeasible subsystem"); } diff --git a/ortools/math_opt/solvers/highs_solver.h b/ortools/math_opt/solvers/highs_solver.h index eaba4360a6..5b0e503467 100644 --- a/ortools/math_opt/solvers/highs_solver.h +++ b/ortools/math_opt/solvers/highs_solver.h @@ -22,6 +22,7 @@ #include #include "Highs.h" +#include "absl/base/nullability.h" #include "absl/container/flat_hash_map.h" #include "absl/status/status.h" #include "absl/status/statusor.h" @@ -51,12 +52,12 @@ class HighsSolver : public SolverInterface { const ModelSolveParametersProto& model_parameters, MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, Callback cb, - const SolveInterrupter* interrupter) override; + const SolveInterrupter* absl_nullable interrupter) override; absl::StatusOr Update(const ModelUpdateProto& model_update) override; absl::StatusOr - ComputeInfeasibleSubsystem(const SolveParametersProto& parameters, - MessageCallback message_cb, - const SolveInterrupter* interrupter) override; + ComputeInfeasibleSubsystem( + const SolveParametersProto& parameters, MessageCallback message_cb, + const SolveInterrupter* absl_nullable interrupter) override; private: struct SolutionClaims { diff --git a/ortools/math_opt/solvers/pdlp_solver.cc b/ortools/math_opt/solvers/pdlp_solver.cc index 537162add0..13d0f15e9e 100644 --- a/ortools/math_opt/solvers/pdlp_solver.cc +++ b/ortools/math_opt/solvers/pdlp_solver.cc @@ -24,6 +24,7 @@ #include #include +#include "absl/base/nullability.h" #include "absl/log/log.h" #include "absl/memory/memory.h" #include "absl/status/status.h" @@ -336,7 +337,7 @@ absl::StatusOr PdlpSolver::Solve( const ModelSolveParametersProto& model_parameters, const MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, const Callback, - const SolveInterrupter* const interrupter) { + const SolveInterrupter* absl_nullable const interrupter) { RETURN_IF_ERROR(ModelSolveParametersAreSupported( model_parameters, kPdlpSupportedStructures, "PDLP")); RETURN_IF_ERROR(CheckRegisteredCallbackEvents(callback_registration, @@ -381,7 +382,7 @@ absl::StatusOr PdlpSolver::Update(const ModelUpdateProto&) { absl::StatusOr PdlpSolver::ComputeInfeasibleSubsystem(const SolveParametersProto&, MessageCallback, - const SolveInterrupter*) { + const SolveInterrupter* absl_nullable) { return absl::UnimplementedError( "PDLP does not provide a method to compute an infeasible subsystem"); } diff --git a/ortools/math_opt/solvers/pdlp_solver.h b/ortools/math_opt/solvers/pdlp_solver.h index edca6bd50d..183bc186c0 100644 --- a/ortools/math_opt/solvers/pdlp_solver.h +++ b/ortools/math_opt/solvers/pdlp_solver.h @@ -16,6 +16,7 @@ #include +#include "absl/base/nullability.h" #include "absl/status/statusor.h" #include "ortools/math_opt/callback.pb.h" #include "ortools/math_opt/core/solver_interface.h" @@ -43,12 +44,12 @@ class PdlpSolver : public SolverInterface { const ModelSolveParametersProto& model_parameters, MessageCallback message_cb, const CallbackRegistrationProto& callback_registration, Callback cb, - const SolveInterrupter* interrupter) override; + const SolveInterrupter* absl_nullable interrupter) override; absl::StatusOr Update(const ModelUpdateProto& model_update) override; absl::StatusOr - ComputeInfeasibleSubsystem(const SolveParametersProto& parameters, - MessageCallback message_cb, - const SolveInterrupter* interrupter) override; + ComputeInfeasibleSubsystem( + const SolveParametersProto& parameters, MessageCallback message_cb, + const SolveInterrupter* absl_nullable interrupter) override; // Returns the merged parameters and a list of warnings. static absl::StatusOr MergeParameters(