eyeprolog 1.3.74 → 1.3.75
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/iso.js +21 -8
- package/test/run-regression.mjs +10 -0
package/package.json
CHANGED
package/src/iso.js
CHANGED
|
@@ -2556,19 +2556,32 @@ function residueVariablesSince(snapshot, env) {
|
|
|
2556
2556
|
return names;
|
|
2557
2557
|
}
|
|
2558
2558
|
|
|
2559
|
-
function
|
|
2559
|
+
function callResidueVarsBuiltin({ solver, goal, env }) {
|
|
2560
2560
|
const invoked = callable(goal.args[0], env);
|
|
2561
2561
|
if (invoked.module == null) invoked.module = goal.module ?? 'user';
|
|
2562
2562
|
const snapshot = residueSnapshot(env);
|
|
2563
2563
|
const child = solver.cloneForInnerGoal();
|
|
2564
|
-
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2564
|
+
let pending = true;
|
|
2565
|
+
// The wrapper iterator is resumable even for a deterministic Goal. Expose
|
|
2566
|
+
// the child's actual search state so the top level does not print a phantom
|
|
2567
|
+
// choicepoint after the final answer.
|
|
2568
|
+
const iterator = (function* residueSolutions() {
|
|
2569
|
+
try {
|
|
2570
|
+
for (const answerEnv of child.solve([invoked], env, 0)) {
|
|
2571
|
+
pending = child.hasPendingAlternatives();
|
|
2572
|
+
const next = answerEnv.clone();
|
|
2573
|
+
if (unify(goal.args[1], listFromItems(residueVariablesSince(snapshot, answerEnv)), next)) {
|
|
2574
|
+
yield next;
|
|
2575
|
+
if (!pending) return;
|
|
2576
|
+
}
|
|
2577
|
+
}
|
|
2578
|
+
pending = false;
|
|
2579
|
+
} finally {
|
|
2580
|
+
solver.absorbStatsFrom(child);
|
|
2568
2581
|
}
|
|
2569
|
-
}
|
|
2570
|
-
|
|
2571
|
-
|
|
2582
|
+
})();
|
|
2583
|
+
iterator.hasPendingAlternatives = () => pending;
|
|
2584
|
+
return iterator;
|
|
2572
2585
|
}
|
|
2573
2586
|
|
|
2574
2587
|
function* freezeBuiltin({ solver, goal, env }) {
|
package/test/run-regression.mjs
CHANGED
|
@@ -178,6 +178,16 @@ check :- call_residue_vars(X in 1..3, Vs), Vs = [X].
|
|
|
178
178
|
`;
|
|
179
179
|
assertIncludes(run(clpzResidue, { goal: 'check' }).stdout, 'check.', 'call_residue_vars/2 includes CLP(Z) attributed variables');
|
|
180
180
|
|
|
181
|
+
const deterministicProgram = Program.parse(':- use_module(library(atts)).');
|
|
182
|
+
const deterministicSolver = new Solver(deterministicProgram);
|
|
183
|
+
const deterministicGoal = parseGoalText('call_residue_vars(true, Xs)');
|
|
184
|
+
const deterministicSolutions = deterministicSolver.solve([deterministicGoal], new Env(), 0);
|
|
185
|
+
const deterministicAnswer = deterministicSolutions.next();
|
|
186
|
+
assertEqual(deterministicAnswer.done, false, 'call_residue_vars/2 deterministic answer');
|
|
187
|
+
assertEqual(deterministicSolver.hasPendingAlternatives(), false,
|
|
188
|
+
'call_residue_vars/2 deterministic success has no leftover choicepoint');
|
|
189
|
+
deterministicSolutions.return();
|
|
190
|
+
|
|
181
191
|
const residualFile = path.join(tmp, `atts-residual-${++tmpCounter}.pl`);
|
|
182
192
|
fs.writeFileSync(residualFile, `:- use_module(library(atts)).
|
|
183
193
|
:- attribute required/1.
|