#![allow(clippy::items_after_test_module)]
use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
use std::collections::HashMap;
use super::types::{
ChainComplex, ChainGroup, ChowGroupData, DGCategoryData, ExtGroup, MixedHodgeStructureData,
SpectralSequence, SpectralSequencePage, TriangulatedCategoryData,
};
pub fn app(f: Expr, a: Expr) -> Expr {
Expr::App(Box::new(f), Box::new(a))
}
pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
app(app(f, a), b)
}
pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
app(app2(f, a, b), c)
}
pub fn cst(s: &str) -> Expr {
Expr::Const(Name::str(s), vec![])
}
pub fn prop() -> Expr {
Expr::Sort(Level::zero())
}
pub fn type0() -> Expr {
Expr::Sort(Level::succ(Level::zero()))
}
pub fn type1() -> Expr {
Expr::Sort(Level::succ(Level::succ(Level::zero())))
}
pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
}
pub fn arrow(a: Expr, b: Expr) -> Expr {
pi(BinderInfo::Default, "_", a, b)
}
pub fn bvar(n: u32) -> Expr {
Expr::BVar(n)
}
pub fn nat_ty() -> Expr {
cst("Nat")
}
pub fn int_ty() -> Expr {
cst("Int")
}
pub fn chain_complex_ty() -> Expr {
pi(
BinderInfo::Default,
"n",
int_ty(),
arrow(app(cst("ModuleObj"), bvar(0)), type0()),
)
}
pub fn homology_group_ty() -> Expr {
arrow(cst("ChainComplex"), arrow(int_ty(), cst("Module")))
}
pub fn exact_sequence_ty() -> Expr {
pi(
BinderInfo::Default,
"A",
cst("Module"),
pi(
BinderInfo::Default,
"B",
cst("Module"),
pi(
BinderInfo::Default,
"C",
cst("Module"),
arrow(
arrow(bvar(2), bvar(1)),
arrow(arrow(bvar(2), bvar(1)), prop()),
),
),
),
)
}
pub fn derived_functor_ty() -> Expr {
arrow(
nat_ty(),
arrow(cst("Module"), arrow(cst("Module"), cst("Module"))),
)
}
pub fn tor_functor_ty() -> Expr {
arrow(
nat_ty(),
arrow(cst("Module"), arrow(cst("Module"), cst("Module"))),
)
}
pub fn snake_lemma_ty() -> Expr {
pi(
BinderInfo::Default,
"A",
cst("Module"),
pi(
BinderInfo::Default,
"B",
cst("Module"),
pi(
BinderInfo::Default,
"C",
cst("Module"),
arrow(app3(cst("ExactRow"), bvar(2), bvar(1), bvar(0)), prop()),
),
),
)
}
pub fn five_lemma_ty() -> Expr {
pi(
BinderInfo::Default,
"A",
cst("FiveTermSeq"),
pi(
BinderInfo::Default,
"B",
cst("FiveTermSeq"),
arrow(
app2(cst("CornerIsomorphisms"), bvar(1), bvar(0)),
app2(cst("MiddleIsomorphism"), bvar(2), bvar(1)),
),
),
)
}
pub fn build_homological_algebra_env(env: &mut Environment) {
let base_types: &[(&str, fn() -> Expr)] = &[
("Module", || type1()),
("ModuleObj", || arrow(int_ty(), type1())),
("ChainComplex", || type1()),
("ExactRow", || {
arrow(
cst("Module"),
arrow(cst("Module"), arrow(cst("Module"), prop())),
)
}),
("FiveTermSeq", || type1()),
];
for (name, mk_ty) in base_types {
let ty = mk_ty();
env.add(Declaration::Axiom {
name: Name::str(*name),
univ_params: vec![],
ty,
})
.ok();
}
let type_axioms: &[(&str, fn() -> Expr)] = &[
("Homology", homology_group_ty),
("ExactSequence", exact_sequence_ty),
("Ext", derived_functor_ty),
("Tor", tor_functor_ty),
];
for (name, mk_ty) in type_axioms {
let ty = mk_ty();
env.add(Declaration::Axiom {
name: Name::str(*name),
univ_params: vec![],
ty,
})
.ok();
}
let theorem_axioms: &[(&str, fn() -> Expr)] = &[
("snake_lemma", snake_lemma_ty),
("five_lemma", five_lemma_ty),
];
for (name, mk_ty) in theorem_axioms {
let ty = mk_ty();
env.add(Declaration::Axiom {
name: Name::str(*name),
univ_params: vec![],
ty,
})
.ok();
}
}
pub fn image_rank(matrix: &[Vec<i64>], cols: usize) -> usize {
if matrix.is_empty() || cols == 0 {
return 0;
}
let rows = matrix.len();
let mut m: Vec<Vec<i64>> = (0..rows)
.map(|r| (0..cols).map(|c| matrix[r][c]).collect())
.collect();
let mut pivot_col = 0usize;
let mut pivot_row = 0usize;
while pivot_row < rows && pivot_col < cols {
let found = (pivot_row..rows).find(|&r| m[r][pivot_col] != 0);
match found {
None => {
pivot_col += 1;
}
Some(r) => {
m.swap(pivot_row, r);
let piv = m[pivot_row][pivot_col];
for r2 in (pivot_row + 1)..rows {
let factor = m[r2][pivot_col];
if factor != 0 {
for c in 0..cols {
m[r2][c] = m[r2][c] * piv - m[pivot_row][c] * factor;
}
}
}
pivot_row += 1;
pivot_col += 1;
}
}
}
pivot_row
}
pub fn kernel_rank(matrix: &[Vec<i64>], cols: usize) -> usize {
let img = image_rank(matrix, cols);
cols.saturating_sub(img)
}
pub fn triangulated_category_ty() -> Expr {
type1()
}
pub fn distinguished_triangle_ty() -> Expr {
pi(
BinderInfo::Default,
"T",
cst("TriangulatedCategory"),
pi(
BinderInfo::Default,
"X",
app(cst("CatObj"), bvar(0)),
pi(
BinderInfo::Default,
"Y",
app(cst("CatObj"), bvar(1)),
pi(
BinderInfo::Default,
"Z",
app(cst("CatObj"), bvar(2)),
prop(),
),
),
),
)
}
pub fn octahedral_axiom_ty() -> Expr {
pi(
BinderInfo::Default,
"T",
cst("TriangulatedCategory"),
prop(),
)
}
pub fn t_structure_ty() -> Expr {
arrow(cst("TriangulatedCategory"), type1())
}
pub fn heart_of_t_structure_ty() -> Expr {
arrow(cst("TStructureAxiom"), type1())
}
pub fn truncation_functor_ty() -> Expr {
arrow(
cst("TStructureAxiom"),
arrow(int_ty(), arrow(cst("DerivedCat"), cst("DerivedCat"))),
)
}
pub fn dg_category_ty() -> Expr {
type1()
}
pub fn maurer_cartan_element_ty() -> Expr {
pi(
BinderInfo::Default,
"C",
cst("DGCategory"),
pi(BinderInfo::Default, "X", app(cst("DGObj"), bvar(0)), prop()),
)
}
pub fn twisted_complex_ty() -> Expr {
arrow(cst("DGCategory"), type1())
}
pub fn a_infinity_category_ty() -> Expr {
type1()
}
pub fn a_infinity_functor_ty() -> Expr {
arrow(
cst("AInfinityCategory"),
arrow(cst("AInfinityCategory"), type1()),
)
}
pub fn yoneda_embedding_dg_ty() -> Expr {
pi(
BinderInfo::Default,
"C",
cst("DGCategory"),
pi(BinderInfo::Default, "M", cst("AInfinityCategory"), prop()),
)
}
pub fn infinity_category_ty() -> Expr {
type1()
}
pub fn stable_infinity_category_ty() -> Expr {
arrow(cst("InfinityCategory"), prop())
}
pub fn infinity_topos_ty() -> Expr {
type1()
}
pub fn presentable_infinity_category_ty() -> Expr {
arrow(cst("InfinityCategory"), prop())
}
pub fn homotopy_coherent_diagram_ty() -> Expr {
arrow(
cst("InfinityCategory"),
arrow(cst("InfinityCategory"), type1()),
)
}
pub fn homotopy_limit_ty() -> Expr {
pi(
BinderInfo::Default,
"I",
cst("InfinityCategory"),
pi(
BinderInfo::Default,
"C",
cst("InfinityCategory"),
pi(
BinderInfo::Default,
"F",
app2(cst("HomotopyCoherentDiagram"), bvar(1), bvar(0)),
pi(
BinderInfo::Default,
"X",
app(cst("CatObj"), bvar(1)),
prop(),
),
),
),
)
}
pub fn homotopy_colimit_ty() -> Expr {
pi(
BinderInfo::Default,
"I",
cst("InfinityCategory"),
pi(
BinderInfo::Default,
"C",
cst("InfinityCategory"),
pi(
BinderInfo::Default,
"F",
app2(cst("HomotopyCoherentDiagram"), bvar(1), bvar(0)),
pi(
BinderInfo::Default,
"X",
app(cst("CatObj"), bvar(1)),
prop(),
),
),
),
)
}
pub fn derived_hom_ty() -> Expr {
pi(
BinderInfo::Default,
"D",
cst("DerivedCat"),
pi(
BinderInfo::Default,
"X",
app(cst("DerivedCatObj"), bvar(0)),
pi(
BinderInfo::Default,
"Y",
app(cst("DerivedCatObj"), bvar(1)),
cst("ChainCx"),
),
),
)
}
pub fn derived_tensor_ty() -> Expr {
pi(
BinderInfo::Default,
"D",
cst("DerivedCat"),
pi(
BinderInfo::Default,
"X",
app(cst("DerivedCatObj"), bvar(0)),
pi(
BinderInfo::Default,
"Y",
app(cst("DerivedCatObj"), bvar(1)),
app(cst("DerivedCatObj"), bvar(2)),
),
),
)
}
pub fn derived_pushforward_ty() -> Expr {
pi(
BinderInfo::Default,
"f",
cst("SchemeMorphism"),
arrow(
app(cst("DerivedCatObj"), cst("DerivedCat")),
app(cst("DerivedCatObj"), cst("DerivedCat")),
),
)
}
pub fn derived_pullback_ty() -> Expr {
pi(
BinderInfo::Default,
"f",
cst("SchemeMorphism"),
arrow(
app(cst("DerivedCatObj"), cst("DerivedCat")),
app(cst("DerivedCatObj"), cst("DerivedCat")),
),
)
}
pub fn perverse_sheaf_ty() -> Expr {
arrow(cst("Scheme"), type1())
}
pub fn middle_perversity_ty() -> Expr {
arrow(cst("Scheme"), arrow(nat_ty(), nat_ty()))
}
pub fn intersection_cohomology_ty() -> Expr {
pi(
BinderInfo::Default,
"X",
cst("Scheme"),
pi(
BinderInfo::Default,
"IC",
app(cst("PerverseSheaf"), bvar(0)),
arrow(nat_ty(), cst("Module")),
),
)
}
pub fn decomposition_theorem_ty() -> Expr {
pi(
BinderInfo::Default,
"f",
cst("SchemeMorphism"),
pi(BinderInfo::Default, "IC", cst("PerverseSheaf"), prop()),
)
}
pub fn mixed_hodge_structure_ty() -> Expr {
type1()
}
pub fn hodge_filtration_ty() -> Expr {
arrow(cst("MixedHodgeStructure"), arrow(nat_ty(), cst("Module")))
}
pub fn weight_filtration_ty() -> Expr {
arrow(cst("MixedHodgeStructure"), arrow(int_ty(), cst("Module")))
}
pub fn polarizable_mhs_ty() -> Expr {
arrow(cst("MixedHodgeStructure"), prop())
}
pub fn hodge_decomposition_ty() -> Expr {
arrow(cst("MixedHodgeStructure"), prop())
}
pub fn motivic_cohomology_ty() -> Expr {
pi(
BinderInfo::Default,
"X",
cst("Scheme"),
arrow(int_ty(), arrow(int_ty(), cst("Module"))),
)
}
pub fn algebraic_k_theory_ty() -> Expr {
arrow(cst("Scheme"), arrow(nat_ty(), cst("Module")))
}
pub fn milnor_k_theory_ty() -> Expr {
arrow(cst("Field"), arrow(nat_ty(), cst("Module")))
}
pub fn bloch_kato_conjecture_ty() -> Expr {
pi(
BinderInfo::Default,
"F",
cst("Field"),
arrow(nat_ty(), prop()),
)
}
pub fn hypercovering_ty() -> Expr {
arrow(cst("Site"), arrow(cst("Scheme"), type1()))
}
pub fn cohomological_descent_ty() -> Expr {
pi(
BinderInfo::Default,
"S",
cst("Site"),
pi(BinderInfo::Default, "F", cst("Sheaf"), prop()),
)
}
pub fn dualizing_complex_ty() -> Expr {
arrow(cst("Scheme"), app(cst("DerivedCatObj"), cst("DerivedCat")))
}
pub fn verdier_duality_ty() -> Expr {
pi(BinderInfo::Default, "X", cst("Scheme"), prop())
}
pub fn six_functors_ty() -> Expr {
arrow(cst("SchemeMorphism"), prop())
}
pub fn local_cohomology_ty() -> Expr {
pi(
BinderInfo::Default,
"X",
cst("Scheme"),
pi(
BinderInfo::Default,
"Z",
cst("ClosedSubscheme"),
pi(
BinderInfo::Default,
"F",
cst("Sheaf"),
arrow(nat_ty(), cst("Module")),
),
),
)
}
pub fn local_duality_ty() -> Expr {
pi(
BinderInfo::Default,
"R",
cst("Ring"),
pi(
BinderInfo::Default,
"M",
cst("Module"),
arrow(nat_ty(), prop()),
),
)
}
pub fn de_rham_cohomology_ty() -> Expr {
arrow(cst("SmoothScheme"), arrow(nat_ty(), cst("Module")))
}
pub fn de_rham_comparison_ty() -> Expr {
pi(
BinderInfo::Default,
"X",
cst("SmoothScheme"),
arrow(nat_ty(), prop()),
)
}
pub fn gauss_manin_connection_ty() -> Expr {
pi(
BinderInfo::Default,
"f",
cst("FamilyOfSchemes"),
pi(BinderInfo::Default, "E", cst("DeRhamBundle"), prop()),
)
}
pub fn crystalline_cohomology_ty() -> Expr {
arrow(cst("SmoothScheme"), arrow(nat_ty(), cst("Module")))
}
pub fn f_crystal_ty() -> Expr {
arrow(cst("SmoothScheme"), type1())
}
pub fn dieudonne_module_ty() -> Expr {
arrow(cst("FormalGroup"), type1())
}
pub fn etale_cohomology_ty() -> Expr {
arrow(cst("Scheme"), arrow(nat_ty(), cst("Module")))
}
pub fn weil_conjectures_ty() -> Expr {
arrow(cst("Scheme"), prop())
}
pub fn purity_theorem_ty() -> Expr {
pi(
BinderInfo::Default,
"X",
cst("Scheme"),
pi(
BinderInfo::Default,
"Z",
cst("ClosedSubscheme"),
arrow(nat_ty(), prop()),
),
)
}
pub fn proper_base_change_ty() -> Expr {
pi(
BinderInfo::Default,
"f",
cst("SchemeMorphism"),
arrow(cst("Sheaf"), prop()),
)
}
pub fn chow_group_ty() -> Expr {
arrow(cst("Scheme"), arrow(nat_ty(), cst("Module")))
}
pub fn blochs_formula_ty() -> Expr {
pi(
BinderInfo::Default,
"X",
cst("SmoothScheme"),
arrow(nat_ty(), prop()),
)
}
pub fn higher_chow_group_ty() -> Expr {
pi(
BinderInfo::Default,
"X",
cst("Scheme"),
arrow(nat_ty(), arrow(nat_ty(), cst("Module"))),
)
}
pub fn cycle_class_map_ty() -> Expr {
pi(
BinderInfo::Default,
"X",
cst("Scheme"),
arrow(nat_ty(), prop()),
)
}
pub fn hodge_conjecture_ty() -> Expr {
pi(
BinderInfo::Default,
"X",
cst("SmoothProjectiveScheme"),
arrow(nat_ty(), prop()),
)
}
pub fn grothendieck_standard_conjectures_ty() -> Expr {
arrow(cst("Scheme"), prop())
}
pub fn register_advanced_homological_axioms(env: &mut Environment) {
let new_base_types: &[(&str, fn() -> Expr)] = &[
("TriangulatedCategory", triangulated_category_ty),
("DerivedCat", || type1()),
("TStructureAxiom", || {
arrow(cst("TriangulatedCategory"), type1())
}),
("DGCategory", dg_category_ty),
("DGObj", || arrow(cst("DGCategory"), type1())),
("AInfinityCategory", a_infinity_category_ty),
("InfinityCategory", infinity_category_ty),
("CatObj", || arrow(cst("InfinityCategory"), type1())),
("DerivedCatObj", || arrow(cst("DerivedCat"), type1())),
("ChainCx", || type1()),
("SchemeMorphism", || type1()),
("Scheme", || type1()),
("SmoothScheme", || type1()),
("SmoothProjectiveScheme", || type1()),
("Site", || type1()),
("Sheaf", || type1()),
("Ring", || type1()),
("Field", || type1()),
("FormalGroup", || type1()),
("ClosedSubscheme", || type1()),
("FamilyOfSchemes", || type1()),
("DeRhamBundle", || type1()),
("PerverseSheaf", || arrow(cst("Scheme"), type1())),
("MixedHodgeStructure", mixed_hodge_structure_ty),
];
for (name, mk_ty) in new_base_types {
let ty = mk_ty();
env.add(Declaration::Axiom {
name: Name::str(*name),
univ_params: vec![],
ty,
})
.ok();
}
let new_axioms: &[(&str, fn() -> Expr)] = &[
("DistinguishedTriangle", distinguished_triangle_ty),
("OctahedralAxiom", octahedral_axiom_ty),
("HeartOfTStructure", heart_of_t_structure_ty),
("TruncationFunctor", truncation_functor_ty),
("MaurerCartanElement", maurer_cartan_element_ty),
("TwistedComplex", twisted_complex_ty),
("AInfinityFunctor", a_infinity_functor_ty),
("YonedaEmbeddingDG", yoneda_embedding_dg_ty),
("StableInfinityCategory", stable_infinity_category_ty),
("InfinityTopos", infinity_topos_ty),
(
"PresentableInfinityCategory",
presentable_infinity_category_ty,
),
("HomotopyCoherentDiagram", homotopy_coherent_diagram_ty),
("HomotopyLimit", homotopy_limit_ty),
("HomotopyColimit", homotopy_colimit_ty),
("DerivedHom", derived_hom_ty),
("DerivedTensor", derived_tensor_ty),
("DerivedPushforward", derived_pushforward_ty),
("DerivedPullback", derived_pullback_ty),
("MiddlePerversity", middle_perversity_ty),
("IntersectionCohomology", intersection_cohomology_ty),
("DecompositionTheorem", decomposition_theorem_ty),
("HodgeFiltration", hodge_filtration_ty),
("WeightFiltration", weight_filtration_ty),
("PolarizableMHS", polarizable_mhs_ty),
("HodgeDecomposition", hodge_decomposition_ty),
("MotivicCohomology", motivic_cohomology_ty),
("AlgebraicKTheory", algebraic_k_theory_ty),
("MilnorKTheory", milnor_k_theory_ty),
("BlochKatoConjecture", bloch_kato_conjecture_ty),
("Hypercovering", hypercovering_ty),
("CohomologicalDescent", cohomological_descent_ty),
("DualizingComplex", dualizing_complex_ty),
("VerdierDuality", verdier_duality_ty),
("SixFunctors", six_functors_ty),
("LocalCohomology", local_cohomology_ty),
("LocalDuality", local_duality_ty),
("DeRhamCohomology", de_rham_cohomology_ty),
("DeRhamComparison", de_rham_comparison_ty),
("GaussManinConnection", gauss_manin_connection_ty),
("CrystallineCohomology", crystalline_cohomology_ty),
("FCrystal", f_crystal_ty),
("DieudonneModule", dieudonne_module_ty),
("EtaleCohomology", etale_cohomology_ty),
("WeilConjectures", weil_conjectures_ty),
("PurityTheorem", purity_theorem_ty),
("ProperBaseChange", proper_base_change_ty),
("ChowGroup", chow_group_ty),
("BlochsFormula", blochs_formula_ty),
("HigherChowGroup", higher_chow_group_ty),
("CycleClassMap", cycle_class_map_ty),
("HodgeConjecture", hodge_conjecture_ty),
(
"GrothendieckStandardConjectures",
grothendieck_standard_conjectures_ty,
),
];
for (name, mk_ty) in new_axioms {
let ty = mk_ty();
env.add(Declaration::Axiom {
name: Name::str(*name),
univ_params: vec![],
ty,
})
.ok();
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_chain_group_display() {
let g = ChainGroup::new(3, "C_2");
assert!(g.to_string().contains("C_2"));
assert!(g.to_string().contains("3"));
}
#[test]
fn test_chain_complex_trivial_betti() {
let mut c = ChainComplex::new();
c.add_group(1, "C_0");
let betti = c.compute_betti_numbers();
assert_eq!(betti, vec![1]);
}
#[test]
fn test_chain_complex_euler_characteristic_circle() {
let mut c = ChainComplex::new();
c.add_group(3, "C_0");
c.add_group(3, "C_1");
c.add_boundary(vec![vec![-1, 0, -1], vec![1, -1, 0], vec![0, 1, 1]]);
let chi = c.euler_characteristic();
assert_eq!(chi, 0);
}
#[test]
fn test_chain_complex_is_exact_at_acyclic() {
let mut c = ChainComplex::new();
c.add_group(1, "C_0");
c.add_group(1, "C_1");
c.add_boundary(vec![vec![1]]);
assert!(c.is_exact_at(0));
}
#[test]
fn test_ext_group_is_zero() {
let e0 = ExtGroup::new("Z", "Z", 0, 1);
let e1 = ExtGroup::new("Z", "Z", 1, 0);
assert!(!e0.is_zero());
assert!(e1.is_zero());
}
#[test]
fn test_ext_group_display() {
let e = ExtGroup::new("Z/2Z", "Z", 1, 1);
let s = e.to_string();
assert!(s.contains("Ext^1"));
assert!(s.contains("Z/2Z"));
assert!(s.contains("rank=1"));
}
#[test]
fn test_spectral_sequence_e_term() {
let mut ss = SpectralSequence::new();
let mut page0: HashMap<(i32, i32), usize> = HashMap::new();
page0.insert((0, 0), 1);
page0.insert((1, 0), 2);
ss.add_page(page0);
assert_eq!(ss.e_term(0, 0, 0), Some(1));
assert_eq!(ss.e_term(0, 1, 0), Some(2));
assert_eq!(ss.e_term(0, 2, 0), None);
}
#[test]
fn test_build_homological_algebra_env() {
let mut env = Environment::new();
build_homological_algebra_env(&mut env);
assert!(env.get(&Name::str("Homology")).is_some());
assert!(env.get(&Name::str("Ext")).is_some());
assert!(env.get(&Name::str("Tor")).is_some());
assert!(env.get(&Name::str("snake_lemma")).is_some());
assert!(env.get(&Name::str("five_lemma")).is_some());
}
#[test]
fn test_register_advanced_axioms_env() {
let mut env = Environment::new();
register_advanced_homological_axioms(&mut env);
assert!(env.get(&Name::str("TriangulatedCategory")).is_some());
assert!(env.get(&Name::str("OctahedralAxiom")).is_some());
assert!(env.get(&Name::str("DGCategory")).is_some());
assert!(env.get(&Name::str("AInfinityCategory")).is_some());
assert!(env.get(&Name::str("InfinityCategory")).is_some());
assert!(env.get(&Name::str("HomotopyLimit")).is_some());
assert!(env.get(&Name::str("HomotopyColimit")).is_some());
assert!(env.get(&Name::str("VerdierDuality")).is_some());
assert!(env.get(&Name::str("WeilConjectures")).is_some());
assert!(env.get(&Name::str("ChowGroup")).is_some());
assert!(env.get(&Name::str("HodgeConjecture")).is_some());
}
#[test]
fn test_triangulated_category_data_basic() {
let mut t = TriangulatedCategoryData::new();
let x = t.add_object("X");
let y = t.add_object("Y");
let z = t.add_object("Z");
t.add_triangle(x, y, z);
assert!(t.is_distinguished(x, y, z));
assert!(!t.is_distinguished(y, x, z));
assert_eq!(t.triangle_count(), 1);
}
#[test]
fn test_triangulated_octahedral_check() {
let mut t = TriangulatedCategoryData::new();
let cone_xy = t.add_object("Cone(f)");
let cone_xz = t.add_object("Cone(gf)");
let cone_yz = t.add_object("Cone(g)");
t.add_triangle(cone_xy, cone_xz, cone_yz);
assert!(t.check_octahedral(cone_xy, cone_xz, cone_yz));
assert!(!t.check_octahedral(cone_yz, cone_xy, cone_xz));
}
#[test]
fn test_dg_category_ext_degree() {
let mut dg = DGCategoryData::new();
let x = dg.add_object("X");
let y = dg.add_object("Y");
let mut hom = ChainComplex::new();
hom.add_group(1, "Hom0");
hom.add_group(1, "Hom1");
hom.add_boundary(vec![vec![1]]);
dg.set_hom(x, y, hom);
assert_eq!(dg.ext_degree(x, y, 0), Some(0));
assert!(dg.are_quasi_isomorphic(x, y));
}
#[test]
fn test_mixed_hodge_structure_hodge_numbers() {
let mut mhs = MixedHodgeStructureData::new(2);
mhs.set_hodge_number(2, 0, 1);
mhs.set_hodge_number(1, 1, 20);
mhs.set_hodge_number(0, 2, 1);
assert_eq!(mhs.hodge_number(2, 0), 1);
assert_eq!(mhs.hodge_number(0, 2), 1);
assert_eq!(mhs.hodge_number(1, 1), 20);
assert!(mhs.satisfies_hodge_symmetry());
assert!(mhs.is_pure());
assert_eq!(mhs.total_dimension(), 22);
}
#[test]
fn test_mixed_hodge_structure_not_pure() {
let mut mhs = MixedHodgeStructureData::new(2);
mhs.set_hodge_number(1, 0, 3);
assert!(!mhs.is_pure());
}
#[test]
fn test_chow_group_degree_and_zero() {
let mut ch = ChowGroupData::new("P1", 1);
assert!(ch.is_zero());
ch.add_cycle("pt", 3);
ch.add_cycle("pt", -3);
assert!(ch.is_zero());
ch.add_cycle("line", 2);
assert_eq!(ch.degree(), 2);
}
#[test]
fn test_chow_group_intersection_number() {
let mut ch1 = ChowGroupData::new("P2", 2);
ch1.add_cycle("p", 3);
let mut ch2 = ChowGroupData::new("P2", 2);
ch2.add_cycle("q", 2);
assert_eq!(ch1.intersection_number(&ch2), 6);
}
#[test]
fn test_spectral_sequence_page_next() {
let mut page = SpectralSequencePage::new(2);
page.set_group(0, 2, 3);
page.set_group(2, 1, 2);
page.add_differential(2, 1, 1);
let next = page.compute_next_page();
assert_eq!(next.get(&(2, 1)).copied().unwrap_or(0), 1);
assert_eq!(next.get(&(0, 2)).copied().unwrap_or(0), 2);
}
#[test]
fn test_spectral_sequence_page_degenerate() {
let mut page = SpectralSequencePage::new(3);
page.set_group(0, 0, 5);
assert!(page.is_degenerate());
page.add_differential(0, 0, 1);
assert!(!page.is_degenerate());
}
}
pub fn ha_ext_bounded_derived_category_ty() -> Expr {
arrow(cst("AbelianCat"), type1())
}
pub fn ha_ext_derived_equivalence_ty() -> Expr {
pi(
BinderInfo::Default,
"A",
cst("AbelianCat"),
pi(BinderInfo::Default, "B", cst("AbelianCat"), prop()),
)
}
pub fn ha_ext_shift_functor_ty() -> Expr {
arrow(
cst("TriangulatedCategory"),
arrow(int_ty(), cst("TriangulatedCategory")),
)
}
pub fn ha_ext_exact_functor_ty() -> Expr {
arrow(
cst("TriangulatedCategory"),
arrow(cst("TriangulatedCategory"), type1()),
)
}
pub fn ha_ext_rotation_axiom_ty() -> Expr {
pi(
BinderInfo::Default,
"T",
cst("TriangulatedCategory"),
prop(),
)
}
pub fn ha_ext_stability_condition_ty() -> Expr {
arrow(cst("TriangulatedCategory"), type1())
}
pub fn ha_ext_central_charge_ty() -> Expr {
pi(
BinderInfo::Default,
"σ",
cst("StabilityCondition"),
arrow(cst("Module"), cst("Complex")),
)
}
pub fn ha_ext_harder_narasimhan_filtration_ty() -> Expr {
pi(
BinderInfo::Default,
"σ",
cst("StabilityCondition"),
arrow(cst("Module"), type1()),
)
}
pub fn ha_ext_semistable_object_ty() -> Expr {
pi(
BinderInfo::Default,
"σ",
cst("StabilityCondition"),
arrow(cst("Module"), prop()),
)
}
pub fn ha_ext_wall_crossing_ty() -> Expr {
arrow(cst("TriangulatedCategory"), prop())
}
pub fn ha_ext_fourier_mukai_kernel_ty() -> Expr {
pi(
BinderInfo::Default,
"X",
cst("Scheme"),
pi(
BinderInfo::Default,
"Y",
cst("Scheme"),
app(cst("DerivedCatObj"), cst("DerivedCat")),
),
)
}
pub fn ha_ext_fourier_mukai_transform_ty() -> Expr {
pi(
BinderInfo::Default,
"X",
cst("Scheme"),
pi(
BinderInfo::Default,
"Y",
cst("Scheme"),
pi(
BinderInfo::Default,
"P",
app2(cst("FourierMukaiKernel"), bvar(1), bvar(0)),
cst("ExactFunctor"),
),
),
)
}
pub fn ha_ext_bondal_orlov_reconstruction_ty() -> Expr {
pi(BinderInfo::Default, "X", cst("Scheme"), prop())
}
pub fn ha_ext_mukai_lattice_ty() -> Expr {
arrow(cst("K3Surface"), cst("Module"))
}
pub fn ha_ext_fourier_mukai_is_equivalence_ty() -> Expr {
pi(
BinderInfo::Default,
"X",
cst("Scheme"),
pi(
BinderInfo::Default,
"Y",
cst("Scheme"),
pi(
BinderInfo::Default,
"P",
app2(cst("FourierMukaiKernel"), bvar(1), bvar(0)),
prop(),
),
),
)
}
pub fn ha_ext_serre_functor_ty() -> Expr {
arrow(cst("TriangulatedCategory"), type1())
}
pub fn ha_ext_serre_isomorphism_ty() -> Expr {
pi(
BinderInfo::Default,
"D",
cst("TriangulatedCategory"),
pi(
BinderInfo::Default,
"X",
cst("Module"),
pi(BinderInfo::Default, "Y", cst("Module"), prop()),
),
)
}
pub fn ha_ext_calabi_yau_category_ty() -> Expr {
arrow(cst("TriangulatedCategory"), arrow(nat_ty(), prop()))
}
pub fn ha_ext_calabi_yau_dimension_ty() -> Expr {
arrow(cst("TriangulatedCategory"), int_ty())
}
pub fn ha_ext_spherical_object_ty() -> Expr {
pi(
BinderInfo::Default,
"D",
cst("TriangulatedCategory"),
arrow(cst("Module"), prop()),
)
}
pub fn ha_ext_spherical_twist_ty() -> Expr {
pi(
BinderInfo::Default,
"D",
cst("TriangulatedCategory"),
arrow(cst("Module"), cst("ExactFunctor")),
)
}
pub fn ha_ext_model_category_ty() -> Expr {
type1()
}
pub fn ha_ext_weak_equivalence_ty() -> Expr {
pi(
BinderInfo::Default,
"M",
cst("ModelCategory"),
arrow(cst("Morphism"), prop()),
)
}
pub fn ha_ext_fibration_ty() -> Expr {
pi(
BinderInfo::Default,
"M",
cst("ModelCategory"),
arrow(cst("Morphism"), prop()),
)
}
pub fn ha_ext_cofibration_ty() -> Expr {
pi(
BinderInfo::Default,
"M",
cst("ModelCategory"),
arrow(cst("Morphism"), prop()),
)
}
pub fn ha_ext_cofibrant_object_ty() -> Expr {
pi(
BinderInfo::Default,
"M",
cst("ModelCategory"),
arrow(cst("Obj"), prop()),
)
}
pub fn ha_ext_fibrant_object_ty() -> Expr {
pi(
BinderInfo::Default,
"M",
cst("ModelCategory"),
arrow(cst("Obj"), prop()),
)
}
pub fn ha_ext_cofibrant_replacement_ty() -> Expr {
pi(
BinderInfo::Default,
"M",
cst("ModelCategory"),
pi(
BinderInfo::Default,
"X",
cst("Obj"),
arrow(cst("Obj"), prop()),
),
)
}
pub fn ha_ext_fibrant_replacement_ty() -> Expr {
pi(
BinderInfo::Default,
"M",
cst("ModelCategory"),
pi(
BinderInfo::Default,
"X",
cst("Obj"),
arrow(cst("Obj"), prop()),
),
)
}
pub fn ha_ext_homotopy_category_ty() -> Expr {
arrow(cst("ModelCategory"), type1())
}
pub fn ha_ext_quillen_adjunction_ty() -> Expr {
arrow(cst("ModelCategory"), arrow(cst("ModelCategory"), type1()))
}
pub fn ha_ext_quillen_equivalence_ty() -> Expr {
arrow(cst("ModelCategory"), arrow(cst("ModelCategory"), prop()))
}
pub fn ha_ext_bousfield_localization_ty() -> Expr {
arrow(
cst("ModelCategory"),
arrow(cst("Class"), cst("ModelCategory")),
)
}
pub fn ha_ext_local_object_ty() -> Expr {
pi(
BinderInfo::Default,
"L",
cst("BousfieldLocalization"),
arrow(cst("Obj"), prop()),
)
}
pub fn ha_ext_local_equivalence_ty() -> Expr {
pi(
BinderInfo::Default,
"M",
cst("ModelCategory"),
pi(
BinderInfo::Default,
"C",
cst("Class"),
arrow(cst("Morphism"), prop()),
),
)
}
pub fn ha_ext_smashing_localization_ty() -> Expr {
arrow(cst("ModelCategory"), prop())
}
pub fn ha_ext_tilting_object_ty() -> Expr {
pi(
BinderInfo::Default,
"A",
cst("AbelianCat"),
arrow(cst("Module"), prop()),
)
}
pub fn ha_ext_tilting_equivalence_ty() -> Expr {
pi(
BinderInfo::Default,
"A",
cst("AbelianCat"),
pi(
BinderInfo::Default,
"B",
cst("AbelianCat"),
arrow(cst("Module"), prop()),
),
)
}
pub fn ha_ext_mutation_of_tilting_ty() -> Expr {
pi(
BinderInfo::Default,
"A",
cst("AbelianCat"),
arrow(cst("Module"), arrow(nat_ty(), cst("Module"))),
)
}
pub fn ha_ext_semiorthogonal_decomposition_ty() -> Expr {
arrow(cst("TriangulatedCategory"), type1())
}
pub fn ha_ext_exceptional_collection_ty() -> Expr {
arrow(cst("TriangulatedCategory"), type1())
}
pub fn register_homological_algebra_extended(env: &mut Environment) -> Result<(), String> {
let base_types: &[(&str, fn() -> Expr)] = &[
("AbelianCat", || type1()),
("K3Surface", || type1()),
("Complex", || type1()),
("Morphism", || type1()),
("Obj", || type1()),
("Class", || type1()),
("ModelCategory", || type1()),
("BousfieldLocalization", || {
arrow(
cst("ModelCategory"),
arrow(cst("Class"), cst("ModelCategory")),
)
}),
("ExactFunctor", || {
arrow(
cst("TriangulatedCategory"),
arrow(cst("TriangulatedCategory"), type1()),
)
}),
("StabilityCondition", ha_ext_stability_condition_ty),
("FourierMukaiKernel", ha_ext_fourier_mukai_kernel_ty),
];
for (name, mk_ty) in base_types {
let ty = mk_ty();
env.add(Declaration::Axiom {
name: Name::str(*name),
univ_params: vec![],
ty,
})
.ok();
}
let axioms: &[(&str, fn() -> Expr)] = &[
("BoundedDerivedCategory", ha_ext_bounded_derived_category_ty),
("DerivedEquivalence", ha_ext_derived_equivalence_ty),
("ShiftFunctor", ha_ext_shift_functor_ty),
("RotationAxiom", ha_ext_rotation_axiom_ty),
("CentralCharge", ha_ext_central_charge_ty),
(
"HarderNarasimhanFiltration",
ha_ext_harder_narasimhan_filtration_ty,
),
("SemistableObject", ha_ext_semistable_object_ty),
("WallCrossing", ha_ext_wall_crossing_ty),
("FourierMukaiTransform", ha_ext_fourier_mukai_transform_ty),
(
"BondalOrlovReconstruction",
ha_ext_bondal_orlov_reconstruction_ty,
),
("MukaiLattice", ha_ext_mukai_lattice_ty),
(
"FourierMukaiIsEquivalence",
ha_ext_fourier_mukai_is_equivalence_ty,
),
("SerreFunctor", ha_ext_serre_functor_ty),
("SerreIsomorphism", ha_ext_serre_isomorphism_ty),
("CalabiyauCategory", ha_ext_calabi_yau_category_ty),
("CalabiyauDimension", ha_ext_calabi_yau_dimension_ty),
("SphericalObject", ha_ext_spherical_object_ty),
("SphericalTwist", ha_ext_spherical_twist_ty),
("WeakEquivalence", ha_ext_weak_equivalence_ty),
("Fibration", ha_ext_fibration_ty),
("Cofibration", ha_ext_cofibration_ty),
("CofibrantObject", ha_ext_cofibrant_object_ty),
("FibrantObject", ha_ext_fibrant_object_ty),
("CofibrantReplacement", ha_ext_cofibrant_replacement_ty),
("FibrantReplacement", ha_ext_fibrant_replacement_ty),
("HomotopyCategory", ha_ext_homotopy_category_ty),
("QuillenAdjunction", ha_ext_quillen_adjunction_ty),
("QuillenEquivalence", ha_ext_quillen_equivalence_ty),
("LocalObject", ha_ext_local_object_ty),
("LocalEquivalence", ha_ext_local_equivalence_ty),
("SmashingLocalization", ha_ext_smashing_localization_ty),
("TiltingObject", ha_ext_tilting_object_ty),
("TiltingEquivalence", ha_ext_tilting_equivalence_ty),
("MutationOfTilting", ha_ext_mutation_of_tilting_ty),
(
"SemiorthogonalDecomposition",
ha_ext_semiorthogonal_decomposition_ty,
),
("ExceptionalCollection", ha_ext_exceptional_collection_ty),
];
for (name, mk_ty) in axioms {
let ty = mk_ty();
env.add(Declaration::Axiom {
name: Name::str(*name),
univ_params: vec![],
ty,
})
.map_err(|e| format!("Failed to add '{}': {:?}", name, e))?;
}
Ok(())
}