Sunteți pe pagina 1din 8

Structura unui program VISUAL PROLOG

Un program PROLOG conţine 4 secţiuni de bază:


“clauses”
“predicates”
“domains”
“goal”
Secţiunea “clauses” conţine faptele şi regulile cu care va opera PROLOG pentru satisfacerea
interogărilor.
Secţiunea “predicates” este secţiunea în care se declară predicatele şi domeniile (tipurile)
argumentelor.
Secţiunea “domains” cuprinde declarea domeniilor (tipurilor) utilizate în program şi care nu sunt
domenii standard.
Secţiunea “goal” este secţiunea în care se fac interogările.

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:

Nume corecte de predicate Nume incorecte de predicate


fact [fact]
este_un *este_un*
are_o are/o
listaDeVerificare lista-De-Verificare
choose_Menu_Item choose Menu Item
predicateName predicate<Name>

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”

În Visual Prolog se declară care sunt domeniile (tipurile) argumentelor predicatelor.


Secţiunea domains permite utilizarea de nume distincte pentru diferitele tipuri de date care sunt de
fapt de acelaşi tip. Într-un program Prolog obiectele dintr-o relaţie (argumentele unui predicat) aparţin
unor domenii. Există domenii predefinite sau domenii definite de utilizatori.
Secţiunea domains este utilă în două scopuri. În primul rând se poate da un sens, un înţeles numelui
unui domeniu, chiar dacă din punct de vedere al reprezentării interne este acelaşi cu un domeniu care

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

masina(renault, 13, 40000, rosu, 12000).


masina(ford, 90000, gri, 4, 25000).
masina(1, rosu, 30000, 80000, cielo).

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.

Visual Prolog are câteva domenii standard:


Domenii standard:
short : -32768 ÷ 32767 - întreg scurt pe 16 biţi, independent de platformă;
ushort : 0 ÷ 65535 - întreg scurt pe 16 biţi fără semn, independent de platformă;
long : întreg lung pe 32 biţi, independent de platformă;
ulong : întreg lung pe 32 biţi fără semn, independent de platformă;
integer: întreg cu semn având dimensiunea dependentă de arhitectura calculatorului (16 sau 32
biţi);
unsigned: întreg fără semn pe 16 sau 32 biţi;
byte : octet 0 ÷ 255;
word : 2 octeţi 0 ÷ 65535;
dword : 4 octeţi : întreg pozitiv.
Din punct de vedere sintactic, o valoare aparţinând unuia dintre domeniile întregi standard este scrisă
ca o secvenţă de cifre precedate opţional de un semn (-), fără spaţii albe. Există şi sintaxe octale sau
hexazecimale pentru domeniile întregi.
Se pot utiliza cuvintele cheie signed şi unsigned în conjuncţie cu byte, word şi dword pentru a
construi noi domenii ca în exemplul următor:
DOMAINS
i8 = signed byte
unde se creează un nou domeniu întreg având valorile între -128 şi +127.
Alte domenii standard sunt prezentate în continuare:
char – un caracter reprezentat pe un octet;
real – numărul real în virgulă mobilă reprezentat pe 8 octeţi în convenţia IEEE, echivalentul tipului
C – „double”;
string – o secvenţă de caractere în două formate acceptate:
1. O secvenţă de litere, numărul care începe cu literă mică;
2. O secvenţă de caractere între ghilimele.
symbol – o secvenţă de caractere cu aceeaşi sintaxă ca şi la tipul string.
Domeniile „string” şi „symbol” sunt la fel, însă Visual Prolog le memorează diferit. Pentru
symbol, Visual Prolog utilizează o tabelă în care sunt reţinute adresele lor, astfel că, dacă într-un program
se utilizează în mod repetat, el poate fi găsit foarte repede şi este memorat mai compact. Pentru domeniul
string nu este posibilă utilizarea unei astfel de tabele şi Visual Prolog va examina un string caracter cu
caracter.
Exemple de obiecte de diferite domenii:
5
„&&”, maria, „produs program”, an_1_info symbol sau string
-1, 3, 42, 5, 0, 25 integer
3, 45, 0.01, -30.0, 123.4e+5 real
′ a′ , ′ b′ , ′ /′ , ′ $′ char

