Sunteți pe pagina 1din 18

Inteligenţă artificială

Laboratorul 1

Introducere în CLIPS (I)


1. Limbajul CLIPS
2. Faptele
2.1. Fapte ordonate
2.2. Adăugarea faptelor
2.3. Gruparea faptelor. Constructorul deffacts

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


3. Definirea regulilor. Constructorul defrule
4. Comanda printout
5. Definirea unei variabile
6. Probleme rezolvate
7. Aplicaţii

1. Limbajul CLIPS
CLIPS este un instrument pentru crearea sistemelor expert, dezvoltat de Software
Technology Branch (STB), NASA/Lyndon B. Johnson Space Center cu scopul facilitării realizării
de programe care modelează cunoaşterea şi experienţa umană. CLIPS este un acronim pentru
C Language Integrated Production System.
Foarte multe probleme de inteligenţă artificială se rezolvă prin căutarea şi executarea unor
reguli aplicabile într-o anumită situaţie. Căutările mai simple pot fi realizate foarte bine în limbajele
procedurale cu care suntem obişnuiţi: C, Java, C# etc. Avantajul CLIPS-ului constă în motorul de
inferenţă bazat pe un algoritm foarte performant, numit Rete. Sintaxa CLIPS-ului permite definirea
foarte succintă a unor căutări după modele foarte complexe.
Să ne imaginăm o problemă simplă:

Găsirea tuturor aranjamentelor a 4 elemente luate câte 3.

Pentru rezolvarea acestei probleme trebuie să avem în vedere modul de stocare a datelor în
CLIPS şi modul de gestionare al acestora. Astfel, în CLIPS există trei forme principale de
reprezentare a informaţiei: fapte (facts), obiecte şi variabile globale. Logica programelor se
implementează utilizând reguli care generează acţiuni în funcţie informaţia stocată sub formă de
fapte, obiecte şi variabile.
Prima metodă de interacţiune cu CLIPS-ul reprezintă linia de comandă care are prompterul
CLIPS>. Comenzile valide pentru acest limbaj reprezintă constructorii şi funcţiile urmate de
parametri, precum şi variabilele globale şi constantele. Un aspect important legat de sintaxă ce
diferenţiază CLIPS-ul de celelalte limbaje de programare reprezintă scrierea comenzilor între
paranteze rotunde. Comenzile pot fi grupate în fişiere de tip batch care pot fi încărcate şi executate
din linia de comandă a CLIPS-ului.
Pentru soluţionarea problemei anterioare programul implementabil cu uşurinţă în CLIPS
precum și programul echivalent realizat în C++ sunt prezentate în figura 1. Aceste programe sunt
prezentate doar cu scop informativ pentru a evidenția simplitatea limbajului CLIPS în rezolvarea
unor tipuri de probleme complexe. Nu este nevoie să le înţelegeţi complet acum. Detalii ce permit
înțelegerea conceptelor utilizate de limbajul CLIPS vor fi prezentate în continuarea acestui laborator
și pe parcursul laboratoarelor următoare.

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


(deffacts obiecte #include <stdio.h>
(obiect cub) #include <string.h>
(obiect sfera)
(obiect con) int i,j,k;
(obiect paralelipiped) char obiect[4][14];
)
main() {
(defrule aranjamente43 strcpy(obiect[0],"cub");
(obiect ?o1) strcpy(obiect[1],"sfera");
(obiect ?o2 &~?o1) strcpy(obiect[2],"romb");
(obiect ?o3 &~?o2 &~?o1) strcpy(obiect[3],"paralelipiped");
=>

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


(printout t "(" ?o1 " " ?o2 " " ?o3 ")" crlf) for(i=0;i<4;i++)
) for(j=0;j<4;j++)
for(k=0;k<4;k++)
Program CLIPS {
if (i!=j&&j!=k)
printf("(%s %s %s)\n", obiect[i],obiect[j],obiect[k]);
Program C++ }
}

Figura 1. Programele CLIPS și respectiv C++ pentru problema aranjamentelor

Programul CLIPS utilizează constructorul de fapte deffacts şi constructorul de reguli defrule


și trei variabile de tip obiect ?o1, ?o2 şi ?o3. După cum se poate observa, o varibilă poate lua toate
valorile faptelor de acelaşi tip definite anterior.
Un alt avantaj remarcabil al limbajului CLIPS este posibilitatea modificării programelor
chiar în timpul execuției acestora prin adăugarea sau înlocuirea de funcții. Inserarea regulilor sau
constructorilor în programul compilat se face cu comanda build. De exemplu, adăugarea unei noi
reguli pentru afişarea aranjamentelor de 4 obiecte luate câte 2 poate fi făcută astfel:

