@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.
Files changed (121) hide show
  1. package/core/alexander-module.js +1469 -0
  2. package/core/arithmetic-link-kernel.js +1338 -0
  3. package/core/index.js +95 -2
  4. package/examples/01-hello-world.js +69 -0
  5. package/examples/02-basic-hash.js +90 -0
  6. package/examples/02-observer-stack.js +385 -0
  7. package/examples/03-quantum-coin.js +136 -0
  8. package/examples/05-symbolic-resonance.js +146 -0
  9. package/examples/06-symbol-database.js +150 -0
  10. package/examples/07-semantic-inference.js +223 -0
  11. package/examples/08-compound-symbols.js +219 -0
  12. package/examples/README.md +170 -0
  13. package/examples/ai/01-embeddings.js +155 -0
  14. package/examples/ai/02-semantic-memory.js +243 -0
  15. package/examples/ai/03-reasoning.js +243 -0
  16. package/examples/ai/04-knowledge-graph.js +279 -0
  17. package/examples/ai/05-llm-integration.js +333 -0
  18. package/examples/ai/06-agent.js +294 -0
  19. package/examples/ai/07-hybrid-ai.js +223 -0
  20. package/examples/ai/08-entropy-reasoning.js +259 -0
  21. package/examples/ai/09-concept-learning.js +271 -0
  22. package/examples/ai/10-prompt-primes.js +312 -0
  23. package/examples/ai/11-rag.js +332 -0
  24. package/examples/ai/12-neuro-symbolic.js +321 -0
  25. package/examples/ai/README.md +80 -0
  26. package/examples/arithmetic-topology/01-legendre-symbol.js +78 -0
  27. package/examples/arithmetic-topology/02-redei-symbol.js +126 -0
  28. package/examples/arithmetic-topology/03-alk-kuramoto.js +138 -0
  29. package/examples/arithmetic-topology/04-alexander-module.js +117 -0
  30. package/examples/arithmetic-topology/05-signature-memory.js +118 -0
  31. package/examples/arithmetic-topology/README.md +291 -0
  32. package/examples/bioinformatics/01-dna-encoding.js +108 -0
  33. package/examples/bioinformatics/02-central-dogma.js +162 -0
  34. package/examples/bioinformatics/03-protein-folding.js +206 -0
  35. package/examples/bioinformatics/04-dna-computing.js +192 -0
  36. package/examples/bioinformatics/05-molecular-binding.js +209 -0
  37. package/examples/chat.js +105 -0
  38. package/examples/crt-homology/01-residue-encoding.js +87 -0
  39. package/examples/crt-homology/02-birkhoff-attention.js +100 -0
  40. package/examples/crt-homology/03-homology-loss.js +132 -0
  41. package/examples/crt-homology/04-crt-resoformer.js +132 -0
  42. package/examples/crt-homology/README.md +67 -0
  43. package/examples/crypto/01-password-hash.js +210 -0
  44. package/examples/crypto/02-key-derivation.js +210 -0
  45. package/examples/crypto/03-hmac.js +229 -0
  46. package/examples/crypto/04-file-integrity.js +263 -0
  47. package/examples/crypto/05-content-hash.js +263 -0
  48. package/examples/crypto/README.md +99 -0
  49. package/examples/demo-modular.js +223 -0
  50. package/examples/demo-two-layer.js +196 -0
  51. package/examples/discrete/01-integer-sine-table.js +120 -0
  52. package/examples/discrete/02-codebook-tunneling.js +118 -0
  53. package/examples/discrete/03-canonical-fusion.js +135 -0
  54. package/examples/discrete/04-tick-gate.js +139 -0
  55. package/examples/discrete/README.md +142 -0
  56. package/examples/formal-semantics/01-typed-terms.js +156 -0
  57. package/examples/formal-semantics/02-reduction.js +202 -0
  58. package/examples/formal-semantics/03-lambda-translation.js +206 -0
  59. package/examples/formal-semantics/04-enochian-language.js +257 -0
  60. package/examples/formal-semantics/README.md +98 -0
  61. package/examples/math/01-quaternions.js +237 -0
  62. package/examples/math/02-octonions.js +192 -0
  63. package/examples/math/03-prime-factorization.js +215 -0
  64. package/examples/math/04-vector-spaces.js +210 -0
  65. package/examples/math/05-gaussian-primes.js +234 -0
  66. package/examples/math/README.md +93 -0
  67. package/examples/physics/01-oscillator.js +177 -0
  68. package/examples/physics/02-lyapunov.js +201 -0
  69. package/examples/physics/03-collapse.js +183 -0
  70. package/examples/physics/04-kuramoto.js +212 -0
  71. package/examples/physics/05-entropy.js +226 -0
  72. package/examples/physics/05-sync-models.js +298 -0
  73. package/examples/physics/06-primeon-ladder.js +233 -0
  74. package/examples/physics/07-kuramoto-coupled-ladder.js +298 -0
  75. package/examples/physics/README.md +126 -0
  76. package/examples/resonance/01-prime-hilbert-space.js +140 -0
  77. package/examples/resonance/02-prime-resonance-network.js +221 -0
  78. package/examples/resonance/03-resoformer.js +349 -0
  79. package/examples/resonance/04-resoformer-training.js +329 -0
  80. package/examples/resonance/05-language-model.js +484 -0
  81. package/examples/resonance/README.md +238 -0
  82. package/examples/run-examples.js +417 -0
  83. package/examples/scientific/01-single-qubit.js +185 -0
  84. package/examples/scientific/02-two-qubit.js +209 -0
  85. package/examples/scientific/03-quantum-circuits.js +270 -0
  86. package/examples/scientific/04-measurement.js +229 -0
  87. package/examples/scientific/05-algorithms.js +245 -0
  88. package/examples/scientific/06-random.js +225 -0
  89. package/examples/scientific/07-wavefunction.js +192 -0
  90. package/examples/scientific/README.md +118 -0
  91. package/examples/semantic/01-vocabulary.js +186 -0
  92. package/examples/semantic/02-similarity.js +263 -0
  93. package/examples/semantic/03-word-algebra.js +295 -0
  94. package/examples/semantic/04-clustering.js +348 -0
  95. package/examples/semantic/05-classification.js +386 -0
  96. package/examples/semantic/06-dna-encoding.js +228 -0
  97. package/examples/semantic/07-search.js +304 -0
  98. package/examples/semantic/08-qa-system.js +278 -0
  99. package/examples/semantic/README.md +116 -0
  100. package/examples/topology/01-108-invariant.js +81 -0
  101. package/examples/topology/02-trefoil-constants.js +112 -0
  102. package/examples/topology/03-gauge-symmetry.js +112 -0
  103. package/examples/topology/04-free-energy-dynamics.js +124 -0
  104. package/examples/topology/README.md +129 -0
  105. package/index.js +32 -0
  106. package/modular.js +63 -2
  107. package/observer/agency.js +885 -0
  108. package/observer/assays.js +973 -0
  109. package/observer/boundary.js +1155 -0
  110. package/observer/entanglement.js +673 -0
  111. package/observer/hqe.js +1465 -0
  112. package/observer/index.js +158 -0
  113. package/observer/prsc.js +1289 -0
  114. package/observer/safety.js +815 -0
  115. package/observer/smf.js +1015 -0
  116. package/observer/symbolic-smf.js +726 -0
  117. package/observer/symbolic-temporal.js +790 -0
  118. package/observer/temporal.js +669 -0
  119. package/package.json +9 -3
  120. package/physics/alk-kuramoto.js +817 -0
  121. package/physics/index.js +23 -2
