algebraeon_sets/
structure.rs1use 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)]
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}