@dallaylaen/ski-interpreter 2.8.2 → 2.9.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.
@@ -2,54 +2,44 @@ import { Expr, Named, FormatOptions, TermInfo, toposort } from './expr';
2
2
  /**
3
3
  * Extra utilities that do not belong in the core.
4
4
  */
5
- /**
6
- * @experimental
7
- * Look for an expression that matches the predicate,
8
- * starting with the seed and applying the terms to one another.
9
- *
10
- * A predicate returning 0 (or nothing) means "keep looking",
11
- * a positive number stands for "found",
12
- * and a negative means "discard this term from further applications".
13
- *
14
- * The order of search is from shortest to longest expressions.
15
- *
16
- * @param {Expr[]} seed
17
- * @param {object} options
18
- * @param {number} [options.depth] - maximum generation to search for
19
- * @param {number} [options.tries] - maximum number of tries before giving up
20
- * @param {boolean} [options.infer] - whether to call infer(), default true.
21
- * @param {number} [options.maxArgs] - arguments in infer()
22
- * @param {number} [options.max] - step limit in infer()
23
- * @param {boolean} [options.noskip] - prevents skipping equivalent terms. Always true if infer is false.
24
- * @param {boolean} [retain] - if true. also add the whole cache to returned value
25
- * @param {({gen: number, total: number, probed: number, step: boolean}) => void} [options.progress]
26
- * @param {number} [options.progressInterval] - minimum number of tries between calls to options.progress, default 1000.
27
- * @param {(e: Expr, props: {}) => number?} predicate
28
- * @return {{expr?: Expr, total: number, probed: number, gen: number, cache?: Expr[][]}}
29
- */
5
+ export type SearchCallbackResult = {
6
+ /** ≥0 = cache at gen+offset; negative = discard; omitted = auto-compute */
7
+ offset?: number;
8
+ /** true = emit this term as a found result */
9
+ found?: boolean;
10
+ /** true = stop the search (after yielding if found is also true) */
11
+ stop?: boolean;
12
+ };
30
13
  export type SearchOptions = {
14
+ /** maximum generation to search for */
31
15
  depth?: number;
16
+ /** maximum number of tried terms before giving up */
32
17
  tries?: number;
18
+ /** whether to call infer() on each term; default true */
33
19
  infer?: boolean;
20
+ /** maximum number of arguments in infer(), see {@link infer} */
34
21
  maxArgs?: number;
22
+ /** maximum number of steps in infer(), see {@link infer} */
35
23
  max?: number;
24
+ /** prevents skipping equivalent terms. Always true if infer is false. */
36
25
  noskip?: boolean;
37
- retain?: boolean;
38
- progress?: (info: {
39
- gen: number;
40
- total: number;
41
- probed: number;
42
- step: boolean;
43
- }) => void;
26
+ /** minimum number of tries between progress yields, default 1000 */
44
27
  progressInterval?: number;
45
28
  };
