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 one() -> Self::T {
17 <Self::Multiplicative as Unital>::unit()
18 }
19 fn add(x: &Self::T, y: &Self::T) -> Self::T {
21 <Self::Additive as Magma>::operate(x, y)
22 }
23 fn mul(x: &Self::T, y: &Self::T) -> Self::T {
25 <Self::Multiplicative as Magma>::operate(x, y)
26 }
27
28 fn add_assign(x: &mut Self::T, y: &Self::T) {
29 <Self::Additive as Magma>::operate_assign(x, y);
30 }
31
32 fn mul_assign(x: &mut Self::T, y: &Self::T) {
33 <Self::Multiplicative as Magma>::operate_assign(x, y);
34 }
35}
36
37pub trait Ring: SemiRing
38where
39 Self::Additive: Invertible,
40{
41 fn neg(x: &Self::T) -> Self::T {
43 <Self::Additive as Invertible>::inverse(x)
44 }
45 fn sub(x: &Self::T, y: &Self::T) -> Self::T {
47 <Self::Additive as Invertible>::rinv_operate(x, y)
48 }
49
50 fn sub_assign(x: &mut Self::T, y: &Self::T) {
51 <Self::Additive as Invertible>::rinv_operate_assign(x, y);
52 }
53}
54
55impl<R> Ring for R
56where
57 R: SemiRing,
58 R::Additive: Invertible,
59{
60}
61
62pub trait Field: Ring
63where
64 Self::Additive: Invertible,
65 Self::Multiplicative: Invertible,
66{
67 fn inv(x: &Self::T) -> Self::T {
69 <Self::Multiplicative as Invertible>::inverse(x)
70 }
71 fn div(x: &Self::T, y: &Self::T) -> Self::T {
73 <Self::Multiplicative as Invertible>::rinv_operate(x, y)
74 }
75
76 fn div_assign(x: &mut Self::T, y: &Self::T) {
77 <Self::Multiplicative as Invertible>::rinv_operate_assign(x, y);
78 }
79}
80
81impl<F> Field for F
82where
83 F: Ring,
84 F::Additive: Invertible,
85 F::Multiplicative: Invertible,
86{
87}
88
89pub struct AddMulOperation<T>
91where
92 T: Clone + Zero + One + Add<Output = T> + Mul<Output = T>,
93{
94 _marker: PhantomData<fn() -> T>,
95}
96impl<T> SemiRing for AddMulOperation<T>
97where
98 T: Clone + Zero + One + Add<Output = T> + Mul<Output = T>,
99{
100 type T = T;
101 type Additive = AdditiveOperation<T>;
102 type Multiplicative = MultiplicativeOperation<T>;
103}