Sunteți pe pagina 1din 5

2017 / 2018, FEAA, MASTER, MAE I, SISTEME INTELIGENTE ÎN AFACERI, LUCRAREA DE LABORATOR NR 2

II. VARIABILE, CONSTRÂNGERI, FUNCŢII ŞI PREDICATE ÎN CLIPS

2.1.Variabile şi constrângeri în şabloane


La fel ca şi alte limbaje de programare, pentru memorarea de valori limbajul CLIPS foloseşte
variabile. Numele unei variabile începe întotdeauna cu simbolul ?, urmat de un cuvânt, cu condiţia
ca acest cuvânt să înceapă cu o literă. Câteva exemple de nume de variabile sunt:
?x
?culoare
?Pret
?cantitate-kg
O astfel de variabilă se mai numeşte şi variabilă univaloare deoarece desemnează un singur
câmp al unui fapt din memoria de lucru.
Înainte de a folosi o variabilă în partea dreaptă a unei reguli, aceasta trebuie să aibă asignată o
valoare; în caz contrar, sistemul CLIPS va afişa un mesaj corespunzător.
Operaţia de asignare a unei valori unei variabile CLIPS se numeşte legare. O variabilă care a
primit o valoare se numeşte legată.
Fie următorul program, care afișează la imprimantă mai multe numere:
LP21.clp
(deffacts nu
(numar 8.9)
(numar 6)
(numar 9))

(defrule N
(numar ?x)
=>
(printout t ?x crlf))
O variabilă devine legată prin operaţia de identificare a şablonului în care apare cu un fapt din
memoria de lucru. Spre exemplu, prin identificarea şablonului (numar ?x) cu faptul (numar
8.9) variabila ?x devine legată la valoarea 8.9.
Dacă o variabilă apare de mai multe ori într-un şablon, ea va trebui să se identifice cu un fapt
în care câmpurile corespunzătoare apariţiilor variabilei sunt identice. Spre exemplu, şablonul
(numere-egale ?x ?x) se identifică cu faptul (numere-egale 1 1), dar nu şi cu faptul
(numere-egale 1 2).
De obicei, o variabilă se utilizează astfel: devine legată prin identificarea şablonului în care
apare cu un fapt din memoria de lucru şi valoarea dobândită este utilizată apoi în partea dreaptă a
regulii, fie pentru construirea unui alt fapt, fie pentru afişarea unui mesaj.
Spre exemplu, să presupunem că memorăm o mulţime de mărfuri sub forma unei mulţimi de
fapte. Pentru fiecare marfă ne interesează: denumirea şi preţul unitar. Vom folosi fapte care verifică
tiparul: (marfa denumire pret-unitar). Programul următor realizează afişarea tuturor
mărfurilor.
LP22.clp
(deffacts marfuri
(marfa b1 1000)
(marfa b2 2000)
(marfa b3 5000))
(defrule afisare
(marfa ?d ?p)
=> (printout t ?d ?p crlf))
Amelia BĂDICĂ, Valentin LIŢOIU 1
2017 / 2018, FEAA, MASTER, MAE I, SISTEME INTELIGENTE ÎN AFACERI, LUCRAREA DE LABORATOR NR 2
Argumentul t al acţiunii printout reprezintă numele logic al terminalului, fapt ce
determină afişarea celorlalte argumente ale acţiunii printout la terminal, iar argumentul crlf
determină inserarea unui sfârşit de linie după afişarea unui produs.
Este interesant şi instructiv de analizat de ce acest program afişează mărfurile în ordinea
inversă în care au fost listate în enunţul deffacts. Pentru aceasta sunt importante noţiunile de
instanţă a unei reguli şi de strategie de control a interpretorului CLIPS.
O regulă devine activă şi este plasată în agendă când toate şabloanele părţii sale stângi se
identifică cu faptele din memoria de lucru. O pereche formată dintr-un șablon aflat în partea stângă
a unei reguli şi un fapt din memoria de lucru care face regula activă se numeşte instanţă a regulii
respective. Este important de observat că agenda conţine de fapt instanţe ale regulilor şi nu reguli
propriu-zise.
La un moment dat agenda poate conţine mai multe instanţe de reguli active. Selectarea
instanţei care va fi aprinsă se face pe baza unei strategii numită strategie de control. Interpretorul
CLIPS are câteva strategii de control predefinite, şi anume:
 strategia depth (în adâncime, LIFO) - potrivit acestei strategii, se aprind întâi instanţele
