hypergraphx 0.0.5

A hypergraph library for Rust, based on the Python library of the same name.
Documentation
/*
    appellation: hypergraph <module>
    authors: @FL03
*/
//! This module is heavily inspired by the `rshyper` crate.
//!

/// the [`hypergraph`] macro works to aide the in the creation of hypergraphs by allowing
/// users to define nodes and edges in a hypergraph in a more declarative way.
///
/// ## Example
///
/// ### Basic Usage
///
/// The `hypergraph` macro allows you to define nodes and edges in a hypergraph
///
/// ```rust
/// use hypergraphx::prelude::*;
/// // initialize a new undirected hypergraph
/// let mut graph = UndirectedHypergraph::<usize, usize>::new();
/// // use the macro to insert nodes and edges into the graph
/// hypergraph! {
///     graph {
///         nodes: {
///             let v0 = 0;
///             let v1 = 1;
///             let v2 = 10;
///         };
///         edges: {
///             let e0: [v0, v1];
///             [v0, v1, v2] = 10;
///         };
///     }
/// }
/// ```
///
/// or
///
/// ```rust
/// use hypergraph::prelude::*;
///
/// // use the macro to initialize a new hypergraph, then insert nodes and edges
/// hypergraph! {
///     let mut graph: UndirectedHypergraph<usize, usize> {
///         nodes: {
///             let v0 = 0;
///             let v1 = 1;
///             let v2 = 2;
///         };
///         edges: {
///             let e0: [v0, v1] = 5;
///             let e1: [v0, v2] = 7;
///             [v0, v1, v2] = 10;
///         };
///     }
/// }
#[cfg(feature = "macros")]
#[macro_export]
macro_rules! hypergraph {
    (
        let mut $graph:ident: $H:ty {
            nodes: {$($nodes:tt)*};
            edges: {$($edges:tt)*};
        }
    ) => {
        // initialize a new hypergraph with the given type
        let mut $graph: $H = <$H>::new();
        // insert nodes into the graph
        $crate::hypernode!($graph {$($nodes)*});
        // insert edges into the graph
        $crate::hyperedge!($graph {$($edges)*});
    };
    (
        $graph:ident {
            nodes: {$($nodes:tt)*};
            edges: {$($edges:tt)*};
        }
    ) => {
        // insert nodes into the graph
        $crate::hypernode!($graph {$($nodes)*});
        // insert edges into the graph
        $crate::hyperedge!($graph {$($edges)*});
    };
}
/// The `hyperedge` macro streamlines the definition of hyperedges in a hypergraph.
///
/// ## Usage
///
/// The macro requires that you to pass a mutable reference to some hypergraph by first
/// defining the ident of the associated graph. Once declared, hyperedges are defined as `let`
/// statement within a block, where each statement defines a hyperedge by its name and the
/// vertices it connects. Instead of specifying the type of hyperedge, a slice of node indices
/// is used to define the edge consituents.
///
/// Edges may be declared without a binding as well.
///
/// ```ignore
/// hyperedge! {
///     ${graph} {
///         let ${edge_name}: [${vertex1}, ${vertex2}, ...] = ${weight};
///     },
///     ${graph} {
///         [${vertex1}, ${vertex2}, ...] = ${weight};
///     }
/// }
/// ```
///

#[cfg(feature = "macros")]
#[macro_export]
macro_rules! hyperedge {
    ($src:ident {
        $($(let $edge:ident:)? [$($var:ident),*] = $w:expr);* $(;)?
    }) => {
        $(
            $crate::hyperedge!(@new $src$(.$edge:)? [$($var),*] = $w);
        )*
    };
    (@new $src:ident.$edge:ident: [$($var:ident),*] = $w:expr) => {
        #[allow(unused_variables)]
        let $edge = $src.add_edge($w, vec![$($var),*]).expect("Failed to insert edge");
    };
    (@new $src:ident [$($var:ident),*] = $w:expr) => {
        $src.add_edge($w, vec![$($var),*]).expect("Failed to insert edge");
    };
    ($src:ident {
        $($(let $edge:ident:)? ([$($var:ident),*] -> [$($dst:ident),*]) = $w:expr);* $(;)?
    }) => {
        $(
            $crate::hyperedge!(@new $src$(.$edge:)? ([$($var),*] -> [$($dst),*]) = $w);
        )*
    };
    (@new $src:ident.$edge:ident: ([$($var:ident),*] -> [$($dst:ident),*]) = $w:expr) => {
        #[allow(unused_variables)]
        let $edge = $src.add_edge($w, vec![$($var),*]).expect("Failed to insert edge");
    };
    (@new $src:ident ([$($var:ident),*] -> [$($dst:ident),*]) = $w:expr) => {
        $src.add_edge($w, vec![$($var),*], vec![$($dst),*]).expect("Failed to insert edge");
    };
}
/// the [`hypernode`] macro streamlines the process of inserting nodes into a hypergraph.
///
/// ## Usage
///
/// The macro requires that you to pass a mutable reference to some hypergraph by first
/// defining the ident of the associated graph. Once declared, hypernodes are defined as `let`
/// statement within a block, where each statement defines the identifier of a node.
/// Optionally, a weight may be specified for the hypernode by appending `= <weight>`.
///
/// ```ignore
/// hypernode! {
///     $graph: {
///         let $var:ident $(= $w:expr)?;
///     }
/// }
/// ```
///
/// ### Example
///
/// ```rust
/// use rshyper::HyperMap;
/// // initialize a new, undirected hypergraph
/// let mut graph = HyperMap::<usize, usize>::undirected();
/// // use the macro to insert nodes into the graph
/// rshyper::hypernode! {
///     graph {
///         let v0;
///         let v1;
///         let v2;
///         let v3 = 1;
///         let v4 = 2;
///         let v5 = 3;
///     }
///  }
/// ```
#[cfg(feature = "macros")]
#[macro_export]
macro_rules! hypernode {
    ($src:ident { $(let $var:ident = $w:expr);* $(;)? }) => {
        $($crate::hypernode!(@new $src.$var = $w);)*
    };
    // (@impl $src:ident.$var:ident $(= $w:expr)?) => {
    //     $crate::hypernode!(@new $src.$var $(= $w)?);
    // };
    (@new $src:ident.$var:ident = $w:expr) => {
        let $var = $src.add_node($w);
    };
}