Documente Academic
Documente Profesional
Documente Cultură
2
Limbajul LPAProlog
Istoria programrii logice cuprinde cteva etape reprezentative:
1970 Robert Kowalsky, Edinburgh University i Alain Colmerauer, Universit dAix
Marseille au pus bazele unei colaborri cu un obiectiv comun: utilizarea formalismului logicii
matematice la definirea unui limbaj de programare. Cercetrile lui R. Kowalsky au constituit
cadrul teoretic necesar, iar A. Colmerauer i P. Roussel au scris primul interpretor i au definit
limbajul Prolog (PROgrammation LOGique). Primul compilator Prolog (Kowalsky) a fost realizat
la Warren Edinburgh University, Department of AI.
1980 Borland a elaborat versiunea Turbo Prolog, implementabil pe IBM PC, ceea ce a dus la
rspndirea i cunoaterea limbajului.
1981 Conferina Internaional de IA de la Tokyo: elaborarea celei de-a V-a generaie de
calculatoare i a procesoarelor de cunotine orientate pe limbajul Prolog.
PVG (Prolog Vendors Group) reunete productorii i utilizatorii limbajului Prolog: Boeing, IBM,
Quintus, LPA, Prolog IA.
William Clocksin i Christopher Mellish public n 1981 cartea Programming in Prolog, care
definete standardul Edinburgh al limbajului Prolog. Standardul Borland este mai restrictiv
referitor la posibilitile de calcul simbolic.
LPA (London Prolog Associates) elaboreaz LPA Prolog, care are la baz standardul Edinburgh,
dar aduce i o serie de dezvoltri proprii (metapredicate).
Cele prezentate n cele ce urmeaz se refer la versiunea LPA Prolog, ce constituie totodat i
suportul aplicaiilor prezentate. Implementarea LPA deriv din mai bine cunoscuta versiune Edinburgh
Prolog, creia firma londonez productoare (London Prolog Associates) i-a adus mbuntiri i
dezvoltri suplimentare (metapredicate, faciliti grafice etc.). Versiunea de referin Edinburgh Prolog
a fost definit de W.F.Clocksin i C.S.Mellish n cartea Programming in Prolog, lucrare considerat
la ora actual un standard neoficial al limbajului Prolog.
Prolog este un limbaj declarativ, spre deosebire de alte limbaje (C, Pascal, Basic etc.) care sunt
procedurale (descriu modul de rezolvare a problemelor).
termen compus
functor ( termen )
,
Functorul cel mai exterior se numete functor principal.
Fiecrui termen i este asociat o aritate (numrul de argumente). Termenii simpli au aritatea =
0, iar cei compui au aritatea 1.
Este a+b un termen Prolog? Da, +(a,b) este un termen Prolog de tip infix i aritate 2.
Structura descris de un termen compus poate fi ilustrat grafic prin reprezentarea acesteia sub
forma unui arbore. Astfel, functorul principal va reprezenta i eticheta rdcina arborelui, care va avea
un numr de descendeni egal cu aritatea (numrul de argumente) functorului respectiv, fiecare dintre
acetia corespunznd unuia din argumentele sale. Dac argumentul este un termen simplu, nodul
corespunztor va constitui o frunz a arborelui, iar n caz contrar functorul respectiv va eticheta
rdcina unui subarbore construit n maniera recursiv astfel definit. De exemplu, primul dintre
termenii citai mai sus se poate reprezenta printr-un arbore a crui mulime de noduri este
{a,b,c,d,e,f,g} i a crui mulime de muchii este {[a,b],[a,c],[c,d],[c,e],[e,f],[e,g]}, nodul a fiind
rdcina, iar b,d,f i g nodurile terminale sau frunzele arborelui respectiv.
Observaie. Un arbore este de fapt un graf neorientat, deci oricare dintre noduri poate fi considerat
rdcina arborelui. Totui, avnd n vedere situaia de fa nodul corespunztor functorului principal
va fi considerat rdcina arborelui.
Liste. O list este o secven format dintr-un numr oarecare de elemente. O list se poate
reprezenta n Prolog enumernd, ntre paranteze ptrate, elementele sale componente separate prin
virgul. De exemplu, urmtorii termeni sunt coreci i reprezint liste:
[a,b,c,d] [jerry] [1,2,3,4,5] [a,2,[1,2,3],a(b,c),d] []
Ultima dintre acestea constituie un caz particular i reprezint lista vid (lista fr nici un element).
Orice list este compus din cap i coad. Capul este primul element al listei, iar coada este lista
format din restul elementelor. De exemplu, prima din listele citate mai sus are capul a i coada
[b,c,d], iar cea de a doua are capul jerry i coada []. Lista vid nu se poate descompune n cap i coad.
Listele sunt de fapt cazuri particulare de termeni compui i au o aplicabilitate deosebit n
limbajele de programare orientate spre calculul simbolic. Functorul care desemneaz o structur de tip
list este punctul, iar aritatea acestuia este 2. Primul argument este capul, iar cel de al doilea este coada
listei. De exemplu, lista [a,b,c,d] se poate reprezenta, n sintaxa standard Edinburgh Prolog, prin
termenul compus .(a,.(b,.(c,.(d,[])))). Atenie, nu se va lsa spaiu ntre punct i paranteza deschis. De
fapt acest mod de scriere corespunde modului intern de reprezentare al listei, aceasta fiind de fapt un
arbore binar. Dat fiind ns lizibilitatea destul de redus a acestei construcii sintactice, limbajul
Prolog accept reprezentarea sub form de enumerare a listelor, dar aceasta reprezint doar un mod de
reprezentare extern a acestora. Tot pentru a veni n ajutorul programatorului o list se poate exprima
i sub forma:
[cap | coad]
deci desprind printr-o bar vertical capul listei de coada acesteia. Totodat o list se poate descrie i
sub forma:
[element1,element2,elementn | coad],
dar avnd grij c dup simbolul | trebuie scris o list i nu un element. De exemplu, fiecare din
termeni de mai jos este corect i reprezint aceeai list [a,b,c,d]:
[a|[a,b,c,d]] [a,b|[c,d]] [a,b,c|[d]] [a,b,c,d|[]]
[a|[b|[c|[d]]]] [a,b|[c|[d]]] [a,b,c|[d|[]]]
Observaie. Modalitile diverse de reprezentare a listelor permit, graie mecanismului de unificare,
extragerea i/sau identificarea elementelor componente ale unei liste.
Liste de octei. O list de octei este o succesiune de caractere de orice tip cuprins ntre
ghilimele. Structura de date astfel definit const n lista codurilor ASCII ale caracterelor care compun
IASE 5/19 Cap. 2. Limbajul LPA Prolog
irul. Pentru a insera caracterul n cadrul unei liste acesta se dubleaz. De exemplu termenul:
Aceasta este o lista
este corect i reprezint lista
[65,99,101,97,115,116,97,32,101,115,116,101,32,111,32,108,105,115,116,97].
Ca i n cazul atomilor de tip quoted, caracterul ~(tilda) poate fi utilizat pentru definirea unor
caractere speciale, de exemplu termenul ~G reprezint lista [7].
Observaie. Listele de octei nu trebuie confundate cu irurile de caractere sau cu atomii de tip quote,
dat fiind faptul c acestea difer sintactic doar prin tipul de apostrofuri utilizate ( ` respectiv ) pentru
ncadrarea succesiunii de caractere care le compun. Dei modul de reprezentare, structurile de date
aferente i modul de operare cu aceste structuri sunt diferite, limbajul LPA Prolog dispune ns de
predicate specifice care permit conversia ntre oricare din cele trei tipuri (quoted atomi, iruri de
caractere, liste de octei).
Clauzele limbajului. Clauzele sunt enunurile sau crmizile din care se compun programele
Prolog. Altfel spus, clauza este cel mai mic enun compilabil. Clauzele sunt de dou tipuri: fapte i
reguli.
IASE 6/19 Cap. 2. Limbajul LPA Prolog
Un fapt este de forma:
antet.
unde, din punct de vedere sintactic, antet este un atom sau un termen compus, al crui functor trebuie
s fie diferit simbolul :- sau =. Sintactic, un fapt se termin prin punct, ce trebuie urmat obligatoriu
de spaiu sau de terminatorul de sfrit de linie.
fapt
predicat/0 .
predicat/1 ( , termen )
,
Un fapt are sintaxa unui termen i reprezint un predicat, care poate fi de aritate 0 sau orice aritate 1.
ntr-un limbaj Prolog, orice functor principal reprezint un predicat. Argumentele oricrui
predicat, dac exist, sunt termeni i nu pot fi alte predicate; de aceea, limbajul se numete de ordinul
I.
O regul este de forma:
antet :- t1, t2,,tk. (1)
unde antet constituie capul sau concluzia regulii i apare n partea stng a simbolului :-, iar t1,
t2,,tk, k1 constituie premisele regulii. Fiecare tk este un predicat sau un termen executabil denumit
n limba englez call term sau goal. Regula este terminat printr-un punct urmat de spaiu sau
terminatorul de sfrit de linie. Intuitiv, un termen este denumit executabil dac consistena sau
valoarea de adevr a acestuia poate fi dedus din contextul clauzelor programului Prolog. Din punct de
vedere al logicii matematice, regula (1) este echivalent cu implicaia (virgula are semnificaia de
conjuncie logic, iar simbolul :- de implicaie invers):
antet t1 t2 tk , (2)
deci inferarea concluziei antet se poate face dac, pentru un anumit mod de instaniere a variabilelor
din componena acestora, premisele t1, t2,,tk. pot simultan satisfcute.
regul
predicat :- predicat .
, Conjuncie
antet
; Disjuncie
corpul regulii
Pentru a nelege noiunea de termen executabil sau goal trebuie plecat de la premisa c ntr-un
program Prolog orice functor principal este un simbol predicativ (predicat) i are n consecin o
valoare de adevr.
Dac n logica matematic scriem abc, adic ab, scriem ac, n Prolog se obine: a :- b; c.
Dpdv matematic, clauzele Prolog sunt clauze Horn pozitive, n cadrul crora variabilele sunt universal
cuantificate. Mulimea acestor clauze poart denumirea de Program.
Definirea unui fapt de forma:
fapt(a1,,ak).
presupune specificarea (asertarea) faptului c predicatul fapt(a1,,ak) este adevrat. Astfel faptele
permit declararea unor piese de cunoatere presupuse adevrate (date, ipoteze), iar regulile
IASE 7/19 Cap. 2. Limbajul LPA Prolog
specificarea unor reguli de inferen (axiome, teoreme) prin care pot fi deduse noi fapte sau piese de
cunoatere.
Program
PROLOG P
Indicatorul yes nseamn c exist o substituie astfel nct din P este deductibil Q (P
Q), adic o instan a lui Q este deductibil din P, deci Q este o consecin logic a mulimii P.
/
Indicatorul no nseamn c din P nu este deductibil Q (P Q), adic Q nu este o consecin
logic a mulimii P.
n cazul rspunsului yes mecanismul inferenial returneaz substituia .
Variabilele instaniate (iniializate) pot fi privite ca parametrii de intrare ai procedurii libere,
iar variabilele libere ca parametri de ieire ai procedurii, parametri ce vor fi instaniai cu valorile
corespunztoare de interpretorul Prolog .
Mulimea clauzelor unui program care corespund unui aceluiai predicat poart numele de
procedur. Aceste proceduri sunt mult mai flexibile dect cele din limbajele de programare. O
procedur Prolog poate fi aplicat n mai multe moduri (flow pattern), programatorul putnd inversa
parametrii de intrare cu cei de ieire.
Exemplu: Predicatul p/2 {(i,i), (i,o), (o,i), (o,o)} i input; o output.
fata(maria, ion).
?: fata(Cine, Cui). % (o,o)
?: fata(Cine, ion). % (o,i) Cine=maria
?: fata(maria, Cui). % (i,o) Cui=ion
?: fata(maria, ion). % (i,i) yes
Fiecare predicat executabil poate fi considerat ca o procedur, n sensul cunoscut din
programarea clasic. O procedur mai returneaz i acel indicator de rspuns (yes sau no).
Dup ce un program Prolog a fost editat i compilat, utilizatorul poate introduce n fereastra de
dialog diverse formule de interogare a sistemului. O formul de interogare, denumit goal n
terminologia englez, este de forma:
p1,p2, , pn. (n1)
unde p1,p2,,pn sunt termeni executabili, iar virgula are semnificaia de conjuncie logic. O formul
de interogare poate fi de dou feluri:
determinit: nu conine variabile libere, rspunsul sistemului la o astfel de
formul fiind yes sau no, dup cum formula respectiv este sau nu o
consecin logic a clauzelor din program;
nedeterminist: conine una sau mai multe variabile libere, sistemul
determinnd prin backtracking toate instanierile posibile ale
variabilelor pentru care respectiva formul este o consecin logic a
clauzelor din program.
Exemplu: place (ion, X) :- are_zestre(X), frumoas (X).
are_zestre(X) :- bogat(Y), fata (X, Y).
...
?: place (ion, Fata). %(i, o)
IASE 9/19 Cap. 2. Limbajul LPA Prolog
Remarca 1: De fiecare dat cnd are de satisfcut un goal introdus n fereastra de interogare
sau din corpul unei reguli, interpretorul Prolog ncepe scanarea tuturor clauzelor din program ncepnd
cu prima dintre acestea, n vederea gsirii unei clauze al crei antet este unifiabil cu goal-ul curent.
{place(ion, X), place(ion, Fata)} cmgu {Fata=X}.
Remarca 2: Dac un goal a fost unificat cu antetul unei reguli, se trece la demonstrarea
predicatelor (subgoal-urilor) din corpul regulii respective. ncercarea de a satisface aceste fapte se face
n ordinea n care acestea apar n corpul regulii. Astfel, se trece la a demonstra bogata (Y) devine
goal curent.
Remarca 3: Dac un predicat din corpul unei reguli a fost demonstrat, se trece la demonstrarea
predicatului urmtor; n caz contrar, se revine la ultimul punct de breakpoint aflat n program. Goal-ul
curent devine fata(X, veta).
Cnd mai multe clauze din program sunt unifiabile cu goal-ul curent, interpretorul plaseaz un
punct de breakpoint pe urmtoarea clauz unifiabil din program.
fata(X, veta)
fata(geta, veta), C = {X=geta}
= C = {Fata=X=geta, Y=veta}
frumoasa(geta).
Remarca 4: Cnd un goal este dovedit inconsistent, se revine prin backtracking la ultimul
punct de breakpoint plasat n program. O dat cu revenirea la ultimul punct de breakpoint, se
elibereaz toate variabilele instaniate dup plasarea n program a respectivului punct de breakpoint.
Variabila X este eliberat (dezlegat de valoarea geta).
Revenindu-se la punctul de breakpoint, variabila X este instaniat din nou cu valoarea maria.
n acest caz, goal-ul frumoasa (maria) poate fi demonstrat i Prolog, innd cont de substituia curent,
rspunde Fata=maria.
Urmtoarele 2 caracteristici exprim o particularitate relevat a limbajului Prolog:
Singura modalitate de instaniere a unei variabile este procedura de unificare
(programatorul nu poate atribui o valoare unei anumite variabile).
Variabilele pot fi eliberate numai prin mecanismul de backtracking al interpretorului
Prolog.
n Prolog, simbolul = este un operator infix care face apel la procedura de unificare; n urma
unificrii variabilelor din cei doi termeni, instanierea se realizeaz dac X este liber.
X=1+2 are drept efect instanierea lui X cu expresia 1+2 dac X este liber: ={X=1+2}.
X=1 are ca efect instanierea variabilei X = 1, dac X este liber. ={X=1}.
X=1, X=X+1: ={X=1} 1=1+1 inconsistent => fail, , (1)=(1+1).
Exemple BAF i CAF:
prezent(alina). prezent(georgiana). prezent(elena). prezent(mircea). prezent(dan).
lista:-
prezent(X), write(X), nl, fail.
lista. % BAF(Backtracking After Fail)
lista:-
prezent(X), write(X), nl, X=dan, !. % CAF(Backtracking After Fail)
Precizare: O formul de interogare Q trebuie privit ca un apel la mecanismul inferenial al
interpretorului (demonstratorul) Prolog, care genereaz soluiile lui Q.
IASE 10/19 Cap. 2. Limbajul LPA Prolog
L E
add(E, L, [E|L])
E L
L1 L2
concat(L1, L2, L)
L L1 L2
IASE 11/19 Cap. 2. Limbajul LPA Prolog
del(X, [X|T], T).
del(X, [H|T], [H|T1]):- del(X, T, T1).
? del(b, [a,b,c,b,d],L).
L=[a,c,b,d]
L=[a,b,c,d]
5. Inserarea unui element ntr-o list
insert(X, L, L1):- del(X, L1, L).
6. Permutarea elementelor unei liste perm (L, L1)
perm([], []).
perm([H|T], L):- perm(T, T1), insert(H, T1, L).
7. Numrarea elementelor unei liste count(L, N)
count([], 0).
count([H|T], N):- count(T,M), N is M+1.
sau
count([], N, N).
count([_|T], Numar, N):- NouNumar is Numar+1, count(T,NouNUmar, N).
Numar se va initializa cu zero.
?: count([1,2,3,4,5], 0, Cate).
Cate=5
count(L, N):-count(L,0,N).
?: count([1,2,3,4,5], Cate).
Cate=5.
2.6. Operatori
Dat fiind faptul c limbajul Prolog este orientat mai degrab n vederea efecturii calculelor
simbolice dect numerice, operatorii trebuie privii ca un mod aparte de reprezentare a termenilor
compui de aritate unu sau doi. Deci un operator nu semnific de regul efectuarea unei operaii, ci
indic mai degrab modul de agregare a operanzilor n cadrul structurii desemnat de acel operator.
Exist totui i o serie de operatori prin care programatorul poate fora la nevoie evaluarea unei
expresii. Spre deosebire de sintaxa standard a unui termen compus, situaie n care functorul precede
paranteza ce conine lista argumentelor sale, operatorii permit scrierea termenilor de aritate 1 sau 2
ntr-o nou sintax, care ntr-un anumit context poate fi mult mai agreabil. Pentru a prezenta aceast
sintax, previzibil de fapt, trebuie menionat mai nti c operatorii pot fi de trei feluri i anume
operatori prefix, postfix i infix. Pentru desemnarea unui operator se poate utiliza un atom de oricare
din cele trei tipuri prezentate mai sus.
Operatori prefix. Un operator prefix este un operator unar care se scrie n faa (precede)
operandului acestuia (de exemplu, semnul minus din faa unui numr negativ este un operator prefix).
Operatorii prefix pot fi utilizai pentru exprimarea unor termeni de aritate unu. De exemplu, termenul
Prolog
functor(termen)
poate fi exprimat la fel de bine i n scrierea
functor termen
dac functor este sau a fost declarat (modul de declarare va fi prezentat ulterior) un operator prefix.
Predicatul predefinit not/1 este un exemplu de operator prefix. Predicatul not este adevrat dac
argumentul su este fals i fals dac argumentul este adevrat. Astfel, termenul not
dangerous(Animal) din exemplul de mai jos nu este altceva dect exprimarea prefix a termenului
not(dangerous(Animal)).
Operatori postfix. Un operator postfix este un operator unar care succede operandul acestuia.
Ca i n cazul operatorilor prefix, operatorii postfix pot fi utilizai pentru expri-marea, ntr-un mod
diferit de sintaxa standard Prolog, a termenilor de aritate unu. De exemplu, termenul
functor(termen)
poate fi exprimat la fel de bine i n scrierea
IASE 12/19 Cap. 2. Limbajul LPA Prolog
termen functor
dac functor este sau a fost declarat operator postfix.
Operatori infix. Un operator infix este un operator binar care se scrie ntre operanzii acestuia (scrierea
algebric uzual). Ca i n cazul operatorilor unari, operatorii infix permit scrierea termenilor de aritate 2 i
ntr-o sintax diferit de cea standard Prolog. De exemplu, termenul
functor(termen1,termen2)
se poate scrie sub forma
termen1 functor termen2
dac functor este sau a fost declarat operator infix. Dac functorul is_a este declarat operator infix, atunci
clauzele corespunztoare acestui predicat pot fi scrise n maniera prezentat mai jos:
mowgli is_a man. rama is_a wolf. bagheera is_a panther.
baloo is_a bear. thati is_a elephant. kaa is_a snake. shere_khan is_a tiger.
n aceast situaie, o ntrebare de tipul Cine este o panter ? se poate formula sub forma:
?- Who is_a panther.
Precedena operatorilor. tiind c + i * sunt doi operatori infix predefinii n limbajul
Prolog, se pune ntrebarea care dintre urmtorii doi termeni,
+(a,*(b,c)) respectiv *(+(a,b),c) ,
este interpretarea corect a expresiei (termenului) a+b*c? Sau, algebric vorbind, termenul respectiv este
evaluat ca a+(b*c) sau (a+b)*c? nainte de a se da un rspuns la aceast ntrebare, trebuie precizat faptul
c n Prolog fiecare operator are sau i se asociaz o preceden, constnd ntr-un numr natural cuprins
ntre 1 i 1200. Cu ct precedena unui operator este mai mic cu att operatorul este mai avid la operanzi
sau, cum se zice n terminologia programrii logice, leag mai bine. Acest principiu se poate formula, mai
simplu, dup cum urmeaz: functorul principal al unui termen compus format din operatori de precedene
diferite este operatorul cu precedena cea mai mare. Precedena implicit (aceasta putnd fi modificat de
programator prin redefinirea operatorilor) a operatorilor + i * este 500 respectiv 400. Prin urmare,
expresia considerat este exprimarea algebric a termenului compus +(a,*(b,c)), dat fiind faptul c atomul
b este operandul lui * care leag mai bine dect + sau, altfel spus, dat fiind faptul c functorul principal
este operatorul +, deoarece acesta are precedena mai mare dect *.
Trebuie subliniat faptul c n Prolog operatorii nu implic existena unor date asociate sau
efectuarea unor calcule, dect n situaii cu totul speciale. Operatorii au rol de functor i specific un
mod de structurare. Limbajul Prolog accept totui scrierea n format algebric a termenilor avnd drept
functori operatori unari sau binari, dar aceste expresii sunt doar un mod extern de reprezentare a
termenilor respectivi. Intern, orice expresie este un termen i se reprezint ca i oricare alt termen
compus (arbore).
Se pune acum ntrebarea cum trebuie interpretat o expresie n care intervin mai muli operatori
de aceeai preceden, de exemplu o expresie de forma:
t1 t 2 t n
unde t1,t2,,tn sunt termeni, iar prin s-a notat un operator oarecare, sau diveri operatori avnd
aceiai preceden. n ce condiii o astfel de expresie este sintactic corect (reprezint un termen) i
cum trebuie interpretat aceasta? Rspunsul la aceast ntrebare necesit asimilarea n prealabil a
noiunii de tip al unui operator. nelegerea acestui concept permite interpretarea corect a oricrei
termen Prolog, indiferent de complexitatea acestuia.
Tipul operatorilor. Pe lng precedena acestuia, un operator este caracterizat prin tip, adic
un descriptor care caracterizeaz proprietile operatorului respectiv. Descriptorii utilizai pentru
definirea operatorilor sunt cei prezentai mai jos:
Operatori prefix: fx fy
Operatori postfix: xf yf
Operatori infix: xfx xfy
yfx
Semnificaia descriptorilor este urmtoarea:
Litera f (f provine de la functor) desemneaz locul de plasare al operatorului n raport cu operandul
sau operanzii acestuia, desemnat sau desemnai prin simbolul x i/sau y. Pentru a nelege care este
IASE 13/19 Cap. 2. Limbajul LPA Prolog
deosebirea dintre x i y trebuie ca n prealabil s se defineasc noiunea de preceden a unui
termen.
Un termen simplu sau inclus ntre paranteze este de preceden 0:
Precedena unui termen compus este egal cu cea a functorului su principal.
Litera x din descriptorii de mai sus arat c precedena termenului asociat trebuie s fie strict mai
mic dect precedena operatorului;
Litera y specific c aceasta trebuie s fie cel mult egal cu cea a operatorului.
De exemplu, dac operatorul i se atribuie ca tip descriptorul yfx atunci expresia t1 t 2 t 3 este
corect i trebuie interpretat ca (t1 t 2 ) t 3 , fapt pentru care un operator yfx mai este denumit
asociativ la stnga. Se poate constata c interpretarea t1 (t 2 t 3 ) nu este posibil deoarece
precedena termenului (t 2 t 3 ) corespunztoare descriptorului x ar fi egal cu cea a operatorului .
Dac ns tipul operatorului ar fi xfy atunci cea de a doua interpretare ar fi corect i operatorul ar fi
asociativ la dreapta. n sfrit, dac descriptorul de tip al operatorului este xfx, atunci expresia
t1 t 2 t 3 este incorect i operatorul este denumit neasociativ.
Recapitulnd, descriptorii de tip utilizai la definirea operatorilor sunt cei enumerai mai jos, n
dreapta acestora fiind specificat() tipul (proprietatea) operaiei respective:
fx operator prefix neasociativ;
fy operator prefix asociativ la dreapta;
xf operator postfix neasociativ;
yf operator postfix asociativ la stnga;
xfx operator infix neasociativ;
xfy operator infix asociativ la dreapta;
yfx operator infix asociativ la stnga.
Definiiile implicite ale principalilor operatori uzuali sunt prezentate mai jos:
:- op(1200, xfx, :-).
:- op(1200, fx, [ :-, ?-]).
:- op(1100, xfy, ;).
:- op(1000, xfy, ,).
:- op(700, xfx, [=, is , < , > , = < , > = , = = , \ = = , = : = , = \ = ] ).
:- op(500, yfx, [ +, - ]).
:- op(500, fx, [ + , - , not]).
:- op(400, yfx, [ * , \ , div]).
:- op(300, xfx, mod).
Noiunea de preceden a unui termen se definete astfel:
un termen atomic sau inclus ntre paranteze are precedena zero;
precedena unui termen compus este cea a functorului su.
Oricare din operatorii de mai sus pot fi la nevoie redefinii de programator. Definiia curent a unui
operator poate fi consultat prin apelarea predicatului current_op/3, al crui prototip este
current_op(<Preceden>,<Tip>,<Nume>). Astfel prin apelul:
current_op(P, T, +) ,
variabilele libere P i T vor fi instaniate cu precedena respectiv tipul operatorului + (se obin prin
backtracking ambele soluii, att pentru operatorul unar ct i pentru cel binar).
IASE 14/19 Cap. 2. Limbajul LPA Prolog
Remarca 4. Din punct de vedere pur sintactic, o regul poate fi considerat de asemenea un termen
compus al crui functor principal este operatorul infix neasociativ :-, virgula de separare a termenilor
executabili din partea dreapt a acestui operator fiind considerat un operator prefix asociativ la dreapta
(vezi definiiile operatorilor respectivi n tabelul de mai sus).
Operaii cu termeni. Orice operator care constituie functorul principal al unui termen compus are o
semnificaie predicativ i are n consecin o valoare de adevr. n funcie de rolul i semnificaia
acestora, operatorii utilizabili la formarea expresiilor Prolog se pot mpri n urmtoarele patru
categorii precizate mai jos.
Operatorul de unificare. Cea mai important operaie pe mulimea termenilor este unificarea
(de fapt aceasta este operaia de baz a limbajului Prolog). Se tie c doi termeni t1 i t2 se numesc
unifiabili dac exist o substituie astfel nct termenii (t1) i (t2)s devin identici. Operaia de
unificare este desemnat prin operatorul infix =. Termenul executabil t1=t2 este de fapt un apel la
rutina de unificare a interpretorului Prolog. Dac cei doi termeni sunt unifiabili, atunci predicatul t1=t2
este satisfcut i variabilele libere din cei doi termeni sunt substituite prin valorile lor corespunztoare
din cmgu(t1,t2). n caz contrar, termenul t1=t2 este inconsistent, iar variabilele din componena acestora
rmn nemodificate.
Se poate testa dac doi termeni t1=t2 sunt unifiabili i fr a produce instanieri ale variabilelor
prin apelarea predicatului predefinit unifiable(t1,t2).
Operatorul \= este complementul operatorului =. Astfel t1\=t2 este adevrat dac t1 i t2 sunt
neunifiabili i este fals cnd t1 i t2 sunt unifiabili.
Operatori de comparaie lexicografic. Operatorul == (dou semne de egalitate) permite
compararea lexicografic a doi termeni. Termenul (predicatul) t1==t2 este valid dac cei doi termeni t1
i t2 sunt lexicografic identici. De exemplu, termenul a+b==b+a este inconsistent, deoarece termenii
a+b i b+a nu sunt identici, n schimb predicatul a+b==a+b este valid. Operatorul \== (back slash i
dou semne de egalitate) este negaia operatorului precedent. Astfel, predicatul a+b\==b+a este
adevrat, n timp ce predicatul a+b\==a+b este fals. Operatorii din aceast categorie nu produc
instanieri ale variabilelor.
Operatorul de evaluare. Dup cum s-a precizat mai sus, limbajul Prolog este orientat pentru
efectuarea calculului simbolic, operatorii fiind utilizai mai degrab pentru reprezentarea unor
structuri. Evident, sfera de utilizare a limbajului ar fi puternic diminuat, dac acesta nu ar permitea
efectuarea unor calcule matematice. Dar, aceste calcule se fac numai la cererea expres a
programatorului. De exemplu, dac X este o variabil liber, termenul executabil X = 1+2 are ca efect
instanierea variabilei X cu valoarea (termenul) 1+2 (ceea ce era de ateptat ntruct 1+2 este
substituia de unificare a celor doi termeni ai operatorului =). Operatorul prin care programatorul poate
cere n mod expres evaluarea unei expresii este desemnat prin atomul rezervat is. n partea stng a
operatorului is trebuie s apar n mod obligatoriu o variabil (liber sau nu), iar n partea dreapta o
expresie algebric, ale crei variabile (dac exist) s fie iniializate cu valori numerice. Astfel, dac X
este o variabil liber, apelul termenului X=1+2 va avea ca efect instanierea variabilei X cu valoarea
3. Trebuie menionat faptul c un termen executabil de forma:
X is <Expresie> ,
nu trebuie confundat cu o instruciune de atribuire. De fapt, dei pare oarecum ocant, limbajul Prolog
nu are instruciune de atribuire !. Mai mult, un predicat de forma:
X is X+1 ,
este inconsistent, deoarece variabila X din membrul drept trebuie s fie instaniat i, indiferent de
valoarea acesteia, aceasta nu poate fi nici cum egal cu X+1.
Dup cum s-a menionat anterior, n Prolog unificarea este singurul mod de instaniere a unei
variabile, dup cum mecanismul de backtracking este singurul mod posibil de eliberare al acesteia.
Operatori relaionali. Limbajul Prolog conine urmtorii operatorii relaionali, ce pot fi
utilizai pentru comparaia numeric a dou expresii. Toate variabilele cuprinse n cele dou expresii
trebuie s fie instaniate n momentul apelului termenului respectiv.
E1=:=E2 egalitate
E1=\=E2 neegalitate
E1<E2 mai mic
IASE 15/19 Cap. 2. Limbajul LPA Prolog
E1=<E2 mai mic sau egal
E1>E2 mai mare
E1>=E2 mai mare sau egal
Fiecare din termenii de mai sus produce evaluarea numeric a expresiilor algebrice E1 i E2, valoarea
de adevr a termenilor de mai sus fiind calculat ca n orice alt limbaj de programare. Operatorii
relaionali nu produc instanieri ale variabilelor din cele dou expresii.
Observaie. Operatorii mai mic sau egal i mai mare sau egal trebuie scrii n maniera ilustrat mai sus,
scrierile <= respectiv => nefiind acceptate de compilatorul Prolog.
corpul ciclului
q1(X), q2(X), , qn(X)
apel predicat Da
C(X)
Mai breakpoints
fail sau variante
C(X)
nencercate ale lui
p(X)
!
Nu
fail
Exemplu:
introducere :-
repeat,
write(Continuati:), read(Continuat), nl,
write(Tara:), read(Tara), nl,
write(Capitala:), read(Capitala), nl,
memorare(Continent, Tara, Capitala),
Tara=stop,!.
Predicatul repeat/1
salut:- (repeat(6), write(Salut!), nl, fail); true.
repeta(0):-!.
repeta(N):- M is N-1, repeta(M).
integer_bound/3 {(i,o,i)}
integer_bound(vmin, V, vmax).
for:- (integer_bound(1, I, 10), Ip is I*I, write(I), write(Ip), nl, Ip=10, fail); true.
Exemplul 1.
Se consider programul Prolog constituit din urmtoarea succesiune de fapte:
is_a(mowgli, man).
is_a(rama, wolf).
is_a(bagheera, panther).
is_a(baloo, bear).
is_a(thati, elephant).
is_a(kaa, snake).
is_a(shere_khan, tiger).
man_eating(tiger).
dangerous(snake).
i se atribuie acestor fapte interpretarea care ne situeaz n universul mirific imaginat de Rudyard
Kipling n Cartea junglei. Aceste fapte definesc relaia is_a/2 prin enumerarea elementelor sale.
Interpretarea acestor fapte n limbajul natural, n contextul amintit mai sus, este urmtoarea: Mowgli is
a man, Bagheera is a panther, Baloo is a bear .a.m.d. Faptele de mai sus se pot rescrie ntr-o form
similar utiliznd atomii de tip quote. De exemplu, dac se dorete ca numele celebrului tigru, i nu
numai, s se scrie n ortografia sa natural, ultima din instanele predicatului is_a/2 s-ar putea scrie sub
forma:
is_a(Shere Khan, tiger).
Se presupune n continuare c se dorete definirea unei relaii friend/1 care s stipuleze care din
personajele de mai sus sunt prietenii lui Mowgli. Pentru aceasta se poate aduga programului de mai
sus cte o instan a predicatului friend/1 corespunztoare fiecruia din personajele de mai sus, mai
puin tigrul Shere Khan i pitonul Kaa:
friend(bagheera). friend(baloo).
friend(rama). friend(thati).
Relaia friend/1 se poate defini ns i observnd c Mowgli este prietenul fiecruia din personajele de
mai sus, mai puin cei doi dumani declarai ai acestuia, tigrul mnctor de oameni Shere Khan i
periculosul piton Kaa.
friend(Name):-
is_a(Name,Animal),
not man_eating(Animal), not dangerous(Animal).
Analog, se poate defini o regul enemy/1 prin care pot deduce dumanii lui Mowgli:
enemy (Name) :-
is_a(Name,Animal),
(man_eating(Animal) ; dangerous(Animal)).
n contextul de mai sus, simbolul ; (punct i virgul) are semnificaia de disjuncie logic.
IASE 18/19 Cap. 2. Limbajul LPA Prolog
De exemplu, n cazul exemplului considerat mai sus, sistemul va rspunde la ntrebrile formulate
(textul introdus de operator apare subliniat) n maniera prezentat mai jos.
?:- is_a(baloo,bear).
Este Baloo un urs?
yes
?:- is_a(bagheera,bear).
Este Bagheera un urs?
no
?:- is_a(thati,What).
Ce este Thati?
What=elephant.
yes.
Semnificaia acestor ntrebri este cea nscris n partea dreapt. La ntrebarea:
?:- is_a(Who,What).
Cine este ce?
sistemul va rspunde indicnd toate instanierile posibile ale variabilelor Who i What pentru care
formula precedent este deductibil din program, obinndu-se astfel ntreaga distribuie a
personajelor.
Who=mowgli, What=man
Who=rama, What=wolf
Who=bagheera, What=panther
Who=baloo, What=bear
Who=thati, What=elephant
Who=kaa, What=snake
Who=shere_khan, What=tiger
Observaie. La formulele de interogare nedeterministe, dup afiarea unei soluii sistemul ateapt ca
operatorul s apese una din urmtoarele taste:
<spaiu> pentru continuarea afirii celorlalte soluii posibile;
<CR> dac se renun la restul soluiilor.
Exerciiul 1. Editai programul Prolog prezentat mai sus i scriei formula de interogare prin care se
pot afia toi prietenii lui Mowgli.
Remarca 1. Interpretorul Prolog rspunde la formulele de interogare ale utilizato-rului numai pe baza
clauzelor (fapte i/sau reguli) din program. De exemplu, la ntrebarea:
?:- is_a(thati, colonel).
sistemul va rspunde cu no, dei n povestea considerat Thati este ntr-adevr colonel, (re)cunoscut de
ntreaga jungl prin rsuntoarele maruri ale patrulei sale.
Revenind la programul prezentat mai sus, dac functorul is_a este declarat operator infix,
atunci clauzele corespunztoare acestui predicat pot fi scrise n maniera prezentat mai jos:
mowgli is_a man.
rama is_a wolf.
bagheera is_a panther.
baloo is_a bear.
thati is_a elephant.
kaa is_a snake.
shere_khan is_a tiger.
n aceast situaie, o ntrebare de tipul Cine este o panter ? se poate formula sub forma:
?- Who is_a panther.
Exerciiul 2. ncercai s anticipai ce va rspunde interpretorul Prolog la ntrebarea Who is_a
Panther. . Este corect formula de interogare Bagheera is_a bear. i, dac da, cum va rspunde
IASE 19/19 Cap. 2. Limbajul LPA Prolog
interpretorul Prolog n acest caz ?. Ce este de fapt Bagheera i care este ntrebarea prin care se poate
afla acest lucru ?
De exemplu, prin comanda
:- op(500,xfx,is_a).
este definit operatorul infix neasociativ is_a utilizat n exemplul precedent.
Remarca 3. Este bine ca definirea operatorilor s se fac pornind de la structura arborescent a
termenilor pe care acetia i reprezint. De exemplu, structura termenului desemnat prin ultima clauz
a programului de mai jos este cea ilustrat n figura
alturat.
:- op(800,xfx,is_a). is a
:- op(500,fy,[black, big,man, eating]). man
bagheera is_a black panther.
baloo is_a big bear. shere_khan eating
shere_khan is_a man eating tiger.
Dup cum se poate constata mai muli operatori de
tiger
acelai tip i avnd aceiai preceden pot fi declarai
n bloc, indicnd lista operatorilor respectivi ca cel de
al treilea parametru al comenzii op. Din analiza arborelui de mai sus se poate constata c operatorii
is_a, man i eating sunt corect definii. Operatorul is_a este infix, nodul corespunztor avnd doi
descendeni, termenii respectivi avnd precedene (shere_khan=0, man=500)) strict mai mici dect cea
a operatorului. Operatorii man este un operator prefix de tipul fy i se aplic termenului eating tiger, a
crui preceden, egal cu cea a functorului eating, este egal cu cea a operatorului. n sfrit,
operatorul prefix eating se aplic termenului tiger de preceden egal cu 0. De remarcat c dintre cei
doi operatori prefix de mai sus, numai eating ar putea fi definit cu descriptorul fx. Altfel spus,
operatorii prefix care nu au ca descendent o frunz (un termen simplu) trebuie s fie n mod obligatoriu
de tip fy (sunt neasociativi).
Exerciiul 3. Reprezentai termenul de mai jos:
noaptea toate pisicile sunt negre ,
sub form arborescent i definii n mod corespunztor operatorii afereni, astfel nct enunul
respectiv s fie un termen Prolog valid. Definii o colecie de predicate care s permit scrierea unor
enunuri similare, avnd structura: [<complement circumstanial de timp>] [<atribut adjectival>]
<subiect> <predicat nominal>.