diff --git a/community/gap/PKGBUILD b/community/gap/PKGBUILD index 972889671..274438e5a 100644 --- a/community/gap/PKGBUILD +++ b/community/gap/PKGBUILD @@ -7,20 +7,18 @@ pkgbase=gap pkgname=(gap gap-doc gap-packages) -pkgver=4.10.2 -pkgrel=11 +pkgver=4.11.0 +pkgrel=1 pkgdesc="Groups, Algorithms, Programming: a system for computational discrete algebra" arch=(x86_64) url="https://www.gap-system.org/" license=(GPL) source=("https://www.gap-system.org/pub/gap/gap-${pkgver%.*}/tar.gz/gap-$pkgver.tar.gz" gap.sh - libsemigroups-1.0.patch git+https://github.com/gap-packages/NormalizInterface#commit=cd69a42 normalizinterface-missing-include.patch gap-polymake-4.0.patch) -sha256sums=('11175bed0234101643d510d4ab94c44db30bd303bfe63d86b9b86ae67cff9e49' +sha256sums=('6fda7af23394708aeb3b4bca8885f5fdcb7c3ae4419639dfb2d9f67d3f590abb' '143fb8a79a52c007903cce13407850df309ef803a9b00398d05169355917de46' - 'ccd95de4f48d26b73d6df7c1847855f68ee70644d130d32f14213988c3e286e3' 'SKIP' '2410dfc69f1f4d2f320e91590d55e59c7b557637f9f60b9e609b318cfc21c181' 'e3f6d671c8df9acb6143a7c279391957967cd44f0a00b949323401d5b54ed685') @@ -40,13 +38,11 @@ prepare() { sed -e '/XGAP/d' -i pkg/cryst/PackageInfo.g # Update NormalizInterface to support recent normaliz - rm -r pkg/NormalizInterface-1.0.2 + rm -r pkg/NormalizInterface-1.1.0 cp -r ../NormalizInterface pkg cd pkg/NormalizInterface patch -p1 -i "$srcdir"/normalizinterface-missing-include.patch - cd ../semigroups-* - patch -p1 -i "$srcdir"/libsemigroups-1.0.patch # Fix build with libsemigroups 1.0 cd ../PolymakeInterface-* patch -p2 -i "$srcdir"/gap-polymake-4.0.patch # Fix build with polymake 4.0 } diff --git a/community/gap/libsemigroups-1.0.patch b/community/gap/libsemigroups-1.0.patch deleted file mode 100644 index e65e007b9..000000000 --- a/community/gap/libsemigroups-1.0.patch +++ /dev/null @@ -1,2244 +0,0 @@ -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);