eyeprolog 1.5.78 → 1.5.79

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.78",
6
+ "version": "1.5.79",
7
7
  "description": "EyeProlog turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
@@ -29,8 +29,8 @@ EyeProlog implements a broad ISO Prolog profile with facts, clauses, terms, list
29
29
  control, arithmetic, dynamic predicates, operators, streams, and standard
30
30
  built-ins. Explicit
31
31
  tabling, explicit integrity checks, and proof output are implementation
32
- capabilities around that standards-based foundation. EyeProlog does not attempt to
33
- claim formal certification of every ISO processor edge case.
32
+ capabilities around that standards-based foundation. EyeProlog does not
33
+ claim formal certification against every ISO processor edge case.
34
34
 
35
35
  Standards are crucial because knowledge and rules often outlive the software
36
36
  that first processes them. Using ISO Prolog keeps programs teachable,
@@ -148,8 +148,10 @@ tricks. By the end, a reader should be able to:
148
148
 
149
149
  That is the stake in the ground: a focused implementation of standard Prolog
150
150
  is enough to teach the large ideas when semantics, execution, and evidence
151
- remain visible together.
152
- The implementation is therefore part of the argument: the examples are executable programs, the reference chapters describe the running system, and proof terms remain available for inspection.
151
+ remain visible together. The implementation is therefore part of the
152
+ argument: the examples are executable programs, the reference chapters
153
+ describe the running system, and proof terms remain available for
154
+ inspection.
153
155
 
154
156
  ### A working discipline
155
157
 
@@ -574,7 +576,7 @@ alternative answers and already has the inputs its registered mode requires.
574
576
 
575
577
  Both readings matter. The declarative reading checks the model. The operational
576
578
  reading helps make search finite and selective. Put a generator before a
577
- built-in that needs its input:
579
+ built-in that needs its input.
578
580
 
579
581
  <figure>
580
582
  <img src="book-assets/logic-and-control.svg" alt="One recursive path rule points to its logical and operational readings.">
@@ -1139,8 +1141,8 @@ normal mode, EyeProlog provides explicit `tnot/1` for that case. When the
1139
1141
  reachable component is finite, function-free, and range-restricted Datalog,
1140
1142
  cycles through `tnot/1` are evaluated with the well-founded semantics (WFS)
1141
1143
  rather than ordinary negation-as-failure. WFS has three truth states: true,
1142
- false, and undefined. A negative cycle may therefore produce a conditional
1143
- answer instead of forcing an arbitrary true/false choice.
1144
+ false, and undefined. A negative cycle may therefore leave the query
1145
+ undefined instead of forcing an arbitrary true/false choice.
1144
1146
 
1145
1147
  ```eyeprolog
1146
1148
  move(a, b).
@@ -1149,9 +1151,10 @@ win(X) :- move(X, Y), tnot(win(Y)).
1149
1151
  ```
1150
1152
 
1151
1153
  Here neither `win(a)` nor `win(b)` is unconditionally established; both belong
1152
- to the undefined part of the well-founded model. EyeProlog retains that state
1153
- internally but does not expose undefined atoms as successful query answers or
1154
- run the remaining goals of a conjunction through them.
1154
+ to the undefined part of the well-founded model. EyeProlog retains that
1155
+ undefined state internally, but it does not treat an undefined atom as a
1156
+ successful query answer, nor does it continue evaluating the rest of a
1157
+ conjunction as though that atom had succeeded.
1155
1158
  Use `wfs_truth/2` when the truth state itself is data:
1156
1159
 
1157
1160
  ```text
@@ -1404,7 +1407,8 @@ Part II turned relations into finite computations:
1404
1407
  - generators state where finite candidates come from;
1405
1408
  - failure prunes a branch, while `\+/1` makes finite failure a closed-world
1406
1409
  test;
1407
- - `once/1` makes search order observable;
1410
+ - recursion through negation is handled by `tnot/1` and the well-founded
1411
+ semantics, whose undefined truth state is retained rather than forced;
1408
1412
  - aggregates turn a finite solution space into a list, count, sum, or optimum;
1409
1413
  - structured terms and contexts belong at explicit modeling boundaries;
1410
1414
  - puzzles become programs by separating generation, constraint, and witness.
@@ -1599,7 +1603,7 @@ must be handled before trusted downstream decisions.
1599
1603
  To see the explicit validation path, run:
1600
1604
 
1601
1605
  ```sh
