Skip to main content

exprtest

exprtest provides fast predicates for mathematical expressions (including exact numeric ones). Its currently primary API, zerotest(), returns True only for a proved zero. By default it returns False for either a proved nonzero value or strong one-sided evidence of nonzeroness, and None when neither conclusion is available. Use confidence="certified" when False must mean proved nonzero.

The package combines specialized SymPy-based exact methods with rigorous Arb/Acb ball arithmetic from python-flint. Numerical guesses and probabilistic evidence never become a proof without an independent certificate. The default probable policy may use strong one-sided nonzero evidence for a False result; users can request certified-only Boolean semantics explicitly.

Installation

pip install exprtest

Install the rigorous Arb/FLINT backend when you want ball-arithmetic and FLINT-accelerated proofs:

pip install "exprtest[flint]"

For development with the full backend:

pip install -e ".[dev]"
pytest

Quick start

import sympy as sp
from exprtest import is_algebraic, is_prime, zerotest

x = sp.symbols("x")

assert zerotest(0) is True
assert zerotest(sp.pi) is False
assert zerotest(sp.Function("f")(x)) is None

assert is_prime(97) is True
assert is_algebraic(sp.sqrt(2)) is True
assert is_algebraic(sp.pi) is False

For a complete executable example, see examples/quickstart.py.

Proof semantics

zerotest(expr) defaults to probable semantics: strong one-sided NONZERO_LIKELY evidence may map to False; probabilistic zero-like evidence is never promoted to True. Use zerotest(expr, confidence="certified") when both Boolean outcomes must be certified. Use profile_zerotest() when you need the method, evidence, or stage timings.

from exprtest import profile_zerotest

profile = profile_zerotest(sp.exp(sp.sqrt(2), evaluate=False))
assert profile.result is False
print(profile.classification.method)
print(profile.classification.evidence)

The distinction between exact proof, rigorous enclosure, probabilistic evidence, and heuristic candidate generation is described in docs/soundness.md.

What the fast oracle handles

The normal oracle uses bounded, structure-specific methods rather than general symbolic simplification. Important classes include exact rational arithmetic, small algebraic towers and radicals, bounded polynomial/rational identities, assumption-aware nonzero and definedness proofs, roots of unity and exact trigonometric/power identities, branch-safe logarithmic/exponential relations, selected exact special-function values, bounded exponential-independence theorems, rigorous Arb/Acb enclosures, and finite-field testing for suitable rational functions.

Potentially expensive stages are admitted by structural budgets. Sparse tower arithmetic, cached expression fingerprints, per-call fact memoization, and adaptive precision selection keep common cases inexpensive.

Function-property knowledge

exprtest includes a small registry of SymPy-native function facts, including selected real/sign properties, complex-domain restrictions, and simple pole sets. The active entries are regression-tested against the documented SymPy semantics used by the package. This improves zerotest() as well as public predicates such as is_real() and is_integer() without adding a runtime dependency. The registry is documented in docs/function_facts.md.

A capability overview is available in docs/capabilities.md.

Number predicates

The package exposes tri-state predicates for common number domains:

from exprtest import (
    ElementOf,
    is_algebraic,
    is_integer,
    is_prime,
    is_rational,
    is_real,
    number_kind,
)

Each predicate returns True, False, or None according to what the bounded proof engine can establish. ElementOf() performs lightweight membership simplification, and number_kind() distinguishes values proved algebraic, proved transcendental, or unresolved.

See docs/api.md for the supported public interface.

Performance model

zerotest() is intended to be a fast heuristic, so does not call general sympy.simplify(), trigsimp(), or together() on its latency-sensitive path. Expensive algebraic operations are size-gated and time-bounded. Stronger separation bounds and higher Arb precision are requested only when cheaper certificates are insufficient.

benchmarks/benchmark_zerotest.py measures cold and repeated-call throughput, median latency, p95 latency, and verdict counts. Benchmark numbers are machine specific; routing and proof-stage assertions in the test suite enforce the performance architecture independently of wall-clock timing. CI also records branch coverage and runs a separate structural performance-contract job.

More detail is in docs/performance.md.

Limitations

exprtest is intentionally incomplete. General symbolic identities with free variables, high-degree algebraic extensions, difficult branch-sensitive complex identities, and transcendental combinations outside known theorems may return None. Algebraic independence questions that are unknown in mathematics remain unknown to the package. And, of course, zero testing in general is undecidable.

See docs/limitations.md for the main boundaries and planned extensions.

Documentation

License

exprtest is free software licensed under the GNU General Public License v3.0 (GPL-3.0-only). See LICENSE for the full license text.

Metadata

Release files for exprtest 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for exprtest 0.1.0
File Size Uploaded
exprtest-0.1.0.tar.gz 104.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for exprtest 0.1.0
File Interpreter ABI Platform
exprtest-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 191.8 kB

Release files / exprtest-0.1.0.tar.gz

Download URL exprtest-0.1.0.tar.gz
Size 104.2 kB
Tags Source
SHA-256 checksum
How to use checksums
268354fd84944628e2b4d760950807bb7c1fc77cc5f2ecd4658835be68b2d63a
BLAKE2b-256 checksum
How to use checksums
de1fe2d7b39fdc72db4ee340cf31fa3b902dd8906ad3ebbe638a8573b6bf3502
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.

Transparency log

Release files / exprtest-0.1.0-py3-none-any.whl

Download URL exprtest-0.1.0-py3-none-any.whl
Size 87.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
52f9705017af22bc3d20c270656fe8666a533264d99e8a06b12ca968a27fd91e
BLAKE2b-256 checksum
How to use checksums
8d289d88b30882812ed0646051f3cf0151c3b5c83631f1aa110d544fbc159865
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 28, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page