If labels are missing, find corresponding figure/table code in figures/*.tex and embed into the correct section file.
Also check compile_utils.sh output for "UNEMBEDDED" warnings — each one means a figure or table from figures/ is not in any section.
MANDATORY FIX LOOP — do NOT proceed to compilation until all figures AND tables are embedded:
UNEMBED=0
for pdf in figures/*.pdf; do
[ -f "$pdf" ] || continue
bn=$(basename"$pdf")
grep -rq "$bn" paper/sections/*.tex paper/main.tex 2>/dev/null || { echo"UNEMBEDDED PDF: $bn"; UNEMBED=$((UNEMBED+1)); }
donefor tbl in figures/TABLE_*.tex; do
[ -f "$tbl" ] || continuefor lbl in $(grep -oh '\\label{[^}]*}'"$tbl" 2>/dev/null); do
grep -rq "$lbl" paper/sections/*.tex paper/main.tex 2>/dev/null || { echo"UNEMBEDDED TABLE: $lbl"; UNEMBED=$((UNEMBED+1)); }
donedoneecho"Total unembedded: $UNEMBED"
If UNEMBED > 0, fix ALL before compiling. For each unembedded item, copy the figure/table block into the appropriate section with lead-in text + analysis. Re-run until UNEMBED = 0.
Step 3: Compile (manual steps, no latexmk)
cd paper/
rm -f main.aux main.blg main.log main.out main.toc 2>/dev/null
pdflatex -interaction=nonstopmode main.tex 2>&1 | tee compile_pass1.log
bibtex main 2>&1 | tee bibtex.log
pdflatex -interaction=nonstopmode main.tex 2>&1 | tee compile_pass2.log
pdflatex -interaction=nonstopmode main.tex 2>&1 | tee compile.log
[ -f main.pdf ] && echo"main.pdf $(wc -c < main.pdf) bytes" || echo"PDF not generated"
Step 4: Error diagnosis and fix loop (MANDATORY)
After each compilation, check main.log for CRITICAL errors. You MUST fix ALL errors before declaring compilation complete.
MATH_ERR=$(grep -c 'Bad math environment delimiter\|Missing \$ inserted\|begin{document} ended by' paper/main.log 2>/dev/null || echo 0)
LR_ERR=$(grep -c 'Not allowed in LR mode' paper/main.log 2>/dev/null || echo 0)
echo"Math errors: $MATH_ERR, LR mode errors: $LR_ERR"
[ $((MATH_ERR + LR_ERR)) -gt 0 ] && grep -B2 'Bad math\|Missing \$ inserted\|Not allowed in LR mode' paper/main.log | grep -E '^\./|^l\.' | head -20
Iterate up to MAX_COMPILE_ATTEMPTS times, each with full 4-step compilation. For each error:
Math errors: read the error location from main.log, open the file, fix broken $...$ delimiters individually. Do NOT use broad sed patterns.
LR mode errors: add \par or blank line before float environments.
Missing packages: install them.
BibTeX failures: fix LaTeX errors first (BibTeX fails when LaTeX errors exist upstream), then recompile.
After each fix, recompile and recheck. ⛔ Do NOT proceed until MATH_ERR = 0 and LR_ERR = 0.
When fixing errors in main.tex, only fix the specific error. Do not rewrite or restructure main.tex — the template's preamble, page margins, and formatting settings must remain unchanged.
Body pages = Introduction through Conclusion, excluding references and appendix.
Body pages must be ≥ MAX_PAGES. If insufficient, return to paper-write to expand content.
"
import json, re, os
try:
with open('figures/all_results.json','r',encoding='utf-8') as f: results=json.load(f)
except Exception:
print('⚠ all_results.json unreadable'); exit(0)
def extract(obj, p=''):
n = {}
if isinstance(obj, dict):
for k, v in obj.items(): n.update(extract(v, f'{p}.{k}'))
elif isinstance(obj, list):
for i, v in enumerate(obj): n.update(extract(v, f'{p}[{i}]'))
elif isinstance(obj, (int, float)) and not isinstance(obj, bool):
if 0.001 < abs(obj) < 1e10: n[p] = obj
return n
jn = extract(results)
pn = set()
section_dir = 'paper/sections' if os.path.isdir('paper/sections') else 'paper'
for tf in sorted(os.listdir(section_dir)):
if not tf.endswith('.tex'): continue
try:
with open(f'{section_dir}/{tf}','r',encoding='utf-8',errors='ignore') as f: t=f.read()
except: continue
for m in re.finditer(r'(?<![a-zA-Z])(\d+\.?\d+)(?![a-zA-Z_{}])', t):
try: pn.add(float(m.group(1)))
except: pass
key_patterns = ['accuracy','acc','rmse','mae','r2','f1','auc','loss','precision','recall','bleu','rouge','perplexity','ppl','speed','latency','throughput','map','ndcg']
key_values = {k: v for k, v in jn.items() if any(w in k.lower() for w in key_patterns)}
miss = sum(1 for k, v in key_values.items() if not any(abs(p - v) < abs(v) * 0.01 + 0.001 for p in pn))
total = len(key_values)
if total == 0:
print(' (no key metrics in JSON to check)')
elif miss > 3:
print(f'❌ {miss}/{total} key values not found in paper — check numerical consistency'); exit(1)
else:
print(f'✅ Numerical consistency: {total-miss}/{total} key values present in paper')
"
1
else
echo
" (no all_results.json to check against)"
fi
# Unrealistic values check (detect fabricated or overfitted values)
echo
"--- Unrealistic values check ---"
if
then
"
import json
with open('figures/all_results.json','r',encoding='utf-8') as f: data=json.load(f)
suspicious = []
def check(name, val):
if not isinstance(val,(int,float)) or isinstance(val,bool): return
key = name.lower()
if any(w in key for w in ['r2','r_squared','accuracy','acc','precision','recall','f1','auc']) and val > 0.999:
suspicious.append(f'{name}={val:.4f} too perfect (>0.999), likely overfitted or leaked')
if any(w in key for w in ['rmse','mae','mse','loss']) and val == 0:
suspicious.append(f'{name}=0 perfect error, nearly impossible')
if ('p_value' in key or 'pvalue' in key) and val == 0:
suspicious.append(f'{name}=0 perfect significance')
if any(w in key for w in ['improvement','speedup','gain']) and val > 10:
suspicious.append(f'{name}={val} (+{val*100:.0f}%) unrealistically large')
def walk(obj, path=''):
if isinstance(obj,dict):
for k,v in obj.items(): walk(v, f'{path}.{k}')
elif isinstance(obj,list):
for i,v in enumerate(obj): walk(v, f'{path}[{i}]')
else: check(path, obj)
walk(data)
if suspicious:
print(f'🚩 {len(suspicious)} suspiciously perfect values (check for data leakage or fabrication):')
for s in suspicious[:5]: print(f' {s}')
print(' If values are genuinely valid, discuss why in the paper')
else:
print('✅ No suspicious values')
"
"❌ $META meta content leaks — remove references to internal files"
1
# Overclaiming
echo
"--- Overclaiming ---"
for
in
do
"$f"
continue
for
in
"首次提出"
"首次发现"
"完美"
"无可比拟"
"前所未有"
"开创性"
"revolutionary"
"unprecedented"
"groundbreaking"
do
"$w"
"$f"
echo
done
done
"$OC"
echo
"✅ No overclaiming"
echo
"⚠ $OC overclaiming instances"
# Claims-Evidence backfill (does paper cover all planned claims?)
echo
"--- Claims coverage ---"
if
then
"
import re, os
try: plan = open('PAPER_PLAN.md','r',encoding='utf-8').read()
except: exit(0)
rows = re.findall(r'\|\s*([^|]+?)\s*\|\s*([^|]+?)\s*\|', plan)
claims = [c.strip() for c, e in rows if c.strip() not in ('Claim','---') and '---' not in c and len(c.strip()) > 8]
if not claims:
print(' (no claims-evidence matrix in PAPER_PLAN.md)'); exit(0)
# 读取所有论文章节
section_dir = 'paper/sections' if os.path.isdir('paper/sections') else 'paper'
paper_text = ''
for tf in sorted(os.listdir(section_dir)):
if tf.endswith('.tex'):
try: paper_text += open(f'{section_dir}/{tf}','r',encoding='utf-8',errors='ignore').read()
except: pass
# 对每个 claim,提取关键词,在论文里找
missing = []
for c in claims[:15]:
keywords = [w for w in re.findall(r'[a-zA-Z_]{4,}|[\u4e00-\u9fff]{2,}', c) if len(w) > 3][:3]
if keywords and not any(kw.lower() in paper_text.lower() for kw in keywords):
missing.append(c[:50])
if missing:
print(f'❌ {len(missing)}/{len(claims)} planned claims not covered in paper:')
for m in missing[:5]: print(f' - {m}')
exit(1)
else:
print(f'✅ All {len(claims)} planned claims covered in paper')
"