Sunteți pe pagina 1din 36

Capitolul 1

Elemente de baz ale limbajului


Prolog
nceputul programrii logice poate fi atribuit lui R. Kowalski i A. Colmerauer i
se situeaz la nceputul anilor '70. Kowalski a plecat de la o formul logic de
tipul:
S1 S2 ... Sn S
care are, n logica cu predicate de ordinul nti, semnificaia declarativ conform
creia S1 S2 ... Sn implic S, adic dac S1 i S2 ... i Sn sunt fiecare adevrate
atunci i S este adevrat, i a propus o interpretare procedural asociat. Conform
acestei interpretri, formula de mai sus poate fi scris sub forma:
S dac S1 i S2 ... i Sn
i poate fi executat ca o procedur a unui limbaj de programare recursiv, unde S
este antetul procedurii i S1, S2, ... Sn corpul acesteia. Deci, pe lng interpretarea
declarativ, logic, a unei astfel de formule, aceasta poate fi interpretat
procedural astfel: pentru a executa S se execut S1 i S2 ... i Sn.
n aceeai perioad, A. Colmerauer i colectivul lui de cercetare de la
Universitatea din Marsilia, au dezvoltat un limbaj de implementare a acestei
abordri, pe care l-au denumit Prolog, abreviere de la "Programmation et
Logique". De atunci i pn n prezent, limbajul Prolog s-a impus ca cel mai
important limbaj de programare logic i s-au dezvoltat numeroase implementri,
att ale unor interpretoare ct i ale unor compilatoare ale limbajului.
Limbajul Prolog este un limbaj declarativ, susinut de o component
procedural. Spre deosebire de limbajele procedurale, cum ar fi C sau Java, n care
rezolvarea problemei este specificat printr-o serie de pai de execuie sau aciuni,
ntr-un limbaj declarativ problema este specificat prin descrierea universului
problemei i a relaiilor sau funciilor existente ntre obiecte din acest univers.
Exemple de astfel de limbaje sunt cele funcionale, de exemplu Lisp, Scheme, ML,
i cele logice, de exemplu Prolog.
Dei iniial a fost gndit pentru scrierea programelor de prelucrare a
limbajului natural, Prolog a devenit cu timpul, un limbaj de uz general, fiind o

CAPITOLUL 1

unealt important n aplicaiile de inteligen artificial. Anumite clase de


probleme pot fi rezolvate mai uor n Prolog, dect n orice alt limbaj procedural.
Pentru aceste probleme, un program Prolog poate avea de 10 ori mai puine linii
dect echivalentul lui n C++ sau Java. Astfel de probleme sunt n principal cele
dedicate prelucrrilor simbolice sau care necesit un proces de cutare a soluiei
ntr-un spaiu posibil de transformri ale problemei, n acest ultim caz structura de
control implicit a mainii Prolog facilitnd implementarea.
Prezentarea ce urmeaz a limbajului Prolog, este n principal orientat pe
descrierea limbajului Prolog standard. Exemplele de programe din aceast parte,
ct i din partea a doua, sunt rulate utiliznd interpretorul SWI-Prolog sub
Windows, mediul de programare SWI-Prolog i particularitile lui sintactice fiind
prezentate n anex.

1.1 Entitile limbajului Prolog


Limbajul Prolog este un limbaj logic, descriptiv, care permite specificarea
problemei de rezolvat, n termenii unor fapte cunoscute despre obiectele
universului problemei i a relaiilor existente ntre aceste obiecte. Execuia unui
program Prolog const n deducerea implicaiilor acestor fapte i relaii, programul
definind astfel o mulime de consecine ce reprezint nelesul sau semnificaia
declarativ a programului.
Un program Prolog conine urmtoarele entiti:

fapte despre obiecte i relaiile existente ntre aceste obiecte;


reguli despre obiecte i relaiile dintre ele, care permit deducerea
(inferarea) de noi fapte pe baza celor cunoscute;

ntrebri, numite i scopuri, despre obiecte i relaiile dintre ele, la care


programul rspunde pe baza faptelor i regulilor existente.

1.1.1

Fapte

Faptele sunt predicate de ordinul nti de aritate n, considerate adevrate. Ele


stabilesc relaii ntre obiectele universului problemei. Numrul de argumente ale
faptelor este dat de aritatea (numrul de argumente) corespunztoare a
predicatelor.

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

Exemple:
Fapt:
papagal(coco).
iubete(mihai, maria).
iubete(mihai, ana).
frumoas(ana).
bun(gelu).
deplaseaz(cub, camera1, camera2).

Aritate:
1
2
2
1
1
3

Interpretarea particular a predicatului i a argumentelor acestuia depinde de


programator. Ordinea argumentelor, odat fixat, este important i trebuie
pstrat la orice alt utilizare a faptului, cu aceeai semnificaie. Mulimea faptelor
unui program Prolog formeaz baza de cunotine Prolog. Se va vedea mai trziu
c n baza de cunotinte a unui program Prolog sunt incluse i regulile Prolog.

1.1.2

Scopuri

Obinerea consecinelor sau a rezultatului unui program Prolog se face prin fixarea
unor scopuri, care pot fi adevrate sau false, n funcie de coninutul bazei de
cunotine Prolog. Scopurile sunt predicate, pentru care se dorete aflarea valorii
de adevr n contextul faptelor existente n baza de cunotine. Cum scopurile pot
fi vzute ca ntrebri, rezultatul unui program Prolog este rspunsul la o ntrebare
(sau la o conjuncie de ntrebri). Acest rspuns poate fi afirmativ, yes, sau
negativ, no. Se va vedea mai trziu c programul Prolog, n cazul unui rspuns
afirmativ la o ntrebare, poate furniza i alte informaii din baza de cunotine.
Exemplu
Considernd baza de cunotine specificat anterior, se pot pune diverse
ntrebri, cum ar fi:
?- iubeste(mihai, maria).
yes
deoarece acest fapt exist n baza de cunotine
?- papagal(coco).
yes
?- papagal(mihai).
no
deoarece acest fapt nu exist n baza de cunotine
?- inalt(gelu).
no

1.1.3

CAPITOLUL 1

Variabile

n exemplele prezentate pn acum, argumentele faptelor i ntrebrilor au fost


obiecte particulare, numite i constante sau atomi simbolici. Predicatele Prolog, ca
orice predicate n logica cu predicate de ordinul I, admit ca argumente i obiecte
generice numite variabile. n Prolog, prin convenie, numele argumentelor
variabile ncepe cu liter, iar numele constantelor simbolice ncepe cu liter mic.
O variabil poate fi instaniat (legat), dac exist un obiect asociat acestei
variabile, sau neinstaniat (liber), dac nu se tie nc ce obiect va desemna
variabila.
La fixarea unui scop Prolog, care conine variabile, acestea sunt
neinstaniate, iar sistemul ncearc satisfacerea acestui scop, cutnd printre
faptele din baza de cunotine un fapt, care se poate identifica cu scopul, printr-o
instaniere adecvat a variabilelor din scopul dat. Este vorba de fapt, de un proces
de unificare a predicatului scop cu unul din predicatele fapte, existente n baza de
cunotine.
La ncercarea de satisfacere a scopului, cutarea se face ntotdeauna pornind
de la nceputul bazei de cunotine. Dac se ntlnete un fapt, cu un simbol
predicativ identic cu cel al scopului, variabilele din scop se instaniaz conform
algoritmului de unificare i valorile variabilelor astfel obinute sunt afiate, ca
rspuns la satisfacerea acestui scop.
Exemple:
?- papagal(CineEste).
CineEste = coco
?- deplaseaza(Ce, DeUnde, Unde).
Ce = cub, DeUnde = camera1, Unde = camera2
?- deplaseaza(Ce, Aici, Aici).
no
Cum se comport sistemul Prolog n cazul n care exist mai multe fapte n
baza de cunotine care unific cu ntrebarea pus ? n acest caz exist mai multe
rspunsuri la ntrebare, corespunznd mai multor soluii ale scopului fixat. Prima
soluie este dat de prima unificare i exist attea soluii, cte unificri diferite
exist. La realizarea primei unificri, se marcheaz faptul care a unificat i care
reprezint prima soluie. La obinerea urmtoarei soluii, cutarea este reluat de la
marcaj n jos, n baza de cunotine. Obinerea primei soluii este de obicei numit
satisfacerea scopului, iar obinerea altor soluii, resatisfacerea scopului. La
satisfacera unui scop, cutarea se face ntotdeauna de la nceputul bazei de
cunotine. La resatisfacerea unui scop, cutarea se face ncepnd de la marcajul
stabilit de satisfacerea anterioar a acelui scop.

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

Sistemul Prolog, fiind un sistem interactiv, permite utilizatorului obinerea


