You are on page 1of 15

INTRODUCCIN

PROLOG es un lenguaje declarativo e interpretado, en este tipo de lenguajes se


representan los conocimientos sobre un determinado dominio y sus relaciones. A
partir de ese conocimiento, se deducen las respuestas a las cuestiones
planteadas, es decir se obtiene una inferencia.
El dominio lo constituye un conjunto de objetos. El conocimiento se formaliza
mediante un conjunto de relaciones que describen de forma simultnea las
propiedades y sus interacciones.

OPERADORES
Son predicados predefinidos en Prolog para las operaciones matemticas bsicas.
Su sintaxis depende de la posicin que ocupen, pudiendo ser infijos o prefijos. Por
ejemplo el operador suma ("+"), podemos encontrarlo en forma prefija + (2,5) o
bien infija, '2 + 5'.
Tambin dispone de predicados de igualdad y desigualdad:
X = Y igual; X \= Y distinto; X < Y menor; X > Y mayor; X =< Y menor o igual;
X >= Y mayor o igual.
Al igual que en otros lenguajes de programacin es necesario tener en cuenta la
asociatividad de los operadores antes de trabajar con ellos, Por ejemplo, 3+2*6 =
3 + (2*6).
is.
Es un operador infijo, que en su parte derecha lleva un trmino que se interpreta
como una expresin aritmtica, contrastndose con el trmino de su izquierda.
Por ejemplo, la expresin 6 is 4+3 es falsa. Por otra parte, si la expresin es '6 is
4+2, ser verdadera. Y si la expresin se define de la siguiente manera X is 4+3.'
el resultado ser la instanciacin de X: X = 7
consult.
El predicado consult est pensado para leer y compilar un programa Prolog o bien
para las situaciones en las que se precise aadir las clusulas existentes en un
determinado fichero a las que ya estn almacenadas y compiladas en la base de
datos. Su sintaxis puede ser una de las siguientes:

consult(fichero); consult(fichero.ext); consult(c:\ia\prolog\fichero).


recon.
El predicado recon es muy parecido a consult, con la salvedad de que las
clusulas existentes en el fichero consultado, reemplazan a las existentes en la
base de hechos. Su sintaxis es la misma que la de consult.
forget.
Tiene como fin eliminar de la base de datos actual aquellos hechos consultados de
un fichero determinado. Su sintaxis es: forget(fichero).
exitsys.
Este predicado nos devuelve al sistema operativo.
corte.
El operador corte, representado por el smbolo "!" nos da un cierto control sobre el
mecanismo de deduccin del Prolog. Su funcin es la de controlar el proceso de
reevaluacin, limitndolo a los hechos que nos interesen. Supongamos la
siguiente regla:
regla :- hecho1, hecho2, !, hecho3, hecho4, hecho5.
Prolog efecta reevaluaciones entre los hechos 1, 2 sin ningn problema, hasta
que se satisface el hecho2. En ese momento se alcanza el hecho3, pudiendo
haber a continuacin reevaluaciones de los hechos 3, 4 y 5. Sin embargo, si el
hecho3 fracasa, no se intentar de ninguna forma reevaluar el hecho2.
Escribir trminos en la forma funcion(arg1,arg2,...) no es frecuentemente
apropiado desde el punto de vista humano. Slo compara las siguientes dos
transcripciones de la misma clusula PROLOG:

p(X,Z) :- q(X,Y),r(Y,Z),s(Z).
' :- '(p(X,Z),(','(q(X,Y),','(r(Y,Z),s(Z))))).
Los Operadores son usados con trminos binarios y unarios solamente. Ellos
permiten colocar la localizacin de la funcin (prefijo, infijo, posfijo), la
caracterstica asociativa y, finalmente, la prioridad entre operadores.
op(Prioridad, Apariencia, Nombre)
|

-- xfy, yfx, xfx, fx, fy, xf, yf

El nmero ms alto tiene la prioridad ms baja.


DECLARACIN DE OPERADORES
Utilizacin de un predicado predefinido:
?-op(Precedencia, tipo, nombre).
?- op(500, yfx, por)
Yes
?-X=a por b
X= a por b
Precedencia [1,1200] y depende de implementaciones.
Tipo:
Aridad
Notacin o posicin
Infijo: xfy, yfx, xfx, yfy (f representa operador; x e y operandos)
Prefijo: fx, fy
Sufijo: xf, yt
Asociatividad
y

