libsemigroups  v3.5.5
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#include "word-graph-helpers.hpp" // for complete_no_checks
38
39#include "detail/cong-common-class.hpp" // for detail::CongruenceCommon
40#include "detail/race.hpp" // for Race
41
42namespace libsemigroups {
43 class FroidurePinBase; // Forward declaration, constructor parameters
44
45 template <typename Node>
46 class WordGraph;
47
58
67
83
93
104
118
155 template <typename Word>
156 class Congruence : public detail::CongruenceCommon {
157 enum class RunnerKind : size_t { TC = 0, KB = 1, K = 2 };
158
160 // Congruence - data - private
162
163 std::vector<Word> _generating_pairs;
164 Presentation<Word> _presentation;
165 mutable detail::Race _race;
166 mutable bool _runners_initted;
167 mutable std::vector<RunnerKind> _runner_kinds;
168
169 // Private init Congruence but not CongruenceCommon
170 Congruence& init_no_base_classes();
171
172 public:
174 // Interface requirements - native-types
176
184 using native_word_type = Word;
185
187 // Congruence - constructors - public
189
197
210
217
224
231
238
239 ~Congruence();
240
253 // NOTE: No rvalue ref version because we anyway must copy p multiple times
254 // TODO note no longer valid impl
256 : Congruence() {
257 init(knd, p);
258 }
259
274 // NOTE: No rvalue ref version because we anyway must copy p multiple times
275 // TODO note no longer valid impl
277
279 // Congruence - interface requirements - add_generating_pair
281
299 template <typename Iterator1,
300 typename Iterator2,
301 typename Iterator3,
302 typename Iterator4>
304 Iterator2 last1,
305 Iterator3 first2,
306 Iterator4 last2) {
307 LIBSEMIGROUPS_ASSERT(!any_runner_started());
308 _runners_initted = false;
309 _generating_pairs.emplace_back(first1, last1);
310 _generating_pairs.emplace_back(first2, last2);
311 return detail::CongruenceCommon::add_internal_generating_pair_no_checks<
312 Congruence>(first1, last1, first2, last2);
313 }
314
329 template <typename Iterator1,
330 typename Iterator2,
331 typename Iterator3,
332 typename Iterator4>
334 Iterator2 last1,
335 Iterator3 first2,
336 Iterator4 last2) {
337 _runners_initted = false;
338 if (any_runner_started()) {
340 "any_runner_started() returned \"true\" so no further "
341 "generating pairs can be added at this stage");
342 }
343 return detail::CongruenceCommon::add_generating_pair<Congruence>(
344 first1, last1, first2, last2);
345 }
346
348 // Congruence - interface requirements - number_of_classes
350
365 [[nodiscard]] uint64_t number_of_classes();
366
368 // Congruence - interface requirements - contains
370
389 template <typename Iterator1,
390 typename Iterator2,
391 typename Iterator3,
392 typename Iterator4>
393 [[nodiscard]] tril currently_contains_no_checks(Iterator1 first1,
394 Iterator2 last1,
395 Iterator3 first2,
396 Iterator4 last2) const;
397
416 template <typename Iterator1,
417 typename Iterator2,
418 typename Iterator3,
419 typename Iterator4>
420 [[nodiscard]] tril currently_contains(Iterator1 first1,
421 Iterator2 last1,
422 Iterator3 first2,
423 Iterator4 last2) const {
424 return detail::CongruenceCommon::currently_contains<Congruence>(
425 first1, last1, first2, last2);
426 }
427
449 template <typename Iterator1,
450 typename Iterator2,
451 typename Iterator3,
452 typename Iterator4>
453 [[nodiscard]] bool contains_no_checks(Iterator1 first1,
454 Iterator2 last1,
455 Iterator3 first2,
456 Iterator4 last2) {
457 return detail::CongruenceCommon::contains_no_checks<Congruence>(
458 first1, last1, first2, last2);
459 }
460
478 template <typename Iterator1,
479 typename Iterator2,
480 typename Iterator3,
481 typename Iterator4>
482 [[nodiscard]] bool contains(Iterator1 first1,
483 Iterator2 last1,
484 Iterator3 first2,
485 Iterator4 last2) {
486 return detail::CongruenceCommon::contains<Congruence>(
487 first1, last1, first2, last2);
488 }
489
491 // Congruence - interface requirements - reduce
493
511 template <typename OutputIterator, typename Iterator1, typename Iterator2>
512 OutputIterator reduce_no_run_no_checks(OutputIterator d_first,
513 Iterator1 first,
514 Iterator2 last) const;
515
533 template <typename OutputIterator, typename Iterator1, typename Iterator2>
534 OutputIterator reduce_no_run(OutputIterator d_first,
535 Iterator1 first,
536 Iterator2 last) const {
537 return detail::CongruenceCommon::reduce_no_run<Congruence>(
538 d_first, first, last);
539 }
540
556 template <typename OutputIterator,
557 typename InputIterator1,
558 typename InputIterator2>
559 OutputIterator reduce_no_checks(OutputIterator d_first,
560 InputIterator1 first,
561 InputIterator2 last) {
562 return detail::CongruenceCommon::reduce_no_checks<Congruence>(
563 d_first, first, last);
564 }
565
581 template <typename OutputIterator,
582 typename InputIterator1,
583 typename InputIterator2>
584 OutputIterator reduce(OutputIterator d_first,
585 InputIterator1 first,
586 InputIterator2 last) {
587 return detail::CongruenceCommon::reduce<Congruence>(d_first, first, last);
588 }
589
591 // Congruence - interface requirements - throw_if_letter_not_in_alphabet
593
611 template <typename Iterator1, typename Iterator2>
612 void throw_if_letter_not_in_alphabet(Iterator1 first, Iterator2 last) const;
613
615 // Congruence - member functions - public
617
636 template <typename Thing>
638
657 template <typename Thing>
658 [[nodiscard]] bool has() const;
659
675 [[nodiscard]] size_t max_threads() const noexcept {
676 return _race.max_threads();
677 }
678
695 Congruence& max_threads(size_t val) noexcept {
696 _race.max_threads(val);
697 return *this;
698 }
699
711 [[nodiscard]] size_t number_of_runners() const noexcept {
712 return _race.number_of_runners();
713 }
714
731 // NOTE: for Congruence objects it's possible that "any_runner_started" is
732 // true but "started" is false ("started" is true if and only if "run_impl"
733 // has been called at least once, but, e.g. is_obviously_infinite might
734 // call Kambites::start but there's no call to Congruence::run_impl).
735 [[nodiscard]] bool any_runner_started() const noexcept {
736 return std::any_of(_race.begin(), _race.end(), [](auto const& r) {
737 return r->started();
738 });
739 }
740
753 [[nodiscard]] Presentation<Word> const& presentation() const noexcept {
754 return _presentation;
755 }
756
768 [[nodiscard]] std::vector<Word> const& generating_pairs() const noexcept {
769 return _generating_pairs;
770 }
771
772#ifdef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
787 [[nodiscard]] congruence_kind kind() const noexcept;
788
804 [[nodiscard]] size_t number_of_generating_pairs() const noexcept;
805#endif
806
807 private:
809 // Congruence - member functions - private
811
812 void add_runner(std::shared_ptr<ToddCoxeter<Word>>&& ptr) const {
813 _race.add_runner(std::move(ptr));
814 _runner_kinds.push_back(RunnerKind::TC);
815 }
816
817 void add_runner(std::shared_ptr<KnuthBendix<Word>>&& ptr) const {
818 _race.add_runner(std::move(ptr));
819 _runner_kinds.push_back(RunnerKind::KB);
820 }
821
822 void add_runner(std::shared_ptr<Kambites<Word>>&& ptr) const {
823 _race.add_runner(std::move(ptr));
824 _runner_kinds.push_back(RunnerKind::K);
825 }
826
827 template <typename Result, typename Node>
828 friend auto to(congruence_kind knd,
829 FroidurePinBase& fpb,
830 WordGraph<Node> const& wg)
831 -> std::enable_if_t<
832 std::is_same_v<Congruence<typename Result::native_word_type>,
833 Result>,
834 Result>;
835
836 template <typename Result, typename Node>
837 friend auto
838 to(congruence_kind knd, WordGraph<Node> const& wg) -> std::enable_if_t<
839 std::is_same_v<Congruence<typename Result::native_word_type>, Result>,
840 Result>;
841
842 void init_runners() const;
843
845 // Runner - pure virtual member functions - private
847
848 void run_impl() override;
849 bool finished_impl() const override {
850 return _race.finished();
851 }
852 }; // class Congruence
853
862 template <typename Word>
863 Congruence(congruence_kind, Presentation<Word> const&) -> Congruence<Word>;
864
873 // NOTE:there's no rvalue ref constructor, so it's possible this guide is
874 // superfluous
875 template <typename Word>
877
886 template <typename Word>
887 Congruence(Congruence<Word> const&) -> Congruence<Word>;
888
897 template <typename Word>
898 Congruence(Congruence<Word>&&) -> Congruence<Word>;
899
915 template <typename Word>
916 std::string to_human_readable_repr(Congruence<Word> const& c);
917} // namespace libsemigroups
918
919#include "cong-class.tpp"
920
921#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:735
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:255
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:559
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:453
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:420
Congruence & add_generating_pair(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Add generating pair via iterators.
Definition cong-class.hpp:333
OutputIterator reduce(OutputIterator d_first, InputIterator1 first, InputIterator2 last)
Reduce a word.
Definition cong-class.hpp:584
size_t number_of_generating_pairs() const noexcept
Returns the number of generating pairs.
std::vector< Word > const & generating_pairs() const noexcept
Get the generating pairs of the congruence.
Definition cong-class.hpp:768
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:303
bool contains(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Check containment of a pair of words via iterators.
Definition cong-class.hpp:482
congruence_kind kind() const noexcept
The kind of the congruence (1- or 2-sided).
Presentation< Word > const & presentation() const noexcept
Get the presentation defining the parent semigroup of the congruence.
Definition cong-class.hpp:753
OutputIterator reduce_no_run(OutputIterator d_first, Iterator1 first, Iterator2 last) const
Reduce a word with no computation.
Definition cong-class.hpp:534
Word native_word_type
Type of the words in the relations of the presentation stored in a Congruence instance.
Definition cong-class.hpp:184
Congruence & max_threads(size_t val) noexcept
Set the maximum number of threads.
Definition cong-class.hpp:695
size_t max_threads() const noexcept
Get the current maximum number of threads.
Definition cong-class.hpp:675
size_t number_of_runners() const noexcept
Get the number of runners.
Definition cong-class.hpp:711
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:99
Presentation(Presentation< Word > const &) -> Presentation< Word >
Deduction guide.
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)