A period inside the math delimiters (`$\frac{1}{3}.$`) makes correct answers fail and can make wrong ones pass
评估
调研方向
从 parser.py 中的 extract_latex 开始,其中带分隔符的内容会传递给规范化处理,然后检查 tests/test_all.py 中的相关用例。为末尾句点、逗号、分号、空白、转义标点和省略号添加回归覆盖;当报告的行按预期评分且现有测试通过时,即表示完成。
由索引模型根据 Issue 内容生成。
描述
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.
- 主要语言
- Python
- 星标
- 1.2k
- 派生
- 67
- PR 合并指标
- 30 天内没有已合并 PR
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
huggingface/Math-Verify 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 78/100
huggingface/Math-Verify#102 ·
-
verify() raises ValueError comparing chained relations of different length可能已有人在做 @chetana1410 于 6 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 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 writes可能已有人在做 @shaurya416 于 34 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 84/100
huggingface/Math-Verify#83 ·
-
verify() rejects a not-equal written in the other order可能已有人在做 @chetana1410 于 5 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 35/100
huggingface/Math-Verify#100 ·
-
verify() rejects an absolute-value inequality that is the same interval可能已有人在做 @chetana1410 于 5 天前认领。 未关闭
难度 4/5 3-5 天 新手友好度 35/100
huggingface/Math-Verify#98 ·
查看 huggingface/Math-Verify 的全部 Issue
相似的 Issue
-
Support .aac audio uploads可能已有人在做 @julien731 今天认领。 未关闭feature
难度 2/5 1-3 小时 新手友好度 78/100
nimblehq/audio-transcriber#153 ·
-
help wanted
难度 2/5 1-3 小时 新手友好度 68/100
antonyrag/ragleap-core#1062 ·
-
needs-triage
难度 2/5 1-3 小时 新手友好度 76/100
gke-labs/kube-agents#4321 ·
维护者通常 1 天内回复
-
enhancement help wanted
难度 2/5 1-3 小时 新手友好度 76/100
Git-Hospital/githealthcheck#61 ·
维护者通常 1 天内回复
-
changelog investigate
难度 2/5 1-3 小时 新手友好度 67/100
ramnes/notion-sdk-py#433 ·