pub trait IsZero {
fn is_zero(&self) -> bool;
}
pub trait Semigroup<Rhs: ?Sized = Self> : Clone + IsZero {
fn plus_equals(&mut self, rhs: &Rhs);
}
impl<'a, S, T: Semigroup<S>> Semigroup<&'a S> for T {
fn plus_equals(&mut self, rhs: &&'a S) {
self.plus_equals(&**rhs);
}
}
pub trait Monoid : Semigroup {
fn zero() -> Self;
}
pub trait Abelian : Monoid {
fn negate(&mut self);
}
pub trait Multiply<Rhs = Self> {
type Output;
fn multiply(self, rhs: &Rhs) -> Self::Output;
}
macro_rules! builtin_implementation {
($t:ty) => {
impl IsZero for $t {
#[inline] fn is_zero(&self) -> bool { self == &0 }
}
impl Semigroup for $t {
#[inline] fn plus_equals(&mut self, rhs: &Self) { *self += rhs; }
}
impl Monoid for $t {
#[inline] fn zero() -> Self { 0 }
}
impl Multiply<Self> for $t {
type Output = Self;
fn multiply(self, rhs: &Self) -> Self { self * rhs}
}
};
}
macro_rules! builtin_abelian_implementation {
($t:ty) => {
impl Abelian for $t {
#[inline] fn negate(&mut self) { *self = -*self; }
}
};
}
builtin_implementation!(i8);
builtin_implementation!(i16);
builtin_implementation!(i32);
builtin_implementation!(i64);
builtin_implementation!(i128);
builtin_implementation!(isize);
builtin_implementation!(u8);
builtin_implementation!(u16);
builtin_implementation!(u32);
builtin_implementation!(u64);
builtin_implementation!(u128);
builtin_implementation!(usize);
builtin_abelian_implementation!(i8);
builtin_abelian_implementation!(i16);
builtin_abelian_implementation!(i32);
builtin_abelian_implementation!(i64);
builtin_abelian_implementation!(i128);
builtin_abelian_implementation!(isize);
macro_rules! wrapping_implementation {
($t:ty) => {
impl IsZero for $t {
#[inline] fn is_zero(&self) -> bool { self == &std::num::Wrapping(0) }
}
impl Semigroup for $t {
#[inline] fn plus_equals(&mut self, rhs: &Self) { *self += rhs; }
}
impl Monoid for $t {
#[inline] fn zero() -> Self { std::num::Wrapping(0) }
}
impl Abelian for $t {
#[inline] fn negate(&mut self) { *self = -*self; }
}
impl Multiply<Self> for $t {
type Output = Self;
fn multiply(self, rhs: &Self) -> Self { self * rhs}
}
};
}
wrapping_implementation!(std::num::Wrapping<i8>);
wrapping_implementation!(std::num::Wrapping<i16>);
wrapping_implementation!(std::num::Wrapping<i32>);
wrapping_implementation!(std::num::Wrapping<i64>);
wrapping_implementation!(std::num::Wrapping<i128>);
wrapping_implementation!(std::num::Wrapping<isize>);
pub use self::present::Present;
mod present {
use serde::{Deserialize, Serialize};
#[derive(Copy, Ord, PartialOrd, Eq, PartialEq, Debug, Clone, Serialize, Deserialize, Hash)]
pub struct Present;
impl<T: Clone> super::Multiply<T> for Present {
type Output = T;
fn multiply(self, rhs: &T) -> T {
rhs.clone()
}
}
impl super::IsZero for Present {
fn is_zero(&self) -> bool { false }
}
impl super::Semigroup for Present {
fn plus_equals(&mut self, _rhs: &Self) { }
}
}
mod tuples {
use super::{IsZero, Semigroup, Monoid, Abelian, Multiply};
macro_rules! tuple_implementation {
( ($($name:ident)*), ($($name2:ident)*) ) => (
impl<$($name: IsZero),*> IsZero for ($($name,)*) {
#[allow(unused_mut)]
#[allow(non_snake_case)]
#[inline] fn is_zero(&self) -> bool {
let mut zero = true;
let ($(ref $name,)*) = *self;
$( zero &= $name.is_zero(); )*
zero
}
}
impl<$($name: Semigroup),*> Semigroup for ($($name,)*) {
#[allow(non_snake_case)]
#[inline] fn plus_equals(&mut self, rhs: &Self) {
let ($(ref mut $name,)*) = *self;
let ($(ref $name2,)*) = *rhs;
$($name.plus_equals($name2);)*
}
}
impl<$($name: Monoid),*> Monoid for ($($name,)*) {
#[allow(non_snake_case)]
#[inline] fn zero() -> Self {
( $($name::zero(), )* )
}
}
impl<$($name: Abelian),*> Abelian for ($($name,)*) {
#[allow(non_snake_case)]
#[inline] fn negate(&mut self) {
let ($(ref mut $name,)*) = self;
$($name.negate();)*
}
}
impl<T, $($name: Multiply<T>),*> Multiply<T> for ($($name,)*) {
type Output = ($(<$name as Multiply<T>>::Output,)*);
#[allow(unused_variables)]
#[allow(non_snake_case)]
#[inline] fn multiply(self, rhs: &T) -> Self::Output {
let ($($name,)*) = self;
( $($name.multiply(rhs), )* )
}
}
)
}
tuple_implementation!((), ());
tuple_implementation!((A1), (A2));
tuple_implementation!((A1 B1), (A2 B2));
tuple_implementation!((A1 B1 C1), (A2 B2 C2));
tuple_implementation!((A1 B1 C1 D1), (A2 B2 C2 D2));
}
mod vector {
use super::{IsZero, Semigroup, Monoid, Abelian, Multiply};
impl<R: IsZero> IsZero for Vec<R> {
fn is_zero(&self) -> bool {
self.iter().all(|x| x.is_zero())
}
}
impl<R: Semigroup> Semigroup for Vec<R> {
fn plus_equals(&mut self, rhs: &Self) {
self.plus_equals(&rhs[..])
}
}
impl<R: Semigroup> Semigroup<[R]> for Vec<R> {
fn plus_equals(&mut self, rhs: &[R]) {
for (index, update) in rhs.iter().enumerate().take(self.len()) {
self[index].plus_equals(update);
}
while self.len() < rhs.len() {
let element = &rhs[self.len()];
self.push(element.clone());
}
}
}
#[cfg(test)]
mod tests {
use crate::difference::Semigroup;
#[test]
fn test_semigroup_vec() {
let mut a = vec![1,2,3];
a.plus_equals([1,1,1,1].as_slice());
assert_eq!(vec![2,3,4,1], a);
}
}
impl<R: Monoid> Monoid for Vec<R> {
fn zero() -> Self {
Self::new()
}
}
impl<R: Abelian> Abelian for Vec<R> {
fn negate(&mut self) {
for update in self.iter_mut() {
update.negate();
}
}
}
impl<T, R: Multiply<T>> Multiply<T> for Vec<R> {
type Output = Vec<<R as Multiply<T>>::Output>;
fn multiply(self, rhs: &T) -> Self::Output {
self.into_iter()
.map(|x| x.multiply(rhs))
.collect()
}
}
}