eyeprolog 1.3.76 → 1.3.78

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.
Files changed (39) hide show
  1. package/README.md +6 -6
  2. package/examples/binomial-vandermonde.pl +1 -1
  3. package/examples/book/chapter-26/02-triple.pl +1 -1
  4. package/examples/book/chapter-28/02-triangle.pl +1 -1
  5. package/examples/book/chapter-28/04-integer_rectangle.pl +1 -1
  6. package/examples/book/chapter-29/01-counterexample_to_odd_square.pl +1 -1
  7. package/examples/book/chapter-31/03-double.pl +1 -1
  8. package/examples/book/chapter-32/04-reference_square.pl +1 -1
  9. package/examples/book/chapter-33/03-chosen_pair.pl +1 -1
  10. package/examples/book/chapter-39/01-answer.pl +1 -1
  11. package/examples/catalan-convolution.pl +1 -1
  12. package/examples/collatz-1000.pl +1 -1
  13. package/examples/continued-fraction-sqrt2.pl +1 -1
  14. package/examples/easter-computus.pl +1 -1
  15. package/examples/equality-saturation.pl +1 -1
  16. package/examples/goldbach.pl +1 -1
  17. package/examples/integer-partitions.pl +1 -1
  18. package/examples/job-shop-scheduling.pl +1 -1
  19. package/examples/matrix-chain-order.pl +1 -1
  20. package/examples/missionaries-cannibals.pl +1 -1
  21. package/examples/pell-equation.pl +1 -1
  22. package/examples/polynomial.pl +1 -1
  23. package/examples/prime-range.pl +1 -1
  24. package/examples/stirling-bell-numbers.pl +1 -1
  25. package/examples/totient-summatory.pl +1 -1
  26. package/package.json +1 -1
  27. package/src/iso.js +74 -25
  28. package/src/lib/lists.pl +15 -5
  29. package/src/lib/prologue.pl +30 -166
  30. package/src/program.js +20 -8
  31. package/src/quads.js +24 -3
  32. package/src/repl.js +4 -2
  33. package/src/solver.js +75 -24
  34. package/src/standard-library.js +5 -6
  35. package/test/fixtures/README.md +8 -0
  36. package/test/fixtures/variable_names_quad.pl +163 -0
  37. package/test/run-regression.mjs +106 -6
  38. package/test/test-support.mjs +1 -1
  39. package/the-art-of-eyeprolog.md +30 -23
package/README.md CHANGED
@@ -335,10 +335,11 @@ may be imported explicitly, while source/CLI/API dependency loading can resolve
335
335
  their unqualified forms conservatively. For Trealla-style interactive timing,
336
336
  `time/1` is also available directly in the normal EyeProlog runtime; strict ISO
337
337
  mode does not expose it.
338
- The aligned `library(lists)` and `library(iso_ext)` exports are kept disjoint so
339
- they can be imported together without an accidental import conflict. EyeProlog's
340
- legacy `library(prologue)` remains a compatibility umbrella and should be
341
- selectively imported when mixed with the aligned modules.
338
+ `library(lists)`, `library(iso_ext)`, and `library(freeze)` follow the focused
339
+ module organization used by Trealla and Scryer. EyeProlog's legacy
340
+ `library(prologue)` is now a compatibility facade over these canonical modules
341
+ and `library(between)`, so it can be imported before or after the focused
342
+ libraries without duplicate-import errors.
342
343
 
343
344
  `library(lambda)` follows Scryer's higher-order lambda notation, adapted from
344
345
  Ulrich Neumerkel's permissively licensed implementation. Importing it installs
@@ -362,8 +363,7 @@ Outside `--iso-strict`, an otherwise undefined unqualified call may autoload a
362
363
  predicate only when the interop profile has one canonical EyeProlog provider.
363
364
  For example, `member/2` autoloads from `library(lists)`, `call_nth/2` from
