Skip to content

Commit

Permalink
Add to_human_readable_repr
Browse files Browse the repository at this point in the history
  • Loading branch information
Joseph-Edwards committed Oct 30, 2024
1 parent 66f737c commit f008948
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 1 deletion.
21 changes: 20 additions & 1 deletion include/libsemigroups/schreier-sims.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,8 @@ namespace libsemigroups {
//!
//! This functions adds the argument \p x as a new generator if and only if
//! \p x is not already an element of the group represented by the
//! Schreier-Sims object.
//! Schreier-Sims object. For example, the identity element is never added
//! as a generator.
//!
//! \param x a const reference to the generator to add.
//!
Expand Down Expand Up @@ -977,6 +978,24 @@ namespace libsemigroups {
SchreierSims<N>& S1,
SchreierSims<N>& S2);
} // namespace schreier_sims

//! \ingroup schreier_sims_group
//!
//! \brief Returns a human readable representation of a SchreierSims object.
//!
//! This function returns a human readable representation of a SchreierSims
//! object.
//!
//! \tparam N the largest point not fixed by the permutations in the
//! permutation groups.
//!
//! \param S the SchreierSims object.
//! \param braces the braces to use to delineate rows (default: `"{}"`).
//! \param max_width the maximum width of the returned representation
//! (default: \c 72).
template <size_t N>
[[nodiscard]] std::string to_human_readable_repr(SchreierSims<N> const& S,
size_t max_width = 72);
} // namespace libsemigroups

#include "schreier-sims.tpp"
Expand Down
56 changes: 56 additions & 0 deletions include/libsemigroups/schreier-sims.tpp
Original file line number Diff line number Diff line change
Expand Up @@ -627,4 +627,60 @@ namespace libsemigroups {
T.run();
}
} // namespace schreier_sims

template <size_t N>
[[nodiscard]] std::string to_human_readable_repr(SchreierSims<N> const& S,
size_t max_width) {
size_t base_size = S.base_size();
size_t nr_generators = S.number_of_generators();
std::string base_string;
std::string out;

// 3 * base_size is a lower bound on the length of the base as a string in
// the form "(X, X, X, X)".
if (base_size == 0) {
base_string = "()";
} else if (3 * base_size < max_width) {
base_string = "(";
for (size_t i = 0; i < base_size - 1; ++i) {
base_string.append(std::to_string(S.base_no_checks(i)) + ", ");
}
base_string.append(std::to_string(S.base_no_checks(base_size - 1)) + ")");
}

if (S.finished()) {
size_t size = const_cast<SchreierSims<N>&>(S).size();

out = fmt::format("<SchreierSims with {} generator{}, base {} & size {}>",
nr_generators,
nr_generators == 1 ? "" : "s",
base_string,
size);

if (out.length() > max_width) {
out = fmt::format(
"<SchreierSims with {} generator{}, base size {} & size {}>",
nr_generators,
nr_generators == 1 ? "" : "s",
base_size,
size);
}
return out;
}

out = fmt::format(
"<partially enumerated SchreierSims with {} generator{} & base {}>",
nr_generators,
nr_generators == 1 ? "" : "s",
base_string);

if (out.length() > max_width) {
out = fmt::format("<partially enumerated SchreierSims with {} "
"generator{} & base size {}>",
nr_generators,
nr_generators == 1 ? "" : "s",
base_size);
}
return out;
}
} // namespace libsemigroups
12 changes: 12 additions & 0 deletions tests/test-schreier-sims.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ namespace libsemigroups {
REQUIRE(S.sift(Perm({1, 0})) == Perm({1, 0}));
REQUIRE(!S.contains(Perm({1, 0})));
REQUIRE(S.contains(Perm({0, 1})));
REQUIRE(
to_human_readable_repr(S)
== "<partially enumerated SchreierSims with 0 generators & base ()>");
}

LIBSEMIGROUPS_TEST_CASE("SchreierSims",
Expand Down Expand Up @@ -111,7 +114,11 @@ namespace libsemigroups {
using Perm = decltype(S)::element_type;
S.add_generator(Perm({1, 0, 2, 3, 4}));
S.add_generator(Perm({1, 2, 3, 4, 0}));
REQUIRE(S.number_of_generators() == 2);
REQUIRE(S.size() == 120);
REQUIRE(
to_human_readable_repr(S)
== "<SchreierSims with 2 generators, base (0, 1, 2, 3) & size 120>");
}

LIBSEMIGROUPS_TEST_CASE("SchreierSims",
Expand All @@ -134,6 +141,8 @@ namespace libsemigroups {
T.add_generator(Perm({1, 2, 3, 4, 5, 6, 7, 0}));
REQUIRE(S.size() == 40'320);
REQUIRE(T.size() == 40'320);
REQUIRE(to_human_readable_repr(S)
== "<SchreierSims with 2 generators, base size 7 & size 40320>");

decltype(T) U(T);
REQUIRE(U.finished());
Expand Down Expand Up @@ -220,6 +229,9 @@ namespace libsemigroups {
Perm({1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 15}));
S.add_generator(
Perm({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 13}));
REQUIRE(to_human_readable_repr(S)
== "<partially enumerated SchreierSims with 3 generators & base "
"size 13>");
REQUIRE(S.size() == static_cast<uint64_t>(10461394944000));
REQUIRE(S.contains(
Perm({0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 14, 15, 13})));
Expand Down

0 comments on commit f008948

Please sign in to comment.