Formglue
The content on this page was written by AI under human supervision.
Formglue is the Python code BootLoops puts around FORM, the symbolic-manipulation program by Vermaseren and collaborators, which BootLoops runs as an external binary and does not modify. It reads FORM's output correctly, wraps FORM 5's arbitrary-precision multiple-zeta-value evaluator as a Python function returning a checked decimal string, assigns loop momenta to the diagrams FORM 5 generates, and drives the HyperFORM integration library. A companion module, tornheim, evaluates the same kind of constants and Mordell–Tornheim lattice sums with mpmath alone, so a number from FORM can be compared with one computed a different way.
What it does
FORM does the symbolic work (traces, color algebra, rewriting expressions too large for memory, diagram generation); its own page covers that. Formglue lets a Python program use FORM's results without silent mistakes, and it has five parts. The first, form_io, fixes one pitfall. FORM wraps long output lines in the middle of a token, with a trailing backslash or an indented continuation line, so code that reads the text line by line gets wrong numbers and wrong expressions. read_form_output joins the continuations back into logical lines; the rest of the package reads FORM output through it.
form_oracle evaluates multiple zeta values, the nested sums $\zeta(a_1,\dots,a_k)=\sum_{m_1\gt \cdots\gt m_k\ge1} m_1^{-a_1}\cdots m_k^{-a_k}$, and alternating Euler sums (the same with a sign $(-1)^{m}$ on chosen variables), using the float engine built into FORM 5. For a digit count dps it runs a short FORM program at dps+10 digits, checks that exactly one well-formed number came back, and returns a decimal string with at least dps correct digits. The outer index comes first (mzv((2,1), dps) is $\zeta(3)$), and a negative Euler index puts the sign on that variable (euler((-2,1), dps) is $\zeta(3)/8$). A FORM failure or a missing or unevaluated value raises an exception; divergent index patterns, total weight above 22 and more than 1000 digits are refused. FORM shares no code with mpmath, so the result is an independent numerical value when testing a proposed closed form. Constants only: FORM 5.0.1 has no numerical polylogarithms.
form_route adds what FORM 5's built-in diagram generator (diagrams_) leaves out. The generator gives every internal edge an independent label; an integrand needs a momentum routingan assignment of a momentum to every internal line, built from the external momenta and one free momentum per loop, such that momentum is conserved at every vertex. The module builds each graph, picks a spanning tree, keeps one label per independent cycle as a loop momentum, and solves every other edge exactly. It writes a readable routing table, FORM id statements (one #procedure route<i>() per diagram) to #include into an integrand program, and optionally JSON. Every run verifies conservation at each vertex, the loop count two independent ways, and that each external enters once; a failure stops the run with RouteError and a nonzero exit code. Vacuum diagrams and self-loops are handled.
form_hyper is a bridge to HyperFORM (Kardos, Moch and Schnetz), a FORM 5 library that integrates hyperlogarithmsiterated integrals of dx/(x - a) with fixed letters a; the Feynman-parameter integrals of many massless diagrams stay inside this class times rational functions one Feynman parameter at a time. The module writes a driver program, points FORM at your HyperFORM checkout, runs it, and parses the result into exact rational coefficients times named factors (z3 for $\zeta(3)$, L(a1,...,an,x) for a hyperlogarithm in HyperInt's convention). build_driver covers finite projective integrals; a divergent one needs a hand-written driver passed to run_driver.
tornheim and tornheim_w5 need no FORM. They evaluate depth-two multiple zeta values, the Euler sum $\sum_k H_k/k^s$, and Mordell–Tornheim sums $T(a,b;c)=\sum_{m,n\ge1} m^{-a}n^{-b}(m+n)^{-c}$ with their triple and quadruple versions. From those they assemble the signed lattice sums $W_3$, $W_4$, $W_5$ that torus lattice sums and massless propagator integrals produce. These are sums over three to five nonzero integers adding to zero, weighted by powers of their absolute values and of the total length. The method is exact recursion plus a finite head sum and an asymptotic tail at the current mp.dps. Results carry no error bound; repeat at higher precision to check. A $W_5$ value takes a few seconds at 60 digits.
Examples
Route a generated diagram set (no FORM needed). The package includes the 30 on-shell one-loop $gg\to q\bar q$ diagrams from the FORM page, as FORM 5.0.1's generator printed them. From tools/formglue/:
python3 form_route.py tests/fixtures/gen/enum_onshell_nodes.out --externals p1,p2,q1,q2 --table -
The table gives each edge's label, endpoints, kind (external, tree edge, or loop edge chord) and assigned momentum; the run ends with ROUTED 30 diagrams, all self-checks PASS (L values: [1]) and exit code 0. In the first diagram, for instance, the loop edge k3 keeps its own label and the tree edges come out as -q1-q2 and -q1-q2-k3. Use --form route.h instead to write the #procedure route1() … blocks, or --json route.json for the full structure. In Python the same call is route_file(path, externals=["p1","p2","q1","q2"]).
A multiple zeta value from FORM, checked without FORM. With a float-capable FORM 5 on PATH (or named in FORM5_BIN), the script's help text gives the command-line form; --dps goes before -- when an index is negative:
python3 form_oracle.py --dps 40 euler -- -2,1
The command prints one number in mantissa-exponent form, $\zeta(3)/8$ to at least 40 digits. From Python, the pattern in the package's tests and in Galois is to parse at an explicit precision and compare with tornheim (run with the repository's tools/ directory on the Python path):
import mpmath as mp
from formglue import form_oracle, tornheim
s = form_oracle.mzv((5, 3), 60) # runs FORM; string with at least 60 correct digits
x = form_oracle.to_mpf(s, 60) # parse at an explicit precision
with mp.workdps(85):
ref = tornheim.mzv2(5, 3) # the same zeta(5,3) from an mpmath series
print(mp.nstr(x - ref, 5))
The difference should be below $10^{-60}$. If FORM is missing or exits with an error, mzv raises FormRunError naming the binary it tried, and FormParseError if FORM ran but printed no number; probe_float_support() checks, without raising, whether the FORM on hand can evaluate floats.
Lattice sums without FORM. python3 tornheim.py prints the module's built-in checks: $W_3((1,1,1);1)$ beside $\pi^4/60$, MT3 and conv22 against brute-force sums, $W_4((1,1,1,1);1)$ against $30\zeta_5-12\zeta_2\zeta_3$, and $W_4((2,2,2,2);1)$ repeated at 60, 100 and 150 digits. python3 tornheim_w5.py evaluates $W_5((1,1,1,1,1);1)$ at 30 digits against a stored reference and exits nonzero if they differ by more than $10^{-25}$. In your own code set mp.mp.dps, then call for example tornheim.W3((1,1,1), 1).
Routines
Reading FORM output (form_io.py)
read_form_output(path_or_str)— read a file or string of FORM output with wrapped lines joined.unwrap_form_text(text)— the joining rule alone, for text in memory.
Constants from FORM 5 (form_oracle.py)
zeta(n, dps),mzv(indices, dps),euler(indices, dps)— $\zeta(n)$, a multiple zeta value (outer index first), an alternating Euler sum; each returns a string with at leastdpscorrect digits and acceptsworkdir=to keep FORM's files.to_mpf(s, dps)— parse a returned string into an mpmath number at that precision.probe_float_support(binary=None)—(capable, detail): whether the FORM found can evaluate floats, and its version.FormRunError,FormParseError— FORM failed, or its output was not exactly one well-formed number.python3 form_oracle.py {zeta|mzv|euler} INDICES --dps N— command-line form.
Momentum routing (form_route.py)
python3 form_route.py INPUT [--externals ..] [--loops ..] [--table FILE|-] [--form FILE] [--json FILE] [--quiet]— route every diagram in adiagrams_dump; exit code 2 on failure.--mutate-edge LABELcorrupts one momentum before the checks, only to demonstrate that they can fail.route_file(path, ...),route_text(text, externals=None, loops=None)— the same from Python; returnRoutedDiagramobjects with.routing()and.to_json().routing_table(diagrams),form_block(diagrams),mom_str(v, order=())— the readable table, the FORM#procedureblock, one momentum as text.RouteError— raised by any parse, graph or check failure.
HyperFORM bridge (form_hyper.py)
run_driver(frm_text, ...)— run a HyperFORM program through FORM 5 (ortformwithnthreads); returns{expression: printed body}.run_example(relpath)— run one of HyperFORM's examples, e.g.run_example('zigzags/zigzag3.frm').build_driver(name, integrand, nalpha, ...)— driver text for a finite projective integral over parametersal1..alN, integrand in FORM syntax withnum()/den().hyper_integrate(name, integrand, nalpha, ...)— build, run, return the body ofname.parse_terms(body)— a printed body as (rational coefficient, {factor: power}) pairs.HyperFormError,HyperFormRunError,HyperFormParseError— unsetHYPERFORM_SRC, FORM failure, unreadable output.python3 form_hyper.py— self-test: replays HyperFORM'szigzag3example, requires exactly $6\zeta(3)$, and runs thebasic/productexample; exit code 0 on success, 1 on failure.
Sums without FORM (tornheim.py, tornheim_w5.py)
mzv2(s, t),eulerH(s)— depth-two $\zeta(s,t)$; $\sum_k H_k/k^s$.T2(a, b, c),MT3(a, b, c, d),MT4(a, b, c, d, e)— double, triple and quadruple Mordell–Tornheim sums.conv22(...),conv23(...)— the convolution sums for the sign sectors of $W_4$ and $W_5$ with two positive entries.W3(p, q),W4(p, q),W5(p, q)— signed lattice sums, exponent tuplep, total-length exponentq._clear_caches()— empty the memo tables. Entries are keyed by working precision, so clearing only frees memory.
Used on this site
- Modular graph functions (string theory) —
tornheimsupplied the independent high-precision values of the lattice sums with three and four wound edges against which the exact Laurent polynomials were checked.
Requirements and source
Python 3 with mpmath. form_oracle and form_hyper need FORM 5 built from github.com/form-dev/form with --enable-float, as form on PATH or via FORM5_BIN; distribution FORM 4 lacks float support. form_hyper also needs a HyperFORM clone with HYPERFORM_SRC set to its src/ directory (nothing to compile). The other modules need neither program.
Self-tests, from tools/formglue/: python3 tests/test_form_io.py and python3 tests/test_form_route.py use stored FORM output in tests/fixtures/ and need no FORM. python3 tests/test_form_oracle.py always runs its validation and error-path tests; its three float-engine tests run when a float-capable FORM 5 is present and otherwise skip, saying which FORM was found and what it lacks. python3 form_hyper.py needs FORM 5 and HyperFORM. All three test files also run under pytest; the package's registered self-test entry, from the repository root, is python3 -m pytest tools/formglue -x -q -p no:cacheprovider (or python3 run_selftests.py formglue).
The code is tools/formglue/ in BootLoops' bootloops-dev repository (GitHub organization BootLoops-ai), released under the MIT license. FORM (form-dev project, GPL-3.0; its diagram generator builds on T. Kaneko's GRACE) and HyperFORM (A. Kardos, S. Moch and O. Schnetz, GPL-3.0, a FORM port of the core of E. Panzer's HyperInt) are downloaded from those projects and used unmodified; the FORM page has the references.