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, loops % occurs-check | sto, X = [X|_A] ; X = [_A,X|_B] ; X = [_A,_B,X|_C] ; ... % rational trees | sto, X = [_A|_B] ; X = [_A,[_A,[_A|_B]|_C]|_C] ; X = [_A,_B,[_A,_B,[_A,_B|_C]|_D]|_D] ; ... . % literal substitutions
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 conditions apply.
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.
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, loops | sto, Xs = [E|Xs] ; Xs = [_A,E|_B], _B = [E|_B] ; ... .
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 conditions apply.
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] ; ... . ?- 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, loops | N = 0, Es = [] ; sto, N = 1, Es = [Es|_A] ; ... . ?- 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.