// libsemigroups - C++ library for semigroups and monoids
// Copyright (C) 2019 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/ >.
//
// TODO(later):
// 1. add examples from Action
#include <algorithm> // for sort
#include <cstdint> // for uint8_t
#include <stdexcept> // for out_of_range
#include <vector> // for vector
#include "libsemigroups/action.hpp" // for LeftAction, RightAction
#include "libsemigroups/bmat.hpp" // for BMat adapters
#include "libsemigroups/bmat8.hpp" // for BMat8 etc
#include "libsemigroups/matrix.hpp" // for BMat
#include "libsemigroups/report.hpp" // for ReportGuard
#include "libsemigroups/transf.hpp" // for PPerm<>
#include "catch.hpp" // for REQUIRE, REQUIRE_THROWS_AS, REQUI...
#include "test-main.hpp" // for LIBSEMIGROUPS_TEST_CASE
namespace libsemigroups {
struct LibsemigroupsException; // forward decl
constexpr bool REPORT = false ;
using row_action_type = ImageRightAction<BMat8, BMat8>;
using col_action_type = ImageLeftAction<BMat8, BMat8>;
using row_orb_type = RightAction<BMat8, BMat8, row_action_type>;
using col_orb_type = LeftAction<BMat8, BMat8, col_action_type>;
namespace {
template <typename Mat> // = BMat..
void test000() {
auto rg = ReportGuard(REPORT);
using boolmat_row_action_type
= ImageRightAction<Mat, detail::StaticVector1<BitSet<5>, 5>>;
using boolmat_col_action_type
= ImageLeftAction<Mat, detail::StaticVector1<BitSet<5>, 5>>;
using boolmat_row_orb_type
= RightAction<Mat,
detail::StaticVector1<BitSet<5>, 5>,
boolmat_row_action_type>;
using boolmat_col_orb_type
= LeftAction<Mat,
detail::StaticVector1<BitSet<5>, 5>,
boolmat_col_action_type>;
const std::vector<Mat> reg_bmat5_gens = {Mat({{0, 1, 0, 0, 0},
{1, 0, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1}}),
Mat({{0, 1, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1},
{1, 0, 0, 0, 0}}),
Mat({{1, 0, 0, 0, 0},
{1, 1, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1}}),
Mat({{0, 0, 0, 0, 0},
{0, 1, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1}})};
boolmat_row_orb_type row_orb;
boolmat_col_orb_type col_orb;
row_orb.add_seed({BitSet<5>(0x10),
BitSet<5>(0x8),
BitSet<5>(0x4),
BitSet<5>(0x2),
BitSet<5>(0x1)});
col_orb.add_seed({BitSet<5>(0x10),
BitSet<5>(0x8),
BitSet<5>(0x4),
BitSet<5>(0x2),
BitSet<5>(0x1)});
for (Mat g : reg_bmat5_gens) {
row_orb.add_generator(g);
col_orb.add_generator(g);
}
row_orb.run_for(std::chrono::milliseconds(100));
row_orb.run_for(std::chrono::milliseconds(100));
row_orb.run_for(std::chrono::milliseconds(100));
col_orb.run_for(std::chrono::milliseconds(100));
col_orb.run_for(std::chrono::milliseconds(100));
col_orb.run_for(std::chrono::milliseconds(100));
REQUIRE(row_orb.size() == 110519);
REQUIRE(col_orb.size() == 110519);
}
} // namespace
LIBSEMIGROUPS_TEST_CASE("Action" ,
"001" ,
"row and column basis orbits for BMat8" ,
"[quick]" ) {
auto rg = ReportGuard(REPORT);
row_orb_type row_orb;
row_orb.add_seed(BMat8({{1, 0, 0}, {0, 1, 0}, {0, 0, 0}}));
row_orb.add_generator(BMat8({{0, 1, 0}, {1, 0, 0}, {0, 0, 1}}));
REQUIRE(row_orb.size() == 1);
col_orb_type col_orb;
col_orb.add_seed(BMat8({{1, 0, 0}, {0, 1, 0}, {0, 0, 0}}));
col_orb.add_generator(BMat8({{0, 1, 0}, {1, 0, 0}, {0, 0, 1}}));
REQUIRE(col_orb.size() == 1);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"002" ,
"row and column basis orbits for BMat8" ,
"[quick]" ) {
auto rg = ReportGuard(REPORT);
row_orb_type row_orb;
row_orb.add_seed(
BMat8({{1, 1, 1, 0}, {1, 1, 0, 0}, {0, 1, 0, 1}, {0, 1, 0, 0}})
.row_space_basis());
row_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}));
row_orb.add_generator(
BMat8({{0, 1, 0, 0}, {1, 0, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}));
row_orb.add_generator(
BMat8({{0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}, {1, 0, 0, 0}}));
row_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {1, 0, 0, 1}}));
row_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}));
REQUIRE(row_orb.size() == 553);
col_orb_type col_orb;
col_orb.add_seed(
BMat8({{1, 1, 1, 0}, {1, 1, 0, 0}, {0, 1, 0, 1}, {0, 1, 0, 0}})
.col_space_basis());
col_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}));
col_orb.add_generator(
BMat8({{0, 1, 0, 0}, {1, 0, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}));
col_orb.add_generator(
BMat8({{0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}, {1, 0, 0, 0}}));
col_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {1, 0, 0, 1}}));
col_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}));
REQUIRE(col_orb.size() == 553);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"003" ,
"add generators after enumeration" ,
"[quick]" ) {
auto rg = ReportGuard(REPORT);
row_orb_type row_orb;
row_orb.add_seed(
BMat8({{1, 1, 1, 0}, {1, 1, 0, 0}, {0, 1, 0, 1}, {0, 1, 0, 0}})
.row_space_basis());
row_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}));
row_orb.add_generator(
BMat8({{0, 1, 0, 0}, {1, 0, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}));
row_orb.add_generator(
BMat8({{0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}, {1, 0, 0, 0}}));
row_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {1, 0, 0, 1}}));
REQUIRE(row_orb.size() == 177);
row_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}));
REQUIRE(row_orb.size() == 553);
col_orb_type col_orb;
col_orb.add_seed(
BMat8({{1, 1, 1, 0}, {1, 1, 0, 0}, {0, 1, 0, 1}, {0, 1, 0, 0}})
.col_space_basis());
col_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}));
col_orb.add_generator(
BMat8({{0, 1, 0, 0}, {1, 0, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}));
col_orb.add_generator(
BMat8({{0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}, {1, 0, 0, 0}}));
col_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {1, 0, 0, 1}}));
REQUIRE(col_orb.size() == 376);
col_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}));
REQUIRE(col_orb.size() == 553);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"004" ,
"multipliers for BMat8 row and column orbits" ,
"[quick][no-valgrind]" ) {
auto rg = ReportGuard(REPORT);
row_orb_type row_orb;
row_orb.add_seed(
BMat8({{1, 1, 1, 0}, {1, 1, 0, 0}, {0, 1, 0, 1}, {0, 1, 0, 0}})
.row_space_basis());
row_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}));
row_orb.add_generator(
BMat8({{0, 1, 0, 0}, {1, 0, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}));
row_orb.add_generator(
BMat8({{0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}, {1, 0, 0, 0}}));
row_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {1, 0, 0, 1}}));
row_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}));
row_orb.reserve(1000);
row_orb.cache_scc_multipliers(true );
REQUIRE(row_orb.size() == 553);
REQUIRE(row_orb.digraph().number_of_scc() == 14);
REQUIRE(std::vector<size_t>(row_orb.digraph().cbegin_scc_roots(),
row_orb.digraph().cend_scc_roots())
== std::vector<size_t>({277,
317,
160,
119,
267,
116,
411,
497,
183,
272,
154,
443,
65,
101}));
for (size_t i = 0; i < row_orb.size(); ++i) {
REQUIRE(
row_orb.position((row_orb.at(i) * row_orb.multiplier_to_scc_root(i))
.row_space_basis())
== row_orb.position(row_orb.root_of_scc(i)));
REQUIRE((row_orb.at(i) * row_orb.multiplier_to_scc_root(i)
* row_orb.multiplier_from_scc_root(i))
.row_space_basis()
== row_orb.at(i));
}
col_orb_type col_orb;
col_orb.add_seed(
BMat8({{1, 1, 1, 0}, {1, 1, 0, 0}, {0, 1, 0, 1}, {0, 1, 0, 0}})
.col_space_basis());
col_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}));
col_orb.add_generator(
BMat8({{0, 1, 0, 0}, {1, 0, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}}));
col_orb.add_generator(
BMat8({{0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 1}, {1, 0, 0, 0}}));
col_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {1, 0, 0, 1}}));
col_orb.add_generator(
BMat8({{1, 0, 0, 0}, {0, 1, 0, 0}, {0, 0, 1, 0}, {0, 0, 0, 0}}));
REQUIRE(col_orb.size() == 553);
for (size_t i = 0; i < col_orb.size(); ++i) {
REQUIRE((col_orb.multiplier_from_scc_root(i)
* col_orb.multiplier_to_scc_root(i) * col_orb.at(i))
.col_space_basis()
== col_orb.at(i));
}
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"005" ,
"orbits for regular boolean mat monoid 5" ,
"[quick][no-valgrind]" ) {
auto rg = ReportGuard(REPORT);
const std::vector<BMat8> reg_bmat5_gens = {BMat8({{0, 1, 0, 0, 0},
{1, 0, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1}}),
BMat8({{0, 1, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1},
{1, 0, 0, 0, 0}}),
BMat8({{1, 0, 0, 0, 0},
{1, 1, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1}}),
BMat8({{0, 0, 0, 0, 0},
{0, 1, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1}})};
row_orb_type row_orb;
col_orb_type col_orb;
row_orb.add_seed(BMat8::one());
col_orb.add_seed(BMat8::one());
for (BMat8 g : reg_bmat5_gens) {
row_orb.add_generator(g);
col_orb.add_generator(g);
}
row_orb.run();
col_orb.run();
REQUIRE(row_orb.size() == 110519);
REQUIRE(col_orb.size() == 110519);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"006" ,
"orbits for regular boolean mat monoid 6" ,
"[extreme]" ) {
// auto rg = ReportGuard(REPORT);
const std::vector<BMat8> reg_bmat6_gens = {BMat8({{0, 1, 0, 0, 0, 0},
{1, 0, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0},
{0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 1}}),
BMat8({{0, 1, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0},
{0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 1},
{1, 0, 0, 0, 0, 0}}),
BMat8({{1, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0},
{0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 1, 0},
{1, 0, 0, 0, 0, 1}}),
BMat8({{1, 0, 0, 0, 0, 0},
{0, 1, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0},
{0, 0, 0, 1, 0, 0},
{0, 0, 0, 0, 1, 0},
{0, 0, 0, 0, 0, 0}})};
row_orb_type row_orb;
row_orb.add_seed(BMat8::one());
for (BMat8 g : reg_bmat6_gens) {
row_orb.add_generator(g);
}
// row_orb.run_for(std::chrono::milliseconds(500));
REQUIRE(row_orb.size() == 37977468);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"007" ,
"partial perm image orbit" ,
"[quick]" ) {
auto rg = ReportGuard(REPORT);
RightAction<PPerm<8>, PPerm<8>, ImageRightAction<PPerm<8>, PPerm<8>>> o;
o.add_seed(PPerm<8>::identity(8));
o.add_generator(
PPerm<8>({0, 1, 2, 3, 4, 5, 6, 7}, {1, 2, 3, 4, 5, 6, 7, 0}, 8));
o.add_generator(
PPerm<8>({0, 1, 2, 3, 4, 5, 6, 7}, {1, 0, 2, 3, 4, 5, 6, 7}, 8));
o.add_generator(PPerm<8>({1, 2, 3, 4, 5, 6, 7}, {0, 1, 2, 3, 4, 5, 6}, 8));
o.add_generator(PPerm<8>({0, 1, 2, 3, 4, 5, 6}, {1, 2, 3, 4, 5, 6, 7}, 8));
REQUIRE(o.size() == 256);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"008" ,
"partial perm image orbit" ,
"[quick][no-valgrind]" ) {
auto rg = ReportGuard(REPORT);
RightAction<PPerm<16>, PPerm<16>, ImageRightAction<PPerm<16>, PPerm<16>>> o;
o.add_seed(PPerm<16>::identity(16));
o.add_generator(
PPerm<16>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0},
16));
o.add_generator(
PPerm<16>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
16));
o.add_generator(
PPerm<16>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},
16));
o.add_generator(
PPerm<16>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
16));
o.reserve(70000);
REQUIRE(o.size() == 65536);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"009" ,
"partial perm image orbit" ,
"[quick][no-valgrind]" ) {
auto rg = ReportGuard(REPORT);
RightAction<PPerm<16>, PPerm<16>, ImageRightAction<PPerm<16>, PPerm<16>>> o;
o.add_seed(One<PPerm<16>>()(16));
o.add_generator(
PPerm<16>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0},
16));
o.add_generator(
PPerm<16>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
16));
o.add_generator(
PPerm<16>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},
16));
o.add_generator(
PPerm<16>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
16));
o.reserve(70000);
REQUIRE(o.size() == 65536);
REQUIRE(o.digraph().number_of_scc() == 17);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"010" ,
"partial perm image orbit" ,
"[quick][no-valgrind]" ) {
auto rg = ReportGuard(REPORT);
LeftAction<PPerm<16>, PPerm<16>, ImageLeftAction<PPerm<16>, PPerm<16>>> o;
o.add_seed(One<PPerm<16>>()(16));
o.add_generator(
PPerm<16>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 0},
16));
o.add_generator(
PPerm<16>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
16));
o.add_generator(
PPerm<16>({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},
16));
o.add_generator(
PPerm<16>({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14},
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15},
16));
REQUIRE(o.size() == 65536);
REQUIRE(o.digraph().number_of_scc() == 17);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"011" ,
"permutation on integers" ,
"[quick]" ) {
auto rg = ReportGuard(REPORT);
using Perm = LeastPerm<8>;
RightAction<Perm, uint8_t, ImageRightAction<Perm, uint8_t>> o;
o.add_seed(0);
o.add_generator(Perm({1, 0, 2, 3, 4, 5, 6, 7}));
o.add_generator(Perm({1, 2, 3, 4, 5, 6, 7, 0}));
REQUIRE(o.size() == 8);
REQUIRE(o.digraph().number_of_scc() == 1);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"012" ,
"permutation on sets, arrays" ,
"[quick]" ) {
auto rg = ReportGuard(REPORT);
using Perm = LeastPerm<10>;
RightAction<Perm,
std::array<uint8_t, 5>,
OnSets<Perm, uint8_t, std::array<uint8_t, 5>>>
o;
o.add_seed({0, 1, 2, 3, 4});
o.add_generator(Perm({1, 0, 2, 3, 4, 5, 6, 7, 8, 9}));
o.add_generator(Perm({1, 2, 3, 4, 5, 6, 7, 8, 9, 0}));
REQUIRE(o.size() == 252);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"013" ,
"permutation on tuples, arrays" ,
"[quick][no-valgrind]" ) {
auto rg = ReportGuard(REPORT);
using Perm = LeastPerm<10>;
RightAction<Perm,
std::array<uint8_t, 5>,
OnTuples<Perm, uint8_t, std::array<uint8_t, 5>>>
o;
o.add_seed({0, 1, 2, 3, 4});
o.add_generator(Perm({1, 0, 2, 3, 4, 5, 6, 7, 8, 9}));
o.add_generator(Perm({1, 2, 3, 4, 5, 6, 7, 8, 9, 0}));
REQUIRE(o.size() == 30240);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"014" ,
"permutation on sets, vectors" ,
"[quick]" ) {
auto rg = ReportGuard(REPORT);
using Perm = LeastPerm<10>;
RightAction<Perm, std::vector<uint8_t>, OnSets<Perm, uint8_t>> o;
o.add_seed({0, 1, 2, 3, 4});
o.add_generator(Perm({1, 0, 2, 3, 4, 5, 6, 7, 8, 9}));
o.add_generator(Perm({1, 2, 3, 4, 5, 6, 7, 8, 9, 0}));
REQUIRE(o.size() == 252);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"015" ,
"permutation on tuples, vectors" ,
"[quick][no-valgrind]" ) {
auto rg = ReportGuard(REPORT);
using Perm = LeastPerm<10>;
RightAction<Perm, std::vector<uint8_t>, OnTuples<Perm, uint8_t>> o;
o.add_seed({0, 1, 2, 3, 4});
o.add_generator(Perm({1, 0, 2, 3, 4, 5, 6, 7, 8, 9}));
o.add_generator(Perm({1, 2, 3, 4, 5, 6, 7, 8, 9, 0}));
REQUIRE(o.size() == 30240);
}
LIBSEMIGROUPS_TEST_CASE("Action" , "016" , "misc" , "[quick]" ) {
auto rg = ReportGuard(REPORT);
using Perm = LeastPerm<8>;
RightAction<Perm, uint8_t, ImageRightAction<Perm, uint8_t>> o;
REQUIRE(o.current_size() == 0);
REQUIRE(o.empty());
REQUIRE_THROWS_AS(o.multiplier_to_scc_root(10), LibsemigroupsException);
o.add_seed(0);
REQUIRE(!o.empty());
REQUIRE(std::vector<uint8_t>(o.cbegin(), o.cend())
== std::vector<uint8_t>({0}));
o.add_generator(Perm({1, 0, 2, 3, 4, 5, 6, 7}));
o.add_generator(Perm({1, 2, 3, 4, 5, 6, 7, 0}));
o.report_every(std::chrono::nanoseconds(10));
REQUIRE(o.current_size() == 1);
REQUIRE(o.size() == 8);
REQUIRE(o.digraph().number_of_scc() == 1);
REQUIRE(o.position(10) == UNDEFINED);
REQUIRE(o.current_size() == 8);
REQUIRE_THROWS_AS(o.at(10), std::out_of_range);
// REQUIRE_NOTHROW(o[10]);
REQUIRE(o[0] == 0);
REQUIRE(o[1] == 1);
REQUIRE(o.at(0) == 0);
REQUIRE(o.at(1) == 1);
REQUIRE_THROWS_AS(o.multiplier_to_scc_root(10), LibsemigroupsException);
REQUIRE_THROWS_AS(o.multiplier_from_scc_root(10), LibsemigroupsException);
std::vector<uint8_t> result(o.cbegin(), o.cend());
std::sort(result.begin(), result.end());
REQUIRE(result == std::vector<uint8_t>({0, 1, 2, 3, 4, 5, 6, 7}));
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"017" ,
"partial perm image orbit" ,
"[quick]" ) {
auto rg = ReportGuard(REPORT);
RightAction<PPerm<3>, PPerm<3>, ImageRightAction<PPerm<3>, PPerm<3>>> o;
o.add_seed(PPerm<3>({0, 1, 2}, {0, 1, 2}, 3));
o.add_generator(PPerm<3>({0, 1, 2}, {1, 2, 0}, 3));
o.add_generator(PPerm<3>({0, 1, 2}, {1, 0, 2}, 3));
o.add_generator(PPerm<3>({1, 2}, {0, 1}, 3));
o.add_generator(PPerm<3>({0, 1}, {1, 2}, 3));
REQUIRE(o.size() == 8);
REQUIRE(std::vector<PPerm<3>>(o.cbegin(), o.cend())
== std::vector<PPerm<3>>({PPerm<3>({0, 1, 2}, {0, 1, 2}, 3),
PPerm<3>({0, 1}, {0, 1}, 3),
PPerm<3>({1, 2}, {1, 2}, 3),
PPerm<3>({0}, {0}, 3),
PPerm<3>({0, 2}, {0, 2}, 3),
PPerm<3>({2}, {2}, 3),
PPerm<3>({1}, {1}, 3),
PPerm<3>({}, {}, 3)}));
REQUIRE_THROWS_AS(o.digraph().cbegin_scc(10), LibsemigroupsException);
REQUIRE(o.root_of_scc(PPerm<3>({0, 2}, {0, 2}, 3))
== PPerm<3>({0, 2}, {0, 2}, 3));
REQUIRE(o.root_of_scc(PPerm<3>({0, 1}, {0, 1}, 3))
== PPerm<3>({0, 2}, {0, 2}, 3));
REQUIRE_THROWS_AS(o.root_of_scc(PPerm<3>::make({0, 3}, {0, 3}, 4)),
LibsemigroupsException);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"018" ,
"permutation on tuples, arrays (360360)" ,
"[quick][no-valgrind]" ) {
auto rg = ReportGuard(REPORT);
using Perm = LeastPerm<15>;
RightAction<Perm,
std::array<uint8_t, 5>,
OnTuples<Perm, uint8_t, std::array<uint8_t, 5>>>
o;
o.add_seed({0, 1, 2, 3, 4});
o.add_generator(Perm({1, 0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}));
o.add_generator(Perm({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0}));
REQUIRE(o.size() == 360360);
}
LIBSEMIGROUPS_TEST_CASE("Action" ,
"019" ,
"orbits for regular BMat8 monoid 5 with stop/start" ,
"[quick][no-valgrind]" ) {
auto rg = ReportGuard(REPORT);
const std::vector<BMat8> reg_bmat5_gens = {BMat8({{0, 1, 0, 0, 0},
{1, 0, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1}}),
BMat8({{0, 1, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1},
{1, 0, 0, 0, 0}}),
BMat8({{1, 0, 0, 0, 0},
{1, 1, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1}}),
BMat8({{0, 0, 0, 0, 0},
{0, 1, 0, 0, 0},
{0, 0, 1, 0, 0},
{0, 0, 0, 1, 0},
{0, 0, 0, 0, 1}})};
row_orb_type row_orb;
col_orb_type col_orb;
row_orb.add_seed(BMat8::one());
col_orb.add_seed(BMat8::one());
for (BMat8 g : reg_bmat5_gens) {
row_orb.add_generator(g);
col_orb.add_generator(g);
}
row_orb.run_for(std::chrono::milliseconds(100));
row_orb.run_for(std::chrono::milliseconds(100));
row_orb.run_for(std::chrono::milliseconds(100));
col_orb.run_for(std::chrono::milliseconds(100));
col_orb.run_for(std::chrono::milliseconds(100));
col_orb.run_for(std::chrono::milliseconds(100));
REQUIRE(row_orb.size() == 110519);
REQUIRE(col_orb.size() == 110519);
}
LIBSEMIGROUPS_TEST_CASE(
"Action" ,
"020" ,
"orbits for regular boolean mat monoid 5 (BMat<>) with stop/start" ,
"[standard][no-valgrind]" ) {
test000<BMat<>>();
}
LIBSEMIGROUPS_TEST_CASE(
"Action" ,
"021" ,
"orbits for regular boolean mat monoid 5 (BMat<5>) with stop/start" ,
"[quick][no-valgrind]" ) {
test000<BMat<5>>();
}
} // namespace libsemigroups
quality 91%
¤ Dauer der Verarbeitung: 0.14 Sekunden
¤
*© Formatika GbR, Deutschland