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
pub trait UnitaryRing<Output = Self>:
Sized
+ Clone
+ num_traits::Zero
+ num_traits::One
+ std::ops::Neg<Output = Output>
+ for<'x> std::ops::AddAssign<&'x Self>
+ for<'x> std::ops::SubAssign<&'x Self>
+ for<'x> std::ops::MulAssign<&'x Self>
{
}
impl<T> UnitaryRing for T where
T: Sized
+ Clone
+ num_traits::Zero
+ num_traits::One
+ std::ops::Neg<Output = Self>
+ for<'x> std::ops::AddAssign<&'x Self>
+ for<'x> std::ops::SubAssign<&'x Self>
+ for<'x> std::ops::MulAssign<&'x Self>
{
}
pub trait EuclideanRing<Output = Self>:
UnitaryRing + for<'x> std::ops::DivAssign<&'x Self> + for<'x> std::ops::RemAssign<&'x Self>
{
}
impl<T> EuclideanRing for T where
T: UnitaryRing + for<'x> std::ops::DivAssign<&'x Self> + for<'x> std::ops::RemAssign<&'x Self>
{
}
pub trait RingOperation<Output = Self>:
Sized
+ std::ops::Add<Output = Output>
+ std::ops::Sub<Output = Output>
+ std::ops::Mul<Output = Output>
{
}
impl<T> RingOperation<T> for T where
T: Sized + std::ops::Add<Output = T> + std::ops::Sub<Output = T> + std::ops::Mul<Output = T>
{
}
impl<'a, T> RingOperation<T> for &'a T where
&'a T:
Sized + std::ops::Add<Output = T> + std::ops::Sub<Output = T> + std::ops::Mul<Output = T>
{
}
pub trait EuclideanRingOperation<Output = Self>:
RingOperation<Output> + std::ops::Div<Output = Output> + std::ops::Rem<Output = Output>
{
}
impl<T> EuclideanRingOperation<T> for T where
T: RingOperation<T> + std::ops::Div<Output = T> + std::ops::Rem<Output = T>
{
}
impl<'a, T> EuclideanRingOperation<T> for &'a T where
&'a T: RingOperation<T> + std::ops::Div<Output = T> + std::ops::Rem<Output = T>
{
}
pub trait RingNormalize {
fn leading_unit(&self) -> Self;
fn normalize_mut(&mut self);
fn into_normalize(mut self) -> Self
where
Self: Sized,
{
self.normalize_mut();
self
}
fn normalize(&self) -> Self
where
Self: Clone,
{
self.clone().into_normalize()
}
fn is_similar(&self, other: &Self) -> bool
where
Self: Clone + Eq,
{
self.normalize() == other.normalize()
}
}
#[cfg(feature = "debug")]
pub trait DebugOnFeature: std::fmt::Debug + std::fmt::Display {}
#[cfg(feature = "debug")]
impl<T> DebugOnFeature for T where T: std::fmt::Debug + std::fmt::Display {}
#[cfg(not(feature = "debug"))]
pub trait DebugOnFeature {}
#[cfg(not(feature = "debug"))]
impl<T> DebugOnFeature for T {}
macro_rules! ring_normalize {
($t:ty) => {
impl RingNormalize for $t {
fn leading_unit(&self) -> Self {
use num_traits::{One, Zero};
if self >= &<$t>::zero() {
<$t>::one()
} else {
-<$t>::one()
}
}
fn normalize_mut(&mut self) {
*self = self.abs();
}
}
};
}
ring_normalize!(i8);
ring_normalize!(i16);
ring_normalize!(i32);
ring_normalize!(i64);
ring_normalize!(i128);
ring_normalize!(isize);