]> Repositorios git - scryer-prolog.git/commitdiff
Compatible Doclog docs for library(lists)
authorAdrián Arroyo Calle <[email protected]>
Tue, 6 Dec 2022 12:19:10 +0000 (13:19 +0100)
committerAdrián Arroyo Calle <[email protected]>
Tue, 6 Dec 2022 12:19:10 +0000 (13:19 +0100)
src/lib/lists.pl

index 4eb204b16760f88d20a0b5b456eb1f266a1326f0..15d9afa0fa58d103fd39cae05c63e59b582fe77f 100644 (file)
@@ -1,3 +1,7 @@
+/**
+List manipulation predicates
+*/
+
 :- 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,
 resource_error(Resource, Context) :-
    throw(error(resource_error(Resource), Context)).
 
+%% length(?Xs, ?N).
+%
+% Relates a list to its length (number of items). It can be used to count the elements of a current list or
+% to create a list full of free variables with N length.
+%
+%     ?- length([a,b,c], 3).
+%        true.
+%     ?- length([a,b,c], N).
+%        N = 3.
+%     ?- length(Xs, 3).
+%        Xs = [_A, _B, _C].
+
 length(Xs0, N) :-
    '$skip_max_list'(M, N, Xs0,Xs),
    !,
@@ -95,28 +111,61 @@ length_addendum([_|Xs], N, M) :-
     M1 is M + 1,
     length_addendum(Xs, N, M1).
 
-
+%% member(?X, ?Xs).
+%
+% Succeeds when X unifies with an item of the list Xs, which can be at any position.
+%
+%     ?- member(X, "hello world").
+%        X = h
+%     ;  ... .
+%
 member(X, [X|_]).
 member(X, [_|Xs]) :- member(X, Xs).
 
-
+%% select(X, Xs0, Xs1).
+%
+% Succeeds when the list Xs1 is the list Xs0 without the item X
+%
+%     ?- select(c, "abcd", X).
+%        X = "abd".
+%
 select(X, [X|Xs], Xs).
 select(X, [Y|Xs], [Y|Ys]) :- select(X, Xs, Ys).
 
-
+%% append(+XsXs, ?Xs).
+%
+% Concatenates a list of lists
+%
+%     ?- append([[1, 2], [3]], Xs).
+%        Xs = [1, 2, 3].
+%
 append([], []).
 append([L0|Ls0], Ls) :-
     append(L0, Rest, Ls),
     append(Ls0, Rest).
 
-
+%% append(Xs0, Xs1, Xs).
+%
+% List Xs is the concatenation of Xs0 and Xs1
+%
+%     ?- append([1,2,3], [4,5,6], Xs).
+%        Xs = [1, 2, 3, 4, 5, 6].
+%
 append([], R, R).
 append([X|L], R, [X|S]) :- append(L, R, S).
 
-
+%% memberchk(?X, +Xs).
+%
+% This predicate is similar to member/2, but it only provides a single answer
 memberchk(X, Xs) :- member(X, Xs), !.
 
