libsemigroups  v3.1.3
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
bipart.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2021-2025 James D. Mitchell
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 declaration of the Bipartition and Blocks classes.
20
21#ifndef LIBSEMIGROUPS_BIPART_HPP_
22#define LIBSEMIGROUPS_BIPART_HPP_
23
24// TODO(2)
25// * benchmarks
26// * use Duf/Suf where possible (later?)
27// * template like transformations/pperms etc (later?)
28
29#include <algorithm> // for max
30#include <cstddef> // for size_t
31#include <cstdint> // for uint32_t, int32_t
32#include <cstdlib> // for abs
33#include <initializer_list> // for initializer_list
34#include <string_view> // for string_view
35#include <type_traits> // for decay_t, false_type, is_signed, true_type
36#include <unordered_set> // for unordered_set
37#include <vector> // for vector
38
39#include "adapters.hpp" // for Hash
40#include "debug.hpp" // for LIBSEMIGROUPS_ASSERT
41#include "exception.hpp" // for LIBSEMIGROUPS_EXCEPTION
42#include "types.hpp" // for enable_if_is_same
43
44#include "detail/fmt.hpp"
45
46namespace libsemigroups {
57
58 // Forward decls
59 class Bipartition;
60 class Blocks;
61
67 namespace blocks {
87 void throw_if_invalid(Blocks const& x);
88
110
111 } // namespace blocks
112
118 namespace bipartition {
133 [[nodiscard]] Bipartition one(Bipartition const& f);
134
156
166
167 } // namespace bipartition
168
178 template <typename Thing>
179 static constexpr bool IsBipartition [[deprecated]]
180 = std::is_same_v<std::decay_t<Thing>, Bipartition>;
181
182 namespace detail {
183
185 template <typename Thing, typename Scalar>
186 static void
187 throw_if_bad_args(std::vector<std::vector<Scalar>> const& blocks) {
188 static_assert(std::is_same_v<Thing, Bipartition>
189 || std::is_same_v<Thing, Blocks>);
190 static_assert(std::is_signed<Scalar>::value,
191 "the 2nd template parameter Scalar must be signed");
192 int32_t offset = 2;
193 if (!std::is_same_v<Thing, Bipartition>) {
194 offset = 1;
195 }
196 int32_t m = 0;
197 int32_t deg = 0;
199 for (size_t i = 0; i < blocks.size(); ++i) {
200 auto const& block = blocks[i];
201 if (block.empty()) {
202 LIBSEMIGROUPS_EXCEPTION("the argument (blocks) is invalid, "
203 "expected all blocks to be non-empty, but "
204 "found empty block in position {}",
205 i);
206 }
207 bool positive = block[0] >= 0;
208
209 for (size_t j = 0; j < block.size(); ++j) {
210 auto x = block[j];
211 vals.insert(x);
212 if (x == 0) {
213 LIBSEMIGROUPS_EXCEPTION("the argument (blocks) is invalid, "
214 "expected non-zero values but found 0 in "
215 "position {} of the block with index {}",
216 j,
217 i);
218 } else if (!std::is_same_v<Thing, Bipartition> && positive && x < 0) {
220 "the argument (blocks) is invalid, expected every value in the "
221 "block with index {} to be {}tive, but found {} in position {}",
222 i,
223 positive ? "posi" : "nega",
224 x,
225 j);
226 }
227 x = std::abs(x);
228
229 m = std::max(x, m);
230 deg++;
231 }
232 }
233
234 if (m >= static_cast<int32_t>(0x40000000)) {
236 "too many points, expected at most {}, found {}", 0x40000000, m);
237 } else if (deg != offset * m || vals.size() != size_t(deg)) {
238 std::string range, prefix;
239 if (std::is_same_v<Thing, Bipartition>) {
240 prefix = "the union of";
241 range = fmt::format("{{{}, ..., -1, 1, ..., {}}}", -m, m);
242 } else {
243 prefix
244 = "the set consisting of the absolute values of the entries in ";
245 range = fmt::format("[1, {}]", m);
246 }
247 LIBSEMIGROUPS_EXCEPTION("{} the given blocks is not {},"
248 " only {} values were given",
249 prefix,
250 range,
251 deg);
252 }
253 }
254
256 template <typename Thing, typename Scalar>
257 static void throw_if_bad_args(
260 throw_if_bad_args<Thing>(arg);
261 }
262
264 template <typename Thing, typename Scalar>
265 static void throw_if_bad_args(std::vector<Scalar> const&) {
266 // checks for this argument type are done in throw_if_invalid
267 }
268
270 template <typename Thing, typename Scalar>
271 static void throw_if_bad_args(std::initializer_list<Scalar> const&) {
272 // checks for this argument type are done in throw_if_invalid
273 }
274 } // namespace detail
275
293 class Blocks {
294 private:
295 std::vector<uint32_t> _blocks;
296 std::vector<bool> _lookup;
297
298 public:
303
308
313
323 Blocks() noexcept;
324
345
355 explicit Blocks(size_t degree) : _blocks(degree), _lookup() {}
356
376 // TODO(0) this should be a make function not a constructor
378
383
388
392 Blocks(Blocks const& copy);
393
397 Blocks(Blocks&& copy);
398
399 ~Blocks();
400
418 LIBSEMIGROUPS_ASSERT(i < _lookup.size());
419 _lookup[i] = val;
420 return *this;
421 }
422
436 Blocks& is_transverse_block(size_t i, bool val) {
437 throw_if_class_index_out_of_range(i);
438 return is_transverse_block_no_checks(i, val);
439 }
440
459 [[nodiscard]] bool is_transverse_block_no_checks(size_t index) const {
460 LIBSEMIGROUPS_ASSERT(index < _lookup.size());
461 return _lookup[index];
462 }
463
479 [[nodiscard]] bool is_transverse_block(size_t index) const {
480 throw_if_class_index_out_of_range(index);
481 return is_transverse_block_no_checks(index);
482 }
483
500 Blocks& block_no_checks(size_t i, uint32_t val);
501
515 Blocks& block(size_t i, uint32_t val);
516
532 [[nodiscard]] bool operator==(Blocks const& that) const {
533 return _blocks == that._blocks && _lookup == that._lookup;
534 }
535
551 [[nodiscard]] bool operator!=(Blocks const& that) const {
552 return !(*this == that);
553 }
554
569 [[nodiscard]] bool operator<(Blocks const& that) const;
570
571 // TODO(2) operator<=, operator>, operator>=
572
583 [[nodiscard]] uint32_t degree() const noexcept {
584 return _blocks.size();
585 }
586
599 [[nodiscard]] uint32_t number_of_blocks() const noexcept {
600 return _lookup.size();
601 }
602
615 [[nodiscard]] uint32_t rank() const;
616
628 [[nodiscard]] size_t hash_value() const noexcept;
629
643 [[nodiscard]] lookup_const_iterator cbegin_lookup() const noexcept {
644 return _lookup.cbegin();
645 }
646
651 [[nodiscard]] lookup_const_iterator cend_lookup() const noexcept {
652 return _lookup.cend();
653 }
654
668 [[nodiscard]] std::vector<bool> const& lookup() const noexcept {
669 return _lookup;
670 }
671
682 [[nodiscard]] const_iterator cbegin() const noexcept {
683 return _blocks.cbegin();
684 }
685
696 [[nodiscard]] const_iterator cend() const noexcept {
697 return _blocks.cend();
698 }
699
712 [[nodiscard]] uint32_t const& operator[](size_t i) const {
713 LIBSEMIGROUPS_ASSERT(i < _blocks.size());
714 return _blocks[i];
715 }
716
728 [[nodiscard]] uint32_t const& at(size_t i) const {
729 // TODO(2) better error
730 return _blocks.at(i);
731 }
732
733 private:
734 void throw_if_class_index_out_of_range(size_t index) const;
735 }; // class Blocks
736
761
772
789 template <typename Return, typename Container>
790 [[nodiscard]] enable_if_is_same<Return, Blocks> make(Container const& cont) {
791 detail::throw_if_bad_args<Blocks>(cont);
792 Blocks result(cont);
794 return result;
795 }
796
812 template <typename Return>
817
836 std::string_view braces
837 = "{}",
838 size_t max_width = 72);
839
856 // TODO(2) add more explanation to the doc here
858 private:
859 mutable size_t _nr_blocks;
860 mutable size_t _nr_left_blocks;
861 mutable std::vector<bool> _trans_blocks_lookup;
862 mutable size_t _rank;
863 std::vector<uint32_t> _vector;
864
865 public:
871
877
883
888
894 explicit Bipartition(size_t N);
895
917
927
936
951
955
960
965
970
975
976 ~Bipartition();
977
989 [[nodiscard]] bool operator==(Bipartition const& that) const {
990 return _vector == that._vector;
991 }
992
1007 [[nodiscard]] bool operator<(Bipartition const& that) const {
1008 return _vector < that._vector;
1009 }
1010
1011 // TODO(2) other operators <=, >, >=, !=
1012
1025 // not noexcept because Hash<T>::operator() isn't
1026 [[nodiscard]] size_t hash_value() const {
1027 return Hash<std::vector<uint32_t>>()(_vector);
1028 }
1029
1044 [[nodiscard]] uint32_t& operator[](size_t i) {
1045 return _vector[i];
1046 }
1047
1063 [[nodiscard]] uint32_t const& operator[](size_t i) const {
1064 return _vector[i];
1065 }
1066
1082 [[nodiscard]] uint32_t& at(size_t i) {
1083 return _vector.at(i);
1084 }
1085
1103 [[nodiscard]] uint32_t const& at(size_t i) const {
1104 return _vector.at(i);
1105 }
1106
1119 [[nodiscard]] const_iterator cbegin() const noexcept {
1120 return _vector.cbegin();
1121 }
1122
1136 [[nodiscard]] const_iterator cend() const noexcept {
1137 return _vector.cend();
1138 }
1139
1153 [[nodiscard]] const_iterator cbegin_left_blocks() const noexcept {
1154 return cbegin();
1155 }
1156
1170 [[nodiscard]] const_iterator cend_left_blocks() const noexcept {
1171 return cbegin() + degree();
1172 }
1173
1187 [[nodiscard]] const_iterator cbegin_right_blocks() const noexcept {
1188 return cend_left_blocks();
1189 }
1190
1204 [[nodiscard]] const_iterator cend_right_blocks() const noexcept {
1205 return cend();
1206 }
1207
1219 [[nodiscard]] size_t degree() const noexcept;
1220
1235 [[nodiscard]] static Bipartition one(size_t n);
1236
1260 Bipartition const& y,
1261 size_t thread_id = 0);
1262
1276 [[nodiscard]] size_t rank() const;
1277
1290 [[nodiscard]] uint32_t number_of_blocks() const;
1291
1306 [[nodiscard]] uint32_t number_of_left_blocks() const;
1307
1322 [[nodiscard]] uint32_t number_of_right_blocks() const;
1323
1340 [[nodiscard]] bool is_transverse_block_no_checks(size_t index) const;
1341
1356 [[nodiscard]] bool is_transverse_block(size_t index) const;
1357
1371 // TODO(2) remove this
1372 [[nodiscard]] Blocks* left_blocks() const;
1373
1388 [[nodiscard]] Blocks* left_blocks_no_checks() const;
1389
1402 // TODO(2) remove this
1403 [[nodiscard]] Blocks* right_blocks() const;
1404
1418 [[nodiscard]] Blocks* right_blocks_no_checks() const;
1419
1432 void set_number_of_blocks(size_t n) noexcept;
1433
1446 void set_number_of_left_blocks(size_t n) noexcept;
1447
1460 void set_rank(size_t n) noexcept;
1461
1475 [[nodiscard]] lookup_const_iterator cbegin_lookup() const noexcept {
1476 init_trans_blocks_lookup();
1477 return _trans_blocks_lookup.cbegin();
1478 }
1479
1484 [[nodiscard]] lookup_const_iterator cend_lookup() const noexcept {
1485 init_trans_blocks_lookup();
1486 return _trans_blocks_lookup.cend();
1487 }
1488
1502 [[nodiscard]] std::vector<bool> const& lookup() const noexcept {
1503 return _trans_blocks_lookup;
1504 }
1505
1506 private:
1507 void init_trans_blocks_lookup() const;
1508 }; // class Bipartition
1509
1520
1537 template <typename Return, typename Container>
1539 make(Container const& cont) {
1540 detail::throw_if_bad_args<Bipartition>(cont);
1541 Bipartition result(cont);
1543 return result;
1544 }
1545
1551 template <typename Return>
1556
1560 template <typename Return>
1565
1586 std::string_view braces
1587 = "{}",
1588 size_t max_width = 72);
1589
1611 [[nodiscard]] Bipartition operator*(Bipartition const& x,
1612 Bipartition const& y);
1613
1629 [[nodiscard]] inline bool operator!=(Bipartition const& x,
1630 Bipartition const& y) {
1631 return !(x == y);
1632 }
1633
1639 [[nodiscard]] inline bool operator<=(Bipartition const& x,
1640 Bipartition const& y) {
1641 return x < y || x == y;
1642 }
1643
1650 [[nodiscard]] inline bool operator>(Bipartition const& x,
1651 Bipartition const& y) {
1652 return y < x;
1653 }
1654
1661 [[nodiscard]] inline bool operator>=(Bipartition const& x,
1662 Bipartition const& y) {
1663 return y <= x;
1664 }
1665
1667 // Adapters
1669
1674 template <>
1689 [[nodiscard]] size_t operator()(Bipartition const& x) const noexcept {
1690 return x.degree() * x.degree();
1691 }
1692 };
1693
1694 template <>
1695 struct Degree<Bipartition> {
1696 [[nodiscard]] size_t operator()(Bipartition const& x) const noexcept {
1697 return x.degree();
1698 }
1699 };
1700
1701 template <>
1702 struct Hash<Bipartition> {
1703 [[nodiscard]] size_t operator()(Bipartition const& x) const {
1704 return x.hash_value();
1705 }
1706 };
1707
1708 template <>
1709 struct One<Bipartition> {
1710 [[nodiscard]] Bipartition operator()(Bipartition const& x) const {
1711 return (*this)(x.degree());
1712 }
1713
1714 [[nodiscard]] Bipartition operator()(size_t N = 0) const {
1715 return Bipartition::one(N);
1716 }
1717 };
1718
1719 template <>
1720 struct Product<Bipartition> {
1721 void operator()(Bipartition& xy,
1722 Bipartition const& x,
1723 Bipartition const& y,
1724 size_t thread_id = 0) {
1725 xy.product_inplace_no_checks(x, y, thread_id);
1726 }
1727 };
1728
1729 template <>
1730 struct IncreaseDegree<Bipartition> {
1731 void operator()(Bipartition&, size_t) {}
1732 };
1733
1734} // namespace libsemigroups
1735#endif // LIBSEMIGROUPS_BIPART_HPP_
Class for representing bipartitions.
Definition bipart.hpp:857
size_t rank() const
Return the number of transverse blocks.
Bipartition(std::vector< std::vector< int32_t > > const &blocks)
Construct a bipartition from a partition.
bool operator<(Bipartition const &that) const
Compare bipartitions for less.
Definition bipart.hpp:1007
void set_number_of_left_blocks(size_t n) noexcept
Set the number of left blocks.
uint32_t & operator[](size_t i)
Return the index of the block containing a value.
Definition bipart.hpp:1044
uint32_t number_of_blocks() const
Return the number of blocks in a Bipartition.
typename std::vector< bool >::const_iterator lookup_const_iterator
Type of const iterators pointing to transverse blocks lookup.
Definition bipart.hpp:882
Bipartition(std::vector< uint32_t > const &blocks)
Construct a bipartition from a const reference to blocks lookup.
std::vector< uint32_t >::const_iterator const_iterator
Type of const iterators pointing to block lookup.
Definition bipart.hpp:876
Blocks * left_blocks_no_checks() const
Return a pointer to the left blocks of a bipartition.
Blocks * right_blocks() const
Return a pointer to the right blocks of a bipartition.
uint32_t const & operator[](size_t i) const
Return the index of the block containing a value.
Definition bipart.hpp:1063
Blocks * left_blocks() const
Return a pointer to the left blocks of a bipartition.
Bipartition & operator=(Bipartition const &)
Default copy assignment operator.
uint32_t number_of_right_blocks() const
Return the number of blocks containing a negative integer.
size_t degree() const noexcept
Return the degree of the bipartition.
void product_inplace_no_checks(Bipartition const &x, Bipartition const &y, size_t thread_id=0)
Modify the current bipartition in-place to contain the product of two bipartitions.
Bipartition()
Construct an uninitialised bipartition of degree 0.
void set_number_of_blocks(size_t n) noexcept
Set the number of blocks.
const_iterator cend_right_blocks() const noexcept
Const iterator pointing one beyond the last index of the last right block.
Definition bipart.hpp:1204
void set_rank(size_t n) noexcept
Set the rank.
bool is_transverse_block(size_t index) const
Check if a block is a transverse block.
uint32_t number_of_left_blocks() const
Return the number of blocks containing a positive integer.
lookup_const_iterator cend_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:1484
std::vector< uint32_t >::iterator iterator
Type of iterators pointing to block lookup.
Definition bipart.hpp:870
bool operator==(Bipartition const &that) const
Compare bipartitions for equality.
Definition bipart.hpp:989
std::vector< bool > const & lookup() const noexcept
Return a const reference to the transverse blocks lookup.
Definition bipart.hpp:1502
const_iterator cbegin_left_blocks() const noexcept
Const iterator pointing to the index of the first left block.
Definition bipart.hpp:1153
const_iterator cend() const noexcept
Return a const iterator pointing one beyond the last index of the last block.
Definition bipart.hpp:1136
bool is_transverse_block_no_checks(size_t index) const
Check if a block is a transverse block.
Bipartition(Bipartition &&)
Default move constructor.
const_iterator cend_left_blocks() const noexcept
Const iterator pointing one beyond the last index of the last left block.
Definition bipart.hpp:1170
uint32_t const & at(size_t i) const
Return a const reference to the index of the block containing a value.
Definition bipart.hpp:1103
lookup_const_iterator cbegin_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:1475
Bipartition(size_t N)
Construct an uninitialised bipartition of given degree.
Bipartition(std::initializer_list< uint32_t > const &blocks)
Construct a bipartition from an initializer list blocks lookup.
const_iterator cbegin() const noexcept
Return a const iterator pointing to the index of the first block.
Definition bipart.hpp:1119
static Bipartition one(size_t n)
Return an identity bipartition of given degree.
Bipartition & operator=(Bipartition &&)
Default move assignment operator.
Bipartition(Bipartition const &)
Default copy constructor.
Bipartition(std::vector< uint32_t > &&blocks)
Construct a bipartition from an rvalue reference to blocks lookup.
size_t hash_value() const
Return a hash value.
Definition bipart.hpp:1026
const_iterator cbegin_right_blocks() const noexcept
Const iterator pointing to the index of the first right block.
Definition bipart.hpp:1187
Bipartition(std::initializer_list< std::vector< int32_t > > const &blocks)
Construct a bipartition from a partition.
uint32_t & at(size_t i)
Return a reference to the index of the block containing a value.
Definition bipart.hpp:1082
Blocks * right_blocks_no_checks() const
Return a pointer to the right blocks of a bipartition.
A Blocks object represents a signed partition of the set .
Definition bipart.hpp:293
Blocks & operator=(Blocks const &)
Default copy assignment operator.
bool operator==(Blocks const &that) const
Compare two blocks objects for equality.
Definition bipart.hpp:532
Blocks(std::vector< std::vector< int32_t > > const &blocks)
Constructs a Blocks object from a vector of vectors of integers.
uint32_t const & operator[](size_t i) const
Return a const reference to the index of the block containing a point.
Definition bipart.hpp:712
Blocks & block_no_checks(size_t i, uint32_t val)
Set the block that a point belongs to.
Blocks & operator=(Blocks &&)
Default move assignment operator.
Blocks() noexcept
Constructs a blocks object of size 0.
bool is_transverse_block(size_t index) const
Check if a block is a transverse block.
Definition bipart.hpp:479
typename std::vector< uint32_t >::iterator iterator
Type for iterators pointing to the index of the block.
Definition bipart.hpp:307
lookup_const_iterator cend_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:651
size_t hash_value() const noexcept
Return a hash value for a Blocks instance.
Blocks & is_transverse_block(size_t i, bool val)
Set whether or not the block containing a point is transverse.
Definition bipart.hpp:436
std::vector< bool > const & lookup() const noexcept
Return a const reference to the transverse blocks lookup.
Definition bipart.hpp:668
const_iterator cend() const noexcept
Return a const iterator pointing one past-the-end of the last block.
Definition bipart.hpp:696
std::vector< bool >::const_iterator lookup_const_iterator
Type for const iterators pointing to the transverse block lookup.
Definition bipart.hpp:302
bool is_transverse_block_no_checks(size_t index) const
Check if a block is a transverse block.
Definition bipart.hpp:459
bool operator<(Blocks const &that) const
Compare two blocks objects for less.
Blocks & is_transverse_block_no_checks(size_t i, bool val)
Set whether or not the block containing a point is transverse.
Definition bipart.hpp:417
uint32_t const & at(size_t i) const
Return a const reference to the index of the block containing a point.
Definition bipart.hpp:728
lookup_const_iterator cbegin_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:643
Blocks(Blocks const &copy)
Default copy constructor.
const_iterator cbegin() const noexcept
Return a const iterator pointing to the index of the first block.
Definition bipart.hpp:682
uint32_t rank() const
Return the number of transverse blocks.
uint32_t number_of_blocks() const noexcept
Return the number of blocks in a Blocks object.
Definition bipart.hpp:599
bool operator!=(Blocks const &that) const
Compare two blocks objects for inequality.
Definition bipart.hpp:551
uint32_t degree() const noexcept
Return the degree of a blocks object.
Definition bipart.hpp:583
Blocks(Blocks &&copy)
Default move constructor.
typename std::vector< uint32_t >::const_iterator const_iterator
Type for const iterators pointing to the index of the block.
Definition bipart.hpp:312
Blocks & block(size_t i, uint32_t val)
Set the block that a point belongs to.
std::string to_human_readable_repr(Action< Element, Point, Func, Traits, LeftOrRight > const &action)
Return a human readable representation of an Action object.
bool operator<=(Bipartition const &x, Bipartition const &y)
Compare bipartitions.
Definition bipart.hpp:1639
bool operator>=(Bipartition const &x, Bipartition const &y)
Compare bipartitions.
Definition bipart.hpp:1661
bool operator>(Bipartition const &x, Bipartition const &y)
Compare bipartitions.
Definition bipart.hpp:1650
Bipartition operator*(Bipartition const &x, Bipartition const &y)
Multiply two bipartitions.
static constexpr bool IsBipartition
Helper variable template.
Definition bipart.hpp:180
bool operator!=(Bipartition const &x, Bipartition const &y)
Check bipartitions for inequality.
Definition bipart.hpp:1629
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:99
enable_if_is_same< Return, Blocks > make(Container const &cont)
Check the arguments, construct a Blocks object, and check it.
Definition bipart.hpp:790
std::enable_if_t< std::is_same_v< Given, Expected >, Expected > enable_if_is_same
Alias equal to the second template parameter if both template parameters are equal.
Definition types.hpp:48
T insert(T... args)
T max(T... args)
Namespace for Bipartition helper functions.
Definition bipart.hpp:118
std::vector< std::vector< int32_t > > underlying_partition(Bipartition const &x)
Return the underlying partition of a Bipartition object.
Bipartition one(Bipartition const &f)
Return the identity bipartition with the same degree as the given bipartition.
void throw_if_invalid(Bipartition const &x)
Checks a bipartition.
Namespace for Blocks helper functions.
Definition bipart.hpp:67
void throw_if_invalid(Blocks const &x)
Check a Blocks object.
std::vector< std::vector< int32_t > > underlying_partition(Blocks const &x)
Return the underlying partition of a Blocks object.
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
T size(T... args)
size_t operator()(Bipartition const &x) const noexcept
Definition bipart.hpp:1689
Adapter for the complexity of multiplication.
Definition adapters.hpp:121
Adapter for hashing.
Definition adapters.hpp:446
size_t operator()(Value const &x) const
Hash x using std::hash.
Definition adapters.hpp:455
Adapter for increasing the degree of an element.
Definition adapters.hpp:199
Adapter for the identity element of the given type.
Definition adapters.hpp:246
Adapter for the product of two elements.
Definition adapters.hpp:284