Sunteți pe pagina 1din 24

InteligenŃă Artificială. Tehnici.

5. OPERAłII ARITMETICE şi RELAłIONALE

5.1. Expresii aritmetice

Chiar dacă principalul scop a maşinii de inferenŃă este acela de a efectua

deducŃii logice, funcŃie de întrebările puse aceasta dispune şi de facilitati de a

efectua calcule matematice in domeniul intreg şi real. Ca urmare maşina de

inferenŃă accpta ca in cadrul unor expresii aritmetice sa apara numere şi variabile

despartite prin operatori aritmetici clasici : + , -- , * , mod , div , / ,etc

Expresiile pot sau nu fi delimitate de paranteze . Regulile de evaluare a

unor expresii aritmetice, respectă convenŃiile standard referitoare la evaluarea

operanzilor şi parantezelor .

5.2. Expresii relaŃionale

Pot fi comparate expresii aritmetice , caractere , şiruri şi respectiv

simboluri . Operatorii relaŃionali :

< , > , <= , >= , <> , = .

Modul de aplicare este cel standard ,cu observaŃia că pentru variabile de

tip string se efectuează compararea codului ASCII a caracterelor intilnite.

5.3. Exemple

1. ConstruiŃi o procedură care să calculeze numărul de elemente ale unei

liste. Predicatul este de forma: nr(lista,nr_elemente). Regulile de construcŃie

pornesc de la două observaŃii :

- lungimea unei liste vide este 0

-dacă lista nu este vidă, lungimea este dată de 1 (lungimea capului listei)

+ lungimea cozii listei. Procedura prezintă aspectul:

clauses

nr([ ], 0). nr([ _ | Rest ],N) if nr(Rest, N1),

N=1+N1.

32

InteligenŃă Artificială. Tehnici.

O intrebare se pune de forma:

?- nr([ a,b,c],R)

R=3

1 solutie

2. ConstruiŃi o procedura care să determine elementul maxim al unei liste.

Considerăm un predicat de forma

maxim(lista,element_maxim)

Procedura rezultă din observatiile:

a) Dacă lista este formată dintr-un singur element ,atunci max este elementul

respectiv .

b) În caz contrar, max se obŃine prin compararea capului listei cu maximul

cozii listei.

ObservaŃie: OperaŃia de comparare presupune prezenŃa unui predicat

suplimentar care să compare două elemente, de forma:

max(X, Y, maxin_dintre_X_Y)

Procedura prezintă aspectul:

clauses

maxim ([X] , X). maxim ([X| Rest], Maxim) if maxim (Rest, Max_rest) max( X, Max_rest, Maxim). max (A,B,A) if A>=B. max (A,B,B) if A<B.

Goals:

?-maxim ([7,3,9,0], M)

M=9

Comentarii

Regula maxim divizează lista în elemente componente, reŃinându-le în stiva.

Când lista se reduce la un singur element ,începe rezolvarea apelurilor

recursive, moment in care regula max funcŃionează ca un filtru intre 2

elemente reŃinându-se de fiecare dată pe cel mai mare găsit.

33

InteligenŃă Artificială. Tehnici.

3. ConstruiŃi o procedură care să determine c.m.m.d.c dintre 2 valori

numerice , x, y .Considerăm un predicat de forma:

cmmdc(x, y, rezultat)

Se pleacă de la considerentul :

--Dacă X=Y cmmdc este unul dintre cele două

--Dacă X>Y cmmdc se obŃine între X şi Y-X

--Dacă X<Y cmmdc se obŃine între X şi Y-X

Procedura prezintă aspectul:

clauses

cmmdc(X, X ,X). cmmdc(X,Y,R) if

X>Y, X1=X-Y, cmmdc(X1,Y,R) . cmmdc(X, Y, R) if

X<Y, Y1=Y-X, cmmdc(X,Y1,R) .

exemplu: ?-cmmdc( 15,20,R)

R=5

Exercitii

(1) ExerciŃii:specificaŃi dacă intrebările:

?- nr(L,4)

?- nr([a,b,c],3)

sunt corecte sau nu.

(2) Procedura max definite anterior acceptă sau nu modul de lucru declarativ ?

Se acceptă o întrebare de forma ?- maxim(L,9)

(3) Sunt acceptate de către procedura cmmd definita anterior întrebări de forma:

-cmmdc(15,20,5)

-cmmdc (X,20,5) -cmmdc (15,Y,5)

34

InteligenŃă Artificială. Tehnici.

