- Documentation
- Reference manual
- Built-in Predicates
- Notation of Predicate Descriptions
- Character representation
- Loading Prolog source files
- Editor Interface
- Verify Type of a Term
- Comparison and Unification of Terms
- Control Predicates
- Meta-Call Predicates
- Delimited continuations
- Exception handling
- Printing messages
- Handling signals
- DCG Grammar rules
- Database
- Declaring predicate properties
- Examining the program
- Input and output
- Status of streams
- Primitive character I/O
- Term reading and writing
- Analysing and Constructing Terms
- Analysing and Constructing Atoms
- Localization (locale) support
- Character properties
- Operators
- Character Conversion
- Arithmetic
- Misc arithmetic support predicates
- Built-in list operations
- Finding all Solutions to a Goal
- Forall
- Formatted Write
- Global variables
- Terminal Control
- Operating System Interaction
- File System Interaction
- User Top-level Manipulation
- Creating a Protocol of the User Interaction
- Debugging and Tracing Programs
- Obtaining Runtime Statistics
- Execution profiling
- Memory Management
- Windows DDE interface
- Miscellaneous
- Built-in Predicates
- Packages
- Reference manual
4.29 Built-in list operations
Most list operations are defined in the library library(lists)
described in section A.21.
Some that are implemented with more low-level primitives are built-in
and described here.
- is_list(+Term)
- True if Term is bound to the empty list (
) or a compound term with name‘[]
’125The traditional list functor name is the dot ([|]
’.'
). This is still the case of the command line option --traditional is given. See also section 5.1. and arity 2 and the second argument is a list.126In versions before 5.0.1, is_list/1 just checked for
or[]
[_|_]
and proper_list/1 had the role of the current is_list/1. The current definition conforms to the de facto standard. Assuming proper coding standards, there should only be very few cases where a quick-and-dirty is_list/1 is a good choice. Richard O'Keefe pointed at this issue. This predicate acts as if defined by the definition below on acyclic terms. The implementation safely fails if Term represents a cyclic list.is_list(X) :- var(X), !, fail. is_list([]). is_list([_|T]) :- is_list(T).
- [semidet]memberchk(?Elem, +List)
- True when Elem is an element of List. This‘chk'
variant of
member/2
is semi deterministic and typically used to test membership of a list.
Raises a
type
error if scanning List encounters a non-list. Note that memberchk/2 does not perform a full list typecheck. For example,memberchk(a, [a|b])
succeeds without error. If List is cyclic and Elem is not a member of List, memberchk/2 eventually raises atype
error.127Eventually here means it will scan as many elements as the longest list that may exist given the current stack usage before raising the exception. - [ISO]length(?List, ?Length)
- True if Length represents the number of elements in List.
This predicate is a true relation and can be used to find the length of
a list or produce a list (holding variables) of length Length.
The predicate is non-deterministic, producing lists of increasing length
if
List is a partial list and Length is a
variable.
?- length(List,4). List = [_27940,_27946,_27952,_27958]. ?- length(List,Length). List = [], Length = 0 ; List = [_24698], Length = 1 ; List = [_24698,_25826], Length = 2 ...
It raises errors if Length is bound to a non-integer or a negative integer or if List is neither a list nor a partial list. This error condition includes cyclic lists:128ISO demands failure here. We think an error is more appropriate.
?- A=[1,2,3|A], length(A,L). ERROR: Type error: `list' expected ...
Covering an edge case, the predicate fails if the tail of List is equivalent to Length:129This is logically correct. An exception would be more appropriate, but to our best knowledge, current practice in Prolog does not describe a suitable candidate exception term.
?- List=[1,2,3|Length],length(List,Length). false. ?- length(Length,Length). false.
- [ISO]sort(+List, -Sorted)
- True if Sorted can be unified with a list holding the
elements of List, sorted to the standard order of terms (see
section 4.6). Duplicates
are removed. The implementation is in C, using natural merge sort.130Contributed
by Richard O'Keefe. The sort/2
predicate can sort a cyclic list, returning a non-cyclic version with
the same elements.
Note that List may contain non-ground terms. If Sorted is unbound at call-time, for each consecutive pair of elements in Sorted, the relation
E1 @< E2
will hold. However, unifying a variable in Sorted may cause this relation to become invalid, even unifying a variable in Sorted with another (older) variable. See also section 4.6.1. - sort(+Key, +Order, +List, -Sorted)
- True when Sorted can be unified with a list holding the
element of
List. Key determines which part of each element in
List is used for comparing two term and Order
describes the relation between each set of consecutive elements in
Sorted.131The
definition of this predicate was established after discussion with
Joachim Schimpf from the ECLiPSe team. ECLiPSe currently only accepts
,<
,=<
and>
for the Order argument but this is likely to change. SWI-Prolog extends this predicate to deal with dicts.>=
If Key is the integer zero (0), the entire term is used to compare two elements. Using Key=0 can be used to sort arbitrary Prolog terms. Other values for Key can only be used with compound terms or dicts (see section 5.4). An integer key extracts the Key-th argument from a compound term. An integer or atom key extracts the value from a dict that is associated with the given key. A type_error is raised if the list element is of the wrong type and an existence_error is raised if the compound has not enough argument or the dict does not contain the requested key.
Deeper nested elements of structures can be selected by using a list of keys for the Key argument.
The Order argument is described in the table below:132For compatibility with ECLiPSe, the values
,<
,=<
and>
are allowed as synonyms.>=
Order Ordering Duplicate handling @<
ascending remove @=<
ascending keep @>
descending remove @>=
descending keep The sort is stable, which implies that, if duplicates are kept, the order of duplicates is not changed. If duplicates are removed, only the first element of a sequence of duplicates appears in Sorted.
This predicate supersedes most of the other sorting primitives, for example:
sort(List, Sorted) :- sort(0, @<, List, Sorted). msort(List, Sorted) :- sort(0, @=<, List, Sorted). keysort(Pairs, Sorted) :- sort(1, @=<, Pairs, Sorted).
The following example sorts a list of rows, for example resulting from csv_read_file/2) ascending on the 3th column and descending on the 4th column:
sort(4, @>=, Rows0, Rows1), sort(3, @=<, Rows1, Sorted).
See also sort/2 (ISO), msort/2, keysort/2, predsort/3 and order_by/2.
- msort(+List, -Sorted)
- Equivalent to sort/2,
but does not remove duplicates. Raises a
type_error
if List is a cyclic list or not a list. - [ISO]keysort(+List, -Sorted)
- Sort a list of pairs. List must be a list of
Key-Value
pairs, terms whose principal functor is (-)/2. List is sorted on Key according to the standard order of terms (see section 4.6.1). Duplicates are not removed. Sorting is stable with regard to the order of the Values, i.e., the order of multiple elements that have the same Key is not changed.The keysort/2 predicate is often used together with library
library(pairs)
. It can be used to sort lists on different or multiple criteria. For example, the following predicates sorts a list of atoms according to their length, maintaining the initial order for atoms that have the same length.:- use_module(library(pairs)). sort_atoms_by_length(Atoms, ByLength) :- map_list_to_pairs(atom_length, Atoms, Pairs), keysort(Pairs, Sorted), pairs_values(Sorted, ByLength).
- predsort(+Pred, +List, -Sorted)
- Sorts similar to sort/2,
but determines the order of two terms by calling Pred(-Delta,
+E1, +E2) . This call must unify Delta
with one of
,<
or>
. Duplicates are removed (i.e. equivalence classes of elements as defined by Pred are collapsed to a single element in Sorted) If the built-in predicate compare/3 is used, the result is the same as sort/2. See also keysort/2.=