// libsemigroups - C++ library for semigroups and monoids
// Copyright (C) 2020 Finn Smith
//
// 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 <cstddef>
// for size_t
#include "catch.hpp" // for REQUIRE
#include "test-main.hpp" // FOR LIBSEMIGROUPS_TEST_CASE
#include "libsemigroups/bmat8.hpp" // for BMat8
#include "libsemigroups/fastest-bmat.hpp" // for FastestBMat
#include "libsemigroups/froidure-pin.hpp" // for FroidurePin
#include "libsemigroups/konieczny.hpp" // for Konieczny
namespace libsemigroups {
constexpr
bool REPORT =
false ;
LIBSEMIGROUPS_TEST_CASE(
"Konieczny" ,
"009" ,
"regular elements and idempotents" ,
"[quick][no-valgrind][bmat8]" ) {
#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored
"-Wpedantic"
#pragma GCC diagnostic ignored
"-Winline"
#endif
using BMat = FastestBMat<
4 >;
auto rg = ReportGuard(REPORT);
const std::vector<BMat> gens
= {BMat({{
0 ,
1 ,
0 ,
0 }, {
1 ,
0 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }}),
BMat({{
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }, {
1 ,
0 ,
0 ,
0 }}),
BMat({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
1 ,
0 ,
0 ,
1 }}),
BMat({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
0 }})};
Konieczny<BMat> KS(gens);
FroidurePin<BMat> S(gens);
S.run();
REQUIRE(KS.size() ==
63904 );
REQUIRE(S.size() ==
63904 );
REQUIRE(KS.number_of_generators() ==
4 );
REQUIRE(KS.number_of_D_classes() ==
50 );
REQUIRE(KS.number_of_L_classes() ==
1256 );
REQUIRE(KS.number_of_R_classes() ==
1256 );
REQUIRE(KS.number_of_regular_D_classes() ==
25 );
REQUIRE(KS.number_of_regular_L_classes() ==
618 );
REQUIRE(KS.number_of_regular_R_classes() ==
618 );
REQUIRE(KS.number_of_idempotents() ==
2360 );
REQUIRE(KS.number_of_H_classes() ==
48092 );
REQUIRE(std::vector<BMat>(KS.cbegin_generators(), KS.cend_generators())
== gens);
size_t count =
0 ;
for (
auto it = S.cbegin(); it < S.cend(); ++it) {
if (KS.is_regular_element(*it)) {
count++;
}
}
REQUIRE(count ==
40408 );
REQUIRE(KS.number_of_regular_elements() ==
40408 );
#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
#pragma GCC diagnostic pop
#endif
}
LIBSEMIGROUPS_TEST_CASE(
"Konieczny" ,
"010" ,
"regular D-class 01" ,
"[quick][bmat8]" ) {
auto rg = ReportGuard(REPORT);
const std::vector<BMat8> gens = {BMat8({{
0 ,
1 ,
0 }, {
0 ,
0 ,
1 }, {
1 ,
0 ,
0 }}),
BMat8({{
0 ,
1 ,
0 }, {
1 ,
0 ,
0 }, {
0 ,
0 ,
1 }}),
BMat8({{
1 ,
0 ,
0 }, {
1 ,
1 ,
0 }, {
0 ,
0 ,
1 }}),
BMat8({{
1 ,
1 ,
0 }, {
0 ,
1 ,
1 }, {
1 ,
0 ,
1 }})};
Konieczny<BMat8> KS(gens);
REQUIRE(KS.size() ==
247 );
BMat8 x({{
1 ,
0 ,
0 }, {
1 ,
1 ,
0 }, {
1 ,
0 ,
1 }});
Konieczny<BMat8>::DClass& D = KS.D_class_of_element(x);
REQUIRE(D.number_of_L_classes() ==
3 );
REQUIRE(D.number_of_R_classes() ==
3 );
REQUIRE(D.size() ==
18 );
REQUIRE(D.is_regular_D_class());
}
LIBSEMIGROUPS_TEST_CASE(
"Konieczny" ,
"011" ,
"regular D-class 02" ,
"[quick][bmat8]" ) {
auto rg = ReportGuard(REPORT);
const std::vector<BMat8> gens
= {BMat8({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }}),
BMat8({{
0 ,
1 ,
0 ,
0 }, {
1 ,
0 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }}),
BMat8({{
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }, {
1 ,
0 ,
0 ,
0 }}),
BMat8({{
0 ,
1 ,
0 ,
1 }, {
1 ,
0 ,
1 ,
0 }, {
1 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
1 ,
1 }}),
BMat8({{
0 ,
1 ,
0 ,
1 }, {
1 ,
0 ,
1 ,
0 }, {
1 ,
0 ,
1 ,
0 }, {
0 ,
1 ,
0 ,
1 }}),
BMat8({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
0 }})};
Konieczny<BMat8> KS(gens);
KS.run();
BMat8 idem(BMat8({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }}));
Konieczny<BMat8>::DClass& D = KS.D_class_of_element(idem);
REQUIRE(D.size() ==
24 );
REQUIRE(D.is_regular_D_class());
}
LIBSEMIGROUPS_TEST_CASE(
"Konieczny" ,
"012" ,
"regular D-class 04: contains" ,
"[quick][no-valgrind][bmat8]" ) {
auto rg = ReportGuard(REPORT);
const std::vector<BMat8> gens
= {BMat8({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }}),
BMat8({{
0 ,
1 ,
0 ,
0 }, {
1 ,
0 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }}),
BMat8({{
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }, {
1 ,
0 ,
0 ,
0 }}),
BMat8({{
0 ,
1 ,
0 ,
1 }, {
1 ,
0 ,
1 ,
0 }, {
1 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
1 ,
1 }}),
BMat8({{
0 ,
1 ,
0 ,
1 }, {
1 ,
0 ,
1 ,
0 }, {
1 ,
0 ,
1 ,
0 }, {
0 ,
1 ,
0 ,
1 }}),
BMat8({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
0 }})};
Konieczny<BMat8> KS(gens);
FroidurePin<BMat8> S(gens);
KS.run();
S.run();
BMat8 idem(BMat8({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }}));
Konieczny<BMat8>::DClass& D = KS.D_class_of_element(idem);
// test that the top D-class contains only permutation matrices
for (
auto it = S.cbegin(); it < S.cend(); it++) {
REQUIRE(D.contains(*it) == (((*it) * (*it).transpose()) == gens[
0 ]));
}
}
LIBSEMIGROUPS_TEST_CASE(
"Konieczny" ,
"013" ,
"non-regular D-classes 01" ,
"[quick][bmat8]" ) {
auto rg = ReportGuard(REPORT);
const std::vector<BMat8> gens = {BMat8({{
0 ,
1 ,
0 }, {
0 ,
0 ,
1 }, {
1 ,
0 ,
0 }}),
BMat8({{
0 ,
1 ,
0 }, {
1 ,
0 ,
0 }, {
0 ,
0 ,
1 }}),
BMat8({{
1 ,
0 ,
0 }, {
1 ,
1 ,
0 }, {
0 ,
0 ,
1 }}),
BMat8({{
1 ,
1 ,
0 }, {
0 ,
1 ,
1 }, {
1 ,
0 ,
1 }})};
const std::vector<BMat8> idems = {BMat8({{
1 ,
0 ,
0 }, {
0 ,
1 ,
0 }, {
0 ,
0 ,
1 }}),
BMat8({{
1 ,
0 ,
0 }, {
1 ,
1 ,
0 }, {
0 ,
0 ,
1 }}),
BMat8({{
1 ,
0 ,
0 }, {
1 ,
1 ,
1 }, {
0 ,
0 ,
1 }}),
BMat8({{
1 ,
0 ,
0 }, {
1 ,
1 ,
0 }, {
1 ,
0 ,
1 }}),
BMat8({{
1 ,
0 ,
0 }, {
1 ,
1 ,
0 }, {
1 ,
1 ,
1 }}),
BMat8({{
1 ,
1 ,
0 }, {
1 ,
1 ,
0 }, {
0 ,
0 ,
1 }}),
BMat8({{
1 ,
0 ,
0 }, {
1 ,
1 ,
1 }, {
1 ,
1 ,
1 }}),
BMat8({{
1 ,
1 ,
0 }, {
1 ,
1 ,
0 }, {
1 ,
1 ,
1 }}),
BMat8({{
1 ,
1 ,
1 }, {
1 ,
1 ,
1 }, {
1 ,
1 ,
1 }})};
Konieczny<BMat8> KS(gens);
KS.run();
REQUIRE(size_t(KS.cend_regular_D_classes() - KS.cbegin_regular_D_classes())
== idems.size());
size_t count =
0 ;
for (BMat8 id : idems) {
Konieczny<BMat8>::DClass& D = KS.D_class_of_element(id);
count += D.size();
REQUIRE(D.is_regular_D_class());
}
REQUIRE(count ==
142 );
std::vector<BMat8> non_reg_reps
= {BMat8({{
0 ,
0 ,
1 }, {
1 ,
0 ,
1 }, {
1 ,
1 ,
0 }}),
BMat8({{
0 ,
0 ,
1 }, {
1 ,
1 ,
1 }, {
1 ,
1 ,
0 }}),
BMat8({{
0 ,
1 ,
1 }, {
1 ,
0 ,
1 }, {
1 ,
1 ,
1 }}),
BMat8({{
0 ,
1 ,
1 }, {
1 ,
1 ,
0 }, {
1 ,
0 ,
1 }}),
BMat8({{
1 ,
0 ,
1 }, {
1 ,
0 ,
1 }, {
1 ,
1 ,
0 }}),
BMat8({{
1 ,
1 ,
0 }, {
1 ,
1 ,
1 }, {
1 ,
1 ,
1 }})};
{
Konieczny<BMat8>::DClass& X = KS.D_class_of_element(non_reg_reps[
0 ]);
REQUIRE(X.size() ==
36 );
REQUIRE(X.size_H_class() ==
1 );
REQUIRE(X.number_of_L_classes() ==
6 );
REQUIRE(X.number_of_R_classes() ==
6 );
}
{
Konieczny<BMat8>::DClass& X = KS.D_class_of_element(non_reg_reps[
1 ]);
REQUIRE(X.size() ==
18 );
REQUIRE(X.size_H_class() ==
1 );
REQUIRE(X.number_of_L_classes() ==
3 );
REQUIRE(X.number_of_R_classes() ==
6 );
}
{
Konieczny<BMat8>::DClass& X = KS.D_class_of_element(non_reg_reps[
2 ]);
REQUIRE(X.size() ==
18 );
REQUIRE(X.size_H_class() ==
2 );
REQUIRE(X.number_of_L_classes() ==
3 );
REQUIRE(X.number_of_R_classes() ==
3 );
}
{
Konieczny<BMat8>::DClass& X = KS.D_class_of_element(non_reg_reps[
3 ]);
REQUIRE(X.size() ==
6 );
REQUIRE(X.size_H_class() ==
6 );
REQUIRE(X.number_of_L_classes() ==
1 );
REQUIRE(X.number_of_R_classes() ==
1 );
}
{
Konieczny<BMat8>::DClass& X = KS.D_class_of_element(non_reg_reps[
4 ]);
REQUIRE(X.size() ==
18 );
REQUIRE(X.size_H_class() ==
1 );
REQUIRE(X.number_of_L_classes() ==
6 );
REQUIRE(X.number_of_R_classes() ==
3 );
}
{
Konieczny<BMat8>::DClass& X = KS.D_class_of_element(non_reg_reps[
5 ]);
REQUIRE(X.size() ==
9 );
REQUIRE(X.size_H_class() ==
1 );
REQUIRE(X.number_of_L_classes() ==
3 );
REQUIRE(X.number_of_R_classes() ==
3 );
}
for (BMat8 x : non_reg_reps) {
Konieczny<BMat8>::DClass& N = KS.D_class_of_element(x);
count += N.size();
REQUIRE(!N.is_regular_D_class());
}
REQUIRE(count ==
247 );
REQUIRE(KS.size() ==
247 );
}
LIBSEMIGROUPS_TEST_CASE(
"Konieczny" ,
"014" ,
"RegularDClass" ,
"[quick][bmat8]" ) {
auto rg = ReportGuard(REPORT);
const std::vector<BMat8> gens
= {BMat8({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }}),
BMat8({{
0 ,
1 ,
0 ,
0 }, {
1 ,
0 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }}),
BMat8({{
0 ,
1 ,
0 ,
1 }, {
1 ,
0 ,
1 ,
0 }, {
1 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
1 ,
1 }}),
BMat8({{
0 ,
1 ,
0 ,
1 }, {
1 ,
0 ,
1 ,
0 }, {
1 ,
0 ,
1 ,
0 }, {
0 ,
1 ,
0 ,
1 }}),
BMat8({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
0 ,
0 }, {
0 ,
0 ,
0 ,
0 }})};
Konieczny<BMat8> KS(gens);
KS.run();
BMat8 x = BMat8({{
0 ,
1 ,
0 }, {
1 ,
0 ,
0 }, {
0 ,
0 ,
0 }});
Konieczny<BMat8>::DClass& D = KS.D_class_of_element(x);
REQUIRE(D.size() ==
90 );
REQUIRE(D.number_of_L_classes() ==
5 );
REQUIRE(D.number_of_R_classes() ==
9 );
REQUIRE(D.is_regular_D_class());
}
LIBSEMIGROUPS_TEST_CASE(
"Konieczny" ,
"015" ,
"full bmat monoid 4" ,
"[quick][no-valgrind][bmat8]" ) {
auto rg = ReportGuard(REPORT);
const std::vector<BMat8> bmat4_gens
= {BMat8({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }}),
BMat8({{
1 ,
1 ,
1 ,
0 }, {
1 ,
0 ,
0 ,
1 }, {
0 ,
1 ,
0 ,
1 }, {
0 ,
0 ,
1 ,
1 }}),
BMat8({{
1 ,
1 ,
0 ,
0 }, {
1 ,
0 ,
1 ,
0 }, {
0 ,
1 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }}),
BMat8({{
1 ,
1 ,
0 ,
0 }, {
1 ,
0 ,
1 ,
0 }, {
0 ,
1 ,
0 ,
1 }, {
0 ,
0 ,
1 ,
1 }}),
BMat8({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
1 ,
0 ,
0 ,
1 }}),
BMat8({{
1 ,
0 ,
0 ,
0 }, {
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
0 }}),
BMat8({{
0 ,
1 ,
0 ,
0 }, {
1 ,
0 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }}),
BMat8({{
0 ,
1 ,
0 ,
0 }, {
0 ,
0 ,
1 ,
0 }, {
0 ,
0 ,
0 ,
1 }, {
1 ,
0 ,
0 ,
0 }})};
Konieczny<BMat8> S(bmat4_gens);
REQUIRE(S.size() ==
65536 );
}
}
// namespace libsemigroups
Messung V0.5 in Prozent C=79 H=90 G=84
¤ Dauer der Verarbeitung: 0.18 Sekunden
(vorverarbeitet am 2026-06-17)
¤
*© Formatika GbR, Deutschland