gdp-wired 0.20.0 → 0.21.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/README.md CHANGED
@@ -76,8 +76,14 @@ All of these are proven automatically, and each proof is also a Lean theorem:
76
76
  proved them, as laws and lemmas with the source to paste.
77
77
  - **Invariants nobody wrote** (`gdp-wired/infer`): `inferLaws(rule, laws)` proves a law that holds but isn't inductive
78
78
  alone, with the laws it finds (bounds, sums and differences over the state, the same where a flag or a choice holds
79
- one value, and laws about every key of a map), each proven by the kernel with yours and handed back as the
79
+ one value, remainders of a value or of a sum or difference of two, x mod 2 = 0 for a counter stepping by 2, and laws
80
+ about every key of a map), each proven by the kernel with yours and handed back as the
80
81
  `r.law(...)` call that states it; a false law comes back with the run that breaks it (`examples/infer.ts`).
82
+ - **There exists**: laws that say some value is a witness, `exists(k => x.eq(k.times(2)))` ("x is even"), over
83
+ naturals, integers, yes/nos or a map's keys, each proven through a witness the prover finds from the kernel's
84
+ counterexamples (a term of the state, or a ghost the run carries: the witness before, moved by the request's values)
85
+ or the one given; an existential in the assumption is a value each request brings, and `inferLaws` finds parities
86
+ and multiples this way. Lean states each as `∃ w, ...`, proven by ⟨witness, proof⟩ (`examples/exists.ts`).
81
87
  - **Orderings at any distance**: "a refund never follows a release", through ghost state that watches the rule.
82
88
  - **Liveness**: "every ticket issued is served", in every run that keeps sending the requests that help, including under
83
89
  weak fairness (`examples/liveness.ts`).
@@ -97,6 +103,12 @@ All of these are proven automatically, and each proof is also a Lean theorem:
97
103
  goal reads), and the lemma a stuck one needs (g(x, 0) = 2x through g(x, a) = a + 2x; a bound on another function);
98
104
  `proveLoop` with no rank finds it (two phases' (x, y)) and the invariants it needs; the kernel checks the cyclic
99
105
  proof (`examples/cycles.ts`).
106
+ - **Recursive datatypes as values** (`gdp-wired/data`): lists, trees, rose trees and their forests, declared by their
107
+ constructors; functions over them by structural recursion, or by any recursion whose termination is proven first (a
108
+ merge of two lists, a quicksort: the measure found, (size xs, size ys) or a sum of sizes, and each call's decrease
109
+ proven by the kernel before the function's equation is used; one that doesn't terminate is refused with the reason);
110
+ `proveData` finds the induction (structural, mutual, or the function's own call graph ranked by its measure) and the
111
+ lemmas, each proof checked in Lean against the `inductive` and the functions as declared (`examples/data.ts`).
100
112
  - **Records and variants**: inputs, state, results, map cells and list items made of named fields, or one of several
101
113
  cases each with fields of its own (a payment by card or in cash, a seat free, held or sold), every case covered
102
114
  (`examples/datatypes.ts`).
@@ -115,7 +127,9 @@ When a law is false, the GPU search finds a real run that breaks it. When a law
115
127
  **What it leaves to Lean or Bend.** Two things, and neither is a gap the next feature closes: proofs the prover would
116
128
  have to invent (induction over a recursive structure whose proof needs a lemma nobody stated and `discover` doesn't find, and arithmetic with
117
129
  products of unknowns beyond what products of facts and sums of squares give; integer arithmetic with induction or
118
- with products is undecidable; a lemma you state about a recurrence is proven, but a recursive datatype as a value is Lean's), and shipping an arbitrary algorithm as its proved source (gdp-wired ships the rule as JavaScript; Bend
130
+ with products is undecidable; a lemma you state about a recurrence is proven, and `proveData` finds the induction and lemmas for a recursive datatype as a value, up to six symbols a lemma, for
131
+ functions structural or whose termination it proves, its values naturals, integers (`integer`, Lean's `Int`, beside
132
+ `natural`) and datatypes), and shipping an arbitrary algorithm as its proved source (gdp-wired ships the rule as JavaScript; Bend
119
133
  compiles the proved source itself). The full list of what is and isn't in scope is in
120
134
  [`docs/comparison.md`](docs/comparison.md#gdp-wireds-scope-in-detail).
121
135
 
@@ -297,14 +311,20 @@ const soon = retry.law('the next try is at most 64 after the last request', ({ne
297
311
  reads them back as runtime values.
298
312
  - **Integers and decimals**: `int` and `decimal(places)` inputs, `.ints({...})` and `.decimals(places, {...})` state;
299
313
  `plus`, `minus`, `negate`, `times(k)` (k may be negative), `min`, `max`, `abs`, `isNegative`, comparisons with numbers
300
- (a decimal's literals are scaled: `price.atMost(19.99)`). Each is two naturals underneath, so the kernel and the Lean
301
- twin see nothing new; `rule.decode(state)` reads them back as numbers.
314
+ (a decimal's literals are scaled: `price.atMost(19.99)`), and `modBy(k)`, `divBy(k)` by Euclid's rule (−7 div 2 is
315
+ −4, −7 mod 2 is 1, as SMT-LIB and Lean's `Int` read them). Each is two naturals underneath, so the kernel twin sees
316
+ nothing new; the Lean export states each law about integers again over `Int` (`law0_int`, proven from the law over
317
+ the naturals by `omega`), and `rule.decode(state)` reads them back as numbers. A natural's `minus` stays truncated:
318
+ an integer is a kind of its own, chosen where a value may go below 0 (`examples/arith.ts`).
302
319
  - **Strings**: `str({like: ['*.internal'], maxLength: 64})`. A string is its interned name, its length and a bit per
303
320
  declared pattern (Cedar's glob), all computed from the string itself when the input is encoded. `s.like(pattern)`,
304
321
  `s.eq('admin')` (which carries the literal's length and pattern bits, so laws reason from either), `s.isEmpty`,
305
322
  `s.length`; sets of strings are carried maps keyed by `s.id`.
306
323
  - **Arithmetic** over the naturals: `plus`, `minus` (truncated), `times(k)`, `mul` (a product of two terms, a map's
307
- cell among them: `Used.at(k).atMost(per.mul(Seats.at(k)))`), `min`, `max`, `when(cond, a, b)`, `count(cond)`;
324
+ cell among them: `Used.at(k).atMost(per.mul(Seats.at(k)))`), `modBy(k)` and `divBy(k)` by a constant k ≥ 1 (the rule's
325
+ functions mod$k and div$k, known to the kernel by x = k·(x div k) + x mod k and x mod k < k, Presburger arithmetic it
326
+ already decides; Lean's `%` and `/`, both facts proven by `omega`; division by a term isn't offered: x = y·q + r is a
327
+ product of two unknowns), `min`, `max`, `when(cond, a, b)`, `count(cond)`;
308
328
  conditions `lt`, `atMost`, `eq`, `and`, `or`, `not`, `implies`. Where a law with products isn't linear in its
309
329
  monomials, the prover multiplies facts together and adds squares, as Lean's `nlinarith` does: (x − y)² for each
310
330
  product x·y the law reads, its factors as the step leaves them, and for each monomial split in two halves
@@ -313,6 +333,17 @@ const soon = retry.law('the next try is at most 64 after the last request', ({ne
313
333
  `disjointFrom`, `sameAs`) anywhere in a step or inside a law, `everyKey((i, j) => ...)` in a step for every two keys
314
334
  (each read on its own, compared with the other plainly: `i.lt(j)`), `M.each(k => ...)` to write every key, and
315
335
  `someKey(k => ..., witness?)` for "some key where", proven through a witness the prover finds or the one given.
336
+ - **There exists** (`exists(kind?, f, witness?)`, core/exists.ts): "some value of the kind (nat, int, bool, upTo(k))
337
+ where f holds", anywhere in a law where it reads so (under no `not`, not before `implies`), after its `forall` key if
338
+ it has one. The kernel never sees it: the law it proves is f with a witness term in place (a term of the state, for
339
+ each bound value), or f over ghosts the machine gains (a value at the start, and after each step one over the
340
+ witness before, the request and the state before), chosen by the kernel's counterexamples among what f's own atoms
341
+ solve for, 0, the state, the params, the request's values and shifts of the witness before, per case of the step; a
342
+ witness given, `exists(k => ..., lo)` or `{start, step: (k, env) => ...}`, is the only one tried. The verdict's
343
+ `witnesses` says how each reads. In the assumption (`exists(int, k => amount.eq(k.times(5)))`) or a precondition, it
344
+ is an input or a param the runtimes find (`encodeInput`, `encodeParams`: exact where it is one natural or integer
345
+ read linearly); a request no witness fits is refused. A run refutes a false one where no value can be a witness,
346
+ decided the same way.
316
347
  - **Functions** (`.fns({perMinute: divBy(60)})`, or `fn(arity, js, {facts, lean})` for your own): read like params that
317
348
  take arguments, `perMinute(t)`; the kernel knows each only by its facts (`.facts(...)`, and a library function's
318
349
  own), and the Lean export takes them as the hypothesis they are, proving them where the function has a Lean
@@ -395,7 +426,7 @@ Proving and checking: a law over 64 steps proves in about 5 s, and Lean checks i
395
426
  | `core/` | Machines, the interpreter and JS compiler, the builders, composition (`compose.ts`), the linear solver and its checker, Houdini invariants, models, the first Lean export |
396
427
  | `kernel/` | The trusted kernel and the untrusted prover, with soundness fuzz (`kernel.test.ts`, `history.test.ts`) |
397
428
  | `lean-kernel/` | The kernel's Lean twin, its soundness proofs, and the exported trees |
398
- | `examples/` | The builders at work: `domains/` (187 rules across 21 domains, each with laws and broken variants), `harness.ts` (the triple check), `readme.ts`, `guide.ts` (the guide's code), `groups.ts` (two groups decided at every pair), `budget.ts`, `gdp.ts` (gdp-ts's example, its checks proven), `datatypes.ts` (records and variants), `lemmas.ts` (recurrences and their lemmas), `invoices.ts` (lists a request carries), `folds.ts` (folds over trees), `trees.ts` (trees and lists of lists in the state), `composition.ts`, `sets.ts`, `quantifiers.ts`, `functions.ts`, `lists.ts`, `sizes.ts`, `liveness.ts`, `steps.ts` (laws over up to 64 steps), and `jev-fabric/` (a Bend project's 59 proven laws, ported) |
429
+ | `examples/` | The builders at work: `domains/` (187 rules across 21 domains, each with laws and broken variants), `harness.ts` (the triple check), `readme.ts`, `guide.ts` (the guide's code), `groups.ts` (two groups decided at every pair), `budget.ts`, `gdp.ts` (gdp-ts's example, its checks proven), `exists.ts` (laws with "there exists"), `datatypes.ts` (records and variants), `lemmas.ts` (recurrences and their lemmas), `invoices.ts` (lists a request carries), `folds.ts` (folds over trees), `trees.ts` (trees and lists of lists in the state), `composition.ts`, `sets.ts`, `quantifiers.ts`, `functions.ts`, `arith.ts` (division and remainder by a constant, integers in rules and datatypes), `lists.ts`, `sizes.ts`, `liveness.ts`, `steps.ts` (laws over up to 64 steps), and `jev-fabric/` (a Bend project's 59 proven laws, ported) |
399
430
  | `docs/` | The comparison with Bend and Lean, and the full scope |
400
431
  | `compare/` | The same three rules in gdp-wired, Bend and plain Lean, checked and measured |
401
432
  | `research/` | Everything around the library ([`research/README.md`](research/README.md)): the GPU searches (`search/`, `hw/`, `modal-gpu/`), invariant and rank synthesis (`synth/`), relational laws and guard synthesis (`next/`), bit-vector laws (`sat/`), the enumeration and benchmarks (`enum/`, `gpu/`, `perf/`), the first Lean checker (`lean/`) and the first prototype, the audit path (`audit/`) |
@@ -37,6 +37,17 @@ export declare const argsKey: (args: E[]) => E;
37
37
  export declare const linE: (coef: Record<string, number>, c: number) => E;
38
38
  export declare const showE: (e: E) => string;
39
39
  export declare const showC: (c: C) => string;
40
+ type Env = Record<string, number>;
41
+ export declare function ranksOfRuns(vars: string[], points: Env[], edges: {
42
+ s: Env;
43
+ t: Env;
44
+ }[], ms?: number): {
45
+ comps: {
46
+ coef: Record<string, number>;
47
+ c: number;
48
+ }[];
49
+ left: number;
50
+ };
40
51
  export declare function claimInstances(facts: Fact[], claim: Claim, depth?: number): NodeSpec['insts'];
41
52
  export declare function findCycles(facts: Fact[], claims: Claim[], opts?: CycleOptions): CycleVerdict;
42
53
  export type RankVerdict = {
@@ -92,3 +103,4 @@ export declare function cycleLemmas(m: Machine, laws: Law[], stepLaws?: StepLaw[
92
103
  proof?: Cyclic;
93
104
  why?: string;
94
105
  };
106
+ export {};
@@ -625,6 +625,13 @@ function lexRanks(idx, nodes, samples, edges, name, until, onEdges = false, weak
625
625
  return { comps, left: left.length };
626
626
  }
627
627
  const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));
628
+ // The same over named naturals and the edges of runs alone (core/data.ts: a recursive function's calls, each from its
629
+ // parameters' sizes to its arguments'): each component's coefficient per variable and its constant.
630
+ export function ranksOfRuns(vars, points, edges, ms = 1000) {
631
+ const node = { name: 'runs', hyps: [], concl: yes, vars, level: 0, given: true };
632
+ const { comps, left } = lexRanks([0], [node], [points.map(env => ({ env, calls: new Set() }))], edges.map(e => ({ from: 0, to: 0, s: e.s, t: e.t })), shared, performance.now() + ms);
633
+ return { comps: comps.map(c => ({ coef: Object.fromEntries(vars.map((x, j) => [x, c[shared(0, j)] ?? 0])), c: c[shared(0, 'b')] ?? 0 })), left };
634
+ }
628
635
  const compE = (c, n, node, name) => unfeat(linE(Object.fromEntries(node.vars.map((x, j) => [x, c[name(n, j)] ?? 0])), c[name(n, 'b')] ?? 0));
629
636
  // Ranks of degree 2: a product of two of a node's variables (a square too) a further variable of the LP, its value at
630
637
  // each sample the product's, one product at a time (a sparse template: with every product at once, the runs fit a rank
@@ -6,10 +6,14 @@ export declare const self: {
6
6
  };
7
7
  export declare const natural: "nat";
8
8
  export declare const boolean: "bool";
9
- export type FieldSort = 'nat' | {
9
+ export declare const integer: "int";
10
+ export type FieldSort = 'nat' | 'int' | {
11
+ data: string;
12
+ };
13
+ export type Sort = 'nat' | 'bool' | 'int' | Data;
14
+ export declare const isDataField: (s: FieldSort) => s is {
10
15
  data: string;
11
16
  };
12
- export type Sort = 'nat' | 'bool' | Data;
13
17
  export type Ctor = {
14
18
  name: string;
15
19
  fields: {
@@ -31,6 +35,35 @@ export type X = {
31
35
  op: 'mul';
32
36
  k: number;
33
37
  a: X;
38
+ } | {
39
+ op: 'prod';
40
+ a: X;
41
+ b: X;
42
+ } | {
43
+ op: 'mod' | 'div';
44
+ k: number;
45
+ a: X;
46
+ } | {
47
+ op: 'int';
48
+ value: number;
49
+ } | {
50
+ op: 'iadd' | 'isub';
51
+ a: X;
52
+ b: X;
53
+ } | {
54
+ op: 'ineg';
55
+ a: X;
56
+ } | {
57
+ op: 'imul';
58
+ k: number;
59
+ a: X;
60
+ } | {
61
+ op: 'ofnat';
62
+ a: X;
63
+ } | {
64
+ op: 'imod' | 'idiv';
65
+ k: number;
66
+ a: X;
34
67
  } | {
35
68
  op: 'if';
36
69
  c: Y;
@@ -66,11 +99,19 @@ export type X = {
66
99
  } | {
67
100
  op: 'bool';
68
101
  c: Y;
102
+ } | {
103
+ op: 'size';
104
+ data: string;
105
+ of: X;
69
106
  };
70
107
  export type Y = {
71
108
  op: '<' | '<=' | '=';
72
109
  a: X;
73
110
  b: X;
111
+ } | {
112
+ op: 'i<' | 'i<=';
113
+ a: X;
114
+ b: X;
74
115
  } | {
75
116
  op: 'and' | 'or';
76
117
  xs: Y[];
@@ -86,12 +127,17 @@ export type Y = {
86
127
  op: 'holds';
87
128
  x: X;
88
129
  };
130
+ export declare const bindName: (field: string) => string;
89
131
  export declare class Nat {
90
132
  readonly x: X;
91
133
  constructor(x: X);
92
134
  plus(b: NatLike): Nat;
93
135
  minus(b: NatLike): Nat;
94
136
  times(k: number): Nat;
137
+ mul(b: NatLike): Nat;
138
+ modBy(k: number): Nat;
139
+ divBy(k: number): Nat;
140
+ toInt(): Integer;
95
141
  lt(b: NatLike): Bool;
96
142
  atMost(b: NatLike): Bool;
97
143
  gt(b: NatLike): Bool;
@@ -99,13 +145,30 @@ export declare class Nat {
99
145
  eq(b: NatLike): Bool;
100
146
  ne(b: NatLike): Bool;
101
147
  match(cases: {
102
- zero: () => Nat | Bool | Val | number;
148
+ zero: () => Nat | Bool | Val | Integer | number;
103
149
  succ: (f: {
104
150
  pred: Nat;
105
- }) => Nat | Bool | Val | number;
151
+ }) => Nat | Bool | Val | Integer | number;
106
152
  }): any;
107
153
  }
108
154
  export type NatLike = Nat | number;
155
+ export declare class Integer {
156
+ readonly x: X;
157
+ constructor(x: X);
158
+ plus(b: IntegerLike): Integer;
159
+ minus(b: IntegerLike): Integer;
160
+ negate(): Integer;
161
+ times(k: number): Integer;
162
+ modBy(k: number): Integer;
163
+ divBy(k: number): Integer;
164
+ lt(b: IntegerLike): Bool;
165
+ atMost(b: IntegerLike): Bool;
166
+ gt(b: IntegerLike): Bool;
167
+ atLeast(b: IntegerLike): Bool;
168
+ eq(b: IntegerLike): Bool;
169
+ ne(b: IntegerLike): Bool;
170
+ }
171
+ export type IntegerLike = Integer | number;
109
172
  export declare class Bool {
110
173
  readonly y: Y;
111
174
  constructor(y: Y);
@@ -121,13 +184,14 @@ export declare class Val {
121
184
  readonly data: Data;
122
185
  readonly x: X;
123
186
  constructor(data: Data, x: X);
124
- match(cases: Record<string, (fields: Record<string, any>) => Nat | Bool | Val | number>): any;
187
+ match(cases: Record<string, (fields: Record<string, any>) => Nat | Bool | Val | Integer | number>): any;
125
188
  is(ctor: string): Bool;
189
+ size(): Nat;
126
190
  eq(b: Val): Bool;
127
191
  ne(b: Val): Bool;
128
192
  }
129
- export declare const wrap: (s: Sort, x: X) => Nat | Bool | Val;
130
- export declare function when<T extends Nat | Val | Bool | number>(c: Bool, a: T, b: T): T extends number ? Nat : T;
193
+ export declare const wrap: (s: Sort, x: X) => Nat | Bool | Val | Integer;
194
+ export declare function when<T extends Nat | Val | Bool | Integer | number>(c: Bool, a: T, b: T): T extends number ? Nat : T;
131
195
  export declare const dataNamed: (name: string) => Data;
132
196
  export declare const fieldSort: (f: {
133
197
  sort: FieldSort;
@@ -143,14 +207,14 @@ export declare class Data {
143
207
  constructor(name: string, decl: Record<string, Record<string, FieldSort>>, group?: string[]);
144
208
  index(ctor: string): number;
145
209
  get nullary(): number;
146
- make(ctor: string, ...args: (Val | NatLike)[]): Val;
210
+ make(ctor: string, ...args: (Val | NatLike | Integer)[]): Val;
147
211
  ctorHeight(c: Ctor): number;
148
212
  get height(): number;
149
213
  }
150
214
  export declare function weakOrder(ds: Data[]): Map<string, number>;
151
215
  type Decl = Record<string, Record<string, unknown>>;
152
216
  export declare function data<const D extends Decl>(name: string, decl: D): Data & {
153
- [c in keyof D]: keyof D[c] extends never ? Val : (...args: (Val | NatLike)[]) => Val;
217
+ [c in keyof D]: keyof D[c] extends never ? Val : (...args: (Val | NatLike | Integer)[]) => Val;
154
218
  };
155
219
  export declare function mutual<const G extends Record<string, Decl>>(decls: G): {
156
220
  [n in keyof G]: Data & Record<string, any>;
@@ -166,14 +230,41 @@ export type Fn = {
166
230
  readonly decreases?: number;
167
231
  readonly ring: string[];
168
232
  paramFns: string[];
233
+ readonly measure?: Measure;
234
+ readonly termination?: Termination;
235
+ stated?: Measure;
169
236
  };
170
- export type Callable = ((...args: (Val | NatLike | Bool)[]) => any) & {
237
+ export type Callable = ((...args: (Val | NatLike | Bool | Integer)[]) => any) & {
171
238
  fn: Fn;
172
239
  };
173
- export declare function define(name: string, params: Record<string, Sort>, ret: Sort, body: (args: Record<string, any>) => Nat | Bool | Val | number): Callable;
240
+ export declare function define(name: string, params: Record<string, Sort>, ret: Sort, body: (args: Record<string, any>) => Nat | Bool | Val | Integer | number, opts?: {
241
+ measure?: (string | string[])[];
242
+ }): Callable;
174
243
  export declare const fnParam: (name: string) => ((x: NatLike) => Nat) & {
175
244
  param: string;
176
245
  };
246
+ export type Measure = {
247
+ comps: {
248
+ coef: number[];
249
+ c: number;
250
+ }[];
251
+ };
252
+ export type Termination = {
253
+ measure: Measure;
254
+ text: string;
255
+ obligations: {
256
+ law: DataLaw;
257
+ proof?: CyclicVerdict;
258
+ scheme?: string;
259
+ lemmas: string[];
260
+ }[];
261
+ ms: number;
262
+ };
263
+ export declare const terminationMs: {
264
+ ms: number;
265
+ };
266
+ export declare const showMeasure: (f: Pick<Fn, "params">, m: Measure) => string;
267
+ export declare function measureX(f: Pick<Fn, 'params'>, c: Measure['comps'][number], args: X[]): X;
177
268
  export type DataLaw = {
178
269
  name: string;
179
270
  vars: {
@@ -189,8 +280,16 @@ export type Value = number | {
189
280
  f: Value[];
190
281
  };
191
282
  type Env = Map<string, Value>;
192
- export declare function evalX(x: X, env: Env, params: Record<string, (n: number) => number>): Value;
193
- export declare function evalY(y: Y, env: Env, params: Record<string, (n: number) => number>): boolean;
283
+ export declare const fnNamed: (name: string) => Fn | undefined;
284
+ export declare class EvalLimit extends RangeError {
285
+ }
286
+ export declare const evalBounds: {
287
+ on: boolean;
288
+ depth: number;
289
+ calls: number;
290
+ };
291
+ export declare function evalX(x: X, env: Env, params: Record<string, (n: number) => number>, d?: number): Value;
292
+ export declare function evalY(y: Y, env: Env, params: Record<string, (n: number) => number>, d?: number): boolean;
194
293
  export declare const showValue: (d: Sort, v: Value) => string;
195
294
  type Rand = () => number;
196
295
  export declare const rng: (seed: number) => Rand;
@@ -205,6 +304,7 @@ export declare function samples(vars: {
205
304
  sort: Sort;
206
305
  }[], paramNames: string[], n: number, seed?: number): Sample[];
207
306
  export declare const keyOf: (args: E[]) => E;
307
+ export declare function argsOf(key: E, n: number): E[] | undefined;
208
308
  export declare const tagMap: (d: string) => string, sizeMap: (d: string) => string;
209
309
  export declare const fieldMap: (d: Data, j: number, i: number) => string;
210
310
  export declare const ctorMap: (d: Data, j: number) => string;
@@ -212,8 +312,14 @@ export type Program = {
212
312
  datas: Data[];
213
313
  fns: Fn[];
214
314
  params: string[];
315
+ divisors: number[];
316
+ ints: boolean;
215
317
  };
216
318
  export declare function programOf(laws: DataLaw[], extra?: Fn[]): Program;
319
+ export declare const divMap: (k: number) => string, modMap: (k: number) => string;
320
+ export declare const zig: (z: number) => number;
321
+ export declare const unzig: (c: number) => number;
322
+ export declare const posMap = "int$pos", negMap = "int$neg";
217
323
  export declare function encX(p: Program, x: X, env: Map<string, E>): E;
218
324
  export declare function encY(p: Program, y: Y, env: Map<string, E>): C;
219
325
  export type Facts = {
@@ -264,6 +370,7 @@ export type DataVerdict = {
264
370
  tried: number;
265
371
  program?: Program;
266
372
  node?: number;
373
+ through?: string[];
267
374
  };
268
375
  export type Options = {
269
376
  samples?: number;
@@ -273,6 +380,7 @@ export type Options = {
273
380
  induction?: boolean;
274
381
  seed?: number;
275
382
  patience?: number;
383
+ transfer?: boolean;
276
384
  };
277
385
  export declare function refute(l: DataLaw, n?: number, seed?: number): Record<string, string> | undefined;
278
386
  type SchemeUse = {
@@ -288,6 +396,8 @@ type Scheme = {
288
396
  };
289
397
  uses: SchemeUse[];
290
398
  companions?: Companion[];
399
+ rank?: E[];
400
+ shapes?: E[];
291
401
  };
292
402
  type Companion = {
293
403
  law: DataLaw;
@@ -298,6 +408,11 @@ type Companion = {
298
408
  uses: SchemeUse[];
299
409
  };
300
410
  export declare const schemesOf: (p: Program, l: DataLaw) => Scheme[];
411
+ export type Proven = {
412
+ law: DataLaw;
413
+ spec: NodeSpec;
414
+ nodes: NodeSpec[];
415
+ };
301
416
  export declare const attemptMs: {
302
417
  ms: number;
303
418
  };
@@ -310,5 +425,15 @@ export declare function conjectures(p: Program, l: DataLaw, max?: number, maxSiz
310
425
  export declare const showX: (x: X) => string;
311
426
  export declare const showY: (y: Y) => string;
312
427
  export declare function proveData(l: DataLaw, opts?: Options): DataVerdict;
428
+ export type SearchCtx = {
429
+ p: Program;
430
+ fs: Facts;
431
+ base: Proven[];
432
+ level: number;
433
+ };
434
+ export declare function searchIn(l: DataLaw, opts: Options, until: number, ctx?: SearchCtx, phase?: 'all' | 'first' | 'rest'): {
435
+ verdict: DataVerdict;
436
+ out?: Proven;
437
+ };
313
438
  export declare const proveDataToday: (l: DataLaw) => DataVerdict;
314
439
  export {};