eyeprolog 1.5.71 → 1.5.72

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.
@@ -15,9 +15,9 @@ cached source bytes, avoiding a second live fetch and its race window.
15
15
 
16
16
  | Gate | Passed | Total | Status |
17
17
  |---|---:|---:|---|
18
- | WG17 syntax | 366 | 366 | pass |
18
+ | WG17 syntax | 379 | 379 | pass |
19
19
 
20
- The WG17 syntax row executes the vendored 366-case conformity-testing matrix
20
+ The WG17 syntax row executes the vendored 379-case conformity-testing matrix
21
21
  against EyeProlog's strict ISO reader/writer. A behavior fix such as operator-token
22
22
  spelling therefore changes this report even when no corpus file is added or removed.
23
23
 
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.5.71",
6
+ "version": "1.5.72",
7
7
  "description": "EyeProlog turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
@@ -23,7 +23,7 @@ relevant implementation-dependent overlap choice to an explicit review outcome.
23
23
 
24
24
  | Requirement | Status | EyeProlog evidence / remaining work |
25
25
  | --- | --- | --- |
26
- | 5.1(a) prepare conforming Prolog text | covered | Clause 6 token/term production and rejection families are mapped by the strict production gate and the complete 366-case vendored WG17 syntax matrix; 7.4 preparation/directive behavior is separately closed. |
26
+ | 5.1(a) prepare conforming Prolog text | covered | Clause 6 token/term production and rejection families are mapped by the strict production gate and the complete 379-case vendored WG17 syntax matrix; 7.4 preparation/directive behavior is separately closed. |
27
27
  | 5.1(b) execute conforming Prolog goals | covered | Clause 7 term/control/execution semantics, the higher-level 7.10 stream model, 7.11 flags, the 7.12 error envelope, all 8.2-8.17 built-in rows, and Clause 9 arithmetic have explicit executable dispositions. |
28
28
  | 5.1(c) reject nonconforming text/read-terms | covered | WG17 negative syntax cases, focused malformed-production/escape/comment/operator cases, read-term syntax errors, and strict rejection of implementation-specific syntax provide explicit rejection evidence across the Clause 6 families. |
29
29
  | 5.1(d) document permitted variations | covered | The clause-by-clause [ISO 5.4 decision index](ISO-IMPLEMENTATION-DEFINED.md) records every explicit implementation-defined decision found in the Part 1 + Corrigenda baseline and separately inventories implementation-specific extension families. The index retains an `gap` category for future discoveries; no current release-facing row depends on one. |
@@ -35,7 +35,7 @@ relevant implementation-dependent overlap choice to an explicit review outcome.
35
35
 
36
36
  | Standard area | Status | Current evidence |
37
37
  | --- | --- | --- |
38
- | Clause 6 — tokens, terms, lists, operators, quoted text | covered | The strict Clause 6 gate maps atomic/variable/compound/operator/list/curly/double-quoted term forms, layout/comments, quoted escapes, integer bases/character codes, floating tokens, and solo/meta token boundaries, with malformed counterparts rejected. The complete 366-case WG17 syntax matrix provides externally sourced production-level expectations, and a cross-profile gate verifies that normal syntax extensions preserve every strict-accepted standard observation. The implementation-defined 6.5/6.6 PCS/collation choices are documented separately. |
38
+ | Clause 6 — tokens, terms, lists, operators, quoted text | covered | The strict Clause 6 gate maps atomic/variable/compound/operator/list/curly/double-quoted term forms, layout/comments, quoted escapes, integer bases/character codes, floating tokens, and solo/meta token boundaries, with malformed counterparts rejected. The complete 379-case WG17 syntax matrix provides externally sourced production-level expectations, and a cross-profile gate verifies that normal syntax extensions preserve every strict-accepted standard observation. The implementation-defined 6.5/6.6 PCS/collation choices are documented separately. |
39
39
  | 7.1-7.3 — term types, term order, unification | covered | [ISO-TERM-SEMANTICS-MATRIX.md](ISO-TERM-SEMANTICS-MATRIX.md) records the five mutually exclusive strict term types, derived variable/compound/list notions, the complete standard-order classes and implementation-dependent variable-order choice, NSTO MGU/failure behavior, and EyeProlog's permitted consistent occurs-check failure for Part 1's undefined STO ordinary-unification cases. The normal JavaScript API string term is documented as a 5.5.4 extension and rejected at strict program/goal entry. |
40
40
  | 7.4 — Prolog text and directives | covered | [ISO-PROLOG-TEXT-EXECUTION-MATRIX.md](ISO-PROLOG-TEXT-EXECUTION-MATRIX.md) closes the preparation/directive rows: declaration semantics, source clauses, cross-text operators/character conversion/flags, initialization order/lifetime, `include/1`, and one-time `ensure_loaded/1`, with implementation-defined cross-text choices indexed under 5.4. |
