#!/usr/bin/env python3 """Prueft die Antwortextraktion und den Vergleich. Bei Mathematik-Benchmarks steckt der Fehler fast nie im Modell, sondern im Vergleich: dieselbe Antwort kommt als 0.75, \\frac{3}{4}, 3/4 oder \\dfrac{3}{4}. Wer stur auf Zeichengleichheit prueft, misst Schreibweise statt Rechnen. Teil 3 laeuft gegen die echten Musterloesungen des Datensatzes: die muessen sich mit sich selbst vergleichen lassen, sonst ist die Quote systematisch zu niedrig. """ import json import sys sys.path.insert(0, "/mnt/models/qwen38-prep") import bench_mathe as B GLEICH = [ ("\\frac{3}{4}", "0.75"), ("0.75", "\\frac{3}{4}"), ("3/4", "\\frac{3}{4}"), ("\\dfrac{1}{2}", "\\frac{1}{2}"), ("\\left( 3, \\frac{\\pi}{2} \\right)", "(3,\\frac{\\pi}{2})"), ("1,000", "1000"), ("42", "42."), ("\\text{even}", "even"), ("90^\\circ", "90"), (" 7 ", "7"), ("50\\%", "50"), # Aus echten Fehlschlaegen des ersten Durchgangs — jeder dieser Faelle # wurde damals faelschlich als falsche Antwort gewertet. ("\\frac{4}{3}", "\\frac43"), ("\\frac{3}{4}", "\\frac 34"), ("\\frac{3}{4}", "\\dfrac34"), ("5", "x=5"), ("[-2, 7]", "x \\in [-2,7]"), ("B", "\\text{(B)}"), ("0,35625", ".35625"), (".5", "0.5"), ("-.25", "-0.25"), # Gefunden am 17.08. in der OMEGA-Bedarfsmessung: die Musterloesung haengt # die Einheit an, das Modell nicht. Wurde als falsch gewertet. ("\\frac{270}{7}", "\\frac{270}7\\text{ degrees}"), ("5", "5\\text{ inches}"), ("5\\text{ cm}", "5"), # Gemischte frac-Schreibweise: nur ein Argument geklammert. ("\\frac{270}{7}", "\\frac{270}7"), ("\\frac2{15}", "\\frac{2}{15}"), # Gefunden am 17.08. bei der Fehleranalyse des OMEGA-Hauptlaufs: von drei # abgeschlossenen Fehlschlaegen waren zwei reine Schreibweise. ("1-\\sqrt{19}, 1+\\sqrt{19}", "1 \\pm \\sqrt{19}"), ("1 \\pm \\sqrt{19}", "1+\\sqrt{19}, 1-\\sqrt{19}"), ("\\begin{pmatrix} \\frac{16}{49} \\\\[2mm] \\frac{48}{49} \\end{pmatrix}", "\\begin{pmatrix} 16/49 \\\\ 48/49 \\end{pmatrix}"), ] UNGLEICH = [ ("\\frac{3}{4}", "\\frac{4}{3}"), ("42", "43"), ("0.75", "0.76"), ("even", "odd"), ("(3,2)", "(2,3)"), # Die Einheitenregel darf nicht so weit gehen, dass Zahlen egal werden. ("\\frac{270}{7}", "\\frac{271}7\\text{ degrees}"), ("5", "6\\text{ inches}"), # Die \pm-Regel darf nur die Schreibweise aufloesen, nicht die Werte. ("1-\\sqrt{19}, 1+\\sqrt{19}", "1 \\pm \\sqrt{17}"), ("2 \\pm \\sqrt{19}", "1 \\pm \\sqrt{19}"), # Matrizen: gleiche Schreibweise, anderer Eintrag. ("\\begin{pmatrix} \\frac{16}{49} \\\\[2mm] \\frac{48}{49} \\end{pmatrix}", "\\begin{pmatrix} 16/49 \\\\ 47/49 \\end{pmatrix}"), ] BOXED = [ ("Also ist die Antwort \\boxed{42}.", "42"), ("\\boxed{\\frac{1}{2}}", "\\frac{1}{2}"), ("erst \\boxed{1}, dann \\boxed{2}", "2"), # das LETZTE zaehlt ("\\boxed{\\left( 3, \\frac{\\pi}{2} \\right)}", "\\left( 3, \\frac{\\pi}{2} \\right)"), ("kein Kasten hier", None), ] GSM = [ ("Rechnung ... #### 18", "18"), ("#### 1,000", "1,000"), ("erst #### 5 dann #### 7", "7"), ("nur Text mit Zahl 33 am Ende", "33"), ] def main(): fehler = 0 print("=== Teil 1: gleiche Antworten müssen als gleich gelten ===") for a, b in GLEICH: ok = B.stimmt(a, b) print(f" {'ok ' if ok else 'FEHL'} {a!r} == {b!r}") if not ok: fehler += 1 print("\n=== Teil 2: verschiedene Antworten müssen verschieden bleiben ===") for a, b in UNGLEICH: ok = not B.stimmt(a, b) print(f" {'ok ' if ok else 'ZU LASCH'} {a!r} != {b!r}") if not ok: fehler += 1 print("\n=== Teil 3: \\boxed{} korrekt herausschälen ===") for text, erwartet in BOXED: got = B.hole_boxed(text) ok = got == erwartet print(f" {'ok ' if ok else 'FEHL'} {text[:44]!r} -> {got!r}") if not ok: fehler += 1 print("\n=== Teil 4: GSM8K-Format ===") for text, erwartet in GSM: got = B.hole_gsm(text) ok = got == erwartet print(f" {'ok ' if ok else 'FEHL'} {text[:44]!r} -> {got!r}") if not ok: fehler += 1 print("\n=== Teil 5: Musterlösungen gegen sich selbst ===") for satz, feld in (("math500", "answer"), ("gsm8k-platinum", None)): try: aufgaben = B.lade(satz, 120) except FileNotFoundError: print(f" {satz}: nicht vorhanden, übersprungen") continue treffer = 0 misslungen = [] for a in aufgaben: erw = a["answer"] if feld else B.hole_gsm(a["answer"]) if B.stimmt(erw, erw): treffer += 1 else: misslungen.append(erw) print(f" {satz}: {treffer}/{len(aufgaben)} vergleichen sich mit sich selbst") for m in misslungen[:5]: print(f" problematisch: {m!r}") if treffer < len(aufgaben): fehler += 1 print(f"\n{'ALLES SAUBER' if not fehler else str(fehler) + ' PROBLEME'}") return 1 if fehler else 0 if __name__ == "__main__": sys.exit(main())