6. DETERMINISM ŞI NEDETERMINISM ÎN BAZELE DE CUNOŞTINłE

Asa cum s-a specificat maşina de inferenŃă in momentul in care actioneaza

asupra unei baze de cunoştinŃe in contextual unei întrebări adresate de utilizator

va furniza intregul spaŃiu de solutii posibile. Acest aspect care se datoreste

modului specific de functionare a mecanismului de backtracking Prolog face ca

solutiile oferite sa aiba un caracter nedeterminist şi implicit ca intreaga baza de

cunoştinŃe formata din cunoştinŃe propriuzise şi din strategii complementare sa

aiba un character nedeterminist.

6.1. Problematica.

Pentru a ilustra conceptul de clauză deterministă ,respectiv

nedeterministă , considerăm

listă .SecvenŃa de clauze pentru un predicat de forma:

exemplul definit de ştergere a unui element dintr-o

sterg(element, lista, rezultat) este

sterg( _ , [

sterg (X, [ X

sterg(X, [ Y | R1] , [ Y | R2 ]) if

] , [

] ).

| R ], R).

sterg(X ,R1, R2).

Pentru o intrebare de forma:

?-sterg(2,[1,2,3,2,4],R) apare următoare structura de explorare a bazei de

cunoştinŃe de catre maşina de inferenŃă:

apare urm ă toare structura de explorare a bazei de cuno ş tin Ń e de

35

InteligenŃă Artificială. Tehnici.

Cu * s-a notat momentul in care incep rezolvarile apelurilor recursive şi refacerea listelor parcurgand in sus arborele spre radacina ( notaŃia [1| R] insemna ca 1 se reŃine in stivă, iar procedura de stergere se aplica pe Rest ). Ca urmare rezultă nu o solutie ci un spaŃiu de soluŃii de forma:

[1,2,3,4]

[1,2,3,4]

[1,2,3,2,4] => 3 solutii

Datorită modului de construcŃie a mecanismului de backtracking şi a complectarii acestuia cu mecanismul de rezolvare a apelurilor recursive, în cazul general se obŃin mai multe soluŃii . Acest aspect imprimă un caracter nedeterminist clauzelor din baza de cunoştinŃe . Apare logic necesitatea de a selecta din multitudinea de soluŃii obŃinute pe acelea care corespund obiectivului din momentul respectiv. Pentru rezolvarea acestui aspect maşina de inferenŃă dispune de un mecanism de selectie a solutiilor care este activat de catre utilizator, daca considera ca este necesara alegerea unei anumite solutii. Mecanismul este activate de un element de tăiere , definit prin ! (cut) al cărui efect constă în interzicerea deplasării pe anumite direcŃii din spaŃiul soluŃiilor . Denumirea de element de tăiere provine din faptul că efectiv se taie o ramură sau mai multe din graful ce defineşte spaŃiul soluŃiilor. De exemplu : amplasând elementul ! (cut) pe regula şterg ,efectul se manifestă prin taierea ramurii drepte, ceea ce are ca efect obŃinerea unei singure soluŃii.

6.2. Modul de acŃiune a elementului de tăiere (!).

Pentru a explica regulă de forma :

H if B 1 , B 2 , … B m , !, B m+1 , … B n .

Presupunem ca H a realizat unificarea cu o întrebare care apare în Goal. Prin

mecanismul de căutare în intervalul B 1 , B 2 , … B m , presupunem că s-a găsit o

soluŃie. În momentul atingerii elementului de tăiere, soluŃia găsită este îngheŃată, operaŃia fiind echivalentă cu ştergerea pointerilor (amplasati de maşina de

inferenŃă) de pe clauzele B 1 , B 2 , … B m . Căutarea continuă pentru B m+1 , … B n ,

modul de funcŃionare al elementului ! considerăm o

36

InteligenŃă Artificială. Tehnici.

în care sunt permise toate soluŃiile posibile. Cu alte cuvinte spaŃiul soluŃiilor este

format din soluŃia definită de B 1 , … B m şi variantele oferite de B m+1 , … B n .

Elementul de tăiere îşi extinde acŃiunea şi pentru clauzele Horn de acelaşi

nume care urmează după acelea în care este prezent.

Sa consideram următoarea situaŃie:

H

if P,Q,R,!,S,T,U.

H

if U,V .

% -> această regulă nu se mai execută

A

if B,H,C.

%->nu ne mai putem întoarce pentru B

A

Elementul de tăiere va afecta execuŃia lui H astfel: backtrackingul este

