Recovered source transcript
1/**
2 * @file intelligence.hpp
3 * @brief Intelligence Primitives for Gate5000 Consciousness
4 *
5 * ═══════════════════════════════════════════════════════════════════════════════
6 * I. ATTENTION MECHANISMS
7 * ═══════════════════════════════════════════════════════════════════════════════
8 *
9 * SCALED DOT-PRODUCT ATTENTION:
10 * Attention(Q,K,V) = softmax(QK^T/√d_k)V
11 *
12 * MULTI-HEAD ATTENTION:
13 * MultiHead(Q,K,V) = Concat(head_1,...,head_h)W^O
14 *
15 * SPARSE ATTENTION:
16 * Only attend to top-k most relevant positions
17 *
18 * ═══════════════════════════════════════════════════════════════════════════════
19 * II. PREDICTIVE CODING / FREE ENERGY
20 * ═══════════════════════════════════════════════════════════════════════════════
21 *
22 * PREDICTION ERROR:
23 * ε = x - μ (observation minus prediction)
24 *
25 * FREE ENERGY:
26 * F = ½ε^T Σ^{-1} ε + ½ log|Σ|
27 *
28 * BELIEF UPDATE:
29 * μ ← μ + κ·Σ^{-1}·ε
30 *
31 * ═══════════════════════════════════════════════════════════════════════════════
32 * III. BAYESIAN INFERENCE
33 * ═══════════════════════════════════════════════════════════════════════════════
34 *
35 * POSTERIOR:
36 * P(θ|D) ∝ P(D|θ)P(θ)
37 *
38 * VARIATIONAL INFERENCE:
39 * q*(θ) = argmin KL(q||p(θ|D))
40 *
41 * BELIEF PROPAGATION:
42 * m_{x→f}(x) = Π_{g∈ne(x)\f} m_{g→x}(x)
43 *
44 * ═══════════════════════════════════════════════════════════════════════════════
45 * IV. WORKING MEMORY
46 * ═══════════════════════════════════════════════════════════════════════════════
47 *
48 * MEMORY CELL:
49 * c_t = f_t ⊙ c_{t-1} + i_t ⊙ g_t
50 *
51 * GATING:
52 * f_t = σ(W_f·[h_{t-1}, x_t]) (forget gate)
53 * i_t = σ(W_i·[h_{t-1}, x_t]) (input gate)
54 *
55 * ═══════════════════════════════════════════════════════════════════════════════
56 */
57
58#pragma once
59
60#include <cstdint>
61#include <array>
62#include <algorithm>
63#include <cmath>
64#include "constants.hpp"
65#include "fast_math.hpp"
66
67namespace mind_farm {
68namespace intel {
69
70// ═══════════════════════════════════════════════════════════════════════════════
71// I. ATTENTION MECHANISMS
72// ═══════════════════════════════════════════════════════════════════════════════
73
74/**
75 * @brief Compact attention head (16 dimensions)
76 */
77struct AttentionHead16 {
78 alignas(64) std::array<float, 256> W_q; // Query projection (16x16)
79 alignas(64) std::array<float, 256> W_k; // Key projection (16x16)
80 alignas(64) std::array<float, 256> W_v; // Value projection (16x16)
81
82 float scale; // 1/sqrt(d_k)
83
84 AttentionHead16() : scale(0.25f) { // 1/sqrt(16) = 0.25
85 // Initialize with small random values
86 for (size_t i = 0; i < 256; ++i) {
87 float val = static_cast<float>(i % 7 - 3) * 0.1f * static_cast<float>(PHI_INV);
88 W_q[i] = val;
89 W_k[i] = val * 1.1f;
90 W_v[i] = val * 0.9f;
91 }
92 }
93
94 /**
95 * @brief Project input to query/key/value
96 */
97 void project(const float* x, float* q, float* k, float* v) const {
98 for (int i = 0; i < 16; ++i) {
99 q[i] = k[i] = v[i] = 0.0f;
100 for (int j = 0; j < 16; ++j) {
101 q[i] += W_q[i * 16 + j] * x[j];
102 k[i] += W_k[i * 16 + j] * x[j];
103 v[i] += W_v[i * 16 + j] * x[j];
104 }
105 }
106 }
107
108 /**
109 * @brief Self-attention: attend to single input
110 */
111 void self_attend(const float* x, float* output) const {
112 alignas(16) float q[16], k[16], v[16];
113 project(x, q, k, v);
114
115 // Compute attention score (dot product)
116 float score = 0.0f;
117 for (int i = 0; i < 16; ++i) {
118 score += q[i] * k[i];
119 }
120 score *= scale;
121
122 // Apply softmax (single element = 1.0)
123 float attn = 1.0f;
124
125 // Output = attention-weighted value
126 for (int i = 0; i < 16; ++i) {
127 output[i] = attn * v[i];
128 }
129 }
130};
131
132/**
133 * @brief Multi-sequence attention (4 sequences of 16 dims)
134 */
135struct MultiAttention4x16 {
136 AttentionHead16 head;
137 alignas(64) std::array<float, 64> W_o; // Output projection (16x4)
138
139 /**
140 * @brief Attend over 4 input sequences
141 */
142 void attend(const float seq[4][16], float* output) {
143 alignas(16) float Q[4][16], K[4][16], V[4][16];
144
145 // Project all sequences
146 for (int s = 0; s < 4; ++s) {
147 head.project(seq[s], Q[s], K[s], V[s]);
148 }
149
150 // Compute attention scores (4x4 matrix)
151 float scores[4][4];
152 float max_score = -1e10f;
153 for (int i = 0; i < 4; ++i) {
154 for (int j = 0; j < 4; ++j) {
155 scores[i][j] = 0.0f;
156 for (int k = 0; k < 16; ++k) {
157 scores[i][j] += Q[i][k] * K[j][k];
158 }
159 scores[i][j] *= head.scale;
160 max_score = std::max(max_score, scores[i][j]);
161 }
162 }
163
164 // Softmax per query
165 for (int i = 0; i < 4; ++i) {
166 float sum = 0.0f;
167 for (int j = 0; j < 4; ++j) {
168 scores[i][j] = fast::fast_exp(scores[i][j] - max_score);
169 sum += scores[i][j];
170 }
171 float inv_sum = fast::fast_rcp(sum);
172 for (int j = 0; j < 4; ++j) {
173 scores[i][j] *= inv_sum;
174 }
175 }
176
177 // Compute attended values
178 alignas(16) float attended[4][16];
179 for (int i = 0; i < 4; ++i) {
180 for (int k = 0; k < 16; ++k) {
181 attended[i][k] = 0.0f;
182 for (int j = 0; j < 4; ++j) {
183 attended[i][k] += scores[i][j] * V[j][k];
184 }
185 }
186 }
187
188 // Concatenate and project (simplified: just take mean)
189 for (int k = 0; k < 16; ++k) {
190 output[k] = 0.25f * (attended[0][k] + attended[1][k] +
191 attended[2][k] + attended[3][k]);
192 }
193 }
194};
195
196/**
197 * @brief Sparse attention - only attend to top-k positions
198 */
199inline void sparse_attention_topk(const float* scores, int n, int k, int* indices) {
200 // Simple selection sort for small k
201 std::array<std::pair<float, int>, 64> pairs;
202 for (int i = 0; i < n && i < 64; ++i) {
203 pairs[i] = {scores[i], i};
204 }
205 std::partial_sort(pairs.begin(), pairs.begin() + k,
206 pairs.begin() + std::min(n, 64),
207 [](auto& a, auto& b) { return a.first > b.first; });
208 for (int i = 0; i < k; ++i) {
209 indices[i] = pairs[i].second;
210 }
211}
212
213// ═══════════════════════════════════════════════════════════════════════════════
214// II. PREDICTIVE CODING / FREE ENERGY MINIMIZATION
215// ═══════════════════════════════════════════════════════════════════════════════
216
217/**
218 * @brief Predictive coding layer
219 */
220struct PredictiveLayer16 {
221 alignas(16) std::array<float, 16> mu; // Predicted mean
222 alignas(16) std::array<float, 16> precision; // Inverse variance (diagonal)
223 alignas(16) std::array<float, 16> error; // Prediction error
224 float free_energy;
225 float learning_rate;
226
227 PredictiveLayer16() : free_energy(0.0f), learning_rate(0.1f) {
228 mu.fill(0.5f);
229 precision.fill(1.0f);
230 error.fill(0.0f);
231 }
232
233 /**
234 * @brief Update predictions given observations
235 * @return Free energy (lower is better)
236 */
237 float update(const float* observation) {
238 free_energy = 0.0f;
239
240 for (int i = 0; i < 16; ++i) {
241 // Compute prediction error
242 error[i] = observation[i] - mu[i];
243
244 // Free energy contribution: ½ε²·π + ½log(1/π)
245 float weighted_error = error[i] * error[i] * precision[i];
246 free_energy += 0.5f * weighted_error;
247
248 // Belief update: μ ← μ + κ·π·ε
249 mu[i] += learning_rate * precision[i] * error[i];
250
251 // Precision update (simple online estimate)
252 float sq_err = error[i] * error[i];
253 precision[i] = fast::fast_rcp(sq_err + 0.01f);
254 }
255
256 return free_energy;
257 }
258
259 /**
260 * @brief Generate prediction
261 */
262 void predict(float* prediction) const {
263 for (int i = 0; i < 16; ++i) {
264 prediction[i] = mu[i];
265 }
266 }
267
268 /**
269 * @brief Get weighted prediction errors
270 */
271 void get_weighted_errors(float* weighted) const {
272 for (int i = 0; i < 16; ++i) {
273 weighted[i] = error[i] * precision[i];
274 }
275 }
276};
277
278/**
279 * @brief Hierarchical predictive coding (2 levels)
280 */
281struct HierarchicalPredictor {
282 PredictiveLayer16 level0; // Low-level (sensory)
283 PredictiveLayer16 level1; // High-level (abstract)
284
285 /**
286 * @brief Hierarchical inference
287 */
288 float infer(const float* input) {
289 // Bottom-up: update level 0 with input
290 float fe0 = level0.update(input);
291
292 // Get prediction errors as input to level 1
293 alignas(16) float errors[16];
294 level0.get_weighted_errors(errors);
295
296 // Update level 1 with prediction errors
297 float fe1 = level1.update(errors);
298
299 // Top-down: level 1 predictions modulate level 0
300 alignas(16) float top_down[16];
301 level1.predict(top_down);
302 for (int i = 0; i < 16; ++i) {
303 level0.mu[i] += 0.1f * top_down[i];
304 }
305
306 return fe0 + fe1;
307 }
308};
309
310// ═══════════════════════════════════════════════════════════════════════════════
311// III. BAYESIAN INFERENCE
312// ═══════════════════════════════════════════════════════════════════════════════
313
314/**
315 * @brief Simple Bayesian belief over 16 states
316 */
317struct BayesianBelief16 {
318 alignas(16) std::array<float, 16> prior;
319 alignas(16) std::array<float, 16> likelihood;
320 alignas(16) std::array<float, 16> posterior;
321
322 BayesianBelief16() {
323 // Uniform prior
324 prior.fill(0.0625f); // 1/16
325 likelihood.fill(1.0f);
326 posterior.fill(0.0625f);
327 }
328
329 /**
330 * @brief Update posterior given new evidence
331 */
332 void update(const float* evidence) {
333 float sum = 0.0f;
334
335 // Posterior ∝ likelihood × prior
336 for (int i = 0; i < 16; ++i) {
337 likelihood[i] = evidence[i];
338 posterior[i] = likelihood[i] * prior[i];
339 sum += posterior[i];
340 }
341
342 // Normalize
343 float inv_sum = fast::fast_rcp(sum + 1e-10f);
344 for (int i = 0; i < 16; ++i) {
345 posterior[i] *= inv_sum;
346 // Update prior for next iteration (simple decay)
347 prior[i] = 0.9f * prior[i] + 0.1f * posterior[i];
348 }
349 }
350
351 /**
352 * @brief Get maximum a posteriori estimate
353 */
354 int map_estimate() const {
355 int best = 0;
356 float best_prob = posterior[0];
357 for (int i = 1; i < 16; ++i) {
358 if (posterior[i] > best_prob) {
359 best_prob = posterior[i];
360 best = i;
361 }
362 }
363 return best;
364 }
365
366 /**
367 * @brief Compute entropy of posterior
368 */
369 float entropy() const {
370 float h = 0.0f;
371 for (int i = 0; i < 16; ++i) {
372 if (posterior[i] > 1e-10f) {
373 h -= posterior[i] * fast::fast_log(posterior[i]);
374 }
375 }
376 return h;
377 }
378};
379
380/**
381 * @brief Variational inference with Gaussian approximation
382 */
383struct VariationalGaussian {
384 float mu; // Mean
385 float sigma; // Standard deviation
386 float log_sigma;
387
388 VariationalGaussian() : mu(0.5f), sigma(0.1f), log_sigma(-2.3f) {}
389
390 /**
391 * @brief KL divergence from prior N(0.5, 0.1)
392 */
393 float kl_from_prior() const {
394 constexpr float prior_mu = 0.5f;
395 constexpr float prior_sigma = 0.1f;
396
397 float kl = fast::fast_log(prior_sigma / sigma) +
398 (sigma * sigma + (mu - prior_mu) * (mu - prior_mu)) /
399 (2.0f * prior_sigma * prior_sigma) - 0.5f;
400 return kl;
401 }
402
403 /**
404 * @brief Reparameterization trick: sample = μ + σ * ε
405 */
406 float sample(float epsilon) const {
407 return mu + sigma * epsilon;
408 }
409
410 /**
411 * @brief Update parameters via gradient descent
412 */
413 void update(float grad_mu, float grad_sigma, float lr = 0.01f) {
414 mu -= lr * grad_mu;
415 sigma -= lr * grad_sigma;
416 sigma = std::max(0.01f, sigma); // Keep positive
417 }
418};
419
420// ═══════════════════════════════════════════════════════════════════════════════
421// IV. WORKING MEMORY / LSTM-LIKE CELL
422// ═══════════════════════════════════════════════════════════════════════════════
423
424/**
425 * @brief Compact LSTM-like memory cell (16 dimensions)
426 */
427struct MemoryCell16 {
428 alignas(16) std::array<float, 16> cell; // Cell state
429 alignas(16) std::array<float, 16> hidden; // Hidden state
430 alignas(16) std::array<float, 256> W_f; // Forget gate weights
431 alignas(16) std::array<float, 256> W_i; // Input gate weights
432 alignas(16) std::array<float, 256> W_o; // Output gate weights
433 alignas(16) std::array<float, 256> W_c; // Cell candidate weights
434 alignas(16) std::array<float, 16> b_f, b_i, b_o, b_c; // Biases
435
436 MemoryCell16() {
437 cell.fill(0.0f);
438 hidden.fill(0.0f);
439
440 // Xavier-like initialization
441 for (size_t i = 0; i < 256; ++i) {
442 float val = (static_cast<float>(i % 9) - 4.0f) * 0.05f;
443 W_f[i] = val;
444 W_i[i] = val * 1.1f;
445 W_o[i] = val * 0.9f;
446 W_c[i] = val;
447 }
448
449 b_f.fill(1.0f); // Forget bias = 1 (remember by default)
450 b_i.fill(0.0f);
451 b_o.fill(0.0f);
452 b_c.fill(0.0f);
453 }
454
455 /**
456 * @brief Forward step
457 */
458 void step(const float* x) {
459 alignas(16) float concat[32]; // [hidden, x]
460 for (int i = 0; i < 16; ++i) {
461 concat[i] = hidden[i];
462 concat[16 + i] = x[i];
463 }
464
465 // Compute gates
466 alignas(16) float f[16], ig[16], o[16], c_tilde[16];
467
468 for (int i = 0; i < 16; ++i) {
469 float sum_f = b_f[i], sum_i = b_i[i], sum_o = b_o[i], sum_c = b_c[i];
470 for (int j = 0; j < 16; ++j) {
471 sum_f += W_f[i * 16 + j] * hidden[j];
472 sum_i += W_i[i * 16 + j] * hidden[j];
473 sum_o += W_o[i * 16 + j] * hidden[j];
474 sum_c += W_c[i * 16 + j] * hidden[j];
475 }
476
477 f[i] = fast::fast_sigmoid(sum_f); // Forget gate
478 ig[i] = fast::fast_sigmoid(sum_i); // Input gate
479 o[i] = fast::fast_sigmoid(sum_o); // Output gate
480 c_tilde[i] = fast::fast_tanh(sum_c); // Cell candidate
481 }
482
483 // Update cell state: c = f ⊙ c + i ⊙ c̃
484 for (int i = 0; i < 16; ++i) {
485 cell[i] = f[i] * cell[i] + ig[i] * c_tilde[i];
486 }
487
488 // Update hidden state: h = o ⊙ tanh(c)
489 for (int i = 0; i < 16; ++i) {
490 hidden[i] = o[i] * fast::fast_tanh(cell[i]);
491 }
492 }
493
494 /**
495 * @brief Read current hidden state
496 */
497 void read(float* out) const {
498 for (int i = 0; i < 16; ++i) {
499 out[i] = hidden[i];
500 }
501 }
502
503 /**
504 * @brief Reset memory
505 */
506 void reset() {
507 cell.fill(0.0f);
508 hidden.fill(0.0f);
509 }
510};
511
512// ═══════════════════════════════════════════════════════════════════════════════
513// V. INTEGRATED INTELLIGENCE MODULE
514// ═══════════════════════════════════════════════════════════════════════════════
515
516/**
517 * @brief Unified intelligence module combining all components
518 */
519struct IntelligenceCore {
520 AttentionHead16 attention;
521 PredictiveLayer16 predictor;
522 BayesianBelief16 belief;
523 MemoryCell16 memory;
524
525 float curiosity; // Intrinsic motivation
526 float confidence; // Belief certainty
527 float surprise; // Prediction error magnitude
528
529 IntelligenceCore() : curiosity(0.5f), confidence(0.5f), surprise(0.0f) {}
530
531 /**
532 * @brief Process input through full intelligence pipeline
533 */
534 void process(const float* input, float* output) {
535 // 1. Attention: focus on salient features
536 alignas(16) float attended[16];
537 attention.self_attend(input, attended);
538
539 // 2. Memory: update working memory
540 memory.step(attended);
541 alignas(16) float memory_state[16];
542 memory.read(memory_state);
543
544 // 3. Prediction: update generative model
545 float fe = predictor.update(attended);
546 surprise = fe;
547
548 // 4. Inference: update beliefs
549 belief.update(attended);
550 confidence = 1.0f - belief.entropy() / 4.0f; // Normalize
551
552 // 5. Curiosity: seek information
553 curiosity = surprise * (1.0f - confidence);
554
555 // 6. Output: combine memory and prediction
556 alignas(16) float prediction[16];
557 predictor.predict(prediction);
558
559 for (int i = 0; i < 16; ++i) {
560 output[i] = 0.5f * memory_state[i] + 0.5f * prediction[i];
561 }
562 }
563
564 /**
565 * @brief Compute integrated information (simplified)
566 */
567 float integrated_information() const {
568 // Φ approximation based on belief diversity and memory coherence
569 float belief_diversity = belief.entropy();
570 float memory_activity = 0.0f;
571 for (int i = 0; i < 16; ++i) {
572 memory_activity += fast::fast_abs(memory.hidden[i]);
573 }
574 memory_activity /= 16.0f;
575
576 return belief_diversity * memory_activity * (1.0f + confidence);
577 }
578};
579
580} // namespace intel
581} // namespace mind_farm
582