libsemigroups  v3.3.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
order.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2019-2025 James D. Mitchell + James W. Swent
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <http://www.gnu.org/licenses/>.
17//
18
19// This file contains the declarations of several functions and structs
20// defining linear orders on words.
21
22// TODO
23// * dry it out
24// * noexcept
25
26#ifndef LIBSEMIGROUPS_ORDER_HPP_
27#define LIBSEMIGROUPS_ORDER_HPP_
28
29#include <algorithm> // for std::find_if, std::lexicographical_compare
30#include <cstddef> // for size_t
31#include <cstdint> // for uint8_t
32#include <initializer_list> // for initializer_list
33#include <iterator> // for distance
34#include <numeric> // for accumulate
35#include <type_traits> // for enable_if_t
36#include <utility> // for move
37#include <vector> // for vector
38
39#include "exception.hpp" // for LIBSEMIGROUPS_EXCEPTION
40#include "ranges.hpp" // for shortlex_compare
41
42namespace libsemigroups {
54 enum class Order : uint8_t {
56 none = 0,
57
61
66
70
71 // wreath TODO(later)
72 };
73
82
110 template <typename Thing,
111 typename = std::enable_if_t<!rx::is_input_or_sink_v<Thing>>>
112 [[nodiscard]] bool lexicographical_compare(Thing const& x, Thing const& y) {
114 x.cbegin(), x.cend(), y.cbegin(), y.cend());
115 }
116
144 template <typename Thing>
145 [[nodiscard]] bool lexicographical_compare(Thing* const x, Thing* const y) {
147 x->cbegin(), x->cend(), y->cbegin(), y->cend());
148 }
149
183 template <typename Thing>
184 [[nodiscard]] bool operator()(Thing const& x, Thing const& y) const {
185 return lexicographical_compare(x, y);
186 }
187
207 // TODO(v4) is this really necessary?
208 template <typename T>
210 std::initializer_list<T> y) const {
212 x.begin(), x.end(), y.begin(), y.end());
213 }
214
237 // TODO(v4) remove this?
238 template <typename Iterator>
239 [[nodiscard]] bool operator()(Iterator first1,
240 Iterator last1,
241 Iterator first2,
242 Iterator last2) const {
243 return std::lexicographical_compare(first1, last1, first2, last2);
244 }
245 };
246
286 template <typename Iterator,
287 typename = std::enable_if_t<!rx::is_input_or_sink_v<Iterator>>>
288 [[nodiscard]] bool shortlex_compare(Iterator first1,
289 Iterator last1,
290 Iterator first2,
291 Iterator last2) {
292 return (last1 - first1) < (last2 - first2)
293 || ((last1 - first1) == (last2 - first2)
294 && std::lexicographical_compare(first1, last1, first2, last2));
295 }
296
327 template <typename Thing,
328 typename = std::enable_if_t<!rx::is_input_or_sink_v<Thing>>>
329 [[nodiscard]] bool shortlex_compare(Thing const& x, Thing const& y) {
330 return shortlex_compare(x.cbegin(), x.cend(), y.cbegin(), y.cend());
331 }
332
363 template <typename Thing>
364 [[nodiscard]] bool shortlex_compare(Thing* const x, Thing* const y) {
365 return shortlex_compare(x->cbegin(), x->cend(), y->cbegin(), y->cend());
366 }
367
399 template <typename Thing>
400 [[nodiscard]] bool operator()(Thing const& x, Thing const& y) const {
401 return shortlex_compare(x, y);
402 }
403 };
404
441 template <typename Iterator,
442 typename = std::enable_if_t<!rx::is_input_or_sink_v<Iterator>>>
443 [[nodiscard]] bool recursive_path_compare(Iterator first1,
444 Iterator last1,
445 Iterator first2,
446 Iterator last2) noexcept;
447
475 template <typename Thing,
476 typename = std::enable_if_t<!rx::is_input_or_sink_v<Thing>>>
477 [[nodiscard]] bool recursive_path_compare(Thing const& x,
478 Thing const& y) noexcept {
479 return recursive_path_compare(x.cbegin(), x.cend(), y.cbegin(), y.cend());
480 }
481
510 template <typename Thing>
511 [[nodiscard]] bool recursive_path_compare(Thing* const x,
512 Thing* const y) noexcept {
514 x->cbegin(), x->cend(), y->cbegin(), y->cend());
515 }
516
547 template <typename Thing>
548 [[nodiscard]] bool operator()(Thing const& x,
549 Thing const& y) const noexcept {
550 return recursive_path_compare(x, y);
551 }
552 };
553
593 template <typename Iterator,
594 typename = std::enable_if_t<!rx::is_input_or_sink_v<Iterator>>>
595 [[nodiscard]] bool
597 Iterator last1,
598 Iterator first2,
599 Iterator last2,
600 std::vector<size_t> const& weights);
601
641 template <typename Thing,
642 typename = std::enable_if_t<!rx::is_input_or_sink_v<Thing>>>
643 [[nodiscard]] bool
645 Thing const& y,
646 std::vector<size_t> const& weights) {
648 x.cbegin(), x.cend(), y.cbegin(), y.cend(), weights);
649 }
650
690 template <typename Thing>
691 [[nodiscard]] bool
693 Thing* const y,
694 std::vector<size_t> const& weights) {
696 x->cbegin(), x->cend(), y->cbegin(), y->cend(), weights);
697 }
698
739 template <typename Iterator,
740 typename = std::enable_if_t<!rx::is_input_or_sink_v<Iterator>>>
741 [[nodiscard]] bool wt_shortlex_compare(Iterator first1,
742 Iterator last1,
743 Iterator first2,
744 Iterator last2,
745 std::vector<size_t> const& weights);
746
785 template <typename Thing,
786 typename = std::enable_if_t<!rx::is_input_or_sink_v<Thing>>>
787 [[nodiscard]] bool wt_shortlex_compare(Thing const& x,
788 Thing const& y,
789 std::vector<size_t> const& weights) {
790 return wt_shortlex_compare(
791 x.cbegin(), x.cend(), y.cbegin(), y.cend(), weights);
792 }
793
832 template <typename Thing>
833 [[nodiscard]] bool wt_shortlex_compare(Thing* const x,
834 Thing* const y,
835 std::vector<size_t> const& weights) {
836 return wt_shortlex_compare(
837 x->cbegin(), x->cend(), y->cbegin(), y->cend(), weights);
838 }
839
868 static constexpr bool checks = true;
869
874 static constexpr bool no_checks = false;
875
891 : _weights(weights), _should_check(should_check) {}
892
906 bool should_check) {
907 _weights = weights;
908 _should_check = should_check;
909 return *this;
910 }
911
927 : _weights(std::move(weights)), _should_check(should_check) {}
928
942 _weights = std::move(weights);
943 _should_check = should_check;
944 return *this;
945 }
946
977 template <typename Thing>
978 [[nodiscard]] bool operator()(Thing const& x, Thing const& y) const {
979 if (_should_check) {
980 return wt_shortlex_compare(x, y, _weights);
981 } else {
982 return wt_shortlex_compare_no_checks(x, y, _weights);
983 }
984 }
985
1007 template <typename Thing>
1008 [[nodiscard]] bool call_no_checks(Thing const& x, Thing const& y) const {
1009 return wt_shortlex_compare_no_checks(x, y, _weights);
1010 }
1011
1023 [[nodiscard]] bool should_check() const noexcept {
1024 return _should_check;
1025 }
1026
1041 WtShortLexCompare& should_check(bool val) noexcept {
1042 _should_check = val;
1043 return *this;
1044 }
1045
1055 [[nodiscard]] std::vector<size_t> const& weights() const noexcept {
1056 return _weights;
1057 }
1058
1071 _weights = val;
1072 return *this;
1073 }
1074
1075 private:
1076 std::vector<size_t> _weights;
1077 bool _should_check;
1078 };
1079
1119 template <typename Iterator,
1120 typename = std::enable_if_t<!rx::is_input_or_sink_v<Iterator>>>
1121 [[nodiscard]] bool
1123 Iterator last1,
1124 Iterator first2,
1125 Iterator last2,
1126 std::vector<size_t> const& weights);
1127
1167 template <typename Thing,
1168 typename = std::enable_if_t<!rx::is_input_or_sink_v<Thing>>>
1169 [[nodiscard]] bool
1171 Thing const& y,
1172 std::vector<size_t> const& weights) {
1174 x.cbegin(), x.cend(), y.cbegin(), y.cend(), weights);
1175 }
1176
1216 template <typename Thing>
1217 [[nodiscard]] bool
1219 Thing* const y,
1220 std::vector<size_t> const& weights) {
1222 x->cbegin(), x->cend(), y->cbegin(), y->cend(), weights);
1223 }
1224
1265 template <typename Iterator,
1266 typename = std::enable_if_t<!rx::is_input_or_sink_v<Iterator>>>
1267 [[nodiscard]] bool wt_lex_compare(Iterator first1,
1268 Iterator last1,
1269 Iterator first2,
1270 Iterator last2,
1271 std::vector<size_t> const& weights);
1272
1311 template <typename Thing,
1312 typename = std::enable_if_t<!rx::is_input_or_sink_v<Thing>>>
1313 [[nodiscard]] bool wt_lex_compare(Thing const& x,
1314 Thing const& y,
1315 std::vector<size_t> const& weights) {
1316 return wt_lex_compare(x.cbegin(), x.cend(), y.cbegin(), y.cend(), weights);
1317 }
1318
1357 template <typename Thing>
1358 [[nodiscard]] bool wt_lex_compare(Thing* const x,
1359 Thing* const y,
1360 std::vector<size_t> const& weights) {
1361 return wt_lex_compare(
1362 x->cbegin(), x->cend(), y->cbegin(), y->cend(), weights);
1363 }
1364
1392 static constexpr bool checks = true;
1393
1398 static constexpr bool no_checks = false;
1399
1415 : _weights(weights), _should_check(should_check) {}
1416
1430 _weights = std::move(weights);
1431 _should_check = should_check;
1432 return *this;
1433 }
1434
1450 : _weights(std::move(weights)), _should_check(should_check) {}
1451
1465 _weights = std::move(weights);
1466 _should_check = should_check;
1467 return *this;
1468 }
1469
1499 template <typename Thing>
1500 [[nodiscard]] bool operator()(Thing const& x, Thing const& y) const {
1501 if (_should_check) {
1502 return wt_lex_compare(x, y, _weights);
1503 } else {
1504 return wt_lex_compare_no_checks(x, y, _weights);
1505 }
1506 }
1507
1529 template <typename Thing>
1530 [[nodiscard]] bool call_no_checks(Thing const& x, Thing const& y) const {
1531 return wt_lex_compare_no_checks(x, y, _weights);
1532 }
1533
1545 [[nodiscard]] bool should_check() const noexcept {
1546 return _should_check;
1547 }
1548
1563 WtLexCompare& should_check(bool val) noexcept {
1564 _should_check = val;
1565 return *this;
1566 }
1567
1577 [[nodiscard]] std::vector<size_t> const& weights() const noexcept {
1578 return _weights;
1579 }
1580
1590 _weights = val;
1591 return *this;
1592 }
1593
1594 private:
1595 std::vector<size_t> _weights;
1596 bool _should_check;
1597 };
1598
1599 // end orders_group
1601
1602} // namespace libsemigroups
1603
1604#include "order.tpp"
1605
1606#endif // LIBSEMIGROUPS_ORDER_HPP_
bool lexicographical_compare(Thing const &x, Thing const &y)
Compare two objects of the same type using std::lexicographical_compare.
Definition order.hpp:112
bool wt_shortlex_compare(Iterator first1, Iterator last1, Iterator first2, Iterator last2, std::vector< size_t > const &weights)
Compare two objects of the same type using the weighted short-lex ordering and check validity.
bool wt_shortlex_compare_no_checks(Iterator first1, Iterator last1, Iterator first2, Iterator last2, std::vector< size_t > const &weights)
Compare two objects of the same type using the weighted short-lex ordering without checks.
bool wt_lex_compare_no_checks(Iterator first1, Iterator last1, Iterator first2, Iterator last2, std::vector< size_t > const &weights)
Compare two objects of the same type using the weighted lex ordering without checks.
bool wt_lex_compare(Iterator first1, Iterator last1, Iterator first2, Iterator last2, std::vector< size_t > const &weights)
Compare two objects of the same type using the weighted lex ordering and check validity.
bool shortlex_compare(Iterator first1, Iterator last1, Iterator first2, Iterator last2)
Compare two objects of the same type using the short-lex reduction ordering.
Definition order.hpp:288
bool recursive_path_compare(Iterator first1, Iterator last1, Iterator first2, Iterator last2) noexcept
Compare two objects of the same type using the recursive path comparison.
Order
The possible orderings of words and strings.
Definition order.hpp:54
@ none
No ordering.
Definition order.hpp:56
@ shortlex
Definition order.hpp:60
@ lex
Definition order.hpp:65
@ recursive
Definition order.hpp:69
T lexicographical_compare(T... args)
T move(T... args)
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
A stateless struct with binary call operator using std::lexicographical_compare.
Definition order.hpp:163
bool operator()(Thing const &x, Thing const &y) const
Call operator that compares x and y using std::lexicographical_compare.
Definition order.hpp:184
bool operator()(std::initializer_list< T > x, std::initializer_list< T > y) const
Call operator that compares x and y given initializer lists using std::lexicographical_compare.
Definition order.hpp:209
bool operator()(Iterator first1, Iterator last1, Iterator first2, Iterator last2) const
Call operator that compares iterators using std::lexicographical_compare.
Definition order.hpp:239
A stateless struct with binary call operator using recursive_path_compare.
Definition order.hpp:530
bool operator()(Thing const &x, Thing const &y) const noexcept
Call operator that compares x and y using recursive_path_compare.
Definition order.hpp:548
A stateless struct with binary call operator using shortlex_compare.
Definition order.hpp:380
bool operator()(Thing const &x, Thing const &y) const
Call operator that compares x and y using shortlex_compare.
Definition order.hpp:400
static constexpr bool checks
Constant to enable validity checks.
Definition order.hpp:1392
WtLexCompare & should_check(bool val) noexcept
Set the value of the constructor parameter should_check.
Definition order.hpp:1563
WtLexCompare & init(std::vector< size_t > &&weights, bool should_check)
Reinitialize an existing WtLexCompare object.
Definition order.hpp:1464
bool operator()(Thing const &x, Thing const &y) const
Call operator that compares x and y using either wt_lex_compare or wt_lex_compare_no_checks.
Definition order.hpp:1500
WtLexCompare & weights(std::vector< size_t > const &val)
Set the weights.
Definition order.hpp:1589
WtLexCompare & init(std::vector< size_t > const &weights, bool should_check)
Reinitialize an existing WtLexCompare object.
Definition order.hpp:1429
WtLexCompare(std::vector< size_t > &&weights, bool should_check)
Construct from weights vector rvalue reference and specify whether or not the call operator should ch...
Definition order.hpp:1449
bool call_no_checks(Thing const &x, Thing const &y) const
Call operator that does no checks.
Definition order.hpp:1530
std::vector< size_t > const & weights() const noexcept
Returns the weights.
Definition order.hpp:1577
WtLexCompare(std::vector< size_t > const &weights, bool should_check)
Construct from weights vector reference and specify whether or not the call operator should check its...
Definition order.hpp:1414
bool should_check() const noexcept
Returns the value of the constructor parameter should_check.
Definition order.hpp:1545
static constexpr bool no_checks
Constant to disable validity checks.
Definition order.hpp:1398
static constexpr bool checks
Constant to enable validity checks.
Definition order.hpp:868
WtShortLexCompare(std::vector< size_t > &&weights, bool should_check)
Construct from weights vector rvalue reference and specify whether or not the call operator should ch...
Definition order.hpp:926
bool operator()(Thing const &x, Thing const &y) const
Call operator that compares x and y using either wt_shortlex_compare or wt_shortlex_compare_no_checks...
Definition order.hpp:978
WtShortLexCompare & init(std::vector< size_t > &&weights, bool should_check)
Reinitialize an existing WtShortLexCompare object.
Definition order.hpp:941
WtShortLexCompare(std::vector< size_t > const &weights, bool should_check)
Construct from weights vector reference and specify whether or not the call operator should check its...
Definition order.hpp:890
bool call_no_checks(Thing const &x, Thing const &y) const
Call operator that does no checks.
Definition order.hpp:1008
std::vector< size_t > const & weights() const noexcept
Returns the weights.
Definition order.hpp:1055
WtShortLexCompare & init(std::vector< size_t > const &weights, bool should_check)
Reinitialize an existing WtShortLexCompare object.
Definition order.hpp:905
bool should_check() const noexcept
Returns the value of the constructor parameter should_check.
Definition order.hpp:1023
WtShortLexCompare & should_check(bool val) noexcept
Set the value of the constructor parameter should_check.
Definition order.hpp:1041
WtShortLexCompare & weights(std::vector< size_t > const &val)
Set the weights.
Definition order.hpp:1070
static constexpr bool no_checks
Constant to disable validity checks.
Definition order.hpp:874