364
365
  `library(iso_ext)`, `call_residue_vars/2` from `library(atts)`, and `between/3`
365
- from EyeProlog's internal
366
- `library(prologue)` implementation. Use `--no-autoload` to disable this
366
+ from `library(between)`. Use `--no-autoload` to disable this
367
367
  convenience. Strict ISO mode never autoloads library predicates.
368
368
 
369
369
  Use `-w` / `--warnings` to diagnose dependencies outside the interop profile,
@@ -1,5 +1,5 @@
1
1
  :- use_module(library(aggregate)).
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
 
4
4
  % Binomial coefficients and Vandermonde's identity.
5
5
  %
@@ -1,5 +1,5 @@
1
1
  % From The Art of EyeProlog, Chapter 26 — Answers are existential witnesses.
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
  :- use_module(library(lists)).
4
4
 
5
5
  triple(A, B, C) :-
@@ -1,5 +1,5 @@
1
1
  % From The Art of EyeProlog, Chapter 28 — Symmetry reduces search.
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
  :- use_module(library(lists)).
4
4
 
5
5
  triangle(A, B, C) :-
@@ -1,5 +1,5 @@
1
1
  % From The Art of EyeProlog, Chapter 28.
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
  :- use_module(library(lists)).
4
4
 
5
5
  integer_rectangle(Area, W, H) :-
@@ -1,5 +1,5 @@
1
1
  % From The Art of EyeProlog, Chapter 29 — Examples suggest; proofs compel.
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
  :- use_module(library(lists)).
4
4
 
5
5
  counterexample_to_odd_square(N) :-
@@ -1,5 +1,5 @@
1
1
  % From The Art of EyeProlog, Chapter 31 — Properties over finite domains.
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
  :- use_module(library(lists)).
4
4
 
5
5
  double(N, D) :- (D is N + N).
@@ -1,5 +1,5 @@
1
1
  % From The Art of EyeProlog, Chapter 32 — Compare specification and implementation.
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
  :- use_module(library(lists)).
4
4
 
5
5
  reference_square(N, S) :-
@@ -1,5 +1,5 @@
1
1
  % From The Art of EyeProlog, Chapter 33 — Pattern 3: Generate, constrain, describe.
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
  :- use_module(library(lists)).
4
4
 
5
5
  chosen_pair(pair(X, Y), reason(sum_is_ten)) :-
@@ -1,6 +1,6 @@
1
1
  % From The Art of EyeProlog, Chapter 39 — The EyeProlog library.
2
2
  :- use_module(library(dates)).
3
- :- use_module(library(prologue), [between/3]).
3
+ :- use_module(library(between), [between/3]).
4
4
  :- use_module(library(random)).
5
5
  :- use_module(library(lists)).
6
6
 
@@ -1,5 +1,5 @@
1
1
  :- use_module(library(aggregate)).
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
 
4
4
  % Catalan numbers by automatically tabled convolution.
5
5
  %
@@ -1,4 +1,4 @@
1
- :- use_module(library(prologue), [between/3]).
1
+ :- use_module(library(between), [between/3]).
2
2
 
3
3
  % Collatz conjecture suite translated from Eyeling's examples/collatz-1000.n3.
4
4
  % It enumerates starts N = 1000, 999, ..., 1 by deriving N = 1000 - N0
@@ -1,5 +1,5 @@
1
1
  :- use_module(library(aggregate)).
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
 
4
4
  % Convergents of sqrt(2) by automatically tabled recurrence.
5
5
  %
@@ -1,4 +1,4 @@
1
- :- use_module(library(prologue), [between/3]).
1
+ :- use_module(library(between), [between/3]).
2
2
 
3
3
  % Gregorian Easter computus adapted from Eyeling's easter.n3.
4
4
  % Each case is a year in a sample decade. The rules derive the Meeus/Jones/
@@ -1,5 +1,5 @@
1
1
  :- use_module(library(aggregate)).
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
  :- use_module(library(lists)).
