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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
|
"""Verbatim prompts recovered from the original GAP/Putnam source.
Do not edit prompt literals in this file. ``tests/test_prompts.py`` pins their
SHA-256 digests against the recovered source files.
"""
from __future__ import annotations
import json
from .models import CanonicalItem, KernelCandidate, KernelPlan
# Source: PutnamVariants@c3bed737370df2dbf73afd66bf6e86d4ece82d68
# scripts/o3_kernel_variant.py
KERNEL_PLAN_SYSTEM = "You are an IMO medalist & pedagogue."
KERNEL_PLAN_PROMPT = """
You are a competition-math expert.
(1) Read the Putnam problem and its official solution below.
(2) List the MINIMAL chain of lemmas / techniques essential to the solution.
(3) Identify every numerical or structural element that could be changed
*without* altering that chain of reasoning. Denote them as MUTABLE_SLOTS.
Return **one JSON object only**:
{{
"core_steps": ["..."], // 1–5 concise phrases
"mutable_slots": {{
"slot1": {{"description": "...", "original": "..."}},
"slot2": {{"description": "...", "original": "..."}}
}}
}}
PROBLEM:
<<<{question}>>>
SOLUTION:
<<<{solution}>>>
"""
KERNEL_GENERATE_SYSTEM = "You are a creative yet rigorous math professor."
KERNEL_GENERATE_PROMPT = """
We previously extracted:
CORE_STEPS = {core}
MUTABLE_SLOTS = {slots}
Here is the ORIGINAL problem for reference:
<<<{orig_q}>>>
And its OFFICIAL solution:
<<<{orig_s}>>>
Create ONE *new* Putnam-level problem that
• still requires exactly the chain CORE_STEPS to solve,
• alters *every* MUTABLE_SLOT in a significant way.
Return JSON only:
{{
"question": "...", // full statement (LaTeX-friendly)
"solution": "..." // complete proof with new data
}}
"""
# Source: paper Appendix F.3, Listing 4.
JUDGE_SYSTEM_PROMPT = """You are a verification judge for a kernel-variant generation pipeline. You must decide whether a CANDIDATE variant problem and its CANDIDATE proof are mathematically equivalent to the ORIGINAL problem under the given METHOD-LABEL sequence (the abstract proof plan).
Your job is verification, not solving. You receive:
- the ORIGINAL problem statement and reference solution,
- the abstract METHOD-LABEL sequence (a list of content-free steps),
- the SLOT replacement that was applied,
- the CANDIDATE variant statement and the CANDIDATE regenerated proof.
You must check, step by step, that:
1. Every CANDIDATE step instantiates the corresponding METHOD label with the new operands.
2. The CANDIDATE proof is mathematically valid: each step follows from the previous one, with no unjustified leap.
3. The CANDIDATE problem statement is well-posed and has a unique terminal answer matching the regenerated proof.
4. The CANDIDATE variant is genuinely different from the ORIGINAL (the slot replacement actually changed the instance) but uses the same plan.
Output a single JSON object with exactly these fields."""
JUDGE_USER_TEMPLATE = """ORIGINAL PROBLEM:
{original_problem}
ORIGINAL REFERENCE SOLUTION:
{original_solution}
METHOD-LABEL SEQUENCE (abstract plan):
{method_labels}
SLOT REPLACEMENT:
{slot_replacement}
CANDIDATE VARIANT PROBLEM:
{candidate_problem}
CANDIDATE REGENERATED PROOF:
{candidate_proof}
Return:
{{"verdict": "accept" or "reject",
"step_by_step_check": "for each METHOD label, state whether the CANDIDATE step instantiates it correctly",
"blocking_issues": "list any logical gap, computation error, ill-posed statement, or plan deviation",
"patch_suggestion": "if reject, propose a minimal patch (a corrected proof step or a corrected slot value); leave empty if accept"}}"""
FIX_SYSTEM_PROMPT = """You are a mathematical expert tasked with fixing kernel variant problems.
Based on the review feedback, correct the identified issues while maintaining the problem's essence.
Guidelines:
- Fix mathematical errors while preserving the problem's structure
- Ensure the corrected version is well-posed and solvable
- Keep solutions detailed and pedagogically clear
- Maintain similar difficulty level to the original problem
Provide COMPLETE corrected versions, not just patches."""
FIX_USER_TEMPLATE = """Based on the review feedback, please fix this kernel variant:
CURRENT PROBLEM:
{kv_question}
CURRENT SOLUTION:
{kv_solution}
REVIEW FEEDBACK:
Problem Issues: {problem_issues}
Solution Issues: {solution_issues}
ORIGINAL PROBLEM (for reference):
{orig_question}
ORIGINAL SOLUTION (for reference):
{orig_solution}
Please provide corrected versions. Return JSON with:
{{"corrected_question": "complete corrected problem statement",
"corrected_solution": "complete corrected solution",\x20
"changes_made": "summary of key changes made"}}"""
# Source: PutnamVariants@c3bed737370df2dbf73afd66bf6e86d4ece82d68
# scripts/o3_rename_vars.py
SURFACE_SYSTEM_BASE = "You are a meticulous LaTeX editor."
SURFACE_TASK_COMMON = """
Given:
• A Putnam problem statement and its official solution (LaTeX-like);
• Two symbol lists: vars (unknowns) and params (given constants).
Rename every symbol in *vars* and *params* with a unique English identifier:
– all-lowercase letters, ≥8 chars, no underscore/space;
– same original symbol → same new name everywhere;
– different symbols → different new names;
– NEVER touch sci_consts (\\pi,e,i,…) or numeric constants;
– do NOT alter any other text or LaTeX markup.
"""
SURFACE_TASK_DESCRIPTIVE = """
Each new identifier **should describe the symbol's mathematical role**.
"""
SURFACE_TASK_CONFUSING = """
Each new identifier **should *not* match the symbol's role**; choose plausible
but misleading nouns so the name sounds related but not matching the true meaning, such as replace Area with Radius.
"""
SURFACE_TASK_MISLEADING = """
Each new identifier **should describe the *opposite* concept**. Pick names that
directly contradict the symbol's actual meaning, e.g. rename a parallel vector
to orthogonalvector.
"""
SURFACE_TASK_GARBLED = """
Each new identifier **should look like random gibberish**: at least eight
lowercase letters with no apparent meaning such as qzxwvtnp or hjgrksla.
"""
SURFACE_RETURN_SPEC = """
Return exactly **one JSON object** and nothing else:
{"map":{"old":"new",...},"question":"...","solution":"..."}
"""
SURFACE_USER_TEMPLATE = """Problem:
<<<
{question}
>>>
Solution:
<<<
{solution}
>>>
vars = {vars}
params = {params}
"""
SURFACE_TASKS = {
"descriptive_long": SURFACE_TASK_DESCRIPTIVE,
"descriptive_long_confusing": SURFACE_TASK_CONFUSING,
"descriptive_long_misleading": SURFACE_TASK_MISLEADING,
"garbled_string": SURFACE_TASK_GARBLED,
}
def kernel_plan_user(item: CanonicalItem) -> str:
return KERNEL_PLAN_PROMPT.format(
question=item.problem,
solution=item.solution,
)
def kernel_generate_user(item: CanonicalItem, plan: KernelPlan) -> str:
return KERNEL_GENERATE_PROMPT.format(
core=json.dumps(plan.core_steps, ensure_ascii=False),
slots=json.dumps(
{
key: value.model_dump(mode="json")
for key, value in plan.mutable_slots.items()
},
ensure_ascii=False,
),
orig_q=item.problem,
orig_s=item.solution,
)
def judge_user(
item: CanonicalItem,
plan: KernelPlan,
candidate: KernelCandidate,
) -> str:
return JUDGE_USER_TEMPLATE.format(
original_problem=item.problem,
original_solution=item.solution,
method_labels=json.dumps(plan.core_steps, ensure_ascii=False),
slot_replacement=json.dumps(
{
key: value.model_dump(mode="json")
for key, value in plan.mutable_slots.items()
},
ensure_ascii=False,
),
candidate_problem=candidate.question,
candidate_proof=candidate.solution,
)
def fix_user(
item: CanonicalItem,
candidate: KernelCandidate,
*,
problem_issues: str,
solution_issues: str,
) -> str:
return FIX_USER_TEMPLATE.format(
kv_question=candidate.question,
kv_solution=candidate.solution,
problem_issues=problem_issues,
solution_issues=solution_issues,
orig_question=item.problem,
orig_solution=item.solution,
)
def surface_system(family: str) -> str:
return (
SURFACE_SYSTEM_BASE
+ SURFACE_TASK_COMMON
+ SURFACE_TASKS[family]
+ SURFACE_RETURN_SPEC
)
def surface_user(item: CanonicalItem) -> str:
return SURFACE_USER_TEMPLATE.format(
question=item.problem,
solution=item.solution,
vars=item.variables,
params=item.parameters,
)
|