(defrule modificare_program
(modificare da)
=>
(build "(defrule aranjamente42 (obiect ?o1) (obiect ?o2 &~?o1) =>
(printout t \"(\" ?o1 \" \" ?o2 \")\" crlf) )" )
)

2. Faptele
Faptele sunt forma principală de reprezentare a informaţiei în sistemul CLIPS. Fiecare fapt
reprezintă un element de informaţie care va fi plasat în lista de fapte numită factlist. Faptul este
forma fundamentală de date folosită de reguli şi constă într-un nume de relaţie urmat de zero sau
mai multe sloturi (câmpuri simbolice cărora li se pot asocia valori). Forma generală a unui fapt este
următoarea:

fact <==> ( nume_relaţie [ (slot)* ] [ (multislot)* ] )

Exemple de fapte:

(persoana) ; fapt fără slot (nume relatie)


(student Ionescu) ; fapt cu un singur slot (nume_relatie slot)
(student Mereanu Mihai 30) ; fapt multislot (nume_relatie multislot)

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


Parantezele pătrate indică faptul că existenţa sloturilor este opţională, iar semnul * arată
faptul că putem avea zero sau mai multe sloturi. Se observă faptul că în CLIPS trebuie să cuprindem
între paranteze atât numele de relaţie cât şi sloturile. Un slot este la rândul său format dintr-un nume
căruia i se poate asocia o valoare. Există însă şi posibilitatea asocierii de mai multe valori şi în acest
caz spunem ca avem un multislot. Acest lucru este posibil datorită existenţei în CLIPS a
multicâmpului (multifield) care este de fapt o secvenţă de zero sau mai multe câmpuri. Afişarea în
CLIPS a unei valori multicâmp se va realiza prin închiderea acestuia între paranteze. Trebuie reţinut
faptul că o valoare multifield nu este unul şi acelaşi lucru cu o valoare câmp (single field).

slot => ( nume_slot valoare )


multislot => ( nume_slot [ valoare ]* )

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


Un slot trebuie să aibă obligatoriu asociată o valoare, pe când la un multislot asocierea unei
valori nu e obligatorie. Valoarea pe care o asociem unui slot poate lua forma unui tip de dată
primitivă (integer, float, symbol, string). Exemple de fapte ar putea fi :

(start)
(strada "Bistritei 32")
(apartament 12)
(bloc X1)
(scara A)
(nume Irina Vlad)
(culoare_par)

În primul caz faptul (start) nu are niciun slot; faptul nume are mai multe valori: Irina, Vlad,
iar faptul strada are o singură valoare de tip string. Se observă că putem asocia unui slot valori de
diferite tipuri: valoarea slotului strada este un şir de caractere, valoarea slotului apartament este un
întreg, iar valorile sloturilor bloc şi scara sunt simboluri. În ultimul caz, atât slotul nume, cât şi
slotul culoare-par, pentru care nu s-a precizat o valoare explicită, sunt multisloturi (au două şi
respectiv zero valori).

(strada "Bistritei 32") (apartament 12)


(apartament 12) (strada "Bistritei 32")
(bloc X1) (bloc X1)

Iată mai jos un mod de a privi faptele neordonate. Presupunem că avem două adrese. O
modalitate de a defini faptele necesare ar putea fi:

(deffacts adresa
(strada "Independentei")
(strada "Bistritei")
(bloc X1)
(bloc X2)
(scara A)
(scara B)
(apartament 10)
(apartament 12)
)

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


Se observă însă că o modalitatea de mai sus introduce şi o serie de ambiguităţi. De exemplu,
dacă considerăm distribuţia datelor ca aparţinând la două locuinţe precum în figura de mai sus,
modul de definire a faptelor nu indică categoric care sloturi cărui fapt aparţin. O modalitate de
rezolvare a acestei probleme este folosirea şabloanelor, dar aceasta va fi studiată în laboratorul 2.

2.1. Fapte ordonate

Un fapt ordonat (ordered fact) constă într-un nume de relaţie urmat de zero sau mai multe
câmpuri separate de spaţii. Acesta ar putea fi comparat cu un slot de tip multifeld (multi-câmp) în
care se pun toate valorile ce urmează după numele de relaţie. Faptele ordonate sunt create automat
de un constructor implicit al CLIPS-ului. Astfel se poate implementa relativ uşor o stivă sau o coadă

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


(şiruri de elemente). De exemplu:

(numere_prime 2 3 5 7 11)
(numere_pare 2 4 6 8 10)

Ilustrarea grafica a modului de aranjare a sloturilor ce definesc faptele ordonate este


prezentata in figura anterioara. Astfel, valorile 2, 4, 6, 8, 10 luate in aceasta ordine definesc faptul
cu numele de relatie numere_pare, iar sloturile ce contin valorile 2, 3, 5, 7, 11 definesc faptul cu
numele de relatie numere_prime.
Câmpurile dintr-un fapt ordonat pot fi orice tip de dată primitivă (cu excepţia primului câmp
care reprezintă numele de relaţie şi care trebuie să fie de tip simbol) şi nu există restricţii privitoare
la ordinea acestora. Totuşi, următoarele simboluri sunt rezervate şi nu pot fi primul câmp dintr-un
fapt (numele de relaţie): test, and, or, not, declare, logical, object, exists şi forall. Deşi aceste
simboluri rezervate pot fi folosite la numele unui slot prin schimbarea unei litere mici într-o litera
mare, în general nu se recomandă aceasta. În următoarele exemple de fapte:

( test de inteligenta artificiala )


( Test de inteligenta artificiala )

CLIPS-ul ne va informa că nu putem folosi ca nume de relaţie simbolul test, dar în al doilea caz se
va accepta ca nume de relaţie simbolul Test, deoarece limbajul CLIPS este case-sensitive şi vede
cele două câmpuri ca fiind diferite. Lista de elemente este formată din trei câmpuri: de, inteligenta,
artificiala.

2.2. Adăugarea faptelor

Toate faptele cunoscute de CLIPS sunt păstrate în lista de fapte fact list. Comanda assert
permite adăugarea la listă a unei noi fapte. Sintaxa comenzii assert este următoarea:

(assert <fact>+)

Prin <fact>+ se înţelege faptul că putem aserta un nou fapt sau mai multe fapte noi, deodată.
Pentru a adăuga un fapt cu mai multe sloturi procedăm astfel:

CLIPS>(deffacts adresa
(strada Independentei 23)
(strada Marasesti)
)
CLIPS> (assert (strada Bistritei 32))
<Fact-3>

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


Funcţia assert returnează o valoare: adresa de fapt. În cazul în care se asertează mai multe
fapte deodată valoarea returnată va fi indexul ultimului fapt introdus. În cazul nostru s-a realizat
introducerea unui singur fapt. După ce a fost introdus în lista de fapte, i-a fost asociat identificatorul
3. Parantezele unghiulare < > sunt folosite ca delimitatori pentru a încadra numele unui articol. La
fiecare nouă adăugare se va realiza automat o incrementare a numărului de fapte, această valoare
fiind returnată de funcţia assert.
De reținut că faptele introduse cu comanda assert sunt păstrate temporar în baza de fapte în
sensul că acestea sunt șterse la comanda reset.
Comanda facts este utilizată pentru afişarea faptelor aflate în lista de fapte. În cazul în care
se utilizează comanda (facts) fără niciun parametru se va realiza afişarea tuturor faptelor din listă,
dar dacă se doreşte o afişare a anumitor fapte dorite de utilizator, se pot folosi şi parametri adiţionali

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


ai acestei comenzi. Această facilitate se dovedeşte a fi foarte utilă atunci când avem un număr mare
de fapte în listă. Sintaxa pentru comanda facts este:

(facts [<start> [<end> [<maximum>]]])

unde <start>, <end>, <maximum> sunt numere întregi pozitive. Toţi parametrii sunt opţionali şi
deci comanda poate funcţiona cu zero până la trei parametri.
Dacă apare primul parametru <start>, toate faptele cu indexul mai mare sau egal decât
valoare lui <start> vor fi afişate; dacă apare al doilea parametru <end> atunci toate faptele cu
indexul mai mic sau egal decât valoarea lui <end> vor fi afişate; dacă apare şi al treilea parametru
<maximum>, atunci vor fi afişate un număr maxim de fapte. Dacă se va da comanda (facts)
rezultatul va fi următorul:

CLIPS> (facts)
f-0 (initial-facts)
f-1 (strada Independentei 23)
f-2 (strada Marasesti)
f-3 (strada Bistritei 32)
For a total of 4 facts.

După cum se observă, comanda facts indică la sfârşit, numărul de fapte pe care le-a afişat pe
monitor. De asemenea pentru fiecare fapt în parte va fi afişat şi identificatorul de fapt, în cazul
nostru acesta fiind <f-3>. Orice fapt inserat în listă are asociat de către CLIPS un identificator unic
care începe cu litera f şi este urmat de un întreg numit şi index de fapt. CLIPS-ul nu acceptă
introducerea unui duplicat în lista de fapte şi de aceea încercarea de asertare a unui fapt identic cu
un altul anterior, duce la returnarea unui mesaj de eroare:

CLIPS> (assert (strada Bistritei 32) )


FALSE

În CLIPS există şi comanda clear al cărei efect este de a şterge toate faptele din listă,
indexul de fapt începând după aceasta, din nou, cu valoarea 0.

CLIPS> (clear)
CLIPS> (assert (a) (b) (c) (d))
<Fact-3>
CLIPS>(facts 1 3 2)
f-1 (b)
f-2 (c)

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


For a total of 3 facts.
CLIPS>(assert (d))
FALSE
CLIPS> (assert (e))
<Fact-4> ;indexul de fapte este incrementat de unde a ramas
CLIPS>(assert ( f ))
<Fact-5>
CLIPS> (assert ( numar (+ 3 5)))
<Fact-6>
CLIPS> (facts)

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


f-0 (a)
f-1 (b)
f-2 (c)
f-3 (d)
f-4 (e)
f-5 (f)
f-6 (numar 8)
For a total of 7 facts.

Din exemplul de mai sus observăm că, indexul a fost incrementat în continuare. CLIPS-ul
nu se ocupă de o reactualizare a indexului faptelor din listă. Astfel, un fapt are întotdeauna acelaşi
index din momentul asertării sale în listă, până în momentul ştergerii sale. La asertarea faptului
numar CLIPS-ul va realiza automat operaţia de adunare astfel încât atunci când se va da comanda
(facts) vom avea în listă faptul (numar 8).

2.3. Gruparea faptelor. Constructorul deffacts

Într-un program este foarte avantajos ca să se poată adauga toate faptele ce reprezintă baza
iniţială de cunoaştere într-o singură aserţiune. Aceste fapte sunt cunoscute a fi adevărate încă
înainte de rularea programului. Se poate defini un grup de fapte care reprezintă baza iniţială de
cunoaştere cu ajutorul construcţiei deffacts. Sintaxa comenzii este următoarea:

(deffacts <deffacts name> [<optional comment>]


<facts>* )

În cadrul construcţiei deffacts poate fi folosit ca nume orice simbol valid. După numele
construcţiei urmează opţional un comentariu şi apoi faptele ce vor fi asertate în lista de fapte. Pentru
a realiza asertarea faptelor dintr-o declaraţie deffacts trebuie obligatoriu utilizată comanda reset.
Efectul acestei comenzi este acela că şterge toate faptele din baza de fapte (ca şi comanda clear ) şi
introduce faptele din declaraţiile deffacts. Sintaxa comenzii este:

(reset)

Se va putea observa de asemenea că o dată cu comanda reset este introdus în lista de fapte
un nou fapt generat implicit de aceasta, numit şi initial fact. CLIPS-ul foloseşte acest fapt pentru a
aprinde o regulă care nu are niciun element condiţional în LHS (se va vedea în continuare).
Identificatorul de fapt al lui initial-fact este întotdeauna f-0 , deoarece acesta este primul fapt
ce va fi introdus de CLIPS în lista de fapte după ce a fost dată comanda reset. Dacă se doreşte o
vizualizare a tuturor construcţiilor deffacts se poate utiliza comanda get-deffacts-list.

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


CLIPS> (clear)
CLIPS> (assert (a))
<Fact-0>
CLIPS> (facts)
f-0 (a)
For a total of 1 facts.
CLIPS> (get-deffacts-list)
(initial-fact)
CLIPS> (watch facts)
CLIPS> (deffacts date-initiale "Baza de salarizare"

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


(nume Cozma George)
(salariu 1500000) )
)
CLIPS> (deffacts salariu_maxim)
CLIPS>(get-deffacts-list)
(initial-fact date-initiale salariu_maxim)
CLIPS> (reset)
<== f-0 (a)
==> f-0 (initial-fact)
==> f-1 (nume Cozma George)
==> f-2 (salariu 1500000)

