Guarantees and limits¶
A verification result is only as useful as the reader's certainty about what it means, so this page states, in one place, what each verdict establishes, what it deliberately does not, and what the record keeps as evidence. Every statement here describes the engine as it runs today. Where a limit exists it is stated precisely rather than hedged, because a verifier that is vague about its own edges is asking to be trusted rather than checked.
What each verdict guarantees¶
| Verdict | What it establishes | What it does not | What the record keeps |
|---|---|---|---|
proven |
The claim holds for every input in the declared domain, established by algebra in exact real arithmetic. On a finite integer domain, derive:brute_force has instead evaluated every point, each decided exactly; where a point has no exact value the sweep is proven on derive:brute_force:within_float64, every point run in float64, each such point's float64 result within float64's own precision of the relation there, and the largest delta stated; a larger miss is not counted (unknown), or holds under a declared tolerance. |
That floating point reproduces what the reals prove. Where the function is undefined inside the domain as mathematics (a root of a negative, a division by zero), or its own source raises there, no proof is reached and the claim itself is falsified; where the computation fails on an input the mathematics admits (an overflow, a NaN, a precision collapse) the [float] companion claim, which runs the real function at the domain's corners and across its interior, is falsified while the proof stands, see Mathematics and computation below and the sigmoid case study. |
The route (derive, derive:extensive, derive:brute_force, derive:brute_force:within_float64) and a sketch naming the mechanism behind the proof. A proven never rests on an unnamed step. |
holds (n=...) |
The real function survived exactly n executed trials without a counterexample, on seeded inputs biased toward domain edges, corners, poles and special values. |
A probability of failure. No statistical bound is computed or implied. The confidence stars beside a holds measure sampling density against the function's structure, and top out at four of five, since five is reserved for proof. |
n, the sampling plan including its seed, and the confidence breakdown. |
falsified |
The real function, called at an in-domain point, violates the claim. That point is the witness, and a falsified always has one. A negated claim (not is_defined(f)) says the positive claim fails somewhere, which no single point can refute, so its witness is the proof of the positive claim over the whole domain. A missing input is not such a point: what the function does with one is judged by its policy row (missing values), and a policy row the code contradicts is falsified like any claim. A raise at that point, a NaN computed from inputs that are not missing, or an infinity returned for a finite input (an overflow or a pole, where math would raise), is no value, so it falsifies every relation, != included. The one agreement is two sides that overflow toward the same infinity (both inf, or both -inf): that is one extended-real point, so the point reads as two equal values; a NaN agrees with nothing, not even another NaN. Probing runs under one pinned floating-point regime, so the witness does not depend on the caller's numpy.seterr settings. |
Anything about why. A falsification may mean the code is wrong or the claim is, and the loop exists to tell those apart, see the CDD loop. | The counterexample, kept permanently and replayed on every later run, so a bug cannot be fixed by accident and quietly unfixed. |
invalidated |
The claim was proven or holds in the previous record and the current code no longer supports it. |
That it may simply be re-adjudicated away. It stays invalidated until the claim is supported again, or a person accepts it as a discovery or as history. |
The previous verdict, what it regressed to, and the last commit where it was supported. |
unknown |
Nothing was decided, and the reason is kept. This includes a symbolic disproof that no executed point reproduces, which is flagged as a probable engine fault rather than reported as a bug in your code. | A pass. verify fails on an unknown unless a person accepts it as risk. |
Why each route stopped (unliftable, undecided, timed out). |
skipped |
The claim could not be adjudicated as stated: misspecified, or a form the chosen route cannot evaluate. | A pass. verify fails on a skipped in its default strict mode. |
The reason, with a reason code. |
Accepted risk is not a verdict. It is a person's recorded decision
to own an unknown or skipped gap, with their name, the date and
their note. It stays visible in every report, and strict verify still
refuses it. See mathema accept.
Mathematics and computation¶
Every result mathema reports belongs to one of two strata, and the
record never lets one stand in for the other. The mathematics is the
function as an object over the reals and its declared sets, the same in
every language and on every machine, and it is what the derive route
reasons about: a proven means the claim holds in exact real
arithmetic over the declared domain, with infinity as infinity, and
nothing about the number representation the code happens to run on enters that
reasoning, no largest double, no overflow threshold, no operational
infinity. What does enter is the mathematics of definedness, namely the
real domain of the primitives (a root of a negative, a logarithm at or
below zero, a division by zero), a raise the function's own source
states, a nan or an infinity its source returns as the value
(math.nan, float("inf")), and a library's is_defined row, since a function undefined at
a point of its domain is not the function the claim describes. The
computation is one implementation executed in one language, one runtime
and one number representation, and the number representation follows the domain: float64 for a claim
over R, complex128 for one over C (its companion is
<name>[complex]). Everything that belongs to the computation, a raise
and its type, a NaN, an overflow, a loss of precision, a recursion
limit, is established only by running that implementation, belongs to
that implementation, and never transfers to another, however the two
are related mathematically.
An executed value is read by one rule on every path that executes
anything, the probe route, the [float] companion, the computation-safety
families (is_numerically_stable, is_representation_safe,
is_missing_safe and the rest) and the computation line of =:= alike. A
raise, a NaN computed from inputs that are not missing, or an infinity
returned for a finite input is no value, and no value fails every
relation, != included; two sides that overflow toward the same
infinity are one extended-real point and agree, while a NaN agrees with
nothing, not even another NaN. The reading does not change with the
kind of claim, so a witness means the same thing wherever it appears in
the record.
A missing input belongs to neither stratum's value claims: the function's behaviour there (raises, drops, propagates, converts, introduces) is its own claim, the policy row.
The number representation never overturns a proof. Where the derive route closes a
claim, the computation's verdict lives on the <name>[float] companion
the proof spawns, which runs the real function at the corners of the
declared domain and across its interior and is falsified, with a
witness, where the computation fails on an input the mathematics
admits; the proof stands, the companion gates verify like any other
claim, and a row that is mathematically proven above a falsified
companion reads exactly as it should, the mathematics sound and the
computation in float64 failing at the witness (see the evidence
ladder).
Where the derive route cannot close a claim, the probe's verdict is the
claim's verdict and its route says so, and an overflow met there
falsifies the claim itself, since a claim decided by execution is a
claim about the computation until something proves the mathematics. In
the other direction a derive disproof becomes falsified only with an
executed witness, so the mathematics is never allowed to convict code
that behaves.
An operational infinity is a fact about the computation and only that:
it says how far along an unbounded direction the code is exercised, by
the probe route and by the companion, and it never bounds a proof,
which is over ℝ whatever the binding says. It is declared on the claim,
let |inf| be 1e100 in the grammar or pseudo_infinity= in Python,
and a claim's own declaration takes precedence over the levels beneath
it. Those resolve in the order claim, function, project
(MATHEMA_PSEUDO_INFINITY) and then the number representation's own maximum,
sys.float_info.max (about 1.8e308) for float64. The value that
applied is shown only where it bounds an unbounded direction of the
claim's effective domain, as a plain binding in front of the
computation rows' condition (let |inf| be 1e+06, for x in R), never
in the claim's statement, with the level it came from recorded in
meta["mathema.pseudo_infinity"]; a claim whose every direction is
already bounded says nothing about infinity at all. See operational
infinity for the grammar
and a worked example.
The computation-safety families each answer one of three questions
about a function: does it run on my domain, is the answer right in
float64, and is it repeatable. The claim
grammar lists every family
under its question, with what it tells you and the usual fix. A safety
predicate reads the claim's assuming clause like every other claim
(its trials run only at points inside the premise, an equality premise
drawn on its surface), and a raise from the function at such a point is
no value, so it falsifies the predicate with that point and the
exception as the witness.
Corroboration: why every falsification has a witness¶
The derive route can report that a claim is false by algebra alone. Such
a disproof stands only if running the real function reproduces it: the
engine tries the symbolic witness, small perturbations of it, and a
seeded blind search, and calls the function at each point. If one of
them fails the claim, the result is falsified with that executed
witness, recorded as mathema.corroboration: "reproduced". If none do,
the result is unknown with mathema.corroboration: "uncorroborated",
since an algebraic disproof that the code never exhibits more likely
points at a fault in the engine than in the code. A safety predicate's
structural disproof follows the same rule. A pole inside the declared
domain (is_pole_safe, is_numerically_stable), or a raising guard on
a missing value the domain admits (is_missing_safe), is checked by
calling the function at the point the structure names. A raise there,
or a non-finite result at a pole, is the witness; a call that behaves
leaves the disproof uncorroborated. Where the code, run where the
difference is, rounds it away, the body is read exactly there (its
literals as written, its divisions as ratios, a root as sympy holds
it), and a difference that reading confirms is the witness. A pole no
float lands on (sqrt(2) for 1 / (x*x - 2), where the nearest float
returns a large finite number) is the witness itself when interval
arithmetic certifies that the divisor is zero there, independently of
the solver that found it, as is_defined certifies the same point.
Where no exact reading confirms it (a gap below float resolution that
comes from a float outside the body), the record adds
mathema.corroboration_reason: "exact arithmetic only" and the note
says so instead of naming an engine bug. A falsification is
therefore equally strong whichever route found it, because it always
rests on the same thing, the real function failing at a real input.
How the routes combine¶
A claim takes the best route unless you pin one. The engine first
attempts a proof (a fast attempt, then the
extensive strategy ladder), and a claim the proof
cannot decide falls through to probing, with the reason the proof
stopped kept in the record. The result names the mechanism that settled
it, and a claim's name never implies a route.
- A claim pinned to
route: derivemakes the fast proof attempt only, and derive gives its verdict. When the proof cannot settle it (a body derive cannot read, a branch it cannot decide, the wall clock), the probe still samples the claim, as a falsifier only: a counterexample it executes falsifies the claim, on the probe's route with derive's reason in the note, and draws that find none leave the claimunknown, neverholds, with the number of draws in the note. A proof's[float]companion and a disproof's executed witness are as on any route. - A claim pinned to
route: probenever attempts a proof. - Calculus forms (
d,lim,integrate,Sum,Prod) are decided by the derive route. When the proof cannot close, numeric evidence on the lifted expression is reported as such, as mathema's reconstruction of the code rather than the code itself. - A matrix identity the algebra cannot close is sampled over matrices
of its declared shape, and stays
unknownonly where it cannot be sampled.
What composes, and what does not¶
Evidence never gets stronger as it propagates. A claim that rests on
another through an assuming premise is capped at the evidence of the
weakest premise, and the record names the cap
(meta["mathema.capped_by"]); a premise that demands is proven and
finds only holds leaves the conclusion unknown. See
Conditional claims and lemmas.
An equivalence between two implementations lets one's mathematical
claims stand for the other at the equivalence's own evidence level and
never higher, so a holds equivalence can never make a claim about the
other implementation proven. Safety properties (state,
representation, overflow) never transfer, since they belong to an
implementation and its language rather than to the mathematics.
Recording transferred claims in the other implementation's own record,
with the equivalence named as provenance, is designed and not yet
built. See Claims transfer.
Boundaries worth knowing¶
- Reals and floats. Proof is over the reals, with infinity as
infinity, and the computation is covered by running the code:
probing, witnesses, the
[float]companion claim every proof spawns, and an operational infinity for how far an unbounded direction is exercised. Mathematics and computation states the rule in full. - Time caps. Proof attempts are capped on the wall clock: 3 seconds
for the ordinary attempt, 15 when
extensive=Trueasks for more, with a 45 second failsafe over the whole extensive ladder. A proof that runs out of time falls through to probing and the record says so (mathema.timeout), so a slow machine can turn aproveninto aholds(anunknownonroute: derive), and never the reverse. - What the derive route lifts. Straight-line and branching scalar code, accumulating loops, linear self-recursion, and more, catalogued in The derive route. Beyond scalars and sequences, matrices are partial: structure and identities prove, and probing samples matrices by shape and structure. Complex-valued code supports identities, not analysis. Everything outside the lift is still checked by running it.
- Shapes are strict. A verdict compares the values the code returned with what the claim wrote, and a container is never its element, 0 included; an ordering over an empty value does not hold; a premise alone reads 0 as the zero of the other side's shape; bindings that fix one dimension to two sizes are misspecified. Shapes states the rules.
- Reproducibility. Sampling is seeded (seed
20260718) and the seed travels in the record's sampling plan, so a re-run on the same code and the same mathema version reproduces the same draws. Each record states the mathema version, the CDD spec version, the date and the commit it was adjudicated at.
Glossary¶
System 0 engine. A verification engine with zero models between the code and its verdict. Every result comes from mathematics and from running the real code, never from a model's judgement.
Claim. A statement about what a function computes, written in the claim grammar, with a name and a declared domain.
Domain. The set of inputs a claim quantifies over. A claim without its domain is a different claim.
Route. The mechanism that decided a claim: derive (algebra),
probe (running the code on sampled inputs) or examine (structural
facts about the code). Colon subroutes such as derive:extensive or
probe:minimal_example name a stronger or more specific mechanism.
Lift. The derive route's translation of a function body into a mathematical expression. A function that lifts can be proven about; one that does not is still probed.
Witness. The executed input at which the real function fails a
claim. Every falsified has one. For a negated claim the witness is the
proof of the positive claim over the whole domain.
Corroboration. Reproducing a symbolic disproof by running the real
function, which is what turns an algebraic disproof into a falsified.
Form hash. A hash of the function's structure with names normalised, so a rename or reformat leaves it unchanged and a change in what the code does moves it. A record binds to it, which is how a verdict notices that its code has changed.
Evidence ladder. The ordering of verdicts by strength, from proven
through holds to the unsettled states, set out in
The evidence ladder.
Record. The durable result of adjudication, stored under
.mathema/verified/, bound to the form hash and committed with the code.