fie a primului rspuns, fie a tuturor rspunsurilor. n cazul n care, dup afiarea
tuturor rspunsurilor, un scop nu mai poate fi resatisfcut, sistemul rspunde no.
Exemple:
?- iubeste(mihai, X).
X = maria;
tastnd caracterul ; i Enter, cerem o nou
soluie
X = ana;
no
?- iubeste(Cine, PeCine).
Cine = mihai, PeCine = maria;
Cine = mihai, PeCine = ana;
no
Exist deci dou soluii pentru scopul iubeste(mihai, X) i tot dou soluii
pentru scopul iubeste(Cine, PeCine), considernd tot baza de cunotine
prezentat n seciunea 1.1.1.

1.1.4

Reguli

O regul Prolog exprim un fapt care depinde de alte fapte i este de forma:
S :- S1, S2, Sn.
cu semnificaia prezentat la nceputul acestui capitol. Fiecare Si, i = 1,n i S au
forma faptelor Prolog, deci sunt predicate, cu argumente constante, variabile sau
structuri. Faptul S care definete regula, se numete antet de regul, iar S1, S2, Sn
formeaz corpul regulii i reprezint conjuncia de scopuri, care trebuie satisfcute
pentru ca antetul regulii s fie satisfcut.
Fie urmtoarea baz de cunotine Prolog:
frumoasa(ana).
bun(vlad).
cunoaste(vlad, maria).
cunoaste(vlad, ana).
iubeste(mihai, maria).
iubeste(X, Y) :bun(X),
cunoaste(X, Y),
frumoasa(Y).

%1
%2
%3
%4
%5
%6

CAPITOLUL 1

Se observ c enunul (6) definete o regul Prolog; relaia


iubeste(Cine, PeCine), fiind definit att printr-un fapt (5) ct i printr-o regul
(6).
n condiiile existenei regulilor n baza de cunotine Prolog, satisfacerea
unui scop se face printr-un procedeu similar cu cel prezentat n Seciunea 1.1.2,
dar unificarea scopului se ncearc att cu fapte din baza de cunotine, ct i cu
antetul regulilor din baz. La unificarea unui scop cu antetul unei reguli, pentru a
putea satisface acest scop trebuie satisfcut regula. Aceasta revine la a satisface
toate faptele din corpul regulii, deci conjuncia de scopuri.
Scopurile din corpul regulii devin subscopuri, a cror satisfacere se va
ncerca printr-un mecanism similar cu cel al satisfacerii scopului iniial.
Pentru baza de cunotine descris mai sus, satisfacerea scopului
?- iubeste(vlad, ana).
se va face n urmtorul mod. Scopul unific cu antetul regulii (6) i duce la
instanierea variabilelor din regula (6): X = vlad i Y = ana. Pentru ca aceast
ntrebare s fie adevrat, trebuie ndeplinit regula, deci fiecare subscop din
corpul acesteia. Aceasta revine la ndeplinirea scopurilor bun(vlad), care reuete
prin unificare cu faptul (2), cunoaste(vlad, ana), care reuete prin unificare cu
faptul (4), i a scopului frumoasa(ana), care reuete prin unificare cu faptul (1).
n consecin, regula a fost ndeplinit, deci i ntrebarea iniial este adevrat, iar
sistemul rspunde yes.
Ce se ntmpl dac se pune ntrebarea:
?- iubeste(X, Y).
Prima soluie a acestui scop este dat de unificarea cu faptul (5), iar rspunsul este:
X = mihai, Y = maria
Sistemul Prolog va pune un marcaj n dreptul faptului (5) care a satisfcut
scopul. Urmtoarea soluie a scopului iubeste(X, Y) se obine ncepnd cutarea
de la acest marcaj n continuare, n baza de cunotine. Scopul unific cu antetul
regulii (6) i se vor fixa trei noi subscopuri de ndeplinit, bun(X), cunoaste(X, Y)
i frumoasa(Y). Scopul bun(X) este satisfcut de faptul (2) i variabila X este
instaniat cu valoarea vlad, X = vlad . Se ncearc acum satisfacerea scopului
cunoaste(vlad, Y), care este satisfcut de faptul (3) i determin instanierea
Y = maria. Se introduce n baza de cunotine un marcaj asociat scopului
cunoaste(vlad, Y), care a fost satisfcut de faptul (3).

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

Se ncearc apoi satisfacerea scopului frumoasa(maria). Acesta eueaz. n


acest moment, sistemul intr ntr-un proces de backtracking, n care se ncearc
resatisfacerea scopului anterior satisfcut, cunoaste(vlad, Y), n sperana c o
noua soluie a acestui scop va putea satisface i scopul curent care a euat,
frumoasa(Y). Resatisfacerea scopului cunoaste(vlad, Y) se face pornind cutarea
de la marcajul asociat scopului n jos, deci de la faptul (3) n jos. O nou soluie
(resatisfacere) a scopului cunoaste(vlad, Y) este dat de faptul (4), care determin
instanierea Y = ana. n acest moment, se ncearc satisfacerea scopului
frumoasa(ana). Cum este vorba de un nou scop, cutarea se face de la nceputul
bazei de cunotine i scopul frumoasa(ana) este satisfcut de faptul (1). n
consecin a doua soluie a scopului iubeste(X, Y) este obinut i sistemul
rspunde:
X = vlad, Y = ana
urmnd un mecanism de backtracking, descris intuitiv n figura 1.1, prin
prezentarea arborilor de deducie construii de sistemul Prolog.
iubeste(X,Y)
%5 iubeste(mihai,maria)
SUCCES
solutie 1: X=mihai, Y=maria

iubeste(X,Y)

bun(X)

cunoaste(X,Y)

%2 bun(vlad)

%6 frumoasa(Y)

cunoaste(vlad,Y)

frumoasa(maria) %1 frumoasa(ana)

SUCCES %3 cunoaste(vlad,maria) %4 cunoaste(vlad,ana) INSUCCES


SUCCES

SUCCES

SUCCES

solutie 2: X=vlad, Y=ana

Figura 1.1. Mecanismul de satisfacere a scopurilor n Prolog


La ncercarea de resatisfacere a scopului iubeste(X, Y), printr-un mecanism
similar, se observ c nu mai exist alte solutii. n concluzie, fiind dat baza de
fapte i reguli Prolog anterioar, comportarea sistemului Prolog este:
?- iubeste(X, Y).

CAPITOLUL 1

X = mihai, Y = maria;
X = vlad, Y = ana;
no
Observaii:

La satisfacerea unei conjuncii de scopuri n Prolog, se ncearc


satisfacerea fiecrui scop pe rnd, de la stnga la dreapta. Prima
satisfacere a unui scop determin plasarea unui marcaj n baza de
cunotine n dreptul faptului sau regulii care a determinat satisfacerea
scopului.

Dac un scop nu poate fi satisfcut (eueaz), sistemul Prolog se ntoarce


i ncearc resatisfacerea scopului din stnga, pornind cutarea n baza de
cunotine de la marcaj n jos. nainte de resatisfacerea unui scop, se
elimin toate instanierile de variabile, determinate de ultima satisfacere
a acestuia. Dac cel mai din stnga scop din conjuncia de scopuri nu
poate fi satisfcut, ntreaga conjuncie de scopuri eueaz.

Aceast comportare a sistemului Prolog, n care se ncearc n mod


repetat satisfacerea i resatisfacerea scopurilor din conjunciile de
scopuri definete mecanismul de backtracking din Prolog.

n capitolul 4 se va discuta pe larg structura de control a sistemului


Prolog, mecanismul fundamental de backtracking i modurile n care se
poate modifica parial acest mecanism.

1.1.5

Un program Prolog simplu

Simplitatea i expresivitatea limbajului Prolog poate fi pus n eviden de


urmtorul exemplu, care permite definirea rapid a unor relaii de asociere.
capitala(burundi,bujumbura).
capitala(bahamas,nassau).
capitala(africa_de_sud,pretoria).
capitala(canada,otawa).
capitala(chile,santiago).
capitala(elvetia,berna).
capitala(danemarca,copenhaga).
capitala(somalia,mogadiscio).
capitala(slovenia,ljubljana).
continent(burundi,africa).
continent(bahamas,america_de_nord).

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

continent(africa_de_sud,africa).
continent(canada,america_de_nord).
continent(chile,america_de_sud).
continent(elvetia,europa).
continent(danemarca,europa).
continent(somalia,africa).
continent(slovenia,europa).
capitala_continent(Oras,Cont):capitala(Tara,Oras),continent(Tara,Cont).
Pentru ntrebarea
?- capitala_continent(bujumbura,Cont).
Cont = africa.
sistemul Prolog indic continentul n care se afl capitala Bujumbura. De
asemenea, se pot cere programului toate continentele asociate capitalelor indicate
n baza de date Prolog astfel:
?- capitala_continent(Capitala,Cont).
Capitala = bujumbura
Cont = africa ;
Capitala = nassau
Cont = america_de_nord ;
Capitala = pretoria
Cont = africa ;
Capitala = otawa
Cont = america_de_nord ;
Capitala = santiago
Cont = america_de_sud ;
Capitala = berna
Cont = europa ;
Capitala = copenhaga
Cont = europa ;
Capitala = mogadiscio
Cont = africa ;
Capitala = ljubljana
Cont = europa ;
No

