/* bridges.c — four candidate BRIDGES past the ribozyme wall, compared head to head.
*
* ribozyme.c bootstrapped fidelity but needed TWO supplied ingredients: (1) decreed structure->catalysis
* map phi->f, (2) compartments + group selection (to privatize the public good). Each bridge removes ONE
* supplied ingredient and asks: does the fidelity/catalysis bootstrap STILL fire (mean phi rises from the
* random-entropy value ~6 toward the max 12)? Shared core so all four are apples-to-apples.
*
* BASELINE well-mixed, shared catalysis (public good, no privatization) -> the thing to beat (falls).
* A SURFACE local catalysis on a 2D grid, local replication. Privatize by SPACE, no compartments.
* B CIS copy fidelity = the strand's OWN phi (cis-acting). Privatize by ATTACHMENT, no compartments.
* C BIND compartments kept, but catalysis is EMERGENT from pairwise binding (no decreed phi->f map).
* D CLAY well-mixed + an environmental fidelity FLOOR f_clay (adsorption assist), sweep f_clay.
*
* Razor: no bridge rewards a specific sequence. phi is an emergent hairpin fold score; catalysis/fidelity
* arise from it (A,B,D) or from binding (C). Whether phi RISES is measured, never encoded.
*
* build: cc -O2 -Wall -std=c11 -o bridges bridges.c -lm
*/
#include <math.h>
#include <stdio.h>
#include <stdint.h>
#define L 24
#define PHIMAX (L/2)
#define F0 0.85
#define F1 0.999
#define BETA 2.0
#define EMPTY 0xffffffffu
static unsigned long long RNG;
static unsigned long long xs(void){ RNG^=RNG<<13; RNG^=RNG>>7; RNG^=RNG<<17; return RNG; }
static double urand(void){ return (double)(xs()>>11)*(1.0/9007199254740992.0); }
static int phi(uint32_t s){ int c=0; for(int i=0;i<PHIMAX;i++){ int a=(s>>i)&1,b=(s>>(L-1-i))&1; if(a!=b)c++; } return c; }
/* hairpin-style complementarity of a's left half against b's right half (a==b -> phi) */
static int bind(uint32_t a,uint32_t b){ int c=0; for(int i=0;i<PHIMAX;i++){ int x=(a>>i)&1,y=(b>>(L-1-i))&1; if(x!=y)c++; } return c; }
static uint32_t replicate(uint32_t t,double f){ uint32_t c=0; for(int i=0;i<L;i++){ int b=(t>>i)&1; int nb=(urand()<f)?(1-b):b; if(nb)c|=(1u<<i);} return c; }
static uint32_t randstrand(void){ uint32_t s=0; for(int b=0;b<L;b++) if(urand()<0.5) s|=(1u<<b); return s; }
/* ---- BASELINE: well-mixed, shared (public-good) catalysis. no privatization. ---- */
static double baseline(int N,int GEN,double *start){
static uint32_t pool[8000],nxt[8000];
for(int i=0;i<N;i++) pool[i]=randstrand();
{ double s=0; for(int i=0;i<N;i++) s+=phi(pool[i]); *start=s/N; }
for(int g=0;g<GEN;g++){
double mphi=0; for(int i=0;i<N;i++) mphi+=phi(pool[i]); mphi/=N; double f=F0+(F1-F0)*(mphi/PHIMAX);
double tot=0; static double cum[8000]; for(int i=0;i<N;i++){ double w=1.0+BETA*(1.0-(double)phi(pool[i])/PHIMAX); tot+=w; cum[i]=tot; }
for(int i=0;i<N;i++){ double r=urand()*tot; int lo=0,hi=N-1; while(lo<hi){int m=(lo+hi)/2; if(cum[m]<r)lo=m+1; else hi=m;} nxt[i]=replicate(pool[lo],f); }
for(int i=0;i<N;i++) pool[i]=nxt[i];
}
double s=0; for(int i=0;i<N;i++) s+=phi(pool[i]); return s/N;
}
/* ---- B CIS: fidelity = the strand's OWN phi (private by construction). well-mixed. ---- */
static double cis(int N,int GEN,double *start){
static uint32_t pool[8000],nxt[8000];
for(int i=0;i<N;i++) pool[i]=randstrand();
{ double s=0; for(int i=0;i<N;i++) s+=phi(pool[i]); *start=s/N; }
for(int g=0;g<GEN;g++){
double tot=0; static double cum[8000]; for(int i=0;i<N;i++){ double w=1.0+BETA*(1.0-(double)phi(pool[i])/PHIMAX); tot+=w; cum[i]=tot; }
for(int i=0;i<N;i++){ double r=urand()*tot; int lo=0,hi=N-1; while(lo<hi){int m=(lo+hi)/2; if(cum[m]<r)lo=m+1; else hi=m;} int par=lo;
double f=F0+(F1-F0)*((double)phi(pool[par])/PHIMAX); nxt[i]=replicate(pool[par],f); }
for(int i=0;i<N;i++) pool[i]=nxt[i];
}
double s=0; for(int i=0;i<N;i++) s+=phi(pool[i]); return s/N;
}
/* ---- A SURFACE: local catalysis (neighbours) + local replication on a 2D grid. no compartments. ---- */
#define G 48
static uint32_t grd[G*G];
static double surface(int GEN,double *start){
int nocc=0; for(int i=0;i<G*G;i++){ if(urand()<0.5){ grd[i]=randstrand(); nocc++; } else grd[i]=EMPTY; }
{ double s=0;int c=0; for(int i=0;i<G*G;i++) if(grd[i]!=EMPTY){ s+=phi(grd[i]); c++; } *start=c?s/c:0; }
for(int g=0;g<GEN;g++){
/* replication attempts */
for(int t=0;t<G*G;t++){
int x=(int)(xs()%G), y=(int)(xs()%G), c=y*G+x; if(grd[c]==EMPTY) continue;
double w=1.0+BETA*(1.0-(double)phi(grd[c])/PHIMAX); /* parasites replicate faster */
if(urand()> w/(1.0+BETA)) continue;
int dx=(int)(xs()%3)-1, dy=(int)(xs()%3)-1; int nx=(x+dx+G)%G, ny=(y+dy+G)%G, nc=ny*G+nx;
if(grd[nc]!=EMPTY) continue;
double sp=0; int cn=0; /* LOCAL catalysis: neighbourhood mean phi */
for(int ddy=-1;ddy<=1;ddy++)for(int ddx=-1;ddx<=1;ddx++){ int a=((y+ddy+G)%G)*G+((x+ddx+G)%G); if(grd[a]!=EMPTY){ sp+=phi(grd[a]); cn++; } }
double mphi=cn?sp/cn:0; double f=F0+(F1-F0)*(mphi/PHIMAX);
grd[nc]=replicate(grd[c],f);
}
for(int i=0;i<G*G;i++) if(grd[i]!=EMPTY && urand()<0.10) grd[i]=EMPTY; /* degradation */
}
double s=0;int c=0; for(int i=0;i<G*G;i++) if(grd[i]!=EMPTY){ s+=phi(grd[i]); c++; } return c?s/c:0;
}
/* ---- C BIND: compartments kept, catalysis EMERGENT from pairwise binding (no decreed phi->f). ---- */
static double bindbridge(int ncomp,int csz,int GEN,double *start){
int TOT=ncomp*csz; static uint32_t pool[8000],nxt[8000];
for(int i=0;i<TOT;i++) pool[i]=randstrand();
{ double s=0; for(int i=0;i<TOT;i++) s+=phi(pool[i]); *start=s/TOT; }
for(int g=0;g<GEN;g++){
for(int cmp=0;cmp<ncomp;cmp++){ int base=cmp*csz;
double mb=0; for(int a=0;a<csz;a++){ int best=0; for(int b=0;b<csz;b++){ int v=bind(pool[base+a],pool[base+b]); if(v>best)best=v; } mb+=best; } mb/=csz;
double f=F0+(F1-F0)*(mb/PHIMAX);
double tot=0; static double cum[8000]; for(int k=0;k<csz;k++){ double w=1.0+BETA*(1.0-(double)phi(pool[base+k])/PHIMAX); tot+=w; cum[base+k]=tot; }
for(int k=0;k<csz;k++){ double r=urand()*tot; int lo=0,hi=csz-1; while(lo<hi){int m=(lo+hi)/2; if(cum[base+m]<r)lo=m+1; else hi=m;} nxt[base+k]=replicate(pool[base+lo],f); }
}
for(int i=0;i<TOT;i++) pool[i]=nxt[i];
/* group selection: productivity = mean binding; assort daughters */
static double cumP[2000]; double tp=0;
for(int cmp=0;cmp<ncomp;cmp++){ int base=cmp*csz; double mb=0; for(int a=0;a<csz;a++){ int best=0; for(int b=0;b<csz;b++){ int v=bind(pool[base+a],pool[base+b]); if(v>best)best=v; } mb+=best; } tp+=mb/csz; cumP[cmp]=tp; }
for(int cmp=0;cmp<ncomp;cmp++){ double r=urand()*tp; int lo=0,hi=ncomp-1; while(lo<hi){int m=(lo+hi)/2; if(cumP[m]<r)lo=m+1; else hi=m;} int par=lo;
for(int k=0;k<csz;k++) nxt[cmp*csz+k]=pool[par*csz+(int)(xs()%csz)]; }
for(int i=0;i<TOT;i++) pool[i]=nxt[i];
}
double s=0; for(int i=0;i<TOT;i++) s+=phi(pool[i]); return s/TOT;
}
/* ---- D CLAY: well-mixed + environmental fidelity FLOOR f_clay (adsorption assist). ---- */
static double clay(int N,int GEN,double fclay,double *start){
static uint32_t pool[8000],nxt[8000];
for(int i=0;i<N;i++) pool[i]=randstrand();
{ double s=0; for(int i=0;i<N;i++) s+=phi(pool[i]); *start=s/N; }
for(int g=0;g<GEN;g++){
double mphi=0; for(int i=0;i<N;i++) mphi+=phi(pool[i]); mphi/=N; double fcat=F0+(F1-F0)*(mphi/PHIMAX); double f=fcat>fclay?fcat:fclay;
double tot=0; static double cum[8000]; for(int i=0;i<N;i++){ double w=1.0+BETA*(1.0-(double)phi(pool[i])/PHIMAX); tot+=w; cum[i]=tot; }
for(int i=0;i<N;i++){ double r=urand()*tot; int lo=0,hi=N-1; while(lo<hi){int m=(lo+hi)/2; if(cum[m]<r)lo=m+1; else hi=m;} nxt[i]=replicate(pool[lo],f); }
for(int i=0;i<N;i++) pool[i]=nxt[i];
}
double s=0; for(int i=0;i<N;i++) s+=phi(pool[i]); return s/N;
}
static const char* verdict(double st,double en){ if(en>st+2.0)return "IGNITES"; if(en>st+0.5)return "partial"; if(en<st-0.5)return "falls"; return "~flat"; }
int main(void){
unsigned long long seed=0x9e3779b97f4a7c15ULL;
double st,en;
printf("=== Four bridges past the ribozyme wall (random start phi~6, max 12; IGNITES = phi climbs) ===\n\n");
printf(" bridge | removes | phi start->end | verdict\n");
printf(" --------------+--------------------+----------------+--------\n");
RNG=seed; en=baseline(3000,250,&st); printf(" BASELINE | (nothing) | %.2f -> %.2f | %s\n",st,en,verdict(st,en));
RNG=seed; en=surface(300,&st); printf(" A surface | compartments(->space) | %.2f -> %.2f | %s\n",st,en,verdict(st,en));
RNG=seed; en=cis(3000,250,&st); printf(" B cis-acting | compartments(->cis) | %.2f -> %.2f | %s\n",st,en,verdict(st,en));
RNG=seed; en=bindbridge(400,8,180,&st); printf(" C bind (emrg) | decreed phi->f map | %.2f -> %.2f | %s\n",st,en,verdict(st,en));
printf(" D clay floor | (adds env fidelity assist), sweep f_clay:\n");
double fcs[]={0.85,0.92,0.97,0.99}; for(int i=0;i<4;i++){ RNG=seed; en=clay(3000,200,fcs[i],&st); printf(" f_clay=%.2f | | %.2f -> %.2f | %s\n",fcs[i],st,en,verdict(st,en)); }
printf("\n");
printf(" (ribozyme.c reference: supplied compartments size<=8 -> phi ~6->11.6 IGNITES; well-mixed falls.)\n");
printf(" Compare: which bridges make phi RISE while removing a supplied ingredient? Read verdicts above.\n");
return 0;
}