From e0dcc47da795d9c84ab894b9891703824ccd7136 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 17:01:06 -0400 Subject: [PATCH 01/22] Add D3129 views update strategy document --- agents/views_update_strategy.md | 778 ++++++++++++++++++++++++++++++++ 1 file changed, 778 insertions(+) create mode 100644 agents/views_update_strategy.md diff --git a/agents/views_update_strategy.md b/agents/views_update_strategy.md new file mode 100644 index 0000000..a793900 --- /dev/null +++ b/agents/views_update_strategy.md @@ -0,0 +1,778 @@ +# D3129 Views Document Update Strategy + +## Purpose + +This document captures all discrepancies between the **D3129 Graph Views** LaTeX proposal +(D3129r3, unreleased) and the **graph-v3** reference implementation in +`graph-v3/include/graph/views/` and `graph-v3/include/graph/graph_data.hpp`, along with a +concrete plan to bring the LaTeX document into alignment with the implementation. + +**The implementation is the definitive/authoritative source.** Where the LaTeX and the +implementation disagree, the implementation is correct and the LaTeX must be updated. + +### Relationship to Other Strategy Documents + +- **`gci_update_strategy.md`** defines the fundamental descriptor shift + (`vertex_reference_t` → `vertex_t`, `edge_reference_t` → `edge_t`) and the + `vertex_data`/`edge_data`/`neighbor_data` type renames that originate in D3130. The Views + paper *consumes* those types — it does not define them. This strategy applies the + GCI-defined types to the Views paper. +- **`algo_update_strategy.md`** defines the visitor and weight function convention changes + (`(graph, descriptor)` 2-arg form). The Views paper uses the same 2-arg convention for + value functions, paralleling the algorithm convention. +- Both companion strategies are complete (GCI: committed through Phase J; Algorithms: plan + written). This strategy is the third leg of the update triangle. + +### Scope + +| In scope | Out of scope | +|----------|-------------| +| `D3129_Views/tex/views.tex` — all sections | D3130 GCI paper (handled by `gci_update_strategy.md`) | +| `D3129_Views/src/*.hpp` — all source files | D3128 Algorithms paper (handled by `algo_update_strategy.md`) | +| `D3129_Views/tex/revision.tex` — revision history | Shared tex files (`conventions.tex`, `getting_started.tex`) — separate cross-paper fixup | +| `D3129_Views/tex/config.tex` — version bump | graph-v3 implementation changes | + +--- + +## 0. Fundamental Design Shifts Affecting Views + +Three design shifts from the implementation affect every section of D3129: + +### 0.1 Info Structs → Data Structs + +The most pervasive change is the **rename and redesign** of the three core return types: + +| Old (LaTeX D3129r3) | New (Implementation) | File | +|---------------------|---------------------|------| +| `vertex_info` | `vertex_data` | `graph_data.hpp` | +| `edge_info` | `edge_data` | `graph_data.hpp` | +| `neighbor_info` | `neighbor_data` | `graph_data.hpp` | + +**Key structural differences:** + +1. **Three template parameters → more template parameters.** `vertex_info` had + 2 parameters where `VorVId` was overloaded to mean either a vertex descriptor or a vertex + id. `vertex_data` has 3 parameters with separate `VId` (vertex id type) and + `V` (vertex descriptor type), each independently voidable. + +2. **8 specializations for vertex_data** (vs 2 for vertex_info). The void-combination space + for `{VId, V, VV}` yields 8 specializations (2³), each eliminating its void fields from + the struct. The LaTeX only has `{VorVId, VV}` with 2 specializations. + +3. **16 specializations for edge_data** (in the main template). The void-combination space + for `{VId, Sourced, E, EV}` with VId=void yields additional specializations for + descriptor-based views where no vertex IDs are available. + +4. **`neighbor_data` gains a vertex descriptor parameter `V`.** The old `neighbor_info` + becomes `neighbor_data` — adding explicit support for the target + vertex descriptor, not just its id. + +5. **Member names changed.** `vertex_info::vertex` → `vertex_data::vertex` (same) but + `vertex_data::id` is new (replaces implicit overloading). `edge_info::source` → + `edge_data::source_id`, `edge_info::target` → `edge_data::target_id`, `edge_info::edge` + → `edge_data::edge` (same). + +### 0.2 Value Functions: 1-arg → 2-arg + +| Aspect | LaTeX (D3129r3) | Implementation | +|--------|-----------------|---------------| +| Vertex value function | `vvf(u)` — 1-arg, descriptor only | `vvf(g, u)` — 2-arg, `(const G&, vertex_t)` | +| Edge value function | `evf(uv)` — 1-arg, edge descriptor only | `evf(g, uv)` — 2-arg, `(const G&, edge_t)` | +| Value function concept | Not in LaTeX | `vertex_value_function`, `edge_value_function` | + +The 2-arg form enables stateless lambdas (no capture needed — the graph is a parameter), +which satisfies `semiregular` and enables `std::views` chaining. + +**Impact:** Every code example in the paper that shows `vvf(u)` or `evf(uv)` must change +to `vvf(g, u)` or `evf(g, uv)`. The lambda captures `[&g]` become `[]`. + +### 0.3 Reference Types → Descriptor Types + +| Old (LaTeX) | New (Implementation) | +|-------------|---------------------| +| `vertex_reference_t` | `vertex_t` (descriptor, value type) | +| `edge_reference_t` | `edge_t` (descriptor, value type) | + +All code examples using `vertex_reference_t` must change to `vertex_t`. + +### 0.4 Basic Variants (New) + +The implementation introduces a `basic_` prefix variant for every non-search view. Basic +views omit the descriptor from the structured binding, yielding only IDs (and optional +value). This is **not in the current LaTeX** at all: + +| Standard View | Basic View | Standard Binding | Basic Binding | +|--------------|-----------|-----------------|---------------| +| `vertexlist(g)` | `basic_vertexlist(g)` | `[uid, u]` | `[uid]` | +| `vertexlist(g, vvf)` | `basic_vertexlist(g, vvf)` | `[uid, u, val]` | `[uid, val]` | +| `incidence(g, u)` | `basic_incidence(g, uid)` | `[tid, uv]` | `[tid]` | +| `incidence(g, u, evf)` | `basic_incidence(g, uid, evf)` | `[tid, uv, val]` | `[tid, val]` | +| `neighbors(g, u)` | `basic_neighbors(g, uid)` | `[tid, n]` | `[tid]` | +| `neighbors(g, u, vvf)` | `basic_neighbors(g, uid, vvf)` | `[tid, n, val]` | `[tid, val]` | +| `edgelist(g)` | `basic_edgelist(g)` | `[sid, tid, uv]` | `[sid, tid]` | +| `edgelist(g, evf)` | `basic_edgelist(g, evf)` | `[sid, tid, uv, val]` | `[sid, tid, val]` | + +Basic views are lighter weight — no descriptor materialization. They are the preferred +form when the algorithm only needs vertex/edge IDs. + +### 0.5 Sourced Variants Removed from Search Views + +The LaTeX has `sourced_edges_dfs`, `sourced_edges_bfs`, and `sourced_edges_topological_sort` +variants. **These do not exist in the implementation.** The implementation's edge search +views return `edge_data, EV>` — unsourced, with just the edge +descriptor (no vertex IDs). + +| LaTeX | Implementation | Status | +|-------|---------------|--------| +| `sourced_edges_dfs(g, source)` → `{u, v, uv}` | Not present | **Remove** | +| `sourced_edges_bfs(g, source)` → `{u, v, uv}` | Not present | **Remove** | +| `sourced_edges_topological_sort(g, source)` → `{u, v, uv}` | Not present | **Remove** | + +### 0.6 Search Views: Descriptor-Based Return (No Vertex IDs) + +The LaTeX search views include vertex IDs in structured bindings — e.g., +`vertices_dfs(g,source)` → `vertex_info` → `[v]` where `v` is a descriptor. +The implementation returns `vertex_data, void>` — VId is `void`, so +there is no vertex ID in the binding, only the descriptor. Users can obtain the ID via +`vertex_id(g, v)`. + +Similarly, edge search views return `edge_data, void>` — no +source_id, no target_id (both void), just the edge descriptor. + +This is a deliberate design: search views operate on graph topology via descriptors, not IDs. + +### 0.7 Incoming Edge Variants (New) + +The implementation adds `in_` prefixed variants for per-vertex views via the `in_edge_accessor` +template parameter: + +| New View | Concept Required | Equivalent To | +|---------|-----------------|---------------| +| `in_incidence(g, u)` | `bidirectional_adjacency_list` | `incidence` but traverses incoming edges | +| `basic_in_incidence(g, uid)` | `bidirectional_adjacency_list` | `basic_incidence` for incoming edges | +| `in_neighbors(g, u)` | `bidirectional_adjacency_list` | `neighbors` but returns source vertices | +| `basic_in_neighbors(g, uid)` | `bidirectional_adjacency_list` | `basic_neighbors` for incoming edges | + +These are **not in the current LaTeX**. + +### 0.8 Pipe Syntax / Range Adaptors (New) + +The implementation provides pipe-syntax adaptor objects in `graph::views::adaptors` +(via `adaptors.hpp`). Every view supports `g | view_name(args...)` syntax: + +```cpp +for (auto [uid, u] : g | vertexlist()) { ... } +for (auto [tid, e] : g | incidence(uid)) { ... } +for (auto [v] : g | vertices_dfs(seed)) { ... } +for (auto [uv] : g | edges_bfs(seed, evf)) { ... } +``` + +This is **not in the current LaTeX**. + +--- + +## 1. Section-by-Section Discrepancies + +### 1.1 Introduction (lines 1–30 of views.tex) + +| Issue | Action | +|-------|--------| +| `\phil` notes reference `basic_index_adjacency_list` | Remove — concept no longer exists. Views use `adjacency_list` or `index_adjacency_list`. | +| `\phil` note "Group views by basic first" | Resolve: the implementation has `basic_` variants. Decide on presentation order. | +| `\phil` note "Use `&&` instead of `const&` for value function parameters" | The implementation uses `VVF&&` / `EVF&&` (forwarding references). Document this. | +| `\phil` note "Can `std::ref` be used for the value function?" | Resolve or remove. The 2-arg value function convention makes this moot — stateless lambdas don't need `ref`. | +| Prose references "View Return Types" | Update to reference `vertex_data`, `edge_data`, `neighbor_data`. | +| Old comment block about consolidating views (lines 15–22) | Review for relevance; delete or update. The `basic_` split in the implementation addresses this. | + +### 1.2 Info Structs Section (lines 31–195) + +This is the "Info Structs (Return Types)" section. It needs a complete rewrite. + +#### 1.2.1 `vertex_info` → `vertex_data` + +| Aspect | LaTeX | Implementation | Change | +|--------|-------|---------------|--------| +| Name | `vertex_info` | `vertex_data` | Rename + add V parameter | +| Template params | 2 (`VorVId`, `VV`) | 3 (`VId`, `V`, `VV`) | Add vertex descriptor param | +| Specializations | 2 (VV=void) | 8 (all {VId,V,VV} void combos) | Expand table | +| Member `vertex` comment | "e.g. vertex_reference_t" | "e.g. vertex_t (vertex descriptor)" | Update type reference | +| Source file | `vertex_info.hpp` | N/A (defined in `graph_data.hpp`) | Rewrite source file | + +#### 1.2.2 `edge_info` → `edge_data` + +| Aspect | LaTeX | Implementation | Change | +|--------|-------|---------------|--------| +| Name | `edge_info` | `edge_data` | Rename | +| Member names | `source`, `target` | `source_id`, `target_id` | Rename members | +| Member type names | `source_type`, `target_type` | `source_id_type`, `target_id_type` | Rename type aliases | +| `edge_type` comment | "e.g. edge_reference_t" | "e.g. edge_t (edge descriptor)" | Update | +| Source file | `edge_info.hpp` | N/A (defined in `graph_data.hpp`) | Rewrite source file | + +#### 1.2.3 `neighbor_info` → `neighbor_data` + +| Aspect | LaTeX | Implementation | Change | +|--------|-------|---------------|--------| +| Name | `neighbor_info` | `neighbor_data` | Rename + add V parameter | +| Template params | 3 (`VorVId`, `Sourced`, `VV`) | 4 (`VId`, `Sourced`, `V`, `VV`) | Add vertex descriptor param | +| Member names | `source`, `target` | `source_id`, `target_id`, `target` (vertex descriptor) | Split target from target_id | +| Source file | `neighbor_info.hpp` | N/A (defined in `graph_data.hpp`) | Rewrite source file | + +#### 1.2.4 Code Examples + +All introductory code examples (lines 39–78 of views.tex) need updating: + +| Old Code | New Code | +|----------|----------| +| `vertex_reference_t u = uu.vertex;` | `vertex_t u = uu.vertex;` | +| `auto vvf = [&g](vertex_reference_t u) { return vertex_value(g,u); };` | `auto vvf = [](const auto& g, vertex_t u) { return vertex_value(g,u); };` | +| `// type is vertex_info, void>` | `// type is vertex_data, vertex_t, void>` | +| `for(auto&& uu : vertexlist(g))` — `uu.vertex` | `for(auto&& [uid, u] : vertexlist(g))` — now yields id + descriptor | +| `for(auto&& [u] : vertexlist(g))` | `for(auto&& [uid, u] : vertexlist(g))` — two bindings now | +| `for(auto&& [u, value] : vertexlist(g, vvf))` | `for(auto&& [uid, u, val] : vertexlist(g, vvf))` — three bindings now | + +**Critical change:** In the old design, `vertexlist(g)` yielded `[u]` (just the descriptor). +In the implementation, `vertexlist(g)` yields `[uid, u]` (vertex id + descriptor). This is +because `vertex_data` always includes the id when VId≠void. + +#### 1.2.5 Copyable Info Structs (Commented-Out Section) + +Lines ~200–240 contain a `\begin{comment}...\end{comment}` block about copyable info +structs. The implementation has `copyable_vertex_t`, `copyable_edge_t`, +and `copyable_neighbor_t` type aliases. **Decision needed**: un-comment and update, +or leave out. The copyable aliases are used by algorithms and views internally. + +--- + +### 1.3 Graph Views — vertexlist (lines ~245–270) + +| Aspect | LaTeX | Implementation | Change | +|--------|-------|---------------|--------| +| Concept | Not specified | `adjacency_list` (descriptor overloads), `index_adjacency_list` (iterator/id overloads) | Document | +| `vertexlist(g)` return | `vertex_info` → `[u]` | `vertex_data` → `[uid, u]` | **Breaking**: now 2 bindings | +| `vertexlist(g,vvf)` return | `vertex_info` → `[u,val]` | `vertex_data` → `[uid, u, val]` | **Breaking**: now 3 bindings | +| VVF convention | `vvf(u)` — 1-arg | `vvf(g, u)` — 2-arg | Update | +| `basic_vertexlist(g)` | **Not in LaTeX** | `vertex_data` → `[uid]` | **Add** | +| `basic_vertexlist(g,vvf)` | **Not in LaTeX** | `vertex_data` → `[uid, val]` | **Add** | +| Iterator/subrange overloads | `vertexlist(g,first,last)`, `vertexlist(g,vr)` | Same pattern, plus basic variants | Update + add basic | +| Iterator type | Not specified | `forward_iterator`, sized, common range | Document | +| Pipe syntax | Not in LaTeX | `g \| vertexlist()`, `g \| basic_vertexlist()` | **Add** | + +### 1.4 Graph Views — incidence (lines ~272–295) + +| Aspect | LaTeX | Implementation | Change | +|--------|-------|---------------|--------| +| `incidence(g,u)` return | `edge_info` → `[uv]` | `edge_data` → `[tid, uv]` | **Breaking**: now 2 bindings | +| `incidence(g,u,evf)` return | `edge_info` → `[uv,val]` | `edge_data` → `[tid, uv, val]` | **Breaking**: now 3 bindings | +| EVF convention | `evf(uv)` — 1-arg | `evf(g, uv)` — 2-arg | Update | +| `basic_incidence(g,uid)` | **Not in LaTeX** | `edge_data` → `[tid]` | **Add** | +| `basic_incidence(g,uid,evf)` | **Not in LaTeX** | `edge_data` → `[tid, val]` | **Add** | +| `in_incidence(g,u)` | **Not in LaTeX** | Same types, incoming edges | **Add** (requires `bidirectional_adjacency_list`) | +| `basic_in_incidence(g,uid)` | **Not in LaTeX** | Same as basic, incoming | **Add** | +| "Since the source vertex `u` is available..." prose | Present | Still true — source is implicit | Keep but update references | +| Pipe syntax | Not in LaTeX | `g \| incidence(uid)` | **Add** | + +### 1.5 Graph Views — neighbors (lines ~297–318) + +| Aspect | LaTeX | Implementation | Change | +|--------|-------|---------------|--------| +| `neighbors(g,uid)` return | `neighbor_info` → `[v]` | `neighbor_data` → `[tid, n]` | **Breaking**: now 2 bindings | +| `neighbors(g,uid,vvf)` return | `neighbor_info` → `[v,val]` | `neighbor_data` → `[tid, n, val]` | **Breaking**: now 3 bindings | +| Value function | `vvf(u)` — 1-arg | `vvf(g, u)` — 2-arg, vertex_value_function | Update | +| `basic_neighbors(g,uid)` | **Not in LaTeX** | `neighbor_data` → `[tid]` | **Add** | +| `basic_neighbors(g,uid,vvf)` | **Not in LaTeX** | `neighbor_data` → `[tid, val]` | **Add** | +| `in_neighbors(g,u)` | **Not in LaTeX** | Same types, incoming direction | **Add** | +| `basic_in_neighbors(g,uid)` | **Not in LaTeX** | Same as basic, incoming | **Add** | +| Pipe syntax | Not in LaTeX | `g \| neighbors(uid)` | **Add** | + +### 1.6 Graph Views — edgelist (lines ~320–340) + +| Aspect | LaTeX | Implementation | Change | +|--------|-------|---------------|--------| +| `edgelist(g)` return | `edge_info` → `[u,v,uv]` | `edge_data` → `[sid, tid, uv]` | Binding names change; VId replaces V | +| `edgelist(g,evf)` return | `edge_info` → `[u,v,uv,val]` | `edge_data` → `[sid, tid, uv, val]` | Same pattern | +| EVF convention | `evf(uv)` — 1-arg | `evf(g, uv)` — 2-arg | Update | +| `basic_edgelist(g)` | **Not in LaTeX** | `edge_data` → `[sid, tid]` | **Add** | +| `basic_edgelist(g,evf)` | **Not in LaTeX** | `edge_data` → `[sid, tid, val]` | **Add** | +| Edgelist concept reference | `basic_sourced_index_edgelist` | Same | Verify alignment with GCI | +| Iterator type | Not specified | `forward_iterator`, conditionally sized | Document | +| Pipe syntax | Not in LaTeX | `g \| edgelist()` | **Add** | + +### 1.7 "Search" Views — Common Types (lines ~343–395) + +| Aspect | LaTeX | Implementation | Change | +|--------|-------|---------------|--------| +| `cancel_search` enum | `cancel_search : int8_t { continue_search, cancel_branch, cancel_all }` | Same definition in `search_base.hpp` | Verify alignment | +| `cancel(search, cancel_search)` | Free function `cancel(S, cancel_search)` | Member function `search.cancel(cancel_search)` | **Change to member** | +| `depth(search)` | Free function `depth(S)` → integral | Member function `search.depth()` → `size_t` | **Change to member** | +| `size(search)` | Free function `size(S)` → integral | Member `search.num_visited()` → `size_t` | **Rename**: `size` → `num_visited` | +| `search_view` concept | Not in LaTeX | `requires { v.cancel(); cv.depth(); cv.num_visited(); }` | **Add** | +| `visited_tracker` | Not in LaTeX | Exposition-only helper class | Consider mentioning | +| Code example (lines 390–402) | Uses `depth(dfs)`, `cancel(dfs, ...)`, `size(dfs)` | Use `dfs.depth()`, `dfs.cancel(...)`, `dfs.num_visited()` | Update | +| Prose about `size(dfs)` vs `depth(dfs)` | Present | Replace `size` with `num_visited` in prose | Update | +| Prose about edgelist concept for sourced views | References sourced view producing edgelist-compatible ranges | Sourced search views removed — delete this prose | **Remove** | + +### 1.8 DFS Views (lines ~405–440) + +| Aspect | LaTeX | Implementation | Change | +|--------|-------|---------------|--------| +| `vertices_dfs(g,source)` return | `vertex_info` → `[v]` | `vertex_data` → `[v]` | Names differ but binding compatible | +| `vertices_dfs(g,source,vvf)` return | `vertex_info` → `[v,val]` | `vertex_data` → `[v, val]` | Update type name | +| `edges_dfs(g,source)` return | `edge_info` → `[v,uv]` | `edge_data` → `[uv]` | **Breaking**: was `[v,uv]`, now `[uv]` only | +| `edges_dfs(g,source,evf)` return | `edge_info` → `[v,uv,val]` | `edge_data` → `[uv, val]` | **Breaking**: was `[v,uv,val]`, now `[uv, val]` | +| `sourced_edges_dfs(g,source)` | `edge_info` → `[u,v,uv]` | **Does not exist** | **Remove** | +| `sourced_edges_dfs(g,source,evf)` | `edge_info` → `[u,v,uv,val]` | **Does not exist** | **Remove** | +| VVF/EVF convention | 1-arg | 2-arg | Update | +| Seed parameter type | `source` (vertex_id) | `seed` as either `vertex_id_t` or `vertex_t` | Update — implementation accepts both | +| Allocator parameter | "Removed" per r0 revision, then "Restored" per r1 | Present in implementation, disambiguated from VVF via concept | Ensure allocator overloads documented | +| Iterator type | Not specified | `input_iterator`, single-pass, sentinel-based | Document | +| `\phil` notes about event enum bitset | Present | Not in implementation | Remove or move to future work | +| Pipe syntax | Not in LaTeX | `g \| vertices_dfs(seed)` | **Add** | + +### 1.9 BFS Views (lines ~450–487) + +Identical structural changes as DFS (§1.8): + +| Aspect | LaTeX | Implementation | Change | +|--------|-------|---------------|--------| +| `vertices_bfs` | Same changes as `vertices_dfs` | Same | Apply same updates | +| `edges_bfs(g,source)` | `[v,uv]` | `[uv]` | **Breaking**: descriptor only | +| `sourced_edges_bfs(...)` | Present | **Does not exist** | **Remove** | +| `\phil` note about `depth_limit` parameter | Present | Not in implementation | Remove or move to future work | +| `\phil` notes about event enum bitset | Present | Not in implementation | Remove | +| Pipe syntax | Not in LaTeX | Present in implementation | **Add** | + +### 1.10 Topological Sort Views (lines ~489–522) + +| Aspect | LaTeX | Implementation | Change | +|--------|-------|---------------|--------| +| Seed parameter | `source` — single source vertex | **No seed** — processes all vertices | **Breaking change** | +| `vertices_topological_sort(g,source)` | 2-arg | `vertices_topological_sort(g)` — 1-arg | Remove source param | +| `edges_topological_sort(g,source)` | 2-arg | `edges_topological_sort(g)` — 1-arg | Remove source param | +| `sourced_edges_topological_sort(...)` | Present | **Does not exist** | **Remove** | +| `_safe` cycle-detection factories | **Not in LaTeX** | Returns `tl::expected>` | **Add** | +| Iterator type | Not specified | **`forward_iterator`** (eagerly computed) | Document — differs from DFS/BFS | +| `depth()` member | Implied by "search views" section | **Not available** — topo sort has no tree depth | Clarify: topo sort does NOT satisfy `search_view` | +| `cancel()` member | Implied | Present, but `cancel_branch` = `cancel_all` (flat ordering) | Document | +| Pipe syntax | Not in LaTeX | `g \| vertices_topological_sort()` | **Add** | + +--- + +## 2. New Content Not in LaTeX + +### 2.1 Transpose View + +The implementation has `transpose_view` (in `views/transpose.hpp`) — a zero-cost wrapper +for bidirectional graphs that swaps outgoing/incoming edge traversal: + +```cpp +auto tv = transpose(g); // transpose_view +// edges(tv, v) → in_edges(g, v) +// in_edges(tv, v) → edges(g, v) +// target_id(tv, e) → source_id(g, e) and vice versa +``` + +Requires `bidirectional_adjacency_list`. Not a range itself — used as a graph wrapper +passed to other views and algorithms. + +**Action:** Add a new subsection for `transpose` in the Graph Views section. + +### 2.2 Edge Accessor Pattern + +The implementation parameterizes per-vertex views (`incidence`, `neighbors`, BFS, DFS, +topological sort) on an `Accessor` template parameter: + +| Accessor | `edges()` call | `neighbor_id()` call | Constraint | +|----------|---------------|---------------------|-----------| +| `out_edge_accessor` (default) | `out_edges(g, u)` | `target_id(g, e)` | `adjacency_list` | +| `in_edge_accessor` | `in_edges(g, u)` | `source_id(g, e)` | `bidirectional_adjacency_list` | + +This is the mechanism behind the `in_incidence`, `in_neighbors` etc. factory functions. + +**Action:** Decide whether to expose the accessor pattern in the paper (as exposition-only +infrastructure) or simply document the `in_` factory function variants without explaining +the mechanism. + +### 2.3 View Concepts + +The implementation defines a `search_view` concept: + +```cpp +template +concept search_view = requires(V& v, const V& cv) { + { v.cancel() } -> std::convertible_to; + { cv.depth() } -> std::convertible_to; + { cv.num_visited() } -> std::convertible_to; +}; +``` + +Satisfied by DFS and BFS views but **NOT** by topological sort (which has no `depth()`). + +**Action:** Add `search_view` concept to the Common Types section. Document which views +satisfy it and which do not. + +### 2.4 Value Function Concepts + +The implementation defines formal concepts for value functions: + +```cpp +template +concept vertex_value_function = + std::invocable && + (!std::is_void_v>); + +template +concept edge_value_function = + std::invocable && + (!std::is_void_v>); +``` + +These are used in view factory function constraints and are defined in D3130 (GCI). The +Views paper should reference them. + +**Action:** Reference `vertex_value_function` and `edge_value_function` from D3130, and +show their use in view constraints. + +### 2.5 Allocator Disambiguation + +Search view factories accept an optional allocator parameter that is disambiguated from +value functions using a `requires(!vertex_value_function)` constraint: + +```cpp +template + requires(!vertex_value_function>) +auto vertices_dfs(G& g, vertex_id_t seed, Alloc alloc); +``` + +**Action:** Document the allocator parameter and its disambiguation. This was "restored" +in r1 but currently under-specified in the prose. + +### 2.6 Pipe Syntax (Range Adaptors) + +All views support C++20 pipe syntax via adaptor objects: + +```cpp +// Basic views +for (auto [uid, u] : g | vertexlist()) { ... } +for (auto [tid, uv] : g | incidence(uid)) { ... } +for (auto [tid, n] : g | neighbors(uid)) { ... } +for (auto [sid, tid, uv]: g | edgelist()) { ... } + +// Search views +for (auto [v] : g | vertices_dfs(seed)) { ... } +for (auto [uv] : g | edges_bfs(seed)) { ... } +for (auto [v] : g | vertices_topological_sort()) { ... } + +// Chaining with standard range adaptors +for (auto id : g | vertexlist() + | std::views::transform(...) + | std::views::filter(...)) { ... } +``` + +**Action:** Add a new subsection documenting pipe syntax support and adaptor objects. + +--- + +## 3. Source File Updates + +### 3.1 Files to Delete and Rewrite + +| Old File | Action | New Content | +|----------|--------|-------------| +| `D3129_Views/src/vertex_info.hpp` | **Rewrite** → `vertex_data.hpp` | `vertex_data` primary template + key specializations | +| `D3129_Views/src/edge_info.hpp` | **Rewrite** → `edge_data.hpp` | `edge_data` primary template + key specializations | +| `D3129_Views/src/neighbor_info.hpp` | **Rewrite** → `neighbor_data.hpp` | `neighbor_data` primary template + key specializations | + +**Note:** The full implementation has many specializations (8 for vertex_data, 16+ for +edge_data). For the paper, show the primary template and a representative subset of +specializations. Use exposition-only commentary for the pattern. + +### 3.2 New Source Files to Add + +| File | Content | Used By | +|------|---------|---------| +| `copyable_types.hpp` | `copyable_vertex_t`, `copyable_edge_t`, `edgelist_edge` | Multiple sections | +| `cancel_search.hpp` | `cancel_search` enum | Common search types section | + +**Decision needed:** Whether to add separate source files for these or inline them in the +LaTeX. The GCI strategy used `\lstinputlisting` for all code; maintain consistency. + +--- + +## 4. Cross-Paper References + +### 4.1 References to D3130 (GCI) + +The Views paper references GCI-defined types. These references need updating: + +| Old Reference | New Reference | +|--------------|--------------| +| `vertex_reference_t` | `vertex_t` | +| `edge_reference_t` | `edge_t` | +| `vertex_info` | `vertex_data` (defined in D3130) | +| `edge_info` | `edge_data` (defined in D3130) | +| `neighbor_info` | `neighbor_data` (defined in D3130) | +| `edges(g,u)` | `out_edges(g,u)` (with `edges` as alias) | +| `degree(g,u)` | `out_degree(g,u)` (with `degree` as alias) | +| `basic_adjacency_list` | **Removed** — use `adjacency_list` | +| `basic_index_adjacency_list` | **Removed** — use `index_adjacency_list` | +| `basic_sourced_adjacency_list` | **Removed** | +| `sourced_adjacency_list` | **Removed** | + +### 4.2 References to D3128 (Algorithms) + +The search views overlap with algorithm concerns: + +| Aspect | Action | +|--------|--------| +| DFS/BFS visitor events vs search view events | Cross-reference D3128 visitor events. Note that search views are an alternative to visitor-based traversal. | +| Topological sort algorithm vs view | Cross-reference D3128's `topological_sort()` algorithm. Note the algorithm returns `bool` for cycle detection; the view offers a `_safe` factory returning `expected`. | + +### 4.3 Shared `conventions.tex` Updates + +The conventions table (`tex/conventions.tex`) contains entries that apply to views: + +| Entry | Current | Needed Update | +|-------|---------|---------------| +| VVF description | `vvf(u)` → vertex value | `vvf(g, u)` → vertex value (2-arg) | +| EVF description | `evf(uv)` → edge value | `evf(g, uv)` → edge value (2-arg) | +| `graph_reference_t` row | Present | Remove (not in implementation) | +| `vertex_edge_range_t` for ER | Present | Update to note `out_edge_range_t` as primary | + +**Note:** `conventions.tex` is shared across all papers and should be updated in a +cross-paper fixup phase (like Phase J in the GCI plan). + +--- + +## 5. Open Questions + +### Q1 — Specialization Presentation + +**Question:** The implementation has 8 `vertex_data` specializations, 16+ `edge_data` +specializations, and 12+ `neighbor_data` specializations. How many should the paper show? + +**Options:** +- (a) Show all specializations exhaustively (accurate but verbose) +- (b) Show primary template + key specializations used by views (the LaTeX's current + approach with a members table) +- (c) Show primary template only with a prose explanation of the void-elimination pattern + +**Recommendation:** (b) — matches the existing approach and keeps the paper readable. +Show ~4 key specializations per type (the ones views actually produce), reference the +implementation for the complete set. + +### Q2 — Basic View Presentation + +**Question:** Should `basic_` variants be presented alongside or separately from standard views? + +**Options:** +- (a) Each view subsection shows both standard and basic variants in the same table +- (b) Group all basic views in a separate section +- (c) Show standard views first, then a single "Basic View Variants" subsection listing all + +**Recommendation:** (a) — keeps related information together. Use a horizontal divider +in each view's table to separate standard from basic rows. + +### Q3 — Pipe Syntax Presentation + +**Question:** How should pipe syntax be presented? + +**Options:** +- (a) A single "Range Adaptors" subsection listing all adaptor objects +- (b) Each view's subsection shows its pipe syntax alongside the function call syntax +- (c) Both — show pipe in each subsection with a summary section + +**Recommendation:** (c) — show pipe syntax in each view table via an additional column or +examples, plus a summary "Range Adaptors" section listing all adaptor objects. + +### Q4 — `tl::expected` Dependency + +**Question:** The topological sort `_safe` factories return `tl::expected>`. +The standard has `std::expected` since C++23. Should the paper: + +**Options:** +- (a) Use `std::expected` (C++23 feature) +- (b) Use an exposition-only `expected` type +- (c) Use a different error reporting mechanism (e.g., `optional>` error output) + +**Recommendation:** (a) — the graph library targets C++23 or later; `std::expected` is +available. If C++20 compatibility is needed, use exposition-only. + +### Q5 — Incoming Edge Search Views + +**Question:** The implementation parameterizes BFS, DFS, and topo sort on an `Accessor` but +does not expose `in_vertices_dfs`, `in_edges_bfs`, etc. factory functions. Should the paper +document the accessor mechanism and/or request incoming-edge search variants? + +**Options:** +- (a) Document only what exists (outgoing search views only) +- (b) Document the accessor mechanism as exposition-only and note that incoming variants + are possible future extensions +- (c) Add incoming search view factories (requires implementation work) + +**Recommendation:** (b) — document the mechanism for completeness, note future extensibility. + +### Q6 — Event Enum / Coroutine-Style Events + +**Question:** Multiple `\phil` notes suggest adding an event enum bitset to search views for +coroutine-style event reporting. The implementation does not have this. + +**Options:** +- (a) Remove all `\phil` notes about event enums +- (b) Add a "Future Directions" note +- (c) Implement the feature first + +**Recommendation:** (a) — remove the notes. This is a future direction that can be proposed +separately. Keep the current visitor-based approach (D3128) and search-view approach (D3129) +as complementary patterns. + +### Q7 — Search View Binding Fields + +**Question:** Search views in the implementation return `vertex_data` for +vertex views (binding: `[v]`) and `edge_data` for edge views +(binding: `[uv]`). The VId is `void` — no vertex id in the binding. Should the paper +explicitly document this design choice and the rationale? + +**Recommendation:** Yes — add a brief "Design Note" paragraph explaining that search views +yield descriptors rather than IDs, because the search context is per-graph (the user already +knows which graph) and descriptors provide richer access via CPOs (`vertex_id(g, v)`, +`vertex_value(g, v)`, etc.). + +--- + +## 6. Implementation Inventory + +### 6.1 View File → LaTeX Section Mapping + +| Implementation File | Purpose | LaTeX Section | +|--------------------|---------|---------------| +| `views/vertexlist.hpp` | Vertex iteration | §3 vertexlist Views | +| `views/incidence.hpp` | Per-vertex edge iteration | §3 incidence Views | +| `views/neighbors.hpp` | Per-vertex neighbor iteration | §3 neighbors Views | +| `views/edgelist.hpp` | All-edges iteration | §3 edgelist Views | +| `views/dfs.hpp` | DFS vertex/edge traversal | §4 DFS Views | +| `views/bfs.hpp` | BFS vertex/edge traversal | §4 BFS Views | +| `views/topological_sort.hpp` | Topological ordering | §4 Topological Sort Views | +| `views/search_base.hpp` | Shared search infrastructure | §4 Common Types | +| `views/view_concepts.hpp` | `search_view` concept | §4 Common Types | +| `views/transpose.hpp` | Direction-swapping adaptor | New §3 or §5 | +| `views/edge_accessor.hpp` | Direction parameterization | Exposition-only | +| `views/adaptors.hpp` | Pipe syntax support | New §5 or integrated | +| `views/basic_views.hpp` | Convenience header | Not a separate section | +| `graph_data.hpp` | `vertex_data`, `edge_data`, `neighbor_data` | §2 Data Structs | + +### 6.2 Test Coverage Reference + +The implementation has comprehensive tests that can be used to verify behavior: + +| Test File | Validates | +|-----------|----------| +| `tests/views/test_basic_views.cpp` | Basic view factories | +| `tests/views/test_incidence.cpp` | Incidence view | +| `tests/views/test_basic_incidence.cpp` | Basic incidence view | +| `tests/views/test_neighbors.cpp` | Neighbors view | +| `tests/views/test_basic_neighbors.cpp` | Basic neighbors view | +| `tests/views/test_edgelist.cpp` | Edgelist view | +| `tests/views/test_basic_edgelist.cpp` | Basic edgelist view | +| `tests/views/test_dfs.cpp` | DFS search views | +| `tests/views/test_bfs.cpp` | BFS search views | +| `tests/views/test_topological_sort.cpp` | Topological sort views | +| `tests/views/test_search_base.cpp` | Search infrastructure | +| `tests/views/test_adaptors.cpp` | Pipe syntax | +| `tests/views/test_reverse_traversal.cpp` | Incoming edge views | +| `tests/views/test_view_chaining.cpp` | View composition | +| `tests/views/test_edge_data.cpp` | Edge data structs | +| `tests/views/test_neighbor_data.cpp` | Neighbor data structs | + +--- + +## 7. Summary of All Changes by Type + +### 7.1 Renames + +| Old | New | Occurrences (est.) | +|-----|-----|--------------------| +| `vertex_info` | `vertex_data` | ~30 | +| `edge_info` | `edge_data` | ~40 | +| `neighbor_info` | `neighbor_data` | ~10 | +| `vertex_reference_t` | `vertex_t` | ~5 | +| `edge_reference_t` | `edge_t` | ~5 | +| `.source` member | `.source_id` member | ~5 | +| `.target` member | `.target_id` member | ~5 | +| `size(search)` | `search.num_visited()` | ~3 | +| `cancel(search, x)` | `search.cancel(x)` | ~3 | +| `depth(search)` | `search.depth()` | ~3 | + +### 7.2 Additions + +| Addition | Sections Affected | +|----------|------------------| +| `basic_` view variants (all 4 basic views) | vertexlist, incidence, neighbors, edgelist | +| `in_` view variants (incidence, neighbors) | incidence, neighbors | +| `_safe` topological sort factories | Topological sort | +| `transpose` view | New section | +| Pipe syntax / range adaptors | All sections | +| `search_view` concept | Common types | +| `vertex_value_function` / `edge_value_function` concepts | Introduction or referenced from GCI | +| Allocator parameter documentation | DFS, BFS, topological sort | +| Edge accessor exposition | Common types or exposition-only | +| Vertex ID in all basic view bindings | vertexlist, incidence, neighbors, edgelist | + +### 7.3 Removals + +| Removal | Sections Affected | +|---------|------------------| +| `sourced_edges_dfs` | DFS | +| `sourced_edges_bfs` | BFS | +| `sourced_edges_topological_sort` | Topological sort | +| Source/seed parameter from topological sort | Topological sort | +| All `\phil` notes | All sections | +| Free function `cancel()`, `depth()`, `size()` — replaced by members | Common types | + +### 7.4 Structural Changes + +| Change | Impact | +|--------|--------| +| `vertex_info` (2 params) → `vertex_data` (3 params) | All vertex views gain an extra binding field (uid) | +| `neighbor_info` (3 params) → `neighbor_data` (4 params) | Neighbor views gain both id and descriptor | +| Value functions: 1-arg → 2-arg | All value function examples and signatures change | +| Search views: vertex ID in binding → descriptor only (VId=void) | DFS, BFS, topological sort edge views lose target_id binding | +| Topological sort: seeded → all-vertex | Signature and usage examples change fundamentally | + +--- + +## 8. Revision History Entry (for D3129r3) + +Draft entry for `revision.tex`: + +```latex +\subsection*{\paperno r3} +\begin{itemize} + \item Renamed \tcode{vertex_info}, \tcode{edge_info}, and \tcode{neighbor_info} to + \tcode{vertex_data}, \tcode{edge_data}, and \tcode{neighbor_data} respectively, + with the addition of separate vertex ID and vertex descriptor template parameters. + \item Updated all value functions from 1-arg \tcode{vvf(u)}/\tcode{evf(uv)} form to + 2-arg \tcode{vvf(g,u)}/\tcode{evf(g,uv)} form, taking the graph as the first + parameter. + \item Added \tcode{basic\_} view variants (\tcode{basic\_vertexlist}, + \tcode{basic\_incidence}, \tcode{basic\_neighbors}, \tcode{basic\_edgelist}) that + yield only vertex/edge IDs without descriptors. + \item Added incoming-edge view variants (\tcode{in\_incidence}, + \tcode{in\_neighbors}) for bidirectional graphs. + \item Added \tcode{transpose} view for direction-swapping graph adaption. + \item Added pipe syntax support via range adaptors for all view functions. + \item Added \tcode{\_safe} topological sort factories with cycle detection + via \tcode{std::expected}. + \item Changed topological sort from seeded (single source) to all-vertex traversal. + \item Removed \tcode{sourced\_edges\_dfs}, \tcode{sourced\_edges\_bfs}, and + \tcode{sourced\_edges\_topological\_sort} — sourced search variants are no longer + in the implementation. + \item Changed search view control from free functions (\tcode{cancel()}, \tcode{depth()}, + \tcode{size()}) to member functions (\tcode{.cancel()}, \tcode{.depth()}, + \tcode{.num\_visited()}). + \item Added \tcode{search\_view} concept. + \item Replaced all uses of \tcode{vertex\_reference\_t} with \tcode{vertex\_t} + and \tcode{edge\_reference\_t} with \tcode{edge\_t}, consistent with the + descriptor-based architecture defined in D3130. + \item Documented allocator parameters for search views (DFS, BFS, topological sort). +\end{itemize} +``` From 22d6b26ebff4c40d57416e7ebfd1cd5b56aa891e Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 17:32:06 -0400 Subject: [PATCH 02/22] =?UTF-8?q?views=5Fupdate=5Fstrategy:=20resolve=20al?= =?UTF-8?q?l=20Section=205=20open=20questions=20(Q1=E2=80=93Q7)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- agents/views_update_strategy.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/agents/views_update_strategy.md b/agents/views_update_strategy.md index a793900..677ff9a 100644 --- a/agents/views_update_strategy.md +++ b/agents/views_update_strategy.md @@ -569,8 +569,10 @@ implementation for the complete set. - (b) Group all basic views in a separate section - (c) Show standard views first, then a single "Basic View Variants" subsection listing all -**Recommendation:** (a) — keeps related information together. Use a horizontal divider -in each view's table to separate standard from basic rows. +**Decision:** (a) — keeps related information together. Use a horizontal divider +in each view's table to separate standard from basic rows, provided the table fits +on the page. If a combined table is too wide or tall, split basic variants into a +separate follow-on table within the same subsection. ### Q3 — Pipe Syntax Presentation @@ -581,7 +583,7 @@ in each view's table to separate standard from basic rows. - (b) Each view's subsection shows its pipe syntax alongside the function call syntax - (c) Both — show pipe in each subsection with a summary section -**Recommendation:** (c) — show pipe syntax in each view table via an additional column or +**Decision:** (c) — show pipe syntax in each view table via an additional column or examples, plus a summary "Range Adaptors" section listing all adaptor objects. ### Q4 — `tl::expected` Dependency @@ -594,8 +596,9 @@ The standard has `std::expected` since C++23. Should the paper: - (b) Use an exposition-only `expected` type - (c) Use a different error reporting mechanism (e.g., `optional>` error output) -**Recommendation:** (a) — the graph library targets C++23 or later; `std::expected` is -available. If C++20 compatibility is needed, use exposition-only. +**Decision:** (b) — use an exposition-only `expected` type to avoid a hard C++23 +dependency. This keeps the paper compatible with C++20 while conveying the intended +semantics. ### Q5 — Incoming Edge Search Views @@ -609,7 +612,8 @@ document the accessor mechanism and/or request incoming-edge search variants? are possible future extensions - (c) Add incoming search view factories (requires implementation work) -**Recommendation:** (b) — document the mechanism for completeness, note future extensibility. +**Decision:** (b) — document the accessor mechanism as exposition-only and note that +incoming variants are possible future extensions. ### Q6 — Event Enum / Coroutine-Style Events @@ -621,9 +625,9 @@ coroutine-style event reporting. The implementation does not have this. - (b) Add a "Future Directions" note - (c) Implement the feature first -**Recommendation:** (a) — remove the notes. This is a future direction that can be proposed -separately. Keep the current visitor-based approach (D3128) and search-view approach (D3129) -as complementary patterns. +**Decision:** (a) — remove all `\phil` notes about event enums. This is a future +direction that can be proposed separately. Keep the current visitor-based approach +(D3128) and search-view approach (D3129) as complementary patterns. ### Q7 — Search View Binding Fields @@ -632,7 +636,7 @@ vertex views (binding: `[v]`) and `edge_data` for edge vie (binding: `[uv]`). The VId is `void` — no vertex id in the binding. Should the paper explicitly document this design choice and the rationale? -**Recommendation:** Yes — add a brief "Design Note" paragraph explaining that search views +**Decision:** Yes — add a brief "Design Note" paragraph explaining that search views yield descriptors rather than IDs, because the search context is per-graph (the user already knows which graph) and descriptors provide richer access via CPOs (`vertex_id(g, v)`, `vertex_value(g, v)`, etc.). From 2071d35efad9dc459afb3f5d72e65c20d7a57786 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 18:24:46 -0400 Subject: [PATCH 03/22] Add views update plan; update strategy Q4 with C++23/C++20 backward compat and D3126 cross-paper note --- agents/views_update_plan.md | 705 ++++++++++++++++++++++++++++++++ agents/views_update_strategy.md | 47 ++- 2 files changed, 741 insertions(+), 11 deletions(-) create mode 100644 agents/views_update_plan.md diff --git a/agents/views_update_plan.md b/agents/views_update_plan.md new file mode 100644 index 0000000..3437fec --- /dev/null +++ b/agents/views_update_plan.md @@ -0,0 +1,705 @@ +# D3129 Views — Implementation Plan + +**Source of truth:** `agents/views_update_strategy.md` +**Target document:** `D3129_Views/tex/views.tex` and all `D3129_Views/src/*.hpp` +**Reference implementation:** `graph-v3/include/graph/views/` and `graph-v3/include/graph/graph_data.hpp` + +All changes are applied to D3129r3 before publication. The implementation is the definitive +source; the LaTeX must conform to it. + +--- + +## Governance + +| Item | Value | +|------|-------| +| Strategy | `agents/views_update_strategy.md` | +| Branch | `view_paper` (P1709 repo) | +| Authoritative source | graph-v3 implementation | +| Scope | D3129 paper + source files | +| Verification | LaTeX compiles (`latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex`), no broken `\lstinputlisting` | + +### Commit discipline + +Each phase ends with a commit. Phases are ordered so every intermediate commit leaves +the LaTeX compilable (possibly with `\phil` TODO notes for forward references, but no +broken `\lstinputlisting` or undefined `\tcode` references). + +### Verification gates + +| Gate | Command | When | +|------|---------|------| +| LaTeX builds | `latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex` in P1709 | After every phase | + +--- + +## Phase overview + +| Phase | Name | Depends on | Risk | Status | +|-------|------|------------|------|--------| +| A | Source file rewrite (data structs) | — | Low — 3 small `.hpp` files | Not started | +| B | Data structs section rewrite | A | Medium — largest prose rewrite, tables | Not started | +| C | Graph views update (vertexlist, incidence, neighbors, edgelist) | B | Medium — table + prose changes | Not started | +| D | Search common types update | B | Low — enum + member functions | Not started | +| E | DFS / BFS views update | C, D | Medium — removals + binding changes | Not started | +| F | Topological sort views update | C, D | Medium — signature changes + new `_safe` factories | Not started | +| G | New content (basic variants, in_ variants, transpose, pipe syntax) | C, D, E, F | Medium — additive | Not started | +| H | Introduction, prose audit & cleanup | A–G | Low — mechanical | Not started | +| I | Revision history & config | H | Low — additive | Not started | +| J | Cross-paper fixups (conventions.tex, D3126 C++23 note) | I | Low — mechanical | Not started | + +Phases A–I are sequential within P1709 (each committed separately). +Phase J is last because it touches shared files and should only run once D3129 is stable. + +--- + +## Phase A — Source File Rewrite + +**Goal:** Replace the 3 `.hpp` files under `D3129_Views/src/` so that `\lstinputlisting` +directives produce correct output immediately. + +### Files to replace with renamed counterparts + +| Old File | New File | Old Content | New Content | +|----------|----------|-------------|-------------| +| `vertex_info.hpp` | `vertex_data.hpp` | `vertex_info` (2 params, 8 lines) | `vertex_data` (3 params) primary template | +| `edge_info.hpp` | `edge_data.hpp` | `edge_info` (4 params, 12 lines) | `edge_data` (4 params) primary template with renamed members | +| `neighbor_info.hpp` | `neighbor_data.hpp` | `neighbor_info` (3 params, 10 lines) | `neighbor_data` (4 params) primary template | + +### Content for new source files + +Model each on the graph-v3 `graph_data.hpp` implementation but simplified to +exposition-only level. Per strategy Q1 recommendation (b), show the primary template +plus ~4 key specializations per type (the ones views actually produce). + +**`vertex_data.hpp`** — primary template + key specializations: +```cpp +template +struct vertex_data { + using id_type = VId; // e.g. vertex_id_t or void + using vertex_type = V; // e.g. vertex_t or void + using value_type = VV; // e.g. invoke_result of vvf, or void + + id_type id; + vertex_type vertex; + value_type value; +}; +``` +Key specializations to show: ``, ``, ``. + +**`edge_data.hpp`** — primary template: +```cpp +template +struct edge_data { + using source_id_type = VId; // e.g. vertex_id_t when Sourced==true, or void + using target_id_type = VId; // e.g. vertex_id_t + using edge_type = E; // e.g. edge_t or void + using value_type = EV; // e.g. invoke_result of evf, or void + + source_id_type source_id; + target_id_type target_id; + edge_type edge; + value_type value; +}; +``` +Key specializations: `` (incidence), `` (edgelist), +`` (search edge views), `` (basic incidence). + +**`neighbor_data.hpp`** — primary template: +```cpp +template +struct neighbor_data { + using source_id_type = VId; // e.g. vertex_id_t when Sourced==true, or void + using target_id_type = VId; // e.g. vertex_id_t + using target_type = V; // e.g. vertex_t or void + using value_type = VV; // e.g. invoke_result of vvf, or void + + source_id_type source_id; + target_id_type target_id; + target_type target; + value_type value; +}; +``` +Key specializations: `` (neighbors), `` (basic). + +### Procedure + +1. Delete `vertex_info.hpp`, `edge_info.hpp`, `neighbor_info.hpp`. +2. Create `vertex_data.hpp`, `edge_data.hpp`, `neighbor_data.hpp` with primary templates + and representative specializations. +3. Update `\lstinputlisting` directives in `views.tex` to reference the new filenames: + - `D3129_Views/src/vertex_info.hpp` → `D3129_Views/src/vertex_data.hpp` + - `D3129_Views/src/edge_info.hpp` → `D3129_Views/src/edge_data.hpp` + - `D3129_Views/src/neighbor_info.hpp` → `D3129_Views/src/neighbor_data.hpp` +4. **Verify:** `latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex` builds. +5. **Commit:** `"Phase A: Rewrite D3129 source files — info structs → data structs"` + +### Safety notes + +- The LaTeX `\lstinputlisting` directives reference files by exact name. Deleting a file + without updating its `\lstinputlisting` will break the build. Step 3 handles this. +- Do NOT update surrounding prose or tables yet. Only source files and their + `\lstinputlisting` references change in this phase. + +--- + +## Phase B — Info Structs Section Rewrite + +**Goal:** Rewrite the "Info Structs (Return Types)" section (§2, views.tex lines ~31–240) +to describe the new data struct types, specialization tables, and introductory code examples. + +### Section heading change + +- `\section{Info Structs (Return Types)}` → `\section{Data Structs (Return Types)}` + +### Subsection heading changes + +| Old | New | +|-----|-----| +| `\subsection{\tcode{struct vertex_info}}` | `\subsection{\tcode{struct vertex_data}}` | +| `\subsection{\tcode{struct edge_info}}` | `\subsection{\tcode{struct edge_data}}` | +| `\subsection{\tcode{struct neighbor_info}}` | `\subsection{\tcode{struct neighbor_data}}` | + +### Introductory code examples (lines ~39–78) + +Update all code examples to use new types, 2-arg value functions, and correct bindings: + +| Old Code | New Code | +|----------|----------| +| `vertex_reference_t u = uu.vertex;` | `vertex_t u = uu.vertex;` | +| `auto vvf = [&g](vertex_reference_t u) { return vertex_value(g,u); };` | `auto vvf = [](const auto& g, vertex_t u) { return vertex_value(g,u); };` | +| `// type is vertex_info, void>` | `// type is vertex_data, vertex_t, void>` | +| `for(auto&& uu : vertexlist(g))` | `for(auto&& [uid, u] : vertexlist(g))` | +| `for(auto&& [u] : vertexlist(g))` | `for(auto&& [uid, u] : vertexlist(g))` | +| `for(auto&& [u, value] : vertexlist(g, vvf))` | `for(auto&& [uid, u, val] : vertexlist(g, vvf))` | + +### Specialization tables + +Replace the existing 2-row `vertex_info` table with an expanded `vertex_data` table +showing the key specializations used by views: + +| Template Arguments | Members | +|--------------------|---------| +| `vertex_data` | `id`, `vertex`, `value` | +| `vertex_data` | `id`, `vertex` | +| `vertex_data` | `id`, `value` | +| `vertex_data` | `id` | + +Similarly expand `edge_data` and `neighbor_data` tables. + +Update member names in the `edge_data` table: +- `source` → `source_id` +- `target` → `target_id` + +### Copyable info structs block (commented-out, lines ~200–240) + +Leave the `\begin{comment}...\end{comment}` block in place for now but update internal +references from `vertex_info` → `vertex_data`, `edge_info` → `edge_data`, +`neighbor_info` → `neighbor_data`. This block can be un-commented in a later revision +if needed. + +### Procedure + +1. Rename section and subsection headings. +2. Rewrite introductory code examples. +3. Replace specialization tables with expanded versions. +4. Update prose references: `vertex_info` → `vertex_data`, `edge_info` → `edge_data`, + `neighbor_info` → `neighbor_data` throughout §2. +5. Update commented-out block. +6. **Verify:** `latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex` builds. +7. **Commit:** `"Phase B: Rewrite data structs section — tables, examples, prose"` + +### Safety notes + +- This is the largest single-phase prose change. Work subsection by subsection. +- After updating each subsection, verify that `\label` references (`\ref{tab:vertex-view}`, + etc.) still match. Update `\label` names if headings change. + +--- + +## Phase C — Graph Views Update + +**Goal:** Update the four graph view subsections (vertexlist, incidence, neighbors, edgelist) +to use the new data struct types, correct structured bindings, and 2-arg value functions. + +### vertexlist (views.tex ~lines 245–270) + +| Old | New | +|-----|-----| +| `for(auto&& [u] : vertexlist(g))` → `vertex_info` | `for(auto&& [uid, u] : vertexlist(g))` → `vertex_data` | +| `for(auto&& [u,val] : vertexlist(g,vvf))` → `vertex_info` | `for(auto&& [uid, u, val] : vertexlist(g,vvf))` → `vertex_data` | +| Same pattern for `(g,first,last)` and `(g,vr)` overloads | Same pattern | + +Update surrounding prose: "returning a `vertex_info`" → "returning a `vertex_data`". + +### incidence (views.tex ~lines 272–295) + +| Old | New | +|-----|-----| +| `for(auto&& [uv] : incidence(g,u))` → `edge_info` | `for(auto&& [tid, uv] : incidence(g,u))` → `edge_data` | +| `for(auto&& [uv,val] : incidence(g,u,evf))` → `edge_info` | `for(auto&& [tid, uv, val] : incidence(g,u,evf))` → `edge_data` | + +Update prose: `edge_info` → `edge_data`. + +### neighbors (views.tex ~lines 297–318) + +| Old | New | +|-----|-----| +| `for(auto&& [v] : neighbors(g,uid))` → `neighbor_info` | `for(auto&& [tid, n] : neighbors(g,uid))` → `neighbor_data` | +| `for(auto&& [v,val] : neighbors(g,uid,vvf))` → `neighbor_info` | `for(auto&& [tid, n, val] : neighbors(g,uid,vvf))` → `neighbor_data` | + +Update prose: `neighbor_info` → `neighbor_data`, `vertex_info` → `vertex_data` (neighbors +prose incorrectly says `vertex_info` in the LaTeX). + +### edgelist (views.tex ~lines 320–340) + +| Old | New | +|-----|-----| +| `for(auto&& [u,v,uv] : edgelist(g))` → `edge_info` | `for(auto&& [sid, tid, uv] : edgelist(g))` → `edge_data` | +| `for(auto&& [u,v,uv,val] : edgelist(g,evf))` → `edge_info` | `for(auto&& [sid, tid, uv, val] : edgelist(g,evf))` → `edge_data` | + +Update prose: `edge_info` → `edge_data`. Update `evf(uv)` references to `evf(g,uv)`. + +### Procedure + +1. Update each subsection table and prose sequentially. +2. Update all value function references from 1-arg to 2-arg in prose. +3. **Verify:** `latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex` builds. +4. **Commit:** `"Phase C: Update graph view sections — data structs, bindings, 2-arg VVF/EVF"` + +--- + +## Phase D — Search Common Types Update + +**Goal:** Update the "Common Types and Functions for Search" subsection to replace free +functions with member functions and rename `size` → `num_visited`. + +### Changes + +| Old | New | +|-----|-----| +| `void cancel(S search, cancel_search);` | `search.cancel(cancel_search);` | +| `auto depth(S search) -> integral;` | `search.depth() -> size_t;` | +| `auto size(S search) -> integral;` | `search.num_visited() -> size_t;` | + +### Code listing update + +Replace the free-function listing with member-function declarations. Add the +`cancel_search` enum (unchanged) and the `search_view` concept: + +```cpp +template +concept search_view = requires(V& v, const V& cv) { + { v.cancel() } -> std::convertible_to; + { cv.depth() } -> std::convertible_to; + { cv.num_visited() } -> std::convertible_to; +}; +``` + +### Code example update + +Replace the free-function usage example: + +| Old | New | +|-----|-----| +| `if(depth(dfs) > 3)` | `if(dfs.depth() > 3)` | +| `cancel(dfs, cancel_search::cancel_branch)` | `dfs.cancel(cancel_search::cancel_branch)` | +| `if(size(dfs) > 1000)` | `if(dfs.num_visited() > 1000)` | +| `std::cout << "Big depth of " << size(dfs)` | `std::cout << "Many visited: " << dfs.num_visited()` | + +### Prose updates + +- Update the paragraph that says "`size(dfs)` is typically the same as `depth(dfs)`" to + use member syntax and `num_visited` name. +- Remove the paragraph about sourced views adhering to `basic_sourced_index_edgelist` — + sourced search views are removed. +- Remove `\phil{Do these apply to all "search" functions?}` note. + +### Procedure + +1. Update code listing (enum + member functions + concept). +2. Update code example. +3. Update surrounding prose. +4. **Verify:** `latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex` builds. +5. **Commit:** `"Phase D: Update search common types — member functions, search_view concept"` + +--- + +## Phase E — DFS / BFS Views Update + +**Goal:** Update DFS and BFS view tables and prose to match the implementation. + +### DFS changes (views.tex ~lines 405–440) + +| Old Row | New Row | +|---------|---------| +| `[v] : vertices_dfs(g,source)` → `vertex_info` | `[v] : vertices_dfs(g,seed)` → `vertex_data` | +| `[v,val] : vertices_dfs(g,source,vvf)` → `vertex_info` | `[v, val] : vertices_dfs(g,seed,vvf)` → `vertex_data` | +| `[v,uv] : edges_dfs(g,source)` → `edge_info` | `[uv] : edges_dfs(g,seed)` → `edge_data` | +| `[v,uv,val] : edges_dfs(g,source,evf)` → `edge_info` | `[uv, val] : edges_dfs(g,seed,evf)` → `edge_data` | +| `[u,v,uv] : sourced_edges_dfs(g,source)` | **Remove** | +| `[u,v,uv,val] : sourced_edges_dfs(g,source,evf)` | **Remove** | + +**Critical:** Edge DFS views change from `[v,uv]` (2 bindings) to `[uv]` (1 binding) — +VId is void, so no vertex id in the binding. + +Remove all `\phil` notes in the DFS subsection. + +Update parameter name: `source` → `seed`. + +### BFS changes (views.tex ~lines 450–487) + +Identical structural changes as DFS: + +| Old Row | New Row | +|---------|---------| +| `[v] : vertices_bfs(g,source)` → `vertex_info` | `[v] : vertices_bfs(g,seed)` → `vertex_data` | +| `[v,val] : vertices_bfs(g,source,vvf)` → `vertex_info` | `[v, val] : vertices_bfs(g,seed,vvf)` → `vertex_data` | +| `[v,uv] : edges_bfs(g,source)` → `edge_info` | `[uv] : edges_bfs(g,seed)` → `edge_data` | +| `[v,uv,val] : edges_bfs(g,source,evf)` → `edge_info` | `[uv, val] : edges_bfs(g,seed,evf)` → `edge_data` | +| `[u,v,uv] : sourced_edges_bfs(g,source)` | **Remove** | +| `[u,v,uv,val] : sourced_edges_bfs(g,source,evf)` | **Remove** | + +Remove all `\phil` notes in the BFS subsection (including `depth_limit` note). + +### Design note (strategy Q7) + +Add a brief "Design Note" paragraph after the DFS/BFS tables explaining that search views +yield descriptors rather than IDs (VId=void). Users obtain IDs via `vertex_id(g, v)`. +Descriptors provide richer access via CPOs. + +### Procedure + +1. Update DFS table and remove sourced rows. +2. Update BFS table and remove sourced rows. +3. Remove all `\phil` notes in DFS and BFS sections. +4. Add design note paragraph. +5. Update surrounding prose. +6. **Verify:** `latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex` builds. +7. **Commit:** `"Phase E: Update DFS/BFS views — remove sourced, descriptor-based return"` + +--- + +## Phase F — Topological Sort Views Update + +**Goal:** Update topological sort to remove seed parameter, remove sourced variants, +and add `_safe` factory documentation. + +### Table changes + +| Old Row | New Row | +|---------|---------| +| `[v] : vertices_topological_sort(g,source)` | `[v] : vertices_topological_sort(g)` — no source param | +| `[v,val] : vertices_topological_sort(g,source,vvf)` | `[v, val] : vertices_topological_sort(g,vvf)` | +| `[v,uv] : edges_topological_sort(g,source)` | `[uv] : edges_topological_sort(g)` — VId=void | +| `[v,uv,val] : edges_topological_sort(g,source,evf)` | `[uv, val] : edges_topological_sort(g,evf)` | +| `[u,v,uv] : sourced_edges_topological_sort(g,source)` | **Remove** | +| `[u,v,uv,val] : sourced_edges_topological_sort(g,source,evf)` | **Remove** | + +### New: `_safe` factories + +Add rows showing cycle-detecting factories that return `std::expected`: + +``` +vertices_topological_sort_safe(g) → std::expected> +vertices_topological_sort_safe(g, vvf) → std::expected> +edges_topological_sort_safe(g) → std::expected> +edges_topological_sort_safe(g, evf) → std::expected> +``` + +Use `std::expected` per strategy Q4 recommendation (a). The paper specifies +`std::expected`; the implementation provides backward compatibility to C++20 via +an external `expected` library (e.g., `tl::expected`), switching to `std::expected` +when C++23 or later is used. Add a brief note in the topological sort section +stating this compatibility approach. + +### Prose updates + +- Update intro prose: "from a given source vertex" → "over all vertices in the graph" +- Note that topo sort does NOT satisfy `search_view` (no `depth()` member). +- Note that `cancel_branch` behaves as `cancel_all` (flat ordering). +- Remove all `\phil` notes. + +### Procedure + +1. Update table — remove source parameter and sourced rows. +2. Add `_safe` factory rows. +3. Update prose. +4. **Verify:** `latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex` builds. +5. **Commit:** `"Phase F: Update topological sort — all-vertex, _safe factories, remove sourced"` + +--- + +## Phase G — New Content + +**Goal:** Add sections for `basic_` variants, `in_` variants, `transpose` view, +and pipe syntax. Per strategy Q2 recommendation (a), basic variants go in the same +table/subsection as their standard counterparts (split to follow-on table if needed +for page fit). Per strategy Q3 recommendation (c), pipe syntax appears both in each +view subsection and in a summary section. + +### G.1 — Basic view variants + +Add rows to each graph view table from Phase C: + +**vertexlist:** +| New Row | Return | +|---------|--------| +| `for(auto&& [uid] : basic_vertexlist(g))` | `vertex_data` | +| `for(auto&& [uid, val] : basic_vertexlist(g,vvf))` | `vertex_data` | + +**incidence:** +| New Row | Return | +|---------|--------| +| `for(auto&& [tid] : basic_incidence(g,uid))` | `edge_data` | +| `for(auto&& [tid, val] : basic_incidence(g,uid,evf))` | `edge_data` | + +**neighbors:** +| New Row | Return | +|---------|--------| +| `for(auto&& [tid] : basic_neighbors(g,uid))` | `neighbor_data` | +| `for(auto&& [tid, val] : basic_neighbors(g,uid,vvf))` | `neighbor_data` | + +**edgelist:** +| New Row | Return | +|---------|--------| +| `for(auto&& [sid, tid] : basic_edgelist(g))` | `edge_data` | +| `for(auto&& [sid, tid, val] : basic_edgelist(g,evf))` | `edge_data` | + +Add brief prose explaining that basic views omit descriptors and yield only IDs. + +### G.2 — Incoming edge variants + +Add new subsections or rows for `in_incidence` and `in_neighbors`: + +| View | Concept Required | Return | +|------|-----------------|--------| +| `in_incidence(g, u)` | `bidirectional_adjacency_list` | Same as `incidence` but incoming | +| `basic_in_incidence(g, uid)` | `bidirectional_adjacency_list` | Same as `basic_incidence` but incoming | +| `in_neighbors(g, u)` | `bidirectional_adjacency_list` | Same as `neighbors` but incoming | +| `basic_in_neighbors(g, uid)` | `bidirectional_adjacency_list` | Same as `basic_neighbors` but incoming | + +Per strategy Q5 recommendation (b), add a brief exposition-only note about the +`edge_accessor` mechanism that enables these variants. + +### G.3 — Transpose view + +Add a new subsection in Graph Views for `transpose`: + +```latex +\subsection{transpose View} +``` + +Document `transpose_view` as a zero-cost wrapper for bidirectional graphs that swaps +outgoing/incoming edge traversal. Not a range itself — a graph wrapper. Requires +`bidirectional_adjacency_list`. + +### G.4 — Value function concepts and allocator parameter documentation + +Add a brief reference to the `vertex_value_function` and `edge_value_function` concepts +(defined in D3130 GCI). These should be mentioned in the Introduction or in a short +"Value Function Concepts" paragraph near the data structs section: + +```cpp +template +concept vertex_value_function = /* see D3130 */; + +template +concept edge_value_function = /* see D3130 */; +``` + +Document the allocator parameter for search views (DFS, BFS, topological sort). +The implementation disambiguates the allocator from value functions using a +`requires(!vertex_value_function)` constraint. Add a brief note in the +DFS, BFS, and topological sort subsections showing the allocator overload and +its disambiguation. + +### G.5 — Pipe syntax / Range Adaptors + +Add pipe syntax examples to each graph view table (via additional example rows or a +separate column). Then add a summary "Range Adaptors" subsection listing all adaptor +objects: + +```cpp +g | vertexlist() g | basic_vertexlist() +g | incidence(uid) g | basic_incidence(uid) +g | neighbors(uid) g | basic_neighbors(uid) +g | edgelist() g | basic_edgelist() +g | vertices_dfs(seed) g | edges_dfs(seed) +g | vertices_bfs(seed) g | edges_bfs(seed) +g | vertices_topological_sort() +``` + +### Procedure + +1. Add basic variant rows to each graph view table (G.1). +2. Add `in_` variant subsections/rows (G.2). +3. Add transpose subsection (G.3). +4. Add value function concept references and allocator parameter documentation (G.4). +5. Add pipe syntax examples and summary section (G.5). +6. **Verify:** `latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex` builds. +7. **Commit:** `"Phase G: Add basic views, in_ variants, transpose, pipe syntax, VVF/EVF concepts"` + +### Safety notes + +- G.1 modifies the same tables as Phase C. Verify table structure carefully. +- Per Q2 recommendation, if a combined table overflows the page, split basic rows + into a follow-on table within the same subsection. + +--- + +## Phase H — Introduction, Prose Audit & Cleanup + +**Goal:** Systematic cleanup pass through all D3129 text. + +### Introduction updates (lines 1–30) + +- Remove `\phil{Use \tcode{basic_index_adjacency_list} as the concept for all views.}` — + concept no longer exists. +- Remove `\phil{Group views by basic first, like with concepts.}` — resolved by basic + variant placement in Phase G. +- Remove `\phil{Use \tcode{&&} instead of \tcode{const&} for value function parameters.}` — + implementation uses `VVF&&`/`EVF&&` forwarding references. Note this in prose if + appropriate. +- Remove `\phil{Can \tcode{std::ref} be used for the value function?}` — moot with 2-arg + convention. +- Remove or update the commented-out consolidation block (lines 15–22). +- Update prose references to "View Return Types" to reference data structs. + +### Search-and-replace pass + +| Old term | New term | Scope | +|----------|----------|-------| +| `vertex_info` | `vertex_data` | All remaining occurrences | +| `edge_info` | `edge_data` | All remaining occurrences | +| `neighbor_info` | `neighbor_data` | All remaining occurrences | +| `vertex_reference_t` | `vertex_t` | All remaining occurrences | +| `edge_reference_t` | `edge_t` | All remaining occurrences | +| `vvf(u)` (in prose) | `vvf(g, u)` | All prose references | +| `evf(uv)` (in prose) | `evf(g, uv)` | All prose references | + +### Additional cleanup + +- Remove all remaining `\phil` notes throughout `views.tex`. +- Verify all `\label` / `\ref` pairs still resolve. +- Verify all `\lstinputlisting` paths are correct. + +### Procedure + +1. Remove `\phil` notes from introduction. +2. Run search-and-replace for each old term. +3. Remove remaining `\phil` notes throughout the document. +4. Spot-check all `\label`/`\ref` and `\lstinputlisting` references. +5. **Verify:** `latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex` builds. +6. **Commit:** `"Phase H: Prose audit — cleanup phil notes, rename all obsolete types"` + +--- + +## Phase I — Revision History & Config + +**Goal:** Update `revision.tex` and `config.tex` to reflect the r3 changes. + +### `config.tex` changes + +- `\newcommand{\docno}{\paperno r3}` — already correct (verify only) +- `\newcommand{\prevdocno}{P3129r1}` → update to `P3129r2` (or whatever the actual + previous published revision is) + +### `revision.tex` — add r3 entry + +Use the draft entry from strategy §8 (already validated). Ensure it references: +- Data struct rename +- 2-arg value functions +- Basic view variants +- Incoming edge variants +- Transpose view +- Pipe syntax +- `_safe` topological sort factories +- All-vertex topological sort +- Sourced search view removal +- Member functions for search control +- `search_view` concept +- `vertex_t`/`edge_t` descriptor types + +### Procedure + +1. Update `config.tex` if needed. +2. Add r3 entry to `revision.tex`. +3. **Verify:** `latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex` builds. +4. **Commit:** `"Phase I: Update revision history and config for D3129r3"` + +--- + +## Phase J — Cross-Paper Fixups + +**Goal:** Update references to D3129-defined or D3129-consumed types in shared files, +and update D3126 Overview to note the C++23 dependency introduced by `std::expected`. + +### Affected files + +| File | Changes | +|------|---------| +| `tex/conventions.tex` | VVF: `vvf(u)` → `vvf(g, u)`. EVF: `evf(uv)` → `evf(g, uv)`. | +| `D3126_Overview/tex/overview.tex` | Add note near §Freestanding: library baseline is C++20; topological sort `_safe` views use `std::expected` (C++23); implementations provide C++20 backward compatibility via external `expected` library. | + +**Note:** `conventions.tex` is shared across all papers. Only update the rows that are +already wrong for D3129. If GCI Phase J has already updated descriptor types, verify +those changes are in place rather than re-applying them. + +### Procedure + +1. Check what GCI Phase J has already done in `conventions.tex`. +2. Update VVF/EVF descriptions if not already done. +3. In `D3126_Overview/tex/overview.tex`, add a "Language Requirements" subsection near + the existing "Freestanding" section stating: + - The library targets C++20 as its baseline. + - The topological sort safe view factories use `std::expected` (C++23). + - Implementations provide backward compatibility to C++20 via an external `expected` + library (e.g., `tl::expected`), switching to `std::expected` when C++23 or later + is used for building. +4. **Verify:** run direct `latexmk` builds for each affected paper to confirm no breakage. + - `latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex` + - `latexmk -output-directory=pdf -aux-directory=aux D3130_Container_Interface.tex` (if `tex/conventions.tex` changed) + - `latexmk -output-directory=pdf -aux-directory=aux D3128_Algorithms.tex` (if `tex/conventions.tex` changed) + - `latexmk -output-directory=pdf -aux-directory=aux D3126_Overview.tex` +5. **Commit:** `"Phase J: Cross-paper fixups — conventions.tex VVF/EVF, D3126 C++23 note"` + +### Safety notes + +- This phase touches shared files. Coordinate with GCI and Algorithms plan status. +- If GCI Phase J is not yet committed, defer this phase until it is. + +--- + +## Phase dependency diagram + +``` + Phase A (source files) + └── Phase B (data structs section) + ├── Phase C (graph views) + └── Phase D (search common types) + ├── Phase E (DFS/BFS) ← also needs C + └── Phase F (topological sort) ← also needs C + + Phase G (new content: basic, in_, transpose, pipe, VVF/EVF, allocator docs) + depends on C, D, E, F + +All A–G ──→ Phase H (prose audit & cleanup) + └── Phase I (revision history & config) + └── Phase J (cross-paper fixups, D3126 C++23 note) +``` + +--- + +## Risk register + +| Risk | Likelihood | Impact | Mitigation | +|------|------------|--------|------------| +| `\lstinputlisting` broken by file rename | High (if not careful) | Build failure | Phase A explicitly handles all directives. Verify build after. | +| Table overflow from basic variant rows | Medium | LaTeX formatting issue | Per Q2: split into follow-on table if combined table exceeds page width/height. | +| Bulk rename introduces false positives | Medium | Incorrect prose | Use targeted edits, not blind sed. Spot-check every replacement. | +| Section numbering drift after adding sections | Low | LaTeX warnings | Use `\label`/`\ref` for all cross-references. | +| `conventions.tex` conflict with GCI Phase J | Medium | Git merge conflict | Phase J is last and checks GCI status first. | +| `\phil` note removal misses one | Low | Stale commentary | Run `grep -n '\\phil' views.tex` as final check in Phase H. | +| `std::expected` not available in LaTeX preamble | Low | Undefined `\tcode` | Verify `\tcode{std::expected}` renders correctly. | +| D3126 Overview C++20 language outdated | Medium | Inconsistent version claims | Phase J adds C++23 note to D3126 adjacent to Freestanding section. | diff --git a/agents/views_update_strategy.md b/agents/views_update_strategy.md index 677ff9a..c58e3a5 100644 --- a/agents/views_update_strategy.md +++ b/agents/views_update_strategy.md @@ -349,7 +349,7 @@ Identical structural changes as DFS (§1.8): | `vertices_topological_sort(g,source)` | 2-arg | `vertices_topological_sort(g)` — 1-arg | Remove source param | | `edges_topological_sort(g,source)` | 2-arg | `edges_topological_sort(g)` — 1-arg | Remove source param | | `sourced_edges_topological_sort(...)` | Present | **Does not exist** | **Remove** | -| `_safe` cycle-detection factories | **Not in LaTeX** | Returns `tl::expected>` | **Add** | +| `_safe` cycle-detection factories | **Not in LaTeX** | Returns `std::expected>` (C++23; `tl::expected` for C++20 compat) | **Add** | | Iterator type | Not specified | **`forward_iterator`** (eagerly computed) | Document — differs from DFS/BFS | | `depth()` member | Implied by "search views" section | **Not available** — topo sort has no tree depth | Clarify: topo sort does NOT satisfy `search_view` | | `cancel()` member | Implied | Present, but `cancel_branch` = `cancel_all` (flat ordering) | Document | @@ -527,7 +527,22 @@ The search views overlap with algorithm concerns: | DFS/BFS visitor events vs search view events | Cross-reference D3128 visitor events. Note that search views are an alternative to visitor-based traversal. | | Topological sort algorithm vs view | Cross-reference D3128's `topological_sort()` algorithm. Note the algorithm returns `bool` for cycle detection; the view offers a `_safe` factory returning `expected`. | -### 4.3 Shared `conventions.tex` Updates +### 4.3 References to D3126 (Overview) + +D3126 Overview describes the library as targeting C++20 (§Prior Art, §Alternatives). The +use of `std::expected` in the topological sort `_safe` view factories introduces a C++23 +dependency. D3126 should be updated to note: + +- The library baseline remains C++20. +- The topological sort safe view factories use `std::expected` (C++23). +- Implementations provide backward compatibility to C++20 via an external `expected` + library (e.g., `tl::expected`), switching to `std::expected` when C++23 or later is + used for building. + +A natural placement is adjacent to the existing "Freestanding" section in D3126, or as a +new "Language Requirements" subsection. + +### 4.4 Shared `conventions.tex` Updates The conventions table (`tex/conventions.tex`) contains entries that apply to views: @@ -569,7 +584,7 @@ implementation for the complete set. - (b) Group all basic views in a separate section - (c) Show standard views first, then a single "Basic View Variants" subsection listing all -**Decision:** (a) — keeps related information together. Use a horizontal divider +**Recommendation:** (a) — keeps related information together. Use a horizontal divider in each view's table to separate standard from basic rows, provided the table fits on the page. If a combined table is too wide or tall, split basic variants into a separate follow-on table within the same subsection. @@ -583,7 +598,7 @@ separate follow-on table within the same subsection. - (b) Each view's subsection shows its pipe syntax alongside the function call syntax - (c) Both — show pipe in each subsection with a summary section -**Decision:** (c) — show pipe syntax in each view table via an additional column or +**Recommendation:** (c) — show pipe syntax in each view table via an additional column or examples, plus a summary "Range Adaptors" section listing all adaptor objects. ### Q4 — `tl::expected` Dependency @@ -596,9 +611,18 @@ The standard has `std::expected` since C++23. Should the paper: - (b) Use an exposition-only `expected` type - (c) Use a different error reporting mechanism (e.g., `optional>` error output) -**Decision:** (b) — use an exposition-only `expected` type to avoid a hard C++23 -dependency. This keeps the paper compatible with C++20 while conveying the intended -semantics. +**Recommendation:** (a) — use `std::expected` and target C++23 for this part of the design. +This matches the implementation intent and keeps the paper concrete. + +The implementation should provide backward compatibility to C++20 by using an external +`expected` library (e.g., `tl::expected`) when building in C++20 mode, and switch to +`std::expected` when C++23 or later is used for building. The paper should present +`std::expected` as the specification type. + +**Cross-paper impact:** D3126 Overview currently describes the library as targeting C++20 +(see Overview §Prior Art and §Alternatives). A note should be added to D3126 stating that +the library baseline is C++20, but the topological sort `_safe` view factories use +`std::expected` (C++23). See Section 4.4 below. ### Q5 — Incoming Edge Search Views @@ -612,7 +636,7 @@ document the accessor mechanism and/or request incoming-edge search variants? are possible future extensions - (c) Add incoming search view factories (requires implementation work) -**Decision:** (b) — document the accessor mechanism as exposition-only and note that +**Recommendation:** (b) — document the accessor mechanism as exposition-only and note that incoming variants are possible future extensions. ### Q6 — Event Enum / Coroutine-Style Events @@ -625,7 +649,7 @@ coroutine-style event reporting. The implementation does not have this. - (b) Add a "Future Directions" note - (c) Implement the feature first -**Decision:** (a) — remove all `\phil` notes about event enums. This is a future +**Recommendation:** (a) — remove all `\phil` notes about event enums. This is a future direction that can be proposed separately. Keep the current visitor-based approach (D3128) and search-view approach (D3129) as complementary patterns. @@ -636,7 +660,7 @@ vertex views (binding: `[v]`) and `edge_data` for edge vie (binding: `[uv]`). The VId is `void` — no vertex id in the binding. Should the paper explicitly document this design choice and the rationale? -**Decision:** Yes — add a brief "Design Note" paragraph explaining that search views +**Recommendation:** Yes — add a brief "Design Note" paragraph explaining that search views yield descriptors rather than IDs, because the search context is per-graph (the user already knows which graph) and descriptors provide richer access via CPOs (`vertex_id(g, v)`, `vertex_value(g, v)`, etc.). @@ -765,7 +789,8 @@ Draft entry for `revision.tex`: \item Added \tcode{transpose} view for direction-swapping graph adaption. \item Added pipe syntax support via range adaptors for all view functions. \item Added \tcode{\_safe} topological sort factories with cycle detection - via \tcode{std::expected}. + via \tcode{std::expected} (C++23; backward compatible to C++20 via external + \tcode{expected} library). \item Changed topological sort from seeded (single source) to all-vertex traversal. \item Removed \tcode{sourced\_edges\_dfs}, \tcode{sourced\_edges\_bfs}, and \tcode{sourced\_edges\_topological\_sort} — sourced search variants are no longer From ac5abdd8d831cd66f2b3de52e6e699a19d8cba49 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 19:48:01 -0400 Subject: [PATCH 04/22] =?UTF-8?q?Phase=20A:=20Rewrite=20D3129=20source=20f?= =?UTF-8?q?iles=20=E2=80=94=20info=20structs=20=E2=86=92=20data=20structs?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- D3129_Views/src/edge_data.hpp | 51 +++++++++++++++++++++++++++++++ D3129_Views/src/edge_info.hpp | 12 -------- D3129_Views/src/neighbor_data.hpp | 43 ++++++++++++++++++++++++++ D3129_Views/src/neighbor_info.hpp | 10 ------ D3129_Views/src/vertex_data.hpp | 39 +++++++++++++++++++++++ D3129_Views/src/vertex_info.hpp | 8 ----- D3129_Views/tex/views.tex | 6 ++-- 7 files changed, 136 insertions(+), 33 deletions(-) create mode 100644 D3129_Views/src/edge_data.hpp delete mode 100644 D3129_Views/src/edge_info.hpp create mode 100644 D3129_Views/src/neighbor_data.hpp delete mode 100644 D3129_Views/src/neighbor_info.hpp create mode 100644 D3129_Views/src/vertex_data.hpp delete mode 100644 D3129_Views/src/vertex_info.hpp diff --git a/D3129_Views/src/edge_data.hpp b/D3129_Views/src/edge_data.hpp new file mode 100644 index 0000000..2a1dc13 --- /dev/null +++ b/D3129_Views/src/edge_data.hpp @@ -0,0 +1,51 @@ +// Primary template +template +struct edge_data { + using source_id_type = VId; // vertex\_id\_t when Sourced==true, or void + using target_id_type = VId; // vertex\_id\_t + using edge_type = E; // edge\_t or void + using value_type = EV; // invoke\_result of evf, or void + + source_id_type source_id; + target_id_type target_id; + edge_type edge; + value_type value; +}; + +// Specialization: incidence (unsourced, no value) +template +struct edge_data { + using target_id_type = VId; + using edge_type = E; + + target_id_type target_id; + edge_type edge; +}; + +// Specialization: edgelist (sourced, no value) +template +struct edge_data { + using source_id_type = VId; + using target_id_type = VId; + using edge_type = E; + + source_id_type source_id; + target_id_type target_id; + edge_type edge; +}; + +// Specialization: basic incidence (unsourced, no descriptor, no value) +template +struct edge_data { + using target_id_type = VId; + + target_id_type target_id; +}; + +// Specialization: search edge views (no id, unsourced) +template +struct edge_data { + using edge_type = E; + + edge_type edge; +}; diff --git a/D3129_Views/src/edge_info.hpp b/D3129_Views/src/edge_info.hpp deleted file mode 100644 index 943ee31..0000000 --- a/D3129_Views/src/edge_info.hpp +++ /dev/null @@ -1,12 +0,0 @@ -template -struct edge_info { - using source_type = VorVId; // e.g. vertex\_t or vertex\_id\_t when Sourced==true, or void - using target_type = VorVId; // e.g. vertex\_t or vertex\_id\_t - using edge_type = E; // e.g. edge\_reference\_t or void - using value_type = EV; // e.g. edge\_value\_t or void - - source_type source; - target_type target; - edge_type edge; - value_type value; -}; diff --git a/D3129_Views/src/neighbor_data.hpp b/D3129_Views/src/neighbor_data.hpp new file mode 100644 index 0000000..dc5826b --- /dev/null +++ b/D3129_Views/src/neighbor_data.hpp @@ -0,0 +1,43 @@ +// Primary template +template +struct neighbor_data { + using source_id_type = VId; // vertex\_id\_t when Sourced==true, or void + using target_id_type = VId; // vertex\_id\_t + using vertex_type = V; // vertex\_t or void + using value_type = VV; // invoke\_result of vvf, or void + + source_id_type source_id; + target_id_type target_id; + vertex_type target; + value_type value; +}; + +// Specialization: neighbors (unsourced, no value) +template +struct neighbor_data { + using target_id_type = VId; + using vertex_type = V; + + target_id_type target_id; + vertex_type target; +}; + +// Specialization: basic neighbors (unsourced, no descriptor, no value) +template +struct neighbor_data { + using target_id_type = VId; + + target_id_type target_id; +}; + +// Specialization: neighbors with value (unsourced) +template +struct neighbor_data { + using target_id_type = VId; + using vertex_type = V; + using value_type = VV; + + target_id_type target_id; + vertex_type target; + value_type value; +}; diff --git a/D3129_Views/src/neighbor_info.hpp b/D3129_Views/src/neighbor_info.hpp deleted file mode 100644 index 207bb47..0000000 --- a/D3129_Views/src/neighbor_info.hpp +++ /dev/null @@ -1,10 +0,0 @@ -template -struct neighbor_info { - using source_type = VorVId; // e.g. vertex\_t or vertex\_id\_t when Sourced==true, or void - using target_type = VorVId; // e.g. vertex\_t or vertex\_id\_t - using value_type = VV; // e.g. vertex\_value\_t or void - - source_type source; - target_type target; - value_type value; -}; diff --git a/D3129_Views/src/vertex_data.hpp b/D3129_Views/src/vertex_data.hpp new file mode 100644 index 0000000..15be2c9 --- /dev/null +++ b/D3129_Views/src/vertex_data.hpp @@ -0,0 +1,39 @@ +// Primary template +template +struct vertex_data { + using id_type = VId; // e.g. vertex\_id\_t or void + using vertex_type = V; // e.g. vertex\_t or void + using value_type = VV; // e.g. invoke\_result of vvf, or void + + id_type id; + vertex_type vertex; + value_type value; +}; + +// Specialization: no value function +template +struct vertex_data { + using id_type = VId; + using vertex_type = V; + + id_type id; + vertex_type vertex; +}; + +// Specialization: no vertex descriptor +template +struct vertex_data { + using id_type = VId; + using value_type = VV; + + id_type id; + value_type value; +}; + +// Specialization: id only +template +struct vertex_data { + using id_type = VId; + + id_type id; +}; diff --git a/D3129_Views/src/vertex_info.hpp b/D3129_Views/src/vertex_info.hpp deleted file mode 100644 index 512d358..0000000 --- a/D3129_Views/src/vertex_info.hpp +++ /dev/null @@ -1,8 +0,0 @@ -template -struct vertex_info { - using vertex_type = VorVId; // e.g. vertex\_reference\_t or void - using value_type = VV; // e.g. vertex\_value\_t or void - - vertex_type vertex; - value_type value; -}; diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index 9f74584..7b73e43 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -84,7 +84,7 @@ \subsection{\tcode{struct vertex_info}}\label{vertex-view}\mbox{} \\ exists. {\small - \lstinputlisting{D3129_Views/src/vertex_info.hpp} + \lstinputlisting{D3129_Views/src/vertex_data.hpp} } Specializations are defined with \tcode{V=void} or \tcode{VV=void} to suppress the existence of their associated member variables, @@ -120,7 +120,7 @@ \subsection{\tcode{struct edge_info}}\label{edge-view}\mbox When \tcode{Sourced=true}, the \tcode{source} member is included with type \tcode{V} or \tcode{VId}. The \tcode{target} member always exists. {\small - \lstinputlisting{D3129_Views/src/edge_info.hpp} + \lstinputlisting{D3129_Views/src/edge_data.hpp} } Specializations are defined with \tcode{Sourced=true|false}, \tcode{E=void} or \tcode{EV=void} to suppress the existence of the associated @@ -158,7 +158,7 @@ \subsection{\tcode{struct neighbor_info}}\label{neighbor-vi When \tcode{Sourced=true}, the \tcode{source} member is included with type \tcode{source_type}. The \tcode{target} member always exists. {\small - \lstinputlisting{D3129_Views/src/neighbor_info.hpp} + \lstinputlisting{D3129_Views/src/neighbor_data.hpp} } Specializations are defined with \tcode{Sourced=true|false} or \tcode{EV}=void to suppress the existence of the From 11528068f71d7d6388e9b53d256cdd6d31b7e425 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 19:56:34 -0400 Subject: [PATCH 05/22] =?UTF-8?q?Phase=20B:=20Rewrite=20data=20structs=20s?= =?UTF-8?q?ection=20=E2=80=94=20tables,=20examples,=20prose?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- D3129_Views/tex/views.tex | 126 ++++++++++++++++++++------------------ 1 file changed, 65 insertions(+), 61 deletions(-) diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index 7b73e43..d5beec5 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -33,63 +33,65 @@ \section{Introduction} Additionally, \tcode{stack} and \tcode{queue} require memory allocation which could throw a \tcode{bad_alloc} exception. -\section{Info Structs (Return Types)} +\section{Data Structs (Return Types)} Views return one of the types in this section, providing a consistent set of value types for all graph data structures. They are templated so that the view can adjust the types of the members to be appropriate for its use. The three types, -\tcode{vertex_info, edge_info} and \tcode{neighbor_info}, define the common data model used by algorithms. +\tcode{vertex_data, edge_data} and \tcode{neighbor_data}, define the common data model used by algorithms. The following examples show the general design and how it's used. The example focuses on vertexlist when iterating over vertices, and the same pattern applies with using the other view functions. \begin{lstlisting} -// the type of uu is vertex\_info, void> +// the type of uu is vertex\_data, vertex\_t, void> for(auto&& uu : vertexlist(g)) { - vertex_reference_t u = uu.vertex; + vertex_id_t uid = uu.id; + vertex_t u = uu.vertex; // ... do something interesting } \end{lstlisting} A function object can also be passed to return a value from the vertex. In this case, \tcode{vertexlist(g, vvf)} returns -a struct with two members, \tcode{vertex} and \tcode{value}. +a struct with three members, \tcode{id}, \tcode{vertex} and \tcode{value}. \begin{lstlisting} -auto vvf = [&g](vertex_reference_t u) { return vertex_value(g,u); }; -// the type of uu is vertex\_info, decltype(vvf(u))> +auto vvf = [](const auto& g, vertex_t u) { return vertex_value(g,u); }; +// the type of uu is vertex\_data, vertex\_t, decltype(vvf(g,u))> for(auto&& uu : vertexlist(g, vvf)) { - vertex_reference_t u = uu.vertex; - vertex_value_t& value = uu.value; + vertex_id_t uid = uu.id; + vertex_t u = uu.vertex; + auto value = uu.value; // ... do something interesting } \end{lstlisting} Structured bindings make it simpler. \begin{lstlisting} -for(auto&& [u] : vertexlist(g)) { +for(auto&& [uid, u] : vertexlist(g)) { // ... do something interesting } \end{lstlisting} Finally, using structured binding with the vertex value function. \begin{lstlisting} -// the type returned by vertexlist is vertex\_info, decltype(vvf(vertex\_t))> -auto vvf = [&g](vertex_reference_t u) { return vertex_value(g,u); }; -for(auto&& [u, value] : vertexlist(g, vvf)) { +// the type returned by vertexlist is vertex\_data, vertex\_t, decltype(vvf(g,u))> +auto vvf = [](const auto& g, vertex_t u) { return vertex_value(g,u); }; +for(auto&& [uid, u, value] : vertexlist(g, vvf)) { // ... do something interesting } \end{lstlisting} -\subsection{\tcode{struct vertex_info}}\label{vertex-view}\mbox{} \\ -\tcode{vertex_info} is used to return vertex information. It is used by \tcode{vertexlist(g)}, \tcode{vertices_breadth_first_search(g,u)}, -\tcode{vertices_dfs(g,u)} and others. The \tcode{vertex} member is typically a vertex descriptor, but can also be a vertex id, and always -exists. +\subsection{\tcode{struct vertex_data}}\label{vertex-view}\mbox{} \\ +\tcode{vertex_data} is used to return vertex information. It is used by \tcode{vertexlist(g)}, \tcode{vertices_breadth_first_search(g,u)}, +\tcode{vertices_dfs(g,u)} and others. The \tcode{id} member is the vertex id, the \tcode{vertex} member is the vertex descriptor, +and \tcode{value} is the result of the value function, if provided. {\small \lstinputlisting{D3129_Views/src/vertex_data.hpp} } Specializations are defined with \tcode{V=void} or \tcode{VV=void} to suppress the existence of their associated member variables, -giving the following valid combinations in Table \ref{tab:vertex-view} . For instance, the second entry, \tcode{vertex_info} -has one member \tcode{\{vertex_type vertex;\}} and \tcode{value_type} is \tcode{void}. +giving the following valid combinations in Table \ref{tab:vertex-view} . For instance, the second entry, \tcode{vertex_data} +has two members \tcode{\{id_type id; vertex_type vertex;\}} and \tcode{value_type} is \tcode{void}. \begin{table}[h!] \begin{center} %\resizebox{\textwidth}{!} @@ -100,24 +102,24 @@ \subsection{\tcode{struct vertex_info}}\label{vertex-view}\mbox{} \\ \multicolumn{3}{c}{\textbf{Members}} \\ %\textbf{Template Arguments} & id & vertex & value \\ \hline - \tcode{vertex_info} & \tcode{vertex} & \tcode{value} \\ - \tcode{vertex_info} & \tcode{vertex} & \\ - %\tcode{vertex_info} & & & \\ % invalid + \tcode{vertex_data} & \tcode{id} & \tcode{vertex} & \tcode{value} \\ + \tcode{vertex_data} & \tcode{id} & \tcode{vertex} & \\ + \tcode{vertex_data} & \tcode{id} & & \tcode{value} \\ + \tcode{vertex_data} & \tcode{id} & & \\ \hline \end{tabular}} -\caption{\tcode{vertex_info} Members} +\caption{\tcode{vertex_data} Members} \label{tab:vertex-view} \end{center} \end{table} -\subsection{\tcode{struct edge_info}}\label{edge-view}\mbox{} \\ +\subsection{\tcode{struct edge_data}}\label{edge-view}\mbox{} \\ -\tcode{edge_info} is used to return edge information. It is used by -\tcode{incidence(g,u), edgelist(g), edges_breadth_first_search(g,u), edges_dfs(g,u)} and others. \tcode{source} and \tcode{target} are -typically vertex descriptors, but can also be vertex ids. If no specific mention of vertex ids are used, assume they are vertex descriptors. -In this section, \tcode{source} and \tcode{target} can be either vertex descriptors or vertex ids. +\tcode{edge_data} is used to return edge information. It is used by +\tcode{incidence(g,u), edgelist(g), edges_breadth_first_search(g,u), edges_dfs(g,u)} and others. +\tcode{source_id} and \tcode{target_id} are vertex ids of type \tcode{vertex_id_t}. -When \tcode{Sourced=true}, the \tcode{source} member is included with type \tcode{V} or \tcode{VId}. The \tcode{target} member always exists. +When \tcode{Sourced=true}, the \tcode{source_id} member is included. The \tcode{target_id} member always exists. {\small \lstinputlisting{D3129_Views/src/edge_data.hpp} @@ -125,7 +127,7 @@ \subsection{\tcode{struct edge_info}}\label{edge-view}\mbox Specializations are defined with \tcode{Sourced=true|false}, \tcode{E=void} or \tcode{EV=void} to suppress the existence of the associated member variables, giving the following valid combinations in Table \ref{tab:edge-view} . For instance, the second entry, -\tcode{edge_info} has three members \tcode{\{source_id_type source_id; target_id_type target_id; edge_type edge;\}} +\tcode{edge_data} has three members \tcode{\{source_id_type source_id; target_id_type target_id; edge_type edge;\}} and \tcode{value_type} is \tcode{void}. \begin{table}[h!] \begin{center} @@ -135,35 +137,35 @@ \subsection{\tcode{struct edge_info}}\label{edge-view}\mbox \multicolumn{1}{l}{\textbf{Template Arguments}} & \multicolumn{4}{c}{\textbf{Members}} \\ - %\textbf{Template Arguments} & id & edge & value \\ \hline - \tcode{edge_info} & \tcode{source} & \tcode{target} & \tcode{edge} & \tcode{value} \\ - \tcode{edge_info} & \tcode{source} & \tcode{target} & \tcode{edge} & \\ - \tcode{edge_info} & \tcode{source} & \tcode{target} & & \tcode{value} \\ - \tcode{edge_info} & \tcode{source} & \tcode{target} & & \\ - \tcode{edge_info} & & \tcode{target} & \tcode{edge} & \tcode{value} \\ - \tcode{edge_info} & & \tcode{target} & \tcode{edge} & \\ - \tcode{edge_info} & & \tcode{target} & & \tcode{value} \\ - \tcode{edge_info} & & \tcode{target} & & \\ + \tcode{edge_data} & \tcode{source_id} & \tcode{target_id} & \tcode{edge} & \tcode{value} \\ + \tcode{edge_data} & \tcode{source_id} & \tcode{target_id} & \tcode{edge} & \\ + \tcode{edge_data} & \tcode{source_id} & \tcode{target_id} & & \tcode{value} \\ + \tcode{edge_data} & \tcode{source_id} & \tcode{target_id} & & \\ + \tcode{edge_data} & & \tcode{target_id} & \tcode{edge} & \tcode{value} \\ + \tcode{edge_data} & & \tcode{target_id} & \tcode{edge} & \\ + \tcode{edge_data} & & \tcode{target_id} & & \tcode{value} \\ + \tcode{edge_data} & & \tcode{target_id} & & \\ \hline \end{tabular}} -\caption{\tcode{edge_info} Members} +\caption{\tcode{edge_data} Members} \label{tab:edge-view} \end{center} \end{table} -\subsection{\tcode{struct neighbor_info}}\label{neighbor-view}\mbox{} +\subsection{\tcode{struct neighbor_data}}\label{neighbor-view}\mbox{} -\tcode{neighbor_info} is used to return information for a neighbor vertex, through an edge. It is used by \tcode{neighbors(g,u)}. -When \tcode{Sourced=true}, the \tcode{source} member is included with type \tcode{source_type}. The \tcode{target} member always exists. +\tcode{neighbor_data} is used to return information for a neighbor vertex, through an edge. It is used by \tcode{neighbors(g,u)}. +When \tcode{Sourced=true}, the \tcode{source_id} member is included. The \tcode{target_id} member always exists. +The \tcode{target} member holds the neighbor's vertex descriptor when \tcode{V} is not \tcode{void}. {\small \lstinputlisting{D3129_Views/src/neighbor_data.hpp} } -Specializations are defined with \tcode{Sourced=true|false} or \tcode{EV}=void to suppress the existence of the +Specializations are defined with \tcode{Sourced=true|false}, \tcode{V=void} or \tcode{VV=void} to suppress the existence of the associated member variables, giving the following valid combinations in Table \ref{tab:neighbor-view} . For instance, the second entry, -\tcode{neighbor_info} has two members \tcode{\{source_type source; target_type target;\}} +\tcode{neighbor_data} has two members \tcode{\{target_id_type target_id; vertex_type target;\}} and \tcode{value_type} is \tcode{void}. \begin{table}[h!] @@ -175,13 +177,15 @@ \subsection{\tcode{struct neighbor_info}}\label{neighbor-vi & \multicolumn{4}{c}{\textbf{Members}} \\ \hline - \tcode{neighbor_info} & \tcode{source} & \tcode{target} & \tcode{value} \\ - \tcode{neighbor_info} & \tcode{source} & \tcode{target} & \\ - \tcode{neighbor_info} & & \tcode{target} & \tcode{value} \\ - \tcode{neighbor_info} & & \tcode{target} & \\ + \tcode{neighbor_data} & \tcode{source_id} & \tcode{target_id} & \tcode{target} & \tcode{value} \\ + \tcode{neighbor_data} & \tcode{source_id} & \tcode{target_id} & \tcode{target} & \\ + \tcode{neighbor_data} & \tcode{source_id} & \tcode{target_id} & & \\ + \tcode{neighbor_data} & & \tcode{target_id} & \tcode{target} & \tcode{value} \\ + \tcode{neighbor_data} & & \tcode{target_id} & \tcode{target} & \\ + \tcode{neighbor_data} & & \tcode{target_id} & & \\ \hline \end{tabular}} -\caption{\tcode{neighbor_info} Members} +\caption{\tcode{neighbor_data} Members} \label{tab:neighbor-view} \end{center} \end{table} @@ -190,15 +194,15 @@ \subsection{\tcode{struct neighbor_info}}\label{neighbor-vi \begin{comment} \phil{Do we really needs these, since VorVId can be either a descriptor or id.} -\subsection{Copyable Info Structs} +\subsection{Copyable Data Structs} -\subsubsection{Copyable Info Struct Types} -Copyable info structs are specializations of the info structs that can be copied. More specifically, they don't include -a vertex or edge reference. \tcode{copyable_vertex_t} shows the simple definition. +\subsubsection{Copyable Data Struct Types} +Copyable data structs are specializations of the data structs that can be copied. More specifically, they don't include +a vertex or edge descriptor. \tcode{copyable_vertex_t} shows the simple definition. \begin{lstlisting} template -using copyable_vertex_t = vertex_info; // {id, value} +using copyable_vertex_t = vertex_data; // {id, value} \end{lstlisting} \begin{table}[h!] @@ -208,17 +212,17 @@ \subsubsection{Copyable Info Struct Types} \hline \textbf{Type} & \textbf{Definition} \\ \hline - \tcode{copyable_vertex_t} & \tcode{vertex_info} \\ - \tcode{copyable_edge_t} & \tcode{edge_info>} \\ - \tcode{copyable_neighbor_t} & \tcode{neighbor_info} \\ + \tcode{copyable_vertex_t} & \tcode{vertex_data} \\ + \tcode{copyable_edge_t} & \tcode{edge_data>} \\ + \tcode{copyable_neighbor_t} & \tcode{neighbor_data} \\ \hline \end{tabular}} -\caption{Info Struct Concepts} +\caption{Data Struct Concepts} \label{tab:info_struct_concepts} \end{center} \end{table} -\subsubsection{Copyable Info Struct Concepts (For Exposition Only)} +\subsubsection{Copyable Data Struct Concepts (For Exposition Only)} Given the copyable types, it's useful to have concepts to determine if a type is a desired copyable type. \begin{table}[h!] @@ -233,7 +237,7 @@ \subsubsection{Copyable Info Struct Concepts (For Exposition Only)} \tcode{copyable_neighbor} & \tcode{convertible_to>} \\ \hline \end{tabular}} -\caption{Info Struct Concepts} +\caption{Data Struct Concepts} \label{tab:info_struct_concepts} \end{center} \end{table} From 6f50537f25e50373f895b5de7df9e524b2ad0120 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 20:03:03 -0400 Subject: [PATCH 06/22] =?UTF-8?q?Phase=20C:=20Update=20graph=20view=20sect?= =?UTF-8?q?ions=20=E2=80=94=20data=20structs,=20bindings,=202-arg=20VVF/EV?= =?UTF-8?q?F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- D3129_Views/tex/views.tex | 42 +++++++++++++++++++-------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index d5beec5..0857274 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -249,9 +249,9 @@ \section{Graph Views} \subsection{vertexlist Views} -\tcode{vertexlist} views iterate over a range of vertices, returning a \tcode{vertex_info} on each iteration. -Table \ref{tab:vertexlist} shows the vertexlist functions overloads and their return values. \tcode{u} is a vertex -descriptor. \tcode{first} and \tcode{last} are vertex iterators. +\tcode{vertexlist} views iterate over a range of vertices, returning a \tcode{vertex_data} on each iteration. +Table \ref{tab:vertexlist} shows the vertexlist functions overloads and their return values. \tcode{uid} is a vertex +id and \tcode{u} is a vertex descriptor. \tcode{first} and \tcode{last} are vertex iterators. The \tcode{vertexlist} view without the value function is of limited value, since \tcode{vertices(g)} does the same thing, without using a structured binding. However, it is included for consistency with the overload that @@ -264,12 +264,12 @@ \subsection{vertexlist Views} \hline \textbf{Example} & \textbf{Return} \\ \hline - \tcode{for(auto\&\& [u] : vertexlist(g))} & \tcode{vertex_info} \\ - \tcode{for(auto\&\& [u,val] : vertexlist(g,vvf))} & \tcode{vertex_info} \\ - \tcode{for(auto\&\& [u] : vertexlist(g,first,last))} & \tcode{vertex_info} \\ - \tcode{for(auto\&\& [u,val] : vertexlist(g,first,last,vvf))} & \tcode{vertex_info} \\ - \tcode{for(auto\&\& [u] : vertexlist(g,vr))} & \tcode{vertex_info} \\ - \tcode{for(auto\&\& [u,val] : vertexlist(g,vr,vvf))} & \tcode{vertex_info} \\ + \tcode{for(auto\&\& [uid, u] : vertexlist(g))} & \tcode{vertex_data} \\ + \tcode{for(auto\&\& [uid, u, val] : vertexlist(g,vvf))} & \tcode{vertex_data} \\ + \tcode{for(auto\&\& [uid, u] : vertexlist(g,first,last))} & \tcode{vertex_data} \\ + \tcode{for(auto\&\& [uid, u, val] : vertexlist(g,first,last,vvf))} & \tcode{vertex_data} \\ + \tcode{for(auto\&\& [uid, u] : vertexlist(g,vr))} & \tcode{vertex_data} \\ + \tcode{for(auto\&\& [uid, u, val] : vertexlist(g,vr,vvf))} & \tcode{vertex_data} \\ \hline \end{tabular}} \caption{\tcode{vertexlist} View Functions} @@ -278,11 +278,11 @@ \subsection{vertexlist Views} \end{table} \subsection{incidence Views} -\tcode{incidence} views iterate over a range of adjacent edges of a vertex, returning a \tcode{edge_info} on each iteration. +\tcode{incidence} views iterate over a range of adjacent edges of a vertex, returning a \tcode{edge_data} on each iteration. Table \ref{tab:incidence} shows the \tcode{incidence} function overloads and their return values. Since the source vertex \tcode{u} is available when calling an \tcode{incidence} function, there's no need to include sourced -versions of the function to include the \tcode{source} vertex in the output. +versions of the function to include the \tcode{source_id} in the output. The \tcode{incidence} view without the value function is of limited value, since \tcode{edges(g,u)} does the same thing, without using a structured binding. However, it is included for consistency with the overload that @@ -295,8 +295,8 @@ \subsection{incidence Views} \hline \textbf{Example} & \textbf{Return} \\ \hline - \tcode{for(auto\&\& [uv] : incidence(g,u))} & \tcode{edge_info} \\ - \tcode{for(auto\&\& [uv,val] : incidence(g,u,evf))} & \tcode{edge_info} \\ + \tcode{for(auto\&\& [tid, uv] : incidence(g,u))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [tid, uv, val] : incidence(g,u,evf))} & \tcode{edge_data} \\ \hline \end{tabular}} \caption{\tcode{incidence} View Functions} @@ -305,11 +305,11 @@ \subsection{incidence Views} \end{table} \subsection{neighbors Views} -\tcode{neighbors} views iterate over a range of edges for a vertex, returning a \tcode{vertex_info} of each neighboring target vertex on each iteration. +\tcode{neighbors} views iterate over a range of edges for a vertex, returning a \tcode{neighbor_data} of each neighboring target vertex on each iteration. Table \ref{tab:neighbors} shows the \tcode{neighbors} function overloads and their return values. Since the source vertex \tcode{u} is available when calling a \tcode{neighbors} function, there's no need to include sourced versions of the function -to include \tcode{source} vertex in the output. +to include \tcode{source_id} in the output. \begin{table}[h!] \begin{center} @@ -318,8 +318,8 @@ \subsection{neighbors Views} \hline \textbf{Example} & \textbf{Return} \\ \hline - \tcode{for(auto\&\& [v] : neighbors(g,uid))} & \tcode{neighbor_info} \\ - \tcode{for(auto\&\& [v,val] : neighbors(g,uid,vvf))} & \tcode{neighbor_info} \\ + \tcode{for(auto\&\& [tid, n] : neighbors(g,uid))} & \tcode{neighbor_data} \\ + \tcode{for(auto\&\& [tid, n, val] : neighbors(g,uid,vvf))} & \tcode{neighbor_data} \\ \hline \end{tabular}} \caption{\tcode{neighbors} View Functions} @@ -328,11 +328,11 @@ \subsection{neighbors Views} \end{table} \subsection{edgelist Views} -\tcode{edgelist} views iterate over all edges for all vertices, returning a \tcode{edge_info} on each iteration. +\tcode{edgelist} views iterate over all edges for all vertices, returning a \tcode{edge_data} on each iteration. Table \ref{tab:edgelist} shows the \tcode{edgelist} function overloads and their return values. The range returned by \tcode{edgelist} adheres to the \tcode{basic_sourced_index_edgelist} concept (future proposals may only -adhere to \tcode{basic_sourced_edgelist}). If a \tcode{evf(uv)} function is passed, it adheres to the \tcode{has_edge_value} concept. +adhere to \tcode{basic_sourced_edgelist}). If a \tcode{evf(g,uv)} function is passed, it adheres to the \tcode{has_edge_value} concept. \begin{table}[h!] \begin{center} @@ -341,8 +341,8 @@ \subsection{edgelist Views} \hline \textbf{Example} & \textbf{Return} \\ \hline - \tcode{for(auto\&\& [u,v,uv] : edgelist(g))} & \tcode{edge_info} \\ - \tcode{for(auto\&\& [u,v,uv,val] : edgelist(g,evf))} & \tcode{edge_info} \\ + \tcode{for(auto\&\& [sid, tid, uv] : edgelist(g))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [sid, tid, uv, val] : edgelist(g,evf))} & \tcode{edge_data} \\ \hline \end{tabular}} \caption{\tcode{edgelist} View Functions} From 2073e7556a1179129c080547ea199a3c91c6b260 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 20:16:30 -0400 Subject: [PATCH 07/22] 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. --- D3129_Views/tex/views.tex | 14 ++++----- agents/views_update_plan.md | 61 ++++++++++++++++++++++++------------- 2 files changed, 47 insertions(+), 28 deletions(-) diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index 0857274..15be34c 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -295,8 +295,8 @@ \subsection{incidence Views} \hline \textbf{Example} & \textbf{Return} \\ \hline - \tcode{for(auto\&\& [tid, uv] : incidence(g,u))} & \tcode{edge_data} \\ - \tcode{for(auto\&\& [tid, uv, val] : incidence(g,u,evf))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [vid, uv] : incidence(g,u))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [vid, uv, val] : incidence(g,u,evf))} & \tcode{edge_data} \\ \hline \end{tabular}} \caption{\tcode{incidence} View Functions} @@ -318,8 +318,8 @@ \subsection{neighbors Views} \hline \textbf{Example} & \textbf{Return} \\ \hline - \tcode{for(auto\&\& [tid, n] : neighbors(g,uid))} & \tcode{neighbor_data} \\ - \tcode{for(auto\&\& [tid, n, val] : neighbors(g,uid,vvf))} & \tcode{neighbor_data} \\ + \tcode{for(auto\&\& [vid, v] : neighbors(g,uid))} & \tcode{neighbor_data} \\ + \tcode{for(auto\&\& [vid, v, val] : neighbors(g,uid,vvf))} & \tcode{neighbor_data} \\ \hline \end{tabular}} \caption{\tcode{neighbors} View Functions} @@ -341,8 +341,8 @@ \subsection{edgelist Views} \hline \textbf{Example} & \textbf{Return} \\ \hline - \tcode{for(auto\&\& [sid, tid, uv] : edgelist(g))} & \tcode{edge_data} \\ - \tcode{for(auto\&\& [sid, tid, uv, val] : edgelist(g,evf))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [uid, vid, uv] : edgelist(g))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [uid, vid, uv, val] : edgelist(g,evf))} & \tcode{edge_data} \\ \hline \end{tabular}} \caption{\tcode{edgelist} View Functions} @@ -386,7 +386,7 @@ \subsection{Common Types and Functions for ``Search'' } \begin{lstlisting} auto&& g = ...; // graph auto&& dfs = vertices_dfs(g,0); // start with vertex\_id=0 -for(auto&& [vid,v] : dfs) { +for(auto&& [uid,u] : dfs) { // No need to search deeper? if(depth(dfs) > 3) { cancel(dfs,cancel_search::cancel_branch); diff --git a/agents/views_update_plan.md b/agents/views_update_plan.md index 3437fec..e93bada 100644 --- a/agents/views_update_plan.md +++ b/agents/views_update_plan.md @@ -31,15 +31,34 @@ broken `\lstinputlisting` or undefined `\tcode` references). |------|---------|------| | LaTeX builds | `latexmk -output-directory=pdf -aux-directory=aux D3129_Views.tex` in P1709 | After every phase | +### Naming convention + +All structured bindings and prose must follow this convention consistently: + +| Symbol | Meaning | +|--------|---------| +| `u` | Source vertex (descriptor) | +| `v` | Target vertex (descriptor) | +| `uid` | Source vertex id | +| `vid` | Target vertex id | +| `uv` | Edge (from u to v) | + +**Context rules:** +- **Vertex-only iteration** (vertexlist, vertex search views): use `uid`/`u` for the iterated vertex. +- **Incidence / edge iteration**: `vid` = target id, `uv` = edge. +- **Neighbor iteration**: `vid` = target id, `v` = target vertex. +- **Edgelist iteration**: `uid` = source id, `vid` = target id, `uv` = edge. +- **Basic views** (id-only): same convention but without descriptor bindings (e.g., `[uid]`, `[vid]`, `[uid, vid]`). + --- ## Phase overview | Phase | Name | Depends on | Risk | Status | |-------|------|------------|------|--------| -| A | Source file rewrite (data structs) | — | Low — 3 small `.hpp` files | Not started | -| B | Data structs section rewrite | A | Medium — largest prose rewrite, tables | Not started | -| C | Graph views update (vertexlist, incidence, neighbors, edgelist) | B | Medium — table + prose changes | Not started | +| A | Source file rewrite (data structs) | — | Low — 3 small `.hpp` files | Done (ac5abdd) | +| B | Data structs section rewrite | A | Medium — largest prose rewrite, tables | Done (1152806) | +| C | Graph views update (vertexlist, incidence, neighbors, edgelist) | B | Medium — table + prose changes | Done (6f50537) | | D | Search common types update | B | Low — enum + member functions | Not started | | E | DFS / BFS views update | C, D | Medium — removals + binding changes | Not started | | F | Topological sort views update | C, D | Medium — signature changes + new `_safe` factories | Not started | @@ -236,8 +255,8 @@ Update surrounding prose: "returning a `vertex_info`" → "returning a `vertex_d | Old | New | |-----|-----| -| `for(auto&& [uv] : incidence(g,u))` → `edge_info` | `for(auto&& [tid, uv] : incidence(g,u))` → `edge_data` | -| `for(auto&& [uv,val] : incidence(g,u,evf))` → `edge_info` | `for(auto&& [tid, uv, val] : incidence(g,u,evf))` → `edge_data` | +| `for(auto&& [uv] : incidence(g,u))` → `edge_info` | `for(auto&& [vid, uv] : incidence(g,u))` → `edge_data` | +| `for(auto&& [uv,val] : incidence(g,u,evf))` → `edge_info` | `for(auto&& [vid, uv, val] : incidence(g,u,evf))` → `edge_data` | Update prose: `edge_info` → `edge_data`. @@ -245,8 +264,8 @@ Update prose: `edge_info` → `edge_data`. | Old | New | |-----|-----| -| `for(auto&& [v] : neighbors(g,uid))` → `neighbor_info` | `for(auto&& [tid, n] : neighbors(g,uid))` → `neighbor_data` | -| `for(auto&& [v,val] : neighbors(g,uid,vvf))` → `neighbor_info` | `for(auto&& [tid, n, val] : neighbors(g,uid,vvf))` → `neighbor_data` | +| `for(auto&& [v] : neighbors(g,uid))` → `neighbor_info` | `for(auto&& [vid, v] : neighbors(g,uid))` → `neighbor_data` | +| `for(auto&& [v,val] : neighbors(g,uid,vvf))` → `neighbor_info` | `for(auto&& [vid, v, val] : neighbors(g,uid,vvf))` → `neighbor_data` | Update prose: `neighbor_info` → `neighbor_data`, `vertex_info` → `vertex_data` (neighbors prose incorrectly says `vertex_info` in the LaTeX). @@ -255,8 +274,8 @@ prose incorrectly says `vertex_info` in the LaTeX). | Old | New | |-----|-----| -| `for(auto&& [u,v,uv] : edgelist(g))` → `edge_info` | `for(auto&& [sid, tid, uv] : edgelist(g))` → `edge_data` | -| `for(auto&& [u,v,uv,val] : edgelist(g,evf))` → `edge_info` | `for(auto&& [sid, tid, uv, val] : edgelist(g,evf))` → `edge_data` | +| `for(auto&& [u,v,uv] : edgelist(g))` → `edge_info` | `for(auto&& [uid, vid, uv] : edgelist(g))` → `edge_data` | +| `for(auto&& [u,v,uv,val] : edgelist(g,evf))` → `edge_info` | `for(auto&& [uid, vid, uv, val] : edgelist(g,evf))` → `edge_data` | Update prose: `edge_info` → `edge_data`. Update `evf(uv)` references to `evf(g,uv)`. @@ -333,8 +352,8 @@ Replace the free-function usage example: | Old Row | New Row | |---------|---------| -| `[v] : vertices_dfs(g,source)` → `vertex_info` | `[v] : vertices_dfs(g,seed)` → `vertex_data` | -| `[v,val] : vertices_dfs(g,source,vvf)` → `vertex_info` | `[v, val] : vertices_dfs(g,seed,vvf)` → `vertex_data` | +| `[v] : vertices_dfs(g,source)` → `vertex_info` | `[u] : vertices_dfs(g,seed)` → `vertex_data` | +| `[v,val] : vertices_dfs(g,source,vvf)` → `vertex_info` | `[u, val] : vertices_dfs(g,seed,vvf)` → `vertex_data` | | `[v,uv] : edges_dfs(g,source)` → `edge_info` | `[uv] : edges_dfs(g,seed)` → `edge_data` | | `[v,uv,val] : edges_dfs(g,source,evf)` → `edge_info` | `[uv, val] : edges_dfs(g,seed,evf)` → `edge_data` | | `[u,v,uv] : sourced_edges_dfs(g,source)` | **Remove** | @@ -353,8 +372,8 @@ Identical structural changes as DFS: | Old Row | New Row | |---------|---------| -| `[v] : vertices_bfs(g,source)` → `vertex_info` | `[v] : vertices_bfs(g,seed)` → `vertex_data` | -| `[v,val] : vertices_bfs(g,source,vvf)` → `vertex_info` | `[v, val] : vertices_bfs(g,seed,vvf)` → `vertex_data` | +| `[v] : vertices_bfs(g,source)` → `vertex_info` | `[u] : vertices_bfs(g,seed)` → `vertex_data` | +| `[v,val] : vertices_bfs(g,source,vvf)` → `vertex_info` | `[u, val] : vertices_bfs(g,seed,vvf)` → `vertex_data` | | `[v,uv] : edges_bfs(g,source)` → `edge_info` | `[uv] : edges_bfs(g,seed)` → `edge_data` | | `[v,uv,val] : edges_bfs(g,source,evf)` → `edge_info` | `[uv, val] : edges_bfs(g,seed,evf)` → `edge_data` | | `[u,v,uv] : sourced_edges_bfs(g,source)` | **Remove** | @@ -389,8 +408,8 @@ and add `_safe` factory documentation. | Old Row | New Row | |---------|---------| -| `[v] : vertices_topological_sort(g,source)` | `[v] : vertices_topological_sort(g)` — no source param | -| `[v,val] : vertices_topological_sort(g,source,vvf)` | `[v, val] : vertices_topological_sort(g,vvf)` | +| `[v] : vertices_topological_sort(g,source)` | `[u] : vertices_topological_sort(g)` — no source param | +| `[v,val] : vertices_topological_sort(g,source,vvf)` | `[u, val] : vertices_topological_sort(g,vvf)` | | `[v,uv] : edges_topological_sort(g,source)` | `[uv] : edges_topological_sort(g)` — VId=void | | `[v,uv,val] : edges_topological_sort(g,source,evf)` | `[uv, val] : edges_topological_sort(g,evf)` | | `[u,v,uv] : sourced_edges_topological_sort(g,source)` | **Remove** | @@ -451,20 +470,20 @@ Add rows to each graph view table from Phase C: **incidence:** | New Row | Return | |---------|--------| -| `for(auto&& [tid] : basic_incidence(g,uid))` | `edge_data` | -| `for(auto&& [tid, val] : basic_incidence(g,uid,evf))` | `edge_data` | +| `for(auto&& [vid] : basic_incidence(g,uid))` | `edge_data` | +| `for(auto&& [vid, val] : basic_incidence(g,uid,evf))` | `edge_data` | **neighbors:** | New Row | Return | |---------|--------| -| `for(auto&& [tid] : basic_neighbors(g,uid))` | `neighbor_data` | -| `for(auto&& [tid, val] : basic_neighbors(g,uid,vvf))` | `neighbor_data` | +| `for(auto&& [vid] : basic_neighbors(g,uid))` | `neighbor_data` | +| `for(auto&& [vid, val] : basic_neighbors(g,uid,vvf))` | `neighbor_data` | **edgelist:** | New Row | Return | |---------|--------| -| `for(auto&& [sid, tid] : basic_edgelist(g))` | `edge_data` | -| `for(auto&& [sid, tid, val] : basic_edgelist(g,evf))` | `edge_data` | +| `for(auto&& [uid, vid] : basic_edgelist(g))` | `edge_data` | +| `for(auto&& [uid, vid, val] : basic_edgelist(g,evf))` | `edge_data` | Add brief prose explaining that basic views omit descriptors and yield only IDs. From ce8f76afdf7ef53eb267d47887f020a2a85a69e8 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 20:36:45 -0400 Subject: [PATCH 08/22] =?UTF-8?q?Phase=20D:=20Update=20search=20common=20t?= =?UTF-8?q?ypes=20=E2=80=94=20member=20functions,=20search=5Fview=20concep?= =?UTF-8?q?t?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- D3129_Views/tex/views.tex | 64 ++++++++++++++++++++------------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index 15be34c..b6aee5b 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -353,57 +353,59 @@ \subsection{edgelist Views} \section{"Search" Views} \subsection{Common Types and Functions for ``Search'' } -\phil{Do these apply to all "search" functions?} -The Depth First, Breadth First, and Topological Sort searches share a number of common types and functions. +The Depth First, Breadth First, and Topological Sort searches share a number of common types and member functions. -Here are the types and functions for cancelling a search, getting the current depth of the search, and active elements in the search (e.g. number of vertices in a stack or queue). +Search views provide member functions for cancelling a search, querying the current depth, and the number of vertices or edges visited so far. The \tcode{cancel_search} enumeration controls search cancellation: \begin{lstlisting} -// enum used to define how to cancel a search -enum struct cancel_search : int8_t { - continue_search, // no change (ignored) - cancel_branch, // stops searching from current vertex - cancel_all // stops searching and dfs will be at end() +enum class cancel_search { + continue_search, // continue normal traversal + cancel_branch, // skip current subtree/branch, continue with siblings + cancel_all // stop entire search immediately }; +\end{lstlisting} -// stop searching from current vertex -template -void cancel(S search, cancel_search); - -// Returns distance from the source vertex to the current vertex, -// or to the target vertex for edge views -template -auto depth(S search) -> integral; +Each search view exposes the following member functions: +\begin{lstlisting} +cancel_search cancel() const noexcept; // get current cancel state +void cancel(cancel_search c) noexcept; // set cancel state +std::size_t depth() const noexcept; // distance from seed to current vertex +std::size_t num_visited() const noexcept; // total vertices/edges visited so far +\end{lstlisting} -// Returns number of pending vertices to process -template -auto size(S search) -> integral; +The \tcode{search_view} concept captures these requirements: +\begin{lstlisting} +template +concept search_view = requires(V& v, const V& cv) { + { v.cancel() } -> std::convertible_to; + { cv.depth() } -> std::convertible_to; + { cv.num_visited() } -> std::convertible_to; +}; \end{lstlisting} -Of particular note, \tcode{size(dfs)} is typically the same as \tcode{depth(dfs)} and is simple to calculate. breadth\_first\_search requires extra bookkeeping to evaluate \tcode{depth(bfs)} and returns a different value than \tcode{size(bfs)}. +Topological sort views support \tcode{cancel()} and \tcode{num_visited()} but not \tcode{depth()} (flat ordering has no tree structure), so they do not satisfy \tcode{search_view}. + +For DFS, \tcode{dfs.num_visited()} is typically close to \tcode{dfs.depth()} and is simple to calculate. Breadth-first search requires extra bookkeeping to evaluate \tcode{bfs.depth()}, which returns a different value than \tcode{bfs.num_visited()}. -The following example shows how the functions could be used, using \tcode{dfs} for one of the depth\_first\_search views. The same functions can be used for all all search views. +The following example shows how the member functions could be used, using \tcode{dfs} for one of the depth-first search views. The same members are available on all search views that satisfy \tcode{search_view}. \begin{lstlisting} auto&& g = ...; // graph -auto&& dfs = vertices_dfs(g,0); // start with vertex\_id=0 +auto&& dfs = vertices_dfs(g,0); // start with seed vertex\_id=0 for(auto&& [uid,u] : dfs) { // No need to search deeper? - if(depth(dfs) > 3) { - cancel(dfs,cancel_search::cancel_branch); + if(dfs.depth() > 3) { + dfs.cancel(cancel_search::cancel_branch); continue; } - - if(size(dfs) > 1000) { - std::cout << "Big depth of " << size(dfs) << '\n'; + + if(dfs.num_visited() > 1000) { + std::cout << "Many visited: " << dfs.num_visited() << '\n'; } - + // do useful things } \end{lstlisting} -The range returned by \textit{sourced} views (includes source\_id) adheres to the \tcode{basic_sourced_index_edgelist} concept. If a -\tcode{evf(uv)} function is passed, it also adheres to the \tcode{has_edge_value} concept. - \subsection{Depth First Search Views} Depth First Search views iterate over the vertices and edges from a given source vertex, returning a \tcode{vertex_info} or \tcode{edge_info} on each iteration when it is first encountered, depending on the function used. From 4ee7cc1e4faf75f091b3033cd3e49f0ca15f430a Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 20:39:32 -0400 Subject: [PATCH 09/22] =?UTF-8?q?Phase=20E:=20Update=20DFS/BFS=20views=20?= =?UTF-8?q?=E2=80=94=20remove=20sourced,=20descriptor-based=20return?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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). --- D3129_Views/tex/views.tex | 58 +++++++++------------------------------ 1 file changed, 13 insertions(+), 45 deletions(-) diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index b6aee5b..0dc0d86 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -408,20 +408,7 @@ \subsection{Common Types and Functions for ``Search'' } \subsection{Depth First Search Views} -Depth First Search views iterate over the vertices and edges from a given source vertex, returning a \tcode{vertex_info} or \tcode{edge_info} on each iteration when it is first encountered, depending on the function used. -Table \ref{tab:dfs} shows the functions and their return values. - -%The \tcode{alloc} parameter shown in the following examples is optional and defaults to \tcode{std::allocator}. It is used for containers -%that are internal to the view. The \tcode{bool} argument has no particular meaning. - -% basic_edges_dfs(g,source,evf) implies the use of Sourced type internally to have source_id in the call call to evf(eid) - -\phil{Consider adding an enum bitset of events matching the visitor events, and creating Overloads - that accept the bitset. The returned type would be a subclass of \tcode{vertex_info} or \tcode{edge_info} - and would add the event bitset as a final member value, with the bit set for the event . This could offer a similar benefit as - coroutines.} - -\phil{sourced\_edges\_dfs introduces the idea that we can have source, target and edge descriptors. Make sure edge\_info can handle that.} +Depth First Search views iterate over vertices and edges reachable from a seed vertex, yielding a \tcode{vertex_data} or \tcode{edge_data} for each element when it is first encountered. Table \ref{tab:dfs} shows the factory functions and their return types. \begin{table}[h!] \begin{center} @@ -430,14 +417,11 @@ \subsection{Depth First Search Views} \hline \textbf{Example} & \textbf{Return} \\ \hline - \tcode{for(auto\&\& [v] : vertices_dfs(g,source))} & \tcode{vertex_info} \\ - \tcode{for(auto\&\& [v,val] : vertices_dfs(g,source,vvf))} & \tcode{vertex_info} \\ -\hdashline - \tcode{for(auto\&\& [v,uv] : edges_dfs(g,source))} & \tcode{edge_info} \\ - \tcode{for(auto\&\& [v,uv,val] : edges_dfs(g,source,evf))} & \tcode{edge_info} \\ + \tcode{for(auto\&\& [u] : vertices_dfs(g,seed))} & \tcode{vertex_data} \\ + \tcode{for(auto\&\& [u,val] : vertices_dfs(g,seed,vvf))} & \tcode{vertex_data} \\ \hdashline - \tcode{for(auto\&\& [u,v,uv] : sourced_edges_dfs(g,source))} & \tcode{edge_info} \\ - \tcode{for(auto\&\& [u,v,uv,val] : sourced_edges_dfs(g,source,evf))} & \tcode{edge_info} \\ + \tcode{for(auto\&\& [uv] : edges_dfs(g,seed))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [uv,val] : edges_dfs(g,seed,evf))} & \tcode{edge_data} \\ \hline \end{tabular}} \caption{depth\_first\_search View Functions} @@ -446,23 +430,8 @@ \subsection{Depth First Search Views} \end{table} \subsection{Breadth First Search Views} -\phil{NetworkX provides an optional depth\_limit parameter for bfs. Add? } - -Breadth First Search views iterate over the vertices and edges from a given source vertex, returning a \tcode{vertex_info} -or \tcode{edge_info} on each iteration when it is first encountered, depending on the function used. -Table \ref{tab:bfs} shows the functions and their return values. -%The \tcode{alloc} parameter shown in the following examples is optional and defaults to \tcode{std::allocator}. It is used for containers -%that are internal to the view. The \tcode{bool} argument has no particular meaning. - -% basic_edges_bfs(g,source,evf) implies the use of Sourced type internally to have source_id in the call call to evf(eid) - -\phil{Consider adding an enum bitset of events matching the visitor events, and creating Overloads - that accept the bitset. The returned type would be a subclass of \tcode{vertex_info} or \tcode{edge_info} - and would add the event bitset as a final member value, with the bit set for the event . This could offer a similar benefit as - coroutines.} - -\phil{sourced\_edges\_bfs introduces the idea that we can have source, target and edge descriptors. Make sure edge\_info can handle that.} +Breadth First Search views iterate over vertices and edges reachable from a seed vertex, yielding a \tcode{vertex_data} or \tcode{edge_data} for each element when it is first encountered. Table \ref{tab:bfs} shows the factory functions and their return types. \begin{table}[h!] \begin{center} @@ -471,15 +440,11 @@ \subsection{Breadth First Search Views} \hline \textbf{Example} & \textbf{Return} \\ \hline + \tcode{for(auto\&\& [u] : vertices_bfs(g,seed))} & \tcode{vertex_data} \\ + \tcode{for(auto\&\& [u,val] : vertices_bfs(g,seed,vvf))} & \tcode{vertex_data} \\ \hdashline - \tcode{for(auto\&\& [v] : vertices_bfs(g,source))} & \tcode{vertex_info} \\ - \tcode{for(auto\&\& [v,val] : vertices_bfs(g,source,vvf))} & \tcode{vertex_info} \\ -\hdashline - \tcode{for(auto\&\& [v,uv] : edges_bfs(g,source))} & \tcode{edge_info} \\ - \tcode{for(auto\&\& [v,uv,val] : edges_bfs(g,source,evf))} & \tcode{edge_info} \\ -\hdashline - \tcode{for(auto\&\& [u,v,uv] : sourced_edges_bfs(g,source))} & \tcode{edge_info} \\ - \tcode{for(auto\&\& [u,v,uv,val] : sourced_edges_bfs(g,source,evf))} & \tcode{edge_info} \\ + \tcode{for(auto\&\& [uv] : edges_bfs(g,seed))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [uv,val] : edges_bfs(g,seed,evf))} & \tcode{edge_data} \\ \hline \end{tabular}} \caption{breadth\_first\_search View Functions} @@ -487,6 +452,9 @@ \subsection{Breadth First Search Views} \end{center} \end{table} +\paragraph{Design Note.} +Search views yield vertex and edge \emph{descriptors} rather than vertex IDs (\tcode{VId} is \tcode{void} in the returned data structs). A vertex ID can always be obtained from a descriptor via \tcode{vertex_id(g, u)}. Descriptors provide richer access to vertex and edge properties through CPOs such as \tcode{vertex_value(g, u)} and \tcode{edge_value(g, uv)}. + \subsection{Topological Sort Views} Topological Sort views iterate over the vertices and edges from a given source vertex, returning a \tcode{vertex_info} or \tcode{edge_info} on each iteration when it is first encountered, depending on the function used. From 8552f767373b0f1275e2975564fdd3afd7b300e1 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 20:47:34 -0400 Subject: [PATCH 10/22] =?UTF-8?q?Phase=20F:=20Update=20topological=20sort?= =?UTF-8?q?=20=E2=80=94=20all-vertex,=20=5Fsafe=20factories,=20remove=20so?= =?UTF-8?q?urced?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- D3129_Views/tex/views.tex | 51 +++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index 0dc0d86..d27b997 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -456,21 +456,9 @@ \subsection{Breadth First Search Views} Search views yield vertex and edge \emph{descriptors} rather than vertex IDs (\tcode{VId} is \tcode{void} in the returned data structs). A vertex ID can always be obtained from a descriptor via \tcode{vertex_id(g, u)}. Descriptors provide richer access to vertex and edge properties through CPOs such as \tcode{vertex_value(g, u)} and \tcode{edge_value(g, uv)}. \subsection{Topological Sort Views} -Topological Sort views iterate over the vertices and edges from a given source vertex, returning a \tcode{vertex_info} or -\tcode{edge_info} on each iteration when it is first encountered, depending on the function used. -Table \ref{tab:topo_sort} shows the functions and their return values. +Topological Sort views iterate over all vertices and edges in the graph in topological order, yielding a \tcode{vertex_data} or \tcode{edge_data} for each element when it is first encountered. Table \ref{tab:topo_sort} shows the factory functions and their return types. -%The \tcode{alloc} parameter shown in the following examples is optional and defaults to \tcode{std::allocator}. It is used for containers -%that are internal to the view. The \tcode{bool} argument has no particular meaning. - -% basic_edges_topological_sort(g,source,evf) implies the use of Sourced type internally to have source_id in the call call to evf(eid) - -\phil{Consider adding an enum bitset of events matching the visitor events, and creating Overloads - that accept the bitset. The returned type would be a subclass of \tcode{vertex_info} or \tcode{edge_info} - and would add the event bitset as a final member value, with the bit set for the event . This could offer a similar benefit as - coroutines.} - -\phil{topological\_sort introduces the idea that we can have source, target and edge descriptors. Make sure edge\_info can handle that.} +Topological sort views support \tcode{cancel()} and \tcode{num_visited()} but not \tcode{depth()}, because the flat topological ordering has no tree structure. As a consequence, they do not satisfy the \tcode{search_view} concept. Note that \tcode{cancel_branch} behaves the same as \tcode{cancel_all} for topological sort, since there is no branch to skip in a flat ordering. \begin{table}[h!] \begin{center} @@ -479,14 +467,11 @@ \subsection{Topological Sort Views} \hline \textbf{Example} & \textbf{Return} \\ \hline - \tcode{for(auto\&\& [v] : vertices_topological_sort(g,source))} & \tcode{vertex_info} \\ - \tcode{for(auto\&\& [v,val] : vertices_topological_sort(g,source,vvf))} & \tcode{vertex_info} \\ + \tcode{for(auto\&\& [u] : vertices_topological_sort(g))} & \tcode{vertex_data} \\ + \tcode{for(auto\&\& [u,val] : vertices_topological_sort(g,vvf))} & \tcode{vertex_data} \\ \hdashline - \tcode{for(auto\&\& [v,uv] : edges_topological_sort(g,source))} & \tcode{edge_info} \\ - \tcode{for(auto\&\& [v,uv,val] : edges_topological_sort(g,source,evf))} & \tcode{edge_info} \\ -\hdashline - \tcode{for(auto\&\& [u,v,uv] : sourced_edges_topological_sort(g,source))} & \tcode{edge_info} \\ - \tcode{for(auto\&\& [u,v,uv,val] : sourced_edges_topological_sort(g,source,evf))} & \tcode{edge_info} \\ + \tcode{for(auto\&\& [uv] : edges_topological_sort(g))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [uv,val] : edges_topological_sort(g,evf))} & \tcode{edge_data} \\ \hline \end{tabular}} \caption{topological\_sort View Functions} @@ -494,3 +479,27 @@ \subsection{Topological Sort Views} \end{center} \end{table} +\paragraph{Cycle-detecting factories.} +The \tcode{_safe} factory variants detect cycles during construction and return a \tcode{std::expected}. On success the expected value is the topological sort view; on failure the unexpected value is the \tcode{vertex_t} where the cycle was detected. Table \ref{tab:topo_sort_safe} shows these factories. + +\begin{table}[h!] +\begin{center} +\resizebox{\textwidth}{!} +{\begin{tabular}{l l} +\hline + \textbf{Factory} & \textbf{Return} \\ +\hline + \tcode{vertices_topological_sort_safe(g)} & \tcode{std::expected<}\textit{view}\tcode{, vertex_t>} \\ + \tcode{vertices_topological_sort_safe(g,vvf)} & \tcode{std::expected<}\textit{view}\tcode{, vertex_t>} \\ +\hdashline + \tcode{edges_topological_sort_safe(g)} & \tcode{std::expected<}\textit{view}\tcode{, vertex_t>} \\ + \tcode{edges_topological_sort_safe(g,evf)} & \tcode{std::expected<}\textit{view}\tcode{, vertex_t>} \\ +\hline +\end{tabular}} +\caption{topological\_sort Safe Factory Functions} +\label{tab:topo_sort_safe} +\end{center} +\end{table} + +The paper specifies \tcode{std::expected} (C++23). The reference implementation provides backward compatibility to C++20 via an external expected library (e.g., \tcode{tl::expected}), switching to \tcode{std::expected} when C++23 or later is available. + From fb0171222519276b7ebb8e8677227b4468858ce1 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 21:05:42 -0400 Subject: [PATCH 11/22] Phase G: Add basic views, in_ variants, transpose, pipe syntax, VVF/EVF concepts --- D3129_Views/tex/views.tex | 177 +++++++++++++++++++++++++++++++++++++- 1 file changed, 176 insertions(+), 1 deletion(-) diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index d27b997..5359ae3 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -33,6 +33,9 @@ \section{Introduction} Additionally, \tcode{stack} and \tcode{queue} require memory allocation which could throw a \tcode{bad_alloc} exception. +\paragraph{Value Function Concepts.} +Many views accept a \emph{vertex value function} (\tcode{vvf}) or \emph{edge value function} (\tcode{evf}) that projects a user-defined value from each vertex or edge. The \tcode{vertex_value_function} and \tcode{edge_value_function} concepts (defined in D3130, Graph Container Interface) constrain these parameters and are used throughout this paper. + \section{Data Structs (Return Types)} Views return one of the types in this section, providing a consistent set of value types for all graph data structures. They are templated so that the view can adjust the types of the members to be appropriate for its use. The three types, @@ -259,7 +262,7 @@ \subsection{vertexlist Views} \begin{table}[h!] \begin{center} -%\resizebox{\textwidth}{!} +\resizebox{\textwidth}{!} {\begin{tabular}{l l} \hline \textbf{Example} & \textbf{Return} \\ @@ -270,6 +273,9 @@ \subsection{vertexlist Views} \tcode{for(auto\&\& [uid, u, val] : vertexlist(g,first,last,vvf))} & \tcode{vertex_data} \\ \tcode{for(auto\&\& [uid, u] : vertexlist(g,vr))} & \tcode{vertex_data} \\ \tcode{for(auto\&\& [uid, u, val] : vertexlist(g,vr,vvf))} & \tcode{vertex_data} \\ +\hdashline + \tcode{for(auto\&\& [uid] : basic_vertexlist(g))} & \tcode{vertex_data} \\ + \tcode{for(auto\&\& [uid, val] : basic_vertexlist(g,vvf))} & \tcode{vertex_data} \\ \hline \end{tabular}} \caption{\tcode{vertexlist} View Functions} @@ -277,6 +283,8 @@ \subsection{vertexlist Views} \end{center} \end{table} +The \tcode{basic_vertexlist} variants omit the vertex descriptor and yield only vertex IDs. They are useful when algorithms need only the vertex identity, not a reference to the vertex object. + \subsection{incidence Views} \tcode{incidence} views iterate over a range of adjacent edges of a vertex, returning a \tcode{edge_data} on each iteration. Table \ref{tab:incidence} shows the \tcode{incidence} function overloads and their return values. @@ -297,6 +305,9 @@ \subsection{incidence Views} \hline \tcode{for(auto\&\& [vid, uv] : incidence(g,u))} & \tcode{edge_data} \\ \tcode{for(auto\&\& [vid, uv, val] : incidence(g,u,evf))} & \tcode{edge_data} \\ +\hdashline + \tcode{for(auto\&\& [vid] : basic_incidence(g,uid))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [vid, val] : basic_incidence(g,uid,evf))} & \tcode{edge_data} \\ \hline \end{tabular}} \caption{\tcode{incidence} View Functions} @@ -304,6 +315,33 @@ \subsection{incidence Views} \end{center} \end{table} +\subsection{in\_incidence Views} +\tcode{in_incidence} views iterate over the incoming edges of a vertex, returning an \tcode{edge_data} on each iteration. +They mirror the \tcode{incidence} views but traverse edges whose target is the given vertex rather than edges whose source is the given vertex. +These views require the graph to model \tcode{bidirectional_adjacency_list}. +Table \ref{tab:in_incidence} shows the \tcode{in\_incidence} function overloads and their return values. + +\begin{table}[h!] +\begin{center} +%\resizebox{\textwidth}{!} +{\begin{tabular}{l l} +\hline + \textbf{Example} & \textbf{Return} \\ +\hline + \tcode{for(auto\&\& [vid, uv] : in_incidence(g,u))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [vid, uv, val] : in_incidence(g,u,evf))} & \tcode{edge_data} \\ +\hdashline + \tcode{for(auto\&\& [vid] : basic_in_incidence(g,uid))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [vid, val] : basic_in_incidence(g,uid,evf))} & \tcode{edge_data} \\ +\hline +\end{tabular}} +\caption{\tcode{in\_incidence} View Functions} +\label{tab:in_incidence} +\end{center} +\end{table} + +For incoming edges the returned \tcode{id} member is the source vertex id of the incoming edge (i.e.\ the ``other'' end). The data structs are identical to those used by \tcode{incidence}; only the direction of traversal changes. + \subsection{neighbors Views} \tcode{neighbors} views iterate over a range of edges for a vertex, returning a \tcode{neighbor_data} of each neighboring target vertex on each iteration. Table \ref{tab:neighbors} shows the \tcode{neighbors} function overloads and their return values. @@ -320,6 +358,9 @@ \subsection{neighbors Views} \hline \tcode{for(auto\&\& [vid, v] : neighbors(g,uid))} & \tcode{neighbor_data} \\ \tcode{for(auto\&\& [vid, v, val] : neighbors(g,uid,vvf))} & \tcode{neighbor_data} \\ +\hdashline + \tcode{for(auto\&\& [vid] : basic_neighbors(g,uid))} & \tcode{neighbor_data} \\ + \tcode{for(auto\&\& [vid, val] : basic_neighbors(g,uid,vvf))} & \tcode{neighbor_data} \\ \hline \end{tabular}} \caption{\tcode{neighbors} View Functions} @@ -327,6 +368,36 @@ \subsection{neighbors Views} \end{center} \end{table} +\subsection{in\_neighbors Views} +\tcode{in_neighbors} views iterate over the incoming neighbors of a vertex, returning a \tcode{neighbor_data} for each source vertex of an incoming edge. +They mirror the \tcode{neighbors} views but traverse incoming rather than outgoing edges. +These views require the graph to model \tcode{bidirectional_adjacency_list}. +Table \ref{tab:in_neighbors} shows the \tcode{in\_neighbors} function overloads and their return values. + +\begin{table}[h!] +\begin{center} +%\resizebox{\textwidth}{!} +{\begin{tabular}{l l} +\hline + \textbf{Example} & \textbf{Return} \\ +\hline + \tcode{for(auto\&\& [vid, v] : in_neighbors(g,uid))} & \tcode{neighbor_data} \\ + \tcode{for(auto\&\& [vid, v, val] : in_neighbors(g,uid,vvf))} & \tcode{neighbor_data} \\ +\hdashline + \tcode{for(auto\&\& [vid] : basic_in_neighbors(g,uid))} & \tcode{neighbor_data} \\ + \tcode{for(auto\&\& [vid, val] : basic_in_neighbors(g,uid,vvf))} & \tcode{neighbor_data} \\ +\hline +\end{tabular}} +\caption{\tcode{in\_neighbors} View Functions} +\label{tab:in_neighbors} +\end{center} +\end{table} + +As with \tcode{in_incidence}, the returned \tcode{id} member is the source vertex id of the incoming edge. + +\paragraph{Edge Accessor Mechanism (Exposition Only).} +Internally, the outgoing and incoming view variants share the same view class templates. An \emph{edge accessor} policy selects the traversal direction: \tcode{out_edge_accessor} (the default) uses \tcode{edges(g,u)} and \tcode{target_id(g,uv)}, while \tcode{in_edge_accessor} uses \tcode{in_edges(g,u)} and \tcode{source_id(g,uv)}. This mechanism is exposition-only and not part of the public interface. + \subsection{edgelist Views} \tcode{edgelist} views iterate over all edges for all vertices, returning a \tcode{edge_data} on each iteration. Table \ref{tab:edgelist} shows the \tcode{edgelist} function overloads and their return values. @@ -343,6 +414,9 @@ \subsection{edgelist Views} \hline \tcode{for(auto\&\& [uid, vid, uv] : edgelist(g))} & \tcode{edge_data} \\ \tcode{for(auto\&\& [uid, vid, uv, val] : edgelist(g,evf))} & \tcode{edge_data} \\ +\hdashline + \tcode{for(auto\&\& [uid, vid] : basic_edgelist(g))} & \tcode{edge_data} \\ + \tcode{for(auto\&\& [uid, vid, val] : basic_edgelist(g,evf))} & \tcode{edge_data} \\ \hline \end{tabular}} \caption{\tcode{edgelist} View Functions} @@ -350,6 +424,20 @@ \subsection{edgelist Views} \end{center} \end{table} +\subsection{transpose View} +The \tcode{transpose} view provides a zero-cost wrapper around a bidirectional graph that swaps the direction of edge traversal. Outgoing edges become incoming and vice versa. It is not a range itself but a graph adaptor: the result models the same graph concepts as the underlying graph with directions reversed. + +\tcode{transpose_view} requires the graph to model \tcode{bidirectional_adjacency_list}. When the underlying graph also models \tcode{index_bidirectional_adjacency_list}, the transposed view does too. + +\begin{lstlisting} +auto gt = transpose(g); // gt is a transpose\_view +for(auto&& [vid, uv] : incidence(gt, u)) { + // iterates what were incoming edges of u in g +} +\end{lstlisting} + +Because \tcode{transpose} is a graph wrapper rather than an edge-level view, it composes with all other views: \tcode{incidence(transpose(g), u)} traverses incoming edges, \tcode{vertexlist(transpose(g))} is unchanged, and algorithm templates work transparently on the transposed graph. + \section{"Search" Views} \subsection{Common Types and Functions for ``Search'' } @@ -455,6 +543,13 @@ \subsection{Breadth First Search Views} \paragraph{Design Note.} Search views yield vertex and edge \emph{descriptors} rather than vertex IDs (\tcode{VId} is \tcode{void} in the returned data structs). A vertex ID can always be obtained from a descriptor via \tcode{vertex_id(g, u)}. Descriptors provide richer access to vertex and edge properties through CPOs such as \tcode{vertex_value(g, u)} and \tcode{edge_value(g, uv)}. +\paragraph{Allocator Support.} +All DFS and BFS factory functions accept an optional trailing allocator parameter for their internal data structures. When a value function is also provided, the allocator is disambiguated via a \tcode{requires(!vertex_value_function)} constraint. For example: +\begin{lstlisting} +vertices_dfs(g, seed, alloc) // allocator, no value function +vertices_dfs(g, seed, vvf, alloc) // value function + allocator +\end{lstlisting} + \subsection{Topological Sort Views} Topological Sort views iterate over all vertices and edges in the graph in topological order, yielding a \tcode{vertex_data} or \tcode{edge_data} for each element when it is first encountered. Table \ref{tab:topo_sort} shows the factory functions and their return types. @@ -503,3 +598,83 @@ \subsection{Topological Sort Views} The paper specifies \tcode{std::expected} (C++23). The reference implementation provides backward compatibility to C++20 via an external expected library (e.g., \tcode{tl::expected}), switching to \tcode{std::expected} when C++23 or later is available. +\paragraph{Allocator Support.} +Topological sort factory functions also accept an optional trailing allocator parameter, following the same pattern as DFS and BFS. + +\section{Range Adaptors (Pipe Syntax)} + +All view factory functions described in this paper are also available as range adaptor closure objects, enabling pipe syntax. The adaptor objects live in \tcode{namespace graph::views} and forward to the corresponding factory function. Table \ref{tab:adaptors_graph} shows the graph view adaptors and Table \ref{tab:adaptors_search} shows the search view adaptors. + +\begin{table}[h!] +\begin{center} +\resizebox{\textwidth}{!} +{\begin{tabular}{l l} +\hline + \textbf{Pipe Expression} & \textbf{Equivalent Factory Call} \\ +\hline + \tcode{g | vertexlist()} & \tcode{vertexlist(g)} \\ + \tcode{g | vertexlist(vvf)} & \tcode{vertexlist(g,vvf)} \\ + \tcode{g | basic_vertexlist()} & \tcode{basic_vertexlist(g)} \\ + \tcode{g | basic_vertexlist(vvf)} & \tcode{basic_vertexlist(g,vvf)} \\ +\hdashline + \tcode{g | incidence(uid)} & \tcode{incidence(g,uid)} \\ + \tcode{g | incidence(uid, evf)} & \tcode{incidence(g,uid,evf)} \\ + \tcode{g | basic_incidence(uid)} & \tcode{basic_incidence(g,uid)} \\ + \tcode{g | basic_incidence(uid, evf)} & \tcode{basic_incidence(g,uid,evf)} \\ +\hdashline + \tcode{g | in_incidence(uid)} & \tcode{in_incidence(g,uid)} \\ + \tcode{g | in_incidence(uid, evf)} & \tcode{in_incidence(g,uid,evf)} \\ + \tcode{g | basic_in_incidence(uid)} & \tcode{basic_in_incidence(g,uid)} \\ + \tcode{g | basic_in_incidence(uid, evf)} & \tcode{basic_in_incidence(g,uid,evf)} \\ +\hdashline + \tcode{g | neighbors(uid)} & \tcode{neighbors(g,uid)} \\ + \tcode{g | neighbors(uid, vvf)} & \tcode{neighbors(g,uid,vvf)} \\ + \tcode{g | basic_neighbors(uid)} & \tcode{basic_neighbors(g,uid)} \\ + \tcode{g | basic_neighbors(uid, vvf)} & \tcode{basic_neighbors(g,uid,vvf)} \\ +\hdashline + \tcode{g | in_neighbors(uid)} & \tcode{in_neighbors(g,uid)} \\ + \tcode{g | in_neighbors(uid, vvf)} & \tcode{in_neighbors(g,uid,vvf)} \\ + \tcode{g | basic_in_neighbors(uid)} & \tcode{basic_in_neighbors(g,uid)} \\ + \tcode{g | basic_in_neighbors(uid, vvf)} & \tcode{basic_in_neighbors(g,uid,vvf)} \\ +\hdashline + \tcode{g | edgelist()} & \tcode{edgelist(g)} \\ + \tcode{g | edgelist(evf)} & \tcode{edgelist(g,evf)} \\ + \tcode{g | basic_edgelist()} & \tcode{basic_edgelist(g)} \\ + \tcode{g | basic_edgelist(evf)} & \tcode{basic_edgelist(g,evf)} \\ +\hline +\end{tabular}} +\caption{Graph View Range Adaptors} +\label{tab:adaptors_graph} +\end{center} +\end{table} + +\begin{table}[h!] +\begin{center} +\resizebox{\textwidth}{!} +{\begin{tabular}{l l} +\hline + \textbf{Pipe Expression} & \textbf{Equivalent Factory Call} \\ +\hline + \tcode{g | vertices_dfs(seed)} & \tcode{vertices_dfs(g,seed)} \\ + \tcode{g | vertices_dfs(seed, vvf)} & \tcode{vertices_dfs(g,seed,vvf)} \\ + \tcode{g | edges_dfs(seed)} & \tcode{edges_dfs(g,seed)} \\ + \tcode{g | edges_dfs(seed, evf)} & \tcode{edges_dfs(g,seed,evf)} \\ +\hdashline + \tcode{g | vertices_bfs(seed)} & \tcode{vertices_bfs(g,seed)} \\ + \tcode{g | vertices_bfs(seed, vvf)} & \tcode{vertices_bfs(g,seed,vvf)} \\ + \tcode{g | edges_bfs(seed)} & \tcode{edges_bfs(g,seed)} \\ + \tcode{g | edges_bfs(seed, evf)} & \tcode{edges_bfs(g,seed,evf)} \\ +\hdashline + \tcode{g | vertices_topological_sort()} & \tcode{vertices_topological_sort(g)} \\ + \tcode{g | vertices_topological_sort(vvf)} & \tcode{vertices_topological_sort(g,vvf)} \\ + \tcode{g | edges_topological_sort()} & \tcode{edges_topological_sort(g)} \\ + \tcode{g | edges_topological_sort(evf)} & \tcode{edges_topological_sort(g,evf)} \\ +\hline +\end{tabular}} +\caption{Search View Range Adaptors} +\label{tab:adaptors_search} +\end{center} +\end{table} + +The \tcode{in_incidence}, \tcode{in_neighbors}, and their \tcode{basic_} variants require the graph to model \tcode{index_bidirectional_adjacency_list} when used as pipe adaptors (vertex-id overloads). + From 51b85b051397fa707cb8a0143b9fa54bc9788762 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 21:10:17 -0400 Subject: [PATCH 12/22] =?UTF-8?q?Phase=20H:=20Prose=20audit=20=E2=80=94=20?= =?UTF-8?q?cleanup=20phil=20notes,=20rename=20all=20obsolete=20types?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- D3129_Views/tex/views.tex | 76 ++------------------------------------- 1 file changed, 3 insertions(+), 73 deletions(-) diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index 5359ae3..72f84fe 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -4,28 +4,9 @@ \section{Introduction} -\phil{Use \tcode{basic_index_adjacency_list} as the concept for all views.} - -\phil{Group views by basic first, like with concepts.} - -\phil{Use \tcode{&&} instead of \tcode{const\&} for value function parameters.} - -\phil{Can \tcode{std::ref} be used for the value function?} - - -% Phil: -% It's tempting to try to consolidate the views so there's no regular views that return a reference to a vertex/edge, -% versus the basic_ views that don't include the reference. There doesn't appear to be any real need to include the -% reference since the vvf/evf can be used to return the value(s) needed by the algorithm. -% -% That's true for the cases where the vertex_id/target_id is also returned by the view. However, for other types -% of graph data structures, it may be better to have the vertex/edge reference for edges(g,u) or target_id(g,uv) -% because there is likely a way to get the return value in O(1) time instead of O(log n) when using an id. -% - The views in this paper provide common ways that algorithms use to traverse graphs. They are as simple as iterating through the set of vertices, or more complex such as iterating through the vertices in a depth-first and breadth-first order. They also -provide a consistent and reliable way to access related elements using the View Return Types, and guaranteeing expected +provide a consistent and reliable way to access related elements using the data structs (\S\ref{sec:data-structs}), and guaranteeing expected values, such as that the target is really the target on unordered edges. We are unable to support freestanding implementations in this proposal. Many of the @@ -36,7 +17,7 @@ \section{Introduction} \paragraph{Value Function Concepts.} Many views accept a \emph{vertex value function} (\tcode{vvf}) or \emph{edge value function} (\tcode{evf}) that projects a user-defined value from each vertex or edge. The \tcode{vertex_value_function} and \tcode{edge_value_function} concepts (defined in D3130, Graph Container Interface) constrain these parameters and are used throughout this paper. -\section{Data Structs (Return Types)} +\section{Data Structs (Return Types)}\label{sec:data-structs} Views return one of the types in this section, providing a consistent set of value types for all graph data structures. They are templated so that the view can adjust the types of the members to be appropriate for its use. The three types, \tcode{vertex_data, edge_data} and \tcode{neighbor_data}, define the common data model used by algorithms. @@ -194,58 +175,7 @@ \subsection{\tcode{struct neighbor_data}}\label{neighbor-vi \end{table} -\begin{comment} -\phil{Do we really needs these, since VorVId can be either a descriptor or id.} - -\subsection{Copyable Data Structs} - -\subsubsection{Copyable Data Struct Types} -Copyable data structs are specializations of the data structs that can be copied. More specifically, they don't include -a vertex or edge descriptor. \tcode{copyable_vertex_t} shows the simple definition. - -\begin{lstlisting} -template -using copyable_vertex_t = vertex_data; // {id, value} -\end{lstlisting} - -\begin{table}[h!] -\begin{center} -%\resizebox{\textwidth}{!} -{\begin{tabular}{l L{12.0cm}} -\hline - \textbf{Type} & \textbf{Definition} \\ -\hline - \tcode{copyable_vertex_t} & \tcode{vertex_data} \\ - \tcode{copyable_edge_t} & \tcode{edge_data>} \\ - \tcode{copyable_neighbor_t} & \tcode{neighbor_data} \\ -\hline -\end{tabular}} -\caption{Data Struct Concepts} -\label{tab:info_struct_concepts} -\end{center} -\end{table} - -\subsubsection{Copyable Data Struct Concepts (For Exposition Only)} - -Given the copyable types, it's useful to have concepts to determine if a type is a desired copyable type. -\begin{table}[h!] -\begin{center} -%\resizebox{\textwidth}{!} -{\begin{tabular}{l L{12.0cm}} -\hline - \textbf{Concept} & \textbf{Definition} \\ -\hline - \tcode{copyable_vertex} & \tcode{convertible_to>} \\ - \tcode{copyable_edge} & \tcode{convertible_to>} \\ - \tcode{copyable_neighbor} & \tcode{convertible_to>} \\ -\hline -\end{tabular}} -\caption{Data Struct Concepts} -\label{tab:info_struct_concepts} -\end{center} -\end{table} - -\end{comment} +% Copyable Data Structs section removed — basic_ view variants (G.1) supersede this. \section{Graph Views} From 81cb59610217cb7fe21cddb971ae955d6c72502c Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 21:14:03 -0400 Subject: [PATCH 13/22] Phase I: Update revision history and config for D3129r3 --- D3129_Views/tex/config.tex | 2 +- D3129_Views/tex/revision.tex | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/D3129_Views/tex/config.tex b/D3129_Views/tex/config.tex index 93668bc..715ec60 100644 --- a/D3129_Views/tex/config.tex +++ b/D3129_Views/tex/config.tex @@ -4,7 +4,7 @@ \newcommand{\paperno}{D3129} \newcommand{\docno}{\paperno r3} \newcommand{\docname}{Graph Library: Views} -\newcommand{\prevdocno}{P3129r1} +\newcommand{\prevdocno}{P3129r2} \newcommand{\cppver}{202002L} %% Release date diff --git a/D3129_Views/tex/revision.tex b/D3129_Views/tex/revision.tex index 9107ddf..77e7409 100644 --- a/D3129_Views/tex/revision.tex +++ b/D3129_Views/tex/revision.tex @@ -21,6 +21,38 @@ \subsection*{\paperno r1} \item Rename \tcode{descriptor} structs to \tcode{info} structs in preparation for new BGL-like descriptors. \end{itemize} +\subsection*{\paperno r3} +\begin{itemize} + \item Renamed \tcode{vertex_info}, \tcode{edge_info}, and \tcode{neighbor_info} to + \tcode{vertex_data}, \tcode{edge_data}, and \tcode{neighbor_data} respectively, + with the addition of separate vertex ID and vertex descriptor template parameters. + \item Updated all value functions from 1-arg \tcode{vvf(u)}/\tcode{evf(uv)} form to + 2-arg \tcode{vvf(g,u)}/\tcode{evf(g,uv)} form, taking the graph as the first + parameter. + \item Added \tcode{basic\_} view variants (\tcode{basic\_vertexlist}, + \tcode{basic\_incidence}, \tcode{basic\_neighbors}, \tcode{basic\_edgelist}) that + yield only vertex/edge IDs without descriptors. + \item Added incoming-edge view variants (\tcode{in\_incidence}, + \tcode{in\_neighbors}) for bidirectional graphs. + \item Added \tcode{transpose} view for direction-swapping graph adaption. + \item Added pipe syntax support via range adaptors for all view functions. + \item Added \tcode{\_safe} topological sort factories with cycle detection + via \tcode{std::expected} (C++23; backward compatible to C++20 via external + \tcode{expected} library). + \item Changed topological sort from seeded (single source) to all-vertex traversal. + \item Removed \tcode{sourced\_edges\_dfs}, \tcode{sourced\_edges\_bfs}, and + \tcode{sourced\_edges\_topological\_sort} --- sourced search variants are no longer + in the implementation. + \item Changed search view control from free functions (\tcode{cancel()}, \tcode{depth()}, + \tcode{size()}) to member functions (\tcode{.cancel()}, \tcode{.depth()}, + \tcode{.num\_visited()}). + \item Added \tcode{search\_view} concept. + \item Replaced all uses of \tcode{vertex\_reference\_t} with \tcode{vertex\_t} + and \tcode{edge\_reference\_t} with \tcode{edge\_t}, consistent with the + descriptor-based architecture defined in D3130. + \item Documented allocator parameters for search views (DFS, BFS, topological sort). +\end{itemize} + \subsection*{\paperno r2} \begin{itemize} \item Replace the use of \textit{id} and \textit{reference} with \textit{descriptor}, leading to a simpler From a3430a4e710ff476cea41db5ebb9e7ea12f42bfc Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 21:18:57 -0400 Subject: [PATCH 14/22] =?UTF-8?q?Phase=20J:=20Cross-paper=20fixups=20?= =?UTF-8?q?=E2=80=94=20conventions.tex=20VVF/EVF,=20D3126=20C++23=20note?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- D3126_Overview/tex/overview.tex | 3 +++ tex/conventions.tex | 4 ++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/D3126_Overview/tex/overview.tex b/D3126_Overview/tex/overview.tex index d5596ed..c6a83bc 100644 --- a/D3126_Overview/tex/overview.tex +++ b/D3126_Overview/tex/overview.tex @@ -254,6 +254,9 @@ \section{Freestanding} Additionally, \tcode{stack} and \tcode{queue} require memory allocation which could throw a \tcode{bad_alloc} exception. +\section{Language Requirements} +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. + \section{Namespaces} Graph containers and their views and algorithms are not interchangeable with existing containers and algorithms. Additionally, there are some domain-specific terms that may clash with existing or future names, such as diff --git a/tex/conventions.tex b/tex/conventions.tex index 61c2d84..bc59ba9 100644 --- a/tex/conventions.tex +++ b/tex/conventions.tex @@ -25,7 +25,7 @@ \section{Naming Conventions} & & & vertex iterator. \tcode{vi} is the target vertex iterator. \\ & & \tcode{first,last} & \tcode{first} and \tcode{last} are the begin and end iterators of a vertex range. \\ - \tcode{VVF} & & \tcode{vvf} & Vertex Value Function: \tcode{vvf(u)} $\rightarrow$ vertex value, or \tcode{vvf(uid)} $\rightarrow$ vertex value, depending on requirements of the consuming algorithm or view. \\ + \tcode{VVF} & & \tcode{vvf} & Vertex Value Function: \tcode{vvf(g, u)} $\rightarrow$ vertex value, or \tcode{vvf(g, uid)} $\rightarrow$ vertex value, depending on requirements of the consuming algorithm or view. \\ \tcode{VProj} & & \tcode{vproj} & Vertex data projection function: \tcode{vproj(u)} $\rightarrow$ \tcode{vertex_data}. \\ \hdashline & \tcode{partition_id_t} & \tcode{pid} & Partition id. \\ @@ -36,7 +36,7 @@ \section{Naming Conventions} \tcode{EV} & \tcode{edge_value_t} & \tcode{val} & Edge Value, value or reference. This can be either the user-defined value on an edge, or a value returned by a function object (e.g. \tcode{EVF}) that is related to the edge. \\ \tcode{ER} & \tcode{vertex_edge_range_t} & & Edge Range for edges of a vertex \\ \tcode{EI} & \tcode{vertex_edge_iterator_t} & \tcode{uvi,vwi} & Edge Iterator for an edge of a vertex. \tcode{uvi} is an iterator for an edge from vertices \tcode{u} to \tcode{v}. \tcode{vwi} is an iterator for an edge from vertices \tcode{v} to \tcode{w}. \\ - \tcode{EVF} & & \tcode{evf} & Edge Value Function: \tcode{evf(uv)} $\rightarrow$ edge value. \\ + \tcode{EVF} & & \tcode{evf} & Edge Value Function: \tcode{evf(g, uv)} $\rightarrow$ edge value. \\ \tcode{EProj} & & \tcode{eproj} & Edge data projection function: \tcode{eproj(uv)} $\rightarrow$ \tcode{edge_data}. \\ \hline \end{tabular}} From 84d40042cf66579eb1551c921dc714df72cdf45a Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 21:21:58 -0400 Subject: [PATCH 15/22] Update plan: mark Phase J complete --- agents/views_update_plan.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/agents/views_update_plan.md b/agents/views_update_plan.md index e93bada..702d3eb 100644 --- a/agents/views_update_plan.md +++ b/agents/views_update_plan.md @@ -59,13 +59,13 @@ All structured bindings and prose must follow this convention consistently: | A | Source file rewrite (data structs) | — | Low — 3 small `.hpp` files | Done (ac5abdd) | | B | Data structs section rewrite | A | Medium — largest prose rewrite, tables | Done (1152806) | | C | Graph views update (vertexlist, incidence, neighbors, edgelist) | B | Medium — table + prose changes | Done (6f50537) | -| D | Search common types update | B | Low — enum + member functions | Not started | -| E | DFS / BFS views update | C, D | Medium — removals + binding changes | Not started | -| F | Topological sort views update | C, D | Medium — signature changes + new `_safe` factories | Not started | -| G | New content (basic variants, in_ variants, transpose, pipe syntax) | C, D, E, F | Medium — additive | Not started | -| H | Introduction, prose audit & cleanup | A–G | Low — mechanical | Not started | -| I | Revision history & config | H | Low — additive | Not started | -| J | Cross-paper fixups (conventions.tex, D3126 C++23 note) | I | Low — mechanical | Not started | +| D | Search common types update | B | Low — enum + member functions | Done (ce8f76a) | +| E | DFS / BFS views update | C, D | Medium — removals + binding changes | Done (4ee7cc1) | +| F | Topological sort views update | C, D | Medium — signature changes + new `_safe` factories | Done (8552f76) | +| G | New content (basic variants, in_ variants, transpose, pipe syntax) | C, D, E, F | Medium — additive | Done (`fb01712`) | +| H | Introduction, prose audit & cleanup | A–G | Low — mechanical | Done (`51b85b0`) | +| I | Revision history & config | H | Low — additive | Done (`81cb596`) | +| J | Cross-paper fixups (conventions.tex, D3126 C++23 note) | I | Low — mechanical | Done (`a3430a4`) | Phases A–I are sequential within P1709 (each committed separately). Phase J is last because it touches shared files and should only run once D3129 is stable. From 12b576346a0aa54b25fc8934e5b37228c45f1cd9 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 12 Mar 2026 21:37:41 -0400 Subject: [PATCH 16/22] Add mapped_algo_strategy.md for D3128 mapped container update --- agents/mapped_algo_strategy.md | 454 +++++++++++++++++++++++++++++++++ 1 file changed, 454 insertions(+) create mode 100644 agents/mapped_algo_strategy.md diff --git a/agents/mapped_algo_strategy.md b/agents/mapped_algo_strategy.md new file mode 100644 index 0000000..6ea15ea --- /dev/null +++ b/agents/mapped_algo_strategy.md @@ -0,0 +1,454 @@ +# Mapped/Associated Container Algorithm Strategy + +**Goal:** Discover all differences between the graph-v3 algorithm implementations (updated for +mapped/associated container support) and the D3128_Algorithms.tex paper, determine how to update +the paper, and identify related inconsistencies and implementation holes. + +--- + +## §0 Background and Design Shift + +The graph-v3 implementation has been extended so that most algorithms work with both: +- **Index graphs** — vertices are dense integer indices (`index_adjacency_list`), backed by + `std::vector` property maps. +- **Mapped graphs** — vertices are arbitrary hashable keys such as strings or structs + (`mapped_adjacency_list`), backed by `std::unordered_map` property maps. + +The D3128 paper currently documents only the index-graph API. All paper source files +(`D3128_Algorithms/src/*.hpp`) still use `index_adjacency_list` as the graph concept, and the paper +`tex/algorithms.tex` contains the editorial note *"Use `basic_index_adjacency_list` as the concept +for all algorithms"* (line 12) — now outdated. + +The new `graph-v3/include/graph/algorithm/*.hpp` files have been updated to use the generalised +`adjacency_list` concept together with a new `vertex_property_map_for` concept that abstracts over +vector and map-based property containers. An `index/` subdirectory preserves the old +`index_adjacency_list` variants for reference. + +--- + +## §1 New Infrastructure + +### §1.1 `vertex_property_map` + +**Header:** `graph/adj_list/vertex_property_map.hpp` + +A type alias that selects the appropriate container based on the graph type: + +```cpp +// index_vertex_range graphs → vector +template +using vertex_property_map = std::vector; + +// mapped graphs → unordered_map keyed on vertex_id_t +template +using vertex_property_map = std::unordered_map, T>; +``` + +### §1.2 `vertex_property_map_for` Concept + +Defined at `vertex_property_map.hpp` line 214. Requires that `M` supports subscript access by +`vertex_id_t`: + +```cpp +concept vertex_property_map_for = requires(M& m, const vertex_id_t& uid) { + m[uid]; +}; +``` + +Algorithms use this as the `requires` constraint instead of `random_access_range` or +`std::vector`. + +### §1.3 `vertex_property_map_value_t` + +Extracts the stored value type: +- `std::vector` → `T` (via `value_type`) +- `std::unordered_map` → `T` (via `mapped_type`) + +Used inside algorithm bodies as `using Distance = vertex_property_map_value_t` instead +of a hardcoded template parameter. + +### §1.4 Factory and Access Helpers + +| Function | Description | +|---|---| +| `make_vertex_property_map(g, init)` | Eager factory: `vector(num_vertices(g), init)` _or_ `unordered_map` pre-reserved and filled | +| `make_vertex_property_map(g)` | Lazy factory: sized vector _or_ empty reserved map | +| `vertex_property_map_contains(m, uid)` | `uid < size(m)` for vector; `.contains(uid)` for map | +| `vertex_property_map_get(m, uid, default_val)` | Read-with-fallback; never inserts into map | + +### §1.5 New Graph Concepts + +Defined in `graph/adj_list/adjacency_list_concepts.hpp` (lines ~320–400): + +| Concept | Definition | +|---|---| +| `hashable_vertex_id` | `std::hash>` is valid | +| `mapped_vertex_range` | `!index_vertex_range` && `hashable_vertex_id` && `find_vertex(g,uid)` valid | +| `mapped_adjacency_list` | `adjacency_list` && `mapped_vertex_range` | +| `mapped_bidirectional_adjacency_list` | `bidirectional_adjacency_list` && `mapped_vertex_range` | + +--- + +## §2 Algorithm-by-Algorithm Changes + +The table below compares the **current D3128 paper** (`D3128_Algorithms/src/`) with the +**graph-v3 implementation** (`graph-v3/include/graph/algorithm/`). + +### §2.1 Traversal: BFS + +| Item | Paper (src/breadth_first_search.hpp) | Implementation | +|---|---|---| +| Graph concept | `index_adjacency_list` | `adjacency_list` | +| Property maps | none (visitor-only) | internal `vertex_property_map` for visited | +| Source param | single `vertex_id_t` | `input_range Sources` for multi-source | +| Validation | `size(visited) < num_vertices(g)` | `find_vertex(g, uid)` for mapped graphs | + +### §2.2 Traversal: DFS + +| Item | Paper | Implementation | +|---|---|---| +| Graph concept | `index_adjacency_list` | `adjacency_list` | +| Property maps | none | internal `vertex_property_map` for visited | + +### §2.3 Traversal: Topological Sort + +| Item | Paper | Implementation | +|---|---|---| +| Graph concept | `index_adjacency_list` | `adjacency_list` | +| All overloads | `index_adjacency_list` | `adjacency_list` | +| Output | `OutputIterator` of `vertex_id_t` | same; `vertex_id_t` works for mapped keys | + +### §2.4 Shortest Paths: Dijkstra + +| Item | Paper | Implementation | +|---|---|---| +| Graph concept | `index_adjacency_list` | `adjacency_list` | +| `Distances` param | `class Distances` requires `random_access_range` | `class Distances` requires `vertex_property_map_for` | +| `Predecessors` param | `class Predecessors` requires `random_access_range` | same constraint updated to `vertex_property_map_for` | +| Distance type | `range_value_t` | `vertex_property_map_value_t` | +| Source validation | `size(distances) < num_vertices(g)` | branch on `index_vertex_range`: size check vs `find_vertex` | +| PQ element type | `vertex_id_t` | `vertex_t` descriptor (avoids repeated find_vertex for mapped graphs) | + +### §2.5 Shortest Paths: Bellman-Ford + +| Item | Paper | Implementation | +|---|---|---| +| Graph concept | `index_adjacency_list` | `adjacency_list` | +| `Distances` / `Predecessors` | `random_access_range` requires | `vertex_property_map_for` requires | +| Distance type | `range_value_t` | `vertex_property_map_value_t` | +| `find_negative_cycle` | `index_adjacency_list` | `adjacency_list` | + +### §2.6 MST: Prim + +| Item | Paper | Implementation | +|---|---|---| +| Graph concept | `index_adjacency_list` | `adjacency_list` | +| `Predecessor` / `Weight` params | `random_access_range` | `vertex_property_map_for` | +| Prim paper file | `prim.hpp` (2 overloads) | same two overloads, concept updated | + +### §2.7 MST: Kruskal + +Paper `kruskal.hpp` uses `x_index_edgelist_range` — completely different (edge-list based, not +adjacency list). Implementation `mst.hpp` has both Kruskal (edge list) and Prim (adjacency list). +No mapped-container change needed for Kruskal edge-list form. + +### §2.8 Maximal Independent Set (MIS) + +| Item | Paper | Implementation | +|---|---|---| +| Graph concept | `index_adjacency_list` | `adjacency_list` | +| Output | `class Iter` output iterator | same | +| Property map | — | internal `vertex_property_map` for `in_set` | + +### §2.9 Triangle Counting (TC) + +| Item | Paper | Implementation | +|---|---|---| +| Graph concept | `index_adjacency_list` | `adjacency_list` + `ordered_vertex_edges` | +| Return type | `size_t` | `size_t` | +| No property maps needed | n/a | n/a | + +### §2.10 Jaccard Coefficient + +| Item | Paper | Implementation | +|---|---|---| +| Graph concept | `index_adjacency_list` | `adjacency_list` | +| Output | `OutOp` callback | same | + +### §2.11 Label Propagation + +| Item | Paper (`lp.hpp`) | Implementation (`label_propagation.hpp`) | +|---|---|---| +| Graph concept | `index_adjacency_list` | `adjacency_list` | +| `Label` param | `random_access_range` | `vertex_property_map_for` | + +### §2.12 Connected Components (Undirected) + +| Item | Paper | Implementation | +|---|---|---| +| Graph concept | `index_adjacency_list` | `adjacency_list` | +| `Component` param | `random_access_range` | `vertex_property_map_for` | + +### §2.13 Articulation Points + +| Item | Paper | Implementation | +|---|---|---| +| Graph concept | likely `index_adjacency_list` (no src file in paper) | `adjacency_list` | +| Output | output iterator of `vertex_id_t` | same | + +### §2.14 Biconnected Components + +| Item | Paper | Implementation | +|---|---|---| +| Graph concept | likely `index_adjacency_list` (no src file in paper) | `adjacency_list` | +| Output | outer container of vertex sets | `OuterContainer` | + +### §2.15 Kosaraju (Strongly Connected Components) + +| Item | Paper (connected_components.hpp) | Implementation | +|---|---|---| +| Two-graph overload concept | `index_adjacency_list G, index_adjacency_list GT` | `adjacency_list G, adjacency_list GT` — **UPDATED** | +| Single-graph overload (bidirectional) | `index_bidirectional_adjacency_list G` | `index_bidirectional_adjacency_list G` — **NOT UPDATED** | +| `Component` param | `random_access_range` | `vertex_property_map_for` | + +The single-graph Kosaraju overload (line 280 in implementation) still requires +`index_bidirectional_adjacency_list` — see §3.1 for analysis. + +### §2.16 Afforest + +Paper has `§Afforest Connected Components` section (line 1253 in algorithms.tex) but no +corresponding `D3128_Algorithms/src/*.hpp` file. Status of mapped support unknown; not in +graph-v3 `algorithm/` directory either — **unimplemented**. + +--- + +## §3 Implementation Holes and Inconsistencies + +### §3.1 Kosaraju Single-Graph Overload — `index_bidirectional_adjacency_list` + +**Location:** `graph-v3/include/graph/algorithm/connected_components.hpp` line 280. + +The single-graph Kosaraju overload requires `index_bidirectional_adjacency_list` and uses the +`in_edges()` view to perform the second DFS on the transpose without materialising it. This is an +intentional constraint because: + +1. Bidirectional (in-edge) support requires `mapped_bidirectional_adjacency_list` for mapped + graphs. +2. The concept `mapped_bidirectional_adjacency_list` **exists** (see §1.5), so upgrading to + `bidirectional_adjacency_list` (which covers both index-bidirectional and + mapped-bidirectional) is technically feasible. + +**Recommendation:** Investigate whether `mapped_bidirectional_adjacency_list` fully supports +`in_edges()` iterator. If so, upgrade the single-graph Kosaraju overload to +`bidirectional_adjacency_list` and add `vertex_property_map_for`. + +### §3.2 Afforest — Unimplemented in graph-v3 + +Paper documents Afforest (§1.6 in algorithms.tex, §8 in algo_update_strategy.md) but it is absent +from `graph-v3/include/graph/algorithm/`. No mapped-container variant exists. + +### §3.3 Tarjan's SCC — No graph-v3 File + +Paper has a stub for Tarjan's SCC (line 1389 in algorithms.tex) but no implementation. + +### §3.4 Delta-Stepping — Paper Has Stub, No graph-v3 File + +`D3128_Algorithms/src/delta_stepping.hpp` is effectively empty. Not in `graph-v3/algorithm/`. + +### §3.5 Stale Documentation Comments in Implementation + +Several implementation files retain documentation mentioning `index_adjacency_list` requirements +(e.g., Bellman-Ford lines 86, 114) even though the template constraint has been updated to +`adjacency_list`. These stale comments can mislead paper authors. + +### §3.6 `has_negative_cycle` Return — Not a `vertex_property_map` + +`bellman_ford_shortest_paths` returns a `bool` `has_negative_cycle` parameter by reference. This +is not a property map; callers just pass a plain `bool`. No change needed here. + +### §3.7 Paper `random_access_range` `requires` Clauses + +The paper uses `random_access_range` and `random_access_range` in several +`requires` clauses (connected_components.hpp, mst.hpp, prim.hpp). These are now +`vertex_property_map_for`, which is *weaker* — not all `vertex_property_map_for` maps are random +access. Updating the concept name also changes the documented contract. + +--- + +## §4 The `index/` Subdirectory + +`graph-v3/include/graph/algorithm/index/` contains matched files for all 13 algorithm headers. +These use `index_adjacency_list` exclusively and represent the **old pre-mapped API**. + +- The files in `D3128_Algorithms/src/` are conceptually the same as the `index/` variants, not the + updated top-level files. +- When updating the paper, the `D3128_Algorithms/src/` files should be brought up to match the + top-level `graph-v3/include/graph/algorithm/` files, not the `index/` variants. + +The paper may eventually want to document both index and mapped forms, or only the general +`adjacency_list` form with a note that index graphs satisfy both. + +--- + +## §5 D3128 Paper Gap Analysis + +### §5.1 What the Paper Currently Shows + +- Every algorithm section that has a `\lstinputlisting` pulls from `D3128_Algorithms/src/*.hpp`, + all of which still use `index_adjacency_list`. +- There is no section covering `vertex_property_map`, `vertex_property_map_for`, + `hashable_vertex_id`, `mapped_vertex_range`, or `mapped_adjacency_list`. +- The "Common Algorithm Definitions" section (§126 in algorithms.tex) covers edge weight concepts, + ordered vertex edges, and visitor concepts — but not property maps. + +### §5.2 Missing Paper Content + +| Gap | Location in tex | +|---|---| +| `vertex_property_map` type alias | New subsection needed in §Common Algorithm Definitions | +| `vertex_property_map_for` concept | Same new subsection | +| `vertex_property_map_value_t` | Same | +| Factory/access helpers | Same | +| `hashable_vertex_id` / `mapped_vertex_range` | Prerequisite concepts — possibly in D3130 Container Interface or in Common Defs | +| `mapped_adjacency_list` / `mapped_bidirectional_adjacency_list` | Same | + +### §5.3 Concept Constraint Changes Per Section + +| Paper Section | Function(s) | Old Constraint | New Constraint | +|---|---|---|---| +| BFS (§266) | `breadth_first_search` | `index_adjacency_list` | `adjacency_list` | +| DFS (§342) | `depth_first_search` | `index_adjacency_list` | `adjacency_list` | +| Topo sort (§408) | all overloads | `index_adjacency_list` | `adjacency_list` | +| Dijkstra (§528) | all overloads | `index_adjacency_list` + `random_access_range` | `adjacency_list` + `vertex_property_map_for` | +| Bellman-Ford (§705) | all overloads | same as Dijkstra | same change | +| TC (§925) | `triangle_count` | `index_adjacency_list` | `adjacency_list` | +| Label Propagation (§980) | `label_propagation` | `index_adjacency_list` + `random_access_range` | `adjacency_list` + `vertex_property_map_for` | +| Articulation Points (§1090) | `articulation_points` | likely `index_adjacency_list` | `adjacency_list` | +| Biconn. Cmpts (§1142) | `biconnected_components` | likely `index_adjacency_list` | `adjacency_list` | +| Conn. Cmpts (§1195) | `connected_components` | `index_adjacency_list` + `random_access_range` | `adjacency_list` + `vertex_property_map_for` | +| Kosaraju (§1325) | two-graph overload | `index_adjacency_list` | `adjacency_list` | +| Kosaraju (§1325) | single-graph (bidir) | `index_bidirectional_adjacency_list` | pending §3.1 resolution | +| MIS (§1394) | `maximal_independent_set` | `index_adjacency_list` | `adjacency_list` | +| Jaccard (§1449) | `jaccard_coefficient` | `index_adjacency_list` | `adjacency_list` | +| MST/Prim (§1504) | `prim` overloads | `index_adjacency_list` + `random_access_range` | `adjacency_list` + `vertex_property_map_for` | + +--- + +## §6 Paper Update Plan + +### Phase MA-0 Decisions + +| ID | Decision | Options | +|---|---|---| +| D-MA-1 | **Scope of mapped support in paper**: document only the general `adjacency_list` form (subsumes index), or document both? | Recommended: general only, with a note that `index_adjacency_list` satisfies `adjacency_list` | +| D-MA-2 | **Where to place `vertex_property_map` section**: in D3128 "Common Definitions" or D3130 Container Interface? | Recommended: D3128 "Common Definitions" because it is tightly coupled to algorithm signatures | +| D-MA-3 | **`mapped_adjacency_list` / `hashable_vertex_id` concepts**: in D3128 or D3130? | Recommended: D3130 Container Interface (they describe container properties) with a cross-reference in D3128 | +| D-MA-4 | **Kosaraju single-graph overload**: upgrade to `bidirectional_adjacency_list` or keep as `index_bidirectional_adjacency_list`? | Investigate §3.1 first; prefer upgrade | +| D-MA-5 | **`Predecessors` type in Dijkstra/Bellman-Ford**: keep as separate template param or merge into `return` type? | Retain separate param matching implementation | + +### Phase MA-1 Add `vertex_property_map` Section to Paper + +**Location:** `D3128_Algorithms/tex/algorithms.tex`, between the current "Ordered Vertex Edges +Concept" subsection and the "Visitor Concepts" subsection (around line 196). + +**Content to add:** +1. `vertex_property_map_for` concept — definition, purpose, why it generalises both vector and + map. +2. `vertex_property_map` type alias. +3. `vertex_property_map_value_t` value extractor. +4. `make_vertex_property_map` factory signatures. +5. `vertex_property_map_contains` / `vertex_property_map_get` access helpers. +6. Cross-reference to D3130 for `mapped_adjacency_list` concept definition. + +Also update the stale editorial note at line 12: +- Remove or revise: *"Use `basic_index_adjacency_list` as the concept for all algorithms."* +- Replace with: *"Algorithms require `adjacency_list` unless specifically constrained to + `mapped_adjacency_list` or `index_adjacency_list`."* + +### Phase MA-2 Update `D3128_Algorithms/src/*.hpp` Signature Files + +For each file below, replace `index_adjacency_list` → `adjacency_list` and update `requires` +clauses for property map parameters: + +| File | Change | +|---|---| +| `breadth_first_search.hpp` | `index_adjacency_list` → `adjacency_list` | +| `breadth_first_search_multi.hpp` | same | +| `depth_first_search.hpp` | same | +| `topological_sort.hpp` | same (both overloads) | +| `topological_sort_multi.hpp` | same | +| `dijkstra_shortest_paths.hpp` | `index_adjacency_list` → `adjacency_list`; `random_access_range` → `vertex_property_map_for` | +| `dijkstra_shortest_paths_multi.hpp` | same | +| `dijkstra_shortest_dists.hpp` | same | +| `dijkstra_shortest_dists_multi.hpp` | same | +| `bellman_shortest_paths.hpp` | same as Dijkstra | +| `bellman_shortest_paths_multi.hpp` | same | +| `bellman_shortest_dists.hpp` | same | +| `bellman_shortest_dists_multi.hpp` | same | +| `find_negative_cycle.hpp` | `index_adjacency_list` → `adjacency_list` | +| `tc.hpp` | `index_adjacency_list` → `adjacency_list`; add `ordered_vertex_edges` | +| `jaccard.hpp` | `index_adjacency_list` → `adjacency_list` | +| `lp.hpp` (label propagation) | `index_adjacency_list` → `adjacency_list`; `random_access_range