posibil în interiorul Ńintelor P,Q,R până în momentul în care ! este atins şi soluŃia

rămine definitiva, toate alternativele posibile fiind eliminate. Rămân în continuare

alternativele relaŃive la Ńintele S,T,U. Următoarea clausa H nu va fi executată

(ştergerea pointerilor fiind efectivă, inclusiv la nivelul clauzei în care se gaseşte).

La nivelul clauzei A, ( în care elementul de tăiere este invizibil ) se oferă de

fiecare dată o singură alternativa la nivelul lui B,H şi una sau mai multe la nivelul

lui C. Următoarea clausa A va fi executată. Deci elementul de tăiere are un efect

local numai la nivelul clauzelor cu acelaşi nume.

Reguli de amplasare

Amplasarea lui ! depinde de contextul întrebării puse.Se recomandă utilizarea

următoarelor 2 metode:

1.

Elementul

de

tăiere

întrebarea pusă.

se

amplasează

pe

axioma

care

implementează

sterge(2,[1, 2, 3],R) sterge(X,[X|R],R) if !. sterge(X, [ Y | R1] , [ Y | R2 ]) if

sterge(X,R1,R2)

37

InteligenŃă Artificială. Tehnici.

2. Se utilizează opŃiunea

programului sub forma:

CHECK_DETERM, care

se amplasează în faŃa

check_determ

domains

-specifică punctul în care poate fi amplasat elemental de tăiere.Din propunerile

avansate se allege aceea care

furnizează

6.3. Construirea regulilor If

rezultatele dorite.

Then

Else

Elementul de taiere ! poate fi utilizat pentru construirea unor reguli de tip

if_then_else , în Prolog, sub forma:

a) ConstruiŃi o procedură max (x, y, maxim_x_y) care se traduce printr-o regula

de forma:

if x>=y then MAX=x else MAX=y.

Obişnuit regula poate fi scrisă in Prolog astfel.

max(X,Y,X) if X>=Y. max(X,Y,Y) if X<Y.

sau

max(X,Y,X) if X>=Y, !. max( _ ,Y,Y).

Dacă prima regulă este adevarată, elementul de tăiere se ia în considerare şi

cea dea doua regulă nu se mai execută.

b) ConstruiŃi o procedură care să asigure adunarea unui element X la o listă L,

numai dacă X nu este prezent în L (în acest caz X devine capul listei), de forma:

aduna(elem, L,Rezult)

38

InteligenŃă Artificială. Tehnici.

care se traduce printr-o regula de forma:

if elem aparŃine L then Rezultat=L else Rezultat=[elem | L ]

SecvenŃa se scrie in Prolog astfel:

aduna(X ,L, L) if aparŃine (X,L), ! . aduna(X,L,[ X |L ]).

Exemplu : ?-aduna (2,[1,3],R)

R=[2,3,1]

?- aduna(3 ,[1, X ,4] ,R) X=3 ,R=[1 ,3, 4]

c) ConstruiŃi o procedură care pornind de la o listă cu elemente numere

întregi ,să construiască 2 liste: prima conŃinând elemente >0 ,cea de-a doua

conŃinând elemente <=0.

% imparte(lista, lista>0,lista<=0)

imparte( [ ], [ ], [ ] ) . imparte( [ESTE | R ] , [ESTE |L1], L2) if ESTE>=0, !, imparte(R,L1 ,L2) . imparte([ESTE,R],L1,[ESTE|L2]) if

imparte(R,L1,L2).

! acŃionează distinct de fiecare dată la un apel.

d) ConstruiŃi o procedură care să permită clasificarea concurenŃilor dintr-un

turneu de tenis în 3 categorii definite astfel:

--categoria câştigătorilor, dacă jucatorul i-a bătut pe toŃi cei cu care a jucat --categoria luptător, dacă jucătorul a cîştigat şi a pierdut jocuri. --categoria sportiv ,dacă jucatorul a piedut toate meciurile.

if X bate pe cineva şi X este bătut de altcineva then X este luptător else if X bate pe cineva then X este cîştigător else if X primeşte bătaie de la toŃi then X este sportiv.

39

InteligenŃă Artificială. Tehnici.

Dacă predicatul este de forma: clasa (nume_sportiv,categoria), regula se implementează astfel :

clasa (X,luptator) if bate_pe(X, _) , bate_pe( _ ,X) , !. clasa(X,cistigator) if bate_pe(X, _), !. clasa (X, sportiv) if bate_pe( _,X).