10

CAPITOLUL 1

1.2 Sintaxa limbajului Prolog


Aa cum s-a artat n seciunea anterioar, un program Prolog este format din
fapte, reguli i ntrebri, acestea fiind construite pe baza predicatelor definite de
utilizator sau predefinite. n orice sistem Prolog, exist o mulime de predicate
predefinite, unele dintre acestea fiind predicate standard, iar altele depinznd de
implementare. Argumentele predicatelor Prolog, prin analogie cu logica
predicatelor de ordinul I, se numesc termeni, i pot fi constante, variabile sau
structuri.
Clasificarea obiectelor n Prolog este prezentat n figura 1.2.

atomi
structuri
iruri de caractere
constante

obiecte

numere ntregi
obiecte elementare
numere reale
variabile
Figura 1.2. Clasificarea obiectelor n Prolog

1.2.1

Constante

Constantele definesc obiecte specifice, particulare, sau relaii particulare. Exist


dou tipuri de constante: atomi i numere. Atomii sunt constante simbolice care
ncep, de obicei, cu o liter i pot conine litere, cifre i caracterul _. Exist i
alte caractere ce pot forma atomi speciali, care au o semnificaie aparte n limbaj.
Atomii pot desemna:

obiecte constante care sunt argumentele predicatelor, de exemplu atomii


mihai i maria n faptul iubeste(mihai, maria);

predicate Prolog, fie cele definite de utilizator, fie cele predefinite n


sistem; de exemplu atomul iubeste n faptul iubeste(mihai, maria);

atomi speciali, de exemplu atomii :- i ?- ;


diverse alte reguli de construcie sintactic a atomilor depind de
implementare.
Numerele pot fi ntregi sau reale; sintaxa particular acceptat, ct i
domeniile de definiie depinznd de implementare. Un numar ntreg este un ir de
cifre zecimale, eventual precedate de un semn. Exemple de numere ntregi: 1 +23

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

11

1515 0 -97. Numerele reale depind de implementarea de Prolog. n general, ele


sunt reprezentate ntr-o form similar celor din limbaje gen Pascal, C, etc.
Exemple de numere reale: 3.14 -0.0035 100.2 +12.02.

1.2.2

Variabile

Variabilele sunt, din punct de vedere sintactic, tot atomi, dar ele au o semnificaie
special, aa cum s-a artat n Seciunea 1.1.3. Spre deosebire de regulile generale
admise pentru construcia atomilor, numele unei variabile poate ncepe i cu
simbolul _, ceea ce indic o variabil anonim. Utilizarea unei variabile
anonime semnific faptul c nu intereseaz valoarea la care se va instania acea
variabil.
De exemplu, interogarea ?- iubeste( _, maria). semnific faptul c se
ntreab dac exist cineva care o iubete pe Maria, dar nu intereseaz cine anume.
Limbajul Prolog face distincia ntre litere mari i litere mici (este case sensitive).
Se reamintete c, din punctul de vedere al conveniei Prolog, numele oricrei
variabile trebuie s nceap fie cu liter mare, fie cu _.
n Prolog exist situaii n care o variabil apare o singur dat ntr-o regula,
caz n care nu avem nevoie de un nume pentru ea, deoarece nu este referit dect
ntr-un singur loc. De exemplu, dac dorim s scriem o regul care ne spune dac
cineva este fiul cuiva, o soluie ar fi:
este_fiu(X) :- parinte(Z, X).
Se observ c s-a denumit cu Z un printe anonim. n acest caz, nu
intereseaz cine apare pe post de printe. Pentru a nu ncrca regulile cu nume
inutile, care pot distrage atenia i ngreuia citirea programelor, se pot considera
astfel de variabile ca anonime, notate cu underscore _. Deci regula anterioar se
poate rescrie astfel:
este_fiu(X) :- parinte( _ , X).
Variabilele din Prolog nu sunt identice ca semnificaie cu variabilele Pascal
sau C, fiind mai curnd similare cu variabilele n sens matematic. O variabil,
odat ce a primit o valoare, nu mai poate fi modificat. Acest lucru elimin
efectele laterale care sunt permise n limbajele procedurale. O variabil Prolog
neinstaniat semnific ceva necunoscut. Pentru structurile de date, care nu sunt
variabile i care au nume, numele lor ncepe cu minuscul, urmat de litere, cifre
sau underscore.
Reprezentarea irurilor depinde de implementarea Prolog. n SWI-Prolog,
interpretor care se aliniaz la standardul Edinbourg Prolog, irurile se reprezint
ntre caractere '.

12

CAPITOLUL 1

Exemple de iruri de caractere:


'Constantin Noica'
'<<-------->>'
Diferena dintre iruri i atomi este urmtoarea: irurile au o reprezentare
intern mai relaxat i nu pot fi folosite pe post de atomi, n timp ce atomii au de
obicei reprezentri interne consumatoare de memorie, n ideea c ei trebuie regsii
rapid, cautrile Prolog facndu-se n general dup aceti atomi.

1.2.3

Structuri

O structur Prolog este un obiect ce desemneaz o colecie de obiecte corelate


logic, care formeaz componentele structurii. Un exemplu este structura asociat
obiectului carte, care este format din componentele: titlu carte, autor, i an
apariie. Un fapt ce refer relaia de posedare a unei cri de Prolog de ctre Mihai
poate fi exprimat astfel:
poseda(mihai, carte(prolog, clocksin, 1997)).
unde carte(prolog, clocksin, 1997) este o structur cu numele carte i cu trei
componente: prolog, clocksin i 1997. Se admit i structuri imbricate, de exemplu:
poseda(mihai, carte(prolog, autori(clocksin, mellish), 1997)).
unde predicatul poseda are dou argumente: primul argument este constanta
mihai, iar cel de-al doilea este structura carte(prolog ....), cu dou componente, a
doua component fiind structura autori(clocksin, mellish).
n Prolog, o structur se definete prin specificarea:
(1) numelui structurii ( functorul structurii);
(2) elementelor structurii (componentele structurii).
Fie tipul punct(X, Y). Atunci tipul segment poate fi reprezentat ca
segment(P1, P2). De exemplu, un segment, avnd capetele n punctele (1, 1) si
(2, 3), poate fi reprezentat astfel:
segment(punct(1, 1), punct(2, 3)).
Structurile Prolog pot fi utilizate pentru reprezentarea structurilor de date
(liste, arbori). De exemplu, un arbore binar poate fi reprezentat n Prolog printr-o
structur cu functorul arb si trei componente: rdcina, subarbore stng si
subarbore drept. Astfel, structura
arb(barbu, arb(ada, vid, vid), vid)

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

13

reprezint un arbore binar cu cheia din rdcina barbu, cu subarborele drept vid i
cu subarborele stng format dintr-un singur nod cu cheia ada.
Exist i cazuri n care un obiect poate avea constitueni compui de
adncime variabil. Astfel se ajunge la al doilea tip de recursivitate n Prolog, i
anume, recursivitatea obiectelor. De exemplu, un arbore binar, cu chei numerice
poate fi definit astfel:
1) Nodul vid este un arbore; putem nota acest nod vid prin constanta
nil;
2) Un nod frunz este un arbore, de exemplu nod(15, nil, nil);
3) Un nod cu succesor stng i succesor drept este un arbore, de
exemplu nod(20, ArbStng, ArbDrept).
De exemplu, reprezentarea n Prolog a arborelui

1
2

7
este nod(1, nod(2, nod(4, nil, nil), nod(5, nod(7, nil, nil), nil)), nod(3, nil, nod(6,
nil, nil)))
Observaii:

Sintaxa structurilor este aceeai cu cea a faptelor Prolog. Un predicat


Prolog poate fi vzut ca o structur a crui functor este numele
predicatului, iar argumentele acestuia reprezint componentele structurii.

Considerarea predicatelor Prolog ca structuri prezint un interes


deosebit; att datele ct i programele n Prolog au aceeai form, ceea ce
faciliteaz tratarea uniform i sinteza dinamic de programe. n
capitolul 4 se vor prezenta predicate predefinite n Prolog, care permit
sinteza i execuia dinamic a programelor Prolog.

14

CAPITOLUL 1

1.2.4

Operatori

