//
// libsemigroups - C++ library for semigroups and monoids
// Copyright (C) 2022 James D. Mitchell
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/ >.
//
#define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
#include <cstddef>
// for size_t
#include "catch.hpp" // for REQUIRE, REQUIRE_THROWS_AS, REQUI...
#include "test-main.hpp" // for LIBSEMIGROUPS_TEST_CASE
#include "libsemigroups/bipart.hpp" // for Bipartition
#include "libsemigroups/containers.hpp" // for StaticVector1
#include "libsemigroups/froidure-pin.hpp" // for FroidurePin
#include "libsemigroups/int-range.hpp" // for IntegralRange
#include "libsemigroups/knuth-bendix.hpp" // for redundant_rule
#include "libsemigroups/make-present.hpp" // for make
#include "libsemigroups/present.hpp" // for Presentation
#include "libsemigroups/siso.hpp" // for Sislo
#include "libsemigroups/types.hpp" // for word_type
namespace libsemigroups {
struct LibsemigroupsException;
// forward decl
namespace {
template <
typename W>
void check_constructors(Presentation<W>& p) {
p.validate();
Presentation<W> pp(p);
pp.validate();
REQUIRE(pp.alphabet() == p.alphabet());
REQUIRE(pp.rules == p.rules);
Presentation<W> q(std::move(p));
q.validate();
REQUIRE(q.alphabet() == pp.alphabet());
REQUIRE(q.rules == pp.rules);
p = q;
p.validate();
REQUIRE(q.alphabet() == p.alphabet());
REQUIRE(q.rules == p.rules);
p = std::move(q);
p.validate();
REQUIRE(pp.alphabet() == p.alphabet());
REQUIRE(pp.rules == p.rules);
}
template <
typename W>
void check_alphabet_letters() {
Presentation<W> p;
p.alphabet({
0 ,
1 ,
2 });
REQUIRE(p.alphabet() == W({
0 ,
1 ,
2 }));
REQUIRE(p.letter(
0 ) ==
0 );
REQUIRE(p.letter(
1 ) ==
1 );
REQUIRE(p.letter(
2 ) ==
2 );
p.alphabet(
4 );
REQUIRE(p.alphabet() == W({
0 ,
1 ,
2 ,
3 }));
p.validate();
REQUIRE_THROWS_AS(p.alphabet({
0 ,
1 ,
1 }), LibsemigroupsException);
presentation::add_rule(p, {
0 ,
1 ,
2 ,
1 }, {
0 ,
0 });
presentation::add_rule(p, {
4 ,
1 }, {
0 ,
5 });
presentation::add_rule(p, {
4 ,
1 }, {
0 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 });
p.alphabet_from_rules();
REQUIRE(p.alphabet() == W({
0 ,
1 ,
2 ,
4 ,
5 }));
REQUIRE(p.index(
0 ) ==
0 );
REQUIRE(p.index(
1 ) ==
1 );
REQUIRE(p.index(
2 ) ==
2 );
REQUIRE(p.index(
4 ) ==
3 );
REQUIRE(p.index(
5 ) ==
4 );
REQUIRE(!p.contains_empty_word());
presentation::add_rule(p, {
4 ,
1 }, {});
p.alphabet_from_rules();
REQUIRE(p.contains_empty_word());
p.alphabet({
0 ,
1 ,
2 ,
3 });
REQUIRE(p.alphabet() == W({
0 ,
1 ,
2 ,
3 }));
}
template <
typename W>
void check_contains_empty_word() {
Presentation<W> p;
REQUIRE(!p.contains_empty_word());
p.contains_empty_word(
true );
REQUIRE(p.contains_empty_word());
p.contains_empty_word(
false );
REQUIRE(!p.contains_empty_word());
}
template <
typename W>
void check_validate_rules_throws() {
Presentation<W> p;
p.rules.emplace_back();
REQUIRE_THROWS_AS(p.validate_rules(), LibsemigroupsException);
}
template <
typename W>
void check_add_rules() {
Presentation<W> p;
presentation::add_rule(p, {
0 ,
1 ,
2 ,
1 }, {
0 ,
0 });
Presentation<W> q;
presentation::add_rule(q, {
4 ,
1 }, {
0 ,
5 });
presentation::add_rule(q, {
4 ,
1 }, {
0 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 });
presentation::add_rules(p, q);
REQUIRE(p.rules
== std::vector<W>({{
0 ,
1 ,
2 ,
1 },
{
0 ,
0 },
{
4 ,
1 },
{
0 ,
5 },
{
4 ,
1 },
{
0 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 }}));
REQUIRE(q.rules
== std::vector<W>(
{{
4 ,
1 }, {
0 ,
5 }, {
4 ,
1 }, {
0 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 ,
1 }}));
REQUIRE_THROWS_AS(p.validate(), LibsemigroupsException);
REQUIRE_THROWS_AS(q.validate(), LibsemigroupsException);
}
template <
typename W>
void check_add_identity_rules() {
Presentation<W> p;
presentation::add_rule(p, {
0 ,
1 ,
2 ,
1 }, {
0 ,
0 });
REQUIRE_THROWS_AS(presentation::add_identity_rules(p,
0 ),
LibsemigroupsException);
p.alphabet_from_rules();
presentation::add_identity_rules(p,
0 );
REQUIRE(p.rules
== std::vector<W>({{
0 ,
1 ,
2 ,
1 },
{
0 ,
0 },
{
0 ,
0 },
{
0 },
{
1 ,
0 },
{
1 },
{
0 ,
1 },
{
1 },
{
2 ,
0 },
{
2 },
{
0 ,
2 },
{
2 }}));
}
template <
typename W>
void check_add_zero_rules() {
Presentation<W> p;
presentation::add_rule(p, {
0 ,
1 ,
2 ,
1 }, {
0 ,
0 });
REQUIRE_THROWS_AS(presentation::add_zero_rules(p,
0 ),
LibsemigroupsException);
p.alphabet_from_rules();
presentation::add_zero_rules(p,
0 );
REQUIRE(p.rules
== std::vector<W>({{
0 ,
1 ,
2 ,
1 },
{
0 ,
0 },
{
0 ,
0 },
{
0 },
{
1 ,
0 },
{
0 },
{
0 ,
1 },
{
0 },
{
2 ,
0 },
{
0 },
{
0 ,
2 },
{
0 }}));
}
template <
typename W>
void check_add_inverse_rules() {
Presentation<W> p;
presentation::add_rule(p, {
0 ,
1 ,
2 ,
1 }, {
0 ,
0 });
p.alphabet_from_rules();
REQUIRE_THROWS_AS(presentation::add_inverse_rules(p, {
0 ,
1 ,
1 },
0 ),
LibsemigroupsException);
REQUIRE_THROWS_AS(presentation::add_inverse_rules(p, {
1 ,
2 ,
0 },
0 ),
LibsemigroupsException);
p.alphabet({
0 ,
1 ,
2 ,
3 });
REQUIRE_THROWS_AS(presentation::add_inverse_rules(p, {
0 ,
2 ,
3 ,
1 },
0 ),
LibsemigroupsException);
REQUIRE_THROWS_AS(presentation::add_inverse_rules(p, {
0 ,
2 ,
1 },
0 ),
LibsemigroupsException);
p.alphabet({
0 ,
1 ,
2 });
presentation::add_inverse_rules(p, {
0 ,
2 ,
1 },
0 );
REQUIRE(
p.rules
== std::vector<W>({{
0 ,
1 ,
2 ,
1 }, {
0 ,
0 }, {
1 ,
2 }, {
0 }, {
2 ,
1 }, {
0 }}));
// When id is UNDEFINED
presentation::add_inverse_rules(p, {
0 ,
2 ,
1 });
REQUIRE(p.rules
== std::vector<W>({{
0 ,
1 ,
2 ,
1 },
{
0 ,
0 },
{
1 ,
2 },
{
0 },
{
2 ,
1 },
{
0 },
{
0 ,
0 },
{},
{
1 ,
2 },
{},
{
2 ,
1 },
{}}));
}
template <
typename W>
void check_remove_duplicate_rules() {
Presentation<W> p;
p.rules.push_back(W({
0 ,
1 ,
2 ,
1 }));
REQUIRE_THROWS_AS(presentation::remove_duplicate_rules(p),
LibsemigroupsException);
p.rules.push_back(W({
0 ,
0 }));
presentation::add_rule(p, {
0 ,
0 }, {
0 ,
1 ,
2 ,
1 });
p.alphabet_from_rules();
REQUIRE(p.rules.size() ==
4 );
presentation::remove_duplicate_rules(p);
REQUIRE(p.rules.size() ==
2 );
}
template <
typename W>
void check_reduce_complements() {
Presentation<W> p;
p.rules.push_back(W({
0 ,
1 ,
2 ,
1 }));
REQUIRE_THROWS_AS(presentation::reduce_complements(p),
LibsemigroupsException);
p.rules.push_back(W({
1 ,
2 ,
1 }));
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
1 ,
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 ,
1 }, {
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
p.alphabet_from_rules();
presentation::reduce_complements(p);
presentation::sort_each_rule(p);
presentation::sort_rules(p);
REQUIRE(p.rules
== std::vector<W>({{
1 ,
1 },
{
0 },
{
1 ,
2 ,
1 },
{
0 },
{
0 ,
1 ,
2 ,
1 },
{
0 },
{
1 ,
1 ,
2 ,
1 },
{
0 }}));
}
template <
typename W>
void check_sort_each_rule() {
Presentation<W> p;
p.rules.push_back(W({
0 ,
1 ,
2 ,
1 }));
REQUIRE_THROWS_AS(presentation::sort_each_rule(p),
LibsemigroupsException);
p.rules.push_back(W({
1 ,
2 ,
1 }));
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
1 ,
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 ,
1 }, {
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
p.alphabet_from_rules();
presentation::sort_each_rule(p);
REQUIRE(p.rules
== std::vector<W>({{
0 ,
1 ,
2 ,
1 },
{
1 ,
2 ,
1 },
{
1 ,
1 ,
2 ,
1 },
{
1 ,
2 ,
1 },
{
1 ,
1 ,
2 ,
1 },
{
1 ,
1 },
{
1 ,
2 ,
1 },
{
1 ,
1 },
{
1 ,
2 ,
1 },
{
0 }}));
}
template <
typename W>
void check_sort_rules() {
Presentation<W> p;
p.rules.push_back(W({
0 ,
1 ,
2 ,
1 }));
REQUIRE_THROWS_AS(presentation::sort_rules(p), LibsemigroupsException);
p.rules.push_back(W({
1 ,
2 ,
1 }));
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
1 ,
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 ,
1 }, {
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
p.alphabet_from_rules();
presentation::sort_rules(p);
REQUIRE(p.rules
== std::vector<W>({{
1 ,
2 ,
1 },
{
0 },
{
1 ,
1 },
{
1 ,
2 ,
1 },
{
1 ,
1 ,
2 ,
1 },
{
1 ,
1 },
{
0 ,
1 ,
2 ,
1 },
{
1 ,
2 ,
1 },
{
1 ,
2 ,
1 },
{
1 ,
1 ,
2 ,
1 }}));
REQUIRE(presentation::are_rules_sorted(p));
}
template <
typename W>
void check_longest_common_subword() {
{
// Normalized alphabet
Presentation<W> p;
p.rules.push_back(W({
0 ,
1 ,
2 ,
1 }));
REQUIRE_NOTHROW(presentation::longest_common_subword(p));
p.rules.push_back(W({
1 ,
2 ,
1 }));
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
1 ,
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 ,
1 }, {
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
p.alphabet_from_rules();
REQUIRE(presentation::longest_common_subword(p) == W({
1 ,
2 ,
1 }));
presentation::replace_subword(p, W({
1 ,
2 ,
1 }), W({
3 }));
presentation::add_rule(p, {
3 }, {
1 ,
2 ,
1 });
REQUIRE(p.rules
== std::vector<W>({{
0 ,
3 },
{
3 },
{
3 },
{
1 ,
3 },
{
1 ,
3 },
{
1 ,
1 },
{
1 ,
1 },
{
3 },
{
3 },
{
0 },
{
3 },
{
1 ,
2 ,
1 }}));
}
{
// Non-normalized alphabet
Presentation<W> p;
presentation::add_rule(p, {
1 ,
2 ,
4 ,
2 }, {
2 ,
4 ,
2 });
presentation::add_rule(p, {
2 ,
4 ,
2 }, {
2 ,
2 ,
4 ,
2 });
presentation::add_rule(p, {
2 ,
2 ,
4 ,
2 }, {
2 ,
2 });
presentation::add_rule(p, {
2 ,
2 }, {
2 ,
4 ,
2 });
presentation::add_rule(p, {
2 ,
4 ,
2 }, {
1 });
p.alphabet_from_rules();
REQUIRE(presentation::longest_common_subword(p) == W({
2 ,
4 ,
2 }));
presentation::replace_subword(p, W({
2 ,
4 ,
2 }), W({
0 }));
presentation::add_rule(p, W({
0 }), W({
2 ,
4 ,
2 }));
REQUIRE(p.rules
== std::vector<W>({{
1 ,
0 },
{
0 },
{
0 },
{
2 ,
0 },
{
2 ,
0 },
{
2 ,
2 },
{
2 ,
2 },
{
0 },
{
0 },
{
1 },
{
0 },
{
2 ,
4 ,
2 }}));
}
}
template <
typename W>
void check_redundant_rule() {
FroidurePin<Bipartition> S;
S.add_generator(Bipartition({{
1 , -
1 }, {
2 , -
2 }, {
3 , -
3 }, {
4 , -
4 }}));
S.add_generator(Bipartition({{
1 , -
2 }, {
2 , -
3 }, {
3 , -
4 }, {
4 , -
1 }}));
S.add_generator(Bipartition({{
1 , -
2 }, {
2 , -
1 }, {
3 , -
3 }, {
4 , -
4 }}));
S.add_generator(Bipartition({{
1 ,
2 }, {
3 , -
3 }, {
4 , -
4 }, {-
1 , -
2 }}));
REQUIRE(S.size() ==
105 );
auto p = make<Presentation<W>>(S);
REQUIRE(presentation::length(p) ==
359 );
presentation::remove_duplicate_rules(p);
REQUIRE(presentation::length(p) ==
359 );
presentation::reduce_complements(p);
REQUIRE(presentation::length(p) ==
359 );
presentation::sort_each_rule(p);
presentation::sort_rules(p);
REQUIRE(presentation::length(p) ==
359 );
REQUIRE(p.rules.size() ==
86 );
p.alphabet_from_rules();
auto it = presentation::redundant_rule(p, std::chrono::milliseconds(
100 ));
REQUIRE(*it == W({
2 ,
1 ,
3 ,
1 ,
1 ,
2 ,
1 ,
2 }));
REQUIRE(*(it +
1 ) == W({
1 ,
1 ,
2 ,
1 ,
3 ,
1 ,
2 ,
1 }));
p.rules.erase(it, it +
2 );
p.validate();
// while (it != p.rules.cend()) { // Too time consuming and indeterminant
// REQUIRE(std::distance(it, p.rules.cend()) % 2 == 0);
// p.rules.erase(it, it + 2);
// p.validate();
// it = presentation::redundant_rule(p, std::chrono::milliseconds(8));
// }
REQUIRE(presentation::length(p) ==
343 );
REQUIRE(p.rules.size() ==
84 );
}
template <
typename W>
void check_shortlex_compare_concat() {
REQUIRE(detail::shortlex_compare_concat(
W({
0 ,
1 ,
2 ,
1 }), W({
0 }), W({
1 ,
1 ,
2 ,
1 }), W({
0 })));
}
template <
typename W>
void check_remove_trivial_rules() {
Presentation<W> p;
p.rules.push_back(W({
0 ,
1 ,
2 ,
1 }));
REQUIRE_THROWS_AS(presentation::remove_trivial_rules(p),
LibsemigroupsException);
p.rules.push_back(W({
1 ,
2 ,
1 }));
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
presentation::add_rule(p, {
0 }, {
0 });
presentation::add_rule(p, {
1 }, {
1 });
presentation::add_rule(p, {
2 }, {
2 });
presentation::remove_trivial_rules(p);
REQUIRE(
p.rules
== std::vector<W>(
{{
0 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 }, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 }, {
1 ,
2 ,
1 }, {
0 }}));
presentation::remove_trivial_rules(p);
REQUIRE(
p.rules
== std::vector<W>(
{{
0 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 }, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 }, {
1 ,
2 ,
1 }, {
0 }}));
}
template <
typename W>
void check_replace_subword() {
Presentation<W> p;
p.rules.push_back(W({
0 ,
1 ,
2 ,
1 }));
REQUIRE_NOTHROW(presentation::replace_subword(p, W({
0 }), W({
1 })));
p.rules.push_back(W({
1 ,
2 ,
1 }));
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
presentation::replace_subword(p, W({
0 }), W({
1 }));
REQUIRE(
p.rules
== std::vector<W>(
{{
1 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 }, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 }, {
1 ,
2 ,
1 }, {
1 }}));
presentation::replace_subword(p, W({
0 }), W({
1 }));
REQUIRE(
p.rules
== std::vector<W>(
{{
1 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 }, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 }, {
1 ,
2 ,
1 }, {
1 }}));
presentation::replace_subword(p, W({
1 ,
2 ,
1 }), W({
0 }));
REQUIRE(p.rules
== std::vector<W>({{
1 ,
0 }, {
0 }, {
1 ,
0 }, {
1 ,
1 }, {
0 }, {
1 }}));
presentation::replace_subword(p, W({
42 ,
42 }), W({
0 }));
REQUIRE(p.rules
== std::vector<W>({{
1 ,
0 }, {
0 }, {
1 ,
0 }, {
1 ,
1 }, {
0 }, {
1 }}));
p.rules.clear();
presentation::add_rule(
p, {
1 ,
2 ,
1 ,
2 ,
1 ,
1 ,
2 ,
1 ,
2 ,
1 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 ,
1 ,
2 ,
1 ,
2 ,
1 });
presentation::replace_subword(p, W({
1 ,
2 ,
1 }), W({
1 }));
REQUIRE(p.rules == std::vector<W>({{
1 ,
2 ,
1 ,
1 ,
2 ,
1 ,
1 }, {
1 ,
1 ,
2 ,
1 }}));
presentation::replace_subword(p, W({
1 ,
2 ,
1 }), W({
1 }));
REQUIRE(p.rules == std::vector<W>({{
1 ,
1 ,
1 }, {
1 ,
1 }}));
// Test for when existing is a suffix of replacement
p.rules.clear();
presentation::add_rule(
p, {
1 ,
2 ,
1 ,
2 ,
1 ,
1 ,
2 ,
1 ,
2 ,
1 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 ,
1 ,
2 ,
1 ,
2 ,
1 });
presentation::replace_subword(p, W({
1 ,
2 }), W({
1 ,
1 ,
2 }));
REQUIRE(p.rules
== std::vector<W>(
{{
1 ,
1 ,
2 ,
1 ,
1 ,
2 ,
1 ,
1 ,
1 ,
2 ,
1 ,
1 ,
2 ,
1 ,
1 ,
1 ,
2 ,
1 },
{
1 ,
1 ,
2 ,
1 ,
1 ,
1 ,
2 ,
1 ,
1 ,
2 ,
1 }}));
}
template <
typename W>
void check_replace_word() {
Presentation<W> p;
presentation::add_rule(p, {
0 ,
1 ,
0 }, {});
p.alphabet_from_rules();
presentation::replace_word(p, W({}), W({
2 }));
REQUIRE(p.rules == std::vector<W>{{
0 ,
1 ,
0 }, {
2 }});
p.rules.clear();
presentation::add_rule(p, {
0 ,
1 ,
0 }, {
2 ,
1 });
presentation::add_rule(p, {
1 ,
1 ,
2 }, {
1 ,
2 ,
1 });
presentation::add_rule(p, {
2 ,
1 ,
2 ,
1 }, {
2 ,
2 });
presentation::add_rule(p, {
2 ,
1 }, {
0 ,
1 ,
1 });
p.alphabet_from_rules();
presentation::replace_word(p, W({
2 ,
1 }), W({
1 ,
2 }));
REQUIRE(p.rules
== std::vector<W>{{
0 ,
1 ,
0 },
{
1 ,
2 },
{
1 ,
1 ,
2 },
{
1 ,
2 ,
1 },
{
2 ,
1 ,
2 ,
1 },
{
2 ,
2 },
{
1 ,
2 },
{
0 ,
1 ,
1 }});
p.rules.clear();
presentation::add_rule(p, {
0 ,
1 ,
0 }, {
1 ,
0 ,
1 });
presentation::add_rule(p, {
0 ,
1 ,
1 }, {
1 ,
0 ,
1 ,
0 });
p.alphabet_from_rules();
presentation::replace_word(p, W({
1 ,
0 ,
1 }), W({}));
REQUIRE(p.rules
== std::vector<W>{{
0 ,
1 ,
0 }, {}, {
0 ,
1 ,
1 }, {
1 ,
0 ,
1 ,
0 }});
}
template <
typename W>
void check_longest_rule() {
Presentation<W> p;
p.rules.push_back(W({
0 ,
1 ,
2 ,
1 }));
REQUIRE_THROWS_AS(presentation::longest_rule(p), LibsemigroupsException);
p.rules.push_back(W({
1 ,
2 ,
1 }));
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
REQUIRE(*presentation::longest_rule(p) == W({
0 ,
1 ,
2 ,
1 }));
REQUIRE_THROWS_AS(*presentation::longest_rule(
presentation::longest_rule(p) +
1 , p.rules.cend()),
LibsemigroupsException);
REQUIRE(*presentation::longest_rule(presentation::longest_rule(p) +
2 ,
p.rules.cend())
== W({
1 ,
1 ,
2 ,
1 }));
REQUIRE(*presentation::shortest_rule(p) == W({
1 ,
2 ,
1 }));
REQUIRE(*presentation::shortest_rule(p.rules.cbegin(),
presentation::shortest_rule(p))
== W({
1 ,
1 ,
2 ,
1 }));
REQUIRE_THROWS_AS(
*presentation::shortest_rule(p.rules.cbegin(),
presentation::shortest_rule(p) -
1 ),
LibsemigroupsException);
}
template <
typename W>
void check_longest_rule_length() {
Presentation<W> p;
p.rules.push_back(W({
0 ,
1 ,
2 ,
1 }));
REQUIRE_THROWS_AS(presentation::longest_rule_length(p),
LibsemigroupsException);
p.rules.push_back(W({
1 ,
2 ,
1 }));
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
REQUIRE(presentation::longest_rule_length(p) ==
7 );
REQUIRE_THROWS_AS(presentation::longest_rule_length(
presentation::longest_rule(p) +
1 , p.rules.cend()),
LibsemigroupsException);
REQUIRE(presentation::longest_rule_length(
presentation::longest_rule(p) +
2 , p.rules.cend())
==
6 );
REQUIRE(presentation::shortest_rule_length(p) ==
4 );
REQUIRE_THROWS_AS(presentation::shortest_rule_length(
presentation::shortest_rule(p) +
1 , p.rules.cend()),
LibsemigroupsException);
REQUIRE(presentation::shortest_rule_length(p.rules.cbegin(),
p.rules.cend() -
2 )
==
6 );
}
template <
typename W>
void check_remove_redundant_generators() {
Presentation<W> p;
p.rules.push_back(W({
0 ,
1 ,
2 ,
1 }));
REQUIRE_THROWS_AS(presentation::remove_redundant_generators(p),
LibsemigroupsException);
p.rules.push_back(W({
1 ,
2 ,
1 }));
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
presentation::remove_redundant_generators(p);
REQUIRE(p.rules
== std::vector<W>(
{{
1 ,
2 ,
1 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 }, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 }}));
presentation::remove_redundant_generators(p);
REQUIRE(p.rules
== std::vector<W>(
{{
1 ,
2 ,
1 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 }, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 }}));
p.rules.clear();
presentation::add_rule(p, {
0 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 }, {
0 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
presentation::remove_redundant_generators(p);
REQUIRE(
p.rules
== std::vector<W>(
{{
0 ,
0 ,
2 ,
0 }, {
0 ,
2 ,
0 }, {
0 ,
0 ,
2 ,
0 }, {
0 ,
0 }, {
0 ,
2 ,
0 }, {
0 }}));
p.rules.clear();
presentation::add_rule(p, {
0 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
0 }, {
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
presentation::remove_redundant_generators(p);
REQUIRE(
p.rules
== std::vector<W>(
{{
0 ,
0 ,
2 ,
0 }, {
0 ,
2 ,
0 }, {
0 ,
0 ,
2 ,
0 }, {
0 ,
0 }, {
0 ,
2 ,
0 }, {
0 }}));
p.rules.clear();
presentation::add_rule(p, {
0 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 }, {
0 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
presentation::remove_redundant_generators(p);
REQUIRE(
p.rules
== std::vector<W>(
{{
0 ,
0 ,
2 ,
0 }, {
0 ,
2 ,
0 }, {
0 ,
0 ,
2 ,
0 }, {
0 ,
0 }, {
0 ,
2 ,
0 }, {
0 }}));
}
template <
typename W>
void check_reverse() {
Presentation<W> p;
presentation::add_rule(p, {
0 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
presentation::reverse(p);
REQUIRE(
p.rules
== std::vector<W>(
{{
1 ,
2 ,
1 ,
0 }, {
1 ,
2 ,
1 }, {
1 ,
2 ,
1 ,
1 }, {
1 ,
1 }, {
1 ,
2 ,
1 }, {
0 }}));
presentation::reverse(p);
REQUIRE(
p.rules
== std::vector<W>(
{{
0 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 }, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 }, {
1 ,
2 ,
1 }, {
0 }}));
}
template <
typename W>
void check_in_alphabet() {
Presentation<W> p;
presentation::add_rule(p, {
0 ,
1 ,
2 ,
1 }, {
1 ,
2 ,
1 });
presentation::add_rule(p, {
1 ,
1 ,
2 ,
1 }, {
1 ,
1 });
presentation::add_rule(p, {
1 ,
2 ,
1 }, {
0 });
// Alphabet not set, so everything false
REQUIRE(!p.in_alphabet(
0 ));
REQUIRE(!p.in_alphabet(
1 ));
REQUIRE(!p.in_alphabet(
2 ));
REQUIRE(!p.in_alphabet(
3 ));
REQUIRE(!p.in_alphabet(
42 ));
p.alphabet_from_rules();
REQUIRE(p.in_alphabet(
0 ));
REQUIRE(p.in_alphabet(
1 ));
REQUIRE(p.in_alphabet(
2 ));
REQUIRE(!p.in_alphabet(
3 ));
REQUIRE(!p.in_alphabet(
42 ));
}
template <
typename W>
void check_make_semigroup() {
Presentation<W> p;
presentation::add_rule(p, {
0 ,
0 }, {});
presentation::add_rule(p, {
1 ,
1 }, {});
presentation::add_rule(p, {
2 ,
2 }, {});
presentation::add_rule(p, {
0 ,
1 ,
0 ,
1 ,
0 ,
1 }, {});
presentation::add_rule(p, {
1 ,
2 ,
1 ,
0 ,
1 ,
2 ,
1 ,
0 }, {});
presentation::add_rule(p, {
2 ,
0 ,
2 ,
1 ,
2 ,
0 ,
2 ,
1 }, {
0 ,
3 });
p.alphabet_from_rules();
auto e = presentation::make_semigroup(p);
REQUIRE(p.rules
== std::vector<W>({{
0 ,
0 },
{e},
{
1 ,
1 },
{e},
{
2 ,
2 },
{e},
{
0 ,
1 ,
0 ,
1 ,
0 ,
1 },
{e},
{
1 ,
2 ,
1 ,
0 ,
1 ,
2 ,
1 ,
0 },
{e},
{
2 ,
0 ,
2 ,
1 ,
2 ,
0 ,
2 ,
1 },
{
0 ,
3 },
{
0 , e},
{
0 },
{e,
0 },
{
0 },
{
1 , e},
{
1 },
{e,
1 },
{
1 },
{
2 , e},
{
2 },
{e,
2 },
{
2 },
{
3 , e},
{
3 },
{e,
3 },
{
3 },
{e, e},
{e}}));
REQUIRE(presentation::make_semigroup(p) == UNDEFINED);
}
}
// namespace
using detail::StaticVector1;
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"000" ,
"vectors of ints" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
Presentation<word_type> p;
p.alphabet({
0 ,
1 ,
2 });
REQUIRE(p.alphabet() == word_type({
0 ,
1 ,
2 }));
REQUIRE_THROWS_AS(p.alphabet({
0 ,
0 }), LibsemigroupsException);
REQUIRE(p.alphabet() == word_type({
0 ,
1 ,
2 }));
presentation::add_rule(p, {
0 ,
0 ,
0 }, {
0 });
REQUIRE(std::distance(p.rules.cbegin(), p.rules.cend()) ==
2 );
REQUIRE(std::vector<word_type>(p.rules.cbegin(), p.rules.cend())
== std::vector<word_type>({{
0 ,
0 ,
0 }, {
0 }}));
presentation::add_rule_and_check(p, {
0 ,
0 ,
0 }, {
0 });
REQUIRE_THROWS_AS(presentation::add_rule_and_check(p, {
0 ,
5 ,
0 }, {
0 }),
LibsemigroupsException);
REQUIRE_THROWS_AS(presentation::add_rule_and_check(p, {}, {
0 }),
LibsemigroupsException);
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"001" ,
"strings" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
Presentation<std::string> p;
p.alphabet(
"abc" );
REQUIRE(p.alphabet() ==
"abc" );
REQUIRE_THROWS_AS(p.alphabet(
"aa" ), LibsemigroupsException);
REQUIRE(p.alphabet() ==
"abc" );
presentation::add_rule(p,
"aaa" ,
"a" );
REQUIRE(std::distance(p.rules.cbegin(), p.rules.cend()) ==
2 );
REQUIRE(std::vector<std::string>(p.rules.cbegin(), p.rules.cend())
== std::vector<std::string>({
"aaa" ,
"a" }));
REQUIRE_THROWS_AS(presentation::add_rule_and_check(p,
"abz" ,
"a" ),
LibsemigroupsException);
REQUIRE_THROWS_AS(presentation::add_rule_and_check(p,
"" ,
"a" ),
LibsemigroupsException);
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"002" ,
"constructors (word_type)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
Presentation<word_type> p;
p.alphabet({
0 ,
1 ,
2 });
presentation::add_rule(p, {
0 ,
0 ,
0 }, {
0 });
REQUIRE(p.rules.size() ==
2 );
presentation::add_rule_and_check(p, {
0 ,
0 ,
0 }, {
0 });
p.validate();
check_constructors(p);
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"003" ,
"constructors (StaticVector1)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
Presentation<StaticVector1<uint16_t,
16 >> p;
p.alphabet({
0 ,
1 ,
2 });
presentation::add_rule(p, {
0 ,
0 ,
0 }, {
0 });
REQUIRE(p.rules.size() ==
2 );
presentation::add_rule_and_check(p, {
0 ,
0 ,
0 }, {
0 });
p.validate();
check_constructors(p);
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"004" ,
"constructors (std::string)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
Presentation<std::string> p;
p.alphabet(
"abc" );
presentation::add_rule(p,
"aaaa" ,
"aa" );
REQUIRE(p.rules.size() ==
2 );
presentation::add_rule_and_check(p,
"aaa" ,
"aa" );
p.validate();
check_constructors(p);
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"005" ,
"alphabet + letters (word_type)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_alphabet_letters<word_type>();
check_alphabet_letters<StaticVector1<uint16_t,
16 >>();
check_alphabet_letters<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"006" ,
"alphabet + letters (std::string)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
Presentation<std::string> p;
p.alphabet(
"abc" );
REQUIRE(p.alphabet() ==
"abc" );
REQUIRE(p.letter(
0 ) ==
'a' );
REQUIRE(p.letter(
1 ) ==
'b' );
REQUIRE(p.letter(
2 ) ==
'c' );
p.alphabet(
4 );
REQUIRE(p.alphabet().size() ==
4 );
p.validate();
REQUIRE_THROWS_AS(p.alphabet(
"abb" ), LibsemigroupsException);
presentation::add_rule(p,
"abca" ,
"aa" );
presentation::add_rule(p,
"eb" ,
"af" );
presentation::add_rule(p,
"eb" ,
"abbbbbb" );
p.alphabet_from_rules();
REQUIRE(p.alphabet() ==
"abcef" );
REQUIRE(p.index(
'a' ) ==
0 );
REQUIRE(p.index(
'b' ) ==
1 );
REQUIRE(p.index(
'c' ) ==
2 );
REQUIRE(p.index(
'e' ) ==
3 );
REQUIRE(p.index(
'f' ) ==
4 );
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"007" ,
"contains_empty_word" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_contains_empty_word<word_type>();
check_contains_empty_word<StaticVector1<uint16_t,
16 >>();
check_contains_empty_word<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"008" ,
"validate_rules throws" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_validate_rules_throws<word_type>();
check_validate_rules_throws<StaticVector1<uint16_t,
16 >>();
check_validate_rules_throws<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"009" ,
"helpers add_rule(s)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_add_rules<word_type>();
check_add_rules<StaticVector1<uint16_t,
10 >>();
check_add_rules<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"010" ,
"helpers add_rule(s) (std::string)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
Presentation<std::string> p;
presentation::add_rule(p,
"abcb" ,
"aa" );
Presentation<std::string> q;
presentation::add_rule(q,
"eb" ,
"af" );
presentation::add_rule(q,
"eb" ,
"abbbbbbbbb" );
presentation::add_rules(p, q);
REQUIRE(p.rules
== std::vector<std::string>(
{
"abcb" ,
"aa" ,
"eb" ,
"af" ,
"eb" ,
"abbbbbbbbb" }));
REQUIRE(q.rules
== std::vector<std::string>({
"eb" ,
"af" ,
"eb" ,
"abbbbbbbbb" }));
REQUIRE_THROWS_AS(p.validate(), LibsemigroupsException);
REQUIRE_THROWS_AS(q.validate(), LibsemigroupsException);
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"011" ,
"helpers add_identity_rules (std::vector/StaticVector1)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_add_identity_rules<word_type>();
check_add_identity_rules<StaticVector1<uint16_t,
10 >>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"035" ,
"helpers add_zero_rules (std::vector/StaticVector1)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_add_zero_rules<word_type>();
check_add_zero_rules<StaticVector1<uint16_t,
10 >>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"012" ,
"helpers add_identity_rules (std::string)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
Presentation<std::string> p;
presentation::add_rule(p,
"abcb" ,
"aa" );
REQUIRE_THROWS_AS(presentation::add_identity_rules(p,
'a' ),
LibsemigroupsException);
p.alphabet_from_rules();
presentation::add_identity_rules(p,
'a' );
REQUIRE(p.rules
== std::vector<std::string>({
"abcb" ,
"aa" ,
"aa" ,
"a" ,
"ba" ,
"b" ,
"ab" ,
"b" ,
"ca" ,
"c" ,
"ac" ,
"c" }));
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"036" ,
"helpers add_zero_rules (std::string)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
Presentation<std::string> p;
presentation::add_rule(p,
"abcb" ,
"aa" );
REQUIRE_THROWS_AS(presentation::add_zero_rules(p,
'0' ),
LibsemigroupsException);
p.alphabet(
"abc0" );
presentation::add_zero_rules(p,
'0' );
REQUIRE(p.rules
== std::vector<std::string>({
"abcb" ,
"aa" ,
"a0" ,
"0" ,
"0a" ,
"0" ,
"b0" ,
"0" ,
"0b" ,
"0" ,
"c0" ,
"0" ,
"0c" ,
"0" ,
"00" ,
"0" }));
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"013" ,
"helpers add_inverse_rules (all)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_add_inverse_rules<word_type>();
check_add_inverse_rules<StaticVector1<uint16_t,
10 >>();
check_add_inverse_rules<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"014" ,
"helpers add_inverse_rules (std::string)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
Presentation<std::string> p;
p.contains_empty_word(
false );
p.alphabet(
"aAbBcCe" );
presentation::add_identity_rules(p,
'e' );
presentation::add_inverse_rules(p,
"AaBbCce" ,
'e' );
presentation::add_rule_and_check(p,
"aaCac" ,
"e" );
presentation::add_rule_and_check(p,
"acbbACb" ,
"e" );
presentation::add_rule_and_check(p,
"ABabccc" ,
"e" );
REQUIRE(
p.rules
== std::vector<std::string>(
{
"ae" ,
"a" ,
"ea" ,
"a" ,
"Ae" ,
"A" ,
"eA" ,
"A" ,
"be" ,
"b" ,
"eb" ,
"b" ,
"Be" ,
"B" ,
"eB" ,
"B" ,
"ce" ,
"c" ,
"ec" ,
"c" ,
"Ce" ,
"C" ,
"eC" ,
"C" ,
"ee" ,
"e" ,
"aA" ,
"e" ,
"Aa" ,
"e" ,
"bB" ,
"e" ,
"Bb" ,
"e" ,
"cC" ,
"e" ,
"Cc" ,
"e" ,
"aaCac" ,
"e" ,
"acbbACb" ,
"e" ,
"ABabccc" ,
"e" }));
REQUIRE(!presentation::are_rules_sorted(p));
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"015" ,
"helpers remove_duplicate_rules" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_remove_duplicate_rules<word_type>();
check_remove_duplicate_rules<StaticVector1<uint16_t,
10 >>();
check_remove_duplicate_rules<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"016" ,
"helpers reduce_complements" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_reduce_complements<word_type>();
check_reduce_complements<StaticVector1<uint16_t,
10 >>();
Presentation<std::string> p;
presentation::add_rule(p,
"abcb" ,
"bcb" );
presentation::add_rule(p,
"bcb" ,
"bbcb" );
presentation::add_rule(p,
"bbcb" ,
"bb" );
presentation::add_rule(p,
"bb" ,
"bcb" );
presentation::add_rule(p,
"bcb" ,
"a" );
p.alphabet_from_rules();
presentation::reduce_complements(p);
presentation::sort_each_rule(p);
presentation::sort_rules(p);
REQUIRE(p.rules
== std::vector<std::string>(
{
"bb" ,
"a" ,
"bcb" ,
"a" ,
"abcb" ,
"a" ,
"bbcb" ,
"a" }));
REQUIRE(p.alphabet() ==
"abc" );
presentation::normalize_alphabet(p);
REQUIRE(p.letter(
0 ) == presentation::letter(p,
0 ));
REQUIRE(p.letter(
1 ) == presentation::letter(p,
1 ));
REQUIRE(p.letter(
2 ) == presentation::letter(p,
2 ));
p.validate();
presentation::add_rule(p,
"abcb" ,
"ecb" );
REQUIRE(!p.in_alphabet(
'e' ));
// Not valid
REQUIRE_THROWS_AS(presentation::normalize_alphabet(p),
LibsemigroupsException);
p.alphabet_from_rules();
presentation::add_rule(p,
"abcd" ,
"bcb" );
REQUIRE_THROWS_AS(presentation::normalize_alphabet(p),
LibsemigroupsException);
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"017" ,
"helpers sort_each_rule" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_sort_each_rule<word_type>();
check_sort_each_rule<StaticVector1<uint16_t,
10 >>();
check_sort_each_rule<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"018" ,
"helpers sort_rules" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_sort_rules<word_type>();
check_sort_rules<StaticVector1<uint16_t,
10 >>();
check_sort_rules<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"019" ,
"helpers longest_common_subword/replace_subword" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_longest_common_subword<word_type>();
check_longest_common_subword<StaticVector1<uint16_t,
10 >>();
check_longest_common_subword<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"020" ,
"helpers redundant_rule" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_redundant_rule<word_type>();
check_redundant_rule<StaticVector1<uint16_t,
10 >>();
check_redundant_rule<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"021" ,
"helpers shortlex_compare_concat" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_shortlex_compare_concat<word_type>();
check_shortlex_compare_concat<StaticVector1<uint16_t,
10 >>();
check_shortlex_compare_concat<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"022" ,
"helpers remove_trivial_rules" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_remove_trivial_rules<word_type>();
check_remove_trivial_rules<StaticVector1<uint16_t,
10 >>();
check_remove_trivial_rules<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"023" ,
"helpers replace_subword (existing, replacement)" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_replace_subword<word_type>();
check_replace_subword<StaticVector1<uint16_t,
64 >>();
check_replace_subword<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"030" ,
"helpers replace_word" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_replace_word<word_type>();
check_replace_word<StaticVector1<uint16_t,
10 >>();
check_replace_word<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"024" ,
"helpers longest_rule" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_longest_rule<word_type>();
check_longest_rule<StaticVector1<uint16_t,
10 >>();
check_longest_rule<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"025" ,
"helpers longest_rule_length" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_longest_rule_length<word_type>();
check_longest_rule_length<StaticVector1<uint16_t,
10 >>();
check_longest_rule_length<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"026" ,
"helpers remove_redundant_generators" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_remove_redundant_generators<word_type>();
check_remove_redundant_generators<StaticVector1<uint16_t,
64 >>();
check_remove_redundant_generators<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"027" ,
"helpers reverse" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_reverse<word_type>();
check_reverse<StaticVector1<uint16_t,
10 >>();
check_reverse<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"028" ,
"in_alphabet" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
check_in_alphabet<word_type>();
check_in_alphabet<StaticVector1<uint16_t,
10 >>();
check_in_alphabet<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"029" ,
"replace_subword with empty word" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
Presentation<std::string> p;
p.alphabet(
2 );
p.contains_empty_word(
true );
presentation::add_rule(p, {
0 ,
0 ,
0 }, {});
p.validate();
REQUIRE_THROWS_AS(presentation::replace_subword(p, {}, {
2 }),
LibsemigroupsException);
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"031" ,
"clear" ,
"[quick][presentation]" ) {
auto rg = ReportGuard(
false );
Presentation<std::string> p;
p.alphabet(
2 );
p.contains_empty_word(
true );
presentation::add_rule(p, {
0 ,
0 ,
0 }, {});
p.validate();
p.clear();
REQUIRE(p.alphabet().empty());
REQUIRE(p.rules.empty());
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"040" ,
"change_alphabet" ,
"[quick][presentation]" ) {
Presentation<std::string> p;
p.alphabet(
"ab" );
presentation::add_rule_and_check(p,
"ba" ,
"abaaabaa" );
presentation::replace_subword(p,
"ba" );
presentation::change_alphabet(p,
"abc" );
REQUIRE(p.rules == std::vector<std::string>({
"c" ,
"acaaca" ,
"c" ,
"ba" }));
REQUIRE(p.alphabet() ==
"abc" );
REQUIRE_NOTHROW(p.validate());
// Alphabet wrong size
REQUIRE_THROWS_AS(presentation::change_alphabet(p,
"ab" ),
LibsemigroupsException);
REQUIRE_THROWS_AS(presentation::change_alphabet(p,
"aab" ),
LibsemigroupsException);
REQUIRE(p.alphabet() ==
"abc" );
REQUIRE(p.rules == std::vector<std::string>({
"c" ,
"acaaca" ,
"c" ,
"ba" }));
presentation::change_alphabet(p,
"bac" );
REQUIRE(p.rules == std::vector<std::string>({
"c" ,
"bcbbcb" ,
"c" ,
"ab" }));
REQUIRE(p.alphabet() ==
"bac" );
presentation::change_alphabet(p,
"xyz" );
REQUIRE(p.rules == std::vector<std::string>({
"z" ,
"xzxxzx" ,
"z" ,
"yx" }));
REQUIRE(p.alphabet() ==
"xyz" );
presentation::change_alphabet(p,
"xyt" );
REQUIRE(p.rules == std::vector<std::string>({
"t" ,
"xtxxtx" ,
"t" ,
"yx" }));
REQUIRE(p.alphabet() ==
"xyt" );
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"032" ,
"letter" ,
"[quick][presentation]" ) {
Presentation<std::vector<uint16_t>> p;
REQUIRE_THROWS_AS(presentation::letter(p,
65536 ), LibsemigroupsException);
REQUIRE(presentation::letter(p,
10 ) ==
10 );
REQUIRE_THROWS_AS(presentation::character(
65536 ), LibsemigroupsException);
REQUIRE(presentation::character(
0 ) ==
'a' );
REQUIRE(presentation::character(
10 ) ==
'k' );
IntegralRange<size_t> ir(
0 ,
255 );
Presentation<std::string> q;
REQUIRE(std::all_of(ir.cbegin(), ir.cend(), [&q](size_t i) {
return presentation::character(i) == presentation::letter(q, i);
}));
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"033" ,
"normalize_alphabet" ,
"[quick][presentation]" ) {
Presentation<std::string> p;
p.alphabet(
"axy" );
presentation::normalize_alphabet(p);
REQUIRE(p.alphabet() ==
"abc" );
Presentation<word_type> q;
q.alphabet({
0 ,
10 ,
12 });
presentation::normalize_alphabet(q);
REQUIRE(q.alphabet() == word_type({
0 ,
1 ,
2 }));
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"042" ,
"first_unused_letter/letter" ,
"[quick][presentation]" ) {
Presentation<std::string> p;
p.alphabet(
"ab" );
presentation::add_rule_and_check(p,
"baabaa" ,
"ababa" );
REQUIRE(presentation::first_unused_letter(p) ==
'c' );
p.alphabet(
"abcdefghijklmnopq" );
REQUIRE(presentation::first_unused_letter(p) ==
'r' );
p.alphabet(
"abcdefghijklmnopqrstuvwxyz" );
REQUIRE(presentation::first_unused_letter(p) ==
'A' );
p.alphabet(
"abcdefgijklmnopqrstuvwxyz" );
REQUIRE(presentation::first_unused_letter(p) ==
'h' );
p.alphabet(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" );
REQUIRE(presentation::first_unused_letter(p) ==
'0' );
p.alphabet(
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ02" );
REQUIRE(presentation::first_unused_letter(p) ==
'1' );
std::string
const letters
=
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" ;
std::unordered_set<letter_type> set;
for (size_t i =
0 ; i < letters.size(); ++i) {
REQUIRE(letters[i] == presentation::letter(p, i));
REQUIRE(set.insert(letters[i]).second);
}
for (size_t i = letters.size(); i <
255 ; ++i) {
REQUIRE(set.insert(presentation::letter(p, i)).second);
}
REQUIRE_THROWS_AS(presentation::letter(p,
255 ), LibsemigroupsException);
p.alphabet(
255 );
REQUIRE_THROWS_AS(presentation::first_unused_letter(p),
LibsemigroupsException);
REQUIRE_THROWS_AS(p.alphabet(
256 ), LibsemigroupsException);
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"034" ,
"longest_common_subword issue" ,
"[quick][presentation]" ) {
Presentation<std::string> p;
p.alphabet(
"a" );
presentation::add_rule_and_check(p,
"aaaaaaaaaaaaaaaaaaa" ,
"a" );
REQUIRE(presentation::longest_common_subword(p) ==
"aaaaaa" );
presentation::replace_subword(p,
"aaaaaa" );
REQUIRE(presentation::longest_common_subword(p) ==
"" );
REQUIRE(p.rules == std::vector<std::string>({
"bbba" ,
"a" ,
"b" ,
"aaaaaa" }));
REQUIRE(presentation::length(p) ==
12 );
p.rules = std::vector<std::string>({
"bba" ,
"a" ,
"b" ,
"aaaaaaaa" });
REQUIRE(presentation::length(p) ==
13 );
p.alphabet(
"ab" );
presentation::add_rule_and_check(p,
"baaaaaaaaaaaaaaaaaaa" ,
"a" );
REQUIRE(presentation::longest_common_subword(p) ==
"aaaaaa" );
p.alphabet(
"ab" );
p.rules.clear();
presentation::add_rule_and_check(p,
"aaaaaaaaaaaaaaaa" ,
"a" );
presentation::add_rule_and_check(p,
"bbbbbbbbbbbbbbbb" ,
"b" );
presentation::add_rule_and_check(p,
"abb" ,
"baa" );
REQUIRE(presentation::length(p) ==
40 );
auto w = presentation::longest_common_subword(p);
REQUIRE(w ==
"bbbb" );
presentation::replace_subword(p, w);
REQUIRE(presentation::length(p) ==
33 );
REQUIRE(
p.rules
== std::vector<std::string>(
{
"aaaaaaaaaaaaaaaa" ,
"a" ,
"cccc" ,
"b" ,
"abb" ,
"baa" ,
"c" ,
"bbbb" }));
w = presentation::longest_common_subword(p);
REQUIRE(w ==
"aaaa" );
presentation::replace_subword(p, w);
REQUIRE(presentation::length(p) ==
26 );
REQUIRE(p.rules
== std::vector<std::string>({
"dddd" ,
"a" ,
"cccc" ,
"b" ,
"abb" ,
"baa" ,
"c" ,
"bbbb" ,
"d" ,
"aaaa" }));
w = presentation::longest_common_subword(p);
REQUIRE(w ==
"" );
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"037" ,
"make_semigroup" ,
"[quick][presentation]" ) {
check_make_semigroup<word_type>();
check_make_semigroup<StaticVector1<uint16_t,
10 >>();
check_make_semigroup<std::string>();
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"038" ,
"greedy_reduce_length" ,
"[quick][presentation]" ) {
Presentation<std::string> p;
p.alphabet(
"ab" );
p.rules.clear();
presentation::add_rule_and_check(p,
"aaaaaaaaaaaaaaaa" ,
"a" );
presentation::add_rule_and_check(p,
"bbbbbbbbbbbbbbbb" ,
"b" );
presentation::add_rule_and_check(p,
"abb" ,
"baa" );
REQUIRE(presentation::length(p) ==
40 );
presentation::greedy_reduce_length(p);
REQUIRE(presentation::length(p) ==
26 );
REQUIRE(p.rules
== std::vector<std::string>({
"dddd" ,
"a" ,
"cccc" ,
"b" ,
"abb" ,
"baa" ,
"c" ,
"bbbb" ,
"d" ,
"aaaa" }));
REQUIRE(presentation::longest_common_subword(p) ==
"" );
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"039" ,
"aaaaaaaab = aaaaaaaaab strong compression" ,
"[quick][presentation]" ) {
Presentation<std::string> p;
p.alphabet(
"ab" );
presentation::add_rule_and_check(p,
"aaaaaaaab" ,
"aaaaaaaaab" );
REQUIRE(presentation::strongly_compress(p));
REQUIRE(p.rules == decltype(p.rules)({
"a" ,
"aa" }));
p.rules = {
"adadnadnasnamdnamdna" ,
"akdjskadjksajdaldja" };
p.alphabet_from_rules();
REQUIRE(presentation::strongly_compress(p));
REQUIRE(presentation::reduce_to_2_generators(p));
REQUIRE(
p.rules
== decltype(p.rules)({
"aaaaaaaaaaaaaaaaaaa" ,
"baaaaaaaaaaaaaaaaa" }));
// Only works for 1-relation monoids at present
p.alphabet(
"ab" );
presentation::add_rule_and_check(p,
"aaaaaaaab" ,
"aaaaaaaaab" );
presentation::add_rule_and_check(p,
"aaaaaaaab" ,
"aaaaaaaaab" );
REQUIRE(!presentation::strongly_compress(p));
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"043" ,
"case where strong compression doesn't work" ,
"[quick][presentation]" ) {
Presentation<std::string> p;
p.alphabet(
"ab" );
presentation::add_rule_and_check(p,
"abaaaabab" ,
"abbabaaaab" );
REQUIRE(presentation::strongly_compress(p));
REQUIRE(p.rules == decltype(p.rules)({
"abccdae" ,
"fgeabccd" }));
auto q = p;
REQUIRE(presentation::reduce_to_2_generators(q));
REQUIRE(q.rules == decltype(q.rules)({
"aaaaaaa" ,
"baaaaaaa" }));
q = p;
REQUIRE(presentation::reduce_to_2_generators(q,
1 ));
REQUIRE(q.rules == decltype(q.rules)({
"abbbbab" ,
"bbbabbbb" }));
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"044" ,
"proof that" ,
"[quick][presentation]" ) {
Presentation<std::string> p;
p.alphabet(
"ab" );
presentation::add_rule_and_check(p,
"aabb" ,
"aaabaaab" );
REQUIRE(presentation::strongly_compress(p));
presentation::reverse(p);
REQUIRE(p.rules == decltype(p.rules)({
"cba" ,
"baadbaa" }));
auto q = p;
REQUIRE(presentation::reduce_to_2_generators(q));
REQUIRE(q.rules == decltype(q.rules)({
"aba" ,
"baaabaa" }));
q = p;
REQUIRE(presentation::reduce_to_2_generators(q,
1 ));
REQUIRE(q.rules == decltype(q.rules)({
"abb" ,
"bbbbbbb" }));
// Wrong index
REQUIRE_THROWS_AS(presentation::reduce_to_2_generators(q,
2 ),
LibsemigroupsException);
q = p;
presentation::add_rule_and_check(q,
"aabb" ,
"aaabaaab" );
// not 1-relation
REQUIRE(!presentation::reduce_to_2_generators(q,
1 ));
q.rules = {
"aaaaa" ,
"a" };
REQUIRE(!presentation::reduce_to_2_generators(q));
q.rules = {
"aaaaa" ,
"" };
REQUIRE(!presentation::reduce_to_2_generators(q));
q.rules = {
"abcacbabab" ,
"" };
REQUIRE(!presentation::reduce_to_2_generators(q));
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"045" ,
"decompression" ,
"[quick][presentation]" ) {
Presentation<std::string> p;
p.alphabet(
"ab" );
p.rules = {
"aabb" ,
"aaabaab" };
REQUIRE(presentation::strongly_compress(p));
REQUIRE(p.rules == decltype(p.rules)({
"abc" ,
"aabdab" }));
REQUIRE(!presentation::reduce_to_2_generators(p));
presentation::reverse(p);
REQUIRE(presentation::reduce_to_2_generators(p));
REQUIRE(p.rules == decltype(p.rules)({
"aba" ,
"baabaa" }));
}
LIBSEMIGROUPS_TEST_CASE(
"Presentation" ,
"041" ,
"sort_rules bug" ,
"[quick][presentation]" ) {
std::string prefix1 =
"dabd" , suffix1 =
"cbb" , prefix2 =
"abbaba" ,
suffix2 =
"c" ;
REQUIRE(
!detail::shortlex_compare_concat(prefix1, suffix1, prefix2, suffix2));
Presentation<std::string> p;
p.alphabet(
"bacd" );
p.rules = {
"baabbabaa" ,
"abaaba" ,
"abbaba" ,
"c" ,
"abb" ,
"d" ,
"daba" ,
"c" ,
"dabd" ,
"cbb" ,
"dbaca" ,
"caba" ,
"dbacc" ,
"cabc" ,
"dbacd" ,
"cabd" ,
"abaaba" ,
"baca" ,
"abaabc" ,
"bacc" ,
"abaabd" ,
"bacd" ,
"cbaaba" ,
"ddaca" ,
"cbaabc" ,
"ddacc" ,
"cbaabd" ,
"ddacd" ,
"cbbaba" ,
"dabc" ,
"dabcbb" ,
"cbbabd" ,
"bacaaba" ,
"ababaca" ,
"bacaabc" ,
"ababacc" ,
"bacaabd" ,
"ababacd" ,
"bacbaca" ,
"abadaca" ,
"bacbacc" ,
"abadacc" ,
"bacbacd" ,
"abadacd" ,
"dabcaba" ,
"cbbbaca" ,
"dabcabc" ,
"cbbbacc" ,
"dabcabd" ,
"cbbbacd" ,
"ddacaaba" ,
"cbabaca" ,
"ddacaabc" ,
"cbabacc" ,
"ddacaabd" ,
"cbabacd" ,
"ddacbaca" ,
"cbadaca" ,
"ddacbacc" ,
"cbadacc" ,
"ddacbacd" ,
"cbadacd" ,
"abababaca" ,
"dacaaba" ,
"abababacc" ,
"dacaabc" ,
"abababacd" ,
"dacaabd" ,
"ababadaca" ,
"dacbaca" ,
"ababadacc" ,
"dacbacc" ,
"ababadacd" ,
"dacbacd" ,
"daababaca" ,
"ccaaba" ,
"daababacc" ,
"ccaabc" ,
"daababacd" ,
"ccaabd" ,
"daabadaca" ,
"ccbaca" ,
"daabadacc" ,
"ccbacc" ,
"daabadacd" ,
"ccbacd" ,
"bacababaca" ,
"abadacaaba" ,
"bacababacc" ,
"abadacaabc" ,
"bacababacd" ,
"abadacaabd" ,
"bacabadaca" ,
"abadacbaca" ,
"bacabadacc" ,
"abadacbacc" ,
"bacabadacd" ,
"abadacbacd" ,
"dabcbabaca" ,
"cbbdacaaba" ,
"dabcbabacc" ,
"cbbdacaabc" ,
"dabcbabacd" ,
"cbbdacaabd" ,
"dabcbadaca" ,
"cbbdacbaca" ,
"dabcbadacc" ,
"cbbdacbacc" ,
"dabcbadacd" ,
"cbbdacbacd" ,
"abaaababaca" ,
"bacacaaba" ,
"abaaababacc" ,
"bacacaabc" ,
"abaaababacd" ,
"bacacaabd" ,
"abaaabadaca" ,
"bacacbaca" ,
"abaaabadacc" ,
"bacacbacc" ,
"abaaabadacd" ,
"bacacbacd" ,
"cbaaababaca" ,
"ddacacaaba" ,
"cbaaababacc" ,
"ddacacaabc" ,
"cbaaababacd" ,
"ddacacaabd" ,
"cbaaabadaca" ,
"ddacacbaca" ,
"cbaaabadacc" ,
"ddacacbacc" ,
"cbaaabadacd" ,
"ddacacbacd" ,
"cbbaababaca" ,
"dabccaaba" ,
"cbbaababacc" ,
"dabccaabc" ,
"cbbaababacd" ,
"dabccaabd" ,
"cbbaabadaca" ,
"dabccbaca" ,
"cbbaabadacc" ,
"dabccbacc" ,
"cbbaabadacd" ,
"dabccbacd" ,
"ddacababaca" ,
"cbadacaaba" ,
"ddacababacc" ,
"cbadacaabc" ,
"ddacababacd" ,
"cbadacaabd" ,
"ddacabadaca" ,
"cbadacbaca" ,
"ddacabadacc" ,
"cbadacbacc" ,
"ddacabadacd" ,
"cbadacbacd" ,
"ababadacbaca" ,
"dacabadaca" ,
"ababadacbacc" ,
"dacabadacc" ,
"ababadacbacd" ,
"dacabadacd" ,
"bacaaababaca" ,
"ababacacaaba" ,
"bacaaababacc" ,
"ababacacaabc" ,
"bacaaababacd" ,
"ababacacaabd" ,
"bacaaabadaca" ,
"ababacacbaca" ,
"bacaaabadacc" ,
"ababacacbacc" ,
"bacaaabadacd" ,
"ababacacbacd" ,
"daabadacbaca" ,
"ccabadaca" ,
"daabadacbacc" ,
"ccabadacc" ,
"daabadacbacd" ,
"ccabadacd" ,
"bacabadacbaca" ,
"abadacabadaca" ,
"bacabadacbacc" ,
"abadacabadacc" ,
"bacabadacbacd" ,
"abadacabadacd" ,
"dabcbadacaaba" ,
"cbbdacababaca" ,
"dabcbadacaabc" ,
"cbbdacababacc" ,
"dabcbadacaabd" ,
"cbbdacababacd" ,
"dabcbadacbaca" ,
"cbbdacabadaca" ,
"dabcbadacbacc" ,
"cbbdacabadacc" ,
"dabcbadacbacd" ,
"cbbdacabadacd" ,
"ddacaaababaca" ,
"cbabacacaaba" ,
"ddacaaababacc" ,
"cbabacacaabc" ,
"ddacaaababacd" ,
"cbabacacaabd" ,
"ddacaaabadaca" ,
"cbabacacbaca" ,
"ddacaaabadacc" ,
"cbabacacbacc" ,
"ddacaaabadacd" ,
"cbabacacbacd" ,
"abaaabadacbaca" ,
"bacacabadaca" ,
"abaaabadacbacc" ,
"bacacabadacc" ,
"abaaabadacbacd" ,
"bacacabadacd" ,
"cbaaabadacbaca" ,
"ddacacabadaca" ,
"cbaaabadacbacc" ,
"ddacacabadacc" ,
"cbaaabadacbacd" ,
"ddacacabadacd" ,
"cbbaabadacbaca" ,
"dabccabadaca" ,
"cbbaabadacbacc" ,
"dabccabadacc" ,
"cbbaabadacbacd" ,
"dabccabadacd" ,
"ddacabadacbaca" ,
"cbadacabadaca" ,
"ddacabadacbacc" ,
"cbadacabadacc" ,
"ddacabadacbacd" ,
"cbadacabadacd" ,
"bacaaabadacbaca" ,
"ababacacabadaca" ,
"bacaaabadacbacc" ,
"ababacacabadacc" ,
"bacaaabadacbacd" ,
"ababacacabadacd" ,
"dabcbabacacaaba" ,
"cbbdacaaababaca" ,
"dabcbabacacaabc" ,
"cbbdacaaababacc" ,
"dabcbabacacaabd" ,
"cbbdacaaababacd" ,
"dabcbabacacbaca" ,
"cbbdacaaabadaca" ,
"dabcbabacacbacc" ,
"cbbdacaaabadacc" ,
"dabcbabacacbacd" ,
"cbbdacaaabadacd" ,
"dabcbadacabadaca" ,
"cbbdacabadacbaca" ,
"dabcbadacabadacc" ,
"cbbdacabadacbacc" };
REQUIRE(p.rules.size() ==
258 );
p.validate();
presentation::sort_each_rule(p);
presentation::sort_rules(p);
REQUIRE(presentation::are_rules_sorted(p));
REQUIRE(p.rules
== std::vector<std::string>({
"abb" ,
"d" ,
"daba" ,
"c" ,
"abbaba" ,
"c" ,
"dabd" ,
"cbb" ,
"dbaca" ,
"caba" ,
"dbacc" ,
"cabc" ,
"dbacd" ,
"cabd" ,
"abaaba" ,
"baca" ,
"abaabc" ,
"bacc" ,
"abaabd" ,
"bacd" ,
"cbbaba" ,
"dabc" ,
"cbaaba" ,
"ddaca" ,
"cbaabc" ,
"ddacc" ,
"cbaabd" ,
"ddacd" ,
"dabcbb" ,
"cbbabd" ,
"bacaaba" ,
"ababaca" ,
"bacaabc" ,
"ababacc" ,
"bacaabd" ,
"ababacd" ,
"bacbaca" ,
"abadaca" ,
"bacbacc" ,
"abadacc" ,
"bacbacd" ,
"abadacd" ,
"dabcaba" ,
"cbbbaca" ,
"dabcabc" ,
"cbbbacc" ,
"dabcabd" ,
"cbbbacd" ,
"baabbabaa" ,
"abaaba" ,
"daababaca" ,
"ccaaba" ,
"daababacc" ,
"ccaabc" ,
"daababacd" ,
"ccaabd" ,
"daabadaca" ,
"ccbaca" ,
"daabadacc" ,
"ccbacc" ,
"daabadacd" ,
"ccbacd" ,
"ddacaaba" ,
"cbabaca" ,
"ddacaabc" ,
"cbabacc" ,
"ddacaabd" ,
"cbabacd" ,
"ddacbaca" ,
"cbadaca" ,
"ddacbacc" ,
"cbadacc" ,
"ddacbacd" ,
"cbadacd" ,
"abababaca" ,
"dacaaba" ,
"abababacc" ,
"dacaabc" ,
"abababacd" ,
"dacaabd" ,
"ababadaca" ,
"dacbaca" ,
"ababadacc" ,
"dacbacc" ,
"ababadacd" ,
"dacbacd" ,
"abaaababaca" ,
"bacacaaba" ,
"abaaababacc" ,
"bacacaabc" ,
"abaaababacd" ,
"bacacaabd" ,
"abaaabadaca" ,
"bacacbaca" ,
"abaaabadacc" ,
"bacacbacc" ,
"abaaabadacd" ,
"bacacbacd" ,
"bacababaca" ,
"abadacaaba" ,
"bacababacc" ,
"abadacaabc" ,
"bacababacd" ,
"abadacaabd" ,
"bacabadaca" ,
"abadacbaca" ,
"bacabadacc" ,
"abadacbacc" ,
"bacabadacd" ,
"abadacbacd" ,
"cbbaababaca" ,
"dabccaaba" ,
"cbbaababacc" ,
"dabccaabc" ,
"cbbaababacd" ,
"dabccaabd" ,
"cbbaabadaca" ,
"dabccbaca" ,
"cbbaabadacc" ,
"dabccbacc" ,
"cbbaabadacd" ,
"dabccbacd" ,
"dabcbabaca" ,
"cbbdacaaba" ,
"dabcbabacc" ,
"cbbdacaabc" ,
"dabcbabacd" ,
"cbbdacaabd" ,
"dabcbadaca" ,
"cbbdacbaca" ,
"dabcbadacc" ,
"cbbdacbacc" ,
"dabcbadacd" ,
"cbbdacbacd" ,
"cbaaababaca" ,
"ddacacaaba" ,
"cbaaababacc" ,
"ddacacaabc" ,
"cbaaababacd" ,
"ddacacaabd" ,
"cbaaabadaca" ,
"ddacacbaca" ,
"cbaaabadacc" ,
"ddacacbacc" ,
"cbaaabadacd" ,
"ddacacbacd" ,
"daabadacbaca" ,
"ccabadaca" ,
"daabadacbacc" ,
"ccabadacc" ,
"daabadacbacd" ,
"ccabadacd" ,
"ddacababaca" ,
"cbadacaaba" ,
"ddacababacc" ,
"cbadacaabc" ,
"ddacababacd" ,
"cbadacaabd" ,
"ddacabadaca" ,
"cbadacbaca" ,
"ddacabadacc" ,
"cbadacbacc" ,
"ddacabadacd" ,
"cbadacbacd" ,
"ababadacbaca" ,
"dacabadaca" ,
"ababadacbacc" ,
"dacabadacc" ,
"ababadacbacd" ,
"dacabadacd" ,
"bacaaababaca" ,
"ababacacaaba" ,
"bacaaababacc" ,
"ababacacaabc" ,
"bacaaababacd" ,
"ababacacaabd" ,
"bacaaabadaca" ,
"ababacacbaca" ,
"bacaaabadacc" ,
"ababacacbacc" ,
"bacaaabadacd" ,
"ababacacbacd" ,
"ddacaaababaca" ,
"cbabacacaaba" ,
"ddacaaababacc" ,
"cbabacacaabc" ,
"ddacaaababacd" ,
"cbabacacaabd" ,
"ddacaaabadaca" ,
"cbabacacbaca" ,
"ddacaaabadacc" ,
"cbabacacbacc" ,
"ddacaaabadacd" ,
"cbabacacbacd" ,
"abaaabadacbaca" ,
"bacacabadaca" ,
"abaaabadacbacc" ,
"bacacabadacc" ,
"abaaabadacbacd" ,
"bacacabadacd" ,
"bacabadacbaca" ,
"abadacabadaca" ,
"bacabadacbacc" ,
"abadacabadacc" ,
"bacabadacbacd" ,
"abadacabadacd" ,
"cbbaabadacbaca" ,
"dabccabadaca" ,
"cbbaabadacbacc" ,
"dabccabadacc" ,
"cbbaabadacbacd" ,
"dabccabadacd" ,
"dabcbadacaaba" ,
"cbbdacababaca" ,
"dabcbadacaabc" ,
"cbbdacababacc" ,
"dabcbadacaabd" ,
"cbbdacababacd" ,
"dabcbadacbaca" ,
"cbbdacabadaca" ,
"dabcbadacbacc" ,
"cbbdacabadacc" ,
"dabcbadacbacd" ,
"cbbdacabadacd" ,
"cbaaabadacbaca" ,
"ddacacabadaca" ,
"cbaaabadacbacc" ,
"ddacacabadacc" ,
"cbaaabadacbacd" ,
"ddacacabadacd" ,
"ddacabadacbaca" ,
"cbadacabadaca" ,
"ddacabadacbacc" ,
"cbadacabadacc" ,
"ddacabadacbacd" ,
"cbadacabadacd" ,
"bacaaabadacbaca" ,
"ababacacabadaca" ,
"bacaaabadacbacc" ,
"ababacacabadacc" ,
"bacaaabadacbacd" ,
"ababacacabadacd" ,
"dabcbabacacaaba" ,
"cbbdacaaababaca" ,
"dabcbabacacaabc" ,
"cbbdacaaababacc" ,
"dabcbabacacaabd" ,
"cbbdacaaababacd" ,
"dabcbabacacbaca" ,
"cbbdacaaabadaca" ,
"dabcbabacacbacc" ,
"cbbdacaaabadacc" ,
"dabcbabacacbacd" ,
"cbbdacaaabadacd" ,
"dabcbadacabadaca" ,
"cbbdacabadacbaca" ,
"dabcbadacabadacc" ,
"cbbdacabadacbacc" }));
std::vector<std::string> expected;
for (
auto it = p.rules.cbegin(); it < p.rules.cend(); it +=
2 ) {
expected.push_back(*it + *(it +
1 ));
}
std::vector<std::string> found = expected;
std::sort(found.begin(), found.end(), ShortLexCompare<std::string>());
REQUIRE(found == expected);
for (size_t i =
0 ; i != found.size(); ++i) {
REQUIRE(std::make_pair(found[i], i) == std::make_pair(expected[i], i));
}
}
}
// namespace libsemigroups
Messung V0.5 in Prozent C=77 H=89 G=83
¤ Dauer der Verarbeitung: 0.49 Sekunden
(vorverarbeitet am 2026-06-17)
¤
*© Formatika GbR, Deutschland