Sunteți pe pagina 1din 19

IASE 1/19 Cap. 2.

Limbajul LPA Prolog

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).

2.1. Alfabetul i elemente de sintaxa limbajului Prolog


Alfabetul limbajului. La scrierea programelor Prolog se poate utiliza ntreaga tabel de
caractere ASCII, att caracterele uzuale cuprinse n prima jumtate a tabelei (avnd codurile ASCII
cuprinse ntre 0 i 127, fapt pentru care sunt denumite impropriu caractere pe 7 bii), precum i
caracterele din cea de a doua jumtate a tabelei ASCII (avnd codurile ntre 128 i 256). Setul de
caractere din partea superioar a tabelei ASCII depinde de pagina de cod sau fontul cu care se
lucreaz. Acesta include de obicei literele greceti, precum i diverse caractere semigrafice.
Separatori i terminatori. Principalul separator ai termenilor limbajului este virgula (,).
Virgula poate s apar de asemenea ca separator ntre elementele unei liste (de fapt o list este un caz
particular de termen compus). Spaiul este utilizat ca separator ntre termeni i operatori, de fiecare
dat cnd natura acestora impune introducerea unui spaiu pentru delimitare (spaiul nu este necesar
atunci cnd termenii i operatorii sunt de natur diferit, adic unul este alfanumeric, iar cellalt
simbolic). De exemplu, dac plus este un operator binar, iar ++ i ** sunt doi termeni, sintaxa
termenului compus: ++plus** este corect. Terminarea unui enun Prolog se realizeaz prin caracterul
punct (.) urmat n mod obligatoriu de spaiu sau terminatorul de sfrit de linie (caracterele CR ,LF).
Punctul poate s apar ns i n componena unui termen simbolic cum ar fi **.**, context n care
acesta nu are rol de terminator.
IASE 2/19 Cap. 2. Limbajul LPA Prolog
Comentariile. Pentru documentare, ntr-un program Prolog se pot introduce oricnd
comentarii. n funcie de ntinderea (amploarea) acestora, exist dou modaliti de introducere a
comentariilor. Caracterul % definete drept comentariu coninutul liniei, ncepnd cu caracterul nsui
i pn la sfritul acesteia. Inserarea unui comentariu pe mai multe rnduri se face ncadrnd textul
respectiv ntre delimitatorii /* i */.

2.2. Vocabularul i termenii limbajului Prolog


