@aleph-ai/tinyaleph 1.5.6 → 1.6.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/core/alexander-module.js +1469 -0
- package/core/arithmetic-link-kernel.js +1338 -0
- package/core/index.js +95 -2
- package/examples/01-hello-world.js +69 -0
- package/examples/02-basic-hash.js +90 -0
- package/examples/02-observer-stack.js +385 -0
- package/examples/03-quantum-coin.js +136 -0
- package/examples/05-symbolic-resonance.js +146 -0
- package/examples/06-symbol-database.js +150 -0
- package/examples/07-semantic-inference.js +223 -0
- package/examples/08-compound-symbols.js +219 -0
- package/examples/README.md +170 -0
- package/examples/ai/01-embeddings.js +155 -0
- package/examples/ai/02-semantic-memory.js +243 -0
- package/examples/ai/03-reasoning.js +243 -0
- package/examples/ai/04-knowledge-graph.js +279 -0
- package/examples/ai/05-llm-integration.js +333 -0
- package/examples/ai/06-agent.js +294 -0
- package/examples/ai/07-hybrid-ai.js +223 -0
- package/examples/ai/08-entropy-reasoning.js +259 -0
- package/examples/ai/09-concept-learning.js +271 -0
- package/examples/ai/10-prompt-primes.js +312 -0
- package/examples/ai/11-rag.js +332 -0
- package/examples/ai/12-neuro-symbolic.js +321 -0
- package/examples/ai/README.md +80 -0
- package/examples/arithmetic-topology/01-legendre-symbol.js +78 -0
- package/examples/arithmetic-topology/02-redei-symbol.js +126 -0
- package/examples/arithmetic-topology/03-alk-kuramoto.js +138 -0
- package/examples/arithmetic-topology/04-alexander-module.js +117 -0
- package/examples/arithmetic-topology/05-signature-memory.js +118 -0
- package/examples/arithmetic-topology/README.md +291 -0
- package/examples/bioinformatics/01-dna-encoding.js +108 -0
- package/examples/bioinformatics/02-central-dogma.js +162 -0
- package/examples/bioinformatics/03-protein-folding.js +206 -0
- package/examples/bioinformatics/04-dna-computing.js +192 -0
- package/examples/bioinformatics/05-molecular-binding.js +209 -0
- package/examples/chat.js +105 -0
- package/examples/crt-homology/01-residue-encoding.js +87 -0
- package/examples/crt-homology/02-birkhoff-attention.js +100 -0
- package/examples/crt-homology/03-homology-loss.js +132 -0
- package/examples/crt-homology/04-crt-resoformer.js +132 -0
- package/examples/crt-homology/README.md +67 -0
- package/examples/crypto/01-password-hash.js +210 -0
- package/examples/crypto/02-key-derivation.js +210 -0
- package/examples/crypto/03-hmac.js +229 -0
- package/examples/crypto/04-file-integrity.js +263 -0
- package/examples/crypto/05-content-hash.js +263 -0
- package/examples/crypto/README.md +99 -0
- package/examples/demo-modular.js +223 -0
- package/examples/demo-two-layer.js +196 -0
- package/examples/discrete/01-integer-sine-table.js +120 -0
- package/examples/discrete/02-codebook-tunneling.js +118 -0
- package/examples/discrete/03-canonical-fusion.js +135 -0
- package/examples/discrete/04-tick-gate.js +139 -0
- package/examples/discrete/README.md +142 -0
- package/examples/formal-semantics/01-typed-terms.js +156 -0
- package/examples/formal-semantics/02-reduction.js +202 -0
- package/examples/formal-semantics/03-lambda-translation.js +206 -0
- package/examples/formal-semantics/04-enochian-language.js +257 -0
- package/examples/formal-semantics/README.md +98 -0
- package/examples/math/01-quaternions.js +237 -0
- package/examples/math/02-octonions.js +192 -0
- package/examples/math/03-prime-factorization.js +215 -0
- package/examples/math/04-vector-spaces.js +210 -0
- package/examples/math/05-gaussian-primes.js +234 -0
- package/examples/math/README.md +93 -0
- package/examples/physics/01-oscillator.js +177 -0
- package/examples/physics/02-lyapunov.js +201 -0
- package/examples/physics/03-collapse.js +183 -0
- package/examples/physics/04-kuramoto.js +212 -0
- package/examples/physics/05-entropy.js +226 -0
- package/examples/physics/05-sync-models.js +298 -0
- package/examples/physics/06-primeon-ladder.js +233 -0
- package/examples/physics/07-kuramoto-coupled-ladder.js +298 -0
- package/examples/physics/README.md +126 -0
- package/examples/resonance/01-prime-hilbert-space.js +140 -0
- package/examples/resonance/02-prime-resonance-network.js +221 -0
- package/examples/resonance/03-resoformer.js +349 -0
- package/examples/resonance/04-resoformer-training.js +329 -0
- package/examples/resonance/05-language-model.js +484 -0
- package/examples/resonance/README.md +238 -0
- package/examples/run-examples.js +417 -0
- package/examples/scientific/01-single-qubit.js +185 -0
- package/examples/scientific/02-two-qubit.js +209 -0
- package/examples/scientific/03-quantum-circuits.js +270 -0
- package/examples/scientific/04-measurement.js +229 -0
- package/examples/scientific/05-algorithms.js +245 -0
- package/examples/scientific/06-random.js +225 -0
- package/examples/scientific/07-wavefunction.js +192 -0
- package/examples/scientific/README.md +118 -0
- package/examples/semantic/01-vocabulary.js +186 -0
- package/examples/semantic/02-similarity.js +263 -0
- package/examples/semantic/03-word-algebra.js +295 -0
- package/examples/semantic/04-clustering.js +348 -0
- package/examples/semantic/05-classification.js +386 -0
- package/examples/semantic/06-dna-encoding.js +228 -0
- package/examples/semantic/07-search.js +304 -0
- package/examples/semantic/08-qa-system.js +278 -0
- package/examples/semantic/README.md +116 -0
- package/examples/topology/01-108-invariant.js +81 -0
- package/examples/topology/02-trefoil-constants.js +112 -0
- package/examples/topology/03-gauge-symmetry.js +112 -0
- package/examples/topology/04-free-energy-dynamics.js +124 -0
- package/examples/topology/README.md +129 -0
- package/index.js +32 -0
- package/modular.js +63 -2
- package/observer/agency.js +885 -0
- package/observer/assays.js +973 -0
- package/observer/boundary.js +1155 -0
- package/observer/entanglement.js +673 -0
- package/observer/hqe.js +1465 -0
- package/observer/index.js +158 -0
- package/observer/prsc.js +1289 -0
- package/observer/safety.js +815 -0
- package/observer/smf.js +1015 -0
- package/observer/symbolic-smf.js +726 -0
- package/observer/symbolic-temporal.js +790 -0
- package/observer/temporal.js +669 -0
- package/package.json +9 -3
- package/physics/alk-kuramoto.js +817 -0
- package/physics/index.js +23 -2
|
@@ -0,0 +1,673 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Entanglement Layer
|
|
3
|
+
*
|
|
4
|
+
* Implements semantic entanglement from "A Design for a Sentient Observer"
|
|
5
|
+
* paper, Section 4.3 and equations 16-17.
|
|
6
|
+
*
|
|
7
|
+
* Key features:
|
|
8
|
+
* - Phrase segmentation via coherence peaks and energy troughs
|
|
9
|
+
* - Intra-phrase entanglement detection
|
|
10
|
+
* - Entanglement graph building and traversal
|
|
11
|
+
* - Persistent conceptual bindings
|
|
12
|
+
* - Associative recall via entanglement chains
|
|
13
|
+
*
|
|
14
|
+
* @module observer/entanglement
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Entangled Pair - Two primes with strong correlation
|
|
19
|
+
*/
|
|
20
|
+
class EntangledPair {
|
|
21
|
+
constructor(data = {}) {
|
|
22
|
+
this.prime1 = data.prime1;
|
|
23
|
+
this.prime2 = data.prime2;
|
|
24
|
+
this.strength = data.strength || 0;
|
|
25
|
+
this.phaseDiff = data.phaseDiff || 0;
|
|
26
|
+
this.formationTime = data.formationTime || Date.now();
|
|
27
|
+
this.accessCount = data.accessCount || 0;
|
|
28
|
+
this.context = data.context || null;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Get pair as sorted tuple
|
|
33
|
+
*/
|
|
34
|
+
get tuple() {
|
|
35
|
+
return this.prime1 < this.prime2
|
|
36
|
+
? [this.prime1, this.prime2]
|
|
37
|
+
: [this.prime2, this.prime1];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Get unique key for this pair
|
|
42
|
+
*/
|
|
43
|
+
get key() {
|
|
44
|
+
const [a, b] = this.tuple;
|
|
45
|
+
return `${a}:${b}`;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Check if this pair contains a prime
|
|
50
|
+
*/
|
|
51
|
+
contains(prime) {
|
|
52
|
+
return this.prime1 === prime || this.prime2 === prime;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get the other prime in the pair
|
|
57
|
+
*/
|
|
58
|
+
other(prime) {
|
|
59
|
+
if (this.prime1 === prime) return this.prime2;
|
|
60
|
+
if (this.prime2 === prime) return this.prime1;
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
toJSON() {
|
|
65
|
+
return {
|
|
66
|
+
prime1: this.prime1,
|
|
67
|
+
prime2: this.prime2,
|
|
68
|
+
strength: this.strength,
|
|
69
|
+
phaseDiff: this.phaseDiff,
|
|
70
|
+
formationTime: this.formationTime,
|
|
71
|
+
accessCount: this.accessCount,
|
|
72
|
+
context: this.context
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
static fromJSON(data) {
|
|
77
|
+
return new EntangledPair(data);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Phrase - A bounded segment of experience
|
|
83
|
+
*
|
|
84
|
+
* Phrases are delimited by coherence peaks or energy troughs,
|
|
85
|
+
* representing coherent units of meaning.
|
|
86
|
+
*/
|
|
87
|
+
class Phrase {
|
|
88
|
+
constructor(data = {}) {
|
|
89
|
+
this.id = data.id || Phrase.generateId();
|
|
90
|
+
this.startTime = data.startTime || Date.now();
|
|
91
|
+
this.endTime = data.endTime || null;
|
|
92
|
+
this.primes = data.primes || [];
|
|
93
|
+
this.entangledPairs = data.entangledPairs || [];
|
|
94
|
+
this.coherencePeak = data.coherencePeak || 0;
|
|
95
|
+
this.energyAtEnd = data.energyAtEnd || 0;
|
|
96
|
+
this.momentIds = data.momentIds || [];
|
|
97
|
+
this.semanticContent = data.semanticContent || null;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
static generateId() {
|
|
101
|
+
return `ph_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Duration in milliseconds
|
|
106
|
+
*/
|
|
107
|
+
get duration() {
|
|
108
|
+
if (!this.endTime) return Date.now() - this.startTime;
|
|
109
|
+
return this.endTime - this.startTime;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Close this phrase
|
|
114
|
+
*/
|
|
115
|
+
close(energyAtEnd = 0) {
|
|
116
|
+
this.endTime = Date.now();
|
|
117
|
+
this.energyAtEnd = energyAtEnd;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Add a prime to this phrase
|
|
122
|
+
*/
|
|
123
|
+
addPrime(prime) {
|
|
124
|
+
if (!this.primes.includes(prime)) {
|
|
125
|
+
this.primes.push(prime);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Add an entangled pair
|
|
131
|
+
*/
|
|
132
|
+
addEntanglement(pair) {
|
|
133
|
+
this.entangledPairs.push(pair);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
toJSON() {
|
|
137
|
+
return {
|
|
138
|
+
id: this.id,
|
|
139
|
+
startTime: this.startTime,
|
|
140
|
+
endTime: this.endTime,
|
|
141
|
+
primes: this.primes,
|
|
142
|
+
entangledPairs: this.entangledPairs.map(p => p.toJSON()),
|
|
143
|
+
coherencePeak: this.coherencePeak,
|
|
144
|
+
energyAtEnd: this.energyAtEnd,
|
|
145
|
+
momentIds: this.momentIds,
|
|
146
|
+
semanticContent: this.semanticContent
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
static fromJSON(data) {
|
|
151
|
+
const phrase = new Phrase(data);
|
|
152
|
+
phrase.entangledPairs = (data.entangledPairs || []).map(p => EntangledPair.fromJSON(p));
|
|
153
|
+
return phrase;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Entanglement Layer
|
|
159
|
+
*
|
|
160
|
+
* Manages semantic entanglement, phrase segmentation, and
|
|
161
|
+
* associative bindings between primes.
|
|
162
|
+
*/
|
|
163
|
+
class EntanglementLayer {
|
|
164
|
+
/**
|
|
165
|
+
* Create an entanglement layer
|
|
166
|
+
* @param {Object} options - Configuration
|
|
167
|
+
*/
|
|
168
|
+
constructor(options = {}) {
|
|
169
|
+
// Thresholds (equation 17)
|
|
170
|
+
this.entanglementThreshold = options.entanglementThreshold || 0.7;
|
|
171
|
+
this.coherencePeakThreshold = options.coherencePeakThreshold || 0.75;
|
|
172
|
+
this.energyTroughThreshold = options.energyTroughThreshold || 0.15;
|
|
173
|
+
|
|
174
|
+
// Decay parameters
|
|
175
|
+
this.strengthDecay = options.strengthDecay || 0.01;
|
|
176
|
+
this.minStrength = options.minStrength || 0.1;
|
|
177
|
+
|
|
178
|
+
// Current phrase
|
|
179
|
+
this.currentPhrase = null;
|
|
180
|
+
this.phrases = [];
|
|
181
|
+
|
|
182
|
+
// Persistent entanglement graph
|
|
183
|
+
// Map from prime -> Map of (otherPrime -> EntangledPair)
|
|
184
|
+
this.entanglementGraph = new Map();
|
|
185
|
+
|
|
186
|
+
// History for phrase segmentation
|
|
187
|
+
this.coherenceHistory = [];
|
|
188
|
+
this.energyHistory = [];
|
|
189
|
+
this.maxHistory = options.maxHistory || 100;
|
|
190
|
+
|
|
191
|
+
// Callbacks
|
|
192
|
+
this.onPhraseComplete = options.onPhraseComplete || null;
|
|
193
|
+
this.onEntanglement = options.onEntanglement || null;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* Update entanglement layer with current oscillator state
|
|
198
|
+
* @param {Object} state - Current state
|
|
199
|
+
* @param {Array} state.oscillators - Array of oscillator objects
|
|
200
|
+
* @param {number} state.coherence - Global coherence
|
|
201
|
+
* @param {number} state.energy - Total energy
|
|
202
|
+
* @param {Object} state.semanticContent - Current semantic content
|
|
203
|
+
*/
|
|
204
|
+
update(state) {
|
|
205
|
+
const { oscillators, coherence, energy, semanticContent } = state;
|
|
206
|
+
|
|
207
|
+
// Update histories
|
|
208
|
+
this.coherenceHistory.push(coherence);
|
|
209
|
+
this.energyHistory.push(energy);
|
|
210
|
+
|
|
211
|
+
if (this.coherenceHistory.length > this.maxHistory) {
|
|
212
|
+
this.coherenceHistory.shift();
|
|
213
|
+
}
|
|
214
|
+
if (this.energyHistory.length > this.maxHistory) {
|
|
215
|
+
this.energyHistory.shift();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Check for phrase boundaries
|
|
219
|
+
const isPeak = this.isCoherencePeak(coherence);
|
|
220
|
+
const isTrough = this.isEnergyTrough(energy);
|
|
221
|
+
|
|
222
|
+
if ((isPeak || isTrough) && this.currentPhrase) {
|
|
223
|
+
// End current phrase
|
|
224
|
+
this.endPhrase(energy, semanticContent);
|
|
225
|
+
|
|
226
|
+
// Start new phrase if coherence peak (continuing flow)
|
|
227
|
+
if (isPeak) {
|
|
228
|
+
this.startPhrase(coherence);
|
|
229
|
+
}
|
|
230
|
+
} else if (!this.currentPhrase && oscillators && oscillators.length > 0) {
|
|
231
|
+
// Start first phrase
|
|
232
|
+
this.startPhrase(coherence);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Detect new entanglements
|
|
236
|
+
if (oscillators && this.currentPhrase) {
|
|
237
|
+
const newPairs = this.detectEntanglements(oscillators);
|
|
238
|
+
|
|
239
|
+
for (const pair of newPairs) {
|
|
240
|
+
this.registerEntanglement(pair);
|
|
241
|
+
this.currentPhrase.addEntanglement(pair);
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Add active primes to current phrase
|
|
245
|
+
for (const osc of oscillators) {
|
|
246
|
+
if (osc.amplitude > 0.1) {
|
|
247
|
+
this.currentPhrase.addPrime(osc.prime);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
// Decay old entanglements
|
|
253
|
+
this.decayEntanglements();
|
|
254
|
+
|
|
255
|
+
return {
|
|
256
|
+
currentPhrase: this.currentPhrase,
|
|
257
|
+
newPairs: this.currentPhrase ? this.currentPhrase.entangledPairs.slice(-5) : []
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
/**
|
|
262
|
+
* Start a new phrase
|
|
263
|
+
* @param {number} coherence - Initial coherence
|
|
264
|
+
*/
|
|
265
|
+
startPhrase(coherence) {
|
|
266
|
+
this.currentPhrase = new Phrase({
|
|
267
|
+
coherencePeak: coherence
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
/**
|
|
272
|
+
* End current phrase
|
|
273
|
+
* @param {number} energy - Ending energy
|
|
274
|
+
* @param {Object} semanticContent - Semantic content
|
|
275
|
+
*/
|
|
276
|
+
endPhrase(energy, semanticContent = null) {
|
|
277
|
+
if (!this.currentPhrase) return null;
|
|
278
|
+
|
|
279
|
+
this.currentPhrase.close(energy);
|
|
280
|
+
this.currentPhrase.semanticContent = semanticContent;
|
|
281
|
+
|
|
282
|
+
this.phrases.push(this.currentPhrase);
|
|
283
|
+
|
|
284
|
+
if (this.onPhraseComplete) {
|
|
285
|
+
this.onPhraseComplete(this.currentPhrase);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
const completed = this.currentPhrase;
|
|
289
|
+
this.currentPhrase = null;
|
|
290
|
+
|
|
291
|
+
return completed;
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
/**
|
|
295
|
+
* Check if coherence is a local peak
|
|
296
|
+
*/
|
|
297
|
+
isCoherencePeak(coherence) {
|
|
298
|
+
if (coherence < this.coherencePeakThreshold) return false;
|
|
299
|
+
if (this.coherenceHistory.length < 3) return false;
|
|
300
|
+
|
|
301
|
+
const h = this.coherenceHistory;
|
|
302
|
+
const n = h.length;
|
|
303
|
+
|
|
304
|
+
// Check if current is higher than recent values
|
|
305
|
+
for (let i = Math.max(0, n - 5); i < n - 1; i++) {
|
|
306
|
+
if (h[i] >= coherence) return false;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
return true;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/**
|
|
313
|
+
* Check if energy is at a local trough
|
|
314
|
+
*/
|
|
315
|
+
isEnergyTrough(energy) {
|
|
316
|
+
return energy < this.energyTroughThreshold;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Detect entanglements between oscillators (equation 16-17)
|
|
321
|
+
* @param {Array} oscillators - Array of oscillators
|
|
322
|
+
*/
|
|
323
|
+
detectEntanglements(oscillators) {
|
|
324
|
+
const pairs = [];
|
|
325
|
+
|
|
326
|
+
for (let i = 0; i < oscillators.length; i++) {
|
|
327
|
+
for (let j = i + 1; j < oscillators.length; j++) {
|
|
328
|
+
const osc1 = oscillators[i];
|
|
329
|
+
const osc2 = oscillators[j];
|
|
330
|
+
|
|
331
|
+
// Both must be active
|
|
332
|
+
if (osc1.amplitude < 0.1 || osc2.amplitude < 0.1) continue;
|
|
333
|
+
|
|
334
|
+
// Compute entanglement strength (equation 17)
|
|
335
|
+
const strength = this.computeStrength(osc1, osc2);
|
|
336
|
+
|
|
337
|
+
if (strength > this.entanglementThreshold) {
|
|
338
|
+
pairs.push(new EntangledPair({
|
|
339
|
+
prime1: osc1.prime,
|
|
340
|
+
prime2: osc2.prime,
|
|
341
|
+
strength,
|
|
342
|
+
phaseDiff: Math.abs(osc1.phase - osc2.phase)
|
|
343
|
+
}));
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
return pairs;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Compute entanglement strength (equation 17)
|
|
353
|
+
* strength(i,j) = ρφ * ρA
|
|
354
|
+
* where ρφ = cos(Δφ) and ρA = min(Ai,Aj) / max(Ai,Aj)
|
|
355
|
+
*/
|
|
356
|
+
computeStrength(osc1, osc2) {
|
|
357
|
+
// Phase correlation
|
|
358
|
+
const deltaPhi = Math.abs(osc1.phase - osc2.phase);
|
|
359
|
+
const rhoPhase = Math.cos(deltaPhi);
|
|
360
|
+
|
|
361
|
+
// Amplitude correlation
|
|
362
|
+
const minA = Math.min(osc1.amplitude, osc2.amplitude);
|
|
363
|
+
const maxA = Math.max(osc1.amplitude, osc2.amplitude);
|
|
364
|
+
const rhoAmplitude = minA / (maxA + 1e-10);
|
|
365
|
+
|
|
366
|
+
return Math.max(0, rhoPhase * rhoAmplitude);
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
/**
|
|
370
|
+
* Register an entanglement in the persistent graph
|
|
371
|
+
*/
|
|
372
|
+
registerEntanglement(pair) {
|
|
373
|
+
// Ensure both primes have entries
|
|
374
|
+
if (!this.entanglementGraph.has(pair.prime1)) {
|
|
375
|
+
this.entanglementGraph.set(pair.prime1, new Map());
|
|
376
|
+
}
|
|
377
|
+
if (!this.entanglementGraph.has(pair.prime2)) {
|
|
378
|
+
this.entanglementGraph.set(pair.prime2, new Map());
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const existing1 = this.entanglementGraph.get(pair.prime1).get(pair.prime2);
|
|
382
|
+
const existing2 = this.entanglementGraph.get(pair.prime2).get(pair.prime1);
|
|
383
|
+
|
|
384
|
+
if (existing1) {
|
|
385
|
+
// Strengthen existing entanglement
|
|
386
|
+
existing1.strength = Math.min(1.0, existing1.strength + pair.strength * 0.1);
|
|
387
|
+
existing1.accessCount++;
|
|
388
|
+
existing2.strength = existing1.strength;
|
|
389
|
+
existing2.accessCount = existing1.accessCount;
|
|
390
|
+
} else {
|
|
391
|
+
// Create new entanglement
|
|
392
|
+
this.entanglementGraph.get(pair.prime1).set(pair.prime2, pair);
|
|
393
|
+
|
|
394
|
+
// Create symmetric entry
|
|
395
|
+
const reversePair = new EntangledPair({
|
|
396
|
+
prime1: pair.prime2,
|
|
397
|
+
prime2: pair.prime1,
|
|
398
|
+
strength: pair.strength,
|
|
399
|
+
phaseDiff: pair.phaseDiff,
|
|
400
|
+
formationTime: pair.formationTime
|
|
401
|
+
});
|
|
402
|
+
this.entanglementGraph.get(pair.prime2).set(pair.prime1, reversePair);
|
|
403
|
+
|
|
404
|
+
if (this.onEntanglement) {
|
|
405
|
+
this.onEntanglement(pair);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* Decay old entanglements
|
|
412
|
+
*/
|
|
413
|
+
decayEntanglements() {
|
|
414
|
+
for (const [prime, neighbors] of this.entanglementGraph) {
|
|
415
|
+
const toRemove = [];
|
|
416
|
+
|
|
417
|
+
for (const [otherPrime, pair] of neighbors) {
|
|
418
|
+
pair.strength *= (1 - this.strengthDecay);
|
|
419
|
+
|
|
420
|
+
if (pair.strength < this.minStrength) {
|
|
421
|
+
toRemove.push(otherPrime);
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
for (const other of toRemove) {
|
|
426
|
+
neighbors.delete(other);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Get all primes entangled with a given prime
|
|
433
|
+
*/
|
|
434
|
+
getEntangled(prime) {
|
|
435
|
+
const neighbors = this.entanglementGraph.get(prime);
|
|
436
|
+
if (!neighbors) return [];
|
|
437
|
+
|
|
438
|
+
return Array.from(neighbors.values())
|
|
439
|
+
.sort((a, b) => b.strength - a.strength);
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Find entanglement chain from source to target
|
|
444
|
+
* Uses BFS to find shortest path
|
|
445
|
+
*/
|
|
446
|
+
findChain(sourcePrime, targetPrime, maxDepth = 5) {
|
|
447
|
+
if (sourcePrime === targetPrime) return [sourcePrime];
|
|
448
|
+
|
|
449
|
+
const queue = [[sourcePrime]];
|
|
450
|
+
const visited = new Set([sourcePrime]);
|
|
451
|
+
|
|
452
|
+
while (queue.length > 0) {
|
|
453
|
+
const path = queue.shift();
|
|
454
|
+
if (path.length > maxDepth) continue;
|
|
455
|
+
|
|
456
|
+
const current = path[path.length - 1];
|
|
457
|
+
const neighbors = this.entanglementGraph.get(current);
|
|
458
|
+
|
|
459
|
+
if (!neighbors) continue;
|
|
460
|
+
|
|
461
|
+
for (const [neighbor, pair] of neighbors) {
|
|
462
|
+
if (neighbor === targetPrime) {
|
|
463
|
+
return [...path, neighbor];
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
if (!visited.has(neighbor)) {
|
|
467
|
+
visited.add(neighbor);
|
|
468
|
+
queue.push([...path, neighbor]);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
return null; // No path found
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
/**
|
|
477
|
+
* Get strongly connected cluster around a prime
|
|
478
|
+
*/
|
|
479
|
+
getCluster(prime, minStrength = 0.3) {
|
|
480
|
+
const cluster = new Set([prime]);
|
|
481
|
+
const queue = [prime];
|
|
482
|
+
|
|
483
|
+
while (queue.length > 0) {
|
|
484
|
+
const current = queue.shift();
|
|
485
|
+
const neighbors = this.entanglementGraph.get(current);
|
|
486
|
+
|
|
487
|
+
if (!neighbors) continue;
|
|
488
|
+
|
|
489
|
+
for (const [neighbor, pair] of neighbors) {
|
|
490
|
+
if (!cluster.has(neighbor) && pair.strength >= minStrength) {
|
|
491
|
+
cluster.add(neighbor);
|
|
492
|
+
queue.push(neighbor);
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
return Array.from(cluster);
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
/**
|
|
501
|
+
* Get the most strongly entangled prime
|
|
502
|
+
*/
|
|
503
|
+
getMostEntangled() {
|
|
504
|
+
let maxPrime = null;
|
|
505
|
+
let maxTotal = 0;
|
|
506
|
+
|
|
507
|
+
for (const [prime, neighbors] of this.entanglementGraph) {
|
|
508
|
+
let total = 0;
|
|
509
|
+
for (const pair of neighbors.values()) {
|
|
510
|
+
total += pair.strength;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
if (total > maxTotal) {
|
|
514
|
+
maxTotal = total;
|
|
515
|
+
maxPrime = prime;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
return { prime: maxPrime, totalStrength: maxTotal };
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* Trigger associative recall from a cue
|
|
524
|
+
*/
|
|
525
|
+
associativeRecall(cuePrimes, depth = 2) {
|
|
526
|
+
const recalled = new Map();
|
|
527
|
+
let frontier = new Set(cuePrimes);
|
|
528
|
+
|
|
529
|
+
for (let d = 0; d < depth; d++) {
|
|
530
|
+
const newFrontier = new Set();
|
|
531
|
+
|
|
532
|
+
for (const prime of frontier) {
|
|
533
|
+
const neighbors = this.entanglementGraph.get(prime);
|
|
534
|
+
if (!neighbors) continue;
|
|
535
|
+
|
|
536
|
+
for (const [neighbor, pair] of neighbors) {
|
|
537
|
+
if (!cuePrimes.includes(neighbor)) {
|
|
538
|
+
const currentStrength = recalled.get(neighbor) || 0;
|
|
539
|
+
// Decay by depth
|
|
540
|
+
const addedStrength = pair.strength * Math.pow(0.7, d);
|
|
541
|
+
recalled.set(neighbor, currentStrength + addedStrength);
|
|
542
|
+
newFrontier.add(neighbor);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
frontier = newFrontier;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
return Array.from(recalled.entries())
|
|
551
|
+
.sort((a, b) => b[1] - a[1])
|
|
552
|
+
.map(([prime, strength]) => ({ prime, strength }));
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
/**
|
|
556
|
+
* Get statistics about the entanglement graph
|
|
557
|
+
*/
|
|
558
|
+
getStats() {
|
|
559
|
+
let totalPairs = 0;
|
|
560
|
+
let totalStrength = 0;
|
|
561
|
+
let maxDegree = 0;
|
|
562
|
+
|
|
563
|
+
for (const neighbors of this.entanglementGraph.values()) {
|
|
564
|
+
const degree = neighbors.size;
|
|
565
|
+
if (degree > maxDegree) maxDegree = degree;
|
|
566
|
+
|
|
567
|
+
for (const pair of neighbors.values()) {
|
|
568
|
+
totalPairs++;
|
|
569
|
+
totalStrength += pair.strength;
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// Each pair is counted twice (symmetric)
|
|
574
|
+
totalPairs = Math.floor(totalPairs / 2);
|
|
575
|
+
|
|
576
|
+
return {
|
|
577
|
+
nodeCount: this.entanglementGraph.size,
|
|
578
|
+
edgeCount: totalPairs,
|
|
579
|
+
averageStrength: totalPairs > 0 ? totalStrength / (totalPairs * 2) : 0,
|
|
580
|
+
maxDegree,
|
|
581
|
+
phraseCount: this.phrases.length,
|
|
582
|
+
currentPhraseActive: this.currentPhrase !== null
|
|
583
|
+
};
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* Get recent phrases
|
|
588
|
+
*/
|
|
589
|
+
recentPhrases(count = 10) {
|
|
590
|
+
return this.phrases.slice(-count);
|
|
591
|
+
}
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Clear all entanglements and phrases
|
|
595
|
+
*/
|
|
596
|
+
reset() {
|
|
597
|
+
this.entanglementGraph.clear();
|
|
598
|
+
this.phrases = [];
|
|
599
|
+
this.currentPhrase = null;
|
|
600
|
+
this.coherenceHistory = [];
|
|
601
|
+
this.energyHistory = [];
|
|
602
|
+
}
|
|
603
|
+
|
|
604
|
+
/**
|
|
605
|
+
* Serialize to JSON
|
|
606
|
+
*/
|
|
607
|
+
toJSON() {
|
|
608
|
+
// Convert entanglement graph to serializable form
|
|
609
|
+
const graphData = [];
|
|
610
|
+
const seen = new Set();
|
|
611
|
+
|
|
612
|
+
for (const [prime, neighbors] of this.entanglementGraph) {
|
|
613
|
+
for (const [otherPrime, pair] of neighbors) {
|
|
614
|
+
const key = pair.key;
|
|
615
|
+
if (!seen.has(key)) {
|
|
616
|
+
seen.add(key);
|
|
617
|
+
graphData.push(pair.toJSON());
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
return {
|
|
623
|
+
entanglements: graphData,
|
|
624
|
+
phrases: this.phrases.map(p => p.toJSON()),
|
|
625
|
+
currentPhrase: this.currentPhrase ? this.currentPhrase.toJSON() : null,
|
|
626
|
+
config: {
|
|
627
|
+
entanglementThreshold: this.entanglementThreshold,
|
|
628
|
+
coherencePeakThreshold: this.coherencePeakThreshold,
|
|
629
|
+
energyTroughThreshold: this.energyTroughThreshold
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/**
|
|
635
|
+
* Load from JSON
|
|
636
|
+
*/
|
|
637
|
+
loadFromJSON(data) {
|
|
638
|
+
this.reset();
|
|
639
|
+
|
|
640
|
+
// Restore entanglements
|
|
641
|
+
if (data.entanglements) {
|
|
642
|
+
for (const pairData of data.entanglements) {
|
|
643
|
+
const pair = EntangledPair.fromJSON(pairData);
|
|
644
|
+
this.registerEntanglement(pair);
|
|
645
|
+
}
|
|
646
|
+
}
|
|
647
|
+
|
|
648
|
+
// Restore phrases
|
|
649
|
+
if (data.phrases) {
|
|
650
|
+
this.phrases = data.phrases.map(p => Phrase.fromJSON(p));
|
|
651
|
+
}
|
|
652
|
+
|
|
653
|
+
if (data.currentPhrase) {
|
|
654
|
+
this.currentPhrase = Phrase.fromJSON(data.currentPhrase);
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
if (data.config) {
|
|
658
|
+
Object.assign(this, data.config);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
export {
|
|
664
|
+
EntangledPair,
|
|
665
|
+
Phrase,
|
|
666
|
+
EntanglementLayer
|
|
667
|
+
};
|
|
668
|
+
|
|
669
|
+
export default {
|
|
670
|
+
EntangledPair,
|
|
671
|
+
Phrase,
|
|
672
|
+
EntanglementLayer
|
|
673
|
+
};
|