Skip to content

Interface for Regina (3-manifold topology and normal surface theory)#40370

Merged
vbraun merged 22 commits intosagemath:developfrom
soehms:add_regina
Sep 7, 2025
Merged

Interface for Regina (3-manifold topology and normal surface theory)#40370
vbraun merged 22 commits intosagemath:developfrom
soehms:add_regina

Conversation

@soehms
Copy link
Copy Markdown
Member

@soehms soehms commented Jul 4, 2025

This PR is intended to resolve the old Trac ticket #17077 (now a GitHub issue). This branch is based on the branch of Trac ticket #31456, which addressed the implementation of the optional SPKG.

In the latter ticket it was noted that the package is not compatible with 32-bit systems and is therefore considered experimental (see #31456 (comment)). According to #31456 (comment), this should now be resolved. However, I haven't verified this yet. Are there still CI runs for this? Is this still a policy?

If this issue turns out to have resisted, I will change the type to experimental.

This PR initiates the integration of Regina via the Sage interface framework. Most of the basics should be included, but given Regina's broad functionality, this PR is still selective focusing on some applications of knot theory. However, future extensions should now be fairly straightforward. Explicitly it starts with the following specific conversions:

  • integers
  • rationals
  • rational univariate polynomials
  • integral uni- and bivariate Laurent polynomials
  • finitely presented groups
  • links (including fundamental group and Homfly polynomial integration and adding link simplification)

📝 Checklist

  • The title is concise and informative.
  • The description explains in detail what this PR is about.
  • I have linked a relevant issue or discussion.
  • I have created tests covering the changes.
  • I have updated the documentation and checked the documentation preview.

⌛ Dependencies

@github-actions
Copy link
Copy Markdown

github-actions bot commented Jul 4, 2025

Documentation preview for this PR (built with commit 4baf0d6; changes) is ready! 🎉
This preview will update shortly after each push to this PR.

@soehms
Copy link
Copy Markdown
Member Author

soehms commented Jul 4, 2025

All relevant CI-tests passed including the ones that have the optional package install (Linux Incremental except the one for Fedora 41 which failed by unrelated reason). For example for Debian bookworm wie have:

025-07-04T12:33:48.9074175Z Running doctests with ID 2025-07-04-12-33-48-1ef19743.
2025-07-04T12:33:48.9075400Z Running with SAGE_LOCAL='/sage/local' and SAGE_VENV='/sage/local/var/lib/sage/venv-python3.12.5'
2025-07-04T12:33:48.9076664Z Using --optional=!sagemath_doc_html,!sagemath_doc_pdf,debian,pip,sage,sage_spkg
2025-07-04T12:33:49.0609317Z Features to be detected: 4ti2,SAGE_SRC,benzene,bliss,buckygen,conway_polynomials,coxeter3,csdp,cvxopt,cvxopt,database_cremona_ellcurve,database_cremona_mini_ellcurve,database_cubic_hecke,database_ellcurves,database_graphs,database_jones_numfield,database_knotinfo,dot2tex,dvipng,ecm,fpylll,fricas,gap_package_atlasrep,gap_package_design,gap_package_grape,gap_package_guava,gap_package_hap,gap_package_polenta,gap_package_polycyclic,gap_package_qpa,gap_package_quagroup,gfan,giac,glucose,graphviz,imagemagick,info,ipython,jmol,jupymake,jupyter_sphinx,kenzo,kissat,latte_int,lrcalc_python,lrslib,mathics,matroid_database,mcqd,meataxe,meson_editable,mpmath,msolve,nauty,networkx,numpy,palp,pandoc,pdf2svg,pdftocairo,pexpect,phitigra,pillow,plantri,polytopes_db,polytopes_db_4d,pplpy,primecountpy,ptyprocess,pycosat,pycryptosat,pynormaliz,pyparsing,python_igraph,regina,requests,rpy2,rubiks,sage.combinat,sage.geometry.polyhedron,sage.graphs,sage.groups,sage.libs.braiding,sage.libs.ecl,sage.libs.flint,sage.libs.gap,sage.libs.giac,sage.libs.homfly,sage.libs.linbox,sage.libs.m4ri,sage.libs.ntl,sage.libs.pari,sage.libs.singular,sage.misc.cython,sage.modular,sage.modules,sage.numerical.mip,sage.plot,sage.rings.complex_double,sage.rings.finite_rings,sage.rings.function_field,sage.rings.number_field,sage.rings.padics,sage.rings.polynomial.pbori,sage.rings.real_double,sage.rings.real_mpfr,sage.sat,sage.schemes,sage.symbolic,sage_numerical_backends_coin,scipy,singular,sirocco,sloane_database,sphinx,symengine_py,sympy,tdlib,threejs,topcom
2025-07-04T12:33:49.0617911Z Doctesting entire Sage library.
2025-07-04T12:33:49.0618156Z Doctesting all documentation sources.
2025-07-04T12:33:49.4500686Z Sorting sources by runtime so that slower doctests are run first....
2025-07-04T12:33:49.6687339Z Doctesting 4708 files using 5 threads.
2025-07-04T12:33:50.7891947Z sage -t --warn-long 5.0 --random-seed=68504888485070477484283094754807837137 src/doc/de/thematische_anleitungen/index.rst
2025-07-04T12:33:50.9076966Z     [0 tests, 0.00s wall]
...
2025-07-04T12:50:22.1074071Z sage -t --warn-long 5.0 --random-seed=68504888485070477484283094754807837137 src/sage/interfaces/regina.py
2025-07-04T12:50:22.2735793Z     [134 tests, 0.36s wall]
...
2025-07-04T13:12:57.1259689Z sage -t --warn-long 5.0 --random-seed=68504888485070477484283094754807837137 src/sage/typeset/unicode_art.py
2025-07-04T13:12:57.3387639Z     [18 tests, 3.92s wall]
2025-07-04T13:12:57.3388697Z ----------------------------------------------------------------------
2025-07-04T13:12:57.3389685Z All tests passed!
2025-07-04T13:12:57.3390175Z ----------------------------------------------------------------------
2025-07-04T13:12:57.3390774Z Total time for all tests: 2346.4 seconds
2025-07-04T13:12:57.3391271Z     cpu time: 7928.8 seconds
2025-07-04T13:12:57.3391710Z     cumulative wall time: 9688.2 seconds
2025-07-04T13:12:57.3399913Z Features detected for doctesting: bliss,conway_polynomials,coxeter3,cvxopt,database_cremona_mini_ellcurve,database_ellcurves,database_graphs,fpylll,gap_package_polycyclic,gfan,info,jupyter_sphinx,lrcalc_python,mcqd,meataxe,mpmath,nauty,networkx,numpy,palp,pexpect,pillow,polytopes_db,pplpy,primecountpy,ptyprocess,pyparsing,regina,sage.combinat,sage.geometry.polyhedron,sage.graphs,sage.groups,sage.libs.braiding,sage.libs.ecl,sage.libs.flint,sage.libs.gap,sage.libs.homfly,sage.libs.linbox,sage.libs.m4ri,sage.libs.ntl,sage.libs.pari,sage.libs.singular,sage.misc.cython,sage.modular,sage.modules,sage.numerical.mip,sage.plot,sage.rings.complex_double,sage.rings.finite_rings,sage.rings.function_field,sage.rings.number_field,sage.rings.padics,sage.rings.polynomial.pbori,sage.rings.real_double,sage.rings.real_mpfr,sage.schemes,sage.symbolic,scipy,singular,sirocco,sphinx,sympy,tdlib,threejs

Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com>
@soehms
Copy link
Copy Markdown
Member Author

soehms commented Jul 7, 2025

@tscrim thanks for reviewing! I will do your other points later on.

@tscrim
Copy link
Copy Markdown
Collaborator

tscrim commented Jul 7, 2025

Okay, just let me know when you're ready for me to have another look.

@soehms
Copy link
Copy Markdown
Member Author

soehms commented Jul 8, 2025

Okay, just let me know when you're ready for me to have another look.

I've now made the changes according to your suggestions. For the Feature class, I've enhanced the implementation by linking the module feature with the PythonModule of the Regina package. This allows a FeatureNotPresentError to be raised instead of an ImportError (or ModuleNotFoundError) when attempting to use the interface even though the optional package isn't installed. I think the Mathics interface should be adapted accordingly.

@soehms
Copy link
Copy Markdown
Member Author

soehms commented Jul 11, 2025

@tscrim did you see my #40370 (comment) from July 8th?

@tscrim
Copy link
Copy Markdown
Collaborator

tscrim commented Jul 14, 2025

Sorry, it's been busy with organizing FPSAC this year.

One thing I should have remembered earlier is you need to add/update the meson files. It's something we're now forced to do when adding new files (something to do with the building Sage).

I will try to take another look soon.

@soehms
Copy link
Copy Markdown
Member Author

soehms commented Jul 14, 2025

Sorry, it's been busy with organizing FPSAC this year.

No problem!

One thing I should have remembered earlier is you need to add/update the meson files. It's something we're now forced to do when adding new files (something to do with the building Sage).

I try to do so in the current commit,

I will try to take another look soon.

Thanks!

@tscrim
Copy link
Copy Markdown
Collaborator

tscrim commented Aug 19, 2025

Just let me know when you've had time to consider the above suggestions.

@soehms
Copy link
Copy Markdown
Member Author

soehms commented Aug 19, 2025

Just let me know when you've had time to consider the above suggestions.

I already did that in July. Did I miss something?

Copy link
Copy Markdown
Collaborator

@tscrim tscrim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, sorry, I thought I had submitted my latest comments as GH was showing them for me.

@@ -2966,7 +3031,7 @@ def _isolated_components(self):
for j in G.connected_components(sort=False)]

