22// This file is part of the CPP-GL project (https://github.com/SpectraL519/cpp-gl).
33// Licensed under the MIT License. See the LICENSE file in the project root for full license information.
44
5+ // / @file hgl/algorithm/util.hpp
6+ // / @brief Internal utilities and default behaviors used by hypergraph traversal algorithms.
7+
58#pragma once
69
710#include " gl/algorithm/util.hpp"
811#include " hgl/algorithm/core.hpp"
912
1013namespace hgl ::algorithm {
1114
15+ // / @ingroup HGL-Algorithm
16+ // / @brief Initializes a search tree based on the static result discriminator.
17+ // / @tparam Result The compilation tag determining if the tree should actually be built.
18+ // / @tparam H The type of the hypergraph.
19+ // / @param hypergraph The hypergraph instance to size the search tree against.
20+ // / @return A fully sized and initialized `search_tree` if `Result == ret`, otherwise a dummy `std::monostate`.
1221template <result_discriminator Result, traits::c_hypergraph H>
1322[[nodiscard]] gl_attr_force_inline non_void_result_type<Result, search_tree<H>> init_search_tree (
1423 const H& hypergraph
@@ -20,26 +29,52 @@ template <result_discriminator Result, traits::c_hypergraph H>
2029 return return_t ();
2130}
2231
32+ // / @ingroup HGL-Algorithm
33+ // / @brief Checks if a specific vertex was reached during the traversal.
34+ // / @param tree The computed search tree resulting from a traversal.
35+ // / @param vertex_id The identifier of the vertex to check.
36+ // / @return `true` if the vertex has a valid predecessor in the tree, `false` otherwise.
2337[[nodiscard]] gl_attr_force_inline bool is_reachable (
2438 const traits::c_search_tree auto & tree, traits::c_id_type auto vertex_id
2539) noexcept {
2640 return tree[to_idx (vertex_id)].pred_id != invalid_id;
2741}
2842
43+ // / @ingroup HGL-Algorithm
44+ // / @brief Initializes a container with a starting set of root search nodes.
45+ // / @tparam H The type of the hypergraph.
46+ // / @param root_vertex_id The ID of the starting vertex.
47+ // / @return A `std::vector` containing a single root @ref hgl::algorithm::search_node "search_node".
2948template <traits::c_hypergraph H>
3049[[nodiscard]] gl_attr_force_inline std::vector<search_node<H>> init_node_range (
3150 typename H::id_type root_vertex_id
3251) {
3352 return std::vector<search_node<H>>{search_node<H>{root_vertex_id}};
3453}
3554
55+ // / @ingroup HGL-Algorithm
56+ // / @brief Generates a default lambda predicate that checks if a popped search node has already been visited.
57+ // / @tparam H The type of the hypergraph.
58+ // / @param visited_v A reference to the boolean array tracking visited vertices.
59+ // / @return A callable predicate that returns `true` if the vertex in the node has not been visited, `false` otherwise.
3660template <traits::c_hypergraph H>
3761[[nodiscard]] gl_attr_force_inline auto default_visit_predicate (std::vector<bool >& visited_v) {
3862 return [&](const search_node<H>& node) -> bool {
3963 return not visited_v[to_idx (node.vertex_id )];
4064 };
4165}
4266
67+ // / @ingroup HGL-Algorithm
68+ // / @brief Generates a default lambda callback executed upon officially visiting a vertex.
69+ // /
70+ // / Marks the vertex as visited. If `Result == ret`, it also records the search node into the provided search tree.
71+ // /
72+ // / @tparam H The type of the hypergraph.
73+ // / @tparam Result The compilation tag dictating whether to populate the search tree.
74+ // / @param visited_v A reference to the boolean array tracking visited vertices.
75+ // / @param pred_map A reference to the search tree being populated (or a dummy if `Result == noret`).
76+ // / @return A callable callback returning `true` to unconditionally continue the traversal.
77+ // / @hideparams
4378template <traits::c_hypergraph H, result_discriminator Result>
4479[[nodiscard]] gl_attr_force_inline auto default_visit_callback (
4580 std::vector<bool >& visited_v, non_void_result_type<Result, search_tree<H>>& pred_map
@@ -53,6 +88,13 @@ template <traits::c_hypergraph H, result_discriminator Result>
5388 };
5489}
5590
91+ // / @ingroup HGL-Algorithm
92+ // / @brief Generates a default lambda predicate that tracks traversed hyperedges to prevent redundant exploration.
93+ // /
94+ // / Records hyperedges as they are encountered and rejects any that have already been traversed during the search.
95+ // /
96+ // / @param visited_he A reference to the boolean array tracking visited hyperedges.
97+ // / @return A callable predicate returning a @ref hgl::algorithm::decision "decision" (`accept` if not previously visited, `reject` if already visited).
5698[[nodiscard]] gl_attr_force_inline auto default_traverse_hyperedge_predicate (
5799 std::vector<bool >& visited_he
58100) {
@@ -66,6 +108,15 @@ template <traits::c_hypergraph H, result_discriminator Result>
66108 };
67109}
68110
111+ // / @ingroup HGL-Algorithm
112+ // / @brief Generates a lambda predicate that blocks hyperedge traversal until its associated counter reaches zero.
113+ // /
114+ // / This predicate is particularly useful in topological sorting or multi-dependency algorithms for *BF-directed*
115+ // / hypergraphs, where a hyperedge should only be evaluated once all of its dependencies (e.g., all vertices in
116+ // / its tail) have been saturated or visited.
117+ // /
118+ // / @param counter_map A reference to an array of size or dependency counters mapped to hyperedge IDs.
119+ // / @return A callable predicate returning a @ref hgl::algorithm::decision "decision" (`accept` if the decremented counter reaches 0, `reject` otherwise).
69120[[nodiscard]] gl_attr_force_inline auto blocking_traverse_hyperedge_predicate (
70121 std::vector<size_type>& counter_map
71122) {
@@ -74,6 +125,12 @@ template <traits::c_hypergraph H, result_discriminator Result>
74125 };
75126}
76127
128+ // / @ingroup HGL-Algorithm
129+ // / @brief Generates a default lambda predicate that checks if a node corresponding to an adjacent vertex should be enqueued.
130+ // / @tparam H The type of the hypergraph.
131+ // / @tparam AsResult If `true`, the generated predicate returns a @ref hgl::algorithm::decision "decision" instead of a raw boolean.
132+ // / @param visited_v A reference to the boolean array tracking visited vertices.
133+ // / @return A callable predicate that returns `true` (or `decision::accept`) if the adjacent vertex has not been visited.
77134template <traits::c_hypergraph H, bool AsResult = false >
78135[[nodiscard]] gl_attr_force_inline auto default_enqueue_predicate (std::vector<bool >& visited_v) {
79136 using return_t = std::conditional_t <AsResult, decision, bool >;
0 commit comments