open_hypergraphs/lax/
mut_category.rs

1//! Mutable versions of categorical operations.
2use super::hypergraph::*;
3use super::open_hypergraph::*;
4
5fn add_offset<'a, I>(n: usize, xs: I) -> impl Iterator<Item = NodeId> + 'a
6where
7    I: Iterator<Item = &'a NodeId> + 'a,
8{
9    xs.map(move |i| NodeId(i.0 + n))
10}
11
12impl<O, A> Hypergraph<O, A> {
13    /// Compute the coproduct `H₀ + H₁` by mutating the data of `H₁`
14    pub fn coproduct_assign(&mut self, rhs: Hypergraph<O, A>) {
15        let n = self.nodes.len();
16
17        self.adjacency
18            .extend(rhs.adjacency.into_iter().map(|edge| Hyperedge {
19                sources: add_offset(n, edge.sources.iter()).collect(),
20                targets: add_offset(n, edge.targets.iter()).collect(),
21            }));
22
23        self.quotient.0.extend(add_offset(n, rhs.quotient.0.iter()));
24        self.quotient.1.extend(add_offset(n, rhs.quotient.1.iter()));
25
26        // no offset; these are coproducts.
27        self.nodes.extend(rhs.nodes);
28        self.edges.extend(rhs.edges);
29    }
30}
31
32impl<O, A> OpenHypergraph<O, A> {
33    /// Compute the tensor product `f.tensor(g)` by mutating the data of `f`
34    pub fn tensor_assign(&mut self, rhs: OpenHypergraph<O, A>) {
35        let n = self.hypergraph.nodes.len();
36        self.hypergraph.coproduct_assign(rhs.hypergraph);
37        self.sources
38            .extend(rhs.sources.iter().map(|&i| NodeId(i.0 + n)));
39        self.targets
40            .extend(rhs.targets.iter().map(|&i| NodeId(i.0 + n)));
41    }
42}