Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

The Path type

Path<NodeT, EdgeT> is the first-class type produced by path-projecting query forms (query). It appears in the built-in type forms (Built-in type forms) because the compiler synthesizes path values from query results; the value-level API lives in the stdlib (std::path).

A path is an ordered, alternating sequence n₀, e₁, n₁, e₂, n₂, …, eₘ, nₘ where m = length(path) is the number of edges. A path of length zero is a single node. NodeT and EdgeT are the least common supertypes of the node and edge values respectively.

Edge values by relation form. Edge values vary with which relation form (Relations) the path traverses:

  • Forms B and C — named relations. Each edge value is the relation tuple-entity itself, carrying any intrinsic properties: path.nth_edge(0)?.distance retrieves the distance field of the first edge when the underlying relation declares it.
  • Form A — anonymous fields. Each edge value is the structural placeholder Edge<From, To> { from: From, to: To }. Form A carries no metarel classification and no intrinsic data, so the placeholder exposes only endpoint identities.

Heterogeneous chains. When a path traverses relations with differing endpoint types (e.g., user.knows(friend).works_at(company) where knows: User → Person and works_at: Person → Company), NodeT is the join (least common supertype) of User, Person, and Company, and EdgeT the join of the involved relation types. When no common supertype is in scope, both fall back to Top. Modelers needing precise heterogeneous typing decompose into single-relation queries and join at the modeler level.

Hyperedges. Paths are over binary relations only. n-ary relations (pub rel Transaction(seller, buyer, item)) are queryable but not path-traversable; hypergraph traversal semantics is out of scope (Out of scope).

API. The shape/projection/fold operators (length, nodes, edges, nth_edge, reverse, concat, map_*, …) are stdlib API on impl<N, E> Path<N, E> in std::path — see Stdlib (selected). The type-system-relevant facts: cost(self) -> Real lives in a conditional impl gated on E <: Weighted (the Rust-aligned conditional-impl pattern), so a uniform Path<N, E> admits cost() only when the edge type implements the std::path trait Weighted { fn weight(self) -> Real; }; without it, shortest-path queries rank by edge count. The Form-A edge value is the placeholder pub struct Edge<A, B> { from: A, to: B } — no metarel classification, just a first-class edge for uniform iteration.

Equality. Path<N, E> has structural equality: two paths are equal iff their node and edge sequences match position-by-position. Paths are value-semantic and immutable; all transformations produce new path values.