/* rung2.c — the self-templating form: the first HEREDITY, built on rung 1.
*
* Rung 1 (RAF) self-PRODUCES but has no heritable form. Rung 2 adds structures that
* TEMPLATE copies of themselves (prion-/crystal-like): a variant propagates its OWN
* form, so which form is present is TRANSMITTED — proto-heredity. The forms compete for
* substrate that rung 1's metabolism supplies (the pool is kept fed).
*
* Dynamics = discrete replicator-with-mutation (Eigen, low-dimensional):
* x'_i = sum_j Q[i][j] f[j] x[j] / normalization ; Q[i][j] = (1-eps) if i==j else eps/(Q-1)
* f = templating rate (fitness, environment-dependent); eps = copying error.
*
* Two emergent phenomena that rung 1 lacks:
* A. COHERENT TAKEOVER + SELECTION (the "laser"): from a mix, the fittest heritable
* form excludes the rest; switch the environment and a DIFFERENT form takes over —
* heredity + selection = the system tracks its world (proto-adaptation).
* B. FIDELITY requirement: raise the copying error and the winner's dominance erodes
* toward a formless mix — heredity needs fidelity. (The SHARP version of this is
* rung 3's error catastrophe, once forms become high-dimensional sequences.)
*
* build: cc -O2 -Wall -std=c11 -o rung2 rung2.c -lm
*/
#include <math.h>
#include <stdio.h>
#define Q 4 /* number of competing self-templating forms */
/* one replicator+mutation step; returns nothing, updates x in place */
static void step(double *x,const double *f,double eps){
double nx[Q],tot=0;
for(int i=0;i<Q;i++){
nx[i]=0;
for(int j=0;j<Q;j++){
double Qij=(i==j)?(1.0-eps):(eps/(Q-1));
nx[i]+=Qij*f[j]*x[j]; /* j templates; copies land on i via the mutation matrix */
}
tot+=nx[i];
}
if(tot<1e-300)tot=1e-300;
for(int i=0;i<Q;i++) x[i]=nx[i]/tot; /* normalize: rung-1 keeps the pool fed */
}
static int argmax(const double *x){ int a=0; for(int i=1;i<Q;i++) if(x[i]>x[a])a=i; return a; }
int main(void){
printf("=== RUNG 2: SELF-TEMPLATING FORM — heredity + coherent takeover ===\n\n");
/* --- Demo A: coherent takeover, then environmental switch (adaptation) --- */
printf("A. Coherent takeover + selection (forms start as an even mix):\n");
double x[Q]={0.25,0.25,0.25,0.25};
double fA[Q]={1.00,0.90,0.80,0.70}; /* form 0 templates fastest */
double eps=0.02;
printf(" env-1 (form 0 fittest):\n");
for(int t=0;t<=80;t++){ if(t%20==0) printf(" t=%3d x=[%.2f %.2f %.2f %.2f] winner=%d\n",t,x[0],x[1],x[2],x[3],argmax(x)); step(x,fA,eps); }
double fB[Q]={0.70,0.80,0.90,1.00}; /* ENVIRONMENT SWITCH: now form 3 fittest */
printf(" env-2 (switch -> form 3 fittest): the population re-coheres onto the new winner\n");
for(int t=0;t<=80;t++){ if(t%20==0) printf(" t=%3d x=[%.2f %.2f %.2f %.2f] winner=%d\n",t,x[0],x[1],x[2],x[3],argmax(x)); step(x,fB,eps); }
/* --- Demo B: fidelity requirement (error erodes heredity) --- */
printf("\nB. Fidelity requirement — dominance of the fittest form vs copying error eps:\n");
printf(" %-7s %12s\n","eps","dominant frac");
double f[Q]={1.00,0.85,0.70,0.55};
for(int ei=0;ei<=12;ei++){
double e=ei*0.05;
double y[Q]={0.25,0.25,0.25,0.25};
for(int t=0;t<3000;t++) step(y,f,e); /* to steady state */
double dom=y[argmax(y)];
int bar=(int)(dom*40+0.5); char b[64]; for(int k=0;k<bar&&k<50;k++)b[k]='#'; b[bar<50?bar:50]=0;
printf(" %-7.2f %12.3f %s\n",e,dom,b);
}
printf("\n Low error: the fittest form dominates (heredity holds). Rising error erodes it\n");
printf(" toward 1/Q=%.2f (formless mix) — heredity needs fidelity. rung 3 makes this SHARP.\n",1.0/Q);
return 0;
}