siguiente anterior arriba atrasadelante (solo si previamente se ha ido
atras)

A.2.3. Operaciones con listas

El tipo lista (Apartado A.1.2) es una forma muy general y muy flexible para estructurar datos. Enseguida lo veremos con un ejemplo, pero presentaremos antes algunas definiciones de predicados sobre listas que son de utilidad general (a cada definición le siguen algunos ejemplos de consultas):

Primer elemento de una lista
 primero([X|Cola],X).

(Recuérdese que la notación «[X|Cola]» indica una lista cuya cabeza es el elemento «X» y cuya cola es la lista «Cola» , que puede contener cualquier número de elementos, o ser vacía. En lugar de «Cola» podríamos haber utilizado cualquier otro nombre de variable, como «Y» , «L» , etc.).

El predicado será verdadero cuando X tenga el mismo valor en cada una de sus apariciones:

 ?- primero([1,2,3],1).  
 YES  
 
 ?- primero([a|L],b).  
 NO  
 
 ?- primero([c,b,d,e,a],X).  
 X=c  
 
 ?- primero([X,b],a).  
 X=a  
 
 ?- primero([],X).  
 NO

Último elemento de una lista
 ultimo([X],X).  
 ultimo([Y|Z],X) :- ultimo(Z,X).

(Es decir, si la lista sólo contiene un elemento, ése es el último. Si contiene más entonces tiene una cabeza y una cola, y el último es el último de la cola; de este modo, tenemos una definición recursiva).

 ?- ultimo([c,b,d,e,a],X).  
 X=a  
 
 ?- ultimo([a,X],b).  
 X=b  
 
 ?- ultimo([],X).  
 NO

Miembro de una lista
 miembro([X|Y],X).  
 miembro([Y|Z],X) :- miembro(Z,X).

(Un miembro de una lista es o bien su cabeza o bien un miembro de su cola).

 ?- miembro([c,b,d,e,a],X).  
 X=c  
 X=b  
 X=d  
 X=e  
 X=a

Concatenación de dos listas

Este es un caso algo más complicado. Se trata de definir un predicado, «concatena(L1,L2,L3)» , tal que sea verdadero si la lista L3 es el resultado de incluir los elementos de L2 a continuación de los de L1. En el caso particular de que L1 sea vacía, L3 es simplemente igual a L2:

  concatena([],L,L).

Si no es así, podemos asegurar que L3 tendrá la misma cabeza que L1, y que su cola se obtendrá concatenando la cola de L1 con L2:

 concatena([X|CL1],L2,[X|CL3])  
            :- concatena(CL1,L2,CL3).

Las dos reglas definen completamente la relación. Con ellas podemos hacer consultas como:

 ?- concatena([a,b],[b,c,d],X).  
 X=[a,b,b,c,d]  
 
 ?- concatena(X,[3,4],[1,2,3,4]).  
 X=[1,2]

Inversa de una lista
 inversa([],[]).  
 inversa([X|CL],Linv) :-  
      inversa(CL,CLinv),concatena(CLinv,[X],Linv).

(La inversa de una lista vacía es ella misma. La inversa de una lista es igual al resultado de concatenar la inversa de su cola con su cabeza).

 ?- inversa([1,2,3],X).  
 X=[3,2,1]

Permutación de una lista

Una permutación de una lista L1 es otra lista L2 con los mismos elementos de L1 en un orden diferente. Si la lista es vacía, o si consta de un solo elemento, su única permutación es ella misma. Si tiene varios elementos, sus permutaciones resultan de extraer un elemento, permutar el resto y colocar el elemento extraido a la cabeza de esta permutación, repitiendo esto para todos los elementos.

Definamos primero un predicado, «menos_elem(X,L1,L2)» , tal que si X es un elemento de L1, L2 es la misma lista L1 a la que se le ha quitado X. Si el elemento es la cabeza de L1, L2 será la cola, y si no, será igual a la resultante de extraer el elemento de la cola de L1; estas dos reglas tratan ambas situaciones:

 menos_elem(X,[X|L],L).  
 menos_elem(X,[C|L],[C|LX]) :- menos_elem(X,L,LX).

Podemos ahora definir «permutacion(L1,L2)» (L2 es una permutación de L1) así:

 permutacion([],[]).  
 permutacion(L,[C|CL1]) :- menos_elem(C,L,LC),  
                          permutacion(LC,CL1).

(No es necesario declarar «permutacion([X],[X]).» : el caso de que la lista sólo tenga un elemento está ya incluido en la regla recursiva, con CL1=[]).

 ?- permutacion([a,b,c],X).  
 X=[a,b,c]  
 X=[a,c,b]  
 X=[b,a,c]  
 X=[b,c,a]  
 X=[c,a,b]  
 X=[c,b,a]


siguiente
anterior arriba atrasadelante (sólo si previamente se ha ido atras)


algunos derechos reservados DIT-ETSIT-UPM
Portada