open_hypergraphs/semifinite/
types.rs1use crate::array::*;
2use crate::category::*;
3use crate::finite_function::FiniteFunction;
4
5use core::fmt::Debug;
6use core::ops::{Add, Shr};
7use num_traits::{One, Zero};
8
9pub struct SemifiniteFunction<K: ArrayKind, T>(pub K::Type<T>);
12
13impl<K: ArrayKind, T> Clone for SemifiniteFunction<K, T>
14where
15 K::Type<T>: Clone,
16{
17 fn clone(&self) -> Self {
18 Self(self.0.clone())
19 }
20}
21
22impl<K: ArrayKind, T> SemifiniteFunction<K, T>
23where
24 K::Type<T>: Array<K, T>,
25{
26 pub fn len(&self) -> K::I {
27 self.0.len()
28 }
29
30 pub fn singleton(x: T) -> SemifiniteFunction<K, T> {
32 SemifiniteFunction(K::Type::<T>::fill(x, K::I::one()))
33 }
34
35 pub fn coproduct(&self, other: &Self) -> Self {
36 SemifiniteFunction(self.0.concatenate(&other.0))
37 }
38}
39
40pub fn compose_semifinite<K: ArrayKind, T>(
43 lhs: &FiniteFunction<K>,
44 rhs: &SemifiniteFunction<K, T>,
45) -> Option<SemifiniteFunction<K, T>>
46where
47 K::Type<T>: Array<K, T>,
48{
49 if lhs.target() != rhs.0.len() {
50 return None;
51 }
52
53 let table = rhs.0.gather(lhs.table.get_range(..));
55 Some(SemifiniteFunction(table))
56}
57
58impl<K: ArrayKind, T> PartialEq<SemifiniteFunction<K, T>> for SemifiniteFunction<K, T>
60where
61 K::Type<T>: PartialEq,
62{
63 fn eq(&self, other: &SemifiniteFunction<K, T>) -> bool {
64 self.0 == other.0
65 }
66}
67
68impl<K: ArrayKind, T> Debug for SemifiniteFunction<K, T>
69where
70 K::Type<T>: Debug,
71{
72 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
73 f.debug_tuple("SemifiniteFunction").field(&self.0).finish()
74 }
75}
76
77impl<K: ArrayKind, T> Add<&SemifiniteFunction<K, T>> for &SemifiniteFunction<K, T>
78where
79 K::Type<T>: Array<K, T>,
80{
81 type Output = Option<SemifiniteFunction<K, T>>; fn add(self, rhs: &SemifiniteFunction<K, T>) -> Self::Output {
84 Some(self.coproduct(rhs))
85 }
86}
87
88impl<K: ArrayKind, T> Add<SemifiniteFunction<K, T>> for SemifiniteFunction<K, T>
89where
90 K::Type<T>: Array<K, T>,
91{
92 type Output = SemifiniteFunction<K, T>;
93
94 fn add(self, rhs: Self) -> Self::Output {
95 self.coproduct(&rhs)
96 }
97}
98
99impl<K: ArrayKind, T> Zero for SemifiniteFunction<K, T>
100where
101 K::Type<T>: Array<K, T>,
102{
103 fn zero() -> Self {
104 SemifiniteFunction(K::Type::<T>::empty())
105 }
106
107 fn is_zero(&self) -> bool {
108 self.0.is_empty()
109 }
110}
111
112impl<K: ArrayKind, T> Shr<&SemifiniteFunction<K, T>> for &FiniteFunction<K>
114where
115 K::Type<T>: Array<K, T>,
116{
117 type Output = Option<SemifiniteFunction<K, T>>;
118
119 fn shr(self, other: &SemifiniteFunction<K, T>) -> Option<SemifiniteFunction<K, T>> {
120 compose_semifinite(self, other)
121 }
122}