Skip to content

Commit

Permalink
v3 Fix bug in SimsRefinerIdeals when dealing with complete graphs (l…
Browse files Browse the repository at this point in the history
  • Loading branch information
reiniscirpons authored May 3, 2024
1 parent 0d35fe2 commit b22934a
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 49 deletions.
9 changes: 8 additions & 1 deletion include/libsemigroups/sims.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ namespace libsemigroups {
//! * \ref number_of_threads to set the number of threads;
//! * \ref include to set the pairs to be included;
//! * \ref exclude to set the pairs to be excluded;
//! * \ref add_pruner to add a pruninf function;
//! * \ref add_pruner to add a pruner;
//! * \ref long_rule_length to set the length of long rules;
//! * \ref idle_thread_restarts to set the number of idle thread restarts.
//!
Expand Down Expand Up @@ -3120,6 +3120,13 @@ namespace libsemigroups {
return false;
}
}
} else {
auto const N = wg.number_of_active_nodes();
auto first = wg.cbegin_nodes();
auto last = wg.cbegin_nodes() + N;
if (word_graph::is_complete(wg, first, last)) {
return false;
}
}
return true;
}
Expand Down
165 changes: 117 additions & 48 deletions tests/test-sims.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

#include "libsemigroups/detail/stl.hpp"
#include "libsemigroups/word-graph.hpp"
#include <cstdint>
#define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER
#define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER

