From f15e82dab2f2de32b0e47857c045f843c99504f5 Mon Sep 17 00:00:00 2001 From: "James D. Mitchell" Date: Mon, 7 Apr 2025 18:25:13 +0200 Subject: [PATCH 1/7] Compiles --- GNUmakefile.in | 11 +-- gapbind14/include/gapbind14/cpp_fn.hpp | 27 ++++++ src/bipart.cpp | 41 +++++---- src/cong.cpp | 116 +++++++++++++------------ src/conglatt.cpp | 6 +- src/froidure-pin-base.cpp | 12 ++- src/froidure-pin-fallback.cpp | 4 +- src/froidure-pin.hpp | 22 +++-- src/pkg.cpp | 109 ++++++++--------------- src/pkg.hpp | 14 +-- src/to_cpp.hpp | 57 ++++++------ src/to_gap.hpp | 82 +++++++++-------- 12 files changed, 257 insertions(+), 244 deletions(-) diff --git a/GNUmakefile.in b/GNUmakefile.in index d55c7e4ec..2015db247 100644 --- a/GNUmakefile.in +++ b/GNUmakefile.in @@ -3,7 +3,7 @@ # KEXT_NAME = semigroups -KEXT_CXXFLAGS = @LIBSEMIGROUPS_CFLAGS@ -std=gnu++14 -O3 +KEXT_CXXFLAGS = @LIBSEMIGROUPS_CFLAGS@ -std=gnu++17 -O3 KEXT_LDFLAGS = @LIBSEMIGROUPS_RPATH@ @LIBSEMIGROUPS_LIBS@ # configure settings @@ -47,10 +47,11 @@ ifdef WITH_INCLUDED_LIBSEMIGROUPS # FIXME(later) all the include paths should point into bin/include/ and not to # the sources, or otherwise we should stop make installing into bin ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED -KEXT_CPPFLAGS += -Ilibsemigroups/extern/HPCombi/include -KEXT_CPPFLAGS += -Ilibsemigroups/extern/HPCombi/include/fallback +KEXT_CPPFLAGS += -Ilibsemigroups/third_party/HPCombi/include +KEXT_CPPFLAGS += -Ilibsemigroups/third_party/HPCombi/third_party/ endif -KEXT_CPPFLAGS += -Ilibsemigroups/extern/fmt-8.0.1/include +KEXT_CPPFLAGS += -Ilibsemigroups/third_party/fmt-11.1.4/include +KEXT_CPPFLAGS += -Ilibsemigroups/third_party/magic_enum-0.9.7/include KEXT_CPPFLAGS += -Ilibsemigroups/include endif KEXT_CPPFLAGS += -DFMT_HEADER_ONLY @@ -102,7 +103,7 @@ lint: etc/cpplint.sh format: - clang-format -i src/*.*pp + clang-format -i src/*.[hc] .PHONY: lint format diff --git a/gapbind14/include/gapbind14/cpp_fn.hpp b/gapbind14/include/gapbind14/cpp_fn.hpp index af973883f..d80d28bf4 100644 --- a/gapbind14/include/gapbind14/cpp_fn.hpp +++ b/gapbind14/include/gapbind14/cpp_fn.hpp @@ -42,6 +42,8 @@ namespace gapbind14 { // Overloading //////////////////////////////////////////////////////////////////////// + static constexpr auto const_ = std::true_type{}; + template struct overload_cast_impl { constexpr overload_cast_impl() {} @@ -94,6 +96,11 @@ namespace gapbind14 { using type = R(A...); }; + template + struct remove_class { + using type = R(A...); + }; + template struct strip_function_object { using type = typename remove_class::type; @@ -186,11 +193,21 @@ namespace gapbind14 { struct CppFunction : CppFunctionBase {}; + // noexcept free functions + template + struct CppFunction + : CppFunctionBase {}; + // Function pointers . . . template struct CppFunction : CppFunctionBase {}; + // noexcept function pointer + template + struct CppFunction + : CppFunctionBase {}; + // Member functions . . . template struct CppFunction @@ -201,6 +218,16 @@ namespace gapbind14 { struct CppFunction : CppMemFnBase {}; + // Const noexcept member functions + template + struct CppFunction + : CppMemFnBase {}; + + // Non-const noexcept member functions + template + struct CppFunction + : CppMemFnBase {}; + // std::function objects template struct CppFunction> diff --git a/src/bipart.cpp b/src/bipart.cpp index dd6504154..3d15e5d08 100644 --- a/src/bipart.cpp +++ b/src/bipart.cpp @@ -34,16 +34,15 @@ #include "gap_all.h" // libsemigroups headers -#include "libsemigroups/bipart.hpp" // for Blocks, Bipartition, validate -#include "libsemigroups/report.hpp" // for Reporter, etc -#include "libsemigroups/timer.hpp" // for Timer -#include "semigroups-config.hpp" // for SEMIGROUPS_KERNEL_DEBUG +#include "libsemigroups/bipart.hpp" // for Blocks, Bipartition, validate +#include "libsemigroups/detail/report.hpp" // for Reporter, etc +#include "libsemigroups/detail/timer.hpp" // for Timer +#include "semigroups-config.hpp" // for SEMIGROUPS_KERNEL_DEBUG #include "gapbind14/gapbind14.hpp" // for GAPBIND14_TRY using libsemigroups::Bipartition; using libsemigroups::Blocks; -using libsemigroups::REPORTER; using libsemigroups::detail::Timer; // Global variables @@ -277,7 +276,7 @@ Obj BIPART_PROD(Obj x, Obj y) { Bipartition* yy = bipart_get_cpp(y); Bipartition* z = new Bipartition(xx->degree()); - z->product_inplace(*xx, *yy); + z->product_inplace_no_checks(*xx, *yy); return bipart_new_obj(static_cast(z)); } @@ -706,11 +705,11 @@ Obj BLOCKS_NC(Obj self, Obj gap_blocks) { SEMIGROUPS_ASSERT(IS_INTOBJ(ELM_LIST(block, j))); int jj = INT_INTOBJ(ELM_LIST(block, j)); if (jj < 0) { - blocks->set_block(-jj - 1, i - 1); - blocks->set_is_transverse_block(i - 1, false); + blocks->block(-jj - 1, i - 1); + blocks->is_transverse_block(i - 1, false); } else { - blocks->set_block(jj - 1, i - 1); - blocks->set_is_transverse_block(i - 1, true); + blocks->block(jj - 1, i - 1); + blocks->is_transverse_block(i - 1, true); } } } @@ -1000,8 +999,8 @@ Obj BLOCKS_LEFT_ACT(Obj self, Obj blocks_gap, Obj x_gap) { tab[j] = next; next++; } - out_blocks->set_block(i, tab[j]); - out_blocks->set_is_transverse_block(tab[j], _BUFFER_bool[j]); + out_blocks->block(i, tab[j]); + out_blocks->is_transverse_block(tab[j], _BUFFER_bool[j]); } #ifdef SEMIGROUPS_KERNEL_DEBUG @@ -1055,8 +1054,8 @@ Obj BLOCKS_RIGHT_ACT(Obj self, Obj blocks_gap, Obj x_gap) { tab[j] = next; next++; } - out_blocks->set_block(i - n, tab[j]); - out_blocks->set_is_transverse_block(tab[j], _BUFFER_bool[j]); + out_blocks->block(i - n, tab[j]); + out_blocks->is_transverse_block(tab[j], _BUFFER_bool[j]); } #ifdef SEMIGROUPS_KERNEL_DEBUG libsemigroups::validate(*out_blocks); @@ -1210,7 +1209,7 @@ Obj BLOCKS_INV_RIGHT(Obj self, Obj blocks_gap, Obj x_gap) { continue; } } - if (junk == static_cast(-1)) { + if (junk == (uint32_t) -1) { junk = next; next++; } @@ -1399,10 +1398,10 @@ class IdempotentCounter { } std::vector count() { - libsemigroups::THREAD_ID_MANAGER.reset(); - REPORT_DEFAULT("using %llu / %llu additional threads", - _nr_threads, - std::thread::hardware_concurrency()); + libsemigroups::detail::reset_thread_ids(); + libsemigroups::report_default("using {} / {} additional threads", + _nr_threads, + std::thread::hardware_concurrency()); Timer timer; for (size_t i = 0; i < _nr_threads; i++) { @@ -1414,7 +1413,7 @@ class IdempotentCounter { _threads[i].join(); } - REPORT_TIME(timer); + libsemigroups::report_elapsed_time("", timer); size_t max = *max_element(_ranks.begin(), _ranks.end()) + 1; std::vector out = std::vector(max, 0); @@ -1450,7 +1449,7 @@ class IdempotentCounter { } } } - REPORT_DEFAULT("finished in %llu", timer.string().c_str()); + libsemigroups::report_default("finished in {}", timer); } // This is basically the same as BLOCKS_E_TESTER, but is required because we diff --git a/src/cong.cpp b/src/cong.cpp index 62cada6e5..3001f7b3d 100644 --- a/src/cong.cpp +++ b/src/cong.cpp @@ -37,7 +37,6 @@ // libsemigroups headers #include "libsemigroups/bipart.hpp" // for Bipartition -#include "libsemigroups/cong-intf.hpp" // for congruence_kind #include "libsemigroups/cong.hpp" // for Congruence #include "libsemigroups/constants.hpp" // for UNDEFINED etc #include "libsemigroups/froidure-pin.hpp" // for FroidurePin @@ -54,7 +53,10 @@ namespace libsemigroups { namespace gapbind14 { template <> - struct IsGapBind14Type : std::true_type {}; + struct IsGapBind14Type> + : std::true_type { + static constexpr std::string_view name = "Congruence"; + }; } // namespace gapbind14 @@ -89,58 +91,60 @@ void init_cong(gapbind14::Module& m) { // Cannot use FroidurePinBase rather than the specialisations because there's // no constructor for a Congruence from a FroidurePinBase&. - gapbind14::class_("Congruence") - .def(gapbind14::init const&>{}, - "make_from_froidurepin_bipartition") - .def(gapbind14::init> const&>{}, - "make_from_froidurepin_bmat") - .def(gapbind14::init const&>{}, - "make_from_froidurepin_bmat8") - .def(gapbind14::init const&>{}, - "make_from_froidurepin_pbr") -#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED - .def(gapbind14::init> const&>{}, - "make_from_froidurepin_leastpperm") - .def(gapbind14::init> const&>{}, - "make_from_froidurepin_leasttransf") -#endif - .def(gapbind14::init> const&>{}, - "make_from_froidurepin_transfUInt2") - .def(gapbind14::init> const&>{}, - "make_from_froidurepin_transfUInt4") - .def(gapbind14::init> const&>{}, - "make_from_froidurepin_ppermUInt2") - .def(gapbind14::init> const&>{}, - "make_from_froidurepin_ppermUInt4") - .def(gapbind14::init{}, - "make_from_fpsemigroup") - .def(gapbind14::init>{}, - "make_from_froidurepinbase") - .def(gapbind14::init{}, - "make_from_table") - .def("set_number_of_generators", &Congruence::set_number_of_generators) - .def("number_of_pairs", &Congruence::number_of_generating_pairs) - .def("add_pair", - overload_cast( - &Congruence::add_pair)) - .def("number_of_classes", &Congruence::number_of_classes) - .def("word_to_class_index", &Congruence::word_to_class_index) - .def("class_index_to_word", &Congruence::class_index_to_word) - .def("contains", &Congruence::contains) - .def("less", &Congruence::less) - .def("add_runner", - &Congruence::add_runner) - .def("is_quotient_obviously_infinite", - &Congruence::is_quotient_obviously_infinite) - .def("ntc", - [](Congruence& C) { - return gapbind14::make_iterator(C.cbegin_ntc(), C.cend_ntc()); - }) - .def("quotient_froidure_pin", &Congruence::quotient_froidure_pin); + // gapbind14::class_("Congruence") + // .def(gapbind14::init + // const&>{}, + // "make_from_froidurepin_bipartition") + // .def(gapbind14::init> const&>{}, + // "make_from_froidurepin_bmat") + // .def(gapbind14::init const&>{}, + // "make_from_froidurepin_bmat8") + // .def(gapbind14::init const&>{}, + // "make_from_froidurepin_pbr") + // #ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED + // .def(gapbind14::init> const&>{}, + // "make_from_froidurepin_leastpperm") + // .def(gapbind14::init> const&>{}, + // "make_from_froidurepin_leasttransf") + // #endif + // .def(gapbind14::init> const&>{}, + // "make_from_froidurepin_transfUInt2") + // .def(gapbind14::init> const&>{}, + // "make_from_froidurepin_transfUInt4") + // .def(gapbind14::init> const&>{}, + // "make_from_froidurepin_ppermUInt2") + // .def(gapbind14::init> const&>{}, + // "make_from_froidurepin_ppermUInt4") + // .def(gapbind14::init{}, + // "make_from_fpsemigroup") + // .def(gapbind14::init>{}, + // "make_from_froidurepinbase") + // .def(gapbind14::init{}, + // "make_from_table") + // .def("set_number_of_generators", + // &Congruence::set_number_of_generators) .def("number_of_pairs", + // &Congruence::number_of_generating_pairs) .def("add_pair", + // overload_cast( + // &Congruence::add_pair)) + // .def("number_of_classes", &Congruence::number_of_classes) + // .def("word_to_class_index", &Congruence::word_to_class_index) + // .def("class_index_to_word", &Congruence::class_index_to_word) + // .def("contains", &Congruence::contains) + // .def("less", &Congruence::less) + // .def("add_runner", + // &Congruence::add_runner) + // .def("is_quotient_obviously_infinite", + // &Congruence::is_quotient_obviously_infinite) + // .def("ntc", + // [](Congruence& C) { + // return gapbind14::make_iterator(C.cbegin_ntc(), C.cend_ntc()); + // }) + // .def("quotient_froidure_pin", &Congruence::quotient_froidure_pin); } diff --git a/src/conglatt.cpp b/src/conglatt.cpp index 6752f0303..1a7c74991 100644 --- a/src/conglatt.cpp +++ b/src/conglatt.cpp @@ -42,8 +42,8 @@ // libsemigroups headers #include "libsemigroups/adapters.hpp" // for Hash -#include "libsemigroups/report.hpp" // for should_report -#include "libsemigroups/string.hpp" // for group_digits +#include "libsemigroups/detail/report.hpp" // for should_report +#include "libsemigroups/detail/string.hpp" // for group_digits // namespace semigroups { @@ -215,7 +215,7 @@ namespace semigroups { auto start_time = std::chrono::high_resolution_clock::now(); auto last_report = start_time; uint32_t last_count = 1; - bool report = libsemigroups::report::should_report(); + bool report = libsemigroups::reporting_enabled(); std::vector gens; gens.reserve(LEN_LIST(list)); diff --git a/src/froidure-pin-base.cpp b/src/froidure-pin-base.cpp index 1e01da412..82b254e24 100644 --- a/src/froidure-pin-base.cpp +++ b/src/froidure-pin-base.cpp @@ -46,16 +46,20 @@ void init_froidure_pin_base(gapbind14::Module& m) { return S->right_cayley_graph(); }) .def("factorisation", - [](FroidurePin_ S, size_t i) { return S->factorisation(i); }) + [](FroidurePin_ S, size_t i) { + return libsemigroups::froidure_pin::factorisation(*S, i); + }) .def("minimal_factorisation", - [](FroidurePin_ S, size_t i) { return S->minimal_factorisation(i); }) + [](FroidurePin_ S, size_t i) { + return libsemigroups::froidure_pin::minimal_factorisation(*S, i); + }) .def("product_by_reduction", [](FroidurePin_ S, size_t i, size_t j) { - return S->product_by_reduction(i, j); + return libsemigroups::froidure_pin::product_by_reduction(*S, i, j); }) .def("current_position", [](FroidurePin_ S, libsemigroups::word_type const& w) { - return S->current_position(w); + return libsemigroups::froidure_pin::current_position(*S, w); }) .def("current_size", [](FroidurePin_ S) { return S->current_size(); }) .def("size", [](FroidurePin_ S) { return S->size(); }) diff --git a/src/froidure-pin-fallback.cpp b/src/froidure-pin-fallback.cpp index d61965562..a7b5e0f0d 100644 --- a/src/froidure-pin-fallback.cpp +++ b/src/froidure-pin-fallback.cpp @@ -32,8 +32,8 @@ #include "semigroups-debug.hpp" // for SEMIGROUPS_ASSERT // libsemigroups headers -#include "libsemigroups/report.hpp" // for REPORTER, Reporter -#include "libsemigroups/timer.hpp" // for Timer +#include "libsemigroups/detail/report.hpp" // for REPORTER, Reporter +#include "libsemigroups/detail/timer.hpp" // for Timer using libsemigroups::detail::Timer; diff --git a/src/froidure-pin.hpp b/src/froidure-pin.hpp index d77c1bcec..5d94af043 100644 --- a/src/froidure-pin.hpp +++ b/src/froidure-pin.hpp @@ -20,7 +20,6 @@ #define SEMIGROUPS_SRC_FROIDURE_PIN_HPP_ #include // for size_t -#include // for shared_ptr #include // for string #include // for true_type #include // for pair @@ -62,26 +61,33 @@ void bind_froidure_pin(gapbind14::Module& m, std::string name) { gapbind14::class_(name) .def(gapbind14::init<>{}, "make") .def(gapbind14::init{}, "copy") - .def("add_generator", &FroidurePin_::add_generator) + .def("add_generator", + [](FroidurePin_& S, element_type const& x) { + return S.add_generator(x); + }) .def("generator", &FroidurePin_::generator) .def("closure", - &FroidurePin_::template closure>) + [](FroidurePin_& S, std::vector const& gens) { + return libsemigroups::froidure_pin::closure(S, gens); + }) .def("number_of_generators", &FroidurePin_::number_of_generators) .def("size", &FroidurePin_::size) .def("at", &FroidurePin_::at) .def("sorted_at", &FroidurePin_::sorted_at) .def("current_position", - gapbind14::overload_cast( - &FroidurePin_::current_position)) + [](FroidurePin_& S, const_reference x) { + return S.current_position(x); + }) .def("sorted_position", &FroidurePin_::sorted_position) .def("number_of_idempotents", &FroidurePin_::number_of_idempotents) .def("enumerate", &FroidurePin_::enumerate) .def("left_cayley_graph", &FroidurePin_::left_cayley_graph) .def("right_cayley_graph", &FroidurePin_::right_cayley_graph) .def("factorisation", - gapbind14::overload_cast(&FroidurePin_::factorisation)) - .def("position_to_sorted_position", - &FroidurePin_::position_to_sorted_position) + [](FroidurePin_& S, size_t i) { + return libsemigroups::froidure_pin::factorisation(S, i); + }) + .def("to_sorted_position", &FroidurePin_::to_sorted_position) .def("fast_product", &FroidurePin_::fast_product) .def("is_idempotent", &FroidurePin_::is_idempotent) .def("finished", &FroidurePin_::finished) diff --git a/src/pkg.cpp b/src/pkg.cpp index 206c4b1e9..63848a838 100644 --- a/src/pkg.cpp +++ b/src/pkg.cpp @@ -51,18 +51,16 @@ #include "gapbind14/gapbind14.hpp" // for class_, InstallGlobalFunction // libsemigroups headers -#include "libsemigroups/bipart.hpp" // for Blocks, Bipartition -#include "libsemigroups/cong-intf.hpp" // for congruence_kind -#include "libsemigroups/digraph.hpp" // for ActionDigraph -#include "libsemigroups/fpsemi.hpp" // for FpSemigroup -#include "libsemigroups/freeband.hpp" // for freeband_equal_to -#include "libsemigroups/report.hpp" // for REPORTER, Reporter -#include "libsemigroups/sims1.hpp" // for Sims1 -#include "libsemigroups/todd-coxeter.hpp" // for ToddCoxeter, ToddCoxeter::table_type -#include "libsemigroups/types.hpp" // for word_type, letter_type - #include "libsemigroups/adapters.hpp" -#include "libsemigroups/uf.hpp" +#include "libsemigroups/bipart.hpp" // for Blocks, Bipartition +#include "libsemigroups/freeband.hpp" // for freeband_equal_to +#include "libsemigroups/presentation.hpp" // for Presentation +#include "libsemigroups/sims.hpp" // for Sims1 +#include "libsemigroups/todd-coxeter.hpp" // for ToddCoxeter, ToddCoxeter::word_graph_type +#include "libsemigroups/types.hpp" // for word_type, letter_type +#include "libsemigroups/word-graph.hpp" // for WordGraph + +#include "libsemigroups/detail/report.hpp" // for REPORTER, Reporter using libsemigroups::Bipartition; using libsemigroups::Blocks; @@ -70,22 +68,16 @@ using libsemigroups::Blocks; using libsemigroups::Hash; using libsemigroups::detail::Duf; -namespace { - void set_report(bool const val) { - libsemigroups::REPORTER.report(val); - } -} // namespace - namespace gapbind14 { template <> struct IsGapBind14Type> : std::true_type {}; template <> - struct IsGapBind14Type> : std::true_type {}; + struct IsGapBind14Type : std::true_type {}; template <> - struct IsGapBind14Type::iterator> + struct IsGapBind14Type : std::true_type {}; template <> @@ -97,9 +89,9 @@ GAPBIND14_MODULE(libsemigroups) { // Free functions //////////////////////////////////////////////////////////////////////// - gapbind14::InstallGlobalFunction("set_report", &set_report); - gapbind14::InstallGlobalFunction("should_report", - &libsemigroups::report::should_report); + // gapbind14::InstallGlobalFunction("set_report", &set_report); + gapbind14::InstallGlobalFunction("reporting_enabled", + &libsemigroups::reporting_enabled); gapbind14::InstallGlobalFunction("hardware_concurrency", &std::thread::hardware_concurrency); gapbind14::InstallGlobalFunction( @@ -127,37 +119,20 @@ GAPBIND14_MODULE(libsemigroups) { init_cong(gapbind14::module()); //////////////////////////////////////////////////////////////////////// - // FpSemigroup + // ToddCoxeter //////////////////////////////////////////////////////////////////////// - using libsemigroups::FpSemigroup; using libsemigroups::word_type; - gapbind14::class_("FpSemigroup") - .def(gapbind14::init<>{}) - .def("set_alphabet", - gapbind14::overload_cast(&FpSemigroup::set_alphabet)) - .def("add_rule", - gapbind14::overload_cast( - &FpSemigroup::add_rule)) - .def("set_identity", - gapbind14::overload_cast( - &FpSemigroup::set_identity)); - - //////////////////////////////////////////////////////////////////////// - // ToddCoxeter - //////////////////////////////////////////////////////////////////////// - using libsemigroups::congruence_kind; - using libsemigroups::congruence::ToddCoxeter; - using table_type = libsemigroups::congruence::ToddCoxeter::table_type; + using libsemigroups::Presentation; + using libsemigroups::ToddCoxeter; - gapbind14::class_("ToddCoxeter") - .def(gapbind14::init{}) - .def("set_number_of_generators", &ToddCoxeter::set_number_of_generators) - .def("number_of_generators", &ToddCoxeter::number_of_generators) - .def("prefill", - gapbind14::overload_cast(&ToddCoxeter::prefill)); + using word_graph_type + = libsemigroups::ToddCoxeter::word_graph_type; + + gapbind14::class_>("ToddCoxeter") + .def(gapbind14::init>{}); using libsemigroups::Presentation; @@ -177,7 +152,8 @@ GAPBIND14_MODULE(libsemigroups) { [](Presentation& thing, bool val) -> void { thing.contains_empty_word(val); }) - .def("validate", &Presentation::validate) + .def("throw_if_bad_alphabet_or_rules", + &Presentation::throw_if_bad_alphabet_or_rules) .def("number_of_rules", [](Presentation const& thing) -> size_t { return thing.rules.size(); @@ -192,40 +168,27 @@ GAPBIND14_MODULE(libsemigroups) { using libsemigroups::Sims1; - gapbind14::class_::iterator>("Sims1Iterator") - .def("increment", [](typename Sims1::iterator& it) { ++it; }) - .def("deref", - [](typename Sims1::iterator const& it) { return *it; }); + gapbind14::class_("Sims1Iterator") + .def("increment", [](typename Sims1::iterator& it) { ++it; }) + .def("deref", [](typename Sims1::iterator const& it) { return *it; }); - gapbind14::class_>("Sims1") - .def(gapbind14::init{}, "make") - .def("short_rules", - [](Sims1& s, Presentation const& p) { - s.short_rules(p); - }) - .def("extra", - [](Sims1& s, Presentation const& p) { - s.extra(p); - }) + gapbind14::class_("Sims1") + .def(gapbind14::init>{}, "make") .def("number_of_threads", - [](Sims1& s, size_t val) { s.number_of_threads(val); }) - .def("number_of_congruences", &Sims1::number_of_congruences) - .def("cbegin", &Sims1::cbegin); + [](Sims1& s, size_t val) { s.number_of_threads(val); }) + .def("number_of_congruences", &Sims1::number_of_congruences) + .def("cbegin", &Sims1::cbegin); using libsemigroups::RepOrc; gapbind14::class_("RepOrc") .def(gapbind14::init<>{}, "make") - .def("short_rules", - [](RepOrc& ro, Presentation const& p) { - ro.short_rules(p); - }) .def("number_of_threads", [](RepOrc& ro, size_t val) { ro.number_of_threads(val); }) .def("max_nodes", [](RepOrc& ro, size_t val) { ro.max_nodes(val); }) .def("min_nodes", [](RepOrc& ro, size_t val) { ro.min_nodes(val); }) .def("target_size", [](RepOrc& ro, size_t val) { ro.target_size(val); }) - .def("digraph", &RepOrc::digraph); + .def("word_graph", &RepOrc::word_graph); } //////////////////////////////////////////////////////////////////////// @@ -324,10 +287,10 @@ void TBlocksObjLoadFunc(Obj o) { Blocks* blocks = new Blocks(deg); for (size_t i = 0; i < deg; i++) { - blocks->set_block(i, LoadUInt4()); + blocks->block(i, LoadUInt4()); } for (size_t i = 0; i < nr_blocks; i++) { - blocks->set_is_transverse_block(i, static_cast(LoadUInt1())); + blocks->is_transverse_block(i, static_cast(LoadUInt1())); } #ifdef SEMIGROUPS_KERNEL_DEBUG libsemigroups::validate(*blocks); @@ -597,7 +560,7 @@ static Int InitKernel(StructInitInfo* module) { } static Int PostRestore(StructInitInfo* module) { - set_report(false); + // TODO set_report(false); return 0; } diff --git a/src/pkg.hpp b/src/pkg.hpp index ae469533f..113db6b63 100644 --- a/src/pkg.hpp +++ b/src/pkg.hpp @@ -33,6 +33,9 @@ #include "gapbind14/gapbind14.hpp" +#include "libsemigroups/todd-coxeter.hpp" // for ToddCoxeter +#include "libsemigroups/types.hpp" // for word_type + extern UInt T_BIPART; extern UInt T_BLOCKS; @@ -75,19 +78,10 @@ extern Obj Integers; extern Obj NrRows; extern Obj Matrix; -namespace libsemigroups { - class FpSemigroup; - namespace congruence { - class ToddCoxeter; - } -} // namespace libsemigroups - namespace gapbind14 { - template <> - struct IsGapBind14Type : std::true_type {}; template <> - struct IsGapBind14Type + struct IsGapBind14Type> : std::true_type {}; } // namespace gapbind14 diff --git a/src/to_cpp.hpp b/src/to_cpp.hpp index 55bfac79b..7473d5fe9 100644 --- a/src/to_cpp.hpp +++ b/src/to_cpp.hpp @@ -49,15 +49,16 @@ #include "gapbind14/to_gap.hpp" // for gap_tnum_type // libsemigroups headers -#include "libsemigroups/adapters.hpp" // for Degree -#include "libsemigroups/bmat8.hpp" // for BMat8 -#include "libsemigroups/cong.hpp" // for Congruence -#include "libsemigroups/constants.hpp" // for NegativeInfinity, PositiveIn... -#include "libsemigroups/containers.hpp" // for DynamicArray2 -#include "libsemigroups/matrix.hpp" // for NTPMat, MaxPlusTruncMat, Min... -#include "libsemigroups/pbr.hpp" // for PBR -#include "libsemigroups/transf.hpp" // for PPerm, Transf, IsPPerm -#include "libsemigroups/types.hpp" // for congruence_kind, congruence_... +#include "libsemigroups/adapters.hpp" // for Degree +#include "libsemigroups/bmat8.hpp" // for BMat8 +#include "libsemigroups/cong.hpp" // for Congruence +#include "libsemigroups/constants.hpp" // for NegativeInfinity, PositiveIn... +#include "libsemigroups/matrix.hpp" // for NTPMat, MaxPlusTruncMat, Min... +#include "libsemigroups/pbr.hpp" // for PBR +#include "libsemigroups/transf.hpp" // for PPerm, Transf, IsPPerm +#include "libsemigroups/types.hpp" // for congruence_kind, congruence_... + +#include "libsemigroups/detail/containers.hpp" // for DynamicArray2 namespace libsemigroups { class Bipartition; @@ -171,7 +172,6 @@ namespace gapbind14 { } } } - GAPBIND14_TRY(libsemigroups::validate(x)); return x; } }; @@ -199,7 +199,7 @@ namespace gapbind14 { } for (size_t j = 0; j < m; j++) { if (ELM_BLIST(row, j + 1) == True) { - x.set(i, j, 1); + x(i, j) = 1; } } } @@ -251,7 +251,7 @@ namespace gapbind14 { x(i, j) = itm; } } - GAPBIND14_TRY(libsemigroups::validate(x)); + // TODO GAPBIND14_TRY(libsemigroups::validate(x)); return x; } } // namespace detail @@ -282,7 +282,7 @@ namespace gapbind14 { ELM_MAT(o, INTOBJ_INT(i + 1), INTOBJ_INT(j + 1))); } } - GAPBIND14_TRY(libsemigroups::validate(x)); + // TODO GAPBIND14_TRY(libsemigroups::validate(x)); return x; } }; @@ -388,15 +388,13 @@ namespace gapbind14 { static gap_tnum_type constexpr gap_type = T_STRING; cpp_type operator()(Obj o) const { - if (!IS_STRING_REP(o)) { + if (TNUM_OBJ(o) != T_STRING && TNUM_OBJ(o) != T_STRING + IMMUTABLE) { ErrorQuit("expected string but got %s!", (Int) TNAM_OBJ(o), 0L); } std::string stype = std::string(CSTR_STRING(o)); - if (stype == "left") { - return congruence_kind::left; - } else if (stype == "right") { - return congruence_kind::right; - } else if (stype == "2-sided") { + if (stype == "onesided") { + return congruence_kind::onesided; + } else if (stype == "twosided") { return congruence_kind::twosided; } else { ErrorQuit("Unrecognised type %s", (Int) stype.c_str(), 0L); @@ -405,20 +403,23 @@ namespace gapbind14 { }; template <> - struct to_cpp { - using cpp_type = libsemigroups::Congruence::options::runners; + struct to_cpp { + using cpp_type = libsemigroups::Order; + static gap_tnum_type constexpr gap_type = T_STRING; cpp_type operator()(Obj o) const { - if (!IS_STRING_REP(o)) { + using Order = libsemigroups::Order; + if (TNUM_OBJ(o) != T_STRING && TNUM_OBJ(o) != T_STRING + IMMUTABLE) { ErrorQuit("expected string but got %s!", (Int) TNAM_OBJ(o), 0L); } - std::string stype = std::string(CSTR_STRING(o)); - if (stype == "none") { - return cpp_type::none; - } else if (stype == "standard") { - return cpp_type::standard; + std::string_view stype = CSTR_STRING(o); + if (stype == "shortlex") { + return Order::shortlex; + } else if (stype == "lex") { + return Order::lex; + // TODO the other cases } else { - ErrorQuit("Unrecognised type %s", (Int) stype.c_str(), 0L); + ErrorQuit("Unrecognised type %s", (Int) stype.begin(), 0L); } } }; diff --git a/src/to_gap.hpp b/src/to_gap.hpp index 6206b5910..b13a73717 100644 --- a/src/to_gap.hpp +++ b/src/to_gap.hpp @@ -41,18 +41,18 @@ #include "semigroups-debug.hpp" // for SEMIGROUPS_ASSERT // gapbind14 headers -#include "gapbind14/gapbind14.hpp" // for gapbind14 +#include "gapbind14/to_gap.hpp" // for gapbind14 // libsemigroups headers -#include "libsemigroups/adapters.hpp" // for Degree -#include "libsemigroups/bipart.hpp" // for Bipartition, IsBipartition -#include "libsemigroups/bmat8.hpp" // for BMat8 -#include "libsemigroups/config.hpp" // for LIBSEMIGROUPS_HPCOMBI_ENABLED -#include "libsemigroups/constants.hpp" // for NEGATIVE_INFINITY etc -#include "libsemigroups/digraph.hpp" // for ActionDigraph -#include "libsemigroups/matrix.hpp" // for matrix_threshold etc -#include "libsemigroups/pbr.hpp" // for PBR -#include "libsemigroups/transf.hpp" // for IsPPerm, IsTransf +#include "libsemigroups/adapters.hpp" // for Degree +#include "libsemigroups/bipart.hpp" // for Bipartition, IsBipartition +#include "libsemigroups/bmat8.hpp" // for BMat8 +#include "libsemigroups/config.hpp" // for LIBSEMIGROUPS_HPCOMBI_ENABLED +#include "libsemigroups/constants.hpp" // for NEGATIVE_INFINITY etc +#include "libsemigroups/matrix.hpp" // for matrix_threshold etc +#include "libsemigroups/pbr.hpp" // for PBR +#include "libsemigroups/transf.hpp" // for IsPPerm, IsTransf +#include "libsemigroups/word-graph.hpp" // for WordGraph using libsemigroups::IsBMat; using libsemigroups::IsIntMat; @@ -169,7 +169,7 @@ namespace gapbind14 { Obj blist = NewBag(T_BLIST, SIZE_PLEN_BLIST(n)); SET_LEN_BLIST(blist, n); for (size_t j = 0; j < n; j++) { - if (x.first.get(i, j)) { + if (x.first(i, j)) { SET_BIT_BLIST(blist, j + 1); } } @@ -241,7 +241,7 @@ namespace gapbind14 { struct to_gap> { using MaxPlusTruncMat_ = libsemigroups::MaxPlusTruncMat<>; Obj operator()(MaxPlusTruncMat_ const& x) { - using libsemigroups::matrix_threshold; + using libsemigroups::matrix::threshold; using scalar_type = typename MaxPlusTruncMat_::scalar_type; auto result = detail::make_matrix( @@ -249,9 +249,8 @@ namespace gapbind14 { return (y == NEGATIVE_INFINITY ? to_gap()(y) : to_gap()(y)); }); - SET_ELM_PLIST(result, - x.number_of_rows() + 1, - to_gap()(matrix_threshold(x))); + SET_ELM_PLIST( + result, x.number_of_rows() + 1, to_gap()(threshold(x))); return result; } }; @@ -265,7 +264,7 @@ namespace gapbind14 { using MinPlusTruncMat_ = libsemigroups::MinPlusTruncMat<>; Obj operator()(MinPlusTruncMat_ const& x) { - using libsemigroups::matrix_threshold; + using libsemigroups::matrix::threshold; using scalar_type = typename MinPlusTruncMat_::scalar_type; auto result = detail::make_matrix( @@ -273,9 +272,8 @@ namespace gapbind14 { return (y == POSITIVE_INFINITY ? to_gap()(y) : to_gap()(y)); }); - SET_ELM_PLIST(result, - x.number_of_rows() + 1, - to_gap()(matrix_threshold(x))); + SET_ELM_PLIST( + result, x.number_of_rows() + 1, to_gap()(threshold(x))); return result; } }; @@ -309,16 +307,14 @@ namespace gapbind14 { Obj operator()(NTPMat_ const& x) { using scalar_type = typename NTPMat_::scalar_type; - using libsemigroups::matrix_period; - using libsemigroups::matrix_threshold; + using libsemigroups::matrix::period; + using libsemigroups::matrix::threshold; auto result = detail::make_matrix(x, NTPMatrixType, 2); - SET_ELM_PLIST(result, - x.number_of_rows() + 1, - to_gap()(matrix_threshold(x))); - SET_ELM_PLIST(result, - x.number_of_rows() + 2, - to_gap()(matrix_period(x))); + SET_ELM_PLIST( + result, x.number_of_rows() + 1, to_gap()(threshold(x))); + SET_ELM_PLIST( + result, x.number_of_rows() + 2, to_gap()(period(x))); return result; } }; @@ -515,24 +511,24 @@ namespace gapbind14 { }; //////////////////////////////////////////////////////////////////////// - // ActionDigraph + // WordGraph //////////////////////////////////////////////////////////////////////// template - struct to_gap> { - using ActionDigraph_ = libsemigroups::ActionDigraph; - Obj operator()(ActionDigraph_ const& ad) const noexcept { - using node_type = typename ActionDigraph_::node_type; + struct to_gap> { + using WordGraph_ = libsemigroups::WordGraph; + Obj operator()(WordGraph_ const& ad) const noexcept { + using node_type = typename WordGraph_::node_type; Obj result = NEW_PLIST(T_PLIST, ad.number_of_nodes()); // this is intentionally not IMMUTABLE - // TODO(ActionDigraph) handle case of zero nodes? + // TODO(WordGraph) handle case of zero nodes? SET_LEN_PLIST(result, ad.number_of_nodes()); for (size_t i = 0; i < ad.number_of_nodes(); ++i) { Obj next = NEW_PLIST(T_PLIST, 0); SET_LEN_PLIST(next, 0); for (size_t j = 0; j < ad.out_degree(); ++j) { - auto val = ad.unsafe_neighbor(i, j); + auto val = ad.target_no_checks(i, j); if (val != UNDEFINED) { AssPlist(next, j + 1, to_gap()(val + 1)); } @@ -544,5 +540,23 @@ namespace gapbind14 { } }; + // TODO could use magic_enum and make this generic + template <> + struct to_gap { + Obj operator()(libsemigroups::Order const& val) const noexcept { + using order = libsemigroups::Order; + switch (val) { + case order::shortlex: + return to_gap()("shortlex"); + case order::lex: + return to_gap()("lex"); + case order::none: + return to_gap()("none"); + case order::recursive: + return to_gap()("recursive"); + } + } + }; + } // namespace gapbind14 #endif // SEMIGROUPS_SRC_TO_GAP_HPP_ From e4848b76f1fe746f761ac5f37e63168ade4f6130 Mon Sep 17 00:00:00 2001 From: "James D. Mitchell" Date: Tue, 8 Apr 2025 10:54:37 +0200 Subject: [PATCH 2/7] More --- src/cong.cpp | 97 ++-------------------------------------------------- src/cong.hpp | 1 + src/pkg.cpp | 44 ++++++++++++++++++++++-- 3 files changed, 45 insertions(+), 97 deletions(-) diff --git a/src/cong.cpp b/src/cong.cpp index 3001f7b3d..625194c0c 100644 --- a/src/cong.cpp +++ b/src/cong.cpp @@ -36,21 +36,10 @@ #include "gapbind14/gapbind14.hpp" // for class_ etc // libsemigroups headers -#include "libsemigroups/bipart.hpp" // for Bipartition #include "libsemigroups/cong.hpp" // for Congruence -#include "libsemigroups/constants.hpp" // for UNDEFINED etc -#include "libsemigroups/froidure-pin.hpp" // for FroidurePin -#include "libsemigroups/matrix.hpp" // for BMat etc -#include "libsemigroups/todd-coxeter.hpp" // for ToddCoxeter -#include "libsemigroups/transf.hpp" // for PPerm etc +#include "libsemigroups/presentation.hpp" // for Presentation #include "libsemigroups/types.hpp" // for word_type -// Forward decls -namespace libsemigroups { - class FpSemigroup; - class PBR; -} // namespace libsemigroups - namespace gapbind14 { template <> struct IsGapBind14Type> @@ -60,91 +49,11 @@ namespace gapbind14 { } // namespace gapbind14 +// TODO rm this file //////////////////////////////////////////////////////////////////////// // Congruence //////////////////////////////////////////////////////////////////////// using gapbind14::overload_cast; -void init_cong(gapbind14::Module& m) { - using libsemigroups::Congruence; - using libsemigroups::congruence_kind; - using libsemigroups::FpSemigroup; - using libsemigroups::FroidurePin; - using libsemigroups::FroidurePinBase; - using libsemigroups::word_type; - - using libsemigroups::Bipartition; - using libsemigroups::BMat; - using libsemigroups::IntMat; - using libsemigroups::LeastPPerm; - using libsemigroups::LeastTransf; - using libsemigroups::MaxPlusMat; - using libsemigroups::MaxPlusTruncMat; - using libsemigroups::MinPlusMat; - using libsemigroups::MinPlusTruncMat; - using libsemigroups::NTPMat; - using libsemigroups::PBR; - using libsemigroups::PPerm; - using libsemigroups::ProjMaxPlusMat; - using libsemigroups::Transf; - - // Cannot use FroidurePinBase rather than the specialisations because there's - // no constructor for a Congruence from a FroidurePinBase&. - // gapbind14::class_("Congruence") - // .def(gapbind14::init - // const&>{}, - // "make_from_froidurepin_bipartition") - // .def(gapbind14::init> const&>{}, - // "make_from_froidurepin_bmat") - // .def(gapbind14::init const&>{}, - // "make_from_froidurepin_bmat8") - // .def(gapbind14::init const&>{}, - // "make_from_froidurepin_pbr") - // #ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED - // .def(gapbind14::init> const&>{}, - // "make_from_froidurepin_leastpperm") - // .def(gapbind14::init> const&>{}, - // "make_from_froidurepin_leasttransf") - // #endif - // .def(gapbind14::init> const&>{}, - // "make_from_froidurepin_transfUInt2") - // .def(gapbind14::init> const&>{}, - // "make_from_froidurepin_transfUInt4") - // .def(gapbind14::init> const&>{}, - // "make_from_froidurepin_ppermUInt2") - // .def(gapbind14::init> const&>{}, - // "make_from_froidurepin_ppermUInt4") - // .def(gapbind14::init{}, - // "make_from_fpsemigroup") - // .def(gapbind14::init>{}, - // "make_from_froidurepinbase") - // .def(gapbind14::init{}, - // "make_from_table") - // .def("set_number_of_generators", - // &Congruence::set_number_of_generators) .def("number_of_pairs", - // &Congruence::number_of_generating_pairs) .def("add_pair", - // overload_cast( - // &Congruence::add_pair)) - // .def("number_of_classes", &Congruence::number_of_classes) - // .def("word_to_class_index", &Congruence::word_to_class_index) - // .def("class_index_to_word", &Congruence::class_index_to_word) - // .def("contains", &Congruence::contains) - // .def("less", &Congruence::less) - // .def("add_runner", - // &Congruence::add_runner) - // .def("is_quotient_obviously_infinite", - // &Congruence::is_quotient_obviously_infinite) - // .def("ntc", - // [](Congruence& C) { - // return gapbind14::make_iterator(C.cbegin_ntc(), C.cend_ntc()); - // }) - // .def("quotient_froidure_pin", &Congruence::quotient_froidure_pin); -} +void init_cong(gapbind14::Module& m) {} diff --git a/src/cong.hpp b/src/cong.hpp index ce6cd4cc3..f5862b8cc 100644 --- a/src/cong.hpp +++ b/src/cong.hpp @@ -1,4 +1,5 @@ // +// TODO rm this file // Semigroups package for GAP // Copyright (C) 2021 James D. Mitchell // diff --git a/src/pkg.cpp b/src/pkg.cpp index 63848a838..6fa6fb3d3 100644 --- a/src/pkg.cpp +++ b/src/pkg.cpp @@ -65,14 +65,22 @@ using libsemigroups::Bipartition; using libsemigroups::Blocks; -using libsemigroups::Hash; -using libsemigroups::detail::Duf; +namespace { + void LIBSEMIGROUPS_REPORTING_ENABLED(bool const val) { + static std::unique_ptr rg; + rg = std::make_unique(val); + } +} // namespace namespace gapbind14 { template <> struct IsGapBind14Type> : std::true_type {}; + template <> + struct IsGapBind14Type> + : std::true_type {}; + template <> struct IsGapBind14Type : std::true_type {}; @@ -89,7 +97,8 @@ GAPBIND14_MODULE(libsemigroups) { // Free functions //////////////////////////////////////////////////////////////////////// - // gapbind14::InstallGlobalFunction("set_report", &set_report); + gapbind14::InstallGlobalFunction("set_report", + &LIBSEMIGROUPS_REPORTING_ENABLED); gapbind14::InstallGlobalFunction("reporting_enabled", &libsemigroups::reporting_enabled); gapbind14::InstallGlobalFunction("hardware_concurrency", @@ -189,6 +198,35 @@ GAPBIND14_MODULE(libsemigroups) { .def("min_nodes", [](RepOrc& ro, size_t val) { ro.min_nodes(val); }) .def("target_size", [](RepOrc& ro, size_t val) { ro.target_size(val); }) .def("word_graph", &RepOrc::word_graph); + + using libsemigroups::Congruence; + using libsemigroups::congruence_kind; + using libsemigroups::FroidurePinBase; + using libsemigroups::Presentation; + using libsemigroups::word_type; + + gapbind14::class_>("Congruence") + .def(gapbind14::init>{}, "make"); + // .def("number_of_generating_pairs", + // &Congruence::number_of_generating_pairs) + // .def("add_generating_pair", + // [](Congruence& self, + // word_type const& u, + // word_type const& v) { + // return libsemigroups::congruence::add_generating_pair(self, u, v); + // }) + // .def("number_of_classes", &Congruence::number_of_classes) + // // .def("index_of", &Congruence::word_to_class_index) + // // .def("word_of", &Congruence::class_index_to_word) + // .def("contains", + // [](Congruence& self, + // word_type const& u, + // word_type const& v) { + // return libsemigroups::congruence::contains(self, u, v); + // }); + // .def("non_trivial_classes", [](Congruence& C) { + // return gapbind14::make_iterator(C.cbegin_ntc(), C.cend_ntc()); + // }); } //////////////////////////////////////////////////////////////////////// From 31b80e412b9e403a1f25e98b2b0c8382782c995f Mon Sep 17 00:00:00 2001 From: Joseph Edwards Date: Tue, 2 Sep 2025 19:07:35 +0100 Subject: [PATCH 3/7] Add Presentation --- gap/libsemigroups/fpsemi.gd | 16 ------------ gap/libsemigroups/presentation.gd | 16 ++++++++++++ .../{fpsemi.gi => presentation.gi} | 26 ++++++++++--------- init.g | 2 +- read.g | 2 +- 5 files changed, 32 insertions(+), 30 deletions(-) delete mode 100644 gap/libsemigroups/fpsemi.gd create mode 100644 gap/libsemigroups/presentation.gd rename gap/libsemigroups/{fpsemi.gi => presentation.gi} (62%) diff --git a/gap/libsemigroups/fpsemi.gd b/gap/libsemigroups/fpsemi.gd deleted file mode 100644 index 2176a5db3..000000000 --- a/gap/libsemigroups/fpsemi.gd +++ /dev/null @@ -1,16 +0,0 @@ -############################################################################# -## -## libsemigroups/fpsemi.gd -## Copyright (C) 2022 James D. Mitchell -## -## Licensing information can be found in the README file of this package. -## -############################################################################# -## - -# This file exists to construct a libsemigroups FpSemigroup object for an fp -# semigroup or monoid. The resulting libsemigroups::FpSemigroup object is only -# used to initialize a libsemigroups::Congruence object where most questions -# asked about FpSemigroup/FpMonoids will be answered. - -DeclareGlobalFunction("LibsemigroupsFpSemigroup"); diff --git a/gap/libsemigroups/presentation.gd b/gap/libsemigroups/presentation.gd new file mode 100644 index 000000000..b66110b34 --- /dev/null +++ b/gap/libsemigroups/presentation.gd @@ -0,0 +1,16 @@ +############################################################################# +## +## libsemigroups/presentation.gd +## Copyright (C) 2025 Joseph Edwards +## +## Licensing information can be found in the README file of this package. +## +############################################################################# +## + +# This file exists to construct a libsemigroups Presentation object for an fp +# semigroup or monoid. The resulting libsemigroups::Presentation object is only +# used to initialize a libsemigroups::Congruence object where most questions +# asked about Presentation/FpMonoids will be answered. + +DeclareGlobalFunction("LibsemigroupsPresentation"); diff --git a/gap/libsemigroups/fpsemi.gi b/gap/libsemigroups/presentation.gi similarity index 62% rename from gap/libsemigroups/fpsemi.gi rename to gap/libsemigroups/presentation.gi index 59a02d02a..1708c6ebf 100644 --- a/gap/libsemigroups/fpsemi.gi +++ b/gap/libsemigroups/presentation.gi @@ -1,25 +1,25 @@ ############################################################################# ## -## libsemigroups/fpsemi.gi -## Copyright (C) 2022 James D. Mitchell +## libsemigroups/presentation.gi +## Copyright (C) 2025 Joseph Edwards ## ## Licensing information can be found in the README file of this package. ## ############################################################################# ## -InstallGlobalFunction("LibsemigroupsFpSemigroup", +InstallGlobalFunction("LibsemigroupsPresentation", function(S) local F, SS, R, add_rule, pair; Assert(1, IsFpSemigroup(S) or (HasIsFreeSemigroup(S) and IsFreeSemigroup(S)) or IsFpMonoid(S) or (HasIsFreeMonoid(S) and IsFreeMonoid(S))); - if IsBound(S!.LibsemigroupsFpSemigroup) - and IsValidGapbind14Object(S!.LibsemigroupsFpSemigroup) then - return S!.LibsemigroupsFpSemigroup; + if IsBound(S!.LibsemigroupsPresentation) + and IsValidGapbind14Object(S!.LibsemigroupsPresentation) then + return S!.LibsemigroupsPresentation; fi; - Unbind(S!.LibsemigroupsFpSemigroup); + Unbind(S!.LibsemigroupsPresentation); if IsFpSemigroup(S) then F := FreeSemigroupOfFpSemigroup(S); elif IsFpMonoid(S) then @@ -29,25 +29,27 @@ function(S) F := S; fi; - SS := libsemigroups.FpSemigroup.make(); - libsemigroups.FpSemigroup.set_alphabet(SS, Size(GeneratorsOfSemigroup(S))); + SS := libsemigroups.Presentation.make(); + libsemigroups.Presentation.set_alphabet_size( + SS, + Size(GeneratorsOfSemigroup(S))); if IsMonoid(S) then # The identity must be 0 so that this corresponds to what happens in # FroidurePin, where GeneratorsOfSemigroup(S) is used and the identity is # the first entry. - libsemigroups.FpSemigroup.set_identity(SS, 0); + libsemigroups.Presentation.set_identity(SS, 0); R := RelationsOfFpMonoid(S); else R := RelationsOfFpSemigroup(S); fi; - add_rule := libsemigroups.FpSemigroup.add_rule; + add_rule := libsemigroups.presentation_add_rule; for pair in R do add_rule(SS, Factorization(F, pair[1]) - 1, Factorization(F, pair[2]) - 1); od; - S!.LibsemigroupsFpSemigroup := SS; + S!.LibsemigroupsPresentation := SS; return SS; end); diff --git a/init.g b/init.g index 1c01899ef..e4b06391f 100644 --- a/init.g +++ b/init.g @@ -65,7 +65,7 @@ ReadPackage("semigroups", "gap/elements/pbr.gd"); ReadPackage("semigroups", "gap/elements/pperm.gd"); ReadPackage("semigroups", "gap/elements/trans.gd"); -ReadPackage("semigroups", "gap/libsemigroups/fpsemi.gd"); +ReadPackage("semigroups", "gap/libsemigroups/presentation.gd"); ReadPackage("semigroups", "gap/libsemigroups/froidure-pin.gd"); ReadPackage("semigroups", "gap/libsemigroups/sims1.gd"); diff --git a/read.g b/read.g index d189d3f46..04c85d468 100644 --- a/read.g +++ b/read.g @@ -26,7 +26,7 @@ ReadPackage("semigroups", "gap/elements/elements.gi"); ReadPackage("semigroups", "gap/elements/pperm.gi"); ReadPackage("semigroups", "gap/libsemigroups/cong.gi"); -ReadPackage("semigroups", "gap/libsemigroups/fpsemi.gi"); +ReadPackage("semigroups", "gap/libsemigroups/presentation.gi"); ReadPackage("semigroups", "gap/libsemigroups/froidure-pin.gi"); ReadPackage("semigroups", "gap/libsemigroups/sims1.gi"); From c1ba0b358366ddf777f30eb285775c1f2b6b7d25 Mon Sep 17 00:00:00 2001 From: Joseph Edwards Date: Tue, 2 Sep 2025 19:24:02 +0100 Subject: [PATCH 4/7] Update to_cpp congruence_kind --- src/to_cpp.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/to_cpp.hpp b/src/to_cpp.hpp index 7473d5fe9..e0ad3d413 100644 --- a/src/to_cpp.hpp +++ b/src/to_cpp.hpp @@ -392,12 +392,13 @@ namespace gapbind14 { ErrorQuit("expected string but got %s!", (Int) TNAM_OBJ(o), 0L); } std::string stype = std::string(CSTR_STRING(o)); - if (stype == "onesided") { + if (stype == "left" || stype == "right") { return congruence_kind::onesided; - } else if (stype == "twosided") { + } else if (stype == "2-sided") { return congruence_kind::twosided; } else { - ErrorQuit("Unrecognised type %s", (Int) stype.c_str(), 0L); + ErrorQuit( + "Unrecognised congruence_kind type %s", (Int) stype.c_str(), 0L); } } }; From a41af9beb8fa607c2dea839d7ec25db14dab846b Mon Sep 17 00:00:00 2001 From: Joseph Edwards Date: Tue, 2 Sep 2025 19:24:20 +0100 Subject: [PATCH 5/7] Add to_cpp for WordGraph --- gap/libsemigroups/froidure-pin.gi | 8 ++++--- src/pkg.cpp | 5 +++++ src/pkg.hpp | 6 +++++- src/to_cpp.hpp | 35 +++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/gap/libsemigroups/froidure-pin.gi b/gap/libsemigroups/froidure-pin.gi index 99a0f6cc8..b6e25a855 100644 --- a/gap/libsemigroups/froidure-pin.gi +++ b/gap/libsemigroups/froidure-pin.gi @@ -607,7 +607,7 @@ function(S) Error("the argument (a semigroup) is not finite"); fi; F := LibsemigroupsFroidurePin(S); - return FroidurePinMemFnRec(S).left_cayley_graph(F) + 1; + return FroidurePinMemFnRec(S).left_cayley_graph(F); end); InstallMethod(LeftCayleyDigraph, @@ -634,7 +634,9 @@ function(S) Error("the argument (a semigroup) is not finite"); fi; F := LibsemigroupsFroidurePin(S); - return FroidurePinMemFnRec(S).right_cayley_graph(F) + 1; + + # No need to add 1 here, since this is handled by to_gap + return FroidurePinMemFnRec(S).right_cayley_graph(F); end); InstallMethod(RightCayleyDigraph, @@ -821,7 +823,7 @@ function(S) product := FroidurePinMemFnRec(S).product_by_reduction; FroidurePinMemFnRec(S).enumerate(T, N + 1); else - pos_to_pos_sorted := FroidurePinMemFnRec(S).position_to_sorted_position; + pos_to_pos_sorted := FroidurePinMemFnRec(S).to_sorted_position; product := FroidurePinMemFnRec(S).fast_product; fi; for i in [0 .. N - 1] do diff --git a/src/pkg.cpp b/src/pkg.cpp index 6fa6fb3d3..1530fe2cb 100644 --- a/src/pkg.cpp +++ b/src/pkg.cpp @@ -392,6 +392,8 @@ Obj TYPES_PBR; Obj TYPE_PBR; Obj DegreeOfPBR; Obj LARGEST_MOVED_PT_TRANS; +Obj IsDigraph; +Obj OutNeighbours; Obj IsSemigroup; Obj IsMatrixObj; @@ -587,6 +589,9 @@ static Int InitKernel(StructInitInfo* module) { ImportGVarFromLibrary("LARGEST_MOVED_PT_TRANS", &LARGEST_MOVED_PT_TRANS); + ImportGVarFromLibrary("IsDigraph", &IsDigraph); + ImportGVarFromLibrary("OutNeighbours", &OutNeighbours); + ImportGVarFromLibrary("IsSemigroup", &IsSemigroup); ImportGVarFromLibrary("IsMatrixObj", &IsMatrixObj); ImportGVarFromLibrary("BaseDomain", &BaseDomain); diff --git a/src/pkg.hpp b/src/pkg.hpp index 113db6b63..b7d5eab9d 100644 --- a/src/pkg.hpp +++ b/src/pkg.hpp @@ -34,7 +34,7 @@ #include "gapbind14/gapbind14.hpp" #include "libsemigroups/todd-coxeter.hpp" // for ToddCoxeter -#include "libsemigroups/types.hpp" // for word_type +#include "libsemigroups/types.hpp" // for word_type, congruence_kind extern UInt T_BIPART; extern UInt T_BLOCKS; @@ -71,6 +71,10 @@ extern Obj TYPE_BIPART; extern Obj TYPES_BIPART; extern Obj LARGEST_MOVED_PT_TRANS; +extern Obj IsDigraph; +extern Obj DigraphNrVertices; +extern Obj OutNeighbours; + extern Obj IsSemigroup; extern Obj IsMatrixObj; extern Obj BaseDomain; diff --git a/src/to_cpp.hpp b/src/to_cpp.hpp index e0ad3d413..affe4e3df 100644 --- a/src/to_cpp.hpp +++ b/src/to_cpp.hpp @@ -93,6 +93,8 @@ using libsemigroups::UNDEFINED; using libsemigroups::detail::DynamicArray2; +using libsemigroups::WordGraph; + namespace semigroups { NTPSemiring<> const* semiring(size_t threshold, size_t period); @@ -738,5 +740,38 @@ namespace gapbind14 { return result; } }; + + //////////////////////////////////////////////////////////////////////// + // WordGraph + //////////////////////////////////////////////////////////////////////// + template + struct to_cpp> { + using cpp_type = WordGraph; + cpp_type operator()(Obj o) const { + if (CALL_1ARGS(IsDigraph, o) != True) { + ErrorQuit("expected a Digraph but got %s!", (Int) TNAM_OBJ(o), 0L); + } + Obj out_nbs = CALL_1ARGS(OutNeighbours, o); + size_t nr_vertices = LEN_LIST(out_nbs); + size_t out_degree + = (nr_vertices == 0 ? 0 : LEN_LIST(ELM_LIST(out_nbs, 1))); + + cpp_type result(nr_vertices, out_degree); + for (size_t s = 0; s < nr_vertices; ++s) { + Obj nbs = ELM_LIST(out_nbs, s + 1); + if (LEN_LIST(nbs) != out_degree) { + ErrorQuit("expected a digraph with constant out degree, but found " + "vertices with outdegree %d and %d", + (Int) LEN_LIST(nbs), + out_degree); + } + for (size_t a = 0; a < out_degree; ++a) { + size_t t = INT_INTOBJ(ELM_LIST(nbs, a + 1)) - 1; + result.target(s, a, t); + } + } + return result; + } + }; } // namespace gapbind14 #endif // SEMIGROUPS_SRC_TO_CPP_HPP_ From cb2708acc5454aa762595bab62dd3fca66662d58 Mon Sep 17 00:00:00 2001 From: Joseph Edwards Date: Tue, 2 Sep 2025 19:32:27 +0100 Subject: [PATCH 6/7] Remove congruence_make_from_... --- gap/libsemigroups/cong.gi | 75 +---------------------------- tst/standard/libsemigroups/cong.tst | 24 --------- tst/testinstall.tst | 28 ++++++----- 3 files changed, 16 insertions(+), 111 deletions(-) diff --git a/gap/libsemigroups/cong.gi b/gap/libsemigroups/cong.gi index 68c338e66..0b487df96 100644 --- a/gap/libsemigroups/cong.gi +++ b/gap/libsemigroups/cong.gi @@ -69,84 +69,11 @@ InstallTrueMethod(CanUseLibsemigroupsCongruence, # libsemigroups object directly ########################################################################### -DeclareAttribute("LibsemigroupsCongruenceConstructor", -IsSemigroup and CanUseLibsemigroupsCongruences); - -# Construct a libsemigroups::Congruence from some GAP object - -InstallMethod(LibsemigroupsCongruenceConstructor, -"for a transformation semigroup with CanUseLibsemigroupsCongruences", -[IsTransformationSemigroup and CanUseLibsemigroupsCongruences], -function(S) - local N; - N := DegreeOfTransformationSemigroup(S); - if N <= 16 and IsBound(LIBSEMIGROUPS_HPCOMBI_ENABLED) then - return libsemigroups.Congruence.make_from_froidurepin_leasttransf; - elif N <= 2 ^ 16 then - return libsemigroups.Congruence.make_from_froidurepin_transfUInt2; - elif N <= 2 ^ 32 then - return libsemigroups.Congruence.make_from_froidurepin_transfUInt4; - else - # Cannot currently test the next line - Error("transformation degree is too high!"); - fi; -end); - -InstallMethod(LibsemigroupsCongruenceConstructor, -"for a partial perm semigroup with CanUseLibsemigroupsCongruences", -[IsPartialPermSemigroup and CanUseLibsemigroupsCongruences], -function(S) - local N; - N := Maximum(DegreeOfPartialPermSemigroup(S), - CodegreeOfPartialPermSemigroup(S)); - if N <= 16 and IsBound(LIBSEMIGROUPS_HPCOMBI_ENABLED) then - return libsemigroups.Congruence.make_from_froidurepin_leastpperm; - elif N <= 2 ^ 16 then - return libsemigroups.Congruence.make_from_froidurepin_ppermUInt2; - elif N <= 2 ^ 32 then - return libsemigroups.Congruence.make_from_froidurepin_ppermUInt4; - else - # Cannot currently test the next line - Error("partial perm degree is too high!"); - fi; -end); - -InstallMethod(LibsemigroupsCongruenceConstructor, -"for a boolean matrix semigroup with CanUseLibsemigroupsCongruences", -[IsBooleanMatSemigroup and CanUseLibsemigroupsCongruences], -function(S) - if DimensionOfMatrixOverSemiring(Representative(S)) <= 8 then - return libsemigroups.Congruence.make_from_froidurepin_bmat8; - fi; - return libsemigroups.Congruence.make_from_froidurepin_bmat; -end); - -# Why does this work for types other than boolean matrices? -InstallMethod(LibsemigroupsCongruenceConstructor, -"for a matrix semigroup with CanUseLibsemigroupsCongruences", -[IsMatrixOverSemiringSemigroup and CanUseLibsemigroupsCongruences], -_ -> libsemigroups.Congruence.make_from_froidurepin_bmat); - -InstallMethod(LibsemigroupsCongruenceConstructor, -"for a bipartition semigroup with CanUseLibsemigroupsCongruences", -[IsBipartitionSemigroup and CanUseLibsemigroupsCongruences], -_ -> libsemigroups.Congruence.make_from_froidurepin_bipartition); - -InstallMethod(LibsemigroupsCongruenceConstructor, -"for a PBR semigroup and CanUseLibsemigroupsCongruences", -[IsPBRSemigroup and CanUseLibsemigroupsCongruences], -_ -> libsemigroups.Congruence.make_from_froidurepin_pbr); - -InstallMethod(LibsemigroupsCongruenceConstructor, -"for a quotient semigroup and CanUseLibsemigroupsCongruences", -[IsQuotientSemigroup and CanUseLibsemigroupsCongruences], -_ -> libsemigroups.Congruence.make_from_froidurepinbase); - # Get the libsemigroups::Congruence object associated to a GAP object BindGlobal("LibsemigroupsCongruence", function(C) - local S, make, CC, factor, N, tc, table, add_pair, pair; + local S, make, CC, factor, N, tc, cayley_digraph, add_generating_pair, pair; Assert(1, CanUseLibsemigroupsCongruence(C)); diff --git a/tst/standard/libsemigroups/cong.tst b/tst/standard/libsemigroups/cong.tst index b3cb1d4cb..c10059a13 100644 --- a/tst/standard/libsemigroups/cong.tst +++ b/tst/standard/libsemigroups/cong.tst @@ -18,69 +18,45 @@ gap> SEMIGROUPS.StartTest(); # LibsemigroupsCongruenceConstructor for transf. semigroup gap> S := Semigroup(Transformation([1, 1, 2])); -gap> LibsemigroupsCongruenceConstructor(S); -function( arg1, arg2 ) ... end gap> S := Semigroup(ConstantTransformation(17, 2)); -gap> LibsemigroupsCongruenceConstructor(S); -function( arg1, arg2 ) ... end gap> S := Semigroup(ConstantTransformation(65537, 2)); -gap> LibsemigroupsCongruenceConstructor(S); -function( arg1, arg2 ) ... end # LibsemigroupsCongruenceConstructor for pperm semigroup gap> S := Semigroup(PartialPerm([1, 2, 5])); -gap> LibsemigroupsCongruenceConstructor(S); -function( arg1, arg2 ) ... end gap> S := Semigroup(PartialPerm([1 .. 17])); -gap> LibsemigroupsCongruenceConstructor(S); -function( arg1, arg2 ) ... end gap> S := Semigroup(PartialPerm([1 .. 65537])); -gap> LibsemigroupsCongruenceConstructor(S); -function( arg1, arg2 ) ... end # LibsemigroupsCongruenceConstructor for a bmat semigroup gap> S := Semigroup(Matrix(IsBooleanMat, [[0, 0], [0, 0]]), > Matrix(IsBooleanMat, [[1, 1], [0, 1]])); -gap> LibsemigroupsCongruenceConstructor(S); -function( arg1, arg2 ) ... end gap> S := Semigroup( > Matrix(IsBooleanMat, [[0, 0, 0, 1, 1, 1, 0, 1, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0], > [0, 1, 0, 1, 0, 1, 0, 1, 0], [1, 0, 0, 0, 1, 1, 0, 0, 0], [1, 0, 0, 0, 1, 1, 0, 1, 1], > [0, 0, 1, 1, 1, 1, 1, 1, 1], [1, 1, 1, 1, 0, 0, 0, 1, 0], [0, 1, 1, 0, 0, 0, 1, 0, 0], > [1, 0, 0, 1, 1, 1, 1, 0, 1]])); -gap> LibsemigroupsCongruenceConstructor(S); -function( arg1, arg2 ) ... end # LibsemigroupsCongruenceConstructor for other matrix over semiring gap> S := Semigroup(Matrix(IsMinPlusMatrix, [[-2, 2], [0, -1]]), > Matrix(IsMinPlusMatrix, [[0, 0], [1, -3]])); -gap> LibsemigroupsCongruenceConstructor(S); -function( arg1, arg2 ) ... end gap> S := Semigroup(Matrix(IsMaxPlusMatrix, [[-2, 2], [0, -1]]), > Matrix(IsMaxPlusMatrix, [[0, 0], [1, -3]])); -gap> LibsemigroupsCongruenceConstructor(S); -function( arg1, arg2 ) ... end # LibsemigroupsCongruenceConstructor for bipartition semigroup gap> S := PartitionMonoid(2); -gap> LibsemigroupsCongruenceConstructor(S); -function( arg1, arg2 ) ... end # LibsemigroupsCongruenceConstructor for pbr semigroup gap> S := FullPBRMonoid(1); -gap> LibsemigroupsCongruenceConstructor(S); -function( arg1, arg2 ) ... end # LibsemigroupsCongruence for a congruence on a semigroup with CanUseLibsemigroupsFroidurePin gap> S := FullBooleanMatMonoid(2); diff --git a/tst/testinstall.tst b/tst/testinstall.tst index a44d7cba5..bd31a9d64 100644 --- a/tst/testinstall.tst +++ b/tst/testinstall.tst @@ -1769,19 +1769,21 @@ gap> NonTrivialEquivalenceClasses(cong); [ ] # Issue 680 -gap> F := FreeSemigroup(2);; -gap> s1 := F.1;; s2 := F.2;; -gap> rels := [[s2 * s1 * s2, s2 * s1], [s1, s1], [s2, s2], -> [s1 * s2, s1 * s2], [s2 * s1, s2 * s1]];; -gap> cong := SemigroupCongruence(F, rels); -<2-sided semigroup congruence over with 1 generating pairs> -gap> NrEquivalenceClasses(cong); -infinity -gap> EquivalenceRelationPartitionWithSingletons(cong); -Error, the argument (a congruence) must have finite range -gap> EquivalenceRelationLookup(cong); -Error, the argument (a 2-sided congruence) must have finite range +# TODO: Uncomment when libsemigroups is updated to check for obviously infinite +# Congruences +# gap> F := FreeSemigroup(2);; +# gap> s1 := F.1;; s2 := F.2;; +# gap> rels := [[s2 * s1 * s2, s2 * s1], [s1, s1], [s2, s2], +# > [s1 * s2, s1 * s2], [s2 * s1, s2 * s1]];; +# gap> cong := SemigroupCongruence(F, rels); +# <2-sided semigroup congruence over with 1 generating pairs> +# gap> NrEquivalenceClasses(cong); +# infinity +# gap> EquivalenceRelationPartitionWithSingletons(cong); +# Error, the argument (a congruence) must have finite range +# gap> EquivalenceRelationLookup(cong); +# Error, the argument (a 2-sided congruence) must have finite range # Issue 788 gap> S := GLM(2, 2); From 99b4a25f1fb06ae801589908565713e98947945e Mon Sep 17 00:00:00 2001 From: Joseph Edwards Date: Tue, 2 Sep 2025 19:33:19 +0100 Subject: [PATCH 7/7] Refactor Congruence and Presentation --- gap/libsemigroups/cong.gi | 101 ++++++++++++++++++------------ gap/libsemigroups/sims1.gi | 6 +- src/pkg.cpp | 122 ++++++++++++++++++++----------------- 3 files changed, 129 insertions(+), 100 deletions(-) diff --git a/gap/libsemigroups/cong.gi b/gap/libsemigroups/cong.gi index 0b487df96..4f3905faa 100644 --- a/gap/libsemigroups/cong.gi +++ b/gap/libsemigroups/cong.gi @@ -87,34 +87,50 @@ function(C) S := Range(C); if IsFpSemigroup(S) or (HasIsFreeSemigroup(S) and IsFreeSemigroup(S)) or IsFpMonoid(S) or (HasIsFreeMonoid(S) and IsFreeMonoid(S)) then - make := libsemigroups.Congruence.make_from_fpsemigroup; - CC := make(CongruenceHandednessString(C), LibsemigroupsFpSemigroup(S)); + CC := libsemigroups.Congruence.make( + CongruenceHandednessString(C), + LibsemigroupsPresentation(S)); factor := Factorization; elif CanUseLibsemigroupsFroidurePin(S) then - CC := LibsemigroupsCongruenceConstructor(S)(CongruenceHandednessString(C), - LibsemigroupsFroidurePin(S)); - factor := MinimalFactorization; + ErrorNoReturn( + Concatenation( + "constructing LibsemigroupsCongruence from a LibsemigroupsFroidurePin ", + "is not yet implemented")); + # TODO: Implement when FroidurePin_to_Congruence function exists + # Something like this: + # fp := LibsemigroupsFroidurePin(S)); + # CC := libsemigroups.FroidurePin_to_Congruence( + # CongruenceHandednessString(C), + # fp, + # fp.right_cayley_graph); + # factor := MinimalFactorization; elif CanUseGapFroidurePin(S) then - N := Length(GeneratorsOfSemigroup(Range(C))); - tc := libsemigroups.ToddCoxeter.make(CongruenceHandednessString(C)); - libsemigroups.ToddCoxeter.set_number_of_generators(tc, N); - if IsRightMagmaCongruence(C) then - table := RightCayleyGraphSemigroup(Range(C)) - 1; - else - table := LeftCayleyGraphSemigroup(Range(C)) - 1; - fi; - libsemigroups.ToddCoxeter.prefill(tc, table); - CC := libsemigroups.Congruence.make_from_table( - CongruenceHandednessString(C), "none"); - libsemigroups.Congruence.set_number_of_generators(CC, N); - libsemigroups.Congruence.add_runner(CC, tc); - factor := MinimalFactorization; + ErrorNoReturn( + Concatenation( + "constructing LibsemigroupsCongruence from a GAP FroidurePin is not ", + "yet implemented")); + # TODO: Implement when ToddCoxeter_tox_FroidurePin and + # FroidurePin_to_Congruence are implemented. Something like: + # if IsRightMagmaCongruence(C) then + # cayley_digraph := RightCayleyDigraph(S); + # else + # cayley := LeftCayleyDigraph(S); + # fi; + # tc := libsemigroups.ToddCoxeter.make_from_wordgraph( + # CongruenceHandednessString(C), + # cayley_digraph); + # fp := libsemigroups.ToddCoexeter_to_FroidurePin(tc); + # CC := libsemigroups.FroidurePin_to_Congruence( + # CongruenceHandednessString(C), + # fp, + # fp.right_cayley_graph); + # factor := MinimalFactorization; else TryNextMethod(); fi; - add_pair := libsemigroups.Congruence.add_pair; + add_generating_pair := libsemigroups.Congruence.add_generating_pair; for pair in GeneratingPairsOfLeftRightOrTwoSidedCongruence(C) do - add_pair(CC, factor(S, pair[1]) - 1, factor(S, pair[2]) - 1); + add_generating_pair(CC, factor(S, pair[1]) - 1, factor(S, pair[2]) - 1); od; C!.LibsemigroupsCongruence := CC; return CC; @@ -235,16 +251,20 @@ function(C) local S, CC, ntc, gens, class, i, j; S := Range(C); if not IsFinite(S) or CanUseLibsemigroupsFroidurePin(S) then - CC := LibsemigroupsCongruence(C); - ntc := libsemigroups.Congruence.ntc(CC) + 1; - gens := GeneratorsOfSemigroup(S); - for i in [1 .. Length(ntc)] do - class := ntc[i]; - for j in [1 .. Length(class)] do - class[j] := EvaluateWord(gens, class[j]); - od; - od; - return ntc; + ErrorNoReturn( + Concatenation( + "computing the non-trivial classes of a Congruence is not yet ", + "implemented")); + # CC := LibsemigroupsCongruence(C); + # ntc := libsemigroups.Congruence.ntc(CC) + 1; + # gens := GeneratorsOfSemigroup(S); + # for i in [1 .. Length(ntc)] do + # class := ntc[i]; + # for j in [1 .. Length(class)] do + # class[j] := EvaluateWord(gens, class[j]); + # od; + # od; + # return ntc; elif CanUseGapFroidurePin(S) then # in this case libsemigroups.Congruence.ntc doesn't work, because S is not # represented in the libsemigroups object @@ -290,15 +310,16 @@ function(C) "number of classes"); fi; - result := EmptyPlist(NrEquivalenceClasses(C)); - CC := LibsemigroupsCongruence(C); - gens := GeneratorsOfSemigroup(Range(C)); - class_index_to_word := libsemigroups.Congruence.class_index_to_word; - for i in [1 .. NrEquivalenceClasses(C)] do - rep := EvaluateWord(gens, class_index_to_word(CC, i - 1) + 1); - result[i] := EquivalenceClassOfElementNC(C, rep); - od; - return result; + ErrorNoReturn("libsemigroups.Congruence has no member 'class_index_to_word'"); + # result := EmptyPlist(NrEquivalenceClasses(C)); + # CC := LibsemigroupsCongruence(C); + # gens := GeneratorsOfSemigroup(Range(C)); + # class_index_to_word := libsemigroups.Congruence.class_index_to_word; + # for i in [1 .. NrEquivalenceClasses(C)] do + # rep := EvaluateWord(gens, class_index_to_word(CC, i - 1) + 1); + # result[i] := EquivalenceClassOfElementNC(C, rep); + # od; + # return result; end); ########################################################################### diff --git a/gap/libsemigroups/sims1.gi b/gap/libsemigroups/sims1.gi index bc235a81f..57ed12f99 100644 --- a/gap/libsemigroups/sims1.gi +++ b/gap/libsemigroups/sims1.gi @@ -51,10 +51,10 @@ function(S, n, extra, kind) if not IsEmpty(rules) then libsemigroups.Presentation.alphabet_from_rules(P); elif (HasIsFreeMonoid(S) and IsFreeMonoid(S)) or IsFpMonoid(S) then - libsemigroups.Presentation.set_alphabet( + libsemigroups.Presentation.alphabet( P, [0 .. Size(GeneratorsOfMonoid(S)) - 1]); elif (HasIsFreeSemigroup(S) and IsFreeSemigroup(S)) or IsFpSemigroup(S) then - libsemigroups.Presentation.set_alphabet( + libsemigroups.Presentation.alphabet( P, [0 .. Size(GeneratorsOfSemigroup(S)) - 1]); fi; libsemigroups.Presentation.validate(P); @@ -68,7 +68,7 @@ function(S, n, extra, kind) if not IsEmpty(extra) then Q := libsemigroups.Presentation.make(); libsemigroups.Presentation.contains_empty_word(Q, IsMonoid(S)); - libsemigroups.Presentation.set_alphabet(Q, + libsemigroups.Presentation.alphabet(Q, libsemigroups.Presentation.alphabet(P)); for pair in extra do diff --git a/src/pkg.cpp b/src/pkg.cpp index 1530fe2cb..5392a5569 100644 --- a/src/pkg.cpp +++ b/src/pkg.cpp @@ -52,18 +52,31 @@ // libsemigroups headers #include "libsemigroups/adapters.hpp" -#include "libsemigroups/bipart.hpp" // for Blocks, Bipartition -#include "libsemigroups/freeband.hpp" // for freeband_equal_to -#include "libsemigroups/presentation.hpp" // for Presentation -#include "libsemigroups/sims.hpp" // for Sims1 -#include "libsemigroups/todd-coxeter.hpp" // for ToddCoxeter, ToddCoxeter::word_graph_type -#include "libsemigroups/types.hpp" // for word_type, letter_type -#include "libsemigroups/word-graph.hpp" // for WordGraph +#include "libsemigroups/bipart.hpp" // for Blocks, Bipartition +#include "libsemigroups/cong-class.hpp" // for Congruence +#include "libsemigroups/freeband.hpp" // for freeband_equal_to +#include "libsemigroups/froidure-pin-base.hpp" // for FroidurePin +#include "libsemigroups/presentation.hpp" // for Presentation +#include "libsemigroups/sims.hpp" // for Sims1 +#include "libsemigroups/to-cong.hpp" // for to +#include "libsemigroups/todd-coxeter.hpp" // for ToddCoxeter, +#include "libsemigroups/types.hpp" // for word_type, letter_type +#include "libsemigroups/word-graph.hpp" // for WordGraph #include "libsemigroups/detail/report.hpp" // for REPORTER, Reporter using libsemigroups::Bipartition; using libsemigroups::Blocks; +using libsemigroups::Congruence; +using libsemigroups::congruence_kind; +using libsemigroups::FroidurePin; +using libsemigroups::FroidurePinBase; +using libsemigroups::Presentation; +using libsemigroups::RepOrc; +using libsemigroups::Sims1; +using libsemigroups::ToddCoxeter; +using libsemigroups::word_type; +using libsemigroups::WordGraph; namespace { void LIBSEMIGROUPS_REPORTING_ENABLED(bool const val) { @@ -74,22 +87,19 @@ namespace { namespace gapbind14 { template <> - struct IsGapBind14Type> - : std::true_type {}; + struct IsGapBind14Type> : std::true_type {}; template <> - struct IsGapBind14Type> - : std::true_type {}; + struct IsGapBind14Type> : std::true_type {}; template <> - struct IsGapBind14Type : std::true_type {}; + struct IsGapBind14Type : std::true_type {}; template <> - struct IsGapBind14Type - : std::true_type {}; + struct IsGapBind14Type : std::true_type {}; template <> - struct IsGapBind14Type : std::true_type {}; + struct IsGapBind14Type : std::true_type {}; } // namespace gapbind14 GAPBIND14_MODULE(libsemigroups) { @@ -105,13 +115,14 @@ GAPBIND14_MODULE(libsemigroups) { &std::thread::hardware_concurrency); gapbind14::InstallGlobalFunction( "freeband_equal_to", - gapbind14::overload_cast( - &libsemigroups::freeband_equal_to)); + gapbind14::overload_cast( + &libsemigroups::freeband_equal_to)); gapbind14::InstallGlobalFunction("LATTICE_OF_CONGRUENCES", &semigroups::LATTICE_OF_CONGRUENCES); + // TODO: Add the to<> functions + //////////////////////////////////////////////////////////////////////// // Initialise from other cpp files //////////////////////////////////////////////////////////////////////// @@ -131,19 +142,17 @@ GAPBIND14_MODULE(libsemigroups) { // ToddCoxeter //////////////////////////////////////////////////////////////////////// - using libsemigroups::word_type; - - using libsemigroups::congruence_kind; - using libsemigroups::Presentation; - using libsemigroups::ToddCoxeter; - - using word_graph_type - = libsemigroups::ToddCoxeter::word_graph_type; + using word_graph_type = ToddCoxeter::word_graph_type; gapbind14::class_>("ToddCoxeter") - .def(gapbind14::init>{}); + .def(gapbind14::init>{}, + "make_from_presentation") + .def(gapbind14::init>{}, + "make_from_wordgraph"); - using libsemigroups::Presentation; + //////////////////////////////////////////////////////////////////////// + // Presentation + //////////////////////////////////////////////////////////////////////// gapbind14::class_>("Presentation") .def(gapbind14::init<>{}, "make") @@ -153,6 +162,10 @@ GAPBIND14_MODULE(libsemigroups) { [](Presentation& thing, word_type val) -> void { thing.alphabet(val); }) + .def("set_alphabet_size", + [](Presentation& thing, size_t size) -> void { + thing.alphabet(size); + }) .def("alphabet_from_rules", [](Presentation& thing) -> void { thing.alphabet_from_rules(); @@ -175,7 +188,9 @@ GAPBIND14_MODULE(libsemigroups) { word_type const&>( &libsemigroups::presentation::add_rule)); - using libsemigroups::Sims1; + //////////////////////////////////////////////////////////////////////// + // Sims + //////////////////////////////////////////////////////////////////////// gapbind14::class_("Sims1Iterator") .def("increment", [](typename Sims1::iterator& it) { ++it; }) @@ -188,8 +203,6 @@ GAPBIND14_MODULE(libsemigroups) { .def("number_of_congruences", &Sims1::number_of_congruences) .def("cbegin", &Sims1::cbegin); - using libsemigroups::RepOrc; - gapbind14::class_("RepOrc") .def(gapbind14::init<>{}, "make") .def("number_of_threads", @@ -199,34 +212,29 @@ GAPBIND14_MODULE(libsemigroups) { .def("target_size", [](RepOrc& ro, size_t val) { ro.target_size(val); }) .def("word_graph", &RepOrc::word_graph); - using libsemigroups::Congruence; - using libsemigroups::congruence_kind; - using libsemigroups::FroidurePinBase; - using libsemigroups::Presentation; - using libsemigroups::word_type; + //////////////////////////////////////////////////////////////////////// + // Congruence + //////////////////////////////////////////////////////////////////////// gapbind14::class_>("Congruence") - .def(gapbind14::init>{}, "make"); - // .def("number_of_generating_pairs", - // &Congruence::number_of_generating_pairs) - // .def("add_generating_pair", - // [](Congruence& self, - // word_type const& u, - // word_type const& v) { - // return libsemigroups::congruence::add_generating_pair(self, u, v); - // }) - // .def("number_of_classes", &Congruence::number_of_classes) - // // .def("index_of", &Congruence::word_to_class_index) - // // .def("word_of", &Congruence::class_index_to_word) - // .def("contains", - // [](Congruence& self, - // word_type const& u, - // word_type const& v) { - // return libsemigroups::congruence::contains(self, u, v); - // }); - // .def("non_trivial_classes", [](Congruence& C) { - // return gapbind14::make_iterator(C.cbegin_ntc(), C.cend_ntc()); - // }); + .def(gapbind14::init>{}, "make") + .def("number_of_generating_pairs", + &Congruence::number_of_generating_pairs) + .def("add_generating_pair", + [](Congruence& self, + word_type const& u, + word_type const& v) { + return libsemigroups::congruence::add_generating_pair(self, u, v); + }) + .def("number_of_classes", &Congruence::number_of_classes) + // .def("index_of", &Congruence::word_to_class_index) + // .def("word_of", &Congruence::class_index_to_word) + .def("contains", + [](Congruence& self, + word_type const& u, + word_type const& v) { + return libsemigroups::congruence::contains(self, u, v); + }); } ////////////////////////////////////////////////////////////////////////