gdp-wired 0.18.0 → 0.19.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/dist/core/cyclic.d.ts +90 -6
- package/dist/core/cyclic.js +668 -27
- package/dist/core/dsl.js +25 -9
- package/dist/core/translate.d.ts +30 -0
- package/dist/core/translate.js +572 -0
- package/dist/kernel/prove.d.ts +13 -0
- package/dist/kernel/prove.js +112 -10
- package/dist/lean-kernel/emit.d.ts +34 -0
- package/dist/lean-kernel/emit.js +406 -50
- package/dist/lean-kernel/library.js +2 -1
- package/package.json +1 -1
package/dist/core/dsl.js
CHANGED
|
@@ -18,8 +18,8 @@
|
|
|
18
18
|
import { carriedView, compileFunction, evalC, evalE, interpret, loadJs, numbersOf, pairedArgs } from "./machine.js";
|
|
19
19
|
import { allowed, keysOf, requestEnv, watch } from "./watch.js";
|
|
20
20
|
import { check, foldObligations, loopObligations } from "../kernel/kernel.js";
|
|
21
|
-
import { factsFor, grow, proveLaws, proveLiveness, proveStepLaws, withDeadline } from "../kernel/prove.js";
|
|
22
|
-
import { crossCyclic, cyclicOn, foldNodes, proveCyclic, quietly, recurNodes } from "./cyclic.js";
|
|
21
|
+
import { factsFor, grow, proveLaws, proveLiveness, proveStepLaws, usualProof, withDeadline } from "../kernel/prove.js";
|
|
22
|
+
import { certCyclic, certOn, crossCyclic, cyclicOn, cycLog, foldNodes, proveCyclic, quietly, recurNodes, translatedProof } from "./cyclic.js";
|
|
23
23
|
import { discover } from "./discover.js";
|
|
24
24
|
import { inferLaws } from "./infer.js";
|
|
25
25
|
import { cycleLemmas, findRank } from "./cycles.js";
|
|
@@ -1410,6 +1410,10 @@ export const recur = (name, def, lemmas = {}, between = {}) => {
|
|
|
1410
1410
|
// The lemmas: x counting up from 0 and fx its value, each lemma a law of that machine.
|
|
1411
1411
|
let verdict = { proven: true, checked: true };
|
|
1412
1412
|
const proofs = {};
|
|
1413
|
+
// The usual proofs, to translate (core/cyclic.ts's recurNodes): the lemmas' machine's, the laws between's.
|
|
1414
|
+
let lemmaProof;
|
|
1415
|
+
const translatedRecur = (u) => (u.lemmas || !stated.length)
|
|
1416
|
+
? st => translatedProof(() => JSON.stringify(['recurrence', recurCase(u.between ? pairs : [])]), () => recurNodes(recurCase(u.between ? pairs : []), u, st), st) : undefined;
|
|
1413
1417
|
if (stated.length) {
|
|
1414
1418
|
// A start that reads a function is a param given as that start by a fact (a start reads the params alone).
|
|
1415
1419
|
const zeroReads = JSON.stringify(zero).includes('"op":"get"');
|
|
@@ -1421,9 +1425,13 @@ export const recur = (name, def, lemmas = {}, between = {}) => {
|
|
|
1421
1425
|
const laws = Object.entries(lemmas).map(([n, f]) => r.law(n, (env) => f(env.x, env.fx, envAt(args.map(a => env[a])))));
|
|
1422
1426
|
// (Its machine's proof timed alone: the recurrence is compared below as its own instance.)
|
|
1423
1427
|
const t0 = performance.now();
|
|
1428
|
+
usualProof.last = undefined;
|
|
1424
1429
|
verdict = quietly(() => proveRule(r, laws, { search: false }));
|
|
1430
|
+
lemmaProof = usualProof.last;
|
|
1425
1431
|
if (cyclicOn())
|
|
1426
|
-
crossCyclic('recurrence', name, verdict.proven && verdict.checked, () => { const { facts, specs } = recurNodes(recurCase([])); return proveCyclic(facts, specs); }, performance.now() - t0);
|
|
1432
|
+
crossCyclic('recurrence', name, verdict.proven && verdict.checked, () => { const { facts, specs } = recurNodes(recurCase([])); return proveCyclic(facts, specs); }, performance.now() - t0, translatedRecur({ lemmas: lemmaProof }));
|
|
1433
|
+
if (certOn() && verdict.proven && verdict.checked)
|
|
1434
|
+
verdict = { ...verdict, checked: certCyclic('recurrence', name, translatedRecur({ lemmas: lemmaProof }), () => { const { facts, specs } = recurNodes(recurCase([])); return proveCyclic(facts, specs); }, performance.now() - t0).checked };
|
|
1427
1435
|
failed('lemmas', verdict);
|
|
1428
1436
|
proofs.lemmas = { machine: r.machine, laws };
|
|
1429
1437
|
}
|
|
@@ -1460,9 +1468,12 @@ export const recur = (name, def, lemmas = {}, between = {}) => {
|
|
|
1460
1468
|
.step((env) => ({ y: env.y.plus(1), fy: def.next(env.y, env.fy, envAt(at(env))) }));
|
|
1461
1469
|
const laws = [...Object.entries(lemmas).map(([n, l]) => r.law(`${n} at y`, (env) => l(env.y, env.fy, envAt(at(env))))),
|
|
1462
1470
|
...Object.entries(between).map(([n, l]) => r.law(n, (env) => l(env.x, env.fx, env.y, env.fy, envAt(at(env)))))];
|
|
1463
|
-
|
|
1471
|
+
usualProof.last = undefined;
|
|
1472
|
+
const t0 = performance.now(), v = quietly(() => proveRule(r, laws, { search: false })), usualMs = performance.now() - t0, betweenProof = usualProof.last;
|
|
1464
1473
|
if (cyclicOn())
|
|
1465
|
-
crossCyclic('recurrence, between', name, v.proven && v.checked, () => { const { facts, specs } = recurNodes(recurCase(pairs)); return proveCyclic(facts, specs); }, usualMs);
|
|
1474
|
+
crossCyclic('recurrence, between', name, v.proven && v.checked, () => { const { facts, specs } = recurNodes(recurCase(pairs)); return proveCyclic(facts, specs); }, usualMs, betweenProof && translatedRecur({ lemmas: lemmaProof, between: betweenProof }));
|
|
1475
|
+
if (certOn() && v.proven && v.checked)
|
|
1476
|
+
v.checked = certCyclic('recurrence, between', name, betweenProof && translatedRecur({ lemmas: lemmaProof, between: betweenProof }), () => { const { facts, specs } = recurNodes(recurCase(pairs)); return proveCyclic(facts, specs); }, usualMs).checked;
|
|
1466
1477
|
failed('laws between two points', v);
|
|
1467
1478
|
proofs.between = { machine: r.machine, laws };
|
|
1468
1479
|
verdict = { proven: true, checked: verdict.checked && v.checked };
|
|
@@ -2504,7 +2515,7 @@ export class Unproven extends Error {
|
|
|
2504
2515
|
this.verdict = verdict;
|
|
2505
2516
|
}
|
|
2506
2517
|
}
|
|
2507
|
-
const goalsVerdict = (goals) => {
|
|
2518
|
+
const goalsVerdict = (goals, checkIt = true) => {
|
|
2508
2519
|
const trees = {};
|
|
2509
2520
|
for (const g of goals) {
|
|
2510
2521
|
const out = grow(g);
|
|
@@ -2512,7 +2523,7 @@ const goalsVerdict = (goals) => {
|
|
|
2512
2523
|
return { proven: false, checked: false, goal: g.name, stuck: out.stuck, ...(out.witness ? { witness: out.witness } : {}), ...(out.why ? { why: out.why } : {}) };
|
|
2513
2524
|
trees[g.name] = out.tree;
|
|
2514
2525
|
}
|
|
2515
|
-
return { proven: true, checked: goals.every(g => check(g, trees[g.name])), trees };
|
|
2526
|
+
return { proven: true, checked: !checkIt || goals.every(g => check(g, trees[g.name])), trees };
|
|
2516
2527
|
};
|
|
2517
2528
|
// The kinds' laws first, those the caller didn't pass already (by name).
|
|
2518
2529
|
const withKinds = (r, laws) => [...r.kindLaws().filter(k => !laws.some(l => l.name === k.name)), ...laws];
|
|
@@ -2679,6 +2690,8 @@ export function crossCheckDecision(d, opts = {}) {
|
|
|
2679
2690
|
// With no rank stated, the rank is searched for from the loop's runs (core/cycles.ts's findRank), with the invariants it
|
|
2680
2691
|
// needs (inferLaws), within `ms` (10 s); the verdict is the kernel's on the rank and the laws found, in `found`.
|
|
2681
2692
|
export const proveLoop = (l, laws, opts = {}) => {
|
|
2693
|
+
if (cyclicOn() || certOn())
|
|
2694
|
+
cycLog({ kind: 'loop', name: l.loop.name, uncovered: true, why: 'a claim about runs that never end' });
|
|
2682
2695
|
if (l.hasRank)
|
|
2683
2696
|
return goalsVerdict(loopObligations(l.loop, laws, l.rankTerms));
|
|
2684
2697
|
const out = findRank(l.loop, laws, opts);
|
|
@@ -2800,9 +2813,12 @@ export class FoldRule {
|
|
|
2800
2813
|
export const fold = (name) => new FoldRule({ name, params: [], inputs: [], pre: [], assume: [] });
|
|
2801
2814
|
// A fold's laws proven over every tree (a rose fold's own laws, its children's lemmas, with them).
|
|
2802
2815
|
export const proveFold = (f, laws) => {
|
|
2803
|
-
|
|
2816
|
+
// (GDP_CERT=cyclic: the certificate a cyclic proof, core/cyclic.ts's certCyclic, the usual trees its input)
|
|
2817
|
+
const all = [...(f.lemmas ?? []), ...laws], t0 = performance.now(), v = goalsVerdict(foldObligations(f.fold, all), !certOn()), usualMs = performance.now() - t0;
|
|
2804
2818
|
if (cyclicOn())
|
|
2805
|
-
crossCyclic('fold', f.fold.name, v.proven && v.checked, () => { const { facts, specs } = foldNodes(f.fold, all); return proveCyclic(facts, specs); }, usualMs);
|
|
2819
|
+
crossCyclic('fold', f.fold.name, v.proven && v.checked, () => { const { facts, specs } = foldNodes(f.fold, all); return proveCyclic(facts, specs); }, usualMs, v.trees && (st => translatedProof(() => JSON.stringify(['fold', f.fold, all]), () => foldNodes(f.fold, all, v.trees, st), st)));
|
|
2820
|
+
if (certOn() && v.proven)
|
|
2821
|
+
v.checked = certCyclic('fold', f.fold.name, v.trees && (st => translatedProof(() => JSON.stringify(['fold', f.fold, all]), () => foldNodes(f.fold, all, v.trees, st), st)), () => { const { facts, specs } = foldNodes(f.fold, all); return proveCyclic(facts, specs); }, usualMs).checked;
|
|
2806
2822
|
return v;
|
|
2807
2823
|
};
|
|
2808
2824
|
const asTerm = (t) => (t instanceof Term ? t : lit(t));
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { C, E } from './machine.js';
|
|
2
|
+
import { type Lin } from './solver.js';
|
|
3
|
+
import { type Goal, type Path, type Subst, type Tree } from '../kernel/kernel.js';
|
|
4
|
+
export type Rename = {
|
|
5
|
+
s: Subst;
|
|
6
|
+
cells?: Record<string, {
|
|
7
|
+
to: string;
|
|
8
|
+
at: E;
|
|
9
|
+
}>;
|
|
10
|
+
};
|
|
11
|
+
export type Renamer = (lin: Lin, wp: Path) => Lin | undefined;
|
|
12
|
+
export declare function renamer(r: Rename): Renamer;
|
|
13
|
+
export type TStats = {
|
|
14
|
+
leaves: number;
|
|
15
|
+
regrown: number;
|
|
16
|
+
splits: number;
|
|
17
|
+
carried: number;
|
|
18
|
+
uncarried: number;
|
|
19
|
+
cached: number;
|
|
20
|
+
};
|
|
21
|
+
export declare const tstats: () => TStats;
|
|
22
|
+
export declare function translate(part: Goal, whole: Goal, tree: Tree, ren0: Renamer, st: TStats, until: number, pp?: Path, wp?: Path, swaps?: [string, string][]): Tree | undefined;
|
|
23
|
+
export type Reads = {
|
|
24
|
+
k: E;
|
|
25
|
+
w: E;
|
|
26
|
+
}[];
|
|
27
|
+
export declare function readsFirst(whole: Goal, reads: Reads, ren: Renamer, inner: (wp: Path, swaps: [string, string][]) => Tree | undefined, st: TStats, until: number, wp?: Path, swaps?: [string, string][]): Tree | undefined;
|
|
28
|
+
export declare function decide(whole: Goal, conds: C[], inner: (wp: Path) => Tree | undefined, st: TStats, until: number, wp?: Path): Tree | undefined;
|
|
29
|
+
export declare function close(g: Goal, wp: Path, st: TStats, until: number): Tree | undefined;
|
|
30
|
+
export declare function carry(g: Goal, nFacts: number, nUses: number, st: TStats, until: number): Tree | undefined;
|