eyeprolog 1.5.2 → 1.5.3
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/README.md
CHANGED
|
@@ -31,8 +31,6 @@ Run EyeProlog without installing it globally:
|
|
|
31
31
|
|
|
32
32
|
```sh
|
|
33
33
|
npx --yes eyeprolog
|
|
34
|
-
?- use_module(library(lists)).
|
|
35
|
-
true.
|
|
36
34
|
?- member(X, [prolog, logic]).
|
|
37
35
|
X = prolog
|
|
38
36
|
; X = logic.
|
|
@@ -63,7 +61,9 @@ printf 'human(socrates).\nmortal(X) :- human(X).\n' |
|
|
|
63
61
|
Normal mode executes top-level `Conclusion :+ Premise` rules natively when no explicit
|
|
64
62
|
`-g/--goal` is supplied. `true :+ Goal` prints answers and `false :+ Goal` emits a
|
|
65
63
|
`fuse/1`; JavaScript `run()` follows the same rule. Strict ISO mode disables this
|
|
66
|
-
extension.
|
|
64
|
+
extension. Bundled `src/lib/` predicates autoload in files, CLI/API goals, and the REPL;
|
|
65
|
+
use `--no-autoload` to require explicit imports, and explicitly import libraries that introduce
|
|
66
|
+
operators before using their syntax. See [*The Art of EyeProlog*](the-art-of-eyeprolog.md) for the full semantics.
|
|
67
67
|
|
|
68
68
|
## Links
|
|
69
69
|
|
package/package.json
CHANGED
|
@@ -121,7 +121,7 @@ families; `--iso-strict` is intended to remove their Part 1 interpretation.
|
|
|
121
121
|
| 5.5.6 Side effects | Normal mode adds `statistics/0-2`, cleanup/library state, and optional proof/statistics host instrumentation. | The strict registry excludes Prolog-visible statistics/cleanup/library adapters; ordinary Part 1 I/O/database/flag/operator side effects remain. Host proof/statistics collection observes execution through the embedding API rather than adding a strict Prolog goal effect. **covered** — strict registry/execution regression. |
|
|
122
122
|
| 5.5.7 Control constructs | `tnot/1` and normal-profile execution optimizations | `tnot/1` and the normal-profile explicit `table` declaration are absent. |
|
|
123
123
|
| 5.5.8 Flags | `occurs_check` | Absent in strict mode. |
|
|
124
|
-
| 5.5.9 Built-in predicates | EyeProlog libraries, CLP(Z), statistics, Part 3 `phrase/2-3`, and
|
|
124
|
+
| 5.5.9 Built-in predicates | EyeProlog libraries, CLP(Z), statistics, Part 3 `phrase/2-3`, and bundled-library autoloaded predicates | Strict registry contains only the Part 1 + Corrigenda core registry. |
|
|
125
125
|
| 5.5.10 Evaluable functors | Normal mode additionally accepts the EyeProlog evaluable atom `e`; the remaining arithmetic functors accepted by strict mode are the Part 1 + Corrigenda set. | Strict mode rejects `e/0` as non-evaluable and retains the Corrigendum arithmetic additions. **covered** — strict extension-boundary regression plus `src/iso-arithmetic.js`. |
|
|
126
126
|
| 5.5.11 Reserved atoms | None | None. |
|
|
127
127
|
| Cor.3 5.5.12 Options | Extra library/host options may exist outside core option lists | Normal mode additionally accepts the EyeProlog `write_term/2-3` options `double_quotes(true|false)` and `spacing(true|false)`. `spacing(false)` emits only lexically required separators; `spacing(true)` adds conventional layout around operators. Strict core excludes these implementation-specific extensions and accepts only the Part 1 plus Corrigendum 3 write-option surface; unknown extension options raise `domain_error(write_option,...)`. |
|
package/test/run-regression.mjs
CHANGED
|
@@ -4784,6 +4784,33 @@ function documentationSyncCases() {
|
|
|
4784
4784
|
assertEqual(result.stderr, '', 'stderr');
|
|
4785
4785
|
},
|
|
4786
4786
|
},
|
|
4787
|
+
{
|
|
4788
|
+
name: 'reference docs match explicit tabling and current runtime extensions',
|
|
4789
|
+
run: () => {
|
|
4790
|
+
const readme = fs.readFileSync(path.join(packageRoot, 'README.md'), 'utf8');
|
|
4791
|
+
const book = fs.readFileSync(path.join(packageRoot, 'the-art-of-eyeprolog.md'), 'utf8');
|
|
4792
|
+
const profile = fs.readFileSync(path.join(packageRoot, 'why-eyeprolog.md'), 'utf8');
|
|
4793
|
+
const combined = `${readme}
|
|
4794
|
+
${book}
|
|
4795
|
+
${profile}`;
|
|
4796
|
+
for (const stale of [
|
|
4797
|
+
'Automatic tabling',
|
|
4798
|
+
'Automatic hybrid reasoning',
|
|
4799
|
+
'eligible positive recursive groups are tabled automatically',
|
|
4800
|
+
'--no-auto-table',
|
|
4801
|
+
'conservative interop autoloading',
|
|
4802
|
+
]) assertNotIncludes(combined, stale, `stale documentation phrase ${stale}`);
|
|
4803
|
+
assertIncludes(book, 'including recursive calls, use depth-first resolution unless the source', 'ordinary recursion is depth-first');
|
|
4804
|
+
assertIncludes(book, 'explicitly declares `:- table p/n.`', 'tabling is explicit');
|
|
4805
|
+
assertIncludes(book, 'The autoload index covers every', 'generic bundled-library autoload');
|
|
4806
|
+
assertIncludes(book, 'interactive top-level query therefore autoloads its canonical', 'REPL autoload');
|
|
4807
|
+
assertIncludes(book, 'Autoloading therefore supplies', 'autoload syntax boundary');
|
|
4808
|
+
assertIncludes(book, 'Residual constraints are part of the displayed answer even when', 'top-level hidden residuals');
|
|
4809
|
+
assertIncludes(book, 'EyeProlog normal mode also accepts `:+`', 'native forward-rule extension');
|
|
4810
|
+
assertIncludes(profile, 'an unresolved unqualified predicate may autoload its unique provider', 'Why EyeProlog autoload policy');
|
|
4811
|
+
assertIncludes(readme, 'Bundled `src/lib/` predicates autoload in files, CLI/API goals, and the REPL', 'README autoload summary');
|
|
4812
|
+
},
|
|
4813
|
+
},
|
|
4787
4814
|
{
|
|
4788
4815
|
name: 'WG17 syntax status matches its executable-coverage manifest',
|
|
4789
4816
|
run: () => {
|
package/the-art-of-eyeprolog.md
CHANGED
|
@@ -30,7 +30,7 @@ program with EyeProlog means learning to move comfortably between these views.
|
|
|
30
30
|
|
|
31
31
|
EyeProlog implements a broad ISO Prolog profile with facts, clauses, terms, lists,
|
|
32
32
|
control, arithmetic, dynamic predicates, operators, streams, and standard
|
|
33
|
-
built-ins.
|
|
33
|
+
built-ins. Explicit
|
|
34
34
|
tabling, explicit integrity checks, and proof output are implementation
|
|
35
35
|
capabilities around that standards-based foundation. EyeProlog does not attempt to
|
|
36
36
|
claim formal certification of every ISO processor edge case.
|
|
@@ -175,7 +175,8 @@ Approach each example through the same six moves:
|
|
|
175
175
|
This rhythm deliberately joins declarative reading, operational reading, and
|
|
176
176
|
program construction. Readers new to logic programming can follow Parts I–III
|
|
177
177
|
in order. Experienced Prolog programmers can begin with Chapters 3, 13, and
|
|
178
|
-
17 to see
|
|
178
|
+
17 to see how EyeProlog combines ordinary depth-first Prolog with explicit
|
|
179
|
+
tabling, native forward rules, and inspectable proofs.
|
|
179
180
|
Chapter 41 gives further routes through the material.
|
|
180
181
|
|
|
181
182
|
### When a run surprises you
|
|
@@ -5685,10 +5686,11 @@ so `edge/2` and `edge/3` are different predicates.
|
|
|
5685
5686
|
|
|
5686
5687
|
Execution is goal-directed rather than complete bottom-up saturation. Goals in
|
|
5687
5688
|
a body normally run from left to right; the solver may select a ready
|
|
5688
|
-
deterministic built-in early as a pure filter. Ordinary user-defined calls
|
|
5689
|
-
depth-first resolution
|
|
5690
|
-
|
|
5691
|
-
negation
|
|
5689
|
+
deterministic built-in early as a pure filter. Ordinary user-defined calls,
|
|
5690
|
+
including recursive calls, use depth-first resolution unless the source
|
|
5691
|
+
explicitly declares `:- table p/n.`. `\+/1` is negation as failure, not
|
|
5692
|
+
classical negation; the separate `tnot/1` extension provides well-founded
|
|
5693
|
+
semantics for eligible finite Datalog components.
|
|
5692
5694
|
|
|
5693
5695
|
EyeProlog supports cut, operator declarations, dynamic database updates, grouped
|
|
5694
5696
|
solutions, exceptions, flags, initialization and inclusion directives, and
|
|
@@ -5840,21 +5842,27 @@ time. Source facts are not echoed as new conclusions, and duplicate answers
|
|
|
5840
5842
|
are suppressed. Answers are not asserted back into the running program.
|
|
5841
5843
|
Supported output syntax is designed to be readable as Prolog input accepted by EyeProlog.
|
|
5842
5844
|
|
|
5843
|
-
####
|
|
5845
|
+
#### Explicit tabling and recursion planning
|
|
5844
5846
|
|
|
5845
|
-
The program loader
|
|
5846
|
-
|
|
5847
|
-
|
|
5848
|
-
|
|
5849
|
-
|
|
5850
|
-
because positive least-fixed-point tabling does not define unstratified
|
|
5851
|
-
negation. Nonrecursive groups use indexed, depth-first resolution.
|
|
5847
|
+
The program loader analyzes predicate dependencies and recursion so the solver
|
|
5848
|
+
can choose semantics-preserving indexes and fast paths. That analysis does
|
|
5849
|
+
**not** decide whether a predicate is tabled. Ordinary predicates—including
|
|
5850
|
+
recursive ones—use indexed, depth-first Prolog resolution unless their source
|
|
5851
|
+
explicitly declares `:- table p/n.`.
|
|
5852
5852
|
|
|
5853
|
-
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5853
|
+
An explicitly tabled positive recursive predicate is coordinated through an
|
|
5854
|
+
answer table: recurring calls consume answers already found, new answers are
|
|
5855
|
+
recorded, and evaluation continues toward a fixed point. For eligible large,
|
|
5856
|
+
finite, function-free Datalog components, EyeProlog may represent that declared
|
|
5857
|
+
table as one shared most-general relation or an indexed least model. For other
|
|
5858
|
+
declared tables the engine may infer structurally bound input positions to
|
|
5859
|
+
improve table reuse. These are implementation choices inside an explicit table
|
|
5860
|
+
declaration; they never opt an undeclared predicate into tabling.
|
|
5861
|
+
|
|
5862
|
+
Ordinary `\+/1` remains ISO-style negation as failure. The separate `tnot/1`
|
|
5863
|
+
extension explicitly requests well-founded evaluation for eligible finite,
|
|
5864
|
+
range-restricted Datalog dependencies. Strict ISO mode exposes neither `table`
|
|
5865
|
+
nor `tnot/1`.
|
|
5858
5866
|
|
|
5859
5867
|
#### Query execution
|
|
5860
5868
|
|
|
@@ -5872,8 +5880,8 @@ answers. The host:
|
|
|
5872
5880
|
7. prints each answer and, only when requested, its `why/2` explanation.
|
|
5873
5881
|
|
|
5874
5882
|
Goal selection affects host execution rather than the program's logical meaning.
|
|
5875
|
-
One goal's answers are not asserted for later goals, although
|
|
5876
|
-
tables may be reused during the solver run. For stable output, queries for
|
|
5883
|
+
One goal's answers are not asserted for later goals, although explicitly
|
|
5884
|
+
declared tables may be reused during the solver run. For stable output, queries for
|
|
5877
5885
|
known predicates are grouped by the source order in which their predicate
|
|
5878
5886
|
groups first appear; goals within one group retain their supplied order.
|
|
5879
5887
|
Queries for predicates with no group follow the known groups.
|
|
@@ -7475,7 +7483,7 @@ recursion as one technique.
|
|
|
7475
7483
|
| [Deep taxonomy: 10](https://github.com/eyereasoner/eyeprolog/blob/main/examples/deep-taxonomy-10.pl) | A small generated hierarchy is readable by hand and establishes the benchmark shape. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/deep-taxonomy-10.pl) |
|
|
7476
7484
|
| [Deep Taxonomy 100](https://github.com/eyereasoner/eyeprolog/blob/main/examples/deep-taxonomy-100.pl) | A 100-step taxonomy chain that exercises deep recursive closure and side-label derivation. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/deep-taxonomy-100.pl) |
|
|
7477
7485
|
| [Deep taxonomy: 1,000](https://github.com/eyereasoner/eyeprolog/blob/main/examples/deep-taxonomy-1000.pl) | The same logical theory tests indexing and recursive closure at a realistic depth. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/deep-taxonomy-1000.pl) |
|
|
7478
|
-
| [Deep Taxonomy 10000](https://github.com/eyereasoner/eyeprolog/blob/main/examples/deep-taxonomy-10000.pl) | A 10,000-step taxonomy chain used as a large-depth
|
|
7486
|
+
| [Deep Taxonomy 10000](https://github.com/eyereasoner/eyeprolog/blob/main/examples/deep-taxonomy-10000.pl) | A 10,000-step taxonomy chain used as a large-depth ordinary-recursion and closure stress test. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/deep-taxonomy-10000.pl) |
|
|
7479
7487
|
| [Deep taxonomy: 100,000](https://github.com/eyereasoner/eyeprolog/blob/main/examples/deep-taxonomy-100000.pl) | A stress case separates semantic simplicity from implementation scale. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/deep-taxonomy-100000.pl) |
|
|
7480
7488
|
| [Family cousins](https://github.com/eyereasoner/eyeprolog/blob/main/examples/family-cousins.pl) | Several relational joins derive kinship beyond a simple transitive closure. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/family-cousins.pl) |
|
|
7481
7489
|
| [Graph reachability](https://github.com/eyereasoner/eyeprolog/blob/main/examples/graph-reachability.pl) | A visited list bounds cyclic traversal and makes explicit negative test cases finite. | [answers](https://github.com/eyereasoner/eyeprolog/blob/main/examples/output/graph-reachability.pl) · [proof](https://github.com/eyereasoner/eyeprolog/blob/main/examples/proof/graph-reachability.pl) |
|
package/why-eyeprolog.md
CHANGED
|
@@ -149,6 +149,14 @@ removes the operator. Because resource exhaustion is not logical failure, normal
|
|
|
149
149
|
execution has no hidden depth cutoff; an explicitly requested depth limit raises
|
|
150
150
|
`resource_error(depth_limit)`.
|
|
151
151
|
|
|
152
|
+
Library convenience is explicit at the profile boundary too. Outside strict ISO
|
|
153
|
+
mode, an unresolved unqualified predicate may autoload its unique provider from
|
|
154
|
+
the bundled `src/lib/` modules after program definitions, standard built-ins,
|
|
155
|
+
and explicit imports have had precedence. `--no-autoload` disables this
|
|
156
|
+
convenience, and strict ISO mode disables it unconditionally. Autoloading happens
|
|
157
|
+
after parsing, so libraries that introduce operators still require an explicit
|
|
158
|
+
`use_module/1-2` before that syntax is read.
|
|
159
|
+
|
|
152
160
|
Definite clause grammars follow the ISO Part 3 difference-list model. Internal
|
|
153
161
|
fast paths make deep finite sequence processing economical while preserving
|
|
154
162
|
relational modes. The checked
|