Se observă existenţa încă de la startarea CLIPS-ului a construcţiei deffacts initial-fact.


Funcţia get-deffacts-list ne informează de existenţa celor trei construcţii deffacts, dar abia după ce
se dă comanda reset în lista de fapte vor fi introduse faptele acestora. Ultima construcţie deffacts
salariu_minim nu are niciun fapt, existenţa ei fiind oarecum inutilă.

3. Definirea regulilor. Constructorul defrule

Metoda principală de reprezentare a cunoaşterii în CLIPS este regula. O regulă este o


colecţie de condiţii şi de acţiuni ce urmează a fi executate dacă condiţiile sunt îndeplinite. Un sistem
expert trebuie să aibă atât reguli, cât şi fapte. Regulile executate sau ‘aprinse’ se bazează pe
existenţa sau non-existenţa unor fapte sau instanţe ale unei clase definite de utilizator. Mecanismul
(motorul de inferenţă) al CLIPS-ului aşteaptă potrivirea regulilor cu starea curentă a sistemului
(reprezentată de lista de fapte şi lista de instanţe) şi apoi aplică acţiunile.
Regulile pot fi scrise direct în CLIPS sau pot fi încărcate dintr-un fişier cu reguli, creat cu un
editor. Se poate folosi în acest scop editorul încorporat al CLIPS-ului sau oricare alt editor. Faţă de
introducerea direct în top level a regulilor sau comenzilor, folosirea unui editor aduce posibilitatea
corectării eventualelor erori, fără a mai fi necesară rescrierea din nou a regulii.
Comanda care permite introducerea regulilor în program este defrule cu următoarea sintaxă:

