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

Capabilities

CategoryExamplesAccuracy
Arithmetic2+2=4, 15*3=45100%
Algebrax^2 - 1 = (x-1)(x+1)100%
CalculusDerivatives, Integrals, Limits100%
Trigonometrysin(π/2) = 1, cos(0) = 1100%
Logarithmslog(e) = 1, ln(e^x) = x100%
FinancialCompound interest, NPV, IRR100%
StatisticsMean, std dev, percentiles100%

Quick Start

from qwed_sdk import QWEDClient

client = QWEDClient(api_key="your_key")

# Verify a math claim
result = client.verify_math("15% of 200 is 30")
print(result.verified)  # True
print(result.status)    # "VERIFIED"

Core Operations

1. Expression Evaluation

Verify that an expression equals a value:
# Simple arithmetic
result = client.verify_math("2 * (5 + 10) = 30")
# ✓ Verified

# Complex expression
result = client.verify_math("sqrt(16) + 3^2 = 13")
# ✓ Verified

# Percentage
result = client.verify_math("15% of 200 = 30")
# ✓ Verified

2. Identity Verification

Check if two expressions are mathematically equivalent:
# Algebraic identity - TRUE
result = client.verify_math("(a+b)^2 = a^2 + 2*a*b + b^2")
# ✓ Verified: Algebraic identity proven

# Algebraic identity - FALSE
result = client.verify_math("(a+b)^2 = a^2 + b^2")
# ✗ Not Verified: Missing 2ab term

# Trig identity
result = client.verify_math("sin(x)^2 + cos(x)^2 = 1")
# ✓ Verified: Pythagorean identity
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 can be successfully evaluated count toward agreement — domain-restricted expressions (e.g., log(x) at x = -1) are skipped rather than causing a false negative.
Numerical sampling cannot prove equivalence. Even if all sample points agree, the result is UNKNOWN with confidence: 0.0 because two expressions can match at fixed points without being algebraically identical. Treat UNKNOWN results as unverified.

3. Derivatives

Verify calculus derivatives:
result = client.verify_derivative(
    expression="x^3 + 2*x^2",
    variable="x",
    expected="3*x^2 + 4*x"
)
# ✓ Verified

# Higher-order derivatives
result = client.verify_derivative(
    expression="x^4",
    variable="x",
    expected="12*x^2",
    order=2  # Second derivative
)
# ✓ Verified

4. Integrals

Verify indefinite and definite integrals:
# Indefinite integral
result = client.verify_integral(
    expression="2*x",
    variable="x",
    expected="x^2"  # + C implied
)
# ✓ Verified

# Definite integral
result = client.verify_integral(
    expression="x^2",
    variable="x",
    lower=0,
    upper=1,
    expected="1/3"
)
# ✓ Verified

5. Limits

result = client.verify_limit(
    expression="sin(x)/x",
    variable="x",
    point=0,
    expected=1
)
# ✓ Verified: lim(x→0) sin(x)/x = 1

Financial Calculations

Compound Interest

result = client.verify_compound_interest(
    principal=1000,
    rate=0.05,      # 5% annual
    time=10,        # years
    n=12,           # monthly compounding
    expected=1647.01
)
# ✓ Verified

Net Present Value (NPV)

result = client.verify_npv(
    rate=0.10,
    cash_flows=[-1000, 300, 400, 500, 600],
    expected=388.07
)
# ✓ Verified

Internal Rate of Return (IRR)

result = client.verify_irr(
    cash_flows=[-1000, 400, 400, 400],
    expected=0.0985  # ~9.85%
)
# ✓ Verified

Trust boundary

When you verify a natural language math query through the /verify/natural_language endpoint, the response includes a trust_boundary object that describes exactly what the pipeline proved and what it did not.
{
  "status": "INCONCLUSIVE",
  "final_answer": 30.0,
  "trust_boundary": {
    "query_interpretation_source": "llm_translation",
    "query_semantics_verified": false,
    "verification_scope": "translated_expression_only",
    "deterministic_expression_evaluation": true,
    "formal_proof": false,
    "translation_claim_self_consistent": true,
    "provider_used": "openai_compat",
    "overall_status": "INCONCLUSIVE"
  }
}
FieldMeaning
query_interpretation_sourceHow the user query was converted to an expression (always llm_translation)
query_semantics_verifiedWhether the translation accurately represents the user’s intent (false — this is not formally provable)
verification_scopeWhat was actually verified (translated_expression_only)
deterministic_expression_evaluationWhether the expression itself was evaluated deterministically
formal_proofWhether a formal proof was established
translation_claim_self_consistentWhether the LLM’s claimed answer matches the computed answer
overall_statusThe response-level status reflecting the trust boundary
The overall status for natural language math queries is INCONCLUSIVE because, while the expression evaluation is deterministic, QWED 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:
result = client.verify_math("15% of 200 = 40")

if not result.verified:
    print(result.error)
    # "Calculation incorrect: 15% of 200 = 30, not 40"
    print(result.expected)
    # 30
    print(result.actual)
    # 40

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:
from decimal import Decimal

result = client.verify_math(
    expression="0.1 + 0.2",
    expected_value=Decimal("0.3")  # Exact comparison, no float drift
)
# ✓ Verified
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:
result = client.verify_math(
    "sqrt(2) = 1.41421",
    tolerance=0.00001  # 5 decimal places
)
# ✓ Verified within tolerance

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.
{
  "trust_boundary": {
    "query_interpretation_source": "llm_translation",
    "query_semantics_verified": false,
    "verification_scope": "translated_expression_only",
    "deterministic_expression_evaluation": true,
    "formal_proof": false,
    "translation_claim_self_consistent": true,
    "provider_used": "openai",
    "overall_status": "INCONCLUSIVE"
  }
}
FieldTypeDescription
query_interpretation_sourcestringAlways "llm_translation" — indicates the query was interpreted by an LLM
query_semantics_verifiedbooleanAlways false — QWED cannot verify that the LLM correctly interpreted the user’s intent
verification_scopestringAlways "translated_expression_only" — only the translated expression was verified
deterministic_expression_evaluationbooleantrue when the inner engine status was VERIFIED or CORRECTION_NEEDED
formal_proofbooleanAlways false — SymPy evaluation is deterministic but not a formal proof of the original query
translation_claim_self_consistentbooleanWhether the translated expression matched its own claimed answer
provider_usedstringThe LLM provider used for translation
overall_statusstringThe top-level response status after trust boundary alignment
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.

Edge Cases

ScenarioBehavior
Division by zeroReturns error, not verified
Undefined expressionsReturns “UNDEFINED” status
Complex numbersFully supported
Very large numbersUses arbitrary precision
Symbolic variablesVerified algebraically

Performance

OperationAvg LatencyThroughput
Simple arithmetic1.5ms690/sec
Complex expression5ms200/sec
Identity proof10ms100/sec

Next Steps