libsemigroups  v3.1.2
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
forest.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2019-2025 Finn Smith + James Mitchell
4//
5// This program is free software: you can redistribute it and/or modify
6// it under the terms of the GNU General Public License as published by
7// the Free Software Foundation, either version 3 of the License, or
8// (at your option) any later version.
9//
10// This program is distributed in the hope that it will be useful,
11// but WITHOUT ANY WARRANTY; without even the implied warranty of
12// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13// GNU General Public License for more details.
14//
15// You should have received a copy of the GNU General Public License
16// along with this program. If not, see <http://www.gnu.org/licenses/>.
17//
18
19#ifndef LIBSEMIGROUPS_FOREST_HPP_
20#define LIBSEMIGROUPS_FOREST_HPP_
21
22#include <algorithm> // for fill
23#include <cstddef> // for size_t
24#include <initializer_list> // for initializer_list
25#include <iterator> // for begin, end
26#include <vector> // for vector, allocator, operator==
27
28#include "constants.hpp" // for Undefined, Max, UNDEFINED, operator!=
29#include "debug.hpp" // for LIBSEMIGROUPS_ASSERT
30#include "exception.hpp" // for LIBSEMIGROUPS_EXCEPTION
31#include "types.hpp" // for word_type, enable_if_is_same
32
33namespace libsemigroups {
42 class Forest {
43 std::vector<uint32_t> _edge_label;
45
46 public:
48 using node_type = uint32_t;
49
51 using label_type = uint32_t;
52
59 explicit Forest(size_t n = 0)
60 : _edge_label(n, static_cast<uint32_t>(UNDEFINED)),
61 _parent(n, static_cast<uint32_t>(UNDEFINED)) {}
62
74 Forest& init(size_t n = 0);
75
77 Forest(Forest const&) = default;
78
80 Forest(Forest&&) = default;
81
83 Forest& operator=(Forest const&) = default;
84
86 Forest& operator=(Forest&&) = default;
87
88 ~Forest();
89
98 [[nodiscard]] bool operator==(Forest const& that) const {
99 return _parent == that._parent && _edge_label == that._edge_label;
100 }
101
109 [[nodiscard]] bool operator!=(Forest const& that) const {
110 return !(*this == that);
111 }
112
128 Forest& add_nodes(size_t n);
129
143 [[nodiscard]] bool empty() const noexcept {
144 return _parent.empty();
145 }
146
170 label_type gen) {
171 _parent[node] = parent;
172 _edge_label[node] = gen;
173 return *this;
174 }
175
195 // not noexcept because std::vector::operator[] isn't.
203
216 [[nodiscard]] size_t number_of_nodes() const noexcept {
217 return _parent.size();
218 }
219
235 // not noexcept because std::vector::operator[] isn't.
236 [[nodiscard]] node_type parent(node_type i) const {
238 return _parent[i];
239 }
240
256 [[nodiscard]] node_type parent_no_checks(node_type i) const {
257 return _parent[i];
258 }
259
275 // not noexcept because std::vector::operator[] isn't.
276 [[nodiscard]] label_type label(node_type i) const {
278 return _edge_label[i];
279 }
280
296 [[nodiscard]] label_type label_no_checks(node_type i) const {
297 return _edge_label[i];
298 }
299
314 [[nodiscard]] std::vector<node_type> const& parents() const noexcept {
315 return _parent;
316 }
317
333 [[nodiscard]] std::vector<label_type> const& labels() const noexcept {
334 return _edge_label;
335 }
336
352 template <typename Iterator>
353 Iterator path_to_root_no_checks(Iterator d_first, node_type i) const;
354
370 template <typename Iterator>
371 Iterator path_from_root_no_checks(Iterator d_first, node_type i) const;
372
379
380 private:
381 class const_iterator_path {
382 private:
383 node_type _current_node;
384 Forest const* _forest;
385
386 public:
387 using iterator_category = std::forward_iterator_tag;
388 using value_type = label_type;
389 using difference_type = std::ptrdiff_t;
390 using pointer = label_type*;
391 using reference = label_type&;
392
393 const_iterator_path(Forest const* f, node_type n)
394 : _current_node(n), _forest(f) {}
395
396 const_iterator_path() = delete;
397
398 const_iterator_path(const_iterator_path const& that) = default;
399 const_iterator_path& operator=(const_iterator_path const& that) = default;
400 const_iterator_path(const_iterator_path&& that) noexcept = default;
401 const_iterator_path& operator=(const_iterator_path&& that) noexcept
402 = default;
403
404 ~const_iterator_path() = default;
405
406 [[nodiscard]] value_type operator*() const;
407
408 // pointer operator->() const {
409 // return TODO;
410 // }
411
412 // Pre-increment
413 const_iterator_path& operator++();
414
415 // Post-increment
416 const_iterator_path operator++(int) {
417 const_iterator_path tmp = *this;
418 ++(*this);
419 return tmp;
420 }
421
422 [[nodiscard]] bool operator==(const_iterator_path const& that) const;
423
424 [[nodiscard]] bool operator!=(const_iterator_path const& that) const {
425 return !(*this == that);
426 }
427 };
428
429 public:
448 [[nodiscard]] const_iterator_path
450 return const_iterator_path(this, n);
451 }
452
471 [[nodiscard]] const_iterator_path
473 (void) n;
474 return const_iterator_path(this, UNDEFINED);
475 }
476
491 [[nodiscard]] const_iterator_path cbegin_path_to_root(node_type n) const {
494 }
495
510 [[nodiscard]] const_iterator_path cend_path_to_root(node_type n) const {
513 }
514 };
515
526
549 template <typename Return>
552 std::vector<uint32_t> const& edge_labels);
553
577 template <typename Return>
581 return make<Forest>(std::vector<uint32_t>(parent),
582 std::vector(edge_labels));
583 }
584
596
602 namespace forest {
615 word_type& w,
617
630 word_type& w,
632
647
662
676
690
704 [[nodiscard]] word_type path_to_root(Forest const& f, Forest::node_type n);
705
719 [[nodiscard]] word_type path_from_root(Forest const& f,
721
734 [[nodiscard]] size_t depth_no_checks(Forest const& f, Forest::node_type n);
735
749 [[nodiscard]] inline size_t depth(Forest const& f, Forest::node_type n) {
751 return depth_no_checks(f, n);
752 }
753
766 [[nodiscard]] inline bool is_root_no_checks(Forest const& f,
768 return f.parent_no_checks(n) == UNDEFINED;
769 }
770
783 [[nodiscard]] inline bool is_root(Forest const& f, Forest::node_type n) {
785 return is_root_no_checks(f, n);
786 }
787 } // namespace forest
788} // namespace libsemigroups
789
790namespace fmt {
791 template <>
792 struct formatter<libsemigroups::Forest> : formatter<std::string> {
813 template <typename FormatContext>
814 auto format(libsemigroups::Forest const& f, FormatContext& ctx) const {
815 return formatter<string_view>::format(
816 fmt::format("{{{}, {}}}", f.parents(), f.labels()), ctx);
817 }
818 };
819} // namespace fmt
820
821#include "forest.tpp"
822
823#endif // LIBSEMIGROUPS_FOREST_HPP_
Class representing a collection of spanning trees of a word graph.
Definition forest.hpp:42
const_iterator_path cbegin_path_to_root_no_checks(node_type n) const noexcept
Returns a const iterator pointing at the first letter of a word from a given node to its root.
Definition forest.hpp:449
uint32_t node_type
Alias for the type of nodes in a forest.
Definition forest.hpp:48
size_t number_of_nodes() const noexcept
Returns the number of nodes in the forest.
Definition forest.hpp:216
Forest & init(size_t n=0)
Reinitialize an existing Forest object.
bool empty() const noexcept
Check if there are any nodes in the forest.
Definition forest.hpp:143
node_type parent_no_checks(node_type i) const
Returns the parent of a node.
Definition forest.hpp:256
Forest(Forest const &)=default
Default copy constructor.
const_iterator_path cend_path_to_root_no_checks(node_type n) const noexcept
Returns a const iterator pointing one beyond the last letter in a word from a given node to its root.
Definition forest.hpp:472
Forest & operator=(Forest const &)=default
Default copy assignment constructor.
bool operator==(Forest const &that) const
Compare Forest objects for equality.
Definition forest.hpp:98
std::vector< node_type > const & parents() const noexcept
Returns a const reference to the vector of parents.
Definition forest.hpp:314
Forest & operator=(Forest &&)=default
Default move assignment constructor.
node_type parent(node_type i) const
Returns the parent of a node.
Definition forest.hpp:236
const_iterator_path cend_path_to_root(node_type n) const
Returns a const iterator pointing one beyond the last letter in a word from a given node to its root.
Definition forest.hpp:510
std::string to_human_readable_repr(Forest const &f)
Return a human readable representation of a Forest object.
Forest(size_t n=0)
Constructs a forest with n nodes.
Definition forest.hpp:59
Forest & add_nodes(size_t n)
Add nodes to the Forest.
bool operator!=(Forest const &that) const
Compare Forest objects for inequality.
Definition forest.hpp:109
Iterator path_to_root_no_checks(Iterator d_first, node_type i) const
Store the labels of the edges on the path to a root node from a given node.
uint32_t label_type
Alias for the type of edge labels in a forest.
Definition forest.hpp:51
label_type label(node_type i) const
Returns the label of the edge from a node to its parent.
Definition forest.hpp:276
Forest & set_parent_and_label_no_checks(node_type node, node_type parent, label_type gen)
Set the parent and edge label for a node.
Definition forest.hpp:168
label_type label_no_checks(node_type i) const
Returns the label of the edge from a node to its parent.
Definition forest.hpp:296
std::vector< label_type > const & labels() const noexcept
Returns a const reference to the vector of edge labels.
Definition forest.hpp:333
Iterator path_from_root_no_checks(Iterator d_first, node_type i) const
Store the labels of the edges on the path from a root node to a given node.
void throw_if_node_out_of_bounds(node_type v) const
Throw an exception if a node is out of bound.
const_iterator_path cbegin_path_to_root(node_type n) const
Returns a const iterator pointing at the first letter of a word from a given node to its root.
Definition forest.hpp:491
Forest & set_parent_and_label(node_type node, node_type parent, label_type gen)
Set the parent and edge label for a node.
Definition forest.hpp:196
Forest(Forest &&)=default
Default move constructor.
Bipartition operator*(Bipartition const &x, Bipartition const &y)
Multiply two bipartitions.
Undefined const UNDEFINED
Value for something undefined.
enable_if_is_same< Return, Blocks > make(Container const &cont)
Check the arguments, construct a Blocks object, and check it.
Definition bipart.hpp:798
std::enable_if_t< std::is_same_v< Given, Expected >, Expected > enable_if_is_same
Alias equal to the second template parameter if both template parameters are equal.
Definition types.hpp:48
std::vector< letter_type > word_type
Type for a word over the generators of a semigroup.
Definition types.hpp:99
auto format(libsemigroups::Forest const &f, FormatContext &ctx) const
Custom formatter for Forest objects.
Definition forest.hpp:814
Helper functions for the Forest class.
Definition forest.hpp:602
bool is_root_no_checks(Forest const &f, Forest::node_type n)
Check if a node is the root of any tree in the Forest.
Definition forest.hpp:766
bool is_root(Forest const &f, Forest::node_type n)
Check if a node is the root of any tree in the Forest.
Definition forest.hpp:783
size_t depth(Forest const &f, Forest::node_type n)
Returns the depth of a node in the forest, i.e. the distance, in terms of the number of edges,...
Definition forest.hpp:749
size_t depth_no_checks(Forest const &f, Forest::node_type n)
Returns the depth of a node in the forest, n.e. the distance, in terms of the number of edges,...
void path_to_root(Forest const &f, word_type &w, Forest::node_type n)
Modifies w to contain the labels of the edges on the path to a root node from n.
void path_from_root_no_checks(Forest const &f, word_type &w, Forest::node_type n)
Modifies w to contain the labels of the edges on the path from a root node to n.
void path_to_root_no_checks(Forest const &f, word_type &w, Forest::node_type n)
Modifies w to contain the labels of the edges on the path to a root node from n.
void path_from_root(Forest const &f, word_type &w, Forest::node_type n)
Modifies w to contain the labels of the edges on the path from a root node to n.
Namespace for everything in the libsemigroups library.
Definition action.hpp:44