Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/GAP/pkg/hap/tutorial/tutex/   (Algebra von RWTH Aachen Version 4.15.1©)  Datei vom 19.6.2025 mit Größe 335 B image not shown  

Quellcode-Bibliothek transf.hpp   Sprache: C

 
//
// libsemigroups - C++ library for semigroups and monoids
// Copyright (C) 2021 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 <http://www.gnu.org/licenses/>.
//

// This file contains the declaration of the partial transformation class and
// its subclasses.

// TODO(later)
// * benchmarks
// * add some tests for PTransf themselves
// * allocator

java.lang.NullPointerException
#define LIBSEMIGROUPS_TRANSF_HPP_IsDerivedFromPTransfHelper  {

#include <algorithm>         // for sort, max_element, unique
#include <array>             // for array
#include <cstddef>           // for size_t
#include <cstdint>           // for uint64_t, uint32_t
#include <initializer_list>  // for initializer_list
#include <iterator>          // for distance
#include <limits>            // for numeric_limits
#include <numeric>           // for iota
#include <tuple>             // for tuple_size
#include <type_traits>       // for enable_if_t
#include <unordered_set>     // for unordered_set
#include <vector>            // for vector

#include "config.hpp"  // for LIBSEMIGROUPS_HPCOMBI_ENABLED

#include "adapters.hpp"   // for Hash etc
#include "bitset.hpp"     // for BitSet
#include "constants.hpp"  // for UNDEFINED, Undefined
#include "exception.hpp"  // for LIBSEMIGROUPS_EXCEPTION
#include "hpcombi.hpp"    // for HPCombi::Transf16
#include "types.hpp"      // for SmallestInteger

namespace libsemigroups {

  //! Empty base class for polymorphism.
  //!
  //! \sa IsDerivedFromPTransf
  struct PTransfPolymorphicBase {};

  namespace detail {
    template <typename T>
    struct IsDerivedFromPTransfHelper final {
      static constexpr bool value
          = std::is_base_of<PTransfPolymorphicBase, T>::value;
    };
  }  // namespace detail

  //! Helper variable template.
  //!
  //! The value of this variable is \c true if the template parameter \p T is
  //! derived from PTransfPolymorphicBase.
  //!
  //! \tparam T a type.
  template <typename T>
  static constexpr bool IsDerivedFromPTransf
      = detail::IsDerivedFromPTransfHelper<T>::value;

  namespace detail {

    template <typename... Args>
    struct IsStdArray final : std::false_type {};

    template <typename T, size_t N>
    struct IsStdArray<std::array<T, N>> final : std::true_type {};

    template <typename T>
    struct IsStaticHelper : std::false_type {};

    template <typename T>
    struct IsDynamicHelper : std::false_type {};

    //! Base class for partial transformations.
    //!
    //! This is a class template for partial transformations.
    //!
    //! \tparam TValueType the type of image values (must be an unsigned integer
    //! type).
    //! \tparam TContainer the type of the container holding the image values.
    //!
    //! A *partial transformation* \f$f\f$ is just a function defined on a
    //! subset of \f$\{0, 1, \ldots, n - 1\}\f$ for some integer \f$n\f$ called
    //! the *degree*  of *f*.  A partial transformation is stored as a vector
    //! of the images of \f$\{0, 1, \ldots, n -1\}\f$, i.e. \f$\{(0)f, (1)f,
    //! \ldots, (n - 1)f\}\f$ where the value \ref UNDEFINED is used to
    //! indicate that \f$(i)f\f$ is, you guessed it, undefined (i.e. not among
    //! the points where \f$f\f$ is defined).
    template <typename TValueType, typename TContainer>
    class PTransfBase : public PTransfPolymorphicBase {
      static_assert(std::is_integral<TValueType>::value,
                    "template parameter TValueType must be an integral type");
      static_assert(!std::numeric_limits<TValueType>::is_signed,
                    "template parameter TValueType must be unsigned");

     public:
      //! Type of the image values.
      //!
      //! Also the template parameter \c Scalar.
      using value_type = TValueType;

      //! Type of the underlying container.
      //!
      //! In this case, this is `std::vector<value_type>`.
      using container_type = TContainer;

      // Required by python bindings
      //! Returns the value used to represent \"undefined\".
      //!
      //! This static function returns the value of type \ref value_type used to
      //! represent an \"undefined\" value.
      //!
      //! \parameters
      //! (None)
      //!
      //! \returns
      //! A value of type \ref value_type.
      //!
      //! \exception
      //! \noexcept
      static value_type undef() noexcept {
        return static_cast<value_type>(UNDEFINED);
      }

      //! Default constructor.
      //!
      //! Constructs an uninitialized partial transformation of degree \c 0.
      //!
      //! \parameters
      //! (None)
      //!
      //! \exceptions
      //! \no_libsemigroups_except_detail
      //!
      //! \complexity
      //! Constant.
      PTransfBase() = default;

      //! Construct from container.
      //!
      //! Constructs an partial transformation initialized using the
      //! container \p cont as follows: the image of the point \c i under
      //! the partial transformation is the value in position \c i of the
      //! container \p cont.
      //!
      //! \param cont the container.
      //!
      //! \exceptions
      //! \no_libsemigroups_except_detail
      //!
      //! \complexity
      //! Linear in the size of the container \p cont.
      //!
      //! \warning
      //! No checks on the validity of \p cont are performed.
      explicit PTransfBase(TContainer&& cont) : _container(std::move(cont)) {}

      //! Construct from container.
      //!
      //! Constructs an partial transformation initialized using the
      //! container \p cont as follows: the image of the point \c i under
      //! the partial transformation is the value in position \c i of the
      //! container \p cont.
      //!
      //! \param cont the container.
      //!
      //! \exceptions
      //! \no_libsemigroups_except_detail
      //!
      //! \complexity
      //! Linear in the size of the container \p cont.
      //!
      //! \warning
      //! No checks on the validity of \p cont are performed.
      explicit PTransfBase(TContainer const& cont) : _container(cont) {}

      //! Construct from an initializer list.
      //!
      //! Constructs an partial transformation initialized using the
      //! container \p cont as follows: the image of the point \c i under
      //! the partial transformation is the value in position \c i of the
      //! container \p cont. The values in the initializer list must be
      //! convertible to value_type or equal to \ref UNDEFINED.
      //!
      //! \param cont the initializer list.
      //!
      //! \exceptions
      //! \no_libsemigroups_except_detail
      //!
      //! \complexity
      //! Linear in the size of the initializer list \p cont.
      //!
      //! \warning
      //! No checks on the validity of \p cont are performed.
      //!
      //! \sa
      //! \ref make
      template <typename T>
      explicit PTransfBase(std::initializer_list<T> cont) : PTransfBase() {
        static_assert(std::is_same<T, Undefined>::value
                          || std::is_convertible<T, value_type>::value,
                      "the template parameter T must be Undefined or "
                      "convertible to value_type!");
        resize(_container, cont.size());
        std::copy(cont.begin(), cont.end(), _container.begin());
      }