Uneori este convenabil s se scrie anumii functori (nume de structuri sau


predicate) n form infixat. Aceasta este o form sintactic ce mrete claritatea
programului, cum ar fi cazul operatorilor aritmetici sau al operatorilor relaionali.
Limbajul Prolog ofer o mulime de operatori, unii care se regsesc n
aproape orice implementare, iar alii care sunt specifici unei versiuni particulare de
implementare a limbajului. n continuare se vor prezenta o parte dintre operatorii
din prima categorie.
(1) Operatori aritmetici
Operatorii aritmetici binari, cum ar fi +, -, *, /, pot fi scrii n Prolog n notaie
infixat; de exemplu:
1 + 2*(X * Y) / Z
Aceast sintax este de fapt o rescriere infixat a formei prefixate a structurilor
echivalente:
+(1, / (* (2,*(X, Y)), Z))
Este important de reinut c operatorii aritmetici sunt o rescriere infixat a
unor structuri, deoarce valoarea expresiei astfel definit nu este calculat.
Evaluarea expresiei se face la cerere, n cazul n care se folosete operatorul
predefinit infixat is, de exemplu:
X is 1 + 2.
va avea ca efect instanierea variabilei X la valoarea 3.
(2) Operatori relaionali
Operatorii relaionali sunt predicate predefinite infixate. Un astfel de operator este
operatorul de egalitate =. Predicatul (operatorul) de egalitate X = Y reuete daca
X unific cu Y. Din aceasta cauz, dndu-se un scop de tipul X = Y, regulile de
decizie care indic dac scopul se ndeplinete sau nu sunt urmtoarele:

Dac X este variabil neinstaniat, iar Y este instaniat la orice obiect


Prolog, atunci scopul reuete. Ca efect lateral, X se va instania la
aceeai valoare cu cea a lui Y. De exemplu:
?- carte(barbu, poezii) = X.
este un scop care reuete i X se instaniaz la carte(barbu, poezii).

Dac att X ct i Y sunt variabile neinstaniate, scopul X = Y reuete,


variabila X este legat la Y i reciproc. Aceasta nseamn c ori de cte

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

15

ori una dintre cele dou variabile se instaniaz la o anumit valoare,


cealalt variabila se va instania la aceeai valoare.

Atomii i numerele sunt ntotdeauna egali cu ei nii.


Dou structuri sunt egale dac au acelai functor, acelai numr de
componente i fiecare component dintr-o structur este egal cu
componenta corespunztoare din cealalt structur. De exemplu, scopul:
autor(barbilian, ciclu(uvedenrode, poezie(riga_crypto))) =
autor(X, ciclu(uvedenrode, poezie(Y)))
este satisfcut, iar ca efect lateral se fac instanierile:
X = barbilian i Y = riga_crypto.
Operatorul de inegalitate \= se definete ca un predicat opus celui de
egalitate. Scopul X \= Y reuete dac scopul X = Y nu este satisfcut i eueaz
dac X = Y reuete. n plus, exist predicatele relaionale de inegalitate, definite
prin operatorii infixai >, <, =<, >=, cu semnificaii evidente.
Un operator interesant este =:=. El face numai evaluare aritmetic i nici o
instaniere. Exemplu:
?- 1 + 2 =:= 2 + 1.
yes
?- 1 + 2 = 2 + 1.
no
Predicatul = = testeaz echivalena a dou variabile. El consider cele dou
variabile egale doar dac ele sunt deja partajate. X = = Y reuete ori de cte ori
X = Y reuete, dar reciproca este fals:
?- X = = X.
X=_23
?- X= =Y.
no
?- X=Y, X= =Y.
X=_23, Y=_23

%variabil neinstaniat

% X i Z variabile neinstaniate partajate

Comentariile dintr-un program Prolog sunt precedate de caracterul %.


Exemple:
1. n cele mai multe implementri Prolog exist predefinit operatorul de
obinere a modulului unui numr, mod. Presupunnd c nu exist

16

CAPITOLUL 1

operatorul predefinit mod, se poate scrie un predicat Prolog cu efect


similar. O definiie posibil a predicatului modulo(X, Y, Z), cu
semnificaia argumentelor Z = X mod Y , presupunnd X, Y > 0, este:
% modulo(X, Y, Z)
modulo(X, Y, X) :- X < Y.
modulo(X, Y, Z) :- X >= Y, X1 is X - Y, modulo(X1, Y, Z).
2. Plecnd de la predicatul modulo definit anterior, se poate defini
predicatul de calcul al celui mai mare divizor comun a dou numere,
conform algoritmului lui Euclid, presupunnd X > 0 , Y > 0 , astfel:
% cmmdc(X, Y, C)
cmmdc(X, 0, X).
cmmdc(X, Y, C) :- modulo(X, Y, Z), cmmdc(Y, Z, C).
La ntrebarea
?- cmmdc(15, 25, C).
C=5
rspunsul sistemului este corect. n cazul n care se ncearc obinerea
unor noi soluii (pentru semnificaia cmmdc acest lucru este irelevant,
dar intereseaz din punctul de vedere al funcionrii sistemului Prolog) se
observ c sistemul intr ntr-o bucl infinit, datorit imposibilitii
resatisfacerii scopului modulo(X, Y, Z) pentru Y = 0. Dac la definiia
predicatului modulo se adaug faptul:
modulo(X, 0, X).
atunci predicatul modulo(X, Y, Z) va genera la fiecare resatisfacere
aceeai soluie, respectiv soluia corect, la infinit. Cititorul este sftuit
s traseze execuia predicatului cmmdc n ambele variante de
implementare a predicatului modulo.
3. Doi copii pot juca un meci ntr-un turneu de tenis dac au aceeai vrsta.
Fie urmtorii copii i vrstele lor:
copil(peter, 9).
copil(paul, 10).
copil(chris, 9).
copil(susan, 9).
Toate perechile de copii care pot juca un meci ntr-un turneu de tenis
sunt calculate de predicatul:

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

17

pot_juca(Pers1, Pers2) :copil(Pers1, Varsta), copil(Pers2, Varsta), Pers1 \= Pers2.


4. S scriem un program care s i gseasc Anei un partener la bal. Ea
dorete s mearg cu un brbat care este nefumator sau vegetarian.
Pentru aceasta dispunem de o baza de date cu informaii despre civa
brbai:
barbat(gelu). barbat(bogdan). barbat(toma).
fumator(toma). fumator(dan).
vegetarian(gelu).
Pentru a exprima doleanele Anei, vom scrie dou reguli:
Ana se ntlnete cu X dac X este brbat i nu este fumtor.
Ana se ntlnete cu X dac X este brbat i este vegetarian.
Adic:
ana_se_intalneste_cu(X) :- barbat(X), not(fumator(X)).
ana_se_intalneste_cu(X) :- barbat(X), vegetarian(X).
5. Un program Prolog este o niruire de fapte (facts) i reguli (rules) care
poart denumirea de clauze (clauses). Faptele i regulile au o structura
comun, ceea ce permite sinteza dinamic de cod, care este adaugat n
baza de cunotine. Un fapt poate fi privit ca o regul care are ca premiz
(ipotez) scopul true, care este adevrat ntotdeauna. Astfel:
fapt.
este echivalent cu
fapt :- true.
O regula fr antet, deci de forma:
:- scop.
determin execuia automat a scopului scop la reconsultarea bufer-ului
n care apare. Efectul este similar cu cel obinut la introducerea n
fereastra principal a ntrebrii:
?- scop.
Exemple de ntrebari:
place(ellen, tennis).
place(john, fotbal).
place(tom, baseball).
place(eric, not).

% lui ellen i place tenisul


% lui john i place fotbalul
% lui tom place baseball-ul
% lui eric i place notul

18

CAPITOLUL 1

place(mark, tenis).
place(bill, X) :- place(tom, X).

% lui mark i place tenisul


% lui bill i place ce i place lui tom

% Ce sporturi i plac lui john?


?- place(john, X).
X = fotbal
% Cui i place tenisul?
?- place(Y, tenis).
Y = ellen;
Y = mark
% Putem pune i ntrebri particulare:
?- place(ellen, tenis).
yes
?- place(ellen, fotbal).
no
?- place(bill, baseball).
yes

1.2.5

Liste

O list este o structur de date ce reprezint o secven ordonat de zero sau mai
multe elemente. O list poate fi definit recursiv astfel:
(1)

lista vid (lista cu 0 elemente) este o list

(2)

o list este o structur cu dou componente: primul element din list


(capul listei) i restul listei (lista format din urmatoarele elemente
din lista).

Sfritul unei liste este de obicei reprezentat ca lista vid.


