OverviewFilesCommitsIssuesDocsReleasesPeers

basal-agent commits / 985f5a3

basal-agent: ladder35.c — milestone 4; all five rungs in one type
Tests the milestone-3 claim that rungs 3 and 5 need no new type. L3 (rung 3: species ARE sequences, mutation is a variant-producing reaction): mu 0.02 0.08 0.14 0.17 0.22 0.45 mast 0.80 0.37 0.10 0.03 0.008 0.004 crosses 0.05 at mu = 0.162 vs Eigen's analytical ln(sigma)/L = 0.173, diff 0.011. Localised below, delocalised above. EXPRESSED. METRIC ERROR CAUGHT AND FIXED: the first criterion used the largest ABSOLUTE drop and put the transition at mu~0.05. On a monotone decreasing curve the biggest absolute drop always sits where the curve is highest — it locates the steep start, not the catastrophe. Same wrong-statistic class as linkage.c's "B stays near 1" bar. Replaced with a crossing point. L5 (rung 5: a specialist participates in only PART of the reaction set): specialists, complementarity REQUIRED : 0.703 specialists, requirement REMOVED (ctl): 0.060 generalists available : 0.993 Coverage sustained and collapses when not required. EXPRESSED. SUBSTRATE COMPLETE. Five independent prior results recovered from one representation: rung1.c's percolation threshold, polymer.c's bootstrap paradox, ribozyme.c's compartment ordering, byproduct.c's isolation-is-not- compartmentalisation, and Eigen's error threshold to within 0.011. NOT A CROSSING. This is scaffolding. It removes the structural reason crossings could not compose — every rung had a different substrate, so a rung's output was never expressible as the next rung's input. Whether a rung can now PRODUCE the next is untested and is the whole remaining question. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
985f5a32f1325de24139ef6d48131c0be615c716
by plankatron <fleeky@gmail.com> · 2026-08-01T02:12:39.000Z

Changed files (3) +224 -0

