234 lines
5.4 KiB
Prolog
234 lines
5.4 KiB
Prolog
:- module(lists, [member/2, select/3, append/2, append/3, foldl/4, foldl/5,
|
|
memberchk/2, reverse/2, length/2, maplist/2,
|
|
maplist/3, maplist/4, maplist/5, maplist/6,
|
|
maplist/7, maplist/8, maplist/9, same_length/2, nth0/3,
|
|
sum_list/2, transpose/2, list_to_set/2, list_max/2, list_min/2]).
|
|
|
|
|
|
:- use_module(library(error)).
|
|
|
|
|
|
:- meta_predicate maplist(1, ?).
|
|
:- meta_predicate maplist(2, ?, ?).
|
|
:- meta_predicate maplist(3, ?, ?, ?).
|
|
:- meta_predicate maplist(4, ?, ?, ?, ?).
|
|
:- meta_predicate maplist(5, ?, ?, ?, ?, ?).
|
|
:- meta_predicate maplist(6, ?, ?, ?, ?, ?, ?).
|
|
:- meta_predicate maplist(7, ?, ?, ?, ?, ?, ?, ?).
|
|
:- meta_predicate maplist(8, ?, ?, ?, ?, ?, ?, ?, ?).
|
|
|
|
:- meta_predicate foldl(3, ?, ?, ?).
|
|
:- meta_predicate foldl(4, ?, ?, ?, ?).
|
|
|
|
|
|
length(Xs, N) :-
|
|
var(N),
|
|
!,
|
|
'$skip_max_list'(M, -1, Xs, Xs0),
|
|
( Xs0 == [] -> N = M
|
|
; var(Xs0) -> length_addendum(Xs0, N, M)).
|
|
length(Xs, N) :-
|
|
integer(N),
|
|
N >= 0, !,
|
|
'$skip_max_list'(M, N, Xs, Xs0),
|
|
( Xs0 == [] -> N = M
|
|
; var(Xs0) -> R is N-M, length_rundown(Xs0, R)).
|
|
length(_, N) :-
|
|
integer(N), !,
|
|
domain_error(not_less_than_zero, N, length/2).
|
|
length(_, N) :-
|
|
type_error(integer, N, length/2).
|
|
|
|
length_addendum([], N, N).
|
|
length_addendum([_|Xs], N, M) :-
|
|
M1 is M + 1,
|
|
length_addendum(Xs, N, M1).
|
|
|
|
length_rundown(Xs, 0) :- !, Xs = [].
|
|
length_rundown([_|Xs], N) :-
|
|
N1 is N-1,
|
|
length_rundown(Xs, N1).
|
|
|
|
|
|
member(X, [X|_]).
|
|
member(X, [_|Xs]) :- member(X, Xs).
|
|
|
|
|
|
select(X, [X|Xs], Xs).
|
|
select(X, [Y|Xs], [Y|Ys]) :- select(X, Xs, Ys).
|
|
|
|
|
|
append([], []).
|
|
append([L0|Ls0], Ls) :-
|
|
append(L0, Rest, Ls),
|
|
append(Ls0, Rest).
|
|
|
|
|
|
append([], R, R).
|
|
append([X|L], R, [X|S]) :- append(L, R, S).
|
|
|
|
|
|
memberchk(X, Xs) :- member(X, Xs), !.
|
|
|
|
|
|
reverse(Xs, Ys) :-
|
|
( nonvar(Xs) -> reverse(Xs, Ys, [], Xs)
|
|
; reverse(Ys, Xs, [], Ys)
|
|
).
|
|
|
|
reverse([], [], YsRev, YsRev).
|
|
reverse([_|Xs], [Y1|Ys], YsPreludeRev, Xss) :-
|
|
reverse(Xs, Ys, [Y1|YsPreludeRev], Xss).
|
|
|
|
maplist(_, []).
|
|
maplist(Cont1, [E1|E1s]) :-
|
|
call(Cont1, E1),
|
|
maplist(Cont1, E1s).
|
|
|
|
maplist(_, [], []).
|
|
maplist(Cont2, [E1|E1s], [E2|E2s]) :-
|
|
call(Cont2, E1, E2),
|
|
maplist(Cont2, E1s, E2s).
|
|
|
|
maplist(_, [], [], []).
|
|
maplist(Cont3, [E1|E1s], [E2|E2s], [E3|E3s]) :-
|
|
call(Cont3, E1, E2, E3),
|
|
maplist(Cont3, E1s, E2s, E3s).
|
|
|
|
maplist(_, [], [], [], []).
|
|
maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s]) :-
|
|
call(Cont, E1, E2, E3, E4),
|
|
maplist(Cont, E1s, E2s, E3s, E4s).
|
|
|
|
|
|
maplist(_, [], [], [], [], []).
|
|
maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s], [E5|E5s]) :-
|
|
call(Cont, E1, E2, E3, E4, E5),
|
|
maplist(Cont, E1s, E2s, E3s, E4s, E5s).
|
|
|
|
|
|
maplist(_, [], [], [], [], [], []).
|
|
maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s], [E5|E5s], [E6|E6s]) :-
|
|
call(Cont, E1, E2, E3, E4, E5, E6),
|
|
maplist(Cont, E1s, E2s, E3s, E4s, E5s, E6s).
|
|
|
|
|
|
maplist(_, [], [], [], [], [], [], []).
|
|
maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s], [E5|E5s], [E6|E6s], [E7|E7s]) :-
|
|
call(Cont, E1, E2, E3, E4, E5, E6, E7),
|
|
maplist(Cont, E1s, E2s, E3s, E4s, E5s, E6s, E7s).
|
|
|
|
|
|
maplist(_, [], [], [], [], [], [], [], []).
|
|
maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s], [E5|E5s], [E6|E6s], [E7|E7s], [E8|E8s]) :-
|
|
call(Cont, E1, E2, E3, E4, E5, E6, E7, E8),
|
|
maplist(Cont, E1s, E2s, E3s, E4s, E5s, E6s, E7s, E8s).
|
|
|
|
|
|
sum_list(Ls, S) :-
|
|
foldl(sum_, Ls, 0, S).
|
|
|
|
sum_(L, S0, S) :- S is S0 + L.
|
|
|
|
|
|
|
|
same_length([], []).
|
|
same_length([_|As], [_|Bs]) :-
|
|
same_length(As, Bs).
|
|
|
|
|
|
foldl(Goal_3, Ls, A0, A) :-
|
|
foldl_(Ls, Goal_3, A0, A).
|
|
|
|
foldl_([], _, A, A).
|
|
foldl_([L|Ls], G_3, A0, A) :-
|
|
call(G_3, L, A0, A1),
|
|
foldl_(Ls, G_3, A1, A).
|
|
|
|
|
|
foldl(Goal_4, Xs, Ys, A0, A) :-
|
|
foldl_(Xs, Ys, Goal_4, A0, A).
|
|
|
|
|
|
foldl_([], [], _, A, A).
|
|
foldl_([X|Xs], [Y|Ys], G_4, A0, A) :-
|
|
call(G_4, X, Y, A0, A1),
|
|
foldl_(Xs, Ys, G_4, A1, A).
|
|
|
|
transpose(Ls, Ts) :-
|
|
lists_transpose(Ls, Ts).
|
|
|
|
lists_transpose([], []).
|
|
lists_transpose([L|Ls], Ts) :-
|
|
maplist(same_length(L), Ls),
|
|
foldl(transpose_, L, Ts, [L|Ls], _).
|
|
|
|
transpose_(_, Fs, Lists0, Lists) :-
|
|
maplist(list_first_rest, Lists0, Fs, Lists).
|
|
|
|
list_first_rest([L|Ls], L, Ls).
|
|
|
|
|
|
list_to_set(Ls0, Ls) :-
|
|
maplist(with_var, Ls0, LVs0),
|
|
keysort(LVs0, LVs),
|
|
same_elements(LVs),
|
|
pick_firsts(LVs0, Ls).
|
|
|
|
pick_firsts([], []).
|
|
pick_firsts([E-V|EVs], Fs0) :-
|
|
( V == visited ->
|
|
Fs0 = Fs
|
|
; V = visited,
|
|
Fs0 = [E|Fs]
|
|
),
|
|
pick_firsts(EVs, Fs).
|
|
|
|
with_var(E, E-_).
|
|
|
|
same_elements([]).
|
|
same_elements([EV|EVs]) :-
|
|
foldl(unify_same, EVs, EV, _).
|
|
|
|
unify_same(E-V, Prev-Var, E-V) :-
|
|
( Prev == E ->
|
|
Var = V
|
|
; true
|
|
).
|
|
|
|
|
|
nth0(N, Es, E) :-
|
|
can_be(integer, N),
|
|
can_be(list, Es),
|
|
( integer(N) ->
|
|
nth0_index(N, Es, E)
|
|
; nth0_search(N, Es, E)
|
|
).
|
|
|
|
nth0_index(0, [E|_], E) :- !.
|
|
nth0_index(N, [_|Es], E) :-
|
|
N > 0,
|
|
N1 is N - 1,
|
|
nth0_index(N1, Es, E).
|
|
|
|
nth0_search(N, Es, E) :-
|
|
nth0_search(0, N, Es, E).
|
|
|
|
nth0_search(N, N, [E|_], E).
|
|
nth0_search(N0, N, [_|Es], E) :-
|
|
N1 is N0 + 1,
|
|
nth0_search(N1, N, Es, E).
|
|
|
|
|
|
list_max([N|Ns], Max) :-
|
|
foldl(list_max_, Ns, N, Max).
|
|
|
|
list_max_(N, Max0, Max) :-
|
|
Max is max(N, Max0).
|
|
|
|
list_min([N|Ns], Min) :-
|
|
foldl(list_min_, Ns, N, Min).
|
|
|
|
list_min_(N, Min0, Min) :-
|
|
Min is min(N, Min0).
|