ariadnetor_tensor/
sector.rs1use std::fmt::Debug;
8use std::hash::Hash;
9
10pub trait Sector: Clone + Eq + Ord + Hash + Debug {
22 fn fuse(&self, other: &Self) -> Self;
24
25 fn identity() -> Self;
27
28 fn dual(&self) -> Self;
30}
31
32#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
41pub struct Z2Sector(u8);
42
43impl Z2Sector {
44 pub fn new(value: u8) -> Self {
46 assert!(value <= 1, "Z2Sector value must be 0 or 1, got {value}");
47 Self(value)
48 }
49
50 pub fn value(self) -> u8 {
52 self.0
53 }
54}
55
56impl Sector for Z2Sector {
57 fn fuse(&self, other: &Self) -> Self {
58 Self(self.0 ^ other.0)
59 }
60
61 fn identity() -> Self {
62 Self(0)
63 }
64
65 fn dual(&self) -> Self {
66 *self
67 }
68}
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
79pub struct U1Sector(pub i32);
80
81impl Sector for U1Sector {
82 fn fuse(&self, other: &Self) -> Self {
83 Self(
84 self.0
85 .checked_add(other.0)
86 .expect("U1Sector charge overflow"),
87 )
88 }
89
90 fn identity() -> Self {
91 Self(0)
92 }
93
94 fn dual(&self) -> Self {
95 Self(self.0.checked_neg().expect("U1Sector charge overflow"))
96 }
97}
98
99impl<A: Sector, B: Sector> Sector for (A, B) {
104 fn fuse(&self, other: &Self) -> Self {
105 (self.0.fuse(&other.0), self.1.fuse(&other.1))
106 }
107
108 fn identity() -> Self {
109 (A::identity(), B::identity())
110 }
111
112 fn dual(&self) -> Self {
113 (self.0.dual(), self.1.dual())
114 }
115}
116
117#[cfg(test)]
122mod tests {
123 use super::*;
124
125 fn assert_sector_laws<S: Sector>(a: &S, b: &S) {
127 let id = S::identity();
128
129 assert_eq!(a.fuse(&id), *a);
131 assert_eq!(id.fuse(a), *a);
132
133 assert_eq!(a.fuse(&a.dual()), id);
135 assert_eq!(a.dual().fuse(a), id);
136
137 assert_eq!(a.fuse(b), b.fuse(a));
139 }
140
141 #[test]
142 fn z2_laws() {
143 let s0 = Z2Sector::new(0);
144 let s1 = Z2Sector::new(1);
145 assert_sector_laws(&s0, &s1);
146 assert_sector_laws(&s1, &s1);
147 }
148
149 #[test]
150 fn z2_fusion_table() {
151 let z0 = Z2Sector::new(0);
152 let z1 = Z2Sector::new(1);
153 assert_eq!(z0.fuse(&z0), z0);
154 assert_eq!(z0.fuse(&z1), z1);
155 assert_eq!(z1.fuse(&z0), z1);
156 assert_eq!(z1.fuse(&z1), z0);
157 }
158
159 #[test]
160 fn z2_dual() {
161 assert_eq!(Z2Sector::new(0).dual(), Z2Sector::new(0));
162 assert_eq!(Z2Sector::new(1).dual(), Z2Sector::new(1));
163 }
164
165 #[test]
166 fn z2_ord() {
167 assert!(Z2Sector::new(0) < Z2Sector::new(1));
168 }
169
170 #[test]
171 #[should_panic(expected = "Z2Sector value must be 0 or 1")]
172 fn z2_invalid_value() {
173 Z2Sector::new(2);
174 }
175
176 #[test]
177 fn u1_laws() {
178 let s0 = U1Sector(0);
179 let s1 = U1Sector(1);
180 let s_neg = U1Sector(-3);
181 assert_sector_laws(&s0, &s1);
182 assert_sector_laws(&s1, &s_neg);
183 assert_sector_laws(&s_neg, &s0);
184 }
185
186 #[test]
187 fn u1_fusion() {
188 assert_eq!(U1Sector(2).fuse(&U1Sector(3)), U1Sector(5));
189 assert_eq!(U1Sector(-1).fuse(&U1Sector(1)), U1Sector(0));
190 }
191
192 #[test]
193 fn u1_dual() {
194 assert_eq!(U1Sector(3).dual(), U1Sector(-3));
195 assert_eq!(U1Sector(0).dual(), U1Sector(0));
196 }
197
198 #[test]
199 fn u1_ord() {
200 assert!(U1Sector(-1) < U1Sector(0));
201 assert!(U1Sector(0) < U1Sector(1));
202 }
203
204 #[test]
205 fn tuple_laws() {
206 let a = (U1Sector(1), Z2Sector::new(0));
207 let b = (U1Sector(-2), Z2Sector::new(1));
208 assert_sector_laws(&a, &b);
209 }
210
211 #[test]
212 fn tuple_fusion() {
213 let a = (U1Sector(1), Z2Sector::new(1));
214 let b = (U1Sector(2), Z2Sector::new(1));
215 assert_eq!(a.fuse(&b), (U1Sector(3), Z2Sector::new(0)));
216 }
217
218 #[test]
219 fn tuple_identity_and_dual() {
220 let id = <(U1Sector, Z2Sector)>::identity();
221 assert_eq!(id, (U1Sector(0), Z2Sector::new(0)));
222
223 let s = (U1Sector(3), Z2Sector::new(1));
224 assert_eq!(s.dual(), (U1Sector(-3), Z2Sector::new(1)));
225 }
226
227 #[test]
228 fn tuple_ord() {
229 let a = (U1Sector(0), Z2Sector::new(1));
231 let b = (U1Sector(1), Z2Sector::new(0));
232 assert!(a < b);
233 }
234
235 #[test]
236 fn nested_tuple() {
237 let a = ((U1Sector(1), Z2Sector::new(0)), U1Sector(2));
239 let b = ((U1Sector(-1), Z2Sector::new(1)), U1Sector(3));
240 assert_sector_laws(&a, &b);
241 }
242}