diff --git a/paper/pnas/body.tex b/paper/pnas/body.tex index b079251..69a57a3 100644 --- a/paper/pnas/body.tex +++ b/paper/pnas/body.tex @@ -20,7 +20,7 @@ An operator of a model population faces recurring decisions for which there is n \begin{figure*}[p]\centering % fig1 \includegraphics[width=\textwidth]{figs/fig1.pdf} -\caption{The experimental programme. Each population-genetic abstraction (Table 1) is tested at up to three tiers of model architecture, ordered left to right by increasing realism: an exact Wright--Fisher simulator over knowledge distributions (closed forms; bitwise-reproducible), trained neural networks measured against exact oracles (recurrent, feedforward, and variational-autoencoder generators on a synthetic mode universe, and a convolutional VAE on MNIST), and language models (LoRA specialists on Qwen bases at 0.5B and 7B, scored by an exact-match verifier). Rows are the paper's five questions; filled cells name the experiments run at each tier; dashed cells were not tested, and the composed society at language-model scale is the paper's stated gap.}\label{fig1} +\caption{The experimental programme. Each population-genetic abstraction (Table 1) is tested at up to three tiers of model architecture, ordered left to right by increasing realism: an exact Wright--Fisher simulator over knowledge distributions (closed forms; bitwise-reproducible), trained neural networks measured against exact oracles (recurrent, feedforward, and variational-autoencoder generators on a synthetic mode universe, and a convolutional VAE on MNIST), and language models (LoRA specialists on Qwen bases at 0.5B and 7B, scored by an exact-match verifier). The same population-genetic abstractions are carried across the three tiers. Rows are the framework's mechanisms, each defined at the left margin; filled cells name the experiments run at each tier; dashed cells were not tested, and the composed society at language-model scale is the paper's stated gap.}\label{fig1} \end{figure*} \section*{The minimal model, and where its exactness ends} diff --git a/paper/pnas/build.py b/paper/pnas/build.py index 3a9dc4c..7f2dbd8 100644 --- a/paper/pnas/build.py +++ b/paper/pnas/build.py @@ -28,9 +28,10 @@ FIGURES: dict[str, tuple[list[str], str]] = { "trained neural networks measured against exact oracles (recurrent, feedforward, and " "variational-autoencoder generators on a synthetic mode universe, and a convolutional VAE on " "MNIST), and language models (LoRA specialists on Qwen bases at 0.5B and 7B, scored by an " - "exact-match verifier). Rows are the paper's five questions; filled cells name the " - "experiments run at each tier; dashed cells were not tested, and the composed society at " - "language-model scale is the paper's stated gap."), + "exact-match verifier). The same population-genetic abstractions are carried across the " + "three tiers. Rows are the framework's mechanisms, each defined at the left margin; filled " + "cells name the experiments run at each tier; dashed cells were not tested, and the composed " + "society at language-model scale is the paper's stated gap."), "fig2": (["paper/pnas/figs/fig2.pdf"], "Grounding is immigration. (A) Stationary diversity against the grounding fraction in the " "minimal inheritance model: simulation (points, 95\\% CI) matches the exact immigration--drift " diff --git a/paper/pnas/figs/fig1.pdf b/paper/pnas/figs/fig1.pdf index 4076c53..1926505 100644 Binary files a/paper/pnas/figs/fig1.pdf and b/paper/pnas/figs/fig1.pdf differ diff --git a/paper/pnas/main.pdf b/paper/pnas/main.pdf index e1155f3..87e39f0 100644 Binary files a/paper/pnas/main.pdf and b/paper/pnas/main.pdf differ diff --git a/paper/pnas/make_figs.py b/paper/pnas/make_figs.py index 8f271d7..176ef5e 100644 --- a/paper/pnas/make_figs.py +++ b/paper/pnas/make_figs.py @@ -48,66 +48,69 @@ def fig1(): TIERS = [ ("Exact model", "Wright\u2013Fisher simulator (NumPy)", "closed forms \u00b7 bitwise-reproducible", - "#4292c6", "#eaf2fa"), + "#3d7eb8", "#eaf2fa"), ("Trained networks", "RNN \u00b7 MLP \u00b7 VAE on a synthetic oracle;\nconvolutional VAE on MNIST", - "sign-level tests \u00b7 exact oracles", "#41ab5d", "#edf8ea"), + "sign-level tests \u00b7 exact oracles", "#3f8f4f", "#edf8ea"), ("Language models", "LoRA specialists on Qwen 0.5B & 7B;\nexact-match verifier", - "seed-replicated signs", "#e6550d", "#fdf0e6"), + "seed-replicated signs", "#d9650f", "#fdf0e6"), ] ROWS = [ - ("Grounding", "how much real data?", + ("Grounding = immigration", + "fresh verified samples from a\nfixed external source enter the\ntraining mix every generation", ["immigration\u2013drift equilibrium:\n$g \\approx 0.05$ retains $\\geq$95% diversity;\nobservation floor $1-e^{-mp}$", "collapse & rescue in every\narchitecture; MNIST: dry 30$\\to$1 modes,\n10% grounding holds 30/30;\nestimator-bias learning kernel", None]), - ("Recombination", "blend or merge?", + ("Recombination = sex", + "a child inherits from several\nparents, reassembling variants\nthat arose in different lineages", ["blending conservation law\n(first-order cancellation);\nunion-operator gain; Fisher\u2013Muller", "merge rescues two forgetting\nspecialists ($\\approx$0.50 $\\to$ 0.955)", "merged specialists beat every parent\n(5 seeds at 0.5B; 7B); routing vs\naveraging: the headroom rule"]), - ("Entangled skills", "who merges with whom?", + ("Epistasis (entangled skills)", + "a variant's fitness contribution\ndepends on the variants present\nat the other loci", ["NK landscapes: outbreeding\ndepression; directed sex restores\nthe gain; mate-pool breadth optimum", None, "bred-and-screened offspring beat\nthe blind blend in every seed\n(hard, unsaturated tasks)"]), - ("The composed society", "can the loop sustain itself?", + ("The composed society", + "selection, recombination,\ndiversity preservation and\ngrounding on one population", ["four-arm ablation: grounding, sex,\ndiversity each removed\n$\\to$ three distinct failures", None, "OPEN"]), - ("Speciation & prediction", "when does merging fail?", + ("Speciation", + "reproductive isolation: diverged\nlineages no longer produce\nviable (mergeable) offspring", ["BDM incompatibility model:\nisolation cliff; quadratic snowball", "barrier decomposition under\npermutation+rescaling; conflict\nsweep 0.97$\\to$0.03; emergent null", "convention conflict $\\to$ hybrid\nbreakdown; duration null; pre-merge\npredictive test (13 cond. $\\times$ 3 seeds)"]), ] - fig, ax = plt.subplots(figsize=(11.4, 5.4)) + fig, ax = plt.subplots(figsize=(11.4, 5.3)) ax.set_axis_off() ax.set_xlim(0, 1) ax.set_ylim(0, 1) - x0, gap = 0.16, 0.008 + x0, gap = 0.205, 0.008 cw = (1.0 - x0) / 3 - row_h, row_top = 0.152, 0.79 + row_h, row_top = 0.157, 0.805 - ax.annotate("", xy=(0.995, 0.975), xytext=(x0 + 0.02, 0.975), - arrowprops=dict(arrowstyle="->", color="#555", lw=1.1)) - ax.text(x0 + (1 - x0) / 2, 0.988, "the same population-genetic abstractions (Table 1), increasing realism", - ha="center", va="bottom", fontsize=8, style="italic", color="#333") + for j2, (name, arch, guarantee, edge, face) in enumerate(TIERS): + x = x0 + j2 * cw + ax.add_patch(FancyBboxPatch((x + gap, 0.825), cw - 2 * gap, 0.155, + boxstyle="round,pad=0.004", fc=edge, ec=edge, lw=1.4)) + ax.text(x + cw / 2, 0.966, name, ha="center", va="top", fontsize=9.5, + fontweight="bold", color="white") + ax.text(x + cw / 2, 0.922, arch, ha="center", va="top", fontsize=6.8, + linespacing=1.3, color="white") + ax.text(x + cw / 2, 0.833, guarantee, ha="center", va="bottom", fontsize=6.4, + style="italic", color="white", alpha=0.92) - for j, (name, arch, guarantee, edge, face) in enumerate(TIERS): - x = x0 + j * cw - ax.add_patch(FancyBboxPatch((x + gap, 0.795), cw - 2 * gap, 0.16, - boxstyle="round,pad=0.004", fc=face, ec=edge, lw=1.4)) - ax.text(x + cw / 2, 0.944, name, ha="center", va="top", fontsize=9, fontweight="bold", color=edge) - ax.text(x + cw / 2, 0.902, arch, ha="center", va="top", fontsize=6.8, linespacing=1.3) - ax.text(x + cw / 2, 0.803, guarantee, ha="center", va="bottom", fontsize=6.4, - style="italic", color="#555") - - for i, (label, question, cells) in enumerate(ROWS): - y1 = row_top - i * row_h + for i2, (label, definition, cells) in enumerate(ROWS): + y1 = row_top - i2 * row_h y0 = y1 - row_h + 2 * gap yc = (y0 + y1) / 2 - ax.text(0.0, yc + 0.012, label, ha="left", va="center", fontsize=8, fontweight="bold") - ax.text(0.0, yc - 0.022, question, ha="left", va="center", fontsize=6.8, style="italic", color="#555") - for j, cell in enumerate(cells): - x = x0 + j * cw - edge, face = TIERS[j][3], TIERS[j][4] + ax.text(0.0, y1 - 0.014, label, ha="left", va="top", fontsize=8, fontweight="bold") + ax.text(0.0, y1 - 0.054, definition, ha="left", va="top", fontsize=6.2, + style="italic", color="#555", linespacing=1.35) + for j2, cell in enumerate(cells): + x = x0 + j2 * cw + edge, face = TIERS[j2][3], TIERS[j2][4] if cell is None: ax.add_patch(FancyBboxPatch((x + gap, y0), cw - 2 * gap, y1 - y0, boxstyle="round,pad=0.004", fc="white", ec="#bbbbbb", @@ -126,7 +129,6 @@ def fig1(): ax.text(x + cw / 2, yc, cell, ha="center", va="center", fontsize=6.4, linespacing=1.35) save(fig, "fig1") - # ---------------------------------------------------------------- fig 2: grounding + MNIST def fig2(): from knowledge.analysis import critical_grounding, reduce_to_stationary