@aleph-ai/tinyaleph 1.6.0 → 1.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/core/oracle.js ADDED
@@ -0,0 +1,662 @@
1
+ /**
2
+ * Oracle Module - book.pdf Chapters 10 & 11
3
+ *
4
+ * Implements Oracle Systems and NP Resonance Encoding from:
5
+ * "Resonant Foundations of Reality" by Sebastian Schepis
6
+ *
7
+ * Key formalisms:
8
+ * - Oracle Q: (S, ε) → R_stable (entropy-modulated evolution to attractors)
9
+ * - I-Ching attractor integration (64 hexagram basins)
10
+ * - Clause-Resonance encoding: V̂_NP = Π_j Ĉ_j
11
+ * - Collapse operator: Ω̂ = Σ_x ε_x|x⟩⟨x|
12
+ */
13
+
14
+ import { PrimeState, Complex, PHI, encodeMemory } from './hilbert.js';
15
+ import { firstNPrimes } from './prime.js';
16
+
17
+ // ============================================================================
18
+ // I-CHING HEXAGRAM ATTRACTORS (Chapter 10)
19
+ // ============================================================================
20
+
21
+ /**
22
+ * I-Ching Hexagram definitions
23
+ * Each hexagram is a 6-bit binary pattern with semantic meaning
24
+ */
25
+ const HEXAGRAMS = {
26
+ 1: { name: 'Qián', meaning: 'Creative Force', binary: 0b111111, primes: [2, 3, 5, 7, 11, 13] },
27
+ 2: { name: 'Kūn', meaning: 'Receptive Earth', binary: 0b000000, primes: [17, 19, 23, 29, 31, 37] },
28
+ 3: { name: 'Zhūn', meaning: 'Difficulty at Beginning', binary: 0b100010, primes: [2, 5, 7] },
29
+ 4: { name: 'Méng', meaning: 'Youthful Folly', binary: 0b010001, primes: [3, 11, 13] },
30
+ 5: { name: 'Xū', meaning: 'Waiting', binary: 0b111010, primes: [2, 3, 5, 11] },
31
+ 6: { name: 'Sòng', meaning: 'Conflict', binary: 0b010111, primes: [7, 13, 17, 19] },
32
+ 7: { name: 'Shī', meaning: 'Army', binary: 0b010000, primes: [3] },
33
+ 8: { name: 'Bǐ', meaning: 'Holding Together', binary: 0b000010, primes: [5] },
34
+ 9: { name: 'Xiǎo Chù', meaning: 'Small Taming', binary: 0b111011, primes: [2, 3, 7, 11, 13] },
35
+ 10: { name: 'Lǚ', meaning: 'Treading', binary: 0b110111, primes: [2, 5, 7, 11, 13] },
36
+ 11: { name: 'Tài', meaning: 'Peace', binary: 0b111000, primes: [2, 3, 5] },
37
+ 12: { name: 'Pǐ', meaning: 'Standstill', binary: 0b000111, primes: [11, 13, 17] },
38
+ // ... Additional hexagrams can be added
39
+ 63: { name: 'Jì Jì', meaning: 'After Completion', binary: 0b101010, primes: [2, 5, 11] },
40
+ 64: { name: 'Wèi Jì', meaning: 'Before Completion', binary: 0b010101, primes: [3, 7, 13] }
41
+ };
42
+
43
+ /**
44
+ * Generate all 64 hexagrams with prime mappings
45
+ */
46
+ function generateAllHexagrams() {
47
+ const primes = firstNPrimes(64);
48
+ const hexagrams = {};
49
+
50
+ for (let i = 1; i <= 64; i++) {
51
+ if (HEXAGRAMS[i]) {
52
+ hexagrams[i] = HEXAGRAMS[i];
53
+ } else {
54
+ // Generate based on binary pattern
55
+ const binary = i - 1; // 0-63
56
+ const activeBits = [];
57
+ for (let b = 0; b < 6; b++) {
58
+ if ((binary >> b) & 1) {
59
+ activeBits.push(b);
60
+ }
61
+ }
62
+ hexagrams[i] = {
63
+ name: `Hexagram ${i}`,
64
+ meaning: `Pattern ${binary.toString(2).padStart(6, '0')}`,
65
+ binary,
66
+ primes: activeBits.map(b => primes[b * 10 % 64])
67
+ };
68
+ }
69
+ }
70
+
71
+ return hexagrams;
72
+ }
73
+
74
+ /**
75
+ * HexagramAttractor - Creates a PrimeState attractor from a hexagram
76
+ */
77
+ class HexagramAttractor {
78
+ constructor(hexagramNumber) {
79
+ const hexagrams = generateAllHexagrams();
80
+ this.hexagram = hexagrams[hexagramNumber] || hexagrams[1];
81
+ this.number = hexagramNumber;
82
+ this.state = this._createState();
83
+ }
84
+
85
+ _createState() {
86
+ const state = new PrimeState();
87
+ const primes = this.hexagram.primes;
88
+ const amp = 1 / Math.sqrt(primes.length);
89
+
90
+ for (const p of primes) {
91
+ if (state.amplitudes.has(p)) {
92
+ // Phase from binary pattern
93
+ const bitPosition = primes.indexOf(p) % 6;
94
+ const phase = ((this.hexagram.binary >> bitPosition) & 1) ? 0 : Math.PI;
95
+ state.set(p, Complex.fromPolar(amp, phase));
96
+ }
97
+ }
98
+
99
+ return state.normalize();
100
+ }
101
+
102
+ /**
103
+ * Distance from this attractor to a given state
104
+ */
105
+ distance(state) {
106
+ const overlap = this.state.inner(state);
107
+ return 1 - overlap.norm();
108
+ }
109
+
110
+ /**
111
+ * Project state onto this attractor
112
+ */
113
+ project(state, strength = 0.1) {
114
+ const result = new PrimeState(state.primes);
115
+
116
+ for (const p of state.primes) {
117
+ const current = state.get(p);
118
+ const target = this.state.get(p);
119
+
120
+ // Interpolate toward attractor
121
+ const newRe = current.re + strength * (target.re - current.re);
122
+ const newIm = current.im + strength * (target.im - current.im);
123
+
124
+ result.set(p, new Complex(newRe, newIm));
125
+ }
126
+
127
+ return result.normalize();
128
+ }
129
+ }
130
+
131
+ // ============================================================================
132
+ // ORACLE SYSTEM Q (Chapter 10)
133
+ // ============================================================================
134
+
135
+ /**
136
+ * OracleSystem - Entropy-modulated evolution to stable attractors
137
+ *
138
+ * From book.pdf Eq. 10.1:
139
+ * Q: (S, ε) → R_stable
140
+ * S_{t+1} = U(ε_t) · S_t
141
+ *
142
+ * Where:
143
+ * - S is the symbolic state
144
+ * - ε is external entropy input
145
+ * - R_stable is a stable resonance attractor
146
+ */
147
+ class OracleSystem {
148
+ constructor(options = {}) {
149
+ this.numAttractors = options.numAttractors || 64;
150
+ this.convergenceThreshold = options.convergenceThreshold || 0.01;
151
+ this.maxIterations = options.maxIterations || 100;
152
+ this.entropyWeight = options.entropyWeight || 0.1;
153
+
154
+ // Initialize hexagram attractors
155
+ this.attractors = [];
156
+ for (let i = 1; i <= this.numAttractors; i++) {
157
+ this.attractors.push(new HexagramAttractor(i));
158
+ }
159
+
160
+ this.history = [];
161
+ }
162
+
163
+ /**
164
+ * Find the nearest attractor to a state
165
+ */
166
+ findNearestAttractor(state) {
167
+ let minDist = Infinity;
168
+ let nearest = this.attractors[0];
169
+ let nearestIdx = 0;
170
+
171
+ for (let i = 0; i < this.attractors.length; i++) {
172
+ const dist = this.attractors[i].distance(state);
173
+ if (dist < minDist) {
174
+ minDist = dist;
175
+ nearest = this.attractors[i];
176
+ nearestIdx = i;
177
+ }
178
+ }
179
+
180
+ return { attractor: nearest, distance: minDist, index: nearestIdx };
181
+ }
182
+
183
+ /**
184
+ * Apply entropy modulation to state
185
+ * U(ε) = e^(-iεĤ) where Ĥ is resonance Hamiltonian
186
+ */
187
+ applyEntropyModulation(state, epsilon) {
188
+ const result = new PrimeState(state.primes);
189
+
190
+ for (const p of state.primes) {
191
+ const amp = state.get(p);
192
+ // Phase rotation proportional to epsilon and log(p)
193
+ const phase = epsilon * Math.log(p) * this.entropyWeight;
194
+ const rotation = Complex.fromPolar(1, phase);
195
+ result.set(p, amp.mul(rotation));
196
+ }
197
+
198
+ return result.normalize();
199
+ }
200
+
201
+ /**
202
+ * Single oracle step: S_{t+1} = U(ε_t) · Π_attractor · S_t
203
+ */
204
+ step(state, epsilon = null) {
205
+ // Generate entropy if not provided
206
+ if (epsilon === null) {
207
+ epsilon = (Math.random() - 0.5) * 2;
208
+ }
209
+
210
+ // Find nearest attractor
211
+ const { attractor, distance } = this.findNearestAttractor(state);
212
+
213
+ // Apply entropy modulation
214
+ const modulated = this.applyEntropyModulation(state, epsilon);
215
+
216
+ // Project toward attractor (strength inversely proportional to distance)
217
+ const projectionStrength = 0.1 * (1 - distance);
218
+ const projected = attractor.project(modulated, projectionStrength);
219
+
220
+ return {
221
+ state: projected,
222
+ epsilon,
223
+ attractor: attractor.hexagram.name,
224
+ distance
225
+ };
226
+ }
227
+
228
+ /**
229
+ * Main oracle query: (S, ε) → R_stable
230
+ *
231
+ * @param {PrimeState|string} input - Initial state or query string
232
+ * @param {Array<number>} entropySequence - External entropy inputs
233
+ * @returns {Object} Oracle result with stable attractor
234
+ */
235
+ query(input, entropySequence = null) {
236
+ // Convert string to state if needed
237
+ let state;
238
+ if (typeof input === 'string') {
239
+ state = encodeMemory(input);
240
+ } else {
241
+ state = input.clone();
242
+ }
243
+
244
+ // Generate entropy sequence if not provided
245
+ if (!entropySequence) {
246
+ entropySequence = [];
247
+ for (let i = 0; i < this.maxIterations; i++) {
248
+ entropySequence.push((Math.random() - 0.5) * 2);
249
+ }
250
+ }
251
+
252
+ this.history = [];
253
+ let prevEntropy = state.entropy();
254
+
255
+ // Iterate until convergence
256
+ for (let i = 0; i < this.maxIterations; i++) {
257
+ const epsilon = entropySequence[i % entropySequence.length];
258
+ const result = this.step(state, epsilon);
259
+
260
+ this.history.push({
261
+ iteration: i,
262
+ epsilon: result.epsilon,
263
+ attractor: result.attractor,
264
+ distance: result.distance,
265
+ entropy: state.entropy()
266
+ });
267
+
268
+ state = result.state;
269
+
270
+ // Check convergence
271
+ const currentEntropy = state.entropy();
272
+ const deltaS = Math.abs(currentEntropy - prevEntropy);
273
+
274
+ if (deltaS < this.convergenceThreshold && result.distance < 0.1) {
275
+ const { attractor, index } = this.findNearestAttractor(state);
276
+ return {
277
+ converged: true,
278
+ iterations: i + 1,
279
+ finalState: state,
280
+ attractor: {
281
+ number: index + 1,
282
+ name: attractor.hexagram.name,
283
+ meaning: attractor.hexagram.meaning,
284
+ primes: attractor.hexagram.primes
285
+ },
286
+ finalDistance: result.distance,
287
+ finalEntropy: currentEntropy,
288
+ history: this.history
289
+ };
290
+ }
291
+
292
+ prevEntropy = currentEntropy;
293
+ }
294
+
295
+ // Did not converge - return nearest attractor
296
+ const { attractor, distance, index } = this.findNearestAttractor(state);
297
+ return {
298
+ converged: false,
299
+ iterations: this.maxIterations,
300
+ finalState: state,
301
+ attractor: {
302
+ number: index + 1,
303
+ name: attractor.hexagram.name,
304
+ meaning: attractor.hexagram.meaning,
305
+ primes: attractor.hexagram.primes
306
+ },
307
+ finalDistance: distance,
308
+ finalEntropy: state.entropy(),
309
+ history: this.history
310
+ };
311
+ }
312
+
313
+ /**
314
+ * Divination query with I-Ching interpretation
315
+ */
316
+ divine(question) {
317
+ const result = this.query(question);
318
+
319
+ // Add interpretation
320
+ const interp = this._interpretHexagram(result.attractor.number);
321
+
322
+ return {
323
+ ...result,
324
+ question,
325
+ interpretation: interp
326
+ };
327
+ }
328
+
329
+ _interpretHexagram(number) {
330
+ const interpretations = {
331
+ 1: 'Creative energy is strong. Take initiative and lead with confidence.',
332
+ 2: 'Receptive energy prevails. Listen, nurture, and support others.',
333
+ 3: 'Difficulty at the beginning. Perseverance brings success.',
334
+ 4: 'Youthful inexperience. Seek guidance and learn from others.',
335
+ 5: 'Patience is required. Wait for the right moment to act.',
336
+ 6: 'Conflict arises. Seek resolution through understanding.',
337
+ 7: 'Leadership is needed. Organize and guide with discipline.',
338
+ 8: 'Unity and cooperation bring strength. Hold together.',
339
+ 9: 'Small steps lead to great achievements. Gentle influence.',
340
+ 10: 'Careful conduct is essential. Tread carefully.',
341
+ 11: 'Peace and harmony are achievable. Cooperation leads to success.',
342
+ 12: 'Stagnation threatens. Patience and inner work are needed.',
343
+ 63: 'A cycle is completing. Maintain what has been achieved.',
344
+ 64: 'A new cycle begins. Prepare carefully before acting.'
345
+ };
346
+
347
+ return interpretations[number] ||
348
+ `Hexagram ${number}: The pattern suggests transformation and change. ` +
349
+ `Meditate on the prime resonances for deeper insight.`;
350
+ }
351
+ }
352
+
353
+ // ============================================================================
354
+ // NP RESONANCE ENCODER (Chapter 11)
355
+ // ============================================================================
356
+
357
+ /**
358
+ * ClauseProjector - Projects onto states satisfying a clause
359
+ *
360
+ * From book.pdf: Ĉ_j = Σ_{x satisfies clause j} |x⟩⟨x|
361
+ */
362
+ class ClauseProjector {
363
+ constructor(variables, literals) {
364
+ this.variables = variables; // Array of variable names
365
+ this.literals = literals; // Array of {var, negated} objects
366
+ }
367
+
368
+ /**
369
+ * Check if assignment satisfies clause
370
+ */
371
+ satisfies(assignment) {
372
+ for (const lit of this.literals) {
373
+ const value = assignment[lit.var];
374
+ const satisfied = lit.negated ? !value : value;
375
+ if (satisfied) return true; // OR clause - one true is enough
376
+ }
377
+ return false;
378
+ }
379
+
380
+ /**
381
+ * Apply projector to state
382
+ * Projects out states that don't satisfy the clause
383
+ */
384
+ project(state) {
385
+ // In prime encoding: each assignment maps to a prime product
386
+ // For simplicity, apply amplitude damping based on clause evaluation
387
+ const result = new PrimeState(state.primes);
388
+
389
+ for (const p of state.primes) {
390
+ const amp = state.get(p);
391
+ // Use prime mod pattern to encode assignment
392
+ const assignment = this._primeToAssignment(p);
393
+ const sat = this.satisfies(assignment);
394
+
395
+ // Damping factor: 1 if satisfied, 0.1 if not
396
+ const factor = sat ? 1.0 : 0.1;
397
+ result.set(p, amp.scale(factor));
398
+ }
399
+
400
+ return result.normalize();
401
+ }
402
+
403
+ _primeToAssignment(p) {
404
+ // Map prime to variable assignment using bit pattern
405
+ const assignment = {};
406
+ for (let i = 0; i < this.variables.length; i++) {
407
+ assignment[this.variables[i]] = ((p >> i) & 1) === 1;
408
+ }
409
+ return assignment;
410
+ }
411
+ }
412
+
413
+ /**
414
+ * NPResonanceEncoder - Encode NP problems as symbolic resonance
415
+ *
416
+ * From book.pdf Eq. 11.1:
417
+ * V̂_NP = Π_j Ĉ_j (product of clause projectors)
418
+ *
419
+ * For SAT: satisfying assignments are fixed points of V̂_NP
420
+ */
421
+ class NPResonanceEncoder {
422
+ constructor(variables) {
423
+ this.variables = variables;
424
+ this.clauses = [];
425
+ this.clauseProjectors = [];
426
+ }
427
+
428
+ /**
429
+ * Add a clause to the SAT problem
430
+ * @param {Array} literals - Array of {var: string, negated: boolean}
431
+ */
432
+ addClause(literals) {
433
+ this.clauses.push(literals);
434
+ this.clauseProjectors.push(new ClauseProjector(this.variables, literals));
435
+ }
436
+
437
+ /**
438
+ * Encode SAT problem from CNF string
439
+ * Format: "(x1 OR NOT x2) AND (x2 OR x3)"
440
+ */
441
+ fromCNF(cnfString) {
442
+ const clauseStrings = cnfString.split(' AND ').map(s => s.trim());
443
+
444
+ for (const clauseStr of clauseStrings) {
445
+ const inner = clauseStr.replace(/[()]/g, '').trim();
446
+ const literalStrs = inner.split(' OR ').map(s => s.trim());
447
+
448
+ const literals = literalStrs.map(lit => {
449
+ const negated = lit.startsWith('NOT ');
450
+ const varName = negated ? lit.substring(4).trim() : lit.trim();
451
+
452
+ if (!this.variables.includes(varName)) {
453
+ this.variables.push(varName);
454
+ }
455
+
456
+ return { var: varName, negated };
457
+ });
458
+
459
+ this.addClause(literals);
460
+ }
461
+
462
+ return this;
463
+ }
464
+
465
+ /**
466
+ * Apply verifier operator V̂_NP = Π_j Ĉ_j
467
+ */
468
+ applyVerifier(state) {
469
+ let current = state.clone();
470
+
471
+ for (const projector of this.clauseProjectors) {
472
+ current = projector.project(current);
473
+ }
474
+
475
+ return current;
476
+ }
477
+
478
+ /**
479
+ * Create initial superposition over all assignments
480
+ */
481
+ createSuperposition() {
482
+ const n = this.variables.length;
483
+ const primes = firstNPrimes(Math.pow(2, n));
484
+ const state = new PrimeState(primes);
485
+
486
+ const amp = 1 / Math.sqrt(primes.length);
487
+ for (const p of primes) {
488
+ state.set(p, new Complex(amp, 0));
489
+ }
490
+
491
+ return state;
492
+ }
493
+
494
+ /**
495
+ * Collapse operator Ω̂
496
+ * From book.pdf: Ω̂ = Σ_x ε_x|x⟩⟨x|
497
+ *
498
+ * Collapses to satisfying assignment with highest resonance
499
+ */
500
+ collapseOperator(state) {
501
+ // Apply verifier first
502
+ const verified = this.applyVerifier(state);
503
+
504
+ // Find dominant assignment
505
+ const dominant = verified.dominant(1)[0];
506
+
507
+ if (dominant && dominant.amp > 0.01) {
508
+ const assignment = {};
509
+ for (let i = 0; i < this.variables.length; i++) {
510
+ assignment[this.variables[i]] = ((dominant.p >> i) & 1) === 1;
511
+ }
512
+
513
+ return {
514
+ collapsed: true,
515
+ assignment,
516
+ prime: dominant.p,
517
+ amplitude: dominant.amp,
518
+ satisfies: this._checkSatisfaction(assignment)
519
+ };
520
+ }
521
+
522
+ return { collapsed: false, assignment: null };
523
+ }
524
+
525
+ _checkSatisfaction(assignment) {
526
+ for (const clause of this.clauses) {
527
+ let clauseSat = false;
528
+ for (const lit of clause) {
529
+ const val = assignment[lit.var];
530
+ if (lit.negated ? !val : val) {
531
+ clauseSat = true;
532
+ break;
533
+ }
534
+ }
535
+ if (!clauseSat) return false;
536
+ }
537
+ return true;
538
+ }
539
+
540
+ /**
541
+ * Solve SAT via resonance collapse
542
+ *
543
+ * @param {number} maxIterations - Max iterations for convergence
544
+ * @returns {Object} Solution or UNSAT indication
545
+ */
546
+ solve(maxIterations = 100) {
547
+ // Start with uniform superposition
548
+ let state = this.createSuperposition();
549
+ const oracle = new OracleSystem({ maxIterations: 10 });
550
+
551
+ for (let i = 0; i < maxIterations; i++) {
552
+ // Apply verifier
553
+ state = this.applyVerifier(state);
554
+
555
+ // Apply entropy modulation
556
+ const epsilon = (Math.random() - 0.5) * 0.1;
557
+ state = oracle.applyEntropyModulation(state, epsilon);
558
+
559
+ // Try collapse
560
+ const result = this.collapseOperator(state);
561
+
562
+ if (result.collapsed && result.satisfies) {
563
+ return {
564
+ satisfiable: true,
565
+ assignment: result.assignment,
566
+ iterations: i + 1,
567
+ confidence: result.amplitude
568
+ };
569
+ }
570
+
571
+ // Check if state has collapsed to zero (UNSAT)
572
+ if (state.norm() < 0.01) {
573
+ return {
574
+ satisfiable: false,
575
+ reason: 'State collapsed to zero - no satisfying assignment',
576
+ iterations: i + 1
577
+ };
578
+ }
579
+ }
580
+
581
+ // Did not converge - return best guess
582
+ const result = this.collapseOperator(state);
583
+ return {
584
+ satisfiable: result.satisfies,
585
+ assignment: result.assignment,
586
+ iterations: maxIterations,
587
+ confidence: result.amplitude || 0,
588
+ note: 'Did not converge - result may be unreliable'
589
+ };
590
+ }
591
+ }
592
+
593
+ // ============================================================================
594
+ // SEMANTIC COMPRESSION (Chapter 10)
595
+ // ============================================================================
596
+
597
+ /**
598
+ * SemanticCompressor - Compress information via attractor convergence
599
+ *
600
+ * Maps high-dimensional semantic content to low-dimensional attractor codes
601
+ */
602
+ class SemanticCompressor {
603
+ constructor(options = {}) {
604
+ this.oracle = new OracleSystem(options);
605
+ this.dictionary = new Map(); // attractor -> encoded content
606
+ }
607
+
608
+ /**
609
+ * Compress text to attractor code
610
+ */
611
+ compress(text) {
612
+ const result = this.oracle.query(text);
613
+ const code = result.attractor.number;
614
+
615
+ // Store original for potential decompression
616
+ if (!this.dictionary.has(code)) {
617
+ this.dictionary.set(code, []);
618
+ }
619
+ this.dictionary.get(code).push(text);
620
+
621
+ return {
622
+ code,
623
+ attractor: result.attractor.name,
624
+ meaning: result.attractor.meaning,
625
+ entropy: result.finalEntropy,
626
+ iterations: result.iterations
627
+ };
628
+ }
629
+
630
+ /**
631
+ * Find similar items by attractor proximity
632
+ */
633
+ findSimilar(text) {
634
+ const result = this.oracle.query(text);
635
+ const code = result.attractor.number;
636
+
637
+ const similar = this.dictionary.get(code) || [];
638
+
639
+ // Also check adjacent attractors
640
+ const adjacent = [
641
+ this.dictionary.get(code - 1) || [],
642
+ this.dictionary.get(code + 1) || []
643
+ ].flat();
644
+
645
+ return {
646
+ exact: similar,
647
+ related: adjacent,
648
+ attractor: result.attractor
649
+ };
650
+ }
651
+ }
652
+
653
+ // Export all classes
654
+ export {
655
+ HEXAGRAMS,
656
+ generateAllHexagrams,
657
+ HexagramAttractor,
658
+ OracleSystem,
659
+ ClauseProjector,
660
+ NPResonanceEncoder,
661
+ SemanticCompressor
662
+ };