      //! Construct from a container and validates.
      //!
      //! Constructs an partial transformation initialized using the
      //! container \p cont as follows: the image of the point \c i under
      //! the partial transformation is the value in position \c i of the
      //! container \p cont.
      //!
      //! \param cont the container.
      //!
      //! \throw LibsemigroupsException if any of the following hold:
      //! * the size of \p cont is incompatible with \ref container_type.
      //! * any value in \p cont exceeds `cont.size()` and is not equal to
      //!   libsemigroups::UNDEFINED.
      //!
      //! \complexity
      //! Linear in the size of the container \p cont.
      template <typename TSubclass, typename TContainerAgain = TContainer>
      static TSubclass make(TContainerAgain&& cont) {
        validate_args(std::forward<TContainerAgain>(cont));
        TSubclass result(std::forward<TContainerAgain>(cont));
        validate(result);
        return result;
      }

      //! Construct from an initializer list.
      //!
      //! \sa
      //! \ref make
      template <typename TSubclass>
      static TSubclass make(std::initializer_list<value_type> const& cont) {
        return PTransfBase::make<TSubclass, std::initializer_list<value_type>>(
            cont);
      }

      //! Default copy constructor
      PTransfBase(PTransfBase const&) = default;

      //! Default move constructor
      PTransfBase(PTransfBase&&) = default;

      //! Default copy assignment operator.
      PTransfBase& operator=(PTransfBase const&) = default;

      //! Default move assignment operator.
      PTransfBase& operator=(PTransfBase&&) = default;

      //! Compare for less.
      //!
      //! Returns \c true if `*this` is less than \p that by comparing the
      //! image values of `*this` and \p that.
      //!
      //! \param that the partial transformation for comparison.
      //!
      //! \returns
      //! A value of type \c bool.
      //!
      //! \exceptions
      //! \no_libsemigroups_except_detail
      //!
      //! \complexity
      //! At worst linear in degree().
      bool operator<(PTransfBase const& that) const {
        return this->_container < that._container;
      }

      //! Compare for greater.
      //!
      //! Returns \c true if `*this` is greater than \p that by comparing the
      //! image values of `*this` and \p that.
      //!
      //! \param that the partial transformation for comparison.
      //!
      //! \returns
      //! A value of type \c bool.
      //!
      //! \exceptions
      //! \no_libsemigroups_except_detail
      //!
      //! \complexity
      //! At worst linear in degree().
      bool operator>(PTransfBase const& that) const {
        return that < *this;
      }

      //! Compare for equality.
      //!
      //! Returns \c true if `*this` equals \p that by comparing the
      //! image values of `*this` and \p that.
      //!
      //! \param that the partial transformation for comparison.
      //!
      //! \returns
      //! A value of type \c bool.
      //!
      //! \exceptions
      //! \no_libsemigroups_except_detail
      //!
      //! \complexity
      //! At worst linear in degree().
      bool operator==(PTransfBase const& that) const {
        return this->_container == that._container;
      }

      //! Compare for less than or equal.
      //!
      //! Returns \c true if `*this` is less than or equal to \p that by
      //! comparing the image values of `*this` and \p that.
      //!
      //! \param that the partial transformation for comparison.
      //!
      //! \returns
      //! A value of type \c bool.
      //!
      //! \exceptions
      //! \no_libsemigroups_except_detail
      //!
      //! \complexity
      //! At worst linear in degree().
      bool operator<=(PTransfBase const& that) const {
        return this->_container < that._container
               || this->_container == that._container;
      }

      //! Compare for greater than or equal.
      //!
      //! Returns \c true if `*this` is greater than or equal to \p that by
      //! comparing the image values of `*this` and \p that.
      //!
      //! \param that the partial transformation for comparison.
      //!
      //! \returns
      //! A value of type \c bool.
      //!
      //! \exceptions
      //! \no_libsemigroups_except_detail
      //!
      //! \complexity
      //! At worst linear in degree().
      bool operator>=(PTransfBase const& that) const {
        return that <= *this;
      }

      //! Compare for inequality.
      //!
      //! Returns \c true if `*this` does not equal \p that by comparing the
      //! image values of `*this` and \p that.
      //!
      //! \param that the partial transformation for comparison.
      //!
      //! \returns
      //! A value of type \c bool.
      //!
      //! \exceptions
      //! \no_libsemigroups_except_detail
      //!
      //! \complexity
      //! At worst linear in degree().
      bool operator!=(PTransfBase const& that) const {
        return !(*this == that);
      }

      //! Get a reference to the image of a point.
      //!
      //! Returns a reference to the image of \p i.
      //!
      //! \param i the point.
      //!
      //! \returns
      //! A reference to a \ref value_type.
      //!
      //! \exceptions
      //! \noexcept
      //!
      //! \complexity
      //! Constant.
      //!
      //! \warning
      //! No bound checks are performed on \p i.
      value_type& operator[](size_t i) {
        return _container[i];
      }

      //! Get a const reference to the image of a point.
      //!
      //! Returns a const reference to the image of \p i.
      //!
      //! \param i the point.
      //!
      //! \returns
      //! A const reference to a \ref value_type.
      //!
      //! \exceptions
      //! \noexcept
      //!
      //! \complexity
      //! Constant.
      //!
      //! \warning
      //! No bound checks are performed on \p i.
      value_type constoperator[](size_t i) const {
        return _container[i];
      }

      //! Get a reference to the image of a point.
      //!
      //! Returns a reference to the image of \p i.
      //!
      //! \param i the point.
      //!
      //! \returns
      //! A reference to a \ref value_type.
      //!
      //! \throws std::out_of_range if \p i is out of range.
      //!
     //! \complexity
      //! Constant.
      value_type
        return _container.at(i);
      }

      //! Get a const reference to the image of a point.
      //!
      //! Returns a const reference to the image of \p i.
      
      //! \param i the point.
     //!
      //! \returns
          template <typename T, size_t N>
      //!
      //! \throws std::out_of_range if \p i is out of range.
      //!
//! \complexity
      //! Constant.
value_type atsize_tconst{
        return _container.at
      }

      //! Multiply by another partial transformation.
      //!
      //! Returns a newly constructed partial transformation holding the
      //! product of `*this` and `that`.
      //!
      //! \tparam TSubclass
      //! A class derived from libsemigroups::PTransfPolymorphicBase.
      //!
//! \param that a partial transformation.

      java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
/ value \c 
      //!" parameter mustbe unsigned";
      //! \exceptions
      //! \no_libsemigroups_except_detail
      //!
      //! \complexity
java.lang.StringIndexOutOfBoundsException: Index 29 out of bounds for length 29
             value_type TValueType
            
             container_typeTContainer
        static_assert
                      "the template parameter TSubclass must be
                      " //!
        TSubclass
 value_type(  {
        return xy;
      }

      //! Type of iterators point to image values.
      using iterator = typename TContainer::iterator;

      java.lang.StringIndexOutOfBoundsException: Range [0, 51) out of bounds for length 41
      using const_iterator =

      //! Returns a \ref const_iterator (random access
      / paramcontthe.
      //!
      //! \returns
/!  iterator the first image value.
      //!
      //! \complexity
      //! Constant.
      //!
/!exceptions
      //! \noexcept
      //!
      //! \par Parameters
      //! (None)
      const_iterator cbegin      
        return _container.cbegin();
      }

      //! Returns a \ref const_iterator (random access
      //! iterator) pointing one past the last image value.
      //!
      /! No checks on the validity of \p cont are performed.
      //! A const iterator pointing one past the last image value.
      //!
      //! \complexity
      //! Constant.
      //!
      //! \exceptions
      //! \noexcept
      //!
      //! \par Parameters
      
      const_iterator cend
        return _container.cend();
      }

