%%% Simple predicates on lists %%% Author: Frank Pfenning %%% %%% If a predicate p is already built-in, the name %%% has been modified to p_ to allow this to compile % list_(Xs) iff Xs is a list % Same as built-in list(Xs) list_([]). list_([X|Xs]) :- list_(Xs). % nat(N) iff N is a natural number in unary notation nat(z). nat(s(N)) :- nat(N). % natlist(N) iff N is a list of natural numbers natlist([]). natlist([N|Ns]) :- nat(N), natlist(Ns). % plist(P, Xs) iff Xs is a list where each element satisfies P plist(P, []). plist(P, [X|Xs]) :- G=..[P, X], call(G), plist(P, Xs). % P(X) or call(P(X)) works in some Prolog implementations, % but not in GNU Prolog. % Decompose into G=..[P, X] which sets G = P(X) and then call G % member_(X, Ys) iff X is a member of the list Ys. % Will succeed multiple times for each member of Ys equal to X. % member_(X, Ys) is identical to built-in member(X, Ys) member_(X, [X|Ys]). member_(X, [Y|Ys]) :- member_(X, Ys). % member1(X, Ys) iff X is a member of the list Ys % Will succeed only once, for the first member of Ys equal to X. member1(X, [X|Ys]). member1(X, [Y|Ys]) :- X \= Y, member1(X, Ys). % prefix_(Xs, Ys) iff list Xs is a prefix of list Ys prefix_([], Ys). prefix_([X|Xs], [X|Ys]) :- prefix_(Xs, Ys). % suffix_(Xs, Ys) iff list Xs if a suffix of list Ys suffix_(Xs, Xs). suffix_(Xs, [Y|Ys]) :- suffix(Xs, Ys). % append_(Xs, Ys, Zs) iff Zs is the result of appending list Ys to list Xs append_([], Ys, Ys). append_([X|Xs], Ys, [X|Zs]) :- append_(Xs, Ys, Zs). % alternative definitions of prefix and suffix. prefix2(Xs, Ys) :- append_(Xs, _, Ys). suffix2(Xs, Ys) :- append_(_, Xs, Ys). % sublist_(Xs, Ys) iff Xs is a sublist of Ys sublist_(Xs, Ys) :- prefix_(Ps, Ys), suffix_(Xs, Ps). % length_(Xs, N) iff Xs is a list of length N. length_([], 0). length_([X|Xs], N) :- length_(Xs, N1), N is N1+1.