//
// libsemigroups - C++ library for semigroups and monoids
// Copyright (C) 2019 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 class TCE, which is a
// wrapper around congruence::ToddCoxeter class indices, that can be used as
// the template parameter TElementType for the FroidurePin class template.
// This file also contains specializations of the adapters complexity, degree,
// less, one, product, and std::hash for TCE.
#ifndef LIBSEMIGROUPS_TCE_HPP_
#define LIBSEMIGROUPS_TCE_HPP_
#include <cstddef> // for size_t
#include <sstream> // for ostream, ostringstream
#include <type_traits> // for integral_constant
#include <utility> // for hash
#include "adapters.hpp" // for Complexity, Degree, Less, One, Product, ...
#include "constants.hpp" // for LIMIT_MAX
#include "string.hpp" // for to_string
#include "todd-coxeter.hpp" // for ToddCoxeter
namespace libsemigroups {
// Forward declarations
namespace congruence {
class ToddCoxeter;
} // namespace congruence
namespace detail {
class TCE {
using ToddCoxeter = congruence::ToddCoxeter;
public:
using coset_type = typename ToddCoxeter::coset_type;
using Table = typename ToddCoxeter::table_type;
TCE() noexcept = default;
TCE(TCE const&) noexcept = default;
TCE(TCE&&) noexcept = default;
TCE& operator=(TCE const&) noexcept = default;
TCE& operator=(TCE&&) noexcept = default;
~TCE() = default;
explicit TCE(coset_type i) noexcept : _index(i) {}
bool operator==(TCE const& that) const noexcept {
return _index == that._index;
}
bool operator<(TCE const& that) const noexcept {
return _index < that._index;
}
TCE one() const noexcept {
return TCE( 0);
}
operator coset_type() const {
return _index;
}
private:
// Note that the value of the class_index_type _value below is the actual
// class_index_type used in the ToddCoxeter class and not that number
// minus 1, which is what "class_index" means in the context of
// CongruenceInterface objects.
coset_type _index;
};
// The following are not really required but are here as a reminder that
// KBE are used in BruidhinnTraits which depends on the values in the
// static_asserts below.
static_assert(std::is_trivial<TCE>::value, "TCE is not trivial!!!");
static_assert(std::integral_constant< bool, ( sizeof(TCE) <= 8)>::value,
"TCE's sizeof exceeds 8!!");
} // namespace detail
//! No doc
inline std::ostringstream& operator<<(std::ostringstream& os,
detail::TCE const& x) {
os << "TCE(" << detail::TCE::coset_type(x) << ")";
return os;
}
//! No doc
inline std::ostream& operator<<(std::ostream& os, detail::TCE const& x) {
os << detail::to_string(x);
return os;
}
// Specialization of the adapter libsemigroups::Complexity for detail::TCE.
template <>
struct Complexity<detail::TCE> {
// Returns LIMIT_MAX, because it is not possible to multiply arbitrary TCE
// instances, only arbitrary TCE by a TCE representing a generator (see
// TCE::operator*). This adapter is used by the FroidurePin class to
// determine if it is better to trace paths in the Cayley graph or to
// directly multiply elements (using the \c * operator). Since LIMIT_MAX is
// returned, elements are not directly multiplied by the \c * operator
// (except if the right hand argument represents a TCE).
constexpr size_t operator()(detail::TCE const&) const noexcept {
return LIMIT_MAX;
}
};
template <>
struct Degree<detail::TCE> {
constexpr size_t operator()(detail::TCE const&) const noexcept {
return 0;
}
};
template <>
struct IncreaseDegree<detail::TCE> {
void operator()(detail::TCE const&, size_t) const noexcept {}
};
//! Specialization of the adapter libsemigroups::One for TCE.
template <>
struct One<detail::TCE> {
//! This directly uses the member function TCE::one.
detail::TCE operator()(detail::TCE const& x) const noexcept {
return x.one();
}
};
template <>
struct Product<detail::TCE> {
void operator()(detail::TCE& xy,
detail::TCE const& x,
detail::TCE const& y,
detail::TCE::Table* t,
size_t = 0) const {
xy = detail::TCE(t->get(x, y - 1));
}
};
} // namespace libsemigroups
namespace std {
template <>
struct hash<libsemigroups::detail::TCE> {
using coset_type = libsemigroups::detail::TCE::coset_type;
size_t operator()(libsemigroups::detail::TCE const& x) const noexcept {
return std::hash<coset_type>()(x);
}
};
} // namespace std
#endif // LIBSEMIGROUPS_TCE_HPP_
¤ Dauer der Verarbeitung: 0.2 Sekunden
¤
*© Formatika GbR, Deutschland
|
|