hypergraphx 0.0.5

A hypergraph library for Rust, based on the Python library of the same name.
Documentation
//! As you may have read in the README, hypergraphs are generalisations of graphs where edges can connect
//! any number of nodes. These edges can represent non-dyadic relationships, such as polyatomic chemical bonds
//! (looking at you, benzene), telecommunication networks, concurrent data structures, databases, image processing,
//! and even hypergraph neural networks. Also, they can be used for anything that graphs can be used for, since they're a true
//! generalisation.
//!
//! The application I had in mind when I first thought of writing this library was in Identity management, where companies
//! (or really anyone with some data) write policies to regulate access to their resources. A policy is defined as a 3-tuple, which
//! I figured was a nice hyperedge type. Since then, I found that a couple of libraries already exist, and I'm trying to borrow
//! the best of them all, and add something new too.
//!
//! Onto the library itself, so far we have three important modules, `traits`, `algo`, and `core`. `core` is where the important
//! user-facing stuff lives, and all the nice types are defined. `algo` is for important graph algorithms, including several
//! shortest-path algorithms, flow algorithms, and more. These are borrowed from `petgraph` and modified to fit my traits. The
//! heart of the implementation (and even a good bit of the docs) is still theirs. Thanks, `petgraph`! The `traits` module is
//! where you need to look if you want to implement your own graph types. Even otherwise, feel free to look around and suggest
//! improvements.
//!
//! Couple of smaller modules too: the prelude, which is, as preludes are, a bundle of commonly used types and traits, and `macros`,
//! which provides some convenient macros for working with hypergraphs.
//!
//! TODO:
//!
//! - Use HypergraphResult everywhere.
//! - Fill up last 5 traits: This is honestly a pain. Not a lot of statistics in Rust afaik.
//!     - Specifically Hypergraph Neural Networks: Welll, this is more of a long term goal. Even in the original python hypergraphx,
//!     it is a part of `community` modules. So this takes a backseat. Meanwhile I'll learn some more ML, or find someone who knows
//!     enough about it to collaborate with. Maybe the real hypergraphs were the friends we made along the way. :-)
//! * Spectral graph stuff: Started off, eigenvalues are up. We'll see about the rest.
//! * Parallelism: Pain to set up parallel traversal and concurrent modification of graphs. The rayon for the weights is
//!     as far as I think I can go for now.
//! * Add some of the more advanced properties.
//! * Add cycles (3 kinds) and cycle detection.
//! * Specialised graphs: DAGs, Trees, Cycles, Regular graphs, ...

use thiserror::Error;

pub mod algo;
pub mod core;
#[cfg(feature = "macros")]
pub mod macros;
pub mod traits;

#[derive(Debug, Clone, Error)]
pub enum HypergraphErrors {
    #[error(
        "Wrong edge weight type for a dynamically typed edge. Expected {expected}, found {found}."
    )]
    EdgeTypeMismatch {
        expected: &'static str,
        found: &'static str,
    },
    #[error(
        "Edge doesn't have enough nodes. For directed edges, 
    it must have at least one source and one target. For undirected edges, 
    it must have at least two nodes."
    )]
    EdgeTooSmall,
    #[error("Algorithm failed due to negative cycle.")]
    NegativeCycle,
    #[error("Tried to access a node or edge that does not exist.")]
    Nonexistent,
    #[error("Violates guarantee provided by graph type: {err}")]
    InvariantViolation { err: String },
}

pub type HypergraphResult<T> = Result<T, HypergraphErrors>;

pub mod prelude {
    pub use crate::core::{
        directed::{
            DiGraph, Edge as DirectedEdge, Hypergraph as DirectedHypergraph, Node as DirectedNode,
            uniform as directed_uniform,
        },
        special::{complete, cycle_free, cycles, partite},
        undirected::{
            Edge as UndirectedEdge, Graph, Hypergraph as UndirectedHypergraph,
            Node as UndirectedNode, uniform as undirected_uniform,
        },
    };

    #[cfg(feature = "multiplex")]
    pub use crate::core::multiplex::{
        DirectedLayer, Layer, MultiplexBase, MultiplexGraph, MultiplexIndex, MultiplexNode,
        UndirectedLayer, WildcardEdgeType,
    };

    #[cfg(feature = "temporal")]
    pub use crate::core::temporal::{
        DirectedTemporalGraph, TemporalBehaviour, UndirectedTemporalGraph,
    };

    pub use crate::HypergraphErrors;
    pub use crate::HypergraphResult;
    #[cfg(feature = "macros")]
    pub use crate::hypergraph;
    pub use crate::traits::*;
    pub use crate::{
        impl_graph_basics, impl_graph_basics_wrapper, impl_weights, impl_weights_wrapper,
    };
}

#[cfg(test)]
mod tests;