The aim of the Prolog prologue is to avoid discussing such details and concentrate on the identification and precise definition of these commonly used predicates instead. The Prolog prologue is a possibly empty file to be included (7.4.2.7). After inclusion, the following predicates are defined. A processor may provide also some other means to include the prologue. For example, via a command line switch.
member(X, L) is true if X is an element of
the list L.
More precisely,
member(X, L) is true iff X is an element of
a list prefix of L.
Procedurally, member/2 is defined with the following
clauses.
member(X, [X|_L]). member(X, [_|L]) :- member(X, L).Alternatively:
member(X, [E|L]) :- ( X = E ; member(X, L) ).
member(?term, ?term)
?- member(X, [1,2]). X = 1 ; X = 2. ?- member(1, L). L = [1|_A] ; L = [_A,1|_B] ; L = [_A,_B,1|_C] ; ..., ad_infinitum. ?- member(X, [Y,Z|nonlist]). X = Y ; X = Z. ?- member(X, nonlist). false. ?- member(X, X). sto, % occurs-check loops | sto, % rational trees X = [X|_A] ; X = [_A,X|_B] ; X = [_A,_B,X|_C] ; ..., ad_infinitum | sto, % literal substitutions X = [_A|_B] ; X = [_A,[_A,[_A|_B]|_C]|_C] ; X = [_A,_B,[_A,_B,[_A,_B|_C]|_D]|_D] ; ..., ad_infinitum. ?- member(X, X). sto, ( loops % occurs-check | X = [X|_A] % rational trees ; X = [_A,X|_B] ; X = [_A,_B,X|_C] ; ..., ad_infinitum | X = [_A|_B] % literal substitutions ; X = [_A,[_A,[_A|_B]|_C]|_C] ; X = [_A,_B,[_A,_B,[_A,_B|_C]|_D]|_D] ; ..., ad_infinitum ).
append(Xs, Ys, Zs) is true if Zs is the
concatenation of the lists Xs and Ys.
More precisely,
append(Xs, Ys, Zs) is true iff the list Xs
is a list prefix of Zs
and Ys is
Zs with prefix Xs removed.
Procedurally, append/3 is defined with the following
clauses.
append([], Zs, Zs). append([X|Xs], Ys, [X|Zs]) :- append(Xs, Ys, Zs).
append(?term, ?term, ?term)
?- append([a,b],[c,d], Xs). Xs = [a,b,c,d]. ?- append([a], nonlist, Xs). Xs = [a|nonlist]. ?- append([a], Ys, Zs). Zs = [a|Ys]. ?- append(Xs, Ys, [a,b,c]). Xs = [], Ys = [a,b,c] ; Xs = [a], Ys = [b,c] ; Xs = [a,b], Ys = [c] ; Xs = [a,b,c], Ys = []. ?- append(Xs, Ys, [a,b|Xs]). Xs = [], Ys = [a,b] ; Xs = [a], Ys = [b,a] ; Xs = [a,b], Ys = [a,b] ; Xs = [a,b,a], Ys = [b,a] ; ..., ad_infinitum.
length(List, Length) is true iff List is a
list of length Length.
length(List, Length) is executed as
follows:
List is neither a partial list nor a list, then
the goal fails.
List is a list, then
unifies Length with the length of List.
Length is an integer, then
unifies List with a list of length Length
with Length distinct fresh variables as elements.
Len of N0 being the integer 0.
Length
with Len and List with a list of
length Len with Len distinct fresh
variables as elements.
List is a partial list and Length is
a variable, chooses the next element Len of N0
and proceeds to step p.p.3.1 g.
length(List, Length) is re-executable. On
backtracking, continue at p.p.3.1 h above.
length(?term, ?integer)
Length is neither a variable nor an integer
type_error(integer, Length).
Length is an integer that is less than zero
domain_error(not_less_than_zero, Length).
?- length([a,b,c], Length). Length = 3. ?- length(List, 5). List = [_A,_B,_C,_D,_E]. ?- length(List, Length). List = [], Length = 0 ; List = [_A], Length = 1 ; List = [_A,_B], Length = 2 ; ..., ad_infinitum. ?- length([a|List],Length). List = [], Length = 1 ; List = [_A], Length = 2 ; List = [_A,_B], Length = 3 ; ..., ad_infinitum.
between(Lower, Upper, X) is true iff X is
greater than or equal to Lower, and less than or equal to Upper.
between(Lower, Upper, X) is
defined with the following clauses when no error condition is satisfied.
between(Lower, Upper, Lower) :- Lower =< Upper. between(Lower1, Upper, X) :- Lower1 < Upper, Lower2 is Lower1 + 1, between(Lower2, Upper, X).
between(+integer,+integer,?integer)
Lower is a variable
instantiation_error.
Upper is a variable
instantiation_error.
Lower is neither a variable nor an integer
type_error(integer, Lower).
Upper is neither a variable nor an integer
type_error(integer, Upper).
X is neither a variable nor an integer
type_error(integer, X).
between(X, X, 1).
?- between(1, 2, 0). false. ?- between(1, 2, I). I = 1 ; I = 2. ?- between(2, 1, I). false. ?- between(I, I, 0). instantiation_error. ?- between(1, I, 0). instantiation_error. ?- between(I, -1, 0). instantiation_error. ?- between(1, c, 0). type_error(integer, c). ?- between(1+1,2,I). type_error(integer, 1+1).
select(X, Xs, Ys) is true if X is an element
of the list Xs and Ys is the
list Xs with one occurrence of X removed.
More precisely,
select(X, Xs, Ys) is true iff X is an element
of a list prefix of Xs and Ys is Xs with one occurrence of X removed.
Procedurally, select/3 is defined with the following
clauses.
select(E, [E|Xs], Xs). select(E, [X|Xs], [X|Ys]) :- select(E, Xs, Ys).
select(?term, ?term, ?term)
?- select(X, [1,2], Xs). X = 1, Xs = [2] ; X = 2, Xs = [1]. ?- select(X, [Y|nonlist], Xs). X = Y, Xs = nonlist. ?- select(E, Xs, Xs). sto, % occurs-check loops | sto, % rational trees Xs = [E|Xs] ; Xs = [_A|_B], _B = [E|_B] ; ..., ad_infinitum | sto, % literal substitutions Xs = [E,E|_A] ; Xs = [_A,E,E|_B] ; ..., ad_infinitum.
succ(X, S) is true iff S is
the successor of the non-negative integer X.
succ(X, S) is
defined with the following clauses when no error condition is satisfied.
succ(X, S) :- ( nonvar(S) -> S > 0, X is S-1 ; S is X+1 ).
succ(?integer,+integer)succ(+integer,-integer)
X is a variable and S is a variable.
instantiation_error.
X is neither a variable nor an integer
type_error(integer, X).
S is neither a variable nor an integer
type_error(integer, S).
X is an integer that is less than zero
domain_error(not_less_than_zero, X).
S is an integer that is less than zero
domain_error(not_less_than_zero, S).
X
is maxint and S is a variable.
evaluation_error(int_overflow).
repesentation_error(max_integer).
succ(X, X) requires an instantiation
error although there is no solution.
?- succ(X, S). instantiation_error. ?- succ(X, X). instantiation_error. ?- succ(0, S). S = 1. ?- succ(1, 1+1). type_error(integer, 1+1). ?- succ(X, 0). false. ?- succ(-1, S). domain_error(not_less_than_zero, -1). ?- current_prolog_flag(max_integer, MI), succ(MI, 0). false. ?- current_prolog_flag(max_integer, MI), succ(MI, 1). false. ?- current_prolog_flag(max_integer, MI), succ(MI, MI). false. ?- current_prolog_flag(max_integer, MI), succ(MI, S). false | evaluation_error(int_overflow) | representation_error(max_integer).
maplist(R_1, E1s)
is true iff
E1s is a list and
for each element E1 of E1s,
call(R_1, E1) is true.
maplist(R_2, E1s, E2s)
is true iff
E1s and E2s are lists of same length
and
for each element E1 of E1s and each corresponding
element of E2,
call(R_2, E1, E2) is true.
maplist(R_n, E1s, E2s, ... Ens) is true iff
E1s, E2s up to Ens are
lists of same length
and call(R_n, E1_i, E2_i, ... En_i) is true for
each i where Ek_i is the i-th element of Listk.
Procedurally, maplist/2..8 is defined with the following
clauses.
maplist(_R_1, []). maplist(R_1, [E1|E1s]) :- call(R_1, E1), maplist(R_1, E1s). maplist(_R_2, [], []). maplist(R_2, [E1|E1s], [E2|E2s]) :- call(R_2, E1, E2), maplist(R_2, E1s, E2s). maplist(_R_3, [], [], []). maplist(R_3, [E1|E1s], [E2|E2s], [E3|E3s]) :- call(R_3, E1, E2, E3), maplist(R_3, E1s, E2s, E3s). ... maplist(_R_n, [], [], ... []). maplist(R_n, [E1|E1s], [E2|E2s], ... [En|Ens]) :- call(R_n, E1, E2, ... En), maplist(R_n, E1s, E2s, ... Ens).
maplist(?term, ?term)maplist(?term, ?term, ?term)maplist(?term, ?term, ?term, ?term)maplist(?term, ?term, ?term, ... ?term)?- maplist(>(3), [1, 2]). true. ?- maplist(>(3), [1, 2, 3]). false. ?- maplist(=(X), Xs). Xs = [] ; Xs = [X] ; Xs = [X, X] ; Xs = [X, X, X] ; ..., ad_infinitum.
nth0(N, Es0, E, Es) is true if E is an
element of the list Es0 and there are N
elements before E. Es is the list without this
occurence of E.
More precisely,
nth0(N, Es0, E, Es) is true iff there is a list
prefix Prefix of Es0
and length(Prefix,N), append(Prefix,[E|Postfix], Es0),
append(Prefix, Postfix, Es) is true.
nth0(?integer, ?term, ?term, ?term)nth0(?integer, ?term, ?term)nth1(?integer, ?term, ?term, ?term)nth1(?integer, ?term, ?term)
N is neither a variable nor an integer
type_error(integer, N).
N is an integer that is less than zero
domain_error(not_less_than_zero, N).
?- nth0(1, [a,b,c], E). E = b. ?- nth0(N, [a,b,c], E). N = 0, E = a ; N = 1, E = b ; N = 2, E = c. ?- nth0(0, [A,B|non_list], E). A = E. ?- nth0(2, Es, E). Es = [_A,_B,E|_C]. ?- nth0(N, Es, E). N = 0, Es = [E|_A] ; N = 1, Es = [_A,E|_B] ; N = 2, Es = [_A,_B,E|_C] ; N = 3, Es = [_A,_B,_C,E|_D] ; ..., ad_infinitum. ?- nth0(non_integer, Es, E). type_error(integer, non_integer). ?- nth0(-1, Es, E). domain_error(not_less_than_zero, -1). ?- nth0(N, [[]|Es], Es). N = 0, Es = [] ; sto, % occurs-check loops | N = 0, Es = [] ; sto, % rational trees N = 1, Es = [Es|_A] ; N = 2, Es = [_A,Es|_B] ; ..., ad_infinitum. ?- nth1(0, Es, E). false.
nth0/3, nth1/4,
and nth1/3 all provide similar functionality to
nth0/4.
nth0(N, Es0, E) :- nth0(N, Es0, E, _). nth1(N, Es0, E, Es) :- N \== 0, nth0(N, [_|Es0], E, [_|Es]), N \== 0. nth1(N, Es0, E) :- nth1(N, Es0, E, _).
foldl(R_3, Xs, S0,S) is true iff Xs is a
list and for all elements X1..Xn
of Xs the
following is true.
call(R_3, X1, S0,S1), call(R_3, X2, S1,S2), ..., call(R_3, Xn, Spn,S).
foldl(R_4, Xs, Ys, S0,S) is true iff Xs
and Ys are lists of same length and for all
elements X1..Xn of Xs
and Y1..Yn of Ys the following is
true.
call(R_4, X1, Y1, S0,S1), call(R_4, X2, Y2, S1,S2), ..., call(R_4, Xn, Yn, Spn,S).
foldl(R_5, Xs, Ys, Zs, S0,S) is true
iff Xs, Ys, and Zs are lists of same length and for all
elements X1..Xn of Xs,
Y1..Yn of Ys, and
Z1..Zn of Zs the following is
true.
call(R_5, X1, Y1, Z1, S0,S1), call(R_5, X2, Y2, Z2, S1,S2), ..., call(R_5, Xn, Yn, Zn, Spn,S).
Procedurally, foldl/4..6 is defined with the following
clauses.
foldl(_, [], S,S). foldl(R_3, [X|Xs], S0,S) :- call(R_3, X, S0,S1), foldl(R_3, Xs, S1,S1). foldl(_, [], [], S,S). foldl(R_4, [X|Xs], [Y|Ys], S0,S) :- call(R_4, X, Y, S0,S1), foldl(R_4, Xs, Ys, S1,S). foldl(_, [], [], [], S,S). foldl(R_5, [X|Xs], [Y|Ys], [Z|Zs], S0,S) :- call(R_5, X, Y, Z, S0,S1), foldl(R_5, Xs, Ys, Zs, S1,S).
foldl(?term, ?term, ?term,?term)foldl(?term, ?term, ?term, ?term,?term)foldl(?term, ?term, ?term, ?term, ?term,?term)
scanlist or reduce in some Prolog
processors.
?- foldl(append, [[1,2],[3],[4,5]], [],Xs). Xs = [4,5,3,1,2].
template(X, S) is true iff S is
the templateessor of the non-negative integer X.
template(?integer,+integer)template(+integer,-integer)
X is a variable and @.
instantiation_error.
?- true. true.