.gitignore +1 -0
……@@ -53,3 +53,4 @@ rung45irr
5353substrate
5454container
5555counts
56ladder35
ladder35.c +168 -0
……@@ -0,0 +1,168 @@
1/* ladder35.c — MILESTONE 4: rungs 3 and 5 in the same type. No new machinery.
2 *
3 * The substrate now carries species, reactions, containers-as-species and counts (substrate.c,
4 * container.c, counts.c), expressing rungs 1, 2 and 4 and reproducing rung1.c's threshold,
5 * polymer.c's bootstrap problem, ribozyme.c's ordering and byproduct.c's isolation control.
6 * The claim was that rungs 3 and 5 need no new type. This tests it.
7 *
8 * rung 3 species ARE sequences. A replication reaction copies a species to itself; mutation is a
9 * variant-producing reaction to a Hamming neighbour. The rung-3 property is Eigen's ERROR
10 * CATASTROPHE — a sharp transition from localised on a master sequence to delocalised over
11 * sequence space, at mu_c ~ ln(sigma)/L.
12 * rung 5 a specialist is a species participating in only PART of the reaction set. Division of
13 * labour is complementary specialists whose union covers everything the container needs,
14 * none of which suffices alone.
15 *
16 * THE CHECK, as at every milestone: expressing something is worthless unless it reproduces the
17 * result we already have.
18 * L3 the master-sequence fraction must show a SHARP fall with mutation rate, and the observed
19 * threshold must sit near ln(sigma)/L — rung3.c's exact quasispecies value.
20 * L5 specialists must sustain complementary coverage that no single species provides, and
21 * coverage must COLLAPSE when the requirement for complementarity is removed (the control).
22 *
23 * build: cc -O2 -Wall -std=c11 -o ladder35 ladder35.c -lm
24 */
25#include <math.h>
26#include <stdio.h>
27#include <string.h>
28
29#define LBITS 8
30#define NSEQ (1<<LBITS) /* 256 sequence-species — species ARE sequences */
31#define POP 4000
32#define GENS 300
33#define SIGMA 4.0 /* master-sequence selective advantage */
34
35#define NROLE 3
36#define NSPC 12 /* rung-5 species */
37#define NCOMP 400
38#define CSZ 10
39
40static unsigned long long RNG;
41static unsigned long long xs(void){ RNG^=RNG<<13; RNG^=RNG>>7; RNG^=RNG<<17; return RNG; }
42static double urand(void){ return (double)(xs()>>11)*(1.0/9007199254740992.0); }
43static int rint_(int n){ return (int)(xs()%(unsigned)n); }
44
45/* ---------------- RUNG 3: species are sequences; mutation is a reaction to a neighbour --------- */
46static int seqpop[NSEQ], nxtpop[NSEQ];
47static double fit_of(int s){ return (s==0)? SIGMA : 1.0; }
48
49static double rung3(double mu){
50 memset(seqpop,0,sizeof seqpop);
51 for(int i=0;i<POP;i++) seqpop[rint_(NSEQ)]++;
52 for(int g=0;g<GENS;g++){
53 double tot=0; static double cum[NSEQ];
54 for(int s=0;s<NSEQ;s++){ tot += seqpop[s]*fit_of(s); cum[s]=tot; }
55 memset(nxtpop,0,sizeof nxtpop);
56 for(int i=0;i<POP;i++){
57 double r=urand()*tot; int lo=0,hi=NSEQ-1;
58 while(lo<hi){ int mid=(lo+hi)/2; if(cum[mid]<r) lo=mid+1; else hi=mid; }
59 int child=lo;
60 for(int b=0;b<LBITS;b++) if(urand()<mu) child^=(1<<b); /* mutation = variant reaction */
61 nxtpop[child]++;
62 }
63 memcpy(seqpop,nxtpop,sizeof seqpop);
64 }
65 return (double)seqpop[0]/POP;
66}
67
68/* ---------------- RUNG 5: a specialist participates in only PART of the reaction set ----------- */
69static unsigned char covers[NSPC][NROLE]; /* which roles a species can perform */
70static int comp[NCOMP][CSZ], ncomp2;
71
72static void build_species(int generalists_allowed){
73 for(int s=0;s<NSPC;s++){
74 memset(covers[s],0,sizeof covers[s]);
75 if(generalists_allowed && s<NROLE){ for(int r=0;r<NROLE;r++) covers[s][r]=1; }
76 else covers[s][s%NROLE]=1; /* specialist: exactly one role */
77 }
78}
79static int coverage(const int *cell){
80 int seen[NROLE]; memset(seen,0,sizeof seen);
81 for(int k=0;k<CSZ;k++) for(int r=0;r<NROLE;r++) if(covers[cell[k]][r]) seen[r]=1;
82 int c=0; for(int r=0;r<NROLE;r++) c+=seen[r];
83 return c;
84}
85/* need_all=1: a container is viable only with ALL roles covered (complementarity required).
86 need_all=0 (CONTROL): any single role suffices — complementarity is not demanded. */
87static double rung5(int need_all){
88 ncomp2=NCOMP;
89 for(int c=0;c<NCOMP;c++) for(int k=0;k<CSZ;k++) comp[c][k]=rint_(NSPC);
90 for(int g=0;g<200;g++){
91 static int nxt[NCOMP][CSZ];
92 double tot=0,cum[NCOMP];
93 for(int c=0;c<NCOMP;c++){
94 int cov=coverage(comp[c]);
95 double v = need_all ? ((cov==NROLE)?1.0:0.02) : ((cov>=1)?1.0:0.02);
96 tot+=v; cum[c]=tot;
97 }
98 for(int c=0;c<NCOMP;c++){
99 double r=urand()*tot; int lo=0,hi=NCOMP-1;
100 while(lo<hi){ int mid=(lo+hi)/2; if(cum[mid]<r) lo=mid+1; else hi=mid; }
101 for(int k=0;k<CSZ;k++){
102 int src=comp[lo][rint_(CSZ)];
103 if(urand()<0.02) src=rint_(NSPC);
104 nxt[c][k]=src;
105 }
106 }
107 memcpy(comp,nxt,sizeof comp);
108 }
109 double full=0;
110 for(int c=0;c<NCOMP;c++) if(coverage(comp[c])==NROLE) full++;
111 return full/NCOMP;
112}
113
114int main(void)
115{
116 printf("=== MILESTONE 4: rungs 3 and 5 in the same type, no new machinery ===\n\n");
117
118 /* ---- L3 ---- */
119 double muc = log(SIGMA)/LBITS;
120 printf(" L3 — rung 3: species ARE sequences, mutation is a variant-producing reaction.\n");
121 printf(" Eigen predicts an error catastrophe near mu_c = ln(sigma)/L = ln(%.0f)/%d = %.3f\n\n",SIGMA,LBITS,muc);
122 printf(" mu | master-sequence fraction\n");
123 printf(" -------+-------------------------\n");
124 double mus[7]={0.02,0.08,0.14,0.17,0.22,0.30,0.45};
125 double v[7];
126 for(int i=0;i<7;i++){
127 double a=0; for(int s=0;s<4;s++){ RNG=0x9e3779b97f4a7c15ULL+(unsigned long long)(i*97+s)*0x2545F4914F6CDD1DULL; a+=rung3(mus[i]); }
128 v[i]=a/4;
129 printf(" %.2f | %.4f %s\n",mus[i],v[i], (mus[i]<muc)?"(below mu_c)":"(above)");
130 }
131 /* Locate the threshold as the CROSSING of a low master fraction, not the biggest absolute drop.
132 On a monotone decreasing curve the largest absolute drop always sits where the curve is
133 highest, so it locates the steep start, not the catastrophe — the same wrong-statistic error
134 as linkage.c's "B stays near 1" bar. Interpolate where the master fraction crosses 0.05. */
135 double where=-1;
136 for(int i=0;i+1<7;i++){
137 if(v[i]>=0.05 && v[i+1]<0.05){
138 double t=(v[i]-0.05)/(v[i]-v[i+1]);
139 where=mus[i]+t*(mus[i+1]-mus[i]); break;
140 }
141 }
142 int l3 = (v[0]>0.3) && (v[6]<0.05) && where>0 && fabs(where-muc)<0.06;
143 printf("\n master fraction crosses 0.05 at mu = %.3f vs Eigen prediction %.3f (diff %+.3f)\n",where,muc,where-muc);
144 printf(" => %s\n\n", l3?"LOCALISED below, DELOCALISED above, transition near ln(sigma)/L — rung 3 expressed."
145 :"does NOT reproduce the error catastrophe — rung 3 is not expressed.");
146
147 /* ---- L5 ---- */
148 printf(" L5 — rung 5: a specialist participates in only PART of the reaction set.\n");
149 printf(" Division of labour = complementary specialists whose union covers what one cannot.\n\n");
150 build_species(0);
151 double spec_need = rung5(1), spec_ctrl = rung5(0);
152 build_species(1);
153 double gen_need = rung5(1);
154 printf(" arm | containers with ALL %d roles\n",NROLE);
155 printf(" --------------------------------------+---------------------------\n");
156 printf(" specialists, complementarity REQUIRED | %.3f\n",spec_need);
157 printf(" specialists, requirement REMOVED (ctl)| %.3f\n",spec_ctrl);
158 printf(" generalists available | %.3f\n",gen_need);
159 int l5 = (spec_need>0.5) && (spec_ctrl < spec_need-0.1);
160 printf("\n => %s\n\n", l5?"complementary coverage is sustained, and COLLAPSES when not required —\n division of labour is a reaction-participation pattern, not a new type."
161 :"coverage does not behave as rung 5 — not expressed.");
162
163 printf(" MILESTONE 4 %s\n", (l3&&l5)?"PASSED — rungs 1,2,3,4,5 all live in one type."
164 :"NOT PASSED — see which check failed above.");
165 printf(" Still scaffolding: nothing here CROSSES a rung. It removes the reason crossings could\n");
166 printf(" not compose, which is what the whole ladder has lacked.\n");
167 return 0;
168}
ladder35.md +55 -0
……@@ -0,0 +1,55 @@
1# `ladder35.c` — milestone 4: all five rungs in one type
2
3The claim after milestone 3 was that rungs 3 and 5 need **no new type**. This tests it.
4
5## L3 — rung 3: species *are* sequences
6
7Mutation is a variant-producing reaction to a Hamming neighbour. Nothing else added.
8
9| μ | master-sequence fraction | |
10|---|---|---|
11| 0.02 | 0.8041 | below μ_c |
12| 0.08 | 0.3702 | below |
13| 0.14 | 0.1008 | below |
14| 0.17 | 0.0309 | below |
15| 0.22 | 0.0076 | **above** |
16| 0.45 | 0.0037 | above |
17
18**Crosses 0.05 at μ = 0.162 against Eigen's analytical ln(σ)/L = 0.173 — a difference of 0.011.**
19Localised below, delocalised above. Rung 3 expressed.
20
21**A metric error, caught and fixed.** The first criterion used the largest *absolute* drop, which
22put the transition at μ≈0.05. On a monotone decreasing curve the biggest absolute drop always sits
23where the curve is highest — it locates the steep start, not the catastrophe. Same wrong-statistic
24class as `linkage.c`'s "B stays near 1" bar. Replaced with a crossing point.
25
26## L5 — rung 5: a specialist participates in only part of the reaction set
27
28| arm | containers with all 3 roles |
29|---|---|
30| specialists, complementarity **required** | **0.703** |
31| specialists, requirement **removed** (control) | **0.060** |
32| generalists available | 0.993 |
33
34Complementary coverage is sustained and **collapses to 0.060 when not required**. Division of labour
35is a reaction-participation pattern, not a new type. Rung 5 expressed.
36
37## The substrate, complete
38
39| milestone | |
40|---|---|
41| 1 `substrate.c` | rungs 1 & 2; reproduces `rung1.c`'s threshold exactly; gives `polymer.c`'s bootstrap problem free |
42| 2 `container.c` | containers are ordinary species — but presence/absence cannot express rung 4 |
43| 3 `counts.c` | abundances; rung 4 expressed, reproducing `ribozyme.c`'s ordering **and** `byproduct.c`'s isolation control |
44| 4 `ladder35.c` | **rungs 3 & 5; all five now live in one type** |
45
46Five independent prior results recovered from one representation: `rung1.c`'s percolation threshold,
47`polymer.c`'s bootstrap paradox, `ribozyme.c`'s compartment ordering, `byproduct.c`'s
48isolation-≠-compartmentalisation, and Eigen's error threshold to within 0.011.
49
50## What it is not
51
52**Nothing here crosses a rung.** This is scaffolding. It removes the structural reason crossings
53could not compose — that every rung had a different substrate, so a rung's output was never
54expressible as the next rung's input. Whether a rung can now *produce* the next is untested and is
55the whole remaining question.