eyeprolog 1.2.15 → 1.2.17
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 +1 -1
- package/src/repl.js +9 -2
- package/src/solver.js +4 -3
- package/test/run-regression.mjs +61 -14
- package/the-art-of-eyeprolog.md +10 -4
package/package.json
CHANGED
package/src/repl.js
CHANGED
|
@@ -9,7 +9,7 @@ const ANSWER_HELP = `
|
|
|
9
9
|
SPACE, "n" or ";": next solution, if any
|
|
10
10
|
RETURN or ".": stop enumeration
|
|
11
11
|
"a": enumerate all solutions
|
|
12
|
-
"f": enumerate the next 5 solutions
|
|
12
|
+
"f": enumerate through the next group of 5 solutions
|
|
13
13
|
"h": display this help message
|
|
14
14
|
"w": write terms without depth limit
|
|
15
15
|
"p": print terms with depth limit
|
|
@@ -486,11 +486,13 @@ async function solveQuery(engine, state, goal, reader, output) {
|
|
|
486
486
|
}
|
|
487
487
|
|
|
488
488
|
let automatic = 0;
|
|
489
|
+
let answersShown = 0;
|
|
489
490
|
let firstAnswer = true;
|
|
490
491
|
while (!current.result.done) {
|
|
491
492
|
const next = pullSolution(solver, solutions, reader);
|
|
492
493
|
output.write(current.output);
|
|
493
494
|
output.write(`${firstAnswer ? ' ' : ''}${formatAnswer(engine, state, variables, current.result.value)}`);
|
|
495
|
+
answersShown++;
|
|
494
496
|
firstAnswer = false;
|
|
495
497
|
if (!next.error && next.result.done) {
|
|
496
498
|
output.write('.\n');
|
|
@@ -516,7 +518,12 @@ async function solveQuery(engine, state, goal, reader, output) {
|
|
|
516
518
|
break;
|
|
517
519
|
}
|
|
518
520
|
if (control === 'f') {
|
|
519
|
-
|
|
521
|
+
// `f` groups leaf answers in blocks of five, rather than merely
|
|
522
|
+
// adding five more answers after whatever the user has already
|
|
523
|
+
// inspected. Stop for control again at the next 5-answer boundary.
|
|
524
|
+
const remainder = answersShown % 5;
|
|
525
|
+
const answersToBoundary = remainder === 0 ? 5 : 5 - remainder;
|
|
526
|
+
automatic = answersToBoundary - 1;
|
|
520
527
|
break;
|
|
521
528
|
}
|
|
522
529
|
if (control === 'w' || control === 'p') {
|
package/src/solver.js
CHANGED
|
@@ -490,10 +490,11 @@ function normalizeHostResourceError(error) {
|
|
|
490
490
|
const message = String(error?.message ?? '');
|
|
491
491
|
// V8 reports exhausted Map/Set capacity as a host RangeError. ISO 7.12.2 h
|
|
492
492
|
// requires processor resource exhaustion to surface as resource_error/1,
|
|
493
|
-
// with the resource atom implementation dependent.
|
|
494
|
-
//
|
|
493
|
+
// with the resource atom implementation dependent. A finite host capacity
|
|
494
|
+
// ceiling is reported as `memory`; reserve `finite_memory` for the separate
|
|
495
|
+
// convention where no finite amount of memory can complete the computation.
|
|
495
496
|
if (/^(?:Map|Set) maximum size exceeded$/.test(message)) {
|
|
496
|
-
return new PrologError('resource_error(
|
|
497
|
+
return new PrologError('resource_error(memory)');
|
|
497
498
|
}
|
|
498
499
|
return error;
|
|
499
500
|
}
|
package/test/run-regression.mjs
CHANGED
|
@@ -752,6 +752,48 @@ c4 ?- call((!;1)).
|
|
|
752
752
|
assertEqual(result.stderr, '', 'stderr');
|
|
753
753
|
},
|
|
754
754
|
},
|
|
755
|
+
{
|
|
756
|
+
name: 'REPL f stops at five-answer boundaries instead of adding five answers',
|
|
757
|
+
run: () => {
|
|
758
|
+
const result = runCli([], {
|
|
759
|
+
input:
|
|
760
|
+
'use_module(library(prologue), [between/3]).\n' +
|
|
761
|
+
'between(0,11,I).\nf\n\n' +
|
|
762
|
+
'between(0,11,J).\n;\n;\nf\n\n' +
|
|
763
|
+
'between(0,11,K).\nf\nf\n\n' +
|
|
764
|
+
'halt.\n',
|
|
765
|
+
});
|
|
766
|
+
assertEqual(result.status, 0, 'exit status');
|
|
767
|
+
assertEqual(result.stdout,
|
|
768
|
+
'?- true.\n' +
|
|
769
|
+
'?- I = 0\n' +
|
|
770
|
+
'; I = 1\n' +
|
|
771
|
+
'; I = 2\n' +
|
|
772
|
+
'; I = 3\n' +
|
|
773
|
+
'; I = 4\n' +
|
|
774
|
+
'; ... .\n' +
|
|
775
|
+
'?- J = 0\n' +
|
|
776
|
+
'; J = 1\n' +
|
|
777
|
+
'; J = 2\n' +
|
|
778
|
+
'; J = 3\n' +
|
|
779
|
+
'; J = 4\n' +
|
|
780
|
+
'; ... .\n' +
|
|
781
|
+
'?- K = 0\n' +
|
|
782
|
+
'; K = 1\n' +
|
|
783
|
+
'; K = 2\n' +
|
|
784
|
+
'; K = 3\n' +
|
|
785
|
+
'; K = 4\n' +
|
|
786
|
+
'; K = 5\n' +
|
|
787
|
+
'; K = 6\n' +
|
|
788
|
+
'; K = 7\n' +
|
|
789
|
+
'; K = 8\n' +
|
|
790
|
+
'; K = 9\n' +
|
|
791
|
+
'; ... .\n' +
|
|
792
|
+
'?- ',
|
|
793
|
+
'stdout');
|
|
794
|
+
assertEqual(result.stderr, '', 'stderr');
|
|
795
|
+
},
|
|
796
|
+
},
|
|
755
797
|
{
|
|
756
798
|
name: 'REPL parenthesizes operator-valued answer substitutions',
|
|
757
799
|
run: () => {
|
|
@@ -2221,22 +2263,27 @@ open(X) :- candidate(X), \\+ closed(X).
|
|
|
2221
2263
|
},
|
|
2222
2264
|
},
|
|
2223
2265
|
{
|
|
2224
|
-
name: 'host Map capacity errors become
|
|
2266
|
+
name: 'host Map/Set capacity errors become resource_error(memory)',
|
|
2225
2267
|
run: () => {
|
|
2226
|
-
const
|
|
2227
|
-
|
|
2228
|
-
|
|
2229
|
-
|
|
2230
|
-
|
|
2231
|
-
|
|
2232
|
-
|
|
2233
|
-
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
caught =
|
|
2268
|
+
for (const [predicate, message] of [
|
|
2269
|
+
['exhaust_map', 'Map maximum size exceeded'],
|
|
2270
|
+
['exhaust_set', 'Set maximum size exceeded'],
|
|
2271
|
+
]) {
|
|
2272
|
+
const registry = new BuiltinRegistry();
|
|
2273
|
+
registry.add(predicate, 0, function* () {
|
|
2274
|
+
throw new RangeError(message);
|
|
2275
|
+
});
|
|
2276
|
+
const solver = new Solver(Program.parse(''), { registry });
|
|
2277
|
+
const goal = parseGoalText(predicate);
|
|
2278
|
+
let caught = null;
|
|
2279
|
+
try {
|
|
2280
|
+
[...solver.solve([goal], new Env(), 0)];
|
|
2281
|
+
} catch (error) {
|
|
2282
|
+
caught = error;
|
|
2283
|
+
}
|
|
2284
|
+
assertEqual(caught?.name, 'PrologError', `${predicate} normalized error type`);
|
|
2285
|
+
assertEqual(caught?.formal, 'resource_error(memory)', `${predicate} normalized resource error`);
|
|
2237
2286
|
}
|
|
2238
|
-
assertEqual(caught?.name, 'PrologError', 'normalized error type');
|
|
2239
|
-
assertEqual(caught?.formal, 'resource_error(finite_memory)', 'normalized resource error');
|
|
2240
2287
|
},
|
|
2241
2288
|
},
|
|
2242
2289
|
{
|
package/the-art-of-eyeprolog.md
CHANGED
|
@@ -1823,8 +1823,12 @@ sorted-list operation. No process-global variable registry or creation ordinal
|
|
|
1823
1823
|
is retained or exposed through later comparisons.
|
|
1824
1824
|
|
|
1825
1825
|
Host capacity failures that V8 reports as `Map maximum size exceeded` or `Set`
|
|
1826
|
-
`maximum size exceeded` are normalized at the solver boundary to
|
|
1827
|
-
`resource_error(
|
|
1826
|
+
`maximum size exceeded` are normalized at the solver boundary to
|
|
1827
|
+
`resource_error(memory)` instead of leaking a JavaScript `RangeError`. ISO
|
|
1828
|
+
13211-1 leaves the resource atom implementation dependent. EyeProlog uses
|
|
1829
|
+
`memory` for a finite host allocation/capacity ceiling and reserves the
|
|
1830
|
+
`finite_memory` spelling for the distinct convention where no finite amount of
|
|
1831
|
+
memory could complete the computation.
|
|
1828
1832
|
|
|
1829
1833
|
### Implementation boundary
|
|
1830
1834
|
|
|
@@ -6260,8 +6264,10 @@ may span lines and end with a full stop, as in Scryer Prolog:
|
|
|
6260
6264
|
|
|
6261
6265
|
When another answer exists in an interactive terminal, press `;`, Space, or
|
|
6262
6266
|
`n` to ask for it immediately; no Return is needed. Return or `.` stops
|
|
6263
|
-
enumeration, `a` enumerates all remaining answers, `f`
|
|
6264
|
-
five
|
|
6267
|
+
enumeration, `a` enumerates all remaining answers, and `f` advances to the
|
|
6268
|
+
next five-answer boundary (5, 10, 15, ... displayed leaf answers), regardless
|
|
6269
|
+
of how many answers were stepped through individually beforehand. `h` displays
|
|
6270
|
+
the answer-control help. While a query is actively
|
|
6265
6271
|
computing, EyeProlog releases readline's terminal signal handling: `Ctrl-C`
|
|
6266
6272
|
therefore terminates the current EyeProlog process immediately, and on POSIX
|
|
6267
6273
|
terminals `Ctrl-Z` suspends it in the usual shell-managed way. This remains a
|