competitive/algebra/
ring.rs1use super::*;
2use std::{
3 marker::PhantomData,
4 ops::{Add, Mul},
5};
6
7pub trait SemiRing {
8 type T: Clone;
9 type Additive: AbelianMonoid<T = Self::T>;
10 type Multiplicative: Monoid<T = Self::T>;
11 fn zero() -> Self::T {
13 <Self::Additive as Unital>::unit()
14 }
15 fn is_zero(x: &Self::T) -> bool
17 where
18 Self::T: PartialEq,
19 {
20 *x == Self::zero()
21 }
22 fn one() -> Self::T {
24 <Self::Multiplicative as Unital>::unit()
25 }
26 fn is_one(x: &Self::T) -> bool
28 where
29 Self::T: PartialEq,
30 {
31 *x == Self::one()
32 }
33 fn add(x: &Self::T, y: &Self::T) -> Self::T {
35 <Self::Additive as Magma>::operate(x, y)
36 }
37 fn mul(x: &Self::T, y: &Self::T) -> Self::T {
39 <Self::Multiplicative as Magma>::operate(x, y)
40 }
41
42 fn add_assign(x: &mut Self::T, y: &Self::T) {
43 <Self::Additive as Magma>::operate_assign(x, y);
44 }
45
46 fn mul_assign(x: &mut Self::T, y: &Self::T) {
47 <Self::Multiplicative as Magma>::operate_assign(x, y);
48 }
49}
50
51pub trait Ring: SemiRing
52where
53 Self::Additive: Invertible,
54{
55 fn neg(x: &Self::T) -> Self::T {
57 <Self::Additive as Invertible>::inverse(x)
58 }
59 fn sub(x: &Self::T, y: &Self::T) -> Self::T {
61 <Self::Additive as Invertible>::rinv_operate(x, y)
62 }
63
64 fn sub_assign(x: &mut Self::T, y: &Self::T) {
65 <Self::Additive as Invertible>::rinv_operate_assign(x, y);
66 }
67}
68
69impl<R> Ring for R
70where
71 R: SemiRing,
72 R::Additive: Invertible,
73{
74}
75
76pub trait Field: Ring
77where
78 Self::Additive: Invertible,
79 Self::Multiplicative: Invertible,
80{
81 fn inv(x: &Self::T) -> Self::T {
83 <Self::Multiplicative as Invertible>::inverse(x)
84 }
85 fn div(x: &Self::T, y: &Self::T) -> Self::T {
87 <Self::Multiplicative as Invertible>::rinv_operate(x, y)
88 }
89
90 fn div_assign(x: &mut Self::T, y: &Self::T) {
91 <Self::Multiplicative as Invertible>::rinv_operate_assign(x, y);
92 }
93}
94
95impl<F> Field for F
96where
97 F: Ring,
98 F::Additive: Invertible,
99 F::Multiplicative: Invertible,
100{
101}
102
103pub struct AddMulOperation<T>
105where
106 T: Clone + Zero + One + Add<Output = T> + Mul<Output = T>,
107{
108 _marker: PhantomData<fn() -> T>,
109}
110impl<T> SemiRing for AddMulOperation<T>
111where
112 T: Clone + Zero + One + Add<Output = T> + Mul<Output = T>,
113{
114 type T = T;
115 type Additive = AdditiveOperation<T>;
116 type Multiplicative = MultiplicativeOperation<T>;
117}