indica que el argumento puede contener operadores de igual o menor

precedencia.
x obliga a que sea estrictamente menor.
Ejemplo: + declarado como yfx

a + b + c: a+(b + c) (a + b)+ c
La primera opcin queda eliminada porque el segundo argumento no puede
contener un operador de precedencia igual.
Esto se conoce como asociatividad por la izquierda (yfx), por la derecha (xfy) o
indistintamente (xfx); segn esto, no tendr sentido (yfy).

Operadores definidos
Se puede saber si un operador est definido y cmo?
current_op(?Precedencia, ?Tipo, ?Nombre)
Es verdadero si el operador Nombre est definido como operador de tipo Tipo con
precedencia Precedencia
Ejemplo:
?- current_op(Precedencia, Tipo, \+).
Precedencia = 900
Tipo = fy
True
Ver todos los operadores definidos:
?- current_op(Precedencia, Tipo, Operador).

Operadores predefinidos
Puede tener efectos laterales al satisfacer, adems de instanciar variables. Puede
forzar a que los argumentos sean de un cierto tipo. Los predicados que deberan
formar el ncleo del interprete Prolog, aunque habr revisarlo para cada versin.
X = Y.
Unificacin: intenta hacer X e Y iguales mediante unificacin.
X \= Y.
Su opuesto: no unifican
X == Y. Identidad
Ms restrictivo que X = Y. Se satisface si X = Y, pero no necesariamente a la
inversa.

?-X = Y.
?-X == X.
?-X = Y, X == Y.
?-append([A|B], C) == append(X, Y).
?-append([A|B], C) == append([A|B], C).
X \== Y.
Su opuesto.
Entrada y salida bsico
Lectura
read(X),
get0(X),
get(X)
Escritura
write(X),
display(X)
put(X)
Formato:
nl
tab(X)
skip(+Code)
skip(a).

Manejo de ficheros
Lectura:
see(X),
seeing(X),
seen

Escritura:

tell(X),
telling(X),
told

Comparacin de nmeros
X = Y.

X > Y.

X \= Y.

X >= Y.

X < Y.

X =< Y.

Ejemplos de operadores aritmticos


Ejemplos de notacin infija y prefija en expresiones aritmticas:
?- +(X,Y) = a+b.
X=a
Y=b
?- +(X,Y) = a+b+c.
X = a+b
Y=c
?- +(X,Y) = a+(b+c).
X=a
Y = b+c
?- a+b+c = (a+b)+c.
Yes
?- a+b+c = a+(b+c).
No
Precedencia

Tipo

Operadore

500
500
400
200

yfx
fx
yfx
xfy

s
+, *, /

Infijo asocia por la izquierda


Prefijo no asocia
Infijo asocia por la izquierda
Infijo asociado por la derecho

APLICACIONES DE LAS LISTAS


En Prolog la estructura de lista est predefinida como una estructura recursiva
lineal cuyas componentes pueden ser heterogneas porque en Prolog no existe
una comprobacin tipos. Bsicamente una lista es una estructura con dos
argumentos: la cabeza de la lista, que es un componente de la lista, y la cola que
es otra lista con el resto de los componentes. Normalmente existen dos notaciones
para listas, una notacin prefija: (Cabeza, Cola) y una notacin infija [Cabeza|
Cola] ms cmoda de utilizar, y para denotar la lista vaca se utiliza siempre [].
As, la lista (a, b, c, d) se puede escribir en Prolog de cualquiera de las dos formas
siguientes:
.(a,.(b,.(c,.(d.[]))))

[a|[b|[c|[d|[]]]]],

Sin embargo, la segunda forma admite simplificaciones que permiten escribir


todos los elementos de la lista entre corchetes y separados por comas:
[a,b,c,d],
O escribir varios elementos a la izquierda del smbolo |, tambin separados por
comas, as como cualquier combinacin de estas dos formas; con lo que nuestra
lista se puede escribir de cualquiera de las formas siguientes:
[a| [b, c, d] ] [a, b| [c, d] ] [a, b, c| [d] ]

[a, b, c, d| [ ] ] .

Es importante observar que en las dos notaciones para listas, el segundo