-
+%% reverse(?Xs, ?Ys).
+%
+% Xs is the Ys list in reverse order
+%
+%     ?- reverse([1,2,3], [3,2,1]).
+%        true.
+%
 reverse(Xs, Ys) :-
     (  nonvar(Xs) -> reverse(Xs, Ys, [], Xs)
     ;  reverse(Ys, Xs, [], Ys)
@@ -126,62 +175,111 @@ reverse([], [], YsRev, YsRev).
 reverse([_|Xs], [Y1|Ys], YsPreludeRev, Xss) :-
     reverse(Xs, Ys, [Y1|YsPreludeRev], Xss).
 
+%% maplist(+Predicate, ?Xs0).
+%
+% This is a metapredicate that applies predicate to each element of the list Xs0
+%
+%     ?- maplist(write, [1,2,3]).
+%     123   true.
+%
 maplist(_, []).
 maplist(Cont1, [E1|E1s]) :-
     call(Cont1, E1),
     maplist(Cont1, E1s).
 
+%% maplist(+Predicate, ?Xs0, ?Xs1).
+%
+% This is a metapredicate that applies predicate to each element of the lists Xs0 and Xs1.
+%
+%     ?- maplist(length, ["hello", "prolog", "marseille"], Xs1).
+%        Xs1 = [5,6,9].
+%
 maplist(_, [], []).
 maplist(Cont2, [E1|E1s], [E2|E2s]) :-
     call(Cont2, E1, E2),
     maplist(Cont2, E1s, E2s).
 
+%% maplist(+Predicate, ?Xs0, ?Xs1, ?Xs2).
+%
+% This is a metapredicate that applies predicate to each element of the lists Xs0, Xs1 and Xs2.
 maplist(_, [], [], []).
 maplist(Cont3, [E1|E1s], [E2|E2s], [E3|E3s]) :-
     call(Cont3, E1, E2, E3),
     maplist(Cont3, E1s, E2s, E3s).
 
+%% maplist(+Predicate, ?Xs0, ?Xs1, ?Xs2, ?Xs3).
+%
+% This is a metapredicate that applies predicate to each element of the lists Xs0, Xs1, Xs2 and Xs3.
 maplist(_, [], [], [], []).
 maplist(Cont, [E1|E1s], [E2|E2s], [E3|E3s], [E4|E4s]) :-
     call(Cont, E1, E2, E3, E4),
     maplist(Cont, E1s, E2s, E3s, E4s).
 
-
+%% maplist(+Predicate, ?Xs0, ?Xs1, ?Xs2, ?Xs3, ?Xs4).
+%
+% This is a metapredicate that applies predicate to each element of the lists Xs0, Xs1, Xs2, Xs3 and Xs4.
 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(+Predicate, ?Xs0, ?Xs1, ?Xs2, ?Xs3, ?Xs4, ?Xs5).
+%
+% This is a metapredicate that applies predicate to each element of the lists Xs0, Xs1, Xs2, Xs3, Xs4 and Xs5.
 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(+Predicate, ?Xs0, ?Xs1, ?Xs2, ?Xs3, ?Xs4, ?Xs5, ?Xs6).
+%
+% This is a metapredicate that applies predicate to each element of the lists Xs0, Xs1, Xs2, Xs3, Xs4, Xs5 and Xs6.
 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(+Predicate, ?Xs0, ?Xs1, ?Xs2, ?Xs3, ?Xs4, ?Xs5, ?Xs6, ?Xs7).
+%
+% This is a metapredicate that applies predicate to each element of the lists Xs0, Xs1, Xs2, Xs3, Xs4, Xs5, Xs6 and Xs7.
 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(+Xs, -Sum).
+%
+% Takes a lists of numbers and unifies Sum with the result of summing all the elements of the list.
+%
+%     ?- sum_list([2,2,2], 6).
+%        true.
 sum_list(Ls, S) :-
         foldl(lists:sum_, Ls, 0, S).
 
 sum_(L, S0, S) :- S is S0 + L.
 
 
-
+%% same_length(?Xs, ?Ys).
+%
+% Succeeds if Xs and Ys are lists of the same length
 same_length([], []).
 same_length([_|As], [_|Bs]) :-
         same_length(As, Bs).
 
+%% foldl(+Predicate, ?Ls, +A0, ?A).
+%
+% foldl, sometimes called reduce, is a metapredicate that takes a predicate, a list of items
+% and a starting value, and outputs a single value. The predicate _Predicate_ must be able to take the current
+% element of the list, the previous value of the computation and the next value of the computation.
+%
+% For example, if we define sum_ as:
+%
+%     sum_(L, S0, S) :- S is S0 + L.
+%
+% Then we can define sum\_list/2 as the following:
+%
+%     sum_list(Ls, S) :- foldl(sum_, Ls, 0, S).
+%
 
 foldl(Goal_3, Ls, A0, A) :-
         foldl_(Ls, Goal_3, A0, A).
@@ -191,7 +289,9 @@ foldl_([L|Ls], G_3, A0, A) :-
         call(G_3, L, A0, A1),
         foldl_(Ls, G_3, A1, A).
 
-
+%% foldl(+Predicate, ?Ls0, ?Ls1, +A0, ?A).
+%
+% Same as foldl/4 but with an extra list
 foldl(Goal_4, Xs, Ys, A0, A) :-
         foldl_(Xs, Ys, Goal_4, A0, A).
 
@@ -201,6 +301,13 @@ 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).
+%
+% If Ls is a list of lists, Ts contains the transposition
+%
+%     ?- transpose([[1,1],[2,2]], Ts).
+%        Ts = [[1,2],[1,2]].
+%
 transpose(Ls, Ts) :-
         lists_transpose(Ls, Ts).
 
@@ -214,7 +321,13 @@ transpose_(_, Fs, Lists0, Lists) :-
 
 list_first_rest([L|Ls], L, Ls).
 
-
+%% list_to_set(+Ls0, -Set).
+%
+% Takes a list Ls0 and returns a list Set that doesn't contain any repeated element
+%
+%     ?- list_to_set([2,3,4,4,1,2], Set).
+%        Set = [2,3,4,1].
+%
 list_to_set(Ls0, Ls) :-
         maplist(lists:with_var, Ls0, LVs0),
         keysort(LVs0, LVs),
