/* bridge.c — bridging the rung 4->5 coordination valley: drift vs duplication.
*
* rung45 stalled: CONVERT (generalist->specialist) drops other functions' coverage ->
* viability falls -> deleterious -> purged. A coordination valley.
*
* Two candidate bridges, both ways of NOT hill-climbing straight up:
* - DRIFT (temperature): accept the small deleterious step by chance.
* - DUPLICATION: ADD a specialist without removing the generalist (size grows) -> other
* functions' coverage unchanged -> the step is NEUTRAL; once all F specialists have drifted
* in, the weakest function is covered and viability JUMPS. Neutral steps need no drift.
*
* Sweep temperature (drift strength) x {CONVERT-only, DUPLICATION}. Prediction: cold (weak
* drift) -> CONVERT stalls in the displacement valley, DUPLICATION still crosses; warm -> both
* cross. => drift and duplication are SUBSTITUTE bridges; you need at least one.
*
* build: cc -O2 -Wall -std=c11 -o bridge bridge.c -lm
*/
#include <math.h>
#include <stdio.h>
#define F 3
#define EGEN 0.2
#define LAMBDA 0.02
#define DMIN 3
#define DMAX 30
#define STEPS 400000
#define TRIES 8
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 sizeof_(int G,const int*sp){ int s=G; for(int k=0;k<F;k++) s+=sp[k]; return s; }
static double mincov(int G,const int*sp){ double m=1e9; for(int k=0;k<F;k++){ double c=sp[k]+EGEN*G; if(c<m)m=c; } return m; }
static double fit(int G,const int*sp){ return mincov(G,sp)-LAMBDA*sizeof_(G,sp); }
/* one Metropolis run from all-generalist; returns best min-coverage reached */
static double run(int dup,double TMP,int *Gout,int *spout){
int G=12, sp[F]={0,0,0};
double f=fit(G,sp);
int bG=G,bsp[F]={0,0,0}; double bmc=mincov(G,sp);
for(int t=0;t<STEPS;t++){
int G2=G, s2[F]; for(int k=0;k<F;k++) s2[k]=sp[k];
double r=urand();
if(dup && r<0.5){ /* size-changing (duplication / loss) */
if(urand()<0.5 && sizeof_(G2,s2)<DMAX){ if(urand()<0.4) G2++; else s2[(int)(xs()%F)]++; }
else if(sizeof_(G2,s2)>DMIN){ if(urand()<0.4 && G2>0) G2--; else { int k=(int)(xs()%F); if(s2[k]>0) s2[k]--; else if(G2>0) G2--; } }
} else { /* CONVERT (size fixed = displacement) */
if(urand()<0.5){ if(G2>0){ G2--; s2[(int)(xs()%F)]++; } }
else { int k=(int)(xs()%F); if(s2[k]>0){ s2[k]--; G2++; } }
}
int sz=sizeof_(G2,s2); if(sz<DMIN||sz>DMAX) continue;
double f2=fit(G2,s2), df=f2-f;
if(df>=0 || urand()<exp(df/TMP)){ G=G2; for(int k=0;k<F;k++) sp[k]=s2[k]; f=f2;
double mc=mincov(G,sp); if(mc>bmc){ bmc=mc; bG=G; for(int k=0;k<F;k++) bsp[k]=sp[k]; } }
}
*Gout=bG; for(int k=0;k<F;k++) spout[k]=bsp[k]; return bmc;
}
int main(void){
printf("=== BRIDGING THE 4->5 VALLEY: drift (temperature) vs duplication ===\n");
printf(" all-generalist baseline min-coverage = %.2f ; crossing = all 3 specialists present\n\n", EGEN*12);
double temps[4]={0.005,0.02,0.05,0.12};
printf(" %-10s %-24s %-24s\n","T (drift)","CONVERT-only","DUPLICATION");
for(int ti=0;ti<4;ti++){
int cross[2]={0,0}; double best[2]={0,0};
for(int mode=0;mode<2;mode++) for(int tr=0;tr<TRIES;tr++){
RNG=0x9e3779b97f4a7c15ULL + (unsigned long long)(ti*1000+mode*100+tr)*0x2545F4914F6CDD1DULL;
int G,sp[F]; double mc=run(mode,temps[ti],&G,sp);
if(sp[0]>0&&sp[1]>0&&sp[2]>0 && mc>EGEN*12+0.3) cross[mode]++;
if(mc>best[mode]) best[mode]=mc;
}
printf(" %-10.3f %d/%d crossed (mincov %-4.1f) %d/%d crossed (mincov %-4.1f)\n",
temps[ti],cross[0],TRIES,best[0],cross[1],TRIES,best[1]);
}
printf("\n Cold (weak drift): CONVERT stalls in the displacement valley; DUPLICATION still crosses\n");
printf(" (its steps are neutral, needing no drift). Warm: both cross. => drift and duplication\n");
printf(" are SUBSTITUTE bridges over a coordination valley — you need at least one.\n");
return 0;
}