use ::num::rational::*;
use un_algebra::tests::*;
use un_algebra::prelude::*;
type Base = i128;
#[derive(Copy, Clone, Debug, PartialEq)]
struct Rational(Ratio<Base>);
impl Rational {
pub fn new(n: Base, d: Base) -> Self {
Self(Ratio::new(n, d))
}
}
impl AddMagma for Rational {
fn add(&self, other: &Self) -> Self {
Self(self.0 + other.0)
}
}
impl AddSemigroup for Rational {}
impl AddMonoid for Rational {
fn zero() -> Self {
Self::new(0, 1)
}
}
impl AddGroup for Rational {
fn negate(&self) -> Self {
Self(-self.0)
}
}
impl AddComGroup for Rational {}
impl MulMagma for Rational {
fn mul(&self, other: &Self) -> Self {
Self(self.0 * other.0)
}
}
impl MulSemigroup for Rational {}
impl Quasigroup for Rational {
fn is_divisor(&self) -> bool {
*self != Self::new(0, 1)
}
fn ldiv(&self, other: &Self) -> Self {
Self(other.0 / self.0)
}
fn rdiv(&self, other: &Self) -> Self {
Self(self.0 / other.0)
}
}
impl MulMonoid for Rational {
fn one() -> Self {
Self::new(1, 1)
}
}
impl MulGroup for Rational {
fn is_invertible(&self) -> bool {
*self != Self::new(0, 1)
}
fn invert(&self) -> Self {
Self(self.0.recip())
}
}
impl MulComGroup for Rational {}
impl Ring for Rational {}
impl ComRing for Rational {}
impl Field for Rational {
fn invert(&self) -> Self {
Self(self.0.recip())
}
}
fn r32() -> impl Strategy<Value = Rational> {
let ints = any::<(i32, i32)>();
ints.prop_map(|(n, d)| Rational::new(i128::from(n), i128::from(d)))
}
#[cfg(test)]
proptest! {
#![proptest_config(config::standard())]
#[test]
fn add_closure([p, q] in [r32(), r32()]) {
prop_assert!(AddMagmaLaws::closure(&p, &q))
}
#[test]
fn mul_closure([p, q] in [r32(), r32()]) {
prop_assert!(MulMagmaLaws::closure(&p, &q))
}
#[test]
fn mul_associative([p, q, r] in [r32(), r32(), r32()]) {
prop_assert!(MulSemigroupLaws::associativity(&p, &q, &r))
}
#[test]
fn left_ldiv([p, q] in [r32(), r32()]) {
prop_assume!(p.is_divisor());
prop_assert!(p.left_lcancellation(&q))
}
#[test]
fn right_ldiv([p, q] in [r32(), r32()]) {
prop_assume!(q.is_divisor());
prop_assert!(p.right_lcancellation(&q))
}
#[test]
fn left_rdiv([p, q] in [r32(), r32()]) {
prop_assume!(q.is_divisor());
prop_assert!(p.left_rcancellation(&q))
}
#[test]
fn right_rdiv([p, q] in [r32(), r32()]) {
prop_assume!(q.is_divisor());
prop_assert!(p.right_rcancellation(&q))
}
#[test]
fn add_associative([p, q, r] in [r32(), r32(), r32()]) {
prop_assert!(AddSemigroupLaws::associativity(&p, &q, &r))
}
#[test]
fn left_add_identity(q in r32()) {
prop_assert!(AddMonoidLaws::left_identity(&q))
}
#[test]
fn right_add_identity(q in r32()) {
prop_assert!(AddMonoidLaws::right_identity(&q))
}
#[test]
fn left_mul_identity(q in r32()) {
prop_assert!(MulMonoidLaws::left_identity(&q))
}
#[test]
fn right_mul_identity(q in r32()) {
prop_assert!(MulMonoidLaws::right_identity(&q))
}
#[test]
fn left_add_inverse(q in r32()) {
prop_assert!(AddGroupLaws::left_inverse(&q))
}
#[test]
fn right_add_inverse(q in r32()) {
prop_assert!(AddGroupLaws::right_inverse(&q))
}
#[test]
fn left_mul_inverse(q in r32()) {
prop_assume!(MulGroup::is_invertible(&q));
prop_assert!(MulGroupLaws::left_inverse(&q))
}
#[test]
fn right_mul_inverse(q in r32()) {
prop_assume!(MulGroup::is_invertible(&q));
prop_assert!(MulGroupLaws::right_inverse(&q))
}
#[test]
fn add_commute([p, q] in [r32(), r32()]) {
prop_assert!(AddComGroupLaws::commutivity(&p, &q))
}
#[test]
fn mul_commute([p, q] in [r32(), r32()]) {
prop_assert!(MulComGroupLaws::commutivity(&p, &q))
}
#[test]
fn left_distributivity([q, r, s] in [r32(), r32(), r32()]) {
prop_assert!(RingLaws::left_distributivity(&q, &r, &s))
}
#[test]
fn right_distributivity([q, r, s] in [r32(), r32(), r32()]) {
prop_assert!(RingLaws::right_distributivity(&q, &r, &s))
}
#[test]
fn left_absorption(q in r32()) {
prop_assert!(RingLaws::left_absorption(&q))
}
#[test]
fn right_absorption(q in r32()) {
prop_assert!(RingLaws::right_absorption(&q))
}
#[test]
fn left_negation((q, r) in (r32(), r32())) {
prop_assert!(RingLaws::left_negation(&q, &r))
}
#[test]
fn right_negation((q, r) in (r32(), r32())) {
prop_assert!(RingLaws::right_negation(&q, &r))
}
#[test]
fn commutivity((q, r) in (r32(), r32())) {
prop_assert!(ComRingLaws::commutivity(&q, &r))
}
#[test]
fn field_left_inverse(q in r32()) {
prop_assume!(Field::is_invertible(&q));
prop_assert!(FieldLaws::left_inverse(&q))
}
#[test]
fn field_right_inverse(q in r32()) {
prop_assume!(Field::is_invertible(&q));
prop_assert!(FieldLaws::left_inverse(&q))
}
#[test]
fn zero_cancellation([p, q] in [r32(), r32()]) {
prop_assert!(FieldLaws::zero_cancellation(&p, &q))
}
#[test]
fn add_cancellation([q, r, s] in [r32(), r32(), r32()]) {
prop_assert!(FieldLaws::add_cancellation(&q, &r, &s))
}
#[test]
fn mul_cancellation([q, r, s] in [r32(), r32(), r32()]) {
prop_assert!(FieldLaws::mul_cancellation(&q, &r, &s))
}
}
fn main() {
}