4
4
  :- use_module(library(iso_ext)).
5
5
 
@@ -1,5 +1,5 @@
1
1
  :- use_module(library(primes)).
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
 
4
4
  % Goldbach's_conjecture
5
5
  % See https://en.wikipedia.org/wiki/Goldbach%27s_conjecture:
@@ -1,5 +1,5 @@
1
1
  :- use_module(library(aggregate)).
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
 
4
4
  % Integer partition counts by tabled dynamic programming.
5
5
  %
@@ -1,5 +1,5 @@
1
1
  :- use_module(library(aggregate)).
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
  :- use_module(library(lists)).
4
4
  :- use_module(library(iso_ext)).
5
5
 
@@ -1,5 +1,5 @@
1
1
  :- use_module(library(aggregate)).
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
  :- use_module(library(lists)).
4
4
  :- use_module(library(iso_ext)).
5
5
 
@@ -1,4 +1,4 @@
1
- :- use_module(library(prologue), [between/3]).
1
+ :- use_module(library(between), [between/3]).
2
2
  :- use_module(library(lists)).
3
3
  :- use_module(library(iso_ext)).
4
4
 
@@ -1,5 +1,5 @@
1
1
  :- use_module(library(aggregate)).
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
 
4
4
  % Pell equation x^2 - 2y^2 = 1 by automatically tabled recurrence.
5
5
  %
@@ -1,4 +1,4 @@
1
- :- use_module(library(prologue), [between/3]).
1
+ :- use_module(library(between), [between/3]).
2
2
  :- use_module(library(lists)).
3
3
 
4
4
  % Polynomial roots over complex integer candidates, adapted from Eyelet's
@@ -1,4 +1,4 @@
1
- :- use_module(library(prologue), [between/3]).
1
+ :- use_module(library(between), [between/3]).
2
2
  :- use_module(library(lists)).
3
3
  :- use_module(library(iso_ext)).
4
4
 
@@ -1,5 +1,5 @@
1
1
  :- use_module(library(aggregate)).
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
 
4
4
  % Stirling numbers of the second kind and Bell numbers.
5
5
  %
@@ -1,5 +1,5 @@
1
1
  :- use_module(library(aggregate)).
2
- :- use_module(library(prologue), [between/3]).
2
+ :- use_module(library(between), [between/3]).
3
3
  :- use_module(library(lists)).
4
4
  :- use_module(library(iso_ext)).
