Add missing MutNode.retain_reachable and bump docs.

This commit is contained in:
Stu Black 2025-01-09 12:55:42 -05:00
parent 651ce5fd84
commit 4abef5b294
3 changed files with 58 additions and 24 deletions

View File

@ -1,9 +1,11 @@
//! This crate provides support for search (in the sense of AI or optimization)
//! over a space of discrete, enumerated states. Its main data structure is
//! [Graph](struct.Graph.html), a directed graph with content-addressable
//! vertices.
//! vertices. See [the documentation for that type](struct.Graph.html) for a
//! description of what information it holds (and why).
//!
//! Several efficient, type-safe interfaces are provided in submodules:
//! Several efficient, type-safe interfaces to `Graph` are also provided. You
//! will likely interact with a `Graph` through these interfaces:
//!
//! * [view](view/index.html) provides a type- and memory-safe view of a `Graph`.
//! * [nav](nav/index.html) provides a read-only cursor-based view of a
@ -11,6 +13,12 @@
//! [zippers](https://en.wikipedia.org/wiki/Zipper_(data_structure)) in other
//! contexts, this pattern should be familiar).
//! * [mutators](mutators/index.html) is a read-write analogue of `nav`.
//!
//! Limited support for deletion of graph elements is available, in the form of
//! mark-and-compact garbage collection. See
//! [MutNode.retain_reachable](mutators/struct.MutNode.html#method.retain_reachable)
//! and
//! [View.retain_reachable_from](view/struct.View.html#method.retain_reachable_from).
pub(crate) mod base;
pub(crate) mod mark_compact;
@ -27,32 +35,42 @@ use symbol_map::SymbolId;
/// A directed graph over a space of discrete, enumerated states.
///
/// In typical usage, vertices in the graph will correspond to game states, and
/// edges will correspond to game actions. Vertices have an associated state
/// (e.g., the configuration of pieces on a chessboard) and data (e.g., upper
/// and lower bounds of the score of the outcomes that can be reached from that
/// state), while edges simply have an associated data item (which may include
/// additional statistics statistics or game-specific data about the action that
/// the edge represents).
/// In typical usage, vertices in the graph correspond to game states, and edges
/// correspond to game actions. Vertices have an associated game state (e.g.,
/// the configuration of pieces on a chessboard) and data (e.g., upper and lower
/// bounds of the score of the outcomes that can be reached from that state),
/// while edges simply have an associated data item (which may include
/// additional statistics or game-specific data about the action that the edge
/// represents).
///
/// A `Graph` is parameterized by three types:
///
/// - `T`: The type of game states. It is required to derive `Hash` and `Eq` to
/// so that it may be stored in a hashtable, where game states are looked up to
/// support de-duplication of game states. It is required to derive `Clone` to
/// accommodate a limitation of the `HashMap` interface.
/// - `T`: The type of game states. It is required to derive `Hash` and `Eq` so
/// that it may be stored in a hashtable, where game states are looked up to
/// support de-duplication. It is required to derive `Clone` to accommodate a
/// limitation of the `HashMap` interface.
/// - `S`: The vertex data type.
/// - `A`: The edge data type.
///
/// Vertices are addressable by content. Cursors into the graph may be obtained
/// with [find_node](struct.Graph.html#method.find_node) or
/// [find_node_mut](struct.Graph.html#method.find_node_mut).
/// The *game state* of a vertex should be immutable. It is technically possible
/// to use a game state type that has interior mutability, but this will
/// probably cause the index that maps from game state to vertex to break.
///
/// The *data* on an edge or vertex may be mutable. It is expected that it will
/// be, with some form of interior mutability. (You need *somewhere* to record
/// information during graph search!)
///
/// Cursors into the graph may be obtained with
/// [find_node](struct.Graph.html#method.find_node) or
/// [find_node_mut](struct.Graph.html#method.find_node_mut). Or you can pass it
/// to [`view::of_graph`](view/fn.of_graph.html) and operate on it via the
/// [`View`](view/struct.View.html) API.
///
/// Content can be added to a `Graph` directly with the
/// [add_node](struct.Graph.html#method.add_node and
/// [add_node](struct.Graph.html#method.add_node) and
/// [add_edge](struct.Graph.html#method.add_edge) methods. It may also be added
/// through the interfaces provided by the [mutators/index.html](mutators) and
/// [view/index.html](view) modules.
/// through the interfaces provided by the [mutators](mutators/index.html) and
/// [view](view/index.html) modules.
pub struct Graph<T: Hash + Eq + Clone, S, A> {
/// Lookup table that maps from game states to `VertexId`.
state_ids: symbol_map::indexing::HashIndexing<T, VertexId>,

View File

@ -138,6 +138,11 @@ impl<'a, T: Hash + Eq + Clone + 'a, S: 'a, A: 'a> MutNode<'a, T, S, A> {
pub fn get_node(&self) -> Node<'_, T, S, A> {
Node::new(self.graph, self.id)
}
/// Deletes all graph components that are not reachable from `self`.
pub fn retain_reachable(&mut self) {
crate::mark_compact::Collector::retain_reachable(self.graph, &[self.id]);
}
}
/// A traversible list of a vertex's outgoing edges.

View File

@ -2,11 +2,22 @@
//! simultaneously allowing multiple live references into the graph.
//!
//! References into the graph are provided by [NodeRef](struct.NodeRef.html) and
//! [EdgeRef](struct.EdgeRef.html). They are created with respect to a
//! [View](struct.View.html), which wraps around a mutable borrow of a
//! [Graph](../struct.Graph.html). They may only be dereferenced with respect to
//! the view that created them, and operations on a `View` that would invalidate
//! these references consume the `View`.
//! [EdgeRef](struct.EdgeRef.html). You may have multiple `NodeRef`s and
//! `EdgeRef`s pointing into the same `View` at any time, without running into
//! restrictions from the borrow checker.
//!
//! To make use of these references, pass them to their respective methods on
//! the `View` that they came from (like
//! [node_state](struct.View.html#method.node_state),
//! [node_data_mut](struct.View.html#method.node_data),
//! [edge_data_mut](struct.View.html#edge_data_mut), and
//! [edge_target](struct.View.html#edge_target)).
//!
//! These references are created with respect to a [View](struct.View.html),
//! which wraps around a mutable borrow of a [Graph](../struct.Graph.html). They
//! may only be dereferenced with respect to the view that created them, and
//! operations on a `View` that would invalidate these references consume the
//! `View`.
//!
//! # Basic usage
//!