argumento debe ser siempre una lista, pues aunque como hemos dicho Prolog no
comprueba tipos, si es capaz de distinguir las listas de otra clase de trminos. As,
notaciones como las siguientes
.(a, b) [ a | b]
Se consideraran errneas porque b es una constante (tomo) y no es una lista.
Tambin hay que tener en cuenta que entre los componentes de una lista pueden
aparecer otras listas, as, por ejemplo, [ a, b, [c, d, e] ] sera una lista con tres

componentes, el ltimo de los cuales es a su vez una lista, mientras que [a, b | [ c,
d, e] ] sera una lista con cinco componentes todos constantes.

Dominios para listas


Como hemos dicho en el apartado anterior, Prolog es capaz de distinguir las listas
de cualquier otra clase de trminos, pero esta distincin la hace a nivel interno
para detectar errores de notacin durante el proceso de unificacin. Si en algn
programa queremos saber si un trmino T es una lista (no vaca) podemos intentar
unificarlo con una expresin de la forma [X | X s] usando el predicado de
unificacin explicita .=., o podemos definir un predicado recursivo lista/1 en la
forma
lista([]).
lista([X|Xs]):-lista(Xs).
Este predicado es lo mas parecido a una definicin del tipo lista que se puede
hacer en Prolog y sirve para comprobar si un trmino es una lista cuando se lo
proporciona un argumento conocido, pero tambin sirve para generar, por
reevaluacin, listas cuyas componentes son variables libres.
Elementos de una lista
En este apartado nos ocuparemos de la construccin de predicados que sirven
para comprobar si un elemento pertenece o no a una lista o si se encuentra en
determinada posicin dentro de una lista y veremos que algunos presentan
comportamientos adicionales a los inicialmente esperados.
Para expresar estos comportamientos utilizaremos los trminos siguientes: test
cuando el comportamiento sea comprobar si se cumple una determinada relacin,
generador nico cuando genere un valor nico que verifique la relacin, generador
acotado cuando genere un nmero finito de valores, generador infinito cuando
genere valores de manera continuada y anmalo cuando no produzca resultado.

Reconocimiento con patrn de lista


En este apartado vamos a ver predicados definidos sobre pares de listas que
sirven para establecer relaciones como ser prefijo, sufijo o sublista de una lista. En
principio, aprovechando la facilidad de acceso a las cabezas y a las colas de las
lista, podemos definir un predicado para la relacin prefijo basado en la
coincidencia de los elementos de cabeza.
Encadenamiento y particin de lista
El encadenamiento de dos listas se puede definir en Prolog de una manera
bastante simple obtenindose un predicado encadena/3 que resulta de gran
utilidad en el manejo de listas. Para la definicin de este predicado basta tener en
cuenta que la cabeza de la lista resultante del encadenamiento ser la cabeza de
la primera de las dos listas que se encadenan y que la cola resultar de encadenar
la cola de la primera lista con la segunda lista completa.
Predicados aritmticos con lista
En este apartado nos dedicaremos a estudiar predicados que realizan clculos
numricos sobre listas. El ms bsico es el que calcula la longitud de una lista, la
forma ms simple de definir un predicado longitud/2 tal que longitud (L,N) calcule
la longitud N de una lista L es contando los elementos de forma recursiva: primero
los de la cola y despus los de la lista completa. Aqu tenemos dos definiciones
distintas,
longitud1 ( [ ], 0 ).
longitud1 ([_|Xs],N):-longitud(Xs,M),N is M+1.
Es una definicin basada en la aritmtica predefinida de Prolog, y
longitud2 ([],0).
longitud2 ([_|Xs],s(M)):-longitud(Xs,M).

