Skip to main content

inertia_algebra/structures/specialized/
grouplike.rs

1
2use crate::*;
3use crate::ops::*;
4use crate::structures::*;
5
6/* Do macro stuff
7macro_rules! specialize_structures(
8    // **With type parameters** for the trait being implemented.
9    (
10        $specialized_parent:ident, 
11        $specialized_element:ident, 
12        $abstract_parent_trait:ident<$($ops: ident),*> : $($bounds: ident)*
13        $abstract_element_trait:ident<$($ops: ident),*> : $($bounds: ident)*
14    ) => {
15        /// [Alias] Algebraic structure specialized for one kind of operation.
16        pub trait $specialized: $abstract_trait<$($ops),*> $(+ $bounds)* { }
17        impl<T: $abstract_trait<$($ops),*> $(+ $bounds)*> $specialized for T { }
18    };
19    // **Without type parameters** for the trait being implemented.
20    (
21        $specialized_parent:ident, 
22        $specialized_element:ident, 
23        $abstract_trait: ident : $($bounds: ident)*
24    ) => {
25        /// [Alias] Algebraic structure specialized for one kind of operation.
26        pub trait $specialized: $abstract_trait $(+ $bounds)* { }
27        impl<T: $abstract_trait $(+ $bounds)*> $specialized for T { }
28    }
29);
30
31specialize_structures! {
32    AdditiveMagma,
33    AbstractMagma<Additive>: 
34}
35specialize_structures! {
36    AdditiveQuasigroup, 
37    AbstractQuasigroup<Additive>: AdditiveMagma SubOps
38}
39*/
40
41// ADDITIVE
42
43// Magma
44
45pub trait AdditiveMagma:
46    AbstractMagma<Additive, Element=<Self as AdditiveMagma>::Element> 
47{
48    type Element: AdditiveMagmaElement<Parent=Self>;
49    fn is_additive_magma(&self) -> bool { true }
50}
51
52pub trait AdditiveMagmaElement:
53    AbstractMagmaElement<Additive, Parent=<Self as AdditiveMagmaElement>::Parent>
54    + AddOps
55{
56    type Parent: AdditiveMagma<Element=Self>;
57}
58
59impl<T> AdditiveMagma for T
60where
61    T: AbstractMagma<Additive>,
62    <T as AbstractMagma<Additive>>::Element: AddOps
63{
64    type Element = Elem<T>;
65}
66
67impl<T> AdditiveMagmaElement for T
68where
69    T: AbstractMagmaElement<Additive>
70    + AddOps
71{
72    type Parent = Par<T>;
73}
74
75// Quasigroup
76
77pub trait AdditiveQuasigroup: 
78    AbstractQuasigroup<Additive, Element=<Self as AdditiveQuasigroup>::Element>
79{
80    type Element: AdditiveQuasigroupElement<Parent=Self>;
81    fn is_additive_quasigroup(&self) -> bool { true }
82}
83
84pub trait AdditiveQuasigroupElement:
85    AbstractQuasigroupElement<Additive, Parent=<Self as AdditiveQuasigroupElement>::Parent>
86    + NegOps
87    + SubOps
88{
89    type Parent: AdditiveQuasigroup<Element=Self>;
90}
91
92impl<T> AdditiveQuasigroup for T
93where
94    T: AbstractQuasigroup<Additive>,
95    <T as AbstractQuasigroup<Additive>>::Element: NegOps + SubOps
96{
97    type Element = Elem<T>;
98}
99
100impl<T> AdditiveQuasigroupElement for T
101where
102    T: AbstractQuasigroupElement<Additive>
103    + NegOps
104    + SubOps
105{
106    type Parent = Par<T>;
107}
108
109// Semigroup
110
111pub trait AdditiveSemigroup: 
112    AbstractSemigroup<Additive, Element=<Self as AdditiveSemigroup>::Element>
113{
114    type Element: AdditiveSemigroupElement<Parent=Self>;
115    fn is_additive_semigroup(&self) -> bool { true }
116}
117
118pub trait AdditiveSemigroupElement:
119    AbstractSemigroupElement<Additive, Parent=<Self as AdditiveSemigroupElement>::Parent>
120{
121    type Parent: AdditiveSemigroup<Element=Self>;
122}
123
124impl<T> AdditiveSemigroup for T
125where
126    T: AbstractSemigroup<Additive> 
127{
128    type Element = Elem<T>;
129}
130
131impl<T> AdditiveSemigroupElement for T
132where
133    T: AbstractSemigroupElement<Additive>
134{
135    type Parent = Par<T>;
136}
137
138// Loop
139
140pub trait AdditiveLoop: 
141    AbstractLoop<Additive, Element=<Self as AdditiveLoop>::Element>
142{
143    type Element: AdditiveLoopElement<Parent=Self>;
144    fn is_additive_loop(&self) -> bool { true }
145}
146
147pub trait AdditiveLoopElement:
148    AbstractLoopElement<Additive, Parent=<Self as AdditiveLoopElement>::Parent>
149{
150    type Parent: AdditiveLoop<Element=Self>;
151}
152
153impl<T> AdditiveLoop for T
154where
155    T: AbstractLoop<Additive> 
156{
157    type Element = Elem<T>;
158}
159
160impl<T> AdditiveLoopElement for T
161where
162    T: AbstractLoopElement<Additive>
163{
164    type Parent = Par<T>;
165}
166
167// Monoid
168
169pub trait AdditiveMonoid: 
170    AbstractMonoid<Additive, Element=<Self as AdditiveMonoid>::Element>
171{
172    type Element: AdditiveMonoidElement<Parent=Self>;
173    fn is_additive_monoid(&self) -> bool { true }
174}
175
176pub trait AdditiveMonoidElement:
177    AbstractMonoidElement<Additive, Parent=<Self as AdditiveMonoidElement>::Parent>
178{
179    type Parent: AdditiveMonoid<Element=Self>;
180}
181
182impl<T> AdditiveMonoid for T
183where
184    T: AbstractMonoid<Additive> 
185{
186    type Element = Elem<T>;
187}
188
189impl<T> AdditiveMonoidElement for T
190where
191    T: AbstractMonoidElement<Additive>
192{
193    type Parent = Par<T>;
194}
195
196// Group
197
198pub trait AdditiveGroup: 
199    AbstractGroup<Additive, Element=<Self as AdditiveGroup>::Element>
200{
201    type Element: AdditiveGroupElement<Parent=Self>;
202    fn is_additive_group(&self) -> bool { true }
203}
204
205pub trait AdditiveGroupElement:
206    AbstractGroupElement<Additive, Parent=<Self as AdditiveGroupElement>::Parent>
207{
208    type Parent: AdditiveGroup<Element=Self>;
209}
210
211impl<T> AdditiveGroup for T
212where
213    T: AbstractGroup<Additive> 
214{
215    type Element = Elem<T>;
216}
217
218impl<T> AdditiveGroupElement for T
219where
220    T: AbstractGroupElement<Additive>
221{
222    type Parent = Par<T>;
223}
224
225// GroupAbelian
226
227pub trait AdditiveGroupAbelian: 
228    AbstractGroupAbelian<Additive, Element=<Self as AdditiveGroupAbelian>::Element>
229{
230    type Element: AdditiveGroupAbelianElement<Parent=Self>;
231    fn is_additive_group_abelian(&self) -> bool { true }
232}
233
234pub trait AdditiveGroupAbelianElement:
235    AbstractGroupAbelianElement<Additive, Parent=<Self as AdditiveGroupAbelianElement>::Parent>
236{
237    type Parent: AdditiveGroupAbelian<Element=Self>;
238}
239
240impl<T> AdditiveGroupAbelian for T
241where
242    T: AbstractGroupAbelian<Additive> 
243{
244    type Element = Elem<T>;
245}
246
247impl<T> AdditiveGroupAbelianElement for T
248where
249    T: AbstractGroupAbelianElement<Additive>
250{
251    type Parent = Par<T>;
252}
253
254// MULTIPLICATIVE
255
256// Magma
257
258pub trait MultiplicativeMagma: 
259    AbstractMagma<Multiplicative, Element=<Self as MultiplicativeMagma>::Element> 
260{
261    type Element: MultiplicativeMagmaElement<Parent=Self>;
262    fn is_multiplicative_magma(&self) -> bool { true }
263}
264
265pub trait MultiplicativeMagmaElement:
266    AbstractMagmaElement<Multiplicative, Parent=<Self as MultiplicativeMagmaElement>::Parent>
267    + MulOps
268{
269    type Parent: MultiplicativeMagma<Element=Self>;
270}
271
272impl<T> MultiplicativeMagma for T
273where
274    T: AbstractMagma<Multiplicative>,
275    <T as AbstractMagma<Multiplicative>>::Element: MulOps
276{
277    type Element = Elem<T>;
278}
279
280impl<T> MultiplicativeMagmaElement for T
281where
282    T: AbstractMagmaElement<Multiplicative>
283    + MulOps
284{
285    type Parent = Par<T>;
286}
287
288// Quasigroup
289
290pub trait MultiplicativeQuasigroup: 
291    AbstractQuasigroup<Multiplicative, Element=<Self as MultiplicativeQuasigroup>::Element>
292{
293    type Element: MultiplicativeQuasigroupElement<Parent=Self>;
294    fn is_multiplicative_quasigroup(&self) -> bool { true }
295}
296
297pub trait MultiplicativeQuasigroupElement:
298    AbstractQuasigroupElement<Multiplicative, Parent=<Self as MultiplicativeQuasigroupElement>::Parent>
299    + DivOps + InvOps
300{
301    type Parent: MultiplicativeQuasigroup<Element=Self>;
302}
303
304impl<T> MultiplicativeQuasigroup for T
305where
306    T: AbstractQuasigroup<Multiplicative>,
307    <T as AbstractMagma<Multiplicative>>::Element: DivOps + InvOps
308{
309    type Element = Elem<T>;
310}
311
312impl<T> MultiplicativeQuasigroupElement for T
313where
314    T: AbstractQuasigroupElement<Multiplicative>
315    + DivOps + InvOps
316{
317    type Parent = Par<T>;
318}
319
320// Semigroup
321
322pub trait MultiplicativeSemigroup: 
323    AbstractSemigroup<Multiplicative, Element=<Self as MultiplicativeSemigroup>::Element>
324{
325    type Element: MultiplicativeSemigroupElement<Parent=Self>;
326    fn is_multiplicative_semigroup(&self) -> bool { true }
327}
328
329pub trait MultiplicativeSemigroupElement:
330    AbstractSemigroupElement<Multiplicative, Parent=<Self as MultiplicativeSemigroupElement>::Parent>
331{
332    type Parent: MultiplicativeSemigroup<Element=Self>;
333}
334
335impl<T> MultiplicativeSemigroup for T
336where
337    T: AbstractSemigroup<Multiplicative> 
338{
339    type Element = Elem<T>;
340}
341
342impl<T> MultiplicativeSemigroupElement for T
343where
344    T: AbstractSemigroupElement<Multiplicative>
345{
346    type Parent = Par<T>;
347}
348
349// Loop
350
351pub trait MultiplicativeLoop: 
352    AbstractLoop<Multiplicative, Element=<Self as MultiplicativeLoop>::Element>
353{
354    type Element: MultiplicativeLoopElement<Parent=Self>;
355    fn is_multiplicative_loop(&self) -> bool { true }
356}
357
358pub trait MultiplicativeLoopElement:
359    AbstractLoopElement<Multiplicative, Parent=<Self as MultiplicativeLoopElement>::Parent>
360{
361    type Parent: MultiplicativeLoop<Element=Self>;
362}
363
364impl<T> MultiplicativeLoop for T
365where
366    T: AbstractLoop<Multiplicative> 
367{
368    type Element = Elem<T>;
369}
370
371impl<T> MultiplicativeLoopElement for T
372where
373    T: AbstractLoopElement<Multiplicative>
374{
375    type Parent = Par<T>;
376}
377
378// Monoid
379
380pub trait MultiplicativeMonoid: 
381    AbstractMonoid<Multiplicative, Element=<Self as MultiplicativeMonoid>::Element>
382{
383    type Element: MultiplicativeMonoidElement<Parent=Self>;
384    fn is_multiplicative_monoid(&self) -> bool { true }
385}
386
387pub trait MultiplicativeMonoidElement:
388    AbstractMonoidElement<Multiplicative, Parent=<Self as MultiplicativeMonoidElement>::Parent>
389{
390    type Parent: MultiplicativeMonoid<Element=Self>;
391}
392
393impl<T> MultiplicativeMonoid for T
394where
395    T: AbstractMonoid<Multiplicative> 
396{
397    type Element = Elem<T>;
398}
399
400impl<T> MultiplicativeMonoidElement for T
401where
402    T: AbstractMonoidElement<Multiplicative>
403{
404    type Parent = Par<T>;
405}
406
407// Group
408
409pub trait MultiplicativeGroup: 
410    AbstractGroup<Multiplicative, Element=<Self as MultiplicativeGroup>::Element>
411{
412    type Element: MultiplicativeGroupElement<Parent=Self>;
413    fn is_multiplicative_group(&self) -> bool { true }
414}
415
416pub trait MultiplicativeGroupElement:
417    AbstractGroupElement<Multiplicative, Parent=<Self as MultiplicativeGroupElement>::Parent>
418{
419    type Parent: MultiplicativeGroup<Element=Self>;
420}
421
422impl<T> MultiplicativeGroup for T
423where
424    T: AbstractGroup<Multiplicative> 
425{
426    type Element = Elem<T>;
427}
428
429impl<T> MultiplicativeGroupElement for T
430where
431    T: AbstractGroupElement<Multiplicative>
432{
433    type Parent = Par<T>;
434}
435
436// GroupAbelian
437
438pub trait MultiplicativeGroupAbelian: 
439    AbstractGroupAbelian<Multiplicative, Element=<Self as MultiplicativeGroupAbelian>::Element>
440{
441    type Element: MultiplicativeGroupAbelianElement<Parent=Self>;
442    fn is_multiplicative_group_abelian(&self) -> bool { true }
443}
444
445pub trait MultiplicativeGroupAbelianElement:
446    AbstractGroupAbelianElement<Multiplicative, Parent=<Self as MultiplicativeGroupAbelianElement>::Parent>
447{
448    type Parent: MultiplicativeGroupAbelian<Element=Self>;
449}
450
451impl<T> MultiplicativeGroupAbelian for T
452where
453    T: AbstractGroupAbelian<Multiplicative> 
454{
455    type Element = Elem<T>;
456}
457
458impl<T> MultiplicativeGroupAbelianElement for T
459where
460    T: AbstractGroupAbelianElement<Multiplicative>
461{
462    type Parent = Par<T>;
463}