From ee6cf3cc33fc0537f286556796b4fc0777bd0c15 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Thu, 11 Jun 2026 09:07:46 -0400 Subject: [PATCH 01/10] Add directedness analysis files - other/Directedness.htm: original email thread on P1709 directedness - other/Directedness_D3127.md: review mapping email to D3127 recommendations - other/Directedness_other_papers.md: applicability to D3128/D3129/D3130/D3131/D3337 --- other/Directedness.htm | 1849 +++++++++++++++++ other/Directedness_D3127.md | 140 ++ .../Directedness_files/colorschememapping.xml | 2 + other/Directedness_files/filelist.xml | 6 + other/Directedness_files/themedata.thmx | Bin 0 -> 3334 bytes other/Directedness_other_papers.md | 89 + 6 files changed, 2086 insertions(+) create mode 100644 other/Directedness.htm create mode 100644 other/Directedness_D3127.md create mode 100644 other/Directedness_files/colorschememapping.xml create mode 100644 other/Directedness_files/filelist.xml create mode 100644 other/Directedness_files/themedata.thmx create mode 100644 other/Directedness_other_papers.md diff --git a/other/Directedness.htm b/other/Directedness.htm new file mode 100644 index 0000000..83c258e --- /dev/null +++ b/other/Directedness.htm @@ -0,0 +1,1849 @@ + + + + + + + + + + + + + + + + + + +
+ +

Re: P1709: directedness?

+ +

Andrew Lumsdaine<al75@uw.edu>

+ +

You

+ +

Scott +McMillan;Kevin +Deweese;Phil +Ratzloff

+ +

Some comments.

+ +

 

+ +

1.  One has to define what +one means by “graph”.  In most of our algorithms, what they actually take is an adjacency list.  An adjacency list +is not a graph.  It is a data structure that represents whether two +vertices are adjacent to each other in the graph.  It’s a sparse form of +an adjacency matrix (which is also not a graph).  In all textbooks, an +adjacency list is an array, each element of which is a container (a “list”) of +adjacent vertices.  Meaning if we have an adjacent list A, if there is an +edge from u to v in the graph, then A[u] will contain v.  If the graph is +undirected, then it is also the case that A[v] will contain u.  An +adjacency list is neither directed nor undirected - it just represents +adjacency and has no actual edges.  Cormen et +al. state explicitly that an adjacency list is neither directed nor undirected.

+ +

 

+ +

2.  An edge list contains +edges.  If the edges it contains are directed, then for each edge (u, v) +in the edgelist, A[u] in the adjacency list will +contain v.  If the edgelist contains undirected +edges, then we also have that A[v] will contain u.

+ +

 

+ +

3. Unfortunately, the literature almost always conflates +adjacency list with graph.  So descriptions of dijkstra’s algorithm will say it takes a graph as input +when in fact it takes an adjacency list.  All other algorithms have this +conflation when their interfaces are described.  More precise would be to +say the algorithm takes as input an adjacency list from a directed graph or it +takes as input an adjacency list from an undirected graph.  Which is +probably how we should state it.

+ +

 

+ +

3a. Note that an adjacency list of an undirected graph is +indistinguishable from an adjacency list of a directed graph, but not vice +versa.  Meaning if a directed graph has a (v, u) for every (u, v) then the +resulting adjacentcy list will be the same as an +adjacency list from an undirected graph that has an edge (u, v).  (I am +not sure if this has anything to do with anything.)

+ +

 

+ +

4. Since an adjacency list is neither directed nor +undirected, we can’t make a data structure that is a directed or undirected +adjacency list.  Moreover, there is no way to enforce that in the type +system anyway.  That is, I can say an adjacency list A comes from an +undirected graph, but I can construct it so that it isn’t symmetric. + Meaning I can construct it so that (u, v) is in the adjacency list but +(v, u) is not.  In that sense, it is exactly like a symmetric matrix in +linear algebra.  It is also analogous to sortedness +in the standard library.  Binary search requires it, but it can’t be +enforced by the type system - so you have a precondition to binary search, +along with a function is_sorted.  Similarly we should probably have a function is_symmetric that checks if an adjacency list is actually symmetric.  We can’t use a type identifier as +a hint, because those can always be violated and don’t add anything to +programmability or type safety of a program.

+ +

 

+ +

5. Unfortunately we have this +thing that BGL calls an incidence graph, which has “out edges” and for a +bidirectional “graph” also has “in edges”.  But the same issues as for an +adjacency list of it not being enforceable in the type system apply.  Just +as with an adjacency list, if (u, v) exists in a directed graph, then (u, v) is +an out edge of A[u] and (u,v) +is an in edge of A[v].  If the graph is undirected then (v,u) would be an out edge of A[v] +and (v, u) would be an in edge of A[u].

+ +

 

+ +

6. We should probably use the terminology adjacency list +of graph and maybe incidence list of a graph.

+ +

 

+ +

7. As long as the input to an +algorithm meets the preconditions of symmetry described above, they will work +just fine.

+ +

 

+ +

8. Where things get wonky is when we have edge +properties.  Unfortunately, we can fake an indcidence +list of a graph by concocting edges on the fly from an adjacency list.  So we can assign a property to an edge and put the property +in an adjacency list, even though the adjacency list doesn’t have edges per se. + An example would be vector<vector<tuple<int, float>>>. + So we kind of need terminology to describe what +that kind of thing is.

+ +

 

+ +

9. Even if we have properties associated with half edges, it is simply a precondition that the properties +be the same.  Meaning, if I have A[u] = (v, f) corresponding to an edge +(u, v) in the graph with property f, when we require (as a precondition) that +A[v] = (u, f) — that is, the property of (v, u) has to also be f.  Again, this is like symmetry or sortedness.  As long as the property is only read, it +doesn’t matter if f is actually the same value or if it just has equal value, +meaning if we have A[u] = (v, f) and A[v] = (u, g) then it doesn’t matter if we +have &f == &g as long as f = g.

+ +

 

+ +

10. For some algorithms it does matter if &f = +&g.  Meaning, if you change the value of f, g must automatically also +change.  However, I am not sure how often that comes up in algorithms or +if it is ever even something that is visible or of concern to the caller — or +something the caller needs to ensure.  Even if it does, it is not +something about the graph or the edges, it is about the property (or the +property map).  My thinking has been that we need something called a “symmetric +property map”.  As with symmetry of an adjacency list, this is still only +something that has to do with values, not the property of a type, so there +wouldn't be a corresponding concept.

+ +

 

+ +

In summary

+ +

- the adjacency lists or a graph is not a graph and is +not directed or undirected — as a concept it would have adjacent vertices — +there is no concept of “out” or “in” — one would want a transpose to get +neighbors going the other way

+ +

- an edge list is directed or undirected

+ +

- an incidence list of a graph has something like edges, +but those are neither directed nor undirected, even if the underlying graph +might be directed or undirected

+ +

- when it is required that an edge actually +be the same thing for in and out, it is really about the property map, +not the “edge”

+ +

- it does not make sense to have directedness or symmetry +as concepts, because they are not enforceable by the type system — only things +that depend on properties types can be concepts, +things that depend on values cannot 

+ +

 

+ +

So for concepts:

+ +

An adjacency list is a thing on which a function (or cpo) adjacent_vertices can be +called

+ +

An incidence list is a thing on which a function (or cpo) out_edges can be called

+ +

A bidirectional incidence list is an incidence list on +which a function (or cpo) in_edges +can be called

+ +

 

+ +

This is all that algorithms need.  It is also, for +good or bad, basically what BGL has.

+ +

 

+ +

For properties, BGL had

+ +

 

+ +

A readable property map is a thing on which get can be +called

+ +

A writeable property map is a thing on which put can be +called

+ +

 

+ +

We might want a concept for when we have an adjacency +list but still want edge properties.  When we were doing nwgraph, it was almost always the case that you iterated +through adjacencies at the same time you were iterating through edge +properties, so there wasn’t ever a random lookup where you needed to actually have a complete edge to get a property.  Maybe +we need the concept of a “half edge”.  We’ll need to study more algorithms I think.

+ +

 

+ +

It seems like we are tending towards having user-defined +functions rather than property maps, so we might not need concepts for them.

+ +


+Sincerely,

+ +

Andrew Lumsdaine

+ +

 

+ +

 

+ +


+
+

+ +

On Mar 29, 2026, at 10:30AM, +Phil Ratzloff <pratzl@outlook.com> wrote:

+ +

 

+ +

Andrew, a topic that came up after you left in our last +meeting was, "What does directed, or undirected, +mean?" You have claimed that there is no reason to make the distinction +for algorithms, but the literature always mentions it.

+ +

 

+ +

In our discussion, Kevin thought that saying +"there's a matching edge in the opposite direction" is a better +distinction, but that may not be the right phrase to use.

+ +

 

+ +

We think there needs to be statement(s) in the Background +and Algorithms papers about this to make clarify what it means to be directed +or undirected.

+ +

 

+ +

It's something you can think of. Feel free to respond to this, or bring your idea(s) to the next meeting.

+ +

 

+ +

Sent from Outlook

+ +

 

