Programacio Logica :- ProLog .Paradigmes i Llenguatges de Programacio
Grau en Informatica - UdG
Mateu Villaret
Guio
I Introduccio
I Sintaxi
I Semantica operacional del Prolog
I Llistes
I Aritmetica
I Arbre de cerca i tall
Introduccio
I Prolog es un llenguatge de programacio logica que serveix pera validar fets en una teoria donada.
I L’usuari defineix una base de dades de fets i regles i Prologrespon a les preguntes que es facin sobre la teoria.
I Surt dels camps del processat de llenguatge natural, de lademostracio automatica de teoremes en logica de primer ordrei del problema de la planificacio.
“Enlloc d’escriure un algorisme per a resoldre unproblema, podem especificar el problema en logica deprimer ordre i deixar que la maquina ens el resolgui...”
Introduccio
I Les especificacions de programes es poden descriurelogicament.
I Aquestes especificacions son independents de la maquina.
I Les regles de la logica ens permeten demostrar la correctesade les especificacions independentment de l’existencia delsprogrames.
I D’altra banda existeixen metodes per a poder fer gran partd’aquestes demostracions automaticament.
I Aixı doncs, les especificacions i els programes sonpracticament el mateix...
I Eficiencia i acabamentI Entrada/sortida
Exemple: Els Simpson
Vegem un programa sobre els personatges dels Simpson.Tenim uns quants fets amb predicats unaris:
nen(bart). home(abe). dona(marge).
nen(milhouse). home(homer). dona(lisa).
nen(lisa). home(bart). dona(maggie).
nen(maggie). home(ned). dona(maude).
nen(rod). home(rod). dona(mrs krabappel).
nen(todd). home(todd). dona(ms hoover).
nen(ralph). home(chief wiggum). dona(patty).
home(ralph). dona(selma).
home(milhouse). dona(jacqueline).
...
viu(homer, adr("Evergreen Terrace", 742, "Springfield")).
viu(ned, adr("Evergreen Terrace", 744, "Springfield")).
...
Exemple: Els Simpson
Alguns fets amb relacions (o predicats) binaries:
pare(abe, homer). mare(marge, bart).
pare(homer, bart). mare(marge, lisa).
pare(homer, lisa). mare(marge, maggie).
pare(homer, maggie). mare(jacqueline, marge).
pare(ned, rod). mare(jacqueline, patty).
pare(ned, todd). mare(jacqueline, selma).
pare(chief wiggum, ralph). mare(maude, rod).
mare(maude, todd).
amic(bart, milhouse).
amic(homer, ned). casat(homer, marge).
amic(marge, maude). casat(ned, maude).
vei(ned, homer).
Exemple: Els Simpson
Tenim les seguents regles:
∀X ,Y . pare(X ,Y ) → progenitor(X ,Y )∀X ,Y . mare(X ,Y ) → progenitor(X ,Y )∀X ,Y ,Z .
(progenitor(Z ,X ) ∧ progenitor(Z ,Y ) ∧ X 6= Y
)→ germa(X ,Y )
que en Prolog serien:
progenitor(X,Y):- pare(X,Y).
progenitor(X,Y):- mare(X,Y).
germa(X,Y):- progenitor(Z,X), progenitor(Z,Y), X\=Y.
Exemple: Els Simpson
SICStus 4.0.1 (x86-win32-nt-4): Tue May 15 21:17:49 West 2007
Licensed to SP4ima.udg.edu
| ?- :-
consult(’U:/paradigmes/els\_simpson.pl’).
% consulting u:/paradigmes/els_simpson.pl...
% consulted u:/paradigmes/els_simpson.pl... in module user, 0 msec 6248 bytes
| ?- nen(bart).
yes
| ?- pare(X,bart).
X = homer ? ;
no
| ?- germa(bart,X).
X = lisa ? ;
X = maggie ? ;
...
Sintaxi
I Els Termes ens serviran per a referir-nos als objectes sobre elsque definirem la teoria: persones, llocs, valors, etc.
terme ::= variables| simbol constant| simbol funcio(termes)
termes ::= terme| terme, termes
Les variables comencen amb majuscules i els sımbols (funcionsi constants) amb minuscules.Exemples de termes:adr("Evergreen Terrace", 742, "Springfield"),homer, Algu, 742, ...
Sintaxi
I Els predicats ens serviran per a establir fets i regles sobre elstermes de la nostra teoria:
atom ::= simbol proposicio| simbol predicat(termes)
Els sımbols de proposicio i predicats comencen ambminuscules.Exemples d’atoms:viu(ned,adr("Evergreen Terrace",744,"Springfield")),home(homer), germa(X,Y), ...
SintaxiEls programes Prolog consten de:
I Fets, ens permeten “assertar” atoms a la teoria.
fet ::= atom.
Per exemple: home(homer)., amic(bart, milhouse)., ...
I Regles, ens permeten “assertar” formules condicionals ambpremises i una conclusio, a la teoria.
regla ::= atom :- atoms.
atoms ::= atom| atoms, atom
on :- representa el condicional (←), i les comes lesconjuncions (∧). Les variables estan quantificadesuniversalment.Per exemple:germa(X,Y):- progenitor(Z,X), progenitor(Z,Y), X\=Y.
Sintaxi
I Les queries o objectius que preguntem a l’interpret Prolog,son la conjuncio d’atoms que volem demostrar o refutarsegons la teoria carregada.
query ::= atoms.
En les queries, les variables estan quantificadesexistencialment. Es pregunta si existeix algun valor per a lesvariables que ens faci certa aquella conjuncio d’atoms d’acordamb la teoria.Per exemple:| ?- germa(bart,X).
| ?- home(ned).
Si al donar-nos una resposta ens apareix un interrogant, teniml’opcio de demanar que segueixi buscant altres solucions: ; .Les solucions son yes, amb assignacions de variables..., no, oesperar-se.
Exercicis d’els Simpson
Penseu com definirieu les relacions:
I avantpassat
I avi, avia
I oncle, tia
Semantica operacionalQ: germa(bart,lisa)
per la regla de germa
G: {progenitor(Z,bart), progenitor(Z,lisa), bart\=lisa}per regla progenitor
{pare(Z,bart), progenitor(Z,lisa), bart \= lisa}pel fet pare(homer, bart)
{progenitor(homer,lisa), bart \= lisa}per regla progenitor
{pare(homer,lisa), bart \= lisa}pel fet pare(homer, lisa)
{bart \= lisa}pel significat \=
{ }qed
Semantica operacional
Aquest exemple ens mostra una linea d’execucio pero en realitattenim un arbre.
I Cada vegada que tenim mes d’una opcio de resoldre unobjectiu, tenim una possible bifurcacio.
I Si per alguna de les opcions (branques) triades quedem ambalgun objectiu que no sabem resoldre, mirarem de recularbacktracking per l’arbre fins a trobar una alternativa que ensdongui opcions a resoldre tots els objectius.
I Si finalment hem explorat totes les branques i no hem pogutresoldre tots els objectius, es que la query no era demostrable.
I quan trobem una solucio (hem resolt tots els objectius) iapretem ; li estem demanant a Prolog que faci backtracking isegueixi explorant l’arbre.
Llistes
Considerant ja predicats, els arguemnts dels predicats siguenttermes qualsevols, n’hi ha uns de molt especials, les llistes:
I Les llistes van sempre dins de: [ i ].
I La llista buida es [ ]
I [X|L], denota llistes amb X com a cap i L com a cua.
I [X,Y |L], X i Y son els dos primers elements i L la cua.
I [X,Y ,Z], denota una llista amb 3 elements.
Per exemple:| ?- [1,2,3]=[X,Y|L].
L=[3], X=1, Y=2
| ?- [1,2,3]=[X,Y,Z|L].
L=[], X=1, Y=2, Z=3
| ?- [1,2,3]=[X,Y,Z,T].
no
Predicats basics sobre llistes (i)Alguns predicats classics:
I
% member(X,L) => X apareix a la llista L.
member(X,[X| ]).
member(X,[ |XS]):-member(X,XS).
Que ens respondra Prolog a:I | ?- member(X,[1,2,3]).I | ?- member(1,X).
I si canviem l’ordre de les definicions dels predicats?
I
% treu(X,L1,L2) => L2 es L1 sense X.
treu(X,[],[]).
treu(X,[X|L1],L2):-treu(X,L1,L2).
treu(X,[Y|L1],[Y|L2]):-treu(X,L1,L2).Compte, que passa si demanem mes solucions a| ?- treu(1, [1,2,1],L).
Predicats basics sobre llistes (ii)
I
% append(L1,L2,L) => L es la concatenacio de L1 i L2.
append([],Ys,Ys).
append([X|Xs],Ys,[X|Zs]):-append(Xs,Ys,Zs).
L’append es molt util, per exemple podem ”redefinir” member idefinir permutacio aixı:
I
% member(X,L) => X apareix a la llista L.
member(X,L):-append( ,[X| ],L).
I
% permutacio(L1,L2) => L2 es una permutacio d’L1.
permutacio([],[]).
permutacio(L,[X|Xs]):- append(V,[X|P],L),
append(V,P,W),
permutacio(W,Xs).
Predicats basics sobre llistes (iii)
Com veiem es poden fer molts predicats sobre llistes amb append.
I
% invers(L,In) => In es la llista L girada.
invers([],[]).
invers([X|Xs],In):-invers(Xs,Ps), append(Ps,[X],In).
I
% prefix(P,L) => P es un prefix de la llista L.
prefix(P,L):- append(P, ,L).
I
% sufix(S,L) => S es un sufix de la llista L.
sufix(S,L):- append( ,S,L).
% subllista(Lp,L) => Lp es una subllista (elements
% consecutius) de la llista L.
subllista(Lp,L) :- ...
Aritmetica (i)
I Els nombres: 33, -2, 2.3 ... i les expressions aritmetiques:3+3, 33*3+1, ... tambe son termes. Per tant:
| ?- 4 = 2+2. | ?- X = 2+2.
no X = 2+2
I Per avaluar expressions aritmetiques s’ha de fer servir elpredicat predefinit is:
% E1 is E2 => E1 unifica amb el valor aritmetic d’E2,
% E2 ha de ser avaluable aritmeticament.
| ?- 4 is 2+2. | ?- X is 2+2.
yes X = 4
| ?- 2+2 is 4. | ?- 4 is X. | ?-4 is 2+X.
no Inst. error. Inst. error.
Aritmetica (ii)
I Els predicats relacionals com <, =<, >, >=, =:= i =\= si queavaluen els dos costats (sempre que siguin avaluables):
| ?- 2+2 =:= 9/2. | ?- 2+2 =:= 9//2.
no yes
| ?- 4 mod 2 >= 2+X. | ?- 2+2 =\= 3+1.
Inst. error no
I Compte, els operadors = i == (i els seus negats \= i \==)signifiquen:
% E1 = E2 => E1 unifica E2.
% E1 == E2 => E1 i E2 son el mateix terme.
| ?- 2+X=2+Y. | ?- 2+X == 2+Y.
X=Y no
Aritmetica (iii)
El predicat del Factorial
I
% fact(+N,F) => F es el factorial del natural N.
fact(0,1).
fact(N,F):- N>0,
Np is N-1,
fact(Np,F1),
F is F1 * N.
El predicat, ”no va en totes dues direccions” ja que +N ha de serun numero degut a l’us de is:
| ?- fact(3,6). | ?- fact(3,F) | ?- fact(N,6).
yes F=6 Int. error.
Llistes i aritmetica
I
% llargada(L,N) => N es la llargada de L.
llargada([],0).
llargada([ |Xs],N):- llargada(Xs,Np), N is Np+1.
I
% conta(L,X,N) => N es quants cops apareix X a L.
conta([], ,0).
conta([X|Xs],X,N):- conta(Xs,X,Np), N is Np+1.
conta([Y|Xs],X,N):- X\=Y, conta(Xs,X,N).
I
% nessim(L,N,X) => X ocorre a la posicio N de L.
nessim([X| ],0,X).
nessim([ |Xs],N,X):- N>0, Np is N-1, nessim(Xs,Np,X).
Ordenacio
I
% parteix(X,L,Men,Maj) => Men son els elements de L
% menors que X, Maj els majors
parteix( ,[],[],[]).
parteix(X,[Y|L],[Y|Mn],Mj):- Y =< X,
parteix(X,L,Mn,Mj).
parteix(X,[Y|L],Mn,[Y|Mj]):- Y > X,
parteix(X,L,Mn,Mj).
I
% quicksort(L1,L2) => L2 es la llista L1 ordenada.
quicksort([],[]).
quicksort([X|Xs],L):- parteix(X,Xs,Men,Maj),
quicksort(Men,MenOrd),
quicksort(Maj,MajOrd),
append(MenOrd,[X|Majord],L).
Exemple de les torres de Hanoi
El famos problema de les torres de Hanoi.% hanoi(N,A,B,C,M) => M son els moviments per passar
% N discos de A a B usant C.
hanoi(s(0),A,B,C,[de a (A, B)]).
hanoi(s(N),A,B,C,Mov):-
hanoi(N,A,C,B,Mov1),
hanoi(N,C,B,A,Mov2),
append(Mov1,[de a (A,B)|Mov2],Mov).
L’arbre de cerca
Pel seguent codi representare el corresponent arbre de cerca:
q(X):- p(X).
q(0).
p(X):-a(X),b(X).
p(1).
a(2).
a(3).
b(2).
b(2).
b(3).
q(X)
p(X)�X = 0
a(X),b(X)�X = 1
b(2) b(3)
�X = 2
�X = 2
�X = 3
[X 7→ 0]
[X 7→ 1]
[X 7→ 2] [X 7→ 3]
Les solucions s’enumerarien d’esquerra a dreta, es a dir:X = 2,X = 2,X = 3,X = 1,X = 0.
Control sobre l’arbre de cerca
L’ordre de les clausules i les repeticions de clausules poden donarlloc a redundancies en les respostes i en les fallades.
I ineficiencia
I comportament no especificat
Es interesant coneixer l’arbre de cerca i poder-lo controlar.
I Prolog ens proporcions un predicat anomenat tall: !, queserveix per a podar l’arbre de cerca.
El tall !
Donada una clausula:
A:- B1,...,Bk,!,Bk+1,...,Bn.
tal que A unifica amb l’objectiu G que es vol resoldre, i B1,...,Bkes satisfan, l’efecte de ! es:
I Qualsevol altra clausula que es pogues aplicar per resoldre G
es ignorada.
I Si a l’intentar satisfer algun Bi d’entre Bk+1,...,Bn esfracassa, nomes es fa BACKTRAKING fins al tall.
I Si s’arriba a haver de refer el tall, es torna fins a l’eleccioanterior de G i es fa BACKTRAKING a partir d’alla.
L’arbre de cerca i el tallCanviant lleugerament el codi anterior...les solucions son:X = 2,X = 2,X = 0. La part grisa s’ha tallat!
q(X):- p(X).
q(0).
p(X):-a(X),!, b(X).
p(1).
a(2).
a(3).
b(2).
b(2).
b(3).
q(X)
p(X)�X = 0
a(X),!,b(X)�X = 1
!,b(2) !,b(3)
b(2) b(3)
�X = 2
�X = 2
�X = 3
[X 7→ 0]
[X 7→ 1]
[X 7→ 2] [X 7→ 3]
Exemple amb el factorial i el tall
% nums(X) => X es un numero natural. Comenca per 0.
nums(0).
nums(X):- nums(Xp), X is Xp+1.
% trobaf(X,+Y) => El factorial d’X es mes gran que Y.
trobaf(X,Y):- nums(X), fact(X,Z), Z>Y.
% fact(+N,F) => F es el factorial del natural N.
fact(0,1).
fact(N,F):- Np is N-1,
fact(Np,F1),
F is F1 * N.
fact(0,1):- !.
fact(N,F):- Np is N-1,
fact(Np,F1),
F is F1 * N.
La query: | ?- trobaf(X,6). utilitzant el factorial de l’esquerraes penjara, mentre que usant el de la dreta no.
Exemple d’ordenacio i el tall
% ordenada(L) => L es una llista ordenada creixent.
ordenada([]).
ordenada([X]).
ordenada([X,Y|Zs]):- X=<Y,
ordenada([Y|Zs]).
% ordena(X,Y) => Y es la llista X ordenada creixentment.
ordena(Xs,Xs):- ordenada(Xs), !.
ordena(Xs,Ys):- append(As,[X,Y|Ns],Xs), X>Y,
!,
append(As,[Y,X|Ns],Xs1), ordena(Xs1,Ys).
I El primer tall ens diu ”d’ordenacio nomes n’hi ha una, pertant no cal mirar si puc ordenar d’una manera diferent”.
I El segon tall ens diu, ”si trobes un parell d’elementdesordenats, segur que s’han d’ordenar, per tant no cal queprovis de deixar-los per mes tard”.
La negacio
I La negacio en ProLog es \+(P) on P es un predicat.
I Funciona segons la CWA, ”assumpcio del mon tancat”: elliteral es satisfa quan no pot demostrar P (i acaba es clar).
q(a).
q(b):- q(a).
| ?- \+(q(c)).yes
| ?- \+(q(b)).no
| ?- \+(q(X)).no
Termes, programar amb unificacio
I Prolog no ens permet definir tipus nous.
I Per a usar altres tipus, hem de crear una definicio delcomportament dels termes:
% arrela(N,A,B,T) => T es l’arbre de node N, fe A i fd B.
arrela(N, A1, A2, arbre(N, A1, A2)).
% node(T,N) => N es l’arrel de l’arbre T.
node( arbre(N, , ), N).
% fe(T,TE)/fd(T,TD) => TE/TD es fill esquerra/dret de T.
fe(arbre( ,AE, ), AE).
fd(arbre( , , AD), AD).
% preordre(T,L) => L es el preordre de l’arbre T.
preordre(arbre(N, A1, A2),[N|L]):- preordre(A1,L1),
preordre(A2,L2),
append(L1,L2,L).
preordre(abuit,[]).
Exemple d’entrada/sortida, tall i aritmetica.
% repeat => un predicat que es satisfa sempre.
repeat.
repeat:- repeat.
% llegeix(X) => X es un numero entrat per teclat.
llegeix(X):- repeat, write(Numeret),
read(X), number(X), !.
% tracta(X) => Si X es 0 es satisfa i talla,
% si no, en calcula el quadrat, el mostra i falla.
tracta(0):- !.
tracta(X):- R is X*X, writeln([X, ’^ 2=’, R]), fail.
% quadrats => Llegeix enters i en mostra el quadrat
% fins que s’entra un 0.
quadrats:- repeat, llegeix(X), tracta(X), !.
Top Related