eyeprolog 1.3.46 → 1.3.47

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.3.46",
6
+ "version": "1.3.47",
7
7
  "description": "EyeProlog turns facts and rules into answers and proofs.",
8
8
  "type": "module",
9
9
  "main": "./index.js",
package/src/iso.js CHANGED
@@ -1772,7 +1772,7 @@ function validCharacterCode(value, solver = null) {
1772
1772
  function listToAtomInput(list, env, kind, solver = null) {
1773
1773
  const { items, tail } = listElements(list, env);
1774
1774
  if (tail.type === VAR || items.some((item) => item.type === VAR)) throw new PrologError('instantiation_error');
1775
- if (tail.type !== ATOM || tail.name !== '[]') throw new PrologError('type_error(list)', tail);
1775
+ if (tail.type !== ATOM || tail.name !== '[]') throw new PrologError('type_error(list)', list);
1776
1776
  if (kind === 'chars') {
1777
1777
  const invalid = items.find((item) => !oneChar(item));
1778
1778
  if (invalid) throw new PrologError('type_error(character)', invalid);
@@ -2228,7 +2228,11 @@ function* callBuiltin({ solver, goal, env }) {
2228
2228
  function* callClosureBuiltin({ solver, goal, env }) {
2229
2229
  const closure = callable(goal.args[0], env);
2230
2230
  const existing = closure.type === COMPOUND ? closure.args : [];
2231
- const invoked = compound(closure.name, [...existing, ...goal.args.slice(1)]);
2231
+ const extra = goal.args.slice(1);
2232
+ if (existing.length + extra.length > ISO_MAX_ARITY) {
2233
+ throw new PrologError('representation_error(max_arity)');
2234
+ }
2235
+ const invoked = compound(closure.name, [...existing, ...extra]);
2232
2236
  if (closure.module != null) invoked.module = closure.module;
2233
2237
  const child = solver.cloneForInnerGoal();
2234
2238
  try {
@@ -110,6 +110,15 @@ EyeProlog-only evaluable atom `e`, while the Corrigendum arithmetic additions
110
110
  remain available. These corrections narrow the remaining `audit` rows but do
111
111
  not by themselves close the full shall-by-shall/error-order exit criteria.
112
112
 
113
+ The next Corrigendum 2 pass closes two smaller prescribed-error gaps.
114
+ `call/2..8` now raises `representation_error(max_arity)` when appending its
115
+ extra arguments would make the resulting goal exceed the declared `max_arity`,
116
+ rather than falling through to a procedure-existence error. Reverse
117
+ `atom_chars/2` and `atom_codes/2` now report the complete improper `List`
118
+ argument as the culprit of `type_error(list, List)`, as required by the
119
+ Corrigendum 2 replacement error clauses. Dedicated strict-core regressions pin
120
+ both behaviors.
121
+
113
122
  ## Strict-core boundary
114
123
 
115
124
  `isoStrict: true` is intentionally a **Part 1 + Corrigenda 1-3** mode. It does
@@ -15,8 +15,8 @@ compliance audit and the remaining work before a full conformance claim.
15
15
  | 8.6-8.7 arithmetic predicates | `is/2` and all six arithmetic comparisons | `arithmetic`, comparison cases, isolated evaluation errors |
16
16
  | 8.8-8.10 database and solutions | logical update view, dynamic mutation, all-solutions grouping | `dynamic_database`, `trealla_logical_update_view`, `corrigenda_retractall`, `grouped_solutions_and_clauses`, plus strict clause/database error and all-solutions precedence checks |
17
17
  | 8.11-8.14 streams and term I/O | text/binary streams, properties, units, read/write options and operators | `streams_and_term_io`, `operators`, Corrigendum 3 option cases, stream error cases, strict 8.14.1-8.14.4 option/error-order tests, Corrigendum 3 variable metadata/write naming checks, and issue #65 checks for stream-term/property validation, text-vs-binary permissions, EOF/flush/position, and open/close semantics |
18
- | 8.15 logic and control | negation, once, repeat, `call/2` through `call/8`, `false/0` | `logtalk_once`, `corrigenda_call_closure`, `false_builtin` |
19
- | 8.16 atomic processing | atoms, characters, codes and number conversion with prescribed errors | `atomic_term_processing`, focused forward/reverse cases, parenthesized-number rejection, Logtalk-derived error cases |
18
+ | 8.15 logic and control | negation, once, repeat, `call/2` through `call/8`, `false/0` | `logtalk_once`, `corrigenda_call_closure`, `false_builtin`, plus strict Corrigendum 2 resulting-goal `max_arity` error coverage |
19
+ | 8.16 atomic processing | atoms, characters, codes and number conversion with prescribed errors | `atomic_term_processing`, focused forward/reverse cases, parenthesized-number rejection, Logtalk-derived error cases, and strict Corrigendum 2 improper-list culprit checks for `atom_chars/2` and `atom_codes/2` |
20
20
  | 8.17 flags and hooks | complete required Part 1 flag set, selected defaults, standard value domains/changeability, halt and character conversion | `exceptions_and_flags`, `remaining_builtins_and_directives`, flag error cases, and the strict complete-flag audit in `run-iso-strict.mjs` |
21
21
  | Clause 9 evaluable functors | integer, float, rounding, transcendental and bitwise operations | `arithmetic`, `corrigenda_arithmetic`, `corrigenda_atan2_zero`, `corrigenda_integer_negative_power`, strict exclusion of the normal-mode `e` evaluable extension and zero-arity unknown-evaluable error checks |
22
22
  | Module compatibility profile (related to ISO/IEC 13211-2 and later WG17 amendment work) | module declarations, exports, imports, qualification, meta-predicate context | `modules/qualified_call`, `modules/selective_library_import`, `dcg_module_nonterminal_indicator` |
@@ -252,6 +252,22 @@ export function runIsoStrict(reporter = new TestReporter()) {
252
252
  'type_error(list)', '=../2 fixed non-list');
253
253
  });
254
254
 
255
+ reporter.test('enforces Corrigendum 2 call/N max-arity errors', () => {
256
+ equal(capture(() => run('', {
257
+ isoStrict: true,
258
+ goal: 'functor(T,f,65535), call(T,x)',
259
+ })).formal, 'representation_error(max_arity)', 'call/2 resulting arity');
260
+ });
261
+
262
+ reporter.test('reports the complete List culprit for Corrigendum 2 atomic conversions', () => {
263
+ for (const goal of ['atom_chars(A,[a|foo])', 'atom_codes(A,[97|foo])']) {
264
+ const error = capture(() => run('', { isoStrict: true, goal }));
265
+ equal(error.formal, 'type_error(list)', `${goal} formal`);
266
+ includes(error.message, '[', `${goal} complete list culprit`);
267
+ if (error.message.endsWith(', foo)')) throw new Error(`${goal}: reported only the improper tail`);
268
+ }
269
+ });
270
+
255
271
  reporter.test('follows ISO clause/2 private-procedure error precedence', () => {
256
272
  equal(capture(() => run('p.\n', { isoStrict: true, goal: 'clause(atom(_),4)' })).formal,
257
273
  'permission_error(access, private_procedure)', 'private procedure before body callability');