#!/usr/bin/env python3 """Generate a high-value porting candidates report from the Research Stack usage graph.""" import json from collections import Counter from pathlib import Path ROOT = Path("/tmp/SilverSight/docs") graph = json.loads((ROOT / "research_stack_usage_graph.json").read_text()) ents = {e["id"]: e for e in graph["entities"]} # Build in-degree and dependency depth indeg = Counter() outdeg = Counter() for e in graph["edges"]: if e["kind"] == "imports": indeg[e["dst"]] += 1 outdeg[e["src"]] += 1 modules = [e for e in graph["entities"] if e["kind"] == "module"] # Scoring: high theorem count, low sorries, imported by many, kind matches SilverSight priorities def score(m): th = m.get("theorem_count", 0) so = m.get("sorry_count", 0) im = indeg.get(m["id"], 0) de = m.get("def_count", 0) # penalize sorries heavily, reward theorems and in-degree return th * 2 + de + im * 3 - so * 10 # Priority kinds for SilverSight priority_kinds = {"fixedpoint", "number_theory", "braid", "rrc", "avm", "geometry", "algebra"} candidates = sorted( [m for m in modules if m.get("math_kind") in priority_kinds and m.get("sorry_count", 0) <= 5], key=score, reverse=True, ) md = ["# Research Stack → SilverSight Porting Candidates", ""] md.append("Generated from `research_stack_usage_graph.json`. Scores reward theorem count,") md.append("in-degree (foundational), and definitions; penalize sorries. Filtered to") md.append("SilverSight-relevant math kinds with ≤5 sorries.") md.append("") md.append(f"## Top 50 candidates") md.append("") md.append("| Module | Kind | Theorems | Defs | Sorries | In-degree | Score |") md.append("|--------|------|----------|------|---------|-----------|-------|") for m in candidates[:50]: md.append( f"| `{m['name']}` | {m.get('math_kind','?')} | " f"{m.get('theorem_count',0)} | {m.get('def_count',0)} | {m.get('sorry_count',0)} | " f"{indeg.get(m['id'],0)} | {score(m)} |" ) md.append("") md.append("## Candidates by math kind") md.append("") for kind in priority_kinds: kind_mods = [m for m in candidates if m.get("math_kind") == kind][:15] if not kind_mods: continue md.append(f"### {kind}") for m in kind_mods: md.append( f"- `{m['name']}` — th={m.get('theorem_count',0)} def={m.get('def_count',0)} " f"sorry={m.get('sorry_count',0)} in={indeg.get(m['id'],0)}" ) md.append("") md.append("## Zero-sorry foundation modules") md.append("") md.append("Modules with 0 sorries that are imported by at least 3 other modules:") md.append("") for m in sorted( [m for m in modules if m.get("sorry_count", 0) == 0 and indeg.get(m["id"], 0) >= 3], key=lambda x: -indeg.get(x["id"], 0), )[:30]: md.append( f"- `{m['name']}` ({m.get('math_kind','?')}) — imported by {indeg.get(m['id'],0)}, " f"th={m.get('theorem_count',0)}" ) md.append("") md.append("## Most referenced concepts by script") md.append("") script_edges = [e for e in graph["edges"] if e["kind"] == "touches_database"] for db_edge in sorted(script_edges, key=lambda x: ents.get(x["src"], {}).get("name", ""))[:20]: src = ents.get(db_edge["src"], {}) dst = ents.get(db_edge["dst"], {}) md.append(f"- `{src.get('name','?')}` → `{dst.get('name','?')}`") md.append("") md.append("## Conceptual bindings to CFF references") md.append("") md.append("When porting a module, check `CITATION.cff` for the source reference that") md.append("supports its mathematical or physical claim.") md.append("") md.append("| SilverSight concept / module | Research Stack source / CFF reference |") md.append("|------------------------------|---------------------------------------|") md.append("| `SidonSets`, `SpherionTwinPrime`, number-theory fixtures | Saucedo 2019 — Pascal's Triangle/Pyramid/Trinomial |") md.append("| `BraidEigensolid`, `BraidSpherionBridge`, `BaselineComparison` | Farr & Groot 2009 — polydisperse hard-sphere packing |") md.append("| Meta-solid 1/7 mixing threshold | Fasolo & Sollich 2004 — terminal polydispersity ~14% |") md.append("| Eigensolid packing bounds | Baranau & Tallarek 2014 — RCP limits |") md.append("| `FixedPoint`, `Q16InverseProof`, no-Float compute | Arrizabalaga et al. 2026 — single-precision differentiable IPM |") md.append("| Recurrent search/classification loops | Yang et al. 2026 — STARS recurrent scaling |") md.append("") (ROOT / "research_stack_porting_candidates.md").write_text("\n".join(md), encoding="utf-8") print(f"Wrote {ROOT / 'research_stack_porting_candidates.md'}") print(f"Total candidates: {len(candidates)}")