#[cfg(test)]
use std::fmt::Debug;
use std::ops::Add;
use std::ops::Neg;
use std::ops::Sub;
pub trait Zero: Sized + Add<Self, Output = Self> {
fn zero() -> Self;
fn is_zero(&self) -> bool;
}
pub trait AbelianGroup:
Sized + Add<Self, Output = Self> + Sub<Self, Output = Self> + Neg<Output = Self> + Zero
{
}
#[cfg(test)]
pub fn assert_abelian_group_laws<T>(values: &[T])
where T: AbelianGroup + Clone + Eq + Debug {
for a in values {
assert_eq!(a.clone() + T::zero(), *a);
assert_eq!(T::zero() + a.clone(), *a);
assert_eq!(a.clone() + (-a.clone()), T::zero());
assert_eq!((-a.clone()) + a.clone(), T::zero());
assert_eq!(-(-a.clone()), *a);
for b in values {
let lhs = a.clone() + b.clone();
let rhs = b.clone() + a.clone();
assert_eq!(lhs, rhs);
for c in values {
let lhs = (a.clone() + b.clone()) + c.clone();
let rhs = a.clone() + (b.clone() + c.clone());
assert_eq!(lhs, rhs);
}
}
}
}