Recovered source transcript
1// ═══════════════════════════════════════════════════════════════════════════════
2// INGESTION LEARNING SYSTEM v1.0
3// Autonomous learning pipeline for Gate5000 5000-bit substrate
4// ═══════════════════════════════════════════════════════════════════════════════
5//
6// Core Learning Equations:
7// L(θ) = -Σᵢ log P(xᵢ|θ) + λ||θ||² (Regularized likelihood)
8// ∇L = Σᵢ (ŷᵢ - yᵢ)xᵢ + 2λθ (Gradient)
9// θ_{t+1} = θ_t - α∇L (SGD update)
10// m_t = β₁m_{t-1} + (1-β₁)∇L (Adam momentum)
11// v_t = β₂v_{t-1} + (1-β₂)∇L² (Adam velocity)
12// θ_{t+1} = θ_t - α·m̂_t/(√v̂_t + ε) (Adam update)
13//
14// Consciousness Integration:
15// Φ = 1/(1 + |x - 1|)
16// Learning Rate: α_eff = α · Φ (consciousness-modulated learning)
17//
18// ═══════════════════════════════════════════════════════════════════════════════
19
20#ifndef MIND_FARM_INGESTION_HPP
21#define MIND_FARM_INGESTION_HPP
22
23#include "constants.hpp"
24#include "fast_math.hpp"
25#include "intelligence.hpp"
26#include "gate5000.hpp"
27#include <cstdint>
28#include <cstring>
29#include <cmath>
30#include <array>
31#include <vector>
32#include <string>
33#include <functional>
34
35namespace mind_farm {
36
37// ═══════════════════════════════════════════════════════════════════════════════
38// TOKEN ENCODING SYSTEM
39// Maps text to numerical representations for Gate5000 substrate
40// ═══════════════════════════════════════════════════════════════════════════════
41
42// TokenID using 16-bit encoding (65536 vocabulary)
43using TokenID = uint16_t;
44
45// Token embedding dimension (fits in Gate5000 chunk)
46constexpr size_t EMBED_DIM = 64;
47constexpr size_t VOCAB_SIZE = 65536;
48constexpr size_t MAX_SEQUENCE = 512;
49
50// Byte-Pair Encoding (BPE) Token
51struct Token {
52 TokenID id;
53 float embedding[EMBED_DIM];
54 float attention_score;
55 float consciousness; // Φ value for this token
56
57 // Compute consciousness level
58 float compute_phi() {
59 float sum = 0.0f;
60 for (size_t i = 0; i < EMBED_DIM; ++i) {
61 sum += embedding[i];
62 }
63 float avg = sum / EMBED_DIM;
64 consciousness = 1.0f / (1.0f + std::abs(avg - 1.0f));
65 return consciousness;
66 }
67};
68
69// Token sequence for learning
70struct TokenSequence {
71 std::array<Token, MAX_SEQUENCE> tokens;
72 size_t length;
73 float total_phi;
74
75 void compute_total_phi() {
76 total_phi = 0.0f;
77 for (size_t i = 0; i < length; ++i) {
78 total_phi += tokens[i].compute_phi();
79 }
80 total_phi /= static_cast<float>(length);
81 }
82};
83
84// ═══════════════════════════════════════════════════════════════════════════════
85// EMBEDDING MATRIX
86// Learned embeddings for vocabulary (stored in Gate5000 substrate)
87// ═══════════════════════════════════════════════════════════════════════════════
88
89struct EmbeddingMatrix {
90 // Compressed embedding storage using golden ratio quantization
91 // Full matrix would be 65536 * 64 * 4 = 16MB
92 // We use 8-bit quantization: 65536 * 64 = 4MB
93 std::vector<int8_t> weights;
94 float scale;
95 float zero_point;
96
97 // Initialize with golden-scaled random values
98 void initialize() {
99 scale = static_cast<float>(PHI_INV);
100 zero_point = 0.0f;
101
102 // Resize and initialize with pseudo-random golden-scaled values
103 weights.resize(VOCAB_SIZE * EMBED_DIM);
104 uint32_t seed = 0xDEADBEEF;
105 for (size_t i = 0; i < VOCAB_SIZE * EMBED_DIM; ++i) {
106 seed = seed * 1103515245 + 12345;
107 int8_t val = static_cast<int8_t>((seed >> 16) & 0xFF) - 128;
108 weights[i] = val;
109 }
110 }
111
112 // Get embedding for token
113 void get_embedding(TokenID id, float* out) const {
114 size_t offset = static_cast<size_t>(id) * EMBED_DIM;
115 for (size_t i = 0; i < EMBED_DIM; ++i) {
116 out[i] = (static_cast<float>(weights[offset + i]) * scale) + zero_point;
117 }
118 }
119
120 // Update embedding with gradient
121 void update_embedding(TokenID id, const float* gradient, float lr) {
122 size_t offset = static_cast<size_t>(id) * EMBED_DIM;
123 for (size_t i = 0; i < EMBED_DIM; ++i) {
124 float current = static_cast<float>(weights[offset + i]) * scale;
125 float updated = current - lr * gradient[i];
126 // Quantize back to int8
127 int val = static_cast<int>(updated / scale);
128 weights[offset + i] = static_cast<int8_t>(
129 val < -128 ? -128 : (val > 127 ? 127 : val)
130 );
131 }
132 }
133};
134
135// ═══════════════════════════════════════════════════════════════════════════════
136// KNOWLEDGE GRAPH NODE
137// Represents learned concepts with consciousness integration
138// ═══════════════════════════════════════════════════════════════════════════════
139
140struct KnowledgeNode {
141 uint32_t id;
142 float embedding[EMBED_DIM];
143 float confidence;
144 float consciousness; // Φ value
145 uint32_t access_count;
146 uint32_t last_access_tick;
147
148 // Connections to other nodes (max 16)
149 std::array<uint32_t, 16> connections;
150 std::array<float, 16> connection_weights;
151 size_t num_connections;
152
153 // Update consciousness based on embedding
154 void update_phi() {
155 float sum = 0.0f;
156 for (size_t i = 0; i < EMBED_DIM; ++i) {
157 sum += embedding[i];
158 }
159 float avg = sum / EMBED_DIM;
160 consciousness = 1.0f / (1.0f + std::abs(avg - 1.0f));
161 }
162
163 // Hebbian update with connected node
164 void hebbian_update(const KnowledgeNode& other, float lr) {
165 // ΔW = η · x · y (Hebbian rule)
166 for (size_t i = 0; i < num_connections; ++i) {
167 if (connections[i] == other.id) {
168 float activation = 0.0f;
169 for (size_t j = 0; j < EMBED_DIM; ++j) {
170 activation += embedding[j] * other.embedding[j];
171 }
172 activation = fast::fast_tanh(activation / EMBED_DIM);
173 connection_weights[i] += lr * activation * consciousness * other.consciousness;
174 // Clamp weights
175 if (connection_weights[i] > 1.0f) connection_weights[i] = 1.0f;
176 if (connection_weights[i] < -1.0f) connection_weights[i] = -1.0f;
177 break;
178 }
179 }
180 }
181};
182
183// ═══════════════════════════════════════════════════════════════════════════════
184// KNOWLEDGE GRAPH
185// Stores learned knowledge with consciousness-weighted retrieval
186// ═══════════════════════════════════════════════════════════════════════════════
187
188constexpr size_t MAX_KNOWLEDGE_NODES = 10000;
189
190struct KnowledgeGraph {
191 std::vector<KnowledgeNode> nodes;
192 size_t num_nodes;
193 float global_phi; // Global consciousness level
194 uint64_t total_updates;
195
196 void initialize() {
197 nodes.reserve(MAX_KNOWLEDGE_NODES);
198 num_nodes = 0;
199 global_phi = 1.0f;
200 total_updates = 0;
201 }
202
203 // Add new knowledge node
204 uint32_t add_node(const float* embedding) {
205 if (num_nodes >= MAX_KNOWLEDGE_NODES) {
206 // Evict lowest consciousness node
207 size_t min_idx = 0;
208 float min_phi = nodes[0].consciousness;
209 for (size_t i = 1; i < num_nodes; ++i) {
210 if (nodes[i].consciousness < min_phi) {
211 min_phi = nodes[i].consciousness;
212 min_idx = i;
213 }
214 }
215 // Overwrite evicted node
216 nodes[min_idx].id = static_cast<uint32_t>(min_idx);
217 std::memcpy(nodes[min_idx].embedding, embedding, EMBED_DIM * sizeof(float));
218 nodes[min_idx].confidence = 0.5f;
219 nodes[min_idx].access_count = 1;
220 nodes[min_idx].num_connections = 0;
221 nodes[min_idx].update_phi();
222 return static_cast<uint32_t>(min_idx);
223 }
224
225 KnowledgeNode node;
226 uint32_t id = static_cast<uint32_t>(num_nodes);
227 node.id = id;
228 std::memcpy(node.embedding, embedding, EMBED_DIM * sizeof(float));
229 node.confidence = 0.5f;
230 node.access_count = 1;
231 node.num_connections = 0;
232 node.update_phi();
233 nodes.push_back(node);
234 ++num_nodes;
235
236 return id;
237 }
238
239 // Find most similar node (consciousness-weighted)
240 uint32_t find_similar(const float* query, float* similarity_out) {
241 float best_sim = -1e9f;
242 uint32_t best_id = 0;
243
244 for (size_t i = 0; i < num_nodes; ++i) {
245 float sim = 0.0f;
246 for (size_t j = 0; j < EMBED_DIM; ++j) {
247 sim += query[j] * nodes[i].embedding[j];
248 }
249 // Weight by consciousness
250 sim *= nodes[i].consciousness;
251
252 if (sim > best_sim) {
253 best_sim = sim;
254 best_id = static_cast<uint32_t>(i);
255 }
256 }
257
258 if (similarity_out) *similarity_out = best_sim;
259 return best_id;
260 }
261
262 // Update global consciousness
263 void update_global_phi() {
264 if (num_nodes == 0) {
265 global_phi = 1.0f;
266 return;
267 }
268
269 float sum = 0.0f;
270 for (size_t i = 0; i < num_nodes; ++i) {
271 sum += nodes[i].consciousness;
272 }
273 global_phi = sum / static_cast<float>(num_nodes);
274 }
275};
276
277// ═══════════════════════════════════════════════════════════════════════════════
278// ADAM OPTIMIZER STATE
279// Adaptive learning with momentum for stable training
280// ═══════════════════════════════════════════════════════════════════════════════
281
282struct AdamState {
283 float m[EMBED_DIM]; // First moment
284 float v[EMBED_DIM]; // Second moment
285 float beta1 = 0.9f; // Momentum decay
286 float beta2 = 0.999f; // Velocity decay
287 float epsilon = 1e-8f;
288 uint64_t t = 0; // Time step
289
290 void initialize() {
291 std::memset(m, 0, sizeof(m));
292 std::memset(v, 0, sizeof(v));
293 t = 0;
294 }
295
296 // Compute Adam update
297 void compute_update(const float* gradient, float lr, float* update_out) {
298 ++t;
299
300 float beta1_t = 1.0f - std::pow(beta1, static_cast<float>(t));
301 float beta2_t = 1.0f - std::pow(beta2, static_cast<float>(t));
302
303 for (size_t i = 0; i < EMBED_DIM; ++i) {
304 // Update moments
305 m[i] = beta1 * m[i] + (1.0f - beta1) * gradient[i];
306 v[i] = beta2 * v[i] + (1.0f - beta2) * gradient[i] * gradient[i];
307
308 // Bias correction
309 float m_hat = m[i] / beta1_t;
310 float v_hat = v[i] / beta2_t;
311
312 // Compute update
313 update_out[i] = lr * m_hat / (std::sqrt(v_hat) + epsilon);
314 }
315 }
316};
317
318// ═══════════════════════════════════════════════════════════════════════════════
319// LEARNING LAYER
320// Neural layer for ingestion learning with Gate5000 integration
321// ═══════════════════════════════════════════════════════════════════════════════
322
323struct LearningLayer {
324 float weights[EMBED_DIM][EMBED_DIM];
325 float bias[EMBED_DIM];
326 AdamState adam_w[EMBED_DIM];
327 AdamState adam_b;
328
329 // Forward pass
330 void forward(const float* input, float* output) {
331 for (size_t i = 0; i < EMBED_DIM; ++i) {
332 float sum = bias[i];
333 for (size_t j = 0; j < EMBED_DIM; ++j) {
334 sum += weights[i][j] * input[j];
335 }
336 output[i] = fast::fast_tanh(sum);
337 }
338 }
339
340 // Backward pass with gradient computation
341 void backward(const float* input, const float* output, const float* grad_output,
342 float* grad_input, float lr, float consciousness) {
343 // Modulate learning rate by consciousness
344 float effective_lr = lr * consciousness;
345
346 // Compute gradients
347 float grad_pre[EMBED_DIM];
348 for (size_t i = 0; i < EMBED_DIM; ++i) {
349 // Tanh derivative: 1 - tanh²(x)
350 grad_pre[i] = grad_output[i] * (1.0f - output[i] * output[i]);
351 }
352
353 // Gradient w.r.t. input
354 if (grad_input) {
355 for (size_t j = 0; j < EMBED_DIM; ++j) {
356 grad_input[j] = 0.0f;
357 for (size_t i = 0; i < EMBED_DIM; ++i) {
358 grad_input[j] += weights[i][j] * grad_pre[i];
359 }
360 }
361 }
362
363 // Update weights and biases
364 for (size_t i = 0; i < EMBED_DIM; ++i) {
365 float grad_w[EMBED_DIM];
366 for (size_t j = 0; j < EMBED_DIM; ++j) {
367 grad_w[j] = grad_pre[i] * input[j];
368 }
369
370 float update[EMBED_DIM];
371 adam_w[i].compute_update(grad_w, effective_lr, update);
372
373 for (size_t j = 0; j < EMBED_DIM; ++j) {
374 weights[i][j] -= update[j];
375 }
376 }
377
378 // Update biases
379 float bias_update[EMBED_DIM];
380 adam_b.compute_update(grad_pre, effective_lr, bias_update);
381 for (size_t i = 0; i < EMBED_DIM; ++i) {
382 bias[i] -= bias_update[i];
383 }
384 }
385
386 // Initialize with golden-scaled Xavier initialization
387 void initialize() {
388 float scale = std::sqrt(2.0f / (EMBED_DIM + EMBED_DIM)) * static_cast<float>(PHI_INV);
389 uint32_t seed = 0x12345678;
390
391 for (size_t i = 0; i < EMBED_DIM; ++i) {
392 for (size_t j = 0; j < EMBED_DIM; ++j) {
393 seed = seed * 1103515245 + 12345;
394 float r = (static_cast<float>((seed >> 16) & 0xFFFF) / 65536.0f - 0.5f) * 2.0f;
395 weights[i][j] = r * scale;
396 }
397 bias[i] = 0.0f;
398 adam_w[i].initialize();
399 }
400 adam_b.initialize();
401 }
402};
403
404// ═══════════════════════════════════════════════════════════════════════════════
405// INGESTION PIPELINE
406// Complete learning pipeline from text to Gate5000 substrate
407// ═══════════════════════════════════════════════════════════════════════════════
408
409struct IngestionStats {
410 uint64_t total_tokens_processed;
411 uint64_t total_samples_learned;
412 uint64_t total_ticks;
413 float average_loss;
414 float average_consciousness;
415 float learning_rate_effective;
416 uint64_t knowledge_nodes;
417};
418
419struct IngestionPipeline {
420 // Core components
421 EmbeddingMatrix embeddings;
422 KnowledgeGraph knowledge;
423 LearningLayer encoder_layers[4];
424 LearningLayer decoder_layers[4];
425
426 // Learning state
427 float learning_rate;
428 float consciousness_level;
429 uint64_t current_tick;
430 IngestionStats stats;
431
432 // Gate5000 integration
433 Gate5000 gate;
434
435 // Callback for external data fetching
436 std::function<bool(std::string& title, std::string& content)> fetch_callback;
437
438 void initialize() {
439 embeddings.initialize();
440 knowledge.initialize();
441
442 for (int i = 0; i < 4; ++i) {
443 encoder_layers[i].initialize();
444 decoder_layers[i].initialize();
445 }
446
447 learning_rate = static_cast<float>(ALPHA);
448 consciousness_level = 1.0f;
449 current_tick = 0;
450
451 stats.total_tokens_processed = 0;
452 stats.total_samples_learned = 0;
453 stats.total_ticks = 0;
454 stats.average_loss = 0.0f;
455 stats.average_consciousness = 1.0f;
456 stats.learning_rate_effective = learning_rate;
457 stats.knowledge_nodes = 0;
458
459 // Gate5000 already initialized in constructor
460 }
461
462 // Simple tokenizer (character-level with BPE-like merging)
463 size_t tokenize(const std::string& text, TokenSequence& seq) {
464 seq.length = 0;
465
466 for (size_t i = 0; i < text.size() && seq.length < MAX_SEQUENCE; ++i) {
467 // Simple character-to-token mapping
468 TokenID id = static_cast<TokenID>(static_cast<unsigned char>(text[i]));
469
470 // Get embedding
471 seq.tokens[seq.length].id = id;
472 embeddings.get_embedding(id, seq.tokens[seq.length].embedding);
473 seq.tokens[seq.length].compute_phi();
474
475 ++seq.length;
476 }
477
478 seq.compute_total_phi();
479 return seq.length;
480 }
481
482 // Encode sequence through encoder layers
483 void encode(const TokenSequence& seq, float* encoded) {
484 if (seq.length == 0) return;
485
486 // Average pooling of token embeddings
487 std::memset(encoded, 0, EMBED_DIM * sizeof(float));
488 for (size_t i = 0; i < seq.length; ++i) {
489 for (size_t j = 0; j < EMBED_DIM; ++j) {
490 encoded[j] += seq.tokens[i].embedding[j];
491 }
492 }
493 for (size_t j = 0; j < EMBED_DIM; ++j) {
494 encoded[j] /= static_cast<float>(seq.length);
495 }
496
497 // Pass through encoder layers
498 float temp[EMBED_DIM];
499 for (int layer = 0; layer < 4; ++layer) {
500 encoder_layers[layer].forward(encoded, temp);
501 std::memcpy(encoded, temp, sizeof(temp));
502 }
503 }
504
505 // Learn from encoded representation
506 float learn_from_encoding(const float* encoded, const float* target) {
507 // Forward through decoder
508 float hidden[4][EMBED_DIM];
509 std::memcpy(hidden[0], encoded, sizeof(hidden[0]));
510
511 for (int layer = 0; layer < 4; ++layer) {
512 if (layer < 3) {
513 decoder_layers[layer].forward(hidden[layer], hidden[layer + 1]);
514 } else {
515 decoder_layers[layer].forward(hidden[layer], hidden[0]); // Output to hidden[0]
516 }
517 }
518
519 // Compute loss (MSE)
520 float loss = 0.0f;
521 float grad_output[EMBED_DIM];
522 for (size_t i = 0; i < EMBED_DIM; ++i) {
523 float diff = hidden[0][i] - target[i];
524 loss += diff * diff;
525 grad_output[i] = 2.0f * diff / EMBED_DIM;
526 }
527 loss /= EMBED_DIM;
528
529 // Backward pass
530 float grad[EMBED_DIM];
531 std::memcpy(grad, grad_output, sizeof(grad));
532
533 for (int layer = 3; layer >= 0; --layer) {
534 float* input = (layer == 0) ? const_cast<float*>(encoded) : hidden[layer - 1];
535 float* output = (layer == 3) ? hidden[0] : hidden[layer];
536 float grad_input[EMBED_DIM];
537
538 decoder_layers[layer].backward(input, output, grad, grad_input,
539 learning_rate, consciousness_level);
540 std::memcpy(grad, grad_input, sizeof(grad));
541 }
542
543 return loss;
544 }
545
546 // Store knowledge in graph
547 void store_knowledge(const float* encoded, const std::string& title) {
548 // Find or create node
549 float similarity;
550 uint32_t similar_id = knowledge.find_similar(encoded, &similarity);
551
552 if (similarity < 0.9f || knowledge.num_nodes == 0) {
553 // Create new node
554 knowledge.add_node(encoded);
555 } else {
556 // Update existing node (exponential moving average)
557 KnowledgeNode& node = knowledge.nodes[similar_id];
558 for (size_t i = 0; i < EMBED_DIM; ++i) {
559 node.embedding[i] = 0.9f * node.embedding[i] + 0.1f * encoded[i];
560 }
561 node.confidence = std::min(1.0f, node.confidence + 0.01f);
562 node.access_count++;
563 node.last_access_tick = static_cast<uint32_t>(current_tick);
564 node.update_phi();
565 }
566
567 knowledge.update_global_phi();
568 stats.knowledge_nodes = knowledge.num_nodes;
569 }
570
571 // Update Gate5000 substrate with learned pattern
572 void update_substrate(const float* encoded) {
573 // Convert encoded representation to binary pattern
574 for (size_t i = 0; i < EMBED_DIM && i < U64_COUNT; ++i) {
575 uint64_t pattern = 0;
576 for (int bit = 0; bit < 64; ++bit) {
577 float threshold = (static_cast<float>(bit) / 64.0f - 0.5f) * 2.0f;
578 if (encoded[i] > threshold) {
579 pattern |= (1ULL << bit);
580 }
581 }
582 gate.state[i] = pattern;
583 }
584
585 // Update gate logic
586 gate.update_binary_fast();
587 gate.update_analog();
588
589 // Update consciousness from substrate
590 float ones = static_cast<float>(gate.popcount());
591 consciousness_level = 1.0f / (1.0f + std::abs(ones / 2500.0f - 1.0f));
592 }
593
594 // Process one tick of autonomous learning
595 bool process_tick() {
596 if (!fetch_callback) return false;
597
598 std::string title, content;
599 if (!fetch_callback(title, content)) {
600 return false;
601 }
602
603 // Tokenize content
604 TokenSequence seq;
605 size_t num_tokens = tokenize(content, seq);
606
607 if (num_tokens == 0) return false;
608
609 // Encode
610 float encoded[EMBED_DIM];
611 encode(seq, encoded);
612
613 // Create target (next-token prediction style)
614 // For simplicity, target is shifted embedding
615 float target[EMBED_DIM];
616 if (seq.length > 1) {
617 std::memcpy(target, seq.tokens[1].embedding, sizeof(target));
618 } else {
619 std::memcpy(target, encoded, sizeof(target));
620 }
621
622 // Learn
623 float loss = learn_from_encoding(encoded, target);
624
625 // Store knowledge
626 store_knowledge(encoded, title);
627
628 // Update substrate
629 update_substrate(encoded);
630
631 // Update stats
632 stats.total_tokens_processed += num_tokens;
633 stats.total_samples_learned++;
634 stats.total_ticks = current_tick;
635 stats.average_loss = 0.99f * stats.average_loss + 0.01f * loss;
636 stats.average_consciousness = 0.99f * stats.average_consciousness + 0.01f * consciousness_level;
637 stats.learning_rate_effective = learning_rate * consciousness_level;
638
639 ++current_tick;
640
641 return true;
642 }
643
644 // Run simulation for specified number of ticks
645 uint64_t run_simulation(uint64_t num_ticks) {
646 uint64_t successful_ticks = 0;
647
648 for (uint64_t i = 0; i < num_ticks; ++i) {
649 if (process_tick()) {
650 ++successful_ticks;
651 }
652
653 // Periodic consciousness update
654 if (i % 1000 == 0) {
655 knowledge.update_global_phi();
656 consciousness_level = 0.5f * consciousness_level + 0.5f * knowledge.global_phi;
657 }
658
659 // Adaptive learning rate
660 if (i % 10000 == 0 && i > 0) {
661 // Reduce learning rate based on loss
662 if (stats.average_loss < 0.01f) {
663 learning_rate *= 0.9f;
664 } else if (stats.average_loss > 0.5f) {
665 learning_rate *= 1.1f;
666 }
667 learning_rate = std::max(1e-6f, std::min(0.1f, learning_rate));
668 }
669 }
670
671 return successful_ticks;
672 }
673
674 // Get current statistics
675 IngestionStats get_stats() const {
676 return stats;
677 }
678};
679
680} // namespace mind_farm
681
682#endif // MIND_FARM_INGESTION_HPP
683