From ff6e172a492af2465fd7465da64298353cc15cc5 Mon Sep 17 00:00:00 2001 From: James Mitchell Date: Wed, 2 May 2018 10:45:40 +0200 Subject: [PATCH] Update for libsemigroups v1.0.0 --- .LIBSEMIGROUPS_VERSION | 2 +- Makefile.am | 16 +- gap/main/fropin.gi | 19 ++- m4/ax_check_libsemigroup.m4 | 4 +- scripts/travis-test.sh | 10 +- src/.clang-format | 10 +- src/bipart.cc | 133 ++++++++-------- src/bipart.h | 9 +- src/congpairs.cc | 235 ++++++++++++++-------------- src/converter.cc | 21 ++- src/converter.h | 50 +++--- src/fropin.cc | 29 ++-- src/pkg.cc | 22 +-- src/pkg.h | 5 +- src/semigrp.cc | 294 +++++++++++++++++++----------------- src/semigrp.h | 63 ++++---- src/uf.cc | 8 +- tst/standard/congfpmon.tst | 17 +-- 18 files changed, 484 insertions(+), 463 deletions(-) diff --git a/.LIBSEMIGROUPS_VERSION b/.LIBSEMIGROUPS_VERSION index 2228cad41..3eefcb9dd 100644 --- a/.LIBSEMIGROUPS_VERSION +++ b/.LIBSEMIGROUPS_VERSION @@ -1 +1 @@ -0.6.7 +1.0.0 diff --git a/Makefile.am b/Makefile.am index b5ee5ea8b..6998d563e 100644 --- a/Makefile.am +++ b/Makefile.am @@ -11,7 +11,7 @@ if WITH_INCLUDED_LIBSEMIGROUPS # the following triggers "make install" on libsemigroups # note that making it a concrete file prevents this target # to be needlessly re-run if libsemigroups/ is not changed. - BUILT_SOURCES = bin/include/libsemigroups/blocks.h + BUILT_SOURCES = bin/include/libsemigroups/libsemigroups.hpp endif AM_CPPFLAGS = @LIBSEMIGROUPS_CFLAGS@ @@ -28,6 +28,18 @@ semigroups_la_SOURCES += src/semigrp.cc semigroups_la_CXXFLAGS = $(GAP_CFLAGS) @LIBSEMIGROUPS_CFLAGS@ -std=gnu++11 -O3 -g -march=native semigroups_la_CPPFLAGS = $(GAP_CPPFLAGS) @LIBSEMIGROUPS_CFLAGS@ semigroups_la_CFLAGS = $(GAP_CFLAGS) + +semigroups_la_CPPFLAGS += -I$(top_srcdir)/libsemigroups/extern/HPCombi/include +semigroups_la_CPPFLAGS += -I$(top_srcdir)/libsemigroups/extern/HPCombi/include/fallback +semigroups_la_CPPFLAGS += -I$(top_srcdir)/libsemigroups/extern/fmt-5.3.0/include +semigroups_la_CPPFLAGS += -DFMT_HEADER_ONLY + +if KERNEL_DEBUG +semigroups_la_CPPFLAGS += -DDEBUG +else +semigroups_la_CPPFLAGS += -DNDEBUG +endif + semigroups_la_LDFLAGS = $(GAP_LDFLAGS) -module -avoid-version semigroups_la_LIBADD = @LIBSEMIGROUPS_LIBS@ @@ -37,7 +49,7 @@ semigroups_la_LDFLAGS += -no-undefined -version-info 0:0:0 -Wl,$(GAPROOT)/bin/$( endif # the following is only run if BUILT_SOURCES is wound up -bin/include/libsemigroups/blocks.h: +bin/include/libsemigroups/libsemigroups.hpp: $(MAKE) -C libsemigroups install all-local: semigroups.la diff --git a/gap/main/fropin.gi b/gap/main/fropin.gi index 49ff8ed7e..cdbb79b5c 100644 --- a/gap/main/fropin.gi +++ b/gap/main/fropin.gi @@ -259,7 +259,9 @@ function(S) enum := rec(); enum.NumberElement := function(enum, x) - return EN_SEMI_POSITION_SORTED(S, x); + # Don't call EN_SEMI_POSITION_SORTED directly because then we pass elements + # of too high degree which causes an exception in Libsemigroups + return PositionSortedOp(S, x); end; enum.ElementNumber := function(enum, nr) @@ -348,6 +350,8 @@ function(S) enum := rec(); enum.NumberElement := function(enum, x) + # Don't call EN_SEMI_POSITION directly since we may then pass too large + # degree pperms or transformations which cause a libsemigroups exception. return PositionCanonical(S, x); end; @@ -475,7 +479,8 @@ function(S, x) or (IsTransformation(x) and DegreeOfTransformation(x) > DegreeOfTransformationSemigroup(S)) or (IsPartialPerm(x) - and DegreeOfPartialPerm(x) > DegreeOfPartialPermSemigroup(S)) then + and (DegreeOfPartialPerm(x) > DegreeOfPartialPermSemigroup(S) + or CodegreeOfPartialPerm(x) > CodegreeOfPartialPermSemigroup(S))) then return fail; fi; @@ -487,6 +492,9 @@ InstallMethod(PositionCanonical, [IsPermGroup and HasGeneratorsOfGroup and IsEnumerableSemigroupRep, IsMultiplicativeElement], function(G, x) + if (not IsPerm(x)) or LargestMovedPointPerm(x) > LargestMovedPoint(G) then + return fail; + fi; return EN_SEMI_POSITION(G, x); end); @@ -513,7 +521,8 @@ function(S, x, n) or (IsTransformation(x) and DegreeOfTransformation(x) > DegreeOfTransformationSemigroup(S)) or (IsPartialPerm(x) - and DegreeOfPartialPerm(x) > DegreeOfPartialPermSemigroup(S)) then + and (DegreeOfPartialPerm(x) > DegreeOfPartialPermSemigroup(S) + or CodegreeOfPartialPerm(x) > CodegreeOfPartialPermSemigroup(S))) then return fail; fi; @@ -529,13 +538,13 @@ function(S, x) or (IsTransformation(x) and DegreeOfTransformation(x) > DegreeOfTransformationSemigroup(S)) or (IsPartialPerm(x) - and DegreeOfPartialPerm(x) > DegreeOfPartialPermSemigroup(S)) then + and (DegreeOfPartialPerm(x) > DegreeOfPartialPermSemigroup(S) + or CodegreeOfPartialPerm(x) > CodegreeOfPartialPermSemigroup(S))) then return fail; elif not IsFinite(S) then ErrorNoReturn("Semigroups: PositionSortedOp: usage,\n", "the first argument (a semigroup) must be finite,"); fi; - return EN_SEMI_POSITION_SORTED(S, x); end); diff --git a/m4/ax_check_libsemigroup.m4 b/m4/ax_check_libsemigroup.m4 index ae1f6f40c..23e498b4a 100644 --- a/m4/ax_check_libsemigroup.m4 +++ b/m4/ax_check_libsemigroup.m4 @@ -21,9 +21,9 @@ AC_DEFUN([AX_CHECK_LIBSEMIGROUPS], [ if test "$need_included_libsemigroups" = yes; then AC_MSG_NOTICE([using included libsemigroups...]) AC_CHECK_FILE( - [libsemigroups/src/semigroups.h], + [libsemigroups/libsemigroups.hpp], [], - [AC_MSG_ERROR([libsemigroups is required, clone or download the repo from https://github.com/james-d-mitchell/libsemigroups into this directory])]) + [AC_MSG_ERROR([libsemigroups is required, clone or download the repo from https://github.com/libsemigroups/libsemigroups into this directory])]) AC_CHECK_FILE( [libsemigroups/VERSION], diff --git a/src/.clang-format b/src/.clang-format index 7de2cef03..8d5699d47 100644 --- a/src/.clang-format +++ b/src/.clang-format @@ -4,7 +4,7 @@ AccessModifierOffset: -1 AlignAfterOpenBracket: Align AlignConsecutiveAssignments: true AlignConsecutiveDeclarations: true -AlignEscapedNewlines: Left +AlignEscapedNewlinesLeft: true AlignOperands: true AlignTrailingComments: true AllowAllParametersOfDeclarationOnNextLine: false @@ -15,7 +15,7 @@ AllowShortIfStatementsOnASingleLine: false AllowShortLoopsOnASingleLine: false AlwaysBreakAfterReturnType: None AlwaysBreakBeforeMultilineStrings: false -AlwaysBreakTemplateDeclarations: false +AlwaysBreakTemplateDeclarations: true BinPackArguments: false BinPackParameters: false BraceWrapping: @@ -79,12 +79,8 @@ PenaltyBreakComment: 300 PenaltyBreakFirstLessLess: 200 PenaltyBreakString: 1000 PenaltyExcessCharacter: 1000000 -PenaltyReturnTypeOnItsOwnLine: 600 +PenaltyReturnTypeOnItsOwnLine: 60 PointerAlignment: Left -RawStringFormats: - - Delimiter: pb - Language: TextProto - BasedOnStyle: google ReflowComments: true SortIncludes: true SpaceAfterCStyleCast: true diff --git a/src/bipart.cc b/src/bipart.cc index 2db351952..83c3a3996 100644 --- a/src/bipart.cc +++ b/src/bipart.cc @@ -28,12 +28,15 @@ #include #include -#include "libsemigroups/semigroups.h" +#include "libsemigroups/blocks.hpp" +#include "libsemigroups/froidure-pin.hpp" + #include "src/compiled.h" +using libsemigroups::Blocks; using libsemigroups::Element; -using libsemigroups::glob_reporter; -using libsemigroups::Timer; +using libsemigroups::REPORTER; +using libsemigroups::detail::Timer; // Global variables @@ -97,7 +100,7 @@ inline Obj blocks_new_obj(Blocks* x) { Obj BIPART_NC(Obj self, Obj gap_blocks) { SEMIGROUPS_ASSERT(IS_LIST(gap_blocks)); - std::vector* blocks = new std::vector(); + std::vector blocks; size_t degree = 0; size_t nr_left_blocks = 0; @@ -110,7 +113,7 @@ Obj BIPART_NC(Obj self, Obj gap_blocks) { SEMIGROUPS_ASSERT(IS_LIST(ELM_LIST(gap_blocks, i))); degree += LEN_LIST(ELM_LIST(gap_blocks, i)); } - blocks->resize(degree); + blocks.resize(degree); degree /= 2; @@ -120,21 +123,21 @@ Obj BIPART_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)[-jj + degree - 1] = i - 1; + blocks[-jj + degree - 1] = i - 1; } else { - nr_left_blocks = i; - (*blocks)[jj - 1] = i - 1; + nr_left_blocks = i; + blocks[jj - 1] = i - 1; } } } } else { // gap_blocks is the internal rep of a bipartition - blocks->reserve(LEN_LIST(gap_blocks)); + blocks.reserve(LEN_LIST(gap_blocks)); for (size_t i = 1; i <= static_cast(LEN_LIST(gap_blocks)) / 2; i++) { SEMIGROUPS_ASSERT(IS_INTOBJ(ELM_LIST(gap_blocks, i)) && INT_INTOBJ(ELM_LIST(gap_blocks, i)) > 0); u_int32_t index = INT_INTOBJ(ELM_LIST(gap_blocks, i)) - 1; - blocks->push_back(index); + blocks.push_back(index); nr_blocks = (index > nr_blocks ? index : nr_blocks); } nr_left_blocks = nr_blocks + 1; @@ -144,7 +147,7 @@ Obj BIPART_NC(Obj self, Obj gap_blocks) { SEMIGROUPS_ASSERT(IS_INTOBJ(ELM_LIST(gap_blocks, i)) && INT_INTOBJ(ELM_LIST(gap_blocks, i)) > 0); u_int32_t index = INT_INTOBJ(ELM_LIST(gap_blocks, i)) - 1; - blocks->push_back(index); + blocks.push_back(index); nr_blocks = (index > nr_blocks ? index : nr_blocks); } nr_blocks++; @@ -168,8 +171,8 @@ Obj BIPART_EXT_REP(Obj self, Obj x) { Bipartition* xx = bipart_get_cpp(x); size_t n = xx->degree(); - Obj ext_rep = NEW_PLIST(n == 0 ? T_PLIST_EMPTY : T_PLIST_TAB, - xx->nr_blocks()); + Obj ext_rep + = NEW_PLIST(n == 0 ? T_PLIST_EMPTY : T_PLIST_TAB, xx->nr_blocks()); SET_LEN_PLIST(ext_rep, (Int) xx->nr_blocks()); for (size_t i = 0; i < 2 * n; i++) { @@ -198,8 +201,7 @@ Obj BIPART_INT_REP(Obj self, Obj x) { Bipartition* xx = bipart_get_cpp(x); // get C++ bipartition pointer size_t n = xx->degree(); - Obj int_rep - = NEW_PLIST_IMM(n == 0 ? T_PLIST_EMPTY : T_PLIST_CYC, 2 * n); + Obj int_rep = NEW_PLIST_IMM(n == 0 ? T_PLIST_EMPTY : T_PLIST_CYC, 2 * n); SET_LEN_PLIST(int_rep, (Int) 2 * n); for (size_t i = 0; i < 2 * n; i++) { @@ -347,18 +349,17 @@ Obj BIPART_LEFT_PROJ(Obj self, Obj x) { -1); _BUFFER_size_t.resize(2 * deg, -1); - std::vector* blocks = new std::vector(); - blocks->resize(2 * deg, -1); + std::vector blocks(2 * deg, -1); for (size_t i = 0; i < deg; i++) { - (*blocks)[i] = xx->at(i); + blocks[i] = xx->at(i); if (xx->is_transverse_block(xx->at(i))) { - (*blocks)[i + deg] = xx->at(i); + blocks[i + deg] = xx->at(i); } else if (_BUFFER_size_t[xx->at(i)] != static_cast(-1)) { - (*blocks)[i + deg] = _BUFFER_size_t[xx->at(i)]; + blocks[i + deg] = _BUFFER_size_t[xx->at(i)]; } else { _BUFFER_size_t[xx->at(i)] = next; - (*blocks)[i + deg] = next; + blocks[i + deg] = next; next++; } } @@ -384,8 +385,7 @@ Obj BIPART_RIGHT_PROJ(Obj self, Obj x) { auto buf1 = _BUFFER_size_t.begin(); auto buf2 = _BUFFER_size_t.begin() + 2 * deg; - std::vector* blocks = new std::vector(); - blocks->resize(2 * deg, -1); + std::vector blocks(2 * deg, -1); for (size_t i = deg; i < 2 * deg; i++) { if (buf2[xx->at(i)] == static_cast(-1)) { @@ -396,8 +396,8 @@ Obj BIPART_RIGHT_PROJ(Obj self, Obj x) { buf1[xx->at(i)] = l_block++; } } - (*blocks)[i - deg] = buf1[xx->at(i)]; - (*blocks)[i] = buf2[xx->at(i)]; + blocks[i - deg] = buf1[xx->at(i)]; + blocks[i] = buf2[xx->at(i)]; } Bipartition* out = new Bipartition(blocks); @@ -418,17 +418,16 @@ Obj BIPART_STAR(Obj self, Obj x) { -1); _BUFFER_size_t.resize(2 * deg, -1); - std::vector* blocks = new std::vector(); - blocks->resize(2 * deg, -1); + std::vector blocks(2 * deg, -1); size_t next = 0; for (size_t i = 0; i < deg; i++) { if (_BUFFER_size_t[xx->at(i + deg)] != static_cast(-1)) { - (*blocks)[i] = _BUFFER_size_t[xx->at(i + deg)]; + blocks[i] = _BUFFER_size_t[xx->at(i + deg)]; } else { _BUFFER_size_t[xx->at(i + deg)] = next; - (*blocks)[i] = next; + blocks[i] = next; next++; } } @@ -437,10 +436,10 @@ Obj BIPART_STAR(Obj self, Obj x) { for (size_t i = 0; i < deg; i++) { if (_BUFFER_size_t[xx->at(i)] != static_cast(-1)) { - (*blocks)[i + deg] = _BUFFER_size_t[xx->at(i)]; + blocks[i + deg] = _BUFFER_size_t[xx->at(i)]; } else { _BUFFER_size_t[xx->at(i)] = next; - (*blocks)[i + deg] = next; + blocks[i + deg] = next; next++; } } @@ -563,8 +562,7 @@ Obj BIPART_STAB_ACTION(Obj self, Obj x, Obj p) { size_t deg = xx->degree(); size_t nr_blocks = xx->nr_blocks(); - std::vector* blocks = new std::vector(); - blocks->resize(2 * deg); + std::vector blocks(2 * deg); _BUFFER_size_t.clear(); _BUFFER_size_t.resize(2 * nr_blocks + std::max(deg, pdeg), -1); @@ -604,8 +602,8 @@ Obj BIPART_STAB_ACTION(Obj self, Obj x, Obj p) { } for (size_t i = 0; i < deg; i++) { - (*blocks)[i] = xx->at(i); - (*blocks)[i + deg] = tab2[tab1[xx->at(i + deg)]]; + blocks[i] = xx->at(i); + blocks[i + deg] = tab2[tab1[xx->at(i + deg)]]; } return bipart_new_obj(new Bipartition(blocks)); @@ -722,8 +720,8 @@ Obj BLOCKS_EXT_REP(Obj self, Obj x) { Blocks* xx = blocks_get_cpp(x); size_t n = xx->degree(); - Obj ext_rep = NEW_PLIST(n == 0 ? T_PLIST_EMPTY : T_PLIST_TAB, - xx->nr_blocks()); + Obj ext_rep + = NEW_PLIST(n == 0 ? T_PLIST_EMPTY : T_PLIST_TAB, xx->nr_blocks()); SET_LEN_PLIST(ext_rep, (Int) xx->nr_blocks()); for (size_t i = 0; i < n; i++) { @@ -793,21 +791,20 @@ Obj BLOCKS_PROJ(Obj self, Obj x) { _BUFFER_size_t.clear(); _BUFFER_size_t.resize(blocks->nr_blocks(), -1); - std::vector* out = new std::vector(); - out->resize(2 * blocks->degree()); - u_int32_t nr_blocks = blocks->nr_blocks(); + std::vector out(2 * blocks->degree()); + u_int32_t nr_blocks = blocks->nr_blocks(); for (u_int32_t i = 0; i < blocks->degree(); i++) { u_int32_t index = blocks->block(i); - (*out)[i] = index; + out[i] = index; if (blocks->is_transverse_block(index)) { - (*out)[i + blocks->degree()] = index; + out[i + blocks->degree()] = index; } else { if (_BUFFER_size_t[index] == static_cast(-1)) { _BUFFER_size_t[index] = nr_blocks; nr_blocks++; } - (*out)[i + blocks->degree()] = _BUFFER_size_t[index]; + out[i + blocks->degree()] = _BUFFER_size_t[index]; } } return bipart_new_obj(new Bipartition(out)); @@ -920,22 +917,21 @@ Obj BLOCKS_E_CREATOR(Obj self, Obj left_gap, Obj right_gap) { } } - std::vector* blocks = new std::vector(); - blocks->resize(2 * left->degree()); + std::vector blocks(2 * left->degree()); size_t next = right->nr_blocks(); for (size_t i = 0; i < left->degree(); i++) { - (*blocks)[i] = right->block(i); - size_t j = left->block(i); + blocks[i] = right->block(i); + size_t j = left->block(i); if (left->is_transverse_block(j)) { - (*blocks)[i + left->degree()] = tab1[fuse_it(j)]; + blocks[i + left->degree()] = tab1[fuse_it(j)]; } else { if (tab2[j] == static_cast(-1)) { tab2[j] = next; next++; } - (*blocks)[i + left->degree()] = tab2[j]; + blocks[i + left->degree()] = tab2[j]; } } @@ -1071,14 +1067,13 @@ Obj BLOCKS_INV_LEFT(Obj self, Obj blocks_gap, Obj x_gap) { x->nr_blocks(), false); SEMIGROUPS_ASSERT(_BUFFER_size_t.size() - == blocks->nr_blocks() + x->nr_blocks()); + == blocks->nr_blocks() + x->nr_blocks()); - std::vector* out_blocks = new std::vector(); - out_blocks->resize(2 * x->degree()); + std::vector out_blocks(2 * x->degree()); _BUFFER_size_t.resize(2 * blocks->nr_blocks() + x->nr_blocks(), -1); SEMIGROUPS_ASSERT(_BUFFER_size_t.size() - == 2 * blocks->nr_blocks() + x->nr_blocks()); + == 2 * blocks->nr_blocks() + x->nr_blocks()); SEMIGROUPS_ASSERT(std::all_of( _BUFFER_size_t.cbegin() + blocks->nr_blocks() + x->nr_blocks(), _BUFFER_size_t.cend(), @@ -1096,12 +1091,12 @@ Obj BLOCKS_INV_LEFT(Obj self, Obj blocks_gap, Obj x_gap) { // find the left blocks of the output for (u_int32_t i = 0; i < blocks->degree(); i++) { - (*out_blocks)[i] = blocks->block(i); - u_int32_t j = fuse_it(x->at(i) + blocks->nr_blocks()); + out_blocks[i] = blocks->block(i); + u_int32_t j = fuse_it(x->at(i) + blocks->nr_blocks()); if (j >= blocks->nr_blocks() || tab[j] == static_cast(-1)) { - (*out_blocks)[i + x->degree()] = blocks->nr_blocks(); // junk + out_blocks[i + x->degree()] = blocks->nr_blocks(); // junk } else { - (*out_blocks)[i + x->degree()] = tab[j]; + out_blocks[i + x->degree()] = tab[j]; } } @@ -1175,8 +1170,7 @@ Obj BLOCKS_INV_RIGHT(Obj self, Obj blocks_gap, Obj x_gap) { u_int32_t junk = -1; u_int32_t next = 0; - std::vector* out_blocks = new std::vector(); - out_blocks->resize(2 * x->degree()); + std::vector out_blocks(2 * x->degree()); _BUFFER_size_t.resize(3 * blocks->nr_blocks() + 2 * x->nr_blocks(), -1); auto tab1 = _BUFFER_size_t.begin() + blocks->nr_blocks() + x->nr_blocks(); @@ -1192,7 +1186,7 @@ Obj BLOCKS_INV_RIGHT(Obj self, Obj blocks_gap, Obj x_gap) { tab1[j] = next; next++; } - (*out_blocks)[i] = tab1[j]; + out_blocks[i] = tab1[j]; continue; } } @@ -1200,7 +1194,7 @@ Obj BLOCKS_INV_RIGHT(Obj self, Obj blocks_gap, Obj x_gap) { junk = next; next++; } - (*out_blocks)[i] = junk; + out_blocks[i] = junk; } u_int32_t out_nr_left_blocks = next; @@ -1210,13 +1204,13 @@ Obj BLOCKS_INV_RIGHT(Obj self, Obj blocks_gap, Obj x_gap) { for (u_int32_t i = blocks->degree(); i < 2 * blocks->degree(); i++) { u_int32_t j = blocks->block(i - blocks->degree()); if (blocks->is_transverse_block(j)) { - (*out_blocks)[i] = tab1[fuse_it(j)]; + out_blocks[i] = tab1[fuse_it(j)]; } else { if (tab2[j] == static_cast(-1)) { tab2[j] = next; next++; } - (*out_blocks)[i] = tab2[j]; + out_blocks[i] = tab2[j]; } } @@ -1390,10 +1384,11 @@ class IdempotentCounter { } std::vector count() { - glob_reporter.reset_thread_ids(); - glob_reporter.set_report(_report); - REPORT("using " << _nr_threads << " / " - << std::thread::hardware_concurrency() << " threads"); + libsemigroups::THREAD_ID_MANAGER.reset(); + auto rg = libsemigroups::ReportGuard(_report); + REPORT_DEFAULT("using %llu / %llu additional threads", + _nr_threads, + std::thread::hardware_concurrency()); Timer timer; for (size_t i = 0; i < _nr_threads; i++) { @@ -1405,7 +1400,7 @@ class IdempotentCounter { _threads[i].join(); } - REPORT(timer); + REPORT_TIME(timer); size_t max = *max_element(_ranks.begin(), _ranks.end()) + 1; std::vector out = std::vector(max, 0); @@ -1441,7 +1436,7 @@ class IdempotentCounter { } } } - REPORT("finished in " << timer.string()); + REPORT_DEFAULT("finished in %llu", timer.string()); } // This is basically the same as BLOCKS_E_TESTER, but is required because we diff --git a/src/bipart.h b/src/bipart.h index 8c09b7548..d8d192486 100644 --- a/src/bipart.h +++ b/src/bipart.h @@ -19,10 +19,15 @@ #ifndef SEMIGROUPS_SRC_BIPART_H_ #define SEMIGROUPS_SRC_BIPART_H_ -#include "libsemigroups/elements.h" +// libsemigroups headers +#include "libsemigroups/element.hpp" + +// GAP headers +#include "src/compiled.h" + +// Semigroups pkg headers #include "pkg.h" #include "semigroups-debug.h" -#include "src/compiled.h" using libsemigroups::Bipartition; using libsemigroups::Blocks; diff --git a/src/congpairs.cc b/src/congpairs.cc index 29457859c..de99163ac 100644 --- a/src/congpairs.cc +++ b/src/congpairs.cc @@ -27,16 +27,34 @@ #include "rnams.h" #include "semigrp.h" -#include "libsemigroups/cong.h" - -using libsemigroups::Congruence; -using libsemigroups::Partition; -using libsemigroups::RecVec; -using libsemigroups::relation_t; -using libsemigroups::word_t; +#include "libsemigroups/cong.hpp" +#include "libsemigroups/fpsemi.hpp" +#include "libsemigroups/report.hpp" + +using libsemigroups::FpSemigroup; +using libsemigroups::detail::DynamicArray2; +using libsemigroups::relation_type; +using libsemigroups::ReportGuard; +using libsemigroups::word_type; +using Congruence = libsemigroups::Congruence; +using congruence_type = libsemigroups::congruence_type; + +static inline congruence_type cstring_to_congruence_t(char const* type) { + std::string stype = std::string(type); + if (stype == "left") { + return congruence_type::left; + } else if (stype == "right") { + return congruence_type::right; + } else if (stype == "twosided") { + return congruence_type::twosided; + } else { + ErrorQuit("Unrecognised type %s", (Int) type, 0L); + return congruence_type::left; + } +} -static inline word_t plist_to_word_t(gap_list_t plist) { - word_t word; +static inline word_type plist_to_word_type(gap_list_t plist) { + word_type word; for (size_t i = 1; i <= (size_t) LEN_PLIST(plist); i++) { Obj j = ELM_PLIST(plist, i); SEMIGROUPS_ASSERT(IS_INTOBJ(j)); @@ -45,7 +63,7 @@ static inline word_t plist_to_word_t(gap_list_t plist) { return word; } -static inline gap_list_t word_t_to_plist(word_t* w) { +static inline gap_list_t word_type_to_plist(word_type const* w) { gap_list_t plist = NEW_PLIST_IMM(T_PLIST_CYC, w->size()); SET_LEN_PLIST(plist, w->size()); for (size_t i = 0; i < w->size(); i++) { @@ -66,13 +84,13 @@ static inline gap_semigroup_t cong_obj_get_range_obj(gap_cong_t o) { return ElmPRec(o, RNam_range); } -static inline Semigroup* cong_obj_get_range(gap_cong_t o) { +static inline FroidurePin* cong_obj_get_range(gap_cong_t o) { return semi_obj_get_semi_cpp(cong_obj_get_range_obj(o)); } static inline bool cong_obj_get_range_type(gap_cong_t o) { initRNams(); - // SEMIGROUPS_ASSERT(IsSemigroupCongruenceByGeneratingPairsRep(o)); + // SEMIGROUPS_ASSERT(IsSemigroup<>CongruenceByGeneratingPairsRep(o)); return semi_obj_get_type(cong_obj_get_range_obj(o)); } @@ -82,82 +100,67 @@ static inline bool cong_obj_is_fp_cong(gap_cong_t cong) { } static void cong_obj_init_cpp_cong(gap_cong_t o) { - // SEMIGROUPS_ASSERT(IsSemigroupCongruenceByGeneratingPairsRep(o)); + // SEMIGROUPS_ASSERT(IsSemigroup<>CongruenceByGeneratingPairsRep(o)); SEMIGROUPS_ASSERT(!cong_obj_has_cpp_cong(o)); - initRNams(); - - gap_list_t genpairs = ElmPRec(o, RNam_genpairs); - gap_semigroup_t range_obj = cong_obj_get_range_obj(o); - std::string type = std::string(CSTR_STRING(ElmPRec(o, RNam_type))); - Congruence* cong; - bool report = semi_obj_get_report(range_obj); + gap_list_t genpairs = ElmPRec(o, RNam_genpairs); + gap_semigroup_t range_obj = cong_obj_get_range_obj(o); + congruence_type type + = cstring_to_congruence_t(CSTR_STRING(ElmPRec(o, RNam_type))); + Congruence* cong = nullptr; + bool report = semi_obj_get_report(range_obj); + auto rg = ReportGuard(report); if (cong_obj_is_fp_cong(o)) { size_t nrgens = INT_INTOBJ(ElmPRec(o, RNam_fp_nrgens)); + auto S = libsemigroups::detail::make_unique(); + S->set_alphabet(nrgens); + // Get the fp semigroup's rels - gap_list_t gap_rels = ElmPRec(o, RNam_fp_rels); - word_t lhs, rhs; - std::vector rels; - rels.reserve(LEN_PLIST(gap_rels)); + gap_list_t gap_rels = ElmPRec(o, RNam_fp_rels); for (size_t i = 1; i <= (size_t) LEN_PLIST(gap_rels); i++) { gap_list_t rel = ELM_PLIST(gap_rels, i); - lhs = plist_to_word_t(ELM_PLIST(rel, 1)); - rhs = plist_to_word_t(ELM_PLIST(rel, 2)); - rels.push_back(make_pair(lhs, rhs)); + S->add_rule(plist_to_word_type(ELM_PLIST(rel, 1)), + plist_to_word_type(ELM_PLIST(rel, 2))); } + cong = new Congruence(type, *S); + // Get the extra pairs - gap_list_t gap_extra = ElmPRec(o, RNam_fp_extra); - std::vector extra; - extra.reserve(LEN_PLIST(gap_extra)); + gap_list_t gap_extra = ElmPRec(o, RNam_fp_extra); for (size_t i = 1; i <= (size_t) LEN_PLIST(gap_extra); i++) { gap_list_t pair = ELM_PLIST(gap_extra, i); - lhs = plist_to_word_t(ELM_PLIST(pair, 1)); - rhs = plist_to_word_t(ELM_PLIST(pair, 2)); - extra.push_back(make_pair(lhs, rhs)); + cong->add_pair(plist_to_word_type(ELM_PLIST(pair, 1)), + plist_to_word_type(ELM_PLIST(pair, 2))); } - - cong = new Congruence(type, nrgens, rels, extra); - cong->set_report(report); } else if (cong_obj_get_range_type(o) != UNKNOWN) { - Semigroup* range = cong_obj_get_range(o); - range->set_report(report); - - std::vector extra; - word_t lhs, rhs; + FroidurePin* range = cong_obj_get_range(o); + cong = new Congruence(type, *range); for (size_t i = 1; i <= (size_t) LEN_PLIST(genpairs); i++) { Obj lhs_obj = ELM_PLIST(ELM_PLIST(genpairs, i), 1); Obj rhs_obj = ELM_PLIST(ELM_PLIST(genpairs, i), 2); - - range->factorisation( - lhs, INT_INTOBJ(EN_SEMI_POSITION(0L, range_obj, lhs_obj)) - 1); - range->factorisation( - rhs, INT_INTOBJ(EN_SEMI_POSITION(0L, range_obj, rhs_obj)) - 1); - - extra.push_back(make_pair(lhs, rhs)); - lhs.clear(); - rhs.clear(); + cong->add_pair( + range->factorisation( + INT_INTOBJ(EN_SEMI_POSITION(0L, range_obj, lhs_obj)) - 1), + range->factorisation( + INT_INTOBJ(EN_SEMI_POSITION(0L, range_obj, rhs_obj)) - 1)); } - cong = new Congruence(type, range, extra); - cong->set_report(report); } else { - gap_rec_t data = fropin(range_obj, INTOBJ_INT(-1), 0, False); - gap_list_t rules = ElmPRec(data, RNam_rules); - gap_list_t words = ElmPRec(data, RNam_words); - std::vector rels; - std::vector extra; - - // convert the rules (i.e. relations) to relation_t's - for (size_t i = 1; i <= (size_t) LEN_PLIST(rules); i++) { - word_t lhs = plist_to_word_t(ELM_PLIST(ELM_PLIST(rules, i), 1)); - word_t rhs = plist_to_word_t(ELM_PLIST(ELM_PLIST(rules, i), 2)); - rels.push_back(make_pair(lhs, rhs)); - } + gap_rec_t data = fropin(range_obj, INTOBJ_INT(-1), 0, False); + // gap_list_t rules = ElmPRec(data, RNam_rules); + gap_list_t words = ElmPRec(data, RNam_words); - // convert the generating pairs to relation_t's + size_t nrgens = LEN_PLIST(semi_obj_get_gens(range_obj)); + + cong = new Congruence(type, Congruence::policy::runners::none); + cong->set_nr_generators(nrgens); + + auto tc = new libsemigroups::congruence::ToddCoxeter(type); + tc->set_nr_generators(nrgens); + + // convert the generating pairs to relation_type's for (size_t i = 1; i <= (size_t) LEN_PLIST(genpairs); i++) { Obj lhs_obj = ELM_PLIST(ELM_PLIST(genpairs, i), 1); Obj rhs_obj = ELM_PLIST(ELM_PLIST(genpairs, i), 2); @@ -166,40 +169,33 @@ static void cong_obj_init_cpp_cong(gap_cong_t o) { INT_INTOBJ(EN_SEMI_POSITION(0L, range_obj, lhs_obj))); Obj rhs = ELM_PLIST(words, INT_INTOBJ(EN_SEMI_POSITION(0L, range_obj, rhs_obj))); - - extra.push_back(make_pair(plist_to_word_t(lhs), plist_to_word_t(rhs))); + tc->add_pair(plist_to_word_type(lhs), plist_to_word_type(rhs)); } - size_t nrgens = LEN_PLIST(semi_obj_get_gens(range_obj)); - Obj graph; - if (type == "left") { + if (type == congruence_type::left) { // the left Cayley graph graph = ElmPRec(data, RNam_left); } else { - SEMIGROUPS_ASSERT(type == "right" || type == "twosided"); + SEMIGROUPS_ASSERT(type == congruence_type::right + || type == congruence_type::twosided); // the right Cayley graph graph = ElmPRec(data, RNam_right); } - RecVec prefill(nrgens, LEN_PLIST(graph) + 1); - - Obj genslookup = ElmPRec(data, RNam_genslookup); - for (size_t i = 0; i < nrgens; i++) { - prefill.set(0, i, INT_INTOBJ(ELM_PLIST(genslookup, i + 1))); - } + DynamicArray2 table(nrgens, LEN_PLIST(graph)); for (size_t i = 1; i <= (size_t) LEN_PLIST(graph); i++) { Obj next = ELM_PLIST(graph, i); for (size_t j = 1; j <= nrgens; j++) { - prefill.set(i, j - 1, INT_INTOBJ(ELM_PLIST(next, j))); + table.set(i - 1, j - 1, INT_INTOBJ(ELM_PLIST(next, j)) - 1); } } - cong = new Congruence(type, nrgens, std::vector(), extra); - cong->set_report(report); - cong->set_prefill(prefill); + tc->prefill(table); + cong->add_runner(*tc); } + SEMIGROUPS_ASSERT(cong != nullptr); AssPRec(o, RNam_cong_pairs_congruence, OBJ_CLASS(cong, T_SEMI_SUBTYPE_CONG)); } @@ -221,17 +217,17 @@ Obj CONG_PAIRS_NR_CLASSES(Obj self, gap_cong_t o) { Obj CONG_PAIRS_IN(Obj self, gap_cong_t o, Obj elm1, Obj elm2) { initRNams(); - word_t lhs, rhs; + word_type lhs, rhs; if (cong_obj_is_fp_cong(o)) { - lhs = plist_to_word_t(elm1); - rhs = plist_to_word_t(elm2); + lhs = plist_to_word_type(elm1); + rhs = plist_to_word_type(elm2); } else { gap_semigroup_t S = cong_obj_get_range_obj(o); size_t lhs_pos = INT_INTOBJ(EN_SEMI_POSITION(0L, S, elm1)); size_t rhs_pos = INT_INTOBJ(EN_SEMI_POSITION(0L, S, elm2)); - SEMIGROUPS_ASSERT(lhs_pos != Semigroup::UNDEFINED); - SEMIGROUPS_ASSERT(rhs_pos != Semigroup::UNDEFINED); + SEMIGROUPS_ASSERT(lhs_pos != UNDEFINED); + SEMIGROUPS_ASSERT(rhs_pos != UNDEFINED); if (IsbPRec(o, RNam_fin_cong_lookup)) { // TODO(JDM) use FindPRec and GET_ELM_PREC @@ -241,7 +237,7 @@ Obj CONG_PAIRS_IN(Obj self, gap_cong_t o, Obj elm1, Obj elm2) { } if (cong_obj_get_range_type(o) != UNKNOWN) { - Semigroup* range = cong_obj_get_range(o); + FroidurePin* range = cong_obj_get_range(o); range->factorisation(lhs, lhs_pos - 1); range->factorisation(rhs, rhs_pos - 1); @@ -249,13 +245,13 @@ Obj CONG_PAIRS_IN(Obj self, gap_cong_t o, Obj elm1, Obj elm2) { gap_rec_t data = fropin(S, INTOBJ_INT(-1), 0, False); gap_list_t words = ElmPRec(data, RNam_words); - lhs = plist_to_word_t(ELM_PLIST(words, lhs_pos)); - rhs = plist_to_word_t(ELM_PLIST(words, rhs_pos)); + lhs = plist_to_word_type(ELM_PLIST(words, lhs_pos)); + rhs = plist_to_word_type(ELM_PLIST(words, rhs_pos)); } } Congruence* cong = cong_obj_get_cpp(o); - return (cong->test_equals(lhs, rhs) ? True : False); + return (cong->contains(lhs, rhs) ? True : False); } // This describes a total ordering on the classes of the congruence. @@ -266,18 +262,18 @@ Obj CONG_PAIRS_LESS_THAN(Obj self, gap_list_t rep2) { initRNams(); - word_t lhs, rhs; + word_type lhs, rhs; if (cong_obj_is_fp_cong(o)) { - lhs = plist_to_word_t(rep1); - rhs = plist_to_word_t(rep2); + lhs = plist_to_word_type(rep1); + rhs = plist_to_word_type(rep2); } else { gap_semigroup_t S = cong_obj_get_range_obj(o); size_t lhs_pos = INT_INTOBJ(EN_SEMI_POSITION(0L, S, rep1)); size_t rhs_pos = INT_INTOBJ(EN_SEMI_POSITION(0L, S, rep2)); if (cong_obj_get_range_type(o) != UNKNOWN) { - Semigroup* range = cong_obj_get_range(o); + FroidurePin* range = cong_obj_get_range(o); range->factorisation(lhs, lhs_pos - 1); range->factorisation(rhs, rhs_pos - 1); @@ -285,13 +281,13 @@ Obj CONG_PAIRS_LESS_THAN(Obj self, gap_rec_t data = fropin(S, INTOBJ_INT(-1), 0, False); gap_list_t words = ElmPRec(data, RNam_words); - lhs = plist_to_word_t(ELM_PLIST(words, lhs_pos)); - rhs = plist_to_word_t(ELM_PLIST(words, rhs_pos)); + lhs = plist_to_word_type(ELM_PLIST(words, lhs_pos)); + rhs = plist_to_word_type(ELM_PLIST(words, rhs_pos)); } } Congruence* cong = cong_obj_get_cpp(o); - return (cong->test_less_than(lhs, rhs) ? True : False); + return (cong->less(lhs, rhs) ? True : False); } Obj CONG_PAIRS_LOOKUP_PART(Obj self, gap_cong_t o) { @@ -323,13 +319,13 @@ Obj CONG_PAIRS_LOOKUP_PART(Obj self, gap_cong_t o) { Obj lookup; if (cong_obj_get_range_type(o) != UNKNOWN) { - Semigroup* range = cong_obj_get_range(o); - range->set_report(report); + FroidurePin* range = cong_obj_get_range(o); + auto rg = ReportGuard(report); lookup = NEW_PLIST_IMM(T_PLIST_CYC, range->size()); SET_LEN_PLIST(lookup, range->size()); - word_t word; + word_type word; for (size_t i = 0; i < range->size(); i++) { range->factorisation(word, i); // changes word in place size_t class_index = cong->word_to_class_index(word); @@ -359,7 +355,7 @@ Obj CONG_PAIRS_LOOKUP_PART(Obj self, gap_cong_t o) { for (size_t i = 1; i <= (size_t) LEN_PLIST(words); i++) { size_t class_index - = cong->word_to_class_index(plist_to_word_t(ELM_PLIST(words, i))); + = cong->word_to_class_index(plist_to_word_type(ELM_PLIST(words, i))); auto it = class_dictionary.find(class_index); if (it == class_dictionary.end()) { @@ -395,13 +391,12 @@ Obj CONG_PAIRS_ELM_COSET_ID(Obj self, gap_cong_t cong_obj, Obj elm) { } else if (cong_obj_is_fp_cong(cong_obj)) { // elm should be a gap_list_t representing a word Congruence* cong = cong_obj_get_cpp(cong_obj); - return INTOBJ_INT(cong->word_to_class_index(plist_to_word_t(elm)) + 1); + return INTOBJ_INT(cong->word_to_class_index(plist_to_word_type(elm)) + 1); } else if (cong_obj_get_range_type(cong_obj) != UNKNOWN) { - Congruence* cong = cong_obj_get_cpp(cong_obj); - Semigroup* range = cong_obj_get_range(cong_obj); - range->set_report(report); - - word_t word; + Congruence* cong = cong_obj_get_cpp(cong_obj); + FroidurePin* range = cong_obj_get_range(cong_obj); + auto rg = ReportGuard(report); + word_type word; range->factorisation( word, INT_INTOBJ(EN_SEMI_POSITION(self, range_obj, elm)) - 1); return INTOBJ_INT(cong->word_to_class_index(word) + 1); @@ -412,7 +407,7 @@ Obj CONG_PAIRS_ELM_COSET_ID(Obj self, gap_cong_t cong_obj, Obj elm) { Obj word = ELM_PLIST(ElmPRec(data, RNam_words), INT_INTOBJ(EN_SEMI_POSITION(self, range_obj, elm))); - return INTOBJ_INT(cong->word_to_class_index(plist_to_word_t(word)) + 1); + return INTOBJ_INT(cong->word_to_class_index(plist_to_word_type(word)) + 1); } } @@ -420,26 +415,22 @@ gap_list_t CONG_PAIRS_NONTRIVIAL_CLASSES(Obj self, gap_cong_t o) { initRNams(); Congruence* cong = cong_obj_get_cpp(o); - Partition* nt_classes = cong->nontrivial_classes(); - // Initialise gap_lists - gap_list_t gap_lists = NEW_PLIST_IMM(T_PLIST_TAB, nt_classes->size()); - SET_LEN_PLIST(gap_lists, nt_classes->size()); + gap_list_t gap_lists + = NEW_PLIST_IMM(T_PLIST_TAB, cong->nr_non_trivial_classes()); + SET_LEN_PLIST(gap_lists, cong->nr_non_trivial_classes()); // Convert the words to plists - for (size_t c = 0; c < nt_classes->size(); c++) { - gap_list_t next_class - = NEW_PLIST_IMM(T_PLIST_TAB, (*nt_classes)[c]->size()); - SET_LEN_PLIST(next_class, (*nt_classes)[c]->size()); - for (size_t e = 0; e < (*nt_classes)[c]->size(); e++) { - SET_ELM_PLIST(next_class, e + 1, word_t_to_plist((*(*nt_classes)[c])[e])); + for (auto it1 = cong->cbegin_ntc(); it1 < cong->cend_ntc(); ++it1) { + gap_list_t next_class = NEW_PLIST_IMM(T_PLIST_TAB, it1->size()); + SET_LEN_PLIST(next_class, it1->size()); + size_t pos = 0; + for (auto it2 = it1->cbegin(); it2 < it1->cend(); ++it2) { + SET_ELM_PLIST(next_class, ++pos, word_type_to_plist(&(*it2))); CHANGED_BAG(next_class); } - SET_ELM_PLIST(gap_lists, c + 1, next_class); + SET_ELM_PLIST(gap_lists, (it1 - cong->cbegin_ntc()) + 1, next_class); CHANGED_BAG(gap_lists); } - - delete nt_classes; - return gap_lists; } diff --git a/src/converter.cc b/src/converter.cc index 5f9fa93aa..95e411fa5 100644 --- a/src/converter.cc +++ b/src/converter.cc @@ -36,16 +36,15 @@ BooleanMat* BoolMatConverter::convert(Obj o, size_t n) const { SEMIGROUPS_ASSERT(CALL_1ARGS(IsBooleanMat, o)); SEMIGROUPS_ASSERT(IS_BLIST_REP(ELM_PLIST(o, 1))); - size_t m = LEN_BLIST(ELM_PLIST(o, 1)); - std::vector* x(new std::vector()); - x->resize(m * m, false); + size_t m = LEN_BLIST(ELM_PLIST(o, 1)); + std::vector x(m * m, false); for (size_t i = 0; i < m; i++) { Obj row = ELM_PLIST(o, i + 1); SEMIGROUPS_ASSERT(IS_BLIST_REP(row)); for (size_t j = 0; j < m; j++) { if (ELM_BLIST(row, j + 1) == True) { - x->at(i * m + j) = true; + x.at(i * m + j) = true; } } } @@ -89,12 +88,11 @@ Obj BoolMatConverter::unconvert(Element const* x) const { Bipartition* BipartConverter::convert(Obj o, size_t n) const { SEMIGROUPS_ASSERT(TNUM_OBJ(o) == T_BIPART); - return static_cast( - static_cast(bipart_get_cpp(o))->really_copy()); + return new Bipartition(*bipart_get_cpp(o)); } Obj BipartConverter::unconvert(Element const* x) const { - return bipart_new_obj(static_cast(x->really_copy())); + return bipart_new_obj(new Bipartition(*static_cast(x))); } //////////////////////////////////////////////////////////////////////////////// @@ -115,10 +113,9 @@ Obj PBRConverter::get_gap_type(size_t deg) const { PBR* PBRConverter::convert(Obj o, size_t n) const { SEMIGROUPS_ASSERT(CALL_1ARGS(IsPBR, o)); - size_t m = INT_INTOBJ(ELM_PLIST(o, 1)); - std::vector>* pbr( - new std::vector>()); - pbr->reserve(m); + size_t m = INT_INTOBJ(ELM_PLIST(o, 1)); + std::vector> pbr; + pbr.reserve(m); for (u_int32_t i = 0; i < 2 * m; i++) { Obj adj = ELM_PLIST(o, i + 2); @@ -128,7 +125,7 @@ PBR* PBRConverter::convert(Obj o, size_t n) const { // assumes that adj is duplicate-free } std::sort(next.begin(), next.end()); - pbr->push_back(next); + pbr.push_back(next); } return new PBR(pbr); } diff --git a/src/converter.h b/src/converter.h index b8f29f798..c4892a4b5 100644 --- a/src/converter.h +++ b/src/converter.h @@ -37,15 +37,15 @@ #include "src/compiled.h" #include "pkg.h" - #include "semigroups-debug.h" -#include "libsemigroups/elements.h" +#include "libsemigroups/element.hpp" +#include "libsemigroups/semiring.hpp" using libsemigroups::Bipartition; using libsemigroups::BooleanMat; using libsemigroups::Element; -using libsemigroups::MatrixOverSemiringBase; +using libsemigroups::detail::MatrixOverSemiringBase; using libsemigroups::NaturalSemiring; using libsemigroups::PartialPerm; using libsemigroups::PBR; @@ -53,6 +53,7 @@ using libsemigroups::ProjectiveMaxPlusMatrix; using libsemigroups::Semiring; using libsemigroups::SemiringWithThreshold; using libsemigroups::Transformation; +using libsemigroups::UNDEFINED; //////////////////////////////////////////////////////////////////////////////// // Abstract base class @@ -69,24 +70,25 @@ class Converter { // Transformations //////////////////////////////////////////////////////////////////////////////// -template class TransConverter : public Converter { +template +class TransConverter : public Converter { public: Transformation* convert(Obj o, size_t n) const override { SEMIGROUPS_ASSERT(IS_TRANS(o)); - auto x = new std::vector(); - x->reserve(n); + std::vector x; + x.reserve(n); size_t i = 0; if (TNUM_OBJ(o) == T_TRANS2) { UInt2* pto2 = ADDR_TRANS2(o); for (i = 0; i < std::min((size_t) DEG_TRANS2(o), n); i++) { - x->push_back(pto2[i]); + x.push_back(pto2[i]); } } else if (TNUM_OBJ(o) == T_TRANS4) { UInt4* pto4 = ADDR_TRANS4(o); for (i = 0; i < std::min((size_t) DEG_TRANS4(o), n); i++) { - x->push_back(pto4[i]); + x.push_back(pto4[i]); } } else { // in case of future changes to transformations in GAP @@ -94,7 +96,7 @@ template class TransConverter : public Converter { } for (; i < n; i++) { - x->push_back(i); + x.push_back(i); } return new Transformation(x); } @@ -115,31 +117,32 @@ template class TransConverter : public Converter { // Partial perms //////////////////////////////////////////////////////////////////////////////// -template class PPermConverter : public Converter { +template +class PPermConverter : public Converter { public: PartialPerm* convert(Obj o, size_t n) const override { SEMIGROUPS_ASSERT(IS_PPERM(o)); - auto x = new std::vector(); - x->reserve(n); + std::vector x; + x.reserve(n); size_t i = 0; if (TNUM_OBJ(o) == T_PPERM2) { UInt2* pto2 = ADDR_PPERM(o); for (i = 0; i < std::min((size_t) DEG_PPERM2(o), n); i++) { if (pto2[i] == 0) { - x->push_back(UNDEFINED); + x.push_back(UNDEFINED); } else { - x->push_back(pto2[i] - 1); + x.push_back(pto2[i] - 1); } } } else if (TNUM_OBJ(o) == T_PPERM4) { UInt4* pto4 = ADDR_PPERM(o); for (i = 0; i < std::min((size_t) DEG_PPERM4(o), n); i++) { if (pto4[i] == 0) { - x->push_back(UNDEFINED); + x.push_back(UNDEFINED); } else { - x->push_back(pto4[i] - 1); + x.push_back(pto4[i] - 1); } } } else { @@ -148,7 +151,7 @@ template class PPermConverter : public Converter { } for (; i < n; i++) { - x->push_back(UNDEFINED); + x.push_back(UNDEFINED); } return new PartialPerm(x); } @@ -186,11 +189,10 @@ template class PPermConverter : public Converter { } } - template inline UIntT* ADDR_PPERM(Obj x) const { + template + inline UIntT* ADDR_PPERM(Obj x) const { return reinterpret_cast(static_cast(ADDR_OBJ(x)) + 2) + 1; } - - T UNDEFINED = (T) -1; }; //////////////////////////////////////////////////////////////////////////////// @@ -226,17 +228,17 @@ class MatrixOverSemiringConverter : public Converter { size_t m = LEN_PLIST(ELM_PLIST(o, 1)); - std::vector* matrix(new std::vector()); - matrix->reserve(m); + std::vector matrix; + matrix.reserve(m); for (size_t i = 0; i < m; i++) { Obj row = ELM_PLIST(o, i + 1); for (size_t j = 0; j < m; j++) { Obj entry = ELM_PLIST(row, j + 1); if (EQ(_gap_zero, entry)) { - matrix->push_back(_semiring->zero()); + matrix.push_back(_semiring->zero()); } else { - matrix->push_back(INT_INTOBJ(entry)); + matrix.push_back(INT_INTOBJ(entry)); } } } diff --git a/src/fropin.cc b/src/fropin.cc index 2de1dbca6..9918cad6c 100644 --- a/src/fropin.cc +++ b/src/fropin.cc @@ -21,13 +21,11 @@ #include #include -#include "libsemigroups/report.h" #include "rnams.h" #include "semigroups-debug.h" #include "semigrp.h" -using libsemigroups::glob_reporter; -using libsemigroups::Timer; +using libsemigroups::detail::Timer; // Macros for the GAP version of the algorithm @@ -112,9 +110,9 @@ Obj fropin(Obj obj, Obj limit, Obj lookfunc, Obj looking) { return data; } int_limit = std::max((size_t) INT_INTOBJ(limit), (size_t)(nr + batch_size)); - - glob_reporter.set_report(report); - REPORT_FROM_FUNC("limit = " << int_limit); + if (report) { + std::cout << "limit = " << int_limit << "\n"; + } Timer timer; @@ -313,15 +311,16 @@ Obj fropin(Obj obj, Obj limit, Obj lookfunc, Obj looking) { len++; AssPlist(lenindex, len, INTOBJ_INT(i)); } - if (i <= nr) { - REPORT_FROM_FUNC("found " << nr << " elements, " << nrrules - << " rules, max word length " << len + 1 - << ", so far"); - } else { - REPORT_FROM_FUNC("found " << nr << " elements, " << nrrules - << " rules, max word length " << len + 1 - << ", finished!"); - REPORT_FROM_FUNC("elapsed time = " << timer); // NOLINT() + if (report) { + if (i <= nr) { + std::cout << "found " << nr << " elements, " << nrrules + << " rules, max word length " << len + 1 << ", so far,\n"; + } else { + std::cout << "found " << nr << " elements, " << nrrules + << " rules, max word length " << len + 1 << ", finished!\n"; + // NOLINTNEXTLINE(build/include_what_you_use) + std::cout << "elapsed time = " << timer.string() << "\n"; + } } } diff --git a/src/pkg.cc b/src/pkg.cc index c4e38c8e1..9399770b0 100644 --- a/src/pkg.cc +++ b/src/pkg.cc @@ -32,12 +32,13 @@ #include "semigrp.h" #include "uf.h" -#include "libsemigroups/cong.h" -#include "libsemigroups/semigroups.h" -#include "libsemigroups/uf.h" +#include "libsemigroups/blocks.hpp" +#include "libsemigroups/cong.hpp" +#include "libsemigroups/froidure-pin.hpp" +#include "libsemigroups/uf.hpp" using libsemigroups::Congruence; -using libsemigroups::UF; +using libsemigroups::detail::UF; #if !defined(SIZEOF_VOID_P) #error Something is wrong with this GAP installation: SIZEOF_VOID_P not defined @@ -111,7 +112,7 @@ void TSemiObjFreeFunc(Obj o) { // don't use functions to access these since they have too many // side effects delete CLASS_OBJ(o, 4); - delete CLASS_OBJ(o, 5); + delete CLASS_OBJ*>(o, 5); } break; } @@ -121,7 +122,6 @@ void TSemiObjFreeFunc(Obj o) { void TBipartObjFreeFunc(Obj o) { SEMIGROUPS_ASSERT(TNUM_OBJ(o) == T_BIPART); - bipart_get_cpp(o)->really_delete(); delete bipart_get_cpp(o); } @@ -207,7 +207,7 @@ void TSemiObjLoadFunc(Obj o) { ADDR_OBJ(o)[2] = LoadSubObj(); // semigroup Obj ADDR_OBJ(o)[3] = reinterpret_cast(LoadUInt4()); // degree ADDR_OBJ(o)[4] = static_cast(nullptr); // Converter* - ADDR_OBJ(o)[5] = static_cast(nullptr); // Semigroup* + ADDR_OBJ(o)[5] = static_cast(nullptr); // FroidurePin* CHANGED_BAG(o); } break; @@ -247,12 +247,12 @@ void TBipartObjSaveFunc(Obj o) { } void TBipartObjLoadFunc(Obj o) { - UInt4 deg = LoadUInt4(); - std::vector* blocks = new std::vector(); - blocks->reserve(2 * deg); + UInt4 deg = LoadUInt4(); + std::vector blocks; + blocks.reserve(2 * deg); for (size_t i = 0; i < 2 * deg; i++) { - blocks->push_back(LoadUInt4()); + blocks.push_back(LoadUInt4()); } ADDR_OBJ(o)[0] = reinterpret_cast(new Bipartition(blocks)); SEMIGROUPS_ASSERT(ADDR_OBJ(o)[1] == NULL && ADDR_OBJ(o)[2] == NULL); diff --git a/src/pkg.h b/src/pkg.h index 715e12eb6..d32cea002 100644 --- a/src/pkg.h +++ b/src/pkg.h @@ -51,7 +51,7 @@ #if !defined(GAP_KERNEL_MAJOR_VERSION) || GAP_KERNEL_MAJOR_VERSION < 3 // compatibility with GAP <= 4.9 static inline Obj NEW_PLIST_IMM(UInt type, Int plen) { - return NEW_PLIST(type | IMMUTABLE, plen); + return NEW_PLIST(type | IMMUTABLE, plen); } #endif @@ -101,7 +101,8 @@ inline Obj OBJ_CLASS(Class* cpp_class, t_semi_subtype_t type, size_t size = 2) { // Get a pointer to a C++ object of type Class from GAP Obj of type T_SEMI -template inline Class CLASS_OBJ(Obj o, size_t pos = 1) { +template +inline Class CLASS_OBJ(Obj o, size_t pos = 1) { return reinterpret_cast(ADDR_OBJ(o)[pos]); } diff --git a/src/semigrp.cc b/src/semigrp.cc index fd9c6fec8..026eaca83 100644 --- a/src/semigrp.cc +++ b/src/semigrp.cc @@ -26,19 +26,20 @@ #include "bipart.h" #include "converter.h" #include "fropin.h" +#include "libsemigroups/froidure-pin-base.hpp" #include "pkg.h" #include "src/compiled.h" -using libsemigroups::cayley_graph_t; using libsemigroups::Integers; +using libsemigroups::LIMIT_MAX; using libsemigroups::MatrixOverSemiring; using libsemigroups::MaxPlusSemiring; using libsemigroups::MinPlusSemiring; using libsemigroups::NaturalSemiring; -using libsemigroups::really_delete_cont; using libsemigroups::TropicalMaxPlusSemiring; using libsemigroups::TropicalMinPlusSemiring; -using libsemigroups::word_t; +using libsemigroups::UNDEFINED; +using libsemigroups::word_type; #ifdef SEMIGROUPS_KERNEL_DEBUG #define ERROR(obj, message) \ @@ -78,12 +79,18 @@ using libsemigroups::word_t; #define CHECK_POS_INTOBJ(obj) #endif -std::vector* plist_to_vec(Converter* converter, - gap_list_t elements, - size_t degree) { +template +void delete_vec(std::vector* vec) { + for (auto x : *vec) { + delete x; + } +} + +std::vector* +plist_to_vec(Converter* converter, gap_list_t elements, size_t degree) { SEMIGROUPS_ASSERT(IS_PLIST(elements)); - auto out = new std::vector(); + auto out = new std::vector(); for (size_t i = 0; i < (size_t) LEN_PLIST(elements); i++) { out->push_back(converter->convert(ELM_LIST(elements, i + 1), degree)); @@ -92,9 +99,8 @@ std::vector* plist_to_vec(Converter* converter, } template -static inline gap_list_t iterator_to_plist(Converter* converter, - T first, - T last) { +static inline gap_list_t +iterator_to_plist(Converter* converter, T first, T last) { gap_list_t out = NEW_PLIST((first == last ? T_PLIST_EMPTY : T_PLIST_HOM), last - first); SET_LEN_PLIST(out, last - first); @@ -106,7 +112,7 @@ static inline gap_list_t iterator_to_plist(Converter* converter, return out; } -gap_list_t word_t_to_plist(word_t const& word) { +gap_list_t word_type_to_plist(word_type const& word) { SEMIGROUPS_ASSERT(!word.empty()); gap_list_t out = NEW_PLIST_IMM(T_PLIST_CYC, word.size()); // IMMUTABLE since it should not be altered on the GAP level @@ -248,7 +254,7 @@ static inline size_t semi_obj_get_period(gap_semigroup_t so) { // 2: gap_semigroup_t so, // 3: size_t degree, // 4: Converter*, -// 5: Semigroup* +// 5: FroidurePin* // // To call en_semi_init_converter positions 0 to 3 must already be set, and 4 // and 5 must be nullptrs. To call en_semi_init_semigroup, @@ -347,9 +353,9 @@ Converter* en_semi_init_converter(en_semi_obj_t es) { return converter; } -Semigroup* en_semi_init_semigroup(en_semi_obj_t es) { +FroidurePin* en_semi_init_semigroup(en_semi_obj_t es) { SEMIGROUPS_ASSERT(en_semi_get_type(es) != UNKNOWN); - SEMIGROUPS_ASSERT(CLASS_OBJ(es, 5) == nullptr); + SEMIGROUPS_ASSERT(CLASS_OBJ*>(es, 5) == nullptr); initRNams(); if (en_semi_get_converter(es) == nullptr) { @@ -361,9 +367,9 @@ Semigroup* en_semi_init_semigroup(en_semi_obj_t es) { size_t deg = en_semi_get_degree(es); gap_list_t plist = semi_obj_get_gens(so); auto gens = plist_to_vec(converter, plist, deg); - Semigroup* semi_cpp = new Semigroup(gens); - semi_cpp->set_batch_size(semi_obj_get_batch_size(so)); - really_delete_cont(gens); + FroidurePin* semi_cpp = new FroidurePin(gens); + semi_cpp->batch_size(semi_obj_get_batch_size(so)); + delete_vec(gens); ADDR_OBJ(es)[5] = reinterpret_cast(semi_cpp); return semi_cpp; @@ -462,11 +468,11 @@ Converter* en_semi_get_converter(en_semi_obj_t es) { return (converter != nullptr ? converter : en_semi_init_converter(es)); } -Semigroup* en_semi_get_semi_cpp(en_semi_obj_t es) { +FroidurePin* en_semi_get_semi_cpp(en_semi_obj_t es) { SEMIGROUPS_ASSERT(TNUM_OBJ(es) == T_SEMI && SUBTYPE_OF_T_SEMI(es) == T_SEMI_SUBTYPE_ENSEMI); SEMIGROUPS_ASSERT(en_semi_get_type(es) != UNKNOWN); - Semigroup* semi_cpp = CLASS_OBJ(es, 5); + FroidurePin* semi_cpp = CLASS_OBJ*>(es, 5); return (semi_cpp != nullptr ? semi_cpp : en_semi_init_semigroup(es)); } @@ -497,7 +503,7 @@ en_semi_t semi_obj_get_type(gap_semigroup_t so) { return en_semi_get_type(semi_obj_get_en_semi(so)); } -Semigroup* semi_obj_get_semi_cpp(gap_semigroup_t so) { +FroidurePin* semi_obj_get_semi_cpp(gap_semigroup_t so) { CHECK_SEMI_OBJ(so); return en_semi_get_semi_cpp(semi_obj_get_en_semi(so)); } @@ -532,9 +538,9 @@ gap_list_t EN_SEMI_AS_LIST(Obj self, gap_semigroup_t so) { en_semi_obj_t es = semi_obj_get_en_semi(so); if (en_semi_get_type(es) != UNKNOWN) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); - semi_cpp->enumerate(); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); + semi_cpp->run(); return iterator_to_plist( en_semi_get_converter(es), semi_cpp->cbegin(), semi_cpp->cend()); } else { @@ -547,8 +553,8 @@ gap_list_t EN_SEMI_AS_SET(Obj self, gap_semigroup_t so) { en_semi_obj_t es = semi_obj_get_en_semi(so); if (en_semi_get_type(es) != UNKNOWN) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); Converter* converter = en_semi_get_converter(es); // The T_PLIST_HOM_SSORTED makes a huge difference to performance!! gap_list_t out = NEW_PLIST_IMM(T_PLIST_HOM_SSORT, semi_cpp->size()); @@ -573,9 +579,8 @@ gap_list_t EN_SEMI_CAYLEY_TABLE(Obj self, gap_semigroup_t so) { CHECK_SEMI_OBJ(so); en_semi_obj_t es = semi_obj_get_en_semi(so); if (en_semi_get_type(es) != UNKNOWN) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); - + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); size_t n = semi_cpp->size(); SEMIGROUPS_ASSERT(n != 0); gap_list_t out = NEW_PLIST(T_PLIST_TAB_RECT, n); @@ -644,7 +649,7 @@ gap_semigroup_t EN_SEMI_CLOSURE(Obj self, Converter* converter = en_semi_get_converter(es); auto coll = plist_to_vec(converter, plist, deg); - Semigroup* old_semi_cpp = semi_obj_get_semi_cpp(old_so); + FroidurePin* old_semi_cpp = semi_obj_get_semi_cpp(old_so); // CAUTION: copy_closure always copies old_semi_cpp regardless of whether or // not every element in coll belongs to old_semi_cpp!! Only call this @@ -654,26 +659,26 @@ gap_semigroup_t EN_SEMI_CLOSURE(Obj self, #ifdef SEMIGROUPS_KERNEL_DEBUG bool valid = false; for (auto const& x : *coll) { - if (!old_semi_cpp->test_membership(x)) { + if (!old_semi_cpp->contains(x)) { valid = true; break; } } SEMIGROUPS_ASSERT(valid); #endif - old_semi_cpp->set_report(semi_obj_get_report(new_so)); - Semigroup* new_semi_cpp = old_semi_cpp->copy_closure(coll); - really_delete_cont(coll); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(new_so)); + FroidurePin* new_semi_cpp = old_semi_cpp->copy_closure(*coll); + delete_vec(coll); - new_semi_cpp->set_batch_size(semi_obj_get_batch_size(new_so)); + new_semi_cpp->batch_size(semi_obj_get_batch_size(new_so)); ADDR_OBJ(es)[5] = reinterpret_cast(new_semi_cpp); CHANGED_BAG(es); // Reset the generators of the new semigroup - gap_list_t gens = NEW_PLIST(T_PLIST_HOM, new_semi_cpp->nrgens()); + gap_list_t gens = NEW_PLIST(T_PLIST_HOM, new_semi_cpp->nr_generators()); - for (size_t i = 0; i < new_semi_cpp->nrgens(); i++) { - AssPlist(gens, i + 1, converter->unconvert(new_semi_cpp->gens(i))); + for (size_t i = 0; i < new_semi_cpp->nr_generators(); i++) { + AssPlist(gens, i + 1, converter->unconvert(new_semi_cpp->generator(i))); } AssPRec(new_so, RNam_GeneratorsOfMagma, gens); @@ -690,9 +695,8 @@ gap_semigroup_t EN_SEMI_CLOSURE(Obj self, // the elements in . If this is not the case, then this should not be // called but ClosureSemigroup should be instead, on the GAP level. -gap_semigroup_t EN_SEMI_CLOSURE_DEST(Obj self, - gap_semigroup_t so, - gap_list_t plist) { +gap_semigroup_t +EN_SEMI_CLOSURE_DEST(Obj self, gap_semigroup_t so, gap_list_t plist) { CHECK_SEMI_OBJ(so); CHECK_PLIST(plist); @@ -705,19 +709,19 @@ gap_semigroup_t EN_SEMI_CLOSURE_DEST(Obj self, SEMIGROUPS_ASSERT(IS_PLIST(plist)); SEMIGROUPS_ASSERT(LEN_PLIST(plist) > 0); - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); size_t const deg = semi_cpp->degree(); Converter* converter = en_semi_get_converter(es); auto coll = plist_to_vec(converter, plist, deg); - semi_cpp->set_report(semi_obj_get_report(so)); - semi_cpp->closure(coll); - really_delete_cont(coll); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); + semi_cpp->closure(*coll); + delete_vec(coll); gap_list_t gens = ElmPRec(so, RNam_GeneratorsOfMagma); - for (size_t i = 0; i < semi_cpp->nrgens(); i++) { - AssPlist(gens, i + 1, converter->unconvert(semi_cpp->gens(i))); + for (size_t i = 0; i < semi_cpp->nr_generators(); i++) { + AssPlist(gens, i + 1, converter->unconvert(semi_cpp->generator(i))); } // Reset the fropin data since none of it is valid any longer @@ -752,7 +756,7 @@ gap_int_t EN_SEMI_CURRENT_NR_RULES(Obj self, gap_semigroup_t so) { if (es == 0L) { return INTOBJ_INT(0); } else if (en_semi_get_type(es) != UNKNOWN) { - return INTOBJ_INT(en_semi_get_semi_cpp(es)->current_nrrules()); + return INTOBJ_INT(en_semi_get_semi_cpp(es)->current_nr_rules()); } else { gap_rec_t fp = semi_obj_get_fropin(so); // TODO(JDM) could write a function return_if_not_bound_prec(prec, rnam, @@ -785,9 +789,8 @@ gap_int_t EN_SEMI_CURRENT_SIZE(Obj self, gap_semigroup_t so) { // Get the element of this is not cached anywhere for cpp semigroups -gap_element_t EN_SEMI_ELEMENT_NUMBER(Obj self, - gap_semigroup_t so, - gap_int_t pos) { +gap_element_t +EN_SEMI_ELEMENT_NUMBER(Obj self, gap_semigroup_t so, gap_int_t pos) { CHECK_SEMI_OBJ(so); CHECK_POS_INTOBJ(pos); @@ -796,10 +799,18 @@ gap_element_t EN_SEMI_ELEMENT_NUMBER(Obj self, if (en_semi_get_type(es) != UNKNOWN) { nr--; - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); - Element const* x = semi_cpp->at(nr); - return (x == nullptr ? Fail : en_semi_get_converter(es)->unconvert(x)); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); + try { + return en_semi_get_converter(es)->unconvert(semi_cpp->at(nr)); + } catch (std::out_of_range& e) { +#ifdef SEMIGROUPS_KERNEL_DEBUG + std::cerr << "exception std::out_of_range thrown " + "by libsemigroups::FroidurePin::at(" + << nr << "): " << e.what() << std::endl; +#endif + return Fail; + } } else { gap_rec_t fp = semi_obj_get_fropin(so); if (IsbPRec(fp, RNam_elts)) { @@ -819,21 +830,27 @@ gap_element_t EN_SEMI_ELEMENT_NUMBER(Obj self, } } -gap_element_t EN_SEMI_ELEMENT_NUMBER_SORTED(Obj self, - gap_semigroup_t so, - gap_int_t pos) { +gap_element_t +EN_SEMI_ELEMENT_NUMBER_SORTED(Obj self, gap_semigroup_t so, gap_int_t pos) { CHECK_SEMI_OBJ(so); CHECK_POS_INTOBJ(pos); en_semi_obj_t es = semi_obj_get_en_semi(so); if (en_semi_get_type(es) != UNKNOWN) { - size_t nr = INT_INTOBJ(pos) - 1; - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); - Element const* x = semi_cpp->sorted_at(nr); - - return (x == nullptr ? Fail : en_semi_get_converter(es)->unconvert(x)); + size_t nr = INT_INTOBJ(pos) - 1; + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); + try { + return en_semi_get_converter(es)->unconvert(semi_cpp->sorted_at(nr)); + } catch (std::out_of_range& e) { +#ifdef SEMIGROUPS_KERNEL_DEBUG + std::cerr << "exception std::out_of_range thrown " + "by libsemigroups::FroidurePin::sorted_at(" + << nr << "): " << e.what() << std::endl; +#endif + return Fail; + } } else { ErrorQuit("EN_SEMI_ELEMENT_NUMBER_SORTED: this shouldn't happen!", 0L, 0L); return 0L; @@ -853,7 +870,7 @@ gap_list_t EN_SEMI_ELMS_LIST(Obj self, gap_semigroup_t so, gap_list_t poslist) { SET_LEN_PLIST(out, len); if (en_semi_get_type(es) != UNKNOWN) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); for (size_t i = 1; i <= len; i++) { gap_int_t pos = ELM_LIST(poslist, i); if (pos == 0 || !IS_INTOBJ(pos) || INT_INTOBJ(pos) <= 0) { @@ -862,16 +879,24 @@ gap_list_t EN_SEMI_ELMS_LIST(Obj self, gap_semigroup_t so, gap_list_t poslist) { (Int) i, 0L); } - semi_cpp->set_report(semi_obj_get_report(so)); - Element const* x = semi_cpp->at(INT_INTOBJ(pos) - 1); - if (x == nullptr) { + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); + try { + SET_ELM_PLIST(out, + i, + en_semi_get_converter(es)->unconvert( + semi_cpp->at(INT_INTOBJ(pos) - 1))); + CHANGED_BAG(out); + } catch (std::out_of_range& e) { +#ifdef SEMIGROUPS_KERNEL_DEBUG + std::cerr << "exception std::out_of_range thrown " + "by libsemigroups::FroidurePin::at(" + << (INT_INTOBJ(pos) - 1) << "): " << e.what() << std::endl; +#endif ErrorQuit("Semigroups: ELMS_LIST: List Elements, [%d] " "must be at most %d,", (Int) i, (Int) semi_cpp->size()); } - SET_ELM_PLIST(out, i, en_semi_get_converter(es)->unconvert(x)); - CHANGED_BAG(out); } } else { for (size_t i = 1; i <= len; i++) { @@ -896,17 +921,15 @@ gap_list_t EN_SEMI_ELMS_LIST(Obj self, gap_semigroup_t so, gap_list_t poslist) { return out; } -gap_semigroup_t EN_SEMI_ENUMERATE(Obj self, - gap_semigroup_t so, - gap_int_t limit) { +gap_semigroup_t +EN_SEMI_ENUMERATE(Obj self, gap_semigroup_t so, gap_int_t limit) { CHECK_SEMI_OBJ(so); CHECK_INTOBJ(limit); - size_t c_limit - = (INT_INTOBJ(limit) < 0 ? Semigroup::LIMIT_MAX : INT_INTOBJ(limit)); + size_t c_limit = (INT_INTOBJ(limit) < 0 ? LIMIT_MAX : INT_INTOBJ(limit)); en_semi_obj_t es = semi_obj_get_en_semi(so); if (en_semi_get_type(es) != UNKNOWN) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); semi_cpp->enumerate(c_limit); } else { fropin(so, limit, 0, False); @@ -927,8 +950,8 @@ gap_list_t EN_SEMI_FACTORIZATION(Obj self, gap_semigroup_t so, gap_int_t pos) { 0L); return 0L; // keep compiler happy } else if (en_semi_get_type(es) != UNKNOWN) { - gap_list_t words; - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); + gap_list_t words; + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); if (pos_c > semi_cpp->current_size()) { ErrorQuit("the 2nd argument must be at most %d not %d", @@ -939,13 +962,13 @@ gap_list_t EN_SEMI_FACTORIZATION(Obj self, gap_semigroup_t so, gap_int_t pos) { gap_rec_t fp = semi_obj_get_fropin(so); if (!IsbPRec(fp, RNam_words)) { // TODO(JDM) Use FindPRec instead - word_t w; // changed in place by the next line - semi_cpp->set_report(semi_obj_get_report(so)); + word_type w; // changed in place by the next line + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); semi_cpp->factorisation(w, pos_c - 1); words = NEW_PLIST_IMM(T_PLIST, pos_c); // IMMUTABLE since it should not be altered on the GAP level SET_LEN_PLIST(words, pos_c); - SET_ELM_PLIST(words, pos_c, word_t_to_plist(w)); + SET_ELM_PLIST(words, pos_c, word_type_to_plist(w)); CHANGED_BAG(words); AssPRec(fp, RNam_words, words); CHANGED_BAG(so); @@ -961,7 +984,8 @@ gap_list_t EN_SEMI_FACTORIZATION(Obj self, gap_semigroup_t so, gap_int_t pos) { gap_list_t new_word = NEW_PLIST_IMM(T_PLIST_CYC, LEN_PLIST(old_word) + 1); // IMMUTABLE since it should not be altered on the GAP level - memcpy(ADDR_OBJ(new_word) + 1, CONST_ADDR_OBJ(old_word) + 1, + memcpy(ADDR_OBJ(new_word) + 1, + CONST_ADDR_OBJ(old_word) + 1, (size_t)(LEN_PLIST(old_word) * sizeof(Obj))); SET_ELM_PLIST(new_word, LEN_PLIST(old_word) + 1, @@ -976,7 +1000,8 @@ gap_list_t EN_SEMI_FACTORIZATION(Obj self, gap_semigroup_t so, gap_int_t pos) { gap_list_t new_word = NEW_PLIST_IMM(T_PLIST_CYC, LEN_PLIST(old_word) + 1); // IMMUTABLE since it should not be altered on the GAP level - memcpy(ADDR_OBJ(new_word) + 2, CONST_ADDR_OBJ(old_word) + 1, + memcpy(ADDR_OBJ(new_word) + 2, + CONST_ADDR_OBJ(old_word) + 1, (size_t)(LEN_PLIST(old_word) * sizeof(Obj))); SET_ELM_PLIST( new_word, 1, INTOBJ_INT(semi_cpp->first_letter(pos_c - 1) + 1)); @@ -985,10 +1010,10 @@ gap_list_t EN_SEMI_FACTORIZATION(Obj self, gap_semigroup_t so, gap_int_t pos) { CHANGED_BAG(fp); CHANGED_BAG(so); } else { - word_t w; // changed in place by the next line - semi_cpp->set_report(semi_obj_get_report(so)); + word_type w; // changed in place by the next line + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); semi_cpp->factorisation(w, pos_c - 1); - AssPlist(words, pos_c, word_t_to_plist(w)); + AssPlist(words, pos_c, word_type_to_plist(w)); CHANGED_BAG(fp); CHANGED_BAG(so); } @@ -1010,17 +1035,17 @@ gap_list_t EN_SEMI_LEFT_CAYLEY_GRAPH(Obj self, gap_semigroup_t so) { CHECK_SEMI_OBJ(so); en_semi_obj_t es = semi_obj_get_en_semi(so); if (en_semi_get_type(es) != UNKNOWN) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); gap_list_t out = NEW_PLIST(T_PLIST_TAB_RECT, semi_cpp->size()); // this is intentionally not IMMUTABLE SET_LEN_PLIST(out, semi_cpp->size()); for (size_t i = 0; i < semi_cpp->size(); ++i) { - gap_list_t next = NEW_PLIST(T_PLIST_CYC, semi_cpp->nrgens()); + gap_list_t next = NEW_PLIST(T_PLIST_CYC, semi_cpp->nr_generators()); // this is intentionally not IMMUTABLE - SET_LEN_PLIST(next, semi_cpp->nrgens()); - for (size_t j = 0; j < semi_cpp->nrgens(); ++j) { + SET_LEN_PLIST(next, semi_cpp->nr_generators()); + for (size_t j = 0; j < semi_cpp->nr_generators(); ++j) { SET_ELM_PLIST(next, j + 1, INTOBJ_INT(semi_cpp->left(i, j) + 1)); } SET_ELM_PLIST(out, i + 1, next); @@ -1037,8 +1062,8 @@ gap_int_t EN_SEMI_LENGTH_ELEMENT(Obj self, gap_semigroup_t so, gap_int_t pos) { CHECK_POS_INTOBJ(pos); en_semi_obj_t es = semi_obj_get_en_semi(so); if (en_semi_get_type(es) != UNKNOWN) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); return INTOBJ_INT(semi_cpp->length_non_const(INT_INTOBJ(pos) - 1)); } else { return INTOBJ_INT(LEN_PLIST(EN_SEMI_FACTORIZATION(self, so, pos))); @@ -1049,11 +1074,11 @@ gap_list_t EN_SEMI_IDEMPOTENTS(Obj self, gap_semigroup_t so) { CHECK_SEMI_OBJ(so); en_semi_obj_t es = semi_obj_get_en_semi(so); if (en_semi_get_type(es) != UNKNOWN) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - Converter* converter = en_semi_get_converter(es); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + Converter* converter = en_semi_get_converter(es); - semi_cpp->set_report(semi_obj_get_report(so)); - semi_cpp->set_max_threads(semi_obj_get_nr_threads(so)); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); + semi_cpp->max_threads(semi_obj_get_nr_threads(so)); return iterator_to_plist(converter, semi_cpp->cbegin_idempotents(), semi_cpp->cend_idempotents()); @@ -1097,9 +1122,9 @@ gap_int_t EN_SEMI_IDEMS_SUBSET(Obj self, gap_semigroup_t so, gap_list_t list) { size_t len = 0; if (en_semi_get_type(es) != UNKNOWN) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); - semi_cpp->set_max_threads(semi_obj_get_nr_threads(so)); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); + semi_cpp->max_threads(semi_obj_get_nr_threads(so)); for (size_t pos = 1; pos <= (size_t) LEN_LIST(list); pos++) { gap_int_t ent = ELM_LIST(list, pos); @@ -1143,7 +1168,7 @@ gap_bool_t EN_SEMI_IS_DONE(Obj self, gap_semigroup_t so) { if (es == 0L) { return False; } else if (en_semi_get_type(es) != UNKNOWN) { - return (en_semi_get_semi_cpp(es)->is_done() ? True : False); + return (en_semi_get_semi_cpp(es)->finished() ? True : False); } gap_rec_t fp = semi_obj_get_fropin(so); @@ -1157,11 +1182,11 @@ gap_int_t EN_SEMI_NR_IDEMPOTENTS(Obj self, gap_semigroup_t so) { CHECK_SEMI_OBJ(so); en_semi_obj_t es = semi_obj_get_en_semi(so); if (en_semi_get_type(es) != UNKNOWN) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); - semi_cpp->set_max_threads(semi_obj_get_nr_threads(so)); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); + semi_cpp->max_threads(semi_obj_get_nr_threads(so)); - return INTOBJ_INT(semi_cpp->nridempotents()); + return INTOBJ_INT(semi_cpp->nr_idempotents()); } else { // This could probably be better but is also probably not worth the effort // of improving @@ -1191,14 +1216,13 @@ Obj EN_SEMI_POSITION(Obj self, gap_semigroup_t so, gap_element_t x) { en_semi_obj_t es = semi_obj_get_en_semi(so); if (en_semi_get_type(es) != UNKNOWN) { - size_t deg = en_semi_get_degree(es); - Element* xx = en_semi_get_converter(es)->convert(x, deg); - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); + size_t deg = en_semi_get_degree(es); + Element* xx = en_semi_get_converter(es)->convert(x, deg); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); size_t pos = semi_cpp->position(xx); - xx->really_delete(); delete xx; - return (pos == Semigroup::UNDEFINED ? Fail : INTOBJ_INT(pos + 1)); + return (pos == UNDEFINED ? Fail : INTOBJ_INT(pos + 1)); } else { gap_rec_t data = semi_obj_get_fropin(so); Obj ht = ElmPRec(data, RNam_ht); @@ -1220,9 +1244,8 @@ Obj EN_SEMI_POSITION(Obj self, gap_semigroup_t so, gap_element_t x) { // Get the position of with out any further enumeration -gap_int_t EN_SEMI_CURRENT_POSITION(Obj self, - gap_semigroup_t so, - gap_element_t x) { +gap_int_t +EN_SEMI_CURRENT_POSITION(Obj self, gap_semigroup_t so, gap_element_t x) { CHECK_SEMI_OBJ(so); en_semi_obj_t es = semi_obj_get_en_semi_no_init(so); @@ -1232,17 +1255,15 @@ gap_int_t EN_SEMI_CURRENT_POSITION(Obj self, size_t deg = en_semi_get_degree(es); Element* xx = en_semi_get_converter(es)->convert(x, deg); size_t pos = en_semi_get_semi_cpp(es)->current_position(xx); - xx->really_delete(); delete xx; - return (pos == Semigroup::UNDEFINED ? Fail : INTOBJ_INT(pos + 1)); + return (pos == UNDEFINED ? Fail : INTOBJ_INT(pos + 1)); } else { return CALL_2ARGS(HTValue, ElmPRec(semi_obj_get_fropin(so), RNam_ht), x); } } -gap_int_t EN_SEMI_POSITION_SORTED(Obj self, - gap_semigroup_t so, - gap_element_t x) { +gap_int_t +EN_SEMI_POSITION_SORTED(Obj self, gap_semigroup_t so, gap_element_t x) { CHECK_SEMI_OBJ(so); en_semi_obj_t es = semi_obj_get_en_semi(so); @@ -1251,14 +1272,13 @@ gap_int_t EN_SEMI_POSITION_SORTED(Obj self, ErrorQuit("EN_SEMI_POSITION_SORTED: this shouldn't happen!", 0L, 0L); return 0L; } else { - size_t deg = en_semi_get_degree(es); - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); + size_t deg = en_semi_get_degree(es); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); Element* xx = en_semi_get_converter(es)->convert(x, deg); size_t pos = semi_cpp->sorted_position(xx); - xx->really_delete(); delete xx; - return (pos == Semigroup::UNDEFINED ? Fail : INTOBJ_INT(pos + 1)); + return (pos == UNDEFINED ? Fail : INTOBJ_INT(pos + 1)); } } @@ -1270,12 +1290,11 @@ gap_list_t EN_SEMI_RELATIONS(Obj self, gap_semigroup_t so) { if (en_semi_get_type(es) != UNKNOWN) { if (!IsbPRec(fp, RNam_rules) || LEN_PLIST(ElmPRec(fp, RNam_rules)) == 0) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); - gap_list_t rules - = NEW_PLIST_IMM(T_PLIST_TAB_RECT, semi_cpp->nrrules()); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); + gap_list_t rules = NEW_PLIST_IMM(T_PLIST_TAB_RECT, semi_cpp->nr_rules()); // IMMUTABLE since it should not be altered on the GAP level - SET_LEN_PLIST(rules, semi_cpp->nrrules()); + SET_LEN_PLIST(rules, semi_cpp->nr_rules()); size_t nr = 0; semi_cpp->reset_next_relation(); @@ -1306,7 +1325,8 @@ gap_list_t EN_SEMI_RELATIONS(Obj self, gap_semigroup_t so) { gap_list_t new_word = NEW_PLIST_IMM(T_PLIST_CYC, LEN_PLIST(old_word) + 1); // IMMUTABLE since it should not be altered on the GAP level - memcpy(ADDR_OBJ(new_word) + 1, CONST_ADDR_OBJ(old_word) + 1, + memcpy(ADDR_OBJ(new_word) + 1, + CONST_ADDR_OBJ(old_word) + 1, (size_t)(LEN_PLIST(old_word) * sizeof(Obj))); SET_ELM_PLIST( new_word, LEN_PLIST(old_word) + 1, INTOBJ_INT(relation[1] + 1)); @@ -1341,18 +1361,18 @@ gap_list_t EN_SEMI_RIGHT_CAYLEY_GRAPH(Obj self, gap_semigroup_t so) { en_semi_obj_t es = semi_obj_get_en_semi(so); if (en_semi_get_type(es) != UNKNOWN) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); gap_list_t out = NEW_PLIST(T_PLIST_TAB_RECT, semi_cpp->size()); // this is intentionally not IMMUTABLE SET_LEN_PLIST(out, semi_cpp->size()); for (size_t i = 0; i < semi_cpp->size(); ++i) { - gap_list_t next = NEW_PLIST(T_PLIST_CYC, semi_cpp->nrgens()); + gap_list_t next = NEW_PLIST(T_PLIST_CYC, semi_cpp->nr_generators()); // this is intentionally not IMMUTABLE - SET_LEN_PLIST(next, semi_cpp->nrgens()); - for (size_t j = 0; j < semi_cpp->nrgens(); ++j) { + SET_LEN_PLIST(next, semi_cpp->nr_generators()); + for (size_t j = 0; j < semi_cpp->nr_generators(); ++j) { SET_ELM_PLIST(next, j + 1, INTOBJ_INT(semi_cpp->right(i, j) + 1)); } SET_ELM_PLIST(out, i + 1, next); @@ -1370,8 +1390,8 @@ gap_int_t EN_SEMI_SIZE(Obj self, gap_semigroup_t so) { en_semi_obj_t es = semi_obj_get_en_semi(so); if (en_semi_get_type(es) != UNKNOWN) { - Semigroup* semi_cpp = en_semi_get_semi_cpp(es); - semi_cpp->set_report(semi_obj_get_report(so)); + FroidurePin* semi_cpp = en_semi_get_semi_cpp(es); + auto rg = libsemigroups::ReportGuard(semi_obj_get_report(so)); return INTOBJ_INT(semi_cpp->size()); } else { gap_rec_t fp = fropin(so, INTOBJ_INT(-1), 0, False); diff --git a/src/semigrp.h b/src/semigrp.h index 1b99accf9..e5427e138 100644 --- a/src/semigrp.h +++ b/src/semigrp.h @@ -21,13 +21,16 @@ #ifndef SEMIGROUPS_SRC_SEMIGRP_H_ #define SEMIGROUPS_SRC_SEMIGRP_H_ +#include "libsemigroups/froidure-pin.hpp" + +#include "src/compiled.h" // GAP headers + #include "converter.h" -#include "libsemigroups/semigroups.h" #include "pkg.h" + #include "rnams.h" -#include "src/compiled.h" // GAP headers -using libsemigroups::Semigroup; +using libsemigroups::FroidurePin; // Typedef for readability, an en_semi_obj_t should be an Obj of TNUM_OBJ = // T_SEMI and SUBTYPE_OF_T_SEMI = T_SEMI_SUBTYPE_ENSEMI @@ -57,12 +60,12 @@ enum en_semi_t { // C++ functions -size_t semi_obj_get_batch_size(gap_semigroup_t so); -bool semi_obj_get_report(gap_semigroup_t so); -gap_list_t semi_obj_get_gens(gap_semigroup_t so); -gap_rec_t semi_obj_get_fropin(gap_semigroup_t so); -en_semi_t semi_obj_get_type(gap_semigroup_t so); -Semigroup* semi_obj_get_semi_cpp(gap_semigroup_t so); +size_t semi_obj_get_batch_size(gap_semigroup_t so); +bool semi_obj_get_report(gap_semigroup_t so); +gap_list_t semi_obj_get_gens(gap_semigroup_t so); +gap_rec_t semi_obj_get_fropin(gap_semigroup_t so); +en_semi_t semi_obj_get_type(gap_semigroup_t so); +FroidurePin* semi_obj_get_semi_cpp(gap_semigroup_t so); static inline en_semi_t en_semi_get_type(en_semi_obj_t es) { SEMIGROUPS_ASSERT(TNUM_OBJ(es) == T_SEMI @@ -84,37 +87,32 @@ static inline size_t en_semi_get_degree(en_semi_obj_t es) { return CLASS_OBJ(es, 3); } -Converter* en_semi_get_converter(en_semi_obj_t es); -Semigroup* en_semi_get_semi_cpp(en_semi_obj_t es); +Converter* en_semi_get_converter(en_semi_obj_t es); +FroidurePin* en_semi_get_semi_cpp(en_semi_obj_t es); // GAP level functions for IsEnumerableSemigroupRep -gap_list_t EN_SEMI_AS_LIST(Obj self, gap_semigroup_t so); -gap_list_t EN_SEMI_AS_SET(Obj self, gap_semigroup_t so); -gap_int_t EN_SEMI_CURRENT_MAX_WORD_LENGTH(Obj self, gap_semigroup_t so); -gap_int_t EN_SEMI_CURRENT_NR_RULES(Obj self, gap_semigroup_t so); -gap_int_t EN_SEMI_CURRENT_POSITION(Obj self, - gap_semigroup_t so, - gap_element_t x); +gap_list_t EN_SEMI_AS_LIST(Obj self, gap_semigroup_t so); +gap_list_t EN_SEMI_AS_SET(Obj self, gap_semigroup_t so); +gap_int_t EN_SEMI_CURRENT_MAX_WORD_LENGTH(Obj self, gap_semigroup_t so); +gap_int_t EN_SEMI_CURRENT_NR_RULES(Obj self, gap_semigroup_t so); +gap_int_t + EN_SEMI_CURRENT_POSITION(Obj self, gap_semigroup_t so, gap_element_t x); gap_int_t EN_SEMI_CURRENT_SIZE(Obj self, gap_semigroup_t so); gap_list_t EN_SEMI_CAYLEY_TABLE(Obj self, gap_semigroup_t so); gap_semigroup_t EN_SEMI_CLOSURE(Obj self, gap_semigroup_t new_so, gap_semigroup_t old_so, gap_list_t plist); -gap_semigroup_t EN_SEMI_CLOSURE_DEST(Obj self, - gap_semigroup_t so, - gap_list_t coll); -gap_element_t EN_SEMI_ELEMENT_NUMBER(Obj self, - gap_semigroup_t so, - gap_int_t pos); -gap_element_t EN_SEMI_ELEMENT_NUMBER_SORTED(Obj self, - gap_semigroup_t so, - gap_int_t pos); +gap_semigroup_t +EN_SEMI_CLOSURE_DEST(Obj self, gap_semigroup_t so, gap_list_t coll); +gap_element_t +EN_SEMI_ELEMENT_NUMBER(Obj self, gap_semigroup_t so, gap_int_t pos); +gap_element_t + EN_SEMI_ELEMENT_NUMBER_SORTED(Obj self, gap_semigroup_t so, gap_int_t pos); gap_list_t EN_SEMI_ELMS_LIST(Obj self, gap_semigroup_t so, gap_list_t poslist); -gap_semigroup_t EN_SEMI_ENUMERATE(Obj self, - gap_semigroup_t so, - gap_int_t limit); +gap_semigroup_t + EN_SEMI_ENUMERATE(Obj self, gap_semigroup_t so, gap_int_t limit); gap_list_t EN_SEMI_FACTORIZATION(Obj self, gap_semigroup_t so, gap_int_t pos); gap_list_t EN_SEMI_LEFT_CAYLEY_GRAPH(Obj self, gap_semigroup_t so); gap_int_t EN_SEMI_LENGTH_ELEMENT(Obj self, gap_semigroup_t so, gap_int_t pos); @@ -123,9 +121,8 @@ gap_list_t EN_SEMI_IDEMS_SUBSET(Obj self, gap_semigroup_t so, gap_list_t list); gap_bool_t EN_SEMI_IS_DONE(Obj self, gap_semigroup_t so); gap_int_t EN_SEMI_NR_IDEMPOTENTS(Obj self, gap_semigroup_t so); gap_int_t EN_SEMI_POSITION(Obj self, gap_semigroup_t so, gap_element_t x); -gap_int_t EN_SEMI_POSITION_SORTED(Obj self, - gap_semigroup_t so, - gap_element_t x); +gap_int_t + EN_SEMI_POSITION_SORTED(Obj self, gap_semigroup_t so, gap_element_t x); gap_list_t EN_SEMI_RELATIONS(Obj self, gap_semigroup_t so); gap_list_t EN_SEMI_RIGHT_CAYLEY_GRAPH(Obj self, gap_semigroup_t so); gap_int_t EN_SEMI_SIZE(Obj self, gap_semigroup_t so); diff --git a/src/uf.cc b/src/uf.cc index ae663c7a8..63643dd4d 100644 --- a/src/uf.cc +++ b/src/uf.cc @@ -26,9 +26,9 @@ #include "semigroups-debug.h" #include "src/compiled.h" -#include "libsemigroups/uf.h" +#include "libsemigroups/uf.hpp" -using libsemigroups::UF; +using libsemigroups::detail::UF; // GAP level functions @@ -67,7 +67,7 @@ Obj UF_FLATTEN(Obj self, Obj uf) { } Obj UF_TABLE(Obj self, Obj uf) { - UF::table_t* table = CLASS_OBJ(uf)->get_table(); + UF::table_type* table = CLASS_OBJ(uf)->get_table(); size_t size = table->size(); Obj gap_table = NEW_PLIST_IMM(T_PLIST_CYC, size); // IMMUTABLE since it should not be altered on the GAP level @@ -79,7 +79,7 @@ Obj UF_TABLE(Obj self, Obj uf) { } Obj UF_BLOCKS(Obj self, Obj uf) { - UF::blocks_t const* blocks = CLASS_OBJ(uf)->get_blocks(); + UF::blocks_type const* blocks = CLASS_OBJ(uf)->get_blocks(); size_t size = blocks->size(); size_t i, j; diff --git a/tst/standard/congfpmon.tst b/tst/standard/congfpmon.tst index c69ad7356..33b51b1d1 100644 --- a/tst/standard/congfpmon.tst +++ b/tst/standard/congfpmon.tst @@ -96,12 +96,9 @@ false gap> class1 = class2; false gap> enum := Enumerator(class1);; -gap> enum[3]; -(m2*m1)^2 -gap> enum[11]; -m2*m1*m2 -gap> Position(enum, M.2 * M.1 * M.2 * M.1); -3 +gap> AsSSortedList(enum); +[ m2, m1^2, m1*m2, m2*m1, m1^2*m2, m1*m2*m1, m2*m1*m2, m1^2*m2*m1, (m1*m2)^2, + (m2*m1)^2, (m1*m2)^2*m1 ] gap> Size(enum); 11 gap> class1 * class2 = EquivalenceClassOfElement(cong, M.2 ^ 20 * M.1 ^ 42); @@ -164,11 +161,11 @@ gap> class1 = class2; false gap> enum := Enumerator(class1);; gap> enum[3]; -m1^2 +m2*m1 gap> enum[11]; -m2^2*m1^2 +m2*m1^3 gap> Position(enum, M.2 * M.1 * M.2 * M.1); -13 +12 gap> Size(enum); 30 @@ -232,7 +229,7 @@ gap> class1 = class2; false gap> enum := Enumerator(class1);; gap> enum[3]; -m1*m2 +m2^2 gap> enum[11]; m1*(m1*m2)^2*m1^3 gap> Position(enum, M.1 * (M.1 * M.2) ^ 2 * M.1 ^ 3);