@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
|
@@ -0,0 +1,375 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Two-Layer Semantic Engine
|
|
3
|
+
*
|
|
4
|
+
* Layer 1 (Core): Works with prime-based meaning
|
|
5
|
+
* - Operates on invariant semantic structure
|
|
6
|
+
* - Performs reasoning via entropy minimization
|
|
7
|
+
* - Handles non-commutative concept ordering
|
|
8
|
+
*
|
|
9
|
+
* Layer 2 (Surface): Biases word selection
|
|
10
|
+
* - Maps primes to specific words
|
|
11
|
+
* - Applies style/register preferences
|
|
12
|
+
* - Handles context-dependent vocabulary
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const { SemanticBackend } = require('./index');
|
|
16
|
+
const { Surface, SurfaceManager, BiasEngine } = require('./surface');
|
|
17
|
+
|
|
18
|
+
class TwoLayerEngine {
|
|
19
|
+
constructor(config = {}) {
|
|
20
|
+
// Layer 1: Core meaning engine
|
|
21
|
+
this.core = new SemanticBackend(config.core || {
|
|
22
|
+
dimension: 16
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
// Layer 2: Surface word selection
|
|
26
|
+
this.surfaces = new SurfaceManager();
|
|
27
|
+
this.biasEngine = new BiasEngine();
|
|
28
|
+
|
|
29
|
+
// Initialize default surfaces
|
|
30
|
+
this._initDefaultSurfaces(config.surfaces || {});
|
|
31
|
+
|
|
32
|
+
// Track conversation history for context
|
|
33
|
+
this.history = [];
|
|
34
|
+
this.maxHistory = config.maxHistory || 10;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Initialize default vocabulary surfaces
|
|
39
|
+
*/
|
|
40
|
+
_initDefaultSurfaces(surfaceConfigs) {
|
|
41
|
+
// Formal academic register
|
|
42
|
+
this.surfaces.create('formal', {
|
|
43
|
+
vocabulary: {
|
|
44
|
+
// Same primes, different words, different biases
|
|
45
|
+
'truth': { primes: [7, 11, 13], bias: 1.0, contexts: ['academic', 'philosophy'] },
|
|
46
|
+
'verity': { primes: [7, 11, 13], bias: 0.8, contexts: ['literary', 'archaic'] },
|
|
47
|
+
'veracity': { primes: [7, 11, 13], bias: 0.6, contexts: ['legal', 'formal'] },
|
|
48
|
+
|
|
49
|
+
'love': { primes: [2, 3, 5], bias: 1.0, contexts: ['general'] },
|
|
50
|
+
'affection': { primes: [2, 3, 5], bias: 0.9, contexts: ['formal'] },
|
|
51
|
+
'devotion': { primes: [2, 3, 5], bias: 0.7, contexts: ['religious', 'romantic'] },
|
|
52
|
+
|
|
53
|
+
'wisdom': { primes: [2, 7, 11], bias: 1.0, contexts: ['philosophy'] },
|
|
54
|
+
'sagacity': { primes: [2, 7, 11], bias: 0.6, contexts: ['archaic', 'literary'] },
|
|
55
|
+
'prudence': { primes: [2, 7, 11], bias: 0.8, contexts: ['practical', 'virtue'] },
|
|
56
|
+
|
|
57
|
+
'knowledge': { primes: [3, 5, 7], bias: 1.0, contexts: ['academic'] },
|
|
58
|
+
'erudition': { primes: [3, 5, 7], bias: 0.5, contexts: ['literary'] },
|
|
59
|
+
'expertise': { primes: [3, 5, 7], bias: 0.8, contexts: ['professional'] },
|
|
60
|
+
|
|
61
|
+
'think': { primes: [5, 7, 11], bias: 1.0, contexts: ['general'] },
|
|
62
|
+
'contemplate': { primes: [5, 7, 11], bias: 0.7, contexts: ['philosophy', 'meditation'] },
|
|
63
|
+
'cogitate': { primes: [5, 7, 11], bias: 0.4, contexts: ['archaic'] },
|
|
64
|
+
'deliberate': { primes: [5, 7, 11], bias: 0.8, contexts: ['decision'] },
|
|
65
|
+
|
|
66
|
+
'good': { primes: [2, 3], bias: 1.0, contexts: ['general'] },
|
|
67
|
+
'virtuous': { primes: [2, 3], bias: 0.7, contexts: ['moral', 'religious'] },
|
|
68
|
+
'beneficent': { primes: [2, 3], bias: 0.5, contexts: ['formal'] },
|
|
69
|
+
|
|
70
|
+
'bad': { primes: [5, 13], bias: 1.0, contexts: ['general'] },
|
|
71
|
+
'malevolent': { primes: [5, 13], bias: 0.6, contexts: ['literary'] },
|
|
72
|
+
'pernicious': { primes: [5, 13], bias: 0.5, contexts: ['formal', 'medical'] }
|
|
73
|
+
},
|
|
74
|
+
defaultBias: 1.0
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
// Casual conversational register
|
|
78
|
+
this.surfaces.create('casual', {
|
|
79
|
+
vocabulary: {
|
|
80
|
+
'truth': { primes: [7, 11, 13], bias: 0.5, contexts: [] },
|
|
81
|
+
'real talk': { primes: [7, 11, 13], bias: 1.0, contexts: ['slang'] },
|
|
82
|
+
'straight up': { primes: [7, 11, 13], bias: 0.8, contexts: ['slang'] },
|
|
83
|
+
'no cap': { primes: [7, 11, 13], bias: 0.6, contexts: ['gen-z'] },
|
|
84
|
+
|
|
85
|
+
'love': { primes: [2, 3, 5], bias: 1.0, contexts: ['general'] },
|
|
86
|
+
'dig': { primes: [2, 3, 5], bias: 0.7, contexts: ['casual'] },
|
|
87
|
+
'vibe with': { primes: [2, 3, 5], bias: 0.8, contexts: ['slang'] },
|
|
88
|
+
|
|
89
|
+
'wisdom': { primes: [2, 7, 11], bias: 0.6, contexts: [] },
|
|
90
|
+
'smarts': { primes: [2, 7, 11], bias: 1.0, contexts: ['casual'] },
|
|
91
|
+
'big brain': { primes: [2, 7, 11], bias: 0.7, contexts: ['slang', 'internet'] },
|
|
92
|
+
|
|
93
|
+
'think': { primes: [5, 7, 11], bias: 1.0, contexts: ['general'] },
|
|
94
|
+
'figure': { primes: [5, 7, 11], bias: 0.9, contexts: ['casual'] },
|
|
95
|
+
'reckon': { primes: [5, 7, 11], bias: 0.7, contexts: ['regional'] },
|
|
96
|
+
|
|
97
|
+
'good': { primes: [2, 3], bias: 1.0, contexts: ['general'] },
|
|
98
|
+
'awesome': { primes: [2, 3], bias: 0.9, contexts: ['casual'] },
|
|
99
|
+
'fire': { primes: [2, 3], bias: 0.6, contexts: ['slang', 'gen-z'] },
|
|
100
|
+
'lit': { primes: [2, 3], bias: 0.5, contexts: ['slang'] },
|
|
101
|
+
|
|
102
|
+
'bad': { primes: [5, 13], bias: 1.0, contexts: ['general'] },
|
|
103
|
+
'trash': { primes: [5, 13], bias: 0.7, contexts: ['slang'] },
|
|
104
|
+
'wack': { primes: [5, 13], bias: 0.5, contexts: ['slang'] }
|
|
105
|
+
},
|
|
106
|
+
defaultBias: 1.0
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// Technical/scientific register
|
|
110
|
+
this.surfaces.create('technical', {
|
|
111
|
+
vocabulary: {
|
|
112
|
+
'truth': { primes: [7, 11, 13], bias: 0.8, contexts: [] },
|
|
113
|
+
'validity': { primes: [7, 11, 13], bias: 1.0, contexts: ['logic', 'science'] },
|
|
114
|
+
'accuracy': { primes: [7, 11, 13], bias: 0.9, contexts: ['measurement'] },
|
|
115
|
+
|
|
116
|
+
'knowledge': { primes: [3, 5, 7], bias: 0.7, contexts: [] },
|
|
117
|
+
'data': { primes: [3, 5, 7], bias: 1.0, contexts: ['science', 'computing'] },
|
|
118
|
+
'information': { primes: [3, 5, 7], bias: 0.9, contexts: ['technical'] },
|
|
119
|
+
|
|
120
|
+
'think': { primes: [5, 7, 11], bias: 0.6, contexts: [] },
|
|
121
|
+
'compute': { primes: [5, 7, 11], bias: 1.0, contexts: ['computing'] },
|
|
122
|
+
'process': { primes: [5, 7, 11], bias: 0.9, contexts: ['technical'] },
|
|
123
|
+
'analyze': { primes: [5, 7, 11], bias: 0.85, contexts: ['science'] },
|
|
124
|
+
|
|
125
|
+
'cause': { primes: [3, 7, 13], bias: 1.0, contexts: ['science'] },
|
|
126
|
+
'induce': { primes: [3, 7, 13], bias: 0.8, contexts: ['technical'] },
|
|
127
|
+
'effect': { primes: [3, 7, 13], bias: 0.7, contexts: ['result'] }
|
|
128
|
+
},
|
|
129
|
+
defaultBias: 1.0
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
// Poetic/literary register
|
|
133
|
+
this.surfaces.create('poetic', {
|
|
134
|
+
vocabulary: {
|
|
135
|
+
'truth': { primes: [7, 11, 13], bias: 0.8, contexts: [] },
|
|
136
|
+
'verity': { primes: [7, 11, 13], bias: 1.0, contexts: ['literary'] },
|
|
137
|
+
'essence': { primes: [7, 11, 13], bias: 0.9, contexts: ['philosophical'] },
|
|
138
|
+
|
|
139
|
+
'love': { primes: [2, 3, 5], bias: 0.8, contexts: [] },
|
|
140
|
+
'ardor': { primes: [2, 3, 5], bias: 1.0, contexts: ['romantic'] },
|
|
141
|
+
'passion': { primes: [2, 3, 5], bias: 0.95, contexts: ['intense'] },
|
|
142
|
+
'devotion': { primes: [2, 3, 5], bias: 0.9, contexts: ['committed'] },
|
|
143
|
+
|
|
144
|
+
'think': { primes: [5, 7, 11], bias: 0.6, contexts: [] },
|
|
145
|
+
'ponder': { primes: [5, 7, 11], bias: 1.0, contexts: ['reflective'] },
|
|
146
|
+
'muse': { primes: [5, 7, 11], bias: 0.9, contexts: ['artistic'] },
|
|
147
|
+
'contemplate': { primes: [5, 7, 11], bias: 0.85, contexts: ['deep'] },
|
|
148
|
+
|
|
149
|
+
'light': { primes: [2, 5, 11], bias: 0.8, contexts: [] },
|
|
150
|
+
'radiance': { primes: [2, 5, 11], bias: 1.0, contexts: ['beautiful'] },
|
|
151
|
+
'luminescence': { primes: [2, 5, 11], bias: 0.8, contexts: ['scientific-poetic'] },
|
|
152
|
+
|
|
153
|
+
'dark': { primes: [3, 7, 13], bias: 0.8, contexts: [] },
|
|
154
|
+
'shadow': { primes: [3, 7, 13], bias: 1.0, contexts: ['imagery'] },
|
|
155
|
+
'void': { primes: [3, 7, 13], bias: 0.9, contexts: ['cosmic'] },
|
|
156
|
+
'abyss': { primes: [3, 7, 13], bias: 0.85, contexts: ['dramatic'] }
|
|
157
|
+
},
|
|
158
|
+
defaultBias: 1.0
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
// Apply any custom surface configs
|
|
162
|
+
for (const [name, config] of Object.entries(surfaceConfigs)) {
|
|
163
|
+
this.surfaces.create(name, config);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
// Default to formal
|
|
167
|
+
this.surfaces.use('formal');
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Process input through both layers
|
|
172
|
+
* Returns { meaning: <prime state>, words: <surface words> }
|
|
173
|
+
*/
|
|
174
|
+
process(input, options = {}) {
|
|
175
|
+
// Layer 1: Core meaning processing
|
|
176
|
+
const tokens = this.core.encodeOrdered(input);
|
|
177
|
+
const orderedPrimes = tokens.map(t => t.primes);
|
|
178
|
+
const meaningState = this.core.orderedPrimesToState(tokens);
|
|
179
|
+
|
|
180
|
+
// Record for history
|
|
181
|
+
this.recordHistory(input, orderedPrimes);
|
|
182
|
+
|
|
183
|
+
// Layer 2: Surface word selection
|
|
184
|
+
const selectedWords = this.selectWords(orderedPrimes, options);
|
|
185
|
+
|
|
186
|
+
return {
|
|
187
|
+
input,
|
|
188
|
+
tokens,
|
|
189
|
+
meaning: {
|
|
190
|
+
state: meaningState,
|
|
191
|
+
primes: orderedPrimes.flat(),
|
|
192
|
+
entropy: meaningState.entropy()
|
|
193
|
+
},
|
|
194
|
+
surface: {
|
|
195
|
+
words: selectedWords,
|
|
196
|
+
register: this.surfaces.activeSurface
|
|
197
|
+
}
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
/**
|
|
202
|
+
* Select words for each prime group using surface layer
|
|
203
|
+
*/
|
|
204
|
+
selectWords(orderedPrimes, options = {}) {
|
|
205
|
+
const words = [];
|
|
206
|
+
const usedWords = new Set();
|
|
207
|
+
|
|
208
|
+
for (let i = 0; i < orderedPrimes.length; i++) {
|
|
209
|
+
const primes = orderedPrimes[i];
|
|
210
|
+
|
|
211
|
+
// Get bias from bias engine
|
|
212
|
+
const biasOptions = {
|
|
213
|
+
...options,
|
|
214
|
+
contexts: this.surfaces.contextStack,
|
|
215
|
+
avoid: options.avoidRepetition ? [...usedWords] : []
|
|
216
|
+
};
|
|
217
|
+
|
|
218
|
+
const word = this.surfaces.decode(primes, biasOptions);
|
|
219
|
+
words.push(word);
|
|
220
|
+
usedWords.add(word);
|
|
221
|
+
|
|
222
|
+
// Apply variety bias (suppress recently used)
|
|
223
|
+
if (options.varietyBias) {
|
|
224
|
+
this.biasEngine.suppressRecent(word, 0.7);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Decay temporary biases
|
|
229
|
+
this.biasEngine.decay();
|
|
230
|
+
|
|
231
|
+
return words;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* Transform meaning and express in target register
|
|
236
|
+
*/
|
|
237
|
+
transform(input, targetRegister, options = {}) {
|
|
238
|
+
// Get meaning from core
|
|
239
|
+
const meaning = this.process(input);
|
|
240
|
+
|
|
241
|
+
// Switch surface
|
|
242
|
+
const originalSurface = this.surfaces.activeSurface;
|
|
243
|
+
this.surfaces.use(targetRegister);
|
|
244
|
+
|
|
245
|
+
// Generate in new register
|
|
246
|
+
const transformed = this.selectWords(
|
|
247
|
+
meaning.tokens.map(t => t.primes),
|
|
248
|
+
options
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
// Restore original surface
|
|
252
|
+
this.surfaces.use(originalSurface);
|
|
253
|
+
|
|
254
|
+
return {
|
|
255
|
+
original: input,
|
|
256
|
+
originalRegister: originalSurface,
|
|
257
|
+
transformed: transformed.join(' '),
|
|
258
|
+
targetRegister,
|
|
259
|
+
meaning: meaning.meaning
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
/**
|
|
264
|
+
* Translate between registers
|
|
265
|
+
*/
|
|
266
|
+
translate(input, fromRegister, toRegister, options = {}) {
|
|
267
|
+
this.surfaces.use(fromRegister);
|
|
268
|
+
const meaning = this.process(input);
|
|
269
|
+
|
|
270
|
+
this.surfaces.use(toRegister);
|
|
271
|
+
const translated = this.selectWords(
|
|
272
|
+
meaning.tokens.map(t => t.primes),
|
|
273
|
+
options
|
|
274
|
+
);
|
|
275
|
+
|
|
276
|
+
return {
|
|
277
|
+
original: input,
|
|
278
|
+
from: fromRegister,
|
|
279
|
+
translated: translated.join(' '),
|
|
280
|
+
to: toRegister,
|
|
281
|
+
meaning: meaning.meaning
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Generate response biased toward specific style
|
|
287
|
+
*/
|
|
288
|
+
generateWithStyle(primes, style, options = {}) {
|
|
289
|
+
// Push style context
|
|
290
|
+
this.surfaces.pushContext(style);
|
|
291
|
+
|
|
292
|
+
// Select words with style bias
|
|
293
|
+
const words = this.selectWords([primes], {
|
|
294
|
+
...options,
|
|
295
|
+
contexts: [style]
|
|
296
|
+
});
|
|
297
|
+
|
|
298
|
+
// Pop context
|
|
299
|
+
this.surfaces.popContext();
|
|
300
|
+
|
|
301
|
+
return words.join(' ');
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/**
|
|
305
|
+
* Record interaction in history
|
|
306
|
+
*/
|
|
307
|
+
recordHistory(input, primes) {
|
|
308
|
+
this.history.push({
|
|
309
|
+
time: Date.now(),
|
|
310
|
+
input,
|
|
311
|
+
primes: primes.flat()
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
while (this.history.length > this.maxHistory) {
|
|
315
|
+
this.history.shift();
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Get primes that have been active recently
|
|
321
|
+
*/
|
|
322
|
+
getRecentPrimes() {
|
|
323
|
+
const recent = new Map();
|
|
324
|
+
const decay = 0.8;
|
|
325
|
+
|
|
326
|
+
for (let i = this.history.length - 1; i >= 0; i--) {
|
|
327
|
+
const age = this.history.length - 1 - i;
|
|
328
|
+
const weight = Math.pow(decay, age);
|
|
329
|
+
|
|
330
|
+
for (const p of this.history[i].primes) {
|
|
331
|
+
recent.set(p, (recent.get(p) || 0) + weight);
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
return recent;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
/**
|
|
339
|
+
* Bias toward words related to recent conversation
|
|
340
|
+
*/
|
|
341
|
+
applyConversationalBias() {
|
|
342
|
+
const recentPrimes = this.getRecentPrimes();
|
|
343
|
+
|
|
344
|
+
for (const [prime, weight] of recentPrimes) {
|
|
345
|
+
// Find words with this prime and boost them slightly
|
|
346
|
+
// This creates topical coherence
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
/**
|
|
351
|
+
* Set current register
|
|
352
|
+
*/
|
|
353
|
+
useRegister(register) {
|
|
354
|
+
this.surfaces.use(register);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Get available registers
|
|
359
|
+
*/
|
|
360
|
+
getRegisters() {
|
|
361
|
+
return [...this.surfaces.surfaces.keys()];
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* Add custom vocabulary to a surface
|
|
366
|
+
*/
|
|
367
|
+
addVocabulary(register, vocabulary) {
|
|
368
|
+
const surface = this.surfaces.surfaces.get(register);
|
|
369
|
+
if (surface) {
|
|
370
|
+
surface.loadVocabulary(vocabulary);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
module.exports = { TwoLayerEngine };
|
package/core/fano.js
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Fano plane structure for octonion/sedenion multiplication
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
// Standard Fano plane lines (7 lines of 3 points each)
|
|
6
|
+
const FANO_LINES = [
|
|
7
|
+
[1, 2, 3],
|
|
8
|
+
[1, 4, 5],
|
|
9
|
+
[1, 6, 7],
|
|
10
|
+
[2, 4, 6],
|
|
11
|
+
[2, 5, 7],
|
|
12
|
+
[3, 4, 7],
|
|
13
|
+
[3, 5, 6]
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Octonion multiplication using Fano plane
|
|
18
|
+
*/
|
|
19
|
+
function octonionMultiplyIndex(i, j) {
|
|
20
|
+
if (i === 0) return [j, 1];
|
|
21
|
+
if (j === 0) return [i, 1];
|
|
22
|
+
if (i === j) return [0, -1];
|
|
23
|
+
|
|
24
|
+
for (const line of FANO_LINES) {
|
|
25
|
+
const xi = line.indexOf(i);
|
|
26
|
+
if (xi >= 0 && line.includes(j)) {
|
|
27
|
+
const xj = line.indexOf(j);
|
|
28
|
+
const k = line[3 - xi - xj];
|
|
29
|
+
const sign = (xj - xi + 3) % 3 === 1 ? 1 : -1;
|
|
30
|
+
return [k, sign];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
return [i ^ j, 1];
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Sedenion multiplication (Cayley-Dickson extension of octonions)
|
|
38
|
+
*/
|
|
39
|
+
function sedenionMultiplyIndex(i, j) {
|
|
40
|
+
if (i === 0) return [j, 1];
|
|
41
|
+
if (j === 0) return [i, 1];
|
|
42
|
+
if (i === j) return [0, -1];
|
|
43
|
+
|
|
44
|
+
const hi = i >= 8, hj = j >= 8;
|
|
45
|
+
const li = i & 7, lj = j & 7;
|
|
46
|
+
|
|
47
|
+
if (!hi && !hj) return octonionMultiplyIndex(li, lj);
|
|
48
|
+
if (hi && hj) {
|
|
49
|
+
const [k, s] = octonionMultiplyIndex(li, lj);
|
|
50
|
+
return [k, -s];
|
|
51
|
+
}
|
|
52
|
+
if (!hi) {
|
|
53
|
+
const [k, s] = octonionMultiplyIndex(lj, li);
|
|
54
|
+
return [k + 8, s];
|
|
55
|
+
}
|
|
56
|
+
const [k, s] = octonionMultiplyIndex(li, lj);
|
|
57
|
+
return [k + 8, -s];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Generic multiplication index lookup
|
|
62
|
+
*/
|
|
63
|
+
function multiplyIndices(dim, i, j) {
|
|
64
|
+
if (dim <= 2) {
|
|
65
|
+
// Complex numbers
|
|
66
|
+
if (i === 0) return [j, 1];
|
|
67
|
+
if (j === 0) return [i, 1];
|
|
68
|
+
if (i === 1 && j === 1) return [0, -1];
|
|
69
|
+
return [i ^ j, 1];
|
|
70
|
+
}
|
|
71
|
+
if (dim <= 4) {
|
|
72
|
+
// Quaternions
|
|
73
|
+
if (i === 0) return [j, 1];
|
|
74
|
+
if (j === 0) return [i, 1];
|
|
75
|
+
if (i === j) return [0, -1];
|
|
76
|
+
// i*j=k, j*k=i, k*i=j (and negatives for reverse)
|
|
77
|
+
const quat = [[0,0,0,0], [0,0,3,-2], [0,-3,0,1], [0,2,-1,0]];
|
|
78
|
+
const k = quat[i][j];
|
|
79
|
+
const sign = k > 0 ? 1 : -1;
|
|
80
|
+
return [Math.abs(k), sign];
|
|
81
|
+
}
|
|
82
|
+
if (dim <= 8) return octonionMultiplyIndex(i % 8, j % 8);
|
|
83
|
+
if (dim <= 16) return sedenionMultiplyIndex(i, j);
|
|
84
|
+
|
|
85
|
+
// Pathion (32D) and beyond: recursive Cayley-Dickson
|
|
86
|
+
if (i === 0) return [j, 1];
|
|
87
|
+
if (j === 0) return [i, 1];
|
|
88
|
+
if (i === j) return [0, -1];
|
|
89
|
+
|
|
90
|
+
const half = dim / 2;
|
|
91
|
+
const hi = i >= half, hj = j >= half;
|
|
92
|
+
const li = i % half, lj = j % half;
|
|
93
|
+
|
|
94
|
+
if (!hi && !hj) return multiplyIndices(half, li, lj);
|
|
95
|
+
if (hi && hj) {
|
|
96
|
+
const [k, s] = multiplyIndices(half, li, lj);
|
|
97
|
+
return [k, -s];
|
|
98
|
+
}
|
|
99
|
+
if (!hi) {
|
|
100
|
+
const [k, s] = multiplyIndices(half, lj, li);
|
|
101
|
+
return [k + half, s];
|
|
102
|
+
}
|
|
103
|
+
const [k, s] = multiplyIndices(half, li, lj);
|
|
104
|
+
return [k + half, -s];
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Build full multiplication table for a given dimension
|
|
109
|
+
*/
|
|
110
|
+
function buildMultiplicationTable(dim) {
|
|
111
|
+
const table = [];
|
|
112
|
+
for (let i = 0; i < dim; i++) {
|
|
113
|
+
table[i] = [];
|
|
114
|
+
for (let j = 0; j < dim; j++) {
|
|
115
|
+
table[i][j] = multiplyIndices(dim, i, j);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return table;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
module.exports = {
|
|
122
|
+
FANO_LINES,
|
|
123
|
+
octonionMultiplyIndex,
|
|
124
|
+
sedenionMultiplyIndex,
|
|
125
|
+
multiplyIndices,
|
|
126
|
+
buildMultiplicationTable
|
|
127
|
+
};
|