hombre ('Antonio').
hombre ('Pedro').
hombre ('Juan').
hombre ('Alejandro').
mujer ('María').
mujer ('Lissethe').
mujer ('Carmen').
mujer ('Julia').
Consultar:
?-hombre (X).
?-mujer (Y).
Verificar si 5+5 es 10
?- 10 is 5+5.
El predicado consult sirve para
"consultar" o cargar ficheros conteniendo código fuente en el
intérprete.
?-consult(practica3_chunga).
?-consult(’c:/hlocal/practica3_suspensa’).
?-consult(’c:/hlocal/practica3_suspensa.pl’).
?- [practica3_chunga].
?- [’practica3_chunga’].
?- [’practica3_chunga.pl’].
?- [’c:/hlocal/practica3_chunga.pl’].
Para consultar en que directorio estamos:
?-pwd.
?- cd(’..’). %recorrer
?- ls.
?- cd('../santos'). %establecerá
c:\..\santos como nuevo directorio de trabajo
?-cd('c:/.../prueba').
Para crear y editar un archivo.pl
?-crea(patos,marisol,sistemasB,a32).
?- edit(hola).
Editor clónico de emacs que viene incluido
en el SWI Prolog.
?- emacs.%invoca el editor
?-emacs('mi_fichero.pl'). edita el fichero
con emacs
Cierro la sesión en el intérprete
?- halt.
INPUT & OUTPUT
?-write(hola_mundo).
?-write(dame_tu_nombre:),
read(NOMBRE),
write(gusto_en_conocerle),nl,
write(NOMBRE).
?-read(Piedra).
OPERADORES
?- 5>5.
PREDICADOS
Se utilizan para
expresar propiedades de los objetos. En Prolog los llamaremos hechos.
simbolo_de_predicado(arg1,arg2,...,argn).
CONECTORES LÓGICOS
La conjunción,
“y”, en prolog ”,” ejm. X,Y.
La disyunción,
“o”, en prolog “;”colocado entre los objetivos
ejm. X;Y.
La negación
lógica no puede ser representada explícitamente en Prolog. La
representamos con el predicado predefinido not o con \+: not(X), \+ X. “no”,
tendrá éxito si el objetivo X fracasa.
La implicación o condicional,
sirve para significar que un hecho depende de un grupo de otros hechos: “si ...
entonces ...”. prolog :cabeza_de_la_regla :- cuerpo_de_la_regla.
/* Conjunción de predicados */
le_gusta_a(clara,jorge),le_gusta_a(clara,chocolate).
/* Disyunción de predicados */
le_gusta_a(clara,jorge);
le_gusta_a(jorge,clara).
/* Negación de predicados */
not(le_gusta_a(clara,jorge)).
/* o también como */
\+ le_gusta_a(clara,jorge).
/* Condicional: REGLAS */
/* novios(Per1,Per2) <- Per1 y Per2 son
novios */
novios(X,Y) :- le_gusta_a(X,Y),
Predicado: Relación, función u operador que
regresa falso o verdadero.
HECHOS: Relación y esto se asume como
un hecho, y un predicado es un conjunto
de hechos o reglas que tienen un mismo nombre y la misma cantidad de objetos
relacionados,
legusta(pepe,pesca).
legusta(maria,bailar).
legusta(ana,pesca).
legusta(pepe,musica).
legusta(maria,musica).
legusta(ana,bailar).
Se pueden realizar las siguientes preguntas
sobre la base de información:
- ¿Le gusta la música a Pepe y a Maria?
:
?-legusta(pepe,musica),legusta(maria,musica).
-
¿Le gusta bailar a Pepe o a Maria le gusta la música?:
?-legusta(pepe,musica);legusta(maria,musica).
-
¿Le gusta bailar a Pepe y a Maria no le gusta la música?:
?-legusta(pepe,musica),not(legusta(maria,musica)).
ACLARACION
Al tener por ejemplo dentro de nuestra base
del conocimiento, los siguientes hechos:
sucesor(1,2).
sucesor(2,3).
sucesor(3,4).
sucesor(4,5).
sucesor(5,6).
sucesor(6,7).
Podemos realizar consultas como las
siguientes:
sucesor(X,6).
sucesor(2,Y).
sucesor(X,Y).
REGLA: Una regla es una sola conclusión
seguida por el signo :- el cual hace la
vez de SI condicional, seguida por una o mas relaciones de condición.
%%
%% declaraciones
%%
padrede(juan, maria). % juan es padre de
maria
padrede(pablo, juan). % pablo es padre de
juan
padrede(pablo, marcela).
padrede(carlos, debora).
% A es hijo de B si B es padre de A
hijode(A,B) :- padrede(B,A).
% A es abuelo de B si A es padre de C y C
es padre B
abuelode(A,B) :- padrede(A,C),
padrede(C,B).
% A y B son hermanos si el padre de A es
también el padre de B y si A y B no son lo mismo
hermanode(A,B) :- padrede(C,A) ,
padrede(C,B), A \== B.
% A
y B son familiares si A es padre de B o A es hijo de B o A es hermano de B
familiarde(A,B) :- padrede(A,B).
familiarde(A,B) :- hijode(A,B).
familiarde(A,B) :- hermanode(A,B).
EJEMPLOS
sum(X,Y,R) :- number(X), number(Y), R is X+Y.
sum(X,X,R) :- atom(X), concat('2',X,R).
sum(X,Y,R) :- concat(X,'+',Z), concat(Z,Y,R).
CONSULTAS
?-
sum(x,1,R). R = 'x+1' ?- sum(2,3,R). R = 5; R = '2+3' ?-
sum(1,0.5,R). R = 1.5;
R
= '1+0.5' ?- sum(x,x,R). R = '2x'; R = 'x+x' ?- sum(x,y,R). R = 'x+y'
EJMPLO:Querer
quiere_a(maria,enrique).
quiere_a(juan,jorge).
quiere_a(maria,susana).
quiere_a(maria,ana).
quiere_a(susana,pablo).
quiere_a(ana,jorge).
varon(juan).
varon(pablo).
varon(jorge).
varon(enrique).
hembra(maria).
hembra(susana).
hembra(ana).
teme_a(susana,pablo).
teme_a(jorge,enrique).
teme_a(maria,pablo).
/* Esta linea es un comentario */
quiere_pero_teme_a(X,Y)
:- quiere_a(X,Y), teme_a(X,Y).
querido_por(X,Y)
:- quiere_a(Y,X).
puede_casarse_con(X,Y)
:- quiere_a(X,Y), varon(X), hembra(Y).
puede_casarse_con(X,Y)
:- quiere_a(X,Y), hembra(X), varon(Y).
Cláusula de Horn
La sintaxis de una cláusula de Horn en
PROLOG tiene el siguiente aspecto:
hija (A, B) :- mujer (A), padre (B, A).
que podría leerse así: "A es hija de B
si A es mujer y B es padre de A".
EJEMPLOS 1
Ejercicio 1: En este ejercicio y los siguientes
vamos a realizar un ejemplo que describe la carta de un restaurante. Los
objetos que interesan son los platos que se pueden consumir y una primera
clasificación puede ser la siguiente:
·
Entradas:
paella, gazpacho, consomé
·
Carne:
filete de cerdo, pollo asado
·
Pescado:
trucha, bacalao
·
Postre:
flan, nueces con miel, naranja
Escribe como programa Prolog la
clasificación de comidas del
restaurante. El programa constara de 10 cláusulas y los predicados a usar son entrada/1, carne/1,
pescado/1 y postre/1. Prueba
después el programa con preguntas como :
?- carne(X).
?- carne(X), postre(X).
entrada(mortadela).
entrada(ensalada).
entrada(atum).
carne(chuleta).
carne(pollo_asado).
carne(filete_de_cerdo).
pescado(trucha).
pescado(bacalao).
pescado(pejerrey).
postre(flan).
postre(nueces_con_miel).
postre(naranja).
Ejercicio 2: Definir la relación
"plato_principal(X)" que
indicara que un plato principal es un plato de carne o de pescado.
plato_principal(X):- carne(X).
plato_principal(X):- pescado(X).
Ejercicio 3: Definir la relación
"comida(X,Y,Z)" que indicara
que la comida consta de tres platos, una entrada "X", un
plato principal "Y" y un
postre "Z". Pidiéndole
respuestas sucesivas a la pregunta ?- comida(X,Y,Z). podemos generar todas las
posibles comidas del restaurante.
comida(X, Y, Z):- entrada(X), plato_principal(Y), postre(Z).
EJEMPLOS 2
Ejercicio 4:Considera el siguiente programa
que describe algunas relaciones familiares
padre(andres,bernardo).
padre(andres,belen).
padre(andres,baltasar).
padre(baltasar,david).
padre(david,emilio).
padre(emilio,francisco).
madre(ana,bernardo).
madre(ana,belen).
madre(ana,baltasar).
madre(belen,carlos).
madre(belen,carmen).
Extender el programa para definir las
siguientes relaciones familiares
abuelo/2
progenitor/2
nieta/2
antepasado/2
descendiente/2
=====================================
abuelo(X, Y):- padre(X, Z), padre(Z,
Y).
abuelo(X, Y):- padre(X, Z), madre(Z,
Y).
progenitor(X, Y):- padre(X, Y).
progenitor(X, Y):- madre(X, Y).
mujer(belen).
mujer(ana).
mujer(carmen).
nieta(X, Y):- mujer(X), progenitor(Y, Z), progenitor(Z,
X).
antepasado(X, Y):- progenitor(X, Y).
antepasado(X, Y):- progenitor(X, Z), antepasado(Z,
Y).
descendiente(X, Y):- antepasado(Y, X).
Factorial de un número
function factorialRecursiva (n: integer):
integer;
BEGIN
if
n=0 then //o n<2
factorialRecursiva := 1
else
(* para N>0*)
factorialRecursiva : = n *
factorialRecursiva (n-1)
END;
% La sintaxis es factorial(N, F) ->
Factorial de N es F (el resultado se guarda en F)
factorial(0,
1) :- !.%corte if-then-else-entonces
factorial(N,
F) :- N>0, N1 is N - 1, factorial(N1, F1), F is N*F1.
%el factorial se llama recursivamente dejando el
resultado en F
?- factorial(5,F).
Fibonacci
% Author:
fibonacci(0,1).
fibonacci(1,1).
fibonacci(N,F)
:- N > 1, N1 is N-1, N2 is N-2,
fibonacci(N1,F1),
fibonacci(N2,F2), F is F1+F2.
% Imprime el resultado y sale del programa.
imprimir(N) :-write('El numero '),write(N),
write(' de la serie de Fibonacci es: '),
fibonacci(N,X),
write(X), nl, fail.%fracaso
LISTAS
La lista es una estructura de datos muy
común en la programación no numérica. Es
una secuencia ordenada de elementos que puede tener cualquier longitud. Ordenada significa que el orden de cada
elemento es significativo. Un elemento
puede ser cualquier término e incluso otra lista. Se representa como una serie de elementos
separados por comas y encerrados entre corchetes.
Para procesar una lista, la dividimos en
dos partes: la cabeza y la cola. Por
ejemplo:
Lista Cabeza Cola
[a,b,c,d] a [b,c,d]
[a] a [] (lista vacía)
[] no tiene no
tiene
[[a,b],c] [a,b] [c]
[a,[b,c]] a [[b,c]]
[a,b,[c,d]] a [b,[c,d]]
Para dividir una lista, utilizamos el
símbolo "|". Una expresión con la forma [X | Y] instanciará X a
la cabeza de una lista e Y a la cola. Por ejemplo:
Creación y consulta de listas
plantas([prolog, java , php, ruby, python,
rebol, asp,c,net]).
lista([1,2,3,4,5,6,7,8,9,10]).
?-lista([Cabeza|Cola]).
Cabeza=1
Cola=[2,3]
?-lista([H,J|T]).
H=1
J=2
T=[3]
Longitud de una lista
% La longitud de una lista vacia es 0.
% La longitud de cualquier lista es la
longitud de la cola + 1.
longitud([],0).
longitud([H|T],N):-longitud(T,N0), N is
N0 + 1.
?- longitud([a,b,c],L).
3
?- longitud([a,b,c],4).
No
Búsqueda de un elemento
% Si queremos determinar si un elemento
pertenece a una lista.
% El elemento pertenece a la lista si
coincide con la cabeza de la lista.
% El elemento pertenece a la lista si se
encuentra en la cola de la lista.
pertenece(X,[X|_]) :- !.
pertenece(X,[_|R]):- pertenece(X,R).
?-
pertenece(b,[a,b,c]).
Yes
?- pertenece(b,[a,[b,c]]).
No
?- pertenece([b,c],[a,[b,c]]).
Yes
Concatenar listas
% Si queremos concatenar dos listas lista.
% Concatenar una lista vacia con L es L.
% Concatenar X|L1 con L2 es poner el primer
% elemento de la primera lista (X) más la
% concatenación del resto de la lista (L1)
con L2
concatenar([],L,L).
concatenar([X|L1],L2,[X|L3]):-concatenar(L1,L2,L3).
?-
concatenar([1,2],[3,4],R).
R = [1, 2, 3, 4].
Eliminar elemento de una lista
% Si queremos eliminar un elemento de la
lista.
% Si X es la cabeza de la lista, la cola T
es la lista sin X
% Si X no es la cabeza de la lista,
conservamos la cabeza de la lista
%
como parte de la respuesta y continuamos eliminando X de la cola T.
elimina(X,[X|T],T).
elimina(X,[H|T],[H|T1]):- elimina(X,T,T1).
?-
elimina(1,[1,2,3,4],R).
R
= [2,3,4]
?- elimina(1,R,[2,3]).
R
= [1, 2, 3]
R
= [2, 1, 3]
R
= [2, 3, 1]
Palindromo
Interesante porque podemos usar operaciones
sobre listas para
manipular y hacer consultas sobre strings,
por ejemplo si
tenemos la regla:
palindrome(X) :- reverse(X,X).
podemos hacer las consultas
?- palindrome("hola").
No
?- palindrome("anicocina").
Yes
?-
palindrome("maripositatisopiram").
Yes
Numeros
masuno(X,Y):- Y is X+1.
xmasuno(X,Y):- Y = X+1.?-masumo(5,Y).?-xmasumo(5,Y).
XPCE/Prolog
Se hace uso de la librería XPCE, la cual ha sido
desarrollada para el desarrollo en GUI Prolog.
XPCE ha escrito una dinámica orientada a objetos del
núcleo. Métodos se puede definir en cualquier idioma. XPCE predefine un gran número de clases.
CARGANDO LA
LIBRERÍA PCE
Para poder usar predicados para trabajar con gráficos bajo
Prolog deberemos cargar la librería PCE.
:- use_module(library(pce)).
Esta línea lo que hace es decirle a
Prolog que cargue la librería una vez ha terminado de compilar, antes de que
desde el prompt de Prolog se nos deje hacer ninguna consulta.
Una vez cargada esta librería, ya
disponemos de una serie de predicados para poder crear ventanas, botones, y una
gran variedad de objetos.
CREANDO OBJETOS PARA LUEGO INTERACTUAR
Con la librería PCE se trabaja con un
esquema orientado a objetos, en donde podremos
crear clases y trabajar con diferentes objetos, pudiendo llamar a métodos de dichos
objetos (pasándoles los correspondientes parámetros) o llamar a métodos que nos
devuelvan algún valor, y obviamente si creamos objetos, también podremos
destruirlos.
Existen 4 predicados con los que se puede trabajar con
XPCE/Prolog. Estos
predicados sirven para crear objetos, enviar mensajes a objetos, recibir
mensajes de objetos y liberar la memoria de los objetos.
·
new(?Reference, +NewTerm): Este predicado recoge dos parámetros,
el primero recogería la referencia que se le asigna al nuevo objeto, ya que new
se usa para crear objetos. El segundo parámetro le indicaría el objeto que se
quiere crear.
·
send(?Receiver, +Selector(...Args...)): El primer parámetro del
predicado es una referencia al objeto al que deseemos enviarle un mensaje. El
segundo parámetro indicará el método al que queremos invocar, lo cual
indicaremos junto a los argumentos que queremos enviarle al método.
·
get(?Receiver, +Selector(+Argument...), -Result): Los dos
primeros parámetros tienen el mismo significado que para send, sin embargo el
último parámetro sirve para recoger el valor que nos devuelva el método que
hallamos invocado.
·
free(?Reference): libera la memoria asociada al objeto que se le
indica en el primer parámetro.
Las referencias se usan para saber a que objeto nos referimos, así pues
cada objeto que creemos deberá tener su propia referencia, ya que después toda
memoria que reservemos con new,
será conveniente liberarla con free.
Las variable de referencia deben crearse con el símbolo @ y el nombre de
la VAR. Posteriormente se liberara con free.
MANOS A LA OBRA: Crear un dialogo que contenga un botón y que al pulsar
sobre el mismo cierre esa ventana.
:- use_module(library(pce)).
ejemplo:-
/*
* Crea el objeto dialogo en la variable D
*/
new(D,dialog('Nombre del Dialogo')),
/*
* Crea el objeto boton almacenandolo en la variable @boton de tal forma
* que al pulsar sobre el boton libere la memoria y cierre la ventana)
*/
new(@boton, button('Cerrar Dialogo',
and(message(D, destroy),message(D, free),message(@boton, free)))),
/*
* Inserta el botón en el diálogo
*/
send(D, append(@boton)),
/*
* Le envia el mensaje open al dialogo para que cree y muestre la
ventana.
*/
send(D, open).
Otro ejemplo
:- use_module(library(pce)).
ejemplo_mensajes :-
% Crea el objeto dialogo en la variable D
new(D, dialog('Nombre del Dialogo')),
% Crea un boton que llama al predicado mostrar_mensaje
new(B, button('Mostrar en Consola',
message(@prolog, mostrar_mensaje, 'Este es el valor que tendra la
variable P'))),
% Crea un boton para cerrar el dialogo
new(@boton, button('Cerrar Dialogo',
and(
message(D, destroy),
message(D, free),
message(D, free),
message(@boton, free)))),
% Inserta los botones en el diálogo
send(D, append(@boton)),
send(D, append(B)),
% Muestre la ventana.
send(D, open).
% Muestra un mensaje en la consola.
mostrar_mensaje(P) :-
write('La variable P vale '), write(P), nl.
hola soy nuevo, usando prolog. En el primer ejemplo lo compile y lo corrí y tiene un error pero no logro indentificar cual es : [PCE error: @pce/pce: Object @prolog already exists]
ResponderEliminarfalse.
Gracias amigo, muy completo
ResponderEliminar