@dallaylaen/ski-interpreter 2.6.2 → 2.7.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/CHANGELOG.md +31 -0
- package/README.md +2 -0
- package/bin/ski.js +5 -1
- package/lib/ski-interpreter.cjs.js +181 -13906
- package/lib/ski-interpreter.cjs.js.map +4 -4
- package/lib/ski-interpreter.min.js +6 -45
- package/lib/ski-interpreter.min.js.map +4 -4
- package/lib/ski-interpreter.mjs +181 -13912
- package/lib/ski-interpreter.mjs.map +4 -4
- package/lib/ski-quest.min.js +6 -45
- package/lib/ski-quest.min.js.map +4 -4
- package/lib/types/expr.d.ts +187 -164
- package/lib/types/extras.d.ts +17 -7
- package/lib/types/index.d.ts +7 -36
- package/lib/types/internal.d.ts +5 -5
- package/lib/types/parser.d.ts +6 -6
- package/lib/types/quest.d.ts +77 -44
- package/lib/types/toposort.d.ts +2 -3
- package/package.json +5 -3
package/lib/types/expr.d.ts
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { z } from 'zod';
|
|
2
1
|
import { TraverseValue } from './internal';
|
|
3
2
|
/**
|
|
4
|
-
*
|
|
3
|
+
* Control primitives for fold() and traverse() methods.
|
|
5
4
|
*/
|
|
6
5
|
export declare const control: {
|
|
7
6
|
descend: <T>(value?: T) => import("./internal").TraverseControl<T>;
|
|
@@ -10,7 +9,7 @@ export declare const control: {
|
|
|
10
9
|
stop: <T>(value?: T) => import("./internal").TraverseControl<T>;
|
|
11
10
|
};
|
|
12
11
|
/**
|
|
13
|
-
*
|
|
12
|
+
* List of predefined native combinators.
|
|
14
13
|
* This is required for toSKI() to work, otherwise could as well have been in parser.js.
|
|
15
14
|
*/
|
|
16
15
|
export declare const native: Record<string, Native>;
|
|
@@ -42,20 +41,19 @@ export type RunOptions = {
|
|
|
42
41
|
throw?: boolean;
|
|
43
42
|
maxSize?: number;
|
|
44
43
|
};
|
|
45
|
-
export
|
|
46
|
-
terse
|
|
47
|
-
html
|
|
48
|
-
brackets
|
|
49
|
-
space
|
|
50
|
-
var
|
|
51
|
-
lambda
|
|
52
|
-
around
|
|
53
|
-
redex
|
|
54
|
-
inventory
|
|
55
|
-
}
|
|
56
|
-
export type FormatOptions = z.infer<typeof FormatOptionsSchema>;
|
|
44
|
+
export type FormatOptions = {
|
|
45
|
+
terse?: boolean;
|
|
46
|
+
html?: boolean;
|
|
47
|
+
brackets?: [string, string];
|
|
48
|
+
space?: string;
|
|
49
|
+
var?: [string, string];
|
|
50
|
+
lambda?: [string, string, string];
|
|
51
|
+
around?: [string, string];
|
|
52
|
+
redex?: [string, string];
|
|
53
|
+
inventory?: Record<string, Expr>;
|
|
54
|
+
};
|
|
57
55
|
/**
|
|
58
|
-
*
|
|
56
|
+
* A version of FormatOptions with defaults plugged in,
|
|
59
57
|
* use for mandatory formatImpl implementation in Expr subclasses.
|
|
60
58
|
*/
|
|
61
59
|
export type RefinedFormatOptions = {
|
|
@@ -69,43 +67,43 @@ export type RefinedFormatOptions = {
|
|
|
69
67
|
redex: [string, string];
|
|
70
68
|
inventory?: Record<string, Expr>;
|
|
71
69
|
};
|
|
72
|
-
type TraverseOptions = {
|
|
70
|
+
export type TraverseOptions = {
|
|
73
71
|
order?: 'LO' | 'LI' | 'leftmost-outermost' | 'leftmost-innermost';
|
|
74
72
|
};
|
|
75
|
-
type TraverseCallback = (e: Expr) => TraverseValue<Expr>;
|
|
73
|
+
export type TraverseCallback = (e: Expr) => TraverseValue<Expr>;
|
|
74
|
+
/**
|
|
75
|
+
* A combinatory logic expression.
|
|
76
|
+
*
|
|
77
|
+
* Applications, variables, lambdas, combinators per se,
|
|
78
|
+
* and other expression subtypes all extend this class.
|
|
79
|
+
*
|
|
80
|
+
* Expr itself cannot (or at least should not) be instantiated.
|
|
81
|
+
*
|
|
82
|
+
* @abstract
|
|
83
|
+
*/
|
|
76
84
|
export declare abstract class Expr {
|
|
77
|
-
/**
|
|
78
|
-
* @desc A combinatory logic expression.
|
|
79
|
-
*
|
|
80
|
-
* Applications, variables, lambdas, combinators per se,
|
|
81
|
-
* and other expression subtypes all extend this class.
|
|
82
|
-
*
|
|
83
|
-
* Expr itself cannot (or at least should not) be instantiated.
|
|
84
|
-
*
|
|
85
|
-
* @abstract
|
|
86
|
-
*/
|
|
87
|
-
/** @desc optional context for the term. Is set by the parser with addContext: true */
|
|
85
|
+
/** optional context for the term. Is set by the parser with addContext: true */
|
|
88
86
|
context?: {
|
|
89
87
|
scope?: object;
|
|
90
88
|
env?: Record<string, Expr>;
|
|
91
89
|
src?: string;
|
|
92
90
|
parser: object;
|
|
93
91
|
};
|
|
94
|
-
/**
|
|
92
|
+
/** number of arguments the term is waiting for (if known) */
|
|
95
93
|
arity?: number;
|
|
96
|
-
/**
|
|
94
|
+
/** a brief description what the term does */
|
|
97
95
|
note?: string;
|
|
98
|
-
/**
|
|
96
|
+
/** the properties of the term, typically inferred from its behavior.
|
|
99
97
|
* This is used internally when declaring Native / Alias terms.
|
|
100
98
|
*/
|
|
101
99
|
props?: TermInfo;
|
|
102
|
-
/**
|
|
100
|
+
/** An estimated number of nodes in the expression tree.
|
|
103
101
|
* Used to prevent runaway computations.
|
|
104
102
|
*/
|
|
105
103
|
size?: number;
|
|
106
104
|
/**
|
|
107
105
|
*
|
|
108
|
-
*
|
|
106
|
+
* Define properties of the term based on user supplied options and/or inference results.
|
|
109
107
|
* Typically useful for declaring Native and Alias terms.
|
|
110
108
|
* @protected
|
|
111
109
|
* @param {Object} options
|
|
@@ -126,19 +124,19 @@ export declare abstract class Expr {
|
|
|
126
124
|
maxArgs?: number;
|
|
127
125
|
}): this;
|
|
128
126
|
/**
|
|
129
|
-
*
|
|
127
|
+
* apply self to zero or more terms and return the resulting term,
|
|
130
128
|
* without performing any calculations whatsoever
|
|
131
129
|
* @param {Expr} args
|
|
132
130
|
* @return {Expr}
|
|
133
131
|
*/
|
|
134
132
|
apply(...args: Expr[]): Expr;
|
|
135
133
|
/**
|
|
136
|
-
*
|
|
134
|
+
* Replace all aliases in the expression with their definitions, recursively.
|
|
137
135
|
* @return {Expr}
|
|
138
136
|
*/
|
|
139
137
|
expand(): Expr;
|
|
140
138
|
/**
|
|
141
|
-
*
|
|
139
|
+
* Traverse the expression tree, applying change() to each node.
|
|
142
140
|
* If change() returns an Expr, the node is replaced with that value.
|
|
143
141
|
* A null/undefined value is interpreted as
|
|
144
142
|
* "descend further if applicable, or leave the node unchanged".
|
|
@@ -162,18 +160,22 @@ export declare abstract class Expr {
|
|
|
162
160
|
* }} [options]
|
|
163
161
|
* @param {(e:Expr) => TraverseValue<Expr>} change
|
|
164
162
|
* @returns {Expr|null}
|
|
165
|
-
* @
|
|
163
|
+
* @sealed
|
|
166
164
|
*/
|
|
167
165
|
traverse(options: TraverseOptions | TraverseCallback, change?: TraverseCallback): Expr | null;
|
|
168
166
|
/**
|
|
167
|
+
*
|
|
168
|
+
*
|
|
169
169
|
* @protected
|
|
170
|
-
*
|
|
170
|
+
*
|
|
171
171
|
* @param {Object} options
|
|
172
172
|
* @param {(e:Expr) => TraverseValue<Expr>} change
|
|
173
173
|
* @returns {TraverseValue<Expr>}
|
|
174
174
|
*/
|
|
175
175
|
_traverse_redo(options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr>;
|
|
176
176
|
/**
|
|
177
|
+
* Apply a {@link traverse} callback to the subterms of the expression, without changing the expression itself.
|
|
178
|
+
*
|
|
177
179
|
* @protected
|
|
178
180
|
* @param {Object} options
|
|
179
181
|
* @param {(e:Expr) => TraverseValue<Expr>} change
|
|
@@ -181,14 +183,14 @@ export declare abstract class Expr {
|
|
|
181
183
|
*/
|
|
182
184
|
_traverse_descend(options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr>;
|
|
183
185
|
/**
|
|
184
|
-
*
|
|
186
|
+
* Returns true if predicate() is true for any subterm of the expression, false otherwise.
|
|
185
187
|
*
|
|
186
188
|
* @param {(e: Expr) => boolean} predicate
|
|
187
189
|
* @returns {boolean}
|
|
188
190
|
*/
|
|
189
191
|
any(predicate: (e: Expr) => boolean): boolean;
|
|
190
192
|
/**
|
|
191
|
-
*
|
|
193
|
+
* Fold the expression into a single value by recursively applying combine() to its subterms.
|
|
192
194
|
* Nodes are traversed in leftmost-outermost order, i.e. the same order as reduction steps are taken.
|
|
193
195
|
*
|
|
194
196
|
* null or undefined return value from combine() means "keep current value and descend further".
|
|
@@ -204,7 +206,7 @@ export declare abstract class Expr {
|
|
|
204
206
|
* expr.fold(0, (acc, e) => acc + 1);
|
|
205
207
|
*
|
|
206
208
|
* @experimental
|
|
207
|
-
*
|
|
209
|
+
*
|
|
208
210
|
* @template T
|
|
209
211
|
* @param {T} initial
|
|
210
212
|
* @param {(acc: T, expr: Expr) => TraverseValue<T>} combine
|
|
@@ -212,7 +214,7 @@ export declare abstract class Expr {
|
|
|
212
214
|
*/
|
|
213
215
|
fold<T>(initial: T, combine: (acc: T, expr: Expr) => TraverseValue<T>): T;
|
|
214
216
|
/**
|
|
215
|
-
*
|
|
217
|
+
* Internal method for fold(), which performs the actual folding.
|
|
216
218
|
* Should be implemented in subclasses having any internal structure.
|
|
217
219
|
*
|
|
218
220
|
* @protected
|
|
@@ -222,7 +224,7 @@ export declare abstract class Expr {
|
|
|
222
224
|
_fold<T>(initial: T, combine: (acc: T, expr: Expr) => TraverseValue<T>): TraverseValue<T>;
|
|
223
225
|
/**
|
|
224
226
|
* @experimental
|
|
225
|
-
*
|
|
227
|
+
* Fold an application tree bottom to top.
|
|
226
228
|
* For each subtree, the function is given the term in the root position and
|
|
227
229
|
* a list of the results of folding its arguments.
|
|
228
230
|
*
|
|
@@ -246,7 +248,7 @@ export declare abstract class Expr {
|
|
|
246
248
|
*/
|
|
247
249
|
foldBottomUp<T>(fun: (head: Expr, tail: T[]) => T): T;
|
|
248
250
|
/**
|
|
249
|
-
*
|
|
251
|
+
* Try to empirically find an equivalent lambda term for the expression,
|
|
250
252
|
* returning also the term's arity and some other properties.
|
|
251
253
|
*
|
|
252
254
|
* This is used internally when declaring a Native / Alias term,
|
|
@@ -257,7 +259,7 @@ export declare abstract class Expr {
|
|
|
257
259
|
*
|
|
258
260
|
* Use toLambda() if you want to get a lambda term in any case.
|
|
259
261
|
*
|
|
260
|
-
* @
|
|
262
|
+
* @sealed
|
|
261
263
|
* @param {{max?: number, maxArgs?: number}} options
|
|
262
264
|
* @return {TermInfo}
|
|
263
265
|
*/
|
|
@@ -267,7 +269,7 @@ export declare abstract class Expr {
|
|
|
267
269
|
maxSize?: number;
|
|
268
270
|
}): TermInfo;
|
|
269
271
|
/**
|
|
270
|
-
*
|
|
272
|
+
* Internal method for infer(), which performs the actual inference.
|
|
271
273
|
* @param {{max: number, maxArgs: number}} options
|
|
272
274
|
* @param {number} nargs - var index to avoid name clashes
|
|
273
275
|
* @returns {TermInfo}
|
|
@@ -280,7 +282,7 @@ export declare abstract class Expr {
|
|
|
280
282
|
skipNames: Record<string, boolean>;
|
|
281
283
|
}, nargs: number): TermInfo;
|
|
282
284
|
/**
|
|
283
|
-
*
|
|
285
|
+
* Expand an expression into a list of terms
|
|
284
286
|
* that give the initial expression when applied from left to right:
|
|
285
287
|
* ((a, b), (c, d)) => [a, b, (c, d)]
|
|
286
288
|
*
|
|
@@ -292,7 +294,7 @@ export declare abstract class Expr {
|
|
|
292
294
|
*/
|
|
293
295
|
unroll(): Expr[];
|
|
294
296
|
/**
|
|
295
|
-
*
|
|
297
|
+
* Returns a series of lambda terms equivalent to the given expression,
|
|
296
298
|
* up to the provided computation steps limit.
|
|
297
299
|
*
|
|
298
300
|
* Unlike infer(), this method will always return something,
|
|
@@ -300,7 +302,7 @@ export declare abstract class Expr {
|
|
|
300
302
|
*
|
|
301
303
|
* See also Expr.walk() and Expr.toSKI().
|
|
302
304
|
*
|
|
303
|
-
* @
|
|
305
|
+
* @sealed
|
|
304
306
|
* @param {{
|
|
305
307
|
* max?: number,
|
|
306
308
|
* maxArgs?: number,
|
|
@@ -319,17 +321,20 @@ export declare abstract class Expr {
|
|
|
319
321
|
steps: number;
|
|
320
322
|
}, void, unknown>;
|
|
321
323
|
/**
|
|
322
|
-
*
|
|
324
|
+
* Rewrite the expression into S, K, and I combinators step by step.
|
|
323
325
|
* Returns an iterator yielding the intermediate expressions,
|
|
324
326
|
* along with the number of steps taken to reach them.
|
|
325
327
|
*
|
|
326
328
|
* See also Expr.walk() and Expr.toLambda().
|
|
327
329
|
*
|
|
328
|
-
* @
|
|
330
|
+
* @sealed
|
|
329
331
|
* @param {{max?: number}} [options]
|
|
330
332
|
* @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}
|
|
331
333
|
*/
|
|
332
|
-
toSKI(
|
|
334
|
+
toSKI(options?: {
|
|
335
|
+
max?: number;
|
|
336
|
+
maxArgs?: number;
|
|
337
|
+
}): Generator<{
|
|
333
338
|
expr: Expr;
|
|
334
339
|
steps: number;
|
|
335
340
|
final: boolean;
|
|
@@ -350,7 +355,7 @@ export declare abstract class Expr {
|
|
|
350
355
|
*/
|
|
351
356
|
subst(search: Expr, replace: Expr): Expr | null;
|
|
352
357
|
/**
|
|
353
|
-
*
|
|
358
|
+
* Apply term reduction rules, if any, to the given argument.
|
|
354
359
|
* A returned value of null means no reduction is possible.
|
|
355
360
|
* A returned value of Expr means the reduction is complete and the application
|
|
356
361
|
* of this and arg can be replaced with the result.
|
|
@@ -370,25 +375,33 @@ export declare abstract class Expr {
|
|
|
370
375
|
*/
|
|
371
376
|
invoke(arg: Expr): Invocation | null;
|
|
372
377
|
/**
|
|
373
|
-
*
|
|
378
|
+
* iterate one step of a calculation.
|
|
374
379
|
* @return {{expr: Expr, steps: number, changed: boolean}}
|
|
375
380
|
*/
|
|
376
381
|
step(): Step;
|
|
377
382
|
/**
|
|
378
|
-
* @
|
|
379
|
-
*
|
|
380
|
-
*
|
|
381
|
-
*
|
|
383
|
+
* Iteratively apply {@link step} to the expression until it's irreducible,
|
|
384
|
+
* or until the provided limits are reached.
|
|
385
|
+
*
|
|
386
|
+
* Returns { expr: Expr, steps: number, final: boolean }.
|
|
387
|
+
*
|
|
388
|
+
* If { throw: true } is given and no irreducible form was reached within the limits, an error is thrown.
|
|
389
|
+
*
|
|
390
|
+
* @sealed
|
|
382
391
|
* @param {{max?: number, steps?: number, throw?: boolean}|Expr} [opt]
|
|
383
392
|
* @param {Expr} args
|
|
384
393
|
* @return {{expr: Expr, steps: number, final: boolean}}
|
|
385
394
|
*/
|
|
386
395
|
run(opt?: RunOptions | Expr, ...args: Expr[]): Run;
|
|
387
396
|
/**
|
|
388
|
-
*
|
|
397
|
+
* Returns an iterator of reduction steps of the expression, up to the provided limits.
|
|
398
|
+
* Each step is an object of { expr, steps, final }, same as in {@link run}.
|
|
399
|
+
*
|
|
400
|
+
* Mnemonics: like {@link run} but slower.
|
|
401
|
+
*
|
|
402
|
+
* @remarks
|
|
403
|
+
* This method is final. Do not override, override {@link step} instead.
|
|
389
404
|
*
|
|
390
|
-
* Mnemonics: like run() but slower.
|
|
391
|
-
* @final
|
|
392
405
|
* @param {{max?: number}} options
|
|
393
406
|
* @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}
|
|
394
407
|
*/
|
|
@@ -397,20 +410,21 @@ export declare abstract class Expr {
|
|
|
397
410
|
maxSize?: number;
|
|
398
411
|
}): IterableIterator<Run>;
|
|
399
412
|
/**
|
|
400
|
-
*
|
|
413
|
+
* True is the expressions are identical, false otherwise.
|
|
401
414
|
* Aliases are expanded.
|
|
402
415
|
* Bound variables in lambda terms are renamed consistently.
|
|
403
416
|
* However, no reductions are attempted.
|
|
404
417
|
*
|
|
405
418
|
* E.g. a->b->a == x->y->x is true, but a->b->a == K is false.
|
|
406
419
|
*
|
|
420
|
+
* @remarks Final. Current implementation is a frontend to {@link diff}.
|
|
421
|
+
*
|
|
407
422
|
* @param {Expr} other
|
|
408
423
|
* @return {boolean}
|
|
409
|
-
* @final
|
|
410
424
|
*/
|
|
411
425
|
equals(other: Expr): boolean;
|
|
412
426
|
/**
|
|
413
|
-
*
|
|
427
|
+
* Recursively compare two expressions and return a string
|
|
414
428
|
* describing the first point of difference.
|
|
415
429
|
* Returns null if expressions are identical.
|
|
416
430
|
*
|
|
@@ -434,49 +448,51 @@ export declare abstract class Expr {
|
|
|
434
448
|
*/
|
|
435
449
|
diff(other: Expr, swap?: boolean): string | null;
|
|
436
450
|
/**
|
|
437
|
-
*
|
|
451
|
+
* Assert expression equality. Can be used in tests.
|
|
438
452
|
*
|
|
439
453
|
* `this` is the expected value and the argument is the actual one.
|
|
440
454
|
* Mnemonic: the expected value is always a combinator, the actual one may be anything.
|
|
441
455
|
*
|
|
442
456
|
* In case of failure, an error is thrown with a message describing the first point of difference
|
|
443
457
|
* and `expected` and `actual` properties like in AssertionError.
|
|
444
|
-
* AssertionError is not used directly
|
|
458
|
+
* AssertionError is not used directly because browsers don't recognize it.
|
|
445
459
|
*
|
|
446
|
-
* @
|
|
460
|
+
* @sealed
|
|
447
461
|
* @param {Expr} actual
|
|
448
462
|
* @param {string} comment
|
|
449
463
|
*/
|
|
450
464
|
expect(actual: Expr | object, comment?: string): void;
|
|
451
465
|
/**
|
|
452
|
-
*
|
|
466
|
+
* Returns string representation of the expression.
|
|
453
467
|
* Same as format() without options.
|
|
454
468
|
*
|
|
455
469
|
* Use formatImpl() to override in subclasses.
|
|
456
470
|
* @return {string}
|
|
457
|
-
* @
|
|
471
|
+
* @sealed
|
|
458
472
|
*/
|
|
459
473
|
toString(): string;
|
|
460
474
|
/**
|
|
461
|
-
*
|
|
462
|
-
* @
|
|
475
|
+
* Whether the expression needs to be parenthesized when printed in terse mode.
|
|
476
|
+
* (see {@link format})
|
|
477
|
+
* @param isFirst whether this is the first term in a sequence
|
|
463
478
|
* @return {boolean}
|
|
464
479
|
* @protected
|
|
465
480
|
*/
|
|
466
|
-
_braced(
|
|
481
|
+
_braced(isFirst?: boolean): boolean;
|
|
467
482
|
/**
|
|
468
|
-
*
|
|
483
|
+
* Whether the expression can be printed without a space when followed by arg.
|
|
469
484
|
* @param {Expr} arg
|
|
470
485
|
* @returns {boolean}
|
|
471
486
|
* @protected
|
|
472
487
|
*/
|
|
473
488
|
_unspaced(arg: Expr): boolean;
|
|
474
489
|
/**
|
|
475
|
-
*
|
|
490
|
+
* Stringify the expression with fancy formatting options.
|
|
476
491
|
* Said options mostly include wrappers around various constructs in form of ['(', ')'],
|
|
477
492
|
* as well as `terse` and `html` flags that fill in appropriate defaults.
|
|
478
493
|
* Format without options is equivalent to toString() and can be parsed back.
|
|
479
|
-
*
|
|
494
|
+
*
|
|
495
|
+
* @sealed
|
|
480
496
|
*
|
|
481
497
|
* @param {Object} [options] - formatting options
|
|
482
498
|
* @param {boolean} [options.terse] - whether to use terse formatting (omitting unnecessary spaces and parentheses)
|
|
@@ -500,14 +516,14 @@ export declare abstract class Expr {
|
|
|
500
516
|
* @example foo.format({terse: false}) // spell out all parentheses
|
|
501
517
|
* @example foo.format({html: true}) // use HTML tags and entities
|
|
502
518
|
* @example foo.format({ around: ['(', ')'], brackets: ['', ''], lambda: ['(', '->', ')'] }) // lisp style, still back-parsable
|
|
503
|
-
* @
|
|
519
|
+
* @example foo.format({ lambda: ['λ', '.', ''] }) // pretty-print for the math department
|
|
504
520
|
* @example foo.format({ lambda: ['', '=>', ''], terse: false }) // make it javascript
|
|
505
521
|
* @example foo.format({ inventory: { T } }) // use T as a named term, expand all others
|
|
506
522
|
*
|
|
507
523
|
*/
|
|
508
524
|
format(options?: FormatOptions): string;
|
|
509
525
|
/**
|
|
510
|
-
*
|
|
526
|
+
* Internal method for format(), which performs the actual formatting.
|
|
511
527
|
* @param {Object} options
|
|
512
528
|
* @param {number} nargs
|
|
513
529
|
* @returns {string}
|
|
@@ -516,7 +532,7 @@ export declare abstract class Expr {
|
|
|
516
532
|
*/
|
|
517
533
|
abstract formatImpl(options: RefinedFormatOptions, nargs: number): string;
|
|
518
534
|
/**
|
|
519
|
-
*
|
|
535
|
+
* Returns a string representation of the expression tree, with indentation to show structure.
|
|
520
536
|
*
|
|
521
537
|
* Applications are flattened to avoid excessive nesting.
|
|
522
538
|
* Variables include ids to distinguish different instances of the same variable name.
|
|
@@ -538,24 +554,30 @@ export declare abstract class Expr {
|
|
|
538
554
|
*/
|
|
539
555
|
diag(indent?: string): string;
|
|
540
556
|
/**
|
|
541
|
-
*
|
|
557
|
+
* Convert the expression to a JSON-serializable format.
|
|
558
|
+
* Sadly the format is not yet finalized and may change in the future.
|
|
559
|
+
*
|
|
560
|
+
* @experimental
|
|
542
561
|
* @returns {string}
|
|
543
|
-
* @
|
|
562
|
+
* @sealed
|
|
544
563
|
*/
|
|
545
564
|
toJSON(): string | object;
|
|
546
565
|
}
|
|
566
|
+
/**
|
|
567
|
+
* Application of two {@link Expr} terms.
|
|
568
|
+
*
|
|
569
|
+
* Never ever call `new App(fun, arg)` directly, use `fun.apply(...args)` instead.
|
|
570
|
+
*/
|
|
547
571
|
export declare class App extends Expr {
|
|
548
|
-
/**
|
|
549
|
-
* @desc Application of fun() to args.
|
|
550
|
-
* Never ever use new App(fun, arg) directly, use fun.apply(...args) instead.
|
|
551
|
-
* @param {Expr} fun
|
|
552
|
-
* @param {Expr} arg
|
|
553
|
-
*/
|
|
554
572
|
fun: Expr;
|
|
555
573
|
arg: Expr;
|
|
574
|
+
/** If irreducible, cache it and don't try anymore */
|
|
556
575
|
final?: boolean;
|
|
576
|
+
/**
|
|
577
|
+
* @param fun
|
|
578
|
+
* @param arg
|
|
579
|
+
*/
|
|
557
580
|
constructor(fun: Expr, arg: Expr);
|
|
558
|
-
/** @property {boolean} [final] */
|
|
559
581
|
_traverse_descend(options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr>;
|
|
560
582
|
any(predicate: (e: Expr) => boolean): boolean;
|
|
561
583
|
_fold<T>(initial: T, combine: (acc: T, expr: Expr) => TraverseValue<T>): TraverseValue<T>;
|
|
@@ -567,40 +589,38 @@ export declare class App extends Expr {
|
|
|
567
589
|
invoke(arg: Expr): Invocation | null;
|
|
568
590
|
unroll(): Expr[];
|
|
569
591
|
diff(other: Expr, swap?: boolean): string | null;
|
|
570
|
-
_braced(
|
|
592
|
+
_braced(isFirst?: boolean): boolean;
|
|
571
593
|
formatImpl(options: RefinedFormatOptions, nargs: number): string;
|
|
572
594
|
diag(indent?: string): string;
|
|
573
595
|
_unspaced(arg: Expr): boolean;
|
|
574
596
|
}
|
|
597
|
+
/**
|
|
598
|
+
* An abstract class representing a named term.
|
|
599
|
+
*
|
|
600
|
+
* @param {String} name
|
|
601
|
+
*/
|
|
575
602
|
export declare class Named extends Expr {
|
|
576
|
-
/**
|
|
577
|
-
* @desc An abstract class representing a term named 'name'.
|
|
578
|
-
*
|
|
579
|
-
* @param {String} name
|
|
580
|
-
*/
|
|
581
603
|
name: string;
|
|
582
604
|
fancyName?: string;
|
|
583
605
|
constructor(name: string);
|
|
584
606
|
_unspaced(arg: Expr): boolean;
|
|
585
607
|
formatImpl(options: RefinedFormatOptions, nargs: number): string;
|
|
586
608
|
}
|
|
609
|
+
/**
|
|
610
|
+
* A named variable.
|
|
611
|
+
*
|
|
612
|
+
* Given the functional nature of combinatory logic, variables are treated
|
|
613
|
+
* as functions that we don't know how to evaluate just yet.
|
|
614
|
+
*
|
|
615
|
+
* Two variables are considered the same iff they have the same `name` and `scope` properties.
|
|
616
|
+
* If `scope` is not given, the variable is only equal to itself.
|
|
617
|
+
*
|
|
618
|
+
* By convention, FreeVar.global is a constant denoting a global unbound variable.
|
|
619
|
+
*/
|
|
587
620
|
export declare class FreeVar extends Named {
|
|
588
621
|
/**
|
|
589
|
-
* @
|
|
590
|
-
*
|
|
591
|
-
* Given the functional nature of combinatory logic, variables are treated
|
|
592
|
-
* as functions that we don't know how to evaluate just yet.
|
|
593
|
-
*
|
|
594
|
-
* By default, two different variables even with the same name are considered different.
|
|
595
|
-
* They display it via a hidden id property.
|
|
596
|
-
*
|
|
597
|
-
* If a scope object is given, however, two variables with the same name and scope
|
|
598
|
-
* are considered identical.
|
|
599
|
-
*
|
|
600
|
-
* By convention, FreeVar.global is a constant denoting a global unbound variable.
|
|
601
|
-
*
|
|
602
|
-
* @param {string} name - name of the variable
|
|
603
|
-
* @param {any} scope - an object representing where the variable belongs to.
|
|
622
|
+
* @param name - name of the variable
|
|
623
|
+
* @param scope - an object representing where the variable belongs to.
|
|
604
624
|
*/
|
|
605
625
|
scope?: object;
|
|
606
626
|
id: number;
|
|
@@ -611,22 +631,23 @@ export declare class FreeVar extends Named {
|
|
|
611
631
|
diag(indent?: string): string;
|
|
612
632
|
static global: string[];
|
|
613
633
|
}
|
|
634
|
+
/**
|
|
635
|
+
* A named term with a known rewriting rule.
|
|
636
|
+
* 'impl' is a function with signature Expr => Expr => ... => Expr
|
|
637
|
+
* (see typedef Partial).
|
|
638
|
+
* This is how S, K, I, and company are implemented.
|
|
639
|
+
*
|
|
640
|
+
* Note that as of current something like a=>b=>b(a) is not possible,
|
|
641
|
+
* use full form instead: a=>b=>b.apply(a).
|
|
642
|
+
*
|
|
643
|
+
* @example new Native('K', x => y => x); // constant
|
|
644
|
+
* @example new Native('Y', function(f) { return f.apply(this.apply(f)); }); // self-application
|
|
645
|
+
*/
|
|
614
646
|
export declare class Native extends Named {
|
|
615
647
|
/**
|
|
616
|
-
* @
|
|
617
|
-
*
|
|
618
|
-
*
|
|
619
|
-
* This is how S, K, I, and company are implemented.
|
|
620
|
-
*
|
|
621
|
-
* Note that as of current something like a=>b=>b(a) is not possible,
|
|
622
|
-
* use full form instead: a=>b=>b.apply(a).
|
|
623
|
-
*
|
|
624
|
-
* @example new Native('K', x => y => x); // constant
|
|
625
|
-
* @example new Native('Y', function(f) { return f.apply(this.apply(f)); }); // self-application
|
|
626
|
-
*
|
|
627
|
-
* @param {String} name
|
|
628
|
-
* @param {Partial} impl
|
|
629
|
-
* @param {{note?: string, arity?: number, canonize?: boolean }} [opt]
|
|
648
|
+
* @param name Name of the term
|
|
649
|
+
* @param impl A javascript implementation of the term's rewriting rule.
|
|
650
|
+
* @param opt Optional settings.
|
|
630
651
|
*/
|
|
631
652
|
constructor(name: string, impl: (e: Expr) => Invocation, opt?: {
|
|
632
653
|
note?: string;
|
|
@@ -634,24 +655,23 @@ export declare class Native extends Named {
|
|
|
634
655
|
canonize?: boolean;
|
|
635
656
|
});
|
|
636
657
|
}
|
|
658
|
+
/**
|
|
659
|
+
* A lambda abstraction.
|
|
660
|
+
*
|
|
661
|
+
* Takes an arg: {@link FreeVar} and an impl: {@link Expr}.
|
|
662
|
+
* Upon evaluation, all occurrences of `arg` within `impl`
|
|
663
|
+
* will be replaced by the given term.
|
|
664
|
+
*
|
|
665
|
+
* Note that 'arg' will be replaced by a localized placeholder,
|
|
666
|
+
* so the original variable can be used elsewhere without interference.
|
|
667
|
+
*/
|
|
637
668
|
export declare class Lambda extends Expr {
|
|
669
|
+
arg: FreeVar;
|
|
670
|
+
impl: Expr;
|
|
638
671
|
/**
|
|
639
|
-
* @desc Lambda abstraction of arg over impl.
|
|
640
|
-
* Upon evaluation, all occurrences of 'arg' within 'impl' will be replaced
|
|
641
|
-
* with the provided argument.
|
|
642
|
-
*
|
|
643
|
-
* Note that 'arg' will be replaced by a localized placeholder, so the original
|
|
644
|
-
* variable can be used elsewhere without interference.
|
|
645
|
-
* Listing symbols contained in the lambda will omit such placeholder.
|
|
646
|
-
*
|
|
647
|
-
* Legacy ([FreeVar], impl) constructor is supported but deprecated.
|
|
648
|
-
* It will create a nested lambda expression.
|
|
649
|
-
*
|
|
650
672
|
* @param {FreeVar} arg
|
|
651
673
|
* @param {Expr} impl
|
|
652
674
|
*/
|
|
653
|
-
arg: FreeVar;
|
|
654
|
-
impl: Expr;
|
|
655
675
|
constructor(arg: FreeVar, impl: Expr);
|
|
656
676
|
invoke(arg: Expr): Expr;
|
|
657
677
|
_traverse_descend(options: TraverseOptions, change: TraverseCallback): TraverseValue<Expr>;
|
|
@@ -661,43 +681,45 @@ export declare class Lambda extends Expr {
|
|
|
661
681
|
diff(other: Expr, swap?: boolean): string | null;
|
|
662
682
|
formatImpl(options: RefinedFormatOptions, nargs: number): string;
|
|
663
683
|
diag(indent?: string): string;
|
|
664
|
-
_braced(
|
|
684
|
+
_braced(isFirst: boolean): boolean;
|
|
665
685
|
}
|
|
686
|
+
/**
|
|
687
|
+
* Church numeral representing non-negative integer `n`:
|
|
688
|
+
* `n f x = f(f(...(f x)...))` with `f` applied `n` times.
|
|
689
|
+
*/
|
|
666
690
|
export declare class Church extends Expr {
|
|
691
|
+
n: number;
|
|
667
692
|
/**
|
|
668
|
-
* @desc Church numeral representing non-negative integer n:
|
|
669
|
-
* n f x = f(f(...(f x)...)) with f applied n times.
|
|
670
693
|
* @param {number} n
|
|
671
694
|
*/
|
|
672
|
-
n: number;
|
|
673
695
|
constructor(n: number);
|
|
674
696
|
diff(other: Expr, swap?: boolean): string | null;
|
|
675
697
|
_unspaced(arg: Expr): boolean;
|
|
676
698
|
formatImpl(options: RefinedFormatOptions, nargs: number): string;
|
|
677
699
|
}
|
|
700
|
+
/**
|
|
701
|
+
* A named alias for an existing expression.
|
|
702
|
+
*
|
|
703
|
+
* Aliasing allows declaring new terms without a native implementation.
|
|
704
|
+
* This is what happens when one writes `B = S(KS)K` in the interpreter.
|
|
705
|
+
*
|
|
706
|
+
* Aliases are transparent in terms of `equals` and `expect`;
|
|
707
|
+
* for that reason, Alias.diag() in not adding to the indentation.
|
|
708
|
+
*
|
|
709
|
+
* Aliases have an `inline` property. Tf true, the alias will be replaced with its implementation
|
|
710
|
+
* everywhere, unless specifically told otherwise e.g. by { inventory: { ... } } option of format().
|
|
711
|
+
*
|
|
712
|
+
* Upon creation, the aliases arity is calculated (unless `canonize` is false).
|
|
713
|
+
*
|
|
714
|
+
* Upon evaluation, the alias will be replaced with its implementation,
|
|
715
|
+
* _unless_ it's not inline and has positive arity,
|
|
716
|
+
* in which case it will wait for the required number of arguments before such replacement.
|
|
717
|
+
*/
|
|
678
718
|
export declare class Alias extends Named {
|
|
679
719
|
/**
|
|
680
|
-
* @
|
|
681
|
-
*
|
|
682
|
-
*
|
|
683
|
-
* This is what happens when one writes `B = S(KS)K` in the interpreter.
|
|
684
|
-
*
|
|
685
|
-
* Aliases are transparent in terms of `equals` and `expect`;
|
|
686
|
-
* for that reason, Alias.diag() in not adding to the indentation.
|
|
687
|
-
*
|
|
688
|
-
* Aliases have an `inline` property. Tf true, the alias will be replaced with its implementation
|
|
689
|
-
* everywhere, unless specifically told otherwise e.g. by { inventory: { ... } } option of format().
|
|
690
|
-
*
|
|
691
|
-
* Upon creation, the aliases arity is calculated (unless `canonize` is false).
|
|
692
|
-
*
|
|
693
|
-
* Upon evaluation, the alias will be replaced with its implementation,
|
|
694
|
-
* _unless_ it's not inline and has positive arity,
|
|
695
|
-
* in which case it will wait for the required number of arguments before such replacement.
|
|
696
|
-
*
|
|
697
|
-
*
|
|
698
|
-
* @param {String} name
|
|
699
|
-
* @param {Expr} impl
|
|
700
|
-
* @param {{canonize?: boolean, max?: number, maxArgs?: number, note?: string, inline?: boolean}} [options]
|
|
720
|
+
* @param name
|
|
721
|
+
* @param impl
|
|
722
|
+
* @param options
|
|
701
723
|
*/
|
|
702
724
|
impl: Expr;
|
|
703
725
|
inline?: boolean;
|
|
@@ -710,11 +732,13 @@ export declare class Alias extends Named {
|
|
|
710
732
|
arity?: number;
|
|
711
733
|
});
|
|
712
734
|
/**
|
|
713
|
-
*
|
|
735
|
+
* Make the alias inline, i.e. replace it with its implementation everywhere.
|
|
714
736
|
*
|
|
715
737
|
* Replaces the old `outdated` attribute.
|
|
716
738
|
* Used by the parser when a term definition is removed or updated.
|
|
717
739
|
*
|
|
740
|
+
*
|
|
741
|
+
*
|
|
718
742
|
* May change in future versions, use with caution.
|
|
719
743
|
*
|
|
720
744
|
* @experimental
|
|
@@ -735,7 +759,7 @@ export declare class Alias extends Named {
|
|
|
735
759
|
*/
|
|
736
760
|
step(): Step;
|
|
737
761
|
diff(other: Expr, swap?: boolean): string | null;
|
|
738
|
-
_braced(
|
|
762
|
+
_braced(isFirst: boolean): boolean;
|
|
739
763
|
formatImpl(options: RefinedFormatOptions, nargs: number): string;
|
|
740
764
|
diag(indent?: string): string;
|
|
741
765
|
}
|
|
@@ -749,4 +773,3 @@ export declare const classes: {
|
|
|
749
773
|
Church: typeof Church;
|
|
750
774
|
Alias: typeof Alias;
|
|
751
775
|
};
|
|
752
|
-
export {};
|