Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/GAP/pkg/semigroups/src/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 29.7.2025 mit Größe 23 kB image not shown  

Quelle  to_cpp.hpp   Sprache: C

 
//
// 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.

#ifndef SEMIGROUPS_SRC_TO_CPP_HPP_
#define SEMIGROUPS_SRC_TO_CPP_HPP_

// 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;

using libsemigroups::detail::DynamicArray2;

namespace semigroups {
  NTPSemiring<> const* semiring(size_t threshold, size_t period);

  template <typename T>
  T const* semiring(size_t threshold) {
    static std::unordered_map<size_t, std::unique_ptr<T const>> cache;
    auto it = cache.find(threshold);
    if (it == cache.end()) {
      it = cache.emplace(threshold, std::make_unique<T const>(threshold)).first;
    }
    return it->second.get();
  }
}  // namespace semigroups

namespace gapbind14 {
  ////////////////////////////////////////////////////////////////////////
  // Constants
  ////////////////////////////////////////////////////////////////////////

  template <>
  struct to_cpp<PositiveInfinity> {
    using cpp_type                          = PositiveInfinity;
    static gap_tnum_type constexpr gap_type = T_POSOBJ;
    auto operator()(Obj x) const {
      if (CALL_1ARGS(IsInfinity, x) != True) {
        ErrorQuit("expected object satisfying IsInfinity, found %s",
                  (Int) TNAM_OBJ(x),
                  0L);
      }
      return libsemigroups::POSITIVE_INFINITY;
    }
  };

  template <>
  struct to_cpp<NegativeInfinity> {
    using cpp_type                          = NegativeInfinity;
    static gap_tnum_type constexpr gap_type = T_POSOBJ;
    auto operator()(Obj x) const {
      if (CALL_1ARGS(IsNegInfinity, x) != True) {
        ErrorQuit("expected object satisfying IsNegInfinity, found %s",
                  (Int) TNAM_OBJ(x),
                  0L);
      }
      return libsemigroups::NEGATIVE_INFINITY;
    }
  };

  ////////////////////////////////////////////////////////////////////////
  // BMat <-> IsBooleanMat
  ////////////////////////////////////////////////////////////////////////

  template <>
  struct to_cpp<BMat<>> {
    using cpp_type                          = BMat<>;
    static gap_tnum_type constexpr gap_type = T_POSOBJ;

    BMat<> operator()(Obj o) const {
      if (CALL_1ARGS(IsBooleanMat, o) != True) {
        ErrorQuit("expected boolean matrix but got %s!", (Int) TNAM_OBJ(o), 0L);
      }

      SEMIGROUPS_ASSERT(LEN_PLIST(o) > 0);

      Obj row = ELM_PLIST(o, 1);
      SEMIGROUPS_ASSERT(IS_PLIST(row) || IS_BLIST_REP(row));
      size_t m = (IS_BLIST_REP(row) ? LEN_BLIST(row) : LEN_PLIST(row));
      BMat<> x(m, m);

      for (size_t i = 0; i < m; i++) {
        row = ELM_PLIST(o, i + 1);
        if (!IS_BLIST_REP(row)) {
          ConvBlist(row);
        }
        for (size_t j = 0; j < m; j++) {
          if (ELM_BLIST(row, j + 1) == True) {
            x(i, j) = 1;
          }
        }
      }
      GAPBIND14_TRY(libsemigroups::validate(x));
      return x;
    }
  };

  template <>
  struct to_cpp<BMat<> const&> : to_cpp<BMat<>> {};

  template <>
  struct to_cpp<WBMat8> {
    WBMat8 operator()(Obj o) const {
      if (CALL_1ARGS(IsBooleanMat, o) != True) {
        ErrorQuit("expected boolean matrix but got %s!", (Int) TNAM_OBJ(o), 0L);
      }
      SEMIGROUPS_ASSERT(LEN_PLIST(o) > 0);

      Obj row = ELM_PLIST(o, 1);
      SEMIGROUPS_ASSERT(IS_PLIST(row) || IS_BLIST_REP(row));
      size_t m = (IS_BLIST_REP(row) ? LEN_BLIST(row) : LEN_PLIST(row));
      BMat8  x(0);

      for (size_t i = 0; i < m; i++) {
        row = ELM_PLIST(o, i + 1);
        if (!IS_BLIST_REP(row)) {
          ConvBlist(row);
        }
        for (size_t j = 0; j < m; j++) {
          if (ELM_BLIST(row, j + 1) == True) {
            x.set(i, j, 1);
          }
        }
      }
      return std::make_pair(x, m);
    }
  };

