A period inside the math delimiters (`$\frac{1}{3}.$`) makes correct answers fail and can make wrong ones pass
@MohammadHijjawi97 ya está trabajando en esto.
Desde el 1/10/2026.
- #86 de @MohammadHijjawi97 — abierto
Evaluación
- Dificultad
- 2/5
- Tiempo estimado
- 1-3 horas
- Aptitud para principiantes
- 90/100
Línea de trabajo
Comienza con extract_latex en parser.py, donde el contenido delimitado se pasa a la normalización, y luego revisa los casos relacionados en tests/test_all.py. Añade cobertura de regresión para puntos finales, comas, puntos y comas, espacios en blanco, signos de puntuación escapados y puntos suspensivos; el trabajo estará terminado cuando las filas indicadas se califiquen como se espera y pasen las pruebas existentes.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
When a sentence-final period (or comma or semicolon) is written inside the math delimiters, the LaTeX does not parse. A correct answer is then graded wrong. With the default extraction config, the number pattern can instead read a fragment of the formula, so some wrong answers are graded correct.
The false-negative half is already documented: arXiv:2609.01354 ("Where the Verifier Fails", §3.2 and Table 8) reports that a trailing period makes Math-Verify reject an expression it otherwise accepts (\frac{1}{2} vs \frac{1}{2}.), and that whitespace and punctuation make up 93.0% of the default LaTeX configuration's in-contract failures in that study. What I haven't seen reported is the other direction: the same trailing period can make a wrong answer pass (the last three rows of the table below).
Reproduction
from math_verify import parse, verify
# Timeouts are disabled only because the default timeout fails on Windows (#79).
def grade(gold, answer):
return verify(
parse(gold, parsing_timeout=None),
parse(answer, parsing_timeout=None),
timeout_seconds=None,
)
print(parse(r"The answer is $\frac{1}{3}.$", parsing_timeout=None)) # ['\\frac{1}{3}.']
print(grade(r"$\frac{1}{3}$", r"The answer is $\frac{1}{3}.$")) # False, expected True
print(parse(r"The answer is $2^{10}.$", parsing_timeout=None)) # [2, '2^{10}.']
print(grade(r"$2$", r"The answer is $2^{10}.$")) # True, expected False
Expected vs actual
All rows use the default parse config (LatexExtractionConfig(), ExprExtractionConfig()) unless noted.
| Gold | Answer | Expected | Actual | parse(answer) |
|---|---|---|---|---|
$\frac{1}{3}$ |
$\frac{1}{3}.$ |
True | False | ['\\frac{1}{3}.'] |
$\frac{1}{3}$ |
$$\frac{1}{3}.$$ |
True | False | ['\\frac{1}{3}.'] |
$\frac{1}{3}$ |
\[\frac{1}{3}.\] |
True | False | ['\\frac{1}{3}.'] |
$\frac{1}{3}$ |
$\frac{1}{3},$ |
True | False | ['\\frac{1}{3},'] |
$\sqrt{2}$ |
$\sqrt{2}.$ |
True | False | ['\\sqrt{2}.'] |
$(1,2)$ |
$(1,2).$ |
True | False | ['(1,2).'] |
$42$ |
$42.$ (LaTeX config only) |
True | False | ['42.'] |
$2$ |
$2^{10}.$ |
False | True | [2, '2^{10}.'] |
$1$ |
The answer is $1/3.$ |
False | True | [1, '1/3.'] |
$12$ |
$12 - \sqrt{5}.$ |
False | True | [12, '12 - \\sqrt{5}.'] |
Controls: $\frac{1}{3}$. (period outside the delimiters) and $\frac{1}{3}$ are accepted. $42.$ is also accepted with the default config, but only because the number pattern reads $42, with $ taken as a currency sign. The LaTeX parse fails for that one too.
Cause
extract_latex passes the delimited content with its trailing . to normalize_latex and latex2sympy, which raises I don't understand this. With the default extraction_mode="any_match", the ExprExtractionConfig patterns are tried next. Their number pattern accepts a currency sign before a number, so it reads $2 from $2^{10}.$. An integer answer still gets its right value, which hides the problem. Any other answer is either lost (only the fallback string is returned) or replaced by its leading number.
Suggested fix
Before normalization, remove one trailing ., , or ; (and any whitespace after it) from the delimited LaTeX. Keep escaped characters (\,, \;, \.) and ellipses (...). This is a small change in parser.py, and I can open a PR for it with regression tests in tests/test_all.py. With the change, every case above grades as expected and the existing tests still pass.
The change does not cover a period inside \boxed{...}, as in \boxed{\sqrt{2}.}, because the boxed content is extracted inside latex2sympy2_extended's normalization. It also leaves the general fallback that reads numbers out of a LaTeX match that failed to parse (the subject of the closed PR #82). It only removes a common way of reaching that fallback.
Environment
- Windows 11 Pro 10.0.26200, x86-64, CPU only
- Python 3.13.14
- math-verify 0.9.0 from
mainat ba3d3aa (editable install), latex2sympy2_extended 1.11.0, sympy 1.14.0, antlr4-python3-runtime 4.13.2 - Not run on Linux. The code path is regex and ANTLR only, so I expect the same result there.
Found while systematically testing graders with meaning-preserving rewrites of gold answers and provably wrong answers.
I plan to mention this case, by mechanism only, in a write-up on grader reliability no earlier than 2026-10-31; happy to wait longer if you need.
- Lenguaje dominante
- Python
- Estrellas
- 1.2k
- Forks
- 65
- Métricas de merge de PR
- Sin PR fusionados en 30 d
Preparar el entorno
Este proyecto no incluye contenedor de desarrollo, Dockerfile ni guía de contribución, así que la configuración corre por tu cuenta: empieza por su README y consulta nuestra guía para la primera contribución para los pasos generales.
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de huggingface/Math-Verify
-
verify() raises ValueError comparing chained relations of different lengthPosiblemente ocupada @chetana1410 la tomó hace 2 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
huggingface/Math-Verify#93 ·
-
evaluate_model_outputs.py: rows whose gold cannot be extracted are dropped from the accuracy denominator, so the printed accuracy disagrees with the is_correct column the script writesPosiblemente ocupada @shaurya416 la tomó hace 30 días. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 84/100
huggingface/Math-Verify#83 ·
-
verify() rejects a not-equal written in the other orderPosiblemente ocupada @chetana1410 la tomó hace 1 día. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 35/100
huggingface/Math-Verify#100 ·
-
verify() rejects an absolute-value inequality that is the same intervalPosiblemente ocupada @chetana1410 la tomó hace 1 día. Abierto
Dificultad 4/5 3-5 días Aptitud para principiantes 35/100
huggingface/Math-Verify#98 ·
-
verify() rejects equivalent chained relations written in a different orderPosiblemente ocupada @chetana1410 la tomó hace 1 día. Abierto
Dificultad 3/5 1-2 días Aptitud para principiantes 35/100
huggingface/Math-Verify#96 ·
Todos los issues de huggingface/Math-Verify
Issues similares
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 65/100
NVIDIA/flare-local-inference#90 ·
Los mantenedores suelen responder en 1 día
-
area/streaming comp/gateway P2 platform/telegram type/bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
NousResearch/hermes-agent#144897 ·
Los mantenedores suelen responder en 1 día
-
request-theme
Dificultad 1/5 Menos de una hora Aptitud para principiantes 66/100
LizardByte/ThemerrDB#9575 ·
Los mantenedores suelen responder en 1 día
-
Author Page: noshin-nawalAbiertoauthor-page correction
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
acl-org/acl-anthology#10599 · 1 comentario ·
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 78/100
zilliztech/memsearch#818 ·
Los mantenedores suelen responder en 1 día