OverviewFilesCommitsIssuesDocsReleasesPeers

basal-agent / ribozyme.c

118 lines · c ref:
/* ribozyme.c — the deepest attempt: does a replicase that BOOTSTRAPS ITS OWN FIDELITY ignite from a
 * random low-fidelity soup? And does it need compartments to survive parasites? (digital-analogy land)
 *
 * polymer.c hit Eigen's bootstrap paradox: heritable function needs fidelity un-catalyzed templating
 * can't supply, and the replicase that would supply it needs the fidelity first. The proposed escape is a
 * ribozyme replicase that improves fidelity for its own kind -> positive feedback over the threshold.
 *
 * RAZOR (no encoded winner): catalysis is an EMERGENT STRUCTURAL property, not a named sequence. A strand's
 * catalytic quality phi(s) = how well it folds into a HAIRPIN (self-complementarity: pair i with L-1-i,
 * complementary when the bits differ, since 0 pairs 1). A fixed fold->function rule; MANY sequences reach
 * high phi. FIDELITY EMERGES from catalysis: f = f0 + (F1-f0)*(meanphi/phimax) -- more replicase present,
 * higher-fidelity copying for all in that compartment (the bootstrap coupling). NOTHING rewards being the
 * replicase directly. The CATCH (what makes it honest): catalysis is a PUBLIC GOOD, and structured catalysts
 * pay a replication cost while unstructured PARASITES (low phi) replicate faster and free-ride (weight
 * 1+beta*(1-phi/phimax)). Measured: does phi (hence fidelity) RISE from a random start, or do parasites
 * crush it? WELL-MIXED (one big pool, no group selection) vs COMPARTMENTS (stochastic corrector: small
 * protocells, random assortment at division, between-compartment selection on catalytic content).
 *
 * build:  cc -O2 -Wall -std=c11 -o ribozyme ribozyme.c -lm
 */
#include <math.h>
#include <stdio.h>
#include <stdint.h>

#define L     24
#define PHIMAX (L/2)          /* max hairpin pairs = 12 */
#define TOTAL 4800            /* total strands (= NCOMP*CSZ for the compartment arm) */
#define GEN   200
#define F0    0.85            /* un-catalyzed fidelity */
#define F1    0.999           /* fully-catalyzed (good ribozyme) fidelity */
#define BETA  2.0             /* parasite advantage: low-phi strands replicate 1+BETA x faster */

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; }
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 pool[TOTAL], nxt[TOTAL];

/* run: ncomp compartments of csz (ncomp*csz=TOTAL). group=1 enables between-compartment selection+assortment.
   returns final mean phi; writes final mean fidelity and start mean phi. */
static double run(int ncomp,int csz,int group,double *f_end,double *phi_start){
	for(int i=0;i<TOTAL;i++){ uint32_t s=0; for(int b=0;b<L;b++) if(urand()<0.5) s|=(1u<<b); pool[i]=s; }
	{ double sp=0; for(int i=0;i<TOTAL;i++) sp+=phi(pool[i]); *phi_start=sp/TOTAL; }

	for(int g=0;g<GEN;g++){
		/* within each compartment: Wright-Fisher replication; fidelity from mean phi; parasites replicate faster */
		for(int cmp=0;cmp<ncomp;cmp++){
			int base=cmp*csz; double sphi=0; for(int k=0;k<csz;k++) sphi+=phi(pool[base+k]); double mphi=sphi/csz;
			double f=F0+(F1-F0)*(mphi/PHIMAX);
			double tot=0; static double w[TOTAL]; static double cum[TOTAL];
			for(int k=0;k<csz;k++){ double ww=1.0+BETA*(1.0-(double)phi(pool[base+k])/PHIMAX); tot+=ww; cum[base+k]=tot; (void)w; }
			for(int k=0;k<csz;k++){ double r=urand()*tot; int lo=0,hi=csz-1; while(lo<hi){int mid=(lo+hi)/2; if(cum[base+mid]<r)lo=mid+1; else hi=mid;} nxt[base+k]=replicate(pool[base+lo],f); }
		}
		for(int i=0;i<TOTAL;i++) pool[i]=nxt[i];

		if(group){
			/* between-compartment: productivity = mean phi (catalytic content); sample parents ~productivity;
			   seed each daughter by RANDOM ASSORTMENT (draw csz strands w/ replacement) -> stochastic corrector */
			static double P[TOTAL/1], cumP[TOTAL/1]; double tp=0;
			for(int cmp=0;cmp<ncomp;cmp++){ int base=cmp*csz; double sphi=0; for(int k=0;k<csz;k++) sphi+=phi(pool[base+k]); tp+=sphi/csz; cumP[cmp]=tp; P[cmp]=0; (void)P; }
			for(int cmp=0;cmp<ncomp;cmp++){
				double r=urand()*tp; int lo=0,hi=ncomp-1; while(lo<hi){int mid=(lo+hi)/2; if(cumP[mid]<r)lo=mid+1; else hi=mid;} int par=lo;
				for(int k=0;k<csz;k++){ int src=par*csz+(int)(xs()%csz); nxt[cmp*csz+k]=pool[src]; }
			}
			for(int i=0;i<TOTAL;i++) pool[i]=nxt[i];
		}
	}
	double sp=0; for(int i=0;i<TOTAL;i++) sp+=phi(pool[i]); double mphi=sp/TOTAL;
	*f_end=F0+(F1-F0)*(mphi/PHIMAX); return mphi;
}

