Skip to content

Commit

Permalink
kernel: fix for HPCombi
Browse files Browse the repository at this point in the history
There was some missing functionality that compiling with HPCombi enabled
required. This commit adds that functionality and fixes a FIXME that
actually comes up in semiquo.tst when compiling with HPCombi enabled.
  • Loading branch information
james-d-mitchell committed Jan 23, 2024
1 parent dfb1735 commit f7c49df
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 23 deletions.
48 changes: 36 additions & 12 deletions gap/libsemigroups/froidure-pin.gi
Original file line number Diff line number Diff line change
Expand Up @@ -48,29 +48,55 @@ 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
Error("transformation degree is too high!");
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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion gapbind14/include/gapbind14/cpp_fn.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@

namespace gapbind14 {

constexpr size_t MAX_FUNCTIONS = 64;
constexpr size_t MAX_FUNCTIONS = 96;
extern UInt T_GAPBIND14_OBJ;

////////////////////////////////////////////////////////////////////////
Expand Down
81 changes: 71 additions & 10 deletions src/to_cpp.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
#include <algorithm> // for max, min, sort
#include <cstddef> // for size_t
#include <cstdint> // for uint32_t
#include <exception> // for exception
#include <functional> // for __unwrap_reference<>::type
#include <memory> // for make_unique, unique_ptr
#include <string> // for string
#include <type_traits> // for decay_t, is_same, conditional_t
Expand Down Expand Up @@ -444,12 +442,28 @@ namespace gapbind14 {
x[i] = i;
}
}
template <typename TransfType>
TransfType new_transf(size_t N) {
return TransfType(N);
}

#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
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();
}
#endif

} // namespace detail

template <typename Scalar>
struct to_cpp<Transf<0, Scalar>> {
using cpp_type = Transf<0, Scalar>;
template <typename TransfType>
struct ToTransf {
using cpp_type = TransfType;

cpp_type operator()(Obj t) const {
if (!IS_PLIST(t)) {
Expand Down Expand Up @@ -477,7 +491,7 @@ namespace gapbind14 {
(Int) DEG_TRANS(x));
}

cpp_type result(N);
cpp_type result = detail::new_transf<cpp_type>(N);
if (TNUM_OBJ(x) == T_TRANS2) {
detail::to_cpp_transf(
result, ADDR_TRANS2(x), std::min(DEG_TRANS(x), N));
Expand All @@ -492,6 +506,20 @@ namespace gapbind14 {
}
};

template <typename Scalar>
struct to_cpp<Transf<0, Scalar>> : ToTransf<Transf<0, Scalar>> {};

#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
template <>
struct to_cpp<HPCombi::Transf16> : public ToTransf<HPCombi::Transf16> {};

template <>
struct to_cpp<HPCombi::Transf16&> : ToTransf<HPCombi::Transf16> {};

template <>
struct to_cpp<HPCombi::Transf16 const&> : ToTransf<HPCombi::Transf16> {};
#endif

////////////////////////////////////////////////////////////////////////
// Partial perms
////////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -532,11 +560,29 @@ namespace gapbind14 {
x[i] = undef;
}
}

template <typename PPermType>
PPermType new_pperm(size_t N) {
return PPermType(N);
}

#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
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();
}
#endif

} // namespace detail

template <typename Scalar>
struct to_cpp<PPerm<0, Scalar>> {
using cpp_type = PPerm<0, Scalar>;
template <typename PPermType>
struct ToPPerm {
using cpp_type = PPermType;

cpp_type operator()(Obj t) const {
if (!IS_PLIST(t)) {
Expand Down Expand Up @@ -573,7 +619,8 @@ namespace gapbind14 {
(Int) M);
}

cpp_type result(N);
cpp_type result = detail::new_pperm<cpp_type>(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) {
Expand All @@ -598,6 +645,20 @@ namespace gapbind14 {
}
};

template <typename Scalar>
struct to_cpp<PPerm<0, Scalar>> : ToPPerm<PPerm<0, Scalar>> {};

#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
template <>
struct to_cpp<HPCombi::PPerm16> : ToPPerm<HPCombi::PPerm16> {};

template <>
struct to_cpp<HPCombi::PPerm16&> : ToPPerm<HPCombi::PPerm16> {};

template <>
struct to_cpp<HPCombi::PPerm16 const&> : ToPPerm<HPCombi::PPerm16> {};
#endif

////////////////////////////////////////////////////////////////////////
// Bipartition
////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit f7c49df

Please sign in to comment.