rs_sci/
algebra.rs

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
246// Update the Identity trait and implementation
247pub 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
274// Update the Inverse trait and implementation
275pub 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 for implementing axioms
317#[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}