eyeprolog 1.2.12 → 1.2.13
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/parser.js +13 -5
- package/test/run-regression.mjs +22 -3
- package/the-art-of-eyeprolog.md +11 -7
package/package.json
CHANGED
package/src/parser.js
CHANGED
|
@@ -746,11 +746,11 @@ class Parser {
|
|
|
746
746
|
const accept = emit ?? ((clause) => clauses.push(clause));
|
|
747
747
|
while (this.token.type !== TOK.EOF) {
|
|
748
748
|
const line = this.token.line;
|
|
749
|
-
//
|
|
750
|
-
//
|
|
751
|
-
//
|
|
752
|
-
//
|
|
753
|
-
//
|
|
749
|
+
// Prefix operator notation needs one program-level distinction so
|
|
750
|
+
// a comma in `?- A, B.` remains inside the query rather than outside the
|
|
751
|
+
// prefix term. Ordinary functional notation is parsed as a term and then
|
|
752
|
+
// recognized structurally by parseQuadTerm; further equivalent spellings
|
|
753
|
+
// are recognized after the general head parser below.
|
|
754
754
|
if (this.operatorTokenName() === '?-' && !this.strictIso) {
|
|
755
755
|
if (this.peek() === '(') {
|
|
756
756
|
const quadTerm = this.parseTerm(0, true);
|
|
@@ -818,6 +818,14 @@ class Parser {
|
|
|
818
818
|
head = items.pop();
|
|
819
819
|
while (items.length > 0) head = compound(',', [items.pop(), head]);
|
|
820
820
|
}
|
|
821
|
+
// Parentheses and other ordinary term syntax may hide the surface ?-
|
|
822
|
+
// token from the program-level dispatch above. Once the complete head
|
|
823
|
+
// term has been parsed, recognize the same ?-/1 or ?-/2 structure here.
|
|
824
|
+
// Requiring the following dot prevents an ordinary rule whose head just
|
|
825
|
+
// happens to be ?-/1 or ?-/2 from being consumed as a quad mid-clause.
|
|
826
|
+
if (!this.strictIso && this.token.type === TOK.DOT && this.parseQuadTerm(head, line, accept)) {
|
|
827
|
+
continue;
|
|
828
|
+
}
|
|
821
829
|
if (this.operatorTokenName() === '?-') {
|
|
822
830
|
if (this.strictIso) {
|
|
823
831
|
// There is no predefined infix ?-/2 in strict core mode. If a
|
package/test/run-regression.mjs
CHANGED
|
@@ -222,7 +222,7 @@ why(
|
|
|
222
222
|
},
|
|
223
223
|
},
|
|
224
224
|
{
|
|
225
|
-
name: 'quad parser treats
|
|
225
|
+
name: 'quad parser treats regular term spellings of ?- equivalently',
|
|
226
226
|
run: () => {
|
|
227
227
|
const labelled = Program.parse(
|
|
228
228
|
`0,passes
|
|
@@ -253,9 +253,28 @@ why(
|
|
|
253
253
|
const functionalReport = publicApi.runQuads(functional);
|
|
254
254
|
assertEqual(functionalReport.stdout, 'quads: 1 run, 1 passed, 0 failed.\n', 'functional quad report');
|
|
255
255
|
|
|
256
|
-
|
|
256
|
+
// Issue #11 is about ordinary term syntax, not one privileged
|
|
257
|
+
// canonical spelling. Parentheses, quoted functor syntax, and mixed
|
|
258
|
+
// operator/functional notation must all denote the same ?-/2 term and
|
|
259
|
+
// therefore the same quad in the normal EyeProlog profile.
|
|
260
|
+
for (const [name, source] of [
|
|
261
|
+
['mixed', `?-((0,passes), X = 1).\n X = 1.\n`],
|
|
262
|
+
['parenthesized', `(?-(','(0,passes),=(X,1))).\n X = 1.\n`],
|
|
263
|
+
['parenthesized mixed', `(?-((0,passes), X = 1)).\n X = 1.\n`],
|
|
264
|
+
['quoted functor', `'?-'(','(0,passes),=(X,1)).\n X = 1.\n`],
|
|
265
|
+
['quoted parenthesized', `('?-'(','(0,passes),=(X,1))).\n X = 1.\n`],
|
|
266
|
+
]) {
|
|
267
|
+
const regular = Program.parse(source);
|
|
268
|
+
assertEqual(regular.quads.length, 1, `${name} quad count`);
|
|
269
|
+
assertEqual(regular.clauses.length, 0, `${name} quad clause count`);
|
|
270
|
+
assertEqual(termToString(regular.quads[0].id), termToString(labelled.quads[0].id), `${name} label`);
|
|
271
|
+
assertEqual(termToString(regular.quads[0].query), termToString(labelled.quads[0].query), `${name} query`);
|
|
272
|
+
assertEqual(publicApi.runQuads(regular).stdout, 'quads: 1 run, 1 passed, 0 failed.\n', `${name} report`);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
const strict = Program.parse(`(?-(','(0,passes),=(X,1))).\n`, { isoStrict: true });
|
|
257
276
|
assertEqual(strict.quads.length, 0, 'strict mode has no quads');
|
|
258
|
-
assertEqual(strict.clauses.length, 1, 'strict
|
|
277
|
+
assertEqual(strict.clauses.length, 1, 'strict ?-/2 remains an ordinary term');
|
|
259
278
|
},
|
|
260
279
|
},
|
|
261
280
|
{
|
package/the-art-of-eyeprolog.md
CHANGED
|
@@ -5156,10 +5156,12 @@ an optional label before the query marker (`Label ?- Query.`), so while quad
|
|
|
5156
5156
|
syntax is supported it additionally exposes `?-` at priority 1200 with
|
|
5157
5157
|
specifier `xfx` as an implementation-specific operator. Consequently
|
|
5158
5158
|
`current_op(Priority, Specifier, ?-)` enumerates both definitions. At top level in the normal EyeProlog profile, the quad marker is recognized
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
|
|
5162
|
-
|
|
5159
|
+
from the parsed `?-/1` or `?-/2` term rather than from one privileged surface
|
|
5160
|
+
spelling. Thus `Label ?- Query.`, `?-(Label, Query).`, mixed forms such as
|
|
5161
|
+
`?-((Label), Query).`, quoted-functor notation, and a parenthesized whole
|
|
5162
|
+
`(?-(Label, Query)).` denote the same quad when followed by indented answer
|
|
5163
|
+
descriptions. In `--iso-strict` mode this quad interpretation is disabled, and
|
|
5164
|
+
`?-/2` remains ordinary Prolog term syntax.
|
|
5163
5165
|
|
|
5164
5166
|
Run [`iso-dynamic-database.pl`](https://github.com/eyereasoner/eyeprolog/blob/main/examples/iso-dynamic-database.pl)
|
|
5165
5167
|
for an explicitly stateful queue and
|
|
@@ -6432,9 +6434,11 @@ Trealla and the ISO Prolog working examples. Because answer descriptions are
|
|
|
6432
6434
|
layout-sensitive, indent every description while keeping ordinary clause heads
|
|
6433
6435
|
and the next quad query at the left margin. A quad label may contain any number
|
|
6434
6436
|
of comma-separated metadata fields, including across layout before `?-`; for
|
|
6435
|
-
example `9, "case", passes ?- Goal.` is one labelled query.
|
|
6436
|
-
|
|
6437
|
-
|
|
6437
|
+
example `9, "case", passes ?- Goal.` is one labelled query. Quad recognition
|
|
6438
|
+
is structural after ordinary term parsing: functional, mixed, quoted-functor,
|
|
6439
|
+
and parenthesized spellings of the same `?-/1` or `?-/2` term are semantically
|
|
6440
|
+
equivalent. For example `?-(Label, Query).` and `(?-(Label, Query)).`, followed
|
|
6441
|
+
by the same indented answer descriptions, create the same labelled quad as
|
|
6438
6442
|
`Label ?- Query.`.
|
|
6439
6443
|
|
|
6440
6444
|
Statistics are comparative evidence, not a score in isolation. Preserve the
|