n Prolog structura de list este reprezentat printr-o structur standard,
predefinit, al crei functor este caracterul . i are dou componente: primul
element al listei i restul listei. Lista vid este reprezentat prin atomul special [ ].
De exemplu, o list cu un singur element a se reprezint n Prolog, prin notaie
prefixat astfel .(a, [ ]), iar o list cu trei elemene, a, b, c, se reprezint ca:
.(a, . (b, . (c, [ ]))).
Deoarece structura de list este foarte des utilizat n Prolog, limbajul ofer
o sintax alternativ pentru descrierea listelor, format din elementele listei

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

19

separate de virgul i ncadrate de paranteze drepte. De exemplu, cele dou liste


anterioare pot fi exprimate astfel:
[a]
[a, b, c]
Aceast sintax a listelor este general i valabil n orice implementare
Prolog. O operaie frecvent asupra listelor este obinerea primului element dintr-o
list i a restului listei, deci a celor dou componente ale structurii de list. Aceast
operaie este realizat n Prolog de operatorul de scindare a listelor | scris sub
urmtoarea form:
[Prim | Rest]
Variabila Prim st pe postul primului element din list, iar variabila Rest pe
postul listei care conine toate elementele din list cu excepia primului. Acest
operator poate fi aplicat pe orice list care conine cel puin un element. Dac lista
conine exact un element, Rest va reprezenta lista vid. ncercarea de identificare a
structurii [Prim | Rest] cu o list vid duce la eec. Mergnd mai departe, se pot
obine chiar primele elemente ale listei i restul listei. Iat cteva echivalene:
[a, b, c] = [a | [b, c] ] = [a, b | [c] ] = [a, b, c | [ ]] = [a | [b | [c]]] = [a | [b | [c | [ ]]] ].
n Prolog, elementele unei liste pot fi atomi, numere, liste i n general orice
structuri. n consecin se pot construi liste de liste.
Exemple:
1. Se poate defini urmtoarea structur de list:
[carte(barbu, poezii), carte(clocksin, prolog)]
2. Considernd urmtoarele fapte existente n baza de cunotine Prolog
pred([1, 2, 3, 4]).
pred([coco, sta, pe, [masa, alba]]).
se pot pune urmtoarele ntrebri obinnd rspunsurile specificate:
?- pred([Prim | Rest]).
Prim = 1, Rest = [2, 3, 4];
Prim = coco, Rest = [sta, pe, [masa, alba]];
no
?- pred([ _, _ , _ , [ _ | Rest]])
Rest = [alba]

20

CAPITOLUL 1

3. Un predicat util n multe aplicaii este cel care testeaz apartenena unui
element la o list i care se definete astfel:
% membru(Element, Lista)
membru(Element, [Element | _ ]).
membru(Element, [ _ | RestLista]) :- membru(Element, RestLista).
Funcionarea acestui scurt program Prolog poate fi urmrit cernd
rspunsul sistemului la urmtoarele scopuri:
?- membru(b, [a, b, c]). %1
yes
?- membru(X, [a, b, c]).
X = a;
X = b;
X = c;
no
?- membru(b, [a, X, b]).
X = b;
X = _G302;
no

%2

%3

Deci pentru cazul n care primul argument este o variabil (%2), exist
trei soluii posibile ale scopului membru(Element, Lista). Dac lista
conine o variabil (%3), exist dou soluii pentru forma listei: [a, b, b],
cnd X se instaniaz la b i predicatul reuete cu b membru pe a doua
poziie, i [a, _ , b], caz n care variabila X este neinstaniat lucru
marcat de sistem printr-un indentificator arbitrar de forma _G302 i
predicatul reuete cu b membru pe a treia poziie.
Observaii:

Exemplul 3 pune n eviden o facilitate deosebit de interesant a


limbajului Prolog, respectiv puterea generativ a limbajului. Predicatul
membru poate fi utilizat att pentru testarea apartenenei unui element la
o list, ct i pentru generarea, pe rnd, a elementelor unei liste, prin
resatisfacere succesiv. n anumite contexte de utilizare, aceast facilitate
poate fi folositoare, iar n altele ea poate genera efecte nedorite atunci
cnd predicatul membru este utilizat n definirea altor predicate, aa
cum se va arta n partea a doua a lucrrii.

La definirea unui predicat p, care va fi utilizat n definirea altor


predicate, trebuie ntotdeauna s se analizeze numrul de soluii ct i
soluiile posibile ale predicatului p. Acest lucru este necesar, deoarece

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

21

dac p apare ntr-o conjuncie de scopuri p1,, pi-1, p ,pi+1,, pn i unul


dintre scopurile pi+1,, pn eueaz, mecanismul de backtracking din
Prolog va ncerca resatisfacerea scopului p. Numrul de soluii, precum
i soluiile scopului p influeneaz astfel, n mod evident, numrul de
soluii, ct i soluiile conjunciei de scopuri p1,, pi-1, p ,pi+1,, pn.
Exemple n acest sens i modaliti de reducere a numrului total de
soluii ale unui corp vor fi prezentate n capitolul 4.

1.3 Limbajul Prolog i logica cu predicate de ordinul


nti
Limbajul Prolog este un limbaj de programare logic. Dei conceput iniial pentru
dezvoltarea unui interpretor de limbaj natural, limbajul s-a impus ca o soluie
practic de construire a unui demonstrator automat de teoreme folosind rezoluia.
Demonstrarea teoremelor prin metoda rezoluiei necesit ca axiomele i teorema s
fie exprimate n forma clauzal. Sintaxa i semantica limbajului Prolog permit
utilizarea numai a unei anumite forme clauzale a formulelor bine formate: clauze
Horn distincte. Se prezint n continuare, pe scurt, noiunile logice de baz
semnificative pentru limbajul Prolog.

1.3.1

Clauze Horn

Definiie. Se numete clauz o disjuncie de literali. Un literal este un predicat


sau un predicat negat. Se numete clauz Horn o clauz care conine cel mult un
literal pozitiv.
Definiie. Se numete clauz vid o clauz far nici un literal; clauza vid se
noteaz, prin convenie, cu .
Deoarece faptele i regulile Prolog sunt n form clauzal, forma particular
a clauzelor fiind clauze Horn distincte, acestea din urm se mai numesc i clauze
Prolog.
Definiie. Se numete clauz Horn o clauz care conine cel mult un literal
pozitiv. O clauz Horn poate avea una din urmtoarele patru forme:
(1)

o clauz unitar pozitiv format dintr-un singur literal pozitiv;

(2)

o clauz negativ format numai din literali negai;

(3)

o clauz format dintr-un literal pozitiv i cel puin un literal negativ,


numit i clauz Horn mixt;

(4)

clauz vid (

).

22

CAPITOLUL 1

Definiie. Se numete clauz Horn distinct o clauz care are exact un literal
pozitiv, ea fiind fie o clauz unitar pozitiv, fie o clauz Horn mixt.
Clauzele Horn unitare pozitive se reprezint n Prolog prin fapte, iar
clauzele Horn mixte prin reguli. O clauz Horn mixt de forma:
S1 S2 Sn S
se exprim n Prolog prin regula:
S :- S1, S2, Sn.
Semnificaia intuitiv a unei reguli Prolog are un corespondent clar n logica
cu predicate de ordinul I dac se ine cont de faptul c o clauz Horn mixt poate
proveni din urmtoarea formul bine format:
S1 S2 Sn S
Variabilele din clauzele distincte se transform n variabile Prolog,
constantele din aceste formule n constante Prolog, iar funciile pot fi asimilate cu
structuri Prolog. Deci argumentele unui predicat Prolog au forma termenilor din
calculul cu predicate de ordinul I.
Exemple:
1. Fie urmtoarele enunuri: Orice sportiv este puternic. Oricine este inteligent i
puternic va reui n via. Oricine este puternic, va reui n via sau va ajunge
btu. Exist un sportiv inteligent. Gelu este sportiv. Exprimnd enunurile n
logica cu predicate de ordinul I se obin urmtoarele formule bine formate:
A1.

(x) (sportiv(x) puternic(x))

A2.

(x) (inteligent(x) puternic(x) reuete(x))

A3.

(x) (puternic(x) (reuete(x) btu(x)))

A4.

(x) (sportiv(x) inteligent(x))

A5.

Sportiv(gelu)

Axiomele se transform n forma clauzal i se obin urmtoarele clauze:


C1.

sportiv(x) puternic(x)

C2.

inteligent(x) ~ puternic(x) reuseste(x)

C3.

~ puternic(x) reuseste(x) bataus(x)

C4.

sportiv(a)

C4'. inteligent(a)
C5.

sportiv(gelu)

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

23

Clauzele C1, C2, C4, C4' i C5 pot fi transformate n Prolog deoarece


