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"
48#include "to-presentation.hpp"
51#include "word-range.hpp"
53#include "detail/cong-common-class.hpp"
54#include "detail/fmt.hpp"
55#include "detail/multi-string-view.hpp"
56#include "detail/string.hpp"
57#include "detail/uf.hpp"
150 template <
typename Word = detail::MultiStringView>
151 class Kambites :
public detail::CongruenceCommon {
165 = std::conditional_t<std::is_same_v<Word, detail::MultiStringView>,
170 using internal_type = Word;
178 struct RelationWords;
193 mutable size_t _class;
194 mutable Complements _complements;
195 mutable bool _have_class;
203 using internal_type_iterator =
typename internal_type::const_iterator;
345 return _presentation;
363 return _generating_pairs;
382 template <
typename Iterator1,
402 template <
typename Iterator1,
410 return detail::CongruenceCommon::add_generating_pair<Kambites>(
411 first1, last1, first2, last2);
474 template <
typename Iterator1,
481 Iterator4 last2)
const;
507 template <
typename Iterator1,
514 Iterator4 last2)
const;
531 template <
typename Iterator1,
539 return detail::CongruenceCommon::contains_no_checks<Kambites>(
540 first1, last1, first2, last2);
559 template <
typename Iterator1,
563 [[nodiscard]]
bool contains(Iterator1 first1,
599 template <
typename OutputIterator,
typename Iterator1,
typename Iterator2>
602 Iterator2 last)
const;
626 template <
typename OutputIterator,
typename Iterator1,
typename Iterator2>
629 Iterator2 last)
const {
630 return detail::CongruenceCommon::reduce_no_run<Kambites>(
631 d_first, first, last);
655 template <
typename OutputIterator,
656 typename InputIterator1,
657 typename InputIterator2>
659 InputIterator1 first,
660 InputIterator2 last) {
661 return detail::CongruenceCommon::reduce_no_checks<Kambites>(
662 d_first, first, last);
686 template <
typename OutputIterator,
687 typename InputIterator1,
688 typename InputIterator2>
689 OutputIterator
reduce(OutputIterator d_first,
690 InputIterator1 first,
691 InputIterator2 last) {
692 return detail::CongruenceCommon::reduce<Kambites>(d_first, first, last);
760 [[nodiscard]] auto const&
ukkonen() noexcept {
787 template <
typename Iterator1,
typename Iterator2>
789 Iterator2 last)
const {
790 _presentation.throw_if_letter_not_in_alphabet(first, last);
828 [[nodiscard]]
bool success()
const override {
832#ifdef LIBSEMIGROUPS_PARSED_BY_DOXYGEN
872 void really_init_XYZ_data(
size_t i)
const;
878#if defined(__GNUC__) && !defined(__clang__)
879#pragma GCC diagnostic push
880#pragma GCC diagnostic ignored "-Winline"
882 inline void init_XYZ_data(
size_t i)
const {
883 LIBSEMIGROUPS_ASSERT(i < _presentation.rules.size());
884 if (_XYZ_data.empty()) {
885 _XYZ_data.resize(_presentation.rules.size());
887 if (!_XYZ_data[i].is_initialized) {
888 really_init_XYZ_data(i);
891#if defined(__GNUC__) && !defined(__clang__)
892#pragma GCC diagnostic pop
894 [[nodiscard]] internal_type
const& X(
size_t i)
const;
895 [[nodiscard]] internal_type
const& Y(
size_t i)
const;
896 [[nodiscard]] internal_type
const& Z(
size_t i)
const;
897 [[nodiscard]] internal_type
const& XY(
size_t i)
const;
898 [[nodiscard]] internal_type
const& YZ(
size_t i)
const;
899 [[nodiscard]] internal_type
const& XYZ(
size_t i)
const;
910 relation_prefix(internal_type_iterator
const& first,
911 internal_type_iterator
const& last)
const;
918 [[nodiscard]]
inline size_t
919 clean_overlap_prefix(internal_type
const& s)
const {
920 return clean_overlap_prefix(s.cbegin(), s.cend());
924 clean_overlap_prefix(internal_type_iterator
const& first,
925 internal_type_iterator
const& last)
const;
935 [[nodiscard]] std::pair<size_t, size_t>
936 clean_overlap_prefix_mod(internal_type
const& s,
size_t n)
const;
958 tuple<size_t, internal_type_iterator, internal_type_iterator>
959 p_active(internal_type
const& x,
960 internal_type_iterator
const& first,
961 internal_type_iterator
const& last)
const;
966 void replace_prefix(internal_type& w, internal_type
const& p)
const;
975 prefix_of_complement(
size_t i,
976 internal_type_iterator
const& first,
977 internal_type_iterator
const& last)
const;
980 [[nodiscard]]
size_t prefix_of_complement(
size_t i,
981 internal_type
const& w)
const {
982 return prefix_of_complement(i, w.cbegin(), w.cend());
987 [[nodiscard]]
size_t complementary_XY_prefix(
size_t i,
988 internal_type
const& w)
const;
994 [[nodiscard]]
size_t Z_active_complement(
size_t i,
995 internal_type
const& w)
const;
1000 Z_active_proper_complement(
size_t i, internal_type
const& w)
const;
1002 [[nodiscard]]
size_t
1003 Z_active_proper_complement(
size_t i,
1004 internal_type_iterator
const& first,
1005 internal_type_iterator
const& last)
const;
1011 [[nodiscard]]
static size_t complementary_relation_word(
size_t i) {
1012 return (i % 2 == 0 ? i + 1 : i - 1);
1015 template <
typename native_word_type>
1020 static void pop_front(detail::MultiStringView& x) {
1024 template <
typename Iterator>
1025 static void append(std::string& w, Iterator first, Iterator last) {
1029 template <
typename Iterator>
1030 static void append(detail::MultiStringView& w,
1033 w.append(first, last);
1036 template <
typename Iterator>
1037 static void append(
word_type& w, Iterator first, Iterator last) {
1038 w.insert(w.end(), first, last);
1060 [[nodiscard]]
bool wp_prefix(internal_type u,
1062 internal_type p)
const;
1066 void normal_form_inner(
size_t& r, internal_type& v, internal_type& w)
const;
1072 void run_impl()
override;
1074 bool finished_impl()
const override {
1087 template <
typename Word>
1098 template <
typename Word>
1109 template <
typename Word>
1120 template <
typename Word>
1138 template <
typename Word>
1143#include "kambites-class.tpp"
For an implementation of presentations for semigroups or monoids.
Definition presentation.hpp:102
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:81
std::string to_human_readable_repr(AhoCorasick const &ac)
Return a string representation.
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::MultiStringView >, std::string, Word > native_word_type
Definition kambites-class.hpp:164
std::vector< letter_type > word_type
Type for a word over the generators of a semigroup.
Definition types.hpp:101
tril
Enum to indicate true, false or not currently knowable.
Definition types.hpp:56
congruence_kind
Enum to indicate the sided-ness of a congruence.
Definition types.hpp:69
Namespace for everything in the libsemigroups library.
Definition action.hpp:44