6.4. Implementarea negaŃiei.

-Se implementează în două moduri:

a) se utilizează | ,fail , true.

b) not

a) Not şi fail reprezintă predicate standard PROLOG care întotdeauna

precizează valoarea fals, respectiv adevărat.

1. DefiniŃi următoarele aspecte:

Lui Tom îi plac animalele cu excepŃia pisicilor. Considerînd predicatul de forma:

% îi_place(propietar,animal)

% animal(nume_animal)

afirmaŃia anterioară se scrie în prolog sub forma:

îi_place(tom,X) if X=pisica ,!,fail. îi_place(tom,X) if animal(X).

%(spune ca proprietatea este falsă)

ObservaŃie : prezenta lui fail în prima regulă face ca aceasta să devină falsă , iar

! din fata lui fail stopează căutarea pe următoarea regulă îi_place.

SecvenŃa poate fi scrisă compactat sub forma:

îi_place(tom,X) if X=pisica, !, fail; animal=X.

40

InteligenŃă Artificială. Tehnici.

2. ConstruiŃi o procedură care să furnizeze fals dacă obiectele X şi Y sunt

identice şi adevărat dacă obiectele X şi Y sunt diferite. Modul de funcŃiune este

de forma

diferit(obiect1,obiect2), diferit(2,3) YES

Procedura se scrie:

diferit(3,3)

NO

diferit(X,Y) if X=Y, !, fail. diferit(X,Y) if X< >Y. sau: diferit(X,Y) if X=Y, ! ,fail. diferit( _, _ ).

sau: diferit(X ,Y) if X=Y ,! ,fail; true.

3. Implementarea negaŃiei printr-o regulă

true apare de forma:

utilizand o combinatie intre fail, ! şi

not( P) if P, !, fail; true.

b) Maşina de inferenŃă pune la dispozitie predicatul not. Modul lui de acŃionare

consta in inversarea rezultatului oferit de maşina de inferenŃă relativ la clausa

sau clausele asupra careia actioneaza.

Cu aceste observaŃii ,secvenŃele anterioare pot fi rescrise:

îi_place(tom,X) if animal(X), not(pisica(X)).

diferit(X,Y) if not(X=Y).

clasa(X,luptator) if bate_pe(X, _ ), bate_pe( _, X). clasa(X,cistigator) if

41

InteligenŃă Artificială. Tehnici.

bate_pe(X, _ ), !. clasa(X,sportiv) if bate_pe( _,X).

Exercitii

1) Fiind data secventa:

A :- B,C.

A :- not(B),D.

se cere construirea unei secvente care sa se comporte identic, in care negatia sa

dispara prin inlocuirea cu elementul de taiere !.Explicati succint

(1) de ce cele doua secvente au aceiasi comportare.

(2)care este efectul elementului de taiere in caz general

2) Considerind procedura: p(1). p(2) if !. p(3).

Care sunt raspunsurile la întrebările:

(a) ?- p(X).

(b)

?- p(X),p(Y).

(c)

?- p(X),!,p(Y).

42

Inteligenţă Artificială. Tehnici.

7. OPERAŢII DE CITIRE / SCRIERE

Dupa cum s-a vazut pana in momentul prezent, maşina de inferenţă actioneaza asupra unei baze de cunoştinţe in contextul unei întrebări puse de utilizator. Acest mod de activare a masinii de efectuat deductii logice reprezinta o restrictie, deoarece pe de o parte raspunsurile date sunt strict limitate la afisarea unor solutii posibil, iar pe de alta parte utilizatorul nu poate interveni in derularea rationamenului efectuat. Asa cum am spus, spaţiul solutiilor care urmeaza sa fie explorat este extreme de vast, motiv pentru care initierea unui dialog cu utilizatorul in vederea indrumarii pe o anumita directie s-au alta a rationamentului devine o necesitate. Toate aceste considerente ridica problema prezentei unei interfete cu utilizatorul alta decat cea standard legata de procesul de tip intrebare / raspuns care sa dea posibilitatea initierii unui dialog cu utilizatorul in timpul procesului de inferenţă. Ca urmare a acestui deziderat, s-a prevazut posibilitatea ca utilizatorul sa-si construiasca propria interfata de intrare / iesire, adaptata problematicii pe care doreste sa o reyolve, interfata complementara celei standard de tip intrebare / raspus. Pentru construirea de catre utilizator a acestei interfete s-au prevazut un numar de predicate standard care se regasesc in toate implementarile masinilor de inferenţă prolog, predicate care sunt grupate in jurul operatiilor de tip read / write. Acestea urmeaza sa fie analizate in continuare, in contextual general al operatiilor de citire / scriere.

