19 #ifndef LIBSEMIGROUPS_SRC_SEMIGROUPS_H_ 20 #define LIBSEMIGROUPS_SRC_SEMIGROUPS_H_ 26 #include <unordered_map> 31 #include "libsemigroups-debug.h" 43 extern Reporter glob_reporter;
49 typedef std::vector<letter_t>
word_t;
63 typedef RecVec<bool> flags_t;
69 typedef size_t index_t;
83 typedef index_t enumerate_index_t;
131 reinterpret_cast<std::vector<
Element const*> const*>(gens)) {}
159 reinterpret_cast<std::vector<
Element const*> const&>(gens)) {}
165 explicit Semigroup(std::initializer_list<Element*> gens)
209 element_index_t
word_to_pos(word_t
const& w)
const;
231 return _lenindex.size() - 2;
232 }
else if (_nr > _lenindex.back()) {
233 return _lenindex.size();
235 return _lenindex.size() - 1;
251 LIBSEMIGROUPS_ASSERT(pos < _gens.size());
261 return (_pos >= _nr);
267 LIBSEMIGROUPS_ASSERT(_lenindex.size() > 1);
268 return (_pos >= _lenindex[1]);
283 if (x->
degree() != _degree) {
287 auto it = _map.find(x);
288 return (it == _map.end() ?
UNDEFINED : it->second);
297 return _elements.size();
314 element_index_t
prefix(element_index_t pos)
const {
315 LIBSEMIGROUPS_ASSERT(pos < _nr);
324 element_index_t
suffix(element_index_t pos)
const {
325 LIBSEMIGROUPS_ASSERT(pos < _nr);
342 LIBSEMIGROUPS_ASSERT(pos < _nr);
359 LIBSEMIGROUPS_ASSERT(pos < _nr);
375 LIBSEMIGROUPS_ASSERT(pos < _nr);
399 element_index_t j)
const;
420 element_index_t
fast_product(element_index_t i, element_index_t j)
const;
433 LIBSEMIGROUPS_ASSERT(i < _nrgens);
434 return _letter_to_pos[i];
489 return _elements.size();
537 return _elements[pos];
550 inline element_index_t
right(element_index_t i, letter_t j) {
552 return _right.get(i, j);
567 inline element_index_t
left(element_index_t i, letter_t j) {
569 return _left.get(i, j);
708 std::atomic<bool> killed(
false);
748 reinterpret_cast<std::vector<Element const*> const*
>(coll));
761 reinterpret_cast<std::vector<Element const*> const&
>(coll));
789 reinterpret_cast<std::vector<Element const*> const*
>(coll));
812 void closure(std::vector<Element const*>
const* coll);
818 void closure(std::vector<Element const*>
const& coll);
824 void closure(std::vector<Element*>
const& coll) {
825 closure(
reinterpret_cast<std::vector<Element const*> const&
>(coll));
832 void closure(std::initializer_list<Element*> coll) {
833 closure(
static_cast<std::vector<Element*>
>(coll));
854 reinterpret_cast<std::vector<Element const*> const*
>(gens));
871 glob_reporter.set_report(val);
883 =
static_cast<unsigned int>(nr_threads == 0 ? 1 : nr_threads);
884 _max_threads = std::min(n, std::thread::hardware_concurrency());
888 template <
typename T,
class C>
class iterator_base {
890 typedef typename std::vector<Element const*>::size_type size_type;
891 typedef typename std::vector<T>::difference_type difference_type;
892 typedef typename std::vector<Element const*>::value_type value_type;
893 typedef typename std::vector<Element const*>::const_reference reference;
894 typedef typename std::vector<Element const*>::const_pointer pointer;
895 typedef std::random_access_iterator_tag iterator_category;
897 explicit iterator_base(
typename std::vector<T>::const_iterator it_vec)
900 iterator_base(iterator_base
const& that) : iterator_base(that._it_vec) {}
902 iterator_base&
operator=(iterator_base
const& that) {
903 _it_vec = that._it_vec;
907 virtual ~iterator_base() {}
909 bool operator==(iterator_base
const& that)
const {
910 return _it_vec == that._it_vec;
913 bool operator!=(iterator_base
const& that)
const {
914 return _it_vec != that._it_vec;
917 bool operator<(iterator_base
const& that)
const {
918 return _it_vec < that._it_vec;
921 bool operator>(iterator_base
const& that)
const {
922 return _it_vec > that._it_vec;
925 bool operator<=(iterator_base
const& that)
const {
926 return operator<(that) || operator==(that);
929 bool operator>=(iterator_base
const& that)
const {
930 return operator>(that) || operator==(that);
933 iterator_base operator++(
int) {
934 iterator_base tmp(*
this);
939 iterator_base operator--(
int) {
940 iterator_base tmp(*
this);
945 iterator_base operator+(size_type val)
const {
946 iterator_base out(*
this);
950 friend iterator_base operator+(size_type val, iterator_base
const& it) {
954 iterator_base operator-(size_type val)
const {
955 iterator_base out(*
this);
960 return *(*
this + pos);
963 iterator_base& operator++() {
968 iterator_base& operator--() {
973 iterator_base& operator+=(size_type val) {
978 iterator_base& operator-=(size_type val) {
983 difference_type operator-(iterator_base that)
const {
984 return _it_vec - that._it_vec;
987 reference operator*()
const {
988 return _methods.indirection(_it_vec);
991 pointer operator->()
const {
992 return _methods.addressof(_it_vec);
996 typename std::vector<T>::const_iterator _it_vec;
997 static C
const _methods;
1000 struct IteratorMethods {
1001 IteratorMethods() {}
1002 typename std::vector<Element const*>::const_reference indirection(
1003 typename std::vector<Element const*>::const_iterator it)
const {
1006 typename std::vector<Element const*>::const_pointer
1007 addressof(
typename std::vector<Element const*>::const_iterator it)
const {
1012 struct IteratorMethodsPairFirst {
1013 IteratorMethodsPairFirst() {}
1014 typename std::vector<Element const*>::const_reference indirection(
1015 typename std::vector<std::pair<Element const*, element_index_t>>::
1016 const_iterator it)
const {
1020 typename std::vector<Element const*>::const_pointer addressof(
1021 typename std::vector<std::pair<Element const*, element_index_t>>::
1022 const_iterator it)
const {
1023 return &((*it).first);
1027 typedef iterator_base<Element const*, IteratorMethods> const_iterator;
1028 typedef iterator_base<std::pair<Element const*, element_index_t>,
1029 IteratorMethodsPairFirst>
1030 const_iterator_pair_first;
1031 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
1032 typedef std::reverse_iterator<const_iterator_pair_first>
1033 const_reverse_iterator_pair_first;
1035 typedef const_iterator_pair_first const_iterator_sorted;
1036 typedef const_iterator_pair_first const_iterator_idempotents;
1037 typedef const_reverse_iterator_pair_first const_reverse_iterator_sorted;
1038 typedef const_reverse_iterator_pair_first
1039 const_reverse_iterator_idempotents;
1050 return const_iterator(_elements.cbegin());
1072 return const_iterator(_elements.cend());
1094 return const_reverse_iterator(
cend());
1105 return const_reverse_iterator(
cbegin());
1116 return const_iterator_pair_first(_sorted.cbegin());
1127 return const_iterator_pair_first(_sorted.cend());
1138 return const_reverse_iterator_pair_first(
cend_sorted());
1163 return const_iterator_pair_first(_idempotents.cbegin());
1173 return const_iterator_pair_first(_idempotents.cend());
1178 void inline expand(index_t nr) {
1180 _reduced.add_rows(nr);
1181 _right.add_rows(nr);
1186 void inline is_one(
Element const* x, element_index_t pos) {
1187 if (!_found_one && *x == *_id) {
1195 void inline closure_update(element_index_t i,
1200 size_t const& thread_id);
1209 typedef std::pair<Element const*, element_index_t> idempotent_value_t;
1213 void init_idempotents();
1220 void idempotents(enumerate_index_t
const first,
1221 enumerate_index_t
const last,
1222 enumerate_index_t
const threshold,
1223 std::vector<idempotent_value_t>& idempotents);
1226 element_index_t _degree;
1227 std::vector<std::pair<letter_t, letter_t>> _duplicate_gens;
1228 std::vector<Element const*> _elements;
1229 std::vector<element_index_t> _enumerate_order;
1230 std::vector<letter_t> _final;
1231 std::vector<letter_t> _first;
1233 std::vector<Element const*> _gens;
1235 std::vector<idempotent_value_t> _idempotents;
1236 bool _idempotents_found;
1237 std::vector<bool> _is_idempotent;
1238 cayley_graph_t _left;
1239 std::vector<index_t> _length;
1240 std::vector<enumerate_index_t> _lenindex;
1241 std::vector<element_index_t> _letter_to_pos;
1242 std::unordered_map<
Element const*,
1247 size_t _max_threads;
1252 enumerate_index_t _pos;
1253 element_index_t _pos_one;
1254 std::vector<element_index_t> _prefix;
1256 letter_t _relation_gen;
1257 enumerate_index_t _relation_pos;
1258 cayley_graph_t _right;
1259 std::vector<std::pair<Element const*, element_index_t>> _sorted;
1260 std::vector<element_index_t> _suffix;
1261 Element* _tmp_product;
1264 static std::vector<element_index_t> _tmp_inverter;
1265 static std::vector<bool> _old_new;
1266 #ifdef LIBSEMIGROUPS_STATS 1267 size_t _nr_products;
1275 template <
typename T,
typename C>
1276 C
const Semigroup::iterator_base<T, C>::_methods;
1279 #endif // LIBSEMIGROUPS_SRC_SEMIGROUPS_H_ Semigroup(std::initializer_list< Element *> gens)
Construct from generators.
Definition: semigroups.h:165
element_index_t position_to_sorted_position(element_index_t pos)
Returns the position of this->at(pos) in the sorted array of elements of the semigroup, or Semigroup::UNDEFINED if pos is greater than the size of the semigroup.
Definition: semigroups.cc:397
void minimal_factorisation(word_t &word, element_index_t pos)
Changes word in-place to contain a minimal word with respect to the short-lex ordering in the generat...
Definition: semigroups.cc:461
static index_t const LIMIT_MAX
This variable is used to indicate the maximum possible limit that can be used with Semigroup::enumera...
Definition: semigroups.h:864
bool is_begun() const
Returns true if no elements other than the generators have been enumerated so far and false otherwise...
Definition: semigroups.h:266
void add_generators(std::vector< Element const *> const *coll)
Add copies of the generators coll to the generators of this.
Definition: semigroups.cc:721
Semigroup(std::vector< Element *> const *gens)
Construct from generators.
Definition: semigroups.h:129
cayley_graph_t * right_cayley_graph_copy()
Returns a copy of the right Cayley graph of the semigroup.
Definition: semigroups.h:558
size_t current_nrrules() const
Returns the number of relations in the presentation for the semigroup that have been found so far...
Definition: semigroups.h:305
Semigroup * copy_add_generators(std::vector< Element *> const *coll) const
Returns a new semigroup generated by this and coll.
Definition: semigroups.h:787
void reset_next_relation()
This method resets Semigroup::next_relation so that when it is next called the resulting relation is ...
Definition: semigroups.h:642
Semigroup(std::vector< Element const *> *gens)
Construct from generators.
Definition: semigroups.h:145
virtual size_t degree() const =0
Returns the degree of an Element.
const_reverse_iterator_sorted crend_sorted()
Returns a const iterator pointing to one before the first element of the semigroup when the elements ...
Definition: semigroups.h:1147
Semigroup(std::vector< Element const *> const *gens)
Construct from generators.
Definition: semigroups.cc:38
void add_generators(std::initializer_list< Element *> coll)
Add copies of the generators coll to the generators of this.
Definition: semigroups.h:767
Semigroup * copy_add_generators(std::vector< Element const *> const *coll) const
Returns a new semigroup generated by this and coll.
Definition: semigroups.cc:705
element_index_t right(element_index_t i, letter_t j)
Returns the index of the product of the element in position i with the generator with index j...
Definition: semigroups.h:550
element_index_t product_by_reduction(element_index_t i, element_index_t j) const
Returns the position in this of the product of this->at(i) and this->at(j) by following a path in the...
Definition: semigroups.cc:332
void set_batch_size(size_t batch_size)
Set a new value for the batch size.
Definition: semigroups.h:472
void enumerate(size_t limit=LIMIT_MAX)
Enumerate the semigroup until limit elements are found.
Definition: semigroups.h:707
Element const * sorted_at(element_index_t pos)
Returns the element of the semigroup in position pos of the sorted array of elements, or nullptr in pos is not valid (i.e. too big).
Definition: semigroups.cc:419
std::vector< letter_t > word_t
Type for a word over the generators of a semigroup.
Definition: semigroups.h:49
Provides a call operator for comparing Elements via pointers.
Definition: elements.h:232
const_reverse_iterator_sorted crbegin_sorted()
Returns a const iterator pointing to the last element of the semigroup when the elements are sorted b...
Definition: semigroups.h:1136
const_iterator begin() const
Returns a const iterator pointing to the first element of the semigroup.
Definition: semigroups.h:1060
Abstract base class for semigroup elements.
Definition: elements.h:57
size_t length_non_const(element_index_t pos)
Returns the length of the element in position pos of the semigroup.
Definition: semigroups.h:383
const_iterator cend() const
Returns a const iterator pointing to one past the last currently known element of the semigroup...
Definition: semigroups.h:1071
size_t current_size() const
Returns the number of elements in the semigroup that have been enumerated so far. ...
Definition: semigroups.h:296
element_index_t letter_to_pos(letter_t i) const
Returns the position in this of the generator with index i.
Definition: semigroups.h:432
element_index_t sorted_position(Element const *x)
Returns the position of x in the sorted array of elements of the semigroup, or Semigroup::UNDEFINED i...
Definition: semigroups.cc:406
const_reverse_iterator crbegin() const
Returns a const reverse iterator pointing to the last currently known element of the semigroup...
Definition: semigroups.h:1093
void closure(std::initializer_list< Element *> coll)
Add copies of the non-redundant generators in coll to the generators of this.
Definition: semigroups.h:832
const_iterator_idempotents cbegin_idempotents()
Returns a const iterator pointing at the first idempotent in the semigroup.
Definition: semigroups.h:1161
Element const * operator[](element_index_t pos) const
Returns the element of the semigroup in position pos.
Definition: semigroups.h:536
Semigroup(std::vector< Element *> const &gens)
Construct from generators.
Definition: semigroups.h:157
void enumerate(std::atomic< bool > &killed, size_t limit=LIMIT_MAX)
Enumerate the semigroup until limit elements are found or killed is true.
Definition: semigroups.cc:523
const_iterator_sorted cend_sorted()
Returns a const iterator pointing to one past the last element of the semigroup when the elements are...
Definition: semigroups.h:1125
element_index_t fast_product(element_index_t i, element_index_t j) const
Returns the position in this of the product of this->at(i) and this->at(j).
Definition: semigroups.cc:352
Element const * at(element_index_t pos)
Returns the element of the semigroup in position pos, or a nullptr if there is no such element...
Definition: semigroups.cc:410
letter_t first_letter(element_index_t pos) const
Returns the first letter of the element in position pos.
Definition: semigroups.h:341
void set_report(bool val) const
Turn reporting on or off.
Definition: semigroups.h:870
element_index_t position(Element const *x)
Returns the position of x in this, or Semigroup::UNDEFINED if x is not an element of this...
Definition: semigroups.cc:378
word_t * factorisation(element_index_t pos)
Returns a pointer to a libsemigroups::word_t which evaluates to the Element in position pos of this...
Definition: semigroups.h:625
element_index_t left(element_index_t i, letter_t j)
Returns the index of the product of the generator with index j and the element in position i...
Definition: semigroups.h:567
size_t length_const(element_index_t pos) const
Returns the length of the element in position pos of the semigroup.
Definition: semigroups.h:374
const_iterator_idempotents cend_idempotents()
Returns a const iterator referring to past the end of the last idempotent in the semigroup.
Definition: semigroups.h:1171
size_t nrrules()
Returns the total number of relations in the presentation defining the semigroup. ...
Definition: semigroups.h:455
const_reverse_iterator crend() const
Returns a const reverse iterator pointing to one before the first element of the semigroup.
Definition: semigroups.h:1104
size_t degree() const
Returns the degree of any (and all) Element's in the semigroup.
Definition: semigroups.h:240
void set_max_threads(size_t nr_threads)
Set the maximum number of threads that any method of an instance of Semigroup can use...
Definition: semigroups.h:881
Semigroup(std::vector< Element *> *gens)
Construct from generators.
Definition: semigroups.h:137
Semigroup & operator=(Semigroup const &semigroup)=delete
Deleted.
Namespace for everything in the libsemigroups library.
Definition: blocks.cc:32
const_iterator end() const
Returns a const iterator pointing to one past the last currently known element of the semigroup...
Definition: semigroups.h:1082
bool is_done() const
Returns true if the semigroup is fully enumerated and false if not.
Definition: semigroups.h:260
bool is_idempotent(element_index_t pos)
Returns true if the element in position pos is an idempotent and false if it is not.
Definition: semigroups.cc:370
void reserve(size_t n)
Requests that the capacity (i.e. number of elements) of the semigroup be at least enough to contain n...
Definition: semigroups.cc:279
RecVec< element_index_t > cayley_graph_t
Type for a left or right Cayley graph of a semigroup.
Definition: semigroups.h:92
element_index_t word_to_pos(word_t const &w) const
Returns the position in the semigroup corresponding to the element represented by the word w...
Definition: semigroups.cc:302
void add_generators(std::vector< Element *> const &coll)
Add copies of the generators coll to the generators of this.
Definition: semigroups.h:759
letter_t final_letter(element_index_t pos) const
Returns the last letter of the element in position pos.
Definition: semigroups.h:358
element_index_t current_position(Element const *x) const
Returns the position of the element x in the semigroup if it is already known to belong to the semigr...
Definition: semigroups.h:282
size_t size()
Returns the size of the semigroup.
Definition: semigroups.h:487
static index_t const UNDEFINED
This variable is used to indicate that a value is undefined, such as, for example, the position of an element that does not belong to a semigroup.
Definition: semigroups.h:860
size_t current_max_word_length() const
Returns the maximum length of a word in the generators so far computed.
Definition: semigroups.h:229
Class for semigroups generated by instances of Element.
Definition: semigroups.h:62
size_t letter_t
Type for the index of a generator of a semigroup.
Definition: semigroups.h:46
size_t nridempotents()
Returns the total number of idempotents in the semigroup.
Definition: semigroups.cc:365
std::pair< word_t, word_t > relation_t
Type for a pair of word_t (a relation) of a semigroup.
Definition: semigroups.h:52
void factorisation(word_t &word, element_index_t pos)
Changes word in-place to contain a word in the generators equal to the pos element of the semigroup...
Definition: semigroups.h:614
Element * word_to_element(word_t const &w) const
Returns a pointer to the element of this represented by the word w.
Definition: semigroups.cc:315
~Semigroup()
A default destructor.
Definition: semigroups.cc:264
Semigroup * copy_closure(std::vector< Element const *> const *coll)
Returns a new semigroup generated by this and copies of the non-redundant elements of coll...
Definition: semigroups.cc:670
size_t batch_size() const
Returns the current value of the batch size. This is the minimum number of elements enumerated in any...
Definition: semigroups.h:365
bool test_membership(Element const *x)
Returns true if x is an element of this and false if it is not.
Definition: semigroups.h:499
Provides a call operator returning a hash value for an Element via a pointer.
Definition: elements.h:245
void closure(std::vector< Element const *> const *coll)
Add copies of the non-redundant generators in coll to the generators of this.
Definition: semigroups.cc:690
void closure(std::vector< Element *> const &coll)
Add copies of the non-redundant generators in coll to the generators of this.
Definition: semigroups.h:824
const_iterator_sorted cbegin_sorted()
Returns a const iterator pointing to the first element of the semigroup when the elements are sorted ...
Definition: semigroups.h:1114
cayley_graph_t * left_cayley_graph_copy()
Returns a copy of the left Cayley graph of the semigroup.
Definition: semigroups.h:575
const_iterator cbegin() const
Returns a const iterator pointing to the first element of the semigroup.
Definition: semigroups.h:1049
Element const * gens(letter_t pos) const
Return a pointer to the generator with index pos.
Definition: semigroups.h:250
Semigroup * copy_closure(std::vector< Element *> const *gens)
Returns a new semigroup generated by this and copies of the non-redundant elements of coll...
Definition: semigroups.h:852
void add_generators(std::vector< Element *> const *coll)
Add copies of the generators coll to the generators of this.
Definition: semigroups.h:746
index_t element_index_t
Type for the position of an element in an instance of Semigroup. The size of the semigroup being enum...
Definition: semigroups.h:89
element_index_t suffix(element_index_t pos) const
Returns the position of the suffix of the element x in position pos (of the semigroup) of length one ...
Definition: semigroups.h:324
size_t nrgens() const
Returns the number of generators of the semigroup.
Definition: semigroups.h:245
void next_relation(word_t &relation)
This method changes relation in-place to contain the next relation of the presentation defining this...
Definition: semigroups.cc:475
element_index_t prefix(element_index_t pos) const
Returns the position of the prefix of the element x in position pos (of the semigroup) of length one ...
Definition: semigroups.h:314