fredrikj.net / blog /
FLINT development in the age of AI
May 14, 2026
Well, 2026 seems to be the year when "AI" actually became useful, and I guess I'm in good company saying so. Here I'll report about my recent experience using AI (mainly Claude Pro) for FLINT development.
Contents
Explaining FLINT code
A very conservative application of AI is to just explain existing code. This ability should be especially useful for new users and developers, but it's probably also going to be helpful for me as a maintainer as FLINT contains a fair amount of code outside of my own areas of expertise written by people who are long gone from the project.
I've tried to generate explanations for dozens of FLINT functions with different AIs, and despite occasional errors, the results are generally becoming good. To give a random example, here is Claude's explanation of the function qqbar_sgn_re, which I asked it to generate from the code without giving any other hints:
Overview
qqbar_sgn_re computes the sign of the real part of an algebraic number $x$, returning $-1$, $0$, or $+1$. In FLINT, a qqbar_t represents an element of $\overline{\mathbb{Q}}$ — an exact algebraic number — stored as two things together: the minimal polynomial over $\mathbb{Z}$ whose root it is, and a ball in $\mathbb{C}$ (an acb_t enclosure) that isolates it from all other roots of that polynomial.
The challenge is that this must be an exact decision despite the number being represented only implicitly. The function works through a hierarchy of cases, using fast shortcuts first and falling back to a rigorous iterative refinement loop.
Case 1: Rational numbers (degree 1)
if (qqbar_degree(x) == 1)
return -fmpz_sgn(QQBAR_COEFFS(x));
When $x$ is rational, its minimal polynomial is linear: $c_1 x + c_0 = 0$, so $x = -c_0/c_1$. The coefficients are stored as QQBAR_COEFFS(x) in order from lowest to highest degree, so the leading coefficient is QQBAR_COEFFS(x)[1] and the constant is QQBAR_COEFFS(x)[0]. Since the minimal polynomial is primitive with positive leading coefficient by convention, $\operatorname{sgn}(x) = -\operatorname{sgn}(c_0)$, which is $-\operatorname{sgn}(\mathtt{QQBAR\_COEFFS}(x)[0])$. This is computed by fmpz_sgn on the zeroth coefficient.
Case 2: Enclosure already certifies zero
else if (arb_is_zero(acb_realref(QQBAR_ENCLOSURE(x))))
return 0;
If the stored enclosure ball has real part that is exactly the zero ball (radius zero, midpoint zero), then $\operatorname{Re}(x) = 0$ is already certified. This happens when the enclosure was previously refined to lie on the imaginary axis.
Case 3: Enclosure already separates from zero
else if (!arb_contains_zero(acb_realref(QQBAR_ENCLOSURE(x))))
return arf_sgn(arb_midref(acb_realref(QQBAR_ENCLOSURE(x))));
If zero is not contained in the real part of the enclosure ball, then the sign is determined immediately: it is the sign of the midpoint of that ball (since the entire ball is on one side of zero). This is the common fast path for numbers that are not purely imaginary.
Case 4: Enclosure straddles zero — iterative refinement
When the enclosure ball for $\operatorname{Re}(x)$ contains zero but is not certified to be zero, the sign is genuinely ambiguous at the current precision. The function must work harder.
Parity shortcut: could $\operatorname{Re}(x)$ be zero?
maybe_zero = 1;
for (i = 1; i < d && maybe_zero; i += 2)
if (!fmpz_is_zero(QQBAR_COEFFS(x) + i))
maybe_zero = 0;
Before entering the refinement loop, the code checks a necessary condition for $\operatorname{Re}(x) = 0$: if $x$ is purely imaginary, then $x$ satisfies a polynomial with only even-degree terms (because $p(iy) = 0$ implies $p$ has only even powers). Equivalently, all odd-degree coefficients of the minimal polynomial must vanish. If any odd coefficient is nonzero, then $\operatorname{Re}(x) \ne 0$ is guaranteed by algebra alone, and the code sets maybe_zero = 0, skipping the more expensive zero-certification test inside the loop.
The refinement loop
for (prec = QQBAR_DEFAULT_PREC / 2; ; prec *= 2)
{
_qqbar_enclosure_raw(t, QQBAR_POLY(x), t, prec);
if (!arb_contains_zero(acb_realref(t)) || arb_is_zero(acb_realref(t)))
{
res = arf_sgn(arb_midref(acb_realref(t)));
break;
}
if (maybe_zero)
{
acb_set(u, t);
arb_zero(acb_realref(u));
if (_qqbar_validate_existence_uniqueness(u, QQBAR_POLY(x), u, prec * 2))
{
res = 0;
break;
}
}
}
The loop doubles the working precision on each iteration. Two exit conditions exist:
- Nonzero certified. _qqbar_enclosure_raw refines the enclosure ball t to the requested precision using interval Newton iterations on the minimal polynomial. If after refinement the real part of t no longer contains zero (or is the exact zero ball), the sign is read off from the midpoint and the loop exits. As precision doubles, the ball radius shrinks exponentially, so if $\operatorname{Re}(x) \ne 0$ this will eventually succeed.
- Zero certified. When maybe_zero is set, the code constructs a modified ball u from t but with its real part forced to zero — i.e., a vertical strip on the imaginary axis. It then calls _qqbar_validate_existence_uniqueness, which uses an interval arithmetic argument (essentially a rigorous version of Rouché's theorem or a Krawczyk/Newton test) to verify that the minimal polynomial has exactly one root inside u. Since $x$ is already known to be the unique root in the original enclosure, and the imaginary-axis sub-ball is contained in it, this proves $\operatorname{Re}(x) = 0$ exactly.
Termination
The loop always terminates. If $\operatorname{Re}(x) \ne 0$, the enclosure radius halves (relative to the distance from zero) on each doubling of precision, so the sign is eventually resolved. If $\operatorname{Re}(x) = 0$, the parity check guarantees maybe_zero is set, and the uniqueness test will eventually succeed once the enclosure is tight enough for the interval Newton contractor to confirm the root lies exactly on the imaginary axis.
Summary
| Condition | Method | Cost |
|---|---|---|
| $x$ rational (degree 1) | Read sign of constant coefficient | $O(1)$ |
| Enclosure already on imaginary axis | Direct read | $O(1)$ |
| Enclosure separated from imaginary axis | Sign of enclosure midpoint | $O(1)$ |
| Enclosure straddles imaginary axis, $\operatorname{Re}(x) \ne 0$ | Iterative precision doubling until separation | $O(\text{prec})$ per iteration |
| Enclosure straddles imaginary axis, $\operatorname{Re}(x) = 0$ | Parity check + uniqueness certification on imaginary axis | $O(\text{prec})$ per iteration |
The overall design reflects a standard pattern in exact real/algebraic computation: try cheap numerical tests first, and fall back to a rigorous (but more expensive) algebraic or interval-analytic certificate only when the numerical evidence is genuinely ambiguous.