Skip to main content
The Math Engine is QWED’s core verification engine. It uses SymPy for symbolic computation to provide exact verification of mathematical claims.

Capabilities


Quick start


Core operations

1. Expression evaluation

Verify that an expression equals a value:

2. Identity verification

Check if two expressions are mathematically equivalent:
Identity verification uses symbolic simplification first. If SymPy proves the identity algebraically, the result is VERIFIED. When symbolic simplification is inconclusive, the engine samples five test points as a fallback. Only points that the engine can successfully evaluate count toward agreement — the engine skips domain-restricted expressions (e.g., log(x) at x = -1) rather than producing a false negative.
Numerical sampling cannot prove equivalence. If all sample points agree but no formal proof was established, the engine now fails closed — returning BLOCKED with is_equivalent: false, method: "numerical_sampling_rejected", and confidence: 0.0. Two expressions can match at fixed points without being algebraically identical, so sampling-only agreement is rejected outright. Treat BLOCKED results as unverified.

3. Derivatives

Verify calculus derivatives:

4. Integrals

Verify indefinite and definite integrals:

5. Limits


Financial calculations

Compound interest

Net present value (NPV)

Internal rate of return (IRR)

Cash flows with more than one sign change, or that fail to converge, are now rejected with BLOCKED rather than returning a best-effort iterate. See verify_irr — convergence proof for the full state table.

Fail-closed semantics

Three verification methods require an additional proof step before returning VERIFIED. When the underlying claim is ambiguous, incomplete, or numerically unproven, the engine returns BLOCKED or CORRECTION_NEEDED with structured diagnostics rather than a best-effort answer.

verify_statistics(statistic="mode") — unique mode required

mode verification returns VERIFIED only when a single value has the maximum frequency. When two or more values tie for the maximum frequency, the engine returns BLOCKED with an ambiguous_modes list — it will not heuristically pick one. Response fields on the BLOCKED case:
The Stats Engine’s compute_statistics method returns an equivalent multimodal error on its own surface — see Stats engine — Errors.

verify_matrix_operation(operation="eigenvalues") — cardinality match required

Eigenvalue verification requires the claimed list to have the same length as the calculated eigenvalue set, counting algebraic multiplicity. Previously the value comparison used zip, which silently truncated to the shorter list — so a claim of [2] for a matrix with eigenvalues [2, 3] could pass. The cardinality check now runs before the value comparison. Response fields on the cardinality-mismatch case:

verify_irr — convergence proof

IRR verification now requires proof that Newton-Raphson converged before returning VERIFIED. Successful results include converged: true and iterations_used for auditability. The engine blocks inputs whose IRR is mathematically ambiguous or numerically unreachable rather than returning the current iterate. Response fields:
These three methods are behavior changes. Inputs that previously received VERIFIED — an ambiguous mode dataset, an under-specified eigenvalue list, or a cash-flow series with multiple sign changes — now return BLOCKED or CORRECTION_NEEDED. Treat both statuses as unverified and consume the structured diagnostic fields rather than relying on a numeric result.

Trust boundary

When you verify a natural language math query through the /verify/natural_language endpoint, the response includes a trust_boundary object. This object describes exactly what the pipeline proved and what it did not.
The overall status for natural language math queries is INCONCLUSIVE because, while QWED evaluates the expression deterministically, it cannot verify that the LLM correctly interpreted the user’s intent. The trust_boundary gives you the information to decide whether the result is sufficient for your use case.

Error handling

When verification fails, QWED provides detailed error information:

Exact SymPy arithmetic

When SymPy is available, the math engine evaluates expressions using SymPy-native types (sympy.Integer, sympy.Float) instead of Python built-in int and float. This prevents floating-point drift during intermediate computation and ensures that comparisons between LLM answers and verified results use symbolic simplification rather than string matching alone.

Decimal precision

The math engine accepts Decimal values for exact arithmetic, which is especially useful for financial calculations:
When use_decimal=True (the default), the engine uses Decimal internally regardless of whether you pass a float or Decimal.

Tolerance settings

For floating-point comparisons, you can specify a tolerance:

Tolerance bounding

To prevent inflated tolerances from masking incorrect results, the math engine enforces a deterministic upper bound on the tolerance parameter. QWED computes the maximum allowed tolerance as a function of the result’s magnitude:
If the requested tolerance exceeds this bound, QWED rejects the verification with a BLOCKED status instead of returning a potentially misleading VERIFIED result. This applies to both decimal and float precision modes.
The engine also rejects invalid tolerance values (negative numbers, NaN, Infinity, or non-numeric strings) with a BLOCKED status and an "Invalid tolerance" error message.

Trust boundary

When math verification runs through the natural language pipeline (POST /verify/natural_language), the response now includes a trust_boundary object. This object describes exactly what the pipeline proved and what it did not, separating deterministic expression evaluation from the non-deterministic LLM translation step.
Because the LLM translation step is non-deterministic, the natural language pipeline now returns INCONCLUSIVE instead of VERIFIED even when the underlying expression evaluation succeeds. This prevents over-representing a translated-query evaluation as a proven user-query verdict. Use the direct POST /verify/math endpoint if you need a fully deterministic result without the LLM translation layer.

Ambiguous expressions

Expressions with implicit multiplication after division are ambiguous — for example, 1/2(3+1) could mean (1/2)*(3+1) or 1/(2*(3+1)). Rather than guessing, the math engine fails closed and returns BLOCKED:
To resolve this, rewrite the expression with explicit parentheses or a * operator:

Edge cases


Performance


Next steps