libsemigroups  v3.3.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-helpers.hpp" // for word_graph
40#include "word-graph.hpp" // for WordGraph
41
42#include "detail/felsch-graph.hpp" // for DoNotReg...
43#include "detail/node-managed-graph.hpp" // for NodeMana...
44#include "detail/node-manager.hpp" // for NodeManager
45#include "detail/report.hpp" // for report_n...
46#include "detail/string.hpp" // for group_di...
47#include "detail/word-graph-with-sources.hpp" // for WordGrap...
48
49// TODO(2)
50// * update so that run_for, run_until work properly (at present basically
51// run_impl starts again from scratch every time)
52// * minimal rep (as per Reinis) (named normal_form?)
53// * invert() - just swap the initial and accept states and re-standardize
54// * idempotent() - just make the accept state = initial state.
55// * class_of for inverse Stephen (i.e. all walks in the graph through all
56// nodes) (not sure how to do this just yet). This is different than
57// words_accepted see Corollary 3.2 in Stephen's "Presentations of inverse
58// monoids" paper (not thesis).
59// * canonical_form (as per Howie's book)
60
65
66namespace libsemigroups {
67
90 template <typename PresentationType>
91 class Stephen : public Runner {
92 template <typename Q>
93 static constexpr bool is_valid_presentation() {
94 return std::is_same_v<Q, Presentation<word_type>>
95 || std::is_same_v<Q, InversePresentation<word_type>>;
96 // TODO(2): uncomment when we figure out how to handle std::string
97 // presentations
98 //|| std::is_same_v<Q, Presentation<std::string>>
99 //|| std::is_same_v<Q, InversePresentation<std::string>>;
100 }
101
102 // TODO (2): Change the error message once std::string presentations are
103 // supported
104 static_assert(is_valid_presentation<PresentationType>(),
105 "the template parameter PresentationType must be "
106 "Presentation<word_type> or InversePresentation<word_type>");
107
108 public:
110 using presentation_type = PresentationType;
111
116
117 private:
118 class StephenGraph; // forward decl
119
120 // Data members
121 node_type _accept_state;
122 bool _finished;
123 bool _is_word_set;
125 word_type _word;
126 StephenGraph _word_graph;
127
128 public:
137
148
149 // TODO(2): Implement make<Stephen> function which checks args
150 // Should presentation::throw_if_not_normalized (until we separate the
151 // implementation and external interface later on).
152 // Should also throw if `p.throw_if_bad_alphabet_or_rules()` throws.
153 // Should also throw if if `p.alphabet().size()` is `0`.
154
163 // Not noexcept because allocated memory
164 explicit Stephen(PresentationType const& p) : Stephen() {
165 init(p);
166 }
167
176 explicit Stephen(PresentationType&& p) : Stephen() {
177 init(std::move(p));
178 }
179
189 init(ptr);
190 }
191
193 Stephen(Stephen const& that) = default;
194
196 Stephen(Stephen&&) = default;
197
199 Stephen& operator=(Stephen const&) = default;
200
202 Stephen& operator=(Stephen&&) = default;
203
204 ~Stephen();
205
217 Stephen& init(PresentationType const& p) {
219 }
220
232 Stephen& init(PresentationType&& p) {
234 }
235
248
257 presentation_type const& presentation() const noexcept {
258 return *_presentation;
259 }
260
276 template <typename Iterator1, typename Iterator2>
277 Stephen& set_word(Iterator1 first, Iterator2 last) {
278 presentation().throw_if_letter_not_in_alphabet(first, last);
279 return set_word_no_checks(first, last);
280 }
281
297 template <typename Iterator1, typename Iterator2>
298 Stephen& set_word_no_checks(Iterator1 first, Iterator2 last);
299
309 bool is_word_set() const noexcept {
310 return _is_word_set;
311 }
312
322 word_type const& word() const {
323 throw_if_not_ready();
324 return _word;
325 }
326
339 throw_if_not_ready();
340 return _word_graph;
341 }
342
356 // Throws if run throws, also this is not in the helper namespace because
357 // we cache the return value.
359
368 static constexpr node_type initial_state() noexcept {
369 return 0;
370 }
371
392
413
414 private:
416 // Reporting
418
419 void report_after_run() const;
420 void report_before_run() const;
421 void report_progress_from_thread() const;
422
423 Stephen& init_after_presentation_set();
424
425 void throw_if_presentation_empty(presentation_type const& p) const {
426 if (p.alphabet().empty()) {
427 LIBSEMIGROUPS_EXCEPTION("the presentation must not have 0 generators");
428 }
429 }
430
431 void throw_if_not_ready() const;
432
433 void init_word_graph_from_word_no_checks() {
434 _word_graph.init(presentation());
435 _word_graph.report_prefix("Stephen");
436 _word_graph.complete_path(
437 presentation(), 0, _word.cbegin(), _word.cend());
438 // Here so we have accurate data when using to_human_readable_repr
439 _word_graph.number_of_active_nodes(_word_graph.number_of_nodes_active());
440 }
441
442 void run_impl() override;
443 void really_run_impl();
444
445 bool finished_impl() const noexcept override {
446 return _finished;
447 }
448
449 void standardize() {
450 v4::word_graph::standardize(_word_graph);
451 _word_graph.induced_subgraph_no_checks(
452 0, _word_graph.number_of_nodes_active());
453 }
454 };
455
456 // Deduction guides
457 // The following is not a mistake but intentional, if no presentation type is
458 // explicitly used, then we use Presentation<word_type>.
459 // Presentation<std::string> is not allowed.
460 // TODO(2): allow for Presentation<std::string> by templating on Word (after
461 // we separate implementation and interface)
462
472
482
492
502 ->Stephen<Presentation<word_type>>;
503
514
525
536
547 // TODO(2): other shared_ptr guides?
548
549} // namespace libsemigroups
550
551namespace libsemigroups {
561 namespace stephen {
562
596 template <typename PresentationType>
598
623 template <typename PresentationType>
625
652 template <typename PresentationType>
654 s.run();
656 return paths.source(s.initial_state()).target(s.accept_state());
657 }
658
682 template <typename PresentationType>
684 s.run();
686 return paths.source(s.initial_state());
687 }
688
727 // Not noexcept because number_of_paths isn't
728 template <typename PresentationType>
730 size_t min = 0,
731 size_t max = POSITIVE_INFINITY) {
732 s.run();
733 using node_type = typename Stephen<PresentationType>::node_type;
734 return v4::paths::count(
735 s.word_graph(), node_type(0), s.accept_state(), min, max);
736 }
737
764 // Not noexcept because number_of_paths isn't
765 template <typename PresentationType>
767 size_t min = 0,
768 size_t max = POSITIVE_INFINITY) {
769 s.run();
770 return v4::paths::count(s.word_graph(), 0, min, max);
771 }
772
784 template <typename PresentationType>
786
799 // things?
800 template <typename PresentationType>
805
820 template <typename PresentationType>
825
826 } // namespace stephen
827
847 template <typename PresentationType>
849 Stephen<PresentationType> const& y) {
850 if (x.presentation() != y.presentation()) {
852 "x.presentation() must equal y.presentation() when comparing "
853 "Stephen instances")
854 }
855 return equal_to_no_checks(x, y);
856 }
857
879 template <typename PresentationType>
881 Stephen<PresentationType> const& y) {
882 return stephen::accepts(const_cast<Stephen<PresentationType>&>(x), y.word())
884 x.word());
885 }
886
895 template <typename PresentationType>
896 [[nodiscard]] std::string
898} // namespace libsemigroups
899
900#include "stephen.tpp"
901
902#endif // LIBSEMIGROUPS_STEPHEN_HPP_
T cbegin(T... args)
A representation of a graph in the DOT language of Graphviz.
Definition dot.hpp:116
For an implementation of inverse presentations for semigroups or monoids.
Definition presentation.hpp:2735
Range for iterating through paths in a WordGraph.
Definition paths.hpp:657
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:91
Stephen & operator=(Stephen const &)=default
Default copy assignment operator.
Stephen(PresentationType const &p)
Construct from a presentation (copy).
Definition stephen.hpp:164
WordGraph< uint32_t > word_graph_type
The return type of the function word_graph.
Definition stephen.hpp:113
presentation_type const & presentation() const noexcept
Get the input presentation.
Definition stephen.hpp:257
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:277
bool is_word_set() const noexcept
Check if the initial word is set.
Definition stephen.hpp:309
Stephen & init(PresentationType &&p)
Initialize from a presentation (move).
Definition stephen.hpp:232
PresentationType presentation_type
The underlying presentation type.
Definition stephen.hpp:110
Stephen(PresentationType &&p)
Construct from a presentation (move).
Definition stephen.hpp:176
Stephen(Stephen const &that)=default
Default copy constructor.
Stephen & init(PresentationType const &p)
Initialize from a presentation (copy).
Definition stephen.hpp:217
Stephen(std::shared_ptr< PresentationType > const &ptr)
Construct from a shared pointer to presentation (copy).
Definition stephen.hpp:188
word_type const & word() const
Get the initial word.
Definition stephen.hpp:322
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:368
Stephen()
Default constructor.
word_graph_type const & word_graph() const
Get the word graph.
Definition stephen.hpp:338
word_graph_type::node_type node_type
The node type of word_graph_type.
Definition stephen.hpp:115
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:2893
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:61
Helper functions for the Stephen class.
Definition stephen.hpp:561
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:653
Stephen< PresentationType > & set_word(Stephen< PresentationType > &s, word_type const &w)
Set the initial word.
Definition stephen.hpp:801
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:683
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:729
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:821
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:766
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:880