(defrule <rule-name> [<comment>]


[<declaration>] ; Rule Properties
<conditional-element>* ; Left-Hand Side (LHS)
=>
<action>* ) ; Right-Hand Side(RHS)

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


Ca un prim exemplu de utilizare a regulilor ne putem imagina cazul în care un calculator
care are introduse deja faptele şi regulile, avertizează operatorul ca în zi de 14 se plătesc salariile.
Regula corespunzătoare este:

IF ziua curenta este 14


THEN răspunsul este "se platesc salariile"

Presupunem din exemplul anterior ca fiind deja introdus faptul data (cu sloturile zi luna an).
În acest caz regula noastră ar putea arăta astfel:

(defrule actiunea_zilei

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


(zi 14)
=>
(assert (actiune "se platesc salariile") )
)

Revenind la exemplul din paragraful 2 unde au fost definite faptele Locuinta1 si Locuinta2
se poate presupune ca exista un dispozitiv GPS care furnizează în permanenţă numele strazii pe care
ne aflăm. O regula ce se poate defini având în vedere structura prezentată este:

IF strada furnizata de GPS este Independentei


THEN ofera informatii cu privire la Locuinta 1

IF strada furnizata de GPS este Bistritei


THEN ofera informatii cu privire la Locuinta 2

(defrule locuinta1
(strada Independentei)
=>
(assert (informatii "Bloc X1, Sc. A, Ap 12"))
)