7.1. Scrierea.

Predicatul de scriere prezintă sintaxa:

write(arg1,

,argn)

În care argumentele pot fi constante sau variabile ce aparţin unor domenii standard sau nu. Dacă argumentul este un şir de caractere atunci acesta

reprezintă mesaj care se tipareşte pe ecran. În interiorul şirului sunt acceptate următoarele caractere de control:

\n,

salt peste n linii

\t,

tab

43

Inteligenţă Artificială. Tehnici.

\b.

spaţiu

De exemplu write(" \t lista1= ",L1,"\n \t Lista2 ", L2)

lista1=[ ] lista2 =[1,2] În general predicatul write apare în proceduri recursive, aspect care implică stoparea operaţiei de căutare a soluţiilor, astfel încât rezultatele parţiale să nu fie tipărite.

are ca efect o tipărire de forma:

7.2. Citirea

- este realizată de următoarele predicate:

--

readreal(X) --

readint(X)

citire variabilă de tip intreg. citire variabile din domeniul real

Operaţia de citire se termină în momentul apăsării tastei ENTER. Rezultatul este un success, dacă numărul citit este un întreg sau real respectiv un eşec dacă valoarea citită conţine caractere care nu aparţin numerelor întregi sau reale. readln(X) -- citirea variabilelor din domeniul simbol sau string readchar(X) -- citirea caracterelor Ultimul predicat este întotdeauna un succes. Primul este un eşec dacă şirul citit nu este delimitat de " .

7.3. Modalităţi de citire / scriere.

Aspectele care apar in momentul efectuarii unui dialog cu masina de inferenţă sunt illustrate printr-un set de exemple:

1. Construiţi o procedură care să genereze o listă atunci când elementele listei se citesc. Considerăm că lista este de tip întreg. Dacă predicatul este de forma:

% citeşte(lista) ,procedura apare sub forma:

44

Inteligenţă Artificială. Tehnici.

domains lista=integer * predicates citeşte(lista) clauses citeşte([ESTE |Rest]) if

goal:

citeste(L),

write(L).

write("Element=");

readint(ESTE),

citeşte(Rest).

Citeşte se termină în momentul în care predicatul este fals.

Element=1 Enter

=4 Enter

Operaţia de introducere continuă până în momentul în care se introduce un

caracter prin care readint este obligat să devină fals. Ca urmare regula citeşte

este falsă, fiind executată regula citeşte plasată după reguli. Prin apeluri

recursive ,se construieşte lista care se scrie.

2. Construiti o procedura care să reia repetat operaţia de citire a unei liste. Dupa

fiecare listă construită prin dialog, se va specifica dacă operaţia continua sau nu.

Reluarea construirii listei va fi efectuată de predicatul repeta, sub forma:

domains

lista=integer*

predicartes

repeat

citeste(lista)

goal repeta. clauses repeta if citeste(L), write("lista= ",L), write("\n Continuati? (d/n)"), readchar(R), R='d', repeta.

% citeste este definit anterior

.

45

Inteligenţă Artificială. Tehnici.

Dialogul apare de forma:

ESTE=1

ESTE=2

ESTE=.

lista=[1,2]

Continuati? (d/n) d Se pot face doua observatii importante:

(1) Procedura "citeşte" este o procedură recursivă. Mecanismul de căutare a

soluţiilor amplasează un pointer pe "citeşte" pentru fiecare element citit. În

momentul în care lista se consideră a fi construită , forţându-se ca readint să fie

fals, are loc rezolvarea apelurilor recursive prin care se construieşte lista. Efectul

pentru exemplul dat este de a fi construite toate listele parţiale care pot apare

prin introducerea fiecarui element, evident insa ca acest aspect nu este de dorit:

Pentru cazul discutat situaţia apare de forma

ESTE=1

ESTE=2

ESTE=.

Lista= [ ]

Continuaţi ? d --------> }

Lista=[2]

Continuaţi ? d --------> } obligatorie amplasarea elementului de taiere !

Lista=[1,2]

}Din acest motiv după procedura recursivă este

Se observă ca apar listele parţiale [ ] , [ 2] , [1, 2 ] din care numai ultima lista

intereseaza. Pentru a rezolva problema este necesara stoparea inferentei, motiv

