Skip to main content

oxilean_std/algebra/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4use super::functions::*;
5
6/// Noetherian ring properties.
7#[allow(dead_code)]
8#[derive(Debug, Clone)]
9pub struct NoetherianRing {
10    pub name: String,
11    pub krull_dimension: Option<usize>,
12}
13impl NoetherianRing {
14    #[allow(dead_code)]
15    pub fn new(name: &str, krull_dim: Option<usize>) -> Self {
16        Self {
17            name: name.to_string(),
18            krull_dimension: krull_dim,
19        }
20    }
21    #[allow(dead_code)]
22    pub fn hilbert_basis_theorem(&self) -> String {
23        format!(
24            "If {} is Noetherian, then {}[x] is Noetherian",
25            self.name, self.name
26        )
27    }
28    #[allow(dead_code)]
29    pub fn primary_decomposition_exists(&self) -> bool {
30        true
31    }
32    #[allow(dead_code)]
33    pub fn krull_dimension_description(&self) -> String {
34        match self.krull_dimension {
35            Some(d) => {
36                format!("dim({}) = {} (max length of chain of primes)", self.name, d)
37            }
38            None => format!("dim({}) = infinity", self.name),
39        }
40    }
41}
42/// Module over a ring.
43#[allow(dead_code)]
44#[derive(Debug, Clone)]
45pub struct Module {
46    pub ring: String,
47    pub name: String,
48    pub is_free: bool,
49    pub rank: Option<usize>,
50    pub is_finitely_generated: bool,
51}
52impl Module {
53    #[allow(dead_code)]
54    pub fn free(ring: &str, name: &str, rank: usize) -> Self {
55        Self {
56            ring: ring.to_string(),
57            name: name.to_string(),
58            is_free: true,
59            rank: Some(rank),
60            is_finitely_generated: true,
61        }
62    }
63    #[allow(dead_code)]
64    pub fn cyclic(ring: &str, name: &str) -> Self {
65        Self {
66            ring: ring.to_string(),
67            name: name.to_string(),
68            is_free: false,
69            rank: Some(1),
70            is_finitely_generated: true,
71        }
72    }
73    #[allow(dead_code)]
74    pub fn over_pid_structure_theorem(&self) -> String {
75        format!(
76            "M ~ R^r + R/d1R + ... + R/dk*R (invariant factors) over PID {}",
77            self.ring
78        )
79    }
80    #[allow(dead_code)]
81    pub fn is_projective(&self) -> bool {
82        self.is_free
83    }
84    #[allow(dead_code)]
85    pub fn is_flat(&self) -> bool {
86        self.is_projective()
87    }
88}
89/// Galois theory for field extensions.
90#[allow(dead_code)]
91#[derive(Debug, Clone)]
92pub struct GaloisExtension {
93    pub base_field: String,
94    pub extension_field: String,
95    pub galois_group: String,
96    pub degree: usize,
97}
98impl GaloisExtension {
99    #[allow(dead_code)]
100    pub fn new(base: &str, ext: &str, gal: &str, degree: usize) -> Self {
101        Self {
102            base_field: base.to_string(),
103            extension_field: ext.to_string(),
104            galois_group: gal.to_string(),
105            degree,
106        }
107    }
108    #[allow(dead_code)]
109    pub fn cyclotomic(n: usize) -> Self {
110        Self {
111            base_field: "Q".to_string(),
112            extension_field: format!("Q(zeta_{n})"),
113            galois_group: format!("(Z/{}Z)*", n),
114            degree: euler_phi_algebra(n as u64) as usize,
115        }
116    }
117    #[allow(dead_code)]
118    pub fn fundamental_theorem(&self) -> String {
119        format!(
120            "Subgroups of Gal({}/{}) <-> subfields between {} and {}",
121            self.extension_field, self.base_field, self.base_field, self.extension_field
122        )
123    }
124    #[allow(dead_code)]
125    pub fn is_abelian_extension(&self) -> bool {
126        self.galois_group.contains("Z") || self.galois_group.contains("abelian")
127    }
128}
129/// Short exact sequence.
130#[allow(dead_code)]
131#[derive(Debug, Clone)]
132pub struct ShortExactSequence {
133    pub a: String,
134    pub b: String,
135    pub c: String,
136}
137impl ShortExactSequence {
138    #[allow(dead_code)]
139    pub fn new(a: &str, b: &str, c: &str) -> Self {
140        Self {
141            a: a.to_string(),
142            b: b.to_string(),
143            c: c.to_string(),
144        }
145    }
146    #[allow(dead_code)]
147    pub fn display(&self) -> String {
148        format!("0 -> {} -> {} -> {} -> 0", self.a, self.b, self.c)
149    }
150    #[allow(dead_code)]
151    pub fn is_split(&self) -> bool {
152        self.b.contains('+') || self.b.contains("oplus")
153    }
154}
155/// Graded ring and algebra.
156#[allow(dead_code)]
157#[derive(Debug, Clone)]
158pub struct GradedRing {
159    pub name: String,
160    pub grading_monoid: String,
161    pub is_commutative: bool,
162}
163impl GradedRing {
164    #[allow(dead_code)]
165    pub fn polynomial_ring(vars: &[&str]) -> Self {
166        Self {
167            name: format!("k[{}]", vars.join(",")),
168            grading_monoid: "N (by total degree)".to_string(),
169            is_commutative: true,
170        }
171    }
172    #[allow(dead_code)]
173    pub fn exterior_algebra(n: usize) -> Self {
174        Self {
175            name: format!("Lambda^* (n={n})"),
176            grading_monoid: "Z (by degree)".to_string(),
177            is_commutative: false,
178        }
179    }
180    #[allow(dead_code)]
181    pub fn is_noetherian(&self) -> bool {
182        true
183    }
184    #[allow(dead_code)]
185    pub fn hilbert_series_description(&self) -> String {
186        format!("H({}, t) = sum dim(R_n) t^n for {}", self.name, self.name)
187    }
188}
189/// Projective resolution.
190#[allow(dead_code)]
191#[derive(Debug, Clone)]
192pub struct ProjectiveResolution {
193    pub module: String,
194    pub projective_dimension: Option<usize>,
195    pub length: usize,
196}
197impl ProjectiveResolution {
198    #[allow(dead_code)]
199    pub fn new(module: &str, pd: Option<usize>, len: usize) -> Self {
200        Self {
201            module: module.to_string(),
202            projective_dimension: pd,
203            length: len,
204        }
205    }
206    #[allow(dead_code)]
207    pub fn is_finite(&self) -> bool {
208        self.projective_dimension.is_some()
209    }
210    #[allow(dead_code)]
211    pub fn global_dimension_description(&self) -> String {
212        format!("gldim(R) = sup over M of pd(M) for all R-modules M")
213    }
214}
215/// Derived category construction.
216#[allow(dead_code)]
217#[derive(Debug, Clone)]
218pub struct DerivedCategory {
219    pub abelian_category: String,
220}
221impl DerivedCategory {
222    #[allow(dead_code)]
223    pub fn new(cat: &str) -> Self {
224        Self {
225            abelian_category: cat.to_string(),
226        }
227    }
228    #[allow(dead_code)]
229    pub fn objects_are_complexes(&self) -> bool {
230        true
231    }
232    #[allow(dead_code)]
233    pub fn localization_description(&self) -> String {
234        format!(
235            "D({}) = K({})[quasi-isomorphisms^-1]",
236            self.abelian_category, self.abelian_category
237        )
238    }
239    #[allow(dead_code)]
240    pub fn t_structure_heart(&self) -> String {
241        format!(
242            "Heart of standard t-structure on D({}) = {}",
243            self.abelian_category, self.abelian_category
244        )
245    }
246}
247/// Abelian category axioms check.
248#[allow(dead_code)]
249#[derive(Debug, Clone)]
250pub struct AbelianCategory {
251    pub name: String,
252    pub has_zero_object: bool,
253    pub has_biproducts: bool,
254    pub every_morphism_has_kernel_cokernel: bool,
255}
256impl AbelianCategory {
257    #[allow(dead_code)]
258    pub fn new(name: &str) -> Self {
259        Self {
260            name: name.to_string(),
261            has_zero_object: true,
262            has_biproducts: true,
263            every_morphism_has_kernel_cokernel: true,
264        }
265    }
266    #[allow(dead_code)]
267    pub fn of_modules(ring: &str) -> Self {
268        Self::new(&format!("R-Mod (R={})", ring))
269    }
270    #[allow(dead_code)]
271    pub fn snake_lemma(&self) -> String {
272        "Snake lemma: long exact sequence from short exact sequences in an abelian category"
273            .to_string()
274    }
275    #[allow(dead_code)]
276    pub fn five_lemma(&self) -> String {
277        "Five lemma: if 4 maps are isomorphisms, the middle one is too".to_string()
278    }
279}
280/// Lie algebra structure.
281#[allow(dead_code)]
282#[derive(Debug, Clone)]
283pub struct LieAlgebra {
284    pub name: String,
285    pub dimension: usize,
286    pub is_semisimple: bool,
287    pub is_nilpotent: bool,
288    pub is_solvable: bool,
289}
290impl LieAlgebra {
291    #[allow(dead_code)]
292    pub fn sl_n(n: usize) -> Self {
293        Self {
294            name: format!("sl({n})"),
295            dimension: n * n - 1,
296            is_semisimple: true,
297            is_nilpotent: false,
298            is_solvable: false,
299        }
300    }
301    #[allow(dead_code)]
302    pub fn heisenberg(n: usize) -> Self {
303        Self {
304            name: format!("h_{n} (Heisenberg)"),
305            dimension: 2 * n + 1,
306            is_semisimple: false,
307            is_nilpotent: true,
308            is_solvable: true,
309        }
310    }
311    #[allow(dead_code)]
312    pub fn abelian(n: usize) -> Self {
313        Self {
314            name: format!("k^{n} (abelian)"),
315            dimension: n,
316            is_semisimple: false,
317            is_nilpotent: true,
318            is_solvable: true,
319        }
320    }
321    #[allow(dead_code)]
322    pub fn engel_theorem(&self) -> String {
323        "Engel's theorem: g nilpotent iff all adj(x) are nilpotent endomorphisms".to_string()
324    }
325    #[allow(dead_code)]
326    pub fn lies_theorem(&self) -> String {
327        "Lie's theorem: solvable Lie algebra acts by upper triangular matrices (over alg. closed field)"
328            .to_string()
329    }
330    #[allow(dead_code)]
331    pub fn cartan_criterion(&self) -> String {
332        format!(
333            "{} is semisimple iff its Killing form is non-degenerate",
334            self.name
335        )
336    }
337}
338/// Ext and Tor groups.
339#[allow(dead_code)]
340#[derive(Debug, Clone)]
341pub struct ExtTorGroups {
342    pub ring: String,
343    pub module_m: String,
344    pub module_n: String,
345}
346impl ExtTorGroups {
347    #[allow(dead_code)]
348    pub fn new(ring: &str, m: &str, n: &str) -> Self {
349        Self {
350            ring: ring.to_string(),
351            module_m: m.to_string(),
352            module_n: n.to_string(),
353        }
354    }
355    #[allow(dead_code)]
356    pub fn ext_description(&self) -> String {
357        format!(
358            "Ext^n_{{{}}}({},{}) = derived functor of Hom, classifies n-fold extensions",
359            self.ring, self.module_m, self.module_n
360        )
361    }
362    #[allow(dead_code)]
363    pub fn tor_description(&self) -> String {
364        format!(
365            "Tor^n_{{{}}}({},{}) = derived functor of tensor, measures flatness failure",
366            self.ring, self.module_m, self.module_n
367        )
368    }
369    #[allow(dead_code)]
370    pub fn short_exact_sequence_long_ext(&self) -> String {
371        "0 -> Hom(M,N) -> ... -> Ext^1(M,N) -> ... long exact sequence".to_string()
372    }
373}
374/// Localization of a ring.
375#[allow(dead_code)]
376#[derive(Debug, Clone)]
377pub struct Localization {
378    pub ring: String,
379    pub multiplicative_set: String,
380    pub localized_ring: String,
381}
382impl Localization {
383    #[allow(dead_code)]
384    pub fn at_prime(ring: &str, prime: &str) -> Self {
385        Self {
386            ring: ring.to_string(),
387            multiplicative_set: format!("{ring} \\ {prime}"),
388            localized_ring: format!("{ring}_{prime}"),
389        }
390    }
391    #[allow(dead_code)]
392    pub fn away_from(ring: &str, element: &str) -> Self {
393        Self {
394            ring: ring.to_string(),
395            multiplicative_set: format!("powers of {element}"),
396            localized_ring: format!("{ring}[1/{element}]"),
397        }
398    }
399    #[allow(dead_code)]
400    pub fn universal_property(&self) -> String {
401        format!(
402            "S^-1 {}: maps to rings where S is invertible factor uniquely through {}",
403            self.ring, self.localized_ring
404        )
405    }
406}
407/// Tensor product of modules.
408#[allow(dead_code)]
409#[derive(Debug, Clone)]
410pub struct TensorProduct {
411    pub module_a: String,
412    pub module_b: String,
413    pub ring: String,
414}
415impl TensorProduct {
416    #[allow(dead_code)]
417    pub fn new(a: &str, b: &str, ring: &str) -> Self {
418        Self {
419            module_a: a.to_string(),
420            module_b: b.to_string(),
421            ring: ring.to_string(),
422        }
423    }
424    #[allow(dead_code)]
425    pub fn right_exact_description(&self) -> String {
426        format!(
427            "- tensor_R {} is right exact (M' -> M -> M'' -> 0 stays exact) over {}",
428            self.module_b, self.ring
429        )
430    }
431    #[allow(dead_code)]
432    pub fn adjunction_hom_tensor(&self) -> String {
433        format!(
434            "Hom_R(A tensor_R B, C) = Hom_R(A, Hom_R(B, C)) for {},{},{} over {}",
435            self.module_a, self.module_b, "C", self.ring
436        )
437    }
438}