use crate::array::*;
use crate::indexed_coproduct::*;
use crate::semifinite::*;
#[non_exhaustive] pub struct Operations<K: ArrayKind, O, A> {
pub x: SemifiniteFunction<K, A>,
pub a: IndexedCoproduct<K, SemifiniteFunction<K, O>>,
pub b: IndexedCoproduct<K, SemifiniteFunction<K, O>>,
}
impl<K: ArrayKind, O, A> Operations<K, O, A>
where
K::Type<A>: Array<K, A>,
K::Type<O>: Array<K, O>,
K::Type<K::I>: NaturalArray<K>, {
pub fn new(
x: SemifiniteFunction<K, A>,
a: IndexedCoproduct<K, SemifiniteFunction<K, O>>,
b: IndexedCoproduct<K, SemifiniteFunction<K, O>>,
) -> Option<Self> {
(Operations { x, a, b }).validate()
}
pub fn validate(self) -> Option<Self> {
let n = self.x.len();
if n != self.a.len() || n != self.b.len() {
None
} else {
Some(self)
}
}
pub fn singleton(x: A, a: SemifiniteFunction<K, O>, b: SemifiniteFunction<K, O>) -> Self {
Self {
x: SemifiniteFunction::singleton(x),
a: IndexedCoproduct::<K, SemifiniteFunction<K, O>>::singleton(a),
b: IndexedCoproduct::<K, SemifiniteFunction<K, O>>::singleton(b),
}
}
pub fn len(&self) -> K::I {
self.x.len()
}
}
impl<K: ArrayKind, O, A> std::fmt::Debug for Operations<K, O, A>
where
K::Type<A>: std::fmt::Debug,
K::Type<O>: std::fmt::Debug,
K::Index: std::fmt::Debug,
{
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("Operations")
.field("x", &self.x)
.field("a", &self.a)
.field("b", &self.b)
.finish()
}
}
impl<K: ArrayKind, O, A> Clone for Operations<K, O, A>
where
K::Type<A>: Array<K, A>,
K::Type<O>: Array<K, O>,
K::Type<K::I>: NaturalArray<K>,
{
fn clone(&self) -> Self {
Self {
x: self.x.clone(),
a: self.a.clone(),
b: self.b.clone(),
}
}
}
use crate::array::vec::VecKind;
impl<O, A> Operations<VecKind, O, A> {
pub fn iter(&self) -> impl Iterator<Item = (&A, &[O], &[O])> {
self.x
.0
.iter()
.zip(self.a.iter())
.zip(self.b.iter())
.map(|((a, b), c)| (a, b, c))
}
}