adăugate cel mai recent la agendă; cu alte cuvinte agenda se comportă ca o stivă; aceasta
este strategia implicită;
 strategia breadth (în lăţime, FIFO) - potrivit acestei strategii, se aprind întâi instanţele
adăugate cel mai târziu la agendă; cu alte cuvinte, agenda se comportă ca o coadă;
 strategia simplicity (simplitate) - potrivit acestei strategii, se aprind întâi instanţele cel mai
puţin specifice;
 strategia complexity (complexitate) - potrivit acestei strategii, se aprind întâi instanţele
cele mai specifice;
 strategia LEX (ordine lexicografică) - potrivit acestei strategii, se aprind întâi instanţele de
recenţă maximă; recenţa unei instanţe este dată de secvenţa indecşilor faptelor cu care se
identifică şabloanele sale, aranjată în ordine descrescătoare; strategia LEX ordonează
instanţele în ordinea lexicografică descrescătoare a recenţelor instanţelor;
 strategia MEA - această strategie acordă prioritate indexului faptului care se identifică cu
primul şablon al părţii stângi a regulii, în sensul că instanţa pentru care acest index este
maximă este aprinsă întâi; dacă există mai multe instanţe cu valori egale ale acestui index,
se aplică strategia LEX;
 strategia random (aleator) - instanţa aprinsă se alege la întâmplare; cu toate acestea,
