Documente Academic
Documente Profesional
Documente Cultură
Secţiunea “CLAUSES”
Clauzele (faptele şi regulile) pentru un predicat trebuie amplasate împreună în secţiunea CLAUSES.
O secvenţă de fapte şi reguli care definesc un predicat poartă numele de procedură.
Atunci când răspunde la o interogare, Visual Prolog va începe cu începutul secţiunii, „clauses”
căutând o potrivire cu toate faptele şi regulile din această secţiune.
Secţiunea „PREDICATES”
Atunci când se defineşte un predicat în secţiunea clauses a unui program Visual Prolog, trebuie în
prealabil declarat în secţiunea predicates prin care se comunică programului Visual Prolog despre ce este
vorba. Există şi predicate predefinite în Visual Prolog care nu trebuie redeclarate. De asemenea vor trebui
precizate domeniile argumentelor predicatului. Declararea unui predicat se face după sintaxa:
nume_predicat(tip_argument1, tip_argument2, ... )
Domeniile utilizate în declararea unui argument sunt fie domenii standard, fie domenii care au fost
declarate în secţiunea DOMAINS.
Numele predicatelor trebuie să înceapă cu literă, urmată apoi de o secvenţă de litere, cifre şi eventual
caracterul _ „underscore”. Nu are importanţă dacă literele utilizate sunt litere mari sau mici dar este
recomandabil ca prima literă să fie literă mică, deoarece alte versiuni ale limbajului Prolog nu acceptă
literele mari ca primă literă în numele unui predicat. Numele unui predicat nu poate depăşi 250 de
caractere.
Exemple de nume de predicate:
Exemple
Se poate declara un predicat cu denumirea my_predicate(symbol, integer)în secţiunea predicates:
1
PREDICATES
my_predicate(symbol, integer)
pentru care nu este necesară declararea domeniilor argumentelor în secţiunea domains deoarece
symbol şi integer sunt domenii standard. Dacă însă se declară predicatul my_predicate(name, number)
în secţiunea predicates:
PREDICATES
my_predicate(name, number)
va fi necesară o declaraţie pentru cele două domenii name şi number care nu sunt domenii standard.
Presupunând că se doreşte ca aceste domenii să corespundă domeniilor standard symbol şi integer,
secţiunea declarării domeniilor va fi:
DOMAINS
name = symbol
number = integer
PREDICATES
my_predicate(name, number)
Următoarea secţiune de program prezintă mai multe astfel de declaraţii de predicate şi de
domenii:
DOMAINS
persoana, activitate = symbol
masina, marca, culoare = symbol
kilometri, vechime, pret = integer
PREDICATES
place(persoana, activitate)
parinte(persoana, persoana)
poate_cumpara(persoana, masina)
masina(marca, kilometri, vechime, culoare, pret)
verde(symbol)
clasifica(symbol, integer)
Această secţiune de program specifică următoarele informaţii despre predicate şi despre
argumentele lor:
Predicatul place are două argumente (persoana şi activitate), ambele aparţinând domeniului
symbol (ceea ce înseamnă că valorile lor sunt alfanumerice)
Predicatul parinte are două argumente de tip persoana, unde domeniul persoana este de tip
symbol.
Predicatul poate_cumpara are două argumente persoana şi masina, care sunt ambele de tip
symbol.
Predicatul masina are 5 argumente marca şi culoare aparţin domeniului symbol, în timp ce
kilometri, vechime şi cost aparţin domeniului integer.
Predicatul clasifica, are două argumente, ambele aparţinând domeniilor standard symbol şi
integer, astfel încât nu mai este necesară declararea tipului acestora în secţiunea domains.
Secţiunea „DOMAINS”
2
există deja. În al doilea rând declararea domeniilor ne permite declararea structurilor de date care nu sunt
definite de către domeniile standard.
Uneori este util să se declare un domeniu atunci când se doreşte clarificarea unei porţiuni din secţiunea
predicates. Prin declararea unui domeniu propriu, cu un nume personalizat, mai uşor şi mai simplu se pot da nume
sugestive ale argumentelor predicatului respectiv.
Exemple
Următorul exemplu ilustrează modul în care declararea unui domeniu ajută la declararea unui
predicat:
Paul este un bărbat care are 45 de ani.
Utilizând domeniile predefinite, se poate face următoarea declaraţie de predicat:
persoana(symbol, symbol, integer)
Această declaraţie este corectă şi serveşte celor mai multor scopuri, însă argumentele sale nu au o
denumire sugestivă, astfel că, dacă peste o perioadă de timp, se doreşte o actualizare a codului respectiv,
programatorul care efectuează modificările de cod nu mai ştie ce semnificaţie a dat argumentelor
predicatului respectiv. În schimb, dacă se face o declarare prealabilă a domeniilor, folosind denumiri
sugestive, acest dezavantaj este eliminat:\
DOMAINS
nume, sex = symbol
varsta = integer
PREDICATES
persoana(nume, sex, varsta)
Unul dintre principalele avantaje ale acestor declaraţii este acela că Visual Prolog poate intercepta
erorile, cum sunt în exemplul următor:
acelasi_sex(X, Y) :-
persoana(X, Sex, _),
persoana(Sex, Y, _).
Cu toate că domeniile nume şi sex sunt definite ambele ca symbol, ele nu sunt echivalente. Prin
utilizarea declaraţiilor de domenii Visual Prolog detectează situaţiile în care ele sunt utilizate greşit, ca în
exemplul anterior în care s-au inversat.
Se pune problema dacă este recomandabil să se utilizeze astfel de declaraţii de domenii întotdeauna.
Răspunsul se poate deduce din următoarea observaţie: odată ce un argument este declarat ca aparţinând
unui domeniu specific, acel domeniu nu va putea fi înlocuit cu al domeniu care are alt nume, chiar dacă el
este de fapt acelaşi domeniu. Astfel, chiar dacă nume şi sex aparţin aceluiaşi domeniu (symbol), ele nu pot
fi inversate. Totuşi, domeniile standard se pot utiliza în locul domeniilor definite de utilizatori.
Următorul exemplu produce o eroare de incompatibilitate de tip la execuţie:
DOMAINS
produs,suma = integer
PREDICATES
adunare(suma,suma,suma)
inmultire(produs,produs,produs)
CLAUSES
adunare(X,Y,Suma):-
Suma=X+Y.
inmultire(X,Y,Produs):-
3
Produs=X*Y.
Acest program face două operaţii: adună şi înmulţeşte. Dacă se specifică următorul goal (obiectiv)):
adunare(32, 54, Suma).
Visual Prolog va da soluţia:
Suma=86
1 Solution
care este corectă.
De asemenea, pentru a testa operaţia de înmulţire, vom utiliza următorul goal:
inmultire(31, 13, Produs).
Soluţia corectă, dată de Visual Prolog va fi:
Produs=403
1 Solution
Să presupunem că avem nevoie să dublăm produsul dintre 31 şi 17, astfel că vom utiliza următorul
goal:
inmultire(31, 17, Suma), adunare(Suma, Suma, Rezultat).
Ne aşteptăm să obţinem următorul rezultat:
Suma=527, Rezultat=1054
1 Solution
Dar, în realitate vom obţine o eroare de incompatibilitate de tip. Ceea ce se întâmplă în realitate este
că se încearcă pasarea rezultatului valorii inmultire(31, 17, Suma), către predicatul adunare, atât ca prim
argument, cât şi ca al doilea argument. Predicatul adunare are însă domeniul suma pentru ambele
argumente, fapt ce va genera o eroare deoarece domeniul produs este diferit de domeniul suma, chiar
dacă ambele reprezintă în realitate integer.
Astfel, dacă o variabilă va fi utilizată în mai multe predicate, în interiorul unei clauze, el trebuie
declarat acelaşi în fiecare predicat.
Pentru o mai bună înţelegere privitoare la incompatibilităţile de tip, considerăm următorul exemplu
de program:
DOMAINS
marca,culoare = symbol
vechime = byte
pret, kilometri = ulong
PREDICATES
nondeterm masina(marca,kilometri,vechime,culoare,pret)
CLAUSES
masina(mercedes,130000,3,rosu,12000).
masina(ford,90000,4,gri,25000).
masina(cielo,8000,1,negru,30000).
În acest exemplu, predicatul masina declarat în secţiunea predicates are 5 argumente. Un argument
aparţine domeniului vechime care este de tip byte. Tipul byte este reprezentat ca întreg fără semn pe 8 biţi
şi poate lua valori de la 0 la 255 inclusiv. La fel, domeniile kilometri şi pret sunt de tipul ulong, care se
reprezintă intern ca întreg fără semn pe 32 de biţi. Domeniile marca şi culoare sunt de tip symbol.
Se poate testa predicatul maşina cu următoarele interogări (goal):
4
Toate cele 3 interogări produc erori de domeniu. În prima situaţie eroarea apare deoarece argumentul
vechime trebuie să fie de tip byte. In al doilea caz s-au interschimbat vechimea şi culoarea, iar în al treilea
caz s-au interschimbat mai multe argumente.
Secţiunea „GOAL”
În esenţă, această secţiune este identică cu corpul unei reguli. Sunt 2 diferenţe între secţiunea goal şi
o regulă:
- cuvântul cheie goal nu este urmat de „: -„
- Visual Prolog execută automat interogarea (goal) când programul rulează.
În timp ce programul rulează, se încearcă satisfacerea corpului regulii din secţiunea Goal. Dacă toate
subobiectivele (subgoal-urile) din secţiunea goal sunt terminate cu success şi programul se încheie cu
success. Dacă, în timp ce programul rulează, unul dintre subobiectivele dintr-un goal se termină cu eşec,
întregul program se termină cu eşec.
Aritate multiplă
Aritatea unui predicat este dată de numărul argumentelor sale. Pot exista două predicate cu acelaşi
nume, dar cu arităţi diferite. Aceste predicate trebuie grupate împreună în secţiunile „predicates” şi
„clauses”.
Exemplu:
DOMAINS
persoana = symbol
PREDICATES
tata(persoana) % Această persoană este un tată
tata(persoana, persoana) % O persoană este tata altei persoane
CLAUSES
tata(X): -
6
tata(X, _).
tata(adam, paul).
tata(ion, petre).
În Visual Prolog o regulă se foloseşte atunci când un fapt depinde de un alt fapt sau grup de fapte. O
regulă are un antet şi un corp cu următoarea sintaxă:
HEAD: - <subgoal 1>, <subgoal 2>, ..., <subgoal n>
Corpul unei reguli este format din unul sau mai multe subobiective (goal = obiectiv).
Subobiectivele se separă prin virgulă, specificând conjuncţia (operaţia ŞI). Fiecare subobiectiv este un
apel la un alt predicat Prolog care se poate încheia cu „succes” sau cu „eşec”. Dacă toate subobiectivele
care alcătuiesc coprul unei reguli se încheie cu succes, atunci regula se încheie cu succes, iar dacă cel
puţin un subobiectiv eşuează, atunci şi regula eşuează.
Pentru a avea succes la o regulă, Prolog trebuie să satisfacă toate subobiectivele sale. Când un
subobiectiv eşuează, Prolog se întoarce înapoi la subobiectivele anterioare, apoi continuă cu valori
schimbate ale variabilelor. Această tehnică este denumită „backtracking”.
Simbolul IF în Prolog
Secţiunea FACTS
Un program Visual Prolog este o colecţie de reguli şi fapte. Uneori, în timp ce programul este în
execuţie, se poate dori o actualizare a unor fapte. În astfel de situaţii faptele constituie o bază de date
internă dinamică, care se poate schimba în timp ce programul se execută. Visual Prolog include o secţiune
specială pentru declararea faptelor care sunt parte a bazei de date dinamice. Secţiunea începe cu cuvântul
cheie „facts”. Cuvântul facts este sinonim cu database.
7
Secţiunea Constants
Se utilizează pentru declararea de constante simbolice în Visual Prolog. O constantă simbolică se
declară astfel:
<identificator> = <macro definiţie>
Exemple:
CONSTANTS
zero = 0
pi = 3.1415927