algebraeon_sets/
structure.rs

1use std::{borrow::Borrow, fmt::Debug, marker::PhantomData, rc::Rc};
2
3pub trait Structure: Clone + Debug + PartialEq + Eq {
4    type Set: Clone + Debug;
5}
6
7#[derive(Debug, Clone)]
8pub struct CannonicalStructure<T: MetaType> {
9    _ghost: std::marker::PhantomData<T>,
10}
11impl<T: MetaType> PartialEq for CannonicalStructure<T> {
12    fn eq(&self, _: &Self) -> bool {
13        true
14    }
15}
16impl<T: MetaType> Eq for CannonicalStructure<T> {}
17pub trait MetaType: Clone + Debug {
18    type Structure: Structure<Set = Self>;
19    fn structure() -> Rc<Self::Structure>;
20}
21
22impl<T: MetaType> CannonicalStructure<T> {
23    pub fn new() -> Self {
24        Self {
25            _ghost: PhantomData::default(),
26        }
27    }
28}
29impl<T: MetaType> Structure for CannonicalStructure<T> {
30    type Set = T;
31}
32
33pub fn common_structure<S: Structure>(
34    structure1: impl Borrow<Rc<S>>,
35    structure2: impl Borrow<Rc<S>>,
36) -> Rc<S> {
37    if structure1.borrow() == structure2.borrow() {
38        structure1.borrow().clone()
39    } else {
40        panic!("Unequal ring structures")
41    }
42}
43
44pub trait ToStringStructure: Structure {
45    fn to_string(&self, elem: &Self::Set) -> String;
46}
47impl<T: MetaType + ToString> ToStringStructure for CannonicalStructure<T> {
48    fn to_string(&self, elem: &Self::Set) -> String {
49        elem.to_string()
50    }
51}
52
53pub trait PartialEqStructure: Structure {
54    fn equal(&self, a: &Self::Set, b: &Self::Set) -> bool;
55}
56impl<T: MetaType + PartialEq> PartialEqStructure for CannonicalStructure<T> {
57    fn equal(&self, a: &T, b: &T) -> bool {
58        a == b
59    }
60}
61
62pub trait EqStructure: PartialEqStructure {}
63impl<T: MetaType + Eq> EqStructure for CannonicalStructure<T> {}
64
65// impl MetaType for Natural {
66//     type Structure = CannonicalStructure<Natural>;
67
68//     fn structure() -> Rc<Self::Structure> {
69//         CannonicalStructure::new().into()
70//     }
71// }
72
73// impl MetaType for Integer {
74//     type Structure = CannonicalStructure<Integer>;
75
76//     fn structure() -> Rc<Self::Structure> {
77//         CannonicalStructure::new().into()
78//     }
79// }
80
81// impl MetaType for Rational {
82//     type Structure = CannonicalStructure<Rational>;
83
84//     fn structure() -> Rc<Self::Structure> {
85//         CannonicalStructure::new().into()
86//     }
87// }
88
89#[cfg(test)]
90mod tests {
91    use super::*;
92
93    #[test]
94    fn cannonical_structure() {
95        #[derive(Debug, Clone, PartialEq, Eq)]
96        struct A {
97            x: i32,
98        }
99
100        impl MetaType for A {
101            type Structure = CannonicalStructure<A>;
102
103            fn structure() -> Rc<Self::Structure> {
104                CannonicalStructure::new().into()
105            }
106        }
107
108        impl ToString for A {
109            fn to_string(&self) -> String {
110                self.x.to_string()
111            }
112        }
113
114        let a = A { x: 3 };
115        let b = A { x: 4 };
116        let v = A::structure().equal(&a, &b);
117        assert_eq!(v, false);
118        println!("{}", A::structure().to_string(&a));
119    }
120
121    #[test]
122    fn foo() {
123        #[derive(Debug, Clone, PartialEq, Eq)]
124        struct Scary {
125            t: usize,
126        }
127
128        impl Structure for Scary {
129            type Set = usize;
130        }
131
132        impl ToStringStructure for Scary {
133            fn to_string(&self, elem: &Self::Set) -> String {
134                elem.to_string()
135            }
136        }
137    }
138}