1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
//!
//! Algebraic trait implementations for _rational_ numbers.
//!
//! The rational numbers (ℚ) form a _field_. We assume the
//! _numerator_ and _denominator_ of a rational number are unbounded
//! signed integers. Rationals implemented using Rust integer types
//! (e.g. i64) overflow too easily during generative testing.
//!
//! In the absence of a rational number type in the Rust standard
//! library, the "big rational" number type used here is from the very
//! handy [num] crate.
//!
#![doc(include = "../doc/references.md")]

use prelude::*;
pub use num::traits::*;
pub use num::rational::*;


///
/// Rational numbers form an additive magma.
///
impl AddMagma for BigRational {

  /// Addition is rational addition.
  fn add(&self, other: &Self) -> Self {
    self + other
  }
}


///
/// Rational numbers form an additive semigroup.
///
impl AddSemigroup for BigRational {}


///
/// Rational numbers form an additive monoid.
///
impl AddMonoid for BigRational {

  /// Zero is rational zero.
  fn zero() -> Self {
    Self::from_integer(Zero::zero())
  }
}


///
/// Rational numbers form an additive group.
///
impl AddGroup for BigRational {

  /// Negation is rational negation.
  fn negate(&self) -> Self {
    -self
  }
}


///
/// Rational numbers form an additive commutative group.
///
impl AddComGroup for BigRational {}

  
///
/// Rational numbers form a multiplicative magma.
///
impl MulMagma for BigRational {

  /// Multiplication is rational multiplication.
  fn mul(&self, other: &Self) -> Self {
    self * other
  }
}


///
/// Rational numbers form a multiplicative semigroup.
///
impl MulSemigroup for BigRational {}


///
/// Rational numbers form a multiplicative monoid.
///
impl MulMonoid for BigRational {

  /// One is rational one.
  fn one() -> Self {
    Self::from_integer(One::one())
  }
}


///
/// Rational numbers (without zero) form a multiplicative group.
///
impl MulGroup for BigRational {

  /// Inversion is rational reciprocal.
  fn invert(&self) -> Self {
    self.recip()
  }

  
  /// Non-zero rationals are invertible.
  fn is_invertible(&self) -> bool {
    *self != Self::from_integer(Zero::zero())
  }
}


///
/// Rational numbers (without zero) form a multiplicative
/// commutative group.
///
impl MulComGroup for BigRational {}


///
/// Rational numbers form a ring.
///
impl Ring for BigRational {}


///
/// Rational numbers form a commutative ring.
///
impl ComRing for BigRational {}


///
/// Rational numbers (without zero) form a field.
///
impl Field for BigRational {

  /// Inversion is rational reciprocal.
  fn invert(&self) -> Self {
    self.recip()
  }  
}


// Module unit tests are in a separate file.
#[cfg(test)]
#[path = "rational_test.rs"]
mod rational_test;