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.
- package/README.md +6 -6
- package/examples/binomial-vandermonde.pl +1 -1
- package/examples/book/chapter-26/02-triple.pl +1 -1
- package/examples/book/chapter-28/02-triangle.pl +1 -1
- package/examples/book/chapter-28/04-integer_rectangle.pl +1 -1
- package/examples/book/chapter-29/01-counterexample_to_odd_square.pl +1 -1
- package/examples/book/chapter-31/03-double.pl +1 -1
- package/examples/book/chapter-32/04-reference_square.pl +1 -1
- package/examples/book/chapter-33/03-chosen_pair.pl +1 -1
- package/examples/book/chapter-39/01-answer.pl +1 -1
- package/examples/catalan-convolution.pl +1 -1
- package/examples/collatz-1000.pl +1 -1
- package/examples/continued-fraction-sqrt2.pl +1 -1
- package/examples/easter-computus.pl +1 -1
- package/examples/equality-saturation.pl +1 -1
- package/examples/goldbach.pl +1 -1
- package/examples/integer-partitions.pl +1 -1
- package/examples/job-shop-scheduling.pl +1 -1
- package/examples/matrix-chain-order.pl +1 -1
- package/examples/missionaries-cannibals.pl +1 -1
- package/examples/pell-equation.pl +1 -1
- package/examples/polynomial.pl +1 -1
- package/examples/prime-range.pl +1 -1
- package/examples/stirling-bell-numbers.pl +1 -1
- package/examples/totient-summatory.pl +1 -1
- package/package.json +1 -1
- package/src/iso.js +74 -25
- package/src/lib/lists.pl +15 -5
- package/src/lib/prologue.pl +30 -166
- package/src/program.js +20 -8
- package/src/quads.js +24 -3
- package/src/repl.js +4 -2
- package/src/solver.js +75 -24
- package/src/standard-library.js +5 -6
- package/test/fixtures/README.md +8 -0
- package/test/fixtures/variable_names_quad.pl +163 -0
- package/test/run-regression.mjs +106 -6
- package/test/test-support.mjs +1 -1
- 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
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
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
|
|
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,
|
package/examples/collatz-1000.pl
CHANGED
package/examples/goldbach.pl
CHANGED
package/examples/polynomial.pl
CHANGED
package/examples/prime-range.pl
CHANGED
package/package.json
CHANGED
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
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
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
|
-
|
|
1604
|
-
|
|
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
|
|
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)
|
|
2838
|
-
|
|
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(
|
|
115
|
-
|
|
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
|
-
|
|
124
|
+
lists__nth0(N0, Xs, Elem, Rest),
|
|
118
125
|
N is N0 + 1.
|
|
119
|
-
|
|
126
|
+
lists__nth0(N, [X|Xs], Elem, [X|Rest]) :-
|
|
120
127
|
nonvar(N),
|
|
121
128
|
N > 0,
|
|
122
129
|
N0 is N - 1,
|
|
123
|
-
|
|
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).
|
package/src/lib/prologue.pl
CHANGED
|
@@ -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
|
-
:-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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]).
|