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