5
5
 
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "1.3.76",
6
+ "version": "1.3.78",
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
@@ -65,9 +65,9 @@ export const isoBuiltins = {
65
65
  registry.add('=..', 2, univBuiltin, { deterministic: true });
66
66
  registry.add('copy_term', 2, copyTermBuiltin, { deterministic: true });
67
67
  registry.add('term_variables', 2, termVariablesBuiltin, { deterministic: true });
68
- registry.add('findall', 3, findallBuiltin);
69
- registry.add('bagof', 3, bagofBuiltin);
70
- registry.add('setof', 3, setofBuiltin);
68
+ registry.add('findall', 3, findallBuiltin, { deterministic: true });
69
+ registry.add('bagof', 3, bagofBuiltin, { deterministicWhen: allSolutionsHasAtMostOneGroup });
70
+ registry.add('setof', 3, setofBuiltin, { deterministicWhen: allSolutionsHasAtMostOneGroup });
71
71
  registry.add('clause', 2, clauseBuiltin, {
72
72
  shouldUse: ({ solver }) => solver.program.findGroup('clause', 2) == null,
73
73
  });
@@ -1586,23 +1586,39 @@ function readTermFromStream(stream, solver) {
1586
1586
  let requestedInteractiveTerm = false;
1587
1587
  while (true) {
1588
1588
  let sawCandidate = false;
1589
- for (const candidate of termTextCandidates(stream, solver)) {
1590
- sawCandidate = true;
1591
- if (candidate.lexicalError) {
1592
- stream.position = candidate.end;
1593
- throw new PrologError('syntax_error(read_term)');
1594
- }
1595
- try {
1596
- const term = parseReadTermText(candidate.text, solver);
1597
- stream.position = candidate.end;
1598
- return scopeReadTerm(term);
1599
- } catch (error) {
1600
- if (error instanceof NumberRepresentationError || error instanceof CharacterRepresentationError) {
1601
- throw new PrologError(error.formal);
1589
+ let lastCandidateEnd = stream.position;
1590
+ try {
1591
+ for (const candidate of termTextCandidates(stream, solver)) {
1592
+ sawCandidate = true;
1593
+ lastCandidateEnd = candidate.end;
1594
+ if (candidate.lexicalError) {
1595
+ stream.position = candidate.end;
1596
+ throw new PrologError('syntax_error(read_term)');
1602
1597
  }
1603
- // A dot inside a graphic operator, such as =.., is only a possible
1604
- // terminator. Keep scanning until a complete term parses.
1598
+ try {
1599
+ const term = parseReadTermText(candidate.text, solver);
1600
+ stream.position = candidate.end;
1601
+ return scopeReadTerm(term);
1602
+ } catch (error) {
1603
+ if (error instanceof NumberRepresentationError || error instanceof CharacterRepresentationError) {
1604
+ throw new PrologError(error.formal);
1605
+ }
1606
+ // A dot inside a graphic operator, such as =.., is only a possible
1607
+ // terminator. Keep scanning until a complete term parses.
1608
+ }
1609
+ }
1610
+ } catch (error) {
1611
+ // A synthetic input boundary uses an invalid-character sentinel after
1612
+ // the required peek character. If a complete candidate already ended
1613
+ // at that boundary but did not parse, the term itself is malformed;
1614
+ // consume it and report syntax_error rather than blaming the sentinel.
1615
+ if (sawCandidate && Number.isInteger(stream.syntheticInputBoundary) &&
1616
+ lastCandidateEnd === stream.syntheticInputBoundary && error?.name === 'PrologError' &&
1617
+ error.formal === 'representation_error(character)') {
1618
+ stream.position = lastCandidateEnd;
1619
+ throw new PrologError('syntax_error(read_term)');
1605
1620
  }
1621
+ throw error;
1606
1622
  }
1607
1623
 
1608
1624
  // The interactive top level may attach a synchronous reader to the
@@ -2351,6 +2367,16 @@ function allSolutionsBuiltin(asSet) {
2351
2367
  const bagofBuiltin = allSolutionsBuiltin(false);
2352
2368
  const setofBuiltin = allSolutionsBuiltin(true);
2353
2369
 
2370
+ function allSolutionsHasAtMostOneGroup({ goal, env }) {
2371
+ try {
2372
+ const { iterated, quantified } = bagGoalParts(goal.args[1], env);
2373
+ return freeVariables(iterated, goal.args[0], quantified, env).length === 0;
2374
+ } catch (_) {
2375
+ // Leave error selection and reporting to the builtin itself.
2376
+ return false;
2377
+ }
2378
+ }
2379
+
2354
2380
  function callable(term, env) {
2355
2381
  term = deref(term, env);
2356
2382
  if (term.type === VAR) throw new PrologError('instantiation_error');
@@ -2807,35 +2833,57 @@ function* negationBuiltin({ solver, goal, env }) {
2807
2833
  for (const _ of solver.cloneForInnerGoal(1).solve([invoked], env.clone(), 0)) return;
2808
2834
  yield env;
2809
2835
  }
2810
- function* solveControlBranch(solver, goal, env) {
2836
+ function* solveControlBranch(solver, goal, env, observePending = null) {
2837
+ const existingStacks = new Set(solver.solveStacks);
2811
2838
  for (const answer of solver.solve([callable(goal, env)], env, 0)) {
2812
2839
  // A branch answer is internal to its enclosing control construct. The
2813
2840
  // surrounding solve will count the completed control goal after the
2814
2841
  // builtin yields it. Leaving both counts in place makes a bounded search
2815
2842
  // such as once/1 or negation stop before it can observe the branch answer.
2816
2843
  if (solver.solutionsSeen > 0) solver.solutionsSeen--;
2844
+ observePending?.(solver.hasPendingAlternatives(existingStacks));
2817
2845
  yield answer;
2818
2846
  }
2819
2847
  }
2820
- function* disjunctionBuiltin({ solver, goal, env }) {
2848
+ function disjunctionBuiltin(context) {
2849
+ const state = { pending: true };
2850
+ const iterator = disjunctionSolutions(context, state);
2851
+ iterator.hasPendingAlternatives = () => state.pending;
2852
+ return iterator;
2853
+ }
2854
+ function* disjunctionSolutions({ solver, goal, env }, state) {
2821
2855
  const left = deref(goal.args[0], env);
2822
2856
  if (left.type === COMPOUND && left.name === '->' && left.arity === 2) {
2823
2857
  for (const conditionEnv of solver.cloneForInnerGoal(1).solve([callable(left.args[0], env)], env.clone(), 0)) {
2824
- yield* solveControlBranch(solver, left.args[1], conditionEnv);
2858
+ yield* solveControlBranch(solver, left.args[1], conditionEnv,
2859
+ (pending) => { state.pending = pending; });
2860
+ state.pending = false;
2825
2861
  return;
2826
2862
  }
2827
- yield* solveControlBranch(solver, goal.args[1], env.clone());
2863
+ yield* solveControlBranch(solver, goal.args[1], env.clone(),
2864
+ (pending) => { state.pending = pending; });
2865
+ state.pending = false;
2828
2866
  return;
2829
2867
  }
2830
2868
  const marker = solver.active[solver.active.length - 1] ?? null;
2831
2869
  const markerCutEpoch = marker?.cutEpoch ?? 0;
2832
2870
  const solverCutEpoch = solver.cutEpoch;
2833
- yield* solveControlBranch(solver, goal.args[0], env.clone());
2871
+ yield* solveControlBranch(solver, goal.args[0], env.clone(), (pending) => {
2872
+ const cutThisScope = marker == null
2873
+ ? solver.cutEpoch !== solverCutEpoch
2874
+ : (marker.cutEpoch ?? 0) !== markerCutEpoch;
2875
+ state.pending = pending || !cutThisScope;
2876
+ });
2834
2877
  const cutThisScope = marker == null
2835
2878
  ? solver.cutEpoch !== solverCutEpoch
2836
2879
  : (marker.cutEpoch ?? 0) !== markerCutEpoch;
2837
- if (cutThisScope) return;
2838
- yield* solveControlBranch(solver, goal.args[1], env.clone());
2880
+ if (cutThisScope) {
2881
+ state.pending = false;
2882
+ return;
2883
+ }
2884
+ yield* solveControlBranch(solver, goal.args[1], env.clone(),
2885
+ (pending) => { state.pending = pending; });
2886
+ state.pending = false;
2839
2887
  }
2840
2888
  function* ifThenBuiltin({ solver, goal, env }) {
2841
2889
  for (const conditionEnv of solver.cloneForInnerGoal(1).solve([callable(goal.args[0], env)], env.clone(), 0)) {
@@ -2859,6 +2907,7 @@ export class BuiltinRegistry {
2859
2907
  arity,
2860
2908
  handler,
2861
2909
  deterministic: options.deterministic ?? false,
2910
+ deterministicWhen: options.deterministicWhen ?? null,
2862
2911
  ready: options.ready ?? null,
2863
2912
  fallbackWhenNotReady: options.fallbackWhenNotReady ?? false,
2864
2913
  shouldUse: options.shouldUse ?? null,
package/src/lib/lists.pl CHANGED
@@ -111,16 +111,23 @@ same_length([_|Xs], [_|Ys]) :- same_length(Xs, Ys).
111
111
 
112
112
  nth0(N, List, Elem) :- nth0(N, List, Elem, _).
113
113
 
114
- nth0(0, [Elem|Rest], Elem, Rest).
115
- nth0(N, [X|Xs], Elem, [X|Rest]) :-
114
+ nth0(N, List, Elem, Rest) :-
115
+ lists__integer_or_variable(N),
116
+ ( var(N) -> lists__nth0(N, List, Elem, Rest)
117
+ ; lists__not_less_than_zero(N),
118
+ lists__nth0(N, List, Elem, Rest)
119
+ ).
120
+
121
+ lists__nth0(0, [Elem|Rest], Elem, Rest).
122
+ lists__nth0(N, [X|Xs], Elem, [X|Rest]) :-
116
123
  var(N),
117
- nth0(N0, Xs, Elem, Rest),
124
+ lists__nth0(N0, Xs, Elem, Rest),
118
125
  N is N0 + 1.
119
- nth0(N, [X|Xs], Elem, [X|Rest]) :-
126
+ lists__nth0(N, [X|Xs], Elem, [X|Rest]) :-
120
127
  nonvar(N),
121
128
  N > 0,
122
129
  N0 is N - 1,
123
- nth0(N0, Xs, Elem, Rest).
130
+ lists__nth0(N0, Xs, Elem, Rest).
124
131
 
125
132
  nth1(N, List, Elem) :- nth1(N, List, Elem, _).
126
133
 
@@ -208,6 +215,9 @@ lists__integer(X) :- var(X), !, 0 is X.
208
215
  % arg/3 performs the ISO integer type check before inspecting its term.
209
216
  lists__integer(X) :- arg(X, type_check, _).
210
217
 
218
+ lists__integer_or_variable(X) :- var(X), !.
219
+ lists__integer_or_variable(X) :- lists__integer(X).
220
+
211
221
  lists__not_less_than_zero(X) :- X >= 0, !.
212
222
  % atom_length/2 reports domain_error(not_less_than_zero) for a negative value.
213
223
  lists__not_less_than_zero(X) :- atom_length('', X).
@@ -1,4 +1,10 @@
1
- /** Predicates proposed by the ISO Prolog Prologue working draft. */
1
+ /** Predicates proposed by the ISO Prolog Prologue working draft.
2
+
3
+ This legacy compatibility module is a facade over the canonical library
4
+ organization shared with Scryer and Trealla. Keeping one implementation
5
+ owner per predicate lets applications combine library(prologue) with the
6
+ specialized libraries without import conflicts.
7
+ */
2
8
 
3
9
  :- module(prologue, [
4
10
  member/2,
@@ -26,168 +32,26 @@
26
32
  countall/2
27
33
  ]).
28
34
 
29
- :- meta_predicate(maplist(1, '?')).
30
- :- meta_predicate(maplist(2, '?', '?')).
31
- :- meta_predicate(maplist(3, '?', '?', '?')).
32
- :- meta_predicate(maplist(4, '?', '?', '?', '?')).
33
- :- meta_predicate(maplist(5, '?', '?', '?', '?', '?')).
34
- :- meta_predicate(maplist(6, '?', '?', '?', '?', '?', '?')).
35
- :- meta_predicate(maplist(7, '?', '?', '?', '?', '?', '?', '?')).
36
- :- meta_predicate(call_nth(0, '?')).
37
- :- meta_predicate(freeze('?', 0)).
38
- :- meta_predicate(foldl(3, '?', '?', '?')).
39
- :- meta_predicate(foldl(4, '?', '?', '?', '?')).
40
- :- meta_predicate(foldl(5, '?', '?', '?', '?', '?')).
41
- :- meta_predicate(countall(0, '?')).
42
-
43
- member(X, [X|_]).
44
- member(X, [_|Xs]) :- member(X, Xs).
45
-
46
- append([], Ys, Ys).
47
- append([X|Xs], Ys, [X|Zs]) :- append(Xs, Ys, Zs).
48
-
49
- length(List, Length) :-
50
- nonvar(Length), !,
51
- prologue__integer(Length),
52
- prologue__not_less_than_zero(Length),
53
- prologue__length_fixed(Length, List).
54
- length(List, Length) :-
55
- prologue__length_generate(List, 0, Length).
56
-
57
- prologue__length_fixed(0, []).
58
- prologue__length_fixed(N, [_|Xs]) :-
59
- N > 0,
60
- Next is N - 1,
61
- prologue__length_fixed(Next, Xs).
62
-
63
- prologue__length_generate([], N, N).
64
- prologue__length_generate([_|Xs], N0, N) :-
65
- N1 is N0 + 1,
66
- prologue__length_generate(Xs, N1, N).
67
-
68
- between(Lower, Upper, X) :-
69
- prologue__integer(Lower),
70
- prologue__integer(Upper),
71
- prologue__integer_or_variable(X),
72
- prologue__between(Lower, Upper, X).
73
-
74
- prologue__between(Lower, Upper, Lower) :- Lower =< Upper.
75
- prologue__between(Lower, Upper, X) :-
76
- Lower < Upper,
77
- Next is Lower + 1,
78
- prologue__between(Next, Upper, X).
79
-
80
- select(X, [X|Xs], Xs).
81
- select(X, [Y|Ys], [Y|Zs]) :- select(X, Ys, Zs).
82
-
83
- succ(X, S) :-
84
- var(X), !,
85
- ( var(S) -> 0 is S
86
- ; prologue__integer(S),
87
- prologue__not_less_than_zero(S),
88
- S > 0,
89
- X is S - 1
90
- ).
91
- succ(X, S) :-
92
- prologue__integer(X),
93
- prologue__not_less_than_zero(X),
94
- ( var(S) -> S is X + 1
95
- ; prologue__integer(S),
96
- prologue__not_less_than_zero(S),
97
- S =:= X + 1
98
- ).
99
-
100
- maplist(_, []).
101
- maplist(Closure, [X|Xs]) :-
102
- call(Closure, X),
103
- maplist(Closure, Xs).
104
-
105
- maplist(_, [], []).
106
- maplist(Closure, [A|As], [B|Bs]) :-
107
- call(Closure, A, B),
108
- maplist(Closure, As, Bs).
109
-
110
- maplist(_, [], [], []).
111
- maplist(Closure, [A|As], [B|Bs], [C|Cs]) :-
112
- call(Closure, A, B, C),
113
- maplist(Closure, As, Bs, Cs).
114
-
115
- maplist(_, [], [], [], []).
116
- maplist(Closure, [A|As], [B|Bs], [C|Cs], [D|Ds]) :-
117
- call(Closure, A, B, C, D),
118
- maplist(Closure, As, Bs, Cs, Ds).
119
-
120
- maplist(_, [], [], [], [], []).
121
- maplist(Closure, [A|As], [B|Bs], [C|Cs], [D|Ds], [E|Es]) :-
122
- call(Closure, A, B, C, D, E),
123
- maplist(Closure, As, Bs, Cs, Ds, Es).
124
-
125
- maplist(_, [], [], [], [], [], []).
126
- maplist(Closure, [A|As], [B|Bs], [C|Cs], [D|Ds], [E|Es], [F|Fs]) :-
127
- call(Closure, A, B, C, D, E, F),
128
- maplist(Closure, As, Bs, Cs, Ds, Es, Fs).
129
-
130
- maplist(_, [], [], [], [], [], [], []).
131
- maplist(Closure, [A|As], [B|Bs], [C|Cs], [D|Ds], [E|Es], [F|Fs], [G|Gs]) :-
132
- call(Closure, A, B, C, D, E, F, G),
133
- maplist(Closure, As, Bs, Cs, Ds, Es, Fs, Gs).
134
-
135
- nth0(N, List, Elem) :- nth0(N, List, Elem, _).
136
-
137
- nth0(N, List, Elem, Rest) :-
138
- prologue__integer_or_variable(N),
139
- ( var(N) -> prologue__nth0(N, List, Elem, Rest)
140
- ; prologue__not_less_than_zero(N),
141
- prologue__nth0(N, List, Elem, Rest)
142
- ).
143
-
144
- prologue__nth0(0, [Elem|Rest], Elem, Rest).
145
- prologue__nth0(N, [X|Xs], Elem, [X|Rest]) :-
146
- var(N),
147
- prologue__nth0(N0, Xs, Elem, Rest),
148
- N is N0 + 1.
149
- prologue__nth0(N, [X|Xs], Elem, [X|Rest]) :-
150
- nonvar(N),
151
- N > 0,
152
- N0 is N - 1,
153
- prologue__nth0(N0, Xs, Elem, Rest).
154
-
155
- nth1(N, List, Elem) :- nth1(N, List, Elem, _).
156
-
157
- nth1(N, List, Elem, Rest) :-
158
- N \== 0,
159
- nth0(N, [_|List], Elem, [_|Rest]),
160
- N \== 0.
161
-
162
- call_nth(Goal, Nth) :- eyeprolog__call_nth(Goal, Nth).
163
-
164
- freeze(Var, Goal) :- eyeprolog__freeze(Var, Goal).
165
-
166
- foldl(_, [], Acc, Acc).
167
- foldl(Closure, [A|As], Acc0, Acc) :-
168
- call(Closure, A, Acc0, Acc1),
169
- foldl(Closure, As, Acc1, Acc).
170
-
171
- foldl(_, [], [], Acc, Acc).
172
- foldl(Closure, [A|As], [B|Bs], Acc0, Acc) :-
173
- call(Closure, A, B, Acc0, Acc1),
174
- foldl(Closure, As, Bs, Acc1, Acc).
175
-
176
- foldl(_, [], [], [], Acc, Acc).
177
- foldl(Closure, [A|As], [B|Bs], [C|Cs], Acc0, Acc) :-
178
- call(Closure, A, B, C, Acc0, Acc1),
179
- foldl(Closure, As, Bs, Cs, Acc1, Acc).
180
-
181
- countall(Goal, Count) :- eyeprolog__countall(Goal, Count).
182
-
183
- prologue__integer_or_variable(X) :- var(X), !.
184
- prologue__integer_or_variable(X) :- prologue__integer(X).
185
-
186
- prologue__integer(X) :- integer(X), !.
187
- prologue__integer(X) :- var(X), !, 0 is X.
188
- % arg/3 performs the required integer type check before inspecting its term.
189
- prologue__integer(X) :- arg(X, type_check, _).
190
-
191
- prologue__not_less_than_zero(X) :- X >= 0, !.
192
- % atom_length/2 reports domain_error(not_less_than_zero) for a negative value.
193
- prologue__not_less_than_zero(X) :- atom_length('', X).
35
+ :- use_module(library(lists), [
36
+ member/2,
37
+ append/3,
38
+ length/2,
39
+ select/3,
40
+ maplist/2,
41
+ maplist/3,
42
+ maplist/4,
43
+ maplist/5,
44
+ maplist/6,
45
+ maplist/7,
46
+ maplist/8,
47
+ nth0/3,
48
+ nth0/4,
49
+ nth1/3,
50
+ nth1/4,
51
+ foldl/4,
52
+ foldl/5,
53
+ foldl/6
54
+ ]).
55
+ :- use_module(library(between), [between/3]).
56
+ :- use_module(library(iso_ext), [succ/2, call_nth/2, countall/2]).
57
+ :- use_module(library(freeze), [freeze/2]).