algebraeon_sets/structure/
structure.rs

1use std::{borrow::Borrow, fmt::Debug};
2
3pub trait Signature: Clone + Debug + Eq {}
4
5/// Instances of a type implementing this trait represent
6/// a set of elements of type `Self::Set` with some
7/// structure, for example, the structure of a ring.
8pub trait SetSignature: Signature {
9    type Set: Clone + Debug;
10
11    /// Some instances of `Self::Set` may not be valid to represent elements of this set.
12    /// Return `true` if `x` is a valid element and `false` if not.
13    fn is_element(&self, x: &Self::Set) -> Result<(), String>;
14}
15
16pub trait MetaType: Clone + Debug {
17    type Signature: SetSignature<Set = Self>;
18    fn structure() -> Self::Signature;
19}
20
21pub trait ToStringSignature: SetSignature {
22    fn to_string(&self, elem: &Self::Set) -> String;
23}
24
25pub trait EqSignature: SetSignature {
26    fn equal(&self, a: &Self::Set, b: &Self::Set) -> bool;
27}
28
29pub trait CountableSetSignature: SetSignature {
30    /// Yield distinct elements of the set such that every element eventually appears.
31    /// Always yields elements in the same order.
32    fn generate_all_elements(&self) -> impl Iterator<Item = Self::Set>;
33}
34
35pub trait FiniteSetSignature: CountableSetSignature {
36    /// A list of all elements in the set.
37    /// Always returns elements in the same order.
38    fn list_all_elements(&self) -> Vec<Self::Set> {
39        self.generate_all_elements().collect()
40    }
41    fn size(&self) -> usize {
42        self.list_all_elements().len()
43    }
44}
45
46pub trait BorrowedStructure<S: Signature>: Borrow<S> + Clone + Debug + Eq {}
47impl<S: Signature, BS: Borrow<S> + Clone + Debug + Eq> BorrowedStructure<S> for BS {}
48
49#[cfg(test)]
50mod tests {
51    use super::*;
52    use algebraeon_macros::CanonicalStructure;
53
54    #[test]
55    fn canonical_structure() {
56        #[derive(Debug, Clone, PartialEq, Eq, CanonicalStructure)]
57        #[canonical_structure(eq)]
58        pub struct A {
59            x: i32,
60        }
61
62        impl ToString for A {
63            fn to_string(&self) -> String {
64                self.x.to_string()
65            }
66        }
67
68        impl ToStringSignature for ACanonicalStructure {
69            fn to_string(&self, elem: &Self::Set) -> String {
70                elem.to_string()
71            }
72        }
73
74        let a = A { x: 3 };
75        let b = A { x: 4 };
76        let v = A::structure().equal(&a, &b);
77        assert!(!v);
78        println!("{}", A::structure().to_string(&a));
79    }
80
81    #[test]
82    fn to_string_structure_impl() {
83        #[derive(Debug, Clone, PartialEq, Eq)]
84        struct A {
85            t: usize,
86        }
87
88        impl Signature for A {}
89
90        impl SetSignature for A {
91            type Set = usize;
92
93            fn is_element(&self, _x: &Self::Set) -> Result<(), String> {
94                Ok(())
95            }
96        }
97
98        impl ToStringSignature for A {
99            fn to_string(&self, elem: &Self::Set) -> String {
100                elem.to_string()
101            }
102        }
103    }
104}