libsemigroups  v3.2.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
stephen.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#ifndef LIBSEMIGROUPS_STEPHEN_HPP_
20#define LIBSEMIGROUPS_STEPHEN_HPP_
21
22#include <array> // for array
23#include <cstddef> // for size_t
24#include <cstdint> // for uint32_t
25#include <memory> // for shared_ptr
26#include <string> // for string
27#include <tuple> // for tie
28#include <utility> // for make_pair
29#include <vector> // for vector
30
31#include "constants.hpp" // for Max, UNDEFINED
32#include "debug.hpp" // for LIBSEMIGROUPS_ASSERT
33#include "dot.hpp" // for Dot
34#include "exception.hpp" // for LIBSEMIGROUPS_EXCEPTION
35#include "paths.hpp" // for Paths
36#include "presentation.hpp" // for Presentation
37#include "runner.hpp" // for Runner
38#include "types.hpp" // for word_type
39#include "word-graph.hpp" // for WordGraph
40
41#include "detail/felsch-graph.hpp" // for DoNotReg...
42#include "detail/node-managed-graph.hpp" // for NodeMana...
43#include "detail/node-manager.hpp" // for NodeManager
44#include "detail/report.hpp" // for report_n...
45#include "detail/string.hpp" // for group_di...
46#include "detail/word-graph-with-sources.hpp" // for WordGrap...
47
48// TODO(2)
49// * update so that run_for, run_until work properly (at present basically
50// run_impl starts again from scratch every time)
51// * minimal rep (as per Reinis) (named normal_form?)
52// * invert() - just swap the initial and accept states and re-standardize
53// * idempotent() - just make the accept state = initial state.
54// * class_of for inverse Stephen (i.e. all walks in the graph through all
55// nodes) (not sure how to do this just yet). This is different than
56// words_accepted see Corollary 3.2 in Stephen's "Presentations of inverse
57// monoids" paper (not thesis).
58// * canonical_form (as per Howie's book)
59
64
65namespace libsemigroups {
66
89 template <typename PresentationType>
90 class Stephen : public Runner {
91 template <typename Q>
92 static constexpr bool is_valid_presentation() {
93 return std::is_same_v<Q, Presentation<word_type>>
94 || std::is_same_v<Q, InversePresentation<word_type>>;
95 // TODO(2): uncomment when we figure out how to handle std::string
96 // presentations
97 //|| std::is_same_v<Q, Presentation<std::string>>
98 //|| std::is_same_v<Q, InversePresentation<std::string>>;
99 }
100
101 // TODO (2): Change the error message once std::string presentations are
102 // supported
103 static_assert(is_valid_presentation<PresentationType>(),
104 "the template parameter PresentationType must be "
105 "Presentation<word_type> or InversePresentation<word_type>");
106
107 public:
109 using presentation_type = PresentationType;
110
115
116 private:
117 class StephenGraph; // forward decl
118
119 // Data members
120 node_type _accept_state;
121 bool _finished;
122 bool _is_word_set;
124 word_type _word;
125 StephenGraph _word_graph;
126
127 public:
136
147
148 // TODO(2): Implement make<Stephen> function which checks args
149 // Should presentation::throw_if_not_normalized (until we separate the
150 // implementation and external interface later on).
151 // Should also throw if `p.throw_if_bad_alphabet_or_rules()` throws.
152 // Should also throw if if `p.alphabet().size()` is `0`.
153
162 // Not noexcept because allocated memory
163 explicit Stephen(PresentationType const& p) : Stephen() {
164 init(p);
165 }
166
175 explicit Stephen(PresentationType&& p) : Stephen() {
176 init(std::move(p));
177 }
178
188 init(ptr);
189 }
190
192 Stephen(Stephen const& that) = default;
193
195 Stephen(Stephen&&) = default;
196
198 Stephen& operator=(Stephen const&) = default;
199
201 Stephen& operator=(Stephen&&) = default;
202
203 ~Stephen();
204
216 Stephen& init(PresentationType const& p) {
218 }
219
231 Stephen& init(PresentationType&& p) {
233 }
234
247
256 presentation_type const& presentation() const noexcept {
257 return *_presentation;
258 }
259
275 template <typename Iterator1, typename Iterator2>
276 Stephen& set_word(Iterator1 first, Iterator2 last) {
277 presentation().throw_if_letter_not_in_alphabet(first, last);
278 return set_word_no_checks(first, last);
279 }
280
296 template <typename Iterator1, typename Iterator2>
297 Stephen& set_word_no_checks(Iterator1 first, Iterator2 last);
298
308 bool is_word_set() const noexcept {
309 return _is_word_set;
310 }
311
321 word_type const& word() const {
322 throw_if_not_ready();
323 return _word;
324 }
325
338 throw_if_not_ready();
339 return _word_graph;
340 }
341
355 // Throws if run throws, also this is not in the helper namespace because
356 // we cache the return value.
358
367 static constexpr node_type initial_state() noexcept {
368 return 0;
369 }
370
391
412
413 private:
415 // Reporting
417
418 void report_after_run() const;
419 void report_before_run() const;
420 void report_progress_from_thread() const;
421
422 Stephen& init_after_presentation_set();
423
424 void throw_if_presentation_empty(presentation_type const& p) const {
425 if (p.alphabet().empty()) {
426 LIBSEMIGROUPS_EXCEPTION("the presentation must not have 0 generators");
427 }
428 }
429
430 void throw_if_not_ready() const;
431
432 void init_word_graph_from_word_no_checks() {
433 _word_graph.init(presentation());
434 _word_graph.report_prefix("Stephen");
435 _word_graph.complete_path(
436 presentation(), 0, _word.cbegin(), _word.cend());
437 // Here so we have accurate data when using to_human_readable_repr
438 _word_graph.number_of_active_nodes(_word_graph.number_of_nodes_active());
439 }
440
441 void run_impl() override;
442 void really_run_impl();
443
444 bool finished_impl() const noexcept override {
445 return _finished;
446 }
447
448 void standardize() {
449 word_graph::standardize(_word_graph);
450 _word_graph.induced_subgraph_no_checks(
451 0, _word_graph.number_of_nodes_active());
452 }
453 };
454
455 // Deduction guides
456 // The following is not a mistake but intentional, if no presentation type is
457 // explicitly used, then we use Presentation<word_type>.
458 // Presentation<std::string> is not allowed.
459 // TODO(2): allow for Presentation<std::string> by templating on Word (after
460 // we separate implementation and interface)
461
471
481
491
501 ->Stephen<Presentation<word_type>>;
502
513
524
535
546 // TODO(2): other shared_ptr guides?
547
548} // namespace libsemigroups
549
550namespace libsemigroups {
560 namespace stephen {
561
595 template <typename PresentationType>
597
622 template <typename PresentationType>
624
651 template <typename PresentationType>
653 s.run();
655 return paths.source(s.initial_state()).target(s.accept_state());
656 }
657
681 template <typename PresentationType>
683 s.run();
685 return paths.source(s.initial_state());
686 }
687
726 // Not noexcept because number_of_paths isn't
727 template <typename PresentationType>
729 size_t min = 0,
730 size_t max = POSITIVE_INFINITY) {
731 s.run();
732 using node_type = typename Stephen<PresentationType>::node_type;
733 return number_of_paths(
734 s.word_graph(), node_type(0), s.accept_state(), min, max);
735 }
736
763 // Not noexcept because number_of_paths isn't
764 template <typename PresentationType>
766 size_t min = 0,
767 size_t max = POSITIVE_INFINITY) {
768 s.run();
769 return number_of_paths(s.word_graph(), 0, min, max);
770 }
771
783 template <typename PresentationType>
785
798 // things?
799 template <typename PresentationType>
804
819 template <typename PresentationType>
824
825 } // namespace stephen
826
846 template <typename PresentationType>
848 Stephen<PresentationType> const& y) {
849 if (x.presentation() != y.presentation()) {
851 "x.presentation() must equal y.presentation() when comparing "
852 "Stephen instances")
853 }
854 return equal_to_no_checks(x, y);
855 }
856
878 template <typename PresentationType>
880 Stephen<PresentationType> const& y) {
881 return stephen::accepts(const_cast<Stephen<PresentationType>&>(x), y.word())
883 x.word());
884 }
885
894 template <typename PresentationType>
895 [[nodiscard]] std::string
897} // namespace libsemigroups
898
899#include "stephen.tpp"
900
901#endif // LIBSEMIGROUPS_STEPHEN_HPP_
T cbegin(T... args)
A representation of a graph in the DOT language of Graphviz.
Definition dot.hpp:115
For an implementation of inverse presentations for semigroups or monoids.
Definition presentation.hpp:2736
Range for iterating through paths in a WordGraph.
Definition paths.hpp:613
uint64_t number_of_paths(WordGraph< Node1 > const &wg, Node2 source)
For an implementation of presentations for semigroups or monoids.
Definition presentation.hpp:103
void run()
Run until finished.
Runner()
Default constructor.
For constructing the word graph of left factors of a word in an f.p. semigroup.
Definition stephen.hpp:90
Stephen & operator=(Stephen const &)=default
Default copy assignment operator.
Stephen(PresentationType const &p)
Construct from a presentation (copy).
Definition stephen.hpp:163
WordGraph< uint32_t > word_graph_type
The return type of the function word_graph.
Definition stephen.hpp:112
presentation_type const & presentation() const noexcept
Get the input presentation.
Definition stephen.hpp:256
Stephen & operator=(Stephen &&)=default
Default move assignment operator.
Stephen & init(std::shared_ptr< PresentationType > const &ptr)
Initialize from a shared pointer to presentation (copy).
node_type accept_state()
Get the accept state of the word graph.
Stephen & set_word(Iterator1 first, Iterator2 last)
Set the initial word.
Definition stephen.hpp:276
bool is_word_set() const noexcept
Check if the initial word is set.
Definition stephen.hpp:308
Stephen & init(PresentationType &&p)
Initialize from a presentation (move).
Definition stephen.hpp:231
PresentationType presentation_type
The underlying presentation type.
Definition stephen.hpp:109
Stephen(PresentationType &&p)
Construct from a presentation (move).
Definition stephen.hpp:175
Stephen(Stephen const &that)=default
Default copy constructor.
Stephen & init(PresentationType const &p)
Initialize from a presentation (copy).
Definition stephen.hpp:216
Stephen(std::shared_ptr< PresentationType > const &ptr)
Construct from a shared pointer to presentation (copy).
Definition stephen.hpp:187
word_type const & word() const
Get the initial word.
Definition stephen.hpp:321
void append_no_checks(Stephen< PresentationType > &that)
Append a Stephen instance (no checks).
Stephen & init()
Reinitialize an existing Stephen instance.
Stephen(Stephen &&)=default
Default move constructor.
static constexpr node_type initial_state() noexcept
Get the initial state of the word graph.
Definition stephen.hpp:367
Stephen()
Default constructor.
word_graph_type const & word_graph() const
Get the word graph.
Definition stephen.hpp:337
word_graph_type::node_type node_type
The node type of word_graph_type.
Definition stephen.hpp:114
Stephen & set_word_no_checks(Iterator1 first, Iterator2 last)
Set the initial word (no checks).
void operator*=(Stephen< PresentationType > &that)
Append a Stephen instance.
Class for representing word graphs.
Definition word-graph.hpp:83
uint32_t node_type
Definition word-graph.hpp:99
T cend(T... args)
std::string to_human_readable_repr(Action< Element, Point, Func, Traits, LeftOrRight > const &action)
Return a human readable representation of an Action object.
PositiveInfinity const POSITIVE_INFINITY
Value for positive infinity.
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:99
bool operator==(Presentation< Word > const &lhop, Presentation< Word > const &rhop)
Compare for equality.
Definition presentation.hpp:2894
Stephen(Presentation< word_type > const &) -> Stephen< Presentation< word_type > >
Deduction guide.
std::vector< letter_type > word_type
Type for a word over the generators of a semigroup.
Definition types.hpp:99
T make_shared(T... args)
T move(T... args)
Namespace containing helper functions for the Paths class.
Definition paths.hpp:56
Helper functions for the Stephen class.
Definition stephen.hpp:560
Dot dot(Stephen< PresentationType > &s)
Returns a Dot object representing the Stephen word graph.
auto words_accepted(Stephen< PresentationType > &s)
Returns a range object containing all words accepted by a Stephen instance in short-lex order.
Definition stephen.hpp:652
Stephen< PresentationType > & set_word(Stephen< PresentationType > &s, word_type const &w)
Set the initial word.
Definition stephen.hpp:800
bool is_left_factor(Stephen< PresentationType > &s, word_type const &w)
Check if a word is a left factor of Stephen::word.
auto left_factors(Stephen< PresentationType > &s)
Returns a range object containing all the words (in short-lex order) that are left factors of Stephen...
Definition stephen.hpp:682
uint64_t number_of_words_accepted(Stephen< PresentationType > &s, size_t min=0, size_t max=POSITIVE_INFINITY)
Returns the number of words accepted with length in a given range.
Definition stephen.hpp:728
bool accepts(Stephen< PresentationType > &s, word_type const &w)
Check if a word is accepted by a Stephen instance.
Stephen< PresentationType > & set_word_no_checks(Stephen< PresentationType > &s, word_type const &w)
Set the initial word (no checks).
Definition stephen.hpp:820
uint64_t number_of_left_factors(Stephen< PresentationType > &s, size_t min=0, size_t max=POSITIVE_INFINITY)
Returns the number of left factors with length in a given range.
Definition stephen.hpp:765
bool standardize(Graph &wg, Forest &f, Order val)
Standardizes a word graph in-place.
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
bool equal_to_no_checks(Stephen< PresentationType > const &x, Stephen< PresentationType > const &y)
Check equality of two Stephen instances (no checks).
Definition stephen.hpp:879