libsemigroups  v3.3.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
froidure-pin.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2019-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#ifndef LIBSEMIGROUPS_FROIDURE_PIN_HPP_
20#define LIBSEMIGROUPS_FROIDURE_PIN_HPP_
21
22#include <cstddef> // for size_t
23#include <initializer_list> // for initializer_list
24#include <iterator> // for make_move_iterator
25#include <memory> // for shared_ptr, make_shared
26#include <mutex> // for mutex
27#include <type_traits> // for is_const, remove_pointer
28#include <unordered_map> // for unordered_map
29#include <utility> // for pair
30#include <vector> // for vector
31
32#include "adapters.hpp" // for Complexity, Degree, IncreaseDegree
33#include "debug.hpp" // for LIBSEMIGROUPS_ASSERT
34#include "exception.hpp" // for LIBSEMIGROUPS_EXCEPTION
35#include "froidure-pin-base.hpp" // for FroidurePinBase, FroidurePinBase::s...
36#include "types.hpp" // for letter_type, word_type
37
38#include "detail/bruidhinn-traits.hpp" // for detail::BruidhinnTraits
39#include "detail/iterator.hpp" // for ConstIteratorStateless
40#include "detail/report.hpp" // for report_default
41#include "detail/stl.hpp" // for EqualTo, Hash
42
43#include "rx/ranges.hpp" // for iterator_range
44
46namespace libsemigroups {
47
48 template <typename T>
49 struct FroidurePinState {
50 using type = void;
51 };
52
66 template <typename Element,
67 typename State = typename FroidurePinState<Element>::type>
69 // Require to get the value_type from detail::BruidhinnTraits to remove
70 // pointer to const.
75 using element_type = typename detail::BruidhinnTraits<Element>::value_type;
76
81 using state_type = State;
82
85
88
91
94
97
100
103
106
109 };
110
188 template <typename Element, typename Traits = FroidurePinTraits<Element>>
189 class FroidurePin : private detail::BruidhinnTraits<Element>,
190 public FroidurePinBase {
191 private:
193 // FroidurePin - typedefs - private
195
196 using internal_element_type =
197 typename detail::BruidhinnTraits<Element>::internal_value_type;
198 using internal_const_element_type =
199 typename detail::BruidhinnTraits<Element>::internal_const_value_type;
200 using internal_const_reference =
201 typename detail::BruidhinnTraits<Element>::internal_const_reference;
202 using internal_idempotent_pair
204
205 static_assert(
206 std::is_const_v<internal_const_element_type>
207 || std::is_const_v<
208 std::remove_pointer_t<internal_const_element_type>>,
209 "internal_const_element_type must be const or pointer to const");
210
211 // The elements of a semigroup are stored in _elements, but because of the
212 // way add_generators/closure work, it might not be the case that all the
213 // words of a given length are contiguous in _elements. Hence we require a
214 // means of finding the next element of a given length. In
215 // _enumerate_order, the first K_1 values are element_index_type's equal to
216 // the positions in _elements of the words of length 1, the next K_2 values
217 // are the element_index_type's equal to the positions in _elements of the
218 // words of length 2, and so on.
219 //
220 // This alias is used to distinguish variables that refer to positions in
221 // _elements (element_index_type) from those that refer to positions in
222 // _enumerate_order (enumerate_index_type).
223 using enumerate_index_type = FroidurePinBase::enumerate_index_type;
224
225 struct InternalEqualTo : private detail::BruidhinnTraits<Element> {
226 [[nodiscard]] bool operator()(internal_const_reference x,
227 internal_const_reference y) const {
228 return EqualTo()(this->to_external_const(x),
229 this->to_external_const(y));
230 }
231 };
232
233 struct InternalHash : private detail::BruidhinnTraits<Element> {
234 [[nodiscard]] size_t operator()(internal_const_reference x) const {
235 return Hash()(this->to_external_const(x));
236 }
237 };
238
239 using map_type = std::unordered_map<internal_const_element_type,
241 InternalHash,
242 InternalEqualTo>;
243
244 public:
246 // FroidurePin - typedefs - public
248
250 using element_type = typename detail::BruidhinnTraits<Element>::value_type;
251
253 // This only really exists to allow the python bindings to compile with
254 // gcc-6 + 7 (at least).
255 using value_type = element_type;
256
258 using const_element_type =
259 typename detail::BruidhinnTraits<Element>::const_value_type;
260
262 using const_reference =
263 typename detail::BruidhinnTraits<Element>::const_reference;
264
266 using rvalue_reference =
267 typename detail::BruidhinnTraits<Element>::rvalue_reference;
268
270 using reference = typename detail::BruidhinnTraits<Element>::reference;
271
273 using const_pointer =
274 typename detail::BruidhinnTraits<Element>::const_pointer;
275
278
281
284
286 using state_type = typename Traits::state_type;
287
289 using Complexity = typename Traits::Complexity;
290
292 using Degree = typename Traits::Degree;
293
295 using EqualTo = typename Traits::EqualTo;
296
298 using Hash = typename Traits::Hash;
299
301 using IncreaseDegree = typename Traits::IncreaseDegree;
302
304 using Less = typename Traits::Less;
305
307 using One = typename Traits::One;
308
310 using Product = typename Traits::Product;
311
313 using Swap = typename Traits::Swap;
314
315 private:
316 template <typename T>
317 static constexpr bool IsState
318 = ((!std::is_void_v<T>) &&std::is_same_v<state_type, T>);
319
321 // FroidurePin - data - private
323
326 internal_element_type _id;
328 map_type _map;
329 mutable std::mutex _mtx;
332 mutable internal_element_type _tmp_product;
333
334 void internal_product(reference xy,
337 state_type* stt,
338 size_t tid = 0) const {
339 if constexpr (std::is_void_v<state_type>) {
340 (void) stt; // To silence warnings in g++-9
341 Product()(xy, x, y, tid);
342 } else {
343 Product()(xy, x, y, stt, tid);
344 }
345 }
346
347 public:
349 // FroidurePin - constructors + destructor - public
351
357 FroidurePin();
358
368 FroidurePin& init();
369
382 template <typename State, typename = std::enable_if_t<IsState<State>>>
384 _state = stt;
385 }
386
398 template <typename State, typename = std::enable_if_t<IsState<State>>>
400 init();
401 _state = stt;
402 }
403
420 template <typename State, typename = std::enable_if_t<IsState<State>>>
421 explicit FroidurePin(State const& stt)
422 : FroidurePin(std::make_shared<state_type>(stt)) {}
423
435 template <typename State, typename = std::enable_if_t<IsState<State>>>
436 FroidurePin& init(State const& stt) {
438 }
439
442
444 FroidurePin& operator=(FroidurePin&&) = default;
445
460 template <typename Iterator1, typename Iterator2>
461 FroidurePin(Iterator1 first, Iterator2 last);
462
479 template <typename Iterator1, typename Iterator2>
480 FroidurePin& init(Iterator1 first, Iterator2 last);
481
492 FroidurePin(FroidurePin const& that);
493
495 FroidurePin(FroidurePin&&) = default;
496
497 ~FroidurePin();
498
499 private:
500 void free_data();
501
503 // FroidurePin - constructor - private
505
507
508 public:
510 // FroidurePin - member functions - public
512
541 template <typename Iterator1, typename Iterator2>
542 [[nodiscard]] const_reference to_element_no_checks(Iterator1 first,
543 Iterator2 last) const;
544
574 template <typename Iterator1, typename Iterator2>
575 [[nodiscard]] const_reference to_element(Iterator1 first,
576 Iterator2 last) const;
577
602 template <typename Iterator1,
603 typename Iterator2,
604 typename Iterator3,
605 typename Iterator4>
606 [[nodiscard]] bool equal_to_no_checks(Iterator1 first1,
607 Iterator2 last1,
608 Iterator3 first2,
609 Iterator4 last2) const;
610
633 template <typename Iterator1,
634 typename Iterator2,
635 typename Iterator3,
636 typename Iterator4>
637 [[nodiscard]] bool equal_to(Iterator1 first1,
638 Iterator2 last1,
639 Iterator3 first2,
640 Iterator4 last2) const {
643 return equal_to_no_checks(first1, last1, first2, last2);
644 }
645
657 [[nodiscard]] size_t number_of_generators() const noexcept override;
658
679 [[nodiscard]] const_reference generator(generator_index_type i) const;
680
701 [[nodiscard]] const_reference
703
725
726#ifndef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
728#endif
729
763 [[nodiscard]] element_index_type
765
780 //! This function does not trigger any enumeration.
782 element_index_type j) const {
785 return fast_product_no_checks(i, j);
786 }
787
801 [[nodiscard]] size_t number_of_idempotents();
802
818 // TODO(1) improve this it doesn't need to trigger a full enum.
819 [[nodiscard]] bool is_idempotent_no_checks(element_index_type i);
820
835 //! This function triggers a full enumeration.
836 [[nodiscard]] bool is_idempotent(element_index_type i) {
837 run();
839 return is_idempotent_no_checks(i);
840 }
841
859 FroidurePin& reserve(size_t val);
860
874 [[nodiscard]] bool contains(const_reference x);
875
893
912
929 // There's no no-checks version of this, there can't be.
931
946 [[nodiscard]] const_reference at(element_index_type i);
947
963
979
995
996#ifndef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
997 // The following are required, they are documented in FroidurePinBase.
998 // Sphinx/doxygen get confused by this, so we don't allow Doxygen to parse
999 // these two declarations.
1002#endif
1003
1022 //! No enumeration is triggered by calls to this function.
1023 [[nodiscard]] tril is_finite() const override {
1024 return tril::TRUE;
1025 }
1026
1045 template <typename Iterator1, typename Iterator2>
1046 FroidurePin& add_generators_no_checks(Iterator1 first, Iterator2 last);
1047
1066 template <typename Iterator1, typename Iterator2>
1067 FroidurePin& add_generators(Iterator1 first, Iterator2 last);
1068
1107
1146
1147 // TODO(1) make the following work
1148 // FroidurePin add_generator(rvalue_reference x);
1149
1171 template <typename Iterator1, typename Iterator2>
1172 [[nodiscard]] FroidurePin
1173 copy_add_generators_no_checks(Iterator1 first, Iterator2 last) const;
1174
1199 template <typename Iterator1, typename Iterator2>
1200 [[nodiscard]] FroidurePin copy_add_generators(Iterator1 first,
1201 Iterator2 last) const {
1202 throw_if_degree_too_small(first, last);
1203 throw_if_inconsistent_degree(first, last);
1204 return copy_add_generators_no_checks(first, last);
1205 }
1206
1207 // TODO(1) copy_add_generator
1208 // TODO(1) copy_add_generators_no_checks
1209
1240 template <typename Iterator1, typename Iterator2>
1241 FroidurePin& closure_no_checks(Iterator1 first, Iterator2 last);
1242
1265 template <typename Iterator1, typename Iterator2>
1266 FroidurePin& closure(Iterator1 first, Iterator2 last) {
1267 throw_if_degree_too_small(first, last);
1268 throw_if_inconsistent_degree(first, last);
1269 return closure_no_checks(first, last);
1270 }
1271
1272 // TODO(1) closure(const_reference)
1273 // TODO(1) closure_no_checks(const_reference)
1274
1299 template <typename Iterator1, typename Iterator2>
1300 [[nodiscard]] FroidurePin copy_closure_no_checks(Iterator1 first,
1301 Iterator2 last);
1302
1330 template <typename Iterator1, typename Iterator2>
1331 [[nodiscard]] FroidurePin copy_closure(Iterator1 first, Iterator2 last) {
1332 throw_if_degree_too_small(first, last);
1333 throw_if_inconsistent_degree(first, last);
1334 return copy_closure_no_checks(first, last);
1335 }
1336
1337 // TODO(1) copy_closure(const_reference)
1338 // TODO(1) copy_closure_no_checks(const_reference)
1339
1346 //! \no_libsemigroups_except
1348 return _state;
1349 }
1350
1366 template <typename Iterator1, typename Iterator2>
1367 static void throw_if_inconsistent_degree(Iterator1 first, Iterator2 last);
1368
1369 private:
1371 // FroidurePin - validation member functions - private
1373
1374 void throw_if_bad_degree(const_reference) const;
1375
1376 template <typename Iterator1, typename Iterator2>
1377 void throw_if_bad_degree(Iterator1, Iterator2) const;
1378
1379 template <typename Iterator1, typename Iterator2>
1380 void throw_if_degree_too_small(Iterator1, Iterator2) const;
1381
1383 // FroidurePin - enumeration member functions - private
1385
1386 void expand(size_type);
1387 void is_one(internal_const_element_type x, element_index_type) noexcept(
1388 std::is_nothrow_default_constructible_v<InternalEqualTo>&& noexcept(
1390
1391 void copy_generators_from_elements(size_t);
1392 void closure_update(element_index_type,
1396 size_type,
1397 size_t const&,
1399 state_type*);
1400
1401 void init_degree(const_reference);
1402
1403 template <typename Iterator1, typename Iterator2>
1404 void add_generators_before_start(Iterator1, Iterator2);
1405
1406 template <typename Iterator1, typename Iterator2>
1407 void add_generators_after_start(Iterator1, Iterator2);
1408
1410 // FroidurePin - initialisation member functions - private
1412
1413 void init_sorted();
1414 void init_idempotents();
1415 void idempotents(enumerate_index_type,
1416 enumerate_index_type,
1417 enumerate_index_type,
1419
1420 // Forward declarations - implemented in froidure-pin.tpp
1421 struct DerefPairFirst;
1422 struct AddressOfPairFirst;
1423 struct IteratorPairFirstTraits;
1424
1426 // FroidurePin - iterators - private
1428
1429 // A type for const iterators through (element, index) pairs of \c this.
1430 using const_iterator_pair_first
1431 = detail::ConstIteratorStateless<IteratorPairFirstTraits>;
1432
1433 public:
1435 // FroidurePin - iterators - public
1442 using const_iterator
1443 = detail::BruidhinnConstIterator<element_type,
1445
1450 using const_iterator_sorted = const_iterator_pair_first;
1451
1459 using const_iterator_idempotents = const_iterator_pair_first;
1460
1480 [[nodiscard]] const_iterator cbegin() const;
1481
1501 [[nodiscard]] const_iterator begin() const;
1502
1522 [[nodiscard]] const_iterator cend() const;
1523
1543 [[nodiscard]] const_iterator end() const;
1544
1558 [[nodiscard]] const_iterator_sorted cbegin_sorted();
1559
1572 [[nodiscard]] const_iterator_sorted cend_sorted();
1573
1587
1600
1601 private:
1602 void run_impl() override;
1603
1604 void report_progress();
1605
1606 bool finished_impl() const override;
1607 };
1608
1613 template <typename Iterator1, typename Iterator2>
1614 FroidurePin(Iterator1, Iterator2)
1616
1617 // Namespace doc is in froidure-pin-base.hpp
1618 namespace froidure_pin {
1619
1634 // NOTE: this isn't called make because it is not constructing anything,
1635 // rather re-initializing.
1636 template <typename Container>
1639 Container const& gens) {
1640 return fp.init(std::begin(gens), std::end(gens));
1641 }
1642
1643 // TODO(1) make the following work
1644 // template <typename Container>
1645 // FroidurePin<typename Container::value_type>&
1646 // init(FroidurePin<typename Container::value_type>& fp, Container&& gens) {
1647 // return fp.init(std::make_move_iterator(std::begin(gens)),
1648 // std::make_move_iterator(std::end(gens)));
1649 // }
1650
1651 // clang-format off
1652 // NOLINTNEXTLINE(whitespace/line_length)
1654 // clang-format on
1655 template <typename Element>
1656 [[nodiscard]] FroidurePin<Element>
1658 return fp.init(std::begin(gens), std::end(gens));
1659 }
1660
1672 template <typename Container>
1674 Container const& coll) {
1675 fp.add_generators(std::begin(coll), std::end(coll));
1676 }
1677
1690 template <typename Container>
1691 void
1696
1697 // TODO(1) make the following work
1698 // template <typename Container>
1699 // FroidurePin<typename Container::value_type>&
1700 // add_generators(FroidurePin<typename Container::value_type>& fp,
1701 // Container&& coll) {
1702 // // Note that this currently doesn't do anything different than the
1703 // // function above.
1704 // return fp.add_generators(std::make_move_iterator(std::begin(coll)),
1705 // std::make_move_iterator(std::end(coll)));
1706 // }
1707
1719 template <typename Element>
1724
1737 template <typename Element>
1742
1758 template <typename Container>
1761 Container const& coll) {
1762 return fp.copy_add_generators(std::begin(coll), std::end(coll));
1763 }
1764
1781 template <typename Container>
1785 Container const& coll) {
1786 return fp.copy_add_generators_no_checks(std::begin(coll), std::end(coll));
1787 }
1788
1804 template <typename Element>
1805 [[nodiscard]] FroidurePin<Element>
1810
1826 template <typename Element>
1827 [[nodiscard]] FroidurePin<Element>
1832
1844 template <typename Container>
1846 Container const& coll) {
1847 fp.closure(std::begin(coll), std::end(coll));
1848 }
1849
1861 template <typename Container>
1863 Container const& coll) {
1864 fp.closure_no_checks(std::begin(coll), std::end(coll));
1865 }
1866
1878 template <typename Element>
1881 fp.closure(std::begin(coll), std::end(coll));
1882 }
1883
1895 template <typename Element>
1900
1915 template <typename Container>
1918 Container const& coll) {
1919 return fp.copy_closure(std::begin(coll), std::end(coll));
1920 }
1921
1936 template <typename Container>
1939 Container const& coll) {
1940 return fp.copy_closure_no_checks(std::begin(coll), std::end(coll));
1941 }
1942
1958 template <typename Element>
1959 [[nodiscard]] FroidurePin<Element>
1964
1980 template <typename Element>
1981 [[nodiscard]] FroidurePin<Element>
1986
1987 // TODO(1) implement the next function
1988 // \brief Returns a range object containing the so-far enumerated
1989 // idempotents.
1990 //
1991 // This function returns a range object containing the so-far enumerated
1992 // idempotents. No enumeration of \p fp is triggered by calls to this
1993 // function.
1994 //
1995 // See TODO(1) for more details about range objects.
1996 //
1997 // \tparam Element the type of the elements in the represented
1998 // semigroup.
1999 //
2000 // \tparam Traits a traits class holding various adapters used by the
2001 // implementation (defaults to FroidurePinTraits).
2002 //
2003 // \param fp the FroidurePin instance.
2004 //
2005 // \returns A range object.
2006 //
2007 // is_idempotent_no_checks current performs a full enum. so this doesn't
2008 // work.
2009 //
2010 // template <typename Element, typename Traits>
2011 // [[nodiscard]] auto
2012 // current_idempotents(FroidurePin<Element, Traits> const& fp) {
2013 // return rx::iterator_range(fp.cbegin(), fp.cend())
2014 // | rx::filter([&fp](auto const& x) {
2015 // return fp.is_idempotent_no_checks(fp.current_position(x));
2016 // });
2017 // }
2018
2038 template <typename Element, typename Traits>
2040 fp.run();
2041 return rx::iterator_range(fp.cbegin_idempotents(), fp.cend_idempotents());
2042 }
2043
2063 template <typename Element, typename Traits>
2065 return rx::iterator_range(fp.cbegin_sorted(), fp.cend_sorted());
2066 }
2067
2068 // TODO(1) current_sorted_elements
2069
2090 template <typename Element, typename Traits>
2091 [[nodiscard]] auto
2093 return rx::iterator_range(fp.cbegin(), fp.cend());
2094 }
2095
2114 template <typename Element, typename Traits>
2115 [[nodiscard]] auto elements(FroidurePin<Element, Traits>& fp) {
2116 fp.run();
2117 return current_elements(fp);
2118 }
2119
2147 template <typename Element, typename Traits, typename Word>
2150 Word const& w) {
2151 return fp.to_element_no_checks(std::begin(w), std::end(w));
2152 }
2153
2154 // clang-format off
2155 // NOLINTNEXTLINE(whitespace/line_length)
2157 // clang-format on
2158 template <typename Element, typename Traits, typename T = size_t>
2165
2192 template <typename Element, typename Traits, typename Word>
2194 to_element(FroidurePin<Element, Traits> const& fp, Word const& w) {
2195 return fp.to_element(std::begin(w), std::end(w));
2196 }
2197
2198 // clang-format off
2199 // NOLINTNEXTLINE(whitespace/line_length)
2201 // clang-format on
2202 template <typename Element, typename Traits, typename T = size_t>
2208
2230 template <typename Element, typename Traits, typename Word>
2231 [[nodiscard]] bool
2233 Word const& x,
2234 Word const& y) {
2235 return fp.equal_to_no_checks(
2236 std::begin(x), std::end(x), std::begin(y), std::end(y));
2237 }
2238
2259 template <typename Element, typename Traits, typename Word>
2260 [[nodiscard]] bool equal_to(FroidurePin<Element, Traits> const& fp,
2261 Word const& x,
2262 Word const& y) {
2263 return fp.equal_to(
2264 std::begin(x), std::end(x), std::begin(y), std::end(y));
2265 }
2266
2288 template <typename Element, typename Traits, typename Word = word_type>
2289 [[nodiscard]] Word minimal_factorisation(
2292
2312 template <typename Element, typename Traits, typename Word>
2315 Word& w,
2317
2340 template <typename Element, typename Traits, typename Word = word_type>
2341 [[nodiscard]] Word
2344
2367 template <typename Element, typename Traits, typename Word>
2368 void
2370 Word& w,
2372
2373 } // namespace froidure_pin
2374
2385
2398 // TODO this only works if FroidurePin is stateless.
2399 template <template <typename...> typename Thing,
2400 typename Container,
2401 typename Element = typename Container::value_type>
2402 [[nodiscard]] auto make(Container const& gens)
2403 -> std::enable_if_t<std::is_same_v<Thing<Element>, FroidurePin<Element>>,
2406 std::end(gens));
2407 return FroidurePin(std::begin(gens), std::end(gens));
2408 }
2409
2410 // TODO(1) make the following work
2411 // template <typename Container>
2412 // FroidurePin<typename Container::value_type>
2413 // make(Container&& gens) {
2414 // return FroidurePin(std::make_move_iterator(std::begin(gens)),
2415 // std::make_move_iterator(std::end(gens)));
2416 // }
2417
2437 template <template <typename...> typename Thing, typename Element>
2439 -> std::enable_if_t<std::is_same_v<Thing<Element>, FroidurePin<Element>>,
2442 std::end(gens));
2443 return FroidurePin(std::begin(gens), std::end(gens));
2444 }
2445
2467 template <template <typename...> typename Thing,
2468 typename Iterator1,
2469 typename Iterator2,
2470 typename Element
2471 = std::decay_t<decltype(*std::declval<Iterator1>())>>
2472 [[nodiscard]] auto make(Iterator1 first, Iterator2 last)
2473 -> std::enable_if_t<std::is_same_v<Thing<Element>, FroidurePin<Element>>,
2475 static_assert(
2476 std::is_same_v<std::decay_t<decltype(*std::declval<Iterator2>())>,
2477 Element>);
2479 return FroidurePin(first, last);
2480 }
2481
2500 template <typename Element, typename Traits>
2501 [[nodiscard]] std::string
2503
2504} // namespace libsemigroups
2505
2506#include "froidure-pin.tpp"
2507
2508#endif // LIBSEMIGROUPS_FROIDURE_PIN_HPP_
T begin(T... args)
element_index_type current_position(Iterator1 first, Iterator2 last) const
Returns the position corresponding to a word.
Definition froidure-pin-base.hpp:311
FroidurePinBase()
Default constructor.
void minimal_factorisation(Iterator d_first, element_index_type pos)
Output to an iterator the short-lex least word representing an element given by index.
Definition froidure-pin-base.hpp:1087
void throw_if_element_index_out_of_range(element_index_type i) const
Throw an exception if an index is out of range.
size_type element_index_type
Alias for the index of an element.
Definition froidure-pin-base.hpp:88
void factorisation(Iterator d_first, element_index_type pos)
Output to an iterator a word representing an element given by index.
Definition froidure-pin-base.hpp:1156
void throw_if_any_generator_index_out_of_range(Iterator1 first, Iterator2 last) const
Throw an exception if any generator index is out of range.
Definition froidure-pin-base.hpp:1806
size_type generator_index_type
Alias for the index of a generator.
Definition froidure-pin-base.hpp:82
WordGraph< element_index_type > cayley_graph_type
Alias for the types of the left and right Cayley graphs.
Definition froidure-pin-base.hpp:91
uint32_t size_type
Alias for the type of the size of the enumerated semigroup.
Definition froidure-pin-base.hpp:76
Class implementing the Froidure-Pin algorithm.
Definition froidure-pin.hpp:190
typename detail::BruidhinnTraits< Element >::const_pointer const_pointer
Type of element const pointers.
Definition froidure-pin.hpp:272
const_reference generator_no_checks(generator_index_type i) const
Returns the generator with specified index.
const_reference at(element_index_type i)
Access element specified by index with bound checks.
typename detail::BruidhinnTraits< Element >::reference reference
Type of element references.
Definition froidure-pin.hpp:269
typename Traits::EqualTo EqualTo
Adapter for testing equality.
Definition froidure-pin.hpp:294
bool contains(const_reference x)
Test membership of an element.
const_iterator begin() const
Returns a const iterator pointing to the first element (ordered by discovery).
bool is_idempotent(element_index_type i)
Check if an element is an idempotent via its index.
Definition froidure-pin.hpp:835
const_reference sorted_at(element_index_type i)
Access element specified by sorted index with bound checks.
const_iterator cbegin() const
Returns a const iterator pointing to the first element (ordered by discovery).
FroidurePin & operator=(FroidurePin const &)
Copy assignment operator.
const_reference to_element_no_checks(Iterator1 first, Iterator2 last) const
Convert a word in the generators to an element.
tril is_finite() const override
Check finiteness.
Definition froidure-pin.hpp:1022
FroidurePin copy_closure_no_checks(Iterator1 first, Iterator2 last)
Copy and add non-redundant generators.
const_iterator_sorted cbegin_sorted()
Returns a const iterator pointing to the first element (sorted by Less).
typename Traits::One One
Adapter for the identity element of the given type.
Definition froidure-pin.hpp:306
FroidurePin & closure(Iterator1 first, Iterator2 last)
Add non-redundant generators in collection.
Definition froidure-pin.hpp:1265
typename detail::BruidhinnTraits< Element >::const_reference const_reference
Type of element const references.
Definition froidure-pin.hpp:261
FroidurePinBase::element_index_type element_index_type
Alias for the index of an element.
Definition froidure-pin.hpp:279
element_index_type fast_product_no_checks(element_index_type i, element_index_type j) const
Multiply elements via their indices.
bool is_idempotent_no_checks(element_index_type i)
Check if an element is an idempotent via its index.
typename Traits::Degree Degree
Adapter for the degree of an element.
Definition froidure-pin.hpp:291
typename Traits::Less Less
Adapter for comparisons.
Definition froidure-pin.hpp:303
typename detail::BruidhinnTraits< Element >::value_type element_type
Type of the elements.
Definition froidure-pin.hpp:249
FroidurePinBase::cayley_graph_type cayley_graph_type
Alias for the types of the left and right Cayley graphs.
Definition froidure-pin.hpp:282
FroidurePin copy_add_generators_no_checks(Iterator1 first, Iterator2 last) const
Copy and add a collection of generators.
element_index_type fast_product(element_index_type i, element_index_type j) const
Multiply elements via their indices.
Definition froidure-pin.hpp:780
typename Traits::Hash Hash
Adapter for hashing.
Definition froidure-pin.hpp:297
FroidurePin & closure_no_checks(Iterator1 first, Iterator2 last)
Add non-redundant generators in collection.
size_t number_of_idempotents()
Returns the number of idempotents.
element_index_type sorted_position(const_reference x)
Returns the sorted index of an element.
std::shared_ptr< state_type > state() const
Returns a std::shared_ptr to the state (if any).
Definition froidure-pin.hpp:1346
const_reference operator[](element_index_type i) const
Access element specified by index.
typename Traits::state_type state_type
Type of the state used for multiplication (if any).
Definition froidure-pin.hpp:285
FroidurePin & init()
Reinitialize a FroidurePin object.
FroidurePin(Iterator1, Iterator2) -> FroidurePin< std::decay_t< decltype(*std::declval< Iterator1 >())> >
size_t number_of_generators() const noexcept override
Returns the number of generators.
FroidurePinBase::size_type size_type
Alias for the type of the size of the enumerated semigroup.
Definition froidure-pin.hpp:276
const_iterator_pair_first const_iterator_idempotents
Return type of cbegin_idempotents and cend_idempotents.
Definition froidure-pin.hpp:1456
typename detail::BruidhinnTraits< Element >::rvalue_reference rvalue_reference
Type of element rvalue references.
Definition froidure-pin.hpp:265
const_iterator cend() const
Returns a const iterator pointing to one past the last known element.
bool equal_to_no_checks(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2) const
Check equality of words in the generators.
typename Traits::Swap Swap
Adapter for swapping.
Definition froidure-pin.hpp:312
const_iterator_idempotents cend_idempotents()
Returns a const iterator pointing one past the last idempotent.
static void throw_if_inconsistent_degree(Iterator1 first, Iterator2 last)
Throws if the degrees of the elements in a given range are not all equal.
typename Traits::Complexity Complexity
Adapter for the complexity of multiplication.
Definition froidure-pin.hpp:288
FroidurePin copy_add_generators(Iterator1 first, Iterator2 last) const
Copy and add a collection of generators.
Definition froidure-pin.hpp:1199
typename Traits::Product Product
Adapter for the product of two elements.
Definition froidure-pin.hpp:309
const_reference generator(generator_index_type i) const
Returns the generator with specified index.
element_type value_type
Alias for element_type.
Definition froidure-pin.hpp:254
FroidurePin copy_closure(Iterator1 first, Iterator2 last)
Copy and add non-redundant generators.
Definition froidure-pin.hpp:1330
element_index_type to_sorted_position(element_index_type i)
Returns the sorted index of an element via its index.
typename detail::BruidhinnTraits< Element >::const_value_type const_element_type
Type of const elements.
Definition froidure-pin.hpp:257
element_index_type current_position(const_reference x) const
Find the position of an element with no enumeration.
FroidurePin & add_generator_no_checks(const_reference x)
Add a copy of an element to the generators.
const_reference to_element(Iterator1 first, Iterator2 last) const
Convert a word in the generators to an element.
const_iterator end() const
Returns a const iterator pointing one past the last known element.
bool equal_to(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2) const
Check equality of words in the generators.
Definition froidure-pin.hpp:636
std::string to_human_readable_repr(FroidurePin< Element, Traits > const &fp)
Return a human readable representation of a FroidurePin object.
FroidurePin & add_generator(const_reference x)
Add a copy of an element to the generators.
FroidurePin & add_generators(Iterator1 first, Iterator2 last)
Add collection of generators via iterators.
const_iterator_idempotents cbegin_idempotents()
Returns a const iterator pointing at the first idempotent.
detail::BruidhinnConstIterator< element_type, std::vector< internal_element_type > > const_iterator
Return type of cbegin and cend.
Definition froidure-pin.hpp:1440
const_reference sorted_at_no_checks(element_index_type i)
Access element specified by sorted index with bound checks.
typename Traits::IncreaseDegree IncreaseDegree
Adapter for increasing the degree of an element.
Definition froidure-pin.hpp:300
element_index_type position(const_reference x)
Find the position of an element with enumeration if necessary.
const_iterator_sorted cend_sorted()
Returns a const iterator pointing one past the last element (sorted by Less).
FroidurePin & add_generators_no_checks(Iterator1 first, Iterator2 last)
Add collection of generators via iterators.
FroidurePin & reserve(size_t val)
Requests the given capacity for elements.
const_iterator_pair_first const_iterator_sorted
Return type of cbegin_sorted and cend_sorted.
Definition froidure-pin.hpp:1447
FroidurePin()
Default constructor.
void run()
Run until finished.
T declval(T... args)
T end(T... args)
enable_if_is_same< Return, Blocks > make(Container const &cont)
Check the arguments, construct a Blocks object, and check it.
Definition bipart.hpp:856
tril
Enum to indicate true, false or not currently knowable.
Definition types.hpp:54
@ TRUE
Value representing true.
Definition types.hpp:58
T make_shared(T... args)
This namespace contains helper functions for the FroidurePin class template.
Definition froidure-pin-base.hpp:1844
FroidurePin< typename Container::value_type > copy_closure(FroidurePin< typename Container::value_type > &fp, Container const &coll)
Copy and add non-redundant generators from a container.
Definition froidure-pin.hpp:1917
auto elements(FroidurePin< Element, Traits > &fp)
Returns a range object containing all of the elements.
Definition froidure-pin.hpp:2115
bool equal_to(FroidurePin< Element, Traits > const &fp, Word const &x, Word const &y)
Check equality of words in the generators.
Definition froidure-pin.hpp:2260
FroidurePin< typename Container::value_type > copy_add_generators(FroidurePin< typename Container::value_type > const &fp, Container const &coll)
Copy a FroidurePin instance and add a collection of generators from a container.
Definition froidure-pin.hpp:1760
FroidurePin< Element, Traits >::const_reference to_element(FroidurePin< Element, Traits > const &fp, Word const &w)
Convert a word in the generators to an element.
Definition froidure-pin.hpp:2194
void add_generators_no_checks(FroidurePin< typename Container::value_type > &fp, Container const &coll)
Add collection of generators from container.
Definition froidure-pin.hpp:1692
bool equal_to_no_checks(FroidurePin< Element, Traits > const &fp, Word const &x, Word const &y)
Check equality of words in the generators.
Definition froidure-pin.hpp:2232
void closure_no_checks(FroidurePin< typename Container::value_type > &fp, Container const &coll)
Add non-redundant generators from a container.
Definition froidure-pin.hpp:1862
FroidurePin< typename Container::value_type > & init(FroidurePin< typename Container::value_type > &fp, Container const &gens)
Re-initialize a FroidurePin object from a container of generators.
Definition froidure-pin.hpp:1638
FroidurePin< Element, Traits >::const_reference to_element_no_checks(FroidurePin< Element, Traits > const &fp, Word const &w)
Convert a word in the generators to an element.
Definition froidure-pin.hpp:2149
void add_generators(FroidurePin< typename Container::value_type > &fp, Container const &coll)
Add collection of generators from container.
Definition froidure-pin.hpp:1673
void factorisation(FroidurePinBase &fpb, Word &word, FroidurePinBase::element_index_type pos)
Modify a word to contain a word representing an element given by index.
Definition froidure-pin-base.hpp:2305
auto current_elements(FroidurePin< Element, Traits > const &fp)
Returns a range object containing the so-far enumerated elements.
Definition froidure-pin.hpp:2092
FroidurePin< typename Container::value_type > copy_add_generators_no_checks(FroidurePin< typename Container::value_type > const &fp, Container const &coll)
Copy a FroidurePin instance and add a collection of generators from a container.
Definition froidure-pin.hpp:1783
void minimal_factorisation(FroidurePinBase &fpb, Word &word, FroidurePinBase::element_index_type pos)
Modify a word to contain the short-lex least word representing an element given by index.
Definition froidure-pin-base.hpp:2205
auto idempotents(FroidurePin< Element, Traits > &fp)
Returns a range object containing all of the idempotents.
Definition froidure-pin.hpp:2039
void closure(FroidurePin< typename Container::value_type > &fp, Container const &coll)
Add non-redundant generators from a container.
Definition froidure-pin.hpp:1845
auto sorted_elements(FroidurePin< Element, Traits > &fp)
Returns a range object containing all of the elements.
Definition froidure-pin.hpp:2064
FroidurePin< typename Container::value_type > copy_closure_no_checks(FroidurePin< typename Container::value_type > &fp, Container const &coll)
Copy and add non-redundant generators from a container.
Definition froidure-pin.hpp:1938
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
Adapter for the complexity of multiplication.
Definition adapters.hpp:128
Adapter for the degree of an element.
Definition adapters.hpp:166
Adapter for testing equality.
Definition adapters.hpp:420
Traits class for FroidurePin.
Definition froidure-pin.hpp:68
::libsemigroups::Degree< element_type > Degree
Adapter for the degree of an element.
Definition froidure-pin.hpp:87
::libsemigroups::Product< element_type > Product
Adapter for the product of two elements.
Definition froidure-pin.hpp:105
::libsemigroups::Complexity< element_type > Complexity
Adapter for the complexity of multiplication.
Definition froidure-pin.hpp:84
typename detail::BruidhinnTraits< Element >::value_type element_type
The type of the elements of a FroidurePin instance.
Definition froidure-pin.hpp:75
::libsemigroups::Hash< element_type > Hash
Adapter for hashing.
Definition froidure-pin.hpp:93
::libsemigroups::IncreaseDegree< element_type > IncreaseDegree
Adapter for increasing the degree of an element.
Definition froidure-pin.hpp:96
::libsemigroups::Less< element_type > Less
Adapter for comparisons.
Definition froidure-pin.hpp:99
::libsemigroups::Swap< element_type > Swap
Adapter for swapping.
Definition froidure-pin.hpp:108
::libsemigroups::EqualTo< element_type > EqualTo
Adapter for testing equality.
Definition froidure-pin.hpp:90
::libsemigroups::One< element_type > One
Adapter for the identity element of the given type.
Definition froidure-pin.hpp:102
State state_type
The type of the state (if any).
Definition froidure-pin.hpp:81
Adapter for hashing.
Definition adapters.hpp:453
Adapter for increasing the degree of an element.
Definition adapters.hpp:206
Adapter for comparisons.
Definition adapters.hpp:641
Adapter for the identity element of the given type.
Definition adapters.hpp:253
Adapter for the product of two elements.
Definition adapters.hpp:291
Adapter for swapping.
Definition adapters.hpp:673