diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c0b9f64..26aa14c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,8 +4,8 @@ repos: rev: v1.3.5 hooks: - id: clang-format - exclude: _clingodl.c + exclude: _clingolpx.c args: ["-i"] - id: clang-tidy - exclude: _clingodl.c + exclude: _clingolpx.c args: ["-fix"] diff --git a/app/lib/clingo-lpx-app/app.hh b/app/lib/clingo-lpx-app/app.hh index fb154a4..69090c5 100644 --- a/app/lib/clingo-lpx-app/app.hh +++ b/app/lib/clingo-lpx-app/app.hh @@ -25,27 +25,27 @@ #ifndef CLINGOLPX_APP_HH #define CLINGOLPX_APP_HH -#include #include +#include #include namespace ClingoLPX { //! Helper class to rewrite logic programs to use with the clingo DL theory. class Rewriter { -public: + public: Rewriter(clingolpx_theory_t *theory, clingo_program_builder_t *builder); //! Rewrite the given files. void rewrite(Clingo::Control &control, Clingo::StringSpan files); //! Rewrite the given program. void rewrite(Clingo::Control &control, char const *str); -private: + private: //! C callback to add a statement using the builder. - static bool add_(clingo_ast_t *stm, void *data); + static auto add_(clingo_ast_t *stm, void *data) -> bool; //! C callback to rewrite a statement and add it via the builder. - static bool rewrite_(clingo_ast_t *stm, void *data); + static auto rewrite_(clingo_ast_t *stm, void *data) -> bool; clingolpx_theory_t *theory_; //!< A theory handle to rewrite statements. clingo_program_builder_t *builder_; //!< The builder to add rewritten statements to. diff --git a/app/lib/src/app.cc b/app/lib/src/app.cc index 456bb16..64a7fac 100644 --- a/app/lib/src/app.cc +++ b/app/lib/src/app.cc @@ -25,32 +25,31 @@ #include #include +#include #include #include -#include namespace ClingoLPX { Rewriter::Rewriter(clingolpx_theory_t *theory, clingo_program_builder_t *builder) -: theory_{theory} -, builder_{builder} { -} + : theory_{theory}, builder_{builder} {} void Rewriter::rewrite(Clingo::Control &control, Clingo::StringSpan files) { - Clingo::Detail::handle_error(clingo_ast_parse_files(files.begin(), files.size(), rewrite_, this, control.to_c(), nullptr, nullptr, 0)); + Clingo::Detail::handle_error( + clingo_ast_parse_files(files.begin(), files.size(), rewrite_, this, control.to_c(), nullptr, nullptr, 0)); } void Rewriter::rewrite(Clingo::Control &control, char const *str) { Clingo::Detail::handle_error(clingo_ast_parse_string(str, rewrite_, this, control.to_c(), nullptr, nullptr, 0)); } -bool Rewriter::add_(clingo_ast_t *stm, void *data) { - auto *self = static_cast(data); +auto Rewriter::add_(clingo_ast_t *stm, void *data) -> bool { + auto *self = static_cast(data); return clingo_program_builder_add(self->builder_, stm); } -bool Rewriter::rewrite_(clingo_ast_t *stm, void *data) { - auto *self = static_cast(data); +auto Rewriter::rewrite_(clingo_ast_t *stm, void *data) -> bool { + auto *self = static_cast(data); return clingolpx_rewrite_ast(self->theory_, stm, add_, self); } diff --git a/app/src/main.cc b/app/src/main.cc index 918e442..04a1cb1 100644 --- a/app/src/main.cc +++ b/app/src/main.cc @@ -22,13 +22,13 @@ // }}} -#include -#include #include -#include -#include +#include +#include #include #include +#include +#include #ifdef CLINGOLPX_PROFILE #include #endif @@ -40,13 +40,9 @@ namespace ClingoLPX { namespace { class Profiler { -public: - Profiler(char const *path) { - ProfilerStart(path); - } - ~Profiler() { - ProfilerStop(); - } + public: + Profiler(char const *path) { ProfilerStart(path); } + ~Profiler() { ProfilerStop(); } }; } // namespace @@ -57,25 +53,17 @@ using Clingo::Detail::handle_error; //! Application class to run clingo-lpx. class App : public Clingo::Application, private Clingo::SolveEventHandler { -public: - App() { - handle_error(clingolpx_create(&theory_)); - } + public: + App() { handle_error(clingolpx_create(&theory_)); } App(App const &) = default; App(App &&) = default; - App &operator=(App const &) = default; - App &operator=(App &&) = default; - ~App() override { - clingolpx_destroy(theory_); - } + auto operator=(App const &) -> App & = default; + auto operator=(App &&) -> App & = default; + ~App() override { clingolpx_destroy(theory_); } //! Set program name to clingo-lpx. - [[nodiscard]] char const *program_name() const noexcept override { - return "clingo-lpx"; - } + [[nodiscard]] auto program_name() const noexcept -> char const * override { return "clingo-lpx"; } //! Set the version. - [[nodiscard]] char const *version() const noexcept override { - return CLINGOLPX_VERSION; - } + [[nodiscard]] auto version() const noexcept -> char const * override { return CLINGOLPX_VERSION; } void print_model(Clingo::Model const &model, std::function default_printer) noexcept override { static_cast(default_printer); try { @@ -102,23 +90,23 @@ class App : public Clingo::Application, private Clingo::SolveEventHandler { auto args = sym.arguments(); std::cout << args.front() << "=" << args.back().string(); comma = true; - } - else if (sym.match("__lpx_objective", 2) && sym.arguments().front().type() == Clingo::SymbolType::String && sym.arguments().back().type() == Clingo::SymbolType::Number) { + } else if (sym.match("__lpx_objective", 2) && + sym.arguments().front().type() == Clingo::SymbolType::String && + sym.arguments().back().type() == Clingo::SymbolType::Number) { auto args = sym.arguments(); objective = std::make_pair(args.front(), args.back() == Clingo::Number(1)); - } } if (objective.has_value()) { - std::cout << "\nOptimization: " << objective->first.string() << " [" << (objective->second ? "bounded" : "unbounded") << "]"; + std::cout << "\nOptimization: " << objective->first.string() << " [" + << (objective->second ? "bounded" : "unbounded") << "]"; } std::cout << std::endl; - } - catch(...) { + } catch (...) { } } //! Pass models to the theory. - bool on_model(Clingo::Model &model) override { + auto on_model(Clingo::Model &model) -> bool override { handle_error(clingolpx_on_model(theory_, model.to_c())); return true; } @@ -146,18 +134,16 @@ class App : public Clingo::Application, private Clingo::SolveEventHandler { handle_error(clingolpx_register_options(theory_, options.to_c())); } //! Validate options of the theory. - void validate_options() override { - handle_error(clingolpx_validate_options(theory_)); - } + void validate_options() override { handle_error(clingolpx_validate_options(theory_)); } -private: + private: clingolpx_theory_t *theory_{nullptr}; //!< The underlying DL theory. }; } // namespace ClingoLPX //! Run the clingo-lpx application. -int main(int argc, char *argv[]) { // NOLINT(bugprone-exception-escape) +auto main(int argc, char *argv[]) -> int { // NOLINT(bugprone-exception-escape) ClingoLPX::App app; return Clingo::clingo_main(app, {argv + 1, static_cast(argc - 1)}); } diff --git a/cmake/shared_mutex.cc b/cmake/shared_mutex.cc index 1d18294..5f34406 100644 --- a/cmake/shared_mutex.cc +++ b/cmake/shared_mutex.cc @@ -1,6 +1,6 @@ #include -int main() { +auto main() -> int { std::shared_mutex mut; std::shared_lock lock{mut}; } diff --git a/libclingo-lpx/clingo-lpx.h b/libclingo-lpx/clingo-lpx.h index 5c8c42a..095948a 100644 --- a/libclingo-lpx/clingo-lpx.h +++ b/libclingo-lpx/clingo-lpx.h @@ -25,6 +25,8 @@ #ifndef CLINGOLPX_H #define CLINGOLPX_H +#include + //! Major version number. #define CLINGOLPX_VERSION_MAJOR 1 //! Minor version number. @@ -39,31 +41,31 @@ extern "C" { #endif #if defined _WIN32 || defined __CYGWIN__ -# define CLINGOLPX_WIN +#define CLINGOLPX_WIN #endif #ifdef CLINGOLPX_NO_VISIBILITY -# define CLINGOLPX_VISIBILITY_DEFAULT -# define CLINGOLPX_VISIBILITY_PRIVATE +#define CLINGOLPX_VISIBILITY_DEFAULT +#define CLINGOLPX_VISIBILITY_PRIVATE +#else +#ifdef CLINGOLPX_WIN +#ifdef CLINGOLPX_BUILD_LIBRARY +#define CLINGOLPX_VISIBILITY_DEFAULT __declspec(dllexport) +#else +#define CLINGOLPX_VISIBILITY_DEFAULT __declspec(dllimport) +#endif +#define CLINGOLPX_VISIBILITY_PRIVATE #else -# ifdef CLINGOLPX_WIN -# ifdef CLINGOLPX_BUILD_LIBRARY -# define CLINGOLPX_VISIBILITY_DEFAULT __declspec (dllexport) -# else -# define CLINGOLPX_VISIBILITY_DEFAULT __declspec (dllimport) -# endif -# define CLINGOLPX_VISIBILITY_PRIVATE -# else -# if __GNUC__ >= 4 -# define CLINGOLPX_VISIBILITY_DEFAULT __attribute__ ((visibility ("default"))) -# define CLINGOLPX_VISIBILITY_PRIVATE __attribute__ ((visibility ("hidden"))) -# else -# define CLINGOLPX_VISIBILITY_DEFAULT -# define CLINGOLPX_VISIBILITY_PRIVATE -# endif -# endif +#if __GNUC__ >= 4 +#define CLINGOLPX_VISIBILITY_DEFAULT __attribute__((visibility("default"))) +#define CLINGOLPX_VISIBILITY_PRIVATE __attribute__((visibility("hidden"))) +#else +#define CLINGOLPX_VISIBILITY_DEFAULT +#define CLINGOLPX_VISIBILITY_PRIVATE +#endif +#endif #endif -#include +// NOLINTBEGIN(modernize-use-using,modernize-use-trailing-return-type) enum clingolpx_value_type { clingolpx_value_type_int = 0, @@ -93,13 +95,14 @@ CLINGOLPX_VISIBILITY_DEFAULT void clingolpx_version(int *major, int *minor, int CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_create(clingolpx_theory_t **theory); //! registers the theory with the control -CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_register(clingolpx_theory_t *theory, clingo_control_t* control); +CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_register(clingolpx_theory_t *theory, clingo_control_t *control); //! Rewrite asts before adding them via the given callback. -CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_rewrite_ast(clingolpx_theory_t *theory, clingo_ast_t *ast, clingolpx_ast_callback_t add, void *data); +CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_rewrite_ast(clingolpx_theory_t *theory, clingo_ast_t *ast, + clingolpx_ast_callback_t add, void *data); //! prepare the theory between grounding and solving -CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_prepare(clingolpx_theory_t *theory, clingo_control_t* control); +CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_prepare(clingolpx_theory_t *theory, clingo_control_t *control); //! destroys the theory, currently no way to unregister a theory CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_destroy(clingolpx_theory_t *theory); @@ -109,18 +112,19 @@ CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_destroy(clingolpx_theory_t *theory); CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_configure(clingolpx_theory_t *theory, char const *key, char const *value); //! add options for your theory -CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_register_options(clingolpx_theory_t *theory, clingo_options_t* options); +CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_register_options(clingolpx_theory_t *theory, clingo_options_t *options); //! validate options for your theory CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_validate_options(clingolpx_theory_t *theory); //! callback on every model -CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_on_model(clingolpx_theory_t *theory, clingo_model_t* model); +CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_on_model(clingolpx_theory_t *theory, clingo_model_t *model); //! obtain a symbol index which can be used to get the value of a symbol //! returns true if the symbol exists //! does not throw -CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_lookup_symbol(clingolpx_theory_t *theory, clingo_symbol_t symbol, size_t *index); +CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_lookup_symbol(clingolpx_theory_t *theory, clingo_symbol_t symbol, + size_t *index); //! obtain the symbol at the given index //! does not throw @@ -128,24 +132,31 @@ CLINGOLPX_VISIBILITY_DEFAULT clingo_symbol_t clingolpx_get_symbol(clingolpx_theo //! initialize index so that it can be used with clingolpx_assignment_next //! does not throw -CLINGOLPX_VISIBILITY_DEFAULT void clingolpx_assignment_begin(clingolpx_theory_t *theory, uint32_t thread_id, size_t *index); +CLINGOLPX_VISIBILITY_DEFAULT void clingolpx_assignment_begin(clingolpx_theory_t *theory, uint32_t thread_id, + size_t *index); //! move to the next index that has a value //! returns true if the updated index is valid //! does not throw -CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_assignment_next(clingolpx_theory_t *theory, uint32_t thread_id, size_t *index); +CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_assignment_next(clingolpx_theory_t *theory, uint32_t thread_id, + size_t *index); //! check if the symbol at the given index has a value //! does not throw -CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_assignment_has_value(clingolpx_theory_t *theory, uint32_t thread_id, size_t index); +CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_assignment_has_value(clingolpx_theory_t *theory, uint32_t thread_id, + size_t index); //! get the symbol and it's value at the given index //! does not throw -CLINGOLPX_VISIBILITY_DEFAULT void clingolpx_assignment_get_value(clingolpx_theory_t *theory, uint32_t thread_id, size_t index, clingolpx_value_t *value); +CLINGOLPX_VISIBILITY_DEFAULT void clingolpx_assignment_get_value(clingolpx_theory_t *theory, uint32_t thread_id, + size_t index, clingolpx_value_t *value); //! callback on statistic updates /// please add a subkey with the name of your theory -CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_on_statistics(clingolpx_theory_t *theory, clingo_statistics_t* step, clingo_statistics_t* accu); +CLINGOLPX_VISIBILITY_DEFAULT bool clingolpx_on_statistics(clingolpx_theory_t *theory, clingo_statistics_t *step, + clingo_statistics_t *accu); + +// NOLINTEND(modernize-use-using,modernize-use-trailing-return-type) #ifdef __cplusplus } diff --git a/libclingo-lpx/src/clingo-lpx.cc b/libclingo-lpx/src/clingo-lpx.cc index b27417a..1393831 100644 --- a/libclingo-lpx/src/clingo-lpx.cc +++ b/libclingo-lpx/src/clingo-lpx.cc @@ -34,115 +34,110 @@ #include #define CLINGOLPX_TRY try // NOLINT -#define CLINGOLPX_CATCH catch (...){ Clingo::Detail::handle_cxx_error(); return false; } return true // NOLINT +#define CLINGOLPX_CATCH \ + catch (...) { \ + Clingo::Detail::handle_cxx_error(); \ + return false; \ + } \ + return true // NOLINT namespace { using Clingo::Detail::handle_error; //! C initialization callback for the LPX propagator. -template -bool init(clingo_propagate_init_t* i, void* data) { +template auto init(clingo_propagate_init_t *i, void *data) -> bool { CLINGOLPX_TRY { Clingo::PropagateInit in(i); - static_cast*>(data)->init(in); + static_cast *>(data)->init(in); } CLINGOLPX_CATCH; } //! C propagation callback for the LPX propagator. template -bool propagate(clingo_propagate_control_t* i, const clingo_literal_t *changes, size_t size, void* data) { +auto propagate(clingo_propagate_control_t *i, const clingo_literal_t *changes, size_t size, void *data) -> bool { CLINGOLPX_TRY { Clingo::PropagateControl in(i); - static_cast*>(data)->propagate(in, {changes, size}); + static_cast *>(data)->propagate(in, {changes, size}); } CLINGOLPX_CATCH; } //! C undo callback for the LPX propagator. template -void undo(clingo_propagate_control_t const* i, const clingo_literal_t *changes, size_t size, void* data) { +void undo(clingo_propagate_control_t const *i, const clingo_literal_t *changes, size_t size, void *data) { Clingo::PropagateControl in(const_cast(i)); // NOLINT - static_cast*>(data)->undo(in, {changes, size}); + static_cast *>(data)->undo(in, {changes, size}); } //! C check callback for the LPX propagator. -template -bool check(clingo_propagate_control_t* i, void* data) { +template auto check(clingo_propagate_control_t *i, void *data) -> bool { CLINGOLPX_TRY { Clingo::PropagateControl in(i); - static_cast*>(data)->check(in); + static_cast *>(data)->check(in); } CLINGOLPX_CATCH; } //! C decide callback for the LPX propagator. template -bool decide(clingo_id_t thread_id, clingo_assignment_t const *assignment, clingo_literal_t fallback, void *data, clingo_literal_t *decision) { +auto decide(clingo_id_t thread_id, clingo_assignment_t const *assignment, clingo_literal_t fallback, void *data, + clingo_literal_t *decision) -> bool { CLINGOLPX_TRY { Clingo::Assignment assign(const_cast(assignment)); // NOLINT - *decision = static_cast*>(data)->decide(thread_id, assign, fallback); + *decision = static_cast *>(data)->decide(thread_id, assign, fallback); } CLINGOLPX_CATCH; } //! High level interface to use the LPX propagator hiding the value type. class PropagatorFacade { -public: + public: PropagatorFacade() = default; PropagatorFacade(PropagatorFacade const &other) = default; PropagatorFacade(PropagatorFacade &&other) = default; - PropagatorFacade &operator=(PropagatorFacade const &other) = default; - PropagatorFacade &operator=(PropagatorFacade &&other) noexcept = default; + auto operator=(PropagatorFacade const &other) -> PropagatorFacade & = default; + auto operator=(PropagatorFacade &&other) noexcept -> PropagatorFacade & = default; virtual ~PropagatorFacade() = default; //! Look up the index of a symbol. //! //! The function returns false if the symbol could not be found. - virtual bool lookup_symbol(clingo_symbol_t name, size_t *index) = 0; + virtual auto lookup_symbol(clingo_symbol_t name, size_t *index) -> bool = 0; //! Get the symbol associated with an index. - virtual clingo_symbol_t get_symbol(size_t index) = 0; + virtual auto get_symbol(size_t index) -> clingo_symbol_t = 0; //! Check if a symbol has a value in a thread. - virtual bool has_value(uint32_t thread_id, size_t index) = 0; + virtual auto has_value(uint32_t thread_id, size_t index) -> bool = 0; //! Get the value of a symbol in a thread. virtual void get_value(uint32_t thread_id, size_t index, clingolpx_value_t *value) = 0; //! Function to iterate over the thread specific assignment of symbols and values. //! //! Argument current should initially be set to 0. The function returns //! false if no more values are available. - virtual bool next(uint32_t thread_id, size_t *current) = 0; + virtual auto next(uint32_t thread_id, size_t *current) -> bool = 0; //! Extend the given model with the assignment stored in the propagator. virtual void extend_model(Clingo::Model &m) = 0; //! Add the propagator statistics to clingo's statistics. - virtual void on_statistics(Clingo::UserStatistics& step, Clingo::UserStatistics &accu) = 0; + virtual void on_statistics(Clingo::UserStatistics &step, Clingo::UserStatistics &accu) = 0; }; //! High level interface to use the LPX propagator. -template -class LPXPropagatorFacade : public PropagatorFacade { -public: - LPXPropagatorFacade(clingo_control_t *control, char const *theory, Options const &options) - : prop_{options} { +template class LPXPropagatorFacade : public PropagatorFacade { + public: + LPXPropagatorFacade(clingo_control_t *control, char const *theory, Options const &options) : prop_{options} { handle_error(clingo_control_add(control, "base", nullptr, 0, theory)); static clingo_propagator_t prp = { - init, - propagate, - undo, - check, - decide, + init, propagate, undo, check, decide, }; static clingo_propagator_t heu = { - init, - propagate, - undo, - check, - nullptr, + init, propagate, undo, check, nullptr, }; - handle_error(clingo_control_register_propagator(control, options.select != SelectionHeuristic::None ? &prp : &heu, &prop_, false)); + handle_error(clingo_control_register_propagator( + control, options.select != SelectionHeuristic::None ? &prp : &heu, &prop_, false)); } - bool lookup_symbol(clingo_symbol_t name, size_t *index) override { + auto lookup_symbol(clingo_symbol_t name, size_t *index) -> bool override { if (auto ret = prop_.lookup_symbol(Clingo::Symbol{name}); ret) { *index = *ret + 1; return true; @@ -150,11 +145,9 @@ class LPXPropagatorFacade : public PropagatorFacade { return false; } - clingo_symbol_t get_symbol(size_t index) override { - return prop_.get_symbol(index - 1).to_c(); - } + auto get_symbol(size_t index) -> clingo_symbol_t override { return prop_.get_symbol(index - 1).to_c(); } - bool has_value(uint32_t thread_id, size_t index) override { + auto has_value(uint32_t thread_id, size_t index) -> bool override { return index > 0 && prop_.has_value(thread_id, index - 1); } @@ -165,7 +158,7 @@ class LPXPropagatorFacade : public PropagatorFacade { value->symbol = Clingo::String(ss_.str().c_str()).to_c(); // NOLINT } - bool next(uint32_t thread_id, size_t *current) override { + auto next(uint32_t thread_id, size_t *current) -> bool override { while (*current < prop_.n_values(thread_id)) { ++*current; if (prop_.get_symbol(*current - 1).type() != Clingo::SymbolType::Number) { @@ -182,37 +175,41 @@ class LPXPropagatorFacade : public PropagatorFacade { for (size_t i = 0; next(thread_id, &i);) { ss_.str(""); ss_ << prop_.get_value(thread_id, i - 1); - symbols.emplace_back(Clingo::Function("__lpx", {prop_.get_symbol(i - 1), Clingo::String(ss_.str().c_str())})); + symbols.emplace_back( + Clingo::Function("__lpx", {prop_.get_symbol(i - 1), Clingo::String(ss_.str().c_str())})); } auto objective = prop_.get_objective(thread_id); if (objective.has_value()) { ss_.str(""); ss_ << objective->first; - symbols.emplace_back(Clingo::Function("__lpx_objective", {Clingo::String(ss_.str().c_str()), Clingo::Number(objective->second ? 1 : 0)})); + symbols.emplace_back(Clingo::Function( + "__lpx_objective", {Clingo::String(ss_.str().c_str()), Clingo::Number(objective->second ? 1 : 0)})); } model.extend(symbols); prop_.on_model(model); } - void on_statistics(Clingo::UserStatistics& step, Clingo::UserStatistics &accu) override { + void on_statistics(Clingo::UserStatistics &step, Clingo::UserStatistics &accu) override { prop_.on_statistics(step, accu); } -private: + private: Propagator prop_; //!< The underlying LPX propagator. std::ostringstream ss_; }; //! Check if b is a lower case prefix of a returning a pointer to the remainder of a. -char const *iequals_pre(char const *a, char const *b) { +auto iequals_pre(char const *a, char const *b) -> char const * { for (; *a && *b; ++a, ++b) { // NOLINT - if (tolower(*a) != tolower(*b)) { return nullptr; } + if (tolower(*a) != tolower(*b)) { + return nullptr; + } } return *b != '\0' ? nullptr : a; } //! Check if two strings are lower case equal. -bool iequals(char const *a, char const *b) { +auto iequals(char const *a, char const *b) -> bool { a = iequals_pre(a, b); return a != nullptr && *a == '\0'; } @@ -220,8 +217,8 @@ bool iequals(char const *a, char const *b) { //! Parse a Boolean and store it in data. //! //! Return false if there is a parse error. -bool parse_bool(const char *value, void *data) { - auto &result = *static_cast(data); +auto parse_bool(const char *value, void *data) -> bool { + auto &result = *static_cast(data); if (iequals(value, "no") || iequals(value, "off") || iequals(value, "0")) { result = false; return true; @@ -234,8 +231,8 @@ bool parse_bool(const char *value, void *data) { } //! Parse value for phase selection heuristic. -bool parse_select(const char *value, void *data) { - auto &options = *static_cast(data); +auto parse_select(const char *value, void *data) -> bool { + auto &options = *static_cast(data); if (iequals(value, "none")) { options.select = SelectionHeuristic::None; return true; @@ -252,8 +249,8 @@ bool parse_select(const char *value, void *data) { } //! Parse value for propagate mode. -bool parse_propagate(const char *value, void *data) { - auto &options = *static_cast(data); +auto parse_propagate(const char *value, void *data) -> bool { + auto &options = *static_cast(data); if (iequals(value, "none")) { options.propagate_mode = PropagateMode::None; return true; @@ -270,8 +267,8 @@ bool parse_propagate(const char *value, void *data) { } //! Parse value for store SAT assignment configuration. -bool parse_store(const char *value, void *data) { - auto &options = *static_cast(data); +auto parse_store(const char *value, void *data) -> bool { + auto &options = *static_cast(data); if (iequals(value, "no")) { options.store_sat_assignment = StoreSATAssignments::No; return true; @@ -288,8 +285,8 @@ bool parse_store(const char *value, void *data) { } //! Parse how objective function is treated. -bool parse_objective(const char *value, void *data) { - auto &options = *static_cast(data); +auto parse_objective(const char *value, void *data) -> bool { + auto &options = *static_cast(data); if (iequals(value, "local")) { options.global_objective = std::nullopt; return true; @@ -318,7 +315,7 @@ bool parse_objective(const char *value, void *data) { //! Set the given error message if the Boolean is false. //! //! Return false if there is a parse error. -bool check_parse(char const *key, bool ret) { +auto check_parse(char const *key, bool ret) -> bool { if (!ret) { std::ostringstream msg; msg << "invalid value for '" << key << "'"; @@ -347,40 +344,40 @@ extern "C" void clingolpx_version(int *major, int *minor, int *patch) { } } -extern "C" bool clingolpx_create(clingolpx_theory_t **theory) { +extern "C" auto clingolpx_create(clingolpx_theory_t **theory) -> bool { CLINGOLPX_TRY { *theory = new clingolpx_theory{}; } // NOLINT CLINGOLPX_CATCH; } -extern "C" bool clingolpx_register(clingolpx_theory_t *theory, clingo_control_t* control) { +extern "C" auto clingolpx_register(clingolpx_theory_t *theory, clingo_control_t *control) -> bool { CLINGOLPX_TRY { if (!theory->strict) { theory->clingolpx = std::make_unique>(control, THEORY, theory->options); - } - else { + } else { theory->clingolpx = std::make_unique>(control, THEORY_Q, theory->options); } } CLINGOLPX_CATCH; } -extern "C" bool clingolpx_rewrite_ast(clingolpx_theory_t *theory, clingo_ast_t *ast, clingolpx_ast_callback_t add, void *data) { +extern "C" auto clingolpx_rewrite_ast(clingolpx_theory_t *theory, clingo_ast_t *ast, clingolpx_ast_callback_t add, + void *data) -> bool { static_cast(theory); return add(ast, data); } -extern "C" bool clingolpx_prepare(clingolpx_theory_t *theory, clingo_control_t *control) { +extern "C" auto clingolpx_prepare(clingolpx_theory_t *theory, clingo_control_t *control) -> bool { static_cast(theory); static_cast(control); return true; } -extern "C" bool clingolpx_destroy(clingolpx_theory_t *theory) { +extern "C" auto clingolpx_destroy(clingolpx_theory_t *theory) -> bool { CLINGOLPX_TRY { delete theory; } // NOLINT CLINGOLPX_CATCH; } -extern "C" bool clingolpx_configure(clingolpx_theory_t *theory, char const *key, char const *value) { +extern "C" auto clingolpx_configure(clingolpx_theory_t *theory, char const *key, char const *value) -> bool { CLINGOLPX_TRY { if (strcmp(key, "strict") == 0) { return check_parse("strict", parse_bool(value, &theory->strict)); @@ -408,29 +405,36 @@ extern "C" bool clingolpx_configure(clingolpx_theory_t *theory, char const *key, CLINGOLPX_CATCH; } -extern "C" bool clingolpx_register_options(clingolpx_theory_t *theory, clingo_options_t* options) { +extern "C" auto clingolpx_register_options(clingolpx_theory_t *theory, clingo_options_t *options) -> bool { CLINGOLPX_TRY { - char const * group = "Clingo.LPX Options"; - handle_error(clingo_options_add_flag(options, group, "strict", "Enable support for strict constraints", &theory->strict)); - handle_error(clingo_options_add_flag(options, group, "propagate-conflicts", "Propagate conflicting bounds", &theory->options.propagate_conflicts)); - handle_error(clingo_options_add(options, group, "propagate-bounds", "Propagate bounds", parse_propagate, &theory->options, false, "{none,changed,full}")); - handle_error(clingo_options_add(options, group, "objective", "Choose how to treat objective function", parse_objective, &theory->options, false, "{local,global[,step]}")); - handle_error(clingo_options_add(options, group, "select", "Choose phase selection heuristic", parse_select, &theory->options, false, "{none,match,conflict}")); - handle_error(clingo_options_add(options, group, "store", "Whether to store SAT assignments", parse_store, &theory->options, false, "{no,partial,total}")); + char const *group = "Clingo.LPX Options"; + handle_error(clingo_options_add_flag(options, group, "strict", "Enable support for strict constraints", + &theory->strict)); + handle_error(clingo_options_add_flag(options, group, "propagate-conflicts", "Propagate conflicting bounds", + &theory->options.propagate_conflicts)); + handle_error(clingo_options_add(options, group, "propagate-bounds", "Propagate bounds", parse_propagate, + &theory->options, false, "{none,changed,full}")); + handle_error(clingo_options_add(options, group, "objective", "Choose how to treat objective function", + parse_objective, &theory->options, false, "{local,global[,step]}")); + handle_error(clingo_options_add(options, group, "select", "Choose phase selection heuristic", parse_select, + &theory->options, false, "{none,match,conflict}")); + handle_error(clingo_options_add(options, group, "store", "Whether to store SAT assignments", parse_store, + &theory->options, false, "{no,partial,total}")); } CLINGOLPX_CATCH; } -extern "C" bool clingolpx_validate_options(clingolpx_theory_t *theory) { +extern "C" auto clingolpx_validate_options(clingolpx_theory_t *theory) -> bool { CLINGOLPX_TRY { - if (!theory->strict && theory->options.global_objective.has_value() && !theory->options.global_objective->is_rational()) { + if (!theory->strict && theory->options.global_objective.has_value() && + !theory->options.global_objective->is_rational()) { throw std::runtime_error("objective step value requires strict mode"); } } CLINGOLPX_CATCH; } -extern "C" bool clingolpx_on_model(clingolpx_theory_t *theory, clingo_model_t* model) { +extern "C" auto clingolpx_on_model(clingolpx_theory_t *theory, clingo_model_t *model) -> bool { CLINGOLPX_TRY { Clingo::Model m(model); theory->clingolpx->extend_model(m); @@ -438,11 +442,11 @@ extern "C" bool clingolpx_on_model(clingolpx_theory_t *theory, clingo_model_t* m CLINGOLPX_CATCH; } -extern "C" bool clingolpx_lookup_symbol(clingolpx_theory_t *theory, clingo_symbol_t symbol, size_t *index) { +extern "C" auto clingolpx_lookup_symbol(clingolpx_theory_t *theory, clingo_symbol_t symbol, size_t *index) -> bool { return theory->clingolpx->lookup_symbol(symbol, index); } -extern "C" clingo_symbol_t clingolpx_get_symbol(clingolpx_theory_t *theory, size_t index) { +extern "C" auto clingolpx_get_symbol(clingolpx_theory_t *theory, size_t index) -> clingo_symbol_t { return theory->clingolpx->get_symbol(index); } @@ -452,19 +456,21 @@ extern "C" void clingolpx_assignment_begin(clingolpx_theory_t *theory, uint32_t *index = 0; } -extern "C" bool clingolpx_assignment_next(clingolpx_theory_t *theory, uint32_t thread_id, size_t *index) { +extern "C" auto clingolpx_assignment_next(clingolpx_theory_t *theory, uint32_t thread_id, size_t *index) -> bool { return theory->clingolpx->next(thread_id, index); } -extern "C" bool clingolpx_assignment_has_value(clingolpx_theory_t *theory, uint32_t thread_id, size_t index) { +extern "C" auto clingolpx_assignment_has_value(clingolpx_theory_t *theory, uint32_t thread_id, size_t index) -> bool { return theory->clingolpx->has_value(thread_id, index); } -extern "C" void clingolpx_assignment_get_value(clingolpx_theory_t *theory, uint32_t thread_id, size_t index, clingolpx_value_t *value) { +extern "C" void clingolpx_assignment_get_value(clingolpx_theory_t *theory, uint32_t thread_id, size_t index, + clingolpx_value_t *value) { theory->clingolpx->get_value(thread_id, index, value); } -extern "C" bool clingolpx_on_statistics(clingolpx_theory_t *theory, clingo_statistics_t* step, clingo_statistics_t* accu) { +extern "C" auto clingolpx_on_statistics(clingolpx_theory_t *theory, clingo_statistics_t *step, + clingo_statistics_t *accu) -> bool { CLINGOLPX_TRY { uint64_t root_s{0}; uint64_t root_a{0}; diff --git a/libclingo-lpx/src/number.hh b/libclingo-lpx/src/number.hh index 4a78b44..eabff1d 100644 --- a/libclingo-lpx/src/number.hh +++ b/libclingo-lpx/src/number.hh @@ -1,116 +1,113 @@ #pragma once #include +#include #include #include -#include #include "number_flint.hh" #include "number_imath.hh" - class RationalQ { -private: - friend RationalQ operator+(RationalQ const &a, fixed_int b); - friend RationalQ operator+(RationalQ const &a, Integer const &b); - friend RationalQ operator+(RationalQ const &a, Rational const &b); - friend RationalQ operator+(RationalQ const &a, RationalQ const &b); - friend RationalQ operator+(RationalQ &&a, fixed_int b); - friend RationalQ operator+(RationalQ &&a, Integer const &b); - friend RationalQ operator+(RationalQ &&a, Rational const &b); - friend RationalQ operator+(RationalQ &&a, RationalQ const &b); - friend RationalQ &operator+=(RationalQ &a, fixed_int b); - friend RationalQ &operator+=(RationalQ &a, Integer const &b); - friend RationalQ &operator+=(RationalQ &a, Rational const &b); - friend RationalQ &operator+=(RationalQ &a, RationalQ const &b); - - friend RationalQ operator-(RationalQ a); - - friend RationalQ operator-(RationalQ const &a, fixed_int b); - friend RationalQ operator-(RationalQ const &a, Integer const &b); - friend RationalQ operator-(RationalQ const &a, Rational const &b); - friend RationalQ operator-(RationalQ const &a, RationalQ const &b); - friend RationalQ operator-(RationalQ &&a, fixed_int b); - friend RationalQ operator-(RationalQ &&a, Integer const &b); - friend RationalQ operator-(RationalQ &&a, Rational const &b); - friend RationalQ operator-(RationalQ &&a, RationalQ const &b); - friend RationalQ &operator-=(RationalQ &a, fixed_int b); - friend RationalQ &operator-=(RationalQ &a, Integer const &b); - friend RationalQ &operator-=(RationalQ &a, Rational const &b); - friend RationalQ &operator-=(RationalQ &a, RationalQ const &b); - - friend RationalQ operator*(RationalQ const &a, fixed_int b); - friend RationalQ operator*(RationalQ const &a, Integer const &b); - friend RationalQ operator*(RationalQ const &a, Rational const &b); - friend RationalQ operator*(RationalQ &&a, fixed_int b); - friend RationalQ operator*(RationalQ &&a, Integer const &b); - friend RationalQ operator*(RationalQ &&a, Rational const &b); - friend RationalQ &operator*=(RationalQ &a, fixed_int b); - friend RationalQ &operator*=(RationalQ &a, Integer const &b); - friend RationalQ &operator*=(RationalQ &a, Rational const &b); - - friend RationalQ operator/(RationalQ const &a, fixed_int b); - friend RationalQ operator/(RationalQ const &a, Integer const &b); - friend RationalQ operator/(RationalQ const &a, Rational const &b); - friend RationalQ operator/(RationalQ &&a, fixed_int b); - friend RationalQ operator/(RationalQ &&a, Integer const &b); - friend RationalQ operator/(RationalQ &&a, Rational const &b); - friend RationalQ &operator/=(RationalQ &a, fixed_int b); - friend RationalQ &operator/=(RationalQ &a, Integer const &b); - friend RationalQ &operator/=(RationalQ &a, Rational const &b); - - friend bool operator<(RationalQ const &a, fixed_int b); - friend bool operator<(RationalQ const &a, Integer const &b); - friend bool operator<(RationalQ const &a, Rational const &b); - friend bool operator<(RationalQ const &a, RationalQ const &b); - - friend bool operator<=(RationalQ const &a, fixed_int b); - friend bool operator<=(RationalQ const &a, Integer const &b); - friend bool operator<=(RationalQ const &a, Rational const &b); - friend bool operator<=(RationalQ const &a, RationalQ const &b); - - friend bool operator>(RationalQ const &a, fixed_int b); - friend bool operator>(RationalQ const &a, Integer const &b); - friend bool operator>(RationalQ const &a, Rational const &b); - friend bool operator>(RationalQ const &a, RationalQ const &b); - - friend bool operator>=(RationalQ const &a, fixed_int b); - friend bool operator>=(RationalQ const &a, Integer const &b); - friend bool operator>=(RationalQ const &a, Rational const &b); - friend bool operator>=(RationalQ const &a, RationalQ const &b); - - friend bool operator==(RationalQ const &a, fixed_int b); - friend bool operator==(RationalQ const &a, Integer const &b); - friend bool operator==(RationalQ const &a, Rational const &b); - friend bool operator==(RationalQ const &a, RationalQ const &b); - - friend bool operator!=(RationalQ const &a, fixed_int b); - friend bool operator!=(RationalQ const &a, Integer const &b); - friend bool operator!=(RationalQ const &a, RationalQ const &b); - friend bool operator!=(RationalQ const &a, Rational const &b); - - friend std::ostream &operator<<(std::ostream &out, RationalQ const &q); - - friend int compare(RationalQ const &a, fixed_int b); - friend int compare(RationalQ const &a, Integer const &b); - friend int compare(RationalQ const &a, Rational const &b); - friend int compare(RationalQ const &a, RationalQ const &b); - -public: - explicit RationalQ(Rational c = Rational{}, Rational k = Rational{}) - : c_{std::move(c)} - , k_{std::move(k)} { } + private: + friend auto operator+(RationalQ const &a, fixed_int b) -> RationalQ; + friend auto operator+(RationalQ const &a, Integer const &b) -> RationalQ; + friend auto operator+(RationalQ const &a, Rational const &b) -> RationalQ; + friend auto operator+(RationalQ const &a, RationalQ const &b) -> RationalQ; + friend auto operator+(RationalQ &&a, fixed_int b) -> RationalQ; + friend auto operator+(RationalQ &&a, Integer const &b) -> RationalQ; + friend auto operator+(RationalQ &&a, Rational const &b) -> RationalQ; + friend auto operator+(RationalQ &&a, RationalQ const &b) -> RationalQ; + friend auto operator+=(RationalQ &a, fixed_int b) -> RationalQ &; + friend auto operator+=(RationalQ &a, Integer const &b) -> RationalQ &; + friend auto operator+=(RationalQ &a, Rational const &b) -> RationalQ &; + friend auto operator+=(RationalQ &a, RationalQ const &b) -> RationalQ &; + + friend auto operator-(RationalQ a) -> RationalQ; + + friend auto operator-(RationalQ const &a, fixed_int b) -> RationalQ; + friend auto operator-(RationalQ const &a, Integer const &b) -> RationalQ; + friend auto operator-(RationalQ const &a, Rational const &b) -> RationalQ; + friend auto operator-(RationalQ const &a, RationalQ const &b) -> RationalQ; + friend auto operator-(RationalQ &&a, fixed_int b) -> RationalQ; + friend auto operator-(RationalQ &&a, Integer const &b) -> RationalQ; + friend auto operator-(RationalQ &&a, Rational const &b) -> RationalQ; + friend auto operator-(RationalQ &&a, RationalQ const &b) -> RationalQ; + friend auto operator-=(RationalQ &a, fixed_int b) -> RationalQ &; + friend auto operator-=(RationalQ &a, Integer const &b) -> RationalQ &; + friend auto operator-=(RationalQ &a, Rational const &b) -> RationalQ &; + friend auto operator-=(RationalQ &a, RationalQ const &b) -> RationalQ &; + + friend auto operator*(RationalQ const &a, fixed_int b) -> RationalQ; + friend auto operator*(RationalQ const &a, Integer const &b) -> RationalQ; + friend auto operator*(RationalQ const &a, Rational const &b) -> RationalQ; + friend auto operator*(RationalQ &&a, fixed_int b) -> RationalQ; + friend auto operator*(RationalQ &&a, Integer const &b) -> RationalQ; + friend auto operator*(RationalQ &&a, Rational const &b) -> RationalQ; + friend auto operator*=(RationalQ &a, fixed_int b) -> RationalQ &; + friend auto operator*=(RationalQ &a, Integer const &b) -> RationalQ &; + friend auto operator*=(RationalQ &a, Rational const &b) -> RationalQ &; + + friend auto operator/(RationalQ const &a, fixed_int b) -> RationalQ; + friend auto operator/(RationalQ const &a, Integer const &b) -> RationalQ; + friend auto operator/(RationalQ const &a, Rational const &b) -> RationalQ; + friend auto operator/(RationalQ &&a, fixed_int b) -> RationalQ; + friend auto operator/(RationalQ &&a, Integer const &b) -> RationalQ; + friend auto operator/(RationalQ &&a, Rational const &b) -> RationalQ; + friend auto operator/=(RationalQ &a, fixed_int b) -> RationalQ &; + friend auto operator/=(RationalQ &a, Integer const &b) -> RationalQ &; + friend auto operator/=(RationalQ &a, Rational const &b) -> RationalQ &; + + friend auto operator<(RationalQ const &a, fixed_int b) -> bool; + friend auto operator<(RationalQ const &a, Integer const &b) -> bool; + friend auto operator<(RationalQ const &a, Rational const &b) -> bool; + friend auto operator<(RationalQ const &a, RationalQ const &b) -> bool; + + friend auto operator<=(RationalQ const &a, fixed_int b) -> bool; + friend auto operator<=(RationalQ const &a, Integer const &b) -> bool; + friend auto operator<=(RationalQ const &a, Rational const &b) -> bool; + friend auto operator<=(RationalQ const &a, RationalQ const &b) -> bool; + + friend auto operator>(RationalQ const &a, fixed_int b) -> bool; + friend auto operator>(RationalQ const &a, Integer const &b) -> bool; + friend auto operator>(RationalQ const &a, Rational const &b) -> bool; + friend auto operator>(RationalQ const &a, RationalQ const &b) -> bool; + + friend auto operator>=(RationalQ const &a, fixed_int b) -> bool; + friend auto operator>=(RationalQ const &a, Integer const &b) -> bool; + friend auto operator>=(RationalQ const &a, Rational const &b) -> bool; + friend auto operator>=(RationalQ const &a, RationalQ const &b) -> bool; + + friend auto operator==(RationalQ const &a, fixed_int b) -> bool; + friend auto operator==(RationalQ const &a, Integer const &b) -> bool; + friend auto operator==(RationalQ const &a, Rational const &b) -> bool; + friend auto operator==(RationalQ const &a, RationalQ const &b) -> bool; + + friend auto operator!=(RationalQ const &a, fixed_int b) -> bool; + friend auto operator!=(RationalQ const &a, Integer const &b) -> bool; + friend auto operator!=(RationalQ const &a, RationalQ const &b) -> bool; + friend auto operator!=(RationalQ const &a, Rational const &b) -> bool; + + friend auto operator<<(std::ostream &out, RationalQ const &q) -> std::ostream &; + + friend auto compare(RationalQ const &a, fixed_int b) -> int; + friend auto compare(RationalQ const &a, Integer const &b) -> int; + friend auto compare(RationalQ const &a, Rational const &b) -> int; + friend auto compare(RationalQ const &a, RationalQ const &b) -> int; + + public: + explicit RationalQ(Rational c = Rational{}, Rational k = Rational{}) : c_{std::move(c)}, k_{std::move(k)} {} RationalQ(RationalQ const &) = default; RationalQ(RationalQ &&) = default; - RationalQ &operator=(RationalQ const &) = default; - RationalQ &operator=(RationalQ &&) = default; + auto operator=(RationalQ const &) -> RationalQ & = default; + auto operator=(RationalQ &&) -> RationalQ & = default; ~RationalQ() = default; void swap(RationalQ &q); - [[nodiscard]] bool is_rational() const; - [[nodiscard]] Rational const &as_rational() const; + [[nodiscard]] auto is_rational() const -> bool; + [[nodiscard]] auto as_rational() const -> Rational const &; -private: + private: Rational c_; Rational k_; }; @@ -122,11 +119,9 @@ inline void RationalQ::swap(RationalQ &q) { k_.swap(q.k_); } -inline bool RationalQ::is_rational() const { - return k_ == 0; -} +inline auto RationalQ::is_rational() const -> bool { return k_ == 0; } -inline Rational const &RationalQ::as_rational() const { +inline auto RationalQ::as_rational() const -> Rational const & { if (!is_rational()) { throw std::runtime_error("cannot convert number with epsilon component to rational"); } @@ -135,7 +130,7 @@ inline Rational const &RationalQ::as_rational() const { // comparision -[[nodiscard]] inline int compare(RationalQ const &a, fixed_int b) { +[[nodiscard]] inline auto compare(RationalQ const &a, fixed_int b) -> int { auto ret = compare(a.c_, b); if (ret != 0) { return ret; @@ -149,7 +144,7 @@ inline Rational const &RationalQ::as_rational() const { return 0; } -[[nodiscard]] inline int compare(RationalQ const &a, Integer const &b) { +[[nodiscard]] inline auto compare(RationalQ const &a, Integer const &b) -> int { auto ret = compare(a.c_, b); if (ret != 0) { return ret; @@ -163,7 +158,7 @@ inline Rational const &RationalQ::as_rational() const { return 0; } -[[nodiscard]] inline int compare(RationalQ const &a, Rational const &b) { +[[nodiscard]] inline auto compare(RationalQ const &a, Rational const &b) -> int { auto ret = compare(a.c_, b); if (ret != 0) { return ret; @@ -177,7 +172,7 @@ inline Rational const &RationalQ::as_rational() const { return 0; } -[[nodiscard]] inline int compare(RationalQ const &a, RationalQ const &b) { +[[nodiscard]] inline auto compare(RationalQ const &a, RationalQ const &b) -> int { auto ret = compare(a.c_, b.c_); if (ret != 0) { return ret; @@ -187,54 +182,44 @@ inline Rational const &RationalQ::as_rational() const { // addition -[[nodiscard]] inline RationalQ operator+(RationalQ const &a, fixed_int b) { - return RationalQ{a.c_ + b, a.k_}; -} +[[nodiscard]] inline auto operator+(RationalQ const &a, fixed_int b) -> RationalQ { return RationalQ{a.c_ + b, a.k_}; } -[[nodiscard]] inline RationalQ operator+(RationalQ const &a, Integer const &b) { +[[nodiscard]] inline auto operator+(RationalQ const &a, Integer const &b) -> RationalQ { return RationalQ{a.c_ + b, a.k_}; } -[[nodiscard]] inline RationalQ operator+(RationalQ const &a, Rational const &b) { +[[nodiscard]] inline auto operator+(RationalQ const &a, Rational const &b) -> RationalQ { return RationalQ{a.c_ + b, a.k_}; } -[[nodiscard]] inline RationalQ operator+(RationalQ const &a, RationalQ const &b) { +[[nodiscard]] inline auto operator+(RationalQ const &a, RationalQ const &b) -> RationalQ { return RationalQ{a.c_ + b.c_, a.k_ + b.k_}; } -[[nodiscard]] inline RationalQ operator+(RationalQ &&a, fixed_int b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(RationalQ &&a, fixed_int b) -> RationalQ { return std::move(a += b); } -[[nodiscard]] inline RationalQ operator+(RationalQ &&a, Integer const &b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(RationalQ &&a, Integer const &b) -> RationalQ { return std::move(a += b); } -[[nodiscard]] inline RationalQ operator+(RationalQ &&a, Rational const &b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(RationalQ &&a, Rational const &b) -> RationalQ { return std::move(a += b); } -[[nodiscard]] inline RationalQ operator+(RationalQ &&a, RationalQ const &b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(RationalQ &&a, RationalQ const &b) -> RationalQ { return std::move(a += b); } -inline RationalQ &operator+=(RationalQ &a, fixed_int b) { +inline auto operator+=(RationalQ &a, fixed_int b) -> RationalQ & { a.c_ += b; return a; } -inline RationalQ &operator+=(RationalQ &a, Integer const &b) { +inline auto operator+=(RationalQ &a, Integer const &b) -> RationalQ & { a.c_ += b; return a; } -inline RationalQ &operator+=(RationalQ &a, Rational const &b) { +inline auto operator+=(RationalQ &a, Rational const &b) -> RationalQ & { a.c_ += b; return a; } -inline RationalQ &operator+=(RationalQ &a, RationalQ const &b) { +inline auto operator+=(RationalQ &a, RationalQ const &b) -> RationalQ & { a.c_ += b.c_; a.k_ += b.k_; return a; @@ -242,60 +227,50 @@ inline RationalQ &operator+=(RationalQ &a, RationalQ const &b) { // subtraction -[[nodiscard]] inline RationalQ operator-(RationalQ a) { +[[nodiscard]] inline auto operator-(RationalQ a) -> RationalQ { a.c_.neg(); a.k_.neg(); return a; } -[[nodiscard]] inline RationalQ operator-(RationalQ const &a, fixed_int b) { - return RationalQ{a.c_ - b, a.k_}; -} +[[nodiscard]] inline auto operator-(RationalQ const &a, fixed_int b) -> RationalQ { return RationalQ{a.c_ - b, a.k_}; } -[[nodiscard]] inline RationalQ operator-(RationalQ const &a, Integer const &b) { +[[nodiscard]] inline auto operator-(RationalQ const &a, Integer const &b) -> RationalQ { return RationalQ{a.c_ - b, a.k_}; } -[[nodiscard]] inline RationalQ operator-(RationalQ const &a, Rational const &b) { +[[nodiscard]] inline auto operator-(RationalQ const &a, Rational const &b) -> RationalQ { return RationalQ{a.c_ - b, a.k_}; } -[[nodiscard]] inline RationalQ operator-(RationalQ const &a, RationalQ const &b) { +[[nodiscard]] inline auto operator-(RationalQ const &a, RationalQ const &b) -> RationalQ { return RationalQ{a.c_ - b.c_, a.k_ - b.k_}; } -[[nodiscard]] inline RationalQ operator-(RationalQ &&a, fixed_int b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(RationalQ &&a, fixed_int b) -> RationalQ { return std::move(a -= b); } -[[nodiscard]] inline RationalQ operator-(RationalQ &&a, Integer const &b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(RationalQ &&a, Integer const &b) -> RationalQ { return std::move(a -= b); } -[[nodiscard]] inline RationalQ operator-(RationalQ &&a, Rational const &b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(RationalQ &&a, Rational const &b) -> RationalQ { return std::move(a -= b); } -[[nodiscard]] inline RationalQ operator-(RationalQ &&a, RationalQ const &b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(RationalQ &&a, RationalQ const &b) -> RationalQ { return std::move(a -= b); } -inline RationalQ &operator-=(RationalQ &a, fixed_int b) { +inline auto operator-=(RationalQ &a, fixed_int b) -> RationalQ & { a.c_ -= b; return a; } -inline RationalQ &operator-=(RationalQ &a, Integer const &b) { +inline auto operator-=(RationalQ &a, Integer const &b) -> RationalQ & { a.c_ -= b; return a; } -inline RationalQ &operator-=(RationalQ &a, Rational const &b) { +inline auto operator-=(RationalQ &a, Rational const &b) -> RationalQ & { a.c_ -= b; return a; } -inline RationalQ &operator-=(RationalQ &a, RationalQ const &b) { +inline auto operator-=(RationalQ &a, RationalQ const &b) -> RationalQ & { a.c_ -= b.c_; a.k_ -= b.k_; return a; @@ -303,43 +278,37 @@ inline RationalQ &operator-=(RationalQ &a, RationalQ const &b) { // multiplication -[[nodiscard]] inline RationalQ operator*(RationalQ const &a, fixed_int b) { +[[nodiscard]] inline auto operator*(RationalQ const &a, fixed_int b) -> RationalQ { return RationalQ{a.c_ * b, a.k_ * b}; } -[[nodiscard]] inline RationalQ operator*(RationalQ const &a, Integer const &b) { +[[nodiscard]] inline auto operator*(RationalQ const &a, Integer const &b) -> RationalQ { return RationalQ{a.c_ * b, a.k_ * b}; } -[[nodiscard]] inline RationalQ operator*(RationalQ const &a, Rational const &b) { +[[nodiscard]] inline auto operator*(RationalQ const &a, Rational const &b) -> RationalQ { return RationalQ{a.c_ * b, a.k_ * b}; } -[[nodiscard]] inline RationalQ operator*(RationalQ &&a, fixed_int b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(RationalQ &&a, fixed_int b) -> RationalQ { return std::move(a *= b); } -[[nodiscard]] inline RationalQ operator*(RationalQ &&a, Integer const &b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(RationalQ &&a, Integer const &b) -> RationalQ { return std::move(a *= b); } -[[nodiscard]] inline RationalQ operator*(RationalQ &&a, Rational const &b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(RationalQ &&a, Rational const &b) -> RationalQ { return std::move(a *= b); } -inline RationalQ &operator*=(RationalQ &a, fixed_int b) { +inline auto operator*=(RationalQ &a, fixed_int b) -> RationalQ & { a.c_ *= b; a.k_ *= b; return a; } -inline RationalQ &operator*=(RationalQ &a, Integer const &b) { +inline auto operator*=(RationalQ &a, Integer const &b) -> RationalQ & { a.c_ *= b; a.k_ *= b; return a; } -inline RationalQ &operator*=(RationalQ &a, Rational const &b) { +inline auto operator*=(RationalQ &a, Rational const &b) -> RationalQ & { a.c_ *= b; a.k_ *= b; return a; @@ -347,43 +316,37 @@ inline RationalQ &operator*=(RationalQ &a, Rational const &b) { // division -[[nodiscard]] inline RationalQ operator/(RationalQ const &a, fixed_int b) { +[[nodiscard]] inline auto operator/(RationalQ const &a, fixed_int b) -> RationalQ { return RationalQ{a.c_ / b, a.k_ / b}; } -[[nodiscard]] inline RationalQ operator/(RationalQ const &a, Integer const &b) { +[[nodiscard]] inline auto operator/(RationalQ const &a, Integer const &b) -> RationalQ { return RationalQ{a.c_ / b, a.k_ / b}; } -[[nodiscard]] inline RationalQ operator/(RationalQ const &a, Rational const &b) { +[[nodiscard]] inline auto operator/(RationalQ const &a, Rational const &b) -> RationalQ { return RationalQ{a.c_ / b, a.k_ / b}; } -[[nodiscard]] inline RationalQ operator/(RationalQ &&a, fixed_int b) { - return std::move(a /= b); -} +[[nodiscard]] inline auto operator/(RationalQ &&a, fixed_int b) -> RationalQ { return std::move(a /= b); } -[[nodiscard]] inline RationalQ operator/(RationalQ &&a, Integer const &b) { - return std::move(a /= b); -} +[[nodiscard]] inline auto operator/(RationalQ &&a, Integer const &b) -> RationalQ { return std::move(a /= b); } -[[nodiscard]] inline RationalQ operator/(RationalQ &&a, Rational const &b) { - return std::move(a /= b); -} +[[nodiscard]] inline auto operator/(RationalQ &&a, Rational const &b) -> RationalQ { return std::move(a /= b); } -inline RationalQ &operator/=(RationalQ &a, fixed_int b) { +inline auto operator/=(RationalQ &a, fixed_int b) -> RationalQ & { a.c_ /= b; a.k_ /= b; return a; } -inline RationalQ &operator/=(RationalQ &a, Integer const &b) { +inline auto operator/=(RationalQ &a, Integer const &b) -> RationalQ & { a.c_ /= b; a.k_ /= b; return a; } -inline RationalQ &operator/=(RationalQ &a, Rational const &b) { +inline auto operator/=(RationalQ &a, Rational const &b) -> RationalQ & { a.c_ /= b; a.k_ /= b; return a; @@ -391,85 +354,39 @@ inline RationalQ &operator/=(RationalQ &a, Rational const &b) { // comparison -[[nodiscard]] inline bool operator<(RationalQ const &a, fixed_int b) { - return compare(a, b) < 0; -} -[[nodiscard]] inline bool operator<(RationalQ const &a, Integer const &b) { - return compare(a, b) < 0; -} -[[nodiscard]] inline bool operator<(RationalQ const &a, Rational const &b) { - return compare(a, b) < 0; -} -[[nodiscard]] inline bool operator<(RationalQ const &a, RationalQ const &b) { - return compare(a, b) < 0; -} - -[[nodiscard]] inline bool operator<=(RationalQ const &a, fixed_int b) { - return compare(a, b) <= 0; -} -[[nodiscard]] inline bool operator<=(RationalQ const &a, Integer const &b) { - return compare(a, b) <= 0; -} -[[nodiscard]] inline bool operator<=(RationalQ const &a, Rational const &b) { - return compare(a, b) <= 0; -} -[[nodiscard]] inline bool operator<=(RationalQ const &a, RationalQ const &b) { - return compare(a, b) <= 0; -} - -[[nodiscard]] inline bool operator>(RationalQ const &a, fixed_int b) { - return compare(a, b) > 0; -} -[[nodiscard]] inline bool operator>(RationalQ const &a, Integer const &b) { - return compare(a, b) > 0; -} -[[nodiscard]] inline bool operator>(RationalQ const &a, Rational const &b) { - return compare(a, b) > 0; -} -[[nodiscard]] inline bool operator>(RationalQ const &a, RationalQ const &b) { - return compare(a, b) > 0; -} - -[[nodiscard]] inline bool operator>=(RationalQ const &a, fixed_int b) { - return compare(a, b) >= 0; -} -[[nodiscard]] inline bool operator>=(RationalQ const &a, Integer const &b) { - return compare(a, b) >= 0; -} -[[nodiscard]] inline bool operator>=(RationalQ const &a, Rational const &b) { - return compare(a, b) >= 0; -} -[[nodiscard]] inline bool operator>=(RationalQ const &a, RationalQ const &b) { - return compare(a, b) >= 0; -} - -[[nodiscard]] inline bool operator==(RationalQ const &a, fixed_int b) { - return a.k_ == 0 && a.c_ == b; -} -[[nodiscard]] inline bool operator==(RationalQ const &a, Integer const &b) { - return a.k_ == 0 && a.c_ == b; -} -[[nodiscard]] inline bool operator==(RationalQ const &a, Rational const &b) { - return a.k_ == 0 && a.c_ == b; -} -[[nodiscard]] inline bool operator==(RationalQ const &a, RationalQ const &b) { +[[nodiscard]] inline auto operator<(RationalQ const &a, fixed_int b) -> bool { return compare(a, b) < 0; } +[[nodiscard]] inline auto operator<(RationalQ const &a, Integer const &b) -> bool { return compare(a, b) < 0; } +[[nodiscard]] inline auto operator<(RationalQ const &a, Rational const &b) -> bool { return compare(a, b) < 0; } +[[nodiscard]] inline auto operator<(RationalQ const &a, RationalQ const &b) -> bool { return compare(a, b) < 0; } + +[[nodiscard]] inline auto operator<=(RationalQ const &a, fixed_int b) -> bool { return compare(a, b) <= 0; } +[[nodiscard]] inline auto operator<=(RationalQ const &a, Integer const &b) -> bool { return compare(a, b) <= 0; } +[[nodiscard]] inline auto operator<=(RationalQ const &a, Rational const &b) -> bool { return compare(a, b) <= 0; } +[[nodiscard]] inline auto operator<=(RationalQ const &a, RationalQ const &b) -> bool { return compare(a, b) <= 0; } + +[[nodiscard]] inline auto operator>(RationalQ const &a, fixed_int b) -> bool { return compare(a, b) > 0; } +[[nodiscard]] inline auto operator>(RationalQ const &a, Integer const &b) -> bool { return compare(a, b) > 0; } +[[nodiscard]] inline auto operator>(RationalQ const &a, Rational const &b) -> bool { return compare(a, b) > 0; } +[[nodiscard]] inline auto operator>(RationalQ const &a, RationalQ const &b) -> bool { return compare(a, b) > 0; } + +[[nodiscard]] inline auto operator>=(RationalQ const &a, fixed_int b) -> bool { return compare(a, b) >= 0; } +[[nodiscard]] inline auto operator>=(RationalQ const &a, Integer const &b) -> bool { return compare(a, b) >= 0; } +[[nodiscard]] inline auto operator>=(RationalQ const &a, Rational const &b) -> bool { return compare(a, b) >= 0; } +[[nodiscard]] inline auto operator>=(RationalQ const &a, RationalQ const &b) -> bool { return compare(a, b) >= 0; } + +[[nodiscard]] inline auto operator==(RationalQ const &a, fixed_int b) -> bool { return a.k_ == 0 && a.c_ == b; } +[[nodiscard]] inline auto operator==(RationalQ const &a, Integer const &b) -> bool { return a.k_ == 0 && a.c_ == b; } +[[nodiscard]] inline auto operator==(RationalQ const &a, Rational const &b) -> bool { return a.k_ == 0 && a.c_ == b; } +[[nodiscard]] inline auto operator==(RationalQ const &a, RationalQ const &b) -> bool { return a.c_ == b.c_ && a.k_ == b.k_; } -[[nodiscard]] inline bool operator!=(RationalQ const &a, fixed_int b) { - return !(a == b); -} -[[nodiscard]] inline bool operator!=(RationalQ const &a, Integer const &b) { - return !(a == b); -} -[[nodiscard]] inline bool operator!=(RationalQ const &a, Rational const &b) { - return !(a == b); -} -[[nodiscard]] inline bool operator!=(RationalQ const &a, RationalQ const &b) { - return !(a == b); -} +[[nodiscard]] inline auto operator!=(RationalQ const &a, fixed_int b) -> bool { return !(a == b); } +[[nodiscard]] inline auto operator!=(RationalQ const &a, Integer const &b) -> bool { return !(a == b); } +[[nodiscard]] inline auto operator!=(RationalQ const &a, Rational const &b) -> bool { return !(a == b); } +[[nodiscard]] inline auto operator!=(RationalQ const &a, RationalQ const &b) -> bool { return !(a == b); } -inline std::ostream &operator<<(std::ostream &out, RationalQ const &q) { +inline auto operator<<(std::ostream &out, RationalQ const &q) -> std::ostream & { if (q.c_ != 0 || q.k_ == 0) { out << q.c_; } diff --git a/libclingo-lpx/src/number_flint.hh b/libclingo-lpx/src/number_flint.hh index a31e902..9059c1f 100644 --- a/libclingo-lpx/src/number_flint.hh +++ b/libclingo-lpx/src/number_flint.hh @@ -2,167 +2,167 @@ #ifdef CLINGOLPX_USE_FLINT -#include #include +#include #include +#include +#include #include #include #include -#include -#include constexpr int BASE = 10; using fixed_int = slong; class Integer { - friend Integer operator+(Integer const &a, fixed_int b); - friend Integer operator+(Integer const &a, Integer const &b); - friend Integer operator+(Integer &&a, fixed_int b); - friend Integer operator+(Integer &&a, Integer const &b); - friend Integer &operator+=(Integer &a, fixed_int b); - friend Integer &operator+=(Integer &a, Integer const &b); + friend auto operator+(Integer const &a, fixed_int b) -> Integer; + friend auto operator+(Integer const &a, Integer const &b) -> Integer; + friend auto operator+(Integer &&a, fixed_int b) -> Integer; + friend auto operator+(Integer &&a, Integer const &b) -> Integer; + friend auto operator+=(Integer &a, fixed_int b) -> Integer &; + friend auto operator+=(Integer &a, Integer const &b) -> Integer &; - friend Integer operator-(Integer a); + friend auto operator-(Integer a) -> Integer; - friend Integer operator-(Integer const &a, fixed_int b); - friend Integer operator-(Integer const &a, Integer const &b); - friend Integer operator-(Integer &&a, fixed_int b); - friend Integer operator-(Integer &&a, Integer const &b); - friend Integer &operator-=(Integer &a, fixed_int b); - friend Integer &operator-=(Integer &a, Integer const &b); + friend auto operator-(Integer const &a, fixed_int b) -> Integer; + friend auto operator-(Integer const &a, Integer const &b) -> Integer; + friend auto operator-(Integer &&a, fixed_int b) -> Integer; + friend auto operator-(Integer &&a, Integer const &b) -> Integer; + friend auto operator-=(Integer &a, fixed_int b) -> Integer &; + friend auto operator-=(Integer &a, Integer const &b) -> Integer &; - friend Integer operator*(Integer const &a, fixed_int b); - friend Integer operator*(Integer const &a, Integer const &b); - friend Integer operator*(Integer &&a, fixed_int b); - friend Integer operator*(Integer &&a, Integer const &b); - friend Integer &operator*=(Integer &a, fixed_int b); - friend Integer &operator*=(Integer &a, Integer const &b); + friend auto operator*(Integer const &a, fixed_int b) -> Integer; + friend auto operator*(Integer const &a, Integer const &b) -> Integer; + friend auto operator*(Integer &&a, fixed_int b) -> Integer; + friend auto operator*(Integer &&a, Integer const &b) -> Integer; + friend auto operator*=(Integer &a, fixed_int b) -> Integer &; + friend auto operator*=(Integer &a, Integer const &b) -> Integer &; - friend bool operator<(Integer const &a, fixed_int b); - friend bool operator<(Integer const &a, Integer const &b); + friend auto operator<(Integer const &a, fixed_int b) -> bool; + friend auto operator<(Integer const &a, Integer const &b) -> bool; - friend bool operator<=(Integer const &a, fixed_int b); - friend bool operator<=(Integer const &a, Integer const &b); + friend auto operator<=(Integer const &a, fixed_int b) -> bool; + friend auto operator<=(Integer const &a, Integer const &b) -> bool; - friend bool operator>(Integer const &a, fixed_int b); - friend bool operator>(Integer const &a, Integer const &b); + friend auto operator>(Integer const &a, fixed_int b) -> bool; + friend auto operator>(Integer const &a, Integer const &b) -> bool; - friend bool operator>=(Integer const &a, fixed_int b); - friend bool operator>=(Integer const &a, Integer const &b); + friend auto operator>=(Integer const &a, fixed_int b) -> bool; + friend auto operator>=(Integer const &a, Integer const &b) -> bool; - friend bool operator==(Integer const &a, fixed_int b); - friend bool operator==(Integer const &a, Integer const &b); + friend auto operator==(Integer const &a, fixed_int b) -> bool; + friend auto operator==(Integer const &a, Integer const &b) -> bool; - friend bool operator!=(Integer const &a, fixed_int b); - friend bool operator!=(Integer const &a, Integer const &b); + friend auto operator!=(Integer const &a, fixed_int b) -> bool; + friend auto operator!=(Integer const &a, Integer const &b) -> bool; - friend std::ostream &operator<<(std::ostream &out, Integer const &a); + friend auto operator<<(std::ostream &out, Integer const &a) -> std::ostream &; - friend int compare(Integer const &a, fixed_int b); - friend int compare(Integer const &a, Integer const &b); + friend auto compare(Integer const &a, fixed_int b) -> int; + friend auto compare(Integer const &a, Integer const &b) -> int; - friend Integer gcd(Integer const &a, Integer const &b); - friend std::tuple gcd_div(Integer const &a, Integer const &b); + friend auto gcd(Integer const &a, Integer const &b) -> Integer; + friend auto gcd_div(Integer const &a, Integer const &b) -> std::tuple; -public: + public: Integer() noexcept; Integer(fixed_int val); Integer(char const *val, int radix); Integer(std::string const &val, int radix); Integer(Integer const &a); Integer(Integer &&a) noexcept; - Integer &operator=(Integer const &a); - Integer &operator=(Integer &&a) noexcept; + auto operator=(Integer const &a) -> Integer &; + auto operator=(Integer &&a) noexcept -> Integer &; ~Integer() noexcept; void swap(Integer &x) noexcept; - Integer ÷(Integer const &a); - Integer &add_mul(Integer const &a, Integer const &b) &; - Integer add_mul(Integer const &a, Integer const &b) &&; - Integer &neg(); - [[nodiscard]] fmpz &impl() const; + auto divide(Integer const &a) -> Integer &; + auto add_mul(Integer const &a, Integer const &b) & -> Integer &; + auto add_mul(Integer const &a, Integer const &b) && -> Integer; + auto neg() -> Integer &; + [[nodiscard]] auto impl() const -> fmpz &; -private: + private: mutable fmpz num_; }; class Rational { -private: - friend Rational operator+(Rational const &a, fixed_int b); - friend Rational operator+(Rational const &a, Integer const &b); - friend Rational operator+(Rational const &a, Rational const &b); - friend Rational operator+(Rational &&a, fixed_int b); - friend Rational operator+(Rational &&a, Integer const &b); - friend Rational operator+(Rational &&a, Rational const &b); - friend Rational &operator+=(Rational &a, fixed_int b); - friend Rational &operator+=(Rational &a, Integer const &b); - friend Rational &operator+=(Rational &a, Rational const &b); - - friend Rational operator-(Rational a); - - friend Rational operator-(Rational const &a, fixed_int b); - friend Rational operator-(Rational const &a, Integer const &b); - friend Rational operator-(Rational const &a, Rational const &b); - friend Rational operator-(Rational &&a, fixed_int b); - friend Rational operator-(Rational &&a, Integer const &b); - friend Rational operator-(Rational &&a, Rational const &b); - friend Rational &operator-=(Rational &a, fixed_int b); - friend Rational &operator-=(Rational &a, Integer const &b); - friend Rational &operator-=(Rational &a, Rational const &b); - - friend Rational operator*(Rational const &a, fixed_int b); - friend Rational operator*(Rational const &a, Integer const &b); - friend Rational operator*(Rational const &a, Rational const &b); - friend Rational operator*(Rational &&a, fixed_int b); - friend Rational operator*(Rational &&a, Integer const &b); - friend Rational operator*(Rational &&a, Rational const &b); - friend Rational &operator*=(Rational &a, fixed_int b); - friend Rational &operator*=(Rational &a, Integer const &b); - friend Rational &operator*=(Rational &a, Rational const &b); - - friend Rational operator/(Rational const &a, fixed_int b); - friend Rational operator/(Rational const &a, Integer const &b); - friend Rational operator/(Rational const &a, Rational const &b); - friend Rational operator/(Rational &&a, fixed_int b); - friend Rational operator/(Rational &&a, Integer const &b); - friend Rational operator/(Rational &&a, Rational const &b); - friend Rational &operator/=(Rational &a, fixed_int b); - friend Rational &operator/=(Rational &a, Integer const &b); - friend Rational &operator/=(Rational &a, Rational const &b); - - friend bool operator<(Rational const &a, fixed_int b); - friend bool operator<(Rational const &a, Integer const &b); - friend bool operator<(Rational const &a, Rational const &b); - - friend bool operator<=(Rational const &a, fixed_int b); - friend bool operator<=(Rational const &a, Integer const &b); - friend bool operator<=(Rational const &a, Rational const &b); - - friend bool operator>(Rational const &a, fixed_int b); - friend bool operator>(Rational const &a, Integer const &b); - friend bool operator>(Rational const &a, Rational const &b); - - friend bool operator>=(Rational const &a, fixed_int b); - friend bool operator>=(Rational const &a, Integer const &b); - friend bool operator>=(Rational const &a, Rational const &b); - - friend bool operator==(Rational const &a, fixed_int b); - friend bool operator==(Rational const &a, Integer const &b); - friend bool operator==(Rational const &a, Rational const &b); - - friend bool operator!=(Rational const &a, fixed_int b); - friend bool operator!=(Rational const &a, Integer const &b); - friend bool operator!=(Rational const &a, Rational const &b); - - friend std::ostream &operator<<(std::ostream &out, Rational const &a); - - friend int compare(Rational const &a, fixed_int b); - friend int compare(Rational const &a, Integer const &b); - friend int compare(Rational const &a, Rational const &b); - -public: + private: + friend auto operator+(Rational const &a, fixed_int b) -> Rational; + friend auto operator+(Rational const &a, Integer const &b) -> Rational; + friend auto operator+(Rational const &a, Rational const &b) -> Rational; + friend auto operator+(Rational &&a, fixed_int b) -> Rational; + friend auto operator+(Rational &&a, Integer const &b) -> Rational; + friend auto operator+(Rational &&a, Rational const &b) -> Rational; + friend auto operator+=(Rational &a, fixed_int b) -> Rational &; + friend auto operator+=(Rational &a, Integer const &b) -> Rational &; + friend auto operator+=(Rational &a, Rational const &b) -> Rational &; + + friend auto operator-(Rational a) -> Rational; + + friend auto operator-(Rational const &a, fixed_int b) -> Rational; + friend auto operator-(Rational const &a, Integer const &b) -> Rational; + friend auto operator-(Rational const &a, Rational const &b) -> Rational; + friend auto operator-(Rational &&a, fixed_int b) -> Rational; + friend auto operator-(Rational &&a, Integer const &b) -> Rational; + friend auto operator-(Rational &&a, Rational const &b) -> Rational; + friend auto operator-=(Rational &a, fixed_int b) -> Rational &; + friend auto operator-=(Rational &a, Integer const &b) -> Rational &; + friend auto operator-=(Rational &a, Rational const &b) -> Rational &; + + friend auto operator*(Rational const &a, fixed_int b) -> Rational; + friend auto operator*(Rational const &a, Integer const &b) -> Rational; + friend auto operator*(Rational const &a, Rational const &b) -> Rational; + friend auto operator*(Rational &&a, fixed_int b) -> Rational; + friend auto operator*(Rational &&a, Integer const &b) -> Rational; + friend auto operator*(Rational &&a, Rational const &b) -> Rational; + friend auto operator*=(Rational &a, fixed_int b) -> Rational &; + friend auto operator*=(Rational &a, Integer const &b) -> Rational &; + friend auto operator*=(Rational &a, Rational const &b) -> Rational &; + + friend auto operator/(Rational const &a, fixed_int b) -> Rational; + friend auto operator/(Rational const &a, Integer const &b) -> Rational; + friend auto operator/(Rational const &a, Rational const &b) -> Rational; + friend auto operator/(Rational &&a, fixed_int b) -> Rational; + friend auto operator/(Rational &&a, Integer const &b) -> Rational; + friend auto operator/(Rational &&a, Rational const &b) -> Rational; + friend auto operator/=(Rational &a, fixed_int b) -> Rational &; + friend auto operator/=(Rational &a, Integer const &b) -> Rational &; + friend auto operator/=(Rational &a, Rational const &b) -> Rational &; + + friend auto operator<(Rational const &a, fixed_int b) -> bool; + friend auto operator<(Rational const &a, Integer const &b) -> bool; + friend auto operator<(Rational const &a, Rational const &b) -> bool; + + friend auto operator<=(Rational const &a, fixed_int b) -> bool; + friend auto operator<=(Rational const &a, Integer const &b) -> bool; + friend auto operator<=(Rational const &a, Rational const &b) -> bool; + + friend auto operator>(Rational const &a, fixed_int b) -> bool; + friend auto operator>(Rational const &a, Integer const &b) -> bool; + friend auto operator>(Rational const &a, Rational const &b) -> bool; + + friend auto operator>=(Rational const &a, fixed_int b) -> bool; + friend auto operator>=(Rational const &a, Integer const &b) -> bool; + friend auto operator>=(Rational const &a, Rational const &b) -> bool; + + friend auto operator==(Rational const &a, fixed_int b) -> bool; + friend auto operator==(Rational const &a, Integer const &b) -> bool; + friend auto operator==(Rational const &a, Rational const &b) -> bool; + + friend auto operator!=(Rational const &a, fixed_int b) -> bool; + friend auto operator!=(Rational const &a, Integer const &b) -> bool; + friend auto operator!=(Rational const &a, Rational const &b) -> bool; + + friend auto operator<<(std::ostream &out, Rational const &a) -> std::ostream &; + + friend auto compare(Rational const &a, fixed_int b) -> int; + friend auto compare(Rational const &a, Integer const &b) -> int; + friend auto compare(Rational const &a, Rational const &b) -> int; + + public: Rational() noexcept; Rational(fixed_int val); Rational(Integer num, Integer den); @@ -170,19 +170,19 @@ public: Rational(std::string const &val, int radix); Rational(Rational const &a); Rational(Rational &&a) noexcept; - Rational &operator=(Rational const &a); - Rational &operator=(Rational &&a) noexcept; + auto operator=(Rational const &a) -> Rational &; + auto operator=(Rational &&a) noexcept -> Rational &; ~Rational() noexcept; - [[nodiscard]] Integer &num(); - [[nodiscard]] Integer const &num() const; - [[nodiscard]] Integer &den(); - [[nodiscard]] Integer const &den() const; - Rational &neg(); + [[nodiscard]] auto num() -> Integer &; + [[nodiscard]] auto num() const -> Integer const &; + [[nodiscard]] auto den() -> Integer &; + [[nodiscard]] auto den() const -> Integer const &; + auto neg() -> Rational &; void swap(Rational &x) noexcept; void canonicalize(); -private: + private: mutable fmpq num_; }; @@ -192,75 +192,58 @@ inline Integer::Integer() noexcept { // NOLINT fmpz_init(&num_); } -inline Integer::Integer(fixed_int val) -: Integer() { - fmpz_set_si(&num_, val); -} +inline Integer::Integer(fixed_int val) : Integer() { fmpz_set_si(&num_, val); } -inline Integer::Integer(char const *val, int radix) -: Integer() { +inline Integer::Integer(char const *val, int radix) : Integer() { if (fmpz_set_str(&num_, val, radix) != 0) { throw std::runtime_error("could not parse number"); } } -inline Integer::Integer(std::string const &val, int radix) -: Integer(val.c_str(), radix) { } +inline Integer::Integer(std::string const &val, int radix) : Integer(val.c_str(), radix) {} -inline Integer::Integer(Integer const &a) -: Integer() { - fmpz_set(&num_, &a.num_); -} +inline Integer::Integer(Integer const &a) : Integer() { fmpz_set(&num_, &a.num_); } -inline Integer::Integer(Integer &&a) noexcept -: Integer() { - swap(a); -} +inline Integer::Integer(Integer &&a) noexcept : Integer() { swap(a); } -inline Integer &Integer::operator=(Integer const &a) { +inline auto Integer::operator=(Integer const &a) -> Integer & { fmpz_set(&num_, &a.num_); return *this; } -inline Integer &Integer::operator=(Integer &&a) noexcept { +inline auto Integer::operator=(Integer &&a) noexcept -> Integer & { swap(a); return *this; } -inline Integer::~Integer() noexcept { - fmpz_clear(&num_); -} +inline Integer::~Integer() noexcept { fmpz_clear(&num_); } -inline void Integer::swap(Integer &x) noexcept { - fmpz_swap(&num_, &x.num_); -} +inline void Integer::swap(Integer &x) noexcept { fmpz_swap(&num_, &x.num_); } -inline Integer &Integer::divide(Integer const &a) { +inline auto Integer::divide(Integer const &a) -> Integer & { fmpz_divexact(&num_, &num_, &a.num_); return *this; } -inline Integer &Integer::add_mul(Integer const &a, Integer const &b) & { +inline auto Integer::add_mul(Integer const &a, Integer const &b) & -> Integer & { fmpz_addmul(&num_, &a.num_, &b.num_); return *this; } -inline Integer Integer::add_mul(Integer const &a, Integer const &b) && { +inline auto Integer::add_mul(Integer const &a, Integer const &b) && -> Integer { return std::move(this->add_mul(a, b)); } -inline Integer &Integer::neg() { +inline auto Integer::neg() -> Integer & { fmpz_neg(&num_, &num_); return *this; } -inline fmpz &Integer::impl() const { - return num_; -} +inline auto Integer::impl() const -> fmpz & { return num_; } // addition -[[nodiscard]] inline Integer operator+(Integer const &a, fixed_int b) { +[[nodiscard]] inline auto operator+(Integer const &a, fixed_int b) -> Integer { #if __FLINT_RELEASE >= 20600 Integer c; fmpz_add_si(&c.num_, &a.num_, b); @@ -270,21 +253,17 @@ inline fmpz &Integer::impl() const { #endif } -[[nodiscard]] inline Integer operator+(Integer const &a, Integer const &b) { +[[nodiscard]] inline auto operator+(Integer const &a, Integer const &b) -> Integer { Integer c; fmpz_add(&c.num_, &a.num_, &b.num_); return c; } -[[nodiscard]] inline Integer operator+(Integer &&a, fixed_int b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(Integer &&a, fixed_int b) -> Integer { return std::move(a += b); } -[[nodiscard]] inline Integer operator+(Integer &&a, Integer const &b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(Integer &&a, Integer const &b) -> Integer { return std::move(a += b); } -inline Integer &operator+=(Integer &a, fixed_int b) { +inline auto operator+=(Integer &a, fixed_int b) -> Integer & { #if __FLINT_RELEASE >= 20600 fmpz_add_si(&a.num_, &a.num_, b); return a; @@ -293,19 +272,19 @@ inline Integer &operator+=(Integer &a, fixed_int b) { #endif } -inline Integer &operator+=(Integer &a, Integer const &b) { +inline auto operator+=(Integer &a, Integer const &b) -> Integer & { fmpz_add(&a.num_, &a.num_, &b.num_); return a; } // subtraction -[[nodiscard]] inline Integer operator-(Integer a) { +[[nodiscard]] inline auto operator-(Integer a) -> Integer { a.neg(); return a; } -[[nodiscard]] inline Integer operator-(Integer const &a, fixed_int b) { +[[nodiscard]] inline auto operator-(Integer const &a, fixed_int b) -> Integer { #if __FLINT_RELEASE >= 20600 Integer c; fmpz_sub_si(&c.num_, &a.num_, b); @@ -315,21 +294,17 @@ inline Integer &operator+=(Integer &a, Integer const &b) { #endif } -[[nodiscard]] inline Integer operator-(Integer const &a, Integer const &b) { +[[nodiscard]] inline auto operator-(Integer const &a, Integer const &b) -> Integer { Integer c; fmpz_sub(&c.num_, &a.num_, &b.num_); return c; } -[[nodiscard]] inline Integer operator-(Integer &&a, fixed_int b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(Integer &&a, fixed_int b) -> Integer { return std::move(a -= b); } -[[nodiscard]] inline Integer operator-(Integer &&a, Integer const &b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(Integer &&a, Integer const &b) -> Integer { return std::move(a -= b); } -inline Integer &operator-=(Integer &a, fixed_int b) { +inline auto operator-=(Integer &a, fixed_int b) -> Integer & { #if __FLINT_RELEASE >= 20600 fmpz_sub_si(&a.num_, &a.num_, b); return a; @@ -338,107 +313,80 @@ inline Integer &operator-=(Integer &a, fixed_int b) { #endif } -inline Integer &operator-=(Integer &a, Integer const &b) { +inline auto operator-=(Integer &a, Integer const &b) -> Integer & { fmpz_sub(&a.num_, &a.num_, &b.num_); return a; } // multiplication -[[nodiscard]] inline Integer operator*(Integer const &a, fixed_int b) { +[[nodiscard]] inline auto operator*(Integer const &a, fixed_int b) -> Integer { Integer c; fmpz_mul_si(&c.num_, &a.num_, b); return c; } -[[nodiscard]] inline Integer operator*(Integer const &a, Integer const &b) { +[[nodiscard]] inline auto operator*(Integer const &a, Integer const &b) -> Integer { Integer c; fmpz_mul(&c.num_, &a.num_, &b.num_); return c; } -[[nodiscard]] inline Integer operator*(Integer &&a, fixed_int b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(Integer &&a, fixed_int b) -> Integer { return std::move(a *= b); } -[[nodiscard]] inline Integer operator*(Integer &&a, Integer const &b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(Integer &&a, Integer const &b) -> Integer { return std::move(a *= b); } -inline Integer &operator*=(Integer &a, fixed_int b) { +inline auto operator*=(Integer &a, fixed_int b) -> Integer & { fmpz_mul_si(&a.num_, &a.num_, b); return a; } -inline Integer &operator*=(Integer &a, Integer const &b) { +inline auto operator*=(Integer &a, Integer const &b) -> Integer & { fmpz_mul(&a.num_, &a.num_, &b.num_); return a; } // less than -[[nodiscard]] inline bool operator<(Integer const &a, fixed_int b) { - return compare(a, b) < 0; -} +[[nodiscard]] inline auto operator<(Integer const &a, fixed_int b) -> bool { return compare(a, b) < 0; } -[[nodiscard]] inline bool operator<(Integer const &a, Integer const &b) { - return compare(a, b) < 0; -} +[[nodiscard]] inline auto operator<(Integer const &a, Integer const &b) -> bool { return compare(a, b) < 0; } // less than or equal to -[[nodiscard]] inline bool operator<=(Integer const &a, fixed_int b) { - return compare(a, b) <= 0; -} +[[nodiscard]] inline auto operator<=(Integer const &a, fixed_int b) -> bool { return compare(a, b) <= 0; } -[[nodiscard]] inline bool operator<=(Integer const &a, Integer const &b) { - return compare(a, b) <= 0; -} +[[nodiscard]] inline auto operator<=(Integer const &a, Integer const &b) -> bool { return compare(a, b) <= 0; } // greater than -[[nodiscard]] inline bool operator>(Integer const &a, fixed_int b) { - return compare(a, b) > 0; -} +[[nodiscard]] inline auto operator>(Integer const &a, fixed_int b) -> bool { return compare(a, b) > 0; } -[[nodiscard]] inline bool operator>(Integer const &a, Integer const &b) { - return compare(a, b) > 0; -} +[[nodiscard]] inline auto operator>(Integer const &a, Integer const &b) -> bool { return compare(a, b) > 0; } // greater than or equal to -[[nodiscard]] inline bool operator>=(Integer const &a, fixed_int b) { - return compare(a, b) >= 0; -} +[[nodiscard]] inline auto operator>=(Integer const &a, fixed_int b) -> bool { return compare(a, b) >= 0; } -[[nodiscard]] inline bool operator>=(Integer const &a, Integer const &b) { - return compare(a, b) >= 0; -} +[[nodiscard]] inline auto operator>=(Integer const &a, Integer const &b) -> bool { return compare(a, b) >= 0; } // greater equal to +[[nodiscard]] inline auto operator==(Integer const &a, fixed_int b) -> bool { return fmpz_equal_si(&a.num_, b) != 0; } -[[nodiscard]] inline bool operator==(Integer const &a, fixed_int b) { - return fmpz_equal_si(&a.num_, b) != 0; -} - -[[nodiscard]] inline bool operator==(Integer const &a, Integer const &b) { +[[nodiscard]] inline auto operator==(Integer const &a, Integer const &b) -> bool { return fmpz_equal(&a.num_, &b.num_) != 0; } // not equal to -[[nodiscard]] inline bool operator!=(Integer const &a, fixed_int b) { - return !(a == b); -} +[[nodiscard]] inline auto operator!=(Integer const &a, fixed_int b) -> bool { return !(a == b); } -[[nodiscard]] inline bool operator!=(Integer const &a, Integer const &b) { - return !(a == b); -} +[[nodiscard]] inline auto operator!=(Integer const &a, Integer const &b) -> bool { return !(a == b); } // printing -inline std::ostream &operator<<(std::ostream &out, Integer const &a) { +inline auto operator<<(std::ostream &out, Integer const &a) -> std::ostream & { std::unique_ptr buf{fmpz_get_str(nullptr, BASE, &a.num_), flint_free}; if (buf == nullptr) { throw std::bad_alloc(); @@ -449,23 +397,19 @@ inline std::ostream &operator<<(std::ostream &out, Integer const &a) { // comparison -[[nodiscard]] inline int compare(Integer const &a, fixed_int b) { - return fmpz_cmp_si(&a.num_, b); -} +[[nodiscard]] inline auto compare(Integer const &a, fixed_int b) -> int { return fmpz_cmp_si(&a.num_, b); } -[[nodiscard]] inline int compare(Integer const &a, Integer const &b) { - return fmpz_cmp_si(&a.num_, b.num_); -} +[[nodiscard]] inline auto compare(Integer const &a, Integer const &b) -> int { return fmpz_cmp_si(&a.num_, b.num_); } // gcd -[[nodiscard]] inline Integer gcd(Integer const &a, Integer const &b) { +[[nodiscard]] inline auto gcd(Integer const &a, Integer const &b) -> Integer { Integer g; fmpz_gcd(&g.num_, &a.num_, &b.num_); return g; } -[[nodiscard]] inline std::tuple gcd_div(Integer const &a, Integer const &b) { +[[nodiscard]] inline auto gcd_div(Integer const &a, Integer const &b) -> std::tuple { std::tuple ret; fmpz_gcd(&std::get<0>(ret).num_, &a.num_, &b.num_); fmpz_divexact(&std::get<1>(ret).num_, &a.num_, &std::get<0>(ret).num_); @@ -479,13 +423,9 @@ inline Rational::Rational() noexcept { // NOLINT fmpq_init(&num_); } -inline Rational::Rational(fixed_int val) -: Rational() { - fmpq_set_si(&num_, val, 1); -} +inline Rational::Rational(fixed_int val) : Rational() { fmpq_set_si(&num_, val, 1); } -inline Rational::Rational(char const *val, int radix) -: Rational() { +inline Rational::Rational(char const *val, int radix) : Rational() { #if __FLINT_RELEASE >= 20600 if (fmpq_set_str(&num_, val, radix) != 0) { throw std::runtime_error("could not parse number"); @@ -498,12 +438,11 @@ inline Rational::Rational(char const *val, int radix) throw std::runtime_error("could not parse number"); } fmpz_set_si(&num_.den, 1); - } - else { + } else { if (fmpz_set_str(&num_.num, buf.substr(0, pos).c_str(), radix) != 0) { throw std::runtime_error("could not parse number"); } - if (fmpz_set_str(&num_.den, buf.substr(pos+1).c_str(), radix) != 0) { + if (fmpz_set_str(&num_.den, buf.substr(pos + 1).c_str(), radix) != 0) { throw std::runtime_error("could not parse number"); } fmpq_canonicalise(&num_); @@ -511,76 +450,61 @@ inline Rational::Rational(char const *val, int radix) #endif } -inline Rational::Rational(std::string const &val, int radix) -: Rational(val.c_str(), radix) { -} +inline Rational::Rational(std::string const &val, int radix) : Rational(val.c_str(), radix) {} -inline Rational::Rational(Rational const &a) -: Rational() { - fmpq_set(&num_, &a.num_); -} +inline Rational::Rational(Rational const &a) : Rational() { fmpq_set(&num_, &a.num_); } -inline Rational::Rational(Integer num, Integer den) -: Rational() { +inline Rational::Rational(Integer num, Integer den) : Rational() { this->num() = std::move(num); this->den() = std::move(den); canonicalize(); } -inline Rational::Rational(Rational &&a) noexcept -: Rational() { - swap(a); -} +inline Rational::Rational(Rational &&a) noexcept : Rational() { swap(a); } -inline Rational &Rational::operator=(Rational const &a) { +inline auto Rational::operator=(Rational const &a) -> Rational & { fmpq_set(&num_, &a.num_); return *this; } -inline Rational &Rational::operator=(Rational &&a) noexcept { +inline auto Rational::operator=(Rational &&a) noexcept -> Rational & { swap(a); return *this; } -inline Rational::~Rational() noexcept { - fmpq_clear(&num_); -} +inline Rational::~Rational() noexcept { fmpq_clear(&num_); } -inline Integer &Rational::num() { +inline auto Rational::num() -> Integer & { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - return reinterpret_cast(num_.num); + return reinterpret_cast(num_.num); } -inline Integer const &Rational::num() const { +inline auto Rational::num() const -> Integer const & { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - return reinterpret_cast(num_.num); + return reinterpret_cast(num_.num); } -inline Integer &Rational::den() { +inline auto Rational::den() -> Integer & { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - return reinterpret_cast(num_.den); + return reinterpret_cast(num_.den); } -inline Integer const &Rational::den() const { +inline auto Rational::den() const -> Integer const & { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - return reinterpret_cast(num_.den); + return reinterpret_cast(num_.den); } -inline Rational &Rational::neg() { +inline auto Rational::neg() -> Rational & { fmpq_neg(&num_, &num_); return *this; } -inline void Rational::swap(Rational &x) noexcept { - fmpq_swap(&num_, &x.num_); -} +inline void Rational::swap(Rational &x) noexcept { fmpq_swap(&num_, &x.num_); } -inline void Rational::canonicalize() { - fmpq_canonicalise(&num_); -} +inline void Rational::canonicalize() { fmpq_canonicalise(&num_); } // addition -[[nodiscard]] inline Rational operator+(Rational const &a, fixed_int b) { +[[nodiscard]] inline auto operator+(Rational const &a, fixed_int b) -> Rational { #if __FLINT_RELEASE >= 20600 Rational c; fmpq_add_si(&c.num_, &a.num_, b); @@ -590,53 +514,47 @@ inline void Rational::canonicalize() { #endif } -[[nodiscard]] inline Rational operator+(Rational const &a, Integer const &b) { +[[nodiscard]] inline auto operator+(Rational const &a, Integer const &b) -> Rational { Rational c; fmpq_add_fmpz(&c.num_, &a.num_, &b.impl()); return c; } -[[nodiscard]] inline Rational operator+(Rational const &a, Rational const &b) { +[[nodiscard]] inline auto operator+(Rational const &a, Rational const &b) -> Rational { Rational c; fmpq_add(&c.num_, &a.num_, &b.num_); return c; } -[[nodiscard]] inline Rational operator+(Rational &&a, fixed_int b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(Rational &&a, fixed_int b) -> Rational { return std::move(a += b); } -[[nodiscard]] inline Rational operator+(Rational &&a, Integer const &b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(Rational &&a, Integer const &b) -> Rational { return std::move(a += b); } -[[nodiscard]] inline Rational operator+(Rational &&a, Rational const &b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(Rational &&a, Rational const &b) -> Rational { return std::move(a += b); } -inline Rational &operator+=(Rational &a, fixed_int b) { +inline auto operator+=(Rational &a, fixed_int b) -> Rational & { fmpq_add_si(&a.num_, &a.num_, b); return a; } -inline Rational &operator+=(Rational &a, Integer const &b) { +inline auto operator+=(Rational &a, Integer const &b) -> Rational & { fmpq_add_fmpz(&a.num_, &a.num_, &b.impl()); return a; } -inline Rational &operator+=(Rational &a, Rational const &b) { +inline auto operator+=(Rational &a, Rational const &b) -> Rational & { fmpq_add(&a.num_, &a.num_, &b.num_); return a; } // subtraction -[[nodiscard]] inline Rational operator-(Rational a) { +[[nodiscard]] inline auto operator-(Rational a) -> Rational { a.neg(); return a; } -[[nodiscard]] inline Rational operator-(Rational const &a, fixed_int b) { +[[nodiscard]] inline auto operator-(Rational const &a, fixed_int b) -> Rational { #if __FLINT_RELEASE >= 20600 Rational c; fmpq_sub_si(&c.num_, &a.num_, b); @@ -646,48 +564,42 @@ inline Rational &operator+=(Rational &a, Rational const &b) { #endif } -[[nodiscard]] inline Rational operator-(Rational const &a, Integer const &b) { +[[nodiscard]] inline auto operator-(Rational const &a, Integer const &b) -> Rational { Rational c; fmpq_sub_fmpz(&c.num_, &a.num_, &b.impl()); return c; } -[[nodiscard]] inline Rational operator-(Rational const &a, Rational const &b) { +[[nodiscard]] inline auto operator-(Rational const &a, Rational const &b) -> Rational { Rational c; fmpq_sub(&c.num_, &a.num_, &b.num_); return c; } -[[nodiscard]] inline Rational operator-(Rational &&a, fixed_int b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(Rational &&a, fixed_int b) -> Rational { return std::move(a -= b); } -[[nodiscard]] inline Rational operator-(Rational &&a, Integer const &b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(Rational &&a, Integer const &b) -> Rational { return std::move(a -= b); } -[[nodiscard]] inline Rational operator-(Rational &&a, Rational const &b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(Rational &&a, Rational const &b) -> Rational { return std::move(a -= b); } -inline Rational &operator-=(Rational &a, fixed_int b) { +inline auto operator-=(Rational &a, fixed_int b) -> Rational & { fmpq_sub_si(&a.num_, &a.num_, b); return a; } -inline Rational &operator-=(Rational &a, Integer const &b) { +inline auto operator-=(Rational &a, Integer const &b) -> Rational & { fmpq_sub_fmpz(&a.num_, &a.num_, &b.impl()); return a; } -inline Rational &operator-=(Rational &a, Rational const &b) { +inline auto operator-=(Rational &a, Rational const &b) -> Rational & { fmpq_sub(&a.num_, &a.num_, &b.num_); return a; } // multiplication -[[nodiscard]] inline Rational operator*(Rational const &a, fixed_int b) { +[[nodiscard]] inline auto operator*(Rational const &a, fixed_int b) -> Rational { #if __FLINT_RELEASE >= 20600 Rational c; fmpq_mul_si(&c.num_, &a.num_, b); @@ -697,31 +609,25 @@ inline Rational &operator-=(Rational &a, Rational const &b) { #endif } -[[nodiscard]] inline Rational operator*(Rational const &a, Integer const &b) { +[[nodiscard]] inline auto operator*(Rational const &a, Integer const &b) -> Rational { Rational c; fmpq_mul_fmpz(&c.num_, &a.num_, &b.impl()); return c; } -[[nodiscard]] inline Rational operator*(Rational const &a, Rational const &b) { +[[nodiscard]] inline auto operator*(Rational const &a, Rational const &b) -> Rational { Rational c; fmpq_mul(&c.num_, &a.num_, &b.num_); return c; } -[[nodiscard]] inline Rational operator*(Rational &&a, fixed_int b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(Rational &&a, fixed_int b) -> Rational { return std::move(a *= b); } -[[nodiscard]] inline Rational operator*(Rational &&a, Integer const &b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(Rational &&a, Integer const &b) -> Rational { return std::move(a *= b); } -[[nodiscard]] inline Rational operator*(Rational &&a, Rational const &b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(Rational &&a, Rational const &b) -> Rational { return std::move(a *= b); } -inline Rational &operator*=(Rational &a, fixed_int b) { +inline auto operator*=(Rational &a, fixed_int b) -> Rational & { #if __FLINT_RELEASE >= 20600 fmpq_mul_si(&a.num_, &a.num_, b); return a; @@ -730,155 +636,115 @@ inline Rational &operator*=(Rational &a, fixed_int b) { #endif } -inline Rational &operator*=(Rational &a, Integer const &b) { +inline auto operator*=(Rational &a, Integer const &b) -> Rational & { fmpq_mul_fmpz(&a.num_, &a.num_, &b.impl()); return a; } -inline Rational &operator*=(Rational &a, Rational const &b) { +inline auto operator*=(Rational &a, Rational const &b) -> Rational & { fmpq_mul(&a.num_, &a.num_, &b.num_); return a; } // division -[[nodiscard]] inline Rational operator/(Rational const &a, fixed_int b) { - return a / Integer{b}; -} +[[nodiscard]] inline auto operator/(Rational const &a, fixed_int b) -> Rational { return a / Integer{b}; } -[[nodiscard]] inline Rational operator/(Rational const &a, Integer const &b) { +[[nodiscard]] inline auto operator/(Rational const &a, Integer const &b) -> Rational { Rational c; fmpq_div_fmpz(&c.num_, &a.num_, &b.impl()); return c; } -[[nodiscard]] inline Rational operator/(Rational const &a, Rational const &b) { +[[nodiscard]] inline auto operator/(Rational const &a, Rational const &b) -> Rational { Rational c; fmpq_div(&c.num_, &a.num_, &b.num_); return c; } -[[nodiscard]] inline Rational operator/(Rational &&a, fixed_int b) { - return std::move(a /= b); -} +[[nodiscard]] inline auto operator/(Rational &&a, fixed_int b) -> Rational { return std::move(a /= b); } -[[nodiscard]] inline Rational operator/(Rational &&a, Integer const &b) { - return std::move(a /= b); -} +[[nodiscard]] inline auto operator/(Rational &&a, Integer const &b) -> Rational { return std::move(a /= b); } -[[nodiscard]] inline Rational operator/(Rational &&a, Rational const &b) { - return std::move(a /= b); -} +[[nodiscard]] inline auto operator/(Rational &&a, Rational const &b) -> Rational { return std::move(a /= b); } -inline Rational &operator/=(Rational &a, fixed_int b) { - return a /= Integer{b}; -} +inline auto operator/=(Rational &a, fixed_int b) -> Rational & { return a /= Integer{b}; } -inline Rational &operator/=(Rational &a, Integer const &b) { +inline auto operator/=(Rational &a, Integer const &b) -> Rational & { fmpq_div_fmpz(&a.num_, &a.num_, &b.impl()); return a; } -inline Rational &operator/=(Rational &a, Rational const &b) { +inline auto operator/=(Rational &a, Rational const &b) -> Rational & { fmpq_div(&a.num_, &a.num_, &b.num_); return a; } // less than -[[nodiscard]] inline bool operator<(Rational const &a, fixed_int b) { - return compare(a, b) < 0; -} +[[nodiscard]] inline auto operator<(Rational const &a, fixed_int b) -> bool { return compare(a, b) < 0; } -[[nodiscard]] inline bool operator<(Rational const &a, Integer const &b) { - return compare(a, b) < 0; -} +[[nodiscard]] inline auto operator<(Rational const &a, Integer const &b) -> bool { return compare(a, b) < 0; } -[[nodiscard]] inline bool operator<(Rational const &a, Rational const &b) { - return compare(a, b) < 0; -} +[[nodiscard]] inline auto operator<(Rational const &a, Rational const &b) -> bool { return compare(a, b) < 0; } // less than or equal to -[[nodiscard]] inline bool operator<=(Rational const &a, fixed_int b) { - return compare(a, b) <= 0; -} +[[nodiscard]] inline auto operator<=(Rational const &a, fixed_int b) -> bool { return compare(a, b) <= 0; } -[[nodiscard]] inline bool operator<=(Rational const &a, Integer const &b) { - return compare(a, b) <= 0; -} +[[nodiscard]] inline auto operator<=(Rational const &a, Integer const &b) -> bool { return compare(a, b) <= 0; } -[[nodiscard]] inline bool operator<=(Rational const &a, Rational const &b) { - return compare(a, b) <= 0; -} +[[nodiscard]] inline auto operator<=(Rational const &a, Rational const &b) -> bool { return compare(a, b) <= 0; } // greater than -[[nodiscard]] inline bool operator>(Rational const &a, fixed_int b) { - return compare(a, b) > 0; -} +[[nodiscard]] inline auto operator>(Rational const &a, fixed_int b) -> bool { return compare(a, b) > 0; } -[[nodiscard]] inline bool operator>(Rational const &a, Integer const &b) { - return compare(a, b) > 0; -} +[[nodiscard]] inline auto operator>(Rational const &a, Integer const &b) -> bool { return compare(a, b) > 0; } -[[nodiscard]] inline bool operator>(Rational const &a, Rational const &b) { - return compare(a, b) > 0; -} +[[nodiscard]] inline auto operator>(Rational const &a, Rational const &b) -> bool { return compare(a, b) > 0; } // greater than or equal to -[[nodiscard]] inline bool operator>=(Rational const &a, fixed_int b) { - return compare(a, b) >= 0; -} +[[nodiscard]] inline auto operator>=(Rational const &a, fixed_int b) -> bool { return compare(a, b) >= 0; } -[[nodiscard]] inline bool operator>=(Rational const &a, Integer const &b) { - return compare(a, b) >= 0; -} +[[nodiscard]] inline auto operator>=(Rational const &a, Integer const &b) -> bool { return compare(a, b) >= 0; } -[[nodiscard]] inline bool operator>=(Rational const &a, Rational const &b) { - return compare(a, b) >= 0; -} +[[nodiscard]] inline auto operator>=(Rational const &a, Rational const &b) -> bool { return compare(a, b) >= 0; } // equal to -[[nodiscard]] inline bool operator==(Rational const &a, fixed_int b) { +[[nodiscard]] inline auto operator==(Rational const &a, fixed_int b) -> bool { #if __FLINT_RELEASE >= 20600 - return fmpq_equal_si(&a.num_, b) != 0; + return fmpq_equal_si(&a.num_, b) != 0; #else - return a == Rational{b}; + return a == Rational{b}; #endif } -[[nodiscard]] inline bool operator==(Rational const &a, Integer const &b) { +[[nodiscard]] inline auto operator==(Rational const &a, Integer const &b) -> bool { #if __FLINT_RELEASE >= 20600 - return fmpq_equal_fmpz(&a.num_, &b.impl()) != 0; + return fmpq_equal_fmpz(&a.num_, &b.impl()) != 0; #else - return a == Rational{b, Integer{1}}; + return a == Rational{b, Integer{1}}; #endif } -[[nodiscard]] inline bool operator==(Rational const &a, Rational const &b) { - return fmpq_equal(&a.num_, &b.num_) != 0; +[[nodiscard]] inline auto operator==(Rational const &a, Rational const &b) -> bool { + return fmpq_equal(&a.num_, &b.num_) != 0; } // not equal to -[[nodiscard]] inline bool operator!=(Rational const &a, fixed_int b) { - return !(a == b); -} +[[nodiscard]] inline auto operator!=(Rational const &a, fixed_int b) -> bool { return !(a == b); } -[[nodiscard]] inline bool operator!=(Rational const &a, Integer const &b) { - return !(a == b); -} +[[nodiscard]] inline auto operator!=(Rational const &a, Integer const &b) -> bool { return !(a == b); } -[[nodiscard]] inline bool operator!=(Rational const &a, Rational const &b) { - return !(a == b); -} +[[nodiscard]] inline auto operator!=(Rational const &a, Rational const &b) -> bool { return !(a == b); } // printing -inline std::ostream &operator<<(std::ostream &out, Rational const &a) { +inline auto operator<<(std::ostream &out, Rational const &a) -> std::ostream & { std::unique_ptr buf{fmpq_get_str(nullptr, BASE, &a.num_), flint_free}; if (buf == nullptr) { throw std::bad_alloc(); @@ -889,24 +755,22 @@ inline std::ostream &operator<<(std::ostream &out, Rational const &a) { // comparison -[[nodiscard]] inline int compare(Rational const &a, fixed_int b) { +[[nodiscard]] inline auto compare(Rational const &a, fixed_int b) -> int { #if __FLINT_RELEASE >= 20600 - return fmpq_cmp_si(&a.num_, b); + return fmpq_cmp_si(&a.num_, b); #else - return compare(a, Rational{b}); + return compare(a, Rational{b}); #endif } -[[nodiscard]] inline int compare(Rational const &a, Integer const &b) { +[[nodiscard]] inline auto compare(Rational const &a, Integer const &b) -> int { #if __FLINT_RELEASE >= 20600 - return fmpq_cmp_fmpz(&a.num_, &b.impl()); + return fmpq_cmp_fmpz(&a.num_, &b.impl()); #else - return compare(a, Rational{b, 1}); + return compare(a, Rational{b, 1}); #endif } -[[nodiscard]] inline int compare(Rational const &a, Rational const &b) { - return fmpq_cmp(&a.num_, &b.num_); -} +[[nodiscard]] inline auto compare(Rational const &a, Rational const &b) -> int { return fmpq_cmp(&a.num_, &b.num_); } #endif diff --git a/libclingo-lpx/src/number_imath.hh b/libclingo-lpx/src/number_imath.hh index 83dbf4c..928c3b3 100644 --- a/libclingo-lpx/src/number_imath.hh +++ b/libclingo-lpx/src/number_imath.hh @@ -6,164 +6,164 @@ #include #include +#include +#include #include #include #include -#include -#include constexpr int BASE = 10; using fixed_int = mp_small; class Integer { -private: - friend Integer operator+(Integer const &a, fixed_int b); - friend Integer operator+(Integer const &a, Integer const &b); - friend Integer operator+(Integer &&a, fixed_int b); - friend Integer operator+(Integer &&a, Integer const &b); - friend Integer &operator+=(Integer &a, fixed_int b); - friend Integer &operator+=(Integer &a, Integer const &b); + private: + friend auto operator+(Integer const &a, fixed_int b) -> Integer; + friend auto operator+(Integer const &a, Integer const &b) -> Integer; + friend auto operator+(Integer &&a, fixed_int b) -> Integer; + friend auto operator+(Integer &&a, Integer const &b) -> Integer; + friend auto operator+=(Integer &a, fixed_int b) -> Integer &; + friend auto operator+=(Integer &a, Integer const &b) -> Integer &; - friend Integer operator-(Integer a); + friend auto operator-(Integer a) -> Integer; - friend Integer operator-(Integer const &a, fixed_int b); - friend Integer operator-(Integer const &a, Integer const &b); - friend Integer operator-(Integer &&a, fixed_int b); - friend Integer operator-(Integer &&a, Integer const &b); - friend Integer &operator-=(Integer &a, fixed_int b); - friend Integer &operator-=(Integer &a, Integer const &b); + friend auto operator-(Integer const &a, fixed_int b) -> Integer; + friend auto operator-(Integer const &a, Integer const &b) -> Integer; + friend auto operator-(Integer &&a, fixed_int b) -> Integer; + friend auto operator-(Integer &&a, Integer const &b) -> Integer; + friend auto operator-=(Integer &a, fixed_int b) -> Integer &; + friend auto operator-=(Integer &a, Integer const &b) -> Integer &; - friend Integer operator*(Integer const &a, fixed_int b); - friend Integer operator*(Integer const &a, Integer const &b); - friend Integer operator*(Integer &&a, fixed_int b); - friend Integer operator*(Integer &&a, Integer const &b); - friend Integer &operator*=(Integer &a, fixed_int b); - friend Integer &operator*=(Integer &a, Integer const &b); + friend auto operator*(Integer const &a, fixed_int b) -> Integer; + friend auto operator*(Integer const &a, Integer const &b) -> Integer; + friend auto operator*(Integer &&a, fixed_int b) -> Integer; + friend auto operator*(Integer &&a, Integer const &b) -> Integer; + friend auto operator*=(Integer &a, fixed_int b) -> Integer &; + friend auto operator*=(Integer &a, Integer const &b) -> Integer &; - friend bool operator<(Integer const &a, fixed_int b); - friend bool operator<(Integer const &a, Integer const &b); + friend auto operator<(Integer const &a, fixed_int b) -> bool; + friend auto operator<(Integer const &a, Integer const &b) -> bool; - friend bool operator<=(Integer const &a, fixed_int b); - friend bool operator<=(Integer const &a, Integer const &b); + friend auto operator<=(Integer const &a, fixed_int b) -> bool; + friend auto operator<=(Integer const &a, Integer const &b) -> bool; - friend bool operator>(Integer const &a, fixed_int b); - friend bool operator>(Integer const &a, Integer const &b); + friend auto operator>(Integer const &a, fixed_int b) -> bool; + friend auto operator>(Integer const &a, Integer const &b) -> bool; - friend bool operator>=(Integer const &a, fixed_int b); - friend bool operator>=(Integer const &a, Integer const &b); + friend auto operator>=(Integer const &a, fixed_int b) -> bool; + friend auto operator>=(Integer const &a, Integer const &b) -> bool; - friend bool operator==(Integer const &a, fixed_int b); - friend bool operator==(Integer const &a, Integer const &b); + friend auto operator==(Integer const &a, fixed_int b) -> bool; + friend auto operator==(Integer const &a, Integer const &b) -> bool; - friend bool operator!=(Integer const &a, fixed_int b); - friend bool operator!=(Integer const &a, Integer const &b); + friend auto operator!=(Integer const &a, fixed_int b) -> bool; + friend auto operator!=(Integer const &a, Integer const &b) -> bool; - friend std::ostream &operator<<(std::ostream &out, Integer const &a); + friend auto operator<<(std::ostream &out, Integer const &a) -> std::ostream &; - friend int compare(Integer const &a, fixed_int b); - friend int compare(Integer const &a, Integer const &b); + friend auto compare(Integer const &a, fixed_int b) -> int; + friend auto compare(Integer const &a, Integer const &b) -> int; - friend Integer gcd(Integer const &a, Integer const &b); - friend std::tuple gcd_div(Integer const &a, Integer const &b); + friend auto gcd(Integer const &a, Integer const &b) -> Integer; + friend auto gcd_div(Integer const &a, Integer const &b) -> std::tuple; -public: + public: Integer() noexcept; Integer(fixed_int val); Integer(char const *val, int radix); Integer(std::string const &val, int radix); Integer(Integer const &a); Integer(Integer &&a) noexcept; - Integer &operator=(Integer const &a); - Integer &operator=(Integer &&a) noexcept; + auto operator=(Integer const &a) -> Integer &; + auto operator=(Integer &&a) noexcept -> Integer &; ~Integer() noexcept; void swap(Integer &x) noexcept; - Integer ÷(Integer const &a); - Integer &add_mul(Integer const &a, Integer const &b) &; - Integer add_mul(Integer const &a, Integer const &b) &&; - Integer &neg(); - [[nodiscard]] mpz_t &impl() const; + auto divide(Integer const &a) -> Integer &; + auto add_mul(Integer const &a, Integer const &b) & -> Integer &; + auto add_mul(Integer const &a, Integer const &b) && -> Integer; + auto neg() -> Integer &; + [[nodiscard]] auto impl() const -> mpz_t &; -private: + private: mutable mpz_t num_; }; class Rational { -private: - friend Rational operator+(Rational const &a, fixed_int b); - friend Rational operator+(Rational const &a, Integer const &b); - friend Rational operator+(Rational const &a, Rational const &b); - friend Rational operator+(Rational &&a, fixed_int b); - friend Rational operator+(Rational &&a, Integer const &b); - friend Rational operator+(Rational &&a, Rational const &b); - friend Rational &operator+=(Rational &a, fixed_int b); - friend Rational &operator+=(Rational &a, Integer const &b); - friend Rational &operator+=(Rational &a, Rational const &b); - - friend Rational operator-(Rational a); - - friend Rational operator-(Rational const &a, fixed_int b); - friend Rational operator-(Rational const &a, Integer const &b); - friend Rational operator-(Rational const &a, Rational const &b); - friend Rational operator-(Rational &&a, fixed_int b); - friend Rational operator-(Rational &&a, Integer const &b); - friend Rational operator-(Rational &&a, Rational const &b); - friend Rational &operator-=(Rational &a, fixed_int b); - friend Rational &operator-=(Rational &a, Integer const &b); - friend Rational &operator-=(Rational &a, Rational const &b); - - friend Rational operator*(Rational const &a, fixed_int b); - friend Rational operator*(Rational const &a, Integer const &b); - friend Rational operator*(Rational const &a, Rational const &b); - friend Rational operator*(Rational &&a, fixed_int b); - friend Rational operator*(Rational &&a, Integer const &b); - friend Rational operator*(Rational &&a, Rational const &b); - friend Rational &operator*=(Rational &a, fixed_int b); - friend Rational &operator*=(Rational &a, Integer const &b); - friend Rational &operator*=(Rational &a, Rational const &b); - - friend Rational operator/(Rational const &a, fixed_int b); - friend Rational operator/(Rational const &a, Integer const &b); - friend Rational operator/(Rational const &a, Rational const &b); - friend Rational operator/(Rational &&a, fixed_int b); - friend Rational operator/(Rational &&a, Integer const &b); - friend Rational operator/(Rational &&a, Rational const &b); - friend Rational &operator/=(Rational &a, fixed_int b); - friend Rational &operator/=(Rational &a, Integer const &b); - friend Rational &operator/=(Rational &a, Rational const &b); - - friend bool operator<(Rational const &a, fixed_int b); - friend bool operator<(Rational const &a, Integer const &b); - friend bool operator<(Rational const &a, Rational const &b); - - friend bool operator<=(Rational const &a, fixed_int b); - friend bool operator<=(Rational const &a, Integer const &b); - friend bool operator<=(Rational const &a, Rational const &b); - - friend bool operator>(Rational const &a, fixed_int b); - friend bool operator>(Rational const &a, Integer const &b); - friend bool operator>(Rational const &a, Rational const &b); - - friend bool operator>=(Rational const &a, fixed_int b); - friend bool operator>=(Rational const &a, Integer const &b); - friend bool operator>=(Rational const &a, Rational const &b); - - friend bool operator==(Rational const &a, fixed_int b); - friend bool operator==(Rational const &a, Integer const &b); - friend bool operator==(Rational const &a, Rational const &b); - - friend bool operator!=(Rational const &a, fixed_int b); - friend bool operator!=(Rational const &a, Integer const &b); - friend bool operator!=(Rational const &a, Rational const &b); - - friend std::ostream &operator<<(std::ostream &out, Rational const &a); - - friend int compare(Rational const &a, fixed_int b); - friend int compare(Rational const &a, Integer const &b); - friend int compare(Rational const &a, Rational const &b); - -public: + private: + friend auto operator+(Rational const &a, fixed_int b) -> Rational; + friend auto operator+(Rational const &a, Integer const &b) -> Rational; + friend auto operator+(Rational const &a, Rational const &b) -> Rational; + friend auto operator+(Rational &&a, fixed_int b) -> Rational; + friend auto operator+(Rational &&a, Integer const &b) -> Rational; + friend auto operator+(Rational &&a, Rational const &b) -> Rational; + friend auto operator+=(Rational &a, fixed_int b) -> Rational &; + friend auto operator+=(Rational &a, Integer const &b) -> Rational &; + friend auto operator+=(Rational &a, Rational const &b) -> Rational &; + + friend auto operator-(Rational a) -> Rational; + + friend auto operator-(Rational const &a, fixed_int b) -> Rational; + friend auto operator-(Rational const &a, Integer const &b) -> Rational; + friend auto operator-(Rational const &a, Rational const &b) -> Rational; + friend auto operator-(Rational &&a, fixed_int b) -> Rational; + friend auto operator-(Rational &&a, Integer const &b) -> Rational; + friend auto operator-(Rational &&a, Rational const &b) -> Rational; + friend auto operator-=(Rational &a, fixed_int b) -> Rational &; + friend auto operator-=(Rational &a, Integer const &b) -> Rational &; + friend auto operator-=(Rational &a, Rational const &b) -> Rational &; + + friend auto operator*(Rational const &a, fixed_int b) -> Rational; + friend auto operator*(Rational const &a, Integer const &b) -> Rational; + friend auto operator*(Rational const &a, Rational const &b) -> Rational; + friend auto operator*(Rational &&a, fixed_int b) -> Rational; + friend auto operator*(Rational &&a, Integer const &b) -> Rational; + friend auto operator*(Rational &&a, Rational const &b) -> Rational; + friend auto operator*=(Rational &a, fixed_int b) -> Rational &; + friend auto operator*=(Rational &a, Integer const &b) -> Rational &; + friend auto operator*=(Rational &a, Rational const &b) -> Rational &; + + friend auto operator/(Rational const &a, fixed_int b) -> Rational; + friend auto operator/(Rational const &a, Integer const &b) -> Rational; + friend auto operator/(Rational const &a, Rational const &b) -> Rational; + friend auto operator/(Rational &&a, fixed_int b) -> Rational; + friend auto operator/(Rational &&a, Integer const &b) -> Rational; + friend auto operator/(Rational &&a, Rational const &b) -> Rational; + friend auto operator/=(Rational &a, fixed_int b) -> Rational &; + friend auto operator/=(Rational &a, Integer const &b) -> Rational &; + friend auto operator/=(Rational &a, Rational const &b) -> Rational &; + + friend auto operator<(Rational const &a, fixed_int b) -> bool; + friend auto operator<(Rational const &a, Integer const &b) -> bool; + friend auto operator<(Rational const &a, Rational const &b) -> bool; + + friend auto operator<=(Rational const &a, fixed_int b) -> bool; + friend auto operator<=(Rational const &a, Integer const &b) -> bool; + friend auto operator<=(Rational const &a, Rational const &b) -> bool; + + friend auto operator>(Rational const &a, fixed_int b) -> bool; + friend auto operator>(Rational const &a, Integer const &b) -> bool; + friend auto operator>(Rational const &a, Rational const &b) -> bool; + + friend auto operator>=(Rational const &a, fixed_int b) -> bool; + friend auto operator>=(Rational const &a, Integer const &b) -> bool; + friend auto operator>=(Rational const &a, Rational const &b) -> bool; + + friend auto operator==(Rational const &a, fixed_int b) -> bool; + friend auto operator==(Rational const &a, Integer const &b) -> bool; + friend auto operator==(Rational const &a, Rational const &b) -> bool; + + friend auto operator!=(Rational const &a, fixed_int b) -> bool; + friend auto operator!=(Rational const &a, Integer const &b) -> bool; + friend auto operator!=(Rational const &a, Rational const &b) -> bool; + + friend auto operator<<(std::ostream &out, Rational const &a) -> std::ostream &; + + friend auto compare(Rational const &a, fixed_int b) -> int; + friend auto compare(Rational const &a, Integer const &b) -> int; + friend auto compare(Rational const &a, Rational const &b) -> int; + + public: Rational() noexcept; Rational(fixed_int val); Rational(Integer num, Integer den); @@ -171,23 +171,22 @@ public: Rational(std::string const &val, int radix); Rational(Rational const &a); Rational(Rational &&a) noexcept; - Rational &operator=(Rational const &a); - Rational &operator=(Rational &&a) noexcept; + auto operator=(Rational const &a) -> Rational &; + auto operator=(Rational &&a) noexcept -> Rational &; ~Rational() noexcept; - [[nodiscard]] Integer &num(); - [[nodiscard]] Integer const &num() const; - [[nodiscard]] Integer &den(); - [[nodiscard]] Integer const &den() const; - Rational &neg(); + [[nodiscard]] auto num() -> Integer &; + [[nodiscard]] auto num() const -> Integer const &; + [[nodiscard]] auto den() -> Integer &; + [[nodiscard]] auto den() const -> Integer const &; + auto neg() -> Rational &; void swap(Rational &x) noexcept; void canonicalize(); -private: + private: mutable mpq_t num_; }; - inline void mp_handle_error_(mp_result res) { if (res != MP_OK) { if (res == MP_MEMORY) { @@ -212,234 +211,176 @@ inline Integer::Integer() noexcept { // NOLINT mp_int_init(&num_); } -inline Integer::Integer(fixed_int val) -: Integer() { - mp_handle_error_(mp_int_set_value(&num_, val)); -} +inline Integer::Integer(fixed_int val) : Integer() { mp_handle_error_(mp_int_set_value(&num_, val)); } -inline Integer::Integer(char const *val, int radix) -: Integer() { +inline Integer::Integer(char const *val, int radix) : Integer() { mp_handle_error_(mp_int_read_string(&num_, radix, val)); } -inline Integer::Integer(std::string const &val, int radix) -: Integer(val.c_str(), radix) { } +inline Integer::Integer(std::string const &val, int radix) : Integer(val.c_str(), radix) {} -inline Integer::Integer(Integer const &a) -: Integer() { - mp_handle_error_(mp_int_copy(&a.num_, &num_)); -} +inline Integer::Integer(Integer const &a) : Integer() { mp_handle_error_(mp_int_copy(&a.num_, &num_)); } -inline Integer::Integer(Integer &&a) noexcept -: Integer() { - swap(a); -} +inline Integer::Integer(Integer &&a) noexcept : Integer() { swap(a); } -inline Integer &Integer::operator=(Integer const &a) { +inline auto Integer::operator=(Integer const &a) -> Integer & { mp_handle_error_(mp_int_copy(&a.num_, &num_)); return *this; } -inline Integer &Integer::operator=(Integer &&a) noexcept { +inline auto Integer::operator=(Integer &&a) noexcept -> Integer & { swap(a); return *this; } -inline Integer::~Integer() noexcept { - mp_int_clear(&num_); -} +inline Integer::~Integer() noexcept { mp_int_clear(&num_); } -inline void Integer::swap(Integer &x) noexcept { - mp_int_swap(&num_, &x.num_); -} +inline void Integer::swap(Integer &x) noexcept { mp_int_swap(&num_, &x.num_); } -inline Integer &Integer::divide(Integer const &a) { +inline auto Integer::divide(Integer const &a) -> Integer & { mp_int_div(&num_, &a.num_, &num_, nullptr); return *this; } -inline Integer &Integer::add_mul(Integer const &a, Integer const &b) & { - return *this += a * b; -} +inline auto Integer::add_mul(Integer const &a, Integer const &b) & -> Integer & { return *this += a * b; } -inline Integer Integer::add_mul(Integer const &a, Integer const &b) && { - return std::move(*this += a * b); -} +inline auto Integer::add_mul(Integer const &a, Integer const &b) && -> Integer { return std::move(*this += a * b); } -inline Integer &Integer::neg() { +inline auto Integer::neg() -> Integer & { mp_handle_error_(mp_int_neg(&num_, &num_)); return *this; } -inline mpz_t &Integer::impl() const { - return num_; -} +inline auto Integer::impl() const -> mpz_t & { return num_; } // addition -[[nodiscard]] inline Integer operator+(Integer const &a, fixed_int b) { +[[nodiscard]] inline auto operator+(Integer const &a, fixed_int b) -> Integer { Integer c; mp_handle_error_(mp_int_add_value(&a.num_, b, &c.num_)); return c; } -[[nodiscard]] inline Integer operator+(Integer const &a, Integer const &b) { +[[nodiscard]] inline auto operator+(Integer const &a, Integer const &b) -> Integer { Integer c; mp_handle_error_(mp_int_add(&a.num_, &b.num_, &c.num_)); return c; } -[[nodiscard]] inline Integer operator+(Integer &&a, fixed_int b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(Integer &&a, fixed_int b) -> Integer { return std::move(a += b); } -[[nodiscard]] inline Integer operator+(Integer &&a, Integer const &b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(Integer &&a, Integer const &b) -> Integer { return std::move(a += b); } -inline Integer &operator+=(Integer &a, fixed_int b) { +inline auto operator+=(Integer &a, fixed_int b) -> Integer & { mp_handle_error_(mp_int_add_value(&a.num_, b, &a.num_)); return a; } -inline Integer &operator+=(Integer &a, Integer const &b) { +inline auto operator+=(Integer &a, Integer const &b) -> Integer & { mp_handle_error_(mp_int_add(&a.num_, &b.num_, &a.num_)); return a; } // subtraction -[[nodiscard]] inline Integer operator-(Integer a) { +[[nodiscard]] inline auto operator-(Integer a) -> Integer { a.neg(); return a; } -[[nodiscard]] inline Integer operator-(Integer const &a, fixed_int b) { +[[nodiscard]] inline auto operator-(Integer const &a, fixed_int b) -> Integer { Integer c; mp_handle_error_(mp_int_sub_value(&a.num_, b, &c.num_)); return c; } -[[nodiscard]] inline Integer operator-(Integer const &a, Integer const &b) { +[[nodiscard]] inline auto operator-(Integer const &a, Integer const &b) -> Integer { Integer c; mp_handle_error_(mp_int_sub(&a.num_, &b.num_, &c.num_)); return c; } -[[nodiscard]] inline Integer operator-(Integer &&a, fixed_int b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(Integer &&a, fixed_int b) -> Integer { return std::move(a -= b); } -[[nodiscard]] inline Integer operator-(Integer &&a, Integer const &b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(Integer &&a, Integer const &b) -> Integer { return std::move(a -= b); } -inline Integer &operator-=(Integer &a, fixed_int b) { +inline auto operator-=(Integer &a, fixed_int b) -> Integer & { mp_handle_error_(mp_int_sub_value(&a.num_, b, &a.num_)); return a; } -inline Integer &operator-=(Integer &a, Integer const &b) { +inline auto operator-=(Integer &a, Integer const &b) -> Integer & { mp_handle_error_(mp_int_sub(&a.num_, &b.num_, &a.num_)); return a; } // multiplication -[[nodiscard]] inline Integer operator*(Integer const &a, fixed_int b) { +[[nodiscard]] inline auto operator*(Integer const &a, fixed_int b) -> Integer { Integer c; mp_handle_error_(mp_int_mul_value(&a.num_, b, &c.num_)); return c; } -[[nodiscard]] inline Integer operator*(Integer const &a, Integer const &b) { +[[nodiscard]] inline auto operator*(Integer const &a, Integer const &b) -> Integer { Integer c; mp_handle_error_(mp_int_mul(&a.num_, &b.num_, &c.num_)); return c; } -[[nodiscard]] inline Integer operator*(Integer &&a, fixed_int b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(Integer &&a, fixed_int b) -> Integer { return std::move(a *= b); } -[[nodiscard]] inline Integer operator*(Integer &&a, Integer const &b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(Integer &&a, Integer const &b) -> Integer { return std::move(a *= b); } -inline Integer &operator*=(Integer &a, fixed_int b) { +inline auto operator*=(Integer &a, fixed_int b) -> Integer & { mp_handle_error_(mp_int_mul_value(&a.num_, b, &a.num_)); return a; } -inline Integer &operator*=(Integer &a, Integer const &b) { +inline auto operator*=(Integer &a, Integer const &b) -> Integer & { mp_handle_error_(mp_int_mul(&a.num_, &b.num_, &a.num_)); return a; } // less than -[[nodiscard]] inline bool operator<(Integer const &a, fixed_int b) { - return compare(a, b) < 0; -} +[[nodiscard]] inline auto operator<(Integer const &a, fixed_int b) -> bool { return compare(a, b) < 0; } -[[nodiscard]] inline bool operator<(Integer const &a, Integer const &b) { - return compare(a, b) < 0; -} +[[nodiscard]] inline auto operator<(Integer const &a, Integer const &b) -> bool { return compare(a, b) < 0; } // less than or equal to -[[nodiscard]] inline bool operator<=(Integer const &a, fixed_int b) { - return compare(a, b) <= 0; -} +[[nodiscard]] inline auto operator<=(Integer const &a, fixed_int b) -> bool { return compare(a, b) <= 0; } -[[nodiscard]] inline bool operator<=(Integer const &a, Integer const &b) { - return compare(a, b) <= 0; -} +[[nodiscard]] inline auto operator<=(Integer const &a, Integer const &b) -> bool { return compare(a, b) <= 0; } // greater than -[[nodiscard]] inline bool operator>(Integer const &a, fixed_int b) { - return compare(a, b) > 0; -} +[[nodiscard]] inline auto operator>(Integer const &a, fixed_int b) -> bool { return compare(a, b) > 0; } -[[nodiscard]] inline bool operator>(Integer const &a, Integer const &b) { - return compare(a, b) > 0; -} +[[nodiscard]] inline auto operator>(Integer const &a, Integer const &b) -> bool { return compare(a, b) > 0; } // greater than or equal to -[[nodiscard]] inline bool operator>=(Integer const &a, fixed_int b) { - return compare(a, b) >= 0; -} +[[nodiscard]] inline auto operator>=(Integer const &a, fixed_int b) -> bool { return compare(a, b) >= 0; } -[[nodiscard]] inline bool operator>=(Integer const &a, Integer const &b) { - return compare(a, b) >= 0; -} +[[nodiscard]] inline auto operator>=(Integer const &a, Integer const &b) -> bool { return compare(a, b) >= 0; } // greater equal to +[[nodiscard]] inline auto operator==(Integer const &a, fixed_int b) -> bool { return compare(a, b) == 0; } -[[nodiscard]] inline bool operator==(Integer const &a, fixed_int b) { - return compare(a, b) == 0; -} - -[[nodiscard]] inline bool operator==(Integer const &a, Integer const &b) { - return compare(a, b) == 0; -} +[[nodiscard]] inline auto operator==(Integer const &a, Integer const &b) -> bool { return compare(a, b) == 0; } // not equal to -[[nodiscard]] inline bool operator!=(Integer const &a, fixed_int b) { - return compare(a, b) != 0; -} +[[nodiscard]] inline auto operator!=(Integer const &a, fixed_int b) -> bool { return compare(a, b) != 0; } -[[nodiscard]] inline bool operator!=(Integer const &a, Integer const &b) { - return compare(a, b) != 0; -} +[[nodiscard]] inline auto operator!=(Integer const &a, Integer const &b) -> bool { return compare(a, b) != 0; } // printing -inline std::ostream &operator<<(std::ostream &out, Integer const &a) { +inline auto operator<<(std::ostream &out, Integer const &a) -> std::ostream & { auto len = mp_int_string_len(&a.num_, BASE); std::unique_ptr buf{std::make_unique(len)}; // NOLINT mp_handle_error_(mp_int_to_string(&a.num_, BASE, buf.get(), len)); @@ -449,23 +390,21 @@ inline std::ostream &operator<<(std::ostream &out, Integer const &a) { // comparison -[[nodiscard]] inline int compare(Integer const &a, fixed_int b) { - return mp_int_compare_value(&a.num_, b); -} +[[nodiscard]] inline auto compare(Integer const &a, fixed_int b) -> int { return mp_int_compare_value(&a.num_, b); } -[[nodiscard]] inline int compare(Integer const &a, Integer const &b) { +[[nodiscard]] inline auto compare(Integer const &a, Integer const &b) -> int { return mp_int_compare(&a.num_, &b.num_); } // gcd -[[nodiscard]] inline Integer gcd(Integer const &a, Integer const &b) { +[[nodiscard]] inline auto gcd(Integer const &a, Integer const &b) -> Integer { Integer g; mp_int_gcd(&a.num_, &b.num_, &g.num_); return g; } -[[nodiscard]] inline std::tuple gcd_div(Integer const &a, Integer const &b) { +[[nodiscard]] inline auto gcd_div(Integer const &a, Integer const &b) -> std::tuple { std::tuple ret; mp_int_gcd(&a.num_, &b.num_, &std::get<0>(ret).num_); mp_int_div(&a.num_, &std::get<0>(ret).num_, &std::get<1>(ret).num_, nullptr); @@ -479,72 +418,57 @@ inline Rational::Rational() noexcept { // NOLINT mp_rat_init(&num_); } -inline Rational::Rational(fixed_int val) -: Rational() { - mp_handle_error_(mp_rat_set_value(&num_, val, 1)); -} +inline Rational::Rational(fixed_int val) : Rational() { mp_handle_error_(mp_rat_set_value(&num_, val, 1)); } -inline Rational::Rational(char const *val, int radix) -: Rational() { +inline Rational::Rational(char const *val, int radix) : Rational() { mp_handle_error_(mp_rat_read_string(&num_, radix, val)); } -inline Rational::Rational(std::string const &val, int radix) -: Rational(val.c_str(), radix) { -} +inline Rational::Rational(std::string const &val, int radix) : Rational(val.c_str(), radix) {} -inline Rational::Rational(Rational const &a) -: Rational() { - mp_handle_error_(mp_rat_copy(&a.num_, &num_)); -} +inline Rational::Rational(Rational const &a) : Rational() { mp_handle_error_(mp_rat_copy(&a.num_, &num_)); } -inline Rational::Rational(Integer num, Integer den) -: Rational() { +inline Rational::Rational(Integer num, Integer den) : Rational() { this->num() = std::move(num); this->den() = std::move(den); canonicalize(); } -inline Rational::Rational(Rational &&a) noexcept -: Rational() { - swap(a); -} +inline Rational::Rational(Rational &&a) noexcept : Rational() { swap(a); } -inline Rational &Rational::operator=(Rational const &a) { +inline auto Rational::operator=(Rational const &a) -> Rational & { mp_handle_error_(mp_rat_copy(&a.num_, &num_)); return *this; } -inline Rational &Rational::operator=(Rational &&a) noexcept { +inline auto Rational::operator=(Rational &&a) noexcept -> Rational & { swap(a); return *this; } -inline Rational::~Rational() noexcept { - mp_rat_clear(&num_); -} +inline Rational::~Rational() noexcept { mp_rat_clear(&num_); } -inline Integer &Rational::num() { +inline auto Rational::num() -> Integer & { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - return reinterpret_cast(num_.num); + return reinterpret_cast(num_.num); } -inline Integer const &Rational::num() const { +inline auto Rational::num() const -> Integer const & { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - return reinterpret_cast(num_.num); + return reinterpret_cast(num_.num); } -inline Integer &Rational::den() { +inline auto Rational::den() -> Integer & { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - return reinterpret_cast(num_.den); + return reinterpret_cast(num_.den); } -inline Integer const &Rational::den() const { +inline auto Rational::den() const -> Integer const & { // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - return reinterpret_cast(num_.den); + return reinterpret_cast(num_.den); } -inline Rational &Rational::neg() { +inline auto Rational::neg() -> Rational & { mp_handle_error_(mp_rat_neg(&num_, &num_)); return *this; } @@ -554,285 +478,206 @@ inline void Rational::swap(Rational &x) noexcept { mp_int_swap(&num_.den, &x.num_.den); } -inline void Rational::canonicalize() { - mp_handle_error_(mp_rat_reduce(&num_)); -} +inline void Rational::canonicalize() { mp_handle_error_(mp_rat_reduce(&num_)); } // addition -[[nodiscard]] inline Rational operator+(Rational const &a, fixed_int b) { - return a + Integer{b}; -} +[[nodiscard]] inline auto operator+(Rational const &a, fixed_int b) -> Rational { return a + Integer{b}; } -[[nodiscard]] inline Rational operator+(Rational const &a, Integer const &b) { +[[nodiscard]] inline auto operator+(Rational const &a, Integer const &b) -> Rational { Rational c; mp_handle_error_(mp_rat_add_int(&a.num_, &b.impl(), &c.num_)); return c; } -[[nodiscard]] inline Rational operator+(Rational const &a, Rational const &b) { +[[nodiscard]] inline auto operator+(Rational const &a, Rational const &b) -> Rational { Rational c; mp_handle_error_(mp_rat_add(&a.num_, &b.num_, &c.num_)); return c; } -[[nodiscard]] inline Rational operator+(Rational &&a, fixed_int b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(Rational &&a, fixed_int b) -> Rational { return std::move(a += b); } -[[nodiscard]] inline Rational operator+(Rational &&a, Integer const &b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(Rational &&a, Integer const &b) -> Rational { return std::move(a += b); } -[[nodiscard]] inline Rational operator+(Rational &&a, Rational const &b) { - return std::move(a += b); -} +[[nodiscard]] inline auto operator+(Rational &&a, Rational const &b) -> Rational { return std::move(a += b); } -inline Rational &operator+=(Rational &a, fixed_int b) { - return a += Integer{b}; -} +inline auto operator+=(Rational &a, fixed_int b) -> Rational & { return a += Integer{b}; } -inline Rational &operator+=(Rational &a, Integer const &b) { +inline auto operator+=(Rational &a, Integer const &b) -> Rational & { mp_handle_error_(mp_rat_add_int(&a.num_, &b.impl(), &a.num_)); return a; } -inline Rational &operator+=(Rational &a, Rational const &b) { +inline auto operator+=(Rational &a, Rational const &b) -> Rational & { mp_handle_error_(mp_rat_add(&a.num_, &b.num_, &a.num_)); return a; } // subtraction -[[nodiscard]] inline Rational operator-(Rational a) { +[[nodiscard]] inline auto operator-(Rational a) -> Rational { a.neg(); return a; } -[[nodiscard]] inline Rational operator-(Rational const &a, fixed_int b) { - return a - Integer{b}; -} +[[nodiscard]] inline auto operator-(Rational const &a, fixed_int b) -> Rational { return a - Integer{b}; } -[[nodiscard]] inline Rational operator-(Rational const &a, Integer const &b) { +[[nodiscard]] inline auto operator-(Rational const &a, Integer const &b) -> Rational { Rational c; mp_handle_error_(mp_rat_sub_int(&a.num_, &b.impl(), &c.num_)); return c; } -[[nodiscard]] inline Rational operator-(Rational const &a, Rational const &b) { +[[nodiscard]] inline auto operator-(Rational const &a, Rational const &b) -> Rational { Rational c; mp_handle_error_(mp_rat_sub(&a.num_, &b.num_, &c.num_)); return c; } -[[nodiscard]] inline Rational operator-(Rational &&a, fixed_int b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(Rational &&a, fixed_int b) -> Rational { return std::move(a -= b); } -[[nodiscard]] inline Rational operator-(Rational &&a, Integer const &b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(Rational &&a, Integer const &b) -> Rational { return std::move(a -= b); } -[[nodiscard]] inline Rational operator-(Rational &&a, Rational const &b) { - return std::move(a -= b); -} +[[nodiscard]] inline auto operator-(Rational &&a, Rational const &b) -> Rational { return std::move(a -= b); } -inline Rational &operator-=(Rational &a, fixed_int b) { - return a -= Integer{b}; -} +inline auto operator-=(Rational &a, fixed_int b) -> Rational & { return a -= Integer{b}; } -inline Rational &operator-=(Rational &a, Integer const &b) { +inline auto operator-=(Rational &a, Integer const &b) -> Rational & { mp_handle_error_(mp_rat_sub_int(&a.num_, &b.impl(), &a.num_)); return a; } -inline Rational &operator-=(Rational &a, Rational const &b) { +inline auto operator-=(Rational &a, Rational const &b) -> Rational & { mp_handle_error_(mp_rat_sub(&a.num_, &b.num_, &a.num_)); return a; } // multiplication -[[nodiscard]] inline Rational operator*(Rational const &a, fixed_int b) { - return a * Integer{b}; -} +[[nodiscard]] inline auto operator*(Rational const &a, fixed_int b) -> Rational { return a * Integer{b}; } -[[nodiscard]] inline Rational operator*(Rational const &a, Integer const &b) { +[[nodiscard]] inline auto operator*(Rational const &a, Integer const &b) -> Rational { Rational c; mp_handle_error_(mp_rat_mul_int(&a.num_, &b.impl(), &c.num_)); return c; } -[[nodiscard]] inline Rational operator*(Rational const &a, Rational const &b) { +[[nodiscard]] inline auto operator*(Rational const &a, Rational const &b) -> Rational { Rational c; mp_handle_error_(mp_rat_mul(&a.num_, &b.num_, &c.num_)); return c; } -[[nodiscard]] inline Rational operator*(Rational &&a, fixed_int b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(Rational &&a, fixed_int b) -> Rational { return std::move(a *= b); } -[[nodiscard]] inline Rational operator*(Rational &&a, Integer const &b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(Rational &&a, Integer const &b) -> Rational { return std::move(a *= b); } -[[nodiscard]] inline Rational operator*(Rational &&a, Rational const &b) { - return std::move(a *= b); -} +[[nodiscard]] inline auto operator*(Rational &&a, Rational const &b) -> Rational { return std::move(a *= b); } -inline Rational &operator*=(Rational &a, fixed_int b) { - return a *= Integer{b}; -} +inline auto operator*=(Rational &a, fixed_int b) -> Rational & { return a *= Integer{b}; } -inline Rational &operator*=(Rational &a, Integer const &b) { +inline auto operator*=(Rational &a, Integer const &b) -> Rational & { mp_handle_error_(mp_rat_mul_int(&a.num_, &b.impl(), &a.num_)); return a; } -inline Rational &operator*=(Rational &a, Rational const &b) { +inline auto operator*=(Rational &a, Rational const &b) -> Rational & { mp_handle_error_(mp_rat_mul(&a.num_, &b.num_, &a.num_)); return a; } // division -[[nodiscard]] inline Rational operator/(Rational const &a, fixed_int b) { - return a / Integer{b}; -} +[[nodiscard]] inline auto operator/(Rational const &a, fixed_int b) -> Rational { return a / Integer{b}; } -[[nodiscard]] inline Rational operator/(Rational const &a, Integer const &b) { +[[nodiscard]] inline auto operator/(Rational const &a, Integer const &b) -> Rational { Rational c; mp_handle_error_(mp_rat_div_int(&a.num_, &b.impl(), &c.num_)); return c; } -[[nodiscard]] inline Rational operator/(Rational const &a, Rational const &b) { +[[nodiscard]] inline auto operator/(Rational const &a, Rational const &b) -> Rational { Rational c; mp_handle_error_(mp_rat_div(&a.num_, &b.num_, &c.num_)); return c; } -[[nodiscard]] inline Rational operator/(Rational &&a, fixed_int b) { - return std::move(a /= b); -} +[[nodiscard]] inline auto operator/(Rational &&a, fixed_int b) -> Rational { return std::move(a /= b); } -[[nodiscard]] inline Rational operator/(Rational &&a, Integer const &b) { - return std::move(a /= b); -} +[[nodiscard]] inline auto operator/(Rational &&a, Integer const &b) -> Rational { return std::move(a /= b); } -[[nodiscard]] inline Rational operator/(Rational &&a, Rational const &b) { - return std::move(a /= b); -} +[[nodiscard]] inline auto operator/(Rational &&a, Rational const &b) -> Rational { return std::move(a /= b); } -inline Rational &operator/=(Rational &a, fixed_int b) { - return a /= Integer{b}; -} +inline auto operator/=(Rational &a, fixed_int b) -> Rational & { return a /= Integer{b}; } -inline Rational &operator/=(Rational &a, Integer const &b) { +inline auto operator/=(Rational &a, Integer const &b) -> Rational & { mp_handle_error_(mp_rat_div_int(&a.num_, &b.impl(), &a.num_)); return a; } -inline Rational &operator/=(Rational &a, Rational const &b) { +inline auto operator/=(Rational &a, Rational const &b) -> Rational & { mp_handle_error_(mp_rat_div(&a.num_, &b.num_, &a.num_)); return a; } // less than -[[nodiscard]] inline bool operator<(Rational const &a, fixed_int b) { - return compare(a, b) < 0; -} +[[nodiscard]] inline auto operator<(Rational const &a, fixed_int b) -> bool { return compare(a, b) < 0; } -[[nodiscard]] inline bool operator<(Rational const &a, Integer const &b) { - return compare(a, b) < 0; -} +[[nodiscard]] inline auto operator<(Rational const &a, Integer const &b) -> bool { return compare(a, b) < 0; } -[[nodiscard]] inline bool operator<(Rational const &a, Rational const &b) { - return compare(a, b) < 0; -} +[[nodiscard]] inline auto operator<(Rational const &a, Rational const &b) -> bool { return compare(a, b) < 0; } // less than or equal to -[[nodiscard]] inline bool operator<=(Rational const &a, fixed_int b) { - return compare(a, b) <= 0; -} +[[nodiscard]] inline auto operator<=(Rational const &a, fixed_int b) -> bool { return compare(a, b) <= 0; } -[[nodiscard]] inline bool operator<=(Rational const &a, Integer const &b) { - return compare(a, b) <= 0; -} +[[nodiscard]] inline auto operator<=(Rational const &a, Integer const &b) -> bool { return compare(a, b) <= 0; } -[[nodiscard]] inline bool operator<=(Rational const &a, Rational const &b) { - return compare(a, b) <= 0; -} +[[nodiscard]] inline auto operator<=(Rational const &a, Rational const &b) -> bool { return compare(a, b) <= 0; } // greater than -[[nodiscard]] inline bool operator>(Rational const &a, fixed_int b) { - return compare(a, b) > 0; -} +[[nodiscard]] inline auto operator>(Rational const &a, fixed_int b) -> bool { return compare(a, b) > 0; } -[[nodiscard]] inline bool operator>(Rational const &a, Integer const &b) { - return compare(a, b) > 0; -} +[[nodiscard]] inline auto operator>(Rational const &a, Integer const &b) -> bool { return compare(a, b) > 0; } -[[nodiscard]] inline bool operator>(Rational const &a, Rational const &b) { - return compare(a, b) > 0; -} +[[nodiscard]] inline auto operator>(Rational const &a, Rational const &b) -> bool { return compare(a, b) > 0; } // greater than or equal to -[[nodiscard]] inline bool operator>=(Rational const &a, fixed_int b) { - return compare(a, b) >= 0; -} +[[nodiscard]] inline auto operator>=(Rational const &a, fixed_int b) -> bool { return compare(a, b) >= 0; } -[[nodiscard]] inline bool operator>=(Rational const &a, Integer const &b) { - return compare(a, b) >= 0; -} +[[nodiscard]] inline auto operator>=(Rational const &a, Integer const &b) -> bool { return compare(a, b) >= 0; } -[[nodiscard]] inline bool operator>=(Rational const &a, Rational const &b) { - return compare(a, b) >= 0; -} +[[nodiscard]] inline auto operator>=(Rational const &a, Rational const &b) -> bool { return compare(a, b) >= 0; } // equal to -[[nodiscard]] inline bool operator==(Rational const &a, fixed_int b) { - return compare(a, b) == 0; -} +[[nodiscard]] inline auto operator==(Rational const &a, fixed_int b) -> bool { return compare(a, b) == 0; } -[[nodiscard]] inline bool operator==(Rational const &a, Integer const &b) { - return compare(a, b) == 0; -} +[[nodiscard]] inline auto operator==(Rational const &a, Integer const &b) -> bool { return compare(a, b) == 0; } -[[nodiscard]] inline bool operator==(Rational const &a, Rational const &b) { - return compare(a, b) == 0; -} +[[nodiscard]] inline auto operator==(Rational const &a, Rational const &b) -> bool { return compare(a, b) == 0; } // not equal to -[[nodiscard]] inline bool operator!=(Rational const &a, fixed_int b) { - return compare(a, b) != 0; -} +[[nodiscard]] inline auto operator!=(Rational const &a, fixed_int b) -> bool { return compare(a, b) != 0; } -[[nodiscard]] inline bool operator!=(Rational const &a, Integer const &b) { - return compare(a, b) != 0; -} +[[nodiscard]] inline auto operator!=(Rational const &a, Integer const &b) -> bool { return compare(a, b) != 0; } -[[nodiscard]] inline bool operator!=(Rational const &a, Rational const &b) { - return compare(a, b) != 0; -} +[[nodiscard]] inline auto operator!=(Rational const &a, Rational const &b) -> bool { return compare(a, b) != 0; } // printing -inline std::ostream &operator<<(std::ostream &out, Rational const &a) { +inline auto operator<<(std::ostream &out, Rational const &a) -> std::ostream & { if (mp_int_compare_value(mp_rat_denom_ref(&a.num_), 1) == 0) { auto len = mp_int_string_len(mp_rat_numer_ref(&a.num_), BASE); auto buf = std::make_unique(len); // NOLINT mp_handle_error_(mp_int_to_string(mp_rat_numer_ref(&a.num_), BASE, buf.get(), len)); out << buf.get(); - } - else { + } else { auto len = mp_rat_string_len(&a.num_, BASE); auto buf = std::make_unique(len); // NOLINT mp_handle_error_(mp_rat_to_string(&a.num_, BASE, buf.get(), len)); @@ -843,16 +688,14 @@ inline std::ostream &operator<<(std::ostream &out, Rational const &a) { // comparison -[[nodiscard]] inline int compare(Rational const &a, fixed_int b) { - return mp_rat_compare_value(&a.num_, b, 1); -} +[[nodiscard]] inline auto compare(Rational const &a, fixed_int b) -> int { return mp_rat_compare_value(&a.num_, b, 1); } -[[nodiscard]] inline int compare(Rational const &a, Integer const &b) { +[[nodiscard]] inline auto compare(Rational const &a, Integer const &b) -> int { // Note: this is not good. return compare(a, Rational{b, Integer{1}}); } -[[nodiscard]] inline int compare(Rational const &a, Rational const &b) { +[[nodiscard]] inline auto compare(Rational const &a, Rational const &b) -> int { return mp_rat_compare(&a.num_, &b.num_); } diff --git a/libclingo-lpx/src/parsing.cc b/libclingo-lpx/src/parsing.cc index 6b13c6e..37963e3 100644 --- a/libclingo-lpx/src/parsing.cc +++ b/libclingo-lpx/src/parsing.cc @@ -12,27 +12,23 @@ namespace { -template -[[nodiscard]] T throw_syntax_error(char const *message="Invalid Syntax") { +template [[nodiscard]] auto throw_syntax_error(char const *message = "Invalid Syntax") -> T { throw std::runtime_error(message); } -void check_syntax(bool condition, char const *message="Invalid Syntax") { +void check_syntax(bool condition, char const *message = "Invalid Syntax") { if (!condition) { throw_syntax_error(message); } } -[[nodiscard]] bool match(Clingo::TheoryTerm const &term, char const *name, size_t arity) { - return (term.type() == Clingo::TheoryTermType::Symbol && - std::strcmp(term.name(), name) == 0 && - arity == 0) || - (term.type() == Clingo::TheoryTermType::Function && - std::strcmp(term.name(), name) == 0 && - term.arguments().size() == arity); +[[nodiscard]] auto match(Clingo::TheoryTerm const &term, char const *name, size_t arity) -> bool { + return (term.type() == Clingo::TheoryTermType::Symbol && std::strcmp(term.name(), name) == 0 && arity == 0) || + (term.type() == Clingo::TheoryTermType::Function && std::strcmp(term.name(), name) == 0 && + term.arguments().size() == arity); } -bool is_string(Clingo::TheoryTerm const &term) { +auto is_string(Clingo::TheoryTerm const &term) -> bool { if (term.type() != Clingo::TheoryTermType::Symbol) { return false; } @@ -42,7 +38,7 @@ bool is_string(Clingo::TheoryTerm const &term) { return len >= 2 && name[0] == '"' && name[len - 1] == '"'; } -[[nodiscard]] Clingo::Symbol evaluate(Clingo::TheoryTerm const &term) { +[[nodiscard]] auto evaluate(Clingo::TheoryTerm const &term) -> Clingo::Symbol { if (is_string(term)) { char const *name = term.name(); size_t len = std::strlen(term.name()); @@ -83,21 +79,15 @@ bool is_string(Clingo::TheoryTerm const &term) { return throw_syntax_error(); } -[[nodiscard]] Clingo::Symbol evaluate_var(Clingo::TheoryTerm const &term) { - check_syntax( - !match(term, "-", 1) && - !match(term, "..", 2) && - !match(term, "*", 2) && - !match(term, "/", 2)); - check_syntax( - term.type() == Clingo::TheoryTermType::Tuple || - term.type() == Clingo::TheoryTermType::Function || - term.type() == Clingo::TheoryTermType::Symbol); +[[nodiscard]] auto evaluate_var(Clingo::TheoryTerm const &term) -> Clingo::Symbol { + check_syntax(!match(term, "-", 1) && !match(term, "..", 2) && !match(term, "*", 2) && !match(term, "/", 2)); + check_syntax(term.type() == Clingo::TheoryTermType::Tuple || term.type() == Clingo::TheoryTermType::Function || + term.type() == Clingo::TheoryTermType::Symbol); return evaluate(term); } -[[nodiscard]] Rational evaluate_num(Clingo::TheoryTerm const &term) { +[[nodiscard]] auto evaluate_num(Clingo::TheoryTerm const &term) -> Rational { if (is_string(term)) { auto const *name = term.name(); std::regex const rgx{"(-)?([0-9]+)(\\.([0-9]+))?"}; @@ -109,7 +99,8 @@ bool is_string(Clingo::TheoryTerm const &term) { auto const *ib = match[4].first; auto const *it = match[4].second; // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic) - for (; it != ib && *(it - 1) == '0'; --it) { } + for (; it != ib && *(it - 1) == '0'; --it) { + } a.append(ib, it); a.append("/1"); a.append(it - ib, '0'); @@ -140,7 +131,7 @@ bool is_string(Clingo::TheoryTerm const &term) { return throw_syntax_error(); } -[[nodiscard]] Relation evaluate_cmp(char const *rel) { +[[nodiscard]] auto evaluate_cmp(char const *rel) -> Relation { if (std::strcmp(rel, "<=") == 0) { return Relation::LessEqual; } @@ -159,26 +150,22 @@ bool is_string(Clingo::TheoryTerm const &term) { return throw_syntax_error(); } -[[nodiscard]] std::vector evaluate_terms(LitMapper const &mapper, VarMap &var_map, std::vector &iqs, Clingo::TheoryElementSpan elements) { +[[nodiscard]] auto evaluate_terms(LitMapper const &mapper, VarMap &var_map, std::vector &iqs, + Clingo::TheoryElementSpan elements) -> std::vector { std::vector lhs; for (auto &&elem : elements) { check_syntax(elem.tuple().size() == 1); auto &&term = elem.tuple().front(); if (match(term, "-", 1)) { - lhs.emplace_back(Term{ - -1, - evaluate_var(term.arguments().back())}); - } - else if (match(term, "*", 2)) { - lhs.emplace_back(Term{ - evaluate_num(term.arguments().front()), - evaluate_var(term.arguments().back())}); - } - else { + lhs.emplace_back(Term{-1, evaluate_var(term.arguments().back())}); + } else if (match(term, "*", 2)) { + lhs.emplace_back(Term{evaluate_num(term.arguments().front()), evaluate_var(term.arguments().back())}); + } else { lhs.emplace_back(Term{1, evaluate_var(term)}); } if (!elem.condition().empty()) { - auto res = var_map.try_emplace(std::make_pair(lhs.back().var, elem.condition_id()), Clingo::Number(safe_cast(var_map.size()))); + auto res = var_map.try_emplace(std::make_pair(lhs.back().var, elem.condition_id()), + Clingo::Number(safe_cast(var_map.size()))); if (res.second) { auto lit = mapper(elem.condition_id()); iqs.emplace_back(Inequality{{{1, res.first->second}}, 0, Relation::Equal, -lit}); @@ -190,7 +177,7 @@ bool is_string(Clingo::TheoryTerm const &term) { return lhs; } -void simplify(std::unordered_map &cos, std::vector &terms) { +void simplify(std::unordered_map &cos, std::vector &terms) { auto ib = terms.begin(); auto ie = terms.end(); @@ -204,15 +191,14 @@ void simplify(std::unordered_map &cos, std::vector }); // remove terms with zero coeffcients - terms.erase(std::remove_if(ib, ie, [](Term const &term) { - return term.co == 0; - }), ie); + terms.erase(std::remove_if(ib, ie, [](Term const &term) { return term.co == 0; }), ie); } } // namespace -void evaluate_theory(Clingo::TheoryAtoms const &theory, LitMapper const &mapper, VarMap &var_map, std::vector &iqs, std::vector &objective) { - std::unordered_map cos; +void evaluate_theory(Clingo::TheoryAtoms const &theory, LitMapper const &mapper, VarMap &var_map, + std::vector &iqs, std::vector &objective) { + std::unordered_map cos; for (auto &&atom : theory) { if (match(atom.term(), "dom", 0)) { check_syntax(atom.elements().size() == 1); @@ -224,22 +210,19 @@ void evaluate_theory(Clingo::TheoryAtoms const &theory, LitMapper const &mapper, auto var = evaluate_var(atom.guard().second); auto lit = mapper(atom.literal()); iqs.emplace_back(Inequality{{{1, var}}, evaluate_num(term.arguments().back()), Relation::LessEqual, lit}); - iqs.emplace_back(Inequality{{{1, var}}, evaluate_num(term.arguments().front()), Relation::GreaterEqual, lit}); - } - else if (match(atom.term(), "sum", 0)) { + iqs.emplace_back( + Inequality{{{1, var}}, evaluate_num(term.arguments().front()), Relation::GreaterEqual, lit}); + } else if (match(atom.term(), "sum", 0)) { check_syntax(atom.has_guard(), "&sum constraints need guards"); auto lhs = evaluate_terms(mapper, var_map, iqs, atom.elements()); auto lit = mapper(atom.literal()); simplify(cos, lhs); - iqs.emplace_back(Inequality{std::move(lhs), - evaluate_num(atom.guard().second), - evaluate_cmp(atom.guard().first), - lit}); - } - else if (match(atom.term(), "minimize", 0) || match(atom.term(), "maximize", 0)) { + iqs.emplace_back( + Inequality{std::move(lhs), evaluate_num(atom.guard().second), evaluate_cmp(atom.guard().first), lit}); + } else if (match(atom.term(), "minimize", 0) || match(atom.term(), "maximize", 0)) { auto lhs = evaluate_terms(mapper, var_map, iqs, atom.elements()); if (match(atom.term(), "minimize", 0)) { - for (auto &term: lhs) { + for (auto &term : lhs) { term.co.neg(); } } diff --git a/libclingo-lpx/src/parsing.hh b/libclingo-lpx/src/parsing.hh index d12776c..0d56d29 100644 --- a/libclingo-lpx/src/parsing.hh +++ b/libclingo-lpx/src/parsing.hh @@ -47,4 +47,5 @@ constexpr char const *THEORY_Q = R"( using VarMap = std::map, Clingo::Symbol>; using LitMapper = std::function; -void evaluate_theory(Clingo::TheoryAtoms const &theory, LitMapper const &mapper, VarMap &var_map, std::vector &iqs, std::vector &objective); +void evaluate_theory(Clingo::TheoryAtoms const &theory, LitMapper const &mapper, VarMap &var_map, + std::vector &iqs, std::vector &objective); diff --git a/libclingo-lpx/src/problem.cc b/libclingo-lpx/src/problem.cc index 8c62c32..1f8eb3a 100644 --- a/libclingo-lpx/src/problem.cc +++ b/libclingo-lpx/src/problem.cc @@ -1,6 +1,6 @@ #include "problem.hh" -Relation invert(Relation rel) { +auto invert(Relation rel) -> Relation { switch (rel) { case Relation::LessEqual: { return Relation::GreaterEqual; @@ -21,7 +21,7 @@ Relation invert(Relation rel) { return Relation::Equal; } -std::ostream &operator<<(std::ostream &out, Relation const &rel) { +auto operator<<(std::ostream &out, Relation const &rel) -> std::ostream & { switch (rel) { case Relation::LessEqual: { out << "<="; @@ -47,24 +47,22 @@ std::ostream &operator<<(std::ostream &out, Relation const &rel) { return out; } -std::ostream &operator<<(std::ostream &out, Term const &term) { +auto operator<<(std::ostream &out, Term const &term) -> std::ostream & { if (term.co == -1) { out << "-"; - } - else if (term.co != 1) { + } else if (term.co != 1) { out << term.co << "*"; } out << term.var; return out; } -std::ostream &operator<<(std::ostream &out, Inequality const &x) { +auto operator<<(std::ostream &out, Inequality const &x) -> std::ostream & { bool plus{false}; for (auto const &term : x.lhs) { if (plus) { out << " + "; - } - else { + } else { plus = true; } out << term; diff --git a/libclingo-lpx/src/problem.hh b/libclingo-lpx/src/problem.hh index 61dfd4b..c331f2b 100644 --- a/libclingo-lpx/src/problem.hh +++ b/libclingo-lpx/src/problem.hh @@ -12,16 +12,16 @@ enum class Relation { Greater = 4, }; -[[nodiscard]] Relation invert(Relation rel); +[[nodiscard]] auto invert(Relation rel) -> Relation; -std::ostream &operator<<(std::ostream &out, Relation const &rel); +auto operator<<(std::ostream &out, Relation const &rel) -> std::ostream &; struct Term { Rational co; Clingo::Symbol var; }; -std::ostream &operator<<(std::ostream &out, Term const &term); +auto operator<<(std::ostream &out, Term const &term) -> std::ostream &; struct Inequality { std::vector lhs; @@ -30,4 +30,4 @@ struct Inequality { Clingo::literal_t lit; }; -std::ostream &operator<<(std::ostream &out, Inequality const &x); +auto operator<<(std::ostream &out, Inequality const &x) -> std::ostream &; diff --git a/libclingo-lpx/src/solving.cc b/libclingo-lpx/src/solving.cc index 38b9bd8..77c5f07 100644 --- a/libclingo-lpx/src/solving.cc +++ b/libclingo-lpx/src/solving.cc @@ -19,27 +19,25 @@ namespace { -RationalQ as_value(RationalQ const &a, RationalQ *b) { +auto as_value(RationalQ const &a, RationalQ *b) -> RationalQ { static_cast(b); return a; } -Rational as_value(RationalQ const &a, Rational *b) { +auto as_value(RationalQ const &a, Rational *b) -> Rational { static_cast(b); return a.as_rational(); } } // namespace -template -void ObjectiveState::reset() { +template void ObjectiveState::reset() { value_ = Value{}; generation_ = 0; bounded_ = true; } -template -void ObjectiveState::update(std::pair value) { +template void ObjectiveState::update(std::pair value) { #ifndef CLINGOLPX_NO_SHARED_MUTEX std::unique_lock lock{mutex_}; #else @@ -52,8 +50,8 @@ void ObjectiveState::update(std::pair value) { } } -template -std::optional> ObjectiveState::value(size_t &generation) { +template +auto ObjectiveState::value(size_t &generation) -> std::optional> { #ifndef CLINGOLPX_NO_SHARED_MUTEX std::shared_lock lock{mutex_}; #else @@ -66,8 +64,7 @@ std::optional> ObjectiveState::value(size_t &gener return std::nullopt; } -template -typename Solver::BoundRelation bound_rel(Relation rel) { +template auto bound_rel(Relation rel) -> typename Solver::BoundRelation { switch (rel) { case Relation::Less: case Relation::LessEqual: { @@ -84,18 +81,15 @@ typename Solver::BoundRelation bound_rel(Relation rel) { return Solver::BoundRelation::Equal; } -template -Value bound_val(Rational x, Relation rel); +template auto bound_val(Rational x, Relation rel) -> Value; -template<> -Rational bound_val(Rational x, Relation rel) { +template <> auto bound_val(Rational x, Relation rel) -> Rational { static_cast(rel); assert(rel != Relation::Less && rel != Relation::Greater); return x; } -template<> -RationalQ bound_val(Rational x, Relation rel) { +template <> auto bound_val(Rational x, Relation rel) -> RationalQ { switch (rel) { case Relation::Less: { return RationalQ{std::move(x), -1}; @@ -112,11 +106,8 @@ RationalQ bound_val(Rational x, Relation rel) { return RationalQ{std::move(x)}; } -template -struct Solver::Prepare { - Prepare(Solver &slv, SymbolMap const &map) - : slv{slv} - , map{map} { +template struct Solver::Prepare { + Prepare(Solver &slv, SymbolMap const &map) : slv{slv}, map{map} { slv.variables_.resize(map.size()); slv.n_non_basic_ = map.size(); for (index_t i = 0; i != slv.n_non_basic_; ++i) { @@ -125,13 +116,13 @@ struct Solver::Prepare { } } - index_t get_non_basic(Clingo::Symbol var) { + auto get_non_basic(Clingo::Symbol var) -> index_t { auto jt = map.find(var); assert(jt != map.end()); return slv.variables_[jt->second].reverse_index; } - index_t add_basic() { + auto add_basic() -> index_t { auto index = slv.variables_.size(); slv.variables_.emplace_back(); slv.variables_.back().index = index; @@ -139,7 +130,7 @@ struct Solver::Prepare { return slv.n_basic_++; } - std::vector> add_row(std::vector const &x) { + auto add_row(std::vector const &x) -> std::vector> { std::vector> row; row.reserve(x.size()); @@ -155,8 +146,7 @@ struct Solver::Prepare { SymbolMap const ↦ }; -template -bool Solver::Solver::Bound::compare(Value const &value) const { +template auto Solver::Solver::Bound::compare(Value const &value) const -> bool { switch (rel) { case BoundRelation::Equal: { return value == this->value; @@ -171,8 +161,7 @@ bool Solver::Solver::Bound::compare(Value const &value) const { return value >= this->value; } -template -bool Solver::Solver::Bound::conflicts(Bound const &other) const { +template auto Solver::Solver::Bound::conflicts(Bound const &other) const -> bool { switch (rel) { case BoundRelation::Equal: { return other.rel == BoundRelation::Equal ? value != other.value : other.conflicts(*this); @@ -187,8 +176,8 @@ bool Solver::Solver::Bound::conflicts(Bound const &other) const { return value >= this->value; } -template -bool Solver::Variable::update_upper(Solver &s, Clingo::Assignment ass, Bound const &bound) { +template +auto Solver::Variable::update_upper(Solver &s, Clingo::Assignment ass, Bound const &bound) -> bool { if (!has_upper() || bound.value < upper()) { if (!has_upper() || ass.level(upper_bound->lit) < ass.decision_level()) { s.bound_trail_.emplace_back(bound.variable, BoundRelation::LessEqual, upper_bound); @@ -198,14 +187,13 @@ bool Solver::Variable::update_upper(Solver &s, Clingo::Assignment ass, Bo return !has_lower() || lower() <= upper(); } -template -bool Solver::Variable::update_lower(Solver &s, Clingo::Assignment ass, Bound const &bound) { +template +auto Solver::Variable::update_lower(Solver &s, Clingo::Assignment ass, Bound const &bound) -> bool { if (!has_lower() || bound.value > lower()) { if (!has_lower() || ass.level(lower_bound->lit) < ass.decision_level()) { if (upper_bound != &bound) { s.bound_trail_.emplace_back(bound.variable, BoundRelation::GreaterEqual, lower_bound); - } - else { + } else { // Note: this assumes that update_lower is called right after update_upper for the same bound std::get<1>(s.bound_trail_.back()) = BoundRelation::Equal; } @@ -215,8 +203,8 @@ bool Solver::Variable::update_lower(Solver &s, Clingo::Assignment ass, Bo return !has_upper() || lower() <= upper(); } -template -bool Solver::Variable::update(Solver &s, Clingo::Assignment ass, Bound const &bound) { +template +auto Solver::Variable::update(Solver &s, Clingo::Assignment ass, Bound const &bound) -> bool { switch (bound.rel) { case BoundRelation::LessEqual: { return update_upper(s, ass, bound); @@ -231,8 +219,7 @@ bool Solver::Variable::update(Solver &s, Clingo::Assignment ass, Bound co return update_upper(s, ass, bound) && update_lower(s, ass, bound); } -template -void Solver::Variable::set_value(Solver &s, index_t lvl, Value const &val, bool add) { +template void Solver::Variable::set_value(Solver &s, index_t lvl, Value const &val, bool add) { // We can always assume that the assignment on a previous level was satisfying. // Thus, we simply store the old values to be able to restore them when backtracking. if (lvl != level) { @@ -241,39 +228,30 @@ void Solver::Variable::set_value(Solver &s, index_t lvl, Value const &val } if (add) { value += val; - } - else { + } else { value = val; } } -template -bool Solver::Variable::has_conflict() const { +template auto Solver::Variable::has_conflict() const -> bool { return (has_lower() && value < lower()) || (has_upper() && value > upper()); } -void Statistics::reset() { - *this = {}; -} +void Statistics::reset() { *this = {}; } -template -Solver::Solver(Options const &options) -: options_{options} { } +template Solver::Solver(Options const &options) : options_{options} {} -template -typename Solver::Variable &Solver::basic_(index_t i) { +template auto Solver::basic_(index_t i) -> typename Solver::Variable & { assert(i < n_basic_); return variables_[variables_[i + n_non_basic_].index]; } -template -typename Solver::Variable &Solver::non_basic_(index_t j) { +template auto Solver::non_basic_(index_t j) -> typename Solver::Variable & { assert(j < n_non_basic_); return variables_[variables_[j].index]; } -template -void Solver::enqueue_(index_t i) { +template void Solver::enqueue_(index_t i) { assert(i < n_basic_); auto ii = variables_[i + n_non_basic_].index; auto &xi = variables_[ii]; @@ -288,21 +266,19 @@ void Solver::enqueue_(index_t i) { } } -template -Value Solver::get_value(index_t i) const { - return variables_[i].value; -} +template auto Solver::get_value(index_t i) const -> Value { return variables_[i].value; } -template -std::optional> Solver::get_objective() const { +template auto Solver::get_objective() const -> std::optional> { if (objective_) { return std::make_pair(variables_[objective_.var].value, objective_.bounded); } return std::nullopt; } -template -bool Solver::prepare(Clingo::PropagateInit &init, SymbolMap const &symbols, std::vector const &inequalities, std::vector const &objective, bool master) { +template +auto Solver::prepare(Clingo::PropagateInit &init, SymbolMap const &symbols, + std::vector const &inequalities, std::vector const &objective, + bool master) -> bool { auto ass = init.assignment(); Prepare prep{*this, symbols}; @@ -356,20 +332,14 @@ bool Solver::prepare(Clingo::PropagateInit &init, SymbolMap const &symbol else if (row.size() == 1) { auto const &[j, v] = row.front(); auto rel = v < 0 ? invert(x.rel) : x.rel; - bounds_.emplace(x.lit, Bound{ - bound_val(x.rhs / v, rel), - variables_[j].index, - x.lit, - bound_rel(rel)}); + bounds_.emplace(x.lit, + Bound{bound_val(x.rhs / v, rel), variables_[j].index, x.lit, bound_rel(rel)}); } // add an inequality else { auto i = prep.add_basic(); - bounds_.emplace(x.lit, Bound{ - bound_val(x.rhs, x.rel), - static_cast(variables_.size() - 1), - x.lit, - bound_rel(x.rel)}); + bounds_.emplace(x.lit, Bound{bound_val(x.rhs, x.rel), static_cast(variables_.size() - 1), + x.lit, bound_rel(x.rel)}); for (auto const &[j, v] : row) { tableau_.set(i, j, v); } @@ -429,8 +399,7 @@ bool Solver::prepare(Clingo::PropagateInit &init, SymbolMap const &symbol return true; } -template -void Solver::debug_() { +template void Solver::debug_() { std::cerr << "tableau:" << std::endl; tableau_.debug(" "); if (objective_) { @@ -444,15 +413,13 @@ void Solver::debug_() { std::cerr << " y_" << i << " = " << x_i.value << " for "; if (x_i.has_lower()) { std::cerr << x_i.lower(); - } - else { + } else { std::cerr << "#inf"; } std::cerr << " <= y_" << i << " <= "; if (x_i.has_upper()) { std::cerr << x_i.upper(); - } - else { + } else { std::cerr << "#sup"; } std::cerr << std::endl; @@ -463,23 +430,20 @@ void Solver::debug_() { std::cerr << " x_" << i << " = " << x_i.value << " for "; if (x_i.has_lower()) { std::cerr << x_i.lower(); - } - else { + } else { std::cerr << "#inf"; } std::cerr << " <= x_" << i << " <= "; if (x_i.has_upper()) { std::cerr << x_i.upper(); - } - else { + } else { std::cerr << "#sup"; } std::cerr << std::endl; } } -template -void Solver::optimize() { +template void Solver::optimize() { assert(!objective_ || variables_[objective_.var].reverse_index >= n_non_basic_); // First, we select an entering variable x_e among the non-basic variables // corresponding to a non-zero coefficient a_ze in the objective function @@ -578,8 +542,7 @@ void Solver::optimize() { auto &y_i = basic_(i); bool pos_a_ie = ((a_ie > 0) == (d_i > 0)); bool increase = pos_a_ie == pos_a_ze; - if (increase ? !y_i.has_upper() - : !y_i.has_lower()) { + if (increase ? !y_i.has_upper() : !y_i.has_lower()) { return; } auto ii = variables_[i + n_non_basic_].index; @@ -587,8 +550,7 @@ void Solver::optimize() { Value const &v_i = increase ? y_i.upper() : y_i.lower(); // we compute the updated value of x_e (see Solver::pivot_) Value v = x_e.value + (v_i - y_i.value) / a_ie * d_i; - if (pos_a_ze ? x_e.has_upper() && v >= x_e.upper() - : x_e.has_lower() && v <= x_e.lower()) { + if (pos_a_ze ? x_e.has_upper() && v >= x_e.upper() : x_e.has_lower() && v <= x_e.lower()) { return; } if (bound_l == nullptr || (pos_a_ze ? v < v_e : v > v_e) || (ii < ll && v == v_e)) { @@ -605,40 +567,34 @@ void Solver::optimize() { if (bound_l != nullptr) { auto l = variables_[ll].reverse_index - n_non_basic_; pivot_(level, l, e, *bound_l); - } - else { + } else { // variable x_e is unbounded - if (pos_a_ze ? !x_e.has_upper() - : !x_e.has_lower()) { + if (pos_a_ze ? !x_e.has_upper() : !x_e.has_lower()) { assert_extra(check_solution_()); objective_.bounded = false; return; } // increase/decrease x_e - update_(level, e, pos_a_ze ? x_e.upper() - : x_e.lower()); + update_(level, e, pos_a_ze ? x_e.upper() : x_e.lower()); } } } -template -void Solver::store_sat_assignment() { +template void Solver::store_sat_assignment() { for (auto &[level, index, number] : assignment_trail_) { variables_[index].level = 0; } for (auto it = trail_offset_.rbegin(), ie = trail_offset_.rend(); it != ie; ++it) { if (it->assignment > 0) { it->assignment = 0; - } - else { + } else { break; } } assignment_trail_.clear(); } -template -bool Solver::update_bound_(Clingo::PropagateControl &ctl, Bound const &bound) { +template auto Solver::update_bound_(Clingo::PropagateControl &ctl, Bound const &bound) -> bool { auto ass = ctl.assignment(); auto &x = variables_[bound.variable]; if (!x.update(*this, ass, bound)) { @@ -651,36 +607,29 @@ bool Solver::update_bound_(Clingo::PropagateControl &ctl, Bound const &bo if (x.reverse_index < n_non_basic_) { if (x.has_lower() && x.value < x.lower()) { update_(ass.decision_level(), x.reverse_index, x.lower()); - } - else if (x.has_upper() && x.value > x.upper()) { + } else if (x.has_upper() && x.value > x.upper()) { update_(ass.decision_level(), x.reverse_index, x.upper()); } - } - else { + } else { enqueue_(x.reverse_index - n_non_basic_); } return true; } -template -bool Solver::assert_bound_(Clingo::PropagateControl &ctl, Value value) { +template auto Solver::assert_bound_(Clingo::PropagateControl &ctl, Value value) -> bool { // Adds a new bound associated with a new literal that is made true by a // unit clause. This ensures that the solver takes care of backtracking and // reasserting the literal. auto lit = ctl.add_literal(); ctl.add_watch(lit); - bounds_.emplace(lit, Bound{ - std::move(value), - objective_.bound_var, - lit, - BoundRelation::GreaterEqual}); + bounds_.emplace(lit, Bound{std::move(value), objective_.bound_var, lit, BoundRelation::GreaterEqual}); conflict_clause_.clear(); conflict_clause_.emplace_back(lit); return ctl.add_clause(conflict_clause_) && ctl.propagate(); } -template -bool Solver::integrate_objective(Clingo::PropagateControl &ctl, ObjectiveState &state) { +template +auto Solver::integrate_objective(Clingo::PropagateControl &ctl, ObjectiveState &state) -> bool { // Here we discard bounded solutions by asserting that the objective value // is greater than the current bound + an epsilon value taken from the // configuration. @@ -700,11 +649,11 @@ bool Solver::integrate_objective(Clingo::PropagateControl &ctl, Objective objective_.discard_bounded = true; return true; } - return assert_bound_(ctl, std::move(value->first) + as_value(*options_.global_objective, static_cast(nullptr))); + return assert_bound_(ctl, + std::move(value->first) + as_value(*options_.global_objective, static_cast(nullptr))); } -template -bool Solver::discard_bounded(Clingo::PropagateControl &ctl) { +template auto Solver::discard_bounded(Clingo::PropagateControl &ctl) -> bool { // Here we discard bounded solutions by asserting that the objective // is greater than the current optimal objective. if (!objective_ || !options_.global_objective.has_value() || !objective_.bounded || !objective_.discard_bounded) { @@ -713,8 +662,7 @@ bool Solver::discard_bounded(Clingo::PropagateControl &ctl) { return assert_bound_(ctl, variables_[objective_.var].value + 1); } -template -bool Solver::solve(Clingo::PropagateControl &ctl, Clingo::LiteralSpan lits) { +template auto Solver::solve(Clingo::PropagateControl &ctl, Clingo::LiteralSpan lits) -> bool { index_t i{0}; index_t j{0}; Value const *v{nullptr}; @@ -723,10 +671,8 @@ bool Solver::solve(Clingo::PropagateControl &ctl, Clingo::LiteralSpan lit auto level = ass.decision_level(); if (trail_offset_.empty() || trail_offset_.back().level < level) { - trail_offset_.emplace_back(TrailOffset{ - level, - static_cast(bound_trail_.size()), - static_cast(assignment_trail_.size())}); + trail_offset_.emplace_back(TrailOffset{level, static_cast(bound_trail_.size()), + static_cast(assignment_trail_.size())}); } for (auto lit : lits) { @@ -763,8 +709,7 @@ bool Solver::solve(Clingo::PropagateControl &ctl, Clingo::LiteralSpan lit } } -template -bool Solver::propagate_(Clingo::PropagateControl &ctl) { +template auto Solver::propagate_(Clingo::PropagateControl &ctl) -> bool { // In principle we could also propgate more bounds (see clingcon). This // would very likely be too expensive. // @@ -786,7 +731,7 @@ bool Solver::propagate_(Clingo::PropagateControl &ctl) { std::optional lower = Value{0}; std::optional upper = Value{0}; // check if a constraint provides a bound - tableau_.update_row(i, [&,this](index_t j, Integer const &a_ij, Integer const &d_i) { + tableau_.update_row(i, [&, this](index_t j, Integer const &a_ij, Integer const &d_i) { auto &x_j = non_basic_(j); bool pos_a_ij = (a_ij > 0) == (d_i > 0); if (pos_a_ij ? !x_j.has_lower() : !x_j.has_upper()) { @@ -802,7 +747,7 @@ bool Solver::propagate_(Clingo::PropagateControl &ctl) { lower_clause.clear(); upper_clause.clear(); // compute the bound - tableau_.update_row(i, [&,this](index_t j, Integer const &a_ij, Integer const &d_i) { + tableau_.update_row(i, [&, this](index_t j, Integer const &a_ij, Integer const &d_i) { auto &x_j = non_basic_(j); auto update_lower = [&](std::vector &clause, std::optional &bound) { if (bound.has_value() && x_j.has_lower()) { @@ -819,8 +764,7 @@ bool Solver::propagate_(Clingo::PropagateControl &ctl) { if ((a_ij > 0) == (d_i > 0)) { update_lower(lower_clause, lower); update_upper(upper_clause, upper); - } - else { + } else { update_upper(lower_clause, lower); update_lower(upper_clause, upper); } @@ -858,14 +802,13 @@ bool Solver::propagate_(Clingo::PropagateControl &ctl) { }; if (options_.propagate_mode == PropagateMode::Changed) { while (!propagate_queue_.empty()) { - auto i = propagate_queue_.front(); + auto i = propagate_queue_.front(); propagate_queue_.pop_front(); if (!propagate_row(i)) { return false; } } - } - else { + } else { for (index_t i = 0; i < n_basic_; ++i) { if (!propagate_row(i)) { return false; @@ -875,8 +818,7 @@ bool Solver::propagate_(Clingo::PropagateControl &ctl) { return true; } -template -void Solver::undo() { +template void Solver::undo() { try { // this function restores the last satisfying assignment auto &offset = trail_offset_.back(); @@ -918,24 +860,18 @@ void Solver::undo() { trail_offset_.pop_back(); assert_extra(check_solution_()); - } - catch (...) { + } catch (...) { std::terminate(); } } -template -Statistics const &Solver::statistics() const { - return statistics_; -} +template auto Solver::statistics() const -> Statistics const & { return statistics_; } -template -bool Solver::check_tableau_() { +template auto Solver::check_tableau_() -> bool { for (index_t i{0}; i < n_basic_; ++i) { Value v_i; - tableau_.update_row(i, [&](index_t j, Integer const &a_ij, Integer d_i){ - v_i += non_basic_(j).value * a_ij / d_i; - }); + tableau_.update_row( + i, [&](index_t j, Integer const &a_ij, Integer d_i) { v_i += non_basic_(j).value * a_ij / d_i; }); if (v_i != basic_(i).value) { return false; } @@ -943,8 +879,7 @@ bool Solver::check_tableau_() { return true; } -template -bool Solver::check_basic_() { +template auto Solver::check_basic_() -> bool { for (index_t i = 0; i < n_basic_; ++i) { auto &xi = basic_(i); if (xi.has_lower() && xi.value < xi.lower() && !xi.queued) { @@ -957,8 +892,7 @@ bool Solver::check_basic_() { return true; } -template -bool Solver::check_non_basic_() { +template auto Solver::check_non_basic_() -> bool { for (index_t j = 0; j < n_non_basic_; ++j) { auto &xj = non_basic_(j); if (xj.has_lower() && xj.value < xj.lower()) { @@ -971,8 +905,7 @@ bool Solver::check_non_basic_() { return true; } -template -bool Solver::check_solution_() { +template auto Solver::check_solution_() -> bool { for (auto &x : variables_) { if (x.has_lower() && x.lower() > x.value) { return false; @@ -984,8 +917,7 @@ bool Solver::check_solution_() { return check_tableau_() && check_basic_(); } -template -void Solver::update_(index_t level, index_t j, Value v) { +template void Solver::update_(index_t level, index_t j, Value v) { auto &xj = non_basic_(j); tableau_.update_col(j, [&](index_t i, Integer const &a_ij, Integer d_i) { basic_(i).set_value(*this, level, (v - xj.value) * a_ij / d_i, true); @@ -994,8 +926,7 @@ void Solver::update_(index_t level, index_t j, Value v) { xj.set_value(*this, level, std::move(v), false); } -template -void Solver::pivot_(index_t level, index_t i, index_t j, Value const &v) { +template void Solver::pivot_(index_t level, index_t i, index_t j, Value const &v) { Integer *a_ij = nullptr; Integer *d_i = nullptr; tableau_.unsafe_get(i, j, a_ij, d_i); @@ -1031,8 +962,8 @@ void Solver::pivot_(index_t level, index_t i, index_t j, Value const &v) assert_extra(check_non_basic_()); } -template -typename Solver::State Solver::select_(index_t &ret_i, index_t &ret_j, Value const *&ret_v) { +template +auto Solver::select_(index_t &ret_i, index_t &ret_j, Value const *&ret_v) -> typename Solver::State { // This implements Bland's rule selecting the variables with the smallest // indices for pivoting. @@ -1063,10 +994,8 @@ typename Solver::State Solver::select_(index_t &ret_i, index_t &re auto &x_j = variables_[jj]; bool upper = lower == ((a_ij > 0) == (d_i > 0)); // preemptively add bound to conflict clause if it can be increased no further - if (upper ? x_j.has_upper() && x_j.value >= x_j.upper() - : x_j.has_lower() && x_j.value <= x_j.lower()) { - conflict_clause_.emplace_back(upper ? -x_j.upper_bound->lit - : -x_j.lower_bound->lit); + if (upper ? x_j.has_upper() && x_j.value >= x_j.upper() : x_j.has_lower() && x_j.value <= x_j.lower()) { + conflict_clause_.emplace_back(upper ? -x_j.upper_bound->lit : -x_j.lower_bound->lit); } // we can set x_i to one of its bounds to get rid of the conflict else { @@ -1089,8 +1018,8 @@ typename Solver::State Solver::select_(index_t &ret_i, index_t &re return State::Satisfiable; } -template -Clingo::literal_t Solver::adjust(Clingo::Assignment const &assign, Clingo::literal_t lit) const { +template +auto Solver::adjust(Clingo::Assignment const &assign, Clingo::literal_t lit) const -> Clingo::literal_t { static_cast(assign); if (options_.select == SelectionHeuristic::None) { return lit; @@ -1114,17 +1043,18 @@ Clingo::literal_t Solver::adjust(Clingo::Assignment const &assign, Clingo return lit; } -template -void Propagator::init(Clingo::PropagateInit &init) { +template void Propagator::init(Clingo::PropagateInit &init) { facts_offset_ = facts_.size(); if (facts_offset_ > 0 || options_.global_objective.has_value()) { init.set_check_mode(Clingo::PropagatorCheckMode::Both); } - evaluate_theory(init.theory_atoms(), [&](Clingo::literal_t lit) { return init.solver_literal(lit); }, aux_map_, iqs_, objective_); + evaluate_theory( + init.theory_atoms(), [&](Clingo::literal_t lit) { return init.solver_literal(lit); }, aux_map_, iqs_, + objective_); auto gather_vars = [this](std::vector const &terms) { - for (auto const &term: terms) { + for (auto const &term : terms) { if (var_map_.emplace(term.var, var_map_.size()).second) { var_vec_.emplace_back(term.var); } @@ -1141,27 +1071,23 @@ void Propagator::init(Clingo::PropagateInit &init) { slvs_.clear(); slvs_.reserve(init.number_of_threads()); for (size_t i = 0, e = init.number_of_threads(); i != e; ++i) { - slvs_.emplace_back(std::piecewise_construct, - std::forward_as_tuple(0), - std::forward_as_tuple(options_)); + slvs_.emplace_back(std::piecewise_construct, std::forward_as_tuple(0), std::forward_as_tuple(options_)); if (!slvs_.back().second.prepare(init, var_map_, iqs_, objective_, i == 0)) { return; } } } -template -void Propagator::register_control(Clingo::Control &ctl) { +template void Propagator::register_control(Clingo::Control &ctl) { ctl.register_propagator(*this); - if constexpr(std::is_same_v) { + if constexpr (std::is_same_v) { ctl.add("base", {}, THEORY_Q); - } - else { + } else { ctl.add("base", {}, THEORY); } } -template +template void Propagator::on_statistics(Clingo::UserStatistics step, Clingo::UserStatistics accu) { auto step_simplex = step.add_subkey("Simplex", Clingo::StatisticsType::Map); auto step_pivots = step_simplex.add_subkey("Pivots", Clingo::StatisticsType::Value); @@ -1177,13 +1103,13 @@ void Propagator::on_statistics(Clingo::UserStatistics step, Clingo::UserS } } -template -Clingo::literal_t Propagator::decide(Clingo::id_t thread_id, Clingo::Assignment const &assign, Clingo::literal_t fallback) { +template +auto Propagator::decide(Clingo::id_t thread_id, Clingo::Assignment const &assign, Clingo::literal_t fallback) + -> Clingo::literal_t { return slvs_[thread_id].second.adjust(assign, fallback); } -template -void Propagator::on_model(Clingo::Model const &model) { +template void Propagator::on_model(Clingo::Model const &model) { if (!options_.global_objective.has_value()) { return; } @@ -1195,8 +1121,7 @@ void Propagator::on_model(Clingo::Model const &model) { objective_state_.update(*std::move(objective)); } -template -void Propagator::check(Clingo::PropagateControl &ctl) { +template void Propagator::check(Clingo::PropagateControl &ctl) { auto ass = ctl.assignment(); auto &[offset, slv] = slvs_[ctl.thread_id()]; if (ass.decision_level() == 0 && offset < facts_offset_) { @@ -1226,7 +1151,7 @@ void Propagator::check(Clingo::PropagateControl &ctl) { } } -template +template void Propagator::propagate(Clingo::PropagateControl &ctl, Clingo::LiteralSpan changes) { auto ass = ctl.assignment(); if (ass.decision_level() == 0 && ctl.thread_id() == 0) { @@ -1237,43 +1162,36 @@ void Propagator::propagate(Clingo::PropagateControl &ctl, Clingo::Literal static_cast(slv.solve(ctl, changes)); } -template +template void Propagator::undo(Clingo::PropagateControl const &ctl, Clingo::LiteralSpan changes) noexcept { static_cast(changes); slvs_[ctl.thread_id()].second.undo(); } -template -std::optional Propagator::lookup_symbol(Clingo::Symbol symbol) const { +template auto Propagator::lookup_symbol(Clingo::Symbol symbol) const -> std::optional { if (auto it = var_map_.find(symbol); it != var_map_.end()) { return it->second; } return {}; } -template -Clingo::Symbol Propagator::get_symbol(index_t i) const { - return var_vec_[i]; -} +template auto Propagator::get_symbol(index_t i) const -> Clingo::Symbol { return var_vec_[i]; } -template -bool Propagator::has_value(index_t thread_id, index_t i) const { +template auto Propagator::has_value(index_t thread_id, index_t i) const -> bool { static_cast(thread_id); return i < var_vec_.size(); } -template -Value Propagator::get_value(index_t thread_id, index_t i) const { +template auto Propagator::get_value(index_t thread_id, index_t i) const -> Value { return slvs_[thread_id].second.get_value(i); } -template -std::optional> Propagator::get_objective(index_t thread_id) const { +template +auto Propagator::get_objective(index_t thread_id) const -> std::optional> { return slvs_[thread_id].second.get_objective(); } -template -index_t Propagator::n_values(index_t thread_id) const { +template auto Propagator::n_values(index_t thread_id) const -> index_t { static_cast(thread_id); return var_vec_.size(); } diff --git a/libclingo-lpx/src/solving.hh b/libclingo-lpx/src/solving.hh index 07c6a9b..e9c1443 100644 --- a/libclingo-lpx/src/solving.hh +++ b/libclingo-lpx/src/solving.hh @@ -1,9 +1,9 @@ #pragma once -#include "problem.hh" #include "parsing.hh" -#include "util.hh" +#include "problem.hh" #include "tableau.hh" +#include "util.hh" #include @@ -51,13 +51,13 @@ struct Statistics { }; //! Helper to distribute current best objective to solver threads. -template -class ObjectiveState { -public: +template class ObjectiveState { + public: void reset(); void update(std::pair value); - std::optional> value(size_t &generation); -private: + auto value(size_t &generation) -> std::optional>; + + private: #ifndef CLINGOLPX_NO_SHARED_MUTEX std::shared_mutex mutex_; #else @@ -69,24 +69,22 @@ private: }; //! A solver for finding an assignment satisfying a set of inequalities. -template -class Solver { -private: +template class Solver { + private: //! Helper class to prepare the inequalities for solving. struct Prepare; //! The bound type. enum class BoundType : uint32_t { Lower = 0, Upper = 1, - //Equal = 2, + // Equal = 2, }; - enum class BoundRelation : uint32_t { + enum class BoundRelation : uint32_t { LessEqual = 0, GreaterEqual = 1, Equal = 2, }; - template - friend typename Solver::BoundRelation bound_rel(Relation rel); + template friend auto bound_rel(Relation rel) -> typename Solver::BoundRelation; //! The bounds associated with a Variable. //! //! In practice, there should be a lot of variables with just one bound. @@ -97,28 +95,28 @@ private: BoundRelation rel{BoundRelation::LessEqual}; //! Compare the given value with the value of the bound according to //! the relation of the bound. - [[nodiscard]] bool compare(Value const &value) const; + [[nodiscard]] auto compare(Value const &value) const -> bool; //! Check if the bound conflicts with the other one. - [[nodiscard]] bool conflicts(Bound const &other) const; + [[nodiscard]] auto conflicts(Bound const &other) const -> bool; }; //! Capture the current state of a variable. struct Variable { //! Adjusts the lower bound of the variable with the value of the given bound. - [[nodiscard]] bool update_lower(Solver &s, Clingo::Assignment ass, Bound const &bound); + [[nodiscard]] auto update_lower(Solver &s, Clingo::Assignment ass, Bound const &bound) -> bool; //! Adjusts the upper bound of the variable with the value of the given bound. - [[nodiscard]] bool update_upper(Solver &s, Clingo::Assignment ass, Bound const &bound); + [[nodiscard]] auto update_upper(Solver &s, Clingo::Assignment ass, Bound const &bound) -> bool; //! Adjusts the bounds of the variable w.r.t. to the relation of the bound. - [[nodiscard]] bool update(Solver &s, Clingo::Assignment ass, Bound const &bound); + [[nodiscard]] auto update(Solver &s, Clingo::Assignment ass, Bound const &bound) -> bool; //! Check if te value of the variable conflicts with the bounds; - [[nodiscard]] bool has_conflict() const; + [[nodiscard]] auto has_conflict() const -> bool; //! Check if the variable has a lower bound. - [[nodiscard]] bool has_lower() const { return lower_bound != nullptr; } + [[nodiscard]] auto has_lower() const -> bool { return lower_bound != nullptr; } //! Check if the variable has an upper bound. - [[nodiscard]] bool has_upper() const { return upper_bound != nullptr; } + [[nodiscard]] auto has_upper() const -> bool { return upper_bound != nullptr; } //! Return the value of the lower bound. - [[nodiscard]] Value const &lower() const { return lower_bound->value; } + [[nodiscard]] auto lower() const -> Value const & { return lower_bound->value; } //! Return thevalue of the upper bound. - [[nodiscard]] Value const &upper() const { return upper_bound->value; } + [[nodiscard]] auto upper() const -> Value const & { return upper_bound->value; } //! Set a new value or add to the existing one. void set_value(Solver &s, index_t lvl, Value const &val, bool add); @@ -148,16 +146,10 @@ private: }; //! Captures what is know about of the satisfiability of a problem while //! solving. - enum class State { - Satisfiable = 0, - Unsatisfiable = 1, - Unknown = 2 - }; + enum class State { Satisfiable = 0, Unsatisfiable = 1, Unknown = 2 }; //! Captures the objective function. struct Objective { - explicit operator bool() const { - return active; - } + explicit operator bool() const { return active; } //! The index of the objective variable. index_t var{0}; //! The bound for global optimization. @@ -172,63 +164,65 @@ private: bool bounded{true}; }; -public: + public: //! Construct a new solver object. Solver(Options const &options); //! Prepare inequalities for solving. - [[nodiscard]] bool prepare(Clingo::PropagateInit &init, SymbolMap const &symbols, std::vector const &inequalities, std::vector const &objective, bool master); + [[nodiscard]] auto prepare(Clingo::PropagateInit &init, SymbolMap const &symbols, + std::vector const &inequalities, std::vector const &objective, + bool master) -> bool; //! Solve the (previously prepared) problem. - [[nodiscard]] bool solve(Clingo::PropagateControl &ctl, Clingo::LiteralSpan lits); + [[nodiscard]] auto solve(Clingo::PropagateControl &ctl, Clingo::LiteralSpan lits) -> bool; //! Undo assignments on the current level. void undo(); //! Get the currently assigned value. - [[nodiscard]] Value get_value(index_t i) const; + [[nodiscard]] auto get_value(index_t i) const -> Value; //! Get the currently assigned objective value. - [[nodiscard]] std::optional> get_objective() const; + [[nodiscard]] auto get_objective() const -> std::optional>; //! Compute the optimal value for the objective function. void optimize(); //! Integrate the objective into this solver. - bool integrate_objective(Clingo::PropagateControl &ctl, ObjectiveState &state); + auto integrate_objective(Clingo::PropagateControl &ctl, ObjectiveState &state) -> bool; //! Discard bounded solutions (if necessary). - bool discard_bounded(Clingo::PropagateControl &ctl); + auto discard_bounded(Clingo::PropagateControl &ctl) -> bool; //! Ensure that the current (SAT) assignment will not be backtracked. void store_sat_assignment(); //! Return the solve statistics. - [[nodiscard]] Statistics const &statistics() const; + [[nodiscard]] auto statistics() const -> Statistics const &; //! Adjust the sign of the given literal so that it does not conflict with //! the current tableau. - [[nodiscard]] Clingo::literal_t adjust(Clingo::Assignment const &assign, Clingo::literal_t lit) const; + [[nodiscard]] auto adjust(Clingo::Assignment const &assign, Clingo::literal_t lit) const -> Clingo::literal_t; -private: + private: //! Check if the tableau. - [[nodiscard]] bool check_tableau_(); + [[nodiscard]] auto check_tableau_() -> bool; //! Check if basic variables with unsatisfied bounds are enqueued. - [[nodiscard]] bool check_basic_(); + [[nodiscard]] auto check_basic_() -> bool; //! Check if bounds of non-basic variables are satisfied. - [[nodiscard]] bool check_non_basic_(); + [[nodiscard]] auto check_non_basic_() -> bool; //! Check if the current assignment is a solution. - [[nodiscard]] bool check_solution_(); + [[nodiscard]] auto check_solution_() -> bool; //! Print a readable representation of the internal problem to stderr. void debug_(); //! Propagate (some) bounds. - [[nodiscard]] bool propagate_(Clingo::PropagateControl &ctl); + [[nodiscard]] auto propagate_(Clingo::PropagateControl &ctl) -> bool; //! Apply the given bound. - [[nodiscard]] bool update_bound_(Clingo::PropagateControl &ctl, Bound const &bound); + [[nodiscard]] auto update_bound_(Clingo::PropagateControl &ctl, Bound const &bound) -> bool; //! Insert a new bound dynamically. - [[nodiscard]] bool assert_bound_(Clingo::PropagateControl &ctl, Value value); + [[nodiscard]] auto assert_bound_(Clingo::PropagateControl &ctl, Value value) -> bool; //! Enqueue basic variable `x_i` if it is conflicting. void enqueue_(index_t i); @@ -240,12 +234,12 @@ private: void pivot_(index_t level, index_t i, index_t j, Value const &v); //! Select pivot point using Bland's rule. - State select_(index_t &ret_i, index_t &ret_j, Value const *&ret_v); + auto select_(index_t &ret_i, index_t &ret_j, Value const *&ret_v) -> State; //! Get basic variable associated with row `i`. - Variable &basic_(index_t i); + auto basic_(index_t i) -> Variable &; //! Get non-basic variable associated with column `j`. - Variable &non_basic_(index_t j); + auto non_basic_(index_t j) -> Variable &; //! Options configuring the algorithms. Options const &options_; @@ -277,35 +271,34 @@ private: Objective objective_; }; -template -class Propagator : public Clingo::Heuristic { -public: - Propagator(Options options) - : options_{std::move(options)} { } +template class Propagator : public Clingo::Heuristic { + public: + Propagator(Options options) : options_{std::move(options)} {} Propagator(Propagator const &) = default; Propagator(Propagator &&) noexcept = default; - Propagator &operator=(Propagator const &) = default; - Propagator &operator=(Propagator &&) noexcept = default; + auto operator=(Propagator const &) -> Propagator & = default; + auto operator=(Propagator &&) noexcept -> Propagator & = default; ~Propagator() override = default; void register_control(Clingo::Control &ctl); void on_statistics(Clingo::UserStatistics step, Clingo::UserStatistics accu); void on_model(Clingo::Model const &model); - [[nodiscard]] std::optional lookup_symbol(Clingo::Symbol symbol) const; - [[nodiscard]] Clingo::Symbol get_symbol(index_t i) const; - [[nodiscard]] bool has_value(index_t thread_id, index_t i) const; - [[nodiscard]] Value get_value(index_t thread_id, index_t i) const; - [[nodiscard]] std::optional> get_objective(index_t thread_id) const; - [[nodiscard]] index_t n_values(index_t thread_id) const; + [[nodiscard]] auto lookup_symbol(Clingo::Symbol symbol) const -> std::optional; + [[nodiscard]] auto get_symbol(index_t i) const -> Clingo::Symbol; + [[nodiscard]] auto has_value(index_t thread_id, index_t i) const -> bool; + [[nodiscard]] auto get_value(index_t thread_id, index_t i) const -> Value; + [[nodiscard]] auto get_objective(index_t thread_id) const -> std::optional>; + [[nodiscard]] auto n_values(index_t thread_id) const -> index_t; void init(Clingo::PropagateInit &init) override; void check(Clingo::PropagateControl &ctl) override; void propagate(Clingo::PropagateControl &ctl, Clingo::LiteralSpan changes) override; void undo(Clingo::PropagateControl const &ctl, Clingo::LiteralSpan changes) noexcept override; - Clingo::literal_t decide(Clingo::id_t thread_id, Clingo::Assignment const &assign, Clingo::literal_t fallback) override; + auto decide(Clingo::id_t thread_id, Clingo::Assignment const &assign, Clingo::literal_t fallback) + -> Clingo::literal_t override; -private: + private: VarMap aux_map_; SymbolMap var_map_; SymbolVec var_vec_; diff --git a/libclingo-lpx/src/tableau.cc b/libclingo-lpx/src/tableau.cc index 1c86361..e0a431f 100644 --- a/libclingo-lpx/src/tableau.cc +++ b/libclingo-lpx/src/tableau.cc @@ -1,10 +1,10 @@ #include "tableau.hh" -#include #include #include +#include -Rational Tableau::get(index_t i, index_t j) const { +auto Tableau::get(index_t i, index_t j) const -> Rational { if (i < rows_.size()) { auto const &r = rows_[i]; auto it = std::lower_bound(r.cells.begin(), r.cells.end(), j); @@ -34,15 +34,13 @@ void Tableau::set(index_t i, index_t j, Rational const &a) { r.erase(it); } } - } - else { + } else { auto &r = reserve_row_(i); auto it = std::lower_bound(r.cells.begin(), r.cells.end(), j); auto [g, ag, rg] = gcd_div(a.den(), r.den); if (it == r.cells.end() || it->col != j) { it = r.cells.emplace(it, j, a.num() * rg); - } - else { + } else { // Note: this case is only for completeness it is not going to be // used in practice. it->val = a.num() * rg; @@ -106,7 +104,8 @@ void Tableau::pivot(index_t i, index_t j, Integer &a_ij, Integer &d_i) { if (k != i) { auto [g, ga_ij, ga_kj] = gcd_div(a_ij, a_kj); size_t pivot_index = 0; - for (auto A_il = A_i0, A_kl = rows_[k].cells.begin(), A_kn = rows_[k].cells.end(); A_il != A_in || A_kl != A_kn; ) { + for (auto A_il = A_i0, A_kl = rows_[k].cells.begin(), A_kn = rows_[k].cells.end(); + A_il != A_in || A_kl != A_kn;) { // case A_il != 0 and A_kl == 0 if (A_kl == A_kn || (A_il != A_in && A_il->col < A_kl->col)) { assert(A_il->col != j); @@ -199,14 +198,13 @@ void Tableau::debug(char const *indent) const { } } -size_t Tableau::size() const { +auto Tableau::size() const -> size_t { return std::accumulate(rows_.begin(), rows_.end(), static_cast(0), [](size_t n, auto const &r) { return n + r.cells.size(); }); } -bool Tableau::empty() const { - return std::all_of(rows_.cbegin(), rows_.cend(), - [](auto const &r) { return r.cells.empty(); }); +auto Tableau::empty() const -> bool { + return std::all_of(rows_.cbegin(), rows_.cend(), [](auto const &r) { return r.cells.empty(); }); } void Tableau::clear() { @@ -214,20 +212,20 @@ void Tableau::clear() { cols_.clear(); } -Tableau::Row &Tableau::reserve_row_(index_t i) { +auto Tableau::reserve_row_(index_t i) -> Tableau::Row & { if (rows_.size() <= i) { rows_.resize(i + 1); } return rows_[i]; } -std::vector &Tableau::reserve_col_(index_t j) { +auto Tableau::reserve_col_(index_t j) -> std::vector & { if (cols_.size() <= j) { cols_.resize(j + 1); } return cols_[j]; } -Rational const &Tableau::zero_() { +auto Tableau::zero_() -> Rational const & { static Rational zero{0}; return zero; } diff --git a/libclingo-lpx/src/tableau.hh b/libclingo-lpx/src/tableau.hh index 2acfce2..02b0fb1 100644 --- a/libclingo-lpx/src/tableau.hh +++ b/libclingo-lpx/src/tableau.hh @@ -1,16 +1,15 @@ #pragma once +#include #include #include #include -#include #include "number.hh" //! Type used for array indices. using index_t = uint32_t; - //! A sparse tableau with efficient access to both rows and columns. //! //! Insertion into the tableau is linear in the number of rows/columns and @@ -28,11 +27,11 @@ using index_t = uint32_t; //! - A_ij is the element at row i and column j, and //! - A^T is the transposed tableau. class Tableau { -public: + public: //! Return a const reference to A_ij. //! //! Runs in O(log(n)). - [[nodiscard]] Rational get(index_t i, index_t j) const; + [[nodiscard]] auto get(index_t i, index_t j) const -> Rational; //! Return a mutable reference to A_ij assuming that A_ij != 0. //! @@ -55,8 +54,7 @@ public: //! not required by a simplex algorithm. //! //! Runs in O(n). - template - void update_row(index_t i, F &&f) { + template void update_row(index_t i, F &&f) { if (i < rows_.size()) { auto &row = rows_[i]; for (auto &[col, val] : row.cells) { @@ -70,8 +68,7 @@ public: //! The same remark as for update_row() applies. //! //! Runs in O(m*log(n)). - template - void update_col(index_t j, F &&f) { + template void update_col(index_t j, F &&f) { if (j < cols_.size()) { auto &col = cols_[j]; auto it = col.begin(); @@ -104,12 +101,12 @@ public: //! Get the number of non-zero elements in the tableau. //! //! Runs in O(m). - [[nodiscard]] size_t size() const; + [[nodiscard]] auto size() const -> size_t; //! Equivalent to `size() == 0`. //! //! Runs in O(m). - [[nodiscard]] bool empty() const; + [[nodiscard]] auto empty() const -> bool; //! Set all elements to zero. //! @@ -119,27 +116,17 @@ public: //! Print tableau to stderr for debugging purposes. void debug(char const *indent) const; -private: + private: //! Simplify the given row. void simplify_(index_t i); struct Cell { - Cell(index_t col, Integer val) - : col{col} - , val{std::move(val)} { } + Cell(index_t col, Integer val) : col{col}, val{std::move(val)} {} - friend bool operator==(Cell const &x, Cell const &y) { - return x.col == y.col && x.val == y.val; - } - friend bool operator<(Cell const &x, Cell const &y) { - return x.col < y.col; - } - friend bool operator<(Cell const &x, index_t col) { - return x.col < col; - } - friend bool operator<(index_t col, Cell const &x) { - return col < x.col; - } + friend auto operator==(Cell const &x, Cell const &y) -> bool { return x.col == y.col && x.val == y.val; } + friend auto operator<(Cell const &x, Cell const &y) -> bool { return x.col < y.col; } + friend auto operator<(Cell const &x, index_t col) -> bool { return x.col < col; } + friend auto operator<(index_t col, Cell const &x) -> bool { return col < x.col; } index_t col; Integer val; @@ -149,11 +136,10 @@ private: std::vector cells; }; - Row &reserve_row_(index_t i); - std::vector &reserve_col_(index_t j); - static Rational const &zero_(); + auto reserve_row_(index_t i) -> Row &; + auto reserve_col_(index_t j) -> std::vector &; + static auto zero_() -> Rational const &; std::vector rows_; std::vector> cols_; }; - diff --git a/libclingo-lpx/src/util.hh b/libclingo-lpx/src/util.hh index e397022..2d00bc2 100644 --- a/libclingo-lpx/src/util.hh +++ b/libclingo-lpx/src/util.hh @@ -1,35 +1,31 @@ #pragma once -#include -#include #include +#include +#include #ifdef CLINGOLPX_CROSSCHECK -# define assert_extra(X) assert(X) // NOLINT +#define assert_extra(X) assert(X) // NOLINT #else -# define assert_extra(X) // NOLINT +#define assert_extra(X) // NOLINT #endif namespace detail { -template -using int_type = std::integral_constant; -template -inline void sc_check(S s, int_type<0> t) { // same sign +template using int_type = std::integral_constant; +template inline void sc_check(S s, int_type<0> t) { // same sign static_cast(t); if (!std::is_same::value && (s < std::numeric_limits::min() || s > std::numeric_limits::max())) { throw std::overflow_error("safe cast failed"); } } -template -inline void sc_check(S s, int_type<-1> t) { // Signed -> Unsigned +template inline void sc_check(S s, int_type<-1> t) { // Signed -> Unsigned static_cast(t); if (s < 0 || static_cast(static_cast(s)) != s) { throw std::overflow_error("safe cast failed"); } } -template -inline void sc_check(S s, int_type<1> t) { // Unsigned -> Signed +template inline void sc_check(S s, int_type<1> t) { // Unsigned -> Signed static_cast(t); if (s > static_cast::type>(std::numeric_limits::max())) { throw std::overflow_error("safe cast failed"); @@ -39,10 +35,9 @@ inline void sc_check(S s, int_type<1> t) { // Unsigned -> Signed } // namespace detail //! A safe numeric cast raising an exception if the target type cannot hold the value. -template -inline T safe_cast(S s) { - constexpr int sv = static_cast(std::numeric_limits::is_signed) - static_cast(std::numeric_limits::is_signed); +template inline auto safe_cast(S s) -> T { + constexpr int sv = + static_cast(std::numeric_limits::is_signed) - static_cast(std::numeric_limits::is_signed); detail::sc_check(s, detail::int_type()); return static_cast(s); } - diff --git a/libclingo-lpx/tests/number.cc b/libclingo-lpx/tests/number.cc index 825ce7b..6d42cb7 100644 --- a/libclingo-lpx/tests/number.cc +++ b/libclingo-lpx/tests/number.cc @@ -31,4 +31,3 @@ TEST_CASE("number") { REQUIRE_THROWS(Rational{"xxx", 10}); } - diff --git a/libclingo-lpx/tests/parsing.cc b/libclingo-lpx/tests/parsing.cc index 7e7ed1c..2a8f8f9 100644 --- a/libclingo-lpx/tests/parsing.cc +++ b/libclingo-lpx/tests/parsing.cc @@ -4,8 +4,7 @@ #include -template -std::string str(T &&x) { +template auto str(T &&x) -> std::string { std::ostringstream oss; oss << x; return oss.str(); @@ -69,8 +68,8 @@ TEST_CASE("parsing") { evaluate_theory(ctl.theory_atoms(), mapper, vars, eqs, objective); REQUIRE(eqs.empty()); REQUIRE(objective.size() == 2); - std::sort(objective.begin(), objective.end(), [](auto &a, auto &b) { return std::make_pair(a.var, a.co) < std::make_pair(b.var, b.co); }); + std::sort(objective.begin(), objective.end(), + [](auto &a, auto &b) { return std::make_pair(a.var, a.co) < std::make_pair(b.var, b.co); }); REQUIRE(str(Inequality{objective, 0, Relation::Equal, 0}) == "-3*x + -y = 0"); } } - diff --git a/libclingo-lpx/tests/solving.cc b/libclingo-lpx/tests/solving.cc index 175fb57..3597cd9 100644 --- a/libclingo-lpx/tests/solving.cc +++ b/libclingo-lpx/tests/solving.cc @@ -9,28 +9,25 @@ namespace { -template -class SHM : public Clingo::SolveEventHandler { -public: - SHM(Propagator &prp) - : prp_{prp} { } - bool on_model(Clingo::Model &model) override { +template class SHM : public Clingo::SolveEventHandler { + public: + SHM(Propagator &prp) : prp_{prp} {} + auto on_model(Clingo::Model &model) -> bool override { prp_.on_model(model); val_ = prp_.get_objective(model.thread_id()); return true; } - std::optional> const &get_objective() const { - return val_; - } -private: + auto get_objective() const -> std::optional> const & { return val_; } + + private: std::optional> val_; Propagator &prp_; }; -Options const options{SelectionHeuristic::Conflict, StoreSATAssignments::Partial, std::nullopt, PropagateMode::Changed, true}; +Options const options{SelectionHeuristic::Conflict, StoreSATAssignments::Partial, std::nullopt, PropagateMode::Changed, + true}; -template -bool run(char const *s) { +template auto run(char const *s) -> bool { Propagator prp{options}; Clingo::Control ctl; prp.register_control(ctl); @@ -42,7 +39,7 @@ bool run(char const *s) { } template -std::optional> run_o(char const *s, bool global = false, long c=0, long k=0) { +auto run_o(char const *s, bool global = false, long c = 0, long k = 0) -> std::optional> { Options opts = options; if (global) { opts.global_objective = RationalQ{Rational{c}, Rational{k}}; @@ -64,7 +61,7 @@ std::optional> run_o(char const *s, bool global = false, long return shm.get_objective(); } -size_t run_m(std::initializer_list m) { +auto run_m(std::initializer_list m) -> size_t { Propagator prp{options}; Clingo::Control ctl{{"0"}}; prp.register_control(ctl); @@ -115,9 +112,9 @@ bound(10). // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) TEST_CASE("solving") { SECTION("non-strict") { - REQUIRE( run("&sum { x1; x2 } <= 20.\n" - "&sum { x1; x3 } = 5.\n" - "&sum { x2; x3 } >= 10.\n")); + REQUIRE(run("&sum { x1; x2 } <= 20.\n" + "&sum { x1; x3 } = 5.\n" + "&sum { x2; x3 } >= 10.\n")); REQUIRE(!run("&sum { x } >= 2.\n" "&sum { x } <= 0.\n")); @@ -132,88 +129,83 @@ TEST_CASE("solving") { "&sum { x; y } <= 0.\n" "&sum { y } = 0.\n")); - REQUIRE( run("&sum { x; y } >= 2.\n" - "&sum { 2*x; -y } >= 0.\n" - "&sum { -x; 2*y } >= 1.\n")); + REQUIRE(run("&sum { x; y } >= 2.\n" + "&sum { 2*x; -y } >= 0.\n" + "&sum { -x; 2*y } >= 1.\n")); } SECTION("strict") { - REQUIRE( run( - "&sum { x1; x2 } < 20.\n" - "&sum { x1; x3 } = 5.\n" - "&sum { x2; x3 } > 10.\n")); - - REQUIRE(!run( - "&sum { x } > 2.\n" - "&sum { x } < 0.\n")); - - REQUIRE(!run( - "&sum { -x } < -2.\n" - "&sum { x } < 0.\n")); - - REQUIRE(!run( - "&sum { 4*x } < 4.\n" - "&sum { x } > 2.\n")); - - REQUIRE(!run( - "&sum { x; y } > 2.\n" - "&sum { x; y } < 0.\n" - "&sum { y } = 0.\n")); - - REQUIRE( run( - "&sum { x; y } > 2.\n" - "&sum { 2*x; -y } > 0.\n" - "&sum { -x; 2*y } > 1.\n")); - - REQUIRE(!run( - "&sum { x; -y } > 0.\n" - "&sum { y; -z } > 0.\n" - "&sum { z; -x } > 0.\n")); + REQUIRE(run("&sum { x1; x2 } < 20.\n" + "&sum { x1; x3 } = 5.\n" + "&sum { x2; x3 } > 10.\n")); + + REQUIRE(!run("&sum { x } > 2.\n" + "&sum { x } < 0.\n")); + + REQUIRE(!run("&sum { -x } < -2.\n" + "&sum { x } < 0.\n")); + + REQUIRE(!run("&sum { 4*x } < 4.\n" + "&sum { x } > 2.\n")); + + REQUIRE(!run("&sum { x; y } > 2.\n" + "&sum { x; y } < 0.\n" + "&sum { y } = 0.\n")); + + REQUIRE(run("&sum { x; y } > 2.\n" + "&sum { 2*x; -y } > 0.\n" + "&sum { -x; 2*y } > 1.\n")); + + REQUIRE(!run("&sum { x; -y } > 0.\n" + "&sum { y; -z } > 0.\n" + "&sum { z; -x } > 0.\n")); } SECTION("multi-shot") { - REQUIRE( run_m({"&sum { x1; x2 } <= 20.\n" - "&sum { x1; x2 } >= 10.\n", - "&sum { x1 } >= 30.\n" - "&sum { x3 } >= 1.\n", - "&sum { x2 } >= 10.\n"}) == 2); - REQUIRE( run_m({"{a; b}.\n" - "&sum { x1: a; x2: b } <= 10.\n" - "&sum { x1: a; x2: b } >= 10.\n", - ":- a.\n" - ":- b."}) == 3); + REQUIRE(run_m({"&sum { x1; x2 } <= 20.\n" + "&sum { x1; x2 } >= 10.\n", + "&sum { x1 } >= 30.\n" + "&sum { x3 } >= 1.\n", + "&sum { x2 } >= 10.\n"}) == 2); + REQUIRE(run_m({"{a; b}.\n" + "&sum { x1: a; x2: b } <= 10.\n" + "&sum { x1: a; x2: b } >= 10.\n", + ":- a.\n" + ":- b."}) == 3); } SECTION("optimize") { - REQUIRE( run_o("&sum { x_1; 2*x_2; 3*x_3 } <= 30.\n" - "&sum { 2*x_1; 2*x_2; 5*x_3 } <= 24.\n" - "&sum { 4*x_1; x_2; 2*x_3 } <= 36.\n" - "&sum { x_1 } >= 0.\n" - "&sum { x_2 } >= 0.\n" - "&sum { x_3 } >= 0.\n" - "&maximize { 3*x_1; x_2; 2*x_3 }.\n") == std::make_pair(Rational{28}, true)); - REQUIRE( run_o("&sum { x_1; 2*x_2; 3*x_3 } <= 30.\n" - "&sum { 2*x_1; 2*x_2; 5*x_3 } <= 24.\n" - "&sum { 4*x_1; x_2; 2*x_3 } <= 36.\n" - "&maximize { 3*x_1; x_2; 2*x_3 }.\n") == std::make_pair(Rational{378, 13}, true)); - REQUIRE( run_o("&sum { 2*x_1; -x_2 } <= 2.\n" - "&sum { x_1; -5*x_2 } <= -4.\n" - "&maximize { 2*x_1; -x_2 }.\n") == std::make_pair(Rational{2}, true)); + REQUIRE(run_o("&sum { x_1; 2*x_2; 3*x_3 } <= 30.\n" + "&sum { 2*x_1; 2*x_2; 5*x_3 } <= 24.\n" + "&sum { 4*x_1; x_2; 2*x_3 } <= 36.\n" + "&sum { x_1 } >= 0.\n" + "&sum { x_2 } >= 0.\n" + "&sum { x_3 } >= 0.\n" + "&maximize { 3*x_1; x_2; 2*x_3 }.\n") == std::make_pair(Rational{28}, true)); + REQUIRE(run_o("&sum { x_1; 2*x_2; 3*x_3 } <= 30.\n" + "&sum { 2*x_1; 2*x_2; 5*x_3 } <= 24.\n" + "&sum { 4*x_1; x_2; 2*x_3 } <= 36.\n" + "&maximize { 3*x_1; x_2; 2*x_3 }.\n") == std::make_pair(Rational{378, 13}, true)); + REQUIRE(run_o("&sum { 2*x_1; -x_2 } <= 2.\n" + "&sum { x_1; -5*x_2 } <= -4.\n" + "&maximize { 2*x_1; -x_2 }.\n") == std::make_pair(Rational{2}, true)); REQUIRE(!run_o("&sum { x; y } >= 7.\n" "&sum { y } >= 3.\n" - "&maximize { 8*x; -5*y }.\n")->second); + "&maximize { 8*x; -5*y }.\n") + ->second); } SECTION("optimize-global") { - REQUIRE(run_o( - "{ a; b }.\n" - "&sum { a; b } <= 5.\n" - "&sum { a } <= 2 :- a.\n" - "&sum { b } <= 2 :- b.\n" - "&maximize { a; b }.\n", true) == std::make_pair(Rational{5}, true)); - REQUIRE(!run_o( - "{ a; b }.\n" - "&sum { a } <= 5 :- a.\n" - "&sum { b } <= 5 :- a.\n" - "&sum { b } <= 5 :- b.\n" - "&sum { a; b } <= 10 :- not a, not b.\n" - "&maximize { a; b }.\n", true)->second); + REQUIRE(run_o("{ a; b }.\n" + "&sum { a; b } <= 5.\n" + "&sum { a } <= 2 :- a.\n" + "&sum { b } <= 2 :- b.\n" + "&maximize { a; b }.\n", + true) == std::make_pair(Rational{5}, true)); + REQUIRE(!run_o("{ a; b }.\n" + "&sum { a } <= 5 :- a.\n" + "&sum { b } <= 5 :- a.\n" + "&sum { b } <= 5 :- b.\n" + "&sum { a; b } <= 10 :- not a, not b.\n" + "&maximize { a; b }.\n", + true) + ->second); REQUIRE(run_o(knapsack, true) == std::make_pair(Rational{180}, true)); REQUIRE(run_o(knapsack, true, 0, 1) == std::make_pair(RationalQ{Rational{180}}, true)); } diff --git a/libclingo-lpx/tests/tableau.cc b/libclingo-lpx/tests/tableau.cc index fba0204..2aa0969 100644 --- a/libclingo-lpx/tests/tableau.cc +++ b/libclingo-lpx/tests/tableau.cc @@ -4,7 +4,7 @@ namespace { -std::vector> as_num_mat(Tableau const &tab, index_t m, index_t n) { +auto as_num_mat(Tableau const &tab, index_t m, index_t n) -> std::vector> { std::vector> ret; ret.reserve(m); for (index_t i = 0; i < m; ++i) { @@ -18,7 +18,7 @@ std::vector> as_num_mat(Tableau const &tab, index_t m, ind return ret; } -std::vector> as_int_mat(Tableau &tab, index_t m, index_t n) { +auto as_int_mat(Tableau &tab, index_t m, index_t n) -> std::vector> { std::vector> ret; ret.reserve(m); for (index_t i = 0; i < m; ++i) { @@ -37,7 +37,7 @@ std::vector> as_int_mat(Tableau &tab, index_t m, index_t n) return ret; } -} +} // namespace // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers) // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) @@ -51,26 +51,26 @@ TEST_CASE("matrix") { tab.set(0, 0, Rational{Integer{2}, Integer{4}}); tab.set(0, 1, Rational{Integer{1}, Integer{3}}); tab.set(0, 2, Rational{Integer{1}, Integer{5}}); - tab.set(0, 3, Rational{Integer{1}, Integer{2L*3*5*7}}); + tab.set(0, 3, Rational{Integer{1}, Integer{2L * 3 * 5 * 7}}); tab.unsafe_get(0, 0, num, den); - REQUIRE(*num == (3L*5*7)); - REQUIRE(*den == (2L*3*5*7)); + REQUIRE(*num == (3L * 5 * 7)); + REQUIRE(*den == (2L * 3 * 5 * 7)); tab.unsafe_get(0, 1, num, den); - REQUIRE(*num == (2L*5*7)); + REQUIRE(*num == (2L * 5 * 7)); tab.unsafe_get(0, 2, num, den); - REQUIRE(*num == (2L*3*7)); + REQUIRE(*num == (2L * 3 * 7)); tab.unsafe_get(0, 3, num, den); REQUIRE(*num == 1); - tab.set(0, 4, Rational{Integer{7}, Integer{2L*3*5*7}}); + tab.set(0, 4, Rational{Integer{7}, Integer{2L * 3 * 5 * 7}}); tab.unsafe_get(0, 4, num, den); REQUIRE(*num == 7); - REQUIRE(*den == (2L*3*5*7)); + REQUIRE(*den == (2L * 3 * 5 * 7)); } SECTION("integer") { @@ -151,13 +151,8 @@ TEST_CASE("matrix") { std::vector> int_ret = as_int_mat(tab, 3, 3); std::vector> num_sol = { - { {-3, 5}, {2, 5}, { 3, 5} }, - { {-4, 5}, {1, 5}, {-6, 5} }, - { { 3, 5}, {8, 5}, {-3, 5} } }; - std::vector> int_sol = { - { -3, 2, 3, 5 }, - { -4, 1, -6, 5 }, - { 3, 8, -3, 5 } }; + {{-3, 5}, {2, 5}, {3, 5}}, {{-4, 5}, {1, 5}, {-6, 5}}, {{3, 5}, {8, 5}, {-3, 5}}}; + std::vector> int_sol = {{-3, 2, 3, 5}, {-4, 1, -6, 5}, {3, 8, -3, 5}}; REQUIRE(num_ret == num_sol); REQUIRE(int_ret == int_sol);