sunt clauze Horn distincte, dar clauza C3 nu poate fi transformat n
Prolog. Programul Prolog care se obine prin transformarea acestor
clauze este urmtorul:
puternic(X) :- sportiv(X).
reuseste(X) :- inteligent(X), puternic(X).
sportiv(a).
inteligent(a).
sportiv(gelu).
2. Fie urmtoarele enunuri:
(a) Orice numr raional este un numr real.
(b) Exist un numr prim.
(c) Pentru fiecare numr x exist un numr y astfel nct x < y .
Dac se noteaz cu prim(x) x este numr prim, cu rational(x) x este
numr raional, cu real(x) x este numr real i cu mai_mic(x, y) x
este mai mic dect y, reprezentarea sub form de formule bine formate
n calculul cu predicate de ordinul I este urmtoarea:
A1.

(x) (raional(x) real(x))

A2.

(x) prim(x)

A3.

(x) (y) mai_mic(x, y)

Reprezentarea n form clauzal este:


C1.

~ rational(x) real(x)

C2.

prim(a)

C3.

mai_mic(x, mai_mare(x))

unde mai_mare(x) este funcia Skolem care nlocuiete variabila y


cuantificat existenial. Forma Prolog echivalent a acestor clauze este:
real(X) :- rational(X).
prim(a).
mai_mic(X, mai_mare(X)).
unde mai_mare(x) este o structur Prolog.
Este evident c nu orice axiom poate fi transformat n Prolog i c,
dintr-un anumit punct de vedere, puterea expresiv a limbajului este inferioar
celei a logicii cu predicate de ordinul I. Pe de alt parte, limbajul Prolog ofer o

24

CAPITOLUL 1

mulime de predicate de ordinul II, adic predicate care accept ca argumente alte
predicate Prolog, care nu sunt permise n logica cu predicate de ordinul I. Acest
lucru ofer limbajului Prolog o putere de calcul superioar celei din logica clasic.
Uneori, aceste predicate de ordinul II, existente n Prolog, pot fi folosite pentru a
modela versiuni de programe Prolog, echivalente cu o mulime de axiome, care nu
au o reprezentare n clauze Horn distincte. Se propune cititorului, dup
parcurgerea seciunii urmtoare, s revin la Exemplul 1 i s ncerce gsirea unei
forme Prolog relativ echivalente (cu un efect similar) cu clauza C3.

1.3.2

Respingere rezolutiv

Limbajul Prolog demonstreaz scopuri (teoreme) prin metoda respingerii


rezolutive. Strategia rezolutiv utilizat n Prolog este strategia rezoluiei de intrare
liniar. Aplicarea principiului rezoluiei n logica cu predicate de ordinul I, implic
construirea rezolventului a doi literali complementari, care fie sunt identici, fie au
fost fcui identici, prin aplicarea substituiei, definit de cel mai general unificator
al celor doi literali asupra clauzelor ce conin aceti doi literali.
Definiie.

Fie clauzele:

(C1) P1 P2 ... Pi ... Pn


(C2) Q1 Q2 ... ~ Q j ... Q m
numite clauze printe i cel mai general unificator al literalilor Pi si Qj, cu
Pi = Q j . Atunci C = rez (C1 ,C2 ) = (C1 - {Pi }) (C 2 - {~ Q j }) este un
rezolvent binar al clauzelor C1 si C2.
Observaie. Rezolventul a dou clauze nu este unic. Aplicarea rezoluiei ntre
dou clauze care rezolv poate genera diveri rezolveni n cazul n care n cele
dou clauze exist mai muli literali complementari care, prin unificare, pot fi
fcui identici.
Demonstrarea teoremelor aplicnd metoda respingerii prin rezoluie poate fi
descris de algoritmul urmtor. Enunurile care descriu problema trebuie
exprimate n modelul logic i formeaz mulimea de axiome A. Concluzia care
trebuie obinut, deci rezolvarea problemei, este teorema de demonstrat.

Algoritm:

Respingerea prin rezoluie n logica cu predicate de ordinul I

1.
Convertete setul de axiome A n form clauzal i obine mulimea de
clauze S0
2.
Neag teorema de demonstrat, transform teorema negat n form
clauzala i adaug rezultatul obinut la S0, S S0

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

3.

25

repet

3.1.

Selecteaz o pereche de clauze C1, C2

3.2.

Fie literalii L1 C1 si ~ L2 C2

3.3.

Aplic unificarea i calculeaz = mgu(L1 ,L2 )

3.4.

dac
atunci

3.4.1. Determin C = rez(C1,C2 )


3.4.2. dac C
atunci S S {C}
pn

s-a obinut clauza vid ( ) sau


nu mai exist nici o pereche de clauze care rezolv sau
o cantitate predefinit de efort a fost epuizat

4.

dac s-a obinut clauza vid


atunci teorema este adevarat (este demonstrat)

5.

altfel
5.1.

dac nu mai exist nici o pereche de clauze care rezolv


atunci teorema este fals

5.2.

altfel nu se poate spune nimic despre adevrul teoremei

sfrsit.
Observaii:

In cazul n care s-a obinut clauza vid, metoda respingerii prin rezoluie
garanteaz faptul c teorema este adevarat, deci demonstrabil pe baza
setului de axiome A.

Reciproc, dac teorema este adevarat, se poate obine clauza vid, dup
un numr finit de execuii ale pasului 3, cu condiia ca strategia de
rezoluie s fie complet.

Condiia de oprire a ciclului, "o cantitate predefinit de efort a fost


epuizat" a fost introdus, deoarece metoda demonstrrii teoremelor prin
respingere rezolutiv este semidecidabil n logica cu predicate de
ordinul I. In cazul n care concluzia T de demonstrat este fals, deci nu
este teorem, este posibil sa se ajung n situaia n care, dac avem
noroc, "nu mai exist nici o pereche de clauze care rezolv". Atunci se
poate concluziona c teorema este fals. Dar este de asemenea posibil ca

26

CAPITOLUL 1

pasul 3 s se execute la infinit, dac T nu este teorem. Din acest motiv,


se introduce o cantitate predefinit de efort (resurse de timp sau spaiu) la
epuizarea creia algoritmul se oprete. In acest caz, s-ar putea ca teorema
sa fie adevarat, dar efortul predefinit impus sa fie prea mic, sau se poate
ca T s nu fie teorem. Rezult deci c, nu se poate spune nimic despre
adevrul teoremei.

Strategia rezoluiei liniare are la baz urmatoarea idee: orice rezolvent


obinut n rezoluie este utilizat ca unul din cei doi rezolveni pe baza crora se
obine urmtorul rezolvent. Astfel, daca S este mulimea iniial de clauze, C0S
clauza de pornire, atunci:
C1 {Rez(C0, Ci)| C0, Ci S}
Ck+1 {Res(Ck, Ci)| Ci {Ck-1, Ck-2, ..}S}, k=1, 2, 3,

Strategia rezoluiei de intrare liniar este un caz particular al strategiei


rezoluiei liniare, n care una din clauzele care rezolv aparine ntotdeauna setului
initial de axiome. Astfel, dac S este mulimea iniial de clauze, C0S clauza de
pornire, atunci:
C1 {Rez(C0, Ci)| C0, Ci S}
Ck+1 {Res(Ck, Ci)| Ci S}, k=1, 2, 3,
Strategia rezoluiei liniare de intrare este o strategie rezolutiv foarte
eficient, dar nu este o strategie care, dei nu este complet n general, este
complet pentru clauze Horn. Aceast strategie este deosebit de eficient din punct
de vedere al implementrii i jutific astfel forma restricionat a clauzelor Prolog
(clauze Horn).

1.4 Structura de control a limbajului Prolog


Spre deosebire de limbajele de programare clasice, n care programul definete
integral structura de control i fluxul de prelucrri de date, n Prolog exist un
mecanism de control predefinit.

1.4.1

Seminificaia declarativ i procedural

Semnificaia declarativ a unui program Prolog se refer la interpretarea strict


logic a clauzelor acelui program, rezultatul programului fiind reprezentat de toate
consecinele logice ale acestuia. Semnificaia declarativ determin dac un scop
este adevrat (poate fi satisfcut) i, n acest caz, pentru ce instane de variabile
este adevrat scopul. Se reamintete c o instan a unei clauze este clauza de baz

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

27

(clauza fr variabile) obinut prin instanierea variabilelor din clauza iniial. n


aceste condiii semnificaia declarativ a unui program Prolog se poate defini
precum urmeaz:

Definiie. Un scop S este adevrat ntr-un program Prolog, adic poate fi


satisfcut sau deriv logic din program, dac i numai dac:
1.

exist o clauz C a programului;

2.

exist o instan I a clauzei C astfel nct:


2.1.

antetul lui I s fie identic cu cel al lui S;

2.2.

toate scopurile din corpul lui I sunt adevrate, deci pot fi


satisfcute.

Observaii:

n definiia de mai sus clauzele refer att fapte, ct i reguli Prolog.


