eyeprolog 1.1.26 → 1.1.27

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 CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.1.26",
6
+ "version": "1.1.27",
7
7
  "description": "EyeProlog turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
package/src/repl.js CHANGED
@@ -370,6 +370,17 @@ function formatAnswer(engine, state, variables, env) {
370
370
  const bindings = [];
371
371
  const queryVariableNames = new Set(variables.map((variable) => variable.name));
372
372
  const names = new Map(variables.map((variable) => [variable.name, variable.name]));
373
+ const operators = [...state.program.operators.values()];
374
+ // Answer substitutions are displayed as `Variable = Value`. Format Value
375
+ // in the right-operand context of the active infix `=/2` definition so an
376
+ // operator term such as `a = b` is parenthesized rather than producing the
377
+ // invalid `T = a = b`. ISO does not standardize a top level, but the term
378
+ // syntax used by the display must still respect the current operator table.
379
+ const equality = operators.find((definition) =>
380
+ definition.name === '=' && ['xfx', 'xfy', 'yfx'].includes(definition.specifier));
381
+ const valueMaxPriority = equality == null
382
+ ? 699
383
+ : equality.specifier === 'xfy' ? equality.priority : equality.priority - 1;
373
384
  let generated = 0;
374
385
 
375
386
  for (const variable of variables) collectUnboundVariables(engine, variable, env, names, () => `_${letterName(generated++)}`);
@@ -379,8 +390,9 @@ function formatAnswer(engine, state, variables, env) {
379
390
  (value.name === variable.name || !queryVariableNames.has(value.name))) continue;
380
391
  bindings.push(`${variable.name} = ${engine.formatTermForWrite(value, env, {
381
392
  quoted: true,
382
- operators: [...state.program.operators.values()],
393
+ operators,
383
394
  variableNames: names,
395
+ maxPriority: valueMaxPriority,
384
396
  })}`);
385
397
  }
386
398
  return bindings.length === 0 ? 'true' : bindings.join(', ');
package/src/write.js CHANGED
@@ -208,5 +208,8 @@ export function formatTermForWrite(term, env = new Env(), options = {}) {
208
208
  compact: options.compact === true,
209
209
  operatorAtomsAsArgs: options.operatorAtomsAsArgs === true,
210
210
  };
211
- return format(term, env, normalized, operatorTable(options.operators), 1200);
211
+ const maxPriority = Number.isInteger(options.maxPriority)
212
+ ? Math.max(0, Math.min(1200, options.maxPriority))
213
+ : 1200;
214
+ return format(term, env, normalized, operatorTable(options.operators), maxPriority);
212
215
  }
@@ -585,6 +585,23 @@ c4 ?- call((!;1)).
585
585
  assertEqual(result.stderr, '', 'stderr');
586
586
  },
587
587
  },
588
+ {
589
+ name: 'REPL parenthesizes operator-valued answer substitutions',
590
+ run: () => {
591
+ const result = runCli([], {
592
+ input: 'T = (a=b).\nU = (a,b).\nV = (a;b).\nW = (a+b).\nhalt.\n',
593
+ });
594
+ assertEqual(result.status, 0, 'exit status');
595
+ assertEqual(result.stdout,
596
+ '?- T = (a = b).\n' +
597
+ '?- U = (a, b).\n' +
598
+ '?- V = (a ; b).\n' +
599
+ '?- W = a + b.\n' +
600
+ '?- ',
601
+ 'stdout');
602
+ assertEqual(result.stderr, '', 'stderr');
603
+ },
604
+ },
588
605
  {
589
606
  name: 'REPL accepts multiline period-terminated queries',
590
607
  run: () => {
@@ -6191,7 +6191,11 @@ When another answer exists in an interactive terminal, press `;`, Space, or
6191
6191
  enumeration, `a` enumerates all remaining answers, `f` enumerates the next
6192
6192
  five, and `h` displays the answer-control help. A
6193
6193
  period-terminated query with no solutions prints `false.`; a solution without
6194
- visible variable bindings prints `true.`. Use `[file].` or `['file.pl'].` to
6194
+ visible variable bindings prints `true.`. Answer substitutions are rendered as
6195
+ valid Prolog syntax under the current operator table: when a bound value would
6196
+ not be a valid right operand of the displayed `=/2`, EyeProlog adds parentheses,
6197
+ for example `T = (a = b).` rather than the invalid `T = a = b.`. Use `[file].`
6198
+ or `['file.pl'].` to
6195
6199
  consult local source, and `halt.` or `halt(Status).` to leave the top level.
6196
6200
  Up and Down recall queries from the current session. Explicit `eyeprolog -h`
6197
6201
  displays command-line help.