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 new(x: K::Type<T>) -> Self {
27 Self(x)
28 }
29
30 pub fn len(&self) -> K::I {
31 self.0.len()
32 }
33
34 pub fn singleton(x: T) -> SemifiniteFunction<K, T> {
36 SemifiniteFunction(K::Type::<T>::fill(x, K::I::one()))
37 }
38
39 pub fn coproduct(&self, other: &Self) -> Self {
40 SemifiniteFunction(self.0.concatenate(&other.0))
41 }
42}
43
44pub fn compose_semifinite<K: ArrayKind, T>(
47 lhs: &FiniteFunction<K>,
48 rhs: &SemifiniteFunction<K, T>,
49) -> Option<SemifiniteFunction<K, T>>
50where
51 K::Type<T>: Array<K, T>,
52{
53 if lhs.target() != rhs.0.len() {
54 return None;
55 }
56
57 let table = rhs.0.gather(lhs.table.get_range(..));
59 Some(SemifiniteFunction(table))
60}
61
62impl<K: ArrayKind, T> PartialEq<SemifiniteFunction<K, T>> for SemifiniteFunction<K, T>
64where
65 K::Type<T>: PartialEq,
66{
67 fn eq(&self, other: &SemifiniteFunction<K, T>) -> bool {
68 self.0 == other.0
69 }
70}
71
72impl<K: ArrayKind, T> Debug for SemifiniteFunction<K, T>
73where
74 K::Type<T>: Debug,
75{
76 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
77 f.debug_tuple("SemifiniteFunction").field(&self.0).finish()
78 }
79}
80
81impl<K: ArrayKind, T> Add<&SemifiniteFunction<K, T>> for &SemifiniteFunction<K, T>
82where
83 K::Type<T>: Array<K, T>,
84{
85 type Output = Option<SemifiniteFunction<K, T>>; fn add(self, rhs: &SemifiniteFunction<K, T>) -> Self::Output {
88 Some(self.coproduct(rhs))
89 }
90}
91
92impl<K: ArrayKind, T> Add<SemifiniteFunction<K, T>> for SemifiniteFunction<K, T>
93where
94 K::Type<T>: Array<K, T>,
95{
96 type Output = SemifiniteFunction<K, T>;
97
98 fn add(self, rhs: Self) -> Self::Output {
99 self.coproduct(&rhs)
100 }
101}
102
103impl<K: ArrayKind, T> Zero for SemifiniteFunction<K, T>
104where
105 K::Type<T>: Array<K, T>,
106{
107 fn zero() -> Self {
108 SemifiniteFunction(K::Type::<T>::empty())
109 }
110
111 fn is_zero(&self) -> bool {
112 self.0.is_empty()
113 }
114}
115
116impl<K: ArrayKind, T> Shr<&SemifiniteFunction<K, T>> for &FiniteFunction<K>
118where
119 K::Type<T>: Array<K, T>,
120{
121 type Output = Option<SemifiniteFunction<K, T>>;
122
123 fn shr(self, other: &SemifiniteFunction<K, T>) -> Option<SemifiniteFunction<K, T>> {
124 compose_semifinite(self, other)
125 }
126}