OverviewFilesCommitsIssuesDocsReleasesPeers

basal-agent commits / 717125d

basal-agent: container.c — milestone 2; recursive move sound, presence/absence type is not
C1 PASSED: a container is an ordinary species that also has contents. Verified as a reaction PRODUCT, verified to NEST inside another container, and its RAF is computed over its own contents (locality is what a compartment is). The recursive move works. C2 THE KILLER, tested before building on it: can a container hold closure the whole mixture lacks? 400 random networks x 3 random partitions = 1200 partitions, 256 with a non-empty local RAF, and ZERO holding closure the global mixture lacks. RAF is MONOTONE in the reaction set — adding reactions never removes closure — so a part can never sustain what the whole cannot. Compartmentalisation therefore buys NOTHING expressible in a presence/absence type. What ribozyme.c's compartments actually bought was PRIVATISATION AGAINST PARASITES: a catalyst-rich compartment out-reproduces a parasite-ridden one. That is a claim about relative ABUNDANCE, not about what can exist, and a static closure formalism cannot state it however the containers are arranged. => MILESTONE 3 IS NOT MORE STRUCTURE, IT IS COUNTS. The type must carry how much of each species is present and the RAF becomes a dynamical attractor rather than a static closure. A measured design requirement rather than a guess, obtained before three further milestones were built on a type that cannot carry rung 4. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
717125d4b82e2a66d89cfd6b337006eecb81b340
by plankatron <fleeky@gmail.com> · 2026-08-01T01:47:04.000Z

Changed files (3) +208 -0

