@aleph-ai/tinyaleph 1.0.0
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/LICENSE +21 -0
- package/README.md +278 -0
- package/backends/cryptographic/index.js +196 -0
- package/backends/index.js +15 -0
- package/backends/interface.js +89 -0
- package/backends/scientific/index.js +272 -0
- package/backends/semantic/index.js +527 -0
- package/backends/semantic/surface.js +393 -0
- package/backends/semantic/two-layer.js +375 -0
- package/core/fano.js +127 -0
- package/core/hilbert.js +564 -0
- package/core/hypercomplex.js +141 -0
- package/core/index.js +133 -0
- package/core/llm.js +132 -0
- package/core/prime.js +184 -0
- package/core/resonance.js +695 -0
- package/core/rformer-tf.js +1086 -0
- package/core/rformer.js +806 -0
- package/core/sieve.js +350 -0
- package/data.json +8163 -0
- package/docs/EXAMPLES_PLAN.md +293 -0
- package/docs/README.md +159 -0
- package/docs/design/ALEPH_CHAT_ARCHITECTURE.md +499 -0
- package/docs/guide/01-quickstart.md +298 -0
- package/docs/guide/02-semantic-computing.md +409 -0
- package/docs/guide/03-cryptographic.md +420 -0
- package/docs/guide/04-scientific.md +494 -0
- package/docs/guide/05-llm-integration.md +568 -0
- package/docs/guide/06-advanced.md +996 -0
- package/docs/guide/README.md +188 -0
- package/docs/reference/01-core.md +695 -0
- package/docs/reference/02-physics.md +601 -0
- package/docs/reference/03-backends.md +892 -0
- package/docs/reference/04-engine.md +632 -0
- package/docs/reference/README.md +252 -0
- package/docs/theory/01-prime-semantics.md +327 -0
- package/docs/theory/02-hypercomplex-algebra.md +421 -0
- package/docs/theory/03-phase-synchronization.md +364 -0
- package/docs/theory/04-entropy-reasoning.md +348 -0
- package/docs/theory/05-non-commutativity.md +402 -0
- package/docs/theory/06-two-layer-meaning.md +414 -0
- package/docs/theory/07-resonant-field-interface.md +419 -0
- package/docs/theory/08-semantic-sieve.md +520 -0
- package/docs/theory/09-temporal-emergence.md +298 -0
- package/docs/theory/10-quaternionic-memory.md +415 -0
- package/docs/theory/README.md +162 -0
- package/engine/aleph.js +418 -0
- package/engine/index.js +7 -0
- package/index.js +23 -0
- package/modular.js +254 -0
- package/package.json +99 -0
- package/physics/collapse.js +95 -0
- package/physics/entropy.js +88 -0
- package/physics/index.js +65 -0
- package/physics/kuramoto.js +91 -0
- package/physics/lyapunov.js +80 -0
- package/physics/oscillator.js +95 -0
- package/types/index.d.ts +575 -0
package/core/rformer.js
ADDED
|
@@ -0,0 +1,806 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResoFormer Primitives
|
|
3
|
+
*
|
|
4
|
+
* Resonant Field Transformer: a prime-indexed, phase-interference model with
|
|
5
|
+
* quaternionic (order-sensitive) composition, coherence-gated compute,
|
|
6
|
+
* entropy-stabilized "collapse," and a prime-resonant external memory.
|
|
7
|
+
*
|
|
8
|
+
* H_Q = H_P ⊗ ℍ (Prime Hilbert space tensor Quaternions)
|
|
9
|
+
*
|
|
10
|
+
* Based on the ResoFormer specification combining:
|
|
11
|
+
* - PRSC (Prime Resonance Symbolic Computing)
|
|
12
|
+
* - Quantum Semantics
|
|
13
|
+
* - Quaternionic Memory Field (QMF)
|
|
14
|
+
* - Prime Resonant Graph Database
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const { firstNPrimes, isPrime, factorize } = require('./prime');
|
|
18
|
+
const { Complex, PrimeState } = require('./hilbert');
|
|
19
|
+
|
|
20
|
+
// ============================================================================
|
|
21
|
+
// QUATERNION ALGEBRA
|
|
22
|
+
// ============================================================================
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Full Quaternion class for H_Q representation
|
|
26
|
+
* q = w + xi + yj + zk (Hamilton quaternion)
|
|
27
|
+
*/
|
|
28
|
+
class Quaternion {
|
|
29
|
+
constructor(w = 1, x = 0, y = 0, z = 0) {
|
|
30
|
+
this.w = w; // scalar part
|
|
31
|
+
this.x = x; // i component
|
|
32
|
+
this.y = y; // j component
|
|
33
|
+
this.z = z; // k component
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
static zero() { return new Quaternion(0, 0, 0, 0); }
|
|
37
|
+
static one() { return new Quaternion(1, 0, 0, 0); }
|
|
38
|
+
static i() { return new Quaternion(0, 1, 0, 0); }
|
|
39
|
+
static j() { return new Quaternion(0, 0, 1, 0); }
|
|
40
|
+
static k() { return new Quaternion(0, 0, 0, 1); }
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Random unit quaternion (uniform on 3-sphere)
|
|
44
|
+
*/
|
|
45
|
+
static random() {
|
|
46
|
+
const u1 = Math.random();
|
|
47
|
+
const u2 = Math.random();
|
|
48
|
+
const u3 = Math.random();
|
|
49
|
+
|
|
50
|
+
const w = Math.sqrt(1 - u1) * Math.sin(2 * Math.PI * u2);
|
|
51
|
+
const x = Math.sqrt(1 - u1) * Math.cos(2 * Math.PI * u2);
|
|
52
|
+
const y = Math.sqrt(u1) * Math.sin(2 * Math.PI * u3);
|
|
53
|
+
const z = Math.sqrt(u1) * Math.cos(2 * Math.PI * u3);
|
|
54
|
+
|
|
55
|
+
return new Quaternion(w, x, y, z);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Create from axis-angle rotation
|
|
60
|
+
*/
|
|
61
|
+
static fromAxisAngle(axis, angle) {
|
|
62
|
+
const s = Math.sin(angle / 2);
|
|
63
|
+
const c = Math.cos(angle / 2);
|
|
64
|
+
const norm = Math.sqrt(axis[0]**2 + axis[1]**2 + axis[2]**2);
|
|
65
|
+
|
|
66
|
+
return new Quaternion(
|
|
67
|
+
c,
|
|
68
|
+
s * axis[0] / norm,
|
|
69
|
+
s * axis[1] / norm,
|
|
70
|
+
s * axis[2] / norm
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Hamilton product: q1 × q2
|
|
76
|
+
* NON-COMMUTATIVE: q1 × q2 ≠ q2 × q1
|
|
77
|
+
*/
|
|
78
|
+
mul(other) {
|
|
79
|
+
return new Quaternion(
|
|
80
|
+
this.w * other.w - this.x * other.x - this.y * other.y - this.z * other.z,
|
|
81
|
+
this.w * other.x + this.x * other.w + this.y * other.z - this.z * other.y,
|
|
82
|
+
this.w * other.y - this.x * other.z + this.y * other.w + this.z * other.x,
|
|
83
|
+
this.w * other.z + this.x * other.y - this.y * other.x + this.z * other.w
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Quaternion addition
|
|
89
|
+
*/
|
|
90
|
+
add(other) {
|
|
91
|
+
return new Quaternion(
|
|
92
|
+
this.w + other.w,
|
|
93
|
+
this.x + other.x,
|
|
94
|
+
this.y + other.y,
|
|
95
|
+
this.z + other.z
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Scalar multiplication
|
|
101
|
+
*/
|
|
102
|
+
scale(k) {
|
|
103
|
+
return new Quaternion(this.w * k, this.x * k, this.y * k, this.z * k);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Conjugate: q* = w - xi - yj - zk
|
|
108
|
+
*/
|
|
109
|
+
conjugate() {
|
|
110
|
+
return new Quaternion(this.w, -this.x, -this.y, -this.z);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* Norm: |q|² = w² + x² + y² + z²
|
|
115
|
+
*/
|
|
116
|
+
norm2() {
|
|
117
|
+
return this.w**2 + this.x**2 + this.y**2 + this.z**2;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
norm() {
|
|
121
|
+
return Math.sqrt(this.norm2());
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Normalize to unit quaternion
|
|
126
|
+
*/
|
|
127
|
+
normalize() {
|
|
128
|
+
const n = this.norm();
|
|
129
|
+
return n > 1e-10 ? this.scale(1/n) : Quaternion.one();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Inverse: q^(-1) = conj(q)/|q|^2
|
|
134
|
+
*/
|
|
135
|
+
inverse() {
|
|
136
|
+
const n2 = this.norm2();
|
|
137
|
+
return n2 > 1e-10 ? this.conjugate().scale(1/n2) : Quaternion.zero();
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Dot product (as 4-vectors)
|
|
142
|
+
*/
|
|
143
|
+
dot(other) {
|
|
144
|
+
return this.w * other.w + this.x * other.x + this.y * other.y + this.z * other.z;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Commutator: [q1, q2] = q1×q2 - q2×q1
|
|
149
|
+
* Non-zero commutator indicates order matters!
|
|
150
|
+
*/
|
|
151
|
+
commutator(other) {
|
|
152
|
+
const ab = this.mul(other);
|
|
153
|
+
const ba = other.mul(this);
|
|
154
|
+
return new Quaternion(
|
|
155
|
+
ab.w - ba.w,
|
|
156
|
+
ab.x - ba.x,
|
|
157
|
+
ab.y - ba.y,
|
|
158
|
+
ab.z - ba.z
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Commutator norm - measure of non-commutativity
|
|
164
|
+
*/
|
|
165
|
+
commutatorNorm(other) {
|
|
166
|
+
return this.commutator(other).norm();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
toArray() { return [this.w, this.x, this.y, this.z]; }
|
|
170
|
+
|
|
171
|
+
toString() {
|
|
172
|
+
return `${this.w.toFixed(4)} + ${this.x.toFixed(4)}i + ${this.y.toFixed(4)}j + ${this.z.toFixed(4)}k`;
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
// ============================================================================
|
|
177
|
+
// SPARSE PRIME STATE (H_Q = H_P ⊗ ℍ)
|
|
178
|
+
// ============================================================================
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Sparse Prime-Quaternion State
|
|
182
|
+
* Each token is represented as sparse activations over primes,
|
|
183
|
+
* with each active prime having a complex amplitude AND quaternion orientation.
|
|
184
|
+
*
|
|
185
|
+
* |Ψ_t⟩ = Σ_{p ∈ P_t} α_{t,p} · q_{t,p} · |p⟩
|
|
186
|
+
* - α_{t,p} ∈ ℂ (complex amplitude with phase)
|
|
187
|
+
* - q_{t,p} ∈ ℍ (quaternion orientation)
|
|
188
|
+
*/
|
|
189
|
+
class SparsePrimeState {
|
|
190
|
+
constructor(numPrimes = 4096, activeK = 32) {
|
|
191
|
+
this.allPrimes = firstNPrimes(numPrimes);
|
|
192
|
+
this.k = activeK;
|
|
193
|
+
|
|
194
|
+
// Sparse activation: Map<prime, {amplitude: Complex, quaternion: Quaternion}>
|
|
195
|
+
this.activations = new Map();
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Get active primes
|
|
200
|
+
*/
|
|
201
|
+
getActivePrimes() {
|
|
202
|
+
return Array.from(this.activations.keys());
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Set activation for a prime
|
|
207
|
+
*/
|
|
208
|
+
set(p, amplitude, quaternion) {
|
|
209
|
+
if (!isPrime(p)) return this;
|
|
210
|
+
this.activations.set(p, {
|
|
211
|
+
amplitude: amplitude instanceof Complex ? amplitude : new Complex(amplitude, 0),
|
|
212
|
+
quaternion: quaternion instanceof Quaternion ? quaternion : Quaternion.one()
|
|
213
|
+
});
|
|
214
|
+
return this;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
/**
|
|
218
|
+
* Get activation for a prime
|
|
219
|
+
*/
|
|
220
|
+
get(p) {
|
|
221
|
+
return this.activations.get(p) || { amplitude: Complex.zero(), quaternion: Quaternion.zero() };
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Create from prime-entropy hash (deterministic)
|
|
226
|
+
*/
|
|
227
|
+
static fromHash(text, numPrimes = 4096, k = 32) {
|
|
228
|
+
const state = new SparsePrimeState(numPrimes, k);
|
|
229
|
+
const primes = state.allPrimes;
|
|
230
|
+
|
|
231
|
+
// Hash text to select k primes
|
|
232
|
+
let hash = 0;
|
|
233
|
+
for (let i = 0; i < text.length; i++) {
|
|
234
|
+
hash = ((hash << 5) - hash + text.charCodeAt(i)) | 0;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
const selectedPrimes = [];
|
|
238
|
+
for (let i = 0; i < k; i++) {
|
|
239
|
+
const idx = Math.abs((hash * (i + 1) * 31337) % primes.length);
|
|
240
|
+
selectedPrimes.push(primes[idx]);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Assign amplitudes and quaternions based on text
|
|
244
|
+
for (let i = 0; i < selectedPrimes.length; i++) {
|
|
245
|
+
const p = selectedPrimes[i];
|
|
246
|
+
const phase = 2 * Math.PI * i / k;
|
|
247
|
+
const amplitude = Complex.fromPolar(1/Math.sqrt(k), phase);
|
|
248
|
+
|
|
249
|
+
// Create quaternion from character codes
|
|
250
|
+
const charSum = text.split('').reduce((s, c) => s + c.charCodeAt(0), 0);
|
|
251
|
+
const q = Quaternion.fromAxisAngle(
|
|
252
|
+
[Math.sin(charSum + i), Math.cos(charSum * i), Math.sin(i)],
|
|
253
|
+
(charSum * i) % (2 * Math.PI)
|
|
254
|
+
);
|
|
255
|
+
|
|
256
|
+
state.set(p, amplitude, q.normalize());
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
return state;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
/**
|
|
263
|
+
* Create from explicit prime list
|
|
264
|
+
*/
|
|
265
|
+
static fromPrimes(primes, amplitudes = null, quaternions = null) {
|
|
266
|
+
const state = new SparsePrimeState(4096, primes.length);
|
|
267
|
+
|
|
268
|
+
for (let i = 0; i < primes.length; i++) {
|
|
269
|
+
const p = primes[i];
|
|
270
|
+
const amp = amplitudes ? amplitudes[i] : new Complex(1/Math.sqrt(primes.length), 0);
|
|
271
|
+
const q = quaternions ? quaternions[i] : Quaternion.random();
|
|
272
|
+
state.set(p, amp, q);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return state;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Normalize amplitudes to unit norm
|
|
280
|
+
*/
|
|
281
|
+
normalize() {
|
|
282
|
+
let sumSq = 0;
|
|
283
|
+
for (const [p, act] of this.activations) {
|
|
284
|
+
sumSq += act.amplitude.norm2();
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
const norm = Math.sqrt(sumSq);
|
|
288
|
+
if (norm < 1e-10) return this;
|
|
289
|
+
|
|
290
|
+
for (const [p, act] of this.activations) {
|
|
291
|
+
act.amplitude = act.amplitude.scale(1/norm);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
return this;
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Compute entropy over prime amplitudes
|
|
299
|
+
*/
|
|
300
|
+
entropy() {
|
|
301
|
+
let sumSq = 0;
|
|
302
|
+
for (const [p, act] of this.activations) {
|
|
303
|
+
sumSq += act.amplitude.norm2();
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (sumSq < 1e-10) return 0;
|
|
307
|
+
|
|
308
|
+
let h = 0;
|
|
309
|
+
for (const [p, act] of this.activations) {
|
|
310
|
+
const prob = act.amplitude.norm2() / sumSq;
|
|
311
|
+
if (prob > 1e-10) {
|
|
312
|
+
h -= prob * Math.log2(prob);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
return h;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
// ============================================================================
|
|
321
|
+
// RESONANT ATTENTION SCORE
|
|
322
|
+
// ============================================================================
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Resonance score between two sparse prime states
|
|
326
|
+
* Res(i,j) = α·Jaccard(P_i, P_j) + β·QuaternionAlign + γ·PhaseCoherence
|
|
327
|
+
*/
|
|
328
|
+
function resonanceScore(stateI, stateJ, alpha = 0.33, beta = 0.33, gamma = 0.34) {
|
|
329
|
+
const primesI = new Set(stateI.getActivePrimes());
|
|
330
|
+
const primesJ = new Set(stateJ.getActivePrimes());
|
|
331
|
+
|
|
332
|
+
// 1. Jaccard similarity of prime sets
|
|
333
|
+
const intersection = new Set([...primesI].filter(p => primesJ.has(p)));
|
|
334
|
+
const union = new Set([...primesI, ...primesJ]);
|
|
335
|
+
const jaccard = intersection.size / (union.size || 1);
|
|
336
|
+
|
|
337
|
+
if (intersection.size === 0) {
|
|
338
|
+
return alpha * jaccard; // No overlap, just return Jaccard
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// 2. Quaternion alignment on overlapping primes
|
|
342
|
+
let quatSum = 0;
|
|
343
|
+
for (const p of intersection) {
|
|
344
|
+
const qi = stateI.get(p).quaternion;
|
|
345
|
+
const qj = stateJ.get(p).quaternion;
|
|
346
|
+
quatSum += Math.abs(qi.dot(qj));
|
|
347
|
+
}
|
|
348
|
+
const quatAlign = quatSum / intersection.size;
|
|
349
|
+
|
|
350
|
+
// 3. Phase coherence on overlapping primes
|
|
351
|
+
let phaseSum = 0;
|
|
352
|
+
for (const p of intersection) {
|
|
353
|
+
const phaseI = stateI.get(p).amplitude.phase();
|
|
354
|
+
const phaseJ = stateJ.get(p).amplitude.phase();
|
|
355
|
+
phaseSum += Math.cos(phaseI - phaseJ);
|
|
356
|
+
}
|
|
357
|
+
const phaseCoherence = (phaseSum / intersection.size + 1) / 2; // Normalize to [0, 1]
|
|
358
|
+
|
|
359
|
+
return alpha * jaccard + beta * quatAlign + gamma * phaseCoherence;
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/**
|
|
363
|
+
* Resonant attention over a set of states (replacing dot-product attention)
|
|
364
|
+
*/
|
|
365
|
+
function resonantAttention(query, keys, values, temperature = 1.0) {
|
|
366
|
+
const n = keys.length;
|
|
367
|
+
if (n === 0) return null;
|
|
368
|
+
|
|
369
|
+
// Compute resonance scores
|
|
370
|
+
const scores = keys.map(k => resonanceScore(query, k));
|
|
371
|
+
|
|
372
|
+
// Softmax
|
|
373
|
+
const maxScore = Math.max(...scores);
|
|
374
|
+
const expScores = scores.map(s => Math.exp((s - maxScore) / temperature));
|
|
375
|
+
const sumExp = expScores.reduce((a, b) => a + b, 0);
|
|
376
|
+
const weights = expScores.map(e => e / sumExp);
|
|
377
|
+
|
|
378
|
+
// Weighted sum of values (as sparse states)
|
|
379
|
+
const result = new SparsePrimeState(query.allPrimes.length, query.k);
|
|
380
|
+
|
|
381
|
+
for (let i = 0; i < n; i++) {
|
|
382
|
+
const w = weights[i];
|
|
383
|
+
for (const [p, act] of values[i].activations) {
|
|
384
|
+
const current = result.get(p);
|
|
385
|
+
const newAmp = current.amplitude.add(act.amplitude.scale(w));
|
|
386
|
+
const newQuat = current.quaternion.add(act.quaternion.scale(w));
|
|
387
|
+
result.set(p, newAmp, newQuat.normalize());
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
return { result: result.normalize(), weights, scores };
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// ============================================================================
|
|
395
|
+
// HAMILTON PRODUCT COMPOSITION (ORDER-SENSITIVE)
|
|
396
|
+
// ============================================================================
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Compose two states using Hamilton product for quaternion mixing
|
|
400
|
+
* This is ORDER-SENSITIVE: compose(A, B) ≠ compose(B, A)
|
|
401
|
+
*/
|
|
402
|
+
function hamiltonCompose(stateA, stateB) {
|
|
403
|
+
const result = new SparsePrimeState(stateA.allPrimes.length, stateA.k);
|
|
404
|
+
|
|
405
|
+
// Get union of active primes
|
|
406
|
+
const primesA = new Set(stateA.getActivePrimes());
|
|
407
|
+
const primesB = new Set(stateB.getActivePrimes());
|
|
408
|
+
const allPrimes = new Set([...primesA, ...primesB]);
|
|
409
|
+
|
|
410
|
+
for (const p of allPrimes) {
|
|
411
|
+
const actA = stateA.get(p);
|
|
412
|
+
const actB = stateB.get(p);
|
|
413
|
+
|
|
414
|
+
// Amplitude: multiply complex amplitudes
|
|
415
|
+
const newAmp = actA.amplitude.mul(actB.amplitude);
|
|
416
|
+
|
|
417
|
+
// Quaternion: Hamilton product (non-commutative!)
|
|
418
|
+
const newQuat = actA.quaternion.mul(actB.quaternion);
|
|
419
|
+
|
|
420
|
+
result.set(p, newAmp, newQuat.normalize());
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
return result.normalize();
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Measure non-commutativity between two states
|
|
428
|
+
* Returns the average commutator norm over shared primes
|
|
429
|
+
*/
|
|
430
|
+
function measureNonCommutativity(stateA, stateB) {
|
|
431
|
+
const primesA = new Set(stateA.getActivePrimes());
|
|
432
|
+
const primesB = new Set(stateB.getActivePrimes());
|
|
433
|
+
const shared = [...primesA].filter(p => primesB.has(p));
|
|
434
|
+
|
|
435
|
+
if (shared.length === 0) return 0;
|
|
436
|
+
|
|
437
|
+
let totalCommNorm = 0;
|
|
438
|
+
for (const p of shared) {
|
|
439
|
+
const qA = stateA.get(p).quaternion;
|
|
440
|
+
const qB = stateB.get(p).quaternion;
|
|
441
|
+
totalCommNorm += qA.commutatorNorm(qB);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return totalCommNorm / shared.length;
|
|
445
|
+
}
|
|
446
|
+
|
|
447
|
+
// ============================================================================
|
|
448
|
+
// COHERENCE-GATED HALTING (ACT-STYLE)
|
|
449
|
+
// ============================================================================
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Coherence function for a sparse prime state
|
|
453
|
+
* C = Σ_{p,q ∈ P_t} w_pq · cos(θ_p - θ_q)
|
|
454
|
+
*/
|
|
455
|
+
function computeCoherence(state, weights = null) {
|
|
456
|
+
const primes = state.getActivePrimes();
|
|
457
|
+
const n = primes.length;
|
|
458
|
+
|
|
459
|
+
if (n < 2) return 1.0; // Single or no prime = fully coherent
|
|
460
|
+
|
|
461
|
+
let sum = 0;
|
|
462
|
+
let count = 0;
|
|
463
|
+
|
|
464
|
+
for (let i = 0; i < n; i++) {
|
|
465
|
+
for (let j = i + 1; j < n; j++) {
|
|
466
|
+
const phaseI = state.get(primes[i]).amplitude.phase();
|
|
467
|
+
const phaseJ = state.get(primes[j]).amplitude.phase();
|
|
468
|
+
const w = weights ? weights[i * n + j] : 1;
|
|
469
|
+
sum += w * Math.cos(phaseI - phaseJ);
|
|
470
|
+
count++;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
return (sum / count + 1) / 2; // Normalize to [0, 1]
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Adaptive Computation Time (ACT) halting decision
|
|
479
|
+
* Returns { halt: boolean, probability: number, coherence: number }
|
|
480
|
+
*/
|
|
481
|
+
function haltingDecision(state, threshold = 0.8, epsilon = 0.1) {
|
|
482
|
+
const coherence = computeCoherence(state);
|
|
483
|
+
const haltProbability = 1 / (1 + Math.exp(-(coherence - threshold) / epsilon));
|
|
484
|
+
const halt = Math.random() < haltProbability;
|
|
485
|
+
|
|
486
|
+
return { halt, probability: haltProbability, coherence };
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Run computation with coherence-gated halting
|
|
491
|
+
* stepFn: (state, step) => newState
|
|
492
|
+
* Returns { finalState, steps, haltHistory }
|
|
493
|
+
*/
|
|
494
|
+
function coherenceGatedCompute(initialState, stepFn, maxSteps = 100, threshold = 0.8) {
|
|
495
|
+
let state = initialState;
|
|
496
|
+
const history = [];
|
|
497
|
+
|
|
498
|
+
for (let step = 0; step < maxSteps; step++) {
|
|
499
|
+
const decision = haltingDecision(state, threshold);
|
|
500
|
+
history.push({ step, ...decision });
|
|
501
|
+
|
|
502
|
+
if (decision.halt) {
|
|
503
|
+
return { finalState: state, steps: step + 1, haltHistory: history, halted: true };
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
state = stepFn(state, step);
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
return { finalState: state, steps: maxSteps, haltHistory: history, halted: false };
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
// ============================================================================
|
|
513
|
+
// ENTROPY COLLAPSE HEAD (64-CODEBOOK)
|
|
514
|
+
// ============================================================================
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Generate 64 attractor states (I-Ching style codebook)
|
|
518
|
+
*/
|
|
519
|
+
function generateAttractorCodebook(numPrimes = 4096) {
|
|
520
|
+
const attractors = [];
|
|
521
|
+
const basePrimes = firstNPrimes(64); // First 64 primes as canonical bases
|
|
522
|
+
|
|
523
|
+
for (let i = 0; i < 64; i++) {
|
|
524
|
+
const state = new SparsePrimeState(numPrimes, 8);
|
|
525
|
+
|
|
526
|
+
// Each attractor activates 8 primes based on its index (6 bits)
|
|
527
|
+
for (let bit = 0; bit < 6; bit++) {
|
|
528
|
+
if ((i >> bit) & 1) {
|
|
529
|
+
const p = basePrimes[bit * 10 + (i % 10)]; // Spread across primes
|
|
530
|
+
const phase = 2 * Math.PI * bit / 6;
|
|
531
|
+
state.set(p, Complex.fromPolar(1/Math.sqrt(6), phase), Quaternion.random());
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
state.normalize();
|
|
536
|
+
attractors.push({ index: i, state });
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
return attractors;
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
/**
|
|
543
|
+
* Entropy collapse head: project to nearest attractor
|
|
544
|
+
*/
|
|
545
|
+
class EntropyCollapseHead {
|
|
546
|
+
constructor(targetEntropy = 5.99) {
|
|
547
|
+
this.attractors = generateAttractorCodebook();
|
|
548
|
+
this.targetEntropy = targetEntropy;
|
|
549
|
+
}
|
|
550
|
+
|
|
551
|
+
/**
|
|
552
|
+
* Compute logits over attractors using resonance score
|
|
553
|
+
*/
|
|
554
|
+
computeLogits(state) {
|
|
555
|
+
return this.attractors.map(a => resonanceScore(state, a.state));
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Soft assignment (training mode)
|
|
560
|
+
*/
|
|
561
|
+
softAssign(state, temperature = 1.0) {
|
|
562
|
+
const logits = this.computeLogits(state);
|
|
563
|
+
const maxLogit = Math.max(...logits);
|
|
564
|
+
const expLogits = logits.map(l => Math.exp((l - maxLogit) / temperature));
|
|
565
|
+
const sumExp = expLogits.reduce((a, b) => a + b, 0);
|
|
566
|
+
const probs = expLogits.map(e => e / sumExp);
|
|
567
|
+
|
|
568
|
+
return { logits, probs, entropy: this.computeEntropyFromProbs(probs) };
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
/**
|
|
572
|
+
* Hard assignment (inference mode)
|
|
573
|
+
*/
|
|
574
|
+
hardAssign(state) {
|
|
575
|
+
const logits = this.computeLogits(state);
|
|
576
|
+
const maxIdx = logits.indexOf(Math.max(...logits));
|
|
577
|
+
return { index: maxIdx, attractor: this.attractors[maxIdx], confidence: logits[maxIdx] };
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Compute entropy from probability distribution
|
|
582
|
+
*/
|
|
583
|
+
computeEntropyFromProbs(probs) {
|
|
584
|
+
let h = 0;
|
|
585
|
+
for (const p of probs) {
|
|
586
|
+
if (p > 1e-10) {
|
|
587
|
+
h -= p * Math.log2(p);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
return h;
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Entropy regularization loss (toward target)
|
|
595
|
+
*/
|
|
596
|
+
entropyLoss(state) {
|
|
597
|
+
const { entropy } = this.softAssign(state);
|
|
598
|
+
return Math.abs(entropy - this.targetEntropy);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
// ============================================================================
|
|
603
|
+
// PR-GRAPH MEMORY (PUT/GET)
|
|
604
|
+
// ============================================================================
|
|
605
|
+
|
|
606
|
+
/**
|
|
607
|
+
* Prime Resonant Graph Database
|
|
608
|
+
* Persistent content-addressable memory with resonance-based retrieval
|
|
609
|
+
*/
|
|
610
|
+
class PRGraphMemory {
|
|
611
|
+
constructor(numPrimes = 4096, lockThreshold = 0.8) {
|
|
612
|
+
this.allPrimes = firstNPrimes(numPrimes);
|
|
613
|
+
this.entries = new Map(); // key: hash -> {state, metadata, entropy, locked}
|
|
614
|
+
this.lockThreshold = lockThreshold;
|
|
615
|
+
this.decayRate = 0.1;
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
/**
|
|
619
|
+
* Generate prime-entropy hash for a key
|
|
620
|
+
*/
|
|
621
|
+
_primeEntropyHash(key) {
|
|
622
|
+
let hash = 0;
|
|
623
|
+
for (let i = 0; i < key.length; i++) {
|
|
624
|
+
hash = ((hash << 5) - hash + key.charCodeAt(i)) | 0;
|
|
625
|
+
}
|
|
626
|
+
return Math.abs(hash);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* PRG-Put: Write to memory
|
|
631
|
+
* 1. Prime-entropy hash selects k primes
|
|
632
|
+
* 2. Phase-code payload onto those primes
|
|
633
|
+
* 3. Store the superposition
|
|
634
|
+
*/
|
|
635
|
+
put(key, state, metadata = {}) {
|
|
636
|
+
const hash = this._primeEntropyHash(key);
|
|
637
|
+
|
|
638
|
+
// Initial entropy (starts high, will decay toward lock)
|
|
639
|
+
const entropy = state.entropy();
|
|
640
|
+
|
|
641
|
+
this.entries.set(hash, {
|
|
642
|
+
key,
|
|
643
|
+
state,
|
|
644
|
+
metadata,
|
|
645
|
+
entropy,
|
|
646
|
+
locked: false,
|
|
647
|
+
createdAt: Date.now(),
|
|
648
|
+
accessCount: 0
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
return hash;
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
/**
|
|
655
|
+
* PRG-Get: Read from memory
|
|
656
|
+
* 1. Generate probe from query
|
|
657
|
+
* 2. Compute resonance overlap with all entries
|
|
658
|
+
* 3. Lock by entropy-guided resonance
|
|
659
|
+
* 4. Return best match
|
|
660
|
+
*/
|
|
661
|
+
get(query, topK = 1) {
|
|
662
|
+
if (this.entries.size === 0) return [];
|
|
663
|
+
|
|
664
|
+
const results = [];
|
|
665
|
+
|
|
666
|
+
for (const [hash, entry] of this.entries) {
|
|
667
|
+
const score = resonanceScore(query, entry.state);
|
|
668
|
+
|
|
669
|
+
// Apply entropy decay
|
|
670
|
+
entry.entropy *= (1 - this.decayRate);
|
|
671
|
+
|
|
672
|
+
// Check lock condition: low entropy + high resonance
|
|
673
|
+
if (entry.entropy < 0.5 && score > this.lockThreshold) {
|
|
674
|
+
entry.locked = true;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
entry.accessCount++;
|
|
678
|
+
|
|
679
|
+
results.push({
|
|
680
|
+
hash,
|
|
681
|
+
key: entry.key,
|
|
682
|
+
score,
|
|
683
|
+
state: entry.state,
|
|
684
|
+
metadata: entry.metadata,
|
|
685
|
+
locked: entry.locked,
|
|
686
|
+
entropy: entry.entropy
|
|
687
|
+
});
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
// Sort by score
|
|
691
|
+
results.sort((a, b) => b.score - a.score);
|
|
692
|
+
|
|
693
|
+
return results.slice(0, topK);
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
/**
|
|
697
|
+
* Delete by hash
|
|
698
|
+
*/
|
|
699
|
+
delete(hash) {
|
|
700
|
+
return this.entries.delete(hash);
|
|
701
|
+
}
|
|
702
|
+
|
|
703
|
+
/**
|
|
704
|
+
* Get all locked entries (stable memories)
|
|
705
|
+
*/
|
|
706
|
+
getLockedMemories() {
|
|
707
|
+
return Array.from(this.entries.values()).filter(e => e.locked);
|
|
708
|
+
}
|
|
709
|
+
|
|
710
|
+
/**
|
|
711
|
+
* CRT reconstruction (for distributed storage)
|
|
712
|
+
*/
|
|
713
|
+
reconstructFromResidues(residues, primes) {
|
|
714
|
+
// Chinese Remainder Theorem reconstruction
|
|
715
|
+
// residues[i] ≡ value (mod primes[i])
|
|
716
|
+
let M = 1;
|
|
717
|
+
for (const p of primes) M *= p;
|
|
718
|
+
|
|
719
|
+
let result = 0;
|
|
720
|
+
for (let i = 0; i < primes.length; i++) {
|
|
721
|
+
const Mi = M / primes[i];
|
|
722
|
+
const yi = this._modInverse(Mi, primes[i]);
|
|
723
|
+
result = (result + residues[i] * Mi * yi) % M;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
return result;
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
_modInverse(a, m) {
|
|
730
|
+
let [old_r, r] = [a, m];
|
|
731
|
+
let [old_s, s] = [1, 0];
|
|
732
|
+
|
|
733
|
+
while (r !== 0) {
|
|
734
|
+
const quotient = Math.floor(old_r / r);
|
|
735
|
+
[old_r, r] = [r, old_r - quotient * r];
|
|
736
|
+
[old_s, s] = [s, old_s - quotient * s];
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
return ((old_s % m) + m) % m;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Memory statistics
|
|
744
|
+
*/
|
|
745
|
+
stats() {
|
|
746
|
+
const total = this.entries.size;
|
|
747
|
+
const locked = this.getLockedMemories().length;
|
|
748
|
+
const avgEntropy = total > 0
|
|
749
|
+
? Array.from(this.entries.values()).reduce((s, e) => s + e.entropy, 0) / total
|
|
750
|
+
: 0;
|
|
751
|
+
|
|
752
|
+
return { total, locked, avgEntropy };
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
|
|
756
|
+
// ============================================================================
|
|
757
|
+
// RESONANCE OPERATOR (PHASE ROTATION)
|
|
758
|
+
// ============================================================================
|
|
759
|
+
|
|
760
|
+
/**
|
|
761
|
+
* Resonance operator: R̂(n)|p⟩ = e^(2πi log_p(n))|p⟩
|
|
762
|
+
* Applies log-based phase rotation to all active primes
|
|
763
|
+
*/
|
|
764
|
+
function applyResonanceOperator(state, n) {
|
|
765
|
+
const result = new SparsePrimeState(state.allPrimes.length, state.k);
|
|
766
|
+
|
|
767
|
+
for (const [p, act] of state.activations) {
|
|
768
|
+
const logPhase = 2 * Math.PI * Math.log(n) / Math.log(p);
|
|
769
|
+
const rotation = Complex.fromPolar(1, logPhase);
|
|
770
|
+
const newAmp = act.amplitude.mul(rotation);
|
|
771
|
+
result.set(p, newAmp, act.quaternion);
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
return result;
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
module.exports = {
|
|
778
|
+
// Quaternion
|
|
779
|
+
Quaternion,
|
|
780
|
+
|
|
781
|
+
// Sparse Prime State
|
|
782
|
+
SparsePrimeState,
|
|
783
|
+
|
|
784
|
+
// Attention
|
|
785
|
+
resonanceScore,
|
|
786
|
+
resonantAttention,
|
|
787
|
+
|
|
788
|
+
// Composition
|
|
789
|
+
hamiltonCompose,
|
|
790
|
+
measureNonCommutativity,
|
|
791
|
+
|
|
792
|
+
// Halting
|
|
793
|
+
computeCoherence,
|
|
794
|
+
haltingDecision,
|
|
795
|
+
coherenceGatedCompute,
|
|
796
|
+
|
|
797
|
+
// Collapse
|
|
798
|
+
EntropyCollapseHead,
|
|
799
|
+
generateAttractorCodebook,
|
|
800
|
+
|
|
801
|
+
// Memory
|
|
802
|
+
PRGraphMemory,
|
|
803
|
+
|
|
804
|
+
// Operators
|
|
805
|
+
applyResonanceOperator
|
|
806
|
+
};
|