1602
- node bin/eyeprolog.js examples/integrity-check.pl
1606
+ eyeprolog examples/integrity-check.pl
1603
1607
  ```
1604
1608
 
1605
1609
  It prints the invalid-state witness and the resulting diagnostic status. Nothing
@@ -1628,8 +1632,7 @@ positive recursive domain, repeated rounds can compute the least fixed point.
1628
1632
  It is therefore especially natural for reachability, grammars, dependency
1629
1633
  analysis, and other recursive relations with overlapping subproblems.
1630
1634
 
1631
- Ordinary goals use indexed depth-first resolution, including ordinary recursive
1632
- goals. Tabling is opt-in: declare a predicate with `:- table p/n.` when its
1635
+ Ordinary goals, including recursive ones, use indexed depth-first resolution. Tabling is opt-in: declare a predicate with `:- table p/n.` when its
1633
1636
  recursive calls should share answers and cyclic calls should iterate toward a
1634
1637
  fixed point. For sufficiently large finite, function-free Datalog dependency
1635
1638
  cones rooted at an explicitly tabled predicate, EyeProlog may share one
@@ -2211,20 +2214,13 @@ when those boundaries became named rather than implicit.
2211
2214
 
2212
2215
  This Part turns from implementation features to habits of construction. A good
2213
2216
  program rarely arrives whole; it is discovered through examples, corrected by
2214
- invariants, and refined without losing sight of the relation it means.
2217
+ invariants, and refined without losing sight of the relation it is meant to express.
2215
2218
 
2216
2219
  ## 17. Logic and control
2217
2220
 
2218
2221
  The central pleasure—and central difficulty—of logic programming is that a
2219
2222
  short definition plays two roles. Consider:
2220
2223
 
2221
- This distinction is one of logic programming's oldest and most durable design
2222
- ideas. The logical component describes admissible answers; the control
2223
- component determines which consequences are explored, in what order, and with
2224
- what resource cost. A change in indexing, goal order, or tabling policy should
2225
- ideally preserve the first while improving the second. In practice, modeful
2226
- built-ins and incomplete searches mean that programmers must reason about both.
2227
-
2228
2224
  ```eyeprolog
2229
2225
 
2230
2226
  :- use_module(library(lists)).
@@ -2237,6 +2233,13 @@ As logic, the clauses say that every edge is a path and that an edge followed
2237
2233
  by a path is a path. As control, they tell the solver to try a direct edge
2238
2234
  first, then choose an outgoing edge and continue from its endpoint.
2239
2235
 
2236
+ This distinction is one of logic programming's oldest and most durable design
2237
+ ideas. The logical component describes admissible answers; the control
2238
+ component determines which consequences are explored, in what order, and with
2239
+ what resource cost. A change in indexing, goal order, or tabling policy should
2240
+ ideally preserve the first while improving the second. In practice, modeful
2241
+ built-ins and incomplete searches mean that programmers must reason about both.
2242
+
2240
2243
  It is useful to write the relation first as a sentence:
2241
2244
 
2242
2245
  > `path(X, Y)` holds when there is a finite sequence of edges from `X` to `Y`.
@@ -2492,15 +2495,15 @@ Testing examples is necessary, but a reusable relation deserves a stronger
2492
2495
  argument. Two questions should be asked separately:
2493
2496
 
2494
2497
  <figure>
2495
- <img src="book-assets/correctness-obligations.svg" alt="Overlapping circles for soundness, completeness, and termination meet at a dependable operational contract.">
2496
- <figcaption>Soundness, completeness, and termination are independent promises; a dependable intended call needs all three.</figcaption>
2498
+ <img src="book-assets/correctness-obligations.svg" alt="Overlapping circles for partial correctness, completeness, and termination meet at a dependable operational contract.">
2499
+ <figcaption>Partial correctness, completeness, and termination are independent promises; a dependable intended call needs all three.</figcaption>
2497
2500
  </figure>
2498
2501
 
2499
2502
  1. **Partial correctness:** if the program returns an answer, is it justified?
