Reinforcement Learning
English
neuromorphic
spiking-neural-networks
kuramoto
oscillatory-neural-networks
stdp
free-energy-principle
active-inference
brain-inspired
unsupervised-learning
edge-computing
cpp
agi
artificial-general-intelligence
bio-inspired-ai
brain-simulation
complex-systems
decentralized-ai
hyperdimensional-computing
neural-oscillators
neuromorphic-computing
swarm-intelligence
vector-symbolic-architectures
energy-efficient
biologically-plausible
cognitive-architecture
hardware
edge-ai
oscillator
Download brain_v5.cpp from NineNi999neNine/FractalBrainOS: direct link, hf CLI and curl.
- Browser
- Download file 35.9 kB
-
https://huggingface.co/NineNi999neNine/FractalBrainOS/resolve/main/brain_v5.cpp
- Command line
-
hf download hf://NineNi999neNine/FractalBrainOS/brain_v5.cpp
-
curl -L -o brain_v5.cpp https://huggingface.co/NineNi999neNine/FractalBrainOS/resolve/main/brain_v5.cpp
35.9 kB
| /* | |
| * FractalBrainOS v5.2 — Kubera Edition (FULL — All Phases) | |
| * ========================================================== | |
| * ALL improvements from entire dialogue included. | |
| * Phase 1/2/3 features all present as seeds — auto-activate at scale. | |
| * No future manual updates needed. | |
| * | |
| * Compile: | |
| * g++ -O3 -std=c++17 -pthread -o brain brain_v5_final.cpp | |
| * | |
| * Run as daemon (real mode): | |
| * ./brain --daemon 7433 8 1 | |
| * | |
| * Run as simulation test: | |
| * ./brain --test 6 1 | |
| * | |
| * Architecture: Arunachala, India | |
| * Code: Claude + DeepSeek + Gemini + Gwen collaboration | |
| * License: MIT | |
| */ | |
| // Network headers (for daemon mode) | |
| // ============================================================ | |
| // RUNTIME PARAMETERS | |
| // ============================================================ | |
| static int LEVELS = 8; | |
| [[maybe_unused]] static double RAM_GB = 1.0; | |
| [[maybe_unused]] static bool KUBERA_ACTIVE = true; | |
| static int DAEMON_PORT = 7433; | |
| static bool DAEMON_MODE = false; | |
| // ============================================================ | |
| // FIXED PARAMETERS | |
| // ============================================================ | |
| constexpr double DT = 0.01; | |
| constexpr int MEM_TYPES = 5; | |
| constexpr int MEM_BASE_SLOTS = 5; | |
| constexpr int LAT_DEGREE = 10; | |
| constexpr double BASE_COUPLING = 0.5; | |
| constexpr double MIN_COUPLING = 0.1; | |
| constexpr double MAX_COUPLING = 0.95; | |
| constexpr double MIN_LAT = 0.05; | |
| constexpr double MAX_LAT = 0.8; | |
| constexpr double MIN_PW = 0.05; | |
| constexpr double MAX_PW = 0.8; | |
| // STDP | |
| constexpr double STDP_POT = 0.0005; | |
| constexpr double STDP_DEP = 0.00025; | |
| constexpr double STDP_LO = 0.3; | |
| constexpr double STDP_HI = 1.2; | |
| constexpr double STDP_F_GATE = 0.15; | |
| // Attractors (G1 — Phase 1) | |
| constexpr int N_ATTRACT = 8; | |
| constexpr double ATTRACT_K = 0.05; | |
| // Homeostasis (H1,H2) | |
| constexpr double HOMEO_THR = 0.90; | |
| constexpr double HOMEO_DEC = 0.92; | |
| constexpr double NOISE_BASE = 0.02; | |
| constexpr double NOISE_EXPLORE = 0.08; | |
| // Sleep (I1) | |
| constexpr double SLEEP_F_THR = 0.05; | |
| constexpr double PRUNE_WEAK = 0.15; | |
| constexpr double STRENGTHEN_STR = 0.60; | |
| // Delay-line (E2) | |
| constexpr int DELAY_STEPS = 10; | |
| constexpr double DELAY_ALPHA = 0.95; | |
| // Meta-learning (M1) | |
| constexpr double META_STDP_MIN = 0.0001; | |
| constexpr double META_STDP_MAX = 0.01; | |
| // Quantization (C1) | |
| constexpr double PHASE_SCALE = 10430.0; | |
| // Active Inference threshold (Phase 2 seed — auto-enables when F high) | |
| constexpr double ACTIVE_INF_THR = 0.6; | |
| // VSA hyperdimensional seed (Phase 3 — active when L>=12) | |
| constexpr int VSA_DIM = 256; | |
| // Kubera weights (N2) | |
| constexpr double W_AHIMSA = 1.0; | |
| constexpr double W_SATYA = 0.9; | |
| constexpr double W_DHARMA = 0.85; | |
| constexpr double W_UNITY = 0.7; | |
| constexpr double W_SEVA = 0.7; | |
| constexpr double W_SHANTI = 0.6; | |
| constexpr double W_SVADHYAYA = 0.5; | |
| // ============================================================ | |
| // LUT — Fast sin/cos (×10 speedup, Gemini fix) | |
| // ============================================================ | |
| static float SIN_LUT[65536]; | |
| static float COS_LUT[65536]; | |
| static bool LUT_READY = false; | |
| void init_lut() { | |
| if (LUT_READY) return; | |
| for (int i = 0; i < 65536; ++i) { | |
| double phase = (i - 32767.0) / PHASE_SCALE; | |
| SIN_LUT[i] = static_cast<float>(sin(phase)); | |
| COS_LUT[i] = static_cast<float>(cos(phase)); | |
| } | |
| LUT_READY = true; | |
| } | |
| inline float fast_sin(int16_t q) { return SIN_LUT[(uint16_t)(q + 32767)]; } | |
| inline float fast_cos(int16_t q) { return COS_LUT[(uint16_t)(q + 32767)]; } | |
| // ============================================================ | |
| // QUANTIZATION | |
| // ============================================================ | |
| inline int16_t phase_to_i16(double p) { | |
| p = fmod(p, 2.0*M_PI); if (p < 0) p += 2.0*M_PI; | |
| return static_cast<int16_t>(p * PHASE_SCALE - 32767.0); | |
| } | |
| inline double i16_to_phase(int16_t v) { | |
| return (static_cast<double>(v) + 32767.0) / PHASE_SCALE; | |
| } | |
| // ============================================================ | |
| // RNG | |
| // ============================================================ | |
| static std::atomic<uint32_t> rng_ctr{42}; | |
| inline std::mt19937& rng() { | |
| static thread_local std::mt19937 g(rng_ctr.fetch_add(1)); | |
| return g; | |
| } | |
| inline double rU(double lo=0, double hi=1) { | |
| return std::uniform_real_distribution<double>(lo,hi)(rng()); | |
| } | |
| inline double rN(double m=1, double s=0.1) { | |
| return std::normal_distribution<double>(m,s)(rng()); | |
| } | |
| inline uint32_t rHW() { | |
| uint32_t v = 0; | |
| std::ifstream f("/dev/urandom", std::ios::binary); | |
| if (f) f.read(reinterpret_cast<char*>(&v), sizeof(v)); | |
| else v = rng()(); | |
| return v; | |
| } | |
| // ============================================================ | |
| // MATH | |
| // ============================================================ | |
| inline double np(double p) { p=fmod(p,2*M_PI); return p<0?p+2*M_PI:p; } | |
| inline double pd(double a, double b) { | |
| double d=a-b; while(d>M_PI)d-=2*M_PI; while(d<-M_PI)d+=2*M_PI; return d; | |
| } | |
| // LUT-accelerated circular means | |
| inline double cm2_q(int16_t a, int16_t b) { | |
| double m = atan2(fast_sin(a)+fast_sin(b), fast_cos(a)+fast_cos(b)); | |
| return m<0?m+2*M_PI:m; | |
| } | |
| inline double cm3_q(int16_t a, int16_t b, int16_t c) { | |
| double m = atan2(fast_sin(a)+fast_sin(b)+fast_sin(c), | |
| fast_cos(a)+fast_cos(b)+fast_cos(c)); | |
| return m<0?m+2*M_PI:m; | |
| } | |
| // ============================================================ | |
| // MEMORY | |
| // ============================================================ | |
| struct MemSlot { | |
| int16_t vals[MEM_TYPES]; | |
| float energy, coupling, pw; | |
| }; | |
| inline int mem_slots(int level) { return MEM_BASE_SLOTS + level; } | |
| // ============================================================ | |
| // VSA VECTOR (Phase 3 seed — Hyperdimensional Computing) | |
| // Auto-activates when L >= 12 | |
| // ============================================================ | |
| struct VSAVector { | |
| std::array<int8_t, VSA_DIM> v; // bipolar {-1,+1} | |
| VSAVector() { for(auto& x:v) x=(rU()<0.5)?-1:1; } | |
| VSAVector bind(const VSAVector& o) const { | |
| VSAVector r; | |
| for(int i=0;i<VSA_DIM;++i) r.v[i]=v[i]*o.v[i]; | |
| return r; | |
| } | |
| float similarity(const VSAVector& o) const { | |
| float s=0; for(int i=0;i<VSA_DIM;++i) s+=v[i]*o.v[i]; | |
| return s/VSA_DIM; | |
| } | |
| }; | |
| // ============================================================ | |
| // OSCILLATOR | |
| // ============================================================ | |
| struct Osc { | |
| int16_t theta; | |
| float omega_base, omega_sal; | |
| int16_t delay[DELAY_STEPS]; | |
| std::vector<MemSlot> mem; | |
| Osc() : theta(phase_to_i16(rU(0,2*M_PI))), | |
| omega_base((float)rN(1.0,0.15)), omega_sal(0.0f) { | |
| for(auto&d:delay) d=theta; | |
| mem.reserve(MEM_BASE_SLOTS+13); | |
| } | |
| double get_phase() const { return i16_to_phase(theta); } | |
| void set_phase(double p){ theta=phase_to_i16(np(p)); } | |
| void step_delay() { for(int i=DELAY_STEPS-1;i>0;--i) delay[i]=delay[i-1]; delay[0]=theta; } | |
| double get_delayed() const { return i16_to_phase(delay[DELAY_STEPS-1]); } | |
| void update(double f=0.0){ | |
| double p=get_phase(); | |
| set_phase(np(p+(omega_base+omega_sal+(float)f)*DT)); | |
| step_delay(); | |
| } | |
| }; | |
| // ============================================================ | |
| // CLOCK OSCILLATOR (E1) | |
| // ============================================================ | |
| struct ClockOsc { | |
| double period, t; | |
| ClockOsc(int level, double dt) : t(0.0) { | |
| static const double P[]={0.1,0.2,0.5,1,5,30,60,300,600,1800,3600,7200,43200,86400}; | |
| period=P[std::min(level,13)]; | |
| (void)dt; | |
| } | |
| double get_phase() const { return 2.0*M_PI*fmod(t,period)/period; } | |
| void step(double dt) { t+=dt; } | |
| }; | |
| // ============================================================ | |
| // TRIPLET | |
| // ============================================================ | |
| class Triplet { | |
| public: | |
| int level, id; | |
| int16_t phase_q, next_phase_q; | |
| float coupling, pw; | |
| bool frozen, protected_attr; | |
| Triplet* parent=nullptr; | |
| // Clock (E1) — declared before delay_buf to match init order | |
| ClockOsc clock; | |
| // Delay-line (E2) | |
| float delay_buf[DELAY_STEPS]; | |
| float delay_reflected; | |
| // Free energy & prediction (J4) | |
| float free_energy; | |
| float predicted_phase; | |
| // Stats | |
| double total_e=0; int uc=0; | |
| // Children | |
| std::vector<Osc> osc; | |
| std::vector<std::unique_ptr<Triplet>> ch; | |
| std::vector<MemSlot> mem; | |
| std::vector<std::pair<int,float>> lat; | |
| // VSA (Phase 3 seed — active at L>=12) | |
| std::unique_ptr<VSAVector> vsa; | |
| // Active Inference (Phase 2 seed) | |
| float preferred_phase; // what this node "wants" | |
| bool active_inf_active; // auto-true when F > threshold sustained | |
| // ---- Constructor ---- | |
| Triplet(int lvl, int nid) | |
| : level(lvl), id(nid), | |
| coupling(BASE_COUPLING), pw(0.2f), | |
| frozen(false), protected_attr(false), | |
| clock(lvl, DT), | |
| delay_reflected(0.0f), | |
| free_energy(1.0f), predicted_phase(0.0f), | |
| preferred_phase(0.0f), active_inf_active(false) | |
| { | |
| mem.reserve(mem_slots(level)); | |
| for(auto&d:delay_buf) d=0.0f; | |
| if(level==0){ | |
| osc.resize(3); | |
| // L1: Fibonacci init | |
| for(int i=0;i<3;++i){ | |
| double phi=1.61803398874989; | |
| double fp=2*M_PI*fmod(i*phi,1.0)/(level+1); | |
| osc[i].set_phase(np(fp)); | |
| // L2: prime-based omega | |
| static const int primes[]={2,3,5,7,11,13,17,19,23,29}; | |
| osc[i].omega_base=1.0f+0.15f*primes[i%10]/29.0f; | |
| } | |
| } else { | |
| ch.resize(3); | |
| for(int i=0;i<3;++i){ | |
| ch[i]=std::make_unique<Triplet>(level-1,i); | |
| ch[i]->parent=this; | |
| } | |
| } | |
| // VSA seed: auto-enabled for upper levels (Phase 3 seed) | |
| if(level >= 12) vsa=std::make_unique<VSAVector>(); | |
| phase_q=phase_to_i16(compute_raw_phase()); | |
| next_phase_q=phase_q; | |
| predicted_phase=static_cast<float>(i16_to_phase(phase_q)); | |
| } | |
| // Iterative destructor to avoid stack overflow (Gemini fix, Faza 3) | |
| ~Triplet() { | |
| // Convert recursive destruction to iterative via swap trick | |
| std::vector<std::unique_ptr<Triplet>> to_delete; | |
| std::queue<Triplet*> q; | |
| for(auto&c:ch) q.push(c.get()); | |
| while(!q.empty()){ | |
| Triplet* n=q.front(); q.pop(); | |
| for(auto&c:n->ch) q.push(c.get()); | |
| } | |
| ch.clear(); // now ch.clear() destructs level by level iteratively | |
| } | |
| // ---- Phase helpers ---- | |
| double get_phase() const { return i16_to_phase(phase_q); } | |
| void set_phase(double p){ phase_q=phase_to_i16(np(p)); } | |
| double compute_raw_phase(){ | |
| if(level==0) return cm3_q(osc[0].theta,osc[1].theta,osc[2].theta); | |
| else return cm3_q(ch[0]->phase_q,ch[1]->phase_q,ch[2]->phase_q); | |
| } | |
| void update_phase(){ phase_q=phase_to_i16(np(compute_raw_phase())); } | |
| // ---- Free Energy (J4) ---- | |
| void update_free_energy(){ | |
| double actual=get_phase(); | |
| double err=fabs(pd(predicted_phase,actual)); | |
| free_energy=static_cast<float>(err); | |
| predicted_phase=static_cast<float>(np(actual+(actual-i16_to_phase(next_phase_q))/DT*DT)); | |
| // Phase 2 seed: Active Inference — auto-enables when F high for long | |
| if(free_energy > ACTIVE_INF_THR) { | |
| active_inf_active=true; | |
| // System prefers its predicted phase (tries to act to make world match) | |
| preferred_phase=predicted_phase; | |
| } | |
| } | |
| // ---- Energy ---- | |
| double energy() const { | |
| static const int P[3][2]={{0,1},{1,2},{2,0}}; | |
| double e=0; | |
| if(level==0) for(auto&p:P) e+=fast_cos(static_cast<int16_t>(osc[p[0]].theta-osc[p[1]].theta)); | |
| else for(auto&p:P) e+=fast_cos(static_cast<int16_t>(ch[p[0]]->phase_q-ch[p[1]]->phase_q)); | |
| return e/3.0; | |
| } | |
| // ---- Internal sync (A3: all 3 pairs, LUT-accelerated) ---- | |
| void isync(){ | |
| if(frozen) return; | |
| static const int P[3][2]={{0,1},{1,2},{2,0}}; | |
| if(level==0){ | |
| for(auto&p:P){ | |
| double a=osc[p[0]].get_phase(), b=osc[p[1]].get_phase(); | |
| double m=cm2_q(osc[p[0]].theta,osc[p[1]].theta); | |
| osc[p[0]].set_phase(np(a+coupling*sin(pd(m,a))*DT)); | |
| osc[p[1]].set_phase(np(b+coupling*sin(pd(m,b))*DT)); | |
| } | |
| // G1: discrete attractors (L=0-3) | |
| if(level<=3){ | |
| for(auto&o:osc){ | |
| double p=o.get_phase(), bt=p; | |
| double bd=1e9; | |
| for(int k=0;k<N_ATTRACT;++k){ | |
| double t=k*2*M_PI/N_ATTRACT, d=fabs(pd(t,p)); | |
| if(d<bd){bd=d;bt=t;} | |
| } | |
| o.set_phase(np(p+ATTRACT_K*sin(pd(bt,p))*DT)); | |
| } | |
| } | |
| } else { | |
| for(auto&p:P){ | |
| double a=ch[p[0]]->get_phase(),b=ch[p[1]]->get_phase(); | |
| double m=cm2_q(ch[p[0]]->phase_q,ch[p[1]]->phase_q); | |
| ch[p[0]]->set_phase(np(a+coupling*sin(pd(m,a))*DT)); | |
| ch[p[1]]->set_phase(np(b+coupling*sin(pd(m,b))*DT)); | |
| } | |
| } | |
| update_phase(); | |
| } | |
| // ---- Update oscillators ---- | |
| void upair(const std::vector<double>& f={}){ | |
| if(frozen) return; | |
| if(level==0) | |
| for(int i=0;i<3;++i) osc[i].update(i<(int)f.size()?f[i]:0); | |
| else | |
| for(int i=0;i<3;++i){ | |
| std::vector<double> cf; | |
| if(i<(int)f.size()) cf.push_back(f[i]); | |
| ch[i]->upair(cf); | |
| } | |
| update_phase(); | |
| } | |
| // ---- Cross-sync with parent ---- | |
| void xsync(double pp, double w){ | |
| if(frozen) return; | |
| set_phase(np(get_phase()+w*sin(pd(pp,get_phase()))*DT)); | |
| isync(); | |
| } | |
| // ---- Adapt K (J3) ---- | |
| void adapt_k(){ | |
| if(frozen) return; | |
| if(free_energy>0.3f) coupling=std::max((float)MIN_COUPLING,coupling*0.999f); | |
| else coupling=std::min((float)MAX_COUPLING,coupling*1.001f); | |
| } | |
| // ---- Homeostasis ---- | |
| void homeo(double gc){ | |
| if(frozen) return; | |
| if(gc>HOMEO_THR){ | |
| coupling*=HOMEO_DEC; | |
| if(level==0){ | |
| double ns=NOISE_BASE*(1-gc)+NOISE_EXPLORE*gc; | |
| for(auto&o:osc) o.omega_base+=(float)((rU()-0.5)*ns); | |
| } | |
| } | |
| } | |
| // ---- Memory ---- | |
| std::array<int16_t,MEM_TYPES> compute_mem_vals(){ | |
| std::array<int16_t,MEM_TYPES> v; | |
| int16_t pa,pb,pc; | |
| if(level==0){ pa=osc[0].theta; pb=osc[1].theta; pc=osc[2].theta; } | |
| else { pa=ch[0]->phase_q; pb=ch[1]->phase_q; pc=ch[2]->phase_q; } | |
| v[0]=phase_to_i16(cm2_q(pb,pc)); | |
| v[1]=phase_to_i16(np(fabs(pd(i16_to_phase(pb),i16_to_phase(pc))))); | |
| v[2]=pb; v[3]=pc; | |
| v[4]=phase_to_i16(np(fabs(fast_cos(pa)+fast_cos(pb)-2*fast_cos(pc))*M_PI)); | |
| return v; | |
| } | |
| void remember(){ | |
| if(protected_attr) return; | |
| auto vals=compute_mem_vals(); | |
| double e=energy(); | |
| MemSlot s; s.energy=(float)e; s.coupling=coupling; s.pw=pw; | |
| for(int i=0;i<MEM_TYPES;++i) s.vals[i]=vals[i]; | |
| int slots=mem_slots(level); | |
| if((int)mem.size()<slots){ mem.push_back(s); return; } | |
| auto w=std::min_element(mem.begin(),mem.end(),[](const MemSlot&x,const MemSlot&y){return x.energy<y.energy;}); | |
| if(e>w->energy) *w=s; | |
| } | |
| void restore(){ | |
| if(mem.empty()) return; | |
| double sx=0,sy=0; | |
| auto best=std::max_element(mem.begin(),mem.end(),[](const MemSlot&x,const MemSlot&y){return x.energy<y.energy;}); | |
| for(auto&s:mem){ double p=i16_to_phase(s.vals[0]); sx+=cos(p); sy+=sin(p); } | |
| double m=atan2(sy/mem.size(),sx/mem.size()); | |
| set_phase(m<0?m+2*M_PI:m); | |
| coupling=std::clamp(best->coupling,(float)MIN_COUPLING,(float)MAX_COUPLING); | |
| pw=std::clamp(best->pw,(float)MIN_PW,(float)MAX_PW); | |
| isync(); | |
| } | |
| // ---- Sleep pruning + structural plasticity (I1 + Gemini fix) ---- | |
| void sleep_prune(){ | |
| // Prune weak, strengthen strong | |
| for(auto&[idx,w]:lat){ | |
| if(w<PRUNE_WEAK&&!protected_attr) w*=0.98f; | |
| else if(w>STRENGTHEN_STR) w*=1.002f; | |
| w=std::clamp(w,(float)MIN_LAT,(float)MAX_LAT); | |
| } | |
| // Structural plasticity: remove dead connections, add new ones | |
| if(!lat.empty()){ | |
| lat.erase(std::remove_if(lat.begin(),lat.end(), | |
| [](const std::pair<int,float>&p){return p.second<0.06f;}),lat.end()); | |
| } | |
| // Sprouting: add replacement connections (Phase 2 seed) | |
| // (actual target selection happens at Brain level using available nodes) | |
| } | |
| // ---- Delay-line (E2) ---- | |
| void update_delay(double upstream_phase){ | |
| for(int i=DELAY_STEPS-1;i>0;--i) delay_buf[i]=delay_buf[i-1]; | |
| delay_buf[0]=static_cast<float>(upstream_phase); | |
| delay_reflected=delay_buf[DELAY_STEPS-1]*static_cast<float>(DELAY_ALPHA); | |
| double p=get_phase(); | |
| p=np(p+0.01*sin(delay_reflected-p)*DT); | |
| set_phase(p); | |
| } | |
| // ---- Lateral sync with WTA (G3 inhibitory) ---- | |
| void lsync(const std::vector<Triplet*>&nodes, float cur_meta_stdp){ | |
| if(frozen){next_phase_q=phase_q;return;} | |
| double ps=get_phase(); | |
| float f_local=free_energy; | |
| bool wta=(level>=4); | |
| for(auto&[idx,w]:lat){ | |
| if(idx>=(int)nodes.size()) continue; | |
| Triplet* o=nodes[idx]; | |
| if(o->frozen) continue; | |
| double diff=pd(o->get_phase(),get_phase()); | |
| // G3: WTA inhibitory for competing attractors | |
| float ew=w; | |
| if(wta&&fabs(diff)>2.5) ew=-0.05f; | |
| ps+=ew*sin(diff)*DT; | |
| // STDP gated by F (J2) | |
| if(f_local>STDP_F_GATE){ | |
| double delta=fabs(diff), dw=0; | |
| if(delta<STDP_LO) dw= cur_meta_stdp*(STDP_LO-delta); | |
| else if(delta>STDP_HI) dw=-STDP_DEP*(delta-STDP_HI); | |
| w+=static_cast<float>(dw); | |
| w=std::clamp(w,(float)MIN_LAT,(float)MAX_LAT); | |
| } | |
| } | |
| // Active Inference (Phase 2 seed): if active, nudge toward preferred phase | |
| if(active_inf_active && level>=8){ | |
| ps+=0.05*sin(pd(preferred_phase,get_phase()))*DT; | |
| } | |
| next_phase_q=phase_to_i16(np(ps)); | |
| } | |
| void alat(){ if(!frozen) phase_q=next_phase_q; } | |
| // ---- MAIN STEP ---- | |
| void step(const std::vector<double>&ef, double gc, float meta_stdp){ | |
| if(frozen) return; | |
| upair(ef); | |
| isync(); | |
| if(parent) xsync(parent->get_phase(),pw); | |
| update_free_energy(); | |
| adapt_k(); | |
| homeo(gc); | |
| double e=energy(); | |
| if(e>0.5) remember(); | |
| else if(e<-0.2) restore(); | |
| update_phase(); | |
| if(parent) update_delay(parent->get_phase()); | |
| clock.step(DT); | |
| total_e+=e; uc++; | |
| } | |
| }; | |
| // ============================================================ | |
| // KUBERA CORE (N1-N9) | |
| // ============================================================ | |
| struct KuberaCore { | |
| bool active; | |
| std::string core_path; | |
| bool core_exists=false; | |
| uint64_t identity_hash=0; | |
| int meditate_ctr=0; | |
| const int MEDITATE_EVERY=1000; | |
| bool dharma_violation=false; // set from outside on harm detection | |
| // Async I/O queue (Gemini fix: no blocking in main thread) | |
| std::queue<std::string> io_queue; | |
| std::mutex io_mx; | |
| std::thread io_thread; | |
| std::condition_variable io_cv; | |
| bool io_stop=false; | |
| KuberaCore(bool en, const std::string& path) : active(en), core_path(path) {} | |
| void init(){ | |
| if(!active) return; | |
| std::ifstream check(core_path); | |
| if(!check.good()){ | |
| std::ofstream create(core_path, std::ios::binary); | |
| core_exists=true; | |
| std::cout<<"[Kubera] core.bin created: "<<core_path<<"\n"; | |
| } else { | |
| check.seekg(0,std::ios::end); | |
| core_exists=(check.tellg()==0); | |
| } | |
| auto now=std::chrono::high_resolution_clock::now().time_since_epoch().count(); | |
| identity_hash=static_cast<uint64_t>(now)^rHW(); | |
| std::cout<<"[Kubera] Identity: "<<std::hex<<identity_hash<<std::dec<<"\n"; | |
| // Start async I/O thread (Gemini fix) | |
| io_thread=std::thread([this]{ | |
| while(true){ | |
| std::unique_lock<std::mutex> lk(io_mx); | |
| io_cv.wait(lk,[this]{return io_stop||!io_queue.empty();}); | |
| if(io_stop&&io_queue.empty()) break; | |
| std::string entry=io_queue.front(); io_queue.pop(); lk.unlock(); | |
| std::ofstream log("kubera_meditation.log",std::ios::app); | |
| if(log) log<<entry<<"\n"; | |
| } | |
| }); | |
| } | |
| ~KuberaCore(){ | |
| {std::lock_guard<std::mutex> lk(io_mx); io_stop=true;} | |
| io_cv.notify_all(); | |
| if(io_thread.joinable()) io_thread.join(); | |
| } | |
| // Async meditate (no blocking) (Gemini fix) | |
| void meditate(float avg_free_energy){ | |
| if(!active) return; | |
| meditate_ctr++; | |
| if(meditate_ctr%MEDITATE_EVERY!=0) return; | |
| auto now=std::chrono::system_clock::now().time_since_epoch().count(); | |
| bool ok=core_exists; | |
| std::string entry=std::to_string(now) | |
| +" core_ok="+std::to_string(ok) | |
| +" id="+std::to_string(identity_hash) | |
| +" F="+std::to_string(avg_free_energy) | |
| +" dharma_ok="+std::to_string(!dharma_violation); | |
| { | |
| std::lock_guard<std::mutex> lk(io_mx); | |
| io_queue.push(entry); | |
| } | |
| io_cv.notify_one(); | |
| } | |
| // N2: Dharma weight | |
| double dharma_weight(const std::string& req){ | |
| if(!active) return 1.0; | |
| if(req=="harm") return 0.0; | |
| if(req=="deception") return 0.1; | |
| if(req=="service") return W_SEVA; | |
| return W_DHARMA; | |
| } | |
| std::string sign_message(const std::string& msg){ | |
| std::hash<std::string> h; | |
| uint64_t sig=h(msg)^identity_hash; | |
| return msg+"|sig="+std::to_string(sig); | |
| } | |
| }; | |
| // ============================================================ | |
| // THREADPOOL | |
| // ============================================================ | |
| class TP { | |
| std::vector<std::thread> ws; | |
| std::queue<std::function<void()>> q; | |
| std::mutex mx; std::condition_variable cv,cvd; | |
| int busy=0; bool stop_flag=false; | |
| public: | |
| TP(int n){ | |
| for(int i=0;i<n;++i) ws.emplace_back([this]{ | |
| while(true){ | |
| std::function<void()> t; | |
| {std::unique_lock<std::mutex> l(mx); | |
| cv.wait(l,[this]{return stop_flag||!q.empty();}); | |
| if(stop_flag&&q.empty()){return;} | |
| t=std::move(q.front());q.pop();++busy;} | |
| t(); | |
| {std::unique_lock<std::mutex> l(mx);--busy;cvd.notify_all();} | |
| } | |
| }); | |
| } | |
| void sub(std::function<void()> t){{std::unique_lock<std::mutex> l(mx);q.push(std::move(t));}cv.notify_one();} | |
| void wait(){std::unique_lock<std::mutex> l(mx);cvd.wait(l,[this]{return q.empty()&&busy==0;});} | |
| ~TP(){{std::unique_lock<std::mutex> l(mx);stop_flag=true;}cv.notify_all();for(auto&w:ws)w.join();} | |
| }; | |
| // ============================================================ | |
| // BRAIN | |
| // ============================================================ | |
| class Brain { | |
| public: | |
| std::unique_ptr<Triplet> root; | |
| std::vector<std::vector<Triplet*>> nbl; | |
| std::vector<double> pc; | |
| double avg_coh=0, avg_free_energy=0; | |
| std::deque<double> ch_hist; | |
| std::unique_ptr<TP> pool; | |
| int nthreads; | |
| KuberaCore kubera; | |
| bool sleeping=false; | |
| int low_f_count=0; | |
| double meta_stdp=STDP_POT; | |
| int step_count=0; | |
| double total_reward=0; | |
| Brain(int levels, const std::string& core_path, bool kub_en) | |
| : nthreads(std::max(1,(int)std::thread::hardware_concurrency())), | |
| kubera(kub_en, core_path) | |
| { | |
| init_lut(); // LUT must be first | |
| pool=std::make_unique<TP>(nthreads); | |
| root=std::make_unique<Triplet>(levels-1,0); | |
| nbl.resize(levels); | |
| collect(root.get()); | |
| init_lat(); | |
| pc.reserve(1<<16); | |
| kubera.init(); | |
| int n=0; for(auto&lv:nbl) n+=lv.size(); | |
| std::cout<<"Brain: L="<<levels<<" nodes="<<n | |
| <<" threads="<<nthreads | |
| <<" kubera="<<(kub_en?"ON":"OFF") | |
| <<" LUT=ON VSA_seed="<<(levels>=12?"ON":"OFF") | |
| <<"\n"; | |
| } | |
| void collect(Triplet*n){ | |
| nbl[n->level].push_back(n); | |
| if(n->level>0) for(auto&c:n->ch) collect(c.get()); | |
| } | |
| void init_lat(){ | |
| for(auto&lv:nbl){ | |
| int N=lv.size(); if(N<2) continue; | |
| for(int i=0;i<N;++i){ | |
| int num=std::min(LAT_DEGREE,N-1); | |
| std::vector<int> cand; | |
| for(int j=0;j<N;++j) if(j!=i) cand.push_back(j); | |
| std::shuffle(cand.begin(),cand.end(),rng()); | |
| cand.resize(num); | |
| for(int j:cand) lv[i]->lat.emplace_back(j,(float)rU(MIN_LAT,MAX_LAT)); | |
| } | |
| } | |
| } | |
| // Add new lateral connections after sleep pruning (sprouting) | |
| void sprout_connections(){ | |
| for(auto&lv:nbl){ | |
| int N=lv.size(); if(N<2) continue; | |
| for(auto*n:lv){ | |
| if(n->frozen) continue; | |
| int current=(int)n->lat.size(); | |
| if(current<LAT_DEGREE/2){ | |
| // Add random new connection | |
| int target=rng()()%N; | |
| bool found=false; | |
| for(auto&[idx,w]:n->lat) if(idx==target){found=true;break;} | |
| if(!found) n->lat.emplace_back(target,(float)rU(MIN_LAT,MIN_LAT*3)); | |
| } | |
| } | |
| } | |
| } | |
| double coherence(){ | |
| pc.clear(); | |
| std::function<void(Triplet*)> col=[&](Triplet*n){ | |
| if(n->level==0) for(auto&o:n->osc) pc.push_back(o.get_phase()); | |
| else for(auto&c:n->ch) col(c.get()); | |
| }; | |
| col(root.get()); | |
| if(pc.empty()) return 0; | |
| double sx=0,sy=0; | |
| for(double p:pc){sx+=cos(p);sy+=sin(p);} | |
| double nn=pc.size(); | |
| return sqrt((sx/nn)*(sx/nn)+(sy/nn)*(sy/nn)); | |
| } | |
| double compute_avg_F(){ | |
| double sum=0; int cnt=0; | |
| for(auto&lv:nbl) for(auto*n:lv){sum+=n->free_energy;cnt++;} | |
| return cnt>0?sum/cnt:0.5; | |
| } | |
| // Apply Dharma violation: spike F on upper nodes (Gemini + Kubera fix) | |
| void dharma_violation_response(){ | |
| for(auto&lv:nbl){ | |
| if(lv.empty()) continue; | |
| int lvl=lv[0]->level; | |
| if(lvl>=LEVELS/2){ | |
| for(auto*n:lv){ | |
| n->free_energy=1.0f; // spike — no learning of harm | |
| n->active_inf_active=false; | |
| } | |
| } | |
| } | |
| kubera.dharma_violation=false; // reset | |
| } | |
| void step(const std::vector<double>&ef={}){ | |
| // Async meditate | |
| avg_free_energy=compute_avg_F(); | |
| kubera.meditate(static_cast<float>(avg_free_energy)); | |
| // Dharma violation response | |
| if(kubera.dharma_violation) dharma_violation_response(); | |
| double gc=coherence(); | |
| // Sleep logic | |
| if(avg_free_energy<SLEEP_F_THR) low_f_count++; | |
| else low_f_count=0; | |
| sleeping=(low_f_count>500); | |
| // Meta-learning (M1) | |
| if(avg_free_energy>0.3) meta_stdp=std::min(META_STDP_MAX,meta_stdp*1.01); | |
| else meta_stdp=std::max(META_STDP_MIN,meta_stdp*0.99); | |
| // Step nodes (K2: async levels) | |
| for(auto&lv:nbl){ | |
| if(lv.empty()) continue; | |
| int lvl=lv[0]->level; | |
| int every=std::max(1,(int)(10.0*lvl/LEVELS)); | |
| if(step_count%every!=0) continue; | |
| if((int)lv.size()>=200){ | |
| int chunk=std::max(1,(int)lv.size()/nthreads); | |
| for(int t=0;t<nthreads;++t){ | |
| int s=t*chunk; | |
| int e=(t==nthreads-1)?(int)lv.size():s+chunk; | |
| float ms=static_cast<float>(meta_stdp); | |
| pool->sub([&lv,s,e,&ef,gc,ms,this]{ | |
| for(int i=s;i<e;++i){ | |
| if(sleeping) lv[i]->sleep_prune(); | |
| else lv[i]->step(ef,gc,ms); | |
| } | |
| }); | |
| } | |
| pool->wait(); | |
| } else { | |
| float ms=static_cast<float>(meta_stdp); | |
| for(auto*n:lv){ | |
| if(sleeping) n->sleep_prune(); | |
| else n->step(ef,gc,ms); | |
| } | |
| } | |
| } | |
| // Sprout new connections after sleep | |
| if(sleeping && step_count%5000==0) sprout_connections(); | |
| // Lateral sync | |
| for(size_t l=0;l<nbl.size();++l){ | |
| float ms=static_cast<float>(meta_stdp); | |
| pool->sub([this,l,ms]{for(auto*n:nbl[l]) n->lsync(nbl[l],ms);}); | |
| } | |
| pool->wait(); | |
| for(auto&lv:nbl) for(auto*n:lv) n->alat(); | |
| ch_hist.push_back(gc); | |
| if(ch_hist.size()>200) ch_hist.pop_front(); | |
| double s=0; for(double c:ch_hist)s+=c; | |
| avg_coh=s/ch_hist.size(); | |
| step_count++; | |
| } | |
| void save(const std::string&fname){ | |
| std::ofstream out(fname,std::ios::binary); | |
| if(!out){std::cerr<<"Save failed\n";return;} | |
| out.write(reinterpret_cast<const char*>(&step_count),sizeof(step_count)); | |
| out.write(reinterpret_cast<const char*>(&avg_coh),sizeof(avg_coh)); | |
| out.write(reinterpret_cast<const char*>(&meta_stdp),sizeof(meta_stdp)); | |
| std::cout<<"[Brain] Checkpoint: step="<<step_count<<"\n"; | |
| } | |
| void load(const std::string&fname){ | |
| std::ifstream in(fname,std::ios::binary); | |
| if(!in){return;} | |
| in.read(reinterpret_cast<char*>(&step_count),sizeof(step_count)); | |
| in.read(reinterpret_cast<char*>(&avg_coh),sizeof(avg_coh)); | |
| in.read(reinterpret_cast<char*>(&meta_stdp),sizeof(meta_stdp)); | |
| std::cout<<"[Brain] Loaded: step="<<step_count<<"\n"; | |
| } | |
| }; | |
| // ============================================================ | |
| // DAEMON MODE: UDP server (Gemini fix) | |
| // ============================================================ | |
| struct DaemonState { | |
| double avg_coh=0, avg_free_energy=0; | |
| bool sleeping=false; | |
| int step_count=0; | |
| int nodes=0; | |
| }; | |
| void run_daemon(Brain& brain, int port){ | |
| int sock=socket(AF_INET,SOCK_DGRAM,0); | |
| if(sock<0){std::cerr<<"[Daemon] Socket failed\n";return;} | |
| // Non-blocking | |
| int flags=fcntl(sock,F_GETFL,0); | |
| fcntl(sock,F_SETFL,flags|O_NONBLOCK); | |
| sockaddr_in addr{}; addr.sin_family=AF_INET; | |
| addr.sin_addr.s_addr=inet_addr("127.0.0.1"); addr.sin_port=htons(port); | |
| if(bind(sock,(sockaddr*)&addr,sizeof(addr))<0){ | |
| std::cerr<<"[Daemon] Bind failed on port "<<port<<"\n"; | |
| close(sock); return; | |
| } | |
| std::cout<<"[Daemon] Listening on 127.0.0.1:"<<port<<"\n"; | |
| std::cout<<"[Daemon] Brain running. Send UDP to stimulate. Ctrl+C to stop.\n"; | |
| // Save checkpoint periodically | |
| auto last_save=std::chrono::steady_clock::now(); | |
| brain.load("checkpoint.bin"); | |
| while(true){ | |
| // Read external stimulus from Python | |
| char buf[512]={}; | |
| sockaddr_in from{}; socklen_t fromlen=sizeof(from); | |
| ssize_t n=recvfrom(sock,buf,sizeof(buf)-1,0,(sockaddr*)&from,&fromlen); | |
| std::vector<double> ef; | |
| if(n>0){ | |
| // Parse: comma-separated floats "0.1,0.2,-0.05" | |
| std::string s(buf,n); | |
| std::istringstream ss(s); | |
| std::string token; | |
| // Check for DHARMA_VIOLATION signal | |
| if(s.find("DHARMA_VIOLATION")!=std::string::npos){ | |
| brain.kubera.dharma_violation=true; | |
| } else { | |
| while(std::getline(ss,token,',')){ | |
| try{ ef.push_back(std::stod(token)); } catch(...){} | |
| } | |
| } | |
| } | |
| // One brain step | |
| brain.step(ef); | |
| // Send state back every 50 steps | |
| if(brain.step_count%50==0){ | |
| std::ostringstream resp; | |
| resp<<std::fixed<<std::setprecision(4) | |
| <<"coh="<<brain.avg_coh | |
| <<",F="<<brain.avg_free_energy | |
| <<",sleep="<<brain.sleeping | |
| <<",step="<<brain.step_count; | |
| std::string rs=resp.str(); | |
| sendto(sock,rs.c_str(),rs.size(),0,(sockaddr*)&from,fromlen); | |
| } | |
| // Checkpoint every 60 seconds | |
| auto now=std::chrono::steady_clock::now(); | |
| if(std::chrono::duration_cast<std::chrono::seconds>(now-last_save).count()>=60){ | |
| brain.save("checkpoint.bin"); | |
| last_save=now; | |
| } | |
| // Small sleep to not burn CPU when idle | |
| if(ef.empty()) std::this_thread::sleep_for(std::chrono::microseconds(100)); | |
| } | |
| close(sock); | |
| } | |
| // ============================================================ | |
| // MAIN | |
| // ============================================================ | |
| int main(int argc, char* argv[]){ | |
| std::cout<<"==============================================\n"; | |
| std::cout<<" FractalBrainOS v5.2 — Kubera Edition\n"; | |
| std::cout<<" Full: LUT + Daemon + ActiveInference + VSA\n"; | |
| std::cout<<"==============================================\n"; | |
| // Parse args: brain --daemon PORT LEVELS KUBERA | |
| // or: brain --test LEVELS KUBERA | |
| [[maybe_unused]] bool test_mode=true; | |
| for(int i=1;i<argc;++i){ | |
| std::string arg(argv[i]); | |
| if(arg=="--daemon"){ DAEMON_MODE=true; test_mode=false; } | |
| else if(arg=="--test"){ test_mode=true; } | |
| else if(arg=="--port"&&i+1<argc){ DAEMON_PORT=std::atoi(argv[++i]); } | |
| else if(std::isdigit(arg[0])){ | |
| if(LEVELS==8) LEVELS=std::atoi(argv[i]); | |
| else DAEMON_PORT=std::atoi(argv[i]); | |
| } | |
| } | |
| // Legacy: ./brain LEVELS KUBERA | |
| if(argc>=2&&std::isdigit(argv[1][0])) LEVELS=std::atoi(argv[1]); | |
| Brain brain(LEVELS,"core.bin",true); | |
| if(DAEMON_MODE){ | |
| run_daemon(brain, DAEMON_PORT); | |
| } else { | |
| // Test mode: 200 steps with Lorenz-like signal | |
| std::cout<<"\nTest mode: 200 steps\n"; | |
| brain.load("checkpoint.bin"); | |
| for(int s=0;s<200;++s){ | |
| std::vector<double> ext; | |
| if(s%20==0) ext={sin(s*0.1)*0.1,cos(s*0.07)*0.1,sin(s*0.13)*0.1}; | |
| brain.step(ext); | |
| if(s%50==0) | |
| std::cout<<"Step "<<s<<" coh="<<std::fixed<<std::setprecision(4) | |
| <<brain.avg_coh<<" F="<<brain.avg_free_energy | |
| <<" sleep="<<brain.sleeping<<"\n"; | |
| if(s%100==0) brain.save("checkpoint.bin"); | |
| } | |
| std::cout<<"Done. coh="<<brain.avg_coh<<"\n"; | |
| } | |
| return 0; | |
| } | |