eyeprolog 1.5.87 → 1.5.88
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/quads.js +36 -19
- package/test/regression/cases-regression.mjs +8 -1
package/package.json
CHANGED
package/src/quads.js
CHANGED
|
@@ -994,24 +994,39 @@ const FAILURE_LABELS = {
|
|
|
994
994
|
|
|
995
995
|
// With several `|`-separated alternatives -- the norm for `sto`-annotated
|
|
996
996
|
// queries -- a bare offending sub-term like `_B = [E|_B]` gives no sense of
|
|
997
|
-
// which alternative it came from
|
|
998
|
-
//
|
|
999
|
-
//
|
|
1000
|
-
//
|
|
1001
|
-
//
|
|
1002
|
-
//
|
|
1003
|
-
//
|
|
997
|
+
// which alternative it came from. Show that whole alternative in place, laid
|
|
998
|
+
// out the same way the answer-description syntax itself lays out alternatives
|
|
999
|
+
// and leaves (a leading `|` per alternative after the first, a leading `;`
|
|
1000
|
+
// per leaf after an alternative's first), and stand in for sibling
|
|
1001
|
+
// alternatives with a bare `...` rather than reproducing them (they were not
|
|
1002
|
+
// the problem) or dropping them silently (a reader can no longer tell how
|
|
1003
|
+
// many alternatives, or which one, this was) -- see issue #112's follow-up
|
|
1004
|
+
// (https://github.com/eyereasoner/eyeprolog/issues/112#issuecomment-5645403025).
|
|
1005
|
+
// Comments are not retained past parsing, so unlike a hand-written answer
|
|
1006
|
+
// description this reconstruction never has any to show. Returns null when
|
|
1007
|
+
// the description has only one alternative to begin with: there is then
|
|
1008
|
+
// nothing to elide, and the existing plain rendering already shows the whole
|
|
1009
|
+
// thing.
|
|
1004
1010
|
function formatAlternativeContext(program, description, alternative) {
|
|
1005
1011
|
const parts = splitOperator(description, '|');
|
|
1006
1012
|
if (parts.length <= 1 || !parts.includes(alternative)) return null;
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1013
|
+
const lines = [];
|
|
1014
|
+
parts.forEach((part, index) => {
|
|
1015
|
+
const prefix = index === 0 ? ' ' : '| ';
|
|
1016
|
+
if (part !== alternative) {
|
|
1017
|
+
lines.push(`${prefix}...`);
|
|
1018
|
+
return;
|
|
1019
|
+
}
|
|
1020
|
+
splitOperator(part, ';').forEach((leaf, leafIndex) => {
|
|
1021
|
+
lines.push(`${leafIndex === 0 ? prefix : '; '}${formatQuadTerm(program, leaf)}`);
|
|
1022
|
+
});
|
|
1023
|
+
});
|
|
1024
|
+
// A trailing `...` glued straight to a full stop reads as four dots; the
|
|
1025
|
+
// answer-description syntax itself always writes a space before the period
|
|
1026
|
+
// in that position (compare `..., ad_infinitum` with `... .`), so match it.
|
|
1027
|
+
const last = lines.length - 1;
|
|
1028
|
+
lines[last] = lines[last].endsWith('...') ? `${lines[last]} .` : `${lines[last]}.`;
|
|
1029
|
+
return lines.join('\n');
|
|
1015
1030
|
}
|
|
1016
1031
|
|
|
1017
1032
|
function formatFailure(program, quad, result, description = quad.answers[0]) {
|
|
@@ -1029,12 +1044,14 @@ function formatFailure(program, quad, result, description = quad.answers[0]) {
|
|
|
1029
1044
|
const detail = result.kind === 'undecided'
|
|
1030
1045
|
? ` undecided: ${result.reason}.\n`
|
|
1031
1046
|
// When the offending sub-term already *is* the whole alternative (an
|
|
1032
|
-
// `expected:` line would just repeat the context
|
|
1033
|
-
// alone is the full, non-redundant report.
|
|
1047
|
+
// `expected:` line would just repeat the context lines), the context
|
|
1048
|
+
// alone is the full, non-redundant report. formatAlternativeContext
|
|
1049
|
+
// already lays out and terminates its own lines, so it needs no further
|
|
1050
|
+
// wrapping here (unlike the plain single-line `expected:` case below).
|
|
1034
1051
|
: context != null && expected === result.alternative
|
|
1035
|
-
?
|
|
1052
|
+
? `${context}\n`
|
|
1036
1053
|
: context != null
|
|
1037
|
-
?
|
|
1054
|
+
? `${context}\n expected: ${formatQuadTerm(program, expected)}.\n`
|
|
1038
1055
|
: ` expected: ${formatQuadTerm(program, expected)}.\n`;
|
|
1039
1056
|
return `quads: ${reason} ${label}${source.filename}:${line}\n` +
|
|
1040
1057
|
` ?- ${formatQuadTerm(program, quad.query)}.\n` + detail;
|
|
@@ -2584,8 +2584,15 @@ c4 ?- call((!;1)).
|
|
|
2584
2584
|
const result = publicApi.runQuads(Program.parseSources([{ text: source, filename: 'select-quad.pl' }]));
|
|
2585
2585
|
assertEqual(result.total, 1, 'quad total');
|
|
2586
2586
|
assertEqual(result.failed, 1, 'quad failed');
|
|
2587
|
+
// Laid out the same way the answer-description syntax itself lays
|
|
2588
|
+
// out alternatives (a leading `|`) and leaves (a leading `;`), per
|
|
2589
|
+
// Ulrich's own proposed shape in that follow-up comment.
|
|
2587
2590
|
assertIncludes(result.stdout,
|
|
2588
|
-
'
|
|
2591
|
+
' ...\n' +
|
|
2592
|
+
'| sto, Xs = [E | Xs]\n' +
|
|
2593
|
+
'; Xs = [_A | _B], Ys = [E | Ys]\n' +
|
|
2594
|
+
'; ..., ad_infinitum\n' +
|
|
2595
|
+
'| ... .\n',
|
|
2589
2596
|
'sibling-elided alternative context');
|
|
2590
2597
|
assertIncludes(result.stdout, ' expected: Ys = [E | Ys].\n', 'still-precise offending sub-term');
|
|
2591
2598
|
},
|