Introducción a PROLOG - jabaier.sitios.ing.uc.cl

56
Introducción a P ROLOG P ROLOG es un lenguaje interpretado basado en la l´ ogica de predicados. Puede ser visto como un lenguaje de programaci´ on o un demostrador mec´ anico de teoremas. Un programa P ROLOG es un conjunto de oraciones (axiomas) en un lenguaje de primer orden. Estos axiomas no pueden tomar una forma arbitraria. Adem ´ as, est ´ a extendido con caracter´ ısticas extra-l´ ogicas y meta-l ´ ogicas, de modo que la relaci´ on que hay entre P ROLOG y l´ ogica de predicados no es obvia. Fue implementado a principios de los a ˜ nos 70, por Alain Colmerauer. Hoy existen muchas implementaciones de P ROLOG (SICStus, Quin- tus, Eclipse, BinProlog, P#, etc.). Nosotros usaremos SWI-Prolog (http://www.swi-prolog.org), desarrollado en la Universidad de Amster- dam por Jan Wielemaker. Jorge Baier Aranda, PUC 24

Transcript of Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Page 1: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Introducción a PROLOG

PROLOG es un lenguaje interpretado basado en la logica de predicados.Puede ser visto como un lenguaje de programacion o un demostradormecanico de teoremas.

Un programa PROLOG es un conjunto de oraciones (axiomas) en un lenguajede primer orden. Estos axiomas no pueden tomar una forma arbitraria.

Ademas, esta extendido con caracterısticas extra-logicas y meta-logicas, demodo que la relacion que hay entre PROLOG y logica de predicados no esobvia.

Fue implementado a principios de los anos 70, por Alain Colmerauer.

Hoy existen muchas implementaciones de PROLOG (SICStus, Quin-tus, Eclipse, BinProlog, P#, etc.). Nosotros usaremos SWI-Prolog(http://www.swi-prolog.org), desarrollado en la Universidad de Amster-dam por Jan Wielemaker.

Jorge Baier Aranda, PUC 24

Page 2: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

El lenguaje: Hechos

Son el tipo basico de oraciones que componen un programa en PROLOG.Supongamos que queremos escribir la informacion genealogica de un grupode personas. Para esto podemos utilizar los predicados madre y padre delsiguiente modo:

padre(juan, amanda).madre(ximena, amanda).madre(laura, juan).padre(andres, juan).padre(patricio, bonifacio).padre(juan, patricio).padre(juan, ana).madre(ximena, ana).

Cada una de las lıneas anteriores representa un hecho. Un hecho corres-ponde a un literal positivo cerrado (sin variables).

Las constantes se representan con nombres que comienzan con minuscu-las. Por otro lado, los nombres que comienzan con mayusculas denotaranvariables.

Jorge Baier Aranda, PUC 25

Page 3: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Interacción con el intérprete

Un programa se puede ingresar de dos formas al interprete; directamente:

$ pl

Welcome to SWI-Prolog (Multi-threaded, Version 5.2.5)Copyright (c) 1990-2003 University of Amsterdam.

?- [user].|: padre(juan,amanda).|: madre(ximena,amanda)....|: ^D% user://1 compiled 0.00 sec, 1,348 bytes

a traves de un archivo. Por ejemplo, si los hechos anteriores estan en elarchivo ej1.pl, entonces el interprete PROLOG lee el archivo de la siguienteforma:

?- [’ejemplo.pl’].% ej1 compiled 0.00 sec, 1,348 bytesYes

Jorge Baier Aranda, PUC 26

Page 4: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

O mediante el uso del predicado consult(’ejemplo.pl’).

A partir de esto uno puede hacer consultas:

?- madre(ximena,ana).Yes?- padre(juan, ana).Yes?- padre(juan, ximena).No

Notese que PROLOG responde yes solo cuando el hecho asociado apareceen la base de datos que tiene almacenada, o cuando se deriva de la infor-macion almacenada

Jorge Baier Aranda, PUC 27

Page 5: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Una pregunta mas interesante involucra el uso de variables. Por ejemplo, siqueremos saber si existe alguien que sea el padre de juan, podemos pre-guntar:

?- padre(X,juan).X = andresYes

Antes de responder Yes o No, Prolog espera una accion por parte del usuario.En el ejemplo de arriba, el usuario presiono [enter].

Si el usuario ingresa un ; entonces PROLOG intenta resatisfacer el objetivo.

Al decir padre(X,juan), estamos preguntandole a PROLOG si existe algunainstanciacion para la variable X que haga que padre(X,juan) sea deduzcade la base de datos. PROLOG responde que andres es un valor que harıaque la consulta sea verdadera del programa.

Antes de que prolog responda Al decir ’;’ se le indica a PROLOG que efecti-vamente se quiere buscar otra solucion.

Jorge Baier Aranda, PUC 28

Page 6: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

?- madre(X,Y).X = ximena,Y = amanda ;

X = laura,Y = juan ;

X = ximena,Y = ana ;

No

Al no haber otra solucion, PROLOG responde No.

En este ultimo ejemplo, PROLOG busca todos los pares 〈X, Y〉 tales quemadre(X,Y) es verdadero. Tambien es posible realizar preguntas mas com-plejas. Por ejemplo, supongamos que queremos saber quien es el abuelopaterno de ana:

?- padre(X,ana), padre(Y,X).X = juan,Y = andres ? ;

Jorge Baier Aranda, PUC 29

Page 7: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

No

En este ejemplo, la consulta padre(X,ana), padre(Y,X). se procesa enorden. Primero se resuelve la sub-consulta padre(X,ana) y los valores re-sultantes de X se usan para responder la segunda sub-consulta. La ’,’ seinterpreta como conjuncion.

Jorge Baier Aranda, PUC 30

Page 8: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Reglas

Una regla PROLOG es una clausula de Horn definitiva, las cuales son de laforma:

ch ∨ ¬c1 ∨ ¬c2 ∨ . . . ∨ ¬cn, (1)

donde, ch y c1, . . . , cn son literales positivos.

El atomo positivo se llama cabeza y el resto de la regla, cola. En la sintaxisde PROLOG la clausula 1 se escribe:

ch:-c1, c2, . . . cn.

que se lee como ch es verdadero si c1, . . . , cn son verdaderos. El sımbolo :-se lee “si” y corresponde a una implicacion de derecha a izquierda.

Las variables que aparecen en la clausula se suponen cuantificadas univer-salmente desde afuera. Por ejemplo, la clausula:

abuelo(X, Y ) ∨ ¬padre(X, Z) ∨ ¬padre(Z, Y )

Jorge Baier Aranda, PUC 31

Page 9: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

es equivalente a:

∀X, Y, Z(abuelo(X, Y ) ∨ ¬padre(X, Z) ∨ ¬padre(Z, Y ))

que finalmente es equivalente a

∀X, Y (abuelo(X, Y )← ∃z(padre(X, Z) ∧ padre(Z, Y )))

Al programa que tenıamos anteriormente, podemos agregarle las siguientesreglas:

abuelo(X,Y):- padre(X,Z), madre(Z,Y).abuelo(X,Y):- padre(X,Z), padre(Z,Y).

Con estas regla podemos consultar quien es abuelo de quien:

?- abuelo(X,Y).

X = andres,Y = amanda ;

Jorge Baier Aranda, PUC 32

Page 10: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

X = andres,Y = patricio ;

X = andres,Y = ana ;

X = juan,Y = bonifacio ;

No?-

Jorge Baier Aranda, PUC 33

Page 11: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Las reglas para abuelo se pueden escribir como:

abuelo(X,Y):- padre(X,Z), (madre(Z,Y);padre(Z,Y)).

En esta notacion el sımbolo ’;’ se utiliza como disyuncion. La regla anteriores equivalente a las dos reglas originales.

Ejercicio : Defina la relacion herm(X,Y) entre dos individuos, que es verda-dera cuando los dos sujetos tengan al padre o a la madre en comun.

Suponga que se desea definir la relacion antecesor(X,Y). En primer termi-no, definiremos:

antecesorDirecto(X,Y):- (padre(X,Y);madre(X,Y)).

Con el significado obvio. Ası, podremos escribir que:

antecesor(X,Y):- antecesorDirecto(X,Y).antecesor(X,Y):- antecesorDirecto(X,Z), antecesor(Z,Y).

De modo que obtenemos:

Jorge Baier Aranda, PUC 34

Page 12: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

| ?- antecesor(X,Y).

X = juan,Y = amanda ;

X = andres,Y = juan ;

X = patricio,Y = bonifacio ;

X = juan,Y = patricio ;.........

Jorge Baier Aranda, PUC 35

Page 13: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Sintaxis y Semántica de un Programa Prolog

Los elementos sintacticos basicos de un progrma Prolog son los terminos,las variables, los functores y los predicados.

Para indicar que p es un predicado de aridad n se escribe p/n. Un literal,asociado al predicado p/n es un atomo de la forma p(t1, . . . , tn). Donde cadati es un termino.

Los terminos pueden ser:

Constantes: Estas pueden ser:Atomos: Sımbolos que comienzan con letra minuscula, por ej. x, y,a, etc. Sımbolos encerrados en comillas simples, por ej. ’X’, ’ 5’,’ x23’, ’a’,, etc. (Nota: el atomo ’a’ es equivalente al atomo a, y delmismo modo para todos los sımbolos que comienzan con minuscula.

Numeros: Enteros y/o reales. Por ej. 4, 4.5, etc..Caracteres y textos (strings): Los caracteres y los strings se encierran

entre comillas dobles. Por ej. "f", "fam", etc.Variables: Sımbolos que comiencen con letra mayuscula o con un unders-

core ’ ’. Por ej., X, 5, x23. El sımbolo de variable tiene un significado

Jorge Baier Aranda, PUC 36

Page 14: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

especial: es una variable que debe ser reemplazada por un nombre nuevocada vez que aparezca (aun y cuando aparezca mas de una vez en lamisma regla).

Functores: El ultimo tipo de termino corresponde a terminos de funcion, esdecir representan objetos. Un functor tiene una aridad asociada. Si f esel nombre de un functor, f/m denota que f tiene aridad m. Un termino defuncion asociado a un functor f/m sera f(t1, t2, . . . , tm), donde cada ti esa la vez un termino.

Por ultimo, un predicado tiene las mismas caracterısticas que un functor.La diferencia fundamental es que semanticamente se les asocia un valor deverdad, no un objeto.

Jorge Baier Aranda, PUC 37

Page 15: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Programa y Consulta

Un programa PROLOG es un conjunto ordenado de clausulas de Horn

l0:-l1, l2, ...ln.

Un hecho corresponde a una clausula de Horn con n=0 y se puede escribircomo1:

l0:-.

o como:l0.

Formulas de la forma anterior reciben el nombre de clausulas unitarias.

Cada li es un literal positivo de la forma p(t1, t2, . . . , tm), donde p/m es unpredicado de aridad m.

1Esta forma no es valida en SWI-PROLOG.

Jorge Baier Aranda, PUC 38

Page 16: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

El interprete de PROLOG toma como entrada un programa PROLOG y unaconsulta. Una consulta es una clausula de Horn sin literal positivo. Una con-sulta se puede ver como una regla sin cabeza:

:-g1, g2, . . . gm.

donde cada gi es un literal.

El interprete de PROLOG recibe como entrada un programa y una consulta.

La salida del interprete sera No, cuando no sea posible demostrar, a partirdel programa, que la consulta es verdadera. En otro caso, responde Yes oentrega valores para las variables en la consulta que hagan que la consultasea verdadera.

Al demostrar un objetivo, el interprete utiliza los conceptos de unificacion ysustitucion, que veremos a continuacion.

Jorge Baier Aranda, PUC 39

Page 17: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Sustitución y Unificación

Una sustitucion es una funcion parcial que mapea variables a terminos dellenguaje. Por ejemplo, las siguientes son sustituciones:

θ1 = {X = patricio, Y = bonifacio}θ2 = {X = nil, Y = a, Z = cons(X, Y )}

Si li es un literal y θ una sustitucion, entonces la notacion liθ representa alliteral que resulta de sustituir las variables que aparezcan en li y θ por losterminos asignados en θ.

Por ejemplo,

padre(X, Y){X = patricio, Y = bonifacio}

corresponde al termino

padre(patricio, bonifacio).

Jorge Baier Aranda, PUC 40

Page 18: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Un literal L′ es una instancia de un literal L si existe una sustitucion θ tal queL′ = Lθ.

Se dice que una sustitucion θ unifica dos literales l1 y l2 cuando l1θ ≡ l2θ,donde el sımbolo ≡ representa igualdad caracter a caracter.

En este caso se dice que θ es un unificador para l1 y l2. Naturalmente, dadosdos literales cualesquiera, no siempre existe un unificador para ellos.

Una sustitucion se puede aplicar a listas de literales, de modo que siL = [l1, . . . , ln] es una lista de literales, entonces Lθ correspondera a la lista[l1θ, . . . , lnθ].

Dos sustituciones θ1 y θ2 pueden componerse para formar una tercera sus-titucion θ = θ1θ2, de modo que si l es un literal, entonces lθ = (lθ1)θ2). Por

Jorge Baier Aranda, PUC 41

Page 19: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

ejemplo:

{X = patricio, Y = bonifacio}{Z = juan} =

{X = patricio, Y = bonifacio, Z = juan}

{X = cons(Z,nil)}{Z = cons(Y, nil)} =

{X = cons(cons(Y, nil), nil), Z = cons(Y, nil)}

Jorge Baier Aranda, PUC 42

Page 20: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

UNIFICADOR MAS GENERAL

Un unificador θ para listas de literales L1 y L2 se dice mas general que ununificador θ1 cuando existe otro unificador θ2 tal que θθ2 = θ1.

Por ejemplo, si queremos unificar p(X, Y, b) con p(X, a, Z), el unificador θ ={Y = a, Z = b} es mas general que el unificador θ1 = {X = c, Y = a, Z = b},puesto que θ{X = c} = θ1.

Dado un par de listas de literales L1 y L2, siempre existe un unificador quees mas general que cualquier otro, a este unificador se le denota UMG(L1, L2).

Jorge Baier Aranda, PUC 43

Page 21: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

La operacion de unificacion es utilizada internamente por el interprete, perotambien puede ser invocada por el usuario con el operador =. Por ejemplo:

?- p(X,b,Z)=p(a,Y,f(T)).

X = aZ = f(_G155)Y = bT = _G155

Yes?- p(X)=q(a).

No

La unificacion juega un rol fundamental en el proceso de demostracion deobjetivos. Por esta razon, es fundamental que este procedimiento sea muyeficiente.

Persiguiendo esta eficiencia, en PROLOG el occurs check no se realiza al efec-tuar una unificacion.

Jorge Baier Aranda, PUC 44

Page 22: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Debido a esto, es posible unificar, por ejemplo X con f(X)

?- X=f(X).X = f(f(f(f(f(f(f(f(f(f(...))))))))))

Yes

Jorge Baier Aranda, PUC 45

Page 23: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

¿Qué hace el intérprete de PROLOG?

Como mencionaramos anteriormente, le interprete recibe como entrada unaconsulta:

:-g1, g2, . . . gm.

Los literales g1, g2, . . . gm se interpretan como una lista de objetivos a serdemostrados uno a uno. Los literales de esta lista pueden incluir variables.

En caso que los literales contengan varibables, lo que hace prolog esdeterminar si existe una sustitucion θ para la cual la conjuncion de[g1θ, g2θ, . . . gmθ] sea demostrable a partir del programa.

El interprete maneja una lista G de objetivos que inicialmente se inicializacomo:

G← [g1, g2, . . . gm].

Ademas, maneja una sustitucion θ inicializada en vacıo.

Jorge Baier Aranda, PUC 46

Page 24: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Algoritmo de PROLOG para resolución de consultas

En la descripcion del algoritmo que estudiamos mas abajo utilizaremos lasiguiente convencion:

GL0: Lista de literales correspondientes al objetivo o consulta inicial.

GL: Lista de objetivos (literales positivos).

S, S′, S′′, . . .: sustituciones.

ren: Un procedimiento que recibe una lista de literales y renombra las variablescon nombres nuevos. Es usual que estos nombres sean de la forma n donden es un numero entero.

PP y PP aux: Dos procedimientos que reciben una lista de objetivos y retornanuna sustitucion o #Falso si no hay sustitucion posible. PP aux recibe ademasde la lista de objetivos, un ındice a una clausula dentro del programa.

Jorge Baier Aranda, PUC 47

Page 25: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

UMG Prolog: El procedimiento UMG sin el occurs check .

c1, c2, . . . cm: Las clausulas del programa.

#m: Constante que se inicializa como el numero de clausulas del programa.

Cabeza y Cola: dos funciones sobre reglas o listas de objetivos. Si x es unalista, entonces Cabeza(x) es el primer literal de x y Cola(x) es el resto de lalista. Si x es una clausula, Cabeza(x) es la cabeza de la clausula y Cola(x)es el cuerpo.

aplicarSust y composicion: Los procedimientos utilizados por el procedi-miento UMG aux descritos anteriormente.

Dado que GL0 es el objetivo inicial, para iniciar la demostracion se invoca:

PP(ren(GL0), nil)

Jorge Baier Aranda, PUC 48

Page 26: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Algoritmo de demostración de PrologEsta es una version simplificada del algoritmo de demostracion de prolog 2.

Function PP(GL,S) /* devuelve una sustitucion que satisfaga GL o #Falso */{

if GL=nil return(S);PP_aux(GL,S,1)

}

Function PP aux(GL,S,i) /* devuelve sustitucion que satisfaga GL o #Falso */{

clausula C’; /* variables auxiliares */sustitucion S’, S’’;if i>#m return(#Falso);C’:= ren(C[i]);S’:= UMG_Prolog(Cabeza(GL),Cabeza(C’));if S’=#Falso return(PP_aux(GL,S,i+1));S’’:=PP(aplicarSust(S’,append(Cola(C’),Cola(GL))),composicion(S,S’));if S’’=#Falso return(PP_aux(GL,S,i+1));return(S’’);

}2En este procedimiento no se considera la posibilidad de que uno de los objetivos pueda corresponder al

predicado extra-logico =. Tampoco se considera resatisfaccion de consultas.

Jorge Baier Aranda, PUC 49

Page 27: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Si quisieramos agregar la posibilidad de buscar nuevas soluciones cada vezque encuentra una, este algoritmo se complica levemente.

Para ello, lo que necesitamos es utilizar continuaciones. Las continuacionespermiten recuperar ambientes de ejecucion. Por ejemplo, antes de ejecutarla ultima instruccion del procedimiento PP aux:

return(S’’);

podrıamos guardar el estado de la computacion en un objeto. Este objeto,llamado continuacion, contendrıa el stack de registros de activacion, los re-gistros de la CPU y el punto en el cual se esta ejecutando el procedimiento.

Entonces, en vez de ejecutar la instruccion de return como aparece en elprocedimiento, se ejecuta una instruccion condicional.

La condicion dira que, en la primera ejecucion de este procedimiento, seretorna la composicion junto con la continuacion. La segunda oportunidaden que se ejecuta esta continuacion, el procedimiento retorna #Falso. Deeste modo, la continuacion permite que se encuentren otras respuestas.

Jorge Baier Aranda, PUC 50

Page 28: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

EJEMPLO :

Consideremos el siguiente programa:

grande(oso).grande(elefante).pequeno(gato).cafe(oso).negro(gato).gris(elefante).oscuro(Z):- negro(Z).oscuro(Z):- cafe(Z).

junto con la consulta:

?- oscuro(X), grande(X).

La figura 3 muestra

Jorge Baier Aranda, PUC 51

Page 29: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

?- trace.

Yes[trace] ?- oscuro(X),grande(X).

Call: (7) oscuro(_G277) ? creepCall: (8) negro(_G277) ? creepExit: (8) negro(gato) ? creepExit: (7) oscuro(gato) ? creepCall: (7) grande(gato) ? creepFail: (7) grande(gato) ? creepFail: (8) negro(_G277) ? creepRedo: (7) oscuro(_G277) ? creepCall: (8) cafe(_G277) ? creepExit: (8) cafe(oso) ? creepExit: (7) oscuro(oso) ? creepCall: (7) grande(oso) ? creepExit: (7) grande(oso) ? creep

X = oso ;Fail: (7) grande(oso) ? creepFail: (8) cafe(_G277) ? creepFail: (7) oscuro(_G277) ? creep

No

Figura 3: Resultado del trace del objetivo oscuro(X), grande(X).

La ejecucion del programa PROLOG es equivalente a realizar una busque-da en profundidad en un espacio definido por el programa y por el objetivo

Jorge Baier Aranda, PUC 52

Page 30: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

inicial. La figura 4 ilustra el mismo.

_G277=gato

oscuro(X),grande(X)

oscuro( G277),grande( G277)

negro( G277),grande( G277)

grande(gato)

× 2

cafe( G277),grande( G277)

cafe(gato)

Figura 4: Arbol de Busqueda de una Demostracion

Jorge Baier Aranda, PUC 53

Page 31: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Significado Declarativo de un Programa PROLOG

El significado procedural de un programa PROLOG esta dado por el algoritmoque simula el comportamiento de PROLOG.

Nos interesa especificar la semantica declarativa de PROLOG.

Si GL es una lista de literales que forman una consulta. Entonces, desde unpunto de vista declarativo, PROLOG intenta demostrar que GL es verdadero.

El objetivo GL sera verdadero si existe una susti-tucion θ tal que, para cada sub-objetivo g de GL,existe una clausula ch:-c1, . . . , cn. en el programa,tal que:• gθ = chθ.• c1θ, . . . , cnθ. son verdaderos.Es importante tener en mente que la semanticadeclarativa y la procedural no son equivalentes.

Jorge Baier Aranda, PUC 54

Page 32: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Manejo de Listas

En forma abstracta, podriamos definir una lista a traves de la siguiente defi-nicion inductiva:

Una lista es:

• nil, que corresponde a una lista vacıa.• Si L y a es una constante (o un atomo), entonces, cons(a, L) es tambien

una lista.

El siguiente predicado Prolog define que es una lista.

lista(nil).lista(cons(X,Y)):- lista(Y).

Supongamos que queremos escribir el predicado pertenece(X,L), dondeX es algun termino, y L es una lista. Queremos que este predicado retorneverdadero cuando la lista contenga al termino en cuestion.

Este predicado se puede escribir de la siguiente manera:

Jorge Baier Aranda, PUC 55

Page 33: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

pertenece(X,cons(Y,_)):- X=Y.pertenece(X,cons(_,Z)):- pertenece(X,Z).

Podemos reescribir este procedimiento como,

pertenece(X,cons(X,_)).pertenece(X,cons(_,Z)):- pertenece(X,Z).

La unica diferencia es que la unificacion de lado derecho se realiza de otraforma.

Al igual que en algunos lenguajes de programacion (como lisp, por ejem-plo), las listas son elementos basicos del lenguaje PROLOG y se encuentranpredefinidas.

En esta definicion, la lista vacıa se denota como [ ]. El operador cons co-rresponde al operador . (punto).

De esta manera, el procedimiento pertenece se puede reescribir como elprocedimiento member (nombre estandar):3.

3Es usual que este predicado, junto con otros predicados para manipulacion de listas, esten predefinidos osean parte de una librerıa estandar de PROLOG.

Jorge Baier Aranda, PUC 56

Page 34: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

member(X,.(Y,_)):- X=Y.member(X,.(_,Z)):- member(X,Z).

Jorge Baier Aranda, PUC 57

Page 35: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Notaciones para representar Listas

Existe una notacion mas facil de leer para manejar listas. De hecho, la lista:

.(a,.(b,.(c,.(d,[]))))

es equivalente a la lista [a,b,c,d], lo que tambien puede escribirse como[a|[b,c,d]] o [a,b|[c,d]]. La tabla de la figura 5 ilustra las equivalenciasentre las diferentes notaciones para listas.

.(a,[]) [|[]] [a]

.(a,.(b,[])) [a|[b|[]]] [a,b]

.(a,X) [a|X] [a|X]

.(a,.(b,X)) [a|[b|X]] [a,b|X]

Figura 5: Notaciones equivalentes para listas

Notese que no cualquier expresion que involucre el functor ./2 puede escri-birse como una lista. Este es el caso de los dos ultimos ejemplos de la figura5.

Jorge Baier Aranda, PUC 58

Page 36: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Concatenación de listas

El predicado append/3 recibe como argumentos tres listas. De modo queappend(L1,L2,L3) es un predicado verdadero cuando L3 es el resultado derealizar append de las listas L1 y L2.

Al satisfacerse append(L1,L2,L3), la variable L3 estara unificada con la con-catenacion de L1 y L2.

Siguiendo la definicion inductiva de listas, la concatenacion se puede definirde la siguiente manera.

append(nil, L) = L (2)

append(cons(a, L1), L2)) = cons(a, append(L1, L2)) (3)

La primera condicion de la definicion dice que si la primera lista es vacıa,entonces el resultado es igual a la segunda lista. Esto se escribe en PROLOG

como:

Jorge Baier Aranda, PUC 59

Page 37: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

append(L1,L2,L3):- L1=[], L3=L2.

Que se puede reescribir como:

append([],L2,L2).

De la siguiente definicion, se puede obtener la siguiente definicion:

append(L1,L2,L3):- L1=[A|L1s],append(L1s,L2,Xs),L3=[A|Xs].

Notese el uso de unificacion para obtener las sub-componentes de una lista.

Al igual que anteriormente, este procedimiento se puede reescribir como:

append([H1|H1s],L2,[H1|Xs]):- append(H1s,L2,Xs).

La siguiente es la version final de este procedimiento.

Jorge Baier Aranda, PUC 60

Page 38: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

append([],L2,L2).append([L1|L1s],L2,[L1|Xs]):- append(L1s,L2,Xs).

Una caracterıstica fundamental de PROLOG es que los argumentos de lospredicados pueden tener un rol de entrada/salida. Esto es, un argumento sepuede utilizar tanto para recibir datos como para entregar resultados. Estose ilustra con las siguientes invocaciones a append/3:

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

Sin embargo, no siempre los parametros funcionan como entrada/salida.Frecuentemente hay parametros que deberan estar unificados previamen-te para que el predicado funcione correctamente.

Jorge Baier Aranda, PUC 61

Page 39: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Reverso de una lista

El objetivo reverse(L1,L2) sera satisfecho cuando L1 y L2 sean listas conlos mismos elementos pero en orden inverso, la figura 6 ilustra una primeraversion de este procedimiento.

reverse([],[]).reverse([X|Xs],Zs):- reverse(Xs,Rs),

append(Rs,[X],Zs).

Figura 6: Primera version de reverse/2

Una version alternativa para reverse se ve en la figura 7.

reverse(L,R):- reverse(L,[],R).reverse([X|Xs],Acum,R):- reverse(Xs,[X|Acum],R).reverse([],R,R).

Figura 7: Segunda version de reverse/2

Jorge Baier Aranda, PUC 62

Page 40: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

¿Que responden las dos versions de reverse frente a la consultareverse(X,[1,2,3])?

Normalmente, cuando se documenta un predicado PROLOG se indica que rolcumplen cada uno de los predicados.

Ası, si se indica:

Significa que al invocar al predicado p/3, la variable X debe estar instancia-da, la variable Y no debe estar instanciada y que no hay restricciones conrespecto a la variable Z.

Ejercicios:

1. Escriba el predicado last/2, que se satisface cuando el su segundo ele-mento es el ultimo elemento de la lista.

2. Escriba el predicado eliminar/3 tal que eliminar(L1,X,L2) se satisfacecuando L2 es igual a L1, pero sin una ocurrencia de X.

3. Escriba el predicado sublista/2 que se satisface cuando el primer ele-mento es una sublista del segundo.

4. Escriba el predicado igual_largo/2, mayor_largo/2 y menor_largo/2

Jorge Baier Aranda, PUC 63

Page 41: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

que se satisface cuando sus argumentos son listas y el primer elemen-to es del igual, mayor o menor tamano que el segundo, respectivamente.

Jorge Baier Aranda, PUC 64

Page 42: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Permutaciones de una lista

La invocacion permutacion(L1,L2) se satisface cuando L1 es una lista y L2es otra lista que es una permutacion de L1.

permutacion(L1,[X|Xs]):- eliminar(L1,X,Ys),permutacion(Ys,Xs).

permutacion([],[]).

Jorge Baier Aranda, PUC 65

Page 43: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Manejo de Números

En PROLOG los objetos numericos pueden corresponder a tipos integer ofloat de C. Para realizar operaciones numericas, se tiene el predicado is,el cual se comporta como una asignacion en un lenguaje imperativo.

Ası, el objetivo X is 〈expresion〉 sera satisfecho cuando X unifique con elresultado de evaluar 〈expresion〉 resulte en un numero. Por ejemplo, si defi-nimos:

masuno(X,Y):- Y is X+1.xmasuno(X,Y):- Y = X+1.

observaremos el siguiente comportamiento:

?- masuno(4,5).Yes

?- masuno(5,Y).Y = 6 ?Yes

Jorge Baier Aranda, PUC 66

Page 44: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

?- xmasuno(5,Y).Y = 5+1 ?Yes

Ademas del predicado is, PROLOG ofrece el siguiente conjunto de predica-dos:

1. =:= y =\= que permiten comparar dos valores numericos. El primero esverdadero si los valores numericos son iguales, y el segundo si son dife-rentes.

2. <, >, =< y >=, que corresponden a comparaciones usuales.

Las expresiones aritmeticas se forman de la manera usual utilizandoparentesis redondos y operadores +,-, *, que son operadores de suma, restay multiplicacion.

/ y // corresponden a division de punto flotante y entera, respectivamente.El operador mod corresponde al resto de la division.

Jorge Baier Aranda, PUC 67

Page 45: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Manejo de Caracteres y de Strings

Un caracter en Prolog es simplemente un numero entre 0 y 127, correspon-diente a los caracteres de la tabla ASCII.

Un string se maneja como una lista de caracteres. Por ejemplo:

| ?- X="un string.".

X = [117,110,32,115,116,114,105,110,103,46] ?

Yes

Jorge Baier Aranda, PUC 68

Page 46: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Ejemplo: Generación y Prueba

Una estrategia comun usada para la solucion de problemas en inteligenciaartificial es la estrategia de generaci on y prueba .

La idea basica es que se generan las posibles soluciones del espacio y seprueba si la posible solucion es en realidad una solucion.

Para que esta estrategia pueda funcionar, es necesario que el espacio desoluciones sea enumerable.

Al usar esta estrategia se utilizan dos modulos:

• Generador de soluciones.• Verificador de soluciones.

A continuacion veremos dos ejemplos de como implementar esta estrategia.

Jorge Baier Aranda, PUC 69

Page 47: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Generación y Prueba: Ordenamiento de listas

Si L es una lista de numeros que queremos ordenar, entonces un espaciode soluciones posibles corresponde al conjunto de permutaciones de L, demodo que podemos escribir:

solucion(L1,L2):- permutacion(L1,L2), ordenada(L2).

En este caso, el generador de soluciones posibles es el predicadopermutacion/2, mientras que ordenada/1 es el probador, que debe satis-facerse cuando su argumento corresponda a una lista ordenada.

Podemos implementar el predicado ordenada/1 de la siguiente manera:

ordenada([_]).ordenada([X|[Y|Ys]]):- X>=Y, ordenada([Y|Ys]).

Ası:

solucion([3,4,4,2,1],Y).

Jorge Baier Aranda, PUC 70

Page 48: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Y = [1,2,3,4,4] ? ;

Y = [1,2,3,4,4] ? ;

no

¿por que se obtienen dos soluciones (iguales)?

Este algoritmo es muy ineficiente! En el peor caso, el algoritmo genera N !permutaciones para obtener el resultado, para una lista de N elementos.

Para el problema especıfico de ordenacion de listas, es posible especificarun algoritmo mas apropiado que el anterior, como por ejemplo, ordenacionpor insercion o quicksort.

Jorge Baier Aranda, PUC 71

Page 49: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Generación y Prueba: El problema de las ocho reinas

El problema de las 8 reinas consiste en ubicar 8 reinas en un tablero deajedrez de manera que ninguna reina quede en posicion de ataque con res-pecto a la otra.

Una solucion a este problema esta dada por la siguiente figura:

2 3 4 5 6 7 81

1

2

3

4

5

6

7

8

Figura 8: Una solucion al problema de las ocho reinas

Para resolver este tipo de problemas primero necesitamos representar una

Jorge Baier Aranda, PUC 72

Page 50: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

configuracion del tablero (mas adelante veremos que esto tiene que ver conrepresentar un estado).

Debido a que, claramente, toda solucion solo tiene a una reina por columna,representaremos el estado como una lista:

[[1,Y1],[2,Y2],...,[8,Y8]]

Donde el par [i,Yi] representa el hecho que hay una reina en la posicion(i,Yi) del tablero.

Construiremos primeramente el procedimiento genera_configuracion(L)que genera una configuracion posible del tablero.

genera_configuracion(L) :-gen_aux(L,1).

gen_aux([],N) :- N>8.gen_aux([[N,X]|L],N) :-

N=<8,member(X,[1,2,3,4,5,6,7,8]),

Jorge Baier Aranda, PUC 73

Page 51: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

M is N+1,gen_aux(L,M).

Al hacer la consulta genera_configuracion(L), PROLOG responde:

?- genera_configuracion(L).

L = [[1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 1], [8, 1]] ;L = [[1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 1], [8, 2]] ;L = [[1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 1], [8, 3]] ;...L = [[1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 2], [8, 1]] ;L = [[1, 1], [2, 1], [3, 1], [4, 1], [5, 1], [6, 1], [7, 2], [8, 2]] ;...

Ahora debemos escribir un predicado para verificar la solucion.

La restriccion de que ningun par de reinas debe atacarse se representa atraves del predicado seguro(L). Donde L representa a una fraccion de laconfiguracion.

segura([]).segura([X|L]) :-

no_ataca(X,L),segura(L).

Jorge Baier Aranda, PUC 74

Page 52: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

La segunda regla establece que una fraccion de configuracion es segura sila reina (representada por X) que aparece en la primera ubicacion de la listano ataca al resto de las reinas de la configuracion (representada por L).

La primera regla dice que una fraccion de configuracion vacıa es segura.

Falta escribir el predicado no_ataca(X,L), que cuando X representa la posi-cion de una reina y L representa una configuracion parcial, se satisface si lareina representada por X no ataca a ninguna reina que aparece en L.

no_ataca(_,[]).no_ataca([X1,Y1],[[X2|Y2]|L]) :-

Y1=\=Y2, % Estan en filas distintasabs(Y1-Y2) =\= abs(X1-X2), % Estan en diagonales distintasno_ataca([X1,Y1],L).

Ahora una configuracion L es una solucion para el problema si:

solucion(L) :-genera_configuracion(L),segura(L).

Jorge Baier Aranda, PUC 75

Page 53: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Podemos encontrar soluciones al problema usando la siguiente consulta:

?- solucion(L).

L = [[1, 1], [2, 5], [3, 8], [4, 6], [5, 3], [6, 7], [7, 2], [8, 4]] ;L = [[1, 1], [2, 6], [3, 8], [4, 3], [5, 7], [6, 4], [7, 2], [8, 5]]Yes

Podemos medir el tiempo que demora en responder la consulta utilizando elpredicado time/1:

?- time(solucion(L)).% 21,875,983 inferences in 23.35 seconds (936873 Lips)

Como vemos un tiempo nada de corto para una maquina de 1GHz...

¿Como se puede mejorar esto? ¿Que parte es la que hay que mejorar?

Jorge Baier Aranda, PUC 76

Page 54: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Una solución más eficiente

Debido a que no es posible que dos reinas esten en la misma fila, podemosreimplementar el generador de soluciones considerando este hecho.

La siguiente implementacion genera soluciones de una manera bastantemas astuta, usando el predicado permutacion, que ya vimos:

genera_configuracion2(L) :-permutacion([1,2,3,4,5,6,7,8],P),empareja([1,2,3,4,5,6,7,8],P,L).

empareja([],[],[]).empareja([X|Xs],[Y|Ys],[[X,Y]|L]) :-

empareja(Xs,Ys,L).

De esta forma, obtenemos el siguiente comportamiento:

?- genera_configuracion2(L).L = [[1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 7], [8, 8]] ;L = [[1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 6], [7, 8], [8, 7]] ;L = [[1, 1], [2, 2], [3, 3], [4, 4], [5, 5], [6, 7], [7, 6], [8, 8]] ;...

Jorge Baier Aranda, PUC 77

Page 55: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

De manera analoga podemos implementar el predicado solucion2, usandoeste generado.

Obtenemos, ası, el siguiente comportamiento:

?- time(solucion2(L)).% 102,920 inferences in 0.13 seconds (791692 Lips)

L = [[1, 1], [2, 5], [3, 8], [4, 6], [5, 3], [6, 7], [7, 2], [8, 4]]

Que es 180 veces mas rapido que la version anterior!

Jorge Baier Aranda, PUC 78

Page 56: Introducción a PROLOG - jabaier.sitios.ing.uc.cl

Otro ejemplo: Ordenación de Listas

ORDENAMIENTO POR INSERCION DIRECTA :

Podemos implementar ordenacion por insercion usando el siguiente predi-cado:

ord_insercion([],[]).ord_insercion([X|Xs],Y):- ord_insercion(Xs,Ys),

insertar(X,Ys,Y).

insertar(X,[],[X]).insertar(X,[Y|Ys],[X,Y|Ys]):- X=<Y.insertar(X,[Y|Ys],[Y|Zs]) :- X>=Y, insertar(X,Ys,Zs).

Como es sabido, este algoritmo ordena una lista en tiempo proporcional an2.

Ejercicio: Implemente quicksort.

Jorge Baier Aranda, PUC 79