28.04.2013 Views

20 elemente de compilare }i dezvoltarea programelor mari

20 elemente de compilare }i dezvoltarea programelor mari

20 elemente de compilare }i dezvoltarea programelor mari

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

Readiness is all<br />

SHAKESPEARE - Hamlet, V, 2<br />

<strong>20</strong><br />

ELEMENTE DE COMPILARE }I<br />

DEZVOLTAREA PROGRAMELOR<br />

MARI<br />

Obiective<br />

-clarificarea unor probleme legate <strong>de</strong> analiza la <strong>compilare</strong>;<br />

-directive <strong>de</strong> <strong>compilare</strong>;<br />

-optimizarea program[rii aplica\iilor <strong>mari</strong>;<br />

A. Utilizarea i<strong>de</strong>ntificatorilor<br />

Exemplul urm[tor pune @n evi<strong>de</strong>n\[ libertatea <strong>de</strong> scriere a<br />

i<strong>de</strong>ntificatorilor @ntr-un program Turbo Prolog (folosirea literelor <strong>mari</strong> ]i<br />

mici, a cifrelor ]i a caracterului '_'un<strong>de</strong>rline):<br />

domains<br />

cifra0=integer<br />

MAJUSCULE=symbol<br />

_LiniaMea=char<br />

trace=string<br />

predicates<br />

este_mare(real)<br />

este_mica(cifra0)<br />

minuscule(majuscule)<br />

_subliniat(_liniaMea)<br />

diagnostics(TRACE)<br />

clauses<br />

este_Mare(124671).<br />

_SUBLINIAT('_").<br />

MINUSCULE(z).<br />

DIAGNOSTICS(proiect).<br />

Exemplul <strong>20</strong>.1. Caractere <strong>de</strong> tot felul ...<br />

Problema omonimiei i<strong>de</strong>ntificatorilor apare <strong>de</strong>stul <strong>de</strong> <strong>de</strong>s @n<br />

scrierea <strong>programelor</strong> Turbo Prolog, atunci c`nd dorim ca ace]tia s[<br />

clarifice textul surs[ al programului. Exemplul <strong>20</strong>.2. vine s[ ilustreze<br />

marea majoritate a omonimiilor permise <strong>de</strong> compilatorul Turbo Prolog:


188 Practica program[rii logice<br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

⎯<br />

domains<br />

oras=symbol<br />

anul=integer<br />

universitate=universitate(oras,anul)<br />

predicates<br />

universitate(universitate)<br />

clauses<br />

universitate(universitate(craiova,1966)).<br />

goal<br />

universitate(Universitate),write(Universitate).<br />

Exemplul <strong>20</strong>.2. Omonimia i<strong>de</strong>ntificatorilor.<br />

Cu toate acestea, compilatorul Turbo Prolog nu accept[<br />

@ntot<strong>de</strong>auna omonimia i<strong>de</strong>ntificatorilor <strong>de</strong> domenii cu cei <strong>de</strong> functori,<br />

avertiz`nd utilizatorul cu eroarea :<br />

111 WARNING: Domain used as a functor<br />

domains<br />

sir=string<br />

cuvant=cuvant(sir);sir<br />

Exemplul <strong>20</strong>.3. Omonimie neacceptat[ (eroare 111).<br />

Eroarea poate fi evitat[ <strong>de</strong> exemplu prin rescrierea argumentului<br />

functorului cuvant astfel:<br />

sau<br />

s=string<br />

sir=string<br />

cuvant=cuvant(s);sir<br />

sir=string<br />

cuvant=cuvant(sir);string()<br />

Mai mult, o alt[ eroare <strong>de</strong> avertisment apare atunci c`nd se<br />

<strong>de</strong>fine]te un domeniu ce con\ine un singur functor:<br />

112 WARNING: Domain <strong>de</strong>claration with a single functor.<br />

domains<br />

cuvant=sir_<strong>de</strong>_litere<br />

Exemplul <strong>20</strong>.4. Domeniu cu un singur functor (eroare 112).


Elemente <strong>de</strong> <strong>compilare</strong> 189<br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

⎯<br />

#n<strong>de</strong>p[rtarea erorii 112 se realizeaz[ tot printr-o rescriere a<br />

<strong>de</strong>clara\iilor <strong>de</strong> domenii. #n cap. 2 am v[zut <strong>de</strong>ja c[ Turbo Prolog dispune<br />

<strong>de</strong> o sec\iune <strong>de</strong> constante - utilizate @n program cu semnifica\ia obi]nuit[<br />

(valori care nu se schimb[ @n timpul execu\iei programului).<br />

constants<br />

ion="Sfantul Ion"<br />

x =Variabila<br />

predicates<br />

sfant(symbol)<br />

clauses<br />

sfant(ion).<br />

goal<br />

sfant("Sfantul Ion"),sfant(x),write(x).<br />

Exemplul <strong>20</strong>.4. O constant[ fals[ ...<br />

Constanta x are valoarea <strong>de</strong>finit[ Variabila ceea ce face ca x s[<br />

fie tratat[ @n <strong>de</strong>monstra\ie ca o variabil[ ! (<strong>de</strong> fapt problema provine <strong>de</strong> la<br />

<strong>de</strong>fini\ia lui x care este un i<strong>de</strong>ntificator ce @ncepe cu liter[ mare)<br />

B. Re<strong>de</strong>finirea predicatelor<br />

O regul[ nu poate utiliza argumente ale unui predicat diferite <strong>de</strong><br />

tipul celor din <strong>de</strong>clara\ia sa.<br />

domains<br />

stanga,dreapta=symbol<br />

predicates<br />

la_stanga(stanga,dreapta)<br />

la_dreapta(dreapta,stanga)<br />

langa(stanga,dreapta)<br />

clauses<br />

la_dreapta(casa,arbore).<br />

la_stanga(casa,garaj).<br />

langa(X,Y):-la_stanga(X,Y).<br />

langa(X,Y):-la_dreapta(X,Y).<br />

Exemplul <strong>20</strong>.5. Concordan\a variabil[ - domeniu.<br />

Programul <strong>de</strong> mai sus furnizeaz[ eroarea fatal[;<br />

505 Type error: Illegal variable type for this<br />

position


190 Practica program[rii logice<br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

⎯<br />

De]i stanga, dreapta sunt ambele simboluri, argumentele<br />

predicatelor langa ]i la_dreapta sunt tratate diferit ("teama <strong>de</strong><br />

semnifica\ii diferite..."). O solu\ie posibil[ este schimbarea <strong>de</strong>clara\iei<br />

predicatului langa (vezi ]i cap. 2):<br />

sau<br />

langa(symbol,symbol)<br />

langa(stanga,dreapta)<br />

langa(dreapta,stanga)<br />

Prezent[m mai jos un program care ilustreaz[ rolul hot[r`tor al<br />

ordinei <strong>de</strong>clara\iilor unui acela]i predicat:<br />

predicates<br />

produs(integer,real,real)<br />

produs(real,integer,real)<br />

produs(integer,integer,integer)<br />

produs(real,real,real)<br />

clauses<br />

produs(X,Y,Z):-bound(X),bound(Y),Z=X*Y.<br />

produs(X,Y,Z):-bound(X),bound(Z),Y=Z/X.<br />

produs(X,Y,Z):-bound(Z),bound(Y),X=Z/Y.<br />

Exemplul <strong>20</strong>.6. Ordinea <strong>de</strong>clara\iilor.<br />

La scopul extern produs(2.4,0.5,X) se furnizeaz[ solu\ia X=1<br />

ceea ce este evi<strong>de</strong>nt o eroare <strong>de</strong> semnifica\ie a predicatului (care nici nu<br />

este <strong>de</strong>pistat[ @n faza <strong>de</strong> <strong>compilare</strong> !). O solu\ie pentru @nl[turarea acestei<br />

situa\ii este scrierea ultimei <strong>de</strong>clara\ii a lui produs pe prima pozi\ie (vezi<br />

conversii <strong>de</strong> tip).<br />

C. Conversii <strong>de</strong> tip<br />

O variabil[, @ntr-o regul[, nu poate fi legat[ la valori <strong>de</strong> tipuri<br />

diferite <strong>de</strong>c`t @n cazul unor conversii <strong>de</strong> tip recunoscute <strong>de</strong> compilator.<br />

Dac[ tipurile nu pot fi convertite compilatorul semnaleaz[:<br />

505 Type error: Illegal variable for this position<br />

510 Objects from these domains cannot be compared<br />

Conversia <strong>de</strong> tip intervine <strong>de</strong>asemenea ]i @ntr-o punere @n<br />

corespon<strong>de</strong>n\[ a unei variabile legate cu o valoare <strong>de</strong> tip diferit.<br />

Tip 1 Tip 2 Compatibilitate Observa\ii


Elemente <strong>de</strong> <strong>compilare</strong> 191<br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

⎯<br />

string char nu 510 sau 505<br />

string integer nu 510 sau 505<br />

string real nu 510 sau 505<br />

string symbol da <strong>de</strong>fini\ie<br />

char integer da<br />

char real da<br />

char symbol nu 510 sau 505<br />

integer real da<br />

integer symbol nu 510 sau 505<br />

real symbol nu 510 sau 505<br />

Tabelul <strong>20</strong>.1. Conversii <strong>de</strong> tipuri.<br />

Remarc[: Compatibilitatea lui char cu integer ]i real se refer[<br />

la plaja <strong>de</strong> numere @ntregi care sunt coduri ASCII pentru caractere.<br />

predicates<br />

go<br />

clauses<br />

go:-X=122,X='z'.<br />

Exemplul <strong>20</strong>.7. Compatibilitate <strong>de</strong> tip.<br />

Cu toate acestea, exemplul urm[tor <strong>de</strong>monstreaz[ c[ exist[ o<br />

diferen\[ @ntre compatibilitatea domeniilor ]i semnifica\ia predicatelor din<br />

program:<br />

predicates<br />

egal(integer,real)<br />

egal(char,integer)<br />

egal(symbol,string)<br />

egal(real,char)<br />

clauses<br />

egal(X,X).<br />

goal<br />

egal(1.1,V),write(1.1,"=",V).<br />

Exemplul <strong>20</strong>.8. Este egalitatea corect[ ?


192 Practica program[rii logice<br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

⎯<br />

D. Probleme <strong>de</strong> <strong>compilare</strong> a <strong>programelor</strong><br />

D1) Pentru a compila un program Turbo Prolog sub form[ <strong>de</strong><br />

fi]ier executabil (.EXE) @n sistemul <strong>de</strong> operare DOS sunt necesare<br />

urm[toarele:<br />

- Fi]ierele PROLOG.LIB ]i INIT.OBJ trebuie s[ se afle @n acela]i<br />

director cu PROLOG.EXE;<br />

- Compila\i programul @n memorie sub Turbo Prolog pentru a<br />

verifica corectitudinea sa;<br />

- Orice program compilat pe disc con\ine obligatoriu un scop<br />

intern;<br />

- Salva\i programul folosind Save din meniul Files (sau F2);<br />

- Selecta\i Compile din meniul principal ]i apoi<br />

EXE file (auto link) din acest meniu; ap[sa\i ]i programul va fi<br />

compilat pe disc; fereastra Message va afi]a: Execute(y/n): cu<br />

semnifica\ia evi<strong>de</strong>nt[;<br />

- #n urma procesului <strong>de</strong> mai sus fi]ierul NUME.PRO al textului<br />

surs[ va fi compilat @n fi]ierul NUME.EXE care se va afla @n acela]i<br />

director.<br />

Remarca: Opera\ia <strong>de</strong> <strong>compilare</strong> extern[ comport[ <strong>de</strong> fapt dou[<br />

etape:<br />

- generarea formatului obiect (fi]ierul NUME.OBJ);<br />

- editarea <strong>de</strong> leg[turi - combinarea fi]ierelor NUME.OBJ,<br />

INIT.OBJ ]i fragmente din PROLOG.LIB pentru a crea NUME.EXE; Nu<br />

este nevoie s[ folosim un alt linkeditor @n linie <strong>de</strong> comand[ ( <strong>de</strong> exemplu<br />

LINK.EXE al DOS).<br />

#nainte <strong>de</strong> <strong>compilare</strong>a extern[ trebuie s[ ne asigur[m c[ exist[<br />

suficient spa\iu pe disc pentru crearea tuturor fi]ierelor (<strong>de</strong> exemplu, dac[<br />

NUME.PRO are 7000 bytes, atunci NUME.OBJ are 11000 bytes iar<br />

NUME.EXE are 56000 bytes).<br />

Op\iunea OBJ file din meniul Compile este utilizat[ pentru<br />

generarea <strong>de</strong> fi]iere format obiect care pot fi apoi legate cu alte fi]iere<br />

obiect scrise @n alte limbaje cu ajutorul unui linkeditor extern ([1]).<br />

D2) #n cazul @n care avem un program Turbo Prolog foarte mare<br />

este posibil ca @n faza <strong>de</strong> <strong>compilare</strong> s[ apar[ o eroare <strong>de</strong> tip Overflow care<br />

specific[ <strong>de</strong>p[]irea zonei <strong>de</strong> memorie alocat[ pentru probramul compilat<br />

pe care o recunoa]te compilatorul (implicit aceast[ zon[ are 16 kB).<br />

Pentru a remedia putem utiliza o directiv[ <strong>de</strong> <strong>compilare</strong> care va<br />

redimensiona aceast[ zon[:


Elemente <strong>de</strong> <strong>compilare</strong> 193<br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

⎯<br />

co<strong>de</strong>=numar<br />

un<strong>de</strong> numar este num[rul <strong>de</strong> paragrafe <strong>de</strong>stinate acestei zone<br />

(1 paragraf = 16 bytes);<br />

De exemplu, pentru dimensionarea unei zone <strong>de</strong> 32 Kb plas[m la<br />

@nceputul programului co<strong>de</strong>=<strong>20</strong>48. Aceast[ directiv[ poate fi substituit[<br />

pentru cazul <strong>programelor</strong> executate sub Turbo Prolog folosind meniul<br />

Options/Compiler directives/Memory allocation/Co<strong>de</strong>....<br />

Dac[ la execu\ia unui program Turbo Prolog apare eroarea<br />

1002 Stack overflow<br />

este necesar s[ ne asigur[m <strong>de</strong> corecta elaborare din punct <strong>de</strong> ve<strong>de</strong>re logic<br />

a programului iar dac[ avem @n<strong>de</strong>plinit[ aceast[ condi\ie, trebuie s[<br />

redimension[m stiva <strong>de</strong> lucru a motorului <strong>de</strong> inferen\e folosind meniul<br />

Options/Compiler directives/Memory allocation/Stack... <strong>de</strong>sigur<br />

tot @n paragrafe.<br />

D3) Un predicat care genereaz[ solu\ii multiple @n cursul unui<br />

proces <strong>de</strong> <strong>de</strong>monstra\ie se nume]te ne<strong>de</strong>terminist. Compilatorul Turbo<br />

Prolog dispune <strong>de</strong> directiva check_<strong>de</strong>term (care se plaseaz[ @naintea<br />

sec\iunii domains din program) pentru avertizarea utilizatorului asupra<br />

clauzelor ne<strong>de</strong>terministe - permite <strong>de</strong>ci programatorului remedierea<br />

situa\iilor nedorite (eventual folosirea t[ieturii). #n cazul @n care<br />

programatorul cunoa]te predicatele ne<strong>de</strong>terministe din program ]i dore]te<br />

s[ r[m`n[ ca atare, aceste predicate trebuie s[ fie precedate @n <strong>de</strong>clara\ie<br />

<strong>de</strong> op\iunea non<strong>de</strong>term. Deasemenea, pentru a ob\ine un raport <strong>de</strong>taliat<br />

asupra predicatelor dintr-un program, se folose]te directiva diagnostics<br />

fie @n program (plasat[ la @nceputul acestuia) c`t ]i din meniul<br />

Options/Compiler directives/Diagnostics.<br />

E. Imbricarea <strong>programelor</strong> Turbo Prolog<br />

#n situa\ia @n care acelea]i <strong>de</strong>clara\ii <strong>de</strong> domenii, <strong>de</strong>clara\ii <strong>de</strong><br />

predicate ]i <strong>de</strong>fini\ii sunt utilizate @n mai multe programe, este util[<br />

folosirea directivei<br />

inclu<strong>de</strong> "NUME.PRO"<br />

un<strong>de</strong> NUME.PRO este numele fi]ierului Turbo Prolog care<br />

con\ine <strong>de</strong>fini\iile ]i <strong>de</strong>clara\iile necesare.<br />

Efectul acestei directive const[ @n imbricarea programului NUME.PRO @n<br />

programul propriu, chiar @n pozi\ia @n care apare directiva. Programatorul<br />

trebuie s[ verifice eventualele neconcordan\e care pot apare (predicate<br />

folosite dar @nc[ ne<strong>de</strong>clarate etc).


194 Practica program[rii logice<br />

⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯<br />

⎯<br />

F. Programarea modular[<br />

Atunci c`nd programul este foarte mare sau c`nd este necesar ca<br />

unele predicate s[ fie scrise @n alte limbaje <strong>de</strong> programare este util[ chiar<br />

necesar[ structurarea sa @n mai multe module care vor fi compilate separat<br />

cu urm[toarele avantaje:<br />

- mai mul\i programatori pot lucra simultan la mai multe module;<br />

- se pot realiza noi programe folosind module <strong>de</strong>ja create ]i testate;<br />

- se simplific[ <strong>de</strong>panarea; modulele pot fi testate in<strong>de</strong>pen<strong>de</strong>nt;<br />

- @n cazul modific[rii programului se modific[ doar modulele relevante;<br />

- modulele pot fi scrise ]i @n alte limbaje <strong>de</strong> programare;<br />

- modulele pot avea at`t predicate locale c`t ]i globale;<br />

Pentru a realiza modularea unui program se parcurg urm[toarele<br />

etape:<br />

- se <strong>de</strong>fine]te un fi]ier proiect (.PRJ) cu ajutorul meniului<br />

0ptions/Edit PRJ files; acest fi]ier va con\ine numele modulelor<br />

programului ca @n exemplul <strong>de</strong> mai jos:<br />

prog1+<br />

prog2+<br />

prog3+<br />

prog4+<br />

Exemplul <strong>20</strong>.9. Con\inutul unui fi]ier proiect.<br />

Aceste module sunt fie fi]iere scrise @n Turbo Prolog fie fi]iere<br />

obiect scrise @n alte limbaje.<br />

- unul din module va fi <strong>de</strong>semnat ca modul principal ]i este<br />

singurul care va con\ine un scop (evi<strong>de</strong>nt, numai intern);<br />

Pentru <strong>compilare</strong>a tuturor modulelor folosim<br />

Compile/Project (all files)<br />

care solicit[ numele proiectului ]i compileaz[ toate modulele.<br />

Un modul poate fi compilat separat @n format obiect cu op\iunea<br />

din meniul Compile/OBJ file. #n cazul @n care un domeniu sau un<br />

predicat se dore]te s[ fie vizibil @n mai multe module trebuie s[ fie<br />

<strong>de</strong>clarat @n sec\iunea global domains respectiv global predicates, care<br />

se plaseaz[ la @nceputul modulului @nainte <strong>de</strong> sec\iunea domains respectiv<br />

predicates. Pentru <strong>de</strong>talii [1].

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!