2500
2503
  2. **Completeness:** for the intended finite calls, can it find every answer
2501
2504
  required by the specification?
2502
2505
 
2503
- For `prefix/2`, partial correctness follows by the clauses. The base clause
2506
+ For `prefix/2`, partial correctness follows from the clauses by induction. The base clause
2504
2507
  returns only the empty prefix. The recursive clause adds the same head to a
2505
2508
  smaller valid prefix, so the result remains a prefix. Completeness follows in
2506
2509
  the opposite direction: every nonempty prefix shares its first element with
@@ -2694,9 +2697,12 @@ invariants and modes. Sterling and Shapiro made construction and improvement
2694
2697
  central to *The Art of Prolog*, showing that declarative clarity and
2695
2698
  procedural competence mature together.
2696
2699
 
2697
- EyeProlog removes several classic Prolog control devices, especially cut. The
2698
- smaller surface changes the techniques but not the problem: authors must still
2699
- turn a true relation into a productive computation and say what was preserved.
2700
+ EyeProlog keeps ISO cut, but Chapter 34 disciplines it: it commits only within
2701
+ the clause that contains it, never across a disjunction branch or a
2702
+ meta-call's own boundary, and it is presented as a last resort next to
2703
+ `once/1` and if-then-else. That discipline changes the techniques but not the
2704
+ problem: authors must still turn a true relation into a productive computation
2705
+ and say what was preserved.
2700
2706
 
2701
2707
  # Part V — Advanced relational design
2702
2708
 
@@ -2718,9 +2724,10 @@ requirements clarified by the 2013 ISO/IEC 13211-2 module amendment are covered
2718
2724
  by a dedicated release-gated suite, including public imports through
2719
2725
  `ensure_loaded/1` and caller-module qualification of `:` meta-arguments. The
2720
2726
  unchanged remainder of Part 2 is still treated as a compatibility surface, not
2721
- as a claim of complete ISO/IEC 13211-2:2000 conformance. Definite-clause grammar notation remains
2722
- outside this profile. The examples still prefer explicit domain
2723
- relations, state, and syntax trees where that makes assumptions easier to
2727
+ as a claim of complete ISO/IEC 13211-2:2000 conformance. Definite-clause grammar notation is
2728
+ also part of the normal profile, though the running examples have avoided it so far;
2729
+ Chapter 22 introduces it explicitly rather than assuming it. The examples still prefer
2730
+ explicit domain relations, state, and syntax trees where that makes assumptions easier to
2724
2731
  inspect.
2725
2732
 
2726
2733
  ## 21. Reading the computation
@@ -3625,7 +3632,7 @@ mathematical acts inside the running machine:
3625
3632
  | Perform induction | base and recursive clauses | reduce to smaller calls |
3626
3633
  | Construct a witness | bind an output term | return evidence, not only truth |
3627
3634
  | Refute a universal guess | search for a counterexample | one answer is enough |
3628
- | Check consistency | an explicit integrity query | let the host reject or report invalid input |
3635
+ | Check consistency | an explicit integrity query | reject or report invalid input |
3629
3636
  | Explain a conclusion | a proof term | expose the successful derivation |
3630
3637
 
3631
3638
  The table is a correspondence, not an identity. A mathematical proof and an
@@ -3793,11 +3800,11 @@ calculation.
3793
3800
  There is an important lifetime distinction between a table that is needed to
3794
3801
  finish one fixed point and a cache of tables retained for possible later reuse.
3795
3802
  DCG nonterminals are ordinary predicates after expansion, so they are depth-first
3796
- unless their expanded predicate indicator is explicitly tabled. For an
3797
- explicitly tabled grammar invoked through `phrase/2-3`, EyeProlog uses a
3798
- separate invocation-keyed table scope rather than retaining tables for unrelated
3799
- input sequences. Untabled list-tail DCGs such as `... --> [_], ...` therefore
3800
- run directly with standard Prolog control, while a declared table remains a
3803
+ unless their expanded predicate indicator is explicitly tabled. Untabled
3804
+ list-tail DCGs such as `... --> [_], ...` therefore run directly with standard
3805
+ Prolog control. For an explicitly tabled grammar invoked through `phrase/2-3`,
3806
+ EyeProlog instead uses a separate invocation-keyed table scope rather than
3807
+ retaining tables for unrelated input sequences a declared table remains a
3801
3808
  conscious source-level choice.
