use crate::graph::*;
pub trait TaggedGraph {
type LowerGraph;
type Vertex;
type Edge: Edge;
fn lower_graph(&self) -> &Self::LowerGraph;
fn vertex_by_id(&self, vid: &VertexId) -> Option<&Self::Vertex>;
fn id_by_vertex(&self, vert: &Self::Vertex) -> Option<VertexId>;
fn edge_by_id(&self, eid: &EdgeId) -> Option<&Self::Edge>;
fn id_by_edge(&self, edge: &Self::Edge) -> Option<EdgeId>;
fn contains_vertex_by_id(&self, vid: &VertexId) -> bool {
self.vertex_by_id(vid).is_some()
}
fn contains_vertex(&self, vert: &Self::Vertex) -> bool {
self.id_by_vertex(vert).is_some()
}
fn contains_edge_by_id(&self, eid: &EdgeId) -> bool {
self.edge_by_id(eid).is_some()
}
fn contains_edge(&self, edge: &Self::Edge) -> bool {
self.id_by_edge(edge).is_some()
}
}
pub trait QueryableTaggedGraph: TaggedGraph
where
Self::LowerGraph: QueryableGraph,
{
fn vertex_size(&self) -> usize;
fn iter_vertices(&self) -> Box<dyn Iterator<Item = (VertexId, &Self::Vertex)> + '_>;
fn edge_size(&self) -> usize;
fn iter_edges(&self) -> Box<dyn Iterator<Item = (crate::graph::Edge, &Self::Edge)> + '_>;
fn edges_connecting(
&self,
source: &VertexId,
sink: &VertexId,
) -> Box<dyn Iterator<Item = (crate::graph::Edge, &Self::Edge)> + '_>;
fn in_edges(
&self,
vid: &VertexId,
) -> Box<dyn Iterator<Item = (crate::graph::Edge, &Self::Edge)> + '_>;
fn out_edges(
&self,
vid: &VertexId,
) -> Box<dyn Iterator<Item = (crate::graph::Edge, &Self::Edge)> + '_>;
}
pub trait GrowableTaggedGraph: TaggedGraph
where
Self::LowerGraph: GrowableGraph,
{
fn new() -> Self;
fn overwrite_vertex(&mut self, vert: Self::Vertex) -> VertexId;
fn add_edge(&mut self, edge: Self::Edge) -> EdgeId;
fn update_edge(&mut self, eid: EdgeId, edge: Self::Edge);
}
pub trait EdgeShrinkableTaggedGraph: TaggedGraph
where
Self::LowerGraph: EdgeShrinkableGraph,
{
fn remove_edge(&mut self, eid: &EdgeId) -> Option<Self::Edge>;
}
pub trait VertexShrinkableTaggedGraph: TaggedGraph
where
Self::LowerGraph: VertexShrinkableGraph,
{
fn remove_vertex(
&mut self,
vid: &VertexId,
) -> Box<dyn Iterator<Item = (EdgeId, Self::Edge)> + '_>;
}
pub trait Edge {
fn source(&self) -> VertexId;
fn sink(&self) -> VertexId;
}
pub trait DebuggableTaggedGraph
where
Self: QueryableTaggedGraph + DirectedOrNot + Sized,
Self::LowerGraph: QueryableGraph + DirectedOrNot,
Self::Vertex: std::fmt::Debug,
Self::Edge: std::fmt::Debug,
{
fn debug(&self) -> GraphDebug<'_, Self> {
self.debug_with_indent(0, 2)
}
fn debug_with_indent(&self, init: usize, indent: usize) -> GraphDebug<'_, Self> {
GraphDebug {
graph: self,
indent: crate::util::Indention {
spaces: init,
step: indent,
},
}
}
}
impl<G> DebuggableTaggedGraph for G
where
G: QueryableTaggedGraph + DirectedOrNot + Sized,
G::LowerGraph: QueryableGraph + DirectedOrNot,
G::Vertex: std::fmt::Debug,
G::Edge: std::fmt::Debug,
{
}
pub struct GraphDebug<'a, G>
where
G: QueryableTaggedGraph + DirectedOrNot,
G::LowerGraph: QueryableGraph + DirectedOrNot,
G::Vertex: std::fmt::Debug,
G::Edge: std::fmt::Debug,
{
graph: &'a G,
indent: crate::util::Indention,
}
impl<'a, G> std::fmt::Debug for GraphDebug<'a, G>
where
G: QueryableTaggedGraph + DirectedOrNot,
G::LowerGraph: QueryableGraph + DirectedOrNot,
G::Vertex: std::fmt::Debug,
G::Edge: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let indent = &self.indent;
let nxt_indent = self.indent.one_more_level();
for (vid, vert) in self.graph.iter_vertices() {
writeln!(f, "{indent}{:?}", vert)?;
for (lower_edge, upper_edge) in self.graph.out_edges(&vid) {
writeln!(
f,
"{nxt_indent}--{:?}-> {:?}",
upper_edge,
self.graph.vertex_by_id(&lower_edge.sink).unwrap()
)?;
}
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use crate::{graph::*, tagged::*};
#[test]
fn undirected_graph_debug() {
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
struct E {
source: VertexId,
sink: VertexId,
}
impl crate::tagged::Edge for E {
fn source(&self) -> VertexId {
self.source
}
fn sink(&self) -> VertexId {
self.sink
}
}
let mut g = NaiveTaggedGraph::<String, E, undirected::TreeBackedGraph>::new();
let vertices = ["a".to_string(), "b".to_string(), "c".to_string()];
let mut vert_iter0 = vertices.iter();
while let Some(v0) = vert_iter0.next() {
let vid0 = g.overwrite_vertex(v0.clone());
for v1 in vert_iter0.clone() {
let vid1 = g.overwrite_vertex(v1.clone());
g.add_edge(E {
source: vid0,
sink: vid1,
});
}
}
println!("{:?}", g.debug());
use std::fmt::Write;
let mut out = String::new();
write!(&mut out, "{:?}", g.debug()).unwrap();
assert_eq!(
out,
r#""a"
--E { source: VertexId(0), sink: VertexId(1) }-> "b"
--E { source: VertexId(0), sink: VertexId(2) }-> "c"
"b"
--E { source: VertexId(0), sink: VertexId(1) }-> "a"
--E { source: VertexId(1), sink: VertexId(2) }-> "c"
"c"
--E { source: VertexId(0), sink: VertexId(2) }-> "a"
--E { source: VertexId(1), sink: VertexId(2) }-> "b"
"#
);
}
}