gdp-wired 0.12.4 → 0.12.5
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 +3 -1
- package/dist/core/dsl.d.ts +5 -0
- package/dist/core/dsl.js +10 -0
- package/dist/kernel/prove.js +4 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -234,7 +234,9 @@ const soon = retry.law('the next try is at most 64 after the last request', ({ne
|
|
|
234
234
|
lemmas too, at the list's end and wherever it reads the list. A lemma reads the folds, the prefix's length and the
|
|
235
235
|
params, not the items: a fact about every item is a fold's (a count of the items that meet it). A fold's start and
|
|
236
236
|
step, and a lemma, may read the params (`{from: ({fee}) => fee, step: (acc, line, {ceil}) => acc.plus(min(line.amount, ceil))}`); a request is then
|
|
237
|
-
encoded with them, `rule.encodeInput(values, params)` (`examples/invoices.ts`).
|
|
237
|
+
encoded with them, `rule.encodeInput(values, params)` (`examples/invoices.ts`). `rule.foldsOf({Lines: [...]}, params)`
|
|
238
|
+
gives each fold at the list's end, computed the same way, without running the rule (to compare a decision's folds
|
|
239
|
+
with the code it describes).
|
|
238
240
|
- **Folds over trees** (`fold(name).params(...).inputs(...).leaf(env => ({...})).node((env, left, right) => ({...}))`,
|
|
239
241
|
`proveFold`): a tree as a value (`{leaf: inputs}` or `{node: inputs, left, right}`), each leaf's values from its inputs
|
|
240
242
|
and each node's from its own and its children's; a law about the values is proven by induction over the tree (the
|
package/dist/core/dsl.d.ts
CHANGED
|
@@ -598,6 +598,11 @@ export declare class Rule<P extends Obj = {}, I extends Obj = {}, S extends Obj
|
|
|
598
598
|
}, params?: {
|
|
599
599
|
[k in keyof P]: Raw;
|
|
600
600
|
}): Request;
|
|
601
|
+
foldsOf(values: {
|
|
602
|
+
[k in keyof I]?: I[k] extends CarriedList<any, any> ? readonly Raw[] : never;
|
|
603
|
+
}, params?: {
|
|
604
|
+
[k in keyof P]: Raw;
|
|
605
|
+
}): Record<string, Record<string, number>>;
|
|
601
606
|
randomParams(rand: Rand, bound: number): Record<string, number>;
|
|
602
607
|
private paramValues;
|
|
603
608
|
randomInput(rand: Rand, bound: number, ps?: Record<string, number>): Request;
|
package/dist/core/dsl.js
CHANGED
|
@@ -2160,6 +2160,16 @@ export class Rule {
|
|
|
2160
2160
|
}
|
|
2161
2161
|
return out;
|
|
2162
2162
|
}
|
|
2163
|
+
// Each carried list's folds at its end (what `L.fold.<f>` reads), computed from its items as encodeInput computes
|
|
2164
|
+
// them, without running the rule: `foldsOf({Lines: [...]})` → {Lines: {total: 30}}. Only the lists given.
|
|
2165
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
2166
|
+
foldsOf(values, params) {
|
|
2167
|
+
const at = params && this.paramValues(this.encodeParams(params));
|
|
2168
|
+
return Object.fromEntries((this.spec.lists2 ?? []).filter(([n]) => n in values).map(([n, k, fs]) => {
|
|
2169
|
+
const { maps, len } = new CarriedList(n, k, v(`${n}_len`), fs, part => new MapRef(part, 0), {}, at).encode(values[n]);
|
|
2170
|
+
return [n, Object.fromEntries(Object.keys(fs).map(f => [f, maps[`${n}$${f}`].get(len) ?? 0]))];
|
|
2171
|
+
}));
|
|
2172
|
+
}
|
|
2163
2173
|
// Random params and inputs that meet their kinds (not the user's `pre` or `assume`, which a caller checks).
|
|
2164
2174
|
randomParams(rand, bound) { return Object.assign({}, ...this.spec.params.map(([n, k]) => k.random(n, rand, bound))); }
|
|
2165
2175
|
// The params' values by their kinds, as constants (what a fold that reads them is computed with).
|
package/dist/kernel/prove.js
CHANGED
|
@@ -667,14 +667,15 @@ const flagInstances = (m, keys, focus = []) => Object.fromEntries(Object.entries
|
|
|
667
667
|
}));
|
|
668
668
|
// A k-step law whose steps keep a condition (a flag that holds at one step and is read again at the next) fails at a
|
|
669
669
|
// later step's witness only where the condition held before: so, per quantified flag over one key, the instances at the
|
|
670
|
-
// law's own keys and that flag's witness at every step (a later step's witness is a key an earlier frame may
|
|
671
|
-
// flag holds at every key: kernel.ts's checkStepLaws). Few instances, where the shared ones are many and
|
|
670
|
+
// law's own keys and that flag's witness at every step (a later step's input or witness is a key an earlier frame may
|
|
671
|
+
// name, as a flag holds at every key: kernel.ts's checkStepLaws). Few instances, where the shared ones are many and
|
|
672
|
+
// mostly idle.
|
|
672
673
|
const keptAcross = (m, laws, inst, own, k) => k < 2 ? [] : Object.entries(m.step.flags ?? {}).flatMap(([f, c]) => {
|
|
673
674
|
if (c.op !== 'all' || c.keys?.length)
|
|
674
675
|
return [];
|
|
675
676
|
const ws = Array.from({ length: k }, (_, i) => ({ op: 'var', name: i ? `w?${f}@${i + 1}` : `w?${f}` })), keys = [...own, ...ws.slice(0, 1)];
|
|
676
677
|
const keep = new Set(keys.map(e => JSON.stringify(e)));
|
|
677
|
-
return [Object.fromEntries(Object.entries(inst).map(([n, ks]) => [n,
|
|
678
|
+
return [Object.fromEntries(Object.entries(inst).map(([n, ks]) => [n, n === `?${f}` ? [...keys, ...ws.slice(1)].filter((e, i, all) => all.findIndex(o => JSON.stringify(o) === JSON.stringify(e)) === i) : arity(m, laws, n) === 1 ? ks.filter(e => keep.has(JSON.stringify(e))) : ks]))];
|
|
678
679
|
});
|
|
679
680
|
const pairFlags = (m) => Object.values(m.step.flags ?? {}).some(c => c.op === 'all' && !!c.keys?.length);
|
|
680
681
|
// How many keys each instance of a name takes: a law's, or a quantified flag's (?f).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gdp-wired",
|
|
3
|
-
"version": "0.12.
|
|
3
|
+
"version": "0.12.5",
|
|
4
4
|
"description": "An automatic prover for stateful rules (budgets, caps, windows, workflows, policies): laws proven with no proof to write, checked again in Lean, counterexamples found on the GPU, the rule shipped as code",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"verification",
|