eyeprolog 1.5.102 → 1.5.103

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.5.102",
6
+ "version": "1.5.103",
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
@@ -674,10 +674,21 @@ function* termVariablesBuiltin({ goal, env }) {
674
674
  }
675
675
 
676
676
  function validPredicateIndicator(term) {
677
- return term.type === COMPOUND && term.name === '/' && term.arity === 2 &&
678
- (term.args[0].type === VAR || term.args[0].type === ATOM) &&
679
- (term.args[1].type === VAR ||
680
- (term.args[1].type === NUMBER && isDecimalInteger(term.args[1].name) && BigInt(term.args[1].name) >= 0n));
677
+ if (term.type !== COMPOUND || term.name !== '/' || term.arity !== 2) return false;
678
+ const [name, arity] = term.args;
679
+ // Name/Arity denotes a predicate indicator only when some instance of it
680
+ // could be one: Name an atom, Arity a non-negative integer. The same
681
+ // shared variable in both positions (current_predicate(X/X), issue #115)
682
+ // looks valid argument-by-argument -- each position individually accepts
683
+ // an unbound variable -- but no instantiation can satisfy both at once,
684
+ // since binding that one variable to an atom makes Arity an atom too, not
685
+ // an integer. stc#79 treats this as no valid instance existing at all,
686
+ // the same as a bare atom argument, so it must raise
687
+ // type_error(predicate_indicator, _) rather than just finding no matches.
688
+ if (name.type === VAR && arity.type === VAR && name.name === arity.name) return false;
689
+ return (name.type === VAR || name.type === ATOM) &&
690
+ (arity.type === VAR ||
691
+ (arity.type === NUMBER && isDecimalInteger(arity.name) && BigInt(arity.name) >= 0n));
681
692
  }
682
693
 
683
694
  const currentPredicateBuiltin = pendingBuiltin(currentPredicateSolutions);
@@ -1541,6 +1541,11 @@ export function runIsoStrict(reporter = new TestReporter()) {
1541
1541
  ['clause(X,_)', 'instantiation_error', 'clause/2 variable head'],
1542
1542
  ['clause(4,_)', 'type_error(callable)', 'clause/2 head type'],
1543
1543
  ['current_predicate(4)', 'type_error(predicate_indicator)', 'current_predicate/1 indicator type'],
1544
+ // The same variable filling both Name and Arity (issue #115, stc#79)
1545
+ // looks valid position-by-position -- each alone accepts an unbound
1546
+ // variable -- but no instantiation can satisfy both at once, since
1547
+ // binding it to an atom makes Arity an atom too, not an integer.
1548
+ ['current_predicate(X/X)', 'type_error(predicate_indicator)', 'current_predicate/1 aliased name/arity variable'],
1544
1549
  ['asserta(_)', 'instantiation_error', 'asserta/1 variable head'],
1545
1550
  ['asserta(4)', 'type_error(callable)', 'asserta/1 head type'],
1546
1551
  ['asserta((p:-4))', 'type_error(callable)', 'asserta/1 body conversion'],