41
41
  | 7.5-7.6 — database and term/clause conversion | covered | [ISO-PROLOG-TEXT-EXECUTION-MATRIX.md](ISO-PROLOG-TEXT-EXECUTION-MATRIX.md) closes static/dynamic and private/public procedure semantics, clause order, logical-update visibility, empty/unknown lifetime, and term/body/clause conversion. Source and runtime assertion conversion recurse through `,/2`, `;/2`, and `->/2`, preserve variable identity, and protect standardized static/control procedures. |
@@ -307,7 +307,7 @@ post-N289 STC drafts remain review input until standardized.
307
307
  | Criterion | Status | Evidence |
308
308
  | --- | --- | --- |
309
309
  | Clause 5 processor obligations have explicit dispositions | covered | `ISO-PROCESSOR-REQUIREMENTS.md` gives explicit outcomes for 5.1-5.5, including the strict/normal extension boundary. |
310
- | Clause 6 lexical/syntactic requirements have explicit dispositions | covered | the strict Clause 6 production/rejection gate and the 366-case vendored WG17 matrix cover the standard families; cross-profile preservation verifies that normal extensions do not reinterpret strict-accepted text. |
310
+ | Clause 6 lexical/syntactic requirements have explicit dispositions | covered | the strict Clause 6 production/rejection gate and the 379-case vendored WG17 matrix cover the standard families; cross-profile preservation verifies that normal extensions do not reinterpret strict-accepted text. |
311
311
  | Clause 7 semantic requirements have explicit dispositions | covered | 7.1-7.12 now have explicit semantic, implementation-defined, or error-envelope dispositions backed by strict tests and the specialized matrices. |
312
312
  | Clause 8 built-in modes/errors have explicit dispositions | covered | `ISO-BUILTIN-MODE-ERROR-MATRIX.md` accounts for 8.2-8.17 condition by condition, using grouped rows only where every grouped condition and its evidence are named |
313
313
  | Clause 9 evaluable-functor requirements have explicit dispositions | covered | `ISO-EVALUABLE-FUNCTOR-MATRIX.md` plus the strict arithmetic regression closes the published Part 1 + Corrigenda arithmetic rows |
@@ -1,7 +1,7 @@
1
1
  # WG17 syntax traceability status
2
2
 
3
3
  Source: [Conformity Testing I: Syntax](https://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_testing)
4
- Upstream inventory checked: 2026-09-01
4
+ Upstream inventory checked: 2026-09-10
5
5
 
6
6
  This ledger counts an upstream case when its WG17 identifier, query, and
7
7
  expected ISO disposition are stored in the offline executable matrix. Every
@@ -20,25 +20,25 @@ A represented case still has to pass the executable upstream assertion in
20
20
 
21
21
  | Measure | Count |
22
22
  | --- | ---: |
23
- | Active upstream cases | 366 |
24
- | Upstream cases represented in the executable matrix | 366 (100.0%) |
23
+ | Active upstream cases | 379 |
24
+ | Upstream cases represented in the executable matrix | 379 (100.0%) |
25
25
  | Not yet traced one-by-one | 0 |
26
26
  | Deleted upstream identifiers | #20, #273 |
27
27
 
28
28
  The matrix runs in strict ISO stream-reader mode as part of `npm test`. The
29
29
  3 upstream `waits` cases are checked through EyeProlog's interactive input
30
- hook. All 366 executable cases are independently checked against the
30
+ hook. All 379 executable cases are independently checked against the
31
31
  upstream Codex expectation. 365 cases additionally retain exact reviewed
32
- outcomes for stronger regression checking; 1 case currently relies on the upstream assertion alone.
32
+ outcomes for stronger regression checking; 14 cases currently rely on the upstream assertion alone.
33
33
 
34
34
  ## Traceable evidence
35
35
 
36
36
  | Executable evidence | Referenced IDs | WG17 cases |
37
37
  | --- | ---: | --- |
38
- | [complete offline executable matrix](../run-wg17.mjs) | 366 | #1–#19, #21–#272, #274–#368 |
38
+ | [complete offline executable matrix](../run-wg17.mjs) | 379 | #1–#19, #21–#272, #274–#381 |
39
39
 
40
- The evidence groups overlap. Their union is **366** active cases:
41
- #1–#19, #21–#272, #274–#368.
40
+ The evidence groups overlap. Their union is **379** active cases:
41
+ #1–#19, #21–#272, #274–#381.
42
42
 
43
43
  ## Untraced upstream identifiers
44
44
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "source": "https://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_testing",
3
- "checkedOn": "2026-09-01",
3
+ "checkedOn": "2026-09-10",
4
4
  "protocol": "Each query is read and executed in strict ISO mode; /**/ rows reuse the preceding setup.",
5
5
  "cases": [
6
6
  {
@@ -5557,8 +5557,112 @@
5557
5557
  }
5558
5558
  ]
5559
5559
  }