Termenii limbajului. n Prolog, termenii constituie tipurile fundamentale de date ale
limbajului i pot fi utilizai att pentru reprezentarea unor date elementare (scalare), ct i pentru
reprezentarea unor structuri foarte complexe (de exemplu o baz de date relaional). Termenii sunt de
fapt crmizile din care se compun clauzele limbajului (clauza este cel mai mic element sintactic
avnd semnificaie de sine stttoare n Prolog sau, mai exact, este cel mai mic enun compilabil).
Termenii pot fi simpli sau compui.
Termenii simpli constituie practic vocabularul limbajului de programare, acetia fiind cele mai
mici uniti lexicale avnd o anumit semnificaie n cadrul limbajului. Termenii simpli sau atomici ai
limbajului Prolog sunt numerele ntregi sau reale, variabilele, atomii i irurile de caractere. Un termen
compus se formeaz prin combinarea unor termeni simpli i/sau compui. Din categoria termenilor
compui fac parte listele i listele de octei, termeni cu o aplicabilitate aparte n cadrul limbajului. n
tabelul 1 este prezentat o clasificare a termenilor limbajului Prolog i sunt descrise predicatele
predefinite prin care programatorul poate testa dac un termen aparine unuia din tipurile specificate
mai sus. Totodat, predicatul type/2 permite determinarea tipului unui anumit termen dat.
Variabilele. O variabil este denumit n Prolog printr-un identificator care trebuie s nceap
n mod obligatoriu cu o majuscul (o liter de la A la Z) sau cu caracterul _ (underscore).
Secvena de caractere din denumirea variabilei poate s includ, de asemenea, caracterul _, acesta
fiind de fapt considerat liter. De exemplu, urmtorii identificatori sunt denumiri corecte de variabile:
Anonim _variabila X Y Cristy
Numere ntregi. Ca n oricare limbaj de programare, un numr ntreg se reprezint printr-o
succesiune de cifre, eventual precedat de semnul plus sau minus. Convenia de reprezentare este
algebric pe 4 octei, domeniul numerelor ntregi reprezentabile fiind cuprins ntre -2147483648 i
2147483647.
Numerele reale. Un numr real poate fi precedat de semn i este format dintr-o secven de una
sau mai multe cifre, punctul zecimal i o secven de una sau mai multe zecimale. Opional numrul
poate fi urmat (fr a se lsa spaiu) de litera e (sau E) i o secven de cifre eventual precedat de
semn (n format exponenial). Dup cum se poate constat, numerele reale au sintaxa similar cu cea
din Pascal (punctul zecimal trebuie cadrat n mod obligatoriu de cifre). Fiecare din termenii de mai jos
sunt coreci i reprezint numere reale:
1.0 258.0752 -12.59432 2.0E7 +1.85e10 ,
n timp ce nici una din urmtoarele succesiuni de caractere
1. 12E3 12.3 E4
nu sunt corecte sintactic.
Numere ntregi ntr-o baz oarecare. Un numr ntreg ntr-o baz oarecare b se poate
reprezenta n Prolog scriind baza b urmat de un apostrof i cifrele numrului n baza respectiv. De
exemplu, succesiunea de caractere
21100100
este corect i reprezint reprezentarea n baza 2 a numrului 100. Acelai numr se poate reprezenta
n format hexazecimal (n baza 16) scriind 1664. Pentru o mai bun edificare, la prompterul ?- al
fereastra de dialog se pot introduce pe rnd comenzile:
X is 1664. <Enter> respectiv X is 201100100. <Enter>
i n ambele situaii interpretorul Prolog va rspunde prin X=100.
Trebuie evideniat aici un caz similar i anume atunci cnd n faa apostrofului apare cifra 0
(care evident nu poate fi baza unui sistem de numeraie), iar n locul cifrelor un caracter. n aceast
situaie secven 0<caracter> desemneaz codul ASCII al caracterului citat dup apostrof. De
IASE 3/19 Cap. 2. Limbajul LPA Prolog
exemplu termenul 0d desemneaz numrul ntreg 100, care este codul ASCII al caracterului d.
Atomii. Atomii sunt denumiri alfanumerice sau simbolice prin care programatorul poate
desemna obiecte, proprieti ale acestora, precum i diverse relaii stabilite ntre acestea. Lungimea
maxim a unui atom este de 255 de caractere. Exist patru tipuri de atomi: alfanumerici, simbolici, de
tip ir de caractere i atomi rezervai.
Atomi alfanumerici. Un atom alfanumeric este format dintr-o liter mic (a-z) urmat de o
secven format din zero sau mai multe litere (a-z, A-Z) sau cifre (0-9). Caracterele din jumtatea
superioar a tabelei ASCII sunt considerate litere mici. Utilizarea acestor caractere nu este ns
recomand din motivele deja menionate la descrierea alfabetului. Urmtorii termeni sunt coreci i
reprezint atomi alfanumerici:
mar cristy michael bmw a123
Atomi simbolici. Un atom simbolic este format dintr-o secven format din unul sau mai multe
din caracterele speciale enumerate mai jos:
# $ & = - ^ ~ \ @
; - / + * ? < >
sau din caractere din partea superioar a tabelei ASCII. Urmtorii termeni
& && + ++ << >> -> <- */* <$>
constituie exemple corecte de atomi simbolici.
Atomi de tip ir. Un atom de tip ir sau quoted atom este o succesiune de caractere cuprins
ntre apostrofuri. Dac se dorete inserarea unui apostrof n cadrul irului de caractere, atunci
apostroful se dubleaz.
Caracterul ~ (tilda) poate fi utilizat pentru definirea unor caractere speciale sau de control. De
exemplu termenul
~<Liter>
semnific caracterul <Ctrl> <Liter>, n timp ce termenul
~<Numr>
reprezint caracterul al crui cod ASCII este <Numr>, Numr{0,1,,255}.
Atomi rezervai. Atomii simbolici enumerai mai jos
! ; [] {} = :-
au o semnificaie prestabilit n cadrul limbajului i nu pot fi utilizai pentru denumirea unor entiti
utilizator.
irurile de caractere. Un ir de caractere este o succesiune de caractere cuprins ntre
apostrofuri invers nclinate (caracterul `). Dei irurile de caractere sunt considerate termeni simpli,
deci de tip atomic (vezi tabelul 1), acestea nu sunt considerate atomi i nu trebuie confundate cu
atomii quoted. Pentru a nu crea confuzii de acest tip, n cele ce urmeaz, pentru a desemna termenii
de acest tip se va utiliza termenul strig. Deosebirea dintre un termen de tip string i un quoted
atom const n primul rnd n modul intern de reprezentare al acestora. n plus, termenii de tip string
pot fi supui unor operaii proprii irurilor de caractere. Exist totui posibilitatea (predicatul
atom_string/2) de a se realiza conversia de la atom la tipul string i reciproc.
Termenii compui. Un termen compus are urmtoarea sintax:
functor(t1,t2,, tn) ,
unde functor este un atom (de oricare din cele trei tipuri descrise mai sus), iar argumentele t1,t2,,,tn
sunt termeni, care pot fi simpli sau structurai la rndul lor. Functorul definete practic modul de
structurare al termenului respectiv. Avnd n vedere faptul c numrul de argumente al functorului este
variabil, iar gradul de imbricare este teoretic nelimitat, un termen compus poate reprezenta practic
orice structur relaional de date, indiferent de gradul de complexitate al acesteia. n sintaxa imbricat
a unui termen compus, functorul cel mai exterior este denumit functor principal. Urmtoarele
construcii sintactice reprezint exemple corecte de termeni compui:
a(b,c(d,e(f,g))) alfa(X,Y) color(blue,yellow) +++(<<,>>,ok)
Un termen compus are urmtoarea sintax:
IASE 4/19 Cap. 2. Limbajul LPA Prolog

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).

Tabelul 1. Termenii limbajului Prolog


Tipul termenului predicat /aritate
variabil var /1, nonvar /1
atomi alfanumerici atom /1
termeni atomic atomi simbolici atom /1
simpli atomic/1 quoted atomi atom /1
simple/1 numere ntregi integer /1
number/1 reale float /1
iruri de caractere string /1
termeni termen compus functor(t1,t2,, tn) compound /1
compui (n particular liste, liste de octei)

2.3. Structura unui program PROLOG


Enunurile care intr n componena unui program LPA Prolog pot fi de unul din urmtoarele
tipuri:
clauze;
reguli de rescriere;
comenzi;
dintre care numai primele sunt obligatorii, ultimele dou tipuri de enunuri fiind opionale.
Regulile de rescriere permit programatorului definirea unui limbaj propriu prin definirea
regulilor de rescriere prin care pot fi generate frazele limbajului respectiv. Cu alte cuvinte, aceste
reguli nu sunt altceva dect produciile unei gramatici independente de context (concept definit de N.
Chomsky), utilizat pentru generarea limbajului ce se dorete a fi definit. Odat ce un astfel de limbaj
(gramatic) a fost definit (definit), programatorul poate testa dac un anumit enun aparine sau nu
limbajului respectiv. Aceste aspecte vor fi reluate i dezvoltate ntr-unul din capitolele urmtoare.
O comand este aproape identic cu o formul de interogare, singura deosebire constnd n
faptul c aceasta are ca prefix simbolul :- (dou puncte liniu). Prin urmare, formatul unei comenzi
este:
:- predicat1, predicat2, ,predicatn . (k1)
Denumirea de comand provine de la faptul c termenii executabili din componena acesteia sunt
executai n mod automat la fiecare (re)ncrcare a programului surs care incorporeaz respectiva
comand De exemplu, dac ntr-un program se insereaz comanda:
:- write(Hello !), nl.
Acesta ne va adresa un salut la fiecare ncrcare a sa.

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.

2.4. Aspectul declarativ i procedural al programelor Prolog


Caracteristica principal a limbajului Prolog const n faptul c este un limbaj declarativ, spre
deosebire de cele procedurale (limbaje specializate n descrierea procedural a rezolvrii unei
probleme).

2.4.1. Aspectul declarativ


Operaia principal care se poate executa asupra termenilor limbajului Prolog este
UNIFICAREA. Doi termeni S i T ai limbajului sunt unifiabili dac:
cei doi termeni sunt identici, ST;
substituia astfel nct ST.
Exemplu: T = data(ziua, aprilie, A); S = data(Z, Luna, 2001);
= {ziua = 1, Z=1, Luna=aprilie, A=2001}.
ST = data(1, aprilie, 2001).
cmgu({S, T}) = {ziua=Z, Luna=aprilie, A=2001}.

Regulile conform crora doi termeni doi termeni sunt unifiabili


1) dac S i T reprezint dou constante, atunci acestea sunt unifiabile numai dac sunt
identice;
2) dac unul din termeni este o variabil liber, atunci aceasta poate fi unificat cu orice
termen (simplu sau compus);
3) dac ambii termeni sunt variabile libere, unificarea se realizeaz prin legarea celor dou
variabile. Dei cele dou variabile nu sunt instaniate (iniializate), ele se comport ca i
cum ar reprezenta o variabil unic; ca urmare, orice instaniere a uneia dintre variabile
atrage dup sine i instanierea celeilalte cu aceeai valoare.
4) doi termeni compui sunt unifiabili dac sunt ndeplinite urmtoarele condiii:
au acelai functor i aceeai aritate;
argumentele de pe poziiile corespunztoare sunt unifiabile ntre ele.
Un program Prolog este o secven de clauze:
P :- Q, R.
P consecina logic a lui Q i R;
Pentru a demonstra P se demonstreaz mai nti Q, iar apoi se demonstreaz R.
Programul Prolog poate fi interogat prin precizarea unei clauze obiectiv (goal):
(G): G1, G2 ... Gn pentru ce valori ale variabilelor, predicatele G1, G2 ... Gn sunt adevrate
(simultan)? Sau, n ce condiii G este o consecin logic a formulelor din program? Pentru ce valori
ale variabilelor G este adevrat (satisfiabil)?
Definiia 1. Fie P = {C1, C2, , Cn} un program Prolog i Q o form predicativ. Q este o
consecin logic a lui P sau Q este adevrat dac sunt ndeplinite urmtoarele condiii:
1) o instan I a unei clauze din P al crei antet este unifiabil cu Q: CP i substituia
astfel nct Q = antet(C);
2) Toate predicatele din corpul regulii C (dac exist) sunt adevrate (satisfiabile).
OBS. Un fapt poate fi privit ca o regul avnt drept antet predicatul respectiv i al crei corp
este clauza vid.
Dac formula Q conine variabile Q=Q(x1, x2, ..., xn), valorile variabilelor pentru care formula
Q este adevrat sunt (x1), (x2), ..., (xn).

2.4.2. Aspectul procedural


Fie P = {C1, C2, , Cn} un program Prolog i Q o form predicativ. Q este o consecin
logic a lui P sau este satisfiabil din P dac:
astfel nct P Q.
Formula Q se numete obiectiv (goal).
IASE 8/19 Cap. 2. Limbajul LPA Prolog
Interpretorul limbajului Prolog are urmtorul mod de lucru:

Program
PROLOG P

Indicator = yes + substituia Q


Interpretor astfel nct P Q (dac Q conine variabile)
PROLOG
Goal
Inference engine

Indicator = no (Q nu este o consecin logic sau nu


este deductibil din P)
/
, P Q .

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

2.5. Liste. Prelucrarea listelor


2.5.1. Listele Prolog
O list este o colecie de zero sau mai multe obiecte. Lista fr nici un obiect se numete vid i
se reprezint prin []. Celelalte liste sunt formate din:
cap, primul element;
coada, lista celorlalte elemente, n particular lista vid.
OBS: Lista vid [] nu se poate descompune n cap i coad.
n Prolog o list se reprezint printr-un termen compus. Orice termen poate fi reprezentat printr-un
arbore. Fie termenul compus:
functor(termen 1, termen 2, ..., termen n).
rdcina arborelui este etichetat cu functorul principal al termenului (functor).
fiecrui nod etichetat cu un termen compus (rdcin) i corespunde un numr de
descendeni egal cu aritatea termenului respectiv. Aceti descendeni vor fi etichetai cu
argumentele termenului respectiv.
nodurile care corespund unor termeni simpli (atomici) sunt noduri finale.
Listele fac excepie de la aceast regul, fiind reprezentate prin functorul . de aritate 2 (cap i coad).
Exemplu: [1, 2, a, b, evrika, 29]
. (1, . (2, . (a, . (b, . (evrika, . (29))))))
S se descrie arborele asociat listei de mai sus!
Exemplu de list: [1, 2, a, b | [evrika | [29]]]. Termenul amplasat dup simbolul | trebuie s fie
o list.

2.5.2. Prelucarea listelor


1. Membru al unei liste
member(X,L), X element, L list.
{(i,i), (o,i)}: determinist (i,i) sau nedeterminist (o,i).
Implementarea se face innd cont c un element aparine unei liste dac:
o este un element al capului listei;
o face parte din coada listei respective.
member(X, [X|_]).
member(X, [_|T]):- member(X, T).
?: member(b, [a, b,c]). %(i, i) yes
?: member(X, [a, b,c]). %(o, i) X=a; X=b ; X=c.

2. Adugarea unui element la list dat

L E
add(E, L, [E|L])

E L

3. Concatenarea a dou liste


concat([], L, L).
concat([H|T], L2, [H|T2]):- concat(T, L2, T2).
4. tergerea uni element al unei liste
del(X, L, L1).
Prin teregerea unui element X din lista L se obine lista L1.

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.

Declararea operatorilor. Pe lng operatorii uzuali predefinii n limbajul Prolog,


programatorul poate s i defineasc propriii lui operatori. Declararea unui operator se realizeaz prin
intermediul comenzii op al crei format este:
:- op(<precedena>,<descriptor tip>,<nume>).
De exemplu, prin comanda
:- op(500,xfx,is_a).
este definit operatorul infix neasociativ is_a utilizat n exemplul precedent.

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.

2.7. Controlul backtraking-ului n limbajul Prolog


Exist dou procedee prin care programatorul poate interveni n funcionarea procedurii de
backtraking:
predicatul fail (predicat inconsistent), are drept efect forarea mecanismului de breaktraking
pentru revenirea n ultimul breakpoint plasat n program;
predicatul cut (predicatul !) este consistent (valid) i are drept efect suprimarea punctelor de
breakpoint plasate de predicatele precedente acestuia din corpul regulii n care acesta se gsete
sau a breakpoints corespunztoare unor clauze ale predicatului ce constituie antetul regulii.
Exemple:
1) % max/3
a) max(A,B,A):- A>=B.
max(A,B,B):- B>A.
b) max(A,B,A):- A>=B, !.
max(A,B,B):- B>A.
c) max(A,B,A):- A>=B, !.
max(A,B,B).
2) a:-b,c,!,d,e.
a:-f,g.
h:-k,l,a,m.

5.8. Structuri iterative n limbajul Prolog


a) C(X) este consistent
CAF :- p(X), C(X), !. % Cut and fail
stat/3: continentul, tara, capitala
stat(europa, romania, bucuresti).
stat(europa, albania, tirana).
stat(africa, maroc, rabat).
stat(africa, egipt, cairo).
stat(asia, thailanda, bangkok).
caf :- stat(africa, X, _), write(X), nl, X=egipt, !.
b) C(X) este inconsistent
baf :- (stat(europa, _, Capitala), write(Capitala), nl, fail); true. % Backtraking after fail
Cnd se revine la un punct de breakpoint, variabilele instaniate dup amplasarea acelui
breakpoint se elibereaz. Nu se pot reine valori prin intermediul variabilelor ntre dou iteraii
succesive.
Structurile anterioare permit parcurgerea (prelucrarea) instanelor unui anumit predicat.
User Defined Repeat se caracterizeaz prin faptul c predicatul generator de puncte de
breakpoint nu este un predicat utilizator, ci unul de forma:
repeat.
repeat :- repeat.
Repeat genereaz un numr infinit de puncte de breakpoint.
IASE 16/19 Cap. 2. Limbajul LPA Prolog
apel predicat nedeterminist
p(X)

p(a1) p(a2) p(an)

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.

Predicatele findall/3, bagof/3, setof/3


Predicatul findall are urmtoarea sintax:
findall(Termen, Obiectiv, Lista).
Obiectivul este precizat sub forma: 1 Obiectiv, 2 Obiectiv, ..., n Obiectiv.
Lista predicatul findall produce lista cu valoarea 1 Termen, 2 Termen, ..., n Termen.
findall(C, stat(europa, _, C), LCE). LCE=[bucuresti, tirana]
findall(C, stat(_, _, C), LCE).
findall(oras(C), stat(europa, _, C), LoE). LoE=[oras(bucuresti), oras(tirana)]
Predicatul bagof are urmtoarea sintax:
bagof (Termen, V1 V2.. VnObiectiv(V1,V2,.., Vn), Lista).
n care Vi sunt variabile cuantificate existenial. Variabilele care apar n obiectiv i care nu sunt
IASE 17/19 Cap. 2. Limbajul LPA Prolog
specificate ca existenial cuantificate i nu apar nici n Termen, sunt considerate variabile libere.
Predicatul bagof genereaz prin backtraking argumentul Lista pentru toate instanierile posibile
ale variabilelor.
bagof(Cap, Tarastat(Cont, Tara, Cap), L).
? Cont=europa
L=[bucuresti, tirana]
? Cont=africa
L=[rabat, cairo]
? Cont=asia
L=[bangkok]
bagof(Cap, ContTarastat(Cont, Tara, Cap), L).
L=[bucuresti, tirana, rabat, cairo, bangkok]
Predicatul setof(Termen, V1 V2.. VnObiectiv(V1,V2,.., Vn),, Lista) genereaz toate insanele
Termen pentru care un goal Prolog este true. elimin soluiile duplicat i ordoneaz elementele
listei (n conformitate cu ordonarea utilizat de predicatul compare/3).

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>.

S-ar putea să vă placă și