eyeprolog 1.2.8 → 1.2.9
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/solver.js +4 -1
- package/test/run-regression.mjs +15 -0
- package/the-art-of-eyeprolog.md +7 -1
package/package.json
CHANGED
package/src/solver.js
CHANGED
|
@@ -47,7 +47,10 @@ export class Solver {
|
|
|
47
47
|
this.maxInferences = options.maxInferences ?? Infinity;
|
|
48
48
|
this.inferences = 0;
|
|
49
49
|
this.inferenceLimitExceeded = false;
|
|
50
|
-
|
|
50
|
+
// Do not impose an implicit answer cap. Infinite and very large searches are
|
|
51
|
+
// part of normal Prolog semantics; callers that need a resource bound can
|
|
52
|
+
// still supply solutionLimit explicitly.
|
|
53
|
+
this.solutionLimit = options.solutionLimit ?? Infinity;
|
|
51
54
|
this.solutionsSeen = 0;
|
|
52
55
|
this.prologFlags = options.prologFlags ?? defaultPrologFlags('error', this.isoStrict);
|
|
53
56
|
if (this.isoStrict) {
|
package/test/run-regression.mjs
CHANGED
|
@@ -2063,6 +2063,21 @@ open(X) :- candidate(X), \\+ closed(X).
|
|
|
2063
2063
|
assertEqual(answers.join('\n'), 'p(a)\np(b)', 'answers');
|
|
2064
2064
|
},
|
|
2065
2065
|
},
|
|
2066
|
+
{
|
|
2067
|
+
name: 'solver has no implicit solution limit',
|
|
2068
|
+
run: () => {
|
|
2069
|
+
const program = Program.parse('p(a).\n');
|
|
2070
|
+
const solver = new Solver(program);
|
|
2071
|
+
assertEqual(String(solver.solutionLimit), 'Infinity', 'default solution limit');
|
|
2072
|
+
// Crossing the former 10,000,000-answer ceiling must not make an
|
|
2073
|
+
// otherwise available answer disappear. This exercises the boundary
|
|
2074
|
+
// without making the regression suite enumerate ten million answers.
|
|
2075
|
+
solver.solutionsSeen = 10_000_000;
|
|
2076
|
+
const goal = parseGoalText('p(X)');
|
|
2077
|
+
const answers = [...solver.solve([goal], new Env(), 0)].map((env) => termToString(goal, env, true));
|
|
2078
|
+
assertEqual(answers.join('\n'), 'p(a)', 'answer beyond former default ceiling');
|
|
2079
|
+
},
|
|
2080
|
+
},
|
|
2066
2081
|
{
|
|
2067
2082
|
name: 'solver honors solution limits',
|
|
2068
2083
|
run: () => {
|
package/the-art-of-eyeprolog.md
CHANGED
|
@@ -1805,7 +1805,13 @@ const solver = new Solver(program, {
|
|
|
1805
1805
|
```
|
|
1806
1806
|
|
|
1807
1807
|
The limits are safety ceilings, not logical declarations. Reaching one may
|
|
1808
|
-
truncate search; it does not prove that no further answer exists.
|
|
1808
|
+
truncate search; it does not prove that no further answer exists. At the `Solver`
|
|
1809
|
+
API boundary, `solutionLimit` is opt-in: if it is omitted, ordinary solving and
|
|
1810
|
+
child searches that inherit the solver limit do not stop after a fixed number of
|
|
1811
|
+
solutions. This matters for re-executable goals such as `repeat/0` and for
|
|
1812
|
+
library relations such as `call_nth/2`; an implementation safety threshold must
|
|
1813
|
+
not turn a still re-executable search into logical failure. Embedders that need
|
|
1814
|
+
a finite answer budget should pass `solutionLimit` explicitly.
|
|
1809
1815
|
|
|
1810
1816
|
### Implementation boundary
|
|
1811
1817
|
|