1use crate::{AddGrp, AddGrpOps, Mon, MonOps, Sign};
2
3pub trait RingOps<T = Self>:
6 AddGrpOps<T> +
7 MonOps<T>
8{}
9
10pub trait Ring:
11 AddGrp +
12 Mon +
13 RingOps
14where
15 for<'a> &'a Self: RingOps<Self>
16{
17 fn from_sign(s: Sign) -> Self {
18 if s.is_positive() {
19 Self::one()
20 } else {
21 -Self::one()
22 }
23 }
24
25 fn inv(&self) -> Option<Self>;
26 fn is_unit(&self) -> bool;
27 fn normalizing_unit(&self) -> Self;
28
29 fn normalized(&self) -> Self {
30 self.clone().into_normalized()
31 }
32
33 fn into_normalized(self) -> Self {
34 let u = self.normalizing_unit();
35 if u.is_one() {
36 self
37 } else {
38 self * u
39 }
40 }
41
42 fn is_pm_one(&self) -> bool {
43 self.is_one() || (-self).is_one()
44 }
45
46 fn c_weight(&self) -> f64 {
48 if self.is_zero() {
49 0.0
50 } else {
51 1.0
52 }
53 }
54}
55
56#[cfg(test)]
57mod tests {
58 use crate::Ring;
59
60 #[test]
61 fn is_pm_one() {
62 assert!(1.is_pm_one());
63 assert!((-1).is_pm_one());
64 assert!(!2.is_pm_one());
65 assert!(!(-2).is_pm_one());
66 }
67
68 #[test]
69 fn normalized() {
70 assert_eq!(3.normalized(), 3);
71 assert_eq!((-3).normalized(), 3);
72 }
73
74}