@@ -0,0 +1,726 @@
1
+ /**
2
+ * Symbolic SMF Layer
3
+ *
4
+ * Enhances SedenionMemoryField with tinyaleph symbolic features:
5
+ * - Symbol database integration (400+ symbols)
6
+ * - Semantic inference for grounding SMF in archetypes
7
+ * - Cultural tag mapping to SMF axes
8
+ * - Compound symbol formation from dominant axes
9
+ *
10
+ * This module connects abstract 16-dimensional SMF orientation
11
+ * to culturally-grounded archetypal symbols.
12
+ *
13
+ * @module observer/symbolic-smf
14
+ */
15
+
16
+ import { SedenionMemoryField, SMF_AXES, AXIS_INDEX } from './smf.js';
17
+ import { symbolDatabase, SymbolCategory } from '../core/symbols.js';
18
+ import { SemanticInference, EntityExtractor } from '../core/inference.js';
19
+ import { CompoundBuilder, CompoundSymbol, SymbolSequence } from '../core/compound.js';
20
+ import { ResonanceCalculator } from '../core/resonance.js';
21
+
22
+ // ═══════════════════════════════════════════════════════════════════
23
+ // SMF Axis to Symbol Category Mapping
24
+ // ═══════════════════════════════════════════════════════════════════
25
+
26
+ /**
27
+ * Maps SMF axes to symbol categories and archetypal symbols
28
+ *
29
+ * Each of the 16 SMF axes has:
30
+ * - A primary symbol category
31
+ * - A list of archetypal symbol IDs (tried in order until found)
32
+ */
33
+ const AXIS_SYMBOL_MAPPING = {
34
+ 0: { category: 'abstract', archetypes: ['unity', 'light', 'order'] }, // coherence
35
+ 1: { category: 'archetype', archetypes: ['hero', 'self', 'everyman'] }, // identity
36
+ 2: { category: 'abstract', archetypes: ['duality', 'yin_yang', 'mirror'] }, // duality
37
+ 3: { category: 'abstract', archetypes: ['structure', 'order', 'temple'] }, // structure
38
+ 4: { category: 'abstract', archetypes: ['transformation', 'change', 'wheel'] }, // change
39
+ 5: { category: 'element', archetypes: ['tree', 'life', 'flower'] }, // life
40
+ 6: { category: 'abstract', archetypes: ['harmony', 'peace', 'balance'] }, // harmony
41
+ 7: { category: 'archetype', archetypes: ['sage', 'wisdom_concept', 'guru'] }, // wisdom
42
+ 8: { category: 'abstract', archetypes: ['infinity', 'void', 'stars'] }, // infinity
43
+ 9: { category: 'abstract', archetypes: ['creation', 'genesis', 'birth'] }, // creation
44
+ 10: { category: 'abstract', archetypes: ['truth', 'light', 'sun'] }, // truth
45
+ 11: { category: 'abstract', archetypes: ['love', 'heart', 'connection'] }, // love
46
+ 12: { category: 'abstract', archetypes: ['power', 'lightning', 'thunder'] }, // power
47
+ 13: { category: 'abstract', archetypes: ['time', 'hourglass', 'wheel'] }, // time
48
+ 14: { category: 'place', archetypes: ['space', 'void', 'cosmos'] }, // space
49
+ 15: { category: 'abstract', archetypes: ['consciousness', 'eye', 'light'] } // consciousness
50
+ };
51
+
52
+ /**
53
+ * Cultural tag to SMF axis mapping
54
+ *
55
+ * Maps cultural/semantic tags from the symbol database to their
56
+ * corresponding SMF axis indices.
57
+ */
58
+ const TAG_TO_AXIS = {
59
+ // Universal tags → axis 0 (coherence)
60
+ 'universal': 0,
61
+ 'unity': 0,
62
+ 'oneness': 0,
63
+
64
+ // Identity tags → axis 1 (identity)
65
+ 'self': 1,
66
+ 'individual': 1,
67
+ 'jungian': 1,
68
+ 'archetype': 1,
69
+
70
+ // Duality tags → axis 2 (duality)
71
+ 'duality': 2,
72
+ 'opposites': 2,
73
+ 'polarity': 2,
74
+ 'eastern': 2,
75
+
76
+ // Structure tags → axis 3 (structure)
77
+ 'order': 3,
78
+ 'form': 3,
79
+ 'architecture': 3,
80
+ 'sacred_geometry': 3,
81
+
82
+ // Change tags → axis 4 (change)
83
+ 'transformation': 4,
84
+ 'alchemy': 4,
85
+ 'metamorphosis': 4,
86
+ 'cycle': 4,
87
+
88
+ // Life tags → axis 5 (life)
89
+ 'nature': 5,
90
+ 'growth': 5,
91
+ 'organic': 5,
92
+ 'vitality': 5,
93
+
94
+ // Harmony tags → axis 6 (harmony)
95
+ 'balance': 6,
96
+ 'peace': 6,
97
+ 'music': 6,
98
+ 'resonance': 6,
99
+
100
+ // Wisdom tags → axis 7 (wisdom)
101
+ 'knowledge': 7,
102
+ 'wisdom': 7,
103
+ 'insight': 7,
104
+ 'philosophy': 7,
105
+
106
+ // Infinity tags → axis 8 (infinity)
107
+ 'infinity': 8,
108
+ 'eternal': 8,
109
+ 'cosmic': 8,
110
+ 'transcendence': 8,
111
+
112
+ // Creation tags → axis 9 (creation)
113
+ 'creation': 9,
114
+ 'genesis': 9,
115
+ 'origin': 9,
116
+ 'birth': 9,
117
+
118
+ // Truth tags → axis 10 (truth)
119
+ 'truth': 10,
120
+ 'reality': 10,
121
+ 'clarity': 10,
122
+
123
+ // Love tags → axis 11 (love)
124
+ 'love': 11,
125
+ 'heart': 11,
126
+ 'connection': 11,
127
+ 'emotion': 11,
128
+
129
+ // Power tags → axis 12 (power)
130
+ 'power': 12,
131
+ 'strength': 12,
132
+ 'force': 12,
133
+ 'authority': 12,
134
+
135
+ // Time tags → axis 13 (time)
136
+ 'time': 13,
137
+ 'temporal': 13,
138
+ 'history': 13,
139
+ 'future': 13,
140
+
141
+ // Space tags → axis 14 (space)
142
+ 'space': 14,
143
+ 'place': 14,
144
+ 'location': 14,
145
+ 'realm': 14,
146
+
147
+ // Consciousness tags → axis 15 (consciousness)
148
+ 'consciousness': 15,
149
+ 'awareness': 15,
150
+ 'mind': 15,
151
+ 'spirit': 15
152
+ };
153
+
154
+ // ═══════════════════════════════════════════════════════════════════
155
+ // Symbolic SMF Enhancement Class
156
+ // ═══════════════════════════════════════════════════════════════════
157
+
158
+ /**
159
+ * SymbolicSMF extends SedenionMemoryField with symbolic grounding
160
+ *
161
+ * This class bridges the abstract 16-dimensional SMF orientation space
162
+ * with the concrete symbol database, enabling:
163
+ * - Symbol-based excitation of SMF axes
164
+ * - Grounding of SMF states in archetypal symbols
165
+ * - Compound symbol creation from current orientation
166
+ * - Symbol resonance calculations
167
+ */
168
+ class SymbolicSMF extends SedenionMemoryField {
169
+ /**
170
+ * Create a SymbolicSMF
171
+ * @param {Float64Array|Array|null} components - Initial components
172
+ * @param {Object} options - Configuration options
173
+ * @param {Object} [options.inference] - SemanticInference instance
174
+ * @param {Object} [options.compoundBuilder] - CompoundBuilder instance
175
+ * @param {Object} [options.resonanceCalc] - ResonanceCalculator instance
176
+ * @param {number} [options.maxHistory=100] - Maximum symbol history size
177
+ */
178
+ constructor(components = null, options = {}) {
179
+ super(components);
180
+
181
+ this.inference = options.inference || new SemanticInference(symbolDatabase);
182
+ this.compoundBuilder = options.compoundBuilder || new CompoundBuilder(symbolDatabase);
183
+ this.resonanceCalc = options.resonanceCalc || new ResonanceCalculator();
184
+
185
+ // Active symbols (derived from SMF state)
186
+ this.activeSymbols = [];
187
+
188
+ // Symbol activation history
189
+ this.symbolHistory = [];
190
+ this.maxHistory = options.maxHistory || 100;
191
+
192
+ // Compound representing current state
193
+ this.currentCompound = null;
194
+ }
195
+
196
+ /**
197
+ * Create from base SedenionMemoryField
198
+ * @param {SedenionMemoryField} smf - Base SMF instance
199
+ * @param {Object} options - Configuration options
200
+ * @returns {SymbolicSMF} New SymbolicSMF instance
201
+ */
202
+ static fromSMF(smf, options = {}) {
203
+ const symbolic = new SymbolicSMF(smf.s, options);
204
+ return symbolic;
205
+ }
206
+
207
+ /**
208
+ * Map cultural tag to SMF axis index
209
+ * @param {string} tag - Cultural tag
210
+ * @returns {number} Axis index or -1 if not found
211
+ */
212
+ tagToAxis(tag) {
213
+ const normalized = tag.toLowerCase().trim();
214
+ return TAG_TO_AXIS[normalized] ?? -1;
215
+ }
216
+
217
+ /**
218
+ * Get the archetypal symbol for a given axis
219
+ * @param {number|string} axis - Axis index or name
220
+ * @returns {Object|null} Symbol or null
221
+ */
222
+ getAxisArchetype(axis) {
223
+ const idx = typeof axis === 'string' ? AXIS_INDEX[axis] : axis;
224
+ const mapping = AXIS_SYMBOL_MAPPING[idx];
225
+
226
+ if (!mapping) return null;
227
+
228
+ // Try each archetype until we find one
229
+ for (const archetypeId of mapping.archetypes) {
230
+ const symbol = symbolDatabase.getSymbol(archetypeId);
231
+ if (symbol) return symbol;
232
+ }
233
+
234
+ return null;
235
+ }
236
+
237
+ /**
238
+ * Ground current SMF orientation in archetypal symbols
239
+ * Returns the symbols most aligned with the dominant axes
240
+ *
241
+ * @param {number} count - Number of symbols to return
242
+ * @returns {Array} Array of {axis, axisValue, symbol, alignment, isPositive} objects
243
+ */
244
+ groundInSymbols(count = 3) {
245
+ const dominant = this.dominantAxes(count);
246
+ const grounded = [];
247
+
248
+ for (const axis of dominant) {
249
+ const symbol = this.getAxisArchetype(axis.index);
250
+ if (symbol) {
251
+ grounded.push({
252
+ axis: axis.name,
253
+ axisValue: axis.value,
254
+ symbol: symbol,
255
+ alignment: Math.abs(axis.value), // How strongly aligned
256
+ isPositive: axis.value >= 0
257
+ });
258
+ }
259
+ }
260
+
261
+ this.activeSymbols = grounded.map(g => g.symbol);
262
+ return grounded;
263
+ }
264
+
265
+ /**
266
+ * Excite SMF from a symbol activation
267
+ * Maps symbol's prime and cultural tags to SMF axes
268
+ *
269
+ * @param {string} symbolId - Symbol ID to activate
270
+ * @param {number} intensity - Activation intensity (0-1)
271
+ * @returns {boolean} True if symbol was found and applied
272
+ */
273
+ exciteFromSymbol(symbolId, intensity = 0.3) {
274
+ const symbol = symbolDatabase.getSymbol(symbolId);
275
+ if (!symbol) return false;
276
+
277
+ // Primary axis: map prime to axis via log2
278
+ const primaryAxis = Math.floor(Math.log2(symbol.prime)) % 16;
279
+ this.s[primaryAxis] = Math.min(1, this.s[primaryAxis] + intensity);
280
+
281
+ // Secondary axes from cultural tags
282
+ const tagIntensity = intensity * 0.3;
283
+ for (const tag of symbol.culturalTags.slice(0, 5)) {
284
+ const axisIdx = this.tagToAxis(tag);
285
+ if (axisIdx >= 0 && axisIdx !== primaryAxis) {
286
+ this.s[axisIdx] = Math.min(1, this.s[axisIdx] + tagIntensity);
287
+ }
288
+ }
289
+
290
+ // Category-based axis (from mapping)
291
+ const categoryAxis = this.categoryToAxis(symbol.category);
292
+ if (categoryAxis >= 0 && categoryAxis !== primaryAxis) {
293
+ this.s[categoryAxis] = Math.min(1, this.s[categoryAxis] + tagIntensity);
294
+ }
295
+
296
+ this.normalize();
297
+
298
+ // Record to history
299
+ this.symbolHistory.push({
300
+ symbolId,
301
+ symbol,
302
+ intensity,
303
+ timestamp: Date.now(),
304
+ primaryAxis,
305
+ smfSnapshot: this.s.slice()
306
+ });
307
+
308
+ if (this.symbolHistory.length > this.maxHistory) {
309
+ this.symbolHistory.shift();
310
+ }
311
+
312
+ return true;
313
+ }
314
+
315
+ /**
316
+ * Map symbol category to primary axis
317
+ * @param {string} category - Symbol category
318
+ * @returns {number} Axis index
319
+ */
320
+ categoryToAxis(category) {
321
+ const mapping = {
322
+ [SymbolCategory.ARCHETYPE]: 1, // identity
323
+ [SymbolCategory.ELEMENT]: 5, // life
324
+ [SymbolCategory.PLACE]: 14, // space
325
+ [SymbolCategory.OBJECT]: 3, // structure
326
+ [SymbolCategory.ABSTRACT]: 0, // coherence
327
+ [SymbolCategory.MYTHOLOGICAL]: 12, // power
328
+ [SymbolCategory.TAROT]: 4, // change
329
+ [SymbolCategory.ICHING]: 2 // duality
330
+ };
331
+ return mapping[category] ?? 0;
332
+ }
333
+
334
+ /**
335
+ * Excite SMF from multiple symbols simultaneously
336
+ * Uses resonance weighting to determine relative intensities
337
+ *
338
+ * @param {Array<string>} symbolIds - Array of symbol IDs
339
+ * @param {number} baseIntensity - Base intensity for each
340
+ */
341
+ exciteFromSymbols(symbolIds, baseIntensity = 0.2) {
342
+ const symbols = symbolIds
343
+ .map(id => symbolDatabase.getSymbol(id))
344
+ .filter(Boolean);
345
+
346
+ if (symbols.length === 0) return;
347
+
348
+ // Calculate resonance weights
349
+ const weights = [];
350
+ for (let i = 0; i < symbols.length; i++) {
351
+ let totalResonance = 0;
352
+ for (let j = 0; j < symbols.length; j++) {
353
+ if (i !== j) {
354
+ totalResonance += this.resonanceCalc.calculateResonance(
355
+ symbols[i].prime,
356
+ symbols[j].prime
357
+ );
358
+ }
359
+ }
360
+ weights.push(1 + totalResonance / symbols.length);
361
+ }
362
+
363
+ // Normalize weights
364
+ const maxWeight = Math.max(...weights);
365
+ const normalizedWeights = weights.map(w => w / maxWeight);
366
+
367
+ // Apply excitations with resonance weighting
368
+ for (let i = 0; i < symbols.length; i++) {
369
+ this.exciteFromSymbol(symbols[i].id, baseIntensity * normalizedWeights[i]);
370
+ }
371
+ }
372
+
373
+ /**
374
+ * Infer symbols from text and excite SMF
375
+ *
376
+ * @param {string} text - Text to process
377
+ * @param {number} intensity - Activation intensity
378
+ * @returns {Array} Inferred symbols
379
+ */
380
+ exciteFromText(text, intensity = 0.3) {
381
+ const results = this.inference.inferWithResonance(text, {
382
+ maxCandidates: 10,
383
+ useAttention: true
384
+ });
385
+
386
+ for (const result of results) {
387
+ this.exciteFromSymbol(
388
+ result.symbol.id,
389
+ intensity * result.confidence * (result.attentionWeight || 1)
390
+ );
391
+ }
392
+
393
+ return results;
394
+ }
395
+
396
+ /**
397
+ * Create a compound symbol from current SMF state
398
+ * Combines the active symbols into a unified concept
399
+ *
400
+ * @param {string} id - ID for the compound
401
+ * @param {string} meaning - Meaning description
402
+ * @returns {CompoundSymbol|null} Created compound or null
403
+ */
404
+ createCompoundFromState(id, meaning = null) {
405
+ const grounded = this.groundInSymbols(4);
406
+
407
+ if (grounded.length < 2) return null;
408
+
409
+ const symbols = grounded.map(g => g.symbol);
410
+ const culturalTags = ['smf-derived', ...grounded.map(g => g.axis)];
411
+
412
+ const defaultMeaning = `SMF compound: ${grounded.map(g =>
413
+ `${g.axis}(${g.symbol.id})`
414
+ ).join(' + ')}`;
415
+
416
+ try {
417
+ this.currentCompound = this.compoundBuilder.createCompoundFromSymbols(
418
+ id,
419
+ symbols,
420
+ meaning || defaultMeaning,
421
+ culturalTags
422
+ );
423
+ return this.currentCompound;
424
+ } catch (e) {
425
+ console.debug('Failed to create compound:', e.message);
426
+ return null;
427
+ }
428
+ }
429
+
430
+ /**
431
+ * Calculate resonance between SMF state and a symbol
432
+ *
433
+ * @param {string} symbolId - Symbol to check
434
+ * @returns {number} Resonance score 0-1
435
+ */
436
+ resonanceWithSymbol(symbolId) {
437
+ const symbol = symbolDatabase.getSymbol(symbolId);
438
+ if (!symbol) return 0;
439
+
440
+ // Get axis activations from symbol
441
+ const primaryAxis = Math.floor(Math.log2(symbol.prime)) % 16;
442
+ let resonance = Math.abs(this.s[primaryAxis]);
443
+
444
+ // Add tag-based resonance
445
+ let tagResonance = 0;
446
+ let tagCount = 0;
447
+ for (const tag of symbol.culturalTags) {
448
+ const axisIdx = this.tagToAxis(tag);
449
+ if (axisIdx >= 0) {
450
+ tagResonance += Math.abs(this.s[axisIdx]);
451
+ tagCount++;
452
+ }
453
+ }
454
+
455
+ if (tagCount > 0) {
456
+ resonance = resonance * 0.6 + (tagResonance / tagCount) * 0.4;
457
+ }
458
+
459
+ return Math.min(1, resonance);
460
+ }
461
+
462
+ /**
463
+ * Find most resonant symbols with current SMF state
464
+ *
465
+ * @param {number} count - Number of symbols to return
466
+ * @param {string} category - Optional category filter
467
+ * @returns {Array} Array of {symbol, resonance} objects
468
+ */
469
+ findResonantSymbols(count = 5, category = null) {
470
+ const candidates = category
471
+ ? symbolDatabase.getSymbolsByCategory(category) || []
472
+ : symbolDatabase.getAllSymbols();
473
+
474
+ const scored = candidates.map(symbol => ({
475
+ symbol,
476
+ resonance: this.resonanceWithSymbol(symbol.id)
477
+ }));
478
+
479
+ scored.sort((a, b) => b.resonance - a.resonance);
480
+ return scored.slice(0, count);
481
+ }
482
+
483
+ /**
484
+ * Get symbol history statistics
485
+ * @returns {Object} Statistics about symbol activations
486
+ */
487
+ getSymbolStats() {
488
+ if (this.symbolHistory.length === 0) {
489
+ return {
490
+ totalActivations: 0,
491
+ uniqueSymbols: 0,
492
+ mostActive: [],
493
+ recentSymbols: []
494
+ };
495
+ }
496
+
497
+ const symbolCounts = new Map();
498
+ for (const entry of this.symbolHistory) {
499
+ const count = symbolCounts.get(entry.symbolId) || 0;
500
+ symbolCounts.set(entry.symbolId, count + 1);
501
+ }
502
+
503
+ const sorted = Array.from(symbolCounts.entries())
504
+ .sort((a, b) => b[1] - a[1]);
505
+
506
+ return {
507
+ totalActivations: this.symbolHistory.length,
508
+ uniqueSymbols: symbolCounts.size,
509
+ mostActive: sorted.slice(0, 5).map(([id, count]) => ({
510
+ symbolId: id,
511
+ symbol: symbolDatabase.getSymbol(id),
512
+ count
513
+ })),
514
+ recentSymbols: this.symbolHistory.slice(-5).map(h => ({
515
+ symbolId: h.symbolId,
516
+ intensity: h.intensity,
517
+ timestamp: h.timestamp
518
+ }))
519
+ };
520
+ }
521
+
522
+ /**
523
+ * Clear symbol history
524
+ */
525
+ clearHistory() {
526
+ this.symbolHistory = [];
527
+ this.activeSymbols = [];
528
+ this.currentCompound = null;
529
+ }
530
+
531
+ /**
532
+ * Enhanced JSON serialization
533
+ * @returns {Object} JSON representation including symbolic data
534
+ */
535
+ toJSON() {
536
+ const base = super.toJSON();
537
+ const grounded = this.groundInSymbols(3);
538
+
539
+ return {
540
+ ...base,
541
+ symbolic: {
542
+ groundedSymbols: grounded.map(g => ({
543
+ axis: g.axis,
544
+ symbolId: g.symbol.id,
545
+ symbolUnicode: g.symbol.unicode,
546
+ alignment: g.alignment
547
+ })),
548
+ currentCompound: this.currentCompound?.toJSON() || null,
549
+ historyStats: this.getSymbolStats()
550
+ }
551
+ };
552
+ }
553
+
554
+ /**
555
+ * String representation with symbols
556
+ * @returns {string} String representation
557
+ */
558
+ toString() {
559
+ const grounded = this.groundInSymbols(3);
560
+ const symbols = grounded.map(g => g.symbol.unicode).join('');
561
+ const axes = grounded.map(g => `${g.axis}:${g.axisValue.toFixed(2)}`).join(', ');
562
+ return `SymbolicSMF(${symbols} | ${axes})`;
563
+ }
564
+ }
565
+
566
+ // ═══════════════════════════════════════════════════════════════════
567
+ // SMF Symbol Mapper (Utility Class)
568
+ // ═══════════════════════════════════════════════════════════════════
569
+
570
+ /**
571
+ * Utility class for mapping between symbols and SMF orientations
572
+ *
573
+ * Provides bidirectional mapping:
574
+ * - Symbols → SMF orientations
575
+ * - SMF orientations → matching symbols
576
+ */
577
+ class SMFSymbolMapper {
578
+ constructor() {
579
+ this.resonanceCalc = new ResonanceCalculator();
580
+ }
581
+
582
+ /**
583
+ * Create SMF orientation from a symbol
584
+ * @param {Object} symbol - Symbol object
585
+ * @returns {SymbolicSMF} SMF oriented toward symbol
586
+ */
587
+ symbolToSMF(symbol) {
588
+ const smf = new SymbolicSMF();
589
+ smf.s.fill(0);
590
+ smf.exciteFromSymbol(symbol.id, 1.0);
591
+ return smf;
592
+ }
593
+
594
+ /**
595
+ * Create SMF from multiple symbols with resonance weighting
596
+ * @param {Array} symbols - Array of symbol objects
597
+ * @returns {SymbolicSMF} Combined SMF
598
+ */
599
+ symbolsToSMF(symbols) {
600
+ const smf = new SymbolicSMF();
601
+ smf.s.fill(0);
602
+ smf.exciteFromSymbols(symbols.map(s => s.id), 0.5);
603
+ return smf;
604
+ }
605
+
606
+ /**
607
+ * Create SMF from compound symbol
608
+ * @param {CompoundSymbol} compound - Compound symbol
609
+ * @returns {SymbolicSMF} SMF from compound components
610
+ */
611
+ compoundToSMF(compound) {
612
+ return this.symbolsToSMF(compound.components);
613
+ }
614
+
615
+ /**
616
+ * Create SMF from symbol sequence (with temporal weighting)
617
+ * @param {SymbolSequence} sequence - Symbol sequence
618
+ * @param {number} recencyBias - How much to weight recent symbols (0-1)
619
+ * @returns {SymbolicSMF} SMF with recency-weighted symbols
620
+ */
621
+ sequenceToSMF(sequence, recencyBias = 0.3) {
622
+ const smf = new SymbolicSMF();
623
+ smf.s.fill(0);
624
+
625
+ const symbols = sequence.symbols;
626
+ const n = symbols.length;
627
+
628
+ for (let i = 0; i < n; i++) {
629
+ // Weight increases with position (recency)
630
+ const position = i / (n - 1 || 1); // 0 to 1
631
+ const weight = (1 - recencyBias) + recencyBias * position;
632
+ smf.exciteFromSymbol(symbols[i].id, 0.3 * weight);
633
+ }
634
+
635
+ return smf;
636
+ }
637
+
638
+ /**
639
+ * Find best matching symbol for an SMF orientation
640
+ * @param {SedenionMemoryField} smf - SMF to match
641
+ * @param {string} category - Optional category filter
642
+ * @returns {Object|null} Best matching symbol
643
+ */
644
+ findBestMatch(smf, category = null) {
645
+ const symbolic = smf instanceof SymbolicSMF
646
+ ? smf
647
+ : SymbolicSMF.fromSMF(smf);
648
+
649
+ const resonant = symbolic.findResonantSymbols(1, category);
650
+ return resonant.length > 0 ? resonant[0].symbol : null;
651
+ }
652
+
653
+ /**
654
+ * Calculate symbolic distance between two SMFs
655
+ * Uses symbol-grounded comparison
656
+ * @param {SedenionMemoryField} smf1 - First SMF
657
+ * @param {SedenionMemoryField} smf2 - Second SMF
658
+ * @returns {number} Distance 0-1 (0 = same, 1 = opposite)
659
+ */
660
+ symbolicDistance(smf1, smf2) {
661
+ const s1 = smf1 instanceof SymbolicSMF ? smf1 : SymbolicSMF.fromSMF(smf1);
662
+ const s2 = smf2 instanceof SymbolicSMF ? smf2 : SymbolicSMF.fromSMF(smf2);
663
+
664
+ const g1 = s1.groundInSymbols(5);
665
+ const g2 = s2.groundInSymbols(5);
666
+
667
+ // Compare symbol sets
668
+ const primes1 = new Set(g1.map(g => g.symbol.prime));
669
+ const primes2 = new Set(g2.map(g => g.symbol.prime));
670
+
671
+ // Jaccard similarity on prime sets
672
+ const intersection = new Set([...primes1].filter(p => primes2.has(p)));
673
+ const union = new Set([...primes1, ...primes2]);
674
+
675
+ const jaccard = union.size > 0 ? intersection.size / union.size : 0;
676
+
677
+ // Also use standard coherence
678
+ const coherence = s1.coherence(s2);
679
+
680
+ // Combined metric
681
+ return 1 - (0.5 * jaccard + 0.5 * Math.abs(coherence));
682
+ }
683
+ }
684
+
685
+ // Singleton instance
686
+ const smfMapper = new SMFSymbolMapper();
687
+
688
+ export {
689
+ // Classes
690
+ SymbolicSMF,
691
+ SMFSymbolMapper,
692
+ // Singleton instance
693
+ smfMapper,
694
+ // Mappings (for external use)
695
+ AXIS_SYMBOL_MAPPING,
696
+ TAG_TO_AXIS,
697
+ // Convenience functions
698
+ createSymbolicSMF: (components,
699
+ options) => new SymbolicSMF(components,
700
+ options),
701
+ fromSMF: (smf,
702
+ options) => SymbolicSMF.fromSMF(smf,
703
+ options),
704
+ symbolToSMF: (symbol) => smfMapper.symbolToSMF(symbol),
705
+ symbolsToSMF: (symbols) => smfMapper.symbolsToSMF(symbols)
706
+ };
707
+
708
+ export default {
709
+ // Classes
710
+ SymbolicSMF,
711
+ SMFSymbolMapper,
712
+ // Singleton instance
713
+ smfMapper,
714
+ // Mappings (for external use)
715
+ AXIS_SYMBOL_MAPPING,
716
+ TAG_TO_AXIS,
717
+ // Convenience functions
718
+ createSymbolicSMF: (components,
719
+ options) => new SymbolicSMF(components,
720
+ options),
721
+ fromSMF: (smf,
722
+ options) => SymbolicSMF.fromSMF(smf,
723
+ options),
724
+ symbolToSMF: (symbol) => smfMapper.symbolToSMF(symbol),
725
+ symbolsToSMF: (symbols) => smfMapper.symbolsToSMF(symbols)
726
+ };