@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.
@@ -1,7 +1,6 @@
1
- import { z } from 'zod';
2
1
  import { TraverseValue } from './internal';
3
2
  /**
4
- * @desc Control primitives for fold() and traverse() methods.
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
- * @desc List of predefined native combinators.
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 declare const FormatOptionsSchema: z.ZodObject<{
46
- terse: z.ZodOptional<z.ZodBoolean>;
47
- html: z.ZodOptional<z.ZodBoolean>;
48
- brackets: z.ZodOptional<z.ZodTuple<[z.ZodString, z.ZodString], null>>;
49
- space: z.ZodOptional<z.ZodString>;
50
- var: z.ZodOptional<z.ZodTuple<[z.ZodString, z.ZodString], null>>;
51
- lambda: z.ZodOptional<z.ZodTuple<[z.ZodString, z.ZodString, z.ZodString], null>>;
52
- around: z.ZodOptional<z.ZodTuple<[z.ZodString, z.ZodString], null>>;
53
- redex: z.ZodOptional<z.ZodTuple<[z.ZodString, z.ZodString], null>>;
54
- inventory: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodCustom<Expr, Expr>>>;
55
- }, z.core.$strip>;
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
- * @desc A version of FormatOptions with defaults plugged in,
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
- /** @desc number of arguments the term is waiting for (if known) */
96
+ /** number of arguments the term is waiting for (if known) */
95
97
  arity?: number;
96
- /** @desc a brief description what the term does */
98
+ /** a brief description what the term does */
97
99
  note?: string;
98
- /** @desc the properties of the term, typically inferred from its behavior.
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
- /** @desc An estimated number of nodes in the expression tree.
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
- * @desc Define properties of the term based on user supplied options and/or inference results.
109
- * Typically useful for declaring Native and Alias terms.
110
- * @protected
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
- _setup(options?: {
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
- * @desc apply self to zero or more terms and return the resulting term,
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
- * @desc Replace all aliases in the expression with their definitions, recursively.
141
+ * Replace all aliases in the expression with their definitions, recursively.
137
142
  * @return {Expr}
138
143
  */
139
144
  expand(): Expr;
140
145
  /**
141
- * @desc Traverse the expression tree, applying change() to each node.
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
- * @final
170
+ * @sealed
166
171
  */
167
172
  traverse(options: TraverseOptions | TraverseCallback, change?: TraverseCallback): Expr | null;
168
173
  /**
174
+ *
175
+ *
169
176
  * @protected
170
- * @final
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
- * @desc Returns true if predicate() is true for any subterm of the expression, false otherwise.
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
- * @desc Fold the expression into a single value by recursively applying combine() to its subterms.
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
- * @final
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
- * @desc Internal method for fold(), which performs the actual folding.
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
- * @desc Fold an application tree bottom to top.
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
- * @desc Try to empirically find an equivalent lambda term for the expression,
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
- * @final
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
- * @desc Internal method for infer(), which performs the actual inference.
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
- * @desc Expand an expression into a list of terms
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
- * @desc Returns a series of lambda terms equivalent to the given expression,
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
- * @final
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
- * @desc Rewrite the expression into S, K, and I combinators step by step.
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
- * @final
337
+ * @sealed
329
338
  * @param {{max?: number}} [options]
330
339
  * @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}
331
340
  */
332
- toSKI(_options?: {}): Generator<{
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
- * @desc Apply term reduction rules, if any, to the given argument.
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
- * @desc iterate one step of a calculation.
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
- * @desc Run uninterrupted sequence of step() applications
379
- * until the expression is irreducible, or max number of steps is reached.
380
- * Default number of steps = 1000.
381
- * @final
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
- * Execute step() while possible, yielding a brief description of events after each step.
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
- * @desc True is the expressions are identical, false otherwise.
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
- * @desc Recursively compare two expressions and return a string
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
- * @desc Assert expression equality. Can be used in tests.
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 to because browsers don't recognize it.
465
+ * AssertionError is not used directly because browsers don't recognize it.
445
466
  *
446
- * @final
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
- * @desc Returns string representation of the expression.
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
- * @final
478
+ * @sealed
458
479
  */
459
480
  toString(): string;
460
481
  /**
461
- * @desc Whether the expression needs parentheses when printed.
462
- * @param {boolean} [first] - whether this is the first term in a sequence
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(_first?: boolean): boolean;
488
+ _braced(isFirst?: boolean): boolean;
467
489
  /**
468
- * @desc Whether the expression can be printed without a space when followed by arg.
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
- * @desc Stringify the expression with fancy formatting options.
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
- * @final
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
- * @exapmle foo.format({ lambda: ['&lambda;', '.', ''] }) // pretty-print for the math department
526
+ * @example foo.format({ lambda: ['&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
- * @desc Internal method for format(), which performs the actual formatting.
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
- * @desc Returns a string representation of the expression tree, with indentation to show structure.
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
- * @desc Convert the expression to a JSON-serializable format.
542
- * @returns {string}
543
- * @final
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(first?: boolean): boolean;
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
- * @desc A named variable.
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
- * @desc A named term with a known rewriting rule.
617
- * 'impl' is a function with signature Expr => Expr => ... => Expr
618
- * (see typedef Partial).
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(first: boolean): boolean;
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
- * @desc A named alias for an existing expression.
681
- *
682
- * Aliasing allows declaring new terms without a native implementation.
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
- * @desc Make the alias inline, i.e. replace it with its implementation everywhere.
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(first: boolean): boolean;
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 {};