@aleph-ai/tinyaleph 1.0.2 → 1.1.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/README.md +219 -0
- package/core/index.js +83 -1
- package/core/lambda.js +845 -0
- package/core/reduction.js +741 -0
- package/core/types.js +913 -0
- package/docs/README.md +84 -0
- package/docs/design/ALEPH_CHAT_ARCHITECTURE.md +1 -1
- package/docs/design/AUTONOMOUS_LEARNING_DESIGN.md +1492 -0
- package/docs/design/WHITEPAPER_GAP_ANALYSIS.md +171 -4
- package/docs/reference/README.md +277 -1
- package/docs/theory/03-phase-synchronization.md +196 -0
- package/docs/theory/README.md +47 -0
- package/package.json +2 -2
- package/physics/index.js +30 -10
- package/physics/sync-models.js +770 -0
package/core/lambda.js
ADDED
|
@@ -0,0 +1,845 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* λ-Calculus Translation Layer for Prime-Indexed Semantic Calculi
|
|
3
|
+
*
|
|
4
|
+
* Provides a denotational semantics via λ-calculus:
|
|
5
|
+
* - τ (tau) translation function from typed terms to λ-expressions
|
|
6
|
+
* - Compositional semantics via function application
|
|
7
|
+
* - Type preservation during translation
|
|
8
|
+
* - Denotational semantics bridge
|
|
9
|
+
*
|
|
10
|
+
* The translation τ maps:
|
|
11
|
+
* - N(p) → λx.p (constant function returning prime p)
|
|
12
|
+
* - A(p) → λf.λx.f(p,x) (operator awaiting application)
|
|
13
|
+
* - FUSE(p,q,r) → λx.(p+q+r) (fusion to sum)
|
|
14
|
+
* - A(p)N(q) → (τ(A(p)))(τ(N(q))) = p ⊕ q
|
|
15
|
+
* - S₁ ◦ S₂ → (τ(S₁), τ(S₂))
|
|
16
|
+
* - S₁ ⇒ S₂ → τ(S₁) → τ(S₂)
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
const {
|
|
20
|
+
NounTerm,
|
|
21
|
+
AdjTerm,
|
|
22
|
+
ChainTerm,
|
|
23
|
+
FusionTerm,
|
|
24
|
+
NounSentence,
|
|
25
|
+
SeqSentence,
|
|
26
|
+
ImplSentence,
|
|
27
|
+
N, A, FUSE, CHAIN
|
|
28
|
+
} = require('./types');
|
|
29
|
+
|
|
30
|
+
const {
|
|
31
|
+
ReductionSystem,
|
|
32
|
+
DEFAULT_OPERATOR
|
|
33
|
+
} = require('./reduction');
|
|
34
|
+
|
|
35
|
+
// ============================================================================
|
|
36
|
+
// λ-EXPRESSION AST
|
|
37
|
+
// ============================================================================
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Base class for λ-expressions
|
|
41
|
+
*/
|
|
42
|
+
class LambdaExpr {
|
|
43
|
+
/**
|
|
44
|
+
* Get the type of this expression
|
|
45
|
+
*/
|
|
46
|
+
getType() {
|
|
47
|
+
throw new Error('Must be implemented by subclass');
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Convert to string representation
|
|
52
|
+
*/
|
|
53
|
+
toString() {
|
|
54
|
+
throw new Error('Must be implemented by subclass');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Check if this is a value (fully evaluated)
|
|
59
|
+
*/
|
|
60
|
+
isValue() {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Substitute variable x with expression e
|
|
66
|
+
*/
|
|
67
|
+
substitute(x, e) {
|
|
68
|
+
throw new Error('Must be implemented by subclass');
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Get free variables
|
|
73
|
+
*/
|
|
74
|
+
freeVars() {
|
|
75
|
+
return new Set();
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Alpha-equivalence check
|
|
80
|
+
*/
|
|
81
|
+
alphaEquals(other) {
|
|
82
|
+
return this.toString() === other.toString();
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Variable expression
|
|
88
|
+
*/
|
|
89
|
+
class VarExpr extends LambdaExpr {
|
|
90
|
+
constructor(name, type = null) {
|
|
91
|
+
super();
|
|
92
|
+
this.name = name;
|
|
93
|
+
this.type = type;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
getType() {
|
|
97
|
+
return this.type;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
toString() {
|
|
101
|
+
return this.name;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
substitute(x, e) {
|
|
105
|
+
if (this.name === x) return e;
|
|
106
|
+
return this;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
freeVars() {
|
|
110
|
+
return new Set([this.name]);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Constant (prime number) expression
|
|
116
|
+
*/
|
|
117
|
+
class ConstExpr extends LambdaExpr {
|
|
118
|
+
constructor(value) {
|
|
119
|
+
super();
|
|
120
|
+
this.value = value;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
getType() {
|
|
124
|
+
return { kind: 'const', value: this.value };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
toString() {
|
|
128
|
+
return String(this.value);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
isValue() {
|
|
132
|
+
return true;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
substitute(x, e) {
|
|
136
|
+
return this;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* Lambda abstraction: λx.body
|
|
142
|
+
*/
|
|
143
|
+
class LamExpr extends LambdaExpr {
|
|
144
|
+
constructor(param, body, paramType = null) {
|
|
145
|
+
super();
|
|
146
|
+
this.param = param;
|
|
147
|
+
this.body = body;
|
|
148
|
+
this.paramType = paramType;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
getType() {
|
|
152
|
+
return {
|
|
153
|
+
kind: 'function',
|
|
154
|
+
paramType: this.paramType,
|
|
155
|
+
returnType: this.body.getType()
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
toString() {
|
|
160
|
+
const typeAnnotation = this.paramType ? `:${JSON.stringify(this.paramType)}` : '';
|
|
161
|
+
return `(λ${this.param}${typeAnnotation}.${this.body})`;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
isValue() {
|
|
165
|
+
return true; // Lambdas are values
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
substitute(x, e) {
|
|
169
|
+
if (this.param === x) {
|
|
170
|
+
// x is bound here, no substitution in body
|
|
171
|
+
return this;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Check for variable capture
|
|
175
|
+
const freeInE = e.freeVars();
|
|
176
|
+
if (freeInE.has(this.param)) {
|
|
177
|
+
// Alpha-rename to avoid capture
|
|
178
|
+
const fresh = this.freshVar(this.param);
|
|
179
|
+
const renamedBody = this.body.substitute(this.param, new VarExpr(fresh));
|
|
180
|
+
return new LamExpr(fresh, renamedBody.substitute(x, e), this.paramType);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
return new LamExpr(this.param, this.body.substitute(x, e), this.paramType);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
freeVars() {
|
|
187
|
+
const vars = this.body.freeVars();
|
|
188
|
+
vars.delete(this.param);
|
|
189
|
+
return vars;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
freshVar(base) {
|
|
193
|
+
return `${base}'`;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Application expression: e1 e2
|
|
199
|
+
*/
|
|
200
|
+
class AppExpr extends LambdaExpr {
|
|
201
|
+
constructor(func, arg) {
|
|
202
|
+
super();
|
|
203
|
+
this.func = func;
|
|
204
|
+
this.arg = arg;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
getType() {
|
|
208
|
+
const funcType = this.func.getType();
|
|
209
|
+
if (funcType && funcType.kind === 'function') {
|
|
210
|
+
return funcType.returnType;
|
|
211
|
+
}
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
toString() {
|
|
216
|
+
return `(${this.func} ${this.arg})`;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
substitute(x, e) {
|
|
220
|
+
return new AppExpr(
|
|
221
|
+
this.func.substitute(x, e),
|
|
222
|
+
this.arg.substitute(x, e)
|
|
223
|
+
);
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
freeVars() {
|
|
227
|
+
const vars = this.func.freeVars();
|
|
228
|
+
for (const v of this.arg.freeVars()) {
|
|
229
|
+
vars.add(v);
|
|
230
|
+
}
|
|
231
|
+
return vars;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Pair expression: (e1, e2) for sentence composition
|
|
237
|
+
*/
|
|
238
|
+
class PairExpr extends LambdaExpr {
|
|
239
|
+
constructor(left, right) {
|
|
240
|
+
super();
|
|
241
|
+
this.left = left;
|
|
242
|
+
this.right = right;
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
getType() {
|
|
246
|
+
return {
|
|
247
|
+
kind: 'pair',
|
|
248
|
+
leftType: this.left.getType(),
|
|
249
|
+
rightType: this.right.getType()
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
toString() {
|
|
254
|
+
return `⟨${this.left}, ${this.right}⟩`;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
isValue() {
|
|
258
|
+
return this.left.isValue() && this.right.isValue();
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
substitute(x, e) {
|
|
262
|
+
return new PairExpr(
|
|
263
|
+
this.left.substitute(x, e),
|
|
264
|
+
this.right.substitute(x, e)
|
|
265
|
+
);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
freeVars() {
|
|
269
|
+
const vars = this.left.freeVars();
|
|
270
|
+
for (const v of this.right.freeVars()) {
|
|
271
|
+
vars.add(v);
|
|
272
|
+
}
|
|
273
|
+
return vars;
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Implication expression: e1 → e2
|
|
279
|
+
*/
|
|
280
|
+
class ImplExpr extends LambdaExpr {
|
|
281
|
+
constructor(antecedent, consequent) {
|
|
282
|
+
super();
|
|
283
|
+
this.antecedent = antecedent;
|
|
284
|
+
this.consequent = consequent;
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
getType() {
|
|
288
|
+
return {
|
|
289
|
+
kind: 'implication',
|
|
290
|
+
anteType: this.antecedent.getType(),
|
|
291
|
+
consType: this.consequent.getType()
|
|
292
|
+
};
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
toString() {
|
|
296
|
+
return `(${this.antecedent} → ${this.consequent})`;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
isValue() {
|
|
300
|
+
return this.antecedent.isValue() && this.consequent.isValue();
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
substitute(x, e) {
|
|
304
|
+
return new ImplExpr(
|
|
305
|
+
this.antecedent.substitute(x, e),
|
|
306
|
+
this.consequent.substitute(x, e)
|
|
307
|
+
);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
freeVars() {
|
|
311
|
+
const vars = this.antecedent.freeVars();
|
|
312
|
+
for (const v of this.consequent.freeVars()) {
|
|
313
|
+
vars.add(v);
|
|
314
|
+
}
|
|
315
|
+
return vars;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
/**
|
|
320
|
+
* Primitive operator application: ⊕(p, q)
|
|
321
|
+
*/
|
|
322
|
+
class PrimOpExpr extends LambdaExpr {
|
|
323
|
+
constructor(op, left, right) {
|
|
324
|
+
super();
|
|
325
|
+
this.op = op; // String name of operator
|
|
326
|
+
this.left = left;
|
|
327
|
+
this.right = right;
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
getType() {
|
|
331
|
+
return { kind: 'prime' };
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
toString() {
|
|
335
|
+
return `(${this.left} ⊕ ${this.right})`;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
substitute(x, e) {
|
|
339
|
+
return new PrimOpExpr(
|
|
340
|
+
this.op,
|
|
341
|
+
this.left.substitute(x, e),
|
|
342
|
+
this.right.substitute(x, e)
|
|
343
|
+
);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
freeVars() {
|
|
347
|
+
const vars = this.left.freeVars();
|
|
348
|
+
for (const v of this.right.freeVars()) {
|
|
349
|
+
vars.add(v);
|
|
350
|
+
}
|
|
351
|
+
return vars;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
// ============================================================================
|
|
356
|
+
// τ TRANSLATION FUNCTION
|
|
357
|
+
// ============================================================================
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Translator - Implements the τ function from Section 4
|
|
361
|
+
*/
|
|
362
|
+
class Translator {
|
|
363
|
+
constructor(operator = DEFAULT_OPERATOR) {
|
|
364
|
+
this.operator = operator;
|
|
365
|
+
this.varCounter = 0;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Generate a fresh variable name
|
|
370
|
+
*/
|
|
371
|
+
freshVar() {
|
|
372
|
+
return `x${this.varCounter++}`;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/**
|
|
376
|
+
* τ: Term → LambdaExpr
|
|
377
|
+
* Main translation function
|
|
378
|
+
*/
|
|
379
|
+
translate(term) {
|
|
380
|
+
// τ(N(p)) = p (constant)
|
|
381
|
+
if (term instanceof NounTerm) {
|
|
382
|
+
return new ConstExpr(term.prime);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
// τ(A(p)) = λf.λx.⊕(p, f(x))
|
|
386
|
+
// Simplified: λx.⊕(p, x)
|
|
387
|
+
if (term instanceof AdjTerm) {
|
|
388
|
+
const x = this.freshVar();
|
|
389
|
+
return new LamExpr(
|
|
390
|
+
x,
|
|
391
|
+
new PrimOpExpr('⊕', new ConstExpr(term.prime), new VarExpr(x)),
|
|
392
|
+
{ kind: 'prime' }
|
|
393
|
+
);
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// τ(FUSE(p,q,r)) = p+q+r (constant)
|
|
397
|
+
if (term instanceof FusionTerm) {
|
|
398
|
+
return new ConstExpr(term.getFusedPrime());
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
// τ(A(p₁)...A(pₖ)N(q)) = ((τ(A(p₁)) ... (τ(A(pₖ)) τ(N(q))))
|
|
402
|
+
if (term instanceof ChainTerm) {
|
|
403
|
+
// Start with the noun
|
|
404
|
+
let result = this.translate(term.noun);
|
|
405
|
+
|
|
406
|
+
// Apply operators from innermost (rightmost) to outermost (leftmost)
|
|
407
|
+
for (let i = term.operators.length - 1; i >= 0; i--) {
|
|
408
|
+
const op = term.operators[i];
|
|
409
|
+
const opLambda = this.translate(op);
|
|
410
|
+
result = new AppExpr(opLambda, result);
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
return result;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
// τ(NounSentence(e)) = τ(e)
|
|
417
|
+
if (term instanceof NounSentence) {
|
|
418
|
+
return this.translate(term.expr);
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// τ(S₁ ◦ S₂) = ⟨τ(S₁), τ(S₂)⟩
|
|
422
|
+
if (term instanceof SeqSentence) {
|
|
423
|
+
return new PairExpr(
|
|
424
|
+
this.translate(term.left),
|
|
425
|
+
this.translate(term.right)
|
|
426
|
+
);
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
// τ(S₁ ⇒ S₂) = τ(S₁) → τ(S₂)
|
|
430
|
+
if (term instanceof ImplSentence) {
|
|
431
|
+
return new ImplExpr(
|
|
432
|
+
this.translate(term.antecedent),
|
|
433
|
+
this.translate(term.consequent)
|
|
434
|
+
);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
throw new Error(`Cannot translate: ${term}`);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
/**
|
|
441
|
+
* Translate and show the translation steps
|
|
442
|
+
*/
|
|
443
|
+
translateWithTrace(term) {
|
|
444
|
+
const result = this.translate(term);
|
|
445
|
+
return {
|
|
446
|
+
source: term.signature(),
|
|
447
|
+
target: result.toString(),
|
|
448
|
+
type: result.getType()
|
|
449
|
+
};
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// ============================================================================
|
|
454
|
+
// λ-CALCULUS EVALUATOR
|
|
455
|
+
// ============================================================================
|
|
456
|
+
|
|
457
|
+
/**
|
|
458
|
+
* Call-by-value evaluator for λ-expressions
|
|
459
|
+
*/
|
|
460
|
+
class LambdaEvaluator {
|
|
461
|
+
constructor(operator = DEFAULT_OPERATOR) {
|
|
462
|
+
this.operator = operator;
|
|
463
|
+
this.maxSteps = 1000;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
/**
|
|
467
|
+
* Evaluate one step (small-step semantics)
|
|
468
|
+
*/
|
|
469
|
+
step(expr) {
|
|
470
|
+
// Application of lambda to value: (λx.e) v → e[x := v]
|
|
471
|
+
if (expr instanceof AppExpr) {
|
|
472
|
+
// First evaluate function to value
|
|
473
|
+
if (!expr.func.isValue()) {
|
|
474
|
+
const newFunc = this.step(expr.func);
|
|
475
|
+
if (newFunc) {
|
|
476
|
+
return new AppExpr(newFunc, expr.arg);
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
// Then evaluate argument to value
|
|
481
|
+
if (!expr.arg.isValue()) {
|
|
482
|
+
const newArg = this.step(expr.arg);
|
|
483
|
+
if (newArg) {
|
|
484
|
+
return new AppExpr(expr.func, newArg);
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// Both are values, perform β-reduction
|
|
489
|
+
if (expr.func instanceof LamExpr && expr.arg.isValue()) {
|
|
490
|
+
return expr.func.body.substitute(expr.func.param, expr.arg);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
// Primitive operator application
|
|
495
|
+
if (expr instanceof PrimOpExpr) {
|
|
496
|
+
// Evaluate operands first
|
|
497
|
+
if (!expr.left.isValue()) {
|
|
498
|
+
const newLeft = this.step(expr.left);
|
|
499
|
+
if (newLeft) {
|
|
500
|
+
return new PrimOpExpr(expr.op, newLeft, expr.right);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
if (!expr.right.isValue()) {
|
|
505
|
+
const newRight = this.step(expr.right);
|
|
506
|
+
if (newRight) {
|
|
507
|
+
return new PrimOpExpr(expr.op, expr.left, newRight);
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Both values, apply operator
|
|
512
|
+
if (expr.left instanceof ConstExpr && expr.right instanceof ConstExpr) {
|
|
513
|
+
const p = expr.left.value;
|
|
514
|
+
const q = expr.right.value;
|
|
515
|
+
if (this.operator.canApply(p, q)) {
|
|
516
|
+
const result = this.operator.apply(p, q);
|
|
517
|
+
return new ConstExpr(result);
|
|
518
|
+
} else if (this.operator.canApply(q, p)) {
|
|
519
|
+
const result = this.operator.apply(q, p);
|
|
520
|
+
return new ConstExpr(result);
|
|
521
|
+
}
|
|
522
|
+
// If neither ordering works, just return the larger value
|
|
523
|
+
return new ConstExpr(Math.max(p, q));
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Pair reduction
|
|
528
|
+
if (expr instanceof PairExpr) {
|
|
529
|
+
if (!expr.left.isValue()) {
|
|
530
|
+
const newLeft = this.step(expr.left);
|
|
531
|
+
if (newLeft) {
|
|
532
|
+
return new PairExpr(newLeft, expr.right);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
if (!expr.right.isValue()) {
|
|
537
|
+
const newRight = this.step(expr.right);
|
|
538
|
+
if (newRight) {
|
|
539
|
+
return new PairExpr(expr.left, newRight);
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
// Implication reduction
|
|
545
|
+
if (expr instanceof ImplExpr) {
|
|
546
|
+
if (!expr.antecedent.isValue()) {
|
|
547
|
+
const newAnte = this.step(expr.antecedent);
|
|
548
|
+
if (newAnte) {
|
|
549
|
+
return new ImplExpr(newAnte, expr.consequent);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
if (!expr.consequent.isValue()) {
|
|
554
|
+
const newCons = this.step(expr.consequent);
|
|
555
|
+
if (newCons) {
|
|
556
|
+
return new ImplExpr(expr.antecedent, newCons);
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
|
|
561
|
+
return null;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
/**
|
|
565
|
+
* Fully evaluate expression to value
|
|
566
|
+
*/
|
|
567
|
+
evaluate(expr) {
|
|
568
|
+
let current = expr;
|
|
569
|
+
let steps = 0;
|
|
570
|
+
|
|
571
|
+
while (steps < this.maxSteps) {
|
|
572
|
+
const next = this.step(current);
|
|
573
|
+
if (!next) break;
|
|
574
|
+
current = next;
|
|
575
|
+
steps++;
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
return {
|
|
579
|
+
result: current,
|
|
580
|
+
steps,
|
|
581
|
+
isValue: current.isValue()
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// ============================================================================
|
|
587
|
+
// COMPOSITIONAL SEMANTICS
|
|
588
|
+
// ============================================================================
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* Denotational semantics via λ-calculus interpretation
|
|
592
|
+
*/
|
|
593
|
+
class Semantics {
|
|
594
|
+
constructor(operator = DEFAULT_OPERATOR) {
|
|
595
|
+
this.translator = new Translator(operator);
|
|
596
|
+
this.evaluator = new LambdaEvaluator(operator);
|
|
597
|
+
this.reducer = new ReductionSystem(operator);
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/**
|
|
601
|
+
* Get the denotation of a term
|
|
602
|
+
* [[e]] = evaluate(τ(e))
|
|
603
|
+
*/
|
|
604
|
+
denote(term) {
|
|
605
|
+
const lambda = this.translator.translate(term);
|
|
606
|
+
const result = this.evaluator.evaluate(lambda);
|
|
607
|
+
return result.result;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/**
|
|
611
|
+
* Check semantic equivalence
|
|
612
|
+
* [[e₁]] = [[e₂]]
|
|
613
|
+
*/
|
|
614
|
+
equivalent(term1, term2) {
|
|
615
|
+
const d1 = this.denote(term1);
|
|
616
|
+
const d2 = this.denote(term2);
|
|
617
|
+
|
|
618
|
+
if (d1 instanceof ConstExpr && d2 instanceof ConstExpr) {
|
|
619
|
+
return d1.value === d2.value;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
return d1.toString() === d2.toString();
|
|
623
|
+
}
|
|
624
|
+
|
|
625
|
+
/**
|
|
626
|
+
* Verify operational and denotational semantics agree
|
|
627
|
+
* Theorem: If e →* v in operational semantics, then [[e]] = v
|
|
628
|
+
*/
|
|
629
|
+
verifySemanticEquivalence(term) {
|
|
630
|
+
// Get operational result
|
|
631
|
+
const opResult = this.reducer.evaluate(term);
|
|
632
|
+
|
|
633
|
+
// Get denotational result
|
|
634
|
+
const denResult = this.denote(term);
|
|
635
|
+
|
|
636
|
+
// Compare
|
|
637
|
+
let equivalent = false;
|
|
638
|
+
if (opResult instanceof NounTerm && denResult instanceof ConstExpr) {
|
|
639
|
+
equivalent = opResult.prime === denResult.value;
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
return {
|
|
643
|
+
term: term.signature(),
|
|
644
|
+
operational: opResult instanceof NounTerm ? opResult.prime : opResult.signature(),
|
|
645
|
+
denotational: denResult instanceof ConstExpr ? denResult.value : denResult.toString(),
|
|
646
|
+
equivalent
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
// ============================================================================
|
|
652
|
+
// INTERPRETATION (Section 5 - Prime → Concept mapping)
|
|
653
|
+
// ============================================================================
|
|
654
|
+
|
|
655
|
+
/**
|
|
656
|
+
* ConceptInterpreter - Maps primes to semantic concepts
|
|
657
|
+
*/
|
|
658
|
+
class ConceptInterpreter {
|
|
659
|
+
constructor() {
|
|
660
|
+
// Default concept mappings (can be customized)
|
|
661
|
+
this.nounConcepts = new Map([
|
|
662
|
+
[2, 'existence'],
|
|
663
|
+
[3, 'unity'],
|
|
664
|
+
[5, 'life'],
|
|
665
|
+
[7, 'truth'],
|
|
666
|
+
[11, 'consciousness'],
|
|
667
|
+
[13, 'knowledge'],
|
|
668
|
+
[17, 'wisdom'],
|
|
669
|
+
[19, 'love'],
|
|
670
|
+
[23, 'creation'],
|
|
671
|
+
[29, 'infinity']
|
|
672
|
+
]);
|
|
673
|
+
|
|
674
|
+
this.adjConcepts = new Map([
|
|
675
|
+
[2, 'dual'],
|
|
676
|
+
[3, 'triple'],
|
|
677
|
+
[5, 'vital'],
|
|
678
|
+
[7, 'true'],
|
|
679
|
+
[11, 'conscious'],
|
|
680
|
+
[13, 'knowing'],
|
|
681
|
+
[17, 'wise'],
|
|
682
|
+
[19, 'loving'],
|
|
683
|
+
[23, 'creative'],
|
|
684
|
+
[29, 'infinite']
|
|
685
|
+
]);
|
|
686
|
+
}
|
|
687
|
+
|
|
688
|
+
/**
|
|
689
|
+
* Interpret a noun term as concept
|
|
690
|
+
*/
|
|
691
|
+
interpretNoun(term) {
|
|
692
|
+
if (!(term instanceof NounTerm)) {
|
|
693
|
+
throw new Error('Expected NounTerm');
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
const p = term.prime;
|
|
697
|
+
if (this.nounConcepts.has(p)) {
|
|
698
|
+
return this.nounConcepts.get(p);
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// Generate description for unknown primes
|
|
702
|
+
return `concept_${p}`;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
/**
|
|
706
|
+
* Interpret an adjective term as modifier
|
|
707
|
+
*/
|
|
708
|
+
interpretAdj(term) {
|
|
709
|
+
if (!(term instanceof AdjTerm)) {
|
|
710
|
+
throw new Error('Expected AdjTerm');
|
|
711
|
+
}
|
|
712
|
+
|
|
713
|
+
const p = term.prime;
|
|
714
|
+
if (this.adjConcepts.has(p)) {
|
|
715
|
+
return this.adjConcepts.get(p);
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
return `modifier_${p}`;
|
|
719
|
+
}
|
|
720
|
+
|
|
721
|
+
/**
|
|
722
|
+
* Interpret a chain as modified concept
|
|
723
|
+
*/
|
|
724
|
+
interpretChain(term) {
|
|
725
|
+
if (!(term instanceof ChainTerm)) {
|
|
726
|
+
throw new Error('Expected ChainTerm');
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
const noun = this.interpretNoun(term.noun);
|
|
730
|
+
const adjs = term.operators.map(op => this.interpretAdj(op));
|
|
731
|
+
|
|
732
|
+
// Build phrase: adj1 adj2 ... noun
|
|
733
|
+
return [...adjs, noun].join(' ');
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* Full interpretation of any term
|
|
738
|
+
*/
|
|
739
|
+
interpret(term) {
|
|
740
|
+
if (term instanceof NounTerm) {
|
|
741
|
+
return this.interpretNoun(term);
|
|
742
|
+
}
|
|
743
|
+
if (term instanceof AdjTerm) {
|
|
744
|
+
return this.interpretAdj(term);
|
|
745
|
+
}
|
|
746
|
+
if (term instanceof ChainTerm) {
|
|
747
|
+
return this.interpretChain(term);
|
|
748
|
+
}
|
|
749
|
+
if (term instanceof FusionTerm) {
|
|
750
|
+
return `fusion(${term.p},${term.q},${term.r})`;
|
|
751
|
+
}
|
|
752
|
+
if (term instanceof NounSentence) {
|
|
753
|
+
return `[${this.interpret(term.expr)}]`;
|
|
754
|
+
}
|
|
755
|
+
if (term instanceof SeqSentence) {
|
|
756
|
+
return `${this.interpret(term.left)} and ${this.interpret(term.right)}`;
|
|
757
|
+
}
|
|
758
|
+
if (term instanceof ImplSentence) {
|
|
759
|
+
return `if ${this.interpret(term.antecedent)} then ${this.interpret(term.consequent)}`;
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
return String(term);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* Add custom concept mappings
|
|
767
|
+
*/
|
|
768
|
+
addNounConcept(prime, concept) {
|
|
769
|
+
this.nounConcepts.set(prime, concept);
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
addAdjConcept(prime, concept) {
|
|
773
|
+
this.adjConcepts.set(prime, concept);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
// ============================================================================
|
|
778
|
+
// TYPE-DIRECTED TRANSLATION
|
|
779
|
+
// ============================================================================
|
|
780
|
+
|
|
781
|
+
/**
|
|
782
|
+
* TypeDirectedTranslator - Translation with type constraints
|
|
783
|
+
*/
|
|
784
|
+
class TypeDirectedTranslator extends Translator {
|
|
785
|
+
constructor(operator = DEFAULT_OPERATOR) {
|
|
786
|
+
super(operator);
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
/**
|
|
790
|
+
* Translate with explicit type annotations
|
|
791
|
+
*/
|
|
792
|
+
translateTyped(term, context = null) {
|
|
793
|
+
const lambda = this.translate(term);
|
|
794
|
+
|
|
795
|
+
// Annotate with source type information
|
|
796
|
+
return {
|
|
797
|
+
expr: lambda,
|
|
798
|
+
sourceType: term.constructor.name,
|
|
799
|
+
targetType: lambda.getType(),
|
|
800
|
+
context: context
|
|
801
|
+
};
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
/**
|
|
805
|
+
* Check type preservation
|
|
806
|
+
* τ preserves typing: Γ ⊢ e : T implies τ(Γ) ⊢ τ(e) : τ(T)
|
|
807
|
+
*/
|
|
808
|
+
checkTypePreservation(term, context = null) {
|
|
809
|
+
const translation = this.translateTyped(term, context);
|
|
810
|
+
|
|
811
|
+
// Verify the translated type matches expected
|
|
812
|
+
return {
|
|
813
|
+
preserved: translation.targetType !== null,
|
|
814
|
+
source: translation.sourceType,
|
|
815
|
+
target: translation.targetType
|
|
816
|
+
};
|
|
817
|
+
}
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
// ============================================================================
|
|
821
|
+
// EXPORTS
|
|
822
|
+
// ============================================================================
|
|
823
|
+
|
|
824
|
+
module.exports = {
|
|
825
|
+
// Lambda expressions
|
|
826
|
+
LambdaExpr,
|
|
827
|
+
VarExpr,
|
|
828
|
+
ConstExpr,
|
|
829
|
+
LamExpr,
|
|
830
|
+
AppExpr,
|
|
831
|
+
PairExpr,
|
|
832
|
+
ImplExpr,
|
|
833
|
+
PrimOpExpr,
|
|
834
|
+
|
|
835
|
+
// Translator
|
|
836
|
+
Translator,
|
|
837
|
+
TypeDirectedTranslator,
|
|
838
|
+
|
|
839
|
+
// Evaluator
|
|
840
|
+
LambdaEvaluator,
|
|
841
|
+
|
|
842
|
+
// Semantics
|
|
843
|
+
Semantics,
|
|
844
|
+
ConceptInterpreter
|
|
845
|
+
};
|