use crate::adjacencies::{InEdges, Neighbors, OutEdges};
use std::rc::Rc;
pub mod refs;
pub trait GraphIterator<G: ?Sized>: Clone {
type Item;
fn next(&mut self, g: &G) -> Option<Self::Item>;
fn size_hint(&self, _g: &G) -> (usize, Option<usize>) {
(0, None)
}
fn count(mut self, g: &G) -> usize {
let mut c = 0;
while self.next(g).is_some() {
c += 1
}
c
}
fn iter(self, g: &G) -> GraphIter<G, Self>
where
G: Sized,
{
GraphIter(self, g)
}
}
pub struct GraphIter<'a, G, I>(pub(crate) I, pub(crate) &'a G);
impl<'a, G, I> Clone for GraphIter<'a, G, I>
where
I: Clone,
{
fn clone(&self) -> Self {
GraphIter(self.0.clone(), self.1)
}
}
impl<'a, G, I> Iterator for GraphIter<'a, G, I>
where
I: GraphIterator<G>,
{
type Item = I::Item;
fn next(&mut self) -> Option<Self::Item> {
self.0.next(self.1)
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.0.size_hint(self.1)
}
fn count(self) -> usize {
self.0.count(self.1)
}
}
pub trait GraphType {
type Node<'a>: Copy + Eq;
type Edge<'a>: Copy + Eq;
}
pub type NodeIterator<'a, G> = GraphIter<'a, G, <G as FiniteGraph>::NodeIt<'a>>;
pub type EdgeIterator<'a, G> = GraphIter<'a, G, <G as FiniteGraph>::EdgeIt<'a>>;
pub trait FiniteGraph: GraphType {
type NodeIt<'a>: GraphIterator<Self, Item = Self::Node<'a>>
where
Self: 'a;
type EdgeIt<'a>: GraphIterator<Self, Item = Self::Edge<'a>>
where
Self: 'a;
fn num_nodes(&self) -> usize;
fn num_edges(&self) -> usize;
fn nodes_iter(&self) -> Self::NodeIt<'_>;
fn nodes(&self) -> NodeIterator<'_, Self>
where
Self: Sized,
{
GraphIter(self.nodes_iter(), self)
}
fn edges_iter(&self) -> Self::EdgeIt<'_>;
fn edges(&self) -> EdgeIterator<Self>
where
Self: Sized,
{
GraphIter(self.edges_iter(), self)
}
fn enodes(&self, e: Self::Edge<'_>) -> (Self::Node<'_>, Self::Node<'_>);
}
pub trait FiniteDigraph: FiniteGraph {
fn src(&self, e: Self::Edge<'_>) -> Self::Node<'_>;
fn snk(&self, e: Self::Edge<'_>) -> Self::Node<'_>;
}
type NeighIterator<'a, G> = GraphIter<'a, G, <G as Undirected>::NeighIt<'a>>;
pub trait Undirected: GraphType {
type NeighIt<'a>: GraphIterator<Self, Item = (Self::Edge<'a>, Self::Node<'a>)>
where
Self: 'a;
fn neigh_iter(&self, u: Self::Node<'_>) -> Self::NeighIt<'_>;
fn neighs(&self, u: Self::Node<'_>) -> NeighIterator<Self>
where
Self: Sized,
{
self.neigh_iter(u).iter(self)
}
fn neighbors(&self) -> Neighbors<Self>
where
Self: Sized,
{
Neighbors(self)
}
}
pub trait DirectedEdge {
type Edge;
fn is_incoming(&self) -> bool;
fn is_outgoing(&self) -> bool {
!self.is_incoming()
}
fn edge(&self) -> Self::Edge;
}
type OutIterator<'a, G> = GraphIter<'a, G, <G as Directed>::OutIt<'a>>;
type InIterator<'a, G> = GraphIter<'a, G, <G as Directed>::InIt<'a>>;
type IncidentIterator<'a, G> = GraphIter<'a, G, <G as Directed>::IncidentIt<'a>>;
pub trait Directed: Undirected {
type OutIt<'a>: GraphIterator<Self, Item = (Self::Edge<'a>, Self::Node<'a>)>
where
Self: 'a;
type InIt<'a>: GraphIterator<Self, Item = (Self::Edge<'a>, Self::Node<'a>)>
where
Self: 'a;
type IncidentIt<'a>: GraphIterator<Self, Item = (Self::DirectedEdge<'a>, Self::Node<'a>)>
where
Self: 'a;
type DirectedEdge<'a>: DirectedEdge<Edge = Self::Edge<'a>> + Copy + Eq
where
Self: 'a;
fn out_iter(&self, u: Self::Node<'_>) -> Self::OutIt<'_>;
fn outedges(&self, u: Self::Node<'_>) -> OutIterator<Self>
where
Self: Sized,
{
GraphIter(self.out_iter(u), self)
}
fn outgoing(&self) -> OutEdges<Self>
where
Self: Sized,
{
OutEdges(self)
}
fn in_iter(&self, u: Self::Node<'_>) -> Self::InIt<'_>;
fn inedges(&self, u: Self::Node<'_>) -> InIterator<Self>
where
Self: Sized,
{
GraphIter(self.in_iter(u), self)
}
fn incoming(&self) -> InEdges<Self>
where
Self: Sized,
{
InEdges(self)
}
fn incident_iter(&self, u: Self::Node<'_>) -> Self::IncidentIt<'_>;
fn incident_edges(&self, u: Self::Node<'_>) -> IncidentIterator<Self>
where
Self: Sized,
{
GraphIter(self.incident_iter(u), self)
}
}
pub trait Graph: FiniteGraph + Undirected {}
impl<G> Graph for G where G: FiniteGraph + Undirected {}
pub trait Digraph: Graph + FiniteDigraph + Directed {}
impl<G> Digraph for G where G: FiniteDigraph + Directed {}
pub trait Indexable {
fn index(&self) -> usize;
}
pub trait IndexGraph: Graph {
fn node_id(&self, u: Self::Node<'_>) -> usize;
fn id2node(&self, id: usize) -> Self::Node<'_>;
fn edge_id(&self, e: Self::Edge<'_>) -> usize;
fn id2edge(&self, id: usize) -> Self::Edge<'_>;
}
pub trait IndexDigraph: IndexGraph + Digraph {}
impl<T> IndexDigraph for T where T: IndexGraph + Digraph {}
pub trait NumberedGraph: Graph
where
for<'a> <Self as GraphType>::Node<'a>: Indexable,
for<'a> <Self as GraphType>::Edge<'a>: Indexable,
{
}
impl<G> NumberedGraph for G
where
G: Graph,
for<'a> G::Node<'a>: Indexable,
for<'a> G::Edge<'a>: Indexable,
{
}
pub trait NumberedDigraph: NumberedGraph + Digraph
where
for<'a> <Self as GraphType>::Node<'a>: Indexable,
for<'a> <Self as GraphType>::Edge<'a>: Indexable,
{
}
impl<G> NumberedDigraph for G
where
G: Digraph + NumberedGraph,
for<'a> G::Node<'a>: Indexable,
for<'a> G::Edge<'a>: Indexable,
{
}
impl<'g, G> GraphType for &'g G
where
G: GraphType,
{
type Node<'a> = G::Node<'a>;
type Edge<'a> = G::Edge<'a>;
}
impl<'g, G> FiniteGraph for &'g G
where
G: FiniteGraph,
{
type NodeIt<'a> = refs::WrapIt<G::NodeIt<'a>>
where
G: 'a,
'g: 'a;
type EdgeIt<'a> = refs::WrapIt<G::EdgeIt<'a>>
where
G: 'a,
'g: 'a;
fn num_nodes(&self) -> usize {
(*self).num_nodes()
}
fn nodes_iter(&self) -> Self::NodeIt<'_> {
(*self).nodes_iter().into()
}
fn num_edges(&self) -> usize {
(*self).num_edges()
}
fn edges_iter(&self) -> Self::EdgeIt<'_> {
(*self).edges_iter().into()
}
fn enodes(&self, e: Self::Edge<'_>) -> (Self::Node<'_>, Self::Node<'_>) {
(*self).enodes(e)
}
}
impl<'g, G> Undirected for &'g G
where
G: Undirected,
{
type NeighIt<'a> = refs::WrapIt<G::NeighIt<'a>>
where
G: 'a,
'g: 'a;
fn neigh_iter(&self, u: Self::Node<'_>) -> Self::NeighIt<'_> {
(*self).neigh_iter(u).into()
}
}
impl<'g, G> Directed for &'g G
where
G: Directed,
{
type OutIt<'a> = refs::WrapIt<G::OutIt<'a>>
where
G: 'a,
'g: 'a;
type InIt<'a> = refs::WrapIt<G::InIt<'a>>
where
G: 'a,
'g: 'a;
type IncidentIt<'a> = refs::WrapIt<G::IncidentIt<'a>>
where
G: 'a,
'g: 'a;
type DirectedEdge<'a> = G::DirectedEdge<'a>
where
Self: 'a;
fn out_iter(&self, u: Self::Node<'_>) -> Self::OutIt<'_> {
(*self).out_iter(u).into()
}
fn in_iter(&self, u: Self::Node<'_>) -> Self::InIt<'_> {
(*self).in_iter(u).into()
}
fn incident_iter(&self, u: Self::Node<'_>) -> Self::IncidentIt<'_> {
(*self).incident_iter(u).into()
}
}
impl<'g, G> FiniteDigraph for &'g G
where
G: FiniteDigraph,
{
fn src(&self, e: Self::Edge<'_>) -> Self::Node<'_> {
(*self).src(e)
}
fn snk(&self, e: Self::Edge<'_>) -> Self::Node<'_> {
(*self).snk(e)
}
}
impl<'g, G> IndexGraph for &'g G
where
G: IndexGraph,
{
fn node_id(&self, u: Self::Node<'_>) -> usize {
(*self).node_id(u)
}
fn edge_id(&self, e: Self::Edge<'_>) -> usize {
(*self).edge_id(e)
}
fn id2node(&self, id: usize) -> Self::Node<'_> {
(*self).id2node(id)
}
fn id2edge(&self, id: usize) -> Self::Edge<'_> {
(*self).id2edge(id)
}
}
impl<G, I> GraphIterator<Rc<G>> for refs::WrapIt<I>
where
I: GraphIterator<G>,
{
type Item = I::Item;
fn next(&mut self, g: &Rc<G>) -> Option<Self::Item> {
self.0.next(g.as_ref())
}
fn size_hint(&self, g: &Rc<G>) -> (usize, Option<usize>) {
self.0.size_hint(g.as_ref())
}
fn count(self, g: &Rc<G>) -> usize {
self.0.count(g.as_ref())
}
}
impl<G> GraphType for Rc<G>
where
G: GraphType,
{
type Node<'a> = G::Node<'a>;
type Edge<'a> = G::Edge<'a>;
}
impl<G> FiniteGraph for Rc<G>
where
G: FiniteGraph,
{
type NodeIt<'a> = refs::WrapIt<G::NodeIt<'a>>
where
G: 'a;
type EdgeIt<'a> = refs::WrapIt<G::EdgeIt<'a>>
where
G: 'a;
fn num_nodes(&self) -> usize {
self.as_ref().num_nodes()
}
fn nodes_iter(&self) -> Self::NodeIt<'_> {
self.as_ref().nodes_iter().into()
}
fn num_edges(&self) -> usize {
self.as_ref().num_edges()
}
fn edges_iter(&self) -> Self::EdgeIt<'_> {
self.as_ref().edges_iter().into()
}
fn enodes(&self, e: Self::Edge<'_>) -> (Self::Node<'_>, Self::Node<'_>) {
self.as_ref().enodes(e)
}
}
impl<G> FiniteDigraph for Rc<G>
where
G: FiniteDigraph,
{
fn src(&self, e: Self::Edge<'_>) -> Self::Node<'_> {
self.as_ref().src(e)
}
fn snk(&self, e: Self::Edge<'_>) -> Self::Node<'_> {
self.as_ref().snk(e)
}
}
impl<G> Undirected for Rc<G>
where
G: Undirected,
{
type NeighIt<'a> = refs::WrapIt<G::NeighIt<'a>>
where
G: 'a;
fn neigh_iter(&self, u: Self::Node<'_>) -> Self::NeighIt<'_> {
self.as_ref().neigh_iter(u).into()
}
}
impl<G> Directed for Rc<G>
where
G: Directed,
{
type OutIt<'a> = refs::WrapIt<G::OutIt<'a>>
where
G: 'a;
type InIt<'a> = refs::WrapIt<G::InIt<'a>>
where
G: 'a;
type IncidentIt<'a> = refs::WrapIt<G::IncidentIt<'a>>
where
G: 'a;
type DirectedEdge<'a> = G::DirectedEdge<'a>
where
G: 'a;
fn out_iter(&self, u: Self::Node<'_>) -> Self::OutIt<'_> {
self.as_ref().out_iter(u).into()
}
fn in_iter(&self, u: Self::Node<'_>) -> Self::InIt<'_> {
self.as_ref().in_iter(u).into()
}
fn incident_iter(&self, u: Self::Node<'_>) -> Self::IncidentIt<'_> {
self.as_ref().incident_iter(u).into()
}
}
impl<G> IndexGraph for Rc<G>
where
G: IndexGraph,
{
fn node_id(&self, u: Self::Node<'_>) -> usize {
self.as_ref().node_id(u)
}
fn edge_id(&self, e: Self::Edge<'_>) -> usize {
self.as_ref().edge_id(e)
}
fn id2node(&self, id: usize) -> Self::Node<'_> {
self.as_ref().id2node(id)
}
fn id2edge(&self, id: usize) -> Self::Edge<'_> {
self.as_ref().id2edge(id)
}
}