open_hypergraphs/lax/functor/
dyn_functor.rs1use crate::array::vec::VecKind;
3use crate::lax::open_hypergraph::*;
4use crate::operations::Operations;
5use crate::strict;
6
7use super::traits::Functor;
8
9pub fn define_map_arrow<
12 F: Functor<O1, A1, O2, A2> + Clone,
13 O1: Clone + PartialEq,
14 A1: Clone,
15 O2: Clone + PartialEq,
16 A2: Clone,
17>(
18 functor: &F,
19 f: &OpenHypergraph<O1, A1>,
20) -> OpenHypergraph<O2, A2> {
21 let strict_functor: DynFunctor<F, O1, A1, O2, A2> = to_dyn_functor(functor.clone());
23 let strict_f = to_strict(f.clone());
24 let strict_g = <_ as strict::functor::Functor<VecKind, O1, A1, O2, A2>>::map_arrow(
25 &strict_functor,
26 &strict_f,
27 );
28 OpenHypergraph::from_strict(strict_g)
29}
30
31pub fn to_dyn_functor<F: Functor<O1, A1, O2, A2>, O1, A1, O2, A2>(
32 functor: F,
33) -> DynFunctor<F, O1, A1, O2, A2> {
34 DynFunctor {
35 inner: functor,
36 _phantom: std::marker::PhantomData,
37 }
38}
39
40fn to_strict<O: Clone + PartialEq, A: Clone>(
41 f: OpenHypergraph<O, A>,
42) -> strict::OpenHypergraph<VecKind, O, A> {
43 f.to_strict()
44}
45
46pub struct DynFunctor<F: Functor<O1, A1, O2, A2>, O1, A1, O2, A2> {
48 inner: F,
49 _phantom: std::marker::PhantomData<(O1, A1, O2, A2)>,
50}
51
52impl<
53 F: Functor<O1, A1, O2, A2>,
54 O1: Clone + PartialEq,
55 A1: Clone,
56 O2: Clone + PartialEq,
57 A2: Clone,
58 > strict::functor::Functor<VecKind, O1, A1, O2, A2> for DynFunctor<F, O1, A1, O2, A2>
59{
60 fn map_object(
61 &self,
62 a: &strict::SemifiniteFunction<VecKind, O1>,
63 ) -> strict::IndexedCoproduct<VecKind, strict::SemifiniteFunction<VecKind, O2>> {
64 let mut sizes = Vec::new();
65 let mut values = Vec::new();
66
67 for obj in a.0 .0.iter() {
68 let iter = self.inner.map_object(obj);
69 sizes.push(iter.len());
70 values.extend(iter);
71 }
72
73 use crate::array::vec::VecArray;
74 use crate::semifinite::SemifiniteFunction;
75 let sizes = SemifiniteFunction::<VecKind, usize>(VecArray(sizes));
76 let values = SemifiniteFunction(VecArray(values));
77 strict::IndexedCoproduct::from_semifinite(sizes, values).unwrap()
78 }
79
80 fn map_operations(
81 &self,
82 ops: Operations<VecKind, O1, A1>,
83 ) -> strict::OpenHypergraph<VecKind, O2, A2> {
84 let op_iter = ops.x.0 .0.iter();
86 let source_iter = ops.a.into_iter();
87 let target_iter = ops.b.into_iter();
88
89 let mut acc: OpenHypergraph<O2, A2> = OpenHypergraph::empty();
90 for (op, (source, target)) in op_iter.zip(source_iter.zip(target_iter)) {
91 acc.tensor_assign(self.inner.map_operation(op, &source.0, &target.0))
92 }
93
94 acc.to_strict()
95 }
96
97 fn map_arrow(
98 &self,
99 f: &strict::OpenHypergraph<VecKind, O1, A1>,
100 ) -> strict::OpenHypergraph<VecKind, O2, A2> {
101 strict::functor::define_map_arrow(self, f)
102 }
103}
104
105#[derive(Clone)]
107pub struct Identity;
108
109impl<O: PartialEq + Clone, A: Clone + PartialEq> Functor<O, A, O, A> for Identity {
110 fn map_object(&self, o: &O) -> impl ExactSizeIterator<Item = O> {
111 std::iter::once(o.clone())
112 }
113
114 fn map_operation(&self, a: &A, source: &[O], target: &[O]) -> crate::lax::OpenHypergraph<O, A> {
115 OpenHypergraph::singleton(a.clone(), source.to_vec(), target.to_vec())
116 }
117
118 fn map_arrow(&self, f: &crate::lax::OpenHypergraph<O, A>) -> crate::lax::OpenHypergraph<O, A> {
119 define_map_arrow(self, f)
120 }
121}