mirror of
https://github.com/allaunthefox/Research-Stack.git
synced 2026-07-31 03:05:21 +00:00
118 lines
4.1 KiB
Python
118 lines
4.1 KiB
Python
#!/usr/bin/env python3
|
|
"""Map equation forest: extract symbols and build connection graph."""
|
|
import json, re, sys
|
|
from collections import defaultdict
|
|
from pathlib import Path
|
|
|
|
DBS = [
|
|
"3-Mathematical-Models/equations_100/equations_database.jsonl",
|
|
"3-Mathematical-Models/equations_10000/equations_database.jsonl",
|
|
"3-Mathematical-Models/equations_parallel_10000/equations_database.jsonl",
|
|
]
|
|
|
|
SYMBOL_RE = re.compile(r'[a-zA-Z\u03b1-\u03c9\u0391-\u03a9\u2102\u2115\u211a\u211d\u2124][a-zA-Z0-9]*')
|
|
|
|
def extract_symbols(eq: str) -> set:
|
|
return set(SYMBOL_RE.findall(eq))
|
|
|
|
def main():
|
|
equations = []
|
|
for path in DBS:
|
|
p = Path("/home/allaun/Documents/Research Stack") / path
|
|
if not p.exists():
|
|
print(f"SKIP: {path}")
|
|
continue
|
|
with open(p) as f:
|
|
for line in f:
|
|
line = line.strip()
|
|
if not line:
|
|
continue
|
|
try:
|
|
obj = json.loads(line)
|
|
except json.JSONDecodeError:
|
|
continue
|
|
eq = obj.get("equation") or obj.get("normalized", "")
|
|
if eq:
|
|
equations.append({
|
|
"id": obj.get("equation_id", f"eq_{len(equations)}"),
|
|
"equation": eq,
|
|
"source": obj.get("source", ""),
|
|
"source_type": obj.get("source_type", ""),
|
|
"paper_title": obj.get("paper_title", ""),
|
|
"category": obj.get("category", ""),
|
|
"symbols": list(extract_symbols(eq)),
|
|
})
|
|
|
|
print(f"Loaded {len(equations)} equations")
|
|
|
|
# Build symbol -> equation index mapping
|
|
symbol_to_eqs = defaultdict(list)
|
|
for i, eq in enumerate(equations):
|
|
for sym in eq["symbols"]:
|
|
symbol_to_eqs[sym].append(i)
|
|
|
|
# Build edges: shared symbols
|
|
edges = []
|
|
for sym, idxs in symbol_to_eqs.items():
|
|
if len(idxs) < 2:
|
|
continue
|
|
for i in range(len(idxs)):
|
|
for j in range(i+1, len(idxs)):
|
|
edges.append({
|
|
"source": equations[idxs[i]]["id"],
|
|
"target": equations[idxs[j]]["id"],
|
|
"type": "shares_variable",
|
|
"symbol": sym,
|
|
})
|
|
|
|
# Build edges: same source paper
|
|
source_to_eqs = defaultdict(list)
|
|
for i, eq in enumerate(equations):
|
|
if eq["source"]:
|
|
source_to_eqs[eq["source"]].append(i)
|
|
for src, idxs in source_to_eqs.items():
|
|
if len(idxs) < 2:
|
|
continue
|
|
for i in range(len(idxs)):
|
|
for j in range(i+1, len(idxs)):
|
|
edges.append({
|
|
"source": equations[idxs[i]]["id"],
|
|
"target": equations[idxs[j]]["id"],
|
|
"type": "same_paper",
|
|
"paper": src,
|
|
})
|
|
|
|
# Deduplicate edges
|
|
seen = set()
|
|
unique_edges = []
|
|
for e in edges:
|
|
key = tuple(sorted([e["source"], e["target"]])) + (e["type"],)
|
|
if key not in seen:
|
|
seen.add(key)
|
|
unique_edges.append(e)
|
|
|
|
# Output
|
|
graph = {
|
|
"meta": {
|
|
"total_equations": len(equations),
|
|
"total_edges": len(unique_edges),
|
|
"databases": DBS,
|
|
},
|
|
"nodes": [{"id": eq["id"], "equation": eq["equation"][:200], "source": eq["source"], "category": eq["category"]} for eq in equations[:1000]],
|
|
"edges": unique_edges[:5000],
|
|
"symbol_frequency": dict(sorted(
|
|
{sym: len(idxs) for sym, idxs in symbol_to_eqs.items()}.items(),
|
|
key=lambda x: -x[1]
|
|
)[:100]),
|
|
}
|
|
|
|
out = Path("/home/allaun/Documents/Research Stack/3-Mathematical-Models/equation_forest_graph.json")
|
|
with open(out, "w") as f:
|
|
json.dump(graph, f, indent=2)
|
|
print(f"Wrote {out}")
|
|
print(f" Nodes: {len(graph['nodes'])}")
|
|
print(f" Edges: {len(graph['edges'])}")
|
|
print(f" Top symbols: {list(graph['symbol_frequency'].keys())[:10]}")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|