3802
3809
 
3803
3810
  **Exercises.**
@@ -4037,7 +4044,7 @@ A function privileges one direction. An equation or relation contains several:
4037
4044
  rectangle(W, H, Area) :- (Area is W * H).
4038
4045
  ```
4039
4046
 
4040
- In a supported arithmetic mode, this relation may verify an area or calculate
4047
+ When `W` and `H` are already bound, this relation may verify an area or calculate
4041
4048
  it from width and height. With a finite generator it can also search for
4042
4049
  factorizations:
4043
4050
 
@@ -4556,7 +4563,7 @@ This is a test over a ground, terminating goal. It does not turn negation as
4556
4563
  failure into classical negation; it records that this finite theory derives no
4557
4564
  such path.
4558
4565
 
4559
- For a reusable package, prefer a dedicated test program that loads or repeats
4566
+ For a reusable package, prefer a dedicated test program that loads or reproduces
4560
4567
  the relevant theory and declares only test queries. For a small example, the
4561
4568
  golden answer file is an executable specification of the expected answer set.
4562
4569
 
@@ -4874,7 +4881,7 @@ testing is a powerful guard during program transformation.
4874
4881
  `--stats` reports work, not meaning. A high solution count may be necessary or
4875
4882
  may indicate a generator that should be constrained. Many table hits may show
4876
4883
  effective reuse; many distinct table entries may reveal an argument that
4877
- prevents calls from sharing. On the Node CLI it also reports current heap use,
4884
+ prevents calls from sharing table entries. On the Node CLI it also reports current heap use,
4878
4885
  non-young/old-generation use, the amount currently compared with the memory
4879
4886
  guard, resident-set size, and the soft and hard memory ceilings in bytes. These
4880
4887
  memory figures are printed even when execution ends by raising a Prolog error.
@@ -4930,7 +4937,7 @@ choice, repaired invariant, and test that would fail if the defect returned.
4930
4937
 
4931
4938
  A pattern is not a copied code fragment. It is a recurring arrangement of
4932
4939
  meaning, representation, and control that solves a named design problem. The
4933
- following patterns summarize recurring constructions that are especially useful in practice.
4940
+ following patterns collect constructions that are especially useful in practice.
4934
4941
 
4935
4942
  <figure>
4936
4943
  <img src="book-assets/pattern-selection-map.svg" alt="Six recurring design symptoms point to patterns for meaning, tabling, closed boundaries, finite search, proof-carrying answers, and canonical representation.">
@@ -5244,7 +5251,7 @@ the language/runtime surface to ISO/IEC 13211-1:1995 plus Technical Corrigenda
5244
5251
  normal and strict profiles: EyeProlog uses Unicode scalar values U+0000..U+10FFFF
5245
5252
  excluding surrogates, with the scalar value as the collating-sequence integer.
5246
5253
  Strict mode restricts implementation-specific language facilities, but it does
5247
- not narrow this processor-defined character repertoire. Isolated mode and error cases live in `test/conformance/cases/iso/`.
5254
+ not narrow this processor-defined character repertoire. Isolation and error cases live in `test/conformance/cases/iso/`.
5248
5255
  The examples here compose those operations into programs worth changing and
5249
5256
  rerunning.
5250
5257
 
@@ -5280,8 +5287,9 @@ The two can produce the same first answer without expressing the same control
5280
5287
  boundary. Keep cut close to the choice it documents and test the complete
5281
5288
  answer set before and after introducing it. A cut executed inside a predicate
5282
5289
  called by one disjunction branch remains local to that predicate: if the branch
5283
- later fails, `Left ; Right` must still try `Right`. This remains true for
5284
- cut-bearing validation helpers used by generators such as `between/3`.
5290
+ later fails, `Left ; Right` must still try `Right`. This also holds when a
5291
+ cut-bearing validation helper is called from a branch driven by a generator
5292
+ such as `between/3`: the helper's own cut still stays local to it.
5285
5293
 
5286
5294
  Exceptions separate an exceptional call from ordinary logical failure:
5287
5295
 
@@ -5484,12 +5492,14 @@ same context rules: with `quoted(true)`, an operator atom is not quoted merely
5484
5492
  because it occurs as a functional argument, list element, or sole curly-bracket
5485
5493
  content. Thus `writeq({*})` emits `{*}`, `writeq([:-,-])` emits `[:-,-]`, and
5486
5494
  `writeq(f(;,'|',';;'))` emits `f(;,'|',';;')`; the bar stays quoted because
5487
- ISO treats the unquoted `|` token as a list separator rather than an atom. The ISO initial operator table also
5495
+ ISO treats the unquoted `|` token as a list separator rather than an atom.
5496
+
5497
+ The ISO initial operator table also
5488
5498
  contains `?-` at priority 1200 with specifier `fx`, so
5489
5499
  `current_op(1200, fx, ?-)` succeeds. EyeProlog's embedded quad syntax permits
5490
- an optional label before the query marker (`Label ?- Query.`), so while quad
5491
- syntax is supported it additionally exposes `?-` at priority 1200 with
5492
- specifier `xfx` as an implementation-specific operator. Consequently
5500
+ an optional label before the query marker (`Label ?- Query.`); supporting that
5501
+ syntax additionally exposes `?-` at priority 1200 with specifier `xfx` as an
5502
+ implementation-specific operator. Consequently
5493
5503
  `current_op(Priority, Specifier, ?-)` enumerates both definitions. At top level in the normal EyeProlog profile, the quad marker is recognized
5494
5504
  from the parsed `?-/1` or `?-/2` term rather than from one privileged surface
5495
5505
  spelling. Thus `Label ?- Query.`, `?-(Label, Query).`, mixed forms such as
@@ -5680,7 +5690,7 @@ lists; strict ISO mode accepts neither syntax extension.
5680
5690
 
5681
5691
  The processor character set is shared by normal and `--iso-strict` modes because
5682
5692
  Part 1 makes it implementation defined rather than an extension boundary.
5683
- EyeProlog's PCS is the Unicode scalar repertoire. Printable ASCII keeps the Part
5693
+ EyeProlog's PCS (processor character set) is the Unicode scalar repertoire. Printable ASCII keeps the Part
5684
5694
  1 lexical classes; Unicode letters extend alphanumeric name syntax, Unicode
5685
5695
  white-space characters are layout, and remaining non-ASCII symbols/punctuation
5686
5696
  are extended graphic characters. Character-code and collation values are the
@@ -5794,7 +5804,7 @@ variable to a term containing that same variable fails.
5794
5804
 
5795
5805
  An **atom constant** such as `pat` is a term. An **atomic formula** such as
5796
5806
  `parent(pat, jan)` is a proposition that may be a fact, rule head, or goal.
5797
- The surface form `pair(pat, jan)` may also be compound data when nested inside
5807
+ The same surface form, `parent(pat, jan)`, may also be compound data when nested inside
5798
5808
  another term; its role comes from context. Predicate identity includes arity,
5799
5809
  so `edge/2` and `edge/3` are different predicates.
5800
5810
 
@@ -5876,7 +5886,7 @@ look_ahead(X), [X] --> [X].
5876
5886
  `phrase(+Body,?Sequence,?Rest)` leaves `Rest` unconsumed and is steadfast in
5877
5887
  that argument. A variable body raises `instantiation_error`; a non-callable
5878
5888
  body raises `type_error(callable)`. EyeProlog elects to perform the optional
5879
- terminal-sequence checks of ISO/IEC TS 13211-3:2025, 8.18.1.3 g and h.
5889
+ terminal-sequence checks of the ISO/IEC TS 13211-3 working draft, 8.18.1.3 g and h.
5880
5890
  It consistently reports `type_error(list, Culprit)` for invalid input in both
5881
5891
  arities and invalid remainder in `phrase/3`, including improper lists.
5882
5892
  Variables, proper lists, and partial lists pass these checks. Validation
@@ -5918,7 +5928,7 @@ round-tripping. The checked answers are in
5918
5928
 
5919
5929
  #### Deep sequence hand-off
5920
5930
 
5921
- `library(iso_ext)` provides the common `... //0` helper, which describes an
5931
+ `library(dcgs)` provides the common `... //0` helper, which describes an
5922
5932
  arbitrary number of input elements. It is not part of ISO Part 3, but it is a
