@dallaylaen/ski-interpreter 2.3.2 → 2.4.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,3 +1,5 @@
1
+ import { Expr, Named, FormatOptions, TermInfo } from './expr';
2
+ import { toposort } from './toposort';
1
3
  /**
2
4
  * @desc Extra utilities that do not belong in the core.
3
5
  */
@@ -26,20 +28,31 @@
26
28
  * @param {(e: Expr, props: {}) => number?} predicate
27
29
  * @return {{expr?: Expr, total: number, probed: number, gen: number, cache?: Expr[][]}}
28
30
  */
29
- export function search(seed: Expr[], options: {
31
+ type SearchOptions = {
30
32
  depth?: number;
31
33
  tries?: number;
32
34
  infer?: boolean;
33
35
  maxArgs?: number;
34
36
  max?: number;
35
37
  noskip?: boolean;
36
- }, predicate: (e: Expr, props: {}) => number | null): {
38
+ retain?: boolean;
39
+ progress?: (info: {
40
+ gen: number;
41
+ total: number;
42
+ probed: number;
43
+ step: boolean;
44
+ }) => void;
45
+ progressInterval?: number;
46
+ };
47
+ type SearchCallback = (e: Expr, props: TermInfo) => (number | undefined);
48
+ type SearchResult = {
37
49
  expr?: Expr;
38
50
  total: number;
39
51
  probed: number;
40
52
  gen: number;
41
53
  cache?: Expr[][];
42
54
  };
55
+ declare function search(seed: Expr[], options: SearchOptions, predicate: SearchCallback): SearchResult;
43
56
  /**
44
57
  * @desc Recursively replace all instances of Expr in a data structure with
45
58
  * respective string representation using the format() options.
@@ -48,12 +61,8 @@ export function search(seed: Expr[], options: {
48
61
  * May be useful for debugging or diagnostic output.
49
62
  *
50
63
  * @experimental
51
- *
52
- * @param {any} obj
53
- * @param {object} [options] - see Expr.format()
54
- * @returns {any}
55
64
  */
56
- export function deepFormat(obj: any, options?: object): any;
65
+ declare function deepFormat(obj: any, options?: FormatOptions): any;
57
66
  /**
58
67
  * @desc Given an expression and a hash of named terms,
59
68
  * return a semicolon-separated string that declares said expression
@@ -68,21 +77,13 @@ export function deepFormat(obj: any, options?: object): any;
68
77
  * @param {{[s: string]: Named}} [env]
69
78
  * @returns {string}
70
79
  */
71
- export function declare(expr: Expr, env?: {
80
+ declare function declare(expr: Expr, env?: {
72
81
  [s: string]: Named;
73
82
  }): string;
74
- /**
75
- * @experimental
76
- * @desc Fold an application tree bottom to top.
77
- * For each subtree, the function is given the term in the root position and
78
- * a list of the results of folding its arguments.
79
- *
80
- * E,g, fold('x y (z t)', f) results in f(x, [f(y, []), f(z, [f(t, [])])])
81
- *
82
- * @template T
83
- * @param {Expr} expr
84
- * @param {(head: Expr, tail: T[]) => T} fun
85
- * @return {T}
86
- */
87
- export function foldr<T>(expr: Expr, fun: (head: Expr, tail: T[]) => T): T;
88
- import { Expr } from "./expr";
83
+ export declare const extras: {
84
+ search: typeof search;
85
+ deepFormat: typeof deepFormat;
86
+ declare: typeof declare;
87
+ toposort: typeof toposort;
88
+ };
89
+ export {};
@@ -0,0 +1,68 @@
1
+ import { FreeVar, Church } from './expr';
2
+ import { Parser } from './parser';
3
+ import { Quest } from './quest';
4
+ import { toposort } from './toposort';
5
+ export declare class SKI extends Parser {
6
+ static native: import("./internal").Dict<import("./expr").Native>;
7
+ static control: {
8
+ descend: <T>(value: T) => import("./internal").TraverseControl<T>;
9
+ prune: <T>(value: T) => import("./internal").TraverseControl<T>;
10
+ redo: <T>(value: T) => import("./internal").TraverseControl<T>;
11
+ stop: <T>(value: T) => import("./internal").TraverseControl<T>;
12
+ };
13
+ static classes: {
14
+ Expr: typeof import("./expr").Expr;
15
+ App: typeof import("./expr").App;
16
+ Named: typeof import("./expr").Named;
17
+ FreeVar: typeof FreeVar;
18
+ Native: typeof import("./expr").Native;
19
+ Lambda: typeof import("./expr").Lambda;
20
+ Church: typeof Church;
21
+ Alias: typeof import("./expr").Alias;
22
+ };
23
+ static B: import("./expr").Native;
24
+ static C: import("./expr").Native;
25
+ static I: import("./expr").Native;
26
+ static K: import("./expr").Native;
27
+ static S: import("./expr").Native;
28
+ static W: import("./expr").Native;
29
+ static vars(scope?: object): {
30
+ [key: string]: FreeVar;
31
+ };
32
+ static church(n: number): Church;
33
+ static extras: {
34
+ search: (seed: import("./expr").Expr[], options: {
35
+ depth?: number;
36
+ tries?: number;
37
+ infer?: boolean;
38
+ maxArgs?: number;
39
+ max?: number;
40
+ noskip?: boolean;
41
+ retain?: boolean;
42
+ progress?: (info: {
43
+ gen: number;
44
+ total: number;
45
+ probed: number;
46
+ step: boolean;
47
+ }) => void;
48
+ progressInterval?: number;
49
+ }, predicate: (e: import("./expr").Expr, props: import("./expr").TermInfo) => (number | undefined)) => {
50
+ expr?: import("./expr").Expr;
51
+ total: number;
52
+ probed: number;
53
+ gen: number;
54
+ cache?: import("./expr").Expr[][];
55
+ };
56
+ deepFormat: (obj: any, options?: import("./expr").FormatOptions) => any;
57
+ declare: (expr: import("./expr").Expr, env?: {
58
+ [s: string]: import("./expr").Named;
59
+ }) => string;
60
+ toposort: typeof toposort;
61
+ };
62
+ static Quest: typeof Quest;
63
+ }
64
+ declare global {
65
+ interface Window {
66
+ SKI: typeof SKI;
67
+ }
68
+ }
@@ -1,12 +1,15 @@
1
- export class Tokenizer {
1
+ export type Dict<T> = {
2
+ [key: string]: T;
3
+ };
4
+ export declare class Tokenizer {
2
5
  /**
3
6
  * @desc Create a tokenizer that splits strings into tokens according to the given terms.
4
7
  * The terms are interpreted as regular expressions, and are sorted by length
5
8
  * to ensure that longer matches are preferred over shorter ones.
6
9
  * @param {...string|RegExp} terms
7
10
  */
8
- constructor(...terms: (string | RegExp)[]);
9
11
  rex: RegExp;
12
+ constructor(...terms: (string | RegExp)[]);
10
13
  /**
11
14
  * @desc Split the given string into tokens according to the terms specified in the constructor.
12
15
  * @param {string} str
@@ -23,14 +26,33 @@ export class Tokenizer {
23
26
  * @param {string} [spec]
24
27
  * @returns {Set<string>}
25
28
  */
26
- export function restrict(set: Set<string>, spec?: string): Set<string>;
29
+ export declare function restrict(set: Set<string>, spec?: string): Set<string>;
30
+ export type TraverseDecorator<T> = (value: T) => TraverseControl<T>;
31
+ export type TraverseValue<T> = T | TraverseControl<T> | null | undefined;
32
+ export declare class TraverseControl<T> {
33
+ /**
34
+ * @desc A wrapper for values returned by fold/traverse callbacks
35
+ * which instructs the traversal to alter its behavior while
36
+ * retaining the value in question.
37
+ *
38
+ * This class is instantiated internally be `SKI.control.*` functions,
39
+ * and is not intended to be used directly by client code.
40
+ *
41
+ * @template T
42
+ * @param {T} value
43
+ * @param {function(T): TraverseControl<T>} decoration
44
+ */
45
+ value: T;
46
+ decoration: TraverseDecorator<T>;
47
+ constructor(value: T, decoration: TraverseDecorator<T>);
48
+ }
27
49
  /**
28
50
  * @private
29
51
  * @template T
30
52
  * @param {T|TraverseControl<T>|null} value
31
53
  * @returns {[T?, function|undefined]}
32
54
  */
33
- export function unwrap<T>(value: T | TraverseControl<T> | null): [T?, Function | undefined];
55
+ export declare function unwrap<T>(value: TraverseValue<T>): [T?, TraverseDecorator<T>?];
34
56
  /**
35
57
  * @desc Prepare a self-referencing wrapper function for use as a fold/traverse control decorator.
36
58
  *
@@ -44,22 +66,4 @@ export function unwrap<T>(value: T | TraverseControl<T> | null): [T?, Function |
44
66
  * @param {string} [label]
45
67
  * @returns {function(T): TraverseControl<T>}
46
68
  */
47
- export function prepareWrapper<T>(label?: string): (arg0: T) => TraverseControl<T>;
48
- declare class TraverseControl {
49
- /**
50
- * @desc A wrapper for values returned by fold/traverse callbacks
51
- * which instructs the traversal to alter its behavior while
52
- * retaining the value in question.
53
- *
54
- * This class is instantiated internally be `SKI.control.*` functions,
55
- * and is not intended to be used directly by client code.
56
- *
57
- * @template T
58
- * @param {T} value
59
- * @param {function(T): TraverseControl<T>} decoration
60
- */
61
- constructor(value: T, decoration: (arg0: T) => TraverseControl<T>);
62
- value: T;
63
- decoration: (arg0: T) => TraverseControl<T>;
64
- }
65
- export {};
69
+ export declare function prepareWrapper(label: string): <T>(value: T) => TraverseControl<T>;
@@ -1,4 +1,29 @@
1
- export class SKI {
1
+ import { Expr, Alias, Native, Invocation } from './expr';
2
+ export type ParserOptions = {
3
+ allow?: string;
4
+ numbers?: boolean;
5
+ lambdas?: boolean;
6
+ terms?: {
7
+ [key: string]: Expr | string;
8
+ } | string[];
9
+ annotate?: boolean;
10
+ };
11
+ export type ParseOptions = {
12
+ env?: {
13
+ [key: string]: Expr;
14
+ };
15
+ scope?: object;
16
+ numbers?: boolean;
17
+ lambdas?: boolean;
18
+ allow?: string;
19
+ };
20
+ export type AddOptions = {
21
+ note?: string;
22
+ canonize?: boolean;
23
+ fancy?: string;
24
+ arity?: number;
25
+ };
26
+ export declare class Parser {
2
27
  /**
3
28
  *
4
29
  * @param {{
@@ -9,23 +34,14 @@ export class SKI {
9
34
  * annotate?: boolean,
10
35
  * }} [options]
11
36
  */
12
- constructor(options?: {
13
- allow?: string;
14
- numbers?: boolean;
15
- lambdas?: boolean;
16
- terms?: {
17
- [key: string]: typeof classes.Expr | string;
18
- } | string[];
19
- annotate?: boolean;
20
- });
21
37
  annotate: boolean;
22
38
  known: {
23
- [key: string]: classes.Native;
39
+ [name: string]: Expr;
24
40
  };
41
+ allow: Set<string>;
25
42
  hasNumbers: boolean;
26
43
  hasLambdas: boolean;
27
- /** @type {Set<string>} */
28
- allow: Set<string>;
44
+ constructor(options?: ParserOptions);
29
45
  /**
30
46
  * @desc Declare a new term
31
47
  * If the first argument is an Alias, it is added as is.
@@ -49,7 +65,7 @@ export class SKI {
49
65
  * @param {number} [options.arity] - custom arity for the term, default is inferred from the implementation
50
66
  * @return {SKI} chainable
51
67
  */
52
- add(term: typeof classes.Alias | string, impl?: string | typeof classes.Expr | ((arg0: typeof classes.Expr) => Partial), options?: object | string): SKI;
68
+ add(term: Alias | string, impl?: Expr | string | ((arg: Expr) => Invocation), options?: AddOptions | string): this;
53
69
  /**
54
70
  * @desc Internal helper for add() that creates an Alias or Native term from the given arguments.
55
71
  * @param {Alias|string} term
@@ -57,7 +73,7 @@ export class SKI {
57
73
  * @returns {Native|Alias}
58
74
  * @private
59
75
  */
60
- private _named;
76
+ _named(term: Alias | string, impl?: Expr | string | ((arg: Expr) => Invocation)): Native | Alias;
61
77
  /**
62
78
  * @desc Declare a new term if it is not known, otherwise just allow it.
63
79
  * Currently only used by quests.
@@ -68,7 +84,7 @@ export class SKI {
68
84
  * @param {string|Expr|function(Expr):Partial} impl
69
85
  * @returns {SKI}
70
86
  */
71
- maybeAdd(name: string | typeof classes.Alias, impl: string | typeof classes.Expr | ((arg0: typeof classes.Expr) => Partial)): SKI;
87
+ maybeAdd(name: string, impl: Expr | string | ((arg: Expr) => Invocation)): this;
72
88
  /**
73
89
  * @desc Declare and remove multiple terms at once
74
90
  * term=impl adds term
@@ -76,7 +92,7 @@ export class SKI {
76
92
  * @param {string[]} list
77
93
  * @return {SKI} chainable
78
94
  */
79
- bulkAdd(list: string[]): SKI;
95
+ bulkAdd(list: string[]): this;
80
96
  /**
81
97
  * Restrict the interpreter to given terms. Terms prepended with '+' will be added
82
98
  * and terms preceeded with '-' will be removed.
@@ -87,7 +103,7 @@ export class SKI {
87
103
  * @param {string} spec
88
104
  * @return {SKI} chainable
89
105
  */
90
- restrict(spec: string): SKI;
106
+ restrict(spec: string): this;
91
107
  /**
92
108
  *
93
109
  * @param {string} spec
@@ -99,13 +115,13 @@ export class SKI {
99
115
  * @param {String} name
100
116
  * @return {SKI}
101
117
  */
102
- remove(name: string): SKI;
118
+ remove(name: string): this;
103
119
  /**
104
120
  *
105
121
  * @return {{[key:string]: Native|Alias}}
106
122
  */
107
123
  getTerms(): {
108
- [key: string]: typeof classes.Native | typeof classes.Alias;
124
+ [key: string]: Expr;
109
125
  };
110
126
  /**
111
127
  * @desc Export term declarations for use in bulkAdd().
@@ -124,15 +140,7 @@ export class SKI {
124
140
  * @param {string} [options.allow]
125
141
  * @return {Expr}
126
142
  */
127
- parse<T_1>(source: string, options?: {
128
- env?: {
129
- [keys: string]: typeof classes.Expr;
130
- };
131
- scope?: T_1;
132
- numbers?: boolean;
133
- lambdas?: boolean;
134
- allow?: string;
135
- }): typeof classes.Expr;
143
+ parse(source: string, options?: ParseOptions): Expr;
136
144
  /**
137
145
  * @desc Parse a single line of source code, without splitting it into declarations.
138
146
  * Internal, always use parse() instead.
@@ -147,17 +155,9 @@ export class SKI {
147
155
  * @param {string} [options.allow]
148
156
  * @return {Expr} parsed expression
149
157
  */
150
- parseLine<T_1>(source: string, env?: {
151
- [keys: string]: typeof classes.Expr;
152
- }, options?: {
153
- env?: {
154
- [keys: string]: typeof classes.Expr;
155
- };
156
- scope?: T_1;
157
- numbers?: boolean;
158
- lambdas?: boolean;
159
- allow?: string;
160
- }): typeof classes.Expr;
158
+ parseLine(source: string, env?: {
159
+ [key: string]: Expr;
160
+ }, options?: ParseOptions): Expr;
161
161
  toJSON(): {
162
162
  version: string;
163
163
  allow: string;
@@ -167,46 +167,3 @@ export class SKI {
167
167
  terms: string[];
168
168
  };
169
169
  }
170
- export namespace SKI {
171
- /**
172
- * Public static shortcuts to common functions (see also ./extras.js)
173
- */
174
- /**
175
- * @desc Create a proxy object that generates variables on demand,
176
- * with names corresponding to the property accessed.
177
- * Different invocations will return distinct variables,
178
- * even if with the same name.
179
- *
180
- *
181
- * @example const {x, y, z} = SKI.vars();
182
- * x.name; // 'x'
183
- * x instanceof FreeVar; // true
184
- * x.apply(y).apply(z); // x(y)(z)
185
- *
186
- * @template T
187
- * @param {T} [scope] - optional context to bind the generated variables to
188
- * @return {{[key: string]: FreeVar}}
189
- */
190
- export function vars<T_1>(scope?: T_1): {
191
- [key: string]: typeof import("./expr").FreeVar;
192
- };
193
- /**
194
- * Convert a number to Church encoding
195
- * @param {number} n
196
- * @return {Church}
197
- */
198
- export function church(n: number): typeof import("./expr").Church;
199
- export { classes };
200
- export { native };
201
- export let control: {
202
- descend: (arg0: T) => TraverseControl<T>;
203
- prune: (arg0: T) => TraverseControl<T>;
204
- redo: (arg0: T) => TraverseControl<T>;
205
- stop: (arg0: T) => TraverseControl<T>;
206
- };
207
- }
208
- import classes = require("./expr");
209
- declare const native: {
210
- [key: string]: classes.Native;
211
- };
212
- export {};
@@ -0,0 +1,232 @@
1
+ import { Parser } from './parser';
2
+ import { Expr, FreeVar, Alias } from './expr';
3
+ export type CaseResult = {
4
+ pass: boolean;
5
+ reason?: string;
6
+ steps: number;
7
+ start: Expr;
8
+ found: Expr;
9
+ expected?: Expr;
10
+ note?: string;
11
+ args: Expr[];
12
+ case: Case;
13
+ };
14
+ export type Capability = {
15
+ linear?: boolean;
16
+ affine?: boolean;
17
+ normal?: boolean;
18
+ proper?: boolean;
19
+ discard?: boolean;
20
+ duplicate?: boolean;
21
+ arity?: number;
22
+ };
23
+ export type TestCase = [
24
+ string,
25
+ string
26
+ ] | [{
27
+ max?: number;
28
+ }, string, string] | [{
29
+ caps: Capability;
30
+ max?: number;
31
+ }, string];
32
+ export type InputSpec = {
33
+ name: string;
34
+ fancy?: string;
35
+ allow?: string;
36
+ numbers?: boolean;
37
+ lambdas?: boolean;
38
+ };
39
+ export type QuestResult = {
40
+ pass: boolean;
41
+ details: CaseResult[];
42
+ expr?: Expr;
43
+ input: Expr[] | string[];
44
+ exception?: Error;
45
+ steps: number;
46
+ weight?: number;
47
+ };
48
+ type QuestMeta = {
49
+ [key: string]: any;
50
+ };
51
+ export type QuestSpec = {
52
+ input: string | InputSpec | (string | InputSpec)[];
53
+ cases: TestCase[];
54
+ allow?: string;
55
+ numbers?: boolean;
56
+ lambdas?: boolean;
57
+ env?: string[];
58
+ engine?: Parser;
59
+ engineFull?: Parser;
60
+ id?: string | number;
61
+ name?: string;
62
+ intro?: string | string[];
63
+ } & QuestMeta;
64
+ export type SelfCheck = {
65
+ accepted?: string[][];
66
+ rejected?: string[][];
67
+ };
68
+ type AddCaseOptions = {
69
+ engine?: Parser;
70
+ env?: {
71
+ [key: string]: Expr;
72
+ };
73
+ max?: number;
74
+ note?: string;
75
+ caps?: Capability;
76
+ };
77
+ export declare class Quest {
78
+ /**
79
+ * @description A combinator problem with a set of test cases for the proposed solution.
80
+ * @param {QuestSpec} options
81
+ * @example const quest = new Quest({
82
+ * input: 'identity',
83
+ * cases: [
84
+ * ['identity x', 'x'],
85
+ * ],
86
+ * allow: 'SK',
87
+ * intro: 'Find a combinator that behaves like the identity function.',
88
+ * });
89
+ * quest.check('S K K'); // { pass: true, details: [...], ... }
90
+ * quest.check('K S'); // { pass: false, details: [...], ... }
91
+ * quest.check('K x'); // fail! internal variable x is not equal to free variable x,
92
+ * // despite having the same name.
93
+ * quest.check('I'); // fail! I not in the allowed list.
94
+ */
95
+ input: (InputSpec & {
96
+ placeholder: FreeVar;
97
+ })[];
98
+ cases: Case[];
99
+ engineFull: Parser;
100
+ engine: Parser;
101
+ restrict: {
102
+ allow?: string;
103
+ numbers?: boolean;
104
+ lambdas?: boolean;
105
+ };
106
+ env: {
107
+ [key: string]: Expr;
108
+ };
109
+ envFull: {
110
+ [key: string]: Expr;
111
+ };
112
+ id?: string | number;
113
+ name?: string;
114
+ intro?: string;
115
+ meta?: QuestMeta;
116
+ constructor(options: QuestSpec);
117
+ /**
118
+ * Display allowed terms based on what engine thinks of this.env + this.restrict.allow
119
+ * @return {string}
120
+ */
121
+ allowed(): string;
122
+ addInput(term: string | InputSpec): void;
123
+ /**
124
+ *
125
+ * @param {{} | string} opt
126
+ * @param {string} terms
127
+ * @return {Quest}
128
+ */
129
+ add(opt: AddCaseOptions | string, ...terms: string[]): this;
130
+ /**
131
+ * @description Statefully parse a list of strings into expressions or fancy aliases thereof.
132
+ * @param {string[]} input
133
+ * @return {{terms: Expr[], weight: number}}
134
+ */
135
+ prepare(...input: string[]): {
136
+ prepared: (FreeVar | Alias)[];
137
+ weight: number;
138
+ };
139
+ /**
140
+ *
141
+ * @param {string} input
142
+ * @return {QuestResult}
143
+ */
144
+ check(...input: string[]): QuestResult;
145
+ verify(options: {
146
+ solutions?: SelfCheck | {
147
+ [key: string | number]: SelfCheck;
148
+ };
149
+ seen?: Set<string | number>;
150
+ date?: boolean;
151
+ }): {
152
+ [key: string]: unknown;
153
+ } | null;
154
+ /**
155
+ * @desc Verify that solutions that are expected to pass/fail do so.
156
+ * @param {SelfCheck|{[key: string]: SelfCheck}} dataset
157
+ * @return {{shouldPass: {input: string[], result: QuestResult}[], shouldFail: {input: string[], result: QuestResult}[]} | null}
158
+ */
159
+ verifySolutions(dataset: SelfCheck | {
160
+ [key: string | number]: SelfCheck;
161
+ }): {
162
+ shouldPass: {
163
+ input: string[];
164
+ result: QuestResult;
165
+ }[];
166
+ shouldFail: {
167
+ input: string[];
168
+ result: QuestResult;
169
+ }[];
170
+ } | null;
171
+ verifyMeta(options?: {
172
+ date?: boolean;
173
+ }): {
174
+ [key: string]: unknown;
175
+ };
176
+ /**
177
+ *
178
+ * @return {TestCase[]}
179
+ */
180
+ show(): Case[];
181
+ static Group: new (options: {
182
+ name?: string;
183
+ intro?: string | string[];
184
+ id?: string | number;
185
+ content?: (Quest | QuestSpec)[];
186
+ }) => {
187
+ verify: (options: {
188
+ seen?: Set<string | number>;
189
+ date?: boolean;
190
+ }) => {
191
+ [key: string]: unknown;
192
+ };
193
+ };
194
+ static Case: new (input: FreeVar[], options: AddCaseOptions) => Case;
195
+ }
196
+ declare class Case {
197
+ /**
198
+ * @param {FreeVar[]} input
199
+ * @param {{
200
+ * max?: number,
201
+ * note?: string,
202
+ * env?: {[key:string]: Expr},
203
+ * engine: Parser
204
+ * }} options
205
+ */
206
+ max: number;
207
+ note: string;
208
+ env: {
209
+ [key: string]: Expr;
210
+ };
211
+ input: FreeVar[];
212
+ engine: Parser;
213
+ constructor(input: FreeVar[], options: AddCaseOptions);
214
+ parse(src: string): Subst;
215
+ /**
216
+ * @param {Expr} expr
217
+ * @return {CaseResult}
218
+ */
219
+ check(..._expr: Expr[]): CaseResult;
220
+ }
221
+ declare class Subst {
222
+ /**
223
+ * @descr A placeholder object with exactly n free variables to be substituted later.
224
+ * @param {Expr} expr
225
+ * @param {FreeVar[]} env
226
+ */
227
+ expr: Expr;
228
+ env: FreeVar[];
229
+ constructor(expr: Expr, env: FreeVar[]);
230
+ apply(list: Expr[]): Expr;
231
+ }
232
+ export {};
@@ -0,0 +1,30 @@
1
+ import { Expr, Named } from './expr';
2
+ /**
3
+ * @desc Sort a list in such a way that dependent terms come after the (named) terms they depend on.
4
+ * If env is given, only terms listed there are taken into account.
5
+ * If env is omitted, it will be implied from the list.
6
+ * If list is omitted, it will default to values of env.
7
+ * If just one term is given instead of a list, it will be coerced into a list.
8
+ *
9
+ * No terms outside env + list may ever appear in the result.
10
+ *
11
+ * The terms in env must be named and their names must match their keys.
12
+ *
13
+ * @param {Expr|Expr[]} list
14
+ * @param {{[s:string]: Named}} env
15
+ * @returns {{list: Expr[], env: {[s:string]: Named}}}
16
+ *
17
+ * @example
18
+ * const expr = ski.parse(src);
19
+ * toposort([expr], ski.getTerms()); // returns all terms appearing in Expr in correct order
20
+ */
21
+ type ToposortResult = {
22
+ list: Expr[];
23
+ env: {
24
+ [s: string]: Named;
25
+ };
26
+ };
27
+ export declare function toposort(list: Expr[] | Expr | undefined, env: {
28
+ [s: string]: Named;
29
+ } | undefined): ToposortResult;
30
+ export {};