debpc
fix: harden claim metadata extraction v4.2.12
0842763
Raw
History Blame Contribute Delete
2.07 kB
"""Claim-schema aware deterministic numeric validation."""
from __future__ import annotations
import re
from copy import deepcopy
from numeric_core import validate_numeric
_EXACT_SPAN_KINDS = {"frequency", "effect_size"}
def _norm(value: str) -> str:
return re.sub(r"\s+", " ", str(value or "")).strip().casefold()
def validate_claim_numbers(
claim_text: str,
evidence_text: str,
numeric_facts: list[dict],
*,
relative_tolerance: float,
) -> tuple[str, list[dict], list[str]]:
facts = deepcopy(numeric_facts)
contains_number = bool(re.search(r"\d", claim_text)) or bool(facts)
if not contains_number:
return "not_applicable", facts, ["The claim contains no numeric assertion."]
full_result = validate_numeric(
claim_text,
evidence_text,
rel_tol=relative_tolerance,
)
reasons: list[str] = []
all_ok = bool(full_result.get("numeric_ok"))
for fact in facts:
raw_text = str(fact.get("raw_text") or "")
kind = str(fact.get("kind") or "")
raw_present = bool(raw_text) and _norm(raw_text) in _norm(evidence_text)
if kind in _EXACT_SPAN_KINDS:
fact_ok = raw_present
else:
fact_result = validate_numeric(
raw_text,
evidence_text,
rel_tol=relative_tolerance,
)
fact_ok = raw_present and bool(fact_result.get("numeric_ok"))
fact["status"] = "validated" if fact_ok else "conflicted"
fact["correction"] = None
if not fact_ok:
all_ok = False
reasons.append(
f"Numeric fact '{raw_text or kind}' is absent from or inconsistent with the source quote."
)
if all_ok:
reasons.append("All numeric assertions match the exact source quote; no correction was applied.")
return "validated", facts, reasons
reasons.append("At least one numeric assertion is unsupported or inconsistent; silent correction is forbidden.")
return "conflicted", facts, reasons