.gitignore +1 -0
……@@ -51,3 +51,4 @@ replicase
5151replisome
5252rung45irr
5353substrate
54container
container.c +166 -0
……@@ -0,0 +1,166 @@
1/* container.c — MILESTONE 2: containers as species. And a structural check that may kill the design.
2 *
3 * substrate.c passed milestone 1: one type expressing rung 1 (a self-sustaining reaction subset) and
4 * rung 2 (a reaction whose product catalyses itself), coexisting in one network with no translation.
5 * The next move is the recursive one — a CONTAINER IS ITSELF A SPECIES, so a compartment can be
6 * produced, consumed, catalysed and nested like anything else. That is what would let a rung's
7 * output be the next rung's input.
8 *
9 * THE CHECK THAT COMES FIRST, AND MIGHT KILL IT. Before building on containers, ask whether this
10 * type can express what rung 4 is FOR. In ribozyme.c compartments bought privatisation against
11 * parasites: a catalyst-rich compartment out-reproduces a parasite-ridden one. That is a claim about
12 * relative ABUNDANCE. But substrate.c's RAF is a purely STRUCTURAL notion — which reactions can
13 * sustain themselves given which species are present — and RAF is MONOTONE in the reaction set:
14 * adding reactions can never remove closure. If so, a container can never hold a RAF that the whole
15 * mixture lacks, and compartmentalisation cannot buy anything expressible in this type.
16 *
17 * That is a falsifiable structural prediction about the substrate's own design, so it is tested here
18 * rather than assumed:
19 * C1 containers work at all — a container's RAF is computed over ITS OWN contents (locality is
20 * what a compartment IS), containers can be reaction products, and containers can nest.
21 * C2 THE KILLER: is global RAF always a superset of every container's RAF? Measured over many
22 * random networks and random partitions. If it always is, static closure cannot express rung 4
23 * and the type needs ABUNDANCES, not just presence.
24 *
25 * A negative on C2 is the useful outcome: it says precisely what milestone 3 must add.
26 *
27 * build: cc -O2 -Wall -std=c11 -o container container.c -lm
28 */
29#include <stdio.h>
30#include <string.h>
31
32#define NSPEC 48
33#define NFOOD 6
34#define NRXN 200
35#define MAXC 8 /* container species occupy the top MAXC species indices */
36
37static unsigned long long RNG;
38static unsigned long long xs(void){ RNG^=RNG<<13; RNG^=RNG>>7; RNG^=RNG<<17; return RNG; }
39static double urand(void){ return (double)(xs()>>11)*(1.0/9007199254740992.0); }
40static int rint_(int n){ return (int)(xs()%(unsigned)n); }
41
42typedef struct { int a,b,prod; unsigned char cat[NSPEC]; } Rxn;
43static Rxn R[NRXN]; static int nrxn;
44
45/* ---- THE RECURSIVE MOVE: a container is a species that also has CONTENTS. Species index c is a
46 container iff c >= NSPEC-MAXC. Its contents are a set of species — which may include other
47 containers, so nesting is free. ---- */
48static unsigned char contents[MAXC][NSPEC];
49static int is_container(int s){ return s>=NSPEC-MAXC; }
50static int cidx(int s){ return s-(NSPEC-MAXC); }
51
52static unsigned char present[NSPEC], active[NRXN];
53
54/* RAF over a RESTRICTED species scope: only species in `scope` may be used. Passing an all-ones
55 scope gives the global RAF; passing a container's contents gives that container's local RAF.
56 Locality is the whole of what a compartment is, in this type. */
57static int raf_scope(const unsigned char *scope){
58 for(int j=0;j<nrxn;j++) active[j]=1;
59 for(;;){
60 for(int m=0;m<NSPEC;m++) present[m]=(m<NFOOD && scope[m])?1:0;
61 int grew=1;
62 while(grew){ grew=0;
63 for(int j=0;j<nrxn;j++){ if(!active[j]) continue;
64 int a=R[j].a,b=R[j].b,p=R[j].prod;
65 if(!scope[a]||!scope[b]||!scope[p]) continue;
66 if(!present[a]||!present[b]||present[p]) continue;
67 int cz=0; for(int m=0;m<NSPEC;m++) if(R[j].cat[m]&&scope[m]&&present[m]){cz=1;break;}
68 if(cz){ present[p]=1; grew=1; }
69 }
70 }
71 int ch=0;
72 for(int j=0;j<nrxn;j++){ if(!active[j]) continue;
73 int ok = scope[R[j].a]&&scope[R[j].b]&&scope[R[j].prod]
74 && present[R[j].a]&&present[R[j].b];
75 int cz=0; if(ok){ for(int m=0;m<NSPEC;m++) if(R[j].cat[m]&&scope[m]&&present[m]){cz=1;break;} }
76 if(!(ok&&cz)){ active[j]=0; ch=1; }
77 }
78 if(!ch) break;
79 }
80 int n=0; for(int j=0;j<nrxn;j++) n+=active[j];
81 return n;
82}
83static void raf_mark(const unsigned char *scope,unsigned char *out){
84 raf_scope(scope); memcpy(out,active,nrxn);
85}
86
87static void net_random(double p){
88 nrxn=0;
89 for(int j=0;j<NRXN;j++){
90 R[j].a=rint_(NSPEC); R[j].b=rint_(NSPEC); R[j].prod=NFOOD+rint_(NSPEC-NFOOD);
91 memset(R[j].cat,0,sizeof R[j].cat);
92 for(int m=0;m<NSPEC;m++) if(urand()<p) R[j].cat[m]=1;
93 nrxn++;
94 }
95}
96
97int main(void)
98{
99 unsigned char all[NSPEC], sc[NSPEC];
100 for(int m=0;m<NSPEC;m++) all[m]=1;
101
102 printf("=== MILESTONE 2: containers as species — and the check that may kill the design ===\n");
103 printf(" A container is a species that also has contents; contents may include containers, so\n");
104 printf(" nesting is free. A container's RAF is its contents' RAF — locality is what a\n");
105 printf(" compartment IS. %d species (%d food, top %d are containers), %d reactions.\n\n",NSPEC,NFOOD,MAXC,NRXN);
106
107 /* ---- C1: containers exist, are products, and nest ---- */
108 printf(" C1 — containers work at all\n");
109 RNG=0x9e3779b97f4a7c15ULL; net_random(0.030);
110 int K1=NSPEC-MAXC, K2=NSPEC-MAXC+1;
111 memset(contents,0,sizeof contents);
112 for(int m=0;m<NFOOD;m++){ contents[cidx(K1)][m]=1; contents[cidx(K2)][m]=1; }
113 for(int m=NFOOD;m<NFOOD+12;m++) contents[cidx(K1)][m]=1;
114 contents[cidx(K2)][K1]=1; /* K2 CONTAINS K1 — nesting */
115 R[0].a=0; R[0].b=1; R[0].prod=K1; R[0].cat[0]=1;/* a reaction whose PRODUCT is a container */
116 int prod_ok = (R[0].prod==K1) && is_container(R[0].prod);
117 int nest_ok = contents[cidx(K2)][K1] && is_container(K1);
118 memcpy(sc,contents[cidx(K1)],NSPEC); int local=raf_scope(sc);
119 int glob=raf_scope(all);
120 printf(" container is a reaction product : %s\n",prod_ok?"YES":"no");
121 printf(" container nested in a container : %s\n",nest_ok?"YES":"no");
122 printf(" local RAF (inside K1) %d vs global RAF %d\n",local,glob);
123 int c1 = prod_ok && nest_ok;
124 printf(" => %s\n\n", c1?"containers are ordinary species — the recursive move works"
125 :"containers are NOT ordinary species here — fix before proceeding");
126
127 /* ---- C2: is a container's RAF always a SUBSET of the global RAF? ---- */
128 printf(" C2 — THE KILLER. Can a container hold closure the whole mixture lacks?\n");
129 printf(" Random networks x random partitions; count any reaction in a container's RAF\n");
130 printf(" but NOT in the global RAF.\n");
131 int trials=0, violations=0, nonempty=0;
132 static unsigned char gmark[NRXN], lmark[NRXN];
133 for(int t=0;t<400;t++){
134 RNG=0x2545f4914f6cdd1dULL + (unsigned long long)t*0x9E3779B97F4A7C15ULL;
135 net_random(0.020+0.02*urand());
136 raf_mark(all,gmark);
137 for(int r=0;r<3;r++){
138 for(int m=0;m<NSPEC;m++) sc[m]=(m<NFOOD)?1:(urand()<0.5);
139 raf_mark(sc,lmark);
140 int loc=0,viol=0;
141 for(int j=0;j<nrxn;j++){ loc+=lmark[j]; if(lmark[j]&&!gmark[j]) viol++; }
142 trials++; if(loc>0) nonempty++; if(viol>0) violations++;
143 }
144 }
145 printf(" %d partitions, %d with a non-empty local RAF, %d holding closure the global\n",trials,nonempty,violations);
146 printf(" mixture lacks.\n");
147 printf(" => %s\n\n", violations==0?
148 "NONE. RAF is MONOTONE: a container can never hold closure the mixture lacks."
149 :"some containers DO hold closure the mixture lacks — the design survives.");
150
151 if(violations==0)
152 printf(" MILESTONE 2: CONTAINERS WORK, BUT STATIC CLOSURE CANNOT EXPRESS RUNG 4.\n"
153 " The recursive move is sound — containers are ordinary species, they can be produced\n"
154 " and nested. But compartmentalisation buys NOTHING expressible in a presence/absence\n"
155 " type, because RAF is monotone in the reaction set: adding reactions never removes\n"
156 " closure, so a part can never sustain what the whole cannot. What ribozyme.c's\n"
157 " compartments actually bought was PRIVATISATION AGAINST PARASITES — a claim about\n"
158 " relative ABUNDANCE, not about what can exist. So milestone 3 is not more structure:\n"
159 " it is COUNTS. The type must carry how MUCH of each species is present, and the RAF\n"
160 " becomes a dynamical attractor rather than a static closure. That is a concrete,\n"
161 " measured design requirement rather than a guess — and it is the honest reason the\n"
162 " substrate is not yet ready to chain rung 3 onward.\n");
163 else
164 printf(" MILESTONE 2 PASSED as designed — proceed to expressing rungs 3 and 5.\n");
165 return 0;
166}
container.md +41 -0
……@@ -0,0 +1,41 @@
1# `container.c` — milestone 2: the recursive move works, the type does not
2
3**C1 — containers are ordinary species.** A container is a species that also has contents; contents
4may include containers. Verified: a container is a valid **reaction product**, a container **nests**
5inside another, and a container's RAF is computed over its own contents (locality is what a
6compartment *is*). The recursive move is sound.
7
8**C2 — the check that killed it.** Before building on containers, ask whether this type can express
9what rung 4 is *for*. 400 random networks × 3 random partitions each:
10
11| | |
12|---|---|
13| partitions tested | 1200 |
14| with a non-empty local RAF | 256 |
15| **holding closure the global mixture lacks** | **0** |
16
17Zero. **RAF is monotone in the reaction set** — adding reactions never removes closure — so a part
18can never sustain what the whole cannot.
19
20## What that means
21
22> Compartmentalisation buys **nothing** expressible in a presence/absence type.
23
24What `ribozyme.c`'s compartments actually bought was **privatisation against parasites**: a
25catalyst-rich compartment out-reproduces a parasite-ridden one. That is a claim about relative
26**abundance**, not about what can exist. A static closure formalism cannot state it, no matter how the
27containers are arranged.
28
29So **milestone 3 is not more structure — it is counts.** The type must carry *how much* of each
30species is present, and the RAF becomes a dynamical attractor rather than a static closure.
31
32That is a measured design requirement rather than a guess, obtained before three more milestones were
33built on a type that could not carry rung 4. It is also the honest reason the substrate is not yet
34ready to chain rung 3 onward.
35
36## Standing
37
38Milestone 1 (`substrate.c`): one type expresses rungs 1 and 2, coexisting, reproducing `rung1.c`'s
39threshold exactly and `polymer.c`'s bootstrap problem for free.
40Milestone 2 (here): the recursive move is sound; the presence/absence type is not sufficient.
41Milestone 3 (unbuilt): abundances.