5560
+ },
5561
+ {
5562
+ "id": 369,
5563
+ "query": "writeq(?-).",
5564
+ "input": "writeq(?-).",
5565
+ "readCount": 1,
5566
+ "expected": "?-",
5567
+ "assertion": "upstream"
5568
+ },
5569
+ {
5570
+ "id": 370,
5571
+ "query": "writeq(./*).",
5572
+ "input": "writeq(./*).",
5573
+ "readCount": 1,
5574
+ "expected": "./*",
5575
+ "assertion": "upstream"
5576
+ },
5577
+ {
5578
+ "id": 371,
5579
+ "query": "writeq({*}).",
5580
+ "input": "writeq({*}).",
5581
+ "readCount": 1,
5582
+ "expected": "{*}",
5583
+ "assertion": "upstream"
5584
+ },
5585
+ {
5586
+ "id": 372,
5587
+ "query": "writeq(.*).",
5588
+ "input": "writeq(.*).",
5589
+ "readCount": 1,
5590
+ "expected": ".*",
5591
+ "assertion": "upstream"
5592
+ },
5593
+ {
5594
+ "id": 373,
5595
+ "query": "writeq(...*).",
5596
+ "input": "writeq(...*).",
5597
+ "readCount": 1,
5598
+ "expected": "...*",
5599
+ "assertion": "upstream"
5600
+ },
5601
+ {
5602
+ "id": 374,
5603
+ "query": "[.",
5604
+ "input": "[.",
5605
+ "readCount": 1,
5606
+ "expected": "syntax err.",
5607
+ "assertion": "upstream"
5608
+ },
5609
+ {
5610
+ "id": 375,
5611
+ "query": "{.",
5612
+ "input": "{.",
5613
+ "readCount": 1,
5614
+ "expected": "syntax err.",
5615
+ "assertion": "upstream"
5616
+ },
5617
+ {
5618
+ "id": 376,
5619
+ "query": "writeq(E).",
5620
+ "input": "writeq(E).",
5621
+ "readCount": 1,
5622
+ "expected": "e.g. _1",
5623
+ "assertion": "upstream"
5624
+ },
5625
+ {
5626
+ "id": 377,
5627
+ "query": "write_term(., [ignore_ops(true)]).",
5628
+ "input": "write_term(., [ignore_ops(true)]).",
5629
+ "readCount": 1,
5630
+ "expected": ".",
5631
+ "assertion": "upstream"
5632
+ },
5633
+ {
5634
+ "id": 380,
5635
+ "query": "write_term([' '], [ignore_ops(true)]).",
5636
+ "input": "write_term([' '], [ignore_ops(true)]).",
5637
+ "readCount": 1,
5638
+ "expected": ".( ,[])",
5639
+ "assertion": "upstream"
5640
+ },
5641
+ {
5642
+ "id": 378,
5643
+ "query": "writeq(--> /2).",
5644
+ "input": "writeq(--> /2).",
5645
+ "readCount": 1,
5646
+ "expected": "syntax err.",
5647
+ "assertion": "upstream"
5648
+ },
5649
+ {
5650
+ "id": 379,
5651
+ "query": "writeq((-->)/2).",
5652
+ "input": "writeq((-->)/2).",
5653
+ "readCount": 1,
5654
+ "expected": "(-->)/2",
5655
+ "assertion": "upstream"
5656
+ },
5657
+ {
5658
+ "id": 381,
5659
+ "query": "Finis ().",
5660
+ "input": "Finis ().",
5661
+ "readCount": 1,
5662
+ "expected": "syntax err.",
5663
+ "assertion": "upstream"
5560
5664
  }
5561
5665
  ],
5562
5666
  "sourceRevision": "1.300",
5563
- "sourceSha256": "b6590c1c5269e8e62a1ec72a8f04f21f123a77709854a8a66c436df25f3ff418"
5667
+ "sourceSha256": "db1edfc48e065b90169be55cd93a2a62b32f9dacb2fd0707667590c1a7536e69"
5564
5668
  }