(defrule locuinta2
(strada Bistritei)
=>
(assert (informatii "Bloc X2, Sc. B, Ap. 12"))
)

Dacă s-a introdus corect regula şi nu s-a omis nicio paranteză, atunci prompter-ul CLIPS> va
reapărea. În caz contrar va apărea un mesaj de eroare în care se indică cuvântul cheie greşit sau
amplasarea greşită a parantezelor.
Redefinirea unei reguli deja existente, face ca regula anterioară cu acelaşi nume să fie
ştearsă, chiar dacă regula actuală nou introdusă are erori. După cum se observă după numele regulii
care poate fi orice simbol valid, după comentariu opţional care trebuie cuprins între ghilimele
(comentariile pot fi introduse şi după punct şi virgula „ ; ”) urmează zero sau mai multe condiţii
(pattern-uri) şi apoi zero sau mai multe acţiuni. Practic o regulă este formată din două părţi LHS şi
RHS separate de secvenţa de caractere ( => ) pe care o putem numi şi săgeată, formată dintr-un
semn „egal” şi un semn „mai mare decât”. În comparaţia regulii cu un IF-THEN săgeata marchează
începutul părţii THEN. Partea stângă LHS este formată din zero sau mai multe elemente
condiţionale (CE) , care sunt legate între ele de un and implicit. RHS-ul este format dintr-o listă de

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


acţiuni care sunt executate dacă şi numai dacă toate elementele condiţionale (pattern-urile) sunt
satisfăcute. Nu există nicio limită pentru numărul de condiţii sau de reguli dintr-o regulă, singura
limitare o constituie memoria actuală valabilă. CLIPS-ul aşteaptă îndeplinirea pattern-urilor unei
reguli verificând faptele din lista de fapte. Atunci când toate pattern-urile se potrivesc cu faptele,
regula este activată şi este pusă în agenda. Agenda reprezintă în CLIPS o colecţie de reguli activate.
In agendă pot fi zero sau mai multe fapte, retractarea unui fapt din lista de fapte putând duce la
stingerea unor reguli şi scoaterea lor automat din agendă. Dacă avem mai multe reguli care se pot
aprinde CLIPS-ul este cel care hotărăşte care din reguli este cea mai apropiată şi le ordonează pe
toate în agendă.
Dacă o regulă nu are nicio condiţie în LHS, atunci CLIPS-ul va adăuga automat pattern-ul
special initial-fact. Orice regulă care nu are condiţii se va aprinde automat şi va fi plasată în agendă,

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


după ce va fi dată comanda reset şi faptul initial-fact va fi introdus în lista de fapte. Se poate
întâmpla de asemenea ca o regulă să nu aibă nicio acţiune în RHS. Acest lucru nu este prea util, dar
e bine de ştiut că este posibilă realizarea unei astfel de reguli.
Lansarea în execuţie în CLIPS a unui program se face cu ajutorul comenzii run a cărei
sintaxa este următoarea:

( run [ <limit> ] )

Argumentul opţional <limit> este un număr întreg, care specifică numărul maxim de reguli
ce vor fi aprinse. Dacă acest argument nu apare, atunci el are implicit valoarea –1 şi toate regulile
vor fi aprinse până ce nu va mai rămâne niciuna în agendă. In caz contrar execuţia regulilor va
înceta după ce un număr de <limit> reguli au fost aprinse. Următoarea comanda run va continua
execuţia din locul de unde s-a oprit, astfel încât comanda (run 1) ar fi echivalentul unei rulări pas cu
pas a programului.
Trebuie reţinut faptul că o regulă o dată aprinsă, nu mai poate fi activată de obicei din nou.
Este necesară ori „reîmprospătarea” ei cu ajutorul comenzii refresh, ori apelarea comenzii reset,
care şterge toate faptele şi reintroduce baza iniţială de fapte din construcţiile deffacts de la care s-a
plecat. Odată refăcută baza iniţială de cunoaştere se poate da din nou comanda run. Exemple de
reguli:

(defrule bariera_coborata (defrule bariera_ridicata


(tren_apropiat da) (tren_apropiat nu)
=> =>
(assert (actiune "Coboara bariera.")) (assert (actiune "Ridica bariera."))
) )

În CLIPS afișarea faptelor se face din linia de comandă cu comanda (facts) sau în fereastra
Facts din mediul de programare CLIPS, ca în figura 2.

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm
Figura 2. Afișarea faptelor şi regulilor pentru care este îndeplinită condiția de activare

De asemenea, numele și rezultatul regulilor care se vor activa la o nouă execuție a


programului sunt afișate în fereastra de dialog cu comanda (agenda) sau în fereastra Agenda din
mediul CLIPS. Cele două ferestre precum și fereastra de dialog pot fi deschise sau închise din
meniul Window.