int main(void){
	unsigned long long seeds[]={0x9e3779b97f4a7c15ULL,0xd1b54a32d192ed03ULL,0x2545f4914f6cdd1dULL};
	int NS=sizeof(seeds)/sizeof(seeds[0]);
	printf("=== Ribozyme replicase bootstrap: does fidelity ignite from a random soup? ===\n");
	printf("  Catalysis = hairpin fold score phi (emergent, no encoded winner). Fidelity = f0 + (f1-f0)*phi/%d.\n",PHIMAX);
	printf("  Parasites (low phi) replicate %.0fx faster and free-ride. f0=%.2f, f1=%.3f. %d strands, %d gens, %d seeds.\n",1+BETA,F0,F1,TOTAL,GEN,NS);
	printf("  Random start: mean phi ~%d (fidelity ~%.2f). RISE = bootstrap ignites; FALL = parasites win.\n\n",PHIMAX/2,F0+(F1-F0)*0.5);
	printf("  arm                         | mean phi (start->end of %2d) | fidelity end\n",PHIMAX);
	printf("  ----------------------------+-----------------------------+-------------\n");

	double wmS=0,wmE=0,wmF=0;
	for(int s=0;s<NS;s++){ double fe,ps; RNG=seeds[s]; wmE+=run(1,TOTAL,0,&fe,&ps); wmS+=ps; wmF+=fe; }
	wmS/=NS;wmE/=NS;wmF/=NS;
	printf("  WELL-MIXED (no compartments)| %.2f -> %.2f                | %.3f\n", wmS,wmE,wmF);

	/* sweep compartment SIZE: the stochastic corrector predicts small compartments are required
	   (more assortment variance -> parasite-free daughters). Report the DEPENDENCE, do not cherry-pick. */
	int sizes[]={4,8,16,32}; int nSz=sizeof(sizes)/sizeof(int);
	double best_end=wmE; int best_sz=0; double cpE_small=0,cpS_small=0;
	for(int z=0;z<nSz;z++){ int csz=sizes[z], ncomp=TOTAL/csz;
		double cS=0,cE=0,cF=0; for(int s=0;s<NS;s++){ double fe,ps; RNG=seeds[s]; cE+=run(ncomp,csz,1,&fe,&ps); cS+=ps; cF+=fe; }
		cS/=NS;cE/=NS;cF/=NS;
		printf("  COMPARTMENTS (%4d x %2d)    | %.2f -> %.2f                | %.3f\n", ncomp,csz, cS,cE,cF);
		if(cE>best_end){ best_end=cE; best_sz=csz; }
		if(csz==sizes[0]){ cpE_small=cE; cpS_small=cS; }
	}
	printf("\n");

	int wm_up = (wmE > wmS+0.5);
	int cp_up = (cpE_small > cpS_small+0.5) || (best_sz>0 && best_end>wmS+0.8);
	printf("  well-mixed : phi %s (%.2f->%.2f)\n", wm_up?"ROSE":(wmE<wmS-0.5?"FELL":"~flat"), wmS,wmE);
	printf("  compartments: best at size=%d -> phi end %.2f (vs random start %.2f) %s\n", best_sz, best_end, wmS, cp_up?"ROSE":"~flat/fell");
	printf("\n");
	if(cp_up && !wm_up)
		printf("  => BOOTSTRAP IGNITES, BUT ONLY WITH COMPARTMENTS. Well-mixed: catalysis is a public good, parasites\n     free-ride and drive phi (hence fidelity) DOWN -- the replicase can't pay its own way. Compartments\n     (stochastic corrector): random assortment makes some protocells catalyst-rich; between-compartment\n     selection on catalytic content spreads them, out-running the within-compartment parasites -> phi and\n     fidelity RISE from the random soup. The replicase bootstraps its own fidelity -- but the escape from\n     Eigen's paradox is COMPARTMENTALIZATION, matching the field (Szathmary-Demeter stochastic corrector)\n     and our own 'heredity may REQUIRE compartments' finding. HONEST BOUND: I supplied the fold->catalysis\n     rule and the fidelity coupling as physics; whether THOSE arise unaided is the deeper edge.\n");
	else if(cp_up && wm_up)
		printf("  => Bootstrap ignites even well-mixed -- parasite pressure (BETA) too weak to create the public-\n     goods tragedy here; the compartment result is then not decisive. Raise BETA and re-examine.\n");
	else if(!cp_up)
		printf("  => Bootstrap does NOT ignite even with compartments -- honest null: parasites win at both levels\n     in this regime; the replicase cannot bootstrap its fidelity here. Do not tune to force it.\n");
	else
		printf("  => Mixed/ambiguous outcome -- report the numbers as-is.\n");
	return 0;
}