1:- encoding(utf8).
    2:- module(
    3  list_ext,
    4  [
    5    common_subsequence/2,      % +Subsequences, -Subsequence
    6    empty_list/1,              % ?L
    7    first/2,                   % ?L, ?Elem
    8    inflist/2,                 % +Elem, -L
    9    list_intersperse/3,        % +L1, +Separator, -L2
   10    list_truncate/3,           % +Whole, +MaxLength, -Part
   11    max_list/3,                % +L, -Max, +Zero
   12    member/3,                  % ?X, ?Y, +L
   13    min_list/3,                % +L, -Min, +Zero
   14    postfix/2,                 % ?Part, ?Whole
   15    postfix/3,                 % ?Part, ?Length, ?Whole
   16   %prefix/2,                  % ?Part, ?Whole
   17    prefix/3,                  % ?Part, ?Length, ?Whole
   18    remove_initial_members/3,  % +List1, +Members, -List2
   19    remove_trailing_members/3, % +List1, +Members, -List2
   20    repeating_list/1,          % ?L
   21    repeating_list/2,          % ?Elem, ?L
   22    repeating_list/3,          % ?Elem, ?N, ?L
   23    singleton_list/2,          % ?X, ?L
   24    substring/2,               % ?Substring, +String
   25    subsequence/2              % ?Subsequence, ?Sequence
   26  ]
   27).   28:- reexport(library(lists)).

Extended support for lists

Extends the list support that is provided by the SWI-Prolog standard library.

*/

   37:- use_module(library(apply)).
 common_subsequence(+Subsequences:list(list), -Subsequence:list) is nondet
   45common_subsequence(Xss, Xs) :-
   46  maplist(subsequence(Xs), Xss).
 empty_list(+L:list) is semidet
empty_list(-L:list) is det
   53empty_list([]).
 first(?L, ?Elem) is semidet
   59first([H|_], H).
 inflist(+Elem, -L:list) is det
Lazy-lists containing an infinitely re-occurring element.

Example of use

?- inflist(0, L), append([A,B,C,D,E,F|_], _, L).
L = [0, 0, 0, 0, 0, 0|_G29924368],
A = B, B = C, C = D, D = E, E = F, F = 0,
freeze(_G29924368, list_ext: (_G29924368=[0|_G29924422], inflist(0, _G29924422)))
See also
- Based on a StackOverflow answer by Michael Hendricks.
   80inflist(X, L) :-
   81  freeze(L, (
   82    L = [X|T],
   83    inflist(X, T)
   84  )).
 list_intersperse(+L1:list, +Separator:term, -L2:list)// is det
Returns a list that is based on the given list, but interspersed with copies of the separator term.

