Sunteți pe pagina 1din 244

UNIVERSITATEA TITU MAIORESCU

Facultatea de INFORMATICĂ

Prof. univ. dr.

VASILE PODARU

Curs pentru învăţământul la distanţă

BUCUREŞTI – 2011
UNIVERSITATEA Titu MAIORESCU Bucureşti
Facultatea de Informatică
Învăţământ la Distanţă

INTELIGENŢĂ ARTIFICIALĂ
Inteligenţa artificială este una din disciplinele de pregătire fundamentală care, pentru
profilul INFORMATICĂ, este esenţială pentru pregătirea studenţilor şi pentru obţinerea
creditelor transferabile prin procedurile de evaluare. Modul de prezentare a acestui material
are în vedere particularităţile învăţământului la distanţă, la care studiul individual este
determinant. Pentru orice nelămuriri faţă de acest material vă rugăm să contactaţi tutorele de
disciplină care are datoria să vă ajute oferindu-vă toate explicaţiile necesare.
Disciplina de Inteligenţa artificială îşi propune următoarele obiective specifice:
Însuşirea noţiunilor fundamentale din domeniile Inteligenţei artificiale.
Formarea deprinderilor de modelare matematică şi de transpunere în programare a
unor probleme de natură tehnică, socială sau economică, cu utilizarea cunoştinţelor
însuşite.
Formarea şi dezvoltarea aptitudinilor şi deprinderilor de analiză logică, formulare
corectă şi argumentare fundamentată, în rezolvarea problemelor tehnico-economice şi
de specialitatecu cu utilizarea cunoştinţelor însuşite prin intermediul metodelor şi
modelelor specifice inteligenţei artificiale;
Insusirea principiilor generale ale programarii logice si insusirea limbajului Prolog;
O comparaţie critică a metodelor de rezolvare evidenţiind, eventual, calea optimă de
soluţionare.
Accentul se va pune pe problemele de cautare si reprezentare a cunostintelor si
respectiv pe programarea logica, limbajul de programare utilizat la laborator fiind
limbajul Prolog (în anexă, modulul 5, se găseşte un îndrumar privind programarea în
PROLOG). Cursul trebuie sa trateze aspecte ale rezolvarii problemelor prin
intermediul cautarii, descriind cele mai importante tehnici de cautare informata si
neinformata. Se vor da exmple de aplicatii ale cautarii, cum ar fi jocurile, tratate ca
probleme de cautare. Se vor prezenta principalele tipuri de cunostinte si principalele
metode de reprezentare a cunostintelor. Se va face legatura dintre reprezentarea
cunostintelor si sistemele expert. Se va da un exemplu de bază de cunoştinţe de sistem
expert cu implementare in Prolog. Vor mai fi tratate, ca modalitati de reprezentare a
cunostintelor, retelele semantice si retelele Bayesiene (cu introducerea rationamentului
statistic). Metodele de învăţare şi reţelele neuronale sunt alte domenii importante pe
care le vom trata în acest material.

Vă precizăm de asemenea că, din punct de vedere al verificărilor şi al notării


(elemente ce vor fi comunicate şi prin fişa disciplinei, calendarul disciplinei şi programarea
orară), cu adevărat importantă este capacitatea pe care trebuie să o dobândiţi şi să o probaţi de
a rezolva toată tipologia de probleme aplicative aferente materialului teoretic prezentat în
continuare. De aceea vă recomandăm să parcurgeţi cu atenţie toate aplicaţiile rezolvate, să
rezolvaţi aplicaţiile propuse prin testele de autoevaluare şi temele de control (pentru fiecare
modul în parte trebuie să predaţi tutorelui de disciplină rezolvarea acestor teme, pentru
verificare şi evaluare); fiţi convinşi că examenul final apelează la tipurile de aplicaţii prezente
în secţiunile menţionate anterior.
Timpul mediu necesar însuşirii noţiunilor teoretice, formării deprinderilor de calcul şi
utilizării metodelor de rezolvare a problemelor specifice acestui modul este estimat la
2
aproximativ 6-8 ore pentru întregul modul , într-un ritm de 3-4 ore pentru fiecare din cele
două unităţi ale modulului.
Întru-cât modulul este privit ca un tot unitar exerciţiile aferente acestui modul se
găsesc la sfârşitul acestui modul. La terminarea parcurgerii acestui modul studenţii trebuie să
prezinte tutorelui de disciplină rezolvarea temei de control propusă spre rezolvare la sfîrşitul
modulului.
Cursul se finalizează prin examen care constă din:
1) o lucrare scrisă sub forma de text grila constând din 9-18 subiecte (ponderea lucrării
scrise este de 70% din nota finală);
2) rezolvarea corectă a temelor de control din cele 4 module (minimum nota 5 pentru
fiecare temă, ponderea mediei celor 5 note în nota finală este de 20%);
3) participarea activă la activităţile tutoriale (apreciată printr-o notă a cărei pondere in
nota finală este de 10%).

Coordonator disciplină: Prof. univ. dr. Vasile PODARU, email: podaruv@gmail.com


Tutori: Prof. univ. dr. Vasile PODARU,

3
MODULUL 1

REPREZENTAREA CUNOAŞTERII. PROBLEMATICA


REZOLVĂRII PROBLEMELOR.

Îndrumări metodice.

În acest modul sunt prezentate principalele noţiuni referitoare la reprezentarea


cunoaşterii şi de rezolvarea problemelor, esenţiale în domeniul inteligenţei artificiale.
În prima parte a acestui modul sunt prezentate informaţii referitoare la domeniul
inteligenţei artificiale, istoric şi domenii de activitate, legătura cu alte discipline. Sunt
prezentate apoi principalele metode de reprezentare a cunoaşterii în contextul transpunerii
acestora în programe pe calculator.
Rezolvarea problemelor este obiectivul fiecărui sistem inteligent şi se va face atât prin
căutarea unor răspunsuri predefinite la unele întrebări, dar mai ales prin procese complexe de
deducţie, de calcul simbolic şi evaluări numerice, care se bazează pe faptele specificate în
enunţul problemelor şi pe fapte înregistrate a priori în baza de cunoştinţe.
În partea a doua a acestui modul se prezintă problematica rezolvării problemelor.
Timpul mediu necesar însuşirii noţiunilor teoretice, formării deprinderilor de calcul şi
utilizării metodelor de rezolvare a problemelor specifice acestui modul este estimat la
aproximativ 6-8 ore pentru întregul modul , într-un ritm de 3-4 ore pentru fiecare din cele
două unităţi ale modulului.
Întru-cât modulul este privit ca un tot unitar exerciţiile aferente acestui modul se
găsesc la sfârşitul acestui modul. La terminarea parcurgerii acestui modul studenţii trebuie să
prezinte tutorelui de disciplină rezolvarea temei de control propusă spre rezolvare la sfîrşitul
modulului.
Cursul se finalizează prin examen care constă din:
1) o lucrare scrisă sub forma de text grila constând din 9-18 subiecte (ponderea lucrării
scrise este de 70% din nota finală);
2) rezolvarea corectă a temelor de control din cele 5 module (minimum nota 5 pentru
fiecare temă, ponderea mediei celor 5 note în nota finală este de 20%);
3) participarea activă la activităţile tutoriale (apreciată printr-o notă a cărei pondere in
nota finală este de 10%).

4
Unitatea de învăţare nr.1
Elemente de reprezentare a cunoaşterii
Cuprins:
1.0. Domeniul inteligenţei artificiale.................................................................. pag. 5
1.0.1. Scurtă prezentare .................................................................................. ... pag. 5
1.0.2. Testul Turing ........................................................................................... pag. 6
1.0.3. Scurt istoric .............................................................................................. pag. 7
1.0.4. Domenii de interes şi de cercetare pentru IA ........................................... pag. 8
1.0.5. Fundamentele matematice.Domeniile principale de studiu şi
de aplicabilitate ale IA ....................................................................................... pag. 9
1.0.6. Limbaje de programare specifice domeniului .......................................... pag. 9
1.1. Reprezentarea cunoaşterii............................................................................ pag. 9
1.1.0. Introducere ............................................................................................... pag. 9
1.1.1. Reprezentarea cunoaşterii în limbajul calculului cu predicate
de ordinul I. ....................................................................................................... pag.11
1.1.2. Metode procedurale de reprezentare a cunoşterii .................................... pag.15
1.1.3. Reprezentarea cunoşterii prin reguli de producţie.................................... pag.16
1.1.4. Reţele semantice ...................................................................................... pag.19
1.1.5. Reprezentarea cunoaşterii cu ajutorul cadrelor ........................................ pag. 25

1.0. Domeniul inteligenţei artificiale.

1.0.1. Scurtă prezentare.


Domeniul de studiu al inteligenţei artificiale (IA) îl reprezintă înţelegerea entităţilor
inteligente. Datorită acestui fapt, unul dintre motivele pentru care se fac cercetări în acest
domeniu este acela de a învăţa mai multe despre noi înşine. Spre deosebire de filozofie şi
psihologie, care studiază de asemenea inteligenţa, IA se ocupă în principal cu crearea şi
înţelegerea entităţilor inteligente.
Inteligenţa artificială a dus la obţinerea unor produse foarte interesante, încă din
primele momente ale existenţei sale. Cu toate că nimeni nu poate prezice viitorul IA, este
evident că apariţia unor calculatoare cu un nivel de inteligenţă comparabil cu cel uman ar avea
un impact uriaş asupra societăţii noastre dar care din nefericire încă nu a ajuns la un astfel de
nivel.
În momentul de faţă IA conţine numeroase subdomenii de studiu, de la cele generale
care se ocupă cu gândirea logică până la unele particulare cum ar fi jocurile, demonstrarea
unor teoreme matematice, scrierea de poezii sau diagnosticarea unor boli, recunoaşterea
formelor şi procesarea limbajului natural, traduceri automate, reţele neuronale, biometrie şi
algorimi genetici, etc.
Există numeroase definiţii ale inteligenţei artificiale. Formele acestora diferă în funcţie
de punctul de vedere din care este privit domeniul. Unele se axează pe procesele de gândire şi
pe raţionamente, în timp ce altele se axează pe comportamente. De asemenea, unele folosesc
pentru comparaţie inteligenţa umană, în timp ce altele se bazează pe un concept ideal de
inteligenţă. Folosind aceste două criterii, obţinem patru clase de definiţii.
Definiţiile din prima clasă se pot rezuma la sisteme care gândesc ca oamenii. Iată
două dintre aceste definiţii:
încercarea de a construi calculatoare care gândesc în întregul sens al
cuvântului;
automatizarea activităţilor pe care le asociem cu gândirea umană şi anume
luarea deciziilor, rezolvarea problemelor, învăţarea etc.

5
Definiţiile din a doua clasă se pot rezuma la sisteme care gândesc raţional. Două
dintre aceste definiţii sunt:
studiul facultăţilor mintale folosind modele computaţionale;
studiul operaţiilor computaţionale care permit percepţia, raţiunea şi acţiunea.
Definiţiile din a treia clasă se pot rezuma la sisteme care acţionează ca oamenii. Iată şi
acest gen de definiţii:
arta creării maşinilor care efectuează operaţii pentru care este nevoie de
inteligenţă atunci când sunt efectuate de oameni;
construirea unor calculatoare care să efectueze operaţii pe care oamenii le
realizează acum cu mai mult succes.
Definiţiile din a patra clasă se pot rezuma la sisteme care acţionează raţional. Două
dintre aceste definiţii sunt:
un domeniu care încearcă să explice şi să emuleze comportamentul inteligent
în termeni de procese computaţionale;
ramura informaticii care se ocupă cu automatizarea comportamentului
inteligent.
Toate cele patru abordări au fost urmate de cercetători de-a lungul ultimelor decenii.
Normal, există disensiuni între cei care folosesc abordări care se bazează pe inteligenţa umană
şi cei care folosesc abordări care se bazează pe raţiune.
Există şi numeroase alte definiţii:
construirea de algoritmi accesibili (polinomiali) care să reprezinte aproximări
ale unor probleme inaccesibile (pentru care nu există soluţii polinomiale);
construirea unui sistem fizic care să fie capabil să treacă testul Turing;
ramura informaticii care studiază modul în care pot fi create maşini care
acţionează inteligent;
un domeniu care foloseşte tehnici computaţionale pentru a efectua sarcini care,
aparent, necesită inteligenţă atunci când sunt realizate de oameni

1.0.2. Testul Turing


Testul Turing a fost propus de matematicianul englez Alan Turing în anul 1950 şi a
fost creat pentru a obţine o definiţie satisfăcătoare a inteligenţei. Testul Turing constă în
principiu din următorul experiment. Un om comunică prin intermediul unui terminal al
calculatorului cu alte două terminale, situate în camere învecinate, punând întrebări şi
obţinând răspunsuri. Răspunsurile sunt date de o persoană la unul din cele două terminale
ascunse celui de la care se întreabă şi de un program la celălalt terminal. Dacă persoana care
întreabă nu poate stabili în urma dialogului care este terminalul de unde i-a răspuns omul şi
care este cel de la care i-a răspuns programul atunci programul are o comportare inteligentă.
Pentru a putea trece de un astfel de test, un calculator ar trebui să aibă următoarele
caracteristici:
să realizeze procesarea limbajului natural pentru a permite comunicarea într-o
anumită limbă;
să realizeze reprezentarea cunoaşterii pentru a putea păstra informaţii primite
înaintea sau în timpul interogării;
să realizeze raţionarea automată pentru a folosi informaţiile stocate pentru a
răspunde la întrebări şi pentru a trage noi concluzii;
să realizeze învăţarea pentru a se putea adapta la noi circumstanţe şi pentru a
detecta şi extrapola anumite şabloane.
La începutul anilor 90 se spera că reţelele neurale vor oferi o nouă mare posibilitate de
a înţelege inteligenţa biologică, însă acest lucru a fost contrazis de către cercetările ulterioare.
Căutarea IA este subiect de discuţie şi pentru dezbateri care au loc în afara câmpului

6
ştiinţei calculatoarelor. În fizică, de exemplu, au fost descoperite în natură structurile formale,
şi fiecare din aceste sisteme formale pot să fie interpretate ca o maşină naturală. Opinia unor
savanţi că întregul univers este o maşină gigantică vine în complementarea credinţei că
adevărata inteligenţă a maşinilor, precum şi conştiinţa de sine, ar trebui să survină numai după
ce maşina ar atinge un anumit grad de complexitate.
Acest lucru însă conduce la o serie de dificultăţi. Din moment ce maşinile urmează
doar instrucţiuni, nu este credibil faptul că ele ar putea dintr-o dată, pe baza unui mare număr
de legături dintre unităţile de calcul, să fie înzestrate cu conştiinţă de sine. Pe de altă parte,
dacă se concluzionează că maşinile nu vor deveni niciodată conştiente de sine, s-ar putea pune
întrebarea de ce este conştient creierul uman, în timp ce computerul de silicon nu este?
Probabil că răspunsul la această enigmă este faptul că creierul este un sistem care se auto-
organizează şi care răspunde la natura şi la calitatea interacţiunii sale cu mediul, în timp ce
calculatoarele nu o fac. Dar şi alte sisteme ecologice, care sunt comunităţi biologice cu
interacţiuni complexe între componente, se auto-organizează, dar fără să fie conştiente de
sine. Acest fapt sugerează că deşi auto-organizarea este necesară pentru conştiinţă, ea nu este
şi suficientă.

1.0.3. Scurt istoric


Locul oficial al naşterii inteligenţei artificiale este Darthmounth College. Aici, în 1956
a avut loc un simpozion care a durat două luni şi la care au fost invitaţi numeroşi oameni de
ştiinţă care se ocupau cu teoria automatelor, cu studiul reţelelor neuronale sau cu studiul
inteligenţei. Deşi la acea vreme tehnologia informaţiei nu avea o dezvoltare deosebită iar
constucţia sistemelor de calcul era în faza de pionerat concluziile participanţilor la acel
simpozion au fost optimiste şi chiar îndrăzneţe în ceea ce priveşte viitorul sistemelor
inteligente.
Primul program care a fost considerat a se încadra în categoraia programelor de IA a
fost Logic Theorist care era capabil să efectueze raţionamente. Programul a reuşit să
demonstreze o mulţime de teoreme care apăreau în lucrarea de referinţă a lui Isaac Newton
numită Principia Mathematica. Pentru una dintre teoreme, programul a găsit o demonstraţie
mai scurtă chiar decât cea care apărea în lucrarea amintită.
După apariţia programului Logic Theorist a apărut GPS (General Problem Solver).
Acest nou program a fost proiectat în aşa fel încât să simuleze raţionamentele umane efectuate
pentru rezolvarea unei probleme. S-a observat că acest program rezolvă subproblemele care
apăreau într-o ordine similară cu cea pe care o folosesc oamenii. Se poate spune că GPS a fost
primul program care a folosit abordarea gândirii umane a inteligenţei artificiale.
Perioada anilor 1970-1990 a fost caracterizată de preocuparea cercetătorilor din
domeniu de a pune bazele teoretice şi practice ale majorităţii subdomeniilor inteligenţei
artificiale, de a proiecta şi implementate limbaje de programare specifice domeniului (LISP
bazat în principal pe procesarea listelor al cărui autor este matematicianul american Winston,
PROLOG – autor francezul Colleman – apărut ca o necesitate de apropiere de programarea
logică dar şi ca un orgoliu al europenilor de a scoate un limbaj diferit de cel al americanilor,
CLIPS – elaborat de NASA pentru proiectarea sistemelor expert, etc.) şi de asemenea de a
scoate pe piaţă produse specifice (sisteme expert, programe “inteligente” pentru rezolvarea
unor jocuri, etc.). Tot în această perioadă Inteligenţa artificială a apărut ca disciplină de
studiu în toate mediile universitare cu preocupări în domeniul ştiinţei calculatoarelor.
Şi la noi în ţară au existat preocupări timpuri în domeniu atât în mediile universitare
cât şi în institute de cercetare în domeniul informaticii. Este de menţionat aici UPB - prin
academicianul Mihai Dragănescu (cu o serie de lucrări în domeniu), prin profesorul Cristian
Giumale (care în perioada menţionată şi-a pregătit şi susţinut doctoratul în Anglia în domeniul
inteligenţei artificiale după care reîntors în ţară a susţinut o serie de cursuri în domeniu la

7
secţia de calculatoare a UPB şi a publicat o serie de materiale specifice domeniului), Institutul
Central de Informatică (prin actualul academician Filip – preşedintele secţiei de Inteligenţă
artificială din Academia Română - şi cercetătorul Ioan Georgescu cu o primă carte în limba
română de inteligenţă artificială), Universitatea Bucureşti (prin preocupările academicianului
Mircea Maliţa şi a altor cadre didactice) şi alte instituţii de învăţământ superior şi de cercetare
din ţară.
Perioada anilor de după 1990 a însemnat o “explozie” a preocupărilor şi produselor
“inteligente”, de apariţie a unei vaste bibliografii, de înfiinţare a unor firme de profil şi a unor
institute şi asociaţii profesionale. Evident că această explozie a fost facilitată şi de dezvoltarea
fără precedent a tehnologiei informaţieia, a produselor soft şi hard, de apariţi a internetului.

1.0.4. Domenii de interes şi de cercetare pentru IA


Iată câteva zone ştiinţifice şi de cercetare asupra cărora s-au concertat preocupările
cercetătorilor din domeniul inteligenţei artificiale:
vedere artificială – ce presupune cunoaşterea formelor, identic cu vederea
umană;
robotica – focalizează producerea dispozitivelor mecanice capabile să
reproducă mişcarea;
prelucrarea vocii – ce priveşte constituirea şi sinteza vocii umane;
prelucrarea în limbaj natural – înţelegerea şi vorbirea în limbaj natural;
demonstrarea teoremelor – în matematică şi logică;
“General Problem Solving” – rezolvarea unei clase generale de probleme
exprimate în limbaje formale;
recunoaşterea formelor – rezolvarea şi clasificarea diferitelor forme;
teoria jocurilor;
învăţarea automată – maşini ce acumulează cunoştinţe prin observarea
exemplelor ;
sisteme expert;
data mining:
biometrie;
reţele neuronale;
algoritmi genetici.

1.0.5. Fundamentele matematice.Domeniile principale de studiu şi de aplicabilitate


ale IA.
IA se bazează pe o puternică construcţie matematică prin folosirea unor diverse
discipline ale acesteia:
- logica matematică (calculul propoziţional, calculul cu predicate, teoria inferenţelor
logice);
- teoria probabilităţilor (cu utilizare în mod deosebit în reprezentarea cunoaşterii
incerte spre exemplu în reţelele Bayesiene care modelează incertitudinea prin
reprezentarea explicită a dependenţelor condiţionale între diferite componente);
- teoria algorimilor (algoritmi de căutare, algoritmi de control, etc.)
- teoria reţelelor neuronale (cu aplicabilitate în recunoaşterea formelor, a sintezei
vorbirii, etc.);
- lingvistica matematică (pentru înţelegerea limbajului natural, a traducerilor
automate, etc.);
- teoria grafurilor (prin posibilitatea reprezentării cunoştinţelor cu ajutorul arborilor)
Principalele domenii de studiu ale IA sunt:
- reprezentarea cunoaşterii şi modalitatea de acces la aceasta

8
- rezolvarea problemelor
- strategii şi metode de căutare în spaţiul stărilor
- metode şi algoritmi de inferenţă

1.0.6. Limbaje de programare specifice domeniului


Dezvoltarea aplicaţiilor din domeniul IA a condus în mod firesc la apariţia unor medii
de programare specifice domeniului. În general aceste medii au apărut şi sau dezvoltat în
primul rând pentru a se găsii o modalitate de reprezentare a cunoaşterii dar şi ca o necesitate
de a transpune în programe de calcul aplicaţii specifice IA.
Dintre aceste medii de programare menţionăm ca cele mai relevante din punct de
vedere al utilizării lor LISP, PROLOG şi CLIPS.
Limbajul LISP este un limbaj de programare funcţional cu un lung istoric. . Conceput
iniţial ca un model de calcul (asemănător celui construit de Turing), a devenit limbajul cel mai
folosit la crearea aplicaţiilor de inteligenţă artificială în anii de glorie ai acestui domeniu
(1970-1980). Denumirea provine de la "LISt Processing". Specificat iniţial în 1958, LISP este
cel de-al doilea ca vechime limbaj de programare de nivel înalt; doar FORTRAN este mai
vechi. Precum FORTRAN, LISP s-a schimbat mult faţă de forma iniţială,existând de-a lungul
vremii o serie de dialecte. Astăzi, cele mai răspândite dialecte LISP sunt COMMON LISP şi
SCHEME. A fost inventat de către John McCarthy în 1958 la MIT. Steve Russell a
implementat primul LISP pe un calculator IBM 704. LISP a fost conceput ca o necesitate de
procesare a listelor, lista fiind o primă formă de reprezentare a cunoaşterii acceptată de
comunitatea IA. Se caracterizează prin faptul că este dotat cu foarte multe funcţii care rezolvă
majoritatea operaţiilor legate de liste, dar nu numai, şi este şi uşor de înţeles de către
programatori.El s-a aplicat cu succes şi se mai aplică şi în prezent în special în SUA.
Limbajul PROLOG (PROgramming in LOGic) a apărut şi ca o necesitate a
prelucrării informaţiilor furnizate de reprezentarea cunoaşterii prin intermediul instrumentelor
puse la dispoziţie de logica matematică (limbajul calcului cu predicate, teoria inferebnţelor
logice, etc.) dar şi ca o contrapondere a cercetătorilor europeni faţă de cei americani. A fost
conceput de profesorul francez Alain Calmaureur de la Universitatea din Marsilia, Franţa şi
folosit cu succes în Europa şi Japonia, dar nu numai. Iniţial a fost conceput pentru analiza
lexicală. Azi în mod curent există mai multe implementări atât open source cât şi proprietare.
Printre cele mai bune implementari existente azi se numără SWI-PRO, VISUAL PROLOG şi
altele.
CLIPS a fost conceput de NASA pentru asistarea programatorilor în proiectarea,
implementarea, utilizarea şi punerea la zi a sistemelor expert. Este un limbaj modular, uşor de
aplicat şi utilizat. CLIPS este un sistem expert. CLIPS este un acronim pentru C Language
Integrated Production System. Sintaxa şi numele au fost inspirate de OPS (sistem de
producţie oficial - Official Production System, în eng.) creat de Charles Forgy. Primele
versiuni de CLIPS au fost dezvoltate începând cu 1984 la NASA-Johnson Space Center (ca o
alternativă la sistemul existent numit ART*Inference) până la începutul anilor 1990 când
subvenţia a încetat din cauza problemelor bugetului Federal, şi a unui ordin conform căruia
NASA trebuia să cumpere software comercial în loc să-l dezvolte.

1.1. Reprezentarea cunoaşterii

1.1.0. Introducere.
Reprezentarea cunoştinţelor într–un calculator constă în găsirea unei corespondenţe
între lumea exterioară şi sistemul simbolic ce permite execuţia raţionamentelor.
În transpunerea de la subiecţii umani la subiecţii cunoscători de tip „program pentru
calculator“ deci de la psihologia gândirii la inteligenţa artificială, conceptul de cunoaştere îşi

9
conservă calităţile, în sensul că, în vederea utilizării unui program cunoaşterea este memorată
sub forma unor piese de cunoaştere ce descriu fapte, fenomene, procese, evenimente dintr–o
parte a lumii reale ce constituie domeniul de competenţă al programului inteligent. Piesele de
cunoaştere alcătuiesc un model al lumii la care programul are acces prin intermediul
procedurilor de organizare, clasificare, căutare şi recunoaştere.
Se poate defini un sistem cognitiv ca totalitatea pieselor de cunoaştere, a modului de
stocare şi a procedurilor de acces la acestea.
Problema fundamentală a inteligenţei artificiale este cea de definire a unor metode
pentru reprezentarea unei mari cantităţi de cunoştinţe într–o formă ce permite stocarea şi
utilizarea eficientă a acestora.
Reprezentarea cunoaşterii poate fi conform celor de mai sus considerată ca o relaţie de
definiţie A B ce stabileşte o legătură între un simbol identificator A (numele entităţii
reprezentate) şi o expresie B formulată în limbajul de reprezentare al sistemului, ce descrie
caracteristicile entităţii şi structura sa cu ajutorul unor termeni primari, termeni purtători de
semnificaţie ai limbajului. Expresia B este o reprezentare a entităţii A sau a piesei de
cunoaştere A în sistemul cognitiv considerat ca gazdă a reprezentării cunoaşterii.
Unul din conceptele de bază de reprezentare a cunoştinţelor este cel de entitate. O
entitate este un obiect al lumii reale, cu o existenţă independentă. O entitate este un obiect cu
existenţă fizică: persoană particulară, automobil, companie, activitate, curs universitar, etc.
Orice entitate are o serie de proprietăţi numite atribute ce particularizează entitatea respectivă.
De exemplu, pentru o entitate automobil se pot enumera o serie de atribute cum sunt marca,
combustibilul utilizat, capacitatea cilindrică etc. Valorile acestor atribute au ca scop
identificarea entităţii.
Unele atribute pot fi împărţite în părţi mai mici cu semnificaţie independentă. Un
astfel de atribut este un atribut complex. Un exemplu este cel al atributului adresa, ce poate fi
subdivizat în atributele componente Oraş, Judeţ, Cod poştal, Stradă. La rândul său atributul
Stradă este definit prin atributele Nume stradă, Număr, Scară, Număr apartament.
Atributele ce nu sunt compuse se numesc atomice. Valoarea atributelor compuse se
formează prin compunerea valorilor atributelor atomice.
Multe atribute au o valoare unică pentru o entitate particulară şi sunt numite atribute
cu o singură valoare. Spre exemplu, vârsta unei persoane. Există atribute ce pot lua mai multe
valori, spre exemplu, culoarea unui automobil. Fiecare atribut al unei entităţi tip are asociat un
set de valori V, numit şi domeniu, ce specifică valorile posibile pe care le poate lua.
Matematic, atributul A al entităţii tip E poate fi definit ca o funcţie de la E la mulţimea
valorilor posibile ale lui V, sau la toate submulţimile lui V.
A: E (V)
(prin (V) s-a notat mulţimea părţilor lui V).
Valoarea atributului A pentru entitatea (e), se va nota A(e). Pentru un atribut simplu
A(e) este o valoare cu un singur element, un atribut nul nu are valoare sau altfel spus are
valoarea null. Pentru un atribut compus A mulţimea de valori este formată ca produsul
cartezian dintre (V1), (V2), …, (Vn) unde V1, V2, …,Vn reprezintă mulţimea valorilor unei
componente simple a lui A, deci
(V) = (V1) × (V2)× …× (Vn).
Între entităţi se pot stabili o serie de relaţii ce pot avea la rândul lor atribute ce le
caracterizează denumite atribute relaţie.
Pentru aplicaţiile de inteligenţă artificială se pot distinge următoarele clase de metode
de reprezentare:
a) metode logice – sunt acele metode ce privesc cunoaşterea ca o serie de aserţiuni
(enunţuri adevărate) privind cunoştinţele şi relaţiile dintre ele. Metoda permite
10
folosirea regulilor de inferenţă direct asupra pieselor de cunoaştere din baza de
cunoştinţe. Are însă dezavantaje prin soluţiile nesatisfăcătoare de sistematizare a
bazei de cunoştinţe, prin inadecvanţa reprezentării cunoaşterii despre acţiuni,
precum şi a reprezentării regulilor euristice;
b) metode relaţionale – sunt metodele prin care cunoaşterea este reprezentată pornind
de la relaţiile dintre obiecte sub formă de grafuri şi reţele. Ele permit organizarea
cunoştinţelor funcţie de omogenitatea acestora ce conduc la clase şi sorturi.
c) metode procedurale – în care cunoaşterea este reprezentată sub formă de proceduri
ce permit obţinerea stărilor la momentele specificate pornind de la stările iniţiale
sau intermediare.
Descrierea formală a unui concept în termenii limbajului de reprezentare, prin care se
diferenţiază de alte concepte sau prin care se poate aprecia echivalenţa cu alte concepte
similare poartă numele de definiţie. Definiţia are ca obiectivitate modelarea obiectelor şi a
relaţiilor dintre ele astfel încât să fie specificate caracteristicile esenţiale ale acestora cât şi
posibilitatea de a facilita operaţiile în care obiectele şi relaţiile sunt frecvent implicate. Este
normal ca pentru un concept să poată fi date mai multe definiţii, fiecare definiţie fiind o
descriere parţială dependentă de perspectiva din care este privită.
Altă informaţie privind un concept este dată de relaţiile acestuia cu entităţi de tip
acţiune. În general un obiect poate să ocupe în cadrul unei acţiuni poziţia de argument, deci
asupra căruia se acţionează cât şi poziţia de rezultat al acţiunii.
Se va numi generalizare a unui concept (C) o definiţie mai puţin restrictivă a acestuia
(D), în care orice instanţă a conceptului (C) este şi o instanţă conceptului (D), concept mai
general. O serie de proprietăţi sunt exprimate printr–un predicat P(x, C, D) în care (x) este o
instanţă de concept, care dacă satisface şi predicatul pentru generalizare va satisface şi
definiţia conceptului C.
DEF(x, D) P(x, D, C) DEF(x, C)
în care, DEF(x, y) este un predicat ce semnifică faptul că (x) satisface definiţia.
Pornind de la aceste observaţii o structură de concepte poate fi reprezentată
arborescent, înaintarea spre frunză reprezentând o specializare, pe când apropierea de rădăcină
o generalizare a conceptului.

1.1.1. Reprezentarea cunoaşterii în limbajul calculului cu predicate de ordinul I


Metoda de reprezentare a cunoaşterii în limbajul calculului cu predicate de ordinul
întâi descrie piesele de cunoaştere cu ajutorul unor expresii, ale căror constituente sunt
formule ale acestui limbaj.
Avantajele oferite de această modalitate de reprezentare:
– piesele de cunoaştere pot fi introduse direct în sistemul rezolutiv pentru a putea fi
folosite la efectuarea de inferenţe.
– condiţia ca sistemul să fie conceput pe baza unor mecanisme inferenţiale definite
în limbajul calculului cu predicate de ordinul întâi.
Dezavantajul apare în practică, unde utilizarea acestei modalităţi se dovedeşte dificilă,
presupunând o anumită experienţă privind captarea trăsăturilor ale pieselor de cunoaştere în
predicate.
La baza metodei de cunoaştere stă caracteristica de funcţie propoziţională a
predicatului. De aceea, descrierea unor piese de cunoaştere este descompusă în propoziţii
elementare adevărate, numite aserţiuni, care specifică fapte (proprietăţi, relaţii) legate de
piesa de cunoaştere rezultând astfel reprezentarea propoziţională.
Fiecare propoziţie elementară este generată de un predicat cu un număr finit de
argumente, în care sunt specificate variabile formale sau obiective din mulţimea suport,
rezultând reprezentarea predicativă.

11
1.1.1.1. Reprezentarea propoziţională
Exemplu: Să considerăm următoarea descriere (incompletă) în limbajul natural a
piesei de cunoaştere „avionul xyz“.
„Avionul xyz este compus dintr–un fuselaj, aripă, sistem de propulsie, sistemul de
comandă şi sistemul de rulare. Avionul zboară dacă viteza relativă de deplasare faţă de
curentul de aer este mai mare decât 180 km/h. Motorul funcţionează dacă are combustibil în
rezervor iar contactul de pornire este închis.“
Se disting următoarele fraze ce sunt propoziţii elementare:

I. A1 = avionul xyz
II. A2 = avionul zboară
A3 = viteza relativă de deplasare faţă de curentul de aer este mai mare decât
180 km/h
III. A4 = motorul funcţionează
A5 = are combustibil în rezervor
A6 = contactul de pornire este închis

Presupunem că nu cunoaştem alte fapte despre acest avion. Atunci cunoaşterea despre
acest obiect este dată de următoarele formule ale calculului propoziţional:

i) A1
ii) A3 A2
iii) (A5 A6) A4

Reprezentarea nu cuprinde o serie de detalii date în descrierea iniţială, deoarece aceste


detalii nu sunt propoziţii ci componente ale acestora.

1.1.1.2. Reprezentarea predicativă.


Pentru a surprinde semnificaţia componentelor fiecărei propoziţii vom trece la faza de
reprezentare predicativă prin efectuarea unei analize care se bazează pe următoarele
observaţii:
– orice propoziţie are structura gramaticală de forma subiect–predicat sau analog
grup nominal–grup predicativ;
– se poate considera grupul predicativ ca având semnificaţia abstractizată printr–un
simbol de predicat, în ale cărui locuri sunt plasate obiectele din grupul nominal;
– unele componente ale propoziţiei au rolul de a modifica valoarea de adevăr în
funcţie de acoperirea domeniului în care variabilele iau valori.

Analiza aserţiunilor
A1 – Grupul predicativ determină un predicat de tipul ESTE–COMPUS având ca
număr de locuri, numărul de obiecte din grupul nominal, în acest caz de 6 locuri;
– Prin convenţie, primul loc este ocupat de obiectul compus, iar următoarele locuri
vor fi ocupate de componentele sale.

ESTE–COMPUS (AVION–XYZ, FUSELAJ, ARIPA, SISTEM–PROPULSIE, SISTEM–


COMANDĂ, SISTEM–RULARE)

Dezavantajele acestei forme sunt:

12
– la efectuarea raţionamentelor rareori se tratează simultan toate componentele, cele
mai frecvente situaţii sunt cele care implică o singură componentă;
– numărul de predicate fiind prestabilit, eventuala rafinare ulterioară a cunoaşterii ar
adăuga noi componente, care vor implica redefinirea predicatului, mărindu–i
unitatea la un număr de locuri (argumente) corespunzător noii descrieri.

Pentru evitarea acestor dezavantaje se reformulează aserţiunea:

A1 : (fuselajul este component al avionului xyz)


(aripa este componentă a avionului xyz)
(sistemul de propulsie este component al avionului xyz)
(sistemul de comandă este component al avionului xyz)
(sistemul de rulare este component al avionului xyz).

Noul grup predicativ determină un predicat cu două locuri:

(1) ESTE–COMPONENT (AVION–XYZ, FUSELAJ)


(2) ESTE–COMPONENT (AVION–XYZ, ARIPA)
(3) ESTE–COMPONENT (AVION–XYZ, SISTEM–PROPULSIE)
(4) ESTE–COMPONENT (AVION–XYZ, SISTEM–COMANDĂ)
(5) ESTE–COMPONENT (AVION–XYZ, SISTEM–RULARE)

Orice instanţă ulterioară a cunoaşterii despre componentele care intră în alcătuirea


avionului se prezintă prin noi instanţe ale aceleiaşi expresii predicative, cum ar fi:

ESTE–COMPONENT (AVION–XYZ, SISTEM–RADIO)

camp predicativ " zboara "


A2 : ZBOARA(nume _ obiect )
camp nominal 1 singur loc

Instanţa variabilei formale care se regăseşte în A2 face adevărat predicatul care reflectă
aserţiunea

(6) ZBOARĂ (AVION–XYZ)

A3 : Predicatul definit de grupul predicativ, având semnificaţia “este mai mare“, va


avea două locuri corespunzătoare celor două variabile formale ale relaţiei x y care este de
fapt reprezentată prin aserţiunea A3.

MAI–MARE (x, y) instanţele pentru variabilele formale x şi y.

(7) MAI–MARE (VITEZA–AVION, 180)

Predicat : FUNCTIONEAZA(X )
A4 :
Subiect : MOTOR

(8) FUNCTIONEAZA( MOTOR )

13
A5 : Predicatul are două locuri: ARE (recipient, conţinut)

(9) ARE (REZERVOR, COMBUSTIBIL)

A6 : ÎNCHIS (contact–electric)

(10) ÎNCHIS (CONTACT–PORNIRE)

În acest fel relaţiile i – iii devin:

(i) ESTE–COMPONENT (AVION–XYZ, FUSELAJ)


ESTE–COMPONENT (AVION–XYZ, ARIPA)
ESTE–COMPONENT (AVION–XYZ, SISTEM– PROPULSIE)
ESTE–COMPONENT (AVION–XYZ, SISTEM– COMANDĂ)
ESTE–COMPONENT (AVION–XYZ, SISTEM– RULARE)

(ii) MAI–MARE (VITEZA–AVION, 180) ZBOARĂ (AVION–XYZ)

(iii) (ARE (REZERVOR, COMBUSTIBIL) (ÎNCHIS (CONTACT–PORNIRE))


FUNCŢIONEAZĂ ( MOTOR)

Rezultă de mai sus că:


– avionul este un concept generic care se instanţiază în obiecte individuale ca XYZ,
IAR–213, AIRBUS, …etc, şi „orice avion are un fuselaj“, ş.a.m.d.
– avion este o caracteristică a obiectului respectiv pe care o exprimăm printr–un
predicat, fie acesta AVION (X).
Exemplu: AVION (XYZ), AVION (IAR-213), … etc.
Dar numărul avioanelor reale este foarte mare şi a scrie pentru fiecare în parte că are
un fuselaj nu reprezintă o soluţie convenabilă. Vom evita acest inconvenient prin cuantificare
universală.
Utilizarea cuantificatorilor este legată de transcrierea în calculul cu predicate de
ordinul întâi a unor propoziţii în care aceşti cuantificatori acţionează ca operatori unari asupra
variabilelor pe care le prefixează.
Aşadar cunoaşterea despre avion poate fi exprimată printr–o singură formulă,
adevărată pentru oricare element al mulţimii avioanelor.

(1 ) ( )x AVION (x) ARE (x, FUSELAJ)


(2 ) ( )x AVION (x) ARE (x, ARIPA)
(3 ) ( )x AVION (x) ARE (x, SISTEM–PROPULSIE)
(4 ) ( )x AVION (x) ARE (x, SISTEM–COMANDĂ)
(5 ) ( )x AVION (x) ARE (x, SISTEM–RULARE)

Dacă considerăm că toate obiectele fizice nu sunt individuale, ci concepte generice


atunci se vor înlocui obiectele FUSELAJ, ARIPA, etc, cu variabile simbolice iar caracteristica
de a fi fuselaj, aripa, etc., se ve specifica prin predicate. Vom defini deci alte expresii
predicative primare care să caracterizeze proprietăţile conceptului:

(1 ) ( )x AVION (x) ESTE–ELEMENT (x, F)

14
unde F este o notaţie: mulţimea de descrieri de fuselaje, diferite ca formă şi caracteristici.
Predicatul ESTE–ELEMENT folosit, semnifică apartenenţa obiectului ataşat variabilei
formale x la mulţimea de fuselaje F.
Rezultă deci definiţia simbolului unar: FUSELAJ : x F şi atunci

(1 ) ( )x AVION (x) ARE (x, FUSELAJ(x))

Puterea de reprezentare a cunoaşterii, pe care o au formulele limbajului calculului


propoziţional de ordinul I se poate cel mai bine aprecia prin considerarea unor exemple
complexe de la sfîrşitul acestui modul în care este folosită şi forma clauzală care reprezintă un
concept nou numit programare logică, care stă la baza limbajului de programare PROLOG.

1.1.2. Metode procedurale de reprezentare a cunoşterii


Acest mod de reprezentare a apărut ca o consecinţă a modului de reprezentare prin
programe de calcul a pieselor de cunoaştere cu ajutorul unor algoritmi.
Reprezentarea cunoaşterii asupra acestor entităţi utilizănd limbajul calculului cu
predicate de ordinul I are dificultăţi datorate caracterului declarativ al metodei, caracter ce nu
corespunde cu natura procedurală a pieselor de cunoaştere.
Metodele procedurale se bazează pe aspectele dinamic ale cunoaşterii asupra modului
de folosire a pieselor de cunoaştere pentru efectuarea inferenţelor, asupra determinării de noi
fapte prin executarea unor noi operaţii asupra pieselor de cunoaştere.
Realizarea prin aceste metode este realizată în termenii unor simboluri prin care se
identifică proceduri (care sunt evaluate de procesoarele interpretative ale limbajelor de nivel
înalt, spre exemplu LIPS) sau chiar programe de calcul (evaluate direct de procesorul
calculatorului electronic).
Să considerăm următoarea reprezentare declarativă a unei probleme cu pinguin:

„Pinguinul are aripi, pene dar nu zboară ci înoată“.

Reprezentarea procedurală ar putea arăta astfel:

PENTRU–A–STABILI PINGUIN (x)


DECLARĂ–PREDICATE (x)
DOVEDEŞTE–PASĂRE (x)
DOVEDEŞTE NU ZBOARĂ (x)
DOVEDEŞTE ÎNOATĂ (x).

În această piesă de cunoaştere simbolurile PENTRU–A–STABILI, DECLARĂ şi


DOVEDEŞTE sunt identificatori de proceduri,cu următoarea semnificaţie:

– PENTRU–A–STABILI _ procedură de determinare a apartenenţei unui obiect la o


clasă.
– DECLARA _ procedură de înscriere sub formă de predicate a proprietăţilor obiectului
x
– DOVEDEŞTE _ procedură de determinare a valorii unui atribut al unei piese de
cunoaştere.

Prima procedură le foloseşte pe celelalte drept componente în corpul reprezentării


procedurale a cunoaşterii. Ordinea de parcurgere este cea specificată, efectul fiind că pentru a
arăta că x este pinguin, este necesar mai întâi să se descrie piesa de cunoaştere x prin

15
intermediul predicatelor ce îi stabileşte proprietăţile, apoi se apelează procedura de
determinare a valorii atributelor lui x.
Pentru folosirea reciprocei piesei de cunoaştere, adică dacă se dau faptele: x este
pasăre, nu zboară, înoată, atunci se defineşte o nouă piesă de cunoaştere în reprezentare
procedurală cu următorul conţinut:

OBIECTIV SPECIE (x)


DECLARĂ PREDICATE (x);
ANALIZEAZĂ CLASA (x);
DACĂ PASĂRE (x) ATUNCI
DACĂ NU–ZBOARĂ (x) ATUNCI
DACĂ ÎNOATĂ (x) ATUNCI
REZULTĂ SPECIE (x) = PINGUIN;
ALTFEL APLICĂ PROCEDURA „CLASIFICARE
PĂSĂRI NEZBURĂTORE“
ALTFEL APLICĂ PROCEDURA „CLASIFICARE PĂSĂRI
ZBURĂTOARE“
ALTFEL APLICĂ PROCEDURA „CLASIFICARE ALTE CLASE“.

Într–o reprezentare procedurală se folosesc două operaţii primitive:


– operaţii asupra memoriei: înscriere, ştergere, extragere, căutare, corespondenţă,
modificare;
– operaţii care returnează valori ale unor funcţii, sau valori de adevăr unor predicate.
Reprezentarea procedurală este dependentă de tipul problemei ce se rezolvă cu piesele
de cunoaştere reprezentate. În măsura în care cunoaşterea devine tot mai complexă, piesele de
cunoaştere devin tot mai numeroase.
Avantajele metodei sunt:
– uşurinţa de a specifica şi aplica regulile existente, specifice domeniului de
competenţă aplicativă ales pentru programele inteligente;
– interpretarea cunoaşterii este este directă rezultând performanţe de timp foarte
bune.
Dezavantajele metodei:
– lipsa de flexibilitate în utilizarea pieselor de cunoaştere pentru efectuarea altor
inferenţe decât cele specificate explicit prin procedurile aferente.

1.1.3. Reprezentarea cunoşterii prin reguli de producţie


Acest mod de reprezentare a cunoaşterii este unul dintre cele mai utilizate în sisteme
expert. Metoda se bazează pe separarea componentelor obişnuite ale calculului, în scopul
manipulării uşoare în procesele la care sunt utilizate. Cunoaşterea în reţelele de producţie este
de natură procedurală şi pot fi definite următoarele componente:
– cunoaştere declarativă sau factuală – ce reprezintă piese de cunoaştere stocate
sub forma unor structuri de date într–o colecţie numită şi context;
– cunoaştere procedurală – reprezentată sub forma unei colecţii de tip condiţie –
acţiune numite şi reguli de producţie, colecţie ce formează baza de reguli;
– cunoaşterea strategică sau de control – formată din reguli ce privesc secvenţele
de acţiuni în procesul de rezolvare.
Sistemul construit în jurul regulilor de producţie se bazează pe structura specifică
compusă din cele două părţi <partea de premisă> <partea de acţiune>. Într–o altă
exprimare, un sistem de producţie este compus dintr–o bază de date şi un set de reguli.
Condiţiile unei reguli pot fi considerate ca o bază de date, ce returnează un indicator de succes

16
sau eroare. Concluzia unei reguli este o acţiune ce manipulează date din baza de date şi în
plus, un control al sistemului determină secvenţa regulilor utilizate.
În descriere generală se poate menţiona faptul că sistemele de producţie sunt similare
gramaticilor şi apar chiar în definiţia gramaticilor Chomsky.
Astfel G = (V, , P, S) este o gramatică de structură a frazei, unde:
– V – reprezintă un set finit de simboluri numit adesea şi alfabet total;
– V reprezintă un set finit de simboluri ale alfabetului numite simboluri
terminale sau, simplu, terminale;
– P – o submulţime a produsului cartezian (V– –S) V. Elementele lui P, deci
perechile ordonate (u, w), se mai scriu în mod obişnuit sub forma u w şi sunt
numite producţii sau reguli de rescriere;
– (S) – un simbol iniţial sau simbol de start.

În concluzie, un sistem de producţie R poate fi considerat un dublet R= (D, P), în care:


D – este o bază de date;
P – un set finit de reguli.
Baza de date este constituită dintr–un set de termeni, iar o regulă are forma generală
IF c THEN t, în care condiţia c este constituită din termeni, paranteze, conective , , , iar
concluzia t, este formată dintr–un singur termen. Termenii sunt constituiţi din parametrii
x P(R) şi din valori a V(R). Se presupune că P(R) şi V(R) sunt mulţimi finite şi
P(R) V(R)= .
Sintaxa x = a, respectiv x a cu x P(R) şi a V(R) va trebui interpretată că x este
mărginit de a şi respectiv că x nu este mărginit de a. Un termen t este adevărat pentru baza de
date D dacă şi numai dacă t D (reamintim că „ “ este functonul lui Sheffer, sau
nonconjuncţia, o expresie A B,semnifica că A şi B nu sunt ambele adevărate). Succesul sau
eşecul unui termen arbitrar în condiţia c este redus la succesul sau eşecul termenilor
componenţi.
Structura generală a unei reguli de producţie este următoarea:

< partea condiţie> <partea acţiune>

având interpretarea:

IF <partea condiţie> este îndeplinită,


THEN se execută <partea acţiune>

sau în forma mai generală:

IF < partea condiţie> este îndeplinită,


THEN se execută <partea acţiune_1>
ELSE se execută < partea acţiune_2>.

Dacă într–o regulă condiţia este satisfăcută, se spune că regula este selectată pentru
declanşare sau regula este aplicabilă. Regulile aplicabile intră într–o mulţime a regulilor
aplicabile, mulţime din care este selectată regula cu cea mai mare prioritate după diverse
criterii. Mecanismul regulilor de producţie este împrumutat din teoria limbajelor formale, este
de natură procedurală şi poate cel mai apropiat de modul de realizare a programelor clasice.
Mecanismul interpretativ al regulilor de producţie conţine următorii paşi:

17
– selectarea tuturor regulilor ce conţin piese de cunoaştere ce satisfac partea de
condiţie numită şi corespondentă. Mulţimea acestor reguli formează mulţimea
candidată, denumire ce are originea în faptul că elementele acestei mulţimi intră
într–o competiţie în urma căreia se decide care regulă este efectiv aplicată.
– Rezolvarea conflictelor prin care din mulţimea regulilor aplicabile se elimină mai
întâi regulile care duc la aceleaşi rezultate, după care în conjuncţie cu
mecanismulde asertare a priorităţii pentru problema respectivă se selectează regula
ce va fi aplicată;
– Execuţia părţii acţiune a regulii cu cea mai mare prioritate, în situaţia în care sunt
producţii aplicabile;
– Pornind de la contextul modificat în urma aplicării regulilor anterioare se reia ciclu
începând cu faza de corespondenţă, atâta timp cât ciclul produce acţiuni
materializate prin modificarea contextului.
Oprirea mecanismului interpretativ poate avea loc dacă acţiunea unei producţii
specifică concret oprirea, sau se selectează o producţie vidă.
Concluzionând, putem da următoarea definiţie:
Un sistem de producţie este un cvintuplu:
SP = ( K, P, , , pS)
în care:
K – reprezintă contextul ca o mulţime de piese de cunoaştere factuală recunoscute de
celelalte componente ale sistemului;
P – baza de reguli ca mulţime finită de reguli de producţie;
– funcţia succesor la îndeplinirea cu succes a condiţiei;
:P P { };
– funcţia succesor în caz de eşec a condiţiei,
: P P { };
pS – regula de producţie iniţială de la care porneşte procesul de selectare a regulilor.
S–a notat cu producţia vidă.

Întrucât partea_condiţie şi partea_acţiune sunt forme complexe ce conţin mai multe


condiţii şi mai multe acţiuni forma cea mai generală a unei reguli de producţie este:
p=(c1 c2 ci) (a1; a2; ... ;ap)
în care cj, 1 j i sunt condiţiile şi ak , 1 k p sunt acţiunile.

Pentru ca o producţie (p) să fie selectată, ţinând cont de conectiva logică dintre
condiţiile cj , este necesar ca în context să existe piese de cunoaştere ce satisfac toate aceste
condiţii. Dacă regula este selectată atunci acţiunile ak , 1 k p sunt executate.
Controlul sistemelor de producţie este specificat complet de cele trei componente ale
sale şi pS putându-se furniza strategii de control adecvate.
O metodă de strategie de control este inspirată din algoritmi normali Markov:
K = { k1, k2,..., kn }
P = { p1, p2,..., pm }
(pi) = p1 , 1 i n
(pi) = pi+1 , 1 i n-1
(pn) =
pS=p1.
Conform acestei strategii sistemul cercetează condiţiile din context începând cu prima
regulă, iar la întâlnirea primei reguli aplicabile o aplică după care comută controlul de regulă
p1 cu noul context. În situaţia de succes controlul este comutat la regula pi+1 realizând astfel o
18
explorare succesivă. În condiţiile în care nici o regula nu este aplicabila se selectează,
conform funcţiei succesor la eşec, producţia vidă.
O metodă des întâlnită este şi cea utilizată în sistemul expert EXSYS, prin care se
alege din mulţimea candidată producţia cu cel mai mare câştig informaţional. Logica de mai
sus se bazează pe faptul că o astfel de regulă conţine mai multă informaţie, fapt ce va
determina atingerea mai repede a obiectivului.

1.1.4. Reţele semantice


Acest mod de reprezentare a apărut ca o consecinţă a modului de surprindere a
structurilor relaţionale de mare complexitate. Aspectul de graf al reprezentării constituie doar
o variantă de evoluţie pentru caracteristicile puse în relief prin reprezentarea cunoaşterii cu
predicate de ordinul întâi.
Elementele primitive constituente ale unei reţele semantice sunt:
- noduri - reprezentând abstractizări structurate pentru concepte, evenimente, stări, alte
obiecte suport;
- arce (legături) - reprezentând abstractizări ale relaţiilor propriu-zise.
Primitivele de acest fel sunt utilizate în limbajele de nivel înalt ce se folosesc, pentru
reprezentarea structurilor de date, de spaţii de memorie numite şi celule, legate între ele prin
pointeri (de exemplu LISP). Simbolurile şi valorile asociate structurilor de date permit
exprimarea unor semnificaţii şi apropierea de cerinţele sistemelor de reprezentarea
cunoaşterii.
Modelul de reprezentare prin “reţele semantice” a fost propus în 1966 de Ross
Quillian. Denumirea se explică prin faptul că reproduce din punct de vedere conceptual
structura semantică a dicţionarelor explicative, cele două componente fiind:
- noduri - concepte reprezentate prin cuvinte;
- arce - relaţii cu alte concepte.
Se poate utiliza noţiunea de “limbajul unei reţele” ce exprimă concepte, evenimente,
stări, episoade şi relaţii între acestea. Pentru limbajul unei reţele se utilizează o serie de
simboluri care sunt înţelese de interpretorul reţelei, simboluri ce formează primitivele
semantice.
Combinarea primitivelor conform regulilor limbajului determină expresii.
Descrierea este făcută prin obiecte formale intensionale denumite şi concepte cât şi
prin obiecte extensionale denumite instanţe. Relaţia între obiecte şi instanţă este denumită şi
instanţiere sau denotare şi are caracter extensional pe când relaţia între instanţe şi concepte
denumită şi conceptualizare are un caracter intensional.

CONCEPT
X

INSTANŢIERE CONCEPTUALIZARE
(extensiune) (intensiune)

INSTANŢA
W

19
O instanţă poate reprezenta un obiect din lumea reală sau un alt concept. Atunci când
instanţa este un concept poate avea la rândul său instanţe. Se obţine astfel o ierarhie
conceptuală de mai multe nivele.
Conceptul fiind de fapt un obiect cu structură este alcătuit din entităţi formale numite
componente împreună cu relaţiile dintre acestea.
De multe ori este greu a se formula un concept dar se pot descrie clase ce aparţin
mulţimii instanţelor unui concept. Asemănător ierarhiei conceptuale se poate defini o ierarhie
de clasificare între componentele cărora se stabilesc relaţii taxonomice. Descrierea relaţiilor
taxonomice între obiectele plasate în nodurile reţelei se face cu ajutorul primitivelor
taxonomice ce asigură interpretarea uniformă a acestor legături în toată reţeaua. Primitivele
taxonomice sunt specificate ca simboluri relaţionale (predicate) ce etichetează arcele reţelei,
la a căror capete se găsesc noduri între care se defineşte o relaţie de apartenenţă de la obiect la
clasă. Iată principalele primitive taxonomice:
- relaţia de apartenenţă a obiectului la clasă, specificată de regulă printr-un predicat
de forma:

ESTE (<element>, <clasa>)

cu semnificaţia cunoscută în algebră <element> <clasa>.

- relaţia de incluziune a unei submulţimi într-o mulţime se specifică printr-un predicat


de forma:

ESTE_SUBMULŢIME (<mulţime1>, <mulţime2>)

cu semnificaţia <mulţime1> <mulţime2>.


În anumite situaţii când aplicaţia o cere se pot rafina aceste relaţii încât pentru relaţia
de incluziune să se specifice submulţimile disjuncte. Spre exemplu apartenenţa persoanei cu
numele POPESCU la clasa oamenilor ce se exprimă cu ajutorul propoziţiei POPESCU ESTE
OM se va transpune în reţeaua semantică

INSTANŢĂ CONCEPT
POPESCU ESTE OM

Relaţie de
intensiune

Apartenenţa persoanei cu numele POPESCU la mai multe clase cum sunt mulţimea
informaticienilor, a cercetătorilor şi a oamenilor este reprezentată de reţeaua

OM
ESTE

POPESCU ESTE INFORMATICIAN

ESTE CERCETĂTOR

20
Utilizarea primitivei taxonomice ESTE permite reprezentarea şi în cazul în care mai
multe persoane sunt membre ale unor clase, de exemplu mulţimea oamenilor,
informaticienilor, cercetătorilor cu reprezentarea

POPESCU ESTE OM
ESTE_SUBMULŢIME
ADRIAN INFORMATICIAN

ION CERCETĂTOR

Cu toate că reprezentarea este sugestivă este însă dificil de regăsit direct propoziţia
POPESCU ESTE OM sau altă propoziţie corespunzătoare relaţiilor specificate.
Relaţia taxonomică nu epuizează toate posibilităţile pe care primitiva le oferă
reprezentării cunoaşterii. Pentru aplicaţiile de inteligenţă artificială au fost elaborate o serie
de primitive semantice din care mai cunoscute sunt cele elaborate de Yorrick Wilks şi Roger
Schank.
Sistemul lui Wilks porneşte de la premisa că în limbajul natural există cuvinte cu
semnificaţii primitive cât şi cuvinte fără semnificaţii primitive. Wilks defineşte următoarele
clase de primitive semantice:
- primitive ce semnifică entităţi de tip om, lucru, substanţă, parte;
- primitive ce specifică semnificaţii cu care se reprezintă acţiuni cum sunt cauză,
mutare, curgere, lovire;
- primitive ce specifică semnificaţii cu care se reprezintă relaţii între entităţi de tip
obiect, instrument;
- primitive ce specifică semnificaţii cu care se reprezintă calificative ale entităţilor şi
acţiunilor cum sunt: mult, puţin, bun, rău, mic, mare;
- primitive ce specifică semnificaţii cu care se reprezintă tipuri de entităţi;
- primitive ce specifică clase de primitive, obiecte fizice, oameni, obiecte în interior,
exterior.
Pentru cuvintele ce nu sunt primitive se dau definiţii cu ajutorul primitivelor
semantice. Primitivele semantice trebuie să fie independente în sensul că nu se pot defini cu
ajutorul altor primitive semantice asigurând astfel consistenţa (în sensul că nu sunt definite
circular).
Sistemul lui Schank sau teoria dependenţelor conceptuale foloseşte reprezentarea fără
ambiguităţi a semnificaţiei utilizând 11 acţiuni elementare grupate în categorii. Într-o astfel de
reţea semantică conceptele sunt legate prin relaţii numite dependente, ce se disting prin tip şi
etichetă. Pot exista mai multe tipuri de dependenţe cum sunt:
- dependenţa de tip cauzal materializată prin descrierea relaţiilor conceptuale ale
obiectului şi legătura sa cu actul primitiv;
- dependenţă de tip subiectival care leagă acţiunea primitivă de agentul său numit şi
concept actor;
- dependenţă de tip predicativ ce leagă un concept de un predicat.
Cele trei tipuri de dependenţe se pun în evidenţă prin mascarea cu linii diferite,
etichetele fiind cele ce denumesc arcele cu tipul dependenţei.
Funcţie de structură şi tipul de reprezentare reţelele semantice se pot clasifica în:
- reţele semantice simple;
- reţele semantice sortate;
- reţele semantice extinse.

21
1.1.4.1. Reţele semantice simple
Sunt acele entităţi în care nodurile sunt entităţi individuale, iar arcele relaţii ale
acestora. În aceste reţele nu se introduc specializări ale arcelor şi nodurilor, fapt ce determină
că interpretarea este dată de conţinutul descrierii ce este asociat fiecărui simbol ce figurează
ca etichetă de nod sau arc. La interpretare se asociază fiecărui simbol de etichetă o procedură
proprie de determinare a semnificaţiei, singura trăsătură comună a elementelor reţelei fiind
legată de structură şi se manifestă sub formă de proceduri fizice de parcurgere a reţelei. Cu
ajutorul reţelelor semantice simple se pot reprezenta aserţiuni libere de orice variabilă întrucât
nu se admit noduri specializate aferente reprezentării variabilelor.
Să presupunem reprezentarea piesei de cunoaştere ce specifică faptul că “LA
SUSŢINEREA TEZEI DE DOCTORAT DE CĂTRE ION CARE ESTE UN BUN SPECIALIST,
COLEGUL SĂU VASILE ÎI OFERĂ UN FRUMOS CADOU.” Se obţine următoarea reţea
semantică simplă:

SUSŢINERE TEZĂ
ESTE
ION SPECIALIST
ESTE Referitor agent

EVENIMENT 2 ESTE
COLEG OM
receptor
CAUZEAZĂ
ESTE
EVENIMENT 1 agent VASILE

ACŢIUNE OBIECT

OFERĂ CADOU CALITATE FRUMOS

Se observă din studiul reprezentării de mai sus că aceasta nu este realizată în formă
propoziţională. Se cunoaşte faptul că ION şi VASILE sunt oameni, adică aparţin clasei OM.
Acţiunea de oferire a cadoului de către VASILE este un eveniment pentru care VASILE este
agent şi ION este receptor. Pentru ION susţinerea tezei de doctorat este de asemenea un
eveniment. Acest eveniment este în relaţie cauzală cu evenimentul oferirii cadoului.
Reţelele semantice simple nu oferă noduri preferenţiale în iniţierea procesului de
interpretare, selecţia unui nod ca nod iniţial este determinată de aplicaţia pentru care este
construită baza de cunoştinţe. Candidaţii pentru poziţia de nod iniţial sunt selectaţi după
diverse criterii dintre care cele mai întâlnite sunt:
- nodul etichetat cu un simbol identic numelui piesei de cunoaştere;
- selecţia candidaţilor dintre nodurile ce au proprietatea de a fi noduri sursă pentru toate
relaţiile în care sunt implicate.
Pentru descrierea unei reţele semantice simple aceasta este descompusă în triplete de
forma

(<nod_sursă> <relaţie> <nod_destinaţie>).

Descompunerea sugerează utilizarea de liste în LISP pe care le puteţi vedea în


exerciţiul 3, probleme rezolvate, de la sfârşitul acestui modul.

22
1.1.4.2. Reţele semantice sortate

Se caracterizează prin aceea că folosesc specializarea nodurilor şi/sau arcelor pentru a


specifica unele diferenţe de natură structurală între entităţi ce nu pot fi relevate prin
etichetare. Pentru aplicaţii de dialog în limbaj natural se foloseşte reprezentarea
propoziţională a cunoaşterii, asociind la aceasta relaţii cauzale. În elaborarea tehnicilor de
etichetare a nodurilor şi tipurilor de relaţii se cunosc mai multe abordări dintre care cea mai
utilizată este cea definită de Fillmore, care stabileşte un număr restrâns de relaţii primitive ce
pot acoperi o varietate semantică largă. Iată câteva exemple de relaţii cauzale:

- PREDICAŢIE - stabileşte că nodul sursă este de tip propoziţional, indicând o


instanţiere a predicatului specificat în eticheta nodului
destinaţie ce reprezintă o instanţiere sau o stare (echivalentă cu
verbul într-o propoziţie);
- AGENT - are ca nod destinaţie o entitate cu capacitatea de a efectua
acţiunea. Entitatea este numită şi “actor” şi are rolul de subiect
logic;
- RECEPTOR - indică un nod destinaţie ce are capacitatea de a participa la
acţiune;
- OBIECT - indică ca nod destinaţie o entitate ce este afectată de acţiunea
specificată pentru propoziţia din nodul sursă;
- INSTRUMENT - are ca nod destinaţie o entitate ce este folosită de agent la
efectuarea acţiunii suportate de obiect;
- LOC - are ca nod destinaţie o entitate ce exprimă o propoziţie ce
indică locul desfăşurării acţiunii;
- TIMP - indică un nod destinaţie ce specifică timpul sub o anumită
formă. Poate fi exprimată durata prin două relaţii momentane
(moment_iniţial, moment_final), fie ca o relaţie durată ce arată
valoarea intervalului fără a specifica scara timpului.

Esenţială pentru reprezentarea propoziţională este predicţia, care poate fi exprimată cu


ajutorul unui simbol predicat, cu argumentele plasate în două clase şi anume:
- argumente de bază - obligatorii pentru a defini o instanţă valabilă a
predicatului şi
- argumente periferice - ce aduc în reţea relaţii suplimentare prin care se
conturează cunoaşterea sub aspecte ce nu depind
exclusiv de predicţia considerată.
Se definesc următoarele sorturi de expresii predicative corespunzătoare la categoriile
sintactice ale limbajului natural:
- sortul expresiilor predicative verbale (V) ce apar în instanţe ca predicate ale
propoziţiilor;
- sortul expresiilor predicative adjectivale (A) ce apar în instanţe ca modificatori de
termeni;
- sortul expresiilor predicative nominale (N) ce apar în instanţe ca definiţii de
termeni.
Cadrul definitoriu pentru predicate cuprinde următoarele date iniţiale:
- formatul predicatului compus din numele identificator, lista argumentelor de bază
şi a argumentelor periferice;
- sortul predicatului;

23
- funcţia semantică a argumentelor exprimate sub forma relaţiilor cauzale;
- restricţii de selecţie a termenilor ce candidează pe poziţia de argumente ale
predicatului.
Starea de lucruri descrisă de o predicţie dă o valoare de adevăr predicatului. Stările de
lucruri ce nu se modifică în timp se numesc statice, spre deosebire de cele dinamice ce sunt
caracterizate de schimbări de timp.
Dacă în cadrul predicatului există un argument numit controlor ce are proprietatea de
a determina starea de lucruri asociată predicţiei se spune că starea este controlată. Dinamismul
şi controlul determină noi sorturi ale predicţiei şi anume:
- acţiunea - stare dinamică şi controlată;
- procesul - corespunde unei stări de lucruri dinamice şi necontrolate;
- poziţia - corespunde unei stări de lucruri statice şi controlate;
- situaţia - corespunde unei stări de lucruri statice, dar necontrolate.
Relaţiile cauzale se pot extinde fără restricţii putând fi definite următoarele tipuri de
relaţii:
- relaţii ce extind specificarea stării de lucruri: calitate, modalitate;
- relaţii ce referă predicţia la alţi participanţi: iniţiator, cunoscător, executor,
terminator;
- relaţii ce extind dimensiunile spaţiale: sub, lângă, deasupra;
- relaţii ce extind dimensiunile temporale: durata, frecvenţa;
- relaţii de interpoziţionare între o stare şi alte stări: cauză, motiv, scop, rezultat,
circumstanţă.
În procesul de instanţiere a pieselor de cunoaştere individuale dintr-o reţea semantică
prin care să reprezentăm cunoaşterea sub toate aspectele sale conceptuale şi factuale, apare
necesară organizarea reţelei semantice în vederea stabilirii ierarhiei între diferitele
componente ale reţelei.
Cea mai simplă organizare împarte reţeaua în două părţi:
- reţeaua conceptuală, în care sunt descrise piesele de cunoaştere care reprezintă
obiecte, acţiuni, procese, stări de lucruri cu caracter generic;
- reţeaua factuală, în care sunt descrise instanţele acestor concepte.

1.1.4.3. Reţele semantice extinse


Caracteristica pentru reţele semantice extinse este specializarea nodurilor şi arcelor,
corespunzătoare cerinţelor programării logice, definindu-se:
- sorturi pentru noduri (simboluri funcţionale, variabile, constante);
- sorturi pentru arce (relaţii condiţionale şi conclusive).
Reţeaua semantică extinsă este o reprezentare grafică echivalentă cu forma cauzală a
formulelor logice.
Piesa de cunoaştere “cine se scoală de dimineaţă, departe ajunge” ce se poate scrie cu
formula

x (este(x, om) se_scoală (x, dimineaţă) ajunge(x, departe)),

se poate reprezenta sub forma unei reţele semantice extinse astfel:

24
OM

Relaţii
X AJUNGE DEPARTE
condiţionale

DIMINEAŢA Relaţie conclusivă

Reţelele semantice extinse sunt de fapt reţele sortate pe baza unor criterii de logică a
programării.
Diferenţe între reţelele semantice extinse sunt date de criteriile:
- setul primitivelor semantice şi metodele de tratare a neprimitivelor;
- stabilirea sorturilor pentru noduri şi arce;
- mecanismele de definire a altor sorturi (definirea pieselor de metacunoaştere);
- convenţiile de reprezentare grafică.
Reţelele semantice extinse oferă un instrument de realizare mai apropiat decât reţelele
semantice simple.
Prin sortarea nodurilor şi arcelor se introduc mecanisme descriptive puternice capabile
să specifice restricţii implicite, ceea ce au efect favorabil asupra: eficienţei utilizării spaţiului
de reprezentare, simplifică accesul la piesele de cunoaştere şi reduce timpul necesar pentru
procesele inferenţiale.

1.1.5. Reprezentarea cunoaşterii cu ajutorul cadrelor


A fost introdusă de Marvin Minsky şi încearcă să reunească o parte din conceptele de
bază ale metodelor de reprezentare procedurală, sisteme de producţii şi reţele semantice.
Conceptul de cadru este o generalizare a gramaticii de cazuri din lingvistică ce cuprinde
informaţia declarativă şi procedurală. Un cadru este reprezentat printr-o structură stereotipă ce
utilizează categoriile sintactice:
- identificator - are asignat un nume care asociat cu alte descrieri specifică structura
cadrului la care este ataşat;
- forma - categorii de caracteristici la care se asignează simboluri relaţionale
specifice conceptului;
- faţeta - sunt reprezentate de perechi simbol-valoare cu care se descriu obiectele din
relaţiile specificate de formele reprezentării.
Cadrul este format dintr-o structură arborescentă de locuri în care piesa de cunoaştere
va plasa simbolurile purtătoare de semnificaţie. Un formalism metalingvistic de reprezentare a
cadrelor este:

<cadru> = (<identificator_cadru> <descriere_formă>).


<descriere_formă> = ((<identificator_formă> <descriere_faţetă>),...
...,(<identificator_formă> <descriere_faţetă>)).
<descriere_faţetă> = ((<identificator_faţetă> <descriere_dată>),...
...,(<identificator_faţetă> <descriere_dată>)).
<descriere_dată> = (<valoare> <descriere_date> <valoare>).
<valoare> = (<date> <etichetă> <mesaje> <comentariu>).

Simbolurile pot reprezenta proprietăţi ale obiectelor sau relaţiilor, nume de alte cadre,
identificatori de proceduri ataşate. Se disting în reprezentarea prin cadre o serie de primitive

25
semantice ce fac să plaseze cunoaşterea în conceptul mai larg oferit de structura cadrului cum
sunt:
- forme utilizate la descrierea piesei de cunoaştere;
- forme ce exprimă elemente reprezentate de utilizarea cadrului;
- forme corespunzând prezumţiilor considerate adevărate;
- forme corespunzând reorientării continuării în situaţia eşecului.
Relaţiile aferente utilizării formelor, relaţii ce caracterizează piesa de cunoaştere şi
legăturile sale cu universul problemei se pot împărţi după tip în :
- generalizare - specifică concepte cu definiţii mai puţin restrictive;
- specializare - specifică concepte cu descrieri ce satisfac o condiţie dată;
- apartenenţa - indică clasa din care face parte piesa de cunoaştere şi prin care se
moştenesc proprietăţile;
- compoziţia - indică obiectele ce intră în alcătuirea obiectului;
- proprietăţile - reprezintă proprietăţile specifice ale obiectului reprezen-tat.
Un exemplu de reprezentare cadru pentru o universitate cu profil tehnic care foloseşte
forme cadru specifice de descriere se găseşte la sfârşitul acestui modul, probleme rezolvate.

O facilitate puternică este cea a introducerii în cadre a reprezentării regulilor de


producţie. Transpunerea unei reguli în cadre porneşte de la obiectivele:
- regula conţine două acţiuni distincte, deci două forme procedurale diferite;
- prima formă cea de evaluare a condiţiilor are ca efect autorizarea execuţiei celei
de-a doua forme procedurale sau ieşirea din regula de eşec;
- a doua formă determină corpul propriu-zis al acţiuni ce se execută când condiţia
este îndeplinită;
- contextul operaţional este reprezentat de celelalte forme cu caracter declarativ.

Structura implicit ierarhizată a conceptului de cadru face posibilă organizarea sub


formă de arbori de clasificare. Structura arborescentă derivă din cadre prototip ale claselor şi
subclaselor.

26
Unitatea de învăţare nr.2
Problematica rezolvării problemelor
(sisteme rezolutive)
Cuprins:
2.1. Probleme, raţionamente, strategii ................................................................ pag. 27
2.1.1. Strategia de control înainte..... .................................................................. pag. 28
2.1.2. Strategia de control înapoi ..... .................................................................. pag. 29
2.1.2. Strategia de control combinat înainte-înapoi ..... ...................................... pag. 30
2.2. Tipuri reprezentative de probleme ............................................................... pag. 31
2.3 Cunoaşterea despre problemă în procesul rezolvării .................................... pag. 32
2.4. Reprezentarea problemelor în limbajul calculului cu predicate
de ordinul întâi .................................................................................................... pag. 33
2.4.1. Skolemizarea formulelor ........................................................................... pag. 35
2.5. Reprezentarea problemei în spaţiul stărilor .................................................. pag. 38
2.6. Utilizarea grafurilor ŞI/SAU ........................................................................ pag. 41
2.6.1. Rezolvarea problemelor prin decompoziţie .............................................. pag. 42
2.7. Aplicaţii. Exerciţii rezolvate, teste de autoevaluare, teme de control ..... .... pag. 43
2.8. Bibliografie modul 1 .................................................................................... pag. 47

2.1. Probleme, raţionamente, strategii

Rezolvarea problemelor este obiectivul fiecărui sistem inteligent şi se va face atât prin
căutarea unor răspunsuri predefinite la unele întrebări, dar mai ales prin procese complexe de
deducţie, de calcul simbolic şi evaluări numerice, care se bazează pe faptele specificate în
enunţul problemelor şi pe fapte înregistrate a priori în baza de cunoştinţe.
Totalitatea componentelor unui astfel de sistem destinat rezolvării de probleme
formează un sistem rezolutiv.
Problema reprezintă o dificultate de natură cognitivă dată de:
- insuficienţa sau inadecvarea unor răspunsuri la întrebări privind o entitate
necunoscută;
- incapacitatea sistemului rezolutiv de a construi un răspuns prin aplicarea
procedeelor cunoscute.
Problema prezentată spre rezolvare sistemului de inteligenţă artificială este un enunţ
de problemă potenţială. Confirmarea ca problemă reală e dată de apariţia în cadrul sistemului
a unei situaţii problematice.
Constituentele primitive ale problemei sunt:
- aserţiuni ce descriu obiectele ce alcătuiesc universul discursului, numite şi date ale
problemei (aspectul factual);
- aserţiuni referitoare la operaţiile permise sau condiţiile problemei (aspectul
procedural);
- obiecte, proprietăţi sau condiţii reformulate explicit, consecinţă a enunţului sau
necunoscutele problemei.
Obiectivul rezolvării îl reprezintă asocierea unei determinări fiecărei necunoscute.
Indiferent de modul de raţionare utilizat ciclul de bază al unui mecanism de inferenţe cuprinde
patru faze şi anume:
- faza de selecţie a unui subansamblu al bazei de fapte şi reguli ce merită atenţia faţă
de restul bazei. Selecţia oferă o economie de timp considerabilă pentru fazele
următoare;

27
- faza de filtrare ce are ca efect comparaţia între partea de premisă a regulii
considerate şi faptele bazei de fapte pentru determinarea regulilor aplicabile;
- faza de rezolvare a conflictelor are ca obiectiv alegerea acelor reguli ce sunt
aplicate efectiv;
- faza de execuţie constă din aplicarea regulilor alese mai înainte, acţiunea constând
în general în adăugarea de noi fapte în baza de fapte.
Raţionamentul reprezintă constituirea lanţurilor sau a reţelelor inferenţiale între
premise şi concluzie. El este fundamentat pe faptele furnizate de enunţ şi pe cele din baza de
cunoştinţe. Dacă acestea sunt suficiente raţionamentul este direct, altfel se ajunge la impas şi
necesită folosirea altor raţionamente cum ar fi cel metaforic sau prin analogie.
Raţionamentele ce pornesc de la premise la concluzie (se numesc formale) şi studiază
transformările structurale. Raţionamentele informale pornesc de la semnificaţiile factuale şi
procedurale cuprinse în enunţuri. Aceste metode de raţionament surprind interpretări
structurale, semnificaţii de natură relaţională, proprietăţi primitive, structuri ierarhice bazate
pe primitive semantice. Raţionamentul informal este necesar să se valideze prin aplicarea
regulilor specifice simbolurilor folosite actual. Desfăşurarea raţionamentelor are loc pe baza
unei strategii ce asigura succesiunea inferenţelor.
Iată câteva strategii de control al raţionamentelor.

2.1.1. Strategia de control înainte

Această strategie porneşte de la starea iniţială descrisă de enunţ şi generează succesiv


candidaţi la soluţie până la obţinerea răspunsului corespunzător obiectivului problemei.
Regulile ce se utilizează pot fi reguli de inferenţă ale mecanismelor logice de bază,
reguli specifice definite prin enunţ referitoare la generarea termenilor, simboluri relaţionale,
restricţii ce reduc spaţiul problemei. Se mai spune despre strategiile de control înainte că
pornesc de la fapte pentru a ajunge la obiectiv. În consecinţă se vor selecta regulile a căror
parte de condiţie este verificată (faza de selecţie şi filtrare). Pentru faza de rezolvare a
conflictelor din ansamblul regulilor selectate se vor alege acelea ce au prioritate maximă. Se
obţine astfel strategia generală de control:

< contextul de stare iniţială >


regula 1 (operatorul 1)
< contextul de stare succesivă 1>
regula 2 (operatorul 2)

regula n (operatorul n)
< contextul de stare finală > < obiectivul problemei >

Succesiunea regulilor de obţinere a căilor de rezolvare sugerează un arbore ale cărui


noduri sunt stări în spaţiul stărilor, soluţia problemei fiind dată printr-o procedură de căutare
în spaţiul stărilor. Metodele ce adoptă această strategie se numesc metode productive, iar
strategia se numeşte de jos în sus sau de căutare dirijată prin date.
Se consideră un exemplu de bază de cunoştinţe reprezentată prin reguli de producţie:

R1 : IF B and D and E THEN F


R2 : IF D and G THEN A
R3 : IF C and F THEN A
R4 : IF B THEN X
R5 : IF D THEN E

28
R6 : IF A and X THEN H
R7 : IF C THEN D
R8 : IF X and C THEN A
R9 : IF X and B THEN D

Dacă se presupune baza de fapte iniţială B, C şi obiectivul H, construcţia arborelui de


decizie pornind de la prima regulă prin secvenţierea regulilor în ordinea în care apar în baza
de cunoştinţe este următoarea:

R9
R 4 (B)
B, C B, C, X
R8
R 7 (C)
R 7 (C)
R9
B, C, X, D
R 5 (D) R8
R9
B, C, X, D ,E
R8
R 1 (E)
R9
B, C, X, D , E, F
R 3 (F) R8
R9
B, C, X, D , E, F, A,
R8
R6
B, C, X, D , E, F, A H

Să considerăm acum o strategie prin care se selectează din mulţimea regulilor


aplicabile acelea pentru care numărul de condiţii din partea de premisă este mai mare. Se
observă că regula R8 este preferabilă faţă de regula R7 întrucât are în premisă două condiţii
faţă de R7 care are doar una. Cu această strategie se obţine arborele:

R4 R8 R6
B, C B, C, X B, C, X, A B, C, X, A, H
R7 R7
R8
R9 R9

Se observă că printr-o astfel de strategie numărul de inferenţe se reduce la trei faţă de


şase anterior. În plus trebuie reţinut faptul că o inferenţă aplicată o dată nu se mai aplică
întrucât nu serveşte la nimic ca să se deducă un fapt ce a fost deja dedus. Eficacitatea
ajungerii la scop este dată de numărul de inferenţe necesare, număr de inferenţe ce depinde în
mare măsură de faza de eliminare conflicte.

2.1.2. Strategia de control înapoi

Această strategie de control porneşte de la obiectivul problemei care prin aplicarea


regulilor de descompunere se transformă în subprobleme de complexitate mai mică.
29
Structura generală a inferenţierii este:

< Obiectivul problemei > < contextul de stare finală >


regula 1
< contextul de stare precedentă 1 >
regula 2

regula n
< contextul de stare iniţială >

Modul de control specificat mai poartă denumirea şi de control dirijat prin obiectivul
problemei sau control de sus în jos. Metoda se mai numeşte şi reductivă.
Raţionarea porneşte de la scop, selectând acele reguli ce au partea dreaptă în
corespondenţă cu obiectivul problemei. Condiţiile necunoscute (partea stângă) devin în acest
mod subscopuri ce se vor demonstra. Procesul continuă până când toate subscopurile se
verifică. În acest caz sistemul poate cere utilizatorului să răspundă la întrebări şi procesul
reîncepe după primirea răspunsurilor. În momentul în care sistemul nu mai poate selecta
reguli, formula întrebări utilizatorului sau utilizatorul nu mai poate răspunde la întrebări se
ajunge la situaţia de eşec.
Pentru exemplul considerat la strategia de control înainte, se poate observa că regulile
R2 , R3 , R8 pot fi utilizate pentru a verifica scopul A. În acest sens regulile sunt aplicate în
ordinea numerotării lor, pentru a încerca să verifice din unul în altul subscopurile produse. În
caz de eşec, cum este subscopul G care nu poate fi dedus, se revine în arbore pentru a selecta
regulile lăsate la prima trecere. În acest fel explorarea încetează atunci când fie a fost
demonstrat obiectivul iniţial, fie când toate selecţiile posibile au condus la eşec. În diversele
faze sistemul poate recurge la chestionări ale utilizatorului asupra subobiectivului nerezolvat.
Avantajele strategiei de căutare înapoi:
- arborele de căutare este adesea mai puţin adânc decât cel aferent strategiei de
control înainte;
- sistemul poate recurge la întrebări adresate utilizatorului, procesul de raţionare
fiind interactiv.
Strategia are şi un mare dezavantaj legat de faptul că există pericolul buclării.

2.1.3. Strategia de control combinat înainte-înapoi

Această strategie este caracterizată de faptul că utilizează metode reductive pentru


descompunerea problemei în subprobleme care apoi sunt rezolvabile prin metode productive,
fie prin metode reductive. Succesiunea inversă nu este posibilă întrucât metodele productive
generează de la primul pas candidaţi la soluţie ce nu reprezintă subproblemele, fapt pentru
care odată selectată metoda productivă nu poate fi părăsită pentru a continua rezolvarea prin
alte metode. Deci odată generată o metodă productivă aceasta va fi utilizată până la obţinerea
soluţiei finale.
Alegerea strategiei de control este dependentă de tipul de raţionament ales. Cert este
faptul că nici o strategie de control nu este bună în orice situaţie. Strategia de control înainte
este indicată pentru tratarea cunoştinţelor empirice şi este ineficientă pentru probleme
complexe. Dacă însă unul sau mai multe scopuri trebuie atinse sau verificate este mult mai
indicat să se utilizeze strategia de control înapoi. Raţionarea înapoi este indicată în cazul
informaţiilor incomplete sau când se poate angaja un dialog cu utilizatorul în vederea
îmbogăţirii sistemului de informaţii necesare inferenţelor.

30
2.2 Tipuri reprezentative de probleme

Capacitatea de rezolvare a problemelor de către un sistem inteligent este apreciată


după uşurinţa cu care dă soluţii la probleme ce nu au fost stabilite în prealabil, precizarea lor
fiind făcută în momentul încărcării bazei de cunoştinţe.
Din punctul de vedere al satisfacerii condiţiilor de formulare se pot distinge trei mari
categorii de probleme:
- probleme bine formulate – sunt acele probleme ce satisfac condiţiile de necesitate
şi suficienţă pentru toate componentele din structură, necunoscutele împreună cu
datele alcătuind un model consistent;
- problemele incomplet definite – sunt problemele în a căror formulare se poate pune
în evidenţă lipsa unor date, a condiţiilor acestora sau sunt lipsuri în specificarea
elementelor văzute ca necunoscute;
- probleme greşit formulate – pentru care pot fi puse în evidenţă contradicţii şi
inconsistenţe sau nu pot fi stabilite clar componentele problemei.

Problemele bine formulate pot fi clasificate în :


(1) – probleme de tip interogativ
(2) – probleme de tip predicativ
(3) – probleme de tip inductiv

(1) – O problemă de tip interogativ este compusă din trei părţi:


- ipoteza =I= (alcătuită din date)
- procesul =P= (la care sunt supuse datele)
- rezultatul =R= (obţinut în urma aplicării procesului).
Funcţie de poziţia necunoscutului =X= în componentele problemei se deosebesc
probleme interogative de tip IPX, IXR şi XPR. Dacă toate componentele problemei sunt
cunoscute enunţul problemei este de tip IPR şi aceasta reprezintă un fapt. Se poate afirma că
atunci când unul din componentele unui fapt este necunoscut acesta devine o problemă.

Problemele de tip IPX au enunţul: “Care este rezultatul X al aplicării procesului P


asupra obiectelor din ipoteza I ?”. Rezultatul se obţine prin aplicarea efectivă a procesului P.

Problemele de tip IXR corespund enunţului: “Ce proces X trebuie aplicat asupra
obiectelor din ipoteze I pentru a obţine rezultatul R ?”. La acest tip se manifestă caracterul
creator, rezolvarea putându-se aborda astfel:

a) pe baza unor reguli euristice de forma:


IF (ipoteza este de tipul I) AND (rezultatul este de tipul R) THEN
se aplică (METODA_1) OR (METODA_2) OR … OR (METODA_n)
b) pe baza raţionamentelor prin analogie
c) pe baza unor metode de sinteză procedurală.

Problemele de tip XPR corespund formulării: “Ce obiecte X trebuie să fie prelucrate
de către procesul P pentru a obţine rezultatul R ?”.
Problema poate fi rezolvată direct doar dacă P este o bijecţie adică ştiind că R = P(X)
soluţia va fi X = P-1(R). Dacă însă P nu este o bijecţie atunci abordarea trebuie făcută prin
metode reductive.

31
(2) – Problemele de tip predicativ – se aseamănă cu cele interogative, diferenţa fiind
că ipoteza şi concluzia sunt entităţi cu valoare de adevăr. Componentele unei probleme de tip
predicativ sunt:
- ipoteza =I=
- procesul inferenţial =R=
- concluzia =C=
Cele trei tipuri de probleme se vor numi astfel:
Problemă de tip IPX – denumită şi deducţie sau derivare. Se întâlneşte frecvent în
aplicarea procedurilor ce vizează descompunerea problemelor în subprobleme;
Problemă de tip IXC – denumită şi demonstraţie. Soluţia unei astfel de probleme este
formată dintr-un lanţ de inferenţe ce porneşte de la ipoteze şi ajunge la concluzie. Aplicarea
unui lanţ inferenţial este caracteristică sistemelor rezolutive pentru demonstrarea automată a
teoremelor.
Problemă de tip XPC – denumită şi inducţie sau învăţare din exemple. Soluţia
presupune descoperirea unor concepte iniţiale, a cauzalităţii sau a altor premise prin
interpretarea rezultatelor ce se obţin pe baza unor reguli de inferenţă cunoscute.

(3) – Problemele de tip imperativ. La aceste tipuri de probleme enunţul nu conţine


necunoscute şi nici date de intrare. Rezultatul invocării procesului este efectul actual, adică
producerea rezultatului cunoscut. O astfel de problemă se poate descompune uneori în
subprobleme de primele două tipuri.
Problemele incomplet formulate au soluţie doar dacă în urma aplicării unor procedee
ce nu alterează specificul problemei din enunţ, se obţine o nouă formulare ce satisface
condiţia de bună formulare. Principalele procedee ce se aplică în astfel de cazuri sunt:
- reducerea enunţului la o problemă bine formulată, ce este făcută prin eliminarea
unor elemente lipsite de relevanţă ce alterau buna formulare;
- completarea enunţului de date transmise prin moştenire, aferente pieselor din
enunţ, cu date asimilate prin analogie;
- descompunerea problemei în subprobleme astfel încât anumite componente să fie
bine formulate;
- extinderea obiectivelor problemei asupra clasei ce cuprinde problema iniţială,
introducerea de obiecte abstracte, a condiţiilor suplimentare ce permit reformularea
enunţului pentru a satisface condiţiile de problemă bine formulată.
Este de la sine înţeles că nu se pune problema rezolvării problemelor incomplet
formulate.

2.3 Cunoaşterea despre problemă în procesul rezolvării

Piesele de cunoaştere pot fi clasificate în raport cu potenţialul lor de implicare în


procesele de rezolvare a problemelor. Primul criteriu de clasificare se referă la rolul jucat de
piesa de cunoaştere în procesul rezolvării, în timp ce al doilea criteriu diferenţiază calitativ
cunoaşterea pentru fiecare dintre roluri.
Pe baza primului criteriu se obţine următorul arbore:

32
conceptuală
factuală
instanţială

transformaţională
Cunoaştere procedurală
inferenţială

pentru structuri
de control
pentru raţionamente

Dependenţele reciproce dintre diferitele clase ce formează piesele de cunoaştere


pornesc de la cunoaşterea factuală ce defineşte prototipuri ale unor fapte şi instanţe ce descriu
fapte individuale. Asupra pieselor de cunoaştere factuală operează cunoaşterea procedurală ce
specifică proceduri e transformare a pieselor de cunoaştere factuală. Cunoaşterea de control
asupra procesului de rezolvare se bazează pe piese de cunoaştere procedurală şi specifică
modul de succesiune în care se înlănţuie procedurile de transformare pentru obţinerea de noi
structuri, modul de succesiune în aplicarea regulilor de inferenţă pentru raţionamente.
O a doua clasificare se referă la piesele de cunoaştere primitive. Se poate considera că
la fiecare nivel pot exista:
- piese ale cunoaşterii directe;
- piese ale cunoaşterii deduse, obţinute din primele prin aplicarea regulilor de
inferenţă.
În domeniile în care cunoaşterea depinde foarte mult de experienţa personală a
specialiştilor ce furnizează cunoaşterea expertă (deci domeniul sistemelor-expert), deosebim
piese aparţinând cunoaşterii globale, pentru care există mai multe opinii convergente şi piese
ale cunoaşterii personalizate, a fiecărui individ.
În continuare se vor trata moduri de reprezentare a problemelor după diferite
formalisme specifice modurilor de reprezentare a cunoştinţelor.

2.4. Reprezentarea problemelor în limbajul calculului cu predicate de ordinul


întâi

Transcrierea în formule a enunţurilor presupune efectuarea unei analize cu obiectivele:


- descompunerea enunţului în piese de cunoaştere ce pot fi descrise cu ajutorul
predicatelor de ordinul întâi;
- extragerea caracteristicilor structurale ale teoriei în care se plasează problema dată;
- definirea cunoaşterii factuale prin asigurarea de simboluri constante la variabilele
predicatelor;
- definirea obiectivului problemei cu ajutorul formulelor din calcul cu predicate de
ordinul întâi.
Enunţul problemei este exprimat în general într-un limbaj apropiat de cel natural, ce
este transcris în formule ale calculului cu predicate de ordinul întâi, problema prezentându-se
sistemului rezolutiv în următoarea grupare de simboluri:
- suportul obiectual ce ataşează piese de cunoaştere ca variabile formale pentru
expresii predicative primare;
- simboluri funcţionale formate din piese de cunoaştere pentru definirea termenilor
din formule;

33
- simboluri predicative ce definesc piese cu valoare de adevăr ce descriu proprietăţi
ale obiectelor sau relaţii între obiecte;
- fapte – expresii formale ce exprimă adevăruri despre obiectele implicate;
- obiectivul reprezentat printr-o expresie formală, prin care se exprimă ce se
urmăreşte ca rezultat.
Să considerăm următorul exemplu de problemă:
“ Un grup de excursionişti ajung pe malul stâng al unui râu ce nu poate fi traversat
înot. La acelaşi mal se găsesc doi copii cu o barcă. În barcă poate să fie la un moment dat un
singur excursionist sau doi copii. În final se cere ca grupul excursioniştilor să se găsească pe
malul drept, iar cei doi copii împreună cu barca pe malul stâng. ”
Se propune următoarea grupare de simboluri:
Suportul obiectual format din:
- mulţimea copiilor C = { c1 , c2 }
- mulţimea excursioniştilor E = { e1 , e2 , … , en }
- elementul barcă {b}
- cele două maluri { d , s }
Simbolurile predicative ce se vor asocia proprietăţilor :
C(x) – x este un copil
E(x) – x este un excursionist
D(x) – x este pe malul drept
S(x) – x este pe malul stâng
B(x) – barca este în poziţia x { d , s }
T(x, y, z) – (x) trece cu barca din poziţia (y) în poziţia (z) în care x C E,
y, z { s , d };
Faptele sunt organizate în fapte reprezentând condiţii ale problemei şi fapte relevând
proprietăţi ale obiectelor.
Condiţiile şi expresiile formale ce definesc problema traversării sunt:
- Barca ajunsă pe malul drept trebuie readusă pe malul stâng numai de către un copil,
un excursionist ajuns pe malul drept va rămâne acolo ştiind că numai aşa obiectivul
problemei poate fi atins. Deci:
i) [D(x) C(x)] B(d) T(x, d, s)
- Dacă barca este pe malul stâng şi pe malul drept există un copil care să o readucă
înapoi atunci un excursionist poate traversa râul;
ii) [S(x) E(x)] [D(y) C(y)] B(s) T(x, s, d)
- Dacă cei doi copii se găsesc pe malul stâng aceştia pot traversa râul împreună
utilizând barca, fapt ce se exprimă prin formula:
iii) [S(x) C(x)] [S(y) C(y)] B(s) T(x, s, d) T(y, s, d)
- Poziţia bărcii după o traversare
iv) T(x, y, z) B(z)
- În urma unei traversări obiectele traversate vor fi plasate pe malul destinaţie
v) T(x, s, d) D(x)
vi) T(x, d, s) S(x)
- Dacă ambii copii sunt pe malul drept unul dintre ei va trebui să aducă barca pe
malul stâng
vii) [D(x) C(x)] [D(y) C(y)] B(d) T(x, d, s)
- Faptele care exprimă proprietăţi ale obiectelor sunt date de mulţimea copiilor,
mulţimea excursioniştilor şi de poziţia iniţială a acestora.
viii) C(c1), C(c2), E(e1), E(e2), … , E(en), S(c1), S(c2), S(e1), S(e2), … , S(en), B(s)
- Obiectivele problemei sunt date de poziţia finală a copiilor, bărcii şi
excursioniştilor
34
ix) D(e1) D(e2) … D(en)
şi
x) S(c1) S(c2) B(s)
Forma generală a formulelor în calculul cu predicate de ordinul întâi nu este
convenabilă pentru aplicarea formulelor cunoscute în logică. În acest sens o serie de
transformări sunt aplicate acestor formule pentru a fi aduse la forma convenabilă
mecanismului de interpretare.

2.4.1. Skolemizarea formulelor

Activitatea de uniformizare a modului de scriere a formulelor se realizează în principal


după următoarele etape:
- reducerea numărului de conective prin eliminarea implicaţiei şi echivalenţei;
- aducerea formulelor la forma normală prenex (cuantificatorii sunt aduşi înaintea
corpului formulei pe care o prefixează);
- rescrierea formulei ca formulă universală pri eliminarea cuantificatorilor
existenţiali utilizând funcţiile Skolem;
- rescrierea formulelor utilizând forma Skolem conjunctivă, mult mai convenabilă
pentru demonstrarea automată.
Se spune că o formulă f are o formă Skolem f S ce nu este logic echivalentă, dar este
adevărată dacă şi numai dacă f este adevărată.
Reducerea numărului de conective are ca obiect aducerea formulelor la forma
convenabilă aplicării regulilor de inferenţă. Reamintim că în teoria inferenţelor logice
reprezentarea regulilor se face în forma clauzală şi anume:
A1 A2 … Am B1 B2 … Bn
ceea ce este echivalent cu
A1 A2 … Am B1 B2 … Bn
Vom prezenta în continuare reguli de calcul în formule ale limbajului calculului cu
predicate de ordinul întâi:

Teorema 1. Fie A şi B două formule oarecare. Atunci sunt valabile următoarele reguli:
1) (A B) ( A B);
2) (A B) (A B);
3) (A B) (A B) ( A B).

Teorema 2. Dacă x este o variabilă, iar A, B, A(x) şi B(x) formule, dar A şi B nu conţin
apariţii libere ale variabilei x , atunci:
1) x (A B(x)) A xB(x);
2) x (A(x) B) xA(x) B;
3) x (A B(x)) A xB(x);
4) x (A(x) B) xA(x) B;
5) x (A(x) B(x)) xA(x) xB(x);
Pornind de la o formulă oarecare A se poate găsi o formulă A’ numită şi formă prenex
a lui A cu proprietăţile:
1) A’ este echivalentă cu A, adică A A’.
2) în formula A’, toţi cuantificatorii (în cazul când există) sunt plasaţi grupat în partea
cea mai din stânga a formulei prefixând corpul formulei în care sunt plasate
35
celelalte simboluri logice ( , , , , în cazul când există) care figurau în scopul
fiecărui cuantificator.

Teorema 3. Dacă x şi y sunt variabile distincte, iar A, B, A(x), B(x) şi A(x, y) sunt
formule, dar A şi B nu conţin apariţii libere ale variabilei x şi dacă x este liber pentru y în A(x,
y) (în formulele 5 şi 6), atunci:
1) x A A;
2) x A A;
3) x y A(x, y) y x A(x, y);
4) x y A(x, y) y x A(x, y);
5) x y A(x, y) x A(x, x);
6) x A(x, x) x y A(x, y);
7) x A(x) x A(x);
8) x y A(x, y) y x A(x, y);
9) x A(x) x A(x);
10) x A(x) x A(x);
11) x A(x) x A(x);
12) x A(x) x A(x);
13) x A(x) x B(x) x (A(x) B(x));
14) x A(x) x B(x) x (A(x) B(x));
15) A x B(x) x (A B(x));
16) A x B(x) x (A B(x));
17) A x B(x) x ( A B(x) );
18) A x B(x) x ( A B(x) );
19) x ( A(x) B(x) ) x A(x) x B(x);
20) x A(x) x B(x) x ( A(x) B(x) );

Obţinerea formei prenex are loc după următoarea succesiune de operaţii:

(a) Tranzitarea negaţiei de la formule la atomi

Teorema 4. Dacă x este o variabilă, iar A, B, A(x) şi B(x) sînt formule atunci:
1) x A(x) x A(x);
2) x A(x) x A(x);
3) (A B) A B;
4) (A B) A B;
5) A) A;

(b) Transferul cuantificatorilor de la formule la atomi

Teorema 5 Dacă x este o variabilă, A(x) si B sînt formule cu x liberă în A dar legată în
B, atunci:
1) x (A(x) B) x A(x) B;
36
2) x (B A(x)) B x A(x);
3) x (A(x) B) x A(x) B;
4) x (B A(x)) B x A(x);
5) x (A(x) B) x A(x) B;
6) x (B A(x)) B x A(x);
7) x (B A(x)) B x A(x);
8) x (A(x) B) x A(x) B;

Teorema 6 Dacă x este o variabilă, A(x) şi B(x) sînt formule cu x liberă atât în A(x) cât
şi în B(x), atunci:
1) x (A(x) B(x)) x A(x) x B(x);
2) x (A(x) B(x)) x A(x) x B(x);

Teorema 7 Dacă x şi y sînt variabile A(x, y) şi B(x, y) sînt formule, x este legată în cel
puţin una din formulele A(x, y) şi B(x, y), iar y este liberă atât în A(x, y) cât şi în B(x, y),
atunci:
1) x y (A(x, y) B(x, y)) y x (A(x, y) B(x, y));
2) x y (A(x, y) B(x, y)) y x (A(x, y) B(x, y))

(c) Schimbarea numelor variabilelor


Când 2 cuantificatori prefixează acelaşi nume de variabilă, numele variabilei este
înlocuit cu un simbol diferit de celelalte simboluri pentru variabilele utilizate. Procedeul se
mai numeşte şi standardizarea variabilelor.

(d) Eliminarea cuantificatorului esenţial


Fie o formulă în limbajul calculului cu predicate de ordinul întâi având variabilele libere x1,
x2, ….xn, y. Pentru o variabilă oarecare, fie aceasta y, se poate asocia cu simbolul funcţional
f ( x1, x2, ….xn) denumit funcţia Skolem a lui , ce satisface axioma Skolem a lui :

| x1, x2, ….xn ( y ( x1, x2, ….xn) ( x1, x2, ….xn, f ( x1, x2, ….xn)

Astfel se elimină din formula dată cuantificatorul existenţial prin înlocuirea variabilei
cuantificate cu un simbol funcţional inexistent având ca argumente acele variabile ce sînt
cuantificate universal.

(e) Tranzitarea în prefix a cuantificatorilor universali


Întrucât simbolurile de variabile sînt individualizate pot fi grupaţi în prefix toţi cuantificatorii
universali obţinând astfel forma normală prenex a formulei.
În concluzie, o formulă în forma normală prenex este alcătuită din două părţi şi
anume:
- partea din stânga, denumită şi prefix, care cuprinde toţi cuatificatorii universali ai
formulei
- partea plasată după prefix numită şi matricea formulei ce cuprinde literele libere de
cuantificatori şi alcătuieşte corpul propriu-zis al formulei
Forma normală prenex permite transmiterea subformulelor componente în vederea
obţinerii formei normale conjuctive, numită şi forma Skolem conjunctivă, formată din
conjuncţii de disjuncţii. Dacă A, B, C sînt formule, atunci:

| A (B C) (A B) (A C);

37
| (A B) C (A C) (B C);

Astfel, forma Skolem conjunctivă trebuie eventual simplificată pentru a ajunge la cea
mai condensată formă de exprimare a formulei.

2.5. Reprezentarea problemei în spaţiul stărilor

Reprezentarea problemei în spaţiul stărilor presupune luarea în considerare a stărilor şi


transformărilor acestora datorate unui număr finit de operatori. Reprezentarea se realizează
prin tripletul
P= ( S, G, R) în care S- reprezintă mulţimea stărilor
G S mulţimea obiectivelor problemei
R S X S mulţimea de transformări de stare care indică un drum în “graful
problemei”
Se spune că secvenţa de stări (s0, s1, … , sn) formează un drum în graf dacă sisi+1 R
( ) i= 0,n , iar n-uplul (s0, s1, … , sn) reprezintă o soluţie a problemei pentru s0 dacă sn G.
Cunoaşterea despre problemă este definită prin:
- mulţimea obiectivelor abstracte ale problemei;
- mulţimea de operatori;
- starea iniţială;
- starea final;
- starea finală formată din stări ce reprezintă obiectivul problemei
Se defineşte obiectivul problemei, ca o structură simbolică ce reprezintă o stare de
lucruri care odată atinsă confirmă faptul că drumul ce a fost parcurs de la starea iniţială prin
graful problemei este o soluţie. Pot fi stabilite câteva obiective în procesul rezolvării, şi
anume:
- parcurgerea înainte în spaţiul stărilor cu scopul atingerii obiectivului
- parcurgerea înapoi având ca scop revenirea la punctele anterioare pentru
comutarea procesului de rezolvare pe o alternativă de drum
Informaţia de stare conţine acele elemente ale cunoaşterii prin care:
- se asigură tranziţia de la o stare la alta, înainte şi înapoi;
- se asigură informaţia de acces la memorie pentru oricare din stările curente;
- se asigură informaţia de revenire pentru refacerea stării sistemului în punctele de
ramificaţie importante ale grafului şi selectarea unei alternative în caz de eşec;
- se asigură informaţia de acces la alte trasee ale grafului în situaţia prelucrărilor
paralele;
- păstrarea informaţiilor de justificare a paşilor sistemului de rezolvare
Prin spaţiul stărilor se înţelege o mulţime finită de obiecte implicate în rezolvarea
problemei pornind de la starea iniţială s0 prin aplicarea unui număr finit de operatori.
Aplicarea unui operator asupra unei stări are ca efect producerea unei stări noi sau a unui
număr finit de stări alternative. Rezolvarea presupune căutarea în spaţiul stărilor a unei stări
ce corespunde obiectivului problemei. Parcurgerea grafului de la starea iniţială s 0 la starea
finală sn se face prin alegerea unui drum dintr-un număr finit de alternative. În acest proces de
parcurgere este cunoscut criteriul de apreciere a obiectivului fără a se cunoaşte ordinea de
aplicare a operatorilor sau lungimea drumului de parcurs.
Modul de reprezentare în spaţiul stărilor se face pe baza unei structuri arborescente.
Aceasta ridică următoarele probleme de rezolvat:

38
- definirea unor reguli restrictive pentru procesul generator de stări având ca scop
eliminarea stărilor redundante, a celor care se depărtează de soluţie, a
combinaţiilor absurde ce nu conduc la soluţie;
- definirea unor strategii de căutare a soluţiei în spaţiul generat;
- definirea unor strategii de revenire în caz de eşec;
- alegerea unei reprezentări compacte ca spaţiu de memorie ocupat;
Se prezintă în continuare problema traversării râului (paragraful 2.4) pentru a cărei
rezolvare se va utiliza spaţiul stărilor. Notând cu S şi D stările parţiale ale problemei ce
reprezintă situaţia pe cele două maluri, stâng şi respectiv drept, se obţine starea ca o reuniune
a celor două “stări potenţiale” S D.

Starea iniţială: S0= { c1, c2, e1, e2, …. , en, b}


D0=
Starea finală: Sf={ c1, c2, b}
Df={ e1, e2, …. , en}
Operatori: Tcd - un copil traversează cu barca pe malul drept
{cj, b} si j=1,2;
T2cd - doi copii traversează cu barca pe malul drept
{ c1, c2, b} si
Ted- un excursionist traversează cu barca pe malul drept
{ej, b} si j=1, n;
Tcs - un copil traversează cu barca pe malul stâng
{cj, b} di j=1,2;
T2cs - doi copii traversează cu barca pe malul stâng
{ c1, c2, b} di
Tes -un excursionist traversează cu barca pe malul stâng
{ej, b} di j=1, n;

Prin aplicarea operatorilor definiţi mai înainte se poate genera spaţiul stărilor, spaţiul
în care prima stare este starea iniţială. Modul de formare a arborelui asociat problemei de
traversare a râului pentru primele trei nivele este următorul:

39
Graful de tranziţie a stărilor cu punctul de plecare starea iniţială are ramuri ce duc la
obiectivul final, operatorii ce conduc la stări redundante fiind eliminate. Soluţia problemei
poate fi privită fie ca o succesiune de stări, fie ca o secvenţă a operatorilor ce conduc la starea
obiectiv. Furnizarea soluţiei ca o secvenţă de operatori ce conduce la obiectiv va da:

O={T2cd, Tcs, Ted, Tcs, T2cd, Tcs, Ted, Tcs, T2cd, …}

În care secvenţa O’’={ T2cd, Tcs, Ted, Tcs} se repetă de un număr egal cu numărul
excursioniştilor.
Din analiza reprezentării în spaţiul stărilor se observă o asemănare între aceasta şi
reprezentarea sistemelor de producţie. Altfel, un operator se aplică numai dacă anumite
criterii prestabilite sînt îndeplinite de starea asupra căreia se aplică (echivalenţă cu
precondiţia), rezultatul aplicării operatorului fiind obţinerea unei stări noi din cea veche
(echivalentul acţiunii sau producţiei). Strategia de control este cea care determină selectarea
operatorilor (regulilor de producţie) şi a modului de aplicare succesivă a acestora pentru
generarea spaţiului stărilor.
Aplicarea unui operator asupra unei stări fără a putea reveni la starea anterioară pentru
a apela un alt operator formează strategia de control irevocabilă. Strategia de control se
numeşte tentativă dacă la un anumit punct se poate lua decizia de revenire la o stare
precedentă în vederea aplicării de noi operatori. Strategia de control cu revenire
(backtracking) este acea strategie prin care punctul de reluare este stabilit din momentul
selectării operatorului, aşa că în caz de eşec se poate relua procesul de la un altfel de punct, nu
neapărat cel mai apropiat. Strategia de control prin căutare în grafuri este cea prin care se
păstrează informaţii privind consecinţele aplicării operatorilor la fiecare pas al generării.

40
2.6. Utilizarea grafurilor ŞI/SAU

Aplicarea strategiilor de rezolvare reductive asupra unei probleme P0 porneşte de la


următoarele precizări:
- descrierea problemei iniţiale P0 exprimată în spaţiul stărilor prin starea iniţială P0;
- precizarea unei mulţimi finite de operatori care aplicaţi asupra problemei produc o
mulţime finită de subprobleme;
- precizarea mulţimii finite a problemei primitive Pp ce sînt echivalente cu stările
finale în spaţiul stărilor.

Un graf orientat ŞI/SAU are următoarele caracteristici:


- fiecare nod reprezintă o problemă sau o subproblemă;
- nodul iniţial reprezintă problema P0 ce trebuie rezolvată, nodurile finale reprezintă
probleme primitive cu rezolvare cunoscută, nodurile intermediare reprezentând
probleme reduse;
- nodul iniţial este un nod neterminal;
- un arc reprezintă un operator de reducere a problemei în subprobleme;
- nodurile neterminale pot fi noduri SI cu succesori reprezentând probleme ce
trebuiesc rezolvate pentru a se da o soluţie nodului predecesor iar nodurile SAU au
succesori probleme alternative din care numai una este suficientă pentru a da o
soluţie nodului predecesor.

Procesul de rezolvare a unei probleme propuse, după generarea grafului SI/SAU al


reducerii problemei, căutarea în acest graf a condiţiilor necesare şi suficiente pentru ca nodul
iniţial, reprezentând problema dată, să fie solvabil.

Un nod este solvabil dacă este îndeplinită cel puţin una din condiţiile:
- nodul considerat reprezintă o problemă primitivă (terminal);
- nodul considerat este un nod terminal de tip SI, ale cărui noduri succesoare sînt
toate terminale;
- nodul considerat este un nod neterminal de tip SAU, iar cel puţin unu din
succesorii săi este solvabil;

Subgraful conţinând nodurile solvabile ale unui graf ŞI/SAU care reprezintă reducerea
unei probleme, în care este conţinut şi nodul iniţial, demonstrează solvabilitatea problemei şi,
de aceea, este denumit graful soluţiei.
Riguros, f (P, L, f, b) un graf orientat cu mulţimea nodurilor D, mulţimea arcelor L, f -
funcţia de înaintare şi b- funcţia de revenire, evident f, b: L D. Se spune că un graf este un
arbore dacă sînt îndeplinite condiţiile:
1) Graful nu are circularităţi
2) Există un nod p, numit şi rădăcină, pentru care f: L D-{p}.

Arborii în aplicaţiile de IA sînt reprezentaţi cu rădăcina sus şi arcele orientate în jos.


Frunzele arborelui sînt acele noduri q din P de la care nu pornesc arce spre alte noduri.
Caracterizarea cea mai uzuală a adâncimii unui nod într-un arbore este nivelul nodului.
Subsetul P1 al punctelor f(xi) din P pentru care

b(x1) = b(x2) =……. = b(xn) = p constituie nivelul 1. Atunci:


P1={f(x1), f(x2), … , f(xi)}

41
Setul Pk al punctelor nivelului k este definit succesiv funcţie de nivelul k-1. Altfel,
dacă b(xi) Pk-1, pentru i=1, 2, … , j atunci:
Pk ={ f(xi); i= 1, 2, … ,j}
Evident, pentru descrierea unei probleme într-un sistem de calcul, este suficient să se descrie
într-un mod riguros cvadruplul ( P, L, f, b) asociat problemei.

2.6.1. Rezolvarea problemelor prin decompoziţie

O strategie de rezolvare a problemelor porneşte de la descompunerea acestora în


probleme mai simple numite şi subprobleme. Dacă problema poate fi descompusă în
subprobleme, spaţiul stărilor poate fi reprezentat prin grafuri ŞI/SAU, şi pot fi aplicate
metodele de căutare specifice pentru grafuri ŞI/SAU, metode ce include căutarea prin
minimizarea costului, precum şi metode de căutare euristică. Jocurile sînt probleme tipice
reprezentate prin grafuri ŞI/SAU aşa că o strategie mutare într-un joc este de fapt redusă la o
căutare în graf.
Fie f(n) costul atingerii simbolului terminal de la nodul n. Dacă se cosideră că n este
rezolvat prin nodurile fiu n1, n2, … , nm se obţine:
f(n) = max {f(n1), f(n2), … , f(nm)}
Dacă regulile nu sînt aplicate în paralel se obţine pentru costul nodului:
f(n) = f(n1) + f(n2) + … +f(nm) = f(ni)
Cele două relaţii sînt exemple tipice pentru calculul costului atunci când o problemă
este descompusă. Una sau alta din aceste formule este practic utilizată la orice problemă.
La problemele reprezentate în spaţiul stărilor este suficient ca un singur nod soluţie să
fie atins, pe când la grafurile ŞI/SAU procesul descompunerii desface problema în
subprobleme.
Pentru rezolvarea problemei corespunzătoare nodului părinte al nodurilor ŞI, trebuiesc
rezolvate toate subproblemele corespunzînd nodului fiu ale acestuia. În reprezentarea unui
graf ŞI/SAU, nodurile ŞI se vor marca prin arce, nodurile nemarcate fiind noduri SAU. Un
graf parţial este numit graf rezolvent, iar rezolvarea unei probleme reprezentată prin grafuri
ŞI/SAU invocă găsirea tuturor grafurilor rezolvente ale acestuia.
În figura care urmează este prezentată o problemă complexă A ce poate fi rezolvată
prin descompunerea în subproblemele B şi C sau prin rezolvarea lui D. În graful respectiv se
regăsesc ambele tipuri de noduri pentru acelaşi părinte.
Se poate introduce un nod suplimentar, pentru separarea nodurilor ŞI/SAU, pentru
care funcţia de cost este egală cu cea de descompunere a problemei A în subproblema M
formată din B şi C.

Un nod într-un arbore ŞI/SAU poate fi un nod ŞI al unui nod părinte dat şi în acelaşi
timp un nod SAU al altui nod părinte. Ca urmare, este necesar să se identifice relaţia părinte-
fiu. Vom utiliza expresiile “ni este un nod ŞI al nodului n “ sau ”nodul ni al lui n este un nod
ŞI“.
42
2.7. Aplicaţii – modul 1.

A. Exerciţii rezolvate.

Exerciţiul 1.
Să se reprezinte în limbajul calculului cu predicate de ordinul întâi următoarea frază din
limbajul natural:

„ÎN FIECARE CIRC EXISTĂ UN CLOVN CARE FACE PE TOŢI SPECTATORII


SĂ RÂDĂ“.

Rezolvare:
Puterea de reprezentare a cunoaşterii, pe care o au formulele limbajului calculului
propoziţional de ordinul I se poate cel mai bine aprecia prin considerarea unor exemple
complexe în care este folosită şi forma clauzală care reprezintă un concept nou numit
programare logică, care stă la baza limbajului de programare PROLOG.

Reprezentarea ar putea fi:


( )x (CIRC (x) ( ) y CLOVN (y, x) ( )z (SPECTATOR (z, x) RÂDE (z, y))).

Menţionăm că poate exista şi alte variante de reprezentare a aceleiaşi fraze. În unele


situaţii cunoaşterea se poate realiza mai bine prin negarea unor predicate.

Exerciţiul 2.
Să se reprezinte în limbajul calculului cu predicate de ordinul întâi, folosind forma
clauzală, următoarea frază din limbajul natural:

„PINGUINUL ARE ARIPI, PENE DAR NU ZBOARĂ CI ÎNOATĂ.“

Rezolvare:
Forma de reprezentare numită şi clauză este :

( )x PASĂRE (x) ( ZBOARĂ (x)) ÎNOATĂ(x) PINGUIN (x).

Cu ajutorul formelor clauzale, a formulelor calculelor cu predicate de ordinul I se


realizează un format simplu şi unitar pentru toate categoriile de constituente ale cunoaşterii:
obiecte, funcţii, relaţii, reguli de inferenţă.
Putem exprima într–o formă compactă caracteristicele structurale ale avionului
folosind forma clauzală.

( )x ARE (x, FUSELAJ) ARE (x, ARIPA) ARE (x, SISTEM–PROPULSIE)


ARE (x, SISTEM–COMANDĂ) ARE (x, SISTEM–RULARE) AVION (x).

Această formă clauzală se poate reprezenta uşor într-un program PROLOG.

43
Exerciţiul 3. Să se reprezinte sub forma unor liste LISP piesa de cunoaştere din
exemplul dat în paragraful 1.1.4.1., folosind şi reprezentarea sub formă de reşea semantică din
acel paragraf:
“LA SUSŢINEREA TEZEI DE DOCTORAT DE CĂTRE ION CARE ESTE
UN BUN SPECIALIST, COLEGUL SĂU VASILE ÎI OFERĂ UN FRUMOS
CADOU.”
Rezolvare:
Singurul nod sursă din reprezentare este <Eveniment2> ce poate fi considerat nod
iniţial, lista pornind descrierea de la acest nod:

(Eveniment_2 este susţinerea tezei)


(Eveniment_2 referitor ION)
(ION este OM)
(ION calitate specialist)
(ION coleg VASILE)
(VASILE este OM)
(Eveniment_2 cauzează Eveniment_1)
(Eveniment_1 acţiune oferă)
(Eveniment_1 obiect cadou)
(Cadou calitate frumos)
(Eveniment_1 receptor ION)
(Eveniment_1 agent VASILE).

O altă modalitate de reprezentare a reţelei constă în construirea conceptului pentru


fiecare nod sursă şi asocierea acestuia cu perechi (<relaţie> <nod destinaţie>).

((Eveniment_2 (este susţinerea tezei)


(referitor ION)
(cauzează Eveniment_1))
(ION (este OM))
(calitate specialist)
(coleg VASILE)
(VASILE (este OM))
((Eveniment_1 (acţiune oferă)
(obiect cadou)
(receptor ION)
(agent VASILE)
((Cadou (calitate frumos)).

Metoda are avantajul eliminării redundanţelor ce apar la specificarea nodului sursă în


toate tripletele ce descriu relaţiile sale cu nodurile destinaţie.

Exerciţiul 4.
Să se reprezinte sub forma unei reţele semantice sortate, folosind relaţiile cauzale
definite în paragraful 1.1.4.2., următoarea piesă de cunoaştere:

“DIMINEAŢA, LA PIAŢĂ, ION CUMPĂRĂ CU BANI FLORI PENTRU MARIA”.

44
Rezolvare:
Reţeaua semantică sortată, folosind relaţiile cauzale definite în paragraful 1.1.4.2., este
următoarea:

P
PREDICAŢIE
TIMP

AGENT
RECEPTOR LOC
INSTRUMENT
OBIECT

CUMPĂRĂ ION MARIA FLORI BANI PIAŢĂ DIMINEAŢA


MARIA

Exerciţiul 5.
Să se descrie reprezentarea unei universităţi cu profil tehnic cu ajutorul cadrelor,
folosind forme cadru specifice de descriere (paragraful 1.1.5.).

Rezolvare:
Iată o variantă de descriere:

cadru: universitate tehnică


forma: generalizare
faţeta: institut de învăţământ superior
forma: specializare
faţeta: pregătire tehnică
forma: apartenenţă
faţeta: universitate
forma: adresa
faţeta: strada
faţeta: număr
faţeta: cod poştal
faţeta: oraş
faţeta: ţara
forma: compoziţie
faţeta: conducere
valoarea: rector
valoarea: prorector
faţeta: compartimente
valoarea: electric
valoarea: mecanic
valoarea: chimic
forma: proprietăţi
faţeta: pregătire
valoare: curs de zi
valoare: curs seral

Piesele de cunoaştere satisfac definiţia cadrelor.


45
B. Test de autocontrol

1. Când exprimăm că “George îşi iubeşte câinele” presupunem implicit că George are un
singur câine? Cum am putea reexprima aceasta dacă am dori să spunem că George îşi
iubeşte toţi câinii săi? Aceasta ar fi adevărată dacă George nu are şi alţi câini?

2. Traduceţi următoarele propoziţii în logica de ordinul întâi:


a) Toma este mai scund decât Carmen.
b) Carmen este mai înaltă decât Toma.
c) Aici nu este nimeni mai înalt decât Victor.
d) Atât Carmen cât şi Elena sunt mai înalte decât Toma.
e) Pentru orice x şi y, dacă x este mai înalt decât y, atunci y este mai scund decât x.
f) Mai “scund decât” este tranzitivă.

3. Traduceţi propoziţiile următoare în logica de ordinul întâi:


a) Poţi păcăli câţiva oameni întotdeauna, şi toţi oamenii câtva timp, dar nu poţi păcăli
toţi oamenii întotdeauna.
b) Un măr pe zi ţine doctorul departe.

4. Traduceţi următoarele propoziţii din logica de ordinul întâi în limba română:


a) x.succes(Toma,x) a_avut(x,George)
b) x.succes(Toma,x) folosit(Toma,George)
c) Este posibil să traduceţi aceste două propoziţii într-o singură propoziţie în limba
română? Justificaţi răspunsul.

B. Temă de control

Exerciţiul 1.
Să se reprezinte cu ajutorul regulilor de producţie următoarea piesă de cunoaştere:

IF : rezultatul testului de citire-scriere este eronat, bitul 2 blocat în 1


(and) se manifestă la circuitul M1
(and) circuitul M2 funcţionează corect
THEN : circuitul M1 este defect
(and) reparare prin înlocuire.

Exerciţiul 2.
Să se reprezinte cu ajutorul cadrelor următoarea piesă de cunoaştere:

IF : rezultatul testului de citire-scriere este eronat, bitul 2 blocat în 1


(and) se manifestă la circuitul M1
(and) circuitul M2 funcţionează corect
THEN : circuitul M1 este defect
(and) reparare prin înlocuire.

46
Exerciţiul 3.
Pe malul unui râu sunt trei misionari şi trei canibali. Există o singură barcă
disponibilă care poate transporta două persoane şi pe care vor s-o folosească pentru a
traversa râul. Dacă numărul canibalilor depăşeşte numărul misionarilor pe unul din malurile
râului (incluzând şi ocupanţii bărcii), misionarii vor fi mâncaţi. Cum poate fi utilizată barca
pentru a transporta în siguranţă toţi misionarii şi canibalii dincolo de râu?

Rezolvaţi problema prezentând sistemului rezolutiv următoarele grupări de simboluri:


- suportul obiectual ;
- simboluri funcţionale sau simboluri predicative ;
- faptele;
- obiectivul problemei.

Indicaţie: Urmăriţi rezolvarea exemplului din paragraful 2.4.

Exerciţiul 4.
Pe malul unui râu sunt trei misionari şi trei canibali. Există o singură barcă
disponibilă care poate transporta două persoane şi pe care vor s-o folosească pentru a
traversa râul. Dacă numărul canibalilor depăşeşte numărul misionarilor pe unul din malurile
râului (incluzând şi ocupanţii bărcii), misionarii vor fi mâncaţi. Cum poate fi utilizată barca
pentru a transporta în siguranţă toţi misionarii şi canibalii dincolo de râu?
Rezolvaţi problema folosind spaţiul stărilor pe baza unei structuri arborescente.
Indicaţie: Modul de formare a arborelui asociat problemei de traversare a râului de
către misionari şi canibali poate fi vazut ăn exemplul din paragraful 2.5.

2.8.BIBLIOGRAFIE RECOMANDATĂ LA MODULUL 1:


1. Podaru Vasile, Inteligenţă artificială şi siteme expert, Editura Academiei Tehnice Militare,
1997
2. Podaru Vasile, Barnoschi Adriana, Sisteme expert, Editura Academiei Tehnice Militare,
2000, 2004.
3. Ioan Georgescu, Elemente de inteligenţă artificială, Editura Academiei RSR, 1985.
4. Podaru Vasile, Inteligenţă artificială, curs în format electronic, CD-învăţământ la distanţă,
Universitatea Titu Maiorescu, 2010.
5. D. Cîrstoiu, Sisteme expert, edira ALL, 1994.
6. SICSTUS PROLOG USER’S MANUAL. Intelligent Systems Laboratory, Sweedish Institute
of Computer Science:
http://www.sics.se/isl/sicstuswww/site/documentation.html
7. M. Maliţa, Bazele inteligenţei artificiale, editura Academiei Române, 1988.

Coordonator disciplină:
Prof. univ. dr. Vasile PODARU, email: podaruv@gmail.com

Tutori: Prof. univ. dr. Vasile PODARU.

47
UNIVERSITATEA TITU MAIORESCU
Facultatea de INFORMATICĂ

Prof. univ. dr.


VASILE PODARU

Curs pentru învăţământul la distanţă

BUCUREŞTI – 2011
UNIVERSITATEA Titu MAIORESCU Bucureşti
Facultatea de Informatică
Învăţământ la Distanţă

INTELIGENŢĂ ARTIFICIALĂ
Inteligenţa artificială este una din disciplinele de pregătire fundamentală care, pentru
profilul INFORMATICĂ, este esenţială pentru pregătirea studenţilor şi pentru obţinerea
creditelor transferabile prin procedurile de evaluare. Modul de prezentare a acestui material
are în vedere particularităţile învăţământului la distanţă, la care studiul individual este
determinant. Pentru orice nelămuriri faţă de acest material vă rugăm să contactaţi tutorele de
disciplină care are datoria să vă ajute oferindu-vă toate explicaţiile necesare.
Disciplina de Inteligenţa artificială îşi propune următoarele obiective specifice:
Însuşirea noţiunilor fundamentale din domeniile Inteligenţei artificiale.
Formarea deprinderilor de modelare matematică şi de transpunere în programare a
unor probleme de natură tehnică, socială sau economică, cu utilizarea cunoştinţelor
însuşite.
Formarea şi dezvoltarea aptitudinilor şi deprinderilor de analiză logică, formulare
corectă şi argumentare fundamentată, în rezolvarea problemelor tehnico-economice şi
de specialitatecu cu utilizarea cunoştinţelor însuşite prin intermediul metodelor şi
modelelor specifice inteligenţei artificiale;
Insusirea principiilor generale ale programarii logice si insusirea limbajului Prolog;
O comparaţie critică a metodelor de rezolvare evidenţiind, eventual, calea optimă de
soluţionare.
Accentul se va pune pe problemele de cautare si reprezentare a cunostintelor si
respectiv pe programarea logica, limbajul de programare utilizat la laborator fiind
limbajul Prolog. Cursul trebuie sa trateze aspecte ale rezolvarii problemelor prin
intermediul cautarii, descriind cele mai importante tehnici de cautare informata si
neinformata. Se vor da exmple de aplicatii ale cautarii, cum ar fi jocurile, tratate ca
probleme de cautare. Se vor prezenta principalele tipuri de cunostinte si principalele
metode de reprezentare a cunostintelor. Se va face legatura dintre reprezentarea
cunostintelor si sistemele expert. Se va da un exemplu de sistem expert cu
implementare in Prolog. Vor mai fi tratate, ca modalitati de reprezentare a
cunostintelor, retelele semantice si retelele Bayesiene (cu introducerea rationamentului
statistic).

Vă precizăm de asemenea că, din punct de vedere al verificărilor şi al notării


(elemente ce vor fi comunicate şi prin fişa disciplinei, calendarul disciplinei şi programarea
orară), cu adevărat importantă este capacitatea pe care trebuie să o dobândiţi şi să o probaţi de
a rezolva toată tipologia de probleme aplicative aferente materialului teoretic prezentat în
continuare. De aceea vă recomandăm să parcurgeţi cu atenţie toate aplicaţiile rezolvate, să
rezolvaţi aplicaţiile propuse prin testele de autoevaluare şi temele de control (pentru fiecare
modul în parte trebuie să predaţi tutorelui de disciplină rezolvarea acestor teme, pentru
verificare şi evaluare); fiţi convinşi că examenul final apelează la tipurile de aplicaţii prezente
în secţiunile menţionate anterior.
Timpul mediu necesar însuşirii noţiunilor teoretice, formării deprinderilor de calcul şi
utilizării metodelor de rezolvare a problemelor specifice acestui modul este estimat la
aproximativ 6-8 ore pentru întregul modul , într-un ritm de 3-4 ore pentru fiecare din cele
două unităţi ale modulului.

49
Întru-cât modulul este privit ca un tot unitar exerciţiile aferente acestui modul se
găsesc la sfârşitul acestui modul. La terminarea parcurgerii acestui modul studenţii trebuie să
prezinte tutorelui de disciplină rezolvarea temei de control propusă spre rezolvare la sfîrşitul
modulului.
Cursul se finalizează prin examen care constă din:
1) o lucrare scrisă sub forma de text grila constând din 9-18 subiecte (ponderea lucrării
scrise este de 70% din nota finală);
2) rezolvarea corectă a temelor de control din cele 4 module (minimum nota 5 pentru
fiecare temă, ponderea mediei celor 5 note în nota finală este de 20%);
3) participarea activă la activităţile tutoriale (apreciată printr-o notă a cărei pondere in
nota finală este de 10%).

Coordonator disciplină: Prof. univ. dr. Vasile PODARU, email: podaruv@gmail.com


Tutori: Prof. univ. dr. Vasile PODARU,

50
MODULUL 2

METODE DE CĂUTARE

Îndrumări metodice.

Inteligenţa artificială a apărut ca disciplină şi a fost fundamentată pe investigaţiile


relative la reprezentarea cunoaşterii şi căutarea.
În acest modul sunt prezentate principalele metode de căutare utilizate în rezolvarea
problemelor, esenţiale în domeniul inteligenţei artificiale.
Rezolvarea problemelor poate fi restrânsă de obicei la reprezentarea cunoaşterii şi la
căutare. Unele probleme scot în evidenţă căutarea şi altele reprezentarea cunoaşterii, dar
multe din problemele de inteligenţă artificială pot fi reduse la una sau la cealaltă.
După cum s-a arătat o problemă reprezentată în spaţiul stărilor conduce la o rezolvare
ce se reduce la căutarea în spaţiul stărilor. Alegerea tehnicii de rezolvare este dependentă de
tipul problemei, mai multe tehnici fiind posibil a fi aplicate. Cea mai simplă tehnică este cea
de selecţie a operatorilor ,, trial-and-error process”, tehnică ce nu este întotdeauna viabilă
deoarece nu oferă o căutare sistematică în spaţiul stărilor. O altă soluţie este cea a atingerii
costului minim, iar în situaţia în care costul atingerii obiectivului poate fi predictat, timpul de
căutare este corespunzător scurtat prin utilizarea acestei informaţii. În cele ce urmează se vor
analiza o parte dintre posibilii algoritmi de căutare.
În prima parte a acestui modul sunt prezentate informaţii referitoare la metodele de
bază în căutare.
În partea a doua a acestui modul se prezintă metode avansate de căutare utilizând şi
problematica rezolvării problemelor cu ajutorul grafurilor. Timpul mediu necesar însuşirii
noţiunilor teoretice, formării deprinderilor de calcul şi utilizării metodelor de căutare specifice
acestui modul este estimat la aproximativ 6-8 ore pentru întregul modul , într-un ritm de 3-4
ore pentru fiecare din cele două unităţi ale modulului.
Întru-cât modulul este privit ca un tot unitar exerciţiile aferente acestui modul se
găsesc la sfârşitul acestui modul. La terminarea parcurgerii acestui modul studenţii trebuie să
prezinte tutorelui de disciplină rezolvarea temei de control propusă spre rezolvare la sfîrşitul
modulului.
Cursul se finalizează prin examen care constă din:
1) o lucrare scrisă sub forma de text grila constând din 9-18 subiecte (ponderea lucrării
scrise este de 70% din nota finală);
2) rezolvarea corectă a temelor de control din cele 5 module (minimum nota 5 pentru
fiecare temă, ponderea mediei celor 5 note în nota finală este de 20%);
3) participarea activă la activităţile tutoriale (apreciată printr-o notă a cărei pondere in
nota finală este de 10%).

51
Unitatea de învăţare nr.3

Metode de bază în căutare.


Cuprins:
3.1. Metode de căutare ...................................................................................... pag. 52
3.2. Căutarea. Generalităţi. ............................................................................... pag. 52
3.2.1. Căutarea oarbă ....................................................................................... pag. 54
3.2.2. Căutarea euristică ................................................................................... pag. 57
3.2.3. Analiza metodei de căutare pe orizontală sau în lăţime .......................... pag. 58
3.2.4. Analiza metodei de căutare pe verticală sau în adâncime ....................... pag. 60
3.2.5. Adâncimea iterativă ................................................................................ pag. 63
3.2.6. Lăţimea iterativă ..................................................................................... pag. 66
3.3. Metode extinse de căutare euristică ........................................................... pag. 67
3.3.1. Metoda gradientului (Hill-climbing method) ......................................... pag. 67
3.3.2. Metoda celei mai bune prime căutări ..................................................... pag. 69
3.3.3. Soluţia optimă când costul poate fi predictat. Algoritmul A ................. pag. 70
3.3.4. Algoritmul A* ........................................................................................ pag. 71
3.3.4.1. Admisibiliutatea .................................................................................. pag.74
3.3.4.2. Extensii şi IDA* ................................................................................. pag.75

3.1. Metode de căutare

Inteligenţa artificială a apărut ca disciplină şi a fost fundamentată pe investigaţiile


relative la reprezentarea cunoaşterii şi căutarea.
Rezolvarea problemelor poate fi restrânsă de obicei la reprezentarea cunoaşterii şi la
căutare. Unele probleme scot în evidenţă căutarea şi altele reprezentarea cunoaşterii, dar
multe din problemele de inteligenţă artificială pot fi reduse la una sau la cealaltă.
3.2 Căutarea. Generalităţi.
Problemele de căutare vor fi descrise uneori folosind diagrame similare cu cea din
figura 3.1.

Figura 3.1 O problemă de căutare


Există un nod iniţial i, de la care începe căutarea, şi un nod ţintă g. Obiectivul este de a
găsi o cale prin spaţiul de căutare între nodul iniţial i şi nodul ţintă g. Spaţiul de căutare nu
este în general memorat în totalitate în calculator; în schimb, sunt disponibile câteva proceduri

52
care acceptă un nod ca intrare şi îi determină succesorii. În figură succesorii nodului iniţial
sunt nodurile c1, c2 şi c3, sunt noduri la care se poate ajunge într-un singur pas plecând de la
nodul i. Astfel intrarea într-o problemă de căutare reprezintă o descriere a nodului iniţial, a
nodului ţintă şi a unei proceduri care furnizează succesorii unui nod oarecare; ieşirea trebuie
să fie o secvenţă legală de noduri începând cu nodul iniţial dat şi terminând cu nodul ţintă.

d=0

..............

P A T M A T B O S
d=1

.......... .........

P A T
O d=2
P

Figura 3.2 Problema cuvintelor încrucişate


Abordarea "cuvânt cu cuvânt"

Un alt exemplu este cel al spaţiului de căutare implicat în problema cuvintelor


încrucişate este prezentată în figura 3.2. Un nod corespunde unui careu completat parţial;
descrierea din figură corespunde modului de abordare în care careul este completat "cuvânt cu
cuvânt". Figura 3.3 prezintă o porţiune a spaţiului de căutare care utilizează modul de
abordare "literă cu literă". În acest caz, vor fi mai multe noduri ţintă - orice careu completat
este acceptabil.

Figura 3.3 Problema cuvintelor încrucişate


Abordarea "literă cu literă"

53
Există de asemenea probleme de căutare cu mai multe noduri iniţiale; să considerăm o
problemă în există un grup de careuri şi trebuie completat unul dintre ele. În astfel de
probleme cu mai multe noduri ţintă şi mai multe noduri iniţiale, obiectivul poate fi să se
găsească o cale de la un nod iniţial la un nod ţintă (ca în problema cuvintelor încrucişate), să
se găsească toate căile sau să se găsească cea mai bună cale.
În problemele de căutare din exemplele anterioare s-a etichetat fiecare nod cu o
adâncime care indică numărul de paşi necesari pentru a ajunge la acel nod iniţial. Deci, nodul
ţintă din figura 3.1 este de adâncime 3; spaţiul său de căutare este de adâncime 4. În căutarea
din figura 3.2, toate nodurile ţintă sunt de adâncime 4, pentru că sunt patru cuvinte de
completat în careu. În plus, fiecare nod de adâncime 4 este un nod ţintă.
Problemele de căutare sunt adesea descrise pe baza factorului lor de ramificare. Acesta
se referă la numărul de fii pe care îi are un nod care nu este terminal. În figura 3.1, factorul de
ramificare variază între 1 şi 3.
Factorul de ramificare în problema cuvintelor încrucişate este mult mai mare;
considerăm nodul iniţial din figura 3.3. Sunt 8 pătrate de completat şi 26 de litere care pot fi
puse în fiecare pătrat, astfel că factorul de ramificare pentru nodul iniţial este 8*26=208.
Fiecare din cele 208 noduri de adâncime 1 au 7*26=182 succesori, şi aşa mai departe. Nu
toate nodurile de adâncime 2 au 6*26 succesori pentru că unii dintre ei ar include cuvinte
complete, ceea ce este ilegal. Factorul de ramificare în această problemă variază de la un nod
la altul, dar evident este mai mare decât cel din figura 3.1. Deoarece sunt mai mult de 26 de
alegeri posibile pentru plasarea unui cuvânt corect în careu, factorul de ramificare pentru
figura 3.2 este şi mai mare. Cu excepţia numărului mare de noduri care trebuiesc de obicei
explorate, rezolvarea problemelor de căutare este uşoară. Presupunând că factorul de
ramificare este un număr finit, se poate aplica următoarea procedură.

PROCEDURA 3.2.1 Pentru rezolvarea unei probleme de căutare:


1. Setează lista L de noduri la nodurile iniţiale din problemă. În orice moment, L este
o listă de noduri care nu au fost încă examinate de program.
2. Dacă lista L este goală, eşec. Altfel, alege un nod n din lista L.
3. Dacă n este un nod ţintă, procedura se termină returnând valoarea n şi calea de la
nodul iniţial până la acesta.
4. Altfel, scoate nodul n din lista L şi adaugă în listă toţi fii acestuia, etichetându-l pe
fiecare cu calea de la nodul iniţial până la el. Revenire la pasul 2.

Această procedură, verifică nodurile pentru a vedea dacă sunt soluţii ale problemei
iniţiale de căutare din momentul în care sunt expandate pentru a genera fii.
Cu excepţia unor modificări nesemnificative a procedurii 3.2.1 prezentată anterior,
toate programele de căutare vor folosii o tehnică asemănătoare ca cea din procedura 3.2.1.
Ceea ce distinge un algoritm de căutare de altul este alegerea făcută la pasul 2 - cum alegem
nodul care va fi expandat în continuare.
Aşa cum se va vedea în cele ce urmează, există două modalităţi prin care se poate face
această alegere. În tehnica de căutare oarbă alegerea este făcută într-un mod dependent doar
de poziţia nodului în arborele de căutare. În căutarea euristică, astfel de informaţii sunt
folosite pentru a decide ce trebuie făcut la următorul pas.

3.2.1 Căutarea oarbă

Există o mare varietate de tehnici de căutare oarbă; vom prezenta două dintre ele în
acest paragraf . Cele două tehnici pe care le vom prezenta în continuare sunt căutarea pe
verticală şi căutarea pe orizontală.

54
Figura 3.4 Căutarea pe verticală
Căutarea pe verticală constă în expandarea arborelui de căutare (de exemplu cel din
figura 3.1) în aşa fel încât nodurile terminale să fie examinate de la stânga la dreapta, aşa cum
este prezentat în figura 3.4. Se explorează întotdeauna un fiu al nodului cel mai recent
expandat; dacă acesta nu are fii, procedura revine la pasul anterior înainte de a alege un alt
nod pentru a-l examina. Căutarea se termină când a fost selectat nodul ţintă g.
Căutarea pe verticală poate fi implementată prin inserarea fiilor unui nod dat la
începutul listei L la pasul 4 al procedurii 3.2.1, şi alegerea întotdeauna a primului nod din listă
ca fiind un nod ce trebuie expandat.
PROCEDURA 3.2.2 Căutarea pe verticală.
(Pentru rezolvarea unei probleme folosind căutarea pe verticală):
1. Setează lista L de noduri la nodurile iniţiale din problemă.
2. Fie n primul nod din lista L. Dacă lista L este goală, eşec.
3. Dacă n este un nod ţintă, procedura se termină returnând valoarea n şi calea
de la nodul iniţial până la acesta.
4. Altfel, scoate nodul n din lista L şi adaugă la începutul acesteia toţi fii nodului
n, etichetându-l pe fiecare cu calea de la nodul iniţial până la el. Revenire le
pasul 2.
În căutarea pe orizontală, arborele de căutare este expandat de sus în jos, astfel încât
fiecare nod de adâncime d este examinat înaintea oricărui nod de adâncime d+1. Figura 3.5
prezintă arborele din figura 3.1 indicând ordinea de examinare a nodurilor folosind tehnica de
căutare pe orizontală.

Figura 3.5 Căutarea pe orizontală

55
Se poate implementa această tehnică prin adăugarea nodurilor noi la sfârşitul listei L.
Procedura 3.2.2 se va modifica astfel:
PROCEDURA 3.2.3 Căutarea pe orizontală.
(Pentru rezolvarea unei probleme folosind căutarea pe orizontală):

1. Setează lista L de noduri la nodurile iniţiale din problemă.


2. Fie n primul nod din lista L. Dacă lista L este goală, eşec.
3. Dacă n este un nod ţintă, procedura se termină returnând valoarea n şi calea de la
nodul iniţial până la acesta.
4. Altfel, scoate nodul n din lista L şi adaugă la sfârşitul acesteia toţi fii nodului n,
etichetându-l pe fiecare cu calea de la nodul iniţial până la el. Revenire le pasul 2.
De reţinut faptul că dacă decidem să executăm o căutare pe verticală într-un arbore,
aceasta nu înseamnă că examinarea nodurilor se va face într-o ordine anume, ci doar ne
asigură că întotdeauna la următorul pas va fi expandat un nod de adâncime mai mare dacă este
posibil. Astfel, o căutare de la dreapta la stânga este de asemenea o căutare pe verticală, aşa
cum este prezentat şi în figura 3.6, unde succesorii fiecărui nod au fost aleşi într-o ordine
aleatoare.

Figura 3.6 O altă căutare pe verticală


În mod similar, dacă decidem să executăm o căutare pe orizontală
într-un arbore ne este permis să alegem oricare dintre nodurile neexplorate de pe un anumit
nivel.
Să examinăm acum cantitatea de memorie necesară pentru fiecare dintre cele două
metode.
La căutarea pe verticală, trebuie să memorăm toate legăturile neexplorate ale oricărui
nod de pe calea de la nodul curent înapoi spre rădăcina arborelui, deoarece vom avea nevoie
de ele pentru examinarea altor porţiuni ale spaţiului de căutare. Ca un exemplu, figura 3.7
prezintă nodurile care trebuiesc reţinute în memorie când examinăm nodul n pe parcursul
căutării pe verticală. Am presupus că fii fiecărui nod sunt examinaţi de la stânga la dreapta.

56
Figura 3.7 Spaţiul necesar pentru căutarea pe verticală

Să considerăm acum căutarea pe orizontală. Înaintea examinării unui nod de adâncime


d+1 trebuie să examinăm (şi să memorăm) toate nodurile de adâncime d; figura 3.8 prezintă
nodurile care trebuiesc memorate imediat înainte de examinarea primului nod de adâncime
d+1.

Figura 3.8 Spaţiul necesar pentru căutarea pe orizontală


Cel puţin din punctul de vedere al cerinţelor de memorie, căutarea pe verticală este de
departe mai eficientă decât contracandidata sa căutarea pe orizontală.
Există şi alte modalităţi în care putem să ajungem la aceeaşi concluzie. Ca un
exemplu, să considerăm o singură iteraţie a ciclului din procedura de căutare de bază. Care
este dimensiunea listei L pe parcursul acestei iteraţii?
Este clar că dimensiunea listei scade cu 1 când nodul n este şters din listă; apoi
dimensiunea acesteia creşte fie cu b (factorul de ramificare al spaţiului de căutare explorat)
dacă nodul n are fii, fie cu zero dacă nodul n este terminal. Astfel dimensiunea listei se
modifică fie cu b-1 dacă nodul n nu este terminal, fie cu -1 dacă acesta este terminal. Rezultă
că o căutare care întâlneşte un nod terminal mai devreme va avea nevoie de mai puţin spaţiu
decât alta care îl întâlneşte mai târziu; deoarece căutarea pe verticală tinde să atingă rapid
nodurile terminale, putem trage concluzia că această metodă necesită mai puţină memorie
decât contracandidata sa căutarea pe orizontală.
3.2.2 Căutarea euristică
În exemplul considerat, nici căutarea pe verticală şi nici căutarea pe orizontală nu
explorează arborele într-o ordine optimă. Să examinăm nodurile în ordinea prezentată în

57
figura 3.9. Prin expandarea nodurilor în această ordine optimă, minimizăm timpul necesar
pentru rezolvarea problemei.

Figura 3.9 O căutare optimală

Căutarea euristică este o încercare de a căuta într-un arbore într-o ordine care este mult
mai aproape din punct de vedere al optimalităţii decât căutarea pe verticală sau pe orizontală.
Când alegem un nod din lista L la pasul 2 al procedurii de căutare, ne mutăm de la nodul
rădăcină spre nodul ţintă prin selectarea întotdeauna a nodului care este cel mai apropiat de
nodul ţintă. În unele domenii este posibil să estimăm distanţa până la nodul ţintă şi să folosim
această informaţie pentru a direcţiona căutarea. Totuşi, este imposibil să executăm căutarea în
arbore într-o ordine optimă ca cea din figura 3.9, adesea putem doar să aproximăm această
ordine.

3.2.3. Analiza metodei de căutare pe orizontală sau în lăţime

Am prezentat pe scurt algoritmii de „căutare pe verticală sau în adâncime” şi „căutarea


pe orizontală sau în lăţime” şi vom examina aceste proceduri în detaliu. O întrebare care apare
este: de câtă memorie şi timp au nevoie aceşti algoritmi?
Pentru simplificarea analizei, presupunem că lucrăm cu un arbore de căutare cu un
factor uniform de ramificare b şi adâncime d, şi că acest arbore are un singur nod ţintă care
are adâncimea d. Un arbore de acest gen cu b=4 şi d=2 apare în figura 3.10. Vom nota nodul
rădăcină cu i, nodurile din nivelul 1 cu n1, n2, n3, şi n4 şi fii lui ni cu ni1, ni2, ni3, şi ni4.
Aşa cum s-a discutat anterior, în căutarea pe orizontală sau în lăţime am văzut lista L a
nodurilor neexpandate ca o coadă, astfel încât noii fii generaţi sunt puşi la sfârşitul acestor
liste şi sunt expandaţi numai după ce nodurile din adâncimea imediată au fost examinate.
Asfel, în timpul primelor iteraţii din procedura 3.2.1., lista L ia valorile următoare:

{i}
{ n1, n2, n3 }
{n2, n3, n4, n11, n12, n13, n14 }
{ n2, n3, n4, n11, n12, n13, n14, n21, n22, n23, n24 }

Ordinea completă pentru căutarea din figura 3.10 este arătată în figura 3.11.

58
Deoarece numărul total de noduri pe nivelul k este bk şi trebuie să memorăm toate
aceste noduri înainte ca primul nod de pe nivelul k +1 să fie examinat, căutarea pe orizontală
sau în lăţime are nevoie la nivelul d de bd-1 spaţiu disponibil pentru a explora un arbore de
căutare ca acela din figura 3.10. De notat că, dacă arborele este examinat în continuare la
nivelul d, atunci va fi necesar mult mai mult spaţiu pentru fiecare generare a succesorilor lui
b. Chiar înainte ca nodul ţintă să fie găsit, L va conţine nodul ţintă şi câteva părţi de la nivelul
d+1din arbore.
i
d=0

n1 n2 n3 n4 d=1

n11 n12 n13 n14 g d=2

Figura 3.10. Spaţiu uniform de căutare

Ce volum de timp este necesar pentru căutarea pe orizontală sau în lăţime? Vom
echivala cantitatea de timp consumată de algoritm cu numărul de noduri examinate de el;
reamintim că un nod este considerat verificat dacă el este un nod ţintă chiar înainte ca nodul
să fie expandat pentru generarea succesorilor şi nu este considerat verificat când nodul însuşi
este adăugat la lista L.
1

2 3 4 5

6 7 8 9 10 11 12 13 14 15 16 17 8 19 20 21

Figura 3.11. Căutarea pe orizontală sau în lăţime

Cum trebuie să atingem ţinta la nivelul d, nodurile interne (care nu sunt marginale)
care pot fi examinate sunt toate nodurile de pe nivelul 0,1,2,3,...,d-1. Numărul unor astfel de
noduri este dat de relaţia:

bd 1
1 b b2 bd 1
(3.1)
b 1
Ce ştim despre nodurile marginale? Nu se poate spune exact câte noduri marginale vor
fi examinate, deoarece nu ştim în care margine este localizat nodul ţintă. Cel mai bun caz ar fi
să putem examina numai un nod marginal (ţinta); cel mai rău caz ar fi dacă ar trebui să
examinăm toate bd noduri. Numărul mediu de noduri examinate la margini este atunci

59
1 bd
(3.2)
2
şi numărul total de noduri examinate este suma dintre (3.1) şi (3.2):

bd 1 bd 1 2b d 2 b d 1 b b d 1
+ = =
b 1 2 2(b 1)
bd 1 bd b 3
(3.3)
2(b 1)

Pentru o adâncime mai mare, (3.3) se reduce la aproximativ bd/2, care este
aproximativ acelaşi cu cantitatea de timp consumată la margini, ceea ce era de aşteptat
deoarece în aceste cazuri, mai mult timp va fi consumat cu căutarea la nivelul cel mai de jos al
arborelui. O versiune grafică a acestei argumentări apare în figura 3.12.

spaţiul =bd-1
întreg de la
nivelul
d-1

marginea
stângă =b d/2

Figura 3.12. Timpul necesar pentru căutarea pe orizontală sau în lăţime

Pe de altă parte dacă b=2 atunci (3.3) se simplifică la

3* 2d 1
2
Acest rezultat se poate deduce şi direct. Dimensiunea arborelui intern este

1 2 2d 1
2d

şi numărul de noduri marginale care trebuie examinate este aproximativ 2 d/2. Suma acestor
două valori este (3/2)*2d.
3.2.4. Analiza metodei de căutare pe verticală sau în adâncime
Dacă L este gândit ca o coadă în căutarea pe orizontală sau în lăţime, în căutarea pe
verticală sau în adâncime L este o stivă. Câteva din primele sale valori pe care le căutăm cu
această metodă în arborele din figura 3.10 sunt:

60
{i}
{ n1, n2, n3, n4}
{ n11, n12, n13, n14, n2, n3, n4}
{ n12, n13, n14, n2, n3, n4 }

Căutarea completă este prezentată în figura 3.13.


1

2 7 12 17

3 4 5 6 8 9 10 11 13 14 15 16 18 19 20 21

Figura 3.13. Căutarea pe verticală sau în adâncime

Spaţiul de memorie necesar accesului pe verticală sau în adâncime este uşor de


calculat. Este nevoie de mult mai multă memorie la primul pas al algoritmului pentru a ajunge
la adâncimea d; de exemplu, nodurile marcate din figura 3.14 vor trebui salvate. În general,
este necesar să stocăm b-1 noduri la fiecare nivel de adâncime (succesorii nodurilor ce vor fi
pregătite pentru a fi expandate), împreună cu un nod adiţional de la adâncimea d (deoarece nu
l-am expandat încă). Astfel spaţiul total necesar este dat de

d (b 1) 1

Figura 3.1 Memoria necesară pentru căutarea pe verticală sau în adâncime

Pentru b fixat, căutarea pe verticală sau în adâncime are nevoie de o cantitate de


memorie care este liniară în d, pe când căutarea pe orizontală sau în lăţime are nevoie de o
cantitate exponenţială în funcţie de adâncimea arborelui de căutare.
Timpul de calcul este mai redus. Să menţionăm că, dacă nodul ţintă se află la o anume
distanţă în partea stângă a arborelui, atunci căutarea pe verticală sau în adâncime se va face
direct la aceasta, examinând un total de d+1 noduri. Dacă nodul ţintă se află la o anume
distanţă în partea dreaptă a arborelui, va fi examinat întreg spaţiul, cu un total de noduri dat de
relaţia:

61
bd 1 1
1 b b2 bd
b 1

Dacă facem media celor două expresii, putem concluziona că numărul de noduri examinate
este în medie:

bd 1
1 b * d d b 1 bd 1
b*d b d 2
= (3.4)
2(b 1) 2(b 1)

Ca şi în cazul căutării pe orizontală sau în lăţime vom examina situaţia într-un mod
mai restrictiv când d este mare şi b=2 . Pentru d mare relaţia 3.4 este:
bd
2

astfel încât lucrul la marginile arborelui continuă să domine calculele (vezi figura 3.15).

= bd/2
Jumătate
din spaţiul
total

Figura 3.15. Timpul necesar pentru căutarea pe verticală sau în adâncime

Să notăm că, atâta timp cât termenul bd-1/2 apare în căutarea pe orizontală sau în lăţime
rezultatul (3.3) este înlocuit cu (3.4); o estimare mai exactă pentru timpul necesar căutării pe
orizontală sau în lăţime este:

bd 1
1
2 b

Observăm de aici că, căutarea pe orizontală sau în lăţime comportă un calcul mai mare
decât căutarea pe verticală sau în adâncime cu un factor de
1 b 1
1 (*)
b b
Valorile tipice pentru această expresie apar în figura 3.16.

62
b Raportul (*)
2 1.5
3 1.3
5 1.2
10 1.1
25 1.04
100 1.01

Figura 3.16. Costul căutării pe orizontală sau în lăţime

Pentru b=2, relaţia 3.4 se simplifică la :

2d 1
2d 2 d 2 2d 1
d
2d
2 2

La căutarea pe orizontală sau în lăţime am obţinut acest rezultat direct. Spaţiul total de
căutare este 2d+1 şi căutarea pe verticală sau în adâncime, în medie, va examina aproape
jumătate din acesta - cu alte cuvinte 2d noduri. Comparând cele două abordări vedem că
căutarea pe verticală sau în adâncime este de câteva ori mai eficientă ca timp şi mult mai
eficientă ca spaţiu decât căutarea pe orizontală sau în lăţime.

3.2.5. Adâncimea iterativă.

Se pune întrebarea dacă există vreo cale de a alege cea mai bună din cele două
abordări, folosind un algoritm care să aibă spaţiul cerut de căutarea pe verticală sau în
adâncime şi proprietăţile de performanţă ale căutării pe orizontală sau în lăţime? Răspunsul
este da; abordarea care face această alegere este cunoscută ca “adâncimea iterativă” şi a fost
investigată mai întâi de Rich Korf.
Există două căi separate de a înţelege adâncimea iterativă. Poate cea mai simplă (deşi
aceasta nu explică numele) este faptul că adâncimea iterativă este asemănătoare cu căutarea
pe orizontală sau în lăţime, cu excepţia că în loc de a stoca toate nodurile la nivelele
intermediare, le regenerăm când este timpul să le expandăm.
De ce este aceasta o abordare viabilă? Dacă cantitatea de timp consumată pentru
regenerarea nodurilor interne ar micşora timpul consumat cu căutarea răspunsului, dar nu
acesta este cazul de aici, cea mai mare parte a efortului de calcul este consumată cu examinrea
nodurilor din margine.
Cealaltă cale de a înţelege adâncimea iterativă este următoarea. În cazurile în care
căutarea pe verticală sau în adâncime nu dă rezultate satisfăcătoare, adâncimea nodului ţintă
este mai mică decât adâncimea întregului arbore deoarece prima ţintă găsită este la o
adâncime mai mare decât cea mai puţin adâncă soluţie a problemei, sau pentru că adâncimea
arborilor este infinită, şi aşa mai departe. Ceea ce face adâncimea iterativă este faptul că are
loc o căutare în arbore pe o cale care garantează că adâncimea ţintei si adâncimea arborelui se
potrivesc.
Ideea este de a căuta în arbore, iniţial cu o adâncime artificială redusă la 1, astfel ca
nici un nod cu adâncime sub nivelul 1 nu este examinat. Dacă această abordare reuşeşte cu
găsirea soluţiei la adâncimea 1, metoda întoarce soluţia. Dacă nu, se caută în arbore cu o
adâncime care este redusă la 2. Fiecare din aceste căutări iterative procedează în modalitatea
de căutare pe verticală sau în adâncime.

63
Procedura 3.3.1.
Căutarea în adâncime iterativă.

1. Setează c = 1 ; acesta este adâncimea curentă redusă.


2. Setează L ca va fi lista nodurilor iniţiale din problemă .
3. Fie n primul nod din L. Dacă lista L este vidă incrementează c şi reia pasul 2 .
4. Dacă n este un nod ţintă, atunci STOP şi întoarce nodul n şi calea de la nodul
iniţial la n.
5. Altfel şterge n din lista L. Presupunând că adâncimea nodului n este mai mică
decât c, adaugă în capul listei L toţi fiii nodului n etichetând pe fiecare cu calea de
la nodul iniţial la el. Reia pasul 3.

Dacă cea mai puţin adânca soluţie este la adâncimea g, căutarea pe verticală sau în
adâncime la acest nivel va reuşi; rezultă din cele discutate până aici că, metoda căutării în
adâncime iterativă va da întotdeauna “soluţia cea mai puţin adâncă” la problema în discuţie.
Deoarece fiecare din căutările individuale este realizată în maniera căutării pe verticală sau în
adâncime, cantitatea de memorie cerută de metodă este aceiaşi cu cea a căutării pe verticală
sau în adâncime.
Cum putem să aflăm numărul de noduri examinate? În general numărul de noduri
examinate în iteraţia finală (care a reuşit) este dat de relaţia 3.4. În iteraţiile anterioare,
căutările nereuşite la adâncimile 1, 2,.., d-1 au examinat întregul arbore la aceste adâncimi;
dimensiunea arborelui la adâncimea j este dată de

bi 1 1
1 b ... b j
b 1

Numărul total de noduri care au fost examinate în căutările nereuşite este:

j d 1
bj 1 1 1 d 1 d 1
1 bd 1
b bj 1 b d
j 0 b 1 b 1 0 0 b 1 b 1
bd 1
b d b d
2
b 1

Combinând aceasta cu relaţia 3.4 şi simplificând rezultatul, numărul total de noduri


care au fost examinate în această abordare este:

bd 2
bd 1
b2 d b2 4 b d 5 b 3 d 2
2
(3.5)
2 b 1

Pentru valori mari ale lui d, această relaţie este dominată de:

b 1 bd 1

2
2 b 1

Deoarece timpul necesar pentru căutarea pe verticală sau în adâncime este dominat de:

64
bd 1
2 b 1

raportul dintre timpul necesar adâncimii iterative şi cel necesar căutării pe verticală sau în
adâncime este dat de:

b 1
(3.6)
b 1

Valorile tipice obţinute din această expresie sunt arătate în figura 3.17. Aşa cum putem
vedea din tabel, costul repetării lucrului la adâncimi mici nu este mare. Deoarece adâncimea
iterativă evită problemele întâlnite în căutarea pe verticală sau în adâncime, ea este o metodă
care este preferabilă în multe probleme de căutare.
Ca de obicei, examinăm cazul b=2 în detaliu. În cazul căutării pe verticală sau în
adâncime, avem nevoie să examinăm jumătate din întreg arborele; deoarece arborele are
dimensiunea 2d+1, căutarea pe verticală sau în adâncime necesită examinarea a 2d noduri. În
adâncimea iterativă, căutările eşuate iau timpul:

1 2 ... 2 d 2d 1

deoarece acestea sunt dimensiunile subarborilor examinaţi. Deoarece acest timp este de două
ori mai mare decât timpul necesar pentru o căutare reuşită la adâncimea d, factorul general în
cazul b=2 este 3, în concordanţă cu relaţia 3.6 şi figura 3.17.
b raport
2 3
3 2
5 1.5
10 1.2
25 1.08
100 1.02

Figura 3.17. Costul adâncimei iterative


Cât de bună este adâncimea iterativă? Într-un sens foarte real, este o procedură
optimală de căutare oarbă. Motivul este că pentru un factor de ramificaţie fixat, procedura ia
spaţiul de memorie O(d) şi timpul O(bd); după cum se va vedea, este imposibil să
îmbunătăţim această căutare. Este clar, de exemplu, că dacă programul este aşteptat să
întoarcă calea către nodul ţintă la adâncimea d, atunci este cerut cel puţin spaţiul d.
Ce putem spune despre timp? Deoarece nodul ţintă este distribuit întâmplător de-a
lungul marginei arborelui şi tehnica de căutare este oarbă, înseamnă că vom avea nevoie în
medie să examinăm cel puţin jumătate din aceste ramuri. Deoarece marginile sunt în număr de
bd, putem deci să ne aşteptăm ca procedura de căutare oarbă să dureze O(bd). Date fiind aceste
lucruri, ne putem întări remarcile cu privire la spaţiul necesar prin argumentul următor:
considerăm orice algoritm care durează O(bd); cât spaţiu îi este necesar pentru a putea distinge
propriile sale stări interne?
Dacă toate stările interne ale algoritmului rămân distincte, este nevoie în mod clar de
cel puţin atâta spaţiu cât ar fi necesar să se numere până la bd. Dar numărătoarea până la bd
necesită log2(bd) biţi; deoarece log2(bd)=d*log2(b) are valoarea O(d) pentru b fixat, se vede că

65
orice algoritm de căutare oarbă necesită spaţiul O(d) dacă se aşteaptă ca el să întoarcă o cale
către răspuns sau nu.
3.2.6. Lăţimea iterativă.
Deşi adâncimea iterativă este optimală, în sensul că funcţia O(bd) în general este cea
mai bună care se poate obţine, există o altă tehnică de căutare oarbă care adesea îmbunătăţeşte
acest rezultat în practică - nu prin reducerea complexităţii problemei, ci prin abordarea
problemei într-un mod corespunzător, şi anume prin aceea că, este examinată doar o mică
porţiune din ramuri dacă există mai multe noduri ţinta. Această tehnică este cunoscută ca fiind
“lăţimea iterativă “.
Aşa cum am observat, este important, acolo unde este posibil, să se recunoască
alegerile greşite înainte de a face căutarea, astfel încât să nu fie nevoie să se extindă arborele
de căutare dincolo de acest nivel înainte de găsirea nodului ţintă. Dar cum să se sezizeze
aceasta dacă algoritmul de căutare este orb? Răspunsul constă în aceea că, în majoritatea
problemelor practice, nodurile ţintă nu sunt dispuse aleator fiind posibil de a se face erori
fatale la începutul căutarii.
Aşa cum adâncimea iterativă impune limite de adâncime artificiale şi creşte gradual
acele limite până este găsită o soluţie, tot aşa lăţimea iterativă impune limite de lăţime
artificiale, crescându-le până se găseşte o soluţie.
Procedura 3.4.1. Lăţimea iterativă.
1. Setează c=2; acesta este lăţimea curentă redusă.
2. Setează L ca fiind lista de noduri iniţiale din problemă .
3. Fie n primul nod din L. Dacă L este vidă, incrementează c şi reia pasul 2.
4. Dacă n este nodul ţintă, atunci STOP şi întoarce nodul n şi calea de la nodul iniţial
la n.
5. Altfel şterge n din L. Adaugă în faţa listei L primul c din fii lui n, etichetând pe
fiecare cu calea sa de la nodul iniţial. Reia pasul 3.
Căutam iniţial arborele cu o lăţime redusă cu 2, cu 3 şi aşa mai departe. O lăţime
redusă cu c înseamnă că maximum c fii ai fiecărui nod dat pot fi examinaţi înainte ca nodul să
fie abandonat ca fiind un eşec. În figura 3.18 este prezentat un arbore cu un factor de
ramificare 4 dar cu o lăţime redusă la 3.

Figura 3.18. Căutarea cu o lăţime redusă

Nodul ordonat dat de lăţimea iterativă din exemplul anterior este arătat în figura 3.19.

66
1, 18, 21

2,9,22 5,13,27 17,22 37

3 4 12 26 6 7 16 31 18 19 20 36 38 39 40 41
10 11 25 14 15 30 33 34 35
23 24 28 29

Figura 3.19 Lăţimea iterativă

La fel ca şi adâncimea iterativă, lăţimea iterativă este o tehnică de căutare viabilă


pentru că există cel mult b căutări şi căutările în lăţime reduse cu c are nevoie de timpul O(cd)
care este mic în comparaţie cu bd, dacă c<b. Timpul maxim consumat prin această tehnică este
aproximativ :
1 2 d ... b d

care este aproximativ bd+1/d pentru un b mare (un factor de b/d mai slab decât la căutarea pe
verticală sau în adâncime) şi este aproximativ b d pentru un d mare.
Lăţimea iterativă poate duce la mari reduceri a volumului de timp necesar rezolvării
problemelor de căutare dacă există noduri ţintă multiple şi dacă este posibil să se facă erori
fatale la începutul căutării. La adâncimi mari este posibil ca metoda să găsească o soluţie mai
uşor decât căutarea pe verticală sau în adâncime, ori de câte ori numărul de noduri ţintă este
mai mare de 3.

3.3. Metode extinse de căutare euristică

În multe situaţii căutarea poate fi făcută mai eficient utilizând informaţiile pentru
reprezentarea problemei. De exemplu, în problema labirintului, dacă se cunoaşte poziţia
obiectivului relativ la punctul de plecare, se va selecta calea ce încarcă cel mai puţin posibil
costul. La problema careului cu opt numere, o informaţie a apropierii de obiectiv este dată de
poziţia punctelor faţă de starea obiectiv. Înformaţia rezultată din predicţia costului faţă de
obiectiv, chiar dacă nu este suficient de precisă, poate fi utilizată.Buclele moarte pot
determina creşterea timpului (şi implicit a costului) de atingere a obiectivului. Astfel de
cunoştinţe sunt de natură euristică, întrucât nu garantează corectitudinea complectă. Căutarea
bazată pe cunoştinţele euristice se numeşte şi căutare euristică.
Se cunosc mai multe tehnici de căutare euristică, tehnici ce vor fi expuse în
continuare.

3.3.1. Metoda gradientului (Hill-climbing method).

Ideea de bază a căutării în cazul unei strategii irevocabile este cea prin care, pornind
de la starea iniţială, să se minimizeze distanţa ce separă starea curentă obţinută de starea
obiectiv a problemei. Metodele matematice cunoscute în teoria sistemelor găsesc un bun teren
de aplicabilitate în această situaţie. O metodă des utilizată este metoda gradientului (metoda
hill-climbing) ce se utilizează în procesele de căutare multidimensională a extremelor
funcţiilor de mai multe variabile sau a soluţiilor sistemelor de ecuaţii neliniare. O serie de
probleme duc la complexitate în procesul generării stărilor ce se reflectă în caracterul

67
neterminal al stărilor obţinute. Aceasta nu permite testarea concordanţei cu obiectivul pentru
toate stările posibil de obţinut dintr-un nod dat. Generarea spaţiului stărilor se face după
strategii ce urmăresc două criterii de optimalitate:
 optimalitate locală – având ca obiectiv găsirea numărului minim de paşi ce duce la
o stare terminală, fără epuizarea tuturor combinaţiilor posibile. Starea precedentă este marcată
pentru a se aigura revenirea ulterioară în caz de eşec şi reluarea procesului prin generarea unui
nou element terminal;
 optimalitate globală – se referă la obţinerea soluţiei problemei cu un număr
minim de reveniri.
Strategiile de control irevocabile se bazează pe cunoaşterea locală, determină
operatorul aplicat de la un pas la altul, noua stare reprezintă un context necunoscut, context
folosit pentru determinarea unui alt operator până se atinge obiectivul. Se poate spune că
secvenţa de operatori defineşte o cunoaştere globală despre soluţia problemei ce se determină
ca urmare a aplicării operatorilor prin strategia de control.
Ideea de bază a acestei metode se bazează pe faptul că disecţia celei mai mari creşteri
a funcţiei f(x1, x2, … xn) este dată de gadientul funcţiei:

f f f
grad f ( x1 , x 2 ,..., x n ) , , ... ,
x1 x2 xn
Aplicarea metodei este dificilă dacă numărul variabilelor este mare, numărul
funcţiilor de cost este mare, funcţia are mai multe valori extreme.
La căutarea într-un graf, strategia traversării pentru atingerea obiectivului prin
alegerea acelor noduri care sunt predictate a fi apropiate de obiectiv este numită metoda de
gradient. Specific pentru alegerea următorului nod după n, se calculează h(nI) pentru toate
nodurile fiu (n1, n2, … nm) ale lui n şi stabileşte ca următor nod acel nod pentru care h(nI)
este mai mic. Funcţia h(n) este o măsură a apropierii de obiectiv. Algoritmul de căutare este:

n = nodul de start;
while (1)
{
if (obiectiv (n) ) exit (succes);
expandează n, calculează h(ni) pentru toate nodurile fiu ni şi face nodul fiu
nod următor (next-n) acel nod care are valoarea minimei;
if ( h(n) h(next-n) ) exit (fail);
n = next-n;
}

Se poate imagina obiectivul ca vârful unui munte şi h(n) ca diferenţa de înălţime între
nodul n şi vârf. Metoda urmăreşte apropierea de obiectiv prin gradient maxim. Dacă există
numai un vârf, metoda permite atingerea obiectivului, însă pot exista vârfuri locale ce sunt
atinse, ce nu permit apoi apropierea de maximul global.
Un exemplu de problemă la care metoda este aplicabilă, este cea a traversării
labirintului. În figura a obiectivul se atinge, iar pentru cel din figura b se obţine eşec.

68
În ambele cazuri, costul de la poziţia caracteristică nodului n la obiectiv, este calculat cu
formula:
h(n) = coordonata x a obiectivului – coordonata x a nodului n coordonata y a
obiectivului – coordonata y a nodului n
În cazul a, obiectivul poate fi atins prin secvenţa de noduri S A B E G, care
este un drum optim ce restrânge aria de căutare. În cazul b, se ajunge la eşec după parcurgerea
secvenţei S A C B, în care B reprezintă un vârf, dar care nu este un obiectiv. Pentru a
ajunge la obiectiv, ar trebui atins punctul E ce determină o depărtare de obiectiv.

3.3.2. Metoda celei mai bune prime căutări

În metoda gradientului maxim, dacă sunt şi alte extreme locale (valori minime ale lui
h(n) ) decât obiectivul, nu se poate garanta continuarea algoritmului pentru atingerea acestuia.
Tehnica cunoscută sub numele de metoda celei mai bune prime căutări, se bazează pe luarea
deciziei după examinarea spaţiului stărilor. Toate nodurile ce au fost examinate prin această
tehnică până la momentul curent sunt stocate, urmând ca nodul cel mai apropiat de obiectiv să
fie expandat. Până aici metoda este similară cu cea bazată pe gradient, însă atunci când h(n)
devine constant sau acţiunile permise în starea curentă produc depărtarea de obiectiv, un alt
nod din listă va fi expandat. Algoritmul pentru căutarea în grafuri după această metodă este
următorul:
pune nodul de start S în open_ list;
while (1)
{
if (open-list = lista_vidă) exit (fail);
n = prim-nod (open_list);
if (obiectiv (n) ) exit (succes);
remove (n, open_list);
add (n, closed_list);
expandează n şi generează toate nodurile fiu.
Pune în open_list numai acele noduri ce nu sunt conţinute
în open_list sau closed_list de până atunci.
Pentru fiecare nod sunt asociaţi pointeri la nodul n.
Lista nodurilor este ordonată crescător;
}

69
Aplicarea procedurii de mai sus pentru labirintul din a) obţine aceiaşi secvenţă de
noduri ca prin aplicarea metodei de gradient.
Pentru labirintul din b) se obţine succcesiunea
(S(6)) (A(4)) (B(2)C(3)) (C(3)E(3)) (E(3)D(4)) (H(2)D(4))
(G(0)D(4)F(4))
Pentru utilizarea metodei cele mai bune prime căutări este necesar să se cunoască
costul atingerii obiectivului, adică o serie de cunoştinţe despre problemă.

3.3.3. Soluţia optimă când costul poate fi predictat. Algoritmul A.

Prezentăm în continuare o metodă de găsire a soluţiei optime când costul atingerii la


scop poate fi predictat. Pentru un nod arbitrar n al grafului, se va nota cu g(n) costul drumului
optim de la nodul S la nodul n, şi h(n) costului drumului de la nodul n la nodul obiectiv. Dacă
între noduri nu există drum aceste costuri sunt infinite. Costul drumului optim de la nodul
iniţial la obiectiv este dat de următoarea formulă:
f(n)=g(n)+h(n)
şi problema este de a găsi drumul optim (partea care dă f(S)) de la nodul de start. Dacă f(n)
este cunoscută exact, soluţia poate fi obţinută prin înlănţuitrea nodurilor cu cel mai mic f(n)
ce pornesc din S. În practică fie g(n), fie h(n) nu sunt cunoscute cu precizie, aşa că este
necesară căutarea.
Ca şi în exemplele precedente, valoarea costului inferenţiat h(n) către obiectiv este dat
pentru toate nodurile. Se va nota cu g’(n) valoarea lui g(n) pentru nodurile deja generate ce au
cost minim şi conţin un drum ce trece prin n. Valoarea inferenţiată f’(n) a costului drumului
optim trecând prin n este dată de formula
f’(n)=g’(n)+h’(n)
Strategia de căutare utilizând această funcţie de evaluare este cunoscută sub numele de
algoritmul A :

Introduce nodul de start în open_list; f’(S)=h’(S);


while(1)
{
if(open_list = vidă) exit (fail);
n = prim_nod(open_list);
if(obiectiv(n)) exit (succes);
remove(n,open_list);
add(n,close_list);
expandează n. Pentru toate nodurile fiu ale nodului n calculează
f’(n,ni)=g’(n, ni)+h’(n, ni)
utilizând costul g’(n, ni) al trecerii prin n la ni de la S.
Pune nodurile ce sunt conţinute în open_list sau closed_list în open_list
şi setează pointerii la n. Pentru nodurile conţinute în open_list
compară f’(ni) şi f’(n,ni) înaintea expandării nodului n.
Dacă nodul fiu ni este conţinut în closed_list şi f’(n,ni) < f’(ni)
face f’(ni)= f’(n,ni), setează un pointer de la n la ni şi pune ni
în open_list. Ordonează open_list crescător după valorile lui f’.
}

70
Dacă se consideră h(n)=0 algoritmul are aceeaşi comportare cu algoritmul de căutare
optimă. Dacă graful este finit , se poate arăta prin aceiaşi metodă bazată pe teorema 1 că
drumul optim este găsit atunci când un nod de start şi un nod obiectiv există. Totuşi, nu se
poate garanta că algoritmul va obţine soluţia optimă. În exemplul de graf care urmează sunt
ilustrate în parantezele asociate nodurilor, valorile funcţiei h(n) pentru nodul n.

Mai întâi se expandează nodul S pentru a obţine nodurile sale fiu A şi B. Se calculează
funcţiile respective de evaluare f’(A)=2+3 şi f’(B)=3+4, open_list este (A,B). Când se citeşte
A din open_list şi este expandat se va obţine nodul C. f’(C)’=6+0 aşa că open_list devine
(C,B). Când este preluat C căutarea se termină. Soluţia este drumul S A C. Cu toate
acestea calea nu este cea de cost minim. Raţiunea pentru care drumul de cost minim S B C
nu este găsit este dată de faptul că f(B) devine mai mare decât f’(B). Se poate dovedi că, dacă
h’(n) excede h(n), algoritmul va găsi soluţia optimă. Dacă costul inferenţiat este marginea
inferioară a costului real (h’(n)<=h(n)) algoritmul A se transformă în algoritmul A* .

3.3.4. Algoritmul A*

Să examinăm acum unul dintre cei mai importanţi algoritmi utilizaţi în căutare, şi
anume algoritmul A*.
Să considerăm mai înâi un exemplu simplu în care se găseşte o soluţie suboptimală
care este arătată în figura 3.20. Numărul care urmează numărului de nod în figură este
valoarea euristică asociată acestuia, deci eticheta 3 asignată rădăcinii nodului înseamnă că
acest nod va fi la trei paşi depărtare până la ţintă.
Metodologia devine greşită pentru nodurile de adâncime 1; nodul din stânga este
marcat cu 2 chiar dacă până la ţintă mai sunt 5 paşi, iar cel din dreapta este marcat cu 4, chiar
dacă ţinta poate fi atinsă doar din 2 paşi.
Numerele dintre paranteze din figură arată ordinea în care nodurile sunt expandate.
Rădăcina este expandată prima, după care îl vom expanda pe fiul său din partea stângă,
deoarece se crede că acest fiu este cel mai apropiat de ţintă decât cel din partea dreaptă.
Deoarece fiecare nod din subsecvenţa din partea stângă a arborelui se aşteaptă să fie mai
aproape de ţintă decât nodul din partea dreaptă de adâncime 1, partea stângă a arborelui este
explorată în întregime şi ţinta este găsită la adâncimea 6 în locul ţintei de adâncime 3.
Nu vom fi surprinşi că cea mai bună primă căutare eşuează în găsirea celei mai bune
soluţii în cazuri ca acesta. După acestă remarcă, ideea în cazul celei mai bune prime căutări
este de a găsi unele soluţii cât mai curând posibil prin găsirea oricărui nod care este la distanţa
0 de nodul ţintei; nici o încercare nu este făcută pentru a descoperi ţinta care se află la o
adâncime minimă în arborele căutării. Dacă vrem să facem acest lucru va trebui să modificăm
algoritmul căutării pentru a reflecta interesul de a găsi ţinta cât mai aproape de suprafaţă (la
adâncime minimă). Ordinea în care vom dezvolta nodurile trebuie să ţină cont de faptul că
vrem să dezvoltăm nodurile aflate la o adâncime cât mai mică în detrimentul celor aflate la
adâncime mai mare.

71
3(1)

(2) 2 4

(3) 1 1

(4) 1

(5) 1

(6) 1

(7)

Figura 3.20 Găsirea unei soluţii suboptimale

Mai precis, deoarece scopul celei mai bune prime căutări este de a găsi o ţintă cât mai
curând posibil, va conduce la dezvoltarea nodului cât mai apropiat de nodul ţintei. Deoarece
scopul modificat este de a găsi ţinta cea mai puţin adâncă cât mai curând posibil, va trebui să
expandăm nodul care pare cel mai apropiat de ţinta specificată. În loc de ordonarea nodurilor
în termenii distanţei până la ţintă, le vom ordona ţinând seama de calitatea ca ţinta să fie cea
mai apropiată de aceste noduri (aceasta este distanţa aşteptată).
Deci să presupunem că avem un nod n la adâncimea d în arborele căutării şi vom
presupune că distanţa de la cea mai apropiată ţintă la acest nod este h ' (n) (vom porni de la
ideea că h ' este pozitiv, deci că h' (n) 0 pentru toate nodurile n). Această ţintă este de aceea
apreciată că va fi la adâncimea d h ' (n) în spaţiul căutării; rezultă că în loc să alegem pentru
expandare nodul cu cel mai mic h' (n) ca în cea mai bună primă căutare (deoarece h ' (n) este
distanţa aşteptată până la ţintă), vom alege pentru expandare nodul cu cel mai mic d + h’(n).
Adâncimea nodului este considerată de asemenea o funcţie de nod, notată de obicei cu g (n)
şi se apreciază ca fiind „costul” atingerii nodului n de la nodul rădăcină. Deoarece intenţia
este de a găsi o ţintă cu un cost minimal, vom expanda nodurile în ordinea crescătoare a
valorilor date de relaţia (4.1):

f ( n) g ( n) h ' ( n) (4.1)

Acest algoritm este cunoscut ca algoritmul A* şi ca exemplificare îl vom aplica în


problema de căutare din figura 3.20, rezultând arborele din figura 3.21. În loc de a eticheta
fiecare nod cu distanţa aşteptată până la ţintă, le vom eticheta cu două numere: adâncimea

72
nodului (0 pentru rădăcină, 1 pentru fii etc.) şi distanţa aşteptată până la ţintă. Vom alege apoi
pentru expandare nodul pentru care această sumă este cea mai mică.

0 3(1)

(2) 1+2 1 4 (6)

(3) 2+1 2 1 (7)

(4) 3+ 1 3+0 (8)


ţinta

(5) 4+1

5+1

ţinta

Figura 3.21 Găsirea unei soluţii optimale.


Prima cifră din sumă este distanţa de la nodul iniţial şi a doua cifră este distanţa estimată până la
ţintă.

Procedura 3.3.1. Algoritmul A*

1. Setează L să fie lista nodurilor iniţiale din problemă


2. Fie n un nod al lui L pentru care f (n) g (n) h ' (n) este minim. Dacă L este vidă,
eşec.
3. Dacă n este nodul ţintă, STOP şi returnează n împreună cu calea de la nodul iniţial
la nodul n.
4. Altfel şterge n din L şi adaugă la L toţi fii lui n, etichetându-l pe fiecare cu calea sa de
la nodul iniţial. Întoarcere la pasul 2.

Ca şi mai înainte, valoarea optimistă asignată nodului din partea stânga de adâncime 1
ne convinge să expandăm această cale înaintea altora, deoarece ne aşteptăm să găsim nodul
ţintă la adîncimea 3 dedesubtul acestui nod şi aşteptăm nodul ţintă dedesubtul altui fiu care va
fi la adâncimea 5. Oricum, când chiar am ajuns la adâncimea 5 pe calea din partea stângă a
arborelui şi nu s-a atins ţinta, va trebui să credem că o altă cale este mai bună şi să o
examinăm în schimb. Cel mai bun dintre cele două noduri ţintă este găsit acum primul. Sunt
două lucruri de reţinut aici. Primul este acela că nu există nici o diferenţă reală între
etichetarea nodurilor (5) şi (6) în figura 3.21.; amândouă sunt aşteptate să conducă spre ţinte
la adâncimea 5. Am ales să expandăm primul pe (5) deoarece a fost gândit să fie aproape de
nodul ţintă dar algoritmul A* însuşi nu ne cere să facem această alegere.
Un lucru mai important de reţinut este acela că nu este garantat faptul că A* găseşte
cea mai bună soluţie pentru orice problemă particulară de căutare. În figura 3.21., de exemplu,

73
dacă nodul etichetat cu (5) (ceea ce înseamnă că, va fi expandat al cincilea) era nodul ţintă, el
va fi găsit înainte de nodul ţintă optimal pe calea din partea dreaptă.

3.3.4.1. Admisibilitatea

Motivul pentru care evităm expandarea căii din partea dreapta din exemplul din figura
3.21. este că avem o etichetare pesimistă a nodului din partea dreapta de adâncime 1 cu
valoarea 4, aceasta indicându-ne că nu ne putem aştepta să găsim ţinta la orice adâncime mai
mică decât 5 de-a lungul acestei căi. Ca atare, suntem conduşi să examinăm nodurile de
adâncime 4 de-a lungul căii din stânga înainte de a căuta ţinta de adâncime 3 din partea
dreaptă a arborelui. Dacă funcţia care estimează distanţa până la ţintă a fost aleasă ca fiind
optimistă, acest lucru nu se va întâmpla.
Pentru a formaliza aceasta, presupunem că notăm cu h(n) (fără apostrof) actuala
distanţă de la nodul n până la nodul ţintă. Acum funcţia euristică estimată h ' va fi optimistă
doar în cazul când avem întotdeauna h ' h şi în acest caz avem.

Teorema 3.3.1. Dacă h' (n) h(n) pentru orice nod n, algoritmul A* va găsi
întotdeauna un nod ţintă optimal.

Demonstraţie: Presupunând că s este cel mai adânc nod ţintă şi calea de la nodul
rădăcină la această ţintă este
n0 , n1 ,..., nk
unde nk s . Ceea ce putem face este să arătăm că dacă algoritmul A* expandează o parte
din această cale:
n0 , n1 ,..., ni
atunci el expandează de asemenea următorul nod de-a lungul acestei căi şi anume ni 1 .
Deoarece nodul rădăcină n0 este întotdeauna extins, rezultă prin inducţie că şi nodul s nk
este întotdeauna extins. În acest sens luăm s ' ni 1 ca fiind un nod de-a lungul căii spre s şi
luăm x ca fiind orice nod mai rău decât s în sensul g ( x) g ( s ) . Deoarece există doar un
număr finit de noduri cu f (n) c pentru orice constantă c, ştim că procedura va expanda în
final fie pe s ' sau un astfel de nod x. În plus, deoarece a fost expandată calea de la rădăcină la
s ' , trebuie doar să arătăm că valoarea euristică asignată lui s ' (incluzând costul ajungerii
acolo) este mai mică decât valoarea asignată lui x. Cu alte cuvinte, trebuie să arătăm că:

g (s ' ) h' (s ' ) g ( x) h ' ( x) .

Dar h' ( s ' ) h( s ' ) pentru că h' este optimistă. De aici rezultă că:

g (s ' ) h' (s) g ( s ' ) h( s ' ) g ( s) g ( x) g ( x) h ' ( x)

Egalitatea apare deoarece suma costurilor ajungerii la s ' şi apoi de la s ' la nodul ţintă optimal
s este chiar costul ajungerii direct la s. Demonstraţia este completă.
O funcţie euristică optimă h ' este numită admisibilă.
Pentru exemplificare, să ne reîntoarcem la spaţiul de căutare din figura 3.21. după
modificarea valorii euristice atribuite nodului din dreapta de adâncime 1 astfel încât funcţia
euristică să fie admisibilă; rezultatul este arătat în figura 3.22.. Nodul ţintă optimal este găsit
într-adevăr în acest caz.

74
3(1)

(2) 1+2 1 2 (4)

(3) 2+ 1 2 1 (5)

3+ 1 3+0 (6)
ţinta

4+1 ţinta?

5+1

ţinta

Figura 3.22 O funcţie euristică admisibilă

Există de asemenea şi alte exemple interesante. Funcţia “euristică” h' (n) 0 este clar
una admisibilă şi conduce în mod simplu la extinderea nodurilor în ordinea creşterii lui g (n) .
Pentru că g (n) este adâncimea nodului n, algoritmul A* reproduce căutarea pe orizontală sau
în lăţime în acest caz. Deoarece căutarea pe verticală sau în adâncime eşuează adesea în
găsirea celei mai bune soluţii a problemei, este sigur că nu există o euristică admisibilă care să
imite căutarea pe verticală sau în adâncime pe o cale similară.
Euristica perfectă h ' h este de asemenea întotdeauna admisibilă.

3.3.4.2. Extensii şi IDA*

Vom încheia discutând câteva extensii ale algoritmului A*. Prima situaţie pe care o
considerăm este aceea în care ”costul” unui nod nu mai este reprezentat de adâncimea lui în
spaţiul de căutare, ci este evaluat în schimb în alte moduri. Vom continua să presupunem
faptul că costul ajungerii la un nod n este suma costurilor arcelor individuale de-a lungul căii
de la rădăcină la n; nu se mai presupune că lungimea fiecărui arc este o unitate de cost.
Nu este greu să observăm că atâta timp cât vom continua să folosim g (n) pentru
costul atingerii nodului n, folosirea algoritmului A* utilizând funcţiile de evaluare obişnuite
date de relaţia 4.1 continuă să găsească soluţiile cu cel mai mic cost. Dacă vom lua h ' (n) 0
în acest caz, vom obţine procedura de căutare cunoscută sub numele de branch and bound
(ramifică şi mărgineşte).
În continuare presupunem că folosim A* pentru a căuta într-un graf în locul unui
simplu arbore, cum este arătat în figura 3.23.. Presupunând că luăm g (n) ca fiind costul celei
mai ieftine căi găsite către nodul n şi să menţinem o listă doar cu nodurilor deschise,
algoritmul rămâne în principiu neschimbat.

75
Figura 3.23. Algoritmul A* folosit la căutarea în graf

Procedura 3.3.2. Algoritmul A* în grafuri

1. Setează L să fie o listă a nodurilor iniţiale din problemă.


2. Fie n un nod în L pentru care f (n) g (n) h ' (n) este minim. Dacă L este vidă,
eşec.
3. Dacă n este nod ţintă, STOP şi întoarce pe n şi calea de la nodul iniţial la n.
4. Altfel şterge pe n din L şi adaugă la L toţi fii lui n, etichetându-l pe fiecare cu
calea de la nodul iniţial până la el. Dacă vreun fiu c este deja în L nu vom face o
copie separată dar, în schimb, reetichetăm c cu cea mai scurtă cale care îl leagă
de nodul iniţial. Întoarce-te la pasul 2.
În figură nodul care este extins al zecelea este iniţial crezut a fi la adâncimea 4 dar el
este de fapt determinat la adâncimea 3 înainte de a fi expandat. În sfârşit, memoria este o
problemă pentru algoritmul A*. Deoarece el se reduce la căutarea pe orizontală sau în lăţime
dacă h ' 0 , se observă că A* posibil va folosi o cantitate de memorie care este exponenţială
cu adâncimea nodului ţintă optimal. Ca şi în cazul căutării oarbe, această problemă poate fi
rezolvată folosind adâncimea iterativă.

Procedura 3.3.3 I.D.A*.

1. Fie c = 1; aceasta este adâncimea curentă a scurtăturii.


2. Fie L o listă a nodurilor iniţiale din problemă.
3. Luăm n primul nod din L. Dacă L este vidă, incrementează c şi întoarce-te la pasul 2.
4. Dacă n este nodul ţintă, STOP şi returnează pe n şi calea de la nodul iniţial la n.
5. Altfel şterge n din lista L. Adaugă la capul listei L fiecare fiu n' al lui n pentru care
f (n ' ) c . Întoarce-te la pasul 3.

Este important să înţelegem că iteraţiile individuale din acest algoritm sunt făcute
folosind convenţionala căutare pe verticală sau în adâncime şi nu folosind A*; funcţia
“euristică“ este folosită pentru a tăia nodurile şi nu pentru a determina ordinea în care ele vor
fi expandate. Cu toate acestea, dacă iteraţiile originale cer ca expandarea să fie făcută folosind
algoritmul A*, o cantitate exponenţială de memorie va fi necesară!

76
Figura 3.24. I.D.A*

Un exemplu de folosire a procedurii 3.3.3. apare în figura 3.24.. Pentru c=1 vom
examina numai nodul rădăcină; pentru c=2 vom examina două noduri şi aşa mai departe.
Căutările individuale sunt conduse în stilul căutării în adâncime, ceea ce explică de ce nodul
12 este extins înaintea nodului 14 în figură deşi estimările euristice indică că nodul 14 este
probabil mai apropiat de o ţintă superficială.
Procedura 3.3.3 este cunoscută ca adâncime iterativă A*, sau simplu I.D.A*. Nu
este foarte greu să arătăm că foloseşte o cantitate de memorie liniară cu adâncimea nodului
ţintă, adică sunt expandate doar nodurile extinse de A* însuşi şi aceasta continuă să caute
soluţiile optimale când este folosită o euristică admisibilă.

77
Unitatea de învăţare 4
Metode avansate de căutare.

Cuprins:
4.1. Căutarea în grafuri ŞI/SAU ....................................................................... pag. 78
4.1.1. Evaluarea şi expandarea grafurilor candidate ......................................... pag. 78
4.1.2. Căutarea în adîncime în grafuri ŞI/SAU ................................................ pag. 79
4.1.3. Căutarea soluţiei optime în grafuri ŞI/SAU ............................................ pag. 81
4.2. Căutarea în arbori pentru jocuri ................................................................. pag. 85
4.2.1. Arbori de joc ........................................................................................... pag. 85
4.2.2. Metoda MINIMAX ................................................................................. pag. 86
4.2.3. Metoda alfa-beta ..................................................................................... pag. 86
4.2.4. Utilizarea metodelor minimax şi alfa-beta în grafuri ŞI/SAU ................ pag. 88
4.3. Execiţii ........................................................................................................ pag.91

4.1. Căutarea în grafuri ŞI/SAU

Când se caută într-un graf este suficient să se găsească un singur drum, aşa că dacă se
cunosc pointerii de la nodurile părinte către toţi fii săi în drumul parcurs, şi căutarea este
completă, înseamnă că s-a găsit o cale ce constituie o soluţie. Totuşi un graf rezolvent al
grafului ŞI/SAU este la rândul său un graf. Procesul găsirii soluţiei prin căutare corespunde
dezvoltării progresive a soluţiei. Numai unele din grafurile rezolvente posibile sînt găsite în
timpul căutării. Acestea sînt numite grafuri candidate. S-a preferat această denumire în loc de
grafuri rezolvente parţiale întrucât nu se cunoaşte încă dacă acestea sînt parte a soluţiei. Uzual
aceste grafuri sînt găsite în timpul căutării şi structurile lor trebuiesc reprezentate.

4.1.1. Evaluarea şi expandarea grafurilor candidate

Un graf ŞI/SAU poate fi cercetat prin evaluări şi expandări repetate după cum
urmează:
1. Determină dacă nodurile grafurilor candidate sînt solvabile, insolvabile sau
nedecizabile, precum şi costul acestora dacă este cazul.
2. Expandează grafurile candidate.
În primul pas se examinează toate punctele finale (nodurile frunză) ale grafului
candidat. Dacă acestea sînt, noduri terminale ele corespund unei probleme rezolvate şi ca
urmare vor fi marcate în acest sens. Dacă punctele terminale ale grafului candidat sînt puncte
finale ale problemei iniţiale, dar nu noduri terminale, problemele corespunzătoare acestor
noduri sînt insolvabile şi se vor marca printr-un marker UNSOLVED. Dacă nodurile fiu ale
unui nod, altele decât nodurile terminale ale grafului candidat sînt noduri ŞI, şi dacă toţi fii
sînt SOLVED, atunci nodul va fi marcat SOLVED. Dacă cel puţin un fiu este UNSOLVED
atunci nodul părinte va fi marcat UNSOLVED. În cazul în care nodurile fiu, altele decât
punctele terminale sînt noduri SAU şi cel puţin unul a fost marcat SOLVED atunci nodul
părinte va purta aceeaşi marcă.
Când nodul S al unui graf candidat devine SOLVED, graful este o soluţie a problemei.
Dacă este necesar calculul costului, se calculează costul tuturor nodurilor utilizînd costul
punctelor finale ale grafurilor candidate. Costul nodului părinte al unui nod ŞI se calculează
ca suma tuturor nodurilor sale fiu, pe când cel al unui nod fiu SAU ca maximul costurilor
fiilor. Costul nodului de start este costul nodului grafului candidat. În pasul 2 se găsesc
nodurile fiu prin expandarea nodurilor ce sînt puncte terminale ale grafului candidat p şi nu au
fost marcate în nici un fel. Dacă nodurile fiu ale nodului expandat n sînt noduri ŞI un nongraf

78
candidat este generat prin adăugarea tuturor nodurilor fiu la nodul p. Dacă nodurile fiu ale
nodului n sînt noduri SAU adăugarea câte unuia din acestea la p va determina generarea mai
multor grafuri câte noduri fiu are. În acest mod un număr mare de grafuri candidate vor fi
generate prin procesul de căutare.

4.1.2. Căutarea în adîncime în grafuri ŞI/SAU

Ca şi în cazul căutării în grafuri obişnuite, strategiile de căutare în grafuri ŞI/SAU sînt:


căutarea în adîncime, căutarea în lărgime, strategii de căutare optimală. Procedura de căutare
în adîncime este:

Introduce în open_list un graf candidat format doar din nodul de start


While(1)
{
if (open_list=vidă) exit (fail);
p= prim_graf(open_list); /* aduce primul graf din listă*/
if(SOLVED(p)) exit(succes); /*dacă p este un graf rezolvent căutarea
se termină şi p este soluţia */
remove(p, open_list);
add(r, closed_list);
expandează p, evaluează toate noile grafuri candidate şi pune
grafurile candidate în care nodul de strat nu este UNSOLVED în
open_list;
}

Figura (a) (t1-t4 sînt noduri terminale)

În figura b care urmează, se arată grafurile candidate în open_list pentru graful


ŞI/SAU din figura a. Când primul graf candidat din open_list este expandat şi evaluat la a
treia parcurgere a buclei este găsit UNSOLVED şi este mutat din open_list. La a şasea
repetare a procedurii graful candidat din open_list este SOLVED şi devine soluţie a
problemei.

79
1. 2.

3.

4. 5.

6.

Figura (b): Grafuri în open_list la căutarea în adîncime

În această procedură grafurile candidate expandate sînt ţinute în open_list, însă nu este
esenţial a face acest lucru în cazul căutării în adâncime. Se poate utiliza un sistem în care
această listă conţine numai un graf parţial SOLVED, pentru formarea soluţiei trebuie

80
combinat corespunzător cu alte grafuri. Pentru realizarea acestui lucru este necesară
construirea unei funcţii care atunci când nodurile sînt expandate toate nodurile fiu ale sale au
fost generate o singură dată. Un singur nod fiu determină un graf parţial la un moment dat de
timp. Pentru formalizare se defineşte funcţia next_fiu. Se presupune că nodul n are nodurile
fiu n1, n2, … , nm şi nodul fiu ni a fost deja generat. Dacă nici un nod fiu nu a fost deja generat
i=0. Aplicarea funcţiei next_fiu(n) la nodul n determină următorul rezultat:

next_fiu(n)= ni-1 0 i m
null i=m

Cu aceste observaţii algoritmul de căutare în adâncime în arbori ŞI/SAU se


desfăşoară după procedura:

Construieşte graful candidat p conţinând numai nodul de start n=s;


Evaluează p;
While true
{
while true
{
if UNSOLVED(p) exit(fail);
if SOLVED(p) exit(succes);
if n este marcat break;
next_n=next_fiu(n);
add next_n la p, evaluează p;
n= next_n;
}
evaluează p;
if n este UNSOLVED elimină n din graful p;
n= nod_părinte(n);
}

Aplicată grafului din figura a anterioară, se obţine secvenţa S, A, C, F, C, A, S, B, E, t3,


E, t4. Secvenţa de căutare este aceeaşi cu cea de căutare în adîncime în grafuri obişnuite. Dacă
în procesul de căutare se obţine că toate nodurile SAU sînt UNSOLVED se întoarce la nodul
imediat precedent şi continuă căutarea după alte arce. Acest proces este numit backtracking.
Întrucât procedura realizează o funcţie backtracking nu este necesar ca toate nodurile fiu
expandate ale unui nod să fie stocate în open_list. Dacă într-un graf candidat p nodurile fiu ale
nodului final n sînt într-un graf candidat p, şi nodurile fiu ale nodului final n sînt sînt noduri
ŞI se adaugă toate la graful p. Pentru a reduce timpul când unul din nodurile fiu este
UNSOLVED, n devine UNSOLVED şi nu necesită găsirea altor noduri fiu. Pentru a continua
procesul se utilizează funcţia next_fiu.

4.1.3. Căutarea soluţiei optime în grafuri ŞI/SAU

Vom trata în continuare găsirea soluţiei optime în graf, soluţie având cost minim când
costul arcelor către nodurile SAU este definit. Se presupune că pentru fiecare nod al grafului
costul estimat al soluţiei este dat. Aceasta corespunde la h’ în căutarea pentru grafuri
obişnuite. Se va nota costul estimat pentru nodul n în h’(n). Dacă funcţia euristică h’(n) nu
este dată, cazul este similar cu h’(n)=0 şi algoritmul este identic cu cel de căutare în adâncime
pentru grafuri ŞI/SAU.

81
La algoritmul de căutare în adâncime descris anterior diferite grafuri candidate au fost
generate. Valoarea inferenţială f’(p) a costului unui graf candidat p este obţinută prin
evaluarea lui p utilizând valoarea inferenţială a costului punctelor finale. În figura c se arată o
parte a unui graf ŞI/SAU. Un graf candidat p este punctat prin linii punctate. Costul nodurilor
ŞI se calculează utilizând suma costurilor fiilor săi, iar pentru nodurile SAU s-a luat valoarea
1.

(3) (2)

Figura (c) (între paranteze s-a prezentat h’ şi fără paranteze costurile evaluate).

Dacă valorile estimate ale costurilor nodurilor A şi S sunt calculate utilizând valorile
inferenţiale, h’(C)=3 şi h’(D)=2 ale punctelor finale C şi D din (p), se obţine

f’(A)=h’(C)+h’(D),

iar pentru S,

f’(S)=f’(A)+1.

Ca urmare f’(p)=6.

Cu algoritmul A căutarea începe prin expandarea grafurilor cu f’(p) minim.


Algoritmul este:

82
Pune în open_list graful candidat (p) format numai din nodul de start S,
f’(p)=h’(S);
while true
{
if (open_list=vidă) exit(fail);
p=prim_graf (open_list); /* aduce primul graf din listă */
if (solved(p)) exit(succes); /* dacă (p) este un graf rezolvent
căutarea se */
/*termină şi (p) este soluţia */
remove (p, open_list);
expandează (p), evaluează toate grafurile candidate (pi) nou
generate şi găseşte f’(pi). Dacă (pi) este UNSOLVED pune-l
în open_list;
}

Pentru a ilustra modul în care algoritmul avansează se consideră exemplul din figura
(d), iar în figura (e) se prezintă conţinutul în open_list prin utilizarea algoritmului de căutare
optimală. În figuri s-au trecut între paranteze costurile estimate, costurile fără paranteze sunt
calculate utilizând costuri estimate. Fiecare candidat este denumit (prin marcarea cu Pi),
pentru a nu desena de mai multe ori acelaşi graf.

(4)

(3) (3)

(3) (2)

(1)
(2)

(1) (1)

t1 (0) t2 (0)

Figura (d) Căutarea soluţiei optime în grafuri ŞI/SAU

83
În figura (e) sunt arătaţi numai primele şase cicluri. După ultimul ciclu ilustrat, H şi I
sunt expandate şi nodurile terminale (t1) şi (t2) sunt adăugate obţinând graful (p10). Costul
pentru (p10) este f(p10)=5. Dacă nodurile fiu ale unui nod (n) asociat unui graf candidat (p)
sunt noduri ŞI, ele sunt generate la acelaşi moment, cu toate că sunt evaluate la paşi diferiţi.
Ca şi în cazul utilizării algoritmului A în grafuri obişnuite, acest algoritm nu garantează
găsirea soluţiei optime.
1. (4 )
P1:
2. (4 ) (4 )

(3 ) 3
P2: P3:
3. 6

(3 ) (2 )
P3 P4:
4. 4

(2) (1)
P5: P4
5. 4 5

3 4

2 (1 ) 3 (1 )

(1 ) (2 )
P6: P7: P4
6. 5

(1 )

(1 )
P8: P7 P4

Figura (e) Soluţia căutării optimale pentru graful din figura (d) .

84
Totuşi se poate demonstra că soluţia optimă este găsită dacă h’<h pentru toate
nodurile. Dacă în calcularea costurilor inferenţiale ale grafurilor candidate se setează costul
tuturor arcelor egal cu (0), aceasta corespunde încercării de minimizare a viitoarelor costuri de
căutare.
4.2. Căutarea în arbori pentru jocuri

Un domeniu des utilizat în tehnicile de inteligentă artificială este şi cel al teoriei


jocurilor. Problema esenţială este cea de luarea deciziei în efectuarea unei noi mutări, ce poate
fi rezolvată prin utilizarea tehnicilor de căutare ce au fost deja descrise.

4.2.1. Arbori de jocuri

Să presupunem că doi jucători mută alternativ (operatorii sunt aplicaţi alternativ),


pornind de la o stare iniţială, până când o stare finală este atinsă. Dacă starea finală este un
eşec sau un succes valoarea evaluată poate fi un scor. Diferitele stări obţinute în timpul
parcurgerii jocului pot fi reprezentate asemănător unui graf. De cele mai multe ori aceleaşi
stări pot fi atinse prin mai multe secvenţe de mutări. Dacă se ignoră aceasta şi se reprezintă
prin noduri distincte, graful este un arbore. În continuare, pentru simplitate, vom reprezenta
jocurile prin arbori.
S

A B

C D ES F
5 2 1 6

Figura (f) Joc simplu reprezentat ca arbore

Se presupune că obiectivul jucătorului care mută primul (numit MAX) este să obţină
maxima evaluată, iar obiectivul jucătorului care mută al doilea (numit MIN) este de a obţine
cea mai mică valoare evaluată. De asemenea, ambii jucători aleg cea mai bună mutare. În
figura (f) este prezentat un arbore simplu asociat, în care nodurile corespunzând lui MAX sunt
pătrate, iar cele corespunzând lui MIN sunt cercuri. Valorile evaluate sunt date la punctele
finale.
În mod normal arborele are o adâncime mare şi din fiecare nod pleacă mai multe arce.
Chiar pentru jocuri de complexitate medie este practic imposibila generarea arborelui
incluzând toate punctele finale. În astfel de cazuri, valorile evaluate sunt găsite prin generarea
unui arbore în adâncime rezonabilă, în care evaluarea punctelor terminale ale arborilor parţiali
se face prin aceleaşi metode.
Valorile evaluate pe această cale sunt numite valori evaluate static. Dacă jocul este
aproape de terminare se poate atinge un punct final, însă de cele mai multe ori cea mai bună
mutare va fi decisă prin utilizarea valorilor evaluate static. Se ia în considerare faptul că
adversarul determină şi el cea mai bună mutare după generarea unui arbore parţial de
adâncime corespunzătoare. Adâncimea arborelui este restricţionată prin memoria şi timpul de

85
calcul necesare. Valorile evaluate static sunt date de cunoaşterea caracteristicilor jocului.
Pentru a juca ŞAH, SHOGI sau GO este necesară atât investigarea metodelor de căutare cât şi
a metodelor de evaluare adecvate. În cele ce urmează vor fi prezentate numai metode de
căutare pentru cazul în care valorile evaluate sunt considerate cunoscute.

4.2.2 Metoda MINIMAX

Se va explica metoda minimax cu referire la exemplul din figura (f). De la nodul de


start S, MAX are de ales între două posibilităţi. Dacă se alege primul arc se ajunge în nodul A.
MIN are în continuare două posibilităţi, dar alegerea nodului D dă cea mai mică valoare
evaluată. Dacă MAX a ales iniţial nodul B, MIN va alege nodul E care dă valoarea
inferenţială (1). MAX trebuie să aleagă propria mutare presupunând că valoare inferenţială
pentru fiecare nod MIN este cea mai mică din valorile evaluate pentru toate nodurile ce
pornesc din el. Dacă se notează nodul MAX cu (n) şi fiii săi cu (ni) (i=1…m), iar nodul fiu al
fiecăruia cu (nij) (j=1…im), MAX maximizează valoarea evaluată a lui f(ni). Selectarea lui (i)
va satisface următoarea condiţie: f(ni)=max f(ni). MIN minimizează f(ni) pentru un (i) dat şi
alege (j) astfel încât f(ni)=min f(nij). Astfel MAX alege (i) în concordanţă cu:
f(nij)=max {min f(nij)}.
Dacă se ia adâncimea arborelui (k), MAX va selecta (iA), aşa că:
f(ni1,i2,…,ik)=max min…{f(ni1,i2,…,ik)}.
Dacă valorile evaluate ale punctelor terminale din arbore sunt corecte, metoda
minimax va selecta cea mai bună mutare. Totuşi, dacă adâncimea arborelui creşte, numărul
nodurilor ce trebuie evaluate creşte exponenţial. Un algoritm mai eficient de rezolvare a
acestei probleme se poate obţine utilizând metoda alfa-beta.

4.2.3. Metoda ALFA-BETA

Fie arborele de căutare din figura (g) în care nodurile sunt numerotate şi un scor este
dat la fiecare nod terminal. Dacă se găsesc cele mai bune mutări utilizând algoritmul
minimax, iniţial MAX alege nodul (1), MIN alege nodul (3), MAX alege nodul (8) ce are
valoarea evaluată (5).

1 2

3 4 5 6

7 8 9 10 11 12 13 14 15 16 17 18

3 5 4 4 5 7 4 3 2 5 8 6

Figura (g) Căutarea în arbori folosind metoda alfa-beta

86
Presupunând că într-o procedură similară cu cea de căutare în adâncime s-a obţinut
valoarea evaluată (5) pentru nodul (3), în continuare se încearcă găsirea valorii nodului (4). Se
cunoaşte în acest moment faptul că valoarea nodului (1) nu poate fi mai mare decât (5).
Motivul rezidă în faptul că dacă valoarea nodului (4) ar fi mai mare decât (5), MIN nu va
alege nodul (4). Cu toate că se cunoaşte că valorile nodurilor (10) şi (11) sunt obţinute,
valoarea nodului (4) este cel puţin (5). Aşa că nu poate fi mai avantajos pentru MIN să aleagă
nodul (4) în detrimentul nodului (3). Se deduce că MIN va alege nodul (3) fără să mai
examineze nodul (12). în acest mod valoarea ce determină costul nodului (1) este (5) şi ca
urmare valoarea nodului S trebuie să fie cel puţin (5). Considerând acum că valoarea evaluată
(4) este obţinută pentru nodul (5), prin examinarea valorilor tuturor nodurilor fiu ale sale, şi
cum selecţia nodului (2) nu va aduce pentru MAX avantaje, nu mai este necesară inspectarea
nodului (6) şi a celor care sunt fiii săi. Metoda de segmentare a numărului de noduri ce sunt
cercetate este numită şi metoda alfa-beta. Pentru căutarea sistematică a arborilor adânci
metoda este simplu de înţeles dacă se formalizează după cum urmează. Se notează marginea
inferioară a fiecărui nod cu alfa, iar marginea superioară cu beta. În starea iniţială pentru
nodul S, alfa şi beta sunt - , respectiv + . Pentru aceasta se va scrie
(S)=( - , + ). Dacă o valoare (x) este mai mică decât alfa sau mai mare decât beta, se
spune că (x) depăşeşte domeniul ( , ). Când valoarea nodului (3) este determinată, (1) = (-
,5). Dacă se cunoaşte că valorile nodurilor fii ale nodului (1) depăşesc gama (- ,5), condiţia
pentru întreruperea căutării este îndeplinită. Când nodul (11) a fost explorat, (4)=(5, ), deci
în afara gamei (- ,5), deci condiţia de întrerupere a căutării este din nou îndeplinită şi nu va fi
necesară căutarea în continuare a fiilor lui (4). În acest moment (1)=(5,5) şi (5)=(5, ).
Când căutarea continuă, valoarea nodului (5) este găsită ca fiind (4), în afara gamei (5, ) şi se
întrerupe căutarea nodului (2) şi a celor ce pornesc din el.
Prima întrerupere a căutării apare datorită faptului că nodul (4) este cel puţin egal cu
valoarea lui beta şi a părinţilor săi, a doua întrucât valoarea nodului (2) este cel puţin egală cu
valoarea lui alfa. Procedeul este denumit beta-cut, respectiv alfa-cut. Metoda de creştere a
eficienţei căutării utilizând marginile inferioare şi superioare este numită metoda alfa-beta.
Pentru a determina eficienţa căutării se calculează numărul maxim al nodurilor explorate în
cel mai bun caz. Considerând momentul în care s-a găsit valoarea (k) a primului nod fiu de la
un nod MAX, nodul (n), atunci (n)=(k, ). Dacă beta al nodului părinte (m) al lui (n) este
mai mic sau egal cu (k), nu este necesară evaluarea celorlalte noduri fiu ale lui (n). Dacă
nodul (m) nu este primul nod fiu al părintelui său, valoarea beta este deja dată şi nu poate fi
. Concluzii similare pot fi trase pentru nodurile MIN. În consecinţă, în cel mai bun caz, dacă
nodul (m) nu este primul nod al uni nod părinte, nu este necesară examinarea nici unui nod fiu
decât a primului nod al lui (m).
Nodurile terminale sunt reprezentate prin secvenţa de arce ce le leagă. De exemplu
nodul (12) din figura (g) poate fi exprimat prin secvenţa (1,2,3), adică este atins urmărind
primul arc al lui S, al doilea de la nodul (1) şi al treilea de la nodul (4). Ca urmare nodurile
terminale ale arborelui de adâncime (k) se exprimă prin k-uplul (e1,e2,…,ek). Nodurile ce nu
necesită examinarea sunt cele pentru care ei 1, ei+1 1. În consecinţă nodurile care au fost
examinate în cel mai bun caz, fie sunt noduri numere pare care au în secvenţă (1), fie sunt
noduri numere impare care au în secvenţă (1). Noţiunea de par sau impar se referă la numărul
nodului în adâncimea arborelui.
Dacă se presupune că numărul arcelor posibile de la noduri neterminale este (m),
atunci numărul nodurilor pare No(k,m) şi numărul nodurilor impare Ne(k,m) sunt date prin
următoarele formule:
- dacă k este par: No(k,m)=m(k-1)/2, Ne(k,m)=m(k+1)/2
- dacă k este impar: No(k,m)=Ne(k,m)=mk/2.

87
Nodul (1,1,…,1) este numărat pentru ambele No(k,m) şi Ne(k,m), aşa că Ntotal(k,m)
este No(k,m)+Ne(k,m)-1. Cu aceste precizări se obţine:
- pentru k par: Ntotal(k,m)=m(k-1)/2+m(k+1)/2-1
- pentru k impar: Ntotal(k,m)=2mk/2-1.
În cel mai bun caz, numărul nodurilor ce trebuie examinate prin metoda alfa-beta este
aproximativ acelaşi cu numărul nodurilor ce trebuie căutat prin metoda minimax într-un
arbore de adâncime jumătate.
În cazul cel mai defavorabil toate nodurile vor trebui examinate.
Uzual situaţia este cuprinsă între două extreme, valoarea reală fiind dată prin
inegalitatea
mk/2 < N(k,m) <= mk.

4.2.4. Utilizarea metodelor minimax şi alfa-beta în grafuri ŞI/SAU pentru jocuri

Un arbore specific pentru jocuri este reprezentat ca un graf ŞI/SAU. De exemplu


arborele din figura (f) reprezentat ca un graf este arătat în figura (h).

A B

C D ES F

5 2 1 6
Figura (h) Arbore ŞI/SAU pentru jocuri

Nodurile fiu ale nodurilor MAX corespund la noduri SAU, cele ale nodurilor MIN la
noduri ŞI (nodul de start este văzut ca un nod ŞI). Ca şi la arborii ŞI/SAU nodurile terminale
au valoarea evaluată dată. Costul arcelor este întotdeauna (0). Utilizând metoda minimax, cea
mai bună mutare este determinată prin următoarele metode:
dacă nodurile fiu ale unui nod dat sunt noduri ŞI, valoarea nodului este dată de cea
mai mică valoare evaluată a fiilor săi;
dacă nodurile fiu sunt noduri SAU, valoarea este dată de valoarea maximă dintre
valorile nodurilor fiu ale sale.
În cazul jocurilor pentru care obiectivul este cel de a face valoarea nodului de start
maximă, valorile evaluate sunt în opoziţie faţă de cost, adică cea mai mare valoare evaluată
este cea mai bună. În consecinţă metoda de calcul a valorilor în diverse noduri ale grafului
este diferită de cea utilizată în metodele descrise anterior pentru arbori ŞI/SAU.
Valoarea evaluată a nodului terminal a soluţiei grafului este însăşi valoarea nodului
terminal. Valoarea într-un nod unde fiii sunt noduri ŞI este valoarea minimă din valorile
asociate nodurilor fiu. Valoarea unui nod unde fiii sunt noduri SAU este aceeaşi cu valoarea
nodului fiu. Dacă se scrie valoarea nodului (n) ca f(n), f(A)=2 şi f(S)=2.
Alte soluţii pot apărea din valorile celorlalte noduri. În cazul de faţă soluţia este (1).
Metoda descrisă anterior referitoare la grafuri ŞI/SAU poate fi aplicată şi la arbori de jocuri.

88
Totuşi h’( ) nu este dată de aceeaşi formulă exceptând nodurile terminale. Pentru a obţine
soluţia optimă condiţia f’(n) >= f(n) este îndeplinită pentru toate nodurile (când se urmăreşte
obţinerea soluţiei de cost minim h’(n) <= h(n) pentru toate nodurile). În consecinţă dacă
valorile punctelor terminale nu sunt date, valorile inferenţiale ale arborilor candidat sunt
infinit de mari. Presupunând că la expandarea nodurilor neterminale ale grafului candidat
nodurile fiu sunt noduri ŞI, ele se expandează în acelaşi moment. Dacă se notează primul nod
fiu cu (n1) (nod ŞI) al lui (ni), se poate lua f’(n) <= f(n1). Aşa se poate calcula f’ şi reactualiza
în timpul procesului de căutare. Asemănător cu metoda de căutare optimală descrisă anterior,
principiul acestei metode este bazat pe faptul că un graf candidat adus din open_list va fi
expandat după cea mai mare valoare inferenţială.
În arbori ŞI/SAU pentru jocuri găsirea soluţiei necesită nu numai nodul terminal care
dă valoarea soluţiei arborelui, ci şi drumul urmat pentru ca pornind de la nodul de start acesta
să fie atins. Pentru transpunerea algoritmului, prin convenţie se va nota cu EXPL nodurile
atinse ce nu au starea SOLVED. În acest context starea nodului (n) este dată de tripletul (n, s,
v) în care (s) indică faptul că nodul (n) este SOLVED sau EXPL, (v) dă valoarea lui f(n) dacă
(n) este SOLVED sau f’(n) dacă el este EXPL. Starea nodului (n) este pusă în open_list
printr-o procedură pe care am notat-o putopen(n, s, v). De asemenea se va scrie pentru nodul
părinte parent(n), nodul terminal n ca terminal(n) şi pentru a detecta un nod (n) ca fiind
ŞI/SAU s-a utilizat funcţia type(n). Algoritmul de căutare în astfel de situaţii este:

putopen (S,EXPL,f’(n));
while true
{
if open=goală then exit(fail);
n=first(open);
if (n=S & SOLVED(n)) then exit(succes);
remove (n,open);
/*1*/ if ((S=EXPL) & (type(n)=AND) & not_terminal(n))
then pentru toate nodurile fiu (ni) ale lui (n)
putopen (n, EXPL, f’(n));
/*2*/ if ((S=EXPL) & (type(n)=OR)) & not_terminal(n))
then
{next_n=next_fiu()
if (next_n=SOLVED) then
putopen (n, SOLVED, f(n));
else putopen (n, EXPL, f’(n));}
/*3*/ if ((S=EXPL) & terminal(n))
putopen (n, SOLVED, min(f’(n), f(n));
/*4*/ if ((S=SOLVED) & (type(n)=AND))
putopen (parent(n), EXPL, f’(n));
/*5*/ if ((S=SOLVED) & (type(n)=OR))
{m=parent(n); /*mută toate nodurile fiu ale lui (m) în open_list
putopen(n, SOLVED, f’(n);}
}

Pentru exemplificarea metodei se consideră graful din figura (i):

89
0

1 2 3

4 5 6 7 8 9 10 11 12

13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

4 3 3 2 6 5 4 2 3 4 3 6 3 5 5 4 6 8

Figura (i) Căutarea soluţiei optime în arbore de joc ŞI/SAU

Aşa cum se vede din tabelul de rezultate, metoda alfa-beta este dependentă de ordinea
nodurilor.

Pas Proc Open_list în care S este SOLVED, E este EXPL


1 (0,E, )
2 1 (1,E, ),(2,E, ),(3,E, )
3 2 (4,E, ),(2,E, ),(3,E, )
4 1 (13,E, ),(14,E, ),(2,E, ),(3,E, )
5 3 (14,E, ),(2,E, ),(3,E, ),(13,S,4)
6 3 (2,E, ), (3,E, ),(13,S,4),(14,S,4)
7 2 (7,E, ), (3,E, ),(13,S,4),(14,S,3)
8 1 (19,E, ), (20,E, ),(3,E, ),(13,S,4),(14,S,3)
9 3 (20,E, ), (3,E, ),(13,S,4),(19,S,4),(14,S,3)
10 3 (3,E, ), (13,S,4),(19,S,4),(14,S,3),(20,S,2)
11 2 (10,E, ), (13,S,4),(19,S,4),(14,S,3),(20,S,2)
12 1 (25,E, ), (26,E, ),(13,S,4),(19,S,4),(14,S,3),(20,S,2)
13 3 (26,E, ), (13,S,4),(19,S,4),(14,S,3),(25,S,3),(20,S,2)
14 3 (26,S,5), (13,S,4),(19,S,4),(14,S,3),(25,S,3),(20,S,2)
15 5 (10,S,5),(13,S,4),(19,S,4),(14,S,3),(20,S,2)
16 4 (3,E,5),(13,S,4),(19,S,4),(14,S,3),(20,S,2)
28 5 (S,S,5),(13,S,4),(19,S,4),(4,S,3),(20,S,2)

În cazul grafului din figura (i) dacă nodul (3) ar fi în locul nodului (1) soluţia optimă
ar fi găsită mult mai rapid. În algoritm au fost notate cele 5 situaţii ce sunt ilustrate şi în
tabelul precedent, pentru a uşura cititorul în înţelegerea algoritmului.
Spre deosebire de căutarea optimală obişnuită care explorează mai întâi nodurile cele mai
promiţătoare şi a cărei eficienţă nu este afectată de aranjarea nodurilor, metoda alfa-beta este
dependentă de aceasta. În al doilea rând memoria necesară pentru algoritmul alfa-beta este
mult mai redusă. Alegerea uneia din cele două metode este dependentă de performanţele
dorite din punctul de vedere al vitezei de calcul şi al memoriei necesare.

90
4.3. Exerciţii

A.1. Exerciţii rezolvate.

Exerciţiul 1. Exemplu de aplicare a metodelor minimax si alfa-beta .

Se consideră un exemplu de joc de două persoane cu informaţie completă care este


arătat în figura 4.1. unde jocul este descris ca un arbore cu un nod rădăcină care este poziţia
de pornire iar nodurile terminale sunt poziţiile de sfârşit. Aceste noduri terminale sunt
etichetate fiecare cu 1 sau –1, depinzând de care din jucători câştigă jocul.
Într-un joc ca acesta, unul dintre jucători va încerca să aleagă un nod etichetat cu -1 şi
altul va încerca să aleagă un nod etichetat cu 1. Îi putem cere jucătorului să încerce să obţină
rezultatul -1, minimizare, şi altui jucător să maximizeze. Vom spune că aceasta este o mişcare
de îndepărtare de poziţia de start din figura 4.1. care corespunde nodului rădăcină a. Această
tehnică de rezolvare este cunoscută ca mini-max.

Rezolvare.
Care este, spre exemplu, valoarea nodului o în această poziţie? Este o încercare de
maximizare şi orice mutare care se va face va termina jocul. Se poate muta în oricare dintre
poziţiile p sau r şi se pierde sau se poate muta în poziţia q şi se câştigă. Numim aceasta ca
fiind sensibilitatea jocului; evident că se va alege q. Aceasta înseamnă că, în realitate nodul o
este câştigător pentru maximizare şi poate fi etichetat cu 1.

Figura 4.1. Un arbore de joc.


Nodurile cu maximizatorul la mutare sunt pătrate; cele cu minimizatorul la mutare sunt
cercuri.

Dar despre nodul k ce putem spune? Indiferent ce va face minimizatorul,


maximizatorul va câştiga imediat dacă minimizatorul mută în nodul n sau într-o singură
mutare dacă mută în nodul o. Deci putem eticheta pe k cu 1. Nodul i este altfel; pentru că
minimizatorul are o opţiune câştigătoare disponibilă m. Deci acest nod poate fi etichetat cu -1.

91
Figura 4.2. Maximizatorul câştigă.

Algoritmul pentru reîntoarcerea valorilor către partea superioară din arbore este acum
evident. Un nod în care maximizatorul este la mutare poate fi etichetat cu valoarea maximă
care etichetează oricare dintre fii săi. Un nod în care minimizatorul mută poate fi etichetat cu
minimumul etichetelor fiilor săi. Acest lucru este făcut în figura 4.2., şi se poate vedea că
poziţia de start este etichetată cu 1, ceea ce într-un joc cu informaţie completă va conduce la
câştigarea jocului de către maximizator.
Înainte de a enunţa procedura de rezolvare, să presupunem că ne întoarcem deasupra
nodului k, determinând că g şi c au valoarea 1. Putem acum să oprim analiza şi să
concluzionăm că valoarea ce va fi atribuită lui a este de asemenea 1! Motivul este acela că
ştim că maximizatorul poate învinge din nodul a printr-o mutare în nodul c şi nu este nici un
motiv să căutăm o altă alternativă pentru această linie câştigătoare.
Iată algoritmul de bază pentru determinarea valorilor ce vor fi ataşate nodurilor interne
într-un arbore de joc .

PROCEDURA 4.1 Mini-max - pentru a evalua un nod n într-un arbore de joc .

1) Expandează întregul arbore de sub n .


2) Evaluează nodurile terminale ca fiind câştigătoare pentru minimizator
sau pentru maximizator .
3) Selectează un nod neetichetat, pentru care toţi fii săi au ataşate valori (etichete).
Dacă nu există un astfel de nod, returnează valoarea ataşată nodului n.
4) Dacă nodul selectat este unul dintre cele în care minimizatorul mută, se ataşează
acestuia o valoare care este minimul dintre valorile fiilor săi. Dacă este un nod
maximizator, i se ataşează valoarea care este maximul valorilor fiilor săi.
Reîntoarcere la pasul 3.

Dacă jocul se termină în situaţia în care ambii jucători au şanse egale – spre exemplu a
unei remize în jocul de şah - aceasta ar corespunde unei poziţii terminale etichetate cu 0 în loc
de -1 sau 1. Remizele se potrivesc foarte bine cu formalismul mini-max, deoarece fiecare
jucător încearcă, dacă este posibil, o mutare câştigătoare şi va căuta o posibilitate de remiză
dacă nu există câştigători.

92
Ca o problemă de terminologie, printr-o mutare într-un arbore de joc înţelegem o
pereche de acţiuni individuale, una pentru fiecare jucător. O acţiune dusă doar cu un singur
jucător este numită o jumătate de mutare sau un strat. Astfel, adâncimea arborelui din figura
4.2. este de 3 mutări sau de 6 straturi.
Câtă memorie şi cât timp sunt necesare pentru un algoritm mini-max în procedura
4.1.? Deoarece întreg arborele trebuie să fie expandat, ne putem aştepta ca această procedură
să aibă nevoie de o cantitate exponenţială de spaţiu, după cum întreaga ramificaţie, are nevoie
aparent să fie stocată înainte ca valorile superioare să fie refăcute. Să remarcăm faptul că,
spaţiul necesar poate fi redus la o cantitate liniară în adâncime printr-o căutare verticală sau
în adâncime în loc de o căutare orizontală sau în lăţime. De aceea, în figura 4.2. putem
întoarce valoarea -1 nodului superior b înainte de a extinde fiii nodului c, şi aşa mai departe.
Aceasta va produce următorul rezultat, unde se actualizează valorile asignate nodurilor interne
după cum valorile sunt asignate fiilor săi:

PROCEDURA 4.2. Mini-max - pentru a evalua un nod n într-un arbore de joc:


1) Fie L ={n}, mulţimea nodurilor neexpandate din arbore.
2) Fie x primul nod din L. Dacă x=n şi există o valoare ataşată lui, returnează
această valoare .
3) Dacă lui x i se va ataşata o valoare vx , fie p un părinte al lui x şi vp valoarea
curentă ataşată lui p. Dacă p este un nod de minimizare atunci ia vp=min (vp,vx).
Dacă p este un nod de maximizare, atunci ia vp=max (vp,vx). Şterge x din L şi
întoarce-te la pasul 2 .
4) Dacă lui x nu i-a fost ataşată nici o valoare şi este un nod terminal, ataşează-i
valoarea 1 sau -1, după cum câştigător este maximizatorul sau respectiv
minimizatorul. Ataşează lui x valoarea 0 dacă poziţia este o remiză. Lasă x în L (avem
încă de-a face cu părinţii săi) şi întoarce-te la pasul 2 .
5) Dacă x nu are ataşată o valoare şi nu este un nod terminal, dă lui vx valoarea ,
dacă x este un nod de maximizare şi , dacă x este un nod de minimizare. (Aceasta
ca să fim siguri că prima minimizare sau maximizare de la pasul 4 are sens). Se
adaugă fiii lui x în capul listei L şi întoarce-te la pasul 2.

Din păcate, procedura 4.2. are nevoie de o cantitate exponenţială de timp pentru a
determina valoarea care va fi ataşată nodului n. În general, nu este practic să se extindă
întregul arbore; ca exemplu, arborele jocului de şah conţine aproximativ 10160 noduri (graful
poziţiilor de şah este întrucâtva mai mic deoarece multe poziţii pot fi atinse în diferite
moduri). Cum reuşesc oamenii să joace un astfel de joc? Nu-i putem analiza toate căile până
la sfârşit; putem doar să privim situaţia astfel încât să putem estima care este jucătorul cel mai
probabil să învingă într-o poziţie neterminală şi să refacem apoi valorile spre partea
superioară a arborelui din poziţiile neterminale pe care le-am găsit. Mini-max se aplică încă;
trebuie doar să-l aplicăm nodurilor interne din arbore .

Exerciţiul 2.
Problema cu privire la căutarea în jocul de şah se rezumă la căutarea în arbori a unor
noduri cu proprietăţi matematice certe. Ca rezultat, multe din nodurile examinate în timpul
căutării pentru o mutare, nu au nici o legătură cu desfăşurarea jocului - ele devin fără sens şi
în cel mai rău caz sinucigaşe. Programul jocului de şah consideră irelevante mişcările pionului
şi piesele fără valoare se sacrifică cu aceeaşi grijă cu care se iau în considerare combinaţiile
învingătoare sau avansările poziţionale prudente. Dacă vrem să îmbunătăţim performanţele
acestor programe, avem nevoie de o cale de a reduce mărimea spaţiului de căutare. Cea mai

93
puternică tehnică cunoscută pentru a face acest lucru este denumită căutarea pe care o
vom aplica pe un set de jocuri reprezentate prin arbori de joc corespunzători.

Rezolvare.
La căutarea din figura 5.5 observăm că, odată ce realizăm că maximizatorul poate
învinge prin mutare la c, nu mai este nevoie să analizeze alte opţiuni ale lui din a. Şi anume,
valorile asignate tuturor nodurilor de sub nodul b cu siguranţă nu afectează valoarea totală
asignată pentru poziţia a.

În exemplul din figura 5.6. considerăm opţiunea c de atacare a reginei adversarului şi


presupunem ca de obicei că suntem jucătorul care maximizează.

Dacă atacăm regina adversarului, putem fi făcuţi mat la următoarea mutare, în felul acesta se
sfârşeşte jocul şi rezultatul va fi -1. Evident, nu este nevoie să luăm în considerare nici un alt
nod care este fiu al lui c.

94
În exemplul din figura 5.7. presupunem că analizăm arborele în maniera căutării în
adâncime şi determinăm valoarea care va fi asignată nodului b care este 0.03. Continuăm prin
examinarea opţiunii din c, atacând regina adversarului cu regina proprie.
Primul răspuns considerăm că este d, implicând un schimb de regine. O examinare
viitoare a fiilor lui d, deci a lui e şi f, arată că f este cea mai bună dintre cele două mutări şi
conduce la o valoare de -0.05 pentru nodul d.
Este posibil să fie c selecţia? Dacă mutăm la c, cel mai bun rezultat pe care ne
aşteptăm să-l obţinem este -0.05, deoarece acesta rămâne cel mai bun dacă adversarul replică
cu d. Dacă g este mai bună pentru adversar decât este d, valoarea care va fi asignată lui c va fi
chiar mai mică decât -0.05. De ce trebuie să acceptăm nişte valori slabe când putem obţine un
rezultat de 0.03 prin mutarea la nodul b ?
Ceea ce vrem să arătăm, de fapt, este că nodul c nu este niciodată pe linia principală,
aceasta fiind cursul jocului când ambii jucători joacă optim. Deoarece b este mai bun pentru
maximizator decât este c şi maximizatorul poate selecta între ele, c va fi evitat în mod
garantat. Valorile asignate lui g şi nodurilor de sub el nu pot influenţa niciodată valoarea
finală asignată nodului a iar subarborele de sub g poate fi şters.
Putem găsi aceeaşi soluţie pe cale algebrică. Dacă notăm cu g valoarea anterioară
asignată nodului g, atunci valoarea asignată nodului c va fi :
c = min( -0.05, g)
deoarece el este minimizatorul cel care va alege între alternativele d şi g.
Continuând, valoarea asignată nodului rădăcină a este
a=max[0.03, min( -0.05, g)] = 0.03 (5.2)
unde a doua egalitate se menţine deoarece min(-.05, g) -.05 < .03. Deoarece valoarea
asignată nodului a este independentă de valoarea g, observăm că nodurile de sub g pot fi
şterse.

În exemplul din figura 5.8. valorile asignate lui b şi lui f sunt .03 şi respectiv -1. Ce
putem spune despre fiii nodului g? Se poate arăta că g nu este pe o linie principală?
Dacă g ar fi pe o linie principală, atunci şi strămoşii lui trebuie să fie pe linia
principală, deci şi e va fi pe o linie principală. Dar din e, minimizatorul are şansa de a se muta
în f şi să obţină un rezultat de -.1. Deoarece acesta este mai prost decât rezultatul de .03 pe
care maximizatorul îl poate obţine prin mutarea în b, rezultă că g nu poate fi pe o linie
principală. Notăm că este posibil ca h să fie pe o linie principală, sau ca i să fie, însă putem
spune cu siguranţă că g nu este. O situaţie cum este aceasta, unde nodul şters este la mai mult

95
de un strat sub cel care îl referim ca motivul ştergerii, este cunoscută ca fiind ştergerea
în adâncime.
Ce se poate spune despre acest caz general? Presupunem că n este un nod oarecare
într-un arbore de joc la care maximizatorul ajunge la mutare (cum ar fi nodul g în figura 5.8),
şi că s este frate cu n având o valoare de întoarcere vs (s va putea fi nodul f în figura de
deasupra, astfel că vs = -.1). Presupunem, de asemenea, că (p0, p1, ..., pk) este calea de la nodul
rădăcină în jos spre n, cu p0 - nodul rădăcină şi pk = n.

Vom mai face remarca că nodurile cu indicii impari (p1, p3, …etc.) sunt noduri
minimizante; dacă oricare din aceste noduri are un frate cu o valoare de întoarcere mai mare
decât vs, atunci nodul n poate fi şters. (În figură p1 = c are un frate b cu valoarea .03 > vs). Iată
o altă cale de exprimare a acestei situaţii şi anume procedura de căutare .

Procedura 4.3. Căutarea . Pentru evaluarea unui nod n într-un arbore joc:
1. Pune L = {n}.
2. Fie x primul nod din L. Dacă x = n şi există o valoare asignată lui, returnează
această valoare.
3. Dacă lui x i-a fost asignată o valoare vx, fie p părintele lui x; dacă lui x nu i-a fost
asignată o valoare, treci la pasul 5. Prima dată determinăm dacă p şi fiii săi pot
sau nu să fie şterşi din arbore: dacă p este un nod minimizat, atunci fie
maximul tuturor valorilor curente asignate fraţilor lui p şi nodurilor
minimizante care sunt strămoşii lui p (dacă nu există astfel de valori, luăm
). Dacă vx ştergem pe p şi pe toţi descendenţii săi din L. Dacă p este
un nod maximizant, îl tratăm în mod similar.
4. Dacă p nu poate fi şters, fie vp valoarea curentă asignată lui p. Dacă p este un
nod minimizant, luăm vp= min(vp , vx). Dacă p este un nod maximizant, luăm vp
= max(vp , vx). Ştergem pe x din L şi ne reîntoarcem la pasul 2.
5. Dacă lui x nu i-a fost asignată o valoare şi este fie un nod terminal fie noi
decidem să nu lărgim arborele mai departe, îi calculăm valoarea utilizând
funcţia de evaluare. Reîntoarcere la pasul 2.

96
6. În caz contrar, luăm vx ca fiind - dacă x este un nod maximizant şi + dacă
este un nod minimizant. Adăugăm toţi copiii lui x în fruntea listei L şi ne
întoarcem la pasul 2.

Valoarea care corespunde lui dar care este calculată ţinând cont de strămoşii
maximizanţi ai lui p este cunoscută sub numele de : cele două valori şi conduc
separat la ştergere. Din această cauză, această metodă de reducere a mărimii arborelui de
căutare este cunoscută sub numele de ştergerea .
Deşi am văzut că ştergerea poate reduce mărimea spaţiului de căutare asociat
unui arbore de joc, nu putem realiza cât de mult spaţiu de căutare este redus.
Este clar, de exemplu, că în cel mai rău caz este posibil ca ştergerea să nu poată
reduce dimensiunea spaţiului de căutare la maximum. Dacă suntem perseverenţi în aranjarea
fiilor fiecărui nod astfel încât opţiunile proaste să fie evaluate primele, atunci nodurile
examinate mai târziu vor fi întotdeauna în “linia principală” şi prin urmare nu vor fi niciodată
şterse.

A.2. Teste de autocontrol.

Testul 1

1. Daţi un exemplu de problemă de căutare unde urcarea dealului şi cea mai bună
primă căutare se comportă diferit.

' '
2. Presupunem că h1 şi h2 două euristici admisibile într-o problemă de căutare.
' '
Arătaţi că max(h1 , h2 ) este de asemenea admisibilă. Daţi un exemplu de problemă de căutare
şi două funcţii euristice admisibile nici una din ele întotdeauna să nu fie mai mică decât
cealaltă.
'
3. Cum se comportă algoritmul A* dacă h h ? Demonstraţi afirmaţiile voastre.
4. Acest exerciţiu examinează alegerea între două funcţii euristice admisibile din
' '
care una este mereu mai mică decât alta. Presupunem că h1 şi h2 sunt două funcţii euristice
' '
admisibile pentru un domeniu oarecare şi deci h1 (n) h2 (n) pentru fiecare nod.
(a) Fie S ordinea de căutare pentru care căutarea A* este legală folosind euristica
h1' şi presupunem că aceasta explorează spaţiul de căutare folosind această ordine care
implică expandarea unei mulţimi de N noduri. Arătaţi că există câteva ordine de căutare
'
pentru care A* este legală folosind euristica h2 care examinează o submulţime al lui N în
'
rezolvarea problemei în cauză. Aceasta arată că este întotdeauna posibil ca h2 să conducă
'
către un spaţiu mai mic de căutare decât o face h1 .
' ' '
(b) Găsiţi o problemă de căutare şi două euristici admisibile h1 şi h2 cu h1 h2'
' '
astfel încât deşi este posibil ca h2 să examineze mai puţine noduri decât h1 , este de departe
'
mai ca sigur ca h1 să conducă la căutarea cea mai eficientă.
5. În ce ordine examinează IDA* spaţiul de căutare asociat celor 2 labirinte ce apare
în figura 4.10.

97
Figura 4.10.

B. TEMA DE CONTROL

1. Aplicaţi algoritmul de căutare A* în graful prezentat mai jos:

Indicaţie. Valoarea lui h’(n) este dată în paranteze asociate nodului. Schimbările în open_list
obţinute prin utilizarea algoritmului A* sunt marcate de indicarea lui f’(n) în parantezele
asociate nodurilor. Se va obţine secvenţa de noduri în open_list.

2. Să se aplice metoda de căutare în adâncime şi metoda de căutare în lăţime


următorului graf ştiind că nodul obiectiv este G şi să se prcizeze drumul parcurs în fiecare caz.
Căutarea porneşte de la nodul S şi continuă până când nodul obiectiv este atins.

98
3. Să se rezolve prin metode de căutare cu ramificare şi limitare problema comis-
voiajorului.
Un comis voiajor ce lucrează într-un oraş X trebuie să ajungă odată pe lună într-o serie
de oraşe în care are de dus obiecte sau de luat obiecte. Firma la care lucrează suportă costul
transportului de la oraşul X la fiecare din oraşele de destinaţie. Problema comis voiajorului
este de a stabili acel traseu pentru care pornind din oraşul X să atingă toate oraşele din traseu
cu destinaţia finală oraşul X, astfel încât costul transportului să fie minim. În afară de
informaţiile alternative ce reprezintă costul transportului între oraşul X şi oraşele învecinate
sunt necesare informaţii despre costul deplasării între oraşele din traseu.
Considerăm harta asociată circuitului, cu costurile corespunzătoare, ca fiind
următoarea:
F

10 4

6
D A
12 7

15 8

11 5
X

D B
25

17 9

C
Indicaţie. Matricea costurilor care are ca elemente costurile corespunzătoare dintre
două localităţi şi pentru drumul dintre oraşul A şi A (acesta nefiind un drum valid) ca şi în
cazul în care între două oraşe nu există legătură directă este următoarea:

99
X A B C D E F
X ∞ 7 5 25 11 12 6

A 7 ∞ 8 4

B 5 8 ∞ 9

C 25 9 ∞ 17

D 11 17 ∞ 15
K=
E 12 15 ∞ 10

F 6 4 10 ∞

BIBLIOGRAFIE RECOMANDATĂ LA MODULUL 2:

1. Podaru Vasile, Inteligenţă artificială şi siteme expert, Editura Academiei Tehnice Militare,
1997
2. Podaru Vasile, Barnoschi Adriana, Sisteme expert, Editura Academiei Tehnice Militare,
2000, 2004.
3. Ioan Georgescu, Elemente de inteligenţă artificială, Editura Academiei RSR, 1985.
4. Podaru Vasile, Inteligenţă artificială, curs în format electronic, CD-învăţământ la distanţă,
Universitatea Titu Maiorescu, 2010.
5. D. Cîrstoiu, Sisteme expert, editura ALL, 1994.
6. SICSTUS PROLOG USER’S MANUAL. Intelligent Systems Laboratory, Sweedish Institute
of Computer Science:
http://www.sics.se/isl/sicstuswww/site/documentation.html
7. M. Maliţa, Bazele inteligenţei artificiale, editura Academiei Române, 1988.

Coordonator disciplină:
Prof. univ. dr. Vasile PODARU, email: podaruv@gmail.com

Tutori: Prof. univ. dr. Vasile PODARU.

100
UNIVERSITATEA TITU MAIORESCU
Facultatea de INFORMATICĂ

Prof. univ. dr.


VASILE PODARU

Curs pentru învăţământul la distanţă

BUCUREŞTI – 2011
UNIVERSITATEA Titu MAIORESCU Bucureşti
Facultatea de Informatică
Învăţământ la Distanţă

INTELIGENŢĂ ARTIFICIALĂ
Inteligenţa artificială este una din disciplinele de pregătire fundamentală care, pentru
profilul INFORMATICĂ, este esenţială pentru pregătirea studenţilor şi pentru obţinerea
creditelor transferabile prin procedurile de evaluare. Modul de prezentare a acestui material
are în vedere particularităţile învăţământului la distanţă, la care studiul individual este
determinant. Pentru orice nelămuriri faţă de acest material vă rugăm să contactaţi tutorele de
disciplină care are datoria să vă ajute oferindu-vă toate explicaţiile necesare.
Disciplina de Inteligenţa artificială îşi propune următoarele obiective specifice:
Însuşirea noţiunilor fundamentale din domeniile Inteligenţei artificiale.
Formarea deprinderilor de modelare matematică şi de transpunere în programare a
unor probleme de natură tehnică, socială sau economică, cu utilizarea cunoştinţelor
însuşite.
Formarea şi dezvoltarea aptitudinilor şi deprinderilor de analiză logică, formulare
corectă şi argumentare fundamentată, în rezolvarea problemelor tehnico-economice şi
de specialitatecu cu utilizarea cunoştinţelor însuşite prin intermediul metodelor şi
modelelor specifice inteligenţei artificiale;
Insusirea principiilor generale ale programarii logice si insusirea limbajului Prolog;
O comparaţie critică a metodelor de rezolvare evidenţiind, eventual, calea optimă de
soluţionare.
Accentul se va pune pe problemele de cautare si reprezentare a cunostintelor si
respectiv pe programarea logica, limbajul de programare utilizat la laborator fiind
limbajul Prolog. Cursul trebuie sa trateze aspecte ale rezolvarii problemelor prin
intermediul cautarii, descriind cele mai importante tehnici de cautare informata si
neinformata. Se vor da exmple de aplicatii ale cautarii, cum ar fi jocurile, tratate ca
probleme de cautare. Se vor prezenta principalele tipuri de cunostinte si principalele
metode de reprezentare a cunostintelor. Se va face legatura dintre reprezentarea
cunostintelor si sistemele expert. Se va da un exemplu de sistem expert cu
implementare in Prolog. Vor mai fi tratate, ca modalitati de reprezentare a
cunostintelor, retelele semantice si retelele Bayesiene (cu introducerea rationamentului
statistic).

Vă precizăm de asemenea că, din punct de vedere al verificărilor şi al notării (elemente


ce vor fi comunicate şi prin fişa disciplinei, calendarul disciplinei şi programarea orară), cu
adevărat importantă este capacitatea pe care trebuie să o dobândiţi şi să o probaţi de a rezolva
toată tipologia de probleme aplicative aferente materialului teoretic prezentat în continuare.
De aceea vă recomandăm să parcurgeţi cu atenţie toate aplicaţiile rezolvate, să rezolvaţi
aplicaţiile propuse prin testele de autoevaluare şi temele de control (pentru fiecare modul în
parte trebuie să predaţi tutorelui de disciplină rezolvarea acestor teme, pentru verificare şi
evaluare); fiţi convinşi că examenul final apelează la tipurile de aplicaţii prezente în secţiunile
menţionate anterior.
Timpul mediu necesar însuşirii noţiunilor teoretice, formării deprinderilor de calcul şi
utilizării metodelor de rezolvare a problemelor specifice acestui modul este estimat la

102
aproximativ 6-8 ore pentru întregul modul , într-un ritm de 3-4 ore pentru fiecare din cele
două unităţi ale modulului.
Întru-cât modulul este privit ca un tot unitar exerciţiile aferente acestui modul se
găsesc la sfârşitul acestui modul. La terminarea parcurgerii acestui modul studenţii trebuie să
prezinte tutorelui de disciplină rezolvarea temei de control propusă spre rezolvare la sfîrşitul
modulului.
Cursul se finalizează prin examen care constă din:
1) o lucrare scrisă sub forma de text grila constând din 9-18 subiecte (ponderea lucrării
scrise este de 70% din nota finală);
2) rezolvarea corectă a temelor de control din cele 4 module (minimum nota 5 pentru
fiecare temă, ponderea mediei celor 5 note în nota finală este de 20%);
3) participarea activă la activităţile tutoriale (apreciată printr-o notă a cărei pondere in
nota finală este de 10%).

Coordonator disciplină: Prof. univ. dr. Vasile PODARU, email: podaruv@gmail.com


Tutori: Prof. univ. dr. Vasile PODARU,

103
MODULUL 3

METODE DE ÎNVĂŢARE.
REŢELE NEURONALE.

Îndrumări metodice.

Inteligenţa artificială a apărut ca disciplină şi a fost fundamentată pe investigaţiile


relative la reprezentarea cunoaşterii şi căutarea dar nu numai.
Învăţarea constitiue unul din domeniile importante din inteligenţa artificială. Statutul
învăţării în AI este asemănător celui al planificării, doar că problemele sunt mai grele şi
soluţiile recunoscute sunt mai rare. Într-o încercare de a face acest subdomeniu al AI oarecum
inteligibil, vom separa învăţarea în învăţare prin descoperire şi învăţare prin generalizare.
Prin învăţare prin descoperire înţelegem acel tip de învăţare, prin care se ajunge la o
concluzie nouă. Prin învăţare prin generalizare înţelegem extrapolarea de la informaţia
existentă la un model mai general.
În partea a doua a acestui modul se prezintă problematica reţeţelor neuronale. Una din
problemele cele mai dificile, pe care trebuie sa le rezolve inteligenta artificiala, este
generata de necesitatea dominării complexităţii informaţionale a domeniilor abordate.
Această nouă abordare a sistemelor inteligente presupune construirea de calculatoare
cu o arhitectură şi capacitate de procesare care să imite anumite abilităţi de procesare ale
creierului. Rezultatul îl constituie reprezentările de cunoştinţe bazate pe o importantă
procesare paralelă, pe acumularea rapidă a unor mari cantităţi de informaţii şi pe capacitatea
de a recunoaşte modele pe baza experienţei. Tehnologia care încearcă să obţină aceste
rezultate este numită procesare neuronală sau reţele neuronale.
Reţelele neuronale sunt tehnologii de prelucrare a informaţiei bazate pe studiile
asupra creierului uman şi a sistemului nervos. Cercetările în domeniu s-au intensificat în
ultimii ani, cunoscând în prezent o mare popularitate, datorită progreselor înregistrate
atât în tehnologia calculatoarelor, cât şi” în domeniul neurologiei, în direcţia unei mai bune
înţelegeri a mecanismelor creierului uman.
Întru-cât modulul este privit ca un tot unitar exerciţiile aferente acestui modul se
găsesc la sfârşitul acestui modul. La terminarea parcurgerii acestui modul studenţii trebuie să
prezinte tutorelui de disciplină rezolvarea temei de control propusă spre rezolvare la sfîrşitul
modulului.
Cursul se finalizează prin examen care constă din:
1) o lucrare scrisă sub forma de text grila constând din 9-18 subiecte (ponderea lucrării
scrise este de 70% din nota finală);
2) rezolvarea corectă a temelor de control din cele 5 module (minimum nota 5 pentru
fiecare temă, ponderea mediei celor 5 note în nota finală este de 20%);
3) participarea activă la activităţile tutoriale (apreciată printr-o notă a cărei pondere in
nota finală este de 10%).

104
Unitatea de învăţare nr.5

Învăţarea.
Cuprins:
5.0. Introducere ................................................................................................. pag. 105
5.1. Învăţarea prin descoperire .......................................................................... pag. 105
5.2. Învăţarea prin generalizare ......................................................................... pag. 107
5.2.1. Învăţarea inductivă ................................................................................. pag. 107
5.2.1.1. Învăţarea probabil aproximativ corectă ................................................ pag. 108
5.2.1.2. Algoritmul lui Mitchell ........................................................................ pag. 111
5.2.1.3. Învăţarea unor inegalităţi ...................................................................... pag. 113
5.2.1.4. Algoritmul lui Quilan ........................................................................... pag. 115

5.0. Introducere.

Statutul învăţării în AI este asemănător celui al planificării, doar că problemele sunt


mai grele şi soluţiile recunoscute sunt mai rare. Într-o încercare de a face acest subdomeniu al
AI oarecum inteligibil, vom separa învăţarea în: învăţare prin descoperire şi învăţare prin
generalizare. Prin învăţare prin descoperire înţelegem acel tip de învăţare, prin care se ajunge
la o concluzie nouă. Prin învăţare prin generalizare înţelegem extrapolarea de la informaţia
existentă la un model mai general. De exemplu, concluzia că o anume ciupercă mare şi
galbenă este otrăvitoare, doarece toate ciupercile mari şi galbene sunt otrăvitoare.
Învăţarea prin generalizare poate fi împărţită în două subtipuri. Vom numi învăţarea
prin generalizare care este logic validă, învăţare prin generalizare deductivă. De exemplu, să
presupunem că vrem să ajungem la casa unui prieten; n-am mai fost acolo niciodată şi un
traseu care arată bine pe hartă nu poate fi urmat doarece una din străzi este cu sens unic. Data
viitoare când vom vizita prietenul, n-ar trebui să mai urmăm acel traseu; putem deduce că
strada va fi tot cu sens unic şi vom avea aceleaşi probleme ca data trecută.
Cele mai multe instanţe ale învăţării prin generalizare nu sunt însă deductive. Învăţarea
prin generalizare non-deductivă este numită inductivă. În acest capitol, vom examina ambele
abordări.
Deductivă sau nu, toată învăţarea este o formă de inferenţă - scopul este să începem cu
o informaţie din domeniu, iar apoi să o extindem într-un anumit fel. Cea mai mare parte a
învăţării este non-deductivă şi este oricum, inferenţă.

5.1 Învăţarea prin descoperire

A existat doar un singur program AI încununat de succes, care a încercat să înveţe


lucruri noi prin descoperirea lor. Este o lucrare veche, dar importantă; programul a fost scris
de Doug Lenat pentru teza sa de doctorat la Stanford şi s-a numit AM.
Datele de intrare pentru AM erau de două tipuri: mai întâi, o descriere a unor concepte
ale teoriei mulţimilor, în forma unor funcţii implementate în LISP. Informaţia iniţială a lui
AM includea descrieri ale mulţimii reuniune şi intersecţie, mulţimii vide, etc. Al doilea tip de
date de intrare pentru AM erau informaţii despre "cum să faci matematică", pe care Lenat le-a
luat din cartea lui George Polya intitulattă “How to solve it” (cum să rezolvi) şi din alte surse.
Un exemplu de informaţie furnizată lui AM este că dacă s-a decis că f(x,y) este o funcţie de
două argumente, iar argumentele ar putea fi egale, atunci funcţia f(x,y) poate fi o funcţie de un
singur argument. Astfel, dacă programul reuşea să "inventeze" operaţia de adunare şi dacă

105
decidea că este interesantă, funcţia x+x ar putea fi probabil o funcţie de un singur argument.
Se spera prin acest tip de reguli ca AM să inventeze înmulţirea o dată ce ar fi descoperit
adunarea.
Scopul lui AM era să dezvolte concepte matematice interesante. Exact asta a şi făcut.
De fapt, dându-i-se doar informaţia de mai sus, a "descoperit":
 Întregii. AM a învăţat destul de devreme că e posibil să numeri elementele oricărei
mulţimi şi a decis că imaginea acestei funcţii de numărare- întregii este ea însăşi o mulţime
interesantă.
 Adunarea. Mulţimile disjuncte erau interesante şi de asemenea, reuniunea
mulţimilor era interesantă. Imaginea operaţiei "ia reuniunea mulţimilor disjuncte" sub funcţia
de numărare descrisă anterior este adunarea.
 Înmulţirea. Aceasta a fost descoperită folosind o regulă ca cea prezentată mai sus.
Lenat a intervenit şi a dat maşinii descrieri mai clare ale adunării şi înmulţirii, care
fuseseră mai înainte descrise în termeni de operaţii laborioase de mulţimi teoretice. Efectul
acestui lucru a fost doar de a face deliberările ulterioare ale maşinii mai eficiente; nu s-a
produs nici o schimbare de fond.
 Numerele prime. Descoperind înmulţirea, maşina a descoperit rapid că numerele
pot fi factorizate, fiind cel mai mult interesată de numerele care aveau un singur factor. Dacă
există o funcţie f şi o valoare y în domeniul lui f, mulţimea lui x astfel încât f(x)=y ar putea fi
interesantă. Considerăm f funcţia "cardinalul mulţimii divizorilor" şi y numărul interesant 1.
Desigur, singurul număr cu un singur factor este chiar 1. Dar întregul 2 este aproape la
fel de interesant ca 1, iar numerele prime sunt chiar cele care au exact doi factori.
 Ipoteza lui Goldbach. Numărul par 28 poate fi scris ca sumă de două numere
prime 11 şi 17. În 1742 Goldbach a afirmat că orice număr par poate fi scris ca suma a două
numere prime, dar ipoteza este încă nedemonstrată. AM a făcut o presupunere similară.1
 În sfârşit, AM a inspirat o "nouă" problemă de matematică. Pe lângă studiul
numerelor prime - numere cu cât mai puţini factori posibil- a examinat şi numerele cu cât mai
mulţi factori posibil, spunând că un întreg k este "maxim divizibil" dacă k are mai mulţi
factori decât orice număr mai mic decât k. Numărul 12 este un exemplu: are 6 divizori (1, 2,
3, 4, 6, 12) şi nu există nici un număr mai mic care să aibă tot atâţia. Mulţimea numerelor
maxim divizibile nu fusese anterior luată în considerare de Lenat sau de alţi membri ai
comunităţii AI, deşi ele fuseseră studiate de matematicianul indian Ramanujan.
AM este o lucrare deosebit de impresionantă, fiind unul din cele mai importante
succese timpurii ale AI. AM este de asemenea un exemplu aproape perfect de AI
experimentală - lucrarea lui Lenat a implicat proiectarea unui program care a manifestat
comportări interesante, surprinzându-şi chiar autorul în timpul rulării!
Ce lecţie trebuie să învăţăm din AM? Care a fost viitorul programului? A purces la
redescoperirea întregii matematici moderne? Au fost aceste idei aplicate cu succes în alte
domenii? Şi în primul rând de ce a avut AM aşa un succes?
Motivul pentru care AM a avut aşa un succes este strânsa legatură dintre limbajul LISP
şi matematică. Parţial, AM a generat funcţii interesante prin modificarea codului unor funcţii
pe care le considera deja interesante.
Dar conexiunea dintre LISP şi matematică este aşa de strânsă încât este destul de
probabil ca modificări arbitrare ale unor fragmente foarte mici de LISP (cum sunt cele cu care

1
AM nu a demonstrat o astfel de ipoteză. AM nu a demonstrat niciodată nimic - doar a remarcat că
multe numere pare ar putea fi scrise ca sumă a două numere prime şi de aici, a speculat că toate
numerele pare ar putea fi la fel. Lenat a fost interesat de descoperire şi nu de demonstrarea automată a
teoriei.

106
a lucrat AM) să producă rezultate interesante. Într-un anume sens, AM a avut succes doarece a
exploatat nedumeririle şi relevaţiile pe care le-a avut John McCarthy când a dezvoltat limbajul
LISP.
Această observaţie are două consecinţe evidente. Prima este că abilitatea lui AM de a
dezvolta noi concepte matematice va scădea rapid pe măsură ce conceptele cu care lucrează
devin tot mai complexe - este mult mai puţin probabil să putem modifica aleator o porţiune
lungă de cod LISP decât una scurtă.
Cealaltă consecinţă spune că este puţin probabil ca tehnici precum cele folosite de AM
să funcţioneze în afara domeniului matematicii, deoarece este puţin probabil ca alte domenii
să afişeze o legatură aşa strânsă între părţi de cod (program) şi idei interesante. Acest lucru a
fost de asemenea observat în practică.
După elaborarea lui AM, Lenat a dezvoltat EURISKO, care se voia a fi o versiune
generalizată a lui AM, care să descopere idei interesante în domenii arbitrare. Dar, în ciuda
aplicaţiilor lui EURISKO într-o varietate de probleme, succesul său a fost destul de limitat.
Ca un exemplu, EURISKO a fost utilizat într-o încercare de a învăţa cum să
construiască circuite integrate tri-dimensionale. Programul a reuşit să genereze un circuit
integrat foarte mic pe suprafaţa unei benzi Möbius, dar în afară de aceasta s-a comportat slab.
EURISKO a fost de asemenea utilizat pentru a juca un joc de conducere a unei flote, în
care fiecare jucător primeşte un buget fix şi trebuie să-şi construiască o flotă furnizând
caracteristicile de mărime, armament, etc. pentru nave. Apoi flotele se luptă şi cea care o
distruge pe cealaltă, câştigă. EURISKO a învăţat să joace acest joc jucând împotriva sa şi apoi
a intrat în campionatul naţional. A câştigat! Dar a câştigat construind nave "ţânţar" - nave
foarte mici şi rapide, fără nici un fel de armament. Când EURISKO întâlnea un adversar
superior, toate navele erau distruse, exceptânnd "ţânţarii", care continuau să "bâzâie" prin
zonă, incapabile să producă vreo distrugere flotei adverse, dar salvând EURISKO de la
înfrângere, doarece regulile spuneau că flota adversă trebuie distrusă în întregime. Această
scăpare a regulilor a fost ceea ce a permis lui EURISKO să fie atât de eficient.
Există ceva comun între acest exemplu şi performanţa originală a lui AM: în ambele
cazuri, programul a trebuit să exploateze o scăpare pentru a avea succes. În cazul lui
EURISKO, scăparea era în regulile jocului cu flote. În cazul lui AM, scăparea era în strânsa
legătură dintre LISP şi matematică. Rezultă că învăţarea prin descoperire, care evită aceste
scăpări se va sprijini pe o înţelegere mult mai dificilă a domeniilor investigate.2

5.2 Învăţarea prin generalizare.

Deoarece învăţarea prin descoperire pare să se bazeze pe o astfel de cunoaştere


dificilă, atenţia comunităţii AI s-a concentrat mai ales pe învăţarea prin generalizare. Vom
discuta mai întâi învăţarea inductivă, în care un sistem încearcă să inducă o regulă generală
dintr-un set de instanţe observate.

5.2.1. Învăţarea inductivă

Toate problemele de acest tip au ceva comun: intrarea programului este un set de
instanţe de instruire (care pot fi selectate fie aleator, fie dintr-o încercare de a face învăţarea
cât mai eficace posibil) şi ieşirea se aşteaptă să fie o metodă de clasificare a instanţelor
ulterioare. Pentru acest motiv învăţarea inductivă se mai numeşte şi învăţare prin exemple. Ca

2
Alternativ, se poate argumenta că toată învăţarea prin descoperire-inclusiv cea umană-
funcţionează prin exploatarea vreunei breşe.
107
exemplu de învăţare inductivă vom alege selecţia ciupercilor comestibile de cele otrăvitoare.
Vom presupune că scopul învăţării inductive este să rezolve o problemă de clasificare binară:
comestibil versus otrăvitor (adică proiectarea unui clasificator binar).

5.2.1.1. Învăţarea probabil aproximativ corectă.

Învăţarea inductivă nu seamană niciodată cu cea deductivă. Faptul că spre exemplu din
10.000 de ciuperci galbene întâlnite au fost toate otrăvitoare, nu dovedeşte că următoarea
ciupercă galbenă va fi la fel; ne dă doar o bună dovadă inductivă (în opoziţie cu deductivă) că
aşa va fi. Cu această observaţie, ne punem întrbarea care este următorul cadru de lucru în care
vom măsura performanţa unui sistem care învaţă inductiv?
Un răspuns la această întrebare a fost dezvoltat de Valiant în 1984; el a argumentat că
un sistem de învăţare trebuie să fie probabil aproximativ corect - pe scurt, PAC.
Să începem prin descrierea a ceea ce înseamnă pentru un sistem învăţarea unei reguli
care este aproximativ corectă. Deoarece problema de clasificare pe care încercăm s-o
rezolvăm este binară, răspunsul nu poate fi el însuşi aproximativ: este fie bun, fie greşit. Spre
exemplu, ciuperca este sau nu clasificată corect? Faţă de aceasta, vom spune că o regulă ca
"toate ciupercile galbene sunt otrăvitoare" este aproximativ corectă ori de câte ori rezolvă cele
mai multe din probleme corect. O regulă învăţată este aproximativ corectă, dacă este complet
corectă cea mai mare parte a timpului.
Notăm cu p(x) conceptul binar pe care încercăm să-l învăţăm – spre exemplu,
comestibil sau necomestibil. Notăm cu p' (x) aproximarea lui p, pe care o învaţă de fapt
sistemul. Vom spune că p' este o eroare pentru x dacă p şi p' sunt diferite şi în consecinţă
eroare(x) este definită astfel:

[ p( x ) p' ( x )] [ p( x ) p' ( x )]

Utilizând semnul de echivalenţă “ ” pentru a nota echivalenţa a două expresii logice,


vom scrie mai compact

[ p( x) p ' ( x)]

Probabilitatea ca regula învăţată să fie greşită este aceeaşi cu probabilitatea ca


eroare(x) să fie adevărată şi definim:

O regulă învăţată p' (x) o vom numi aproximativ corectă cu precizia dacă şi numai
dacă

pr(eroare) (5.1)

unde pr este funcţia de probabilitate.


Practic ne trebuie o cale de evaluare a probabilităţii (5.1). Pentru aceasta, vom
presupune că obiectul x pe care îl clasificăm este luat dintr-un univers U (de exemplu
mulţimea tuturor ciupercilor) şi fiecare element m U este ales cu o anumită probabilitate
pr(m). Presupunând că

pr ( m ) 1 (5.2)
m U

108
se poate rescrie

pr ( eroare) pr ( x ) (5.3)
{ x |eroare( x )}

unde am adunat probabilităţile tuturor elementelor x pentru care p'(x) este în eroare.
Dar probabil aproximativ corectă? Aceasta înseamnă că probabil sistemul va învăţa
reguli care sunt corecte aproximativ!
Pentru a rezolva această problemă, se presupune că exemplele de instruire folosite
pentru dezvoltarea regulilor sunt alese cu aceleaşi probabilităţi ca cele care apar deja în (5.2).
Se obţin exemple de instruire folosind probabilităţile pr(m) şi apoi se aplică o procedură de
învăţare L pentru a ajunge la un concept învăţat p'.
Dăm acum următoarea definiţie:

O procedură de învăţare L este probabil aproximativ corectă cu încrederea dacă,


dându-se o secvenţă de exemple de instruire aleator alese, probabilitatea ca L să înveţe o
regulă care nu este aproximativ corectă este cel mult . Mai formal, cerem ca:

pr [pr(eroare)> ] <

S-a introdus în învăţarea PAC, notiunea de bias3. Majoritatea algoritmilor îşi


restricţionează atenţia asupra învăţării conceptelor într-o formă sintactică particulară, în
special a unui concept conjunctiv – spre exemplu, poate că ciupercile mari şi galbene sunt
otrăvitoare şi toate celelalte nu. Alte sisteme fac alte presupuneri. Se presupune că atât
conceptul ţintă p cât şi aproximarea învăţată p’ satisfac aceste restricţii sintactice. Motivul
pentru care aceste presupuneri sunt importante este că ele restricţionează dimensiunea
spaţiului ipotezei. Această formă particulară a ideii de bias este cunoscută ca bias restrictiv
asupra spaţiului ipotezelor. Considerăm următorul algoritm de învăţare: fiind dat un set de m
instanţe de instruire, trebuie întors orice predicat p’ care respectă atât restricţia spaţiului
ipotezelor, cât şi concordanţa cu valorile raportate ale exemplelor de instruire. Poate o astfel
de procedură să fie PAC?
Dacă universul U este finit şi m este infinit de mare, răspunsul este în mod clar, da.
Pentru un m mare, probabilitatea este ca toate elementele din universul de învăţare U să apară
ca exemple de instruire, adică orice predicat p’ care se potriveşte cu datele să fie echivalent cu
conceptul ţintă p. Deci întrebarea este: Cât de mare trebuie să fie m pentru ca această abordare
să fie PAC?
Pentru a răspunde la aceasta, să presupunem că avem m exemple de instruire. Care este
probabilitatea ca să putem găsi un concept p’ care este în conformitate cu aceste exemple, dar
nu aproximativ corectă .
Pentru a răspunde la aceasta, fie q un concept selectat aleator cu condiţia ca să nu fie
aproximativ corectă. Probabilitatea ca q să se potrivească cu datele de instruire nu este mai
m
mare ca (1 ) , deoarece probabilitatea ca q să nimerească o singură instanţă de invăţare
este cel mult 1- . Dacă era mai mare, q ar fi fost aproximativ corectă.

3
Noţiune preluată din electronică care în cazul algoritmilor de învăţare reprezintă un set de ipoteze
care folosesc pentru a prezice rezultate având în vedere intrări cu care nu s-a confruntat (Mitchell,
1980)

109
Dat fiind bias-ul restrictiv asupra spaţiului ipotezelor în care lucrăm, presupunem că
exista un total de H concepte posibile. Deoarece fiecare are probabilitatea de cel mult
(1 ) m atât ca să se potrivească cu data, cât şi ca să nu fie aproximativ corectă, rezultă că
probabilitatea ca să existe oricare astfel de q este marginită de:

H (1 )m

De fapt, dacă există un astfel de q, el trebuie să fie unul din conceptele H şi


probabilitatea unei disjuncţii este mărginită de suma probabilităţilor fiecărei disjuncţii.
Rezultă că:

Orice propoziţie consistentă cu date de instruire este PAC atunci când:

H (1 )m (5.4)

Altfel rescris:

ln
H
m (5.5)
ln 1

unde sensul inegalităţii s-a schimbat pentru că ln(1- ) este negativ. Afirmăm că:

ln(1 ) 0 (5.6)

pentru 0 1 . Pentru a vedea asta, se observa ca (5.6) devine 0 daca =0, si derivata lui
(5.6) faţă de , este

1
1
1 1

care este clar negativă pentru 0 1 . Folosind (5.6), rezultă că ln(1 ) şi (5.5)
devine:

H
ln ln
H
m

Teoremă: Orice propoziţie consistentă cu date de instruire este PAC dacă şi numai dacă:

H
ln
m (5.7)

110
Ca un exemplu, să presupunem că folosim bias-ul ca ţintă şi conceptele învăţate sunt
n
conjunctii într-un spaţiu cu n predicate. Deoarece există 3 astfel de conjunctii, (5.7) ne
spune că orice concept acceptabil va fi PAC dacă

n 3
m ln

Există două caracteristici ale teoremei, care sunt importante. Prima este că nu se mai
menţionează distribuţia probabilităţii, care apare în (5.3); (5.7) merge pentru orice distribuţie,
adică aceeaşi distribuţie este folosită atât pentru a defini funcţia de eroare, cât şi pentru a
selecta exemplele de instruire folosite de procedura de învăţat.
A doua caracteristică este legată de numărul de instanţe de instruire, care sunt necesare
în teoremă şi care creşte logaritmic cu numărul de concepte posibile.

Figura 1. Numărul necesar de exemple în învăţarea PAC.

În figura 1 ne întoarcem la exemplul conjunctiv, arătând numărul elementelor posibile


n
din domeniu ( 2 , deoarece fiecare predicat poate fi sau adevarat, sau fals), numărul de
n
concepte posibile ( 3 , ca cele discutate mai înainte) şi numărul de exemple necesare unui
sistem de învăţare PAC pentru diferite valori ale şi .

5.2.1.2 Algoritmul lui Mitchell.

Dar cum am putea găsi precis un concept care se potriveşte cu datele din setul de
instruire ? Este clar că examinarea fiecărui concept acceptabil din punct de vedere sintactic
pentru a vedea dacă se potriveşte sau nu, este în general, complet impracticabil.

111
În cazul în care se presupune că un concept este o conjuncţie de literale pozitive, cel
mai bine cunoscut algoritm pentru producerea unui concept acceptabil este algoritmul lui
Mitchell4.
Ideea algoritmului este cel mai bine descrisă prin următorul exemplu. Să presupunem
că lucrăm cu un pachet de cărţi şi încercăm să identificăm un concept conjunctiv necunoscut.
Predicatele în limbaj sunt fapte ca "roşu", "negru", "cupa", "trefla", "carte pară", "carte
impară", ş.a.m.d. Optul de caro este o carte pară, roşie şi de caro. Setul de instruire constă într-
o colecţie de cărţi: pentru fiecare carte, ni se spune dacă este sau nu în setul ţintă.

Figura 2. Ordonarea particularităţilor în conceptele con juctive.

Cheia algoritmului este observaţia că, setul de concepte conjunctive din acest domeniu
(sau din oricare altul) poate fi parţial ordonat după specificacitate. Astfel conceptul “negru”
este mai puţin specific decât conceptul “negru impar” sau “trefla”. Cele două concepte “negru
impar” si “trefla” sunt incomparabile unul cu altul, din moment ce nici unul nu este mai
specific decât celălalt. “Negru” este mai specific decât “orice carte”; “orice 7” este mai
specific decât “orice carte impară”. O diagramă parţială a setului tuturor conceptelor din
domeniul nostru este arătată în figura 2, cu conceptele mai puţin specifice desenate în partea
superioară a imaginii.
Algoritmul tratează incremental datele. Pe măsură ce lucrează, el reţine o listă cu cele
mai specifice concepte şi una cu cele mai puţin specifice, care sunt consistente cu toate
instanţele de instruire (exemplele), care au fost întâlnite până acum. În cazul în care p1 şi p2
sunt două concepte conjunctive consistente cu exemplele, atunci conjunctia p1 p2 este mai
specifică, dar şi consistentă în acelaşi timp cu exemplele. Aceasta înseamnă că “cel mai
specific concept consistent cu exemplele” este întotdeauna unic.
Spre exemplu, presupunem că exemplele (datele) de instruire arată astfel:

4
Prin conjuncţia unor literale pozitive, înţelegem conceptul obţinut prin conjuncţia unor
predicate fără negaţiile lor.
112
Tabela 1
Carte Este in setul ţintă
A da
7 da
8 nu
9 da
5 nu
K nu
6 nu
7 da

Iniţial, cel mai specific concept consistent cu datele este mulţimea vidă; cel mai puţin
specific concept este mulţimea tuturor cărţilor. Dar când vedem că A este în setul ţintă, cel
mai specific concept este A singur (cuvântul “as” face parte din limbaj); cel mai puţin
specific concept rămâne încă mulţimea tuturor cărţilor. Când învăţăm că 7 este în setul ţintă,
cel mai specific concept este probabil “cărţi negre impare”; cel mai puţin specific concept este
neschimbat.
Acum vom învăţa că 8 nu este în setul ţintă. Există două concepte consistente cel
mai puţin specifice cu aceasta - toate cărţile impare şi toate cărţile negre. Pe măsură ce
continuăm, se observă că exemplele pozitive determină ca cele mai specifice concepte să
devină treptat mai puţin specifice (spre exemplu, cărţile negre şi impare în locul asului de
pică). Exemplele negative determină ca cele mai puţin specifice concepte să devină mai
specifice. Dacă cele două mulţimi converg, rezultatul este în mod garantat conceptul ţintă.
Trebuie notat că algoritmul este util şi înainte ca cele două seturi să se potrivească
exact. Chiar dacă conceptul ţintă nu a fost identificat în mod unic în acest punct, s-a identificat
un grup de concepte care se potrivesc cu exemplele de instruire şi se poate aplica teorema de
mai sus (5.7) pentru a concluziona inductiv că toate aceste concepte sunt probabil aproximativ
corecte . Când algoritmul a identificat precis conceptul, putem concluziona deductiv că a fost
găsit conceptul ţintă, cu condiţia validităţii presupunerii că acest concept este o conjuncţie de
literale pozitive.

5.2.1.3. Învăţarea unor inegalităţi.

Să aruncăm o privire asupra unui alt fel de spaţiu al ipotezelor restrictive (bias). Se
presupune că argumentul x al predicatului este un număr real şi că bias-ul pe care îl alegem
presupune ca p(x ) este de forma x>c sau x<c pentru o anumită constantă c. Un exemplu
tipic este arătat în figura 3, în care conceptul este “toţi x>5.0” şi exemplele de instruire
indicate sunt consistente cu ipoteza x>c pentru orice c (4.2, 5.3).

Figura 3. Învăţarea unei inegalităţi.

113
Chiar dacă dimensiunea spaţiului ipotezei (H din teoremă) este infinită, lucru dovedit
de faptul că putem mărgini domeniul valorilor de intrare posibile x, cele m exemple de
instruire selectate aleator fac probabil o bună şi echitabilă trasare a parantezei în punctul de
tranzitie c şi o analogie cu teorema (5.7) poate fi dovedită în acest exemplu - este posibil să se
înveţe PAC în acest domeniu.
Dar dacă în loc de o caracteristică avem mai multe? O idee similară poate fi aplicată în
acest caz. În loc de a diviza linia în două în punctul c, putem diviza un plan în două cu o linie.
Putem diviza un spaţiu tridimensional în două cu un plan, ş.a.m.d. Un spaţiu n-dimensional
poate fi înjumătăţit cu un hiper-plan (n-1) dimensional.
În general, putem modela această operaţie geometrică descriind hiperplanul în termeni
de n coordonate ( h1 , , hn ) şi spunând că un punct ( x1 , , xn ) este în “dreapta”
hiperplanului dacă şi numai dacă

xi hi (5.8)
i
pentru anumite fixate. Există o oarecare redondanţă în această descriere: putem multiplica
atât cât şi toate valorile hi cu o constantă pozitivă fără a afecta (5.8). În figura 4 am desenat
o reprezentare schematică a trei intrări procesate în acest fel pentru a produce o singură ieşire
care poate fi sau 1 sau 0, în funcţie de (5.8) care evident, poate fi asimilata cu o reţea
neuronală.

Figura 4. Reţea neuronală cu un singur nivel.

Acum, încercăm să învăţăm o funcţie f şi presupunem că ea are o formă specifică, dată


de (5.8). Aceasta se dovedeşte a fi un bias substanţial - există multe funcţii care nu pot fi
aproximate prin funcţii învăţate în această formă.

Figura 5 O reţea mai complicată

114
Pentru a ajunge la aceasta, presupunem că prelucrăm intrările nu o dată, ci de mai
multe ori, ca în figura 5 Rezultatele multiplelor iteraţii pot fi ele însele vazute ca intrări ale
altor iteraţii ale formulei (5.8); am desenat schematic rezultatul în figura 6.
Se observă că acum apare dificultatea: fiecare funcţie a intrărilor multiple poate fi
aproximată cu o funcţie de forma descrisă în figură. Mai mult, există algoritmi pentru
învăţarea valorilor folosite pentru apariţiile hi' şi în diverse versiuni ale (5.8), care sunt
folosite la operaţii.

Figura 6 O reţea neuronală cu trei nivele

Ce mod minunat ar fi acesta pentru rezolvarea problemelor de AI. Fiind date intrările
unor senzori, sistemul ar putea simplu să înveţe să-şi clasifice acţiunile posibile ca inteligente
sau non-inteligente, iar apoi să acţioneze inteligent. Din nefericire, nu este clar că această
abordare va reuşi - în principiu va avea succes, dar realizarea practică este deja o altă
problemă. Dimensiunile spaţiilor pot fi extraordinar de mari, timpul necesar pentru a învăţa
conceptele poate fi efectiv infinit, practic nu există nici o modalitate de a decide de cât de
multe nivele interne are nevoie reţeaua, ş.a.m.d.

5.2.1.4. Algoritmul lui Quilan

Mai există o tehnică inductivă de învăţare despre care dorim să discutăm este
algoritmul lui Quinlan, cunoscut sub denumirea prescurtată ID3.
Conform prezumpţiei asupra spaţiului ipotezelor facută în ID3, conceptul care se
învaţă poate fi exprimat cu ajutorul unui arbore de decizie, asemănător celui din figura 7.
Revenim la exemplul acela de clasificare al ciupercilor. În cazul de faţă, pentru a clasifica
ciuperca m, se începe prin a determina dacă m este mare sau nu. Dacă m este mare, adică
mare(m) este adevarat, ne mutăm pe partea stângă a arborelui; dacă mare(m) este fals, ne
mutăm pe partea dreaptă a lui.

115
Figura 7. Un arbore de decizie

Apoi, se vor lua în considerare predicate ca: galbenă(m) sau pătată(m), ş.a.m.d. Când
se ajunge într-un nod frunză (terminal) al acestui arbore, ciuperca va fi clasificată ca
otrăvitoare sau nu. În exemplul din figură, arborele de decizie este echivalent cu regulile de
inferenţă incluzând

mare(m) galbenă(m) otrăvitoare(m) (5.9)

Nu este greu de observat că arborii de decizie nu sunt deloc amalgamaţi; orice concept
poate fi reprezentat utilizând unul dintre aceştia. Contribuţia adusă de ID3 constă în realizarea
faptului că, există metode efective de a învăţa conceptele în această formă, ca şi domeniile
variantelor care sunt mijloace efective de a învăţa conceptele conjunctive. Odată alese
predicatele folosite pentru a eticheta arcele, restul este relativ uşor - nodurile marginale sunt
uşor de recunoscut deoarece exemplele de instruire care duc la astfel de noduri satisfac toate
conceptul ţintă, sau toate esuează.
În ID3, arcele sunt etichetate astfel încât să-şi poată executa efectiv sarcina de
împărţire a exemplelor de instruire la fiecare nod, în pozitive şi negative. Aceasta înseamnă că
vrem ca fiecare test să împartă setul de exemple de instruire aproximativ în două (dacă ţinta
este “trefle impare” nu e prea mult de testat pentru un 7 de treflă) şi mai vrem ca testele să fie
relevante pentru conceptul ţintă (dacă ţinta este “cărţi impare”, verificarea culorii unei cărţi
constă în împărţirea exactă a exemplelor de instruire pe culori, împărţire necorelată cu
conceptul de învăţat).
Există vreun mod prin care să se definească precis care atribut ar trebui verificat în
oricare punct al arborelui de decizie? Da, există. Matematic este puţin complicat.
Presupunem că avem o mulţime M cu |M| elemente şi vrem să punem întrebări cu
răspunsuri da/nu despre un element particular pentru a determina care este el. M poate fi
mulţimea întregilor mai mici decât 1000 şi despre un întreg x putem întreba “Este mai mare
decât 500?” Sub 750?” ş.a.m.d. Numărul minim de întrebări pe care va trebui să-l punem
este log 2 | M | , deoarece tot timpul trebuie împărţit în două domeniul rămas de posibilităţi.

116
Să presupunem că M este împărţit în două submulţimi, P şi N şi încercăm să deducem
în care din aceste două submulţimi se află x. Câte întrebări sunt necesare pentru a determina
valoarea lui x?
Dacă x P, sunt necesare log 2 | P | întrebări; dacă este în N, sunt necesare
log 2 | N | . Presupunând că probabilitatea ca x P este p p , şi că probabilitatea ca x N
este p n , numărul total de întrebări care trebuie puse pentru a obţine informaţii suplimentare
despre x este în medie

p p log 2 | P | pn log n | N |

Rezultă că acest număr de întrebări poate fi redus ştiind dacă x este în P sau în N
astfel:

log 2 | S | p p log 2 | P | pn log 2 | N | (5.10)

Dar p p | P | / | M | , astfel că (5.10) se rescrie după cum urmează:

log2 ( M ) p p log2 ( p p | M |) pn log2 ( pn | M |)


= log 2 ( M ) p p log 2 ( p p ) p n log 2 ( p n ) ( p p p n ) log 2 (| M |)
= p p log 2 ( p p ) p n log 2 ( p n ) (5.11)

Caracteristic pentru această expresie este valoarea ei mai mică decât 1; se poate
oricând întreba: ”Este x în P sau nu?” Dar dacă dimensiunea lui P este mult diferită de a lui
N, stilul “da/nu” nu va fi foarte folositor.
Într-o problemă de clasificare, scopul nu este de a decide exact care element x din
mulţimea M este luat în considerare, ci numai dacă acel element este sau nu o instanţă din
clasa ţinta T (adică o anumită ciupercă este sau nu otrăvitoare). Mai formal, datorită faptului
că se pot pune o sumedenie de întrebări cu răspunsuri “da/nu” (mare sau mică?,galbenă sau
nu?), atunci putem pune o întrebare care să spună cel mai exact dacă x este sau nu în T. Cu
alte cuvinte, punem întrebarea pentru care să nu existe nici o valoare a informaţiei adiţionale
despre faptul că x se găseşte sau nu în T.
Presupunem acum, că avem un subset U M ; se poate partiţiona U în două
submulţimi U U T şi U U T , unde T este clasa ţinta. Conform (5.11),
informaţia câstigată dacă învăţăm despre obiectul considerat că este în T este dată de:

U U U U
I log log (5.12)
U U U U U U U U U

Să presupunem că avem o caracteristică particulară f , iar întrebarea care se pune este


dacă instanţa x luată în considerare satisface sau nu f. Dacă întrebările anterioare au redus
setul de instanţe (exemple) posibile la o submulţime V M , se va indica prin
V f submulţimea lui V care satisface caracteristica f, iar prin V f submulţimea lui V care nu

117
satisface f. Câştigul aşteptat al informaţiei despre învăţarea dacă x se găseşte sau nu în T ,
după ce se foloseşte caracteristica f pentru a împărţi pe V în V f şi V f este dat de:

V V
f f
G I I (5.13)
f V V
V V f V V f
f f f f

Primul termen corespunde câştigului informaţiei, dacă mai întâi se învăţă că x Vf


(importanţă dată de probabilitatea că acest lucru este învăţat când întrebăm despre f) şi al
doilea termen corespunde câştigului informaţiei, dacă mai întâi se învăţă că x V f .
Definiţia 5.2.5 Să presupunem că avem construit un arbore de decizie şi că s-a ajuns la
un nod care corespunde submulţimii V al întregului domeniu. O caracteristica f este maximal
discriminatorie pentru un concept ţintă T dacă ea minimizează valoarea lui G f care apare în
(5.13).
Spre exemplu, trebuie să se afle care este prima întrebare ce poate fi pusă, având în
vedere că, conceptul ţintă în domeniul cărţilor este “cărţile negre impare sau 2 ”.
Caracteristicile despre care se pot pune întrebări sunt culoarea, paritatea, sau orice rang. Se iau
în considerare doar două posibile întrebări: Cartea este roşie? şi Este cartea trei? Dacă se
întrebă despre culoare, există şansa de 50% ca să fie roşie şi 50% să fie neagră.
Răspunsul la aceste întrebări îl găsiţi în exerciţiul 1 de la paragraful exerciţii rezolvate,
de la sfârşitul acestui modul.
Odată ce avem abilitatea de a selecta cea mai folositoare întrebare, construirea
arborelui de decizie este simplă; la orice punct dat, ne oprim dacă avem suficientă informaţie
pentru a determina dacă obiectul este în clasa ţintă sau nu. Dacă nu avem suficiente informaţii,
punem cea mai bună întrebare şi recurgem la algoritmul care urmează.

ALGORITMUL ID3Fiind date ca intrări un set F de caracteristici, mulţimea M


despre care s-a vorbit şi un concept T:
1. Dacă fiecare element al mulţimii M este în T, întoarce răspunsul “da”. Dacă nici un
element al mulţimii M nu este în T, întoarce raspunsul “nu”.
2. În orice alt caz, fie f cel mai discriminator element al lui F. (dacă n-a mai rămas nici o
caracteristică, întoarce “eşec”). Întoarce un arbore a cărui ramură stângă este ID3(F-
{f},M f,T) şi a cărui ramură dreaptă este ID3(F-{f},M-f,T). Se indică acel subset al lui
M care satisface f prin S f şi subsetul care nu satisface f prin S-f.

În practică, desigur, datele de instruire nu vor include informaţii despre toate obiectele
din domeniu, ci numai despre câteva dintre ele. În aceste condiţii, ID3 poate fi folosit pe
construirea descrierii PAC a conceptului ţintă.

118
Unitatea de învăţare 6.

Reţele neuronale.

Cuprins:

6.1. Introducere ................................................................................................. pag. 119


6.2. Sistemul nervos biologic. Reţele neuronale biologice ............................... pag. 120
6.3. Reţele neuronale artificiale ........................................................................ pag. 122
6.4. Proiectarea şi realizarea reţelelor neuronale ............................................. pag. 127
6.4.1. Colectarea datelor ................................................................................... pag. 128
6.4.2. Definirea structurii reţelei ....................................................................... pag. 128
6.4.3. Alegerea algoritmului de învăţare ......... ................................................. pag. 130
6.4.3.1 Reguli de corecţie a erorilor ................................................................. pag. 131
6.4.3.2. Învăţarea de tip Boltzman .................................................................... pag. 132
6.4.3.3. Postulatul de învăţare a lui Heb ........................................................... pag. 132
6.4.3.4. Reguli de învăţare competitive ............................................................ pag. 133
6.4.3.5 Algoritmul de propagare înapoi (backpropagation) .............................. pag. 134
6.4..4. Testarea reţelei ................................................................................................. pag. 135
6.5. Avantaje şi limite ale reţelelor neuronale artificiale ................................... pag. 135
6.6. Reţelele neuronale versus sistemele expert ……………...………………. pag. 136
6.7. Aplicaţii ale reţelelor neuronale ……………………………………… pag. 137
6.8. Direcţii de cercetare în cadrul reţelelor neurale ......................................... pag. 139
6.9. Exerciţii rezolvate şi tema de control ......................................................... pag. 140
6.10. Bibliografie modulul 3 ............................................................................. pag. 147

6.1. Introducere

Una din problemele cele mai dificile, pe care trebuie să le rezolve inteligenţa
artificială, este generată de necesitatea dominării complexităţii informaţionale a domeniilor
abordate. O posibilă soluţie este oferită în unele cazuri de sistemele expert. Utilizarea acestora
este însă limitată la domenii bine definite, comportamentul unui sistem expert devenind
fragil la frontierele domeniului pentru care a fost realizat.
În cazul unor aplicaţii mult mai complexe, se conturează o alta abordare: Învăţarea
automată, ca un set de metode utilizate în scopul învăţării de către calculator a modului de
rezolvare a unei probleme prin analogie cu anumite cazuri trecute. Acest obiectiv nu este
deloc simplu. Pe de o parte, există mai multe modele de învăţare şi alegerea unui model
potrivit specificului problemei poate fi extrem de dificilă. Pe de altă parte, cu toate că
învăţarea automată este considerată un domeniu al inteligenţei artificiale, multe din tehnologiile
sale nu sunt caracteristice acesteia.
Cercetările în domeniul învăţării automate s-au intensificat în ultimele patru decenii,
iniţial insistându-se mai degrabă asupra modalităţilor de a realiza un sistem care să se
dovedească inteligent, decât asupra modalităţilor prin care acesta să poată învăţa în scopul
îmbunătăţirii propriilor performanţe. Cea mai mare parte a cercetărilor în domeniul
învăţării automate au fost orientate spre definirea unor paradigme ale învăţării (ca domeniu
care constă într-o investigare a principiilor de bază ale inteligenţei), stabilirea unor relaţii
între acestea şi elaborarea algoritmilor care le caracterizează.
Metodele de învăţare corespund unor tehnici relativ diferite: metode de învăţare
inductivă, sisteme de clasificare, reţele neuronale, algoritmi genetici, sisteme de învăţare

119
bazate pe explicaţii. Aceste tehnici au în comun abilitatea de a modifica performanţele
sistemului odată cu câştigarea experienţei. Herbert Simon a caracterizat procesul de învăţare
într-un mod suficient de abstract pentru a permite utilizarea oricăror metode: „ învăţarea
denotă modificări în cadrul sistemului, care sunt flexibile în sensul că ele permit acestuia să
îndeplinească aceleaşi sarcini, extrase din acelaşi domeniu într-un mod mult mai eficient în
viitor”.
Această nouă abordare a sistemelor inteligente presupune construirea de calculatoare
cu o arhitectură şi capacitate de procesare care să imite anumite abilităţi de procesare ale
creierului. Rezultatul îl constituie reprezentările de cunoştinţe bazate pe o importantă
procesare paralelă, pe acumularea rapidă a unor mari cantităţi de informaţii şi pe capacitatea
de a recunoaşte modele pe baza experienţei. Tehnologia care încearcă să obţină aceste
rezultate este numită procesare neuronală sau reţele neuronale.
Preocuparea pentru reţelele neuronale artificiale, denumite în mod curent „reţele
neuronale”, a fost motivată de recunoaşterea faptului că modul în care calculează creierul
fiinţelor vii este complet diferit de cel al calculatoarelor numerice convenţionale.
Spre deosebire de maşinile von Neumann, unde există o unitate de procesare care
execută instrucţiunile stocate în memorie în mod serial, numai o instrucţiune la un moment
dat, reţelele neuronale utilizează în mod masiv paralelismul.
Fiind modele simplificate ale creierului uman, ele deţin capacitatea de a învăţa, spre
deosebire de calculatoarele convenţionale, care rămân totuşi mai eficiente pentru sarcinile
bazate pe operaţii aritmetice precise şi rapide.
Reţelele neuronale nu dispun de unităţi de procesare puternice, dimpotrivă, acestea
sunt caracterizate printr-o simplitate extremă, însă interacţiunile lor pe ansamblu produc
rezultate complexe datorită numărului mare de conexiuni.
Reţelele neuronale sunt tehnologii de prelucrare a informaţiei bazate pe studiile
asupra creierului uman şi a sistemului nervos. Cercetările în domeniu s-au intensificat în
ultimii ani, cunoscând în prezent o mare popularitate, datorită progreselor înregistrate
atât în tehnologia calculatoarelor, cât şi în domeniul neurologiei, în direcţia unei mai bune
înţelegeri a mecanismelor creierului uman.
În timp ce japonezii caracterizează reţelele neuronale ca aparţinând generaţiei a
VI-a de calculatoare, americanii consideră că pot recâştiga poziţia de lider în domeniul
tehnologiilor informaţionale prin realizarea unor sisteme informatice bazate pe procesele
biologice ale creierului uman. Din ce în ce mai mult, în cercetările din domeniul neurologiei,
se caută identificarea principiilor de prelucrare biologică a informaţiei, în scopul aplicării lor
în cadrul unor sisteme artificiale.

6.2. Sistemul nervos biologic. Reţele neuronale biologice.

Pentru a înţelege mai bine această abordare, trebuie precizat modul de funcţionare al
sistemului nervos.
Capacitatea de a învăţa şi a reacţiona la schimbările din jurul nostru, necesită
inteligenţă. Gândirea şi comportamentul inteligent sunt controlate de creier şi de sistemul
nervos central. Încercarea de a înţelege modul în care creierul uman poate gestiona într-o
manieră atât de eficientă, o enormă cantitate de cunoştinţe, porneşte de la analiza neuronilor,
ca elemente fundamentale ale sistemului nervos central.
Constituienţii structurali ai creierului sunt neuronii, conectaţi prin sinapse. Se
estimează că în cortexul uman există circa 10 miliarde de neuroni şi 60 de trilioane de sinapse.
Trebuie precizat însă că neuronii nu sunt cele mai numeroase celule din creier. Celulele gliale
sunt de 10 ori mai multe. În mod tradiţional, se considera că acestea au numai funcţii de

120
nutriţie şi protecţie, însă în ultimul timp au demarat cercetări privitoare la influenţa lor
potenţială asupra activităţii de procesare a neuronilor.
Structura biologică a unui neuron (figura 6.1.) include:
 nucleul (corpul celular);
 axonul (ieşirea din celula neuronală);
 dendritele ( intrările în celula neuronală).
Dendritele (numite astfel datorită asemănării cu un copac, „dendron” în greacă) sunt
„intrările” neuronului, fibre scurte ramificate, de câţiva milimetri, care primesc impulsuri.
Axonul („axōn”, axă), „ieşirea”, este o fibră mai lungă, de câţiva centimetri putând
ajunge însă la 1-1,5 metri. Fiecare neuron are un singur axon şi mai multe (10-20) de dendrite.

Figura 6.1. Schema biologică a unui neuron.

Conexiunile dintre neuroni se realizează într-un spaţiu numit sinapsă. Acestea sunt
unităţi structurale şi funcţionale elementare care mediază interacţiunile dintre neuroni. Tipul
cel mai răspândit de sinapsă este sinapsa chimică, ce operează astfel: un proces presinaptic
eliberează o substanţă transmiţătoare, care difuzează peste joncţiunea sinaptică dintre neuroni
şi apoi acţionează asupra unui proces postsinaptic. Astfel, o sinapsă converteşte un semnal
electric presinaptic într-un semnal chimic (ioni de sodiu şi potasiu) şi apoi din nou într-un
semnal electric postsinaptic.
În descrierile tradiţionale ale organizării neuronale, se consideră că o sinapsă este o
conexiune simplă care poate impune excitare sau inhibare, dar nu ambele, neuronului
receptor. Ambele efecte sunt locale; ele se propagă pe o distanţă mică în corpul celulei şi sunt
însumate la nivelul axonului. Dacă suma potenţialelor de excitare depăşeşte un anumit prag,
atunci neuronul este activat şi transmite un impuls mai departe.
Fiecare neuron primeşte impulsuri electrice prin intermediul dendritelor sale. Dacă
aceste impulsuri sunt suficient de puternice, axonul va transmite un impuls electric în vederea
excitării diferiţilor neuroni conectaţi care, în funcţie de intensitatea semnalului primit, vor fi
activaţi la rândul lor. Semnalele pot fi transmise nemodificate sau pot fi alterate de sinapse.
O sinapsă este capabilă să intensifice sau să diminueze puterea de conecţie, provocând
excitarea sau inhibarea neuronului respectiv. Abordarea conexionistă în informatică se
bazează pe acest model biologic.
Cea mai importantă trăsătură a reţelei neuronale biologice este plasticitatea. Ca
răspuns la stimulările primite, la nivelul conexiunilor se produc schimbări pe termen lung,
astfel încât conexiunile care ajută la obţinerea de rezultate pozitive sunt întărite, iar cele care

121
determină rezultate nedorite sunt slăbite. De asemenea, neuronii pot forma în timp noi
conexiuni cu alţi neuroni. Aceste mecanisme stau la baza capacităţii de adaptare a creierului la
stimulii primiţi, pe care o numim în mod convenţional învăţare.

6.3. Reţele neuronale artificiale.

Reţelele neuronale artificiale, au ca punct principal de inspiraţie sistemul nervos,


fiind alcătuite dintr-o mulţime de noduri în care se află neuronii artificiali, interconectate în
funcţie de diverse tipologii. Intrările în neuronul artificial sunt similare cu impulsurile
electrice pe care dendritele neuronului biologic le primesc de la alţi neuroni, în timp ce
ieşirea neuronului artificial corespunde semnalelor trimise de neuronul biologic prin
intermediul axonului. Aceste semnale artificiale pot fi modificate în aceeaşi manieră cu
modificările ce au loc în cadrul sinapselor. Problema constă în determinarea intrărilor
acceptabile, pe baza ponderilor asociate fiecărei intrări. Învăţarea, pe baza exemplelor şi a
contraexemplelor va permite ajustarea acestor ponderi cu ajutorul, unui algoritm retroactiv a
ecarturilor între rezultatul obţinut şi cel dorit.
În procesarea neuronală devine tot mai importantă înţelegerea mecanismului de
funcţionare a creierului uman, mecanism care, deocamdată, prezintă multe neclarităţi
pentru cercetătorii din domeniu. Acesta poate fi unul din motivele pentru care modelele
de procesare neuronală nu sunt foarte apropiate de sistemul biologic - unii autori
estimează aceasta asemănare cu mult sub 10%. Comportamentul rigid al reţelelor neuronale
artificiale, în comparaţie cu cel al sistemelor biologice, constituie deocamdată principalul
impediment în încercarea de a simula cât mai fidel comportamentul inteligent uman. De
exemplu, dacă ne referim la modelul aditiv (ca una din reprezentările tipice ale reţelelor
neuronale artificiale), putem enumera câteva din caracteristicile care îi conferă rigiditate
în funcţionare:
 prima limită a acestui model constă în faptul că performanţa neuronilor este colectivă, dar
nu este paralelă; orice schimbare în activitatea unui neuron va afecta ceilalţi neuroni. în
cadrul sistemelor biologice, neuronii funcţionează atât colectiv, cât şi paralel. De exemplu,
mâna stângă şi mâna dreaptă sunt independente din punct de vedere mecanic
(funcţionează paralel), însă activitatea lor este coordonată de creier (funcţionează colectiv).
 a doua limită a modelului artificial o constituie dependenţa performanţelor acestuia de
condiţiile iniţiale. Sistemul nu uită niciodată aceste condiţii, iar pentru a-i modifica
performanţele, inputurile externe trebuie să domine „inerţia trecutului”, în timp ce
sistemele biologice sunt mult mai flexibile; ele pot uita trecutul, adaptându-şi
comportamentul în funcţie de caracteristicile ambientale.
Totodată, caracteristicile sistemului artificial sunt de aceeaşi scală, în timp ce sistemele
biologice implică mecanisme care acoperă întregul câmp, de la molecular la macroscopic.
Cu toate acestea, reţelele neuronale artificiale prezintă un număr surprinzător de mare de
caracteristici ale creierului, fiind posibilă realizarea unor sisteme utile care prezintă anumite
caracteristici comune sistemelor biologice.
În cea mai generală formă a sa, o reţea neuronală este o maşină proiectată pentru a
modela felul în care creierul rezolvă o anumită problemă sau execută o funcţie cu un anumit
scop; reţeaua este de obicei implementată folosindu-se componente electronice sau simulată
printr-un program.
Definiţie. Simon Haykin consideră că o reţea neuronală este un procesor masiv
paralel, distribuit, care are o tendinţă naturală de a înmagazina cunoştinţe experimentale şi de
a le face disponibile pentru utilizare.
Ea se aseamănă cu creierul în două privinţe:

122
- Cunoştinţele sunt căpătate de reţea printr-un proces de învăţare;
- Cunoştinţele sunt depozitate nu în unităţile de procesare (neuroni), ci în conexiunile
interneuronale, cunoscute drept ponderi sinaptice.
Procedura folosită pentru a executa procesul de învăţare se numeşte algoritm de
învăţare, funcţia căruia este de a modifica ponderile sinaptice ale reţelei într-un stil sistematic
pentru a atinge obiectivul dorit de proiectare. Printre numeroasele proprietăţi interesante ale
unei reţele neuronale, cea mai semnificativă este abilitatea acesteia de a învăţa prin
intermediul mediului înconjurător, şi prin aceasta să-şi îmbunătăţească performanţele;
creşterea performanţelor are loc în timp şi conform cu unele reguli prestabilite.
O reţea neuronală îşi învaţă mediul printr-un proces iterativ de ajustări aplicate
conexiunilor şi pragurilor sale sinaptice. În mod ideal, reţeaua devine mai „inteligentă” după
fiecare iteraţie a procesului de învăţare.
În contextul reţelelor neuronale vom defini astfel învăţarea: un proces prin care
parametrii variabili ai unei reţele neuronale se adaptează prin continua stimulare din partea
mediului în care este inclusă. Tipul de învăţare este determinat de modul în care au loc
schimbările parametrilor. Aşadar, învăţarea în contextul unei reţele neuronale se
caracterizează prin următoarele elemente:
- Reţeaua neuronală este stimulată de un mediu;
- Reţeaua neuronală suferă schimbări datorită acestor stimulări;
- Reţeaua neuronală răspunde în mod diferit mediului datorită schimbărilor care au
apărut în structura sa internă.
Cu toate că asemănarea între sistemul nervos biologic şi reţelele neuronale artificiale
este relativ mică, reţelele neuronale artificiale prezintă un număr surprinzător de caracteristici
ale creierului. De exemplu, acestea pot învăţa din experienţă, generaliza din anumite exemple
altele noi şi sintetiza caracteristicile esenţiale din intrări ce conţin şi date irelevante. Un mare
avantaj al reţelelor neuronale este că pot să descrie o problemă şi să o rezolve în acelaşi timp,
prin auto-organizarea lor şi nu prin programul explicit. Acest proces de auto-organizare are
loc pe parcursul învăţării datorate topologiei iniţiale, unor reguli de învăţare şi unui număr
mare de antrenamente.
Caracteristicile cele mai importante ale reţelelor neuronale sunt:
- Capacitatea de a învăţa: Reţelele neuronale artificiale nu necesită programe
puternice ci sunt mai degrabă rezultatul unor antrenamente asupra unui set de date.
Reţelele neuronale artificiale au un algoritm de învăţare, după care ponderile
conexiunilor sunt ajustate pe baza unor modele prezentate. Cu alte cuvinte, reţelele
neuronale învaţă din exemple, la fel cum învaţă copiii să recunoască un obiect pe baza
mai multor instanţe ale acelui tip de obiect
- Capacitatea de generalizare: Dacă au fost instruite corespunzător, reţelele sunt
capabile să dea răspunsuri corecte şi pentru intrări diferite faţă de cele cu care au fost
antrenate, atâta timp cât aceste intrări nu sunt foarte diferite;
- Capacitatea de sinteză: Reţelele neuronale artificiale pot lua decizii sau trage
concluzii când sunt confruntate cu informaţii afectate de zgomot, irelevante sau
parţiale.
Datorită acestor trăsături ale prelucrării informaţiei, reţelele neuronale pot rezolva
probleme complexe care sunt dificil de abordat prin metode clasice. Cu toate acestea,
cercetătorii recunosc că mai au un drum lung de parcurs până vor ajunge să construiască un
calculator care să imite creierul omenesc. „Inteligenţa” la care au ajuns în prezent cele mai
sofisticate reţele neuronale este sub nivelul gândirii unui copil de câţiva ani. Cu toate acestea
nu trebuie minimizată sau ignorată importanţa reţelelor neuronale artificiale şi este posibil ca
pe viitor, cu ajutorul lor să se ajungă la o cunoaştere mai aprofundată a fenomenelor ce au loc

123
în creierul uman. Ceea ce recomandă reţelele neuronale artificiale este raportul favorabil
performanţă-complexitate, aflat într-o continuă creştere şi care este superior sistemelor de
inteligenţă artificială implementate prin alte tehnologii.
Începutul reţelelor neuronale artificiale este legat de problema clasificării unor obiecte
definite de o serie de atribute. Cel mai simplu model era funcţia ŞI logic între anumite atribute
(prezente sau absente), care să determine o anumită clasă. Totuşi, unele clase pot avea atribute
comune, iar unele valori, în cazul în care provin dintr-un mecanism perceptual, pot fi afectate
de zgomot. Soluţia s-a bazat pe faptul de bun simţ că unele atribute sunt mai importante decât
altele pentru determinarea unei anumite clase. O clasă era determinată dacă sumarea valorilor
ponderate depăşea un anumit prag, în bună concordanţă cu legea biologică „totul sau nimic”
(dacă un impuls nu depăşeşte un prag minim, el nu produce nici un răspuns).
Neuronii artificiali sunt elemente de procesare neliniare, care operează în paralel. Prin
analogie cu neuronul biologic, fiecare neuron artificial va recepţiona una sau mai multe
intrări, le va prelucra şi va furniza o singura ieşire, care se poate conecta la intrările mai
multor neuroni.
Fiecare intrare corespunde unui singur atribut. De exemplu, dacă problema constă
în a decide asupra acordării unui credit, atributul poate constitui un nivel de activitate, un tip
de garanţie etc. Valoarea numerică a atributului va deveni o intrare în reţea. Se pot utiliza
diferite tipuri de date drept intrări, dar în cadrul reţelei se pot prelucra doar date numerice. În
cazul în care sunt necesare atribute calitative, acestea vor fi transformate în echivalente
numerice. Ieşirea unui element de procesare poate constitui rezultatul final sau poate deveni
intrare într-un alt proces de prelucrare. Pentru exemplul anterior, soluţia problemei
(ieşirea care constituie rezultatul final) poate fi „da” sau „nu”. Reţeaua va atribui valori
numerice de exemplu 1 pentru „da” şi 0 pentru „nu”, scopul constând în evaluarea valorilor
rezultatului obţinut.
Fiecărei intrări îi este asociată o pondere, care reprezintă importanţa relativă a
acesteia. Modalitatea prin care reţeaua „invaţă” este repetata ajustare a acestor ponderi.
Elementul de prelucrare (neuronul) calculează suma ponderată a intrărilor sale, fiind activat
doar dacă această sumă depăşeşte un anumit prag, numit „prag de activare”.
Warren McCulloch şi Walter Pitts (1943) au propus un model, care rămâne până în
prezent fundamentul structural pentru majoritatea reţelelor neuronale numit perceptron, o
„reţea” cu un singur neuron, la fel ca aceea din figura 6.2.

Figura 6.2. Modelul Warren McCulloch şi Walter Pitts.

124
Fiecărei conexiuni îi corespunde o valoare reală, numită pondere sinaptică, care
determină efectul intrării respective asupra nivelului de activare a neuronului. Suma ponderată
a intrărilor poartă denumirea de intrare netă (în engleză, „net input”). În figură, x j reprezintă
intrările, w j ponderile sinaptice, f o funcţie de activare, valoarea prag iar y ieşirea, care se
calculează după formula:
n
y f wi xi
i 1

McCulloch şi Pitts foloseau o funcţie de activare signum, cu valorile -1 şi 1:


1, s 0
f (s)
1, s 0

0 X

-1

Figura 6.3. Funcţia signum

Din punctul de vedere al funcţiei de activare a neuronilor, s-a constatat că reţelele


multistrat nu asigură o creştere a puterii de calcul în raport cu reţelele cu un singur strat dacă
funcţiile de activare rămân liniare, deoarece o funcţie liniară de funcţii liniare este tot o funcţie
liniară. Puterea perceptronului multistrat provine tocmai din funcţiile de activare neliniare.
Aproape orice funcţie neliniară poate fi folosită în acest scop, cu excepţia funcţiilor
polinomiale.
Se punea acum problema determinării automate a acestor ponderi, în cazul în care
neuronului îi erau prezentate mai multe obiecte, împreună cu clasa căreia îi aparţineau acestea.
Rezolvarea a fost adusă de Frank Rosenblatt (1960), care a imaginat un algoritm de învăţare
pentru perceptron. Algoritmul de antrenare garantează clasificarea corectă a două clase pe
baza setului de antrenare, cu condiţia ca acele clase să fie liniar separabile. Scopul iniţial al
perceptronului era recunoaşterea optică a caracterelor. Rosenblatt a reuşit să construiască în
1968 un sistem bazat pe implementarea sa hardware, numit Mark I Perceptron, care e
considerat primul neurocomputer funcţional
Ideea principală este de a face mici ajustări ale ponderilor pentru a reduce diferenţa
dintre ieşirea reală a perceptronului şi ieşirea dorită. Ponderile iniţiale sunt iniţializate
aleatoriu (în general în intervalul [-0.5, 0.5]) şi apoi actualizate treptat astfel încât ieşirea să se
apropie de valorile dorite. Exemplele de antrenare sunt prezentate succesiv, în orice ordine.
Dacă în pasul p ieşirea reală este y ( p ) iar ieşirea dorită este yd ( p ) , atunci eroarea
este:
e( p ) yd ( p ) y ( p )

125
Dacă eroarea e este pozitivă, trebuie să mărim y ; dacă este negativă, y trebuie
micşorat. Având în vedere că fiecare intrare are contribuţia xi wi , atunci dacă xi este
pozitivă, o creştere a ponderii wi va avea ca efect o creştere a ieşirii perceptonului. Invers,
dacă xi este negativă, creşterea ponderii wi va determina scăderea ponderii y . De aici poate
fi stabilită regula de învăţare a perceptonului:
wi ( p 1) wi ( p ) e( p ) xi ( p ) ,
unde (0,1) este numită rata de învăţare.
În prezent, funcţiile cele mai des utilizate sunt sigmoida unipolară (sau logistică):

1
f ( x) x
1 e

Figura 6.4. Funcţia sigmoidă

O altă formă pentru funcţia sigmoidă poate fi f : ( 1, 1) numită şi


sigmoida bipolară (tangenta hiperbolică).

kx
1 e
f ( x) kx
, k 0
1 e

0 X

-1

Figura 6.5. Funcţia sigmoidă bipolară.

126
Se poate constata că funcţiile sigmoide se comportă aproximativ liniar pentru valori
absolute mici ale argumentului şi se saturează, preluând oarecum rolul de prag, pentru valori
absolute mari ale argumentului. S-a demonstrat (Cybenko, 1989) că o reţea (posibil infinită)
cu un singur strat ascuns este capabilă să aproximeze orice funcţie continuă. Astfel se justifică
proprietatea perceptronului multistrat de aproximator universal. De asemenea, aplicând
teorema Stone-Weierstrass în domeniul reţelelor neuronale, s-a demonstrat că acestea pot
calcula anumite expresii polinomiale: dacă există două reţele care calculează exact două
funcţii f1, respectiv f2, atunci există o reţea mai mare care calculează exact o expresie
polinomială de f1 şi f2.

6.4. Proiectarea şi realizarea reţelelor neuronale.

Conceperea unei reţele neuronale necesită în primul rând definirea configuraţiei


acesteia, prin precizarea următoarelor elemente: volumul datelor de testare şi antrenare,
algoritmul de învăţare, structura reţelei, funcţia de transfer şi mijloacele de testare şi
validare a acesteia.

Definirea structurii reţelei

*altă structură

reiniţializare

Implementare

Figura 6.6.. Etapele proiectării şi realizării unei reţele neuronale

127
6.4.1. Colectarea datelor.

Tipul datelor (binare sau continue) va fi stabilit în funcţie de structura reţelei şi de


algoritmul de învăţare ce urmează a fi utilizat. Datele ce vor fi furnizate reţelei trebuie să fie
cât mai clare şi să acopere în întregime domeniul problemei (nu doar operaţiile de rutină,
ci şi excepţiile sau condiţiile specifice ce se manifestă la graniţele acestuia). Calitatea reţelei
va depinde direct de volumul şi calitatea datelor de intrare; de regulă, cu cât volumul acestora
este mai mare, cu atât cresc şansele de a se ajunge mai repede la un set de ponderi
corespunzătoare în cadrul procesului de învăţare.

6.4.2. Definirea structurii reţelei.

Ca şi reţelele biologice, reţelele neuronale artificiale pot fi organizate în diverse


moduri, ca posibilităţi de interconectare între neuroni. În definirea structurii reţelei, cât şi în
alegerea algoritmului de învăţare, punctul de pornire îl constituie mijloacele disponibile
şi aptitudinile echipei de realizare. Cele mai reprezentative structuri sunt: sistemele
bazate pe memorie asociativă, reţelele cu doua nivele şi reţelele multinivel.
Conform rezultatelor unor studii biologice, memoria asociativă constă în capacitatea
omului de a asocia un ansamblu de caracteristici unui obiect complex şi de a-1 identifica în
condiţiile în care nu sunt specificate decât o parte a caracteristicilor sale. Într-o asemenea
structură toate informaţiile se regăsesc în sinapse, deci chiar şi în absenţa unei legături directe
între doi neuroni.

Figura 6.7. Memoria asociativă

Principala caracteristică a sistemelor bazate pe memoria asociativă, este capacitatea


acestora de a identifica complet anumite situaţii în condiţiile furnizării unor informaţii
parţiale, prin căutarea similitudinilor între datele de intrare şi cele stocate în reţea. Acest tip
de structură permite utilizarea unor reţele în care legăturile sunt quasicunoscute (în sensul
că nu există restricţii privind sensul sau ordinea acestora) iar răspunsul reţelei este aproape
instantaneu, fiind necesară doar o simplă parcurgere a acesteia.
O arhitectură de mare importanţă istorică este adaline (“adaptive linear element”,
Widrow, 1962), prezentată la scurt timp după publicarea algoritmului lui Rosenblatt. Spre
deosebire de perceptron, ieşirea nu este discretă, ci continuă, deoarece foloseşte funcţia de
activare liniară: f(s) = s. De asemenea, algoritmul de antrenare este diferit conceptual,
bazându-se pe metoda celor mai mici pătrate, sau regula delta. Scopul este minimizarea erorii

128
pătratice medii dintre ieşirea reală şi cea dorită cu ajutorul unei metode de tip gradient
descendent numită coborârea cea mai abruptă (engl. “steepest descent”). Actualizarea
ponderilor se face după aceeaşi formulă ca la perceptron, cu precizarea că eroarea e are acum
valori reale. Din punctul de vedere al comportamentului, spre deosebire de perceptron, adaline
converge repede şi învăţarea este în general stabilă chiar în probleme de clasificare
neseparabile liniar. Dezavantajul său principal este faptul că nu poate garanta separarea celor
două clase, chiar dacă acestea sunt liniar separabile.
Widrow a generalizat modelul la o arhitectură cu mai multe straturi numită madaline
(“many adalines”). Aceasta constă dintr-un strat de neuroni adaline care pot fi antrenaţi şi ale
căror ieşiri sunt conectate într-un al doilea strat, stratul de ieşire, format din neuroni care
funcţionează ca porţi logice: ŞI, SAU sau vot majoritar. Ponderile neuronilor din acest strat de
ieşire nu sunt antrenabile, ci fixate, ceea ce conduce la clasificarea arhitecturii madaline tot ca
o reţea cu un singur strat.
Reţelele multinivel au apărut din încercările de rezolvare a problemelor neseparabile
liniar şi au condus la diverse variante privind numărul de straturi de neuroni şi funcţiile de
activare utilizate şi sunt alcătuite dintr-un nivel al neuronilor de intrare, un nivel al neuronilor
de ieşire şi unul sau mai multe nivele intermediare (numite şi nivele ascunse). Un neuron va
putea să-si transmită rezultatul unui alt neuron, situat pe un nivel superior; setul de intrări în
reţea fiind stabilit, rezultatul va fi furnizat în urma parcurgerii succesive a tuturor nivelelor
acesteia. Perceptronul multistrat este tipul de reţea neuronală cel mai cunoscut şi mai des
folosit. De cele mai multe ori, semnalele se transmit în interiorul reţelei într-o singură direcţie:
de la intrare spre ieşire; nu există bucle, ieşirea fiecărui neuron neafectând neuronul respectiv.
Această arhitectură se numeşte cu propagare înainte (engl. “feed-forward”).

Figura 6.8.. Reţea cu trei nivele

Straturile care nu sunt conectate direct la mediu se numesc ascunse. Există în literatura
de specialitate o controversă privind considerarea primului strat (de intrare) ca strat propriu-
zis în reţea, de vreme ce singura sa funcţie este transmiterea semnalelor de intrare spre
straturile superioare, fără a face vreo prelucrare asupra intrărilor. În cele ce urmează, am ales
să numărăm numai straturile formate din neuroni propriu-zişi, însă spunem că intrările sunt
grupate în stratul de intrare.
Dezavantajul principal al acestei structuri ii constituie timpul de învăţare, care sporeşte
odată cu numărul nivelelor intermediare.

129
În cadrul reţelelor cu două nivele, fiecare neuron aparţinând nivelului de intrare va fi
conectat cu fiecare neuron aparţinând nivelului de ieşire; neuronii nivelului de ieşire .vor
modifica valorile furnizate de neuronii nivelului inferior, atribuindu-le diverse ponderi.
În funcţie de arhitectură reţelele neurale se împart în 2 categorii:
a) reţele de tipul feed-forward în care grafurile nu au salturi înapoi.
b) reţele recurente în care apar salturi înapoi din cauza conexiunilor feedback.
În cazul cel mai răspândit al reţelelor de tipul feed forward (numite şi perceptron
multilayer) neuronii sunt organizaţi pe mai multe nivele care au legături unidirecţionale între
ei.
Diversele modalităţi de conectare conduc la diverse comportamente. Vorbind la modul
general reţelele de tipul feed forward sunt statice deoarece produc acelaşi set de valori de
ieşire şi nu o secvenţă de valori pentru o intrare dată. Reţelele de tipul feed forward sunt fără
memorie în sensul că răspunsul acestora la o intrare este independent de starea anterioară a
reţelei. Reţelele recurente sunt sisteme dinamice. Când este prezentat un nou model de intrare
sunt calculate ieşirile neuronului. Datorită căilor de feedback intrările fiecărui neuron sunt
modificate ceea ce conduce reţeaua către o nouă stare. Arhitecturi diferite ale reţelei necesită
algoritmi de învăţare specifici.

6.4.3. Alegerea algoritmului de învăţare.

Abilitatea de învăţa este o caracteristică fundamentală a inteligenţei. Deşi este greu


de formulat o definiţie precisă a învăţării un proces de învăţare în contextul reţelelor neurale
artificiale poate fi văzut ca problema actualizării arhitecturii reţelei şi a ponderii conexiunii
astfel încât reţeaua să efectueze eficient o anumită slujbă. Reţeaua învaţă de obicei
ponderile conexiunilor din modelele de antrenament disponibile. Performanţa este
îmbunătăţită în timp updatarea iterativă a ponderilor din reţea. Abilitatea reţelelor neurale
artificiale de a învăţa din exemple face ca acestea să devină atractive şi interesante. În loc să
urmeze un set de reguli întocmit de experţi umani reţelele neurale artificiale învaţă regulile
de bază (în forma de relaţii intrare-ieşire) dintr-o colecţie de exemple reprezentative. Acesta
este unul din avantajele majore ale reţelelor neurale faţă de sistemele expert tradiţionale.
Pentru a înţelege sau proiecta un algoritm de învăţare trebuie mai întâi creat un
model al mediului în care va opera reţeaua neurală, aceasta înseamnă că trebuie ştiut ce
informaţie este disponibilă reţelei. Apoi trebuie înţeles cum se actualizează ponderile adică
regulile de învăţare care guvernează procesul de actualizare a ponderilor. Algoritmul de
învăţare se referă la procedura în care regulile de învăţare sunt folosite pentru ajustarea
ponderilor.
Algoritmii de învăţare a reţelelor neuronale se împart în trei categorii: algoritmi
supervizaţi, algoritmi nesupervizaţi şi algoritmi hibrizi.
Învăţarea supervizată presupune existenţa unui set de intrări pentru care se cunosc
valorile dorite ale ieşirilor. Aceste două seturi de valori formează o pereche de antrenament, o
reţea urmând să fie antrenată cu un număr de perechi de antrenament ce depinde de tipul şi de
complexitatea problemei. Pe baza diferenţei între rezultatul dorit şi cel efectiv obţinut se vor
determina corecţiile ce trebuie aplicate ponderilor reţelei, până în momentul în care eroarea
corespunzătoare întregii reţele se află sub un prag minim.
Învăţarea nesupervizată se apropie mai mult de modul de învăţare caracteristic unui
sistem biologic, nemaifiind necesare valori de ieşire asociate celor de intrare şi nici
comparări în vederea minimizării erorilor. Învăţarea nesupervizată are ca scop clusterizarea
datelor de intrare, adică gruparea obiectelor similare şi separarea celor diferite, în lipsa unor

130
informaţii a priori în acest sens. Nu există, în acest caz, posibilitatea determinării anterior
procesului de învăţare a valorilor ieşirilor asociate unei clase a intrărilor.
De cele mai multe ori, reţelele neuronale care utilizează această paradigmă de învăţare
sunt foarte simple, cu un singur strat. Neexistând un instructor, reţeaua trebuie să se auto-
organizeze în conformitate cu unele reguli interne ca răspuns la stimulii din mediul extern.
Învăţarea hibridă combină învăţarea supervizată cu cea nesupervizată. O parte din
ponderi sunt determinate prin învăţare supervizată iar cealaltă este obţinută prin învăţare
nesupervizată.
Teoria învăţării trebuie să rezolve trei probleme fundamentale asociate cu învăţarea
din exemple: capacitatea, complexitatea exemplelor şi complexitatea computaţională.
Capacitatea se referă la numărul pattern-urilor care pot fi stocate precum şi la funcţiile şi
deciziile pe care o reţea trebuie să le ia.
Complexitatea mostrelor determină numărul modelelor de antrenament necesare
pentru antrenarea reţelei pentru a garanta o bună generalizare. În acest caz reţeaua se descurcă
bine numai în cadrul setului de date de antrenament dar foarte slab pe alte modele de test
extrase din aceeaşi distribuţie precum modelele de antrenament.
Complexitatea computaţională se referă la timpul necesar unui algoritm de învăţare
pentru a estima o soluţie dintre modelele de antrenament. Mare parte din algoritmii de
învăţare existenţi au o complexitate computaţională ridicată. Proiectarea unor algoritmi
eficienţi pentru învăţare în cadrul reţelelor neurale este o ramură de cercetare foarte activă.
Există patru tipuri de bază de reguli de învăţare: corecţia erorilor, Boltzmann, Hebian
şi învăţarea concurenţială (competitive learning)

6.4.3.1 Reguli de corecţie a erorilor.

În cazul de învăţare supervizată reţelei i se atribuie o ieşire dorită pentru fiecare pattern
de intrare. În timpul procesului de învăţare ieşirea „y” generată de reţea e posibil să fie diferită
de ieşirea dorită „d”. Principiul de bază al regulilor de învăţare este folosirea semnalului de
eroare (d-y) în scopul modificării ponderilor pentru reducerea graduală a erorii.
Regula de învăţare a perceptronului se bazează pe principiul de corecţie a erorii. Un
perceptron constă dintr-un neuron cu ponderi ajustabile wj, j=1,2,...,n şi pragul u. Dându-se un
n
vector de intrare X=(x1, x2,...,xn)t intrarea reţelei în neuron este v= xi wi u.
i 1

Ieşirea perceptronului este 1 daca v>0 şi 0 altfel. Într-o problemă de clasificare în două
clase perceptronul clasifică un model de intrare într-o clasă dacă y=1 şi în cealaltă clasă dacă
n
y=0. Ecuaţia liniară xi wi u 0 defineşte limita de decizie (un hiperplan în spaţiul de
i 1

decizie cu n dimensiuni de la intrare) care înjumătăţeşte spaţiul.


Rosenblast a dezvoltat o tehnică de învăţare pentru determinarea ponderilor şi pragului
într-un perceptron dându-se un set de modele de antrenament.
De observat că învăţarea apare numai atunci când perceptronul face o eroare.
Rossenblat a dovedit că atunci când modelele de antrenament provin din două clase liniare
separabile procedura de învăţare a perceptronului converge după un număr finit de paşi.
Aceasta este teorema de convergenţă a perceptronului. În practică nu se cunoaşte dacă
modelele sunt separabile din punct de vedere liniar. Important este că un perceptron cu un
singur nivel poate să separe doar modele separabile din punct de vedere liniar atâta timp cât
este folosită o funcţie monotonă de activare.

131
Algoritmul de învăţare „back-propagation” se bazează tot pe principiul corecţiei
erorilor.

Algoritmul de învăţare al perceptronului


1. Se iniţializează ponderile şi valoarea pragului cu numere mici aleatoare;
2. Alegeţi un vector X=(x1, x2,...,xn) şi evaluaţi ieşirea neuronului;
3. actualizaţi ponderile conform cu Wj(t+1)=Wj(t)+n(d-y)Xj unde d este ieşirea
dorită, t este numărul iteraţiei iar n (0<n<1) este câştigul (mărimea pasului).

6.4.3.2 Învăţarea de tip Boltzman.

Maşinile Boltzman sunt reţele recurente simetrice formate din unităţi binare (+1 pentru
„on” şi -1 pentru „off”). Prin simetrie se înţelege că ponderea conexiunii de la i la j este egală
cu ponderea conexiunii de la j la i (Wij=Wji). Un subset de neuroni „vizibili” interacţionează cu
mediul în timp ce ceilalţi, ascunşi nu interacţionează cu mediul. Fiecare neuron este o unitate
stochastică care generează o ieşire sau stare conform cu distribuţia Boltzman a mecanicii
statistice. Maşinile Boltzman operează în două moduri: fix, în care neuronii vizibili sunt
stabiliţi în stări specifice determinate de mediu iar cel de-al doilea mod liber, în care atât
neuronii vizibili cât şi cei ascunşi operează liber.
Învăţarea de tip Boltzmann este o regulă de învăţare stocastică derivată din teoria
informaţiei şi din principiile termodinamice. Obiectivul învăţarii de tip Boltzmann este
ajustarea ponderilor conexiunilor aşa încât stările unităţilor vizibile satisfac o anumită
distribuţie a probabilităţii dorită. În conformitate cu regulile de învăţare Boltzmann
schimbarea ponderii Wij a unei conexiuni este dată de:

Wij n * ( P`ij Pij )

unde n este rata de învăţare iar P 'ij şi Pij sunt corelaţii între stările unităţilor i şi j unde reţelele
operează în modul fix respectiv în modul liber. Valorile lui P 'ij şi Pij sunt de obicei estimate
din experimentele Monte Carlo care însă sunt extreme de încete.
Învăţarea de tip Boltzmann poate fi văzută ca un caz special al învăţarii prin corecţia
erorii în care eroarea este măsurată nu ca diferenţă directă între corelaţiile dintre ieşirile dorite
şi cele actuale, dar ca diferenţă între corelaţii dintre ieşirile a doi neuroni în condiţii de operare
fixă şi liberă.

6.4.3.3 Postulatul de învăţare al lui Hebb.

Cea mai veche regulă de învăţare este postulatul de învăţare al lui Hebb care se
bazează pe următoarea observaţie din experimentele neurobiologice: Dacă neuronii din
ambele părţi ale unei sinapse sunt activaţi sincron şi repetat puterea sinapsei este mărită
selectiv.
Matematic regula Hebbian poate fi descrisă ca:
Wij(t+1)=Wij(t)+nYi(t)Xi(t).
Unde Xi şi Yi sunt valorile de ieşire ale neuronilor i şi j care sunt conectaţi de sinapsa
Wij iar n este rata de învăţare. De observat că Xi este intrarea în sinapsă.
O proprietate importantă a acestei reguli este că învăţarea se face local, aceasta
înseamnă că schimbarea în ponderea sinapsei depinde numai de activitatea celor doi neuroni

132
conectaţi de aceasta. Aceasta simplifică semnificativ complexitatea circuitului de învăţare
într-o implementare VLSI.

6.4.3.4 Reguli de învăţare competitive.

Spre deosebire de învăţarea hebbian (în care mai multe unităţi de ieşire pot fi
sincronizate) unităţile de ieşire de învăţare competitivă concurează între ele pentru activare,
aşa încât numai o unitate de ieşire este activă la un anumit moment dat. Acest fenomen este
cunoscut ca „câştigătorul ia totul” De remarcat că s-a descoperit că învăţarea competitivă
există în reţelele neurale biologice.
Învăţarea competitivă de obicei grupează sau categoriseşte datele de intrare. Modelele
similare sunt grupate de către reţea şi reprezentate printr-o singură unitate. Gruparea se face
automat bazându-se pe corelaţia datelor.
Cea mai simplă reţea de învăţare competitivă constă într-un singur nivel de unităţi de
ieşire precum este expus în figura de mai jos.

Figura 6.9. Un model de clasificare a reţelelor neuronale

Fiecare unitate de ieşire i din reţea se conectează la toate unităţile de intrare X 'j S prin
ponderile Wij, j=1,2,...,n. Fiecare unitate de ieşire se conectează de asemenea către toate
celelalte ieşiri prin ponderi inhibitoare dar are un feedback propriu cu o pondere excitantă. Ca
rezultat al competiţiei numai unitatea i ' cu cea mai mare sau cea mai mică intrare de reţea
devine câştigătoare, asta înseamnă că Wi' X Wi X , i sau ||Wi’-X|| ||Wi-X|| i . Când toţi
vectorii ponderilor sunt normalizaţi cele două inegalităţi devin echivalente. O regulă simplă de
învăţare competitivă poate fi formulată astfel:

n( Xj u Wi ' j ), pentru i i '.


Wij
0, pentru i i'

133
De observat că numai ponderile unităţii câştigătoare sunt actualizate.
Efectul acestei reguli de învăţare este de a muta modelul stocat în unitatea câştigătoare
(ponderile unităţii) un pic mai aproape de modelul de intrare.

Figura 6.10. Un exemplu de învăţare competitivă


a) înainte de învăţare b) după învăţare

Figura de mai sus demonstrează o interpretare geometrică a învăţării competitive. În


acest exemplu presupunem că toţi vectorii de intrare au fost normalizaţi şi au lungimea
unitate. Aceştia sunt înfăţişaţi ca puncte negre în Figura 6.10. Vectorii pondere ai celor trei
unităţi sunt iniţializaţi aleatoriu. Poziţiile lor iniţiale şi finale pe sferă după învăţarea
competitivă sunt marcate cu X în figurile 6.10.a. şi 6.10.b.. În figura 6.10. fiecare din cele trei
grupuri naturale de modele au fost descoperite de o unitete de ieşire al cărei vector pondere
pointează către centrul de greutate al grupului descoperit.
Se poate vedea din regulile de învăţare competitivă că reţeaua nu se va opri din învăţat
(actualizarea ponderilor) decât dacă rata de învăţare n este 0. un anumit model de intrare poate
provoca diferite unităţi de ieşire la diferite iteraţii în timpul învăţării. Aceasta aduce în vedere
problema stabilităţii unui sistem de învăţare. Se zice că sistemul este stabil dacă nici un model
din datele de antrenament după un număr finit de iteraţii de învăţare. O modalitate de a atinge
stabilitatea este de a forţa rata de învăţare sî descrească gradual la 0 pe parcursul procesului de
învăţare. Însă această îngheţare artificială a învăţării cauzează altă problemă denumită
„plasticitate” , care reprezintă abilitatea de a se adapta la date noi. Acest lucru este cunoscut ca
dilema stabilităţii-plasticităţii în învăţarea competitivă

6.4.3.5 Algoritmul de propagare înapoi (backpropagation).

Unul dintre cei mai utilizaţi algoritmi de învăţare este algoritmul de propagare înapoi
(backpropagation). Este un algoritm supervizat, aplicat în special reţelelor feedfoward (în care
nu există conexiuni între rezultatul furnizat de un neuron şi un alt neuron situat pe acelaşi
nivel sau pe un nivel anterior).

134
Forma cea mai generală a algoritmului:

Iniţializarea ponderilor (valori mici, aleatoare)


ATÎTA -TIMP cît eroarea se află peste pragul minim
PENTRU fiecare pereche de antrenament
{prezentarea valorilor de intrare şi propagarea fluxului de activare
nivel cu nivel până la nivelul de ieşire calculul erorii pe baza
ieşirii obţinute şi celei dorite şi propagarea ei înapoi
nivel cu nivel ajustându-se ponderile în scopul minimizării erorii}
SFÂRŞIT-ATÎTA-TIMP.

Procesul de învăţare constă în aplicarea efectivă a algoritmului de învăţare, în scopul


ajustării ponderilor reţelei. Algoritmul backpropagation este cel mai cunoscut şi utilizat
algoritm de învăţare supervizată. Numit şi algoritmul delta generalizat deoarece extinde
modalitatea de antrenare a reţelei adaline (regula delta), el se bazează pe minimizarea
diferenţei dintre ieşirea dorită şi ieşirea reală, tot prin metoda gradientului descendent
(gradientul ne spune cum variază o funcţie în diferite direcţii).
Metoda a fost propusă pentru prima dată de Bryson şi Ho (1969), dar atunci a fost
practic ignorată, deoarece presupunea un volum de calcule prea mare pentru vremea
respectivă. A fost redescoperită apoi de Werbos (1974), însă abia la mijlocul anilor ’80 a fost
lansată de Rumelhart, Hinton şi Williams (1986) ca instrument general acceptat de antrenare a
perceptronului multistrat. Ideea de bază este găsirea minimului funcţiei de eroare e(w) în
raport cu ponderile conexiunilor.

6.4..4. Testarea reţelei.

În această etapă, se evaluează performanţele reţelei prin aplicarea ponderilor obţinute


asupra datelor de testare, urmărindu-se corecta clasificare a acestora. De cele mai multe
ori, este suficientă atingerea unui anumit nivel al performanţei, nefiind necesar ca reţeaua să
funcţioneze perfect.
Implementarea reţelei necesită de regulă asigurarea unei interfeţe adecvate cu
celelalte aplicaţii informatice şi o pregătire corespunzătoare a utilizatorilor. De asemenea,
trebuie realizate actualizări ale datelor de antrenament şi reluări periodice ale procesului de
învăţare, pentru a include noile situaţii care apar în urma utilizării frecvente a reţelei, precum
şi reevaluări ale performanţelor acesteia.

6.5. Avantaje şi limite ale reţelelor neuronale artificiale.

Reţelele neuronale artificiale sunt utilizate cu succes în rezolvarea unor probleme


complexe care presupun recunoaşterea modelelor, învăţarea, clasificarea, generalizarea şi
abstractizarea, interpretarea unor informaţii incomplete sau irelevante. Reţelele neuronale, ca
sisteme care „învaţă”, constituie interfeţe mult mai naturale cu lumea reala decât sistemele
care trebuie programate. Ele prezintă avantajul potenţial de a utiliza caracteristici umane în
rezolvarea unor probleme dificil de simulat cu ajutorul tehnicilor logice, analitice ale
sistemelor expert sau cu ajutorul, altor tehnici convenţionale. De exemplu, reţelele
neuronale pot analiza mari cantităţi de date pentru a stabili modele şi caracteristici în
situaţii în care nu există reguli cunoscute.
De asemenea, reţelele neuronale au şi capacitatea de a generaliza, oferind soluţii
corecte şi în cazul unor intrări incomplete, diferite faţă de cele cu care au fost „antrenate”. Ele

135
generalizează automat ca urmare a structurii lor, şi nu pe baza unui program special creat în
acest scop.
Adaptabilitatea este o altă caracteristică a reţelelor neuronale, ele fiind capabile să
înveţe şi în cadrul unor medii noi, să ia decizii sau să tragă concluzii când sunt confruntate
cu informaţii complexe, irelevante sau parţiale.
Un alt avantaj îl constituie posibilitatea de a obţine aproape instantaneu soluţia unei
probleme (pentru anumite tipuri de reţele), fiind suficientă în acest scop o simplă parcurgere a
reţelei.
În ceea ce priveşte limitele reţelelor neuronale, ele nu constituie o alternativă
eficientă în domeniile consacrate tehnologiilor convenţionale .
Reţelele neuronale nu oferă posibilitatea justificării soluţiilor obţinute (ca în cazul
sistemelor expert), deoarece ajustarea ponderilor nu oferă interpretări facile, iar în ceea
ce priveşte recunoaşterea modelelor este foarte dificil să explici logica din spatele deciziilor.
Procesarea neuronală necesită cantităţi mari de date de testare şi pregătire şi în
unele cazuri timpul de antrenare poate deveni excesiv.
Cu toate aceste limite, reţelele neuronale sunt privite din ce în ce mai mult ca o soluţie
pertinentă pentru tot mai multe tipuri de aplicaţii, ţinând cont şi de raportul favorabil
performanţe/complexitate, care este în continuă creştere, fiind mult mai mare decât cel al
sistemelor inteligenţei artificiale implementate cu ajutorul altor tehnologii. Procesarea
neuronală constituie o alternativă pentru celelalte tehnologii ale inteligenţei artificiale în
domeniile în care datele sunt variate, incomplete, prezentând un înalt grad de
interdependenţă sau în care diverse ipoteze trebuie evaluate simultan. Nu trebuie ignorată
nici posibilitatea combinării acestei tehnologii cu alte aplicaţii soft (sisteme expert, baze de
date) în scopul realizării unor sisteme hibrid pentru automatizarea rezolvării unor probleme
complexe.

6.6. Reţelele neuronale versus sistemele expert.

Atât reţelele neuronale, cât şi sistemele expert constituie aplicaţii ale inteligenţei
artificiale şi nu trebuie privite ca tehnologii care se află în competiţie, chiar dacă în anumite
cazuri utilizarea reţelele neuronale se poate dovedi mai eficientă comparativ cu sistemele
expert. Mai mult decât atât, caracteristicile celor doua tehnologii sunt atât de diferite, încât ele
se pot completa una pe alta în anumite situaţii. în timp ce sistemele expert presupun o
abordare logică, simbolică reţelele neuronale utilizează procese numerice, asociative în scopul
imitării modelelor sistemelor biologice.
Reţelele neuronale pot constitui o alternativă în reprezentarea cunoştinţelor în cadrul
unui sistem expert, principalul dezavantaj constituindu-1 în acest caz opacitatea acestui
formalism, cunoştiinţele fiind reprezentate într-o maniera implicită.
Un domeniu în care reţelele neuronale pot fi mult mai bine utilizate îl constituie
achiziţionarea cunoştinţelor pentru un sistem expert. Cercetările privind psihologia cunoaşterii
şi a comunicării au confirmat ideea conform căreia învăţarea este necesară nu doar pentru a
interpreta faptele, ci şi pentru a le percepe. De asemenea, practica realizării sistemelor expert
a demonstrat că achiziţionarea cunoştinţelor reprezintă una din problemele cele mai delicate în
cadrul acestui proces. Pe de o parte, expertul uman întâmpină serioase dificultăţi în
exprimarea cunoştinţelor sale în termeni uşor de exploatat. Pe de altă parte, structurarea
cunoştinţelor devine o sarcină tot mai dificilă pentru cognitician, mai ales atunci când acestea
au un caracter evolutiv, fiind necesare numeroase revizuiri ale bazei de reguli.

136
Caracteristici Sisteme expert Reţele neuronale
Abordare simbolică numerică
Raţionament logic asociativ
Operaţii mecanice biologice
Explicaţii da nu
Procesare secvenţială paralelă
Sistem închis autoorganizare
Validare şi verificare dificilă rapidă
Prelucrează cunoştiinţe date
Menţinere dificilă facilă

Figura 6.11. Caracteristicile principale ale celor două tehnologii

Reţeaua neuronală poate fi utilizată în scopul identificării rapide a cunoştinţelor


implicite prin analizarea unor date istorice în situaţiile în care regulile nu pot fi determinate
direct sau în care această operaţie ar necesita prea mult timp. Reţeaua neuronală analizează
datele în scopul identificării unor modele şi relaţii care pot constitui reguli în cadrul
sistemului expert. Aceasta poate fi utilizată ca tehnică singulară în achiziţionarea
cunoştinţelor sau poate adăuga un număr de reguli explicite derivate din utilizarea unor alte
tehnici ( metoda interviului sau inducţia automata).
Deasemenea, reţelele neuronale pot contribui la achiziţionarea cunoştinţelor în
cazurile în care interfaţa cu expertul uman este completată cu un modul expert care pune
întrebări şi direcţionează informaţiile obţinute într-un mod eficient şi clar. Reţeaua neuronală
poate prelucra rapid aceste informaţii în scopul obţinerii unor consecinţe şi fapte asociate,
analizate de un modul expert în scopul obţinerii de noi rezultate. Vor fi astfel necesare mai
puţine reguli explicite, de vreme ce reţeaua conţine cunoştinţe generale şi este capabilă să
producă cunoştinţe specifice, relevante pentru problema definită de utilizator.

6.7. Aplicaţii ale reţelelor neuronale.

Reţelele neuronale sunt dedicate rezolvării problemelor care presupun recunoaşterea


unor modele, învăţarea, clasificarea, generalizarea şi abstractizarea, interpretarea unor date
incomplete şi irelevante. Domeniile lor de aplicaţie nu se suprapun cu cele ale tehnicilor
convenţionale sau ale celorlalte tehnologii ale inteligenţei artificiale. Principalele aplicaţii
ale reţelelor neuronale sunt următoarele.

Recunoaşterea modelelor. Reţelele neuronale sunt capabile să recunoască forme,


culori, dimensiuni, sunete. O primă aplicaţie a reţelelor neuronale a fost recunoaşterea
caracterelor, dezvoltându-se sisteme automate pentru trierea scrisorilor. S-au dezvoltat multe
aplicaţii şi în domeniul recunoaşterii şi sintezei sistemului vocal. Aplicaţia de recunoaştere a
modelelor reprezintă corelarea unui simbol de intrare precum o formă de undă sau un simbol
scris, sau reprezentat de un vector caracteristic către una sau mai multe clase.
Clustering-categorizarea. Clusterizarea cunoscută ca şi clasificarea
nesupravegheată a modelelor nu există date de antrenament care provin din clase
cunoscute. Un algoritm de clusterizare explorează similarităţile dintre modele şi
plasează modelele similare într-un cluster. Aplicaţiile binecunoscute de clusterizare
includ data mining, data compresion şi analiza datelor prin explorare.
Aproximarea unei funcţii. Presupunând că avem un set de date de antrenament
(perechi intrare-ieşire) {(x1 ,y1 ), (x2 ,y2 ), …, (xn ,yn )} care au fost generate de o funcţie
necunoscută u(x) afectată de paraziţi. Scopul aproximării funcţiei este găsirea unei

137
aproximări a funcţiei necunoscute. Diverse probleme de modelare ştiinţifică necesită
aproximarea funcţiilor.
Predicţie. Fiind dat un set de n valori {y(t 1 ), y(t 2 ), …, y(t n )} într-o secvenţă de
timp de la t 1 la t n , se cere prezicerea valorii y(t n+1 ) la momentul t n+1 . Predicţia are un
impact semnificativ în luarea deciziilor în afaceri şi ştiinţă.
Optimizare. O mare varietate de probleme în ştiinţă matematică medicină,
economie pot fi considerate probleme de optimizare. Scopul unui algoritm de
optimizare este de a găsi soluţii care să satisfacă un set de constrângeri aşa încât o
funcţie obiectiv să fie maximizată sau minimizată. Un exemplu clasic îl reprezintă
problema comis voiajorului.
Memorie adresabilă pe baza conţinutului. În modelul computaţional von
Neumann o locaţie de memorie este accesată numai prin adresa acesteia care este
independentă de conţinutul acesteia. Mai mult dacă se face o mică eroare în calculul
adresei de memorie se va accesa un element total diferit. Memoria asociativă sau
memoria adresabilă prin conţinut precum reiese chiar din nume poate fi adresată prin
conţinut. Conţinutul memoriei poate fi obţinut chiar prin introducerea unor date de
intrare incomplete sau distorsionate. Memoria asociativă este foarte utilă în construirea
bazelor de date cu informaţii multimedia.
Control. Să considerăm un sistem dinamic definit prin perechea {u(t), y(t)} unde u(t)
este intrarea de control iar y(t) este ieşirea corespunzătoare a sistemului la momentul t. În
modelul de referinţă adaptive-control scopul este generarea intrării de control u(t) astfel încât
sistemul să urmeze traiectoria dorită determinată de modelul referinţă. Un exemplu este
controlul vitezei de relanti al unui motor.
Alte aplicaţii ale reţelelor neuronale. Deoarece reţelele neuronale sunt cele mai bune
în identificarea şabloanelor sau a tendinţelor în date, ele sunt folosite pentru predicţii sau
estimări în: estimarea vânzărilor, controlul proceselor industriale, căutarea clienţilor sau a
pieţelor de desfacere, validarea datelor, managementul riscului, prospectarea pieţii.
Reţelele neuronale sunt folosite şi în alte domenii importante ca: recunoaşterea vocii,
diagnosticarea bolilor, recuperarea unei convorbiri din cauza unui soft defect, interpretarea
sensurilor multiple ale cuvintelor chinezeşti, detectarea minelor marine, analiza textelor,
recunoaşterea obiectelor tri-dimensionale, recunoaşterea scrisului de mână, recunoaşterea
amprentelor, recunoaşterea feţei.
Reţelele neuronale în medicină. În domeniul medicinei există aplicaţii privind:
modelarea corpului uman, identificarea maladiilor din diferite explorări (EKG, RMN, ECO),
aplicaţii în sistemele biomedicale, modelarea şi dignosticul sistemului cardiovascular,
potenţiale aplicaţii ţn telemedicină.
O aplicaţie ce datează din anii 80 este numită "instant physician" antrenată printr-o
reţea neuronală cu memorie asociativă pentru a memora un număr mare de de înregistrări
medicale fiecare din acestea incluzând informaţii despre simptome, diagnostice şi tratamente
pentru diverse cazuri particulare. După antrenament i se prezintă reţelei ca intrare un caz
printr-un set de simptome; ea va căuta cel mai adecvat şablon memorat care să reprezinte " cel
mai bun" diagnostic şi tratament.
Reţelele neuronale în afaceri. În afaceri reţelele neuronale îşi găsesc aplicarea în:
analize financiare, planificarea şi alocarea resurselor, exploatarea bazelor de date prin
intermediul unor şabloane, marketing (spre exemplu, marketingul controlului rezervării
locurilor pentru companiile aeriene), evaluarea creditelor.

138
6.8. Direcţii de cercetare în cadrul reţelelor neurale.

În ultimii ani au fost aduse multe contribuţii care arată ce probleme pot fi rezolvate în
principiu de către reţelele neurale. Susţinerea plauzibilităţii biologice a fost treptat abandonată
în favoarea reţelelor care rezolvau anumite probleme.
Optimizarea proiectării reţelelor neurale. Proiectarea unei reţele neurale făcută în
funcţie de nivelul de cunoaştere al proiectantului nu mai reprezintă o situaţie satisfăcătoare.
De asemenea ar trebui observat că în cele mai multe aplicaţii curente componenta neurală
constă într-un singur sau într-un număr mic de module neurale de obicei de mărime şi
complexitate moderată. Este surprinzător cum sisteme aşa mici pot să îndeplinească cu succes
sarcini complicate. Putem astfel să apreciem la ce ne putem aştepta dacă reuşim să înţelegem
şi să folosim sisteme neurale mai aproape de nivelul de complexitate pe care-l observăm chiar
la sistemele neurale biologice simple. Există 3 metode care abordează această problemă.
Algoritmi genetici şi evoluţionişti care pot fi folosiţi pentru antrenarea reţelei dar şi
pentru a evolua structuri de reţele din populaţii de reţele.
Abordări incrementale în care se porneşte cu reţele foarte mici care cresc până este
îndeplinit un criteriu anume
Abordări de reducere metode opuse celei de deasupra, precum neuro-chirurgia
optimă în care ponderile sau nodurile care nu sunt necesare sunt eliminate dintr-o reţea
iniţială supradimensionată.
Observaţie. Dezvoltarea de sisteme hibride deşi mai multe proiecte pot fi transformate
cu succes în aplicaţii, numărul de reţele neurale folosite în aplicaţii este mic. De obicei
folosirea reţelelor neurale nu conduce la îmbunătăţiri substanţiale a performanţelor aşa încât
nu trebuie abandonate tehnicile folosite în prezent. Aşadar dacă dorim aplicaţii practice
trebuie să acceptăm că reţelele neurale sunt folosite numai pentru rezolvarea sarcinilor
complexe. Din moment ce există o lipsă de metode pentru antrenarea sistemelor mari,
problemele trebuie descompuse în părţi mai mici. De fiecare dată când există cunoştinţe
explicite sau metode exacte acestea trebuie folosite pentru a reduce complexitatea. De fiecare
dată când descompunerea este prea complexă sau nu sunt disponibile cunoştinţe exacte despre
procesul de bază, reţelele neurale trebuie luate în calcul, lucru care necesită o strânsă
cooperare între experţi din diverse domenii.
În concluzie, lumea computerelor are avantaje imense din folosirea reţelelor neuronale.
Abilitatea reţelei de a învăţa din exemple o face foarte flexibilă şi puternică. Reţelele
neuronale au contribiţii importante şi în alte domenii de cercetare cum ar fi neurologia şi
psihologia.Există diferite aplicaţii privind modelarea comportamentelor organismelor vii şi
investigarea mecanismelor interne ale creierului uman. Reţelele neuronale îşi dovedesc în
principal utilitatea în rezolvarea unor probleme dificile, cum sunt cele de estimare, identificare
şi predicţie sau de optimizare complexă. Datorită independenţei efectuării operaţiilor din
interiorul componentelor faţă de celelalte componente din sistem, modelele conexioniste au
un potenţial mare de paralelism. Modul de memorare şi procesare a datelor diferenţiază
reţelele neuronale artificiale de programele clasice, care urmează instrucţiunile într-o ordine
secvenţială predefinită, iar informaţia este memorată în zone bine definite. Datorită capacităţii
lor de a rezolva probleme complexe pe baza unei mulţimi consistente de exemple, sistemele
conexioniste au un spectru larg de aplicabilitate: de la sisteme de recunoaştere de forme
(caractere, semnături, etc.) sau de semnale sonore, până la sisteme pentru controlul unor
procese complexe, cum ar fi sistemele de auto-reglare sau piloţii automaţi.

139
6.9. Exerciţii.

A. EXERCIŢII REZOLVATE.

Exerciţiul 1. Exemplu de aplcare a metodelor de învăţare la jocul de cărţi.


Trebuie să se afle care este prima întrebare ce poate fi pusă, având în vedere că
conceptul ţintă în domeniul cărţilor este “cărţile negre impare sau 2 ”. Caracteristicile despre
care se pot pune întrebări sunt culoarea, paritatea, sau orice rang. Se iau în considerare doar
două posibile întrebări: Cartea este roşie? şi Este cartea trei? Dacă se întrebă despre culoare,
există şansa de 50% ca să fie roşie şi 50% să fie neagră. Deci relaţia (5.13), paragraful 5.2.1.4.
devine:

Gculoare 0.5IV rosie 0.5IVneagra (5.14)

Din cele douăzeci şi sase de cărţi roşii, una (2 ) este în clasa ţinta şi celelalte douăzeci
şi cinci nu sunt. Deci, valoarea adiţională a informaţiei despre apartenenţa lui x la T este dată
de:

1 1 25 25
IV log log 0.235
rosie 26 26 26 26

Din cele douăzeci şi sase de cărţi negre, paisprezece (cele impare) sunt în T şi
douăsprezece nu sunt. Deci:

14 14 12 12
IV log log 0.996
neagra 26 26 26 26

Combinând aceste doua relaţii cu (5.14) rezultă:

Gculoare 0.615

În cazul în care se întreabă dacă o carte este un 3, relaţia (5.14) devine:

1 12
G I I
3 13 V3 13 V 3

Din cele patru cărţi de 3, două (cele negre) sunt în T, iar celelalte două nu sunt.
Aceasta înseamnă că IV 1 . Din cele 48 de cărţi care nu sunt 3, treisprezece sunt în set (12
3
cărţi negre impare ramase plus 2 ) şi restul nu sunt. Aceasta conduce la I 3 0.843 , deci:

G3 0.855

şi rezultă din aceasta că întrebând despre culoare este mai eficient decât întrebând dacă o carte
este un 3. Acest lucru este normal deoarece - întrebând despre culoare se parcurge un drum

140
lung până la decizia dacă o carte este neagră impară, în timp ce întrebarea “dacă este un 3?”
este chiar fără sens.

Exerciţiul 2. Exemplu de simulare a unui neuron arttificial.


Un model simplificat de neuron artificial poate fi uşor simulat printr-un model ca în
figura 2.2..

Fig.2.2. Modelul neuronului artificial

Dendritele sunt reprezentate prin săgeţile de intrare şi variabilele xi care reprezintă


prezenţa ( xi (t ) 1 ) sau absenţa ( xi (t ) 0 ) pulsului de antrenare pe fibra i la momentul t.
Fiecare neuron artificial are o singură ieşire reprezentând axonul neuronului şi prezenţa sau
absenţa pulsului de antrenare la un axon este prezentată prin valorile 1 sau 0 a variabilei y (t ) .
Există o linie de intrare specială cu o constantă de intrare x0 1 , şi o pondere w0 . Această
constantă de intrare x0 1 şi ponderea w0 realizează un prag egal cu w0 . Când suma
ponderată a semnalelor de intrare este mai mare decât pragul T w0 ieşirea y va deveni 1.
n
1, daca wi xi w0
y i 1 (1)
0, in celelalte cazuri

141
Exerciţiul 3.
Fie următoarea schemă electrică (care poate fi o reprezentare electonică a neuronului
artificial) în care ieşirea este un tranzistor.

Tranzistorul va fi deschis dacă:

E1 E2 Us
(2)
R1 R2 RT
Să se reprezinte această schemă ca o reţea neuronală cu alegerea valorilor în
conformitate cu exerciţiul 2.

Rezolvare.
Us
Alegem intrările x1 E1 şi x2 E2 iar ponderea w0 şi atunci luând ponderile
RT
1 1
w1 şi w2 condiţia (2) de funcţionare a tranzistorului dată în enunţ devine
R1 R2
w1 x1 w2 x2 w0
ceea ce asigură faptul că tranzistorul va fi deschis.

Exerciţiul 4.
Să se reprezinte sub forma unei reţele neuronale următoarea frază „Ion va merge
afară la plimbare dacă şi numai dacă soarele străluceşte sau dacă este frig iar vântul bate
spre vest” folosind reprezentarea predicativă a frazei.

Rezolvare.
Predicatul „Ion va merge afară la plimbare” va fi adevărat dacă condiţiile menţionate
vor fi adevărate. Vom reprezenta în valorile de adevăr, ADEVĂRAT şi respectiv FALS, prin
1 şi respectiv 0. Vom reprezenta de asemenea în valorea de adevăr a propoziţiei „soarele
străluceşte ” prin variabila x1 , valorea de adevăr a propoziţiei „este frig” prin variabila x2 şi
valorea de adevăr a propoziţiei „ vântul bate spre vest” prin variabila x3 şi însfârşit valorea
de adevăr a propoziţiei „Ion va merge afară la plimbare” prin variabila y . Cu aceste notaţii
putem enumera toate situaţiile posibile printr-un tabel de adevăr după cum urmează:

142
Tabelul 2.1.

Dacă considerăm valorile lui x1 , x2 şi x3 ca intrări ale unui neuron artificial simplu şi
y caieşirea sa, atunci putem selecta ponderile w0 , w1 , w2 şi w3 astfel încât acest neuron să
indice la ieşire valorile de adevăr posibile ale propoziţiei „Ion va merge afară la plimbare”
iar reprezentarea neuronală va fi următoarea:

x0 1

x1 w0

w1

x2
w2
y

w3

x3

Precizăm că există metode analitice sau metode prin învăţare care determină valorile
apropiate ale ponderilor.

143
Exerciţiul 5.
Fie o funcţie specificată prin tabela de adevăr următoare.

Tabelul 5

Să se obţină expresia funcţiei prag y S ( w0 w1 x1 w2 x2 w3 x3 ) şi să se reprezinte sub


formă de reţea neuronală funcţia obţinută.

Rezolvare:
Ţinând seama de relaţia (1), exerciţiul 2, este clar că
w0 0, pentru y 0
n (3)
wi xi w0 0, pentru y 1
i 1

Şi atunci din tabelul 2.4.obţinem următoarele inegalităţi:


(1). w0 0
(2). w0 w3 0
(3). w0 w2 0
(4). w0 w2 w3 0
(4)
(5). w0 w1 0
(6). w0 w1 w3 0
(7). w0 w1 w2 0
(8). w0 w1 w2 w3 0

Din (1) şi (4) deducem că w2 w3 0 . Luând w2 1 şi w3 1 atunci din (2) şi (3)


deducem w0 1 . Luăm w0 1 şi din (5) putem lua w1 2 . Cu această alegere a
ponderilor toate inegalităţile sunt satisfăcute şi obţinem următoarea funcţie prag funcţiei prag
y S ( 1 2 x1 x2 x3 ) .
Modelul de reţea neuronală corespunzător acestei alegeri a ponderilor este următorul:

144
Pentru acest exemplu este clar că există, evident cu respectarea resticţiilor impuse de
inegalităţile (4), mai multe de posibilităţi de alegere a setului de ponderi ( w0 , w1 , w2 , w3 ) .
Spre exemplu o alegere
( w0 2, w1 4, w2 2, w3 2) i
iar alta ar fi
( w0 1, w1 4, w2 1, w3 1) .

B. TEMA DE CONTROL.

Exerciţiul 1.
Considerăm funcţia logică y f ( x1 , x2 , x3 ) definită prin y 1 dacă numărul de 1 în
lista argumentelor este impar şi y 0 în sens contrar. Această funcţie este cunoscută ca
problema parităţii şi este specificată în tabelul următor:

145
Să se precizece dacă există o funcţie prag de forma y S ( w0 w1 x1 w2 x2 w3 x3 )
care să rezolve problema parităţii şi în caz afirmativ să se reprezinte reţeaua neuronală
corespunzătoare.

Exerciţiul 2.
Considerăm funcţia booleană
1, daca x1 x2
f ( x1 , x2 ) (5)
0, daca x1 x2
Tabelul valorilor de adevăr pentru această funcţie este:

Să se precizece dacă există o funcţie prag de forma y S ( w0 w1 x1 w2 x2 ) care să


rezolve problema acestei funcţii şi în caz afirmativ să se reprezinte reţeaua neuronală
corespunzătoare.

Exerciţiul 3.
Fie funcţia booleană disjuncţie
f ( x1 , x2 ) x1 x2
al cărui tabel de adevăr este următorul:

Să se precizece dacă există o funcţie prag de forma y S ( w0 w1 x1 w2 x2 ) care să rezolve


problema acestei funcţii şi în caz afirmativ să se reprezinte reţeaua neuronală corespunzătoare.

146
6.10. BIBLIOGRAFIE RECOMANDATĂ LA MODULUL 3:
1. Podaru Vasile, Inteligenţă artificială şi siteme expert, Editura Academiei
Tehnice Militare, 1997
2. Podaru Vasile, Barnoschi Adriana, Sisteme expert, Editura Academiei
Tehnice Militare, 2000, 2004.
3. Ioan Georgescu, Elemente de inteligenţă artificială, Editura Academiei RSR,
1985.
4. Podaru Vasile, Inteligenţă artificială, curs în format electronic, CD-
învăţământ la distanţă, Universitatea Titu Maiorescu, 2010.
5. D. Cîrstoiu, Sisteme expert, editura ALL, 1994.
6. SICSTUS PROLOG USER’S MANUAL. Intelligent Systems Laboratory,
Sweedish Institute of Computer Science:
http://www.sics.se/isl/sicstuswww/site/documentation.html
7. M. Maliţa, Bazele inteligenţei artificiale, editura Academiei Române, 1988.

147
UNIVERSITATEA TITU MAIORESCU
Facultatea de INFORMATICĂ

Prof. univ. dr.

VASILE PODARU

Curs pentru învăţământul la distanţă

BUCUREŞTI – 2011
UNIVERSITATEA Titu MAIORESCU Bucureşti
Facultatea de Informatică
Învăţământ la Distanţă

INTELIGENŢĂ ARTIFICIALĂ
Inteligenţa artificială este una din disciplinele de pregătire fundamentală care, pentru
profilul INFORMATICĂ, este esenţială pentru pregătirea studenţilor şi pentru obţinerea
creditelor transferabile prin procedurile de evaluare. Modul de prezentare a acestui material are în
vedere particularităţile învăţământului la distanţă, la care studiul individual este determinant.
Pentru orice nelămuriri faţă de acest material vă rugăm să contactaţi tutorele de disciplină care
are datoria să vă ajute oferindu-vă toate explicaţiile necesare.
Disciplina de Inteligenţa artificială îşi propune următoarele obiective specifice:
Însuşirea noţiunilor fundamentale din domeniile Inteligenţei artificiale.
Formarea deprinderilor de modelare matematică şi de transpunere în programare a unor
probleme de natură tehnică, socială sau economică, cu utilizarea cunoştinţelor însuşite.
Formarea şi dezvoltarea aptitudinilor şi deprinderilor de analiză logică, formulare corectă
şi argumentare fundamentată, în rezolvarea problemelor tehnico-economice şi de
specialitatecu cu utilizarea cunoştinţelor însuşite prin intermediul metodelor şi modelelor
specifice inteligenţei artificiale;
Insusirea principiilor generale ale programarii logice si insusirea limbajului Prolog;
O comparaţie critică a metodelor de rezolvare evidenţiind, eventual, calea optimă de
soluţionare.
Accentul se va pune pe problemele de cautare si reprezentare a cunostintelor si respectiv
pe programarea logica, limbajul de programare utilizat la laborator fiind limbajul Prolog.
Cursul trebuie sa trateze aspecte ale rezolvarii problemelor prin intermediul cautarii,
descriind cele mai importante tehnici de cautare informata si neinformata. Se vor da
exmple de aplicatii ale cautarii, cum ar fi jocurile, tratate ca probleme de cautare. Se vor
prezenta principalele tipuri de cunostinte si principalele metode de reprezentare a
cunostintelor. Se va face legatura dintre reprezentarea cunostintelor si sistemele expert. Se
va da un exemplu de sistem expert cu implementare in Prolog. Vor mai fi tratate, ca
modalitati de reprezentare a cunostintelor, retelele semantice si retelele Bayesiene (cu
introducerea rationamentului statistic).

Vă precizăm de asemenea că, din punct de vedere al verificărilor şi al notării (elemente ce


vor fi comunicate şi prin fişa disciplinei, calendarul disciplinei şi programarea orară), cu adevărat
importantă este capacitatea pe care trebuie să o dobândiţi şi să o probaţi de a rezolva toată
tipologia de probleme aplicative aferente materialului teoretic prezentat în continuare. De aceea
vă recomandăm să parcurgeţi cu atenţie toate aplicaţiile rezolvate, să rezolvaţi aplicaţiile propuse
prin testele de autoevaluare şi temele de control (pentru fiecare modul în parte trebuie să predaţi
tutorelui de disciplină rezolvarea acestor teme, pentru verificare şi evaluare); fiţi convinşi că
examenul final apelează la tipurile de aplicaţii prezente în secţiunile menţionate anterior.
Timpul mediu necesar însuşirii noţiunilor teoretice, formării deprinderilor de calcul şi
utilizării metodelor de rezolvare a problemelor specifice acestui modul este estimat la
aproximativ 6-8 ore pentru întregul modul , într-un ritm de 3-4 ore pentru fiecare din cele două
unităţi ale modulului.

149
Întru-cât modulul este privit ca un tot unitar exerciţiile aferente acestui modul se găsesc la
sfârşitul acestui modul. La terminarea parcurgerii acestui modul studenţii trebuie să prezinte
tutorelui de disciplină rezolvarea temei de control propusă spre rezolvare la sfîrşitul modulului.
Cursul se finalizează prin examen care constă din:
1) o lucrare scrisă sub forma de text grila constând din 9-18 subiecte (ponderea lucrării
scrise este de 70% din nota finală);
2) rezolvarea corectă a temelor de control din cele 4 module (minimum nota 5 pentru
fiecare temă, ponderea mediei celor 5 note în nota finală este de 20%);
3) participarea activă la activităţile tutoriale (apreciată printr-o notă a cărei pondere in
nota finală este de 10%).

Coordonator disciplină: Prof. univ. dr. Vasile PODARU, email: podaruv@gmail.com


Tutori: Prof. univ. dr. Vasile PODARU,

150
MODULUL 4

APLICAŢII ALE INTELIGENŢEI ARTIFICIALE.


Îndrumări metodice.

Inteligenţa artificială a apărut ca disciplină şi a fost fundamentată pe investigaţiile relative


la reprezentarea cunoaşterii şi căutarea dar nu numai.
În acest modul vom trata câteva din domeniile de aplicabilitate ale inteligenţei artificiale,
urmând ca altă parte din ele să fie studiate ân cadrul pregătirii prin masterat.
Prima parte a modulului este dedicată metodelor biometrice de autentificare. Astăzi,
tehnologiile biometrice au devenit soluţiile preferate ale unei arii extinse de aplicaţii, în special în
domeniul identificării şi verificării personalului. Este de aşteptat că biometria să fie încorporată în
soluţii de securitate naţională, cum ar fi îmbunătăţirea securităţii aeroporturilor, intărirea
graniţelor, verificarea documentelor de identificare şi a vizelor, prevenirea falsurilor de identitate.
Bineînteles, există domenii de aplicare şi în afara securităţii naţionale, cum ar fi securizarea
reţelelor marilor corporaţii, securizarea e-banking, investiţiile şi alte tranzacţii financiare,
vânzările cu amănuntul, sănătatea şi serviciile sociale.
A doua parte tratează problematica sistemelor expert. Un sistem expert este un program
de calculator conceput să simuleze unele forme ale raţiunii umane (prin intermedierea unui motor
de deducţie) şi capabil să administreze o importantă cantitate de cunoştinţe specializate.
Calea care duce la dezvoltarea sistemelor expert este diferită de cea a tehnicilor
convenţionale de programare. Conceptele pentru dezvoltarea sistemelor expert vin din domeniul
inteligenţei artificiale (AI), şi necesită o îndepărtare de la practicile convenţionale ale
calculatorului şi tehnicilor de programare. Un program convenţional constă într-un proces
algoritmic pentru a atinge un rezultat specific. Un program AI este făcut dintr-o bază de
cunoştinţe şi o procedură pentru a indica un răspuns.
Sistemele expert sunt capabile să distribuie informaţii cantitative, multe din ele fiind
dezvoltate în urma unor cercetări de bază şi aplicate (ex. praguri economic, modele de dezvoltare
în serie) dar şi euristice pentru a interpreta valorile derivate calitativ, sau pentru folosirea în locul
unor informaţii cantitative. Altă caracteristică este că aceste sisteme pot adresa date imprecise şi
incorecte prin asignarea unor valori de încredere la intrări şi concluzii.
Unul dintre cele mai puternice atribute ale unui sistem expert este abilitatea de a explica
raţional. Deoarece sistemul îşi aminteşte lanţul logic al raţionării, un utilizator va putea cere o
explicaţie a unei recomandări şi sistemul va afişa factorii pe care-i consideră în acea recomandare
particulară. Acest atribut măreşte încrederea utilizatorului în recomandarea făcută de sistem şi în
acceptarea acestuia.
Întru-cât modulul este privit ca un tot unitar exerciţiile aferente acestui modul se găsesc la
sfârşitul acestui modul. La terminarea parcurgerii acestui modul studenţii trebuie să prezinte
tutorelui de disciplină rezolvarea temei de control propusă spre rezolvare la sfîrşitul modulului.
Cursul se finalizează prin examen care constă din:
1) o lucrare scrisă sub forma de text grila constând din 9-18 subiecte (ponderea lucrării
scrise este de 70% din nota finală);
2) rezolvarea corectă a temelor de control din cele 5 module (minimum nota 5 pentru
fiecare temă, ponderea mediei celor 5 note în nota finală este de 20%);
3) participarea activă la activităţile tutoriale (apreciată printr-o notă a cărei pondere in
nota finală este de 10%).

151
Unitatea de învăţare nr.7

Metode biometrice în Inteligenţa Artificială.


Cuprins:
7.1. Biometria .................................................................................................... pag. 152
7.2. Sisteme biometrice unimodale ................................................................... pag. 154
7.3. Sisteme biometrice multimodale ................................................................ pag. 155
7.4. Performanţele şi erorile sistemelor biometrice .......................................... pag. 156
7.5. Securitatea sistemelor biometrice ............................................................... pag. 164
7.6. Metode de Autentificare ............................................................................ pag. 167

7.1. Biometria.

Biometria (cuvânt derivat din grescul bios = “viaţă” şi metron = “măsură”) constă în
metode automate de recunoaştere a individului, bazate pe caracteristici fizice sau
comportamentale. Printre acestea se numară amprentele, scanarea retinei şi a irisului, geometria
mâinii şi a degetului, recunoaşterea caracteristicilor vocale şi recunoaşterea facială. Astăzi,
tehnologiile biometrice au devenit soluţiile preferate ale unei arii extinse de aplicaţii, în special în
domeniul identificării şi verificării personalului. Este de aşteptat că biometria să fie încorporată în
soluţii de securitate naţională, cum ar fi îmbunătăţirea securităţii aeroporturilor, intărirea
graniţelor, verificarea documentelor de identificare şi a vizelor, prevenirea falsurilor de identitate.
Bineînteles, există domenii de aplicare şi în afara securităţii naţionale, cum ar fi securizarea
reţelelor marilor corporaţii, securizarea e-banking, investiţiile şi alte tranzacţii financiare,
vânzările cu amănuntul, sănătatea şi serviciile sociale. În Occident, toate aceste sfere de activitate
beneficiază deja de aplicaţiile biometrice şi pe lângă aceastea se iau în considerare, ca obiective
de acoperit, parcurile de distracţii, băncile şi alte organizaţii financiare, colegiile, cantinele
şcolare şi multe alte facilităţi.
Definiţie: Biometria – o disciplină recentă – este ştiinţa identificării sau verificării
identităţii unei persoane pe baza caracteristicilor fizice sau comportamentale.
• caracteristici fizice (măsurate la un anumit moment de timp): amprentele digitale,
faţa, geometria mâinii, irisul, retina, forma urechii, mirosul, reflexia pielii, termogramele
• caracteristici comportamentale (variaţia pe o durată de timp): scrisul, vocea,
mersul, modul de tastare, mişcarea buzelor

152
Orice caracteristică umană fizică sau comportamentală poate fi utilizată ca identificator
biometric dacă satisface următoarele cerinţe:
• universalitate;
• unicitate;
• permanenţă;
• colectabilitate.
Într-un sistem biometric practic, există şi alte aspecte care trebuie luate în considerare:
• performanţele sistemului: acurateţea recunoaşterii, viteza, robusteţea realizabilă,
resursele necesare pentru a atinge acurateţea şi viteza dorită, precum şi factorii operaţionali şi de
mediu care afectează acurateţea recunoaşterii şi viteza;
• acceptabilitatea;
• posibilitatea de fraudare a sistemului.
Fiecare din aceste criterii conduc la metode care prezintă avantaje şi dezavantaje cu
privire la securitate, uşurinţă în exploatare şi cost.
Nivelul de securitate oferit de o soluţie biometrică este relativ foarte ridicat, deoarece
administratorul sistemului este singura persoană autorizată să managerizeze datele existente în
sistemul de control al accesului. Prin implementarea unui sistem biometric de securitate se
elimină costurile de administrare a sistemului (carduri, personal autorizat, managementul
înregistrarilor, etc) care, printr-o soluţie clasică, nu pot fi diminuate sau evitate. În al doilea rând,
reducerea costurilor reprezintă o consecinţă directă a scăderii riscurilor de securitate odată cu
implementarea unei asemenea soluţii.
Autentificarea biometrică, adică bazată pe identificarea amprentelor digitale, a irisului, a
amprentei vocale, este cea mai puternică metodă de autentificare a unui utilizator al unui sistem
informatic.Majoritatea metodelor de autentificare utilizate pe scară largă prezintă vulnerabilităţi
şi dezavantaje: cheile se pot pierde, parolele pot fi uitate sau aflate de persoane care nu ar avea
dreptul să le posede. Trăsăturile anatomice nu pot fi copiate uşor şi nici pierdute. Utilizarea
autentificării biometrice este soluţia ideală pentru a asigura securitatea datelor permiţând
renunţarea definitivă la folosirea parolelor şi la riscurile presupuse de acestea, de a fi deconspirate
sau uitate. Dintre toate metodele de autentificare, biometrica cea mai utilizată este cea bazată pe
identificarea amprentelor digitale.

153
Folosirea amprentelor digitale ca metodă infailibilă de identificare coboară în timp în
1880, când Alphonse Bertillon a demonstrat că desenele liniilor de pe buricele degetelor noastre
rămân neschimbate toată viaţa. De la finele secolului al XIX-lea, poliţia a început să folosească
tehnica în descoperirea anumitor infracţiuni, constituindu-şi imense fişiere cu amprente digitale
pe care trebuiau să le foileteze experţi specializaţi. La finele anilor ’70, serviciile de poliţie au
recurs la informatică pentru compararea amprentelor, soluţie care le permite stocarea şi
identificarea a zeci de milioane de amprente. Acum identificarea cu ajutorul amprentei este
folosită cu mare succes în industria telefoanelor mobile, a computerelor şi chiar a automobilelor.
Astfel, au apărut telefoane mobile care nu se deschid decât după verificarea amprentei digitale a
posesorului. Astfel încât, dacă acestea sunt furate, ele nu mai pot fi folosite de către hoţ.
Un sistem de verificare autentifică identitatea unei persoane prin compararea
caracteristicii biometrice capturate cu modelul biometric propriu acelei persoane, stocat anterior
în sistem. Acesta efectuează o comparaţie 1-1 pentru a determina dacă identitatea pretinsă de
către individ este cea adevărată. Sistemul de verificare respinge sau acceptă identitatea susţinută.
Un sistem de identificare recunoaşte un individ prin compararea caracteristicii biometrice
cu întreaga bază de date de modele. Aceasta efectuează comparaţii de tipul 1-N pentru a stabili
identitatea individului. Într-un sistem de identificare, sistemul stabileşte identitatea subiectului
(sau eşuează dacă subiectul nu este înregistrat în baza de date a sistemului) fără ca subiectul să
pretindă o identitate.

7.2. Sisteme biometrice unimodale.


Un sistem biometric simplu (unimodal) conţine patru componente (module) de bază:
Modulul de senzori, Modulul extracţiei caracteristicilor, Modulul de potrivire, Modulul de luare
a deciziilor.
Limitările sistemelor biometrice folosind o singură caracteristică biometrică sunt:
Nivelul de zgomot simţit în date,Variaţii intra-clasă, Deosebiri ,Non-universabilitatea, Atacuri
spoofing (de falsificare).
Principalele metode biometrice unimodale de autentificare sunt: Recunoaşterea facială,
Amprentele digitale, Geometria mâini,Scanarea irisului, Scanarea retinei, Modelele de vene,
Semnătură, Verificarea vocii, ADN, Structura dinţilor, Mersul, Urechea, Presiunea şi Ritmul

154
apăsării tastelor. Tabelul de mai jos (Figura 1.2.1) ne arată o comparaţie între diferite metode
biometrice:

Figura 1.2.1 Comparaţie între diferite metode biometrice unimodale

7.3. Sistemele biometrice multimodale.

Depăşirea inconvenienţelor şi a limitelor menţionate se poate realiza prin utilizarea


sistemelor multimodale care duc la îmbunătăţirea performanţelor sistemelor, creşterea numărului
populaţiei înrolate în sistem şi la descurajarea fraudei.
Sistemele biometrice multimodale pot fi văzute din mai multe puncte de vedere,astfel în
cazul celor bazate pe amprentă :
 Sisteme multisenzor(optic,capacitiv,pe baza de chip etc.).
 Sisteme multi-metoda – folosesc mai multe metode la compararea vectorilor de test cu
referinţele( bazate pe filtrare).
 Sisteme multi-caracteristică – se folosesc amprentele de la mai multe degete;
 Sisteme multi-captură – se prelevează eşantioane ale aceleiaşi caracteristici
biometrice( de exemplu aceeaşi amprentă se preia de mai multe ori).
 Sisteme multi-verificator – se utilizează mai multe caracteristici biometrice
(amprenta, faţa,mâna,voce,iris etc).
În cazul sistemelor multimodale multi-verificator, caracteristicile biometrice care se
pretează la fuziune sunt prezentate în tabelul următor( Figura 1.3.1).

155
Figura 1.3.1 Identificatori biometrici folosiţi pentru sistemele multimodale multi-verificator.

7.4. Performanţele şi erorile sistemelor biometrice.

Datorită poziţionării diferite ale senzorilor de achiziţie, condiţiilor imperfecte de


fotografiere, schimbărilor mediului, deformaţiilor, zgomotului şi ale interacţiunii
necorespunzătoare dintre utilizator şi senzor, este imposibil ca două probe din aceleaşi
caracteristici biometrice, achiziţionate în sesiuni diferite, să corespundă cu exactitate. Din acest
motiv, răspunsul sistemului biometric de potrivire este un scor tipic de potrivire s (în mod normal
un singur numar) care cuantifică asemănările dintre intrare şi reprezentările şablon din baza de
date. Cu cât este mai mare scorul, cu atât mai mult sistemul este sigur că două probe coincid.Un
scor similar s este comparat cu un prag de acceptare t şi dacă s este mai mare sau egal cu t,
probele comparate aparţin aceleiaşi persoane. Perechi de probe biometrice care generează scoruri
mai mici decât t aparţin unor persoane diferite. Distribuţia de scoruri generate de perechi de
probe aparţinând unor persoane diferite este numită distribuţie impostor, şi distribuţia de scoruri
generate de perechi de mostre aparţinând aceleiaşi persoane poartă numele de distribuţie
veritabilă (Figura 1.4.1).

156
Figura 1.4.1 Ratele de eroare ale sistemelor biometrice

Principalele erori de sistem sunt măsurate de obicei în termeni ca:


 FNMR ( rata falsă de neasemănare – false nonmatch rate) – greşeala făcută atunci
când sistemul confirmă că două masurători biometrice aparţinând aceleiaşi persoane să aparţină
de două persoane diferite.
 FMR (rata falsă de asemănare-false match rate) - greşeala ca măsurătorile biometrice
de la două persoane diferite să aparţină unei singure persoane.
Există un compromis strict între FMR şi FNMR în orice sistem biometric. Dacă pragului
sistemului t scade pentru a face sistemul mai tolerant cu privire la variaţiile intrării şi ale
zgomotului, atunci FMR creşte; invers, dacă t creşte pentru a face sistemul mai sigur, atunci
FNMR creşte în consecinţă.
Este recomandabil să se raporteze performanţele sistemului pentru toate punctele de
operare t. Aceasta se face prin trasarea curbei Caracteristica de Operare a receptorului (ROC)
(Figura 1.4.2 ). O curbă ROC este graficul FMR faţă de (1 FNMR) pentru diferite praguri de
decizie.

157
Figura 1.4.2 Receptor de caracteristici operaţionale(ROC)
Matematic, erorile întru-un sistem de verificare pot fi formulate dupa cum urmează. În
cazul în care şabloanele biometrice stocate ale utilizatorului I sunt reprezentate de X1 şi
achiziţiile de intrare pentru recunoaştere sunt reprezentate de Xq, atunci ipoteze alternante şi
ipotezele zero sunt:
 H0 :Intrarea Xq nu provide de la aceeaşi persoană ca a şablonului X1;
 H1: Intrarea Xq provine de la aceeaşi persoană ca a şablonului X1;
Deciziile sunt asociate aşa cum urmează:
 D0:Persoana nu este cine pretinede a fi;
 D1:Persoana este cine pretinde a fi.
Regula decizională este următoarea:dacă scorul de potrivire S(Xq,X1) este mai mic decât
pragul sistem t, atunci este valabilă decizia D0, dacă nu decizia D1. Dacă H0 este ipoteza,atunci
semnalul primit este un semnal de zgomot singur, şi dacă H1 este ipoteza atunci semnalul primit
este un mesaj plus zgomot. O astfel de ipostază de testare formulată în mod inerent conţine două
tipuri de erori:
 Tipul 1 : Falsa potrivire (D1 este ales când H0 este adevărat).
 Tipul 2 : Falsa nepotrivire (D0 este ales când H1 este adevărat).
FMR este probabilitatea de eroare de tipul 1 şi FNMR este probabilitatea de eroare de
tipul 2.

158
 FMR = P(D1|H0 = adevărat);

 FNMR = P(D0|H1 = adevărat).


Pentru a evalua acurateţea unui sistem biometric se colectează scoruri generate de un
număr de perechi de caracteristici biometrice de la aceeaşi persoană (distribuţia
p(s|H1 = adevărat)) şi scoruri generate de un număr de perechi de caracteristici biometrice de la
persoane diferite (distribuţia p(s|H0 = adevărat)).

Calculul lui FMR şi FNMR se poate realiza cu ajutorul formulelor:


ărat d
t
FNMR p s H1 adev s
0 ărat d
1
FMR p s H0 adev s
t

În afară de ratele de eroare de mai sus, eşecul de a captura rata (FTC) şi eşecul de a
înscrie rata (FTE) sunt de asemenea folosiţi pentru a rezuma precizia unui sistem biometric. Rata
FTC este aplicabilă când dispozitivul biometric are o funcţionalitate automată de capturare
implementată în el şi aceasta denotă numărul de încercari nereuşite ale dispozitivului biometric în
încercarea de a captura un şablon în cazul în care caracteristicile biometrice îi sunt prezentate.
Rata FTE pe cealaltă parte, denotă numărul de încercari nereuşite de înscriere în sistemul de
recunoaştere ale utilizatorilor. Există o legatură între rata FTE şi rata de precizie a sistemului
(FMR şi FNMR).
Acurateţea unui sistem este cea mai importantă caracteristică a acestuia şi, din acest
motiv, este unul din principalii parametrii de diferenţiere între un sistem performant şi unul
defectuos. Din acest motiv, au apărut competiţii şi teste internaţionale care îşi propun clasificări
după criterii foarte stricte a metodelor biometrice.
În cazul evaluării performanţelor unui algoritm de înrolare şi verificare biometrică, se
disting două caracteristici principale, definite la rândul lor de două rate de eroare. Prima este Rata
de Rejecţie falsă (FRR), care defineşte numărul de date autorizate ce sunt excluse de algoritm. A
doua este Rata de Acceptare falsă (FAR), care defineşte numărul de date neautorizate (impostor),
cărora algoritmul le permite accesul.
Pentru fiecare algoritm şi bază de date se raportează o serie de indicatori, cei mai
importanţi dintre ei fiind:

159
 REJENROLL (Numărul de date biometrice refuzate în procesul de înrolare);
 REJNGRA (Numărul de date biometrice refuzate în cazul testelor de autentificare
autorizată);
 REJNIRA (Numărul de date biometrice refuzate în cazul testelor de autentificare
neautorizată);
 FMR100 (cea mai mică rată de acceptare falsă pentru FAR<=1%);
 FMR1000 (cea mai mică rată de acceptare falsă pentru FAR <=0.1%);
 ZeroFMR (cea mai mică rată de acceptare falsă pentru FAR =0%);
 ZeroFNMR (cea mai mică rată de rejecţie falsă pentru FRR =0%);
 Timpul mediu de înrolare;
 Timpul mediu de verificare; Valoarea medie FMR100;
 Valoarea medie FMR1000;
 Valoarea medie ZeroFMR;
 Valoarea medie REJENROLL (numărul mediu de date biometrice refuzate la înrolare);
 Valoarea medie REJMATCH (numărul mediu de date biometrice refuzate în cazul
autentificărilor autorizate şi neautorizate);
 FTE (Fail To Enroll), imposibilitatea utilizatorului de a se înrola în sistem;
 FTA (Fail To Acquire), imposibilitatea utilizatorului de a se autentifica în sistem.
Aceşti indicatori sunt, de fapt, o serie de valori caracteristice ce fac diferenţa dintre un
algoritm, respectiv, un produs sigur şi unul defectuos.
Figura 1.4.3. arată un mod de comportare al acestor indicatori.

160
Figura 1.4.3.

Alţi indicatori care reflectă acurateţea sistemului de verificare:


• Rata erorilor egale (ERR): rata potrivirii false şi rata nepotrivirii false sunt egale.
• Zero FNMR: cea mai mică FMR la care nu are loc nici o nepotrivire falsă.
• Zero FMR: cea mai mică FNMR la care nu are loc nici o potrivire falsă.
• Rata eşecului de captură (FTC): de câte ori dispozitivul nu reuşeşte să captureze automat
caracteristica biometrică când aceasta este prezentată senzorului.
• Rata eşecului de înscriere (FTE): de câte ori utilizatorii nu se pot înscrie în sistem. Există
un compromis între rata FTE şi acurateţea sistemului (FMR şi FNMR). Erorile FTE au
loc, de obicei, când sistemul efectuează un control de calitate pentru a se asigura că numai
şabloanele de bună calitate sunt stocate în baza de date. Prin urmare, baza de date conţine
doar şabloane de bună calitate şi acurateţea sistemului (FMR şi FNMR) se îmbunătăţeşte.
• Rata eşecului de potrivire (FTM): de câte ori intrarea nu poate fi procesată sau potrivită cu
şablonul respectiv datorită calităţii insuficiente. Aceasta este diferită de eroarea de
nepotrivire falsă; de fapt, în cazul eşecului de potrivire sistemul nu poate lua o decizie, în
timp ce într-o eroare de nepotrivire falsă sistemul decide greşit că cele două intrări nu
provin de la acelaşi persoană.
Totodată, ca rezultat al dezvoltării domeniului biometric, pe plan internaţional s-a
constatat nevoia instituirii unui consorţiu ce are ca scop interfaţarea şi certificarea diverselor

161
aplicaţii biometrice sub un singur standard. Acest consorţiu poartă numele de BioAPI, iar
certificarea BioAPI a devenit un standard necesar pentru orice algoritm biometric.
Rezultatul final al autentificării/verificării este dat, de fapt, de unul din cele patru cazuri
menţionate mai sus: acceptare corectă sau falsă şi rejecţie corectă sau falsă.
Formulele de calcul pentru aceste rate de eroare sunt:
 FRR = FTE+ FTA+ FNMR
 FAR= (1- FTE) * (1- FTA) * FMR
Valorile astfel calculate pot fi introduse într-un grafic, rezultând astfel un punct de
intersecţie EER (Equal Error Rate-Figura 1.4.3 ), ce poate fi folosit ca o evaluare a
performanţelor simplificate în cazul sistemelor biometrice.

Figura 1.4.3

Realizarea unui sistem biometric pentru câţiva utilizatori poate fi relativ uşoară, dar
adaptarea pentru milioane de utilizatori implică probleme mult mai complicate. Chiar dacă viteza
de verificare şi acurateţea rămân esenţiale atât pentru un sistem cu 100 de utilizatori, cât şi pentru
unul cu 10 milioane, modul de identificare va deveni complet diferit. Adiţional faţă de erorile de
falsă acceptare şi falsă rejecţie, apare un alt tip de eroare ce se referă la falsa identificare (FI); în
acest caz, un utilizator poate fi asociat greşit unei alte înregistrări biometrice. Această rată de
eroare asociată FI va purta denumirea FIR. În ceea ce privesc erorile sistemelor de identificare
sunt de discutat următoarele aspecte.
• În condiţiile unor simplificări, o estimare a performanţelor în modul identificare poate fi
dedusă din evaluarea erorilor în modul verificare.

162
• Să presupunem că nu este disponibil nici un mecanism de indexare/regăsire (deci trebuie
căutată întreaga bază de date conţinând N şabloane) şi că este prezent un singur şablon în baza de
date pentru fiecare utilizator.
Fie FNMRN şi FMRN, rata nepotrivirii false şi respectiv rata potrivirii false în cazul
identificării, atunci:
FNMRN = FNMR: probabilitatea nepotrivirii false a intrării cu şablonul
utilizatorului este aceeaşi ca în modul verificare;
FMRN = 1 (1 FMR)N: o potrivire falsă are loc când intrarea se potriveşte
fals cu unul sau mai multe şabloane din baza de date.
Dacă FMR este foarte mic atunci
FMRN N FMR şi probabilitatea potrivirii false creşte liniar cu mărimea
bazei de date.
• Acest rezultat are implicaţii serioase în proiectarea sistemelor de identificare la scară
largă. Să considerăm o aplicaţie de identificare cu ajutorul amprentelor digitale cu 10.000 de

utilizatori. Să presupunem că, pentru un FNMR acceptabil, FMR-ul algoritmului ales este 10 5
(doar o potrivire falsă la 100.000 de comparări). Atunci probabilitatea acceptării false a unui
individ în timpul identificării este FMRN 10%, şi oricine are o bună şansă de a obţine accesul la
sistem prin încercarea celor zece degete de la cele două mâini.
• Dacă şabloanele din baza de date au fost clasificate/indexate, atunci doar o parte a bazei
de date este căutată în timpul identificării şi aceasta duce la o formulare diferită a FNMRN şi
FMRN:

FNMRN = RER +(1 RER) FNMR, unde RER (rata erorii de regăsire) este
probabilitatea că şablonul căutat să fie depistat greşit de
mecanismul de regăsire;

FMRN = 1 (1 FMR)N P, unde P (numită şi rată de pătrundere) este


numărul mediu de şabloane căutate în timpul identificării.

163
7.5. Securitatea sistemelor biometrice.

Elementele componente ale sistemului biometric pot fi gândite ca o schema prezentată în


figura 1.4.5.

1 3 5

Dispozitivul de Extractorul de
intrare / senzorul Comparatorul Aplicaţia
caracteristici
biometric 2 4 6

7
Înscrierea în Baza de date a
caracteristicilor
sistem
9 de referinţă

8 10

Figura 1.4.5.

Pe schemă sunt figurate şi numerele care definesc punctele de atac într-un sistem
biometric. Iată care sunt acestea:
1. La prezentarea caracteristicilor biometrice la senzorul de intrare:
– atac prin constrângere: în care sunt prezentate datele biometrice reale, dar
într-o modalitate neautorizată.
– atac prin simulare: în care un individ neautorizat îşi modifică trăsăturile
biometrice (mai ales în cazul feţei sau vocii) pentru a apărea asemenea
persoanei autorizate.
– atac de tip reluare: în care o înregistrare a datelor biometrice reale este
prezentată dispozitivului de intrare.
Contramăsuri:
– detecţia situaţiile de constrângere prin analiza stresului utilizatorului sau
prin supravegherea sistemului
– detecţia semnelor vitale
– metode multibiometrice
2. Atacul canalului de legătură dintre senzorul biometric şi extractorul de caracteristici:
– Acesta poate fi un atac de tip reluare, prezentarea unui semnal

164
biometric
stocat anterior, sau o simulare electronică. Acesta include ocolirea
senzorului prin reintroducerea imaginii unei amprente sau a feţei sau prin
injectarea unui semnal audio la ieşirea microfonului. Dacă accesul fizic în
acest punct este disponibil, acest atac este mai simplu decât atacul asupra
senzorului. Tehnici de criptare digitală şi indicatori de timp pot contracara
aceste atacuri. Mai mult, sistemul poate detecta potrivirea perfectă cu date
anterioare din sistem.
– Simularea electronică poate consta în introducerea imaginii unei amprente
creată în mod artificial din dispunerea detaliile striaţiilor obţinute din
înregistrarea acestor detalii de pe un card.
3. Atac de tip „cal Troian” asupra extractorului de caracteristici:
– Modulul de extragere a caracteristicilor poate fi atacat astfel încât va
produce un set prestabilit de caracteristici la un anumit moment de timp şi
în anumite condiţii. După extragerea caracteristicilor din semnalul de
intrare, acestea sunt înlocuite cu un set sintetizat de caracteristici diferit,
presupunând că modul de reprezentare este cunoscut.
4. Atacul canalului de legătură dintre extractorul de caracteristici şi comparator.
– În cazul amprentelor dacă detaliile striaţiilor sunt transmise la un
comparator aflat la distanţă (de exemplu în cazul în care se utilizează
smartcarduri pentru stocarea reprezentării de referinţă) această ameninţare
este foarte reală.
5. Atac de tip „cal Troian” asupra comparatorului caracteristicilor de intrare cu cele de
referinţă.
– În acest caz comparatorul produce un scor de similitudine mare sau mic în
mod artificial, astfel falsificând deciziile comparatorului pentru un anumit
utilizator.
6. O ameninţare foarte importantă prin care nu se ţine cont de ieşirea modulului de
comparare. Ieşirea acestui modul poate fi o decizie categorică (da sau nu) sau poate fi
probabilitatea de asemănare, decizia finală fiind lăsată pe seama aplicaţiei.

165
7. Atacul canalului de comunicaţii dintre baza de date (centrală sau distribuită) şi
comparator.
– Reprezentarea biometrică stocată în baza de date este trimisă la comparator
prin acest canal. În cazul în care acest canal de legătură este atacat,
reprezentarea biometrică este modificată înainte de a ajunge la comparator.
8. Atacul la înscrierea în sistem.
– Procesele de înscriere şi de autentificare sunt simulare şi astfel
înregistrarea în sistem este vulnerabilă la atacurile 1…5.
9. Atacul canalului prin care reprezentarea biometrică de referinţă este trimisă bazei de
date.
10. Atacul asupra bazei de date a caracteristicilor de referinţă.
– Baza de date a înregistrărilor reprezentărilor biometrice poate fi disponibilă
local sau la distanţă, distribuită pe mai multe servere. Această ameninţare
constă în modificarea neautorizată a uneia sau mai multor reprezentări din
baza de date. Aceasta poate avea drept consecinţă autorizarea unui
infractor, refuzul serviciului persoanei asociate cu modelul de referinţă
corupt (presupunând că formatul reprezentărilor este cunoscut), sau
eliminarea unor indivizi de pe o listă de supraveghere.
Alte atacuri într-un sistem biometric pot fi următoarele:
• Posibilitatea de atac a sistemului biometric prin evitarea acestuia. În orice sistem
biometric este prevăzută o facilitate de lucru care permite tratarea excepţiilor. De exemplu,
autentificarea persoanelor fără degete într-un sistem de recunoaştere a amprentelor digitale.
• Atacul progresiv. Acest tip de atac implică prezentarea în mod repetat a datelor
biometrice unui algoritm cu uşoare modificări şi păstrarea acelor modificări care au ca rezultat un
scor îmbunătăţit. În final poate fi obţinut un scor care să depăşească pragul de comparare.
Această metodă este potrivită mai ales când atacatorul nu are nici o cunoştinţă referitoare la
datele biometrice ale utilizatorului legitim. Un asemenea atac poate fi împiedicat prin limitarea
încercărilor limitate sau prin furnizarea la ieşire doar a unor răspunsuri categorice de tipul da sau
nu, prin cuantificarea scorurilor de comparare sau prin adăugarea la acestea a unei mici cantităţi
de zgomot.

166
• Atacul prin inundare. Acesta este similar atacului de tip forţă brută în cazul parolelor,
exploatându-se slăbiciunile algoritmului de comparare. De exemplu, în cazul amprentelor
atacatorul poate prezenta o imagine sintetizată conţinând sute de detalii ale striaţiilor în speranţa
că cel puţin un anumit număr N, corespunzător unui prag, vor corespunde cu modelul de referinţă
stocat.
• Înscrierea ilegitimă în sistem. Reprezintă o ameninţare la orice sistem de securitate şi se
realizează prin simpla înregistrare a atacatorului sau prin atribuirea unor drepturi de acces
necorespunzătoare.
Metodele de creştere a securităţii sistemelor biometrice pot fi următoarele:
- Combinarea smartcardurilor şi a metodelor biometrice în aplicaţiile biometrice;
- Mecanisme eficiente de provocare-răspuns la sistemele proiectate;
- Transformări eficiente ale caracteristicilor biometrice:
• în domeniul semnalului biometric;
• în domeniul reprezentărilor biometrice.

7.6. Metode de Autentificare


Metodele biometrice de autentificare se împart în două mari categorii (Figura 1.4.6.):
 Metode biometrice fizice: incluzând studiul amprentelor digitale, a lungimii
segmentelor corporale, recunoaşterea geometriei palmei, desenului irisului ocular sau retinei,
formelor desenului reţelei vasculare sau structurii AND-ului celular.
 Metode biometrice comportamentale: implicând domenii ca recunoaşterea vocii, a
scrisului sau a semnăturii, a ritmului personal de scriere la tastatură, gestică, mimică şi mers.

Figura 1.4.6. Tipuri de metode biometrice

167
În industria biometriei, se face o distincţie clară între termenii „identificare“,
„recunoaştere“ şi „verificare“.
Identificarea şi recunoaşterea sunt în esenţă termeni sinonimi şi, în ambele procese, o
probă este prezentată sistemului biometric,care încearcă să determine cui aparţine, prin
compararea acesteia cu probele din baza de date, în speranţa găsirii unei perechi. Acest proces
poartă numele de „comparaţie unu la mai multe“.
Verificarea este o „comparaţie unu la unu“ în care sistemul biometric încearcă să verifice
identitatea unui individ. În acest caz, o nouă probă biometrică este capturată şi comparată cu
modelele anterior stocate. Dacă cele două modele se potrivesc, sistemul confirmă faptul că
individul este cine pretinde a fi.
În concluzie, în timp ce identificarea şi recunoaşterea presupun găsirea perechii unei
mostre într-o bază de date, verificarea implică potrivirea mostrei într-o bază de date, formată
dintr-un singur model. Astfel, în timpul identificării, sistemul biometric întreabă „Cine este
utilizatorul?“ şi stabileşte dacă înregistrarea biometrică există în baza de date, în timp ce la
verificare, sistemul întreabă „Utilizatorul este cine pretinde că este?“.
Înainte de a alege biometria ca soluţie de identificare a individului, o organizaţie trebuie
să-şi evalueze cu atenţie nevoile. Ceea ce trebuie să fie luat în considerare sunt nivelul de
securitate optim, acurateţea, costul şi timpul de implementare, precum şi acceptarea de către
utilizator.
Tehnicile biometrice de identificare a caracteristicilor fizice sunt mult mai precise oferind,
prin urmare, un nivel de securitate mai ridicat.
În ceea ce priveşte acurateţea, scanarea retinală şi identificarea irisului sunt metode de
identificare a individului foarte precise. Cu toate acestea, ambele sunt foarte costisitoare, iar
majoritatea organizaţiilor nu au nevoie de un nivel de siguranţă atât de precis.
Tehnicile de autentificare pe bază de amprentă, scanare facială sau geometria mâinii oferă
o buna acurateţe la un preţ mult mai mic. Schimbările fizice, precum tăieturi, cicatrice,
îmbătrânire, pot afecta precizia anumitor tehnici de determinare biometrică, însă aceste probleme
pot fi soluţionate printr-o continuă actualizare a bazelor de date.
Costul şi timpul de implementare al unui sistem biometric trebuie asociat cu o serie de
factori cum ar fi căutarea, achiziţionarea şi instalarea componentelor hardware şi software de
captură, autentificarea şi menţinerea bazelor de date, timpul de integrare a sistemului în mediul

168
existent, iniţierea personalului IT în utilizarea noului sistem şi familiarizarea utilizatorilor cu noul
protocol de identificare, colectarea şi menţinerea bazei de date necesară autentificării.

Figura 1.4.7.

Acceptarea sistemului biometric de către utilizator este o problemă foarte importantă, iar
în acest sens, organizaţia trebuie să familiarizeze angajaţii cu toate cerinţele sistemului, înainte ca
acesta să fie integrat.
Principalele metode biometrice de autentificare sunt: Recunoaşterea facială, Amprentele
digitale, Geometria mâinii, Scanarea irisului, Scanarea retinei,Modelele de vene, Semnătura,
Verificarea vocii, ADN, Structura dinţilor, Mersul, Urechea, Presiunea şi ritmul apăsării
tastelor.

169
Unitatea de învăţare nr.8.

Sisteme expert
Cuprins:
8.1. Introducere .................................................................................................... pag. 170
8.2. Metodologia de proiectare, implementare şi utilizare a unui sistem expert .. pag. 175
8.3. Studii de caz ................................................................................................... pag. 182
Bibliografie .......................................................................................................... pag. 189

8.1. Introducere.

Un sistem expert este un program de calculator conceput să simuleze unele forme ale
raţiunii umane (prin intermedierea unui motor de deducţie) şi capabil să administreze o
importantă cantitate de cunoştinţe specializate.
Un sistem expert este o aplicaţie de calculator care rezolvă probleme complicate care ar
necesita o vastă expertiză umană. Pentru a face aceasta, el simulează procesul de raţiune umană
prin aplicarea unor interfeţe şi cunoştinţe specifice. Acest raport a explicat procesul de luare a
deciziilor în cazul sistemelor expert pentru a da cele mai bune soluţii în rezolvarea problemelor.
Există şi alte încercări de definiţie a unui sistem expert:
- un sistem care foloseşte cunoştinţele umane captate într-un calculator pentru a rezolva
probleme care în mod curent necesită expertiză umană (Turban & Aronson, 2001);
- un program de calculator conceput să modeleze abilitatea de a rezolva a unui expert
uman (Durkin, 1994);
- un program de calculator inteligent care foloseşte proceduri de cunoaştere şi de deducţie
pentru a rezolva probleme care sunt deosebit de dificile astfel încât să necesite expertiză umană
semnificativă pentru a le rezolva (Feigenbaum).
Aceste capacităţi pentru raţionament şi control permit sistemului să analizeze un număr
mic de ipoteze relevante pentru a găsi o concluzie satisfăcătoare. Două caracteristici ale
sistemului expert sunt necesare pentru a îndeplini această sarcină:
 capacitatea de a procesa o cantitate mare de cunoştinţe şi
 capacitatea de a simula raţionamentul uman (într-o manieră imperfectă).
Sunt multe avantaje cunoscute în folosirea instrumentelor computerizate şi a sistemelor
expert:

170
 reducerea datelor lipsă,
 o mai bună culegere a datelor,
 neomiterea întrebărilor,
 ne-transcrierea datelor,
 o acoperire mai largă a diagnosticelor.
Arhitectura generală a unui sistem expert este:

Figura 8.1. Arhitectura generală a unui sistem expert

Aşa cum am văzut un sistem expert este un program de calculator creat pentru a simula
comportamentul în rezolvarea problemelor a unui om care este expert într-un domeniu sau o
disciplină anume. Un sistem expert este compus dintr-o bază de cunoştinţe (informaţii, euristică,

171
etc.), motor de decizie (analizează baza de cunoştinţe) şi, interfaţa cu utilizatorul (acceptă intrări,
generează ieşiri).
Calea care duce la dezvoltarea sistemelor expert este diferită de cea a tehnicilor
convenţionale de programare. Conceptele pentru dezvoltarea sistemelor expert vin din domeniul
inteligenţei artificiale (AI), şi necesită o îndepărtare de la practicile convenţionale ale
calculatorului şi tehnicilor de programare. Un program convenţional constă într-un proces
algoritmic pentru a atinge un rezultat specific. Un program AI este făcut dintr-o bază de
cunoştinţe şi o procedură pentru a indica un răspuns.
Sistemele expert sunt capabile să distribuie informaţii cantitative, multe din ele fiind
dezvoltate în urma unor cercetări de bază şi aplicate (ex. praguri economic, modele de dezvoltare
în serie) dar şi euristice pentru a interpreta valorile derivate calitativ, sau pentru folosirea în locul
unor informaţii cantitative. Altă caracteristică este că aceste sisteme pot adresa date imprecise şi
incorecte prin asignarea unor valori de încredere la intrări şi concluzii.
Unul dintre cele mai puternice atribute ale unui sistem expert este abilitatea de a explica
raţional. Deoarece sistemul îşi aminteşte lanţul logic al raţionării, un utilizator va putea cere o
explicaţie a unei recomandări şi sistemul va afişa factorii pe care-i consideră în acea recomandare
particulară. Acest atribut măreşte încrederea utilizatorului în recomandarea făcută de sistem şi în
acceptarea acestuia.
Basri (1999) a notat faptul că un sistem expert încearcă să imite cum un expert uman ar
rezolva o problemă, în special prin manipularea simbolurilor decât a numerelor. În timp ce
programarea algoritmică convenţională înlocuieşte munca analitică, sofisticată a inginerilor,
sistemele expert sunt potrivite în special părţilor mai puţin determinante ale planificării şi
proiectării.
Yang şi Okrent (1991) au afirmat că sistemele expert sunt mai ieftine în comparaţie cu
experţii umani în cazul unui scenariu de durată. Totuşi, sistemele expert sunt costisitoare la
dezvoltare dar sunt uşor şi ieftin de lucrat cu ele. În adiţie, sistemele expert permit automatizarea
mai multor task-uri ce nu pot fi manevrate cu uşurinţă de experţii umani.
Iată câteva diagrame care arată modalitatea de funcţionare unui sistem expert.

172
Figura 8.3. Părţile majore ale unui sistem expert

Figura 8.3. Proces tipic de achiziţie a cunoaşterii pentru construirea unui sistem expert

Sistemele expert trebuie văzute ca un tip particular de sisteme informaţionale. Sistemele


expert sunt distincte în forma în care se apropie de reprezentarea problemei, sistemele
informaţionale procesând informaţia, în timp ce sistemele expert încearcă să proceseze
cunoaşterea. Cunoaşterea în cazul unui sistem expert poate proveni din multe surse, cum ar fi

173
cărţi, rapoarte, baze de date, studii de caz, date empirice şi experienţa personală. Sursa dominantă
de cunoaştere în sistemele expert de azi este dominanta expert. Un inginer de cunoaştere obţine
de obicei cunoaşterea prin interacţiune directă cu expertul.

Figure 8.4. Sistem Expert şi Interacţiunea cu utilizatorul

Sistemele expert sunt folosite în aplicaţii din multe domenii: medical, agricol, juridic,
economie, industrie, învăţămâmt, cercetare, prognoză, guvernamental, poliţie, etc..

174
8.2. Metodologia de proiectare, implementare şi utilizare a unui sistem expert.
Metodologia Ingineriei Cunoaşterii (Knowledge engineering – KE) se referă la
proiectarea, întreţinerea şi dezvoltarea sistemelor bazate pe cunoaştere şi asigură succesul unui
sistem expert în îndeplinirea cerinţelor, obiectivelor şi scopului propus.

Figura 8.5. Metodologia Ingineriei Cunoaşterii

În acest context sunt necesare luarea în considerare a câtorva faze importante:

Faza 1: Aprecierea Problemei


Majoritatea organizaţiilor când achiziţionează orice tehnologie nouă îşi vor pune
întrebările fireşti: ‘Oare va funcţiona?’ şi ‘De ce ar trebui să încercăm?’ Din moment ce această
tehnologie este relativ nouă, răspunsurile la aceste întrebări vor veni curând. Totuşi, este
important ca un efort serios să fie depus pentru a răspunde la aceste întrebări înainte ca proiectul
să înceapă. Eşecul de a face aceasta va oferi neîncredere în proiect care va avea puţine şanse de a
reuşi şi nu va oferi mari beneficii organizaţiei.
Această fază este structurată conform următoarelor sarcini:

175
Sarcina 1: Determinarea motivării organizaţiei
Sarcina 2: Identificarea problemelor
Sarcina 3: Realizarea unor studii de fezabilitate
Sarcina 4: Realizarea unor analize de cost / beneficii
Sarcina 5: Selectarea celui mai bun proiect
Sarcina 6: Scrierea propunerii pentru proiect

Faza 2: Achiziţia şi Analiza Cunoştinţelor


Această sarcină este cea mai dificilă în dezvoltarea un sistem expert. Achiziţia cunoaşterii
este moştenită ca un proces ciclic. Sunt folosite aceste sarcini ale colecţiei cunoaşterii,
interpretarea şi analiza lor, şi design-ul metodelor pentru a strânge cunoştinţe adiţionale. Un
sistem expert îşi ia puterea din cunoştinţele pe care le deţine (Durkin, 1994). Una din cele mai
dificile aspecte ale sarcinii unui KE este ajutarea expertului în structurarea domeniului de
cunoştinţe, pentru a identifica şi formaliza conceptele (Hayes-Roth, Waterman şi Lenat).

Faza 3: Design şi Implementare


Această fază începe cu selecţia tehnicii de reprezentare a cunoştinţelor şi controlul
strategiei. Aceasta este urmată de selectarea unui instrument software care îndeplineşte cel mai
bine cerinţele problemei. Se construieşte un prototip pentru a valida proiectul şi pentru a oferi
ghid în lucrările următoare. Este dezvoltat proiectul în continuare pentru a îndeplini cerinţele
obiectivului.
Acest proces este structurat în conformitate cu următoarele sarcini:
Sarcina 1: Selectează reguli ca tehnici de reprezentare a cunoştinţelor
Sarcina 2: Selectează tehnica de control
Sarcina 3: Selectează software-ul de dezvoltare
Sarcina 4: Dezvoltă prototipul, interfaţa şi produsul
O apropiere bazată pe reguli este potrivită pentru sistemele care tratează probleme
folosind în special instrucţiuni de tip IF/ THEN. Această discuţie va crea un neajuns în descrierea
obiectivelor problemei, care va justifica nevoia pentru o apropiere bazată pe frame-uri.
Problemele de clasificare sunt tipice acestei situaţii în care expertul încearcă să clasifice unele

176
ipoteze conform informaţiilor disponibile. Cheile pentru un design eficient sunt consistenţa,
claritatea şi controlul.

Faza 4: Testarea
SE va trebui testat periodic şi evaluat pentru a se asigura faptul că performanţa acestuia
converge către scopurile stabilite. Este important ca aceste decizii să fie făcute timpuriu, la un
timp când scopurile originale au fost stabilite.
Stadiul 1: Testarea Preliminară
 Studierea bazei de cunoaştere completă
 Descoperirea deficienţelor în strategiile de raţionament
 Validarea reprezentării cunoştinţelor şi aproximaţia deducţiei
Stadiul 2: Testarea prin Demonstraţie
 Alegerea unei probleme cu interval limitat în capacităţile SE
 Folosirea demonstraţiei pentru a valida aproximarea sistemului expert
 Prezentarea caracteristicilor majore ale SE
 Designul interfeţei pentru a fi comod utilizatorului
Stadiul 3: Validarea Testării Informale
 Selectarea cazurilor testate anterior
 Evaluarea abilităţilor SE în rezolvarea cazurilor tipice şi
 Identificarea deficienţelor SE şi obţinerea comentariilor de la utilizator prin
interfaţă
Stadiul 4: Testarea Reevaluării
 Selectarea cazurilor neobişnuite din trecut
 Evaluarea capacităţii SE în rezolvarea cazurilor neobişnuite
 Descoperirea deficienţelor în controlul şi cunoaşterea SE
 Identificarea deficienţelor SE
Stadiul 5: Testarea Formală
 Selectarea cazurilor din trecut şi definirea criteriilor de test
 Rularea SE pentru fiecare caz de test şi întrebarea evaluatorilor despre
performanţa sistemului pentru fiecare caz de test
 Obţinerea comentariilor asupra interfeţei

177
 Identificarea punctelor forte şi a deficienţilor SE
Stadiul 6: Testarea în timp real
 Definirea criteriilor de test pentru testarea în câmp deschis
 Determinarea dacă SE îşi îndeplineşte scopurile când este aplicat problemelor real

Faza 5: Manualul de utilizare. Documentarea.


Acest document serveşte ca un jurnal personal al proiectului. El conţine tot materialul
colectat în timpul proiectului care trebuie să fie referinţă pentru dezvoltarea sistemului. Dacă este
proiectat corespunzător, va servi de asemenea sarcinilor finale ale întreţinerii SE şi scrierea
raportului final al SE.

Faza 6: Întreţinerea
După terminarea design-ului, implementării, testării şi documentării, SE va trebui
perfecţionat sau actualizat pentru a îndeplini cerinţele curente. Este foarte important pentru a
menţine o bună înregistrare a modificărilor care s-au produs la SE. Dacă acest lucru nu este
realizat, se poate pierde urma cunoştinţelor SE. Iar de fiecare dată când SE este modificat,
următoarele piese de informaţii trebuie documentate:
 Ce s-a modificat şi cine a realizat modificarea
 Când a fost realizată modificarea
 De ce a fost realizată modificarea
Sistemul expert menţine domeniul de cunoştinţe expert într-un modul cunoscut ca baza de
cunoştinţe. Acesta foloseşte tehnici şi reguli pentru a codifica cunoştinţele în baza de
cunoştinţe. O regulă este o structură de forma IF/THEN care interpretează logic informaţii
conţinute în partea IF cu Alte caracteristici ale sistemului expert complet sunt memoria
funcţionabilă şi motorul de decizie. Pentru motorul de decizie sunt folosite clase iar pentru
memoria funcţionabilă sunt folosiţi vectori.
SE are de asemenea facilitatea de explicare. Înseamnă că SE poate oferi o explicaţie
utilizatorului despre întrebările care i se adresează şi cum desprinde concluziile pe baza acestor
întrebări. Interacţiunea cu Utilizatorul se face de regulă prin intermediul unor ferestre-ecran
prietenoase cu ajutorul cărora se poartă un dialog utilizator – SE.
Iată exemplu de schemă de dialog SE-utilizator:

178
Figura 8.6. Schemă de dialog SE-utilizator

Sistemele Expert au fost folosite pentru a rezolva o gamă largă de probleme în domenii ca
medicina, matematica, ingineria, geologia, informatica, afaceri, drept, apărare şi educaţie. În
cazul fiecărui domeniu, ele au fost folosite pentru a rezolva diferite tipuri de probleme. Tipurile
de probleme includ diagnostice (ex., a unei erori de sistem, a unei molime sau a unei erori
studenţeşti); proiectare (a unui sistem computerizat, a unui hotel etc.); şi interpretare (de
exemplu, a datelor geologice). Tehnica potrivită de rezolvare tinde să depindă mai mult de tipul
problemei decât de domeniu.
În tabela 1 sunt prezentate avantajele intrinseci ale sistemelor care simulează
comportamentul intelligent şi avantaje datorate tehnologiei.

179
Tabela 1

A Avantaje intrinseci ale sistemelor care


simulează comportamentul inteligent

1. Îmbunătăţirea performanţelor -- completitudinii (toate faptele relevante sunt


experţilor (prin minimizarea erorilor descoperite )
umane) datorită: -- înţelegerii depline (toate faptele relevante
sunt analizate )
--consistenţei (cazurile identice conduc
întotdeauna la acelaşi rezultat)
2. Creşterea capacităţilor non- --dependenţele slabe de expertizele rare
experţilor (şi a productivităţii experţilor) --facilitarea activităţii experţilor în cazurile
simple
3. Întreţinerea şi extensia KB prin: --arhivarea calificărilor critice
-- combinarea cunoştinţelor din mai multe
surse interne
--duplicarea cunoştinţelor existente
-- cumpărarea expertizelor dovedite
--explicitarea cunoştinţelor existente
B Avantaje datorate tehnologiei
1. Sistem uşor de întreţinut
2. Sistem uşor de dezvoltat

Un sistem expert poate face greşeli, dar mai puţin decât ar face un om. Mai mult, el
funcţionează mereu consistent, niciodată devenind obosit sau plictisit. Alta diferenţă este că SE
poate fi folosit oriunde spre deosebire de oameni.
Utilizatorul îşi va putea clarifica problema de sincronizare cu SE cu răspuns imediat şi
poate primi diagnoze prin intermediul SE. Această caracteristică îl va asista să recunoască
cauzele care permit nesincronizarea SE. Ei vor putea solicita SE explicaţii la întrebările care li se
pun în timpul interacţiunii.
SE poate fi îmbunătăţit prin convertirea la o aplicaţie web. În loc să lucreze în modul, ar
putea fi accesat prin website care măresc locaţia de acces.
Sistemele expert hibride împreună cu sistemele expert fuzzy pot fi văzute ca noi tehnici ce
vor putea fi folosite de cercetători mai târziu. Implementarea unui sistem expert în mai multe
domenii este puternic influenţată de tehnicile şi metodele care adoptă hypertext şi hypermedia.
Caracteristici ale personalizării, modelarea utilizatorului şi abilitatea de adaptare la mediu vor

180
deveni noi provocări. Vor putea fi folosite ca un ghid în promovarea sistemelor expert în variate
funcţii.
Pe viitor, SE vor putea fi folosite împreună cu reţele neuronale artificiale, logica fuzzy,
algoritmi genetici şi alte metode ale Inteligenţei Artificiale. Aceste metode permit luarea în
considerare a avantajelor lor în sistemul proiectat şi, deci, noile sisteme proiectate sunt
instrumente mai puternice în facilitarea variatelor sarcini care necesită răspunsuri pe moment,
precise şi de încredere.
În dezvoltarea SE sunt folosite atât limbaje convenţionale cât şi tehnicile IA. Iată o
diagramă a procentelor de folosire a acestora în Marea Britanie în ultimul deceniu:

Figura 8.7.

181
8.3. Aplicaţii. Studii de caz.

8.3.1. Studiu de caz 1.

Baza de cunoştinţe arătată în Lista 1 este legată de o companie fictivă ”Compania_X”.


Sistemului expert i se cere să recomande un preţ adecvat pentru ofertant, determinat de
multiplicarea costului obligatoriu estimativ cerut de Compania_X pentru definitivarea
contractului, cu un procent adecvat de piaţă. Firma Compania_X a formulat o tactică pentru
obţinerea unui bun procentaj de piaţă, într-o mare varietate de situaţii de ofertare. Această tactică
ţine cont de natura contractului de muncă, de mărimea contractului şi relaţiile firmei cu
cumpărătorul menţionat în contract. Această situaţie particulară a fost aleasă deoarece, a crea
oferte este o activitate importantă pentru multe organizaţii şi de obicei implică o judecată atentă şi
bună, bazată pe o experienţă acumulată de la experţii răspândiţi în toată organizaţia. Se apreciază
importanţa acestui domeniu de lucru şi avantajele pe care un sistem expert le poate aduce.

LISTA 1

Studiul de caz 1 – BAZA DE CUNOŞTINŢE

cauta pret
if cost_estimat > 0
and mult este gasit
then pret_oferta=cost_estimat* factor_mult ;
pret este gasit

if valoare_indice este gasit


then factor_mult = 1 + indice/100.0 ;
mult este gasit

if indice_standard > 0
and factor_dimensiune >= 0
and factor_client >= 0
then indice = indice_standard – factor _dimensiune + factor_client;
valoare_indice este gasit

182
if tip_contract este ‘proiect_propriu’
and data_contract este fixată
then segment_piata este ‘proiect_propriu_datat’

if tip_contract este “proiect_propriu”


and data_contract este variabila
then segment_piata este ‘proiect_propriu_nedatat’

if tip_contract este ‘proiect_oferit’


then segment_piata este ‘stoc_pana-_la’

if segment_piata este ‘stoc_pana_la_specificari_date’


then standard_indice = 18

if segment_piata este ‘proiect_propriu_datat’


then indice_standard = 22

if segment_piata este ‘proiect_propriu_nedatat’


then indice_standard = 28

if segment_piata este ‘stoc_pana_la_specificari_date’


and cost_estimativ< 50000
then factor_marime = 0

if segment_piata este ‘stoc_pana_la_specificari_date’


and cost_estimativ > = 50000
and cost _estimativ < 200000
then factor_marime = 0.5

if segment_piata este ‘stoc_pana_la_specificari_date’


and cost_estimativ > = 200000
then factor_marime = 1.0

183
if tip_contract este ‘proiect_propriu’
and cost_estimativ < 75000
then factor_marime = 0

if tip_contract este ‘proiect_propriu’


and cost_estimativ > = 75000
and cost_estimativ < 250000
then factor_marime = 0.5

if tip_contract este ‘proiect_propriu’


and estimare_cost > = 250000
then factor_marime = 1.0

if relatia_cu_client este rea


then factor_client = 0

if relatia_cu_client este medie


then factor_client = 1

if relatia_cu_client este buna


then factor_client = 1.5

if numar_de_invitatii_la_licitatie > 4
and numar_de_licitatii_castigate = 0
then relatia_cu_client este rea

if numar_de_invitatii_la_licitatie > 0
and numar_de_licitatii_castigate > 0
and clientul este nemultumit
then relatia_cu_client este rea

184
if numar_de_invitatii_la_licitatie = 0
then relatia_cu_client este medie

if numar_de_invitatii_la_licitatie > 0
and numar_de_invitatii_la_licitatie < = 4
and numar_de_licitatii_castigate = 0
then relatia_cu_client este medie

if numar_de_invitatii_la_licitatie > 0
and numar_de_licitatii_castigate > 0
and clientul este multumit
then relatia_cu_client este medie

if numar_de_invitatii_la_licitatie > 0
and numar_de_licitatii_castigate > 0
and consumatorul este ‘pe_deplin_satisfăcut’
then relaţia_cu_client este bună.

Figura 2 Diagrama pentru “obiecte/variabile” în studiul de caz 1.

185
Diagrama pentru situaţia de ofertant al unui produs pe piaţă din baza de cunoştinţe pentru
demonstraţie este aratată în Figura 2. Următoarea etapă este crearea unei liste a tuturor obiectelor
sau variabilelor împreuna cu valorile permise pe care le pot primi. Această listă şi diagramă
formează o structurare importantă a cunoaşterii şi odată realizată, se dezvoltă uşor o serie de
reguli pentru baza de cunoştinţe. Desigur, e necesară o bogată experienţă pentru a aranja regulile
şi clauzele regulilor într-o ordine optimă, iar apoi, pe baza lor, să se poată scrie mai eficient
reguli. Regulile din Lista 1 sunt mai simple decât cele implicate în figura 2.

8.3.2. Studiul de caz 2 – Descriere.

Compania “Compania_Y” obţine cea mai mare parte din afacerile sale din licitaţii
competitive. Când “Compania_Y” primeşte o invitaţie de licitaţie pentru un contract din partea
unui client, este făcută o analiză preliminară a detaliilor contractului. Scopul acesteia este de a
identifica acele contracte care pot duce la întelegeri neprofitabile.
Analiza preliminară presupune o privire asupra factorilor de decizie cu privire la contract
şi apoi determină dacă firma trebuie să refuze invitaţia de licitaţie, sau să propună o licitaţie
competitivă.
Când a fost întrebat de natura exactă a analizei preliminare, directorul departamentului de
licitaţii a răspuns:
“ În primul rând, scopul analizei primare este de a determina cât de atractiv este contractul
dat companiei, cu privire la mărimea şi termenii acestuia. În general, compania refuză să propună
o licitaţie pentru acele contracte, care sunt considerate prea mici sau prea mari, aceasta
însemnând, acele contracte cu un cost de pornire mai mici decât 100,000$ sau, mai mare decât
1,5 milioane$. Oricum, existând condiţia ca firma să aibă un contract cu clientul, atunci trebuie
considerată o submisiune de licitaţie, aşa numitul ”contract cu valoare mică". Acestea sunt
contractele cu un cost de pornire de cel putin 50,000$, dar mai mic de 100,000$. Ideea este de a
se încerca stabilirea unei relaţii bune cu clienţii existenţi, dar nu mă întrebaţi dacă merge sau nu!
Recent am început să primim o mulţime de invitaţii la licitaţii pentru contracte de la
clienţi străini, iar în prezent invitaţiile din străinătate însumează 15% din toate invitaţiile primite.
Încă nu a fost adoptată o politică clară de selectare, dar în timp scurt am înfiinţat reprezentanţe în
diverse tări străine. Având reprezentant în ţara din care a venit invitaţia, atunci clienţii străini

186
sunt trataţii la fel ca cei din propria piaţă. Dacă nu este disponibil nici un reprezentant al
companiei, atunci declinăm invitaţia la licitaţie “.
Din informaţiile date de discursul directorului compartimentului de licitaţii, se proiectează
şi se construieşte un sistem expert, folosind Prolog apoi se recomandă companiei “Compania_Y”
cea mai potrivită decizie de luat, când se primeşte o invitaţie pentru licitaţie. Aceasta înseamnă că
sistemul expert face o recomandare firmei, cu privire la o ofertă competitivă sau declină invitaţia
la licitaţie.

Tabelul 2. Studiul de caz 2 - lista obiectelor


‘Obiecte’ / ’Variabile’ Valori permise
Scop / Ieşire 1. ofertă competitivă
decizia de oferta / licitaţie 2 . refuzarea ofertei
Intrări: - cost estimativ numeric>0
- locul clientului 1. acasă
(cumpărătorului) 2. strainătate
- reprezentanţa 1. disponibil
companiei 2. indisponibil
- contract existent 1. da
cu clientul 2. nu
Intermedieri - locul 1. Acceptabil
- contract 1. valoare mică
2. valoare mare

LISTA 2
Studiul de caz 2 - BAZA DE CUNOŞTINŢE

caută decizie-ofertă

if cost_estimativ < 50000


then decizie_oferta este “refuz_invitatia_la_licitatie”

if cost_estimativ > 1500000


then decizie_oferta este “refuz_invitatia_la_licitatie”

if locatia_clientului este strainatate


and reprezentanta _companiei nu este disponibila
then decizie_oferta este “refuz_invitatia_la_licitatie”

187
if cost_estimativ >= 100000
and cost_estimativ <= 1500000
then contractul este “de_valoare_înalta”

if cost_estimativ >= 50000


and cost_estimativ < 100000
then contractul este de “de_valoare_scazuta”

if contractul este “de_valoare_scazuta”


and locatia este acceptabilă
and exista_contract_cu_cumpărătorul este nu
then decizie_oferta este “refuz_invitatia_la_licitatie”

if locatia_clientului este în străinătate


and reprezentantul_companiei nu este valabil
then locatia este acceptabilă

if contractul este “de_valoare_scazuta”


and locatia este acceptabilă
and exista_contract_cu_cumpărătorul este da
then decizie_oferta este “oferta_competitivă”

if contractul este “de_valoare_inalta”


and locatia este acceptabilă
then decizie_oferta este “oferta_competitivă”

if locatia_clientului este acasă


then locatia este acceptabilă.

Bibliografie

1. Podaru, V., Inteligenţă artificială şi siteme expert, Editura Academiei Tehnice Militare, 1997
2. Podaru, V., Barnoschi, A., Sisteme expert, Editura Academiei Tehnice Militare, 2000, 2004.
3. Georgescu, I., Elemente de inteligenţă artificială, Editura Academiei RSR, 1985.

188
INTRODUCERE ÎN LIMBAJUL PROLOG
LECŢIA 1.
NOŢIUNI INTRODUCTIVE

Prolog este un limbaj de programare utilizat pentru rezolvarea problemelor care


implică existenţa obiectelor şi a relaţiilor dintre acestea. În acest capitol vom prezenta
principalele elemente ale limbajului fără însă a acorda atenţie detaliilor, regulilor formale şi
excepţiilor. Ne vom concentra atenţia asupra unor noţiuni de bază cum ar fi fapte, întrebări,
variabile, conjuncţii şi reguli. Ceea ce dorim este să ajungem cât mai repede în stadiul de a
scrie programe utile. Alte caracteristici ale limbajului Prolog, cum ar fi listele şi
recursivitatea, vor fi abordate în capitolele următoare.
Utilizăm limbajul Prolog pentru rezolvarea cu ajutorul calculatorului a problemelor
care pot fi exprimate în forma obiectelor şi a relaţiilor dintre acestea. De exemplu, atunci când
spunem Cartea este a lui Ion , declarăm faptul că există o relaţie, cea de proprietate, între un
obiect Ion şi un alt obiect individual carte . În plus, relaţia de mai sus este o relaţie de
ordine cartea este proprietatea lui Ion, dar Ion nu este proprietatea cărţii! Atunci când punem
întrebarea Cartea este a lui Ion , încercăm să ne informăm despre o anumită relaţie.
Un alt exemplu, regula Doi indivizi umani sunt surori, dacă ambii sunt de sex feminin
şi dacă au aceiaşi părinţi precizează înţelesul faptului de a fi surori. De asemenea, regula ne
arată şi cum aflăm dacă doi indivizi umani sunt surori nu trebuie decât să verificăm dacă
ambii sunt de sex feminin şi dacă au aceiaşi părinţi.
Ceea ce este de reţinut în privinţa regulilor este faptul că acestea sunt de obicei mult
simplificate, dar sunt acceptabile ca şi definiţii.
Programarea în limbajul Prolog constă în
 declararea unor fapte despre obiecte şi relaţiile dintre acestea;
 definirea unor reguli în legătură cu obiectele şi relaţiile dintre acestea; şi
 formularea de întrebări relative la obiecte şi la relaţiile dintre acestea.
De exemplu, să presupunem că am făcut cunoscută unui sistem Prolog regula de mai
sus cu privire la surori. Putem apoi să întrebăm dacă Maria şi Jana sunt surori. Prolog va
căuta prin baza de date ceea ce i-am spus despre Maria şi Jana, şi va furniza la ieşire
răspunsul yes (da) sau no (nu), în funcţie de datele pe care i le-am furnizat anterior. Prin
urmare, putem considera Prolog ca un depozitar de fapte şi reguli, pe care le foloseşte pentru a
răspunde la întrebări. Programarea în Prolog constă în precizarea tuturor acestor fapte şi
reguli. Sistemul Prolog transformă calculatorul în depozitar al acestor fapte şi reguli şi pune la
dispoziţie moduri de efectuare a inferenţelor logice.
Prolog este un limbaj conversaţional, ceea ce înseamnă că între calculator şi utilizator
poate avea loc un dialog. Faptele şi regulile relative la problema care se doreşte a fi rezolvată
sunt introduse în Prolog. Ulterior, prin formularea de întrebări corecte, Prolog va elabora şi
va afişa răspunsurile pe dispozitivul de afişare.
În continuare vom introduce, pe rând, fiecare dintre elementele fundamentale ale
Prolog-ului. Nu vom prezentata imediat fiecare din facilităţile Prolog in extenso. În capitolele
următoare vom găsi referinţe complete şi exemple.
1.1 Fapte

Mai întâi vom prezenta problematica faptelor şi legătura acestora cu obiectele şi


relaţiile dintre acestea. Să presupunem că dorim să comunicăm Prolog-ului faptul că Ion o
place pe Maria . Acest fapt se compune din două obiecte, denumite Ion şi Maria , şi o
relaţie denumită place . În limbajul Prolog faptele trebuie scrise într-o formă standard (de
obicei sub forma unui predicat), precum cea de mai jos

place(ion,maria).

Este important să reţinem următoarele aspecte


- Numele tuturor relaţiilor şi obiectelor trebuie să înceapă cu caractere minuscule. De
exemplu, place, ion, maria.
- Relaţia este cea scrisă mai întâi, obiectele fiind scrise între paranteze rotunde şi
separate prin virgulă.
- La sfârşitul fiecărui fapt trebuie să existe caracterul punct . .
Atunci când definim relaţii între obiecte prin intermediul faptelor, trebuie să acordăm
atenţie ordinii în care sunt scrise obiectele între parantezele rotunde. De fapt, odinea este
arbitrară, însă trebuie să decidem o anumită ordine pe care să o respectăm. De exemplu, în
faptul descris mai sus am plasat subiectul acţiunii de a place ( cel care place ) pe prima
poziţie, iar obiectul acţiunii de a place ( cel care este plăcut ) pe cea de a doua poziţie. Astfel,
faptul place(ion,maria) nu reprezintă acelaşi lucru ca şi faptul place(maria,ion).
Primul fapt afirmă că Ion o place pe Maria, iar al doilea afirmă că Maria îl place pe Ion, în
conformitate cu convenţia pe care am stabilit-o. Dacă dorim să exprimăm faptul că Maria îl
place pe Ion, atunci trebuie ca în mod explicit să scriem astfel

place(maria,ion).

Iată câteva exemple de fapte, împreună cu posibilele lor interpretări

valoros(aur). Aurul este preţios.


femeie(jana). Jana este femeie.
are(ion,aur). Ion are aur.
tata(ion,maria). Ion este tatăl Mariei.
da(ion,carte,maria). Ion dă cartea Mariei.

Ori de câte ori este folosit un nume, acesta se referă la un anumit obiect particular.
Este clar că numele ion şi maria se referă la indivizi umani. Dar am folosit în faptele de mai
sus şi numele aur şi valoros şi nu rezultă în mod necesar evident ce ar putea însemna. Acest
fel de nume este denumit de către logicieni non-count word (cuvânt non-număr). Atunci
când folosim un nume, trebuie să ne decidem asupra modului în care interpretăm numele.
Să discutăm câteva aspecte privitoare la terminologie. Numele obiectelor cuprinse
între paranteze rotunde în cadrul fiecărui fapt sunt denumite argumente. Numele relaţiei care
se află plasat înaintea perechii de paranteze rotunde se numeşte predicat. Astfel, valoros
este un predicat cu un singur argument, iar place este un predicat care are două argumente.
Numele obiectelor şi relaţiilor sunt complet arbitrare. În locul termenului
place(ion,maria) putem folosi la fel de bine şi cu acceaşi semnificaţie termenul
a(b,c), trebuind doar să ţinem minte că a înseamnă place, b înseamnă ion, iar c
înseamnă maria. Este recomandat să se folosească acele nume care să aibă semnificaţia a
ceea ce ele reprezintă.
Relaţiile pot avea un număr arbitrar de argumente. Spre exemplu, dacă definim un
predicat denumit joaca, în cadrul căruia sunt precizaţi doi jucători şi jocul pe care-l joacă,
vor fi necesare trei argumente. Iată două exemple de astfel de fapte
10
joaca(ion,maria,fotbal).
joaca(jana,jean,badminton).

Utilizarea mai multor argumente într-un predicat este importantă în reprezentarea


interacţiunilor complexe dintre relaţii.
Există posibilitatea de a declara fapte care nu sunt adevărate în lumea reală. Putem
scrie, de exemplu, rege(ion,romania), pentru a preciza faptul că Ion este regele
Romaniei. În lumea reală acest fapt este în mod evident fals, pentru că Romania este republică
constituţională deoarece monarhia a fost abolită în anul 1947. Prolog nu ştie şi nici nu-l
interesează acest lucru. În Prolog, faptele permit pur şi simplu exprimarea unor relaţii
arbitrare între obiecte.
În Prolog, o colecţie de fapte este denumită o bază de date. Se va folosi sintagma bază
de date ori de câte ori avem o colecţie de fapte (şi, mai târziu, reguli) care sunt folosite pentru
rezolvarea unei anumite probleme particulare.

1.2 Întrebări

Odată definite faptele, se pot formula întrebări asupra acestora. În Prolog, o întrebare
arată la fel ca şi un fapt, deosebirea constând în precedarea acestuia de către un simbol
special. Simbolul special este scris sub forma unui semn de întrebare şi a unei cratime(‘?-“).
Să considerăm întrebarea de mai jos

-are(maria,carte).

Dacă interpretăm argumentul maria ca desemnând o persoană pe nume Maria, şi


argumentul carte ca desemnând o anumită carte, prin această întrebare se doreşte a se afla
dacă Cartea este a Mariei sau Este un fapt acela că Maria are cartea Nu ne rezultă de
aici dacă toate cărţile sunt ale Mariei sau dacă ea are anumite cărţi .
Atunci când i se adresează o întrebare, Prolog caută în baza de date constituită
anterior. El caută fapte care să se potrivească cu faptul conţinut în întrebare. Două fapte se
potrivesc, dacă predicatele lor sunt identice (sunt scrise identic) şi dacă argumentele lor
corespunzătoare sunt aceleaşi. Dacă Prolog găseşte un fapt care se potriveşte cu întrebarea,
atunci va răspunde yes. Dacă în baza de date nu există un asemenea fapt, Prolog va răspunde
no. Răspunsul dat de Prolog va fi afişat pe ecranul terminalului, pe linia imediat următoare
celei pe care s-a scris întrebarea. Să considerăm următoarea bază de date

place(gogu,peste).
place(gogu,maria).
place(maria,carte).
place(ion,carte).

După ce s-a introdus toate aceste fapte în sistemul Prolog, se pot formula întrebări, iar
Prolog va da răspunsurile (arătate mai jos cu caractere aldine) pe linia imediat următoare
liniei pe care se află scrisă întrebarea)

- place(gogu,bani).
no
- place(maria,gogu).

11
no
- place(maria,carte).
yes
- rege(ion,romania).
no

Răspunsurile la primele trei întrebări sunt clare. Prolog a răspuns, de asemenea, no, şi
la întrebarea dacă Ion este regele Romaniei. Aceasta deoarece nu există nici un fapt relativ la
regalitate în cadrul bazei de date care conţine cele patru relaţii place. În Prolog, răspunsul
no este utilizat pentru a semnifica faptul că nimic nu se potriveşte cu întrebarea. Este
important de reţinut faptul că no nu reprezintă acelaşi lucru cu false.
Să considerăm un alt exemplu, cu o bază de date despre unii dintre cei mai faimoşi
filozofi greci ai antichităţii, bază care conţine următoarele trei fapte

om(socrate).
om(aristotel).
atenian(socrate).

Putem formula întrebări

- atenian(socrate).
yes
- atenian(aristotel).
no
- grec(socrate).
no

Deşi în istoria adevărată este adevărat faptul că Aristotel a trăit în Atena, nu se poate
dovedi acest lucru cu ajutorul faptelor care se găsesc în baza de date. Mai mult, deşi se
specifică în baza de date faptul că Socrate este atenian, aceasta nu dovedeşte că este grec,
deoarece nu există informaţii suplimentare în acest sens, în baza de date. Deci, atunci când
Prolog răspunde no la o întrebare, aceasta înseamnă că faptul respectiv nu poate fi dovedit.

1.3 Variabile

În Prolog nu numai că putem da nume unor anumite obiecte particulare, dar putem
folosi nume ca X, care să înlocuiască obiectele ce vor fi determinate de Prolog. Numele din
această a doua categorie sunt denumite variabile. Atunci când Prolog foloseşte o variabilă,
aceasta poate fi instanţiată sau neinstanţiată.
O variabilă este instanţiată atunci când există un obiect pe care variabila îl înlocuieşte.
O variabilă este neinstanţiată atunci când ceea ce este înlocuit de către variabilă este încă
necunoscut. Prolog face deosebire între variabile şi nume ale anumitor obiecte particulare prin
faptul că orice nume care începe cu majusculă este considerat variabilă.
Atunci când i se pune Prolog-ului o întrebare care conţine o variabilă, acesta caută
printre toate faptele un obiect ce ar putea fi înlocuit de către variabilă. Astfel, atunci când
întrebăm Îi place lui Ion obiectul X , Prolog caută printre toate faptele pentru a găsi lucrurile
care îi plac lui Ion.
O variabilă, spre exemplu X, nu desemnează un anume obiect în sine, dar poate fi
folosită pentru a înlocui obiecte pe care nu le putem numi. Prolog permite utilizarea

12
variabilelor, în felul următor

- place(ion,X).

Să considerăm următoarea bază de date cu fapte, urmată de o întrebare

place(ion,flori).
place(ion,maria).
place(paul,maria).

- place(ion,X).

Deci întrebarea are semnificaţia dacă Există ceva care să-i placă lui Ion Atunci când
îi este adresată această întrebare, Prolog va răspunde

X=flori

şi va aştepta instrucţiuni suplimentare, despre care vom vorbi imediat. Cum funcţionează
acest mecanism Atunci când Prolog-ului i se pune această întrebare, variabila X este iniţial
neinstanţiată. Prolog caută prin baza de date un fapt care să se potrivească cu întrebarea. Dacă
în conţinutul întrebării apare o variabilă neinstanţiată ca argument, atunci Prolog va permite
ca potrivirea acestui argument să se facă cu orice alt argument aflat în aceeaşi poziţie în
cadrul declaraţiei faptului. Ceea ce se întâmplă este aceea că Prolog caută orice fapt al cărui
predicat este place şi al cărui prim argument este ion. În acest caz cel de-al doilea argument
poate avea orice valoare, deoarece întrebarea a fost pusă având drept al doilea argument o
variabilă neinstanţiată. Atunci când este găsit un asemenea fapt, variabila X va fi instanţiată cu
cel de-al doilea argument, indiferent de valoarea acestuia. Prolog caută în baza de date în
ordinea în care aceasta a fost scrisă (de sus în jos, în pagină), primul găsit este faptul
place(ion,flori). Variabila X este instanţiată cu obiectul al cărui nume este flori.
Totodată, Prolog marchează locul în care a descoperit o potrivire în cadrul bazei de date, acest
marker fiind folosit atunci când se va efectua o revenire pe care o vom discuta mai târziu.
Odată ce Prolog găseşte un fapt care să se potrivească cu întrebarea, el afişează
variabilele şi obiectele cu care sunt instanţiate. În acest caz X a fost instanţiat cu flori. În
continuare Prolog aşteaptă instrucţiuni suplimentare. Dacă apăsăm tasta Enter, ceea ce
înseamnă că suntem satisfăcuţi cu un singur răspuns, atunci Prolog va opri procesul de
căutare. Dacă apăsăm tasta (urmată de apăsarea tastei Enter), atunci Prolog va relua
căutarea în baza de date după acelaşi principiu, pornind din locul în care a plasat markerul.
Atunci când Prolog începe căutarea dintr-un loc marcat şi nu de la începutul bazei de date,
spunem că Prolog încearcă să resatisfacă întrebarea.
Să presupunem că la primul răspuns al Prolog-ului (X=flori) i-am cerut (apăsând
tasta ) să continue. Aceasta înseamnă că dorim satisfacerea întrebării într-un alt mod (alt
răspuns) dorim să găsim un alt obiect care să fie înlocuit de X. Aceasta însemnă că Prolog
trebuie să „uite“ că variabila X înlocuieşte obiectul flori şi să reia căutarea având din nou
variabila X neinstanţiată. Deoarece căutăm o altă variantă de răspuns, căutarea este reluată din
locul în care este plasat markerul. Următorul fapt care se potriveşte cu întrebarea este
place(ion,maria). Variabila X este acum instanţiată cu valoarea maria, iar Prolog pune
markerul în dreptul faptului place(ion,maria). Prolog va afişa X=maria şi va aştepta
comenzile următoare. Dacă vom continua apăsând din nou tasta ”;”, Prolog va continua
căutarea. În acest exemplu nu mai sunt alte fapte care să afirme ce îi place lui Ion. Astfel,

13
Prolog va opri căutarea, permiţându-ne să formulăm şi alte întrebări sau să adăugăm noi fapte.
Ce se întâmplă dacă, date fiind faptele de mai sus, punem întrebarea:

?- place(X,maria).

Această întrebare înseamnă, Este un obiect care să o placă pe Maria? Deja ar fi


trebuit să fi văzut că obiectele, din exemplul dat, care o plac pe maria sunt ion şi paul. Din
nou, dacă dorim să vedem toate răspunsurile, vom apăsa tasta ” ; ” după care Prolog afişează
câte un răspuns:

?- place(X,maria). Întrebarea pe care o punem.


X=ion; primul răspuns. Tastăm ”;”.
X=paul; al doilea răspuns. Tastăm din nou ”;”.
no nu mai sunt răspunsuri.

1.4 Conjuncţii

Să presupunem că dorim să obţinem răspunsuri la întrebări referitoare la relaţii mai


complexe, cum ar fi, Se plac Ion şi Maria? O modalitate de a face acest lucru ar fi accea de a
întreba mai întâi dacă Ion o place pe Maria şi, dacă Prolog răspunde yes, atunci să întrebăm
şi dacă Maria îl place pe Ion. Astfel, această problemă constă din două scopuri pe care
sistemul Prolog trebuie să încerce să le satisfacă. Deoarece o astfel de combinaţie este
frecvent utilizată de către programatorii în limbajul Prolog, există o notaţie specială pentru
aceasta. Să presupunem că avem următoarea bază de date:

place(maria,mancare).
place(maria,vin).
place(ion,vin).
place(ion,maria).

Dorim să întrebăm dacă Ion şi Maria se plac. Pentru aceasta întrebăm O place Ion pe
Maria? şi Îl place Maria pe Ion?. Conjuncţia “şi” (and) exprimă ideea că suntem interesaţi de
conjuncţia dintre cele două scopuri - adică dorim satisfacerea ambelor, unul după altul. Putem
reprezenta acest lucru prin plasarea unei virgule ”,” între cele două scopuri (care va juca rolul
conjuncţiei “şi”):

?- place(ion,maria), place(maria,ion).

Virgula se citeşte ”şi” putând separa oricâte scopuri se doresc a fi satisfăcute, pentru a
răspunde la o întrebare. Atunci când i se transmite sistemului Prolog o secvenţă de scopuri
(separate prin virgule), acesta încearcă satisfacerea fiecăruia pe rând, prin căutarea unei
potriviri în baza de date. Pentru ca secvenţa să fie satisfăcută, toate scopurile ce o compun
trebuie să fie satisfăcute. Folosind lista de fapte anterioară, ce va afişa Prolog atunci când i se
pune întrebarea de mai sus? Răspunsul este no. Este un fapt care afirmă că Ion o place pe
Maria, deci primul scop este satisfăcut (true). Cu toate acestea cel de-al doilea scop nu
poate fi dovedit, deoarece nu există în lista de fapte nici unul de forma
place(maria,ion), care să afirme că Maria îl place pe Ion. Cum am dorit să aflăm dacă
cei doi se plac unul pe celălalt, răspunsul la întrebare este no.
Pentru a rezuma, ne putem imagina o conjuncţie de scopuri aranjate de la stânga la
14
dreapta, scopurile fiind separate prin virgule. Fiecare scop poate avea un vecin aflat la stânga
şi unul aflat la dreapta. Evident, scopul aflat la limita stângă a conjuncţiei nu mai are nici un
vecin în stânga sa, iar cel aflat la limita dreaptă a conjuncţiei nu mai are nici un vecin în
dreapta sa. Atunci când trece la rezolvarea unei conjuncţii de scopuri, Prolog încearcă
satisfacerea fiecărui scop în parte, de la stânga spre dreapta. Dacă un scop este satisfăcut,
Prolog lasă un marker în baza de date care este asociat scopului respectiv. Gândim aceasta ca
şi când am desena o săgeată de la scop până la locul din baza de date în care se află soluţia.
Mai departe, toate variabilele care anterior erau neinstanţiate, pot fi acum instanţiate. Aceasta
s-a produs la pasul 1 din succesiunea prezentată mai sus. Dacă o variabilă devine instanţiată,
atunci toate apariţiile variabilei în cadrul întrebării vor fi înlocuite cu acea valoare. Prolog
încearcă apoi să satisfacă scopul care este vecinul din dreapta al scopului pe care tocmai l-a
satisfăcut, efectuând căutarea de la începutul bazei de date.
Pe măsura satisfacerii scopurilor, pentru fiecare scop satisfăcut rămâne câte un marker
în cadrul bazei de date (o săgeată de la scop până la faptul care se potriveşte), în cazul în care
scopul va trebui resatisfăcut ulterior. Ori de câte ori un scop nu poate fi satisfăcut (nu se poate
găsi un fapt care să se potrivească întrebării), Prolog se întoarce şi încearcă resatisfacerea
vecinului din stânga, începând căutarea de la markerul acestuia. Mai mult, Prolog trebuie să
dezinstanţieze toate variabilele care au fost instanţiate în cadrul scopului respectiv. Cu alte
cuvinte, Prolog trebuie să ”şteargă” conţinutul tuturor variabilelor, atunci când resatisface un
scop. Dacă fiecare scop începând din dreapta, nu mai poate fi resatisfăcut, atunci eşuările se
propagă spre stânga, pe măsură ce scopurile nu pot fi satisfăcute. Dacă şi primul scop (cel mai
din stânga) eşuează, acesta nu mai are un alt vecin, la stânga sa, pe care să încerce să-l
resatisfacă. În acest caz întreaga conjuncţie de scopuri eşuează (nu poate fi satisfăcută). Acest
mod de lucru, în care Prolog încearcă să satisfacă şi să resatisfacă scopurile din compunerea
unor conjuncţii, se numeşte backtracking. Acesta este prezentat sumar în capitolul următor, şi
este tratat pe larg în capitolul 4.
O regulă este o afirmaţie cu caracter general despre obiecte şi despre relaţiile dintre
acestea. De exemplu, putem spune că Nicu este pasăre, dacă Nicu este animal şi dacă Nicu
are pene chiar dacă în lumea reală o astfel de afirmaţie nu-şi are sens. Astfel, putem face ca o
variabilă să înlocuiască un obiect diferit, la fiecare utilizare diferită a regulii. În cadrul unei
singure utilizări a unei reguli, desigur, variabilele sunt interpretate în mod consistent.
Să considerăm un alt exemplu, cu o regulă care utilizează o variabilă şi o conjuncţie.

Lui Ion îi place X, dacă lui X îi place vinul.


În Prolog, o regulă se compune din antet şi corp. Antetul şi corpul sunt legate prin
simbolul ":-", format dintr-un caracter două puncte şi un caracter cratimă. Simbolul ":-"
este citit dacă. Exemplul de mai sus este scris în Prolog astfel:
place(ion,X):- place(X,vin).
Observăm că şi pentru reguli scrierea se încheie cu punct. Antetul acestei reguli este
place(ion,X). Antetul regulii descrie faptul care se intenţionează a se defini. Corpul, în
acest caz place(X,vin), descrie conjuncţia de scopuri care trebuie satisfăcute, unul după
altul, pentru ca faptul definit de antet să fie adevărat. Ori de câte ori o variabilă X devine
instanţiată cu un anumit obiect, toate apariţiile variabilei X sunt instanţiate cu acelaşi obiect pe
întrega întindere a domeniului de vizibilitate şi valabilitate al variabilei X. Pentru o anumită
utilizare a unei reguli, domeniul de vizibilitate şi valabilitate al variabilei X este întreaga
regulă, inclusiv antetul, inclusiv punctul ”.”, de la sfârşitul regulii. Astfel, în regula de mai
sus, dacă se întâmplă ca X să fie instanţiată cu valoarea maria, atunci Prolog va încerca să
satisfacă scopurile femeie(maria) şi place(maria,vin).
15
LECTIA 2.
ELEMENTELE DE BAZĂ PROLOG
Prolog asigură moduri de structurare a datelor cât şi moduri de a structura ordinea în
care se încearcă satisfacerea scopurilor. Structurarea datelor implică cunoaşterea sintaxei cu
ajutorul căreia se pot deduce datele. Structurarea ordinii în care se rezolvă scopurile implică
cunoştinţe despre backtracking. În acest capitol vom trata mai pe larg componentele din
Prolog introduse în capitolul anterior.

1.5 Sintaxa

Sintaxa unui limbaj descrie regulile de scriere a instrucţiunilor. Programele Prolog


sunt constituite din termeni. Un termen poate fi o constantă, o variabilă, sau o structură.
Fiecare termen este scris ca o secvenţă de caractere. Caracterele sunt împărţite în patru
categorii după cum urmează:

A B C D E F G H I J K L N O P Q R S T U V W X Y Z
a b c d e f g h i j k l n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9
+ - * / \ ” ^ < > : . , ? @ ă $ &

Pimul rând constă în literele mari. Al doilea rând conţine literele mici. Al treilea rând
conţine cifrele, iar al patrulea semnele speciale. De fapt sunt mai multe caractere semn decât
cele din rândul patru, dar ele au întrebuinţare specială care va fi discutată mai jos. Fiecare
termen, fie că este o constantă, fie o variabilă sau structură, are reguli specifice de formare a
numelui lor din caractere. Vom descrie mai departe fiecare categorie de termeni.

1.5.1 Constante

Constantele definesc obiecte sau relaţii specifice. Sunt două tipuri de constante: atomi
şi întregi. Exemple de atomi sunt numele pe care le-am dat în capitolul anterior:

place maria ion carte vin are bijuterii poate_fura

Simbolurile speciale pe care le foloseşte Prolog-ul pentru a arăta interogarea “?-” şi


regulile “:-” sunt de asemenea atomi. Sunt două tipuri de atomi: cei constituiţi din litere şi
cifre şi cei formaţi din semne. Primul tip trebuie să înceapă în mod normal cu o literă mică,
aşa cum am văzut în capitolul anterior. Acei atomi care sunt formaţi din semne vor conţine
numai semne. Unii atomi încep cu o literă mare sau o cifră (situaţie în care sunt consideraţi
atomi numere). Dacă un atom este închis între ghilimele simple “ ‘ “, atunci atomul poate
conţine orice caracter în numele său. În sfârşit caracterul subliniere “_” poate fi inserat în
mijlocul unui atom pentru a creşte lizibilitatea. În continuare câteva exemple de atomi:

loc = ‘george-iancu’ george_iancu ieh2304

Următoarele nu sunt exemple de atomi:

2304ieh george-iancu Loc _alfa

Întregii, altă categorie de constante, sunt folosite pentru a reprezenta numere, astfel
16
încât să poată fi rezolvate operaţiile aritmetice. Întregii sunt numere compuse numai din cifre
şi care nu conţin punctul zecimal, de exemplu:

0 1 999 512 8192 14765 6224

Prolog este disponibil pe diverse tipuri de calculatoare astfel că în funcţie de calculator


apar limitări în ceea ce priveşte mărimea şi semnul întregilor. În această carte se vor folosi
numai numere întregi cuprinse între 0 şi 65535 care lucrează sub orice tip de Prolog deoarece
Prolog-ul nu necesită în general calcule care să folosească întregi mari, fracţii sau numere
negative. Totuşi, Prolog fiind un limbaj extensibil, programatorii pot adăuga fără prea mari
dificultăţi, asemenea facilităţi. De exemplu, anumite sisteme Prolog oferă biblioteci de
programe care definesc operaţii cu numere raţionale şi numere cu o precizie arbitrară.

1.5.2 Variabile

Al doilea tip de termeni folosit în Prolog este variabila. Variabilele sunt asemănătoare
atomilor, cu excepţia faptului că numele lor începe cu literă mare sau cu semnul cratimă “_”.
O variabilă se foloseşte ca un suport pentru un obiect pe care nu îl putem încă nominaliza. În
exemplele pe care le-am dat am folosit variabile cu nume ca X, Y şi Z. Numele variabilelor pot
fi de lungime arbitrară:

Raspuns Input Plata_Proasta Soareci_orbi

Câteodată se simte nevoia folosirii unei variabile, fără a ne interesa numele ei. De
exemplu, dacă vrem să căutăm pe cineva care-l place pe Ion dar nu vrem să ştim cine este,
putem folosi “variabile anonime”. Variabila anonimă se scrie ca un singur caracter “ _ ”.
Exemplul nostru este scris în Prolog ca:

?-place(_,ion).

1.5.3 Structuri

Al treilea tip de termeni folosit în scrierea programelor Prolog este structura. O


structură este un obiect singular care constă dintr-o colecţie de alte obiecte, numite
componente. Componentele sunt grupate împreună într-o singură structură pentru uşurinţa
manipulării lor. Structurile sunt numite uneori “termeni compuşi” sau “termeni complecşi”.
Din aceste două posibilităţi preferăm numele “termen compus”.
Un exemplu de structură din viaţa reală este o fişa-index pentru o carte din bibliotecă.
Fişa-index conţine câteva componente: numele autorului, titlul cărţii, data publicării, cota
cărţii şi altele. Unele componente pot fi descompuse în alte componente. De exemplu, numele
autorului constă din câteva iniţiale şi numele de familie.
Structurile ajută la organizarea datelor în program deoarece ele permit tratarea unui
grup de informaţii înrudite ca un singur obiect (o fişă de bibliotecă) şi nu ca entităţi separate.
Modul de descompunere a datelor în componente depinde de tipul de problemă pe care-l
rezolvăm.
Structurile sunt de asemeni folositoare când există un număr mare de obiecte de
acelaşi tip, cărţi, de exemplu.
O structură este scrisă în Prolog prin specificarea functorului şi componentelor sale.
Functorul denumeşte tipul general de structură şi corespunde unui tip de dată din limbajele de
programare obişnuite. Componentele sunt închise între paranteze şi sunt despărţite de virgule.

17
Să considerăm următorul fapt, acela că Ion deţine o carte numită Duminica orbului, de Cezar
Petrescu:

are(ion,carte(duminica_orbului,petrescu)).

În interior, faptul are o structură cu numele carte, care are două componente, un titlu şi
un autor. Deoarece structura carte apare în interiorul faptului ca unul din argumentele sale, se
comportă ca un obiect, luând parte la relaţie. Putem avea o altă structură pentru numele
autorului dacă dorim să distingem între doi autori cu numele Petrescu (Camil şi Cezar) ca în
exemplul:

are(ion,carte(duminica_orbului,autor(cezar,petrescu)))

Structurile pot participa, folosind variabilele, în procesul de interogare-răspuns al


Prolog-ului. De exemplu putem întreba dacă Ion deţine vreo carte de unul din autorii
Petrescu:

?-are(ion,carte(X,autor(Y,petrescu))).

Dacă este adevărat, X va fi instanţiat la titlul găsit şi Y la prenumele autorului. Sau, putem
folosi variabile anonime:

?-are(ion,carte(_,autor(_,petrescu))).

Să reţinem că variabilele anonime nu partajează una cu cealaltă.


Sintaxa structurii este asemănătoare cu cea a faptului. Un predicat (folosit în fapte şi
reguli) este functorul structurii. Programele Prolog sunt constituite din constante, variabile şi
structuri.

1.6 Caractere
Numele constantelor şi variabilelor sunt construite din şiruri de caractere. Deşi fiecare
tip de nume (atom, întreg, variabilă) are reguli specifice de construcţie, este bine de ştiut care
sunt caracterele recunoscute de Prolog. Prolog recunoaşte două tipuri de caractere: tipăribile şi
netipăribile. Caracterele tipăribile se exteriorizează prin semne care apar pe display.
Caracterele netipăribile determină execuţia unei acţiuni fără a fi reprezentabile pe ecran.
Tipuri de acţiuni obişnuite sunt: spaţiul, începutul unei noi linii de text şi poate chiar un
semnal sonor. Iată toate caracterele tipăribile care pot fi folosite

A B C D E F G H I J K L N O P Q R S T U V W X Y Z
a b c d e f g h i j k l n o p q r s t u v w x y z
0 1 2 3 4 5 6 7 8 9
! “ ă $ % & ` ( ) = - ” ^ | \ { } ş ţ
_ ‘ @ + ; * : < >,. ? /

Evident un set mai complet decât cel dat la începutul capitolului. Unele caractere au înţelesuri
speciale. De exemplu, parantezele rotunde sunt folosite pentru a exprima componentele unei
structuri. Caracterele pot fi tipărite, citite de la tastatură, comparate, şi pot lua parte la operaţii
aritmetice.
Caracterele sunt tratate ca întregi mici între 0 şi 127. Fiecare caracter are un întreg
asociat, numit codul ASCII. Termenul “ASCII” înseamnă “American Standard Code for
18
Information Interchange”, şi este codul pe care îl folosesc multe calculatoare şi limbaje de
calculatoare. O tabelă cu codurile ASCII poate fi găsită în diverse manuale de calculatoare.
Literele sunt aşezate în ordine alfabetică, astfel că a compara ordinea alfabetică înseamnă a
compara codurile ASCII folosind operatorii relaţionali ce vor fi descrişi în acest capitol.
Caracterele tipăribile au codul ASCII mai mare decât 32.

1.7 Operatori

Câteodată este convenabil să se scrie anumiţi functori ca operatori în acest caz


anumite structuri sunt mai uşor de citit. Operaţiile aritmetice sunt scrise în mod obişnuit ca
operatori, spre exemplu, în expresia aritmetică “x+y*z”, “semnul plus, +” şi semnul de
“multiplicare, *” sunt operatori. Atunci expresia aritmetică “x+y*z” va arăta scrisă ca o
structură astfel: +(x,*(y,z)), şi va fi un termen Prolog legal. Este important de subliniat
că operatorii nu “determină” ca o operaţie aritmetică să se execute. Astfel în Prolog, 3+4 nu
înseamnă acelaşi lucru ca valoarea 7. Termenul 3+4 este o altă cale de a scrie termenul
+(3,4), care este o dată de tip structură. Vom vedea mai târziu o cale în care structurile pot
fi interpretate ca şi cum ar reprezenta expresii aritmetice, şi pot fi evaluate în concordanţă cu
regulile aritmetice.
Pentru a interpreta expresiile aritmetice care conţin operatori trebuie să se ştie despre
fiecare operator următoarele: poziţia, precedenţa şi asociativitatea sa. Deşi pot fi construite
diverse tipuri de operatori vom trata doar atomii care definesc operaţiile arirmetice +, -, *
şi /.
Sintaxa termenilor care conţin operatori depinde în parte de poziţia operatorilor.
Operatorii cum ar fi plus (+), liniuţă (-), asterix (*) şi slash (/) sunt scrişi între argumentele
lor şi se vor numi operatori infix. Operatorii se pot pune şi înaintea argumentelor ca în “-
x+y”, unde minus din faţa lui x este folosit în aritmetică pentru a arăta opusul lui x.
Operatorii care sunt aşezaţi înaintea argumentelor lor se numesc operatori prefix. Unii
operatori pot fi aşezaţi şi după argumentele lor, de exemplu, operatorul factorial (“x!”).
Operatorii care sunt scrişi după argumentele lor se numesc operatori postfix. Deci poziţia unui
operator ne arată unde va fi scris operatorul în relaţie cu argumentele sale.
Precedenţa unui operator este folosită pentru a indica care operaţie va fi executată
prima. Fiecare operator folosit în Prolog are o clasă de precedenţă asociată care este un întreg
asociat operatorului. Valoarea exactă a întregului depinde de versiunea de Prolog folosită. Un
operator cu o precedenţă mai mare are o clasă de precedenţă mai apropiată de 1. În Prolog
operatorii de multiplicare şi împărţire au o precedenţă mai mare decât adunarea şi scăderea,
astfel că termenul a-b/c este la fel ca termenul -(a,/(b,c)). Asocierea exactă a
operatorilor la clasele de precedenţă nu este importantă dar este important de reţinut ordinea
relativă în care se execută operaţiile.
Să reţinem că, nici o operaţie aritmetică nu este executată până nu este comandată de
predicatul “is” descris în secţiunea 2.5.

1.8 Egalitate şi potrivire

Un predicat important este egalitatea, care este un operator infix scris astfel: “=“.
Când se încearcă satisfacerea scopului

?- X = Y.

(pronunţat “X egal cu Y”), Prolog încearcă să potrivească X şi Y, şi scopul reuşeşte dacă se

19
potrivesc. Se poate judeca această acţiune ca o încercare de a face pe X şi Y egali. Predicatul
egalitate este predefinit, este deja definit în sistemul Prolog şi lucrează ca şi cum ar fi definit
de următorul fapt:

X = X.

Fiind dat un scop de forma X = Y, unde X şi Y sunt orice doi termeni care pot conţine
variabile neinstanţiate, regulile după care se decide când X şi Y sunt egali sunt următoarele:
 dacă X este o variabilă neinstanţiată şi dacă Y este instanţiat cu orice termen, atunci
X şi Y sunt egali. De asemenea X va deveni instanţiat cu valoarea lui Y.

 întregii şi atomii sunt întotdeauna egali cu ei înşişi. De exemplu, următoarele


scopuri au comportarea arătată:

politai = politai reuşeşte


hartie = creion nu reuşeşte
1066= 1066 reuşeşte
1206 =1583 nu reuşeşte

 două structuri sunt egale dacă au acelaşi functor şi acelaşi număr de componente, şi
toate componentele corespondente sunt egale. De exemplu, următorul scop reuşeşte, şi face ca
X să fie instanţiat cu bicicleta:

merge(preot,bicicleta) = merge(preot,X)

Structurile pot fi “încuibărite” una în cealaltă pe orice nivel. Dacă asemenea structuri
sunt testate pentru egalitate, testul va dura ceva mai mult deoarece sunt mai multe structuri de
testat. Următorul scop

a(b,C,d(e,F,g(h,i,J))) = a(B,c,d(E,f,g(H,i,j)))

va reuşi şi va determina ca B să fie instanţiat cu b, C cu c, E cu e, F cu f, H cu h, şi J cu j.


Un scop X=Y va reuşi întotdeauna chiar dacă unul dintre argumente este neinstanţiat.
Un mod mai uşor de a scrie o asemenea regulă este de a folosi faptul că o variabilă este egală
cu ea însăşi, rezultând:

egal(X,X).

Prolog asigură de asemenea un predicat “\=“, care se citeşte “nu este egal”. Scopul
X\=Y reuşeşte dacă X=Y nu reuşeşte, şi nu reuşeşte dacă X=Y reuşeşte. Astfel, X\=Y
înseamnă X nu poate fi făcut egal cu Y.

1.9 Aritmetica limbajului.

În această secţiune vom vedea modalitatea în care Prolog abordează operaţiile


aritmetice
Compararea numerelor. Prolog oferă câteva predicate predefinite pentru compararea
numerelor. Argumentele pot fi variabile instanţiate cu întregi, sau pot fi întregi scrise ca şi
constante. Iată lista predicatelor folosite pentru compararea numerelor. Reţinem că putem să
le scriem ca operatori infix:
20
X=Y x şi y sunt egale
X\=Y x şi y sunt diferite
X<Y x este mai mic ca y
X>Y x este mai mare ca y
X=<Y x este mai mic sau egal cu y
X>=Y x este mai mare sau egal cu y

Simbolul “mai mic sau egal cu” nu este scris ca <= ca în alte limbaje de programare.
Aceasta deoarece Prolog poate folosi în alte scopuri atomul <= (care arată ca o săgeată).
Deoarece aceşti operatori de comparaţie sunt predicate, se poate scrie următorul fapt
Prolog, 2>3, pentru a afirma că 2 este de fapt mai mare ca 3. Un asemenea fapt este legal în
Prolog, din punct de vedere sintactic. Totuşi, Prolog nu permite adăugarea de fapte la
predicatele care sunt predefinite. Asta previne schimbarea într-un mod neaşteptat a sensului
predicatelor predefinite. În capitolul 6 se vor descrie toate predicatele predefinite, inclusiv
cele întâlnite deja.
Operatorul “is” este un operator nou şi este de tip infix. Argumentul din dreapta este
un termen care este interpretat ca o expresie aritmetică. Pentru a satisface un “is”, Prolog-ul
evaluează prima dată argumentul din dreapta în concordanţă cu regulile aritmetice şi această
valoare este atribuită argumentului din stânga. În exemplu de mai sus, Y este necunoscut când
se întâlneşte “is” şi trebuie ca “is” să evalueze expresia şi să atribuie valoarea expresiei lui
Y . Aceasta presupune că valorile tuturor variabilelor din dreapta lui “is” trebuie să fie
cunoscute.
Predicatul “is” trebuie folosit întotdeauna când este necesar să se evalueze o expresie
aritmetică. Reţinem că ceva ca P/A este doar o structură Prolog obişnuită ca şi
autor(cezar,petrescu), spre exemplu. Dacă însă interpretăm o structură ca o expresie
aritmetică, există atunci o operaţie specială care poate fi aplicată la această structură numită
evaluarea expresiei aritmetice şi anume, aceea de a executa operaţiile aritmetice şi de a
calcula rezultatul. Nu toate structurile pot fi evaluate ca expresii aritmetice. Este clar că putem
evalua structuri care au definite operaţii aritmetice.
În funcţie de tipul de calculator folosit se pot folosi diverşi operatori în partea dreaptă
a lui “is”. Toate sistemele Prolog vor avea totuşi următorii operatori:

X + Y suma lui x şi y
X - Y diferenţa lui x şi y
X * Y produsul lui x şi y
X / Y câtul împărţirii întregi a lui x la y
X mod Y restul împărţirii întregi a lui x la y

Această listă împreună cu lista operatorilor de comparare ar trebui să fie un minim de


operatori pentru rezolvarea problemelor aritmetice simple. Desigur, Prolog a fost proiectat în
special spre probleme nenumerice aşa că facilităţile aritmetice nu sunt la fel de importante ca
la celelalte limbaje de programare.

1.10 Concluzii referitoare la satisfacerea scopurilor

Prologul execută o acţiune ca răspuns la o întrebare a programatorului. O întrebare


furnizează o conjuncţie de scopuri pentru a fi satisfăcute. Prolog utilizează clauzele cunoscute
pentru a satisface scopurile. Un fapt poate determina ca un scop să fie satisfăcut imediat, pe
21
când o regulă poate reduce sarcina la aceea de a satisface o conjuncţie de subscopuri. Totuşi,
o clauză poate fi folosită numai dacă ea se potriveşte scopului luat în calcul. Dacă un scop nu
poate fi satisfăcut, se va iniţia backtracking-ul. Backtracking-ul constă în revizuirea a ceea ce
s-a executat şi încercarea de resatisfacere a scopului prin găsirea unui drum alternativ de
satisfacere. Dacă răspunsul la o întrebare nu este satsfăcător atunci se poate iniţia
backtracking-ul tastând “;”.
În paragraful care urmează, se face o prezentare folosind diagrame pentru a arăta cum
şi când Prolog încearcă să satisfacă şi să resatisfacă scopurile.

1.10.1 Satisfacerea unei conjuncţii de scopuri

Prolog încearcă să satisfacă scopurile dintr-o conjuncţie după modul în care apar în
corpul regulii sau al întrebării, în ordinea în care sunt scrise (de la stânga la dreapta). Aceasta
înseamnă că Prolog nu va încerca să satisfacă un scop până când vecinul din stânga nu a fost
satisfăcut. Când va fi satisfăcut se va încerca satisfacerea vecinului său din dreapta. Să
considerăm următorul program care se referă la relaţiile de familie:

femeie(maria).
parinti(C,M,T):-mama(C,M),tata(C,T).
mama(ion,ana).
mama(maria,ana).
tata(maria,stefan).
tata(ion,stefan).

Predicatul parinti(C,M,T) înseamnă că părinţii copilului C sunt M-mama şi


T-tata şi de asemenea predicatele mama(C,M) şi tata(C,T) înseamnă că M este mama
copilului C şi T este tatăl copilului C. Dacă se pune întrebarea:

?-femeie(maria),parinte(maria,M,T),
parinte(ion,M,T).

este interesant să urmărim secvenţa de evenimente care ne conduce la răspunsul pentru


această întrebare (care în viaţa reală caută să ne asigure când maria este o soră a lui ion).
Pentru a face aceasta Prolog caută să satisfacă secvenţa de subscopuri arătate în figura 2.1., în
care scopurile sunt reprezentate ca nişte dreptunghiuri aşezate unele sub altele.

Figura 2.1 O secvenţă de subscopuri încă nesatisfăcute.

Săgeata indică scopurile care au fost deja satisfăcute şi anume dreptunghiul din care pleacă
săgeata indică scopul care este satisfăcut iar dreptunghiurile care sunt sub vârful săgeţii nu au

22
fost luate încă în considerare. Numim aceasta o diagramă de satisfacere.
În exemplul de mai înainte săgeata pleacă de sus şi trece mai jos la cele trei căsuţe pe
măsură ce cele trei scopuri sunt satisfăcute. Astfel încât situaţia finală va fi cea arătată în
figura 2.2.

Figura 2.2 Secvenţa de subscopuri a fost satisfăcută.

Să observăm că în această diagramă variabilele M şi T au fost iniţializate cu valorile


date de secvenţa de program.

1.10.2 Potriviri

Regulile după care se decide dacă un scop se potriveşte cu o clauză sunt prezentate în
continuare. Observăm că într-o clauză iniţial toate variabilele sunt neiniţializate.
 O variabilă neiniţializată se va potrivi cu orice obiect. Ca rezultat, acel obiect va
fi cel căutat de către variabilă.
 Un număr întreg sau un atom se vor potrivi numai cu ei înşişi.
 O structură se va potrivi cu o altă structură dacă au acelaşi functor şi număr de
argumente şi toate argumentele corespondente se potrivesc.
Un caz remarcabil în procesul de potrivire este acela în care două variabile
neiniţializate se potrivesc una cu alta. În acest caz spunem că aceste variabile sunt legate.
Două variabile legate sunt cele care, în cazul în care una este iniţializată şi cealaltă va fi
iniţializată cu aceeaşi valoare. Să observăm o similitudine între potriviri şi egalizarea
argumentelor (secţiunea 2.4). Aceasta deoarece predicatul “=“ încearcă să-şi egalizeze
argumentele prin potrivire.

23
LECŢIA 3.
UTILIZAREA STRUCTURILOR DE DATE
Recursivitatea este o tehnică foarte populară şi puternică în lumea programării. Poate
fi folosită pentru a descrie programe care au nevoie să satisfacă o copie proprie înainte de a se
încheia cu succes ele însele. Poate fi folosită de asemenea pentru a descrie structuri care au
alte structuri ca şi componente. În Prolog, recursivitatea este calea naturală şi normală de
vizualizare a structurilor de date şi a programelor.
1.11 Structuri şi arbori
De obicei este mai uşor de înţeles forma unei structuri complicate dacă o descriem pe
aceasta ca pe un arbore, în care fiecare functor este un nod, iar componentele sunt ramificaţii.
Fiecare ramificaţie poate pointa către o altă structură, astfel încât putem avea structuri în
interiorul altor structuri. De regulă descriem o diagramă-arbore având rădăcina în vârf, iar
ramificaţiile către bază. De exemplu, structura parinti(mihai,elena,carol_2) este
descrisă astfel:

Structura a+b*c sau (a,*(b,c)) este descrisă ca:

Structura carte(delirul,autor(marin,preda)) este descrisă ca:

Să observăm că ultimele două structuri au arbori de aceeaşi mărime şi topologie, cu


toate că rădăcinile şi frunzele lor sunt diferite.
24
Să presupunem că se dă propoziţia “Ion place Maria” şi este nevoie să reprezentăm
sintaxa acesteia. Cea mai simplă sintaxă constă în aceea că o propoziţie constă dintr-un
substantiv urmat de un verb. Putem reprezenta structura oricărei astfel de propoziţii printr-o
structură de forma:

propozitie(substantiv(X),
verb_compus(verb(Y),substantiv(Z))).

care are un arbore de forma:

Dacă reluăm propoziţia (“Ion place Maria”), şi instanţiem variabilele din structură
folosind cuvintele din propoziţie, obţinem:

Aceasta arată modul cum se pot folosi structurile şi variabilele Prolog pentru a
reprezenta sintaxa unei clase de propoziţii simple. În general dacă se cunosc cuvintele dintr-o
propoziţie, este posibil să se scrie o structură Prolog care descrie explicit relaţiile dintre
cuvintele din propoziţie.

1.12 Liste

Lista este o structură de date foarte utilizată în programare. Lista este o secvenţă
ordonată de elemente care pot o lungime variabilă. Elementele unei liste pot fi orice termeni
(constante, variabile, structuri) care desigur pot include alte liste. Aceste proprietăţi sunt
folositoare atunci când nu se poate prevedea cât de mare trebuie să fie o listă şi ce informaţii
trebuie să conţină. Mai mult, listele pot reprezenta practic orice fel de structură folosită în
25
calculul simbolic. Listele sunt larg folosite pentru a reprezenta arbori de analiză gramaticală,
gramatici, hărţi ale oraşelor, programe de calculator şi entităţi matematice cum ar fi grafice,
formule şi funcţii. În limbajul de programare LISP, singurele structuri de date disponibile sunt
constantele şi listele. În Prolog, lista este o structură particulară de date.
Listele pot fi reprezentate sub forma unui arbore special. O listă este fie vidă, neavând
nici un element, fie este o structură care are două componente: cap şi coadă. Sfârşitul unei
liste este de obicei reprezentat ca o coadă care este ataşată listei vide. Lista vidă este scrisă
sub forma []. Capul şi coada unei liste sunt componente ale functorului denumit “.”(care
este punctul). Astfel, lista care conţine un singur element “a” este reprezentată sub forma
“.(a,[])” iar arborele său asociat are forma următoare:

De asemenea, lista care conţine elementele atomice a,b,c este scrisă sub
forma(a,.(b,.(c,[]))), iar arborele asociat arată astfel:

Unii optează pentru reprezentarea diagramei arborescente a unei liste având arborele
de la stânga la dreapta şi cu ramurile în jos numită şi diagramă “vine”. Lista de mai sus are
următoarea reprezentare printr-o diagramă “vine”:

În această diagramă componenta cap a functorului punct este orientată către în jos iar
componenta coadă este orientată către dreapta. Sfârşitul listei este marcat clar pentru ultima
componentă coadă care reprezintă de fapt lista vidă. Principalul avantaj al celei de a doua
diagrame, în reprezentarea listelor, este acela că listele pot fi scrise de la stânga la dreapta.
Diagrama “vine” poate fi utilizată pentru scrierea listelor atunci când se doreşte să
vedem structura listei, dar asemenea diagrame nu sunt utilizate pentru scrierea listelor în
cadrul programului Prolog. Deoarece notaţia cu “.” este dificilă pentru scrierea listelor mai
26
complicate există o altă sintaxă care poate fi folosită pentru scrierea listelor în cadrul unui
program Prolog. Această notaţie listă se compune din elementele listei separate prin virgule,
întreaga listă fiind cuprinsă între paranteze []. De exemplu, listele de mai sus pot fi
reprezentate cu ajutorul notaţiei listă prin: [a] şi [a,b,c].
Este posibil ca listele să conţină alte liste şi variabile. De exemplu, următoarele liste
sunt corecte din punct de vedere sintactic în Prolog:

[]
[un, om,[place, un, peste]]
[a, V1,b, [X,Y]]

Variabilele din cadrul listelor sunt tratate la fel ca variabilele din oricare altă structură.
Acestea pot fi instanţiate în orice moment astfel încât utilizarea judicioasă a lor poate furniza
o modalitate de a insera în liste elemente vide care să poată fi completate cu date la un
moment ulterior. Pentru a reprezenta structura listelor cuprinse în alte liste, să scriem
diagrama “vine” pentru ultima listă de mai sus:

Este uşor de remarcat din această diagramă că fiecare nivel orizontal al diagramei este
o listă având un anumit număr de elemente. Nivelul cel mai de sus reprezintă o listă ce are 4
elemente, unul dintre acestea fiind o listă. Nivelul al doilea, având 2 elemente, este cel de al
patrulea element al listei de la nivelul cel mai înalt.
Listele pot fi manipulate prin împărţirea lor într-un cap şi o coadă. Capul unei liste
este prima componentă a functorului punct utilizat în construirea listei. Să reţinem faptul că
vorbim despre capul (antetul) unei reguli şi despre capul (antetul) unei liste, aceste două
lucruri fiind însă diferite. Coada unei liste este componenta a doua a functorului “.”. Când o
listă apare în paranteze [] capul listei este reprezentat de primul element al acesteia.
Coada listei este o sublistă care constă din toate elementele cu excepţia primului.
Exemplele din tabelul 3.1. ilustrează câteva capete şi cozi. Observăm că o listă vidă nu are
nici cap nici coadă. În ultimul exemplu, operatorul “+” este folosit ca functor pentru
structurile +(X,Y) şi +(x,y).
Deoarece o operaţie obişnuită asupra listelor este aceea de a împărţii o listă în cap şi
coadă, există o notaţie specială în Prolog pentru a reprezenta “lista cu capul X şi coada Y”.
Aceasta este scrisă [X|Y] unde simbolul care separă pe X de Y este o bară verticală. Un mod
de lucru cu această formă de scriere va iniţializa capul listei cu X şi coada cu Y ca în exemplul
următor:

p([1,2,3]).
P([o,pisica,sta,[pe,o,masa]]).
?- p([X|Y]).
X=1 Y=[2,3];
27
X=o Y=[pisica,sta,[pe,o,masa]]
?- p([_,_,_,[_|X]]).
X=[o,masa]

Tabelul 3.1. Exemple de liste cu capetele şi cozile lor.


Liste Capete Cozi
[a,b,c] a [b,c]
[] (none) (none)
[[o,pisica],sta] [o,pisica] [sta]
[o,[pisica,sta]] o [[pisica,sta]]
[o,[pisica,sta],jos] o [[pisica,sta],jos]
[X+Y,x+y] X+Y [x+y]

Listele pot fi utilizate în reprezentarea şirurilor de caractere. Avem nevoie de şiruri de


caractere pentru a citi sau tipări texte constând din propoziţii. Şirul de caractere este pus între
“ ” şi este reprezentat ca o listă de coduri întregi (codul ASCII) ce reprezintă caracterele. De
exemplu, şirul “SYSTEM” este translatat de Prolog în lista
[115,121,115,116,101,109].

1.13 Căutarea recursivă

Uneori este necesar să căutăm în interiorul unei structuri Prolog pentru a găsi anumite
informaţii dorite. Atunci când structura are alte structuri ca şi componente, trebuie efectuată o
căutare recursivă.
Definim în Prolog un predicat ”membru” astfel încât scopul membru(X,Y) este
adevărat dacă termenul reprezentat de X este un membru al listei reprezentate de Y.
Apartenenţa lui X la lista Y se poate verifica în două moduri.
În primul rând este cert că X va fi membru al lui Y dacă X este identic cu capul listei Y.
În Prolog, acesta se scrie:

membru(X,[X|_])

care înseamnă ”X este un membru al listei care îl are pe X ca şi cap”. S-a folosit variabila
anonimă ”_” pentru a reprezenta coada listei, aceasta datorită faptului că nu folosim coada la
nimic. Această regulă poate fi scrisă de asemenea ca:

membru(X,[Y|_]):-X=Y.

În al doilea rând, următoarea regulă, care foloseşte recursivitatea, spune că X este un


membru al unei liste care îl conţine pe acesta în coada ei numită Y:

membru(X,[_|Y]):-membru(X,Y).

S-a folosit variabila anonimă ”_” deoarece nu interesează numele variabilelor ce constituie
capul listei. Cele două reguli împreună definesc predicatul membru şi spun Prolog-ului cum
să caute într-o listă de la început la sfârşit, urmărind un termen specific.
Cel mai important lucru ce trebuie luat în considerare la definirea unui predicat
recursiv este de a căuta condiţiile de restricţie în cazul recursiv. Există două condiţii
restrictive pentru predicatul membru: prima condiţie restrictivă este conţinută în prima clauză

28
care va determina oprirea căutării în listă dacă primul argument din membru se potriveşte cu
capul celui de al doilea argument; a doua condiţie restrictivă intervine atunci când al doilea
argument al lui membru este o listă vidă.
Prima condiţie restrictivă este recunoscută de către o regulă ceea ce nu implică luarea în
considerare a altor viitoare subscopuri. A doua condiţie restrictivă este recunoscută de către
orice clauză a lui membru astfel încât acesta va eşua.
Este foarte important de reţinut că de fiecare dată când membru foloseşte a doua
clauză pentru a încerca satisfacerea sa, Prolog tratează fiecare ciclare recursivă a scopului
membru ca pe o copie diferită. Aceasta previne faptul că variabilele folosite într-o clauză să
se confunde cu variabilele folosite în altă clauză.
Predicatul membru este important deoarece este unul din cele mai scurte exemple de
predicat recursiv. Definiţiile recursive se întâlnesc frecvent în programe Prolog şi trebuie să
fim atenţi pentru a nu scrie definiţii circulare, ca de exemplu:

parinte(X,Y):-copil(Y,X).
copil(A,B):-parinte(B,A).

Pentru a satisface predicatul parinte se consideră copil ca pe un scop. Definiţia lui


copil foloseşte la rândul ei pe parinte ca şi scop. Punerea unei întrebări despre
parinte sau copil va duce la o buclă în care Prolog-ul nu va deduce nimic şi care nu se
va termina niciodată.
1.14 Maparea

Dându-se o structură Prolog frecvent se doreşte să se construiască o nouă structură


similară cu cea veche dar puţin schimbată. Se parcurg componentele din vechea structură şi se
construiesc componentele noii structuri. Numim această activitate mapare.
Să ne imaginăm un program Prolog în care introducem o propoziţie în engleză iar
Prolog-ul ne furnizează o altă propoziţie care reprezintă o versiune modificată a celei
introduse. Acest program care ”dă replici” programatorului poate produce un dialog de genul:

you are a computer


i am not a computer
do you speak french
no i speak german

Cu toate că acest dialog poate părea ca o conversaţie puţin forţată, este uşor să scriem un
program care să rezolve partea de dialog urmând paşii:
1. Acceptarea propoziţiei introdusă de către utilizator.
2. Schimbarea fiecărui you din propoziţie în “i”.
3. Schimbarea fiecărui are în am not.
4. Schimbarea cuvântului french cu german.
5. Schimbarea cuvântului do cu no.
Aplicată asupra unor propoziţii alese cu grijă cum sunt cele din dialogul de mai sus, această
schemă va produce propoziţiile modificate.
Un program Prolog care schimbă o propoziţie într-o altă propoziţie ar putea fi scris
după cum urmează. În primul rând este necesar să se ţină seama că există o relaţie între
propoziţia originală şi cea modificată. Este nevoie să se definească un predicat, numit
modifica, astfel încât modifica(X,Y) înseamnă că propoziţia X poate fi modificată
pentru a obţine Y. Este convenabil ca X şi Y să fie liste cu elemente atomice corespunzătoare
29
cuvintelor, astfel încât propoziţiile să poată fi scrise sun forma:

[aceasta,este,o,propozitie].

Dacă predicatul modifica este definit, şi ţinând seama şi de regulile de modificare definite
anterior putem pune întrebări Prolog-ului de forma

?-modifica([do,you,know,french],X).

iar Prolog-ul va răspunde

X=[no,i,know,german].

Deoarece modifica lucrează cu liste trebuie să rezolve şi cazul în care lista este vidă
şi anume o listă vidă este modificată şi rezultă o altă listă vidă:

modifica([ ],[ ]).

Rezultă că principalele funcţii ale lui modifica sunt de a:


1. Schimba capul listei de intrare cu alt cuvânt şi a pune în capul listei de ieşire acel
cuvânt.
2. Modifica coada listei de intrare şi de a introduce modificările în lista de ieşire.
3. Dacă se va întâlni sfârşitul listei de intrare, atunci nu se mai poate adăuga nimic
listei de ieşire, astfel încât aceasta se încheie cu o listă vidă []. Deci:
Modificarea unei liste ce are capul H şi coada T produce o listă cu capul X şi coada Y
dacă:
- schimbând cuvântul H rezultă cuvântul X, şi
- modificând lista T obţinem lista Y.
Pentru transpunerea în fapte a modificărilor anterioare este nevoie să se rezolve
“schimbarea” unui cuvânt în altul. Aceasta poate fi făcut având în baza de date un predicat de
forma schimba(X,Y), care înseamnă că cuvântul X poate fi schimbat în cuvântul Y. Faptul
global schimba(X,X)înseamnă că, cuvântul X se transformă în el însuşi. O bază de date
care tratează schimbările enunţate mai sus este:

schimba(you,i).
schimba(are,[am,not]).
schimba(french,german).
schimba(do,no).
schimba(X,X).

Reţinem faptul că propoziţia “am not” a fost tratată ca o listă, astfel încât ea ocupă locul
unui singur argument.
Toate considerentele de mai sus se pot translata din pseudo-Prolog într-o secvenţă
Prolog (amintindu-ne notaţia [A|B] pentru lista care are capul A şi coada B). Vom obţine
următoarele:

modifica([ ],[ ]).


modifica([H|T],[X|Y]):- schimba(H,X),modifica(T,Y).

Prima clauză din această procedură verifică dacă lista este goală. Aceeaşi clauză verifică şi
30
sfârşitul listei. Punând acum întrebarea:

?-modifica([you,are,a,computer],Z).

Această regulă va corespunde cu regula principală modifica, realizând corespondenţa


dintre variabila H şi you, şi dintre variabila T şi lista [are,a,computer]. În continuare
scopul schimba(you,X) va reuşi, făcând ca X să corespundă cuvântului “i”. Cum X este
capul listei de ieşire (în scopul modifica), primul cuvânt în lista de ieşire este “ i ”. În
continuare, scopul modifica([are,a,computer],Y) va utiliza aceeaşi regulă.
Cuvântul are este schimbat în interiorul listei cu [am,not] din baza de date, şi apoi este
generat un alt scop modifica:

modifica([a,computer],Y).

1.15 Comparaţia recursivă.

După cum am văzut în capitolul 2, Prolog furnizează predicate pentru compararea


întregilor. Compararea structurilor este în general mai complicată, deoarece este necesar să fie
luate în considerare toate componentele individuale. Când componentele sunt ele însele
structuri, comparaţia poate deveni recursivă. Spre exemplu, în aplicaţii cum ar fi dicţionarele,
ce lucrează cu cuvinte, este de ajuns să existe un predicat care să compare cuvintele în ordine
alfabetică. Aceasta implică compararea recursivă a listelor.
Definim un predicat denumit compara. Când compara(X,Y) este folosit ca scop
acesta va fi atins dacă X şi Y sunt consideraţi atomici şi X este (alfabetic vorbind) înaintea lui
Y. Deci,

?- compara(avocat,cler) va reuşi, şi
?- compara(vin,motor) va eşua.
De asemenea,
?- compara(piua,piua) va eşua.

Compararea a două cuvinte, se face literă cu literă, şi pentru fiecare comparaţie, se determină
care din următoarele condiţii sunt aplicabile:
1. Se poate atinge sfârşitul primului cuvânt fără a atinge sfârşitul celui de-al doilea cuvânt.
Spre exemplu, compara(car,cart), în acest caz compara trebuie să reuşească.
2. Un caracter din primul cuvânt este alfabetic mai mic decât caracterul corespunzător din al
doilea cuvânt caz în care compara reuşeşte. De exemplu,
compara(elefant,elevator), „f”-ul din elefant este alfabetic înaintea lui „v ”
din elevator.
3. Se poate găsi că un caracter din primul cuvânt este alfabetic egal cu caracterul
corespunzător din al doilea cuvânt. În acest caz, trebuie să se încerce compara pe caracterele
rămase din ambele cuvinte. De exemplu, compara(lada,leac), litera „l” este la
începutul ambelor cuvinte, deci va trebui să încercăm compara(ada,eac) ca scop
următor.
4. Se poate întâmpla să ajungă concomitent la sfârşitul primului şi celui de-al doilea cuvânt,
spre exemplu compara(mare,mare), în acest caz compara va eşua deoarece cele două
cuvinte sunt identice.
5. Se poate termina parcurgerea caracterelor din cuvântul al doilea înainte de a se termina
parcurgerea caracterelor din primul cuvânt, cum ar fi compara(alfa,alf). În acest caz
31
compara va eşua.
Condiţiile anterioare pot fi transpuse în Prolog prin reprezentarea cuvintelor ca liste de
caractere (întregi mici), deci trebuie să existe o modalitate de a converti un atom Prolog într-o
listă de caractere. Acesta este scopul predicatului predefinit name. Scopul name(X,Y) este
îndeplinit atunci când atomul instanţiat pentru X consistă dintr-o listă de coduri de caractere
(coduri ASCII) instanţiată pentru Y. Dacă unul din argumente este neinstanţiat, Prolog va
încerca să-l instanţieze prin crearea unei structuri corespunzătoare. De exemplu, cunoscând
codul ASCII pentru „a”, 97, pentru „l”, 108, şi pentru „p”, 112, următoarele întrebări puse
lui name va genera răspunsurile:

?- name(X,[97,108,112]).
X=alp
?- name(alp,X).
X=[97,108,112])

1.16 Alăturarea structurilor

Predicatul de procesare a listei adauga este folosit pentru a uni două liste rezultând
una nouă. Predicatul adauga este definit astfel:

adauga([],L,L).
adauga([X L1],L2,[X L3]):- adauga(L1,L2,L3).

Condiţiile limită apar când prima listă este lista vidă. În acest caz, orice listă adăugată
listei vide rămâne aceeaşi listă.
Cea de a doua regulă lucrează după următoarele principii:
1. Primul element al primei liste (X) va fi întotdeauna primul element al listei a treia.
2. Coada primei liste (L1) va avea întotdeauna al doilea argument (L2) adăugat la ea pentru a
forma coada (L3) a celui de-al treilea argument.
3. Trebuie folosit adauga pentru a realiza unirea arătată la punctul 2.
4. Evident se ia în mod continuu capul din ceea ce a mai rămas din primul argument, şi acesta
va fi gradual redus către lista vidă, ceea ce va conduce la condiţia limită.
În capitolele următoare vom trata diferite proprietăţi şi aplicaţii ale predicatului
adauga.
Uneori este nevoie să se parcurgă o structură Prolog şi să calculeze un rezultat care
depinde de ceea ce este găsit în structură la momentul respectiv. Evident că acest rezultat are
o valoare provizorie, într-un stadiu intermediar al acestei parcurgeri, valoare care trebuie
însă „reţinută” (deci memorată). O tehnică obişnuită de a rezolva această problemă este de a
folosi un argument al predicatului pentru a memora această valoare. Acest argument este
denumit acumulator.

32
LECŢIA 4.
BACKTRACKING (REVENIREA) ŞI TĂIETURA (CUT)
Acest capitol va trata “ backtracking-ul ” (revenirea) în detaliu, de asemenea va trata
un mecanism special, care poate fi utilizat în programele Prolog - „cut” (tăietura). Tăietura
permite programatorului să comunice Prolog -ului care dintre alegerile anterioare e necesar a
nu mai fi considerate din nou.
1.17 Generarea soluţiilor multiple
Cea mai simplă cale prin care un set de fapte poate furniza mai multe soluţii la o
întrebare este atunci când există mai multe fapte care sunt în neconcordanţă cu întrebarea. De
exemplu, dacă avem următoarele fapte în care prin tata(X,Y) înţelegem că tatăl lui X este
Y:
tata(maria,george).
tata(ion,george).
tata(elena,nicu).
tata(george,emil).
Întrebarea
?- tata(X,Y).
va avea mai multe răspunsuri posibile. Prolog ne va da următoarele răspunsuri:
X=maria, Y=george;
X=ion, Y=george;
X=elena, Y=nicu;
X=george,Y=emil;
Aceste răspunsuri au fost afişate căutând în baza de date pentru a găsi faptele şi regula
referitoare la tata în ordinea în care ele au fost date. Prolog nu-şi aminteşte nimic despre
ceea ce a indicat mai înainte. Deci dacă întrebăm
?-tata(_,X).
(pentru care dintre X este X un tată ?) va răspunde:
X=george;
X=george;
X=nicu;
X=emil;

george apărând de două ori deoarece George este tată pentru Maria şi Ion. Dacă Prolog are
două modalităţi de a arăta acelaşi lucru, le tratează ca pe două soluţii diferite.
Backtracking-ul apare exact în acelaşi mod dacă alternativele sunt întipărite mai adânc
în procesare. De exemplu, o regulă pentru definiţia „unul dintre copiii lui X este Y” poate fi:
copil(X,Y):- tata(Y,X).
Apoi, întrebarea
?- copil(X,Y).
va da următorul răspuns:
33
X=george, Y=maria;
X=george, Y=ion;
X=nicu, Y=elena;
X=emil, Y=george;

Deoarece tata(Y,X) are patru soluţii, tot aşa va avea şi copil(X,Y). Mai mult,
soluţiile sunt generate în aceeaşi ordine dar acestea sunt diferite pentru că ordinea
argumentelor este diferită, după cum este specificat în definiţia lui copil. Similar dacă
definim
tata(X):- tata(_,X).
(tata(X) înseamnă că X este un tată), atunci întrebarea
?- tata(X).
va indica:
X=george;
X=george;
X=nicu;
X=emil;
Să considerăm acum un caz şi mai interesant - acolo unde sunt două scopuri, fiecare
din ele având câteva soluţii. Să presupunem că planificăm o petrecere şi că dorim să speculăm
cine cu cine ar putea dansa. Să scriem programul următor:
pereche_posibila(X,Y):-baiat(X),fata(Y).
baiat(ion).
baiat(mitica).
baiat(bebe).
baiat(cosmin).
fata(georgeta).
fata(emilia).
fata(raluca).
Acest program spune că X şi Y formează o pereche posibilă dacă X este un băiat şi Y
este o fată. Acum să vedem care sunt posibilele perechi:
? pereche_posibila(X).
X=ion, Y=georgeta;
X=ion, Y=emilia;
X=ion, Y=raluca;
X=mitica, Y=georgeta;
X=mitica, Y=emilia;
X=mitica, Y=raluca;
X=bebe, Y=georgeta;
X=bebe, Y=emilia;
X=bebe, Y=raluca;
X=cosmin, Y=georgeta;
X=cosmin, Y=emilia;
X=cosmin, Y=raluca

34
Să vedem de ce Prolog produce soluţiile în această ordine. Mai întâi, el îndeplineşte
scopul baiat(X), găsindu-l pe ion, primul băiat. Apoi îndeplineşte scopul fata(Y),
găsind-o pe georgeta, prima fată. În acest punct, cerem o altă soluţie, cauzând un eşec.
Prolog încearcă să resatisfacă ceea ce a făcut anterior, adică scopul fata în interiorul
satisfacerii scopului pereche_posibila. El va găsi alternativa fetei emilia, deci a doua
soluţie este ion şi emilia. Similar, va genera ion şi raluca ca o a treia soluţie. În
momentul următor când va încerca să resatisfacă fata(Y), Prolog va găsi markerul său la
sfârşitul bazei de date şi astfel scopul eşuează. Acum va încerca să resatisfacă baiat(X).
Markerul a fost plasat la primul element pentru băiat, astfel încât următoarea soluţie găsită
este al doilea băiat, mitica. Acum că are îndeplinit acest scop, Prolog priveşte să vadă ce
urmează: trebuie să îndeplinească fata(Y) din nou, de la început. Astfel încât găseşte
georgeta prima fată. Următoarele trei soluţii implică acum pe mitica şi pe cele trei fete.
Mai departe, căutând o alternativă, scopul fata nu poate fi resatisfăcut. Deci un alt băiat este
găsit, iar căutarea printre fete începe din nou de la linia iniţială, ş.a.m.d. Eventual, scopul
fata eşuează şi de asemenea nu mai sunt soluţii pentru scopul baiat, astfel programul nu
mai poate găsi perechi.
Aceste exemple sunt toate foarte simple. Ele implică doar specificarea mai multor
fapte sau utilizarea regulilor pentru accesarea acestor elemente. De aceea, ele pot genera doar
un număr finit de soluţii posibile. Uneori am putea dori să generăm un număr infinit de
posibilităţi, nu pentru că dorim să le considerăm pe toate, ci pentru că am putea să nu ştim
anticipat de câte avem nevoie. În acest, caz avem nevoie de o definiţie recursivă (discutată în
capitolul anterior).
Considerăm următoarea definiţie a ceea ce este un întreg (unde prin întreg înţelegem
un număr nu mai mic decât 0). Scopul este_întreg(N) va fi atins cu condiţia ca N să fie
instanţiat cu un întreg. Dacă N nu este instanţiat în acelaşi timp în care scopul este considerat,
atunci este_întreg(N) va determina să fie ales un întreg, iar N va fi ataşat la acesta:
/*1*/ este_întreg(0).
/*2*/ este_întreg(X):-este_întreg(Y), X is Y+1.
Dacă punem întrebarea
?- este_întreg(X).
vom avea ca răspunsuri posibile toate numerele întregi în ordine crescătoare
( 0, 1, 2, 3,...), dându-se pe rând câte unul din ele. De fiecare dată forţăm backtracking-ul
(imprimând “;”) pentru a obţine cum, este_întreg va fi realizat cu argumentul său
instanţiat cu un nou întreg. Deci, în principiu, această scurtă definiţie generează un număr
infinit de răspunsuri.
Cele mai multe reguli ale lui Prolog vor da naştere la soluţii alternative dacă sunt folosite
pentru scopuri ce conţin o mulţime de variabile neinstanţiate. De exemplu, relaţia membrilor
unei liste (din capitolul 3):
membru(X,[X|_]).
membru(X,[_|Y]):-membru(X,Y).
va genera alternative. Dacă întrebăm
?- membru(a,X).
(notăm că X este neinstanţiat), atunci valorile succesive ale lui X vor fi liste parţial definite,
unde a este primul membru, al doilea, şi aşa mai departe. Vă puteţi da seama de ce ?
35
Un rezultat suplimentar al admiterii acestei definiţii a lui membru este că întrebarea:
?- membru(a,[a,b,r,a,c,a,d,a,b,r,a]).

va primi răspuns de cinci ori. În mod clar, există unele aplicaţii pentru membru unde avem
nevoie doar de o singură realizare şi apoi putem elimina cele patru posibilităţi. Putem spune
Prolog-ului să elimine posibilităţile în acest mod utilizând „tăietura”.
4.2. “Tăietura”(cut)
Acest subcapitol face referiri asupra unui mecanism special care poate fi utilizat în
progamele Prolog-ului -„tăietura”. Tăietura permite programatorului să comunice care opţiuni
anterioare nu trebuie reconsiderate când acesta reia căutarea prin lanţul de scopuri atinse.
Există două motive pentru care este important să facem acest lucru:
- Programul va opera mai repede deoarece nu va mai irosi timp încercând să
îndeplinească scopuri despre care putem spune dinainte că nu vor contribui niciodată la o
soluţionare a problemei;
- Programul poate ocupa mai puţin din spaţiul de memorie al calculatorului deoarece
poate fi realizată o folosire mai economică dacă punctele urmărite nu trebuie să fie
înregistrate pentru o examinare ulterioară.
În unele cazuri, includerea unei tăieturi poate însemna diferenţa între un program care
va merge şi un program care nu va merge.
Din punct de vedere sintactic, o folosire a tăieturii într-o regulă arată exact ca apariţia
unui scop care are predicatul „ ! ” şi fără argumente. Ca scop, acesta este îndeplinit imediat
şi nu poate fi resatisfăcut. Oricum, el are de asemenea efecte secundare, care schimbă modul
în care lucrează backtracking-ul după aceea. Efectul este de a face inaccesibili indicatorii de
loc pentru anumite scopuri astfel încât ele nu vor mai putea fi resatisfăcute.
Definiţia formală a efectului simbolului tăietura este următoarea:
Când o tăietură este întâlnită ca un scop, sistemul devine dedicat tuturor alegerilor
făcute de când scopul părinte a fost invocat. Orice alte alternative sunt eliminate. Din acest
motiv o încercare de resatisfacere a oricărui scop între scopul părinte şi scopul tăietura va
eşua.
Există mai multe modalităţi de descriere a ceea ce se întâmplă cu alegerile care sunt
efectuate de o tăietură. În primul rând că alegerile sunt tăiate sau imobilizate, dacă sistemul se
dedică alegerilor făcute sau se renunţă la alternative. De asemenea putem privi la simbolul
“tăietura” care devine mai degrabă ca un delimitator de scopuri.
Încă o observaţie înainte de a merge mai departe. Deja am spus că dacă tăietura apare
într-o regulă iar scopul este satisfăcut atunci Prolog devine dedicat spre toate alegerile făcute
din momentul în care scopul părinte a fost invocat. Aceasta înseamnă că alegerea acestei
reguli şi toate celelalte alegeri făcute după aceea devin fixe. Vom vedea mai târziu că este
posibil să se furnizeze alternative în interiorul unei singure reguli folosind predicatul
încorporat „ ; ” ( însemnând „ sau ” ). Alegerile introduse în această facilitate sunt afectate
exact în acelaşi mod. Aceasta înseamnă că, când un scop de tăietură este satisfăcut, toate
alegerile ”sau” care au fost făcute din momentul alegerii regulii devin fixe.
4.3. Folosirea comună a tăieturii
Putem împărţi folosirea comună a tăieturii în trei domenii importante:
- Primul implică locurile unde dorim să spunem sistemului Prolog că a găsit regula
potrivită pentru un scop particular. Aici, tăietura spune „ dacă ai ajuns până aici, înseamnă că
ai ales regula corectă pentru acest scop.”
- Al doilea domeniu implică locurile în care dorim să spunem sistemului Prolog să
36
abandoneze un scop particular imediat, fără a încerca soluţii alternative. Aici folosim tăietura
în conjuncţie cu predicatul fail pentru a spune „ dacă ai ajuns aici, trebuie să te opreşti a mai
încerca să satisfaci acest scop.”
- Al treilea implică locurile în care dorim să încheiem generarea soluţiilor alternative
prin backtracking. Aici tăietura spune „ dacă ai ajuns aici, ai găsit singura soluţie la această
problemă şi nu are rost căutarea alternativelor.”

4.3.1. Confirmarea alegerii unei reguli

Foarte des într-un program Prolog dorim să asociem mai multe clauze cu acelaşi
predicat. O clauză poate fi potrivită dacă argumentele sunt într-o singură formă, o alta va fi
potrivită dacă argumentele sunt într-o altă formă, ş.a.m.d. Adesea, putem specifica care regulă
trebuie să fie utilizată pentru un scop dat prin furnizarea modelelor în antetele regulei care se
vor potrivi doar cu scopurile ce au tipul corect. Oricum, acest lucru nu poate fi întodeauna
posibil. Dacă nu putem spune în avans ce formă pot lua argumentele sau dacă nu putem
specifica un set exhaustiv de modele, trebuie să realizăm un compromis. Aceasta înseamnă
furnizarea regulilor pentru unele tipuri specifice de argumente şi apoi furnizarea unei reguli
„de prindere” la sfârşit pentru orice altceva.
Ca un exemplu pentru acesta, considerăm următorul program. Regulile definesc
predicatul suma_1_n care furnizează Prolog-ului scopul suma_1_n(N,X) cu N având o
valoare întreagă, determinând instanţierea lui X cu suma numerelor de la 1 la N. Astfel:
?- suma_1_n(5,X).
X=15 ;
yes
deoarece 1+2+3+4+5 este 15. Acesta este programul.
suma_1_n( 1, 1 ):- !.
suma_1_n( N, Rezultat ):-
N1 is N - 1,
suma_1_n( N1,Rezultat1 ),
Rezultat is Rezultat1+N.

Aceasta este o definiţie recursivă. Ideea este că această condiţie limită apare când
primul număr este 1. În acest caz răspunsul este de asemenea 1. A doua clauză introduce un
scop recursiv suma_1_n. Oricum, primul număr al noului scop este cu 1 mai mic decât cel
original. Noul scop pe care acest scop îl va invoca va avea primul său argument din nou cu 1
mai mic, şi aşa mai departe până ce este atinsă condiţia limită. Deoarece primele argumente
sunt întodeauna mai mici, condiţia limită trebuie să fie atinsă eventual (presupunând că scopul
original are un prim argument nu mai mic decât 1), iar programul se va sfârşi.
Un stil bun de programare este de a înlocui tăieturile prin folosirea lui not. Aceasta
deoarece programele ce conţin tăieturi sunt în general mai greu de citit decât programele care
nu le conţin. Dacă unul poate localiza toate apariţiile tăieturilor în interiorul definiţiei lui not
atunci programul va fi mai uşor de înţeles. Oricum definirea lui not implică încercarea de a
arăta că scopul dat poate fi satisfăcut. De aceea, dacă avem un program de forma generală:
A:- B,C.
A:- not(B),D.
Prolog poate foarte bine să termine încercând să satisfacă de două ori pe B. El va
încerca să satisfacă pe B când ia în consideraţie prima regulă. De asemenea, efectuează
37
backtracking şi considerând a doua regulă, va trebui să încerce să satisfacă din nou B pentru a
vedea dacă not(B) poate fi satisfăcut. Această duplicare poate fi foarte ineficientă dacă
condiţia B a fost destul de complicată. Aceasta nu se întâmplă dacă în locul lui avem:
A:- B,!,C.
A:- D.
4.3.2. Combinaţia „tăietură - eşuare” (cut - fail)

În cel de-al doilea domeniu de aplicaţii, tăietura este folosită în conjuncţie cu


predicatul fail. Acesta este un alt predicat predefinit, la fel ca şi not. Nu are argumente,
ceea ce înseamnă că realizarea scopului fail nu depinde de o variabilă oarecare. Într-adevăr,
fail este definit într-un astfel de mod încât un scop eşuează întodeauna şi determină apariţia
backtracking-ului. Aceasta se întâmplă dacă încercăm să satisfacem un scop pentru un
predicat fără fapte sau reguli. Când fail este folosit după o tăietură, comportamentul de
backtracking normal va fi alterat de efectul tăieturii. De fapt, combinaţia particulară „cut-fail”
devine deosebit de folositoare în practică.
O aplicaţie interesantă a combinaţiei “tăietură-eşuare” este definiţia predicatului not.
Majoritatea implementărilor limbajului Prolog furnizează deja această definiţie, dar este
interesant să considerăm modul în care putem furniza reguli pentru el. Dorim ca scopul
not(P), unde P înseamnă un alt scop, să reuşească dacă şi numai dacă scopul P eşuează. Nu
este exact în concordanţă cu noţiunea intuitivă de “neadevărat” (nu este corect să presupunem
că ceva nu este adevărat dacă nu suntem capabili să dovedim acest lucru). Totuşi, iată o
definiţie:

not(P):- call(P), !, fail


not(P).
Definiţia lui not implică apelarea argumentului P ca scop, folosind predicatul
predefinit call. Predicatul call tratează pur şi simplu argumentul său ca un scop şi
încearcă să-l satisfacă. Noi dorim ca prima regulă să fie aplicabilă dacă P poate fi satisfăcut
iar a doua să fie aplicabilă în caz contrar. Astfel, spunem că dacă Prolog poate satisface
call(P) el trebuie să abandoneze în consecinţă satisfacerea scopului not. O altă
posibilitate este ca Prolog să nu poată satisface call(P); în acest caz el niciodată nu
realizează tăietura. Deoarece scopul call(P) a eşuat, în acest caz are loc revenirea şi Prolog
găseşte a doua regulă. Deci scopul not(P) va reuşi atunci când P nu poate fi demonstrat. Ca
şi în primul caz de folosire a tăieturii, putem înlocui folosirea combinaţiei “tăietură-eşuare” cu
folosirea scopului not. Aceasta implică mai curând o mai bună reorganizare a programului
decât înainte, dar nu introduce aceeaşi ineficienţă.

38
LECŢIA 5.

INTRĂRI SI IESIRI

Până acum, singura sursă de obţinere a informaţiilor pentru un program Prolog era
prin întrebări puse sistemului Prolog. De asemenea singura metodă de a afla semnificaţia unei
variabile în obţinerea rezultatului final era prin punerea unor întrebări la care Prolog va tipări
răspunsul în forma "X=raspuns". O astfel de legătură directă, prin întrebări, este suficientă
pentru a ne asigura că un program funcţionează corect. Cu toate acestea, în multe cazuri este
util să scriem un program Prolog care să iniţieze singur un astfel de dialog. În acest capitol
descriem diferite metode de scriere şi citire.

1.18 Citirea şi scrierea termenilor

1.18.1 Scrierea termenilor

Cel mai folositor mod de a afişa termeni pe displayul calculatorului este să folosim
predicatul write. Dacă X este iniţializat cu un termen atunci write(X)va determina
afişarea pe display a termenului. Dacă X nu este iniţializat, o variabilă numerică unică (cum ar
fi '_253') va fi afişată. Dacă două variabile împart acelaşi argument al lui write, atunci
ele vor avea acelaşi număr. Write poate fi asignat o singură dată.
Să ne amintim că un string este reprezentat ca o listă de coduri-caracter. Dacă ar fi să
folosim write lista va fi afişată ca o secvenţă de numere întregi, separate prin virgulă şi
incluse între paranteze drepte.
Alt predicat cu care este dotat Prolog-ul este 'nl' care înseamnă 'new line'. El este
folosit pentru a forţa datele de ieşire ce urmează lui nl să fie tipărite pe următoarea linie a
displayului. Ca şi write, nl are efect o singură dată.
Următorul predicat este tab. Este folosit pentru a tipări un număr de spaţii egale de-a
lungul monitorului. tab(X)are efect o singură dată şi determină cursorul să se deplaseze
spre dreapta cu X spaţii. Se presupune că X este iniţializat cu un număr întreg.
La afişarea listelor trebuie să avem în vedere ca elementele să fie astfel tipărite aşa
încât să poată fi uşor înţelese. Listele ce conţin, la rândul lor, alte liste sunt de regulă dificil de
citit, cu atât mai mult cu cât unele au şi structuri interne.
Predicatul write ţine seama la afişarea unui termen de declaraţiile făcute asupra
operatorilor. De exemplu, dacă am declarat atomul ca pe un operator infix, atunci un termen
al acestui atom este un functor şi două argumente vor fi afişate, cu atomul între cele două
argumente. Mai există un predicat care se comportă în acelaşi fel ca şi write, cu excepţia
faptului că ignoră oricare declaraţii făcute asupra operaţiilor. Acest predicat este display.
Diferenţa dintre cele două este ilustrată în exemplul următor:

?-write(a+b c c),nl,display(a+b c c),nl.


a+b c c
+(a, ( (b,c),c))
yes

Folosirea lui display este recomandată atunci când nu suntem prea siguri despre
precedenţele operatorilor utilizaţi.

39
1.18.2 Citirea termenilor

Predicatul read va citi următorul termen pe care-l scriem la tastatură. Termenul


trebuie să fie urmat de un punct "." şi de un caracter netipăribil cum ar fi space sau
return. Dacă X nu este iniţializat rezultatul lui read(X) va determina citirea următorului
termen şi iniţializarea acestuia cu X.
Ca şi alte predicate de intrare/ieşire, read are efect o singură dată. Dacă argumentul
lui read este iniţializat în momentul folosirii acestuia, atunci următorul termen va fi citit în
conformitate cu argumentul folosit. read va avea efect sau nu în funcţie de "potrivirea"
termenului cu argumentul.
1.19 Citirea şi scrierea caracterelor
Cea mai mică entitate ce poate fi scrisă sau citită este caracterul. După cum am văzut
până acum, caracterele sunt considerate numere întregi ce corespund codului ASCII pentru
caracterele respective. Prolog-ul are câteva predicate predefinite pentru citirea şi scrierea
caracterelor.

1.19.1 Scrierea caracterelor

Dacă X este iniţializat cu un caracter (un cod ASCII reprezentat de un întreg) acesta va
fi afişat când Prolog întâlneşte scopul put(X). Scopul put îşi face întotdeauna efectul dar
numai o singură dată. Ca un "efect secundar", put afişează argumentul ca pe un caracter pe
display-ul terminalului. De exemplu, putem afişa cuvântul salut în următorul fel:
?-put(115),put(97),put(108),put(117),put(116).
salut
Rezultatul acestei conjuncţi de scopuri este că Prolog afişează caracterele s,a, l, u, t.
ştim deja că putem să începem afişarea la începutul liniei următoare folosind nl, care nu are
nici un argument. Ceea ce face, de fapt, nl este să afişeze anumite caractere de control care
determină cursorul să se mute la începutul liniei următoare. Întrebarea:
?-put(108),put(97),nl,put(112),put(101),
put(108),put(101),put(115).
va determina afişarea:
la
peles

O altă soluţie: tab(X), care tipăreşte X spaţii (cod ASCII 32). Bineînţeles, X trebuie
să fie iniţializat cu un număr întreg. tab(X) poate fi definit astfel:
tab(0):-!.
tab(N):-put(32),M is N - 1,tab(M).

1.19.2 Citirea caracterelor

Caracterele pot fi citite de la tastatură folosind get0(X) şi get(X). Aceste scopuri


au întotdeauna efect dacă argumentele lor sunt neiniţializate şi, de asemenea, au efect când nu
pot fi resatisfăcute. Când sunt folosite determină calculatorul să aştepte intoducerea
40
caracterelor de la tastatură. Sunt foarte puţin diferite deoarece: get0(X) îl va iniţializa pe X
cu primul caracter primit de la tastatură, indiferent care va fi acela, pe când get(X) îl va
iniţializa pe X cu primul caracter tipăribil, deci va sări peste cele netipăribile primite de la
tastatură (Un caracter tipăribil este acela care poate fi vizualizat pe display).
Dacă X este deja iniţializat, atunci get(X) va sări peste caracterele netipăribile şi va
compara primul caracter tipăribil cu iniţializarea lui X. Get(X) va avea succes în funcţie de
rezultatul testului. Get0(X) compară următorul caracter pentru egalitate, succesul depinzând
de asemenea de rezultatul testului. Următorul paragraf prezintă câteva exemple cu privire la
citirea caracterelor. O importanţă deosebită o constituie reparcurgerea bazei de date după
scopul get.

1.20 Citirea şi scrierea fişierelor

Predicatele discutate anterior în acest capitol au fost folosite doar la citirea sau scrierea
pe terminalul calculatorului, dar de fapt ele sunt mult mai larg folosite. Sistemul Prolog
recunoaşte un "şir de intrare curent" din care este citită informaţia de intrare (input curent) şi
un "şir de iesire curent " în care sunt scrise datele de ieşire (outputul curent). În mod normal
tastatura calculatorului este aşa-numitul input curent iar displayul - outputul curent. Deseori
este mult mai util să citeşti sau să scrii fişiere, care reprezintă secvenţe de caractere aflate pe
diferite medii de înmagazinare a informaţiilor, de regulă discuri magnetice. Se presupune că
fiecare fişier are un nume necesar identificării. În Prolog numele de fişiere sunt reprezentate
ca atomi, dar nu putem exclude posibilitatea unor restricţii întâlnite la instalare în legătură cu
aceste nume de fişiere.
Fişierele au o anumită lungime, conţin deci un anumit număr de caractere. La sfârşitul
fiecărui fişier există un "indicator" de sfârşit de fişier: end of file marker. Dacă un
program citeşte informaţii dintr-un fişier, sfârşitul de fişier poate fi detectat dacă programul
citeşte termeni sau caractere. Dacă get0(X) întâlneşte semnul de sfârşit de fişier, X va fi
iniţializat cu un caracter de control, de regulă cel care are codul ASCII 26. Dacă read(X)
întâlneşte sfârşitul de fişier, X va fi iniţializat cu un termen special ce depinde de
particularităţile sistemului Prolog instalat. Acest termen special este, de regulă, atomul
end_of_file. Dacă se încearcă să se citească dincolo de sfârşitul de fişier se generează
eroarea de sfârşit de fişier.
Există un fişier livrat împreună cu sistemul, numit USER. Citirea acestui fişier
determină posibilitatea introducerii unor caractere de la tastatură şi scrierea lor în acest fişier
cu afişarea pe display a caracterelor. Acesta este modul normal de operare. Când inputul
provine de la tastatură, un sfârşit de fişier poate fi generat prin tipărirea caracterului de control
end_of_file (cod ASCII 26 sau CTRL+Z). Aceasta va determina ca get0 şi read să se
comporte ca şi cum ar fi întâlnit semnul de sfârşit de fişier.

1.20.1 Scrierea fişierelor

Termeni şi caractere pot fi scrise în fişiere folosind aceleaşi predicate discutate mai
sus. Singura diferenţă este că, atunci când dorim să scriem un fişier, trebuie să schimbăm
outputul curent în sensul că acesta trebuie să fie fişierul respectiv şi nu displayul. Acest lucru
este posibil prin folosirea predicatului tell. Dacă X este iniţializat cu un nume de fişier, care
trebuie să fie un atom, tell(X) va determina redirectarea outputului curent astfel încât orice
scriere (realizată cu write, put etc) va fi făcută în fişier în loc să fie făcută pe displayul
calculatorului. Tell(X) are efect o singură dată (nu poate fi reutilizat). Când Prolog-ul
reparcurge fişierul după tell nu va determina resetarea outputului curent la ceea ce a fost
41
iniţial. Tell mai realizează şi alte operaţii în afara acestei redirecţionări a outputului. Prima
oară când se foloseşte tell(X) pentru un anumit X, Prolog presupune că dorim să creem un
fişier cu acel nume. Deci, dacă X este iniţializat cu un atom aceasta presupune că fişierul
există deja şi atunci toate caracterele existente în fişier vor fi şterse. Pe de altă parte, dacă X
este iniţializat cu un atom care nu constituie nume al nici unui fişier existent, atunci va fi creat
un nou fişier cu numele respectiv. În ambele cazuri, fişierul este considerat deschis (pentru
output). Aceasta înseamnă că scrierea în fişier va determina adăugarea de caractere la sfârşitul
fişierului până când vom spune explicit că fişierul este complet (închidem fişierul). În acest
punct dacă încercăm să mai scriem în fişier, Prolog va presupune că vrem să scriem o nouă
versiune după cum am arătat mai sus. Dacă încercăm să folosim tell(X), cu X neiniţializat
sau este iniţializat cu un obiect diferit de un nume de fişier se primeşte un mesaj de eroare.
Predicatul telling este folosit pentru a afla numele fişierului care constituie
outputul curent. Telling(X) are succes când X este iniţializat cu numele fişierului output.
Dacă X nu este iniţializat, atunci telling îl va iniţializa de la sine în aşa fel încât operaţia să
fie realizată cu succes.
Când se termină scrierea în fişier predicatul told va închide fişierul (pentru output).
De asemenea, va redirecţiona outputul spre display. Deci, o secvenţă tipică pentru a scrie
câteva caractere într-un fişier poate fi următoarea:

... tell(munca),write(X),told, ...

Dacă şirul de date de ieşire este redirecţionat fără a folosi told asupra fişierului
anterior, acest fişier nu va fi închis, fiind încă disponibil pentru scris. Acest lucru permite
scrierea într-un fişier la momente de timp diferite, ca în exemplul:

...tell(X),write(A),tell(user),
write(B),tell(X),write(C),told.

1.20.2 Citirea fişierelor

Predicatele pe care Prolog-ul le pune la dispoziţie pentru redirecţionarea şirului curent


de date de intrare sunt analoage celor prezentate mai sus. Scopul See(X) direcţionează şirul
curent de date de intrare către fişierul specificat. Ca şi în cazul lui tell, obiectivul acesta nu
poate fi reasigurat şi operaţia rămâne nedeterminată la o nouă parcurgere.
Prima dată, folosirea lui see(X) este realizabilă pentru fişierul X, fişierul se deschide
(pentru input) şi se începe de la semnul de început de fişier. Următorul început de secvenţă
continuă de unde s-a rămas până când, în mod explicit, se închide fişierul. După această
operaţie, o nouă încercare de a citi fişierul va determina deschiderea acestuia, începându-se de
la semnul de început de fişier ca şi mai înainte. Şirul curent de început poate fi aflat prin
realizarea obiectivului lui seeing(X), iar inputul curent poate fi direcţionat înapoi către
tastatura terminalului prin seen, care închide, de asemenea, fişierul.

1.20.3 Consultarea fişierelor

Scrierea şi citirea fişierelor este de mare ajutor în special când programele folosesc
mai mulţi termeni decât cei pe care putem să-i tastăm manual de fiecare dată când dorim să-i
introducem într-o bază de date. În Prolog, fişierele sunt de regulă folosite pentru programe.
Dacă într-un fişier se salvează textul unui program Prolog se pot citi toate clauzele existente
în fişierul respectiv şi transfera într-o bază de date folosind predicatul consult. Când X este

42
iniţializat cu un nume de fişier, efectul predicatului consult(X) va fi citirea clauzelor
Prolog şi a efectelor acestora din fişierul respectiv. Cele mai multe implementări ale Prolog-
ului au o notaţie specială pentru consult, care permite consultarea unei liste de fişiere unul
după altul. Dacă o listă de atomi este pusă Prolog-ului sub forma unei întrebări, atunci Prolog-
ul va consulta fiecare fişier din listă. Predicatul consult opreşte automat clauzele de citire
când se întâlneşte semnul de sfârşit de fişier. Secţiunea 6.1 descrie în detaliu predicatul
consult.
1.21 Declararea operatorilor
Operatorii sunt consideraţi importanţi în acest capitol " Intări şi Ieşiri " deoarece oferă
uşurinţă sintactică la scrierea sau citirea termenilor. Acesta este motivul principal pentru
folosirea operatorilor.
Sintaxa Prolog conferă operatorilor trei proprietăţi: poziţie, clasă de precedenţă şi
asociativitate. Poziţia poate fi infixă, postfixă sau prefixă (un operator ce are două argumente
poate fi poziţionat între ele; un operator cu un singur argument poate fi poziţionat înainte sau
după acesta). Clasa de precedenţă este un număr întreg a cărei mărime depinde de
implementarea sistemului Prolog, cea mai folosită este de la 1 la 1200. Clasa de precedenţă
este folosită pentru creşterea eficienţei expresiilor în care sintaxa termenilor nu este explicită
prin folosirea parantezelor. Asociativitatea este folosită pentru creşterea eficienţei expresiilor
în care sunt doi operatori, în expresiile care au aceeaşi precedenţă. În Prolog se asociază un
atom special cu un operator, care reprezintă poziţia acestuia şi asociativitatea. Specificatorii
posibili pentru un operator infix sunt:
xfx xfy yfx yfy .
Pentru a înţelege aceşti specificatori, ei ne ajută să-i vedem ca pe posibile "imagini"
ale operatorilor. În aceste imagini, litera f reprezintă operatorul, iar x şi y reprezintă
argumentele. Deci, în exemplul de mai sus, operatorul trebuie să apară între două argumente
deci, este un operator infix. În consecinţă cu această convenţie fx şi fy sunt doi
specificatori pentru operatori-prefix (operatorul apare înaintea argumentului său). De
asemenea, xf şi yf sunt posibili specificatori pentru operatori postfix. Alegerea lui x şi y în
aceste poziţii determină transmiterea informaţiei asociative. Presupunem că nu există
paranteze, un y semnifică faptul că argumentul poate conţine operatori de aceeaşi sau mai
mică clasă de precedenţă decât acest operator. Pe de altă parte, un x semnifică faptul că orice
operatori ai argumentului trebuie să aibă o clasă de precedenţă strict mai mică decât a
operatorului. Imaginaţi-vă ce înseamnă acest lucru pentru operatorul +, declarat ca yfx.
Pentru a+b+c există două interpretări posibile: (a+b)+c sau a+(b+c), a doua
interpretare fiind exclusă deoarece presupunem că argumentul după primul + trebiue să
conţină un operator de aceeaşi precedenţă (încă un +, de exemplu). Acest lucru contrazice
prezenţa unui x după f-ul specificatorului.
În plus, un operator declarat yfx este asociativ la stânga iar un operator declarat xfy
este asociativ la dreapta. Dacă cunoaştem asociativitatea pe care dorim să i-o asigurăm unui
operator infix pe care-l declarăm, aceasta înseamnă că specificatorul este unic determinat.
Semnificaţia lui x şi y este aceeaşi şi în celelalte cazuri. Aceasta înseamnă că, de
exemplu, secvenţa
not not a
este, sintactic posibilă dacă not este declarat ca fy, dar este imposibilă dacă este declarată
fx.

43
LECŢIA 6.

PREDICATE PREDEFINITE

În acest capitol vom introduce câteva din predicatele predefinite pe care un sistem
Prolog le poate încorpora. Ce înţelegem atunci când spunem că un predicat este predefinit?
Aceasta înseamnă că definiţia predicatului este furnizată în avans de către sistemul Prolog, în
loc de a fi furnizată prin propriile clauze. Predicatele predefinite pot furniza facilităţi ce nu pot
fi obţinute cu ajutorul definiţiilor în sistemul Prolog pur. Ele pot furniza facilităţi convenabile
în scopul de a salva programatorul de a le defini el însuşi. Am întâlnit deja anumite predicate
predefinite: predicatele pentru citire şi scriere discutate în capitolul 5. Deasemenea “tăietura”
poate fi considerat ca un predicat predefinit.
1.22 Introducerea de noi clauze
Atunci când scrieţi un program Prolog, veţi dori să spuneţi sistemului ce clauze să
utilizeze, tot atât de bine cum doriţi să puneţi întrebări despre ele. Aţi putea dori ca într-o
clauză nouă să scrieţi ceva la terminal sau să spuneţi sistemului Prolog să preia clauze dintr-
un fişier pe care-l aveţi pregătit în prealabil. De fapt, aceste două operaţii se aseamănă din
punctul de vedere al sistemului Prolog, deoarece terminalul este văzut ca orice alt fişier,
având numele user. Există două predicate predefinite de bază pentru citire în clauzele noi:
consult şi reconsult.

consult(X)
Predicatul predefinit consult este valoros pentru acele situaţii când doriţi ca,
clauzele dintr-un anume fişier (sau care să fie tipărite la terminal) să crească clauzele dintr-o
bază de date. Argumentul trebuie să fie un atom ce furnizează numele fişierului din care să fie
preluate clauzele. Care atomi constituie un nume de fişier legal, aceasta va depinde de tipul
calculatorului.
Când încearcă să satisfacă scopul consult, Prolog citeşte din fişier, adăugând
clauzele pe care le găseşte la sfârşitul bazei de date. Ca rezultat, noile clauze vor apărea după
oricare clauză deja existentă pentru acelaşi predicat. Dacă este găsită o întrebare în fişier,
aceasta va fi tratată ca o întrebare obişnuită, exceptând faptul că răspunsul nu va fi afişat. În
mod obişnuit nu are sens să combinăm întrebările cu clauzele noi într-un fişier, exceptând
situaţia când avem de-a face cu declararea de noi operatori şi afişarea de mesaje utile.

reconsult(X)
Predicatul reconsult este exact la fel ca predicatul consult, exceptând faptul că,
clauzele citite sunt preluate prin suprascrierea tuturor clauzelor existente pentru acelaşi
predicat. Datorită acestui lucru, reconsult este potrivit pentru corectarea greşelilor de
programare. Dacă se citeşte din mai multe fişiere de clauze şi apoi se descoperă că există o
greşeală într-o clauză, aceasta poate fi corectată fără citirea din nou a tuturor fişierelor. Pentru
aceasta, trebuie doar aplicat scopul reconsult fişierului ce conţine setul corect de clauze
pentru predicatul în discuţie. Se poate obţine clauza corectă fie prin scrierea ei la terminal
(reconsult(user)) fie prin editarea unui fişier fără a ieşi din Prolog (posibil doar în
anumite implementări) şi apoi reconsultarea aceluiaşi fişier. Bineînţeles, scrierea clauzei
revizuite la terminal va altera ceea ce Prolog vede în baza de date, dar nu va schimba fişierul
original defect, din care provine clauza.

44
1.23 Succes şi eşec

În execuţia normală a unui program Prolog, un scop reuşeşte când el poate fi


satisfăcut, şi eşuează atunci când nu există nici o modalitate de satisfacere a lui. Există două
predicate ce fac mai uşor de specificat dacă un scop reuşeşte sau eşuează. Acestea sunt
predicatele true şi fail.

true
Aceast scop reuşeşte întotdeauna. El nu este de fapt necesar, deoarece clauzele şi
scopurile pot fi reordonate şi recombinate pentru a obţine orice folosire a lui true. Totuşi, el
există prin convenţie.

fail
Aceast scop eşuează întotdeauna. Există două locuri în care el este util. Un loc este
combinaţia tăietură-eşuare, care a fost descrisă în secţiunea 4.3. O conjuncţie de scopuri de
forma

..., !, fail.

este folosită pentru a spune “dacă execuţia continuă din acest punct, atunci cineva poate
abandona încercarea de a satisface acest scop”. Conjuncţia eşuează datorită predicatului
fail, iar scopul părinte eşuează datorită tăieturii.
Un alt loc în care este folosit predicatul fail este acela în care se doreşte în mod explicit să
se utilizeze alt scop pentru a trece prin toate soluţiile. Este posibil să se dorească afişarea
tuturor soluţiilor.

1.24 Determinarea tipului

Dacă dorim să definim predicate care vor fi folosite cu o mare varietate de tipuri de
argumente, este util să fim capabili să distingem în definiţie ce trebuie să fie făcut pentru
fiecare tip posibil. Predicatele următoare permit programatorului să includă aceste condiţii
suplimentare în clauzele sale.

var(X)
Scopul var(X) reuşeşte dacă X este în acel moment o variabilă neiniţializată. Astfel
ne putem aştepta la următorul comportament:

?- var(X).
yes
?- var(23).
no
?- X = Y, Y = 23, var(X).
no

nonvar(X)
Scopul nonvar(X) reuşeşte dacă X nu este în acel moment o variabilă neiniţializată.
Predicatul nonvar este în consecinţă opusul predicatului var. Într-adevăr, el poate fi scris
în Prolog prin:

45
nonvar(X):-var(X),!,fail.
nonvar(_).

atom(X)
Scopul atom(X) reuşeşte dacă X înlocuieşte în acel moment un atom Prolog. Drept
rezultat, are loc următorul comportament:

integer(X)
Scopul integer(X) reuşeşte dacă X înlocuieşte în acel moment un întreg

atomic(X)
Scopul atomic(X) reuşeşte dacă X înlocuieşte în acel moment fie un întreg, fie un
atom. Predicatul atomic poate fi definit prin predicatele atom şi integer astfel

atomic(X):-atom(X).
atomic(X):-integer(X).

1.25 Tratarea clauzelor ca termeni

Prolog permite programatorului să examineze şi să modifice programul (clauzele ce


sunt utilizate pentru a satisface scopurile sale). Aceasta este simplu în particular, deoarece o
clauză poate fi văzută ca o structură Prolog obşnuită. În consecinţă, Prolog furnizează
predicate predefinite pentru a permite programatorului să:
 Să construiască o structură ce reprezintă o clauză într-o bază de date;
 Să adauge o clauză, reprezentată printr-o structură dată, la o bază de date;
 Să elimine o clauză, reprezentată printr-o structură dată, dintr-o bază de date.
Majoritatea operaţiilor asupra bazelor de date pot fi realizate prin folosirea acestor predicate,
împreună cu operaţiile Prolog obişnuite de construire şi descompunere a structurilor. Înainte
de a studia predicatele predefinite relevante, este important să vedem modul în care o clauză
Prolog poate fi văzută ca o structură.
Regula, pe de altă parte, poate fi văzută ca o structură al cărui operator principal este
“:-”, cu două argumente. Acest operator este declarat ca un operator infix. Primul argument
este antetul clauzei iar al doilea este corpul ei.
În final, când există mai mult de un scop în regulă, scopurile sunt considerate legate
împreună de către functorul “,” (cu două argumente). Acesta este declarat de asemenea ca un
operator infix.
În acest caz acestea sunt predicate ce permit programatorului să examineze şi să
modifice clauzele.

listing(A)
Satisfacerea unui scop de forma listing(A), unde A este iniţializat cu un atom
determină ca toate clauzele care au atomul drept predicat să fie scrise, în sensul sistemului
Prolog, în fişierul curent de ieşire. Acesta este modul în care se verifică ce clauze sunt folosite
în mod curent pentru un anume predicat. Formatul exact al ieşirii va depinde de
implementarea sistemului Prolog. Să observăm că, se vor vedea toate clauzele în care acel
atom este predicat, fără a ţine seama de cît de multe argumente are. Folosirea scopului
listing poate fi utilă în descoperirea unei greşeli dintr-un program.

46
clause(X,Y)
Satisfacerea unui scop de forma clause(X,Y) determină ca X şi Y să fie identificate
cu antetul şi corpul unei clauze existente în baza de date. Când se face o încercare de a
satisface scopul, X trebuie să fie iniţializat astfel încât predicatul principal al clauzei să fie
cunoscut. Dacă nu există clauze pentru predicat, atunci scopul eşuează. Dacă există mai mult
de o clauză ce se potriveşte, Prolog o va alege pe prima. În acest caz, dacă se face o încercare
de a resatisface scopul, celelalte clauze care corespund vor fi pierdute, câte una la un moment
dat.
Să reţinem că, deşi scopul clause are întotdeauna un argument pentru corpul
clauzei, nu fiecare clauză are întotdeauna un corp. Dacă o clauză nu are corp, se consideră că
are corpul true. Vom numi astfel de clauze “fapte”. Prin furnizarea parametrilor X şi Y
iniţializaţi sau nu, se pot urmări toate clauzele pentru un predicat dat şi numărul de argumente,
sau toate clauzele care se potrivesc cu un anumit şablon. Predicatul clause este foarte
important dacă dorim să construim programe ce examinează sau execută alte programe.

asserta(X), assertz(X)
Cele două predicate predefinite asserta şi assertz permit adăugarea de noi
clauze la baza de date. Cele două predicate acţionează exact în acelaşi mod, exceptând faptul
că asserta adaugă o clauză la începutul bazei de date, în timp ce assertz adaugă o
clauză la sfârşit. Această convenţie poate fi uşor reţinută deoarece a este prima literă a
alfabetului iar z este ultima. În scopul asserta(X), X trebuie să fie deja instanţiat cu ceva
ce reprezintă o clauză; într-adevăr, ca şi pentru clauze, este suficient să fie făcută iniţializarea
astfel încât să fie cunoscut predicatul principal.
Este important de reţinut că acţiunea de adăugare a unei clauze la baza de date nu este
reversibilă atunci când are loc revenirea. În consecinţă, odată ce am utilizat asserta sau
assertz pentru a adăuga o clauză nouă, acea clauză va fi înlăturată doar dacă facem explicit
acest lucru (folosind retract).

retract(X)
Predicatul predefinit retract permite unui program să înlăture clauze din baza de
date. Predicatul are un singur argument, reprezentând un termen care trebuie să se potrivească
cu clauza. Termenul trebuie să fie suficient iniţializat astfel încât să poată fi determinat
predicatul clauzei (la fel ca pentru asserta, clause, etc). Când se încearcă să se satisfacă
scopul retract(X), X este identificat cu prima clauză din baza de date care se potriveşte, şi
acea clauză este înlăturată. Când se face o încercare de resatisfacere a scopului, Prolog
continuă căutarea acestei clauze, căutând alta care se potriveşte. Dacă găseşte una, se întâmplă
acelaşi lucru ca mai înainte. Dacă se face o încercare de resatisfacere a scopului, căutarea
continuă pentru o altă clauză corespunzătoare, şi aşa mai departe. Să reţinem că, odată ce o
clauză a fost înlăturată ea nu mai este niciodată refăcută, chiar şi în cazul în care
backtracking-ul încearcă să resatisfacă scopul retract. Dacă la un moment dat căutarea nu
mai poate găsi nici o clauză care să corespundă, scopul eşuează.
Deoarece argumentul X corespunde cu o clauză care va fi înlăturată, este posibil să
vedem exact ce clauză a fost înlăturată, chiar dacă X indică un obiect cu mai multe variabile
neiniţializate în el. Astfel cineva poate utiliza scopul retract pentru a duplica func ionarea
lui clause, în cazul în care se doreşte înlăturarea clauzei după găsirea ei.
1.26 Crearea şi accesul componentelor unei structuri
În mod normal, atunci când dorim să accesăm o structură de un anumit tip într-un
program Prolog, realizăm acest lucru prin “menţionarea” structurii. Astfel, dacă un predicat
47
are nevoie să lucreze cu o varietate de tipuri diferite de structuri ce apar în calitate de
argument, în mod normal furnizăm doar o clauză separată pentru fiecare tip de structură.
În anumite programe nu putem anticipa toate structurile care pot apare. Elementul
esenţial este că dorim ca acest program să lucreze cu orice tip de structură pe care i-o
furnizăm. Bineînţeles, o posibilitate este de a furniza o clauză pentru fiecare operator pe care
este posibil să-l creem. Dar aceasta este o sarcină pe care nu o vom termina niciodată,
deoarece în anumite programe ar putea exista o infinitate de operatori. Modalitatea de a scrie
un astfel de program este de a folosi predicate predefinite ce realizează operaţii pe structuri
arbitrare. Vom descrie acum câteva dintre acestea predicatele functor, arg şi “=..”. De
asemenea vom descrie un predicat ce lucrează cu atomi, predicatul name.

functor(T,F,N)
Predicatul functor este definit astfel încât functor(T,F,N) înseamnă “T este o
structură care are operatorul F şi numărul de argumente N”. El poate fi utilizat în principiu
în două moduri. În prima modalitate, T este deja iniţializat. Scopul eşuează dacă T nu este un
atom sau o structură. Dacă T este un atom sau o structură, F corespunde operatorului iar N
corespunde cu un întreg egal cu numărul de argumente al operatorului. Să reţinem că în acest
context un atom este considerat a fi o structură cu numărul de argumente egal cu zero.
Trebuie să considerăm o a doua utilizare posibilă a lui functor. Aceasta are loc
atunci când primul argument al scopului (T) este neiniţializat. În acest caz, celelalte două
argumente trebuie să fie iniţializate specificând operatorul şi respectiv numărul de
argumente. Un scop de această formă va reuşi întotdeauna şi ca rezultat T va deveni iniţializat
cu o structură având operatorul şi numărul de argumente furnizate. Acesta este modul de
construire a structurilor arbitrare, dată prin specificarea operatorului şi numărului său de
argumente. Argumentele unei astfel de structuri construită cu ajutorul predicatului functor
are variabile neiniţializate. De aceea structura va corespunde cu orice altă structură având
acelaşi operator şi număr de argumente.

arg(N,T,A)
Predicatul arg trebuie utilizat întotdeauna cu primele două argumente iniţializate. El
este folosit pentru a accesa un argument particular al unei structuri. Primul argument al
predicatului arg specifică ce argument este cerut. Al doilea specifică structura în care va fi
găsit argumentul. Prolog găseşte argumentul corespunzător şi apoi încearcă să-l potrivească
cu al treilea argument. Astfel arg(N,T,A) reuşeşte dacă cel de-al N-lea argument al lui T
este A.
Predicatele functor şi arg furnizează o modalitate de creare şi accesare a
argumentelor unor structuri arbitrare. Predicatul “=..” (pronunţat “univ” din motive istorice)
furnizează o modalitate alternativă, care este utilă dacă se doreşte obţinerea împreună a
tuturor argumentelor unei structuri, sau dacă se doreşte construirea unei structuri după o listă
de argumente. Scopul X=..L semnifică “L este lista constând din operatorul X urmat de
argumentele lui X”. Un astfel de scop poate fi folosit în două moduri, aceleaşi în care poate fi
folosit scopul functor. Dacă X este iniţializat, Prolog construieşte lista corespunzătoare şi
încearcă să o potrivească cu L. Pe de altă parte, dacă X este neiniţializat, lista va fi folosită
pentru a construi o structură corespunzătoare care să corespundă lui X. În acest caz, antetul lui
L trebuie să fie un atom (el va deveni operatorul lui X).

48
name(A,L)
În timp ce predicatele functor, arg şi =.. sunt utilizate pentru construirea şi
accesarea structurilor arbitrare, predicatul name se ocupă cu atomi arbitrari. Predicatul name
leagă un atom de o listă de caractere (coduri ASCII). Aceasta poate fi utilă fie pentru a găsi
caracterele unui atom dat, fie pentru a găsi atomul care are date anumite caractere. Scopul
name(A,L) semnifică faptul că, “caracterele pentru atomul A sunt membrii ai listei L”.
Dacă argumentul A este iniţializat, Prolog crează o listă de caractere şi încearcă să le
potrivească cu L. În caz contrar, Prolog utilizează lista L pentru a realiza un atom pentru a-l
înlocui pe A.
1.27 Modificarea comportamentului la backtracking
Există două predicate predefinite ce modifică secvenţa normală de evenimente care au
loc pe durata revenirii. În principiu, “!” înlătură posibilităţile de resatisfacere a scopurilor, iar
repeat oferă noi alternative care nu existau înainte.

!
Simbolul “ tăietura ” poate fi considerat ca un predicat predefinit ce impune
sistemului Prolog anumite posibilităţi pe care le are. Pentru mai multe detalii despre “ tăietura
” vezi capitolul 4.

repeat
Predicatul predefinit repeat este furnizat ca o modalitate suplimentară de a genera
soluţii multiple cu ajutorul backtracking-ului. Deşi el este predefinit, poate fi gândit ca având
definiţia următoare:

repeat.
repeat:-repeat.
O problemă care apare cu scopul repeat este aceea că întotdeauna are o soluţie de
refăcut atunci când backtracking-ul o reconsideră. Astfel, backtracking-ul nu va fi niciodată
capabil să reconsidere alternativele alese mai devreme de ultimul apel al scopului repeat,
cu excepţia cazului când gestionăm anularea alegerii printr-un anume mod. Datorită acestui
lucru, definiţia de mai sus trebuie rescrisă astfel:

1.28 Construirea de scopuri compuse

În regulile şi întrebările de forma X:-Y sau ?-Y, termenul care apare drept Y poate
consta dintr-un singur scop, o conjuncţie de scopuri sau o disjuncţie de scopuri. Mai mult, este
posibil să avem variabile drept scopuri şi să satisfacem un scop în cazul în care el eşuează
folosind not. Predicatele descrise în această secţiune furnizează modalităţi de specificare a
acestor căi complicate de exprimare a scopurilor.

X,Y
Operatorul ”,” specifică o conjuncţie de scopuri. Acest operator a fost introdus în
capitolul 1. Dacă X şi Y sunt scopuri, scopul X,Y reuşeşte dacă X reuşeşte şi dacă Y reuşeşte.
Dacă X reuşeşte şi apoi Y eşuează, atunci se face o încercare de resatisfacere a lui X. Dacă X
eşuează, atunci întreaga conjuncţie eşuează. Aceasta este esenţa backtracking-ului. Operatorul
”,” are o declaraţie încorporată ca un operator infix asociativ la dreapta, astfel încât X,Y,Z
este echivalentă cu X,(Y,Z).

49
X;Y
Operatorul ”;” specifică o disjuncţie (cu înţeles de sau) de scopuri. Dacă X şi Y sunt
scopuri, atunci scopul X;Y reuşeşte dacă X reuşeşte sau dacă Y reuşeşte. Dacă X eşuează,
atunci se face o încercare de satisfacere a lui Y. Dacă Y eşuează apoi, atunci întreaga
disjuncţie eşuează. Putem folosi operatorul “;” pentru a exprima alternative în cadrul
aceleiaşi clauze.

call(X)
Se presupune că X este iniţializat cu un termen care poate fi interpretat ca un scop.
Scopul call(X) reuşeşte dacă o încercare de satisfacere a lui X reuşeşte. Scopul call(X)
eşuează dacă o încercare de satisfacere a lui X eşuează. La prima vedere, acest predicat poate
părea redundant, deoarece cineva s-ar putea întreba de ce argumentul scopului call nu poate
pur şi simplu să apară el însuşi drept scop?

not(X)
Se presupune că X este iniţializat cu un termen care poate fi interpretat ca un scop.
Scopul not(X) reuşeşte dacă o încercare de satisfacere a lui X eşuează. Scopul not(X)
eşuează dacă o încercare de satisfacere a lui X reuşeşte. În acest fel, not se aseamănă cu
call, exceptând faptul că succesul sau eşecul argumentului, interpretat ca un scop, este
inversat.

1.29 Egalitate
Această secţiune se ocupă pe scurt cu diverse predicate predefinite pentru testarea
egalităiţii în Prolog.

X=Y
Când Prolog întâlneşte scopul X=Y, el încearcă să facă pe X şi Y egale prin potrivirea
lor împreună. Dacă le poate potrivi, scopul reuşeşte (atât X cât şi Y pot deveni acum mai
iniţializate). În caz contrar scopul eşuează. O discuţie mai completă despre acest predicat este
dată în secţiunea 2.4. Predicatul de egalitate este definit prin

X=X.

X\=Y
Predicatul “X\=Y” este opusul predicatului “=” în termeni de succes şi eşec. Astfel,
X\=Y reuşeşte dacă X=Y eşuează şi invers. Dacă scopul X\=Y reuşeşte (X şi Y nu pot fi
potrivite), iniţializările lui X şi Y nu vor fi deloc schimbate.

X == Y
Predicatul “==” reprezintă un test de egalitate mult mai strict decât “=”. Astfel, dacă
X==Y reuşeşte atunci şi X=Y reuşeşte tot atât de bine. Pe de altă parte, reciproca nu este
adevărată. Modalitatea prin care “==” este mult mai strictă este dată de modul în care se
consideră variabilele. Predicatul “=” va considera o variabilă neiniţializată ca fiind egală cu
orice altceva, deoarece se va potrivi oricum. Pe de altă parte, “==” va considera doar că o
variabilă neiniţializată este egală cu o altă variabilă neiniţializată care este deja partajată cu ea.
În caz contrar testul va eşua.

50
X\==Y
Acest predicat este pentru “==” acelaşi lucru cum este “\=” pentru “=”. Astfel, un
scop implicând acest predicat va reuşi exact atunci când acelaşi scop pentru “==” va eşua şi
invers.
1.30 Intrări şi ieşiri
Predicatele ce sunt disponibile pentru citirea şi scrierea caracterelor şi termenilor au
fost descrise în capitolul 5. Acum le prezentăm pe scurt pe fiecare.

get0(X)
Acest scop reuşeşte dacă X poate fi potrivit cu următorul caracter întâlnit din şirul
curent de intrare. Scopul get0 reuşeşte doar o dată (el nu poate fi resatisfăcut). Operaţia de
mutare a următorului caracter nu este refăcută la backtracking, deoarece nu exită nici o
modalitate de a pune caracterul înapoi în şirul de intrare curent.

get(X)
Acest scop reuşeşte dacă X poate fi potrivit cu următorul caracter afişabil întâlnit în
şirul de intrare curent. Caracterele afişabile au un cod ASCII care este mai mare decât 32.
Orice caracter neafişabil este ignorat. Scopul get reuşeşte doar o dată (el nu poate fi
resatisfăcut). Operaţia executată de get nu este refăcută la backtracking, deoarece nu exită
nici o modalitate de a pune un caracter înapoi în şirul de intrare curent.

skip(X)
Acest scop citeşte şi ignoră caracterele din şirul curent de intrare până când este găsit
un caracter care se potriveşte cu X. Scopul skip reuşeşte doar o dată.

read(X)
Acest scop citeşte următorul termen din şirul curent de intrare şi îl potriveşte cu X. Un
scop read reuşeşte doar o dată. Termenul trebuie să fie urmat de un punct “.”, care nu este
parte a termenului, şi cel puţin un caracter neafişabil. Punctul este înlăturat din şirul de intrare
curent.

put(X)
Acest scop scrie întregul X ca un caracter în şirul de ieşire curent. Scopul put reuşeşte
doar o dată. Dacă X nu este iniţializat are loc o eroare.

nl
Scrie o secvenţă de control în şirul de ieşire curent ce determină o “linie nouă”. Pe
displayul unui calculator, după folosirea scopului nl toate caracterele apar pe următoarea
linie a paginii. Scopul nl reuşeşte doar o dată.

tab(X)
Scrie o cantitate de X “spaţii“ în şirul de ieşire curent. Are loc o eroare dacă X nu este
iniţializat. Scopul tab reuşeşte doar o dată.

write(X)
Acest scop scrie termenul X în şirul de ieşire curent. Scopul write reuşeşte doar o
dată. Orice variabilă neiniţializată din X este scrisă ca un număr unic de variabilă precedat cu
un “_”, cum ar fi “_239”. Variabilele partajate în cadrul aceluiaşi argument pentru write

51
au acelaşi număr la afişare. Predicatul write ţine cont de declaraţiile operatorului curent
când afişează un termen. De exemplu un operator infix va fi afişat între argumentele sale.

display(X)
Predicatul display lucrează exact în acelaşi mod ca şi write exceptând faptul că
ignoră orice declaraţii de operator. Când este utilizat display, orice structură este afişată
având mai întâi operatorul urmat de argumentele sale în paranteză.

op(X,Y,Z)
Aceast scop declară un operator având clasa de precedenţă X, poziţia şi asociativitatea
Y, şi numele Z. Specificarea poziţiei şi asociativităţii este preluată din următoarele seturi de
atomi:

fx fy xf yf xfx xfy yfx yfy

Dacă declaratia operatorului este legală atunci scopul op va reuşi. Vezi secţiunea 5.5.
pentru mai multe detalii.
1.31 Tratarea fişierelor
Predicatele de care dispune Prolog pentru modificarea şirurilor curente de intrare şi
ieşire pentru fişiere au fost prezentate în capitolul 5. Aici prezentăm pe scurt pe fiecare din
ele.

see(X)
Acest scop deschide fişierul X, dacă nu este deja deschis şi defineşte şirul curent de
intrare ca având sursă fişierul X. Dacă X nu este iniţializat sau dacă numele variabilei X nu
reprezintă un fişier existent, are loc o eroare.

seeing(X)
Acest scop reuşeşte dacă numele şirului de intrare curent se potriveşte cu X, şi eşuează
în caz contrar.

seen
Acest scop închide şirul de intrare curent, şi defineşte şirul de intrare curent ca fiind
tastatura terminalului (calculatorului).

tell(X)
Acest scop deschide fişierul X, dacă nu este deja deschis şi defineşte şirul de ieşire
curent pentru scriere în fişier. Dacă X nu este iniţializat are loc o eroare. Mai întâi tell este
utilizat asupra unui fişier care nu este deja deschis, dacă X denumeşte un fişier care nu există,
atunci este creat un fişier cu acel nume. În caz contrar, dacă X denumeşte un fişier care
există, atunci conţinutul anterior al fişierului este distrus.

telling(X)
Acest scop reuşeşte dacă X corespunde cu numele şirului de ieşire curent, şi eşuează în
caz contrar.

told
Acest scop închide şirul curent de ieşire, determinând ca un marker de sfârşit de fişier
să fie scris în fişier. Şirul curent de ieşire redevine displayul calculatorului.
52
1.32 Evaluarea expresiilor aritmetice
Expresiile aritmetice au fost discutate mai întâi în secţiunea 2.5. În această secţiune
vom prezenta pe scurt folosirea predicatului “is”, şi ce operatori sunt disponibili pentru
construirea expresiilor aritmetice.

X is Y
Y trebuie să fie iniţializat cu o structură ce poate fi interpretată ca o expresie aritmetică
aşa cum este descrisă în secţiunea 2.4. Mai întâi, structura iniţializată pentru Y este evaluată
pentru a furniza un întreg, denumit rezultat. Rezultatul este comparat cu X, şi predicatul is
reuşeşte sau eşuează în funcţie de rezultatul comparării. Operatorii pot fi folosiţi pentru a
realiza structuri diferite de predicatul is, după cum urmează:

X+Y
Este operator de adunare. Când este evaluat cu ajutorul predicatului is, rezultatul său
este suma aritmetică a celor două argumente ale sale. Argumentele trebuie să fie iniţializate cu
întregi sau cu structuri care sunt evaluate drept întregi.

X-Y
Este operator de scădere. Când este evaluat cu ajutorul predicatului is, rezultatul său
este diferenţa aritmetică a celor două argumente ale sale. Argumentele trebuie să fie
iniţializate cu întregi sau cu structuri care sunt evaluate drept întregi.

X*Y
Este operator de înmulţire. Când este evaluat cu ajutorul predicatului is, rezultatul său
este produsul aritmetic a celor două argumente ale sale. Argumentele trebuie să fie iniţializate
cu întregi sau cu structuri care sunt evaluate drept întregi.

X/Y
Este operator de împărţire întreagă. Când este evaluat cu ajutorul predicatului is,
rezultatul său este câtul întreg a celor două argumente ale sale. Argumentele trebuie să fie
iniţializate cu întregi sau cu structuri care sunt evaluate drept întregi.

X mod Y
Este operator modulo întreg. Când este evaluat cu ajutorul predicatului is, rezultatul
său este restul întreg care este generat atunci când X este împărţit cu Y. Argumentele trebuie
să fie iniţializate cu întregi sau cu structuri care sunt evaluate drept întregi.
Anumite implementări particulare de Prolog pot include mai multe operaţii aritmetice,
cum ar fi exponenţierea. Exemplele arătate în această carte necesită doar pe cele arătate mai
sus.
1.33 Compararea numerelor
Prolog furnizează şase predicate pentru compararea numerelor (întregi). Aceste
predicate au fost prezentate mai întâi în secţiunea 2.5. unde am discutat aritmetica. Fiecare
predicat este descris ca un operator infix având două argumente.

X = Y
Predicatul de egalitate, descris în secţiunea 6.8, reuşeşte întotdeauna atunci când cele
două argumente de tip întreg sunt aceleaşi.

53
X /= Y
Predicatul de inegalitate, descris şi el în secţiunea 6.8, reuşeşte atunci când cele două
argumente ale sale nu reprezintă acelaşi întreg.

X < Y
Predicatul mai mic reuşeşte când argumentul întreg din membrul stâng este mai mic
decât argumentul întreg din membrul drept. Ambele argumente trebuie să fie iniţializate.

X > Y
Predicatul mai mare reuşeşte când argumentul întreg din membrul stâng este mai
mare decât argumentul întreg din membrul drept. Ambele argumente trebuie să fie iniţializate,
altfel are loc o eroare.

X >= Y
Predicatul mai mare sau egal reuşeşte când argumentul întreg din membrul
stâng este mai mare sau egal decât argumentul întreg din membrul drept. Ambele argumente
trebuie să fie iniţializate.

X =< Y
Predicatul mai mic sau egal reuşeşte când argumentul întreg din membrul stâng
este mai mic sau egal decât argumentul întreg din membrul drept. Ambele argumente trebuie
să fie iniţializate. Să reţinem faptul că predicatul se scrie “=<” şi nu “<=”, astfel încât “<=”
este liber pentru a fi utilizat ca un alt operator.
1.34 Urmărirea Prolog-ului în lucru
Această secţiune descrie predicatele predefinite ce permit urmărirea programelor pe
timpul execuţiei lor. În continuare vom descrie sumar aceste predicate predefinite, urmând ca
în capitolul 8 să fie studiat mai în detaliu depanarea şi trasarea execuţiei programelor.

trace
Efectul de a satisface scopul trace este de a executa o urmărire exhaustivă. Aceasta
înseamnă că din acest moment se poate urmări fiecare scop pe care îl generează programul, în
fiecare din cele patru porturi principale.

notrace
Efectul scopului notrace este de a opri urmărirea exhaustivă din momentul apelării
ei. Totuşi, este continuată orice urmărire datorită prezenţei punctelor de vizualizare.

spy P
Predicatul spy este utilizat atunci când dorim să acordăm o atenţie specială scopurilor
ce implică anumite predicate specifice. Acest lucru se poate realiza prin setarea punctelor de
vizualizare în cadrul lor. Predicatul este definit ca un operator prefix, astfel încât nu este
necesar să se pună paranteze în jurul argumentului. Argumentul poate fi unul din următoarele:
- Un atom. În acest caz, punctul de vizualizare este pus în toate predicatele ce
utilizează acest atom; totuşi sunt utilizate mai multe argumente.
- O structură de forma Nume/Dimensiune, unde Nume este un atom iar
Dimensiune este un întreg.
- O listă. În acest caz, lista trebuie să fie terminată cu “[]”, şi fiecare element al listei

54
trebuie să fie el însuşi un argument permis predicatului spy. Prolog va pune puncte de
vizualizare în toate locurile specificate în listă.

debugging
Predicatul predefinit debugging permite aflarea tuturor punctelor de vizualizare
care sunt setate în mod curent. Lista punctelor de vizualizare este afişată ca un efect lateral al
satisfacerii scopului debugging.

nodebug
Scopul nodebug determină înlăturarea tuturor punctelor de vizualizare curentă.

nospy
Ca şi operatorul spy, nospy este un operator de tip prefix. Acest operator este mult
mai selectiv decât nodebug, deoarece se poate specifica cu exactitate ce puncte de
vizualizare trebuie să fie înlăturate. Acest lucru se poate face prin furnizarea unui argument în
exact aceeaşi formă ca şi pentru predicatul spy.

55
LECŢIA 6
EXEMPLE DE PROGRAME

Fiecare secţiune a acestui capitol tratează o aplicaţie particulară a programării în


Prolog. Sugerăm parcurgerea tuturor secţiunilor acestui capitol. Nu vă faceţi probleme dacă
nu înţelegeţi scopul programului deoarece nu sunteţi la curent cu aplicaţia respectivă. Ceea ce
este important este înţelegerea tehnicilor de programare disponibile în Prolog, indiferent de o
aplicaţie particulară.
Sperăm că am inclus suficiente aplicaţii pentru a satisface cele mai multe exigenţe.
Normal, toate aceste aplicaţii lucrează cu arii care sunt specifice modului în care Prolog îşi
reprezintă lumea exterioară. Din păcate, scopurile unei cărţi ca aceasta fac imposibilă discuţia
programelor mai mari de o pagină de text, programe care fac obiectul unei audienţe mai mari
la specialişti.

6.1. Căutarea în labirint

Este o noapte întunecoasă şi cu o furtună puternică. Deoarece conduceţi maşina pe un


drum lăturalnic, şi aceasta s-a defectat, opriţi în faţa unui castel splendid. Mergeţi la uşă, o
găsiţi deschisă şi începeţi căutarea unui telefon. Cum căutaţi în castel fără să vă pierdeţi, şi să
ştiţi că aţi căutat în toate camerele? De asemenea, care este cea mai scurtă cale către telefon?
Acestea sunt pericolele pentru care a fost proiectat acest model.
În multe programe, cum ar fi cele pentru căutarea în labirint, este utilă păstrarea listei
cu informaţii şi căutarea în listă atunci când este necesară o informaţie într-un anumit
moment. De exemplu, dacă am decis să căutăm telefonul în castel, este nevoie să păstrăm o
listă cu numărul camerelor vizitate anterior astfel încât să nu intrăm într-o vizită ciclică în
anumite camere. Pentru aceasta notăm numărul camerelor vizitate pe o hârtie. Înainte să
intrăm în cameră verificăm dacă numărul acesteia este pe listă. Dacă acest lucru se întâmplă
ignorăm camera deoarece a fost vizitată anterior. Dacă nu este în listă mai întâi scriem
numărul în listă şi apoi intrăm în cameră. Procesul se continuă până la găsirea telefonului.
Sunt câteva rafinamente ce se pot face la metodă, care vor fi prezentate atunci când vom
discuta căutarea în grafuri. Mai întâi însă să scriem în ordine paşii, pentru a şti ce probleme
avem de rezolvat:

1. Mergeţi la uşa fiecărei camere;


2. Dacă numărul camerei este în listă, ignoraţi camera şi reveniţi la pasul 1.
Dacă din camera în care am ajuns nu putem intra în alte camere, atunci revenim în
camera anterioară din care am intrat în camera curentă pentru a căuta o nouă cale;
3. Altfel adaugă numărul camerei în listă;
4. Caută în camera respectivă telefonul;
5. Dacă nu este, revin-o la pasul 1. Altfel stop, iar în listă se află calea pe care
trebuie să o urmăm pentru a ajunge la camera corectă.

Vom presupune că numerele camerelor sunt constante, dar nu contează dacă acestea
sunt integer sau atom. Mai întâi, putem rezolva problema căutării numerelor de cameră din
listă folosind predicatul membru definit în secţiunea 3.3, considerând bucata de hârtie ca
listă. Acum putem trata problema căutării în labirint. Iată un mic exemplu în care avem un
etaj de casă, în care camerele sunt etichetate cu litere astfel:

56
Observaţi că orificiile din pereţi sunt uşile iar spaţiul din afara casei este reprezentat ca
fiind camera a. Sunt uşi între camerele a-b, c-d, f-e, şi aşa mai departe. Faptele care
arată unde sunt uşi pot fi reprezentaţi în Prolog astfel:

d(a,b) .
d(b,e) .
d(b,c) .
d(d,e) .
d(c,d) .
d(e,f) .
d(g,e) .

Observaţi că informaţiile referitoare la uşi nu sunt redundante. De exemplu, deşi există


uşa între camerele g şi e nu am reprezentat ca fiind uşă între e şi g: deoarece nu există
d(e,g). Sau, putem face ca programul să recunoască faptul că fiecare fapt uşă poate fi
interpretat pe două căi. Aceasta este alternativa folosită în programul ce urmează.
Pentru a merge dintr-o cameră în alta trebuie să recunoaştem unul din următoarele
două cazuri:
 suntem în camera în care dorim sau
 intrăm pe uşă şi revenim în situaţia descoperirii celor două cazuri (recursiv).
Considerăm scopul trece(X,Y,T), care precizează dacă se poate trece din camera
X în camera Y. Al treilea argument T este lista pe care o avem, care dă şirul camerelor care au
fost vizitate anterior .
Condiţia limită de trecere din camera X în camera Y este să ne aflăm deja în camera Y
(adică, dacă X=Y). Aceasta este reprezentată sub forma clauzei:

trece(X,X,T).

Pe de altă parte, vom alege câteva camere intermediare, numite Z, şi vedem dacă am
fost în ele anterior. Dacă nu am fost, atunci vom trece din Z în Y, adăugând Z la listă. Toate
acestea se reprezintă prin următoarele clauze:

trece(X,Y,T):-
d(X,Z),not(membru(Z,T)),trece(Z,Y,{Z|T}).

Ceea ce în cuvinte poate fi redată astfel:


Pentru a merge din X în Y fără a trece prin camerele din T, găseşte o uşă d care
face legătura între X şi o cameră oarecare (Z), asigură-te că Z nu este deja în listă, şi mergi
din Z către Y folosind lista T la care adaugi Z.
57
Sunt trei căi care pot duce la eşec folosind această regulă. Prima, dacă X este izolată
(nu are legătură cu o altă cameră). A doua, dacă uşa aleasă este în listă. A treia, dacă nu putem
merge din Z în Y atunci eşecul se va regăsi în decursul recursivităţii. Dacă primul scop
d(X,Z) eşuează, atunci acesta va determina eşecul schemei. La nivelul cel mai de sus (nu
într-un apel recursiv) aceasta înseamnă că între X şi Y nu există cale. La nivelul cel mai de jos,
înseamnă că trebuie să revenim şi să găsim o altă uşă.
Programul prezentat tratează uşile ca fiind inversabile. Dacă presupunem că având o
uşă ce dă din camera a în camera b, aceasta este acelaşi lucru ca şi când am avea uşă din b
către a, acum va trebui să facem asta explicit, aşa cum s-a indicat mai sus. În schimbul
realizării unui duplicat pentru fiecare factor d însă cu argumentele inverse, sunt alte două căi
pentru a pune aceste informaţii în program. Cea mai evidentă cale este prin a adăuga o nouă
regulă, dând:

trece(X,X,T).
trece(X,Y,T):-
d(X,Z),not(membru(Z,T)),trece(Z,Y,[Z|T]).
trece(X,Y,T):-
d(Z,X),not(membru(Z,T)),trece(Z,Y,[Z|T]).

Sau se poate folosi predicatul “ ; ”(pentru disjuncţie):

trece(X,X,T).
trece(X,Y,T):-
(d(X,Z);d(Z,X)).
not(membru(Z,T)).
trece(Z,Y,[Y|T]).

Acum pentru a găsi telefonul: considerăm scopul are_telefon(X) care este


adevărat dacă în camera X este telefonul. Dacă dorim să oferim că în camera g se află telefon,
vom face asta prin înscrierea în baza de date a are_telefon(g). Presupunând că plecăm
din camera a, o întrebare posibilă pe care o punem pentru a determina calea către telefon este:

? - trece(a,X,[ ]),are_telefon(X).

Această întrebare este o “generare şi testare” , pentru găsirea unei posibile camere,
care are telefon. O altă cale este de a satisface are_telefon(X) primul, atunci când trecem
din camera a în X :

? - are_telefon(X),trece(a,X,[ ]).

Această metodă este mult mai eficientă, dar implică cunoaşterea unde se află telefonul
înainte de a începe căutarea. Iniţializând al treilea argument cu o listă vidă aceasta înseamnă
că la început vom avea o listă vidă. Aceasta poate fi schimbată astfel încât să producă
variante: întrebarea “Găsiţi telefonul fără să intraţi în camerele d şi f ” poate fi exprimată în
Prolog astfel:

?-are_telefon(X), trece(a,X,[d,f]).

58
6.2. Turnurile din Hanoi

Turnurile din Hanoi este un joc ce se joacă cu trei axe şi un set de discuri. Discurile
sunt gradate în diametru, şi ca să intri pe ax fiecare disc are în centru o gaură. Iniţial toate
discurile sunt pe axul din stânga. Scopul jocului este să muţi toate discurile pe axul central.
Axul din dreapta poate fi folosit ca ax de schimb, un loc temporar pentru discuri. De fiecare
dată un disc este mutat de la un pol la altul; două “lucruri” trebuie avute în vedere: numai
discul din vârful axului poate fi mutat şi un disc cu diametrul mai mare nu poate fi pus peste
un disc cu diametrul mai mic.

Mulţi oameni care au jucat acest joc n-au descoperit o strategie simplă şi rapidă ca să
joace corect jocul “Turnurile din Hanoi” cu trei axe şi N discuri. Vă scutim de efortul de a
descoperi relevând aici:
 condiţia limită se întâmplă atunci când nu avem discuri pe axul sursă (axul
din stânga).
 mutaţi N-1 discuri de la axul sursă la axul de rezervă (din dreapta) folosind
destinaţia ca “temporar”. Observaţi că aceasta este o mişcare recursivă.
 mutaţi un singur disc de la polul sursă la polul destinaţie.
 în final, mutaţi N-1 discuri de pe polul de rezervă la destinaţie, folosind
sursa ca rezervă.
Programul Prolog ce implementează această strategie este definit după cum urmează.
Am definit un predicat hanoi având un argument, astfel că hanoi(N) înseamnă tipărirea
secvenţei mişcărilor când N discuri sunt pe polul sursă. Cele două clauze muta, prima este
condiţia limită descrisă mai sus şi a doua clauză implementează cazurile recursive, predicatul
muta are patru argumente: primul este numărul discurilor ce vor fi mutate. Celelalte trei
reprezintă axele care sunt: sursă, destinaţie şi rezervă pentru mutarea discurilor. Predicatul
inform foloseşte write pentru tipărirea numerelor axelor implicate în mutarea unui disc.

hanoi(N):- muta(N, stanga, centru, dreapta).


muta(0,-,-,-):-!
muta(N,A,B,C):-
M is N-1
muta(M,A,C,B), inform(A,B), muta(M,C,B,A).
inform(X,Y) :-
write([muta, discul, din, polul, X, in, polul,Y]).
nl.

59
6.3. Procesarea listelor

În această secţiune vom descrie câteva predicate de bază folosite în manipularea


listelor. Deoarece Prolog-ul face structurile de date arbitrare disponibile, listele nu vor avea un
rol prea mare aşa cum se întâmplă în alte limbaje de programare cum ar fi LISP şi POP-2.
Dacă programele vor folosi sau nu liste este important de înţeles cum lucrează predicatele,
deoarece ele folosesc principii ce pot fi aplicate la manipularea diferitelor structurii de date.
Găsirea ultimului element dintr-o listă: scopul ultim(X,L) reuşeşte dacă X este
ultimul element din lista L. Condiţia limită este când lista are un singur element. Aceasta este
prima regulă de controlat. A doua regulă reprezintă formele de caz recursiv.

ultim(X,[X]).
ultim(X,[_|Y]:-ultim(X,Y).
?-ultim(X,[caut, un, breloc]).
X=breloc

Verificarea elementelor consecutive: scopul consecutiv(X,Y,L) reuşeşte dacă


elementele X şi Y sunt elemente consecutive în lista L. Din cauza modului de lucru cu
variabilele, atât X, sau Y, sau amândouă pot fi neinstanţiate când o încercare este determinată
să satisfacă scopul. Prima clauză, care verifică condiţia limită trebuie să ţină cont că mai pot
exista elemente după X şi Y. Aceasta deoarece variabilele anonime apar la sfârşitul listei.

consecutiv(X,Y,[X,Y|_].
consecutiv(X,Y,[_|Z]):-consecutiv(X,Y,Z).

Adăugarea în liste: am văzut acest exemplu în secţiunea 3.6. scopul


adauga(X,Y,Z) arată că Z este o listă construită prin adăugarea lui Y după X. De
exemplu:

?-adauga([a,b,c],[d,e,f],Q).
Q=[a,b,c,d,e,f]

Scopul adauga este definit astfel:

?-adauga([ ],L,L).
adauga([X|L1], L2, [X|L3]):-adauga(L1,L2,L3).

Condiţia limită este atunci când primul argument este listă vidă. Aceasta deoarece
adăugând lista vidă la o listă, aceasta din urmă nu se schimbă. Mai mult, ne vom apropia
treptat de condiţia limită deoarece fiecare rechemare a lui adauga mută încă o dată un
element de la capul primului argument. Atenţie că oricare două argumente ale lui adauga
pot fi instanţiate, şi adauga va instanţia al treilea argument la rezultatul cel mai apropiat.
Această proprietate este adevărată pentru multe predicate definite în acest capitol. Datorită
flexibilităţii lui adauga, putem acum să definim alte câteva predicate astfel:

ultim(El,List):-adauga(_,[El],List).
consecutiv(El1,El2,List):-adauga(_,[El1,El2|_],List).
membru(El,List):-adauga(_,[El|_],List).

60
Inversarea unei liste: scopul invers_lista(L,M) reuşeşte dacă rezultatul
inversării elementelor din lista L este lista M. Programul utilizează un standard tehnic, unde
întoarcerea în listă înseamnă schimbarea primului element din listă cu ultimul. {i ce cale mai
bună de a muta ultimul element avem decât folosirea lui invers_lista ! Condiţia limită
este când primul argument este redus la o listă vidă, în care caz rezultatul este lista vidă.

invers_lista([ ], [ ]).
invers_lista([H|T],L):-
invers_lista(T,Z), adauga(Z,[H],L).

Atenţie că am inclus pe H în paranteze drepte în al doilea argument al lui adauga.


Aceasta deoarece H a fost selectat ca, cap al primului argument şi capul unei liste nu este
neapărat o listă. Prin convenţie coada unei liste este întotdeauna o listă. Pentru o
implementare mai eficientă a lui invers_lista, putem încorpora adăugarea în clauze
pentru invers_lista.

invers_lista(L1,L2):-invers_listaac(L1,[ ],L2).
invers_listaac([X|L],L2,L3):-
invers_listaac(L,[X|L2],L3),
invers_listaac([],L,L).

Al doilea argument al lui invers_listaac este folosit pentru a ţine “răspunsul


departe” cu alte cuvinte, un acumulator, introdus în secţiunea 3.7. Oricum, este descoperită o
nouă piesă( X) a răspunsului, acumulatorul nou trece la rezultatul programului şi acumulatorul
vechi este combinat cu noua piesă X. La sfârşit, ultimul acumulator este trimis înapoi pentru a
fi răspuns la scopul original.
Ştergerea unui element: Scopul scoate_X_din_Y(X,Y,Z) este mutarea primei
apariţii a lui X în lista Y, dând o nouă configuraţie lista Z. Dacă X nu este element în lista Y,
predicatul eşuează. Condiţia limită este când am găsit elementul. Altfel, ne întoarcem la coada
lui Y.

scoate_X_din_Y(A,[A|L],L):- !.
scoate_X_din_Y(A,[B|L],[B|M]):-
scoate_X_din_Y(A,L,M).

Este uşor a adăuga o clauză astfel încât predicatul să nu eşueze când al doilea
argument este redus la o listă vidă. Noua clauză care reprezintă noua condiţie limită este:

scoate_X_din_Y(_,[ ], [ ] ).

Ştergerea tuturor apariţiilor unui element: scopul sterge(X,L1,L2)


construieşte o listă L2 prin ştergerea tuturor elementelor X din lista L1. Condiţia limită este
când L1 este listă vidă, ceea ce înseamnă că am parcurs întreaga listă. Altfel, dacă X este în
listă, atunci rezultatul este coada listei, excepţie făcând cazul când ştergem din listă. Cazul
final este acela când am văzut altceva decât X în al doilea argument : atunci reluăm căutarea.

sterge(_,[ ],[ ]).


sterge(X,[X|L],M):- !, sterge(X,L,M)
sterge(X,[Y|L1],[Y,L2]):- sterge(X,L1,L2).

61
Substituirea: Aceasta este aproape similară cu sterge înlocuind ştergerea
elementului dorit cu inserarea altui element în locul lui. Scopul substituire(X,L,A,M)
va realiza construirea unei liste noi M făcută din elementele listei L, cu excepţia faptului că
orice apariţie a lui X va fi înlocuită de A. Sunt trei cazuri. Primul este chiar condiţia limită,
întocmai ca la sterge. Al doilea caz este când X este găsit în al doilea argument şi al treilea
caz este când se găseşte altceva decât X.

substituire(_, [ ],_,[ ] ).
substituire(X,[X|L],A,[A|M]):-!,
substituire(X,L,A,M).
substituire(X,[Y|L],A,[Y|M):-
substituire(X,L,A,M).
Subliste: Lista X este o sublistă a listei Y dacă fiecare parte din X apare şi în Y,
consecutiv şi în aceeaşi ordine. Următorul scop reuşeşte:
sublist([la,club],[lume,multa,la,club,astazi]).
Programul sublist necesită două predicate: unul care găseşte primul element care
se potriveşte şi unul care asigură că ceea ce rămâne din prima potrivire a primului argument
se potriveşte element cu element cu ceea ce rămâne din al doilea argument:

sublist([X|L],[X|M]):- prefix(L,M),!
sublist(L,[_|M]):- sublist(L,M).
prefix([ ],_).
prefix([X|L],[X|M]):-prefix(L,M).
Eliminarea duplicatelor: Predicatul elimin_duplicat şterge direct o listă de
orice elemente şi face o listă nouă. Deşi lista poate conţine elemente în duplicat la intrare, la
ieşire lista va conţine câte un exemplar din fiecare element. Scopul
elimin_duplicat(L,M) construieşte din lista L o nouă listă M în care dublurile dispar.
Definiţia foloseşte un predicat auxiliar duplicat_acum în care acumulatorul (vezi
secţiunea 3.7) este argument secund, iniţializat la lista vidă. Se foloseşte de asemenea
predicatul membru de la secţiunea 3.3.
elimin_duplicat(L,M):- duplicat_acum(L,[ ],M).
duplicat_acum([ ],A,A).
duplicat_acum([H|T],A,L):-membru(H,A),
duplicat_acum(T,A,L).
duplicat_acum([H|T],A,L):-
duplicat_acum(T,[H|A],L).

Predicatul duplicat_acum are trei clauze. Prima este condiţia limită, când lista de
intrare este vidă, rezultatul fiind trecut într-un acumulator. A doua clauză verifică dacă
următorul element din listă este un membru al listei acumulate. Dacă este, revenim simplu la
coadă, fără nici o schimbare a acumulatorului. Altfel, folosind următoarea clauză, revenim la
coada listei de intrare, cu un acumulator care are adăugat un nou element (H).
Maparea: o tehnică puternică este capacitatea de a converti o listă în altă listă prin
aplicarea unei funcţii fiecărui element al primei liste, folosind ca rezultate succesive
elementele aflate în cea de-a doua listă. Programul din capitolul 3, pentru schimbarea unei
propoziţii în alta, este un exemplu de mapare. Spunem că facem "maparea unei propoziţii în
alta".
62
6.4. Reprezentarea şi manipularea mulţimilor

Mulţimea este una dintre cele mai importante structuri de date utilizate în matematică,
operaţiile cu mulţimi găsindu-şi aplicaţii în programarea pe calculator. O mulţime este o
colecţie de elemente, asemenea unei liste, în care ordinea enumerării elementelor nu este
importantă.
Astfel, mulţimea {1,2,3} este la fel cu mulţimea {2,3,1}, deoarece problema este
dacă un element dat este sau nu al mulţimii. Mulţimile pot, de asemenea, avea alte mulţimi în
calitate de elemente. Operaţia de bază asupra unui mulţimi este de a determina dacă un
element aparţine unei mulţimi date. Nu este surprinzător faptul că o reprezentare convenabilă
pentru mulţimi este aceea de liste. O listă poate conţine elemente arbitrare, inclusiv alte liste şi
este posibilă definirea unui predicat de apartenenţă la o listă. Cu toate acestea, când
reprezentăm o mulţime ca o listă, vom aranja ca lista să aibă doar un element pentru fiecare
obiect aparţinând mulţimi. Legăturile cu listele, fără duplicarea elementelor, simplifică unele
operaţii cum ar fi ştergerea elementelor. Vom trata doar listele fără duplicate. Predicatele
descrise în această secţiune menţin această proprietate. Este uzuală definirea următoarelor
operaţii peste mulţimi. Vom folosi notaţii matematice uzuale pentru acelea care sunt uzuale:

Apartenenţa: X Y
X este un membru al unui mulţimi Y dacă X este un element al lui Y.
Exemplu: a {c,a,t}

Submulţime: X Y
Mulţimea X este un submulţime a mulţimii Y dacă fiecare element al lui X este de
asemenea element al lui Y. Y poate conţine unele elemente pe care X nu le are.
Exemplu: {x,r,u} {p,q,r,s,t,u,v,w,x,y,z}

Intersecţie: X Y
Intersecţia mulţimilor X şi Y este mulţimea care conţine acele elemente care sunt
comune atât lui X cât şi lui Y.
Exemplu: {r,a,p,i,d} {p,i,c,t,u,r,a}={r,i,p,a}.

Reuniunea: X Y
Reuniunea mulţimilor X şi Y este mulţimea conţinând elementele din X sau Y, sau din
ambele luate o singură dată.
Exemplu: {a,b,c} {c,d,e}={a,b,c,d,e}

Există operaţii de bază care sunt în mod normal folosite pentru manipularea
mulţimilor. Putem scrie acum programe în Prolog care să le implementeze pe fiecare în parte.
Prima operaţie de bază, calitatea de membru, este acelaşi predicat membru pe care l-am
văzut de câteva ori înainte. Totuşi, definiţia sa pe care o folosim nu conţine simbolul
"tăietura" în cazuri limită astfel că putem genera elemente succesive ale listei prin
backtracking.

membru(X,[X|_]).
membru(X,[_|Y]):-membru(X,Y).

Apoi, un predicat submultime pentru care submultime(X,Y) va reuşi dacă X


este o submulţime al lui Y. A doua clauză în definiţie a concretizat notaţia matematică că
63
submulţimea vidă este o submulţime a fiecărei mulţimi. În Prolog, această notaţie se
transformă într-o cale de a verifica condiţia limită a primului argument; ne vom întoarce la
detaliile lui.

submultime[A|X],Y):-membru(A,Y),submultime(X,Y).
submultime([ ],Y).

Definim acum intersecţia. Scopul intersectie(X,Y,Z) va reuşi dacă intersecţia


lui X cu Y va fi Z. Iată unde va trebui să presupunem că listele nu conţin elemente duplicate.

intersectie([ ],X,[ ]).


intersectie([X|R],Y,[X|Z]):- membru(X,Y), ! ,
intersectie(R,Y,Z).
intersectie([X|R] Y,Z):-intersectie(R,Y,Z).

În sfârşit, reuniunea. Scopul reuniune(X,Y,Z) va reuşi dacă reuniunea lui X şi Y


este Z. Notaţi că reuniune arată mai curând ca un aranjament între intersectie şi
adauga:

reuniune([],X,X).
reuniune([X|R,Y,Z):-membru(X,Y),!,reuniune(R,Y,Z).
reuniune([X|R],Y,[X|Z]):-reuniune(R,Y,Z).

Aceasta încheie repertoarul nostru de predicate dedicate procesării unei mulţimi. Deşi
mulţimile nu se pot prezenta în tipul de programare pe care intenţionăm să-l facem, merită
osteneala să studiem aceste exemple pentru a obţine o înţelegere bună a modului cum putem
face recursivitate şi backtracking.

Bibliografie

1. Podaru, V., Inteligenţă artificială şi siteme expert, Editura Academiei Tehnice


Militare, 1997

64

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