28#ifndef LIBSEMIGROUPS_KAMBITES_CLASS_HPP_
29#define LIBSEMIGROUPS_KAMBITES_CLASS_HPP_
35#include <initializer_list>
39#include <unordered_map>
43#include "constants.hpp"
45#include "exception.hpp"
47#include "presentation.hpp"
50#include "word-range.hpp"
52#include "detail/cong-common-class.hpp"
53#include "detail/fmt.hpp"
54#include "detail/multi-view.hpp"
55#include "detail/string.hpp"
56#include "detail/uf.hpp"
149 template <
typename Word = detail::MultiView<std::
string>>
150 class Kambites :
public detail::CongruenceCommon {
164 std::is_same_v<Word, detail::MultiView<std::string>>,
169 using internal_type = Word;
177 struct RelationWords;
192 mutable size_t _class;
193 mutable Complements _complements;
194 mutable bool _have_class;
202 using internal_type_iterator =
typename internal_type::const_iterator;
344 return _presentation;
362 return _generating_pairs;
381 template <
typename Iterator1,
401 template <
typename Iterator1,
409 return detail::CongruenceCommon::add_generating_pair<Kambites>(
410 first1, last1, first2, last2);
473 template <
typename Iterator1,
480 Iterator4 last2)
const;
506 template <
typename Iterator1,
513 Iterator4 last2)
const;
530 template <
typename Iterator1,
538 return detail::CongruenceCommon::contains_no_checks<Kambites>(
539 first1, last1, first2, last2);
558 template <
typename Iterator1,
598 template <
typename OutputIterator,
typename Iterator1,
typename Iterator2>
601 Iterator2 last)
const;
625 template <
typename OutputIterator,
typename Iterator1,
typename Iterator2>
628 Iterator2 last)
const {
629 return detail::CongruenceCommon::reduce_no_run<Kambites>(
630 d_first, first, last);
654 template <
typename OutputIterator,
655 typename InputIterator1,
656 typename InputIterator2>
658 InputIterator1 first,
659 InputIterator2 last) {
660 return detail::CongruenceCommon::reduce_no_checks<Kambites>(
661 d_first, first, last);
685 template <
typename OutputIterator,
686 typename InputIterator1,
687 typename InputIterator2>
688 OutputIterator
reduce(OutputIterator d_first,
689 InputIterator1 first,
690 InputIterator2 last) {
691 return detail::CongruenceCommon::reduce<Kambites>(d_first, first, last);
759 [[nodiscard]] auto const&
ukkonen() noexcept {
786 template <
typename Iterator1,
typename Iterator2>
788 Iterator2 last)
const {
789 _presentation.throw_if_letter_not_in_alphabet(first, last);
831#ifdef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
871 void really_init_XYZ_data(
size_t i)
const;
877#if defined(__GNUC__) && !defined(__clang__)
878#pragma GCC diagnostic push
879#pragma GCC diagnostic ignored "-Winline"
881 inline void init_XYZ_data(
size_t i)
const {
882 LIBSEMIGROUPS_ASSERT(i < _presentation.rules.size());
883 if (_XYZ_data.empty()) {
884 _XYZ_data.resize(_presentation.rules.size());
886 if (!_XYZ_data[i].is_initialized) {
887 really_init_XYZ_data(i);
890#if defined(__GNUC__) && !defined(__clang__)
891#pragma GCC diagnostic pop
893 [[nodiscard]] internal_type
const& X(
size_t i)
const;
894 [[nodiscard]] internal_type
const& Y(
size_t i)
const;
895 [[nodiscard]] internal_type
const& Z(
size_t i)
const;
896 [[nodiscard]] internal_type
const& XY(
size_t i)
const;
897 [[nodiscard]] internal_type
const& YZ(
size_t i)
const;
898 [[nodiscard]] internal_type
const& XYZ(
size_t i)
const;
909 relation_prefix(internal_type_iterator
const& first,
910 internal_type_iterator
const& last)
const;
917 [[nodiscard]]
inline size_t
918 clean_overlap_prefix(internal_type
const& s)
const {
919 return clean_overlap_prefix(s.cbegin(), s.cend());
923 clean_overlap_prefix(internal_type_iterator
const& first,
924 internal_type_iterator
const& last)
const;
934 [[nodiscard]] std::pair<size_t, size_t>
935 clean_overlap_prefix_mod(internal_type
const& s,
size_t n)
const;
957 tuple<size_t, internal_type_iterator, internal_type_iterator>
958 p_active(internal_type
const& x,
959 internal_type_iterator
const& first,
960 internal_type_iterator
const& last)
const;
965 void replace_prefix(internal_type& w, internal_type
const& p)
const;
974 prefix_of_complement(
size_t i,
975 internal_type_iterator
const& first,
976 internal_type_iterator
const& last)
const;
979 [[nodiscard]]
size_t prefix_of_complement(
size_t i,
980 internal_type
const& w)
const {
981 return prefix_of_complement(i, w.cbegin(), w.cend());
986 [[nodiscard]]
size_t complementary_XY_prefix(
size_t i,
987 internal_type
const& w)
const;
993 [[nodiscard]]
size_t Z_active_complement(
size_t i,
994 internal_type
const& w)
const;
999 Z_active_proper_complement(
size_t i, internal_type
const& w)
const;
1001 [[nodiscard]]
size_t
1002 Z_active_proper_complement(
size_t i,
1003 internal_type_iterator
const& first,
1004 internal_type_iterator
const& last)
const;
1010 [[nodiscard]]
static size_t complementary_relation_word(
size_t i) {
1011 return (i % 2 == 0 ? i + 1 : i - 1);
1014 template <
typename native_word_type>
1019 static void pop_front(detail::MultiView<std::string>& x) {
1023 template <
typename Iterator>
1024 static void append(std::string& w, Iterator first, Iterator last) {
1028 template <
typename Iterator>
1029 static void append(detail::MultiView<std::string>& w,
1032 w.append(first, last);
1035 template <
typename Iterator>
1036 static void append(
word_type& w, Iterator first, Iterator last) {
1037 w.insert(w.end(), first, last);
1059 [[nodiscard]]
bool wp_prefix(internal_type u,
1061 internal_type p)
const;
1065 void normal_form_inner(
size_t& r, internal_type& v, internal_type& w)
const;
1071 void run_impl()
override;
1073 bool finished_impl()
const override {
1086 template <
typename Word>
1097 template <
typename Word>
1108 template <
typename Word>
1119 template <
typename Word>
1137 template <
typename Word>
1142#include "kambites-class.tpp"
For an implementation of presentations for semigroups or monoids.
Definition presentation.hpp:103
void run()
Run until finished.
bool finished() const
Check if run has been run to completion or not.
For an implementation of Ukkonen's algorithm.
Definition ukkonen.hpp:90
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.
size_t small_overlap_class()
Get the small overlap class.
auto const & ukkonen() noexcept
Definition kambites-class.hpp:759
Kambites(congruence_kind, Presentation< Word > const &) -> Kambites< Word >
Deduction guide.
Kambites & init()
Re-initialize a Kambites instance.
Kambites()
Default constructor.
Kambites & operator=(Kambites const &)
Default copy assignment operator.
void throw_if_letter_not_in_alphabet(Iterator1 first, Iterator2 last) const
Throws if any letter in a range is out of bounds.
Definition kambites-class.hpp:787
void throw_if_not_C4()
Throws if small_overlap_class isn't at least .
bool success() const override
Check if the small overlap class has been computed and is at least 4.
Definition kambites-class.hpp:827
OutputIterator reduce_no_checks(OutputIterator d_first, InputIterator1 first, InputIterator2 last)
Reduce a word with no checks.
Definition kambites-class.hpp:657
uint64_t number_of_classes()
Compute the number of classes in the congruence.
Definition kambites-class.hpp:435
bool contains_no_checks(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Check containment of a pair of words via iterators.
Definition kambites-class.hpp:534
Kambites & add_generating_pair_no_checks(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Add generating pair via iterators.
OutputIterator reduce_no_run_no_checks(OutputIterator d_first, Iterator1 first, Iterator2 last) const
Reduce a word with no computation of the small_overlap_class or checks.
tril currently_contains(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2) const
Check containment of a pair of words via iterators.
OutputIterator reduce(OutputIterator d_first, InputIterator1 first, InputIterator2 last)
Reduce a word.
Definition kambites-class.hpp:688
size_t number_of_generating_pairs() const noexcept
std::vector< native_word_type > const & generating_pairs() const noexcept
Get the generating pairs of the congruence.
Definition kambites-class.hpp:361
tril currently_contains_no_checks(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2) const
Check containment of a pair of words via iterators.
Presentation< native_word_type > const & presentation() const noexcept
Get the presentation used to define a Kambites instance (if any).
Definition kambites-class.hpp:343
bool contains(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Check containment of a pair of words via iterators.
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 of the small_overlap_class.
Definition kambites-class.hpp:626
Kambites & add_generating_pair(Iterator1 first1, Iterator2 last1, Iterator3 first2, Iterator4 last2)
Add generating pair via iterators.
Definition kambites-class.hpp:405
std::conditional_t< std::is_same_v< Word, detail::MultiView< std::string > >, std::string, Word > native_word_type
Definition kambites-class.hpp:163
std::vector< letter_type > word_type
Type for a word over the generators of a semigroup.
Definition types.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
Namespace for everything in the libsemigroups library.
Definition action.hpp:44