mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-30 18:56:16 +00:00
- SDPVerify.lean: certificate verification engine (714 lines, compiles cleanly) - GoormaghtighCert.lean: Goormaghtigh conjecture SDP certificate - HachimojiManifoldAxiom/HachimojiSubstitution: Hachimoji DNA encoding - GeneticBraidBridge.lean: genetic algorithm braid bridge - load_dependency_graph/load_module_graph: Gremlin Cosmos DB graph loaders - test_graph_queries/rrc_math_xref: graph verification queries - Gremlin mathblob DB provisioned and accessible - Branch cleanup: deleted 11 stale remote branches Build: 3297 jobs, 0 errors (lake build Semantics.SDPVerify)
168 lines
5.8 KiB
Python
168 lines
5.8 KiB
Python
#!/usr/bin/env -S uv run
|
|
# /// script
|
|
# requires-python = ">=3.11"
|
|
# dependencies = ["gremlinpython", "python-dotenv"]
|
|
# ///
|
|
"""
|
|
rrc_math_xref.py — Cross-reference RRC equations → arxiv papers → Lean modules
|
|
|
|
For each named RRC equation, finds top Jaccard-matching arxiv papers,
|
|
then queries Gremlin for Lean modules whose names overlap with paper keywords.
|
|
Prints a full cross-reference report.
|
|
"""
|
|
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
from dotenv import load_dotenv
|
|
|
|
ROOT = Path(__file__).resolve().parent.parent
|
|
ENV_FILE = ROOT / ".env.gremlin"
|
|
load_dotenv(ENV_FILE)
|
|
|
|
NEON_HOST = "neon-64gb"
|
|
CONTAINER = "arxiv-pg"
|
|
DB = "arxiv"
|
|
|
|
EQUATIONS = [
|
|
"Chirality_Algebra",
|
|
"BLINK_GATE_Ternary_Clock",
|
|
"Christoffel_Symbols_2D",
|
|
"Stereographic_Chart_Transition",
|
|
"Affine_Mapping_Periodic_Theorem",
|
|
"Affine_Mapping_LTSF_Linear_Layer",
|
|
"BitFlip_Gradient_5D",
|
|
"DAG_Force_Equilibrium",
|
|
"Energy_Function",
|
|
"Energy_Monotonicity_Theorem",
|
|
]
|
|
|
|
# ── Neon ──────────────────────────────────────────────────────────────────────
|
|
|
|
def neon(sql: str, timeout: int = 90) -> list[list[str]]:
|
|
r = subprocess.run(
|
|
["ssh", NEON_HOST,
|
|
f"podman exec {CONTAINER} psql -U postgres -d {DB} -t -A -F '|' -c \"{sql}\""],
|
|
capture_output=True, text=True, timeout=timeout,
|
|
)
|
|
return [ln.split("|") for ln in r.stdout.strip().split("\n") if ln]
|
|
|
|
def jaccard_top(eq_name: str, k: int = 5) -> list[dict]:
|
|
rows = neon(f"""
|
|
WITH eq_codes AS (
|
|
SELECT unnest(codes) AS code, array_length(codes,1) AS eq_len
|
|
FROM rrc_equation_codes8 WHERE name = '{eq_name}'
|
|
),
|
|
eq_meta AS (SELECT MAX(eq_len) AS eq_len FROM eq_codes),
|
|
scored AS (
|
|
SELECT pc.paper_id, COUNT(x.code) AS isect,
|
|
array_length(pc.codes,1) + m.eq_len - COUNT(x.code) AS union_sz
|
|
FROM arxiv_paper_codes8 pc JOIN eq_meta m ON true JOIN eq_codes x ON x.code = ANY(pc.codes)
|
|
GROUP BY pc.paper_id, pc.codes, m.eq_len
|
|
)
|
|
SELECT s.paper_id, ROUND(s.isect::numeric/s.union_sz,3), ap.title, ap.categories
|
|
FROM scored s JOIN arxiv_papers ap ON s.paper_id = ap.paper_id
|
|
ORDER BY 2 DESC LIMIT {k}
|
|
""".replace("\n", " "))
|
|
return [{"id": r[0], "j": r[1], "title": r[2], "cat": r[3]} for r in rows if len(r) >= 3]
|
|
|
|
# ── Gremlin ───────────────────────────────────────────────────────────────────
|
|
|
|
from gremlin_python.driver import client as gc, serializer
|
|
|
|
_client = None
|
|
def gremlin():
|
|
global _client
|
|
if _client is None:
|
|
_client = gc.Client(
|
|
os.environ["GREMLIN_ENDPOINT"], "g",
|
|
username=os.environ["GREMLIN_USERNAME"],
|
|
password=os.environ["GREMLIN_PASSWORD"],
|
|
message_serializer=serializer.GraphSONSerializersV2d0(),
|
|
)
|
|
return _client
|
|
|
|
def gremlin_q(q: str, b: dict = None) -> list:
|
|
try:
|
|
return gremlin().submitAsync(q, b or {}).result().all().result()
|
|
except Exception as e:
|
|
return []
|
|
|
|
def modules_for_keywords(keywords: list[str]) -> list[str]:
|
|
"""Find internal Lean modules whose id contains any keyword."""
|
|
all_ids = gremlin_q(
|
|
"g.V().hasLabel('module').has('kind','internal').values('id')"
|
|
)
|
|
hits = []
|
|
for mid in all_ids:
|
|
for kw in keywords:
|
|
if kw.lower() in mid.lower():
|
|
hits.append(mid)
|
|
break
|
|
return sorted(set(hits))
|
|
|
|
def module_in_degree(module_id: str) -> int:
|
|
r = gremlin_q(
|
|
"g.V().has('module','id',mid).in('imports').count()",
|
|
{"mid": module_id}
|
|
)
|
|
return r[0] if r else 0
|
|
|
|
# ── Keyword extraction ────────────────────────────────────────────────────────
|
|
|
|
STOP = {"and","the","of","a","in","on","for","with","to","from","by","an","is","are","via"}
|
|
|
|
def title_keywords(title: str) -> list[str]:
|
|
words = title.lower().replace("-"," ").replace("$","").split()
|
|
return [w.strip(".,()[]{}") for w in words if len(w) > 3 and w not in STOP]
|
|
|
|
# ── Main ──────────────────────────────────────────────────────────────────────
|
|
|
|
def main():
|
|
print("Loading all internal module IDs from Gremlin...")
|
|
all_modules = gremlin_q(
|
|
"g.V().hasLabel('module').has('kind','internal').values('id')"
|
|
)
|
|
print(f" {len(all_modules)} internal modules\n")
|
|
|
|
for eq in EQUATIONS:
|
|
print(f"{'═'*70}")
|
|
print(f" {eq}")
|
|
print(f"{'─'*70}")
|
|
|
|
papers = jaccard_top(eq, k=5)
|
|
if not papers:
|
|
print(" (no Neon matches)\n")
|
|
continue
|
|
|
|
# Collect keywords from top paper titles
|
|
all_kws = []
|
|
for p in papers:
|
|
all_kws.extend(title_keywords(p["title"]))
|
|
|
|
# Find Lean modules matching keywords
|
|
matching_mods = []
|
|
for mid in all_modules:
|
|
short = mid.split(".")[-1].lower()
|
|
for kw in all_kws:
|
|
if kw in short or short in kw:
|
|
matching_mods.append(mid)
|
|
break
|
|
matching_mods = sorted(set(matching_mods))
|
|
|
|
print(f" arxiv matches:")
|
|
for p in papers:
|
|
print(f" [{p['j']}] {p['id']:15s} {p['title'][:55]} ({p['cat']})")
|
|
|
|
print(f" Lean modules ({len(matching_mods)}):")
|
|
for m in matching_mods[:8]:
|
|
deg = module_in_degree(m)
|
|
print(f" {m:55s} ← {deg} importers")
|
|
|
|
print()
|
|
|
|
gremlin().close()
|
|
|
|
if __name__ == "__main__":
|
|
main()
|