pentru care se utilizeaza elemental de taiere care se va amplasa dupa procedura

recursive care genereaza printre altele şi aceste rezultate partiale.

(2) Problematica apare şi in cazul unor proceduri recursive prezente in strategiile

complementare masinii de inferenţă, moment in care aceste genereaza pe langa

rezultatele corecte şi o multitudine de rezultate partiale care trebuie inlaturate.

Atunci când se doreşte rezolvarea repetată a unor probleme pentru alte

date , procedura generala pentru alte date este :

46

Inteligenţă Artificială. Tehnici.

repeta

Goal

if citeste_date ,!, executa ,!, scrie, !, continuare , repeta.

%

%

%

Dacă procedura citeste_date şi executa, sunt recursive , amplasarea elementului ! (cut) este obligatorie.

Interfata de intrare / iesire cu utilizatorul,

repeta.

3. Construiţi o procedură care să asigure scrierea unei liste cu elemente numere

întregi , pe rânduri succesive ,fiecare rând având 3 elemente.

Considerăm că predicatele utilizate sunt :

% scrie (lista)

% scrie_rind(lista,nr_elem_pe_rind)

pot fi luate în considerare următoarele situaţii:

a) Scrierea listei începe cu scrierea primului rând .

b) După ce s-a scris un rând ,se trece la rândul următor.

Procedura apare sub forma:

domains I = integer* predicates scrie (l) scrie_rind(l,integer)

clauses scrie (L) if nl, scrie_rind(L,0).

scrie_rind([ ],-).

scrie_rind(L,3) if nl, scrie_rind(L,0).

scrie_rind ([ESTE|Rest],N) if write(" ",ESTE),

% ------------>oprirea procesului recursiv

N1=N+L,

scrie_rind(Rest,N1).

Observaţii:

a)Predicatul ne asigură trecerea la începutul unei linii noi.

b)Pentru procedura scrisă se contorizează numărul de elemente care se

scriu, după care regula scrie_rind(L,3) asigură trecerea la următorul rând.

47

Inteligenţă Artificială. Tehnici.

4) Specificaţi setul de clauze care să asigure citirea unei liste a căror

elemente sunt obiecte compuse , de forma:

% persoana=p(nume,prenume,virsta)

domains nume,prenume=symbol persoana =p(nume,prenume,integer) lista=persoana * predicates citesc(lista) citeste(pers) clauses

citesc([Obiect|R]) if citeste(Obiect), citesc(R). citesc([ ]). citeste(p(N,P,V)) if nl, write("Nume="),readln(N), write("Prenume="),readln(P), write("Virsta="),readint(V),nl.

Observaţii :

Operaţia presupune definirea unui predicat de citire separat, la nivelul de

obiect compus. Acest predicat este utilizat pentru citirea fiecărui element al listei

ce se construieşte. Întreruperea operaţiei de construire se face introducând un

caracter care să forţeze readint să fie fals. Pentru structura de date in discutie se

va obţine o listă de forma :

[p(Ion,V,17),p(Vlad,C,20)

5) Scrierea cu format

]

Este asigurată de predicatul

writef (format, arg1, arg2,

)

unde:

format reprezinta un şir de caractere în care apar descriptori de forma:

48

Inteligenţă Artificială. Tehnici.

%-m pentru scrierea câmpurilor alfanumerice şi întregi pe m poziţii.

'-' e opţional şi semnifică aliniere la stânga în loc de dreapta implicit

%-m.pf pentru numere reale cu sau fară exponent.

p specifică numărul de poziţii luate în considerare după

virgulă

Exemplu:

Considerand ca avem o lista de obiecte compuse de forma:

p(nume, prenume, vârsta, venit) unde sunt prezente obiectele

[ p(ion, dan, 20, 37000.0), p(vasile, ionel, 50, 57000.7),

)]

se cere construire unei proceduri de scrieere a elementelor din lista cu

precizarea semnificatiei fiecarui element component intr-o structura data.

Procedura apare de forma:

scriu([E| Rest]) if

scrie_p(E),

scriu(Rest).

