Skip to main content

mathema

mathema checks Python functions against claims, short mathematical statements of what a function is meant to do, and keeps each result as a record bound to the exact code it was checked against. Where the body can be read as mathematics, mathema proves the claim for every input in the range the claim names, and where it cannot, it runs the real function on inputs chosen to break the claim and reports what it found, evidence or a counterexample, without upgrading one into the other.

AI-assisted development has made code cheaper to produce without making it any cheaper to know whether that code is correct, and a claim gives the reviewer something smaller and more precise to read than the diff. Every verdict comes from mathematics or from running the real code rather than from a model's judgement, so there is no account or API key and your code stays on your machine. The name is Greek, μάθημα, a thing learned.

A function with a pole in it

A discount factor written in a hurry, checked with no claim at all, so only mathema's built-in claims apply:

import mathema

def discount_factor(x: float) -> float:
    """A discount factor that divides by one minus the rate."""
    return 1 / (1 - x)

print(mathema.check(discount_factor))
mathema.Record(discount_factor) · source, no side effects · form ebb4c9b87847
  proven    is_defined: 1 - x != 0
  falsified is_pole_safe[x]: is_pole_safe(x)
           counterexample x = 1 is admitted by the declared domain but sits at or beside a pole: the call raised ZeroDivisionError

Those are two of the record's fourteen built-in claims. Uniform random sampling lands on x = 1 with probability zero, so a property-based run can pass a thousand trials here and report nothing, whereas mathema solves the lifted expression for where its denominator vanishes and makes sure that point is tried. is_defined states the region on which f returns, and every falsification rests on an executed witness, never on a symbolic argument alone.

A claim proven over its domain

import math

def put_call_parity_gap(s: float, k: float, r: float, t: float,
                        sigma: float) -> float:
    """A European call minus a European put on the same strike."""
    root_t = math.sqrt(t)
    d1 = (math.log(s / k) + (r + 0.5 * sigma * sigma) * t) / (sigma * root_t)
    d2 = d1 - sigma * root_t
    phi = lambda z: 0.5 * (1.0 + math.erf(z / math.sqrt(2.0)))
    call = s * phi(d1) - k * math.exp(-r * t) * phi(d2)
    put = k * math.exp(-r * t) * phi(-d2) - s * phi(-d1)
    return call - put

Put-call parity says this call minus put, both priced by Black-Scholes, is S - K*exp(-r*T) whatever the volatility. In a claim everything before the last comma is the domain and everything after it is the law, with f standing for the function:

mathema check options.py --claim "for s in [50,150], k in [50,150], \
    r in [0.0,0.1], t in [0.1,2], sigma in [0.05,0.8], \
    f(s,k,r,t,sigma) == s - k*exp(-r*t)"
ok   options.put_call_parity_gap: source, no side effects; claims 7/7 checked (1 proven, 6 holds, 0 falsified)

[0.1,2] is an interval of reals, and mathema lifted the body to an expression in which both Gaussian terms cancel and sigma drops out, so the mathematics is proven for the whole region. Of the six that hold, one is the same identity run through the real code in float64 and five record what the function does with a nan in each parameter. Without its domain the claim covers every real input, a negative maturity where math.sqrt(t) raises included:

import mathema
from options import put_call_parity_gap

print(mathema.check(put_call_parity_gap, claims=[mathema.claim(
    "f(s,k,r,t,sigma) == s - k*exp(-r*t)", name="parity")]))
mathema.Record(put_call_parity_gap) · source, no side effects · form a0c3d838b4f8
  falsified parity: f(s, k, r, t, sigma) = -k*exp(-r*t) + s
           counterexample s = 1, k = 1, r = 1, t = -1, sigma = 1

Four verdicts

Verdict Means
proven established mathematically over the claim's stated domain
holds survived every trial mathema ran, which is evidence and not proof
falsified an input inside the domain broke the claim, and that input is kept
unknown nothing was settled, and the record keeps the reason

A proof is about real numbers and whether float64 keeps up is a separate question, so a record shows each claim's headline above a mathematics line and a computation line, each with its own verdict, as reading a record shows; guarantees says what each verdict establishes and what it leaves open.

Install

mathema supports Python 3.10 to 3.14, runs offline, and is best installed into a virtual environment:

pip install "mathema[all]"    # recommended, with numpy, z3, MCP, coverage and mathema-language
pip install mathema           # the core alone

Claims over strings and structured values take their domains from the mathema-language package, which [all] includes; without it such a claim is unknown and names the package it needs.

Record, verify, gate

mathema.write_spec writes a function's record as YAML under .mathema/verified/, with a form hash over the code's structure and a sig hash over its parameters, and mathema verify re-checks every record whose function, or a function it depends on, has since changed. A falsified claim or an unaccepted unknown exits 1 and a run that could not start exits 2, so a pipeline can tell a finding from a broken job. mathema init --ci scaffolds the GitHub Actions or GitLab step, and gate a pipeline shows each case from a real run.

Coding agents

The mathema-agents skills teach a coding agent to propose claims and read verdicts, and arrive through an explicit, opt-in mathema init --agents, the one command that fetches anything. Accepting a verdict and unlocking a locked function stay with a person (working with coding agents).

Where next

Start here offers a reading order for each job, from a numerical function to a CI pipeline, and the quick start takes one function from falsified to proven. mathema is pre-1.0, with its claim grammar and record format fixed by the claim-driven development specification and its Python API likely to change, as stability sets out. See also CHANGELOG.md, CONTRIBUTING.md, SECURITY.md and SUPPORT.md.

mathema is source-available under the Business Source License 1.1, and each release converts to AGPL-3.0-or-later four years after it is published. LICENSING.md sets out the grant in plain language.

Metadata

Release files for mathema 0.6.1

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

Source distribution (sdist)

Source distribution for mathema 0.6.1
File Size Uploaded
mathema-0.6.1.tar.gz 2.2 MB Details

Built distribution (wheel)

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

Total release size: 3.6 MB

Release files / mathema-0.6.1.tar.gz

Download URL mathema-0.6.1.tar.gz
Size 2.2 MB
Tags Source
SHA-256 checksum
How to use checksums
05977b6a6d09e9434f12b72ad1c105ddf5f0f083f43458e17ba8004f3a3f4ee2
BLAKE2b-256 checksum
How to use checksums
41a9fcc3a4cdf0e27f01c3fd92081c269442ee3103db175cda07411cea2f857e
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 Oct 8, 2026.

Transparency log

Release files / mathema-0.6.1-py3-none-any.whl

Download URL mathema-0.6.1-py3-none-any.whl
Size 1.4 MB
Tags Python 3
SHA-256 checksum
How to use checksums
c509c3b1bf24af0a44461c2ceb6e5501c7ae728530a13ac4b866f7a088207a01
BLAKE2b-256 checksum
How to use checksums
04d367579e39480afc4097ed1db6c40dff73993a86d2eea17e80cadb4aa1a351
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 Oct 8, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.2

2 release files

This release

0.6.1 This release

2 release files

0.6.0

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