open_hypergraphs/lax/
category.rs1use 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 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}