  template <>
  struct to_cpp<WBMat8&> : to_cpp<WBMat8> {};

  template <>
  struct to_cpp<WBMat8 const&> : to_cpp<WBMat8> {};

  ////////////////////////////////////////////////////////////////////////
  // MaxPlusMat + MinPlusMat
  ////////////////////////////////////////////////////////////////////////

  namespace detail {

    template <typename T, typename... TArgs>
    T make_matrix(size_t r, size_t c, TArgs&&... params) {
      return T(std::forward<TArgs>(params)..., r, c);
    }

    template <typename T, typename... TArgs>
    T init_cpp_matrix(Obj o, TArgs&&... params) {
      using scalar_type = typename T::scalar_type;
      if (LEN_PLIST(o) == 0) {
        ErrorQuit("expected matrix of non-zero dimension!", 0L, 0L);
      }

      size_t m = LEN_PLIST(ELM_PLIST(o, 1));
      T      x = make_matrix<T>(m, m, std::forward<TArgs>(params)...);
      for (size_t i = 0; i < m; i++) {
        Obj row = ELM_PLIST(o, i + 1);
        for (size_t j = 0; j < m; j++) {
          Obj         val = ELM_PLIST(row, j + 1);
          scalar_type itm;
          if (CALL_1ARGS(IsInfinity, val) != True
              && CALL_1ARGS(IsNegInfinity, val) != True) {
            itm = to_cpp<scalar_type>()(val);
          } else if (CALL_1ARGS(IsInfinity, val) == True) {
            itm = to_cpp<PositiveInfinity>()(val);
          } else if (CALL_1ARGS(IsNegInfinity, val) == True) {
            itm = to_cpp<std::conditional_t<std::is_signed<scalar_type>::value,
                                            NegativeInfinity,
                                            scalar_type>>()(val);
          }
          x(i, j) = itm;
        }
      }
      GAPBIND14_TRY(libsemigroups::validate(x));
      return x;
    }
  }  // namespace detail

  template <>
  struct to_cpp<IntMat<>> {
    static gap_tnum_type constexpr gap_type = T_POSOBJ;