4. Comanda printout
Comanda printout trimite spre un dispozitiv ataşat unui nume logic un şir de caractere.
Numele logic trebuie în prealabil specificat pentru ca dispozitivul spre care se trimite să fie pregătit
(de exemplu un fişier trebuie mai întâi deschis). Pentru a avea ieşirea spre stdout (ieşirea standard,
în general monitorul) se foloseşte numele logic t. Sintaxa comenzii printout este următoarea :

( printout <logical-name> <expression>* )

Această comandă îşi dovedeşte utilitatea atunci când este amplasată în RHS-ul regulilor cu
scopul de a se afişa mesaje. Orice număr de expresii poate fi amplasat într-o comandă printout
pentru a fi afişate. Fiecare expresie este evaluată în vederea eliminării spaţiilor adiţionale aflate
între expresiile ce se doresc a fi afişate.
Simbolul crlf utilizat ca o <expresie> poate fi amplasat oriunde în lista de expresii, el
introducând un salt la început de linie nouă. crlf semnifică succesiunea de caractere 13, 10
( \r\n – carriage return, line feed).
Funcţia printout îşi marchează şirurile pe care le afişează încadrându-le între ghilimele. Pot
fi afişate de asemenea şi adresele de fapt, adresele de instanţă şi adresele externe. Această funcţie nu
returnează nicio valoare. Dispozitivul spre care se trimite poate fi redefinit, astfel încât se pot
transmite informaţii spre un modem sau o imprimantă. Următoarea regulă demonstrează utilizarea
comenzii printout :

10

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


(defrule cartela_telefonica
(cartela introdusa)
=>
(printout t "Puteti forma numarul de telefon" crlf)
)

În această regulă, prezenţa comenzii printout în RHS-ul regulii duce la afişarea la terminal
(standard output device) a unui şir de caractere. Singurul argument al funcţiei este şirul: Puteti
forma numarul de telefon, care va fi afişat pe ecran fără ghilimele.

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


5. Definirea unei variabile

Ca orice alt limbaj de programare, CLIPS-ul are variabile ce pot lua valori. Valoarea pe care
o poate lua o variabila poate fi unul din tipurile de date primitive (float, integer, symbol, string,
external address, fact address, instance name şi instance address). Faţă de fapte, care sunt statice,
conţinutul unei variabile este dinamic, astfel încât valoarea asignată acesteia poate fi schimbată.
Întotdeauna în CLIPS o variabilă este scrisă în sintaxa unui semn de întrebare „ ? “, urmat de un
câmp simbolic, care e numele variabilei. Formatul general este:

?<variable-name>

Numele variabilei poate fi orice simbol, cu restricţia că trebuie să înceapă cu o literă (în caz
contrar, deşi nu se semnalează eroare, variabila este ca şi inexistentă !). Pentru o bună înţelegere a
programului este indicat ca numele variabilelor să fie cât mai sugestive. De exemplu:

?varsta ?loc_nastere ?clasa_apartenenta ?specie

De reţinut faptul că spaţiile nu trebuiesc puse între semnul de întrebare şi numele variabilei.
Ulterior se va vedea cum se foloseşte în CLIPS semnul de întrebare, singur, fără nume de variabilă.
O variabilă poate fi folosită în LHS-ul regulii pentru a conţine valoarea unui slot, apoi se pot face
comparaţii ale acesteia cu alte valori din LHS, sau poate fi accesată din RHS-ul regulii pentru o
afişare.

(deffacts masini
(tip Toyota)
(tip Mercedes)
(tip Dacia_1300)
(tip Trabant)
)

(defrule afiseaza_tipul_masinii
(tip ?marca)
=>
(printout t "Automobilul " ?marca crlf )
)

Se vor salva aceste construcţii într-un fişier automobil.clp şi se va lansa în execuţie


programul, observându-se mesajele afişate pe monitor.

11

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


CLIPS> (clear)
CLIPS> (load "C:\\temp\\automobil.clp")
CLIPS> (reset)
CLIPS> (run)
Automobilul Trabant.
Automobilul Dacia.
Automobilul Mercedes.
Automobilul Toyota.

La lansarea în execuţie, în agendă se pot observa patru aprinderi ale aceleiaşi reguli însă în
ipostaze diferite (se poate da comanda agenda înainte de run). CLIPS-ul găseşte patru fapte diferite

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


pe care le poate potrivi cu pattern-ul regulii. Se poate observa că ordinea apariţiei celor patru
automobile este inversă, decât cea în care ele au fost introduse din construcţia deffacts în lista de
fapte la tastarea comenzii reset (se poate verifica cu facts). Ne-am putea explica acest lucru
imaginându-ne lista de fapte ca o stiva LIFO, astfel încât ultimul fapt intrat este primul comparat cu
pattern-ul regulii. Ordinea introducerii faptelor în lista este un aspect de care utilizatorul trebuie să
ţină seama atunci când doreşte afişarea într-o anumită ordine a faptelor. Înainte ca o variabilă să fie
folosită, trebuie să-i asignăm o valoare. În cazul următor variabila neavând asignată nicio valoare,
CLIPS-ul va afişa un mesaj de eroare.