Ordenacin de lista
Teniendo en cuenta la posibilidad que ofrece la representacin de listas en Prolog
de acceder directamente a varios elementos del comienzo de una lista y
compararlos, podemos definir un predicado ordenada/1 que determine si una lista
(de nmeros o de trminos) est ordenada o no.
Respecto a la ordenacin de listas, la mayora de los algoritmos se basan en la
combinacin de una particin de las listas en dos trozos, la ordenacin de los
trozos y la combinacin de los trozos ordenados. Este esquema lo siguen los
algoritmos de ordenacin por insercin, ordenacin por mezcla y ordenacin con
pivote (quicksort) que lo aplican del siguiente modo:
El algoritmo de ordenacin por insercin parte la lista en cabeza y cola, ordena la
cola e inserta la cabeza en el lugar adecuado de la cola ordenada, por lo que
nicamente necesita un procedimiento auxiliar para insertar elementos en listas
ordenadas.
El algoritmo de ordenacin por mezcla parte la lista en dos trozos
aproximadamente de igual longitud, ordena cada trozo y despus los mezcla. Este
algoritmo necesita dos procedimientos auxiliares: un procedimiento para separar
una lista en dos aproximadamente de igual longitud y otro para mezclar listas
ordenadas de forma que se obtenga una lista igualmente ordenada.
El algoritmo de ordenacin por pivote usa un elemento como pivote para partir la
lista en una lista con los elementos menores o iguales que el pivote y otra con los
elementos estrictamente mayores, ordena ambas listas y despus las encadena
los menores delante de los mayores.
Este algoritmo necesita dos procedimientos: uno para separar una lista con ayuda
de un pivote en dos listas una con los elementos menores o iguales que el pivote y
otra con los elementos mayores, y otro procedimiento para encadenar dos listas
que ya conocemos.

Combinatoria con listas


Teniendo en cuenta que una lista es un conjunto de elementos ordenados segn el
orden de aparicin de izquierda a derecha, dentro de los ejercicios con listas
podemos considerar la generacin de variaciones y permutaciones a partir de los
elementos de una lista; pero tambin podemos considerar la generacin de
combinaciones y un tratamiento de conjuntos donde ya la ordenacin no debe
tenerse en cuenta.
A partir del predicado seleccin/3 que permite seleccionar de forma aleatoria un
elemento de una lista devolviendo adems una lista con los restantes elementos,
podemos definir predicados para generar variaciones de un determinado tamao,
y en el caso extremo de que el tamao coincida con la longitud de la lista podemos
mejorar la definicin para producir permutaciones.
Ejemplo: longitud de lista
Longitud de una lista
longitud(L,N) se verifica si N es la longitud de la lista L
Ejemplos
longitud([],N) => N = 0
longitud([a,b,c],N) => N = 3
longitud([a,[b,c]],N) => N = 2
Programa: longitud.pl

longitud([],0).
longitud([_X|L],N) :longitud(L,M),
N is M + 1.

Sesin
?- longitud([a,b,c],N).
N=3
Yes
Predicado predefinido: length(L,N)
Mximo de una lista

max_list(L,N) se verifica si N es el mximo de los elementos de la lista de


nmeros L
Sesin
?- max_list([1,3,9,5],X).
X=9
Yes
Programa: max list.pl

max_list([X],X).
max_list([X,Y|L],Z) :max_list([Y|L],U),
maximo(X,U,Z).

maximo(X,Y,X) : X >= Y.
maximo(X,Y,Y) : X < Y.

IIC-Practica
Tema 6 operadores
Tema-15-1x2
Apunte05-03-6x

RBOLES
En Ciencias de la Computacin, hablamos de un rbol como una estructura, que
contiene un nodo padre y dos nodos hijos, un izquierdo y un derecho, los cuales a

su vez hacen referencia a "null", o ms dicho en prolog seria "nil", que significa
vaci.
En prolog un rbol binario se definir de la siguiente manera
arbol(Hi,X,Hd), donde Hi es hijo izquierdo , Hd hijo derecho, y X el padre.

rbol binario
Definicin: el conjunto de rboles binarios B de D se define
1. nil B (rbol vaco) [base]
2. si I, D B R D, entonces I::R::D B [recursivo]
:: :: es un constructor ternario: B D B B
hijo izquierdo :: raz :: hijo derecho
Ejemplo:
(nil :: a :: nil ) :: b :: (nil :: c :: nil)

Representacin
Necesitamos trminos recursivos para representar rboles
Seguimos la definicin inductiva de B:
1. nil B (rbol vaco) [base]
2. si I, D B R D, entonces I::R::D B [recursivo]
Caso base constante vacioB
Caso recursivo estructura funtor nodoB/3 nodoB(I,R,D)
Un rbol binario bien formado es un trmino de la gramtica:
AB ::= vacioB
| nodoB(AB,T,AB)
donde T es un trmino Prolog

Referencias bibliogrficas