Set indentation correctly and run rustfmt on everything.
This commit is contained in:
parent
d6de8fb161
commit
072a28fa76
48
src/base.rs
48
src/base.rs
@ -9,12 +9,12 @@ use symbol_map;
|
||||
pub(crate) struct EdgeId(pub usize);
|
||||
|
||||
impl EdgeId {
|
||||
/// Converts an `EdgeId` to a usize that is guaranteed to be unique within a
|
||||
/// graph.
|
||||
pub fn as_usize(self) -> usize {
|
||||
let EdgeId(x) = self;
|
||||
x
|
||||
}
|
||||
/// Converts an `EdgeId` to a usize that is guaranteed to be unique within a
|
||||
/// graph.
|
||||
pub fn as_usize(self) -> usize {
|
||||
let EdgeId(x) = self;
|
||||
x
|
||||
}
|
||||
}
|
||||
|
||||
/// Internal vertex identifier.
|
||||
@ -27,12 +27,18 @@ impl EdgeId {
|
||||
pub(crate) struct VertexId(pub usize);
|
||||
|
||||
impl Default for VertexId {
|
||||
fn default() -> Self { VertexId(0) }
|
||||
fn default() -> Self {
|
||||
VertexId(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl symbol_map::SymbolId for VertexId {
|
||||
fn next(&self) -> Self { VertexId(self.0 + 1) }
|
||||
fn as_usize(&self) -> usize { self.0 }
|
||||
fn next(&self) -> Self {
|
||||
VertexId(self.0 + 1)
|
||||
}
|
||||
fn as_usize(&self) -> usize {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
/// Internal type for graph edges.
|
||||
@ -41,21 +47,21 @@ impl symbol_map::SymbolId for VertexId {
|
||||
/// identical statistics.
|
||||
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub(crate) struct RawEdge<A> {
|
||||
/// Edge data.
|
||||
pub data: A,
|
||||
/// Source vertex.
|
||||
pub source: VertexId,
|
||||
/// Target vertex.
|
||||
pub target: VertexId,
|
||||
/// Edge data.
|
||||
pub data: A,
|
||||
/// Source vertex.
|
||||
pub source: VertexId,
|
||||
/// Target vertex.
|
||||
pub target: VertexId,
|
||||
}
|
||||
|
||||
/// Internal type for graph vertices.
|
||||
#[derive(Debug, Eq, Ord, PartialEq, PartialOrd)]
|
||||
pub(crate) struct RawVertex<S> {
|
||||
/// Vertex data.
|
||||
pub data: S,
|
||||
/// Parent edges pointing into this vertex.
|
||||
pub parents: Vec<EdgeId>,
|
||||
/// Child edges pointing out of this vertex.
|
||||
pub children: Vec<EdgeId>,
|
||||
/// Vertex data.
|
||||
pub data: S,
|
||||
/// Parent edges pointing into this vertex.
|
||||
pub parents: Vec<EdgeId>,
|
||||
/// Child edges pointing out of this vertex.
|
||||
pub children: Vec<EdgeId>,
|
||||
}
|
||||
|
406
src/lib.rs
406
src/lib.rs
@ -29,239 +29,239 @@ use symbol_map::SymbolId;
|
||||
/// `add_root` and retrieve extant vertices with `get_node_mut`.
|
||||
pub struct Graph<T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone,
|
||||
T: Hash + Eq + Clone,
|
||||
{
|
||||
/// Lookup table that maps from game states to `VertexId`.
|
||||
state_ids: symbol_map::indexing::HashIndexing<T, VertexId>,
|
||||
vertices: Vec<RawVertex<S>>, // Indexed by VertexId.
|
||||
arcs: Vec<RawEdge<A>>, // Indexed by EdgeId.
|
||||
/// Lookup table that maps from game states to `VertexId`.
|
||||
state_ids: symbol_map::indexing::HashIndexing<T, VertexId>,
|
||||
vertices: Vec<RawVertex<S>>, // Indexed by VertexId.
|
||||
arcs: Vec<RawEdge<A>>, // Indexed by EdgeId.
|
||||
}
|
||||
|
||||
impl<T, S, A> Graph<T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone,
|
||||
T: Hash + Eq + Clone,
|
||||
{
|
||||
/// Creates an empty `Graph` with no vertices or edges.
|
||||
pub fn new() -> Self {
|
||||
Graph {
|
||||
state_ids: Default::default(),
|
||||
vertices: Vec::new(),
|
||||
arcs: Vec::new(),
|
||||
}
|
||||
/// Creates an empty `Graph` with no vertices or edges.
|
||||
pub fn new() -> Self {
|
||||
Graph {
|
||||
state_ids: Default::default(),
|
||||
vertices: Vec::new(),
|
||||
arcs: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the vertex for the given `VertexId`.
|
||||
fn get_vertex(&self, state: VertexId) -> &RawVertex<S> {
|
||||
&self.vertices[state.as_usize()]
|
||||
}
|
||||
/// Returns the vertex for the given `VertexId`.
|
||||
fn get_vertex(&self, state: VertexId) -> &RawVertex<S> {
|
||||
&self.vertices[state.as_usize()]
|
||||
}
|
||||
|
||||
/// Returns the vertex for the given `VertexId`.
|
||||
fn get_vertex_mut(&mut self, state: VertexId) -> &mut RawVertex<S> {
|
||||
&mut self.vertices[state.as_usize()]
|
||||
}
|
||||
/// Returns the vertex for the given `VertexId`.
|
||||
fn get_vertex_mut(&mut self, state: VertexId) -> &mut RawVertex<S> {
|
||||
&mut self.vertices[state.as_usize()]
|
||||
}
|
||||
|
||||
/// Returns the edge for the given `EdgeId`.
|
||||
fn get_arc(&self, arc: EdgeId) -> &RawEdge<A> {
|
||||
&self.arcs[arc.as_usize()]
|
||||
}
|
||||
/// Returns the edge for the given `EdgeId`.
|
||||
fn get_arc(&self, arc: EdgeId) -> &RawEdge<A> {
|
||||
&self.arcs[arc.as_usize()]
|
||||
}
|
||||
|
||||
/// Returns the edge for the given `EdgeId`.
|
||||
fn get_arc_mut(&mut self, arc: EdgeId) -> &mut RawEdge<A> {
|
||||
&mut self.arcs[arc.as_usize()]
|
||||
}
|
||||
/// Returns the edge for the given `EdgeId`.
|
||||
fn get_arc_mut(&mut self, arc: EdgeId) -> &mut RawEdge<A> {
|
||||
&mut self.arcs[arc.as_usize()]
|
||||
}
|
||||
|
||||
/// Returns the game state associated with `id`.
|
||||
fn get_state(&self, id: VertexId) -> Option<&T> {
|
||||
self.state_ids.get_symbol(&id).as_ref().map(|x| x.data())
|
||||
}
|
||||
/// Returns the game state associated with `id`.
|
||||
fn get_state(&self, id: VertexId) -> Option<&T> {
|
||||
self.state_ids.get_symbol(&id).as_ref().map(|x| x.data())
|
||||
}
|
||||
|
||||
/// Adds a new vertex with the given data, returning a mutable reference to it.
|
||||
///
|
||||
/// This method does not add incoming or outgoing edges (expanded or
|
||||
/// not). That must be done by calling `add_arc` with the new vertex
|
||||
/// `VertexId`.
|
||||
fn add_raw_vertex(&mut self, data: S) -> &mut RawVertex<S> {
|
||||
self.vertices.push(RawVertex {
|
||||
data: data,
|
||||
parents: Vec::new(),
|
||||
children: Vec::new(),
|
||||
});
|
||||
self.vertices.last_mut().unwrap()
|
||||
}
|
||||
/// Adds a new vertex with the given data, returning a mutable reference to it.
|
||||
///
|
||||
/// This method does not add incoming or outgoing edges (expanded or
|
||||
/// not). That must be done by calling `add_arc` with the new vertex
|
||||
/// `VertexId`.
|
||||
fn add_raw_vertex(&mut self, data: S) -> &mut RawVertex<S> {
|
||||
self.vertices.push(RawVertex {
|
||||
data: data,
|
||||
parents: Vec::new(),
|
||||
children: Vec::new(),
|
||||
});
|
||||
self.vertices.last_mut().unwrap()
|
||||
}
|
||||
|
||||
/// Adds a new edge with the given data, source, and target. Returns the
|
||||
/// internal ID for the new edge.
|
||||
fn add_raw_edge(&mut self, data: A, source: VertexId, target: VertexId) -> EdgeId {
|
||||
let arc_id = EdgeId(self.arcs.len());
|
||||
self.get_vertex_mut(source).children.push(arc_id);
|
||||
self.get_vertex_mut(target).parents.push(arc_id);
|
||||
self.arcs.push(RawEdge {
|
||||
data: data,
|
||||
source: source,
|
||||
target: target,
|
||||
});
|
||||
arc_id
|
||||
}
|
||||
/// Adds a new edge with the given data, source, and target. Returns the
|
||||
/// internal ID for the new edge.
|
||||
fn add_raw_edge(&mut self, data: A, source: VertexId, target: VertexId) -> EdgeId {
|
||||
let arc_id = EdgeId(self.arcs.len());
|
||||
self.get_vertex_mut(source).children.push(arc_id);
|
||||
self.get_vertex_mut(target).parents.push(arc_id);
|
||||
self.arcs.push(RawEdge {
|
||||
data: data,
|
||||
source: source,
|
||||
target: target,
|
||||
});
|
||||
arc_id
|
||||
}
|
||||
|
||||
/// Gets a node handle for the given game state.
|
||||
///
|
||||
/// If `state` does not correspond to a known game state, returns `None`.
|
||||
pub fn get_node<'s>(&'s self, state: &T) -> Option<Node<'s, T, S, A>> {
|
||||
match self.state_ids.get(state) {
|
||||
Some(symbol) => Some(Node::new(self, *symbol.id())),
|
||||
None => None,
|
||||
}
|
||||
/// Gets a node handle for the given game state.
|
||||
///
|
||||
/// If `state` does not correspond to a known game state, returns `None`.
|
||||
pub fn get_node<'s>(&'s self, state: &T) -> Option<Node<'s, T, S, A>> {
|
||||
match self.state_ids.get(state) {
|
||||
Some(symbol) => Some(Node::new(self, *symbol.id())),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Gets a mutable node handle for the given game state.
|
||||
///
|
||||
/// If `state` does not correspond to a known game state, returns `None`.
|
||||
pub fn get_node_mut<'s>(&'s mut self, state: &T) -> Option<MutNode<'s, T, S, A>> {
|
||||
match self.state_ids.get(state).map(|s| s.id().clone()) {
|
||||
Some(id) => Some(MutNode::new(self, id)),
|
||||
None => None,
|
||||
}
|
||||
/// Gets a mutable node handle for the given game state.
|
||||
///
|
||||
/// If `state` does not correspond to a known game state, returns `None`.
|
||||
pub fn get_node_mut<'s>(&'s mut self, state: &T) -> Option<MutNode<'s, T, S, A>> {
|
||||
match self.state_ids.get(state).map(|s| s.id().clone()) {
|
||||
Some(id) => Some(MutNode::new(self, id)),
|
||||
None => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Adds a root vertex (one with no parents) for the given game state and
|
||||
/// data and returns a mutable handle for it.
|
||||
///
|
||||
/// If `state` is already known, returns a mutable handle to that state,
|
||||
/// ignoring the `data` parameter. As a result, this method is guaranteed to
|
||||
/// return a handle for a root vertex only when `state` is a novel game
|
||||
/// state.
|
||||
pub fn add_root<'s>(&'s mut self, state: T, data: S) -> MutNode<'s, T, S, A> {
|
||||
let node_id = match self.state_ids.get_or_insert(state).map(|s| s.id().clone()) {
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
self.add_raw_vertex(data);
|
||||
id
|
||||
}
|
||||
};
|
||||
MutNode::new(self, node_id)
|
||||
}
|
||||
/// Adds a root vertex (one with no parents) for the given game state and
|
||||
/// data and returns a mutable handle for it.
|
||||
///
|
||||
/// If `state` is already known, returns a mutable handle to that state,
|
||||
/// ignoring the `data` parameter. As a result, this method is guaranteed to
|
||||
/// return a handle for a root vertex only when `state` is a novel game
|
||||
/// state.
|
||||
pub fn add_root<'s>(&'s mut self, state: T, data: S) -> MutNode<'s, T, S, A> {
|
||||
let node_id = match self.state_ids.get_or_insert(state).map(|s| s.id().clone()) {
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
self.add_raw_vertex(data);
|
||||
id
|
||||
}
|
||||
};
|
||||
MutNode::new(self, node_id)
|
||||
}
|
||||
|
||||
/// Adds an edge from the vertex with state data `source` to the vertex with
|
||||
/// state data `dest`. If vertices are not found for `source` or `dest`,
|
||||
/// they are added, with the data provided by `source_data` and `dest_data`
|
||||
/// callbacks.
|
||||
///
|
||||
/// The edge that is created will have the data `edge_data`. Returns a
|
||||
/// mutable edge handle for that edge.
|
||||
pub fn add_edge<'s, F, G>(
|
||||
&'s mut self,
|
||||
source: T,
|
||||
source_data: F,
|
||||
dest: T,
|
||||
dest_data: G,
|
||||
edge_data: A,
|
||||
) -> MutEdge<'s, T, S, A>
|
||||
where
|
||||
F: for<'b> FnOnce(Node<'b, T, S, A>) -> S,
|
||||
G: for<'b> FnOnce(Node<'b, T, S, A>) -> S,
|
||||
{
|
||||
let source_id = match self.state_ids.get_or_insert(source).map(|s| s.id().clone()) {
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
let data = source_data(Node::new(self, id));
|
||||
self.add_raw_vertex(data);
|
||||
id
|
||||
}
|
||||
};
|
||||
let dest_id = match self.state_ids.get_or_insert(dest).map(|s| s.id().clone()) {
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
let data = dest_data(Node::new(self, id));
|
||||
self.add_raw_vertex(data);
|
||||
id
|
||||
}
|
||||
};
|
||||
let edge_id = self.add_raw_edge(edge_data, source_id, dest_id);
|
||||
MutEdge::new(self, edge_id)
|
||||
}
|
||||
/// Adds an edge from the vertex with state data `source` to the vertex with
|
||||
/// state data `dest`. If vertices are not found for `source` or `dest`,
|
||||
/// they are added, with the data provided by `source_data` and `dest_data`
|
||||
/// callbacks.
|
||||
///
|
||||
/// The edge that is created will have the data `edge_data`. Returns a
|
||||
/// mutable edge handle for that edge.
|
||||
pub fn add_edge<'s, F, G>(
|
||||
&'s mut self,
|
||||
source: T,
|
||||
source_data: F,
|
||||
dest: T,
|
||||
dest_data: G,
|
||||
edge_data: A,
|
||||
) -> MutEdge<'s, T, S, A>
|
||||
where
|
||||
F: for<'b> FnOnce(Node<'b, T, S, A>) -> S,
|
||||
G: for<'b> FnOnce(Node<'b, T, S, A>) -> S,
|
||||
{
|
||||
let source_id = match self.state_ids.get_or_insert(source).map(|s| s.id().clone()) {
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
let data = source_data(Node::new(self, id));
|
||||
self.add_raw_vertex(data);
|
||||
id
|
||||
}
|
||||
};
|
||||
let dest_id = match self.state_ids.get_or_insert(dest).map(|s| s.id().clone()) {
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
let data = dest_data(Node::new(self, id));
|
||||
self.add_raw_vertex(data);
|
||||
id
|
||||
}
|
||||
};
|
||||
let edge_id = self.add_raw_edge(edge_data, source_id, dest_id);
|
||||
MutEdge::new(self, edge_id)
|
||||
}
|
||||
|
||||
/// Returns the number of vertices in the graph.
|
||||
pub fn vertex_count(&self) -> usize {
|
||||
// TODO: This is actually the number of vertices we have allocated.
|
||||
self.vertices.len()
|
||||
}
|
||||
/// Returns the number of vertices in the graph.
|
||||
pub fn vertex_count(&self) -> usize {
|
||||
// TODO: This is actually the number of vertices we have allocated.
|
||||
self.vertices.len()
|
||||
}
|
||||
|
||||
/// Returns the number of edges in the graph.
|
||||
pub fn edge_count(&self) -> usize {
|
||||
// TODO: This is actually the number of edges we have allocated.
|
||||
self.arcs.len()
|
||||
}
|
||||
/// Returns the number of edges in the graph.
|
||||
pub fn edge_count(&self) -> usize {
|
||||
// TODO: This is actually the number of edges we have allocated.
|
||||
self.arcs.len()
|
||||
}
|
||||
|
||||
/// Deletes all graph components that are not reachable by traversal
|
||||
/// starting from each vertex corresponding to the game states in `roots`.
|
||||
///
|
||||
/// Game states in `roots` which do not have a corresponding vertex are
|
||||
/// ignored.
|
||||
pub fn retain_reachable_from(&mut self, roots: &[&T]) {
|
||||
let mut root_ids = Vec::with_capacity(roots.len());
|
||||
for state in roots.iter() {
|
||||
if let Some(symbol) = self.state_ids.get(state) {
|
||||
root_ids.push(*symbol.id());
|
||||
}
|
||||
}
|
||||
self.retain_reachable_from_ids(&root_ids);
|
||||
/// Deletes all graph components that are not reachable by traversal
|
||||
/// starting from each vertex corresponding to the game states in `roots`.
|
||||
///
|
||||
/// Game states in `roots` which do not have a corresponding vertex are
|
||||
/// ignored.
|
||||
pub fn retain_reachable_from(&mut self, roots: &[&T]) {
|
||||
let mut root_ids = Vec::with_capacity(roots.len());
|
||||
for state in roots.iter() {
|
||||
if let Some(symbol) = self.state_ids.get(state) {
|
||||
root_ids.push(*symbol.id());
|
||||
}
|
||||
}
|
||||
self.retain_reachable_from_ids(&root_ids);
|
||||
}
|
||||
|
||||
/// As `retain_reachable_from`, but working over raw `VertexId`s instead of
|
||||
/// root data.
|
||||
fn retain_reachable_from_ids(&mut self, root_ids: &[VertexId]) {
|
||||
mutators::mark_compact::Collector::retain_reachable(self, root_ids);
|
||||
}
|
||||
/// As `retain_reachable_from`, but working over raw `VertexId`s instead of
|
||||
/// root data.
|
||||
fn retain_reachable_from_ids(&mut self, root_ids: &[VertexId]) {
|
||||
mutators::mark_compact::Collector::retain_reachable(self, root_ids);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use crossbeam_utils::thread;
|
||||
use std::sync::Arc;
|
||||
use crossbeam_utils::thread;
|
||||
use std::sync::Arc;
|
||||
|
||||
type Graph = crate::Graph<&'static str, &'static str, &'static str>;
|
||||
type Graph = crate::Graph<&'static str, &'static str, &'static str>;
|
||||
|
||||
#[test]
|
||||
fn send_to_thread_safe_ok() {
|
||||
let mut g = Graph::new();
|
||||
g.add_edge("root", |_| "root_data", "0", |_| "0_data", "root_0_data");
|
||||
g.add_edge("root", |_| "root_data", "1", |_| "1_data", "root_1_data");
|
||||
let graph = Arc::new(g);
|
||||
thread::scope(move |s| {
|
||||
let g = graph.clone();
|
||||
let t1 = s.spawn(move |_| g.get_node(&"root").map(|n| n.get_id()));
|
||||
let g = graph.clone();
|
||||
let t2 = s.spawn(move |_| g.get_node(&"1").map(|n| n.get_id()));
|
||||
match t1.join() {
|
||||
Ok(Some(id)) => assert_eq!(id, 0),
|
||||
_ => panic!(),
|
||||
}
|
||||
match t2.join() {
|
||||
Ok(Some(id)) => assert_eq!(id, 2),
|
||||
_ => panic!(),
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
#[test]
|
||||
fn send_to_thread_safe_ok() {
|
||||
let mut g = Graph::new();
|
||||
g.add_edge("root", |_| "root_data", "0", |_| "0_data", "root_0_data");
|
||||
g.add_edge("root", |_| "root_data", "1", |_| "1_data", "root_1_data");
|
||||
let graph = Arc::new(g);
|
||||
thread::scope(move |s| {
|
||||
let g = graph.clone();
|
||||
let t1 = s.spawn(move |_| g.get_node(&"root").map(|n| n.get_id()));
|
||||
let g = graph.clone();
|
||||
let t2 = s.spawn(move |_| g.get_node(&"1").map(|n| n.get_id()));
|
||||
match t1.join() {
|
||||
Ok(Some(id)) => assert_eq!(id, 0),
|
||||
_ => panic!(),
|
||||
}
|
||||
match t2.join() {
|
||||
Ok(Some(id)) => assert_eq!(id, 2),
|
||||
_ => panic!(),
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sync_to_thread_ok() {
|
||||
let mut g = Graph::new();
|
||||
g.add_edge("root", |_| "root_data", "0", |_| "0_data", "root_0_data");
|
||||
g.add_edge("root", |_| "root_data", "1", |_| "1_data", "root_1_data");
|
||||
let g = &g;
|
||||
thread::scope(|s| {
|
||||
let t1 = s.spawn(move |_| g.get_node(&"root").map(|n| n.get_id()));
|
||||
let t2 = s.spawn(move |_| g.get_node(&"1").map(|n| n.get_id()));
|
||||
match t1.join() {
|
||||
Ok(Some(id)) => assert_eq!(id, 0),
|
||||
_ => panic!(),
|
||||
}
|
||||
match t2.join() {
|
||||
Ok(Some(id)) => assert_eq!(id, 2),
|
||||
_ => panic!(),
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
#[test]
|
||||
fn sync_to_thread_ok() {
|
||||
let mut g = Graph::new();
|
||||
g.add_edge("root", |_| "root_data", "0", |_| "0_data", "root_0_data");
|
||||
g.add_edge("root", |_| "root_data", "1", |_| "1_data", "root_1_data");
|
||||
let g = &g;
|
||||
thread::scope(|s| {
|
||||
let t1 = s.spawn(move |_| g.get_node(&"root").map(|n| n.get_id()));
|
||||
let t2 = s.spawn(move |_| g.get_node(&"1").map(|n| n.get_id()));
|
||||
match t1.join() {
|
||||
Ok(Some(id)) => assert_eq!(id, 0),
|
||||
_ => panic!(),
|
||||
}
|
||||
match t2.join() {
|
||||
Ok(Some(id)) => assert_eq!(id, 2),
|
||||
_ => panic!(),
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -9,11 +9,11 @@ use std::clone::Clone;
|
||||
use std::cmp::Eq;
|
||||
use std::hash::Hash;
|
||||
|
||||
use crate::Graph;
|
||||
use crate::base::{EdgeId, RawEdge, RawVertex, VertexId};
|
||||
use crate::nav::{ChildList, ChildListIter, Edge, Node, ParentList, ParentListIter};
|
||||
use symbol_map::SymbolId;
|
||||
use crate::Graph;
|
||||
use symbol_map::indexing::{Indexing, Insertion};
|
||||
use symbol_map::SymbolId;
|
||||
|
||||
pub(crate) mod mark_compact;
|
||||
|
||||
@ -25,318 +25,426 @@ pub(crate) mod mark_compact;
|
||||
/// It enables local graph mutation, whether via mutation of vertex data or
|
||||
/// mutation of graph topology (adding edges). Edges may be added
|
||||
/// using the handle returned by `get_child_adder` or `to_child_adder`.
|
||||
pub struct MutNode<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
pub(crate) graph: &'a mut Graph<T, S, A>,
|
||||
pub(crate) id: VertexId,
|
||||
pub struct MutNode<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
pub(crate) graph: &'a mut Graph<T, S, A>,
|
||||
pub(crate) id: VertexId,
|
||||
}
|
||||
|
||||
impl<'a, T, S, A> MutNode<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
/// Creates a new `MutNode` for the given graph and gamestate. This method is
|
||||
/// not exported by the crate because it exposes implementation details.
|
||||
pub(crate) fn new(graph: &'a mut Graph<T, S, A>, id: VertexId) -> Self {
|
||||
MutNode { graph, id }
|
||||
}
|
||||
|
||||
impl<'a, T, S, A> MutNode<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
/// Creates a new `MutNode` for the given graph and gamestate. This method is
|
||||
/// not exported by the crate because it exposes implementation details.
|
||||
pub(crate) fn new(graph: &'a mut Graph<T, S, A>, id: VertexId) -> Self {
|
||||
MutNode { graph, id }
|
||||
}
|
||||
fn vertex<'s>(&'s self) -> &'s RawVertex<S> {
|
||||
self.graph.get_vertex(self.id)
|
||||
}
|
||||
|
||||
fn vertex<'s>(&'s self) -> &'s RawVertex<S> {
|
||||
self.graph.get_vertex(self.id)
|
||||
}
|
||||
fn vertex_mut<'s>(&'s mut self) -> &'s mut RawVertex<S> {
|
||||
self.graph.get_vertex_mut(self.id)
|
||||
}
|
||||
|
||||
fn vertex_mut<'s>(&'s mut self) -> &'s mut RawVertex<S> {
|
||||
self.graph.get_vertex_mut(self.id)
|
||||
}
|
||||
/// Returns an immutable ID that is guaranteed to identify this vertex
|
||||
/// uniquely within its graph. This ID may change when the graph is mutated.
|
||||
pub fn get_id(&self) -> usize {
|
||||
self.id.as_usize()
|
||||
}
|
||||
|
||||
/// Returns an immutable ID that is guaranteed to identify this vertex
|
||||
/// uniquely within its graph. This ID may change when the graph is mutated.
|
||||
pub fn get_id(&self) -> usize {
|
||||
self.id.as_usize()
|
||||
}
|
||||
/// Returns the canonical label that is used to address this `MutNode`.
|
||||
///
|
||||
/// Graph instances which project multiple labels to the same vertex will
|
||||
/// consistently return a single value, regardless of which value was used
|
||||
/// to obtain this node handle.
|
||||
pub fn get_label(&self) -> &T {
|
||||
&self.graph.get_state(self.id).unwrap()
|
||||
}
|
||||
|
||||
/// Returns the canonical label that is used to address this `MutNode`.
|
||||
///
|
||||
/// Graph instances which project multiple labels to the same vertex will
|
||||
/// consistently return a single value, regardless of which value was used
|
||||
/// to obtain this node handle.
|
||||
pub fn get_label(&self) -> &T {
|
||||
&self.graph.get_state(self.id).unwrap()
|
||||
}
|
||||
/// Returns the data at this vertex.
|
||||
pub fn get_data<'s>(&'s self) -> &'s S {
|
||||
&self.vertex().data
|
||||
}
|
||||
|
||||
/// Returns the data at this vertex.
|
||||
pub fn get_data<'s>(&'s self) -> &'s S {
|
||||
&self.vertex().data
|
||||
}
|
||||
/// Returns the data at this vertex, mutably.
|
||||
pub fn get_data_mut<'s>(&'s mut self) -> &'s mut S {
|
||||
&mut self.vertex_mut().data
|
||||
}
|
||||
|
||||
/// Returns the data at this vertex, mutably.
|
||||
pub fn get_data_mut<'s>(&'s mut self) -> &'s mut S {
|
||||
&mut self.vertex_mut().data
|
||||
}
|
||||
/// Returns true iff this vertex has no outgoing edges (regardless of
|
||||
/// whether they are expanded).
|
||||
pub fn is_leaf(&self) -> bool {
|
||||
self.vertex().children.is_empty()
|
||||
}
|
||||
|
||||
/// Returns true iff this vertex has no outgoing edges (regardless of
|
||||
/// whether they are expanded).
|
||||
pub fn is_leaf(&self) -> bool {
|
||||
self.vertex().children.is_empty()
|
||||
}
|
||||
/// Returns true iff this vertex has no incoming edges.
|
||||
pub fn is_root(&self) -> bool {
|
||||
self.vertex().parents.is_empty()
|
||||
}
|
||||
|
||||
/// Returns true iff this vertex has no incoming edges.
|
||||
pub fn is_root(&self) -> bool {
|
||||
self.vertex().parents.is_empty()
|
||||
}
|
||||
/// Returns a traversible list of outgoing edges. Its lifetime will be
|
||||
/// limited to a local borrow of `self`.
|
||||
pub fn get_child_list<'s>(&'s self) -> ChildList<'s, T, S, A> {
|
||||
ChildList::new(self.graph, self.id)
|
||||
}
|
||||
|
||||
/// Returns a traversible list of outgoing edges. Its lifetime will be
|
||||
/// limited to a local borrow of `self`.
|
||||
pub fn get_child_list<'s>(&'s self) -> ChildList<'s, T, S, A> {
|
||||
ChildList::new(self.graph, self.id)
|
||||
/// Returns a traversible list of outgoing edges. Its lifetime will be
|
||||
/// limited to a local borrow of `self`.
|
||||
pub fn get_child_list_mut<'s>(&'s mut self) -> MutChildList<'s, T, S, A> {
|
||||
MutChildList {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a traversible list of outgoing edges. Its lifetime will be
|
||||
/// limited to a local borrow of `self`.
|
||||
pub fn get_child_list_mut<'s>(&'s mut self) -> MutChildList<'s, T, S, A> {
|
||||
MutChildList { graph: self.graph, id: self.id, }
|
||||
/// Returns a traversible list of outgoing edges. `self` is consumed, and
|
||||
/// the return value's lifetime will be the same as that of `self`.
|
||||
pub fn to_child_list(self) -> MutChildList<'a, T, S, A> {
|
||||
MutChildList {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a traversible list of outgoing edges. `self` is consumed, and
|
||||
/// the return value's lifetime will be the same as that of `self`.
|
||||
pub fn to_child_list(self) -> MutChildList<'a, T, S, A> {
|
||||
MutChildList { graph: self.graph, id: self.id, }
|
||||
}
|
||||
/// Returns a traversible list of incoming edges. Its lifetime will be
|
||||
/// limited to a local borrow of `self`.
|
||||
pub fn get_parent_list<'s>(&'s self) -> ParentList<'s, T, S, A> {
|
||||
ParentList::new(self.graph, self.id)
|
||||
}
|
||||
|
||||
/// Returns a traversible list of incoming edges. Its lifetime will be
|
||||
/// limited to a local borrow of `self`.
|
||||
pub fn get_parent_list<'s>(&'s self) -> ParentList<'s, T, S, A> {
|
||||
ParentList::new(self.graph, self.id)
|
||||
/// Returns a traversible list of incoming edges. Its lifetime will be
|
||||
/// limited to a local borrow of `self`.
|
||||
pub fn get_parent_list_mut<'s>(&'s mut self) -> MutParentList<'s, T, S, A> {
|
||||
MutParentList {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a traversible list of incoming edges. Its lifetime will be
|
||||
/// limited to a local borrow of `self`.
|
||||
pub fn get_parent_list_mut<'s>(&'s mut self) -> MutParentList<'s, T, S, A> {
|
||||
MutParentList { graph: self.graph, id: self.id, }
|
||||
/// Returns a traversible list of outgoing edges. `self` is consumed, and
|
||||
/// the return value's lifetime will be the same as that of `self`.
|
||||
pub fn to_parent_list(self) -> MutParentList<'a, T, S, A> {
|
||||
MutParentList {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a traversible list of outgoing edges. `self` is consumed, and
|
||||
/// the return value's lifetime will be the same as that of `self`.
|
||||
pub fn to_parent_list(self) -> MutParentList<'a, T, S, A> {
|
||||
MutParentList { graph: self.graph, id: self.id, }
|
||||
}
|
||||
/// Returns a non-mutating node obtained by converting this node. `self` is
|
||||
/// consumed, and the return value's lifetime will be the same as that of
|
||||
/// `self`. The source graph is still considered to have a mutable borrow in
|
||||
/// play, but the resulting node can be cloned freely.
|
||||
pub fn to_node(self) -> Node<'a, T, S, A> {
|
||||
Node::new(self.graph, self.id)
|
||||
}
|
||||
|
||||
/// Returns a non-mutating node obtained by converting this node. `self` is
|
||||
/// consumed, and the return value's lifetime will be the same as that of
|
||||
/// `self`. The source graph is still considered to have a mutable borrow in
|
||||
/// play, but the resulting node can be cloned freely.
|
||||
pub fn to_node(self) -> Node<'a, T, S, A> {
|
||||
Node::new(self.graph, self.id)
|
||||
}
|
||||
/// Returns a non-mutating node obtained by borrowing this node. Returns a
|
||||
/// value whose lifetime is limited to a borrow of `self`.
|
||||
pub fn get_node<'s>(&'s self) -> Node<'s, T, S, A> {
|
||||
Node::new(self.graph, self.id)
|
||||
}
|
||||
|
||||
/// Returns a non-mutating node obtained by borrowing this node. Returns a
|
||||
/// value whose lifetime is limited to a borrow of `self`.
|
||||
pub fn get_node<'s>(&'s self) -> Node<'s, T, S, A> {
|
||||
Node::new(self.graph, self.id)
|
||||
}
|
||||
|
||||
/// Prunes the underlying graph by removing components not reachable from
|
||||
/// this node.
|
||||
pub fn retain_reachable(&mut self) {
|
||||
self.graph.retain_reachable_from_ids(&[self.id]);
|
||||
self.id = VertexId(0);
|
||||
}
|
||||
/// Prunes the underlying graph by removing components not reachable from
|
||||
/// this node.
|
||||
pub fn retain_reachable(&mut self) {
|
||||
self.graph.retain_reachable_from_ids(&[self.id]);
|
||||
self.id = VertexId(0);
|
||||
}
|
||||
}
|
||||
|
||||
/// A traversible list of a vertex's outgoing edges.
|
||||
pub struct MutChildList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
graph: &'a mut Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
pub struct MutChildList<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
graph: &'a mut Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
}
|
||||
|
||||
impl<'a, T, S, A> MutChildList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
fn vertex<'s>(&'s self) -> &'s RawVertex<S> {
|
||||
self.graph.get_vertex(self.id)
|
||||
}
|
||||
impl<'a, T, S, A> MutChildList<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
fn vertex<'s>(&'s self) -> &'s RawVertex<S> {
|
||||
self.graph.get_vertex(self.id)
|
||||
}
|
||||
|
||||
/// Returns the number of outgoing eges.
|
||||
pub fn len(&self) -> usize {
|
||||
self.vertex().children.len()
|
||||
}
|
||||
/// Returns the number of outgoing eges.
|
||||
pub fn len(&self) -> usize {
|
||||
self.vertex().children.len()
|
||||
}
|
||||
|
||||
/// Returns true iff there are no outgoing edges.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.vertex().children.is_empty()
|
||||
}
|
||||
/// Returns true iff there are no outgoing edges.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.vertex().children.is_empty()
|
||||
}
|
||||
|
||||
/// Returns an edge handle for the `i`th edge.
|
||||
pub fn get_edge<'s>(&'s self, i: usize) -> Edge<'s, T, S, A> {
|
||||
Edge::new(self.graph, self.vertex().children[i])
|
||||
}
|
||||
/// Returns an edge handle for the `i`th edge.
|
||||
pub fn get_edge<'s>(&'s self, i: usize) -> Edge<'s, T, S, A> {
|
||||
Edge::new(self.graph, self.vertex().children[i])
|
||||
}
|
||||
|
||||
/// Returns an edge handle for the `i`th edge. Its lifetime will be limited
|
||||
/// to a local borrow of `self`.
|
||||
pub fn get_edge_mut<'s>(&'s mut self, i: usize) -> MutEdge<'s, T, S, A> {
|
||||
let id = self.vertex().children[i];
|
||||
MutEdge { graph: self.graph, id: id, }
|
||||
/// Returns an edge handle for the `i`th edge. Its lifetime will be limited
|
||||
/// to a local borrow of `self`.
|
||||
pub fn get_edge_mut<'s>(&'s mut self, i: usize) -> MutEdge<'s, T, S, A> {
|
||||
let id = self.vertex().children[i];
|
||||
MutEdge {
|
||||
graph: self.graph,
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an edge handle for the `i`th `self` is consumed, and the return
|
||||
/// value's lifetime will be the same as that of `self`.
|
||||
pub fn to_edge(self, i: usize) -> MutEdge<'a, T, S, A> {
|
||||
let id = self.vertex().children[i];
|
||||
MutEdge { graph: self.graph, id: id, }
|
||||
/// Returns an edge handle for the `i`th `self` is consumed, and the return
|
||||
/// value's lifetime will be the same as that of `self`.
|
||||
pub fn to_edge(self, i: usize) -> MutEdge<'a, T, S, A> {
|
||||
let id = self.vertex().children[i];
|
||||
MutEdge {
|
||||
graph: self.graph,
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a node handle for the vertex these edges originate from. Its
|
||||
/// lifetime will be limited to a local borrow of `self`.
|
||||
pub fn get_source_node<'s>(&'s self) -> Node<'s, T, S, A> {
|
||||
Node::new(self.graph, self.id)
|
||||
/// Returns a node handle for the vertex these edges originate from. Its
|
||||
/// lifetime will be limited to a local borrow of `self`.
|
||||
pub fn get_source_node<'s>(&'s self) -> Node<'s, T, S, A> {
|
||||
Node::new(self.graph, self.id)
|
||||
}
|
||||
|
||||
/// Returns a mutable node handle for the vertex these edges originate
|
||||
/// from. Its lifetime will be limited to a local borrow of `self`.
|
||||
pub fn get_source_node_mut<'s>(&'s mut self) -> MutNode<'s, T, S, A> {
|
||||
MutNode {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a mutable node handle for the vertex these edges originate
|
||||
/// from. Its lifetime will be limited to a local borrow of `self`.
|
||||
pub fn get_source_node_mut<'s>(&'s mut self) -> MutNode<'s, T, S, A> {
|
||||
MutNode { graph: self.graph, id: self.id, }
|
||||
/// Returns a mutable node handle for the vertex these edges originate
|
||||
/// from. `self` is consumed, and the return value's lifetime will be the
|
||||
/// same as that of `self`.
|
||||
pub fn to_source_node(self) -> MutNode<'a, T, S, A> {
|
||||
MutNode {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a mutable node handle for the vertex these edges originate
|
||||
/// from. `self` is consumed, and the return value's lifetime will be the
|
||||
/// same as that of `self`.
|
||||
pub fn to_source_node(self) -> MutNode<'a, T, S, A> {
|
||||
MutNode { graph: self.graph, id: self.id, }
|
||||
/// Returns an iterator over child edges.
|
||||
pub fn iter<'s>(&'s self) -> ChildListIter<'s, T, S, A> {
|
||||
self.get_source_node().get_child_list().iter()
|
||||
}
|
||||
|
||||
/// Adds a child edge to the vertex labeled by `child_label`. If no such
|
||||
/// vertex exists, it is created and associated with the data returned by
|
||||
/// `f`. Returns a mutable edge handle for the new edge, with a lifetime
|
||||
/// limited to a borrow of `self`.
|
||||
pub fn add_child<'s, F>(&'s mut self, child_label: T, f: F, edge_data: A) -> MutEdge<'s, T, S, A>
|
||||
where
|
||||
F: FnOnce() -> S,
|
||||
{
|
||||
let target_id = match self
|
||||
.graph
|
||||
.state_ids
|
||||
.get_or_insert(child_label)
|
||||
.map(|s| *s.id())
|
||||
{
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
self.graph.add_raw_vertex(f());
|
||||
id
|
||||
}
|
||||
};
|
||||
let edge_id = self.graph.add_raw_edge(edge_data, self.id, target_id);
|
||||
MutEdge {
|
||||
graph: self.graph,
|
||||
id: edge_id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over child edges.
|
||||
pub fn iter<'s>(&'s self) -> ChildListIter<'s, T, S, A> {
|
||||
self.get_source_node().get_child_list().iter()
|
||||
/// Adds a child edge to the vertex labeled by `child_label`. If no such
|
||||
/// vertex exists, it is created and associated with the data returned by
|
||||
/// `f`. Returns a mutable edge handle for the new edge.
|
||||
pub fn to_add_child<F>(self, child_label: T, f: F, edge_data: A) -> MutEdge<'a, T, S, A>
|
||||
where
|
||||
F: FnOnce() -> S,
|
||||
{
|
||||
let target_id = match self
|
||||
.graph
|
||||
.state_ids
|
||||
.get_or_insert(child_label)
|
||||
.map(|s| *s.id())
|
||||
{
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
self.graph.add_raw_vertex(f());
|
||||
id
|
||||
}
|
||||
};
|
||||
let edge_id = self.graph.add_raw_edge(edge_data, self.id, target_id);
|
||||
MutEdge {
|
||||
graph: self.graph,
|
||||
id: edge_id,
|
||||
}
|
||||
|
||||
/// Adds a child edge to the vertex labeled by `child_label`. If no such
|
||||
/// vertex exists, it is created and associated with the data returned by
|
||||
/// `f`. Returns a mutable edge handle for the new edge, with a lifetime
|
||||
/// limited to a borrow of `self`.
|
||||
pub fn add_child<'s, F>(&'s mut self, child_label: T, f: F, edge_data: A)
|
||||
-> MutEdge<'s, T, S, A>
|
||||
where F: FnOnce() -> S {
|
||||
let target_id = match self.graph.state_ids.get_or_insert(child_label).map(|s| *s.id()) {
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
self.graph.add_raw_vertex(f());
|
||||
id
|
||||
},
|
||||
};
|
||||
let edge_id = self.graph.add_raw_edge(edge_data, self.id, target_id);
|
||||
MutEdge { graph: self.graph, id: edge_id, }
|
||||
}
|
||||
|
||||
/// Adds a child edge to the vertex labeled by `child_label`. If no such
|
||||
/// vertex exists, it is created and associated with the data returned by
|
||||
/// `f`. Returns a mutable edge handle for the new edge.
|
||||
pub fn to_add_child<F>(self, child_label: T, f: F, edge_data: A) -> MutEdge<'a, T, S, A>
|
||||
where F: FnOnce() -> S {
|
||||
let target_id = match self.graph.state_ids.get_or_insert(child_label).map(|s| *s.id()) {
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
self.graph.add_raw_vertex(f());
|
||||
id
|
||||
},
|
||||
};
|
||||
let edge_id = self.graph.add_raw_edge(edge_data, self.id, target_id);
|
||||
MutEdge { graph: self.graph, id: edge_id, }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A traversible list of a vertex's incoming edges.
|
||||
pub struct MutParentList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
graph: &'a mut Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
pub struct MutParentList<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
graph: &'a mut Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
}
|
||||
|
||||
impl<'a, T, S, A> MutParentList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
fn vertex<'s>(&'s self) -> &'s RawVertex<S> {
|
||||
self.graph.get_vertex(self.id)
|
||||
impl<'a, T, S, A> MutParentList<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
fn vertex<'s>(&'s self) -> &'s RawVertex<S> {
|
||||
self.graph.get_vertex(self.id)
|
||||
}
|
||||
|
||||
/// Returns the number of incoming edges.
|
||||
pub fn len(&self) -> usize {
|
||||
self.vertex().parents.len()
|
||||
}
|
||||
|
||||
/// Returns true iff there are no incoming edges.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.vertex().parents.is_empty()
|
||||
}
|
||||
|
||||
/// Returns a node handle for the vertex these edges originate terminate
|
||||
/// on. Its lifetime will be limited to a local borrow of `self`.
|
||||
pub fn get_target_node<'s>(&'s self) -> Node<'s, T, S, A> {
|
||||
Node::new(self.graph, self.id)
|
||||
}
|
||||
|
||||
/// Returns a mutable node handle for the vertex these edges terminate
|
||||
/// on. Its lifetime will be limited to a local borrow of `self`.
|
||||
pub fn get_target_node_mut<'s>(&'s mut self) -> MutNode<'s, T, S, A> {
|
||||
MutNode {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the number of incoming edges.
|
||||
pub fn len(&self) -> usize {
|
||||
self.vertex().parents.len()
|
||||
/// Returns a mutable node handle for the vertex these edges terminate
|
||||
/// on. `self` is consumed, and the return value's lifetime will be the same
|
||||
/// as that of `self`.
|
||||
pub fn to_target_node(self) -> MutNode<'a, T, S, A> {
|
||||
MutNode {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns true iff there are no incoming edges.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.vertex().parents.is_empty()
|
||||
/// Returns a handle to the `i`th edge. Its lifetime will be limited to a
|
||||
/// local borrow of `self`.
|
||||
pub fn get_edge<'s>(&'s self, i: usize) -> Edge<'s, T, S, A> {
|
||||
Edge::new(self.graph, self.vertex().parents[i])
|
||||
}
|
||||
|
||||
/// Returns a mutable handle to the `i`th edge. Its lifetime will be limited
|
||||
/// to a local borrow of `self`.
|
||||
pub fn get_edge_mut<'s>(&'s mut self, i: usize) -> MutEdge<'s, T, S, A> {
|
||||
let id = self.vertex().parents[i];
|
||||
MutEdge {
|
||||
graph: self.graph,
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a node handle for the vertex these edges originate terminate
|
||||
/// on. Its lifetime will be limited to a local borrow of `self`.
|
||||
pub fn get_target_node<'s>(&'s self) -> Node<'s, T, S, A> {
|
||||
Node::new(self.graph, self.id)
|
||||
/// Returns a mutable handle to the `i`th edge. `self` is consumed, and the
|
||||
/// return value's lifetime will be the same as that of `self`.
|
||||
pub fn to_edge(self, i: usize) -> MutEdge<'a, T, S, A> {
|
||||
let id = self.vertex().parents[i];
|
||||
MutEdge {
|
||||
graph: self.graph,
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a mutable node handle for the vertex these edges terminate
|
||||
/// on. Its lifetime will be limited to a local borrow of `self`.
|
||||
pub fn get_target_node_mut<'s>(&'s mut self) -> MutNode<'s, T, S, A> {
|
||||
MutNode { graph: self.graph, id: self.id, }
|
||||
/// Returns an iterator over parent edges.
|
||||
pub fn iter<'s>(&'s self) -> ParentListIter<'s, T, S, A> {
|
||||
self.get_target_node().get_parent_list().iter()
|
||||
}
|
||||
|
||||
/// Adds a parent edge to the vertex labeled by `parent_label`. If no such
|
||||
/// vertex exists, it is created and associated with the data returned by
|
||||
/// `f`. Returns a mutable edge handle for the new edge, with a lifetime
|
||||
/// limited to a borrow of `self`.
|
||||
pub fn add_parent<'s, F>(
|
||||
&'s mut self,
|
||||
parent_label: T,
|
||||
f: F,
|
||||
edge_data: A,
|
||||
) -> MutEdge<'s, T, S, A>
|
||||
where
|
||||
F: FnOnce() -> S,
|
||||
{
|
||||
let source_id = match self
|
||||
.graph
|
||||
.state_ids
|
||||
.get_or_insert(parent_label)
|
||||
.map(|s| *s.id())
|
||||
{
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
self.graph.add_raw_vertex(f());
|
||||
id
|
||||
}
|
||||
};
|
||||
let edge_id = self.graph.add_raw_edge(edge_data, source_id, self.id);
|
||||
MutEdge {
|
||||
graph: self.graph,
|
||||
id: edge_id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a mutable node handle for the vertex these edges terminate
|
||||
/// on. `self` is consumed, and the return value's lifetime will be the same
|
||||
/// as that of `self`.
|
||||
pub fn to_target_node(self) -> MutNode<'a, T, S, A> {
|
||||
MutNode { graph: self.graph, id: self.id, }
|
||||
/// Adds a parent edge to the vertex labeled by `parent_label`. If no such
|
||||
/// vertex exists, it is created and associated with the data returned by
|
||||
/// `f`. Returns a mutable edge handle for the new edge.
|
||||
pub fn to_add_parent<F>(self, parent_label: T, f: F, edge_data: A) -> MutEdge<'a, T, S, A>
|
||||
where
|
||||
F: FnOnce() -> S,
|
||||
{
|
||||
let source_id = match self
|
||||
.graph
|
||||
.state_ids
|
||||
.get_or_insert(parent_label)
|
||||
.map(|s| *s.id())
|
||||
{
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
self.graph.add_raw_vertex(f());
|
||||
id
|
||||
}
|
||||
};
|
||||
let edge_id = self.graph.add_raw_edge(edge_data, source_id, self.id);
|
||||
MutEdge {
|
||||
graph: self.graph,
|
||||
id: edge_id,
|
||||
}
|
||||
|
||||
/// Returns a handle to the `i`th edge. Its lifetime will be limited to a
|
||||
/// local borrow of `self`.
|
||||
pub fn get_edge<'s>(&'s self, i: usize) -> Edge<'s, T, S, A> {
|
||||
Edge::new(self.graph, self.vertex().parents[i])
|
||||
}
|
||||
|
||||
/// Returns a mutable handle to the `i`th edge. Its lifetime will be limited
|
||||
/// to a local borrow of `self`.
|
||||
pub fn get_edge_mut<'s>(&'s mut self, i: usize) -> MutEdge<'s, T, S, A> {
|
||||
let id = self.vertex().parents[i];
|
||||
MutEdge { graph: self.graph, id: id, }
|
||||
}
|
||||
|
||||
/// Returns a mutable handle to the `i`th edge. `self` is consumed, and the
|
||||
/// return value's lifetime will be the same as that of `self`.
|
||||
pub fn to_edge(self, i: usize) -> MutEdge<'a, T, S, A> {
|
||||
let id = self.vertex().parents[i];
|
||||
MutEdge { graph: self.graph, id: id, }
|
||||
}
|
||||
|
||||
/// Returns an iterator over parent edges.
|
||||
pub fn iter<'s>(&'s self) -> ParentListIter<'s, T, S, A> {
|
||||
self.get_target_node().get_parent_list().iter()
|
||||
}
|
||||
|
||||
/// Adds a parent edge to the vertex labeled by `parent_label`. If no such
|
||||
/// vertex exists, it is created and associated with the data returned by
|
||||
/// `f`. Returns a mutable edge handle for the new edge, with a lifetime
|
||||
/// limited to a borrow of `self`.
|
||||
pub fn add_parent<'s, F>(&'s mut self, parent_label: T, f: F, edge_data: A)
|
||||
-> MutEdge<'s, T, S, A>
|
||||
where F: FnOnce() -> S {
|
||||
let source_id = match self.graph.state_ids.get_or_insert(parent_label).map(|s| *s.id()) {
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
self.graph.add_raw_vertex(f());
|
||||
id
|
||||
},
|
||||
};
|
||||
let edge_id = self.graph.add_raw_edge(edge_data, source_id, self.id);
|
||||
MutEdge { graph: self.graph, id: edge_id, }
|
||||
}
|
||||
|
||||
/// Adds a parent edge to the vertex labeled by `parent_label`. If no such
|
||||
/// vertex exists, it is created and associated with the data returned by
|
||||
/// `f`. Returns a mutable edge handle for the new edge.
|
||||
pub fn to_add_parent<F>(self, parent_label: T, f: F, edge_data: A) -> MutEdge<'a, T, S, A>
|
||||
where F: FnOnce() -> S {
|
||||
let source_id = match self.graph.state_ids.get_or_insert(parent_label).map(|s| *s.id()) {
|
||||
Insertion::Present(id) => id,
|
||||
Insertion::New(id) => {
|
||||
self.graph.add_raw_vertex(f());
|
||||
id
|
||||
},
|
||||
};
|
||||
let edge_id = self.graph.add_raw_edge(edge_data, source_id, self.id);
|
||||
MutEdge { graph: self.graph, id: edge_id, }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Mutable handle to a graph edge ("edge handle") when edge expansion state is
|
||||
@ -349,94 +457,115 @@ impl<'a, T, S, A> MutParentList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S:
|
||||
/// mutation of graph topology (adding vertices). Vertices may be added to
|
||||
/// unexpanded edges using the handle returned by `get_target_mut` or
|
||||
/// `to_target`.
|
||||
pub struct MutEdge<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
graph: &'a mut Graph<T, S, A>,
|
||||
id: EdgeId,
|
||||
pub struct MutEdge<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
graph: &'a mut Graph<T, S, A>,
|
||||
id: EdgeId,
|
||||
}
|
||||
|
||||
impl<'a, T, S, A> MutEdge<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
/// Creates a new `MutEdge` for the given graph and gamestate. This method is
|
||||
/// not exported by the crate because it exposes implementation details.
|
||||
pub(crate) fn new(graph: &'a mut Graph<T, S, A>, id: EdgeId) -> Self {
|
||||
MutEdge { graph, id }
|
||||
}
|
||||
impl<'a, T, S, A> MutEdge<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
/// Creates a new `MutEdge` for the given graph and gamestate. This method is
|
||||
/// not exported by the crate because it exposes implementation details.
|
||||
pub(crate) fn new(graph: &'a mut Graph<T, S, A>, id: EdgeId) -> Self {
|
||||
MutEdge { graph, id }
|
||||
}
|
||||
|
||||
fn arc(&self) -> &RawEdge<A> {
|
||||
self.graph.get_arc(self.id)
|
||||
}
|
||||
fn arc(&self) -> &RawEdge<A> {
|
||||
self.graph.get_arc(self.id)
|
||||
}
|
||||
|
||||
fn arc_mut(&mut self) -> &mut RawEdge<A> {
|
||||
self.graph.get_arc_mut(self.id)
|
||||
}
|
||||
fn arc_mut(&mut self) -> &mut RawEdge<A> {
|
||||
self.graph.get_arc_mut(self.id)
|
||||
}
|
||||
|
||||
/// Returns an immutable ID that is guaranteed to identify this vertex
|
||||
/// uniquely within its graph. This ID may change when the graph is mutated.
|
||||
pub fn get_id(&self) -> usize {
|
||||
self.id.as_usize()
|
||||
}
|
||||
/// Returns an immutable ID that is guaranteed to identify this vertex
|
||||
/// uniquely within its graph. This ID may change when the graph is mutated.
|
||||
pub fn get_id(&self) -> usize {
|
||||
self.id.as_usize()
|
||||
}
|
||||
|
||||
/// Returns the data at this edge.
|
||||
pub fn get_data(&self) -> &A {
|
||||
&self.arc().data
|
||||
}
|
||||
/// Returns the data at this edge.
|
||||
pub fn get_data(&self) -> &A {
|
||||
&self.arc().data
|
||||
}
|
||||
|
||||
/// Returns the data at this edge, mutably.
|
||||
pub fn get_data_mut(&mut self) -> &mut A {
|
||||
&mut self.arc_mut().data
|
||||
}
|
||||
/// Returns the data at this edge, mutably.
|
||||
pub fn get_data_mut(&mut self) -> &mut A {
|
||||
&mut self.arc_mut().data
|
||||
}
|
||||
|
||||
/// Returns the target of this edge. If the edge is unexpanded, no data will
|
||||
/// be available. If it is expanded, a node handle will be available, with
|
||||
/// its lifetime limited to a local borrow of `self`.
|
||||
pub fn get_target<'s>(&'s self) -> Node<'s, T, S, A> {
|
||||
Node::new(self.graph, self.arc().target)
|
||||
}
|
||||
/// Returns the target of this edge. If the edge is unexpanded, no data will
|
||||
/// be available. If it is expanded, a node handle will be available, with
|
||||
/// its lifetime limited to a local borrow of `self`.
|
||||
pub fn get_target<'s>(&'s self) -> Node<'s, T, S, A> {
|
||||
Node::new(self.graph, self.arc().target)
|
||||
}
|
||||
|
||||
/// Returns the target of this edge. If the edge is unexpanded, an
|
||||
/// `EdgeExpander` will be provided. If it is expanded, a mutable node
|
||||
/// handle will be available. In both cases, lifetimes will be limited to a
|
||||
/// local borrow of `self`.
|
||||
pub fn get_target_mut<'s>(&'s mut self) -> MutNode<'s, T, S, A> {
|
||||
let id = self.arc().target;
|
||||
MutNode { graph: self.graph, id: id, }
|
||||
/// Returns the target of this edge. If the edge is unexpanded, an
|
||||
/// `EdgeExpander` will be provided. If it is expanded, a mutable node
|
||||
/// handle will be available. In both cases, lifetimes will be limited to a
|
||||
/// local borrow of `self`.
|
||||
pub fn get_target_mut<'s>(&'s mut self) -> MutNode<'s, T, S, A> {
|
||||
let id = self.arc().target;
|
||||
MutNode {
|
||||
graph: self.graph,
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the target of this edge. If the edge is unexpanded, an
|
||||
/// `EdgeExpander` will be provided. If it is expanded, a mutable node
|
||||
/// handle will be available. In both cases `self` is consumed, and the
|
||||
/// return value's lifetime will be the same as that of `self`.
|
||||
pub fn to_target(self) -> MutNode<'a, T, S, A> {
|
||||
let id = self.arc().target;
|
||||
MutNode { graph: self.graph, id: id, }
|
||||
/// Returns the target of this edge. If the edge is unexpanded, an
|
||||
/// `EdgeExpander` will be provided. If it is expanded, a mutable node
|
||||
/// handle will be available. In both cases `self` is consumed, and the
|
||||
/// return value's lifetime will be the same as that of `self`.
|
||||
pub fn to_target(self) -> MutNode<'a, T, S, A> {
|
||||
let id = self.arc().target;
|
||||
MutNode {
|
||||
graph: self.graph,
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a node handle for the source of this edge. Its lifetime will be
|
||||
/// limited to a local borrow of `self`.
|
||||
pub fn get_source<'s>(&'s self) -> Node<'s, T, S, A> {
|
||||
Node::new(self.graph, self.arc().source)
|
||||
}
|
||||
/// Returns a node handle for the source of this edge. Its lifetime will be
|
||||
/// limited to a local borrow of `self`.
|
||||
pub fn get_source<'s>(&'s self) -> Node<'s, T, S, A> {
|
||||
Node::new(self.graph, self.arc().source)
|
||||
}
|
||||
|
||||
/// Returns a mutable node handle for the source of this edge. Its lifetime
|
||||
/// will be limited to a local borrow of `self`.
|
||||
pub fn get_source_mut<'s>(&'s mut self) -> MutNode<'s, T, S, A> {
|
||||
let id = self.arc().source;
|
||||
MutNode { graph: self.graph, id: id, }
|
||||
/// Returns a mutable node handle for the source of this edge. Its lifetime
|
||||
/// will be limited to a local borrow of `self`.
|
||||
pub fn get_source_mut<'s>(&'s mut self) -> MutNode<'s, T, S, A> {
|
||||
let id = self.arc().source;
|
||||
MutNode {
|
||||
graph: self.graph,
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a mutable node handle for the source of this edge. `self` is
|
||||
/// consumed, and the return value's lifetime will be equal to that of
|
||||
/// `self`.
|
||||
pub fn to_source(self) -> MutNode<'a, T, S, A> {
|
||||
let id = self.arc().source;
|
||||
MutNode { graph: self.graph, id: id, }
|
||||
/// Returns a mutable node handle for the source of this edge. `self` is
|
||||
/// consumed, and the return value's lifetime will be equal to that of
|
||||
/// `self`.
|
||||
pub fn to_source(self) -> MutNode<'a, T, S, A> {
|
||||
let id = self.arc().source;
|
||||
MutNode {
|
||||
graph: self.graph,
|
||||
id: id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a non-mutating edge obtained by converting this edge. `self` is
|
||||
/// consumed, and the return value's lifetime will be the same as that of
|
||||
/// `self`. The source graph is still considered to have a mutable borrow in
|
||||
/// play, but the resulting edge can be cloned freely.
|
||||
pub fn to_edge(self) -> Edge<'a, T, S, A> {
|
||||
Edge::new(self.graph, self.id)
|
||||
}
|
||||
/// Returns a non-mutating edge obtained by converting this edge. `self` is
|
||||
/// consumed, and the return value's lifetime will be the same as that of
|
||||
/// `self`. The source graph is still considered to have a mutable borrow in
|
||||
/// play, but the resulting edge can be cloned freely.
|
||||
pub fn to_edge(self) -> Edge<'a, T, S, A> {
|
||||
Edge::new(self.graph, self.id)
|
||||
}
|
||||
}
|
||||
|
||||
|
495
src/nav.rs
495
src/nav.rs
@ -10,279 +10,378 @@
|
||||
use std::hash::Hash;
|
||||
use std::iter::Iterator;
|
||||
|
||||
use crate::base::{EdgeId, RawEdge, RawVertex, VertexId};
|
||||
use crate::Graph;
|
||||
use crate::base::{EdgeId, VertexId, RawEdge, RawVertex};
|
||||
use symbol_map::SymbolId;
|
||||
|
||||
/// Immutable handle to a graph vertex ("node handle").
|
||||
///
|
||||
/// This zipper-like type enables traversal of a graph along the vertex's
|
||||
/// incoming and outgoing edges.
|
||||
pub struct Node<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
graph: &'a Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
pub struct Node<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
graph: &'a Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
}
|
||||
|
||||
impl<'a, T, S, A> Node<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
/// Creates a new `Node` for the given graph and gamestate. This method is
|
||||
/// not exported by the crate because it exposes implementation details.
|
||||
pub(crate) fn new(graph: &'a Graph<T, S, A>, id: VertexId) -> Self {
|
||||
Node { graph, id }
|
||||
}
|
||||
impl<'a, T, S, A> Node<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
/// Creates a new `Node` for the given graph and gamestate. This method is
|
||||
/// not exported by the crate because it exposes implementation details.
|
||||
pub(crate) fn new(graph: &'a Graph<T, S, A>, id: VertexId) -> Self {
|
||||
Node { graph, id }
|
||||
}
|
||||
|
||||
fn children(&self) -> &'a [EdgeId] {
|
||||
&self.graph.get_vertex(self.id).children
|
||||
}
|
||||
fn children(&self) -> &'a [EdgeId] {
|
||||
&self.graph.get_vertex(self.id).children
|
||||
}
|
||||
|
||||
/// Returns the canonical label that is used to address this `Node`.
|
||||
///
|
||||
/// Graph instances which project multiple labels to the same vertex will
|
||||
/// consistently return a single value, regardless of which value was used
|
||||
/// to obtain this node handle.
|
||||
pub fn get_label(&self) -> &T {
|
||||
&self.graph.get_state(self.id).unwrap()
|
||||
}
|
||||
/// Returns the canonical label that is used to address this `Node`.
|
||||
///
|
||||
/// Graph instances which project multiple labels to the same vertex will
|
||||
/// consistently return a single value, regardless of which value was used
|
||||
/// to obtain this node handle.
|
||||
pub fn get_label(&self) -> &T {
|
||||
&self.graph.get_state(self.id).unwrap()
|
||||
}
|
||||
|
||||
/// Returns an immutable ID that is guaranteed to identify this vertex
|
||||
/// uniquely within its graph. This ID may change when the graph is mutated.
|
||||
pub fn get_id(&self) -> usize {
|
||||
self.id.as_usize()
|
||||
}
|
||||
/// Returns an immutable ID that is guaranteed to identify this vertex
|
||||
/// uniquely within its graph. This ID may change when the graph is mutated.
|
||||
pub fn get_id(&self) -> usize {
|
||||
self.id.as_usize()
|
||||
}
|
||||
|
||||
fn parents(&self) -> &'a [EdgeId] {
|
||||
&self.graph.get_vertex(self.id).parents
|
||||
}
|
||||
fn parents(&self) -> &'a [EdgeId] {
|
||||
&self.graph.get_vertex(self.id).parents
|
||||
}
|
||||
|
||||
/// Returns the data at this vertex.
|
||||
pub fn get_data(&self) -> &'a S {
|
||||
&self.graph.get_vertex(self.id).data
|
||||
}
|
||||
/// Returns the data at this vertex.
|
||||
pub fn get_data(&self) -> &'a S {
|
||||
&self.graph.get_vertex(self.id).data
|
||||
}
|
||||
|
||||
/// Returns true iff this vertex has no outgoing edges (regardless of
|
||||
/// whether they are expanded).
|
||||
pub fn is_leaf(&self) -> bool {
|
||||
self.children().is_empty()
|
||||
}
|
||||
/// Returns true iff this vertex has no outgoing edges (regardless of
|
||||
/// whether they are expanded).
|
||||
pub fn is_leaf(&self) -> bool {
|
||||
self.children().is_empty()
|
||||
}
|
||||
|
||||
/// Returns true iff this vertex has no incoming edges.
|
||||
pub fn is_root(&self) -> bool {
|
||||
self.parents().is_empty()
|
||||
}
|
||||
/// Returns true iff this vertex has no incoming edges.
|
||||
pub fn is_root(&self) -> bool {
|
||||
self.parents().is_empty()
|
||||
}
|
||||
|
||||
/// Returns a traversible list of outgoing edges.
|
||||
pub fn get_child_list(&self) -> ChildList<'a, T, S, A> {
|
||||
ChildList { graph: self.graph, id: self.id, }
|
||||
/// Returns a traversible list of outgoing edges.
|
||||
pub fn get_child_list(&self) -> ChildList<'a, T, S, A> {
|
||||
ChildList {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns a traversible list of incoming edges.
|
||||
pub fn get_parent_list(&self) -> ParentList<'a, T, S, A> {
|
||||
ParentList { graph: self.graph, id: self.id, }
|
||||
/// Returns a traversible list of incoming edges.
|
||||
pub fn get_parent_list(&self) -> ParentList<'a, T, S, A> {
|
||||
ParentList {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A traversible list of a vertex's outgoing edges.
|
||||
pub struct ChildList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
graph: &'a Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
pub struct ChildList<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
graph: &'a Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
}
|
||||
|
||||
impl<'a, T, S, A> ChildList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
/// Creates a new `ChildList` for the given graph and gamestate. This method
|
||||
/// is not exported by the crate because it exposes implementation details.
|
||||
pub(crate) fn new(graph: &'a Graph<T, S, A>, id: VertexId) -> Self {
|
||||
ChildList { graph, id }
|
||||
}
|
||||
impl<'a, T, S, A> ChildList<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
/// Creates a new `ChildList` for the given graph and gamestate. This method
|
||||
/// is not exported by the crate because it exposes implementation details.
|
||||
pub(crate) fn new(graph: &'a Graph<T, S, A>, id: VertexId) -> Self {
|
||||
ChildList { graph, id }
|
||||
}
|
||||
|
||||
fn vertex(&self) -> &'a RawVertex<S> {
|
||||
self.graph.get_vertex(self.id)
|
||||
}
|
||||
fn vertex(&self) -> &'a RawVertex<S> {
|
||||
self.graph.get_vertex(self.id)
|
||||
}
|
||||
|
||||
/// Returns the number of edges.
|
||||
pub fn len(&self) -> usize {
|
||||
self.vertex().children.len()
|
||||
}
|
||||
/// Returns the number of edges.
|
||||
pub fn len(&self) -> usize {
|
||||
self.vertex().children.len()
|
||||
}
|
||||
|
||||
/// Returns true iff there are no outgoing edges.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.vertex().children.is_empty()
|
||||
}
|
||||
/// Returns true iff there are no outgoing edges.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.vertex().children.is_empty()
|
||||
}
|
||||
|
||||
/// Returns a node handle for the vertex these edges originate from.
|
||||
pub fn get_source_node(&self) -> Node<'a, T, S, A> {
|
||||
Node { graph: self.graph, id: self.id, }
|
||||
/// Returns a node handle for the vertex these edges originate from.
|
||||
pub fn get_source_node(&self) -> Node<'a, T, S, A> {
|
||||
Node {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an edge handle for the `i`th edge.
|
||||
pub fn get_edge(&self, i: usize) -> Edge<'a, T, S, A> {
|
||||
Edge { graph: self.graph, id: self.vertex().children[i], }
|
||||
/// Returns an edge handle for the `i`th edge.
|
||||
pub fn get_edge(&self, i: usize) -> Edge<'a, T, S, A> {
|
||||
Edge {
|
||||
graph: self.graph,
|
||||
id: self.vertex().children[i],
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over child edges.
|
||||
pub fn iter(&self) -> ChildListIter<'a, T, S, A> {
|
||||
ChildListIter { graph: self.graph, id: self.id, i: 0, }
|
||||
/// Returns an iterator over child edges.
|
||||
pub fn iter(&self) -> ChildListIter<'a, T, S, A> {
|
||||
ChildListIter {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
i: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator over a vertex's child edges.
|
||||
pub struct ChildListIter<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
graph: &'a Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
i: usize,
|
||||
pub struct ChildListIter<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
graph: &'a Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
i: usize,
|
||||
}
|
||||
|
||||
impl <'a, T, S, A> ChildListIter<'a, T, S, A>
|
||||
where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
fn children(&self) -> &'a [EdgeId] {
|
||||
&self.graph.get_vertex(self.id).children
|
||||
}
|
||||
}
|
||||
impl<'a, T, S, A> ChildListIter<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
fn children(&self) -> &'a [EdgeId] {
|
||||
&self.graph.get_vertex(self.id).children
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, S, A> Iterator for ChildListIter<'a, T, S, A>
|
||||
where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
type Item = Edge<'a, T, S, A>;
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
type Item = Edge<'a, T, S, A>;
|
||||
|
||||
fn next(&mut self) -> Option<Edge<'a, T, S, A>> {
|
||||
let cs = self.children();
|
||||
if self.i >= cs.len() {
|
||||
None
|
||||
} else {
|
||||
let e = Edge::new(self.graph, cs[self.i]);
|
||||
self.i += 1;
|
||||
Some(e)
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let l = self.children().len();
|
||||
if l <= self.i {
|
||||
(0, Some(0))
|
||||
} else {
|
||||
(l - self.i, Some(l - self.i))
|
||||
}
|
||||
}
|
||||
fn next(&mut self) -> Option<Edge<'a, T, S, A>> {
|
||||
let cs = self.children();
|
||||
if self.i >= cs.len() {
|
||||
None
|
||||
} else {
|
||||
let e = Edge::new(self.graph, cs[self.i]);
|
||||
self.i += 1;
|
||||
Some(e)
|
||||
}
|
||||
}
|
||||
|
||||
/// A traversible list of a vertex's incoming edges.
|
||||
pub struct ParentList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
graph: &'a Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let l = self.children().len();
|
||||
if l <= self.i {
|
||||
(0, Some(0))
|
||||
} else {
|
||||
(l - self.i, Some(l - self.i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, S, A> ParentList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
/// Creates a new `ParentList` for the given graph and gamestate. This
|
||||
/// method is not exported by the crate because it exposes implementation
|
||||
/// details.
|
||||
pub(crate) fn new(graph: &'a Graph<T, S, A>, id: VertexId) -> Self {
|
||||
ParentList { graph, id, }
|
||||
}
|
||||
/// A traversible list of a vertex's incoming edges.
|
||||
pub struct ParentList<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
graph: &'a Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
}
|
||||
|
||||
fn vertex(&self) -> &'a RawVertex<S> {
|
||||
self.graph.get_vertex(self.id)
|
||||
}
|
||||
impl<'a, T, S, A> ParentList<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
/// Creates a new `ParentList` for the given graph and gamestate. This
|
||||
/// method is not exported by the crate because it exposes implementation
|
||||
/// details.
|
||||
pub(crate) fn new(graph: &'a Graph<T, S, A>, id: VertexId) -> Self {
|
||||
ParentList { graph, id }
|
||||
}
|
||||
|
||||
/// Returns the number of edges.
|
||||
pub fn len(&self) -> usize {
|
||||
self.vertex().parents.len()
|
||||
}
|
||||
fn vertex(&self) -> &'a RawVertex<S> {
|
||||
self.graph.get_vertex(self.id)
|
||||
}
|
||||
|
||||
/// Returns true iff there are no incoming edges.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.vertex().parents.is_empty()
|
||||
}
|
||||
/// Returns the number of edges.
|
||||
pub fn len(&self) -> usize {
|
||||
self.vertex().parents.len()
|
||||
}
|
||||
|
||||
/// Returns a node handle for the vertex these edges point to.
|
||||
pub fn target_node(&self) -> Node<'a, T, S, A> {
|
||||
Node { graph: self.graph, id: self.id, }
|
||||
}
|
||||
/// Returns true iff there are no incoming edges.
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.vertex().parents.is_empty()
|
||||
}
|
||||
|
||||
/// Returns an edge handle for the `i`th edge.
|
||||
pub fn get_edge(&self, i: usize) -> Edge<'a, T, S, A> {
|
||||
Edge { graph: self.graph, id: self.vertex().parents[i] }
|
||||
/// Returns a node handle for the vertex these edges point to.
|
||||
pub fn target_node(&self) -> Node<'a, T, S, A> {
|
||||
Node {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over parent edges.
|
||||
pub fn iter(&self) -> ParentListIter<'a, T, S, A> {
|
||||
ParentListIter { graph: self.graph, id: self.id, i: 0, }
|
||||
/// Returns an edge handle for the `i`th edge.
|
||||
pub fn get_edge(&self, i: usize) -> Edge<'a, T, S, A> {
|
||||
Edge {
|
||||
graph: self.graph,
|
||||
id: self.vertex().parents[i],
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns an iterator over parent edges.
|
||||
pub fn iter(&self) -> ParentListIter<'a, T, S, A> {
|
||||
ParentListIter {
|
||||
graph: self.graph,
|
||||
id: self.id,
|
||||
i: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Iterator over a vertex's parent edges.
|
||||
pub struct ParentListIter<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
graph: &'a Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
i: usize,
|
||||
pub struct ParentListIter<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
graph: &'a Graph<T, S, A>,
|
||||
id: VertexId,
|
||||
i: usize,
|
||||
}
|
||||
|
||||
impl<'a, T, S, A> ParentListIter<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
fn parents(&self) -> &'a [EdgeId] {
|
||||
&self.graph.get_vertex(self.id).parents
|
||||
}
|
||||
impl<'a, T, S, A> ParentListIter<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
fn parents(&self) -> &'a [EdgeId] {
|
||||
&self.graph.get_vertex(self.id).parents
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T, S, A> Iterator for ParentListIter<'a, T, S, A>
|
||||
where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
type Item = Edge<'a, T, S, A>;
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
type Item = Edge<'a, T, S, A>;
|
||||
|
||||
fn next(&mut self) -> Option<Edge<'a, T, S, A>> {
|
||||
let ps = self.parents();
|
||||
if self.i >= ps.len() {
|
||||
None
|
||||
} else {
|
||||
let e = Edge::new(self.graph, ps[self.i]);
|
||||
self.i += 1;
|
||||
Some(e)
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let l = self.parents().len();
|
||||
if l <= self.i {
|
||||
(0, Some(0))
|
||||
} else {
|
||||
(l - self.i, Some(l - self.i))
|
||||
}
|
||||
}
|
||||
fn next(&mut self) -> Option<Edge<'a, T, S, A>> {
|
||||
let ps = self.parents();
|
||||
if self.i >= ps.len() {
|
||||
None
|
||||
} else {
|
||||
let e = Edge::new(self.graph, ps[self.i]);
|
||||
self.i += 1;
|
||||
Some(e)
|
||||
}
|
||||
}
|
||||
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let l = self.parents().len();
|
||||
if l <= self.i {
|
||||
(0, Some(0))
|
||||
} else {
|
||||
(l - self.i, Some(l - self.i))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Immutable handle to a graph edge ("edge handle").
|
||||
///
|
||||
/// This zipper-like type enables traversal of a graph along the edge's source
|
||||
/// and target vertices.
|
||||
pub struct Edge<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
graph: &'a Graph<T, S, A>,
|
||||
id: EdgeId,
|
||||
pub struct Edge<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
graph: &'a Graph<T, S, A>,
|
||||
id: EdgeId,
|
||||
}
|
||||
|
||||
impl<'a, T, S, A> Edge<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
|
||||
/// Creates a new `Edge` for the given graph and gamestate. This method is
|
||||
/// not exported by the crate because it exposes implementation details.
|
||||
pub(crate) fn new(graph: &'a Graph<T, S, A>, id: EdgeId) -> Edge<'a, T, S, A> {
|
||||
Edge { graph, id }
|
||||
}
|
||||
fn arc(&self) -> &'a RawEdge<A> {
|
||||
self.graph.get_arc(self.id)
|
||||
}
|
||||
impl<'a, T, S, A> Edge<'a, T, S, A>
|
||||
where
|
||||
T: Hash + Eq + Clone + 'a,
|
||||
S: 'a,
|
||||
A: 'a,
|
||||
{
|
||||
/// Creates a new `Edge` for the given graph and gamestate. This method is
|
||||
/// not exported by the crate because it exposes implementation details.
|
||||
pub(crate) fn new(graph: &'a Graph<T, S, A>, id: EdgeId) -> Edge<'a, T, S, A> {
|
||||
Edge { graph, id }
|
||||
}
|
||||
fn arc(&self) -> &'a RawEdge<A> {
|
||||
self.graph.get_arc(self.id)
|
||||
}
|
||||
|
||||
/// Returns an immutable ID that is guaranteed to identify this edge
|
||||
/// uniquely within its graph. This ID may change when the graph is
|
||||
/// mutated.
|
||||
pub fn get_id(&self) -> usize {
|
||||
self.id.as_usize()
|
||||
}
|
||||
/// Returns an immutable ID that is guaranteed to identify this edge
|
||||
/// uniquely within its graph. This ID may change when the graph is
|
||||
/// mutated.
|
||||
pub fn get_id(&self) -> usize {
|
||||
self.id.as_usize()
|
||||
}
|
||||
|
||||
/// Returns the data at this edge.
|
||||
pub fn get_data(&self) -> &'a A {
|
||||
&self.arc().data
|
||||
}
|
||||
/// Returns the data at this edge.
|
||||
pub fn get_data(&self) -> &'a A {
|
||||
&self.arc().data
|
||||
}
|
||||
|
||||
/// Returns a node handle for this edge's source vertex.
|
||||
pub fn get_source(&self) -> Node<'a, T, S, A> {
|
||||
Node { graph: self.graph, id: self.arc().source, }
|
||||
/// Returns a node handle for this edge's source vertex.
|
||||
pub fn get_source(&self) -> Node<'a, T, S, A> {
|
||||
Node {
|
||||
graph: self.graph,
|
||||
id: self.arc().source,
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns the target of this edge. If the edge is unexpanded, no data will
|
||||
/// be available. If it is expanded, a node handle will be available.
|
||||
pub fn get_target(&self) -> Node<'a, T, S, A> {
|
||||
Node { graph: self.graph, id: self.arc().target, }
|
||||
/// Returns the target of this edge. If the edge is unexpanded, no data will
|
||||
/// be available. If it is expanded, a node handle will be available.
|
||||
pub fn get_target(&self) -> Node<'a, T, S, A> {
|
||||
Node {
|
||||
graph: self.graph,
|
||||
id: self.arc().target,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1204
src/search.rs
1204
src/search.rs
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user