1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
use crate::{
binary_operation::BinaryOperationId,
commutative_monoid::CommutativeMonoid,
distributive_property::DistributiveProperty,
magma::Magma,
monoid::Monoid,
zero_element::ZeroElement,
};
pub trait Semiring<Add, Mul>
where
Add: BinaryOperationId,
Mul: BinaryOperationId,
{
type S;
fn add(l: Self::S, r: Self::S) -> Self::S;
fn mul(l: Self::S, r: Self::S) -> Self::S;
fn zero() -> Self::S;
fn one() -> Self::S;
}
impl<S, Add, Mul, T> Semiring<Add, Mul> for T
where
T: CommutativeMonoid<Add, S = S>
+ Monoid<Mul, S = S>
+ DistributiveProperty<Add, Mul>
+ ZeroElement<Add, Mul>,
Add: BinaryOperationId,
Mul: BinaryOperationId,
{
type S = S;
fn add(l: Self::S, r: Self::S) -> Self::S {
<T as Magma<Add>>::operate(l, r)
}
fn mul(l: Self::S, r: Self::S) -> Self::S {
<T as Magma<Mul>>::operate(l, r)
}
fn zero() -> Self::S { <T as Monoid<Add>>::identity() }
fn one() -> Self::S { <T as Monoid<Mul>>::identity() }
}