Antetul unei clauze este antetul regulii, dac clauza este o regul Prolog
(clauz Horn mixt) i este chiar faptul, dac clauza este un fapt Prolog
(clauz unitar pozitiv). Corpul unui fapt este considerat vid i un fapt
este un scop, care se ndeplinete ntotdeauna.

n cazul n care ntrebarea pus sistemului Prolog este o conjuncie de


scopuri, definiia anterioar se aplic fiecrui scop din conjuncie.

Semnificaia procedural a unui program Prolog se refer la modul n care


sistemul ncearc satisfacerea scopurilor, deci la strategia de control utilizat.
Diferena dintre semnificaia declarativ i semnificaia procedural este aceea c
cea de a doua definete, pe lnga relaiile logice specificate de program, i ordinea
de satisfacere a scopurilor i subscopurilor. n prima seciune a acestui capitol s-a
fcut o prezentare informal a modalitii procedurale de satisfacere a scopurilor n
Prolog. n continuare, se rafineaz aceast comportare. Din punct de vedere
procedural, un program Prolog poate fi descris de schema bloc prezentat n figura
1.3.
Program Prolog

Conjuncii
de scopuri

Execuie sistem
Prolog

Indicator SUCCES sau INSUCCES


Instanele variabilelor din scopuri

Figura 1.3. Comportarea procedural a sistemului Prolog

28

CAPITOLUL 1

Semnificaia procedural a unui program Prolog poate fi descris de


urmtorul algoritm, n care L = {S1, S2, , Sn} este lista de scopuri de satisfcut,
iar B este lista de instanieri (unificri) ale variabilelor din scopuri, iniial vid.
Aceast list se va actualiza la fiecare apel.

Algoritm. Strategia de control Prolog


SATISFACE(L,B)
1. dac L = {}

% lista vid

atunci afieaz B i ntoarce SUCCES.


2. Fie S1 primul scop din L i p predicatul referit de S1. Parcurge clauzele
programului, de la prima clauz sau de la ultimul marcaj fixat, asociat lui p,
pn ce se gsete o clauz C al crei antet unific cu S1.
3. dac nu exist o astfel de clauz

atunci ntoarce INSUCCES.


4. Fie C de forma H :- D1,,Dm, m0. Plaseaz un marcaj n dreptul clauzei C,
asociat lui p. (H conine predicatul p).
5. Redenumete variabilele din C i obtine C' astfel nct s nu existe nici o
variabil comun ntre C' i L; C' este de tot forma H :- D1,,Dm. cu
redenumirile fcute.
6. L { D1,,Dm, S2,,Sn }

% dac C este fapt, atunci L se va reduce

7. Fie B1 instanierea variabilelor care rezult din unificarea lui S1 cu H.


8. Substituie variabilele din L cu valorile date de B1 i obine:

L { D1,,Dm, S2,,Sn }.
9. B B B1.
10. dac SATISFACE(L, B)=SUCCES

atunci afieaz B i ntoarce SUCCES.


11. repet de la 1.

sfrit
Observaii:

Algoritmul de mai sus reprezint de fapt implementarea strategiei


rezolutive de intrare liniar utilizat de limbajul Prolog, pentru care se
impune o ordine prestabilit de considerare a clauzelor.

Algoritmul arat funcionarea sistemului pentru gsirea primei soluii.

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

29

Indicatorul SUCCES/INSUCCES corespunde rspunsurilor de yes,


respectiv no, date de sistemul Prolog la ncercarea de satisfacere a unei
liste de scopuri.

1.4.2

Ordinea clauzelor i a scopurilor

Urmtoarele dou exemple pun n eviden diferena dintre semnificaia


declarativ i semnificaia procedural a programelor Prolog. Primul exemplu este
un scurt program care definete relaiile de printe i strmo existente ntre
membrii unei familii. Se dau patru definiii posibile ale relaiei de strmo, str1,
str2, str3 i str4, toate fiind perfect corecte din punct de vedere logic, deci din
punct de vedere a semnificaiei declarative a limbajului.
% parinte(IndividX, IndividY), stramos(IndividX, IndividZ)
parinte(vali, gelu).
parinte(ada, gelu).
parinte(ada, mia).
parinte(gelu, lina).
parinte(gelu, misu).
parinte(misu, roco).
str1(X, Z) :- parinte(X, Z).
str1(X, Z) :- parinte(X, Y), str1(Y, Z).
% Se schimb ordinea regulilor:
str2(X, Z) :- parinte(X, Y), str2(Y, Z).
str2(X, Z) :- parinte(X, Z).
% Se schimb ordinea scopurilor n prima variant:
str3(X, Z) :- parinte(X, Z).
str3(X, Z) :- str3(X, Y), parinte(Y, Z).
% Se schimb att ordinea regulilor, ct i ordinea scopurilor:
str4(X, Z) :- str4(X, Y), parinte(Y, Z).
str4(X, Z) :- parinte(X,Z).

30

CAPITOLUL 1

vali

ada

gelu

mia

lina

miu

roco
Figura 1.4. Arborele genealogic definit de programul Prolog
Figura 1.4 prezint arborele genealogic definit de faptele Prolog anterioare.
n raport cu semantica declarativ a limbajului se pot schimba, fr a modifica
nelesul logic, att ordinea clauzelor care definesc relaia de strmo, ct i
ordinea scopurilor n corpul regulii de aflare a strmoilor. Schimbnd ordinea
clauzelor, se obine din predicatul str1 definiia alternativ a relaiei de strmo
str2; schimbnd ordinea scopurilor din corpul regulii n varianta iniial se obine
definiia predicatului str3; i, schimbnd att ordinea clauzelor, ct i ordinea
scopurilor n regul, se obine predicatul str4.
Comportarea programului folosind cele patru definiii alternative, dac se
dorete aflarea adevrului relaiei de strmo pentru perechile (ada, miu) i
(mia, roco), este cea prezentat n continuare.

?- str1(ada, misu).
yes
Pentru acest scop, arborele de deducie este prezentat n figura 1.5.

str1(ada, misu)
parinte(ada, misu)
INSUCCES

parinte(ada, Y), str1(Y, misu)


Y=gelu

str1(gelu, misu)

parinte(ada, gelu)
parinte(gelu, misu)
SUCCES
SUCCES
Figura 1.5. Arborele de deducie a scopului str1(ada, misu)

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

31

?- str2(ada, misu).
yes
?- str3(ada, misu).
yes
Pentru scopul str3(ada, misu), arborele de deducie este cel prezentat n
figura 1.6.

str3(ada, misu)
parinte(ada, misu)
INSUCCES

str3(ada, Y), parinte(Y, misu)


Y=Y'

parinte(gelu, misu)

