open_hypergraphs/semifinite/
arrow.rs

1use super::types::*;
2use crate::array::*;
3use crate::category::*;
4use crate::finite_function::*;
5
6use core::marker::PhantomData;
7use num_traits::Zero;
8
9/// Arrows in the category of semifinite functions
10pub enum SemifiniteArrow<K: ArrayKind, T> {
11    Identity, // Identities on types T
12    Finite(FiniteFunction<K>),
13    Semifinite(SemifiniteFunction<K, T>),
14}
15
16/// Objects of arrows
17#[derive(PartialEq, Eq)]
18pub enum SemifiniteObject<K: ArrayKind, T> {
19    Finite(K::I),        // all sources are natural numbers
20    Set(PhantomData<T>), // Targets are arbitrary types
21}
22
23impl<K: ArrayKind, T> Arrow for SemifiniteArrow<K, T>
24where
25    K::Type<T>: Array<K, T>,
26{
27    type Object = SemifiniteObject<K, T>;
28
29    fn source(&self) -> Self::Object {
30        //SemifiniteObject::Finite(self.0.len())
31        match self {
32            SemifiniteArrow::Finite(f) => SemifiniteObject::Finite(f.source()),
33            SemifiniteArrow::Semifinite(f) => SemifiniteObject::Finite(f.0.len()),
34            _ => SemifiniteObject::Set(PhantomData),
35        }
36    }
37
38    fn target(&self) -> Self::Object {
39        match self {
40            SemifiniteArrow::Finite(f) => SemifiniteObject::Finite(f.target()),
41            _ => SemifiniteObject::Set(PhantomData),
42        }
43    }
44
45    fn identity(a: Self::Object) -> Self {
46        match a {
47            SemifiniteObject::Finite(a) => FiniteFunction::identity(a).into(),
48            SemifiniteObject::Set(_) => SemifiniteArrow::Identity,
49        }
50    }
51
52    fn compose(&self, other: &Self) -> Option<Self> {
53        // LHS must always be finite otherwise this is not composable.
54        if let SemifiniteArrow::Finite(f) = self {
55            match other {
56                SemifiniteArrow::Finite(g) => (f >> g).map(SemifiniteArrow::Finite),
57                SemifiniteArrow::Semifinite(g) => {
58                    let result: Option<SemifiniteFunction<K, T>> = compose_semifinite(f, g);
59                    result.map(SemifiniteArrow::Semifinite)
60                    //(f >> g).map(|x| SemifiniteArrow::Semifinite(x))
61                }
62                _ => None, // Identity is only for types!
63            }
64        } else {
65            None
66        }
67    }
68}
69
70impl<K: ArrayKind, T> Coproduct for SemifiniteArrow<K, T>
71where
72    K::Type<T>: Array<K, T>,
73{
74    fn initial_object() -> Self::Object {
75        SemifiniteObject::Finite(K::I::zero())
76    }
77
78    fn initial(_a: Self::Object) -> Self {
79        todo!()
80    }
81
82    fn inj0(_a: Self::Object, _b: Self::Object) -> Self {
83        todo!()
84    }
85
86    fn inj1(_a: Self::Object, _b: Self::Object) -> Self {
87        todo!()
88    }
89
90    fn coproduct(&self, _other: &Self) -> Option<Self> {
91        todo!()
92    }
93}
94
95impl<K: ArrayKind, T> From<FiniteFunction<K>> for SemifiniteArrow<K, T> {
96    fn from(val: FiniteFunction<K>) -> Self {
97        SemifiniteArrow::Finite(val)
98    }
99}
100
101impl<K: ArrayKind, T> From<SemifiniteFunction<K, T>> for SemifiniteArrow<K, T> {
102    fn from(val: SemifiniteFunction<K, T>) -> Self {
103        SemifiniteArrow::Semifinite(val)
104    }
105}
106
107impl<K: ArrayKind, T> TryFrom<SemifiniteArrow<K, T>> for SemifiniteFunction<K, T> {
108    type Error = ();
109
110    fn try_from(value: SemifiniteArrow<K, T>) -> Result<Self, Self::Error> {
111        match value {
112            SemifiniteArrow::Semifinite(f) => Ok(f),
113            _ => Err(()),
114        }
115    }
116}