This repository has been archived on 2023-08-20. You can view files and clone it, but cannot push or open issues or pull requests.
yap-6.3/pl/lists.yap

142 lines
3.4 KiB
Plaintext
Raw Normal View History

2015-12-15 09:05:24 +00:00
/**
* @file pl/lists.yap
* @author VITOR SANTOS COSTA <vsc@VITORs-MBP.lan>
* @date Thu Nov 19 09:54:00 2015
2016-01-03 02:06:09 +00:00
*
* @brief core list operations
*
2015-12-15 09:05:24 +00:00
* @ingroup lists
* @{
*/
2013-11-26 09:40:00 +00:00
2014-04-09 12:39:29 +01:00
:- system_module( '$_lists', [], []).
2015-06-19 01:12:05 +01:00
:- set_prolog_flag(source, true). % source.
2013-11-26 09:40:00 +00:00
% memberchk(+Element, +Set)
% means the same thing, but may only be used to test whether a known
% Element occurs in a known Set. In return for this limited use, it
% is more efficient when it is applicable.
2016-01-03 02:06:09 +00:00
/** @pred memberchk(+ _Element_, + _Set_)
2014-09-11 20:06:57 +01:00
As member/2, but may only be used to test whether a known
_Element_ occurs in a known Set. In return for this limited use, it
is more efficient when it is applicable.
2016-01-03 02:06:09 +00:00
2014-09-11 20:06:57 +01:00
*/
lists:memberchk(X,[X|_]) :- !.
lists:memberchk(X,[_|L]) :-
lists:memberchk(X,L).
2016-01-03 02:06:09 +00:00
%% member(?Element, ?Set)
% is true when Set is a list, and Element occurs in it. It may be used
% to test for an element or to enumerate all the elements by backtracking.
% Indeed, it may be used to generate the Set!
2016-01-03 02:06:09 +00:00
/** @pred member(? _Element_, ? _Set_)
2014-09-11 20:06:57 +01:00
True when _Set_ is a list, and _Element_ occurs in it. It may be used
to test for an element or to enumerate all the elements by backtracking.
2016-01-03 02:06:09 +00:00
2014-09-11 20:06:57 +01:00
*/
lists:member(X,[X|_]).
lists:member(X,[_|L]) :-
lists:member(X,L).
2016-01-03 02:06:09 +00:00
2015-10-22 12:01:20 +01:00
%% @pred identical_member(?Element, ?Set) is nondet
%
% identical_member holds true when Set is a list, and Element is
2016-01-03 02:06:09 +00:00
% exactly identical to one of the elements that occurs in it.
2015-10-22 12:01:20 +01:00
lists:identical_member(X,[Y|M]) :-
(
X == Y
;
M \= [], lists:identical_member(X,M)
).
2016-01-03 02:06:09 +00:00
/** @pred append(? _List1_,? _List2_,? _List3_)
2014-09-11 20:06:57 +01:00
Succeeds when _List3_ unifies with the concatenation of _List1_
and _List2_. The predicate can be used with any instantiation
pattern (even three variables).
2016-01-03 02:06:09 +00:00
2014-09-11 20:06:57 +01:00
*/
lists:append([], L, L).
lists:append([H|T], L, [H|R]) :-
lists:append(T, L, R).
2015-08-18 21:08:52 +01:00
:- set_prolog_flag(source, false). % :- no_source.
2014-04-09 12:39:29 +01:00
% lists:delete(List, Elem, Residue)
% is true when List is a list, in which Elem may or may not occur, and
% Residue is a copy of List with all elements identical to Elem lists:deleted.
2016-01-03 02:06:09 +00:00
/** @pred delete(+ _List_, ? _Element_, ? _Residue_)
2014-09-11 20:06:57 +01:00
2015-06-19 01:12:05 +01:00
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
2014-09-11 20:06:57 +01:00
True when _List_ is a list, in which _Element_ may or may not
occur, and _Residue_ is a copy of _List_ with all elements
identical to _Element_ deleted.
2016-01-03 02:06:09 +00:00
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
2014-09-11 20:06:57 +01:00
*/
2014-04-09 12:39:29 +01:00
lists:delete([], _, []).
lists:delete([Head|List], Elem, Residue) :-
Head == Elem, !,
lists:delete(List, Elem, Residue).
lists:delete([Head|List], Elem, [Head|Residue]) :-
lists:delete(List, Elem, Residue).
2015-06-19 01:12:05 +01:00
:- set_prolog_flag(source, false). % disable source.
2014-04-09 12:39:29 +01:00
2015-12-15 09:05:24 +00:00
% length of a list.
/** @pred length(? _L_,? _S_)
Unify the well-defined list _L_ with its length. The procedure can
be used to find the length of a pre-defined list, or to build a list
of length _S_.
*/
prolog:length(L, M) :-
'$skip_list'(L, M, M0, R),
( var(R) -> '$$_length'(R, M, M0) ;
R == []
).
2015-12-15 09:04:47 +00:00
%
2015-12-15 09:05:24 +00:00
% in case A1 is unbound or a difference list, things get tricky
%
'$$_length'(R, M, M0) :-
( var(M) -> '$$_length1'(R,M,M0)
; M >= M0 -> '$$_length2'(R,M,M0) ).
%
% Size is unbound, generate lists
%
'$$_length1'([], M, M).
'$$_length1'([_|L], O, N) :-
M is N + 1,
'$$_length1'(L, O, M).
%
% Size is bound, generate single list
%
'$$_length2'(NL, O, N) :-
( N =:= O -> NL = [];
M is N + 1, NL = [_|L], '$$_length2'(L, O, M) ).
%% @}