use oxilean_kernel::{BinderInfo, Declaration, Environment, Expr, Level, Name};
use super::types::{
DehnSurgery, DehnSurgeryComputer, FourManifold, HeegaardDiagramSimplifier,
HeegaardSplitting2V2, HeegaardSplittingData, IntersectionFormData, KhovanovHomologyComputer,
KirbyDiagramData, KnotConcordanceChecker, KnotDiagram, ReidemeisterMove, Surface, SurfaceType,
SurgerySpec, ThurstonGeometrizationData, ThurstonGeometry, ThurstonGeometryKind,
WRTInvariantComputer,
};
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 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 bool_ty() -> Expr {
cst("Bool")
}
pub fn ring_ty() -> Expr {
cst("Ring")
}
pub fn group_ty() -> Expr {
cst("Group")
}
pub fn manifold_ty() -> Expr {
cst("Manifold")
}
pub fn surface_ty() -> Expr {
cst("Surface")
}
pub fn knot_ty() -> Expr {
cst("Knot")
}
pub fn closed_surface_ty() -> Expr {
type0()
}
pub fn surface_genus_ty() -> Expr {
arrow(surface_ty(), nat_ty())
}
pub fn is_orientable_ty() -> Expr {
arrow(surface_ty(), prop())
}
pub fn euler_characteristic_surface_ty() -> Expr {
arrow(surface_ty(), int_ty())
}
pub fn surface_classification_ty() -> Expr {
pi(BinderInfo::Default, "S", surface_ty(), prop())
}
pub fn connected_sum_surface_ty() -> Expr {
arrow(surface_ty(), arrow(surface_ty(), surface_ty()))
}
pub fn mapping_torus_ty() -> Expr {
arrow(
surface_ty(),
arrow(arrow(surface_ty(), surface_ty()), manifold_ty()),
)
}
pub fn handlebody_genus_ty() -> Expr {
arrow(nat_ty(), manifold_ty())
}
pub fn heegaard_splitting_ty() -> Expr {
arrow(manifold_ty(), arrow(nat_ty(), prop()))
}
pub fn heegaard_genus_ty() -> Expr {
arrow(manifold_ty(), nat_ty())
}
pub fn reidemeister_singer_ty() -> Expr {
pi(BinderInfo::Default, "M", manifold_ty(), prop())
}
pub fn irreducible_3manifold_ty() -> Expr {
arrow(manifold_ty(), prop())
}
pub fn kneser_milnor_ty() -> Expr {
pi(BinderInfo::Default, "M", manifold_ty(), prop())
}
pub fn jsj_decomposition_ty() -> Expr {
arrow(manifold_ty(), type0())
}
pub fn dehn_surgery_ty() -> Expr {
arrow(
manifold_ty(),
arrow(knot_ty(), arrow(nat_ty(), arrow(nat_ty(), manifold_ty()))),
)
}
pub fn surgery_coefficient_ty() -> Expr {
type0()
}
pub fn lickorish_wallace_ty() -> Expr {
pi(BinderInfo::Default, "M", manifold_ty(), prop())
}
pub fn dehn_filling_ty() -> Expr {
arrow(manifold_ty(), manifold_ty())
}
pub fn thurston_dehn_surgery_ty() -> Expr {
pi(BinderInfo::Default, "M", manifold_ty(), prop())
}
pub fn mcg_ty() -> Expr {
arrow(surface_ty(), group_ty())
}
pub fn dehn_twist_ty() -> Expr {
arrow(
surface_ty(),
arrow(knot_ty(), arrow(surface_ty(), group_ty())),
)
}
pub fn nielsen_thurston_ty() -> Expr {
arrow(group_ty(), type0())
}
pub fn pseudo_anosov_ty() -> Expr {
arrow(group_ty(), prop())
}
pub fn dilation_factor_ty() -> Expr {
arrow(group_ty(), nat_ty())
}
pub fn birman_hilden_ty() -> Expr {
pi(BinderInfo::Default, "g", nat_ty(), prop())
}
pub fn torelli_group_ty() -> Expr {
arrow(surface_ty(), group_ty())
}
pub fn thurston_geometry_ty() -> Expr {
type0()
}
pub fn geometric_structure_ty() -> Expr {
arrow(manifold_ty(), arrow(thurston_geometry_ty(), prop()))
}
pub fn geometrization_theorem_ty() -> Expr {
pi(BinderInfo::Default, "M", manifold_ty(), prop())
}
pub fn poincare_conjecture_ty() -> Expr {
pi(BinderInfo::Default, "M", manifold_ty(), prop())
}
pub fn hyperbolic_volume_ty() -> Expr {
arrow(manifold_ty(), nat_ty())
}
pub fn is_hyperbolic_ty() -> Expr {
arrow(manifold_ty(), prop())
}
pub fn mostow_rigidity_ty() -> Expr {
pi(
BinderInfo::Default,
"M",
manifold_ty(),
pi(BinderInfo::Default, "N", manifold_ty(), prop()),
)
}
pub fn wang_finiteness_ty() -> Expr {
pi(BinderInfo::Default, "V", nat_ty(), prop())
}
pub fn cusped_manifold_ty() -> Expr {
arrow(manifold_ty(), arrow(nat_ty(), prop()))
}
pub fn four_manifold_ty() -> Expr {
type0()
}
pub fn intersection_form_ty() -> Expr {
arrow(four_manifold_ty(), type0())
}
pub fn signature_4mfld_ty() -> Expr {
arrow(four_manifold_ty(), int_ty())
}
pub fn second_betti_ty() -> Expr {
arrow(four_manifold_ty(), nat_ty())
}
pub fn even_intersection_form_ty() -> Expr {
arrow(four_manifold_ty(), prop())
}
pub fn donaldson_diagonalisation_ty() -> Expr {
pi(BinderInfo::Default, "M", four_manifold_ty(), prop())
}
pub fn rokhlin_theorem_ty() -> Expr {
pi(BinderInfo::Default, "M", four_manifold_ty(), prop())
}
pub fn spin_manifold_ty() -> Expr {
arrow(four_manifold_ty(), prop())
}
pub fn kirby_diagram_ty() -> Expr {
type0()
}
pub fn kirby_move1_ty() -> Expr {
arrow(kirby_diagram_ty(), arrow(kirby_diagram_ty(), prop()))
}
pub fn kirby_move2_ty() -> Expr {
arrow(kirby_diagram_ty(), arrow(kirby_diagram_ty(), prop()))
}
pub fn kirby_theorem_ty() -> Expr {
pi(
BinderInfo::Default,
"D1",
kirby_diagram_ty(),
pi(BinderInfo::Default, "D2", kirby_diagram_ty(), prop()),
)
}
pub fn framed_link_ty() -> Expr {
type0()
}
pub fn boundary_manifold_ty() -> Expr {
arrow(kirby_diagram_ty(), four_manifold_ty())
}
pub fn spinc_structure_ty() -> Expr {
arrow(four_manifold_ty(), type0())
}
pub fn sw_basic_class_ty() -> Expr {
arrow(four_manifold_ty(), type0())
}
pub fn sw_invariant_ty() -> Expr {
arrow(four_manifold_ty(), arrow(type0(), int_ty()))
}
pub fn taubes_theorem_ty() -> Expr {
pi(BinderInfo::Default, "X", four_manifold_ty(), prop())
}
pub fn donaldson_sw_equivalence_ty() -> Expr {
pi(BinderInfo::Default, "M", four_manifold_ty(), prop())
}
pub fn heegaard_diagram_ty() -> Expr {
type0()
}
pub fn diagram_genus_ty() -> Expr {
arrow(heegaard_diagram_ty(), nat_ty())
}
pub fn heegaard_stabilization_ty() -> Expr {
arrow(heegaard_diagram_ty(), heegaard_diagram_ty())
}
pub fn diagram_reidemeister_move_ty() -> Expr {
arrow(heegaard_diagram_ty(), arrow(heegaard_diagram_ty(), prop()))
}
pub fn surgery_exact_triangle_ty() -> Expr {
arrow(
manifold_ty(),
arrow(manifold_ty(), arrow(manifold_ty(), prop())),
)
}
pub fn surgery_description_ty() -> Expr {
arrow(manifold_ty(), type0())
}
pub fn link_surgery_ty() -> Expr {
arrow(nat_ty(), manifold_ty())
}
pub fn knot_concordance_ty() -> Expr {
arrow(knot_ty(), arrow(knot_ty(), prop()))
}
pub fn concordance_group_ty() -> Expr {
group_ty()
}
pub fn slice_knot_ty() -> Expr {
arrow(knot_ty(), prop())
}
pub fn smooth_slice_knot_ty() -> Expr {
arrow(knot_ty(), prop())
}
pub fn topological_slice_knot_ty() -> Expr {
arrow(knot_ty(), prop())
}
pub fn slice_ribbon_conjecture_ty() -> Expr {
pi(BinderInfo::Default, "K", knot_ty(), prop())
}
pub fn khovanov_homology_ty() -> Expr {
arrow(knot_ty(), arrow(nat_ty(), arrow(int_ty(), type0())))
}
pub fn cube_of_resolutions_ty() -> Expr {
arrow(knot_ty(), type0())
}
pub fn rasmussen_invariant_ty() -> Expr {
arrow(knot_ty(), int_ty())
}
pub fn knot_floer_complex_ty() -> Expr {
arrow(knot_ty(), type0())
}
pub fn tau_invariant_ty() -> Expr {
arrow(knot_ty(), int_ty())
}
pub fn alexander_polynomial_ty() -> Expr {
arrow(knot_ty(), type0())
}
pub fn knot_floer_homology_ty() -> Expr {
arrow(knot_ty(), arrow(int_ty(), arrow(int_ty(), type0())))
}
pub fn hf_hat_ty() -> Expr {
arrow(manifold_ty(), type0())
}
pub fn hf_plus_ty() -> Expr {
arrow(manifold_ty(), type0())
}
pub fn hf_minus_ty() -> Expr {
arrow(manifold_ty(), type0())
}
pub fn hf_infinity_ty() -> Expr {
arrow(manifold_ty(), type0())
}
pub fn hf_exact_triangle_ty() -> Expr {
arrow(
manifold_ty(),
arrow(manifold_ty(), arrow(manifold_ty(), prop())),
)
}
pub fn freedman_classification_ty() -> Expr {
pi(BinderInfo::Default, "M", four_manifold_ty(), prop())
}
pub fn donaldson_polynomial_ty() -> Expr {
arrow(four_manifold_ty(), arrow(int_ty(), int_ty()))
}
pub fn exotic_r4_ty() -> Expr {
type0()
}
pub fn hyperbolic_structure_ty() -> Expr {
arrow(manifold_ty(), prop())
}
pub fn thurston_geometrization_full_ty() -> Expr {
pi(BinderInfo::Default, "M", manifold_ty(), prop())
}
pub fn vol_conj_ty() -> Expr {
pi(BinderInfo::Default, "K", knot_ty(), prop())
}
pub fn mcg_presentation_ty() -> Expr {
arrow(surface_ty(), type0())
}
pub fn dehn_twist_relation_ty() -> Expr {
arrow(surface_ty(), arrow(knot_ty(), arrow(knot_ty(), prop())))
}
pub fn nielsen_thurston_extended_ty() -> Expr {
arrow(group_ty(), arrow(nat_ty(), prop()))
}
pub fn ribbon_surface_ty() -> Expr {
arrow(knot_ty(), type0())
}
pub fn ribbon_singularity_ty() -> Expr {
type0()
}
pub fn reshetikhin_turaev_ty() -> Expr {
arrow(manifold_ty(), arrow(nat_ty(), int_ty()))
}
pub fn wrt_invariant_ty() -> Expr {
arrow(manifold_ty(), arrow(nat_ty(), int_ty()))
}
pub fn tqft_functor_ty() -> Expr {
type0()
}
pub fn virtual_knot_ty() -> Expr {
type0()
}
pub fn virtual_crossing_ty() -> Expr {
type0()
}
pub fn gauss_diagram_ty() -> Expr {
arrow(virtual_knot_ty(), type0())
}
pub fn kauffman_virtual_ty() -> Expr {
arrow(virtual_knot_ty(), type0())
}
pub fn build_low_dimensional_topology_env(env: &mut Environment) {
let axioms: &[(&str, Expr)] = &[
("Manifold", type0()),
("Surface", type0()),
("Knot", type0()),
("Ring", type0()),
("Group", type0()),
("ClosedSurface", closed_surface_ty()),
("SurfaceGenus", surface_genus_ty()),
("IsOrientable", is_orientable_ty()),
(
"EulerCharacteristicSurface",
euler_characteristic_surface_ty(),
),
("SurfaceClassification", surface_classification_ty()),
("ConnectedSumSurface", connected_sum_surface_ty()),
("MappingTorus", mapping_torus_ty()),
("HandlebodyGenus", handlebody_genus_ty()),
("HeegaardSplitting", heegaard_splitting_ty()),
("HeegaardGenus", heegaard_genus_ty()),
("ReidemeisterSinger", reidemeister_singer_ty()),
("Irreducible3Manifold", irreducible_3manifold_ty()),
("KneserMilnor", kneser_milnor_ty()),
("JSJDecomposition", jsj_decomposition_ty()),
("DehnSurgery", dehn_surgery_ty()),
("SurgeryCoefficient", surgery_coefficient_ty()),
("LickorishWallace", lickorish_wallace_ty()),
("DehnFilling", dehn_filling_ty()),
("ThurstonDehnSurgery", thurston_dehn_surgery_ty()),
("MCG", mcg_ty()),
("DehnTwist", dehn_twist_ty()),
("NielsenThurston", nielsen_thurston_ty()),
("PseudoAnosov", pseudo_anosov_ty()),
("DilationFactor", dilation_factor_ty()),
("BirmanHilden", birman_hilden_ty()),
("TorelliGroup", torelli_group_ty()),
("ThurstonGeometry", thurston_geometry_ty()),
("GeometricStructure", geometric_structure_ty()),
("GeometrizationTheorem", geometrization_theorem_ty()),
("PoincareConjecture", poincare_conjecture_ty()),
("HyperbolicVolume", hyperbolic_volume_ty()),
("IsHyperbolic", is_hyperbolic_ty()),
("MostowRigidity", mostow_rigidity_ty()),
("WangFiniteness", wang_finiteness_ty()),
("CuspedManifold", cusped_manifold_ty()),
("FourManifold", four_manifold_ty()),
("IntersectionForm", intersection_form_ty()),
("Signature4Mfld", signature_4mfld_ty()),
("SecondBetti", second_betti_ty()),
("EvenIntersectionForm", even_intersection_form_ty()),
("DonaldsonDiagonalisation", donaldson_diagonalisation_ty()),
("RokhlinTheorem", rokhlin_theorem_ty()),
("SpinManifold", spin_manifold_ty()),
("KirbyDiagram", kirby_diagram_ty()),
("KirbyMove1", kirby_move1_ty()),
("KirbyMove2", kirby_move2_ty()),
("KirbyTheorem", kirby_theorem_ty()),
("FramedLink", framed_link_ty()),
("BoundaryManifold", boundary_manifold_ty()),
("SpinCStructure", spinc_structure_ty()),
("SWBasicClass", sw_basic_class_ty()),
("SeibergWittenInvariant", sw_invariant_ty()),
("TaubesTheorem", taubes_theorem_ty()),
("DonaldsonSWEquivalence", donaldson_sw_equivalence_ty()),
("HeegaardDiagram", heegaard_diagram_ty()),
("DiagramGenus", diagram_genus_ty()),
("HeegaardStabilization", heegaard_stabilization_ty()),
("DiagramReidemeisterMove", diagram_reidemeister_move_ty()),
("SurgeryExactTriangle", surgery_exact_triangle_ty()),
("SurgeryDescription", surgery_description_ty()),
("LinkSurgery", link_surgery_ty()),
("KnotConcordance", knot_concordance_ty()),
("ConcordanceGroup", concordance_group_ty()),
("SliceKnot", slice_knot_ty()),
("SmoothSliceKnot", smooth_slice_knot_ty()),
("TopologicalSliceKnot", topological_slice_knot_ty()),
("SliceRibbonConjecture", slice_ribbon_conjecture_ty()),
("KhovanovHomology", khovanov_homology_ty()),
("CubeOfResolutions", cube_of_resolutions_ty()),
("RasmussenInvariant", rasmussen_invariant_ty()),
("KnotFloerComplex", knot_floer_complex_ty()),
("TauInvariant", tau_invariant_ty()),
("AlexanderPolynomial", alexander_polynomial_ty()),
("KnotFloerHomology", knot_floer_homology_ty()),
("HFHat", hf_hat_ty()),
("HFPlus", hf_plus_ty()),
("HFMinus", hf_minus_ty()),
("HFInfinity", hf_infinity_ty()),
("HFExactTriangle", hf_exact_triangle_ty()),
("FreedmanClassification", freedman_classification_ty()),
("DonaldsonPolynomial", donaldson_polynomial_ty()),
("ExoticR4", exotic_r4_ty()),
("HyperbolicStructure", hyperbolic_structure_ty()),
(
"ThurstonGeometrizationFull",
thurston_geometrization_full_ty(),
),
("VolConj", vol_conj_ty()),
("MappingClassGroupPresentation", mcg_presentation_ty()),
("DehnTwistRelation", dehn_twist_relation_ty()),
("NielsenThurstonExtended", nielsen_thurston_extended_ty()),
("RibbonSurface", ribbon_surface_ty()),
("RibbonSingularity", ribbon_singularity_ty()),
("ReshetikhinTuraevInvariant", reshetikhin_turaev_ty()),
("WRTInvariant", wrt_invariant_ty()),
("TQFTFunctor", tqft_functor_ty()),
("VirtualKnot", virtual_knot_ty()),
("VirtualCrossing", virtual_crossing_ty()),
("GaussDiagram", gauss_diagram_ty()),
("KauffmanVirtualPolynomial", kauffman_virtual_ty()),
];
for (name, ty) in axioms {
env.add(Declaration::Axiom {
name: Name::str(*name),
univ_params: vec![],
ty: ty.clone(),
})
.ok();
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_build_env_nonempty() {
let mut env = Environment::new();
build_low_dimensional_topology_env(&mut env);
assert!(env.get(&Name::str("Manifold")).is_some());
assert!(env.get(&Name::str("HeegaardSplitting")).is_some());
assert!(env.get(&Name::str("GeometrizationTheorem")).is_some());
assert!(env.get(&Name::str("KirbyTheorem")).is_some());
assert!(env.get(&Name::str("DonaldsonDiagonalisation")).is_some());
}
#[test]
fn test_surface_euler_characteristic() {
assert_eq!(SurfaceType::Sphere.euler_characteristic(), 2);
assert_eq!(SurfaceType::OrientableSurface(1).euler_characteristic(), 0);
assert_eq!(SurfaceType::OrientableSurface(2).euler_characteristic(), -2);
assert_eq!(
SurfaceType::NonOrientableSurface(1).euler_characteristic(),
1
);
assert_eq!(
SurfaceType::NonOrientableSurface(2).euler_characteristic(),
0
);
}
#[test]
fn test_surface_connected_sum() {
let t2 = SurfaceType::OrientableSurface(1);
let t2b = SurfaceType::OrientableSurface(1);
let s2g2 = t2.connected_sum(&t2b);
assert_eq!(s2g2, SurfaceType::OrientableSurface(2));
let sphere = SurfaceType::Sphere;
assert_eq!(sphere.connected_sum(&t2), SurfaceType::OrientableSurface(1));
}
#[test]
fn test_thurston_geometry_names() {
let geoms = [
ThurstonGeometryKind::Spherical,
ThurstonGeometryKind::Euclidean,
ThurstonGeometryKind::Hyperbolic,
ThurstonGeometryKind::S2xR,
ThurstonGeometryKind::H2xR,
ThurstonGeometryKind::SL2R,
ThurstonGeometryKind::Nil,
ThurstonGeometryKind::Sol,
];
assert_eq!(geoms.len(), 8);
assert!(ThurstonGeometryKind::Hyperbolic.is_constant_curvature());
assert!(!ThurstonGeometryKind::Nil.is_constant_curvature());
}
#[test]
fn test_intersection_form_e8() {
let e8 = IntersectionFormData::e8();
assert_eq!(e8.rank, 8);
assert!(e8.is_even());
assert_eq!(e8.matrix[0][0], 2);
}
#[test]
fn test_intersection_form_hyperbolic() {
let h = IntersectionFormData::hyperbolic();
assert_eq!(h.rank, 2);
assert!(h.is_even());
assert_eq!(h.signature_diagonal(), 0);
assert!(!h.is_definite());
}
#[test]
fn test_kirby_diagram_cp2() {
let d = KirbyDiagramData::cp2();
assert_eq!(d.components.len(), 1);
assert_eq!(d.components[0].framing, 1);
let m = d.intersection_matrix();
assert_eq!(m[0][0], 1);
}
#[test]
fn test_heegaard_genus_lens_space() {
let ls = HeegaardSplittingData::lens_space(5, 2);
assert_eq!(ls.genus, 1);
assert!(ls.strongly_irreducible);
}
#[test]
fn test_surgery_spec_label() {
let s = SurgerySpec::integer("trefoil", 1);
let label = s.label();
assert!(label.contains("trefoil"));
assert!(label.contains("1/1"));
}
}
#[cfg(test)]
mod new_impl_tests {
use super::*;
#[test]
fn test_heegaard_diagram_stabilize() {
let d = HeegaardDiagramSimplifier::new(2);
assert_eq!(d.genus, 2);
let d2 = d.stabilize();
assert_eq!(d2.genus, 3);
assert!(d2.stabilized);
let d3 = d2.destabilize().expect("destabilize should succeed");
assert_eq!(d3.genus, 2);
}
#[test]
fn test_heegaard_diagram_destabilize_genus_zero() {
let d = HeegaardDiagramSimplifier::new(0);
assert!(d.destabilize().is_none());
}
#[test]
fn test_khovanov_cube_dimension() {
let kc = KhovanovHomologyComputer::new(3, -3);
assert_eq!(kc.cube_dimension(), 8);
assert_eq!(KhovanovHomologyComputer::unknot_rank(), 2);
let ranks = KhovanovHomologyComputer::trefoil_ranks();
assert!(!ranks.is_empty());
}
#[test]
fn test_dehn_surgery_computer() {
let s = DehnSurgeryComputer::integer_surgery("unknot", 5);
let name = s.result_manifold_name();
assert!(name.contains("lens"));
assert_eq!(s.slope_label(), "5");
assert_eq!(s.first_homology(), "Z/5");
}
#[test]
fn test_knot_concordance_checker() {
let checker = KnotConcordanceChecker::new("3_1", -1, -2, -2);
assert!(!checker.is_potentially_slice());
assert!(checker.four_ball_genus_lower_bound() >= 1);
let unknot = KnotConcordanceChecker::new("unknot", 0, 0, 0);
assert!(unknot.is_potentially_slice());
}
#[test]
fn test_wrt_invariant_computer() {
let wrt = WRTInvariantComputer::new("S^3", 5);
assert_eq!(wrt.modular_category_rank(), 4);
let desc = wrt.wrt_invariant_description();
assert!(desc.contains("WRT_5"));
let poincare = WRTInvariantComputer::new("Poincare", 5);
assert!(poincare.poincare_sphere_note().is_some());
}
#[test]
fn test_build_env_new_axioms() {
let mut env = Environment::new();
build_low_dimensional_topology_env(&mut env);
assert!(env.get(&Name::str("HeegaardDiagram")).is_some());
assert!(env.get(&Name::str("KhovanovHomology")).is_some());
assert!(env.get(&Name::str("TauInvariant")).is_some());
assert!(env.get(&Name::str("HFHat")).is_some());
assert!(env.get(&Name::str("WRTInvariant")).is_some());
assert!(env.get(&Name::str("VirtualKnot")).is_some());
assert!(env.get(&Name::str("RasmussenInvariant")).is_some());
assert!(env.get(&Name::str("SliceKnot")).is_some());
assert!(env.get(&Name::str("FreedmanClassification")).is_some());
}
}
pub fn build_env(env: &mut Environment) {
build_low_dimensional_topology_env(env);
}
#[cfg(test)]
mod tests_low_dim_topo_ext {
use super::*;
#[test]
fn test_thurston_geometrization() {
let mut tg = ThurstonGeometrizationData::new("M");
tg.add_piece(ThurstonGeometry::Hyperbolic, "M is hyperbolic");
assert!(tg.is_hyperbolic);
assert!(tg.hyperbolic_volume_lower_bound() > 2.0);
assert!(tg.perelman_theorem().contains("Perelman"));
}
#[test]
fn test_heegaard_splitting() {
let hs = HeegaardSplitting2V2::new("S^3", 0);
assert!(hs.waldhausen_s3());
assert!(hs.genus1_classification().is_none());
let lens = HeegaardSplitting2V2::new("L(p,q)", 1).strongly_irreducible();
assert!(lens.strongly_irreducible);
assert!(lens.genus1_classification().is_some());
}
#[test]
fn test_dehn_surgery() {
let ds = DehnSurgery::new("trefoil", 1, 0, "S^3");
assert!(ds.coefficient().is_infinite());
let ds2 = DehnSurgery::new("trefoil", 5, 1, "lens space");
assert!((ds2.coefficient() - 5.0).abs() < 1e-10);
assert!(ds2.is_integral());
assert!(ds2.lickorish_wallace().contains("Lickorish"));
}
}
#[cfg(test)]
mod tests_low_dim_topo_ext2 {
use super::*;
#[test]
fn test_reidemeister_moves() {
let r1 = ReidemeisterMove::R1;
assert!(r1.preserves_knot_type());
assert!(!r1.preserves_writhe());
let r2 = ReidemeisterMove::R2;
assert!(r2.preserves_writhe());
let r3 = ReidemeisterMove::R3;
assert!(r3.description().contains("triangle"));
}
#[test]
fn test_knot_diagram() {
let tr = KnotDiagram::trefoil_right();
assert_eq!(tr.crossing_number, 3);
assert_eq!(tr.writhe, 3);
assert!(tr.is_alternating);
assert!((tr.jones_at_one() - 1.0).abs() < 1e-10);
let fig8 = KnotDiagram::figure_eight();
assert_eq!(fig8.writhe, 0);
assert!((fig8.kauffman_bracket_approx() - 1.0).abs() < 1e-10);
}
}