1use crate::structure::*;
2use algebraeon_nzq::*;
3use algebraeon_sets::structure::*;
4use std::fmt::Display;
5
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, CanonicalStructure)]
8#[canonical_structure(eq)]
9pub enum QuaternaryField {
10 Zero,
11 One,
12 Alpha,
13 Beta,
14}
15
16impl ToStringSignature for QuaternaryFieldCanonicalStructure {
17 fn to_string(&self, elem: &Self::Set) -> String {
18 format!("{}", elem)
19 }
20}
21
22impl Display for QuaternaryField {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 match self {
25 QuaternaryField::Zero => write!(f, "0"),
26 QuaternaryField::One => write!(f, "1"),
27 QuaternaryField::Alpha => write!(f, "a"),
28 QuaternaryField::Beta => write!(f, "b"),
29 }
30 }
31}
32
33impl RinglikeSpecializationSignature for QuaternaryFieldCanonicalStructure {}
34
35impl ZeroSignature for QuaternaryFieldCanonicalStructure {
36 fn zero(&self) -> Self::Set {
37 QuaternaryField::Zero
38 }
39}
40
41impl AdditionSignature for QuaternaryFieldCanonicalStructure {
42 fn add(&self, a: &Self::Set, b: &Self::Set) -> Self::Set {
43 #[allow(clippy::match_same_arms)]
44 match (a, b) {
45 (_, QuaternaryField::Zero) => *a,
46 (QuaternaryField::Zero, _) => *b,
47 (QuaternaryField::One, QuaternaryField::One) => QuaternaryField::Zero,
48 (QuaternaryField::One, QuaternaryField::Alpha) => QuaternaryField::Beta,
49 (QuaternaryField::One, QuaternaryField::Beta) => QuaternaryField::Alpha,
50 (QuaternaryField::Alpha, QuaternaryField::One) => QuaternaryField::Beta,
51 (QuaternaryField::Alpha, QuaternaryField::Alpha) => QuaternaryField::Zero,
52 (QuaternaryField::Alpha, QuaternaryField::Beta) => QuaternaryField::One,
53 (QuaternaryField::Beta, QuaternaryField::One) => QuaternaryField::Alpha,
54 (QuaternaryField::Beta, QuaternaryField::Alpha) => QuaternaryField::One,
55 (QuaternaryField::Beta, QuaternaryField::Beta) => QuaternaryField::Zero,
56 }
57 }
58}
59
60impl CancellativeAdditionSignature for QuaternaryFieldCanonicalStructure {
61 fn try_sub(&self, a: &Self::Set, b: &Self::Set) -> Option<Self::Set> {
62 Some(self.sub(a, b))
63 }
64}
65
66impl TryNegateSignature for QuaternaryFieldCanonicalStructure {
67 fn try_neg(&self, a: &Self::Set) -> Option<Self::Set> {
68 Some(self.neg(a))
69 }
70}
71
72impl AdditiveMonoidSignature for QuaternaryFieldCanonicalStructure {}
73
74impl OneSignature for QuaternaryFieldCanonicalStructure {
75 fn one(&self) -> Self::Set {
76 QuaternaryField::One
77 }
78}
79
80impl MultiplicationSignature for QuaternaryFieldCanonicalStructure {
81 fn mul(&self, a: &Self::Set, b: &Self::Set) -> Self::Set {
82 #[allow(clippy::match_same_arms)]
83 match (a, b) {
84 (_, QuaternaryField::Zero) => QuaternaryField::Zero,
85 (QuaternaryField::Zero, _) => QuaternaryField::Zero,
86 (_, QuaternaryField::One) => *a,
87 (QuaternaryField::One, _) => *b,
88 (QuaternaryField::Alpha, QuaternaryField::Alpha) => QuaternaryField::Beta,
89 (QuaternaryField::Alpha, QuaternaryField::Beta) => QuaternaryField::One,
90 (QuaternaryField::Beta, QuaternaryField::Alpha) => QuaternaryField::One,
91 (QuaternaryField::Beta, QuaternaryField::Beta) => QuaternaryField::Alpha,
92 }
93 }
94}
95
96impl CommutativeMultiplicationSignature for QuaternaryFieldCanonicalStructure {}
97
98impl MultiplicativeMonoidSignature for QuaternaryFieldCanonicalStructure {}
99
100impl MultiplicativeAbsorptionMonoidSignature for QuaternaryFieldCanonicalStructure {}
101
102impl LeftDistributiveMultiplicationOverAddition for QuaternaryFieldCanonicalStructure {}
103
104impl RightDistributiveMultiplicationOverAddition for QuaternaryFieldCanonicalStructure {}
105
106impl SemiRingSignature for QuaternaryFieldCanonicalStructure {}
107
108impl RingSignature for QuaternaryFieldCanonicalStructure {
109 fn is_reduced(&self) -> Result<bool, String> {
110 Ok(true)
111 }
112}
113
114impl CharacteristicSignature for QuaternaryFieldCanonicalStructure {
115 fn characteristic(&self) -> Natural {
116 Natural::TWO
117 }
118}
119
120impl AdditiveGroupSignature for QuaternaryFieldCanonicalStructure {
121 fn neg(&self, a: &Self::Set) -> Self::Set {
122 *a
123 }
124}
125
126impl TryReciprocalSignature for QuaternaryFieldCanonicalStructure {
127 fn try_reciprocal(&self, a: &Self::Set) -> Option<Self::Set> {
128 self.try_divide(&self.one(), a)
129 }
130}
131
132impl CancellativeMultiplicationSignature for QuaternaryFieldCanonicalStructure {
133 fn try_divide(&self, a: &Self::Set, b: &Self::Set) -> Option<Self::Set> {
134 #[allow(clippy::match_same_arms)]
135 match (&a, &b) {
136 (_, QuaternaryField::Zero) => None,
137 (_, QuaternaryField::One) => Some(*a),
138 (QuaternaryField::Zero, _) => Some(QuaternaryField::Zero),
139 (QuaternaryField::One, QuaternaryField::Alpha) => Some(QuaternaryField::Beta),
140 (QuaternaryField::One, QuaternaryField::Beta) => Some(QuaternaryField::Alpha),
141 (QuaternaryField::Alpha, QuaternaryField::Alpha) => Some(QuaternaryField::One),
142 (QuaternaryField::Alpha, QuaternaryField::Beta) => Some(QuaternaryField::Beta),
143 (QuaternaryField::Beta, QuaternaryField::Alpha) => Some(QuaternaryField::Alpha),
144 (QuaternaryField::Beta, QuaternaryField::Beta) => Some(QuaternaryField::One),
145 }
146 }
147}
148
149impl MultiplicativeIntegralMonoidSignature for QuaternaryFieldCanonicalStructure {}
150
151impl IntegralDomainSignature for QuaternaryFieldCanonicalStructure {}
152
153impl FieldSignature for QuaternaryFieldCanonicalStructure {}
154
155impl<B: BorrowedStructure<QuaternaryFieldCanonicalStructure>> CountableSetSignature
156 for MultiplicativeMonoidUnitsStructure<QuaternaryFieldCanonicalStructure, B>
157{
158 fn generate_all_elements(&self) -> impl Iterator<Item = Self::Set> + Clone {
159 self.list_all_elements().into_iter()
160 }
161}
162
163impl<B: BorrowedStructure<QuaternaryFieldCanonicalStructure>> FiniteSetSignature
164 for MultiplicativeMonoidUnitsStructure<QuaternaryFieldCanonicalStructure, B>
165{
166 fn list_all_elements(&self) -> Vec<Self::Set> {
167 vec![
168 QuaternaryField::One,
169 QuaternaryField::Alpha,
170 QuaternaryField::Beta,
171 ]
172 }
173}
174
175impl CountableSetSignature for QuaternaryFieldCanonicalStructure {
176 fn generate_all_elements(&self) -> impl Iterator<Item = Self::Set> + Clone {
177 self.all_units_and_zero().into_iter()
178 }
179}
180
181impl FiniteSetSignature for QuaternaryFieldCanonicalStructure {}
182
183impl FiniteFieldSignature for QuaternaryFieldCanonicalStructure {
184 fn characteristic_and_power(&self) -> (Natural, Natural) {
185 (Natural::from(2u8), Natural::from(2u8))
186 }
187}
188
189#[cfg(test)]
190mod tests {
191 use super::*;
192
193 #[test]
194 fn test_neg() {
195 assert_eq!(QuaternaryField::Zero.neg(), QuaternaryField::Zero);
196 assert_eq!(QuaternaryField::One.neg(), QuaternaryField::One);
197 assert_eq!(QuaternaryField::Alpha.neg(), QuaternaryField::Alpha);
198 assert_eq!(QuaternaryField::Beta.neg(), QuaternaryField::Beta);
199 }
200
201 #[test]
202 fn test_add() {
203 assert_eq!(
204 QuaternaryField::add(&QuaternaryField::Zero, &QuaternaryField::Zero),
205 QuaternaryField::Zero
206 );
207 assert_eq!(
208 QuaternaryField::add(&QuaternaryField::Zero, &QuaternaryField::One),
209 QuaternaryField::One
210 );
211 assert_eq!(
212 QuaternaryField::add(&QuaternaryField::Zero, &QuaternaryField::Alpha),
213 QuaternaryField::Alpha
214 );
215 assert_eq!(
216 QuaternaryField::add(&QuaternaryField::Zero, &QuaternaryField::Beta),
217 QuaternaryField::Beta
218 );
219 assert_eq!(
220 QuaternaryField::add(&QuaternaryField::One, &QuaternaryField::Zero),
221 QuaternaryField::One
222 );
223 assert_eq!(
224 QuaternaryField::add(&QuaternaryField::One, &QuaternaryField::One),
225 QuaternaryField::Zero
226 );
227 assert_eq!(
228 QuaternaryField::add(&QuaternaryField::One, &QuaternaryField::Alpha),
229 QuaternaryField::Beta
230 );
231 assert_eq!(
232 QuaternaryField::add(&QuaternaryField::One, &QuaternaryField::Beta),
233 QuaternaryField::Alpha
234 );
235 assert_eq!(
236 QuaternaryField::add(&QuaternaryField::Alpha, &QuaternaryField::Zero),
237 QuaternaryField::Alpha
238 );
239 assert_eq!(
240 QuaternaryField::add(&QuaternaryField::Alpha, &QuaternaryField::One),
241 QuaternaryField::Beta
242 );
243 assert_eq!(
244 QuaternaryField::add(&QuaternaryField::Alpha, &QuaternaryField::Alpha),
245 QuaternaryField::Zero
246 );
247 assert_eq!(
248 QuaternaryField::add(&QuaternaryField::Alpha, &QuaternaryField::Beta),
249 QuaternaryField::One
250 );
251 assert_eq!(
252 QuaternaryField::add(&QuaternaryField::Beta, &QuaternaryField::Zero),
253 QuaternaryField::Beta
254 );
255 assert_eq!(
256 QuaternaryField::add(&QuaternaryField::Beta, &QuaternaryField::One),
257 QuaternaryField::Alpha
258 );
259 assert_eq!(
260 QuaternaryField::add(&QuaternaryField::Beta, &QuaternaryField::Alpha),
261 QuaternaryField::One
262 );
263 assert_eq!(
264 QuaternaryField::add(&QuaternaryField::Beta, &QuaternaryField::Beta),
265 QuaternaryField::Zero
266 );
267 }
268
269 #[test]
270 fn test_mul() {
271 assert_eq!(
272 QuaternaryField::mul(&QuaternaryField::Zero, &QuaternaryField::Zero),
273 QuaternaryField::Zero
274 );
275 assert_eq!(
276 QuaternaryField::mul(&QuaternaryField::Zero, &QuaternaryField::One),
277 QuaternaryField::Zero
278 );
279 assert_eq!(
280 QuaternaryField::mul(&QuaternaryField::Zero, &QuaternaryField::Alpha),
281 QuaternaryField::Zero
282 );
283 assert_eq!(
284 QuaternaryField::mul(&QuaternaryField::Zero, &QuaternaryField::Beta),
285 QuaternaryField::Zero
286 );
287 assert_eq!(
288 QuaternaryField::mul(&QuaternaryField::One, &QuaternaryField::Zero),
289 QuaternaryField::Zero
290 );
291 assert_eq!(
292 QuaternaryField::mul(&QuaternaryField::One, &QuaternaryField::One),
293 QuaternaryField::One
294 );
295 assert_eq!(
296 QuaternaryField::mul(&QuaternaryField::One, &QuaternaryField::Alpha),
297 QuaternaryField::Alpha
298 );
299 assert_eq!(
300 QuaternaryField::mul(&QuaternaryField::One, &QuaternaryField::Beta),
301 QuaternaryField::Beta
302 );
303 assert_eq!(
304 QuaternaryField::mul(&QuaternaryField::Alpha, &QuaternaryField::Zero),
305 QuaternaryField::Zero
306 );
307 assert_eq!(
308 QuaternaryField::mul(&QuaternaryField::Alpha, &QuaternaryField::One),
309 QuaternaryField::Alpha
310 );
311 assert_eq!(
312 QuaternaryField::mul(&QuaternaryField::Alpha, &QuaternaryField::Alpha),
313 QuaternaryField::Beta
314 );
315 assert_eq!(
316 QuaternaryField::mul(&QuaternaryField::Alpha, &QuaternaryField::Beta),
317 QuaternaryField::One
318 );
319 assert_eq!(
320 QuaternaryField::mul(&QuaternaryField::Beta, &QuaternaryField::Zero),
321 QuaternaryField::Zero
322 );
323 assert_eq!(
324 QuaternaryField::mul(&QuaternaryField::Beta, &QuaternaryField::One),
325 QuaternaryField::Beta
326 );
327 assert_eq!(
328 QuaternaryField::mul(&QuaternaryField::Beta, &QuaternaryField::Alpha),
329 QuaternaryField::One
330 );
331 assert_eq!(
332 QuaternaryField::mul(&QuaternaryField::Beta, &QuaternaryField::Beta),
333 QuaternaryField::Alpha
334 );
335 }
336
337 #[test]
338 fn test_divide() {
339 assert_eq!(
340 QuaternaryField::try_divide(&QuaternaryField::Zero, &QuaternaryField::Zero),
341 None
342 );
343 assert_eq!(
344 QuaternaryField::try_divide(&QuaternaryField::Zero, &QuaternaryField::One),
345 Some(QuaternaryField::Zero)
346 );
347 assert_eq!(
348 QuaternaryField::try_divide(&QuaternaryField::Zero, &QuaternaryField::Alpha),
349 Some(QuaternaryField::Zero)
350 );
351 assert_eq!(
352 QuaternaryField::try_divide(&QuaternaryField::Zero, &QuaternaryField::Beta),
353 Some(QuaternaryField::Zero)
354 );
355 assert_eq!(
356 QuaternaryField::try_divide(&QuaternaryField::One, &QuaternaryField::Zero),
357 None
358 );
359 assert_eq!(
360 QuaternaryField::try_divide(&QuaternaryField::One, &QuaternaryField::One),
361 Some(QuaternaryField::One)
362 );
363 assert_eq!(
364 QuaternaryField::try_divide(&QuaternaryField::One, &QuaternaryField::Alpha),
365 Some(QuaternaryField::Beta)
366 );
367 assert_eq!(
368 QuaternaryField::try_divide(&QuaternaryField::One, &QuaternaryField::Beta),
369 Some(QuaternaryField::Alpha)
370 );
371 assert_eq!(
372 QuaternaryField::try_divide(&QuaternaryField::Alpha, &QuaternaryField::Zero),
373 None
374 );
375 assert_eq!(
376 QuaternaryField::try_divide(&QuaternaryField::Alpha, &QuaternaryField::One),
377 Some(QuaternaryField::Alpha)
378 );
379 assert_eq!(
380 QuaternaryField::try_divide(&QuaternaryField::Alpha, &QuaternaryField::Alpha),
381 Some(QuaternaryField::One)
382 );
383 assert_eq!(
384 QuaternaryField::try_divide(&QuaternaryField::Alpha, &QuaternaryField::Beta),
385 Some(QuaternaryField::Beta)
386 );
387 assert_eq!(
388 QuaternaryField::try_divide(&QuaternaryField::Beta, &QuaternaryField::Zero),
389 None
390 );
391 assert_eq!(
392 QuaternaryField::try_divide(&QuaternaryField::Beta, &QuaternaryField::One),
393 Some(QuaternaryField::Beta)
394 );
395 assert_eq!(
396 QuaternaryField::try_divide(&QuaternaryField::Beta, &QuaternaryField::Alpha),
397 Some(QuaternaryField::Alpha)
398 );
399 assert_eq!(
400 QuaternaryField::try_divide(&QuaternaryField::Beta, &QuaternaryField::Beta),
401 Some(QuaternaryField::One)
402 );
403 }
404}