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

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

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!