1use std::fmt::Debug;
2use std::ops::{Add, Div, Mul, Sub};
3
4#[derive(Debug, Clone, Copy, PartialEq)]
5pub struct AlgebraicStructure<T>(pub T);
6
7impl<T: Add<Output = T> + Copy> Add for AlgebraicStructure<T> {
8 type Output = Self;
9
10 fn add(self, other: Self) -> Self {
11 AlgebraicStructure(self.0 + other.0)
12 }
13}
14
15impl<T: Sub<Output = T> + Copy> Sub for AlgebraicStructure<T> {
16 type Output = Self;
17
18 fn sub(self, other: Self) -> Self {
19 AlgebraicStructure(self.0 - other.0)
20 }
21}
22
23impl<T: Mul<Output = T> + Copy> Mul for AlgebraicStructure<T> {
24 type Output = Self;
25
26 fn mul(self, other: Self) -> Self {
27 AlgebraicStructure(self.0 * other.0)
28 }
29}
30
31impl<T: Div<Output = T> + Copy> Div for AlgebraicStructure<T> {
32 type Output = Self;
33
34 fn div(self, other: Self) -> Self {
35 AlgebraicStructure(self.0 / other.0)
36 }
37}
38
39pub trait Distributivity<T> {
40 fn verify_distributivity(&self, b: &Self, c: &Self) -> bool;
41}
42
43#[macro_export]
44macro_rules! algstruct {
45 ($name:ident, +, *) => {
46 #[derive(Debug, Clone, Copy, PartialEq)]
47 pub struct $name<T>(T);
48
49 impl<T: std::ops::Add<Output = T> + Copy> std::ops::Add for $name<T> {
50 type Output = Self;
51 fn add(self, other: Self) -> Self {
52 $name(self.0 + other.0)
53 }
54 }
55
56 impl<T: std::ops::Sub<Output = T> + Copy> std::ops::Sub for $name<T> {
57 type Output = Self;
58 fn sub(self, other: Self) -> Self {
59 $name(self.0 - other.0)
60 }
61 }
62
63 impl<T: std::ops::Mul<Output = T> + Copy> std::ops::Mul for $name<T> {
64 type Output = Self;
65 fn mul(self, other: Self) -> Self {
66 $name(self.0 * other.0)
67 }
68 }
69
70 impl<T: std::ops::Div<Output = T> + Copy> std::ops::Div for $name<T> {
71 type Output = Self;
72 fn div(self, other: Self) -> Self {
73 $name(self.0 / other.0)
74 }
75 }
76
77 impl<T> From<T> for $name<T> {
78 fn from(value: T) -> Self {
79 $name(value)
80 }
81 }
82 };
83
84 ($name:ident, +) => {
85 #[derive(Debug, Clone, Copy, PartialEq)]
86 struct $name<T>(T);
87
88 impl<T: std::ops::Add<Output = T> + Copy> std::ops::Add for $name<T> {
89 type Output = Self;
90 fn add(self, other: Self) -> Self {
91 $name(self.0 + other.0)
92 }
93 }
94
95 impl<T: std::ops::Sub<Output = T> + Copy> std::ops::Sub for $name<T> {
96 type Output = Self;
97 fn sub(self, other: Self) -> Self {
98 $name(self.0 - other.0)
99 }
100 }
101
102 impl<T> From<T> for $name<T> {
103 fn from(value: T) -> Self {
104 $name(value)
105 }
106 }
107 };
108
109 ($name:ident, *) => {
110 #[derive(Debug, Clone, Copy, PartialEq)]
111 struct $name<T>(T);
112
113 impl<T: std::ops::Mul<Output = T> + Copy> std::ops::Mul for $name<T> {
114 type Output = Self;
115 fn mul(self, other: Self) -> Self {
116 $name(self.0 * other.0)
117 }
118 }
119
120 impl<T: std::ops::Div<Output = T> + Copy> std::ops::Div for $name<T> {
121 type Output = Self;
122 fn div(self, other: Self) -> Self {
123 $name(self.0 / other.0)
124 }
125 }
126
127 impl<T> From<T> for $name<T> {
128 fn from(value: T) -> Self {
129 $name(value)
130 }
131 }
132 };
133}
134
135pub trait AdditiveOperation<T> {
136 fn add_op(&self, other: &Self) -> Self;
137}
138
139pub trait MultiplicativeOperation<T> {
140 fn mul_op(&self, other: &Self) -> Self;
141}
142
143impl<T: Add<Output = T> + Copy> AdditiveOperation<T> for AlgebraicStructure<T> {
144 fn add_op(&self, other: &Self) -> Self {
145 *self + *other
146 }
147}
148
149impl<T: Mul<Output = T> + Copy> MultiplicativeOperation<T> for AlgebraicStructure<T> {
150 fn mul_op(&self, other: &Self) -> Self {
151 *self * *other
152 }
153}
154
155pub trait ClosureUnderOperation<T> {
156 fn verify_closure_add(&self, other: &Self) -> bool
157 where
158 Self: AdditiveOperation<T>;
159 fn verify_closure_mul(&self, other: &Self) -> bool
160 where
161 Self: MultiplicativeOperation<T>;
162}
163
164impl<T: Add<Output = T> + Mul<Output = T> + Copy + PartialEq> ClosureUnderOperation<T>
165 for AlgebraicStructure<T>
166{
167 fn verify_closure_add(&self, other: &Self) -> bool
168 where
169 Self: AdditiveOperation<T>,
170 {
171 let _result = self.add_op(other);
172 true
173 }
174
175 fn verify_closure_mul(&self, other: &Self) -> bool
176 where
177 Self: MultiplicativeOperation<T>,
178 {
179 let _result = self.mul_op(other);
180 true
181 }
182}
183
184pub trait Associativity<T> {
185 fn verify_associativity_add(&self, b: &Self, c: &Self) -> bool
186 where
187 Self: AdditiveOperation<T>;
188 fn verify_associativity_mul(&self, b: &Self, c: &Self) -> bool
189 where
190 Self: MultiplicativeOperation<T>;
191}
192
193impl<T: Add<Output = T> + Mul<Output = T> + Copy + PartialEq> Associativity<T>
194 for AlgebraicStructure<T>
195{
196 fn verify_associativity_add(&self, b: &Self, c: &Self) -> bool
197 where
198 Self: AdditiveOperation<T>,
199 {
200 let left = self.add_op(b).add_op(c);
201 let right = self.add_op(&b.add_op(c));
202 left == right
203 }
204
205 fn verify_associativity_mul(&self, b: &Self, c: &Self) -> bool
206 where
207 Self: MultiplicativeOperation<T>,
208 {
209 let left = self.mul_op(b).mul_op(c);
210 let right = self.mul_op(&b.mul_op(c));
211 left == right
212 }
213}
214
215pub trait Commutativity<T> {
216 fn verify_commutativity_add(&self, other: &Self) -> bool
217 where
218 Self: AdditiveOperation<T>;
219 fn verify_commutativity_mul(&self, other: &Self) -> bool
220 where
221 Self: MultiplicativeOperation<T>;
222}
223
224impl<T: Add<Output = T> + Mul<Output = T> + Copy + PartialEq> Commutativity<T>
225 for AlgebraicStructure<T>
226{
227 fn verify_commutativity_add(&self, other: &Self) -> bool
228 where
229 Self: AdditiveOperation<T>,
230 {
231 let left = self.add_op(other);
232 let right = other.add_op(self);
233 left == right
234 }
235
236 fn verify_commutativity_mul(&self, other: &Self) -> bool
237 where
238 Self: MultiplicativeOperation<T>,
239 {
240 let left = self.mul_op(other);
241 let right = other.mul_op(self);
242 left == right
243 }
244}
245
246pub trait Identity<T> {
248 fn verify_additive_identity(&self, identity: &T) -> bool;
249 fn verify_multiplicative_identity(&self, identity: &T) -> bool;
250 fn get_additive_identity() -> T;
251 fn get_multiplicative_identity() -> T;
252}
253
254impl Identity<f32> for AlgebraicStructure<f32> {
255 fn verify_additive_identity(&self, identity: &f32) -> bool {
256 let id = AlgebraicStructure(*identity);
257 *self + id == *self && id + *self == *self
258 }
259
260 fn verify_multiplicative_identity(&self, identity: &f32) -> bool {
261 let id = AlgebraicStructure(*identity);
262 *self * id == *self && id * *self == *self
263 }
264
265 fn get_additive_identity() -> f32 {
266 0.0
267 }
268
269 fn get_multiplicative_identity() -> f32 {
270 1.0
271 }
272}
273
274pub trait Inverse<T> {
276 fn has_additive_inverse(&self) -> bool;
277 fn has_multiplicative_inverse(&self) -> bool;
278 fn get_additive_inverse(&self) -> Option<Self>
279 where
280 Self: Sized;
281 fn get_multiplicative_inverse(&self) -> Option<Self>
282 where
283 Self: Sized;
284}
285
286impl Inverse<f32> for AlgebraicStructure<f32> {
287 fn has_additive_inverse(&self) -> bool {
288 true
289 }
290
291 fn has_multiplicative_inverse(&self) -> bool {
292 self.0 != 0.0
293 }
294
295 fn get_additive_inverse(&self) -> Option<Self> {
296 Some(AlgebraicStructure(-self.0))
297 }
298
299 fn get_multiplicative_inverse(&self) -> Option<Self> {
300 if self.has_multiplicative_inverse() {
301 Some(AlgebraicStructure(1.0 / self.0))
302 } else {
303 None
304 }
305 }
306}
307
308impl Distributivity<f32> for AlgebraicStructure<f32> {
309 fn verify_distributivity(&self, b: &Self, c: &Self) -> bool {
310 let left = *self * (*b + *c);
311 let right = (*self * *b) + (*self * *c);
312 left == right
313 }
314}
315
316#[macro_export]
318macro_rules! impl_axioms {
319 ($type:ident, $($axiom:ident $(($($arg:expr),*))? ),*) => {
320 $(
321 $crate::impl_axiom!($type, $axiom $(($($arg),*))?);
322 )*
323 };
324}
325#[macro_export]
326macro_rules! impl_axiom {
327 ($type:ident, Associativity) => {
328 impl<T: std::ops::Add<Output = T> + std::ops::Mul<Output = T> + Copy + PartialEq>
329 $crate::algebra::Associativity<T> for $type<T>
330 where
331 $type<T>:
332 $crate::algebra::AdditiveOperation<T> + $crate::algebra::MultiplicativeOperation<T>,
333 {
334 fn verify_associativity_add(&self, b: &Self, c: &Self) -> bool {
335 let left = (*self + *b) + *c;
336 let right = *self + (*b + *c);
337 left == right
338 }
339
340 fn verify_associativity_mul(&self, b: &Self, c: &Self) -> bool {
341 let left = (*self * *b) * *c;
342 let right = *self * (*b * *c);
343 left == right
344 }
345 }
346 };
347
348 ($type:ident, Commutativity) => {
349 impl<T: std::ops::Add<Output = T> + std::ops::Mul<Output = T> + Copy + PartialEq>
350 $crate::algebra::Commutativity<T> for $type<T>
351 where
352 $type<T>:
353 $crate::algebra::AdditiveOperation<T> + $crate::algebra::MultiplicativeOperation<T>,
354 {
355 fn verify_commutativity_add(&self, other: &Self) -> bool {
356 let left = *self + *other;
357 let right = *other + *self;
358 left == right
359 }
360
361 fn verify_commutativity_mul(&self, other: &Self) -> bool {
362 let left = *self * *other;
363 let right = *other * *self;
364 left == right
365 }
366 }
367 };
368
369 ($type:ident, Identity($($identity:expr),*)) => {
370 impl $crate::algebra::Identity<f32> for $type<f32> {
371 fn verify_additive_identity(&self, identity: &f32) -> bool {
372 let id = $type(*identity);
373 *self + id == *self && id + *self == *self
374 }
375
376 fn verify_multiplicative_identity(&self, identity: &f32) -> bool {
377 let id = $type(*identity);
378 *self * id == *self && id * *self == *self
379 }
380
381 fn get_additive_identity() -> f32 {
382 0.0
383 }
384
385 fn get_multiplicative_identity() -> f32 {
386 1.0
387 }
388 }
389 };
390
391 ($type:ident, Distributivity) => {
392 impl<T: std::ops::Add<Output = T> + std::ops::Mul<Output = T> + Copy + PartialEq>
393 $crate::algebra::Distributivity<T> for $type<T>
394 {
395 fn verify_distributivity(&self, b: &Self, c: &Self) -> bool {
396 let left = *self * (*b + *c);
397 let right = (*self * *b) + (*self * *c);
398 left == right
399 }
400 }
401 };
402}
403
404algstruct!(Ring, +, *);
405
406impl_axioms!(
407 Ring,
408 Associativity,
409 Commutativity,
410 Identity(0.0, 1.0),
411 Distributivity
412);
413
414algstruct!(Field, +, *);
415impl_axioms!(
416 Field,
417 Associativity,
418 Commutativity,
419 Identity(0.0, 1.0),
420 Distributivity
421);
422
423#[allow(unused)]
424impl<T: Div<Output = T> + Copy + PartialEq> Field<T> {
425 fn has_multiplicative_inverse(&self) -> bool
426 where
427 T: Default,
428 {
429 self.0 != T::default()
430 }
431}