libsemigroups
semigroups.h
1 //
2 // libsemigroups - C++ library for semigroups and monoids
3 // Copyright (C) 2016 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_SRC_SEMIGROUPS_H_
20 #define LIBSEMIGROUPS_SRC_SEMIGROUPS_H_
21 
22 #include <algorithm>
23 #include <mutex>
24 #include <string>
25 #include <thread>
26 #include <unordered_map>
27 #include <utility>
28 #include <vector>
29 
30 #include "elements.h"
31 #include "libsemigroups-debug.h"
32 #include "recvec.h"
33 #include "report.h"
34 
36 namespace libsemigroups {
37 
38  class RWSE;
39 
40  // This object is used for printing information during a computation. The
41  // reason it is global is that we must be able to report from different
42  // threads running concurrently.
43  extern Reporter glob_reporter;
44 
46  typedef size_t letter_t;
47 
49  typedef std::vector<letter_t> word_t;
50 
52  typedef std::pair<word_t, word_t> relation_t;
53 
62  class Semigroup {
63  typedef RecVec<bool> flags_t;
64 
65  // Type used for indexing elements in a Semigroup, use this when not
66  // specifically referring to a position in _elements. It should be possible
67  // to change this type and everything will just work, provided the size of
68  // the semigroup is less than the maximum value of this type of integer.
69  typedef size_t index_t;
70 
71  // The elements of a semigroup are stored in _elements, but because of the
72  // way add_generators/closure work, it might not be the case that all the
73  // words of a given length are contiguous in _elements. Hence we require a
74  // means of finding the next element of a given length. In
75  // _enumerate_order, the first K_1 values are element_index_t's
76  // equal to the positions in _elements of the words of length 1,
77  // the next K_2 values are the element_index_t's equal to the positions in
78  // _elements of the words of length 2, and so on.
79  //
80  // This typedef is used to distinguish variables that refer to positions in
81  // _elements (element_index_t) from those that refer to positions in
82  // _enumerate_order (enumerate_index_t).
83  typedef index_t enumerate_index_t;
84 
85  public:
89  typedef index_t element_index_t;
90 
92  typedef RecVec<element_index_t> cayley_graph_t;
93 
94  public:
101  Semigroup& operator=(Semigroup const& semigroup) = delete;
102 
122  explicit Semigroup(std::vector<Element const*> const* gens);
123 
129  explicit Semigroup(std::vector<Element*> const* gens)
130  : Semigroup(
131  reinterpret_cast<std::vector<Element const*> const*>(gens)) {}
132 
137  explicit Semigroup(std::vector<Element*>* gens)
138  : Semigroup(const_cast<std::vector<Element*> const*>(gens)) {}
139 
145  explicit Semigroup(std::vector<Element const*>* gens)
146  : Semigroup(const_cast<std::vector<Element const*> const*>(gens)) {}
147 
151  explicit Semigroup(std::vector<Element const*> const& gens);
152 
157  explicit Semigroup(std::vector<Element*> const& gens)
158  : Semigroup(
159  reinterpret_cast<std::vector<Element const*> const&>(gens)) {}
160 
165  explicit Semigroup(std::initializer_list<Element*> gens)
166  : Semigroup(static_cast<std::vector<Element*>>(gens)) {}
167 
173  Semigroup(const Semigroup& copy);
174 
175  private:
176  // Partial copy.
177  // \p copy a semigroup
178  // \p coll a collection of additional generators
179  //
180  // This is a constructor for a semigroup generated by the generators of the
181  // Semigroup copy and the (possibly) additional generators coll.
182  //
183  // The relevant parts of the data structure of copy are copied and
184  // \c this will be corrupt unless add_generators or closure is called
185  // subsequently. This is why this method is private.
186  //
187  // The same effect can be obtained by copying copy using the copy
188  // constructor and then calling add_generators or closure. However,
189  // this constructor avoids copying those parts of the data structure of
190  // copy that add_generators invalidates anyway. If copy has not been
191  // enumerated at all, then these two routes for adding more generators are
192  // equivalent.
193  Semigroup(Semigroup const& copy, std::vector<Element const*> const* coll);
194 
195  public:
197  ~Semigroup();
198 
209  element_index_t word_to_pos(word_t const& w) const;
210 
220  Element* word_to_element(word_t const& w) const;
221 
229  size_t current_max_word_length() const {
230  if (is_done()) {
231  return _lenindex.size() - 2;
232  } else if (_nr > _lenindex.back()) {
233  return _lenindex.size();
234  } else {
235  return _lenindex.size() - 1;
236  }
237  }
238 
240  size_t degree() const {
241  return _degree;
242  }
243 
245  size_t nrgens() const {
246  return _gens.size();
247  }
248 
250  Element const* gens(letter_t pos) const {
251  LIBSEMIGROUPS_ASSERT(pos < _gens.size());
252  return _gens[pos];
253  }
254 
260  bool is_done() const {
261  return (_pos >= _nr);
262  }
263 
266  bool is_begun() const {
267  LIBSEMIGROUPS_ASSERT(_lenindex.size() > 1);
268  return (_pos >= _lenindex[1]);
269  }
270 
282  element_index_t current_position(Element const* x) const {
283  if (x->degree() != _degree) {
284  return UNDEFINED;
285  }
286 
287  auto it = _map.find(x);
288  return (it == _map.end() ? UNDEFINED : it->second);
289  }
290 
296  size_t current_size() const {
297  return _elements.size();
298  }
299 
305  size_t current_nrrules() const {
306  return _nrrules;
307  }
308 
314  element_index_t prefix(element_index_t pos) const {
315  LIBSEMIGROUPS_ASSERT(pos < _nr);
316  return _prefix[pos];
317  }
318 
324  element_index_t suffix(element_index_t pos) const {
325  LIBSEMIGROUPS_ASSERT(pos < _nr);
326  return _suffix[pos];
327  }
328 
341  letter_t first_letter(element_index_t pos) const {
342  LIBSEMIGROUPS_ASSERT(pos < _nr);
343  return _first[pos];
344  }
345 
358  letter_t final_letter(element_index_t pos) const {
359  LIBSEMIGROUPS_ASSERT(pos < _nr);
360  return _final[pos];
361  }
362 
365  size_t batch_size() const {
366  return _batch_size;
367  }
368 
374  size_t length_const(element_index_t pos) const {
375  LIBSEMIGROUPS_ASSERT(pos < _nr);
376  return _length[pos];
377  }
378 
383  size_t length_non_const(element_index_t pos) {
384  if (pos >= _nr) {
385  enumerate();
386  }
387  return length_const(pos);
388  }
389 
398  element_index_t product_by_reduction(element_index_t i,
399  element_index_t j) const;
400 
420  element_index_t fast_product(element_index_t i, element_index_t j) const;
421 
432  element_index_t letter_to_pos(letter_t i) const {
433  LIBSEMIGROUPS_ASSERT(i < _nrgens);
434  return _letter_to_pos[i];
435  }
436 
442  size_t nridempotents();
443 
449  bool is_idempotent(element_index_t pos);
450 
455  size_t nrrules() {
456  enumerate();
457  return _nrrules;
458  }
459 
471  // FIXME Make _batch_size mutable and this const
472  void set_batch_size(size_t batch_size) {
473  _batch_size = batch_size;
474  }
475 
484  void reserve(size_t n);
485 
487  size_t size() {
488  enumerate();
489  return _elements.size();
490  }
491 
499  bool test_membership(Element const* x) {
500  return (position(x) != UNDEFINED);
501  }
502 
512  element_index_t position(Element const* x);
513 
517  element_index_t sorted_position(Element const* x);
518 
522  element_index_t position_to_sorted_position(element_index_t pos);
523 
530  Element const* at(element_index_t pos);
531 
536  Element const* operator[](element_index_t pos) const {
537  return _elements[pos];
538  }
539 
544  Element const* sorted_at(element_index_t pos);
545 
550  inline element_index_t right(element_index_t i, letter_t j) {
551  enumerate();
552  return _right.get(i, j);
553  }
554 
558  cayley_graph_t* right_cayley_graph_copy() {
559  enumerate();
560  return new cayley_graph_t(_right);
561  }
562 
567  inline element_index_t left(element_index_t i, letter_t j) {
568  enumerate();
569  return _left.get(i, j);
570  }
571 
575  cayley_graph_t* left_cayley_graph_copy() {
576  enumerate();
577  return new cayley_graph_t(_left);
578  }
579 
591  void minimal_factorisation(word_t& word, element_index_t pos);
592 
599  word_t* minimal_factorisation(element_index_t pos);
600 
606  word_t* minimal_factorisation(Element const* x);
607 
614  void factorisation(word_t& word, element_index_t pos) {
615  minimal_factorisation(word, pos);
616  }
617 
625  word_t* factorisation(element_index_t pos) {
626  return minimal_factorisation(pos);
627  }
628 
634  word_t* factorisation(Element const* x);
635 
643  _relation_pos = UNDEFINED;
644  _relation_gen = 0;
645  }
646 
678  void next_relation(word_t& relation);
679 
701  void enumerate(std::atomic<bool>& killed, size_t limit = LIMIT_MAX);
702 
707  void enumerate(size_t limit = LIMIT_MAX) {
708  std::atomic<bool> killed(false);
709  enumerate(killed, limit);
710  }
711 
741  void add_generators(std::vector<Element const*> const* coll);
742 
746  void add_generators(std::vector<Element*> const* coll) {
748  reinterpret_cast<std::vector<Element const*> const*>(coll));
749  }
750 
754  void add_generators(std::vector<Element const*> const& coll);
755 
759  void add_generators(std::vector<Element*> const& coll) {
761  reinterpret_cast<std::vector<Element const*> const&>(coll));
762  }
763 
767  void add_generators(std::initializer_list<Element*> coll) {
768  add_generators(static_cast<std::vector<Element*>>(coll));
769  }
770 
781  Semigroup*
782  copy_add_generators(std::vector<Element const*> const* coll) const;
783 
787  Semigroup* copy_add_generators(std::vector<Element*> const* coll) const {
788  return copy_add_generators(
789  reinterpret_cast<std::vector<Element const*> const*>(coll));
790  }
791 
812  void closure(std::vector<Element const*> const* coll);
813 
818  void closure(std::vector<Element const*> const& coll);
819 
824  void closure(std::vector<Element*> const& coll) {
825  closure(reinterpret_cast<std::vector<Element const*> const&>(coll));
826  }
827 
832  void closure(std::initializer_list<Element*> coll) {
833  closure(static_cast<std::vector<Element*>>(coll));
834  }
835 
846  Semigroup* copy_closure(std::vector<Element const*> const* coll);
847 
852  Semigroup* copy_closure(std::vector<Element*> const* gens) {
853  return copy_closure(
854  reinterpret_cast<std::vector<Element const*> const*>(gens));
855  }
856 
860  static index_t const UNDEFINED;
861 
864  static index_t const LIMIT_MAX;
865 
867  //
870  void set_report(bool val) const {
871  glob_reporter.set_report(val);
872  }
873 
881  void set_max_threads(size_t nr_threads) {
882  unsigned int n
883  = static_cast<unsigned int>(nr_threads == 0 ? 1 : nr_threads);
884  _max_threads = std::min(n, std::thread::hardware_concurrency());
885  }
886 
887  private:
888  template <typename T, class C> class iterator_base {
889  public:
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;
896 
897  explicit iterator_base(typename std::vector<T>::const_iterator it_vec)
898  : _it_vec(it_vec) {}
899 
900  iterator_base(iterator_base const& that) : iterator_base(that._it_vec) {}
901 
902  iterator_base& operator=(iterator_base const& that) {
903  _it_vec = that._it_vec;
904  return *this;
905  }
906 
907  virtual ~iterator_base() {}
908 
909  bool operator==(iterator_base const& that) const {
910  return _it_vec == that._it_vec;
911  }
912 
913  bool operator!=(iterator_base const& that) const {
914  return _it_vec != that._it_vec;
915  }
916 
917  bool operator<(iterator_base const& that) const {
918  return _it_vec < that._it_vec;
919  }
920 
921  bool operator>(iterator_base const& that) const {
922  return _it_vec > that._it_vec;
923  }
924 
925  bool operator<=(iterator_base const& that) const {
926  return operator<(that) || operator==(that);
927  }
928 
929  bool operator>=(iterator_base const& that) const {
930  return operator>(that) || operator==(that);
931  }
932 
933  iterator_base operator++(int) { // postfix
934  iterator_base tmp(*this);
935  operator++();
936  return tmp;
937  }
938 
939  iterator_base operator--(int) {
940  iterator_base tmp(*this);
941  operator--();
942  return tmp;
943  }
944 
945  iterator_base operator+(size_type val) const {
946  iterator_base out(*this);
947  return out += val;
948  }
949 
950  friend iterator_base operator+(size_type val, iterator_base const& it) {
951  return it + val;
952  }
953 
954  iterator_base operator-(size_type val) const {
955  iterator_base out(*this);
956  return out -= val;
957  }
958 
959  reference operator[](size_type pos) const {
960  return *(*this + pos);
961  }
962 
963  iterator_base& operator++() { // prefix
964  ++_it_vec;
965  return *this;
966  }
967 
968  iterator_base& operator--() {
969  --_it_vec;
970  return *this;
971  }
972 
973  iterator_base& operator+=(size_type val) {
974  _it_vec += val;
975  return *this;
976  }
977 
978  iterator_base& operator-=(size_type val) {
979  _it_vec -= val;
980  return *this;
981  }
982 
983  difference_type operator-(iterator_base that) const {
984  return _it_vec - that._it_vec;
985  }
986 
987  reference operator*() const {
988  return _methods.indirection(_it_vec);
989  }
990 
991  pointer operator->() const {
992  return _methods.addressof(_it_vec);
993  }
994 
995  protected:
996  typename std::vector<T>::const_iterator _it_vec;
997  static C const _methods;
998  }; // iterator_base definition ends
999 
1000  struct IteratorMethods {
1001  IteratorMethods() {}
1002  typename std::vector<Element const*>::const_reference indirection(
1003  typename std::vector<Element const*>::const_iterator it) const {
1004  return *it;
1005  }
1006  typename std::vector<Element const*>::const_pointer
1007  addressof(typename std::vector<Element const*>::const_iterator it) const {
1008  return &(*it);
1009  }
1010  };
1011 
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 {
1017  return (*it).first;
1018  }
1019 
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);
1024  }
1025  };
1026 
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;
1034 
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;
1040 
1041  public:
1049  const_iterator cbegin() const {
1050  return const_iterator(_elements.cbegin());
1051  }
1052 
1060  const_iterator begin() const {
1061  return cbegin();
1062  }
1063 
1071  const_iterator cend() const {
1072  return const_iterator(_elements.cend());
1073  }
1074 
1082  const_iterator end() const {
1083  return cend();
1084  }
1085 
1093  const_reverse_iterator crbegin() const {
1094  return const_reverse_iterator(cend());
1095  }
1096 
1104  const_reverse_iterator crend() const {
1105  return const_reverse_iterator(cbegin());
1106  }
1107 
1114  const_iterator_sorted cbegin_sorted() {
1115  init_sorted();
1116  return const_iterator_pair_first(_sorted.cbegin());
1117  }
1118 
1125  const_iterator_sorted cend_sorted() {
1126  init_sorted();
1127  return const_iterator_pair_first(_sorted.cend());
1128  }
1129 
1136  const_reverse_iterator_sorted crbegin_sorted() {
1137  init_sorted();
1138  return const_reverse_iterator_pair_first(cend_sorted());
1139  }
1140 
1147  const_reverse_iterator_sorted crend_sorted() {
1148  init_sorted();
1149  return const_reverse_iterator_pair_first(cbegin_sorted());
1150  }
1151 
1161  const_iterator_idempotents cbegin_idempotents() {
1162  init_idempotents();
1163  return const_iterator_pair_first(_idempotents.cbegin());
1164  }
1165 
1171  const_iterator_idempotents cend_idempotents() {
1172  init_idempotents();
1173  return const_iterator_pair_first(_idempotents.cend());
1174  }
1175 
1176  private:
1177  // Expand the data structures in the semigroup with space for nr elements
1178  void inline expand(index_t nr) {
1179  _left.add_rows(nr);
1180  _reduced.add_rows(nr);
1181  _right.add_rows(nr);
1182  }
1183 
1184  // Check if an element is the identity, x should be in the position pos
1185  // of _elements.
1186  void inline is_one(Element const* x, element_index_t pos) {
1187  if (!_found_one && *x == *_id) {
1188  _pos_one = pos;
1189  _found_one = true;
1190  }
1191  }
1192 
1193  void copy_gens();
1194 
1195  void inline closure_update(element_index_t i,
1196  letter_t j,
1197  letter_t b,
1198  element_index_t s,
1199  index_t old_nr,
1200  size_t const& thread_id);
1201 
1202  // Initialise the data member _sorted. We store a list of pairs consisting
1203  // of an Element* and element_index_t which is sorted on the first entry
1204  // using the operator< of the Element class. The second component is then
1205  // inverted (as a permutation) so that we can then find the position of an
1206  // element in the sorted list of elements.
1207  void init_sorted();
1208 
1209  typedef std::pair<Element const*, element_index_t> idempotent_value_t;
1210 
1211  // Find the idempotents and store their pointers and positions in a
1212  // std::pair of type idempotent_value_t.
1213  void init_idempotents();
1214 
1215  // Find the idempotents in the range [first, last) and store
1216  // the corresponding std::pair of type idempotent_value_t in the 4th
1217  // parameter. The parameter threshold is the point, calculated in
1218  // init_idempotents, at which it is better to simply multiply elements
1219  // rather than trace in the left/right Cayley graph.
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);
1224 
1225  size_t _batch_size;
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;
1232  bool _found_one;
1233  std::vector<Element const*> _gens;
1234  Element const* _id;
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*,
1244  Element::Hash,
1246  _map;
1247  size_t _max_threads;
1248  std::mutex _mtx;
1249  index_t _nr;
1250  letter_t _nrgens;
1251  size_t _nrrules;
1252  enumerate_index_t _pos;
1253  element_index_t _pos_one;
1254  std::vector<element_index_t> _prefix;
1255  flags_t _reduced;
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;
1262  size_t _wordlen;
1263 
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;
1268 #endif
1269  };
1270 
1274 
1275  template <typename T, typename C>
1276  C const Semigroup::iterator_base<T, C>::_methods;
1277 } // namespace libsemigroups
1278 
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&#39;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