libsemigroups  v3.0.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
action.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2019-2025 James D. Mitchell
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <http://www.gnu.org/licenses/>.
17//
18
19// This file contains a generic implementation of a class Action which
20// represents the action of a semigroup on a set.
21
22#ifndef LIBSEMIGROUPS_ACTION_HPP_
23#define LIBSEMIGROUPS_ACTION_HPP_
24
25#include <cstddef> // for size_t
26#include <stack> // for stack
27#include <type_traits> // for is_trivially_default_construc...
28#include <unordered_map> // for unordered_map
29#include <utility> // for pair
30#include <vector> // for vector
31
32#include "adapters.hpp" // for One
33#include "constants.hpp" // for UNDEFINED
34#include "debug.hpp" // for LIBSEMIGROUPS_ASSERT
35#include "exception.hpp" // for LIBSEMIGROUPS_EXCEPTION
36#include "forest.hpp" // for Forest
37#include "gabow.hpp" // for Gabow
38#include "runner.hpp" // for Runner
39#include "word-graph.hpp" // for WordGraph
40
41#include "detail/bruidhinn-traits.hpp" // for detail::BruidhinnTraits
42#include "detail/report.hpp" // for report_default
43
44namespace libsemigroups {
82
89 enum class side {
96 };
97
169 template <typename Element,
170 typename Point,
171 typename Func,
172 typename Traits,
173 side LeftOrRight>
174 class Action : public Runner, private detail::BruidhinnTraits<Point> {
176 // Action - typedefs - private
178
179 using internal_point_type =
180 typename detail::BruidhinnTraits<Point>::internal_value_type;
181 using internal_const_point_type =
182 typename detail::BruidhinnTraits<Point>::internal_const_value_type;
183 using internal_const_reference =
184 typename detail::BruidhinnTraits<Point>::internal_const_reference;
185
186 struct InternalEqualTo : private detail::BruidhinnTraits<Point> {
187 using EqualTo = typename Traits::EqualTo;
188 bool operator()(internal_const_point_type x,
189 internal_const_point_type y) const {
190 return EqualTo()(this->to_external_const(x),
191 this->to_external_const(y));
192 }
193 };
194
195 struct InternalHash : private detail::BruidhinnTraits<Point> {
196 using Hash = typename Traits::Hash;
197 size_t operator()(internal_const_point_type x) const {
198 return Hash()(this->to_external_const(x));
199 }
200 };
201
202 // Forward decls
203 class MultiplierCache;
204 struct Options;
205
206 static_assert(
209 internal_const_point_type>::type>::value,
210 "internal_const_element_type must be const or pointer to const");
211
212 public:
214 // Action - typedefs - public
216
221 using element_type = Element;
222
227 using point_type = Point;
228
234 using index_type = size_t;
235
246 using action_type = Func;
247
252 template <typename Elment,
253 typename Pint,
254 typename Fnc,
255 typename Trits,
256 side LftOrRight>
260
265 friend std::ostream& operator<<(std::ostream& os, Action const& action) {
266 os << detail::to_string(action);
267 return os;
268 }
269
271 // Action - iterators - public
273
279 = detail::BruidhinnConstIterator<point_type,
281
287 typename detail::BruidhinnTraits<Point>::const_reference;
288
294 typename detail::BruidhinnTraits<Point>::const_pointer;
295
296 private:
298 // Action - internal types with call operators - private
300
301 using ActionOp = Func;
302 using One = typename Traits::One;
303 using Product = typename Traits::Product;
304 using Swap = typename Traits::Swap;
305
307 "the 3rd template parameter Func is not trivially "
308 "default constructible");
309 // TODO(2) more static assertions
310
312 // Action - product functions for left/right multiplication - private
314
315 auto internal_product(element_type& xy,
316 element_type const& x,
317 element_type const& y) {
318 if constexpr (LeftOrRight == side::right) {
319 Product()(xy, x, y);
320 } else {
321 Product()(xy, y, x);
322 }
323 }
324
326 // Action - data members - private
328
329 // TODO(1) change size_t -> uint32_t
331 WordGraph<uint32_t> _graph;
332 std::unordered_map<internal_const_point_type,
333 size_t,
334 InternalHash,
335 InternalEqualTo>
336 _map;
337 Options _options;
339 MultiplierCache _multipliers_from_scc_root;
340 MultiplierCache _multipliers_to_scc_root;
341 size_t _pos;
342 Gabow<uint32_t> _scc;
343 internal_point_type _tmp_point;
344 bool _tmp_point_init;
345
346 public:
348 // Action - constructor + destructor - public
350
361 Action();
362
372 Action& init();
373
374 //! Default copy constructor.
375 Action(Action const& that) : Action() {
376 *this = that;
377 }
378
379 //! Default move constructor.
380 Action(Action&& that) : Action() {
381 *this = std::move(that);
382 }
383
385 Action& operator=(Action const&);
386
389
390 ~Action();
391
393 // Action - modifiers - public
395
409 Action& reserve(size_t val);
410
427
441 //! Constant.
442 Action& add_generator(element_type const& gen) {
443 // TODO(1) shouldn't this check if the degree of gen is the same as the
444 // degrees of the other generators in _gens?
445 _gens.push_back(gen);
446 return *this;
447 }
448
450 // Action - member functions: position, empty, size, etc - public
452
461 //! Constant.
462 [[nodiscard]] size_t number_of_generators() const noexcept {
463 return _gens.size();
464 }
465
474 //! Constant.
475 [[nodiscard]] std::vector<Element> const& generators() const noexcept {
476 return _gens;
477 }
478
494 [[nodiscard]] index_type position(const_reference_point_type pt) const;
495
505 //! Constant.
506 [[nodiscard]] bool empty() const noexcept {
507 return _orb.empty();
508 }
509
523 [[nodiscard]] inline const_reference_point_type
524 operator[](index_type pos) const noexcept {
525 LIBSEMIGROUPS_ASSERT(pos < _orb.size());
526 return this->to_external_const(_orb[pos]);
527 }
528
541 //! Constant.
542 [[nodiscard]] inline const_reference_point_type at(index_type pos) const {
543 return this->to_external_const(_orb.at(pos));
544 }
545
557 //! points in the orbit and \f$n\f$ is the number of generators.
558 [[nodiscard]] size_t size() {
559 run();
560 return _orb.size();
561 }
562
574 //! Constant.
575 [[nodiscard]] size_t current_size() const noexcept {
576 return _orb.size();
577 }
578
592 //! Constant.
593 [[nodiscard]] const_iterator cbegin() const noexcept {
594 return const_iterator(_orb.cbegin());
595 }
596
597 //! \copydoc cbegin
598 [[nodiscard]] const_iterator begin() const noexcept {
599 return cbegin();
600 }
601
615 // TODO(1) add a reference to the ranges page when it exists
616 [[nodiscard]] auto range() const noexcept {
617 return rx::iterator_range(_orb.cbegin(), _orb.cend())
618 | rx::transform([this](auto const& pt) {
619 return this->to_external_const(pt);
620 });
621 }
622
637 //! Constant.
638 [[nodiscard]] const_iterator cend() const noexcept {
639 return const_iterator(_orb.cend());
640 }
641
642 //! \copydoc cend
643 [[nodiscard]] const_iterator end() const noexcept {
644 return cend();
645 }
646
648 // Action - member functions: strongly connected components - public
650
664 //! Constant.
665 [[nodiscard]] bool cache_scc_multipliers() const noexcept {
666 return _options._cache_scc_multipliers;
667 }
668
684 //! Constant.
685 Action& cache_scc_multipliers(bool val) noexcept {
686 _options._cache_scc_multipliers = val;
687 return *this;
688 }
689
707 //! enumerated orbit.
709 return multiplier_private<true>(
710 _multipliers_from_scc_root, _scc.spanning_forest(), pos);
711 }
712
730 //! enumerated orbit.
732 return multiplier_private<false>(
733 _multipliers_to_scc_root, _scc.reverse_spanning_forest(), pos);
734 }
735
755 // TODO(2) this could be a helper
756 return root_of_scc(position(x));
757 }
758
775 //! enumerated orbit.
777 return this->to_external_const(_orb[_scc.root_of(pos)]);
778 }
779
790 //! enumerated orbit.
791 [[nodiscard]] WordGraph<uint32_t> const& word_graph() {
792 run();
793 return _graph;
794 }
795
810 //! enumerated orbit.
811 [[nodiscard]] Gabow<uint32_t> const& scc() {
812 run();
813 return _scc;
814 }
815
816 private:
818 // Runner - pure virtual member functions - private
820
821 [[nodiscard]] bool finished_impl() const override {
822 return (_pos == _orb.size()) && (_graph.out_degree() == _gens.size());
823 }
824
825 void run_impl() override;
826
828 // Action - member functions - private
830
831 template <bool Forward>
832 element_type multiplier_private(MultiplierCache& mults,
833 Forest const& f,
834 index_type pos);
835
836 void throw_if_index_out_of_range(index_type i) const;
837 void throw_if_no_generators() const;
838 };
839
848 template <typename Element, typename Point>
861
866 template <typename Element,
867 typename Point,
868 typename Func,
869 typename Traits = ActionTraits<Element, Point>>
871
876 template <typename Element,
877 typename Point,
878 typename Func,
879 typename Traits = ActionTraits<Element, Point>>
881} // namespace libsemigroups
882
883#include "action.tpp"
884#endif // LIBSEMIGROUPS_ACTION_HPP_
Class for generating the action of a semigroup.
Definition action.hpp:174
index_type position(const_reference_point_type pt) const
Returns the position of a point in the so far discovered points.
size_t size()
Returns the size of the fully enumerated action.
Definition action.hpp:557
auto range() const noexcept
Returns a range object containing the current points in the action.
Definition action.hpp:615
Action & init()
Initialize an existing Action object.
Action & operator=(Action const &)
Default copy assignment operator.
typename detail::BruidhinnTraits< Point >::const_reference const_reference_point_type
The type of a const reference to a point_type.
Definition action.hpp:285
const_iterator begin() const noexcept
Returns a const_iterator (random access iterator) pointing at the first point.
Definition action.hpp:597
friend std::ostringstream & operator<<(std::ostringstream &os, Action< Elment, Pint, Fnc, Trits, LftOrRight > const &action)
Insertion operator.
bool empty() const noexcept
Checks if the Action contains any points.
Definition action.hpp:505
Func action_type
Type of the action of element_type on point_type.
Definition action.hpp:246
Element element_type
The template parameter Element.
Definition action.hpp:221
typename detail::BruidhinnTraits< Point >::const_pointer const_pointer_point_type
The type of a const pointer to a point_type.
Definition action.hpp:292
element_type multiplier_from_scc_root(index_type pos)
Returns a multiplier from a scc root to a given index.
Definition action.hpp:707
const_iterator end() const noexcept
Returns a const_iterator (random access iterator) pointing one past the last point.
Definition action.hpp:642
Action & add_generator(element_type const &gen)
Add a generator to the action.
Definition action.hpp:441
element_type multiplier_to_scc_root(index_type pos)
Returns a multiplier from a given index to a scc root.
Definition action.hpp:730
size_t number_of_generators() const noexcept
Returns the number of generators.
Definition action.hpp:461
Action & reserve(size_t val)
Increase the capacity to a value that is greater or equal to val.
size_t index_type
The type of the index of a point.
Definition action.hpp:234
Point point_type
The template parameter Point.
Definition action.hpp:227
detail::BruidhinnConstIterator< point_type, std::vector< internal_point_type > > const_iterator
The type of a const iterator pointing to a point_type.
Definition action.hpp:278
const_iterator cend() const noexcept
Returns a const_iterator (random access iterator) pointing one past the last point.
Definition action.hpp:637
Action()
Default constructor.
Gabow< uint32_t > const & scc()
Returns a reference to a Gabow object for strongly connected components.
Definition action.hpp:810
size_t current_size() const noexcept
Returns the number of points found so far.
Definition action.hpp:574
std::vector< Element > const & generators() const noexcept
Returns a const reference to the vector of generators.
Definition action.hpp:474
const_reference_point_type root_of_scc(const_reference_point_type x)
Returns a const reference to the root point of a strongly connected component.
Definition action.hpp:753
const_iterator cbegin() const noexcept
Returns a const_iterator (random access iterator) pointing at the first point.
Definition action.hpp:592
Action & add_seed(const_reference_point_type seed)
Add a seed to the action.
WordGraph< uint32_t > const & word_graph()
Definition action.hpp:790
friend std::ostream & operator<<(std::ostream &os, Action const &action)
Definition action.hpp:265
bool cache_scc_multipliers() const noexcept
Returns whether or not we are caching scc multipliers.
Definition action.hpp:664
const_reference_point_type at(index_type pos) const
Returns a const reference to the point in a given position.
Definition action.hpp:541
const_reference_point_type operator[](index_type pos) const noexcept
Returns a const reference to the point in a given position.
Definition action.hpp:523
Class implementing Gabow's algorithm for computing strongly connected components of a WordGraph.
Definition gabow.hpp:61
void run()
Run until finished.
Runner()
Default constructor.
Class for representing word graphs.
Definition word-graph.hpp:82
size_type out_degree() const noexcept
Returns the out-degree.
Definition word-graph.hpp:823
Action< Element, Point, Func, Traits, side::right > RightAction
Definition action.hpp:870
Action< Element, Point, Func, Traits, side::left > LeftAction
Definition action.hpp:880
side
Enum class indicating the handedness or side of an action.
Definition action.hpp:89
@ right
Definition action.hpp:95
@ left
Definition action.hpp:92
T move(T... args)
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
T size(T... args)
Definition action.hpp:849
::libsemigroups::Hash< Point > Hash
Adapter for hashing.
Definition action.hpp:851
::libsemigroups::Swap< Element > Swap
Adapter for swapping.
Definition action.hpp:855
::libsemigroups::EqualTo< Point > EqualTo
Adapter for testing equality.
Definition action.hpp:853
::libsemigroups::Product< Element > Product
Adapter for the product of two elements.
Definition action.hpp:859
::libsemigroups::One< Element > One
Adapter for the identity element of the given type.
Definition action.hpp:857
Adapter for testing equality.
Definition adapters.hpp:413
Adapter for hashing.
Definition adapters.hpp:446
Adapter for the identity element of the given type.
Definition adapters.hpp:246
Adapter for the product of two elements.
Definition adapters.hpp:284
Adapter for swapping.
Definition adapters.hpp:666