1use crate::{Integer, Rational};
8
9pub trait Ring: Sized + Clone + PartialEq {
11 fn zero() -> Self;
12 fn one() -> Self;
13 fn from_i64_coeff(v: i64) -> Self;
15 fn add(&self, other: &Self) -> Self;
16 fn sub(&self, other: &Self) -> Self;
17 fn mul(&self, other: &Self) -> Self;
18 fn neg(&self) -> Self;
19 fn is_zero(&self) -> bool;
20 fn is_one(&self) -> bool;
21
22 fn pow_u32(&self, e: u32) -> Self {
24 let mut acc = Self::one();
25 for _ in 0..e {
26 acc = acc.mul(self);
27 }
28 acc
29 }
30}
31
32pub trait Field: Ring {
34 fn inv(&self) -> Option<Self>;
35}
36
37impl Ring for Integer {
38 fn zero() -> Self {
39 Integer::zero()
40 }
41 fn one() -> Self {
42 Integer::one()
43 }
44 fn from_i64_coeff(v: i64) -> Self {
45 Integer::from_i64(v)
46 }
47 fn add(&self, other: &Self) -> Self {
48 Integer::add(self, other)
49 }
50 fn sub(&self, other: &Self) -> Self {
51 Integer::sub(self, other)
52 }
53 fn mul(&self, other: &Self) -> Self {
54 Integer::mul(self, other)
55 }
56 fn neg(&self) -> Self {
57 Integer::neg(self)
58 }
59 fn is_zero(&self) -> bool {
60 Integer::is_zero(self)
61 }
62 fn is_one(&self) -> bool {
63 Integer::is_one(self)
64 }
65 fn pow_u32(&self, e: u32) -> Self {
66 Integer::pow(self, e)
67 }
68}
69
70impl Ring for Rational {
71 fn zero() -> Self {
72 Rational::zero()
73 }
74 fn one() -> Self {
75 Rational::one()
76 }
77 fn from_i64_coeff(v: i64) -> Self {
78 Rational::from_integer(&Integer::from_i64(v))
79 }
80 fn add(&self, other: &Self) -> Self {
81 Rational::add(self, other)
82 }
83 fn sub(&self, other: &Self) -> Self {
84 Rational::sub(self, other)
85 }
86 fn mul(&self, other: &Self) -> Self {
87 Rational::mul(self, other)
88 }
89 fn neg(&self) -> Self {
90 Rational::neg(self)
91 }
92 fn is_zero(&self) -> bool {
93 Rational::is_zero(self)
94 }
95 fn is_one(&self) -> bool {
96 Rational::is_one(self)
97 }
98 fn pow_u32(&self, e: u32) -> Self {
99 Rational::pow_reduced(self, e)
101 }
102}
103
104impl Field for Rational {
105 fn inv(&self) -> Option<Self> {
106 Rational::inv_reduced(self)
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113
114 #[test]
115 fn 整数环() {
116 let (a, b) = (Integer::from_i64(7), Integer::from_i64(-6));
117 assert!(a.add(&b).is_one());
118 let c = Integer::from_i64(7);
119 assert!(!c.mul(&Integer::from_i64(1)).is_one() || c.is_one());
120 assert_eq!(a.sub(&a), <Integer as Ring>::zero());
121 assert_eq!(Integer::from_i64(-3).pow_u32(3), Integer::from_i64(-27));
122 assert_eq!(<Integer as Ring>::from_i64_coeff(5), Integer::from_i64(5));
123 }
124
125 #[test]
126 fn 有理数域() {
127 let r = Rational::from_ints(&Integer::from_i64(3), &Integer::from_i64(4)).unwrap();
128 let inv = <Rational as Field>::inv(&r).unwrap();
129 assert!(inv.mul(&r).is_one());
130 assert!(Rational::zero().inv().is_none());
131 assert!(r.pow_u32(2).to_string() == "9/16");
132 }
133}