// libsemigroups - C++ library for semigroups and monoids
// Copyright (C) 2020 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/ >.
//
// This file is the second of six that contains tests for the KnuthBendix
// classes. In a mostly vain attempt to speed up compilation the tests are
// split across 6 files as follows:
//
// 1: contains quick tests for fpsemigroup::KnuthBendix created from rules and
// all commented out tests.
//
// 2: contains more quick tests for fpsemigroup::KnuthBendix created from rules
//
// 3: contains yet more quick tests for fpsemigroup::KnuthBendix created from
// rules
//
// 4: contains standard and extreme test for fpsemigroup::KnuthBendix created
// from rules
//
// 5: contains tests for fpsemigroup::KnuthBendix created from FroidurePin
// instances
//
// 6: contains tests for congruence::KnuthBendix.
// #define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
#include <iostream>
// for ostringstream
#include <string>
// for string
#include <vector>
// for vector
#include "catch.hpp" // for REQUIRE, REQUIRE_NOTHROW, REQUIRE_THROWS_AS
#include "test-main.hpp" // for LIBSEMIGROUPS_TEST_CASE
#include "libsemigroups/constants.hpp" // for POSITIVE_INFINITY
#include "libsemigroups/knuth-bendix.hpp" // for KnuthBendix, operator<<
#include "libsemigroups/report.hpp" // for ReportGuard
namespace libsemigroups {
struct LibsemigroupsException;
constexpr
bool REPORT =
false ;
using rule_type = fpsemigroup::KnuthBendix::rule_type;
namespace fpsemigroup {
// Fibonacci group F(2,5) - monoid presentation - has order 12 (group
// elements + empty word)
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"021" ,
"(from kbmag/standalone/kb_data/f25monoid)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"abcde" );
kb.add_rule(
"ab" ,
"c" );
kb.add_rule(
"bc" ,
"d" );
kb.add_rule(
"cd" ,
"e" );
kb.add_rule(
"de" ,
"a" );
kb.add_rule(
"ea" ,
"b" );
REQUIRE(!kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 24);
REQUIRE(kb.equal_to(
"ab" ,
"c" ));
REQUIRE(kb.equal_to(
"bc" ,
"d" ));
REQUIRE(kb.equal_to(
"cd" ,
"e" ));
REQUIRE(kb.equal_to(
"de" ,
"a" ));
REQUIRE(kb.equal_to(
"ea" ,
"b" ));
REQUIRE(kb.equal_to(
"cc" ,
"ad" ));
REQUIRE(kb.equal_to(
"dd" ,
"be" ));
REQUIRE(kb.equal_to(
"ee" ,
"ca" ));
REQUIRE(kb.equal_to(
"ec" ,
"bb" ));
REQUIRE(kb.equal_to(
"db" ,
"aa" ));
REQUIRE(kb.equal_to(
"aac" ,
"be" ));
REQUIRE(kb.equal_to(
"bd" ,
"aa" ));
REQUIRE(kb.equal_to(
"bbe" ,
"aad" ));
REQUIRE(kb.equal_to(
"aaa" ,
"e" ));
REQUIRE(kb.equal_to(
"eb" ,
"be" ));
REQUIRE(kb.equal_to(
"ba" ,
"c" ));
REQUIRE(kb.equal_to(
"da" ,
"ad" ));
REQUIRE(kb.equal_to(
"ca" ,
"ac" ));
REQUIRE(kb.equal_to(
"ce" ,
"bb" ));
REQUIRE(kb.equal_to(
"cb" ,
"d" ));
REQUIRE(kb.equal_to(
"ed" ,
"a" ));
REQUIRE(kb.equal_to(
"dc" ,
"e" ));
REQUIRE(kb.equal_to(
"ae" ,
"b" ));
REQUIRE(kb.equal_to(
"bbb" ,
"a" ));
REQUIRE(
kb.active_rules()
== std::vector<rule_type>(
{{
"ab" ,
"c" }, {
"ae" ,
"b" }, {
"ba" ,
"c" }, {
"bc" ,
"d" },
{
"bd" ,
"aa" }, {
"ca" ,
"ac" }, {
"cb" ,
"d" }, {
"cc" ,
"ad" },
{
"cd" ,
"e" }, {
"ce" ,
"bb" }, {
"da" ,
"ad" }, {
"db" ,
"aa" },
{
"dc" ,
"e" }, {
"dd" ,
"be" }, {
"de" ,
"a" }, {
"ea" ,
"b" },
{
"eb" ,
"be" }, {
"ec" ,
"bb" }, {
"ed" ,
"a" }, {
"ee" ,
"ca" },
{
"aaa" ,
"e" }, {
"aac" ,
"be" }, {
"bbb" ,
"ed" }, {
"bbe" ,
"aad" }}));
REQUIRE(
std::vector<std::string>(
{
"a" ,
"b" ,
"c" ,
"d" ,
"e" ,
"aa" ,
"ac" ,
"ad" ,
"bb" ,
"be" ,
"aad" })
== std::vector<std::string>(kb.cbegin_normal_forms(0, 5),
kb.cend_normal_forms()));
REQUIRE(kb.size() == 11);
REQUIRE(std::distance(kb.cbegin_normal_forms(0, POSITIVE_INFINITY),
kb.cend_normal_forms())
== 11);
}
// trivial group - BHN presentation
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"022" ,
"(from kbmag/standalone/kb_data/degen4a)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"aAbBcC" );
kb.set_identity(
"" );
kb.set_inverses(
"AaBbCc" );
kb.add_rule(
"Aba" ,
"bb" );
kb.add_rule(
"Bcb" ,
"cc" );
kb.add_rule(
"Cac" ,
"aa" );
REQUIRE(!kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 6);
REQUIRE(kb.equal_to(
"Aba" ,
"bb" ));
REQUIRE(kb.equal_to(
"Bcb" ,
"cc" ));
REQUIRE(kb.equal_to(
"Cac" ,
"aa" ));
REQUIRE(kb.active_rules()
== std::vector<rule_type>({{
"A" ,
"" },
{
"B" ,
"" },
{
"C" ,
"" },
{
"a" ,
"" },
{
"b" ,
"" },
{
"c" ,
"" }}));
REQUIRE(kb.size() == 1);
REQUIRE(std::vector<std::string>({
"" })
== std::vector<std::string>(
kb.cbegin_normal_forms(0, POSITIVE_INFINITY),
kb.cend_normal_forms()));
}
// Torus group
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"023" ,
"(from kbmag/standalone/kb_data/torus)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"aAcCbBdD" );
kb.set_identity(
"" );
kb.set_inverses(
"AaCcBbDd" );
kb.add_rule(
"ABab" ,
"DCdc" );
REQUIRE(!kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 16);
REQUIRE(kb.equal_to(
"DCdc" ,
"ABab" ));
REQUIRE(kb.active_rules()
== std::vector<rule_type>({{
"Aa" ,
"" },
{
"Bb" ,
"" },
{
"Cc" ,
"" },
{
"Dd" ,
"" },
{
"aA" ,
"" },
{
"bB" ,
"" },
{
"cC" ,
"" },
{
"dD" ,
"" },
{
"BAba" ,
"CDcd" },
{
"BabC" ,
"aDCd" },
{
"DCdc" ,
"ABab" },
{
"DcdA" ,
"cBAb" },
{
"bCDc" ,
"AbaD" },
{
"baDC" ,
"abCD" },
{
"dABa" ,
"CdcB" },
{
"dcBA" ,
"cdAB" }}));
REQUIRE(kb.size() == POSITIVE_INFINITY);
REQUIRE(
std::distance(kb.cbegin_normal_forms(0, 7), kb.cend_normal_forms())
== 155577);
REQUIRE(
std::vector<std::string>(
{
"" ,
"a" ,
"A" ,
"c" ,
"C" ,
"b" ,
"B" ,
"d" ,
"D" ,
"aa" ,
"ac" ,
"aC" ,
"ab" ,
"aB" ,
"ad" ,
"aD" ,
"AA" ,
"Ac" ,
"AC" ,
"Ab" ,
"AB" ,
"Ad" ,
"AD" ,
"ca" ,
"cA" ,
"cc" ,
"cb" ,
"cB" ,
"cd" ,
"cD" ,
"Ca" ,
"CA" ,
"CC" ,
"Cb" ,
"CB" ,
"Cd" ,
"CD" ,
"ba" ,
"bA" ,
"bc" ,
"bC" ,
"bb" ,
"bd" ,
"bD" ,
"Ba" ,
"BA" ,
"Bc" ,
"BC" ,
"BB" ,
"Bd" ,
"BD" ,
"da" ,
"dA" ,
"dc" ,
"dC" ,
"db" ,
"dB" ,
"dd" ,
"Da" ,
"DA" ,
"Dc" ,
"DC" ,
"Db" ,
"DB" ,
"DD" })
== std::vector<std::string>(kb.cbegin_normal_forms(0, 3),
kb.cend_normal_forms()));
}
// 3-fold cover of A_6
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"024" ,
"(from kbmag/standalone/kb_data/3a6)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"abAB" );
kb.set_identity(
"" );
kb.set_inverses(
"ABab" );
kb.add_rule(
"aaa" ,
"" );
kb.add_rule(
"bbb" ,
"" );
kb.add_rule(
"abababab" ,
"" );
kb.add_rule(
"aBaBaBaBaB" ,
"" );
REQUIRE(!kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 183);
REQUIRE(kb.equal_to(
"aaa" ,
"" ));
REQUIRE(kb.equal_to(
"bbb" ,
"" ));
REQUIRE(kb.equal_to(
"BaBaBaBaB" ,
"aa" ));
REQUIRE(kb.equal_to(
"bababa" ,
"aabb" ));
REQUIRE(kb.equal_to(
"ababab" ,
"bbaa" ));
REQUIRE(kb.equal_to(
"aabbaa" ,
"babab" ));
REQUIRE(kb.equal_to(
"bbaabb" ,
"ababa" ));
REQUIRE(kb.equal_to(
"bababbabab" ,
"aabbabbaa" ));
REQUIRE(kb.equal_to(
"ababaababa" ,
"bbaabaabb" ));
REQUIRE(kb.equal_to(
"bababbabaababa" ,
"aabbabbaabaabb" ));
REQUIRE(kb.equal_to(
"bbaabaabbabbaa" ,
"ababaababbabab" ));
REQUIRE(kb.size() == 1080);
REQUIRE(std::distance(kb.cbegin_normal_forms(0, POSITIVE_INFINITY),
kb.cend_normal_forms())
== 1080);
REQUIRE(std::vector<std::string>({
"" ,
"a" ,
"b" ,
"A" ,
"B" ,
"ab" ,
"aB" ,
"ba" ,
"bA" ,
"Ab" ,
"AB" ,
"Ba" ,
"BA" })
== std::vector<std::string>(kb.cbegin_normal_forms(0, 3),
kb.cend_normal_forms()));
}
// Free group on 2 generators
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"025" ,
"(from kbmag/standalone/kb_data/f2)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"aAbB" );
kb.set_identity(
"" );
kb.set_inverses(
"AaBb" );
REQUIRE(kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 4);
REQUIRE(kb.size() == POSITIVE_INFINITY);
REQUIRE(std::vector<std::string>({
"" ,
"a" ,
"A" ,
"b" ,
"B" ,
"aa" ,
"ab" ,
"aB" ,
"AA" ,
"Ab" ,
"AB" ,
"ba" ,
"bA" ,
"bb" ,
"Ba" ,
"BA" ,
"BB" })
== std::vector<std::string>(kb.cbegin_normal_forms(0, 3),
kb.cend_normal_forms()));
REQUIRE(
std::distance(kb.cbegin_normal_forms(0, 5), kb.cend_normal_forms())
== 161);
}
// Symmetric group S_16
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"026" ,
"(from kbmag/standalone/kb_data/s16)" ,
"[quick][knuth-bendix][kbmag][shortlex][no-valgrind]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"abcdefghijklmno" );
kb.set_identity(
"" );
kb.set_inverses(
"abcdefghijklmno" );
kb.add_rule(
"bab" ,
"aba" );
kb.add_rule(
"ca" ,
"ac" );
kb.add_rule(
"da" ,
"ad" );
kb.add_rule(
"ea" ,
"ae" );
kb.add_rule(
"fa" ,
"af" );
kb.add_rule(
"ga" ,
"ag" );
kb.add_rule(
"ha" ,
"ah" );
kb.add_rule(
"ia" ,
"ai" );
kb.add_rule(
"ja" ,
"aj" );
kb.add_rule(
"ka" ,
"ak" );
kb.add_rule(
"la" ,
"al" );
kb.add_rule(
"ma" ,
"am" );
kb.add_rule(
"na" ,
"an" );
kb.add_rule(
"oa" ,
"ao" );
kb.add_rule(
"cbc" ,
"bcb" );
kb.add_rule(
"db" ,
"bd" );
kb.add_rule(
"eb" ,
"be" );
kb.add_rule(
"fb" ,
"bf" );
kb.add_rule(
"gb" ,
"bg" );
kb.add_rule(
"hb" ,
"bh" );
kb.add_rule(
"ib" ,
"bi" );
kb.add_rule(
"jb" ,
"bj" );
kb.add_rule(
"kb" ,
"bk" );
kb.add_rule(
"lb" ,
"bl" );
kb.add_rule(
"mb" ,
"bm" );
kb.add_rule(
"nb" ,
"bn" );
kb.add_rule(
"ob" ,
"bo" );
kb.add_rule(
"dcd" ,
"cdc" );
kb.add_rule(
"ec" ,
"ce" );
kb.add_rule(
"fc" ,
"cf" );
kb.add_rule(
"gc" ,
"cg" );
kb.add_rule(
"hc" ,
"ch" );
kb.add_rule(
"ic" ,
"ci" );
kb.add_rule(
"jc" ,
"cj" );
kb.add_rule(
"kc" ,
"ck" );
kb.add_rule(
"lc" ,
"cl" );
kb.add_rule(
"mc" ,
"cm" );
kb.add_rule(
"nc" ,
"cn" );
kb.add_rule(
"oc" ,
"co" );
kb.add_rule(
"ede" ,
"ded" );
kb.add_rule(
"fd" ,
"df" );
kb.add_rule(
"gd" ,
"dg" );
kb.add_rule(
"hd" ,
"dh" );
kb.add_rule(
"id" ,
"di" );
kb.add_rule(
"jd" ,
"dj" );
kb.add_rule(
"kd" ,
"dk" );
kb.add_rule(
"ld" ,
"dl" );
kb.add_rule(
"md" ,
"dm" );
kb.add_rule(
"nd" ,
"dn" );
kb.add_rule(
"od" ,
"do" );
kb.add_rule(
"fef" ,
"efe" );
kb.add_rule(
"ge" ,
"eg" );
kb.add_rule(
"he" ,
"eh" );
kb.add_rule(
"ie" ,
"ei" );
kb.add_rule(
"je" ,
"ej" );
kb.add_rule(
"ke" ,
"ek" );
kb.add_rule(
"le" ,
"el" );
kb.add_rule(
"me" ,
"em" );
kb.add_rule(
"ne" ,
"en" );
kb.add_rule(
"oe" ,
"eo" );
kb.add_rule(
"gfg" ,
"fgf" );
kb.add_rule(
"hf" ,
"fh" );
kb.add_rule(
"if" ,
"fi" );
kb.add_rule(
"jf" ,
"fj" );
kb.add_rule(
"kf" ,
"fk" );
kb.add_rule(
"lf" ,
"fl" );
kb.add_rule(
"mf" ,
"fm" );
kb.add_rule(
"nf" ,
"fn" );
kb.add_rule(
"of" ,
"fo" );
kb.add_rule(
"hgh" ,
"ghg" );
kb.add_rule(
"ig" ,
"gi" );
kb.add_rule(
"jg" ,
"gj" );
kb.add_rule(
"kg" ,
"gk" );
kb.add_rule(
"lg" ,
"gl" );
kb.add_rule(
"mg" ,
"gm" );
kb.add_rule(
"ng" ,
"gn" );
kb.add_rule(
"og" ,
"go" );
kb.add_rule(
"ihi" ,
"hih" );
kb.add_rule(
"jh" ,
"hj" );
kb.add_rule(
"kh" ,
"hk" );
kb.add_rule(
"lh" ,
"hl" );
kb.add_rule(
"mh" ,
"hm" );
kb.add_rule(
"nh" ,
"hn" );
kb.add_rule(
"oh" ,
"ho" );
kb.add_rule(
"jij" ,
"iji" );
kb.add_rule(
"ki" ,
"ik" );
kb.add_rule(
"li" ,
"il" );
kb.add_rule(
"mi" ,
"im" );
kb.add_rule(
"ni" ,
"in" );
kb.add_rule(
"oi" ,
"io" );
kb.add_rule(
"kjk" ,
"jkj" );
kb.add_rule(
"lj" ,
"jl" );
kb.add_rule(
"mj" ,
"jm" );
kb.add_rule(
"nj" ,
"jn" );
kb.add_rule(
"oj" ,
"jo" );
kb.add_rule(
"lkl" ,
"klk" );
kb.add_rule(
"mk" ,
"km" );
kb.add_rule(
"nk" ,
"kn" );
kb.add_rule(
"ok" ,
"ko" );
kb.add_rule(
"mlm" ,
"lml" );
kb.add_rule(
"nl" ,
"ln" );
kb.add_rule(
"ol" ,
"lo" );
kb.add_rule(
"nmn" ,
"mnm" );
kb.add_rule(
"om" ,
"mo" );
kb.add_rule(
"ono" ,
"non" );
REQUIRE(!kb.confluent());
// kb.knuth_bendix_by_overlap_length();
kb.run();
// faster
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 211);
// verified with KBMAG
REQUIRE(kb.gilman_digraph().number_of_nodes() == 121);
REQUIRE(kb.gilman_digraph().number_of_edges() == 680);
// verified with KBMAG
REQUIRE(
std::distance(kb.cbegin_normal_forms(0, 7), kb.cend_normal_forms())
== 49436);
REQUIRE(kb.number_of_normal_forms(0, 7) == 49436);
// verified with KBMAG
REQUIRE(kb.number_of_normal_forms(0, 11) == 2554607);
REQUIRE(kb.size() == 20922789888000);
}
// Presentation of group A_4 regarded as monoid presentation - gives
// infinite monoid.
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"027" ,
"(from kbmag/standalone/kb_data/a4monoid)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"abB" );
kb.add_rule(
"bb" ,
"B" );
kb.add_rule(
"BaB" ,
"aba" );
REQUIRE(!kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 6);
REQUIRE(kb.equal_to(
"bb" ,
"B" ));
REQUIRE(kb.equal_to(
"BaB" ,
"aba" ));
REQUIRE(kb.equal_to(
"Bb" ,
"bB" ));
REQUIRE(kb.equal_to(
"Baaba" ,
"abaaB" ));
REQUIRE(kb.equal_to(
"BabB" ,
"abab" ));
REQUIRE(kb.equal_to(
"Bababa" ,
"ababaB" ));
REQUIRE(kb.active_rules()
== std::vector<rule_type>({{{
"Bb" ,
"bB" },
{
"bb" ,
"B" },
{
"BaB" ,
"aba" },
{
"BabB" ,
"abab" },
{
"Baaba" ,
"abaaB" },
{
"Bababa" ,
"ababaB" }}}));
}
// fairly clearly the trivial group
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"028" ,
"(from kbmag/standalone/kb_data/degen3)" ,
"[quick][knuth-bendix][kbmag][shortlex][no-valgrind]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"aAbB" );
kb.add_rule(
"ab" ,
"" );
kb.add_rule(
"abb" ,
"" );
REQUIRE(kb.active_rules()
== std::vector<rule_type>({{
"a" ,
"" }, {
"b" ,
"" }}));
REQUIRE(kb.number_of_active_rules() == 2);
REQUIRE(kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 2);
REQUIRE(kb.equal_to(
"b" ,
"" ));
REQUIRE(kb.equal_to(
"a" ,
"" ));
REQUIRE(kb.active_rules()
== std::vector<rule_type>({{
"a" ,
"" }, {
"b" ,
"" }}));
}
// infinite cyclic group
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"029" ,
"(from kbmag/standalone/kb_data/ab1)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"aA" );
kb.set_identity(
"" );
kb.set_inverses(
"Aa" );
REQUIRE(kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 2);
REQUIRE(kb.size() == POSITIVE_INFINITY);
}
// A generator, but trivial.
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"030" ,
"(from kbmag/standalone/kb_data/degen2)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"aA" );
kb.add_rule(
"a" ,
"" );
REQUIRE(kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 1);
REQUIRE(kb.equal_to(
"a" ,
"" ));
REQUIRE(kb.active_rules() == std::vector<rule_type>({{
"a" ,
"" }}));
}
// Fibonacci group F(2,5)
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"031" ,
"(from kbmag/standalone/kb_data/f25)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"aAbBcCdDyY" );
kb.add_rule(
"ab" ,
"c" );
kb.add_rule(
"bc" ,
"d" );
kb.add_rule(
"cd" ,
"y" );
kb.add_rule(
"dy" ,
"a" );
kb.add_rule(
"ya" ,
"b" );
REQUIRE(!kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 24);
REQUIRE(kb.equal_to(
"ab" ,
"c" ));
REQUIRE(kb.equal_to(
"bc" ,
"d" ));
REQUIRE(kb.equal_to(
"cd" ,
"y" ));
REQUIRE(kb.equal_to(
"dy" ,
"a" ));
REQUIRE(kb.equal_to(
"ya" ,
"b" ));
REQUIRE(kb.equal_to(
"cc" ,
"ad" ));
REQUIRE(kb.equal_to(
"dd" ,
"by" ));
REQUIRE(kb.equal_to(
"yy" ,
"ac" ));
REQUIRE(kb.equal_to(
"yc" ,
"bb" ));
REQUIRE(kb.equal_to(
"db" ,
"aa" ));
REQUIRE(kb.equal_to(
"aac" ,
"by" ));
REQUIRE(kb.equal_to(
"bd" ,
"aa" ));
REQUIRE(kb.equal_to(
"bby" ,
"aad" ));
REQUIRE(kb.equal_to(
"aaa" ,
"y" ));
REQUIRE(kb.equal_to(
"yb" ,
"by" ));
REQUIRE(kb.equal_to(
"ba" ,
"c" ));
REQUIRE(kb.equal_to(
"da" ,
"ad" ));
REQUIRE(kb.equal_to(
"ca" ,
"ac" ));
REQUIRE(kb.equal_to(
"cy" ,
"bb" ));
REQUIRE(kb.equal_to(
"cb" ,
"d" ));
REQUIRE(kb.equal_to(
"yd" ,
"a" ));
REQUIRE(kb.equal_to(
"dc" ,
"y" ));
REQUIRE(kb.equal_to(
"ay" ,
"b" ));
REQUIRE(kb.equal_to(
"bbb" ,
"a" ));
REQUIRE(
kb.active_rules()
== std::vector<rule_type>(
{{
"ab" ,
"c" }, {
"ay" ,
"b" }, {
"ba" ,
"c" }, {
"bc" ,
"d" },
{
"bd" ,
"aa" }, {
"ca" ,
"ac" }, {
"cb" ,
"d" }, {
"cc" ,
"ad" },
{
"cd" ,
"y" }, {
"cy" ,
"bb" }, {
"da" ,
"ad" }, {
"db" ,
"aa" },
{
"dc" ,
"y" }, {
"dd" ,
"by" }, {
"dy" ,
"a" }, {
"ya" ,
"b" },
{
"yb" ,
"by" }, {
"yc" ,
"bb" }, {
"yd" ,
"a" }, {
"yy" ,
"ca" },
{
"aaa" ,
"y" }, {
"aac" ,
"by" }, {
"bbb" ,
"yd" }, {
"bby" ,
"aad" }}));
}
// Von Dyck (2,3,7) group - infinite hyperbolic - small tidyint works better
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"032" ,
"(from kbmag/standalone/kb_data/237)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"aAbBc" );
kb.set_identity(
"" );
kb.set_inverses(
"AaBbc" );
kb.add_rule(
"aaaa" ,
"AAA" );
kb.add_rule(
"bb" ,
"B" );
kb.add_rule(
"BA" ,
"c" );
REQUIRE(!kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 32);
REQUIRE(kb.active_rules()
== std::vector<rule_type>({{
"Aa" ,
"" },
{
"Ac" ,
"b" },
{
"BA" ,
"c" },
{
"BB" ,
"b" },
{
"Bb" ,
"" },
{
"Bc" ,
"bA" },
{
"aA" ,
"" },
{
"ab" ,
"c" },
{
"bB" ,
"" },
{
"ba" ,
"AB" },
{
"bb" ,
"B" },
{
"bc" ,
"A" },
{
"cB" ,
"a" },
{
"ca" ,
"B" },
{
"cb" ,
"aB" },
{
"cc" ,
"" },
{
"BaB" ,
"bAb" },
{
"bAB" ,
"Ba" },
{
"cAB" ,
"aBa" },
{
"AAAA" ,
"aaa" },
{
"AAAb" ,
"aaac" },
{
"aaaa" ,
"AAA" },
{
"bAbA" ,
"Bac" },
{
"cAAA" ,
"Baaa" },
{
"cAbA" ,
"aBac" },
{
"ABaaa" ,
"bAAA" },
{
"Baaac" ,
"cAAb" },
{
"bAABaac" ,
"BacAAb" },
{
"cAABaac" ,
"aBacAAb" },
{
"BaaaBaaa" ,
"cAAbAAA" },
{
"bAABaaBaaa" ,
"BacAAbAAA" },
{
"cAABaaBaaa" ,
"aBacAAbAAA" }}));
REQUIRE(kb.size() == POSITIVE_INFINITY);
}
// Cyclic group of order 2.
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"033" ,
"(from kbmag/standalone/kb_data/c2)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"a" );
kb.add_rule(
"aa" ,
"" );
REQUIRE(kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 1);
REQUIRE(kb.active_rules() == std::vector<rule_type>({{
"aa" ,
"" }}));
}
// The group is S_4, and the subgroup H of order 4. There are 30 reduced
// words - 24 for the group elements, and 6 for the 6 cosets Hg.
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"034" ,
"(from kbmag/standalone/kb_data/cosets)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"HaAbB" );
kb.add_rule(
"aaa" ,
"" );
kb.add_rule(
"bbbb" ,
"" );
kb.add_rule(
"abab" ,
"" );
kb.add_rule(
"Hb" ,
"H" );
kb.add_rule(
"HH" ,
"H" );
kb.add_rule(
"aH" ,
"H" );
kb.add_rule(
"bH" ,
"H" );
REQUIRE(!kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 14);
REQUIRE(kb.equal_to(
"aaa" ,
"" ));
REQUIRE(kb.equal_to(
"Hb" ,
"H" ));
REQUIRE(kb.equal_to(
"HH" ,
"H" ));
REQUIRE(kb.equal_to(
"aH" ,
"H" ));
REQUIRE(kb.equal_to(
"bH" ,
"H" ));
REQUIRE(kb.equal_to(
"bab" ,
"aa" ));
REQUIRE(kb.equal_to(
"bbb" ,
"aba" ));
REQUIRE(kb.equal_to(
"Hab" ,
"Haa" ));
REQUIRE(kb.equal_to(
"abaab" ,
"bbaa" ));
REQUIRE(kb.equal_to(
"baaba" ,
"aabb" ));
REQUIRE(kb.equal_to(
"Haabb" ,
"Haaba" ));
REQUIRE(kb.equal_to(
"bbaabb" ,
"abba" ));
REQUIRE(kb.equal_to(
"aabbaa" ,
"baab" ));
REQUIRE(kb.equal_to(
"baabba" ,
"abbaab" ));
REQUIRE(kb.active_rules()
== std::vector<rule_type>({{{
"HH" ,
"H" },
{
"Hb" ,
"H" },
{
"aH" ,
"H" },
{
"bH" ,
"H" },
{
"Hab" ,
"Haa" },
{
"aaa" ,
"" },
{
"bab" ,
"aa" },
{
"bbb" ,
"aba" },
{
"Haabb" ,
"Haaba" },
{
"abaab" ,
"bbaa" },
{
"baaba" ,
"aabb" },
{
"aabbaa" ,
"baab" },
{
"baabba" ,
"abbaab" },
{
"bbaabb" ,
"abba" }}}));
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"035" ,
"Example 5.1 in Sims (KnuthBendix 09 again)" ,
"[quick][knuth-bendix][fpsemigroup]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"aAbB" );
kb.add_rule(
"aA" ,
"" );
kb.add_rule(
"Aa" ,
"" );
kb.add_rule(
"bB" ,
"" );
kb.add_rule(
"Bb" ,
"" );
kb.add_rule(
"ba" ,
"ab" );
REQUIRE(!kb.confluent());
kb.run();
REQUIRE(kb.number_of_active_rules() == 8);
REQUIRE(kb.confluent());
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"036" ,
"(from kbmag/standalone/kb_data/nilp2)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"cCbBaA" );
kb.set_identity(
"" );
kb.set_inverses(
"CcBbAa" );
kb.add_rule(
"ba" ,
"abc" );
kb.add_rule(
"ca" ,
"ac" );
kb.add_rule(
"cb" ,
"bc" );
REQUIRE(!kb.confluent());
// The following never terminates (requires recursive order?)
// kb.knuth_bendix_by_overlap_length();
// REQUIRE(kb.confluent());
// REQUIRE(kb.number_of_active_rules() == 32758);
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"037" ,
"Example 6.4 in Sims" ,
"[quick][knuth-bendix][fpsemigroup][no-valgrind]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"abc" );
kb.add_rule(
"aa" ,
"" );
kb.add_rule(
"bc" ,
"" );
kb.add_rule(
"bbb" ,
"" );
kb.add_rule(
"ababababababab" ,
"" );
kb.add_rule(
"abacabacabacabac" ,
"" );
REQUIRE(kb.number_of_active_rules() == 5);
REQUIRE(!kb.confluent());
kb.max_rules(10);
kb.run();
REQUIRE(kb.number_of_active_rules() == 10);
REQUIRE(!kb.confluent());
kb.run();
REQUIRE(kb.number_of_active_rules() == 10);
REQUIRE(!kb.confluent());
kb.max_rules(20);
kb.run();
REQUIRE(kb.number_of_active_rules() == 21);
REQUIRE(!kb.confluent());
kb.max_rules(LIMIT_MAX);
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 40);
}
// Von Dyck (2,3,7) group - infinite hyperbolic
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"038" ,
"KnuthBendix 071 again" ,
"[no-valgrind][quick][knuth-bendix][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"aAbBc" );
kb.set_identity(
"" );
kb.set_inverses(
"AaBbc" );
kb.add_rule(
"BA" ,
"c" );
kb.add_rule(
"Bb" ,
"bB" );
kb.add_rule(
"bb" ,
"B" );
kb.add_rule(
"AAAa" ,
"aAAA" );
kb.add_rule(
"aaaa" ,
"AAA" );
kb.add_rule(
"BaAAA" ,
"cAAa" );
kb.add_rule(
"BaaAAA" ,
"cAAaa" );
kb.add_rule(
"BaAaAAA" ,
"cAAaAa" );
kb.add_rule(
"BaaaAAA" ,
"cAAaaa" );
kb.add_rule(
"BaAAaAAA" ,
"cAAaAAa" );
kb.add_rule(
"BaAaaAAA" ,
"cAAaAaa" );
kb.add_rule(
"BaaAaAAA" ,
"cAAaaAa" );
kb.add_rule(
"BaAAaaAAA" ,
"cAAaAAaa" );
kb.add_rule(
"BaAaAaAAA" ,
"cAAaAaAa" );
kb.add_rule(
"BaAaaaAAA" ,
"cAAaAaaa" );
kb.add_rule(
"BaaAAaAAA" ,
"cAAaaAAa" );
kb.add_rule(
"BaaAaaAAA" ,
"cAAaaAaa" );
kb.add_rule(
"BaAAaAaAAA" ,
"cAAaAAaAa" );
kb.add_rule(
"BaAAaaaAAA" ,
"cAAaAAaaa" );
kb.add_rule(
"BaAaAAaAAA" ,
"cAAaAaAAa" );
kb.add_rule(
"BaAaAaaAAA" ,
"cAAaAaAaa" );
kb.add_rule(
"BaAaaAaAAA" ,
"cAAaAaaAa" );
kb.add_rule(
"BaaAAaaAAA" ,
"cAAaaAAaa" );
kb.add_rule(
"BaaAaAaAAA" ,
"cAAaaAaAa" );
kb.add_rule(
"BaAAaAAaAAA" ,
"cAAaAAaAAa" );
kb.add_rule(
"BaAAaAaaAAA" ,
"cAAaAAaAaa" );
kb.add_rule(
"BaAAaaAaAAA" ,
"cAAaAAaaAa" );
kb.add_rule(
"BaAaAAaaAAA" ,
"cAAaAaAAaa" );
kb.add_rule(
"BaAaAaAaAAA" ,
"cAAaAaAaAa" );
kb.add_rule(
"BaAaaAAaAAA" ,
"cAAaAaaAAa" );
kb.add_rule(
"BaaAAaAaAAA" ,
"cAAaaAAaAa" );
kb.add_rule(
"BaaAaAAaAAA" ,
"cAAaaAaAAa" );
kb.add_rule(
"BaAAaAAaaAAA" ,
"cAAaAAaAAaa" );
kb.add_rule(
"BaAAaAaAaAAA" ,
"cAAaAAaAaAa" );
kb.add_rule(
"BaAAaaAAaAAA" ,
"cAAaAAaaAAa" );
kb.add_rule(
"BaAaAAaAaAAA" ,
"cAAaAaAAaAa" );
kb.add_rule(
"BaAaAaAAaAAA" ,
"cAAaAaAaAAa" );
kb.add_rule(
"BaaAAaAAaAAA" ,
"cAAaaAAaAAa" );
kb.add_rule(
"BaAAaAAaAaAAA" ,
"cAAaAAaAAaAa" );
kb.add_rule(
"BaAAaAaAAaAAA" ,
"cAAaAAaAaAAa" );
kb.add_rule(
"BaAaAAaAAaAAA" ,
"cAAaAaAAaAAa" );
kb.add_rule(
"BaAAaAAaAAaAAA" ,
"cAAaAAaAAaAAa" );
REQUIRE(kb.number_of_active_rules() == 9);
REQUIRE(!kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 32);
REQUIRE(kb.size() == POSITIVE_INFINITY);
REQUIRE(kb.number_of_normal_forms(4, 5) == 24);
REQUIRE(std::vector<std::string>(kb.cbegin_normal_forms(4, 5),
kb.cend_normal_forms())
== std::vector<std::string>(
{
"aaaB" ,
"aaac" ,
"aaBa" ,
"aacA" ,
"aBaa" ,
"aBac" ,
"acAA" ,
"acAb" ,
"AAAB" ,
"AAbA" ,
"AABa" ,
"AbAA" ,
"AbAb" ,
"ABaa" ,
"ABac" ,
"bAAA" ,
"bAAb" ,
"bAAB" ,
"Baaa" ,
"BaaB" ,
"Baac" ,
"BacA" ,
"cAAb" ,
"cAAB" }));
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"039" ,
"Example 5.4 in Sims (KnuthBendix 11 again) "
"(different overlap policy)" ,
"[quick][knuth-bendix][fpsemigroup]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"Bab" );
kb.add_rule(
"aa" ,
"" );
kb.add_rule(
"bB" ,
"" );
kb.add_rule(
"bbb" ,
"" );
kb.add_rule(
"ababab" ,
"" );
kb.overlap_policy(KnuthBendix::options::overlap::AB_BC);
REQUIRE(!kb.confluent());
kb.knuth_bendix_by_overlap_length();
REQUIRE(kb.number_of_active_rules() == 11);
REQUIRE(kb.confluent());
REQUIRE(kb.size() == 12);
REQUIRE(kb.number_of_normal_forms(4, 5) == 0);
REQUIRE(
std::vector<std::string>(kb.cbegin_normal_forms(0, POSITIVE_INFINITY),
kb.cend_normal_forms())
== std::vector<std::string>({
"" ,
"B" ,
"a" ,
"b" ,
"Ba" ,
"aB" ,
"ab" ,
"ba" ,
"BaB" ,
"Bab" ,
"aBa" ,
"baB" }));
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"040" ,
"Example 5.4 in Sims (KnuthBendix 11 again) "
"(different overlap policy)" ,
"[quick][knuth-bendix][fpsemigroup]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"Bab" );
kb.add_rule(
"aa" ,
"" );
kb.add_rule(
"bB" ,
"" );
kb.add_rule(
"bbb" ,
"" );
kb.add_rule(
"ababab" ,
"" );
kb.overlap_policy(KnuthBendix::options::overlap::MAX_AB_BC);
// The next line tests that we don't delete the old OverlapMeasure.
kb.overlap_policy(KnuthBendix::options::overlap::MAX_AB_BC);
REQUIRE(!kb.confluent());
kb.knuth_bendix_by_overlap_length();
REQUIRE(kb.number_of_active_rules() == 11);
REQUIRE(kb.confluent());
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"041" ,
"operator<<" ,
"[quick][knuth-bendix]" ) {
std::ostringstream os;
KnuthBendix kb1;
kb1.set_alphabet(
"Bab" );
kb1.add_rule(
"aa" ,
"" );
kb1.add_rule(
"bB" ,
"" );
kb1.add_rule(
"bbb" ,
"" );
kb1.add_rule(
"ababab" ,
"" );
os << kb1;
// Does not do anything visible
KnuthBendix kb2;
kb2.set_alphabet(
"cbaB" );
kb2.add_rule(
"aa" ,
"" );
kb2.add_rule(
"bB" ,
"" );
kb2.add_rule(
"bbb" ,
"" );
kb2.add_rule(
"ababab" ,
"" );
os << kb2;
// Does not do anything visible
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"042" ,
"confluence_interval" ,
"[quick][knuth-bendix]" ) {
KnuthBendix kb;
kb.set_alphabet(
"Bab" );
kb.add_rule(
"aa" ,
"" );
kb.add_rule(
"bB" ,
"" );
kb.add_rule(
"bbb" ,
"" );
kb.add_rule(
"ababab" ,
"" );
kb.check_confluence_interval(LIMIT_MAX);
kb.check_confluence_interval(10);
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"043" ,
"max_overlap" ,
"[quick][knuth-bendix]" ) {
KnuthBendix kb;
kb.set_alphabet(
"Bab" );
kb.add_rule(
"aa" ,
"" );
kb.add_rule(
"bB" ,
"" );
kb.add_rule(
"bbb" ,
"" );
kb.add_rule(
"ababab" ,
"" );
kb.max_overlap(10);
kb.max_overlap(-11);
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"044" ,
"(fpsemi) (from kbmag/standalone/kb_data/d22) (2 / 3) (finite)" ,
"[quick][knuth-bendix][fpsemigroup][fpsemi][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"ABCDYFabcdyf" );
kb.set_identity(
"" );
kb.set_inverses(
"abcdyfABCDYF" );
kb.add_rule(
"aCAd" ,
"" );
kb.add_rule(
"bfBY" ,
"" );
kb.add_rule(
"cyCD" ,
"" );
kb.add_rule(
"dFDa" ,
"" );
kb.add_rule(
"ybYA" ,
"" );
kb.add_rule(
"fCFB" ,
"" );
REQUIRE(!kb.confluent());
kb.knuth_bendix_by_overlap_length();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_rules() == 18);
REQUIRE(kb.size() == 22);
REQUIRE(
std::vector<std::string>(kb.cbegin_normal_forms(0, POSITIVE_INFINITY),
kb.cend_normal_forms())
== std::vector<std::string>({
"" ,
"A" ,
"B" ,
"C" ,
"D" ,
"Y" ,
"F" ,
"AB" ,
"AC" ,
"AD" ,
"AY" ,
"AF" ,
"BA" ,
"BD" ,
"BY" ,
"CY" ,
"DB" ,
"ABA" ,
"ABD" ,
"ABY" ,
"ACY" ,
"ADB" }));
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"045" ,
"(fpsemi) (from kbmag/standalone/kb_data/d22) (3 / 3) (finite)" ,
"[quick][knuth-bendix][fpsemigroup][fpsemi][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"aAbBcCdDyYfF" );
kb.set_identity(
"" );
kb.set_inverses(
"AaBbCcDdYyFf" );
kb.add_rule(
"aCAd" ,
"" );
kb.add_rule(
"bfBY" ,
"" );
kb.add_rule(
"cyCD" ,
"" );
kb.add_rule(
"dFDa" ,
"" );
kb.add_rule(
"ybYA" ,
"" );
kb.add_rule(
"fCFB" ,
"" );
REQUIRE(!kb.confluent());
kb.knuth_bendix_by_overlap_length();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_rules() == 18);
REQUIRE(kb.size() == 22);
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"046" ,
"(fpsemi) small example" ,
"[quick][knuth-bendix][fpsemigroup][fpsemi][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"ab" );
kb.add_rule(
"aaa" ,
"a" );
kb.add_rule(
"bbbb" ,
"b" );
kb.add_rule(
"ababababab" ,
"aa" );
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.size() == 243);
REQUIRE(std::vector<std::string>(kb.cbegin_normal_forms(0, 3),
kb.cend_normal_forms())
== std::vector<std::string>({
"a" ,
"b" ,
"aa" ,
"ab" ,
"ba" ,
"bb" }));
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"047" ,
"code coverage" ,
"[quick]" ) {
KnuthBendix kb1;
KnuthBendix kb2(kb1);
REQUIRE(kb1.size() == 0);
kb1.set_alphabet(
"ab" );
kb1.add_rule(
"aaa" ,
"a" );
KnuthBendix kb3(kb1);
REQUIRE(kb3.number_of_rules() == 1);
REQUIRE_THROWS_AS(kb3.set_identity(
"ab" ), LibsemigroupsException);
REQUIRE_NOTHROW(kb3.set_identity(
"a" ));
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"048" ,
"small overlap 1" ,
"[quick]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"BCA" );
kb.add_rule(
"AABC" ,
"ACBA" );
REQUIRE(kb.confluent());
REQUIRE(kb.normal_form(
"CBACBAABCAABCACBACBA" ) ==
"CBACBACBAACBAACBACBA" );
REQUIRE(kb.equal_to(
"CBAABCABCAABCAABCABC" ,
"CBACBAABCAABCACBACBA" ));
REQUIRE(kb.equal_to(
"CBAABCABCAABCAABCABC" ,
"CBACBAABCAABCACBACBA" ));
REQUIRE(kb.equal_to(
"AABCAABCCACAACBBCBCCACBBAABCBA" ,
"ACBAACBACACAACBBCBCCACBBACBABA" ));
REQUIRE(kb.equal_to(
"CACCBABACCBABACCAAAABCAABCBCAA" ,
"CACCBABACCBABACCAAACBAACBABCAA" ));
REQUIRE(kb.equal_to(
"CAAACAABCCBABCCBCCBCACABACBBAC" ,
"CAAACACBACBABCCBCCBCACABACBBAC" ));
REQUIRE(kb.equal_to(
"BABCACBACBCCCCCAACCAAABAABCBCC" ,
"BABCACBACBCCCCCAACCAAABACBABCC" ));
REQUIRE(kb.size() == POSITIVE_INFINITY);
// REQUIRE(std::vector<std::string>(cbegin_silo("BCA", 5, 6),
// cend_silo("BCA", 5, 6))
// == std::vector<std::string>());
// REQUIRE(number_of_words(3, 20, 21) == size_t(18446744071562067968ULL));
// auto lex_normal_form = [&kb](std::string const& w) {
// auto ww = kb.normal_form(w);
// auto it = std::find_if(cbegin_silo("BCA", ww, 4 * w.size()),
// cend_silo("BCA", ww.size(), 4 * w.size()),
// [&kb, &ww](std::string const& u) {
// return kb.normal_form(u) == ww;
// });
// return *it;
// };
// kb.run();
// REQUIRE(kb.finished());
// REQUIRE(lex_normal_form("BBBBB") == "BBBBB");
// REQUIRE(kb.normal_form("AABCB") == "ACBAB");
// REQUIRE(lex_normal_form("AABCB") == "");
// std::vector<std::string> result(number_of_words(3, 5, 20));
// std::transform(cbegin_
// TODO(later) The following code spends the majority of its time in
// FpSemigroupInterface::validate_letter
// auto it =
// REQUIRE(it != cend_silo("BCA", 0, 80));
// REQUIRE(*it == "CBACBAABCAABCACBACBA");
}
// Symmetric group S_9
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"049" ,
"(from kbmag/standalone/kb_data/s9)" ,
"[quick][knuth-bendix][kbmag][shortlex]" ) {
auto rg = ReportGuard(REPORT);
KnuthBendix kb;
kb.set_alphabet(
"abcdefgh" );
kb.set_identity(
"" );
kb.set_inverses(
"abcdefgh" );
kb.add_rule(
"bab" ,
"aba" );
kb.add_rule(
"ca" ,
"ac" );
kb.add_rule(
"da" ,
"ad" );
kb.add_rule(
"ea" ,
"ae" );
kb.add_rule(
"fa" ,
"af" );
kb.add_rule(
"ga" ,
"ag" );
kb.add_rule(
"ha" ,
"ah" );
kb.add_rule(
"cbc" ,
"bcb" );
kb.add_rule(
"db" ,
"bd" );
kb.add_rule(
"eb" ,
"be" );
kb.add_rule(
"fb" ,
"bf" );
kb.add_rule(
"gb" ,
"bg" );
kb.add_rule(
"hb" ,
"bh" );
kb.add_rule(
"dcd" ,
"cdc" );
kb.add_rule(
"ec" ,
"ce" );
kb.add_rule(
"fc" ,
"cf" );
kb.add_rule(
"gc" ,
"cg" );
kb.add_rule(
"hc" ,
"ch" );
kb.add_rule(
"ede" ,
"ded" );
kb.add_rule(
"fd" ,
"df" );
kb.add_rule(
"gd" ,
"dg" );
kb.add_rule(
"hd" ,
"dh" );
kb.add_rule(
"fef" ,
"efe" );
kb.add_rule(
"ge" ,
"eg" );
kb.add_rule(
"he" ,
"eh" );
kb.add_rule(
"gfg" ,
"fgf" );
kb.add_rule(
"hf" ,
"fh" );
kb.add_rule(
"hgh" ,
"ghg" );
REQUIRE(!kb.confluent());
kb.run();
REQUIRE(kb.confluent());
REQUIRE(kb.number_of_active_rules() == 57);
REQUIRE(kb.size() == 362880);
}
LIBSEMIGROUPS_TEST_CASE(
"KnuthBendix" ,
"019" ,
"(fpsemi) C(4) monoid" ,
"[quick][knuthbendix][fpsemigroup][fpsemi]" ) {
KnuthBendix k;
k.set_alphabet(
"abcde" );
k.add_rule(
"bceac" ,
"aeebbc" );
k.add_rule(
"aeebbc" ,
"dabcd" );
k.run();
REQUIRE(k.confluent());
}
}
// namespace fpsemigroup
}
// namespace libsemigroups
Messung V0.5 C=88 H=95 G=91
¤ Dauer der Verarbeitung: 0.19 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland