@dallaylaen/ski-interpreter 2.0.0 → 2.2.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 +43 -0
- package/README.md +1 -1
- package/bin/ski.js +96 -97
- package/lib/ski-interpreter.cjs.js +2047 -0
- package/lib/ski-interpreter.cjs.js.map +7 -0
- package/lib/ski-interpreter.esm.js +2052 -0
- package/lib/ski-interpreter.esm.js.map +7 -0
- package/package.json +13 -6
- package/types/index.d.ts +3 -7
- package/types/{lib → src}/expr.d.ts +146 -48
- package/types/src/extras.d.ts +58 -0
- package/types/src/internal.d.ts +52 -0
- package/types/{lib → src}/parser.d.ts +11 -4
- package/types/{lib → src}/quest.d.ts +56 -39
- package/index.js +0 -8
- package/lib/expr.js +0 -1316
- package/lib/parser.js +0 -418
- package/lib/quest.js +0 -401
- package/lib/util.js +0 -57
- package/types/lib/util.d.ts +0 -11
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
export type ActionWrapper<T> = T | {
|
|
2
|
+
value: T | null;
|
|
3
|
+
action: string;
|
|
4
|
+
} | null;
|
|
1
5
|
export type Partial = Expr | ((arg0: Expr) => Partial);
|
|
2
6
|
/**
|
|
3
7
|
* @typedef {Expr | function(Expr): Partial} Partial
|
|
@@ -11,7 +15,7 @@ export class Expr {
|
|
|
11
15
|
*/
|
|
12
16
|
apply(...args: Expr): Expr;
|
|
13
17
|
/**
|
|
14
|
-
*
|
|
18
|
+
* @desc Replace all aliases in the expression with their definitions, recursively.
|
|
15
19
|
* @return {Expr}
|
|
16
20
|
*/
|
|
17
21
|
expand(): Expr;
|
|
@@ -36,7 +40,28 @@ export class Expr {
|
|
|
36
40
|
*/
|
|
37
41
|
any(predicate: (e: Expr) => boolean): boolean;
|
|
38
42
|
/**
|
|
39
|
-
* @desc
|
|
43
|
+
* @desc Fold the expression into a single value by recursively applying combine() to its subterms.
|
|
44
|
+
* Nodes are traversed in leftmost-outermost order, i.e. the same order as reduction steps are taken.
|
|
45
|
+
*
|
|
46
|
+
* null or undefined return value from combine() means "keep current value and descend further".
|
|
47
|
+
*
|
|
48
|
+
* SKI.control provides primitives to control the folding flow:
|
|
49
|
+
* - SKI.control.prune(value) means "use value and don't descend further into this branch";
|
|
50
|
+
* - SKI.control.stop(value) means "stop folding immediately and return value".
|
|
51
|
+
* - SKI.control.descend(value) is the default behavior, meaning "use value and descend further".
|
|
52
|
+
*
|
|
53
|
+
* This method is experimental and may change in the future.
|
|
54
|
+
*
|
|
55
|
+
* @experimental
|
|
56
|
+
* @template T
|
|
57
|
+
* @param {T} initial
|
|
58
|
+
* @param {(acc: T, expr: Expr) => ActionWrapper<T>} combine
|
|
59
|
+
* @returns {T}
|
|
60
|
+
*/
|
|
61
|
+
fold<T>(initial: T, combine: (acc: T, expr: Expr) => ActionWrapper<T>): T;
|
|
62
|
+
_fold(initial: any, combine: any): any;
|
|
63
|
+
/**
|
|
64
|
+
* @desc rough estimate of the complexity of the term
|
|
40
65
|
* @return {number}
|
|
41
66
|
*/
|
|
42
67
|
weight(): number;
|
|
@@ -52,7 +77,7 @@ export class Expr {
|
|
|
52
77
|
*
|
|
53
78
|
* Use toLambda() if you want to get a lambda term in any case.
|
|
54
79
|
*
|
|
55
|
-
* @param {{max
|
|
80
|
+
* @param {{max?: number, maxArgs?: number}} options
|
|
56
81
|
* @return {{
|
|
57
82
|
* normal: boolean,
|
|
58
83
|
* steps: number,
|
|
@@ -66,8 +91,8 @@ export class Expr {
|
|
|
66
91
|
* }}
|
|
67
92
|
*/
|
|
68
93
|
infer(options?: {
|
|
69
|
-
max
|
|
70
|
-
maxArgs
|
|
94
|
+
max?: number;
|
|
95
|
+
maxArgs?: number;
|
|
71
96
|
}): {
|
|
72
97
|
normal: boolean;
|
|
73
98
|
steps: number;
|
|
@@ -79,9 +104,27 @@ export class Expr {
|
|
|
79
104
|
skip?: Set<number>;
|
|
80
105
|
dup?: Set<number>;
|
|
81
106
|
};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
107
|
+
/**
|
|
108
|
+
*
|
|
109
|
+
* @param {{max: number, maxArgs: number, index: number}} options
|
|
110
|
+
* @param {FreeVar[]} preArgs
|
|
111
|
+
* @param {number} steps
|
|
112
|
+
* @returns {{normal: boolean, steps: number}|{normal: boolean, steps: number}|{normal: boolean, steps: number, expr: Lambda|*, arity?: *, skip?: Set<any>, dup?: Set<any>, duplicate, discard, proper: boolean}|*|{normal: boolean, steps: number}}
|
|
113
|
+
* @private
|
|
114
|
+
*/
|
|
115
|
+
private _infer;
|
|
116
|
+
/**
|
|
117
|
+
* @desc Expand an expression into a list of terms
|
|
118
|
+
* that give the initial expression when applied from left to right:
|
|
119
|
+
* ((a, b), (c, d)) => [a, b, (c, d)]
|
|
120
|
+
*
|
|
121
|
+
* This can be thought of as an opposite of apply:
|
|
122
|
+
* fun.apply(...arg).unroll() is exactly [fun, ...args]
|
|
123
|
+
* (even if ...arg is in fact empty).
|
|
124
|
+
*
|
|
125
|
+
* @returns {Expr[]}
|
|
126
|
+
*/
|
|
127
|
+
unroll(): Expr[];
|
|
85
128
|
/**
|
|
86
129
|
* @desc Returns a series of lambda terms equivalent to the given expression,
|
|
87
130
|
* up to the provided computation steps limit,
|
|
@@ -122,17 +165,23 @@ export class Expr {
|
|
|
122
165
|
*
|
|
123
166
|
* See also Expr.walk() and Expr.toLambda().
|
|
124
167
|
*
|
|
125
|
-
* @param {{max
|
|
168
|
+
* @param {{max?: number}} [options]
|
|
126
169
|
* @return {IterableIterator<{final: boolean, expr: Expr, steps: number}>}
|
|
127
170
|
*/
|
|
128
171
|
toSKI(options?: {
|
|
129
|
-
max
|
|
172
|
+
max?: number;
|
|
130
173
|
}): IterableIterator<{
|
|
131
174
|
final: boolean;
|
|
132
175
|
expr: Expr;
|
|
133
176
|
steps: number;
|
|
134
177
|
}>;
|
|
135
|
-
|
|
178
|
+
/**
|
|
179
|
+
* @desc Internal method for toSKI, which performs one step of the conversion.
|
|
180
|
+
* @param {{max: number, steps: number}} options
|
|
181
|
+
* @returns {Expr}
|
|
182
|
+
* @private
|
|
183
|
+
*/
|
|
184
|
+
private _rski;
|
|
136
185
|
/**
|
|
137
186
|
* Replace all instances of plug in the expression with value and return the resulting expression,
|
|
138
187
|
* or null if no changes could be made.
|
|
@@ -256,7 +305,13 @@ export class Expr {
|
|
|
256
305
|
* @return {boolean}
|
|
257
306
|
*/
|
|
258
307
|
_braced(first?: boolean): boolean;
|
|
259
|
-
|
|
308
|
+
/**
|
|
309
|
+
* @desc Whether the expression can be printed without a space when followed by arg.
|
|
310
|
+
* @param {Expr} arg
|
|
311
|
+
* @returns {boolean}
|
|
312
|
+
* @private
|
|
313
|
+
*/
|
|
314
|
+
private _unspaced;
|
|
260
315
|
/**
|
|
261
316
|
* @desc Stringify the expression with fancy formatting options.
|
|
262
317
|
* Said options mostly include wrappers around various constructs in form of ['(', ')'],
|
|
@@ -302,31 +357,43 @@ export class Expr {
|
|
|
302
357
|
[x: string]: Expr;
|
|
303
358
|
};
|
|
304
359
|
}): string;
|
|
305
|
-
|
|
306
|
-
|
|
360
|
+
/**
|
|
361
|
+
* @desc Internal method for format(), which performs the actual formatting.
|
|
362
|
+
* @param {Object} options
|
|
363
|
+
* @param {number} nargs
|
|
364
|
+
* @returns {string}
|
|
365
|
+
* @private
|
|
366
|
+
*/
|
|
367
|
+
private _format;
|
|
368
|
+
/**
|
|
369
|
+
* @desc Convert the expression to a JSON-serializable format.
|
|
370
|
+
* @returns {string}
|
|
371
|
+
*/
|
|
372
|
+
toJSON(): string;
|
|
307
373
|
}
|
|
308
374
|
export namespace Expr {
|
|
309
|
-
export { declare };
|
|
310
375
|
export { native };
|
|
376
|
+
export { control };
|
|
377
|
+
export namespace extras {
|
|
378
|
+
export { toposort };
|
|
379
|
+
}
|
|
311
380
|
}
|
|
312
381
|
export class App extends Expr {
|
|
313
382
|
/**
|
|
314
383
|
* @desc Application of fun() to args.
|
|
315
|
-
* Never ever use new App(fun,
|
|
384
|
+
* Never ever use new App(fun, arg) directly, use fun.apply(...args) instead.
|
|
316
385
|
* @param {Expr} fun
|
|
317
|
-
* @param {Expr}
|
|
386
|
+
* @param {Expr} arg
|
|
318
387
|
*/
|
|
319
|
-
constructor(fun: Expr,
|
|
320
|
-
arg:
|
|
321
|
-
fun:
|
|
388
|
+
constructor(fun: Expr, arg: Expr);
|
|
389
|
+
arg: Expr;
|
|
390
|
+
fun: Expr;
|
|
322
391
|
final: boolean;
|
|
323
|
-
arity:
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
expand(): any;
|
|
327
|
-
traverse(change: any): any;
|
|
392
|
+
arity: number;
|
|
393
|
+
_infer(options: any, preArgs?: any[], steps?: number): any;
|
|
394
|
+
traverse(change: any): Expr;
|
|
328
395
|
any(predicate: any): any;
|
|
329
|
-
subst(search: any, replace: any):
|
|
396
|
+
subst(search: any, replace: any): Expr;
|
|
330
397
|
/**
|
|
331
398
|
* @return {{expr: Expr, steps: number}}
|
|
332
399
|
*/
|
|
@@ -334,13 +401,27 @@ export class App extends Expr {
|
|
|
334
401
|
expr: Expr;
|
|
335
402
|
steps: number;
|
|
336
403
|
};
|
|
337
|
-
invoke(arg: any):
|
|
338
|
-
|
|
339
|
-
|
|
404
|
+
invoke(arg: any): Partial;
|
|
405
|
+
/**
|
|
406
|
+
* @desc Convert the expression to SKI combinatory logic
|
|
407
|
+
* @return {Expr}
|
|
408
|
+
*/
|
|
409
|
+
_rski(options: any): Expr;
|
|
340
410
|
diff(other: any, swap?: boolean): string;
|
|
341
411
|
_braced(first: any): boolean;
|
|
412
|
+
_format(options: any, nargs: any): string;
|
|
413
|
+
_unspaced(arg: any): boolean;
|
|
414
|
+
}
|
|
415
|
+
export class Named extends Expr {
|
|
416
|
+
/**
|
|
417
|
+
* @desc An abstract class representing a term named 'name'.
|
|
418
|
+
*
|
|
419
|
+
* @param {String} name
|
|
420
|
+
*/
|
|
421
|
+
constructor(name: string);
|
|
422
|
+
name: string;
|
|
423
|
+
_unspaced(arg: any): boolean;
|
|
342
424
|
_format(options: any, nargs: any): any;
|
|
343
|
-
_unspaced(arg: any): any;
|
|
344
425
|
}
|
|
345
426
|
export class FreeVar extends Named {
|
|
346
427
|
/**
|
|
@@ -384,14 +465,14 @@ export class Lambda extends Expr {
|
|
|
384
465
|
arg: FreeVar;
|
|
385
466
|
impl: Expr;
|
|
386
467
|
arity: number;
|
|
468
|
+
_infer(options: any, preArgs?: any[], steps?: number): any;
|
|
387
469
|
invoke(arg: any): Expr;
|
|
388
470
|
traverse(change: any): Expr | Lambda;
|
|
389
471
|
any(predicate: any): any;
|
|
390
472
|
subst(search: any, replace: any): Lambda;
|
|
391
|
-
expand(): Lambda;
|
|
392
473
|
_rski(options: any): any;
|
|
393
474
|
diff(other: any, swap?: boolean): string;
|
|
394
|
-
_format(options: any, nargs: any):
|
|
475
|
+
_format(options: any, nargs: any): string;
|
|
395
476
|
_braced(first: any): boolean;
|
|
396
477
|
}
|
|
397
478
|
export class Native extends Named {
|
|
@@ -420,7 +501,7 @@ export class Native extends Named {
|
|
|
420
501
|
invoke: Partial;
|
|
421
502
|
arity: any;
|
|
422
503
|
note: any;
|
|
423
|
-
_rski(options: any):
|
|
504
|
+
_rski(options: any): Expr | this;
|
|
424
505
|
}
|
|
425
506
|
export class Alias extends Named {
|
|
426
507
|
/**
|
|
@@ -456,6 +537,7 @@ export class Alias extends Named {
|
|
|
456
537
|
traverse(change: any): any;
|
|
457
538
|
any(predicate: any): any;
|
|
458
539
|
subst(search: any, replace: any): any;
|
|
540
|
+
_infer(options: any, preArgs?: any[], steps?: number): any;
|
|
459
541
|
/**
|
|
460
542
|
*
|
|
461
543
|
* @return {{expr: Expr, steps: number}}
|
|
@@ -479,26 +561,42 @@ export class Church extends Native {
|
|
|
479
561
|
arity: number;
|
|
480
562
|
diff(other: any, swap?: boolean): string;
|
|
481
563
|
}
|
|
482
|
-
/**
|
|
483
|
-
*
|
|
484
|
-
* @param {Expr[]} inventory
|
|
485
|
-
* @return {string[]}
|
|
486
|
-
*/
|
|
487
|
-
declare function declare(inventory: Expr[]): string[];
|
|
488
564
|
/**
|
|
489
565
|
* @type {{[key: string]: Native}}
|
|
490
566
|
*/
|
|
491
567
|
declare const native: {
|
|
492
568
|
[key: string]: Native;
|
|
493
569
|
};
|
|
494
|
-
declare
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
* @param {String} name
|
|
499
|
-
*/
|
|
500
|
-
constructor(name: string);
|
|
501
|
-
name: string;
|
|
502
|
-
_format(options: any, nargs: any): any;
|
|
570
|
+
declare namespace control {
|
|
571
|
+
let descend: (arg0: any) => any;
|
|
572
|
+
let prune: (arg0: any) => any;
|
|
573
|
+
let stop: (arg0: any) => any;
|
|
503
574
|
}
|
|
575
|
+
/**
|
|
576
|
+
* @desc Sort a list in such a way that dependent terms come after the (named) terms they depend on.
|
|
577
|
+
* If env is given, only terms listed there are taken into account.
|
|
578
|
+
* If env is omitted, it will be implied from the list.
|
|
579
|
+
* If list is omitted, it will default to values of env.
|
|
580
|
+
* If just one term is given instead of a list, it will be coerced into a list.
|
|
581
|
+
*
|
|
582
|
+
* No terms outside env + list may ever appear in the result.
|
|
583
|
+
*
|
|
584
|
+
* The terms in env must be named and their names must match their keys.
|
|
585
|
+
*
|
|
586
|
+
* @param {Expr|Expr[]} list
|
|
587
|
+
* @param {{[s:string]: Named}} env
|
|
588
|
+
* @returns {{list: Expr[], env: {[s:string]: Named}}}
|
|
589
|
+
*
|
|
590
|
+
* @example
|
|
591
|
+
* const expr = ski.parse(src);
|
|
592
|
+
* toposort([expr], ski.getTerms()); // returns all terms appearing in Expr in correct order
|
|
593
|
+
*/
|
|
594
|
+
declare function toposort(list: Expr | Expr[], env: {
|
|
595
|
+
[s: string]: Named;
|
|
596
|
+
}): {
|
|
597
|
+
list: Expr[];
|
|
598
|
+
env: {
|
|
599
|
+
[s: string]: Named;
|
|
600
|
+
};
|
|
601
|
+
};
|
|
504
602
|
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @desc Extra utilities that do not belong in the core.
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* @experimental
|
|
6
|
+
* @desc Look for an expression that matches the predicate,
|
|
7
|
+
* starting with the seed and applying the terms to one another.
|
|
8
|
+
*
|
|
9
|
+
* A predicate returning 0 (or nothing) means "keep looking",
|
|
10
|
+
* a positive number stands for "found",
|
|
11
|
+
* and a negative means "discard this term from further applications".
|
|
12
|
+
*
|
|
13
|
+
* The order of search is from shortest to longest expressions.
|
|
14
|
+
*
|
|
15
|
+
* @param {Expr[]} seed
|
|
16
|
+
* @param {object} options
|
|
17
|
+
* @param {number} [options.depth] - maximum generation to search for
|
|
18
|
+
* @param {number} [options.tries] - maximum number of tries before giving up
|
|
19
|
+
* @param {boolean} [options.infer] - whether to call infer(), default true.
|
|
20
|
+
* @param {number} [options.maxArgs] - arguments in infer()
|
|
21
|
+
* @param {number} [options.max] - step limit in infer()
|
|
22
|
+
* @param {boolean} [options.noskip] - prevents skipping equivalent terms. Always true if infer is false.
|
|
23
|
+
* @param {boolean} [retain] - if true. also add the whole cache to returned value
|
|
24
|
+
* @param {({gen: number, total: number, probed: number, step: boolean}) => void} [options.progress]
|
|
25
|
+
* @param {number} [options.progressInterval] - minimum number of tries between calls to options.progress, default 1000.
|
|
26
|
+
* @param {(e: Expr, props: {}) => number?} predicate
|
|
27
|
+
* @return {{expr?: Expr, total: number, probed: number, gen: number, cache?: Expr[][]}}
|
|
28
|
+
*/
|
|
29
|
+
export function search(seed: Expr[], options: {
|
|
30
|
+
depth?: number;
|
|
31
|
+
tries?: number;
|
|
32
|
+
infer?: boolean;
|
|
33
|
+
maxArgs?: number;
|
|
34
|
+
max?: number;
|
|
35
|
+
noskip?: boolean;
|
|
36
|
+
}, predicate: (e: Expr, props: {}) => number | null): {
|
|
37
|
+
expr?: Expr;
|
|
38
|
+
total: number;
|
|
39
|
+
probed: number;
|
|
40
|
+
gen: number;
|
|
41
|
+
cache?: Expr[][];
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* @desc Recursively replace all instances of Expr in a data structure with
|
|
45
|
+
* respective string representation using the format() options.
|
|
46
|
+
* Objects of other types and primitive values are eft as is.
|
|
47
|
+
*
|
|
48
|
+
* May be useful for debugging or diagnostic output.
|
|
49
|
+
*
|
|
50
|
+
* @experimental
|
|
51
|
+
*
|
|
52
|
+
* @param {any} obj
|
|
53
|
+
* @param {object} [options] - see Expr.format()
|
|
54
|
+
* @returns {any}
|
|
55
|
+
*/
|
|
56
|
+
export function deepFormat(obj: any, options?: object): any;
|
|
57
|
+
export function declare(expr: any, env: any): string;
|
|
58
|
+
import { Expr } from "./expr";
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export class Tokenizer {
|
|
2
|
+
/**
|
|
3
|
+
* @desc Create a tokenizer that splits strings into tokens according to the given terms.
|
|
4
|
+
* The terms are interpreted as regular expressions, and are sorted by length
|
|
5
|
+
* to ensure that longer matches are preferred over shorter ones.
|
|
6
|
+
* @param {...string|RegExp} terms
|
|
7
|
+
*/
|
|
8
|
+
constructor(...terms: (string | RegExp)[]);
|
|
9
|
+
rex: RegExp;
|
|
10
|
+
/**
|
|
11
|
+
* @desc Split the given string into tokens according to the terms specified in the constructor.
|
|
12
|
+
* @param {string} str
|
|
13
|
+
* @return {string[]}
|
|
14
|
+
*/
|
|
15
|
+
split(str: string): string[];
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* @desc Add ot remove tokens from a set according to a spec string.
|
|
19
|
+
* The spec string is a sequence of tokens, with each group optionally prefixed
|
|
20
|
+
* by one of the operators '=', '+', or '-'.
|
|
21
|
+
* The '=' operator resets the set to contain only the following token(s).
|
|
22
|
+
* @param {Set<string>} set
|
|
23
|
+
* @param {string} [spec]
|
|
24
|
+
* @returns {Set<string>}
|
|
25
|
+
*/
|
|
26
|
+
export function restrict(set: Set<string>, spec?: string): Set<string>;
|
|
27
|
+
/**
|
|
28
|
+
* @private
|
|
29
|
+
* @template T
|
|
30
|
+
* @param {T|ActionWrapper<T>} value
|
|
31
|
+
* @returns {[T?, string|undefined]}
|
|
32
|
+
*/
|
|
33
|
+
export function unwrap<T>(value: T | ActionWrapper<T>): [T?, string | undefined];
|
|
34
|
+
/**
|
|
35
|
+
*
|
|
36
|
+
* @private
|
|
37
|
+
* @template T
|
|
38
|
+
* @param {string} action
|
|
39
|
+
* @returns {function(T): ActionWrapper<T>}
|
|
40
|
+
*/
|
|
41
|
+
export function prepareWrapper<T>(action: string): (arg0: T) => ActionWrapper<T>;
|
|
42
|
+
declare class ActionWrapper {
|
|
43
|
+
/**
|
|
44
|
+
* @template T
|
|
45
|
+
* @param {T} value
|
|
46
|
+
* @param {string} action
|
|
47
|
+
*/
|
|
48
|
+
constructor(value: T, action: string);
|
|
49
|
+
value: T;
|
|
50
|
+
action: string;
|
|
51
|
+
}
|
|
52
|
+
export {};
|
|
@@ -86,7 +86,8 @@ export class SKI {
|
|
|
86
86
|
[key: string]: typeof classes.Native | typeof classes.Alias;
|
|
87
87
|
};
|
|
88
88
|
/**
|
|
89
|
-
* Export term declarations for use in bulkAdd().
|
|
89
|
+
* @desc Export term declarations for use in bulkAdd().
|
|
90
|
+
* Currently only Alias terms are serialized.
|
|
90
91
|
* @returns {string[]}
|
|
91
92
|
*/
|
|
92
93
|
declare(): string[];
|
|
@@ -143,7 +144,9 @@ export class SKI {
|
|
|
143
144
|
};
|
|
144
145
|
}
|
|
145
146
|
export namespace SKI {
|
|
146
|
-
|
|
147
|
+
/**
|
|
148
|
+
* Public static shortcuts to common functions (see also ./extras.js)
|
|
149
|
+
*/
|
|
147
150
|
/**
|
|
148
151
|
* @desc Create a proxy object that generates variables on demand,
|
|
149
152
|
* with names corresponding to the property accessed.
|
|
@@ -167,12 +170,16 @@ export namespace SKI {
|
|
|
167
170
|
* @return {Church}
|
|
168
171
|
*/
|
|
169
172
|
export function church(n: number): typeof import("./expr").Church;
|
|
173
|
+
export { classes };
|
|
170
174
|
export { native };
|
|
171
|
-
export
|
|
175
|
+
export let control: {
|
|
176
|
+
descend: (arg0: any) => any;
|
|
177
|
+
prune: (arg0: any) => any;
|
|
178
|
+
stop: (arg0: any) => any;
|
|
179
|
+
};
|
|
172
180
|
}
|
|
173
181
|
import classes = require("./expr");
|
|
174
182
|
declare const native: {
|
|
175
183
|
[key: string]: classes.Native;
|
|
176
184
|
};
|
|
177
|
-
declare const declare: (inventory: Expr[]) => string[];
|
|
178
185
|
export {};
|
|
@@ -18,6 +18,13 @@ export type Capability = {
|
|
|
18
18
|
duplicate: boolean | null;
|
|
19
19
|
arity: number | null;
|
|
20
20
|
};
|
|
21
|
+
export type InputSpec = string | {
|
|
22
|
+
name: string;
|
|
23
|
+
fancy?: string;
|
|
24
|
+
allow?: string;
|
|
25
|
+
numbers?: boolean;
|
|
26
|
+
lambdas?: boolean;
|
|
27
|
+
};
|
|
21
28
|
export type QuestResult = {
|
|
22
29
|
pass: boolean;
|
|
23
30
|
details: CaseResult[];
|
|
@@ -58,6 +65,9 @@ export type QuestResult = {
|
|
|
58
65
|
* | [{caps: Capability, max: number?}, string]
|
|
59
66
|
* } TestCase
|
|
60
67
|
*/
|
|
68
|
+
/**
|
|
69
|
+
* @typedef {string | {name: string, fancy?: string, allow?: string, numbers?: boolean, lambdas?: boolean}} InputSpec
|
|
70
|
+
*/
|
|
61
71
|
/**
|
|
62
72
|
* @typedef {{
|
|
63
73
|
* pass: boolean,
|
|
@@ -73,48 +83,55 @@ export class Quest {
|
|
|
73
83
|
/**
|
|
74
84
|
* @description A combinator problem with a set of test cases for the proposed solution.
|
|
75
85
|
* @param {{
|
|
76
|
-
*
|
|
77
|
-
* descr: string?,
|
|
78
|
-
* subst: string?,
|
|
79
|
-
* allow: string?,
|
|
80
|
-
* numbers: boolean?,
|
|
81
|
-
* vars: string[]?,
|
|
82
|
-
* engine: SKI?,
|
|
83
|
-
* engineFull: SKI?,
|
|
86
|
+
* input: InputSpec | InputSpec[],
|
|
84
87
|
* cases: TestCase[],
|
|
88
|
+
*
|
|
89
|
+
* // the rest is optional
|
|
90
|
+
|
|
91
|
+
* allow?: string,
|
|
92
|
+
* numbers?: boolean,
|
|
93
|
+
* env?: string[],
|
|
94
|
+
* engine?: SKI,
|
|
95
|
+
* engineFull?: SKI,
|
|
96
|
+
*
|
|
97
|
+
* // metadata, also any fields not listed here will go to quest.meta.???
|
|
98
|
+
* id?: string|number,
|
|
99
|
+
* name?: string,
|
|
100
|
+
* intro?: string|string[], // multiple strings will be concatenated with spaces
|
|
85
101
|
* }} options
|
|
102
|
+
*
|
|
103
|
+
* @example const quest = new Quest({
|
|
104
|
+
* input: 'identity',
|
|
105
|
+
* cases: [
|
|
106
|
+
* ['identity x', 'x'],
|
|
107
|
+
* ],
|
|
108
|
+
* allow: 'SK',
|
|
109
|
+
* intro: 'Find a combinator that behaves like the identity function.',
|
|
110
|
+
* });
|
|
111
|
+
* quest.check('S K K'); // { pass: true, details: [...], ... }
|
|
112
|
+
* quest.check('K S'); // { pass: false, details: [...], ... }
|
|
113
|
+
* quest.check('K x'); // fail! internal variable x is not equal to free variable x,
|
|
114
|
+
* // despite having the same name.
|
|
115
|
+
* quest.check('I'); // fail! I not in the allowed list.
|
|
86
116
|
*/
|
|
87
|
-
constructor(options?: {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
subst: string | null;
|
|
91
|
-
allow: string | null;
|
|
92
|
-
numbers: boolean | null;
|
|
93
|
-
vars: string[] | null;
|
|
94
|
-
engine: SKI | null;
|
|
95
|
-
engineFull: SKI | null;
|
|
96
|
-
cases: TestCase[];
|
|
97
|
-
});
|
|
98
|
-
engine: SKI;
|
|
99
|
-
engineFull: SKI;
|
|
117
|
+
constructor(options?: {});
|
|
118
|
+
engine: any;
|
|
119
|
+
engineFull: any;
|
|
100
120
|
restrict: {
|
|
101
|
-
allow:
|
|
102
|
-
numbers:
|
|
121
|
+
allow: any;
|
|
122
|
+
numbers: any;
|
|
103
123
|
lambdas: any;
|
|
104
124
|
};
|
|
105
|
-
|
|
106
|
-
subst: string[] | (string & any[]);
|
|
125
|
+
env: {};
|
|
107
126
|
input: any[];
|
|
108
|
-
|
|
127
|
+
envFull: {};
|
|
109
128
|
cases: any[];
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
descr: string | null;
|
|
115
|
-
};
|
|
129
|
+
name: any;
|
|
130
|
+
intro: any;
|
|
131
|
+
id: any;
|
|
132
|
+
meta: {};
|
|
116
133
|
/**
|
|
117
|
-
* Display allowed terms based on what engine thinks of this.
|
|
134
|
+
* Display allowed terms based on what engine thinks of this.env + this.restrict.allow
|
|
118
135
|
* @return {string}
|
|
119
136
|
*/
|
|
120
137
|
allowed(): string;
|
|
@@ -153,21 +170,21 @@ declare class Case {
|
|
|
153
170
|
* @param {{
|
|
154
171
|
* max?: number,
|
|
155
172
|
* note?: string,
|
|
156
|
-
*
|
|
173
|
+
* env?: {[key:string]: Expr},
|
|
157
174
|
* engine: SKI
|
|
158
175
|
* }} options
|
|
159
176
|
*/
|
|
160
177
|
constructor(input: typeof import("./expr").FreeVar[], options: {
|
|
161
178
|
max?: number;
|
|
162
179
|
note?: string;
|
|
163
|
-
|
|
180
|
+
env?: {
|
|
164
181
|
[key: string]: typeof import("./expr").Expr;
|
|
165
182
|
};
|
|
166
183
|
engine: SKI;
|
|
167
184
|
});
|
|
168
185
|
max: number;
|
|
169
186
|
note: string;
|
|
170
|
-
|
|
187
|
+
env: {
|
|
171
188
|
[key: string]: typeof import("./expr").Expr;
|
|
172
189
|
};
|
|
173
190
|
input: typeof import("./expr").FreeVar[];
|
|
@@ -184,11 +201,11 @@ declare class Subst {
|
|
|
184
201
|
/**
|
|
185
202
|
* @descr A placeholder object with exactly n free variables to be substituted later.
|
|
186
203
|
* @param {Expr} expr
|
|
187
|
-
* @param {FreeVar[]}
|
|
204
|
+
* @param {FreeVar[]} env
|
|
188
205
|
*/
|
|
189
|
-
constructor(expr: typeof import("./expr").Expr,
|
|
206
|
+
constructor(expr: typeof import("./expr").Expr, env: typeof import("./expr").FreeVar[]);
|
|
190
207
|
expr: typeof import("./expr").Expr;
|
|
191
|
-
|
|
208
|
+
env: typeof import("./expr").FreeVar[];
|
|
192
209
|
apply(list: any): typeof import("./expr").Expr;
|
|
193
210
|
}
|
|
194
211
|
export {};
|