21
22:- module(listutils,
23 [ natural/1 24 , int/1 25 , enumerate/2 26 , measure/2 27 , take/3, takec/3, take_while/3
28 , drop/3, dropc/3, drop_while/3
29 , map_filter/3
30 , foldr/4
31 , split_at/4
32 , same_length/2
33 , rep/3 34 , cons/3 35 , decons/3 36 , print_list/1 37 , printq_list/1 38 , print_numbered_list/1
39 , zip/3
40 ]). 41
42:- meta_predicate
43 drop_while(1,?,?)
44 , take_while(1,?,?)
45 , map_filter(2,+,-)
46 , foldr(3,?,?,?)
.
55natural(N) :- (var(N) -> between(0,inf,N); integer(N), N>=0).
65int(N) :- nonvar(N), integer(N).
66int(N) :- var(N), (N=0; (between(1,inf,M), (N=M; N is -M))).
71enumerate(X,Y) :- enumerate(X,0,Y).
72enumerate([],_,[]).
73enumerate([X|Xs],I,[J-X|IXs]) :- J is I+1, enumerate(Xs,J,IXs).
78measure(Xs,Ns) :- measure(Xs,Ns,0).
79measure([],[],_).
80measure([_|Xs],[N|Ns],N) :- M is N+1, measure(Xs,Ns,M).
85print_list([]) :- writeln('~'), nl.
86print_list([H|T]) :- print(H), nl, print_list(T).
91printq_list([]) :- writeln('~'), nl.
92printq_list([H|T]) :- writeq(H), nl, printq_list(T).
97print_numbered_list(L) :-
98 length(L,Max),
99 number_codes(Max,MC),
100 length(MC,Width),
101 print_num_list(Width,1,L).
102
103print_num_list(_,_,[]) :- nl.
104print_num_list(Width,N,[H|T]) :- succ(N,M),
105 copy_term(H,H1),
106 numbervars(H1,0,_),
107 format('~` t~d~*+. ~q\n',[N,Width,H1]),
108 print_num_list(Width,M,T).
109
116cons(H,T,[H|T]).
121decons(H,[H|T],T).
128rep(0,_,[]).
129rep(N,A,[A|X]) :-
130 ( nonvar(N)
131 -> succ(M,N), rep(M,A,X)
132 ; rep(M,A,X), succ(M,N)
133 ).
138drop(N,X,T) :- length(H,N), append(H,T,X).
143take(N,X,H) :- length(H,N), append(H,_,X).
149dropc(0,T,T) :- !.
150dropc(N,[_|T],V) :- !, succ(M,N), dropc(M,T,V).
151dropc(_,[],[]).
157takec(0,_,[]) :- !.
158takec(_,[],[]) :- !.
159takec(N,[X|XS],[X|YS]) :- succ(M,N), takec(M,XS,YS).
165drop_while(P,[X|T],V) :- call(P,X) -> drop_while(P,T,V); V=[X|T].
166drop_while(_,[],[]).
173take_while(P,[X|T],O) :- call(P,X) -> O=[X|V], take_while(P,T,V); O=[].
174take_while(_,[],[]).
182split_at(N,Pref,Rest,List) :-
183 ( nonvar(N)
184 -> length(Pref,N), append(Pref,Rest,List)
185 ; append(Pref,Rest,List), length(Pref,N)
186 ).
192same_length([],[]).
193same_length([_|X],[_|Y]) :- same_length(X,Y).
201zip([],[],[]).
202zip([X|XX],[Y|YY],[Z|ZZ]) :- Z=X-Y, zip(XX,YY,ZZ).
206map_filter(P,L1,L2) :- map_filter_(L1,L2,P).
207map_filter_([], [], _).
208map_filter_([X|Xs], [Y|Ys], P) :- call(P,X,Y), !, map_filter_(Xs, Ys, P).
209map_filter_([_|Xs], Ys, P) :- map_filter_(Xs, Ys, P).
212foldr(P,XX) --> foldr_(XX,P).
213foldr_([],_) --> [].
214foldr_([X|XX],P) --> foldr_(XX,P), call(P,X)