//
// libsemigroups - C++ library for semigroups and monoids
// Copyright (C) 2019 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/>.
//
#include <vector>
// for vector
#include "catch.hpp" // for LIBSEMIGROUPS_TEST_CASE
#include "libsemigroups/froidure-pin.hpp" // for FroidurePin
#include "libsemigroups/kbe.hpp" // for KBE
#include "libsemigroups/knuth-bendix.hpp" // for KnuthBendix
#include "libsemigroups/transf.hpp" // for Transf<>
#include "test-main.hpp" // for LIBSEMIGROUPS_TEST_CASE
namespace libsemigroups {
namespace detail {
using KnuthBendix = fpsemigroup::KnuthBendix;
using FroidurePinKBE
= FroidurePin<KBE, FroidurePinTraits<KBE, KnuthBendix>>;
constexpr
bool REPORT =
false;
LIBSEMIGROUPS_TEST_CASE(
"KBE",
"000",
"constructors",
"[quick]") {
auto rg = ReportGuard(REPORT);
FroidurePin<Transf<>> S;
S.add_generator(Transf<>({1, 0}));
S.add_generator(Transf<>({0, 0}));
KnuthBendix kb(S);
KBE ab(kb, word_type({0, 1}));
KBE b(ab);
REQUIRE(b == ab);
b = ab;
REQUIRE(b == ab);
KBE c(std::move(ab));
REQUIRE(c == b);
KBE d;
d = std::move(c);
REQUIRE(d == b);
}
LIBSEMIGROUPS_TEST_CASE(
"KBE",
"001",
"test",
"[quick]") {
auto rg = ReportGuard(REPORT);
FroidurePin<Transf<>> S({Transf<>({1, 0}), Transf<>({0, 0})});
REQUIRE(S.size() == 4);
REQUIRE(S.degree() == 2);
REQUIRE(S.number_of_rules() == 4);
KnuthBendix kb(S);
REQUIRE(kb.confluent());
FroidurePinKBE T(kb);
T.add_generator(KBE(kb, 0));
T.add_generator(KBE(kb, 1));
REQUIRE(T.size() == 4);
KBE ab(kb, word_type({0, 1}));
KBE b(kb, 1);
REQUIRE(!(b < ab));
REQUIRE(b == ab);
REQUIRE(!(ab < b));
REQUIRE(!(ab < b));
KBE aba(kb, word_type({0, 1, 0}));
REQUIRE(b < aba);
}
LIBSEMIGROUPS_TEST_CASE(
"KBE",
"002",
"factorisation",
"[quick]") {
auto rg = ReportGuard(REPORT);
FroidurePin<Transf<>> S({Transf<>({1, 0}), Transf<>({0, 0})});
KnuthBendix kb(S);
REQUIRE(kb.confluent());
FroidurePinKBE T(kb);
T.add_generators({KBE(kb, 0), KBE(kb, 1)});
KBE ab(kb, word_type({0, 1}));
REQUIRE(T.factorisation(ab) == word_type({1}));
KBE aaa(kb, word_type({0, 0, 0}));
REQUIRE(T.factorisation(aaa) == word_type({0}));
}
LIBSEMIGROUPS_TEST_CASE(
"KBE",
"003",
"swap",
"[quick]") {
auto rg = ReportGuard(REPORT);
FroidurePin<Transf<>> S({Transf<>({1, 0}), Transf<>({0, 0})});
KnuthBendix kb(S);
REQUIRE(kb.confluent());
auto x = KBE(kb, 0);
auto y = KBE(kb, 1);
REQUIRE(x == KBE(kb, 0));
REQUIRE(y == KBE(kb, 1));
x.swap(y);
REQUIRE(x == KBE(kb, 1));
REQUIRE(y == KBE(kb, 0));
}
LIBSEMIGROUPS_TEST_CASE(
"KBE",
"004",
"adapters",
"[quick]") {
auto rg = ReportGuard(REPORT);
FroidurePin<Transf<>> S({Transf<>({1, 0}), Transf<>({0, 0})});
KnuthBendix kb(S);
REQUIRE(kb.confluent());
auto x = KBE(kb, 0);
REQUIRE(Complexity<KBE>()(x) == LIMIT_MAX);
REQUIRE(EqualTo<KBE>()(x, x));
REQUIRE(One<KBE>()(x) == KBE());
auto y(x);
IncreaseDegree<KBE>()(y, 10);
REQUIRE(x == y);
}
LIBSEMIGROUPS_TEST_CASE(
"KBE",
"005",
"conversions",
"[quick]") {
auto rg = ReportGuard(REPORT);
FroidurePin<Transf<>> S({Transf<>({1, 0}), Transf<>({0, 0})});
KnuthBendix kb(S);
REQUIRE(kb.confluent());
auto x = KBE(kb, 0);
REQUIRE(x.word(kb) == word_type({0}));
REQUIRE(x.string(kb) == std::string(1, kb.alphabet()[0]));
}
}
// namespace detail
}
// namespace libsemigroups