open_hypergraphs/lax/
category.rs

1//! Implement [`crate::category`] traits for [`crate::lax::OpenHypergraph`]
2use crate::array::vec::VecKind;
3use crate::category::*;
4use crate::lax::*;
5
6impl<O: Clone + PartialEq, A: Clone> Arrow for OpenHypergraph<O, A> {
7    type Object = Vec<O>;
8
9    fn source(&self) -> Self::Object {
10        self.sources
11            .iter()
12            .map(|i| self.hypergraph.nodes[i.0].clone())
13            .collect()
14    }
15
16    fn target(&self) -> Self::Object {
17        self.targets
18            .iter()
19            .map(|i| self.hypergraph.nodes[i.0].clone())
20            .collect()
21    }
22
23    fn identity(a: Self::Object) -> Self {
24        let mut f = OpenHypergraph::empty();
25        let node_ids: Vec<NodeId> = a.iter().map(|o| f.new_node(o.clone())).collect();
26        f.sources = node_ids.clone();
27        f.targets = node_ids.clone();
28        f
29    }
30
31    fn compose(&self, other: &Self) -> Option<Self> {
32        if self.target() != other.source() {
33            return None;
34        }
35
36        let n = self.hypergraph.nodes.len();
37        let mut f = self.tensor(other);
38        for (u, v) in self.targets.iter().zip(other.sources.iter()) {
39            f.unify(*u, NodeId(v.0 + n));
40        }
41
42        f.sources = f.sources[..self.sources.len()].to_vec();
43        f.targets = f.targets[self.targets.len()..].to_vec();
44
45        Some(f)
46    }
47}
48
49impl<O: Clone + PartialEq, A: Clone> Monoidal for OpenHypergraph<O, A> {
50    fn unit() -> Self::Object {
51        vec![]
52    }
53
54    fn tensor(&self, other: &Self) -> Self {
55        let hypergraph = self.hypergraph.coproduct(&other.hypergraph);
56
57        // renumber all nodes
58        let n = self.hypergraph.nodes.len();
59
60        let sources = self
61            .sources
62            .iter()
63            .cloned()
64            .chain(other.sources.iter().map(|&i| NodeId(i.0 + n)))
65            .collect();
66
67        let targets = self
68            .targets
69            .iter()
70            .cloned()
71            .chain(other.targets.iter().map(|&i| NodeId(i.0 + n)))
72            .collect();
73
74        OpenHypergraph {
75            sources,
76            targets,
77            hypergraph,
78        }
79    }
80}
81
82use crate::array::vec::VecArray;
83use crate::semifinite::*;
84
85impl<O: Clone + PartialEq, A: Clone + PartialEq> SymmetricMonoidal for OpenHypergraph<O, A> {
86    fn twist(a: Self::Object, b: Self::Object) -> Self {
87        let f = crate::strict::open_hypergraph::OpenHypergraph::twist(
88            SemifiniteFunction(VecArray(a)),
89            SemifiniteFunction(VecArray(b)),
90        );
91        OpenHypergraph::from_strict(f)
92    }
93}
94
95impl<O: Clone + PartialEq, A: Clone + PartialEq> Spider<VecKind> for OpenHypergraph<O, A> {
96    fn dagger(&self) -> Self {
97        let mut f = self.clone();
98        f.sources = self.targets.clone();
99        f.targets = self.sources.clone();
100        f
101    }
102
103    fn spider(
104        s: crate::finite_function::FiniteFunction<VecKind>,
105        t: crate::finite_function::FiniteFunction<VecKind>,
106        w: Self::Object,
107    ) -> Option<Self> {
108        let w = SemifiniteFunction(VecArray(w));
109        let f = crate::strict::open_hypergraph::OpenHypergraph::spider(s, t, w)?;
110        Some(OpenHypergraph::from_strict(f))
111    }
112}
113
114use core::ops::{BitOr, Shr};
115
116impl<O: Clone + PartialEq, A: Clone> Shr<&OpenHypergraph<O, A>> for &OpenHypergraph<O, A> {
117    type Output = Option<OpenHypergraph<O, A>>;
118
119    fn shr(self, rhs: &OpenHypergraph<O, A>) -> Self::Output {
120        self.compose(rhs)
121    }
122}
123
124impl<O: Clone + PartialEq, A: Clone> BitOr<&OpenHypergraph<O, A>> for &OpenHypergraph<O, A> {
125    type Output = OpenHypergraph<O, A>;
126
127    fn bitor(self, rhs: &OpenHypergraph<O, A>) -> Self::Output {
128        self.tensor(rhs)
129    }
130}