libsemigroups  v3.0.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
sims.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2022-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 a declaration of a class for performing the "low-index
20// congruence" algorithm for 1-sided or 2-sided congruences of semigroups and
21// monoids.
22
23// TODO(2) (later):
24// * use SimsRefinerFaithful in RepOrc + MinimalRepOrc
25// * a version which allows specifying the word_graph to Sims1 too
26// * implement maximum_2_sided_congruence_contained to compute the kernel of the
27// associated homomorphism, which is the largest 2-sided congruence contained
28// in the right congruence.
29// * change RepOrc and MinimalRepOrc to compute minimal 2-sided congruences
30// first (by using generating pairs), and then to try and find a right
31// congruence not containing any of the minimal 2-sided congruences.
32//
33// TODO(3) (far future):
34// * Figure out a way of making refining functions possible. A refining function
35// differs from a pruner in that it is also allowed to modify the word graph.
36// * Implement one and two sided compatibility checking as refiners, following
37// the theoretical description in the paper.
38// * Modify SimsBase to perform the backtrack on all standard word graphs
39// (without explicitly checking compatibility).
40// * Make SimsBase -> Sims, i.e. implement all the relevant functions and
41// settings of Sims1, Sims2, RepOrc, MinimalRepOrc into a single unified
42// class.
43// * Implement Sims1, Sim2, RepOrc, MinimalRepOrc just particular constructors
44// of the Sims object, which automatically set the relevant pruners etc.
45
46#ifndef LIBSEMIGROUPS_SIMS_HPP_
47#define LIBSEMIGROUPS_SIMS_HPP_
48
49#include <algorithm> // for max, fill, count, for_each
50#include <atomic> // for atomic_uint64_t, __atomic_base
51#include <chrono> // for operator-
52#include <cstddef> // for size_t
53#include <cstdint> // for uint64_t, uint32_t
54#include <functional> // for function
55#include <iterator> // for distance, forward_iterator_tag, pair
56#include <list> // for operator!=
57#include <memory> // for unique_ptr
58#include <mutex> // for mutex
59#include <string> // for operator+, basic_string, string, to_string
60#include <thread> // for thread
61#include <type_traits> // for decay_t
62#include <utility> // for move, pair, swap
63#include <vector> // for vector
64
65#include "constants.hpp" // for operator!=, operator==, Max, UNDEFINED
66#include "debug.hpp" // for LIBSEMIGROUPS_ASSERT
67#include "dot.hpp" // for Dot
68#include "exception.hpp" // for LIBSEMIGROUPS_EXCEPTION
69#include "forest.hpp" // for Forest
70#include "knuth-bendix.hpp" // for KnuthBendix, to<Presentation>
71#include "matrix.hpp" // for DynamicMatrix, MatrixCommon, BMat
72#include "presentation.hpp" // for Presentation, longest_rule_length, short...
73#include "ranges.hpp" // for operator|, iterator_range
74#include "runner.hpp" // for delta, Reporter
75#include "todd-coxeter.hpp" // for ToddCoxeter
76#include "types.hpp" // for word_type, relation_type, congruence_kind
77#include "word-graph.hpp" // for Joiner, WordGraph
78
79#include "detail/felsch-graph.hpp" // for FelschGraph
80#include "detail/fmt.hpp" // for format, print
81#include "detail/iterator.hpp" // for detail/default_postfix_increment
82#include "detail/path-iterators.hpp" // for const_pstilo_iterator
83#include "detail/report.hpp" // for ReportCell
84#include "detail/rewriters.hpp" // for RewriteTrie
85#include "detail/word-graph-with-sources.hpp" // for WordGraphWithSources
86
92namespace libsemigroups {
93
107 class SimsStats {
108 public:
117 // TODO(2) might be better to have a mutex here and just lock it in
118 // check_point below
119 std::atomic_uint64_t count_last;
120
126 // Atomic so as to avoid races between report_progress_from_thread and the
127 // threads modifying count_last
128 std::atomic_uint64_t count_now;
129
138 std::atomic_uint64_t max_pending;
139
153 std::atomic_uint64_t total_pending_last;
154
167 // Atomic so as to avoid races between report_progress_from_thread and the
168 // threads modifying total_pending_now
169 std::atomic_uint64_t total_pending_now;
170
178
189 stats_zero();
190 return *this;
191 }
192
203 SimsStats(SimsStats const& that) : SimsStats() {
204 init(that);
205 }
206
218 return init(that);
219 }
220
232 init(that);
233 }
234
246 return init(that);
247 }
248
250 SimsStats& init(SimsStats const& that);
251
259
269 count_last = count_now.load();
271 return *this;
272 }
273 };
274
290 template <typename Subclass>
292 public:
293 // We use WordGraph, even though the iterators produced by this class
294 // hold FelschGraph's, none of the features of FelschGraph are useful
295 // for the output, only for the implementation
298
301
304
307
309 using letter_type = typename word_type::value_type;
310
311 private:
312 std::vector<word_type> _exclude;
313 size_t _exclude_pruner_index;
314 size_t _idle_thread_restarts;
315 std::vector<word_type> _include;
317 size_t _num_threads;
318 Presentation<word_type> _presentation;
319 std::vector<std::function<bool(word_graph_type const&)>> _pruners;
320 mutable SimsStats _stats;
321
322 public:
338
348 Subclass& init();
349
359 // Copy constructor is explicitly required, the constructor template is not
360 // a substitute. If no copy constructor is implemented, then _longs_begin
361 // is not properly initialised, and leads to badness.
363 init(that);
364 }
365
376 init(that);
377 return *this;
378 }
379
390 init(that);
391 }
392
403 init(that);
404 return *this;
405 }
406
408 template <typename OtherSubclass>
410 init(that);
411 }
412
414 template <typename OtherSubclass>
415 Subclass& init(SimsSettings<OtherSubclass> const& that);
416
418
434 // So that we can access the settings from the derived class T.
435 [[nodiscard]] SimsSettings const& settings() const noexcept {
436 return *this;
437 }
438
454 Subclass& number_of_threads(size_t val);
455
465 [[nodiscard]] size_t number_of_threads() const noexcept {
466 return _num_threads;
467 }
468
490
515 [[nodiscard]] Presentation<word_type> const& presentation() const noexcept {
516 return _presentation;
517 }
518
544
569 Subclass& cbegin_long_rules(size_t pos);
570
580 cbegin_long_rules() const noexcept {
581 LIBSEMIGROUPS_ASSERT(_presentation.rules.cbegin() <= _longs_begin);
582 LIBSEMIGROUPS_ASSERT(_longs_begin <= _presentation.rules.cend());
583 return _longs_begin;
584 }
585
592 Subclass& clear_long_rules() {
593 return cbegin_long_rules(_presentation.rules.cend());
594 }
595
597 [[nodiscard]] size_t number_of_long_rules() const noexcept {
598 return std::distance(_longs_begin, _presentation.rules.cend()) / 2;
599 }
600
619 Subclass& long_rule_length(size_t val);
620
640 auto const& pruners() const noexcept {
641 return _pruners;
642 }
643
655 template <typename Func>
656 Subclass& add_pruner(Func&& func) {
657 _pruners.emplace_back(func);
658 // TODO(2) could return an iterator to the inserted func in case we want
659 // to remove it again
660 return static_cast<Subclass&>(*this);
661 }
662
669 Subclass& clear_pruners();
670
687 [[nodiscard]] std::vector<word_type> const&
688 included_pairs() const noexcept {
689 return _include;
690 }
691
702 template <typename Iterator1,
703 typename Iterator2,
704 typename Iterator3,
705 typename Iterator4>
706 Subclass& add_included_pair_no_checks(Iterator1 first1,
707 Iterator2 last1,
708 Iterator3 first2,
709 Iterator4 last2) {
710 return include_exclude_no_checks(first1, last1, first2, last2, _include);
711 }
712
723 template <typename Iterator1,
724 typename Iterator2,
725 typename Iterator3,
726 typename Iterator4>
727 Subclass& add_included_pair(Iterator1 first1,
728 Iterator2 last1,
729 Iterator3 first2,
730 Iterator4 last2) {
731 return include_exclude(first1, last1, first2, last2, _include);
732 }
733
741 _include.clear();
742 return static_cast<Subclass&>(*this);
743 }
744
761 [[nodiscard]] std::vector<word_type> const&
762 excluded_pairs() const noexcept {
763 return _exclude;
764 }
765
776 template <typename Iterator1,
777 typename Iterator2,
778 typename Iterator3,
779 typename Iterator4>
780 Subclass& add_excluded_pair_no_checks(Iterator1 first1,
781 Iterator2 last1,
782 Iterator3 first2,
783 Iterator4 last2) {
784 add_exclude_pruner();
785 return include_exclude_no_checks(first1, last1, first2, last2, _exclude);
786 }
787
798 template <typename Iterator1,
799 typename Iterator2,
800 typename Iterator3,
801 typename Iterator4>
802 Subclass& add_excluded_pair(Iterator1 first1,
803 Iterator2 last1,
804 Iterator3 first2,
805 Iterator4 last2) {
806 add_exclude_pruner();
807 return include_exclude(first1, last1, first2, last2, _exclude);
808 }
809
817
830 [[nodiscard]] SimsStats& stats() const noexcept {
831 return _stats;
832 }
833
845 [[nodiscard]] size_t idle_thread_restarts() const noexcept {
846 return _idle_thread_restarts;
847 }
848
864 // Number of times an idle thread will attempt to restart before yielding.
865 Subclass& idle_thread_restarts(size_t val);
866
882 // TODO(1) rm
883 template <typename Iterator1, typename Iterator2>
885 Iterator2 last) const {
886 presentation().throw_if_letter_not_in_alphabet(first, last);
887 }
888
889 protected:
890 Subclass const& stats_copy_from(SimsStats const& stts) const {
891 _stats = std::move(stts);
892 return static_cast<Subclass const&>(*this);
893 }
894
895 private:
896 template <typename Iterator1,
897 typename Iterator2,
898 typename Iterator3,
899 typename Iterator4>
900 Subclass&
901 include_exclude_no_checks(Iterator1 first1,
902 Iterator2 last1,
903 Iterator3 first2,
904 Iterator4 last2,
905 std::vector<word_type>& include_or_exclude) {
906 include_or_exclude.emplace_back(first1, last1);
907 include_or_exclude.emplace_back(first2, last2);
908 return static_cast<Subclass&>(*this);
909 }
910
911 template <typename Iterator1,
912 typename Iterator2,
913 typename Iterator3,
914 typename Iterator4>
915 Subclass& include_exclude(Iterator1 first1,
916 Iterator2 last1,
917 Iterator3 first2,
918 Iterator4 last2,
919 std::vector<word_type>& include_or_exclude) {
920 throw_if_letter_not_in_alphabet(first1, last1);
921 throw_if_letter_not_in_alphabet(first2, last2);
922 return static_cast<Subclass&>(*this).include_exclude_no_checks(
923 first1, last1, first2, last2, include_or_exclude);
924 }
925
926 size_t add_exclude_pruner();
927 };
928
935 namespace sims {
953 template <typename Subclass, typename Word>
955 Word const& u,
956 Word const& v) {
957 return sims.add_included_pair_no_checks(
958 u.cbegin(), u.cend(), v.cbegin(), v.cend());
959 }
960
967 template <typename Subclass, typename Int>
971 static_assert(std::is_integral_v<Int>);
973 sims, u, v);
974 }
975
982 template <typename Subclass>
984 char const* u,
985 char const* v) {
986 return sims.add_included_pair_no_checks(
987 u, u + std::strlen(u), v, v + std::strlen(v));
988 }
989
990 // This version of the function catches the cases when u & v are not of the
991 // same type but both convertible to string_view
998 template <typename Subclass>
1000 std::string_view u,
1001 std::string_view v) {
1002 return sims.add_included_pair_no_checks(
1003 std::begin(u), std::end(u), std::begin(v), std::end(v));
1004 }
1005
1024 template <typename Subclass, typename Word>
1026 Word const& u,
1027 Word const& v) {
1028 return sims.add_included_pair(u.cbegin(), u.cend(), v.cbegin(), v.cend());
1029 }
1030
1037 template <typename Subclass, typename Int>
1040 std::initializer_list<Int> const& v) {
1041 static_assert(std::is_integral_v<Int>);
1043 }
1044
1051 template <typename Subclass>
1053 char const* u,
1054 char const* v) {
1055 return sims.add_included_pair(
1056 u, u + std::strlen(u), v, v + std::strlen(v));
1057 }
1058
1059 // This version of the function catches the cases when u & v are not of the
1060 // same type but both convertible to string_view
1067 template <typename Subclass>
1069 std::string_view u,
1070 std::string_view v) {
1071 return sims.add_included_pair(
1072 std::begin(u), std::end(u), std::begin(v), std::end(v));
1073 }
1074
1092 template <typename Subclass, typename Word>
1094 Word const& u,
1095 Word const& v) {
1096 return sims.add_excluded_pair_no_checks(
1097 u.cbegin(), u.cend(), v.cbegin(), v.cend());
1098 }
1099
1106 template <typename Subclass, typename Int>
1109 std::initializer_list<Int> const& v) {
1110 static_assert(std::is_integral_v<Int>);
1112 sims, u, v);
1113 }
1114
1121 template <typename Subclass>
1123 char const* u,
1124 char const* v) {
1125 return sims.add_excluded_pair_no_checks(
1126 u, u + std::strlen(u), v, v + std::strlen(v));
1127 }
1128
1129 // This version of the function catches the cases when u & v are not of the
1130 // same type but both convertible to string_view
1137 template <typename Subclass>
1139 std::string_view u,
1140 std::string_view v) {
1141 return sims.add_excluded_pair_no_checks(
1142 std::begin(u), std::end(u), std::begin(v), std::end(v));
1143 }
1144
1163 template <typename Subclass, typename Word>
1165 Word const& u,
1166 Word const& v) {
1167 return sims.add_excluded_pair(u.cbegin(), u.cend(), v.cbegin(), v.cend());
1168 }
1169
1176 template <typename Subclass, typename Int>
1179 std::initializer_list<Int> const& v) {
1180 static_assert(std::is_integral_v<Int>);
1182 }
1183
1190 template <typename Subclass>
1192 char const* u,
1193 char const* v) {
1194 return sims.add_excluded_pair(
1195 u, u + std::strlen(u), v, v + std::strlen(v));
1196 }
1197
1198 // This version of the function catches the cases when u & v are not of the
1199 // same type but both convertible to string_view
1206 template <typename Subclass>
1208 std::string_view u,
1209 std::string_view v) {
1210 return sims.add_excluded_pair(
1211 std::begin(u), std::end(u), std::begin(v), std::end(v));
1212 }
1213
1214 } // namespace sims
1215
1217 // Sims1 - Sims2 - forward decl
1219
1220 class Sims1;
1221 class Sims2;
1222
1223 namespace detail {
1224 template <typename Sims1or2>
1225 class SimsBase : public SimsSettings<Sims1or2>, public Reporter {
1226 static_assert(std::is_same_v<Sims1or2, Sims1>
1227 || std::is_same_v<Sims1or2, Sims2>);
1228
1229 public:
1231 // We use WordGraph, even though the iterators produced by this class
1232 // hold FelschGraph's, none of the features of FelschGraph are useful
1233 // for the output, only for the implementation
1234 using word_graph_type = typename SimsSettings<Sims1or2>::word_graph_type;
1235
1237 using node_type = typename word_graph_type::node_type;
1238
1240 using label_type = typename word_graph_type::label_type;
1241
1243 using size_type = typename word_graph_type::size_type;
1244
1246 using letter_type = typename word_type::value_type;
1247
1249 // SimsBase nested classes - protected
1251
1252 // This class collects some common aspects of the iterator and
1253 // thread_iterator nested classes. The mutex does nothing for <iterator>
1254 // and is an actual std::mutex for <thread_iterator>. Also subclassed by
1255 // Sims2::iterator_base.
1256 class IteratorBase {
1257 public:
1258 using const_reference = word_graph_type const&;
1259 using const_pointer = word_graph_type const*;
1260 using sims_type = Sims1or2;
1261
1262 private:
1263 size_type _max_num_classes;
1264 size_type _min_target_node;
1265
1266 protected:
1267 using PendingDef = typename Sims1or2::PendingDef;
1268 using Definition = std::pair<node_type, label_type>;
1269
1270 // TODO(1) (Sims1) ensure that _felsch_graph's settings are
1271 // properly initialised
1272 FelschGraph<word_type, node_type, std::vector<Definition>>
1273 _felsch_graph;
1274
1275 // This mutex does nothing for iterator, only does something for
1276 // thread_iterator
1277 std::mutex _mtx;
1278 std::vector<PendingDef> _pending;
1279 Sims1or2 const* _sims1or2;
1280
1281 // Push initial PendingDef's into _pending, see tpp file for
1282 // explanation.
1283 void init(size_type n);
1284
1285 // We could use the copy constructor, but there's no point in copying
1286 // anything except the FelschGraph and so we only copy that.
1287 void partial_copy_for_steal_from(IteratorBase const& that) {
1288 _felsch_graph = that._felsch_graph;
1289 }
1290
1291 // Try to pop from _pending into the argument (reference), returns
1292 // true if successful and false if not.
1293 [[nodiscard]] bool try_pop(PendingDef& pd);
1294
1295 // Try to make the definition represented by PendingDef, returns false
1296 // if it wasn't possible, and true if it was.
1297 bool try_define(PendingDef const& current);
1298
1299 // Install any new pending definitions arising from the definition of
1300 // "current", this should only be called after "try_define(current)",
1301 // and is in a separate function so that we can define another version
1302 // of "try_define" in "Sims2".
1303 bool install_descendents(PendingDef const& current);
1304
1305 IteratorBase(Sims1or2 const* s, size_type n);
1306
1307 public:
1308 // None of the constructors are noexcept because the corresponding
1309 // constructors for Presentation aren't currently
1310 IteratorBase();
1311 IteratorBase(IteratorBase const& that);
1312 IteratorBase(IteratorBase&& that);
1313 IteratorBase& operator=(IteratorBase const& that);
1314 IteratorBase& operator=(IteratorBase&& that);
1315 ~IteratorBase();
1316
1317 [[nodiscard]] bool operator==(IteratorBase const& that) const noexcept {
1318 return _felsch_graph == that._felsch_graph;
1319 }
1320
1321 [[nodiscard]] bool operator!=(IteratorBase const& that) const noexcept {
1322 return !(operator==(that));
1323 }
1324
1325 [[nodiscard]] const_reference operator*() const noexcept {
1326 return _felsch_graph;
1327 }
1328
1329 [[nodiscard]] const_pointer operator->() const noexcept {
1330 return &_felsch_graph;
1331 }
1332
1333 void swap(IteratorBase& that) noexcept;
1334
1335 SimsStats& stats() noexcept {
1336 return _sims1or2->stats();
1337 }
1338
1339 size_type maximum_number_of_classes() const noexcept {
1340 return _max_num_classes;
1341 }
1342
1343 Sims1or2 const& sims() const noexcept {
1344 return *_sims1or2;
1345 }
1346 }; // class IteratorBase
1347
1348 public:
1350 // SimsBase nested classes - public
1352
1359 class iterator : public Sims1or2::iterator_base {
1360 using iterator_base = typename Sims1or2::iterator_base;
1361 using PendingDef = typename Sims1or2::PendingDef;
1362
1363 using iterator_base::init;
1364 using iterator_base::install_descendents;
1365 using iterator_base::try_define;
1366 using iterator_base::try_pop;
1367
1368 public:
1370 using const_pointer = typename iterator_base::const_pointer;
1372 using const_reference = typename iterator_base::const_reference;
1383 using value_type = word_graph_type;
1386
1388 using sims_type = typename iterator_base::sims_type;
1389
1391 using iterator_base::iterator_base;
1392
1393 private:
1394 // Only want SimsBase to be able to use this constructor.
1395 iterator(Sims1or2 const* s, size_type n);
1396
1397 // So that we can use the constructor above.
1398 friend iterator SimsBase::cbegin(SimsBase::size_type) const;
1399 friend iterator SimsBase::cend(SimsBase::size_type) const;
1400
1401 public:
1402 ~iterator();
1403
1405 iterator() : iterator_base() {}
1406
1408 iterator(iterator const& that) : iterator_base(that) {}
1409
1411 iterator(iterator&& that) : iterator_base(std::move(that)) {}
1412
1414 iterator& operator=(iterator const& that) {
1416 iterator_base::operator=(that);
1417 return *this;
1418 }
1419
1421 iterator& operator=(iterator&& that) {
1422 iterator_base::operator=(std::move(that));
1423 return *this;
1424 }
1425
1427 // prefix
1428 iterator const& operator++();
1429
1431 // postfix
1432 iterator operator++(int) {
1433 return detail::default_postfix_increment(*this);
1434 }
1435
1436 using iterator_base::swap;
1437 }; // class iterator
1438
1439 private:
1440 class thread_runner;
1441 class thread_iterator;
1442
1443 void report_at_start(size_t num_classes) const;
1444 void report_progress_from_thread() const;
1445 void report_final() const;
1446
1447 void throw_if_not_ready(size_type n) const;
1448
1449 public:
1450 SimsBase();
1451 SimsBase(SimsBase const& other) = default;
1452 SimsBase(SimsBase&&) = default;
1453 SimsBase& operator=(SimsBase const&) = default;
1454 SimsBase& operator=(SimsBase&&) = default;
1455 ~SimsBase();
1456
1457 Sims1or2& init();
1458
1459 // Required because we are inheriting from Reporter and SimsSettings
1460 using SimsSettings<Sims1or2>::presentation;
1461 using SimsSettings<Sims1or2>::number_of_threads;
1462 using SimsSettings<Sims1or2>::stats;
1463 using SimsSettings<Sims1or2>::included_pairs;
1464 using SimsSettings<Sims1or2>::excluded_pairs;
1465 using SimsSettings<Sims1or2>::cbegin_long_rules;
1466
1467 [[nodiscard]] iterator cbegin(size_type n) const {
1468 throw_if_not_ready(n);
1469 return iterator(static_cast<Sims1or2 const*>(this), n);
1470 }
1471
1472 [[nodiscard]] iterator cend(size_type n) const {
1473 throw_if_not_ready(n);
1474 return iterator(static_cast<Sims1or2 const*>(this), 0);
1475 }
1476
1477 // Apply the function pred to every congruence with at
1478 // most n classes
1479 void for_each(size_type n,
1480 std::function<void(word_graph_type const&)> pred) const;
1481
1482 word_graph_type
1483 find_if(size_type n,
1484 std::function<bool(word_graph_type const&)> pred) const;
1485
1486 uint64_t number_of_congruences(size_type n) const;
1487 }; // SimsBase
1488 } // namespace detail
1489
1490 namespace sims {
1491 class const_cgp_iterator;
1492 class const_rcgp_iterator;
1493 } // namespace sims
1494
1520 class Sims1 : public detail::SimsBase<Sims1> {
1521 // Aliases
1522 using SimsBase = detail::SimsBase<Sims1>;
1523 using iterator_base = IteratorBase;
1524
1525 // Friends
1526 // so that SimsBase can access iterator_base, PendingDef, etc
1527 friend SimsBase;
1528 // so that Sims2 can access PendingDef
1529 friend Sims2;
1530
1531 // Forward decl
1532 struct PendingDef;
1533
1534 public:
1535 // We use WordGraph, even though the iterators produced by this class
1536 // hold FelschGraph's, none of the features of FelschGraph are useful
1537 // for the output, only for the implementation
1539 using word_graph_type = SimsBase::word_graph_type;
1540
1542 using node_type = word_graph_type::node_type;
1543
1545 using label_type = word_graph_type::label_type;
1546
1548 using letter_type = word_type::value_type;
1549
1551 using size_type = word_graph_type::size_type;
1552
1553 private:
1554 using Definition = std::pair<node_type, label_type>;
1555
1556 friend class sims::const_rcgp_iterator;
1557 friend class sims::const_cgp_iterator;
1558
1559 using felsch_graph_type
1560 = detail::FelschGraph<word_type, node_type, std::vector<Definition>>;
1561
1562 public:
1564 Sims1() = default;
1565
1566 using SimsBase::init;
1567
1582 //! \sa init
1583 explicit Sims1(Presentation<word_type> const& p) : Sims1() {
1584 presentation(p);
1585 }
1586
1587 //! \copydoc Sims1::Sims1(Presentation<word_type> const&)
1588 explicit Sims1(Presentation<word_type> const&& p) : Sims1() {
1590 }
1591
1593 Sims1(Sims1 const&) = default;
1594
1596 Sims1(Sims1&&) = default;
1597
1599 Sims1& operator=(Sims1 const&) = default;
1600
1602 Sims1& operator=(Sims1&&) = default;
1603
1604 ~Sims1() = default;
1605
1623 //! \sa presentation(Presentation<word_type> const&)
1625 init();
1626 presentation(p);
1627 return *this;
1628 }
1629
1630 //! \copydoc Sims1::init(Presentation<word_type> const&)
1631 Sims1& init(Presentation<word_type> const&& p) {
1632 init();
1634 return *this;
1635 }
1636
1637#ifdef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
1647 Sims1& init();
1648
1666 uint64_t number_of_congruences(size_t n);
1667
1689 void for_each(size_type n,
1690 std::function<void(word_graph_type const&)> pred) const;
1691
1717 std::function<bool(word_graph_type const&)> pred) const;
1718
1764 // TODO(2) (Sims1) it'd be good to remove node 0 to avoid confusion. This
1765 // seems complicated however, and so isn't done at present.
1766 [[nodiscard]] iterator cbegin(size_type n) const;
1767
1791 [[nodiscard]] iterator cend(size_type n) const;
1792#endif // LIBSEMIGROUPS_PARSED_BY_DOXYGEN
1793 };
1794
1816 class Sims2 : public detail::SimsBase<Sims2> {
1817 using SimsBase = detail::SimsBase<Sims2>;
1818 // so that SimsBase can access iterator_base, PendingDef, etc
1819 friend SimsBase;
1820
1821 public:
1823 using word_graph_type = SimsBase::word_graph_type;
1824
1826 using node_type = word_graph_type::node_type;
1827
1829 using label_type = word_graph_type::label_type;
1830
1832 using letter_type = word_type::value_type;
1833
1835 using size_type = word_graph_type::size_type;
1836
1837 using SimsBase::init;
1838
1840 Sims2() = default;
1841
1843 Sims2(Sims2 const& other) = default;
1844
1846 Sims2(Sims2&&) = default;
1847
1849 Sims2& operator=(Sims2 const&) = default;
1850
1852 Sims2& operator=(Sims2&&) = default;
1853
1854 ~Sims2() = default;
1855
1857 explicit Sims2(Presentation<word_type> const& p) : Sims2() {
1858 presentation(p);
1859 }
1860
1862 explicit Sims2(Presentation<word_type> const&& p) : Sims2() {
1864 }
1865
1885 init();
1886 presentation(p);
1887 return *this;
1888 }
1889
1892 init();
1894 return *this;
1895 }
1896
1897#ifdef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
1908
1910 uint64_t number_of_congruences(size_t n);
1911
1914 std::function<void(word_graph_type const&)> pred) const;
1915
1919 std::function<bool(word_graph_type const&)> pred) const;
1920
1922 [[nodiscard]] iterator cbegin(size_type n) const;
1923
1925 [[nodiscard]] iterator cend(size_type n) const;
1926#endif
1927
1928 private:
1929 struct PendingDef;
1930
1931 // This class collects some common aspects of the iterator and
1932 // thread_iterator nested classes. The mutex does nothing for <iterator>
1933 // and is an actual std::mutex for <thread_iterator>.
1934 class iterator_base : public SimsBase::IteratorBase {
1935 class RuleContainer;
1936
1937 public:
1938 using const_reference = SimsBase::IteratorBase::const_reference;
1939 using const_pointer = SimsBase::IteratorBase::const_pointer;
1940
1941 private:
1942 std::unique_ptr<RuleContainer> _2_sided_include;
1943 std::vector<word_type> _2_sided_words;
1944
1945 protected:
1946 // We could use the copy constructor, but there's no point in copying
1947 // anything except the FelschGraph and so we only copy that.
1948 void partial_copy_for_steal_from(iterator_base const& that);
1949
1950 // Try to make the definition represented by PendingDef, returns false if
1951 // it wasn't possible, and true if it was.
1952 [[nodiscard]] bool try_define(PendingDef const&);
1953
1954 iterator_base(Sims2 const* s, size_type n);
1955
1956 public:
1957 iterator_base();
1958 iterator_base(iterator_base const& that);
1959 iterator_base(iterator_base&& that);
1960 iterator_base& operator=(iterator_base const& that);
1961 iterator_base& operator=(iterator_base&& that);
1962 ~iterator_base();
1963
1965 void swap(iterator_base& that) noexcept;
1966
1968 }; // class iterator_base
1969 }; // class Sims2
1970
1989 class RepOrc : public SimsSettings<RepOrc> {
1990 private:
1991 size_t _min;
1992 size_t _max;
1993 size_t _size;
1994
1995 public:
1997 RepOrc() : _min(), _max(), _size() {
1998 init();
1999 }
2000
2011
2026 template <typename OtherSubclass>
2030
2045 template <typename OtherSubclass>
2048 return *this;
2049 }
2050
2062 RepOrc& min_nodes(size_t val) noexcept {
2063 _min = val;
2064 return *this;
2065 }
2066
2076 [[nodiscard]] size_t min_nodes() const noexcept {
2077 return _min;
2078 }
2079
2091 RepOrc& max_nodes(size_t val) noexcept {
2092 _max = val;
2093 return *this;
2094 }
2095
2105 [[nodiscard]] size_t max_nodes() const noexcept {
2106 return _max;
2107 }
2108
2121 RepOrc& target_size(size_t val) noexcept {
2122 _size = val;
2123 return *this;
2124 }
2125
2136 [[nodiscard]] size_t target_size() const noexcept {
2137 return _size;
2138 }
2139
2164 [[nodiscard]] Sims1::word_graph_type word_graph() const;
2165 }; // class RepOrc
2166
2183 class MinimalRepOrc : public SimsSettings<MinimalRepOrc> {
2184 private:
2185 size_t _size;
2186
2187 public:
2189
2191 MinimalRepOrc() : _size() {
2192 init();
2193 }
2194
2205 _size = 0;
2206 return *this;
2207 }
2208
2221 MinimalRepOrc& target_size(size_t val) noexcept {
2222 _size = val;
2223 return *this;
2224 }
2225
2236 [[nodiscard]] size_t target_size() const noexcept {
2237 return _size;
2238 }
2239
2273 [[nodiscard]] Sims1::word_graph_type word_graph() const;
2274 }; // class MinimalRepOrc
2275
2276 namespace sims {
2277 class const_cgp_iterator;
2278
2289 // This is similar to FroidurePinBase::const_rule_iterator
2290 // Right Congruence Generating Pairs (rcgp)
2291 class const_rcgp_iterator {
2292 public:
2295
2299
2302
2305
2309
2312
2315
2318
2321
2323 using felsch_graph_type = Sims1::felsch_graph_type;
2324
2326 using node_type = word_graph_type::node_type;
2327
2329 using label_type = word_graph_type::label_type;
2330
2331 protected:
2332 felsch_graph_type _reconstructed_word_graph;
2333
2334 private:
2335 label_type _gen;
2336 node_type _source;
2337 mutable relation_type _relation;
2338 Forest _tree;
2339 word_graph_type const* _word_graph;
2340
2341 // Set source to ptr->number_of_active_nodes() for cend
2343 word_graph_type const* ptr,
2344 node_type source,
2345 label_type gen);
2346
2347 // To allow the use of the above constructor
2348 template <typename Node>
2349 friend const_rcgp_iterator
2350 cbegin_right_generating_pairs_no_checks(WordGraph<Node> const&);
2351
2352 template <typename Node>
2353 friend const_rcgp_iterator
2354 cbegin_right_generating_pairs_no_checks(Presentation<word_type> const&,
2355 WordGraph<Node> const&);
2356
2357 // To allow the use of the above constructor
2358 template <typename Node>
2359 friend const_rcgp_iterator
2360 cend_right_generating_pairs_no_checks(WordGraph<Node> const&);
2361
2362 template <typename Node>
2363 friend const_rcgp_iterator
2364 cend_right_generating_pairs_no_checks(Presentation<word_type> const&,
2365 WordGraph<Node> const&);
2366
2367 // To allow the use of the private constructor from pointer
2368 template <typename Node>
2369 friend const_cgp_iterator
2370 cbegin_two_sided_generating_pairs_no_checks(WordGraph<Node> const&);
2371
2372 template <typename Node>
2373 friend const_cgp_iterator cbegin_two_sided_generating_pairs_no_checks(
2375 WordGraph<Node> const&);
2376
2377 // To allow the use of the above constructor
2378 template <typename Node>
2379 friend const_cgp_iterator
2380 cend_two_sided_generating_pairs_no_checks(WordGraph<Node> const&);
2381
2382 template <typename Node>
2383 friend const_cgp_iterator
2384 cend_two_sided_generating_pairs_no_checks(Presentation<word_type> const&,
2385 WordGraph<Node> const&);
2386
2387 public:
2391 const_rcgp_iterator(const_rcgp_iterator const&) = default;
2393 const_rcgp_iterator(const_rcgp_iterator&&) = default;
2395 const_rcgp_iterator& operator=(const_rcgp_iterator const&) = default;
2397 const_rcgp_iterator& operator=(const_rcgp_iterator&&) = default;
2398
2399 ~const_rcgp_iterator();
2400
2402 [[nodiscard]] bool
2403 operator==(const_rcgp_iterator const& that) const noexcept {
2404 return _gen == that._gen && _source == that._source;
2405 }
2406
2408 [[nodiscard]] bool
2409 operator!=(const_rcgp_iterator const& that) const noexcept {
2410 return !(this->operator==(that));
2411 }
2412
2418 [[nodiscard]] const_reference operator*() const {
2419 populate_relation();
2420 return _relation;
2421 }
2422
2425 [[nodiscard]] const_pointer operator->() const {
2426 populate_relation();
2427 return &_relation;
2428 }
2429
2431 const_rcgp_iterator const& operator++();
2432
2434 const_rcgp_iterator operator++(int) noexcept {
2435 return detail::default_postfix_increment(*this);
2436 }
2437
2439 void swap(const_rcgp_iterator& that) noexcept;
2440
2441 protected:
2442 [[nodiscard]] bool at_end() const noexcept {
2443 return _source == _word_graph->number_of_active_nodes();
2444 }
2445
2446 private:
2447 bool populate_relation() const;
2448 }; // const_rcgp_iterator
2449
2461 public:
2464
2467
2470
2473
2476
2479
2482
2485
2488
2490 using felsch_graph_type = Sims1::felsch_graph_type;
2491
2493 using node_type = word_graph_type::node_type;
2494
2496 using label_type = word_graph_type::label_type;
2497
2498 using const_rcgp_iterator::const_rcgp_iterator;
2499
2501
2502 using const_rcgp_iterator::operator==;
2503 using const_rcgp_iterator::operator!=;
2504 using const_rcgp_iterator::operator*;
2505 using const_rcgp_iterator::operator->;
2506
2509
2512 return detail::default_postfix_increment(*this);
2513 }
2514
2516 void swap(const_cgp_iterator& that) noexcept {
2518 }
2519
2520 private:
2521 bool populate_relation() const;
2522 }; // class const_cgp_iterator
2523
2524 // Forward decl, documented below
2525 template <typename Node>
2526 rx::iterator_range<const_rcgp_iterator>
2528 WordGraph<Node> const& wg);
2529
2530 // Forward decl, documented below
2531 template <typename Node>
2532 rx::iterator_range<const_rcgp_iterator>
2534
2535 // Forward decl, documented below
2536 template <typename Node>
2537 rx::iterator_range<const_cgp_iterator>
2539 WordGraph<Node> const& wg);
2540
2541 // Forward decl, documented below
2542 template <typename Node>
2543 rx::iterator_range<const_cgp_iterator>
2545
2551 template <typename Node>
2553 WordGraph<Node> const& wg);
2554
2557 template <typename Node>
2559 WordGraph<Node> const& wg);
2560
2571 template <typename Node>
2573 WordGraph<Node> const& wg) {
2574 auto p_rev(p);
2575 presentation::reverse(p_rev);
2576 return is_right_congruence(p_rev, wg);
2577 }
2578
2591 template <typename Node>
2593 WordGraph<Node> const& wg);
2594
2601 template <typename Node>
2603 WordGraph<Node> const& wg);
2604
2607 template <typename Node>
2609 WordGraph<Node> const& wg);
2610
2622 // Note that this is the generating pairs of the right
2623 // congruence so defined not the two-sided congruence.
2624 template <typename Node>
2627 WordGraph<Node> const& wg) {
2628 return const_rcgp_iterator(p, &wg, 0, 0);
2629 }
2630
2640 template <typename Node>
2647
2667 // Note that this is the generating pairs of the right
2668 // congruence so defined not the two-sided congruence.
2669 template <typename Node>
2675
2692 template <typename Node>
2699
2712 template <typename Node>
2713 const_rcgp_iterator
2715 WordGraph<Node> const& wg) {
2716 return const_rcgp_iterator(p, &wg, wg.number_of_active_nodes(), 0);
2717 }
2718
2728 template <typename Node>
2735
2755 template <typename Node>
2756 const_cgp_iterator
2758 WordGraph<Node> const& wg) {
2759 return const_cgp_iterator(p, &wg, wg.number_of_active_nodes(), 0);
2760 }
2761
2778 template <typename Node>
2785
2797 template <typename Node>
2798 rx::iterator_range<const_rcgp_iterator>
2804
2814 template <typename Node>
2815 rx::iterator_range<const_rcgp_iterator>
2821
2833 template <typename Node>
2834 rx::iterator_range<const_rcgp_iterator>
2840
2850 template <typename Node>
2851 rx::iterator_range<const_rcgp_iterator>
2853
2873 template <typename Node>
2874 rx::iterator_range<const_cgp_iterator>
2881
2898 template <typename Node>
2899 rx::iterator_range<const_cgp_iterator>
2905
2924 template <typename Node>
2925 rx::iterator_range<const_cgp_iterator>
2933
2950 template <typename Node>
2951 rx::iterator_range<const_cgp_iterator>
2958
2965 template <typename Node>
2967 WordGraph<Node> const& wg);
2968
2985 template <typename Iterator>
2986 BMat<> poset(Iterator first, Iterator last);
2987
2992 // The following produces a self-contained Dot object which doesn't render
2993 // very well.
2994 template <typename Iterator>
2995 Dot dot_poset(Iterator first, Iterator last);
2996 } // namespace sims
2997
3015 // This struct provides an alternative way of doing MinimalRepOrc, when the
3016 // generating pairs of the minimal 2-sided congruences are known. These pairs
3017 // should be added to forbid, and then your SimsRefinerFaithful instance
3018 // should be passed to a Sims1 object via add_pruner.
3020 private:
3021 std::vector<word_type> _forbid;
3022
3023 public:
3025 SimsRefinerFaithful() : _forbid() {}
3026
3034 _forbid.clear();
3035 return *this;
3036 }
3037
3058 // TODO(2): Construct from std::vector<std::string>
3059 // TODO(1) construct from iterators, and move word_type version of to helper
3060 // namespace
3062 : _forbid(forbid) {}
3063
3074 // TODO(1) construct from iterators, and move word_type version of to helper
3075 // namespace
3077 _forbid.clear();
3078 _forbid = forbid;
3079 return *this;
3080 }
3081
3093 [[nodiscard]] std::vector<word_type> const& forbid() const noexcept {
3094 return _forbid;
3095 }
3096
3105 }; // class SimsRefinerFaithful
3106
3120 private:
3121 using node_type = uint32_t;
3122 using KnuthBendix_ = KnuthBendix<word_type>;
3123 std::vector<KnuthBendix_> _knuth_bendices;
3124 Presentation<word_type> _presentation;
3125
3126 public:
3128 // TODO(1) to tpp
3130 : _knuth_bendices(std::thread::hardware_concurrency() + 1,
3131 KnuthBendix_()),
3132 _presentation() {
3133 init();
3134 }
3135
3142 // TODO(1) to tpp
3144 _presentation.init();
3145 _knuth_bendices[0].init();
3146 std::fill(_knuth_bendices.begin() + 1,
3147 _knuth_bendices.end(),
3148 _knuth_bendices[0]);
3149 return *this;
3150 }
3151
3164 : _knuth_bendices(std::thread::hardware_concurrency() + 1,
3165 KnuthBendix_()),
3166 _presentation() {
3167 init(p);
3168 }
3169
3195
3208 [[nodiscard]] Presentation<word_type> const& presentation() const noexcept {
3209 return _presentation;
3210 }
3211
3224 }; // class SimsRefinerIdeals
3225
3237
3249
3261
3274
3287
3300
3312 [[nodiscard]] std::string
3314
3315} // namespace libsemigroups
3316
3317#include "sims.tpp"
3318
3319#endif // LIBSEMIGROUPS_SIMS_HPP_
T begin(T... args)
A representation of a graph in the DOT language of Graphviz.
Definition dot.hpp:115
Class representing a collection of spanning trees of a word graph.
Definition forest.hpp:42
For computing the minimal degree of a transformation representation arising from a right congruences ...
Definition sims.hpp:2183
MinimalRepOrc & target_size(size_t val) noexcept
Set the target size.
Definition sims.hpp:2221
MinimalRepOrc()
Default constructor.
Definition sims.hpp:2191
size_t target_size() const noexcept
Get the current target size.
Definition sims.hpp:2236
Sims1::word_graph_type word_graph() const
Get the word graph.
MinimalRepOrc & init()
Reinitialize an existing MinimalRepOrc object.
Definition sims.hpp:2204
For an implementation of presentations for semigroups or monoids.
Definition presentation.hpp:102
word_type const & alphabet() const noexcept
Return the alphabet of the presentation.
Definition presentation.hpp:183
For computing small degree transformation representations of a finite semigroup or monoid.
Definition sims.hpp:1989
RepOrc & max_nodes(size_t val) noexcept
Set the maximum number of nodes.
Definition sims.hpp:2091
size_t max_nodes() const noexcept
Get the current maximum number of nodes.
Definition sims.hpp:2105
RepOrc & target_size(size_t val) noexcept
Set the target size.
Definition sims.hpp:2121
RepOrc()
Default constructor.
Definition sims.hpp:1997
size_t min_nodes() const noexcept
Get the current minimum number of nodes.
Definition sims.hpp:2076
size_t target_size() const noexcept
Get the current target size.
Definition sims.hpp:2136
Sims1::word_graph_type word_graph() const
Get the word_graph.
RepOrc & init()
Reinitialize an existing RepOrc object.
RepOrc & min_nodes(size_t val) noexcept
Set the minimum number of nodes.
Definition sims.hpp:2062
RepOrc & init(SimsSettings< OtherSubclass > const &s)
Initialize an existing RepOrc object from Sims1, Sims2 or MinimalRepOrc.
Definition sims.hpp:2046
RepOrc(SimsSettings< OtherSubclass > const &s)
Construct from Sims1, Sims2 or MinimalRepOrc.
Definition sims.hpp:2027
For computing finite index right congruences of a finitely presented semigroup or monoid.
Definition sims.hpp:1520
uint64_t number_of_congruences(size_t n)
Returns the number of one-sided congruences with up to a given number of classes.
word_type::value_type letter_type
Type for letters in the underlying presentation.
Definition sims.hpp:1548
Sims1 & operator=(Sims1 const &)=default
Default copy assignment operator.
SimsBase::word_graph_type word_graph_type
The type of the associated WordGraph objects.
Definition sims.hpp:1539
word_graph_type::size_type size_type
The size_type of the associated WordGraph objects.
Definition sims.hpp:1551
word_graph_type::label_type label_type
Type of the edge labels in the associated WordGraph objects.
Definition sims.hpp:1545
void for_each(size_type n, std::function< void(word_graph_type const &)> pred) const
Apply a unary predicate to every one-sided congruence with at most a given number of classes.
Sims1()=default
Default constructor.
word_graph_type find_if(size_type n, std::function< bool(word_graph_type const &)> pred) const
Apply a unary predicate to one-sided congruences with at most a given number of classes,...
word_graph_type::node_type node_type
Type of the nodes in the associated WordGraph objects.
Definition sims.hpp:1542
iterator cbegin(size_type n) const
Returns a forward iterator pointing at the first congruence.
iterator cend(size_type n) const
Returns a forward iterator pointing one beyond the last congruence.
Sims1 & init()
Reinitialize an existing Sims1 object.
For computing finite index two-sided congruences of a finitely presented semigroup or monoid.
Definition sims.hpp:1816
Sims2(Presentation< word_type > const &&p)
Construct from a presentation.
Definition sims.hpp:1862
uint64_t number_of_congruences(size_t n)
Returns the number of one-sided congruences with up to a given number of classes.
Sims2(Sims2 &&)=default
Default move constructor.
word_type::value_type letter_type
Type for letters in the underlying presentation.
Definition sims.hpp:1832
Sims2(Sims2 const &other)=default
Default copy constructor.
SimsBase::word_graph_type word_graph_type
The type of the associated WordGraph objects.
Definition sims.hpp:1823
Sims2()=default
Default constructor.
Sims2 & operator=(Sims2 const &)=default
Default copy assignment operator.
word_graph_type::size_type size_type
The size_type of the associated WordGraph objects.
Definition sims.hpp:1835
word_graph_type::label_type label_type
Type of the edge labels in the associated WordGraph objects.
Definition sims.hpp:1829
Sims2 & init(Presentation< word_type > const &&p)
Reinitialize an existing Sims2 object.
Definition sims.hpp:1891
Sims2 & init()
Reinitialize an existing Sims2 object.
void for_each(size_type n, std::function< void(word_graph_type const &)> pred) const
Apply a unary predicate to every one-sided congruence with at most a given number of classes.
Sims2 & init(Presentation< word_type > const &p)
Reinitialize an existing Sims2 object.
Definition sims.hpp:1884
word_graph_type find_if(size_type n, std::function< bool(word_graph_type const &)> pred) const
Apply a unary predicate to one-sided congruences with at most a given number of classes,...
Sims2(Presentation< word_type > const &p)
Construct from a presentation.
Definition sims.hpp:1857
word_graph_type::node_type node_type
Type of the nodes in the associated WordGraph objects.
Definition sims.hpp:1826
iterator cbegin(size_type n) const
Returns a forward iterator pointing at the first congruence.
iterator cend(size_type n) const
Returns a forward iterator pointing one beyond the last congruence.
Sims2 & operator=(Sims2 &&)=default
Default move assignment operator.
For pruning the search tree when looking for congruences arising from right or two-sided congruences ...
Definition sims.hpp:3019
std::vector< word_type > const & forbid() const noexcept
Get the forbidden pairs defining the refiner.
Definition sims.hpp:3093
bool operator()(Sims1::word_graph_type const &wg)
Check if a word graph can be extended to one defining a faithful congruence.
SimsRefinerFaithful & init(std::vector< word_type > const &forbid)
Reinitialize an existing SimsRefinerFaithful object from a set of forbidden pairs.
Definition sims.hpp:3076
SimsRefinerFaithful(std::vector< word_type > const &forbid)
Construct from set of forbidden pairs.
Definition sims.hpp:3061
SimsRefinerFaithful()
Default constructor.
Definition sims.hpp:3025
SimsRefinerFaithful & init()
Reinitialize an existing SimsRefinerFaithful object.
Definition sims.hpp:3033
For pruning the search tree when looking for congruences arising from right or two-sided ideals.
Definition sims.hpp:3119
SimsRefinerIdeals & init()
Reinitialize an existing SimsRefinerIdeals object.
Definition sims.hpp:3143
SimsRefinerIdeals(Presentation< word_type > const &p)
Construct from presentation.
Definition sims.hpp:3163
Presentation< word_type > const & presentation() const noexcept
Get the presentation over which the refiner is defined.
Definition sims.hpp:3208
SimsRefinerIdeals & init(Presentation< word_type > const &p)
Reinitialize an existing SimsRefinerIdeals object from a word_type presentation.
bool operator()(Sims1::word_graph_type const &wg)
Check if a word graph can be extended to one defining a Rees congruence.
SimsRefinerIdeals()
Default constructor.
Definition sims.hpp:3129
For setting the presentation and various runtime parameters of the Sims low index algorithm.
Definition sims.hpp:291
SimsStats & stats() const noexcept
Get the current stats object.
Definition sims.hpp:830
Subclass & add_excluded_pair(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Add an excluded pair via iterators.
Definition sims.hpp:802
Subclass & clear_excluded_pairs()
Clear the set of excluded words.
WordGraph< uint32_t > word_graph_type
The type of the associated WordGraph objects.
Definition sims.hpp:297
SimsSettings & operator=(SimsSettings const &that)
Definition sims.hpp:375
size_t number_of_long_rules() const noexcept
Returns the number of rules marked as long rules.
Definition sims.hpp:597
Subclass & clear_pruners()
Clear the set of pruners.
SimsSettings const & settings() const noexcept
Definition sims.hpp:435
typename word_graph_type::node_type node_type
Type for the nodes in the associated WordGraph objects.
Definition sims.hpp:300
Subclass & cbegin_long_rules(size_t pos)
Set the beginning of the long rules (position).
size_t number_of_threads() const noexcept
Get the number of threads.
Definition sims.hpp:465
Subclass & add_included_pair(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Add an included pair via iterators (no checks).
Definition sims.hpp:727
SimsSettings(SimsSettings const &that)
Definition sims.hpp:362
Subclass & idle_thread_restarts(size_t val)
Set the idle thread restart attempt count.
Subclass & long_rule_length(size_t val)
Set the length of a long rule.
typename word_graph_type::label_type label_type
Type for the labels in the associated WordGraph objects.
Definition sims.hpp:303
SimsSettings & operator=(SimsSettings &&that)
Definition sims.hpp:402
SimsSettings(SimsSettings< OtherSubclass > const &that)
Construct from SimsSettings with different subclass.
Definition sims.hpp:409
Subclass & presentation(Presentation< word_type > const &p)
Set the presentation over which the congruences produced by an instance are defined.
Subclass & add_excluded_pair_no_checks(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Add an excluded pair via iterators (no checks).
Definition sims.hpp:780
Presentation< word_type > const & presentation() const noexcept
Get the presentation over which the congruences produced by an instance are defined.
Definition sims.hpp:515
Subclass & clear_included_pairs()
Clear the set of included pairs.
Definition sims.hpp:740
SimsSettings(SimsSettings &&that)
Definition sims.hpp:389
std::vector< word_type > const & included_pairs() const noexcept
Get the set of pairs that must be included in every congruence.
Definition sims.hpp:688
void throw_if_letter_not_in_alphabet(Iterator1 first, Iterator2 last) const
Throws if any letter in a range is out of bounds.
Definition sims.hpp:884
size_t idle_thread_restarts() const noexcept
Get the idle thread restart attempt count.
Definition sims.hpp:845
auto const & pruners() const noexcept
Get all active pruners of the search tree.
Definition sims.hpp:640
Subclass & add_included_pair_no_checks(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Add an included pair via iterators.
Definition sims.hpp:706
typename word_graph_type::size_type size_type
The size_type of the associated WordGraph objects.
Definition sims.hpp:306
Subclass & init(SimsSettings< OtherSubclass > const &that)
Initialize from SimsSettings with different subclass.
Subclass & cbegin_long_rules(std::vector< word_type >::const_iterator it)
Set the beginning of the long rules (iterator).
Subclass & number_of_threads(size_t val)
Set the number of threads.
typename word_type::value_type letter_type
Type for letters in the underlying presentation.
Definition sims.hpp:309
std::vector< word_type > const & excluded_pairs() const noexcept
Get the set of pairs that must be excluded from every congruence.
Definition sims.hpp:762
Subclass & init()
Reinitialize an existing SimsSettings object.
Subclass & add_pruner(Func &&func)
Add a pruner to the search tree.
Definition sims.hpp:656
Subclass & clear_long_rules()
Clear the set of long rules.
Definition sims.hpp:592
std::vector< word_type >::const_iterator cbegin_long_rules() const noexcept
Get the pointer to the first long rule.
Definition sims.hpp:580
For keeping track of various statistics arising during the runtime of the low index algorithm.
Definition sims.hpp:107
SimsStats & operator=(SimsStats &&that)
Definition sims.hpp:245
std::atomic_uint64_t count_now
Definition sims.hpp:128
SimsStats & operator=(SimsStats const &that)
Definition sims.hpp:217
std::atomic_uint64_t total_pending_last
Definition sims.hpp:153
SimsStats & stats_zero()
Set all statistics to zero.
std::atomic_uint64_t count_last
Definition sims.hpp:119
SimsStats(SimsStats &&that)
Definition sims.hpp:231
SimsStats(SimsStats const &that)
Definition sims.hpp:203
SimsStats & init()
Reinitialize an existing SimsStats object.
Definition sims.hpp:188
SimsStats & stats_check_point()
Store the current statistic values.
Definition sims.hpp:268
SimsStats & init(SimsStats const &that)
Initialize from SimsStats.
std::atomic_uint64_t max_pending
Definition sims.hpp:138
std::atomic_uint64_t total_pending_now
Definition sims.hpp:169
Class for representing word graphs.
Definition word-graph.hpp:82
uint32_t node_type
Definition word-graph.hpp:98
uint32_t label_type
Definition word-graph.hpp:101
size_type out_degree() const noexcept
Returns the out-degree.
Definition word-graph.hpp:823
std::size_t size_type
Definition word-graph.hpp:104
typename std::vector< word_graph_type >::pointer pointer
No doc.
Definition sims.hpp:1379
typename std::vector< word_graph_type >::size_type size_type
No doc.
Definition sims.hpp:1374
word_graph_type value_type
No doc.
Definition sims.hpp:1383
iterator(iterator const &that)
No doc.
Definition sims.hpp:1408
typename iterator_base::const_pointer const_pointer
No doc.
Definition sims.hpp:1370
iterator const & operator++()
No doc.
iterator(iterator &&that)
No doc.
Definition sims.hpp:1411
typename std::vector< word_graph_type >::difference_type difference_type
No doc.
Definition sims.hpp:1376
iterator operator++(int)
No doc.
Definition sims.hpp:1432
iterator & operator=(iterator const &that)
No doc.
Definition sims.hpp:1414
iterator()
No doc.
Definition sims.hpp:1405
std::forward_iterator_tag iterator_category
No doc.
Definition sims.hpp:1385
iterator & operator=(iterator &&that)
No doc.
Definition sims.hpp:1421
typename iterator_base::sims_type sims_type
No doc.
Definition sims.hpp:1388
typename iterator_base::const_reference const_reference
No doc.
Definition sims.hpp:1372
typename std::vector< word_graph_type >::reference reference
No doc.
Definition sims.hpp:1381
For iterating over the two-sided congruence generating pairs.
Definition sims.hpp:2460
const_cgp_iterator const & operator++()
Prefix increment operator.
relation_type value_type
Type of values pointed to by const_cgp_iterator.
Definition sims.hpp:2481
const_rcgp_iterator::const_pointer const_pointer
Type of const pointers to value_type.
Definition sims.hpp:2469
const_rcgp_iterator::const_reference const_reference
Type of const references to value_type.
Definition sims.hpp:2475
Sims1::word_graph_type word_graph_type
Type of WordGraph.
Definition sims.hpp:2487
std::forward_iterator_tag iterator_category
Iterator category (forward iterator).
Definition sims.hpp:2484
void swap(const_cgp_iterator &that) noexcept
Swap.
Definition sims.hpp:2516
const_rcgp_iterator::pointer pointer
Type of pointers to value_type.
Definition sims.hpp:2472
const_rcgp_iterator()=default
Default constructor.
word_graph_type::label_type label_type
Type of the labels in word_graph_type.
Definition sims.hpp:2496
const_rcgp_iterator::difference_type difference_type
Difference type for const_cgp_iterator.
Definition sims.hpp:2466
const_cgp_iterator operator++(int) noexcept
Postfix increment operator.
Definition sims.hpp:2511
const_rcgp_iterator::reference reference
Type of references to value_type.
Definition sims.hpp:2478
word_graph_type::node_type node_type
Type of the nodes in word_graph_type.
Definition sims.hpp:2493
Sims1::felsch_graph_type felsch_graph_type
Type of FelschGraph.
Definition sims.hpp:2490
const_rcgp_iterator::size_type size_type
Size type for const_cgp_iterator.
Definition sims.hpp:2463
For iterating over the right congruence generating pairs.
Definition sims.hpp:2291
const_pointer operator->() const
Definition sims.hpp:2425
void swap(const_rcgp_iterator &that) noexcept
Swap.
relation_type value_type
Type of values pointed to by const_cgp_iterator.
Definition sims.hpp:2314
const_rcgp_iterator & operator=(const_rcgp_iterator &&)=default
Default move assignment operator.
typename std::vector< relation_type >::const_reference const_reference
Type of const references to value_type.
Definition sims.hpp:2307
const_rcgp_iterator(const_rcgp_iterator &&)=default
Default move constructor.
Sims1::word_graph_type word_graph_type
Type of WordGraph.
Definition sims.hpp:2320
typename std::vector< relation_type >::const_pointer const_pointer
Type of const pointers to value_type.
Definition sims.hpp:2301
std::forward_iterator_tag iterator_category
Iterator category (forward iterator).
Definition sims.hpp:2317
const_rcgp_iterator const & operator++()
Prefix increment operator.
bool operator==(const_rcgp_iterator const &that) const noexcept
Check if both iterators point to the same generating pair.
Definition sims.hpp:2403
const_rcgp_iterator()=default
Default constructor.
word_graph_type::label_type label_type
Type of the labels in word_graph_type.
Definition sims.hpp:2329
typename std::vector< relation_type >::pointer pointer
Type of pointers to value_type.
Definition sims.hpp:2304
typename std::vector< relation_type >::size_type size_type
Size type for const_rcgp_iterator.
Definition sims.hpp:2294
bool operator!=(const_rcgp_iterator const &that) const noexcept
Check if both iterators point to distinct generating pairs.
Definition sims.hpp:2409
const_rcgp_iterator(const_rcgp_iterator const &)=default
Default copy constructor.
typename std::vector< relation_type >::difference_type difference_type
Difference type for const_rcgp_iterator.
Definition sims.hpp:2297
const_rcgp_iterator & operator=(const_rcgp_iterator const &)=default
Default copy assignment operator.
const_reference operator*() const
Return a const reference to the generating pair pointed to by the iterator.
Definition sims.hpp:2418
word_graph_type::node_type node_type
Type of the nodes in word_graph_type.
Definition sims.hpp:2326
typename std::vector< relation_type >::reference reference
Type of references to value_type.
Definition sims.hpp:2311
const_rcgp_iterator operator++(int) noexcept
Postfix increment operator.
Definition sims.hpp:2434
Sims1::felsch_graph_type felsch_graph_type
Type of FelschGraph.
Definition sims.hpp:2323
T distance(T... args)
T emplace_back(T... args)
T end(T... args)
T fill(T... args)
std::string to_human_readable_repr(AhoCorasick const &ac)
Return a string representation.
std::conditional_t< R==0||C==0, DynamicBMat, StaticBMat< R, C > > BMat
Alias template for boolean matrices.
Definition matrix.hpp:3963
std::pair< word_type, word_type > relation_type
Type for a pair of word_type (a relation) of a semigroup.
Definition types.hpp:104
T move(T... args)
Namespace for Presentation helper functions.
Definition obvinf.hpp:59
void reverse(Presentation< Word > &p)
Reverse every rule.
Definition presentation.hpp:1543
Helper functions for low-index congruences.
Definition sims.hpp:935
bool is_right_congruence_of_dual(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Check if a word graph defines a right congruence on the dual of an f.p. semigroup or monoid.
Definition sims.hpp:2572
bool is_maximal_right_congruence(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Check if a word graph defines a maximal right congruence on an f.p. semigroup or monoid.
bool is_right_congruence(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Check if a word graph defines a right congruence on an f.p. semigroup or monoid.
void throw_if_not_two_sided_congruence(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Throw if a word graph does not define a two sided congruence on a f.p. semigroup or monoid.
const_cgp_iterator cend_two_sided_generating_pairs(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Get an iterator pointing to one after the last two-sided congruence generating pair.
Definition sims.hpp:2780
rx::iterator_range< const_cgp_iterator > two_sided_generating_pairs_no_checks(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Compute the two-sided congruence generating pairs of a word graph on an f.p. semigroup or monoid (no ...
Definition sims.hpp:2875
rx::iterator_range< const_cgp_iterator > two_sided_generating_pairs(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Range object containing the two-sided congruence generating pairs of a word graph on an f....
Definition sims.hpp:2900
bool is_two_sided_congruence(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Check if a word graph defines a two sided congruence on an f.p. semigroup or monoid.
BMat poset(Iterator first, Iterator last)
Compute the inclusion poset of a collection of congruences defined by word graphs.
const_rcgp_iterator cend_right_generating_pairs(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Get an iterator pointing to one after the last right congruence generating pair.
Definition sims.hpp:2730
Subclass & add_included_pair(SimsSettings< Subclass > &sims, Word const &u, Word const &v)
Helper for adding an included pair of words.
Definition sims.hpp:1025
const_rcgp_iterator cbegin_right_generating_pairs(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Get an iterator pointing to the first right congruence generating pair.
Definition sims.hpp:2642
const_rcgp_iterator cend_right_generating_pairs_no_checks(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Get an iterator pointing to one after the last right congruence generating pair (no checks).
Definition sims.hpp:2714
rx::iterator_range< const_rcgp_iterator > right_generating_pairs_no_checks(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Compute the right congruence generating pairs of a word graph on an f.p. semigroup or monoid (no chec...
Definition sims.hpp:2799
Subclass & add_excluded_pair(SimsSettings< Subclass > &sims, Word const &u, Word const &v)
Helper for adding an excluded pair of words.
Definition sims.hpp:1164
Dot dot_poset(Iterator first, Iterator last)
Construct a Dot object representing the inclusion poset of a collection of word graphs.
const_cgp_iterator cend_two_sided_generating_pairs_no_checks(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Get an iterator pointing to one after the last two-sided congruence generating pair (no checks).
Definition sims.hpp:2757
Subclass & add_excluded_pair_no_checks(SimsSettings< Subclass > &sims, Word const &u, Word const &v)
Helper for adding an excluded pair of words.
Definition sims.hpp:1093
const_rcgp_iterator cbegin_right_generating_pairs_no_checks(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Get an iterator pointing to the first right congruence generating pair (no checks).
Definition sims.hpp:2626
bool is_two_sided_congruence_no_checks(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Check if a word graph defines a two-sided congruence on an f.p. semigroup or monoid (no checks).
const_cgp_iterator cbegin_two_sided_generating_pairs_no_checks(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Get an iterator pointing to the first two-sided congruence generating pair (no checks).
Definition sims.hpp:2670
rx::iterator_range< const_rcgp_iterator > right_generating_pairs(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Compute the right congruence generating pairs of a word graph on an f.p. semigroup or monoid.
Definition sims.hpp:2816
void throw_if_not_right_congruence(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Throw if a word graph does not define a right congruence on a f.p. semigroup or monoid.
const_cgp_iterator cbegin_two_sided_generating_pairs(Presentation< word_type > const &p, WordGraph< Node > const &wg)
Get an iterator pointing to the first two-sided congruence generating pair.
Definition sims.hpp:2694
Subclass & add_included_pair_no_checks(SimsSettings< Subclass > &sims, Word const &u, Word const &v)
Helper for adding an included pair of words.
Definition sims.hpp:954
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
T strlen(T... args)