// // Semigroups package for GAP // Copyright (C) 2020-2022 James D. Mitchell // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see <https://www.gnu.org/licenses/>. //
// This file contains specialisations of gapbind14::to_cpp for various types // defined in the GAP package Semigroups and the corresponding types in // libsemigroups.
// Standard library #include <algorithm> // for max, min, sort #include <cstddef> // for size_t #include <cstdint> // for uint32_t #include <memory> // for make_unique, unique_ptr #include <string> // for string #include <type_traits> // for decay_t, is_same, conditional_t #include <unordered_map> // for operator==, unordered_map #include <utility> // for forward #include <vector> // for vector
// GAP headers #include"gap_all.h"
// Semigroups package headers #include"bipart.hpp"// for bipart_get_cpp #include"froidure-pin.hpp"// for WBMat8 #include"pkg.hpp"// for IsInfinity etc #include"semigroups-debug.hpp"// for SEMIGROUPS_ASSERT
// gapbind14 headers #include"gapbind14/cpp_fn.hpp"// for GAPBIND14_TRY #include"gapbind14/to_cpp.hpp"// for to_cpp #include"gapbind14/to_gap.hpp"// for gap_tnum_type
// libsemigroups headers #include"libsemigroups/adapters.hpp"// for Degree #include"libsemigroups/bmat8.hpp"// for BMat8 #include"libsemigroups/cong.hpp"// for Congruence #include"libsemigroups/constants.hpp"// for NegativeInfinity, PositiveIn... #include"libsemigroups/containers.hpp"// for DynamicArray2 #include"libsemigroups/matrix.hpp"// for NTPMat, MaxPlusTruncMat, Min... #include"libsemigroups/pbr.hpp"// for PBR #include"libsemigroups/transf.hpp"// for PPerm, Transf, IsPPerm #include"libsemigroups/types.hpp"// for congruence_kind, congruence_...
namespace libsemigroups { class Bipartition;
}
using libsemigroups::BMat; using libsemigroups::BMat8; using libsemigroups::IntMat; using semigroups::WBMat8;
using libsemigroups::IntMat; using libsemigroups::MaxPlusMat; using libsemigroups::MaxPlusTruncMat; using libsemigroups::MinPlusMat; using libsemigroups::MinPlusTruncMat; using libsemigroups::NTPMat; using libsemigroups::ProjMaxPlusMat;
using libsemigroups::NTPSemiring;
using libsemigroups::Bipartition; using libsemigroups::PBR;
using libsemigroups::IsPPerm; using libsemigroups::PPerm; using libsemigroups::Transf;
using libsemigroups::congruence_kind; using libsemigroups::NegativeInfinity; using libsemigroups::PositiveInfinity; using libsemigroups::UNDEFINED;
IntMat<> operator()(Obj o) { if (CALL_1ARGS(IsMatrixObj, o) != True) {
ErrorMayQuit("expected a matrix obj found %s!", (Int) TNAM_OBJ(o), 0L);
} elseif (!EQ(CALL_1ARGS(BaseDomain, o), Integers)) {
ErrorMayQuit( "expected a base domain of matrix to be the integers!", 0L, 0L);
}
size_t m = INT_INTOBJ(CALL_1ARGS(NrRows, o)); if (m == 0) {
ErrorQuit("expected matrix of non-zero dimension!", 0L, 0L);
}
IntMat<> x(m, m); using scalar_type = typename IntMat<>::scalar_type; for (size_t i = 0; i < m; i++) { for (size_t j = 0; j < m; j++) {
SEMIGROUPS_ASSERT(
IS_INTOBJ(ELM_MAT(o, INTOBJ_INT(i + 1), INTOBJ_INT(j + 1))));
x(i, j) = to_cpp<scalar_type>()(
ELM_MAT(o, INTOBJ_INT(i + 1), INTOBJ_INT(j + 1)));
}
}
GAPBIND14_TRY(libsemigroups::validate(x)); return x;
}
};
template <> struct to_cpp<MaxPlusMat<>> { using cpp_type = MaxPlusMat<>;
namespace detail { template <typename S, typename T> void to_cpp_transf(S& x, T* ptr, size_t const N) {
static_assert(
std::is_same<T, UInt2>::value || std::is_same<T, UInt4>::value, "the template parameter T must be the same as UInt2 or UInt4");
SEMIGROUPS_ASSERT(N <= libsemigroups::Degree<S>()(x));
T i; for (i = 0; i < N; ++i) {
x[i] = ptr[i];
} for (; i < libsemigroups::Degree<S>()(x); ++i) {
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 TransfType> struct ToTransf { using cpp_type = TransfType;
cpp_type operator()(Obj t) const { if (!IS_PLIST(t)) {
ErrorQuit("expected list, got %s", (Int) TNAM_OBJ(t), 0L);
} elseif (LEN_PLIST(t) != 2) {
ErrorQuit("expected list of length 2, but it has length %d",
(Int) LEN_PLIST(t),
0L);
} elseif (!IS_TRANS(ELM_PLIST(t, 1))) {
ErrorQuit("expected transforamtion in position 1, got %s",
(Int) TNAM_OBJ(t),
0L);
} elseif (!IS_INTOBJ(ELM_PLIST(t, 2))) {
ErrorQuit( "expected integer in position 2, got %s", (Int) TNAM_OBJ(t), 0L);
}
Obj x = ELM_PLIST(t, 1);
decltype(DEG_TRANS(x)) N = INT_INTOBJ(ELM_PLIST(t, 2));
if (INT_INTOBJ(CALL_1ARGS(LARGEST_MOVED_PT_TRANS, x)) > N) {
ErrorQuit("expected transformation with largest moved point not " "greater than %d, found %d",
(Int) N,
(Int) DEG_TRANS(x));
}
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));
} elseif (TNUM_OBJ(x) == T_TRANS4) {
detail::to_cpp_transf(
result, ADDR_TRANS4(x), std::min(DEG_TRANS(x), N));
} else { // in case of future changes to transf in GAP
ErrorQuit("transformation degree too high!", 0L, 0L);
} return result;
}
};
#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 PPermType> struct ToPPerm { using cpp_type = PPermType;
cpp_type operator()(Obj t) const { if (!IS_PLIST(t)) {
ErrorQuit("expected list, got %s", (Int) TNAM_OBJ(t), 0L);
} elseif (LEN_PLIST(t) != 2) {
ErrorQuit("expected list of length 2, but it has length %d",
(Int) LEN_PLIST(t),
0L);
} elseif (!IS_PPERM(ELM_PLIST(t, 1))) {
ErrorQuit("expected partial perm in position 1, got %s",
(Int) TNAM_OBJ(t),
0L);
} elseif (!IS_INTOBJ(ELM_PLIST(t, 2))) {
ErrorQuit( "expected integer in position 2, got %s", (Int) TNAM_OBJ(t), 0L);
}
Obj x = ELM_PLIST(t, 1);
UInt4 N = INT_INTOBJ(ELM_PLIST(t, 2));
UInt4 M = 0; if (TNUM_OBJ(x) == T_PPERM2) {
M = lmp<UInt2>(ADDR_PPERM2(x), DEG_PPERM2(x));
} elseif (TNUM_OBJ(x) == T_PPERM4) {
M = lmp<UInt4>(ADDR_PPERM4(x), DEG_PPERM4(x));
} else {
ErrorQuit("partial perm degree too high!", 0L, 0L);
}
if (M > N) {
ErrorQuit( "expected partial perm where the largest point in the domain and " "range is %d, found %d",
(Int) N,
(Int) M);
}
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));
} elseif (TNUM_OBJ(x) == T_PPERM4) {
detail::to_cpp_pperm(result, ADDR_PPERM4(x), DEG_PPERM4(x));
} else { // in case of future changes to partial perms in GAP
ErrorQuit("partial perm degree too high!", 0L, 0L);
} return result;
}
template <typename S> static S lmp(S* ptr, S deg) {
S result = 0; for (S i = 0; i < deg; i++) { if (ptr[i] != 0) {
result = std::max(result, i);
result = std::max(result, S(ptr[i] - 1));
}
} return result;
}
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.