parinte(ada, Y')
Y'=gelu

SUCCES

parinte(ada, gelu)
SUCCES
Figura 1.6. Arborele de deducie a scopului str3(ada, misu)
?- str4(ada, misu).
% bucl infinita; mesaj de depire a stivei (ERROR: Out of local stack)
Pentru acest scop, arborele de deducie este cel prezentat n figura 1.7.

str4(ada, misu)
str4(ada, Y), parinte(Y, misu)
str4(ada, Y'), parinte(Y', Y)
str4(ada, Y"), parinte(Y", Y)
...
arbore infinit
Figura 1.7. Arborele de deducie (infinit) a scopului str4(ada, misu)
Din punctul de vedere al semnificaiei procedurale, cele patru definiii nu
sunt echivalente. Primele dou, str1 i str2, pot da rspuns pozitiv sau negativ la
orice ntrebare, dar str2 este mai ineficient dect str1. Cititorul poate ncerca

32

CAPITOLUL 1

trasarea arborelui de deducie al satisfacerii scopului str2(ada, misu) i


compararea acestuia cu cel corespunztor satisfacerii scopului str1(ada, misu).
Definiia str4 produce o bucl infinit datorit intrrii infinite n recursivitate. Este
evident o definiie greit din punct de vedere procedural. Definiia relaiei de
strmo str3 este o definiie "capcan". Dup cum se poate observ din arborele de
deducie prezentat, rspunsul sistemului este afirmativ, n cazul n care exist o
relaie de strmo ntre cele dou persoane argumente ale predicatului. n cazul n
care o astfel de relaie nu exist, sistemul intr ntr-o bucl infinit, cum ar fi, de
exemplu, pentru persoanele mia i roco.

?- str1(mia, roco).
no
?- str2(mia, roco).
no
?- str3(mia, roco).
% bucl infinit; mesaj de depire a stivei
n acest caz, arborele de deducie al scopului str3(mia, roco) este prezentat
n figura 1.8. Datorit semnificaiei procedurale a limbajului Prolog, trebuie
urmrit cu atenie modul de definire a unui predicat, att din punctul de vedere al
ordinii clauzelor, ct i din punctul de vedere al ordinii scopurilor n corpul
regulilor.

str3(mia, roco)
parinte(mia, roco)

str3(mia, Y), parinte(Y, roco)

INSUCCES parinte(mia, Y)

str3(mia, Y'), parinte(Y', Y)

INSUCCES parinte(mia, Y')

str3(mia, Y"), parinte(Y", Y')

INSUCCES parinte(mia, Y")

...
arbore infinit

INSUCCES
Figura 1.8. Arbore de deducie infinit pentru un scop fals
Al doilea exemplu se refer la rezolvarea n Prolog a urmtoarei probleme.
O maimu se gsete la ua unei camere i o banan se afl agat de plafon n
centrul camerei. Lng fereastra camerei se afl o cutie pe care maimua o poate
folosi pentru a se urca pe ea i a ajunge la banan. Maimua tie s fac
urmtoarele micri: s mearg pe sol, s se urce pe cutie, s deplaseze cutia dac

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

33

este lng cutie, s apuce banana dac este pe cutie i cutia este n centrul camerei.
Se cere s se scrie un program Prolog care s descrie aceast problem i care s
poat rspunde dac, dintr-o configuraie iniial specificat prin poziia maimuei
i a cubului, maimua poate apuca banana, dup execuia unei secvene de micri.
Reprezentarea universului problemei n Prolog este specificat dup cum
urmeaz. Starea iniial este:
(1) Maimua este la u.
(2) Maimua este pe sol.
(3) Cutia este la fereastr.
(4) Maimua nu are banana.

i poate fi descris prin structura Prolog:


stare(la_usa, pe_sol, la_fereastra, nu_are_banana)
Starea final este aceea n care maimua are banana
stare( _ , _ , _ , are_banana)
Micrile cunoscute de maimu, deci operatorii de tranziie dintr-o stare n alta,
sunt:
(m1) Apuc banana.

apuc

(m2) Urc pe cutie.

urc

(m3) Mut cutia.

mut(Poziia1, Poziia2)

(m4) Merge (maimua se deplaseaz pe sol).

merge(Poziia1, Poziia2)

i sunt reprezentate prin structurile Prolog indicate la dreapta micrilor.


Dintr-o anumit stare numai anumite micri sunt permise. De exemplu,
maimua nu poate apuca banana dect dac este urcat pe cutie i cutia este n
centrul camerei, adic sub banan. Micrile permise pot fi reprezentate n Prolog
prin predicatul de deplasare depl cu trei argumente:
depl(Stare1, Micare, Stare2)
Micare
Stare1
Stare2
care transform problema din starea Stare1 n starea Stare2, prin efectuarea
micrii legale Micare n starea Stare1. Se observ c, reprezentarea aleas este
o reprezentare a problemei, folosind spaiul strilor.

34

CAPITOLUL 1

Soluia problemei este completat prin adugarea predicatului


poatelua(Stare), care va reui, dac maimua poate ajunge din starea iniial Stare
ntr-o stare final, n care poate lua banana, stare final descris de:
poate_lua(stare( _ , _ , _ , are_banana)).
Programul Prolog complet este prezentat n continuare.
% Structura stare:
% stare(poz_o_maimuta, poz_v_maimuta, poz_cub, are_nu_are_banana)
% Micri admise: apuc, urca, muta(Pozitia1, Pozitia2),
% merge(Pozitia1, Pozitia2),
% reprezentate tot prin structuri.
% Predicate:
% depl(Stare1, Miscare, Stare2)
% poate_lua(Stare)
depl(stare(la_centru, pe_cutie, la_centru, nu_are_banana),
apuca, stare(la_centru, pe_cutie, la_centru, are_banana)).
depl(stare(P, pe_sol, P, H), urca, stare(P, pe_cutie, P, H)).
depl(stare(P1, pe_sol, P1, H), muta(P1, P2), stare(P2, pe_sol, P2, H)).
depl(stare(P1, pe_sol, B, H), merge(P1, P2), stare(P2, pe_sol, B, H)).
poate_lua(stare( _ , _ , _ , are_banana)).
poate_lua(Stare1) :- depl(Stare1, Miscare, Stare2), poate_lua(Stare2).
La ntrebarea

?- poate_lua(stare(la_usa, pe_sol, la_fereastra, nu_are_banana)).


yes
sistemul rspunde afirmativ: maimua este fericit i mnnc banana.
O analiz atent a programului conduce la concluzia c programul d soluii
numai pentru anumite situaii. n primul rnd, strategia de control a micrilor
maimuei este impus de ordinea clauzelor care definesc predicatul depl. Astfel,
maimua prefer nti s apuce, apoi s urce, apoi s mute cubul i numai la urm
s
mearga
prin
camer. Dac
clauza
corespunztoare
micrii
merge(Pozitia1, Pozitia2) ar fi fost pus ca prima clauz n definiia predicatului
de deplasare, maimua ar fi mers la infinit prin camer, fr s mai ajung s mute
cubul sau s apuce banana. Chiar pentru ordinea dat a clauzelor, dac se pune
ntrebarea

?- poate_lua(stare(X, pe_sol, la_fereastra, nu_are_banana)).

ELEMENTE DE BAZ ALE LIMBAJULUI PROLOG

35

Deci, dac intereseaz din ce poziii maimua poate lua banana, rezolvarea dat nu
este total satisfctoare, deoarece programul are o infinitate de soluii. La cererea
repetat a unei soluii, se va afia ntotdeauna valoarea:

X = la_fereastra
Considernd din nou modelul spaiului strilor, se observ c n acest caz
este vorba de un spaiu de cutare de tip graf, n care o aceeai stare poate fi
descoperit i redescoperit la infinit, prin parcurgerea unui ciclu de tranziii de
stri n acest graf. Astfel de cazuri trebuie tratate prin introducerea unor liste de
stri parcurse, care s mpiedice parcurgerea repetat a unor stri deja parcurse.
Pericolul de apariie a unor cicluri infinite, datorit parcurgerii unui spaiu
de cutare graf nu este specific limbajului Prolog i poate s apar n orice
implementare, n aceste cazuri. Ceea ce este neobinuit, n raport cu alte limbaje
este faptul c, semnificaia declarativ a programului este corect, indiferent de
ordonarea clauzelor, n timp ce programul este procedural incorect, avnd
comportri diferite n funcie de aceast ordonare. Rezolvarea problemei ar mai
trebui completat cu afiarea strilor i a micrilor executate de maimu, pentru a
ajunge n starea final, n care ea poate apuca banana. Modaliti de eliminare a
ciclurilor infinite, de tipul celor ce apar n aceast problem, vor fi discutate in
capitolele urmtoare.

1.5 Exerciii propuse


EP1. Exprimai in Prolog urmatoarele fapte:
1) susan are un cal;
2) rex mannca carne;
3) aurul este pretios;
4) maina este un Mercedes albastru cu capacitatea de cinci cltori.
EP2. Se consider urmtoarele fapte, exprimate n Prolog:
masina(mercedes, albastru, 5).
masina(chrysler, rosu, 4).
masina(ford, gri, 8).
masina(datsun, rosu, 5).
S se exprime urmtoarele ntrebri n Prolog:
1) Ce tipuri de maini au cinci locuri pentru cltori?
2) Ce maini sunt roii?

36

CAPITOLUL 1

3) S se transcrie urmtoarea regul n Prolog:


X este o masin mare dac poate transporta cel putin 5 cltori.
EP3. Se d o baz de fapte de forma:
parinte(Parinte, Copil).
barbat(Persoana).
femeie(Persoana).
Se cere:
1) S se introduc cteva fapte de aceast form.
2) S se scrie regulile care definesc urmatoarele relaii de rudenie:
tata(Tata, Copil).
mama(Mama, Copil).
fiu(Parinte, Copil).
fiica(Parinte, Copil).
bunic(Bunic, Copil).
bunica(Bunica, Copil).
nepot(Bunic, Copil).
nepoata(Bunic, Copil).
3) S se pun urmatoarele ntrebri:

Cine este parintele lui Dan?


Cine este fiu?
Cine este bunic?
Cine este fiu si tat?
EP4. S se descrie principalele operatii logice n Prolog: not, or, and, xor, nor,
nand. Pentru aceasta se consider faptele
op_not(Variabila, Rezultat) si
op_or(Variabila1,Variabila2, Rezultat).
S se scrie:
1) faptele necesare descrierii lui op_not si op_or;
2) regulile necesare construciei celorlali operatori pe baza lui op_not
si op_or. Se cer reguli pentru:
op_and(Var1, Var2, Rezultat).
op_xor(Var1, Var2, Rezultat).
op_nor(Var1, Var2, Rezultat).
op_nand(Var1, Var2, Rezultat).