main: keep only what reproduces the manuscript; everything else lives on dev
Removed from main (all preserved on the dev branch): the arXiv build and
its sources, design documents (blueprint, results summary, review responses,
essay drafts), tasks/ and CLAUDE.md, the cover letter and reference tooling,
two unused manuscript figures, and every experiment that feeds no figure or
number in the paper: the collapse null, the sexual-vs-asexual lineage, the
NK speciation variant, the 0.5B single-seed LLM prototypes, the compose and
society experiments with their calibration and pilot runs, and their
configs, runners, tests, figure scripts and PBS jobs. Their result bundles
are moved to results/_archive/ (ignored) so the parquets stay on disk.
Also: plot_llm_speciation reads the s{seed}/ layout; the mating-breadth
plot writes under its bundle name; Makefile targets reduced to the kept
experiments; REPRODUCING.md and README point to dev for the rest.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y64o8FKP7rCuXzC48pxpMm
This commit is contained in:
parent
ab3dc10587
commit
6f8cef1ac5
292 changed files with 26 additions and 15590 deletions
|
|
@ -1,291 +0,0 @@
|
|||
"""Build a Zotero-importable library from the manuscript's reference list.
|
||||
|
||||
For each of the numbered references in paper/manuscript/main.md: take the DOI printed in the entry when
|
||||
there is one, otherwise ask Crossref for it by title (accepting only a high-scoring match whose title
|
||||
really is the same, checked by normalised comparison). Then fetch authoritative metadata for every
|
||||
resolved DOI by content negotiation against doi.org, which serves Crossref and DataCite alike, and
|
||||
write the result as CSL-JSON plus RIS.
|
||||
|
||||
Entries whose DOI cannot be resolved (pre-DOI literature, books, chapters) are reported and written
|
||||
from the manuscript's own metadata so nothing is silently dropped.
|
||||
|
||||
Usage: python paper/manuscript/build_zotero_library.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import time
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from pathlib import Path
|
||||
|
||||
MAIN = Path(__file__).resolve().parent / "main.md"
|
||||
OUT = Path(__file__).resolve().parent / "refs"
|
||||
MAILTO = "g.gilestro@imperial.ac.uk" # Crossref polite pool
|
||||
UA = f"LamarckianAI-refs/1.0 (mailto:{MAILTO})"
|
||||
|
||||
# Reference numbers whose sources predate DOIs or are books/chapters: never send these to Crossref
|
||||
# title search, because it returns confident nonsense for them.
|
||||
NO_DOI_EXPECTED = {33, 35, 39} # Jenkin 1867; Fisher 1930 (book); Templeton 1986 (chapter)
|
||||
|
||||
# DOIs the title search could not find and that were verified by hand against the publisher record.
|
||||
DOI_OVERRIDE = {
|
||||
17: "10.1038/s41562-023-01742-2", # Brinkmann et al., Machine culture (Nat. Hum. Behav.)
|
||||
64: "10.48550/arXiv.1805.06370", # Schwarz et al., Progress & Compress (no Crossref DOI)
|
||||
}
|
||||
|
||||
# The three genuinely pre-DOI sources, written out rather than parsed, so the Zotero records are
|
||||
# complete instead of merely non-empty.
|
||||
HAND_WRITTEN = {
|
||||
33: {"type": "article-journal", "title": "[Review of] The Origin of Species",
|
||||
"author": [{"given": "Fleeming", "family": "Jenkin"}],
|
||||
"container-title": "The North British Review", "volume": "46", "page": "277-318",
|
||||
"issued": {"date-parts": [[1867]]}},
|
||||
35: {"type": "book", "title": "The Genetical Theory of Natural Selection",
|
||||
"author": [{"given": "Ronald A.", "family": "Fisher"}],
|
||||
"publisher": "Clarendon Press", "publisher-place": "Oxford",
|
||||
"issued": {"date-parts": [[1930]]}},
|
||||
39: {"type": "chapter", "title": "Coadaptation and outbreeding depression",
|
||||
"author": [{"given": "Alan R.", "family": "Templeton"}],
|
||||
"editor": [{"given": "Michael E.", "family": "Soulé"}],
|
||||
"container-title": "Conservation Biology: The Science of Scarcity and Diversity",
|
||||
"publisher": "Sinauer Associates", "publisher-place": "Sunderland, MA",
|
||||
"page": "105-116", "issued": {"date-parts": [[1986]]}},
|
||||
}
|
||||
|
||||
|
||||
def get(url: str, accept: str | None = None, tries: int = 3) -> bytes | None:
|
||||
req = urllib.request.Request(url, headers={"User-Agent": UA})
|
||||
if accept:
|
||||
req.add_header("Accept", accept)
|
||||
for i in range(tries):
|
||||
try:
|
||||
with urllib.request.urlopen(req, timeout=30) as r:
|
||||
return r.read()
|
||||
except Exception as e: # noqa: BLE001
|
||||
if i == tries - 1:
|
||||
print(f" ! {type(e).__name__}: {str(e)[:80]}", file=sys.stderr)
|
||||
time.sleep(1.5 * (i + 1))
|
||||
return None
|
||||
|
||||
|
||||
def parse_refs() -> list[tuple[int, str]]:
|
||||
refs = MAIN.read_text().split("## References")[1]
|
||||
out = []
|
||||
for line in refs.splitlines():
|
||||
if m := re.match(r"^(\d+)\. (.*)$", line):
|
||||
out.append((int(m.group(1)), m.group(2).strip()))
|
||||
return out
|
||||
|
||||
|
||||
def strip_md(s: str) -> str:
|
||||
return re.sub(r"[*_`]", "", s)
|
||||
|
||||
|
||||
def guess_title(entry: str) -> str:
|
||||
"""The title is the run of text between the author list and the italic venue or the year."""
|
||||
t = strip_md(entry)
|
||||
t = re.sub(r"\s*https?://\S+$", "", t).strip()
|
||||
# drop the leading author list: everything up to the last ", " before the title is unreliable,
|
||||
# so instead cut after the first ", " that follows an initial-style name block
|
||||
m = re.match(r"^((?:[A-ZÀ-Þ]\.\s*)+[^,]+,\s*)+", t)
|
||||
rest = t[m.end():] if m else t
|
||||
rest = re.sub(r"^et al\.,\s*", "", rest)
|
||||
# the title ends at the venue (". *Venue*") or at " arXiv [Preprint]" or " (Year)"
|
||||
rest = re.split(r"\.\s+(?:arXiv \[Preprint\]|[A-Z][a-zA-Z.\s&]*\*|Proc\.|Int\.|Adv\.|Conf\.|Nat\.|Trans\.)", rest)[0]
|
||||
rest = re.split(r"\s*\(\d{4}\)", rest)[0]
|
||||
return rest.strip(" .,")
|
||||
|
||||
|
||||
def norm(s: str) -> str:
|
||||
return re.sub(r"[^a-z0-9]", "", s.lower())
|
||||
|
||||
|
||||
def crossref_by_title(title: str, year: str | None) -> tuple[str | None, str]:
|
||||
q = urllib.parse.urlencode({"query.bibliographic": title, "rows": 5, "mailto": MAILTO})
|
||||
raw = get(f"https://api.crossref.org/works?{q}")
|
||||
if not raw:
|
||||
return None, "crossref unreachable"
|
||||
items = json.loads(raw).get("message", {}).get("items", [])
|
||||
tn = norm(title)
|
||||
for it in items:
|
||||
cand = (it.get("title") or [""])[0]
|
||||
cn = norm(cand)
|
||||
if not cn:
|
||||
continue
|
||||
# accept only a genuine title match, not merely a high Crossref score
|
||||
if cn.startswith(tn[:60]) or tn.startswith(cn[:60]):
|
||||
return it.get("DOI"), f"matched: {cand[:70]}"
|
||||
return None, f"no title match (best: {(items[0].get('title') or [''])[0][:60] if items else '-'})"
|
||||
|
||||
|
||||
def csl_from_doi(doi: str) -> dict | None:
|
||||
raw = get(f"https://doi.org/{urllib.parse.quote(doi)}",
|
||||
accept="application/vnd.citationstyles.csl+json")
|
||||
if not raw:
|
||||
return None
|
||||
try:
|
||||
return json.loads(raw)
|
||||
except json.JSONDecodeError:
|
||||
return None
|
||||
|
||||
|
||||
# ---------------------------------------------------------------- fallback CSL from the manuscript
|
||||
def manual_csl(num: int, entry: str) -> dict:
|
||||
t = strip_md(entry)
|
||||
year = (re.search(r"\((\d{4})\)", t) or re.search(r"(\d{4})", t))
|
||||
authors = []
|
||||
m = re.match(r"^((?:[A-ZÀ-Þ]\.(?:\s*[A-ZÀ-Þ]\.)*\s+[^,]+,\s*)+)", t)
|
||||
if m:
|
||||
for name in re.findall(r"([A-ZÀ-Þ]\.(?:\s*[A-ZÀ-Þ]\.)*)\s+([^,]+)", m.group(1)):
|
||||
authors.append({"given": name[0].strip(), "family": name[1].strip()})
|
||||
venue = re.search(r"\*([^*]+)\*", entry)
|
||||
vol = re.search(r"\*\*(\d+)\*\*", entry)
|
||||
pages = re.search(r"\*\*\d+\*\*,\s*([\d–\-]+)", entry)
|
||||
return {k: v for k, v in {
|
||||
"id": f"ref{num}",
|
||||
"type": "book" if "Press)" in t or "Sinauer" in t else "article-journal",
|
||||
"title": guess_title(entry),
|
||||
"author": authors or None,
|
||||
"container-title": venue.group(1) if venue else None,
|
||||
"volume": vol.group(1) if vol else None,
|
||||
"page": pages.group(1).replace("–", "-") if pages else None,
|
||||
"issued": {"date-parts": [[int(year.group(1))]]} if year else None,
|
||||
"note": f"manuscript reference {num}; no DOI",
|
||||
}.items() if v is not None}
|
||||
|
||||
|
||||
def clean_text(s: str) -> str:
|
||||
"""Publisher abstracts arrive with JATS tags, HTML entities, and hard line breaks; RIS is a
|
||||
line-oriented format, so every field has to end up as one clean line."""
|
||||
import html
|
||||
|
||||
s = re.sub(r"<[^>]+>", " ", s) # JATS/HTML tags
|
||||
s = html.unescape(s)
|
||||
return re.sub(r"\s+", " ", s).strip()
|
||||
|
||||
|
||||
def clean_csl(c: dict) -> dict:
|
||||
for k, v in list(c.items()):
|
||||
if isinstance(v, str):
|
||||
c[k] = clean_text(v)
|
||||
elif isinstance(v, list) and v and isinstance(v[0], str):
|
||||
c[k] = [clean_text(x) for x in v]
|
||||
doi = c.get("DOI", "")
|
||||
if doi.lower().startswith("10.48550/arxiv."):
|
||||
# DataCite returns these uppercased and with no venue; restore the canonical DOI casing and
|
||||
# give Zotero something to show in the publication field instead of a blank.
|
||||
arxiv_id = doi.split(".", 2)[-1]
|
||||
c["DOI"] = f"10.48550/arXiv.{arxiv_id}"
|
||||
c["container-title"] = "arXiv"
|
||||
c["number"] = f"arXiv:{arxiv_id}"
|
||||
c["genre"] = "preprint"
|
||||
return c
|
||||
|
||||
|
||||
# Crossref reports its own type vocabulary alongside real CSL types; map both.
|
||||
CSL2RIS_EXTRA = {"journal-article": "JOUR", "book-chapter": "CHAP", "proceedings-article": "CPAPER",
|
||||
"posted-content": "JOUR", "book-section": "CHAP", "monograph": "BOOK"}
|
||||
|
||||
|
||||
CSL2RIS = {"article-journal": "JOUR", "paper-conference": "CPAPER", "chapter": "CHAP",
|
||||
"book": "BOOK", "article": "JOUR", "posted-content": "JOUR", "report": "RPRT",
|
||||
"dataset": "DATA", "thesis": "THES"}
|
||||
|
||||
|
||||
def ris_type(c: dict) -> str:
|
||||
t = c.get("type", "")
|
||||
return CSL2RIS.get(t) or CSL2RIS_EXTRA.get(t) or "JOUR"
|
||||
|
||||
|
||||
def to_ris(c: dict, num: int) -> str:
|
||||
L = [f"TY - {ris_type(c)}"]
|
||||
for a in c.get("author") or []:
|
||||
fam, giv = a.get("family", ""), a.get("given", "")
|
||||
L.append(f"AU - {fam}, {giv}".rstrip(", ") if fam else f"AU - {a.get('literal', '')}")
|
||||
ttl = c.get("title")
|
||||
if isinstance(ttl, list):
|
||||
ttl = ttl[0]
|
||||
if ttl:
|
||||
L.append(f"TI - {ttl}")
|
||||
ct = c.get("container-title")
|
||||
if isinstance(ct, list):
|
||||
ct = ct[0] if ct else None
|
||||
if ct:
|
||||
L.append(f"{'BT' if ris_type(c) == 'CHAP' else 'T2'} - {ct}")
|
||||
for ed in c.get("editor") or []:
|
||||
L.append(f"A2 - {ed.get('family', '')}, {ed.get('given', '')}".rstrip(", "))
|
||||
if c.get("number"):
|
||||
L.append(f"AN - {c['number']}")
|
||||
if c.get("publisher-place"):
|
||||
L.append(f"CY - {c['publisher-place']}")
|
||||
parts = (c.get("issued") or {}).get("date-parts") or [[]]
|
||||
if parts and parts[0]:
|
||||
L.append(f"PY - {parts[0][0]}")
|
||||
for key, tag in (("volume", "VL"), ("issue", "IS"), ("publisher", "PB"), ("DOI", "DO"),
|
||||
("URL", "UR"), ("abstract", "AB")):
|
||||
if c.get(key):
|
||||
L.append(f"{tag} - {c[key]}")
|
||||
if c.get("page"):
|
||||
pg = str(c["page"]).replace("–", "-").split("-")
|
||||
L.append(f"SP - {pg[0]}")
|
||||
if len(pg) > 1:
|
||||
L.append(f"EP - {pg[-1]}")
|
||||
L.append(f"N1 - {c.get('note') or f'Manuscript reference {num}'}")
|
||||
L.append("ER - \n")
|
||||
return "\n".join(L)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
refs = parse_refs()
|
||||
print(f"{len(refs)} references parsed\n")
|
||||
csls, report = [], []
|
||||
for num, entry in refs:
|
||||
doi = None
|
||||
if num in HAND_WRITTEN:
|
||||
c = dict(HAND_WRITTEN[num], id=f"ref{num}", note=f"Manuscript reference {num}; predates DOIs")
|
||||
csls.append(c)
|
||||
report.append((num, "HAND (pre-DOI source)", c["title"][:64], "written by hand"))
|
||||
print(f" {num:3d} {'HAND (pre-DOI source)':52s} {c['title'][:56]}")
|
||||
continue
|
||||
if num in DOI_OVERRIDE:
|
||||
doi, src = DOI_OVERRIDE[num], "verified by hand"
|
||||
elif m := re.search(r"doi\.org/(10\.\S+?)\.?$", entry):
|
||||
doi = m.group(1)
|
||||
src = "in manuscript"
|
||||
elif num not in NO_DOI_EXPECTED:
|
||||
title = guess_title(entry)
|
||||
yr = re.search(r"\((\d{4})\)", entry)
|
||||
doi, why = crossref_by_title(title, yr.group(1) if yr else None)
|
||||
src = f"crossref ({why})"
|
||||
time.sleep(0.3)
|
||||
else:
|
||||
src = "pre-DOI / book — not searched"
|
||||
|
||||
c = csl_from_doi(doi) if doi else None
|
||||
if c:
|
||||
c["id"] = f"ref{num}"
|
||||
c["note"] = f"Manuscript reference {num}"
|
||||
status = f"OK {doi}"
|
||||
else:
|
||||
c = manual_csl(num, entry)
|
||||
status = f"MANUAL ({src})" if not doi else f"MANUAL (DOI {doi} would not resolve)"
|
||||
csls.append(c)
|
||||
report.append((num, status, (c.get('title') or '')[:64], src))
|
||||
print(f" {num:3d} {status:52s} {(c.get('title') or '')[:56]}")
|
||||
time.sleep(0.2)
|
||||
|
||||
csls = [clean_csl(c) for c in csls]
|
||||
(OUT / "references.json").write_text(json.dumps(csls, indent=1, ensure_ascii=False))
|
||||
(OUT / "references.ris").write_text("".join(to_ris(c, n) for (n, _), c in zip(refs, csls)))
|
||||
ok = sum(1 for _, s, _, _ in report if s.startswith("OK"))
|
||||
print(f"\nresolved from DOI: {ok}/{len(refs)} manual: {len(refs)-ok}")
|
||||
(OUT / "report.txt").write_text("\n".join(f"{n}\t{s}\t{t}\t{src}" for n, s, t, src in report))
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
|
|
@ -1,39 +0,0 @@
|
|||
Giorgio F. Gilestro
|
||||
Department of Life Sciences, Imperial College London
|
||||
giorgio@gilest.ro
|
||||
|
||||
[Date]
|
||||
|
||||
Dear Editor,
|
||||
|
||||
Please consider the enclosed manuscript, "The evolution of sex for artificial intelligence: a population-genetic framework for multigenerational model populations", for publication as an Article in *Nature Machine Intelligence*.
|
||||
|
||||
Machine learning has become a population process. Public repositories hold millions of models, most of them fine-tunes, distillations or weight merges of a few ancestors; models learn from the output of earlier models; and merging, now mainstream practice with standard tooling, is described in its own literature with the words crossover, mutation and mate choice. A population whose members inherit from one another, recombine and retransmit is an evolving population in the technical sense, and the branch of biology built for that situation is the population genetics of sexual reproduction. That training on model output is genetic drift, with model collapse as its signature, has been established several times over. This paper takes the next step and develops the mechanisms population genetics offers for sustaining a population against drift (immigration, recombination, selection, population structure), and the point where they fail (reproductive isolation), and tests each of them in a chain from closed forms to trained networks to language models.
|
||||
|
||||
Four measurements are new, and each was chosen because the existing experimental designs could not make it.
|
||||
|
||||
First, a six-generation population of language models in which three lineages each learn a new skill every generation and then choose whether, and with whom, to merge. Merging has been iterated before, in evolutionary pools of fixed parents and in continual streams folded into one model, but never while the lineages were also learning. The population shows that obligate merging collapses once partners hold conflicting conventions (accuracy 0.65 to 0.27), that a merge each lineage may decline, or a fixed early stop, avoids the collapse at no cost against never merging, and that merging with one's own ancestor is safer than merging with a contemporary in every seed. A second curriculum decoupling partner complementarity from generation shows that declines track generation, which corrects an interpretation the first curriculum invited.
|
||||
|
||||
Second, model speciation as a named and tested question. Using the permutation-and-rescaling alignment of Git Re-Basin and REPAIR, the merge barrier between networks is separated into the part alignment removes and the part it cannot. Conflicting label maps leave a residual alignment does not touch, while six times the base training on non-conflicting tasks produces no isolation at all and the strongest rescue-by-merging in the paper, against the expectation that specialisation by itself erodes mergeability.
|
||||
|
||||
Third, a pre-merge predictive test on 39 language-model parent pairs across three decorrelated axes (conflict, compatible overlap, duration). Functional disagreement between parents predicts merge damage out of sample where LoRA-weight cosine and distance do not, in agreement with recent correlational reports. The control that matters is new: on a grid that varies conflict and shared training data together, weight cosine is the best predictor (ρ = 0.60), and adding overlap without conflict collapses it to 0.03. Any weight-geometry predictor validated on such a grid is reading the shared data, which bears on the merge-prediction literature independently of the biology.
|
||||
|
||||
Fourth, a conservation law for blending inheritance. Refitting a child on the average of several parents' outputs carries a rare capability across a generation no better than inheriting from one parent, to first order, so the gain of having several parents is realised only by operators that keep each parent's strongest contribution. The law fixes the null against which every recombination operator is judged and predicted the headroom rule measured in language models at two scales: routing and offspring selection beat the weight average wherever that average falls short of attainable performance (hard tasks at 7B, every seed), and add nothing where it does not.
|
||||
|
||||
Around these sit results that place the framework in the existing literature: a closed-form grounding equilibrium and per-item floor that agree with the fresh-data stability theorems and with the finding that absolute real-sample counts matter more than proportions; the transfer of every drift sign to trained networks with a measured, architecture-specific estimator bias; and a four-arm ablation of a composed population. Two refinements the framework proposed were not supported, and the paper says so.
|
||||
|
||||
I am submitting to *Nature Machine Intelligence* because the readers who make the decisions this paper prices (how much verified data a synthetic pipeline needs, whether to merge or route, when to stop merging, how to detect an incompatible pair before paying for the merge) are this journal's readers, and because the journal has already published evolutionary model merging as a research direction (Akiba et al., 2025). The paper gives that direction its theory and its failure modes. What biology receives in return is a model system where every genotype, environment and mating decision is observable and manipulable, so the paper should also interest the evolutionary biologists among your readership.
|
||||
|
||||
All code, configurations, seeds, results artefacts and a one-command reproduction script will be deposited openly with an archived DOI on publication; every figure regenerates from committed artefacts without re-simulation. The manuscript is not under consideration elsewhere and has not been published in any form. [A preprint has been / will be posted to arXiv.] I am the sole author and declare no competing interests.
|
||||
|
||||
Suggested referees:
|
||||
- [Name, affiliation, email] (model merging)
|
||||
- [Name, affiliation, email] (model collapse / synthetic data theory)
|
||||
- [Name, affiliation, email] (population genetics of recombination and speciation)
|
||||
- [Name, affiliation, email] (continual learning)
|
||||
|
||||
Excluded referees: [none / names].
|
||||
|
||||
Yours sincerely,
|
||||
|
||||
Giorgio F. Gilestro
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -1,80 +0,0 @@
|
|||
1 OK 10.48550/arXiv.2508.06811 Anatomy of a Machine Learning Ecosystem: 2 Million Models on Hug in manuscript
|
||||
2 OK 10.48550/arXiv.2405.18432 Unsupervised Model Tree Heritage Recovery in manuscript
|
||||
3 OK 10.48550/arXiv.2402.00699 PeaTMOSS: A Dataset and Initial Analysis of Pre-Trained Models i in manuscript
|
||||
4 OK 10.48550/arXiv.2306.01708 TIES-Merging: Resolving Interference When Merging Models in manuscript
|
||||
5 OK 10.1038/s42256-024-00975-8 Evolutionary optimization of model merging recipes crossref (matched: Evolutionary optimization of model merging recipes)
|
||||
6 OK 10.48550/arXiv.2403.13257 Arcee's MergeKit: A Toolkit for Merging Large Language Models in manuscript
|
||||
7 OK 10.48550/arXiv.2408.07666 Model Merging in LLMs, MLLMs, and Beyond: Methods, Theories, App in manuscript
|
||||
8 OK 10.48550/arXiv.2503.01155 Nature-Inspired Population-Based Evolution of Large Language Mod in manuscript
|
||||
9 OK 10.48550/arXiv.2508.16204 Competition and Attraction Improve Model Fusion in manuscript
|
||||
10 OK 10.48550/arXiv.2501.05707 Multiagent Finetuning: Self Improvement with Diverse Reasoning C in manuscript
|
||||
11 OK 10.48550/arXiv.2406.11704 Nemotron-4 340B Technical Report in manuscript
|
||||
12 OK 10.48550/arXiv.2412.08905 Phi-4 Technical Report in manuscript
|
||||
13 OK 10.48550/arXiv.2212.10560 Self-Instruct: Aligning Language Models with Self-Generated Inst in manuscript
|
||||
14 OK 10.48550/arXiv.2401.05749 A Shocking Amount of the Web is Machine Translated: Insights fro in manuscript
|
||||
15 OK 10.48550/arXiv.2403.07183 Monitoring AI-Modified Content at Scale: A Case Study on the Imp in manuscript
|
||||
16 OK 10.48550/arXiv.2211.04325 Will we run out of data? Limits of LLM scaling based on human-ge in manuscript
|
||||
17 OK 10.1038/s41562-023-01742-2 Machine culture verified by hand
|
||||
18 OK 10.48550/arXiv.2304.03442 Generative Agents: Interactive Simulacra of Human Behavior in manuscript
|
||||
19 OK 10.48550/arXiv.2402.01680 Large Language Model based Multi-Agents: A Survey of Progress an in manuscript
|
||||
20 OK 10.48550/arXiv.2509.10147 Virtual Agent Economies in manuscript
|
||||
21 OK 10.1038/s41586-024-07566-y AI models collapse when trained on recursively generated data crossref (matched: AI models collapse when trained on recursively generated data)
|
||||
22 OK 10.1371/journal.pcbi.1002510 Structural Drift: The Population Dynamics of Sequential Learning crossref (matched: Structural Drift: The Population Dynamics of Sequential Learning)
|
||||
23 OK 10.48550/arXiv.2604.08554 Drift and selection in LLM text ecosystems in manuscript
|
||||
24 OK 10.48550/arXiv.2509.20101 First-Extinction Law for Resampling Processes in manuscript
|
||||
25 OK 10.48550/arXiv.2407.17493 Model Collapse in the Self-Consuming Chain of Diffusion Finetuni in manuscript
|
||||
26 OK 10.1016/s0079-7421(08)60536-8 Catastrophic Interference in Connectionist Networks: The Sequent crossref (matched: Catastrophic Interference in Connectionist Networks: The Sequential Le)
|
||||
27 OK 10.1016/s1364-6613(99)01294-2 Catastrophic forgetting in connectionist networks crossref (matched: Catastrophic forgetting in connectionist networks)
|
||||
28 OK 10.1016/0027-5107(64)90047-8 The relation of recombination to mutational advance crossref (matched: The relation of recombination to mutational advance)
|
||||
29 OK 10.48550/arXiv.2510.16657 Escaping Model Collapse via Synthetic Data Verification: Near-te in manuscript
|
||||
30 OK 10.48550/arXiv.2404.01413 Is Model Collapse Inevitable? Breaking the Curse of Recursion by in manuscript
|
||||
31 OK 10.1093/genetics/16.2.97 EVOLUTION IN MENDELIAN POPULATIONS crossref (matched: EVOLUTION IN MENDELIAN POPULATIONS)
|
||||
32 OK 10.1046/j.1523-1739.1996.10061509.x The One‐Migrant‐per‐Generation Rule in Conservation and Manageme crossref (matched: The One‐Migrant‐per‐Generation Rule in Conservation and Management)
|
||||
33 HAND (pre-DOI source) [Review of] The Origin of Species written by hand
|
||||
34 OK 10.48550/arXiv.2411.02207 Collective Model Intelligence Requires Compatible Specialization in manuscript
|
||||
35 HAND (pre-DOI source) The Genetical Theory of Natural Selection written by hand
|
||||
36 OK 10.1086/280418 Some Genetic Aspects of Sex crossref (matched: Some Genetic Aspects of Sex)
|
||||
37 OK 10.48550/arXiv.2106.09685 LoRA: Low-Rank Adaptation of Large Language Models in manuscript
|
||||
38 OK 10.1016/s0022-5193(87)80029-2 Towards a general theory of adaptive walks on rugged landscapes crossref (matched: Towards a general theory of adaptive walks on rugged landscapes)
|
||||
39 HAND (pre-DOI source) Coadaptation and outbreeding depression written by hand
|
||||
40 OK 10.1162/evco_a_00025 Abandoning Objectives: Evolution Through the Search for Novelty crossref (matched: Abandoning Objectives: Evolution Through the Search for Novelty Alone)
|
||||
41 OK 10.48550/arXiv.2503.05683 WikiBigEdit: Understanding the Limits of Lifelong Knowledge Edit in manuscript
|
||||
42 OK 10.48550/arXiv.2502.04390 In Praise of Stubbornness: An Empirical Case for Cognitive-Disso in manuscript
|
||||
43 OK 10.48550/arXiv.2607.09202 Interference and Retention in Continual Learning in manuscript
|
||||
44 OK 10.1017/s0016672300033140 A general model for the evolution of recombination crossref (matched: A general model for the evolution of recombination)
|
||||
45 OK 10.1006/tpbi.1997.1301 Deleterious Mutations, Variable Epistatic Interactions, and the crossref (matched: Deleterious Mutations, Variable Epistatic Interactions, and the Evolut)
|
||||
46 OK 10.1038/nrg761 Resolving the paradox of sex and recombination crossref (matched: Resolving the paradox of sex and recombination)
|
||||
47 OK 10.1093/genetics/117.3.559 Selection, Generalized Transmission and the Evolution of Modifie crossref (matched: Selection, Generalized Transmission and the Evolution of Modifier Gene)
|
||||
48 OK 10.1093/genetics/139.4.1805 The population genetics of speciation: the evolution of hybrid i crossref (matched: The population genetics of speciation: the evolution of hybrid incompa)
|
||||
49 OK 10.1111/j.0014-3820.2001.tb00628.x THE EVOLUTION OF POSTZYGOTIC ISOLATION: ACCUMULATING DOBZHANSKY- crossref (matched: THE EVOLUTION OF POSTZYGOTIC ISOLATION: ACCUMULATING DOBZHANSKY-MULLER)
|
||||
50 OK 10.48550/arXiv.2209.04836 Git Re-Basin: Merging Models modulo Permutation Symmetries in manuscript
|
||||
51 OK 10.48550/arXiv.2606.23607 Scaling Linear Mode Connectivity and Merging to Billion Paramete in manuscript
|
||||
52 OK 10.48550/arXiv.2410.12766 The Non-Local Model Merging Problem: Permutation Symmetries and in manuscript
|
||||
53 OK 10.48550/arXiv.2607.11997 Are we Merging the Right Models? Impact of Expert Training Durat in manuscript
|
||||
54 OK 10.48550/arXiv.2601.22285 Demystifying Mergeability: Interpretable Properties to Predict M in manuscript
|
||||
55 OK 10.48550/arXiv.2205.12393 Fine-tuned Language Models are Continual Learners in manuscript
|
||||
56 OK 10.48550/arXiv.2403.08763 Simple and Scalable Strategies to Continually Pre-train Large La in manuscript
|
||||
57 OK 10.1080/09540099550039318 Catastrophic Forgetting, Rehearsal and Pseudorehearsal crossref (matched: Catastrophic Forgetting, Rehearsal and Pseudorehearsal)
|
||||
58 OK 10.48550/arXiv.1705.08690 Continual Learning with Deep Generative Replay in manuscript
|
||||
59 OK 10.48550/arXiv.2406.07515 Beyond Model Collapse: Scaling Up with Synthesized Data Requires in manuscript
|
||||
60 OK 10.48550/arXiv.1606.04671 Progressive Neural Networks in manuscript
|
||||
61 OK 10.48550/arXiv.2405.09673 LoRA Learns Less and Forgets Less in manuscript
|
||||
62 OK 10.1037/0033-295x.102.3.419 Why there are complementary learning systems in the hippocampus crossref (matched: Why there are complementary learning systems in the hippocampus and ne)
|
||||
63 OK 10.1016/j.tics.2016.05.004 What Learning Systems do Intelligent Agents Need? Complementary crossref (matched: What Learning Systems do Intelligent Agents Need? Complementary Learni)
|
||||
64 OK 10.48550/arXiv.1805.06370 Progress & Compress: A scalable framework for continual lear verified by hand
|
||||
65 OK 10.48550/arXiv.2212.04089 Editing Models with Task Arithmetic in manuscript
|
||||
66 OK 10.48550/arXiv.2407.06322 MagMax: Leveraging Model Merging for Seamless Continual Learning in manuscript
|
||||
67 OK 10.48550/arXiv.2407.08699 Mitigating Catastrophic Forgetting in Language Transfer via Mode in manuscript
|
||||
68 OK 10.48550/arXiv.2412.06712 How to Merge Your Multimodal Models Over Time? in manuscript
|
||||
69 OK 10.48550/arXiv.1812.05159 An Empirical Study of Example Forgetting during Deep Neural Netw in manuscript
|
||||
70 OK 10.48550/arXiv.2211.08411 Large Language Models Struggle to Learn Long-Tail Knowledge in manuscript
|
||||
71 OK 10.48550/arXiv.2210.00266 Long-Tailed Class Incremental Learning in manuscript
|
||||
72 OK 10.48550/arXiv.2309.10105 Understanding Catastrophic Forgetting in Language Models via Imp in manuscript
|
||||
73 OK 10.48550/arXiv.2311.03099 Language Models are Super Mario: Absorbing Abilities from Homolo in manuscript
|
||||
74 OK 10.48550/arXiv.2203.05482 Model soups: averaging weights of multiple fine-tuned models imp in manuscript
|
||||
75 OK 10.48550/arXiv.2603.09463 An Empirical Study and Theoretical Explanation on Task-Level Mod in manuscript
|
||||
76 OK 10.48550/arXiv.2506.14126 From Memorization to Parameter Interference: How Overtraining Ex in manuscript
|
||||
77 OK 10.1145/2934662 Sex as an algorithm crossref (matched: Sex as an algorithm)
|
||||
78 OK 10.48550/arXiv.2311.09807 The Curious Decline of Linguistic Diversity: Training Language M in manuscript
|
||||
79 OK 10.48550/arXiv.2309.05196 Does Writing with Language Models Reduce Content Diversity? in manuscript
|
||||
80 OK 10.1126/sciadv.adn5290 Generative AI enhances individual creativity but reduces the col crossref (matched: Generative AI enhances individual creativity but reduces the collectiv)
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
1 OK 10.48550/arXiv.2508.06811 Anatomy of a Machine Learning Ecosystem: 2 Million Models on Hug in manuscript
|
||||
2 OK 10.48550/arXiv.2405.18432 Unsupervised Model Tree Heritage Recovery in manuscript
|
||||
3 OK 10.48550/arXiv.2402.00699 PeaTMOSS: A Dataset and Initial Analysis of Pre-Trained Models i in manuscript
|
||||
4 OK 10.48550/arXiv.2306.01708 TIES-Merging: Resolving Interference When Merging Models in manuscript
|
||||
5 OK 10.1038/s42256-024-00975-8 Evolutionary optimization of model merging recipes crossref (matched: Evolutionary optimization of model merging recipes)
|
||||
6 OK 10.48550/arXiv.2403.13257 Arcee's MergeKit: A Toolkit for Merging Large Language Models in manuscript
|
||||
7 OK 10.48550/arXiv.2408.07666 Model Merging in LLMs, MLLMs, and Beyond: Methods, Theories, App in manuscript
|
||||
8 OK 10.48550/arXiv.2503.01155 Nature-Inspired Population-Based Evolution of Large Language Mod in manuscript
|
||||
9 OK 10.48550/arXiv.2508.16204 Competition and Attraction Improve Model Fusion in manuscript
|
||||
10 OK 10.48550/arXiv.2501.05707 Multiagent Finetuning: Self Improvement with Diverse Reasoning C in manuscript
|
||||
11 OK 10.48550/arXiv.2406.11704 Nemotron-4 340B Technical Report in manuscript
|
||||
12 OK 10.48550/arXiv.2412.08905 Phi-4 Technical Report in manuscript
|
||||
13 OK 10.48550/arXiv.2212.10560 Self-Instruct: Aligning Language Models with Self-Generated Inst in manuscript
|
||||
14 OK 10.48550/arXiv.2401.05749 A Shocking Amount of the Web is Machine Translated: Insights fro in manuscript
|
||||
15 OK 10.48550/arXiv.2403.07183 Monitoring AI-Modified Content at Scale: A Case Study on the Imp in manuscript
|
||||
16 OK 10.48550/arXiv.2211.04325 Will we run out of data? Limits of LLM scaling based on human-ge in manuscript
|
||||
17 OK 10.1038/s41562-023-01742-2 Machine culture verified by hand
|
||||
18 OK 10.48550/arXiv.2304.03442 Generative Agents: Interactive Simulacra of Human Behavior in manuscript
|
||||
19 OK 10.48550/arXiv.2402.01680 Large Language Model based Multi-Agents: A Survey of Progress an in manuscript
|
||||
20 OK 10.48550/arXiv.2509.10147 Virtual Agent Economies in manuscript
|
||||
21 OK 10.1038/s41586-024-07566-y AI models collapse when trained on recursively generated data crossref (matched: AI models collapse when trained on recursively generated data)
|
||||
22 OK 10.1371/journal.pcbi.1002510 Structural Drift: The Population Dynamics of Sequential Learning crossref (matched: Structural Drift: The Population Dynamics of Sequential Learning)
|
||||
23 OK 10.48550/arXiv.2604.08554 Drift and selection in LLM text ecosystems in manuscript
|
||||
24 OK 10.48550/arXiv.2509.20101 First-Extinction Law for Resampling Processes in manuscript
|
||||
25 OK 10.48550/arXiv.2407.17493 Model Collapse in the Self-Consuming Chain of Diffusion Finetuni in manuscript
|
||||
26 OK 10.1016/s0079-7421(08)60536-8 Catastrophic Interference in Connectionist Networks: The Sequent crossref (matched: Catastrophic Interference in Connectionist Networks: The Sequential Le)
|
||||
27 OK 10.1016/s1364-6613(99)01294-2 Catastrophic forgetting in connectionist networks crossref (matched: Catastrophic forgetting in connectionist networks)
|
||||
28 OK 10.1016/0027-5107(64)90047-8 The relation of recombination to mutational advance crossref (matched: The relation of recombination to mutational advance)
|
||||
29 OK 10.48550/arXiv.2510.16657 Escaping Model Collapse via Synthetic Data Verification: Near-te in manuscript
|
||||
30 OK 10.48550/arXiv.2404.01413 Is Model Collapse Inevitable? Breaking the Curse of Recursion by in manuscript
|
||||
31 OK 10.1093/genetics/16.2.97 EVOLUTION IN MENDELIAN POPULATIONS crossref (matched: EVOLUTION IN MENDELIAN POPULATIONS)
|
||||
32 OK 10.1046/j.1523-1739.1996.10061509.x The One‐Migrant‐per‐Generation Rule in Conservation and Manageme crossref (matched: The One‐Migrant‐per‐Generation Rule in Conservation and Management)
|
||||
33 HAND (pre-DOI source) [Review of] The Origin of Species written by hand
|
||||
34 OK 10.48550/arXiv.2411.02207 Collective Model Intelligence Requires Compatible Specialization in manuscript
|
||||
35 HAND (pre-DOI source) The Genetical Theory of Natural Selection written by hand
|
||||
36 OK 10.1086/280418 Some Genetic Aspects of Sex crossref (matched: Some Genetic Aspects of Sex)
|
||||
37 OK 10.48550/arXiv.2106.09685 LoRA: Low-Rank Adaptation of Large Language Models in manuscript
|
||||
38 OK 10.1016/s0022-5193(87)80029-2 Towards a general theory of adaptive walks on rugged landscapes crossref (matched: Towards a general theory of adaptive walks on rugged landscapes)
|
||||
39 HAND (pre-DOI source) Coadaptation and outbreeding depression written by hand
|
||||
40 OK 10.1162/evco_a_00025 Abandoning Objectives: Evolution Through the Search for Novelty crossref (matched: Abandoning Objectives: Evolution Through the Search for Novelty Alone)
|
||||
41 OK 10.48550/arXiv.2503.05683 WikiBigEdit: Understanding the Limits of Lifelong Knowledge Edit in manuscript
|
||||
42 OK 10.48550/arXiv.2502.04390 In Praise of Stubbornness: An Empirical Case for Cognitive-Disso in manuscript
|
||||
43 OK 10.48550/arXiv.2607.09202 Interference and Retention in Continual Learning in manuscript
|
||||
44 OK 10.1017/s0016672300033140 A general model for the evolution of recombination crossref (matched: A general model for the evolution of recombination)
|
||||
45 OK 10.1006/tpbi.1997.1301 Deleterious Mutations, Variable Epistatic Interactions, and the crossref (matched: Deleterious Mutations, Variable Epistatic Interactions, and the Evolut)
|
||||
46 OK 10.1038/nrg761 Resolving the paradox of sex and recombination crossref (matched: Resolving the paradox of sex and recombination)
|
||||
47 OK 10.1093/genetics/117.3.559 Selection, Generalized Transmission and the Evolution of Modifie crossref (matched: Selection, Generalized Transmission and the Evolution of Modifier Gene)
|
||||
48 OK 10.1093/genetics/139.4.1805 The population genetics of speciation: the evolution of hybrid i crossref (matched: The population genetics of speciation: the evolution of hybrid incompa)
|
||||
49 OK 10.1111/j.0014-3820.2001.tb00628.x THE EVOLUTION OF POSTZYGOTIC ISOLATION: ACCUMULATING DOBZHANSKY- crossref (matched: THE EVOLUTION OF POSTZYGOTIC ISOLATION: ACCUMULATING DOBZHANSKY-MULLER)
|
||||
50 OK 10.48550/arXiv.2209.04836 Git Re-Basin: Merging Models modulo Permutation Symmetries in manuscript
|
||||
51 OK 10.48550/arXiv.2606.23607 Scaling Linear Mode Connectivity and Merging to Billion Paramete in manuscript
|
||||
52 OK 10.48550/arXiv.2410.12766 The Non-Local Model Merging Problem: Permutation Symmetries and in manuscript
|
||||
53 OK 10.48550/arXiv.2607.11997 Are we Merging the Right Models? Impact of Expert Training Durat in manuscript
|
||||
54 OK 10.48550/arXiv.2601.22285 Demystifying Mergeability: Interpretable Properties to Predict M in manuscript
|
||||
55 OK 10.48550/arXiv.2205.12393 Fine-tuned Language Models are Continual Learners in manuscript
|
||||
56 OK 10.48550/arXiv.2403.08763 Simple and Scalable Strategies to Continually Pre-train Large La in manuscript
|
||||
57 OK 10.1080/09540099550039318 Catastrophic Forgetting, Rehearsal and Pseudorehearsal crossref (matched: Catastrophic Forgetting, Rehearsal and Pseudorehearsal)
|
||||
58 OK 10.48550/arXiv.1705.08690 Continual Learning with Deep Generative Replay in manuscript
|
||||
59 OK 10.48550/arXiv.2406.07515 Beyond Model Collapse: Scaling Up with Synthesized Data Requires in manuscript
|
||||
60 OK 10.48550/arXiv.1606.04671 Progressive Neural Networks in manuscript
|
||||
61 OK 10.48550/arXiv.2405.09673 LoRA Learns Less and Forgets Less in manuscript
|
||||
62 OK 10.1037/0033-295x.102.3.419 Why there are complementary learning systems in the hippocampus crossref (matched: Why there are complementary learning systems in the hippocampus and ne)
|
||||
63 OK 10.1016/j.tics.2016.05.004 What Learning Systems do Intelligent Agents Need? Complementary crossref (matched: What Learning Systems do Intelligent Agents Need? Complementary Learni)
|
||||
64 OK 10.48550/arXiv.1805.06370 Progress & Compress: A scalable framework for continual lear verified by hand
|
||||
65 OK 10.48550/arXiv.2212.04089 Editing Models with Task Arithmetic in manuscript
|
||||
66 OK 10.48550/arXiv.2407.06322 MagMax: Leveraging Model Merging for Seamless Continual Learning in manuscript
|
||||
67 OK 10.48550/arXiv.2407.08699 Mitigating Catastrophic Forgetting in Language Transfer via Mode in manuscript
|
||||
68 OK 10.48550/arXiv.2412.06712 How to Merge Your Multimodal Models Over Time? in manuscript
|
||||
69 OK 10.48550/arXiv.1812.05159 An Empirical Study of Example Forgetting during Deep Neural Netw in manuscript
|
||||
70 OK 10.48550/arXiv.2211.08411 Large Language Models Struggle to Learn Long-Tail Knowledge in manuscript
|
||||
71 OK 10.48550/arXiv.2210.00266 Long-Tailed Class Incremental Learning in manuscript
|
||||
72 OK 10.48550/arXiv.2309.10105 Understanding Catastrophic Forgetting in Language Models via Imp in manuscript
|
||||
73 OK 10.48550/arXiv.2311.03099 Language Models are Super Mario: Absorbing Abilities from Homolo in manuscript
|
||||
74 OK 10.48550/arXiv.2203.05482 Model soups: averaging weights of multiple fine-tuned models imp in manuscript
|
||||
75 OK 10.48550/arXiv.2603.09463 An Empirical Study and Theoretical Explanation on Task-Level Mod in manuscript
|
||||
76 OK 10.48550/arXiv.2506.14126 From Memorization to Parameter Interference: How Overtraining Ex in manuscript
|
||||
77 OK 10.1145/2934662 Sex as an algorithm crossref (matched: Sex as an algorithm)
|
||||
78 OK 10.48550/arXiv.2311.09807 The Curious Decline of Linguistic Diversity: Training Language M in manuscript
|
||||
79 OK 10.48550/arXiv.2309.05196 Does Writing with Language Models Reduce Content Diversity? in manuscript
|
||||
80 OK 10.1126/sciadv.adn5290 Generative AI enhances individual creativity but reduces the col crossref (matched: Generative AI enhances individual creativity but reduces the collectiv)
|
||||
|
|
|
@ -1,131 +0,0 @@
|
|||
"""Renumber the manuscript's references to first-appearance order (PNAS style).
|
||||
|
||||
Reads paper/manuscript/main.md, finds every parenthesised citation group in the text above
|
||||
"## References", derives the order in which references first appear, and rewrites the citation
|
||||
groups in main.md, si.md, and the figure captions in build.py, then reorders the reference list.
|
||||
Citation groups are parentheses containing only reference numbers, commas, en-dash ranges, an optional
|
||||
"cf. " prefix, or a prose prefix ending in a semicolon ("...; 11, 12"). Four-digit numbers (years)
|
||||
never match, and any number above the list length is reported and left alone.
|
||||
|
||||
Usage: python paper/manuscript/renumber_refs.py # dry run: mapping + per-file counts
|
||||
python paper/manuscript/renumber_refs.py --apply # rewrite the three files in place
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
MAIN, SI, BUILD = (ROOT / "paper" / "manuscript" / n for n in ("main.md", "si.md", "build.py"))
|
||||
REF_HEADER = "## References"
|
||||
CIT = re.compile(
|
||||
r"\((?P<pre>[^()]*?;\s*)?(?P<cf>cf\.\s*)?"
|
||||
r"(?P<nums>\d{1,3}(?:\s*[–-]\s*\d{1,3})?(?:,\s*\d{1,3}(?:\s*[–-]\s*\d{1,3})?)*)\)"
|
||||
)
|
||||
REF_LINE = re.compile(r"^(\d+)\. (.*)$")
|
||||
|
||||
|
||||
def expand(nums: str) -> list[int]:
|
||||
out: list[int] = []
|
||||
for part in re.split(r",\s*", nums):
|
||||
if re.search(r"[–-]", part):
|
||||
a, b = (int(x) for x in re.split(r"\s*[–-]\s*", part))
|
||||
out.extend(range(a, b + 1))
|
||||
else:
|
||||
out.append(int(part))
|
||||
return out
|
||||
|
||||
|
||||
def compress(nums: list[int]) -> str:
|
||||
"""Ascending, with runs of three or more collapsed to an en-dash range."""
|
||||
nums = sorted(set(nums))
|
||||
runs: list[list[int]] = []
|
||||
for n in nums:
|
||||
if runs and n == runs[-1][-1] + 1:
|
||||
runs[-1].append(n)
|
||||
else:
|
||||
runs.append([n])
|
||||
return ", ".join(f"{r[0]}–{r[-1]}" if len(r) >= 3 else ", ".join(map(str, r)) for r in runs)
|
||||
|
||||
|
||||
def split_main(text: str) -> tuple[str, list[tuple[int, str]]]:
|
||||
body, _, refs = text.partition(REF_HEADER)
|
||||
entries = [(int(m.group(1)), m.group(2)) for line in refs.splitlines() if (m := REF_LINE.match(line))]
|
||||
return body, entries
|
||||
|
||||
|
||||
def first_appearance(body: str, n_refs: int) -> list[int]:
|
||||
order: list[int] = []
|
||||
for m in CIT.finditer(body):
|
||||
for n in expand(m.group("nums")):
|
||||
if n <= n_refs and n not in order:
|
||||
order.append(n)
|
||||
return order
|
||||
|
||||
|
||||
def rewrite(text: str, mapping: dict[int, int], n_refs: int, label: str) -> tuple[str, int, list[str]]:
|
||||
count, suspicious = 0, []
|
||||
|
||||
def sub(m: re.Match) -> str:
|
||||
nonlocal count
|
||||
nums = expand(m.group("nums"))
|
||||
if any(n > n_refs or n < 1 for n in nums):
|
||||
suspicious.append(m.group(0))
|
||||
return m.group(0)
|
||||
count += 1
|
||||
return f"({m.group('pre') or ''}{m.group('cf') or ''}{compress([mapping[n] for n in nums])})"
|
||||
|
||||
return CIT.sub(sub, text), count, suspicious
|
||||
|
||||
|
||||
def main(apply: bool) -> int:
|
||||
main_text = MAIN.read_text()
|
||||
body, entries = split_main(main_text)
|
||||
n_refs = len(entries)
|
||||
assert [n for n, _ in entries] == list(range(1, n_refs + 1)), "reference list is not 1..N"
|
||||
order = first_appearance(body, n_refs)
|
||||
orphans = sorted(set(range(1, n_refs + 1)) - set(order))
|
||||
if orphans:
|
||||
print(f"ERROR: never cited in main text: {orphans}")
|
||||
return 1
|
||||
mapping = {old: new for new, old in enumerate(order, start=1)}
|
||||
changed = {o: n for o, n in mapping.items() if o != n}
|
||||
print(f"{n_refs} references; {len(changed)} renumbered" + (":" if changed else "."))
|
||||
for o in sorted(changed):
|
||||
print(f" {o:3d} -> {mapping[o]:3d} {entries[o - 1][1][:70]}")
|
||||
|
||||
outputs: dict[Path, str] = {}
|
||||
new_body, c, sus = rewrite(body, mapping, n_refs, "main")
|
||||
print(f"main.md: {c} citation groups" + (f"; left alone: {sus}" if sus else ""))
|
||||
by_new = sorted(entries, key=lambda e: mapping[e[0]])
|
||||
new_refs = "\n".join(f"{mapping[o]}. {t}" for o, t in by_new)
|
||||
outputs[MAIN] = f"{new_body}{REF_HEADER}\n\n{new_refs}\n"
|
||||
text, c, sus = rewrite(SI.read_text(), mapping, n_refs, SI.name)
|
||||
print(f"{SI.name}: {c} citation groups" + (f"; left alone: {sus}" if sus else ""))
|
||||
outputs[SI] = text
|
||||
# build.py is Python: only its FIGURES caption block may carry citations, so rewrite that slice
|
||||
# alone — tuples like (0, 1) elsewhere in the code would otherwise look like citations.
|
||||
btext = BUILD.read_text()
|
||||
head = re.search(r"^FIGURES\b[^\n]*\{\s*$", btext, re.M)
|
||||
if head is None:
|
||||
print(f"{BUILD.name}: no FIGURES block found; skipped")
|
||||
else:
|
||||
start = head.start()
|
||||
end = btext.index("\n}\n", start) + 3
|
||||
block, c, sus = rewrite(btext[start:end], mapping, n_refs, BUILD.name)
|
||||
print(f"{BUILD.name} captions: {c} citation groups" + (f"; left alone: {sus}" if sus else ""))
|
||||
outputs[BUILD] = btext[:start] + block + btext[end:]
|
||||
|
||||
if apply:
|
||||
for path, text in outputs.items():
|
||||
path.write_text(text)
|
||||
print("applied.")
|
||||
else:
|
||||
print("dry run — pass --apply to write.")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main("--apply" in sys.argv))
|
||||
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue