eyeprolog 1.5.82 → 1.5.83

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/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.5.82",
6
+ "version": "1.5.83",
7
7
  "description": "EyeProlog turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
@@ -1,6 +1,6 @@
1
1
  # EyeProlog — latest Neumerkel conformity
2
2
 
3
- Status: **PASS** — **719/719** discovered upstream cases passed.
3
+ Status: **PASS — 1 divergence to be addressed** — **718/719** discovered upstream cases passed.
4
4
 
5
5
  This tracked report records the latest upstream inventory successfully checked by EyeProlog.
6
6
  `npm test` fetches the eight TU Wien sources again and executes the discovered cases.
@@ -15,9 +15,13 @@ Counts are output from upstream, not hard-coded test constants.
15
15
  | dif/2 | 26 | 26 |
16
16
  | length/2 | 37 | 37 |
17
17
  | phrase/2,3 | 58 | 58 |
18
- | Prologue draft | 33 | 33 |
18
+ | Prologue draft | 32 | 33 |
19
19
  | setup_call_cleanup/3 | 25 | 25 |
20
- | **Total** | **719** | **719** |
20
+ | **Total** | **718** | **719** |
21
+
22
+ ## Known divergences
23
+
24
+ - **Prologue draft** (line 118): bounded=false: EyeProlog reports no max_integer value at all (ISO 7.11.1.1), so this quad's evaluation_error(int_overflow) | Max = unbounded pair never applies
21
25
 
22
26
  ## Upstream sources
23
27
 
@@ -19,9 +19,12 @@ The Prologue corpus carries one permanent, documented divergence (its
19
19
  `max_integer` quad — see `KNOWN_QUAD_DIVERGENCES` in `test/neumerkel.mjs`):
20
20
  EyeProlog's `bounded=false` reports no `max_integer` value at all, which
21
21
  neither of the quad's two anticipated answers describes. That quad is still
22
- executed and verified every run; it is reported as a passing, documented
23
- divergence for as long as it keeps reproducing, and would fail loudly if it
24
- ever stopped.
22
+ executed every run and counted honestly (it does not report as passing), but
23
+ it does not abort the run the way an unexplained failure would; the tracked
24
+ report and console summary both say "N divergence(s) to be addressed" rather
25
+ than a bare pass/fail count. See `NEUMERKEL-LATEST.md`'s own "Known
26
+ divergences" section for the explanation. If the divergence ever stopped
27
+ reproducing, the counts would simply climb back to a plain, unqualified PASS.
25
28
 
26
29
  The runner discovers the inventory at run time. A new upstream row is therefore
27
30
  executed automatically and a removed row disappears automatically. The syntax
@@ -308,10 +308,11 @@ function expectedMatches(expected, actual) {
308
308
 
309
309
  // A permanent, deliberate divergence from an upstream quad: EyeProlog's own
310
310
  // implementation choice, not a bug to chase. Keyed by corpus key, then by the
311
- // answer description's source line. Reported as its own test either way, so a
312
- // future upstream change that makes the divergence stop reproducing (as
313
- // happened with the length corpus's occurs-check quad) is caught immediately
314
- // instead of silently masked.
311
+ // answer description's source line. It is still reported and counted as an
312
+ // ordinary failing test (so the totals stay honest and it self-corrects the
313
+ // moment it stops reproducing, exactly as happened with the length corpus's
314
+ // occurs-check quad); it just does not abort the run the way an unexplained
315
+ // failure would.
315
316
  const KNOWN_QUAD_DIVERGENCES = {
316
317
  prologue: new Map([
317
318
  [118, 'bounded=false: EyeProlog reports no max_integer value at all (ISO 7.11.1.1), ' +
@@ -358,17 +359,9 @@ function runQuadCorpus(reporter, label, item, knownDivergences = new Map()) {
358
359
  const divergence = knownDivergences.get(description.line);
359
360
  const name = divergence == null
360
361
  ? `${label} ${locator} (line ${description.line ?? '?'}) ?- ${formatQuadTerm(program, description.query)}`
361
- : `${label} ${locator} (line ${description.line ?? '?'}, documented divergence) ?- ${formatQuadTerm(program, description.query)}`;
362
+ : `${label} ${locator} (line ${description.line ?? '?'}, documented divergence: ${divergence}) ?- ${formatQuadTerm(program, description.query)}`;
362
363
  try {
363
364
  reporter.test(name, () => {
364
- if (divergence != null) {
365
- // Verify the divergence itself, not just tolerate it: if it stops
366
- // reproducing, that is exactly the kind of change worth noticing.
367
- if (description.ok) {
368
- throw new Error(`documented divergence (${divergence}) no longer reproduces; remove it from KNOWN_QUAD_DIVERGENCES`);
369
- }
370
- return;
371
- }
372
365
  if (!description.ok) {
373
366
  const reason = description.reason ? `: ${description.reason}` : '';
374
367
  throw new Error(`${description.kind ?? 'failed'}${reason}`);
@@ -376,10 +369,12 @@ function runQuadCorpus(reporter, label, item, knownDivergences = new Map()) {
376
369
  });
377
370
  passed++;
378
371
  } catch (error) {
379
- // Upstream changes often arrive in small clusters. Keep running the
380
- // corpus so one live test run exposes every new mismatch instead of
381
- // forcing a fix/rerun cycle for each row.
382
- failures.push(error);
372
+ // A documented divergence is expected to keep failing; note it without
373
+ // aborting the run over it. Upstream changes otherwise often arrive in
374
+ // small clusters -- keep running the corpus so one live test run
375
+ // exposes every new mismatch instead of forcing a fix/rerun cycle for
376
+ // each row.
377
+ if (divergence == null) failures.push(error);
383
378
  }
384
379
  });
385
380
  return { total: result.results.length, passed, failures };
@@ -514,10 +509,21 @@ export function formatNeumerkelMarkdown({ summary }) {
514
509
  const rows = labels.map(([key, label]) => ({ key, label, ...summary[key] }));
515
510
  const passed = rows.reduce((sum, row) => sum + row.passed, 0);
516
511
  const total = rows.reduce((sum, row) => sum + row.total, 0);
512
+ const divergenceCount = Object.values(KNOWN_QUAD_DIVERGENCES)
513
+ .reduce((sum, byLine) => sum + byLine.size, 0);
514
+ const shortfall = total - passed;
515
+ // A shortfall fully accounted for by known, documented divergences (see
516
+ // KNOWN_QUAD_DIVERGENCES and the list below) is not a build failure; any
517
+ // other shortfall is.
518
+ const status = shortfall === 0
519
+ ? 'PASS'
520
+ : shortfall === divergenceCount
521
+ ? `PASS — ${shortfall} divergence${shortfall === 1 ? '' : 's'} to be addressed`
522
+ : 'FAIL';
517
523
  const lines = [
518
524
  '# EyeProlog — latest Neumerkel conformity',
519
525
  '',
520
- `Status: **${passed === total ? 'PASS' : 'FAIL'}** — **${passed}/${total}** discovered upstream cases passed.`,
526
+ `Status: **${status}** — **${passed}/${total}** discovered upstream cases passed.`,
521
527
  '',
522
528
  'This tracked report records the latest upstream inventory successfully checked by EyeProlog.',
523
529
  '`npm test` fetches the eight TU Wien sources again and executes the discovered cases.',
@@ -530,6 +536,14 @@ export function formatNeumerkelMarkdown({ summary }) {
530
536
  for (const row of rows) lines.push(`| ${row.label} | ${row.passed} | ${row.total} |`);
531
537
  lines.push(`| **Total** | **${passed}** | **${total}** |`);
532
538
 
539
+ if (divergenceCount > 0) {
540
+ lines.push('', '## Known divergences', '');
541
+ for (const [key, byLine] of Object.entries(KNOWN_QUAD_DIVERGENCES)) {
542
+ const label = labels.find(([labelKey]) => labelKey === key)?.[1] ?? key;
543
+ for (const [line, reason] of byLine) lines.push(`- **${label}** (line ${line}): ${reason}`);
544
+ }
545
+ }
546
+
533
547
  lines.push(
534
548
  '',
535
549
  '## Upstream sources',
@@ -57,7 +57,7 @@ export class TestReporter {
57
57
  const shortfall = total - ok;
58
58
  const outcome = shortfall === 0
59
59
  ? 'passed'
60
- : `passed (${shortfall} known divergence${shortfall === 1 ? '' : 's'})`;
60
+ : `passed with ${shortfall} divergence${shortfall === 1 ? '' : 's'} to be addressed`;
61
61
  this.stdout.write(`${colors.green}OK${colors.reset} ${ok}/${total} ${suite} tests ${outcome} ${colors.dim}(${ms} ms)${colors.reset}\n`);
62
62
  }
63
63
 
@@ -120,7 +120,7 @@ export class TestReporter {
120
120
  const shortfall = this.total - this.ok;
121
121
  const outcome = shortfall === 0
122
122
  ? 'passed'
123
- : `passed (${shortfall} known divergence${shortfall === 1 ? '' : 's'})`;
123
+ : `passed with ${shortfall} divergence${shortfall === 1 ? '' : 's'} to be addressed`;
124
124
  this.stdout.write(`${colors.green}OK${colors.reset} ${this.ok}/${this.total} tests ${outcome} ${colors.dim}(${ms} ms)${colors.reset}\n`);
125
125
  }
126
126
  }