1#![allow(clippy::items_after_test_module)]
5
6use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
7
8use super::types::{
9 BezoutBound, ChowRingElem, CycleClass, IntersectionMatrix, QuantumCohomologyP2, SchubertCalc,
10 VectorBundleData,
11};
12
13pub fn app(f: Expr, a: Expr) -> Expr {
14 Expr::App(Box::new(f), Box::new(a))
15}
16pub fn app2(f: Expr, a: Expr, b: Expr) -> Expr {
17 app(app(f, a), b)
18}
19pub fn app3(f: Expr, a: Expr, b: Expr, c: Expr) -> Expr {
20 app(app2(f, a, b), c)
21}
22pub fn cst(s: &str) -> Expr {
23 Expr::Const(Name::str(s), vec![])
24}
25pub fn prop() -> Expr {
26 Expr::Sort(Level::zero())
27}
28pub fn type0() -> Expr {
29 Expr::Sort(Level::succ(Level::zero()))
30}
31pub fn type1() -> Expr {
32 Expr::Sort(Level::succ(Level::succ(Level::zero())))
33}
34pub fn pi(bi: BinderInfo, name: &str, dom: Expr, body: Expr) -> Expr {
35 Expr::Pi(bi, Name::str(name), Box::new(dom), Box::new(body))
36}
37pub fn arrow(a: Expr, b: Expr) -> Expr {
38 pi(BinderInfo::Default, "_", a, b)
39}
40pub fn bvar(n: u32) -> Expr {
41 Expr::BVar(n)
42}
43pub fn nat_ty() -> Expr {
44 cst("Nat")
45}
46pub fn int_ty() -> Expr {
47 cst("Int")
48}
49pub fn real_ty() -> Expr {
50 cst("Real")
51}
52pub fn bool_ty() -> Expr {
53 cst("Bool")
54}
55pub fn list_ty(elem: Expr) -> Expr {
56 app(cst("List"), elem)
57}
58pub fn chow_group_ty() -> Expr {
61 arrow(cst("Scheme"), arrow(nat_ty(), type0()))
62}
63pub fn chow_ring_ty() -> Expr {
66 arrow(cst("Scheme"), type0())
67}
68pub fn algebraic_cycle_ty() -> Expr {
71 arrow(cst("Scheme"), arrow(nat_ty(), type0()))
72}
73pub fn rational_equiv_ty() -> Expr {
76 arrow(
77 app2(cst("AlgebraicCycle"), cst("Scheme"), cst("k")),
78 arrow(app2(cst("AlgebraicCycle"), cst("Scheme"), cst("k")), prop()),
79 )
80}
81pub fn intersection_product_ty() -> Expr {
83 arrow(cst("ChowRing"), arrow(cst("ChowRing"), cst("ChowRing")))
84}
85pub fn pushforward_cycle_ty() -> Expr {
87 arrow(cst("Morphism"), arrow(cst("ChowGroup"), cst("ChowGroup")))
88}
89pub fn pullback_cycle_ty() -> Expr {
92 arrow(cst("Morphism"), arrow(cst("ChowGroup"), cst("ChowGroup")))
93}
94pub fn fundamental_class_ty() -> Expr {
97 arrow(cst("Scheme"), cst("ChowGroup"))
98}
99pub fn bezout_intersection_ty() -> Expr {
102 arrow(list_ty(nat_ty()), nat_ty())
103}
104pub fn bezout_theorem_ty() -> Expr {
107 arrow(
108 list_ty(nat_ty()),
109 arrow(prop(), app2(cst("Eq"), cst("Nat"), nat_ty())),
110 )
111}
112pub fn excess_intersection_formula_ty() -> Expr {
115 arrow(
116 cst("Morphism"),
117 arrow(cst("Scheme"), arrow(cst("ExcessBundle"), cst("ChowGroup"))),
118 )
119}
120pub fn chern_class_ty() -> Expr {
123 arrow(cst("VectorBundle"), arrow(nat_ty(), cst("ChowGroup")))
124}
125pub fn total_chern_class_ty() -> Expr {
128 arrow(cst("VectorBundle"), cst("ChowRing"))
129}
130pub fn chern_character_ty() -> Expr {
133 arrow(cst("VectorBundle"), cst("ChowRing"))
134}
135pub fn whitney_sum_formula_ty() -> Expr {
137 arrow(
138 cst("VectorBundle"),
139 arrow(
140 cst("VectorBundle"),
141 app2(
142 cst("Eq"),
143 cst("ChowRing"),
144 app(
145 cst("TotalChernClass"),
146 app2(cst("DirectSum"), bvar(1), bvar(0)),
147 ),
148 ),
149 ),
150 )
151}
152pub fn splitting_principle_ty() -> Expr {
154 arrow(cst("VectorBundle"), arrow(cst("Morphism"), prop()))
155}
156pub fn segre_class_ty() -> Expr {
159 arrow(cst("Subscheme"), arrow(cst("Scheme"), cst("ChowGroup")))
160}
161pub fn self_intersection_formula_ty() -> Expr {
165 arrow(
166 cst("Morphism"),
167 arrow(cst("Scheme"), arrow(cst("NormalBundle"), cst("ChowGroup"))),
168 )
169}
170pub fn segre_chern_relation_ty() -> Expr {
172 arrow(
173 cst("VectorBundle"),
174 app2(
175 cst("Eq"),
176 cst("ChowRing"),
177 app(cst("InverseChow"), app(cst("TotalChernClass"), bvar(0))),
178 ),
179 )
180}
181pub fn todd_class_ty() -> Expr {
184 arrow(cst("VectorBundle"), cst("ChowRing"))
185}
186pub fn grothendieck_riemann_roch_ty() -> Expr {
189 arrow(
190 cst("Morphism"),
191 arrow(
192 cst("CoherentSheaf"),
193 app2(
194 cst("Eq"),
195 cst("ChowRing"),
196 app2(
197 cst("ChowMul"),
198 app(cst("ChernCharacter"), cst("PushforwardSheaf")),
199 app(cst("ToddClass"), cst("TangentBundle")),
200 ),
201 ),
202 ),
203 )
204}
205pub fn hirzebruch_riemann_roch_ty() -> Expr {
208 arrow(
209 cst("SmoothProj"),
210 arrow(
211 cst("VectorBundle"),
212 app2(cst("Eq"), int_ty(), app(cst("EulerChar"), cst("E"))),
213 ),
214 )
215}
216pub fn obstruction_theory_ty() -> Expr {
220 arrow(cst("Morphism"), type0())
221}
222pub fn virtual_fundamental_class_ty() -> Expr {
225 arrow(cst("ObstructionTheory"), cst("ChowGroup"))
226}
227pub fn virtual_dimension_ty() -> Expr {
230 arrow(cst("ObstructionTheory"), int_ty())
231}
232pub fn stable_map_ty() -> Expr {
235 arrow(
236 nat_ty(),
237 arrow(cst("Scheme"), arrow(list_ty(nat_ty()), type1())),
238 )
239}
240pub fn gromov_witten_invariant_ty() -> Expr {
243 arrow(
244 cst("Scheme"),
245 arrow(nat_ty(), arrow(list_ty(cst("ChowClass")), int_ty())),
246 )
247}
248pub fn wdvv_equation_ty() -> Expr {
253 arrow(
254 cst("Scheme"),
255 arrow(
256 cst("ChowClass"),
257 arrow(
258 cst("ChowClass"),
259 arrow(cst("ChowClass"), arrow(cst("ChowClass"), prop())),
260 ),
261 ),
262 )
263}
264pub fn degeneration_formula_ty() -> Expr {
266 arrow(
267 cst("Morphism"),
268 arrow(cst("GromovWittenInvariant"), cst("GromovWittenInvariant")),
269 )
270}
271pub fn quantum_cohomology_ty() -> Expr {
274 arrow(cst("Scheme"), type0())
275}
276pub fn quantum_product_ty() -> Expr {
279 arrow(
280 cst("QuantumCohomology"),
281 arrow(cst("QuantumCohomology"), cst("QuantumCohomology")),
282 )
283}
284pub fn quantum_ring_associativity_ty() -> Expr {
287 arrow(
288 cst("QuantumCohomology"),
289 arrow(
290 cst("QuantumCohomology"),
291 arrow(
292 cst("QuantumCohomology"),
293 app2(
294 cst("Eq"),
295 cst("QuantumCohomology"),
296 app2(
297 cst("QuantumProduct"),
298 app2(cst("QuantumProduct"), bvar(2), bvar(1)),
299 bvar(0),
300 ),
301 ),
302 ),
303 ),
304 )
305}
306pub fn conway_potential_ty() -> Expr {
309 arrow(cst("Scheme"), arrow(nat_ty(), real_ty()))
310}
311pub fn dt_invariant_ty() -> Expr {
314 arrow(cst("Scheme"), arrow(cst("CurveClass"), int_ty()))
315}
316pub fn dt_gw_correspondence_ty() -> Expr {
319 arrow(
320 cst("Scheme"),
321 app2(
322 cst("Eq"),
323 cst("FormalPowerSeries"),
324 app(cst("DTPartitionFunction"), bvar(0)),
325 ),
326 )
327}
328pub fn vertex_formalism_ty() -> Expr {
330 arrow(
331 cst("ToricVariety"),
332 arrow(
333 cst("Partition"),
334 arrow(cst("Partition"), cst("DTInvariant")),
335 ),
336 )
337}
338pub fn hilbert_scheme_dt_ty() -> Expr {
340 arrow(cst("Surface"), arrow(nat_ty(), cst("DTInvariant")))
341}
342pub fn schubert_variety_ty() -> Expr {
345 arrow(cst("Grassmannian"), arrow(cst("Partition"), cst("Scheme")))
346}
347pub fn schubert_class_ty() -> Expr {
350 arrow(
351 cst("Grassmannian"),
352 arrow(cst("Partition"), cst("ChowGroup")),
353 )
354}
355pub fn pieri_formula_ty() -> Expr {
358 arrow(cst("SchubertClass"), arrow(nat_ty(), cst("ChowGroup")))
359}
360pub fn giambelli_formula_ty() -> Expr {
363 arrow(cst("Partition"), cst("ChowGroup"))
364}
365pub fn littlewood_richardson_ty() -> Expr {
368 arrow(
369 cst("Partition"),
370 arrow(cst("Partition"), list_ty(cst("ChowGroup"))),
371 )
372}
373pub fn grassmannian_chow_ring_ty() -> Expr {
376 arrow(nat_ty(), arrow(nat_ty(), type0()))
377}
378pub fn flag_variety_ty() -> Expr {
381 arrow(list_ty(nat_ty()), type0())
382}
383pub fn schubert_polynomial_ty() -> Expr {
386 arrow(cst("Permutation"), cst("Polynomial"))
387}
388pub fn blowup_ty() -> Expr {
391 arrow(cst("Scheme"), arrow(cst("Subscheme"), cst("Scheme")))
392}
393pub fn exceptional_divisor_ty() -> Expr {
396 arrow(cst("BlowupScheme"), cst("Divisor"))
397}
398pub fn blowup_chow_ring_map_ty() -> Expr {
401 arrow(cst("Scheme"), arrow(cst("Subscheme"), cst("ChowRing")))
402}
403pub fn strict_transform_ty() -> Expr {
406 arrow(cst("Scheme"), arrow(cst("BlowupScheme"), cst("Scheme")))
407}
408pub fn blowup_formula_ty() -> Expr {
411 arrow(
412 cst("Scheme"),
413 arrow(
414 cst("Subscheme"),
415 app2(cst("Eq"), cst("ChowRing"), cst("ChowRing")),
416 ),
417 )
418}
419pub fn degeneracy_locus_ty() -> Expr {
422 arrow(cst("BundleMap"), arrow(nat_ty(), cst("Scheme")))
423}
424pub fn thom_porteous_formula_ty() -> Expr {
427 arrow(cst("BundleMap"), arrow(cst("Partition"), cst("ChowGroup")))
428}
429pub fn euler_class_ty() -> Expr {
432 arrow(cst("VectorBundle"), cst("ChowGroup"))
433}
434pub fn euler_class_zero_locus_ty() -> Expr {
437 arrow(
438 cst("VectorBundle"),
439 arrow(
440 cst("BundleSection"),
441 app2(cst("Eq"), cst("ChowGroup"), app(cst("EulerClass"), bvar(1))),
442 ),
443 )
444}
445pub fn moduli_curves_ty() -> Expr {
448 arrow(nat_ty(), arrow(nat_ty(), type1()))
449}
450pub fn deligne_mumford_ty() -> Expr {
453 arrow(nat_ty(), arrow(nat_ty(), type1()))
454}
455pub fn kontsevich_space_ty() -> Expr {
458 arrow(cst("Scheme"), arrow(nat_ty(), arrow(nat_ty(), type1())))
459}
460pub fn psi_class_ty() -> Expr {
463 arrow(cst("ModuliCurvesType"), arrow(nat_ty(), cst("ChowGroup")))
464}
465pub fn lambda_class_ty() -> Expr {
468 arrow(cst("ModuliCurvesType"), arrow(nat_ty(), cst("ChowGroup")))
469}
470pub fn virasoro_constraints_ty() -> Expr {
472 arrow(nat_ty(), arrow(cst("GWPotential"), prop()))
473}
474pub fn dilation_equation_ty() -> Expr {
476 arrow(cst("GWPotential"), prop())
477}
478pub fn motivic_cohomology_ty() -> Expr {
481 arrow(cst("Scheme"), arrow(nat_ty(), arrow(nat_ty(), type0())))
482}
483pub fn algebraic_k_theory_ty() -> Expr {
486 arrow(cst("Scheme"), arrow(nat_ty(), type0()))
487}
488pub fn chern_character_k_theory_ty() -> Expr {
491 arrow(cst("KTheoryClass"), cst("ChowRing"))
492}
493pub fn atiyah_hirzebruch_ty() -> Expr {
495 arrow(
496 cst("Scheme"),
497 app2(cst("Eq"), type0(), app(cst("K0Ring"), bvar(0))),
498 )
499}
500pub fn motivic_integration_ty() -> Expr {
503 arrow(cst("Scheme"), real_ty())
504}
505pub fn hilbert_scheme_points_ty() -> Expr {
508 arrow(cst("Scheme"), arrow(nat_ty(), type1()))
509}
510pub fn hilbert_chow_ty() -> Expr {
513 arrow(cst("HilbertSchemeType"), cst("SymmetricProduct"))
514}
515pub fn nakajima_operator_ty() -> Expr {
518 arrow(
519 cst("HilbertSchemeType"),
520 arrow(cst("ChowGroup"), cst("ChowGroup")),
521 )
522}
523pub fn gottsche_formula_ty() -> Expr {
526 arrow(cst("Surface"), arrow(nat_ty(), int_ty()))
527}
528pub fn intersection_multiplicity_ty() -> Expr {
531 arrow(
532 cst("Scheme"),
533 arrow(cst("Scheme"), arrow(cst("Scheme"), nat_ty())),
534 )
535}
536pub fn polynomial_resultant_ty() -> Expr {
539 arrow(
540 cst("Polynomial"),
541 arrow(cst("Polynomial"), cst("Polynomial")),
542 )
543}
544pub fn intersection_multiplicity_formula_ty() -> Expr {
547 arrow(list_ty(cst("Polynomial")), arrow(nat_ty(), prop()))
548}
549pub fn build_intersection_theory_env(env: &mut Environment) {
551 let base_types: &[(&str, Expr)] = &[
552 ("Scheme", type1()),
553 ("VectorBundle", type0()),
554 ("CoherentSheaf", type0()),
555 ("ChowGroup", type0()),
556 ("ChowRing", type0()),
557 ("ChowClass", type0()),
558 ("AlgebraicCycle", type0()),
559 ("Morphism", type0()),
560 ("Subscheme", type0()),
561 ("NormalBundle", type0()),
562 ("ExcessBundle", type0()),
563 ("ObstructionTheory", type0()),
564 ("FormalPowerSeries", type0()),
565 ("ToricVariety", type0()),
566 ("Surface", type0()),
567 ("SmoothProj", type0()),
568 ("Partition", type0()),
569 ("CurveClass", type0()),
570 ("GromovWittenInvariant", type0()),
571 ("QuantumCohomology", type0()),
572 ("DTInvariant", type0()),
573 ("Nat", type0()),
574 ("Int", type0()),
575 ("Real", type0()),
576 ("Bool", type0()),
577 ("Eq", arrow(type0(), arrow(type0(), prop()))),
578 ("And", arrow(prop(), arrow(prop(), prop()))),
579 ("Exists", arrow(type0(), arrow(type0(), prop()))),
580 ("List", arrow(type0(), type0())),
581 (
582 "DirectSum",
583 arrow(
584 cst("VectorBundle"),
585 arrow(cst("VectorBundle"), cst("VectorBundle")),
586 ),
587 ),
588 (
589 "ChowMul",
590 arrow(cst("ChowRing"), arrow(cst("ChowRing"), cst("ChowRing"))),
591 ),
592 ("InverseChow", arrow(cst("ChowRing"), cst("ChowRing"))),
593 ("PushforwardSheaf", cst("CoherentSheaf")),
594 ("TangentBundle", cst("VectorBundle")),
595 ("EulerChar", arrow(cst("CoherentSheaf"), int_ty())),
596 (
597 "DTPartitionFunction",
598 arrow(cst("Scheme"), cst("FormalPowerSeries")),
599 ),
600 (
601 "GWPartitionFunction",
602 arrow(cst("Scheme"), cst("FormalPowerSeries")),
603 ),
604 ("Grassmannian", type0()),
605 ("SchubertClass", type0()),
606 ("Permutation", type0()),
607 ("Polynomial", type0()),
608 ("BlowupScheme", type0()),
609 ("Divisor", type0()),
610 ("BundleMap", type0()),
611 ("BundleSection", type0()),
612 ("ModuliCurvesType", type0()),
613 ("GWPotential", type0()),
614 ("KTheoryClass", type0()),
615 ("K0Ring", arrow(cst("Scheme"), type0())),
616 ("HilbertSchemeType", type0()),
617 ("SymmetricProduct", type0()),
618 ("EulerClass", arrow(cst("VectorBundle"), cst("ChowGroup"))),
619 ];
620 for (name, ty) in base_types {
621 env.add(Declaration::Axiom {
622 name: Name::str(*name),
623 univ_params: vec![],
624 ty: ty.clone(),
625 })
626 .ok();
627 }
628 let type_axioms: &[(&str, fn() -> Expr)] = &[
629 ("chow_group", chow_group_ty),
630 ("chow_ring", chow_ring_ty),
631 ("algebraic_cycle", algebraic_cycle_ty),
632 ("intersection_product", intersection_product_ty),
633 ("pushforward_cycle", pushforward_cycle_ty),
634 ("pullback_cycle", pullback_cycle_ty),
635 ("fundamental_class", fundamental_class_ty),
636 ("bezout_intersection", bezout_intersection_ty),
637 ("chern_class", chern_class_ty),
638 ("total_chern_class", total_chern_class_ty),
639 ("chern_character", chern_character_ty),
640 ("segre_class", segre_class_ty),
641 ("todd_class", todd_class_ty),
642 ("obstruction_theory", obstruction_theory_ty),
643 ("virtual_fundamental_class", virtual_fundamental_class_ty),
644 ("virtual_dimension", virtual_dimension_ty),
645 ("stable_map", stable_map_ty),
646 ("gromov_witten_invariant", gromov_witten_invariant_ty),
647 ("quantum_cohomology", quantum_cohomology_ty),
648 ("quantum_product", quantum_product_ty),
649 ("dt_invariant", dt_invariant_ty),
650 ("schubert_variety", schubert_variety_ty),
651 ("schubert_class", schubert_class_ty),
652 ("pieri_formula", pieri_formula_ty),
653 ("giambelli_formula", giambelli_formula_ty),
654 ("littlewood_richardson", littlewood_richardson_ty),
655 ("grassmannian_chow_ring", grassmannian_chow_ring_ty),
656 ("flag_variety", flag_variety_ty),
657 ("schubert_polynomial", schubert_polynomial_ty),
658 ("blowup", blowup_ty),
659 ("exceptional_divisor", exceptional_divisor_ty),
660 ("blowup_chow_ring_map", blowup_chow_ring_map_ty),
661 ("strict_transform", strict_transform_ty),
662 ("degeneracy_locus", degeneracy_locus_ty),
663 ("euler_class", euler_class_ty),
664 ("moduli_curves", moduli_curves_ty),
665 ("deligne_mumford", deligne_mumford_ty),
666 ("kontsevich_space", kontsevich_space_ty),
667 ("psi_class", psi_class_ty),
668 ("lambda_class", lambda_class_ty),
669 ("motivic_cohomology", motivic_cohomology_ty),
670 ("algebraic_k_theory", algebraic_k_theory_ty),
671 ("chern_character_k_theory", chern_character_k_theory_ty),
672 ("motivic_integration", motivic_integration_ty),
673 ("hilbert_scheme_points", hilbert_scheme_points_ty),
674 ("hilbert_chow", hilbert_chow_ty),
675 ("nakajima_operator", nakajima_operator_ty),
676 ("gottsche_formula", gottsche_formula_ty),
677 ("intersection_multiplicity", intersection_multiplicity_ty),
678 ("polynomial_resultant", polynomial_resultant_ty),
679 ];
680 for (name, mk_ty) in type_axioms {
681 let ty = mk_ty();
682 env.add(Declaration::Axiom {
683 name: Name::str(*name),
684 univ_params: vec![],
685 ty,
686 })
687 .ok();
688 }
689 let theorem_axioms: &[(&str, fn() -> Expr)] = &[
690 ("bezout_theorem", bezout_theorem_ty),
691 (
692 "excess_intersection_formula",
693 excess_intersection_formula_ty,
694 ),
695 ("whitney_sum_formula", whitney_sum_formula_ty),
696 ("splitting_principle", splitting_principle_ty),
697 ("self_intersection_formula", self_intersection_formula_ty),
698 ("segre_chern_relation", segre_chern_relation_ty),
699 ("grothendieck_riemann_roch", grothendieck_riemann_roch_ty),
700 ("hirzebruch_riemann_roch", hirzebruch_riemann_roch_ty),
701 ("wdvv_equation", wdvv_equation_ty),
702 ("degeneration_formula", degeneration_formula_ty),
703 ("quantum_ring_associativity", quantum_ring_associativity_ty),
704 ("dt_gw_correspondence", dt_gw_correspondence_ty),
705 ("thom_porteous_formula", thom_porteous_formula_ty),
706 ("euler_class_zero_locus", euler_class_zero_locus_ty),
707 ("blowup_formula", blowup_formula_ty),
708 ("virasoro_constraints", virasoro_constraints_ty),
709 ("dilation_equation", dilation_equation_ty),
710 ("atiyah_hirzebruch", atiyah_hirzebruch_ty),
711 (
712 "intersection_multiplicity_formula",
713 intersection_multiplicity_formula_ty,
714 ),
715 ];
716 for (name, mk_ty) in theorem_axioms {
717 let ty = mk_ty();
718 env.add(Declaration::Axiom {
719 name: Name::str(*name),
720 univ_params: vec![],
721 ty,
722 })
723 .ok();
724 }
725}
726pub fn bezout_number(degrees: &[u64]) -> u64 {
731 degrees.iter().product()
732}
733pub fn euler_characteristic_from_betti(betti: &[i64]) -> i64 {
735 betti
736 .iter()
737 .enumerate()
738 .map(|(i, &b)| if i % 2 == 0 { b } else { -b })
739 .sum()
740}
741pub fn projective_line_bundle_degree(n: usize, power: u64) -> u64 {
745 if power == n as u64 {
746 1
747 } else if power > n as u64 {
748 0
749 } else {
750 1
751 }
752}
753pub fn intersection_number(c1: &CycleClass, c2: &CycleClass, dim: usize) -> Option<i64> {
756 if c1.codim + c2.codim == dim {
757 Some(c1.multiplicity * c2.multiplicity)
758 } else {
759 None
760 }
761}
762pub fn gw_invariant_pn(n: usize, d: u64, a1: usize, a2: usize, a3: usize) -> i64 {
767 let lhs = a1 + a2 + a3;
768 let rhs = n + (n as i64 - 3) as usize * d as usize;
769 if lhs == rhs && d > 0 {
770 (d as i64).pow((n as u32).saturating_sub(1))
771 } else if d == 0 && lhs == n {
772 1
773 } else {
774 0
775 }
776}
777pub fn dt_partition_function_coeff(euler_char: i64, degree: usize) -> f64 {
781 let mut coeff = vec![0.0f64; degree + 1];
782 coeff[0] = 1.0;
783 for n in 1..=degree {
784 for _k in 1..=n {
785 for j in (n..=degree).rev() {
786 coeff[j] += coeff[j - n];
787 }
788 }
789 }
790 let sign: f64 = if euler_char % 2 == 0 { 1.0 } else { -1.0 };
791 sign * coeff[degree]
792}
793pub fn todd_class_projective_space(n: usize) -> Vec<f64> {
798 let n1 = (n + 1) as f64;
799 let mut td = vec![0.0f64; n + 1];
800 if n + 1 > 0 {
801 td[0] = 1.0;
802 }
803 if n + 1 > 1 {
804 td[1] = n1 / 2.0;
805 }
806 if n + 1 > 2 {
807 td[2] = n1 * (n1 + 1.0) / 12.0;
808 }
809 if n + 1 > 3 {
810 td[3] = n1 * n1 * (n1 + 1.0) / 24.0;
811 }
812 td
813}
814pub fn hrr_projective_space(n: usize, d: i64) -> i64 {
818 if d >= 0 {
819 binomial(n as i64 + d, n as i64)
820 } else {
821 let sign = if n % 2 == 0 { 1 } else { -1 };
822 sign * hrr_projective_space(n, -(n as i64) - 1 - d)
823 }
824}
825pub fn binomial(n: i64, k: i64) -> i64 {
827 if k < 0 || k > n {
828 return 0;
829 }
830 if k == 0 || k == n {
831 return 1;
832 }
833 let k = k.min(n - k) as usize;
834 let mut result = 1i64;
835 for i in 0..k as i64 {
836 result = result * (n - i) / (i + 1);
837 }
838 result
839}
840#[cfg(test)]
841mod tests {
842 use super::*;
843 use oxilean_kernel::Environment;
844 #[test]
845 fn test_bezout_number() {
846 assert_eq!(bezout_number(&[2, 2, 2]), 8);
847 assert_eq!(bezout_number(&[1, 2]), 2);
848 assert_eq!(bezout_number(&[]), 1);
849 }
850 #[test]
851 fn test_vector_bundle_direct_sum() {
852 let e = VectorBundleData::line_bundle(1);
853 let f = VectorBundleData::line_bundle(2);
854 let ef = e.direct_sum(&f);
855 assert_eq!(ef.rank, 2);
856 assert_eq!(ef.chern_numbers[0], 3);
857 assert_eq!(ef.chern_numbers[1], 2);
858 }
859 #[test]
860 fn test_chern_character_line_bundle() {
861 let e = VectorBundleData::line_bundle(3);
862 let ch = e.chern_character_coeffs();
863 assert_eq!(ch.len(), 3);
864 assert_eq!(ch[0], 1.0);
865 assert_eq!(ch[1], 3.0);
866 assert!((ch[2] - 4.5).abs() < 1e-10);
867 }
868 #[test]
869 fn test_cycle_class_operations() {
870 let h = CycleClass::new(1, 1, "H");
871 let h2 = h.scale(2);
872 assert_eq!(h2.multiplicity, 2);
873 assert_eq!(h2.codim, 1);
874 let h3 = CycleClass::new(1, 3, "3H");
875 let sum = h.add(&h3).expect("add should succeed");
876 assert_eq!(sum.multiplicity, 4);
877 let pt = CycleClass::new(2, 1, "pt");
878 assert!(h.add(&pt).is_none());
879 }
880 #[test]
881 fn test_intersection_number() {
882 let h = CycleClass::new(1, 1, "H");
883 let result = intersection_number(&h, &h, 2);
884 assert_eq!(result, Some(1));
885 let pt = CycleClass::new(2, 1, "pt");
886 assert_eq!(intersection_number(&h, &pt, 2), None);
887 }
888 #[test]
889 fn test_hrr_projective_space() {
890 assert_eq!(hrr_projective_space(2, 0), 1);
891 assert_eq!(hrr_projective_space(2, 1), 3);
892 assert_eq!(hrr_projective_space(2, 2), 6);
893 assert_eq!(hrr_projective_space(1, 3), 4);
894 }
895 #[test]
896 fn test_quantum_cohomology_p2() {
897 let qh = QuantumCohomologyP2::new(1.0);
898 let (c1, c_h, c_h2) = qh.quantum_product_h_powers(1, 2);
899 assert!((c1 - 1.0).abs() < 1e-10);
900 assert!((c_h).abs() < 1e-10);
901 assert!((c_h2).abs() < 1e-10);
902 }
903 #[test]
904 fn test_build_intersection_theory_env() {
905 let mut env = Environment::new();
906 build_intersection_theory_env(&mut env);
907 assert!(env.get(&Name::str("chow_group")).is_some());
908 assert!(env.get(&Name::str("chern_class")).is_some());
909 assert!(env.get(&Name::str("bezout_theorem")).is_some());
910 assert!(env.get(&Name::str("grothendieck_riemann_roch")).is_some());
911 assert!(env.get(&Name::str("wdvv_equation")).is_some());
912 assert!(env.get(&Name::str("dt_gw_correspondence")).is_some());
913 assert!(env.get(&Name::str("quantum_product")).is_some());
914 assert!(env.get(&Name::str("schubert_class")).is_some());
915 assert!(env.get(&Name::str("pieri_formula")).is_some());
916 assert!(env.get(&Name::str("giambelli_formula")).is_some());
917 assert!(env.get(&Name::str("littlewood_richardson")).is_some());
918 assert!(env.get(&Name::str("grassmannian_chow_ring")).is_some());
919 assert!(env.get(&Name::str("flag_variety")).is_some());
920 assert!(env.get(&Name::str("schubert_polynomial")).is_some());
921 assert!(env.get(&Name::str("blowup")).is_some());
922 assert!(env.get(&Name::str("exceptional_divisor")).is_some());
923 assert!(env.get(&Name::str("strict_transform")).is_some());
924 assert!(env.get(&Name::str("blowup_formula")).is_some());
925 assert!(env.get(&Name::str("degeneracy_locus")).is_some());
926 assert!(env.get(&Name::str("thom_porteous_formula")).is_some());
927 assert!(env.get(&Name::str("euler_class")).is_some());
928 assert!(env.get(&Name::str("deligne_mumford")).is_some());
929 assert!(env.get(&Name::str("kontsevich_space")).is_some());
930 assert!(env.get(&Name::str("psi_class")).is_some());
931 assert!(env.get(&Name::str("lambda_class")).is_some());
932 assert!(env.get(&Name::str("virasoro_constraints")).is_some());
933 assert!(env.get(&Name::str("motivic_cohomology")).is_some());
934 assert!(env.get(&Name::str("algebraic_k_theory")).is_some());
935 assert!(env.get(&Name::str("atiyah_hirzebruch")).is_some());
936 assert!(env.get(&Name::str("hilbert_scheme_points")).is_some());
937 assert!(env.get(&Name::str("nakajima_operator")).is_some());
938 assert!(env.get(&Name::str("gottsche_formula")).is_some());
939 assert!(env.get(&Name::str("intersection_multiplicity")).is_some());
940 assert!(env.get(&Name::str("polynomial_resultant")).is_some());
941 }
942 #[test]
943 fn test_todd_class_projective_space() {
944 let td = todd_class_projective_space(2);
945 assert!((td[0] - 1.0).abs() < 1e-10);
946 assert!((td[1] - 1.5).abs() < 1e-10);
947 }
948 #[test]
949 fn test_chow_ring_elem_arithmetic() {
950 let h = ChowRingElem::hyperplane(2);
951 let h2 = h.mul(&h).expect("mul should succeed");
952 assert_eq!(h2.coeffs, vec![0, 0, 1]);
953 let h3 = h2.mul(&h).expect("mul should succeed");
954 assert_eq!(h3.degree(), 0);
955 let one = ChowRingElem::one(2);
956 let one_plus_h = one.add(&h).expect("add should succeed");
957 assert_eq!(one_plus_h.coeffs[0], 1);
958 assert_eq!(one_plus_h.coeffs[1], 1);
959 }
960 #[test]
961 fn test_intersection_matrix() {
962 let mat = IntersectionMatrix::new(vec![vec![-1]]);
963 assert_eq!(mat.self_intersections(), vec![-1]);
964 assert_eq!(mat.determinant(), Some(-1));
965 let mat2 = IntersectionMatrix::new(vec![vec![-2, 1], vec![1, -2]]);
966 assert_eq!(mat2.determinant(), Some(3));
967 assert!(mat2.is_negative_definite());
968 }
969 #[test]
970 fn test_schubert_calc_grassmannian() {
971 let calc = SchubertCalc::new(2, 4);
972 assert_eq!(calc.dim(), 4);
973 assert!(calc.is_valid_partition(&[2, 1]));
974 assert!(calc.is_valid_partition(&[1]));
975 assert!(!calc.is_valid_partition(&[3]));
976 assert_eq!(calc.degree(), 2);
977 }
978 #[test]
979 fn test_bezout_bound() {
980 let b = BezoutBound::new(vec![2, 3, 4]);
981 assert_eq!(b.bound(), 24);
982 assert_eq!(b.mixed_bound(&[0, 1]), 6);
983 assert!(b.is_overdetermined(2));
984 assert!(!b.is_overdetermined(3));
985 assert!(b.is_underdetermined(4));
986 }
987 #[test]
988 fn test_vector_bundle_euler_and_todd() {
989 let e = VectorBundleData::line_bundle(3);
990 assert_eq!(e.euler_class(), 3);
991 let td = e.todd_class_coeffs();
992 assert!((td[0] - 1.0).abs() < 1e-10);
993 assert!((td[1] - 1.5).abs() < 1e-10);
994 }
995}
996pub fn it_ext_chow_group_hom_ty() -> Expr {
999 arrow(cst("ChowGroup"), arrow(cst("ChowGroup"), prop()))
1000}
1001pub fn it_ext_chow_ring_iso_ty() -> Expr {
1004 arrow(cst("ChowRing"), arrow(cst("ChowRing"), prop()))
1005}
1006pub fn it_ext_cycle_map_ty() -> Expr {
1009 arrow(
1010 cst("Scheme"),
1011 arrow(cst("MotivicCohomology"), cst("ChowGroup")),
1012 )
1013}
1014pub fn it_ext_rational_equiv_class_ty() -> Expr {
1017 arrow(cst("AlgebraicCycle"), cst("ChowGroup"))
1018}
1019pub fn it_ext_numerical_equivalence_ty() -> Expr {
1022 arrow(cst("AlgebraicCycle"), arrow(cst("AlgebraicCycle"), prop()))
1023}
1024pub fn it_ext_homological_equivalence_ty() -> Expr {
1027 arrow(cst("AlgebraicCycle"), arrow(cst("AlgebraicCycle"), prop()))
1028}
1029pub fn it_ext_proper_pushforward_ty() -> Expr {
1032 arrow(cst("Morphism"), arrow(cst("ChowGroup"), cst("ChowGroup")))
1033}
1034pub fn it_ext_flat_pullback_ty() -> Expr {
1037 arrow(cst("Morphism"), arrow(cst("ChowGroup"), cst("ChowGroup")))
1038}
1039pub fn it_ext_lci_pullback_ty() -> Expr {
1042 arrow(cst("Morphism"), arrow(cst("ChowGroup"), cst("ChowGroup")))
1043}
1044pub fn it_ext_projection_formula_ty() -> Expr {
1046 arrow(
1047 cst("Morphism"),
1048 arrow(
1049 cst("ChowGroup"),
1050 arrow(
1051 cst("ChowGroup"),
1052 app2(cst("Eq"), cst("ChowGroup"), cst("ChowGroup")),
1053 ),
1054 ),
1055 )
1056}
1057pub fn it_ext_degree_of_map_ty() -> Expr {
1060 arrow(cst("Morphism"), nat_ty())
1061}
1062pub fn it_ext_chern_class_funct_ty() -> Expr {
1064 arrow(
1065 cst("Morphism"),
1066 arrow(
1067 cst("VectorBundle"),
1068 app2(cst("Eq"), cst("ChowGroup"), cst("ChowGroup")),
1069 ),
1070 )
1071}
1072pub fn it_ext_chern_root_decomp_ty() -> Expr {
1075 arrow(cst("VectorBundle"), arrow(nat_ty(), cst("ChowGroup")))
1076}
1077pub fn it_ext_grothendieck_group_ty() -> Expr {
1080 arrow(cst("Scheme"), type0())
1081}
1082pub fn it_ext_adams_operation_ty() -> Expr {
1085 arrow(cst("KTheoryClass"), arrow(nat_ty(), cst("KTheoryClass")))
1086}
1087pub fn it_ext_riemann_roch_transform_ty() -> Expr {
1090 arrow(
1091 cst("Morphism"),
1092 arrow(
1093 cst("CoherentSheaf"),
1094 app2(cst("Eq"), cst("ChowRing"), cst("ChowRing")),
1095 ),
1096 )
1097}
1098pub fn it_ext_lefschetz_number_ty() -> Expr {
1101 arrow(cst("Morphism"), int_ty())
1102}
1103pub fn it_ext_lefschetz_fpt_ty() -> Expr {
1106 arrow(
1107 cst("Morphism"),
1108 arrow(app2(cst("Eq"), int_ty(), int_ty()), prop()),
1109 )
1110}
1111pub fn it_ext_riemann_hurwitz_ty() -> Expr {
1114 arrow(cst("Morphism"), arrow(nat_ty(), arrow(nat_ty(), prop())))
1115}
1116pub fn it_ext_zeta_function_ty() -> Expr {
1119 arrow(cst("Scheme"), cst("FormalPowerSeries"))
1120}
1121pub fn it_ext_weil_conjectures_ty() -> Expr {
1124 arrow(cst("Scheme"), prop())
1125}
1126pub fn it_ext_kontsevich_formula_ty() -> Expr {
1129 arrow(nat_ty(), nat_ty())
1130}
1131pub fn it_ext_quantum_frobenius_ty() -> Expr {
1133 arrow(cst("QuantumCohomology"), prop())
1134}
1135pub fn it_ext_mirror_symmetry_ty() -> Expr {
1137 arrow(cst("Scheme"), arrow(cst("Scheme"), prop()))
1138}
1139pub fn it_ext_topological_vertex_ty() -> Expr {
1142 arrow(
1143 cst("Partition"),
1144 arrow(cst("Partition"), arrow(cst("Partition"), int_ty())),
1145 )
1146}
1147pub fn it_ext_gw_potential_genus0_ty() -> Expr {
1149 arrow(cst("Scheme"), arrow(list_ty(real_ty()), real_ty()))
1150}
1151pub fn it_ext_string_equation_ty() -> Expr {
1153 arrow(cst("GWPotential"), prop())
1154}
1155pub fn it_ext_perfect_obstruction_ty() -> Expr {
1158 arrow(cst("Scheme"), arrow(cst("Morphism"), type0()))
1159}
1160pub fn it_ext_virtual_normal_bundle_ty() -> Expr {
1163 arrow(cst("ObstructionTheory"), cst("VectorBundle"))
1164}
1165pub fn it_ext_virtual_pushforward_ty() -> Expr {
1168 arrow(cst("ObstructionTheory"), arrow(cst("ChowGroup"), int_ty()))
1169}
1170pub fn it_ext_deformation_invariance_ty() -> Expr {
1172 arrow(cst("ObstructionTheory"), prop())
1173}
1174pub fn it_ext_schur_determinant_ty() -> Expr {
1177 arrow(
1178 cst("Partition"),
1179 arrow(
1180 cst("VectorBundle"),
1181 arrow(cst("VectorBundle"), cst("ChowGroup")),
1182 ),
1183 )
1184}
1185pub fn it_ext_grassmann_bundle_formula_ty() -> Expr {
1187 arrow(
1188 cst("Scheme"),
1189 arrow(cst("VectorBundle"), arrow(nat_ty(), cst("ChowRing"))),
1190 )
1191}
1192pub fn it_ext_projective_bundle_formula_ty() -> Expr {
1195 arrow(cst("Scheme"), arrow(cst("VectorBundle"), cst("ChowRing")))
1196}
1197pub fn it_ext_motivic_spectral_seq_ty() -> Expr {
1199 arrow(cst("Scheme"), arrow(nat_ty(), arrow(nat_ty(), type0())))
1200}
1201pub fn it_ext_bloch_ogus_ty() -> Expr {
1203 arrow(cst("Scheme"), arrow(nat_ty(), type0()))
1204}
1205pub fn it_ext_gersten_resolution_ty() -> Expr {
1207 arrow(cst("Scheme"), type0())
1208}
1209pub fn it_ext_milnor_k_theory_ty() -> Expr {
1212 arrow(cst("Scheme"), arrow(nat_ty(), type0()))
1213}
1214pub fn register_intersection_theory_extended(env: &mut Environment) -> Result<(), String> {
1216 let extra_types: &[(&str, Expr)] = &[("MotivicCohomology", type0()), ("Frobenius", type0())];
1217 for (name, ty) in extra_types {
1218 env.add(Declaration::Axiom {
1219 name: Name::str(*name),
1220 univ_params: vec![],
1221 ty: ty.clone(),
1222 })
1223 .ok();
1224 }
1225 let axioms: &[(&str, fn() -> Expr)] = &[
1226 ("ChowGroupHom", it_ext_chow_group_hom_ty),
1227 ("ChowRingIso", it_ext_chow_ring_iso_ty),
1228 ("CycleMap", it_ext_cycle_map_ty),
1229 ("RationalEquivClass", it_ext_rational_equiv_class_ty),
1230 ("NumericalEquivalence", it_ext_numerical_equivalence_ty),
1231 ("HomologicalEquivalence", it_ext_homological_equivalence_ty),
1232 ("ProperPushforward", it_ext_proper_pushforward_ty),
1233 ("FlatPullback", it_ext_flat_pullback_ty),
1234 ("LciPullback", it_ext_lci_pullback_ty),
1235 ("ProjectionFormula", it_ext_projection_formula_ty),
1236 ("DegreeOfMap", it_ext_degree_of_map_ty),
1237 ("ChernClassFunct", it_ext_chern_class_funct_ty),
1238 ("ChernRootDecomp", it_ext_chern_root_decomp_ty),
1239 ("GrothendieckGroupExt", it_ext_grothendieck_group_ty),
1240 ("AdamsOperation", it_ext_adams_operation_ty),
1241 ("RiemannRochTransform", it_ext_riemann_roch_transform_ty),
1242 ("LefschetzNumber", it_ext_lefschetz_number_ty),
1243 ("LefschetzFpt", it_ext_lefschetz_fpt_ty),
1244 ("RiemannHurwitz", it_ext_riemann_hurwitz_ty),
1245 ("ZetaFunction", it_ext_zeta_function_ty),
1246 ("WeilConjectures", it_ext_weil_conjectures_ty),
1247 ("KontsevichFormula", it_ext_kontsevich_formula_ty),
1248 ("QuantumFrobenius", it_ext_quantum_frobenius_ty),
1249 ("MirrorSymmetry", it_ext_mirror_symmetry_ty),
1250 ("TopologicalVertex", it_ext_topological_vertex_ty),
1251 ("GwPotentialGenus0", it_ext_gw_potential_genus0_ty),
1252 ("StringEquation", it_ext_string_equation_ty),
1253 ("PerfectObstruction", it_ext_perfect_obstruction_ty),
1254 ("VirtualNormalBundle", it_ext_virtual_normal_bundle_ty),
1255 ("VirtualPushforward", it_ext_virtual_pushforward_ty),
1256 ("DeformationInvariance", it_ext_deformation_invariance_ty),
1257 ("SchurDeterminant", it_ext_schur_determinant_ty),
1258 ("GrassmannBundleFormula", it_ext_grassmann_bundle_formula_ty),
1259 (
1260 "ProjectiveBundleFormula",
1261 it_ext_projective_bundle_formula_ty,
1262 ),
1263 ("MotivicSpectralSeq", it_ext_motivic_spectral_seq_ty),
1264 ("BlochOgus", it_ext_bloch_ogus_ty),
1265 ("GerstenResolution", it_ext_gersten_resolution_ty),
1266 ("MilnorKTheory", it_ext_milnor_k_theory_ty),
1267 ];
1268 for (name, mk_ty) in axioms {
1269 let ty = mk_ty();
1270 env.add(Declaration::Axiom {
1271 name: Name::str(*name),
1272 univ_params: vec![],
1273 ty,
1274 })
1275 .ok();
1276 }
1277 Ok(())
1278}
1279pub fn kontsevich_nd(d: usize) -> u64 {
1284 if d == 1 {
1285 return 1;
1286 }
1287 let mut n = vec![0u64; d + 1];
1288 n[1] = 1;
1289 for dd in 2..=d {
1290 let mut sum = 0u64;
1291 for d1 in 1..dd {
1292 let d2 = dd - d1;
1293 let d1u = d1 as u64;
1294 let d2u = d2 as u64;
1295 let top = 3 * dd - 4;
1296 let c1 = binomial_u64(top as i64, (3 * d1 - 2) as i64);
1297 let c2 = if 3 * d1 >= 1 {
1298 binomial_u64(top as i64, (3 * d1 - 1) as i64)
1299 } else {
1300 0
1301 };
1302 let term1 = n[d1]
1303 .saturating_mul(n[d2])
1304 .saturating_mul(d1u * d1u)
1305 .saturating_mul(d2u * d2u)
1306 .saturating_mul(c1);
1307 let term2 = n[d1]
1308 .saturating_mul(n[d2])
1309 .saturating_mul(d1u * d1u * d1u)
1310 .saturating_mul(d2u)
1311 .saturating_mul(c2);
1312 sum = sum.saturating_add(term1).saturating_sub(term2.min(sum));
1313 }
1314 n[dd] = sum;
1315 }
1316 n[d]
1317}
1318pub fn binomial_u64(n: i64, k: i64) -> u64 {
1319 if k < 0 || k > n || n < 0 {
1320 return 0;
1321 }
1322 let k = k.min(n - k) as usize;
1323 let mut result = 1u64;
1324 for i in 0..k as i64 {
1325 result = result.saturating_mul((n - i) as u64) / (i as u64 + 1);
1326 }
1327 result
1328}
1329pub fn whitney_sum_chern(c_e: &[i64], c_f: &[i64]) -> Vec<i64> {
1334 let deg = c_e.len() + c_f.len() - 1;
1335 let mut result = vec![0i64; deg];
1336 for (i, &a) in c_e.iter().enumerate() {
1337 for (j, &b) in c_f.iter().enumerate() {
1338 result[i + j] += a * b;
1339 }
1340 }
1341 result
1342}
1343pub fn segre_class_from_chern(c: &[i64], max_terms: usize) -> Vec<i64> {
1348 let mut s = vec![0i64; max_terms];
1349 if max_terms == 0 {
1350 return s;
1351 }
1352 s[0] = 1;
1353 for k in 1..max_terms {
1354 let mut val = 0i64;
1355 for j in 1..=k {
1356 if j < c.len() {
1357 val += c[j] * s[k - j];
1358 }
1359 }
1360 s[k] = -val;
1361 }
1362 s
1363}
1364pub fn chern_character_from_classes(c: &[i64]) -> Vec<f64> {
1368 let c1 = c.get(1).copied().unwrap_or(0) as f64;
1369 let c2 = c.get(2).copied().unwrap_or(0) as f64;
1370 let c3 = c.get(3).copied().unwrap_or(0) as f64;
1371 let rank = c.first().copied().unwrap_or(1) as f64;
1372 vec![
1373 rank,
1374 c1,
1375 (c1 * c1 - 2.0 * c2) / 2.0,
1376 (c1 * c1 * c1 - 3.0 * c1 * c2 + 3.0 * c3) / 6.0,
1377 ]
1378}
1379pub fn it_binomial(n: i64, k: i64) -> i64 {
1380 if k < 0 || k > n || n < 0 {
1381 return 0;
1382 }
1383 let k = k.min(n - k) as usize;
1384 let mut result = 1i64;
1385 for i in 0..k as i64 {
1386 result = result * (n - i) / (i + 1);
1387 }
1388 result
1389}