Skip to content

Commit 23b86b8

Browse files
authored
View paper (#124)
* Add D3129 views update strategy document * views_update_strategy: resolve all Section 5 open questions (Q1–Q7) * Add views update plan; update strategy Q4 with C++23/C++20 backward compat and D3126 cross-paper note * Phase A: Rewrite D3129 source files — info structs → data structs * Phase B: Rewrite data structs section — tables, examples, prose * Phase C: Update graph view sections — data structs, bindings, 2-arg VVF/EVF * Apply naming convention: u/uid=source, v/vid=target, uv=edge Fix views.tex bindings: incidence [vid,uv], neighbors [vid,v], edgelist [uid,vid,uv], search example [uid,u]. Update plan: add naming convention section, fix Phase C/E/F/G binding examples, mark Phases A-C done. * Phase D: Update search common types — member functions, search_view concept Replace free functions (cancel, depth, size) with member functions (cancel(), depth(), num_visited()). Add search_view concept. Remove sourced views paragraph. Update code example to member syntax. * Phase E: Update DFS/BFS views — remove sourced, descriptor-based return Update DFS and BFS tables: source→seed, vertex_info→vertex_data, edge_info→edge_data, remove sourced_edges rows, update bindings ([u], [u,val], [uv], [uv,val]). Remove all phil notes. Add design note explaining descriptor-based return (VId=void). * Phase F: Update topological sort — all-vertex, _safe factories, remove sourced Remove source parameter (all-vertex traversal). Remove sourced rows. Update bindings ([u], [u,val], [uv], [uv,val]) and types (vertex_data, edge_data). Add _safe factory table returning std::expected for cycle detection. Note cancel_branch == cancel_all. Remove phil notes. * Phase G: Add basic views, in_ variants, transpose, pipe syntax, VVF/EVF concepts * Phase H: Prose audit — cleanup phil notes, rename all obsolete types * Phase I: Update revision history and config for D3129r3 * Phase J: Cross-paper fixups — conventions.tex VVF/EVF, D3126 C++23 note * Update plan: mark Phase J complete * Add mapped_algo_strategy.md for D3128 mapped container update * Add mapped_algo_plan.md for D3128 mapped container update * mapped_algo_plan: fold confirmed decisions, collapse to 4 phases * D3128 Phase 1: add vertex_property_map concept section, remove stale note * D3128 Phase 2: index_adjacency_list -> adjacency_list (BFS, DFS, topo sort, TC, Jaccard, MIS, find_negative_cycle) * D3128 Phase 3: vertex_property_map_for requires clauses (Dijkstra, Bellman-Ford, Prim, LP, components) * D3128 Phase 4: prop-map preconditions, Kosaraju bidir upgrade, mapped graph example - 4A (algorithms.tex): replace size-based preconditions/throws with vertex-property-map-neutral wording in Dijkstra, Bellman-Ford, Connected Components, Afforest, Kosaraju, and Prim; add remarks referencing vertex_property_map_for and §Vertex Property Map Concept; fix Prim range_value_t -> vertex_property_map_value_t; fix Tarjan note concept name - 4C (connected_components.hpp): upgrade Kosaraju bidir overload from index_bidirectional_adjacency_list to bidirectional_adjacency_list - 4D: add dijkstra_example_mapped.hpp showing Dijkstra on a mapped graph (string vertex IDs via uov_graph_traits) and reference it from algorithms.tex
1 parent 4365230 commit 23b86b8

38 files changed

Lines changed: 3188 additions & 486 deletions

D3126_Overview/tex/overview.tex

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,9 @@ \section{Freestanding}
254254
Additionally, \tcode{stack} and \tcode{queue} require memory allocation which could throw a \tcode{bad_alloc}
255255
exception.
256256
257+
\section{Language Requirements}
258+
The library targets C++20 as its baseline. The topological sort safe view factories (\tcode{vertices_topological_sort_safe}, \tcode{edges_topological_sort_safe}) use \tcode{std::expected} from C++23. The reference implementation provides backward compatibility to C++20 via an external \tcode{expected} library (e.g., \tcode{tl::expected}), switching to \tcode{std::expected} when C++23 or later is available.
259+
257260
\section{Namespaces}
258261
Graph containers and their views and algorithms are not interchangeable with existing containers and algorithms.
259262
Additionally, there are some domain-specific terms that may clash with existing or future names, such as
Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
1-
template <index_adjacency_list G,
2-
random_access_range Distances,
3-
class WF = function<range_value_t<Distances>(const remove_reference_t<G>&,
4-
const edge_t<G>&)>,
1+
template <adjacency_list G,
2+
class Distances,
3+
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
4+
const edge_t<G>&)>,
55
class Visitor = empty_visitor,
6-
class Compare = less<range_value_t<Distances>>,
7-
class Combine = plus<range_value_t<Distances>>>
8-
requires is_arithmetic_v<range_value_t<Distances>> && sized_range<Distances> &&
9-
basic_edge_weight_function<G, WF, range_value_t<Distances>, Compare, Combine>
6+
class Compare = less<vertex_property_map_value_t<Distances>>,
7+
class Combine = plus<vertex_property_map_value_t<Distances>>>
8+
requires vertex_property_map_for<Distances, G> &&
9+
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
10+
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
1011
[[nodiscard]] constexpr optional<vertex_id_t<G>> bellman_ford_shortest_distances(
1112
G&& g,
1213
const vertex_id_t<G>& source,
1314
Distances& distances,
1415
WF&& weight = [](const auto&,
15-
const edge_t<G>& uv) { return range_value_t<Distances>(1); },
16+
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
1617
Visitor&& visitor = empty_visitor(),
17-
Compare&& compare = less<range_value_t<Distances>>(),
18-
Combine&& combine = plus<range_value_t<Distances>>());
18+
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
19+
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,21 @@
1-
template <index_adjacency_list G,
2-
input_range Sources,
3-
random_access_range Distances,
4-
class WF = function<range_value_t<Distances>(const remove_reference_t<G>&,
5-
const edge_t<G>&)>,
1+
template <adjacency_list G,
2+
input_range Sources,
3+
class Distances,
4+
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
5+
const edge_t<G>&)>,
66
class Visitor = empty_visitor,
7-
class Compare = less<range_value_t<Distances>>,
8-
class Combine = plus<range_value_t<Distances>>>
9-
requires convertible_to<range_value_t<Sources>, vertex_id_t<G>> &&
10-
is_arithmetic_v<range_value_t<Distances>> && sized_range<Distances> &&
11-
basic_edge_weight_function<G, WF, range_value_t<Distances>, Compare, Combine>
7+
class Compare = less<vertex_property_map_value_t<Distances>>,
8+
class Combine = plus<vertex_property_map_value_t<Distances>>>
9+
requires vertex_property_map_for<Distances, G> &&
10+
convertible_to<range_value_t<Sources>, vertex_id_t<G>> &&
11+
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
12+
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
1213
[[nodiscard]] constexpr optional<vertex_id_t<G>> bellman_ford_shortest_distances(
1314
G&& g,
1415
const Sources& sources,
1516
Distances& distances,
1617
WF&& weight = [](const auto&,
17-
const edge_t<G>& uv) { return range_value_t<Distances>(1); },
18+
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
1819
Visitor&& visitor = empty_visitor(),
19-
Compare&& compare = less<range_value_t<Distances>>(),
20-
Combine&& combine = plus<range_value_t<Distances>>());
20+
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
21+
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,23 @@
1-
template <index_adjacency_list G,
2-
random_access_range Distances,
3-
random_access_range Predecessors,
4-
class WF = function<range_value_t<Distances>(const remove_reference_t<G>&,
5-
const edge_t<G>&)>,
1+
template <adjacency_list G,
2+
class Distances,
3+
class Predecessors,
4+
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
5+
const edge_t<G>&)>,
66
class Visitor = empty_visitor,
7-
class Compare = less<range_value_t<Distances>>,
8-
class Combine = plus<range_value_t<Distances>>>
9-
requires is_arithmetic_v<range_value_t<Distances>> &&
10-
convertible_to<vertex_id_t<G>, range_value_t<Predecessors>> &&
11-
sized_range<Distances> && sized_range<Predecessors> &&
12-
basic_edge_weight_function<G, WF, range_value_t<Distances>, Compare, Combine>
7+
class Compare = less<vertex_property_map_value_t<Distances>>,
8+
class Combine = plus<vertex_property_map_value_t<Distances>>>
9+
requires vertex_property_map_for<Distances, G> &&
10+
vertex_property_map_for<Predecessors, G> &&
11+
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
12+
convertible_to<vertex_id_t<G>, vertex_property_map_value_t<Predecessors>> &&
13+
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
1314
[[nodiscard]] constexpr optional<vertex_id_t<G>> bellman_ford_shortest_paths(
1415
G&& g,
1516
const vertex_id_t<G>& source,
1617
Distances& distances,
1718
Predecessors& predecessor,
1819
WF&& weight = [](const auto&,
19-
const edge_t<G>& uv) { return range_value_t<Distances>(1); },
20+
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
2021
Visitor&& visitor = empty_visitor(),
21-
Compare&& compare = less<range_value_t<Distances>>(),
22-
Combine&& combine = plus<range_value_t<Distances>>());
22+
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
23+
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());
Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,25 @@
1-
template <index_adjacency_list G,
2-
input_range Sources,
3-
random_access_range Distances,
4-
random_access_range Predecessors,
5-
class WF = function<range_value_t<Distances>(const remove_reference_t<G>&,
6-
const edge_t<G>&)>,
1+
template <adjacency_list G,
2+
input_range Sources,
3+
class Distances,
4+
class Predecessors,
5+
class WF = function<vertex_property_map_value_t<Distances>(const remove_reference_t<G>&,
6+
const edge_t<G>&)>,
77
class Visitor = empty_visitor,
8-
class Compare = less<range_value_t<Distances>>,
9-
class Combine = plus<range_value_t<Distances>>>
10-
requires convertible_to<range_value_t<Sources>, vertex_id_t<G>> &&
11-
is_arithmetic_v<range_value_t<Distances>> &&
12-
convertible_to<vertex_id_t<G>, range_value_t<Predecessors>> &&
13-
sized_range<Distances> && sized_range<Predecessors> &&
14-
basic_edge_weight_function<G, WF, range_value_t<Distances>, Compare, Combine>
8+
class Compare = less<vertex_property_map_value_t<Distances>>,
9+
class Combine = plus<vertex_property_map_value_t<Distances>>>
10+
requires vertex_property_map_for<Distances, G> &&
11+
vertex_property_map_for<Predecessors, G> &&
12+
convertible_to<range_value_t<Sources>, vertex_id_t<G>> &&
13+
is_arithmetic_v<vertex_property_map_value_t<Distances>> &&
14+
convertible_to<vertex_id_t<G>, vertex_property_map_value_t<Predecessors>> &&
15+
basic_edge_weight_function<G, WF, vertex_property_map_value_t<Distances>, Compare, Combine>
1516
[[nodiscard]] constexpr optional<vertex_id_t<G>> bellman_ford_shortest_paths(
1617
G&& g,
1718
const Sources& sources,
1819
Distances& distances,
1920
Predecessors& predecessor,
2021
WF&& weight = [](const auto&,
21-
const edge_t<G>& uv) { return range_value_t<Distances>(1); },
22+
const edge_t<G>& uv) { return vertex_property_map_value_t<Distances>(1); },
2223
Visitor&& visitor = empty_visitor(),
23-
Compare&& compare = less<range_value_t<Distances>>(),
24-
Combine&& combine = plus<range_value_t<Distances>>());
24+
Compare&& compare = less<vertex_property_map_value_t<Distances>>(),
25+
Combine&& combine = plus<vertex_property_map_value_t<Distances>>());

