Skip to main content

cas_domain/
ring.rs

1//! 环与域的代数 trait 层(D2)。
2//!
3//! P0-M2 引入 Ring/Field,poly 内核泛型于此。EuclideanDomain(gcd,
4//! M3 的 PRS/因式分解用)随后引入。实现类型自带规范形(相等 ⇔ 值相等),
5//! trait 运算保持规范形。
6
7use crate::{Integer, Rational};
8
9/// 交换环(含单位元)。
10pub trait Ring: Sized + Clone + PartialEq {
11    fn zero() -> Self;
12    fn one() -> Self;
13    /// 由 i64 构造系数(poly 偏导的指数乘子等用途)。
14    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    /// 非负整数幂;默认重复乘,实现方可覆写快速路径。
23    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
32/// 域:环 + 乘法逆(零无逆)。
33pub 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 规范形保证既约,幂仍既约(跳过 gcd 的快速路径)
100        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}