haar_lib/algebra/
traits.rs1use crate::trait_alias;
3
4pub trait Set: Sized {
6 type Element;
8}
9
10pub trait BinaryOp: Set {
12 fn op(&self, a: Self::Element, b: Self::Element) -> Self::Element;
14
15 fn op_assign_r(&self, a: &mut Self::Element, b: Self::Element)
17 where
18 Self::Element: Clone,
19 {
20 *a = self.op(a.clone(), b);
21 }
22
23 fn op_assign_l(&self, a: &mut Self::Element, b: Self::Element)
25 where
26 Self::Element: Clone,
27 {
28 *a = self.op(b, a.clone());
29 }
30}
31
32pub trait Identity: Set {
34 fn id(&self) -> Self::Element;
36 fn is_id(&self, a: &Self::Element) -> bool
38 where
39 Self::Element: PartialEq,
40 {
41 a == &self.id()
42 }
43}
44
45pub trait Inverse: Set {
47 fn inv(&self, a: Self::Element) -> Self::Element;
49}
50
51pub trait Commutative {}
53pub trait Associative {}
55pub trait Idempotence {}
57
58pub trait Additive: BinaryOp {
60 fn times(&self, a: Self::Element, n: u64) -> Self::Element;
61}
62
63pub trait Multiplicative: BinaryOp {}
65
66pub trait Ordered: BinaryOp<Element: Ord> {}
70
71pub trait Semigroup: BinaryOp + Associative {
73 fn reduce<I>(&self, iter: I) -> Option<Self::Element>
76 where
77 I: IntoIterator<Item = Self::Element>,
78 {
79 iter.into_iter().reduce(|a, b| self.op(a, b))
80 }
81}
82impl<T: BinaryOp + Associative> Semigroup for T {}
83
84pub trait Monoid: Semigroup + Identity {
86 fn fold_m<I>(&self, iter: I) -> Self::Element
89 where
90 I: IntoIterator<Item = Self::Element>,
91 {
92 self.reduce(iter).unwrap_or(self.id())
93 }
94
95 fn times(&self, mut a: Self::Element, mut n: u64) -> Self::Element
97 where
98 Self::Element: Clone,
99 {
100 let mut ret = self.id();
101
102 while n > 0 {
103 if n & 1 == 1 {
104 ret = self.op(ret, a.clone());
105 }
106 a = self.op(a.clone(), a);
107 n >>= 1;
108 }
109
110 ret
111 }
112}
113impl<T: Semigroup + Identity> Monoid for T {}
114
115trait_alias!(#[doc = "可換モノイド"] AbelianMonoid: Monoid + Commutative);
116trait_alias!(#[doc = "群"] Group: Monoid + Inverse);
117trait_alias!(#[doc = "可換群"] AbelianGroup: Group + Commutative);
118
119trait_alias!(#[doc = "半束"] Semilattice: Semigroup + Commutative + Idempotence);
120
121pub trait FoldM: Iterator {
123 fn fold_m<M>(self, monoid: &M) -> Self::Item
125 where
126 Self: Sized,
127 M: Monoid<Element = Self::Item>,
128 {
129 monoid.fold_m(self)
130 }
131}
132
133impl<I> FoldM for I where I: Iterator + ?Sized {}