@@ -242,7 +355,12 @@ unify_same(E-V, Prev-Var, E-V) :-
         ;   true
         ).
 
-
+%% nth0(?N, ?Ls, ?E).
+%
+% Succeeds if in the N position of the list Ls, we found the element E. The elements start counting from zero.
+%
+%     ?- nth0(2, [1,2,3,4], 3).
+%        true.
 nth0(N, Es0, E) :-
    nonvar(N),
    '$skip_max_list'(Skip, N, Es0,Es1),
@@ -277,6 +395,12 @@ nth0_el(N0,N, _,E, [E0|Es0]) :-
    N1 is N0+1,
    nth0_el(N1,N, E0,E, Es0).
 
+%% nth1(?N, ?Ls, ?E).
+%
+% Succeeds if in the N position of the list Ls, we found the element E. The elements start counting from one.
+%
+%     ?- nth1(2, [1,2,3,4], 2).
+%        true.
 nth1(N, Es0, E) :-
    N \== 0,
    nth0(N, [_|Es0], E),
@@ -291,6 +415,12 @@ skipn(N0, Es0,Es, Xs0,Xs) :-
    skipn(N1, Es1,Es, Xs1,Xs).
 skipn(0, Es,Es, Xs,Xs).
 
+%% nth0(?N, ?Ls, ?E, ?Rs).
+%
+% Succeeds if in the N position of the list Ls, we found the element E and the rest of the list is Rs. The elements start counting from zero.
+%
+%     ?- nth0(2, [1,2,3,4], 3, [1,2,4]).
+%        true.
 nth0(N, Es0, E, Es) :-
    integer(N),
    N >= 0,
@@ -315,45 +445,54 @@ nth0_elx(N0,N, E0,E, [E1|Es0], [E0|Es]) :-
 
 % p.p.8.5
 
+%% nth1(?N, ?Ls, ?E, ?Rs).
+%
+% Succeeds if in the N position of the list Ls, we found the element E and the rest of the list is Rs. The elements start counting from one.
+%
+%     ?- nth1(2, [1,2,3,4], 2, [1,3,4]).
+%        true.
 nth1(N, Es0, E, Es) :-
    N \== 0,
    nth0(N, [_|Es0], E, [_|Es]),
    N \== 0.
 
-
+%% list_max(+Xs, -Max).
+%
+% Takes a list Xs and unifies with the maximum value of the list
 list_max([N|Ns], Max) :-
     foldl(lists:list_max_, Ns, N, Max).
 
 list_max_(N, Max0, Max) :-
     Max is max(N, Max0).
 
+%% list_min(+Xs, -Min).
+%
+% Takes a list Xs and unifies with the minimum value of the list
 list_min([N|Ns], Min) :-
     foldl(lists:list_min_, Ns, N, Min).
 
 list_min_(N, Min0, Min) :-
     Min is min(N, Min0).
 
-% permutation(?Xs, ?Ys) is nondet.
+%% permutation(?Xs, ?Ys) is nondet.
 %
-%   True when Xs is a permutation of Ys. This can solve for Ys given
-%   Xs or Xs given Ys, or  even   enumerate  Xs and Ys together. The
-%   predicate  permutation/2  is  primarily   intended  to  generate
-%   permutations. Note that a list of  length N has N! permutations,
-%   and  unbounded  permutation  generation   becomes  prohibitively
-%   expensive, even for rather short lists (10! = 3,628,800).
+% True when Xs is a permutation of Ys. This can solve for Ys given
+% Xs or Xs given Ys, or  even   enumerate  Xs and Ys together. The
+% predicate  permutation/2  is  primarily   intended  to  generate
+% permutations. Note that a list of  length N has N! permutations,
+% and  unbounded  permutation  generation   becomes  prohibitively
+% expensive, even for rather short lists (10! = 3,628,800).
 %
-%   The example below illustrates that Xs   and Ys being proper lists
-%   is not a sufficient condition to use the above replacement.
+% The example below illustrates that Xs   and Ys being proper lists
+% is not a sufficient condition to use the above replacement.
 %
-%     ==
 %     ?- permutation([1,2], [X,Y]).
-%     X = 1, Y = 2 ;
-%     X = 2, Y = 1 ;
-%     false.
-%     ==
+%        X = 1, Y = 2
+%     ;  X = 2, Y = 1
+%     ;  false.
 %
-%   @error  type_error(list, Arg) if either argument is not a proper
-%           or partial list.
+%   Throws type\_error(list, Arg) if either argument is not a proper
+%   or partial list.
 
 permutation(Xs, Ys) :-
     '$skip_max_list'(Xlen, _, Xs, XTail),