• No se han encontrado resultados

Rafael Cadenas

In document Poetas venezolanos (página 83-95)

Most list operations are defined in the librarylistsdescribed in sectionA.15. Some that are imple- mented with more low-level primitives are built-in and described here.

is list(+Term)

True ifTermis bound to the empty list ([]) or a term with functor ‘’[|]’’85and arity 2 and the second argument is a list.86 This predicate acts as if defined by the definition below on acyclicterms. The implementationfailssafely ifTermrepresents a cyclic list.

is_list(X) :- var(X), !, fail. is_list([]). 83

The limitations of the underlying (GMP) library are unknown, which makes it impossible to validate theState.

84

BUG: GMP provides no portable mechanism to fetch and restore the state. The current implementation works, but the state depends on the platform. I.e., it is generally not possible to reuse the state with another version of GMP or on a CPU with different datasizes or endian-ness.

85The traditional list functor is the dot (’.’). This is still the case of the command line option--traditionalis

given. See also section5.1.

86

In versions before 5.0.1,is list/1just checked for[]or[ | ]andproper list/1had 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-dirtyis list/1is a good choice. Richard O’Keefe pointed at this issue.

4.29. BUILT-IN LIST OPERATIONS 187

is_list([_|T]) :- is_list(T).

memberchk(?Elem, +List) [semidet]

True when Elemis an element ofList. This ‘chk’ variant ofmember/2is semi deterministic and typically used to test membership of a list. Raises atypeerror if scanningListencounters a non-list. Note that memberchk/2 does not perform a full list typecheck. For example, memberchk(a, [a|b])succeeds without error. IfListis cyclic andElemis not a member ofList,memberchk/2eventually raises atypeerror.87

length(?List, ?Int) [ISO]

True if Int 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 Int. The predicate is non-deterministic, producing lists of increasing length ifListis a partial listand Intis unbound. It raises errors if

• Intis bound to a non-integer. • Intis a negative integer.

• Listis neither a list nor a partial list. This error condition includes cyclic lists.88 This predicate fails if the tail ofListis equivalent toInt(e.g.,length(L,L)).89

sort(+List, -Sorted) [ISO]

True if Sorted can be unified with a list holding the elements of List, sorted to the standard order of terms (see section 4.7). Duplicates are removed. The implementation is in C, using natural merge sort.90 The sort/2 predicate can sort a cyclic list, returning a non-cyclic version with the same elements.

sort(+Key, +Order, +List, -Sorted)

True whenSortedcan be unified with a list holding the element ofList. Keydetermines which part of each element inListis used for comparing two term andOrder describes the relation between each set of consecutive elements inSorted.91

IfKeyis the integer zero (0), the entire term is used to compare two elements. UsingKey=0 can be used to sort arbitrary Prolog terms. Other values forKeycan only be used with compound terms or dicts (see section5.4). An integer key extracts theKey-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.

87

Eventuallyhere means it will scan as many elements as the longest list that may exist given the current stack usage before raising the exception.

88

ISO demands failure here. We think an error is more appropriate.

89

This 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.

90

Contributed by Richard O’Keefe.

91

The definition of this predicate was established after discussion with Joachim Schimpf from the ECLiPSe team. ECLiPSe currently only accepts<,=<, >and>=for theOrderargument but this is likely to change. SWI-Prolog ex- tends this predicate to deal with dicts.

Deeper nested elements of structures can be selected by using a list of keys for theKeyargument. TheOrderargument is described in the table below92

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 inSorted.

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 fromcsv read file/2) ascending on the 3th column and descending on the 4th column:

sort(4, @>=, Rows0, Rows1), sort(3, @=<, Rows1, Sorted).

See alsosort/2(ISO),msort/2,keysort/2,predsort/3andorder by/2. msort(+List, -Sorted)

Equivalent to sort/2, but does not remove duplicates. Raises a type error if Listis a cyclic list or not a list.

keysort(+List, -Sorted) [ISO]

Sort a list ofpairs.Listmust be a list ofKey-Valuepairs, terms whose principal functor is (-)/2. Listis sorted onKeyaccording to the standard order of terms (see section4.7.1). Duplicates are notremoved. Sorting isstablewith regard to the order of theValues, i.e., the order of multiple elements that have the sameKeyis not changed.

The keysort/2predicate is often used together with librarypairs. 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).

In document Poetas venezolanos (página 83-95)