@@ -1,14 +1,14 @@
1
1
  {
2
2
  "source": "https://www.complang.tuwien.ac.at/ulrich/iso-prolog/conformity_testing",
3
- "checkedOn": "2026-09-01",
3
+ "checkedOn": "2026-09-10",
4
4
  "upstream": {
5
5
  "firstId": 1,
6
- "lastId": 368,
6
+ "lastId": 381,
7
7
  "deletedIds": [
8
8
  20,
9
9
  273
10
10
  ],
11
- "activeCases": 366
11
+ "activeCases": 379
12
12
  },
13
13
  "evidence": [
14
14
  {
@@ -8,7 +8,7 @@ import { createDefaultRegistry, eyePrologLibraryIndicators, eyePrologNativeLibra
8
8
  import { assertEqual, assertIncludes, assertNotIncludes } from '../test-style.mjs';
9
9
  import { buildConformanceReport, formatConformanceReport } from '../run-conformance-report.mjs';
10
10
  import { renderWg17SyntaxStatus } from '../../tools/report-wg17-syntax-coverage.mjs';
11
- import { parseWg17SyntaxTable } from '../../tools/upgrade-wg17.mjs';
11
+ import { parseWg17SyntaxTable, updateWg17InventoryReferences } from '../../tools/upgrade-wg17.mjs';
12
12
  import { executeWg17Item, matchesUpstreamExpectation, readWg17SyntaxFixture } from '../run-wg17.mjs';
13
13
  import {
14
14
  assertArrayEqual,
@@ -169,6 +169,18 @@ ${profile}`;
169
169
  assertEqual(fs.readFileSync(filename, 'utf8'), renderWg17SyntaxStatus(), 'WG17 syntax status');
170
170
  },
171
171
  },
172
+ {
173
+ name: 'WG17 inventory documentation accepts omitted counts and repairs partial updates',
174
+ run: () => {
175
+ const countFree = 'The vendored WG17 syntax snapshot is intentionally secondary.';
176
+ assertEqual(updateWg17InventoryReferences(countFree, 379), countFree, 'no count required');
177
+ const stale = 'The 366-case vendored WG17 matrix and 365-case WG17 syntax matrix; WG17 matrix has 366 executable cases. An unrelated 366-case suite stays unchanged.';
178
+ const expected = 'The 379-case vendored WG17 matrix and 379-case WG17 syntax matrix; WG17 matrix has 379 executable cases. An unrelated 366-case suite stays unchanged.';
179
+ const updated = updateWg17InventoryReferences(stale, 379);
180
+ assertEqual(updated, expected, 'all stale WG17 counts repaired independently of fixture state');
181
+ assertEqual(updateWg17InventoryReferences(updated, 379), updated, 'retry is idempotent');
182
+ },
183
+ },
172
184
  {
173
185
  name: 'WG17 upgrader accepts omitted HTML table end tags',
174
186
  run: () => {
@@ -396,17 +396,20 @@ function formatIdList(ids) {
396
396
  return ids.length === 0 ? 'none' : ids.map((id) => `#${id}`).join(', ');
397
397
  }
398
398
 
399
- function updateDocumentedInventoryCount(previousCount, nextCount) {
400
- if (previousCount === nextCount) return;
399
+ export function updateWg17InventoryReferences(text, nextCount) {
400
+ // Some documents deliberately omit a count. Update only explicit WG17
401
+ // inventory references, independently of the previous fixture count: a
402
+ // retry may follow a partial update that already wrote the new fixture.
403
+ return text
404
+ .replace(/\b\d+-case(?=\s+(?:vendored\s+)?WG17\b)/g, `${nextCount}-case`)
405
+ .replace(/\bWG17 matrix has \d+ executable/g, `WG17 matrix has ${nextCount} executable`);
406
+ }
407
+
408
+ function updateDocumentedInventoryCount(nextCount) {
401
409
  for (const filename of countDocumentationPaths) {
402
410
  const original = fs.readFileSync(filename, 'utf8');
403
- const updated = original
404
- .replaceAll(`${previousCount}-case`, `${nextCount}-case`)
405
- .replaceAll(`WG17 matrix has ${previousCount} executable`, `WG17 matrix has ${nextCount} executable`);
406
- if (updated === original) {
407
- throw new Error(`WG17 inventory count was not found in ${path.relative(packageRoot, filename)}`);
408
- }
409
- fs.writeFileSync(filename, updated);
411
+ const updated = updateWg17InventoryReferences(original, nextCount);
412
+ if (updated !== original) fs.writeFileSync(filename, updated);
410
413
  }
411
414
  }
412
415
 
@@ -507,7 +510,7 @@ export async function upgradeWg17({ check = false, source = syntaxSource } = {})
507
510
  // Generate status after the fixture/manifest are synchronized.
508
511
  const { renderWg17SyntaxStatus } = await import('./report-wg17-syntax-coverage.mjs');
509
512
  fs.writeFileSync(syntaxStatusPath, renderWg17SyntaxStatus());
510
- updateDocumentedInventoryCount(previous.cases.length, fixture.cases.length);
513
+ updateDocumentedInventoryCount(fixture.cases.length);
511
514
 
512
515
  // The public report executes the refreshed fixture, so keep its measured row
513
516
  // synchronized as part of the same explicit upgrade operation.