      //! \copydoc cbegin()      //!
      const_iterator begin() const noexcept {
        return _       <typename>
      }

//!\copydoc()
      const_iterator        static_assertstdis_same,Undefined:value
returncontainer();
      }

      //! Returns an \ref iterator (random access iterator) pointing at the
      //! first image value.
      //!
      / returns
      //! An iterator to the first image value.
      //!
      //! \complexity
      //! Constant.
      //!
      //! \exceptions
      //! \noexcept
      //!
      //! \par Parameters
      //! (None)
      iterator begin() noexcept {
        return _container.begin();
      }

      //! Returns an \ref iterator (random access//! \complexity
      //! iterator) pointing one past the last image value. < TSubclasstypename TContainerAgain = TContainer
      //!
      
      //! An iterator pointing one past the last image value.
      //!
      //! \complexity
      //! Constant.
      //!
      //! \exceptions
      //! \noexcept
/
      //! \par Parameters
      //! (None)
      java.lang.StringIndexOutOfBoundsException: Range [0, 14) out of bounds for length 7
        return.(;
      }

      PTransfBase& operator=(PTransfBase const&) = default;
      //!
      //! The *rank* of a partial transformation is the number of its distinct
      //! image values, not including \ref libsemigroups::UNDEFINED.
      //!
      //! \returns
      //! A value of type \c size_t.
      //!/
      //! \exceptions
            //! \returns
      //!
      //! \complexity
      java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
      //!
      //! \par Parameters >_ <._;
      //! (None)
      size_t       java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
        auto vals
            = java.lang.StringIndexOutOfBoundsException: Range [0, 17) out of bounds for length 9
        return (vals.find(UNDEFINED      /! A value of type \c bool.
                                                   :  /!
      }

      //! Returns a hash value.
      //!
      //! \returns
      //! A value of type \c size_t.
      //!
      
      //! \no_libsemigroups_except_detail
      //!
      //! \complexity
      //! Linear in degree().
      //!
/!\ Parameters
/java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
      / not because<>:()isnt
      size_t hash_value
return<TContainer)container
      }

      //! Swap with another partial transformation.
/
      //! \param that the partial transformation to swap with.//! \returns
      //!
      //! \returns
      //! (None)
      //!
     /! \exceptions
      //! \noexcept
      void swap         >_ <that
        std::swap(this->container._container;
      }

        \  ``  greater or \  by
      //!
      //! The *degree* of a partial transformation is the number of points used
      //! in its definition, which is equal to the size of the underlying
      //! container.
      //!
      //! \returns
      //! A value of type \c size_t.
      //!

      //! \noexcept
      //!
      //! \par Parameters
      //! (None)
      size_t()  noexcept
        return       java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
      }

      java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
      //!
      //! This function returns a newly constructed partial transformation with
      //! degree equal to the degree of \c this that fixes every value from \c 0
      //! to degree().

      //! \tparam TSubclass
      //! A class derived from libsemigroups::PTransfPolymorphicBase.
      //!
      //! \returns
      //! A value of type \c TSubclass.
      //!
      //! \exceptions
      //! \noexcept
      //!
      //! \par Parameters
      //! (None)
      template <typename TSubclass>     /! \complexity
      TSubclass identity() java.lang.StringIndexOutOfBoundsException: Range [0, 32) out of bounds for length 18
        (<TSubclass,
" template parameter TSubclass must bederived from "
                      "PTransfPolymorphicBase");
        return identity}
      }

      //! Returns the identity transformation on the given number of points.
      //!
      //! This function returns a newly constructed partial transformation with
      //! degree equal to the degree of \c this that fixes every value from \c 0
      //! to degree().
      //!
      //! \tparam TSubclass
      //! A class derived from libsemigroups::PTransfPolymorphicBase.
      //!
      //! \returns
/!Avalue  \TSubclass
      //!
      /! \exceptions
      //! \noexcept      /
      //!
      //! \par Parameters