ordinea de aprindere este păstrată între două rulări succesive ale aceluiaşi program.
Deoarece strategia implicită este depth şi întrucât faptele din enunţul deffacts sunt
considerate în procesul de determinare a instanţelor în ordinea în care au fost listate, rezultă că se va
aprinde ultima instanţă a regulii afisare creată şi anume cea corespunzătoare ultimului fapt, apoi
penultima etc.
Determinarea strategiei de control curente se face cu comanda get-strategy. Schimbarea
strategiei se face cu comanda set-strategy cu sintaxa:
(set-strategy strategie)
Dacă se alege strategia breadth cu comanda:
CLIPS> (set-strategy breadth,
atunci mărfurile vor fi afişate în ordinea în care au fost listate în enunţul deffacts.
Pentru a putea referi un fapt în partea dreaptă a unei reguli (de exemplu pentru a-l şterge din
memoria de lucru cu retract), trebuie să asignăm faptul unei variabile şi ulterior să folosim acea
variabilă. Asignarea faptului la o variabilă se face cu operatorul <-. Un exemplu este modelarea cu
ajutorul unei reguli CLIPS a efectuării unei tranzacţii.

Amelia BĂDICĂ, Valentin LIŢOIU 2


2017 / 2018, FEAA, MASTER, MAE I, SISTEME INTELIGENTE ÎN AFACERI, LUCRAREA DE LABORATOR NR 2

LP24.clp
(deffacts ex4
(premise-tranzactie indeplinite)
(premise-tranzactie indoielnice))

(defrule modelare-tranzactie
?f <- (premise-tranzactie indeplinite)
=>
(printout t "Efectueaza tranzactia ... " crlf)
(retract ?f)
(assert (tranzactie-executata)))
Deseori trebuie să specificăm într-un şablon o variabilă a cărei valoare nu mai este folosită
ulterior. Pentru aceasta putem folosi o variabilă anonimă. O variabilă anonimă care ţine locul unui
singur câmp dintr-un fapt se numeşte variabilă anonimă univaloare şi se simbolizează prin
caracterul ?. Spre exemplu, dacă reprezentăm angajaţii unei companii printr-o mulţime de fapte care
verifică tiparul (angajat nume adresa telefon salariu) şi dorim să afişăm
salariul pentru fiecare angajat, putem proceda astfel:
LP25.clp
(deffacts angajati
(angajat Ionescu Cv 123 2000)
(angajat Popescu Buc 321 3000)
(angajat Radu Cv 124 8000))

(defrule afis-sal
(angajat ?nume ? ? ?salariul)
=>
(printout t ?nume " Are salariul " ?salariul crlf))
Uneori este util ca o variabilă să desemneze o secvenţă de zero sau mai multe câmpuri dintr-
un fapt. O astfel de variabilă se numeşte variabilă multivaloare. Numele unei variabile
multivaloare începe cu secvenţa de caractere $? şi continuă cu un câmp ce începe cu o literă. Prin
operaţia de identificare a şablonului din care face parte cu un fapt al memoriei de lucru, o variabilă
multivaloare devine legată la o secvenţă de zero sau mai multe câmpuri - spre deosebire de o
variabilă univaloare, care devine legată la exact un singur câmp. CLIPS-ul permite totodată şi
folosirea de variabile anonime multivaloare simbolizate prin secvenţa $?. Aceste variabile se
identifică cu orice secvenţă de zero sau mai multe câmpuri, dar nu-şi păstrează legătura. Deşi
variabilele multivaloare pot în utile în multe situaţii, se apreciază că folosirea lor abundentă poate
duce la scăderea vitezei de execuţie a programului şi la creşterea consumului de memorie. Acest
lucru se datorează faptului că variabilele multivaloare nu beneficiază de mecanismul eficient de
identificare a şabloanelor din CLIPS, care funcţionează doar pentru variabilele univaloare. Din acest
motiv, se recomandă ca variabilele multivaloare să se folosească doar atunci când nu se cunoaşte
numărul exact de câmpuri din cadrul unui fapt care trebuie identificate.
Să presupunem că membrii unui colectiv de muncă sunt împărţiţi pe grupuri de lucru. Fiecare
grup de lucru are un nume şi unul sau mai mulţi membri. Pentru reprezentarea unui grup de lucru se
foloseşte un fapt cu tiparul (grup nume--grup membrii-grup). Grupurile de lucru pot
fi reprezentate cu ajutorul unei mulţimi de fapte.
Dacă se doreşte afişarea numelor tuturor grupurilor care conţin cel puţin 3 membri, atunci se
poate folosi programul de mai jos:

Amelia BĂDICĂ, Valentin LIŢOIU 3


2017 / 2018, FEAA, MASTER, MAE I, SISTEME INTELIGENTE ÎN AFACERI, LUCRAREA DE LABORATOR NR 2

LP26.clp
(deffacts grupuri-munca
(grup grup1 Alina Dana Mihai)
(grup grup2 Radu Barbu)
(grup grup3 Vlad Mircea Dragos Stan)
(grup grup4 Dan ion stan nicu george cristi))

(defrule afis-grupuri
(grup ?nume-grup ? ? ? $?)
=>
(printout t ?nume-grup crlf))
Variabila $? este anonimă multivaloare, care se identifică cu zero câmpuri pentru grup1, cu
un câmp (Stan) pentru grup3 și cu trei câmpuri (nicu george cristi) pentru grup4, dar
nu poate fi folosită în partea dreaptă a regulii.
În exemplul de mai jos variabila $?rest este doar multivaloare (nu și anonimă). Ea permite
aceleași identificări ca și variabila $?, dar poate fi folosită în partea dreaptă a regulii pentru a afișa
numele persoanelor din fiecare grup aflate pe pozițiile patru și următoarele.
LP26_1.clp
(deffacts grupuri-munca
(grup grup1 Alina Dana Mihai)
(grup grup2 Radu Barbu)
(grup grup3 Vlad Mircea Dragos Stan)
(grup grup4 Dan ion stan nicu george cristi))

(defrule afis-grupuri
(grup ?nume-grup ? ? ? $?)
=>
(printout t ?nume-grup crlf))
Pe lângă facilităţile elementare de identificare a şabloanelor, bazate pe operaţia de identitate
textuală, limbajul CLIPS oferă în plus o mulţime de operatori, cunoscuţi şi sub numele de
constrângeri ale valorilor câmpurilor, care facilitează implementarea unor identificări complexe.
Există trei tipuri de constrângeri: NOT, AND şi OR. Constrângerile se simbolizează prin
intermediul operatorilor de constrângere. Cu ajutorul operatorilor şi constantelor se pot forma
expresii care desemnează constrângeri complexe. O astfel de expresie se plasează în cadrul unui
şablon, imediat după câmpul pe care îl afectează.
Constrângerea NOT se indică prin operatorul unar ~ şi semnifică faptul că valoarea câmpului
afectat trebuie să fie diferită de operandul operatorului ~.
Constrângerea OR se indică prin operatorul binar | şi semnifică faptul că valoarea câmpului
afectat trebuie să fie egală cu unul dintre operanzii operatorului |.
Constrângerea AND se indică prin operatorul binar & şi semnifică faptul că valoarea câmpului
afectat trebuie să verifice ambele constrângeri desemnate de operanzii operatorului &. Această
constrângere se utilizează deci pentru reprezentarea unor constrângeri complexe.
O problemă o reprezintă posibilitatea apariţiei unor variabile în cadrul unor constrângeri
complexe. Aceste variabile pot fi doar variabile univaloare şi în plus trebuie avute în vedere
restricţiile următoare:
 o variabilă dintr-o constrângere complexă devine legată doar dacă apare în prima condiţie a
constrângerii fie singură, fie făcând parte dintr-o constrângere AND;
 o variabilă poate să apară într-o constrângere OR doar dacă este legată.

Amelia BĂDICĂ, Valentin LIŢOIU 4


2017 / 2018, FEAA, MASTER, MAE I, SISTEME INTELIGENTE ÎN AFACERI, LUCRAREA DE LABORATOR NR 2
Să presupunem că pentru fiecare persoană dintr-un grup dorim să reprezentăm următoarele
informaţii: nume, culoare păr şi culoare ochi. Pentru aceasta putem folosi o mulţime de fapte care
verifică următorul tipar: (persoana nume culoare-ochi culoare-păr). În aceste condiţii, regula
următoare realizează determinarea tuturor perechilor de persoane care verifică următoarele condiţii:
prima persoană are ochii albaştrii sau verzi şi nu are părul negru, iar a doua persoană are culoarea
ochilor diferită faţă de prima persoană şi are părul roşcat sau de aceeaşi culoare cu al primei
persoane.
LP27.clp
(deffacts persoane
(persoana Dana albastri blond)
(persoana Nina caprui negru)
(persoana Carmen negri saten)
(persoana Geta verzi roscat))

(defrule ident-compl
(persoana ?nume1 ?ochi1&albastri|verzi ?par1&~negru)
(persoana ?nume2&~?nume1 ?ochi2&~?ochi1 ?par2&roscat|?par1)
=>
(printout t ?nume1 " Are ochii " ?ochi1 " si parul " ?par1
crlf)
(printout t ?nume2 " Are ochii " ?ochi2 " si parul " ?par2
crlf))
Alte exemple de utilizare a constrângerilor sunt programele următoare:

LP271.clp
(deffacts note
(disc d1 10)
(disc d2 8)
(disc d3 5))

(defrule afis-note
(disc ?di ?nota&~8)
=>
(printout t ?di " " ?nota crlf))

LP272.clp
(deffacts note1
(disc d1 10)
(disc d2 8)
(disc d1 5))

(defrule afis-note1
(disc ?di ?nota&10|8)
=>
(printout t ?di " " ?nota crlf))

Amelia BĂDICĂ, Valentin LIŢOIU 5

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