Expand Down Expand Up @@ -3848,6 +3849,7 @@ namespace libsemigroups {
"[quick][sims1]") {
Presentation<std::string> p;
p.alphabet("ab");
p.contains_empty_word(false);
presentation::add_rule(p, "aaa", "bb");
presentation::add_rule(p, "aab", "ba");

Expand All @@ -3858,61 +3860,15 @@ namespace libsemigroups {
SimsRefinerIdeals ip(s.presentation());
s.add_pruner(ip);

// size_t result = 0;
// s.for_each(3, [&ip, &result](auto const& wg) {
// if (ip(wg)) {
// result++;
// }
// });
// REQUIRE(result == 5);
// result = 0;
// s.for_each(4, [&ip, &result](auto const& wg) {
// if (ip(wg)) {
// result++;
// }
// });
// REQUIRE(result == 7);
//
// result = 0;
// s.for_each(5, [&ip, &result](auto const& wg) {
// if (ip(wg)) {
// result++;
// }
// });
// REQUIRE(result == 9);
//
// result = 0;
// s.for_each(6, [&ip, &result](auto const& wg) {
// if (ip(wg)) {
// result++;
// }
// });
// REQUIRE(result == 11);
//
// result = 0;
// s.for_each(7, [&ip, &result](auto const& wg) {
// if (ip(wg)) {
// result++;
// }
// });
// REQUIRE(result == 12);
//
// result = 0;
// s.for_each(8, [&ip, &result](auto const& wg) {
// if (ip(wg)) {
// result++;
// }
// });
// REQUIRE(result == 12);

REQUIRE(s.number_of_congruences(1) == 1); // computed using GAP
REQUIRE(s.number_of_congruences(2) == 3); // computed using GAP
REQUIRE(s.number_of_congruences(3) == 5); // computed using GAP
REQUIRE(s.number_of_congruences(4) == 7); // computed using GAP
REQUIRE(s.number_of_congruences(5) == 9); // computed using GAP
REQUIRE(s.number_of_congruences(6) == 11); // computed using GAP
REQUIRE(s.number_of_congruences(7) == 12); // computed using GAP
REQUIRE(s.number_of_congruences(8) == 12); // computed using GAP
for (size_t nr_classes = 8; nr_classes < 16; ++nr_classes)
REQUIRE(s.number_of_congruences(nr_classes) == 12); // computed using GAP
}

// about 2 seconds
Expand Down Expand Up @@ -4031,6 +3987,119 @@ namespace libsemigroups {
// REQUIRE(result == 6);
// REQUIRE(s.number_of_congruences(15) == 0);
}

LIBSEMIGROUPS_TEST_CASE("Sims2",
"123",
"Adding and removing pruners",
"[quick][low-index]") {
Presentation<std::string> p;
p.alphabet("ab");
p.contains_empty_word(false);
presentation::add_rule(p, "aaa", "bb");
presentation::add_rule(p, "aab", "ba");

Sims2 s(p);
SimsRefinerIdeals ip(s.presentation());
s.add_pruner(ip);
REQUIRE(s.number_of_congruences(12) == 12); // computed using GAP
s.clear_pruners();
REQUIRE(s.number_of_congruences(12) == 41); // computed using GAP
s.add_pruner(ip);
REQUIRE(s.number_of_congruences(12) == 12); // computed using GAP
}

LIBSEMIGROUPS_TEST_CASE("Sims1",
"124",
"Right congruence checking",
"[quick][low-index]") {
Presentation<word_type> p;
p.alphabet(01_w);
p.contains_empty_word(true);
presentation::add_rule(p, 000_w, 11_w);
presentation::add_rule(p, 001_w, 10_w);

word_graph_type wg;

// Wrong alphabet size
wg = to_word_graph<node_type>(3, {{1, 1, 1}, {2, 2, 2}, {2, 2, 2}});
wg.number_of_active_nodes(3);
REQUIRE(!sims::is_right_congruence(p, wg));

// Incomplete
wg = to_word_graph<node_type>(2, {{1, 1}, {1, UNDEFINED}});
wg.number_of_active_nodes(2);
REQUIRE(!sims::is_right_congruence(p, wg));

// Incompatible
wg = to_word_graph<node_type>(2, {{1, 1}, {1, 0}});
wg.number_of_active_nodes(2);
REQUIRE(!sims::is_right_congruence(p, wg));
REQUIRE_THROWS_AS(sims::validate_right_congruence(p, wg),
LibsemigroupsException);

// Works
wg = to_word_graph<node_type>(4, {{1, 2}, {2, 2}, {3, 3}, {3, 3}});
wg.number_of_active_nodes(4);
REQUIRE(sims::is_right_congruence(p, wg));

// Non maximal
wg = to_word_graph<node_type>(2, {{1, 1}, {1, 0}});
wg.number_of_active_nodes(2);
REQUIRE(!sims::is_maximal_right_congruence(p, wg));
wg = to_word_graph<node_type>(4, {{1, 2}, {2, 2}, {3, 3}, {3, 3}});
wg.number_of_active_nodes(4);
REQUIRE(!sims::is_maximal_right_congruence(p, wg));
wg = to_word_graph<node_type>(1, {{0, 0}});
wg.number_of_active_nodes(1);
REQUIRE(!sims::is_maximal_right_congruence(p, wg));

// Is maximal
wg = to_word_graph<node_type>(2, {{1, 1}, {1, 1}});
wg.number_of_active_nodes(2);
REQUIRE(sims::is_maximal_right_congruence(p, wg));
}

LIBSEMIGROUPS_TEST_CASE("Sims2",
"125",
"Two-sided congruence checking",
"[quick][low-index]") {
Presentation<word_type> p;
p.alphabet(01_w);
p.contains_empty_word(true);
presentation::add_rule(p, 000_w, 11_w);
presentation::add_rule(p, 001_w, 10_w);

word_graph_type wg;

// Wrong alphabet size
wg = to_word_graph<node_type>(3, {{1, 1, 1}, {2, 2, 2}, {2, 2, 2}});
wg.number_of_active_nodes(3);
REQUIRE(!sims::is_two_sided_congruence(p, wg));

// Incomplete
wg = to_word_graph<node_type>(2, {{1, 1}, {1, UNDEFINED}});
wg.number_of_active_nodes(2);
REQUIRE(!sims::is_two_sided_congruence(p, wg));

// Incompatible
wg = to_word_graph<node_type>(2, {{1, 1}, {1, 0}});
wg.number_of_active_nodes(2);
REQUIRE(!sims::is_two_sided_congruence(p, wg));
REQUIRE_THROWS_AS(sims::validate_two_sided_congruence(p, wg),
LibsemigroupsException);

// Not compatible with X_Gamma
wg = to_word_graph<node_type>(4, {{1, 2}, {2, 2}, {3, 3}, {3, 3}});
wg.number_of_active_nodes(4);
REQUIRE(!sims::is_two_sided_congruence(p, wg));
REQUIRE_THROWS_AS(sims::validate_two_sided_congruence(p, wg),
LibsemigroupsException);

// Works
wg = to_word_graph<node_type>(2, {{1, 1}, {1, 1}});
wg.number_of_active_nodes(2);
REQUIRE(sims::is_two_sided_congruence(p, wg));
}
} // namespace libsemigroups

// [[[0, 0, 0]], #1#
Expand Down

0 comments on commit b22934a

Please sign in to comment.