Declararea argumentelor în cadrul predicatelor


Presupunem că avem următoarea relaţie între obiecte:
pavel este un bărbat în vârstă de 45 de ani.
Faptele Prolog care corespund acestei relaţii în limbaj natural sunt:
persoana(pavel, bărbat, 45)
Pentru a declara predicatul „persoana” cu acest argument, se face următoarea declaraţie în
secţiunea „predicates”
persoana(symbol, symbol, byte)
În această declaraţie s-au folosit 3 argumente de tipuri (domenii) standard. Dacă programul
foloseşte numai argumente standard, nu este necesară secţiunea „domains”.
Să presupunem că dorim să declarăm un predicat care va furniza poziţia unei litere în alfabet. Acest
predicat ar putea fi:
pozitie_alfabet(Litera, Pozitia)
vom avea Pozitia = 1 dacă Litera = a, Pozitia = 2 dacă Litera = b şi aşa mai departe. Clauzele pentru
acest predicat vor fi asemănătoare cu următoarea clauză:
pozitie_alfabet(Un_caracter, N).
Clauzele pentru acest predicat vor fi:
pozitie_alfabet('a', 1).
pozitie_alfabet('b', 2).
pozitie_alfabet('c', 3).
...
pozitie_alfabet('z', 26).
Se poate declara predicatul pozitie_alfabet astfel:
PREDICATES
pozitie_alfabet(char, unsigned)
Se poate interoga acest program cu următoarele interogări:
pozitie_alfabet('a', 1).
pozitie_alfabet (X, 3).
pozitie_alfabet ('z', Care).

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

Sintaxa unei reguli în Visual Prolog

Î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

- se utilizează în loc de „: - ” şi se poate „citi” astfel:


„HEAD” is true if „BODY” is true
antetul este adevărat, dacă corpul este adevărat.
Semnificaţia simbolului IF în Prolog diferă de semnificaţia aceluiaşi simbol din alte limbaje de
programare, ca de exemplu Pascal sau C.
În Pascal, condiţia conţinută în instrucţiunea IF trebuie pusă înaintea corpului instrucţiunii, cu alte
cuvinte:
"if HEAD is true, then BODY is true (sau: then do BODY)"

Conversii automate de tip


Când Prolog încearcă satisfacerea unui goal (obiectiv), de exemplu prin potrivirea a două variabile,
este necesar ca aceste variabile să aparţină aceluiaşi domeniu. De asemenea, variabilele pot fi uneori
legate cu constante aparţinând altor domenii. Acest lucru este posibil deoarece Visual Prolog face
conversii de tip în mod automat (de la un domeniu la altul) în următoarele situaţii:
• Între string şi symbol.
• Între toate domeniile întregi şi real. La conversia unui caracter într-un întreg acesta primeşte ca
valoare codul să ASCII.

Alte secţiuni 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

Există câteva restricţii în utilizarea constantelor simbolice:


Definirea unei constante nu poate face o referire la ea însăşi. De exemplu:
x = 2*x/2 /* nu este corect */
şi va genera următorul mesaj de eroare: Recursion in constant definition.
Sistemul nu face distincţie între literele mari şi literele mici într-o declaraţie de constante. Totuşi
trebuie evitată utilizarea literelor mari ca primă literă într-o secţiune clauses pentru a nu se confunda cu
variabilele, ca în exemplul următor:
CONSTANTS
Doi = 2
GOAL
A=doi, write(A).
Pot fi declarate mai multe constante într-un program, însă constantele trebuie declarate înainte de
utilizarea lor.
Declaraţiile de constante devin effective din punctul în care sunt făcute şi rămân valabile în orice fişier
inclus după declarare. Un identificator constantă trebuie declarat o singură dată.

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