libsemigroups  v3.5.3
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
cong-class.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2019-2026 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 declaration of the Congruence class template, for
20// creating congruence over FroidurePin objects or over Presentation objects.
21
22#ifndef LIBSEMIGROUPS_CONG_CLASS_HPP_
23#define LIBSEMIGROUPS_CONG_CLASS_HPP_
24
25#include <cstddef> // for size_t
26#include <cstdint> // for uint64_t
27#include <memory> // for shared_ptr
28#include <string> // for string
29#include <string_view> // for string_view
30#include <utility> // for move
31#include <vector> // for vector
32
33#include "knuth-bendix-class.hpp" // for KnuthBendix
34#include "presentation.hpp" // for Presentation
35#include "todd-coxeter-class.hpp" // for ToddCoxeter
36#include "types.hpp" // for letter_type, wor...
37
38#include "detail/cong-common-class.hpp" // for detail::CongruenceCommon
39#include "detail/race.hpp" // for Race
40
41namespace libsemigroups {
42 class FroidurePinBase; // Forward declaration, constructor parameters
43
44 template <typename Node>
45 class WordGraph;
46
57
66
82
92
103
117
154 template <typename Word>
155 class Congruence : public detail::CongruenceCommon {
156 enum class RunnerKind : size_t { TC = 0, KB = 1, K = 2 };
157
159 // Congruence - data - private
161
162 mutable detail::Race _race;
163 mutable bool _runners_initted;
164 std::vector<RunnerKind> _runner_kinds;
165
166 public:
168 // Interface requirements - native-types
170
178 using native_word_type = Word;
179
181 // Congruence - constructors - public
183
191
204
211
218
225
232
233 ~Congruence();
234
247 // NOTE: No rvalue ref version because we anyway must copy p multiple times
249 : Congruence() {
250 init(knd, p);
251 }
252
267 // NOTE: No rvalue ref version because we anyway must copy p multiple times
269
271 // Congruence - interface requirements - add_generating_pair
273
291 template <typename Iterator1,
292 typename Iterator2,
293 typename Iterator3,
294 typename Iterator4>
296 Iterator2 last1,
297 Iterator3 first2,
298 Iterator4 last2) {
299 LIBSEMIGROUPS_ASSERT(!any_runner_started());
300 _runners_initted = false;
301 return detail::CongruenceCommon::add_internal_generating_pair_no_checks<
302 Congruence>(first1, last1, first2, last2);
303 }
304
319 template <typename Iterator1,
320 typename Iterator2,
321 typename Iterator3,
322 typename Iterator4>
324 Iterator2 last1,
325 Iterator3 first2,
326 Iterator4 last2) {
327 _runners_initted = false;
328 if (any_runner_started()) {
330 "any_runner_started() returned \"true\" so no further "
331 "generating pairs can be added at this stage");
332 }
333 return detail::CongruenceCommon::add_generating_pair<Congruence>(
334 first1, last1, first2, last2);
335 }
336
338 // Congruence - interface requirements - number_of_classes
340
355 [[nodiscard]] uint64_t number_of_classes();
356
358 // Congruence - interface requirements - contains
360
379 template <typename Iterator1,
380 typename Iterator2,
381 typename Iterator3,
382 typename Iterator4>
383 [[nodiscard]] tril currently_contains_no_checks(Iterator1 first1,
384 Iterator2 last1,
385 Iterator3 first2,
386 Iterator4 last2) const;
387
406 template <typename Iterator1,
407 typename Iterator2,
408 typename Iterator3,
409 typename Iterator4>
410 [[nodiscard]] tril currently_contains(Iterator1 first1,
411 Iterator2 last1,
412 Iterator3 first2,
413 Iterator4 last2) const {
414 return detail::CongruenceCommon::currently_contains<Congruence>(
415 first1, last1, first2, last2);
416 }
417
439 template <typename Iterator1,
440 typename Iterator2,
441 typename Iterator3,
442 typename Iterator4>
443 [[nodiscard]] bool contains_no_checks(Iterator1 first1,
444 Iterator2 last1,
445 Iterator3 first2,
446 Iterator4 last2) {
447 return detail::CongruenceCommon::contains_no_checks<Congruence>(
448 first1, last1, first2, last2);
449 }
450
468 template <typename Iterator1,
469 typename Iterator2,
470 typename Iterator3,
471 typename Iterator4>
472 [[nodiscard]] bool contains(Iterator1 first1,
473 Iterator2 last1,
474 Iterator3 first2,
475 Iterator4 last2) {
476 return detail::CongruenceCommon::contains<Congruence>(
477 first1, last1, first2, last2);
478 }
479
481 // Congruence - interface requirements - reduce
483
501 template <typename OutputIterator, typename Iterator1, typename Iterator2>
502 OutputIterator reduce_no_run_no_checks(OutputIterator d_first,
503 Iterator1 first,
504 Iterator2 last) const;
505
523 template <typename OutputIterator, typename Iterator1, typename Iterator2>
524 OutputIterator reduce_no_run(OutputIterator d_first,
525 Iterator1 first,
526 Iterator2 last) const {
527 return detail::CongruenceCommon::reduce_no_run<Congruence>(
528 d_first, first, last);
529 }
530
546 template <typename OutputIterator,
547 typename InputIterator1,
548 typename InputIterator2>
549 OutputIterator reduce_no_checks(OutputIterator d_first,
550 InputIterator1 first,
551 InputIterator2 last) {
552 return detail::CongruenceCommon::reduce_no_checks<Congruence>(
553 d_first, first, last);
554 }
555
571 template <typename OutputIterator,
572 typename InputIterator1,
573 typename InputIterator2>
574 OutputIterator reduce(OutputIterator d_first,
575 InputIterator1 first,
576 InputIterator2 last) {
577 return detail::CongruenceCommon::reduce<Congruence>(d_first, first, last);
578 }
579
581 // Congruence - interface requirements - throw_if_letter_not_in_alphabet
583
601 template <typename Iterator1, typename Iterator2>
602 void throw_if_letter_not_in_alphabet(Iterator1 first, Iterator2 last) const;
603
605 // Congruence - member functions - public
607
626 template <typename Thing>
628
647 template <typename Thing>
648 [[nodiscard]] bool has() const;
649
665 [[nodiscard]] size_t max_threads() const noexcept {
666 return _race.max_threads();
667 }
668
685 Congruence& max_threads(size_t val) noexcept {
686 _race.max_threads(val);
687 return *this;
688 }
689
701 [[nodiscard]] size_t number_of_runners() const noexcept {
702 return _race.number_of_runners();
703 }
704
721 // NOTE: for Congruence objects it's possible that "any_runner_started" is
722 // true but "started" is false ("started" is true if and only if "run_impl"
723 // has been called at least once, but, e.g. is_obviously_infinite might
724 // call Kambites::start but there's no call to Congruence::run_impl).
725 [[nodiscard]] bool any_runner_started() const noexcept {
726 return std::any_of(_race.begin(), _race.end(), [](auto const& r) {
727 return r->started();
728 });
729 }
730
743 [[nodiscard]] Presentation<Word> const& presentation() const;
744
756 [[nodiscard]] std::vector<Word> const& generating_pairs() const;
757
758#ifdef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
773 [[nodiscard]] congruence_kind kind() const noexcept;
774
790 [[nodiscard]] size_t number_of_generating_pairs() const noexcept;
791#endif
792
793 private:
795 // Congruence - member functions - private
797
798 void add_runner(std::shared_ptr<ToddCoxeter<Word>>&& ptr) {
799 _race.add_runner(std::move(ptr));
800 _runner_kinds.push_back(RunnerKind::TC);
801 }
802
803 void add_runner(std::shared_ptr<KnuthBendix<Word>>&& ptr) {
804 _race.add_runner(std::move(ptr));
805 _runner_kinds.push_back(RunnerKind::KB);
806 }
807
808 void add_runner(std::shared_ptr<Kambites<Word>>&& ptr) {
809 _race.add_runner(std::move(ptr));
810 _runner_kinds.push_back(RunnerKind::K);
811 }
812
813 template <typename Result, typename Node>
814 friend auto to(congruence_kind knd,
815 FroidurePinBase& fpb,
816 WordGraph<Node> const& wg)
817 -> std::enable_if_t<
818 std::is_same_v<Congruence<typename Result::native_word_type>,
819 Result>,
820 Result>;
821
822 template <typename Result, typename Node>
823 friend auto
824 to(congruence_kind knd, WordGraph<Node> const& wg) -> std::enable_if_t<
825 std::is_same_v<Congruence<typename Result::native_word_type>, Result>,
826 Result>;
827
828 void init_runners() const;
829
831 // Runner - pure virtual member functions - private
833
834 void run_impl() override;
835 bool finished_impl() const override {
836 return _race.finished();
837 }
838 }; // class Congruence
839
848 template <typename Word>
849 Congruence(congruence_kind, Presentation<Word> const&) -> Congruence<Word>;
850
859 // NOTE:there's no rvalue ref constructor, so it's possible this guide is
860 // superfluous
861 template <typename Word>
863
872 template <typename Word>
873 Congruence(Congruence<Word> const&) -> Congruence<Word>;
874
883 template <typename Word>
884 Congruence(Congruence<Word>&&) -> Congruence<Word>;
885
901 template <typename Word>
902 std::string to_human_readable_repr(Congruence<Word> const& c);
903} // namespace libsemigroups
904
905#include "cong-class.tpp"
906
907#endif // LIBSEMIGROUPS_CONG_CLASS_HPP_
T any_of(T... args)
Base class for FroidurePin containing non-element specific data and member functions.
Definition froidure-pin-base.hpp:67
For an implementation of presentations for semigroups or monoids.
Definition presentation.hpp:103
Class for representing word graphs.
Definition word-graph.hpp:83
std::string to_human_readable_repr(Action< Element, Point, Func, Traits, LeftOrRight > const &action)
Return a human readable representation of an Action object.
std::shared_ptr< Thing > get() const
Get a derived class of Runner being used to compute a Congruence instance.
bool has() const
Check if a derived class of Runner being used to compute a Congruence instance.
bool any_runner_started() const noexcept
Check if any runner has started.
Definition cong-class.hpp:725
Congruence(congruence_kind, Presentation< Word > const &) -> Congruence< Word >
Deduction guide.
Congruence(Congruence const &)
Copy constructor.
Congruence(Congruence &&)
Move constructor.
Congruence()
Default constructor.
Congruence & init()
Re-initialize a Congruence instance.
Congruence & operator=(Congruence &&)
Move assignment operator.
Congruence(congruence_kind knd, Presentation< Word > const &p)
Construct from congruence_kind and Presentation.
Definition cong-class.hpp:248
void throw_if_letter_not_in_alphabet(Iterator1 first, Iterator2 last) const
Throws if any letter in a range is out of bounds.
Congruence & operator=(Congruence const &)
Copy assignment operator.
Congruence & init(congruence_kind knd, Presentation< Word > const &p)
Re-initialize a Congruence instance.
OutputIterator reduce_no_checks(OutputIterator d_first, InputIterator1 first, InputIterator2 last)
Reduce a word with no checks.
Definition cong-class.hpp:549
uint64_t number_of_classes()
Compute the number of classes in the congruence.
bool contains_no_checks(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Check containment of a pair of words via iterators.
Definition cong-class.hpp:443
OutputIterator reduce_no_run_no_checks(OutputIterator d_first, Iterator1 first, Iterator2 last) const
Reduce a word with no computation or checks.
tril currently_contains(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2) const
Check containment of a pair of words via iterators.
Definition cong-class.hpp:410
Congruence & add_generating_pair(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Add generating pair via iterators.
Definition cong-class.hpp:323
OutputIterator reduce(OutputIterator d_first, InputIterator1 first, InputIterator2 last)
Reduce a word.
Definition cong-class.hpp:574
size_t number_of_generating_pairs() const noexcept
Returns the number of generating pairs.
tril currently_contains_no_checks(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2) const
Check containment of a pair of words via iterators.
Congruence & add_generating_pair_no_checks(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Add generating pair via iterators.
Definition cong-class.hpp:295
bool contains(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Check containment of a pair of words via iterators.
Definition cong-class.hpp:472
std::vector< Word > const & generating_pairs() const
Get the generating pairs of the congruence.
congruence_kind kind() const noexcept
The kind of the congruence (1- or 2-sided).
OutputIterator reduce_no_run(OutputIterator d_first, Iterator1 first, Iterator2 last) const
Reduce a word with no computation.
Definition cong-class.hpp:524
Presentation< Word > const & presentation() const
Get the presentation defining the parent semigroup of the congruence.
Word native_word_type
Type of the words in the relations of the presentation stored in a Congruence instance.
Definition cong-class.hpp:178
Congruence & max_threads(size_t val) noexcept
Set the maximum number of threads.
Definition cong-class.hpp:685
size_t max_threads() const noexcept
Get the current maximum number of threads.
Definition cong-class.hpp:665
size_t number_of_runners() const noexcept
Get the number of runners.
Definition cong-class.hpp:701
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:99
tril
Enum to indicate true, false or not currently knowable.
Definition types.hpp:54
congruence_kind
Enum to indicate the sided-ness of a congruence.
Definition types.hpp:67
T move(T... args)
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
T push_back(T... args)