@cached_method
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
@cached_method
@cached_method(key=lambda s,v1,v2,n,a: (s,v1,v2,n))

We should ignore the algorithm when doing the caching. (I think this is the correct syntax; sorry if I am misremembering.)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should ignore the algorithm when doing the caching. (I think this is the correct syntax; sorry if I am misremembering.)

I'm not sure about that! For example, if you want to compare two algorithms, say

sage: all(K.homfly_polynomial() == K.homfly_polynomial(algorithm=regina.ALG_DEFAULT) for K in sample_list)

you will always get True, even if sample_list contains links where the algorithms don't match.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible to clear the cache, but the only reason to compare the algorithms would be for testing. Unless there is a convention difference?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible to clear the cache, but the only reason to compare the algorithms would be for testing. Unless there is a convention difference?

No there isn't. However, if there is a bug in the implementation of one of the algorithms (only appearing for specific knots, such as we had with the plot method, see #37587 (comment)), this can cause considerable confusion. Another example of confusion can arise when a user tries to figure out which of the algorithms is faster (especially if he doesn't know anything about cached_method).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If someone is trying to test something between the algorithms, then they will see in the doctest how to clear the cache and do the comparison. Granted, in most cases, this won't matter because a user won't pass the algorithm, but the most likely scenario to me is a user passes the algorithm, then runs it again with the default (i.e., not passing the arg) that is different. However, the user simply wanted the result again and shouldn't need to wait for it to redo the computation (in a different way).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've now implemented your suggestion. Unfortunately, this resulted in a doctest failure in get_knotinfo:

