inertia_algebra/structures/
grouplike.rs1
2use crate::*;
3
4pub type Elem<T> = <T as Parent>::Element;
5pub type Par<T> = <T as Element>::Parent;
6
7pub trait Parent: Clone {
8 type Element: Element<Parent=Self>;
9}
10
11pub trait Element: Clone + PartialEq {
12 type Parent: Parent<Element=Self>;
13
14 fn parent(&self) -> Self::Parent;
15}
16
17pub trait AbstractMagma<O: Operator>:
26 Parent<Element=<Self as AbstractMagma<O>>::Element>
27{
28 type Element: AbstractMagmaElement<O, Parent=Self>;
29 fn is_abstract_magma(&self, _: O) -> bool { true }
30}
31
32pub trait AbstractMagmaElement<O: Operator>:
33 Element<Parent=<Self as AbstractMagmaElement<O>>::Parent>
34 + Operation<O>
35{
36 type Parent: AbstractMagma<O, Element=Self>;
37}
38
39impl<T, O: Operator> AbstractMagma<O> for T
40where
41 T: Parent,
42 Elem<T>: Operation<O>
43{
44 type Element = Elem<T>;
45}
46
47impl<T, O: Operator> AbstractMagmaElement<O> for T
48where
49 T: Element + Operation<O>
50{
51 type Parent = Par<T>;
52}
53
54pub trait AbstractQuasigroup<O: Operator>:
74 AbstractMagma<O, Element=<Self as AbstractQuasigroup<O>>::Element>
75 + Divisible<O>
76{
77 type Element: AbstractQuasigroupElement<O, Parent=Self>;
78 fn is_abstract_quasigroup(&self, _: O) -> bool { true }
79}
80
81pub trait AbstractQuasigroupElement<O: Operator>:
82 AbstractMagmaElement<O, Parent=<Self as AbstractQuasigroupElement<O>>::Parent>
83 + TwoSidedInverse<O>
84{
85 type Parent: AbstractQuasigroup<O, Element=Self>;
86}
87
88impl<T, O: Operator> AbstractQuasigroup<O> for T
89where
90 T: AbstractMagma<O> + Divisible<O>,
91 Elem<T>: TwoSidedInverse<O>
92{
93 type Element = Elem<T>;
94}
95
96impl<T, O: Operator> AbstractQuasigroupElement<O> for T
97where
98 T: AbstractMagmaElement<O> + TwoSidedInverse<O>,
99 Par<T>: Divisible<O>
100{
101 type Parent = Par<T>;
102}
103
104pub trait AbstractSemigroup<O: Operator>:
114 AbstractMagma<O, Element=<Self as AbstractSemigroup<O>>::Element>
115 + Associative<O>
116{
117 type Element: AbstractSemigroupElement<O, Parent=Self>;
118 fn is_abstract_semigroup(&self, _: O) -> bool { true }
119}
120
121pub trait AbstractSemigroupElement<O: Operator>:
122 AbstractMagmaElement<O, Parent=<Self as AbstractSemigroupElement<O>>::Parent>
123{
124 type Parent: AbstractSemigroup<O, Element=Self>;
125}
126
127impl<T, O: Operator> AbstractSemigroup<O> for T
128where
129 T: AbstractMagma<O> + Associative<O>,
130{
131 type Element = Elem<T>;
132}
133
134impl<T, O: Operator> AbstractSemigroupElement<O> for T
135where
136 T: AbstractMagmaElement<O>,
137 Par<T>: Associative<O>
138{
139 type Parent = Par<T>;
140}
141
142pub trait AbstractLoop<O: Operator>:
161 AbstractQuasigroup<O, Element=<Self as AbstractLoop<O>>::Element>
162 + Identity<O>
163{
164 type Element: AbstractLoopElement<O, Parent=Self>;
165 fn is_abstract_loop(&self, _: O) -> bool { true }
166}
167
168pub trait AbstractLoopElement<O: Operator>:
169 AbstractQuasigroupElement<O, Parent=<Self as AbstractLoopElement<O>>::Parent>
170 + IsIdentity<O>
171{
172 type Parent: AbstractLoop<O, Element=Self>;
173
174}
175
176impl<T, O: Operator> AbstractLoop<O> for T
177where
178 T: AbstractQuasigroup<O> + Identity<O>,
179 Elem<T>: IsIdentity<O>
180{
181 type Element = Elem<T>;
182}
183
184impl<T, O: Operator> AbstractLoopElement<O> for T
185where
186 T: AbstractQuasigroupElement<O> + IsIdentity<O>,
187 Par<T>: Identity<O>
188{
189 type Parent = Par<T>;
190}
191
192pub trait AbstractMonoid<O: Operator>:
203 AbstractSemigroup<O, Element=<Self as AbstractMonoid<O>>::Element>
204 + Identity<O>
205{
206 type Element: AbstractMonoidElement<O, Parent=Self>;
207 fn is_abstract_monoid(&self, _: O) -> bool { true }
208}
209
210pub trait AbstractMonoidElement<O: Operator>:
211 AbstractSemigroupElement<O, Parent=<Self as AbstractMonoidElement<O>>::Parent>
212 + IsIdentity<O>
213{
214 type Parent: AbstractMonoid<O, Element=Self>;
215}
216
217impl<T, O: Operator> AbstractMonoid<O> for T
218where
219 T: AbstractSemigroup<O> + Identity<O>,
220 Elem<T>: IsIdentity<O>
221{
222 type Element = Elem<T>;
223}
224
225impl<T, O: Operator> AbstractMonoidElement<O> for T
226where
227 T: AbstractSemigroupElement<O> + IsIdentity<O>,
228 Par<T>: Identity<O>
229{
230 type Parent = Par<T>;
231}
232
233pub trait AbstractGroup<O: Operator>:
237 AbstractLoop<O, Element=<Self as AbstractGroup<O>>::Element>
238 + Associative<O>
239{
240 type Element: AbstractGroupElement<O, Parent=Self>;
241 fn is_abstract_group(&self, _: O) -> bool { true }
242}
243
244pub trait AbstractGroupElement<O: Operator>:
245 AbstractLoopElement<O, Parent=<Self as AbstractGroupElement<O>>::Parent>
246{
247 type Parent: AbstractGroup<O, Element=Self>;
248}
249
250impl<T, O: Operator> AbstractGroup<O> for T
251where
252 T: AbstractLoop<O> + Associative<O>,
253{
254 type Element = Elem<T>;
255}
256
257impl<T, O: Operator> AbstractGroupElement<O> for T
258where
259 T: AbstractLoopElement<O>,
260 Par<T>: Associative<O>
261{
262 type Parent = Par<T>;
263}
264
265pub trait AbstractGroupAbelian<O: Operator>:
275 AbstractGroup<O, Element=<Self as AbstractGroupAbelian<O>>::Element>
276 + Commutative<O>
277{
278 type Element: AbstractGroupAbelianElement<O, Parent=Self>;
279 fn is_abstract_group_abelian(&self, _: O) -> bool { true }
280}
281
282pub trait AbstractGroupAbelianElement<O: Operator>:
283 AbstractGroupElement<O, Parent=<Self as AbstractGroupAbelianElement<O>>::Parent>
284{
285 type Parent: AbstractGroupAbelian<O, Element=Self>;
286}
287
288impl<T, O: Operator> AbstractGroupAbelian<O> for T
289where
290 T: AbstractGroup<O> + Commutative<O>,
291{
292 type Element = Elem<T>;
293}
294
295impl<T, O: Operator> AbstractGroupAbelianElement<O> for T
296where
297 T: AbstractGroupElement<O>,
298 Par<T>: Commutative<O>
299{
300 type Parent = Par<T>;
301}