eyeprolog 1.3.82 → 1.3.84
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 +12 -22
- package/test/run-regression.mjs +24 -9
- package/the-art-of-eyeprolog.md +4 -2
package/package.json
CHANGED
package/src/repl.js
CHANGED
|
@@ -720,6 +720,15 @@ function formatAnswer(engine, state, variables, env) {
|
|
|
720
720
|
const valueMaxPriority = equality == null
|
|
721
721
|
? 699
|
|
722
722
|
: equality.specifier === 'xfy' ? equality.priority : equality.priority - 1;
|
|
723
|
+
const answerWriteOptions = {
|
|
724
|
+
quoted: true,
|
|
725
|
+
minimalOperatorSpacing: true,
|
|
726
|
+
operators,
|
|
727
|
+
variableNames: names,
|
|
728
|
+
operatorAtomsAsArgs: true,
|
|
729
|
+
dottedGraphicAtoms: true,
|
|
730
|
+
doubleQuotes: state.solver.prologFlags.get('double_quotes')?.value?.name ?? 'chars',
|
|
731
|
+
};
|
|
723
732
|
let generated = 0;
|
|
724
733
|
|
|
725
734
|
// Meta-predicate wrappers can make a query variable alias an internal fresh
|
|
@@ -734,30 +743,18 @@ function formatAnswer(engine, state, variables, env) {
|
|
|
734
743
|
if (value.type === 'var' &&
|
|
735
744
|
(value.name === variable.name || !queryVariableNames.has(value.name))) continue;
|
|
736
745
|
bindings.push(`${variable.name} = ${engine.formatTermForWrite(value, env, {
|
|
737
|
-
|
|
738
|
-
operators,
|
|
739
|
-
variableNames: names,
|
|
746
|
+
...answerWriteOptions,
|
|
740
747
|
maxPriority: valueMaxPriority,
|
|
741
748
|
// A binding value is the right-hand `arg` of =/2. ISO 6.3.3.1 permits
|
|
742
749
|
// current operator atoms in argument and list-element positions without
|
|
743
750
|
// quotes, just as writeq/1 already prints them.
|
|
744
|
-
operatorAtomsAsArgs: true,
|
|
745
|
-
dottedGraphicAtoms: true,
|
|
746
|
-
doubleQuotes: state.solver.prologFlags.get('double_quotes')?.value?.name ?? 'chars',
|
|
747
751
|
})}`);
|
|
748
752
|
}
|
|
749
753
|
for (const constraint of env.variableConstraints?.() ?? []) {
|
|
750
754
|
const residual = constraint.residualGoal?.(env);
|
|
751
755
|
if (residual == null) continue;
|
|
752
756
|
collectUnboundVariables(engine, residual, env, names, () => `_${letterName(generated++)}`);
|
|
753
|
-
bindings.push(engine.formatTermForWrite(residual, env,
|
|
754
|
-
quoted: true,
|
|
755
|
-
operators,
|
|
756
|
-
variableNames: names,
|
|
757
|
-
operatorAtomsAsArgs: true,
|
|
758
|
-
dottedGraphicAtoms: true,
|
|
759
|
-
doubleQuotes: state.solver.prologFlags.get('double_quotes')?.value?.name ?? 'chars',
|
|
760
|
-
}));
|
|
757
|
+
bindings.push(engine.formatTermForWrite(residual, env, answerWriteOptions));
|
|
761
758
|
}
|
|
762
759
|
const projectedAttributeRoots = new Set();
|
|
763
760
|
for (const variable of variables) {
|
|
@@ -767,14 +764,7 @@ function formatAnswer(engine, state, variables, env) {
|
|
|
767
764
|
names.set(root.name, variable.name);
|
|
768
765
|
for (const residual of state.solver.attributeResidualGoals(root, env)) {
|
|
769
766
|
collectUnboundVariables(engine, residual, env, names, () => `_${letterName(generated++)}`);
|
|
770
|
-
bindings.push(engine.formatTermForWrite(residual, env,
|
|
771
|
-
quoted: true,
|
|
772
|
-
operators,
|
|
773
|
-
variableNames: names,
|
|
774
|
-
operatorAtomsAsArgs: true,
|
|
775
|
-
dottedGraphicAtoms: true,
|
|
776
|
-
doubleQuotes: state.solver.prologFlags.get('double_quotes')?.value?.name ?? 'chars',
|
|
777
|
-
}));
|
|
767
|
+
bindings.push(engine.formatTermForWrite(residual, env, answerWriteOptions));
|
|
778
768
|
}
|
|
779
769
|
}
|
|
780
770
|
return bindings.length === 0 ? 'true' : bindings.join(', ');
|
package/test/run-regression.mjs
CHANGED
|
@@ -186,7 +186,7 @@ function regressionCases() {
|
|
|
186
186
|
});
|
|
187
187
|
assertEqual(residuals.status, 0, 'dif/2 residual display status');
|
|
188
188
|
assertEqual(residuals.stdout,
|
|
189
|
-
'?- C = z, D = z, dif(A
|
|
189
|
+
'?- C = z, D = z, dif(A-z, B-z).\n' +
|
|
190
190
|
'?- A = [[]], B = [], dif([[]], [C]).\n' +
|
|
191
191
|
'?- X = Y.\n' +
|
|
192
192
|
'?- ',
|
|
@@ -1449,7 +1449,7 @@ c4 ?- call((!;1)).
|
|
|
1449
1449
|
input: 'read(T).\n!,*.\n.\nread(T).\na\n.\nhalt.\n',
|
|
1450
1450
|
});
|
|
1451
1451
|
assertEqual(continuedGraphic.status, 0, 'continued graphic operator REPL status');
|
|
1452
|
-
assertIncludes(continuedGraphic.stdout, 'T = (
|
|
1452
|
+
assertIncludes(continuedGraphic.stdout, 'T = (!,*.).', 'continued graphic operator answer');
|
|
1453
1453
|
assertIncludes(continuedGraphic.stdout, 'T = a.', 'read after continued graphic operator');
|
|
1454
1454
|
assertNotIncludes(continuedGraphic.stdout, 'syntax_error', 'continued graphic operator syntax');
|
|
1455
1455
|
assertEqual(continuedGraphic.stderr, '', 'continued graphic operator REPL stderr');
|
|
@@ -2456,10 +2456,10 @@ c4 ?- call((!;1)).
|
|
|
2456
2456
|
});
|
|
2457
2457
|
assertEqual(result.status, 0, 'exit status');
|
|
2458
2458
|
assertEqual(result.stdout,
|
|
2459
|
-
'?- T = (a
|
|
2460
|
-
'?- U = (a,
|
|
2461
|
-
'?- V = (a
|
|
2462
|
-
'?- W = a
|
|
2459
|
+
'?- T = (a=b).\n' +
|
|
2460
|
+
'?- U = (a,b).\n' +
|
|
2461
|
+
'?- V = (a;b).\n' +
|
|
2462
|
+
'?- W = a+b.\n' +
|
|
2463
2463
|
'?- ',
|
|
2464
2464
|
'stdout');
|
|
2465
2465
|
assertEqual(result.stderr, '', 'stderr');
|
|
@@ -2665,9 +2665,9 @@ c4 ?- call((!;1)).
|
|
|
2665
2665
|
});
|
|
2666
2666
|
assertEqual(result.status, 0, 'exit status');
|
|
2667
2667
|
assertEqual(result.stdout,
|
|
2668
|
-
'?- |: X = (_A
|
|
2669
|
-
'?- |: X = (_A
|
|
2670
|
-
"?- |: X = (_A
|
|
2668
|
+
'?- |: X = (_A=a).\n' +
|
|
2669
|
+
'?- |: X = (_A=a).\n' +
|
|
2670
|
+
"?- |: X = (_A=pair(_A, _B)), Vs = [_A, _B], Names = ['X'=_A, 'Y'=_B], Singletons = ['Y'=_B].\n" +
|
|
2671
2671
|
'?- ',
|
|
2672
2672
|
'stdout');
|
|
2673
2673
|
assertEqual(result.stderr, '', 'stderr');
|
|
@@ -3881,6 +3881,21 @@ child.stdin.write(\`consult(${consultedAtom}).\\n\`);
|
|
|
3881
3881
|
assertEqual(run(source, { goal: 'emit' }).stdout, '1+2|a+ -b|a+b*c\nemit.\n', 'minimal operator spacing');
|
|
3882
3882
|
},
|
|
3883
3883
|
},
|
|
3884
|
+
{
|
|
3885
|
+
name: 'REPL answers use only lexically required operator spacing (issue #76)',
|
|
3886
|
+
run: () => {
|
|
3887
|
+
const result = runCli([], {
|
|
3888
|
+
input: 'X=1*1.\nX=a + -b.\nhalt.\n',
|
|
3889
|
+
});
|
|
3890
|
+
assertEqual(result.status, 0, 'exit status');
|
|
3891
|
+
assertEqual(result.stdout,
|
|
3892
|
+
'?- X = 1*1.\n' +
|
|
3893
|
+
'?- X = a+ -b.\n' +
|
|
3894
|
+
'?- ',
|
|
3895
|
+
'minimal operator layout preserves required token separation');
|
|
3896
|
+
assertEqual(result.stderr, '', 'stderr');
|
|
3897
|
+
},
|
|
3898
|
+
},
|
|
3884
3899
|
{
|
|
3885
3900
|
name: 'write predicates and write_term options select distinct formats',
|
|
3886
3901
|
run: () => {
|
package/the-art-of-eyeprolog.md
CHANGED
|
@@ -5427,7 +5427,9 @@ still retained where adjacent graphic tokens would otherwise merge, as in
|
|
|
5427
5427
|
`variable_names/1`. Normal mode additionally accepts the EyeProlog extension
|
|
5428
5428
|
`double_quotes(true|false)`: `true` lets eligible character/code lists use the
|
|
5429
5429
|
current `double_quotes` representation, while strict ISO mode rejects this
|
|
5430
|
-
non-standard write option.
|
|
5430
|
+
non-standard write option. The REPL follows the same minimal-separator rule as
|
|
5431
|
+
term output, so `X=1*1` is displayed as `X = 1*1`, while a separator is retained
|
|
5432
|
+
in `X = a+ -b` because the adjacent graphic tokens would otherwise merge.
|
|
5431
5433
|
|
|
5432
5434
|
Character operations are `get_char`, `peek_char`, `put_char`, `get_code`,
|
|
5433
5435
|
`peek_code`, and `put_code`; byte streams use the corresponding byte
|
|
@@ -6120,7 +6122,7 @@ the beginning. A peek does not mark the stream as past-end.
|
|
|
6120
6122
|
| `write(+Term)`, `write(+Stream,+Term)` | Writes readable operator notation without quoting atoms merely because quoting would be required for reparsing. Number variables are enabled. |
|
|
6121
6123
|
| `writeq(+Term)`, `writeq(+Stream,+Term)` | Like `write`, but quotes atoms when required for unambiguous input syntax. |
|
|
6122
6124
|
| `write_canonical(+Term)`, `write_canonical(+Stream,+Term)` | Writes quoted canonical functor notation while ignoring operators and without interpreting *$VAR/1*. |
|
|
6123
|
-
| `write_term(+Term,+Options)`, `write_term(+Stream,+Term,+Options)` | Writes with *quoted(true or false)*, *ignore_ops(true or false)*, *numbervars(true or false)*, and *variable_names([Name=Variable,...])*. |
|
|
6125
|
+
| `write_term(+Term,+Options)`, `write_term(+Stream,+Term,+Options)` | Writes with *quoted(true or false)*, *ignore_ops(true or false)*, *numbervars(true or false)*, and *variable_names([Name=Variable,...])*. Normal mode also supports *double_quotes(true or false)*. |
|
|
6124
6126
|
|
|
6125
6127
|
Term input uses the program's current operator table and the same ISO quoted-character
|
|
6126
6128
|
syntax as source text, including backslash-terminated octal and hexadecimal
|