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/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
- const t0 = performance.now(), v = quietly(() => proveRule(r, laws, { search: false })), usualMs = performance.now() - t0;
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
- const all = [...(f.lemmas ?? []), ...laws], t0 = performance.now(), v = goalsVerdict(foldObligations(f.fold, all)), usualMs = performance.now() - t0;
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;