    IntMat<> operator()(Obj o) {
      if (CALL_1ARGS(IsMatrixObj, o) != True) {
        ErrorMayQuit("expected a matrix obj found %s!", (Int) TNAM_OBJ(o), 0L);
      } else if (!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<>;

    MaxPlusMat<> operator()(Obj o) const {
      if (CALL_1ARGS(IsMaxPlusMatrix, o) != True) {
        ErrorQuit("expected max-plus matrix, found %s", (Int) TNAM_OBJ(o), 0L);
      }
      return detail::init_cpp_matrix<MaxPlusMat<>>(o);
    }
  };

  template <>
  struct to_cpp<MinPlusMat<>> {
    using cpp_type = MinPlusMat<>;

    MinPlusMat<> operator()(Obj o) const {
      if (CALL_1ARGS(IsMinPlusMatrix, o) != True) {
        ErrorQuit("expected min-plus matrix, found %s", (Int) TNAM_OBJ(o), 0L);
      }
      return detail::init_cpp_matrix<MinPlusMat<>>(o);
    }
  };

  template <>
  struct to_cpp<ProjMaxPlusMat<>> {
    using cpp_type = ProjMaxPlusMat<>;

    ProjMaxPlusMat<> operator()(Obj o) const {
      if (CALL_1ARGS(IsProjectiveMaxPlusMatrix, o) != True) {
        ErrorQuit("expected min-plus matrix, found %s", (Int) TNAM_OBJ(o), 0L);
      }
      return detail::init_cpp_matrix<ProjMaxPlusMat<>>(o);
    }
  };

  template <>
  struct to_cpp<MaxPlusTruncMat<>> {
    using cpp_type = MaxPlusTruncMat<>;

    cpp_type operator()(Obj o) const {
      if (CALL_1ARGS(IsTropicalMaxPlusMatrix, o) != True) {
        ErrorQuit("expected tropical max-plus matrix, found %s",
                  (Int) TNAM_OBJ(o),
                  0L);
      }

      size_t m            = LEN_PLIST(ELM_PLIST(o, 1));
      using semiring_type = typename MaxPlusTruncMat<>::semiring_type;
      auto const* sr      = semigroups::semiring<semiring_type>(
          static_cast<size_t>(INT_INTOBJ(ELM_PLIST(o, m + 1))));
      return detail::init_cpp_matrix<MaxPlusTruncMat<>>(o, sr);
    }
  };

  template <>
  struct to_cpp<MinPlusTruncMat<>> {
    using cpp_type = MinPlusTruncMat<>;

    cpp_type operator()(Obj o) const {
      if (CALL_1ARGS(IsTropicalMinPlusMatrix, o) != True) {
        ErrorQuit("expected tropical min-plus matrix, found %s",
                  (Int) TNAM_OBJ(o),
                  0L);
      }

      size_t m            = LEN_PLIST(ELM_PLIST(o, 1));
      using semiring_type = typename MinPlusTruncMat<>::semiring_type;
      auto const* sr      = semigroups::semiring<semiring_type>(
          static_cast<size_t>(INT_INTOBJ(ELM_PLIST(o, m + 1))));
      return detail::init_cpp_matrix<MinPlusTruncMat<>>(o, sr);
    }
  };

  template <>
  struct to_cpp<NTPMat<>> {
    using cpp_type = NTPMat<>;

    NTPMat<> operator()(Obj o) const {
      if (CALL_1ARGS(IsNTPMatrix, o) != True) {
        ErrorQuit("expected ntp matrix, found %s!", (Int) TNAM_OBJ(o), 0L);
      }
      SEMIGROUPS_ASSERT(LEN_PLIST(o) != 0);
      size_t      m  = LEN_PLIST(ELM_PLIST(o, 1));
      auto const* sr = semigroups::semiring(
          static_cast<size_t>(INT_INTOBJ(ELM_PLIST(o, m + 1))),
          static_cast<size_t>(INT_INTOBJ(ELM_PLIST(o, m + 2))));
      return detail::init_cpp_matrix<NTPMat<>>(o, sr);
    }
  };

  ////////////////////////////////////////////////////////////////////////
  // congruence_kind
  ////////////////////////////////////////////////////////////////////////

  template <>
  struct to_cpp<congruence_kind> {
    using cpp_type                          = congruence_kind;
    static gap_tnum_type constexpr gap_type = T_STRING;

    cpp_type operator()(Obj o) const {
      if (!IS_STRING_REP(o)) {
        ErrorQuit("expected string but got %s!", (Int) TNAM_OBJ(o), 0L);
      }
      std::string stype = std::string(CSTR_STRING(o));
      if (stype == "left") {
        return congruence_kind::left;
      } else if (stype == "right") {
        return congruence_kind::right;
      } else if (stype == "2-sided") {
        return congruence_kind::twosided;
      } else {
        ErrorQuit("Unrecognised type %s", (Int) stype.c_str(), 0L);
      }
    }
  };

  template <>
  struct to_cpp<libsemigroups::Congruence::options::runners> {
    using cpp_type = libsemigroups::Congruence::options::runners;

    cpp_type operator()(Obj o) const {
      if (!IS_STRING_REP(o)) {
        ErrorQuit("expected string but got %s!", (Int) TNAM_OBJ(o), 0L);
      }
      std::string stype = std::string(CSTR_STRING(o));
      if (stype == "none") {
        return cpp_type::none;
      } else if (stype == "standard") {
        return cpp_type::standard;
      } else {
        ErrorQuit("Unrecognised type %s", (Int) stype.c_str(), 0L);
      }
    }
  };

  ////////////////////////////////////////////////////////////////////////
  // Transformations
  ////////////////////////////////////////////////////////////////////////

  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);
      } else if (LEN_PLIST(t) != 2) {
        ErrorQuit("expected list of length 2, but it has length %d",
                  (Int) LEN_PLIST(t),
                  0L);
      } else if (!IS_TRANS(ELM_PLIST(t, 1))) {
        ErrorQuit("expected transforamtion in position 1, got %s",
                  (Int) TNAM_OBJ(t),
                  0L);
      } else if (!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));
      } else if (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;
    }
  };

  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
  ////////////////////////////////////////////////////////////////////////

  namespace detail {
    template <typename T>
    struct Undef;

    template <typename T>
    struct Undef<PPerm<0, T>> {
      static constexpr T value = UNDEFINED;
    };

#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
    template <>
    struct Undef<HPCombi::PPerm16> {
      static constexpr UInt2 value = 0xFF;
    };
#endif

    template <typename S, typename T>
    void to_cpp_pperm(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 UInt2 or UInt4");
      SEMIGROUPS_ASSERT(N <= libsemigroups::Degree<S>()(x));
      T i;
      T undef = static_cast<T>(Undef<S>::value);

      for (i = 0; i < N; ++i) {
        if (ptr[i] == 0) {
          x[i] = undef;
        } else {
          x[i] = ptr[i] - 1;
        }
      }
      for (; i < libsemigroups::Degree<S>()(x); ++i) {
        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 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);
      } else if (LEN_PLIST(t) != 2) {
        ErrorQuit("expected list of length 2, but it has length %d",
                  (Int) LEN_PLIST(t),
                  0L);
      } else if (!IS_PPERM(ELM_PLIST(t, 1))) {
        ErrorQuit("expected partial perm in position 1, got %s",
                  (Int) TNAM_OBJ(t),
                  0L);
      } else if (!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));
      } else if (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));
      } else if (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;
    }
  };

  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
  ////////////////////////////////////////////////////////////////////////

  template <>
  struct to_cpp<Bipartition> {
    Bipartition& operator()(Obj x) const {
      if (TNUM_OBJ(x) != T_BIPART) {
        ErrorQuit("expected a bipartition, got %s", (Int) TNAM_OBJ(x), 0L);
      }
      return *bipart_get_cpp(x);
    }
  };

  ////////////////////////////////////////////////////////////////////////
  // PBR
  ////////////////////////////////////////////////////////////////////////

  template <>
  struct to_cpp<PBR> {
    PBR operator()(Obj x) const {
      if (CALL_1ARGS(IsPBR, x) != True) {
        ErrorQuit("expected a PBR, got %s", (Int) TNAM_OBJ(x), 0L);
      } else if (LEN_PLIST(x) == 0) {
        ErrorQuit("expected a PBR of degree > 0", 0L, 0L);
      }

      size_t m = INT_INTOBJ(ELM_PLIST(x, 1));
      // SEMIGROUPS_ASSERT(LEN_PLIST(x) == 2 * m + 1);

      libsemigroups::PBR result(m);

      for (uint32_t i = 0; i < 2 * m; i++) {
        Obj adj = ELM_PLIST(x, i + 2);
        for (uint32_t j = 1; j <= LEN_PLIST(adj); j++) {
          result[i].push_back(INT_INTOBJ(ELM_PLIST(adj, j)) - 1);
          // assumes that adj is duplicate-free
        }
        std::sort(result[i].begin(), result[i].end());
      }
      return result;
    }
  };

  template <typename T>
  struct to_cpp<DynamicArray2<T>> {
    using cpp_type = DynamicArray2<T>;
    cpp_type operator()(Obj x) {
      using value_type = typename DynamicArray2<T>::value_type;
      if (!IS_LIST(x)) {
        ErrorQuit("expected a list, got %s", (Int) TNAM_OBJ(x), 0L);
      }
      for (size_t i = 0; i < LEN_LIST(x); ++i) {
        Obj item = ELM_LIST(x, i + 1);
        if (!IS_HOMOG_LIST(item)) {
          ErrorQuit(
              "expected a list of homog. lists, but got %s in position %d",
              (Int) TNAM_OBJ(x),
              (Int) i + 1);
        } else if (i > 0 && LEN_LIST(ELM_LIST(x, i)) != LEN_LIST(item)) {
          ErrorQuit("expected a list of lists of equal length, but found a "
                    "list of length %d in position %d",
                    (Int) LEN_LIST(item),
                    (Int) i + 1);
        }
      }
      size_t   nr_cols = (LEN_LIST(x) == 0 ? 0 : LEN_LIST(ELM_LIST(x, 1)));
      cpp_type result(nr_cols, LEN_LIST(x));
      for (size_t i = 0; i < LEN_LIST(x); ++i) {
        Obj item = ELM_LIST(x, i + 1);
        for (size_t j = 0; j < nr_cols; ++j) {
          result.set(i, j, to_cpp<value_type>()(ELM_LIST(item, j + 1)));
        }
      }
      return result;
    }
  };
}  // namespace gapbind14
#endif  // SEMIGROUPS_SRC_TO_CPP_HPP_

93%


¤ Dauer der Verarbeitung: 0.19 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

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.