39#ifndef LIBSEMIGROUPS_SCHREIER_SIMS_HPP_
40#define LIBSEMIGROUPS_SCHREIER_SIMS_HPP_
51#include <unordered_set>
53#include "adapters.hpp"
56#include "exception.hpp"
60#include "detail/bruidhinn-traits.hpp"
61#include "detail/containers.hpp"
62#include "detail/fmt.hpp"
63#include "detail/int-range.hpp"
64#include "detail/stl.hpp"
99 template <
size_t N,
typename Po
int,
typename Element>
178 static_assert(std::is_same_v<Point, typename Traits::point_type>,
179 "incompatible point types, Traits::point_type and Point "
182 std::is_same_v<Element, typename Traits::element_type>,
183 "incompatible element types, Traits::element_type and Element "
185 static_assert(N <= std::numeric_limits<Point>::max(),
186 "the first template parameter N cannot be expressed as value "
187 "of type equal to the second template parameter Point");
189 using internal_element_type =
190 typename detail::BruidhinnTraits<Element>::internal_value_type;
191 using internal_reference =
192 typename detail::BruidhinnTraits<Element>::internal_reference;
193 using internal_const_element_type =
194 typename detail::BruidhinnTraits<Element>::internal_const_value_type;
202 using element_type =
typename detail::BruidhinnTraits<Element>::value_type;
209 typename detail::BruidhinnTraits<Element>::const_reference;
215 typename detail::BruidhinnTraits<Element>::reference;
247 using One =
typename Traits::One;
253 using Swap =
typename Traits::Swap;
255 static_assert(detail::has_call_operator_size_t_v<One>,
256 "Traits::One must implement operator()(size_t)!");
264 internal_element_type _one;
265 detail::StaticTriVector2<point_type, N> _orbits;
266 detail::Array2<bool, N> _orbits_lookup;
267 detail::StaticTriVector2<internal_element_type, N> _strong_gens;
268 mutable internal_element_type _tmp_element1;
269 mutable internal_element_type _tmp_element2;
270 detail::Array2<internal_element_type, N> _transversal;
271 detail::Array2<internal_element_type, N> _inversal;
431 throw_if_bad_depth(depth);
456 return _strong_gens.size(depth);
501 return this->to_external_const(_strong_gens.at(depth, index));
527 return this->to_external_const(_transversal[depth][pt]);
575 return this->to_external_const(_inversal[depth][pt]);
622 return _orbits_lookup[depth][pt];
642 throw_if_bad_depth(depth);
643 throw_if_point_gt_degree(pt);
661 return _strong_gens.size(0) == 0;
700 internal_sift(this->to_internal(x));
715 throw_if_bad_degree(x);
732 this->to_external(_tmp_element2) = x;
734 internal_sift(_tmp_element2);
735 return this->to_external_const(_tmp_element2);
752 throw_if_bad_degree(x);
801 noexcept(noexcept(this->to_external_const(_one))) {
802 return this->to_external_const(_one);
873 throw_if_bad_depth(index);
912 bool is_valid_degree(
point_type x)
const noexcept {
914#ifdef LIBSEMIGROUPS_HPCOMBI_ENABLED
915 std::is_same_v<HPCombi::Perm16, element_type> ||
921 std::string_view arg_pos =
"1st")
const;
923 void throw_if_bad_depth(
size_t depth,
924 std::string_view arg_pos =
"1st")
const;
927 std::string_view arg_pos =
"1st")
const;
929 void throw_if_point_not_in_orbit(
index_type depth,
931 std::string_view depth_arg_pos =
"1st",
932 std::string_view pt_arg_pos =
"2nd")
const;
938 bool internal_equal_to(internal_const_element_type x,
939 internal_const_element_type y)
const
941 EqualTo()(this->to_external_const(x),
942 this->to_external_const(
943 y)) &&
noexcept(this->to_external_const(x)))) {
944 return EqualTo()(this->to_external_const(x), this->to_external_const(y));
948 void init_strong_gens_traversal_inversal(
SchreierSims const& that);
949 void free_strong_gens_traversal_inversal();
953 void orbit_add_gen(
index_type depth, internal_element_type gen);
955 internal_element_type x,
959 index_type internal_sift(internal_reference x)
const;
961 typename domain_type::const_iterator
962 first_non_fixed_point(internal_const_element_type x)
const {
963 auto const& y = this->to_external_const(x);
964 return std::find_if(_domain.cbegin(), _domain.cend(), [&y](
auto pt) {
965 return pt != Action()(pt, y);
1000 template <
size_t N,
typename Po
int,
typename Element,
typename Traits>
1019 template <
size_t N,
typename Po
int,
typename Element,
typename Traits>
1022 size_t max_width = 72);
1025#include "schreier-sims.tpp"
A deterministic version of the Schreier-Sims algorithm acting on a small number of points.
Definition schreier-sims.hpp:177
SchreierSims(SchreierSims &&)
Default move constructor.
const_element_reference strong_generator_no_checks(index_type depth, index_type index) const
Get a strong generator.
Definition schreier-sims.hpp:500
bool orbit_lookup(index_type depth, point_type pt) const
Check if a point is in the orbit of a basepoint.
Definition schreier-sims.hpp:641
bool currently_contains(const_element_reference x) const
Test membership of an element without running.
void run()
Run the Schreier-Sims algorithm.
const_element_reference generator(index_type index) const
Get a generator.
Definition schreier-sims.hpp:377
const_element_reference sift(const_element_reference x) const
Sift an element through the stabiliser chain.
Definition schreier-sims.hpp:751
const_element_reference transversal_element_no_checks(index_type depth, point_type pt) const
Get a transversal element.
Definition schreier-sims.hpp:526
typename Traits::EqualTo EqualTo
Adapter for testing equality.
Definition schreier-sims.hpp:241
void sift_inplace(element_reference x) const
Sift an element through the stabiliser chain in-place.
Definition schreier-sims.hpp:714
size_t base_size() const noexcept
Get the size of the current base.
Definition schreier-sims.hpp:889
size_t number_of_strong_generators_no_checks(index_type depth) const
The number of strong generators at a given depth.
Definition schreier-sims.hpp:455
size_t number_of_strong_generators(index_type depth) const
The number of strong generators at a given depth.
Definition schreier-sims.hpp:430
typename detail::BruidhinnTraits< Element >::reference element_reference
Type of a reference to the elements.
Definition schreier-sims.hpp:214
bool finished() const noexcept
Check if the stabiliser chain is fully enumerated.
Definition schreier-sims.hpp:818
typename Traits::One One
Adapter for the identity element of the given type.
Definition schreier-sims.hpp:247
point_type base(index_type index) const
Get a base point.
Definition schreier-sims.hpp:872
const_element_reference generator_no_checks(index_type index) const
Get a generator.
Definition schreier-sims.hpp:397
typename Traits::Degree Degree
Adapter for the degree of an element.
Definition schreier-sims.hpp:238
typename detail::BruidhinnTraits< Element >::value_type element_type
Type of the elements.
Definition schreier-sims.hpp:202
void sift_inplace_no_checks(element_reference x) const
Sift an element through the stabiliser chain in-place.
Definition schreier-sims.hpp:698
typename Traits::index_type index_type
Type of indices.
Definition schreier-sims.hpp:230
uint64_t size()
Returns the size of the group represented by this.
typename Traits::Inverse Inverse
Adapter for the inverse of an element.
Definition schreier-sims.hpp:244
bool empty() const
Check if any generators have been added so far.
Definition schreier-sims.hpp:660
const_element_reference inverse_transversal_element_no_checks(index_type depth, point_type pt) const
Get an inverse of a transversal element.
Definition schreier-sims.hpp:573
typename Traits::Action Action
Alias for Traits::Action.
Definition schreier-sims.hpp:235
const_element_reference transversal_element(index_type depth, point_type pt) const
Get a transversal element.
const_element_reference sift_no_checks(const_element_reference x) const
Sift an element through the stabiliser chain.
Definition schreier-sims.hpp:731
Point point_type
Type of the points acted on.
Definition schreier-sims.hpp:220
SchreierSims()
Default constructor.
bool add_generator(const_element_reference x)
Add a generator.
const_element_reference one() const noexcept(noexcept(this->to_external_const(_one)))
Returns a const reference to the identity.
Definition schreier-sims.hpp:800
typename Traits::domain_type domain_type
Type of the object containing all points acted on.
Definition schreier-sims.hpp:225
bool add_generator_no_checks(const_element_reference x)
Add a generator.
point_type base_no_checks(index_type index) const
Get a base point.
Definition schreier-sims.hpp:855
SchreierSims & add_base_point(point_type pt)
Add a base point to the stabiliser chain.
typename Traits::Swap Swap
Adapter for swapping.
Definition schreier-sims.hpp:253
size_t number_of_generators() const
The number of generators.
bool orbit_lookup_no_checks(index_type depth, point_type pt) const
Check if a point is in the orbit of a basepoint.
Definition schreier-sims.hpp:620
typename Traits::Product Product
Adapter for the product of two elements.
Definition schreier-sims.hpp:250
bool contains(const_element_reference x)
Test membership of an element.
uint64_t current_size() const
Returns the size of the group represented by this, without running.
SchreierSims & init()
Reset to the trivial group.
typename detail::BruidhinnTraits< Element >::const_reference const_element_reference
Type of a const reference to the elements.
Definition schreier-sims.hpp:208
SchreierSims & operator=(SchreierSims const &that)
Default copy assignment.
const_element_reference strong_generator(index_type depth, index_type index) const
Get a strong generator.
SchreierSims(SchreierSims const &that)
Default copy constructor.
const_element_reference inverse_transversal_element(index_type depth, point_type pt) const
Get an inverse of a transversal element.
SchreierSims & operator=(SchreierSims &&)
Default move assignment.
std::string to_human_readable_repr(Action< Element, Point, Func, Traits, LeftOrRight > const &action)
Return a human readable representation of an Action object.
typename detail::LeastPermHelper< N >::type LeastPerm
Type of perms using the least memory for a given degree.
Definition transf.hpp:2413
Namespace for SchreierSims helper functions.
Definition schreier-sims.hpp:974
void intersection(SchreierSims< N, Point, Element, Traits > &T, SchreierSims< N, Point, Element, Traits > &S1, SchreierSims< N, Point, Element, Traits > &S2)
Find the intersection of two permutation groups.
Namespace for everything in the libsemigroups library.
Definition action.hpp:44
Adapter for the degree of an element.
Definition adapters.hpp:166
Adapter for testing equality.
Definition adapters.hpp:418
Adapter for the value of a right action.
Definition adapters.hpp:397
Adapter for the inverse of an element.
Definition adapters.hpp:324
Adapter for the identity element of the given type.
Definition adapters.hpp:251
Adapter for the product of two elements.
Definition adapters.hpp:289
Traits class for use with the class template SchreierSims.
Definition schreier-sims.hpp:100
libsemigroups::Swap< element_type > Swap
Adapter for swapping.
Definition schreier-sims.hpp:141
detail::IntRange< Point > domain_type
Type of the object containing all points acted on.
Definition schreier-sims.hpp:109
libsemigroups::One< element_type > One
Adapter for the identity element of the given type.
Definition schreier-sims.hpp:135
libsemigroups::ImageRightAction< element_type, Point > Action
Adapter for the value of a right action.
Definition schreier-sims.hpp:123
Element element_type
Type of the elements.
Definition schreier-sims.hpp:120
libsemigroups::Inverse< element_type > Inverse
Adapter for increasing the degree of an element.
Definition schreier-sims.hpp:132
size_t index_type
The type of indices to be used by a SchreierSims instance.
Definition schreier-sims.hpp:104
libsemigroups::EqualTo< element_type > EqualTo
Adapter for testing equality.
Definition schreier-sims.hpp:129
Point point_type
Type of the points acted on.
Definition schreier-sims.hpp:115
libsemigroups::Product< element_type > Product
Adapter for the product of two elements.
Definition schreier-sims.hpp:138
libsemigroups::Degree< element_type > Degree
Adapter for the degree of an element.
Definition schreier-sims.hpp:126
std::conditional_t< N >=0x100000000, uint64_t, std::conditional_t< N >=0x10000, uint32_t, std::conditional_t< N >=0x100, uint16_t, uint8_t > > > type
Definition types.hpp:87
Adapter for swapping.
Definition adapters.hpp:671