Upload
fleta
View
65
Download
1
Embed Size (px)
DESCRIPTION
II. Estructuras de datos en Prolog. Jorge Cabrera Gámez Departamento de Informática y Sistemas Universidad de Las Palmas de Gran Canaria. Tipos de datos. Datos. Términos simples. Estructuras. Constantes. Variables. Átomos. Números. Tipos de datos. - PowerPoint PPT Presentation
Citation preview
Prolog II 1
II. Estructuras de
datos en Prolog
Jorge Cabrera GámezDepartamento de Informática y Sistemas
Universidad de Las Palmas de Gran Canaria
Prolog II 2
Tipos de datosDatos
Términos simples Estructuras
Constantes Variables
Átomos Números
Prolog II 3
Tipos de datosDatos
Términos simples Estructuras
Constantes Variables
Átomos Números
maýusculas: A, B, ... Z
minúsculas: a, b, ... z
números: 0, 1, 2, ... 9
car. especiales: + - * / <> = : . & _ ~
Cadenas de caracteres y números y _, que comiencen con minúscula
pepe
nil
x25
a_ED
miss_jones
x_
Cadenas de caracteres especiales
<-->
===>
:-:
Ojo con predefinidos,
p.e. :-
Cadenas de caracteres encerrados entre comillas simples
‘Pepe’
‘Esther Colero’
‘Ali Catados’
Números
Enteros: 1, 3 10000
Reales: 1.00, -0.093
Prolog II 4
Tipos de datosDatos
Términos simples Estructuras
Constantes Variables
Átomos Números
Variables:
Cadenas de caracteres, números y _, que comiencen con mayúscula o _
_pepe
Nil
_x25
A_ED
_234
La variable anónima: cuando una variable aparece una sola vez no es necesario inventarnos un nombre para ella.
con_hijo(X) :- progenitor(X, Y).
con_hijo(X) :- progenitor(X, _).
El contexto léxico de una
variable es la cláusula.
1 ?- [user].|: con_hijo(X) :- progenitor(X, Y).Warning: (user://1:9): Singleton variables: [Y]
Prolog II 5
Tipos de datosDatos
Términos simples Estructuras
Constantes Variables
Átomos Números
Estructuras:
Objetos que contienen datos como componentes.
• Functores
• Listas
Prolog II 6
Functor:
Ejemplo: una estructura para representar la fecha.
fecha( 13, octubre, 1998)
Functor Argumentos
fecha
13 octubre 1998
“Cualquier día de
octubre de 1998”:
fecha( Dia, octubre, 1998)
Functor
Prolog II 7
Ejemplo:
ficha( identidad( 'Luis', 'Perez', 'Martinez'), nacimiento( fecha( 10, 5, 1970), lugar('Teror', 'Gran Canaria')), direccion( calle( 'Perez Galdos', 41), poblacion( 'Las Palmas de Gran Canaria')), datos( 42232787, estudiante, 928234567)).
ficha( identidad( 'Javier', 'Galindo', 'Martinez'), nacimiento( fecha( 1, 5, 1978), lugar('Guia', 'Gran Canaria')), direccion( calle( 'Ansite', 4), poblacion( 'Las Palmas de Gran Canaria')), datos( 42234347, estudiante, 928234117)).
ficha( identidad( 'Maria', 'Garzon', 'Martin'), nacimiento( fecha( 1, 2, 1956), lugar('Guia', 'Gran Canaria')), direccion( calle( 'Gomera', 124), poblacion( 'Santa Brigida')), datos( 89234347, arquitecto, 928234227)).
Prolog II 8
Ejemplo:?- ficha( identidad( N, A1, A2),| nacimiento( _, lugar( 'Teror', 'Gran Canaria')),| _, _).
N = 'Luis'A1 = 'Perez'A2 = 'Martinez' ;No
El nombre y apellidos de las personas nacidas en Teror de Gran Canaria
ficha( identidad( 'Luis', 'Perez', 'Martinez'), nacimiento( fecha( 10, 5, 1970), lugar('Teror', 'Gran Canaria')), direccion( calle( 'Perez Galdos', 41), poblacion( 'Las Palmas de Gran Canaria')), datos( 42232787, estudiante, 928234567)).
Prolog II 9
A efectos de eficacia, resulta conveniente simplificar laestructura de representación
ficha( 5123, identidad( 'Luis', 'Perez', 'Martinez')).
nacimiento( 5123, fecha( 10, 5, 1970), lugar('Teror', 'Gran Canaria')).
direccion( 5123, calle( 'Perez Galdos', 41), poblacion( 'Las Palmas de Gran Canaria')).
datos( 5123, 42232787, estudiante, 928234567)).
Prolog II 10
ficha
localizador identidad
nombre apellido1 apellido2
ficha ( 5123, identidad( 'Luis', 'Perez', 'Martinez')).
Prolog II 11
Ejemplo (cont.):
?- ficha( X, identidad( N, A1, A2)),| nacimiento( X, _, lugar( 'Teror', _)),| direccion( X, _, poblacion('Las Palmas de Gran Canaria')).
X = 5183N = 'Luis'A1 = 'Perez'A2 = 'Martinez' ;
No
El nombre y apellidos de las personas nacidas en (cualquier) Terory que residan en Las Palmas de Gran Canaria
Prolog II 12
Ejemplo (cont.):
?- nacimiento(X,fecha(_, _, Año), _),| datos( X, _, _, Telefono),| Año > 1975.
X = 5184Año = 1978Telefono = 928234117 ;
No
El teléfono de todas las personas nacidas después de 1975
Prolog II 13
Listas
. (a, . ( b, . ( c, [ ] )))
. (Cabeza, Cola )
.
a .
b .
c [ ]
Prolog II 14
Listas (cont.)
[a, b, c ] =
. (a, . ( b, . ( c, [ ] )))
?- Lista1 = [a, b, c],| Lista2 = .(a, .(b, .(c, []))).
Lista1 = [a, b, c]Lista2 = [a, b, c]
Yes
.
a .
b .
c [ ]
[ ]
a b c
Prolog II 15
Listas (cont.)[a, [b, c ], d ]
=[ ]
a
b
d
c
[ ]
?- display( [a, [b, c], d]).
.(a, .(.(b, .(c, [])), .(d, [])))
Yes
Prolog II 16
Listas (cont.)
Las listas se manipulan dividiéndolas en cabeza y cola
Lista
[a,b,c]
[a]
[ ]
[[el, gato], maulla ]
[maulla, [el, gato ]]
Cabeza
a
a
no tiene
[el, gato]
maulla
Cola
[ b,c ]
[ ]
no tiene
[maulla]
[[el, gato]]
Prolog II 17
Listas (cont.)
Las listas se manipulan dividiéndolas en cabeza y cola
Lista
[a,b,c]
[a]
[ ]
[[el, gato], maulla ]
[maulla, [el, gato ]]
?- [X|Y] = [a, b, c].
X = aY = [b, c]
Yes
?- [X|Y] = [a].
X = aY = []
Yes
?- [X|Y] = [].
No
?- [X|Y] = [[el, gato], maulla].
X = [el, gato]Y = [maulla]
Yes
?- [X|Y] = [maulla, [el, gato]].
X = maullaY = [[el, gato]]
Yes
Prolog II 18
Listas (cont.)
Una operación básica: unificación de listas
Lista1
[ X, Y, Z]
[ gato ]
[X, Y | Z ]
[[el, Y], Z ]
[ X, [ Y| Z ], U ]
[ X, Y, X ]
Lista2
[ se, ha, ido]
[ X | Y ]
[yo, bebo, vino ]
[[X, ratón], [se, fué ]]
[ a, [ b, c], u]
[ a, b, c ]
Unificación
X = se
Y = ha
Z = ido
Unificación
X = gato
Y = [ ]
Unificación
X = yo
Y = bebo
Z = [ vino ]
Unificación
X = el
Y = ratón
Z = [ se, fue ]
Unificación
X = a
Y = b
Z = [ c ]
U = u
Unificación
No unificables
Prolog II 19
Listas (cont.)
Cadenas de caracteres
como listas de códigos
ASCII ?- name( lógica, X).X = [108, 243, 103, 105, 99, 97] Yes
?- name(X, [108,243,103,105,99,97]).X = lógica Yes
Prolog II 20
Operaciones elementales en ListasEl predicado eslista es cierto si su argumento
es una lista.
?- eslista([ ]).Yes
?- eslista( [a | [b , d]] ).Yes
Definición
eslista( [ ] ).eslista( [ _ | _ ] ).
Prolog II 21
Operaciones elementales en Listas
El predicado pertenece es cierto si su primer
argumento pertenece a la lista que aparece como
segundo argumento.?- pertenece(a, [x,y,a,z]).Yes
?- pertenece(X, [a,b,c]).X = a ;X = b ;X = c ;No
Definición
pertenece ( X, [X | _ ] ).pertenece ( X, [ _ | Y] ) :-
pertenece (X, Y).
Prolog II 22
?- trace(pertenece). pertenece/2: call redo exit fail
Yes?- pertenece(a,[x,y,a,z]).T Call: ( 8) pertenece(a, [x, y, a, z])T Call: ( 9) pertenece(a, [y, a, z])T Call: ( 10) pertenece(a, [a, z])T Exit: ( 10) pertenece(a, [a, z])T Exit: ( 9) pertenece(a, [y, a, z])T Exit: ( 8) pertenece(a, [x, y, a, z])
Yes
pertenece ( X, [X | _ ] ).
pertenece ( X, [ _ | Y] ) :- pertenece (X, Y).
Prolog II 23
?- trace(pertenece). pertenece/2: call redo exit fail
Yes?- pertenece(a,[s,d,e]).T Call: ( 7) pertenece(a, [s, d, e])T Call: ( 8) pertenece(a, [d, e])T Call: ( 9) pertenece(a, [e])T Call: ( 10) pertenece(a, [])T Fail: ( 10) pertenece(a, [])T Fail: ( 9) pertenece(a, [e])T Fail: ( 8) pertenece(a, [d, e])T Fail: ( 7) pertenece(a, [s, d, e])
No
pertenece ( X, [X | _ ] ).
pertenece ( X, [ _ | Y] ) :- pertenece (X, Y).
Prolog II 24
?- pertenece(a,[f,a,c]). YesOjo: Mal definido
pertenece ( X, [ _ | Y] ) :- pertenece (X, Y).
pertenece ( X, [X | _ ] ).
?- trace(pertenece). pertenece/2: call redo exit failYes
?- pertenece(a,[f,a,c]). T Call: (6) pertenece(a, [f, a, c]) T Call: (7) pertenece(a, [a, c]) T Call: (8) pertenece(a, [c]) T Call: (9) pertenece(a, []) T Fail: (9) pertenece(a, []) T Redo: (8) pertenece(a, [c]) T Fail: (8) pertenece(a, [c]) T Redo: (7) pertenece(a, [a, c]) T Exit: (7) pertenece(a, [a, c]) T Exit: (6) pertenece(a, [f, a, c])
Yes
Prolog II 25
Operaciones elementales en ListasEl predicado incluir proporciona una lista que es
concatenación de otras dos.
?- incluir( [yo, no], [soy, pepe], L).
L = [yo, no, soy, pepe]
YesDefinición
incluir ( [] , L, L).incluir ( [X | L1], L2, [ X | L3] ) :-
incluir (L1, L2, L3).
?- incluir( X, [soy, pepe], [yo, soy, pepe]).
X = [yo]
Yes
Prolog II 26
?- incluir([yo],[soy, pepe],L).T Call: ( 7) incluir([yo], [soy, pepe], _G242)T Call: ( 8) incluir([], [soy, pepe], _G344)T Exit: ( 8) incluir([], [soy, pepe], [soy, pepe])T Exit: ( 7) incluir([yo], [soy, pepe], [yo, soy, pepe])
L = [yo, soy, pepe] Yes
Definición
incluir ( [] , L, L).incluir ( [X | L1], L2, [ X | L3] ) :-
incluir (L1, L2, L3).
incluir/3 es equivalente al predicado predefinido append/3
Prolog II 27
Operaciones elementales en Listas
El predicado cuenta devuelve el número de ocurrencias
de un elemento en una lista simple (sin estructura).
?- cuenta( a, [t,r,a,g,a], N).N = 2 ;
NoDefinición
cuenta( _, [], 0).cuenta(X, [X | Y], N) :- cuenta(X,Y,Z), N is Z+1.cuenta(X, [W| Y], Z) :- X \== W, cuenta(X,Y,Z).
¿ Es necesario ?
Prolog II 28
cuenta( _, [], 0).cuenta(X, [X | Y], N) :- cuenta(X,Y,Z), N is Z+1.cuenta(X, [W| Y], Z) :- X \== W, cuenta(X,Y,Z).
?- cuenta( a, [t,r,a,g,a], N).N = 2 ;No
cuenta( _, [], 0).cuenta(X, [X | Y], N) :- cuenta(X,Y,Z), N is Z+1.cuenta(X, [W| Y], Z) :- cuenta(X,Y,Z).
?- cuenta( a, [t,r,a,g,a], N).N = 2 ;N = 1 ;N = 1 ;N = 0 ;No
Prolog II 29
Operaciones elementales en Listas
El predicado elimina elimina todas las ocurrencias
de un elemento en una lista simple (sin estructura).
?- elimina( i, [e,l,i,m,i,n,a], R).R = [e, l, m, n, a]
YesDefinición
elimina( _ , [ ], [ ]).elimina( X, [X | Y], R) :- elimina( X, Y, R).elimina( X, [W| Y], [W | R]) :- X \== W, elimina( X, Y, R).
Prolog II 30
Operaciones elementales en Listas
El predicado sustituye todas las ocurrencias de un elemento
(1er arg.) por el 2º argumento en una lista simple
(sin estructura).?- sustituye( i, a, [e,l,i,m,i,n,a], R).R = [e, l, a, m, a, n, a]
YesDefinición
sustituye( _ , _ , [ ], [ ]).sustituye( X, Y, [X | U], [Y | V]) :- sustituye( X, Y, U, V).sustituye( X, Y, [Z | U], [Z | V]) :- X \== Z, sustituye( X, Y, U, V).
Prolog II 31
Operaciones elementales en Listas
El predicado reverso devuelve la lista inversa de una
dada.
?- reverso( [1,2,3,4,5], R).R = [5, 4, 3, 2, 1]
YesDefinición
reverso( L1, L2):- rev( L1, [ ], L2).rev( [ ], L, L).rev( [X | Y], L1, L2) :- rev( Y, [X | L1], L2).
Prolog II 32
?- trace(rev), trace(reverso). rev/3: call redo exit fail reverso/2: call redo exit failYes
?- reverso([1,2,3,4,5],R).T Call: ( 8) reverso([1, 2, 3, 4, 5], _G217)T Call: ( 9) rev([1, 2, 3, 4, 5], [], _G217)T Call: ( 10) rev([2, 3, 4, 5], [1], _G217)T Call: ( 11) rev([3, 4, 5], [2, 1], _G217)T Call: ( 12) rev([4, 5], [3, 2, 1], _G217)T Call: ( 13) rev([5], [4, 3, 2, 1], _G217)T Call: ( 14) rev([], [5, 4, 3, 2, 1], _G217)T Exit: ( 14) rev([], [5, 4, 3, 2, 1], [5, 4, 3, 2, 1])T Exit: ( 13) rev([5], [4, 3, 2, 1], [5, 4, 3, 2, 1])T Exit: ( 12) rev([4, 5], [3, 2, 1], [5, 4, 3, 2, 1])T Exit: ( 11) rev([3, 4, 5], [2, 1], [5, 4, 3, 2, 1])T Exit: ( 10) rev([2, 3, 4, 5], [1], [5, 4, 3, 2, 1])T Exit: ( 9) rev([1, 2, 3, 4, 5], [], [5, 4, 3, 2, 1])T Exit: ( 8) reverso([1, 2, 3, 4, 5], [5, 4, 3, 2, 1])R = [5, 4, 3, 2, 1] Yes
reverso( L1, L2):- rev( L1, [ ], L2).
rev( [ ], L, L).
rev( [X | Y], L1, L2) :- rev( Y, [X | L1], L2).
Prolog II 33
Operaciones elementales en Listas
El predicado sublista que comprueba si una lista (1er arg.)
es parte de otra dada (2º arg.).
?- sublista( [a,s,f], [b,e,a,s,f,g,h]).
Yes
Definición
sublista( S, L):- append( L1, L2, L),append(S, L3, L2).
Definición
sublista( S, L):- append( _, L2, L), append(S, _, L2).
L1 S L3
L
L2
Prolog II 34
?- sublista( [a,s,f], [b,e,a,s,f,g,h]).[debug] ?- sublista( [a,s,f], [b,e,a,s,f,g,h]). T Call: (6) sublista([a, s, f], [b, e, a, s, f, g, h]) Call: (6) sublista([a, s, f], [b, e, a, s, f, g, h]) ? creep Call: (7) append(_G598, _G599, [b, e, a, s, f, g, h]) ? creep Exit: (7) append([], [b, e, a, s, f, g, h], [b, e, a, s, f, g, h]) ? creep Call: (7) append([a, s, f], _G599, [b, e, a, s, f, g, h]) ? creep Fail: (7) append([a, s, f], _G599, [b, e, a, s, f, g, h]) ? creep Exit: (7) append([b], [e, a, s, f, g, h], [b, e, a, s, f, g, h]) ? creep Call: (7) append([a, s, f], _G602, [e, a, s, f, g, h]) ? creep Fail: (7) append([a, s, f], _G602, [e, a, s, f, g, h]) ? creep Exit: (7) append([b, e], [a, s, f, g, h], [b, e, a, s, f, g, h]) ? creep Call: (7) append([a, s, f], _G605, [a, s, f, g, h]) ? creep Exit: (7) append([a, s, f], [g, h], [a, s, f, g, h]) ? creep T Exit: (6) sublista([a, s, f], [b, e, a, s, f, g, h]) Exit: (6) sublista([a, s, f], [b, e, a, s, f, g, h]) ? creepYes
sublista( S, L):- append( _, L2, L), append(S, _, L2).
Prolog II 35
Operaciones elementales en Listas
El predicado aplana transforma una lista compleja,
que puede contener a otras listas como elementos,
en una lista sin estructura.
Definición
aplana([H|T], Lp):-aplana(H, Hp),aplana(T, Tp),append(Hp, Tp, Lp).
aplana([], []).aplana(X, [X]).
?- aplana([a, [ [b], c] ], L).L = [a, b, c]
Yes
Prolog II 36
2 ?- trace(aplana).% aplana/2: [call, redo, exit, fail]
Yes[debug] 3 ?- aplana([a,[b]],Lp).
T Call: (7) aplana([a, [b]], _G486) T Call: (8) aplana(a, _L171) T Exit: (8) aplana(a, [a]) T Call: (8) aplana([[b]], _L172) T Call: (9) aplana([b], _L192) T Call: (10) aplana(b, _L213) T Exit: (10) aplana(b, [b]) T Call: (10) aplana([], _L214) T Exit: (10) aplana([], []) T Exit: (9) aplana([b], [b]) T Call: (9) aplana([], _L193) T Exit: (9) aplana([], []) T Exit: (8) aplana([[b]], [b]) T Exit: (7) aplana([a, [b]], [a, b])
Lp = [a, b] ;
T Redo: (9) aplana([], _L193) T Exit: (9) aplana([], [[]]) T Exit: (8) aplana([[b]], [b, []]) T Exit: (7) aplana([a, [b]], [a, b, []])
Lp = [a, b, []] ;…
Esta definición produce “basura” en el backtracking.
aplana([H|T], Lp):-aplana(H, Hp),aplana(T, Tp),append(Hp, Tp, Lp).
aplana([], []).aplana(X, [X]).
Además, el uso de append/3 hace que sea muy ineficiente.
Prolog II 37
2 ?- trace(aplana2).% aplana2/2: [call, redo, exit, fail]
[debug] 11 ?- aplana2([a,[b]],Lp). T Call: (8) aplana2([a, [b]], _G501) T Call: (9) aplana2([a, [b]], [], _G501) T Call: (10) aplana2(a, [], _L189) T Exit: (10) aplana2(a, [], [a]) T Call: (10) aplana2([[b]], [a], _G501) T Call: (11) aplana2([b], [a], _L210) T Call: (12) aplana2(b, [a], _L231) T Exit: (12) aplana2(b, [a], [b, a]) T Call: (12) aplana2([], [b, a], _L210) T Exit: (12) aplana2([], [b, a], [b, a]) T Exit: (11) aplana2([b], [a], [b, a]) T Call: (11) aplana2([], [b, a], _G501) T Exit: (11) aplana2([], [b, a], [b, a]) T Exit: (10) aplana2([[b]], [a], [b, a]) T Exit: (9) aplana2([a, [b]], [], [b, a]) T Exit: (8) aplana2([a, [b]], [b, a])
Lp = [b, a] ; T Redo: (11) aplana2([], [b, a], _G501) T Exit: (11) aplana2([], [b, a], [[], b, a]) T Exit: (10) aplana2([[b]], [a], [[], b, a]) T Exit: (9) aplana2([a, [b]], [], [[], b, a]) T Exit: (8) aplana2([a, [b]], [[], b, a])
Lp = [[], b, a] …
Una nueva definición que es más eficiente.
aplana2(L,LP):-aplana2(L,[],LP).
aplana2([H|T],A,LP):-aplana2(H,A,HA),aplana2(T,HA,LP).
aplana2([],A,A).aplana2(X,A,[X|A]).
Problema: La lista resulta invertida
Prolog II 38
% Execution Aborted12 ?- trace(aplana3).% aplana3/2: [call, redo, exit, fail]% aplana3/3: [call, redo, exit, fail]
Yes[debug] 13 ?- aplana3([a,[b]],Lp). T Call: (8) aplana3([a, [b]], _G501) T Call: (9) aplana3([a, [b]], [], _G501) T Call: (10) aplana3([[b]], [], _L189) T Call: (11) aplana3([], [], _L210) T Exit: (11) aplana3([], [], []) T Call: (11) aplana3([b], [], _L189) T Call: (12) aplana3([], [], _L249) T Exit: (12) aplana3([], [], []) T Call: (12) aplana3(b, [], _L189) T Exit: (12) aplana3(b, [], [b]) T Exit: (11) aplana3([b], [], [b]) T Exit: (10) aplana3([[b]], [], [b]) T Call: (10) aplana3(a, [b], _G501) T Exit: (10) aplana3(a, [b], [a, b]) T Exit: (9) aplana3([a, [b]], [], [a, b]) T Exit: (8) aplana3([a, [b]], [a, b])
Lp = [a, b] ;
…
Lp = [a, b, []] …
Un pequeño arreglo es suficiente …
aplana3(L,LP):-aplana3(L,[],LP).
aplana3([H|T],A,LP):-aplana3(T,A,HA),aplana3(H,HA,LP).
aplana3([ ],A,A).aplana3(X,A,[X|A]).
para que la lista salga en el orden correcto.
Prolog II 39
Operaciones elementales en Listas
El predicado crossword permite encontrar las
palabras que forman un crucigrama de 6 palabras
cruzadas (3 verticales y 3 horizontales) de siete
letras cada una.Las palabras
word(abalone).word(abandon).word(enhance).word(anagram).word(connect).word(elegant).
?- crossword(V1,V2,V3,H1,H2,H3).V1 = abalone,V2 = anagram,V3 = connect,H1 = abandon,H2 = elegant,H3 = enhance Yes
Prolog II 40
word(abalone).word(abandon).word(enhance).word(anagram).word(connect).word(elegant).
crossword(V1,V2,V3,H1,H2,H3):-word(V1), name(V1,[_,C12,_,C14,_,C16,_]),word(V2), name(V2,[_,C22,_,C24,_,C26,_]),word(V3), name(V3,[_,C32,_,C34,_,C36,_]),word(H1), name(H1,[_,C12,_,C22,_,C32,_]),word(H2), name(H2,[_,C14,_,C24,_,C34,_]),word(H3), name(H3,[_,C16,_,C26,_,C36,_]).
Una versión más sofisticada – y realista - podría
partir de una “plantilla” de celdas libres y ocupadas
para definir el crucigrama. ¿Alguien se anima?
a a c abandon a a n elegant o r e enhance e m t
Prolog II 41
Sumario.
• Los objetos simples en Prolog: átomos, variables y números.• Las estructuras sirven para representar objetos compuestos.• Las estructuras se construyen por medio de functores.• Cada functor se define por su nombre y aridad.• La misma variable en dos cláusulas representa dos cosas diferentes. El ámbito léxico de una variable es la cláusula.• La lista es una estructura versátil, compuesta de cabeza y cola.