use super::functions::*;
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct ChowGroup {
pub variety: String,
pub codimension: usize,
pub generators: Vec<String>,
}
#[allow(dead_code)]
impl ChowGroup {
pub fn new(variety: impl Into<String>, codimension: usize) -> Self {
Self {
variety: variety.into(),
codimension,
generators: Vec::new(),
}
}
pub fn ch0(variety: impl Into<String>) -> Self {
let mut g = Self::new(variety, 0);
g.generators.push("[X]".to_string());
g
}
pub fn pic(variety: impl Into<String>) -> Self {
let mut g = Self::new(variety, 1);
g.generators.push("Pic".to_string());
g
}
pub fn add_generator(&mut self, gen: impl Into<String>) {
self.generators.push(gen.into());
}
pub fn intersect(&self, other: &Self) -> Self {
Self {
variety: self.variety.clone(),
codimension: self.codimension + other.codimension,
generators: vec![format!(
"{} · {}",
self.generators.first().map(|s| s.as_str()).unwrap_or("?"),
other.generators.first().map(|s| s.as_str()).unwrap_or("?")
)],
}
}
pub fn rank(&self) -> usize {
self.generators.len()
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct BerkovichSpace {
pub algebra: String,
pub base_field: String,
pub dimension: usize,
pub is_smooth: bool,
}
#[allow(dead_code)]
impl BerkovichSpace {
pub fn new(algebra: impl Into<String>, base_field: impl Into<String>, dim: usize) -> Self {
Self {
algebra: algebra.into(),
base_field: base_field.into(),
dimension: dim,
is_smooth: false,
}
}
pub fn unit_disc(base_field: impl Into<String>) -> Self {
Self {
algebra: "K{T}".to_string(),
base_field: base_field.into(),
dimension: 1,
is_smooth: true,
}
}
pub fn affine_n_space(base_field: impl Into<String>, n: usize) -> Self {
let gens = (1..=n)
.map(|i| format!("T_{}", i))
.collect::<Vec<_>>()
.join(", ");
Self {
algebra: format!("K{{{}}}", gens),
base_field: base_field.into(),
dimension: n,
is_smooth: true,
}
}
pub fn gauss_point_description(&self) -> String {
format!(
"Gauss point of M({}) over {}: seminorm |·|_1",
self.algebra, self.base_field
)
}
pub fn smooth(mut self) -> Self {
self.is_smooth = true;
self
}
pub fn skeleton_description(&self) -> String {
format!("Skeleton of M({}) (dim ≤ {})", self.algebra, self.dimension)
}
}
#[derive(Debug, Clone)]
pub struct AbsoluteHeight {
pub point_description: String,
pub value: f64,
}
impl AbsoluteHeight {
pub fn of_rational(p: i64, q: u64) -> Self {
let value = (p.unsigned_abs()).max(q) as f64;
Self {
point_description: format!("{}/{}", p, q),
value,
}
}
pub fn of_minimal_poly(coeffs: &[i64]) -> Self {
let max_coeff = coeffs.iter().map(|c| c.unsigned_abs()).max().unwrap_or(0);
Self {
point_description: format!("root of poly with coeffs {:?}", coeffs),
value: max_coeff as f64,
}
}
pub fn value(&self) -> f64 {
self.value
}
}
#[derive(Debug, Clone)]
pub struct LanglandsCorrespondence {
pub galois_rep: GaloisRepresentation,
pub automorphic_rep: AutomorphicRepresentation,
pub correspondence_type: LanglandsType,
}
impl LanglandsCorrespondence {
pub fn new(
gal: GaloisRepresentation,
aut: AutomorphicRepresentation,
kind: LanglandsType,
) -> Self {
Self {
galois_rep: gal,
automorphic_rep: aut,
correspondence_type: kind,
}
}
}
#[derive(Debug, Clone)]
pub struct NorthcottProperty {
pub space: String,
pub absolute: bool,
}
impl NorthcottProperty {
pub fn projective_space(n: usize) -> Self {
Self {
space: format!("P^{}", n),
absolute: true,
}
}
pub fn count_estimate_p1_rational(bound: f64) -> usize {
if bound < 1.0 {
return 0;
}
((12.0 / std::f64::consts::PI.powi(2)) * bound * bound).round() as usize
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AbelianVariety {
pub field: String,
pub dimension: usize,
pub is_simple: bool,
pub name: String,
}
impl AbelianVariety {
pub fn new(field: impl Into<String>, dimension: usize) -> Self {
Self {
field: field.into(),
dimension,
is_simple: false,
name: String::new(),
}
}
pub fn named(field: impl Into<String>, dimension: usize, name: impl Into<String>) -> Self {
Self {
field: field.into(),
dimension,
is_simple: false,
name: name.into(),
}
}
pub fn dimension(&self) -> usize {
self.dimension
}
pub fn tate_module_rank(&self) -> usize {
2 * self.dimension
}
pub fn trace_of_frobenius(&self, _prime: u64) -> i64 {
0
}
pub fn endomorphism_ring(&self) -> String {
if self.is_simple {
"Division algebra".to_string()
} else {
"Matrix algebra".to_string()
}
}
pub fn simple(mut self) -> Self {
self.is_simple = true;
self
}
}
#[derive(Debug, Clone)]
pub struct AutomorphicRepresentation {
pub group: String,
pub field: String,
pub weight: Vec<i32>,
pub is_cuspidal: bool,
}
impl AutomorphicRepresentation {
pub fn new(group: impl Into<String>, field: impl Into<String>) -> Self {
Self {
group: group.into(),
field: field.into(),
weight: Vec::new(),
is_cuspidal: false,
}
}
pub fn modular_form_gl2(weight: i32, field: impl Into<String>) -> Self {
Self {
group: "GL_2".to_string(),
field: field.into(),
weight: vec![weight],
is_cuspidal: true,
}
}
pub fn local_components(&self) -> String {
format!("⊗_v π_v of {} over {}", self.group, self.field)
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum LanglandsType {
LocalGLn,
GlobalGL2,
Functoriality,
Geometric,
}
#[derive(Debug, Clone)]
pub struct LogarithmicHeight {
pub absolute: AbsoluteHeight,
}
impl LogarithmicHeight {
pub fn from_absolute(h: AbsoluteHeight) -> Self {
Self { absolute: h }
}
pub fn of_rational(p: i64, q: u64) -> Self {
Self::from_absolute(AbsoluteHeight::of_rational(p, q))
}
pub fn value(&self) -> f64 {
self.absolute.value.ln()
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct CondensedAbelianGroup {
pub label: String,
pub is_solid: bool,
pub is_discrete: bool,
}
#[allow(dead_code)]
impl CondensedAbelianGroup {
pub fn discrete(label: impl Into<String>) -> Self {
Self {
label: label.into(),
is_solid: false,
is_discrete: true,
}
}
pub fn solid_free(profinite_set: impl Into<String>) -> Self {
Self {
label: format!("Z[{}]^solid", profinite_set.into()),
is_solid: true,
is_discrete: false,
}
}
pub fn solidify(mut self) -> Self {
self.is_solid = true;
self
}
pub fn solid_tensor_product(&self, other: &Self) -> String {
format!("{} ⊗_solid {}", self.label, other.label)
}
pub fn is_p_liquid(&self, p: f64) -> bool {
self.is_solid && p > 0.0 && p <= 1.0
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct NeronModel {
pub variety: String,
pub dvr: String,
pub fraction_field: String,
pub reduction_type: NeronReductionType,
pub component_group_order: Option<u64>,
}
#[allow(dead_code)]
impl NeronModel {
pub fn new(
variety: impl Into<String>,
dvr: impl Into<String>,
fraction_field: impl Into<String>,
reduction_type: NeronReductionType,
) -> Self {
Self {
variety: variety.into(),
dvr: dvr.into(),
fraction_field: fraction_field.into(),
reduction_type,
component_group_order: None,
}
}
pub fn good_reduction(
variety: impl Into<String>,
dvr: impl Into<String>,
frac: impl Into<String>,
) -> Self {
Self::new(variety, dvr, frac, NeronReductionType::Good)
}
pub fn semi_stable(
variety: impl Into<String>,
dvr: impl Into<String>,
frac: impl Into<String>,
) -> Self {
Self::new(variety, dvr, frac, NeronReductionType::SemiStable)
}
pub fn with_component_group(mut self, order: u64) -> Self {
self.component_group_order = Some(order);
self
}
pub fn has_good_reduction(&self) -> bool {
self.reduction_type == NeronReductionType::Good
}
pub fn is_semi_stable(&self) -> bool {
matches!(
self.reduction_type,
NeronReductionType::Good
| NeronReductionType::SemiStable
| NeronReductionType::PurelyToric
)
}
pub fn tamagawa_number(&self) -> u64 {
self.component_group_order.unwrap_or(1)
}
}
#[allow(dead_code)]
#[derive(Debug, Clone, PartialEq, Eq)]
pub enum NeronReductionType {
Good,
SemiStable,
PurelyToric,
Additive,
}
#[derive(Debug, Clone)]
pub struct EllipticCurve {
pub field: String,
pub a: i64,
pub b: i64,
}
impl EllipticCurve {
pub fn new(field: impl Into<String>, a: i64, b: i64) -> Self {
Self {
field: field.into(),
a,
b,
}
}
pub fn discriminant(&self) -> i64 {
-16 * (4 * self.a.pow(3) + 27 * self.b.pow(2))
}
pub fn is_non_singular(&self) -> bool {
self.discriminant() != 0
}
pub fn j_invariant(&self) -> Option<f64> {
let delta = self.discriminant();
if delta == 0 {
return None;
}
let numerator = -1728.0 * (4.0 * (self.a as f64)).powi(3);
Some(numerator / (delta as f64))
}
pub fn j_class(&self) -> String {
match self.j_invariant() {
Some(j) => format!("j = {:.4}", j),
None => "Singular (not an elliptic curve)".to_string(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TateModule {
pub variety: String,
pub prime: u64,
pub rank: usize,
}
impl TateModule {
pub fn new(variety: impl Into<String>, prime: u64, dimension: usize) -> Self {
Self {
variety: variety.into(),
prime,
rank: 2 * dimension,
}
}
}
#[derive(Debug, Clone)]
pub struct ShimuraDatum {
pub group: String,
pub domain: String,
pub reflex_field: String,
}
impl ShimuraDatum {
pub fn new(
group: impl Into<String>,
domain: impl Into<String>,
reflex_field: impl Into<String>,
) -> Self {
Self {
group: group.into(),
domain: domain.into(),
reflex_field: reflex_field.into(),
}
}
pub fn gl2_upper_half_plane() -> Self {
Self::new("GL_2", "H (upper half-plane)", "Q")
}
pub fn siegel(g: usize) -> Self {
Self::new(
format!("GSp_{{2{}}}", g),
format!("H_{} (Siegel half-space)", g),
"Q",
)
}
}
#[derive(Debug, Clone)]
pub struct CanonicalModel {
pub shimura_variety: ShimuraVariety,
pub reflex_field: String,
}
impl CanonicalModel {
pub fn new(variety: ShimuraVariety, reflex_field: impl Into<String>) -> Self {
Self {
shimura_variety: variety,
reflex_field: reflex_field.into(),
}
}
}
#[derive(Debug, Clone)]
pub struct NearlyOrdinaryRepresentation {
pub rep: GaloisRepresentation,
pub prime: u64,
}
impl NearlyOrdinaryRepresentation {
pub fn new(rep: GaloisRepresentation, prime: u64) -> Self {
Self { rep, prime }
}
}
#[derive(Debug, Clone)]
pub struct HeightFunction {
pub curve: String,
pub field: String,
}
impl HeightFunction {
pub fn neron_tate(curve: impl Into<String>, field: impl Into<String>) -> Self {
Self {
curve: curve.into(),
field: field.into(),
}
}
pub fn naive_height(x_num: i64, x_den: u64) -> f64 {
if x_den == 0 {
return 0.0;
}
0.5 * ((x_num.unsigned_abs()).max(x_den) as f64).ln()
}
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct PerfectoidField {
pub name: String,
pub residue_char: u64,
pub is_alg_closed: bool,
pub tilt_name: String,
}
#[allow(dead_code)]
impl PerfectoidField {
pub fn new(name: impl Into<String>, residue_char: u64, tilt_name: impl Into<String>) -> Self {
Self {
name: name.into(),
residue_char,
is_alg_closed: false,
tilt_name: tilt_name.into(),
}
}
pub fn c_p(p: u64) -> Self {
Self {
name: format!("C_{}", p),
residue_char: p,
is_alg_closed: true,
tilt_name: format!("C_{}^flat", p),
}
}
pub fn q_p_cyclotomic(p: u64) -> Self {
Self {
name: format!("Q_{}(zeta_{{p^inf}})", p),
residue_char: p,
is_alg_closed: false,
tilt_name: format!("F_{}((t^{{1/p^inf}}))", p),
}
}
pub fn residue_characteristic(&self) -> u64 {
self.residue_char
}
pub fn tilt_characteristic(&self) -> u64 {
self.residue_char
}
pub fn hodge_tate_description(&self, dim: usize) -> String {
format!(
"H^{{}} decomposes over {} as direct sum of dim {} C_p-spaces with Hodge-Tate weights",
self.name, dim
)
}
}
#[derive(Debug, Clone)]
pub struct Isogeny {
pub source: String,
pub target: String,
pub degree: u64,
}
impl Isogeny {
pub fn new(source: impl Into<String>, target: impl Into<String>, degree: u64) -> Self {
Self {
source: source.into(),
target: target.into(),
degree,
}
}
pub fn multiplication_by_n(curve: impl Into<String>, n: u64) -> Self {
let c = curve.into();
Self {
source: c.clone(),
target: c,
degree: n * n,
}
}
pub fn is_endomorphism(&self) -> bool {
self.source == self.target
}
}
#[derive(Debug, Clone)]
pub struct DualAbelianVariety {
pub variety: AbelianVariety,
}
impl DualAbelianVariety {
pub fn of(variety: AbelianVariety) -> Self {
Self { variety }
}
pub fn dimension(&self) -> usize {
self.variety.dimension
}
}
#[derive(Debug, Clone)]
pub struct PolarizedAbelianVariety {
pub variety: AbelianVariety,
pub polarization_degree: u64,
pub is_principal: bool,
}
impl PolarizedAbelianVariety {
pub fn principally_polarized(variety: AbelianVariety) -> Self {
Self {
variety,
polarization_degree: 1,
is_principal: true,
}
}
pub fn polarized(variety: AbelianVariety, degree: u64) -> Self {
Self {
variety,
polarization_degree: degree,
is_principal: degree == 1,
}
}
}
#[derive(Debug, Clone)]
pub struct BirchSwinnertonDyerData {
pub curve: String,
pub rank: usize,
pub regulator: f64,
pub sha_order: Option<u64>,
pub bsd_rank_verified: bool,
}
impl BirchSwinnertonDyerData {
pub fn new(curve: impl Into<String>, rank: usize, regulator: f64) -> Self {
Self {
curve: curve.into(),
rank,
regulator,
sha_order: None,
bsd_rank_verified: false,
}
}
pub fn leading_coefficient_prediction(&self) -> f64 {
let sha = self.sha_order.unwrap_or(1) as f64;
sha * self.regulator
}
}
#[derive(Debug, Clone)]
pub struct ShimuraVariety {
pub datum: ShimuraDatum,
pub level: String,
pub complex_dimension: usize,
}
impl ShimuraVariety {
pub fn new(datum: ShimuraDatum, level: impl Into<String>, dim: usize) -> Self {
Self {
datum,
level: level.into(),
complex_dimension: dim,
}
}
pub fn modular_curve_y(n: usize) -> Self {
Self::new(ShimuraDatum::gl2_upper_half_plane(), format!("Γ({})", n), 1)
}
}
#[derive(Debug, Clone)]
pub struct GaloisRepresentation {
pub galois_group: String,
pub dimension: usize,
pub coefficient_ring: String,
pub is_irreducible: bool,
pub is_geometric: bool,
}
impl GaloisRepresentation {
pub fn new(gal_group: impl Into<String>, dim: usize, ring: impl Into<String>) -> Self {
Self {
galois_group: gal_group.into(),
dimension: dim,
coefficient_ring: ring.into(),
is_irreducible: false,
is_geometric: false,
}
}
pub fn cyclotomic(ell: u64) -> Self {
let mut r = Self::new("G_Q", 1, format!("Z_{}", ell));
r.is_irreducible = true;
r.is_geometric = true;
r
}
pub fn from_elliptic_curve(curve: &str, ell: u64) -> Self {
let mut r = Self::new("G_Q", 2, format!("Z_{}", ell));
r.galois_group = format!("G_Q (from {})", curve);
r.is_geometric = true;
r
}
pub fn irreducible(mut self) -> Self {
self.is_irreducible = true;
self
}
}
#[derive(Debug, Clone)]
pub struct TolimaniConjecture {
pub proved: bool,
pub proof_method: String,
}
impl TolimaniConjecture {
pub fn proved() -> Self {
Self {
proved: true,
proof_method: "o-minimality (Pila-Wilkie) + height bounds".to_string(),
}
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct TorsionPoint {
pub curve: String,
pub n: u64,
pub is_full_n_torsion: bool,
}
impl TorsionPoint {
pub fn full(curve: impl Into<String>, n: u64) -> Self {
Self {
curve: curve.into(),
n,
is_full_n_torsion: true,
}
}
pub fn size(&self) -> u64 {
if self.is_full_n_torsion {
self.n * self.n
} else {
self.n
}
}
}
#[derive(Debug, Clone)]
pub struct FaltingsThm {
pub curve: String,
pub genus: usize,
pub field: String,
pub known_rational_points: Vec<String>,
}
impl FaltingsThm {
pub fn for_curve(curve: impl Into<String>, genus: usize, field: impl Into<String>) -> Self {
Self {
curve: curve.into(),
genus,
field: field.into(),
known_rational_points: Vec::new(),
}
}
pub fn finiteness_guaranteed(&self) -> bool {
self.genus >= 2
}
pub fn add_rational_point(&mut self, point: impl Into<String>) {
self.known_rational_points.push(point.into());
}
pub fn fermat_curve(n: usize, field: impl Into<String>) -> Self {
let genus = if n >= 3 { (n - 1) * (n - 2) / 2 } else { 0 };
Self::for_curve(format!("x^{} + y^{} = 1", n, n), genus, field)
}
}