+ +
+ + + + diff --git a/other/Directedness_D3127.md b/other/Directedness_D3127.md new file mode 100644 index 0000000..2876c37 --- /dev/null +++ b/other/Directedness_D3127.md @@ -0,0 +1,140 @@ +# Review of `other/Directedness.htm` — Recommendations for D3127 (Terminology) + +## Source + +`other/Directedness.htm` is an email thread on **"P1709: directedness?"** It begins with +Phil Ratzloff's question — *"What does directed, or undirected, mean?"* (with Kevin Deweese's +suggestion that the distinction is "there's a matching edge in the opposite direction") — and is +answered at length by Andrew Lumsdaine. Andrew's central thesis is that **directedness is a +property of values, not of types or data structures**, and therefore the terminology document +must be precise about what carries directedness and what does not. + +Below, each of Andrew's points is mapped to a concrete recommendation for +[D3127_Terminology/tex/terminology_0.tex](D3127_Terminology/tex/terminology_0.tex). + +--- + +## Key claims in the email + +1. Algorithms generally take an **adjacency list**, not a "graph". An adjacency list is *not* a + graph; it is a sparse form of the adjacency matrix that records *whether two vertices are + adjacent*. +2. An adjacency list is **neither directed nor undirected** — Andrew notes CLRS states this + explicitly. It just represents adjacency and has no actual edges; to traverse "the other + direction" you need a transpose. +3. An **edge list**, by contrast, *does* contain edges, and those edges *are* directed or + undirected. +4. The literature **conflates adjacency list with graph** (e.g. "Dijkstra takes a graph"). More + precise: an algorithm takes *an adjacency list from a directed graph* or *from an undirected + graph*. +5. (3a) An adjacency list of an undirected graph is **indistinguishable** from the adjacency list + of a directed graph that happens to have a reciprocal edge `(v,u)` for every `(u,v)` — but not + vice versa. +6. Directedness / symmetry **cannot be enforced by the type system**. You can declare an adjacency + list "comes from an undirected graph" yet build it asymmetrically. This is exactly analogous to + a symmetric matrix in linear algebra, or to `sortedness` in the standard library: binary search + has a *precondition* `is_sorted`, not a type. So there should be an `is_symmetric`-style + predicate, **not** a directed/undirected *type* and **not** a directedness *concept*. +7. **Incidence list / incidence graph** (BGL): `out_edges`, plus `in_edges` for a bidirectional + incidence graph. These half-edges look directed but are subject to the same + non-enforceability — they are neither directed nor undirected even when the underlying graph is. +8. Recommended terminology: **"adjacency list of a graph"** and **"incidence list of a graph"**. +9. **Edge properties**: one can "fake" an incidence list from an adjacency list by attaching + properties (e.g. `vector>>`). This needs terminology — perhaps a + **"half-edge"** concept and a **"symmetric property map"** (again a value-level, not type-level, + constraint). + +### Concepts Andrew proposes +- *adjacency list* — supports `adjacent_vertices` +- *incidence list* — supports `out_edges` +- *bidirectional incidence list* — additionally supports `in_edges` +- *readable / writeable property map* — supports `get` / `put` + +--- + +## Recommendations for D3127 + +### 1. State explicitly that an adjacency list is neither directed nor undirected +This is the email's headline point and is currently **only present as a commented-out `\andrew{}` +note** near the end of the source ("the structure of an adjacency list does not capture +directedness -- directedness is a run-time property"). The body text defines directed/undirected +for *graphs* and *edges*, and shows that for an undirected graph `J[i]` contains `j` and `J[j]` +contains `i`, but never states the converse conclusion. + +**Add** (in the "Adjacency-Based Representations" subsection, after the compressed sparse adjacency +matrix is introduced): a sentence making explicit that the adjacency list / compressed sparse +adjacency matrix itself carries *no* directedness — directedness is a property of which entries are +present (a value/run-time property), not of the data structure. Cite CLRS for the claim that an +adjacency list is neither directed nor undirected to strengthen it. + +### 2. Add a dedicated subsection: "Directedness is a property of values, not types" +The doc currently has no place that answers Phil's original question head-on. **Add** a short +subsection (or a clearly-flagged paragraph) covering: +- Directed vs. undirected is a property of the **edge set's contents** (whether reciprocal pairs + exist), not of any representation type. +- Therefore it **cannot be enforced by the type system** and should **not** be modeled as a + separate directed/undirected type or as a concept. +- Draw the explicit analogies Andrew gives: a *symmetric matrix* in linear algebra, and + *sortedness* (`is_sorted` precondition) in the standard library; suggest an `is_symmetric`-style + predicate as the corresponding check. + +This directly resolves Kevin's "matching edge in the opposite direction" framing: an undirected +graph's representation is one whose stored adjacencies are symmetric. + +### 3. Adopt "adjacency list of a graph" / "incidence list of a graph" phrasing +Reflect Andrew's point #4/#8. Where the doc says algorithms operate on graphs, prefer the precise +"an adjacency list *of* (or *from*) a directed/undirected graph." The doc already makes the +graph-vs-representation distinction strongly; this extends that discipline to how directedness is +attributed. + +### 4. Make the indistinguishability point explicit (email 3a) +The coordinate-representation paragraph already observes there is "not a 1-1 correspondence between +the edges in `E` and the contents of `C`" for undirected graphs. **Extend** this with Andrew's +sharper statement: the adjacency list of an undirected graph is *indistinguishable* from that of a +directed graph containing a reciprocal edge for every edge — but not vice versa. This reinforces +why directedness cannot be recovered from the representation alone. + +### 5. Define "incidence list" (and bidirectional incidence list) — not just incidence *matrix* +The doc has an "Incident Matrices" subsection (note: heading reads "Incident", body reads +"Incidence" — make consistent), but no **incidence list** terminology, despite the email and the +algorithms relying on `out_edges` / `in_edges`. **Add** terminology for: +- *incidence list of a graph* — exposes out-edges; +- *bidirectional incidence list* — additionally exposes in-edges; +and clarify that these "half-edges" / out/in distinctions are still not enforceable directedness — +they mirror the underlying graph but the structure itself does not guarantee it. + +> Note: this interacts with the existing bullet in "Basic Terminology" that, for the *undirected* +> case, says *"The edge `e_k` is an out-edge of both `v_i` and `v_j` and it is an in-edge of both."* +> Per the email's framing, in/out are representation-level notions on an incidence list rather than +> properties of an undirected edge. Reconcile this wording so the in/out vocabulary is introduced +> with the incidence representation, not with undirected edges in the abstract graph. + +### 6. Add terminology for edge properties on adjacency lists ("half-edge", "symmetric property map") +Points #8–#10 are not addressed anywhere in D3127. **Add** terminology to cover the common +`vector>>` pattern (adjacency list carrying per-adjacency property +data), introduce the **half-edge** notion, and note the **symmetric property map** requirement +(that the property of `(u,v)` equal that of `(v,u)`) as another *value-level* precondition — not a +type/concept. A brief forward-reference to where concepts/property maps are formally defined would +suffice if full treatment belongs elsewhere. + +### 7. Cite CLRS for "adjacency list is neither directed nor undirected" +The doc already adopts CLRS as its terminology baseline. Andrew explicitly attributes the +"neither directed nor undirected" claim to Cormen et al.; adding that citation gives the +recommendation in #1 authoritative backing. + +--- + +## Adjacent observations (surfaced while cross-checking the directedness claims) + +These are quality issues noticed in the directedness-related passages; worth fixing while editing +the same sections: + +- **Directed vs. undirected adjacency-matrix definitions are identical in the LaTeX.** In the + "Adjacency-Based Representations" subsection both `a_{ij}` cases use `(v_i, v_j) \in E`; the + undirected one should express symmetry (`a_{ij} = a_{ji}`) via an unordered edge `\{v_i, v_j\}`. + The following sentence also has a typo: *"the difference ... is that and the adjacency matrix"* + and `a_ij` is missing braces (`$a_{ij}$`). +- **"path" is defined twice and inconsistently** (once in Basic Terminology allowing the simple + sequence, once in special cases requiring distinct vertices), and the **"cycle"** definition + ("every vertex appears twice") is garbled. A self-loop is written `${v_i, v_i}$` (missing + `\{ \}`). These are not directedness issues but sit in the same terminology section. diff --git a/other/Directedness_files/colorschememapping.xml b/other/Directedness_files/colorschememapping.xml new file mode 100644 index 0000000..b200daa --- /dev/null +++ b/other/Directedness_files/colorschememapping.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/other/Directedness_files/filelist.xml b/other/Directedness_files/filelist.xml new file mode 100644 index 0000000..b8d43e4 --- /dev/null +++ b/other/Directedness_files/filelist.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/other/Directedness_files/themedata.thmx b/other/Directedness_files/themedata.thmx new file mode 100644 index 0000000000000000000000000000000000000000..9beb129a5fe85202d7cf00e9c875462f769903d0 GIT binary patch literal 3334 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 literal 0 HcmV?d00001 diff --git a/other/Directedness_other_papers.md b/other/Directedness_other_papers.md new file mode 100644 index 0000000..07387db --- /dev/null +++ b/other/Directedness_other_papers.md @@ -0,0 +1,89 @@ +# Applicability of `other/Directedness.htm` to Other Papers + +This file records where Andrew Lumsdaine's directedness email thread +(see `other/Directedness_D3127.md` for the full analysis) has implications +beyond D3127 (Terminology). + +--- + +## D3130 — Graph Container Interface (strong relevance) + +The GCI already defines six adjacency-list concepts with no directed/undirected +axis — the correct outcome. However, the introduction still describes the adjacency +list as a "graph" (`"(aka graphs)"` in `container_interface.tex` §1), conflating the +two. Andrew's sharper framing — *adjacency list ≠ graph; an adjacency list carries +no directedness* — should inform how the GCI describes what its concepts model. + +Additionally, the `sorted_adjacency_list` concept is directly analogous to the +`is_sorted` / `is_symmetric` precondition argument Andrew makes: sortedness is a +value-level property enforced by precondition, not a type. The paper could draw that +explicit analogy to justify the design. + +**Recommended change:** Revise the introductory description to say the GCI defines +the interface for *adjacency lists* (and edge lists), not "graphs," and note that +directedness is a property of which edges the caller stores, not a type parameter. + +--- + +## D3131 — Containers (direct framing conflict) + +`containers.tex` says `is_directed` is **not supported** for `compressed_graph`, and +that an undirected graph "must include edge pairs for both directions." The behavior +is correct, but the *framing* conflicts with the email: the paper presents +directedness as an absent type-level trait rather than as a value-level property of +the stored edge set. + +**Recommended change:** Reframe the note: not *"the `is_directed` trait is +unsupported"* but *"directedness is determined by which edges are stored, not by the +type; callers treating the graph as undirected are responsible for storing symmetric +edge pairs."* This aligns `compressed_graph`'s behavior with the principled +terminology. + +--- + +## D3128 — Algorithms (moderate relevance) + +Algorithm summary boxes use `Directed? Yes / No` as a static property, and text +says algorithms operate on "directed/undirected graphs." Andrew's position is that +algorithms take *"an adjacency list of a directed/undirected graph"* rather than a +directed/undirected type — and that `triangle_count`'s undirected requirement is a +*precondition* (`is_symmetric`) not a type constraint. + +**Recommended changes:** +- In algorithm descriptions, prefer "requires a symmetric adjacency list" (or + "requires the adjacency list of an undirected graph") over "operates on an + undirected graph." +- Consider adding an `is_symmetric` precondition note to `triangle_count` and any + other algorithm whose correctness depends on symmetric adjacencies. +- The commented-out text at lines 131/133 (adjacency list as range-of-ranges) is + correct and could be restored/updated with the clarification that the structure + itself carries no directedness. + +--- + +## D3129 — Views (minor relevance) + +The `incidence` / `in_incidence` view split corresponds directly to Andrew's +*incidence list* vs. *bidirectional incidence list* distinction. His point — that +these out/in half-edges are *representation-level* notions and still do not enforce +directedness — could appear as a brief note in the views introduction. + +**Recommended change:** Add a sentence near the `incidence` / `in_incidence` +introduction noting that the presence of `in_incidence` support reflects the +underlying graph's structure but does not itself guarantee symmetry; that remains a +value-level property. + +--- + +## D3337 — Comparison (informational / citation opportunity) + +D3337 already correctly notes (line 21) that `std::graph` does not specify edge +direction as a graph property and that undirected graphs store edges in both +directions — which is precisely the behavior the email justifies. The paper frames +this as a difference from BGL's `undirectedS` without explaining the design +rationale. + +**Recommended change:** Add a forward reference (or brief sentence) pointing to D3127 +for the principled justification: directedness cannot be enforced by the type system, +so the design intentionally leaves it as a value-level precondition rather than a +type tag. From cdb0886e03866f57adf684e2087208c1739c9d5d Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Mon, 15 Jun 2026 22:00:17 -0400 Subject: [PATCH 02/10] Refine directedness terminology and representation notes --- D3127_Terminology/tex/terminology_0.tex | 44 ++++++++++++++---- agents/D3130_review.md | 40 ++++++++++++++++ other/Directedness_D3127.md | 61 +++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 10 deletions(-) diff --git a/D3127_Terminology/tex/terminology_0.tex b/D3127_Terminology/tex/terminology_0.tex index 7fa73f1..200d444 100644 --- a/D3127_Terminology/tex/terminology_0.tex +++ b/D3127_Terminology/tex/terminology_0.tex @@ -98,7 +98,8 @@ \subsection{Graph Representation: Enumerating the Vertices} $e_k$ is said to be \emph{incident} on the vertices $v_i$ and $v_j$. Moreover, vertex $v_j$ is adjacent to vertex $v_i$ \emph{and} vertex $v_i$ is adjacent to vertex $v_j$. - The edge $e_k$ is an out-edge of both $v_i$ and $v_j$ and it is an in-edge of both $v_i$ and $v_j$. + We reserve the terms \emph{out-edge} and \emph{in-edge} for incidence-list representations, + where these terms are associated with stored adjacency records. \item The \emph{neighbors} of a vertex $v_i$ are all the vertices $v_j$ that are adjacent to $v_i$. The set of all the neighbors of $v_i$ is the \emph{neighborhood} of $v_i$. \item A \emph{path} is a sequence of vertices $v_0, v_1, \ldots, v_{k-1}$ such that there is an edge from $v_0$ to $v_1$, an edge from $v_1$ to $v_2$, and so on. @@ -110,7 +111,7 @@ \subsection{Graph Representation: Enumerating the Vertices} There are some special cases that deserve mention, as their presence or absence may determine algorithmic properties. \begin{itemize} % -\item A \emph{self-loop} is an edge from a vertex $v_i$ to itself, that is, there is an edge ${v_i, v_i}$ in $E$. +\item A \emph{self-loop} is an edge from a vertex $v_i$ to itself, that is, there is an edge $\{v_i, v_i\}$ in $E$. % \item An \emph{isolated vertex} $v_i$ is one that has no edge incident on it, that is, a vertex $v_i$ for which there is no edge $\{v_i, v_j\}$ nor $\{v_j, v_i\}$. % @@ -121,13 +122,12 @@ \subsection{Graph Representation: Enumerating the Vertices} elements of $E$ may be $\{v_i, v_j, v_k, \ldots\}$. Consideration of hypergraphs is outside the scope of this proposal. \item A \emph{hypersparse} graph is a graph for which the enumeration is not contiguous. That is for $V = \{v_i, v_j, v_k, \ldots\}$, with $i < j < k < \ldots$ the set $\{i, j, k, \ldots\}$ may not be contiguous and may not start at $0$. -\item A \emph{path} is sequence of edges $\{v_i, v_j\}, \{v_j, v_k\}, \{v_k, v_l\}, \ldots $ such that every $v_i$ is distinct. +\item A \emph{simple path} is sequence of edges $\{v_i, v_j\}, \{v_j, v_k\}, \{v_k, v_l\}, \ldots $ such that every vertex in the sequence is distinct. That is, any $v_i$ appears once and only once in an edge $\{v_j, v_i\}$ and once and only once in an edge $\{v_i, v_k\}$. -\item A \emph{cycle} is a path such that every vertex appears twice, that is, for every $v_i$ there is an edge - $\{v_j, v_i\}$ and an -edge $\{v_i, v_k\}$. In terms of the sequence above, a path is a cycle if the second vertex of the last edge is the first vertex of the first edge. +\item A \emph{cycle} is a path whose first and last vertices are the same, and whose intermediate vertices are distinct. + In terms of the sequence above, a path is a cycle if the second vertex of the last edge is the first vertex of the first edge. \item A \emph{directed acyclic graph (DAG)} is a directed graph with no cycles. \item A \emph{tree} is a connected graph with no cycles. Trees are a special case of graphs but are important enough that they have their own rich theory (and corresponding software). As such, we omit trees from this proposal and look forward to @@ -161,12 +161,12 @@ \subsection{Adjacency-Based Representations} a_{i j} = a_{ji} = \left\{ \begin{array}{rl} - 1 & \textrm{if } (v_i, v_j) \in E \\ + 1 & \textrm{if } \{v_i, v_j\} \in E \\ 0 & \textrm { otherwise } \end{array} \right. \] -That is, $a_{ij} = 1$ if and only if $v_j$ is adjacent to $v_i$ in the original graph $G$ (hence the name ``adjacency matrix``). We note that the difference between the adjacency matrices for a directed vs an undirected graph is that and the adjacency matrix for an undirected graph has $a_{ji} = 1$ whenever $a_ij$ is equal to one. That is, it is symmetric. +That is, $a_{ij} = 1$ if and only if $v_j$ is adjacent to $v_i$ in the original graph $G$ (hence the name ``adjacency matrix``). We note that the difference between the adjacency matrices for a directed vs an undirected graph is that the adjacency matrix for an undirected graph has $a_{ji} = 1$ whenever $a_{ij}$ is equal to one. That is, it is symmetric. Here we can see also why we said that the initial enumeration of $V$ is foundational to representations: \emph{The adjacency matrix is based solely on the indices used in that enumeration}. It does not contain the vertices or edges themselves. The enumeration corresponding to vertices is implicit: the neighbor information for vertex $v_i$ is stored on row $i$ of the matrix. Similarly, we don't store an edge $(v_i, v_j)$ explicitly, but rather an indicator as to whether $(v_i, v_j)$ exists in $E$ or not. @@ -178,6 +178,7 @@ \subsection{Adjacency-Based Representations} \textbf{NB:} At first glance, it may seem that we have simply created a data structure $C$ that has a pair $(i,j)$ if $E$ in the original graph has an edge from $v_i$ to $v_j$. This is true in the directed case. However, in the undirected case, if there is an edge between $v_i$ and $v_j$, then $v_i$ is adjacent to $v_j$, and $v_j$ is adjacent to $v_i$. In other words, if there is an edge between $v_i$ and $v_j$ in an undirected graph, then both the entries $a_{ij}$ and $a_{ji}$ are equal to $1$\footnote{That is, the adjacency matrix is symmetric.} --- and therefore for a single edge between $v_i$ and $v_j$, $C$ contains two index pairs: $(i, j)$ and $(j, i)$. The sparse coordinate representation is commonly known as \emph{edge list}. However, we caution the reader that $C$ does not store edges, but rather indices that represent adjacencies between vertices. In the case that $C$ represents an undirected graph, there is not a 1-1 correspondence between the edges in $E$ and the contents of $C$. +Indeed, the adjacency list of an undirected graph is indistinguishable from the adjacency list of a directed graph that has a reciprocal edge $(v_j, v_i)$ for every edge $(v_i, v_j)$. Although the sparse coordinate adjacency matrix is much more efficient in terms of storage than the original adjacency matrix, it isn't as efficient as it could be. Much more importantly, it is not useful for the types of operations used by most graph algorithms, which need to be able to get the set of neighbors of a given vertex in constant time. @@ -187,6 +188,14 @@ \subsection{Adjacency-Based Representations} The common name for this data structure is \emph{adjacency list}. Although this name is problematic (for instance, it is not actually a list), it is so widely used that we also use it here---but \emph{we mean specifically that an ``adjacency list'' is the compressed sparse adjacency matrix representation of a graph}\footnote{We concede that ``adjacency list'' rolls off the tongue much more easily than ``compressed sparse adjacency matrix representation of a graph.''}. Again we emphasize the distinction between a graph and its representation: An adjacency list $J$ is not the same as the graph $G$---it is a representation of $G$, based on an enumeration of the vertices in $\{V\}$. +In particular, an adjacency list representation is neither directed nor undirected in itself~\cite{CLRS2022}. Directedness is a property of the values present in the representation (for example, whether reciprocal index pairs are present), not a property of the representation type. +Both the dense adjacency matrix and the compressed adjacency list are representations of the same abstract object, namely $G = \{V, E\}$. + +\subsubsection{Directedness Is a Property of Values, Not Types} + +The distinction between directed and undirected is determined by the contents of the represented edge relation, not by whether a program uses an adjacency matrix, an adjacency list, or another storage scheme. +In this sense, directedness is analogous to matrix symmetry in linear algebra, or sortedness in the standard library: it is a value-level condition that algorithms may require, but it is not generally enforceable by representation type alone. +In practice, this means algorithms often require predicates over representation contents (for example, symmetry checks) rather than separate directed or undirected representation types. Illustrations of the adjacency-matrix representations of the airline route graph and the electronic instagram graph are shown in Figures~\ref{fig:airport-representation} and~\ref{fig:instagram}, respectively. @@ -261,7 +270,7 @@ \subsection{Adjacency-Based Representations} \end{figure} -\subsection{Incident Matrices} +\subsection{Incidence Matrices} An \emph{Incidence matrix} of a directed graph $G$ is a $|V|\times |E|$ matrix $B = (b_{ij})$ such that @@ -275,9 +284,24 @@ \subsection{Incident Matrices} \end{array} \right. \] - We note that the product $BB^\top$ of an incident matrix $B$ is the adjacency matrix + We note that the product $BB^\top$ of an incidence matrix $B$ is the adjacency matrix of the graph $G$, i.e., $G=BB^\top$. +\subsection{Incidence-List Representations} + +In addition to adjacency-based representations, many graph interfaces use an \emph{incidence list of a graph}, in which each vertex exposes the out-edges incident from that vertex. +For directed graphs, an out-edge record identifies a source vertex and a target vertex. +For undirected graphs, implementations may still store an edge as one or more oriented records, but this orientation is a representation choice rather than a statement about graph directedness. + +A \emph{bidirectional incidence list of a graph} additionally exposes in-edges for each vertex. +As with adjacency lists, these structures do not by themselves enforce directedness or undirectedness; those properties remain conditions on stored values. + +The operation commonly called \lstinline{adjacent_vertices} in other libraries can be expressed directly as a neighbor projection of an adjacency list in this proposal, without introducing a separate concept solely for that operation. +Likewise, this proposal does not adopt a separate readable/writeable property-map abstraction. +Instead, graph-, vertex-, and edge-associated values are accessed directly through value operations (for example, \tcode{graph_value}, \tcode{vertex_value}, and \tcode{edge_value}); readability follows from availability of access and writability from non-\tcode{const} reference return. +When an adjacency-list entry stores additional per-adjacency data (for example, tuples of target index and value), each stored adjacency record may be viewed as a \emph{half-edge}. +For undirected data modeled this way, requiring the property on $(v_i, v_j)$ to match the property on $(v_j, v_i)$ is a symmetry condition on values, i.e., a run-time precondition rather than a type-level guarantee. + \section{Direct Representations} diff --git a/agents/D3130_review.md b/agents/D3130_review.md index 0a0512b..b8b9a1d 100644 --- a/agents/D3130_review.md +++ b/agents/D3130_review.md @@ -229,3 +229,43 @@ wording/snippet polish. - **Q5 (`hashable_vertex_id`):** RESOLVED — documented in this paper; it is GCI-local and underpins `mapped_vertex_range` and the `vertex_property_map` utilities. See 1.9. + +## 5. Architectural note — graph concept hierarchy and adjacency_matrix + +**Context (2026-06-15):** A graph library implementation is fundamentally +centered on two representation types: the *adjacency list* and the +*adjacency matrix*. The `adjacency_list` concept (and its refinements) +already captures the former. The `adjacency_matrix` concept is documented as +future design in the paper (§1.5) but not yet in the reference implementation. + +**The role of "graph" as a mathematical concept.** In mathematical terms, +`graph` denotes the abstract entity $G = \{V, E\}$ — a vertex set and an edge +set — that *defines* what an adjacency list or adjacency matrix represents. +This meaning must not be lost in the C++ concept hierarchy. Currently the +concept names go directly to `adjacency_list` / `adjacency_matrix` with no +base `graph` concept in the library. Two design options to consider: + +1. **Introduce a base `graph` concept** (requiring only `vertices(g)`) that + both `adjacency_list` and `adjacency_matrix` refine. This makes the + mathematical hierarchy explicit in code: `graph` → `adjacency_list` / + `adjacency_matrix` → more-refined variants. +2. **Document the hierarchy in prose only** (D3127 + D3130 introductions) + without adding a bare `graph` concept, since a concept that requires + only `vertices(g)` may be too weak to be useful on its own. + +**Adjacency-matrix concept shape (when implemented).** The concept should +require at minimum: +```cpp +template +concept adjacency_matrix = requires(const G& g, vertex_id_t uid, vertex_id_t vid) { + { vertices(g) } -> vertex_range; + { adjacent(g, uid, vid) } -> convertible_to; // O(1) adjacency test +}; +``` +The constant-time `contains_out_edge` branch already planned in the Edge +Functions default (§1.5) is exactly this adjacency-matrix semantic guarantee. + +**Cross-reference:** D3127 should acknowledge both representations as equally +primary and should not leave `adjacency_matrix` as merely a theoretical tool +(see note in `other/Directedness_D3127.md`, "Graph as mathematical +foundation"). diff --git a/other/Directedness_D3127.md b/other/Directedness_D3127.md index 2876c37..d2ef832 100644 --- a/other/Directedness_D3127.md +++ b/other/Directedness_D3127.md @@ -50,6 +50,25 @@ Below, each of Andrew's points is mapped to a concrete recommendation for - *bidirectional incidence list* — additionally supports `in_edges` - *readable / writeable property map* — supports `get` / `put` +> **Library decision (2026-06-15):** Andrew's `adjacent_vertices` operation comes +> from the BGL `adjacency_graph` concept. In this library it is **not** a separate +> GCI CPO or concept — it is covered directly by the `neighbors` view +> (`std::graph::views::neighbors(g, u)`), which yields the neighboring vertices of +> `u` as a range. No additional concept or function is needed; `adjacency_list` +> already implies everything required to implement that view. + +> **Library decision (2026-06-15):** The readable/writeable property map concept +> comes from the BGL, whose property-map machinery is considered overly complex +> for this library and is **not** adopted. Instead, the library provides a single +> value per graph element via three CPOs: `graph_value(g)`, `vertex_value(g,u)`, +> and `edge_value(g,uv)` — analogous to `std::map::operator[]`. The *existence* +> of the CPO implies readability; returning a non-`const` reference implies +> writability. This covers the general property-access functionality without the +> additional concept/type machinery that BGL's property maps require. Recommendation +> §6 (half-edge / symmetric property map) may still be relevant for *terminology* +> around per-adjacency data, but the BGL `get`/`put` interface is explicitly out of +> scope. + --- ## Recommendations for D3127 @@ -138,3 +157,45 @@ the same sections: sequence, once in special cases requiring distinct vertices), and the **"cycle"** definition ("every vertex appears twice") is garbled. A self-loop is written `${v_i, v_i}$` (missing `\{ \}`). These are not directedness issues but sit in the same terminology section. + +--- + +## Graph as mathematical foundation (2026-06-15) + +A graph library implementation is centered on two primary representation types: +the **adjacency list** (compressed sparse adjacency matrix) and the +**adjacency matrix** (dense). The library already has a full +`adjacency_list` concept family; `adjacency_matrix` is planned but not +yet in the reference implementation. + +The term **"graph"** carries the mathematical meaning — an abstract entity +$G = \{V, E\}$ — that *defines what these representations represent*. This +meaning must not be diluted or lost: + +- In **D3127**, the distinction between the graph $G$ and its representations + (adjacency list, adjacency matrix, edge list) is well established. However, + the current text treats the adjacency matrix primarily as a theoretical + stepping stone toward the adjacency list. The two representations are equally + primary in the library; D3127 should present them as parallel, co-equal + concrete forms of a graph, not as a hierarchy where the matrix is merely + motivation for the list. + +- In **D3130**, consider whether a base `graph` concept (requiring only + `vertices(g)`) should appear at the top of the concept hierarchy so that both + `adjacency_list` and `adjacency_matrix` visibly refine it. This would + preserve the mathematical meaning at the C++ concept level. See the note in + `agents/D3130_review.md` §5 for the full discussion. + +### Recommendation for D3127 §"Adjacency-Based Representations" + +After introducing both the adjacency matrix and the adjacency list, add a +summary paragraph along the lines of: + +> Both the (dense) adjacency matrix and the (sparse/compressed) adjacency list +> are representations of the same abstract object — the graph $G = \{V, E\}$. +> A graph library is fundamentally an implementation of algorithms and data +> structures that operate on these two representations. The word "graph" in +> algorithm specifications, concept names, and library interfaces always refers +> to this mathematical object; when we write `adjacency_list` or +> `adjacency_matrix`, `G` is the type that *represents* a graph, not the +> graph itself. From dab30807cbf7ee8dce647d6f029b965793b0b293 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Wed, 24 Jun 2026 19:31:58 -0400 Subject: [PATCH 03/10] Remove vertex-id visitors and directedness trait --- D3126_Overview/tex/overview.tex | 10 ++++- D3127_Terminology/tex/revision.tex | 5 +++ D3128_Algorithms/src/visitor_vertex.hpp | 45 +++++-------------- D3128_Algorithms/tex/algorithms.tex | 19 +++----- D3128_Algorithms/tex/revision.tex | 1 - .../src/edgelist_typetraits.hpp | 5 --- .../tex/container_interface.tex | 4 +- D3131_Containers/tex/containers.tex | 3 +- D3131_Containers/tex/revision.tex | 2 +- agents/D3130_review.md | 2 +- agents/d3131_review.md | 7 --- agents/gci_update_plan.md | 2 +- other/Directedness_other_papers.md | 12 ----- 13 files changed, 35 insertions(+), 82 deletions(-) delete mode 100644 D3130_Container_Interface/src/edgelist_typetraits.hpp diff --git a/D3126_Overview/tex/overview.tex b/D3126_Overview/tex/overview.tex index c6a83bc..6284768 100644 --- a/D3126_Overview/tex/overview.tex +++ b/D3126_Overview/tex/overview.tex @@ -187,9 +187,15 @@ \section{Performance Considerations} \section{Prior Art} \textbf{boost::graph} has been an important C++ graph implementation since 2001. It was developed with the goal of providing -a modern (at the time) generic library that addressed all the needs of a graph library user. It is still a viable library used today, attesting to the value it brings. +a modern (at the time) generic library that addressed all the needs of a graph library user. It is still a viable library used today, +attesting to the value it brings. -However, boost::graph was written using C++98 in an ``expert-friendly'' style, adding many abstractions and using sophisticated template metaprogramming, making it difficult to use by a casual developer. Particular pain-points described in ad-hoc discussions with users include: property maps, parameter-passing, visitors. +However, boost::graph was written using C++98 in an ``expert-friendly'' style, adding many abstractions and using sophisticated +template metaprogramming, making it difficult to use by a casual developer. Particular pain-points described in ad-hoc discussions +with users include: property maps, parameter-passing, visitors. + +This library draws on the experience gained from boost::graph to provide a more modern and accessible C++ graph library. +The reference library has been extended to support many of the features and capabilities of \textbf{boost::graph}. \medskip diff --git a/D3127_Terminology/tex/revision.tex b/D3127_Terminology/tex/revision.tex index 9482bdb..63c8c9f 100644 --- a/D3127_Terminology/tex/revision.tex +++ b/D3127_Terminology/tex/revision.tex @@ -16,3 +16,8 @@ \subsection*{\paperno r1} occur in graphs such as \emph{self-loops}, \emph{multigraph}, \emph{cycle}, \emph{tree}, etc. \item Add a sections on Incident Matrices and Regarding Algorithms. \end{itemize} + +\subsection*{\paperno r2} +\begin{itemize} + \item Add about directedness of graphs and how it affects adjacency and incidence representations. +\end{itemize} diff --git a/D3128_Algorithms/src/visitor_vertex.hpp b/D3128_Algorithms/src/visitor_vertex.hpp index cd78ca8..2d13b39 100644 --- a/D3128_Algorithms/src/visitor_vertex.hpp +++ b/D3128_Algorithms/src/visitor_vertex.hpp @@ -1,50 +1,25 @@ template concept has_on_initialize_vertex = // For exposition only - requires(Visitor& v, const G& g, const vertex_t& vdesc) { - { v.on_initialize_vertex(g, vdesc) }; - }; -template -concept has_on_initialize_vertex_id = // For exposition only - requires(Visitor& v, const G& g, const vertex_id_t& uid) { - { v.on_initialize_vertex(g, uid) }; + requires(Visitor& v, const G& g, const vertex_t& u) { + { v.on_initialize_vertex(g, u) }; }; template concept has_on_discover_vertex = // For exposition only - requires(Visitor& v, const G& g, const vertex_t& vdesc) { - { v.on_discover_vertex(g, vdesc) }; - }; -template -concept has_on_discover_vertex_id = // For exposition only - requires(Visitor& v, const G& g, const vertex_id_t& uid) { - { v.on_discover_vertex(g, uid) }; + requires(Visitor& v, const G& g, const vertex_t& u) { + { v.on_discover_vertex(g, u) }; }; template concept has_on_start_vertex = // For exposition only - requires(Visitor& v, const G& g, const vertex_t& vdesc) { - { v.on_start_vertex(g, vdesc) }; - }; -template -concept has_on_start_vertex_id = // For exposition only - requires(Visitor& v, const G& g, const vertex_id_t& uid) { - { v.on_start_vertex(g, uid) }; + requires(Visitor& v, const G& g, const vertex_t& u) { + { v.on_start_vertex(g, u) }; }; template concept has_on_examine_vertex = // For exposition only - requires(Visitor& v, const G& g, const vertex_t& vdesc) { - { v.on_examine_vertex(g, vdesc) }; - }; -template -concept has_on_examine_vertex_id = // For exposition only - requires(Visitor& v, const G& g, const vertex_id_t& uid) { - { v.on_examine_vertex(g, uid) }; + requires(Visitor& v, const G& g, const vertex_t& u) { + { v.on_examine_vertex(g, u) }; }; template concept has_on_finish_vertex = // For exposition only - requires(Visitor& v, const G& g, const vertex_t& vdesc) { - { v.on_finish_vertex(g, vdesc) }; - }; -template -concept has_on_finish_vertex_id = // For exposition only - requires(Visitor& v, const G& g, const vertex_id_t& uid) { - { v.on_finish_vertex(g, uid) }; + requires(Visitor& v, const G& g, const vertex_t& u) { + { v.on_finish_vertex(g, u) }; }; diff --git a/D3128_Algorithms/tex/algorithms.tex b/D3128_Algorithms/tex/algorithms.tex index b5da5fd..cb0f474 100644 --- a/D3128_Algorithms/tex/algorithms.tex +++ b/D3128_Algorithms/tex/algorithms.tex @@ -350,27 +350,22 @@ \subsubsection{Vertex Visitor Concepts} {\small \lstinputlisting{D3128_Algorithms/src/visitor_vertex.hpp} } -Each vertex event concept exists in two variants. -The \textit{descriptor} variant (e.g.\ \lstinline{has_on_initialize_vertex}) requires an event -function whose second argument is \lstinline{const vertex_t&}. -The \textit{ID} variant (e.g.\ \lstinline{has_on_initialize_vertex_id}) requires an event -function whose second argument is \lstinline{const vertex_id_t&}. -The ID variant is useful when the visitor only needs the vertex identifier rather than the full -vertex descriptor. In both variants the first argument is \lstinline{const G&}. +Each vertex event concept requires an event function whose second argument is \lstinline{const vertex_t&}, +with the first argument being \lstinline{const G&}. The vertex events are called under the following conditions. \begin{itemize} - \item \lstinline{on_initialize_vertex(g, vdesc)} (or \lstinline{on_initialize_vertex(g, uid)}) + \item \lstinline{on_initialize_vertex(g, u)} is called once for each vertex before the algorithm is run. - \item \lstinline{on_discover_vertex(g, vdesc)} (or \lstinline{on_discover_vertex(g, uid)}) + \item \lstinline{on_discover_vertex(g, u)} is called once for each source vertex passed to the algorithm. - \item \lstinline{on_examine_vertex(g, vdesc)} (or \lstinline{on_examine_vertex(g, uid)}) + \item \lstinline{on_examine_vertex(g, u)} is called for a vertex before any of its outgoing edges are examined. It is possible that it will be called multiple times for the same vertex if paths are found to it from other vertices with a shorter distance. - \item \lstinline{on_start_vertex(g, vdesc)} (or \lstinline{on_start_vertex(g, uid)}) + \item \lstinline{on_start_vertex(g, u)} is called for a vertex that is being examined. - \item \lstinline{on_finish_vertex(g, vdesc)} (or \lstinline{on_finish_vertex(g, uid)}) + \item \lstinline{on_finish_vertex(g, u)} is called for a vertex that is being examined, after all its outgoing edges have been examined. \end{itemize} diff --git a/D3128_Algorithms/tex/revision.tex b/D3128_Algorithms/tex/revision.tex index a3768c3..b4e8c75 100644 --- a/D3128_Algorithms/tex/revision.tex +++ b/D3128_Algorithms/tex/revision.tex @@ -61,7 +61,6 @@ \subsection*{\paperno r4} \item Add \tcode{ordered_vertex_edges} concept for algorithms requiring sorted adjacency. \item Rewrite vertex visitor concepts (\tcode{has_on_initialize_vertex}, etc.) to use 2-argument descriptor form \tcode{(const G\&, const vertex_t\&)}. - Add corresponding \tcode{_id} variants accepting \tcode{vertex_id_t}. \item Rewrite edge visitor concepts (\tcode{has_on_examine_edge}, etc.) to use 2-argument form \tcode{(const G\&, const edge_t\&)}. \item Add hardened preconditions section to each algorithm for C++26. Reword diff --git a/D3130_Container_Interface/src/edgelist_typetraits.hpp b/D3130_Container_Interface/src/edgelist_typetraits.hpp deleted file mode 100644 index 37a6877..0000000 --- a/D3130_Container_Interface/src/edgelist_typetraits.hpp +++ /dev/null @@ -1,5 +0,0 @@ -template -struct is_directed : public false_type {}; // specialized for graph container - -template -inline constexpr bool is_directed_v = is_directed::value; diff --git a/D3130_Container_Interface/tex/container_interface.tex b/D3130_Container_Interface/tex/container_interface.tex index 64e0846..ec8cde6 100644 --- a/D3130_Container_Interface/tex/container_interface.tex +++ b/D3130_Container_Interface/tex/container_interface.tex @@ -733,9 +733,7 @@ \subsection{Traits} \hline \textbf{Trait} & \textbf{Type} & \textbf{Comment} \\ \hline - \tcode{is_directed : false_type} & struct & When specialized for an edgelist to derive \\ - \tcode{is_directed_v} & & from \tcode{true_type}, it may be used during graph - construction to add a second edge with source\_id and target\_id reversed. \\ + \hline \end{tabular}} \caption{Graph Container Interface Type Traits} diff --git a/D3131_Containers/tex/containers.tex b/D3131_Containers/tex/containers.tex index 34a64db..fe81a6b 100644 --- a/D3131_Containers/tex/containers.tex +++ b/D3131_Containers/tex/containers.tex @@ -46,8 +46,7 @@ \section{compressed\_graph Graph Container} $P$ is the number of partitions and is expected to be small, e.g. $P = 2$ for bipartite and $P \leq 10$ for typical multi-partite graphs. -The \tcode{is_directed} trait is not supported. If \tcode{compressed_graph} is intended to be used for an undirected -graph, then the edge pairs must be included for both directions, (uid,vid) and (vid,uid), when constructing the graph. +For undirected graphs, edge pairs must be included for both directions, (uid,vid) and (vid,uid), when constructing the graph. A public \tcode{operator[](vertex_id_t)} is \emph{not} provided. The only value it could return is an internal CSR element that is not useful on its own, and exposing it would breach the rule that diff --git a/D3131_Containers/tex/revision.tex b/D3131_Containers/tex/revision.tex index e2e587d..b88c099 100644 --- a/D3131_Containers/tex/revision.tex +++ b/D3131_Containers/tex/revision.tex @@ -26,7 +26,7 @@ \subsection*{\paperno r2} \begin{itemize} \item Add the edgelist as an abstract data structure as a peer to the adjacency list. A section on edgelists has been added to Using Existing Data Structures. - \item Add \tcode{is_directed} item in the feature summary box to \tcode{compressed_graph}. + \end{itemize} \subsection*{\paperno r3} diff --git a/agents/D3130_review.md b/agents/D3130_review.md index b8b9a1d..3f55c1f 100644 --- a/agents/D3130_review.md +++ b/agents/D3130_review.md @@ -211,7 +211,7 @@ wording/snippet polish. `num_vertices(g,pid)` — present. - `graph_error : runtime_error` — matches. - Edgelist concepts `basic_sourced_edgelist`, `basic_sourced_index_edgelist`, - `has_edge_value`, and the `is_directed`/`is_directed_v` trait — match. + `has_edge_value` — match. --- diff --git a/agents/d3131_review.md b/agents/d3131_review.md index 31200f9..28e8891 100644 --- a/agents/d3131_review.md +++ b/agents/d3131_review.md @@ -214,13 +214,6 @@ internal contradiction; **[LOW]** = wording/snippet polish. vertex/edge/graph mutable — matches (`csr_row_values`/`csr_col_values`, `graph_value()` accessor; no public add/remove vertex/edge). - `void` EV/VV/GV → no storage overhead: matches the empty specializations of - `csr_row_values`/`csr_col_values` and the `GV=void` class specialization. -- Summary box: vertex_id contiguous, contiguous vertices/edges ranges, - `num_edges(g)` $O(1)$, `has_edges(g)` $O(1)$, `num_partitions` $O(1)$, - Append vertices/edges = No, Partitions = Yes — all consistent with the code. -- `is_directed` not supported for `compressed_graph` (no specialization in - `compressed_graph.hpp`); undirected use requires inserting both `(u,v)` and - `(v,u)` — matches. - Memory-size formula $|V|(sizeof(EIndex)+sizeof(VV)) + |E|(sizeof(VId)+sizeof(EV)) + sizeof(GV)$ is consistent with the CSR layout (`row_index_`+row values sized to |V|, `col_index_` diff --git a/agents/gci_update_plan.md b/agents/gci_update_plan.md index 0c0f111..764dfaf 100644 --- a/agents/gci_update_plan.md +++ b/agents/gci_update_plan.md @@ -75,7 +75,7 @@ Phase J is last because it touches other papers and should only run once D3130 i | `descriptor_view.hpp` | `descriptor_view` + `descriptor_subrange_view` (11 lines) | `vertex_descriptor_view` + `edge_descriptor_view` | | `edgelist_concepts.hpp` | 1-arg `sourced_edgelist`, `sourced_index_edgelist`, `has_edge_value` | 2-arg `basic_sourced_edgelist`, `basic_sourced_index_edgelist`, `has_edge_value` | | `edgelist_types.hpp` | 1-arg type aliases, includes `edge_reference_t` | 2-arg type aliases, remove `edge_reference_t`, add `raw_vertex_id_t` | -| `edgelist_typetraits.hpp` | `is_directed` only | Same (no change needed) | +| `edgelist_typetraits.hpp` | Will be deleted | Same (no change needed) | ### New files to add diff --git a/other/Directedness_other_papers.md b/other/Directedness_other_papers.md index 07387db..e4a1e17 100644 --- a/other/Directedness_other_papers.md +++ b/other/Directedness_other_papers.md @@ -27,19 +27,7 @@ directedness is a property of which edges the caller stores, not a type paramete ## D3131 — Containers (direct framing conflict) -`containers.tex` says `is_directed` is **not supported** for `compressed_graph`, and -that an undirected graph "must include edge pairs for both directions." The behavior -is correct, but the *framing* conflicts with the email: the paper presents -directedness as an absent type-level trait rather than as a value-level property of -the stored edge set. - -**Recommended change:** Reframe the note: not *"the `is_directed` trait is -unsupported"* but *"directedness is determined by which edges are stored, not by the -type; callers treating the graph as undirected are responsible for storing symmetric -edge pairs."* This aligns `compressed_graph`'s behavior with the principled -terminology. ---- ## D3128 — Algorithms (moderate relevance) From 9b691af15f908eb9591d1fae55cb7f04fc9cb024 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Fri, 26 Jun 2026 14:21:08 -0400 Subject: [PATCH 04/10] Update D3126_Overview and related files Update the document to reflect the current status of the proposal and matching reference library. --- D3126_Overview/tex/config.tex | 4 +- D3126_Overview/tex/overview.tex | 188 ++++++++--------------- D3126_Overview/tex/revision.tex | 7 + D3127_Terminology/tex/config.tex | 2 +- D3128_Algorithms/tex/config.tex | 2 +- D3129_Views/tex/config.tex | 2 +- D3129_Views/tex/revision.tex | 2 +- D3129_Views/tex/views.tex | 5 +- D3130_Container_Interface/tex/config.tex | 2 +- D3131_Containers/tex/config.tex | 2 +- D3337_Comparison/tex/config.tex | 4 +- D9903/tex/config.tex | 2 +- D9907/tex/config.tex | 2 +- tex/example-config.tex | 2 +- tex/getting_started.tex | 13 +- 15 files changed, 90 insertions(+), 149 deletions(-) diff --git a/D3126_Overview/tex/config.tex b/D3126_Overview/tex/config.tex index c3ab099..39297e2 100644 --- a/D3126_Overview/tex/config.tex +++ b/D3126_Overview/tex/config.tex @@ -4,8 +4,8 @@ \newcommand{\paperno}{D3126} \newcommand{\docno}{\paperno r4} \newcommand{\docname}{Graph Library: Overview} -\newcommand{\prevdocno}{P3126r2} -\newcommand{\cppver}{202002L} +\newcommand{\prevdocno}{P3126r3} +\newcommand{\cppver}{202302L} \newcommand{\mailing}{} %% Release date diff --git a/D3126_Overview/tex/overview.tex b/D3126_Overview/tex/overview.tex index 6284768..f9c29ce 100644 --- a/D3126_Overview/tex/overview.tex +++ b/D3126_Overview/tex/overview.tex @@ -39,17 +39,17 @@ \section{Goals and Priorities} algorithms, named requirements, views, and utilities. % It is informed by the authors' past experience with the Boost Graph Library (BGL), the NWGraph library, the C++ -GraphBLAS, and the library proposed in P1709. The proposed library seeks to leverage the existing Standard -Library while introducing as little new machinery as possible. +GraphBLAS, proprietary graphs embedded in products, and the library originally proposed in P1709. The proposed +library seeks to leverage the existing Standard Library while introducing as little new machinery as possible. % Because of the broad scope of graph data structures and algorithms, we have defined a focused set of goals and priorities to deliver an initial set of useful and practical functionality that will also establish a solid -foundation for future development. +foundation for future work. \textbf{Design Principles.} We propose a lightweight library of software components for graph computing that is self-consistent and systematically defined. The foundation of the library is its collection of generic traversal -patterns and algorithms. Although concepts will be used ``under the hood,'' the API for the library's +patterns, views and algorithms. Although concepts will be used ``under the hood,'' the API for the library's algorithms and traversals will be specified using named requirements. As little new machinery as possible is introduced; to the greatest extent possible, graph library components are built on top of existing Standard Library components. @@ -61,32 +61,31 @@ \section{Goals and Priorities} \textbf{Graph Representation.} To be precise, and in keeping with common practice, the named requirements, the underlying concepts, and the algorithms in the library are defined in terms of representations of graphs. -What we mean by a graph representations is developed in detail in the companion document D3127. +What we mean by a graph representations is developed in detail in the companion document \href{https://www.wg21.link/P3127}{P3127}. \textbf{Leverage the Standard Library.} With the basis of the library being the representation of graphs in the form of hierarchical containers, and with the intention for the library to be included as part of the C++ standard library, we leverage standard -library components to the greatest extent possible. Notably, compositions of Standard Library containers +library components to the greatest extent possible. Notably, compositions of Standard Library ranges satisfy the graph representation requirements, sufficient for their use with the proposed graph library. \textbf{Graph Library Components.} The library will comprise algorithms and views, along with domain-specific -named requirements.\andrew{This is still in flux. I imagine a diagram and a table of some kind.} +named requirements. + +\andrew{This is still in flux. I imagine a diagram and a table of some kind.} +% +\phil{I believe this is done with the concepts diagrams in P3130. Is that sufficient?} % https://www.boost.org/doc/libs/1_81_0/libs/graph/doc/graph_concepts.html \subsection{Future Roadmap} -\noindent -\andrew{Aren't we doing most of these?} -\noindent - The following areas are opportunities for future proposals, after the initial proposals are accepted. We endeavor to investigate them (without introducing additional proposals) to ensure the currently proposed design will support them. \begin{itemize} - \item Additional graph algorithms. The Graph Algorithms proposals (D3128) identifies tiers of algorithms that we suggest be added in a staged fashion (including parallel algorithms). - \item Support for sparse vertex ids, implying the use of bi-directional containers such as \tcode{map} and \tcode{unordered_map} for vertices. - \item Bi-directional graphs, where vertices have incoming and outgoing edges. + \item Additional graph algorithms. The Graph Algorithms proposal (\href{https://www.wg21.link/P3128}{P3128}) identifies + tiers of algorithms that we suggest be added in a staged fashion (including parallel algorithms). \item Constexpr graphs, where vertices and edges are stored in \tcode{std::array} or other constexpr-friendly container. \item Parallel graph algorithms. \end{itemize} @@ -147,8 +146,9 @@ \section{Example: Six Degrees of Kevin Bacon} \section{What this proposal is \textbf{not}} -The Graph Library proposal limits itself to adjacency graphs and edgelists only. An adjacency graph is an outer range of vertices with an inner range of outgoing -edges on each vertex. An edgelist is a view of edges on an adjacency list, or a range of edge types. +The Graph Library proposal limits itself to adjacency lists and edgelists only. An adjacency list is an outer range of vertices with an inner range of outgoing +edges on each vertex. An edgelist is a view of edges on an adjacency list, or a range of edge types; they are indistinguishable in terms of the edges they represent +to an algorithm. Parallel graph algorithms are not included in this proposal for several reasons. \begin{itemize} @@ -168,35 +168,41 @@ \section{Impact on the Standard} This proposal is a pure \textbf{library} extension. \section{Interaction with Other Papers} -The entirety of our proposal for graph algorithms and data structures comprises multiple companion papers: D3127 (Terminology), D3128 (Algorithms), D3129 (Views), D3130 (Container Interface), D3131 (Containers), D9903 (Operators), and D9907 (Adaptors). +The entirety of our proposal for graph algorithms and data structures comprises multiple companion papers: \href{https://www.wg21.link/P3127}{P3127} (Background and Terminology), +\href{https://www.wg21.link/P3128}{P3128} (Algorithms), \href{https://www.wg21.link/P3129}{P3129} (Views), \href{https://www.wg21.link/P3130}{P3130} (Container Interface), +\href{https://www.wg21.link/P3131}{P3131} (Containers) and \href{https://www.wg21.link/P3337}{P3337} (Comparison to other graph libraries). Other than these papers, there are no interactions with other proposals to the standard. \section{Implementation Experience} -The github \href{https://github.com/stdgraph}{github.com/stdgraph} repository contains a reference implementation for this proposal. +The github \href{https://github.com/stdgraph/graph-v3}{github.com/stdgraph/graph-v3} repository contains a reference implementation for this proposal. \section{Usage Experience} -There is no current use of the library outside of the proposers. There are plans to begin using it in 2025 in commercial, academic, and research settings. +There is no current use of the library outside of the proposers. We are working on plans to make it available for broader use in commercial, academic, and research settings. \section{Deployment Experience} There is no current deployment experience of the library. Deployment experience will be gathered in conjunction with use. \section{Performance Considerations} -The algorithms are being ported from NWGraph to the \href{https://github.com/stdgraph}{github.com/stdgraph} implementation used for this proposal. -Performance analysis from those algorithms can be found in the peer-reviewed papers for NWGraph~\cite{REF_nwgraph_paper,gapbs_2023}. +The algorithms are being ported from Boost Graph and NWGraph to the \href{https://github.com/stdgraph/graph-v3}{github.com/stdgraph/graph-v3} +implementation used for this proposal. Performance analysis from those algorithms can be found in the peer-reviewed papers for NWGraph~\cite{REF_nwgraph_paper,gapbs_2023}. \section{Prior Art} +\phil{Summarize issues with each library WRT standardization as a basis. Demonstrate issues in P3337 Comparison.} + \textbf{boost::graph} has been an important C++ graph implementation since 2001. It was developed with the goal of providing a modern (at the time) generic library that addressed all the needs of a graph library user. It is still a viable library used today, attesting to the value it brings. However, boost::graph was written using C++98 in an ``expert-friendly'' style, adding many abstractions and using sophisticated template metaprogramming, making it difficult to use by a casual developer. Particular pain-points described in ad-hoc discussions -with users include: property maps, parameter-passing, visitors. +with users include: property maps, parameter-passing, and adapting to existing graph data structures. This library draws on the experience gained from boost::graph to provide a more modern and accessible C++ graph library. The reference library has been extended to support many of the features and capabilities of \textbf{boost::graph}. +(NB: Andrew is a co-author of boost::graph) + \medskip \textbf{NWGraph} (\cite{REF_nwgraph_library} and \cite{REF_nwgraph_paper}) was published in 2022 @@ -208,7 +214,9 @@ \section{Prior Art} data structures that could be applied to existing graphs, and there wasn't a uniform approach to properties. This proposal takes the best of NWGraph, with previous work done for P1709 to define a Graph Container Interface, to provide a library that -embraces performance, ease-of-use, and the ability to use the algorithms and views on externally defined graph containers. +embraces performance, ease-of-use, and the ability to use the algorithms and views on adjacency lists defined with standard containers. + +(Scott and Andrew were participants in GraphBLAS standardization and co-authors of GBTL.) \medskip @@ -236,10 +244,11 @@ \section{Prior Art} GraphBLAS Template Library (GBTL). % Scott -- is there a reference to your and Ben's current efforts? -(NB: Andrew is a co-author of boost::graph; -Scott and Andrew were participants in GraphBLAS standardization -and co-authors of GBTL; Andrew, Scott, and Phil are -co-authors of NWGraph.) +(Andrew, Scott, and Phil are co-authors of NWGraph.) + +\phil{Add discussion of LEMON library.} + +\phil{Add discussion of NetworkX library.} \section{Alternatives} Although the prior efforts have served, and do serve, important roles, @@ -248,8 +257,8 @@ \section{Alternatives} unaware of any existing graph library that meets the same requirements and uses concepts and ranges from C++20. -%Later revisions should include this: -%\section{Changes Library Evolution previously requested} +\phil{Comment on other graph libraries in github} + \section{Feature Test Macro} The \tcode{__cpp_lib_graph} feature test macro is recommended to represent all features in this proposal including algorithms, views, concepts, traits, types, functions, and graph container(s). @@ -261,22 +270,27 @@ \section{Freestanding} 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. +The library targets C++23 as its baseline. \tcode{std::expected} from C++23 are used by the topological sort safe +view factories (\tcode{vertices_topological_sort_safe} and \tcode{edges_topological_sort_safe}). + +The reference implementation provides backward compatibility to C++20 via an external \tcode{expected} library +(e.g., \tcode{tl::expected}). Switching it to require C++23 may limit those who can use it, so care will be +taken when deciding to require C++23. \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 \tcode{degree} and \tcode{partition_id}. -For these reasons, we recommend their own namespaces. The following assumption is used in this proposal. +For these reasons, we recommend separate namespace(s) for the graph functionality. The following assumption is used in this proposal. \begin{itemize} -\item[]\tcode{std::graph}, \tcode{std::graph::views} and \tcode{std::graph::edgelist} +\item[]\tcode{std::graph::adj_list}, \tcode{std::graph::views} and \tcode{std::graph::edge_list} \end{itemize} \noindent Alternative locations include the following: \begin{itemize} -\item[]\tcode{std::ranges}, \tcode{std::ranges::views}, and \tcode{std::ranges::edgelist} -\item[]\tcode{std::ranges/graph}, \tcode{std::ranges::graph::views} and \tcode{std::ranges::graph::edgelist} +\item[]\tcode{std::ranges}, \tcode{std::ranges::adj_list}, \tcode{std::ranges::edge_list}, and \tcode{std::ranges::views} +\item[]\tcode{std::ranges::graph}, \tcode{std::ranges::graph::adj_list}, \tcode{std::ranges::graph::edge_list}, \tcode{std::ranges::graph::views} \end{itemize} The advantage of these two options are that there would be no requirement to use the ranges:: prefix for things in the std::ranges namespace, a common occurrence. @@ -289,20 +303,12 @@ \section{Notes and Considerations} range of ranges. This introduces a new form of container beyond a simple range. \item There is more than one possible value type, one each for edge, vertex, and graph. Each is optional. This is in contrast to existing practice where the value type is the distinguishing difference between - different containers, such as for \tcode{set} and \tcode{map}. + different containers, such as for \tcode{set} and \tcode{map}. This decision was made to + avoid the combinatorial explosion of types that would otherwise occur if each combination of + edge, vertex, and graph value types required a separate container type. \item Algorithms will often use views, though they can use the GCI functions when needed. - \item Algorithms and Views often need to allocate memory internally to achieve their purpose. This is a departure from - common practice in the standard. -\end{itemize} - -There are other observations we've also discovered along the way that may not be obvious. -\begin{itemize} - \item Storing vertices in a \tcode{map} (bi-directional range) requires a different style of programming - algorithms, compared to being kept in a \tcode{vector} (random access range). When using a \tcode{vector}, - \tcode{edges(g,uid)} would normally be used without much thought. Using that with a \tcode{map} would - incur a $\mathcal{O}(\log(V))$ cost. Instead, it will use vertex id once to get the vertex reference - and then use \tcode{edges(g,uv)}. This is expected to result in overloading of existing algorithms based on the - range type of a container, distinguished with concepts. + \item Algorithms and Views often need to allocate memory internally because of the traversal requirement + of using a stack or queue. This is a departure from common practice in the standard. \end{itemize} The addition of concepts to the standard library is a serious consideration because, once added, they cannot @@ -319,33 +325,7 @@ \subsection{Open Design Issues} \subsection{Open Reported Issues} \begin{itemize} - \item \href{https://www.wg21.link/P3127}{P3127 Background and Terminology} - \begin{enumerate} - \item P1709 has lots of details which I think to be irrelevant. (P1709 is the original proposal that was split into multiple papers) - \begin{itemize} - \item Clarification: I don't find the discussion about adjacency matrices helpful, but rather a distraction. - It's not that it shouldn't be there in some form, but at the moment it has a prominence which I don't think is - commensurate with its importance to the paper, perhaps exacerbated by the fact that the paper lacks many salient details (see next point). - \end{itemize} - \item It is very hard to follow - \begin{itemize} - \item Clarification: As it stands, the paper lacks a discussion of the authors' standpoint on graph terminology, defining features - (e.g. self loops, multi-edges) and the sort of trade-offs you get by allowing/not allowing them. Put another way, I think the - paper would be easier to follow if there's a technical narrative that reveals the way the authors are thinking about this huge area. - - I like the style of the motivation in P1709R5; if this could be greatly extended to include the mathematical background that Andrew is - working on, this would be really helpful. And beyond the mathematical background, as discussion of the computational tradeoffs for - both graph implementations and the associated algorithms, given certain choice, would be great to have. - \item This paper includes much of the content from P1709R5 for motivation. Andrew will be extending the paper to include a more rigorous - mathematical description. - \end{itemize} - \item We need to add a mathematical perspective to the paper. - \begin{itemize} - \item P3127 includes some of this. We plan on extending it to include a more rigorous mathematical description. - \end{itemize} - \item There needs to be a proper discussion about whether the paper's definition of graph is what some authors call a multigraph - and whether it does/doesn't include loops. - \end{enumerate} + % P3127 Background and Terminology: issues removed because there is now a dedicated paper. \item \href{https://www.wg21.link/P3128}{P3128 Graph Algorithms} \begin{enumerate} \item The summary tables for the algorithms are necessary but not sufficient: @@ -359,66 +339,18 @@ \subsection{Open Reported Issues} \item A justification of the choices made for the algorithms may be helpful. \end{itemize} \end{enumerate} - \item \href{https://www.wg21.link/P3337}{P3337 Comparison to Other Graph Libraries} (Unpublished) + \item \href{https://www.wg21.link/P3337}{P3337 Comparison to Other Graph Libraries} \begin{enumerate} \item My comment about the structure of the paper changing was a reference to previous comparisons with boost::graph. I'm sure these were in an earlier version, or am I misremembering? \begin{itemize} \item We never had any comparisons to boost::graph. - \item A draft was reviewed in the March 2025 SG19 meeting. It will be published after it is updated with new - benchmark numbers when the descriptors functionality is fully implemented. + \item The paper was published 2025-07-30. A new version with updated benchmark numbers is in process with descriptors + functionality. + \item Additional comparision with other graph libraries beyond boost::graph is needed, e.g. LEMON, igraph, NetworkX, etc. + More content is also needed to describe why they aren't suitable as a basis for standardization. \end{itemize} \end{enumerate} \end{itemize} -\subsection{Resolved Issues} -\begin{itemize} - \item General Library Design - \begin{enumerate} - \item Build on \tcode{mdspan} and try to standardize (or at least understand) what might reasonably be called an unstructured span - - Suppose someone standardizes unstructured span, as a natural extension of mdspan. What could we - learn from its api that may be relevant for graphs? In both cases, we will presumably have a method which allows iteration over the ith partition - (or edges of a given node, for graphs). Consistency of the stl may mean we want these to have the same look/feel. - \begin{itemize} - \item This is a very different direction and beyond the scope of this proposal. This will not be pursued - and we invite others to submit a separate proposal. - \end{itemize} - \item Complete the unpublished \textbf{Graph Operators} proposal, which adds utility functions including degree, sort, relabel, transpose and join. - \begin{itemize} - \item While useful, the funcitons are not critical to offer a complete library. This is deferred until the other papers - have been voted out of SG19. - \end{itemize} - \end{enumerate} - \item \href{https://www.wg21.link/P3126}{P3126 Overview} - \begin{enumerate} - \item GraphBLAS is not included as part of the prior art. - \begin{itemize} - \item Added in P3126r1. - \end{itemize} - \item The electrical circuit example has issues in P3127, section 6.1. - \begin{itemize} - \item Removed in P3126r3. - \end{itemize} - \end{enumerate} - \item \href{https://www.wg21.link/P3128}{P3128 Graph Algorithms} - \begin{enumerate} - \item A concern is that the DFS and BFS functionality isn't flexible enough, especially when compared to boost::graph's visitors. - \begin{itemize} - \item Visitors have been added to the BFS and DFS algorithms, and to Dijkstra's and Belman-Ford shortest - paths algorithms. The same visitor events are supported as boost::graph for each of the algorithms. - If a visitor event is not used, there is no performance overhead. We also investigated the use of - coroutines but found it resulted in an unacceptable overhead, whether a visitor event was used or not. - \end{itemize} - \end{enumerate} - \item \href{https://www.wg21.link/P3130}{P3130 Graph Container Interface} - \begin{enumerate} - \item I'm not convinced by the load API. - \begin{itemize} - \item We agree because the use of both load functions and constructors creates ambiguity and complexity when both are defined. - Even though constructors weren't in the paper it wasn't clear whether they should be included or not. - We have removed the load functions and added constructors for \tcode{compressed_graph} to simplify the interface. - \end{itemize} - \item Complete the definition of the edgelist concepts, types and CPO functions. This is distinct from the existing edgelist view. - \end{enumerate} -\end{itemize} +% Removed section on resolved issues because it's no longer needed diff --git a/D3126_Overview/tex/revision.tex b/D3126_Overview/tex/revision.tex index e79b24a..30e5a1f 100644 --- a/D3126_Overview/tex/revision.tex +++ b/D3126_Overview/tex/revision.tex @@ -39,3 +39,10 @@ \subsection*{\paperno r3} The changes revolve around the introduction of the new boost::graph-like descriptors and improvements to the BFS, DFS and Topological Sort algorithms. \end{itemize} + +\subsection*{\paperno r4} +Update the wording to reflect the current status of the proposal along with minor corrections. +\begin{itemize} + \item Sparse vertex ids and bi-directional graphs are now supported and are no longer future work. + \item Remove completed items from the Issues Status section. +\end{itemize} diff --git a/D3127_Terminology/tex/config.tex b/D3127_Terminology/tex/config.tex index 5f038c3..9c9d30b 100644 --- a/D3127_Terminology/tex/config.tex +++ b/D3127_Terminology/tex/config.tex @@ -5,7 +5,7 @@ \newcommand{\docno}{\paperno r2} \newcommand{\docname}{Graph Library: Background and Terminology} \newcommand{\prevdocno}{P3127r0} -\newcommand{\cppver}{202002L} +\newcommand{\cppver}{202302L} %% Release date \newcommand{\reldate}{\today} diff --git a/D3128_Algorithms/tex/config.tex b/D3128_Algorithms/tex/config.tex index 538ffc4..2587f8e 100644 --- a/D3128_Algorithms/tex/config.tex +++ b/D3128_Algorithms/tex/config.tex @@ -5,7 +5,7 @@ \newcommand{\docno}{\paperno r4} \newcommand{\docname}{Graph Library: Algorithms} \newcommand{\prevdocno}{P3128r2} -\newcommand{\cppver}{202002L} +\newcommand{\cppver}{202302L} %% Release date \newcommand{\reldate}{\today} diff --git a/D3129_Views/tex/config.tex b/D3129_Views/tex/config.tex index 715ec60..df3132b 100644 --- a/D3129_Views/tex/config.tex +++ b/D3129_Views/tex/config.tex @@ -5,7 +5,7 @@ \newcommand{\docno}{\paperno r3} \newcommand{\docname}{Graph Library: Views} \newcommand{\prevdocno}{P3129r2} -\newcommand{\cppver}{202002L} +\newcommand{\cppver}{202302L} %% Release date \newcommand{\reldate}{\today} diff --git a/D3129_Views/tex/revision.tex b/D3129_Views/tex/revision.tex index 77e7409..d68d565 100644 --- a/D3129_Views/tex/revision.tex +++ b/D3129_Views/tex/revision.tex @@ -49,7 +49,7 @@ \subsection*{\paperno r3} \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. + descriptor-based architecture defined in \href{https://www.wg21.link/P3130}{P3130}. \item Documented allocator parameters for search views (DFS, BFS, topological sort). \end{itemize} diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index b33ce3c..dbc6c83 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -15,7 +15,10 @@ \section{Introduction} 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. +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 \href{https://www.wg21.link/P3130}{P3130}, Graph Container Interface) constrain these parameters and are used +throughout this paper. \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. diff --git a/D3130_Container_Interface/tex/config.tex b/D3130_Container_Interface/tex/config.tex index 12b80e6..6dfde40 100644 --- a/D3130_Container_Interface/tex/config.tex +++ b/D3130_Container_Interface/tex/config.tex @@ -5,7 +5,7 @@ \newcommand{\docno}{\paperno r4} \newcommand{\docname}{Graph Library: Graph Container Interface} \newcommand{\prevdocno}{P3130r2} -\newcommand{\cppver}{202002L} +\newcommand{\cppver}{202302L} %% Release date \newcommand{\reldate}{\today} diff --git a/D3131_Containers/tex/config.tex b/D3131_Containers/tex/config.tex index 47bbe4d..b007c7f 100644 --- a/D3131_Containers/tex/config.tex +++ b/D3131_Containers/tex/config.tex @@ -5,7 +5,7 @@ \newcommand{\docno}{\paperno r4} \newcommand{\docname}{Graph Library: Graph Containers} \newcommand{\prevdocno}{P3131r2} -\newcommand{\cppver}{202002L} +\newcommand{\cppver}{202302L} %% Release date \newcommand{\reldate}{\today} diff --git a/D3337_Comparison/tex/config.tex b/D3337_Comparison/tex/config.tex index b939952..a48ea69 100644 --- a/D3337_Comparison/tex/config.tex +++ b/D3337_Comparison/tex/config.tex @@ -4,8 +4,8 @@ \newcommand{\paperno}{D3337} \newcommand{\docno}{\paperno r1} \newcommand{\docname}{Graph Library: Comparison} -\newcommand{\prevdocno}{D3337r0} -\newcommand{\cppver}{202002L} +\newcommand{\prevdocno}{P3337r0} +\newcommand{\cppver}{202302L} %% Release date \newcommand{\reldate}{\today} diff --git a/D9903/tex/config.tex b/D9903/tex/config.tex index a251419..1226adc 100644 --- a/D9903/tex/config.tex +++ b/D9903/tex/config.tex @@ -5,7 +5,7 @@ \newcommand{\docno}{\paperno r0} \newcommand{\docname}{Graph Library: Operators} \newcommand{\prevdocno}{P1709r5} -\newcommand{\cppver}{202002L} +\newcommand{\cppver}{202302L} %% Release date \newcommand{\reldate}{\today} diff --git a/D9907/tex/config.tex b/D9907/tex/config.tex index 7f63722..9b4f7b2 100644 --- a/D9907/tex/config.tex +++ b/D9907/tex/config.tex @@ -5,7 +5,7 @@ \newcommand{\docno}{\paperno r0} \newcommand{\docname}{Graph Library: Adaptors} \newcommand{\prevdocno}{P1709r5} -\newcommand{\cppver}{202002L} +\newcommand{\cppver}{202302L} %% Release date \newcommand{\reldate}{\today} diff --git a/tex/example-config.tex b/tex/example-config.tex index fd20065..ca50661 100644 --- a/tex/example-config.tex +++ b/tex/example-config.tex @@ -5,7 +5,7 @@ \newcommand{\docno}{\paperno r1} \newcommand{\docname}{Example Paper Title} \newcommand{\prevdocno}{PXXXX r0} -\newcommand{\cppver}{202002L} +\newcommand{\cppver}{202302L} \newcommand{\mailing}{} %% Release date diff --git a/tex/getting_started.tex b/tex/getting_started.tex index 5104a97..1a461bb 100644 --- a/tex/getting_started.tex +++ b/tex/getting_started.tex @@ -16,19 +16,18 @@ \section{Getting Started} \href{https://www.wg21.link/P3126}{P3126} & Active & \textbf{Overview}, describes the big picture of what we are proposing. \\ \href{https://www.wg21.link/P3127}{P3127} & Active & \textbf{Background and Terminology} provides the motivation, theoretical background, and terminology used across the other documents.\\ \href{https://www.wg21.link/P3128}{P3128} & Active & \textbf{Algorithms} covers the initial algorithms - as well as the ones we'd like to see in the future. \\ + as well as the ones we'd like to see in the future. \\ %P9903 & Future & \textbf{Operators} includes useful utility functions when % working with graphs. \\ \href{https://www.wg21.link/P3129}{P3129} & Active & \textbf{Views} has helpful views for traversing a graph. \\ \href{https://www.wg21.link/P3130}{P3130} & Active & \textbf{Graph Container Interface} is the core interface used - for uniformly accessing graph data structures by views and algorithms. - It is also designed to easily adapt to existing graph data structures.\\ + for uniformly accessing graph data structures by views and algorithms. + It is also designed to easily adapt to existing graph data structures.\\ \href{https://www.wg21.link/P3131}{P3131} & Active & \textbf{Graph Containers} describes a proposed high-performance \tcode{compressed_graph} container. - It also discusses how to use containers in the standard library to define a graph, and how - to adapt existing graph data structures.\\ + It also discusses how to use containers in the standard library to define a graph, and how + to adapt existing graph data structures.\\ %P9907 & Future & \textbf{Adaptors} containing useful utilities to create adjacency lists from other data structures.\\ - \href{https://www.wg21.link/P3337}{P3337} & Active & \textbf{Comparison to other graph libraries} on performance and usage syntax. - Not published yet. \\ + \href{https://www.wg21.link/P3337}{P3337} & Active & \textbf{Comparison to other graph libraries} on performance and usage syntax. \\ \hline \end{tabular}} \caption{Graph Library Papers} From 5fce5c1f3e56859e84a291fcc4628f51490a8403 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Fri, 26 Jun 2026 15:34:07 -0400 Subject: [PATCH 05/10] Update D3128_Algorithms to reflect the current state and understanding Remove Directed? and Self-cycle? in algo summary box Tighten up the r4 revision comments --- D3128_Algorithms/tex/algorithms.tex | 108 ++++++++++++++-------------- D3128_Algorithms/tex/revision.tex | 24 +++---- tex/algo_intro.tex | 13 ++-- 3 files changed, 67 insertions(+), 78 deletions(-) diff --git a/D3128_Algorithms/tex/algorithms.tex b/D3128_Algorithms/tex/algorithms.tex index cb0f474..6f3a9cf 100644 --- a/D3128_Algorithms/tex/algorithms.tex +++ b/D3128_Algorithms/tex/algorithms.tex @@ -410,14 +410,14 @@ \subsection{Breadth-First Search} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|V| + |E|)$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} No & \textbf{Throws?} Yes \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} No & \textbf{Throws?} Yes \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -506,14 +506,14 @@ \subsection{Depth-First Search} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|V| + |E|)$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} No & \textbf{Throws?} No \\ - & \textbf{Multi-edge?} Yes & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} No & \textbf{Throws?} Yes \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -596,14 +596,14 @@ \subsection{Topological Sort} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|E|+|V|)$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} No & \textbf{Throws?} No \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} No & \textbf{Throws?} No \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -730,14 +730,14 @@ \subsection{Dijkstra Shortest Paths and Shortest Distances} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}((|E| + |V|)\log{|V|})$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} No & \textbf{Throws?} Yes \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} No & \textbf{Throws?} Yes \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -1006,14 +1006,14 @@ \subsection{Bellman-Ford Shortest Paths and Shortest Distances} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|E| \cdot |V|)$ \\ } - & \textbf{Directed?} Yes & \textbf{Cycles?} No & \textbf{Throws?} Yes \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} No & \textbf{Throws?} Yes \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -1290,14 +1290,14 @@ \subsubsection{Triangle Count (Undirected)} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(m^{3/2})$ \\ } - & \textbf{Directed?} No & \textbf{Cycles?} Yes & \textbf{Throws?} No \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} No & \\ + & \textbf{Cycles?} Yes & \textbf{Throws?} No \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -1372,14 +1372,14 @@ \subsubsection{Directed Triangle Count} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(m^{3/2})$ \\ } - & \textbf{Directed?} Yes & \textbf{Cycles?} Yes & \textbf{Throws?} No \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} No & \\ + & \textbf{Cycles?} Yes & \textbf{Throws?} No \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -1456,14 +1456,14 @@ \subsection{Label Propagation} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(M)$ \\ } - & \textbf{Directed?} Yes & \textbf{Cycles?} Yes & \textbf{Throws?} Yes \\ - & \textbf{Multi-edge?} Yes & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} Yes & \textbf{Throws?} Yes \\ + & \textbf{Multi-edge?} Yes & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -1557,14 +1557,14 @@ \subsection{Articulation Points} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|E|+|V|)$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} Yes & \textbf{Throws?} Yes \\ - & \textbf{Multi-edge?} Yes & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} Yes & \textbf{Throws?} Yes \\ + & \textbf{Multi-edge?} Yes & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -1639,14 +1639,14 @@ \subsection{BiConnected Components} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|E|+|V|)$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} Yes & \textbf{Throws?} Yes \\ - & \textbf{Multi-edge?} Yes & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} Yes & \textbf{Throws?} Yes \\ + & \textbf{Multi-edge?} Yes & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -1718,14 +1718,14 @@ \subsection{Connected Components} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|E|+|V|)$ } - & \textbf{Directed?} No & \textbf{Cycles?} Yes & \textbf{Throws?} No \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} Yes & \textbf{Throws?} No \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -1787,14 +1787,14 @@ \subsubsection{Kosaraju} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|E|+|V|)$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} Yes & \textbf{Throws?} No \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} Yes & \textbf{Throws?} No \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -1858,14 +1858,14 @@ \subsubsection{Tarjan's SCC} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|E|+|V|)$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} Yes & \textbf{Throws?} Yes \\ - & \textbf{Multi-edge?} Yes & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} Yes & \textbf{Throws?} Yes \\ + & \textbf{Multi-edge?} Yes & \\ \hline \end{tabular} \end{table} @@ -1943,14 +1943,14 @@ \subsection{Maximal Independent Set} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|E|)$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} No & \textbf{Throws?} No \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} No & \\ + & \textbf{Cycles?} No & \textbf{Throws?} No \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -1996,14 +1996,14 @@ \subsection{Jaccard Coefficient} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|N|^3)$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} No & \textbf{Throws?} No \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} No & \\ + & \textbf{Cycles?} No & \textbf{Throws?} No \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -2058,14 +2058,14 @@ \subsection{Kruskal Minimum Spanning Tree} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|E|)$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} No & \textbf{Throws?} No \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} No & \\ + & \textbf{Cycles?} No & \textbf{Throws?} No \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -2117,14 +2117,14 @@ \subsection{Inplace Kruskal Minimum Spanning Tree} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|E|\log{|E|})$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} No & \textbf{Throws?} No \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} No & \\ + & \textbf{Cycles?} No & \textbf{Throws?} No \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} \label{tab:algo_inplace_kruskal} @@ -2181,14 +2181,14 @@ \subsection{Prim Minimum Spanning Tree} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|E|log|V|)$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} No & \textbf{Throws?} Yes \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} No & \textbf{Throws?} Yes \\ + & \textbf{Multi-edge?} No & \\ \hline \end{tabular} %\caption{Algorithm Example} diff --git a/D3128_Algorithms/tex/revision.tex b/D3128_Algorithms/tex/revision.tex index b4e8c75..8dd30c0 100644 --- a/D3128_Algorithms/tex/revision.tex +++ b/D3128_Algorithms/tex/revision.tex @@ -54,25 +54,16 @@ \subsection*{\paperno r3} \subsection*{\paperno r4} \begin{itemize} \item Adopt value-based descriptor design throughout: \tcode{vertex_t} and \tcode{edge_t} - replace the former \tcode{vertex_reference_t}, \tcode{edge_reference_t}, - \tcode{vertex_info}, and \tcode{edge_info} types. - \item Add \tcode{basic_edge_weight_function} and \tcode{edge_weight_function} concepts - using a 2-argument form \tcode{WF(G\&, edge_t\&)}. - \item Add \tcode{ordered_vertex_edges} concept for algorithms requiring sorted adjacency. - \item Rewrite vertex visitor concepts (\tcode{has_on_initialize_vertex}, etc.) to use - 2-argument descriptor form \tcode{(const G\&, const vertex_t\&)}. - \item Rewrite edge visitor concepts (\tcode{has_on_examine_edge}, etc.) to use - 2-argument form \tcode{(const G\&, const edge_t\&)}. + value types replace the former \tcode{vertex_reference_t} and \tcode{edge_reference_t}. + Also added views \tcode{vertex_descriptor_view_t} and \tcode{edge_descriptor_view_t} + to provide consistent range wrapper for underlying vertex and edge ranges. + \item Add \tcode{ordered_vertex_edges} semantic concept for algorithms requiring sorted adjacency. \item Add hardened preconditions section to each algorithm for C++26. Reword existing clauses to conform to standard expectations; move statements formerly in \textit{Mandates} and \textit{Preconditions} to \textit{Hardened preconditions}; add \textit{Throws} clauses where appropriate. - \item Add time and space complexity to every algorithm section. - \item New algorithms: - \begin{itemize} - \item Tarjan's Strongly Connected Components. - \item Minimum Spanning Tree: Inplace Kruskal. - \end{itemize} + \item Include space complexity in addition to time complexity to every algorithm section. + \item New algorithm: Minimum Spanning Tree: Inplace Kruskal. \item Replace raw container (range) predecessor and distance parameters with function objects (\tcode{PredecessorFn}, \tcode{DistanceFn}) constrained by new \tcode{predecessor_fn_for} and \tcode{distance_fn_for} concepts, enabling flexible storage strategies for per-vertex properties. @@ -81,4 +72,7 @@ \subsection*{\paperno r4} a value-type trait, and a concept for uniform per-vertex storage across index and mapped graphs. \item Add an allocator parameter to algorithms that require internal containers such as a \tcode{stack} or \tcode{queue}. + \item Remove items in the algorithm summary box: \textit{Directed?} applies to the underlying characteristics + of the graph, not the algorithm itself, and \textit{Multi-edge?} handling is described in the algorithm + remarks section. \end{itemize} diff --git a/tex/algo_intro.tex b/tex/algo_intro.tex index b7de243..c6ea89f 100644 --- a/tex/algo_intro.tex +++ b/tex/algo_intro.tex @@ -5,14 +5,14 @@ \section{Algorithm Introduction} \setcellgapes{3pt} \makegapedcells \centering -\begin{tabular}{|P{0.30\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|P{0.20\textwidth}|} +\begin{tabular}{|P{0.30\textwidth}|P{0.22\textwidth}|P{0.22\textwidth}|} \hline \multirowcell{2}{ \textbf{Complexity} \\ $\mathcal{O}(|E|+|V|)$ } - & \textbf{Directed?} Yes & \textbf{Cycles?} No & \textbf{Throws?} No \\ - & \textbf{Multi-edge?} No & \textbf{Self-loops} Yes & \\ + & \textbf{Cycles?} No & \textbf{Throws?} No \\ + & \textbf{Multi-edge?} Yes & \\ \hline \end{tabular} %\caption{Algorithm Example} @@ -23,16 +23,11 @@ \section{Algorithm Introduction} The parts of the table have the following meaning: \begin{itemize} \item \textbf{Complexity} The complexity of the algorithm based on the number of vertices (V) and edges (E). - \item \textbf{Directed?} Is the algorithm only for directed graphs, or can it also be used for undirected graphs that have complimentary - edges, with different directions, between two vertices. - \item \textbf{Multi-edge?} Does the algorithm act as expected if more than one edge with the same direction exists between the same two vertices? \item \textbf{Cycles?} Does the algorithm act act as expected if a vertex (or edge) is part of a cycle? - \item \textbf{Self-loops?} Does the algorithm act act as expected if an edge exists with the same source and target? + \item \textbf{Multi-edge?} Does the algorithm act as expected if more than one edge with the same direction exists between the same two vertices? \item \textbf{Throws?} Will the algorithm throw at all? If so, look at the \textit{Throws} section after the function prototypes for details. \end{itemize} -\phil{The Directed? section needs work.} - We are unable to support freestanding implementations in this proposal. Many of the algorithms require a \tcode{stack} or \tcode{queue}, which are not available in a freestanding environment. Additionally, \tcode{stack} and \tcode{queue} require memory allocation which could throw a \tcode{bad_alloc} From 990d3ee45512c78bb691205c9b0f9459d09a9ef1 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Fri, 26 Jun 2026 16:25:57 -0400 Subject: [PATCH 06/10] Update D3129_Views to reflect the current state and recent changes in the views implementation. --- D3129_Views/tex/revision.tex | 47 ++++++++------------- D3129_Views/tex/views.tex | 80 ++++++++++++++++++------------------ 2 files changed, 58 insertions(+), 69 deletions(-) diff --git a/D3129_Views/tex/revision.tex b/D3129_Views/tex/revision.tex index d68d565..2e90528 100644 --- a/D3129_Views/tex/revision.tex +++ b/D3129_Views/tex/revision.tex @@ -21,25 +21,32 @@ \subsection*{\paperno r1} \item Rename \tcode{descriptor} structs to \tcode{info} structs in preparation for new BGL-like descriptors. \end{itemize} +\subsection*{\paperno r2} +\begin{itemize} + \item Replace the use of \textit{id} and \textit{reference} in view functions with the + \tcode{vertex_t} and \tcode{edge_t} descriptors, leading to a simpler interace. + The number of View functions has been halved because we no longer need separate functions that + only have \tcode{id}, and another set that has has both \tcode{id} and \tcode{reference}. Only functions + with \tcode{vertex_t} and \tcode{edge_t} descriptors are needed. + \item See \href{https://www.wg21.link/P3130}{P3130 Graph Container Interface} for more details about + vertex and edge 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 Renamed \tcode{vertex_info}, \tcode{edge_info}, and \tcode{neighbor_info} to \tcode{vertex_data}, + \tcode{edge_data}, and \tcode{neighbor_data} respectively, to align their names to represent + the core data models used. \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 Added \tcode{\_safe} topological sort factories with cycle detection + via \tcode{std::expected}. \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. @@ -49,25 +56,5 @@ \subsection*{\paperno r3} \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 \href{https://www.wg21.link/P3130}{P3130}. - \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 - interace. It also creates a more flexible interface that can support associative containers in the future. - The following changes were made: - \begin{itemize} - \item The number of View functions has been halved because we no longer need separate functions that - only have \tcode{id}, and another set that has has both \tcode{id} and \tcode{reference}. Only functions - with \tcode{descriptor} are needed. - \item The \tcode{vertex_id} member has been removed from the \tcode{vertex_info} struct, and the \tcode{vertex} - member can hold either an id or a descriptor, depending on the context it's used. The same changes have - also been applied to the \tcode{edge_info} and \tcode{neighbor_info} structs. - \item The copyable info type aliases and concepts have been removed. \tcode{vertex_info}, \tcode{edge_info} - and \tcode{neighbor_info} are always copyable because they no longer contain references. - \item See \href{https://www.wg21.link/P3130}{P3130 Graph Container Interface} for more details about - descriptors. - \end{itemize} + descriptor-based architecture defined in \href{https://www.wg21.link/P3130}{P3130 Graph Container Interface}. \end{itemize} diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index dbc6c83..4c142dd 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -197,7 +197,7 @@ \subsection{vertexlist Views} \begin{table}[h!] \begin{center} -\resizebox{\textwidth}{!} +%\resizebox{\textwidth}{!} {\begin{tabular}{l l} \hline \textbf{Example} & \textbf{Return} \\ @@ -208,9 +208,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} \\ +%\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} @@ -218,7 +218,7 @@ \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. +%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. @@ -240,9 +240,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} \\ +%\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} @@ -265,9 +265,9 @@ \subsection{in\_incidence Views} \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} \\ +%\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} @@ -293,9 +293,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} \\ +%\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} @@ -318,9 +318,9 @@ \subsection{in\_neighbors Views} \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} \\ +%\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} @@ -349,9 +349,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} \\ +%\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} @@ -438,7 +438,7 @@ \subsection{Depth First Search Views} \begin{table}[h!] \begin{center} -\resizebox{\textwidth}{!} +%\resizebox{\textwidth}{!} {\begin{tabular}{l l} \hline \textbf{Example} & \textbf{Return} \\ @@ -461,7 +461,7 @@ \subsection{Breadth First Search Views} \begin{table}[h!] \begin{center} -\resizebox{\textwidth}{!} +%\resizebox{\textwidth}{!} {\begin{tabular}{l l} \hline \textbf{Example} & \textbf{Return} \\ @@ -495,7 +495,7 @@ \subsection{Topological Sort Views} \begin{table}[h!] \begin{center} -\resizebox{\textwidth}{!} +%\resizebox{\textwidth}{!} {\begin{tabular}{l l} \hline \textbf{Example} & \textbf{Return} \\ @@ -517,7 +517,7 @@ \subsection{Topological Sort Views} \begin{table}[h!] \begin{center} -\resizebox{\textwidth}{!} +%\resizebox{\textwidth}{!} {\begin{tabular}{l l} \hline \textbf{Factory} & \textbf{Return} \\ @@ -545,40 +545,40 @@ \section{Range Adaptors (Pipe Syntax)} \begin{table}[h!] \begin{center} -\resizebox{\textwidth}{!} +%\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)} \\ + %\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)} \\ + %\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)} \\ + %\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)} \\ + %\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)} \\ + %\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)} \\ + %\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} @@ -588,7 +588,7 @@ \section{Range Adaptors (Pipe Syntax)} \begin{table}[h!] \begin{center} -\resizebox{\textwidth}{!} +%\resizebox{\textwidth}{!} {\begin{tabular}{l l} \hline \textbf{Pipe Expression} & \textbf{Equivalent Factory Call} \\ @@ -614,5 +614,7 @@ \section{Range Adaptors (Pipe Syntax)} \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). +The \tcode{in_incidence} and \tcode{in_neighbors} +%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 9d9397e2d0688644ed695ecaf025d21fb2d677ca Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Sun, 28 Jun 2026 16:36:11 -0400 Subject: [PATCH 07/10] Edit for D3130 Container Interface changes to sync with current implementation --- D3129_Views/tex/views.tex | 117 +---- .../src/adjacency_list_concepts.dot | 104 ++++ .../src/adjacency_list_concepts.pdf | Bin 0 -> 13768 bytes .../src/adjacency_list_concepts.svg | 278 ++++++++++ .../src/concepts_adj_list.hpp | 7 + .../src/concepts_edges.hpp | 12 +- .../src/concepts_vertex_range.hpp | 2 +- .../src/edge_data.hpp | 0 .../src/neighbor_data.hpp | 0 .../src/vertex_data.hpp | 0 .../tex/container_interface.tex | 497 ++++++++++-------- D3130_Container_Interface/tex/revision.tex | 10 +- 12 files changed, 676 insertions(+), 351 deletions(-) create mode 100644 D3130_Container_Interface/src/adjacency_list_concepts.dot create mode 100644 D3130_Container_Interface/src/adjacency_list_concepts.pdf create mode 100644 D3130_Container_Interface/src/adjacency_list_concepts.svg rename {D3129_Views => D3130_Container_Interface}/src/edge_data.hpp (100%) rename {D3129_Views => D3130_Container_Interface}/src/neighbor_data.hpp (100%) rename {D3129_Views => D3130_Container_Interface}/src/vertex_data.hpp (100%) diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index 4c142dd..fb8eacf 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -67,121 +67,8 @@ \section{Data Structs (Return Types)}\label{sec:data-structs} } \end{lstlisting} -\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_bfs(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_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}{!} -{\begin{tabular}{l |c c c} -\hline - \multicolumn{1}{l}{\textbf{Template Arguments}} - & - \multicolumn{3}{c}{\textbf{Members}} \\ - %\textbf{Template Arguments} & id & vertex & value \\ -\hline - \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_data} Members} -\label{tab:vertex-view} -\end{center} -\end{table} - -\subsection{\tcode{struct edge_data}}\label{edge-view}\mbox{} \\ - -\tcode{edge_data} is used to return edge information. It is used by -\tcode{incidence(g,u), edgelist(g), edges_bfs(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_id} member is included. The \tcode{target_id} member always exists. - -{\small - \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 -member variables, giving the following valid combinations in Table \ref{tab:edge-view} . For instance, the second entry, -\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} -%\resizebox{\textwidth}{!} -{\begin{tabular}{l |c c c c} -\hline - \multicolumn{1}{l}{\textbf{Template Arguments}} - & - \multicolumn{4}{c}{\textbf{Members}} \\ -\hline - \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_data} Members} -\label{tab:edge-view} -\end{center} -\end{table} - -\subsection{\tcode{struct neighbor_data}}\label{neighbor-view}\mbox{} - -\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}, \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_data} has two members \tcode{\{target_id_type target_id; vertex_type target;\}} -and \tcode{value_type} is \tcode{void}. - -\begin{table}[h!] -\begin{center} -%\resizebox{\textwidth}{!} -{\begin{tabular}{l |c c c c} -\hline - \multicolumn{1}{l}{\textbf{Template Arguments}} - & - \multicolumn{4}{c}{\textbf{Members}} \\ -\hline - \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{value} \\ - \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} & & \tcode{value} \\ - \tcode{neighbor_data} & & \tcode{target_id} & & \\ -\hline -\end{tabular}} -\caption{\tcode{neighbor_data} Members} -\label{tab:neighbor-view} -\end{center} -\end{table} - - -% Copyable Data Structs section removed — basic_ view variants (G.1) supersede this. - +See the Utility Types and Functions in \href{https://www.wg21.link/P3130}{P3130 Graph Container Interface} +for more details about the definition and use of the vertex, edge and neighbor data types. \section{Graph Views} diff --git a/D3130_Container_Interface/src/adjacency_list_concepts.dot b/D3130_Container_Interface/src/adjacency_list_concepts.dot new file mode 100644 index 0000000..bf5cf88 --- /dev/null +++ b/D3130_Container_Interface/src/adjacency_list_concepts.dot @@ -0,0 +1,104 @@ +// Concept hierarchy for graph::adj_list +// Generate PDF: dot -Tpdf adjacency_list_concepts.dot -o adjacency_list_concepts.pdf + +digraph ConceptHierarchy { + rankdir = TB + size="6.5,9.5" + nodesep = 0.35 + ranksep = 0.7 + node [shape=box, style="filled,rounded", fontname="Helvetica", fontsize=12] + edge [fontname="Helvetica", fontsize=9] + + // -- Primitive concepts -------------------------------------------------- + // Foundational -- no prerequisites + + node [fillcolor="#cce5ff"] // light blue + + basic_edge_c [label="basic_edge\n(shared with edge_list)"] + edge_c [label="edge"] + vertex_c [label="vertex"] + hashable_vertex_id [label="hashable_vertex_id"] + + // -- Range concepts ------------------------------------------------------ + + node [fillcolor="#d4edda"] // light green + + out_edge_range [label="out_edge_range"] + in_edge_range [label="in_edge_range"] + vertex_range [label="vertex_range"] + + // -- Vertex range refinements -------------------------------------------- + + node [fillcolor="#fff3cd"] // light yellow + + index_vertex_range [label="index_vertex_range"] + mapped_vertex_range [label="mapped_vertex_range\nnot index_vertex_range"] + + // -- Core graph concepts ------------------------------------------------- + + node [fillcolor="#f8d7da"] // light red/salmon + + adjacency_list [label="adjacency_list"] + ordered_vertex_edges [label="ordered_vertex_edges\n(semantic: edges sorted\nby target_id)"] + bidirectional_adjacency_list [label="bidirectional_adjacency_list"] + + // -- Compound / specialised concepts ------------------------------------- + + node [fillcolor="#e2d9f3"] // light purple + + index_adjacency_list [label="index_adjacency_list"] + adjacency_matrix_c [label="adjacency_matrix"] + mapped_adjacency_list [label="mapped_adjacency_list"] + index_bidirectional_adjacency_list [label="index_bidirectional_adjacency_list"] + mapped_bidirectional_adjacency_list [label="mapped_bidirectional_adjacency_list"] + + // -- Edges (arrows = "is required by" / "refines") ----------------------- + + // Shared edge floor -> adjacency-list edge refinement + basic_edge_c -> edge_c + + // Primitives -> ranges + edge_c -> out_edge_range + edge_c -> in_edge_range + vertex_c -> vertex_range + + // vertex_range -> vertex range refinements + vertex_range -> index_vertex_range + vertex_range -> mapped_vertex_range [style=dashed, label=" !index_vertex_range"] + hashable_vertex_id -> mapped_vertex_range + + // Ranges -> adjacency_list + out_edge_range -> adjacency_list + vertex_range -> adjacency_list + + // adjacency_list -> refinements + adjacency_list -> ordered_vertex_edges + adjacency_list -> bidirectional_adjacency_list + in_edge_range -> bidirectional_adjacency_list + + // adjacency_list + vertex range kind -> compound concepts + adjacency_list -> index_adjacency_list + index_vertex_range -> index_adjacency_list + + index_adjacency_list -> adjacency_matrix_c + + adjacency_list -> mapped_adjacency_list + mapped_vertex_range -> mapped_adjacency_list + + bidirectional_adjacency_list -> index_bidirectional_adjacency_list + index_vertex_range -> index_bidirectional_adjacency_list + + bidirectional_adjacency_list -> mapped_bidirectional_adjacency_list + mapped_vertex_range -> mapped_bidirectional_adjacency_list + + // -- Rank hints for cleaner layout --------------------------------------- + { rank=same; basic_edge_c; vertex_c; hashable_vertex_id } + { rank=same; edge_c } + { rank=same; out_edge_range; in_edge_range; vertex_range } + { rank=same; index_vertex_range; mapped_vertex_range } + { rank=same; adjacency_list } + { rank=same; ordered_vertex_edges; bidirectional_adjacency_list } + { rank=same; index_adjacency_list; mapped_adjacency_list; + index_bidirectional_adjacency_list; mapped_bidirectional_adjacency_list } + { rank=same; adjacency_matrix_c } +} diff --git a/D3130_Container_Interface/src/adjacency_list_concepts.pdf b/D3130_Container_Interface/src/adjacency_list_concepts.pdf new file mode 100644 index 0000000000000000000000000000000000000000..04d5f76fbc7a688ac5d3953ae052f946fbe17e11 GIT binary patch literal 13768 zcma*O1z1~K(>8p77I&8df#MJ#1cF0xcZwD$PH?v(rBK|hxH}YgcUp>5pt!rc!w)_3 zoacYv@4LS2Tsv#cl9@HL_9U5m7PX?NI1t3liA-IyUwVto4qye?7?>mT@c~$5jjc@` z%>W!vBxPg(0Kg&+wRAMLfBLl4cQh6?HncG^Mivl2c5t*e*0(}-P1%3{1Idr_jrRLHUU^+@9DP^6IT{p<{b7uf(NJwnimnjwc`0RH z7Kw9dd&zRzW5}Gn+)jp`w0YrE5KiNu7VZ8pBHRYheLQo=wHCv~q2pp1y~BoQ29ye~ zz^KnuRwo!>rnhGz;h=t}*7>TWgNKNE@G=%@)?jG4)Xh+wRMtr?)#1kRN((yOxcCVF zVcoX__W^Fq^y*ao{Q3)Er;Eh+Y`HGr5JNm^GX2*|#O>Ac-YPkIn*}ct_w58D9>k{7 zskMLo&5#eZIKdZ;1)I{?tnuZEn47g-iTiI~J1oS;1*n=)l^QxA-VFh%jg~K-(?r zGODTtUZW<|8mz)jlzNV8`z2ZV;?*td88V=ysR`@(YaLleXa=lF+?H@AcM+C!KpIqN z3qbP=8NiKK;TOI{R@J?IJVYFX*TuXT)fkv?{p= zYx$V#FeH9}z%OIfNnFxn7K&6{LMJ1&dJzg7=q_iR*$$(Y+ zO&1NyJ4otD_oO9#$Q4s;(6|Xlc%LxWu5zt`J^A_jjG@=6Ch2Ov`QnOILVA;Ep=2PN z-0o>gedn2TiivPmlNv=DYZUFHtxOu1n}XC2D7S}Sut-_`JGze%cv#In#l#=r6Kydb zKMCMXxV;^1dsx0ge5s9h;gV50c6OWHZ}3926;l%nMKe?AnWMT?=c5puml+jbhvE>$( z?eXyWd{o$&KO7|=(j-@s6HfmromgLL(UaYWTPR?*I^TJJ`w}^ihPOD?O)cv|IKof) z#Lze>D@PX~GjiK_11A^%-i}mN-zOK7VB%vPW-gV)w8iT*#t3KG3ooUUk@}fN248<)=Jvdb69No@qfSC@Zi0EGUrI<}F5G8H@37Ew!IRFvOM zUof-XCXxRo;V`04qE1CgaE!0BX}a8)_qJY{_0eR%)X=&?zZry987Nr(<=<2ZnyVy#MWXh(Uwtl8s!6_A-E;*DDMPCV@St%*z4(s$wh?ni`R6B>eUuotR-8}P4NW{60fubm znW!2BRqf+c>?YNt48=eDw>QJq`aExJFSg}zwo_+6`BB%Qtqr`Z6*aL|tjv!NE0Nwg zuOgOL>XFJh+MrAPS-%AmVI(#ar+9a-27L004)FGOR|;RJ#T?dIr)``z5-aTV2!5br)aO|BC*V?^fzY zbuFNB^%~J@oL05335dHR-{f7^a0%+Hz`_%?Azm3lEUyZD%PTF*v<_3Xs2uy%>cs?| zj4!&JpZBKoKH9v~kFFJS%K=m*zW2kgyee>kTxtTXfP;(p25ZOA74i4fik9Jvy@gq7 z;&b~JwF|g?8hV`vA=VS=bV#O6iiNK3yO(*NwRz$;n>N~pks!55bL~f5aJw&!-q?I< z`|1OhqX@P(uv9!ZA4bCI)e?M%Xv&YgC$ep5pi;hxn=4T4uaKGrUs$%wo?l8SeGh>91!M{_OJd`Ob3vg!yMSkFZQS3DrC`kEmE!K7!P1{Hu$d*^5 zOApy{ceZ)I0c4A@8rPbQuQ`}BTd^)z>+c@aV)66*V)AvipsW1CO>TUaZd~g!cfOOB zUeTe>G$gd6zk1S_wI%Q~o1KFwKA*d+#k>UR!cgVQOO$w)P8M3j-<$a(7O`)--cG7@e&Y~Ew{*vuj04VG6LmzK;W5hI0Ak~1Q3D*h zTFG2k@8)(pHYD+}gX+8~SpyJSw0;Jr{5V2vj%|hZQAt$DF0h1U`QWyaw*$SA5ra>$z=$+qr0w2wn&;+svJB_ENqF z=hZdzkvi$cN$#g=UOVB;KokkeAW`(*D4EP6K-VcRqabnLcro);w7K(sDD}Rr&T#N0 zKZD>*hRPyvu2uUT#n;Aq+%&vN7q{{$&z&CMw}{8uCa-g{^}@G zcv0rKoT}_!#J(k`1`@%o^^2x&Ev>1Ns`B9c$~2G^e4`36&8p8mVAJs0*xO~ei)G+x zR4AF>$>Vo}EUe6md*~la7tiTjtfYB*eVm^93~hLbV8Lkian3#aLwi2>%yw-npfOAv zidhu{W`t|S9Eq*26?DE0I=|@o2Gmi1Im0xRo#~6FA`?KxF`b7Ir6~>L zy|wX@Z0`;>A5AGPZzsosf+hi=6ssDu_nbl+zePs?9E>-u+h#2 zWnf~PI26=T6vx|P;H$}rC5}~k2|hO$3D8~X9GBk0R3Vde;?g#Zi(Jrsjr`7?%mI2- zjs4_WrGK4gxFeokHb1_XCAaS6A*oS@w+zudhDsFf6|5ExmBdXCZ)ylyPa@Q6Ueajk z6J%s;r*?s*dT%T)m25PZ$kOrM+po1;lafVb5j5s6J|054rzQQE7s6jvp~Ca{)7p|( z7#HdaRg||LMYwfEEkvItU$T@J6b4orw51ftWdb#=s6KFzYSM8@*=PBnoM(-RrMocH zo5q#^?YXU_$E6dUhIg;38PmdPmV|>&5z+Y2r-g|$nlpK+g$9RwzED2%wmH2mC(A>{UMXs)cZLar5K^)y{o5 z3y+ER@C%!tf>Ikp>$U39%xn~sNo;o+ugrZeD;Ga}E5aCoDTzYW)S+kA)-7y>QTW=a zc#+34={HpFNvg2wB2QE=wZpyOQV>1k|4MmclRc*tJ1-@iW4;~L0c*mw&O(Wh+>x8K zTyE=?%g^|#_UT48(ZP;J&WiH8mz+rJ@_dJqe6-nz1qUgcP?m1XoKLEQFG1{{KVnC7 zQ@-}}Z7K^*_@>+U8b!q4y|4M)9X(Xm8_6pEXm7D~%%A6%YdB;@mFFJ7zh<;1YuIIZ ze#P>kB_Q&+)YIOL)`+o(GP01(lQiAk+%}lVgq8)~e}UXJ!T&RxEl!m~^Pyr-2^x2p zdiu|5>o~TTRwcXe8^%{R-`-chhoR`Efa17J3(}(ga_aje5dg*Ni_{SU4tNXA!>O=- zR$p8YnY)Ouc(ee84J;OM_-N-rWiL^HFpX*lekDR zu#H_4pFs1#MmeCPtO|-DKpwaeC5Jb09+See&P5F^K-yIM>gP$Y7y2clzaV-uhQ!fI zmo%N{&oA(IhvFwZduGdXYQg)yMWmU-7P+W%@wF?XB4`h1O1zJg!1~3^&l5e19C|;n zp@9u^?%yb3uT3_zr#3%xvH(;c)q!6w`dma$)FN=3M*|H`-N_9uM=CBBEaDGuR7j$> z7_QouINhvPENz_xc)VF2w-|Mzhi#1Hzg(#Vs1fIgTvpN`pam#oKfQRTH+Dn z*uv(u`)5z^-F#?&x<~vJqFO~JjS<20{_>V0#xTUv(NkL`g-Y^J0amN)o47ot$`l9b z5NAlvh(R+R3zZDXYhP*nqbzcTg$avqOcw`g9SG#I%l6a*b8AdH(Tw^G^BV#Qw)fN= zX0NfDRoe_=iL1#70uuba8GWZCKg$_ue-$dbFD>(%0$lYoi6dDRJZ90kE+{WeIEhFk zt1B;OoHl@}Hf6IE&I9C5J#0mzikDRi8pt+0*1{scs9ws0iA;(?vAzLjx#f`#*!=Ie z_zg)t>LqK^MHu*jpZSSXdYx6|_*6 zS3EKFgOjo$c|bmI_5GFAa8FlWXB(K;?MR#_9<)L&uO08{4@URrMeX)x_TL@jQuE(t zrI;bx2Zb%XiA2dr#jGi4gNb=pcfjiN;o)U}<3kxqPBPyD@#6R7AIi11C&Be~k(E7T z0XO?DJC6!5ay7`t)<%B?R-Q`FA(`hm%=70{B!-X>zghnkFXH}tB#S%%^t(YEYVY6(VE?Q9e~%%7RalpT zH-gt;|A6O$(fOZRc%J<)Er1|@ivzC6kfk#^xA)BbdMixhO@JUIZRhKgO{FY#SSEoyQtc}!oxUXWCzv+Y*U z5?CK@-^WM3z`NZgO9dMeXU-lA=;K^)@V5j}>4G(!n@!1nKEf$wp3?mIU0&rF2zht&vQl0obf??Obr(1NrKbg{CAsl zJ?y?rXnBK{-cP?An{>|HTl#q89&h*18+Q8Z*HtvMQphXBw5vLLUJ~uKv7|bSuKx^T zG&~r{qZCou^ev4pcft6D8Vy-ku>v}gMb;}S^R*4i+Vb8h{4Eo>)jXJD7X1-0&+>u&IAkotigPtA)O7o6{xCnocX@rw|Ej?b};|JMoSANi868gf+$5yGdGH4 z1Ca0AaE26wRFpbhjT97w z#`c-kP^R$4K;9#J3!kUvP2*Y8nfA6$UUcDUK^v!4 zUA<`1n|pyCw%U{zu||5h7V!IWKrBWLuM8%ST?tt?jfn*zZQIt>JKUi>>zJzL=+fJ8V6h{@xApnl`Fi%q%WG z{hU>&AIU3{omJ?q{K;E|9~pT}?6tk|d9o^(zvMpnwEPm7V&3{0XbHE!nC`*mhrrUR zl6}=$e#U`u?gV#^C+DA3QSjyMT+LX6bk!O5XZN5Aw^XAX8`seMTu^bL3R)eIV+r{{ zLt(G-ms15tMSbU`{hOiNYv8Kz)N844*I^ZHOs@L_iBrg4+!wUGdA0o*P?jRuxgm#( z%dO+-o{;qOtqM-+m#GtCEsk$0b3fP85Dk0U3!ZFyrS4_=*$r=xyI}cY?kMyxxAKyI zzqgpG{qe$WY5kio#igxb#LTA>wn!r?$BWD*t|?zQ@>-o2`E)4K=LlUhERaczOzTFluBbD5S9 ze)je5X#r1k$3v-Gl`!#<4{P2j3$9n~weo3s8EO3c8iXne?^@k6OYJ^yi3hHT8ox#@ z6W|jVkW`y=(Qv(y&@eM{spm!+$CK*nhh94WB11;ws$cUUf%3Mkz2DUo?U`@FB3efL zuw^6HB$GF)uiE4Ai+%g>4~YjDKi^jwZ#yYqd9 zD=OJRJA|38Ek4WJ@vmJXT^lP>CEcc@9hsG9JT)(q4jy0DWb-j?^AZrt@_xIdyjJ3# zF87p}@F(SksO}?5P4ihj*4xeYws~<~jzqg?X)S2l({Xmgr#HEu&rKJrx5cLSv#j9g z?oQudC1VUE$Rj9bq@X7V7?v4ds(%w%F>H;YTcb5`sm0?O`RZrC+gYIaV!9}huY-sh z)|s)%GBye~&9X{3!Wdka%=0GD+xWDAG|c<$&xxTs_JH7sLysR5CiH}J(JbH2CAL2B zZhx3;Je?K5DeeKH{%kP$7^tE3vf^#grFt)nciiqvCpp;HcH-n|^VC|GR7>W-Fkt?y z)ld6o8A3jLu&=nXe01iKvx7|kicr z;_-~_Q1qPW6xd9Fb*XW;pMn#$4jYOEs$Dq#n=((u9% zx|DYc)wOju1Yv~^0f#};ZHOT7s|O%d>GQScLcyA9{CMANMBG;o=j-64ogy?6yu(fV zZ($_%OXn=xi3+8o<8t*2O0kAWH{LI{eG?;7KZY>iF~45>RiKm?U7?m1by#IYB<}~$ zk*Pw+|h~^zS~SyZ6r1EaC6fq|`JS z!=36*kdyc_oZ(LMq=MghHi5v$B#L;Gtppwffu(AH{{61_6K2tM|J=m52`J490y=YR zTQGWYrb+VqC?;jc3Hxd#%h+#IvimR>9}^1j%p$7##0qNz)kTE_g!;3$Vb zM(0I240i3<%dpikE3)nj=^DjTyzmOYzY)GU!+daSWzqQExwi zoLfI`iyFdZ)dfh9uIJX=I#p$p3(>1E#{IYRemKfe#%xikwf6-b_q%HQ@O0=F$o({p z#O8?^^iTAtP53%c%Ws{YC%Bies`UncM9h+&X-%fbAorc7C1V{>m01%1EN`3vRWk`#1+|k{S9$B;^fzcW%m;Za`3z_5luixG4@Ii+1gkWsBy1`CV66(e; z5(O_nh9moj6%>@bW4o6iZF@Z%d2+Roa>chgRR-7gJ+o8@I=70Hs!q7+5QRp4-IOiU%2~I z*GuhP8uI7pPA5edgCSmur0=~VP2%Ko_B746}8on?wh8wIu#Ig(%C-I;_Soxwr9wHfk zSQj{G)fd}aB2UQ6*Y_AtE<_DGTAW&NXrHL+-VR%-7a)B3>YeS$E6*=v#=P43Eq5nD zT58VuCf?hj+U3cP24)HVt%AKH{@$UPVT(ZBJ?|;4yFR*|M;k?4{XtkIlb$z9fgn~` zhdN)AaGe?$g9N++R8&KuUs>v-X zym%w5H}hqE+yf%Rw1m<5&Kb`U#AxQgWT)vPRUtscQAPUhq^{1 zVQ3?rM2h-1QZO3k4{k6W&g9DkVO*4vI6nXP%q2^5FKKI?aSuiJKu!WLEFUj5Jb6MV z5+d$jXVgYs6TF_bRP*0ziUu08lxyW_p-gv>#mk{~AE`!5k5i-~{CpKHg3$g)TH!{F z2M@CNu?I*Q^cF=VBqNZZAU7vg05;+%pob|}L+4Fejm(lpSS-f2gBhoeT06uXzd>7~1`!f3#jNdB7dV4(Bo@<(|&LJRn(XlQ1r zqkBXm3u;fEZ8dSS6V|IL5?0o_Q8W)_@E&mubEALesP+5z1LKw{_IT@kJO`0F5~cu0 zm+l5zNl_SvRP36AuFhu1nXORIN2as;7C%mCiUnw{EZ5xkT4zSotIeuXt%zTY;56S- z!F>4Cv}W+mxOMa*t5$wi>heha8hw^gD-1s$hJbMQobU*xjbB_LKozUnWeRQxhMnLh zNT9a$;vN4uH}Xl3?XB6oBfe(RdokO#gdE&yn!=bpF?Sz_a0d#YORFg7uZvMF?bK79 zO%Bs!Fr2ZK>38Q~Z#sKjN^kK?-6)CmQN}Zl>u$Ux`EfV9-I~c5b}EU=Q6}Y~YzrW% zYso#+na<~C{k+V%Q9?9Xwi1+$1dRY&@)clYPY{lCc%cMd0W1*~cwrJG+u4y^}=}<*Q zbZPnzeu9+vG5K36mRNdJ_;f#1Ls_JGPEtj?#Cyf-(yl-1W!6s^>_*x^twY`Ca)BLHw`G50${hrbp{`(!qvtTYyYuD|QknM0w->OY8l zF=@IgCSaw(l;B)|v2}lAEHU4rY(xB5yn)0V>g(LcfURp6)+B+uucmtZN{`*2YIt|k zU2m>a&(B46@qr5naWZK)8!9NO-Zc}jZ)>e?Wo%lp;im%fS)gT?5e8^lA$%G&$C%*S zDhPVRW`xsmpzY^7-&A1*Lqk(H%bD5TRRwIWRN}kvtZ=JNax3zozJc>59pT9~ zheKPJT^O<1TVGG%8)H)+%h9QeiWJ--BF7b)t^uyp>A+pTE;Wkq82CP+h#jncPx&Gq z$yVBC!|?=?g#a^TiCtTL%N?>VcH~e4!_v`Kw^bGQk(3KoGpm*66ZZ$5h&hsl@0zE} z+S>V6YK@*)y^$SsBq*lyjx}x(a>mZS^}qx`_deTP_dfe8c>|qy^0MWm@Oe{i^7982 zjRhZ9nOizm?RnUFO(u$xo17GAKNjf!8u9*v#GMc_qtxZ=(^P1vcbaZIxKdoegaWpv z7cB@TO^MQq9bc7o-r$meUP291RrXY>r?oyiBs#Q=7h_Suf(_<#o3abi-RdPop#t-p zfp$Ihde+vc1f6lF$LUO|TrN)HY`j$%ad1sI>mj_U0eUpk$+Y&6=>C-%;F z=g@#V)=VVwQcTH9!)(Lt!|apADTpNcDuNW-Q84vrC|l=j+Q_TcgTg7*qng_3a&s-? zF9LV5Tq>0Em>q$R>d~8fjAwY^(x$n^V=dFVx$4}t^|kdD=URONQvxoj$E9|IW?+*n z1!Mv%^+iSE3;9~FJ%8$5@|HSQUMX}-4EU-c-~yYyF$MW-B@7wbEY@H}C}{;^VCvd? zc&YePQ$jUiTrP^F{2m4~9$$(iB`!HL%Z5m)2u%JAf-P2#1gm{_l1Nnc&AaQ<)_pJf zp7lw$6KbBS`7hR)qbV!jm+!l|#&enaX56_^SVq^I?nPy3z8VNN`?&7H@#U<2kFGZT zhR>o|SIA8@MMT}w`8jZM_b^U%W?)AeXUA$f^` z;fPy(G<{hXhH?;N{bKMNfa{`B;_^Dy^Pmm z0GZi6g+1ADj1kMUw2MI*ZouZUBpR=%TI5SE`{1T1WJFd}y%-_N-94zT>}52IYlRh$*KHlXME!<7gp8Yk8tqq_8sE3^ zH;u3iQOXvOw0G5E8$?$EULCc#4KzmRYmw8g>f-2;A~^)AF*R4YtZmYQ#{?b@jE`_9 z&G7=m55mlytkLq)*K)BOJn)4yYiQcH&gk1jM?Wi;3Zi)&=GNL9o|1$3A7wa~DqikL z3Z*(I0e()Zu_pEfXYpXEBM8-mBg8x&4bwc16mKSc`tH*>x!lFm%G2yh7%rC(TBn8) zVCQjFew0#UmWsHtSg_LA9;)fH$u~@m;W`9%c*BA%{^ml_Omi)U*L#QT3{6V43vwrQ z`k^6ps?F<{eOd80FT5smLW)lD@Dq1g%HaAnJwZ#dO@x`L?}Wo@KhS;JE8~xhPo=To&{_szG^phgSFLD1Y++-#gm2inz7N zKhNZP-eLwbS2ptaCH?RvwV_^wQ{0d&kif#DyZfGSiaYARp>mVZf0C2MItC( z?!10sC-ii?(!p;AE)O7!qy+gcig!Yh@~Q5`JEf3pq+C@xk&ybR*(JGXmJ49c8GW;K zg}1^CDXEsjUaRzw^eu%M-+kK^vNI~0hL@0iaK}WKas5h+F2zNcDc@O)jUL-xrc>^% zr?|)BLEKTl^A}fYl-i~xb!tW5h@YxmKd@`> z$0%y0u5#gOTXBK4@$E9&d@H$TzgBz(i7lhcD`w~+(gn`Kc&(~$(MTqny8W%o7hbYJ zx=?n*g9xZfw0Yl_@WSuLAJ?=Y2G^+QfBo)_<+n*)qB*Z!5>?*F$roTL;KHd|IwqEj zp|-8)1BXXlj!j*|hRBF|rH36aXc4%MoyM_5g!F?dR)%%ftJSgas=+T;Mqdgk7Vkz( z6BA!XgGxUWCC#~Ag_tSw$Ot@O<4>EUuL~ZCW0mM!#U_*clrEKEwH7puvxJ3I72nzQ zi$0E3ML5Wh2s=+E0rE$1@-hX2Y~0aDKYHw78jGv~A{q-@Z=>pZK@=LPgg{1x0bgN3 z*$gsJCQ9gKNBt<4LCTAP>4O;73tBReTBib^ZJ8g43oPEbr9=keffeuJ?V-a6b?ih$ zx}IQdCia)A4>-rZWEWWg)qg-u!1k9WWc$VFfA#(dP)E4;SqLuGAaZ)c-$$MhK%p-D z=p``PMs#z29_S^om7E>YO7?9uQvue9mtvP$$4IJPCSU+n$B2hQBw(RsFRKp0eLB+= z|7?p4mtQ*LL!-JQhHxW6WA00_x+V%BVxf>uP9sHuNU)y~lFodjp9hT_g(7UwVB|+8 zs@ONpI4g>u?63`zDQGaVDsX_AGDxDCIaySqD>6}|OJ9~^Fey4hFkGqCR$Kg{5Ylp& zm|?!W$bYTOMa^{tm7vV#y4~t6eFQ@Gak`bJ!giN*{l- z@4=hUh(~htlgFfw-frEGdi7w#z5j_;{RW}_f~z2$An-qc)qhaCzhNi<=sEZL|1Hs4 zNBM_!Co5+2Eu%*cLhKTia};GxurAkG=9t%;a!z(-J4zh%J5Lw>Kxuv|Ub5j*(|urV z)27ZV6P@P#(L?CuJ*G(3sjF1lnNPTgDr0un(&j9~<9%VWYRC86UAMe(=8J4|Z5@xJ z4L5o97FXm|AF|lVMpqf1G0X_}P| zj8muYQ19U3UD27fbL99t!Yw|hG-ZN_oSDkGt=dD*V1uhVbq-1Hvxg>`q8k5PXig-oZ_MA}u$3cOA-IPz$ezV$+^HkSz~%V)&FM zdWtxh{qsfbC(=9KV;gBR>1CxwDNh7J=GzWUwIQ~xA8V~6A#u8|`0D3S_%x13mP*8j z?D2^i3B6LTpzWNUvmfUG#I6o2gU(C5%gY@>2)?(R_K$e%uhy_^%BY9w9bD3JyrqI9 zs4z^^&=P|w#yq|9?V?NW?qP|4bd>!smi{|){s~wFb8-G-=)Y0hX8`t3#Pk_%6*YD+ zw1?U{+SvaIiawF#^{t-ZR5kIpqM}laqQ>U>YECNp)(-!)i|boKE!_Zge>MT0+vxvn zwA43s0D#&4=_xF1;|kCQ070y5tN4)o%?ACPv&~o@V^E^Ku@a# zL7w#T@0nQv>`!zMn2qbnxpJ_vGIMi7o(F=t*`Aig&Gn>)f6c+c{dBg48^ZM@AJ>1( z_%G_eioc(Yr>E5Btu^%dYzqMN?4|#`dqL0Y`S0zk@IUe&K+i_`(~rylll1VM0Ko?S zy|4baY=ox_i+@hhyp2+@@MFd8KJ*H1h~3Fdx~kJL!YD3}RgRo*i6aw6EmaJqs&H)c z#L)p#=U*D?n)piy@g==}t&5tZ6oD@p{F6~e^vf(ACPxX*3>;?5`PW_q1I&~o?rdp! zUzqcYTeobb%G7$rBktX}7iilKl1qAFMCZ)GCQrY2bU&1e6gC1hT9rN}>Y{UiVZB;H zq*7w|hM-sk+dpum$dQoLV%juZ%O|bd^rh=xF;Al|h|N~{-c{HId1^{WQhmpFXH_eW zvcAcV9uKT^^i3v+NG#p5EHv;XOC@OgdW9!0XOPNJT-4(-+_UX!J7VH|M^&AIOF;a6 z!>u-Cj%l=}rL)Z)54=PyUvTlj|RU`*(iGe;ka4 zva!i;#s8HU!pZ%AG{bXJhziu*7{KpXd zJ;Coi@{a)x-@m_lOb_x2@qrO#1tF6ey?<}Cgn<32_>IA + + + + + +ConceptHierarchy + + + +basic_edge_c + +basic_edge<G,E> +source_id(g, e) +target_id(g, e) +(shared with edge_list) + + + +edge_c + +edge<G,E> +basic_edge<G,E> +source(g, e) +target(g, e) + + + +basic_edge_c->edge_c + + + + + +out_edge_range + +out_edge_range<R,G> +forward_range<R> +edge<G, range_value_t<R>> + + + +edge_c->out_edge_range + + + + + +in_edge_range + +in_edge_range<R,G> +forward_range<R> +edge<G, range_value_t<R>> + + + +edge_c->in_edge_range + + + + + +vertex_c + +vertex<G,V> +is_vertex_descriptor_v<V> +vertex_id(g, u) +find_vertex(g, uid) + + + +vertex_range + +vertex_range<R,G> +forward_range<R> ∧ sized_range<R> +vertex<G, range_value_t<R>> + + + +vertex_c->vertex_range + + + + + +hashable_vertex_id + +hashable_vertex_id<G> +hash<vertex_id_t<G>>{}(uid) → size_t + + + +mapped_vertex_range + +mapped_vertex_range<G> +¬index_vertex_range<G> +hashable_vertex_id<G> +find_vertex(g, uid) + + + +hashable_vertex_id->mapped_vertex_range + + + + + +adjacency_list + +adjacency_list<G> +vertices(g) → vertex_range<G> +out_edges(g, u) → out_edge_range<G> + + + +out_edge_range->adjacency_list + + + + + +bidirectional_adjacency_list + +bidirectional_adjacency_list<G> +adjacency_list<G> +in_edges(g, u) → in_edge_range<G> + + + +in_edge_range->bidirectional_adjacency_list + + + + + +index_vertex_range + +index_vertex_range<G> +integral<vertex_id_t<G>> +integral<vertex_range_t<G>::storage_type> + + + +vertex_range->index_vertex_range + + + + + +vertex_range->mapped_vertex_range + + +  !index_vertex_range + + + +vertex_range->adjacency_list + + + + + +index_adjacency_list + +index_adjacency_list<G> +adjacency_list<G> ∧ index_vertex_range<G> + + + +index_vertex_range->index_adjacency_list + + + + + +index_bidirectional_adjacency_list + +index_bidirectional +_adjacency_list<G> +bidirectional_adjacency_list<G> ∧ index_vertex_range<G> + + + +index_vertex_range->index_bidirectional_adjacency_list + + + + + +mapped_adjacency_list + +mapped_adjacency_list<G> +adjacency_list<G> ∧ mapped_vertex_range<G> + + + +mapped_vertex_range->mapped_adjacency_list + + + + + +mapped_bidirectional_adjacency_list + +mapped_bidirectional +_adjacency_list<G> +bidirectional_adjacency_list<G> ∧ mapped_vertex_range<G> + + + +mapped_vertex_range->mapped_bidirectional_adjacency_list + + + + + +ordered_vertex_edges + +ordered_vertex_edges<G> +adjacency_list<G> +out_edges(g, u) sorted by target_id + + + +adjacency_list->ordered_vertex_edges + + + + + +adjacency_list->bidirectional_adjacency_list + + + + + +adjacency_list->index_adjacency_list + + + + + +adjacency_list->mapped_adjacency_list + + + + + +bidirectional_adjacency_list->index_bidirectional_adjacency_list + + + + + +bidirectional_adjacency_list->mapped_bidirectional_adjacency_list + + + + + +adjacency_matrix_c + +adjacency_matrix<G> +index_adjacency_list<G> +contains_out_edge(g, uid, vid) +find_vertex_edge(g, u, vid) + + + +index_adjacency_list->adjacency_matrix_c + + + + + diff --git a/D3130_Container_Interface/src/concepts_adj_list.hpp b/D3130_Container_Interface/src/concepts_adj_list.hpp index 79c4305..124c197 100644 --- a/D3130_Container_Interface/src/concepts_adj_list.hpp +++ b/D3130_Container_Interface/src/concepts_adj_list.hpp @@ -32,6 +32,13 @@ concept mapped_bidirectional_adjacency_list = bidirectional_adjacency_list && mapped_vertex_range; +template +concept adjacency_matrix = index_adjacency_list && + requires(G& g, vertex_t u, vertex_t v) { + find_out_edge(g, u, v); + { contains_out_edge(g, u, v) } -> std::convertible_to; + }; + // Semantic refinement: each vertex's out-edges are sorted by ascending // target\_id. The structural check below only confirms a forward edge range; // the ascending-order property is a semantic requirement the author asserts. diff --git a/D3130_Container_Interface/src/concepts_edges.hpp b/D3130_Container_Interface/src/concepts_edges.hpp index 1b7ebbb..dac93ab 100644 --- a/D3130_Container_Interface/src/concepts_edges.hpp +++ b/D3130_Container_Interface/src/concepts_edges.hpp @@ -2,15 +2,15 @@ // Shared edge floor (namespace std::graph): ids only. template -concept basic_edge = requires(G& g, const E& e) { - source_id(g, e); - target_id(g, e); +concept basic_edge = requires(G& g, const E& uv) { + source_id(g, uv); // returns vertex\_id\_t + target_id(g, uv); // returns vertex\_id\_t }; // Adjacency-list refinement (namespace std::graph::adj\_list): // adds the source/target vertex descriptors. template -concept edge = basic_edge && requires(G& g, const E& e) { - source(g, e); - target(g, e); +concept edge = basic_edge && is_edge_descriptor_v && requires(G& g, const E& uv) { + source(g, uv); // returns vertex descriptor vertex\_t + target(g, uv); // returns vertex descriptor vertex\_t }; diff --git a/D3130_Container_Interface/src/concepts_vertex_range.hpp b/D3130_Container_Interface/src/concepts_vertex_range.hpp index ccee44d..e5506ce 100644 --- a/D3130_Container_Interface/src/concepts_vertex_range.hpp +++ b/D3130_Container_Interface/src/concepts_vertex_range.hpp @@ -4,7 +4,7 @@ template concept vertex = is_vertex_descriptor_v> && requires(G& g, const V& u, const vertex_id_t& uid) { vertex_id(g, u); - find_vertex(g, uid); + { find_vertex(g, uid) } -> std::forward_iterator; }; template diff --git a/D3129_Views/src/edge_data.hpp b/D3130_Container_Interface/src/edge_data.hpp similarity index 100% rename from D3129_Views/src/edge_data.hpp rename to D3130_Container_Interface/src/edge_data.hpp diff --git a/D3129_Views/src/neighbor_data.hpp b/D3130_Container_Interface/src/neighbor_data.hpp similarity index 100% rename from D3129_Views/src/neighbor_data.hpp rename to D3130_Container_Interface/src/neighbor_data.hpp diff --git a/D3129_Views/src/vertex_data.hpp b/D3130_Container_Interface/src/vertex_data.hpp similarity index 100% rename from D3129_Views/src/vertex_data.hpp rename to D3130_Container_Interface/src/vertex_data.hpp diff --git a/D3130_Container_Interface/tex/container_interface.tex b/D3130_Container_Interface/tex/container_interface.tex index ec8cde6..ce9f49e 100644 --- a/D3130_Container_Interface/tex/container_interface.tex +++ b/D3130_Container_Interface/tex/container_interface.tex @@ -3,10 +3,10 @@ %% \chapter{Graph Container Interface} \section{Graph Container Interface} -The Graph Container Interface (GCI) defines the primitive concepts, traits, types and functions used to define and access adjacency lists (aka graphs) -and edgelists, no matter their internal design and organization. For instance, an adjacency list can be a vector of lists from standard containers, -CSR-based graph and adjacency matrix. Likewise, an edgelist can be a range of edges from a standard container or externally defined edge types, -provided they have a source\_id, target\_id and optional edge\_value. +The Graph Container Interface (GCI) defines the primitive concepts, traits, types and functions used to define and access adjacency lists +and edge lists, no matter their internal design and organization. For instance, an adjacency list can be a vector of lists from standard containers, +CSR-based graph, or an adjacency matrix. Likewise, an edge list can be the edges from an adjacency list, or a range of edges from a standard container +or externally defined edge types, provided they have a source\_id, target\_id and optional edge\_value. The GCI covers two peer abstract data types, each with its own namespace: \begin{itemize} @@ -17,27 +17,18 @@ \section{Graph Container Interface} symbols are \emph{not} re-exported because several names (notably \tcode{vertex\_id\_t}) have different definitions in each namespace and cannot coexist at the root level. -If there is a desire to use the algorithms against externally defined data structures, the GCI exposes its functions as customization points -to be overridden as needed. Likewise, externally defined algorithms can be used to operate on other data structures that meet the GCI requirements. -This achieves the same goals as the STL, where algorithms can be used on any container that meets the requirements of the algorithm. +\phil{Consider not exporting the adjacency list symbols into \tcode{std::graph} and instead require users to explicitly use the \tcode{std::graph::adj\_list} namespace.} -The GCI is designed to support a wider scope of graph containers than required by the views and algorithms in this -proposal. This enables for future growth of the graph data model (e.g. incoming edges on a vertex), or as a framework for graph implementations -outside of the standard. For instance, existing implementations may have requirements that cause them to define features with looser constraints, -such as sparse vertex\_ids, non-integral vertex\_ids, or storing vertices in associative bi-directional containers (e.g. std::map or std::unordered\_map). - -Such features require specialized implementations for views and algorithms. The performance for such algorithms will be sub-optimal, but may be -preferable to run them on the existing container rather than loading the graph into a high-performance graph container and then running the -algorithm on it, where the loading time can far outweigh the time to run the sub-optimal algorithm. To achieve this, care has been taken to -make sure that the use of concepts chosen is appropriate for algorithm, view and container. - -All algorithms in this and related proposals require that adjacency list vertices are stored in random access containers and that \tcode{vertex_id_t} -is integral. Future designs may relax these requirements, but for now they are required. +The GCI functions are customization point objects (CPOs) that provide access to adjacency lists and edge lists, providing +a uniform interface for retrieving vertices, edges, and related properties regardless of the underlying container. +They may be overridden for external adjacency list data structures to enable the use of algorithms on those data +structures. This achieves the same goals as the STL, where algorithms can be used on any container that meets +the requirements of the algorithm. \section{Adjacency List Interface} \subsection{Namespace} -All adjacency list concepts, type aliases, CPOs and descriptors are defined in the \tcode{std::graph::adj\_list} +All adjacency list concepts, types, CPOs, and functions are defined in the \tcode{std::graph::adj\_list} namespace. Every symbol is also re-exported into \tcode{std::graph} via \tcode{using} declarations so that callers who include \tcode{} can write \tcode{graph::vertices(g)} rather than \tcode{graph::adj\_list::vertices(g)}. Code that wishes to be explicit about the choice of abstract data @@ -58,13 +49,16 @@ \subsection{Concepts} \subsubsection{Edge Concepts} Two layered edge concepts are defined. \tcode{basic_edge} is the shared floor: an edge must -provide \tcode{source_id(g,e)} and \tcode{target_id(g,e)}. It lives in \tcode{std::graph} and depends only +provide \tcode{source_id(g,e)} and \tcode{target_id(g,e)}. It is defined in \tcode{std::graph} and depends only on the shared id CPOs, so it ties an edge to both the adjacency list and the edge list (it is the concept required by \tcode{basic_sourced_edgelist}, below). -The adjacency-list \tcode{edge} concept refines \tcode{basic_edge} by additionally requiring the -\tcode{source(g,e)} and \tcode{target(g,e)} vertex descriptors. Within an \tcode{adjacency_list} these are -always available: \tcode{out_edges(g,u)} and \tcode{in_edges(g,u)} always yield edge descriptors, and +\phil{ The \tcode{basic_sourced_edgelist} uses a carry-over name from using "sourced" when source was optional, which no longer occurs. Consider renaming. } + +The \tcode{edge} concept refines \tcode{basic_edge} by additionally requiring the \tcode{source(g,e)} +and \tcode{target(g,e)} that return vertex descriptors. Within an \tcode{adjacency_list}, \tcode{out_edges(g,u)} +for vertex \tcode{u} is always available and yields a range of edge descriptors, and \tcode{in_edges(g,u)} +additionally yields a range of edge descriptors when a \tcode{bidirectional_adjacency_list} is used. \tcode{adjacency_list} implies a \tcode{vertex_range} (hence \tcode{find_vertex}), so the default \tcode{source}/\tcode{target} resolve to \tcode{*find_vertex(g, source_id/target_id(g,e))}. The descriptor requirement is therefore free for conforming graphs while keeping edge-list elements --- which have no @@ -73,20 +67,15 @@ \subsubsection{Edge Concepts} \lstinputlisting{D3130_Container_Interface/src/concepts_edges.hpp} } -The previous version of this interface defined separate concepts for targeted edges (with only \tcode{target_id}) and sourced edges -(with both \tcode{source_id} and \tcode{target_id}). The descriptor design makes this distinction -unnecessary: every edge descriptor carries enough information to provide both ids, so the single \tcode{edge} concept is sufficient. - -Return types are not validated in order to provide flexibility. Constraining the return type of \tcode{target_id(g,uv)} to \tcode{integral} -would exclude graphs whose vertex id is a non-integral key (e.g.\ a \tcode{string} for a \tcode{map}-based graph). Constraining to -\tcode{vertex_id_t} gives obscure error messages on failure. Leaving the return type unconstrained allows the compiler to +Return types are not validated for better error reporting. Constraining the return type to +\tcode{vertex_id_t} often results in obscure error messages on failure. Leaving the return type unconstrained allows the compiler to report the actual type mismatch at the point of use, which is easier to diagnose. There is precedent for this choice in the \href{https://en.cppreference.com/w/cpp/ranges/sized_range}{\tcode{sized_range}} concept. \paragraph{Edge Range Concepts} \tcode{out_edge_range} constrains the range returned by \tcode{out_edges(g,u)}, and \tcode{in_edge_range} constrains -the range returned by \tcode{in_edges(g,u)} for bidirectional graphs. Both require a \tcode{forward_range} whose value type +the range returned by \tcode{in_edges(g,u)}. Both require a \tcode{forward_range} whose value type satisfies \tcode{edge>}. {\small \lstinputlisting{D3130_Container_Interface/src/concepts_target_edge_range.hpp} @@ -108,29 +97,36 @@ \subsubsection{Vertex Concepts} \item \tcode{index_vertex_range} — vertex id is integral and the vertex range is random-access with an integral \tcode{storage_type}. Used for high-performance graphs such as \tcode{index_adjacency_list}. \item \tcode{mapped_vertex_range} — not an \tcode{index_vertex_range}, the vertex id is \tcode{hashable_vertex_id}, and vertices are found via \tcode{find_vertex(g, uid)}. Used for graphs whose vertices are stored in associative containers. \end{itemize} + +\phil{ \tcode{integral::storage_type>} is an obscure way to express that the storage type of the \tcode{index_vertex_range} is an integral vs. iterator/mapped type.} + {\small \lstinputlisting{D3130_Container_Interface/src/concepts_vertex_range.hpp} } \subsubsection{Adjacency List Concepts} -The adjacency list concepts combine the vertex and edge concepts. Six concepts are defined, covering three axes: -\begin{itemize} - \item \tcode{adjacency_list} — base concept: \tcode{vertices(g)} returns a \tcode{vertex_range} and \tcode{out_edges(g,u)} returns an \tcode{out_edge_range}. - \item \tcode{index_adjacency_list} — \tcode{adjacency_list} with \tcode{index_vertex_range}. All algorithms currently proposed for the Graph Library use this concept. - \item \tcode{bidirectional_adjacency_list} — \tcode{adjacency_list} that also exposes \tcode{in_edges(g,u)} as an \tcode{in_edge_range} with accessible \tcode{source_id}. - \item \tcode{index_bidirectional_adjacency_list} — \tcode{bidirectional_adjacency_list} with \tcode{index_vertex_range}. - \item \tcode{mapped_adjacency_list} — \tcode{adjacency_list} with \tcode{mapped_vertex_range}. - \item \tcode{mapped_bidirectional_adjacency_list} — \tcode{bidirectional_adjacency_list} with \tcode{mapped_vertex_range}. -\end{itemize} - -A seventh, orthogonal concept describes a graph whose adjacency lists are sorted: -\begin{itemize} - \item \tcode{ordered_vertex_edges} — an \tcode{adjacency_list} in which each vertex's out-edges are ordered by ascending \tcode{target_id}. This is primarily a \emph{semantic} property: the concept can only confirm structurally that \tcode{out_edges(g,u)} is a \tcode{forward_range}, while the ascending-order guarantee is asserted by the graph author. Graphs that store edges in ordered containers (e.g.\ \tcode{set} or \tcode{map} keyed by target id) satisfy it; unordered storage (e.g.\ \tcode{vector} appended in arbitrary order, or \tcode{unordered_set}) generally does not. It is used by algorithms that rely on a linear set-intersection merge, such as triangle counting (see the Algorithms proposal). -\end{itemize} - -The previous interface defined \tcode{basic_*} and \tcode{sourced_*} variants to distinguish edges with or without a source id. -The descriptor design makes this distinction unnecessary: all edge descriptors carry source information, so the \tcode{basic_*} -and \tcode{sourced_*} concept families have been removed. +The adjacency list concepts combine the vertex and edge concepts into six main concepts +covering three axes (index vs.\ mapped storage, unidirectional vs.\ bidirectional), plus +two orthogonal refinements. All algorithms currently proposed for the Graph Library +require \tcode{index\_adjacency\_list}. Figure~\ref{fig:adj_list_concepts} shows the +full refinement hierarchy. + +\tcode{ordered\_vertex\_edges} is a primarily \emph{semantic} concept: it can only +confirm structurally that \tcode{out\_edges(g,u)} is a \tcode{forward\_range}, while the +ascending-\tcode{target\_id} ordering guarantee is asserted by the graph author. Graphs +that store edges in ordered containers (e.g.\ \tcode{set} or \tcode{map} keyed by target +id) satisfy it; unordered storage (e.g.\ \tcode{vector} appended in arbitrary order, or +\tcode{unordered\_set}) generally does not. It is used by algorithms that rely on a +linear set-intersection merge, such as triangle counting (see the Algorithms proposal). + +\begin{figure}[h!] + \centering + \includegraphics[width=\textwidth]{D3130_Container_Interface/src/adjacency_list_concepts.pdf} + \caption{Adjacency list concept refinement hierarchy. Arrows denote refinement + (child concept requires parent). Dashed arrow indicates negation constraint. + All algorithms in this proposal require \tcode{index\_adjacency\_list}.} + \label{fig:adj_list_concepts} +\end{figure} {\small \lstinputlisting{D3130_Container_Interface/src/concepts_adj_list.hpp} } @@ -156,12 +152,6 @@ \subsection{Traits} \hdashline \tcode{has_basic_queries} & concept & \tcode{has_degree \&\& has_find_vertex \&\& has_find_vertex_edge} \\ \tcode{has_full_queries} & concept & \tcode{has_basic_queries \&\& has_contains_edge>} \\ -\hline - \tcode{define_adjacency_matrix : false_type} & struct & Specialize for graph implementation to derive from \tcode{true_type} for edges stored as a square 2-dimensional array. \\ - \tcode{is_adjacency_matrix} & struct & \\ - \tcode{is_adjacency_matrix_v} & type alias & \\ - \tcode{adjacency_matrix} & concept & \\ - \multicolumn{3}{l}{\emph{The adjacency\_matrix trait family is not yet in the reference implementation.}} \\ \hline \end{tabular}} \caption{Graph Container Interface Type Traits} @@ -228,179 +218,11 @@ \subsection{Classes and Structs} \emph{While we believe the use of concepts is appropriate for graphs as a range-of-ranges, we are marking them as "For exposition only" until we have consensus of whether they belong in the standard or not.} -\subsubsection{Data Structs} - -\tcode{vertex_data}, \tcode{edge_data} and \tcode{neighbor_data} are aggregates used by -views for structured-binding iteration. They are defined with multiple specializations -that void-out unused members so that the structured binding is compact. - -\tcode{vertex_data} has the following members depending on the template -parameters (a \tcode{void} parameter omits the corresponding member): - -\begin{table}[h!] -\begin{center} -{\begin{tabular}{l l L{7.5cm}} -\hline - \textbf{Members present} & \textbf{Specialization} & \textbf{Typical use} \\ -\hline - \tcode{id, vertex, value} & \tcode{} & Full vertexlist with descriptor and value \\ - \tcode{id, vertex} & \tcode{} & Vertexlist with descriptor, no value \\ - \tcode{id, value} & \tcode{} & Vertexlist with value, no descriptor \\ - \tcode{id} & \tcode{} & ID-only vertexlist \\ - \tcode{vertex, value} & \tcode{} & Descriptor-based, no id \\ - \tcode{vertex} & \tcode{} & Descriptor only \\ - \tcode{value} & \tcode{} & Value only \\ - (empty) & \tcode{} & No members \\ -\hline -\hline -\end{tabular}} -\caption{\tcode{vertex\_data} Specializations} -\label{tab:vertex_data} -\end{center} -\end{table} - -\tcode{edge_data} has the following members. The \tcode{Sourced} -boolean controls whether \tcode{source_id} is included. A \tcode{void} VId or EV omits -the corresponding member; a \tcode{void} E omits the edge descriptor member. - -\begin{table}[h!] -\begin{center} -{\begin{tabular}{l l L{6.5cm}} -\hline - \textbf{Members present} & \textbf{Specialization} & \textbf{Typical use} \\ -\hline - \tcode{source\_id, target\_id, edge, value} & \tcode{} & Sourced incidence with descriptor and value \\ - \tcode{source\_id, target\_id, edge} & \tcode{} & Sourced incidence with descriptor \\ - \tcode{source\_id, target\_id, value} & \tcode{} & Sourced incidence with value \\ - \tcode{source\_id, target\_id} & \tcode{} & Sourced incidence, IDs only \\ - \tcode{target\_id, edge, value} & \tcode{} & Unsourced incidence with descriptor and value \\ - \tcode{target\_id, edge} & \tcode{} & Unsourced incidence with descriptor \\ - \tcode{target\_id, value} & \tcode{} & Unsourced incidence with value \\ - \tcode{target\_id} & \tcode{} & Target ID only \\ -\hline -\hline -\end{tabular}} -\caption{\tcode{edge\_data} Specializations (VId present)} -\label{tab:edge_data} -\end{center} -\end{table} - -\tcode{neighbor_data} is analogous to \tcode{edge_data} but replaces -the edge descriptor with a target vertex descriptor. It is used by adjacency (neighbor) -views. - -The following helper type aliases simplify the most common structured-binding patterns: - -\begin{table}[h!] -\begin{center} -{\begin{tabular}{l L{8cm}} -\hline - \textbf{Alias} & \textbf{Definition} \\ -\hline - \tcode{copyable_vertex_t} & \tcode{vertex_data} --- \texttt{\{id, value\}} \\ - \tcode{copyable_edge_t} & \tcode{edge_data} --- \texttt{\{source\_id, target\_id, value\}} \\ - \tcode{copyable_neighbor_t} & \tcode{neighbor_data} --- \texttt{\{source\_id, target\_id, value\}} \\ -\hline -\hline -\end{tabular}} -\caption{Helper type aliases for common structured-binding patterns} -\label{tab:copyable_types} -\end{center} -\end{table} - -\subsection{Value Function Concepts} - -\tcode{vertex_value_function} and \tcode{edge_value_function} define the required -interface for callables passed to views and algorithms to extract per-vertex or per-edge -scalar values (e.g.\ a weight or a label). Both concepts use the two-argument -\tcode{f(const G\&, descriptor)} convention so that stateless lambdas may be captured -into \tcode{std::views} pipelines without holding a reference to the graph. - -\begin{lstlisting} -template -concept vertex_value_function = - invocable && - (!is_void_v>); - -template -concept edge_value_function = - invocable && - (!is_void_v>); -\end{lstlisting} - -\tcode{basic_edge_weight_function} (defined in the algorithms proposal) refines -\tcode{edge_value_function} with the additional requirement that the return type is -arithmetic. - -\subsection{Vertex Property Map} - -Algorithms that maintain per-vertex state (visited flags, distances, component labels, -etc.) need a container indexed by vertex ID. For index-based graphs a \tcode{vector} is -natural; for mapped (key-based) graphs an \tcode{unordered_map} is required. -\tcode{vertex_property_map} abstracts over this difference. - -\begin{lstlisting} -template -using vertex_property_map = - conditional_t, - vector, - unordered_map, T>>; -\end{lstlisting} - -Four helper functions complete the interface: - -\begin{table}[h!] -\begin{center} -\resizebox{\textwidth}{!} -{\begin{tabular}{l L{9cm}} -\hline - \textbf{Function} & \textbf{Description} \\ -\hline - \tcode{make_vertex_property_map(g, init)} & Eager factory: creates a map with every vertex pre-populated to \tcode{init}. O(V). \\ - \tcode{make_vertex_property_map(g)} & Lazy factory: creates an empty map with capacity reserved. O(V) for index, O(1) for mapped. \\ - \tcode{vertex_property_map_contains(m, uid)} & Returns \tcode{true} if \tcode{uid} has an entry (\tcode{uid < size(m)} for \tcode{vector}; \tcode{m.contains(uid)} for \tcode{unordered\_map}). \\ - \tcode{vertex_property_map_get(m, uid, dflt)} & Returns the stored value or \tcode{dflt} if absent. Does not insert. \\ -\hline -\hline -\end{tabular}} -\caption{Vertex Property Map Functions} -\label{tab:vpm_func} -\end{center} -\end{table} - -Two further utilities let algorithms accept a caller-supplied property map without -caring which underlying container backs it: - -\begin{lstlisting} -// Per-vertex value type of a property-map container: -// vector yields T (value\_type); unordered\_map yields V (mapped\_type) -template -using vertex_property_map_value_t = /* see prose */; - -// A container usable as a per-vertex property map for graph G: -// it can be subscripted by the graph's vertex id. -template -concept vertex_property_map_for = - requires(M& m, const vertex_id_t& uid) { - { m[uid] } -> convertible_to>; - }; -\end{lstlisting} - -\tcode{vertex_property_map_value_t} extracts the stored value type from -either container shape (the \tcode{mapped_type} of an \tcode{unordered_map}, or the -\tcode{value_type} of a \tcode{vector}). \tcode{vertex_property_map_for} is the -precise constraint for algorithm parameters such as \emph{Distances} or -\emph{Predecessors}: it requires only that \tcode{m[uid]} is valid for the graph's -\tcode{vertex_id_t}, since algorithms subscript such maps by vertex id rather than -iterating them as a range. Both \tcode{vector} (index graphs) and -\tcode{unordered_map,T>} (mapped graphs) satisfy it. - \subsection{Functions} Tables \ref{tab:graph_func}, \ref{tab:vertex_func} and \ref{tab:edge_func} summarize the primitive functions in the Graph Container Interface. used to access an adjacency graph, no matter its internal design and organization. Thus, it is designed -to be able to reflect all forms of adjacency graphs including a vector of lists, CSR-based graph and adjacency matrix. - +to be able to reflect all forms of adjacency graphs such as a vector of lists, CSR-based graph and adjacency matrix. \begin{table}[h!] \begin{center} @@ -472,6 +294,8 @@ \subsection{Functions} \end{center} \end{table} +\phil{The same edge type is required for both incoming and outgoing edge ranges. Consider enabling different edge types.} + The default implementation for the \tcode{out_degree} and \tcode{in_degree} functions assumes that \tcode{out_edge_range_t} or \tcode{in_edge_range_t} is a sized range to have constant complexity. If the underlying container has a non-linear \tcode{size(R)} function, the degree functions will also be non-linear. This is expected to be an uncommon case. @@ -686,6 +510,229 @@ \subsection{Unipartite, Bipartite and Multipartite Graph Representation} \tcode{out_edges(g,uid,pid)} and \tcode{out_edges(g,u,pid)} filter the edges where the target is in the partition \tcode{pid} passed. This isn't needed for bipartite graphs. These partition-filtered \tcode{out_edges} overloads are not yet in the reference implementation. +\subsection{Utility Types and Functions} + +\subsubsection{Vertex, Edge and Neighbor Data} +\tcode{vertex_data}, \tcode{edge_data} and \tcode{neighbor_data} are used to provide structured +definitions of the core data model associated with vertices, edges and neighbors. They're +useful aggregates that show up in different contexts including for structured-binding iteration, +and binding external data for use in graph construction. + +\paragraph{\tcode{struct vertex_data}}\label{vertex-view}\mbox{} \\ +\tcode{vertex_data} is used to define or return vertex information. 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_data} +has two members \tcode{\{id_type id; vertex_type vertex;\}} and \tcode{value_type} is \tcode{void}. + +\tcode{vertex_data} has the following members depending on the template +parameters (a \tcode{void} parameter omits the corresponding member): + +\begin{table}[h!] +\begin{center} +{\begin{tabular}{l l L{7.5cm}} +\hline + \textbf{Members present} & \textbf{Specialization} & \textbf{Typical use} \\ +\hline + \tcode{id, vertex, value} & \tcode{} & Full vertexlist with descriptor and value \\ + \tcode{id, vertex} & \tcode{} & Vertexlist with descriptor, no value \\ + \tcode{id, value} & \tcode{} & Vertexlist with value, no descriptor \\ + \tcode{id} & \tcode{} & ID-only vertexlist \\ + \tcode{vertex, value} & \tcode{} & Descriptor-based, no id \\ + \tcode{vertex} & \tcode{} & Descriptor only \\ + \tcode{value} & \tcode{} & Value only \\ + %%(empty) & \tcode{} & No members \\ +\hline +\hline +\end{tabular}} +\caption{\tcode{vertex\_data} Specializations} +\label{tab:vertex_data} +\end{center} +\end{table} + +\paragraph{\tcode{struct edge_data}}\label{edge-view}\mbox{} \\ + +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} +} + +\tcode{edge_data} has the following members. The \tcode{Sourced} +boolean controls whether \tcode{source_id} is included. A \tcode{void} VId or EV omits +the corresponding member; a \tcode{void} E omits the edge descriptor member. + +\begin{table}[h!] +\begin{center} +{\begin{tabular}{l l L{6.5cm}} +\hline + \textbf{Members present} & \textbf{Specialization} & \textbf{Typical use} \\ +\hline + \tcode{source\_id, target\_id, edge, value} & \tcode{} & Sourced incidence with descriptor and value \\ + \tcode{source\_id, target\_id, edge} & \tcode{} & Sourced incidence with descriptor \\ + \tcode{source\_id, target\_id, value} & \tcode{} & Sourced incidence with value \\ + \tcode{source\_id, target\_id} & \tcode{} & Sourced incidence, IDs only \\ + \tcode{target\_id, edge, value} & \tcode{} & Unsourced incidence with descriptor and value \\ + \tcode{target\_id, edge} & \tcode{} & Unsourced incidence with descriptor \\ + \tcode{target\_id, value} & \tcode{} & Unsourced incidence with value \\ + \tcode{target\_id} & \tcode{} & Target ID only \\ +\hline +\hline +\end{tabular}} +\caption{\tcode{edge\_data} Specializations (VId present)} +\label{tab:edge_data} +\end{center} +\end{table} + +\paragraph{\tcode{struct neighbor_data}}\label{neighbor-view}\mbox{} \\ + +\tcode{neighbor_data} is used to return information for a neighbor vertex, through an edge. 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} +} + +\tcode{neighbor_data} is analogous to \tcode{edge_data} but replaces +the edge descriptor with a target vertex descriptor. It is used by adjacency (neighbor) +views. + +\begin{table}[h!] +\begin{center} +{\begin{tabular}{l l L{6.5cm}} +\hline + \textbf{Members present} & \textbf{Specialization} & \textbf{Typical use} \\ +\hline + \tcode{source\_id, target\_id, target, value} & \tcode{} & Sourced neighbor descriptor and value \\ + \tcode{source\_id, target\_id, target} & \tcode{} & Sourced neighbor descriptor \\ + \tcode{source\_id, target\_id, value} & \tcode{} & Sourced neighbor with value \\ + \tcode{source\_id, target\_id} & \tcode{} & Sourced neighbor, IDs only \\ + \tcode{target\_id, target, value} & \tcode{} & Unsourced neighbor descriptor and value \\ + \tcode{target\_id, target} & \tcode{} & Unsourced neighbor descriptor \\ + \tcode{target\_id, value} & \tcode{} & Unsourced neighbor with value \\ + \tcode{target\_id} & \tcode{} & Unsourced neighbor, IDs only \\ +\hline +\hline +\end{tabular}} +\caption{\tcode{neighbor\_data} Specializations (VId present)} +\label{tab:neighbor_data} +\end{center} +\end{table} + +\paragraph{Copyable vertex, edge, and neighbor types} + +The following helper type aliases simplify the most common structured-binding patterns: + +\begin{table}[h!] +\begin{center} +{\begin{tabular}{l L{8cm}} +\hline + \textbf{Alias} & \textbf{Definition} \\ +\hline + \tcode{copyable_vertex_t} & \tcode{vertex_data} --- \texttt{\{id, value\}} \\ + \tcode{copyable_edge_t} & \tcode{edge_data} --- \texttt{\{source\_id, target\_id, value\}} \\ + \tcode{copyable_neighbor_t} & \tcode{neighbor_data} --- \texttt{\{source\_id, target\_id, value\}} \\ +\hline +\hline +\end{tabular}} +\caption{Helper type aliases for common structured-binding patterns} +\label{tab:copyable_types} +\end{center} +\end{table} + +\subsubsection{Value Function Concepts} + +\tcode{vertex_value_function} and \tcode{edge_value_function} define the required +interface for callables passed to views and algorithms to extract per-vertex or per-edge +scalar values (e.g.\ a weight or a label). Both concepts use the two-argument +\tcode{f(const G\&, descriptor)} convention so that stateless lambdas may be captured +into \tcode{std::views} pipelines without holding a reference to the graph. + +\begin{lstlisting} +template +concept vertex_value_function = + invocable && + (!is_void_v>); + +template +concept edge_value_function = + invocable && + (!is_void_v>); +\end{lstlisting} + +\tcode{edge_weight_function} (defined in the algorithms proposal) refines +\tcode{edge_value_function} with the additional requirement that the return type is +arithmetic. + +\subsubsection{Vertex Property Map} + +Algorithms that maintain per-vertex state (visited flags, distances, component labels, +etc.) need a container indexed by vertex ID. For index-based graphs a \tcode{vector} is +natural; for mapped (key-based) graphs an \tcode{unordered_map} is required. +\tcode{vertex_property_map} abstracts over this difference. + +\begin{lstlisting} +template +using vertex_property_map = + conditional_t, + vector, + unordered_map, T>>; +\end{lstlisting} + +Four helper functions complete the interface: + +\begin{table}[h!] +\begin{center} +\resizebox{\textwidth}{!} +{\begin{tabular}{l L{9cm}} +\hline + \textbf{Function} & \textbf{Description} \\ +\hline + \tcode{make_vertex_property_map(g, init)} & Eager factory: creates a map with every vertex pre-populated to \tcode{init}. O(V). \\ + \tcode{make_vertex_property_map(g)} & Lazy factory: creates an empty map with capacity reserved. O(V) for index, O(1) for mapped. \\ + \tcode{vertex_property_map_contains(m, uid)} & Returns \tcode{true} if \tcode{uid} has an entry (\tcode{uid < size(m)} for \tcode{vector}; \tcode{m.contains(uid)} for \tcode{unordered\_map}). \\ + \tcode{vertex_property_map_get(m, uid, dflt)} & Returns the stored value or \tcode{dflt} if absent. Does not insert. \\ +\hline +\hline +\end{tabular}} +\caption{Vertex Property Map Functions} +\label{tab:vpm_func} +\end{center} +\end{table} + +Two further utilities let algorithms accept a caller-supplied property map without +caring which underlying container backs it: + +\begin{lstlisting} +// Per-vertex value type of a property-map container: +// vector yields T (value\_type); unordered\_map yields V (mapped\_type) +template +using vertex_property_map_value_t = /* see prose */; + +// A container usable as a per-vertex property map for graph G: +// it can be subscripted by the graph's vertex id. +template +concept vertex_property_map_for = + requires(M& m, const vertex_id_t& uid) { + { m[uid] } -> convertible_to>; + }; +\end{lstlisting} + +\tcode{vertex_property_map_value_t} extracts the stored value type from +either container shape (the \tcode{mapped_type} of an \tcode{unordered_map}, or the +\tcode{value_type} of a \tcode{vector}). \tcode{vertex_property_map_for} is the +precise constraint for algorithm parameters such as \emph{Distances} or +\emph{Predecessors}: it requires only that \tcode{m[uid]} is valid for the graph's +\tcode{vertex_id_t}, since algorithms subscript such maps by vertex id rather than +iterating them as a range. Both \tcode{vector} (index graphs) and +\tcode{unordered_map,T>} (mapped graphs) satisfy it. + + \section{Edgelist Interface} An edgelist is a range of values where we can get the source\_id and target\_id, and an optional edge\_value. It is similar to edges in an adjacency list or edges in the incidence view, but is a distinct range of values that are separate from the others. diff --git a/D3130_Container_Interface/tex/revision.tex b/D3130_Container_Interface/tex/revision.tex index d301cd7..39f10fe 100644 --- a/D3130_Container_Interface/tex/revision.tex +++ b/D3130_Container_Interface/tex/revision.tex @@ -74,9 +74,10 @@ \subsection*{\paperno r3} \subsection*{\paperno r4} \begin{itemize} - \item \textbf{Associative-container support}: vertex and edge containers may now be - associative (e.g.\ \tcode{std::map}, \tcode{std::unordered_map}), enabling - graphs with non-integer or string vertex ids. Related changes: + \item \textbf{Mapped vertices and edges}: vertex container may now be associative (e.g.\ \tcode{std::map}, + \tcode{std::unordered_map}), enabling adjacency lists with non-integral vertex ids. Likewise, + an edge container/range may also be associative or include a key-only container such as \tcode{std::set}. + Related changes: \begin{itemize} \item New concept \tcode{mapped_vertex_range} alongside \tcode{index_vertex_range}. \item New \textit{raw-vertex-id-type} exposition-only type alias. @@ -114,7 +115,8 @@ \subsection*{\paperno r4} \tcode{edge_reference_t}. \item New concepts: \tcode{vertex_value_function} and \tcode{edge_value_function} (value-function concepts for views and algorithms). - \item Edgelist namespace renamed from \tcode{std::graph::edgelist} to \tcode{std::graph::edge_list}. + \item Edgelist namespace renamed from \tcode{std::graph::edgelist} to \tcode{std::graph::edge_list} + to distinguish it from the edgelist view. Adjacency list symbols now formally reside in \tcode{std::graph::adj_list} and are re-exported to \tcode{std::graph}; the two sub-namespaces are peers. \item \tcode{vertex_data}, \tcode{edge_data} and \tcode{neighbor_data} aggregates From 77b8ece3b279f9e578c7cfb70b48fdd28ad1bf4e Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Sun, 28 Jun 2026 16:37:00 -0400 Subject: [PATCH 08/10] Update revisions for D3130_Container_Interface --- D3129_Views/tex/revision.tex | 5 +++++ D3129_Views/tex/views.tex | 1 + D3130_Container_Interface/tex/container_interface.tex | 6 +++--- D3130_Container_Interface/tex/revision.tex | 8 +++++--- 4 files changed, 14 insertions(+), 6 deletions(-) diff --git a/D3129_Views/tex/revision.tex b/D3129_Views/tex/revision.tex index 2e90528..49cf526 100644 --- a/D3129_Views/tex/revision.tex +++ b/D3129_Views/tex/revision.tex @@ -57,4 +57,9 @@ \subsection*{\paperno r3} \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 \href{https://www.wg21.link/P3130}{P3130 Graph Container Interface}. + \item Moved \tcode{vertex_data}, \tcode{edge_data}, and \tcode{neighbor_data} to + \href{https://www.wg21.link/P3130}{P3130 Graph Container Interface}. + \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 \href{https://www.wg21.link/P3130}{P3130 Graph Container Interface}. \end{itemize} diff --git a/D3129_Views/tex/views.tex b/D3129_Views/tex/views.tex index fb8eacf..6927202 100644 --- a/D3129_Views/tex/views.tex +++ b/D3129_Views/tex/views.tex @@ -70,6 +70,7 @@ \section{Data Structs (Return Types)}\label{sec:data-structs} See the Utility Types and Functions in \href{https://www.wg21.link/P3130}{P3130 Graph Container Interface} for more details about the definition and use of the vertex, edge and neighbor data types. + \section{Graph Views} \subsection{vertexlist Views} diff --git a/D3130_Container_Interface/tex/container_interface.tex b/D3130_Container_Interface/tex/container_interface.tex index ce9f49e..78599d3 100644 --- a/D3130_Container_Interface/tex/container_interface.tex +++ b/D3130_Container_Interface/tex/container_interface.tex @@ -523,7 +523,7 @@ \subsubsection{Vertex, Edge and Neighbor Data} and \tcode{value} is the result of the value function, if provided. {\small - \lstinputlisting{D3129_Views/src/vertex_data.hpp} + \lstinputlisting{D3130_Container_Interface/src/vertex_data.hpp} } Specializations are defined with \tcode{V=void} or \tcode{VV=void} to suppress the existence of their associated member variables, @@ -560,7 +560,7 @@ \subsubsection{Vertex, Edge and Neighbor Data} 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} + \lstinputlisting{D3130_Container_Interface/src/edge_data.hpp} } \tcode{edge_data} has the following members. The \tcode{Sourced} @@ -595,7 +595,7 @@ \subsubsection{Vertex, Edge and Neighbor Data} 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} + \lstinputlisting{D3130_Container_Interface/src/neighbor_data.hpp} } \tcode{neighbor_data} is analogous to \tcode{edge_data} but replaces diff --git a/D3130_Container_Interface/tex/revision.tex b/D3130_Container_Interface/tex/revision.tex index 39f10fe..e5a095a 100644 --- a/D3130_Container_Interface/tex/revision.tex +++ b/D3130_Container_Interface/tex/revision.tex @@ -75,10 +75,10 @@ \subsection*{\paperno r4} \begin{itemize} \item \textbf{Mapped vertices and edges}: vertex container may now be associative (e.g.\ \tcode{std::map}, - \tcode{std::unordered_map}), enabling adjacency lists with non-integral vertex ids. Likewise, - an edge container/range may also be associative or include a key-only container such as \tcode{std::set}. - Related changes: + \tcode{std::unordered_map}). Likewise, an edge container/range may also be associative or include a + key-only container such as \tcode{std::set}. Related changes: \begin{itemize} + \item Support for non-integral vertex ids. \item New concept \tcode{mapped_vertex_range} alongside \tcode{index_vertex_range}. \item New \textit{raw-vertex-id-type} exposition-only type alias. \item New \tcode{vertex_property_map} utility type alias; @@ -129,4 +129,6 @@ \subsection*{\paperno r4} paper now states only the normative recognition patterns (random-access / associative vertex patterns and the integral/\tcode{pair}/\tcode{tuple} edge element patterns), with the concrete container catalog, trade-off table and worked examples moved to that paper. + \item Moved \tcode{vertex_data}, \tcode{edge_data}, and \tcode{neighbor_data} descriptions from + \href{https://www.wg21.link/P3129}{P3129 Views}. \end{itemize} From 9cf13f13e4e8fe19c0580f12821f123807280948 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Mon, 6 Jul 2026 11:27:33 -0400 Subject: [PATCH 09/10] Publish P3126..P3130 General improvements 1. Support for mapped vertices & edges (e.g. sparse vertices) 2. Non-integral vertex descriptors 3. Upgrade to C++23 Ran out of time to update P3131 in time for SG19 this Thursday Additional improvements needed for vertex_descriptor --- D3126_Overview/tex/config.tex | 2 +- D3126_Overview/tex/overview.tex | 7 +- D3126_Overview/tex/revision.tex | 1 + D3127_Terminology/tex/config.tex | 4 +- D3128_Algorithms/src/Makefile | 2 +- D3128_Algorithms/tex/config.tex | 4 +- D3128_Algorithms/tex/revision.tex | 1 + D3129_Views/tex/config.tex | 6 +- D3129_Views/tex/revision.tex | 4 +- .../src/concepts_adj_list.hpp | 2 +- D3130_Container_Interface/tex/config.tex | 4 +- .../tex/container_interface.tex | 76 +++++++++---------- D3130_Container_Interface/tex/revision.tex | 4 +- D3131_Containers/tex/containers.tex | 3 + tex/P1709-preamble.tex | 2 +- tex/config.tex | 7 +- tex/title.tex | 2 +- 17 files changed, 68 insertions(+), 63 deletions(-) diff --git a/D3126_Overview/tex/config.tex b/D3126_Overview/tex/config.tex index 39297e2..e154ae3 100644 --- a/D3126_Overview/tex/config.tex +++ b/D3126_Overview/tex/config.tex @@ -1,7 +1,7 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\paperno}{D3126} +\newcommand{\paperno}{P3126} \newcommand{\docno}{\paperno r4} \newcommand{\docname}{Graph Library: Overview} \newcommand{\prevdocno}{P3126r3} diff --git a/D3126_Overview/tex/overview.tex b/D3126_Overview/tex/overview.tex index f9c29ce..f49fdcf 100644 --- a/D3126_Overview/tex/overview.tex +++ b/D3126_Overview/tex/overview.tex @@ -206,7 +206,7 @@ \section{Prior Art} \medskip \textbf{NWGraph} (\cite{REF_nwgraph_library} and \cite{REF_nwgraph_paper}) was published in 2022 -by Lumsdaine et al, bringing additional experience gained since creating boost::graph, to create a modern graph library using C++20 for its implementation +by Lumsdaine et al, bringing additional experience gained since creating boost::graph, to create a modern graph library using C++23 for its implementation that was more accessible to the average developer. % with the latest algorithms. While NWGraph made important strides to introduce the idea of an adjacency list as a range-of-ranges and implemented many important algorithms, @@ -255,7 +255,7 @@ \section{Alternatives} they do not meet the needs or expectations of modern C++ development. We are currently unaware of any existing graph -library that meets the same requirements and uses concepts and ranges from C++20. +library that meets the same requirements and uses concepts and ranges from C++23. \phil{Comment on other graph libraries in github} @@ -270,8 +270,7 @@ \section{Freestanding} exception. \section{Language Requirements} -The library targets C++23 as its baseline. \tcode{std::expected} from C++23 are used by the topological sort safe -view factories (\tcode{vertices_topological_sort_safe} and \tcode{edges_topological_sort_safe}). +The library targets C++23 as its baseline. The reference implementation provides backward compatibility to C++20 via an external \tcode{expected} library (e.g., \tcode{tl::expected}). Switching it to require C++23 may limit those who can use it, so care will be diff --git a/D3126_Overview/tex/revision.tex b/D3126_Overview/tex/revision.tex index 30e5a1f..2939522 100644 --- a/D3126_Overview/tex/revision.tex +++ b/D3126_Overview/tex/revision.tex @@ -43,6 +43,7 @@ \subsection*{\paperno r3} \subsection*{\paperno r4} Update the wording to reflect the current status of the proposal along with minor corrections. \begin{itemize} + \item Changed C++ version requirements from C++20 to C++23 throughout all documents. \item Sparse vertex ids and bi-directional graphs are now supported and are no longer future work. \item Remove completed items from the Issues Status section. \end{itemize} diff --git a/D3127_Terminology/tex/config.tex b/D3127_Terminology/tex/config.tex index 9c9d30b..8da746b 100644 --- a/D3127_Terminology/tex/config.tex +++ b/D3127_Terminology/tex/config.tex @@ -1,10 +1,10 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\paperno}{D3127} +\newcommand{\paperno}{P3127} \newcommand{\docno}{\paperno r2} \newcommand{\docname}{Graph Library: Background and Terminology} -\newcommand{\prevdocno}{P3127r0} +\newcommand{\prevdocno}{P3127r1} \newcommand{\cppver}{202302L} %% Release date diff --git a/D3128_Algorithms/src/Makefile b/D3128_Algorithms/src/Makefile index 6f947be..c86ce69 100644 --- a/D3128_Algorithms/src/Makefile +++ b/D3128_Algorithms/src/Makefile @@ -5,7 +5,7 @@ CXX := g++-11 default: - $(CXX) -c -std=c++20 -fconcepts-diagnostics-depth=4 prototypes.cpp + $(CXX) -c -std=c++23 -fconcepts-diagnostics-depth=4 prototypes.cpp clean: /bin/rm -f prototypes.o diff --git a/D3128_Algorithms/tex/config.tex b/D3128_Algorithms/tex/config.tex index 2587f8e..193d7b5 100644 --- a/D3128_Algorithms/tex/config.tex +++ b/D3128_Algorithms/tex/config.tex @@ -1,10 +1,10 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\paperno}{D3128} +\newcommand{\paperno}{P3128} \newcommand{\docno}{\paperno r4} \newcommand{\docname}{Graph Library: Algorithms} -\newcommand{\prevdocno}{P3128r2} +\newcommand{\prevdocno}{P3128r3} \newcommand{\cppver}{202302L} %% Release date diff --git a/D3128_Algorithms/tex/revision.tex b/D3128_Algorithms/tex/revision.tex index 8dd30c0..f088639 100644 --- a/D3128_Algorithms/tex/revision.tex +++ b/D3128_Algorithms/tex/revision.tex @@ -53,6 +53,7 @@ \subsection*{\paperno r3} \subsection*{\paperno r4} \begin{itemize} + \item Changed C++ version requirements from C++20 to C++23 throughout all documents. \item Adopt value-based descriptor design throughout: \tcode{vertex_t} and \tcode{edge_t} value types replace the former \tcode{vertex_reference_t} and \tcode{edge_reference_t}. Also added views \tcode{vertex_descriptor_view_t} and \tcode{edge_descriptor_view_t} diff --git a/D3129_Views/tex/config.tex b/D3129_Views/tex/config.tex index df3132b..4f5cff5 100644 --- a/D3129_Views/tex/config.tex +++ b/D3129_Views/tex/config.tex @@ -1,10 +1,10 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\paperno}{D3129} -\newcommand{\docno}{\paperno r3} +\newcommand{\paperno}{P3129} +\newcommand{\docno}{\paperno r2} \newcommand{\docname}{Graph Library: Views} -\newcommand{\prevdocno}{P3129r2} +\newcommand{\prevdocno}{P3129r1} \newcommand{\cppver}{202302L} %% Release date diff --git a/D3129_Views/tex/revision.tex b/D3129_Views/tex/revision.tex index 49cf526..280e943 100644 --- a/D3129_Views/tex/revision.tex +++ b/D3129_Views/tex/revision.tex @@ -21,7 +21,7 @@ \subsection*{\paperno r1} \item Rename \tcode{descriptor} structs to \tcode{info} structs in preparation for new BGL-like descriptors. \end{itemize} -\subsection*{\paperno r2} +\subsection*{\paperno r1b} \begin{itemize} \item Replace the use of \textit{id} and \textit{reference} in view functions with the \tcode{vertex_t} and \tcode{edge_t} descriptors, leading to a simpler interace. @@ -32,7 +32,7 @@ \subsection*{\paperno r2} vertex and edge descriptors. \end{itemize} -\subsection*{\paperno r3} +\subsection*{\paperno r2} \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, to align their names to represent diff --git a/D3130_Container_Interface/src/concepts_adj_list.hpp b/D3130_Container_Interface/src/concepts_adj_list.hpp index 124c197..5824c92 100644 --- a/D3130_Container_Interface/src/concepts_adj_list.hpp +++ b/D3130_Container_Interface/src/concepts_adj_list.hpp @@ -35,7 +35,7 @@ concept mapped_bidirectional_adjacency_list = template concept adjacency_matrix = index_adjacency_list && requires(G& g, vertex_t u, vertex_t v) { - find_out_edge(g, u, v); + find_out_edge(g, u, v) -> std::forward_iterator; { contains_out_edge(g, u, v) } -> std::convertible_to; }; diff --git a/D3130_Container_Interface/tex/config.tex b/D3130_Container_Interface/tex/config.tex index 6dfde40..4205ce2 100644 --- a/D3130_Container_Interface/tex/config.tex +++ b/D3130_Container_Interface/tex/config.tex @@ -1,10 +1,10 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\paperno}{D3130} +\newcommand{\paperno}{P3130} \newcommand{\docno}{\paperno r4} \newcommand{\docname}{Graph Library: Graph Container Interface} -\newcommand{\prevdocno}{P3130r2} +\newcommand{\prevdocno}{P3130r3} \newcommand{\cppver}{202302L} %% Release date diff --git a/D3130_Container_Interface/tex/container_interface.tex b/D3130_Container_Interface/tex/container_interface.tex index 78599d3..99fd755 100644 --- a/D3130_Container_Interface/tex/container_interface.tex +++ b/D3130_Container_Interface/tex/container_interface.tex @@ -143,7 +143,7 @@ \subsection{Traits} \hline \tcode{has_degree} & concept & Is the \tcode{out_degree(g,u)} function available? \\ \tcode{has_find_vertex} & concept & Are the \tcode{find_vertex(g,\_)} functions available? \\ - \tcode{has_find_vertex_edge} & concept & Are the \tcode{find_out_edge(g,\_)} functions available?\\ + \tcode{has_find_out_edge} & concept & Are the \tcode{find_out_edge(g,\_)} functions available?\\ \tcode{has_contains_edge} & concept & Is the \tcode{contains_out_edge(g,uid,vid)} function available?\\ \hdashline \tcode{has_in_degree} & concept & Is the \tcode{in_degree(g,u)} function available? \\ @@ -269,20 +269,20 @@ \subsection{Functions} & & & Override to define a different \\ & & & \tcode{vertex_id_t} type (e.g. int32\_t). \\ \tcode{vertex_value(g,u)} & \tcode{vertex_value_t} & constant & n/a, optional \\ - \tcode{vertex_value(g,uid)} & \tcode{vertex_value_t} & constant & \tcode{vertex_value(g,*find_vertex(g,uid))}, \\ - & & & optional \\ + %\tcode{vertex_value(g,uid)} & \tcode{vertex_value_t} & constant & \tcode{vertex_value(g,*find_vertex(g,uid))}, \\ + % & & & optional \\ \tcode{out_edges(g,u)} & \tcode{out_edge_range_t} & constant & \tcode{u} if \tcode{forward_range>}, n/a otherwise \\ - \tcode{out_edges(g,uid)} & \tcode{out_edge_range_t} & constant & \tcode{out\_edges(g,*find\_vertex(g,uid))} \\ + %\tcode{out_edges(g,uid)} & \tcode{out_edge_range_t} & constant & \tcode{out\_edges(g,*find\_vertex(g,uid))} \\ \tcode{out_degree(g,u)} & \tcode{integral} & constant & \tcode{size(out\_edges(g,u))} if \tcode{sized_range>} \\ - \tcode{out_degree(g,uid)} & \tcode{integral} & constant & \tcode{size(out\_edges(g,uid))} if \tcode{sized_range>} \\ - (\tcode{edges(g,u), edges(g,uid)} & & & aliases for \tcode{out\_edges}) \\ - (\tcode{degree(g,u), degree(g,uid)} & & & aliases for \tcode{out\_degree}) \\ - (\tcode{num\_edges(g,u), num\_edges(g,uid)} & & & aliases for \tcode{out\_degree}) \\ + %\tcode{out_degree(g,uid)} & \tcode{integral} & constant & \tcode{size(out\_edges(g,uid))} if \tcode{sized_range>} \\ + %(\tcode{edges(g,u), edges(g,uid)} & & & aliases for \tcode{out\_edges}) \\ + %(\tcode{degree(g,u), degree(g,uid)} & & & aliases for \tcode{out\_degree}) \\ + %(\tcode{num\_edges(g,u), num\_edges(g,uid)} & & & aliases for \tcode{out\_degree}) \\ \hdashline \tcode{in_edges(g,u)} & \tcode{in_edge_range_t} & constant & n/a (requires bidirectional graph) \\ - \tcode{in_edges(g,uid)} & \tcode{in_edge_range_t} & constant & \tcode{in\_edges(g,*find\_vertex(g,uid))} \\ + %\tcode{in_edges(g,uid)} & \tcode{in_edge_range_t} & constant & \tcode{in\_edges(g,*find\_vertex(g,uid))} \\ \tcode{in_degree(g,u)} & \tcode{integral} & constant & \tcode{size(in\_edges(g,u))} if \tcode{sized_range>} \\ - \tcode{in_degree(g,uid)} & \tcode{integral} & constant & \tcode{size(in\_edges(g,uid))} if \tcode{sized_range>} \\ + %\tcode{in_degree(g,uid)} & \tcode{integral} & constant & \tcode{size(in\_edges(g,uid))} if \tcode{sized_range>} \\ \hdashline \tcode{partition_id(g,u)} & \tcode{partition_id_t} & constant & \tcode{0} (partition 0) \\ \tcode{partition_id(g,uid)} & \tcode{partition_id_t} & constant & \tcode{partition_id(g,*find_vertex(g,uid))} \\ @@ -318,27 +318,27 @@ \subsection{Functions} & & & \hspace{3mm}\tcode{\&\& integral} \\ \tcode{edge_value(g,uv)} & \tcode{edge_value_t} & constant & \tcode{uv} if \tcode{forward_range>}, \\ & & & n/a otherwise, optional \\ - \tcode{find_out_edge(g,u,vid)} & \tcode{out_edge_t} & linear & \tcode{find(out\_edges(g,u),} \\ - & & & \tcode{[](uv) \{ return target\_id(g,uv)==vid; \})} \\ - \tcode{find_out_edge(g,uid,vid)} & \tcode{out_edge_t} & linear & \tcode{find\_out\_edge(} \\ - & & & \hspace{8mm}\tcode{g, *find\_vertex(g,uid), vid)} \\ + \tcode{find_out_edge(g,u,v)} & \tcode{out_edge_t} & linear & \tcode{find(out\_edges(g,u),} \\ + & & & \tcode{[](uv) \{ return target\_id(g,uv)==vertex\_id(v); \})} \\ + %\tcode{find_out_edge(g,uid,vid)} & \tcode{out_edge_t} & linear & \tcode{find\_out\_edge(} \\ + % & & & \hspace{8mm}\tcode{g, *find\_vertex(g,uid), vid)} \\ \tcode{contains_out_edge(g,uid,vid)} & \tcode{bool} & constant & \tcode{uid < size(vertices(g))} \\ & & & \tcode{\&\& vid < size(vertices(g))} \\ & & & \hspace{3mm}if \tcode{is_adjacency_matrix_v}.\\ & & linear & \tcode{find\_out\_edge(g,uid,vid)} \\ & & & \tcode{!= end(out\_edges(g,uid))} otherwise. \\ - (\tcode{find\_vertex\_edge(g,u,vid)} & & & alias for \tcode{find\_out\_edge}) \\ - (\tcode{find\_vertex\_edge(g,uid,vid)} & & & alias for \tcode{find\_out\_edge}) \\ - (\tcode{contains\_edge(g,uid,vid)} & & & alias for \tcode{contains\_out\_edge}) \\ + %(\tcode{find\_vertex\_edge(g,u,vid)} & & & alias for \tcode{find\_out\_edge}) \\ + %(\tcode{find\_vertex\_edge(g,uid,vid)} & & & alias for \tcode{find\_out\_edge}) \\ + %(\tcode{contains\_edge(g,uid,vid)} & & & alias for \tcode{contains\_out\_edge}) \\ \hdashline \tcode{source_id(g,uv)} & \tcode{vertex_id_t} & constant & mandatory for descriptor-based edges \\ \tcode{source(g,uv)} & \tcode{vertex_t} & constant & \tcode{*(begin(vertices(g)) + source\_id(g,uv))} \\ & & & if \tcode{random_access_range>} \\ & & & \hspace{3mm}\tcode{\&\& integral} \\ \hdashline - \tcode{find_in_edge(g,u,vid)} & \tcode{in_edge_t} & linear & n/a (requires bidirectional graph) \\ - \tcode{find_in_edge(g,uid,vid)} & \tcode{in_edge_t} & linear & \tcode{find\_in\_edge(} \\ - & & & \hspace{8mm}\tcode{g, *find\_vertex(g,uid), vid)} \\ + \tcode{find_in_edge(g,u,v)} & \tcode{in_edge_t} & linear & n/a (requires bidirectional graph) \\ + %\tcode{find_in_edge(g,uid,vid)} & \tcode{in_edge_t} & linear & \tcode{find\_in\_edge(} \\ + % & & & \hspace{8mm}\tcode{g, *find\_vertex(g,uid), vid)} \\ \tcode{contains_in_edge(g,uid,vid)} & \tcode{bool} & linear & \tcode{find\_in\_edge(g,uid,vid)} \\ & & & \tcode{!= end(in\_edges(g,uid))} \\ \hline @@ -626,24 +626,24 @@ \subsubsection{Vertex, Edge and Neighbor Data} \paragraph{Copyable vertex, edge, and neighbor types} -The following helper type aliases simplify the most common structured-binding patterns: - -\begin{table}[h!] -\begin{center} -{\begin{tabular}{l L{8cm}} -\hline - \textbf{Alias} & \textbf{Definition} \\ -\hline - \tcode{copyable_vertex_t} & \tcode{vertex_data} --- \texttt{\{id, value\}} \\ - \tcode{copyable_edge_t} & \tcode{edge_data} --- \texttt{\{source\_id, target\_id, value\}} \\ - \tcode{copyable_neighbor_t} & \tcode{neighbor_data} --- \texttt{\{source\_id, target\_id, value\}} \\ -\hline -\hline -\end{tabular}} -\caption{Helper type aliases for common structured-binding patterns} -\label{tab:copyable_types} -\end{center} -\end{table} +%The following helper type aliases simplify the most common structured-binding patterns: +% +%\begin{table}[h!] +%\begin{center} +%{\begin{tabular}{l L{8cm}} +%\hline +% \textbf{Alias} & \textbf{Definition} \\ +%\hline +% \tcode{copyable_vertex_t} & \tcode{vertex_data} --- \texttt{\{id, value\}} \\ +% \tcode{copyable_edge_t} & \tcode{edge_data} --- \texttt{\{source\_id, target\_id, value\}} \\ +% \tcode{copyable_neighbor_t} & \tcode{neighbor_data} --- \texttt{\{source\_id, target\_id, value\}} \\ +%\hline +%\hline +%\end{tabular}} +%\caption{Helper type aliases for common structured-binding patterns} +%\label{tab:copyable_types} +%\end{center} +%\end{table} \subsubsection{Value Function Concepts} diff --git a/D3130_Container_Interface/tex/revision.tex b/D3130_Container_Interface/tex/revision.tex index e5a095a..e06d1e4 100644 --- a/D3130_Container_Interface/tex/revision.tex +++ b/D3130_Container_Interface/tex/revision.tex @@ -130,5 +130,7 @@ \subsection*{\paperno r4} patterns and the integral/\tcode{pair}/\tcode{tuple} edge element patterns), with the concrete container catalog, trade-off table and worked examples moved to that paper. \item Moved \tcode{vertex_data}, \tcode{edge_data}, and \tcode{neighbor_data} descriptions from - \href{https://www.wg21.link/P3129}{P3129 Views}. + \href{https://www.wg21.link/P3129}{P3129 Views} to this paper. + \item Simplified the GCI interface by removing most GCI function overloads that take a vertex id as an argument. + \tcode{find_out_edge(g,u,v)} replaces all overloads that take a vertex id as an argument. \end{itemize} diff --git a/D3131_Containers/tex/containers.tex b/D3131_Containers/tex/containers.tex index fe81a6b..8a98fad 100644 --- a/D3131_Containers/tex/containers.tex +++ b/D3131_Containers/tex/containers.tex @@ -129,6 +129,9 @@ \subsection{compressed\_graph description} \end{itemdescr} \section{Using Existing Data Structures} + +\phil{Use range-based descriptions. Concrete containers are also important, but stress that non-std containers can also be used.} + Reasonable defaults have been defined for the adjacency list and edgelist using data structures and types in the standard library, with some adaptation for externally defined containers, out of the box that require no function overrides. diff --git a/tex/P1709-preamble.tex b/tex/P1709-preamble.tex index d3b9324..d8f3a55 100644 --- a/tex/P1709-preamble.tex +++ b/tex/P1709-preamble.tex @@ -44,7 +44,7 @@ xleftmargin=1em, } -%% Keywords for C++20 +%% Keywords for C++23 \lstset{ morekeywords = { char8_t, diff --git a/tex/config.tex b/tex/config.tex index 8cb8cc3..22f572a 100644 --- a/tex/config.tex +++ b/tex/config.tex @@ -76,7 +76,7 @@ xleftmargin=1em, } -%% Keywords for C++20 +%% Keywords for C++23 \lstset{ morekeywords = { char8_t, @@ -116,12 +116,11 @@ % \usepackage{underscore} % remove special status of '_' in ordinary text %\usepackage{parskip} -\newcommand{\xcomment}[2]{{\color{xcomment}[{\textsc{#1:}} \textsf{#2}]}} -% \newcommand{\xcomment}[2]{} +% \newcommand{\xcomment}[2]{{\color{xcomment}[{\textsc{#1:}} \textsf{#2}]}} +\newcommand{\xcomment}[2]{} \newcommand{\phil}[1]{\xcomment{Phil}{#1}} \newcommand{\andrew}[1]{\xcomment{Andrew}{#1}} \newcommand{\kevin}[1]{\xcomment{Kevin}{#1}} -\newcommand{\muhammad}[1]{\xcomment{Muhammad}{#1}} \usepackage{multicol} diff --git a/tex/title.tex b/tex/title.tex index d422268..114b37f 100644 --- a/tex/title.tex +++ b/tex/title.tex @@ -40,4 +40,4 @@ % \subtitle{Visual inspection of various features of the framework} \author{\paperauthors} -\date{2025-07-30} +\date{2026-07-06} From 857f9cb132789dd42e438a5c1adf018d2015e319 Mon Sep 17 00:00:00 2001 From: Phil Ratzloff Date: Mon, 6 Jul 2026 17:35:31 -0400 Subject: [PATCH 10/10] Update papers from Published to Draft and bump revision numbers Papers: D3126, D3127, D3128, D3129, and D3130 --- D3126_Overview/tex/config.tex | 6 +++--- D3127_Terminology/tex/config.tex | 6 +++--- D3128_Algorithms/tex/config.tex | 6 +++--- D3129_Views/tex/config.tex | 6 +++--- D3130_Container_Interface/tex/config.tex | 6 +++--- tex/config.tex | 4 ++-- 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/D3126_Overview/tex/config.tex b/D3126_Overview/tex/config.tex index e154ae3..bc7908a 100644 --- a/D3126_Overview/tex/config.tex +++ b/D3126_Overview/tex/config.tex @@ -1,10 +1,10 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\paperno}{P3126} -\newcommand{\docno}{\paperno r4} +\newcommand{\paperno}{D3126} +\newcommand{\docno}{\paperno r5} \newcommand{\docname}{Graph Library: Overview} -\newcommand{\prevdocno}{P3126r3} +\newcommand{\prevdocno}{P3126r4} \newcommand{\cppver}{202302L} \newcommand{\mailing}{} diff --git a/D3127_Terminology/tex/config.tex b/D3127_Terminology/tex/config.tex index 8da746b..1e5277f 100644 --- a/D3127_Terminology/tex/config.tex +++ b/D3127_Terminology/tex/config.tex @@ -1,10 +1,10 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\paperno}{P3127} -\newcommand{\docno}{\paperno r2} +\newcommand{\paperno}{D3127} +\newcommand{\docno}{\paperno r3} \newcommand{\docname}{Graph Library: Background and Terminology} -\newcommand{\prevdocno}{P3127r1} +\newcommand{\prevdocno}{P3127r2} \newcommand{\cppver}{202302L} %% Release date diff --git a/D3128_Algorithms/tex/config.tex b/D3128_Algorithms/tex/config.tex index 193d7b5..f6952a5 100644 --- a/D3128_Algorithms/tex/config.tex +++ b/D3128_Algorithms/tex/config.tex @@ -1,10 +1,10 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\paperno}{P3128} -\newcommand{\docno}{\paperno r4} +\newcommand{\paperno}{D3128} +\newcommand{\docno}{\paperno r5} \newcommand{\docname}{Graph Library: Algorithms} -\newcommand{\prevdocno}{P3128r3} +\newcommand{\prevdocno}{P3128r4} \newcommand{\cppver}{202302L} %% Release date diff --git a/D3129_Views/tex/config.tex b/D3129_Views/tex/config.tex index 4f5cff5..df3132b 100644 --- a/D3129_Views/tex/config.tex +++ b/D3129_Views/tex/config.tex @@ -1,10 +1,10 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\paperno}{P3129} -\newcommand{\docno}{\paperno r2} +\newcommand{\paperno}{D3129} +\newcommand{\docno}{\paperno r3} \newcommand{\docname}{Graph Library: Views} -\newcommand{\prevdocno}{P3129r1} +\newcommand{\prevdocno}{P3129r2} \newcommand{\cppver}{202302L} %% Release date diff --git a/D3130_Container_Interface/tex/config.tex b/D3130_Container_Interface/tex/config.tex index 4205ce2..6c16ea3 100644 --- a/D3130_Container_Interface/tex/config.tex +++ b/D3130_Container_Interface/tex/config.tex @@ -1,10 +1,10 @@ %!TEX root = std.tex %%-------------------------------------------------- %% Version numbers -\newcommand{\paperno}{P3130} -\newcommand{\docno}{\paperno r4} +\newcommand{\paperno}{D3130} +\newcommand{\docno}{\paperno r5} \newcommand{\docname}{Graph Library: Graph Container Interface} -\newcommand{\prevdocno}{P3130r3} +\newcommand{\prevdocno}{P3130r4} \newcommand{\cppver}{202302L} %% Release date diff --git a/tex/config.tex b/tex/config.tex index 22f572a..0d1c75f 100644 --- a/tex/config.tex +++ b/tex/config.tex @@ -116,8 +116,8 @@ % \usepackage{underscore} % remove special status of '_' in ordinary text %\usepackage{parskip} -% \newcommand{\xcomment}[2]{{\color{xcomment}[{\textsc{#1:}} \textsf{#2}]}} -\newcommand{\xcomment}[2]{} +\newcommand{\xcomment}[2]{{\color{xcomment}[{\textsc{#1:}} \textsf{#2}]}} +%\newcommand{\xcomment}[2]{} \newcommand{\phil}[1]{\xcomment{Phil}{#1}} \newcommand{\andrew}[1]{\xcomment{Andrew}{#1}} \newcommand{\kevin}[1]{\xcomment{Kevin}{#1}}