use std::fmt::Debug;
use auto_impl::auto_impl;
#[auto_impl(&)] pub trait SemiringOperations {
type Element: Clone + PartialEq + Debug;
fn is_0( &self, x : Self::Element ) -> bool;
fn is_1( &self, x : Self::Element ) -> bool;
fn zero() -> Self::Element;
fn one() -> Self::Element;
fn add( &self, x : Self::Element, y : Self::Element ) -> Self::Element;
fn multiply( &self, x : Self::Element, y: Self::Element ) -> Self::Element;
}
pub trait RingOperations: SemiringOperations {
fn subtract( &self, x : Self::Element, y: Self::Element ) -> Self::Element;
fn negate( &self, x : Self::Element ) -> Self::Element;
fn minus_one( &self ) -> Self::Element {
self.negate( Self::one() )
}
fn minus_one_to_power( &self, k: usize ) -> Self::Element {
if k.is_even() { Self::one() }
else { self.minus_one() }
}
}
pub trait DivisionRingOperations: RingOperations {
fn divide( &self, x : Self::Element, y: Self::Element ) -> Self::Element;
fn invert( &self, x : Self::Element ) -> Self::Element;
}
use num::integer::Integer;
pub trait MinusOne: RingOperations {
fn minus_one( &self ) -> Self::Element;
}
impl < RingOperator >
MinusOne for
RingOperator
where
RingOperator: RingOperations
{
fn minus_one( &self ) -> Self::Element {
self.negate( RingOperator::one() )
}
}
pub trait MinusOneToPower: RingOperations {
fn minus_one_to_power( &self, k: usize ) -> Self::Element;
}
impl < RingOperator >
MinusOneToPower for
RingOperator
where RingOperator: RingOperations
{
fn minus_one_to_power( &self, k: usize ) -> Self::Element {
if k.is_even() { RingOperator::one() }
else { self.minus_one() }
}
}