scriu([ ]). scrie_p(p(N,P,Vr,Vn)) if writef("\n Nume= %-20 Prenume= %-10 ,

Venit=%7.1f",N,P,Vr,V)

49

InteligenŃă Artificială. Tehnici.

8. BAZE DE DATE INTERNE

În acord cu modelul relaŃional al unei baze de date, setul de clauze Prolog

poate fi poate fi privit ca o baza de cunoştinŃe, pentru care sunt specificate relaŃii şi

caracteristici ale unor obiecte şi fenomene.

Acest punct de vedere a impus introducerea facilităŃii de a modifica în cursul

execuŃiei setul de clauze prezente în baza de cunoştinŃe. Ca urmare a acestei

caracteristici – modificarea dinamica a setului de cunoştinŃe in urma dialogului cu

utilizatorul – devine posibil ca baza de cunoştinŃe se evolueze in timp, evolutie care

se concretizeaza faptic prin modificarea, disparitia si respective adaugarea de noi

cunoştinŃe. Ca urmare apare un aspect interesant si anume acela ca baza de

cunoştinŃe invata, fiind retinuta intreaga experienta castigate anterior. Din punct de

vedere practice aceasta facilitate se referă atât la adaugarea de noi clauze cât şi la

stergerea selectivă în timpul execuŃiei a acestora. S-a prevazut de asemenea

posibilitatea salvării setului de clauze şi a restaurării acestuia dinamic.

8.1. Caracteristicile bazelor de date interne.

Declararea bazelor de date interne se face în secŃiunea database care

conŃine predicatele ce aparŃin unei baze de date.

Exemplu:

Implementăm relaŃiile dintre persoane referitoare la capacitatea lor de a

alerga (incet,repede).

1)

domains nume=symbol predicates aleargă_repede(nume) aleargă_încet(nume) mai_rapid(nume,nume) clauses aleargă_repede(ana). aleargă_repede(radu). aleargă_încet(doru). mai_rapid(X,Y) :- aleargă_repede(X), aleargă_încet(Y).

50

InteligenŃă Artificială. Tehnici.

2)

domains nume=symbol predicates mai_rapid(nume,nume) database aleargă_repede(nume) aleargă_încet(nume) clauses aleargă_repede(ana). aleargă_repede(radu). aleargă_încet(doru). mai_rapid(X,Y) :- alearga_repede(X), alearga_incet(Y).

Goals : assert(aleargă_repede(ion))

Yes

Goals : aleargă_repede(X)

X=ana X=radu X=ion 3 solutions

Goals : save("axiome.dba")

Yes

Goals:consult("axiome.dba")

{se încarcă baza de date}

8.2 . ModalităŃi de asertare a clauzelor într-o baza de date.

- Asertarea poate fi făcută în spatele setului de clauze cu acelaşi nume prin

predicatele :

assert(clausa) assertz(clausa) - Asertarea poate fi făcută în faŃa setului de clauze cu acelaşi nume prin predicatul :

asserta(clausa)

- Ştergerea unei clauze din setul de axiome se face cu:

retract(clausa)

retractall(clausa) - şterge toate clauzele cu acest nume

- şterge clausa

Pentru retract este posibilă în momentul ştergerii, obŃinerea de informaŃii

privind structura clauzei care se şterge dacă variabila din clauză este liberă.

51

InteligenŃă Artificială. Tehnici.

Exemplu: Pentru exemplul de mai sus

Goal : retract(aleargă_repede(X)),write(X)

va legă pe X la valoarea ana

- Salvarea/restaurarea bazei de date se face cu:

save(nume_dos)

consult(nume_dos)

Observatii:

1) Intr-o baza de date nu pot fi asertate decât axiome. Există totuşi dialecte

de Prolog care permit şi asertarea regulilor.

2) La un moment dat pot exista 2 sau mai multe baze de date active. Pentru

a face deosebirea între acestea setul de predicate prezintă extensiile:

assertz(clausa,nume_baza_date)

asserta(clausa,nume_baza_date)

retract(clausa,nume_baza_date)

retractall(clausa,nume_baza_date)

save(nume_dos,nume_baza_date)

consult(nume_dos,nume_baza_date)

Pe întregul set, indiferent câte baze de date am deschise se lucrează cu

predicatele standard (se folosesc pentru toate bazele de date).

3) Numele bazei de date se specifică direct sub forma unui nume simbolic în

predicatele care gestionează o baza de date.

Exemplu:

ConstruiŃi un sistem de clasificare a obiectelor utilizând o baza de date

internă a cărei structură este de forma:

este_un( limbaj, unealtă, ["comunic"]) este_un( plug, unealtă, ["ara camp", "folosit de fermier"]) este_un(creion,unealtă,["scris", "folosit la scris"]) tip_de(engleză, limbaj, ["comunicarea cu oamenii"]) tip_de(pascal, limbaj, ["comunicarea cu calculatorul"])

