algebraeon_sets/structure/
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#[cfg(test)]
66mod tests {
67    use super::*;
68
69    #[test]
70    fn cannonical_structure() {
71        #[derive(Debug, Clone, PartialEq, Eq)]
72        struct A {
73            x: i32,
74        }
75
76        impl MetaType for A {
77            type Structure = CannonicalStructure<A>;
78
79            fn structure() -> Rc<Self::Structure> {
80                CannonicalStructure::new().into()
81            }
82        }
83
84        impl ToString for A {
85            fn to_string(&self) -> String {
86                self.x.to_string()
87            }
88        }
89
90        let a = A { x: 3 };
91        let b = A { x: 4 };
92        let v = A::structure().equal(&a, &b);
93        assert_eq!(v, false);
94        println!("{}", A::structure().to_string(&a));
95    }
96
97    #[test]
98    fn foo() {
99        #[derive(Debug, Clone, PartialEq, Eq)]
100        struct A {
101            t: usize,
102        }
103
104        impl Structure for A {
105            type Set = usize;
106        }
107
108        impl ToStringStructure for A {
109            fn to_string(&self, elem: &Self::Set) -> String {
110                elem.to_string()
111            }
112        }
113    }
114}