(defrule exemplu
=>
(printout t ?x) )
[PRCCODE3] Undefined variable x refered in RHS of defrule.

Cum s-ar putea modifica regula de mai sus ca să se poată afişa şi numele maşinii şi vârsta?
Credeţi că sunt necesare mai multe reguli? De ce?

6. Problemă rezolvată

Întrucât CLIPS-ul presupune un mod de gândire diferit de cel cu care s-a obişnuit un
programator folosind limbaje procedurale, vom considera în cele ce urmează un exemplu de
problemă simplă rezolvată.
Să se iniţializeze o bază de cunoştinţe cu numele şi prenumele unor persoane, apoi să se
afişeze persoanele cu un anumit nume de familie.

Rezolvare:

Se deschide CLIPS-ul 

File → New: apare un nou document pentru editarea programului

Se iniţializează baza de cunoştinţe (se introduc datele iniţiale ale problemei):

(deffacts init
(nume Popescu)
(prenume Ion)
(nume Ionescu)
(prenume Ana)

12

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


(nume Stanescu)
(prenume Eldorado)
(nume Popescu)
(prenume Maria)
)

Se defineşte regula pentru afişarea tuturor persoanelor:

(defrule afiseaza_nume
(nume ?p)

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


=>
(printout t ?p crlf)
)

File → Save: se salvează programul

Se şterg eventualele fapte din execuţii anterioare:

Execution → Clear CLIPS sau comanda (clear)

Această operaţie este foarte importantă; dacă nu se şterg regulile şi faptele anterioare, o nouă
versiune, corectă, a unui program va da eroare.

File → Load: se încarcă programul în CLIPS pentru execuţie (Open deschide un fişier
pentru editare, Load – pentru execuţie). Dacă, după prelucrarea regulilor, rezultatul este TRUE,
programul este corect. Dacă nu, trebuie revăzut. Una din cele mai des întâlnite greşeli este
neînchiderea numărului corespunzător de paranteze.

Se deschid ferestrele pentru urmărirea faptelor şi regulilor:

Window → 1 Facts Window


Window → 2 Agenda Window

Se activează faptele iniţiale şi regulile corespunzătoare pentru începerea problemei:

Execution → Reset sau comanda (reset) – CTRL+E

Se rulează programul:

Execution → Run sau comanda (run) – CTRL+R

13

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


7. Aplicaţii

7.1. Să se realizeze un program CLIPS care, plecând de la relaţiile de rudenie între mai
multe persoane (Hinton, 1986):

(deffacts kinship

(father Christopher Arthur) ; Christopher este tatal lui Arthur


(father Christopher Victoria)

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


(father Andrew James)
(father Andrew Jennifer)
(father James Colin)
(father James Charlotte)
(father Roberto Emilio)
(father Roberto Lucia)
(father Pierro Marco)
(father Pierro Angela)
(father Marco Alfonso)
(father Marco Sophia)

(mother Penelope Arthur)


(mother Penelope Victoria)
(mother Christine James)
(mother Christine Jennifer)
(mother Victoria Colin)
(mother Victoria Charlotte)
(mother Maria Emilio)
(mother Maria Lucia)
(mother Francesca Marco)
(mother Francesca Angela)
(mother Lucia Alfonso)
(mother Lucia Sophia)

(husband Christopher Penelope)


(husband Andrew Christine)
(husband Arthur Margaret)
(husband James Victoria)
(husband Charles Jennifer)
(husband Roberto Maria)
(husband Pierro Francesca)
(husband Emilio Gina)
(husband Marco Lucia)
(husband Tomaso Angela)

(wife Penelope Christopher)


(wife Christine Andrew)
(wife Margaret Arthur)
(wife Victoria James)

14

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


(wife Jennifer Charles)
(wife Maria Roberto)
(wife Francesca Pierro)
(wife Gina Emilio)
(wife Lucia Marco)
(wife Angela Tomaso)

(son Arthur Christopher)


(son Arthur Penelope)
(son James Andrew)

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


(son James Christine)
(son Colin Victoria)
(son Colin James)
(son Emilio Roberto)
(son Emilio Maria)
(son Marco Pierro)
(son Marco Francesca)
(son Alfonso Lucia)
(son Alfonso Marco)

(daughter Victoria Christopher)


(daughter Victoria Penelope)
(daughter Jennifer Andrew)
(daughter Jennifer Christine)
(daughter Charlotte Victoria)
(daughter Charlotte James)
(daughter Lucia Roberto)
(daughter Lucia Maria)
(daughter Angela Pierro)
(daughter Angela Francesca)
(daughter Sophia Lucia)
(daughter Sophia Marco)

(brother Arthur Victoria)


(brother James Jennifer)
(brother Colin Charlotte)
(brother Emilio Lucia)
(brother Marco Angela)
(brother Alfonso Sophia)

(sister Victoria Arthur)


(sister Jennifer James)
(sister Charlotte Colin)
(sister Lucia Emilio)
(sister Angela Marco)
(sister Sophia Alfonso)

15

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


(uncle Arthur Colin)
(uncle Charles Colin)
(uncle Arthur Charlotte)
(uncle Charles Charlotte)
(uncle Emilio Alfonso)
(uncle Tomaso Alfonso)
(uncle Emilio Sophia)
(uncle Tomaso Sophia)

(aunt Jennifer Colin)

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


(aunt Margaret Colin)
(aunt Jennifer Charlotte)
(aunt Margaret Charlotte)
(aunt Angela Alfonso)
(aunt Gina Alfonso)
(aunt Angela Sophia)
(aunt Gina Sophia)

(nephew Colin Arthur)


(nephew Colin Jennifer)
(nephew Alfonso Emilio)
(nephew Alfonso Angela)
(nephew Colin Margaret)
(nephew Colin Charles)
(nephew Alfonso Gina)
(nephew Alfonso Tomaso)

(niece Charlotte Arthur)


(niece Charlotte Jennifer)
(niece Sophia Emilio)
(niece Sophia Angela)
(niece Charlotte Margaret)
(niece Charlotte Charles)
(niece Sophia Gina)
(niece Sophia Tomaso)
)

