File size: 5,241 Bytes
2dc1d0c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
52467f4
 
 
 
 
 
 
 
 
 
 
 
 
 
2dc1d0c
 
 
 
 
 
 
52467f4
 
 
 
 
 
 
 
 
2dc1d0c
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
#!/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())