5923
5933
  useful interoperability and stress-test relation. A compact hand-off test is:
5924
5934
 
@@ -5936,10 +5946,10 @@ constructing a fresh general clause-resolution frame at every suffix. The list
5936
5946
  spine is still traversed; this is a control/allocation optimization rather than
5937
5947
  an O(1) semantic shortcut.
5938
5948
 
5939
- The optimization is deliberately narrow. `phrase(..., Sequence, Rest)` still
5949
+ The optimization is deliberately narrow. `phrase(..., Sequence, Rest)` still
5940
5950
  enumerates the valid remainders, open or non-compact inputs retain ordinary
5941
5951
  relational behavior, and grammars that can consume or constrain the remainder
5942
- are not treated as identity continuations. `time/1` can be used in normal mode
5952
+ are not treated as identity continuations. `time/1` can be used in normal mode
5943
5953
  to measure such runs; its inference counter records solver-level inferences and
5944
5954
  does not count every internal step of an optimized scanner.
5945
5955
 
@@ -10336,7 +10346,7 @@ hand.
10336
10346
 
10337
10347
  #### Running and extending the corpus
10338
10348
 
10339
- Run all 210 normal answer goldens and the 61 selected proof goldens with:
10349
+ Run all 228 normal answer goldens and the 61 selected proof goldens with:
10340
10350
 
