20 elemente de compilare }i dezvoltarea programelor mari
20 elemente de compilare }i dezvoltarea programelor mari
20 elemente de compilare }i dezvoltarea programelor mari
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].