sebastian@ThinkPadKlein:~/devel/sage$ sage -tp --optional=sage,regina src/sage/knots/link.py
Running doctests with ID 2025-08-21-18-31-37-5591f73b.
Git branch: add_regina
Git ref: 10.8.beta0-20-g151cc74569f-dirty
Running with SAGE_LOCAL='/home/sebastian/devel/sage/local' and SAGE_VENV='/home/sebastian/devel/sage/local/var/lib/sage/venv-python3.12.5'
Using --optional=regina,sage
...
Doctesting 1 file using 4 threads.
sage -t --warn-long 5.0 --random-seed=251566221754781793842429710826575491863 src/sage/knots/link.py
**********************************************************************
File "src/sage/knots/link.py", line 4315, in sage.knots.link.Link.get_knotinfo
Failed example:
    k11mr.get_knotinfo()
Expected:
    KnotInfo['K11n_82m']
Got:
    KnotInfo['K11n_82']
**********************************************************************
1 item had failures:
   1 of  56 in sage.knots.link.Link.get_knotinfo
    [662 tests, 1 failure, 16.06s wall]

This happens because cached_method requires a hash for self, which forces the calculation of the braid:

> /home/sebastian/devel/sage/src/sage/knots/link.py(3033)<lambda>()->(Knot represen...y 11 crossings, None, None, 'vz')
-> @cached_method(key=lambda s,v1,v2,n,a: (s,v1,v2,n))
(Pdb)
--Call--
> /home/sebastian/devel/sage/src/sage/knots/link.py(643)__hash__()
-> def __hash__(self):
(Pdb)
> /home/sebastian/devel/sage/src/sage/knots/link.py(653)__hash__()
-> return hash(self.braid())

Now, get_knotinfo compares k11 = KnotInfo.K11n_82.link() with k11s = k11.mirror_image().reverse().mirror_image().reverse() to determine the symmetry type. Before the change, mirror_image and reverse processed the pd_code in each step. Therefore, k11 and k11s were identical. After the change, these methods process the braid in the second step, since the homfly polynomial has since been calculated. Unfortunately, the braid recorded in KnotInfo for KnotInfo.K11n_82 is not conjugate to the braid calculated by Sage. Therefore, get_knotinfo can no longer identify k11 with k11s.

I learned two things from this:

  1. There's a bug in get_knotinfo, because it should have raised an error instead of returning the wrong symmetry type.
  2. Symmetry type detection can be improved by additionally comparing with the braid calculated by Sage.

I think the first point requires a separate PR, which I'll open later. I'll add the second point to the current commit. This fixes the doctest.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So everything for this PR is now done? At least, my understanding is that the change I proposed only uncovered this and did not cause it (or at least it shouldn't). Sorry I'm not quite following the details.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So everything for this PR is now done?

Yes!

At least, my understanding is that the change I proposed only uncovered this and did not cause it (or at least it shouldn't).

Exactly!

FYI: I'm on vacation for the next two weeks, so I won't be responding very often.

Co-authored-by: Travis Scrimshaw <clfrngrown@aol.com>
@soehms
Copy link
Copy Markdown
Member Author

soehms commented Aug 19, 2025

Caution: The current commit introduced build errors (see for example this in this CI-run). I will look at them later on!

@soehms
Copy link
Copy Markdown
Member Author

soehms commented Aug 20, 2025

Caution: The current commit introduced build errors (see for example this in this CI-run). I will look at them later on!

Done in 151cc74.

Copy link
Copy Markdown
Collaborator

@tscrim tscrim left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, thanks. Let's get this in.

PS - Enjoy your vacation.

@soehms
Copy link
Copy Markdown
Member Author

soehms commented Sep 5, 2025

Alright, thanks. Let's get this in.

PS - Enjoy your vacation.

Thanks!

@vbraun vbraun merged commit 9096302 into sagemath:develop Sep 7, 2025
40 of 44 checks passed
@soehms soehms deleted the add_regina branch September 13, 2025 10:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants