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 +37 -6
- package/dist/core/cycles.d.ts +12 -0
- package/dist/core/cycles.js +7 -0
- package/dist/core/data.d.ts +138 -13
- package/dist/core/data.js +842 -145
- package/dist/core/dsl.d.ts +27 -1
- package/dist/core/dsl.js +137 -26
- package/dist/core/exists.d.ts +26 -0
- package/dist/core/exists.js +625 -0
- package/dist/core/infer.d.ts +13 -0
- package/dist/core/infer.js +258 -41
- package/dist/core/machine.d.ts +27 -0
- package/dist/core/machine.js +45 -0
- package/dist/core/transfer.d.ts +17 -0
- package/dist/core/transfer.js +468 -0
- package/dist/core/watch.js +5 -1
- package/dist/kernel/prove.d.ts +5 -1
- package/dist/kernel/prove.js +11 -5
- package/dist/lean-kernel/emit.d.ts +2 -0
- package/dist/lean-kernel/emit.js +196 -15
- package/dist/lean-kernel/library.js +2 -2
- package/package.json +2 -2
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,
|
|
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,
|
|
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)`)
|
|
301
|
-
|
|
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)))`), `
|
|
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/`) |
|
package/dist/core/cycles.d.ts
CHANGED
|
@@ -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 {};
|
package/dist/core/cycles.js
CHANGED
|
@@ -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
|
package/dist/core/data.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
193
|
-
export declare
|
|
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 {};
|