10341
10351
  ```sh
10342
10352
  node test/run-examples.mjs
@@ -10393,7 +10403,7 @@ When adding an example:
10393
10403
  6. include both a positive case and a meaningful boundary or failure case;
10394
10404
  7. run the full corpus before treating the example as documentation.
10395
10405
 
10396
- Every top-level program under `examples/` appears in the thematic lists and the alphabetical index. Apply the same reading discipline to every example—sentence, mode, finite domain, answer, proof, and revision.
10406
+ Every top-level program under `examples/` appears in the thematic lists above. Apply the same reading discipline to every example—sentence, mode, finite domain, answer, proof, and revision.
10397
10407
 
10398
10408
  ## 42. Standards, limits, and implementation boundaries
10399
10409
 
@@ -10416,8 +10426,7 @@ node test/run-conformance-report.mjs
10416
10426
  ```
10417
10427
 
10418
10428
  `test/conformance/ISO-COMPLIANCE.md` is the processor-requirement ledger for the
10419
- Part 1 conformance review. It records explicit dispositions for the tracked processor, syntax, semantic, built-in, and arithmetic requirements. `test/conformance/ISO-COMPLIANCE.md`
10420
- maps language families to representative executable cases.
10429
+ Part 1 conformance review. It records explicit dispositions for the tracked processor, syntax, semantic, built-in, and arithmetic requirements, and maps language families to representative executable cases.
10421
10430
  `test/conformance/ISO-IMPLEMENTATION-DEFINED.md` is the ISO 5.4 decision
10422
10431
  index: it enumerates the Part 1 implementation-defined decisions and the
10423
10432
  implementation-specific extension families without turning draft WG17/STC
@@ -10436,7 +10445,7 @@ accept texts outside the strict grammar, but it may not reinterpret an accepted
10436
10445
  standard case.
10437
10446
 
10438
10447
  The file-based conformance corpus contains 810 cases, including 393 focused ISO cases derived from the success, failure, mode, and error behavior in ISO/IEC 13211-1 clauses 7 and 8, Part 2 modules, and Part 3 grammar rules.
10439
- Separate exact-output suites check 210 normal examples and 61 proof examples; all executable chapter programs are parsed and their declared goals are executed. The eight-case
10448
+ Separate exact-output suites check 228 normal examples and 61 proof examples; all executable chapter programs are parsed and their declared goals are executed. The nine-case
10440
10449
  playground contract suite imports the production worker, sends real reasoning
10441
10450
  requests through its message protocol, and crawls the served module graph for
10442
10451
  missing assets, bad MIME types, and static Node-only imports. `conformance-report.md` records the current executable WG17 syntax result and file-based conformance category totals.