If the length of the given list is n, then the length of the new list is `2n - 1 for n > 0`.

   96list_intersperse([], _, []) :- !.
   97list_intersperse([H], _, [H]) :- !.
   98list_intersperse([H|T1], Sep, [H,Sep|T2]) :-
   99  list_intersperse(T1, Sep, T2).
  100
  101
  102
  103%! list_truncate(+Whole:list, +MaxLength:or([oneof([∞]),nonneg]),
  104%!               -Part:list) is det.
  105%
  106% Returns the truncated version of the given list.  The maximum length
  107% indicates the exact maximum.  Truncation will always result in a
  108% list which contains at most `MaxLength' elements.
  109
  110list_truncate(Whole, ∞, Whole):- !.
  111% The list does not have to be truncated, it is not that long.
  112list_truncate(Whole, MaxLength, Whole) :-
  113  length(Whole, Length),
  114  Length =< MaxLength, !.
  115% The list exceeds the maximum length, it is truncated.
  116list_truncate(Whole, MaxLength, Part) :-
  117  prefix(Part, MaxLength, Whole).
 max_list(+L:list(number), -Max:number, +Zero:number) is det
  123max_list([], Zero, Zero) :- !.
  124max_list(L, Max, _) :-
  125  max_list(L, Max).
 member(?X:term, ?Y:term, +L:list(term)) is nondet
  131member(X, Y, L) :-
  132  member(X, L),
  133  member(Y, L).
 min_list(+L:list(number), -Min:number, +Zero:number) is det
  139min_list([], Zero, Zero) :- !.
  140min_list(L, Min, _) :-
  141  min_list(L, Min).
 postfix(?Part:list, ?Whole:list) is nondet
 postfix(?Part:list, ?N:nonneg, ?Whole:list) is nondet
Part is the length-N postfix of Whole.
  150postfix(Part, Whole) :-
  151  postfix(Part, _, Whole).
  152
  153
  154postfix(Part, Length, Whole) :-
  155  length(Part, Length),
  156  append(_, Part, Whole).
 prefix(?Part:list, ?Length:nonneg, ?Whole:list) is det
Shorter prefixes are generated first.
  164prefix(Part, Length, Whole) :-
  165  length(Part, Length),
  166  append(Part, _, Whole).
 remove_initial_members(+List1:list(term), +Members:list(term), -List2:list(term)) is det
  174remove_initial_members([H|T1], Xs, T2) :-
  175  memberchk(H, Xs), !,
  176  remove_initial_members(T1, Xs, T2).
  177remove_initial_members(L, _, L).
 remove_trailing_members_(+List1:list(term), +Members:list(term), -List2:list(term)) is det
  185remove_trailing_members(L1, Xs, L2) :-
  186  reverse(L1, L1Rev),
  187  remove_initial_members(L1Rev, Xs, L2Rev),
  188  % @bug: reverse(+,?) and reverse(?,+) should be deterministic
  189  once(reverse(L2, L2Rev)).
 repeating_list(+L:list) is semidet
repeating_list(-L:list) is multi
  196repeating_list(L) :-
  197  repeating_list(_, _, L).
 repeating_list(+Elem, +L:list) is semidet
repeating_list(+Elem, -L:list) is multi
repeating_list(-Elem, +L:list) is semidet
repeating_list(-Elem, -L:list) is multi
  205repeating_list(Elem, L) :-
  206  repeating_list(Elem, _, L).
 repeating_list(+Elem, +N:nonneg, +L:list) is semidet
repeating_list(+Elem, +N:nonneg, -L:list) is det
repeating_list(+Elem, -N:nonneg, +L:list) is semidet
repeating_list(-Elem, +N:nonneg, +L:list) is semidet
repeating_list(+Elem, -N:nonneg, -L:list) is multi
repeating_list(-Elem, +N:nonneg, -L:list) is det
repeating_list(-Elem, -N:nonneg, +L:list) is det
repeating_list(-Elem, -N:nonneg, -L:list) is multi
Succeeds for lists L that repeat term Elem exactly N times.
  220repeating_list(Elem, N, L) :-
  221  length(L, N),
  222  maplist(=(Elem), L).
 singleton_list(+X, +L) is semidet
singleton_list(+X, -L) is det
singleton_list(-X, +L) is det
singleton_list(-X, -L) is det
  231singleton_list(X, [X]).
 substring(?Substring:list, +String:list) is nondet
Returns substrings of the given string. Construction proceeds from smaller to greater substrings.

`[1,3]' is not a substring of `[1,2,3]', but it is a subsequence.

  242substring([], _).
  243substring(Ys, Xs) :-
  244  Ys = [_|_],
  245  append(_, Zs, Xs),
  246  append(Ys, _, Zs).
 subsequence(?Subsequence:list, ?Sequence:list) is nondet
Returns substrings of the given string. Construction proceeds from smaller to greater subsequences.
  255subsequence([], []).
  256subsequence(L, [_|T]) :-
  257  subsequence(L, T).
  258subsequence([H|T2], [H|T1]) :-
  259  subsequence(T2, T1)