libsemigroups  v3.0.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
todd-coxeter-helpers.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 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 the declarations of some helper functions for the
20// ToddCoxeter<Word> class.
21
22#ifndef LIBSEMIGROUPS_TODD_COXETER_HELPERS_HPP_
23#define LIBSEMIGROUPS_TODD_COXETER_HELPERS_HPP_
24
25#include <algorithm> // for reverse
26#include <chrono> // for milliseconds
27#include <cstring> // for strlen, size_t
28#include <initializer_list> // for begin, end, initi...
29#include <iterator> // for back_inserter
30#include <string> // for basic_string, string
31#include <type_traits> // for is_integral_v
32#include <utility> // for move
33#include <vector> // for vector
34
35#include "cong-common-helpers.hpp" // for partition, add_ge...
36#include "constants.hpp" // for UNDEFINED, operat...
37#include "exception.hpp" // for LIBSEMIGROUPS_EXC...
38#include "paths.hpp" // for Paths
39#include "presentation.hpp" // for Presentation::val...
40#include "ranges.hpp" // for seq, operator|
41#include "todd-coxeter-class.hpp" // for ToddCoxeter
42#include "types.hpp" // for word_type, congru...
43#include "word-graph.hpp" // for follow_path_no_ch...
44
45#include "detail/fmt.hpp" // for format
46#include "detail/path-iterators.hpp" // for const_pilo_iterat...
47
48namespace libsemigroups {
52 namespace todd_coxeter {
54 // ToddCoxeter<Word> helpers
56
57#ifndef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
58 // This is just for our convenience here, so not documented.
59 using index_type = typename detail::ToddCoxeterImpl::index_type;
60#endif
61
79
80 // TODO(1) this group is a bit hard to look at, it'd be better if all the
81 // overloads of a given function were on one page, with a single bit of
82 // documentation. This is because the overloads all do the same thing, and
83 // so there's no real benefit in repeating the doc over and over again.
84
86 // Possible future interface helpers - word -> index
88
106 template <typename Word>
107 [[nodiscard]] index_type
108 current_index_of_no_checks(ToddCoxeter<Word> const& tc, Word const& w) {
110 }
111
129 template <typename Word>
130 [[nodiscard]] index_type current_index_of(ToddCoxeter<Word> const& tc,
131 Word const& w) {
132 return tc.current_index_of(std::begin(w), std::end(w));
133 }
134
152 template <typename Word>
153 [[nodiscard]] index_type index_of_no_checks(ToddCoxeter<Word>& tc,
154 Word const& w) {
155 return tc.index_of_no_checks(std::begin(w), std::end(w));
156 }
157
175 template <typename Word>
176 [[nodiscard]] index_type index_of(ToddCoxeter<Word>& tc, Word const& w) {
177 return tc.index_of(std::begin(w), std::end(w));
178 }
179
197 template <typename Word, typename Int>
198 [[nodiscard]] index_type
199 current_index_of_no_checks(ToddCoxeter<Word>& tc,
201 static_assert(std::is_integral_v<Int>);
203 }
204
222 template <typename Word, typename Int>
223 [[nodiscard]] index_type
224 current_index_of(ToddCoxeter<Word>& tc,
226 static_assert(std::is_integral_v<Int>);
227 return tc.current_index_of(std::begin(w), std::end(w));
228 }
229
247 template <typename Word, typename Int>
248 [[nodiscard]] index_type
249 index_of_no_checks(ToddCoxeter<Word>& tc,
251 static_assert(std::is_integral_v<Int>);
252 return tc.index_of_no_checks(std::begin(w), std::end(w));
253 }
254
272 template <typename Word, typename Int>
273 [[nodiscard]] index_type index_of(ToddCoxeter<Word>& tc,
275 static_assert(std::is_integral_v<Int>);
276 return tc.index_of(std::begin(w), std::end(w));
277 }
278
294 template <typename Word>
295 [[nodiscard]] inline index_type
296 current_index_of_no_checks(ToddCoxeter<Word>& tc, char const* w) {
297 LIBSEMIGROUPS_ASSERT(w != nullptr);
298 return tc.current_index_of_no_checks(w, w + std::strlen(w));
299 }
300
316 template <typename Word>
317 [[nodiscard]] inline index_type current_index_of(ToddCoxeter<Word>& tc,
318 char const* w) {
319 detail::throw_if_nullptr(w, "2nd");
320 return tc.current_index_of(w, w + std::strlen(w));
321 }
322
338 template <typename Word>
339 [[nodiscard]] inline index_type index_of_no_checks(ToddCoxeter<Word>& tc,
340 char const* w) {
341 LIBSEMIGROUPS_ASSERT(w != nullptr);
342 return tc.index_of_no_checks(w, w + std::strlen(w));
343 }
344
360 template <typename Word>
361 [[nodiscard]] inline index_type index_of(ToddCoxeter<Word>& tc,
362 char const* w) {
363 detail::throw_if_nullptr(w, "2nd");
364 return tc.index_of(w, w + std::strlen(w));
365 }
366
368 // Possible future interface helpers - index -> word
370
384 template <typename Word>
385 [[nodiscard]] Word current_word_of_no_checks(ToddCoxeter<Word>& tc,
386 index_type i);
387
401 template <typename Word>
402 [[nodiscard]] Word current_word_of(ToddCoxeter<Word>& tc, index_type i);
403
417 template <typename Word>
418 [[nodiscard]] Word word_of_no_checks(ToddCoxeter<Word>& tc, index_type i);
419
433 template <typename Word>
434 [[nodiscard]] Word word_of(ToddCoxeter<Word>& tc, index_type i);
435
437 // Possible future interface helpers - class_of
439
461 // Can't out of line this because of auto return type
462 template <typename Word>
463 [[nodiscard]] auto class_by_index(ToddCoxeter<Word>& tc, index_type n) {
464 size_t const offset = (tc.presentation().contains_empty_word() ? 0 : 1);
465 tc.run();
466 // We call run and then current_word_graph, because the word
467 // graph does not need to be standardized for this to work.
468 // TODO(1) again there are alots of copies here
469 // TODO(1) this also has the disadvantage that we can't set the various
470 // settings in the Paths object, in particular, the size_hint + count
471 // functions!
472 return Paths(tc.current_word_graph()).source(0).target(n + offset)
473 | rx::transform([&tc](auto const& w) {
474 Word ww;
475 for (auto index : w) {
476 ww.push_back(tc.presentation().letter_no_checks(index));
477 }
478 return ww;
479 });
480 }
481
503 // Can't out of line this because of auto return type
504 template <typename Word>
505 [[nodiscard]] auto class_by_index_no_checks(ToddCoxeter<Word>& tc,
506 index_type n) {
507 size_t const offset = (tc.presentation().contains_empty_word() ? 0 : 1);
508 tc.run();
509 // We call run and then current_word_graph, because the word
510 // graph does not need to be standardized for this to work.
511 // TODO(1) again there are alots of copies here
512 // TODO(1) this also has the disadvantage that we can't set the various
513 // settings in the Paths object, in particular, the size_hint + count
514 // functions!
515 return Paths(tc.current_word_graph())
516 .source_no_checks(0)
517 .target_no_checks(n + offset)
518 | rx::transform([&tc](auto const& w) {
519 Word ww;
520 for (auto index : w) {
521 ww.push_back(tc.presentation().letter_no_checks(index));
522 }
523 return ww;
524 });
525 }
526
551 template <typename Word, typename Iterator1, typename Iterator2>
552 [[nodiscard]] auto class_of(ToddCoxeter<Word>& tc,
553 Iterator1 first,
554 Iterator2 last) {
555 return class_by_index(tc, tc.index_of(first, last));
556 }
557
582 template <typename Word, typename Iterator1, typename Iterator2>
583 [[nodiscard]] auto class_of_no_checks(ToddCoxeter<Word>& tc,
584 Iterator1 first,
585 Iterator2 last) {
586 return class_by_index_no_checks(tc, tc.index_of_no_checks(first, last));
587 }
588
612 template <typename Word>
613 [[nodiscard]] auto class_of(ToddCoxeter<Word>& tc, Word const& w) {
614 return class_of(tc, std::begin(w), std::end(w));
615 }
616
640 template <typename Word>
641 [[nodiscard]] auto class_of_no_checks(ToddCoxeter<Word>& tc,
642 Word const& w) {
643 return class_of_no_checks(tc, std::begin(w), std::end(w));
644 }
645
669 template <typename Word, typename Int>
670 [[nodiscard]] auto class_of(ToddCoxeter<Word>& tc,
672 static_assert(std::is_integral_v<Int>);
673 return class_of(tc, std::begin(w), std::end(w));
674 }
675
699 template <typename Word, typename Int>
700 [[nodiscard]] auto class_of_no_checks(ToddCoxeter<Word>& tc,
702 static_assert(std::is_integral_v<Int>);
703 return class_of_no_checks(tc, std::begin(w), std::end(w));
704 }
705
727 template <typename Word>
728 [[nodiscard]] inline auto class_of_no_checks(ToddCoxeter<Word>& tc,
729 char const* w) {
730 LIBSEMIGROUPS_ASSERT(w != nullptr);
731 return class_of_no_checks(tc, w, w + std::strlen(w));
732 }
733
755 template <typename Word>
756 [[nodiscard]] auto class_of(ToddCoxeter<Word>& tc, char const* w) {
757 detail::throw_if_nullptr(w, "2nd");
758 LIBSEMIGROUPS_ASSERT(w != nullptr);
759
760#if defined(__GNUC__) && !defined(__clang__)
761#pragma GCC diagnostic push
762#pragma GCC diagnostic ignored "-Wnonnull"
763#endif
764 return class_of(tc, w, w + std::strlen(w));
765#if defined(__GNUC__) && !defined(__clang__)
766#pragma GCC diagnostic pop
767#endif
768 }
769
771 // Possible future interface helpers - is_non_trivial
773
805 [[nodiscard]] tril is_non_trivial(detail::ToddCoxeterImpl& tc,
806 size_t tries = 10,
809 float threshold = 0.99);
810
812 // Possible future interface helpers - redundant_rule
814
847 template <typename Word, typename Time>
848 [[nodiscard]] typename std::vector<Word>::const_iterator
850
852
853 } // namespace todd_coxeter
854
855 // This namespace contains implementations of the interface helpers (i.e.
856 // specific versions for ToddCoxeterImpl of the helper functions from
857 // cong-common.hpp).
858 namespace congruence_common {
860 // Interface helpers - normal_forms
862
885 template <typename Word>
886 [[nodiscard]] auto normal_forms(ToddCoxeter<Word>& tc);
887
889 // Interface helpers - partition
891
916 // The following function is also declared in cong-common-helpers.hpp:
917 template <typename Word, typename Range, typename>
918 [[nodiscard]] std::vector<std::vector<Word>>
919 partition(ToddCoxeter<Word>& tc, Range r);
920
922 // Interface helpers - non_trivial_classes
924
947 template <typename Word>
948 [[nodiscard]] std::vector<std::vector<Word>>
949 non_trivial_classes(ToddCoxeter<Word>& tc1, ToddCoxeter<Word>& tc2);
950 } // namespace congruence_common
951
952 // The todd_coxeter namespace contains all helpers specific to
953 // ToddCoxeter<Word> and aliases for the common functionality in the
954 // congruence_common namespace.
955 namespace todd_coxeter {
957 // ToddCoxeter<Word> add_generating_pairs helpers
959
962
964 // Interface helpers - contains
966
971
973 // Interface helpers - reduce[_no_run][_no_checks]
975
980
982 // Interface helpers - partitioning and normal forms
984
986 using congruence_common::normal_forms;
988
989 } // namespace todd_coxeter
990} // namespace libsemigroups
991
992#include "todd-coxeter-helpers.tpp"
993#endif // LIBSEMIGROUPS_TODD_COXETER_HELPERS_HPP_
T begin(T... args)
Paths(WordGraph< Node > const &) -> Paths< Node >
For an implementation of presentations for semigroups or monoids.
Definition presentation.hpp:102
void run()
Run until finished.
T end(T... args)
void add_generating_pair(Thing &thing, typename Thing::native_word_type const &u, typename Thing::native_word_type const &v)
Helper for adding a generating pair of words.
Definition cong-common-helpers.hpp:200
void add_generating_pair_no_checks(Thing &thing, typename Thing::native_word_type const &u, typename Thing::native_word_type const &v)
Helper for adding a generating pair of words.
Definition cong-common-helpers.hpp:112
bool contains_no_checks(Thing &thing, typename Thing::native_word_type const &u, typename Thing::native_word_type const &v)
Check containment of a pair of words.
Definition cong-common-helpers.hpp:513
bool contains(Thing &thing, typename Thing::native_word_type const &u, typename Thing::native_word_type const &v)
Check containment of a pair of words.
Definition cong-common-helpers.hpp:605
tril currently_contains(Thing const &thing, typename Thing::native_word_type const &u, typename Thing::native_word_type const &v)
Check containment of a pair of words.
Definition cong-common-helpers.hpp:425
tril currently_contains_no_checks(Thing const &thing, typename Thing::native_word_type const &u, typename Thing::native_word_type const &v)
Check containment of a pair of words.
Definition cong-common-helpers.hpp:322
std::vector< std::vector< typename Thing::native_word_type > > non_trivial_classes(Thing &thing, Range r)
Find the non-trivial classes in the partition of a range of words.
std::vector< std::vector< typename Thing::native_word_type > > partition(Thing &thing, Range r)
Partition a range of words.
Thing::native_word_type reduce(Thing const &thing, typename Thing::native_word_type const &w)
Reduce a word.
Thing::native_word_type reduce_no_run_no_checks(Thing const &thing, typename Thing::native_word_type const &w)
Reduce a word with no enumeration or checks.
Thing::native_word_type reduce_no_checks(Thing const &thing, typename Thing::native_word_type const &w)
Reduce a word with no checks.
Thing::native_word_type reduce_no_run(Thing const &thing, typename Thing::native_word_type const &w)
Reduce a word with no enumeration.
word_graph_type const & current_word_graph() const noexcept
Get the current word graph.
Definition todd-coxeter-impl.hpp:1213
Presentation< Word > const & presentation() const noexcept
Get the presentation used to define a ToddCoxeter instance (if any).
Definition todd-coxeter-class.hpp:649
index_type current_index_of(Iterator1 first, Iterator2 last) const
Returns the current index of the class containing a word.
Definition todd-coxeter-class.hpp:1055
index_type current_index_of_no_checks(Iterator1 first, Iterator2 last) const
Returns the current index of the class containing a word.
Definition todd-coxeter-class.hpp:1025
index_type index_of_no_checks(Iterator1 first, Iterator2 last)
Returns the index of the class containing a word.
Definition todd-coxeter-class.hpp:1085
index_type index_of(Iterator1 first, Iterator2 last)
Returns the index of the class containing a word.
Definition todd-coxeter-class.hpp:1115
auto class_of(ToddCoxeter< Word > &tc, Iterator1 first, Iterator2 last)
Returns a range object containing every word in the congruence class of a word given by iterators.
Definition todd-coxeter-helpers.hpp:552
auto class_by_index_no_checks(ToddCoxeter< Word > &tc, index_type n)
Returns a range object containing every word in the congruence class with given index.
Definition todd-coxeter-helpers.hpp:505
auto class_by_index(ToddCoxeter< Word > &tc, index_type n)
Returns a range object containing every word in the congruence class with given index.
Definition todd-coxeter-helpers.hpp:463
Word current_word_of(ToddCoxeter< Word > &tc, index_type i)
Returns a word representing a class with given index.
tril is_non_trivial(detail::ToddCoxeterImpl &tc, size_t tries=10, std::chrono::milliseconds try_for=std::chrono::milliseconds(100), float threshold=0.99)
Check if the congruence has more than one class.
Word current_word_of_no_checks(ToddCoxeter< Word > &tc, index_type i)
Returns a word representing a class with given index.
Word word_of(ToddCoxeter< Word > &tc, index_type i)
Returns a word representing a class with given index.
auto class_of_no_checks(ToddCoxeter< Word > &tc, Iterator1 first, Iterator2 last)
Returns a range object containing every word in the congruence class of a word given by iterators.
Definition todd-coxeter-helpers.hpp:583
index_type index_of_no_checks(ToddCoxeter< Word > &tc, Word const &w)
Returns the index of the class containing a word.
Definition todd-coxeter-helpers.hpp:153
index_type current_index_of(ToddCoxeter< Word > const &tc, Word const &w)
Returns the current index of the class containing a word.
Definition todd-coxeter-helpers.hpp:130
index_type current_index_of_no_checks(ToddCoxeter< Word > const &tc, Word const &w)
Returns the current index of the class containing a word.
Definition todd-coxeter-helpers.hpp:108
index_type index_of(ToddCoxeter< Word > &tc, Word const &w)
Returns the index of the class containing a word.
Definition todd-coxeter-helpers.hpp:176
Word word_of_no_checks(ToddCoxeter< Word > &tc, index_type i)
Returns a word representing a class with given index.
std::vector< Word >::const_iterator redundant_rule(Presentation< Word > const &p, Time t)
Return an iterator pointing at the left hand side of a redundant rule.
tril
Enum to indicate true, false or not currently knowable.
Definition types.hpp:56
Definition todd-coxeter-helpers.hpp:52
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
T strlen(T... args)