use ops::{Additive, Multiplicative};
use cmp::ApproxEq;
use wrapper::Wrapper as W;
use structure::MonoidApprox;
use structure::Monoid;
use structure::GroupAbelianApprox;
use structure::GroupAbelian;
pub trait RingApprox
: GroupAbelianApprox<Additive>
+ MonoidApprox<Multiplicative>
{
fn prop_mul_and_add_are_distributive_approx(args: (Self, Self, Self)) -> bool {
let (a, b, c) = (|| W(args.0.clone()), || W(args.1.clone()), || W(args.2.clone()));
((a() * b()) + c()).approx_eq(&((a() * b()) + (a() * c()))) &&
((b() + c()) * a()).approx_eq(&((b() * a()) + (c() * a())))
}
}
impl_marker!(RingApprox; i8, i16, i32, i64);
pub trait Ring
: RingApprox
+ GroupAbelian<Additive>
+ Monoid<Multiplicative>
{
fn prop_mul_and_add_are_distributive_approx(args: (Self, Self, Self)) -> bool {
let (a, b, c) = (|| W(args.0.clone()), || W(args.1.clone()), || W(args.2.clone()));
(a() * b()) + c() == (a() * b()) + (a() * c()) &&
(b() + c()) * a() == (b() * a()) + (c() * a())
}
}
impl_marker!(Ring; i8, i16, i32, i64);
pub trait RingCommutativeApprox
: RingApprox
{
fn prop_mul_is_commutative_approx(args: (Self, Self)) -> bool {
let (a, b) = (|| W(args.0.clone()), || W(args.1.clone()));
(a() * b()).approx_eq(&(b() * a()))
}
}
impl_marker!(RingCommutativeApprox; i8, i16, i32, i64);
pub trait RingCommutative
: RingCommutativeApprox
+ Ring
{
fn prop_mul_is_commutative(args: (Self, Self)) -> bool {
let (a, b) = (|| W(args.0.clone()), || W(args.1.clone()));
a() * b() == b() * a()
}
}
impl_marker!(RingCommutative; i8, i16, i32, i64);
pub trait FieldApprox
: RingCommutativeApprox
+ GroupAbelianApprox<Multiplicative>
{}
pub trait Field
: FieldApprox
+ RingCommutative
+ GroupAbelian<Multiplicative>
{}