graph_base/interfaces/
hypergraph.rs

1use std::{collections::HashMap, fmt::Display};
2use crate::interfaces::graph::SingleId;
3use crate::interfaces::edge::Hyperedge;
4
5use super::{edge::DirectedHyperedge, vertex::Vertex};
6
7pub trait IdVector {
8    fn id(&self) -> Vec<usize>;
9}
10
11pub trait Hypergraph<'a> {
12    type Node: Vertex;
13    type Edge: Hyperedge;
14    fn new() -> Self;
15    fn nodes(&'a self) -> impl Iterator<Item = &'a Self::Node>;
16    fn hyperedges(&'a self) -> impl Iterator<Item = &'a Self::Edge>;
17    fn get_hyperedges_vector(&'a self) -> impl Iterator<Item = Vec<&'a Self::Node>> {
18        let id_map: HashMap<_, _> = HashMap::from_iter(self.nodes().map(|node| (node.id(), node)));
19        self.hyperedges().map(move |edge| edge.id().iter().map(|id| id_map.get(id).unwrap()).cloned().collect::<Vec<_>>()).collect::<Vec<_>>().into_iter()
20    }
21    fn get_hyperedges_vector_with_edge(&'a self) -> impl Iterator<Item = (&'a Self::Edge, Vec<&'a Self::Node>)> {
22        let id_map: HashMap<_, _> = HashMap::from_iter(self.nodes().map(|node| (node.id(), node)));
23        self.hyperedges().map(move |edge| (edge, edge.id().iter().map(|id| id_map.get(id).unwrap()).cloned().collect::<Vec<_>>())).collect::<Vec<_>>().into_iter()
24    }
25    fn add_node(&mut self, node: Self::Node);
26    fn add_hyperedge(&mut self, edge: Self::Edge);
27}
28
29
30pub struct AdjacencyList<'a, T: Hypergraph<'a>>(HashMap<&'a T::Node, Vec<&'a T::Node>>);
31
32impl<'a, T> Display for AdjacencyList<'a, T> 
33where 
34    T: Hypergraph<'a> {    
35    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36        let mut s = String::new();
37        for (node, adj) in self.0.iter() {
38            
39            let s1 = format!("{}", node);
40            let mut s2 = String::new();
41            for node in adj {
42                s2.push_str(format!("{}, ", node).as_str());
43            }
44
45            s.push_str(format!("Node {} -> {{{}}}\n", s1, s2).as_str());
46        }
47        write!(f, "{}", s)
48    }
49}
50
51pub trait DirectedHypergraph<'a>: Hypergraph<'a> + Sized 
52where 
53    Self::Edge: DirectedHyperedge {}
54
55pub trait Neighbor<'a>: Hypergraph<'a> + Sized {
56    fn get_neighbors(&'a self) -> AdjacencyList<'a, Self> {
57        let mut adj = HashMap::new();
58        for node in self.nodes() {
59            adj.insert(node, Vec::new());
60        }
61        for edge in self.hyperedges() {
62            let nodes = edge.id();
63            for i in 0..nodes.len() {
64                for j in (i + 1)..nodes.len() {
65                    let node1 = self.nodes().find(|node| node.id() == nodes[i]).unwrap();
66                    let node2 = self.nodes().find(|node| node.id() == nodes[j]).unwrap();
67                    adj.get_mut(node1).unwrap().push(node2);
68                    adj.get_mut(node2).unwrap().push(node1);
69                }
70            }
71        }
72        AdjacencyList(adj)
73    }
74
75    fn neighbors(&'a self, adj: &AdjacencyList<'a, Self>, node: &Self::Node) -> impl Iterator<Item = &'a Self::Node> {
76        adj.0.get(node).unwrap().iter().cloned()
77    }
78}
79
80pub trait Precursor<'a>: DirectedHypergraph<'a>
81where
82    Self::Edge: DirectedHyperedge, {
83    fn get_precursor(&'a self) -> AdjacencyList<'a, Self> {
84        let mut adj = HashMap::new();
85        for node in self.nodes() {
86            adj.insert(node, Vec::new());
87        }
88        for edge in self.hyperedges() {
89            let nodes = edge.id();
90            for i in 0..nodes.len() {
91                for j in (i + 1)..nodes.len() {
92                    let node1 = self.nodes().find(|node| node.id() == nodes[i]).unwrap();
93                    let node2 = self.nodes().find(|node| node.id() == nodes[j]).unwrap();
94                    adj.get_mut(node2).unwrap().push(node1);
95                }
96            }
97        }
98        AdjacencyList(adj)
99    }
100}
101
102pub trait Successor<'a>: DirectedHypergraph<'a>
103where
104    Self::Edge: DirectedHyperedge, {
105    fn get_postcursor(&'a self) -> AdjacencyList<'a, Self> {
106        let mut adj = HashMap::new();
107        for node in self.nodes() {
108            adj.insert(node, Vec::new());
109        }
110        for edge in self.hyperedges() {
111            let nodes = edge.id();
112            for i in 0..nodes.len() {
113                for j in (i + 1)..nodes.len() {
114                    let node1 = self.nodes().find(|node| node.id() == nodes[i]).unwrap();
115                    let node2 = self.nodes().find(|node| node.id() == nodes[j]).unwrap();
116                    adj.get_mut(node1).unwrap().push(node2);
117                }
118            }
119        }
120        AdjacencyList(adj)
121    }
122}
123
124pub struct HyperedgeList<'a, T: Hypergraph<'a>>(HashMap<&'a T::Node, Vec<&'a T::Edge>>);
125
126impl<'a, T> Display for HyperedgeList<'a, T> 
127where 
128    T: Hypergraph<'a> {    
129    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
130        let mut s = String::new();
131        for (node, edges) in self.0.iter() {
132            
133            let s1 = format!("{}", node);
134            let mut s2 = String::new();
135            for edge in edges {
136                // s2.push_str(format!("{}, ", edge).as_str());
137            }
138
139            s.push_str(format!("Node {} -> {{{}}}\n", s1, s2).as_str());
140        }
141        write!(f, "{}", s)
142    }
143}
144
145pub trait ContainedHyperedge<'a>: Hypergraph<'a> + Sized {
146    fn get_hyperedges_list(&'a self) -> HyperedgeList<'a, Self> {
147        let mut adj = HashMap::new();
148        for node in self.nodes() {
149            adj.insert(node, Vec::new());
150        }
151        for edge in self.hyperedges() {
152            let nodes = edge.id();
153            for i in 0..nodes.len() {
154                let node = self.nodes().find(|node| node.id() == nodes[i]).unwrap();
155                adj.get_mut(node).unwrap().push(edge);
156            }
157        }
158        HyperedgeList(adj)
159    }
160
161    fn contained_hyperedges(&'a self, adj: &HyperedgeList<'a, Self>, node: &Self::Node) -> impl Iterator<Item = &'a Self::Edge> {
162        adj.0.get(node).unwrap().iter().cloned()
163    }
164}
165pub trait ContainedDirectedHyperedge<'a>: DirectedHypergraph<'a> + Sized
166where 
167    Self::Edge: DirectedHyperedge {
168    fn contained_hyperedges(&'a self, adj: &HyperedgeList<'a, Self>, node: &Self::Node) -> impl Iterator<Item = &'a Self::Edge> {
169        adj.0.get(node).unwrap().iter().cloned()
170    }
171
172    fn get_hyperedges_src(&'a self) -> HyperedgeList<'a, Self> {
173        let mut adj = HashMap::new();
174        for node in self.nodes() {
175            adj.insert(node, Vec::new());
176        }
177        for edge in self.hyperedges() {
178            for id in edge.src() {
179                let node = self.nodes().find(|node| node.id() == id).unwrap();
180                adj.get_mut(node).unwrap().push(edge);
181            }
182        }
183        HyperedgeList(adj)
184    }
185    fn get_hyperedges_dst(&'a self) -> HyperedgeList<'a, Self> {
186        let mut adj = HashMap::new();
187        for node in self.nodes() {
188            adj.insert(node, Vec::new());
189        }
190        for edge in self.hyperedges() {
191            for id in edge.dst() {
192                let node = self.nodes().find(|node| node.id() == id).unwrap();
193                adj.get_mut(node).unwrap().push(edge);
194            }    
195        }
196        HyperedgeList(adj)
197    }
198    
199}