diff --git a/gap/libsemigroups/froidure-pin.gi b/gap/libsemigroups/froidure-pin.gi index 163b78b2b..e4de024b0 100644 --- a/gap/libsemigroups/froidure-pin.gi +++ b/gap/libsemigroups/froidure-pin.gi @@ -48,16 +48,33 @@ Q -> CanUseLibsemigroupsCongruence(QuotientSemigroupCongruence(Q))); ########################################################################### DeclareOperation("FroidurePinMemFnRec", [IsSemigroup]); +DeclareOperation("FroidurePinMemFnRec", + [IsSemigroup, IsListOrCollection]); -InstallMethod(FroidurePinMemFnRec, "for a transformation semigroup", -[IsTransformationSemigroup], -function(S) - if DegreeOfTransformationSemigroup(S) <= 16 +InstallMethod(FroidurePinMemFnRec, "for a semigroup", +[IsSemigroup], S -> FroidurePinMemFnRec(S, [])); + +InstallMethod(FroidurePinMemFnRec, "for a semigroup", +[IsSemigroup, IsListOrCollection], {S, coll} -> FroidurePinMemFnRec(S)); + +InstallMethod(FroidurePinMemFnRec, +"for a transformation semigroup and list or coll.", +[IsTransformationSemigroup, IsListOrCollection], +function(S, coll) + local N; + N := DegreeOfTransformationSemigroup(S); + if IsTransformationCollection(coll) then + N := Maximum(N, DegreeOfTransformationCollection(coll)); + elif not IsEmpty(coll) then + Error("Expected a transf. coll. or empty list, found ", + TNAM_OBJ(coll)); + fi; + if N <= 16 and IsBound(LIBSEMIGROUPS_HPCOMBI_ENABLED) then return libsemigroups.FroidurePinTransf16; - elif DegreeOfTransformationSemigroup(S) <= 2 ^ 16 then + elif N <= 2 ^ 16 then return libsemigroups.FroidurePinTransfUInt2; - elif DegreeOfTransformationSemigroup(S) <= 2 ^ 32 then + elif N <= 2 ^ 32 then return libsemigroups.FroidurePinTransfUInt4; else # Cannot currently test the next line @@ -65,12 +82,21 @@ function(S) fi; end); -InstallMethod(FroidurePinMemFnRec, "for a partial perm semigroup", -[IsPartialPermSemigroup], -function(S) +InstallMethod(FroidurePinMemFnRec, +"for a partial perm. semigroup and list or coll.", +[IsPartialPermSemigroup, IsListOrCollection], +function(S, coll) local N; N := Maximum(DegreeOfPartialPermSemigroup(S), CodegreeOfPartialPermSemigroup(S)); + if IsPartialPermCollection(coll) then + N := Maximum(N, + DegreeOfPartialPermCollection(coll), + CodegreeOfPartialPermCollection(coll)); + elif not IsEmpty(coll) then + Error("Expected a partial perm. coll. or empty list, found ", + TNAM_OBJ(coll)); + fi; if N <= 16 and IsBound(LIBSEMIGROUPS_HPCOMBI_ENABLED) then return libsemigroups.FroidurePinPPerm16; elif N <= 2 ^ 16 then @@ -860,7 +886,7 @@ function(Constructor, S, coll, opts) Sort(coll, IsGreensDGreaterThanFunc(Semigroup(coll))); fi; - R := FroidurePinMemFnRec(S); + R := FroidurePinMemFnRec(S, coll); # Perform the closure if IsPartialPermSemigroup(S) or IsTransformationSemigroup(S) then @@ -875,8 +901,6 @@ function(Constructor, S, coll, opts) fi; if M > N then # Can't use closure, TODO(later) use copy_closure - # FIXME(later) if M goes larger than the type of R can support this will - # end badly CppT := R.make(); add_generator := R.add_generator; for x in GeneratorsOfSemigroup(S) do diff --git a/gapbind14/include/gapbind14/cpp_fn.hpp b/gapbind14/include/gapbind14/cpp_fn.hpp index 371106a94..af973883f 100644 --- a/gapbind14/include/gapbind14/cpp_fn.hpp +++ b/gapbind14/include/gapbind14/cpp_fn.hpp @@ -35,7 +35,7 @@ namespace gapbind14 { - constexpr size_t MAX_FUNCTIONS = 64; + constexpr size_t MAX_FUNCTIONS = 96; extern UInt T_GAPBIND14_OBJ; //////////////////////////////////////////////////////////////////////// diff --git a/src/to_cpp.hpp b/src/to_cpp.hpp index 0bc9461c9..0ca1d3e45 100644 --- a/src/to_cpp.hpp +++ b/src/to_cpp.hpp @@ -27,8 +27,6 @@ #include // for max, min, sort #include // for size_t #include // for uint32_t -#include // for exception -#include // for __unwrap_reference<>::type #include // for make_unique, unique_ptr #include // for string #include // for decay_t, is_same, conditional_t @@ -444,12 +442,26 @@ namespace gapbind14 { x[i] = i; } } + template + TransfType new_transf(size_t N) { + return TransfType(N); + } + + template <> + inline HPCombi::Transf16 new_transf(size_t N) { + if (N > 16) { + ErrorQuit("expected transformation of degree at most 16, found %d", + (Int) N, + 0L); + } + return HPCombi::Transf16(); + } } // namespace detail - template - struct to_cpp> { - using cpp_type = Transf<0, Scalar>; + template + struct ToTransf { + using cpp_type = TransfType; cpp_type operator()(Obj t) const { if (!IS_PLIST(t)) { @@ -477,7 +489,7 @@ namespace gapbind14 { (Int) DEG_TRANS(x)); } - cpp_type result(N); + cpp_type result = detail::new_transf(N); if (TNUM_OBJ(x) == T_TRANS2) { detail::to_cpp_transf( result, ADDR_TRANS2(x), std::min(DEG_TRANS(x), N)); @@ -492,6 +504,20 @@ namespace gapbind14 { } }; + template + struct to_cpp> : ToTransf> {}; + +#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED + template <> + struct to_cpp : public ToTransf {}; + + template <> + struct to_cpp : ToTransf {}; + + template <> + struct to_cpp : ToTransf {}; +#endif + //////////////////////////////////////////////////////////////////////// // Partial perms //////////////////////////////////////////////////////////////////////// @@ -532,11 +558,27 @@ namespace gapbind14 { x[i] = undef; } } + + template + PPermType new_pperm(size_t N) { + return PPermType(N); + } + + template <> + inline HPCombi::PPerm16 new_pperm(size_t N) { + if (N > 16) { + ErrorQuit("expected partial perm of degree at most 16, found %d", + (Int) N, + 0L); + } + return HPCombi::PPerm16(); + } + } // namespace detail - template - struct to_cpp> { - using cpp_type = PPerm<0, Scalar>; + template + struct ToPPerm { + using cpp_type = PPermType; cpp_type operator()(Obj t) const { if (!IS_PLIST(t)) { @@ -573,7 +615,8 @@ namespace gapbind14 { (Int) M); } - cpp_type result(N); + cpp_type result = detail::new_pperm(N); + if (TNUM_OBJ(x) == T_PPERM2) { detail::to_cpp_pperm(result, ADDR_PPERM2(x), DEG_PPERM2(x)); } else if (TNUM_OBJ(x) == T_PPERM4) { @@ -598,6 +641,20 @@ namespace gapbind14 { } }; + template + struct to_cpp> : ToPPerm> {}; + +#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED + template <> + struct to_cpp : ToPPerm {}; + + template <> + struct to_cpp : ToPPerm {}; + + template <> + struct to_cpp : ToPPerm {}; +#endif + //////////////////////////////////////////////////////////////////////// // Bipartition ////////////////////////////////////////////////////////////////////////