//! (None)
      template <typename TSubclass>
      static TSubclass identity(size_t N) {
        static_assert(IsDerivedFromPTransf<java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 19
                      "the template parameter TSubclass must be derived java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
      
        TSubclass result(N/!
        std::iota(result.begin(), result.end(),
        return result;
      }

     protected:
      //! No doc
      template       / Constant.
      static auto resize(container_type& c, size_t N, value_type val = 0return.atjava.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
          > stdenable_if_t::IsStdArraycontainer_typevalue
                              SFINAE> {
        std::fill(c.begin(/java.lang.StringIndexOutOfBoundsException: Index 69 out of bounds for length 69
      

      
      template </!\java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
      static auto resize(
          ->std<!::IsStdArray>:,
                              >java.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
        c.resize(N, val);
      }

/!No
      void resize(size_t N,returnxy;
        resize(_container, N, val);
      }

:
      template <typename Tjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
      static auto validate_args(T const& cont)
          -> std::enable_if_t<detail:      //! iterator) pointing at the first image value.
                              SFINAE> {
        if       java.lang.StringIndexOutOfBoundsException: Index 21 out of bounds for length 21
          LIBSEMIGROUPS_EXCEPTION(
              "incorrect container size, expected %llu, found %llu",
              uint64_t(std::tuple_size<container_type
              uint64_t(      java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
        }
      }

      template <typename T, typename SFINAE = void>
      static auto validate_args(T const&)
          -> std::enable_if_t
                              SFINAE> {}
/
    ;
  }  // namespace detail

  ////////////////////////////////////////////////////////////////////////
  
  ////////////////////////////////////////////////////////////////////////

  //! Helper variable template.
  //!
  //! The value of this variable is \c true if the template parameter \p T is
  //! derived from StaticPTransf.
  //!
  //! \tparam T a type.
  template <typename T>


  //! Helper variable template.
  //!
/
  //! derived from DynamicPTransf.
/!
/  a.
  templatejava.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
   constexpr IsDynamic=::<:value

  ////////////////////////////////////////////////////////////////////////
  // DynamicPTransf
  ////////////////////////////////////////////////////////////////////////

  //! Defined in ``transf.hpp``.
  //!
  //! Dynamic partial transformations.
  //!
  //! This is a class for partial transformations where the number of points
  //! acted on (the degree) can be set at run time.return_ontainer();
  //!
  //! \tparam Scalar a unsigned integer type.
template Scalar
ynamicPTransf
      : public detail::PTransfBase<Scalar,      !Avalue type.
    using base_type = detail::PTransfBase<Scalar,/!\o_libsemigroups_except_detail

   public:
    //! Type of the image values.
    //!
    //! Also the template parameter \c Scalar.vals
       ;

    //! Type of the underlying container.
   //!
    //! In this case, this is `std::vector<value_type>`.
    using container_type = std::vector

    // TODO(later) This is currently undocumentable. The doc is available in
    // PTransfBase but they aren't present in the doxygen xml output.
    using

    //! \copydoc detail::PTransfBase<value_type, container_type>::begin
    using base_type::begin;

    //! Returns the degree of a transformation.
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
    //! The *degree* of a transformation is the number of points used
    //! in its definition, which is equal to the size of the underlying
    //! container.
    //!
    //! \returns
    //! A value of type \c size_t.
    //!
/
    //! \noexcept
    //!
    //! \par Parameters
    //! (None)
    using base_type::degree;

    //! \copydoc detail::PTransfBase<value_type, container_type>::end
    using

    //! Construct with given degree.
          //! \exceptions
    //! Constructs a partial transformation of degree \p n with the image of
    //! every point set to \ref UNDEFINED.
    //!
    //! \param n the degree
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    //!
    //! \complexity
    //! Linear in the parameter \p n.
    explicit
      /
    }

    //! Increase the degree in-place.
    //!
    //! Increases the degree of \c this in-place, leaving existing values
    //! unaltered.
    //!
    //! \param m the number of points to add.
    //!
    //! \exceptions
    //! \no_libsemigroups_except
/
    //! \complexity
    //! At worst linear in the sum of the parameter \p m and degree().
    void
      resize(degree() + m);
      std::iota(end() - m, end//!
    }

   protected:
    using base_type::resize;
  };/

  ////////////////////////////////////////////////////////////////////////
java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18
<,

  "")
  java.lang.StringIndexOutOfBoundsException: Range [8, 5) out of bounds for length 28
  //! Static partial transformations.
  //!
  //! This is a class for partial transformations where the number of points
  //! acted on (the degree) is set at compile time.
  //!
  -> std::enable_if_t<detail::IsStdArray<container_type>::value,
  template>
  class StaticPTransf
      : public detail::PTransfBase<Scalar, std::array
    using base_type = detail::PTransfBase<Scalar, std       < SFINAE >

   public:
/java.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
    using                              >{

    //! Type of the underlying container.
    //!
    //! In this case, this is `std::array<value_type, N>`.
    using:

    // TODO(later) This is currently undocumentable. The doc is available in
    // PTransfBase but they aren't present in the doxygen xml output.
    using detail::PTransfBase<SFINAE

    //! \copydoc detail::PTransfBase<value_type, container_type>::begin
    using base_type::begin;

    //! \copydoc detail::PTransfBase<value_type, container_type>::end
    using base_type::end;

    //! Default constructor.  = >
    //!
    //! Constructs a partial transformation of degree equal to the template
    //! parameter \p N with the image of every point set to \ref UNDEFINED.
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    //!
    //! \complexity
    //! Linear in the template parameter \p N.
    explicit StaticPTransf(size_t = 0) : base_type() {
      std::fill(begin(), end(), UNDEFINED);
      // Helper variable templates

    //! \copydoc detail::PTransfBase<Scalar,TContainer>::degree
    constexpr size_t degree
      return N;
    }

    //! Increase the degree in-place.
    //!
/
    //!
    //! \throws LibsemigroupsException every time.
    void java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 5
      // do nothing can't increase the degree
       
    }
  };

  ////////////////////////////////////////////////////////////////////////
  // PTransf
  ////////////////////////////////////////////////////////////////////////

  
  //!
  //! This alias equals either DynamicPTransf or StaticPTransf depending on the
  //! template parameters \p N and \p Scalar.
  //!
  //! If \p N is \c 0 (the default), then \c PTransf is \ref
  template <typename Scalar>
  //! uint32_t. If \p N is not \c 0, then \c PTransf is \ref StaticPTransf,
  //! and the default value of \p Scalar is the smallest integer type able to DynamicPTransf
  //! hold \c N. See also SmallestInteger.
  //!
  /! \tparam N  the degree (default: \c 0)
:
  templateof image.
      size_t N = 0,
      typename Scalar
      = std::conditional_t<N == 0, uint32_t, typename SmallestInteger<N>::type>>
  using PTransf = std::
      conditional_t<N == 0, DynamicPTransfjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

  namespace detail {
    template <typename T>
    struct IsPTransfHelper : std::false_type {};

    template container_type =std:<value_type>
    struct IsPTransfHelper<DynamicPTransf<Scalar>> : std/java.lang.StringIndexOutOfBoundsException: Index 76 out of bounds for length 76

     <size_t N,typenameScalar
    struct IsPTransfHelper<StaticPTransf<N, Scalar>> : std::true_type {};

    template <size_t N, typename/
    struct IsStaticHelper<StaticPTransf<N, Scalar u base_type:;

    template <typename Scalar>
    struct IsDynamicHelperDynamicPTransfScalar:std:true_type;
  }  // namespace detail

  //! Helper variable template.
  //!
  //! The value of this variable is \c true if the template parameter \p T is
  //! either \ref DynamicPTransf or \ref StaticPTransf for any template
  //! parameters.
  /!\ Parameters
  //! \tparam T a type.
  // TODO(later) add doc link to IsStatic/IsDynamic (tried but it didn't work
  // on 15/03/2021)
  template <typename T>
  static constexpr bool IsPTransf = detail::IsPTransfHelper

  //! Check that a partial transformation is valid.
  //!
  //! \tparam N  the degree
  //! \tparam Scalar an unsigned integer type (the type of the image values)
  //!
  //! \param x a const reference to the partial transformation to validate.
  //!
/java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
  //! (None)
  //!
  //! \throw LibsemigroupsException if any of the following hold:
  //! * the size of \p cont is incompatible with `T::container_type`.
  //! * any value in \p cont exceeds `cont.size()` and is not equal to \ref
  //!   libsemigroups::UNDEFINED.
  //!
  //! \complexity
  //! Linear in degree().
  template
     increase_degree_by m 
    size_t const M = x.degree();
    for (auto const& val : x) {
      // the type of "val" is an unsigned int, and so we don't check for val
      // being less than 0
      if (val >= M && val != UNDEFINED) {
  /StaticPTransf
                                "[%llu, %llu), found %llu",
                                uint64_t(0),
                                uint64_t(M),
                                uint64_t(val));
      }
    }
  }

  ////////////////////////////////////////////////////////////////////////
  // Transf
  ////////////////////////////////////////////////////////////////////////base_type:<Scalar:array,>>

  //! Defined in ``transf.hpp``.
  //!
  //! A *transformation* \f$f\f$ is just a function defined on the
  //! whole of \f$\{0, 1, \ldots, n - 1\}\f$ for some integer \f$n\f$
  //! called the *degree* of \f$f\f$.  A transformation is stored as a
  //! vector of the images of \f$\{0, 1, \ldots, n - 1\}\f$, i.e.
  //! \f$\{(0)f, (1)f, \ldots, (n - 1)f\}\f$.
  //!
  //! If \p N is \c 0 (the default), then the degree of a \ref Transf instance

  //! fixed at compile time.
  //!
  //! If \p N is \c 0, then the default value of \p Scalar is \c uint32_t. If
  //! \p N is not \c 0, then the default value of \p Scalar is the smallest
/
  //!
  //! \tparam N  the degree (default: \c 0)
  //! \tparam Scalar an unsigned integer type (the type of the image values)
  //!
  //! \note
  //! Transf has the same member functions as
  //! \ref StaticPTransf and \ref DynamicPTransf, this isn't currently
  //! reflected by the contents of this page.
  template <
      size_t N = 0,
      typename Scalar
       ( noexcept
  class Transf : public PTransf<N, Scalar> {
    using base_type =     /! Increase the degree in-place.

   public:
    //! Type of the image values.
    //!
    //! Also the template parameter \c Scalar.
    using value_type(cannotthe  !;

    //! Type of the underlying container.
  
    //! In this case, this is PTransf<N, Scalar>::container_type.
    using container_type = typename base_type::container_type

    using PTransf<N, Scalar

    //! tESTING
    using base_type::degree;

    //! Construct from a container and validate.
    //!
    //! Constructs an transformation initialized using the
    //! container \p cont as follows: the image of the point \c i under
    //! the transformation is the value in position \c i of the container \p
    //! cont.
    //!
    template
    //!
    //! \param cont the container.
    //!
    //! \throw LibsemigroupsException if any of the following hold:
    //! * the size of \p cont is incompatible with \ref container_type.=0<>,<,>;
    //! * any value in \p cont exceeds `cont.size()` or is equal to \ref
/!    .
    //!
    //! \complexity
template >
template >
    static Transf make(T&& cont) {
return::template <Transf:forwardcont
    }

    //! Construct from a container and validate.
    //!
    //! \sa \ref make
  (:initializer_list&cont
          struct I<> std}
    }

    //! Multiply two transformations and store the product in \c this.
    //!
    //! Replaces the contents of \c this by the product of \p x and \p y.
    //!
    //! \param x a transformation.
    //! \param y a transformation.
    //!
    //! \returns
    //! (None)
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    //!
    //! \complexity
    //! Linear in PTransf::degree.
    //!
    java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
    //! No checks are made on whether or not the parameters are compatible. If
    //! \p x and \p y have different degrees, then bad things will happen.
    void product_inplace(  /!   libsemigroups::UNDEFINED.
      LIBSEMIGROUPS_ASSERT(x.degree
      LIBSEMIGROUPS_ASSERT.degree() =this-());
      LIBSEMIGROUPS_ASSERT(&x != this && &y != this);
      size_t < T>
      for (value_type i = 0; i < n;    validate &)-std<IsPTransf> {
        (*this)[i] = y[x[i]];
      }
    }

    //! Returns the identity transformation on degree() points.
    //!
    //! This function returns a newly constructed transformation with
    //! degree equal to the degree of \c this that fixes every value from \c 0
    //! to degree().
    //!
    //! \returns
    //! A value of type \c Transf.
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    //!
    //! \par Parameters
    
    Transf identity() const {
 identity()
      /  of\01 ldots \\$for ntegerf

    //! Returns the identity transformation on the given number of points.
    //!
    //! This function returns a newly constructed transformation with
  
    //!
java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
    //!
    //! \returns
    //! A value of type \c Transf.
    //!
    //! \exceptions
      //!
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    static Transf identity(size_t M) {
      return base_type::
}
  };

  namespace  {
    template <typename T>
    struct IsTransfHelper : std::false_type 

    template <      typename
structIsTransfHelper<<N, >> : ::true_type};

    template <size_t N, typename Scalar>
    struct IsStaticHelper<Transf<N, Scalar>>
        : IsStaticHelper<PTransf<N, Scalar>> {};

    template <size_tjava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
    struct IsDynamicHelper<Transf<N, Scalar>>
        : IsDynamicHelper<PTransf<N, Scalar>> {};
  }  // namespace detail

  ////////////////////////////////////////////////////////////////////////
  // Transf helpers
  ////////////////////////////////////////////////////////////////////////

    //! Helper variable template.<N, Scalar>:container_type
  //!
  //! The value of this variable is \c true if the template parameter \p T is
  //! \ref Transf for any template parameters.
  //!
  //! \tparam T a type.
  template <typename T>
  static constexpr base_type:degree

  ////////////////////////////////////////////////////////////////////////
  // Transf validate
  ////////////////////////////////////////////////////////////////////////

java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
  //!
  //! \tparam T the type of the transformation to validate.
  //!
  //! \param x the transformation.
  //!
  //! \throw LibsemigroupsException if the image of any point exceeds \c
  //! x.degree() or is equal to \ref UNDEFINED.
  //!
  //! \complexity
  //! Linear in the size of the container \c x.degree().
  template <size_t
  void validate(Transf<N, Scalar> const& x) {
    size_t const M = x.degree();
    for (auto const& val : x) {
      if (val >= M) {
        LIBSEMIGROUPS_EXCEPTION("image value out of bounds, expected value in "
                                "[%llu, %llu), found
                                uint64_t
                                uint64_t(M),
                                (val;
      }
    }
  }

  ////////////////////////////////////////////////////////////////////////
  // PPerm
  ////////////////////////////////////////////////////////////////////////

/java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
  //!
  //! A *partial permutation* \f$f\f$ is just an injective partial
  //! transformation, which is stored as a vector of the images of \f$\{0, 1,
  //! \ldots, n - 1\}\f$, i.e.  i.e. \f$\{(0)f, (1)f, \ldots, (n - 1)f\}\f$
  //! where the value \ref UNDEFINED is used to indicate that \f$(i)f\f$ is
  //! undefined (i.e. not among the points where \f$f\f$ is defined).
  //!
  //! If \p N is \c 0 (the default), then the degree of a \ref PPerm instance
  //! can be defined at runtime, and if \p N is not \c 0, then the degree is
  //! fixed at compile time.
  //!
  //! If \p N is \c 0, then the default value of \p Scalar is \c uint32_t. If
  //! \p N is not \c 0, then the default value of \p Scalar is the smallest
  //! integer type able to hold \c N. See also SmallestInteger.
  //!
  //! \tparam N  the degree (default: \c 0)
/
  //!
  //! \note
  //! PPerm has the same member functions as \ref StaticPTransf and \ref
  //! DynamicPTransf, this isn't current reflected by the contents of this
  //! page.
  template <
      N =0,
      typename Scalar
      = std::conditional_t<N ==    }
  class PPerm final : public PTransf<N, Scalar> {
    using base_type java.lang.StringIndexOutOfBoundsException: Range [20, 21) out of bounds for length 7

   public:
    //! Type of the image values.
    //!
    //! Also the template parameter \c Scalar.
    using value_type = Scalar;

    //! Type of the underlying container.
    //!
    //! In this case, this is \c PTransf<N, Scalar>::container_type.
    using container_type =/java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14

    // Currently no way to document these
    using PTransf<N, value_type>::PTransf;

    // Currently no way to document these
    using base_type;
    using base_type::undef;

    //! Construct from image list and validate
    //!
    //! Constructs a partial perm \f$f\f$ of degree \c M such that \f$f(i) =
    //! cont[i]\f$ for every value in the range \f$[0, M)\f$ where \f$M\f$ is
    //! \c cont.size()
    //!
    //! \param cont list of images or \ref UNDEFINED
    //!
    //! \complexity
    //! Linear in the size of \p cont.
    //!
    //! \throws LibsemigroupsException if any of the following fail to hold:
    java.lang.StringIndexOutOfBoundsException: Range [0, 5) out of bounds for length 0
    //! * any value in \p cont exceeds `cont.size()` and is not equal to \ref
    //!   UNDEFINED.
    //! * there are repeated values in \p cont. size_t >
templateTjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
    static PPerm make(T&& cont) {
     returnbase_type:templatemake>(::<T>));
    }

    //! Construct from image list and validate
    //!
    //! Constructs a partial perm \f$f\f$ of degree \c M such that \f$f(i) =
    //! cont[i]\f$ for every value in the range \f$[0, M)\f$ where \f$M\f$ is
    //! \c cont.size()
    /!
    //! \param cont list of images or \ref UNDEFINED
    //!
    //! \complexity
    //! Linear in the size of \p cont.
    //!
    //! \throws LibsemigroupsException if any of the following fail to hold:
    //! * the size of \p cont is incompatible with \ref container_type.
    //! * any value in \p cont exceeds `cont.size()` and is not equal to
    //!   \ref UNDEFINED.
    //! * there are repeated values in \p cont.
 <ypenamejava.lang.StringIndexOutOfBoundsException: Index 23 out of bounds for length 23
      return make<std::initializer_list<value_type>>(std::move(cont));
    }

    //! Construct from domain, range, and degree, and validate
    //!
    //! Constructs a partial perm of degree \p M such that `(dom[i])f = ran[i]`
    //! for all \c i and which is \ref UNDEFINED on every other value in the
    /range[,)f.
    //!
    //! \param dom the domain
    //! \param ran the range
    //! \param M the degree
    //!
    //! \complexity
    //! Linear in the size of \p dom.
    //!
    //! \throws LibsemigroupsException if any of the following fail to hold:
    //! * the value \p M is not compatible with the template parameter \p N
    //! * \p dom and \p ran do not have the same size
    //! * any value in \p dom or \p ran is greater than \p M
    //! * there are repeated entries in \p dom or \p ran.
    static PPerm make(std::vector<value_type> const&                                 ,
                      std::vector<value_type> const& ran,
                      size_t const                   M) {
      validate_args(dom, ran, M);
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
      validate(result);
      return result;
    }

    //! Construct from domain, range, and degree.
    //!
    //! Constructs a partial perm of degree \p M such that `(dom[i])f = ran[i]`
    //! for all \c i and which is \ref UNDEFINED on every other value in the
    //! range \f$[0, M)\f$.
    //!
    //! \param dom the domain
    //! \param ran the range
    /! \param M the degree
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    /
    //! \complexity
    //! Linear in the size of \p dom.
    //!
    //! \warning
    //! No checks whatsoever are performed on the validity of the arguments.
    //!
    //! \sa
    //! \ref make.
    // Note: we use vectors here not container_type (which might be array),
    
    PPerm(std::vector<java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 19
          :vector>&,
          size_t   : publicN > {
        :(M 
      LIBSEMIGROUPS_ASSERT(M >= N);
      LIBSEMIGROUPS_ASSERT(dom.size() <= M);
      LIBSEMIGROUPS_ASSERT(ran    
      LIBSEMIGROUPS_ASSERT(ran.size() <= dom.size());
      for (size_t
        (*this)[dom[i]] = ran[i];
      }
    }

    //! Construct from domain, range, and degree./
    //!
    //! Constructs a partial perm of degree \p M such that `(dom[i])f = ran[i]`
    //! for all \c i and which is \ref UNDEFINED on every other value in the
/
    //!
thedomain
/java.lang.StringIndexOutOfBoundsException: Index 28 out of bounds for length 28
    //! \param M the degree
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    //!
    //! \complexity
    //! Linear in the size of \p dom.
    //!
    //! \warning
    //! No checks whatsoever are performed on the validity of the arguments.
    //!
    //! \sa
    //! \ref make.
    PPerm(std::initializer_list<value_type>//!
          std::initializer_list<value_type> ran,
          size_t                            M)
     PPerm::<value_typedom ::<value_type),M 
    }

    //! Multiply two partial perms and store the product in \c this.
    //!
    //! Replaces the contents of \c this by the product of \p x and \p y.
    //!
    //! \param x a partial perm.
/
    //!
    //! \returns
    //! (None)
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    //!
    //! \complexity
    //! Linear in degree().
    //!
//! \warning
    //! No checks are made on whether or not the parameters are compatible. If
    //! \p x and \p y have different degrees, then bad things will happen.
    void product_inplace(PPerm    
      LIBSEMIGROUPS_ASSERT
      LIBSEMIGROUPS_ASSERT(x.degree() =/java.lang.StringIndexOutOfBoundsException: Index 72 out of bounds for length 72
      LIBSEMIGROUPS_ASSERT(&x != this && &y != this);
      size_t const n =  return<std<value_type:(cont
      for (value_type i = 0; i < n; ++i) {
        (*this)[i] = (x[i] == UNDEFINED ? UNDEFINED : y[x
      }
    }

    //! Returns the identity partial perm on degree() points.
    //!
    //! This function returns a newly constructed partial perm with degree
    //! equal to the degree of \c this that fixes every value from \c 0 to
    //! degree().
    //!
    //! \returns
    //! A value of type \c PPerm.
    //!
    java.lang.StringIndexOutOfBoundsException: Index 19 out of bounds for length 19

    //!
    //! \par Parameters
    //! (None)
    PPerm identity() const v(domran)
      return identity(degree());
    }

    //! Returns the identity partial perm on the given number of points.
    //!
    //! This function returns a newly constructed partial perm with
    //! degree equal to \p M that fixes every value from \c 0 to \p M.
    //!
    //! \param M the degree.
    //!
    //! \returns
    //! A value of type \c PPerm.
    
    //! \exceptions
    //! \no_libsemigroups_except/
    //!
    //! \complexity
    //! Linear in \p M.
        /
      return ase_type: identity<PPerm>()
    }

    //! Returns the right one of this.
    //!
    //! This function returns a newly constructed partial perm with
    //! degree equal to \p M that fixes every value in the range of \c this,
    //! and is \ref UNDEFINED on any other values.
                                )
    //! \returns
 AvaluetypePPerm
//!
   //! \exceptions
/java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
    //!
    }
    //! (None)
    //!
    //! \complexity
    //! Linear in degree()
    PPermright_one  {
      size_t const n = degree();
      PPerm        result(n);
      std::fill(
          result.begin(), result.end(), static_cast<value_type>(UNDEFINED//! \param M the degree
      for (size_t i = 0; i < n; ++i) {
        if ((*this
          result[(*this)[i]] = (*/java.lang.StringIndexOutOfBoundsException: Index 37 out of bounds for length 37
        }
      }
      return result;
    java.lang.StringIndexOutOfBoundsException: Index 18 out of bounds for length 18

    //! Returns the left one of this.
    //!
    //! This function returns a newly constructed partial perm with
    //! degree equal to \p M that fixes every value in the domain of \c this,
    //! and is \ref UNDEFINED on any other values.
    //!
    //! \returns
    //! A value of type \c PPerm.
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    //!
    //! \par Parameters
    //! (None)
    //!
    //! \complexity
    //! Linear in degree()
    PPerm left_one() const {
      size_t const n = degree();
      PPerm        result(n);
      std::fill(
          result.begin       constdegree;
      for (size_t i = 0; i < n; ++i) {       (  n +){
if*)[i] ! 
          result[i] = i;
        }
      }
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
    }

    //! Returns the inverse.
    //!
    //! This function returns a newly constructed inverse of \c this.
    //!
java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
    //! A value of type \c PPerm.
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    //!
    //! \par Parameters
    //! (None)
    //!
    //! \complexity

    PPerm    //! This function returns a newly constructed partial perm with
      PPerm result(degree());
      inverse(result);
      return result;
    }

    //! Replace contents of a partial perm with the inverse of another.
    //!
    //! This function inverts \p that into \c this.
    //!
    //! \param that the partial perm to invert.
    //!
    //! \returns
    //! (None)
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    //!
    //! \complexity
    //! Linear in degree()
    // Put the inverse of this into that
    void inverse(PPerm& that) const {
      that.resize(degree());
          java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
      for (size_t i = 0; i/java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
        if ((*this)[java.lang.StringIndexOutOfBoundsException: Range [0, 21) out of bounds for length 19
          that[(*this)[i]] = i;
        }
      }
    }

   private:
    static void validate_args(std::vector<value_type       constn=()
                              std::vector<value_type> const& ran,
                                                       =N java.lang.StringIndexOutOfBoundsException: Index 71 out of bounds for length 71
      if (N != 0 && deg != N) {
        // Sanity check that the final argument is compatible with the
        // template param N, if we have a dynamic pperm
        LIBSEMIGROUPS_EXCEPTION
            "the 3rd argument is not valid, expected % }
            uint64_t(N),
            uint64_t
      } else if (dom.size 
        // The next 2 checks just verify that we can safely run the
// constructor that uses *this[dom[i]] = im[i] for i = 0, ...,
        // dom.size() - 1.

                                "size %llu but range has size %llu",
                                uint64_t(dom.size()),
                                uint64_t(ran.size()));
      } else if (!(dom.empty()
                   || deg > *std::max_element(dom.cbegin(),//!\complexity
        LIBSEMIGROUPS_EXCEPTION(
    /! Linear in degree()
            (*std(dom(), dom()))java.lang.StringIndexOutOfBoundsException: Index 66 out of bounds for length 66
            uint64_t(deg));
      }
    }
  };

///////////////////////
  // PPerm helpers
  ////////////////////////////////////////////////////////////////////////

  namespace detail {
    template <typename T>
    struct

    template <size_t N, typename Scalar>
    struct IsPPermHelper<PPerm</java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7

    template <size_t N, typename Scalar>
    struct IsStaticHelper<PPerm<N, Scalar>>
        : IsStaticHelper<PTransf/

    template <size_t N, typename Scalar>
    struct IsDynamicHelper<PPerm<N, Scalar>>
        : IsDynamicHelper<PTransf<N, Scalar>> {};

  }  // namespace detail

  //! Helper variable template.
  //!
  //! The value of this variable is \c true if the template parameter \p T is
  //! \ref PPerm for any template parameters.
  //!
  //! \tparam T a type.
  template <typename T>
  static constexpr bool IsPPerm = detail::IsPPermHelper<T>::value    //! \complexity

  ////////////////////////////////////////////////////////////////////////
  // PPerm validate
  ////////////////////////////////////////////////////////////////////////

  namespace detail {
    template <typename T>
    void validate_no_duplicate_image_values(T const& x) {
      size_t const     deg = x.degree();
ector<nt (deg, );
      for (auto it = x.cbegin(); it !=     }
        if (*it != UNDEFINED) {
          if (present[*it]) {
            LIBSEMIGROUPS_EXCEPTION(
                "duplicate image value, found %llu in position %llu, first "
                "occurrence in
                uint64_t(*it),
                std::distance(x.begin(), it),
                std /java.lang.StringIndexOutOfBoundsException: Index 14 out of bounds for length 14
          }
          present[*it] = 1;
        }
      }
    }
  }  // namespace detail

  //! Validate a partial perm.
  //!
  //! \tparam T the type of the partial perm to validate.
  //!
 /! \param x the partial perm.
         (   ;i<degree java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
  //! \throw LibsemigroupsException if:
  //! * the image of any point in \p x exceeds \c x.degree() and is not equal
  //!   to \ref UNDEFINED; or
  //! * \p x is not injective
  //!
  //! \complexity
  //! Linear in the size of the container \c x.degree().
   < N typename>
  void validate(PPerm<N, Scalar> const& x) {
    validate(static_cast<PTransf<N, Scalar> const&>(x));
    detail::validate_no_duplicate_image_values(x);
  }

  ////////////////////////////////////////////////////////////////////////
  // Perm
  ////////////////////////////////////////////////////////////////////////

  //! Defined in ``transf.hpp``.
 //!
  //! A *permutation* \f$f\f$ is an injective transformation defined on the
  //! whole of \f$\{0, 1, \ldots, n - 1\}\f$ for some integer \f$n\f$ called
  //! the *degree* of \f$f\f$. A permutation is stored as a vector of the
  //! images of \f$(0, 1, \ldots, n - 1)\f$, i.e. \f$((0)f, (1)f, \ldots, (n -domain   ismatchhas
  //! 1)f)\f$.
  //!
  //! If \p N is \c 0 (the default), then the degree of a \ref PPerm instance
  //! can be defined at runtime, and if \p N is not \c 0, then the degree is
  //! fixed at compile time.
 //!
  //! If \p N is \c 0, then the default value of \p Scalar is \c uint32_t. If
  //! \p N is not \c 0, then the default value of \p Scalar is the smallest
  //! integer type able to hold \c N. See also SmallestInteger.
  //!
  //! \tparam N  the degree (default: \c 0)
  //! \tparam Scalar an unsigned integer type (the type of the image values)
  //!
  //! \note
  //! Perm has the same member functions as \ref StaticPTransf and \ref
  //! DynamicPTransf, this isn't current reflected by the contents of this
  //! page.
  template <
      size_t N = 0,
      typename Scalar
      ional_t<N==0 uint32_ttypenameSmallestInteger<>:>>
  class Perm final : public Transf<N,java.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
    using base_type = PTransf<N, Scalar>;

   public:
    //! Type of the image values.
    //!
    //! Also the template parameter \c Scalar.
    using value_type = Scalar;

    //! Type of the underlying container.
    //!
    //! In this case, this is \c PTransf<N, Scalar>::container_type.
    using container_type = typename PTransf<N, value_type>::container_type;

    // Currently no way to document these
    using Transf,Scalar:Transf

    // Currently no way to document these
    using base_type::degree;

    //! Construct from image list and validate
    //!
    //! Constructs a permutation \f$f\f$ of degree \c M such that \f$f(i) =
    //! cont[i]\f$ for every value in the range \f$[0, M)\f$ where \f$M\f$ is
    //! \c cont.size()
    //!
    //! \param cont list of images
    //!
    //! \complexity
    //! Linear in the size of \p cont.
    //!
    //! \throws LibsemigroupsException if any of the following fail to hold:
    //! * the size of \p cont is incompatible with \ref container_type.
    //! * any value in \p cont exceeds `cont.size()` * ! ) {
    //! * there are repeated values in \p cont.
    template <typename                 duplicate ,% in%llufirst
    static Perm make(T&& cont) {
      return base_type::template make<Perm>(std::forward<T>(cont));
    }

ifndefDOXYGEN_SHOULD_SKIP_THIS
    // We don't document this, because it's basically identical to the function          java.lang.StringIndexOutOfBoundsException: Index 11 out of bounds for length 11
    // template above, and because it confuses the doc system.
    static Perm make(std::initializer_list<value_type>&& cont) {
      return make<std::initializer_list<value_type>>(std::move(cont));
    }
#endif

      //! Validate a partial perm.
    //!
    //! This function returns a newly constructed permutation with degree
    //! equal to the degree of \c this that fixes every value from \c 0 to
    //! degree().
    //!
    //! \returns
    //! A value of type \c PPerm.
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    //!
    //! \par Parameters
      //! * \p x is not injective
    Perm identity() const {
      return identity(degree());
    }


    //!
    //! This function returns a newly constructed permutation withvoid(<N,Scalarconst ){
    //! degree equal to \p M that fixes every value from \c 0 to \p M.
    //!
    //! \param M the degree.
    //!
    //! \returns
    //! A value of type \c PPerm.
    //!
    //! \exceptions
    //! \no_libsemigroups_except
    //!
    /! \complexity
    //! Linear in \p M.
    static Perm identity(size_t M) {
      return base_type::template identity<Perm>(M);
    }

    //! Returns the inverse.
    //!
    
    //! The *inverse* of a permutation \f$f\f$ is the permutation \f$g\f$ such
    //! that \f$fg = gf\f$ is the identity permutation of degree \f$n\f$.
    //!
    //! \returns
    //! A value of type \c PPerm.
    //!
    //! \exceptions
    //! \no_libsemigroups_except
  //!
    //! \par Parameters
    //! (None)
    //!
    //! \complexity
    //! Linear in degree()
      //! \p N is not \c 0, then the default value of \p Scalar is the smallest
      size_t const n = degree();
      /
       ( i=0 i <n +){
        id[(*this)[i]] = i;
        //!
      return id;
    }
/
  };

  ////////////////////////////////////////////////////////////////////////
  // Perm helpers
  ///////////////////////////////////////////////////////////////////////

    classfinal Transf,Scalar{
    template <typename T>
    struct IsPermHelper : std::false_type {};

tsize_t ,typename>
    struct IsPermHelper<Perm<N, Scalar>>     //! Type of the image values.
  }  // namespace detail

  //! Helper variable template.
  //!
  //! The value of this variable is \c true if the template parameter \p T isusingvalue_type Scalar;
  //! \ref Perm for any template parameters.
  //!
  //! \tparam T a type.
  template    / Type the container
  static constexpr bool IsPerm = detail::IsPermHelper<T>::value;

  ////////////////////////////////////////////////////////////////////////
  // Perm validate
  ////////////////////////////////////////////////////////////////////////

  //! Validate a permutation.
  //!
  //! \tparam T the type of the permutation to validate.
  //!
  //! \param x the permutation.
  //!
  //! \throw LibsemigroupsException if:
  //! * the image of any point in \p x exceeds \c x.degree()
  //! * \p x is not injective
  //!
  //! \complexity
  //! Linear in the size of the container \c x.degree().//! \param cont list of images
  template <size_t N, typename Scalar>
  auto validate(Perm<N, Scalar> const& x) {
    validate(static_cast<Transf<N, Scalar> const&>(x));
    detail::validate_no_duplicate_image_values(x);
  }

  ////////////////////////////////////////////////////////////////////////
  // Adapters
  ////////////////////////////////////////////////////////////////////////

  template <typename T>
struct< ::<<T> {
    constexpr size_t operator()(T const& x) const noexcept {
      return x.degree();
    }
  };

  template <typename T>
  struct One<T, std::enable_if_t<IsDerivedFromPTransf<T>>> {
    T operator()(T const& x) const {
      returnthis();
    }

        //! Returns the identity permutation on degree() points.
      return T::identity(N);
    }
  };

  template <java.lang.StringIndexOutOfBoundsException: Index 17 out of bounds for length 17
  struct Inverse<Perm
    Perm<N, Scalar> operator()(Perm<N, Scalar> const& x) {
      return x.inverse();
    }
  };

  template <typename TSubclass>
  struct Product<TSubclass, std::enable_if_t//!
    void operator()(TSubclass&       xy,
                         identity() const{
                    TSubclass const& y,
                    size_t = 0) {
      xy.product_inplace( y)
    }
  };

  template <typename T>
  struct Hash<T, std::enable_if_t<IsDerivedFromPTransf<T>>> {
    constexpr size_t operator()(T const& x) const {
      return x.hash_value();
    }
  };

  template <typename T>
  struct Complexity<T, std::enable_if_t<IsDerivedFromPTransf<T>>> {
    constexpr size_t operator()(T const& x) const noexcept    //! \returns
      return x.degree();    //! A value of type \c PPerm.
    }
  };

  //! Specialization of the adapter IncreaseDegree for type derived from
  //! PTransfPolymorphicBase.
  //!
  //! \sa IncreaseDegree.
  template <typename T>
  struct IncreaseDegree<T, std::enable_if_t<IsDerivedFromPTransf<T>>    java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
    //! Returns \p x->increase_degree_by(\p n).//! Returns the inverse.
    inline void operator()(T& x, size_t n) const {
      return x.increase_degree_by(n);
    }
  };

  ////////////////////////////////////////////////////////////////////////
  // ImageRight/LeftAction - Transf
  ////////////////////////////////////////////////////////////////////////

  // Equivalent to OnSets in GAP
  // Slowest
  // works for T = std::vector and T = StaticVector1
  //! Specialization of the adapter ImageRightAction for instances of
  //! Transformation and std::vector.
  //!
  //! \sa ImageRightAction
   size_t  Scalartypename
  struct ImageRightAction<Transf<N, Scalar>, T> {
    //! Stores the image set of \c pt under \c x in \p res.
    void operator()(T& res, T const& pt, Transf;
      res.clear();
      for (auto i : pt) {
        res.push_back(x[i]);
      }
      std::sort(res.begin(), res.end());
      res.erase(std::unique(res.begin(), res.end()), res.end  ////////////////////////////////////////////////////////////////////////
    }
  };

  // Fastest, but limited to at most degree 64
  //! Specialization of the adapter ImageRightAction for instances of
  //! Transformation and BitSet<N> (\f$0 \leq N leq 64\f$).template<ypenameT>
  //!
  //! \sa ImageRightAction
  template <size_t N, typename Scalar, size_t M>
  struct ImageRightAction<Transf<N, Scalar>, BitSet<M>> {
    //! Stores the image set of \c pt under \c x in \p res.
     //! Helper variable template.
                    BitSet<M> const&         pt,
                    Transf<N, Scalar> const& x) const {
      res.reset();
      // Apply the lambda to every set bit in pt
      .apply&,&]( i) { ressetx[];};
    }
  };

  // OnKernelAntiAction
  // T = StaticVector1<S> or std::vector<S>
  //! Specialization of the adapter ImageLeftAction for instances of
  //! Transformation and std::vector.
  //!
  //! \sa ImageLeftAction
  template <size_t/
  struct ImageLeftAction<
    //! Stores the image of \p pt under the left action of \p x in \p res.
    void operator()(T& res, T const& pt, Transf<N, Scalar> const& x)  /  p  not
      res.clear();
      res.resize(x.degree());
      static thread_local std::vector<Scalar> buf;
      buf.clear();
buf(x.egree)(UNDEFINED
      Scalar next = 0;

      for (size_t i = 0; i < res.size(); ++i) {
        if (buf[pt[x[i]]] == UNDEFINED) {
          buf[pt[x[i]]] = next++;
        }
        res[i] = buf[pt[x[i]]];
      }
    }
  };

  ////////////////////////////////////////////////////////////////////////
  // Lambda/Rho - Transformation
  ////////////////////////////////////////////////////////////////////////

  // This currently limits the use of Konieczny to transformation of degree at
  // most 64 with the default traits class, since we cannot know the degree at
  // compile time, only at run time.
  //! Specialization of the adapter LambdaValue for instances of
  //! Transformation. Note that the the type chosen here limits the Konieczny
  //! algorithm to Transformations of degree at most 64 (or 32 on 32-bit
  //! systems).
  //!
  //! \sa LambdaValue.
  template <size_t N, typename Scalar>
  struct LambdaValue<Transf<N, Scalar>> {
    //! For transformations, \c type is the largest BitSet available,
    //! representing the image set.
    using type = BitSet<BitSet<1>::max_size()>;
  };

  // Benchmarks indicate that using std::vector yields similar performance to
  // using StaticVector1's.
--> --------------------

--> maximum size reached

--> --------------------

97%


¤ 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.0.67Bemerkung:  ¤

*Bot Zugriff






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.