să deducă următoarele informaţii:

 ce persoane sunt părinţii aceluiaşi copil;


 ce persoane sunt bunic şi nepot;
 ce persoane sunt veri de gradul 2 (copiii ai căror părinţi sunt fraţi).

Pentru faptele considerate:

Marco si Lucia sunt parintii lui Sophia


Marco si Lucia sunt parintii lui Alfonso
Pierro si Francesca sunt parintii lui Angela
Pierro si Francesca sunt parintii lui Marco

16

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


Roberto si Maria sunt parintii lui Lucia
Roberto si Maria sunt parintii lui Emilio
James si Victoria sunt parintii lui Charlotte
James si Victoria sunt parintii lui Colin
Andrew si Christine sunt parintii lui Jennifer
Andrew si Christine sunt parintii lui James
Christopher si Penelope sunt parintii lui Victoria
Christopher si Penelope sunt parintii lui Arthur

Roberto este bunicul lui Sophia

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


Roberto este bunicul lui Alfonso
Christopher este bunicul lui Charlotte
Christopher este bunicul lui Colin
Pierro este bunicul lui Sophia
Pierro este bunicul lui Alfonso
Andrew este bunicul lui Charlotte
Andrew este bunicul lui Colin

ş.a.m.d.

Indicaţii

Se dă regula pentru găsirea părinţilor:

(defrule parinti
(father ?t ?f)
(mother ?m ?f)
=>
(printout t ?t " si " ?m " sunt parintii lui " ?f crlf)
)

Se observă că variabilele corespund exact locului din listă unde se află un anumit nume. De
exemplu, pentru perechea de fapte:

(father Marco Sophia)


(mother Lucia Sophia)

?t va fi Marco, ?m va fi Lucia şi ?f va fi Sophia. Legarea celor două fapte se face prin utilizarea
aceleiaşi variabile ?f, care trebuie să ia acelaşi nume, în acest caz Sophia.
În acelaşi mod, regula descoperă şi celelalte perechi de fapte father şi mother, care au
acelaşi copil.

Bunicul poate fi din partea mamei sau a tatălui. Problema se poate rezolva cu două reguli.
După introducerea operaţiilor logice, într-un laborator viitor, problema se va putea rezolva
mai simplu, utilizând operaţia sau logic în LHS: (or (fapt1) (fapt2)). În acest laborator nu se cere
acest lucru.

17

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


7.2. Lista primelor 8 elemente chimice este următoarea: H, He, Li, Be, B, C, N, O.
H are numărul atomic 1, He 2 ş.a.m.d.
Introduceţi cu ajutorul constructorului deffacts fapte de tip perechi element - număr atomic.
Scrieţi o regulă în care să introduceţi doar lista elementelor, cu ajutorul funcţiei assert.
Mai scrieţi o regulă care să afişeze elementul al cărui număr atomic este 8.

Indicaţie. Execuţia programului ar trebui să dea următoarele rezultate:

CLIPS> (reset)
CLIPS> (facts)
f-0 (initial-fact)

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm


f-1 (numar_atomic H 1)
f-2 (numar_atomic He 2)
f-3 (numar_atomic Li 3)
f-4 (numar_atomic Be 4)
f-5 (numar_atomic B 5)
f-6 (numar_atomic C 6)
f-7 (numar_atomic N 7)
f-8 (numar_atomic O 8)
For a total of 9 facts.
CLIPS> (run)
O are numarul atomic 8
CLIPS> (facts)
f-0 (initial-fact)
f-1 (numar_atomic H 1)
f-2 (numar_atomic He 2)
f-3 (numar_atomic Li 3)
f-4 (numar_atomic Be 4)
f-5 (numar_atomic B 5)
f-6 (numar_atomic C 6)
f-7 (numar_atomic N 7)
f-8 (numar_atomic O 8)
f-9 (elemente H He Li Be B C N O)
For a total of 10 facts.

18

Inteligenta artificiala - Laborator, http://florinleon.byethost24.com/lab_ia.htm

S-ar putea să vă placă și