libsemigroups  v3.2.0
C++ library for semigroups and monoids
Loading...
Searching...
No Matches
node-managed-graph.hpp
1//
2// libsemigroups - C++ library for semigroups and monoids
3// Copyright (C) 2022-2025 James D. 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// This file contains the declaration of the NodeManagedGraph class, used
20// by Stephen and by ToddCoxeterImpl.
21
22// TODO:
23// * iwyu
24// * code coverage
25
26#ifndef LIBSEMIGROUPS_DETAIL_NODE_MANAGED_GRAPH_HPP_
27#define LIBSEMIGROUPS_DETAIL_NODE_MANAGED_GRAPH_HPP_
28
29#include <cstddef> // for size_t
30#include <cstdint> // for uint32_t
31#include <vector> // for vector
32
33#include <cstddef> // for size_t
34#include <cstdint> // for uint32_t
35#include <stack> // for stack
36#include <type_traits> // for is_base_of
37#include <utility> // for pair
38#include <vector> // for vector
39
40#include "libsemigroups/presentation.hpp" // for Presentation, Presentation<>:...
41#include "libsemigroups/runner.hpp"
42#include "libsemigroups/types.hpp" // for word_type
43#include "libsemigroups/word-graph.hpp" // for WordGraph
44
45#include "felsch-graph.hpp"
46#include "node-manager.hpp" // for NodeManager
47#include "report.hpp" // for REPORT_DEFAULT
48#include "timer.hpp" // for Timer
49#include "word-graph-with-sources.hpp" // for WordGraphWithSources
50
51namespace libsemigroups {
52 namespace detail {
53
54 template <typename Node>
55 class NodeManagedGraph : public WordGraphWithSources<Node>,
56 public NodeManager<Node>,
57 public Reporter {
58 public:
60 // Aliases - public
62
63 using BaseGraph = WordGraphWithSources<Node>;
64 using node_type = typename BaseGraph::node_type;
65 using label_type = typename BaseGraph::label_type;
66
67 static_assert(
68 std::is_base_of<WordGraphWithSources<node_type>, BaseGraph>::value,
69 "the template parameter BaseGraph must be derived from "
70 "WordGraphWithSources<node_type>");
71
72 protected:
74 // Data - protected
76
77 using Coincidence = std::pair<node_type, node_type>;
78 using Coincidences = std::stack<Coincidence>;
79 struct CollectCoincidences; // forward decl
80
81 Coincidences _coinc;
82
83 private:
85 // Data - private
87
88 struct Settings; // forward decl
89 struct Stats; // forward decl
90
91 Settings _settings;
92 mutable Stats _stats;
93
94 public:
96 // BaseGraph mem fns
98
100
101 NodeManagedGraph& target_no_checks(node_type s,
102 label_type a,
103 node_type t) noexcept {
104 _stats.num_edges_active += (t != UNDEFINED);
105 WordGraphWithSources<Node>::target_no_checks(s, a, t);
106 // The next assertion is extremely slow so don't do it!
107 // LIBSEMIGROUPS_ASSERT(_stats.num_edges_active
108 // == count_number_of_edges_active());
109 return *this;
110 }
111 using BaseGraph::target_no_checks;
112
113 using NodeManager<node_type>::cursor;
114 using NodeManager<node_type>::lookahead_cursor;
115
117 // Constructors + initializers
119
120 NodeManagedGraph();
121 NodeManagedGraph& init();
122
123 NodeManagedGraph(NodeManagedGraph const&);
124 NodeManagedGraph(NodeManagedGraph&&);
125 NodeManagedGraph& operator=(NodeManagedGraph const&);
126 NodeManagedGraph& operator=(NodeManagedGraph&&);
127 ~NodeManagedGraph();
128
129 template <typename OtherNode>
130 explicit NodeManagedGraph(WordGraph<OtherNode> const& wg)
131 : BaseGraph(wg), NodeManager<node_type>() {
132 // NodeManager always has one node active
133 NodeManager<node_type>::add_active_nodes(
134 WordGraph<node_type>::number_of_nodes() - 1);
135 _stats.num_edges_active += wg.number_of_edges();
136 }
137
138 template <typename OtherNode>
139 NodeManagedGraph& init(WordGraph<OtherNode> const& wg) {
140 init();
141 BaseGraph::init(wg);
142 // NodeManager always has one node active
143 NodeManager<node_type>::add_active_nodes(
144 WordGraph<node_type>::number_of_nodes() - 1);
145 _stats.num_edges_active += wg.number_of_edges();
146 return *this;
147 }
148
149 template <typename OtherNode>
150 NodeManagedGraph& operator=(WordGraph<OtherNode> const& wg);
151
152 NodeManagedGraph& reserve(size_t n);
153
155 // Operators
157
158 [[nodiscard]] bool operator==(WordGraph<node_type> const& that) const {
159 return static_cast<WordGraph<node_type> const&>(*this) == that;
160 }
161
163 // Settings
165
166 NodeManagedGraph& large_collapse(size_t val) noexcept {
167 _settings.large_collapse = val;
168 return *this;
169 }
170
171 [[nodiscard]] size_t large_collapse() const noexcept {
172 return _settings.large_collapse;
173 }
174
176 // Stats
178
179 [[nodiscard]] Stats& stats() noexcept {
180 return _stats;
181 }
182
183 [[nodiscard]] Stats& stats() const noexcept {
184 return _stats;
185 }
186
187 void stats_check_point() const;
188
190 // Accessors
192
193 [[nodiscard]] uint64_t number_of_edges_active() const noexcept {
194 return _stats.num_edges_active;
195 }
196
197 // 100% not thread safe
198 [[nodiscard]] uint64_t count_number_of_edges_active() const noexcept;
199
201 // Modifiers
203
204 node_type new_node();
205
206 template <bool RegisterDefs = false>
207 [[nodiscard]] std::pair<bool, node_type>
208 complete_path(node_type c,
209 word_type::const_iterator first,
210 word_type::const_iterator last) noexcept;
211
212 void merge_nodes_no_checks(node_type x, node_type y) {
213 _coinc.emplace(x, y);
214 }
215
216 template <typename Functor = Noop>
217 void process_coincidences(Functor&& = Noop{});
218
219 void standardize(std::vector<node_type> const& p,
220 std::vector<node_type> const& q) {
221 BaseGraph::permute_nodes_no_checks(
222 p, q, NodeManager<node_type>::number_of_nodes_active());
223 NodeManager<node_type>::compact();
224 }
225
226 void permute_nodes_no_checks(std::vector<node_type> const& p,
227 std::vector<node_type> const& q) {
228 BaseGraph::permute_nodes_no_checks(
229 p, q, NodeManager<node_type>::number_of_nodes_active());
230 NodeManager<node_type>::apply_permutation(p);
231 }
232
233 // Not currently used for anything, previously required for immediate
234 // standardization
235 void swap_nodes_no_checks(node_type c, node_type d);
236 };
237
238 namespace node_managed_graph {
239 template <typename BaseGraph>
240 typename BaseGraph::node_type
241 random_active_node(NodeManagedGraph<BaseGraph> const& nmg);
242
243 } // namespace node_managed_graph
244
245 } // namespace detail
246} // namespace libsemigroups
247
248#include "node-managed-graph.tpp"
249
250#endif // LIBSEMIGROUPS_DETAIL_NODE_MANAGED_GRAPH_HPP_
size_type out_degree() const noexcept
Returns the out-degree.
Definition word-graph.hpp:842
Undefined const UNDEFINED
Value for something undefined.
std::vector< letter_type > word_type
Type for a word over the generators of a semigroup.
Definition types.hpp:99
Namespace for everything in the libsemigroups library.
Definition action.hpp:44