libsemigroups  v3.3.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
word-graph-view.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2025 Nadim Searight
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// This file contains an implementation of word graph views, a thin layer over
20// word graphs exposing a chosen range of nodes
21
22#ifndef LIBSEMIGROUPS_WORD_GRAPH_VIEW_HPP_
23#define LIBSEMIGROUPS_WORD_GRAPH_VIEW_HPP_
24
25#include <type_traits> // for is_integral
26#include <utility> // for pair
27
28#include "config.hpp" // for LIBSEMIGROUPS_DEBUG
29#include "debug.hpp" // for LIBSEMIGROUPS_ASSERT
30#include "word-graph.hpp" // for word_graph pointer
31
32#include "detail/containers.hpp"
33#include "detail/int-range.hpp" // for IntRange
34
35namespace libsemigroups {
47 template <typename Node>
49 public:
50 static_assert(std::is_integral<Node>(),
51 "the template parameter Node must be an integral type!");
52 static_assert(
54 "the template parameter Node must be an unsigned integral type!");
55
57 using node_type = Node;
58
60 using label_type = Node;
61
64
68 typename detail::IntRange<Node>::const_iterator;
69
73 typename detail::IntRange<Node>::const_reverse_iterator;
74
77 typename detail::DynamicArray2<Node>::const_iterator;
78
79 private:
80 WordGraph<Node> const* _graph;
81 node_type _start;
82 node_type _end;
83
84 constexpr node_type to_graph(node_type n) const noexcept;
85
86 constexpr node_type to_view(node_type n) const noexcept;
87
88 constexpr auto
89 to_view(rx::iterator_range<const_iterator_targets> it) const {
90 return it
91 | rx::transform([this](auto elem) { return this->to_view(elem); });
92 }
93
94 void to_view(std::pair<label_type, node_type>& in) const {
95 // this is designed to operate on pairs of <label, node>
96 // so does not modify the first element
97 in.second = to_view(in.second);
98 }
99
100 public:
102 // Constructors + initialisers
104 // TODO: Add make functions that construct with checks
105
115 : _graph(&graph), _start(start), _end(end) {
116 LIBSEMIGROUPS_ASSERT(start <= end);
117 LIBSEMIGROUPS_ASSERT(end <= graph.number_of_nodes());
118 }
119
136 size_type start,
137 size_type end);
138
145 explicit WordGraphView(WordGraph<Node> const& graph)
146 : _graph(&graph), _start(0), _end(graph.number_of_nodes()) {}
147
159 return init(graph, 0, graph.number_of_nodes());
160 }
161
165 WordGraphView() : _graph(nullptr), _start(0), _end(0) {}
166
175 _graph = nullptr;
176 _start = 0;
177 _end = 0;
178 return *this;
179 }
180
183
186
189
192
193 ~WordGraphView() = default;
194
196 // Modifiers
198
217
234 throw_if_graph_is_nullptr();
235 throw_if_invalid_range(start, end);
236 return reshape_no_checks(start, end);
237 }
238
256 LIBSEMIGROUPS_ASSERT(start <= _end);
257 _start = start;
258 return *this;
259 }
260
276
294
310
312 // Accessors
314
325 [[nodiscard]] size_type number_of_nodes_no_checks() const noexcept {
326 LIBSEMIGROUPS_ASSERT(_start <= _end);
327 return _end - _start;
328 }
329
342 [[nodiscard]] size_type number_of_nodes() const {
345 }
346
357 [[nodiscard]] size_type number_of_edges_no_checks() const noexcept;
358
371 [[nodiscard]] size_type number_of_edges() const {
374 }
375
386 [[nodiscard]] node_type start_node() const noexcept {
387 return _start;
388 }
389
401 [[nodiscard]] node_type end_node() const noexcept {
402 return _end;
403 }
404
416 [[nodiscard]] size_type out_degree_no_checks() const noexcept {
417 return _graph->out_degree();
418 }
419
434 [[nodiscard]] size_type out_degree() const {
435 throw_if_graph_is_nullptr();
436 return out_degree_no_checks();
437 }
438
451 [[nodiscard]] WordGraph<Node> const* word_graph() const noexcept {
452 return _graph;
453 }
454
456 // Nodes, targets and labels
458
474 return detail::IntRange<node_type>(0, number_of_nodes_no_checks())
475 .cbegin();
476 }
477
498
513 [[nodiscard]] const_iterator_nodes cend_nodes_no_checks() const noexcept {
514 return detail::IntRange<node_type>(0, number_of_nodes_no_checks()).cend();
515 }
516
533 [[nodiscard]] const_iterator_nodes cend_nodes() const {
535 return cend_nodes_no_checks();
536 }
537
547 [[nodiscard]] auto nodes_no_checks() const noexcept {
548 return rx::iterator_range(cbegin_nodes_no_checks(),
550 }
551
563 [[nodiscard]] auto nodes() const {
565 return nodes_no_checks();
566 }
567
591 [[nodiscard]] auto
592 cbegin_targets_no_checks(node_type source) const noexcept {
593 return rx::begin(targets_no_checks(source));
594 }
595
617 // Not noexcept because throw_if_node_out_of_bounds isn't
618 [[nodiscard]] auto cbegin_targets(node_type source) const {
621 return cbegin_targets_no_checks(source);
622 }
623
646 [[nodiscard]] auto cend_targets_no_checks(node_type source) const noexcept {
647 return rx::end(targets_no_checks(source));
648 }
649
671 // Not noexcept because throw_if_node_out_of_bounds isn't
672 [[nodiscard]] auto cend_targets(node_type source) const {
675 return cend_targets_no_checks(source);
676 }
677
695 [[nodiscard]] auto targets_no_checks(node_type source) const noexcept {
696 node_type translated = to_graph(source);
697 return to_view(_graph->targets_no_checks(translated));
698 }
699
716 [[nodiscard]] auto targets(node_type source) const {
719 return targets_no_checks(source);
720 }
721
732 [[nodiscard]] auto labels_no_checks() const noexcept {
733 return _graph->labels();
734 }
735
746 [[nodiscard]] auto labels() const {
747 throw_if_graph_is_nullptr();
748 return labels_no_checks();
749 }
750
786
822 // Not noexcept because next_label_and_target_no_checks is not
825
843 [[nodiscard]] auto
845 return rx::enumerate(targets_no_checks(source));
846 }
847
863 [[nodiscard]] auto labels_and_targets(node_type source) const {
866 return labels_and_targets_no_checks(source);
867 }
868
886 // Not noexcept because throw_if_node_out_of_bounds/label aren't
888 label_type a) const {
889 node_type translated = to_graph(source);
890 return to_view(_graph->target_no_checks(translated, a));
891 }
892
912 // Not noexcept because throw_if_node_out_of_bounds/label aren't
913 [[nodiscard]] node_type target(node_type source, label_type a) const;
914
916 // Operators
918
928 [[nodiscard]] bool equal_to_no_checks(WordGraphView const& that) const;
929
945 [[nodiscard]] bool operator==(WordGraphView const& that) const;
946
955 [[nodiscard]] bool not_equal_to_no_checks(WordGraphView const& that) const {
956 return !equal_to_no_checks(that);
957 }
958
973 [[nodiscard]] bool operator!=(WordGraphView const& that) const {
974 return !operator==(that);
975 }
976
978 // Validation
980
993
1013 template <typename Iterator>
1014 void throw_if_any_target_out_of_bounds(Iterator first, Iterator last) const;
1015
1024 // not noexcept because it throws an exception!
1025 void
1027
1037 void throw_if_label_out_of_bounds(word_type const& word) const {
1039 }
1040
1054 template <typename Iterator>
1055 void throw_if_label_out_of_bounds(Iterator first, Iterator last) const {
1056 std::for_each(first, last, [this](letter_type a) {
1058 });
1059 }
1060
1071 void
1073 std::for_each(rules.cbegin(), rules.cend(), [this](word_type const& w) {
1074 this->throw_if_label_out_of_bounds(w);
1075 });
1076 }
1077
1088 // not noexcept because it throws an exception!
1089 template <typename Node2>
1090 void throw_if_node_out_of_bounds(Node2 n) const;
1091
1105 // not noexcept because it throws an exception!
1106 template <typename Iterator1, typename Iterator2>
1107 void throw_if_node_out_of_bounds(Iterator1 first, Iterator2 last) const {
1108 for (auto it = first; it != last; ++it) {
1110 }
1111 }
1112
1123 throw_if_invalid_range(_start, _end);
1124 }
1125
1137 throw_if_graph_is_nullptr();
1139 }
1140
1141 private:
1142 void throw_if_graph_is_nullptr() const {
1143 if (_graph == nullptr) {
1144 LIBSEMIGROUPS_EXCEPTION("the underlying WordGraph is not defined");
1145 }
1146 }
1147
1148 void throw_if_endpoint_out_of_bounds(node_type endpoint,
1149 std::string_view node_name) const;
1150
1151 void throw_if_endpoints_wrong_order(node_type start, node_type end) const;
1152
1153 void throw_if_invalid_range(node_type start, node_type end) const {
1154 throw_if_endpoint_out_of_bounds(start, "start");
1155 throw_if_endpoint_out_of_bounds(end, "end");
1156 throw_if_endpoints_wrong_order(start, end);
1157 }
1158 };
1159} // namespace libsemigroups
1160#include "word-graph-view.tpp"
1161
1162#endif // LIBSEMIGROUPS_WORD_GRAPH_VIEW_HPP_
T cbegin(T... args)
Class for representing word graphs.
Definition word-graph.hpp:83
Node label_type
The type of edge labels in a word graph.
Definition word-graph.hpp:102
size_type number_of_nodes() const noexcept
Returns the number of nodes.
Definition word-graph.hpp:766
size_type number_of_nodes() const
The number of nodes that this view ranges over.
Definition word-graph-view.hpp:342
Node node_type
The type of nodes in a word graph.
Definition word-graph-view.hpp:57
auto labels_and_targets(node_type source) const
Returns a range object containing pairs consisting of edge labels and target nodes.
Definition word-graph-view.hpp:863
size_type out_degree_no_checks() const noexcept
Returns the out degree.
Definition word-graph-view.hpp:416
std::pair< label_type, node_type > next_label_and_target_no_checks(node_type s, label_type a) const
Get the next target of an edge incident to a given node that doesn't equal UNDEFINED.
WordGraphView & start_node(node_type start)
Set the index in the underlying graph of the first node in the view.
WordGraph< Node > const * word_graph() const noexcept
Returns a const pointer to the underlying WordGraph.
Definition word-graph-view.hpp:451
void throw_if_any_target_out_of_bounds() const
Throws if the target of any edge is out of bounds.
Definition word-graph-view.hpp:989
bool not_equal_to_no_checks(WordGraphView const &that) const
Compares two word graph views to see if they are not equal.
Definition word-graph-view.hpp:955
size_type number_of_edges() const
The number of edges in the underlying graph.
Definition word-graph-view.hpp:371
WordGraphView & init(WordGraph< Node > const &graph, size_type start, size_type end)
Re-initialize the view to be a view over graph over the range start to end.
bool operator!=(WordGraphView const &that) const
Compares two word graph views to see if they are not equal.
Definition word-graph-view.hpp:973
auto labels_no_checks() const noexcept
Returns a range object containing all labels of edges in a word graph.
Definition word-graph-view.hpp:732
const_iterator_nodes cbegin_nodes_no_checks() const noexcept
Returns a random access iterator pointing at the first node of the word graph.
Definition word-graph-view.hpp:473
auto labels() const
Returns a range object containing all labels of edges in a word graph.
Definition word-graph-view.hpp:746
size_type number_of_nodes_no_checks() const noexcept
The number of nodes that this view ranges over.
Definition word-graph-view.hpp:325
Node label_type
The type of edge labels in a word graph.
Definition word-graph-view.hpp:60
auto cbegin_targets_no_checks(node_type source) const noexcept
Returns a random access iterator pointing at the target of the edge with label 0 incident to a given ...
Definition word-graph-view.hpp:592
auto labels_and_targets_no_checks(node_type source) const noexcept
Returns a range object containing pairs consisting of edge labels and target nodes.
Definition word-graph-view.hpp:844
auto targets(node_type source) const
Returns a range object containing all the targets of edges with a given source.
Definition word-graph-view.hpp:716
WordGraphView(WordGraph< Node > const &graph, size_type start, size_type end)
Construct from a WordGraph and range of nodes.
Definition word-graph-view.hpp:114
void throw_if_invalid_view() const
Throws if the this is in an invalid state.
Definition word-graph-view.hpp:1136
WordGraphView(WordGraphView< Node > &&)=default
Default move constructor.
WordGraphView & operator=(WordGraphView< Node > &&)=default
Default move assignment.
WordGraphView & operator=(WordGraphView< Node > const &)=default
Default copy assignment.
void throw_if_node_out_of_bounds(Iterator1 first, Iterator2 last) const
Throws if any node in a range is out of bounds.
Definition word-graph-view.hpp:1107
node_type end_node() const noexcept
The index in the underlying graph of one beyond the final node in the view.
Definition word-graph-view.hpp:401
WordGraphView & reshape(node_type start, node_type end)
Reshape this view over the same graph.
Definition word-graph-view.hpp:233
WordGraphView & end_node(node_type end)
Set the index in the underlying graph of one beyond the last node in the view.
node_type target(node_type source, label_type a) const
Get the target of the edge with given source node and label.
WordGraphView & init(WordGraph< Node > const &graph)
Re-initialize the view to be a view over graph.
Definition word-graph-view.hpp:158
WordGraphView()
Default constructor.
Definition word-graph-view.hpp:165
WordGraphView & end_node_no_checks(node_type end) noexcept
Set the index in the underlying graph of one beyond the last node in the view.
void throw_if_node_out_of_bounds(Node2 n) const
Throws if a node is out of bounds.
WordGraphView & start_node_no_checks(node_type start) noexcept
Set the index in the underlying graph of the first node in the view.
Definition word-graph-view.hpp:255
WordGraphView & reshape_no_checks(node_type start, node_type end)
Reshape this view over the same graph.
auto cbegin_targets(node_type source) const
Returns a random access iterator pointing at the target of the edge with label 0 incident to a given ...
Definition word-graph-view.hpp:618
void throw_if_label_out_of_bounds(word_type const &word) const
Throws if word contains labels that are out of bounds.
Definition word-graph-view.hpp:1037
void throw_if_label_out_of_bounds(std::vector< word_type > const &rules) const
Throws if any of the labels in vector of words is out of bounds.
Definition word-graph-view.hpp:1072
typename detail::DynamicArray2< Node >::const_iterator const_iterator_targets
The type of an iterator pointing to the targets of a node.
Definition word-graph-view.hpp:76
const_iterator_nodes cbegin_nodes() const
Returns a random access iterator pointing at the first node of the word graph.
Definition word-graph-view.hpp:494
void throw_if_invalid_range() const
Throws if the range specified by [start_node(), end_node()] is invalid.
Definition word-graph-view.hpp:1122
node_type start_node() const noexcept
The index in the underlying graph of the first node in the view.
Definition word-graph-view.hpp:386
void throw_if_label_out_of_bounds(typename WordGraph< Node >::label_type a) const
Throws if a label is out of bounds.
void throw_if_any_target_out_of_bounds(Iterator first, Iterator last) const
Throws if the target of any edge with source in a given range is out of bounds.
const_iterator_nodes cend_nodes() const
Returns a random access iterator pointing one past the last node of the range of this word graph view...
Definition word-graph-view.hpp:533
size_type number_of_edges_no_checks() const noexcept
The number of edges in the underlying graph.
WordGraphView & init()
Re-initialize the view as if it had been default constructed.
Definition word-graph-view.hpp:174
size_type out_degree() const
Returns the out degree.
Definition word-graph-view.hpp:434
auto nodes_no_checks() const noexcept
Returns a range object containing all nodes in a word graph.
Definition word-graph-view.hpp:547
std::pair< label_type, node_type > next_label_and_target(node_type s, label_type a) const
Get the next target of an edge incident to a given node that doesn't equal UNDEFINED.
typename detail::IntRange< Node >::const_reverse_iterator const_reverse_iterator_nodes
The type of a reverse iterator pointing to the nodes of a word graph view.
Definition word-graph-view.hpp:72
void throw_if_label_out_of_bounds(Iterator first, Iterator last) const
Throws if range contains labels that are out of bounds.
Definition word-graph-view.hpp:1055
bool equal_to_no_checks(WordGraphView const &that) const
Compares two word graph views to see if they are equal.
node_type target_no_checks(node_type source, label_type a) const
Get the target of the edge with given source node and label.
Definition word-graph-view.hpp:887
auto cend_targets_no_checks(node_type source) const noexcept
Returns a random access iterator pointing one beyond the target of the edge with label out_degree() -...
Definition word-graph-view.hpp:646
auto targets_no_checks(node_type source) const noexcept
Returns a range object containing all the targets of edges with a given source.
Definition word-graph-view.hpp:695
const_iterator_nodes cend_nodes_no_checks() const noexcept
Returns a random access iterator pointing one past the last node of the range of this word graph view...
Definition word-graph-view.hpp:513
typename detail::IntRange< Node >::const_iterator const_iterator_nodes
The type of an iterator pointing to the nodes of the word graph view.
Definition word-graph-view.hpp:67
WordGraphView(WordGraphView< Node > const &)=default
Default copy constructor.
WordGraphView(WordGraph< Node > const &graph)
Construct from a WordGraph.
Definition word-graph-view.hpp:145
auto nodes() const
Returns a range object containing all nodes in a word graph.
Definition word-graph-view.hpp:563
std::size_t size_type
Unsigned integer type.
Definition word-graph-view.hpp:63
bool operator==(WordGraphView const &that) const
Compares two word graph views to see if they are equal.
auto cend_targets(node_type source) const
Returns a random access iterator pointing one beyond the target of the edge with label out_degree() -...
Definition word-graph-view.hpp:672
T cend(T... args)
T for_each(T... args)
#define LIBSEMIGROUPS_EXCEPTION(...)
Throw a LibsemigroupsException.
Definition exception.hpp:99
std::vector< letter_type > word_type
Type for a word over the generators of a semigroup.
Definition types.hpp:99
size_t letter_type
Type for the index of a generator of a semigroup.
Definition types.hpp:96
Namespace for everything in the libsemigroups library.
Definition action.hpp:44