46
- export type SearchCallback = (e: Expr, props: TermInfo) => (number | undefined);
47
- export type SearchResult = {
29
+ export type SearchCallback = (e: Expr, props: TermInfo) => (SearchCallbackResult | number | undefined);
30
+ /** Yielded by the search generator on every progress tick and on each found term. */
31
+ export type SearchProgress = {
32
+ /** The found expression; present only when found === true. */
48
33
  expr?: Expr;
34
+ /** True when this yield carries a found term. */
35
+ found: boolean;
36
+ /** True when this is a new-generation tick (step progress), false for mid-generation ticks. */
37
+ step: boolean;
38
+ gen: number;
49
39
  total: number;
50
40
  probed: number;
51
- gen: number;
52
- cache?: Expr[][];
41
+ /** The full generation cache at the time of this yield. */
42
+ cache: Expr[][];
53
43
  };
54
44
  export type EquivResult = {
55
45
  steps: number;
@@ -58,7 +48,7 @@ export type EquivResult = {
58
48
  canonical: [Expr | null, Expr | null];
59
49
  };
60
50
  /**
61
- * Converts an unknown object into a FormatOptions, or returns an error it it is not valid.
51
+ * Converts an unknown object into a FormatOptions, or returns an error if it is not valid.
62
52
  * A null/undefined counts as an empty options object (and is thus valid).
63
53
  */
64
54
  declare function checkFormatOptions(raw: unknown): {
@@ -102,10 +92,29 @@ declare function declare(expr: Expr, env?: Record<string, Named>): string;
102
92
  declare function deepFormat(obj: any, options?: FormatOptions): any;
103
93
  /**
104
94
  * @experimental
105
- * Look for an expression that matches the predicate,
106
- * starting with the seed and applying the terms to one another.
95
+ * Given a seed set of expressions, search for expressions that match the predicate
96
+ * by applying already known expressions to one another.
97
+ * Seen terms are organized into generations, with gen(g f) == gen(g) + gen(f) + an optional offset
98
+ * (e.g. we want to study duplicating terms later than the discarding ones).
99
+ *
100
+ * The predicate receives a term and its inferred properties (if `infer` is true) and
101
+ * returns an object with the following optional properties:
102
+ * - `found`: boolean - if true, the expression is yielded as a result;
103
+ * - `stop`: boolean - if true, the search stops after yielding, independent of `found`;
104
+ * - `offset`: a number with the following meaning:
105
+ * - negative: discard the expression entirely;
106
+ * - 0: keep the expression to compute further terms;
107
+ * - n >0: keep the expression, but delay its use by n generations.
108
+ * Or it can just return a number, which is shorthand for `{ offset: n }`.
109
+ *
110
+ * An intermediate result is yielded, when:
111
+ * - a term is found (`found === true`) and/or the search is stopped (`stop === true`);
112
+ * - a new generation is started;
113
+ * - the number of tries since the last yield exceeds `progressInterval`.
114
+ * Such approach allows implementing progress bars and prevents the search from blocking for too long.
115
+ *
107
116
  */
108
- declare function search(seed: Expr[], options: SearchOptions, predicate: SearchCallback): SearchResult;
117
+ declare function search(seed: Expr[], options: SearchOptions, predicate: SearchCallback): Generator<SearchProgress>;
109
118
  export declare const extras: {
110
119
  search: typeof search;
111
120
  deepFormat: typeof deepFormat;
@@ -41,7 +41,7 @@ export declare class SKI extends Parser {
41
41
  };
42
42
  static church(n: number): Church;
43
43
  static extras: {
44
- search: (seed: import("./expr").Expr[], options: import("./extras").SearchOptions, predicate: import("./extras").SearchCallback) => import("./extras").SearchResult;
44
+ search: (seed: import("./expr").Expr[], options: import("./extras").SearchOptions, predicate: import("./extras").SearchCallback) => Generator<import("./extras").SearchProgress>;
45
45
  deepFormat: (obj: any, options?: import("./expr").FormatOptions) => any;
46
46
  declare: (expr: import("./expr").Expr, env?: Record<string, import("./expr").Named>) => string;
47
47
  toposort: typeof toposort;
@@ -118,6 +118,7 @@ export declare class Quest {
118
118
  id?: string | number;
119
119
  name?: string;
120
120
  intro?: string;
121
+ created?: Date;
121
122
  meta?: Record<string, unknown>;
122
123
  constructor(options: QuestSpec);
123
124
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dallaylaen/ski-interpreter",
3
- "version": "2.8.2",
3
+ "version": "2.9.0",
4
4
  "description": "Simple Kombinator Interpreter - a combinatory logic & lambda calculus parser and interpreter. Supports SKI, BCKW, Church numerals, and setting up assertions ('quests') involving all of the above.",
5
5
  "keywords": [
6
6
  "combinatory logic",