D3128_Algorithms/src/breadth_first_search.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
template <index_adjacency_list G, class Visitor = empty_visitor>
1+
template <adjacency_list G, class Visitor = empty_visitor>
22
void breadth_first_search(
33
G&& g, // graph
44
vertex_id_t<G> source, // starting vertex\_id

D3128_Algorithms/src/breadth_first_search_multi.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
template <index_adjacency_list G, input_range Sources, class Visitor = empty_visitor>
1+
template <adjacency_list G, input_range Sources, class Visitor = empty_visitor>
22
requires convertible_to<range_value_t<Sources>, vertex_id_t<G>>
33
void breadth_first_search(G&& g, // graph
44
const Sources& sources,
Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,41 @@
11
/*
22
* Hopcroft-Tarjan Articulation Points
33
*/
4-
template <index_adjacency_list G, class Iter>
4+
template <adjacency_list G, class Iter>
55
requires output_iterator<Iter, vertex_id_t<G>>
66
void articulation_points(G&& g, Iter cut_vertices);
77

88
/*
99
* Hopcroft-Tarjan Biconnected Components
1010
*/
11-
template <index_adjacency_list G, class OuterContainer>
11+
template <adjacency_list G, class OuterContainer>
1212
void biconnected_components(G&& g, OuterContainer& components);
1313

1414
/*
1515
* Connected Components
1616
*/
17-
template <index_adjacency_list G, random_access_range Component>
17+
template <adjacency_list G, class Component>
18+
requires vertex_property_map_for<Component, G>
1819
size_t connected_components(G&& g, Component& component);
1920

2021
/*
2122
* Afforest Connected Components
2223
*/
23-
template <index_adjacency_list G, random_access_range Component>
24+
template <adjacency_list G, class Component>
25+
requires vertex_property_map_for<Component, G>
2426
void afforest(G&& g, Component& component, const size_t neighbor_rounds = 2);
2527

26-
template <index_adjacency_list G, adjacency_list GT, random_access_range Component>
28+
template <adjacency_list G, adjacency_list GT, class Component>
29+
requires vertex_property_map_for<Component, G>
2730
void afforest(G&& g, GT&& g_t, Component& component, const size_t neighbor_rounds = 2);
2831

2932
/*
3033
* Kosaraju Strongly Connected Components
3134
*/
32-
template <index_adjacency_list G, index_adjacency_list GT, random_access_range Component>
35+
template <adjacency_list G, adjacency_list GT, class Component>
36+
requires vertex_property_map_for<Component, G>
3337
void kosaraju(G&& g, GT&& g_t, Component& component);
3438

35-
template <index_bidirectional_adjacency_list G, random_access_range Component>
39+
template <bidirectional_adjacency_list G, class Component>
40+
requires vertex_property_map_for<Component, G>
3641
void kosaraju(G&& g, Component& component);

D3128_Algorithms/src/depth_first_search.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
template <index_adjacency_list G, class Visitor = empty_visitor>
1+
template <adjacency_list G, class Visitor = empty_visitor>
22
void depth_first_search(
33
G&& g, // graph
44
vertex_id_t<G> source, // starting vertex\_id
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Example: Dijkstra on a mapped graph (string vertex IDs, double edge weights)
2+
3+
#include <graph/container/dynamic_graph.hpp>
4+
#include <graph/container/traits/uov_graph_traits.hpp>
5+
#include <graph/adj_list/vertex_property_map.hpp>
6+
#include <graph/algorithm/dijkstra_shortest_paths.hpp>
7+
using namespace graph;
8+
using namespace graph::adj_list;
9+
10+
using Traits = container::uov_graph_traits<double, void, void, std::string>;
11+
using G = container::dynamic_graph<double, void, void, std::string, false, Traits>;
12+
13+
G g({{"a", "b", 4.0}, {"a", "c", 2.0},
14+
{"b", "d", 5.0},
15+
{"c", "b", 1.0}, {"c", "d", 8.0}});
16+
17+
constexpr double inf = std::numeric_limits<double>::max();
18+
19+
auto dist = make_vertex_property_map<G, double>(g, inf);
20+
auto pred = make_vertex_property_map<G, vertex_id_t<G>>(g, vertex_id_t<G>{});
21+
for (auto&& [uid, u] : views::vertexlist(g))
22+
pred[uid] = uid;
23+
24+
dijkstra_shortest_paths(g, std::string{"a"}, dist, pred,
25+
[](const auto& g, const edge_t<G>& e) { return edge_value(g, e); });
26+
27+
// Shortest a to d: a to c (2) to b (1) to d (5) = 8
28+
// dist["d"] == 8
29+

0 commit comments

Comments
 (0)