52

InteligenŃă Artificială. Tehnici.

domains

obiect=string

database

atribut=string

este_un(obiect,obiect,atribute)

fals(atribut)

atribute=atribut*

tip_de(obiect,obiect,atribute)

predicates

run(obiect)

intreaba(atribute)

clauses

run(Art):-

este_un(X, Art, Lista ), întreabă( Lista ),

tip_de(Răspuns,X,Lista2),

întreabă(Lista2),

run( _ ) :-

write(Art, " de care aveŃi nevoie este ", Raspuns), nl, !. write( "Nu există informaŃie suficientă" ).

întreabă( [ ] ). întreabă( [A|R] ) :- not(fals(A)), write("Vă ajută la",A), write(" da sau nu? readchar(C), nl, C='d',

întreabă(R). întreabă( [A|_ ] ) :- assertz(fals(A)), fail.

Goal:run(unealtă)

Vă ajută la comunicare? d

Vă ajută la comunicarea cu oamenii? n

{În baza de date se assertează clausa fals("comunicarea cu oamenii") }

Vă ajută la comunicarea cu calculatorul? d

Unealta de care aveŃi nevoie este Pascal

ObservaŃie:

1) În acest mod, procedura poate reŃine o informaŃie în timpul dialogului

(faptul ca comunicaŃia cu oamenii este falsă) ceea ce face ca la o nouă reluare a

execuŃiei această întrebare să nu se mai pună.

53

InteligenŃă Artificială. Tehnici.

2) Practic in acest moment s-a generat o baza de cunoştinŃe care

este independentă de componta care este utilizată pentru interogarea ei ( baza de

cunoştinŃe poate fi editată şi actualizată cu orice utilitar de editare n mod text )

3) In baza de cunoştinte informaŃiile se reŃin prin intermediul unor structuri

de tip arbore. Fiecare arbore defineşte o clasa de obiecte în care rădăcina defineşte

clasa de obiecte, frunzele obiectele care sunt indivizibile iar nodurile subclase de

obiecte de aceaşi natură prezente în clasa definită de arboreal respective. Fiecare

nod (radaăcina, intermediary sau de tip frunză) are ataşată o listă de attribute care

sunt validate sau nu în cursul procesului de inferenŃă. Modul de validare determină

sensul de parcurgere a arborelui (vezi figura următoare).

Clase de obiecte

Clase de obiecte Clasa 1 ………………………… Clasa n Da Subclase Nu …………………. Obiect 1
Clasa 1 ………………………… Clasa n Da Subclase Nu …………………. Obiect 1 2……………m
Clasa 1 …………………………
Clasa
n
Da
Subclase
Nu
………………….
Obiect 1
2……………m
Pentru raspuns:

Da pentru toate atributele unui nod acesta este validat Nu pentru un singur răspuns de acest tip se invalideaza nodul

54

InteligenŃă Artificială. Tehnici.

8.3 Colectarea soluŃiilor

Prin mecanismul de backtracking, soluŃiile sunt generate pas cu pas. Utilizatorul are

acces numai la soluŃia din pasul curent (soluŃiile anterioare sunt pierdute). Pentru a

da posibilitatea prelucrării întregului ansamblu de soluŃii, s-a prevăzut facilitatea de

colectare a acestora într-o listă în care elementele sunt soluŃii. OperaŃia e realizată

de predicatul :

findall(SoluŃie,Întrebare, Listă_soluŃii)

Pentru a ilustra tehnica de colectare, considerăm o procedură în care se stabileşte

apartenenŃa unui caracter la clasa vocale sau consoane. IniŃial, programul prezintă

aspectul :

domains literă = char predicates tip_literă = ( literă, symbol ) clauses tip_literă( 'a', vocală ). tip_literă( 'b', consoană ). tip_literă( 'c', consoană ).

Pentru a colecta soluŃia se pot utiliza două tehnici :

a) goal

findall( C, tip_literă( C, consoană ), L ), write( 'SoluŃie = ', L )

=> SoluŃie = [ b, c ]

b) findall poate fi întrebuinŃat în procedura utilizator. In acest caz, devine

necesară declararea în secŃiunea domains a unei liste de soluŃii :

domains

litera = char

lista = litera*

.

findall( C, tip_literă( C, consoană ), L ),

.

procedura de prelucrare a listei L,

Exercitii

1) Care sunt raspunsurile la întrebările:

? assert(p(a)),assertz(p(b)),asserta(p(c))

? p(X)

55