Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

A period inside the math delimiters (`$\frac{1}{3}.$`) makes correct answers fail and can make wrong ones pass

Đang mở Phù hợp với người mới
#85 0 bình luận 0 reaction 0 người được giao Xem trên GitHub

@MohammadHijjawi97 đang làm issue này rồi.

Từ ngày 1/10/2026.

  • #86 của @MohammadHijjawi97 — đang mở

Đánh giá

Độ khó
2/5
Thời gian dự kiến
1-3 giờ
Mức phù hợp với người mới
90/100
Loại issue
Lỗi
Độ rõ ràng
Đặc tả rõ ràng
Mức độ hoạt động
Sôi nổi
Công nghệ
python
Lĩnh vực
backend

Hướng nghiên cứu

Bắt đầu với extract_latex trong parser.py, nơi nội dung được phân cách được chuyển đến bước chuẩn hóa, sau đó xem xét các trường hợp liên quan trong tests/test_all.py. Bổ sung kiểm thử hồi quy cho dấu chấm, dấu phẩy, dấu chấm phẩy, khoảng trắng, dấu câu được escape và dấu ba chấm ở cuối; công việc được hoàn tất khi các dòng được báo cáo được chấm điểm như mong đợi và các kiểm thử hiện có đều đạt.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Mô tả

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 main at 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.

Ngôn ngữ chính
Python
Star
1.2k
Fork
65
Chỉ số merge pull request
Không có pull request nào được merge trong 30 ngày

Chuẩn bị môi trường

Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của huggingface/Math-Verify

Tất cả issue của huggingface/Math-Verify

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.