libsemigroups  v3.0.0
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
169 namespace detail {
170
171 template <typename T>
172 struct IsBipartitionHelper : std::false_type {};
173
174 template <>
175 struct IsBipartitionHelper<Bipartition> : std::true_type {};
176
177 } // namespace detail
178
186 template <typename T>
187 static constexpr bool IsBipartition
188 = detail::IsBipartitionHelper<std::decay_t<T>>::value;
189
190 namespace detail {
191
193 template <typename BipartitionOrBlocks, typename Scalar>
194 static void
195 throw_if_bad_args(std::vector<std::vector<Scalar>> const& blocks) {
196 static_assert(std::is_same_v<BipartitionOrBlocks, Bipartition>
197 || std::is_same_v<BipartitionOrBlocks, Blocks>);
198 static_assert(std::is_signed<Scalar>::value,
199 "the 2nd template parameter Scalar must be signed");
200 int32_t offset = 2;
202 offset = 1;
203 }
204 int32_t m = 0;
205 int32_t deg = 0;
207 for (size_t i = 0; i < blocks.size(); ++i) {
208 auto const& block = blocks[i];
209 if (block.empty()) {
210 LIBSEMIGROUPS_EXCEPTION("the argument (blocks) is invalid, "
211 "expected all blocks to be non-empty, but "
212 "found empty block in position {}",
213 i);
214 }
215 bool positive = block[0] >= 0;
216
217 for (size_t j = 0; j < block.size(); ++j) {
218 auto x = block[j];
219 vals.insert(x);
220 if (x == 0) {
221 LIBSEMIGROUPS_EXCEPTION("the argument (blocks) is invalid, "
222 "expected non-zero values but found 0 in "
223 "position {} of the block with index {}",
224 j,
225 i);
226 } else if (!IsBipartition<BipartitionOrBlocks> && positive && x < 0) {
228 "the argument (blocks) is invalid, expected every value in the "
229 "block with index {} to be {}tive, but found {} in position {}",
230 i,
231 positive ? "posi" : "nega",
232 x,
233 j);
234 }
235 x = std::abs(x);
236
237 m = std::max(x, m);
238 deg++;
239 }
240 }
241
242 if (m >= static_cast<int32_t>(0x40000000)) {
244 "too many points, expected at most {}, found {}", 0x40000000, m);
245 } else if (deg != offset * m || vals.size() != size_t(deg)) {
246 std::string range, prefix;
248 prefix = "the union of";
249 range = fmt::format("{{{}, ..., -1, 1, ..., {}}}", -m, m);
250 } else {
251 prefix
252 = "the set consisting of the absolute values of the entries in ";
253 range = fmt::format("[1, {}]", m);
254 }
255 LIBSEMIGROUPS_EXCEPTION("{} the given blocks is not {},"
256 " only {} values were given",
257 prefix,
258 range,
259 deg);
260 }
261 }
262
264 template <typename BipartitionOrBlocks, typename Scalar>
265 static void throw_if_bad_args(
268 throw_if_bad_args<BipartitionOrBlocks>(arg);
269 }
270
272 template <typename BipartitionOrBlocks, typename Scalar>
273 static void throw_if_bad_args(std::vector<Scalar> const&) {
274 // checks for this argument type are done in throw_if_invalid
275 }
276
278 template <typename BipartitionOrBlocks, typename Scalar>
279 static void throw_if_bad_args(std::initializer_list<Scalar> const&) {
280 // checks for this argument type are done in throw_if_invalid
281 }
282 } // namespace detail
283
301 class Blocks {
302 private:
303 std::vector<uint32_t> _blocks;
304 std::vector<bool> _lookup;
305
306 public:
311
316
321
331 Blocks() noexcept = default;
332
353
363 explicit Blocks(size_t degree) : _blocks(degree), _lookup() {}
364
384 // TODO(0) this should be a make function not a constructor
386
390 Blocks& operator=(Blocks const&) = default;
391
395 Blocks& operator=(Blocks&&) = default;
396
400 Blocks(Blocks const& copy) = default;
401
405 Blocks(Blocks&& copy) = default;
406
407 ~Blocks();
408
426 LIBSEMIGROUPS_ASSERT(i < _lookup.size());
427 _lookup[i] = val;
428 return *this;
429 }
430
444 Blocks& is_transverse_block(size_t i, bool val) {
445 throw_if_class_index_out_of_range(i);
446 return is_transverse_block_no_checks(i, val);
447 }
448
467 [[nodiscard]] bool is_transverse_block_no_checks(size_t index) const {
468 LIBSEMIGROUPS_ASSERT(index < _lookup.size());
469 return _lookup[index];
470 }
471
487 [[nodiscard]] bool is_transverse_block(size_t index) const {
488 throw_if_class_index_out_of_range(index);
489 return is_transverse_block_no_checks(index);
490 }
491
508 Blocks& block_no_checks(size_t i, uint32_t val);
509
523 Blocks& block(size_t i, uint32_t val);
524
540 [[nodiscard]] bool operator==(Blocks const& that) const {
541 return _blocks == that._blocks && _lookup == that._lookup;
542 }
543
559 [[nodiscard]] bool operator!=(Blocks const& that) const {
560 return !(*this == that);
561 }
562
577 [[nodiscard]] bool operator<(Blocks const& that) const;
578
579 // TODO(2) operator<=, operator>, operator>=
580
591 [[nodiscard]] uint32_t degree() const noexcept {
592 return _blocks.size();
593 }
594
607 [[nodiscard]] uint32_t number_of_blocks() const noexcept {
608 return _lookup.size();
609 }
610
623 [[nodiscard]] uint32_t rank() const;
624
636 [[nodiscard]] size_t hash_value() const noexcept;
637
651 [[nodiscard]] lookup_const_iterator cbegin_lookup() const noexcept {
652 return _lookup.cbegin();
653 }
654
659 [[nodiscard]] lookup_const_iterator cend_lookup() const noexcept {
660 return _lookup.cend();
661 }
662
676 [[nodiscard]] std::vector<bool> const& lookup() const noexcept {
677 return _lookup;
678 }
679
690 [[nodiscard]] const_iterator cbegin() const noexcept {
691 return _blocks.cbegin();
692 }
693
704 [[nodiscard]] const_iterator cend() const noexcept {
705 return _blocks.cend();
706 }
707
720 [[nodiscard]] uint32_t const& operator[](size_t i) const {
721 LIBSEMIGROUPS_ASSERT(i < _blocks.size());
722 return _blocks[i];
723 }
724
736 [[nodiscard]] uint32_t const& at(size_t i) const {
737 // TODO(2) better error
738 return _blocks.at(i);
739 }
740
741 private:
742 void throw_if_class_index_out_of_range(size_t index) const;
743 }; // class Blocks
744
769
780
797 template <typename Return, typename Container>
798 [[nodiscard]] enable_if_is_same<Return, Blocks> make(Container const& cont) {
799 detail::throw_if_bad_args<Blocks>(cont);
800 Blocks result(cont);
802 return result;
803 }
804
820 template <typename Return>
825
844 std::string_view braces
845 = "{}",
846 size_t max_width = 72);
847
864 // TODO(2) add more explanation to the doc here
866 private:
867 mutable size_t _nr_blocks;
868 mutable size_t _nr_left_blocks;
869 mutable std::vector<bool> _trans_blocks_lookup;
870 mutable size_t _rank;
871 std::vector<uint32_t> _vector;
872
873 public:
879
885
891
896
902 explicit Bipartition(size_t N);
903
925
935
944
959
963
968
973
978
983
984 ~Bipartition();
985
997 [[nodiscard]] bool operator==(Bipartition const& that) const {
998 return _vector == that._vector;
999 }
1000
1015 [[nodiscard]] bool operator<(Bipartition const& that) const {
1016 return _vector < that._vector;
1017 }
1018
1019 // TODO(2) other operators <=, >, >=, !=
1020
1033 // not noexcept because Hash<T>::operator() isn't
1034 [[nodiscard]] size_t hash_value() const {
1035 return Hash<std::vector<uint32_t>>()(_vector);
1036 }
1037
1052 [[nodiscard]] uint32_t& operator[](size_t i) {
1053 return _vector[i];
1054 }
1055
1071 [[nodiscard]] uint32_t const& operator[](size_t i) const {
1072 return _vector[i];
1073 }
1074
1090 [[nodiscard]] uint32_t& at(size_t i) {
1091 return _vector.at(i);
1092 }
1093
1111 [[nodiscard]] uint32_t const& at(size_t i) const {
1112 return _vector.at(i);
1113 }
1114
1127 [[nodiscard]] const_iterator cbegin() const noexcept {
1128 return _vector.cbegin();
1129 }
1130
1144 [[nodiscard]] const_iterator cend() const noexcept {
1145 return _vector.cend();
1146 }
1147
1161 [[nodiscard]] const_iterator cbegin_left_blocks() const noexcept {
1162 return cbegin();
1163 }
1164
1178 [[nodiscard]] const_iterator cend_left_blocks() const noexcept {
1179 return cbegin() + degree();
1180 }
1181
1195 [[nodiscard]] const_iterator cbegin_right_blocks() const noexcept {
1196 return cend_left_blocks();
1197 }
1198
1212 [[nodiscard]] const_iterator cend_right_blocks() const noexcept {
1213 return cend();
1214 }
1215
1227 [[nodiscard]] size_t degree() const noexcept;
1228
1243 [[nodiscard]] static Bipartition one(size_t n);
1244
1268 Bipartition const& y,
1269 size_t thread_id = 0);
1270
1284 [[nodiscard]] size_t rank() const;
1285
1298 [[nodiscard]] uint32_t number_of_blocks() const;
1299
1314 [[nodiscard]] uint32_t number_of_left_blocks() const;
1315
1330 [[nodiscard]] uint32_t number_of_right_blocks() const;
1331
1348 [[nodiscard]] bool is_transverse_block_no_checks(size_t index) const;
1349
1364 [[nodiscard]] bool is_transverse_block(size_t index) const;
1365
1379 // TODO(2) remove this
1380 [[nodiscard]] Blocks* left_blocks() const;
1381
1396 [[nodiscard]] Blocks* left_blocks_no_checks() const;
1397
1410 // TODO(2) remove this
1411 [[nodiscard]] Blocks* right_blocks() const;
1412
1426 [[nodiscard]] Blocks* right_blocks_no_checks() const;
1427
1440 void set_number_of_blocks(size_t n) noexcept;
1441
1454 void set_number_of_left_blocks(size_t n) noexcept;
1455
1468 void set_rank(size_t n) noexcept;
1469
1483 [[nodiscard]] lookup_const_iterator cbegin_lookup() const noexcept {
1484 init_trans_blocks_lookup();
1485 return _trans_blocks_lookup.cbegin();
1486 }
1487
1492 [[nodiscard]] lookup_const_iterator cend_lookup() const noexcept {
1493 init_trans_blocks_lookup();
1494 return _trans_blocks_lookup.cend();
1495 }
1496
1510 [[nodiscard]] std::vector<bool> const& lookup() const noexcept {
1511 return _trans_blocks_lookup;
1512 }
1513
1514 private:
1515 void init_trans_blocks_lookup() const;
1516 }; // class Bipartition
1517
1528
1545 template <typename Return, typename Container>
1547 make(Container const& cont) {
1548 detail::throw_if_bad_args<Bipartition>(cont);
1549 Bipartition result(cont);
1551 return result;
1552 }
1553
1559 template <typename Return>
1564
1568 template <typename Return>
1573
1594 std::string_view braces
1595 = "{}",
1596 size_t max_width = 72);
1597
1619 [[nodiscard]] Bipartition operator*(Bipartition const& x,
1620 Bipartition const& y);
1621
1637 [[nodiscard]] inline bool operator!=(Bipartition const& x,
1638 Bipartition const& y) {
1639 return !(x == y);
1640 }
1641
1647 [[nodiscard]] inline bool operator<=(Bipartition const& x,
1648 Bipartition const& y) {
1649 return x < y || x == y;
1650 }
1651
1658 [[nodiscard]] inline bool operator>(Bipartition const& x,
1659 Bipartition const& y) {
1660 return y < x;
1661 }
1662
1669 [[nodiscard]] inline bool operator>=(Bipartition const& x,
1670 Bipartition const& y) {
1671 return y <= x;
1672 }
1673
1675 // Adapters
1677
1682 template <>
1697 [[nodiscard]] size_t operator()(Bipartition const& x) const noexcept {
1698 return x.degree() * x.degree();
1699 }
1700 };
1701
1702 template <>
1703 struct Degree<Bipartition> {
1704 [[nodiscard]] size_t operator()(Bipartition const& x) const noexcept {
1705 return x.degree();
1706 }
1707 };
1708
1709 template <>
1710 struct Hash<Bipartition> {
1711 [[nodiscard]] size_t operator()(Bipartition const& x) const {
1712 return x.hash_value();
1713 }
1714 };
1715
1716 template <>
1717 struct One<Bipartition> {
1718 [[nodiscard]] Bipartition operator()(Bipartition const& x) const {
1719 return (*this)(x.degree());
1720 }
1721
1722 [[nodiscard]] Bipartition operator()(size_t N = 0) const {
1723 return Bipartition::one(N);
1724 }
1725 };
1726
1727 template <>
1728 struct Product<Bipartition> {
1729 void operator()(Bipartition& xy,
1730 Bipartition const& x,
1731 Bipartition const& y,
1732 size_t thread_id = 0) {
1733 xy.product_inplace_no_checks(x, y, thread_id);
1734 }
1735 };
1736
1737 template <>
1738 struct IncreaseDegree<Bipartition> {
1739 void operator()(Bipartition&, size_t) {}
1740 };
1741
1742} // namespace libsemigroups
1743#endif // LIBSEMIGROUPS_BIPART_HPP_
Class for representing bipartitions.
Definition bipart.hpp:865
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:1015
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:1052
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:890
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:884
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:1071
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:1212
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:1492
std::vector< uint32_t >::iterator iterator
Type of iterators pointing to block lookup.
Definition bipart.hpp:878
bool operator==(Bipartition const &that) const
Compare bipartitions for equality.
Definition bipart.hpp:997
std::vector< bool > const & lookup() const noexcept
Return a const reference to the transverse blocks lookup.
Definition bipart.hpp:1510
const_iterator cbegin_left_blocks() const noexcept
Const iterator pointing to the index of the first left block.
Definition bipart.hpp:1161
const_iterator cend() const noexcept
Return a const iterator pointing one beyond the last index of the last block.
Definition bipart.hpp:1144
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:1178
uint32_t const & at(size_t i) const
Return a const reference to the index of the block containing a value.
Definition bipart.hpp:1111
lookup_const_iterator cbegin_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:1483
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:1127
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:1034
const_iterator cbegin_right_blocks() const noexcept
Const iterator pointing to the index of the first right block.
Definition bipart.hpp:1195
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:1090
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:301
Blocks & operator=(Blocks const &)=default
Default copy assignment operator.
Blocks(Blocks &&copy)=default
Default move constructor.
bool operator==(Blocks const &that) const
Compare two blocks objects for equality.
Definition bipart.hpp:540
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:720
Blocks & block_no_checks(size_t i, uint32_t val)
Set the block that a point belongs to.
bool is_transverse_block(size_t index) const
Check if a block is a transverse block.
Definition bipart.hpp:487
Blocks(Blocks const &copy)=default
Default copy constructor.
typename std::vector< uint32_t >::iterator iterator
Type for iterators pointing to the index of the block.
Definition bipart.hpp:315
lookup_const_iterator cend_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:659
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:444
std::vector< bool > const & lookup() const noexcept
Return a const reference to the transverse blocks lookup.
Definition bipart.hpp:676
Blocks() noexcept=default
Constructs a blocks object of size 0.
const_iterator cend() const noexcept
Return a const iterator pointing one past-the-end of the last block.
Definition bipart.hpp:704
std::vector< bool >::const_iterator lookup_const_iterator
Type for const iterators pointing to the transverse block lookup.
Definition bipart.hpp:310
bool is_transverse_block_no_checks(size_t index) const
Check if a block is a transverse block.
Definition bipart.hpp:467
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:425
uint32_t const & at(size_t i) const
Return a const reference to the index of the block containing a point.
Definition bipart.hpp:736
lookup_const_iterator cbegin_lookup() const noexcept
Return a const iterator pointing to the first transverse block lookup.
Definition bipart.hpp:651
const_iterator cbegin() const noexcept
Return a const iterator pointing to the index of the first block.
Definition bipart.hpp:690
uint32_t rank() const
Return the number of transverse blocks.
Blocks & operator=(Blocks &&)=default
Default move assignment operator.
uint32_t number_of_blocks() const noexcept
Return the number of blocks in a Blocks object.
Definition bipart.hpp:607
bool operator!=(Blocks const &that) const
Compare two blocks objects for inequality.
Definition bipart.hpp:559
uint32_t degree() const noexcept
Return the degree of a blocks object.
Definition bipart.hpp:591
typename std::vector< uint32_t >::const_iterator const_iterator
Type for const iterators pointing to the index of the block.
Definition bipart.hpp:320
Blocks & block(size_t i, uint32_t val)
Set the block that a point belongs to.
std::string to_human_readable_repr(AhoCorasick const &ac)
Return a string representation.
bool operator<=(Bipartition const &x, Bipartition const &y)
Compare bipartitions.
Definition bipart.hpp:1647
bool operator>=(Bipartition const &x, Bipartition const &y)
Compare bipartitions.
Definition bipart.hpp:1669
bool operator>(Bipartition const &x, Bipartition const &y)
Compare bipartitions.
Definition bipart.hpp:1658
Bipartition operator*(Bipartition const &x, Bipartition const &y)
Multiply two bipartitions.
static constexpr bool IsBipartition
Helper variable template.
Definition bipart.hpp:188
bool operator!=(Bipartition const &x, Bipartition const &y)
Check bipartitions for inequality.
Definition bipart.hpp:1637
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:95
enable_if_is_same< Return, Blocks > make(Container const &cont)
Check the arguments, construct a Blocks object, and check it.
Definition bipart.hpp:798
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:50
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:1697
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