open_hypergraphs/functor/
spider.rs1use crate::array::*;
3use crate::category::*;
4use crate::finite_function::*;
5use crate::indexed_coproduct::*;
6use crate::open_hypergraph::*;
7use crate::operations::*;
8use crate::semifinite::*;
9
10pub trait Functor<K: ArrayKind, O1, A1, O2, A2> {
12 fn map_object(a: &SemifiniteFunction<K, O1>) -> IndexedCoproduct<K, SemifiniteFunction<K, O2>>;
14
15 fn map_arrow(a: &OpenHypergraph<K, O1, A1>) -> OpenHypergraph<K, O2, A2>;
17}
18
19pub struct Identity;
21
22impl<K: ArrayKind, O, A> Functor<K, O, A, O, A> for Identity
23where
24 K::Type<K::I>: NaturalArray<K>,
25 K::Type<O>: Array<K, O>,
26 K::Type<A>: Array<K, A>,
27{
28 fn map_object(a: &SemifiniteFunction<K, O>) -> IndexedCoproduct<K, SemifiniteFunction<K, O>> {
29 IndexedCoproduct::elements(a.clone())
30 }
31
32 fn map_arrow(f: &OpenHypergraph<K, O, A>) -> OpenHypergraph<K, O, A> {
33 f.clone()
34 }
35}
36
37pub fn to_operations<K: ArrayKind, O, A>(f: &OpenHypergraph<K, O, A>) -> Operations<K, O, A>
41where
42 K::Type<K::I>: NaturalArray<K>,
43 K::Type<O>: Array<K, O>,
44 K::Type<A>: Array<K, A>,
45{
46 Operations {
47 x: f.h.x.clone(),
48 a: f.h.s.map_semifinite(&f.h.w).unwrap(),
49 b: f.h.t.map_semifinite(&f.h.w).unwrap(),
50 }
51}
52
53fn map_half_spider<K: ArrayKind, O>(
54 w: &IndexedCoproduct<K, SemifiniteFunction<K, O>>,
55 f: &FiniteFunction<K>,
56) -> FiniteFunction<K> {
57 w.sources.injections(f).unwrap()
58}
59
60pub trait SpiderFunctor<K: ArrayKind, O1, A1, O2, A2>: Sized
66where
67 K::Type<K::I>: NaturalArray<K>,
68
69 K::Type<O1>: Array<K, O1>,
70 K::Type<A1>: Array<K, A1>,
71
72 K::Type<O2>: Array<K, O2>,
73 K::Type<A2>: Array<K, A2>,
74{
75 fn map_object(a: &SemifiniteFunction<K, O1>) -> IndexedCoproduct<K, SemifiniteFunction<K, O2>>;
77
78 fn map_operations(ops: Operations<K, O1, A1>) -> OpenHypergraph<K, O2, A2>;
82
83 fn map_arrow(f: &OpenHypergraph<K, O1, A1>) -> OpenHypergraph<K, O2, A2> {
84 let fx = Self::map_operations(to_operations(f));
87
88 let fw = Self::map_object(&f.h.w);
91
92 spider_map_arrow::<K, O1, A1, O2, A2>(f, fw, fx)
93 }
94}
95
96pub(crate) fn spider_map_arrow<K: ArrayKind, O1, A1, O2, A2>(
99 f: &OpenHypergraph<K, O1, A1>,
100 fw: IndexedCoproduct<K, SemifiniteFunction<K, O2>>,
101 fx: OpenHypergraph<K, O2, A2>,
102) -> OpenHypergraph<K, O2, A2>
103where
104 K::Type<K::I>: NaturalArray<K>,
105
106 K::Type<O1>: Array<K, O1>,
107 K::Type<A1>: Array<K, A1>,
108
109 K::Type<O2>: Array<K, O2>,
110 K::Type<A2>: Array<K, A2>,
111{
112 let i = OpenHypergraph::<K, O2, A2>::identity(fw.values.clone());
114
115 let sx = {
116 let fs = map_half_spider(&fw, &f.s);
117 let e_s = map_half_spider(&fw, &f.h.s.values);
118 OpenHypergraph::<K, O2, A2>::spider(fs, i.t.coproduct(&e_s).unwrap(), i.h.w.clone())
119 .unwrap()
120 };
121
122 let yt = {
123 let ft = map_half_spider(&fw, &f.t);
124 let fe_t = map_half_spider(&fw, &f.h.t.values);
125 OpenHypergraph::<K, O2, A2>::spider(i.s.coproduct(&fe_t).unwrap(), ft, i.h.w.clone())
126 .unwrap()
127 };
128
129 sx.compose(&i.tensor(&fx)).unwrap().compose(&yt).unwrap()
146}
147
148impl<K: ArrayKind, O, A> SpiderFunctor<K, O, A, O, A> for Identity
149where
150 K::Type<K::I>: NaturalArray<K>,
151 K::Type<O>: Array<K, O>,
152 K::Type<A>: Array<K, A>,
153{
154 fn map_object(a: &SemifiniteFunction<K, O>) -> IndexedCoproduct<K, SemifiniteFunction<K, O>> {
155 <Self as Functor<K, O, A, O, A>>::map_object(a)
157 }
158
159 fn map_operations(ops: Operations<K, O, A>) -> OpenHypergraph<K, O, A> {
160 OpenHypergraph::tensor_operations(ops)
161 }
162}